1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2016 Marek Vasut <marex@denx.de>
5 * This code is based on drivers/video/fbdev/mxsfb.c :
6 * Copyright (C) 2010 Juergen Beisert, Pengutronix
7 * Copyright (C) 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
8 * Copyright (C) 2008 Embedded Alley Solutions, Inc All Rights Reserved.
11 #include <linux/clk.h>
13 #include <linux/iopoll.h>
14 #include <linux/pm_runtime.h>
15 #include <linux/spinlock.h>
17 #include <drm/drm_atomic.h>
18 #include <drm/drm_atomic_helper.h>
19 #include <drm/drm_bridge.h>
20 #include <drm/drm_crtc.h>
21 #include <drm/drm_encoder.h>
22 #include <drm/drm_fb_cma_helper.h>
23 #include <drm/drm_fourcc.h>
24 #include <drm/drm_gem_cma_helper.h>
25 #include <drm/drm_gem_framebuffer_helper.h>
26 #include <drm/drm_plane.h>
27 #include <drm/drm_plane_helper.h>
28 #include <drm/drm_vblank.h>
30 #include "mxsfb_drv.h"
31 #include "mxsfb_regs.h"
33 /* 1 second delay should be plenty of time for block reset */
34 #define RESET_TIMEOUT 1000000
36 /* -----------------------------------------------------------------------------
40 static u32
set_hsync_pulse_width(struct mxsfb_drm_private
*mxsfb
, u32 val
)
42 return (val
& mxsfb
->devdata
->hs_wdth_mask
) <<
43 mxsfb
->devdata
->hs_wdth_shift
;
47 * Setup the MXSFB registers for decoding the pixels out of the framebuffer and
48 * outputting them on the bus.
50 static void mxsfb_set_formats(struct mxsfb_drm_private
*mxsfb
)
52 struct drm_device
*drm
= mxsfb
->drm
;
53 const u32 format
= mxsfb
->crtc
.primary
->state
->fb
->format
->format
;
54 u32 bus_format
= MEDIA_BUS_FMT_RGB888_1X24
;
57 if (mxsfb
->connector
->display_info
.num_bus_formats
)
58 bus_format
= mxsfb
->connector
->display_info
.bus_formats
[0];
60 DRM_DEV_DEBUG_DRIVER(drm
->dev
, "Using bus_format: 0x%08X\n",
63 ctrl
= CTRL_BYPASS_COUNT
| CTRL_MASTER
;
65 /* CTRL1 contains IRQ config and status bits, preserve those. */
66 ctrl1
= readl(mxsfb
->base
+ LCDC_CTRL1
);
67 ctrl1
&= CTRL1_CUR_FRAME_DONE_IRQ_EN
| CTRL1_CUR_FRAME_DONE_IRQ
;
70 case DRM_FORMAT_RGB565
:
71 dev_dbg(drm
->dev
, "Setting up RGB565 mode\n");
72 ctrl
|= CTRL_WORD_LENGTH_16
;
73 ctrl1
|= CTRL1_SET_BYTE_PACKAGING(0xf);
75 case DRM_FORMAT_XRGB8888
:
76 dev_dbg(drm
->dev
, "Setting up XRGB8888 mode\n");
77 ctrl
|= CTRL_WORD_LENGTH_24
;
78 /* Do not use packed pixels = one pixel per word instead. */
79 ctrl1
|= CTRL1_SET_BYTE_PACKAGING(0x7);
84 case MEDIA_BUS_FMT_RGB565_1X16
:
85 ctrl
|= CTRL_BUS_WIDTH_16
;
87 case MEDIA_BUS_FMT_RGB666_1X18
:
88 ctrl
|= CTRL_BUS_WIDTH_18
;
90 case MEDIA_BUS_FMT_RGB888_1X24
:
91 ctrl
|= CTRL_BUS_WIDTH_24
;
94 dev_err(drm
->dev
, "Unknown media bus format %d\n", bus_format
);
98 writel(ctrl1
, mxsfb
->base
+ LCDC_CTRL1
);
99 writel(ctrl
, mxsfb
->base
+ LCDC_CTRL
);
102 static void mxsfb_enable_controller(struct mxsfb_drm_private
*mxsfb
)
106 if (mxsfb
->clk_disp_axi
)
107 clk_prepare_enable(mxsfb
->clk_disp_axi
);
108 clk_prepare_enable(mxsfb
->clk
);
110 /* If it was disabled, re-enable the mode again */
111 writel(CTRL_DOTCLK_MODE
, mxsfb
->base
+ LCDC_CTRL
+ REG_SET
);
113 /* Enable the SYNC signals first, then the DMA engine */
114 reg
= readl(mxsfb
->base
+ LCDC_VDCTRL4
);
115 reg
|= VDCTRL4_SYNC_SIGNALS_ON
;
116 writel(reg
, mxsfb
->base
+ LCDC_VDCTRL4
);
118 writel(CTRL_RUN
, mxsfb
->base
+ LCDC_CTRL
+ REG_SET
);
121 static void mxsfb_disable_controller(struct mxsfb_drm_private
*mxsfb
)
126 * Even if we disable the controller here, it will still continue
127 * until its FIFOs are running out of data
129 writel(CTRL_DOTCLK_MODE
, mxsfb
->base
+ LCDC_CTRL
+ REG_CLR
);
131 readl_poll_timeout(mxsfb
->base
+ LCDC_CTRL
, reg
, !(reg
& CTRL_RUN
),
134 reg
= readl(mxsfb
->base
+ LCDC_VDCTRL4
);
135 reg
&= ~VDCTRL4_SYNC_SIGNALS_ON
;
136 writel(reg
, mxsfb
->base
+ LCDC_VDCTRL4
);
138 clk_disable_unprepare(mxsfb
->clk
);
139 if (mxsfb
->clk_disp_axi
)
140 clk_disable_unprepare(mxsfb
->clk_disp_axi
);
144 * Clear the bit and poll it cleared. This is usually called with
145 * a reset address and mask being either SFTRST(bit 31) or CLKGATE
148 static int clear_poll_bit(void __iomem
*addr
, u32 mask
)
152 writel(mask
, addr
+ REG_CLR
);
153 return readl_poll_timeout(addr
, reg
, !(reg
& mask
), 0, RESET_TIMEOUT
);
156 static int mxsfb_reset_block(struct mxsfb_drm_private
*mxsfb
)
160 ret
= clear_poll_bit(mxsfb
->base
+ LCDC_CTRL
, CTRL_SFTRST
);
164 writel(CTRL_CLKGATE
, mxsfb
->base
+ LCDC_CTRL
+ REG_CLR
);
166 ret
= clear_poll_bit(mxsfb
->base
+ LCDC_CTRL
, CTRL_SFTRST
);
170 return clear_poll_bit(mxsfb
->base
+ LCDC_CTRL
, CTRL_CLKGATE
);
173 static dma_addr_t
mxsfb_get_fb_paddr(struct drm_plane
*plane
)
175 struct drm_framebuffer
*fb
= plane
->state
->fb
;
176 struct drm_gem_cma_object
*gem
;
181 gem
= drm_fb_cma_get_gem_obj(fb
, 0);
188 static void mxsfb_crtc_mode_set_nofb(struct mxsfb_drm_private
*mxsfb
)
190 struct drm_device
*drm
= mxsfb
->crtc
.dev
;
191 struct drm_display_mode
*m
= &mxsfb
->crtc
.state
->adjusted_mode
;
192 u32 bus_flags
= mxsfb
->connector
->display_info
.bus_flags
;
193 u32 vdctrl0
, vsync_pulse_len
, hsync_pulse_len
;
197 * It seems, you can't re-program the controller if it is still
198 * running. This may lead to shifted pictures (FIFO issue?), so
199 * first stop the controller and drain its FIFOs.
202 /* Mandatory eLCDIF reset as per the Reference Manual */
203 err
= mxsfb_reset_block(mxsfb
);
207 /* Clear the FIFOs */
208 writel(CTRL1_FIFO_CLEAR
, mxsfb
->base
+ LCDC_CTRL1
+ REG_SET
);
210 if (mxsfb
->devdata
->has_overlay
)
211 writel(0, mxsfb
->base
+ LCDC_AS_CTRL
);
213 mxsfb_set_formats(mxsfb
);
215 clk_set_rate(mxsfb
->clk
, m
->crtc_clock
* 1000);
217 if (mxsfb
->bridge
&& mxsfb
->bridge
->timings
)
218 bus_flags
= mxsfb
->bridge
->timings
->input_bus_flags
;
220 DRM_DEV_DEBUG_DRIVER(drm
->dev
, "Pixel clock: %dkHz (actual: %dkHz)\n",
222 (int)(clk_get_rate(mxsfb
->clk
) / 1000));
223 DRM_DEV_DEBUG_DRIVER(drm
->dev
, "Connector bus_flags: 0x%08X\n",
225 DRM_DEV_DEBUG_DRIVER(drm
->dev
, "Mode flags: 0x%08X\n", m
->flags
);
227 writel(TRANSFER_COUNT_SET_VCOUNT(m
->crtc_vdisplay
) |
228 TRANSFER_COUNT_SET_HCOUNT(m
->crtc_hdisplay
),
229 mxsfb
->base
+ mxsfb
->devdata
->transfer_count
);
231 vsync_pulse_len
= m
->crtc_vsync_end
- m
->crtc_vsync_start
;
233 vdctrl0
= VDCTRL0_ENABLE_PRESENT
| /* Always in DOTCLOCK mode */
234 VDCTRL0_VSYNC_PERIOD_UNIT
|
235 VDCTRL0_VSYNC_PULSE_WIDTH_UNIT
|
236 VDCTRL0_SET_VSYNC_PULSE_WIDTH(vsync_pulse_len
);
237 if (m
->flags
& DRM_MODE_FLAG_PHSYNC
)
238 vdctrl0
|= VDCTRL0_HSYNC_ACT_HIGH
;
239 if (m
->flags
& DRM_MODE_FLAG_PVSYNC
)
240 vdctrl0
|= VDCTRL0_VSYNC_ACT_HIGH
;
241 /* Make sure Data Enable is high active by default */
242 if (!(bus_flags
& DRM_BUS_FLAG_DE_LOW
))
243 vdctrl0
|= VDCTRL0_ENABLE_ACT_HIGH
;
245 * DRM_BUS_FLAG_PIXDATA_DRIVE_ defines are controller centric,
246 * controllers VDCTRL0_DOTCLK is display centric.
247 * Drive on positive edge -> display samples on falling edge
248 * DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE -> VDCTRL0_DOTCLK_ACT_FALLING
250 if (bus_flags
& DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE
)
251 vdctrl0
|= VDCTRL0_DOTCLK_ACT_FALLING
;
253 writel(vdctrl0
, mxsfb
->base
+ LCDC_VDCTRL0
);
255 /* Frame length in lines. */
256 writel(m
->crtc_vtotal
, mxsfb
->base
+ LCDC_VDCTRL1
);
258 /* Line length in units of clocks or pixels. */
259 hsync_pulse_len
= m
->crtc_hsync_end
- m
->crtc_hsync_start
;
260 writel(set_hsync_pulse_width(mxsfb
, hsync_pulse_len
) |
261 VDCTRL2_SET_HSYNC_PERIOD(m
->crtc_htotal
),
262 mxsfb
->base
+ LCDC_VDCTRL2
);
264 writel(SET_HOR_WAIT_CNT(m
->crtc_htotal
- m
->crtc_hsync_start
) |
265 SET_VERT_WAIT_CNT(m
->crtc_vtotal
- m
->crtc_vsync_start
),
266 mxsfb
->base
+ LCDC_VDCTRL3
);
268 writel(SET_DOTCLK_H_VALID_DATA_CNT(m
->hdisplay
),
269 mxsfb
->base
+ LCDC_VDCTRL4
);
272 static int mxsfb_crtc_atomic_check(struct drm_crtc
*crtc
,
273 struct drm_atomic_state
*state
)
275 struct drm_crtc_state
*crtc_state
= drm_atomic_get_new_crtc_state(state
,
277 bool has_primary
= crtc_state
->plane_mask
&
278 drm_plane_mask(crtc
->primary
);
280 /* The primary plane has to be enabled when the CRTC is active. */
281 if (crtc_state
->active
&& !has_primary
)
284 /* TODO: Is this needed ? */
285 return drm_atomic_add_affected_planes(state
, crtc
);
288 static void mxsfb_crtc_atomic_flush(struct drm_crtc
*crtc
,
289 struct drm_atomic_state
*state
)
291 struct drm_pending_vblank_event
*event
;
293 event
= crtc
->state
->event
;
294 crtc
->state
->event
= NULL
;
299 spin_lock_irq(&crtc
->dev
->event_lock
);
300 if (drm_crtc_vblank_get(crtc
) == 0)
301 drm_crtc_arm_vblank_event(crtc
, event
);
303 drm_crtc_send_vblank_event(crtc
, event
);
304 spin_unlock_irq(&crtc
->dev
->event_lock
);
307 static void mxsfb_crtc_atomic_enable(struct drm_crtc
*crtc
,
308 struct drm_atomic_state
*state
)
310 struct mxsfb_drm_private
*mxsfb
= to_mxsfb_drm_private(crtc
->dev
);
311 struct drm_device
*drm
= mxsfb
->drm
;
314 pm_runtime_get_sync(drm
->dev
);
315 mxsfb_enable_axi_clk(mxsfb
);
317 drm_crtc_vblank_on(crtc
);
319 mxsfb_crtc_mode_set_nofb(mxsfb
);
321 /* Write cur_buf as well to avoid an initial corrupt frame */
322 paddr
= mxsfb_get_fb_paddr(crtc
->primary
);
324 writel(paddr
, mxsfb
->base
+ mxsfb
->devdata
->cur_buf
);
325 writel(paddr
, mxsfb
->base
+ mxsfb
->devdata
->next_buf
);
328 mxsfb_enable_controller(mxsfb
);
331 static void mxsfb_crtc_atomic_disable(struct drm_crtc
*crtc
,
332 struct drm_atomic_state
*state
)
334 struct mxsfb_drm_private
*mxsfb
= to_mxsfb_drm_private(crtc
->dev
);
335 struct drm_device
*drm
= mxsfb
->drm
;
336 struct drm_pending_vblank_event
*event
;
338 mxsfb_disable_controller(mxsfb
);
340 spin_lock_irq(&drm
->event_lock
);
341 event
= crtc
->state
->event
;
343 crtc
->state
->event
= NULL
;
344 drm_crtc_send_vblank_event(crtc
, event
);
346 spin_unlock_irq(&drm
->event_lock
);
348 drm_crtc_vblank_off(crtc
);
350 mxsfb_disable_axi_clk(mxsfb
);
351 pm_runtime_put_sync(drm
->dev
);
354 static int mxsfb_crtc_enable_vblank(struct drm_crtc
*crtc
)
356 struct mxsfb_drm_private
*mxsfb
= to_mxsfb_drm_private(crtc
->dev
);
358 /* Clear and enable VBLANK IRQ */
359 writel(CTRL1_CUR_FRAME_DONE_IRQ
, mxsfb
->base
+ LCDC_CTRL1
+ REG_CLR
);
360 writel(CTRL1_CUR_FRAME_DONE_IRQ_EN
, mxsfb
->base
+ LCDC_CTRL1
+ REG_SET
);
365 static void mxsfb_crtc_disable_vblank(struct drm_crtc
*crtc
)
367 struct mxsfb_drm_private
*mxsfb
= to_mxsfb_drm_private(crtc
->dev
);
369 /* Disable and clear VBLANK IRQ */
370 writel(CTRL1_CUR_FRAME_DONE_IRQ_EN
, mxsfb
->base
+ LCDC_CTRL1
+ REG_CLR
);
371 writel(CTRL1_CUR_FRAME_DONE_IRQ
, mxsfb
->base
+ LCDC_CTRL1
+ REG_CLR
);
374 static const struct drm_crtc_helper_funcs mxsfb_crtc_helper_funcs
= {
375 .atomic_check
= mxsfb_crtc_atomic_check
,
376 .atomic_flush
= mxsfb_crtc_atomic_flush
,
377 .atomic_enable
= mxsfb_crtc_atomic_enable
,
378 .atomic_disable
= mxsfb_crtc_atomic_disable
,
381 static const struct drm_crtc_funcs mxsfb_crtc_funcs
= {
382 .reset
= drm_atomic_helper_crtc_reset
,
383 .destroy
= drm_crtc_cleanup
,
384 .set_config
= drm_atomic_helper_set_config
,
385 .page_flip
= drm_atomic_helper_page_flip
,
386 .atomic_duplicate_state
= drm_atomic_helper_crtc_duplicate_state
,
387 .atomic_destroy_state
= drm_atomic_helper_crtc_destroy_state
,
388 .enable_vblank
= mxsfb_crtc_enable_vblank
,
389 .disable_vblank
= mxsfb_crtc_disable_vblank
,
392 /* -----------------------------------------------------------------------------
396 static const struct drm_encoder_funcs mxsfb_encoder_funcs
= {
397 .destroy
= drm_encoder_cleanup
,
400 /* -----------------------------------------------------------------------------
404 static int mxsfb_plane_atomic_check(struct drm_plane
*plane
,
405 struct drm_plane_state
*plane_state
)
407 struct mxsfb_drm_private
*mxsfb
= to_mxsfb_drm_private(plane
->dev
);
408 struct drm_crtc_state
*crtc_state
;
410 crtc_state
= drm_atomic_get_new_crtc_state(plane_state
->state
,
413 return drm_atomic_helper_check_plane_state(plane_state
, crtc_state
,
414 DRM_PLANE_HELPER_NO_SCALING
,
415 DRM_PLANE_HELPER_NO_SCALING
,
419 static void mxsfb_plane_primary_atomic_update(struct drm_plane
*plane
,
420 struct drm_plane_state
*old_pstate
)
422 struct mxsfb_drm_private
*mxsfb
= to_mxsfb_drm_private(plane
->dev
);
425 paddr
= mxsfb_get_fb_paddr(plane
);
427 writel(paddr
, mxsfb
->base
+ mxsfb
->devdata
->next_buf
);
430 static void mxsfb_plane_overlay_atomic_update(struct drm_plane
*plane
,
431 struct drm_plane_state
*old_pstate
)
433 struct mxsfb_drm_private
*mxsfb
= to_mxsfb_drm_private(plane
->dev
);
434 struct drm_plane_state
*state
= plane
->state
;
438 paddr
= mxsfb_get_fb_paddr(plane
);
440 writel(0, mxsfb
->base
+ LCDC_AS_CTRL
);
445 * HACK: The hardware seems to output 64 bytes of data of unknown
446 * origin, and then to proceed with the framebuffer. Until the reason
447 * is understood, live with the 16 initial invalid pixels on the first
448 * line and start 64 bytes within the framebuffer.
452 writel(paddr
, mxsfb
->base
+ LCDC_AS_NEXT_BUF
);
455 * If the plane was previously disabled, write LCDC_AS_BUF as well to
456 * provide the first buffer.
459 writel(paddr
, mxsfb
->base
+ LCDC_AS_BUF
);
461 ctrl
= AS_CTRL_AS_ENABLE
| AS_CTRL_ALPHA(255);
463 switch (state
->fb
->format
->format
) {
464 case DRM_FORMAT_XRGB4444
:
465 ctrl
|= AS_CTRL_FORMAT_RGB444
| AS_CTRL_ALPHA_CTRL_OVERRIDE
;
467 case DRM_FORMAT_ARGB4444
:
468 ctrl
|= AS_CTRL_FORMAT_ARGB4444
| AS_CTRL_ALPHA_CTRL_EMBEDDED
;
470 case DRM_FORMAT_XRGB1555
:
471 ctrl
|= AS_CTRL_FORMAT_RGB555
| AS_CTRL_ALPHA_CTRL_OVERRIDE
;
473 case DRM_FORMAT_ARGB1555
:
474 ctrl
|= AS_CTRL_FORMAT_ARGB1555
| AS_CTRL_ALPHA_CTRL_EMBEDDED
;
476 case DRM_FORMAT_RGB565
:
477 ctrl
|= AS_CTRL_FORMAT_RGB565
| AS_CTRL_ALPHA_CTRL_OVERRIDE
;
479 case DRM_FORMAT_XRGB8888
:
480 ctrl
|= AS_CTRL_FORMAT_RGB888
| AS_CTRL_ALPHA_CTRL_OVERRIDE
;
482 case DRM_FORMAT_ARGB8888
:
483 ctrl
|= AS_CTRL_FORMAT_ARGB8888
| AS_CTRL_ALPHA_CTRL_EMBEDDED
;
487 writel(ctrl
, mxsfb
->base
+ LCDC_AS_CTRL
);
490 static bool mxsfb_format_mod_supported(struct drm_plane
*plane
,
494 return modifier
== DRM_FORMAT_MOD_LINEAR
;
497 static const struct drm_plane_helper_funcs mxsfb_plane_primary_helper_funcs
= {
498 .prepare_fb
= drm_gem_fb_prepare_fb
,
499 .atomic_check
= mxsfb_plane_atomic_check
,
500 .atomic_update
= mxsfb_plane_primary_atomic_update
,
503 static const struct drm_plane_helper_funcs mxsfb_plane_overlay_helper_funcs
= {
504 .prepare_fb
= drm_gem_fb_prepare_fb
,
505 .atomic_check
= mxsfb_plane_atomic_check
,
506 .atomic_update
= mxsfb_plane_overlay_atomic_update
,
509 static const struct drm_plane_funcs mxsfb_plane_funcs
= {
510 .format_mod_supported
= mxsfb_format_mod_supported
,
511 .update_plane
= drm_atomic_helper_update_plane
,
512 .disable_plane
= drm_atomic_helper_disable_plane
,
513 .destroy
= drm_plane_cleanup
,
514 .reset
= drm_atomic_helper_plane_reset
,
515 .atomic_duplicate_state
= drm_atomic_helper_plane_duplicate_state
,
516 .atomic_destroy_state
= drm_atomic_helper_plane_destroy_state
,
519 static const uint32_t mxsfb_primary_plane_formats
[] = {
524 static const uint32_t mxsfb_overlay_plane_formats
[] = {
534 static const uint64_t mxsfb_modifiers
[] = {
535 DRM_FORMAT_MOD_LINEAR
,
536 DRM_FORMAT_MOD_INVALID
539 /* -----------------------------------------------------------------------------
543 int mxsfb_kms_init(struct mxsfb_drm_private
*mxsfb
)
545 struct drm_encoder
*encoder
= &mxsfb
->encoder
;
546 struct drm_crtc
*crtc
= &mxsfb
->crtc
;
549 drm_plane_helper_add(&mxsfb
->planes
.primary
,
550 &mxsfb_plane_primary_helper_funcs
);
551 ret
= drm_universal_plane_init(mxsfb
->drm
, &mxsfb
->planes
.primary
, 1,
553 mxsfb_primary_plane_formats
,
554 ARRAY_SIZE(mxsfb_primary_plane_formats
),
555 mxsfb_modifiers
, DRM_PLANE_TYPE_PRIMARY
,
560 if (mxsfb
->devdata
->has_overlay
) {
561 drm_plane_helper_add(&mxsfb
->planes
.overlay
,
562 &mxsfb_plane_overlay_helper_funcs
);
563 ret
= drm_universal_plane_init(mxsfb
->drm
,
564 &mxsfb
->planes
.overlay
, 1,
566 mxsfb_overlay_plane_formats
,
567 ARRAY_SIZE(mxsfb_overlay_plane_formats
),
568 mxsfb_modifiers
, DRM_PLANE_TYPE_OVERLAY
,
574 drm_crtc_helper_add(crtc
, &mxsfb_crtc_helper_funcs
);
575 ret
= drm_crtc_init_with_planes(mxsfb
->drm
, crtc
,
576 &mxsfb
->planes
.primary
, NULL
,
577 &mxsfb_crtc_funcs
, NULL
);
581 encoder
->possible_crtcs
= drm_crtc_mask(crtc
);
582 return drm_encoder_init(mxsfb
->drm
, encoder
, &mxsfb_encoder_funcs
,
583 DRM_MODE_ENCODER_NONE
, NULL
);