1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright © 2019-2020 Intel Corporation |
4 | */ |
5 | |
6 | #include <linux/clk.h> |
7 | #include <linux/delay.h> |
8 | #include <linux/of.h> |
9 | #include <linux/of_graph.h> |
10 | #include <linux/mfd/syscon.h> |
11 | #include <linux/platform_device.h> |
12 | #include <linux/regmap.h> |
13 | |
14 | #include <drm/drm_atomic_helper.h> |
15 | #include <drm/drm_bridge.h> |
16 | #include <drm/drm_bridge_connector.h> |
17 | #include <drm/drm_mipi_dsi.h> |
18 | #include <drm/drm_simple_kms_helper.h> |
19 | #include <drm/drm_print.h> |
20 | #include <drm/drm_probe_helper.h> |
21 | |
22 | #include "kmb_dsi.h" |
23 | #include "kmb_regs.h" |
24 | |
25 | static struct mipi_dsi_host *dsi_host; |
26 | static struct mipi_dsi_device *dsi_device; |
27 | static struct drm_bridge *adv_bridge; |
28 | |
29 | /* Default setting is 1080p, 4 lanes */ |
30 | #define IMG_HEIGHT_LINES 1080 |
31 | #define IMG_WIDTH_PX 1920 |
32 | #define MIPI_TX_ACTIVE_LANES 4 |
33 | |
34 | static struct mipi_tx_frame_section_cfg mipi_tx_frame0_sect_cfg = { |
35 | .width_pixels = IMG_WIDTH_PX, |
36 | .height_lines = IMG_HEIGHT_LINES, |
37 | .data_type = DSI_LP_DT_PPS_RGB888_24B, |
38 | .data_mode = MIPI_DATA_MODE1, |
39 | .dma_packed = 0 |
40 | }; |
41 | |
42 | static struct mipi_tx_frame_cfg mipitx_frame0_cfg = { |
43 | .sections[0] = &mipi_tx_frame0_sect_cfg, |
44 | .sections[1] = NULL, |
45 | .sections[2] = NULL, |
46 | .sections[3] = NULL, |
47 | .vsync_width = 5, |
48 | .v_backporch = 36, |
49 | .v_frontporch = 4, |
50 | .hsync_width = 44, |
51 | .h_backporch = 148, |
52 | .h_frontporch = 88 |
53 | }; |
54 | |
55 | static const struct mipi_tx_dsi_cfg mipitx_dsi_cfg = { |
56 | .hfp_blank_en = 0, |
57 | .eotp_en = 0, |
58 | .lpm_last_vfp_line = 0, |
59 | .lpm_first_vsa_line = 0, |
60 | .sync_pulse_eventn = DSI_VIDEO_MODE_NO_BURST_EVENT, |
61 | .hfp_blanking = SEND_BLANK_PACKET, |
62 | .hbp_blanking = SEND_BLANK_PACKET, |
63 | .hsa_blanking = SEND_BLANK_PACKET, |
64 | .v_blanking = SEND_BLANK_PACKET, |
65 | }; |
66 | |
67 | static struct mipi_ctrl_cfg mipi_tx_init_cfg = { |
68 | .active_lanes = MIPI_TX_ACTIVE_LANES, |
69 | .lane_rate_mbps = MIPI_TX_LANE_DATA_RATE_MBPS, |
70 | .ref_clk_khz = MIPI_TX_REF_CLK_KHZ, |
71 | .cfg_clk_khz = MIPI_TX_CFG_CLK_KHZ, |
72 | .tx_ctrl_cfg = { |
73 | .frames[0] = &mipitx_frame0_cfg, |
74 | .frames[1] = NULL, |
75 | .frames[2] = NULL, |
76 | .frames[3] = NULL, |
77 | .tx_dsi_cfg = &mipitx_dsi_cfg, |
78 | .line_sync_pkt_en = 0, |
79 | .line_counter_active = 0, |
80 | .frame_counter_active = 0, |
81 | .tx_always_use_hact = 1, |
82 | .tx_hact_wait_stop = 1, |
83 | } |
84 | }; |
85 | |
86 | struct mipi_hs_freq_range_cfg { |
87 | u16 default_bit_rate_mbps; |
88 | u8 hsfreqrange_code; |
89 | }; |
90 | |
91 | struct vco_params { |
92 | u32 freq; |
93 | u32 range; |
94 | u32 divider; |
95 | }; |
96 | |
97 | static const struct vco_params vco_table[] = { |
98 | {52, 0x3f, 8}, |
99 | {80, 0x39, 8}, |
100 | {105, 0x2f, 4}, |
101 | {160, 0x29, 4}, |
102 | {210, 0x1f, 2}, |
103 | {320, 0x19, 2}, |
104 | {420, 0x0f, 1}, |
105 | {630, 0x09, 1}, |
106 | {1100, 0x03, 1}, |
107 | {0xffff, 0x01, 1}, |
108 | }; |
109 | |
110 | static const struct mipi_hs_freq_range_cfg |
111 | mipi_hs_freq_range[MIPI_DPHY_DEFAULT_BIT_RATES] = { |
112 | {.default_bit_rate_mbps = 80, .hsfreqrange_code = 0x00}, |
113 | {.default_bit_rate_mbps = 90, .hsfreqrange_code = 0x10}, |
114 | {.default_bit_rate_mbps = 100, .hsfreqrange_code = 0x20}, |
115 | {.default_bit_rate_mbps = 110, .hsfreqrange_code = 0x30}, |
116 | {.default_bit_rate_mbps = 120, .hsfreqrange_code = 0x01}, |
117 | {.default_bit_rate_mbps = 130, .hsfreqrange_code = 0x11}, |
118 | {.default_bit_rate_mbps = 140, .hsfreqrange_code = 0x21}, |
119 | {.default_bit_rate_mbps = 150, .hsfreqrange_code = 0x31}, |
120 | {.default_bit_rate_mbps = 160, .hsfreqrange_code = 0x02}, |
121 | {.default_bit_rate_mbps = 170, .hsfreqrange_code = 0x12}, |
122 | {.default_bit_rate_mbps = 180, .hsfreqrange_code = 0x22}, |
123 | {.default_bit_rate_mbps = 190, .hsfreqrange_code = 0x32}, |
124 | {.default_bit_rate_mbps = 205, .hsfreqrange_code = 0x03}, |
125 | {.default_bit_rate_mbps = 220, .hsfreqrange_code = 0x13}, |
126 | {.default_bit_rate_mbps = 235, .hsfreqrange_code = 0x23}, |
127 | {.default_bit_rate_mbps = 250, .hsfreqrange_code = 0x33}, |
128 | {.default_bit_rate_mbps = 275, .hsfreqrange_code = 0x04}, |
129 | {.default_bit_rate_mbps = 300, .hsfreqrange_code = 0x14}, |
130 | {.default_bit_rate_mbps = 325, .hsfreqrange_code = 0x25}, |
131 | {.default_bit_rate_mbps = 350, .hsfreqrange_code = 0x35}, |
132 | {.default_bit_rate_mbps = 400, .hsfreqrange_code = 0x05}, |
133 | {.default_bit_rate_mbps = 450, .hsfreqrange_code = 0x16}, |
134 | {.default_bit_rate_mbps = 500, .hsfreqrange_code = 0x26}, |
135 | {.default_bit_rate_mbps = 550, .hsfreqrange_code = 0x37}, |
136 | {.default_bit_rate_mbps = 600, .hsfreqrange_code = 0x07}, |
137 | {.default_bit_rate_mbps = 650, .hsfreqrange_code = 0x18}, |
138 | {.default_bit_rate_mbps = 700, .hsfreqrange_code = 0x28}, |
139 | {.default_bit_rate_mbps = 750, .hsfreqrange_code = 0x39}, |
140 | {.default_bit_rate_mbps = 800, .hsfreqrange_code = 0x09}, |
141 | {.default_bit_rate_mbps = 850, .hsfreqrange_code = 0x19}, |
142 | {.default_bit_rate_mbps = 900, .hsfreqrange_code = 0x29}, |
143 | {.default_bit_rate_mbps = 1000, .hsfreqrange_code = 0x0A}, |
144 | {.default_bit_rate_mbps = 1050, .hsfreqrange_code = 0x1A}, |
145 | {.default_bit_rate_mbps = 1100, .hsfreqrange_code = 0x2A}, |
146 | {.default_bit_rate_mbps = 1150, .hsfreqrange_code = 0x3B}, |
147 | {.default_bit_rate_mbps = 1200, .hsfreqrange_code = 0x0B}, |
148 | {.default_bit_rate_mbps = 1250, .hsfreqrange_code = 0x1B}, |
149 | {.default_bit_rate_mbps = 1300, .hsfreqrange_code = 0x2B}, |
150 | {.default_bit_rate_mbps = 1350, .hsfreqrange_code = 0x3C}, |
151 | {.default_bit_rate_mbps = 1400, .hsfreqrange_code = 0x0C}, |
152 | {.default_bit_rate_mbps = 1450, .hsfreqrange_code = 0x1C}, |
153 | {.default_bit_rate_mbps = 1500, .hsfreqrange_code = 0x2C}, |
154 | {.default_bit_rate_mbps = 1550, .hsfreqrange_code = 0x3D}, |
155 | {.default_bit_rate_mbps = 1600, .hsfreqrange_code = 0x0D}, |
156 | {.default_bit_rate_mbps = 1650, .hsfreqrange_code = 0x1D}, |
157 | {.default_bit_rate_mbps = 1700, .hsfreqrange_code = 0x2E}, |
158 | {.default_bit_rate_mbps = 1750, .hsfreqrange_code = 0x3E}, |
159 | {.default_bit_rate_mbps = 1800, .hsfreqrange_code = 0x0E}, |
160 | {.default_bit_rate_mbps = 1850, .hsfreqrange_code = 0x1E}, |
161 | {.default_bit_rate_mbps = 1900, .hsfreqrange_code = 0x2F}, |
162 | {.default_bit_rate_mbps = 1950, .hsfreqrange_code = 0x3F}, |
163 | {.default_bit_rate_mbps = 2000, .hsfreqrange_code = 0x0F}, |
164 | {.default_bit_rate_mbps = 2050, .hsfreqrange_code = 0x40}, |
165 | {.default_bit_rate_mbps = 2100, .hsfreqrange_code = 0x41}, |
166 | {.default_bit_rate_mbps = 2150, .hsfreqrange_code = 0x42}, |
167 | {.default_bit_rate_mbps = 2200, .hsfreqrange_code = 0x43}, |
168 | {.default_bit_rate_mbps = 2250, .hsfreqrange_code = 0x44}, |
169 | {.default_bit_rate_mbps = 2300, .hsfreqrange_code = 0x45}, |
170 | {.default_bit_rate_mbps = 2350, .hsfreqrange_code = 0x46}, |
171 | {.default_bit_rate_mbps = 2400, .hsfreqrange_code = 0x47}, |
172 | {.default_bit_rate_mbps = 2450, .hsfreqrange_code = 0x48}, |
173 | {.default_bit_rate_mbps = 2500, .hsfreqrange_code = 0x49} |
174 | }; |
175 | |
176 | static void kmb_dsi_clk_disable(struct kmb_dsi *kmb_dsi) |
177 | { |
178 | clk_disable_unprepare(clk: kmb_dsi->clk_mipi); |
179 | clk_disable_unprepare(clk: kmb_dsi->clk_mipi_ecfg); |
180 | clk_disable_unprepare(clk: kmb_dsi->clk_mipi_cfg); |
181 | } |
182 | |
183 | void kmb_dsi_host_unregister(struct kmb_dsi *kmb_dsi) |
184 | { |
185 | kmb_dsi_clk_disable(kmb_dsi); |
186 | mipi_dsi_host_unregister(host: kmb_dsi->host); |
187 | } |
188 | |
189 | /* |
190 | * This DSI can only be paired with bridges that do config through i2c |
191 | * which is ADV 7535 in the KMB EVM |
192 | */ |
193 | static ssize_t kmb_dsi_host_transfer(struct mipi_dsi_host *host, |
194 | const struct mipi_dsi_msg *msg) |
195 | { |
196 | return 0; |
197 | } |
198 | |
199 | static int kmb_dsi_host_attach(struct mipi_dsi_host *host, |
200 | struct mipi_dsi_device *dev) |
201 | { |
202 | return 0; |
203 | } |
204 | |
205 | static int kmb_dsi_host_detach(struct mipi_dsi_host *host, |
206 | struct mipi_dsi_device *dev) |
207 | { |
208 | return 0; |
209 | } |
210 | |
211 | static const struct mipi_dsi_host_ops kmb_dsi_host_ops = { |
212 | .attach = kmb_dsi_host_attach, |
213 | .detach = kmb_dsi_host_detach, |
214 | .transfer = kmb_dsi_host_transfer, |
215 | }; |
216 | |
217 | int kmb_dsi_host_bridge_init(struct device *dev) |
218 | { |
219 | struct device_node *encoder_node, *dsi_out; |
220 | |
221 | /* Create and register MIPI DSI host */ |
222 | if (!dsi_host) { |
223 | dsi_host = kzalloc(size: sizeof(*dsi_host), GFP_KERNEL); |
224 | if (!dsi_host) |
225 | return -ENOMEM; |
226 | |
227 | dsi_host->ops = &kmb_dsi_host_ops; |
228 | |
229 | if (!dsi_device) { |
230 | dsi_device = kzalloc(size: sizeof(*dsi_device), GFP_KERNEL); |
231 | if (!dsi_device) { |
232 | kfree(objp: dsi_host); |
233 | return -ENOMEM; |
234 | } |
235 | } |
236 | |
237 | dsi_host->dev = dev; |
238 | mipi_dsi_host_register(host: dsi_host); |
239 | } |
240 | |
241 | /* Find ADV7535 node and initialize it */ |
242 | dsi_out = of_graph_get_endpoint_by_regs(parent: dev->of_node, port_reg: 0, reg: 1); |
243 | if (!dsi_out) { |
244 | DRM_ERROR("Failed to get dsi_out node info from DT\n" ); |
245 | return -EINVAL; |
246 | } |
247 | encoder_node = of_graph_get_remote_port_parent(node: dsi_out); |
248 | if (!encoder_node) { |
249 | of_node_put(node: dsi_out); |
250 | DRM_ERROR("Failed to get bridge info from DT\n" ); |
251 | return -EINVAL; |
252 | } |
253 | /* Locate drm bridge from the hdmi encoder DT node */ |
254 | adv_bridge = of_drm_find_bridge(np: encoder_node); |
255 | of_node_put(node: dsi_out); |
256 | of_node_put(node: encoder_node); |
257 | if (!adv_bridge) { |
258 | DRM_DEBUG("Wait for external bridge driver DT\n" ); |
259 | return -EPROBE_DEFER; |
260 | } |
261 | |
262 | return 0; |
263 | } |
264 | |
265 | static u32 mipi_get_datatype_params(u32 data_type, u32 data_mode, |
266 | struct mipi_data_type_params *params) |
267 | { |
268 | struct mipi_data_type_params data_type_param; |
269 | |
270 | switch (data_type) { |
271 | case DSI_LP_DT_PPS_YCBCR420_12B: |
272 | data_type_param.size_constraint_pixels = 2; |
273 | data_type_param.size_constraint_bytes = 3; |
274 | switch (data_mode) { |
275 | /* Case 0 not supported according to MDK */ |
276 | case 1: |
277 | case 2: |
278 | case 3: |
279 | data_type_param.pixels_per_pclk = 2; |
280 | data_type_param.bits_per_pclk = 24; |
281 | break; |
282 | default: |
283 | DRM_ERROR("DSI: Invalid data_mode %d\n" , data_mode); |
284 | return -EINVAL; |
285 | } |
286 | break; |
287 | case DSI_LP_DT_PPS_YCBCR422_16B: |
288 | data_type_param.size_constraint_pixels = 2; |
289 | data_type_param.size_constraint_bytes = 4; |
290 | switch (data_mode) { |
291 | /* Case 0 and 1 not supported according |
292 | * to MDK |
293 | */ |
294 | case 2: |
295 | data_type_param.pixels_per_pclk = 1; |
296 | data_type_param.bits_per_pclk = 16; |
297 | break; |
298 | case 3: |
299 | data_type_param.pixels_per_pclk = 2; |
300 | data_type_param.bits_per_pclk = 32; |
301 | break; |
302 | default: |
303 | DRM_ERROR("DSI: Invalid data_mode %d\n" , data_mode); |
304 | return -EINVAL; |
305 | } |
306 | break; |
307 | case DSI_LP_DT_LPPS_YCBCR422_20B: |
308 | case DSI_LP_DT_PPS_YCBCR422_24B: |
309 | data_type_param.size_constraint_pixels = 2; |
310 | data_type_param.size_constraint_bytes = 6; |
311 | switch (data_mode) { |
312 | /* Case 0 not supported according to MDK */ |
313 | case 1: |
314 | case 2: |
315 | case 3: |
316 | data_type_param.pixels_per_pclk = 1; |
317 | data_type_param.bits_per_pclk = 24; |
318 | break; |
319 | default: |
320 | DRM_ERROR("DSI: Invalid data_mode %d\n" , data_mode); |
321 | return -EINVAL; |
322 | } |
323 | break; |
324 | case DSI_LP_DT_PPS_RGB565_16B: |
325 | data_type_param.size_constraint_pixels = 1; |
326 | data_type_param.size_constraint_bytes = 2; |
327 | switch (data_mode) { |
328 | case 0: |
329 | case 1: |
330 | data_type_param.pixels_per_pclk = 1; |
331 | data_type_param.bits_per_pclk = 16; |
332 | break; |
333 | case 2: |
334 | case 3: |
335 | data_type_param.pixels_per_pclk = 2; |
336 | data_type_param.bits_per_pclk = 32; |
337 | break; |
338 | default: |
339 | DRM_ERROR("DSI: Invalid data_mode %d\n" , data_mode); |
340 | return -EINVAL; |
341 | } |
342 | break; |
343 | case DSI_LP_DT_PPS_RGB666_18B: |
344 | data_type_param.size_constraint_pixels = 4; |
345 | data_type_param.size_constraint_bytes = 9; |
346 | data_type_param.bits_per_pclk = 18; |
347 | data_type_param.pixels_per_pclk = 1; |
348 | break; |
349 | case DSI_LP_DT_LPPS_RGB666_18B: |
350 | case DSI_LP_DT_PPS_RGB888_24B: |
351 | data_type_param.size_constraint_pixels = 1; |
352 | data_type_param.size_constraint_bytes = 3; |
353 | data_type_param.bits_per_pclk = 24; |
354 | data_type_param.pixels_per_pclk = 1; |
355 | break; |
356 | case DSI_LP_DT_PPS_RGB101010_30B: |
357 | data_type_param.size_constraint_pixels = 4; |
358 | data_type_param.size_constraint_bytes = 15; |
359 | data_type_param.bits_per_pclk = 30; |
360 | data_type_param.pixels_per_pclk = 1; |
361 | break; |
362 | default: |
363 | DRM_ERROR("DSI: Invalid data_type %d\n" , data_type); |
364 | return -EINVAL; |
365 | } |
366 | |
367 | *params = data_type_param; |
368 | return 0; |
369 | } |
370 | |
371 | static u32 compute_wc(u32 width_px, u8 size_constr_p, u8 size_constr_b) |
372 | { |
373 | /* Calculate the word count for each long packet */ |
374 | return (((width_px / size_constr_p) * size_constr_b) & 0xffff); |
375 | } |
376 | |
377 | static u32 compute_unpacked_bytes(u32 wc, u8 bits_per_pclk) |
378 | { |
379 | /* Number of PCLK cycles needed to transfer a line |
380 | * with each PCLK cycle, 4 Bytes are sent through the PPL module |
381 | */ |
382 | return ((wc * 8) / bits_per_pclk) * 4; |
383 | } |
384 | |
385 | static u32 mipi_tx_fg_section_cfg_regs(struct kmb_dsi *kmb_dsi, |
386 | u8 frame_id, u8 section, |
387 | u32 height_lines, u32 unpacked_bytes, |
388 | struct mipi_tx_frame_sect_phcfg *ph_cfg) |
389 | { |
390 | u32 cfg = 0; |
391 | u32 ctrl_no = MIPI_CTRL6; |
392 | u32 reg_adr; |
393 | |
394 | /* Frame section packet header */ |
395 | /* Word count bits [15:0] */ |
396 | cfg = (ph_cfg->wc & MIPI_TX_SECT_WC_MASK) << 0; |
397 | |
398 | /* Data type (bits [21:16]) */ |
399 | cfg |= ((ph_cfg->data_type & MIPI_TX_SECT_DT_MASK) |
400 | << MIPI_TX_SECT_DT_SHIFT); |
401 | |
402 | /* Virtual channel (bits [23:22]) */ |
403 | cfg |= ((ph_cfg->vchannel & MIPI_TX_SECT_VC_MASK) |
404 | << MIPI_TX_SECT_VC_SHIFT); |
405 | |
406 | /* Data mode (bits [24:25]) */ |
407 | cfg |= ((ph_cfg->data_mode & MIPI_TX_SECT_DM_MASK) |
408 | << MIPI_TX_SECT_DM_SHIFT); |
409 | if (ph_cfg->dma_packed) |
410 | cfg |= MIPI_TX_SECT_DMA_PACKED; |
411 | |
412 | dev_dbg(kmb_dsi->dev, |
413 | "ctrl=%d frame_id=%d section=%d cfg=%x packed=%d\n" , |
414 | ctrl_no, frame_id, section, cfg, ph_cfg->dma_packed); |
415 | kmb_write_mipi(kmb_dsi, |
416 | reg: (MIPI_TXm_HS_FGn_SECTo_PH(ctrl_no, frame_id, section)), |
417 | value: cfg); |
418 | |
419 | /* Unpacked bytes */ |
420 | |
421 | /* There are 4 frame generators and each fg has 4 sections |
422 | * There are 2 registers for unpacked bytes (# bytes each |
423 | * section occupies in memory) |
424 | * REG_UNPACKED_BYTES0: [15:0]-BYTES0, [31:16]-BYTES1 |
425 | * REG_UNPACKED_BYTES1: [15:0]-BYTES2, [31:16]-BYTES3 |
426 | */ |
427 | reg_adr = |
428 | MIPI_TXm_HS_FGn_SECT_UNPACKED_BYTES0(ctrl_no, |
429 | frame_id) + (section / 2) * 4; |
430 | kmb_write_bits_mipi(kmb_dsi, reg: reg_adr, offset: (section % 2) * 16, num_bits: 16, |
431 | value: unpacked_bytes); |
432 | dev_dbg(kmb_dsi->dev, |
433 | "unpacked_bytes = %d, wordcount = %d\n" , unpacked_bytes, |
434 | ph_cfg->wc); |
435 | |
436 | /* Line config */ |
437 | reg_adr = MIPI_TXm_HS_FGn_SECTo_LINE_CFG(ctrl_no, frame_id, section); |
438 | kmb_write_mipi(kmb_dsi, reg: reg_adr, value: height_lines); |
439 | return 0; |
440 | } |
441 | |
442 | static u32 mipi_tx_fg_section_cfg(struct kmb_dsi *kmb_dsi, |
443 | u8 frame_id, u8 section, |
444 | struct mipi_tx_frame_section_cfg *frame_scfg, |
445 | u32 *bits_per_pclk, u32 *wc) |
446 | { |
447 | u32 ret = 0; |
448 | u32 unpacked_bytes; |
449 | struct mipi_data_type_params data_type_parameters; |
450 | struct mipi_tx_frame_sect_phcfg ph_cfg; |
451 | |
452 | ret = mipi_get_datatype_params(data_type: frame_scfg->data_type, |
453 | data_mode: frame_scfg->data_mode, |
454 | params: &data_type_parameters); |
455 | if (ret) |
456 | return ret; |
457 | |
458 | /* Packet width has to be a multiple of the minimum packet width |
459 | * (in pixels) set for each data type |
460 | */ |
461 | if (frame_scfg->width_pixels % |
462 | data_type_parameters.size_constraint_pixels != 0) |
463 | return -EINVAL; |
464 | |
465 | *wc = compute_wc(width_px: frame_scfg->width_pixels, |
466 | size_constr_p: data_type_parameters.size_constraint_pixels, |
467 | size_constr_b: data_type_parameters.size_constraint_bytes); |
468 | unpacked_bytes = compute_unpacked_bytes(wc: *wc, |
469 | bits_per_pclk: data_type_parameters.bits_per_pclk); |
470 | ph_cfg.wc = *wc; |
471 | ph_cfg.data_mode = frame_scfg->data_mode; |
472 | ph_cfg.data_type = frame_scfg->data_type; |
473 | ph_cfg.dma_packed = frame_scfg->dma_packed; |
474 | ph_cfg.vchannel = frame_id; |
475 | |
476 | mipi_tx_fg_section_cfg_regs(kmb_dsi, frame_id, section, |
477 | height_lines: frame_scfg->height_lines, |
478 | unpacked_bytes, ph_cfg: &ph_cfg); |
479 | |
480 | /* Caller needs bits_per_clk for additional caluclations */ |
481 | *bits_per_pclk = data_type_parameters.bits_per_pclk; |
482 | |
483 | return 0; |
484 | } |
485 | |
486 | #define CLK_DIFF_LOW 50 |
487 | #define CLK_DIFF_HI 60 |
488 | #define SYSCLK_500 500 |
489 | |
490 | static void mipi_tx_fg_cfg_regs(struct kmb_dsi *kmb_dsi, u8 frame_gen, |
491 | struct mipi_tx_frame_timing_cfg *fg_cfg) |
492 | { |
493 | u32 sysclk; |
494 | u32 ppl_llp_ratio; |
495 | u32 ctrl_no = MIPI_CTRL6, reg_adr, val, offset; |
496 | |
497 | /* 500 Mhz system clock minus 50 to account for the difference in |
498 | * MIPI clock speed in RTL tests |
499 | */ |
500 | if (kmb_dsi->sys_clk_mhz == SYSCLK_500) { |
501 | sysclk = kmb_dsi->sys_clk_mhz - CLK_DIFF_LOW; |
502 | } else { |
503 | /* 700 Mhz clk*/ |
504 | sysclk = kmb_dsi->sys_clk_mhz - CLK_DIFF_HI; |
505 | } |
506 | |
507 | /* PPL-Pixel Packing Layer, LLP-Low Level Protocol |
508 | * Frame genartor timing parameters are clocked on the system clock, |
509 | * whereas as the equivalent parameters in the LLP blocks are clocked |
510 | * on LLP Tx clock from the D-PHY - BYTE clock |
511 | */ |
512 | |
513 | /* Multiply by 1000 to maintain precision */ |
514 | ppl_llp_ratio = ((fg_cfg->bpp / 8) * sysclk * 1000) / |
515 | ((fg_cfg->lane_rate_mbps / 8) * fg_cfg->active_lanes); |
516 | |
517 | dev_dbg(kmb_dsi->dev, "ppl_llp_ratio=%d\n" , ppl_llp_ratio); |
518 | dev_dbg(kmb_dsi->dev, "bpp=%d sysclk=%d lane-rate=%d active-lanes=%d\n" , |
519 | fg_cfg->bpp, sysclk, fg_cfg->lane_rate_mbps, |
520 | fg_cfg->active_lanes); |
521 | |
522 | /* Frame generator number of lines */ |
523 | reg_adr = MIPI_TXm_HS_FGn_NUM_LINES(ctrl_no, frame_gen); |
524 | kmb_write_mipi(kmb_dsi, reg: reg_adr, value: fg_cfg->v_active); |
525 | |
526 | /* vsync width |
527 | * There are 2 registers for vsync width (VSA in lines for |
528 | * channels 0-3) |
529 | * REG_VSYNC_WIDTH0: [15:0]-VSA for channel0, [31:16]-VSA for channel1 |
530 | * REG_VSYNC_WIDTH1: [15:0]-VSA for channel2, [31:16]-VSA for channel3 |
531 | */ |
532 | offset = (frame_gen % 2) * 16; |
533 | reg_adr = MIPI_TXm_HS_VSYNC_WIDTHn(ctrl_no, frame_gen / 2); |
534 | kmb_write_bits_mipi(kmb_dsi, reg: reg_adr, offset, num_bits: 16, value: fg_cfg->vsync_width); |
535 | |
536 | /* vertical backporch (vbp) */ |
537 | reg_adr = MIPI_TXm_HS_V_BACKPORCHESn(ctrl_no, frame_gen / 2); |
538 | kmb_write_bits_mipi(kmb_dsi, reg: reg_adr, offset, num_bits: 16, value: fg_cfg->v_backporch); |
539 | |
540 | /* vertical frontporch (vfp) */ |
541 | reg_adr = MIPI_TXm_HS_V_FRONTPORCHESn(ctrl_no, frame_gen / 2); |
542 | kmb_write_bits_mipi(kmb_dsi, reg: reg_adr, offset, num_bits: 16, value: fg_cfg->v_frontporch); |
543 | |
544 | /* vertical active (vactive) */ |
545 | reg_adr = MIPI_TXm_HS_V_ACTIVEn(ctrl_no, frame_gen / 2); |
546 | kmb_write_bits_mipi(kmb_dsi, reg: reg_adr, offset, num_bits: 16, value: fg_cfg->v_active); |
547 | |
548 | /* hsync width */ |
549 | reg_adr = MIPI_TXm_HS_HSYNC_WIDTHn(ctrl_no, frame_gen); |
550 | kmb_write_mipi(kmb_dsi, reg: reg_adr, |
551 | value: (fg_cfg->hsync_width * ppl_llp_ratio) / 1000); |
552 | |
553 | /* horizontal backporch (hbp) */ |
554 | reg_adr = MIPI_TXm_HS_H_BACKPORCHn(ctrl_no, frame_gen); |
555 | kmb_write_mipi(kmb_dsi, reg: reg_adr, |
556 | value: (fg_cfg->h_backporch * ppl_llp_ratio) / 1000); |
557 | |
558 | /* horizontal frontporch (hfp) */ |
559 | reg_adr = MIPI_TXm_HS_H_FRONTPORCHn(ctrl_no, frame_gen); |
560 | kmb_write_mipi(kmb_dsi, reg: reg_adr, |
561 | value: (fg_cfg->h_frontporch * ppl_llp_ratio) / 1000); |
562 | |
563 | /* horizontal active (ha) */ |
564 | reg_adr = MIPI_TXm_HS_H_ACTIVEn(ctrl_no, frame_gen); |
565 | |
566 | /* convert h_active which is wc in bytes to cycles */ |
567 | val = (fg_cfg->h_active * sysclk * 1000) / |
568 | ((fg_cfg->lane_rate_mbps / 8) * fg_cfg->active_lanes); |
569 | val /= 1000; |
570 | kmb_write_mipi(kmb_dsi, reg: reg_adr, value: val); |
571 | |
572 | /* llp hsync width */ |
573 | reg_adr = MIPI_TXm_HS_LLP_HSYNC_WIDTHn(ctrl_no, frame_gen); |
574 | kmb_write_mipi(kmb_dsi, reg: reg_adr, value: fg_cfg->hsync_width * (fg_cfg->bpp / 8)); |
575 | |
576 | /* llp h backporch */ |
577 | reg_adr = MIPI_TXm_HS_LLP_H_BACKPORCHn(ctrl_no, frame_gen); |
578 | kmb_write_mipi(kmb_dsi, reg: reg_adr, value: fg_cfg->h_backporch * (fg_cfg->bpp / 8)); |
579 | |
580 | /* llp h frontporch */ |
581 | reg_adr = MIPI_TXm_HS_LLP_H_FRONTPORCHn(ctrl_no, frame_gen); |
582 | kmb_write_mipi(kmb_dsi, reg: reg_adr, |
583 | value: fg_cfg->h_frontporch * (fg_cfg->bpp / 8)); |
584 | } |
585 | |
586 | static void mipi_tx_fg_cfg(struct kmb_dsi *kmb_dsi, u8 frame_gen, |
587 | u8 active_lanes, u32 bpp, u32 wc, |
588 | u32 lane_rate_mbps, struct mipi_tx_frame_cfg *fg_cfg) |
589 | { |
590 | u32 i, fg_num_lines = 0; |
591 | struct mipi_tx_frame_timing_cfg fg_t_cfg; |
592 | |
593 | /* Calculate the total frame generator number of |
594 | * lines based on it's active sections |
595 | */ |
596 | for (i = 0; i < MIPI_TX_FRAME_GEN_SECTIONS; i++) { |
597 | if (fg_cfg->sections[i]) |
598 | fg_num_lines += fg_cfg->sections[i]->height_lines; |
599 | } |
600 | |
601 | fg_t_cfg.bpp = bpp; |
602 | fg_t_cfg.lane_rate_mbps = lane_rate_mbps; |
603 | fg_t_cfg.hsync_width = fg_cfg->hsync_width; |
604 | fg_t_cfg.h_backporch = fg_cfg->h_backporch; |
605 | fg_t_cfg.h_frontporch = fg_cfg->h_frontporch; |
606 | fg_t_cfg.h_active = wc; |
607 | fg_t_cfg.vsync_width = fg_cfg->vsync_width; |
608 | fg_t_cfg.v_backporch = fg_cfg->v_backporch; |
609 | fg_t_cfg.v_frontporch = fg_cfg->v_frontporch; |
610 | fg_t_cfg.v_active = fg_num_lines; |
611 | fg_t_cfg.active_lanes = active_lanes; |
612 | |
613 | /* Apply frame generator timing setting */ |
614 | mipi_tx_fg_cfg_regs(kmb_dsi, frame_gen, fg_cfg: &fg_t_cfg); |
615 | } |
616 | |
617 | static void mipi_tx_multichannel_fifo_cfg(struct kmb_dsi *kmb_dsi, |
618 | u8 active_lanes, u8 vchannel_id) |
619 | { |
620 | u32 fifo_size, fifo_rthreshold; |
621 | u32 ctrl_no = MIPI_CTRL6; |
622 | |
623 | /* Clear all mc fifo channel sizes and thresholds */ |
624 | kmb_write_mipi(kmb_dsi, MIPI_TX_HS_MC_FIFO_CTRL_EN, value: 0); |
625 | kmb_write_mipi(kmb_dsi, MIPI_TX_HS_MC_FIFO_CHAN_ALLOC0, value: 0); |
626 | kmb_write_mipi(kmb_dsi, MIPI_TX_HS_MC_FIFO_CHAN_ALLOC1, value: 0); |
627 | kmb_write_mipi(kmb_dsi, MIPI_TX_HS_MC_FIFO_RTHRESHOLD0, value: 0); |
628 | kmb_write_mipi(kmb_dsi, MIPI_TX_HS_MC_FIFO_RTHRESHOLD1, value: 0); |
629 | |
630 | fifo_size = ((active_lanes > MIPI_D_LANES_PER_DPHY) ? |
631 | MIPI_CTRL_4LANE_MAX_MC_FIFO_LOC : |
632 | MIPI_CTRL_2LANE_MAX_MC_FIFO_LOC) - 1; |
633 | |
634 | /* MC fifo size for virtual channels 0-3 |
635 | * REG_MC_FIFO_CHAN_ALLOC0: [8:0]-channel0, [24:16]-channel1 |
636 | * REG_MC_FIFO_CHAN_ALLOC1: [8:0]-2, [24:16]-channel3 |
637 | */ |
638 | SET_MC_FIFO_CHAN_ALLOC(kmb_dsi, ctrl_no, vchannel_id, fifo_size); |
639 | |
640 | /* Set threshold to half the fifo size, actual size=size*16 */ |
641 | fifo_rthreshold = ((fifo_size) * 8) & BIT_MASK_16; |
642 | SET_MC_FIFO_RTHRESHOLD(kmb_dsi, ctrl_no, vchannel_id, fifo_rthreshold); |
643 | |
644 | /* Enable the MC FIFO channel corresponding to the Virtual Channel */ |
645 | kmb_set_bit_mipi(kmb_dsi, MIPI_TXm_HS_MC_FIFO_CTRL_EN(ctrl_no), |
646 | offset: vchannel_id); |
647 | } |
648 | |
649 | static void mipi_tx_ctrl_cfg(struct kmb_dsi *kmb_dsi, u8 fg_id, |
650 | struct mipi_ctrl_cfg *ctrl_cfg) |
651 | { |
652 | u32 sync_cfg = 0, ctrl = 0, fg_en; |
653 | u32 ctrl_no = MIPI_CTRL6; |
654 | |
655 | /* MIPI_TX_HS_SYNC_CFG */ |
656 | if (ctrl_cfg->tx_ctrl_cfg.line_sync_pkt_en) |
657 | sync_cfg |= LINE_SYNC_PKT_ENABLE; |
658 | if (ctrl_cfg->tx_ctrl_cfg.frame_counter_active) |
659 | sync_cfg |= FRAME_COUNTER_ACTIVE; |
660 | if (ctrl_cfg->tx_ctrl_cfg.line_counter_active) |
661 | sync_cfg |= LINE_COUNTER_ACTIVE; |
662 | if (ctrl_cfg->tx_ctrl_cfg.tx_dsi_cfg->v_blanking) |
663 | sync_cfg |= DSI_V_BLANKING; |
664 | if (ctrl_cfg->tx_ctrl_cfg.tx_dsi_cfg->hsa_blanking) |
665 | sync_cfg |= DSI_HSA_BLANKING; |
666 | if (ctrl_cfg->tx_ctrl_cfg.tx_dsi_cfg->hbp_blanking) |
667 | sync_cfg |= DSI_HBP_BLANKING; |
668 | if (ctrl_cfg->tx_ctrl_cfg.tx_dsi_cfg->hfp_blanking) |
669 | sync_cfg |= DSI_HFP_BLANKING; |
670 | if (ctrl_cfg->tx_ctrl_cfg.tx_dsi_cfg->sync_pulse_eventn) |
671 | sync_cfg |= DSI_SYNC_PULSE_EVENTN; |
672 | if (ctrl_cfg->tx_ctrl_cfg.tx_dsi_cfg->lpm_first_vsa_line) |
673 | sync_cfg |= DSI_LPM_FIRST_VSA_LINE; |
674 | if (ctrl_cfg->tx_ctrl_cfg.tx_dsi_cfg->lpm_last_vfp_line) |
675 | sync_cfg |= DSI_LPM_LAST_VFP_LINE; |
676 | |
677 | /* Enable frame generator */ |
678 | fg_en = 1 << fg_id; |
679 | sync_cfg |= FRAME_GEN_EN(fg_en); |
680 | |
681 | if (ctrl_cfg->tx_ctrl_cfg.tx_always_use_hact) |
682 | sync_cfg |= ALWAYS_USE_HACT(fg_en); |
683 | if (ctrl_cfg->tx_ctrl_cfg.tx_hact_wait_stop) |
684 | sync_cfg |= HACT_WAIT_STOP(fg_en); |
685 | |
686 | dev_dbg(kmb_dsi->dev, "sync_cfg=%d fg_en=%d\n" , sync_cfg, fg_en); |
687 | |
688 | /* MIPI_TX_HS_CTRL */ |
689 | |
690 | /* type:DSI, source:LCD */ |
691 | ctrl = HS_CTRL_EN | TX_SOURCE; |
692 | ctrl |= LCD_VC(fg_id); |
693 | ctrl |= ACTIVE_LANES(ctrl_cfg->active_lanes - 1); |
694 | if (ctrl_cfg->tx_ctrl_cfg.tx_dsi_cfg->eotp_en) |
695 | ctrl |= DSI_EOTP_EN; |
696 | if (ctrl_cfg->tx_ctrl_cfg.tx_dsi_cfg->hfp_blank_en) |
697 | ctrl |= DSI_CMD_HFP_EN; |
698 | |
699 | /*67 ns stop time */ |
700 | ctrl |= HSEXIT_CNT(0x43); |
701 | |
702 | kmb_write_mipi(kmb_dsi, MIPI_TXm_HS_SYNC_CFG(ctrl_no), value: sync_cfg); |
703 | kmb_write_mipi(kmb_dsi, MIPI_TXm_HS_CTRL(ctrl_no), value: ctrl); |
704 | } |
705 | |
706 | static u32 mipi_tx_init_cntrl(struct kmb_dsi *kmb_dsi, |
707 | struct mipi_ctrl_cfg *ctrl_cfg) |
708 | { |
709 | u32 ret = 0; |
710 | u8 active_vchannels = 0; |
711 | u8 frame_id, sect; |
712 | u32 bits_per_pclk = 0; |
713 | u32 word_count = 0; |
714 | struct mipi_tx_frame_cfg *frame; |
715 | |
716 | /* This is the order to initialize MIPI TX: |
717 | * 1. set frame section parameters |
718 | * 2. set frame specific parameters |
719 | * 3. connect lcd to mipi |
720 | * 4. multi channel fifo cfg |
721 | * 5. set mipitxcctrlcfg |
722 | */ |
723 | |
724 | for (frame_id = 0; frame_id < 4; frame_id++) { |
725 | frame = ctrl_cfg->tx_ctrl_cfg.frames[frame_id]; |
726 | |
727 | /* Find valid frame, assume only one valid frame */ |
728 | if (!frame) |
729 | continue; |
730 | |
731 | /* Frame Section configuration */ |
732 | /* TODO - assume there is only one valid section in a frame, |
733 | * so bits_per_pclk and word_count are only set once |
734 | */ |
735 | for (sect = 0; sect < MIPI_CTRL_VIRTUAL_CHANNELS; sect++) { |
736 | if (!frame->sections[sect]) |
737 | continue; |
738 | |
739 | ret = mipi_tx_fg_section_cfg(kmb_dsi, frame_id, section: sect, |
740 | frame_scfg: frame->sections[sect], |
741 | bits_per_pclk: &bits_per_pclk, |
742 | wc: &word_count); |
743 | if (ret) |
744 | return ret; |
745 | } |
746 | |
747 | /* Set frame specific parameters */ |
748 | mipi_tx_fg_cfg(kmb_dsi, frame_gen: frame_id, active_lanes: ctrl_cfg->active_lanes, |
749 | bpp: bits_per_pclk, wc: word_count, |
750 | lane_rate_mbps: ctrl_cfg->lane_rate_mbps, fg_cfg: frame); |
751 | |
752 | active_vchannels++; |
753 | |
754 | /* Stop iterating as only one virtual channel |
755 | * shall be used for LCD connection |
756 | */ |
757 | break; |
758 | } |
759 | |
760 | if (active_vchannels == 0) |
761 | return -EINVAL; |
762 | /* Multi-Channel FIFO Configuration */ |
763 | mipi_tx_multichannel_fifo_cfg(kmb_dsi, active_lanes: ctrl_cfg->active_lanes, vchannel_id: frame_id); |
764 | |
765 | /* Frame Generator Enable */ |
766 | mipi_tx_ctrl_cfg(kmb_dsi, fg_id: frame_id, ctrl_cfg); |
767 | |
768 | return ret; |
769 | } |
770 | |
771 | static void test_mode_send(struct kmb_dsi *kmb_dsi, u32 dphy_no, |
772 | u32 test_code, u32 test_data) |
773 | { |
774 | /* Steps to send test code: |
775 | * - set testclk HIGH |
776 | * - set testdin with test code |
777 | * - set testen HIGH |
778 | * - set testclk LOW |
779 | * - set testen LOW |
780 | */ |
781 | |
782 | /* Set testclk high */ |
783 | SET_DPHY_TEST_CTRL1_CLK(kmb_dsi, dphy_no); |
784 | |
785 | /* Set testdin */ |
786 | SET_TEST_DIN0_3(kmb_dsi, dphy_no, test_code); |
787 | |
788 | /* Set testen high */ |
789 | SET_DPHY_TEST_CTRL1_EN(kmb_dsi, dphy_no); |
790 | |
791 | /* Set testclk low */ |
792 | CLR_DPHY_TEST_CTRL1_CLK(kmb_dsi, dphy_no); |
793 | |
794 | /* Set testen low */ |
795 | CLR_DPHY_TEST_CTRL1_EN(kmb_dsi, dphy_no); |
796 | |
797 | if (test_code) { |
798 | /* Steps to send test data: |
799 | * - set testen LOW |
800 | * - set testclk LOW |
801 | * - set testdin with data |
802 | * - set testclk HIGH |
803 | */ |
804 | |
805 | /* Set testen low */ |
806 | CLR_DPHY_TEST_CTRL1_EN(kmb_dsi, dphy_no); |
807 | |
808 | /* Set testclk low */ |
809 | CLR_DPHY_TEST_CTRL1_CLK(kmb_dsi, dphy_no); |
810 | |
811 | /* Set data in testdin */ |
812 | kmb_write_mipi(kmb_dsi, |
813 | DPHY_TEST_DIN0_3 + ((dphy_no / 0x4) * 0x4), |
814 | value: test_data << ((dphy_no % 4) * 8)); |
815 | |
816 | /* Set testclk high */ |
817 | SET_DPHY_TEST_CTRL1_CLK(kmb_dsi, dphy_no); |
818 | } |
819 | } |
820 | |
821 | static inline void |
822 | set_test_mode_src_osc_freq_target_low_bits(struct kmb_dsi *kmb_dsi, |
823 | u32 dphy_no, |
824 | u32 freq) |
825 | { |
826 | /* Typical rise/fall time=166, refer Table 1207 databook, |
827 | * sr_osc_freq_target[7:0] |
828 | */ |
829 | test_mode_send(kmb_dsi, dphy_no, TEST_CODE_SLEW_RATE_DDL_CYCLES, |
830 | test_data: (freq & 0x7f)); |
831 | } |
832 | |
833 | static inline void |
834 | set_test_mode_src_osc_freq_target_hi_bits(struct kmb_dsi *kmb_dsi, |
835 | u32 dphy_no, |
836 | u32 freq) |
837 | { |
838 | u32 data; |
839 | |
840 | /* Flag this as high nibble */ |
841 | data = ((freq >> 6) & 0x1f) | (1 << 7); |
842 | |
843 | /* Typical rise/fall time=166, refer Table 1207 databook, |
844 | * sr_osc_freq_target[11:7] |
845 | */ |
846 | test_mode_send(kmb_dsi, dphy_no, TEST_CODE_SLEW_RATE_DDL_CYCLES, test_data: data); |
847 | } |
848 | |
849 | static void mipi_tx_get_vco_params(struct vco_params *vco) |
850 | { |
851 | int i; |
852 | |
853 | for (i = 0; i < ARRAY_SIZE(vco_table); i++) { |
854 | if (vco->freq < vco_table[i].freq) { |
855 | *vco = vco_table[i]; |
856 | return; |
857 | } |
858 | } |
859 | |
860 | WARN_ONCE(1, "Invalid vco freq = %u for PLL setup\n" , vco->freq); |
861 | } |
862 | |
863 | static void mipi_tx_pll_setup(struct kmb_dsi *kmb_dsi, u32 dphy_no, |
864 | u32 ref_clk_mhz, u32 target_freq_mhz) |
865 | { |
866 | u32 best_n = 0, best_m = 0; |
867 | u32 n = 0, m = 0, div = 0, delta, freq = 0, t_freq; |
868 | u32 best_freq_delta = 3000; |
869 | |
870 | /* pll_ref_clk: - valid range: 2~64 MHz; Typically 24 MHz |
871 | * Fvco: - valid range: 320~1250 MHz (Gen3 D-PHY) |
872 | * Fout: - valid range: 40~1250 MHz (Gen3 D-PHY) |
873 | * n: - valid range [0 15] |
874 | * N: - N = n + 1 |
875 | * -valid range: [1 16] |
876 | * -conditions: - (pll_ref_clk / N) >= 2 MHz |
877 | * -(pll_ref_clk / N) <= 8 MHz |
878 | * m: valid range [62 623] |
879 | * M: - M = m + 2 |
880 | * -valid range [64 625] |
881 | * -Fvco = (M/N) * pll_ref_clk |
882 | */ |
883 | struct vco_params vco_p = { |
884 | .range = 0, |
885 | .divider = 1, |
886 | }; |
887 | |
888 | vco_p.freq = target_freq_mhz; |
889 | mipi_tx_get_vco_params(vco: &vco_p); |
890 | |
891 | /* Search pll n parameter */ |
892 | for (n = PLL_N_MIN; n <= PLL_N_MAX; n++) { |
893 | /* Calculate the pll input frequency division ratio |
894 | * multiply by 1000 for precision - |
895 | * no floating point, add n for rounding |
896 | */ |
897 | div = ((ref_clk_mhz * 1000) + n) / (n + 1); |
898 | |
899 | /* Found a valid n parameter */ |
900 | if ((div < 2000 || div > 8000)) |
901 | continue; |
902 | |
903 | /* Search pll m parameter */ |
904 | for (m = PLL_M_MIN; m <= PLL_M_MAX; m++) { |
905 | /* Calculate the Fvco(DPHY PLL output frequency) |
906 | * using the current n,m params |
907 | */ |
908 | freq = div * (m + 2); |
909 | freq /= 1000; |
910 | |
911 | /* Trim the potential pll freq to max supported */ |
912 | if (freq > PLL_FVCO_MAX) |
913 | continue; |
914 | |
915 | delta = abs(freq - target_freq_mhz); |
916 | |
917 | /* Select the best (closest to target pll freq) |
918 | * n,m parameters so far |
919 | */ |
920 | if (delta < best_freq_delta) { |
921 | best_n = n; |
922 | best_m = m; |
923 | best_freq_delta = delta; |
924 | } |
925 | } |
926 | } |
927 | |
928 | /* Program vco_cntrl parameter |
929 | * PLL_VCO_Control[5:0] = pll_vco_cntrl_ovr, |
930 | * PLL_VCO_Control[6] = pll_vco_cntrl_ovr_en |
931 | */ |
932 | test_mode_send(kmb_dsi, dphy_no, TEST_CODE_PLL_VCO_CTRL, test_data: (vco_p.range |
933 | | (1 << 6))); |
934 | |
935 | /* Program m, n pll parameters */ |
936 | dev_dbg(kmb_dsi->dev, "m = %d n = %d\n" , best_m, best_n); |
937 | |
938 | /* PLL_Input_Divider_Ratio[3:0] = pll_n_ovr */ |
939 | test_mode_send(kmb_dsi, dphy_no, TEST_CODE_PLL_INPUT_DIVIDER, |
940 | test_data: (best_n & 0x0f)); |
941 | |
942 | /* m - low nibble PLL_Loop_Divider_Ratio[4:0] |
943 | * pll_m_ovr[4:0] |
944 | */ |
945 | test_mode_send(kmb_dsi, dphy_no, TEST_CODE_PLL_FEEDBACK_DIVIDER, |
946 | test_data: (best_m & 0x1f)); |
947 | |
948 | /* m - high nibble PLL_Loop_Divider_Ratio[4:0] |
949 | * pll_m_ovr[9:5] |
950 | */ |
951 | test_mode_send(kmb_dsi, dphy_no, TEST_CODE_PLL_FEEDBACK_DIVIDER, |
952 | test_data: ((best_m >> 5) & 0x1f) | PLL_FEEDBACK_DIVIDER_HIGH); |
953 | |
954 | /* Enable overwrite of n,m parameters :pll_n_ovr_en, pll_m_ovr_en */ |
955 | test_mode_send(kmb_dsi, dphy_no, TEST_CODE_PLL_OUTPUT_CLK_SEL, |
956 | test_data: (PLL_N_OVR_EN | PLL_M_OVR_EN)); |
957 | |
958 | /* Program Charge-Pump parameters */ |
959 | |
960 | /* pll_prop_cntrl-fixed values for prop_cntrl from DPHY doc */ |
961 | t_freq = target_freq_mhz * vco_p.divider; |
962 | test_mode_send(kmb_dsi, dphy_no, |
963 | TEST_CODE_PLL_PROPORTIONAL_CHARGE_PUMP_CTRL, |
964 | test_data: ((t_freq > 1150) ? 0x0C : 0x0B)); |
965 | |
966 | /* pll_int_cntrl-fixed value for int_cntrl from DPHY doc */ |
967 | test_mode_send(kmb_dsi, dphy_no, TEST_CODE_PLL_INTEGRAL_CHARGE_PUMP_CTRL, |
968 | test_data: 0x00); |
969 | |
970 | /* pll_gmp_cntrl-fixed value for gmp_cntrl from DPHY doci */ |
971 | test_mode_send(kmb_dsi, dphy_no, TEST_CODE_PLL_GMP_CTRL, test_data: 0x10); |
972 | |
973 | /* pll_cpbias_cntrl-fixed value for cpbias_cntrl from DPHY doc */ |
974 | test_mode_send(kmb_dsi, dphy_no, TEST_CODE_PLL_CHARGE_PUMP_BIAS, test_data: 0x10); |
975 | |
976 | /* pll_th1 -Lock Detector Phase error threshold, |
977 | * document gives fixed value |
978 | */ |
979 | test_mode_send(kmb_dsi, dphy_no, TEST_CODE_PLL_PHASE_ERR_CTRL, test_data: 0x02); |
980 | |
981 | /* PLL Lock Configuration */ |
982 | |
983 | /* pll_th2 - Lock Filter length, document gives fixed value */ |
984 | test_mode_send(kmb_dsi, dphy_no, TEST_CODE_PLL_LOCK_FILTER, test_data: 0x60); |
985 | |
986 | /* pll_th3- PLL Unlocking filter, document gives fixed value */ |
987 | test_mode_send(kmb_dsi, dphy_no, TEST_CODE_PLL_UNLOCK_FILTER, test_data: 0x03); |
988 | |
989 | /* pll_lock_sel-PLL Lock Detector Selection, |
990 | * document gives fixed value |
991 | */ |
992 | test_mode_send(kmb_dsi, dphy_no, TEST_CODE_PLL_LOCK_DETECTOR, test_data: 0x02); |
993 | } |
994 | |
995 | static void set_slewrate_gt_1500(struct kmb_dsi *kmb_dsi, u32 dphy_no) |
996 | { |
997 | u32 test_code = 0, test_data = 0; |
998 | /* Bypass slew rate calibration algorithm |
999 | * bits[1:0} srcal_en_ovr_en, srcal_en_ovr |
1000 | */ |
1001 | test_code = TEST_CODE_SLEW_RATE_OVERRIDE_CTRL; |
1002 | test_data = 0x02; |
1003 | test_mode_send(kmb_dsi, dphy_no, test_code, test_data); |
1004 | |
1005 | /* Disable slew rate calibration */ |
1006 | test_code = TEST_CODE_SLEW_RATE_DDL_LOOP_CTRL; |
1007 | test_data = 0x00; |
1008 | test_mode_send(kmb_dsi, dphy_no, test_code, test_data); |
1009 | } |
1010 | |
1011 | static void set_slewrate_gt_1000(struct kmb_dsi *kmb_dsi, u32 dphy_no) |
1012 | { |
1013 | u32 test_code = 0, test_data = 0; |
1014 | |
1015 | /* BitRate: > 1 Gbps && <= 1.5 Gbps: - slew rate control ON |
1016 | * typical rise/fall times: 166 ps |
1017 | */ |
1018 | |
1019 | /* Do not bypass slew rate calibration algorithm |
1020 | * bits[1:0}=srcal_en_ovr_en, srcal_en_ovr, bit[6]=sr_range |
1021 | */ |
1022 | test_code = TEST_CODE_SLEW_RATE_OVERRIDE_CTRL; |
1023 | test_data = (0x03 | (1 << 6)); |
1024 | test_mode_send(kmb_dsi, dphy_no, test_code, test_data); |
1025 | |
1026 | /* Enable slew rate calibration */ |
1027 | test_code = TEST_CODE_SLEW_RATE_DDL_LOOP_CTRL; |
1028 | test_data = 0x01; |
1029 | test_mode_send(kmb_dsi, dphy_no, test_code, test_data); |
1030 | |
1031 | /* Set sr_osc_freq_target[6:0] low nibble |
1032 | * typical rise/fall time=166, refer Table 1207 databook |
1033 | */ |
1034 | test_code = TEST_CODE_SLEW_RATE_DDL_CYCLES; |
1035 | test_data = (0x72f & 0x7f); |
1036 | test_mode_send(kmb_dsi, dphy_no, test_code, test_data); |
1037 | |
1038 | /* Set sr_osc_freq_target[11:7] high nibble |
1039 | * Typical rise/fall time=166, refer Table 1207 databook |
1040 | */ |
1041 | test_code = TEST_CODE_SLEW_RATE_DDL_CYCLES; |
1042 | test_data = ((0x72f >> 6) & 0x1f) | (1 << 7); |
1043 | test_mode_send(kmb_dsi, dphy_no, test_code, test_data); |
1044 | } |
1045 | |
1046 | static void set_slewrate_lt_1000(struct kmb_dsi *kmb_dsi, u32 dphy_no) |
1047 | { |
1048 | u32 test_code = 0, test_data = 0; |
1049 | |
1050 | /* lane_rate_mbps <= 1000 Mbps |
1051 | * BitRate: <= 1 Gbps: |
1052 | * - slew rate control ON |
1053 | * - typical rise/fall times: 225 ps |
1054 | */ |
1055 | |
1056 | /* Do not bypass slew rate calibration algorithm */ |
1057 | test_code = TEST_CODE_SLEW_RATE_OVERRIDE_CTRL; |
1058 | test_data = (0x03 | (1 << 6)); |
1059 | test_mode_send(kmb_dsi, dphy_no, test_code, test_data); |
1060 | |
1061 | /* Enable slew rate calibration */ |
1062 | test_code = TEST_CODE_SLEW_RATE_DDL_LOOP_CTRL; |
1063 | test_data = 0x01; |
1064 | test_mode_send(kmb_dsi, dphy_no, test_code, test_data); |
1065 | |
1066 | /* Typical rise/fall time=255, refer Table 1207 databook */ |
1067 | test_code = TEST_CODE_SLEW_RATE_DDL_CYCLES; |
1068 | test_data = (0x523 & 0x7f); |
1069 | test_mode_send(kmb_dsi, dphy_no, test_code, test_data); |
1070 | |
1071 | /* Set sr_osc_freq_target[11:7] high nibble */ |
1072 | test_code = TEST_CODE_SLEW_RATE_DDL_CYCLES; |
1073 | test_data = ((0x523 >> 6) & 0x1f) | (1 << 7); |
1074 | test_mode_send(kmb_dsi, dphy_no, test_code, test_data); |
1075 | } |
1076 | |
1077 | static void setup_pll(struct kmb_dsi *kmb_dsi, u32 dphy_no, |
1078 | struct mipi_ctrl_cfg *cfg) |
1079 | { |
1080 | u32 test_code = 0, test_data = 0; |
1081 | |
1082 | /* Set PLL regulator in bypass */ |
1083 | test_code = TEST_CODE_PLL_ANALOG_PROG; |
1084 | test_data = 0x01; |
1085 | test_mode_send(kmb_dsi, dphy_no, test_code, test_data); |
1086 | |
1087 | /* PLL Parameters Setup */ |
1088 | mipi_tx_pll_setup(kmb_dsi, dphy_no, ref_clk_mhz: cfg->ref_clk_khz / 1000, |
1089 | target_freq_mhz: cfg->lane_rate_mbps / 2); |
1090 | |
1091 | /* Set clksel */ |
1092 | kmb_write_bits_mipi(kmb_dsi, DPHY_INIT_CTRL1, PLL_CLKSEL_0, num_bits: 2, value: 0x01); |
1093 | |
1094 | /* Set pll_shadow_control */ |
1095 | kmb_set_bit_mipi(kmb_dsi, DPHY_INIT_CTRL1, PLL_SHADOW_CTRL); |
1096 | } |
1097 | |
1098 | static void set_lane_data_rate(struct kmb_dsi *kmb_dsi, u32 dphy_no, |
1099 | struct mipi_ctrl_cfg *cfg) |
1100 | { |
1101 | u32 i, test_code = 0, test_data = 0; |
1102 | |
1103 | for (i = 0; i < MIPI_DPHY_DEFAULT_BIT_RATES; i++) { |
1104 | if (mipi_hs_freq_range[i].default_bit_rate_mbps < |
1105 | cfg->lane_rate_mbps) |
1106 | continue; |
1107 | |
1108 | /* Send the test code and data */ |
1109 | /* bit[6:0] = hsfreqrange_ovr bit[7] = hsfreqrange_ovr_en */ |
1110 | test_code = TEST_CODE_HS_FREQ_RANGE_CFG; |
1111 | test_data = (mipi_hs_freq_range[i].hsfreqrange_code & 0x7f) | |
1112 | (1 << 7); |
1113 | test_mode_send(kmb_dsi, dphy_no, test_code, test_data); |
1114 | break; |
1115 | } |
1116 | } |
1117 | |
1118 | static void dphy_init_sequence(struct kmb_dsi *kmb_dsi, |
1119 | struct mipi_ctrl_cfg *cfg, u32 dphy_no, |
1120 | int active_lanes, enum dphy_mode mode) |
1121 | { |
1122 | u32 test_code = 0, test_data = 0, val; |
1123 | |
1124 | /* Set D-PHY in shutdown mode */ |
1125 | /* Assert RSTZ signal */ |
1126 | CLR_DPHY_INIT_CTRL0(kmb_dsi, dphy_no, RESETZ); |
1127 | |
1128 | /* Assert SHUTDOWNZ signal */ |
1129 | CLR_DPHY_INIT_CTRL0(kmb_dsi, dphy_no, SHUTDOWNZ); |
1130 | val = kmb_read_mipi(kmb_dsi, DPHY_INIT_CTRL0); |
1131 | |
1132 | /* Init D-PHY_n |
1133 | * Pulse testclear signal to make sure the d-phy configuration |
1134 | * starts from a clean base |
1135 | */ |
1136 | CLR_DPHY_TEST_CTRL0(kmb_dsi, dphy_no); |
1137 | ndelay(15); |
1138 | SET_DPHY_TEST_CTRL0(kmb_dsi, dphy_no); |
1139 | ndelay(15); |
1140 | CLR_DPHY_TEST_CTRL0(kmb_dsi, dphy_no); |
1141 | ndelay(15); |
1142 | |
1143 | /* Set mastermacro bit - Master or slave mode */ |
1144 | test_code = TEST_CODE_MULTIPLE_PHY_CTRL; |
1145 | |
1146 | /* DPHY has its own clock lane enabled (master) */ |
1147 | if (mode == MIPI_DPHY_MASTER) |
1148 | test_data = 0x01; |
1149 | else |
1150 | test_data = 0x00; |
1151 | |
1152 | /* Send the test code and data */ |
1153 | test_mode_send(kmb_dsi, dphy_no, test_code, test_data); |
1154 | |
1155 | /* Set the lane data rate */ |
1156 | set_lane_data_rate(kmb_dsi, dphy_no, cfg); |
1157 | |
1158 | /* High-Speed Tx Slew Rate Calibration |
1159 | * BitRate: > 1.5 Gbps && <= 2.5 Gbps: slew rate control OFF |
1160 | */ |
1161 | if (cfg->lane_rate_mbps > 1500) |
1162 | set_slewrate_gt_1500(kmb_dsi, dphy_no); |
1163 | else if (cfg->lane_rate_mbps > 1000) |
1164 | set_slewrate_gt_1000(kmb_dsi, dphy_no); |
1165 | else |
1166 | set_slewrate_lt_1000(kmb_dsi, dphy_no); |
1167 | |
1168 | /* Set cfgclkfreqrange */ |
1169 | val = (((cfg->cfg_clk_khz / 1000) - 17) * 4) & 0x3f; |
1170 | SET_DPHY_FREQ_CTRL0_3(kmb_dsi, dphy_no, val); |
1171 | |
1172 | /* Enable config clk for the corresponding d-phy */ |
1173 | kmb_set_bit_mipi(kmb_dsi, DPHY_CFG_CLK_EN, offset: dphy_no); |
1174 | |
1175 | /* PLL setup */ |
1176 | if (mode == MIPI_DPHY_MASTER) |
1177 | setup_pll(kmb_dsi, dphy_no, cfg); |
1178 | |
1179 | /* Send NORMAL OPERATION test code */ |
1180 | test_code = 0x0; |
1181 | test_data = 0x0; |
1182 | test_mode_send(kmb_dsi, dphy_no, test_code, test_data); |
1183 | |
1184 | /* Configure BASEDIR for data lanes |
1185 | * NOTE: basedir only applies to LANE_0 of each D-PHY. |
1186 | * The other lanes keep their direction based on the D-PHY type, |
1187 | * either Rx or Tx. |
1188 | * bits[5:0] - BaseDir: 1 = Rx |
1189 | * bits[9:6] - BaseDir: 0 = Tx |
1190 | */ |
1191 | kmb_write_bits_mipi(kmb_dsi, DPHY_INIT_CTRL2, offset: 0, num_bits: 9, value: 0x03f); |
1192 | ndelay(15); |
1193 | |
1194 | /* Enable CLOCK LANE |
1195 | * Clock lane should be enabled regardless of the direction |
1196 | * set for the D-PHY (Rx/Tx) |
1197 | */ |
1198 | kmb_set_bit_mipi(kmb_dsi, DPHY_INIT_CTRL2, offset: 12 + dphy_no); |
1199 | |
1200 | /* Enable DATA LANES */ |
1201 | kmb_write_bits_mipi(kmb_dsi, DPHY_ENABLE, offset: dphy_no * 2, num_bits: 2, |
1202 | value: ((1 << active_lanes) - 1)); |
1203 | |
1204 | ndelay(15); |
1205 | |
1206 | /* Take D-PHY out of shutdown mode */ |
1207 | /* Deassert SHUTDOWNZ signal */ |
1208 | SET_DPHY_INIT_CTRL0(kmb_dsi, dphy_no, SHUTDOWNZ); |
1209 | ndelay(15); |
1210 | |
1211 | /* Deassert RSTZ signal */ |
1212 | SET_DPHY_INIT_CTRL0(kmb_dsi, dphy_no, RESETZ); |
1213 | } |
1214 | |
1215 | static void dphy_wait_fsm(struct kmb_dsi *kmb_dsi, u32 dphy_no, |
1216 | enum dphy_tx_fsm fsm_state) |
1217 | { |
1218 | enum dphy_tx_fsm val = DPHY_TX_POWERDWN; |
1219 | int i = 0; |
1220 | int status = 1; |
1221 | |
1222 | do { |
1223 | test_mode_send(kmb_dsi, dphy_no, TEST_CODE_FSM_CONTROL, test_data: 0x80); |
1224 | |
1225 | val = GET_TEST_DOUT4_7(kmb_dsi, dphy_no); |
1226 | i++; |
1227 | if (i > TIMEOUT) { |
1228 | status = 0; |
1229 | break; |
1230 | } |
1231 | } while (val != fsm_state); |
1232 | |
1233 | dev_dbg(kmb_dsi->dev, "%s: dphy %d val = %x" , __func__, dphy_no, val); |
1234 | dev_dbg(kmb_dsi->dev, "* DPHY %d WAIT_FSM %s *" , |
1235 | dphy_no, status ? "SUCCESS" : "FAILED" ); |
1236 | } |
1237 | |
1238 | static void wait_init_done(struct kmb_dsi *kmb_dsi, u32 dphy_no, |
1239 | u32 active_lanes) |
1240 | { |
1241 | u32 stopstatedata = 0; |
1242 | u32 data_lanes = (1 << active_lanes) - 1; |
1243 | int i = 0; |
1244 | int status = 1; |
1245 | |
1246 | do { |
1247 | stopstatedata = GET_STOPSTATE_DATA(kmb_dsi, dphy_no) |
1248 | & data_lanes; |
1249 | |
1250 | /* TODO-need to add a time out and return failure */ |
1251 | i++; |
1252 | |
1253 | if (i > TIMEOUT) { |
1254 | status = 0; |
1255 | dev_dbg(kmb_dsi->dev, |
1256 | "! WAIT_INIT_DONE: TIMING OUT!(err_stat=%d)" , |
1257 | kmb_read_mipi(kmb_dsi, MIPI_DPHY_ERR_STAT6_7)); |
1258 | break; |
1259 | } |
1260 | } while (stopstatedata != data_lanes); |
1261 | |
1262 | dev_dbg(kmb_dsi->dev, "* DPHY %d INIT - %s *" , |
1263 | dphy_no, status ? "SUCCESS" : "FAILED" ); |
1264 | } |
1265 | |
1266 | static void wait_pll_lock(struct kmb_dsi *kmb_dsi, u32 dphy_no) |
1267 | { |
1268 | int i = 0; |
1269 | int status = 1; |
1270 | |
1271 | do { |
1272 | /* TODO-need to add a time out and return failure */ |
1273 | i++; |
1274 | if (i > TIMEOUT) { |
1275 | status = 0; |
1276 | dev_dbg(kmb_dsi->dev, "%s: timing out" , __func__); |
1277 | break; |
1278 | } |
1279 | } while (!GET_PLL_LOCK(kmb_dsi, dphy_no)); |
1280 | |
1281 | dev_dbg(kmb_dsi->dev, "* PLL Locked for DPHY %d - %s *" , |
1282 | dphy_no, status ? "SUCCESS" : "FAILED" ); |
1283 | } |
1284 | |
1285 | static u32 mipi_tx_init_dphy(struct kmb_dsi *kmb_dsi, |
1286 | struct mipi_ctrl_cfg *cfg) |
1287 | { |
1288 | u32 dphy_no = MIPI_DPHY6; |
1289 | |
1290 | /* Multiple D-PHYs needed */ |
1291 | if (cfg->active_lanes > MIPI_DPHY_D_LANES) { |
1292 | /* |
1293 | *Initialization for Tx aggregation mode is done according to |
1294 | *a. start init PHY1 |
1295 | *b. poll for PHY1 FSM state LOCK |
1296 | * b1. reg addr 0x03[3:0] - state_main[3:0] == 5 (LOCK) |
1297 | *c. poll for PHY1 calibrations done : |
1298 | * c1. termination calibration lower section: addr 0x22[5] |
1299 | * - rescal_done |
1300 | * c2. slewrate calibration (if data rate < = 1500 Mbps): |
1301 | * addr 0xA7[3:2] - srcal_done, sr_finished |
1302 | *d. start init PHY0 |
1303 | *e. poll for PHY0 stopstate |
1304 | *f. poll for PHY1 stopstate |
1305 | */ |
1306 | /* PHY #N+1 ('slave') */ |
1307 | |
1308 | dphy_init_sequence(kmb_dsi, cfg, dphy_no: dphy_no + 1, |
1309 | active_lanes: (cfg->active_lanes - MIPI_DPHY_D_LANES), |
1310 | mode: MIPI_DPHY_SLAVE); |
1311 | dphy_wait_fsm(kmb_dsi, dphy_no: dphy_no + 1, fsm_state: DPHY_TX_LOCK); |
1312 | |
1313 | /* PHY #N master */ |
1314 | dphy_init_sequence(kmb_dsi, cfg, dphy_no, MIPI_DPHY_D_LANES, |
1315 | mode: MIPI_DPHY_MASTER); |
1316 | |
1317 | /* Wait for DPHY init to complete */ |
1318 | wait_init_done(kmb_dsi, dphy_no, MIPI_DPHY_D_LANES); |
1319 | wait_init_done(kmb_dsi, dphy_no: dphy_no + 1, |
1320 | active_lanes: cfg->active_lanes - MIPI_DPHY_D_LANES); |
1321 | wait_pll_lock(kmb_dsi, dphy_no); |
1322 | wait_pll_lock(kmb_dsi, dphy_no: dphy_no + 1); |
1323 | dphy_wait_fsm(kmb_dsi, dphy_no, fsm_state: DPHY_TX_IDLE); |
1324 | } else { /* Single DPHY */ |
1325 | dphy_init_sequence(kmb_dsi, cfg, dphy_no, active_lanes: cfg->active_lanes, |
1326 | mode: MIPI_DPHY_MASTER); |
1327 | dphy_wait_fsm(kmb_dsi, dphy_no, fsm_state: DPHY_TX_IDLE); |
1328 | wait_init_done(kmb_dsi, dphy_no, active_lanes: cfg->active_lanes); |
1329 | wait_pll_lock(kmb_dsi, dphy_no); |
1330 | } |
1331 | |
1332 | return 0; |
1333 | } |
1334 | |
1335 | static void connect_lcd_to_mipi(struct kmb_dsi *kmb_dsi, |
1336 | struct drm_atomic_state *old_state) |
1337 | { |
1338 | struct regmap *msscam; |
1339 | |
1340 | msscam = syscon_regmap_lookup_by_compatible(s: "intel,keembay-msscam" ); |
1341 | if (IS_ERR(ptr: msscam)) { |
1342 | dev_dbg(kmb_dsi->dev, "failed to get msscam syscon" ); |
1343 | return; |
1344 | } |
1345 | drm_atomic_bridge_chain_enable(bridge: adv_bridge, state: old_state); |
1346 | /* DISABLE MIPI->CIF CONNECTION */ |
1347 | regmap_write(map: msscam, MSS_MIPI_CIF_CFG, val: 0); |
1348 | |
1349 | /* ENABLE LCD->MIPI CONNECTION */ |
1350 | regmap_write(map: msscam, MSS_LCD_MIPI_CFG, val: 1); |
1351 | /* DISABLE LCD->CIF LOOPBACK */ |
1352 | regmap_write(map: msscam, MSS_LOOPBACK_CFG, val: 1); |
1353 | } |
1354 | |
1355 | int kmb_dsi_mode_set(struct kmb_dsi *kmb_dsi, struct drm_display_mode *mode, |
1356 | int sys_clk_mhz, struct drm_atomic_state *old_state) |
1357 | { |
1358 | u64 data_rate; |
1359 | |
1360 | kmb_dsi->sys_clk_mhz = sys_clk_mhz; |
1361 | mipi_tx_init_cfg.active_lanes = MIPI_TX_ACTIVE_LANES; |
1362 | |
1363 | mipi_tx_frame0_sect_cfg.width_pixels = mode->crtc_hdisplay; |
1364 | mipi_tx_frame0_sect_cfg.height_lines = mode->crtc_vdisplay; |
1365 | mipitx_frame0_cfg.vsync_width = |
1366 | mode->crtc_vsync_end - mode->crtc_vsync_start; |
1367 | mipitx_frame0_cfg.v_backporch = |
1368 | mode->crtc_vtotal - mode->crtc_vsync_end; |
1369 | mipitx_frame0_cfg.v_frontporch = |
1370 | mode->crtc_vsync_start - mode->crtc_vdisplay; |
1371 | mipitx_frame0_cfg.hsync_width = |
1372 | mode->crtc_hsync_end - mode->crtc_hsync_start; |
1373 | mipitx_frame0_cfg.h_backporch = |
1374 | mode->crtc_htotal - mode->crtc_hsync_end; |
1375 | mipitx_frame0_cfg.h_frontporch = |
1376 | mode->crtc_hsync_start - mode->crtc_hdisplay; |
1377 | |
1378 | /* Lane rate = (vtotal*htotal*fps*bpp)/4 / 1000000 |
1379 | * to convert to Mbps |
1380 | */ |
1381 | data_rate = ((((u32)mode->crtc_vtotal * (u32)mode->crtc_htotal) * |
1382 | (u32)(drm_mode_vrefresh(mode)) * |
1383 | MIPI_TX_BPP) / mipi_tx_init_cfg.active_lanes) / 1000000; |
1384 | |
1385 | dev_dbg(kmb_dsi->dev, "data_rate=%u active_lanes=%d\n" , |
1386 | (u32)data_rate, mipi_tx_init_cfg.active_lanes); |
1387 | |
1388 | /* When late rate < 800, modeset fails with 4 lanes, |
1389 | * so switch to 2 lanes |
1390 | */ |
1391 | if (data_rate < 800) { |
1392 | mipi_tx_init_cfg.active_lanes = 2; |
1393 | mipi_tx_init_cfg.lane_rate_mbps = data_rate * 2; |
1394 | } else { |
1395 | mipi_tx_init_cfg.lane_rate_mbps = data_rate; |
1396 | } |
1397 | |
1398 | /* Initialize mipi controller */ |
1399 | mipi_tx_init_cntrl(kmb_dsi, ctrl_cfg: &mipi_tx_init_cfg); |
1400 | |
1401 | /* Dphy initialization */ |
1402 | mipi_tx_init_dphy(kmb_dsi, cfg: &mipi_tx_init_cfg); |
1403 | |
1404 | connect_lcd_to_mipi(kmb_dsi, old_state); |
1405 | dev_info(kmb_dsi->dev, "mipi hw initialized" ); |
1406 | |
1407 | return 0; |
1408 | } |
1409 | |
1410 | struct kmb_dsi *kmb_dsi_init(struct platform_device *pdev) |
1411 | { |
1412 | struct kmb_dsi *kmb_dsi; |
1413 | struct device *dev = get_device(dev: &pdev->dev); |
1414 | |
1415 | kmb_dsi = devm_kzalloc(dev, size: sizeof(*kmb_dsi), GFP_KERNEL); |
1416 | if (!kmb_dsi) { |
1417 | dev_err(dev, "failed to allocate kmb_dsi\n" ); |
1418 | return ERR_PTR(error: -ENOMEM); |
1419 | } |
1420 | |
1421 | kmb_dsi->host = dsi_host; |
1422 | kmb_dsi->host->ops = &kmb_dsi_host_ops; |
1423 | |
1424 | dsi_device->host = kmb_dsi->host; |
1425 | kmb_dsi->device = dsi_device; |
1426 | |
1427 | return kmb_dsi; |
1428 | } |
1429 | |
1430 | int kmb_dsi_encoder_init(struct drm_device *dev, struct kmb_dsi *kmb_dsi) |
1431 | { |
1432 | struct drm_encoder *encoder; |
1433 | struct drm_connector *connector; |
1434 | int ret = 0; |
1435 | |
1436 | encoder = &kmb_dsi->base; |
1437 | encoder->possible_crtcs = 1; |
1438 | encoder->possible_clones = 0; |
1439 | |
1440 | ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_DSI); |
1441 | if (ret) { |
1442 | dev_err(kmb_dsi->dev, "Failed to init encoder %d\n" , ret); |
1443 | return ret; |
1444 | } |
1445 | |
1446 | /* Link drm_bridge to encoder */ |
1447 | ret = drm_bridge_attach(encoder, bridge: adv_bridge, NULL, |
1448 | flags: DRM_BRIDGE_ATTACH_NO_CONNECTOR); |
1449 | if (ret) { |
1450 | drm_encoder_cleanup(encoder); |
1451 | return ret; |
1452 | } |
1453 | drm_info(dev, "Bridge attached : SUCCESS" ); |
1454 | connector = drm_bridge_connector_init(drm: dev, encoder); |
1455 | if (IS_ERR(ptr: connector)) { |
1456 | DRM_ERROR("Unable to create bridge connector" ); |
1457 | drm_encoder_cleanup(encoder); |
1458 | return PTR_ERR(ptr: connector); |
1459 | } |
1460 | drm_connector_attach_encoder(connector, encoder); |
1461 | return 0; |
1462 | } |
1463 | |
1464 | int kmb_dsi_map_mmio(struct kmb_dsi *kmb_dsi) |
1465 | { |
1466 | struct resource *res; |
1467 | struct device *dev = kmb_dsi->dev; |
1468 | |
1469 | res = platform_get_resource_byname(kmb_dsi->pdev, IORESOURCE_MEM, |
1470 | "mipi" ); |
1471 | if (!res) { |
1472 | dev_err(dev, "failed to get resource for mipi" ); |
1473 | return -ENOMEM; |
1474 | } |
1475 | kmb_dsi->mipi_mmio = devm_ioremap_resource(dev, res); |
1476 | if (IS_ERR(ptr: kmb_dsi->mipi_mmio)) { |
1477 | dev_err(dev, "failed to ioremap mipi registers" ); |
1478 | return PTR_ERR(ptr: kmb_dsi->mipi_mmio); |
1479 | } |
1480 | return 0; |
1481 | } |
1482 | |
1483 | static int kmb_dsi_clk_enable(struct kmb_dsi *kmb_dsi) |
1484 | { |
1485 | int ret; |
1486 | struct device *dev = kmb_dsi->dev; |
1487 | |
1488 | ret = clk_prepare_enable(clk: kmb_dsi->clk_mipi); |
1489 | if (ret) { |
1490 | dev_err(dev, "Failed to enable MIPI clock: %d\n" , ret); |
1491 | return ret; |
1492 | } |
1493 | |
1494 | ret = clk_prepare_enable(clk: kmb_dsi->clk_mipi_ecfg); |
1495 | if (ret) { |
1496 | dev_err(dev, "Failed to enable MIPI_ECFG clock: %d\n" , ret); |
1497 | return ret; |
1498 | } |
1499 | |
1500 | ret = clk_prepare_enable(clk: kmb_dsi->clk_mipi_cfg); |
1501 | if (ret) { |
1502 | dev_err(dev, "Failed to enable MIPI_CFG clock: %d\n" , ret); |
1503 | return ret; |
1504 | } |
1505 | |
1506 | dev_info(dev, "SUCCESS : enabled MIPI clocks\n" ); |
1507 | return 0; |
1508 | } |
1509 | |
1510 | int kmb_dsi_clk_init(struct kmb_dsi *kmb_dsi) |
1511 | { |
1512 | struct device *dev = kmb_dsi->dev; |
1513 | unsigned long clk; |
1514 | |
1515 | kmb_dsi->clk_mipi = devm_clk_get(dev, id: "clk_mipi" ); |
1516 | if (IS_ERR(ptr: kmb_dsi->clk_mipi)) { |
1517 | dev_err(dev, "devm_clk_get() failed clk_mipi\n" ); |
1518 | return PTR_ERR(ptr: kmb_dsi->clk_mipi); |
1519 | } |
1520 | |
1521 | kmb_dsi->clk_mipi_ecfg = devm_clk_get(dev, id: "clk_mipi_ecfg" ); |
1522 | if (IS_ERR(ptr: kmb_dsi->clk_mipi_ecfg)) { |
1523 | dev_err(dev, "devm_clk_get() failed clk_mipi_ecfg\n" ); |
1524 | return PTR_ERR(ptr: kmb_dsi->clk_mipi_ecfg); |
1525 | } |
1526 | |
1527 | kmb_dsi->clk_mipi_cfg = devm_clk_get(dev, id: "clk_mipi_cfg" ); |
1528 | if (IS_ERR(ptr: kmb_dsi->clk_mipi_cfg)) { |
1529 | dev_err(dev, "devm_clk_get() failed clk_mipi_cfg\n" ); |
1530 | return PTR_ERR(ptr: kmb_dsi->clk_mipi_cfg); |
1531 | } |
1532 | /* Set MIPI clock to 24 Mhz */ |
1533 | clk_set_rate(clk: kmb_dsi->clk_mipi, KMB_MIPI_DEFAULT_CLK); |
1534 | if (clk_get_rate(clk: kmb_dsi->clk_mipi) != KMB_MIPI_DEFAULT_CLK) { |
1535 | dev_err(dev, "failed to set to clk_mipi to %d\n" , |
1536 | KMB_MIPI_DEFAULT_CLK); |
1537 | return -1; |
1538 | } |
1539 | dev_dbg(dev, "clk_mipi = %ld\n" , clk_get_rate(kmb_dsi->clk_mipi)); |
1540 | |
1541 | clk = clk_get_rate(clk: kmb_dsi->clk_mipi_ecfg); |
1542 | if (clk != KMB_MIPI_DEFAULT_CFG_CLK) { |
1543 | /* Set MIPI_ECFG clock to 24 Mhz */ |
1544 | clk_set_rate(clk: kmb_dsi->clk_mipi_ecfg, KMB_MIPI_DEFAULT_CFG_CLK); |
1545 | clk = clk_get_rate(clk: kmb_dsi->clk_mipi_ecfg); |
1546 | if (clk != KMB_MIPI_DEFAULT_CFG_CLK) { |
1547 | dev_err(dev, "failed to set to clk_mipi_ecfg to %d\n" , |
1548 | KMB_MIPI_DEFAULT_CFG_CLK); |
1549 | return -1; |
1550 | } |
1551 | } |
1552 | |
1553 | clk = clk_get_rate(clk: kmb_dsi->clk_mipi_cfg); |
1554 | if (clk != KMB_MIPI_DEFAULT_CFG_CLK) { |
1555 | /* Set MIPI_CFG clock to 24 Mhz */ |
1556 | clk_set_rate(clk: kmb_dsi->clk_mipi_cfg, rate: 24000000); |
1557 | clk = clk_get_rate(clk: kmb_dsi->clk_mipi_cfg); |
1558 | if (clk != KMB_MIPI_DEFAULT_CFG_CLK) { |
1559 | dev_err(dev, "failed to set clk_mipi_cfg to %d\n" , |
1560 | KMB_MIPI_DEFAULT_CFG_CLK); |
1561 | return -1; |
1562 | } |
1563 | } |
1564 | |
1565 | return kmb_dsi_clk_enable(kmb_dsi); |
1566 | } |
1567 | |