6666#define DATA_LANE_2_EN BIT(4)
6767#define DATA_LANE_1_EN BIT(3)
6868#define DATA_LANE_0_EN BIT(2)
69+ #define FBDIV_8_MASK BIT(5)
70+ #define PREDIV_MASK (0x1f << 0)
71+ #define FBDIV_7_0_MASK (0xff << 0)
6972#define FBDIV_8 (x ) (((x) & 0x1) << 5)
7073#define PREDIV (x ) (((x) & 0x1f) << 0)
7174#define FBDIV_7_0 (x ) (((x) & 0xff) << 0)
75+ #define T_LPX_MASK (0x3f << 0)
76+ #define T_HS_PREPARE_MASK (0x7f << 0)
77+ #define T_HS_ZERO_MASK (0x3f << 0)
78+ #define T_HS_TRAIL_MASK (0x7f << 0)
79+ #define T_HS_EXIT_MASK (0x1f << 0)
80+ #define T_CLK_POST_MASK (0xf << 0)
81+ #define T_WAKUP_H_MASK (0x3 << 0)
82+ #define T_WAKUP_L_MASK (0xff << 0)
83+ #define T_CLK_PRE_MASK (0xf << 0)
84+ #define T_TA_GO_MASK (0x3f << 0)
85+ #define T_TA_SURE_MASK (0x3f << 0)
86+ #define T_TA_WAIT_MASK (0x3f << 0)
7287#define T_LPX (x ) (((x) & 0x3f) << 0)
7388#define T_HS_PREPARE (x ) (((x) & 0x7f) << 0)
7489#define T_HS_ZERO (x ) (((x) & 0x3f) << 0)
@@ -90,82 +105,12 @@ enum lane_type {
90105 DATA_LANE_3 ,
91106};
92107
93- static const u32 lane_reg_offset [] = {
94- [CLOCK_LANE ] = INNO_CLOCK_LANE_REG_BASE ,
95- [DATA_LANE_0 ] = INNO_DATA_LANE_0_REG_BASE ,
96- [DATA_LANE_1 ] = INNO_DATA_LANE_1_REG_BASE ,
97- [DATA_LANE_2 ] = INNO_DATA_LANE_2_REG_BASE ,
98- [DATA_LANE_3 ] = INNO_DATA_LANE_3_REG_BASE ,
99- };
100-
101- enum hs_clk_range {
102- HS_CLK_RANGE_80_110_MHZ ,
103- HS_CLK_RANGE_110_150_MHZ ,
104- HS_CLK_RANGE_150_200_MHZ ,
105- HS_CLK_RANGE_200_250_MHZ ,
106- HS_CLK_RANGE_250_300_MHZ ,
107- HS_CLK_RANGE_300_400_MHZ ,
108- HS_CLK_RANGE_400_500_MHZ ,
109- HS_CLK_RANGE_500_600_MHZ ,
110- HS_CLK_RANGE_600_700_MHZ ,
111- HS_CLK_RANGE_700_800_MHZ ,
112- HS_CLK_RANGE_800_1000_MHZ ,
113- };
114-
115- static const u8 t_hs_prepare_val [] = {
116- [HS_CLK_RANGE_80_110_MHZ ] = 0x20 ,
117- [HS_CLK_RANGE_110_150_MHZ ] = 0x06 ,
118- [HS_CLK_RANGE_150_200_MHZ ] = 0x18 ,
119- [HS_CLK_RANGE_200_250_MHZ ] = 0x05 ,
120- [HS_CLK_RANGE_250_300_MHZ ] = 0x51 ,
121- [HS_CLK_RANGE_300_400_MHZ ] = 0x64 ,
122- [HS_CLK_RANGE_400_500_MHZ ] = 0x20 ,
123- [HS_CLK_RANGE_500_600_MHZ ] = 0x6a ,
124- [HS_CLK_RANGE_600_700_MHZ ] = 0x3e ,
125- [HS_CLK_RANGE_700_800_MHZ ] = 0x21 ,
126- [HS_CLK_RANGE_800_1000_MHZ ] = 0x09 ,
127- };
128-
129- static const u8 clock_lane_t_hs_zero_val [] = {
130- [HS_CLK_RANGE_80_110_MHZ ] = 0x16 ,
131- [HS_CLK_RANGE_110_150_MHZ ] = 0x16 ,
132- [HS_CLK_RANGE_150_200_MHZ ] = 0x17 ,
133- [HS_CLK_RANGE_200_250_MHZ ] = 0x17 ,
134- [HS_CLK_RANGE_250_300_MHZ ] = 0x18 ,
135- [HS_CLK_RANGE_300_400_MHZ ] = 0x19 ,
136- [HS_CLK_RANGE_400_500_MHZ ] = 0x1b ,
137- [HS_CLK_RANGE_500_600_MHZ ] = 0x1d ,
138- [HS_CLK_RANGE_600_700_MHZ ] = 0x1e ,
139- [HS_CLK_RANGE_700_800_MHZ ] = 0x1f ,
140- [HS_CLK_RANGE_800_1000_MHZ ] = 0x20 ,
141- };
142-
143- static const u8 data_lane_t_hs_zero_val [] = {
144- [HS_CLK_RANGE_80_110_MHZ ] = 2 ,
145- [HS_CLK_RANGE_110_150_MHZ ] = 3 ,
146- [HS_CLK_RANGE_150_200_MHZ ] = 4 ,
147- [HS_CLK_RANGE_200_250_MHZ ] = 5 ,
148- [HS_CLK_RANGE_250_300_MHZ ] = 6 ,
149- [HS_CLK_RANGE_300_400_MHZ ] = 7 ,
150- [HS_CLK_RANGE_400_500_MHZ ] = 7 ,
151- [HS_CLK_RANGE_500_600_MHZ ] = 8 ,
152- [HS_CLK_RANGE_600_700_MHZ ] = 8 ,
153- [HS_CLK_RANGE_700_800_MHZ ] = 9 ,
154- [HS_CLK_RANGE_800_1000_MHZ ] = 9 ,
155- };
156-
157- static const u8 t_hs_trail_val [] = {
158- [HS_CLK_RANGE_80_110_MHZ ] = 0x22 ,
159- [HS_CLK_RANGE_110_150_MHZ ] = 0x45 ,
160- [HS_CLK_RANGE_150_200_MHZ ] = 0x0b ,
161- [HS_CLK_RANGE_200_250_MHZ ] = 0x16 ,
162- [HS_CLK_RANGE_250_300_MHZ ] = 0x2c ,
163- [HS_CLK_RANGE_300_400_MHZ ] = 0x33 ,
164- [HS_CLK_RANGE_400_500_MHZ ] = 0x4e ,
165- [HS_CLK_RANGE_500_600_MHZ ] = 0x3a ,
166- [HS_CLK_RANGE_600_700_MHZ ] = 0x6a ,
167- [HS_CLK_RANGE_700_800_MHZ ] = 0x29 ,
168- [HS_CLK_RANGE_800_1000_MHZ ] = 0x27 ,
108+ struct t_param {
109+ u32 hs_clk_rate ;
110+ u8 t_hs_prepare ;
111+ u8 clock_lane_t_hs_zero ;
112+ u8 data_lane_t_hs_zero ;
113+ u8 t_hs_trail ;
169114};
170115
171116struct mipi_dphy_timing {
@@ -226,6 +171,28 @@ struct inno_mipi_dphy {
226171 u32 lane_mbps ;
227172};
228173
174+ static const u32 lane_reg_offset [] = {
175+ [CLOCK_LANE ] = INNO_CLOCK_LANE_REG_BASE ,
176+ [DATA_LANE_0 ] = INNO_DATA_LANE_0_REG_BASE ,
177+ [DATA_LANE_1 ] = INNO_DATA_LANE_1_REG_BASE ,
178+ [DATA_LANE_2 ] = INNO_DATA_LANE_2_REG_BASE ,
179+ [DATA_LANE_3 ] = INNO_DATA_LANE_3_REG_BASE ,
180+ };
181+
182+ static const struct t_param t_fixed_param_table [] = {
183+ { 110 , 0x20 , 0x16 , 0x02 , 0x22 },
184+ { 150 , 0x06 , 0x16 , 0x03 , 0x45 },
185+ { 200 , 0x18 , 0x17 , 0x04 , 0x0b },
186+ { 250 , 0x05 , 0x17 , 0x05 , 0x16 },
187+ { 300 , 0x51 , 0x18 , 0x06 , 0x2c },
188+ { 400 , 0x64 , 0x19 , 0x07 , 0x33 },
189+ { 500 , 0x20 , 0x1b , 0x07 , 0x4e },
190+ { 600 , 0x6a , 0x1d , 0x08 , 0x3a },
191+ { 700 , 0x3e , 0x1e , 0x08 , 0x6a },
192+ { 800 , 0x21 , 0x1f , 0x09 , 0x29 },
193+ {1000 , 0x09 , 0x20 , 0x09 , 0x27 }
194+ };
195+
229196static inline void inno_write (struct inno_mipi_dphy * inno , u32 reg , u32 val )
230197{
231198 writel_relaxed (val , inno -> regs + reg );
@@ -280,46 +247,85 @@ static void inno_mipi_dphy_timing_update(struct inno_mipi_dphy *inno,
280247 struct inno_mipi_dphy_timing * t )
281248{
282249 u32 base = lane_reg_offset [lane_type ];
250+ u32 val , mask ;
283251
284- inno_write (inno , base + T_HS_PREPARE_OFFSET ,
285- T_HS_PREPARE (t -> t_hs_prepare ));
286- inno_write (inno , base + T_HS_ZERO_OFFSET , T_HS_ZERO (t -> t_hs_zero ));
287- inno_write (inno , base + T_HS_TRAIL_OFFSET , T_HS_TRAIL (t -> t_hs_trail ));
288- inno_write (inno , base + T_HS_EXIT_OFFSET , T_HS_EXIT (t -> t_hs_exit ));
289- inno_write (inno , base + T_CLK_POST_OFFSET , T_CLK_POST (t -> t_clk_post ));
290- inno_write (inno , base + T_CLK_PRE_OFFSET , T_CLK_PRE (t -> t_clk_pre ));
291- inno_write (inno , base + T_WAKUP_H_OFFSET , T_WAKUP_H (t -> t_wakup_h ));
292- inno_write (inno , base + T_WAKUP_L_OFFSET , T_WAKUP_L (t -> t_wakup_l ));
293- inno_write (inno , base + T_LPX_OFFSET , T_LPX (t -> t_lpx ));
294- inno_write (inno , base + T_TA_GO_OFFSET , T_TA_GO (t -> t_ta_go ));
295- inno_write (inno , base + T_TA_SURE_OFFSET , T_TA_SURE (t -> t_ta_sure ));
296- inno_write (inno , base + T_TA_WAIT_OFFSET , T_TA_WAIT (t -> t_ta_wait ));
252+ mask = T_HS_PREPARE_MASK ;
253+ val = T_HS_PREPARE (t -> t_hs_prepare );
254+ inno_update_bits (inno , base + T_HS_PREPARE_OFFSET , mask , val );
255+
256+ mask = T_HS_ZERO_MASK ;
257+ val = T_HS_ZERO (t -> t_hs_zero );
258+ inno_update_bits (inno , base + T_HS_ZERO_OFFSET , mask , val );
259+
260+ mask = T_HS_TRAIL_MASK ;
261+ val = T_HS_TRAIL (t -> t_hs_trail );
262+ inno_update_bits (inno , base + T_HS_TRAIL_OFFSET , mask , val );
263+
264+ mask = T_HS_EXIT_MASK ;
265+ val = T_HS_EXIT (t -> t_hs_exit );
266+ inno_update_bits (inno , base + T_HS_EXIT_OFFSET , mask , val );
267+
268+ if (lane_type == CLOCK_LANE ) {
269+ mask = T_CLK_POST_MASK ;
270+ val = T_CLK_POST (t -> t_clk_post );
271+ inno_update_bits (inno , base + T_CLK_POST_OFFSET , mask , val );
272+
273+ mask = T_CLK_PRE_MASK ;
274+ val = T_CLK_PRE (t -> t_clk_pre );
275+ inno_update_bits (inno , base + T_CLK_PRE_OFFSET , mask , val );
276+ }
277+
278+ mask = T_WAKUP_H_MASK ;
279+ val = T_WAKUP_H (t -> t_wakup_h );
280+ inno_update_bits (inno , base + T_WAKUP_H_OFFSET , mask , val );
281+
282+ mask = T_WAKUP_L_MASK ;
283+ val = T_WAKUP_L (t -> t_wakup_l );
284+ inno_update_bits (inno , base + T_WAKUP_L_OFFSET , mask , val );
285+
286+ mask = T_LPX_MASK ;
287+ val = T_LPX (t -> t_lpx );
288+ inno_update_bits (inno , base + T_LPX_OFFSET , mask , val );
289+
290+ mask = T_TA_GO_MASK ;
291+ val = T_TA_GO (t -> t_ta_go );
292+ inno_update_bits (inno , base + T_TA_GO_OFFSET , mask , val );
293+
294+ mask = T_TA_SURE_MASK ;
295+ val = T_TA_SURE (t -> t_ta_sure );
296+ inno_update_bits (inno , base + T_TA_SURE_OFFSET , mask , val );
297+
298+ mask = T_TA_WAIT_MASK ;
299+ val = T_TA_WAIT (t -> t_ta_wait );
300+ inno_update_bits (inno , base + T_TA_WAIT_OFFSET , mask , val );
297301}
298302
299- static enum hs_clk_range inno_mipi_dphy_get_hs_clk_range (u32 lane_mbps )
303+ static int inno_mipi_dphy_get_fixed_param (struct inno_mipi_dphy_timing * t ,
304+ u32 hs_clk_rate ,
305+ enum lane_type lane_type )
300306{
301- if (lane_mbps < 110 )
302- return HS_CLK_RANGE_80_110_MHZ ;
303- else if (lane_mbps < 150 )
304- return HS_CLK_RANGE_110_150_MHZ ;
305- else if (lane_mbps < 200 )
306- return HS_CLK_RANGE_150_200_MHZ ;
307- else if (lane_mbps < 250 )
308- return HS_CLK_RANGE_200_250_MHZ ;
309- else if (lane_mbps < 300 )
310- return HS_CLK_RANGE_250_300_MHZ ;
311- else if (lane_mbps < 400 )
312- return HS_CLK_RANGE_400_500_MHZ ;
313- else if (lane_mbps < 500 )
314- return HS_CLK_RANGE_400_500_MHZ ;
315- else if (lane_mbps < 600 )
316- return HS_CLK_RANGE_500_600_MHZ ;
317- else if (lane_mbps < 700 )
318- return HS_CLK_RANGE_600_700_MHZ ;
319- else if (lane_mbps < 800 )
320- return HS_CLK_RANGE_700_800_MHZ ;
307+ const struct t_param * param ;
308+ int i ;
309+
310+ for (i = 0 ; i < ARRAY_SIZE (t_fixed_param_table ); i ++ ) {
311+ if (hs_clk_rate <= t_fixed_param_table [i ].hs_clk_rate )
312+ break ;
313+ }
314+
315+ if (i == ARRAY_SIZE (t_fixed_param_table ))
316+ return - EINVAL ;
317+
318+ param = & t_fixed_param_table [i ];
319+
320+ if (lane_type == CLOCK_LANE )
321+ t -> t_hs_zero = param -> clock_lane_t_hs_zero ;
321322 else
322- return HS_CLK_RANGE_800_1000_MHZ ;
323+ t -> t_hs_zero = param -> data_lane_t_hs_zero ;
324+
325+ t -> t_hs_prepare = param -> t_hs_prepare ;
326+ t -> t_hs_trail = param -> t_hs_trail ;
327+
328+ return 0 ;
323329}
324330
325331static void inno_mipi_dphy_lane_timing_init (struct inno_mipi_dphy * inno ,
@@ -330,22 +336,12 @@ static void inno_mipi_dphy_lane_timing_init(struct inno_mipi_dphy *inno,
330336 u32 txbyteclkhs = inno -> lane_mbps / 8 ; /* MHz */
331337 u32 txclkesc = 20 ; /* MHz */
332338 u32 UI = DIV_ROUND_CLOSEST (NSEC_PER_USEC , inno -> lane_mbps ); /* ns */
333- enum hs_clk_range range ;
334339
335340 memset (& timing , 0 , sizeof (timing ));
336341 memset (& data , 0 , sizeof (data ));
337342
338343 mipi_dphy_timing_get_default (& timing , UI );
339-
340- range = inno_mipi_dphy_get_hs_clk_range (inno -> lane_mbps );
341-
342- if (lane_type == CLOCK_LANE )
343- data .t_hs_zero = clock_lane_t_hs_zero_val [range ];
344- else
345- data .t_hs_zero = data_lane_t_hs_zero_val [range ];
346-
347- data .t_hs_prepare = t_hs_prepare_val [range ];
348- data .t_hs_trail = t_hs_trail_val [range ];
344+ inno_mipi_dphy_get_fixed_param (& data , inno -> lane_mbps , lane_type );
349345
350346 /* txbyteclkhs domain */
351347 data .t_hs_exit = DIV_ROUND_UP (txbyteclkhs * timing .hsexit ,
@@ -374,7 +370,7 @@ static void inno_mipi_dphy_pll_init(struct inno_mipi_dphy *inno)
374370 unsigned int target_mbps = 1000 ;
375371 unsigned int max_mbps = 1000 ;
376372 u32 fbdiv = 1 , prediv = 1 ;
377- u32 val ;
373+ u32 val , mask ;
378374
379375 mpclk = DIV_ROUND_UP (panel -> vm .pixelclock , USEC_PER_SEC );
380376 if (mpclk ) {
@@ -390,6 +386,8 @@ static void inno_mipi_dphy_pll_init(struct inno_mipi_dphy *inno)
390386 tmp = pllref ;
391387
392388 for (i = 1 ; i < 6 ; i ++ ) {
389+ if (pllref % i )
390+ continue ;
393391 pre = pllref / i ;
394392 if ((tmp > (target_mbps % pre )) && (target_mbps / pre < 512 )) {
395393 tmp = target_mbps % pre ;
@@ -400,17 +398,19 @@ static void inno_mipi_dphy_pll_init(struct inno_mipi_dphy *inno)
400398 break ;
401399 }
402400
403- inno -> lane_mbps = pllref * fbdiv / prediv ;
401+ inno -> lane_mbps = pllref / prediv * fbdiv ;
404402 phy_set_bus_width (inno -> phy , inno -> lane_mbps );
405403
404+ mask = FBDIV_8_MASK | PREDIV_MASK ;
406405 val = FBDIV_8 (fbdiv >> 8 ) | PREDIV (prediv );
407- inno_write (inno , INNO_PHY_PLL_CTRL_0 , val );
406+ inno_update_bits (inno , INNO_PHY_PLL_CTRL_0 , mask , val );
408407
408+ mask = FBDIV_7_0_MASK ;
409409 val = FBDIV_7_0 (fbdiv );
410- inno_write (inno , INNO_PHY_PLL_CTRL_1 , val );
410+ inno_update_bits (inno , INNO_PHY_PLL_CTRL_1 , mask , val );
411411
412- dev_info (inno -> dev , "fin=%d, fout=%d, prediv=%d, fbdiv=%d\n" ,
413- pllref , inno -> lane_mbps , prediv , fbdiv );
412+ dev_info (inno -> dev , "fin=%d, target_mbps=%d, fout=%d, prediv=%d, fbdiv=%d\n" ,
413+ pllref , target_mbps , inno -> lane_mbps , prediv , fbdiv );
414414}
415415
416416static void inno_mipi_dphy_reset (struct inno_mipi_dphy * inno )
0 commit comments