xref: /openbmc/linux/drivers/gpu/drm/tegra/mipi-phy.c (revision dec727399a4b36bec87b7b4d4c1b20025e69758a)
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