forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
....@@ -1,17 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (c) 2015 MediaTek Inc.
34 * Authors:
45 * YT Shen <yt.shen@mediatek.com>
56 * CK Hu <ck.hu@mediatek.com>
6
- *
7
- * This program is free software; you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License version 2 as
9
- * published by the Free Software Foundation.
10
- *
11
- * This program is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- * GNU General Public License for more details.
157 */
168
179 #include <linux/clk.h>
....@@ -20,7 +12,9 @@
2012 #include <linux/of_irq.h>
2113 #include <linux/of_platform.h>
2214 #include <linux/platform_device.h>
23
-#include <drm/drmP.h>
15
+#include <linux/soc/mediatek/mtk-cmdq.h>
16
+#include <drm/drm_print.h>
17
+
2418 #include "mtk_drm_drv.h"
2519 #include "mtk_drm_plane.h"
2620 #include "mtk_drm_ddp_comp.h"
....@@ -40,6 +34,27 @@
4034
4135 #define DISP_AAL_EN 0x0000
4236 #define DISP_AAL_SIZE 0x0030
37
+#define DISP_AAL_OUTPUT_SIZE 0x04d8
38
+
39
+#define DISP_CCORR_EN 0x0000
40
+#define CCORR_EN BIT(0)
41
+#define DISP_CCORR_CFG 0x0020
42
+#define CCORR_RELAY_MODE BIT(0)
43
+#define CCORR_ENGINE_EN BIT(1)
44
+#define CCORR_GAMMA_OFF BIT(2)
45
+#define CCORR_WGAMUT_SRC_CLIP BIT(3)
46
+#define DISP_CCORR_SIZE 0x0030
47
+#define DISP_CCORR_COEF_0 0x0080
48
+#define DISP_CCORR_COEF_1 0x0084
49
+#define DISP_CCORR_COEF_2 0x0088
50
+#define DISP_CCORR_COEF_3 0x008C
51
+#define DISP_CCORR_COEF_4 0x0090
52
+
53
+#define DISP_DITHER_EN 0x0000
54
+#define DITHER_EN BIT(0)
55
+#define DISP_DITHER_CFG 0x0020
56
+#define DITHER_RELAY_MODE BIT(0)
57
+#define DISP_DITHER_SIZE 0x0030
4358
4459 #define DISP_GAMMA_EN 0x0000
4560 #define DISP_GAMMA_CFG 0x0020
....@@ -72,36 +87,84 @@
7287 #define DITHER_ADD_LSHIFT_G(x) (((x) & 0x7) << 4)
7388 #define DITHER_ADD_RSHIFT_G(x) (((x) & 0x7) << 0)
7489
90
+void mtk_ddp_write(struct cmdq_pkt *cmdq_pkt, unsigned int value,
91
+ struct mtk_ddp_comp *comp, unsigned int offset)
92
+{
93
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
94
+ if (cmdq_pkt)
95
+ cmdq_pkt_write(cmdq_pkt, comp->subsys,
96
+ comp->regs_pa + offset, value);
97
+ else
98
+#endif
99
+ writel(value, comp->regs + offset);
100
+}
101
+
102
+void mtk_ddp_write_relaxed(struct cmdq_pkt *cmdq_pkt, unsigned int value,
103
+ struct mtk_ddp_comp *comp,
104
+ unsigned int offset)
105
+{
106
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
107
+ if (cmdq_pkt)
108
+ cmdq_pkt_write(cmdq_pkt, comp->subsys,
109
+ comp->regs_pa + offset, value);
110
+ else
111
+#endif
112
+ writel_relaxed(value, comp->regs + offset);
113
+}
114
+
115
+void mtk_ddp_write_mask(struct cmdq_pkt *cmdq_pkt,
116
+ unsigned int value,
117
+ struct mtk_ddp_comp *comp,
118
+ unsigned int offset,
119
+ unsigned int mask)
120
+{
121
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
122
+ if (cmdq_pkt) {
123
+ cmdq_pkt_write_mask(cmdq_pkt, comp->subsys,
124
+ comp->regs_pa + offset, value, mask);
125
+ } else {
126
+#endif
127
+ u32 tmp = readl(comp->regs + offset);
128
+
129
+ tmp = (tmp & ~mask) | (value & mask);
130
+ writel(tmp, comp->regs + offset);
131
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
132
+ }
133
+#endif
134
+}
135
+
75136 void mtk_dither_set(struct mtk_ddp_comp *comp, unsigned int bpc,
76
- unsigned int CFG)
137
+ unsigned int CFG, struct cmdq_pkt *cmdq_pkt)
77138 {
78139 /* If bpc equal to 0, the dithering function didn't be enabled */
79140 if (bpc == 0)
80141 return;
81142
82143 if (bpc >= MTK_MIN_BPC) {
83
- writel(0, comp->regs + DISP_DITHER_5);
84
- writel(0, comp->regs + DISP_DITHER_7);
85
- writel(DITHER_LSB_ERR_SHIFT_R(MTK_MAX_BPC - bpc) |
86
- DITHER_ADD_LSHIFT_R(MTK_MAX_BPC - bpc) |
87
- DITHER_NEW_BIT_MODE,
88
- comp->regs + DISP_DITHER_15);
89
- writel(DITHER_LSB_ERR_SHIFT_B(MTK_MAX_BPC - bpc) |
90
- DITHER_ADD_LSHIFT_B(MTK_MAX_BPC - bpc) |
91
- DITHER_LSB_ERR_SHIFT_G(MTK_MAX_BPC - bpc) |
92
- DITHER_ADD_LSHIFT_G(MTK_MAX_BPC - bpc),
93
- comp->regs + DISP_DITHER_16);
94
- writel(DISP_DITHERING, comp->regs + CFG);
144
+ mtk_ddp_write(cmdq_pkt, 0, comp, DISP_DITHER_5);
145
+ mtk_ddp_write(cmdq_pkt, 0, comp, DISP_DITHER_7);
146
+ mtk_ddp_write(cmdq_pkt,
147
+ DITHER_LSB_ERR_SHIFT_R(MTK_MAX_BPC - bpc) |
148
+ DITHER_ADD_LSHIFT_R(MTK_MAX_BPC - bpc) |
149
+ DITHER_NEW_BIT_MODE,
150
+ comp, DISP_DITHER_15);
151
+ mtk_ddp_write(cmdq_pkt,
152
+ DITHER_LSB_ERR_SHIFT_B(MTK_MAX_BPC - bpc) |
153
+ DITHER_ADD_LSHIFT_B(MTK_MAX_BPC - bpc) |
154
+ DITHER_LSB_ERR_SHIFT_G(MTK_MAX_BPC - bpc) |
155
+ DITHER_ADD_LSHIFT_G(MTK_MAX_BPC - bpc),
156
+ comp, DISP_DITHER_16);
157
+ mtk_ddp_write(cmdq_pkt, DISP_DITHERING, comp, CFG);
95158 }
96159 }
97160
98161 static void mtk_od_config(struct mtk_ddp_comp *comp, unsigned int w,
99162 unsigned int h, unsigned int vrefresh,
100
- unsigned int bpc)
163
+ unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
101164 {
102
- writel(w << 16 | h, comp->regs + DISP_OD_SIZE);
103
- writel(OD_RELAYMODE, comp->regs + DISP_OD_CFG);
104
- mtk_dither_set(comp, bpc, DISP_OD_CFG);
165
+ mtk_ddp_write(cmdq_pkt, w << 16 | h, comp, DISP_OD_SIZE);
166
+ mtk_ddp_write(cmdq_pkt, OD_RELAYMODE, comp, DISP_OD_CFG);
167
+ mtk_dither_set(comp, bpc, DISP_OD_CFG, cmdq_pkt);
105168 }
106169
107170 static void mtk_od_start(struct mtk_ddp_comp *comp)
....@@ -116,9 +179,10 @@
116179
117180 static void mtk_aal_config(struct mtk_ddp_comp *comp, unsigned int w,
118181 unsigned int h, unsigned int vrefresh,
119
- unsigned int bpc)
182
+ unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
120183 {
121
- writel(h << 16 | w, comp->regs + DISP_AAL_SIZE);
184
+ mtk_ddp_write(cmdq_pkt, w << 16 | h, comp, DISP_AAL_SIZE);
185
+ mtk_ddp_write(cmdq_pkt, w << 16 | h, comp, DISP_AAL_OUTPUT_SIZE);
122186 }
123187
124188 static void mtk_aal_start(struct mtk_ddp_comp *comp)
....@@ -131,12 +195,99 @@
131195 writel_relaxed(0x0, comp->regs + DISP_AAL_EN);
132196 }
133197
198
+static void mtk_ccorr_config(struct mtk_ddp_comp *comp, unsigned int w,
199
+ unsigned int h, unsigned int vrefresh,
200
+ unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
201
+{
202
+ mtk_ddp_write(cmdq_pkt, h << 16 | w, comp, DISP_CCORR_SIZE);
203
+ mtk_ddp_write(cmdq_pkt, CCORR_ENGINE_EN, comp, DISP_CCORR_CFG);
204
+}
205
+
206
+static void mtk_ccorr_start(struct mtk_ddp_comp *comp)
207
+{
208
+ writel(CCORR_EN, comp->regs + DISP_CCORR_EN);
209
+}
210
+
211
+static void mtk_ccorr_stop(struct mtk_ddp_comp *comp)
212
+{
213
+ writel_relaxed(0x0, comp->regs + DISP_CCORR_EN);
214
+}
215
+
216
+/* Converts a DRM S31.32 value to the HW S1.10 format. */
217
+static u16 mtk_ctm_s31_32_to_s1_10(u64 in)
218
+{
219
+ u16 r;
220
+
221
+ /* Sign bit. */
222
+ r = in & BIT_ULL(63) ? BIT(11) : 0;
223
+
224
+ if ((in & GENMASK_ULL(62, 33)) > 0) {
225
+ /* identity value 0x100000000 -> 0x400, */
226
+ /* if bigger this, set it to max 0x7ff. */
227
+ r |= GENMASK(10, 0);
228
+ } else {
229
+ /* take the 11 most important bits. */
230
+ r |= (in >> 22) & GENMASK(10, 0);
231
+ }
232
+
233
+ return r;
234
+}
235
+
236
+static void mtk_ccorr_ctm_set(struct mtk_ddp_comp *comp,
237
+ struct drm_crtc_state *state)
238
+{
239
+ struct drm_property_blob *blob = state->ctm;
240
+ struct drm_color_ctm *ctm;
241
+ const u64 *input;
242
+ uint16_t coeffs[9] = { 0 };
243
+ int i;
244
+ struct cmdq_pkt *cmdq_pkt = NULL;
245
+
246
+ if (!blob)
247
+ return;
248
+
249
+ ctm = (struct drm_color_ctm *)blob->data;
250
+ input = ctm->matrix;
251
+
252
+ for (i = 0; i < ARRAY_SIZE(coeffs); i++)
253
+ coeffs[i] = mtk_ctm_s31_32_to_s1_10(input[i]);
254
+
255
+ mtk_ddp_write(cmdq_pkt, coeffs[0] << 16 | coeffs[1],
256
+ comp, DISP_CCORR_COEF_0);
257
+ mtk_ddp_write(cmdq_pkt, coeffs[2] << 16 | coeffs[3],
258
+ comp, DISP_CCORR_COEF_1);
259
+ mtk_ddp_write(cmdq_pkt, coeffs[4] << 16 | coeffs[5],
260
+ comp, DISP_CCORR_COEF_2);
261
+ mtk_ddp_write(cmdq_pkt, coeffs[6] << 16 | coeffs[7],
262
+ comp, DISP_CCORR_COEF_3);
263
+ mtk_ddp_write(cmdq_pkt, coeffs[8] << 16,
264
+ comp, DISP_CCORR_COEF_4);
265
+}
266
+
267
+static void mtk_dither_config(struct mtk_ddp_comp *comp, unsigned int w,
268
+ unsigned int h, unsigned int vrefresh,
269
+ unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
270
+{
271
+ mtk_ddp_write(cmdq_pkt, h << 16 | w, comp, DISP_DITHER_SIZE);
272
+ mtk_ddp_write(cmdq_pkt, DITHER_RELAY_MODE, comp, DISP_DITHER_CFG);
273
+}
274
+
275
+static void mtk_dither_start(struct mtk_ddp_comp *comp)
276
+{
277
+ writel(DITHER_EN, comp->regs + DISP_DITHER_EN);
278
+}
279
+
280
+static void mtk_dither_stop(struct mtk_ddp_comp *comp)
281
+{
282
+ writel_relaxed(0x0, comp->regs + DISP_DITHER_EN);
283
+}
284
+
134285 static void mtk_gamma_config(struct mtk_ddp_comp *comp, unsigned int w,
135286 unsigned int h, unsigned int vrefresh,
136
- unsigned int bpc)
287
+ unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
137288 {
138
- writel(h << 16 | w, comp->regs + DISP_GAMMA_SIZE);
139
- mtk_dither_set(comp, bpc, DISP_GAMMA_CFG);
289
+ mtk_ddp_write(cmdq_pkt, h << 16 | w, comp, DISP_GAMMA_SIZE);
290
+ mtk_dither_set(comp, bpc, DISP_GAMMA_CFG, cmdq_pkt);
140291 }
141292
142293 static void mtk_gamma_start(struct mtk_ddp_comp *comp)
....@@ -179,6 +330,19 @@
179330 .stop = mtk_aal_stop,
180331 };
181332
333
+static const struct mtk_ddp_comp_funcs ddp_ccorr = {
334
+ .config = mtk_ccorr_config,
335
+ .start = mtk_ccorr_start,
336
+ .stop = mtk_ccorr_stop,
337
+ .ctm_set = mtk_ccorr_ctm_set,
338
+};
339
+
340
+static const struct mtk_ddp_comp_funcs ddp_dither = {
341
+ .config = mtk_dither_config,
342
+ .start = mtk_dither_start,
343
+ .stop = mtk_dither_stop,
344
+};
345
+
182346 static const struct mtk_ddp_comp_funcs ddp_gamma = {
183347 .gamma_set = mtk_gamma_set,
184348 .config = mtk_gamma_config,
....@@ -197,11 +361,14 @@
197361
198362 static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
199363 [MTK_DISP_OVL] = "ovl",
364
+ [MTK_DISP_OVL_2L] = "ovl-2l",
200365 [MTK_DISP_RDMA] = "rdma",
201366 [MTK_DISP_WDMA] = "wdma",
202367 [MTK_DISP_COLOR] = "color",
368
+ [MTK_DISP_CCORR] = "ccorr",
203369 [MTK_DISP_AAL] = "aal",
204370 [MTK_DISP_GAMMA] = "gamma",
371
+ [MTK_DISP_DITHER] = "dither",
205372 [MTK_DISP_UFOE] = "ufoe",
206373 [MTK_DSI] = "dsi",
207374 [MTK_DPI] = "dpi",
....@@ -221,8 +388,10 @@
221388 [DDP_COMPONENT_AAL0] = { MTK_DISP_AAL, 0, &ddp_aal },
222389 [DDP_COMPONENT_AAL1] = { MTK_DISP_AAL, 1, &ddp_aal },
223390 [DDP_COMPONENT_BLS] = { MTK_DISP_BLS, 0, NULL },
391
+ [DDP_COMPONENT_CCORR] = { MTK_DISP_CCORR, 0, &ddp_ccorr },
224392 [DDP_COMPONENT_COLOR0] = { MTK_DISP_COLOR, 0, NULL },
225393 [DDP_COMPONENT_COLOR1] = { MTK_DISP_COLOR, 1, NULL },
394
+ [DDP_COMPONENT_DITHER] = { MTK_DISP_DITHER, 0, &ddp_dither },
226395 [DDP_COMPONENT_DPI0] = { MTK_DPI, 0, NULL },
227396 [DDP_COMPONENT_DPI1] = { MTK_DPI, 1, NULL },
228397 [DDP_COMPONENT_DSI0] = { MTK_DSI, 0, NULL },
....@@ -234,6 +403,8 @@
234403 [DDP_COMPONENT_OD1] = { MTK_DISP_OD, 1, &ddp_od },
235404 [DDP_COMPONENT_OVL0] = { MTK_DISP_OVL, 0, NULL },
236405 [DDP_COMPONENT_OVL1] = { MTK_DISP_OVL, 1, NULL },
406
+ [DDP_COMPONENT_OVL_2L0] = { MTK_DISP_OVL_2L, 0, NULL },
407
+ [DDP_COMPONENT_OVL_2L1] = { MTK_DISP_OVL_2L, 1, NULL },
237408 [DDP_COMPONENT_PWM0] = { MTK_DISP_PWM, 0, NULL },
238409 [DDP_COMPONENT_PWM1] = { MTK_DISP_PWM, 1, NULL },
239410 [DDP_COMPONENT_PWM2] = { MTK_DISP_PWM, 2, NULL },
....@@ -244,6 +415,22 @@
244415 [DDP_COMPONENT_WDMA0] = { MTK_DISP_WDMA, 0, NULL },
245416 [DDP_COMPONENT_WDMA1] = { MTK_DISP_WDMA, 1, NULL },
246417 };
418
+
419
+static bool mtk_drm_find_comp_in_ddp(struct mtk_ddp_comp ddp_comp,
420
+ const enum mtk_ddp_comp_id *path,
421
+ unsigned int path_len)
422
+{
423
+ unsigned int i;
424
+
425
+ if (path == NULL)
426
+ return false;
427
+
428
+ for (i = 0U; i < path_len; i++)
429
+ if (ddp_comp.id == path[i])
430
+ return true;
431
+
432
+ return false;
433
+}
247434
248435 int mtk_ddp_comp_get_id(struct device_node *node,
249436 enum mtk_ddp_comp_type comp_type)
....@@ -260,6 +447,26 @@
260447 return -EINVAL;
261448 }
262449
450
+unsigned int mtk_drm_find_possible_crtc_by_comp(struct drm_device *drm,
451
+ struct mtk_ddp_comp ddp_comp)
452
+{
453
+ struct mtk_drm_private *private = drm->dev_private;
454
+ unsigned int ret = 0;
455
+
456
+ if (mtk_drm_find_comp_in_ddp(ddp_comp, private->data->main_path, private->data->main_len))
457
+ ret = BIT(0);
458
+ else if (mtk_drm_find_comp_in_ddp(ddp_comp, private->data->ext_path,
459
+ private->data->ext_len))
460
+ ret = BIT(1);
461
+ else if (mtk_drm_find_comp_in_ddp(ddp_comp, private->data->third_path,
462
+ private->data->third_len))
463
+ ret = BIT(2);
464
+ else
465
+ DRM_INFO("Failed to find comp in ddp table\n");
466
+
467
+ return ret;
468
+}
469
+
263470 int mtk_ddp_comp_init(struct device *dev, struct device_node *node,
264471 struct mtk_ddp_comp *comp, enum mtk_ddp_comp_id comp_id,
265472 const struct mtk_ddp_comp_funcs *funcs)
....@@ -267,6 +474,11 @@
267474 enum mtk_ddp_comp_type type;
268475 struct device_node *larb_node;
269476 struct platform_device *larb_pdev;
477
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
478
+ struct resource res;
479
+ struct cmdq_client_reg cmdq_reg;
480
+ int ret;
481
+#endif
270482
271483 if (comp_id < 0 || comp_id >= DDP_COMPONENT_ID_MAX)
272484 return -EINVAL;
....@@ -294,11 +506,12 @@
294506 comp->irq = of_irq_get(node, 0);
295507 comp->clk = of_clk_get(node, 0);
296508 if (IS_ERR(comp->clk))
297
- comp->clk = NULL;
509
+ return PTR_ERR(comp->clk);
298510
299511 /* Only DMA capable components need the LARB property */
300512 comp->larb_dev = NULL;
301513 if (type != MTK_DISP_OVL &&
514
+ type != MTK_DISP_OVL_2L &&
302515 type != MTK_DISP_RDMA &&
303516 type != MTK_DISP_WDMA)
304517 return 0;
....@@ -320,6 +533,20 @@
320533
321534 comp->larb_dev = &larb_pdev->dev;
322535
536
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
537
+ if (of_address_to_resource(node, 0, &res) != 0) {
538
+ dev_err(dev, "Missing reg in %s node\n", node->full_name);
539
+ put_device(&larb_pdev->dev);
540
+ return -EINVAL;
541
+ }
542
+ comp->regs_pa = res.start;
543
+
544
+ ret = cmdq_dev_get_client_reg(dev, &cmdq_reg, 0);
545
+ if (ret)
546
+ dev_dbg(dev, "get mediatek,gce-client-reg fail!\n");
547
+ else
548
+ comp->subsys = cmdq_reg.subsys;
549
+#endif
323550 return 0;
324551 }
325552