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>
12 #include <linux/iopoll.h>
13 #include <linux/of_graph.h>
14 #include <linux/platform_data/simplefb.h>
16 #include <video/videomode.h>
18 #include <drm/drm_atomic_helper.h>
19 #include <drm/drm_crtc.h>
20 #include <drm/drm_fb_cma_helper.h>
21 #include <drm/drm_fb_helper.h>
22 #include <drm/drm_gem_cma_helper.h>
23 #include <drm/drm_of.h>
24 #include <drm/drm_plane_helper.h>
25 #include <drm/drm_probe_helper.h>
26 #include <drm/drm_simple_kms_helper.h>
27 #include <drm/drm_vblank.h>
29 #include "mxsfb_drv.h"
30 #include "mxsfb_regs.h"
32 #define MXS_SET_ADDR 0x4
33 #define MXS_CLR_ADDR 0x8
34 #define MODULE_CLKGATE BIT(30)
35 #define MODULE_SFTRST BIT(31)
36 /* 1 second delay should be plenty of time for block reset */
37 #define RESET_TIMEOUT 1000000
39 static u32
set_hsync_pulse_width(struct mxsfb_drm_private
*mxsfb
, u32 val
)
41 return (val
& mxsfb
->devdata
->hs_wdth_mask
) <<
42 mxsfb
->devdata
->hs_wdth_shift
;
45 /* Setup the MXSFB registers for decoding the pixels out of the framebuffer */
46 static int mxsfb_set_pixel_fmt(struct mxsfb_drm_private
*mxsfb
)
48 struct drm_crtc
*crtc
= &mxsfb
->pipe
.crtc
;
49 struct drm_device
*drm
= crtc
->dev
;
50 const u32 format
= crtc
->primary
->state
->fb
->format
->format
;
53 ctrl
= CTRL_BYPASS_COUNT
| CTRL_MASTER
;
56 * WARNING: The bus width, CTRL_SET_BUS_WIDTH(), is configured to
57 * match the selected mode here. This differs from the original
58 * MXSFB driver, which had the option to configure the bus width
59 * to arbitrary value. This limitation should not pose an issue.
62 /* CTRL1 contains IRQ config and status bits, preserve those. */
63 ctrl1
= readl(mxsfb
->base
+ LCDC_CTRL1
);
64 ctrl1
&= CTRL1_CUR_FRAME_DONE_IRQ_EN
| CTRL1_CUR_FRAME_DONE_IRQ
;
67 case DRM_FORMAT_RGB565
:
68 dev_dbg(drm
->dev
, "Setting up RGB565 mode\n");
69 ctrl
|= CTRL_SET_WORD_LENGTH(0);
70 ctrl1
|= CTRL1_SET_BYTE_PACKAGING(0xf);
72 case DRM_FORMAT_XRGB8888
:
73 dev_dbg(drm
->dev
, "Setting up XRGB8888 mode\n");
74 ctrl
|= CTRL_SET_WORD_LENGTH(3);
75 /* Do not use packed pixels = one pixel per word instead. */
76 ctrl1
|= CTRL1_SET_BYTE_PACKAGING(0x7);
79 dev_err(drm
->dev
, "Unhandled pixel format %08x\n", format
);
83 writel(ctrl1
, mxsfb
->base
+ LCDC_CTRL1
);
84 writel(ctrl
, mxsfb
->base
+ LCDC_CTRL
);
89 static void mxsfb_set_bus_fmt(struct mxsfb_drm_private
*mxsfb
)
91 struct drm_crtc
*crtc
= &mxsfb
->pipe
.crtc
;
92 struct drm_device
*drm
= crtc
->dev
;
93 u32 bus_format
= MEDIA_BUS_FMT_RGB888_1X24
;
96 reg
= readl(mxsfb
->base
+ LCDC_CTRL
);
98 if (mxsfb
->connector
->display_info
.num_bus_formats
)
99 bus_format
= mxsfb
->connector
->display_info
.bus_formats
[0];
101 DRM_DEV_DEBUG_DRIVER(drm
->dev
, "Using bus_format: 0x%08X\n",
104 reg
&= ~CTRL_BUS_WIDTH_MASK
;
105 switch (bus_format
) {
106 case MEDIA_BUS_FMT_RGB565_1X16
:
107 reg
|= CTRL_SET_BUS_WIDTH(STMLCDIF_16BIT
);
109 case MEDIA_BUS_FMT_RGB666_1X18
:
110 reg
|= CTRL_SET_BUS_WIDTH(STMLCDIF_18BIT
);
112 case MEDIA_BUS_FMT_RGB888_1X24
:
113 reg
|= CTRL_SET_BUS_WIDTH(STMLCDIF_24BIT
);
116 dev_err(drm
->dev
, "Unknown media bus format %d\n", bus_format
);
119 writel(reg
, mxsfb
->base
+ LCDC_CTRL
);
122 static void mxsfb_enable_controller(struct mxsfb_drm_private
*mxsfb
)
126 if (mxsfb
->clk_disp_axi
)
127 clk_prepare_enable(mxsfb
->clk_disp_axi
);
128 clk_prepare_enable(mxsfb
->clk
);
130 /* If it was disabled, re-enable the mode again */
131 writel(CTRL_DOTCLK_MODE
, mxsfb
->base
+ LCDC_CTRL
+ REG_SET
);
133 /* Enable the SYNC signals first, then the DMA engine */
134 reg
= readl(mxsfb
->base
+ LCDC_VDCTRL4
);
135 reg
|= VDCTRL4_SYNC_SIGNALS_ON
;
136 writel(reg
, mxsfb
->base
+ LCDC_VDCTRL4
);
138 writel(CTRL_RUN
, mxsfb
->base
+ LCDC_CTRL
+ REG_SET
);
141 static void mxsfb_disable_controller(struct mxsfb_drm_private
*mxsfb
)
146 * Even if we disable the controller here, it will still continue
147 * until its FIFOs are running out of data
149 writel(CTRL_DOTCLK_MODE
, mxsfb
->base
+ LCDC_CTRL
+ REG_CLR
);
151 readl_poll_timeout(mxsfb
->base
+ LCDC_CTRL
, reg
, !(reg
& CTRL_RUN
),
154 reg
= readl(mxsfb
->base
+ LCDC_VDCTRL4
);
155 reg
&= ~VDCTRL4_SYNC_SIGNALS_ON
;
156 writel(reg
, mxsfb
->base
+ LCDC_VDCTRL4
);
158 clk_disable_unprepare(mxsfb
->clk
);
159 if (mxsfb
->clk_disp_axi
)
160 clk_disable_unprepare(mxsfb
->clk_disp_axi
);
164 * Clear the bit and poll it cleared. This is usually called with
165 * a reset address and mask being either SFTRST(bit 31) or CLKGATE
168 static int clear_poll_bit(void __iomem
*addr
, u32 mask
)
172 writel(mask
, addr
+ MXS_CLR_ADDR
);
173 return readl_poll_timeout(addr
, reg
, !(reg
& mask
), 0, RESET_TIMEOUT
);
176 static int mxsfb_reset_block(void __iomem
*reset_addr
)
180 ret
= clear_poll_bit(reset_addr
, MODULE_SFTRST
);
184 writel(MODULE_CLKGATE
, reset_addr
+ MXS_CLR_ADDR
);
186 ret
= clear_poll_bit(reset_addr
, MODULE_SFTRST
);
190 return clear_poll_bit(reset_addr
, MODULE_CLKGATE
);
193 static dma_addr_t
mxsfb_get_fb_paddr(struct mxsfb_drm_private
*mxsfb
)
195 struct drm_framebuffer
*fb
= mxsfb
->pipe
.plane
.state
->fb
;
196 struct drm_gem_cma_object
*gem
;
201 gem
= drm_fb_cma_get_gem_obj(fb
, 0);
208 static void mxsfb_crtc_mode_set_nofb(struct mxsfb_drm_private
*mxsfb
)
210 struct drm_device
*drm
= mxsfb
->pipe
.crtc
.dev
;
211 struct drm_display_mode
*m
= &mxsfb
->pipe
.crtc
.state
->adjusted_mode
;
212 u32 bus_flags
= mxsfb
->connector
->display_info
.bus_flags
;
213 u32 vdctrl0
, vsync_pulse_len
, hsync_pulse_len
;
217 * It seems, you can't re-program the controller if it is still
218 * running. This may lead to shifted pictures (FIFO issue?), so
219 * first stop the controller and drain its FIFOs.
222 /* Mandatory eLCDIF reset as per the Reference Manual */
223 err
= mxsfb_reset_block(mxsfb
->base
);
227 /* Clear the FIFOs */
228 writel(CTRL1_FIFO_CLEAR
, mxsfb
->base
+ LCDC_CTRL1
+ REG_SET
);
230 err
= mxsfb_set_pixel_fmt(mxsfb
);
234 clk_set_rate(mxsfb
->clk
, m
->crtc_clock
* 1000);
236 if (mxsfb
->bridge
&& mxsfb
->bridge
->timings
)
237 bus_flags
= mxsfb
->bridge
->timings
->input_bus_flags
;
239 DRM_DEV_DEBUG_DRIVER(drm
->dev
, "Pixel clock: %dkHz (actual: %dkHz)\n",
241 (int)(clk_get_rate(mxsfb
->clk
) / 1000));
242 DRM_DEV_DEBUG_DRIVER(drm
->dev
, "Connector bus_flags: 0x%08X\n",
244 DRM_DEV_DEBUG_DRIVER(drm
->dev
, "Mode flags: 0x%08X\n", m
->flags
);
246 writel(TRANSFER_COUNT_SET_VCOUNT(m
->crtc_vdisplay
) |
247 TRANSFER_COUNT_SET_HCOUNT(m
->crtc_hdisplay
),
248 mxsfb
->base
+ mxsfb
->devdata
->transfer_count
);
250 vsync_pulse_len
= m
->crtc_vsync_end
- m
->crtc_vsync_start
;
252 vdctrl0
= VDCTRL0_ENABLE_PRESENT
| /* Always in DOTCLOCK mode */
253 VDCTRL0_VSYNC_PERIOD_UNIT
|
254 VDCTRL0_VSYNC_PULSE_WIDTH_UNIT
|
255 VDCTRL0_SET_VSYNC_PULSE_WIDTH(vsync_pulse_len
);
256 if (m
->flags
& DRM_MODE_FLAG_PHSYNC
)
257 vdctrl0
|= VDCTRL0_HSYNC_ACT_HIGH
;
258 if (m
->flags
& DRM_MODE_FLAG_PVSYNC
)
259 vdctrl0
|= VDCTRL0_VSYNC_ACT_HIGH
;
260 /* Make sure Data Enable is high active by default */
261 if (!(bus_flags
& DRM_BUS_FLAG_DE_LOW
))
262 vdctrl0
|= VDCTRL0_ENABLE_ACT_HIGH
;
264 * DRM_BUS_FLAG_PIXDATA_DRIVE_ defines are controller centric,
265 * controllers VDCTRL0_DOTCLK is display centric.
266 * Drive on positive edge -> display samples on falling edge
267 * DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE -> VDCTRL0_DOTCLK_ACT_FALLING
269 if (bus_flags
& DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE
)
270 vdctrl0
|= VDCTRL0_DOTCLK_ACT_FALLING
;
272 writel(vdctrl0
, mxsfb
->base
+ LCDC_VDCTRL0
);
274 mxsfb_set_bus_fmt(mxsfb
);
276 /* Frame length in lines. */
277 writel(m
->crtc_vtotal
, mxsfb
->base
+ LCDC_VDCTRL1
);
279 /* Line length in units of clocks or pixels. */
280 hsync_pulse_len
= m
->crtc_hsync_end
- m
->crtc_hsync_start
;
281 writel(set_hsync_pulse_width(mxsfb
, hsync_pulse_len
) |
282 VDCTRL2_SET_HSYNC_PERIOD(m
->crtc_htotal
),
283 mxsfb
->base
+ LCDC_VDCTRL2
);
285 writel(SET_HOR_WAIT_CNT(m
->crtc_htotal
- m
->crtc_hsync_start
) |
286 SET_VERT_WAIT_CNT(m
->crtc_vtotal
- m
->crtc_vsync_start
),
287 mxsfb
->base
+ LCDC_VDCTRL3
);
289 writel(SET_DOTCLK_H_VALID_DATA_CNT(m
->hdisplay
),
290 mxsfb
->base
+ LCDC_VDCTRL4
);
293 void mxsfb_crtc_enable(struct mxsfb_drm_private
*mxsfb
)
297 mxsfb_enable_axi_clk(mxsfb
);
298 mxsfb_crtc_mode_set_nofb(mxsfb
);
300 /* Write cur_buf as well to avoid an initial corrupt frame */
301 paddr
= mxsfb_get_fb_paddr(mxsfb
);
303 writel(paddr
, mxsfb
->base
+ mxsfb
->devdata
->cur_buf
);
304 writel(paddr
, mxsfb
->base
+ mxsfb
->devdata
->next_buf
);
307 mxsfb_enable_controller(mxsfb
);
310 void mxsfb_crtc_disable(struct mxsfb_drm_private
*mxsfb
)
312 mxsfb_disable_controller(mxsfb
);
313 mxsfb_disable_axi_clk(mxsfb
);
316 void mxsfb_plane_atomic_update(struct mxsfb_drm_private
*mxsfb
,
317 struct drm_plane_state
*state
)
319 struct drm_simple_display_pipe
*pipe
= &mxsfb
->pipe
;
320 struct drm_crtc
*crtc
= &pipe
->crtc
;
321 struct drm_pending_vblank_event
*event
;
324 spin_lock_irq(&crtc
->dev
->event_lock
);
325 event
= crtc
->state
->event
;
327 crtc
->state
->event
= NULL
;
329 if (drm_crtc_vblank_get(crtc
) == 0) {
330 drm_crtc_arm_vblank_event(crtc
, event
);
332 drm_crtc_send_vblank_event(crtc
, event
);
335 spin_unlock_irq(&crtc
->dev
->event_lock
);
337 paddr
= mxsfb_get_fb_paddr(mxsfb
);
339 mxsfb_enable_axi_clk(mxsfb
);
340 writel(paddr
, mxsfb
->base
+ mxsfb
->devdata
->next_buf
);
341 mxsfb_disable_axi_clk(mxsfb
);