1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
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"
14 (BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) |\
15 BIT(DPU_SSPP_CSC_10BIT) | BIT(DPU_SSPP_CDP) |\
16 BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_EXCL_RECT))
18 #define VIG_SDM845_MASK \
19 (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3))
21 #define VIG_SC7180_MASK \
22 (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED4))
24 #define VIG_SM8250_MASK \
25 (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3LITE))
27 #define DMA_SDM845_MASK \
28 (BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) | BIT(DPU_SSPP_QOS_8LVL) |\
29 BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_TS_PREFILL_REC1) |\
30 BIT(DPU_SSPP_CDP) | BIT(DPU_SSPP_EXCL_RECT))
32 #define DMA_CURSOR_SDM845_MASK \
33 (DMA_SDM845_MASK | BIT(DPU_SSPP_CURSOR))
35 #define MIXER_SDM845_MASK \
36 (BIT(DPU_MIXER_SOURCESPLIT) | BIT(DPU_DIM_LAYER))
38 #define MIXER_SC7180_MASK \
41 #define PINGPONG_SDM845_MASK BIT(DPU_PINGPONG_DITHER)
43 #define PINGPONG_SDM845_SPLIT_MASK \
44 (PINGPONG_SDM845_MASK | BIT(DPU_PINGPONG_TE2))
46 #define MERGE_3D_SM8150_MASK (0)
48 #define DSPP_SC7180_MASK BIT(DPU_DSPP_PCC)
50 #define INTF_SDM845_MASK (0)
52 #define INTF_SC7180_MASK BIT(DPU_INTF_INPUT_CTRL) | BIT(DPU_INTF_TE)
54 #define DEFAULT_PIXEL_RAM_SIZE (50 * 1024)
55 #define DEFAULT_DPU_LINE_WIDTH 2048
56 #define DEFAULT_DPU_OUTPUT_LINE_WIDTH 2560
58 #define MAX_HORZ_DECIMATION 4
59 #define MAX_VERT_DECIMATION 4
61 #define MAX_UPSCALE_RATIO 20
62 #define MAX_DOWNSCALE_RATIO 4
63 #define SSPP_UNITY_SCALE 1
65 #define STRCAT(X, Y) (X Y)
67 static const uint32_t plane_formats[] = {
98 static const uint32_t plane_formats_yuv[] = {
140 /*************************************************************
141 * DPU sub blocks config
142 *************************************************************/
143 /* DPU top level caps */
144 static const struct dpu_caps sdm845_dpu_caps = {
145 .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
146 .max_mixer_blendstages = 0xb,
147 .qseed_type = DPU_SSPP_SCALER_QSEED3,
148 .smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
149 .ubwc_version = DPU_HW_UBWC_VER_20,
150 .has_src_split = true,
151 .has_dim_layer = true,
153 .has_3d_merge = true,
154 .max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
155 .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
156 .max_hdeci_exp = MAX_HORZ_DECIMATION,
157 .max_vdeci_exp = MAX_VERT_DECIMATION,
160 static const struct dpu_caps sc7180_dpu_caps = {
161 .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
162 .max_mixer_blendstages = 0x9,
163 .qseed_type = DPU_SSPP_SCALER_QSEED4,
164 .smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
165 .ubwc_version = DPU_HW_UBWC_VER_20,
166 .has_dim_layer = true,
168 .max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
169 .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
172 static const struct dpu_caps sm8150_dpu_caps = {
173 .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
174 .max_mixer_blendstages = 0xb,
175 .qseed_type = DPU_SSPP_SCALER_QSEED3,
176 .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
177 .ubwc_version = DPU_HW_UBWC_VER_30,
178 .has_src_split = true,
179 .has_dim_layer = true,
181 .has_3d_merge = true,
182 .max_linewidth = 4096,
183 .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
184 .max_hdeci_exp = MAX_HORZ_DECIMATION,
185 .max_vdeci_exp = MAX_VERT_DECIMATION,
188 static const struct dpu_caps sm8250_dpu_caps = {
189 .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
190 .max_mixer_blendstages = 0xb,
191 .qseed_type = DPU_SSPP_SCALER_QSEED3LITE,
192 .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
193 .ubwc_version = DPU_HW_UBWC_VER_40,
194 .has_src_split = true,
195 .has_dim_layer = true,
197 .has_3d_merge = true,
198 .max_linewidth = 4096,
199 .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
202 static const struct dpu_mdp_cfg sdm845_mdp[] = {
204 .name = "top_0", .id = MDP_TOP,
205 .base = 0x0, .len = 0x45C,
207 .highest_bank_bit = 0x2,
208 .clk_ctrls[DPU_CLK_CTRL_VIG0] = {
209 .reg_off = 0x2AC, .bit_off = 0},
210 .clk_ctrls[DPU_CLK_CTRL_VIG1] = {
211 .reg_off = 0x2B4, .bit_off = 0},
212 .clk_ctrls[DPU_CLK_CTRL_VIG2] = {
213 .reg_off = 0x2BC, .bit_off = 0},
214 .clk_ctrls[DPU_CLK_CTRL_VIG3] = {
215 .reg_off = 0x2C4, .bit_off = 0},
216 .clk_ctrls[DPU_CLK_CTRL_DMA0] = {
217 .reg_off = 0x2AC, .bit_off = 8},
218 .clk_ctrls[DPU_CLK_CTRL_DMA1] = {
219 .reg_off = 0x2B4, .bit_off = 8},
220 .clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
221 .reg_off = 0x2BC, .bit_off = 8},
222 .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
223 .reg_off = 0x2C4, .bit_off = 8},
227 static const struct dpu_mdp_cfg sc7180_mdp[] = {
229 .name = "top_0", .id = MDP_TOP,
230 .base = 0x0, .len = 0x494,
232 .highest_bank_bit = 0x3,
233 .clk_ctrls[DPU_CLK_CTRL_VIG0] = {
234 .reg_off = 0x2AC, .bit_off = 0},
235 .clk_ctrls[DPU_CLK_CTRL_DMA0] = {
236 .reg_off = 0x2AC, .bit_off = 8},
237 .clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
238 .reg_off = 0x2B4, .bit_off = 8},
239 .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
240 .reg_off = 0x2C4, .bit_off = 8},
244 static const struct dpu_mdp_cfg sm8250_mdp[] = {
246 .name = "top_0", .id = MDP_TOP,
247 .base = 0x0, .len = 0x45C,
249 .highest_bank_bit = 0x3, /* TODO: 2 for LP_DDR4 */
250 .clk_ctrls[DPU_CLK_CTRL_VIG0] = {
251 .reg_off = 0x2AC, .bit_off = 0},
252 .clk_ctrls[DPU_CLK_CTRL_VIG1] = {
253 .reg_off = 0x2B4, .bit_off = 0},
254 .clk_ctrls[DPU_CLK_CTRL_VIG2] = {
255 .reg_off = 0x2BC, .bit_off = 0},
256 .clk_ctrls[DPU_CLK_CTRL_VIG3] = {
257 .reg_off = 0x2C4, .bit_off = 0},
258 .clk_ctrls[DPU_CLK_CTRL_DMA0] = {
259 .reg_off = 0x2AC, .bit_off = 8},
260 .clk_ctrls[DPU_CLK_CTRL_DMA1] = {
261 .reg_off = 0x2B4, .bit_off = 8},
262 .clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
263 .reg_off = 0x2BC, .bit_off = 8},
264 .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
265 .reg_off = 0x2C4, .bit_off = 8},
266 .clk_ctrls[DPU_CLK_CTRL_REG_DMA] = {
267 .reg_off = 0x2BC, .bit_off = 20},
271 /*************************************************************
272 * CTL sub blocks config
273 *************************************************************/
274 static const struct dpu_ctl_cfg sdm845_ctl[] = {
276 .name = "ctl_0", .id = CTL_0,
277 .base = 0x1000, .len = 0xE4,
278 .features = BIT(DPU_CTL_SPLIT_DISPLAY)
281 .name = "ctl_1", .id = CTL_1,
282 .base = 0x1200, .len = 0xE4,
283 .features = BIT(DPU_CTL_SPLIT_DISPLAY)
286 .name = "ctl_2", .id = CTL_2,
287 .base = 0x1400, .len = 0xE4,
291 .name = "ctl_3", .id = CTL_3,
292 .base = 0x1600, .len = 0xE4,
296 .name = "ctl_4", .id = CTL_4,
297 .base = 0x1800, .len = 0xE4,
302 static const struct dpu_ctl_cfg sc7180_ctl[] = {
304 .name = "ctl_0", .id = CTL_0,
305 .base = 0x1000, .len = 0xE4,
306 .features = BIT(DPU_CTL_ACTIVE_CFG)
309 .name = "ctl_1", .id = CTL_1,
310 .base = 0x1200, .len = 0xE4,
311 .features = BIT(DPU_CTL_ACTIVE_CFG)
314 .name = "ctl_2", .id = CTL_2,
315 .base = 0x1400, .len = 0xE4,
316 .features = BIT(DPU_CTL_ACTIVE_CFG)
320 static const struct dpu_ctl_cfg sm8150_ctl[] = {
322 .name = "ctl_0", .id = CTL_0,
323 .base = 0x1000, .len = 0x1e0,
324 .features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY)
327 .name = "ctl_1", .id = CTL_1,
328 .base = 0x1200, .len = 0x1e0,
329 .features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY)
332 .name = "ctl_2", .id = CTL_2,
333 .base = 0x1400, .len = 0x1e0,
334 .features = BIT(DPU_CTL_ACTIVE_CFG)
337 .name = "ctl_3", .id = CTL_3,
338 .base = 0x1600, .len = 0x1e0,
339 .features = BIT(DPU_CTL_ACTIVE_CFG)
342 .name = "ctl_4", .id = CTL_4,
343 .base = 0x1800, .len = 0x1e0,
344 .features = BIT(DPU_CTL_ACTIVE_CFG)
347 .name = "ctl_5", .id = CTL_5,
348 .base = 0x1a00, .len = 0x1e0,
349 .features = BIT(DPU_CTL_ACTIVE_CFG)
353 /*************************************************************
354 * SSPP sub blocks config
355 *************************************************************/
357 /* SSPP common configuration */
359 #define _VIG_SBLK(num, sdma_pri, qseed_ver) \
361 .maxdwnscale = MAX_DOWNSCALE_RATIO, \
362 .maxupscale = MAX_UPSCALE_RATIO, \
363 .smart_dma_priority = sdma_pri, \
364 .src_blk = {.name = STRCAT("sspp_src_", num), \
365 .id = DPU_SSPP_SRC, .base = 0x00, .len = 0x150,}, \
366 .scaler_blk = {.name = STRCAT("sspp_scaler", num), \
368 .base = 0xa00, .len = 0xa0,}, \
369 .csc_blk = {.name = STRCAT("sspp_csc", num), \
370 .id = DPU_SSPP_CSC_10BIT, \
371 .base = 0x1a00, .len = 0x100,}, \
372 .format_list = plane_formats_yuv, \
373 .num_formats = ARRAY_SIZE(plane_formats_yuv), \
374 .virt_format_list = plane_formats, \
375 .virt_num_formats = ARRAY_SIZE(plane_formats), \
378 #define _DMA_SBLK(num, sdma_pri) \
380 .maxdwnscale = SSPP_UNITY_SCALE, \
381 .maxupscale = SSPP_UNITY_SCALE, \
382 .smart_dma_priority = sdma_pri, \
383 .src_blk = {.name = STRCAT("sspp_src_", num), \
384 .id = DPU_SSPP_SRC, .base = 0x00, .len = 0x150,}, \
385 .format_list = plane_formats, \
386 .num_formats = ARRAY_SIZE(plane_formats), \
387 .virt_format_list = plane_formats, \
388 .virt_num_formats = ARRAY_SIZE(plane_formats), \
391 static const struct dpu_sspp_sub_blks sdm845_vig_sblk_0 =
392 _VIG_SBLK("0", 5, DPU_SSPP_SCALER_QSEED3);
393 static const struct dpu_sspp_sub_blks sdm845_vig_sblk_1 =
394 _VIG_SBLK("1", 6, DPU_SSPP_SCALER_QSEED3);
395 static const struct dpu_sspp_sub_blks sdm845_vig_sblk_2 =
396 _VIG_SBLK("2", 7, DPU_SSPP_SCALER_QSEED3);
397 static const struct dpu_sspp_sub_blks sdm845_vig_sblk_3 =
398 _VIG_SBLK("3", 8, DPU_SSPP_SCALER_QSEED3);
400 static const struct dpu_sspp_sub_blks sdm845_dma_sblk_0 = _DMA_SBLK("8", 1);
401 static const struct dpu_sspp_sub_blks sdm845_dma_sblk_1 = _DMA_SBLK("9", 2);
402 static const struct dpu_sspp_sub_blks sdm845_dma_sblk_2 = _DMA_SBLK("10", 3);
403 static const struct dpu_sspp_sub_blks sdm845_dma_sblk_3 = _DMA_SBLK("11", 4);
405 #define SSPP_BLK(_name, _id, _base, _features, \
406 _sblk, _xinid, _type, _clkctrl) \
408 .name = _name, .id = _id, \
409 .base = _base, .len = 0x1c8, \
410 .features = _features, \
414 .clk_ctrl = _clkctrl \
417 static const struct dpu_sspp_cfg sdm845_sspp[] = {
418 SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SDM845_MASK,
419 sdm845_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0),
420 SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SDM845_MASK,
421 sdm845_vig_sblk_1, 4, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1),
422 SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SDM845_MASK,
423 sdm845_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2),
424 SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SDM845_MASK,
425 sdm845_vig_sblk_3, 12, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3),
426 SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, DMA_SDM845_MASK,
427 sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0),
428 SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, DMA_SDM845_MASK,
429 sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1),
430 SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, DMA_CURSOR_SDM845_MASK,
431 sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR0),
432 SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, DMA_CURSOR_SDM845_MASK,
433 sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1),
436 static const struct dpu_sspp_sub_blks sc7180_vig_sblk_0 =
437 _VIG_SBLK("0", 4, DPU_SSPP_SCALER_QSEED4);
439 static const struct dpu_sspp_cfg sc7180_sspp[] = {
440 SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SC7180_MASK,
441 sc7180_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0),
442 SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, DMA_SDM845_MASK,
443 sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0),
444 SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, DMA_CURSOR_SDM845_MASK,
445 sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR0),
446 SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, DMA_CURSOR_SDM845_MASK,
447 sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1),
450 static const struct dpu_sspp_sub_blks sm8250_vig_sblk_0 =
451 _VIG_SBLK("0", 5, DPU_SSPP_SCALER_QSEED3LITE);
452 static const struct dpu_sspp_sub_blks sm8250_vig_sblk_1 =
453 _VIG_SBLK("1", 6, DPU_SSPP_SCALER_QSEED3LITE);
454 static const struct dpu_sspp_sub_blks sm8250_vig_sblk_2 =
455 _VIG_SBLK("2", 7, DPU_SSPP_SCALER_QSEED3LITE);
456 static const struct dpu_sspp_sub_blks sm8250_vig_sblk_3 =
457 _VIG_SBLK("3", 8, DPU_SSPP_SCALER_QSEED3LITE);
459 static const struct dpu_sspp_cfg sm8250_sspp[] = {
460 SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SM8250_MASK,
461 sm8250_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0),
462 SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SM8250_MASK,
463 sm8250_vig_sblk_1, 4, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1),
464 SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SM8250_MASK,
465 sm8250_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2),
466 SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SM8250_MASK,
467 sm8250_vig_sblk_3, 12, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3),
468 SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, DMA_SDM845_MASK,
469 sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0),
470 SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, DMA_SDM845_MASK,
471 sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1),
472 SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, DMA_CURSOR_SDM845_MASK,
473 sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR0),
474 SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, DMA_CURSOR_SDM845_MASK,
475 sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1),
478 /*************************************************************
479 * MIXER sub blocks config
480 *************************************************************/
484 static const struct dpu_lm_sub_blks sdm845_lm_sblk = {
485 .maxwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
486 .maxblendstages = 11, /* excluding base layer */
487 .blendstage_base = { /* offsets relative to mixer base */
488 0x20, 0x38, 0x50, 0x68, 0x80, 0x98,
489 0xb0, 0xc8, 0xe0, 0xf8, 0x110
493 #define LM_BLK(_name, _id, _base, _fmask, _sblk, _pp, _lmpair, _dspp) \
495 .name = _name, .id = _id, \
496 .base = _base, .len = 0x320, \
497 .features = _fmask, \
500 .lm_pair_mask = (1 << _lmpair), \
504 static const struct dpu_lm_cfg sdm845_lm[] = {
505 LM_BLK("lm_0", LM_0, 0x44000, MIXER_SDM845_MASK,
506 &sdm845_lm_sblk, PINGPONG_0, LM_1, 0),
507 LM_BLK("lm_1", LM_1, 0x45000, MIXER_SDM845_MASK,
508 &sdm845_lm_sblk, PINGPONG_1, LM_0, 0),
509 LM_BLK("lm_2", LM_2, 0x46000, MIXER_SDM845_MASK,
510 &sdm845_lm_sblk, PINGPONG_2, LM_5, 0),
511 LM_BLK("lm_3", LM_3, 0x0, MIXER_SDM845_MASK,
512 &sdm845_lm_sblk, PINGPONG_MAX, 0, 0),
513 LM_BLK("lm_4", LM_4, 0x0, MIXER_SDM845_MASK,
514 &sdm845_lm_sblk, PINGPONG_MAX, 0, 0),
515 LM_BLK("lm_5", LM_5, 0x49000, MIXER_SDM845_MASK,
516 &sdm845_lm_sblk, PINGPONG_3, LM_2, 0),
521 static const struct dpu_lm_sub_blks sc7180_lm_sblk = {
522 .maxwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
523 .maxblendstages = 7, /* excluding base layer */
524 .blendstage_base = { /* offsets relative to mixer base */
525 0x20, 0x38, 0x50, 0x68, 0x80, 0x98, 0xb0
529 static const struct dpu_lm_cfg sc7180_lm[] = {
530 LM_BLK("lm_0", LM_0, 0x44000, MIXER_SC7180_MASK,
531 &sc7180_lm_sblk, PINGPONG_0, LM_1, DSPP_0),
532 LM_BLK("lm_1", LM_1, 0x45000, MIXER_SC7180_MASK,
533 &sc7180_lm_sblk, PINGPONG_1, LM_0, 0),
538 static const struct dpu_lm_cfg sm8150_lm[] = {
539 LM_BLK("lm_0", LM_0, 0x44000, MIXER_SDM845_MASK,
540 &sdm845_lm_sblk, PINGPONG_0, LM_1, DSPP_0),
541 LM_BLK("lm_1", LM_1, 0x45000, MIXER_SDM845_MASK,
542 &sdm845_lm_sblk, PINGPONG_1, LM_0, DSPP_1),
543 LM_BLK("lm_2", LM_2, 0x46000, MIXER_SDM845_MASK,
544 &sdm845_lm_sblk, PINGPONG_2, LM_3, 0),
545 LM_BLK("lm_3", LM_3, 0x47000, MIXER_SDM845_MASK,
546 &sdm845_lm_sblk, PINGPONG_3, LM_2, 0),
547 LM_BLK("lm_4", LM_4, 0x48000, MIXER_SDM845_MASK,
548 &sdm845_lm_sblk, PINGPONG_4, LM_5, 0),
549 LM_BLK("lm_5", LM_5, 0x49000, MIXER_SDM845_MASK,
550 &sdm845_lm_sblk, PINGPONG_5, LM_4, 0),
553 /*************************************************************
554 * DSPP sub blocks config
555 *************************************************************/
556 static const struct dpu_dspp_sub_blks sc7180_dspp_sblk = {
557 .pcc = {.id = DPU_DSPP_PCC, .base = 0x1700,
558 .len = 0x90, .version = 0x10000},
561 static const struct dpu_dspp_sub_blks sm8150_dspp_sblk = {
562 .pcc = {.id = DPU_DSPP_PCC, .base = 0x1700,
563 .len = 0x90, .version = 0x40000},
566 #define DSPP_BLK(_name, _id, _base, _mask, _sblk) \
568 .name = _name, .id = _id, \
569 .base = _base, .len = 0x1800, \
574 static const struct dpu_dspp_cfg sc7180_dspp[] = {
575 DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_SC7180_MASK,
579 static const struct dpu_dspp_cfg sm8150_dspp[] = {
580 DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_SC7180_MASK,
582 DSPP_BLK("dspp_1", DSPP_1, 0x56000, DSPP_SC7180_MASK,
584 DSPP_BLK("dspp_2", DSPP_2, 0x58000, DSPP_SC7180_MASK,
586 DSPP_BLK("dspp_3", DSPP_3, 0x5a000, DSPP_SC7180_MASK,
590 /*************************************************************
591 * PINGPONG sub blocks config
592 *************************************************************/
593 static const struct dpu_pingpong_sub_blks sdm845_pp_sblk_te = {
594 .te2 = {.id = DPU_PINGPONG_TE2, .base = 0x2000, .len = 0x0,
596 .dither = {.id = DPU_PINGPONG_DITHER, .base = 0x30e0,
597 .len = 0x20, .version = 0x10000},
600 static const struct dpu_pingpong_sub_blks sdm845_pp_sblk = {
601 .dither = {.id = DPU_PINGPONG_DITHER, .base = 0x30e0,
602 .len = 0x20, .version = 0x10000},
605 #define PP_BLK_TE(_name, _id, _base, _merge_3d) \
607 .name = _name, .id = _id, \
608 .base = _base, .len = 0xd4, \
609 .features = PINGPONG_SDM845_SPLIT_MASK, \
610 .merge_3d = _merge_3d, \
611 .sblk = &sdm845_pp_sblk_te \
613 #define PP_BLK(_name, _id, _base, _merge_3d) \
615 .name = _name, .id = _id, \
616 .base = _base, .len = 0xd4, \
617 .features = PINGPONG_SDM845_MASK, \
618 .merge_3d = _merge_3d, \
619 .sblk = &sdm845_pp_sblk \
622 static const struct dpu_pingpong_cfg sdm845_pp[] = {
623 PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, 0),
624 PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, 0),
625 PP_BLK("pingpong_2", PINGPONG_2, 0x71000, 0),
626 PP_BLK("pingpong_3", PINGPONG_3, 0x71800, 0),
629 static struct dpu_pingpong_cfg sc7180_pp[] = {
630 PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, 0),
631 PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, 0),
634 static const struct dpu_pingpong_cfg sm8150_pp[] = {
635 PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0),
636 PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0),
637 PP_BLK("pingpong_2", PINGPONG_2, 0x71000, MERGE_3D_1),
638 PP_BLK("pingpong_3", PINGPONG_3, 0x71800, MERGE_3D_1),
639 PP_BLK("pingpong_4", PINGPONG_4, 0x72000, MERGE_3D_2),
640 PP_BLK("pingpong_5", PINGPONG_5, 0x72800, MERGE_3D_2),
643 /*************************************************************
644 * MERGE_3D sub blocks config
645 *************************************************************/
646 #define MERGE_3D_BLK(_name, _id, _base) \
648 .name = _name, .id = _id, \
649 .base = _base, .len = 0x100, \
650 .features = MERGE_3D_SM8150_MASK, \
654 static const struct dpu_merge_3d_cfg sm8150_merge_3d[] = {
655 MERGE_3D_BLK("merge_3d_0", MERGE_3D_0, 0x83000),
656 MERGE_3D_BLK("merge_3d_1", MERGE_3D_1, 0x83100),
657 MERGE_3D_BLK("merge_3d_2", MERGE_3D_2, 0x83200),
660 /*************************************************************
661 * INTF sub blocks config
662 *************************************************************/
663 #define INTF_BLK(_name, _id, _base, _type, _ctrl_id, _progfetch, _features) \
665 .name = _name, .id = _id, \
666 .base = _base, .len = 0x280, \
667 .features = _features, \
669 .controller_id = _ctrl_id, \
670 .prog_fetch_lines_worst_case = _progfetch \
673 static const struct dpu_intf_cfg sdm845_intf[] = {
674 INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24, INTF_SDM845_MASK),
675 INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SDM845_MASK),
676 INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 24, INTF_SDM845_MASK),
677 INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 1, 24, INTF_SDM845_MASK),
680 static const struct dpu_intf_cfg sc7180_intf[] = {
681 INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24, INTF_SC7180_MASK),
682 INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SC7180_MASK),
685 static const struct dpu_intf_cfg sm8150_intf[] = {
686 INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24, INTF_SC7180_MASK),
687 INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SC7180_MASK),
688 INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 24, INTF_SC7180_MASK),
689 INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 1, 24, INTF_SC7180_MASK),
692 /*************************************************************
693 * VBIF sub blocks config
694 *************************************************************/
696 static const u32 sdm845_rt_pri_lvl[] = {3, 3, 4, 4, 5, 5, 6, 6};
697 static const u32 sdm845_nrt_pri_lvl[] = {3, 3, 3, 3, 3, 3, 3, 3};
699 static const struct dpu_vbif_cfg sdm845_vbif[] = {
701 .name = "vbif_0", .id = VBIF_0,
702 .base = 0, .len = 0x1040,
703 .features = BIT(DPU_VBIF_QOS_REMAP),
704 .xin_halt_timeout = 0x4000,
706 .npriority_lvl = ARRAY_SIZE(sdm845_rt_pri_lvl),
707 .priority_lvl = sdm845_rt_pri_lvl,
710 .npriority_lvl = ARRAY_SIZE(sdm845_nrt_pri_lvl),
711 .priority_lvl = sdm845_nrt_pri_lvl,
714 .memtype = {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
718 static const struct dpu_reg_dma_cfg sdm845_regdma = {
719 .base = 0x0, .version = 0x1, .trigger_sel_off = 0x119c
722 static const struct dpu_reg_dma_cfg sm8150_regdma = {
723 .base = 0x0, .version = 0x00010001, .trigger_sel_off = 0x119c
726 static const struct dpu_reg_dma_cfg sm8250_regdma = {
728 .version = 0x00010002,
729 .trigger_sel_off = 0x119c,
731 .clk_ctrl = DPU_CLK_CTRL_REG_DMA,
734 /*************************************************************
736 *************************************************************/
739 static const struct dpu_qos_lut_entry sdm845_qos_linear[] = {
740 {.fl = 4, .lut = 0x357},
741 {.fl = 5, .lut = 0x3357},
742 {.fl = 6, .lut = 0x23357},
743 {.fl = 7, .lut = 0x223357},
744 {.fl = 8, .lut = 0x2223357},
745 {.fl = 9, .lut = 0x22223357},
746 {.fl = 10, .lut = 0x222223357},
747 {.fl = 11, .lut = 0x2222223357},
748 {.fl = 12, .lut = 0x22222223357},
749 {.fl = 13, .lut = 0x222222223357},
750 {.fl = 14, .lut = 0x1222222223357},
751 {.fl = 0, .lut = 0x11222222223357}
754 static const struct dpu_qos_lut_entry sc7180_qos_linear[] = {
755 {.fl = 0, .lut = 0x0011222222335777},
758 static const struct dpu_qos_lut_entry sm8150_qos_linear[] = {
759 {.fl = 0, .lut = 0x0011222222223357 },
762 static const struct dpu_qos_lut_entry sdm845_qos_macrotile[] = {
763 {.fl = 10, .lut = 0x344556677},
764 {.fl = 11, .lut = 0x3344556677},
765 {.fl = 12, .lut = 0x23344556677},
766 {.fl = 13, .lut = 0x223344556677},
767 {.fl = 14, .lut = 0x1223344556677},
768 {.fl = 0, .lut = 0x112233344556677},
771 static const struct dpu_qos_lut_entry sc7180_qos_macrotile[] = {
772 {.fl = 0, .lut = 0x0011223344556677},
775 static const struct dpu_qos_lut_entry sdm845_qos_nrt[] = {
776 {.fl = 0, .lut = 0x0},
779 static const struct dpu_qos_lut_entry sc7180_qos_nrt[] = {
780 {.fl = 0, .lut = 0x0},
783 static const struct dpu_perf_cfg sdm845_perf_data = {
784 .max_bw_low = 6800000,
785 .max_bw_high = 6800000,
786 .min_core_ib = 2400000,
787 .min_llcc_ib = 800000,
788 .min_dram_ib = 800000,
790 .core_clk_ff = "1.0",
792 "NV12/5/1/1.23 AB24/5/1/1.23 XB24/5/1/1.23",
794 "NV12/5/1/1.25 AB24/5/1/1.25 XB24/5/1/1.25",
795 .undersized_prefill_lines = 2,
796 .xtra_prefill_lines = 2,
797 .dest_scale_prefill_lines = 3,
798 .macrotile_prefill_lines = 4,
799 .yuv_nv12_prefill_lines = 8,
800 .linear_prefill_lines = 1,
801 .downscaling_prefill_lines = 1,
802 .amortizable_threshold = 25,
803 .min_prefill_lines = 24,
804 .danger_lut_tbl = {0xf, 0xffff, 0x0},
806 {.nentry = ARRAY_SIZE(sdm845_qos_linear),
807 .entries = sdm845_qos_linear
809 {.nentry = ARRAY_SIZE(sdm845_qos_macrotile),
810 .entries = sdm845_qos_macrotile
812 {.nentry = ARRAY_SIZE(sdm845_qos_nrt),
813 .entries = sdm845_qos_nrt
817 {.rd_enable = 1, .wr_enable = 1},
818 {.rd_enable = 1, .wr_enable = 0}
820 .clk_inefficiency_factor = 105,
821 .bw_inefficiency_factor = 120,
824 static const struct dpu_perf_cfg sc7180_perf_data = {
825 .max_bw_low = 6800000,
826 .max_bw_high = 6800000,
827 .min_core_ib = 2400000,
828 .min_llcc_ib = 800000,
829 .min_dram_ib = 1600000,
830 .min_prefill_lines = 24,
831 .danger_lut_tbl = {0xff, 0xffff, 0x0},
833 {.nentry = ARRAY_SIZE(sc7180_qos_linear),
834 .entries = sc7180_qos_linear
836 {.nentry = ARRAY_SIZE(sc7180_qos_macrotile),
837 .entries = sc7180_qos_macrotile
839 {.nentry = ARRAY_SIZE(sc7180_qos_nrt),
840 .entries = sc7180_qos_nrt
844 {.rd_enable = 1, .wr_enable = 1},
845 {.rd_enable = 1, .wr_enable = 0}
847 .clk_inefficiency_factor = 105,
848 .bw_inefficiency_factor = 120,
851 static const struct dpu_perf_cfg sm8150_perf_data = {
852 .max_bw_low = 12800000,
853 .max_bw_high = 12800000,
854 .min_core_ib = 2400000,
855 .min_llcc_ib = 800000,
856 .min_dram_ib = 800000,
857 .min_prefill_lines = 24,
858 .danger_lut_tbl = {0xf, 0xffff, 0x0},
860 {.nentry = ARRAY_SIZE(sm8150_qos_linear),
861 .entries = sm8150_qos_linear
863 {.nentry = ARRAY_SIZE(sc7180_qos_macrotile),
864 .entries = sc7180_qos_macrotile
866 {.nentry = ARRAY_SIZE(sc7180_qos_nrt),
867 .entries = sc7180_qos_nrt
869 /* TODO: macrotile-qseed is different from macrotile */
872 {.rd_enable = 1, .wr_enable = 1},
873 {.rd_enable = 1, .wr_enable = 0}
875 .clk_inefficiency_factor = 105,
876 .bw_inefficiency_factor = 120,
879 static const struct dpu_perf_cfg sm8250_perf_data = {
880 .max_bw_low = 13700000,
881 .max_bw_high = 16600000,
882 .min_core_ib = 4800000,
884 .min_dram_ib = 800000,
885 .min_prefill_lines = 35,
886 .danger_lut_tbl = {0xf, 0xffff, 0x0},
888 {.nentry = ARRAY_SIZE(sc7180_qos_linear),
889 .entries = sc7180_qos_linear
891 {.nentry = ARRAY_SIZE(sc7180_qos_macrotile),
892 .entries = sc7180_qos_macrotile
894 {.nentry = ARRAY_SIZE(sc7180_qos_nrt),
895 .entries = sc7180_qos_nrt
897 /* TODO: macrotile-qseed is different from macrotile */
900 {.rd_enable = 1, .wr_enable = 1},
901 {.rd_enable = 1, .wr_enable = 0}
903 .clk_inefficiency_factor = 105,
904 .bw_inefficiency_factor = 120,
907 /*************************************************************
908 * Hardware catalog init
909 *************************************************************/
912 * sdm845_cfg_init(): populate sdm845 dpu sub-blocks reg offsets
913 * and instance counts.
915 static void sdm845_cfg_init(struct dpu_mdss_cfg *dpu_cfg)
917 *dpu_cfg = (struct dpu_mdss_cfg){
918 .caps = &sdm845_dpu_caps,
919 .mdp_count = ARRAY_SIZE(sdm845_mdp),
921 .ctl_count = ARRAY_SIZE(sdm845_ctl),
923 .sspp_count = ARRAY_SIZE(sdm845_sspp),
925 .mixer_count = ARRAY_SIZE(sdm845_lm),
927 .pingpong_count = ARRAY_SIZE(sdm845_pp),
928 .pingpong = sdm845_pp,
929 .intf_count = ARRAY_SIZE(sdm845_intf),
931 .vbif_count = ARRAY_SIZE(sdm845_vbif),
934 .dma_cfg = sdm845_regdma,
935 .perf = sdm845_perf_data,
941 * sc7180_cfg_init(): populate sc7180 dpu sub-blocks reg offsets
942 * and instance counts.
944 static void sc7180_cfg_init(struct dpu_mdss_cfg *dpu_cfg)
946 *dpu_cfg = (struct dpu_mdss_cfg){
947 .caps = &sc7180_dpu_caps,
948 .mdp_count = ARRAY_SIZE(sc7180_mdp),
950 .ctl_count = ARRAY_SIZE(sc7180_ctl),
952 .sspp_count = ARRAY_SIZE(sc7180_sspp),
954 .mixer_count = ARRAY_SIZE(sc7180_lm),
956 .dspp_count = ARRAY_SIZE(sc7180_dspp),
958 .pingpong_count = ARRAY_SIZE(sc7180_pp),
959 .pingpong = sc7180_pp,
960 .intf_count = ARRAY_SIZE(sc7180_intf),
962 .vbif_count = ARRAY_SIZE(sdm845_vbif),
965 .dma_cfg = sdm845_regdma,
966 .perf = sc7180_perf_data,
972 * sm8150_cfg_init(): populate sm8150 dpu sub-blocks reg offsets
973 * and instance counts.
975 static void sm8150_cfg_init(struct dpu_mdss_cfg *dpu_cfg)
977 *dpu_cfg = (struct dpu_mdss_cfg){
978 .caps = &sm8150_dpu_caps,
979 .mdp_count = ARRAY_SIZE(sdm845_mdp),
981 .ctl_count = ARRAY_SIZE(sm8150_ctl),
983 .sspp_count = ARRAY_SIZE(sdm845_sspp),
985 .mixer_count = ARRAY_SIZE(sm8150_lm),
987 .dspp_count = ARRAY_SIZE(sm8150_dspp),
989 .pingpong_count = ARRAY_SIZE(sm8150_pp),
990 .pingpong = sm8150_pp,
991 .merge_3d_count = ARRAY_SIZE(sm8150_merge_3d),
992 .merge_3d = sm8150_merge_3d,
993 .intf_count = ARRAY_SIZE(sm8150_intf),
995 .vbif_count = ARRAY_SIZE(sdm845_vbif),
998 .dma_cfg = sm8150_regdma,
999 .perf = sm8150_perf_data,
1005 * sm8250_cfg_init(): populate sm8250 dpu sub-blocks reg offsets
1006 * and instance counts.
1008 static void sm8250_cfg_init(struct dpu_mdss_cfg *dpu_cfg)
1010 *dpu_cfg = (struct dpu_mdss_cfg){
1011 .caps = &sm8250_dpu_caps,
1012 .mdp_count = ARRAY_SIZE(sm8250_mdp),
1014 .ctl_count = ARRAY_SIZE(sm8150_ctl),
1016 .sspp_count = ARRAY_SIZE(sm8250_sspp),
1017 .sspp = sm8250_sspp,
1018 .mixer_count = ARRAY_SIZE(sm8150_lm),
1020 .dspp_count = ARRAY_SIZE(sm8150_dspp),
1021 .dspp = sm8150_dspp,
1022 .pingpong_count = ARRAY_SIZE(sm8150_pp),
1023 .pingpong = sm8150_pp,
1024 .merge_3d_count = ARRAY_SIZE(sm8150_merge_3d),
1025 .merge_3d = sm8150_merge_3d,
1026 .intf_count = ARRAY_SIZE(sm8150_intf),
1027 .intf = sm8150_intf,
1028 .vbif_count = ARRAY_SIZE(sdm845_vbif),
1029 .vbif = sdm845_vbif,
1031 .dma_cfg = sm8250_regdma,
1032 .perf = sm8250_perf_data,
1037 static const struct dpu_mdss_hw_cfg_handler cfg_handler[] = {
1038 { .hw_rev = DPU_HW_VER_400, .cfg_init = sdm845_cfg_init},
1039 { .hw_rev = DPU_HW_VER_401, .cfg_init = sdm845_cfg_init},
1040 { .hw_rev = DPU_HW_VER_500, .cfg_init = sm8150_cfg_init},
1041 { .hw_rev = DPU_HW_VER_501, .cfg_init = sm8150_cfg_init},
1042 { .hw_rev = DPU_HW_VER_600, .cfg_init = sm8250_cfg_init},
1043 { .hw_rev = DPU_HW_VER_620, .cfg_init = sc7180_cfg_init},
1046 void dpu_hw_catalog_deinit(struct dpu_mdss_cfg *dpu_cfg)
1051 struct dpu_mdss_cfg *dpu_hw_catalog_init(u32 hw_rev)
1054 struct dpu_mdss_cfg *dpu_cfg;
1056 dpu_cfg = kzalloc(sizeof(*dpu_cfg), GFP_KERNEL);
1058 return ERR_PTR(-ENOMEM);
1060 for (i = 0; i < ARRAY_SIZE(cfg_handler); i++) {
1061 if (cfg_handler[i].hw_rev == hw_rev) {
1062 cfg_handler[i].cfg_init(dpu_cfg);
1063 dpu_cfg->hwversion = hw_rev;
1068 DPU_ERROR("unsupported chipset id:%X\n", hw_rev);
1069 dpu_hw_catalog_deinit(dpu_cfg);
1070 return ERR_PTR(-ENODEV);