1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2021 MediaTek Inc.
7 #include <linux/component.h>
9 #include <linux/platform_device.h>
10 #include <linux/reset.h>
11 #include <linux/soc/mediatek/mtk-cmdq.h>
13 #include "mtk_ddp_comp.h"
14 #include "mtk_drm_drv.h"
15 #include "mtk_disp_drv.h"
17 #define DISP_REG_MERGE_CTRL 0x000
19 #define DISP_REG_MERGE_CFG_0 0x010
20 #define DISP_REG_MERGE_CFG_1 0x014
21 #define DISP_REG_MERGE_CFG_4 0x020
22 #define DISP_REG_MERGE_CFG_10 0x038
25 #define FLD_SWAP_MODE GENMASK(4, 0)
26 #define DISP_REG_MERGE_CFG_12 0x040
27 #define CFG_10_10_1PI_2PO_BUF_MODE 6
28 #define CFG_10_10_2PI_2PO_BUF_MODE 8
29 #define CFG_11_10_1PI_2PO_MERGE 18
30 #define FLD_CFG_MERGE_MODE GENMASK(4, 0)
31 #define DISP_REG_MERGE_CFG_24 0x070
32 #define DISP_REG_MERGE_CFG_25 0x074
33 #define DISP_REG_MERGE_CFG_26 0x078
34 #define DISP_REG_MERGE_CFG_27 0x07c
35 #define DISP_REG_MERGE_CFG_36 0x0a0
36 #define ULTRA_EN BIT(0)
37 #define PREULTRA_EN BIT(4)
38 #define DISP_REG_MERGE_CFG_37 0x0a4
39 /* 0: Off, 1: SRAM0, 2: SRAM1, 3: SRAM0 + SRAM1 */
41 #define FLD_BUFFER_MODE GENMASK(1, 0)
43 * For the ultra and preultra settings, 6us ~ 9us is experience value
44 * and the maximum frequency of mmsys clock is 594MHz.
46 #define DISP_REG_MERGE_CFG_40 0x0b0
47 /* 6 us, 594M pixel/sec */
48 #define ULTRA_TH_LOW (6 * 594)
49 /* 8 us, 594M pixel/sec */
50 #define ULTRA_TH_HIGH (8 * 594)
51 #define FLD_ULTRA_TH_LOW GENMASK(15, 0)
52 #define FLD_ULTRA_TH_HIGH GENMASK(31, 16)
53 #define DISP_REG_MERGE_CFG_41 0x0b4
54 /* 8 us, 594M pixel/sec */
55 #define PREULTRA_TH_LOW (8 * 594)
56 /* 9 us, 594M pixel/sec */
57 #define PREULTRA_TH_HIGH (9 * 594)
58 #define FLD_PREULTRA_TH_LOW GENMASK(15, 0)
59 #define FLD_PREULTRA_TH_HIGH GENMASK(31, 16)
61 #define DISP_REG_MERGE_MUTE_0 0xf00
63 struct mtk_disp_merge
{
66 struct clk
*async_clk
;
67 struct cmdq_client_reg cmdq_reg
;
70 struct reset_control
*reset_ctl
;
73 void mtk_merge_start(struct device
*dev
)
75 mtk_merge_start_cmdq(dev
, NULL
);
78 void mtk_merge_stop(struct device
*dev
)
80 mtk_merge_stop_cmdq(dev
, NULL
);
83 void mtk_merge_start_cmdq(struct device
*dev
, struct cmdq_pkt
*cmdq_pkt
)
85 struct mtk_disp_merge
*priv
= dev_get_drvdata(dev
);
87 if (priv
->mute_support
)
88 mtk_ddp_write(cmdq_pkt
, 0x0, &priv
->cmdq_reg
, priv
->regs
,
89 DISP_REG_MERGE_MUTE_0
);
91 mtk_ddp_write(cmdq_pkt
, 1, &priv
->cmdq_reg
, priv
->regs
,
95 void mtk_merge_stop_cmdq(struct device
*dev
, struct cmdq_pkt
*cmdq_pkt
)
97 struct mtk_disp_merge
*priv
= dev_get_drvdata(dev
);
99 if (priv
->mute_support
)
100 mtk_ddp_write(cmdq_pkt
, 0x1, &priv
->cmdq_reg
, priv
->regs
,
101 DISP_REG_MERGE_MUTE_0
);
103 mtk_ddp_write(cmdq_pkt
, 0, &priv
->cmdq_reg
, priv
->regs
,
104 DISP_REG_MERGE_CTRL
);
106 if (!cmdq_pkt
&& priv
->async_clk
)
107 reset_control_reset(priv
->reset_ctl
);
110 static void mtk_merge_fifo_setting(struct mtk_disp_merge
*priv
,
111 struct cmdq_pkt
*cmdq_pkt
)
113 mtk_ddp_write(cmdq_pkt
, ULTRA_EN
| PREULTRA_EN
,
114 &priv
->cmdq_reg
, priv
->regs
, DISP_REG_MERGE_CFG_36
);
116 mtk_ddp_write_mask(cmdq_pkt
, BUFFER_MODE
,
117 &priv
->cmdq_reg
, priv
->regs
, DISP_REG_MERGE_CFG_37
,
120 mtk_ddp_write_mask(cmdq_pkt
, ULTRA_TH_LOW
| ULTRA_TH_HIGH
<< 16,
121 &priv
->cmdq_reg
, priv
->regs
, DISP_REG_MERGE_CFG_40
,
122 FLD_ULTRA_TH_LOW
| FLD_ULTRA_TH_HIGH
);
124 mtk_ddp_write_mask(cmdq_pkt
, PREULTRA_TH_LOW
| PREULTRA_TH_HIGH
<< 16,
125 &priv
->cmdq_reg
, priv
->regs
, DISP_REG_MERGE_CFG_41
,
126 FLD_PREULTRA_TH_LOW
| FLD_PREULTRA_TH_HIGH
);
129 void mtk_merge_config(struct device
*dev
, unsigned int w
,
130 unsigned int h
, unsigned int vrefresh
,
131 unsigned int bpc
, struct cmdq_pkt
*cmdq_pkt
)
133 mtk_merge_advance_config(dev
, w
, 0, h
, vrefresh
, bpc
, cmdq_pkt
);
136 void mtk_merge_advance_config(struct device
*dev
, unsigned int l_w
, unsigned int r_w
,
137 unsigned int h
, unsigned int vrefresh
, unsigned int bpc
,
138 struct cmdq_pkt
*cmdq_pkt
)
140 struct mtk_disp_merge
*priv
= dev_get_drvdata(dev
);
141 unsigned int mode
= CFG_10_10_1PI_2PO_BUF_MODE
;
144 dev_err(dev
, "%s: input width(%d) or height(%d) is invalid\n", __func__
, l_w
, h
);
149 mtk_merge_fifo_setting(priv
, cmdq_pkt
);
150 mode
= CFG_10_10_2PI_2PO_BUF_MODE
;
154 mode
= CFG_11_10_1PI_2PO_MERGE
;
156 mtk_ddp_write(cmdq_pkt
, h
<< 16 | l_w
, &priv
->cmdq_reg
, priv
->regs
,
157 DISP_REG_MERGE_CFG_0
);
158 mtk_ddp_write(cmdq_pkt
, h
<< 16 | r_w
, &priv
->cmdq_reg
, priv
->regs
,
159 DISP_REG_MERGE_CFG_1
);
160 mtk_ddp_write(cmdq_pkt
, h
<< 16 | (l_w
+ r_w
), &priv
->cmdq_reg
, priv
->regs
,
161 DISP_REG_MERGE_CFG_4
);
163 * DISP_REG_MERGE_CFG_24 is merge SRAM0 w/h
164 * DISP_REG_MERGE_CFG_25 is merge SRAM1 w/h.
165 * If r_w > 0, the merge is in merge mode (input0 and input1 merge together),
166 * the input0 goes to SRAM0, and input1 goes to SRAM1.
167 * If r_w = 0, the merge is in buffer mode, the input goes through SRAM0 and
168 * then to SRAM1. Both SRAM0 and SRAM1 are set to the same size.
170 mtk_ddp_write(cmdq_pkt
, h
<< 16 | l_w
, &priv
->cmdq_reg
, priv
->regs
,
171 DISP_REG_MERGE_CFG_24
);
173 mtk_ddp_write(cmdq_pkt
, h
<< 16 | r_w
, &priv
->cmdq_reg
, priv
->regs
,
174 DISP_REG_MERGE_CFG_25
);
176 mtk_ddp_write(cmdq_pkt
, h
<< 16 | l_w
, &priv
->cmdq_reg
, priv
->regs
,
177 DISP_REG_MERGE_CFG_25
);
180 * DISP_REG_MERGE_CFG_26 and DISP_REG_MERGE_CFG_27 is only used in LR merge.
181 * Only take effect when the merge is setting to merge mode.
183 mtk_ddp_write(cmdq_pkt
, h
<< 16 | l_w
, &priv
->cmdq_reg
, priv
->regs
,
184 DISP_REG_MERGE_CFG_26
);
185 mtk_ddp_write(cmdq_pkt
, h
<< 16 | r_w
, &priv
->cmdq_reg
, priv
->regs
,
186 DISP_REG_MERGE_CFG_27
);
188 mtk_ddp_write_mask(cmdq_pkt
, SWAP_MODE
, &priv
->cmdq_reg
, priv
->regs
,
189 DISP_REG_MERGE_CFG_10
, FLD_SWAP_MODE
);
190 mtk_ddp_write_mask(cmdq_pkt
, mode
, &priv
->cmdq_reg
, priv
->regs
,
191 DISP_REG_MERGE_CFG_12
, FLD_CFG_MERGE_MODE
);
194 int mtk_merge_clk_enable(struct device
*dev
)
197 struct mtk_disp_merge
*priv
= dev_get_drvdata(dev
);
199 ret
= clk_prepare_enable(priv
->clk
);
201 dev_err(dev
, "merge clk prepare enable failed\n");
205 ret
= clk_prepare_enable(priv
->async_clk
);
207 /* should clean up the state of priv->clk */
208 clk_disable_unprepare(priv
->clk
);
210 dev_err(dev
, "async clk prepare enable failed\n");
217 void mtk_merge_clk_disable(struct device
*dev
)
219 struct mtk_disp_merge
*priv
= dev_get_drvdata(dev
);
221 clk_disable_unprepare(priv
->async_clk
);
222 clk_disable_unprepare(priv
->clk
);
225 enum drm_mode_status
mtk_merge_mode_valid(struct device
*dev
,
226 const struct drm_display_mode
*mode
)
228 struct mtk_disp_merge
*priv
= dev_get_drvdata(dev
);
231 rate
= clk_get_rate(priv
->clk
);
233 /* Convert to KHz and round the number */
234 rate
= (rate
+ 500) / 1000;
236 if (rate
&& mode
->clock
> rate
) {
237 dev_dbg(dev
, "invalid clock: %d (>%lu)\n", mode
->clock
, rate
);
238 return MODE_CLOCK_HIGH
;
242 * Measure the bandwidth requirement of hardware prefetch (per frame)
244 * let N = prefetch buffer size in lines
245 * (ex. N=3, then prefetch buffer size = 3 lines)
247 * prefetch size = htotal * N (pixels)
248 * time per line = 1 / fps / vtotal (seconds)
249 * duration = vbp * time per line
250 * = vbp / fps / vtotal
252 * data rate = prefetch size / duration
253 * = htotal * N / (vbp / fps / vtotal)
254 * = htotal * vtotal * fps * N / vbp
255 * = clk * N / vbp (pixels per second)
257 * Say 4K60 (CEA-861) is the maximum mode supported by the SoC
258 * data rate = 594000K * N / 72 = 8250 (standard)
259 * (remove K * N due to the same unit)
261 * For 2560x1440@144 (clk=583600K, vbp=17):
262 * data rate = 583600 / 17 ~= 34329 > 8250 (NG)
264 * For 2560x1440@120 (clk=497760K, vbp=77):
265 * data rate = 497760 / 77 ~= 6464 < 8250 (OK)
267 * A non-standard 4K60 timing (clk=521280K, vbp=54)
268 * data rate = 521280 / 54 ~= 9653 > 8250 (NG)
270 * Bandwidth requirement of hardware prefetch increases significantly
271 * when the VBP decreases (more than 4x in this example).
273 * The proposed formula is only one way to estimate whether our SoC
274 * supports the mode setting. The basic idea behind it is just to check
275 * if the data rate requirement is too high (directly proportional to
276 * pixel clock, inversely proportional to vbp). Please adjust the
277 * function if it doesn't fit your situation in the future.
279 rate
= mode
->clock
/ (mode
->vtotal
- mode
->vsync_end
);
282 dev_dbg(dev
, "invalid rate: %lu (>8250): " DRM_MODE_FMT
"\n",
283 rate
, DRM_MODE_ARG(mode
));
290 static int mtk_disp_merge_bind(struct device
*dev
, struct device
*master
,
296 static void mtk_disp_merge_unbind(struct device
*dev
, struct device
*master
,
301 static const struct component_ops mtk_disp_merge_component_ops
= {
302 .bind
= mtk_disp_merge_bind
,
303 .unbind
= mtk_disp_merge_unbind
,
306 static int mtk_disp_merge_probe(struct platform_device
*pdev
)
308 struct device
*dev
= &pdev
->dev
;
309 struct resource
*res
;
310 struct mtk_disp_merge
*priv
;
313 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
317 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
318 priv
->regs
= devm_ioremap_resource(dev
, res
);
319 if (IS_ERR(priv
->regs
))
320 return dev_err_probe(dev
, PTR_ERR(priv
->regs
),
321 "failed to ioremap merge\n");
323 priv
->clk
= devm_clk_get(dev
, NULL
);
324 if (IS_ERR(priv
->clk
))
325 return dev_err_probe(dev
, PTR_ERR(priv
->clk
),
326 "failed to get merge clk\n");
328 priv
->async_clk
= devm_clk_get_optional(dev
, "merge_async");
329 if (IS_ERR(priv
->async_clk
))
330 return dev_err_probe(dev
, PTR_ERR(priv
->async_clk
),
331 "failed to get merge async clock\n");
333 if (priv
->async_clk
) {
334 priv
->reset_ctl
= devm_reset_control_get_optional_exclusive(dev
, NULL
);
335 if (IS_ERR(priv
->reset_ctl
))
336 return PTR_ERR(priv
->reset_ctl
);
339 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
340 ret
= cmdq_dev_get_client_reg(dev
, &priv
->cmdq_reg
, 0);
342 dev_dbg(dev
, "get mediatek,gce-client-reg fail!\n");
345 priv
->fifo_en
= of_property_read_bool(dev
->of_node
,
346 "mediatek,merge-fifo-en");
348 priv
->mute_support
= of_property_read_bool(dev
->of_node
,
349 "mediatek,merge-mute");
350 platform_set_drvdata(pdev
, priv
);
352 ret
= component_add(dev
, &mtk_disp_merge_component_ops
);
354 return dev_err_probe(dev
, ret
, "Failed to add component\n");
359 static void mtk_disp_merge_remove(struct platform_device
*pdev
)
361 component_del(&pdev
->dev
, &mtk_disp_merge_component_ops
);
364 static const struct of_device_id mtk_disp_merge_driver_dt_match
[] = {
365 { .compatible
= "mediatek,mt8195-disp-merge", },
369 MODULE_DEVICE_TABLE(of
, mtk_disp_merge_driver_dt_match
);
371 struct platform_driver mtk_disp_merge_driver
= {
372 .probe
= mtk_disp_merge_probe
,
373 .remove
= mtk_disp_merge_remove
,
375 .name
= "mediatek-disp-merge",
376 .of_match_table
= mtk_disp_merge_driver_dt_match
,