1*dec72739SThierry Reding /* 2*dec72739SThierry Reding * Copyright (C) 2013 NVIDIA Corporation 3*dec72739SThierry Reding * 4*dec72739SThierry Reding * Permission to use, copy, modify, distribute, and sell this software and its 5*dec72739SThierry Reding * documentation for any purpose is hereby granted without fee, provided that 6*dec72739SThierry Reding * the above copyright notice appear in all copies and that both that copyright 7*dec72739SThierry Reding * notice and this permission notice appear in supporting documentation, and 8*dec72739SThierry Reding * that the name of the copyright holders not be used in advertising or 9*dec72739SThierry Reding * publicity pertaining to distribution of the software without specific, 10*dec72739SThierry Reding * written prior permission. The copyright holders make no representations 11*dec72739SThierry Reding * about the suitability of this software for any purpose. It is provided "as 12*dec72739SThierry Reding * is" without express or implied warranty. 13*dec72739SThierry Reding * 14*dec72739SThierry Reding * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15*dec72739SThierry Reding * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16*dec72739SThierry Reding * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17*dec72739SThierry Reding * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18*dec72739SThierry Reding * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19*dec72739SThierry Reding * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 20*dec72739SThierry Reding * OF THIS SOFTWARE. 21*dec72739SThierry Reding */ 22*dec72739SThierry Reding 23*dec72739SThierry Reding #include <linux/kernel.h> 24*dec72739SThierry Reding 25*dec72739SThierry Reding #include "mipi-phy.h" 26*dec72739SThierry Reding 27*dec72739SThierry Reding /* 28*dec72739SThierry Reding * Default D-PHY timings based on MIPI D-PHY specification. Derived from 29*dec72739SThierry Reding * the valid ranges specified in Section 5.9 of the D-PHY specification 30*dec72739SThierry Reding * with minor adjustments. 31*dec72739SThierry Reding */ 32*dec72739SThierry Reding int mipi_dphy_timing_get_default(struct mipi_dphy_timing *timing, 33*dec72739SThierry Reding unsigned long period) 34*dec72739SThierry Reding { 35*dec72739SThierry Reding timing->clkmiss = 0; 36*dec72739SThierry Reding timing->clkpost = 70 + 52 * period; 37*dec72739SThierry Reding timing->clkpre = 8; 38*dec72739SThierry Reding timing->clkprepare = 65; 39*dec72739SThierry Reding timing->clksettle = 95; 40*dec72739SThierry Reding timing->clktermen = 0; 41*dec72739SThierry Reding timing->clktrail = 80; 42*dec72739SThierry Reding timing->clkzero = 260; 43*dec72739SThierry Reding timing->dtermen = 0; 44*dec72739SThierry Reding timing->eot = 0; 45*dec72739SThierry Reding timing->hsexit = 120; 46*dec72739SThierry Reding timing->hsprepare = 65 + 5 * period; 47*dec72739SThierry Reding timing->hszero = 145 + 5 * period; 48*dec72739SThierry Reding timing->hssettle = 85 + 6 * period; 49*dec72739SThierry Reding timing->hsskip = 40; 50*dec72739SThierry Reding timing->hstrail = max(8 * period, 60 + 4 * period); 51*dec72739SThierry Reding timing->init = 100000; 52*dec72739SThierry Reding timing->lpx = 60; 53*dec72739SThierry Reding timing->taget = 5 * timing->lpx; 54*dec72739SThierry Reding timing->tago = 4 * timing->lpx; 55*dec72739SThierry Reding timing->tasure = 2 * timing->lpx; 56*dec72739SThierry Reding timing->wakeup = 1000000; 57*dec72739SThierry Reding 58*dec72739SThierry Reding return 0; 59*dec72739SThierry Reding } 60*dec72739SThierry Reding 61*dec72739SThierry Reding /* 62*dec72739SThierry Reding * Validate D-PHY timing according to MIPI Alliance Specification for D-PHY, 63*dec72739SThierry Reding * Section 5.9 "Global Operation Timing Parameters". 64*dec72739SThierry Reding */ 65*dec72739SThierry Reding int mipi_dphy_timing_validate(struct mipi_dphy_timing *timing, 66*dec72739SThierry Reding unsigned long period) 67*dec72739SThierry Reding { 68*dec72739SThierry Reding if (timing->clkmiss > 60) 69*dec72739SThierry Reding return -EINVAL; 70*dec72739SThierry Reding 71*dec72739SThierry Reding if (timing->clkpost < (60 + 52 * period)) 72*dec72739SThierry Reding return -EINVAL; 73*dec72739SThierry Reding 74*dec72739SThierry Reding if (timing->clkpre < 8) 75*dec72739SThierry Reding return -EINVAL; 76*dec72739SThierry Reding 77*dec72739SThierry Reding if (timing->clkprepare < 38 || timing->clkprepare > 95) 78*dec72739SThierry Reding return -EINVAL; 79*dec72739SThierry Reding 80*dec72739SThierry Reding if (timing->clksettle < 95 || timing->clksettle > 300) 81*dec72739SThierry Reding return -EINVAL; 82*dec72739SThierry Reding 83*dec72739SThierry Reding if (timing->clktermen > 38) 84*dec72739SThierry Reding return -EINVAL; 85*dec72739SThierry Reding 86*dec72739SThierry Reding if (timing->clktrail < 60) 87*dec72739SThierry Reding return -EINVAL; 88*dec72739SThierry Reding 89*dec72739SThierry Reding if (timing->clkprepare + timing->clkzero < 300) 90*dec72739SThierry Reding return -EINVAL; 91*dec72739SThierry Reding 92*dec72739SThierry Reding if (timing->dtermen > 35 + 4 * period) 93*dec72739SThierry Reding return -EINVAL; 94*dec72739SThierry Reding 95*dec72739SThierry Reding if (timing->eot > 105 + 12 * period) 96*dec72739SThierry Reding return -EINVAL; 97*dec72739SThierry Reding 98*dec72739SThierry Reding if (timing->hsexit < 100) 99*dec72739SThierry Reding return -EINVAL; 100*dec72739SThierry Reding 101*dec72739SThierry Reding if (timing->hsprepare < 40 + 4 * period || 102*dec72739SThierry Reding timing->hsprepare > 85 + 6 * period) 103*dec72739SThierry Reding return -EINVAL; 104*dec72739SThierry Reding 105*dec72739SThierry Reding if (timing->hsprepare + timing->hszero < 145 + 10 * period) 106*dec72739SThierry Reding return -EINVAL; 107*dec72739SThierry Reding 108*dec72739SThierry Reding if ((timing->hssettle < 85 + 6 * period) || 109*dec72739SThierry Reding (timing->hssettle > 145 + 10 * period)) 110*dec72739SThierry Reding return -EINVAL; 111*dec72739SThierry Reding 112*dec72739SThierry Reding if (timing->hsskip < 40 || timing->hsskip > 55 + 4 * period) 113*dec72739SThierry Reding return -EINVAL; 114*dec72739SThierry Reding 115*dec72739SThierry Reding if (timing->hstrail < max(8 * period, 60 + 4 * period)) 116*dec72739SThierry Reding return -EINVAL; 117*dec72739SThierry Reding 118*dec72739SThierry Reding if (timing->init < 100000) 119*dec72739SThierry Reding return -EINVAL; 120*dec72739SThierry Reding 121*dec72739SThierry Reding if (timing->lpx < 50) 122*dec72739SThierry Reding return -EINVAL; 123*dec72739SThierry Reding 124*dec72739SThierry Reding if (timing->taget != 5 * timing->lpx) 125*dec72739SThierry Reding return -EINVAL; 126*dec72739SThierry Reding 127*dec72739SThierry Reding if (timing->tago != 4 * timing->lpx) 128*dec72739SThierry Reding return -EINVAL; 129*dec72739SThierry Reding 130*dec72739SThierry Reding if (timing->tasure < timing->lpx || timing->tasure > 2 * timing->lpx) 131*dec72739SThierry Reding return -EINVAL; 132*dec72739SThierry Reding 133*dec72739SThierry Reding if (timing->wakeup < 1000000) 134*dec72739SThierry Reding return -EINVAL; 135*dec72739SThierry Reding 136*dec72739SThierry Reding return 0; 137*dec72739SThierry Reding } 138