1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (C) 2022 Marek Vasut <marex@denx.de>
4 */
5
6 #include <linux/clk.h>
7 #include <linux/media-bus-format.h>
8 #include <linux/mfd/syscon.h>
9 #include <linux/module.h>
10 #include <linux/of.h>
11 #include <linux/of_graph.h>
12 #include <linux/platform_device.h>
13 #include <linux/regmap.h>
14
15 #include <drm/drm_atomic_helper.h>
16 #include <drm/drm_bridge.h>
17 #include <drm/drm_of.h>
18 #include <drm/drm_panel.h>
19
20 #define LDB_CTRL_CH0_ENABLE BIT(0)
21 #define LDB_CTRL_CH0_DI_SELECT BIT(1)
22 #define LDB_CTRL_CH1_ENABLE BIT(2)
23 #define LDB_CTRL_CH1_DI_SELECT BIT(3)
24 #define LDB_CTRL_SPLIT_MODE BIT(4)
25 #define LDB_CTRL_CH0_DATA_WIDTH BIT(5)
26 #define LDB_CTRL_CH0_BIT_MAPPING BIT(6)
27 #define LDB_CTRL_CH1_DATA_WIDTH BIT(7)
28 #define LDB_CTRL_CH1_BIT_MAPPING BIT(8)
29 #define LDB_CTRL_DI0_VSYNC_POLARITY BIT(9)
30 #define LDB_CTRL_DI1_VSYNC_POLARITY BIT(10)
31 #define LDB_CTRL_REG_CH0_FIFO_RESET BIT(11)
32 #define LDB_CTRL_REG_CH1_FIFO_RESET BIT(12)
33 #define LDB_CTRL_ASYNC_FIFO_ENABLE BIT(24)
34 #define LDB_CTRL_ASYNC_FIFO_THRESHOLD_MASK GENMASK(27, 25)
35
36 #define LVDS_CTRL_CH0_EN BIT(0)
37 #define LVDS_CTRL_CH1_EN BIT(1)
38 /*
39 * LVDS_CTRL_LVDS_EN bit is poorly named in i.MX93 reference manual.
40 * Clear it to enable LVDS and set it to disable LVDS.
41 */
42 #define LVDS_CTRL_LVDS_EN BIT(1)
43 #define LVDS_CTRL_VBG_EN BIT(2)
44 #define LVDS_CTRL_HS_EN BIT(3)
45 #define LVDS_CTRL_PRE_EMPH_EN BIT(4)
46 #define LVDS_CTRL_PRE_EMPH_ADJ(n) (((n) & 0x7) << 5)
47 #define LVDS_CTRL_PRE_EMPH_ADJ_MASK GENMASK(7, 5)
48 #define LVDS_CTRL_CM_ADJ(n) (((n) & 0x7) << 8)
49 #define LVDS_CTRL_CM_ADJ_MASK GENMASK(10, 8)
50 #define LVDS_CTRL_CC_ADJ(n) (((n) & 0x7) << 11)
51 #define LVDS_CTRL_CC_ADJ_MASK GENMASK(13, 11)
52 #define LVDS_CTRL_SLEW_ADJ(n) (((n) & 0x7) << 14)
53 #define LVDS_CTRL_SLEW_ADJ_MASK GENMASK(16, 14)
54 #define LVDS_CTRL_VBG_ADJ(n) (((n) & 0x7) << 17)
55 #define LVDS_CTRL_VBG_ADJ_MASK GENMASK(19, 17)
56
57 enum fsl_ldb_devtype {
58 IMX6SX_LDB,
59 IMX8MP_LDB,
60 IMX93_LDB,
61 };
62
63 struct fsl_ldb_devdata {
64 u32 ldb_ctrl;
65 u32 lvds_ctrl;
66 bool lvds_en_bit;
67 bool single_ctrl_reg;
68 };
69
70 static const struct fsl_ldb_devdata fsl_ldb_devdata[] = {
71 [IMX6SX_LDB] = {
72 .ldb_ctrl = 0x18,
73 .single_ctrl_reg = true,
74 },
75 [IMX8MP_LDB] = {
76 .ldb_ctrl = 0x5c,
77 .lvds_ctrl = 0x128,
78 },
79 [IMX93_LDB] = {
80 .ldb_ctrl = 0x20,
81 .lvds_ctrl = 0x24,
82 .lvds_en_bit = true,
83 },
84 };
85
86 struct fsl_ldb {
87 struct device *dev;
88 struct drm_bridge bridge;
89 struct drm_bridge *panel_bridge;
90 struct clk *clk;
91 struct regmap *regmap;
92 const struct fsl_ldb_devdata *devdata;
93 bool ch0_enabled;
94 bool ch1_enabled;
95 };
96
fsl_ldb_is_dual(const struct fsl_ldb * fsl_ldb)97 static bool fsl_ldb_is_dual(const struct fsl_ldb *fsl_ldb)
98 {
99 return (fsl_ldb->ch0_enabled && fsl_ldb->ch1_enabled);
100 }
101
to_fsl_ldb(struct drm_bridge * bridge)102 static inline struct fsl_ldb *to_fsl_ldb(struct drm_bridge *bridge)
103 {
104 return container_of(bridge, struct fsl_ldb, bridge);
105 }
106
fsl_ldb_link_frequency(struct fsl_ldb * fsl_ldb,int clock)107 static unsigned long fsl_ldb_link_frequency(struct fsl_ldb *fsl_ldb, int clock)
108 {
109 if (fsl_ldb_is_dual(fsl_ldb))
110 return clock * 3500;
111 else
112 return clock * 7000;
113 }
114
fsl_ldb_attach(struct drm_bridge * bridge,enum drm_bridge_attach_flags flags)115 static int fsl_ldb_attach(struct drm_bridge *bridge,
116 enum drm_bridge_attach_flags flags)
117 {
118 struct fsl_ldb *fsl_ldb = to_fsl_ldb(bridge);
119
120 return drm_bridge_attach(bridge->encoder, fsl_ldb->panel_bridge,
121 bridge, flags);
122 }
123
fsl_ldb_atomic_enable(struct drm_bridge * bridge,struct drm_atomic_state * state)124 static void fsl_ldb_atomic_enable(struct drm_bridge *bridge,
125 struct drm_atomic_state *state)
126 {
127 struct fsl_ldb *fsl_ldb = to_fsl_ldb(bridge);
128 const struct drm_bridge_state *bridge_state;
129 const struct drm_crtc_state *crtc_state;
130 const struct drm_display_mode *mode;
131 struct drm_connector *connector;
132 struct drm_crtc *crtc;
133 unsigned long configured_link_freq;
134 unsigned long requested_link_freq;
135 bool lvds_format_24bpp;
136 bool lvds_format_jeida;
137 u32 reg;
138
139 /* Get the LVDS format from the bridge state. */
140 bridge_state = drm_atomic_get_new_bridge_state(state, bridge);
141
142 switch (bridge_state->output_bus_cfg.format) {
143 case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
144 lvds_format_24bpp = false;
145 lvds_format_jeida = true;
146 break;
147 case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:
148 lvds_format_24bpp = true;
149 lvds_format_jeida = true;
150 break;
151 case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
152 lvds_format_24bpp = true;
153 lvds_format_jeida = false;
154 break;
155 default:
156 /*
157 * Some bridges still don't set the correct LVDS bus pixel
158 * format, use SPWG24 default format until those are fixed.
159 */
160 lvds_format_24bpp = true;
161 lvds_format_jeida = false;
162 dev_warn(fsl_ldb->dev,
163 "Unsupported LVDS bus format 0x%04x, please check output bridge driver. Falling back to SPWG24.\n",
164 bridge_state->output_bus_cfg.format);
165 break;
166 }
167
168 /*
169 * Retrieve the CRTC adjusted mode. This requires a little dance to go
170 * from the bridge to the encoder, to the connector and to the CRTC.
171 */
172 connector = drm_atomic_get_new_connector_for_encoder(state,
173 bridge->encoder);
174 crtc = drm_atomic_get_new_connector_state(state, connector)->crtc;
175 crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
176 mode = &crtc_state->adjusted_mode;
177
178 requested_link_freq = fsl_ldb_link_frequency(fsl_ldb, mode->clock);
179 clk_set_rate(fsl_ldb->clk, requested_link_freq);
180
181 configured_link_freq = clk_get_rate(fsl_ldb->clk);
182 if (configured_link_freq != requested_link_freq)
183 dev_warn(fsl_ldb->dev, "Configured LDB clock (%lu Hz) does not match requested LVDS clock: %lu Hz\n",
184 configured_link_freq,
185 requested_link_freq);
186
187 clk_prepare_enable(fsl_ldb->clk);
188
189 /* Program LDB_CTRL */
190 reg = (fsl_ldb->ch0_enabled ? LDB_CTRL_CH0_ENABLE : 0) |
191 (fsl_ldb->ch1_enabled ? LDB_CTRL_CH1_ENABLE : 0) |
192 (fsl_ldb_is_dual(fsl_ldb) ? LDB_CTRL_SPLIT_MODE : 0);
193
194 if (lvds_format_24bpp)
195 reg |= (fsl_ldb->ch0_enabled ? LDB_CTRL_CH0_DATA_WIDTH : 0) |
196 (fsl_ldb->ch1_enabled ? LDB_CTRL_CH1_DATA_WIDTH : 0);
197
198 if (lvds_format_jeida)
199 reg |= (fsl_ldb->ch0_enabled ? LDB_CTRL_CH0_BIT_MAPPING : 0) |
200 (fsl_ldb->ch1_enabled ? LDB_CTRL_CH1_BIT_MAPPING : 0);
201
202 if (mode->flags & DRM_MODE_FLAG_PVSYNC)
203 reg |= (fsl_ldb->ch0_enabled ? LDB_CTRL_DI0_VSYNC_POLARITY : 0) |
204 (fsl_ldb->ch1_enabled ? LDB_CTRL_DI1_VSYNC_POLARITY : 0);
205
206 regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->ldb_ctrl, reg);
207
208 if (fsl_ldb->devdata->single_ctrl_reg)
209 return;
210
211 /* Program LVDS_CTRL */
212 reg = LVDS_CTRL_CC_ADJ(2) | LVDS_CTRL_PRE_EMPH_EN |
213 LVDS_CTRL_PRE_EMPH_ADJ(3) | LVDS_CTRL_VBG_EN;
214 regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->lvds_ctrl, reg);
215
216 /* Wait for VBG to stabilize. */
217 usleep_range(15, 20);
218
219 reg |= (fsl_ldb->ch0_enabled ? LVDS_CTRL_CH0_EN : 0) |
220 (fsl_ldb->ch1_enabled ? LVDS_CTRL_CH1_EN : 0);
221
222 regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->lvds_ctrl, reg);
223 }
224
fsl_ldb_atomic_disable(struct drm_bridge * bridge,struct drm_atomic_state * state)225 static void fsl_ldb_atomic_disable(struct drm_bridge *bridge,
226 struct drm_atomic_state *state)
227 {
228 struct fsl_ldb *fsl_ldb = to_fsl_ldb(bridge);
229
230 /* Stop channel(s). */
231 if (fsl_ldb->devdata->lvds_en_bit)
232 /* Set LVDS_CTRL_LVDS_EN bit to disable. */
233 regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->lvds_ctrl,
234 LVDS_CTRL_LVDS_EN);
235 else
236 if (!fsl_ldb->devdata->single_ctrl_reg)
237 regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->lvds_ctrl, 0);
238 regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->ldb_ctrl, 0);
239
240 clk_disable_unprepare(fsl_ldb->clk);
241 }
242
243 #define MAX_INPUT_SEL_FORMATS 1
244 static u32 *
fsl_ldb_atomic_get_input_bus_fmts(struct drm_bridge * bridge,struct drm_bridge_state * bridge_state,struct drm_crtc_state * crtc_state,struct drm_connector_state * conn_state,u32 output_fmt,unsigned int * num_input_fmts)245 fsl_ldb_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
246 struct drm_bridge_state *bridge_state,
247 struct drm_crtc_state *crtc_state,
248 struct drm_connector_state *conn_state,
249 u32 output_fmt,
250 unsigned int *num_input_fmts)
251 {
252 u32 *input_fmts;
253
254 *num_input_fmts = 0;
255
256 input_fmts = kcalloc(MAX_INPUT_SEL_FORMATS, sizeof(*input_fmts),
257 GFP_KERNEL);
258 if (!input_fmts)
259 return NULL;
260
261 input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24;
262 *num_input_fmts = MAX_INPUT_SEL_FORMATS;
263
264 return input_fmts;
265 }
266
267 static enum drm_mode_status
fsl_ldb_mode_valid(struct drm_bridge * bridge,const struct drm_display_info * info,const struct drm_display_mode * mode)268 fsl_ldb_mode_valid(struct drm_bridge *bridge,
269 const struct drm_display_info *info,
270 const struct drm_display_mode *mode)
271 {
272 struct fsl_ldb *fsl_ldb = to_fsl_ldb(bridge);
273
274 if (mode->clock > (fsl_ldb_is_dual(fsl_ldb) ? 160000 : 80000))
275 return MODE_CLOCK_HIGH;
276
277 return MODE_OK;
278 }
279
280 static const struct drm_bridge_funcs funcs = {
281 .attach = fsl_ldb_attach,
282 .atomic_enable = fsl_ldb_atomic_enable,
283 .atomic_disable = fsl_ldb_atomic_disable,
284 .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
285 .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
286 .atomic_get_input_bus_fmts = fsl_ldb_atomic_get_input_bus_fmts,
287 .atomic_reset = drm_atomic_helper_bridge_reset,
288 .mode_valid = fsl_ldb_mode_valid,
289 };
290
fsl_ldb_probe(struct platform_device * pdev)291 static int fsl_ldb_probe(struct platform_device *pdev)
292 {
293 struct device *dev = &pdev->dev;
294 struct device_node *panel_node;
295 struct device_node *remote1, *remote2;
296 struct drm_panel *panel;
297 struct fsl_ldb *fsl_ldb;
298 int dual_link;
299
300 fsl_ldb = devm_kzalloc(dev, sizeof(*fsl_ldb), GFP_KERNEL);
301 if (!fsl_ldb)
302 return -ENOMEM;
303
304 fsl_ldb->devdata = of_device_get_match_data(dev);
305 if (!fsl_ldb->devdata)
306 return -EINVAL;
307
308 fsl_ldb->dev = &pdev->dev;
309 fsl_ldb->bridge.funcs = &funcs;
310 fsl_ldb->bridge.of_node = dev->of_node;
311
312 fsl_ldb->clk = devm_clk_get(dev, "ldb");
313 if (IS_ERR(fsl_ldb->clk))
314 return PTR_ERR(fsl_ldb->clk);
315
316 fsl_ldb->regmap = syscon_node_to_regmap(dev->of_node->parent);
317 if (IS_ERR(fsl_ldb->regmap))
318 return PTR_ERR(fsl_ldb->regmap);
319
320 /* Locate the remote ports and the panel node */
321 remote1 = of_graph_get_remote_node(dev->of_node, 1, 0);
322 remote2 = of_graph_get_remote_node(dev->of_node, 2, 0);
323 fsl_ldb->ch0_enabled = (remote1 != NULL);
324 fsl_ldb->ch1_enabled = (remote2 != NULL);
325 panel_node = of_node_get(remote1 ? remote1 : remote2);
326 of_node_put(remote1);
327 of_node_put(remote2);
328
329 if (!fsl_ldb->ch0_enabled && !fsl_ldb->ch1_enabled) {
330 of_node_put(panel_node);
331 return dev_err_probe(dev, -ENXIO, "No panel node found");
332 }
333
334 dev_dbg(dev, "Using %s\n",
335 fsl_ldb_is_dual(fsl_ldb) ? "dual-link mode" :
336 fsl_ldb->ch0_enabled ? "channel 0" : "channel 1");
337
338 panel = of_drm_find_panel(panel_node);
339 of_node_put(panel_node);
340 if (IS_ERR(panel))
341 return PTR_ERR(panel);
342
343 fsl_ldb->panel_bridge = devm_drm_panel_bridge_add(dev, panel);
344 if (IS_ERR(fsl_ldb->panel_bridge))
345 return PTR_ERR(fsl_ldb->panel_bridge);
346
347
348 if (fsl_ldb_is_dual(fsl_ldb)) {
349 struct device_node *port1, *port2;
350
351 port1 = of_graph_get_port_by_id(dev->of_node, 1);
352 port2 = of_graph_get_port_by_id(dev->of_node, 2);
353 dual_link = drm_of_lvds_get_dual_link_pixel_order(port1, port2);
354 of_node_put(port1);
355 of_node_put(port2);
356
357 if (dual_link < 0)
358 return dev_err_probe(dev, dual_link,
359 "Error getting dual link configuration\n");
360
361 /* Only DRM_LVDS_DUAL_LINK_ODD_EVEN_PIXELS is supported */
362 if (dual_link == DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS) {
363 dev_err(dev, "LVDS channel pixel swap not supported.\n");
364 return -EINVAL;
365 }
366 }
367
368 platform_set_drvdata(pdev, fsl_ldb);
369
370 drm_bridge_add(&fsl_ldb->bridge);
371
372 return 0;
373 }
374
fsl_ldb_remove(struct platform_device * pdev)375 static void fsl_ldb_remove(struct platform_device *pdev)
376 {
377 struct fsl_ldb *fsl_ldb = platform_get_drvdata(pdev);
378
379 drm_bridge_remove(&fsl_ldb->bridge);
380 }
381
382 static const struct of_device_id fsl_ldb_match[] = {
383 { .compatible = "fsl,imx6sx-ldb",
384 .data = &fsl_ldb_devdata[IMX6SX_LDB], },
385 { .compatible = "fsl,imx8mp-ldb",
386 .data = &fsl_ldb_devdata[IMX8MP_LDB], },
387 { .compatible = "fsl,imx93-ldb",
388 .data = &fsl_ldb_devdata[IMX93_LDB], },
389 { /* sentinel */ },
390 };
391 MODULE_DEVICE_TABLE(of, fsl_ldb_match);
392
393 static struct platform_driver fsl_ldb_driver = {
394 .probe = fsl_ldb_probe,
395 .remove = fsl_ldb_remove,
396 .driver = {
397 .name = "fsl-ldb",
398 .of_match_table = fsl_ldb_match,
399 },
400 };
401 module_platform_driver(fsl_ldb_driver);
402
403 MODULE_AUTHOR("Marek Vasut <marex@denx.de>");
404 MODULE_DESCRIPTION("Freescale i.MX8MP LDB");
405 MODULE_LICENSE("GPL");
406