1 // SPDX-License-Identifier: GPL-2.0
3 * RZ/G2L MIPI DSI Encoder Driver
5 * Copyright (C) 2022 Renesas Electronics Corporation
8 #include <linux/delay.h>
10 #include <linux/iopoll.h>
11 #include <linux/module.h>
13 #include <linux/of_graph.h>
14 #include <linux/platform_device.h>
15 #include <linux/pm_runtime.h>
16 #include <linux/reset.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_mipi_dsi.h>
23 #include <drm/drm_of.h>
24 #include <drm/drm_panel.h>
25 #include <drm/drm_probe_helper.h>
27 #include "rzg2l_mipi_dsi_regs.h"
29 struct rzg2l_mipi_dsi
{
33 struct reset_control
*rstc
;
34 struct reset_control
*arstc
;
35 struct reset_control
*prstc
;
37 struct mipi_dsi_host host
;
38 struct drm_bridge bridge
;
39 struct drm_bridge
*next_bridge
;
43 enum mipi_dsi_pixel_format format
;
44 unsigned int num_data_lanes
;
46 unsigned long mode_flags
;
49 static inline struct rzg2l_mipi_dsi
*
50 bridge_to_rzg2l_mipi_dsi(struct drm_bridge
*bridge
)
52 return container_of(bridge
, struct rzg2l_mipi_dsi
, bridge
);
55 static inline struct rzg2l_mipi_dsi
*
56 host_to_rzg2l_mipi_dsi(struct mipi_dsi_host
*host
)
58 return container_of(host
, struct rzg2l_mipi_dsi
, host
);
61 struct rzg2l_mipi_dsi_timings
{
62 unsigned long hsfreq_max
;
76 static const struct rzg2l_mipi_dsi_timings rzg2l_mipi_dsi_global_timings
[] = {
106 .hsfreq_max
= 250000,
120 .hsfreq_max
= 360000,
134 .hsfreq_max
= 720000,
148 .hsfreq_max
= 1500000,
163 static void rzg2l_mipi_dsi_phy_write(struct rzg2l_mipi_dsi
*dsi
, u32 reg
, u32 data
)
165 iowrite32(data
, dsi
->mmio
+ reg
);
168 static void rzg2l_mipi_dsi_link_write(struct rzg2l_mipi_dsi
*dsi
, u32 reg
, u32 data
)
170 iowrite32(data
, dsi
->mmio
+ LINK_REG_OFFSET
+ reg
);
173 static u32
rzg2l_mipi_dsi_phy_read(struct rzg2l_mipi_dsi
*dsi
, u32 reg
)
175 return ioread32(dsi
->mmio
+ reg
);
178 static u32
rzg2l_mipi_dsi_link_read(struct rzg2l_mipi_dsi
*dsi
, u32 reg
)
180 return ioread32(dsi
->mmio
+ LINK_REG_OFFSET
+ reg
);
183 /* -----------------------------------------------------------------------------
187 static int rzg2l_mipi_dsi_dphy_init(struct rzg2l_mipi_dsi
*dsi
,
188 unsigned long hsfreq
)
190 const struct rzg2l_mipi_dsi_timings
*dphy_timings
;
199 /* All DSI global operation timings are set with recommended setting */
200 for (i
= 0; i
< ARRAY_SIZE(rzg2l_mipi_dsi_global_timings
); ++i
) {
201 dphy_timings
= &rzg2l_mipi_dsi_global_timings
[i
];
202 if (hsfreq
<= dphy_timings
->hsfreq_max
)
206 /* Initializing DPHY before accessing LINK */
207 dphyctrl0
= DSIDPHYCTRL0_CAL_EN_HSRX_OFS
| DSIDPHYCTRL0_CMN_MASTER_EN
|
208 DSIDPHYCTRL0_RE_VDD_DETVCCQLV18
| DSIDPHYCTRL0_EN_BGR
;
210 rzg2l_mipi_dsi_phy_write(dsi
, DSIDPHYCTRL0
, dphyctrl0
);
211 usleep_range(20, 30);
213 dphyctrl0
|= DSIDPHYCTRL0_EN_LDO1200
;
214 rzg2l_mipi_dsi_phy_write(dsi
, DSIDPHYCTRL0
, dphyctrl0
);
215 usleep_range(10, 20);
217 dphytim0
= DSIDPHYTIM0_TCLK_MISS(0) |
218 DSIDPHYTIM0_T_INIT(dphy_timings
->t_init
);
219 dphytim1
= DSIDPHYTIM1_THS_PREPARE(dphy_timings
->ths_prepare
) |
220 DSIDPHYTIM1_TCLK_PREPARE(dphy_timings
->tclk_prepare
) |
221 DSIDPHYTIM1_THS_SETTLE(0) |
222 DSIDPHYTIM1_TCLK_SETTLE(0);
223 dphytim2
= DSIDPHYTIM2_TCLK_TRAIL(dphy_timings
->tclk_trail
) |
224 DSIDPHYTIM2_TCLK_POST(dphy_timings
->tclk_post
) |
225 DSIDPHYTIM2_TCLK_PRE(dphy_timings
->tclk_pre
) |
226 DSIDPHYTIM2_TCLK_ZERO(dphy_timings
->tclk_zero
);
227 dphytim3
= DSIDPHYTIM3_TLPX(dphy_timings
->tlpx
) |
228 DSIDPHYTIM3_THS_EXIT(dphy_timings
->ths_exit
) |
229 DSIDPHYTIM3_THS_TRAIL(dphy_timings
->ths_trail
) |
230 DSIDPHYTIM3_THS_ZERO(dphy_timings
->ths_zero
);
232 rzg2l_mipi_dsi_phy_write(dsi
, DSIDPHYTIM0
, dphytim0
);
233 rzg2l_mipi_dsi_phy_write(dsi
, DSIDPHYTIM1
, dphytim1
);
234 rzg2l_mipi_dsi_phy_write(dsi
, DSIDPHYTIM2
, dphytim2
);
235 rzg2l_mipi_dsi_phy_write(dsi
, DSIDPHYTIM3
, dphytim3
);
237 ret
= reset_control_deassert(dsi
->rstc
);
246 static void rzg2l_mipi_dsi_dphy_exit(struct rzg2l_mipi_dsi
*dsi
)
250 dphyctrl0
= rzg2l_mipi_dsi_phy_read(dsi
, DSIDPHYCTRL0
);
252 dphyctrl0
&= ~(DSIDPHYCTRL0_EN_LDO1200
| DSIDPHYCTRL0_EN_BGR
);
253 rzg2l_mipi_dsi_phy_write(dsi
, DSIDPHYCTRL0
, dphyctrl0
);
255 reset_control_assert(dsi
->rstc
);
258 static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi
*dsi
,
259 const struct drm_display_mode
*mode
)
261 unsigned long hsfreq
;
273 * Relationship between hsclk and vclk must follow
274 * vclk * bpp = hsclk * 8 * lanes
275 * where vclk: video clock (Hz)
276 * bpp: video pixel bit depth
277 * hsclk: DSI HS Byte clock frequency (Hz)
278 * lanes: number of data lanes
280 * hsclk(bit) = hsclk(byte) * 8
282 bpp
= mipi_dsi_pixel_format_to_bpp(dsi
->format
);
283 hsfreq
= (mode
->clock
* bpp
* 8) / (8 * dsi
->lanes
);
285 ret
= pm_runtime_resume_and_get(dsi
->dev
);
289 clk_set_rate(dsi
->vclk
, mode
->clock
* 1000);
291 ret
= rzg2l_mipi_dsi_dphy_init(dsi
, hsfreq
);
295 /* Enable Data lanes and Clock lanes */
296 txsetr
= TXSETR_DLEN
| TXSETR_NUMLANEUSE(dsi
->lanes
- 1) | TXSETR_CLEN
;
297 rzg2l_mipi_dsi_link_write(dsi
, TXSETR
, txsetr
);
300 * Global timings characteristic depends on high speed Clock Frequency
301 * Currently MIPI DSI-IF just supports maximum FHD@60 with:
302 * - videoclock = 148.5 (MHz)
303 * - bpp: maximum 24bpp
304 * - data lanes: maximum 4 lanes
305 * Therefore maximum hsclk will be 891 Mbps.
307 if (hsfreq
> 445500) {
312 } else if (hsfreq
> 250000) {
324 clstptsetr
= CLSTPTSETR_CLKKPT(clkkpt
) | CLSTPTSETR_CLKBFHT(clkbfht
) |
325 CLSTPTSETR_CLKSTPT(clkstpt
);
326 rzg2l_mipi_dsi_link_write(dsi
, CLSTPTSETR
, clstptsetr
);
328 lptrnstsetr
= LPTRNSTSETR_GOLPBKT(golpbkt
);
329 rzg2l_mipi_dsi_link_write(dsi
, LPTRNSTSETR
, lptrnstsetr
);
334 rzg2l_mipi_dsi_dphy_exit(dsi
);
335 pm_runtime_put(dsi
->dev
);
340 static void rzg2l_mipi_dsi_stop(struct rzg2l_mipi_dsi
*dsi
)
342 rzg2l_mipi_dsi_dphy_exit(dsi
);
343 pm_runtime_put(dsi
->dev
);
346 static void rzg2l_mipi_dsi_set_display_timing(struct rzg2l_mipi_dsi
*dsi
,
347 const struct drm_display_mode
*mode
)
358 /* Configuration for Pixel Packet */
359 dsi_format
= mipi_dsi_pixel_format_to_bpp(dsi
->format
);
360 switch (dsi_format
) {
362 vich1ppsetr
= VICH1PPSETR_DT_RGB24
;
365 vich1ppsetr
= VICH1PPSETR_DT_RGB18
;
369 if ((dsi
->mode_flags
& MIPI_DSI_MODE_VIDEO_SYNC_PULSE
) &&
370 !(dsi
->mode_flags
& MIPI_DSI_MODE_VIDEO_BURST
))
371 vich1ppsetr
|= VICH1PPSETR_TXESYNC_PULSE
;
373 rzg2l_mipi_dsi_link_write(dsi
, VICH1PPSETR
, vich1ppsetr
);
375 /* Configuration for Video Parameters */
376 vich1vssetr
= VICH1VSSETR_VACTIVE(mode
->vdisplay
) |
377 VICH1VSSETR_VSA(mode
->vsync_end
- mode
->vsync_start
);
378 vich1vssetr
|= (mode
->flags
& DRM_MODE_FLAG_PVSYNC
) ?
379 VICH1VSSETR_VSPOL_HIGH
: VICH1VSSETR_VSPOL_LOW
;
381 vich1vpsetr
= VICH1VPSETR_VFP(mode
->vsync_start
- mode
->vdisplay
) |
382 VICH1VPSETR_VBP(mode
->vtotal
- mode
->vsync_end
);
384 vich1hssetr
= VICH1HSSETR_HACTIVE(mode
->hdisplay
) |
385 VICH1HSSETR_HSA(mode
->hsync_end
- mode
->hsync_start
);
386 vich1hssetr
|= (mode
->flags
& DRM_MODE_FLAG_PHSYNC
) ?
387 VICH1HSSETR_HSPOL_HIGH
: VICH1HSSETR_HSPOL_LOW
;
389 vich1hpsetr
= VICH1HPSETR_HFP(mode
->hsync_start
- mode
->hdisplay
) |
390 VICH1HPSETR_HBP(mode
->htotal
- mode
->hsync_end
);
392 rzg2l_mipi_dsi_link_write(dsi
, VICH1VSSETR
, vich1vssetr
);
393 rzg2l_mipi_dsi_link_write(dsi
, VICH1VPSETR
, vich1vpsetr
);
394 rzg2l_mipi_dsi_link_write(dsi
, VICH1HSSETR
, vich1hssetr
);
395 rzg2l_mipi_dsi_link_write(dsi
, VICH1HPSETR
, vich1hpsetr
);
398 * Configuration for Delay Value
399 * Delay value based on 2 ranges of video clock.
400 * 74.25MHz is videoclock of HD@60p or FHD@30p
402 if (mode
->clock
> 74250) {
410 if (dsi
->mode_flags
& MIPI_DSI_CLOCK_NON_CONTINUOUS
)
415 rzg2l_mipi_dsi_link_write(dsi
, VICH1SET1R
,
416 VICH1SET1R_DLY(delay
[index
]));
419 static int rzg2l_mipi_dsi_start_hs_clock(struct rzg2l_mipi_dsi
*dsi
)
426 is_clk_cont
= !(dsi
->mode_flags
& MIPI_DSI_CLOCK_NON_CONTINUOUS
);
429 hsclksetr
= HSCLKSETR_HSCLKRUN_HS
| (is_clk_cont
?
430 HSCLKSETR_HSCLKMODE_CONT
:
431 HSCLKSETR_HSCLKMODE_NON_CONT
);
432 rzg2l_mipi_dsi_link_write(dsi
, HSCLKSETR
, hsclksetr
);
435 ret
= read_poll_timeout(rzg2l_mipi_dsi_link_read
, status
,
436 status
& PLSR_CLLP2HS
,
437 2000, 20000, false, dsi
, PLSR
);
439 dev_err(dsi
->dev
, "failed to start HS clock\n");
444 dev_dbg(dsi
->dev
, "Start High Speed Clock with %s clock mode",
445 is_clk_cont
? "continuous" : "non-continuous");
450 static int rzg2l_mipi_dsi_stop_hs_clock(struct rzg2l_mipi_dsi
*dsi
)
456 is_clk_cont
= !(dsi
->mode_flags
& MIPI_DSI_CLOCK_NON_CONTINUOUS
);
459 rzg2l_mipi_dsi_link_write(dsi
, HSCLKSETR
,
460 is_clk_cont
? HSCLKSETR_HSCLKMODE_CONT
:
461 HSCLKSETR_HSCLKMODE_NON_CONT
);
464 ret
= read_poll_timeout(rzg2l_mipi_dsi_link_read
, status
,
465 status
& PLSR_CLHS2LP
,
466 2000, 20000, false, dsi
, PLSR
);
468 dev_err(dsi
->dev
, "failed to stop HS clock\n");
476 static int rzg2l_mipi_dsi_start_video(struct rzg2l_mipi_dsi
*dsi
)
482 /* Configuration for Blanking sequence and start video input*/
483 vich1set0r
= VICH1SET0R_HFPNOLP
| VICH1SET0R_HBPNOLP
|
484 VICH1SET0R_HSANOLP
| VICH1SET0R_VSTART
;
485 rzg2l_mipi_dsi_link_write(dsi
, VICH1SET0R
, vich1set0r
);
487 ret
= read_poll_timeout(rzg2l_mipi_dsi_link_read
, status
,
488 status
& VICH1SR_VIRDY
,
489 2000, 20000, false, dsi
, VICH1SR
);
491 dev_err(dsi
->dev
, "Failed to start video signal input\n");
496 static int rzg2l_mipi_dsi_stop_video(struct rzg2l_mipi_dsi
*dsi
)
501 rzg2l_mipi_dsi_link_write(dsi
, VICH1SET0R
, VICH1SET0R_VSTPAFT
);
502 ret
= read_poll_timeout(rzg2l_mipi_dsi_link_read
, status
,
503 (status
& VICH1SR_STOP
) && (!(status
& VICH1SR_RUNNING
)),
504 2000, 20000, false, dsi
, VICH1SR
);
508 ret
= read_poll_timeout(rzg2l_mipi_dsi_link_read
, status
,
509 !(status
& LINKSR_HSBUSY
),
510 2000, 20000, false, dsi
, LINKSR
);
517 dev_err(dsi
->dev
, "Failed to stop video signal input\n");
521 /* -----------------------------------------------------------------------------
525 static int rzg2l_mipi_dsi_attach(struct drm_bridge
*bridge
,
526 enum drm_bridge_attach_flags flags
)
528 struct rzg2l_mipi_dsi
*dsi
= bridge_to_rzg2l_mipi_dsi(bridge
);
530 return drm_bridge_attach(bridge
->encoder
, dsi
->next_bridge
, bridge
,
534 static void rzg2l_mipi_dsi_atomic_enable(struct drm_bridge
*bridge
,
535 struct drm_bridge_state
*old_bridge_state
)
537 struct drm_atomic_state
*state
= old_bridge_state
->base
.state
;
538 struct rzg2l_mipi_dsi
*dsi
= bridge_to_rzg2l_mipi_dsi(bridge
);
539 const struct drm_display_mode
*mode
;
540 struct drm_connector
*connector
;
541 struct drm_crtc
*crtc
;
544 connector
= drm_atomic_get_new_connector_for_encoder(state
, bridge
->encoder
);
545 crtc
= drm_atomic_get_new_connector_state(state
, connector
)->crtc
;
546 mode
= &drm_atomic_get_new_crtc_state(state
, crtc
)->adjusted_mode
;
548 ret
= rzg2l_mipi_dsi_startup(dsi
, mode
);
552 rzg2l_mipi_dsi_set_display_timing(dsi
, mode
);
554 ret
= rzg2l_mipi_dsi_start_hs_clock(dsi
);
558 ret
= rzg2l_mipi_dsi_start_video(dsi
);
565 rzg2l_mipi_dsi_stop_hs_clock(dsi
);
567 rzg2l_mipi_dsi_stop(dsi
);
570 static void rzg2l_mipi_dsi_atomic_disable(struct drm_bridge
*bridge
,
571 struct drm_bridge_state
*old_bridge_state
)
573 struct rzg2l_mipi_dsi
*dsi
= bridge_to_rzg2l_mipi_dsi(bridge
);
575 rzg2l_mipi_dsi_stop_video(dsi
);
576 rzg2l_mipi_dsi_stop_hs_clock(dsi
);
577 rzg2l_mipi_dsi_stop(dsi
);
580 static enum drm_mode_status
581 rzg2l_mipi_dsi_bridge_mode_valid(struct drm_bridge
*bridge
,
582 const struct drm_display_info
*info
,
583 const struct drm_display_mode
*mode
)
585 if (mode
->clock
> 148500)
586 return MODE_CLOCK_HIGH
;
591 static const struct drm_bridge_funcs rzg2l_mipi_dsi_bridge_ops
= {
592 .attach
= rzg2l_mipi_dsi_attach
,
593 .atomic_duplicate_state
= drm_atomic_helper_bridge_duplicate_state
,
594 .atomic_destroy_state
= drm_atomic_helper_bridge_destroy_state
,
595 .atomic_reset
= drm_atomic_helper_bridge_reset
,
596 .atomic_enable
= rzg2l_mipi_dsi_atomic_enable
,
597 .atomic_disable
= rzg2l_mipi_dsi_atomic_disable
,
598 .mode_valid
= rzg2l_mipi_dsi_bridge_mode_valid
,
601 /* -----------------------------------------------------------------------------
605 static int rzg2l_mipi_dsi_host_attach(struct mipi_dsi_host
*host
,
606 struct mipi_dsi_device
*device
)
608 struct rzg2l_mipi_dsi
*dsi
= host_to_rzg2l_mipi_dsi(host
);
611 if (device
->lanes
> dsi
->num_data_lanes
) {
613 "Number of lines of device (%u) exceeds host (%u)\n",
614 device
->lanes
, dsi
->num_data_lanes
);
618 switch (mipi_dsi_pixel_format_to_bpp(device
->format
)) {
623 dev_err(dsi
->dev
, "Unsupported format 0x%04x\n", device
->format
);
627 dsi
->lanes
= device
->lanes
;
628 dsi
->format
= device
->format
;
629 dsi
->mode_flags
= device
->mode_flags
;
631 dsi
->next_bridge
= devm_drm_of_get_bridge(dsi
->dev
, dsi
->dev
->of_node
,
633 if (IS_ERR(dsi
->next_bridge
)) {
634 ret
= PTR_ERR(dsi
->next_bridge
);
635 dev_err(dsi
->dev
, "failed to get next bridge: %d\n", ret
);
639 drm_bridge_add(&dsi
->bridge
);
644 static int rzg2l_mipi_dsi_host_detach(struct mipi_dsi_host
*host
,
645 struct mipi_dsi_device
*device
)
647 struct rzg2l_mipi_dsi
*dsi
= host_to_rzg2l_mipi_dsi(host
);
649 drm_bridge_remove(&dsi
->bridge
);
654 static const struct mipi_dsi_host_ops rzg2l_mipi_dsi_host_ops
= {
655 .attach
= rzg2l_mipi_dsi_host_attach
,
656 .detach
= rzg2l_mipi_dsi_host_detach
,
659 /* -----------------------------------------------------------------------------
663 static int __maybe_unused
rzg2l_mipi_pm_runtime_suspend(struct device
*dev
)
665 struct rzg2l_mipi_dsi
*dsi
= dev_get_drvdata(dev
);
667 reset_control_assert(dsi
->prstc
);
668 reset_control_assert(dsi
->arstc
);
673 static int __maybe_unused
rzg2l_mipi_pm_runtime_resume(struct device
*dev
)
675 struct rzg2l_mipi_dsi
*dsi
= dev_get_drvdata(dev
);
678 ret
= reset_control_deassert(dsi
->arstc
);
682 ret
= reset_control_deassert(dsi
->prstc
);
684 reset_control_assert(dsi
->arstc
);
689 static const struct dev_pm_ops rzg2l_mipi_pm_ops
= {
690 SET_RUNTIME_PM_OPS(rzg2l_mipi_pm_runtime_suspend
, rzg2l_mipi_pm_runtime_resume
, NULL
)
693 /* -----------------------------------------------------------------------------
697 static int rzg2l_mipi_dsi_probe(struct platform_device
*pdev
)
699 unsigned int num_data_lanes
;
700 struct rzg2l_mipi_dsi
*dsi
;
704 dsi
= devm_kzalloc(&pdev
->dev
, sizeof(*dsi
), GFP_KERNEL
);
708 platform_set_drvdata(pdev
, dsi
);
709 dsi
->dev
= &pdev
->dev
;
711 ret
= drm_of_get_data_lanes_count_ep(dsi
->dev
->of_node
, 1, 0, 1, 4);
713 return dev_err_probe(dsi
->dev
, ret
,
714 "missing or invalid data-lanes property\n");
716 num_data_lanes
= ret
;
718 dsi
->mmio
= devm_platform_ioremap_resource(pdev
, 0);
719 if (IS_ERR(dsi
->mmio
))
720 return PTR_ERR(dsi
->mmio
);
722 dsi
->vclk
= devm_clk_get(dsi
->dev
, "vclk");
723 if (IS_ERR(dsi
->vclk
))
724 return PTR_ERR(dsi
->vclk
);
726 dsi
->rstc
= devm_reset_control_get_exclusive(dsi
->dev
, "rst");
727 if (IS_ERR(dsi
->rstc
))
728 return dev_err_probe(dsi
->dev
, PTR_ERR(dsi
->rstc
),
729 "failed to get rst\n");
731 dsi
->arstc
= devm_reset_control_get_exclusive(dsi
->dev
, "arst");
732 if (IS_ERR(dsi
->arstc
))
733 return dev_err_probe(&pdev
->dev
, PTR_ERR(dsi
->arstc
),
734 "failed to get arst\n");
736 dsi
->prstc
= devm_reset_control_get_exclusive(dsi
->dev
, "prst");
737 if (IS_ERR(dsi
->prstc
))
738 return dev_err_probe(dsi
->dev
, PTR_ERR(dsi
->prstc
),
739 "failed to get prst\n");
741 platform_set_drvdata(pdev
, dsi
);
743 pm_runtime_enable(dsi
->dev
);
745 ret
= pm_runtime_resume_and_get(dsi
->dev
);
750 * TXSETR register can be read only after DPHY init. But during probe
751 * mode->clock and format are not available. So initialize DPHY with
752 * timing parameters for 80Mbps.
754 ret
= rzg2l_mipi_dsi_dphy_init(dsi
, 80000);
758 txsetr
= rzg2l_mipi_dsi_link_read(dsi
, TXSETR
);
759 dsi
->num_data_lanes
= min(((txsetr
>> 16) & 3) + 1, num_data_lanes
);
760 rzg2l_mipi_dsi_dphy_exit(dsi
);
761 pm_runtime_put(dsi
->dev
);
763 /* Initialize the DRM bridge. */
764 dsi
->bridge
.funcs
= &rzg2l_mipi_dsi_bridge_ops
;
765 dsi
->bridge
.of_node
= dsi
->dev
->of_node
;
767 /* Init host device */
768 dsi
->host
.dev
= dsi
->dev
;
769 dsi
->host
.ops
= &rzg2l_mipi_dsi_host_ops
;
770 ret
= mipi_dsi_host_register(&dsi
->host
);
777 rzg2l_mipi_dsi_dphy_exit(dsi
);
778 pm_runtime_put(dsi
->dev
);
780 pm_runtime_disable(dsi
->dev
);
784 static void rzg2l_mipi_dsi_remove(struct platform_device
*pdev
)
786 struct rzg2l_mipi_dsi
*dsi
= platform_get_drvdata(pdev
);
788 mipi_dsi_host_unregister(&dsi
->host
);
789 pm_runtime_disable(&pdev
->dev
);
792 static const struct of_device_id rzg2l_mipi_dsi_of_table
[] = {
793 { .compatible
= "renesas,rzg2l-mipi-dsi" },
797 MODULE_DEVICE_TABLE(of
, rzg2l_mipi_dsi_of_table
);
799 static struct platform_driver rzg2l_mipi_dsi_platform_driver
= {
800 .probe
= rzg2l_mipi_dsi_probe
,
801 .remove
= rzg2l_mipi_dsi_remove
,
803 .name
= "rzg2l-mipi-dsi",
804 .pm
= &rzg2l_mipi_pm_ops
,
805 .of_match_table
= rzg2l_mipi_dsi_of_table
,
809 module_platform_driver(rzg2l_mipi_dsi_platform_driver
);
811 MODULE_AUTHOR("Biju Das <biju.das.jz@bp.renesas.com>");
812 MODULE_DESCRIPTION("Renesas RZ/G2L MIPI DSI Encoder Driver");
813 MODULE_LICENSE("GPL");