1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2015 MediaTek Inc.
6 #include <drm/drm_fourcc.h>
9 #include <linux/component.h>
10 #include <linux/module.h>
12 #include <linux/platform_device.h>
13 #include <linux/pm_runtime.h>
14 #include <linux/soc/mediatek/mtk-cmdq.h>
17 #include "mtk_ddp_comp.h"
18 #include "mtk_disp_drv.h"
19 #include "mtk_drm_drv.h"
21 #define DISP_REG_RDMA_INT_ENABLE 0x0000
22 #define DISP_REG_RDMA_INT_STATUS 0x0004
23 #define RDMA_TARGET_LINE_INT BIT(5)
24 #define RDMA_FIFO_UNDERFLOW_INT BIT(4)
25 #define RDMA_EOF_ABNORMAL_INT BIT(3)
26 #define RDMA_FRAME_END_INT BIT(2)
27 #define RDMA_FRAME_START_INT BIT(1)
28 #define RDMA_REG_UPDATE_INT BIT(0)
29 #define DISP_REG_RDMA_GLOBAL_CON 0x0010
30 #define RDMA_ENGINE_EN BIT(0)
31 #define RDMA_MODE_MEMORY BIT(1)
32 #define DISP_REG_RDMA_SIZE_CON_0 0x0014
33 #define RDMA_MATRIX_ENABLE BIT(17)
34 #define RDMA_MATRIX_INT_MTX_SEL GENMASK(23, 20)
35 #define RDMA_MATRIX_INT_MTX_BT601_to_RGB (6 << 20)
36 #define DISP_REG_RDMA_SIZE_CON_1 0x0018
37 #define DISP_REG_RDMA_TARGET_LINE 0x001c
38 #define DISP_RDMA_MEM_CON 0x0024
39 #define MEM_MODE_INPUT_FORMAT_RGB565 (0x000 << 4)
40 #define MEM_MODE_INPUT_FORMAT_RGB888 (0x001 << 4)
41 #define MEM_MODE_INPUT_FORMAT_RGBA8888 (0x002 << 4)
42 #define MEM_MODE_INPUT_FORMAT_ARGB8888 (0x003 << 4)
43 #define MEM_MODE_INPUT_FORMAT_UYVY (0x004 << 4)
44 #define MEM_MODE_INPUT_FORMAT_YUYV (0x005 << 4)
45 #define MEM_MODE_INPUT_SWAP BIT(8)
46 #define DISP_RDMA_MEM_SRC_PITCH 0x002c
47 #define DISP_RDMA_MEM_GMC_SETTING_0 0x0030
48 #define DISP_REG_RDMA_FIFO_CON 0x0040
49 #define RDMA_FIFO_UNDERFLOW_EN BIT(31)
50 #define RDMA_FIFO_PSEUDO_SIZE(bytes) (((bytes) / 16) << 16)
51 #define RDMA_OUTPUT_VALID_FIFO_THRESHOLD(bytes) ((bytes) / 16)
52 #define RDMA_FIFO_SIZE(rdma) ((rdma)->data->fifo_size)
53 #define DISP_RDMA_MEM_START_ADDR 0x0f00
55 #define RDMA_MEM_GMC 0x40402020
57 static const u32 mt8173_formats
[] = {
71 struct mtk_disp_rdma_data
{
72 unsigned int fifo_size
;
78 * struct mtk_disp_rdma - DISP_RDMA driver structure
79 * @data: local driver data
81 struct mtk_disp_rdma
{
84 struct cmdq_client_reg cmdq_reg
;
85 const struct mtk_disp_rdma_data
*data
;
86 void (*vblank_cb
)(void *data
);
91 static irqreturn_t
mtk_disp_rdma_irq_handler(int irq
, void *dev_id
)
93 struct mtk_disp_rdma
*priv
= dev_id
;
95 /* Clear frame completion interrupt */
96 writel(0x0, priv
->regs
+ DISP_REG_RDMA_INT_STATUS
);
101 priv
->vblank_cb(priv
->vblank_cb_data
);
106 static void rdma_update_bits(struct device
*dev
, unsigned int reg
,
107 unsigned int mask
, unsigned int val
)
109 struct mtk_disp_rdma
*rdma
= dev_get_drvdata(dev
);
110 unsigned int tmp
= readl(rdma
->regs
+ reg
);
112 tmp
= (tmp
& ~mask
) | (val
& mask
);
113 writel(tmp
, rdma
->regs
+ reg
);
116 void mtk_rdma_register_vblank_cb(struct device
*dev
,
117 void (*vblank_cb
)(void *),
118 void *vblank_cb_data
)
120 struct mtk_disp_rdma
*rdma
= dev_get_drvdata(dev
);
122 rdma
->vblank_cb
= vblank_cb
;
123 rdma
->vblank_cb_data
= vblank_cb_data
;
126 void mtk_rdma_unregister_vblank_cb(struct device
*dev
)
128 struct mtk_disp_rdma
*rdma
= dev_get_drvdata(dev
);
130 rdma
->vblank_cb
= NULL
;
131 rdma
->vblank_cb_data
= NULL
;
134 void mtk_rdma_enable_vblank(struct device
*dev
)
136 rdma_update_bits(dev
, DISP_REG_RDMA_INT_ENABLE
, RDMA_FRAME_END_INT
,
140 void mtk_rdma_disable_vblank(struct device
*dev
)
142 rdma_update_bits(dev
, DISP_REG_RDMA_INT_ENABLE
, RDMA_FRAME_END_INT
, 0);
145 const u32
*mtk_rdma_get_formats(struct device
*dev
)
147 struct mtk_disp_rdma
*rdma
= dev_get_drvdata(dev
);
149 return rdma
->data
->formats
;
152 size_t mtk_rdma_get_num_formats(struct device
*dev
)
154 struct mtk_disp_rdma
*rdma
= dev_get_drvdata(dev
);
156 return rdma
->data
->num_formats
;
159 int mtk_rdma_clk_enable(struct device
*dev
)
161 struct mtk_disp_rdma
*rdma
= dev_get_drvdata(dev
);
163 return clk_prepare_enable(rdma
->clk
);
166 void mtk_rdma_clk_disable(struct device
*dev
)
168 struct mtk_disp_rdma
*rdma
= dev_get_drvdata(dev
);
170 clk_disable_unprepare(rdma
->clk
);
173 void mtk_rdma_start(struct device
*dev
)
175 rdma_update_bits(dev
, DISP_REG_RDMA_GLOBAL_CON
, RDMA_ENGINE_EN
,
179 void mtk_rdma_stop(struct device
*dev
)
181 rdma_update_bits(dev
, DISP_REG_RDMA_GLOBAL_CON
, RDMA_ENGINE_EN
, 0);
184 void mtk_rdma_config(struct device
*dev
, unsigned int width
,
185 unsigned int height
, unsigned int vrefresh
,
186 unsigned int bpc
, struct cmdq_pkt
*cmdq_pkt
)
188 unsigned int threshold
;
190 struct mtk_disp_rdma
*rdma
= dev_get_drvdata(dev
);
193 mtk_ddp_write_mask(cmdq_pkt
, width
, &rdma
->cmdq_reg
, rdma
->regs
,
194 DISP_REG_RDMA_SIZE_CON_0
, 0xfff);
195 mtk_ddp_write_mask(cmdq_pkt
, height
, &rdma
->cmdq_reg
, rdma
->regs
,
196 DISP_REG_RDMA_SIZE_CON_1
, 0xfffff);
199 rdma_fifo_size
= rdma
->fifo_size
;
201 rdma_fifo_size
= RDMA_FIFO_SIZE(rdma
);
204 * Enable FIFO underflow since DSI and DPI can't be blocked.
205 * Keep the FIFO pseudo size reset default of 8 KiB. Set the
206 * output threshold to 70% of max fifo size to make sure the
207 * threhold will not overflow
209 threshold
= rdma_fifo_size
* 7 / 10;
210 reg
= RDMA_FIFO_UNDERFLOW_EN
|
211 RDMA_FIFO_PSEUDO_SIZE(rdma_fifo_size
) |
212 RDMA_OUTPUT_VALID_FIFO_THRESHOLD(threshold
);
213 mtk_ddp_write(cmdq_pkt
, reg
, &rdma
->cmdq_reg
, rdma
->regs
, DISP_REG_RDMA_FIFO_CON
);
216 static unsigned int rdma_fmt_convert(struct mtk_disp_rdma
*rdma
,
219 /* The return value in switch "MEM_MODE_INPUT_FORMAT_XXX"
220 * is defined in mediatek HW data sheet.
221 * The alphabet order in XXX is no relation to data
222 * arrangement in memory.
226 case DRM_FORMAT_RGB565
:
227 return MEM_MODE_INPUT_FORMAT_RGB565
;
228 case DRM_FORMAT_BGR565
:
229 return MEM_MODE_INPUT_FORMAT_RGB565
| MEM_MODE_INPUT_SWAP
;
230 case DRM_FORMAT_RGB888
:
231 return MEM_MODE_INPUT_FORMAT_RGB888
;
232 case DRM_FORMAT_BGR888
:
233 return MEM_MODE_INPUT_FORMAT_RGB888
| MEM_MODE_INPUT_SWAP
;
234 case DRM_FORMAT_RGBX8888
:
235 case DRM_FORMAT_RGBA8888
:
236 return MEM_MODE_INPUT_FORMAT_ARGB8888
;
237 case DRM_FORMAT_BGRX8888
:
238 case DRM_FORMAT_BGRA8888
:
239 return MEM_MODE_INPUT_FORMAT_ARGB8888
| MEM_MODE_INPUT_SWAP
;
240 case DRM_FORMAT_XRGB8888
:
241 case DRM_FORMAT_ARGB8888
:
242 return MEM_MODE_INPUT_FORMAT_RGBA8888
;
243 case DRM_FORMAT_XBGR8888
:
244 case DRM_FORMAT_ABGR8888
:
245 return MEM_MODE_INPUT_FORMAT_RGBA8888
| MEM_MODE_INPUT_SWAP
;
246 case DRM_FORMAT_UYVY
:
247 return MEM_MODE_INPUT_FORMAT_UYVY
;
248 case DRM_FORMAT_YUYV
:
249 return MEM_MODE_INPUT_FORMAT_YUYV
;
253 unsigned int mtk_rdma_layer_nr(struct device
*dev
)
258 void mtk_rdma_layer_config(struct device
*dev
, unsigned int idx
,
259 struct mtk_plane_state
*state
,
260 struct cmdq_pkt
*cmdq_pkt
)
262 struct mtk_disp_rdma
*rdma
= dev_get_drvdata(dev
);
263 struct mtk_plane_pending_state
*pending
= &state
->pending
;
264 unsigned int addr
= pending
->addr
;
265 unsigned int pitch
= pending
->pitch
& 0xffff;
266 unsigned int fmt
= pending
->format
;
269 con
= rdma_fmt_convert(rdma
, fmt
);
270 mtk_ddp_write_relaxed(cmdq_pkt
, con
, &rdma
->cmdq_reg
, rdma
->regs
, DISP_RDMA_MEM_CON
);
272 if (fmt
== DRM_FORMAT_UYVY
|| fmt
== DRM_FORMAT_YUYV
) {
273 mtk_ddp_write_mask(cmdq_pkt
, RDMA_MATRIX_ENABLE
, &rdma
->cmdq_reg
, rdma
->regs
,
274 DISP_REG_RDMA_SIZE_CON_0
,
276 mtk_ddp_write_mask(cmdq_pkt
, RDMA_MATRIX_INT_MTX_BT601_to_RGB
,
277 &rdma
->cmdq_reg
, rdma
->regs
, DISP_REG_RDMA_SIZE_CON_0
,
278 RDMA_MATRIX_INT_MTX_SEL
);
280 mtk_ddp_write_mask(cmdq_pkt
, 0, &rdma
->cmdq_reg
, rdma
->regs
,
281 DISP_REG_RDMA_SIZE_CON_0
,
284 mtk_ddp_write_relaxed(cmdq_pkt
, addr
, &rdma
->cmdq_reg
, rdma
->regs
,
285 DISP_RDMA_MEM_START_ADDR
);
286 mtk_ddp_write_relaxed(cmdq_pkt
, pitch
, &rdma
->cmdq_reg
, rdma
->regs
,
287 DISP_RDMA_MEM_SRC_PITCH
);
288 mtk_ddp_write(cmdq_pkt
, RDMA_MEM_GMC
, &rdma
->cmdq_reg
, rdma
->regs
,
289 DISP_RDMA_MEM_GMC_SETTING_0
);
290 mtk_ddp_write_mask(cmdq_pkt
, RDMA_MODE_MEMORY
, &rdma
->cmdq_reg
, rdma
->regs
,
291 DISP_REG_RDMA_GLOBAL_CON
, RDMA_MODE_MEMORY
);
295 static int mtk_disp_rdma_bind(struct device
*dev
, struct device
*master
,
302 static void mtk_disp_rdma_unbind(struct device
*dev
, struct device
*master
,
307 static const struct component_ops mtk_disp_rdma_component_ops
= {
308 .bind
= mtk_disp_rdma_bind
,
309 .unbind
= mtk_disp_rdma_unbind
,
312 static int mtk_disp_rdma_probe(struct platform_device
*pdev
)
314 struct device
*dev
= &pdev
->dev
;
315 struct mtk_disp_rdma
*priv
;
316 struct resource
*res
;
320 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
324 irq
= platform_get_irq(pdev
, 0);
328 priv
->clk
= devm_clk_get(dev
, NULL
);
329 if (IS_ERR(priv
->clk
))
330 return dev_err_probe(dev
, PTR_ERR(priv
->clk
),
331 "failed to get rdma clk\n");
333 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
334 priv
->regs
= devm_ioremap_resource(dev
, res
);
335 if (IS_ERR(priv
->regs
))
336 return dev_err_probe(dev
, PTR_ERR(priv
->regs
),
337 "failed to ioremap rdma\n");
338 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
339 ret
= cmdq_dev_get_client_reg(dev
, &priv
->cmdq_reg
, 0);
341 dev_dbg(dev
, "get mediatek,gce-client-reg fail!\n");
344 ret
= of_property_read_u32(dev
->of_node
,
345 "mediatek,rdma-fifo-size",
347 if (ret
&& (ret
!= -EINVAL
))
348 return dev_err_probe(dev
, ret
, "Failed to get rdma fifo size\n");
350 /* Disable and clear pending interrupts */
351 writel(0x0, priv
->regs
+ DISP_REG_RDMA_INT_ENABLE
);
352 writel(0x0, priv
->regs
+ DISP_REG_RDMA_INT_STATUS
);
354 ret
= devm_request_irq(dev
, irq
, mtk_disp_rdma_irq_handler
,
355 IRQF_TRIGGER_NONE
, dev_name(dev
), priv
);
357 return dev_err_probe(dev
, ret
, "Failed to request irq %d\n", irq
);
359 priv
->data
= of_device_get_match_data(dev
);
361 platform_set_drvdata(pdev
, priv
);
363 pm_runtime_enable(dev
);
365 ret
= component_add(dev
, &mtk_disp_rdma_component_ops
);
367 pm_runtime_disable(dev
);
368 return dev_err_probe(dev
, ret
, "Failed to add component\n");
374 static void mtk_disp_rdma_remove(struct platform_device
*pdev
)
376 component_del(&pdev
->dev
, &mtk_disp_rdma_component_ops
);
378 pm_runtime_disable(&pdev
->dev
);
381 static const struct mtk_disp_rdma_data mt2701_rdma_driver_data
= {
383 .formats
= mt8173_formats
,
384 .num_formats
= ARRAY_SIZE(mt8173_formats
),
387 static const struct mtk_disp_rdma_data mt8173_rdma_driver_data
= {
389 .formats
= mt8173_formats
,
390 .num_formats
= ARRAY_SIZE(mt8173_formats
),
393 static const struct mtk_disp_rdma_data mt8183_rdma_driver_data
= {
394 .fifo_size
= 5 * SZ_1K
,
395 .formats
= mt8173_formats
,
396 .num_formats
= ARRAY_SIZE(mt8173_formats
),
399 static const struct mtk_disp_rdma_data mt8195_rdma_driver_data
= {
401 .formats
= mt8173_formats
,
402 .num_formats
= ARRAY_SIZE(mt8173_formats
),
405 static const struct of_device_id mtk_disp_rdma_driver_dt_match
[] = {
406 { .compatible
= "mediatek,mt2701-disp-rdma",
407 .data
= &mt2701_rdma_driver_data
},
408 { .compatible
= "mediatek,mt8173-disp-rdma",
409 .data
= &mt8173_rdma_driver_data
},
410 { .compatible
= "mediatek,mt8183-disp-rdma",
411 .data
= &mt8183_rdma_driver_data
},
412 { .compatible
= "mediatek,mt8195-disp-rdma",
413 .data
= &mt8195_rdma_driver_data
},
416 MODULE_DEVICE_TABLE(of
, mtk_disp_rdma_driver_dt_match
);
418 struct platform_driver mtk_disp_rdma_driver
= {
419 .probe
= mtk_disp_rdma_probe
,
420 .remove
= mtk_disp_rdma_remove
,
422 .name
= "mediatek-disp-rdma",
423 .of_match_table
= mtk_disp_rdma_driver_dt_match
,