This source file includes following definitions.
- sdm845_cfg_init
- dpu_hw_catalog_deinit
- dpu_hw_catalog_init
1
2
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_SDM845_MASK \
15 (BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_SCALER_QSEED3) | 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 DMA_SDM845_MASK \
20 (BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) | BIT(DPU_SSPP_QOS_8LVL) |\
21 BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_TS_PREFILL_REC1) |\
22 BIT(DPU_SSPP_CDP) | BIT(DPU_SSPP_EXCL_RECT))
23
24 #define DMA_CURSOR_SDM845_MASK \
25 (DMA_SDM845_MASK | BIT(DPU_SSPP_CURSOR))
26
27 #define MIXER_SDM845_MASK \
28 (BIT(DPU_MIXER_SOURCESPLIT) | BIT(DPU_DIM_LAYER))
29
30 #define PINGPONG_SDM845_MASK BIT(DPU_PINGPONG_DITHER)
31
32 #define PINGPONG_SDM845_SPLIT_MASK \
33 (PINGPONG_SDM845_MASK | BIT(DPU_PINGPONG_TE2))
34
35 #define DEFAULT_PIXEL_RAM_SIZE (50 * 1024)
36 #define DEFAULT_DPU_LINE_WIDTH 2048
37 #define DEFAULT_DPU_OUTPUT_LINE_WIDTH 2560
38
39 #define MAX_HORZ_DECIMATION 4
40 #define MAX_VERT_DECIMATION 4
41
42 #define MAX_UPSCALE_RATIO 20
43 #define MAX_DOWNSCALE_RATIO 4
44 #define SSPP_UNITY_SCALE 1
45
46 #define STRCAT(X, Y) (X Y)
47
48
49
50
51
52 static const struct dpu_caps sdm845_dpu_caps = {
53 .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
54 .max_mixer_blendstages = 0xb,
55 .qseed_type = DPU_SSPP_SCALER_QSEED3,
56 .smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
57 .ubwc_version = DPU_HW_UBWC_VER_20,
58 .has_src_split = true,
59 .has_dim_layer = true,
60 .has_idle_pc = true,
61 };
62
63 static struct dpu_mdp_cfg sdm845_mdp[] = {
64 {
65 .name = "top_0", .id = MDP_TOP,
66 .base = 0x0, .len = 0x45C,
67 .features = 0,
68 .highest_bank_bit = 0x2,
69 .clk_ctrls[DPU_CLK_CTRL_VIG0] = {
70 .reg_off = 0x2AC, .bit_off = 0},
71 .clk_ctrls[DPU_CLK_CTRL_VIG1] = {
72 .reg_off = 0x2B4, .bit_off = 0},
73 .clk_ctrls[DPU_CLK_CTRL_VIG2] = {
74 .reg_off = 0x2BC, .bit_off = 0},
75 .clk_ctrls[DPU_CLK_CTRL_VIG3] = {
76 .reg_off = 0x2C4, .bit_off = 0},
77 .clk_ctrls[DPU_CLK_CTRL_DMA0] = {
78 .reg_off = 0x2AC, .bit_off = 8},
79 .clk_ctrls[DPU_CLK_CTRL_DMA1] = {
80 .reg_off = 0x2B4, .bit_off = 8},
81 .clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
82 .reg_off = 0x2BC, .bit_off = 8},
83 .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
84 .reg_off = 0x2C4, .bit_off = 8},
85 },
86 };
87
88
89
90
91 static struct dpu_ctl_cfg sdm845_ctl[] = {
92 {
93 .name = "ctl_0", .id = CTL_0,
94 .base = 0x1000, .len = 0xE4,
95 .features = BIT(DPU_CTL_SPLIT_DISPLAY)
96 },
97 {
98 .name = "ctl_1", .id = CTL_1,
99 .base = 0x1200, .len = 0xE4,
100 .features = BIT(DPU_CTL_SPLIT_DISPLAY)
101 },
102 {
103 .name = "ctl_2", .id = CTL_2,
104 .base = 0x1400, .len = 0xE4,
105 .features = 0
106 },
107 {
108 .name = "ctl_3", .id = CTL_3,
109 .base = 0x1600, .len = 0xE4,
110 .features = 0
111 },
112 {
113 .name = "ctl_4", .id = CTL_4,
114 .base = 0x1800, .len = 0xE4,
115 .features = 0
116 },
117 };
118
119
120
121
122
123
124 static const struct dpu_sspp_blks_common sdm845_sspp_common = {
125 .maxlinewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
126 .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
127 .maxhdeciexp = MAX_HORZ_DECIMATION,
128 .maxvdeciexp = MAX_VERT_DECIMATION,
129 };
130
131 #define _VIG_SBLK(num, sdma_pri) \
132 { \
133 .common = &sdm845_sspp_common, \
134 .maxdwnscale = MAX_DOWNSCALE_RATIO, \
135 .maxupscale = MAX_UPSCALE_RATIO, \
136 .smart_dma_priority = sdma_pri, \
137 .src_blk = {.name = STRCAT("sspp_src_", num), \
138 .id = DPU_SSPP_SRC, .base = 0x00, .len = 0x150,}, \
139 .scaler_blk = {.name = STRCAT("sspp_scaler", num), \
140 .id = DPU_SSPP_SCALER_QSEED3, \
141 .base = 0xa00, .len = 0xa0,}, \
142 .csc_blk = {.name = STRCAT("sspp_csc", num), \
143 .id = DPU_SSPP_CSC_10BIT, \
144 .base = 0x1a00, .len = 0x100,}, \
145 .format_list = plane_formats_yuv, \
146 .num_formats = ARRAY_SIZE(plane_formats_yuv), \
147 .virt_format_list = plane_formats, \
148 .virt_num_formats = ARRAY_SIZE(plane_formats), \
149 }
150
151 #define _DMA_SBLK(num, sdma_pri) \
152 { \
153 .common = &sdm845_sspp_common, \
154 .maxdwnscale = SSPP_UNITY_SCALE, \
155 .maxupscale = SSPP_UNITY_SCALE, \
156 .smart_dma_priority = sdma_pri, \
157 .src_blk = {.name = STRCAT("sspp_src_", num), \
158 .id = DPU_SSPP_SRC, .base = 0x00, .len = 0x150,}, \
159 .format_list = plane_formats, \
160 .num_formats = ARRAY_SIZE(plane_formats), \
161 .virt_format_list = plane_formats, \
162 .virt_num_formats = ARRAY_SIZE(plane_formats), \
163 }
164
165 static const struct dpu_sspp_sub_blks sdm845_vig_sblk_0 = _VIG_SBLK("0", 5);
166 static const struct dpu_sspp_sub_blks sdm845_vig_sblk_1 = _VIG_SBLK("1", 6);
167 static const struct dpu_sspp_sub_blks sdm845_vig_sblk_2 = _VIG_SBLK("2", 7);
168 static const struct dpu_sspp_sub_blks sdm845_vig_sblk_3 = _VIG_SBLK("3", 8);
169
170 static const struct dpu_sspp_sub_blks sdm845_dma_sblk_0 = _DMA_SBLK("8", 1);
171 static const struct dpu_sspp_sub_blks sdm845_dma_sblk_1 = _DMA_SBLK("9", 2);
172 static const struct dpu_sspp_sub_blks sdm845_dma_sblk_2 = _DMA_SBLK("10", 3);
173 static const struct dpu_sspp_sub_blks sdm845_dma_sblk_3 = _DMA_SBLK("11", 4);
174
175 #define SSPP_BLK(_name, _id, _base, _features, \
176 _sblk, _xinid, _type, _clkctrl) \
177 { \
178 .name = _name, .id = _id, \
179 .base = _base, .len = 0x1c8, \
180 .features = _features, \
181 .sblk = &_sblk, \
182 .xin_id = _xinid, \
183 .type = _type, \
184 .clk_ctrl = _clkctrl \
185 }
186
187 static struct dpu_sspp_cfg sdm845_sspp[] = {
188 SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SDM845_MASK,
189 sdm845_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0),
190 SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SDM845_MASK,
191 sdm845_vig_sblk_1, 4, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1),
192 SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SDM845_MASK,
193 sdm845_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2),
194 SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SDM845_MASK,
195 sdm845_vig_sblk_3, 12, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3),
196 SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, DMA_SDM845_MASK,
197 sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0),
198 SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, DMA_SDM845_MASK,
199 sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1),
200 SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, DMA_CURSOR_SDM845_MASK,
201 sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR0),
202 SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, DMA_CURSOR_SDM845_MASK,
203 sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1),
204 };
205
206
207
208
209 static const struct dpu_lm_sub_blks sdm845_lm_sblk = {
210 .maxwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
211 .maxblendstages = 11,
212 .blendstage_base = {
213 0x20, 0x38, 0x50, 0x68, 0x80, 0x98,
214 0xb0, 0xc8, 0xe0, 0xf8, 0x110
215 },
216 };
217
218 #define LM_BLK(_name, _id, _base, _pp, _lmpair) \
219 { \
220 .name = _name, .id = _id, \
221 .base = _base, .len = 0x320, \
222 .features = MIXER_SDM845_MASK, \
223 .sblk = &sdm845_lm_sblk, \
224 .pingpong = _pp, \
225 .lm_pair_mask = (1 << _lmpair) \
226 }
227
228 static struct dpu_lm_cfg sdm845_lm[] = {
229 LM_BLK("lm_0", LM_0, 0x44000, PINGPONG_0, LM_1),
230 LM_BLK("lm_1", LM_1, 0x45000, PINGPONG_1, LM_0),
231 LM_BLK("lm_2", LM_2, 0x46000, PINGPONG_2, LM_5),
232 LM_BLK("lm_3", LM_3, 0x0, PINGPONG_MAX, 0),
233 LM_BLK("lm_4", LM_4, 0x0, PINGPONG_MAX, 0),
234 LM_BLK("lm_5", LM_5, 0x49000, PINGPONG_3, LM_2),
235 };
236
237
238
239
240 static const struct dpu_pingpong_sub_blks sdm845_pp_sblk_te = {
241 .te2 = {.id = DPU_PINGPONG_TE2, .base = 0x2000, .len = 0x0,
242 .version = 0x1},
243 .dither = {.id = DPU_PINGPONG_DITHER, .base = 0x30e0,
244 .len = 0x20, .version = 0x10000},
245 };
246
247 static const struct dpu_pingpong_sub_blks sdm845_pp_sblk = {
248 .dither = {.id = DPU_PINGPONG_DITHER, .base = 0x30e0,
249 .len = 0x20, .version = 0x10000},
250 };
251
252 #define PP_BLK_TE(_name, _id, _base) \
253 {\
254 .name = _name, .id = _id, \
255 .base = _base, .len = 0xd4, \
256 .features = PINGPONG_SDM845_SPLIT_MASK, \
257 .sblk = &sdm845_pp_sblk_te \
258 }
259 #define PP_BLK(_name, _id, _base) \
260 {\
261 .name = _name, .id = _id, \
262 .base = _base, .len = 0xd4, \
263 .features = PINGPONG_SDM845_MASK, \
264 .sblk = &sdm845_pp_sblk \
265 }
266
267 static struct dpu_pingpong_cfg sdm845_pp[] = {
268 PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000),
269 PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800),
270 PP_BLK("pingpong_2", PINGPONG_2, 0x71000),
271 PP_BLK("pingpong_3", PINGPONG_3, 0x71800),
272 };
273
274
275
276
277 #define INTF_BLK(_name, _id, _base, _type, _ctrl_id) \
278 {\
279 .name = _name, .id = _id, \
280 .base = _base, .len = 0x280, \
281 .type = _type, \
282 .controller_id = _ctrl_id, \
283 .prog_fetch_lines_worst_case = 24 \
284 }
285
286 static struct dpu_intf_cfg sdm845_intf[] = {
287 INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0),
288 INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0),
289 INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1),
290 INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 1),
291 };
292
293
294
295
296
297 static u32 sdm845_rt_pri_lvl[] = {3, 3, 4, 4, 5, 5, 6, 6};
298 static u32 sdm845_nrt_pri_lvl[] = {3, 3, 3, 3, 3, 3, 3, 3};
299
300 static struct dpu_vbif_cfg sdm845_vbif[] = {
301 {
302 .name = "vbif_0", .id = VBIF_0,
303 .base = 0, .len = 0x1040,
304 .features = BIT(DPU_VBIF_QOS_REMAP),
305 .xin_halt_timeout = 0x4000,
306 .qos_rt_tbl = {
307 .npriority_lvl = ARRAY_SIZE(sdm845_rt_pri_lvl),
308 .priority_lvl = sdm845_rt_pri_lvl,
309 },
310 .qos_nrt_tbl = {
311 .npriority_lvl = ARRAY_SIZE(sdm845_nrt_pri_lvl),
312 .priority_lvl = sdm845_nrt_pri_lvl,
313 },
314 .memtype_count = 14,
315 .memtype = {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
316 },
317 };
318
319 static struct dpu_reg_dma_cfg sdm845_regdma = {
320 .base = 0x0, .version = 0x1, .trigger_sel_off = 0x119c
321 };
322
323
324
325
326
327
328 static struct dpu_qos_lut_entry sdm845_qos_linear[] = {
329 {.fl = 4, .lut = 0x357},
330 {.fl = 5, .lut = 0x3357},
331 {.fl = 6, .lut = 0x23357},
332 {.fl = 7, .lut = 0x223357},
333 {.fl = 8, .lut = 0x2223357},
334 {.fl = 9, .lut = 0x22223357},
335 {.fl = 10, .lut = 0x222223357},
336 {.fl = 11, .lut = 0x2222223357},
337 {.fl = 12, .lut = 0x22222223357},
338 {.fl = 13, .lut = 0x222222223357},
339 {.fl = 14, .lut = 0x1222222223357},
340 {.fl = 0, .lut = 0x11222222223357}
341 };
342
343 static struct dpu_qos_lut_entry sdm845_qos_macrotile[] = {
344 {.fl = 10, .lut = 0x344556677},
345 {.fl = 11, .lut = 0x3344556677},
346 {.fl = 12, .lut = 0x23344556677},
347 {.fl = 13, .lut = 0x223344556677},
348 {.fl = 14, .lut = 0x1223344556677},
349 {.fl = 0, .lut = 0x112233344556677},
350 };
351
352 static struct dpu_qos_lut_entry sdm845_qos_nrt[] = {
353 {.fl = 0, .lut = 0x0},
354 };
355
356 static struct dpu_perf_cfg sdm845_perf_data = {
357 .max_bw_low = 6800000,
358 .max_bw_high = 6800000,
359 .min_core_ib = 2400000,
360 .min_llcc_ib = 800000,
361 .min_dram_ib = 800000,
362 .core_ib_ff = "6.0",
363 .core_clk_ff = "1.0",
364 .comp_ratio_rt =
365 "NV12/5/1/1.23 AB24/5/1/1.23 XB24/5/1/1.23",
366 .comp_ratio_nrt =
367 "NV12/5/1/1.25 AB24/5/1/1.25 XB24/5/1/1.25",
368 .undersized_prefill_lines = 2,
369 .xtra_prefill_lines = 2,
370 .dest_scale_prefill_lines = 3,
371 .macrotile_prefill_lines = 4,
372 .yuv_nv12_prefill_lines = 8,
373 .linear_prefill_lines = 1,
374 .downscaling_prefill_lines = 1,
375 .amortizable_threshold = 25,
376 .min_prefill_lines = 24,
377 .danger_lut_tbl = {0xf, 0xffff, 0x0},
378 .qos_lut_tbl = {
379 {.nentry = ARRAY_SIZE(sdm845_qos_linear),
380 .entries = sdm845_qos_linear
381 },
382 {.nentry = ARRAY_SIZE(sdm845_qos_macrotile),
383 .entries = sdm845_qos_macrotile
384 },
385 {.nentry = ARRAY_SIZE(sdm845_qos_nrt),
386 .entries = sdm845_qos_nrt
387 },
388 },
389 .cdp_cfg = {
390 {.rd_enable = 1, .wr_enable = 1},
391 {.rd_enable = 1, .wr_enable = 0}
392 },
393 };
394
395
396
397
398
399
400
401
402
403 static void sdm845_cfg_init(struct dpu_mdss_cfg *dpu_cfg)
404 {
405 *dpu_cfg = (struct dpu_mdss_cfg){
406 .caps = &sdm845_dpu_caps,
407 .mdp_count = ARRAY_SIZE(sdm845_mdp),
408 .mdp = sdm845_mdp,
409 .ctl_count = ARRAY_SIZE(sdm845_ctl),
410 .ctl = sdm845_ctl,
411 .sspp_count = ARRAY_SIZE(sdm845_sspp),
412 .sspp = sdm845_sspp,
413 .mixer_count = ARRAY_SIZE(sdm845_lm),
414 .mixer = sdm845_lm,
415 .pingpong_count = ARRAY_SIZE(sdm845_pp),
416 .pingpong = sdm845_pp,
417 .intf_count = ARRAY_SIZE(sdm845_intf),
418 .intf = sdm845_intf,
419 .vbif_count = ARRAY_SIZE(sdm845_vbif),
420 .vbif = sdm845_vbif,
421 .reg_dma_count = 1,
422 .dma_cfg = sdm845_regdma,
423 .perf = sdm845_perf_data,
424 };
425 }
426
427 static struct dpu_mdss_hw_cfg_handler cfg_handler[] = {
428 { .hw_rev = DPU_HW_VER_400, .cfg_init = sdm845_cfg_init},
429 { .hw_rev = DPU_HW_VER_401, .cfg_init = sdm845_cfg_init},
430 };
431
432 void dpu_hw_catalog_deinit(struct dpu_mdss_cfg *dpu_cfg)
433 {
434 kfree(dpu_cfg);
435 }
436
437 struct dpu_mdss_cfg *dpu_hw_catalog_init(u32 hw_rev)
438 {
439 int i;
440 struct dpu_mdss_cfg *dpu_cfg;
441
442 dpu_cfg = kzalloc(sizeof(*dpu_cfg), GFP_KERNEL);
443 if (!dpu_cfg)
444 return ERR_PTR(-ENOMEM);
445
446 for (i = 0; i < ARRAY_SIZE(cfg_handler); i++) {
447 if (cfg_handler[i].hw_rev == hw_rev) {
448 cfg_handler[i].cfg_init(dpu_cfg);
449 dpu_cfg->hwversion = hw_rev;
450 return dpu_cfg;
451 }
452 }
453
454 DPU_ERROR("unsupported chipset id:%X\n", hw_rev);
455 dpu_hw_catalog_deinit(dpu_cfg);
456 return ERR_PTR(-ENODEV);
457 }
458