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_kms.h"
12 
13 #define VIG_MASK \
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))
17 
18 #define VIG_SDM845_MASK \
19 	(VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3))
20 
21 #define VIG_SC7180_MASK \
22 	(VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED4))
23 
24 #define VIG_SM8250_MASK \
25 	(VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3LITE))
26 
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))
31 
32 #define DMA_CURSOR_SDM845_MASK \
33 	(DMA_SDM845_MASK | BIT(DPU_SSPP_CURSOR))
34 
35 #define MIXER_SDM845_MASK \
36 	(BIT(DPU_MIXER_SOURCESPLIT) | BIT(DPU_DIM_LAYER))
37 
38 #define MIXER_SC7180_MASK \
39 	(BIT(DPU_DIM_LAYER))
40 
41 #define PINGPONG_SDM845_MASK BIT(DPU_PINGPONG_DITHER)
42 
43 #define PINGPONG_SDM845_SPLIT_MASK \
44 	(PINGPONG_SDM845_MASK | BIT(DPU_PINGPONG_TE2))
45 
46 #define MERGE_3D_SM8150_MASK (0)
47 
48 #define DSPP_SC7180_MASK BIT(DPU_DSPP_PCC)
49 
50 #define INTF_SDM845_MASK (0)
51 
52 #define INTF_SC7180_MASK BIT(DPU_INTF_INPUT_CTRL) | BIT(DPU_INTF_TE)
53 
54 #define DEFAULT_PIXEL_RAM_SIZE		(50 * 1024)
55 #define DEFAULT_DPU_LINE_WIDTH		2048
56 #define DEFAULT_DPU_OUTPUT_LINE_WIDTH	2560
57 
58 #define MAX_HORZ_DECIMATION	4
59 #define MAX_VERT_DECIMATION	4
60 
61 #define MAX_UPSCALE_RATIO	20
62 #define MAX_DOWNSCALE_RATIO	4
63 #define SSPP_UNITY_SCALE	1
64 
65 #define STRCAT(X, Y) (X Y)
66 
67 static const uint32_t plane_formats[] = {
68 	DRM_FORMAT_ARGB8888,
69 	DRM_FORMAT_ABGR8888,
70 	DRM_FORMAT_RGBA8888,
71 	DRM_FORMAT_BGRA8888,
72 	DRM_FORMAT_XRGB8888,
73 	DRM_FORMAT_RGBX8888,
74 	DRM_FORMAT_BGRX8888,
75 	DRM_FORMAT_XBGR8888,
76 	DRM_FORMAT_RGB888,
77 	DRM_FORMAT_BGR888,
78 	DRM_FORMAT_RGB565,
79 	DRM_FORMAT_BGR565,
80 	DRM_FORMAT_ARGB1555,
81 	DRM_FORMAT_ABGR1555,
82 	DRM_FORMAT_RGBA5551,
83 	DRM_FORMAT_BGRA5551,
84 	DRM_FORMAT_XRGB1555,
85 	DRM_FORMAT_XBGR1555,
86 	DRM_FORMAT_RGBX5551,
87 	DRM_FORMAT_BGRX5551,
88 	DRM_FORMAT_ARGB4444,
89 	DRM_FORMAT_ABGR4444,
90 	DRM_FORMAT_RGBA4444,
91 	DRM_FORMAT_BGRA4444,
92 	DRM_FORMAT_XRGB4444,
93 	DRM_FORMAT_XBGR4444,
94 	DRM_FORMAT_RGBX4444,
95 	DRM_FORMAT_BGRX4444,
96 };
97 
98 static const uint32_t plane_formats_yuv[] = {
99 	DRM_FORMAT_ARGB8888,
100 	DRM_FORMAT_ABGR8888,
101 	DRM_FORMAT_RGBA8888,
102 	DRM_FORMAT_BGRX8888,
103 	DRM_FORMAT_BGRA8888,
104 	DRM_FORMAT_XRGB8888,
105 	DRM_FORMAT_XBGR8888,
106 	DRM_FORMAT_RGBX8888,
107 	DRM_FORMAT_RGB888,
108 	DRM_FORMAT_BGR888,
109 	DRM_FORMAT_RGB565,
110 	DRM_FORMAT_BGR565,
111 	DRM_FORMAT_ARGB1555,
112 	DRM_FORMAT_ABGR1555,
113 	DRM_FORMAT_RGBA5551,
114 	DRM_FORMAT_BGRA5551,
115 	DRM_FORMAT_XRGB1555,
116 	DRM_FORMAT_XBGR1555,
117 	DRM_FORMAT_RGBX5551,
118 	DRM_FORMAT_BGRX5551,
119 	DRM_FORMAT_ARGB4444,
120 	DRM_FORMAT_ABGR4444,
121 	DRM_FORMAT_RGBA4444,
122 	DRM_FORMAT_BGRA4444,
123 	DRM_FORMAT_XRGB4444,
124 	DRM_FORMAT_XBGR4444,
125 	DRM_FORMAT_RGBX4444,
126 	DRM_FORMAT_BGRX4444,
127 
128 	DRM_FORMAT_NV12,
129 	DRM_FORMAT_NV21,
130 	DRM_FORMAT_NV16,
131 	DRM_FORMAT_NV61,
132 	DRM_FORMAT_VYUY,
133 	DRM_FORMAT_UYVY,
134 	DRM_FORMAT_YUYV,
135 	DRM_FORMAT_YVYU,
136 	DRM_FORMAT_YUV420,
137 	DRM_FORMAT_YVU420,
138 };
139 
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,
152 	.has_idle_pc = 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,
158 };
159 
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,
167 	.has_idle_pc = true,
168 	.max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
169 	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
170 };
171 
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,
180 	.has_idle_pc = 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,
186 };
187 
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,
196 	.has_idle_pc = true,
197 	.has_3d_merge = true,
198 	.max_linewidth = 4096,
199 	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
200 };
201 
202 static const struct dpu_mdp_cfg sdm845_mdp[] = {
203 	{
204 	.name = "top_0", .id = MDP_TOP,
205 	.base = 0x0, .len = 0x45C,
206 	.features = 0,
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},
224 	},
225 };
226 
227 static const struct dpu_mdp_cfg sc7180_mdp[] = {
228 	{
229 	.name = "top_0", .id = MDP_TOP,
230 	.base = 0x0, .len = 0x494,
231 	.features = 0,
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},
241 	},
242 };
243 
244 static const struct dpu_mdp_cfg sm8250_mdp[] = {
245 	{
246 	.name = "top_0", .id = MDP_TOP,
247 	.base = 0x0, .len = 0x45C,
248 	.features = 0,
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},
268 	},
269 };
270 
271 /*************************************************************
272  * CTL sub blocks config
273  *************************************************************/
274 static const struct dpu_ctl_cfg sdm845_ctl[] = {
275 	{
276 	.name = "ctl_0", .id = CTL_0,
277 	.base = 0x1000, .len = 0xE4,
278 	.features = BIT(DPU_CTL_SPLIT_DISPLAY)
279 	},
280 	{
281 	.name = "ctl_1", .id = CTL_1,
282 	.base = 0x1200, .len = 0xE4,
283 	.features = BIT(DPU_CTL_SPLIT_DISPLAY)
284 	},
285 	{
286 	.name = "ctl_2", .id = CTL_2,
287 	.base = 0x1400, .len = 0xE4,
288 	.features = 0
289 	},
290 	{
291 	.name = "ctl_3", .id = CTL_3,
292 	.base = 0x1600, .len = 0xE4,
293 	.features = 0
294 	},
295 	{
296 	.name = "ctl_4", .id = CTL_4,
297 	.base = 0x1800, .len = 0xE4,
298 	.features = 0
299 	},
300 };
301 
302 static const struct dpu_ctl_cfg sc7180_ctl[] = {
303 	{
304 	.name = "ctl_0", .id = CTL_0,
305 	.base = 0x1000, .len = 0xE4,
306 	.features = BIT(DPU_CTL_ACTIVE_CFG)
307 	},
308 	{
309 	.name = "ctl_1", .id = CTL_1,
310 	.base = 0x1200, .len = 0xE4,
311 	.features = BIT(DPU_CTL_ACTIVE_CFG)
312 	},
313 	{
314 	.name = "ctl_2", .id = CTL_2,
315 	.base = 0x1400, .len = 0xE4,
316 	.features = BIT(DPU_CTL_ACTIVE_CFG)
317 	},
318 };
319 
320 static const struct dpu_ctl_cfg sm8150_ctl[] = {
321 	{
322 	.name = "ctl_0", .id = CTL_0,
323 	.base = 0x1000, .len = 0x1e0,
324 	.features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY)
325 	},
326 	{
327 	.name = "ctl_1", .id = CTL_1,
328 	.base = 0x1200, .len = 0x1e0,
329 	.features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY)
330 	},
331 	{
332 	.name = "ctl_2", .id = CTL_2,
333 	.base = 0x1400, .len = 0x1e0,
334 	.features = BIT(DPU_CTL_ACTIVE_CFG)
335 	},
336 	{
337 	.name = "ctl_3", .id = CTL_3,
338 	.base = 0x1600, .len = 0x1e0,
339 	.features = BIT(DPU_CTL_ACTIVE_CFG)
340 	},
341 	{
342 	.name = "ctl_4", .id = CTL_4,
343 	.base = 0x1800, .len = 0x1e0,
344 	.features = BIT(DPU_CTL_ACTIVE_CFG)
345 	},
346 	{
347 	.name = "ctl_5", .id = CTL_5,
348 	.base = 0x1a00, .len = 0x1e0,
349 	.features = BIT(DPU_CTL_ACTIVE_CFG)
350 	},
351 };
352 
353 /*************************************************************
354  * SSPP sub blocks config
355  *************************************************************/
356 
357 /* SSPP common configuration */
358 
359 #define _VIG_SBLK(num, sdma_pri, qseed_ver) \
360 	{ \
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), \
367 		.id = qseed_ver, \
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), \
376 	}
377 
378 #define _DMA_SBLK(num, sdma_pri) \
379 	{ \
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), \
389 	}
390 
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);
399 
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);
404 
405 #define SSPP_BLK(_name, _id, _base, _features, \
406 		_sblk, _xinid, _type, _clkctrl) \
407 	{ \
408 	.name = _name, .id = _id, \
409 	.base = _base, .len = 0x1c8, \
410 	.features = _features, \
411 	.sblk = &_sblk, \
412 	.xin_id = _xinid, \
413 	.type = _type, \
414 	.clk_ctrl = _clkctrl \
415 	}
416 
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),
434 };
435 
436 static const struct dpu_sspp_sub_blks sc7180_vig_sblk_0 =
437 				_VIG_SBLK("0", 4, DPU_SSPP_SCALER_QSEED4);
438 
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),
448 };
449 
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);
458 
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),
476 };
477 
478 /*************************************************************
479  * MIXER sub blocks config
480  *************************************************************/
481 
482 /* SDM845 */
483 
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
490 	},
491 };
492 
493 #define LM_BLK(_name, _id, _base, _fmask, _sblk, _pp, _lmpair, _dspp) \
494 	{ \
495 	.name = _name, .id = _id, \
496 	.base = _base, .len = 0x320, \
497 	.features = _fmask, \
498 	.sblk = _sblk, \
499 	.pingpong = _pp, \
500 	.lm_pair_mask = (1 << _lmpair), \
501 	.dspp = _dspp \
502 	}
503 
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),
517 };
518 
519 /* SC7180 */
520 
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
526 	},
527 };
528 
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),
534 };
535 
536 /* SM8150 */
537 
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),
551 };
552 
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},
559 };
560 
561 static const struct dpu_dspp_sub_blks sm8150_dspp_sblk = {
562 	.pcc = {.id = DPU_DSPP_PCC, .base = 0x1700,
563 		.len = 0x90, .version = 0x40000},
564 };
565 
566 #define DSPP_BLK(_name, _id, _base, _mask, _sblk) \
567 		{\
568 		.name = _name, .id = _id, \
569 		.base = _base, .len = 0x1800, \
570 		.features = _mask, \
571 		.sblk = _sblk \
572 		}
573 
574 static const struct dpu_dspp_cfg sc7180_dspp[] = {
575 	DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_SC7180_MASK,
576 		 &sc7180_dspp_sblk),
577 };
578 
579 static const struct dpu_dspp_cfg sm8150_dspp[] = {
580 	DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_SC7180_MASK,
581 		 &sm8150_dspp_sblk),
582 	DSPP_BLK("dspp_1", DSPP_1, 0x56000, DSPP_SC7180_MASK,
583 		 &sm8150_dspp_sblk),
584 	DSPP_BLK("dspp_2", DSPP_2, 0x58000, DSPP_SC7180_MASK,
585 		 &sm8150_dspp_sblk),
586 	DSPP_BLK("dspp_3", DSPP_3, 0x5a000, DSPP_SC7180_MASK,
587 		 &sm8150_dspp_sblk),
588 };
589 
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,
595 		.version = 0x1},
596 	.dither = {.id = DPU_PINGPONG_DITHER, .base = 0x30e0,
597 		.len = 0x20, .version = 0x10000},
598 };
599 
600 static const struct dpu_pingpong_sub_blks sdm845_pp_sblk = {
601 	.dither = {.id = DPU_PINGPONG_DITHER, .base = 0x30e0,
602 		.len = 0x20, .version = 0x10000},
603 };
604 
605 #define PP_BLK_TE(_name, _id, _base, _merge_3d) \
606 	{\
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 \
612 	}
613 #define PP_BLK(_name, _id, _base, _merge_3d) \
614 	{\
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 \
620 	}
621 
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),
627 };
628 
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),
632 };
633 
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),
641 };
642 
643 /*************************************************************
644  * MERGE_3D sub blocks config
645  *************************************************************/
646 #define MERGE_3D_BLK(_name, _id, _base) \
647 	{\
648 	.name = _name, .id = _id, \
649 	.base = _base, .len = 0x100, \
650 	.features = MERGE_3D_SM8150_MASK, \
651 	.sblk = NULL \
652 	}
653 
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),
658 };
659 
660 /*************************************************************
661  * INTF sub blocks config
662  *************************************************************/
663 #define INTF_BLK(_name, _id, _base, _type, _ctrl_id, _progfetch, _features) \
664 	{\
665 	.name = _name, .id = _id, \
666 	.base = _base, .len = 0x280, \
667 	.features = _features, \
668 	.type = _type, \
669 	.controller_id = _ctrl_id, \
670 	.prog_fetch_lines_worst_case = _progfetch \
671 	}
672 
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),
678 };
679 
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),
683 };
684 
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),
690 };
691 
692 /*************************************************************
693  * VBIF sub blocks config
694  *************************************************************/
695 /* VBIF QOS remap */
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};
698 
699 static const struct dpu_vbif_cfg sdm845_vbif[] = {
700 	{
701 	.name = "vbif_0", .id = VBIF_0,
702 	.base = 0, .len = 0x1040,
703 	.features = BIT(DPU_VBIF_QOS_REMAP),
704 	.xin_halt_timeout = 0x4000,
705 	.qos_rt_tbl = {
706 		.npriority_lvl = ARRAY_SIZE(sdm845_rt_pri_lvl),
707 		.priority_lvl = sdm845_rt_pri_lvl,
708 		},
709 	.qos_nrt_tbl = {
710 		.npriority_lvl = ARRAY_SIZE(sdm845_nrt_pri_lvl),
711 		.priority_lvl = sdm845_nrt_pri_lvl,
712 		},
713 	.memtype_count = 14,
714 	.memtype = {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
715 	},
716 };
717 
718 static const struct dpu_reg_dma_cfg sdm845_regdma = {
719 	.base = 0x0, .version = 0x1, .trigger_sel_off = 0x119c
720 };
721 
722 static const struct dpu_reg_dma_cfg sm8150_regdma = {
723 	.base = 0x0, .version = 0x00010001, .trigger_sel_off = 0x119c
724 };
725 
726 static const struct dpu_reg_dma_cfg sm8250_regdma = {
727 	.base = 0x0,
728 	.version = 0x00010002,
729 	.trigger_sel_off = 0x119c,
730 	.xin_id = 7,
731 	.clk_ctrl = DPU_CLK_CTRL_REG_DMA,
732 };
733 
734 /*************************************************************
735  * PERF data config
736  *************************************************************/
737 
738 /* SSPP QOS LUTs */
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}
752 };
753 
754 static const struct dpu_qos_lut_entry sc7180_qos_linear[] = {
755 	{.fl = 0, .lut = 0x0011222222335777},
756 };
757 
758 static const struct dpu_qos_lut_entry sm8150_qos_linear[] = {
759 	{.fl = 0, .lut = 0x0011222222223357 },
760 };
761 
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},
769 };
770 
771 static const struct dpu_qos_lut_entry sc7180_qos_macrotile[] = {
772 	{.fl = 0, .lut = 0x0011223344556677},
773 };
774 
775 static const struct dpu_qos_lut_entry sdm845_qos_nrt[] = {
776 	{.fl = 0, .lut = 0x0},
777 };
778 
779 static const struct dpu_qos_lut_entry sc7180_qos_nrt[] = {
780 	{.fl = 0, .lut = 0x0},
781 };
782 
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,
789 	.core_ib_ff = "6.0",
790 	.core_clk_ff = "1.0",
791 	.comp_ratio_rt =
792 	"NV12/5/1/1.23 AB24/5/1/1.23 XB24/5/1/1.23",
793 	.comp_ratio_nrt =
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},
805 	.qos_lut_tbl = {
806 		{.nentry = ARRAY_SIZE(sdm845_qos_linear),
807 		.entries = sdm845_qos_linear
808 		},
809 		{.nentry = ARRAY_SIZE(sdm845_qos_macrotile),
810 		.entries = sdm845_qos_macrotile
811 		},
812 		{.nentry = ARRAY_SIZE(sdm845_qos_nrt),
813 		.entries = sdm845_qos_nrt
814 		},
815 	},
816 	.cdp_cfg = {
817 		{.rd_enable = 1, .wr_enable = 1},
818 		{.rd_enable = 1, .wr_enable = 0}
819 	},
820 };
821 
822 static const struct dpu_perf_cfg sc7180_perf_data = {
823 	.max_bw_low = 6800000,
824 	.max_bw_high = 6800000,
825 	.min_core_ib = 2400000,
826 	.min_llcc_ib = 800000,
827 	.min_dram_ib = 1600000,
828 	.min_prefill_lines = 24,
829 	.danger_lut_tbl = {0xff, 0xffff, 0x0},
830 	.qos_lut_tbl = {
831 		{.nentry = ARRAY_SIZE(sc7180_qos_linear),
832 		.entries = sc7180_qos_linear
833 		},
834 		{.nentry = ARRAY_SIZE(sc7180_qos_macrotile),
835 		.entries = sc7180_qos_macrotile
836 		},
837 		{.nentry = ARRAY_SIZE(sc7180_qos_nrt),
838 		.entries = sc7180_qos_nrt
839 		},
840 	},
841 	.cdp_cfg = {
842 		{.rd_enable = 1, .wr_enable = 1},
843 		{.rd_enable = 1, .wr_enable = 0}
844 	},
845 	.clk_inefficiency_factor = 105,
846 	.bw_inefficiency_factor = 120,
847 };
848 
849 static const struct dpu_perf_cfg sm8150_perf_data = {
850 	.max_bw_low = 12800000,
851 	.max_bw_high = 12800000,
852 	.min_core_ib = 2400000,
853 	.min_llcc_ib = 800000,
854 	.min_dram_ib = 800000,
855 	.danger_lut_tbl = {0xf, 0xffff, 0x0},
856 	.qos_lut_tbl = {
857 		{.nentry = ARRAY_SIZE(sm8150_qos_linear),
858 		.entries = sm8150_qos_linear
859 		},
860 		{.nentry = ARRAY_SIZE(sc7180_qos_macrotile),
861 		.entries = sc7180_qos_macrotile
862 		},
863 		{.nentry = ARRAY_SIZE(sc7180_qos_nrt),
864 		.entries = sc7180_qos_nrt
865 		},
866 		/* TODO: macrotile-qseed is different from macrotile */
867 	},
868 	.cdp_cfg = {
869 		{.rd_enable = 1, .wr_enable = 1},
870 		{.rd_enable = 1, .wr_enable = 0}
871 	},
872 };
873 
874 static const struct dpu_perf_cfg sm8250_perf_data = {
875 	.max_bw_low = 13700000,
876 	.max_bw_high = 16600000,
877 	.min_core_ib = 4800000,
878 	.min_llcc_ib = 0,
879 	.min_dram_ib = 800000,
880 	.danger_lut_tbl = {0xf, 0xffff, 0x0},
881 	.qos_lut_tbl = {
882 		{.nentry = ARRAY_SIZE(sc7180_qos_linear),
883 		.entries = sc7180_qos_linear
884 		},
885 		{.nentry = ARRAY_SIZE(sc7180_qos_macrotile),
886 		.entries = sc7180_qos_macrotile
887 		},
888 		{.nentry = ARRAY_SIZE(sc7180_qos_nrt),
889 		.entries = sc7180_qos_nrt
890 		},
891 		/* TODO: macrotile-qseed is different from macrotile */
892 	},
893 	.cdp_cfg = {
894 		{.rd_enable = 1, .wr_enable = 1},
895 		{.rd_enable = 1, .wr_enable = 0}
896 	},
897 };
898 
899 /*************************************************************
900  * Hardware catalog init
901  *************************************************************/
902 
903 /*
904  * sdm845_cfg_init(): populate sdm845 dpu sub-blocks reg offsets
905  * and instance counts.
906  */
907 static void sdm845_cfg_init(struct dpu_mdss_cfg *dpu_cfg)
908 {
909 	*dpu_cfg = (struct dpu_mdss_cfg){
910 		.caps = &sdm845_dpu_caps,
911 		.mdp_count = ARRAY_SIZE(sdm845_mdp),
912 		.mdp = sdm845_mdp,
913 		.ctl_count = ARRAY_SIZE(sdm845_ctl),
914 		.ctl = sdm845_ctl,
915 		.sspp_count = ARRAY_SIZE(sdm845_sspp),
916 		.sspp = sdm845_sspp,
917 		.mixer_count = ARRAY_SIZE(sdm845_lm),
918 		.mixer = sdm845_lm,
919 		.pingpong_count = ARRAY_SIZE(sdm845_pp),
920 		.pingpong = sdm845_pp,
921 		.intf_count = ARRAY_SIZE(sdm845_intf),
922 		.intf = sdm845_intf,
923 		.vbif_count = ARRAY_SIZE(sdm845_vbif),
924 		.vbif = sdm845_vbif,
925 		.reg_dma_count = 1,
926 		.dma_cfg = sdm845_regdma,
927 		.perf = sdm845_perf_data,
928 		.mdss_irqs = 0x3ff,
929 	};
930 }
931 
932 /*
933  * sc7180_cfg_init(): populate sc7180 dpu sub-blocks reg offsets
934  * and instance counts.
935  */
936 static void sc7180_cfg_init(struct dpu_mdss_cfg *dpu_cfg)
937 {
938 	*dpu_cfg = (struct dpu_mdss_cfg){
939 		.caps = &sc7180_dpu_caps,
940 		.mdp_count = ARRAY_SIZE(sc7180_mdp),
941 		.mdp = sc7180_mdp,
942 		.ctl_count = ARRAY_SIZE(sc7180_ctl),
943 		.ctl = sc7180_ctl,
944 		.sspp_count = ARRAY_SIZE(sc7180_sspp),
945 		.sspp = sc7180_sspp,
946 		.mixer_count = ARRAY_SIZE(sc7180_lm),
947 		.mixer = sc7180_lm,
948 		.dspp_count = ARRAY_SIZE(sc7180_dspp),
949 		.dspp = sc7180_dspp,
950 		.pingpong_count = ARRAY_SIZE(sc7180_pp),
951 		.pingpong = sc7180_pp,
952 		.intf_count = ARRAY_SIZE(sc7180_intf),
953 		.intf = sc7180_intf,
954 		.vbif_count = ARRAY_SIZE(sdm845_vbif),
955 		.vbif = sdm845_vbif,
956 		.reg_dma_count = 1,
957 		.dma_cfg = sdm845_regdma,
958 		.perf = sc7180_perf_data,
959 		.mdss_irqs = 0x3f,
960 	};
961 }
962 
963 /*
964  * sm8150_cfg_init(): populate sm8150 dpu sub-blocks reg offsets
965  * and instance counts.
966  */
967 static void sm8150_cfg_init(struct dpu_mdss_cfg *dpu_cfg)
968 {
969 	*dpu_cfg = (struct dpu_mdss_cfg){
970 		.caps = &sm8150_dpu_caps,
971 		.mdp_count = ARRAY_SIZE(sdm845_mdp),
972 		.mdp = sdm845_mdp,
973 		.ctl_count = ARRAY_SIZE(sm8150_ctl),
974 		.ctl = sm8150_ctl,
975 		.sspp_count = ARRAY_SIZE(sdm845_sspp),
976 		.sspp = sdm845_sspp,
977 		.mixer_count = ARRAY_SIZE(sm8150_lm),
978 		.mixer = sm8150_lm,
979 		.dspp_count = ARRAY_SIZE(sm8150_dspp),
980 		.dspp = sm8150_dspp,
981 		.pingpong_count = ARRAY_SIZE(sm8150_pp),
982 		.pingpong = sm8150_pp,
983 		.merge_3d_count = ARRAY_SIZE(sm8150_merge_3d),
984 		.merge_3d = sm8150_merge_3d,
985 		.intf_count = ARRAY_SIZE(sm8150_intf),
986 		.intf = sm8150_intf,
987 		.vbif_count = ARRAY_SIZE(sdm845_vbif),
988 		.vbif = sdm845_vbif,
989 		.reg_dma_count = 1,
990 		.dma_cfg = sm8150_regdma,
991 		.perf = sm8150_perf_data,
992 		.mdss_irqs = 0x3ff,
993 	};
994 }
995 
996 /*
997  * sm8250_cfg_init(): populate sm8250 dpu sub-blocks reg offsets
998  * and instance counts.
999  */
1000 static void sm8250_cfg_init(struct dpu_mdss_cfg *dpu_cfg)
1001 {
1002 	*dpu_cfg = (struct dpu_mdss_cfg){
1003 		.caps = &sm8250_dpu_caps,
1004 		.mdp_count = ARRAY_SIZE(sm8250_mdp),
1005 		.mdp = sm8250_mdp,
1006 		.ctl_count = ARRAY_SIZE(sm8150_ctl),
1007 		.ctl = sm8150_ctl,
1008 		.sspp_count = ARRAY_SIZE(sm8250_sspp),
1009 		.sspp = sm8250_sspp,
1010 		.mixer_count = ARRAY_SIZE(sm8150_lm),
1011 		.mixer = sm8150_lm,
1012 		.dspp_count = ARRAY_SIZE(sm8150_dspp),
1013 		.dspp = sm8150_dspp,
1014 		.pingpong_count = ARRAY_SIZE(sm8150_pp),
1015 		.pingpong = sm8150_pp,
1016 		.merge_3d_count = ARRAY_SIZE(sm8150_merge_3d),
1017 		.merge_3d = sm8150_merge_3d,
1018 		.intf_count = ARRAY_SIZE(sm8150_intf),
1019 		.intf = sm8150_intf,
1020 		.vbif_count = ARRAY_SIZE(sdm845_vbif),
1021 		.vbif = sdm845_vbif,
1022 		.reg_dma_count = 1,
1023 		.dma_cfg = sm8250_regdma,
1024 		.perf = sm8250_perf_data,
1025 		.mdss_irqs = 0xff,
1026 	};
1027 }
1028 
1029 static const struct dpu_mdss_hw_cfg_handler cfg_handler[] = {
1030 	{ .hw_rev = DPU_HW_VER_400, .cfg_init = sdm845_cfg_init},
1031 	{ .hw_rev = DPU_HW_VER_401, .cfg_init = sdm845_cfg_init},
1032 	{ .hw_rev = DPU_HW_VER_500, .cfg_init = sm8150_cfg_init},
1033 	{ .hw_rev = DPU_HW_VER_501, .cfg_init = sm8150_cfg_init},
1034 	{ .hw_rev = DPU_HW_VER_600, .cfg_init = sm8250_cfg_init},
1035 	{ .hw_rev = DPU_HW_VER_620, .cfg_init = sc7180_cfg_init},
1036 };
1037 
1038 void dpu_hw_catalog_deinit(struct dpu_mdss_cfg *dpu_cfg)
1039 {
1040 	kfree(dpu_cfg);
1041 }
1042 
1043 struct dpu_mdss_cfg *dpu_hw_catalog_init(u32 hw_rev)
1044 {
1045 	int i;
1046 	struct dpu_mdss_cfg *dpu_cfg;
1047 
1048 	dpu_cfg = kzalloc(sizeof(*dpu_cfg), GFP_KERNEL);
1049 	if (!dpu_cfg)
1050 		return ERR_PTR(-ENOMEM);
1051 
1052 	for (i = 0; i < ARRAY_SIZE(cfg_handler); i++) {
1053 		if (cfg_handler[i].hw_rev == hw_rev) {
1054 			cfg_handler[i].cfg_init(dpu_cfg);
1055 			dpu_cfg->hwversion = hw_rev;
1056 			return dpu_cfg;
1057 		}
1058 	}
1059 
1060 	DPU_ERROR("unsupported chipset id:%X\n", hw_rev);
1061 	dpu_hw_catalog_deinit(dpu_cfg);
1062 	return ERR_PTR(-ENODEV);
1063 }
1064 
1065