1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
3 */
4
5 #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__
6 #include <linux/slab.h>
7 #include <linux/of_address.h>
8 #include <linux/platform_device.h>
9 #include "dpu_hw_mdss.h"
10 #include "dpu_hw_catalog.h"
11 #include "dpu_hw_catalog_format.h"
12 #include "dpu_kms.h"
13
14 #define VIG_MASK \
15 (BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) |\
16 BIT(DPU_SSPP_CSC_10BIT) | BIT(DPU_SSPP_CDP) | BIT(DPU_SSPP_QOS_8LVL) |\
17 BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_EXCL_RECT))
18
19 #define VIG_SDM845_MASK \
20 (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
21
22 #define VIG_SC7180_MASK \
23 (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED4))
24
25 #define DMA_SDM845_MASK \
26 (BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) | BIT(DPU_SSPP_QOS_8LVL) |\
27 BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_TS_PREFILL_REC1) |\
28 BIT(DPU_SSPP_CDP) | BIT(DPU_SSPP_EXCL_RECT))
29
30 #define DMA_CURSOR_SDM845_MASK \
31 (DMA_SDM845_MASK | BIT(DPU_SSPP_CURSOR))
32
33 #define MIXER_SDM845_MASK \
34 (BIT(DPU_MIXER_SOURCESPLIT) | BIT(DPU_DIM_LAYER))
35
36 #define MIXER_SC7180_MASK \
37 (BIT(DPU_DIM_LAYER))
38
39 #define PINGPONG_SDM845_MASK BIT(DPU_PINGPONG_DITHER)
40
41 #define PINGPONG_SDM845_SPLIT_MASK \
42 (PINGPONG_SDM845_MASK | BIT(DPU_PINGPONG_TE2))
43
44 #define DSPP_SC7180_MASK BIT(DPU_DSPP_PCC)
45
46 #define INTF_SDM845_MASK (0)
47
48 #define INTF_SC7180_MASK BIT(DPU_INTF_INPUT_CTRL) | BIT(DPU_INTF_TE)
49
50 #define DEFAULT_PIXEL_RAM_SIZE (50 * 1024)
51 #define DEFAULT_DPU_LINE_WIDTH 2048
52 #define DEFAULT_DPU_OUTPUT_LINE_WIDTH 2560
53
54 #define MAX_HORZ_DECIMATION 4
55 #define MAX_VERT_DECIMATION 4
56
57 #define MAX_UPSCALE_RATIO 20
58 #define MAX_DOWNSCALE_RATIO 4
59 #define SSPP_UNITY_SCALE 1
60
61 #define STRCAT(X, Y) (X Y)
62
63 /*************************************************************
64 * DPU sub blocks config
65 *************************************************************/
66 /* DPU top level caps */
67 static const struct dpu_caps sdm845_dpu_caps = {
68 .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
69 .max_mixer_blendstages = 0xb,
70 .qseed_type = DPU_SSPP_SCALER_QSEED3,
71 .smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
72 .ubwc_version = DPU_HW_UBWC_VER_20,
73 .has_src_split = true,
74 .has_dim_layer = true,
75 .has_idle_pc = true,
76 .has_3d_merge = true,
77 .max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
78 .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
79 .max_hdeci_exp = MAX_HORZ_DECIMATION,
80 .max_vdeci_exp = MAX_VERT_DECIMATION,
81 };
82
83 static const struct dpu_caps sc7180_dpu_caps = {
84 .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
85 .max_mixer_blendstages = 0x9,
86 .qseed_type = DPU_SSPP_SCALER_QSEED4,
87 .smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
88 .ubwc_version = DPU_HW_UBWC_VER_20,
89 .has_dim_layer = true,
90 .has_idle_pc = true,
91 .max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
92 .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
93 };
94
95 static const struct dpu_caps sm8150_dpu_caps = {
96 .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
97 .max_mixer_blendstages = 0xb,
98 .qseed_type = DPU_SSPP_SCALER_QSEED3,
99 .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
100 .ubwc_version = DPU_HW_UBWC_VER_30,
101 .has_src_split = true,
102 .has_dim_layer = true,
103 .has_idle_pc = true,
104 .has_3d_merge = true,
105 .max_linewidth = 4096,
106 .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
107 .max_hdeci_exp = MAX_HORZ_DECIMATION,
108 .max_vdeci_exp = MAX_VERT_DECIMATION,
109 };
110
111 static const struct dpu_caps sm8250_dpu_caps = {
112 .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
113 .max_mixer_blendstages = 0xb,
114 .max_linewidth = 4096,
115 .qseed_type = DPU_SSPP_SCALER_QSEED3, /* TODO: qseed3 lite */
116 .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
117 .ubwc_version = DPU_HW_UBWC_VER_40,
118 .has_src_split = true,
119 .has_dim_layer = true,
120 .has_idle_pc = true,
121 .has_3d_merge = true,
122 .max_linewidth = 4096,
123 .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
124 };
125
126 static const struct dpu_mdp_cfg sdm845_mdp[] = {
127 {
128 .name = "top_0", .id = MDP_TOP,
129 .base = 0x0, .len = 0x45C,
130 .features = 0,
131 .highest_bank_bit = 0x2,
132 .clk_ctrls[DPU_CLK_CTRL_VIG0] = {
133 .reg_off = 0x2AC, .bit_off = 0},
134 .clk_ctrls[DPU_CLK_CTRL_VIG1] = {
135 .reg_off = 0x2B4, .bit_off = 0},
136 .clk_ctrls[DPU_CLK_CTRL_VIG2] = {
137 .reg_off = 0x2BC, .bit_off = 0},
138 .clk_ctrls[DPU_CLK_CTRL_VIG3] = {
139 .reg_off = 0x2C4, .bit_off = 0},
140 .clk_ctrls[DPU_CLK_CTRL_DMA0] = {
141 .reg_off = 0x2AC, .bit_off = 8},
142 .clk_ctrls[DPU_CLK_CTRL_DMA1] = {
143 .reg_off = 0x2B4, .bit_off = 8},
144 .clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
145 .reg_off = 0x2BC, .bit_off = 8},
146 .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
147 .reg_off = 0x2C4, .bit_off = 8},
148 },
149 };
150
151 static const struct dpu_mdp_cfg sc7180_mdp[] = {
152 {
153 .name = "top_0", .id = MDP_TOP,
154 .base = 0x0, .len = 0x494,
155 .features = 0,
156 .highest_bank_bit = 0x3,
157 .clk_ctrls[DPU_CLK_CTRL_VIG0] = {
158 .reg_off = 0x2AC, .bit_off = 0},
159 .clk_ctrls[DPU_CLK_CTRL_DMA0] = {
160 .reg_off = 0x2AC, .bit_off = 8},
161 .clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
162 .reg_off = 0x2B4, .bit_off = 8},
163 .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
164 .reg_off = 0x2C4, .bit_off = 8},
165 },
166 };
167
168 static const struct dpu_mdp_cfg sm8250_mdp[] = {
169 {
170 .name = "top_0", .id = MDP_TOP,
171 .base = 0x0, .len = 0x45C,
172 .features = 0,
173 .highest_bank_bit = 0x3, /* TODO: 2 for LP_DDR4 */
174 .clk_ctrls[DPU_CLK_CTRL_VIG0] = {
175 .reg_off = 0x2AC, .bit_off = 0},
176 .clk_ctrls[DPU_CLK_CTRL_VIG1] = {
177 .reg_off = 0x2B4, .bit_off = 0},
178 .clk_ctrls[DPU_CLK_CTRL_VIG2] = {
179 .reg_off = 0x2BC, .bit_off = 0},
180 .clk_ctrls[DPU_CLK_CTRL_VIG3] = {
181 .reg_off = 0x2C4, .bit_off = 0},
182 .clk_ctrls[DPU_CLK_CTRL_DMA0] = {
183 .reg_off = 0x2AC, .bit_off = 8},
184 .clk_ctrls[DPU_CLK_CTRL_DMA1] = {
185 .reg_off = 0x2B4, .bit_off = 8},
186 .clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
187 .reg_off = 0x2BC, .bit_off = 8},
188 .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
189 .reg_off = 0x2C4, .bit_off = 8},
190 .clk_ctrls[DPU_CLK_CTRL_REG_DMA] = {
191 .reg_off = 0x2BC, .bit_off = 20},
192 },
193 };
194
195 /*************************************************************
196 * CTL sub blocks config
197 *************************************************************/
198 static const struct dpu_ctl_cfg sdm845_ctl[] = {
199 {
200 .name = "ctl_0", .id = CTL_0,
201 .base = 0x1000, .len = 0xE4,
202 .features = BIT(DPU_CTL_SPLIT_DISPLAY)
203 },
204 {
205 .name = "ctl_1", .id = CTL_1,
206 .base = 0x1200, .len = 0xE4,
207 .features = BIT(DPU_CTL_SPLIT_DISPLAY)
208 },
209 {
210 .name = "ctl_2", .id = CTL_2,
211 .base = 0x1400, .len = 0xE4,
212 .features = 0
213 },
214 {
215 .name = "ctl_3", .id = CTL_3,
216 .base = 0x1600, .len = 0xE4,
217 .features = 0
218 },
219 {
220 .name = "ctl_4", .id = CTL_4,
221 .base = 0x1800, .len = 0xE4,
222 .features = 0
223 },
224 };
225
226 static const struct dpu_ctl_cfg sc7180_ctl[] = {
227 {
228 .name = "ctl_0", .id = CTL_0,
229 .base = 0x1000, .len = 0xE4,
230 .features = BIT(DPU_CTL_ACTIVE_CFG)
231 },
232 {
233 .name = "ctl_1", .id = CTL_1,
234 .base = 0x1200, .len = 0xE4,
235 .features = BIT(DPU_CTL_ACTIVE_CFG)
236 },
237 {
238 .name = "ctl_2", .id = CTL_2,
239 .base = 0x1400, .len = 0xE4,
240 .features = BIT(DPU_CTL_ACTIVE_CFG)
241 },
242 };
243
244 static const struct dpu_ctl_cfg sm8150_ctl[] = {
245 {
246 .name = "ctl_0", .id = CTL_0,
247 .base = 0x1000, .len = 0x1e0,
248 .features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY)
249 },
250 {
251 .name = "ctl_1", .id = CTL_1,
252 .base = 0x1200, .len = 0x1e0,
253 .features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY)
254 },
255 {
256 .name = "ctl_2", .id = CTL_2,
257 .base = 0x1400, .len = 0x1e0,
258 .features = BIT(DPU_CTL_ACTIVE_CFG)
259 },
260 {
261 .name = "ctl_3", .id = CTL_3,
262 .base = 0x1600, .len = 0x1e0,
263 .features = BIT(DPU_CTL_ACTIVE_CFG)
264 },
265 {
266 .name = "ctl_4", .id = CTL_4,
267 .base = 0x1800, .len = 0x1e0,
268 .features = BIT(DPU_CTL_ACTIVE_CFG)
269 },
270 {
271 .name = "ctl_5", .id = CTL_5,
272 .base = 0x1a00, .len = 0x1e0,
273 .features = BIT(DPU_CTL_ACTIVE_CFG)
274 },
275 };
276
277 /*************************************************************
278 * SSPP sub blocks config
279 *************************************************************/
280
281 /* SSPP common configuration */
282
283 #define _VIG_SBLK(num, sdma_pri, qseed_ver) \
284 { \
285 .maxdwnscale = MAX_DOWNSCALE_RATIO, \
286 .maxupscale = MAX_UPSCALE_RATIO, \
287 .smart_dma_priority = sdma_pri, \
288 .src_blk = {.name = STRCAT("sspp_src_", num), \
289 .id = DPU_SSPP_SRC, .base = 0x00, .len = 0x150,}, \
290 .scaler_blk = {.name = STRCAT("sspp_scaler", num), \
291 .id = qseed_ver, \
292 .base = 0xa00, .len = 0xa0,}, \
293 .csc_blk = {.name = STRCAT("sspp_csc", num), \
294 .id = DPU_SSPP_CSC_10BIT, \
295 .base = 0x1a00, .len = 0x100,}, \
296 .format_list = plane_formats_yuv, \
297 .num_formats = ARRAY_SIZE(plane_formats_yuv), \
298 .virt_format_list = plane_formats, \
299 .virt_num_formats = ARRAY_SIZE(plane_formats), \
300 }
301
302 #define _DMA_SBLK(num, sdma_pri) \
303 { \
304 .maxdwnscale = SSPP_UNITY_SCALE, \
305 .maxupscale = SSPP_UNITY_SCALE, \
306 .smart_dma_priority = sdma_pri, \
307 .src_blk = {.name = STRCAT("sspp_src_", num), \
308 .id = DPU_SSPP_SRC, .base = 0x00, .len = 0x150,}, \
309 .format_list = plane_formats, \
310 .num_formats = ARRAY_SIZE(plane_formats), \
311 .virt_format_list = plane_formats, \
312 .virt_num_formats = ARRAY_SIZE(plane_formats), \
313 }
314
315 static const struct dpu_sspp_sub_blks sdm845_vig_sblk_0 =
316 _VIG_SBLK("0", 5, DPU_SSPP_SCALER_QSEED3);
317 static const struct dpu_sspp_sub_blks sdm845_vig_sblk_1 =
318 _VIG_SBLK("1", 6, DPU_SSPP_SCALER_QSEED3);
319 static const struct dpu_sspp_sub_blks sdm845_vig_sblk_2 =
320 _VIG_SBLK("2", 7, DPU_SSPP_SCALER_QSEED3);
321 static const struct dpu_sspp_sub_blks sdm845_vig_sblk_3 =
322 _VIG_SBLK("3", 8, DPU_SSPP_SCALER_QSEED3);
323
324 static const struct dpu_sspp_sub_blks sdm845_dma_sblk_0 = _DMA_SBLK("8", 1);
325 static const struct dpu_sspp_sub_blks sdm845_dma_sblk_1 = _DMA_SBLK("9", 2);
326 static const struct dpu_sspp_sub_blks sdm845_dma_sblk_2 = _DMA_SBLK("10", 3);
327 static const struct dpu_sspp_sub_blks sdm845_dma_sblk_3 = _DMA_SBLK("11", 4);
328
329 #define SSPP_BLK(_name, _id, _base, _features, \
330 _sblk, _xinid, _type, _clkctrl) \
331 { \
332 .name = _name, .id = _id, \
333 .base = _base, .len = 0x1c8, \
334 .features = _features, \
335 .sblk = &_sblk, \
336 .xin_id = _xinid, \
337 .type = _type, \
338 .clk_ctrl = _clkctrl \
339 }
340
341 static const struct dpu_sspp_cfg sdm845_sspp[] = {
342 SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SDM845_MASK,
343 sdm845_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0),
344 SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SDM845_MASK,
345 sdm845_vig_sblk_1, 4, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1),
346 SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SDM845_MASK,
347 sdm845_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2),
348 SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SDM845_MASK,
349 sdm845_vig_sblk_3, 12, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3),
350 SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, DMA_SDM845_MASK,
351 sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0),
352 SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, DMA_SDM845_MASK,
353 sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1),
354 SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, DMA_CURSOR_SDM845_MASK,
355 sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR0),
356 SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, DMA_CURSOR_SDM845_MASK,
357 sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1),
358 };
359
360 static const struct dpu_sspp_sub_blks sc7180_vig_sblk_0 =
361 _VIG_SBLK("0", 4, DPU_SSPP_SCALER_QSEED4);
362
363 static const struct dpu_sspp_cfg sc7180_sspp[] = {
364 SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SC7180_MASK,
365 sc7180_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0),
366 SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, DMA_SDM845_MASK,
367 sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0),
368 SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, DMA_CURSOR_SDM845_MASK,
369 sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR0),
370 SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, DMA_CURSOR_SDM845_MASK,
371 sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1),
372 };
373
374 /*************************************************************
375 * MIXER sub blocks config
376 *************************************************************/
377
378 /* SDM845 */
379
380 static const struct dpu_lm_sub_blks sdm845_lm_sblk = {
381 .maxwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
382 .maxblendstages = 11, /* excluding base layer */
383 .blendstage_base = { /* offsets relative to mixer base */
384 0x20, 0x38, 0x50, 0x68, 0x80, 0x98,
385 0xb0, 0xc8, 0xe0, 0xf8, 0x110
386 },
387 };
388
389 #define LM_BLK(_name, _id, _base, _fmask, _sblk, _pp, _lmpair, _dspp) \
390 { \
391 .name = _name, .id = _id, \
392 .base = _base, .len = 0x320, \
393 .features = _fmask, \
394 .sblk = _sblk, \
395 .pingpong = _pp, \
396 .lm_pair_mask = (1 << _lmpair), \
397 .dspp = _dspp \
398 }
399
400 static const struct dpu_lm_cfg sdm845_lm[] = {
401 LM_BLK("lm_0", LM_0, 0x44000, MIXER_SDM845_MASK,
402 &sdm845_lm_sblk, PINGPONG_0, LM_1, 0),
403 LM_BLK("lm_1", LM_1, 0x45000, MIXER_SDM845_MASK,
404 &sdm845_lm_sblk, PINGPONG_1, LM_0, 0),
405 LM_BLK("lm_2", LM_2, 0x46000, MIXER_SDM845_MASK,
406 &sdm845_lm_sblk, PINGPONG_2, LM_5, 0),
407 LM_BLK("lm_3", LM_3, 0x0, MIXER_SDM845_MASK,
408 &sdm845_lm_sblk, PINGPONG_MAX, 0, 0),
409 LM_BLK("lm_4", LM_4, 0x0, MIXER_SDM845_MASK,
410 &sdm845_lm_sblk, PINGPONG_MAX, 0, 0),
411 LM_BLK("lm_5", LM_5, 0x49000, MIXER_SDM845_MASK,
412 &sdm845_lm_sblk, PINGPONG_3, LM_2, 0),
413 };
414
415 /* SC7180 */
416
417 static const struct dpu_lm_sub_blks sc7180_lm_sblk = {
418 .maxwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
419 .maxblendstages = 7, /* excluding base layer */
420 .blendstage_base = { /* offsets relative to mixer base */
421 0x20, 0x38, 0x50, 0x68, 0x80, 0x98, 0xb0
422 },
423 };
424
425 static const struct dpu_lm_cfg sc7180_lm[] = {
426 LM_BLK("lm_0", LM_0, 0x44000, MIXER_SC7180_MASK,
427 &sc7180_lm_sblk, PINGPONG_0, LM_1, DSPP_0),
428 LM_BLK("lm_1", LM_1, 0x45000, MIXER_SC7180_MASK,
429 &sc7180_lm_sblk, PINGPONG_1, LM_0, 0),
430 };
431
432 /* SM8150 */
433
434 static const struct dpu_lm_cfg sm8150_lm[] = {
435 LM_BLK("lm_0", LM_0, 0x44000, MIXER_SDM845_MASK,
436 &sdm845_lm_sblk, PINGPONG_0, LM_1, 0),
437 LM_BLK("lm_1", LM_1, 0x45000, MIXER_SDM845_MASK,
438 &sdm845_lm_sblk, PINGPONG_1, LM_0, 0),
439 LM_BLK("lm_2", LM_2, 0x46000, MIXER_SDM845_MASK,
440 &sdm845_lm_sblk, PINGPONG_2, LM_3, 0),
441 LM_BLK("lm_3", LM_3, 0x47000, MIXER_SDM845_MASK,
442 &sdm845_lm_sblk, PINGPONG_3, LM_2, 0),
443 LM_BLK("lm_4", LM_4, 0x48000, MIXER_SDM845_MASK,
444 &sdm845_lm_sblk, PINGPONG_4, LM_5, 0),
445 LM_BLK("lm_5", LM_5, 0x49000, MIXER_SDM845_MASK,
446 &sdm845_lm_sblk, PINGPONG_5, LM_4, 0),
447 };
448
449 /*************************************************************
450 * DSPP sub blocks config
451 *************************************************************/
452 static const struct dpu_dspp_sub_blks sc7180_dspp_sblk = {
453 .pcc = {.id = DPU_DSPP_PCC, .base = 0x1700,
454 .len = 0x90, .version = 0x10000},
455 };
456
457 #define DSPP_BLK(_name, _id, _base) \
458 {\
459 .name = _name, .id = _id, \
460 .base = _base, .len = 0x1800, \
461 .features = DSPP_SC7180_MASK, \
462 .sblk = &sc7180_dspp_sblk \
463 }
464
465 static const struct dpu_dspp_cfg sc7180_dspp[] = {
466 DSPP_BLK("dspp_0", DSPP_0, 0x54000),
467 };
468
469 /*************************************************************
470 * PINGPONG sub blocks config
471 *************************************************************/
472 static const struct dpu_pingpong_sub_blks sdm845_pp_sblk_te = {
473 .te2 = {.id = DPU_PINGPONG_TE2, .base = 0x2000, .len = 0x0,
474 .version = 0x1},
475 .dither = {.id = DPU_PINGPONG_DITHER, .base = 0x30e0,
476 .len = 0x20, .version = 0x10000},
477 };
478
479 static const struct dpu_pingpong_sub_blks sdm845_pp_sblk = {
480 .dither = {.id = DPU_PINGPONG_DITHER, .base = 0x30e0,
481 .len = 0x20, .version = 0x10000},
482 };
483
484 #define PP_BLK_TE(_name, _id, _base) \
485 {\
486 .name = _name, .id = _id, \
487 .base = _base, .len = 0xd4, \
488 .features = PINGPONG_SDM845_SPLIT_MASK, \
489 .sblk = &sdm845_pp_sblk_te \
490 }
491 #define PP_BLK(_name, _id, _base) \
492 {\
493 .name = _name, .id = _id, \
494 .base = _base, .len = 0xd4, \
495 .features = PINGPONG_SDM845_MASK, \
496 .sblk = &sdm845_pp_sblk \
497 }
498
499 static const struct dpu_pingpong_cfg sdm845_pp[] = {
500 PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000),
501 PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800),
502 PP_BLK("pingpong_2", PINGPONG_2, 0x71000),
503 PP_BLK("pingpong_3", PINGPONG_3, 0x71800),
504 };
505
506 static struct dpu_pingpong_cfg sc7180_pp[] = {
507 PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000),
508 PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800),
509 };
510
511 static const struct dpu_pingpong_cfg sm8150_pp[] = {
512 PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000),
513 PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800),
514 PP_BLK("pingpong_2", PINGPONG_2, 0x71000),
515 PP_BLK("pingpong_3", PINGPONG_3, 0x71800),
516 PP_BLK("pingpong_4", PINGPONG_4, 0x72000),
517 PP_BLK("pingpong_5", PINGPONG_5, 0x72800),
518 };
519
520 /*************************************************************
521 * INTF sub blocks config
522 *************************************************************/
523 #define INTF_BLK(_name, _id, _base, _type, _ctrl_id, _features) \
524 {\
525 .name = _name, .id = _id, \
526 .base = _base, .len = 0x280, \
527 .features = _features, \
528 .type = _type, \
529 .controller_id = _ctrl_id, \
530 .prog_fetch_lines_worst_case = 24 \
531 }
532
533 static const struct dpu_intf_cfg sdm845_intf[] = {
534 INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, INTF_SDM845_MASK),
535 INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, INTF_SDM845_MASK),
536 INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, INTF_SDM845_MASK),
537 INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 1, INTF_SDM845_MASK),
538 };
539
540 static const struct dpu_intf_cfg sc7180_intf[] = {
541 INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, INTF_SC7180_MASK),
542 INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, INTF_SC7180_MASK),
543 };
544
545 static const struct dpu_intf_cfg sm8150_intf[] = {
546 INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, INTF_SC7180_MASK),
547 INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, INTF_SC7180_MASK),
548 INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, INTF_SC7180_MASK),
549 INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 1, INTF_SC7180_MASK),
550 };
551
552 /*************************************************************
553 * VBIF sub blocks config
554 *************************************************************/
555 /* VBIF QOS remap */
556 static const u32 sdm845_rt_pri_lvl[] = {3, 3, 4, 4, 5, 5, 6, 6};
557 static const u32 sdm845_nrt_pri_lvl[] = {3, 3, 3, 3, 3, 3, 3, 3};
558
559 static const struct dpu_vbif_cfg sdm845_vbif[] = {
560 {
561 .name = "vbif_0", .id = VBIF_0,
562 .base = 0, .len = 0x1040,
563 .features = BIT(DPU_VBIF_QOS_REMAP),
564 .xin_halt_timeout = 0x4000,
565 .qos_rt_tbl = {
566 .npriority_lvl = ARRAY_SIZE(sdm845_rt_pri_lvl),
567 .priority_lvl = sdm845_rt_pri_lvl,
568 },
569 .qos_nrt_tbl = {
570 .npriority_lvl = ARRAY_SIZE(sdm845_nrt_pri_lvl),
571 .priority_lvl = sdm845_nrt_pri_lvl,
572 },
573 .memtype_count = 14,
574 .memtype = {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
575 },
576 };
577
578 static const struct dpu_reg_dma_cfg sdm845_regdma = {
579 .base = 0x0, .version = 0x1, .trigger_sel_off = 0x119c
580 };
581
582 static const struct dpu_reg_dma_cfg sm8150_regdma = {
583 .base = 0x0, .version = 0x00010001, .trigger_sel_off = 0x119c
584 };
585
586 static const struct dpu_reg_dma_cfg sm8250_regdma = {
587 .base = 0x0,
588 .version = 0x00010002,
589 .trigger_sel_off = 0x119c,
590 .xin_id = 7,
591 .clk_ctrl = DPU_CLK_CTRL_REG_DMA,
592 };
593
594 /*************************************************************
595 * PERF data config
596 *************************************************************/
597
598 /* SSPP QOS LUTs */
599 static const struct dpu_qos_lut_entry sdm845_qos_linear[] = {
600 {.fl = 4, .lut = 0x357},
601 {.fl = 5, .lut = 0x3357},
602 {.fl = 6, .lut = 0x23357},
603 {.fl = 7, .lut = 0x223357},
604 {.fl = 8, .lut = 0x2223357},
605 {.fl = 9, .lut = 0x22223357},
606 {.fl = 10, .lut = 0x222223357},
607 {.fl = 11, .lut = 0x2222223357},
608 {.fl = 12, .lut = 0x22222223357},
609 {.fl = 13, .lut = 0x222222223357},
610 {.fl = 14, .lut = 0x1222222223357},
611 {.fl = 0, .lut = 0x11222222223357}
612 };
613
614 static const struct dpu_qos_lut_entry sc7180_qos_linear[] = {
615 {.fl = 0, .lut = 0x0011222222335777},
616 };
617
618 static const struct dpu_qos_lut_entry sm8150_qos_linear[] = {
619 {.fl = 0, .lut = 0x0011222222223357 },
620 };
621
622 static const struct dpu_qos_lut_entry sdm845_qos_macrotile[] = {
623 {.fl = 10, .lut = 0x344556677},
624 {.fl = 11, .lut = 0x3344556677},
625 {.fl = 12, .lut = 0x23344556677},
626 {.fl = 13, .lut = 0x223344556677},
627 {.fl = 14, .lut = 0x1223344556677},
628 {.fl = 0, .lut = 0x112233344556677},
629 };
630
631 static const struct dpu_qos_lut_entry sc7180_qos_macrotile[] = {
632 {.fl = 0, .lut = 0x0011223344556677},
633 };
634
635 static const struct dpu_qos_lut_entry sdm845_qos_nrt[] = {
636 {.fl = 0, .lut = 0x0},
637 };
638
639 static const struct dpu_qos_lut_entry sc7180_qos_nrt[] = {
640 {.fl = 0, .lut = 0x0},
641 };
642
643 static const struct dpu_perf_cfg sdm845_perf_data = {
644 .max_bw_low = 6800000,
645 .max_bw_high = 6800000,
646 .min_core_ib = 2400000,
647 .min_llcc_ib = 800000,
648 .min_dram_ib = 800000,
649 .core_ib_ff = "6.0",
650 .core_clk_ff = "1.0",
651 .comp_ratio_rt =
652 "NV12/5/1/1.23 AB24/5/1/1.23 XB24/5/1/1.23",
653 .comp_ratio_nrt =
654 "NV12/5/1/1.25 AB24/5/1/1.25 XB24/5/1/1.25",
655 .undersized_prefill_lines = 2,
656 .xtra_prefill_lines = 2,
657 .dest_scale_prefill_lines = 3,
658 .macrotile_prefill_lines = 4,
659 .yuv_nv12_prefill_lines = 8,
660 .linear_prefill_lines = 1,
661 .downscaling_prefill_lines = 1,
662 .amortizable_threshold = 25,
663 .min_prefill_lines = 24,
664 .danger_lut_tbl = {0xf, 0xffff, 0x0},
665 .qos_lut_tbl = {
666 {.nentry = ARRAY_SIZE(sdm845_qos_linear),
667 .entries = sdm845_qos_linear
668 },
669 {.nentry = ARRAY_SIZE(sdm845_qos_macrotile),
670 .entries = sdm845_qos_macrotile
671 },
672 {.nentry = ARRAY_SIZE(sdm845_qos_nrt),
673 .entries = sdm845_qos_nrt
674 },
675 },
676 .cdp_cfg = {
677 {.rd_enable = 1, .wr_enable = 1},
678 {.rd_enable = 1, .wr_enable = 0}
679 },
680 };
681
682 static const struct dpu_perf_cfg sc7180_perf_data = {
683 .max_bw_low = 6800000,
684 .max_bw_high = 6800000,
685 .min_core_ib = 2400000,
686 .min_llcc_ib = 800000,
687 .min_dram_ib = 1600000,
688 .min_prefill_lines = 24,
689 .danger_lut_tbl = {0xff, 0xffff, 0x0},
690 .qos_lut_tbl = {
691 {.nentry = ARRAY_SIZE(sc7180_qos_linear),
692 .entries = sc7180_qos_linear
693 },
694 {.nentry = ARRAY_SIZE(sc7180_qos_macrotile),
695 .entries = sc7180_qos_macrotile
696 },
697 {.nentry = ARRAY_SIZE(sc7180_qos_nrt),
698 .entries = sc7180_qos_nrt
699 },
700 },
701 .cdp_cfg = {
702 {.rd_enable = 1, .wr_enable = 1},
703 {.rd_enable = 1, .wr_enable = 0}
704 },
705 .clk_inefficiency_factor = 105,
706 .bw_inefficiency_factor = 120,
707 };
708
709 static const struct dpu_perf_cfg sm8150_perf_data = {
710 .max_bw_low = 12800000,
711 .max_bw_high = 12800000,
712 .min_core_ib = 2400000,
713 .min_llcc_ib = 800000,
714 .min_dram_ib = 800000,
715 .danger_lut_tbl = {0xf, 0xffff, 0x0},
716 .qos_lut_tbl = {
717 {.nentry = ARRAY_SIZE(sm8150_qos_linear),
718 .entries = sm8150_qos_linear
719 },
720 {.nentry = ARRAY_SIZE(sc7180_qos_macrotile),
721 .entries = sc7180_qos_macrotile
722 },
723 {.nentry = ARRAY_SIZE(sc7180_qos_nrt),
724 .entries = sc7180_qos_nrt
725 },
726 /* TODO: macrotile-qseed is different from macrotile */
727 },
728 .cdp_cfg = {
729 {.rd_enable = 1, .wr_enable = 1},
730 {.rd_enable = 1, .wr_enable = 0}
731 },
732 };
733
734 static const struct dpu_perf_cfg sm8250_perf_data = {
735 .max_bw_low = 13700000,
736 .max_bw_high = 16600000,
737 .min_core_ib = 4800000,
738 .min_llcc_ib = 0,
739 .min_dram_ib = 800000,
740 .danger_lut_tbl = {0xf, 0xffff, 0x0},
741 .qos_lut_tbl = {
742 {.nentry = ARRAY_SIZE(sc7180_qos_linear),
743 .entries = sc7180_qos_linear
744 },
745 {.nentry = ARRAY_SIZE(sc7180_qos_macrotile),
746 .entries = sc7180_qos_macrotile
747 },
748 {.nentry = ARRAY_SIZE(sc7180_qos_nrt),
749 .entries = sc7180_qos_nrt
750 },
751 /* TODO: macrotile-qseed is different from macrotile */
752 },
753 .cdp_cfg = {
754 {.rd_enable = 1, .wr_enable = 1},
755 {.rd_enable = 1, .wr_enable = 0}
756 },
757 };
758
759 /*************************************************************
760 * Hardware catalog init
761 *************************************************************/
762
763 /*
764 * sdm845_cfg_init(): populate sdm845 dpu sub-blocks reg offsets
765 * and instance counts.
766 */
sdm845_cfg_init(struct dpu_mdss_cfg * dpu_cfg)767 static void sdm845_cfg_init(struct dpu_mdss_cfg *dpu_cfg)
768 {
769 *dpu_cfg = (struct dpu_mdss_cfg){
770 .caps = &sdm845_dpu_caps,
771 .mdp_count = ARRAY_SIZE(sdm845_mdp),
772 .mdp = sdm845_mdp,
773 .ctl_count = ARRAY_SIZE(sdm845_ctl),
774 .ctl = sdm845_ctl,
775 .sspp_count = ARRAY_SIZE(sdm845_sspp),
776 .sspp = sdm845_sspp,
777 .mixer_count = ARRAY_SIZE(sdm845_lm),
778 .mixer = sdm845_lm,
779 .pingpong_count = ARRAY_SIZE(sdm845_pp),
780 .pingpong = sdm845_pp,
781 .intf_count = ARRAY_SIZE(sdm845_intf),
782 .intf = sdm845_intf,
783 .vbif_count = ARRAY_SIZE(sdm845_vbif),
784 .vbif = sdm845_vbif,
785 .reg_dma_count = 1,
786 .dma_cfg = sdm845_regdma,
787 .perf = sdm845_perf_data,
788 .mdss_irqs = 0x3ff,
789 };
790 }
791
792 /*
793 * sc7180_cfg_init(): populate sc7180 dpu sub-blocks reg offsets
794 * and instance counts.
795 */
sc7180_cfg_init(struct dpu_mdss_cfg * dpu_cfg)796 static void sc7180_cfg_init(struct dpu_mdss_cfg *dpu_cfg)
797 {
798 *dpu_cfg = (struct dpu_mdss_cfg){
799 .caps = &sc7180_dpu_caps,
800 .mdp_count = ARRAY_SIZE(sc7180_mdp),
801 .mdp = sc7180_mdp,
802 .ctl_count = ARRAY_SIZE(sc7180_ctl),
803 .ctl = sc7180_ctl,
804 .sspp_count = ARRAY_SIZE(sc7180_sspp),
805 .sspp = sc7180_sspp,
806 .mixer_count = ARRAY_SIZE(sc7180_lm),
807 .mixer = sc7180_lm,
808 .dspp_count = ARRAY_SIZE(sc7180_dspp),
809 .dspp = sc7180_dspp,
810 .pingpong_count = ARRAY_SIZE(sc7180_pp),
811 .pingpong = sc7180_pp,
812 .intf_count = ARRAY_SIZE(sc7180_intf),
813 .intf = sc7180_intf,
814 .vbif_count = ARRAY_SIZE(sdm845_vbif),
815 .vbif = sdm845_vbif,
816 .reg_dma_count = 1,
817 .dma_cfg = sdm845_regdma,
818 .perf = sc7180_perf_data,
819 .mdss_irqs = 0x3f,
820 };
821 }
822
823 /*
824 * sm8150_cfg_init(): populate sm8150 dpu sub-blocks reg offsets
825 * and instance counts.
826 */
sm8150_cfg_init(struct dpu_mdss_cfg * dpu_cfg)827 static void sm8150_cfg_init(struct dpu_mdss_cfg *dpu_cfg)
828 {
829 *dpu_cfg = (struct dpu_mdss_cfg){
830 .caps = &sm8150_dpu_caps,
831 .mdp_count = ARRAY_SIZE(sdm845_mdp),
832 .mdp = sdm845_mdp,
833 .ctl_count = ARRAY_SIZE(sm8150_ctl),
834 .ctl = sm8150_ctl,
835 .sspp_count = ARRAY_SIZE(sdm845_sspp),
836 .sspp = sdm845_sspp,
837 .mixer_count = ARRAY_SIZE(sm8150_lm),
838 .mixer = sm8150_lm,
839 .pingpong_count = ARRAY_SIZE(sm8150_pp),
840 .pingpong = sm8150_pp,
841 .intf_count = ARRAY_SIZE(sm8150_intf),
842 .intf = sm8150_intf,
843 .vbif_count = ARRAY_SIZE(sdm845_vbif),
844 .vbif = sdm845_vbif,
845 .reg_dma_count = 1,
846 .dma_cfg = sm8150_regdma,
847 .perf = sm8150_perf_data,
848 .mdss_irqs = 0x3ff,
849 };
850 }
851
852 /*
853 * sm8250_cfg_init(): populate sm8250 dpu sub-blocks reg offsets
854 * and instance counts.
855 */
sm8250_cfg_init(struct dpu_mdss_cfg * dpu_cfg)856 static void sm8250_cfg_init(struct dpu_mdss_cfg *dpu_cfg)
857 {
858 *dpu_cfg = (struct dpu_mdss_cfg){
859 .caps = &sm8250_dpu_caps,
860 .mdp_count = ARRAY_SIZE(sm8250_mdp),
861 .mdp = sm8250_mdp,
862 .ctl_count = ARRAY_SIZE(sm8150_ctl),
863 .ctl = sm8150_ctl,
864 /* TODO: sspp qseed version differs from 845 */
865 .sspp_count = ARRAY_SIZE(sdm845_sspp),
866 .sspp = sdm845_sspp,
867 .mixer_count = ARRAY_SIZE(sm8150_lm),
868 .mixer = sm8150_lm,
869 .pingpong_count = ARRAY_SIZE(sm8150_pp),
870 .pingpong = sm8150_pp,
871 .intf_count = ARRAY_SIZE(sm8150_intf),
872 .intf = sm8150_intf,
873 .vbif_count = ARRAY_SIZE(sdm845_vbif),
874 .vbif = sdm845_vbif,
875 .reg_dma_count = 1,
876 .dma_cfg = sm8250_regdma,
877 .perf = sm8250_perf_data,
878 .mdss_irqs = 0xff,
879 };
880 }
881
882 static const struct dpu_mdss_hw_cfg_handler cfg_handler[] = {
883 { .hw_rev = DPU_HW_VER_400, .cfg_init = sdm845_cfg_init},
884 { .hw_rev = DPU_HW_VER_401, .cfg_init = sdm845_cfg_init},
885 { .hw_rev = DPU_HW_VER_500, .cfg_init = sm8150_cfg_init},
886 { .hw_rev = DPU_HW_VER_501, .cfg_init = sm8150_cfg_init},
887 { .hw_rev = DPU_HW_VER_600, .cfg_init = sm8250_cfg_init},
888 { .hw_rev = DPU_HW_VER_620, .cfg_init = sc7180_cfg_init},
889 };
890
dpu_hw_catalog_deinit(struct dpu_mdss_cfg * dpu_cfg)891 void dpu_hw_catalog_deinit(struct dpu_mdss_cfg *dpu_cfg)
892 {
893 kfree(dpu_cfg);
894 }
895
dpu_hw_catalog_init(u32 hw_rev)896 struct dpu_mdss_cfg *dpu_hw_catalog_init(u32 hw_rev)
897 {
898 int i;
899 struct dpu_mdss_cfg *dpu_cfg;
900
901 dpu_cfg = kzalloc(sizeof(*dpu_cfg), GFP_KERNEL);
902 if (!dpu_cfg)
903 return ERR_PTR(-ENOMEM);
904
905 for (i = 0; i < ARRAY_SIZE(cfg_handler); i++) {
906 if (cfg_handler[i].hw_rev == hw_rev) {
907 cfg_handler[i].cfg_init(dpu_cfg);
908 dpu_cfg->hwversion = hw_rev;
909 return dpu_cfg;
910 }
911 }
912
913 DPU_ERROR("unsupported chipset id:%X\n", hw_rev);
914 dpu_hw_catalog_deinit(dpu_cfg);
915 return ERR_PTR(-ENODEV);
916 }
917
918