1 // SPDX-License-Identifier: GPL-2.0
3 * rcar_lvds.c -- R-Car LVDS Encoder
5 * Copyright (C) 2013-2018 Renesas Electronics Corporation
7 * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
10 #include <linux/clk.h>
11 #include <linux/delay.h>
14 #include <linux/of_device.h>
15 #include <linux/of_graph.h>
16 #include <linux/platform_device.h>
17 #include <linux/slab.h>
19 #include <drm/drm_atomic.h>
20 #include <drm/drm_atomic_helper.h>
21 #include <drm/drm_bridge.h>
22 #include <drm/drm_crtc_helper.h>
23 #include <drm/drm_panel.h>
25 #include "rcar_lvds_regs.h"
27 /* Keep in sync with the LVDCR0.LVMD hardware register values. */
29 RCAR_LVDS_MODE_JEIDA
= 0,
30 RCAR_LVDS_MODE_MIRROR
= 1,
31 RCAR_LVDS_MODE_VESA
= 4,
34 #define RCAR_LVDS_QUIRK_LANES (1 << 0) /* LVDS lanes 1 and 3 inverted */
35 #define RCAR_LVDS_QUIRK_GEN2_PLLCR (1 << 1) /* LVDPLLCR has gen2 layout */
36 #define RCAR_LVDS_QUIRK_GEN3_LVEN (1 << 2) /* LVEN bit needs to be set */
37 /* on R8A77970/R8A7799x */
39 struct rcar_lvds_device_info
{
46 const struct rcar_lvds_device_info
*info
;
48 struct drm_bridge bridge
;
50 struct drm_bridge
*next_bridge
;
51 struct drm_connector connector
;
52 struct drm_panel
*panel
;
58 struct drm_display_mode display_mode
;
59 enum rcar_lvds_mode mode
;
62 #define bridge_to_rcar_lvds(bridge) \
63 container_of(bridge, struct rcar_lvds, bridge)
65 #define connector_to_rcar_lvds(connector) \
66 container_of(connector, struct rcar_lvds, connector)
68 static void rcar_lvds_write(struct rcar_lvds
*lvds
, u32 reg
, u32 data
)
70 iowrite32(data
, lvds
->mmio
+ reg
);
73 /* -----------------------------------------------------------------------------
77 static int rcar_lvds_connector_get_modes(struct drm_connector
*connector
)
79 struct rcar_lvds
*lvds
= connector_to_rcar_lvds(connector
);
81 return drm_panel_get_modes(lvds
->panel
);
84 static int rcar_lvds_connector_atomic_check(struct drm_connector
*connector
,
85 struct drm_connector_state
*state
)
87 struct rcar_lvds
*lvds
= connector_to_rcar_lvds(connector
);
88 const struct drm_display_mode
*panel_mode
;
89 struct drm_crtc_state
*crtc_state
;
94 if (list_empty(&connector
->modes
)) {
95 dev_dbg(lvds
->dev
, "connector: empty modes list\n");
99 panel_mode
= list_first_entry(&connector
->modes
,
100 struct drm_display_mode
, head
);
102 /* We're not allowed to modify the resolution. */
103 crtc_state
= drm_atomic_get_crtc_state(state
->state
, state
->crtc
);
104 if (IS_ERR(crtc_state
))
105 return PTR_ERR(crtc_state
);
107 if (crtc_state
->mode
.hdisplay
!= panel_mode
->hdisplay
||
108 crtc_state
->mode
.vdisplay
!= panel_mode
->vdisplay
)
111 /* The flat panel mode is fixed, just copy it to the adjusted mode. */
112 drm_mode_copy(&crtc_state
->adjusted_mode
, panel_mode
);
117 static const struct drm_connector_helper_funcs rcar_lvds_conn_helper_funcs
= {
118 .get_modes
= rcar_lvds_connector_get_modes
,
119 .atomic_check
= rcar_lvds_connector_atomic_check
,
122 static const struct drm_connector_funcs rcar_lvds_conn_funcs
= {
123 .reset
= drm_atomic_helper_connector_reset
,
124 .fill_modes
= drm_helper_probe_single_connector_modes
,
125 .destroy
= drm_connector_cleanup
,
126 .atomic_duplicate_state
= drm_atomic_helper_connector_duplicate_state
,
127 .atomic_destroy_state
= drm_atomic_helper_connector_destroy_state
,
130 /* -----------------------------------------------------------------------------
134 static u32
rcar_lvds_lvdpllcr_gen2(unsigned int freq
)
137 return LVDPLLCR_CEEN
| LVDPLLCR_COSEL
| LVDPLLCR_PLLDLYCNT_38M
;
138 else if (freq
< 61000)
139 return LVDPLLCR_CEEN
| LVDPLLCR_COSEL
| LVDPLLCR_PLLDLYCNT_60M
;
140 else if (freq
< 121000)
141 return LVDPLLCR_CEEN
| LVDPLLCR_COSEL
| LVDPLLCR_PLLDLYCNT_121M
;
143 return LVDPLLCR_PLLDLYCNT_150M
;
146 static u32
rcar_lvds_lvdpllcr_gen3(unsigned int freq
)
149 return LVDPLLCR_PLLDIVCNT_42M
;
150 else if (freq
< 85000)
151 return LVDPLLCR_PLLDIVCNT_85M
;
152 else if (freq
< 128000)
153 return LVDPLLCR_PLLDIVCNT_128M
;
155 return LVDPLLCR_PLLDIVCNT_148M
;
158 static void rcar_lvds_enable(struct drm_bridge
*bridge
)
160 struct rcar_lvds
*lvds
= bridge_to_rcar_lvds(bridge
);
161 const struct drm_display_mode
*mode
= &lvds
->display_mode
;
163 * FIXME: We should really retrieve the CRTC through the state, but how
164 * do we get a state pointer?
166 struct drm_crtc
*crtc
= lvds
->bridge
.encoder
->crtc
;
172 WARN_ON(lvds
->enabled
);
174 ret
= clk_prepare_enable(lvds
->clock
);
179 * Hardcode the channels and control signals routing for now.
186 rcar_lvds_write(lvds
, LVDCTRCR
, LVDCTRCR_CTR3SEL_ZERO
|
187 LVDCTRCR_CTR2SEL_DISP
| LVDCTRCR_CTR1SEL_VSYNC
|
188 LVDCTRCR_CTR0SEL_HSYNC
);
190 if (lvds
->info
->quirks
& RCAR_LVDS_QUIRK_LANES
)
191 lvdhcr
= LVDCHCR_CHSEL_CH(0, 0) | LVDCHCR_CHSEL_CH(1, 3)
192 | LVDCHCR_CHSEL_CH(2, 2) | LVDCHCR_CHSEL_CH(3, 1);
194 lvdhcr
= LVDCHCR_CHSEL_CH(0, 0) | LVDCHCR_CHSEL_CH(1, 1)
195 | LVDCHCR_CHSEL_CH(2, 2) | LVDCHCR_CHSEL_CH(3, 3);
197 rcar_lvds_write(lvds
, LVDCHCR
, lvdhcr
);
199 /* PLL clock configuration. */
200 if (lvds
->info
->quirks
& RCAR_LVDS_QUIRK_GEN2_PLLCR
)
201 lvdpllcr
= rcar_lvds_lvdpllcr_gen2(mode
->clock
);
203 lvdpllcr
= rcar_lvds_lvdpllcr_gen3(mode
->clock
);
204 rcar_lvds_write(lvds
, LVDPLLCR
, lvdpllcr
);
206 /* Set the LVDS mode and select the input. */
207 lvdcr0
= lvds
->mode
<< LVDCR0_LVMD_SHIFT
;
208 if (drm_crtc_index(crtc
) == 2)
209 lvdcr0
|= LVDCR0_DUSEL
;
210 rcar_lvds_write(lvds
, LVDCR0
, lvdcr0
);
212 /* Turn all the channels on. */
213 rcar_lvds_write(lvds
, LVDCR1
,
214 LVDCR1_CHSTBY(3) | LVDCR1_CHSTBY(2) |
215 LVDCR1_CHSTBY(1) | LVDCR1_CHSTBY(0) | LVDCR1_CLKSTBY
);
217 if (lvds
->info
->gen
< 3) {
218 /* Enable LVDS operation and turn the bias circuitry on. */
219 lvdcr0
|= LVDCR0_BEN
| LVDCR0_LVEN
;
220 rcar_lvds_write(lvds
, LVDCR0
, lvdcr0
);
223 /* Turn the PLL on. */
224 lvdcr0
|= LVDCR0_PLLON
;
225 rcar_lvds_write(lvds
, LVDCR0
, lvdcr0
);
227 if (lvds
->info
->gen
> 2) {
228 /* Set LVDS normal mode. */
229 lvdcr0
|= LVDCR0_PWD
;
230 rcar_lvds_write(lvds
, LVDCR0
, lvdcr0
);
233 if (lvds
->info
->quirks
& RCAR_LVDS_QUIRK_GEN3_LVEN
) {
234 /* Turn on the LVDS PHY. */
235 lvdcr0
|= LVDCR0_LVEN
;
236 rcar_lvds_write(lvds
, LVDCR0
, lvdcr0
);
239 /* Wait for the startup delay. */
240 usleep_range(100, 150);
242 /* Turn the output on. */
243 lvdcr0
|= LVDCR0_LVRES
;
244 rcar_lvds_write(lvds
, LVDCR0
, lvdcr0
);
247 drm_panel_prepare(lvds
->panel
);
248 drm_panel_enable(lvds
->panel
);
251 lvds
->enabled
= true;
254 static void rcar_lvds_disable(struct drm_bridge
*bridge
)
256 struct rcar_lvds
*lvds
= bridge_to_rcar_lvds(bridge
);
258 WARN_ON(!lvds
->enabled
);
261 drm_panel_disable(lvds
->panel
);
262 drm_panel_unprepare(lvds
->panel
);
265 rcar_lvds_write(lvds
, LVDCR0
, 0);
266 rcar_lvds_write(lvds
, LVDCR1
, 0);
268 clk_disable_unprepare(lvds
->clock
);
270 lvds
->enabled
= false;
273 static bool rcar_lvds_mode_fixup(struct drm_bridge
*bridge
,
274 const struct drm_display_mode
*mode
,
275 struct drm_display_mode
*adjusted_mode
)
278 * The internal LVDS encoder has a restricted clock frequency operating
279 * range (31MHz to 148.5MHz). Clamp the clock accordingly.
281 adjusted_mode
->clock
= clamp(adjusted_mode
->clock
, 31000, 148500);
286 static void rcar_lvds_get_lvds_mode(struct rcar_lvds
*lvds
)
288 struct drm_display_info
*info
= &lvds
->connector
.display_info
;
289 enum rcar_lvds_mode mode
;
292 * There is no API yet to retrieve LVDS mode from a bridge, only panels
298 if (!info
->num_bus_formats
|| !info
->bus_formats
) {
299 dev_err(lvds
->dev
, "no LVDS bus format reported\n");
303 switch (info
->bus_formats
[0]) {
304 case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG
:
305 case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA
:
306 mode
= RCAR_LVDS_MODE_JEIDA
;
308 case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG
:
309 mode
= RCAR_LVDS_MODE_VESA
;
312 dev_err(lvds
->dev
, "unsupported LVDS bus format 0x%04x\n",
313 info
->bus_formats
[0]);
317 if (info
->bus_flags
& DRM_BUS_FLAG_DATA_LSB_TO_MSB
)
318 mode
|= RCAR_LVDS_MODE_MIRROR
;
323 static void rcar_lvds_mode_set(struct drm_bridge
*bridge
,
324 struct drm_display_mode
*mode
,
325 struct drm_display_mode
*adjusted_mode
)
327 struct rcar_lvds
*lvds
= bridge_to_rcar_lvds(bridge
);
329 WARN_ON(lvds
->enabled
);
331 lvds
->display_mode
= *adjusted_mode
;
333 rcar_lvds_get_lvds_mode(lvds
);
336 static int rcar_lvds_attach(struct drm_bridge
*bridge
)
338 struct rcar_lvds
*lvds
= bridge_to_rcar_lvds(bridge
);
339 struct drm_connector
*connector
= &lvds
->connector
;
340 struct drm_encoder
*encoder
= bridge
->encoder
;
343 /* If we have a next bridge just attach it. */
344 if (lvds
->next_bridge
)
345 return drm_bridge_attach(bridge
->encoder
, lvds
->next_bridge
,
348 /* Otherwise we have a panel, create a connector. */
349 ret
= drm_connector_init(bridge
->dev
, connector
, &rcar_lvds_conn_funcs
,
350 DRM_MODE_CONNECTOR_LVDS
);
354 drm_connector_helper_add(connector
, &rcar_lvds_conn_helper_funcs
);
356 ret
= drm_connector_attach_encoder(connector
, encoder
);
360 return drm_panel_attach(lvds
->panel
, connector
);
363 static void rcar_lvds_detach(struct drm_bridge
*bridge
)
365 struct rcar_lvds
*lvds
= bridge_to_rcar_lvds(bridge
);
368 drm_panel_detach(lvds
->panel
);
371 static const struct drm_bridge_funcs rcar_lvds_bridge_ops
= {
372 .attach
= rcar_lvds_attach
,
373 .detach
= rcar_lvds_detach
,
374 .enable
= rcar_lvds_enable
,
375 .disable
= rcar_lvds_disable
,
376 .mode_fixup
= rcar_lvds_mode_fixup
,
377 .mode_set
= rcar_lvds_mode_set
,
380 /* -----------------------------------------------------------------------------
384 static int rcar_lvds_parse_dt(struct rcar_lvds
*lvds
)
386 struct device_node
*local_output
= NULL
;
387 struct device_node
*remote_input
= NULL
;
388 struct device_node
*remote
= NULL
;
389 struct device_node
*node
;
390 bool is_bridge
= false;
393 local_output
= of_graph_get_endpoint_by_regs(lvds
->dev
->of_node
, 1, 0);
395 dev_dbg(lvds
->dev
, "unconnected port@1\n");
400 * Locate the connected entity and infer its type from the number of
403 remote
= of_graph_get_remote_port_parent(local_output
);
405 dev_dbg(lvds
->dev
, "unconnected endpoint %pOF\n", local_output
);
410 if (!of_device_is_available(remote
)) {
411 dev_dbg(lvds
->dev
, "connected entity %pOF is disabled\n",
417 remote_input
= of_graph_get_remote_endpoint(local_output
);
419 for_each_endpoint_of_node(remote
, node
) {
420 if (node
!= remote_input
) {
422 * We've found one endpoint other than the input, this
432 lvds
->next_bridge
= of_drm_find_bridge(remote
);
433 if (!lvds
->next_bridge
)
436 lvds
->panel
= of_drm_find_panel(remote
);
437 if (IS_ERR(lvds
->panel
))
438 ret
= PTR_ERR(lvds
->panel
);
442 of_node_put(local_output
);
443 of_node_put(remote_input
);
449 static int rcar_lvds_probe(struct platform_device
*pdev
)
451 struct rcar_lvds
*lvds
;
452 struct resource
*mem
;
455 lvds
= devm_kzalloc(&pdev
->dev
, sizeof(*lvds
), GFP_KERNEL
);
459 platform_set_drvdata(pdev
, lvds
);
461 lvds
->dev
= &pdev
->dev
;
462 lvds
->info
= of_device_get_match_data(&pdev
->dev
);
463 lvds
->enabled
= false;
465 ret
= rcar_lvds_parse_dt(lvds
);
469 lvds
->bridge
.driver_private
= lvds
;
470 lvds
->bridge
.funcs
= &rcar_lvds_bridge_ops
;
471 lvds
->bridge
.of_node
= pdev
->dev
.of_node
;
473 mem
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
474 lvds
->mmio
= devm_ioremap_resource(&pdev
->dev
, mem
);
475 if (IS_ERR(lvds
->mmio
))
476 return PTR_ERR(lvds
->mmio
);
478 lvds
->clock
= devm_clk_get(&pdev
->dev
, NULL
);
479 if (IS_ERR(lvds
->clock
)) {
480 dev_err(&pdev
->dev
, "failed to get clock\n");
481 return PTR_ERR(lvds
->clock
);
484 drm_bridge_add(&lvds
->bridge
);
489 static int rcar_lvds_remove(struct platform_device
*pdev
)
491 struct rcar_lvds
*lvds
= platform_get_drvdata(pdev
);
493 drm_bridge_remove(&lvds
->bridge
);
498 static const struct rcar_lvds_device_info rcar_lvds_gen2_info
= {
500 .quirks
= RCAR_LVDS_QUIRK_GEN2_PLLCR
,
503 static const struct rcar_lvds_device_info rcar_lvds_r8a7790_info
= {
505 .quirks
= RCAR_LVDS_QUIRK_GEN2_PLLCR
| RCAR_LVDS_QUIRK_LANES
,
508 static const struct rcar_lvds_device_info rcar_lvds_gen3_info
= {
512 static const struct rcar_lvds_device_info rcar_lvds_r8a77970_info
= {
514 .quirks
= RCAR_LVDS_QUIRK_GEN2_PLLCR
| RCAR_LVDS_QUIRK_GEN3_LVEN
,
517 static const struct of_device_id rcar_lvds_of_table
[] = {
518 { .compatible
= "renesas,r8a7743-lvds", .data
= &rcar_lvds_gen2_info
},
519 { .compatible
= "renesas,r8a7790-lvds", .data
= &rcar_lvds_r8a7790_info
},
520 { .compatible
= "renesas,r8a7791-lvds", .data
= &rcar_lvds_gen2_info
},
521 { .compatible
= "renesas,r8a7793-lvds", .data
= &rcar_lvds_gen2_info
},
522 { .compatible
= "renesas,r8a7795-lvds", .data
= &rcar_lvds_gen3_info
},
523 { .compatible
= "renesas,r8a7796-lvds", .data
= &rcar_lvds_gen3_info
},
524 { .compatible
= "renesas,r8a77970-lvds", .data
= &rcar_lvds_r8a77970_info
},
528 MODULE_DEVICE_TABLE(of
, rcar_lvds_of_table
);
530 static struct platform_driver rcar_lvds_platform_driver
= {
531 .probe
= rcar_lvds_probe
,
532 .remove
= rcar_lvds_remove
,
535 .of_match_table
= rcar_lvds_of_table
,
539 module_platform_driver(rcar_lvds_platform_driver
);
541 MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
542 MODULE_DESCRIPTION("Renesas R-Car LVDS Encoder Driver");
543 MODULE_LICENSE("GPL");