1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2013 NVIDIA Corporation
6 #include <linux/errno.h>
7 #include <linux/kernel.h>
12 * Default D-PHY timings based on MIPI D-PHY specification. Derived from the
13 * valid ranges specified in Section 6.9, Table 14, Page 40 of the D-PHY
14 * specification (v1.2) with minor adjustments.
16 int mipi_dphy_timing_get_default(struct mipi_dphy_timing
*timing
,
20 timing
->clkpost
= 70 + 52 * period
;
22 timing
->clkprepare
= 65;
23 timing
->clksettle
= 95;
24 timing
->clktermen
= 0;
25 timing
->clktrail
= 80;
26 timing
->clkzero
= 260;
30 timing
->hsprepare
= 65 + 5 * period
;
31 timing
->hszero
= 145 + 5 * period
;
32 timing
->hssettle
= 85 + 6 * period
;
36 * The MIPI D-PHY specification (Section 6.9, v1.2, Table 14, Page 40)
37 * contains this formula as:
39 * T_HS-TRAIL = max(n * 8 * period, 60 + n * 4 * period)
41 * where n = 1 for forward-direction HS mode and n = 4 for reverse-
42 * direction HS mode. There's only one setting and this function does
43 * not parameterize on anything other that period, so this code will
44 * assumes that reverse-direction HS mode is supported and uses n = 4.
46 timing
->hstrail
= max(4 * 8 * period
, 60 + 4 * 4 * period
);
48 timing
->init
= 100000;
50 timing
->taget
= 5 * timing
->lpx
;
51 timing
->tago
= 4 * timing
->lpx
;
52 timing
->tasure
= 2 * timing
->lpx
;
53 timing
->wakeup
= 1000000;
59 * Validate D-PHY timing according to MIPI D-PHY specification (v1.2, Section
60 * Section 6.9 "Global Operation Timing Parameters").
62 int mipi_dphy_timing_validate(struct mipi_dphy_timing
*timing
,
65 if (timing
->clkmiss
> 60)
68 if (timing
->clkpost
< (60 + 52 * period
))
71 if (timing
->clkpre
< 8)
74 if (timing
->clkprepare
< 38 || timing
->clkprepare
> 95)
77 if (timing
->clksettle
< 95 || timing
->clksettle
> 300)
80 if (timing
->clktermen
> 38)
83 if (timing
->clktrail
< 60)
86 if (timing
->clkprepare
+ timing
->clkzero
< 300)
89 if (timing
->dtermen
> 35 + 4 * period
)
92 if (timing
->eot
> 105 + 12 * period
)
95 if (timing
->hsexit
< 100)
98 if (timing
->hsprepare
< 40 + 4 * period
||
99 timing
->hsprepare
> 85 + 6 * period
)
102 if (timing
->hsprepare
+ timing
->hszero
< 145 + 10 * period
)
105 if ((timing
->hssettle
< 85 + 6 * period
) ||
106 (timing
->hssettle
> 145 + 10 * period
))
109 if (timing
->hsskip
< 40 || timing
->hsskip
> 55 + 4 * period
)
112 if (timing
->hstrail
< max(8 * period
, 60 + 4 * period
))
115 if (timing
->init
< 100000)
118 if (timing
->lpx
< 50)
121 if (timing
->taget
!= 5 * timing
->lpx
)
124 if (timing
->tago
!= 4 * timing
->lpx
)
127 if (timing
->tasure
< timing
->lpx
|| timing
->tasure
> 2 * timing
->lpx
)
130 if (timing
->wakeup
< 1000000)