GNU Linux-libre 4.19.295-gnu1
[releases.git] / drivers / gpu / drm / msm / disp / dpu1 / dpu_hw_catalog.c
1 /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
2  *
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License version 2 and
5  * only version 2 as published by the Free Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  */
12
13 #define pr_fmt(fmt)     "[drm:%s:%d] " fmt, __func__, __LINE__
14 #include <linux/slab.h>
15 #include <linux/of_address.h>
16 #include <linux/platform_device.h>
17 #include "dpu_hw_mdss.h"
18 #include "dpu_hw_catalog.h"
19 #include "dpu_hw_catalog_format.h"
20 #include "dpu_kms.h"
21
22 #define VIG_SDM845_MASK \
23         (BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_SCALER_QSEED3) | BIT(DPU_SSPP_QOS) |\
24         BIT(DPU_SSPP_CSC_10BIT) | BIT(DPU_SSPP_CDP) | BIT(DPU_SSPP_QOS_8LVL) |\
25         BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_EXCL_RECT))
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 MIXER_SDM845_MASK \
33         (BIT(DPU_MIXER_SOURCESPLIT) | BIT(DPU_DIM_LAYER))
34
35 #define PINGPONG_SDM845_MASK BIT(DPU_PINGPONG_DITHER)
36
37 #define PINGPONG_SDM845_SPLIT_MASK \
38         (PINGPONG_SDM845_MASK | BIT(DPU_PINGPONG_TE2))
39
40 #define DEFAULT_PIXEL_RAM_SIZE          (50 * 1024)
41 #define DEFAULT_DPU_LINE_WIDTH          2048
42 #define DEFAULT_DPU_OUTPUT_LINE_WIDTH   2560
43
44 #define MAX_HORZ_DECIMATION     4
45 #define MAX_VERT_DECIMATION     4
46
47 #define MAX_UPSCALE_RATIO       20
48 #define MAX_DOWNSCALE_RATIO     4
49 #define SSPP_UNITY_SCALE        1
50
51 #define STRCAT(X, Y) (X Y)
52
53 /*************************************************************
54  * DPU sub blocks config
55  *************************************************************/
56 /* DPU top level caps */
57 static const struct dpu_caps sdm845_dpu_caps = {
58         .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
59         .max_mixer_blendstages = 0xb,
60         .qseed_type = DPU_SSPP_SCALER_QSEED3,
61         .smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
62         .ubwc_version = DPU_HW_UBWC_VER_20,
63         .has_src_split = true,
64         .has_dim_layer = true,
65         .has_idle_pc = true,
66 };
67
68 static struct dpu_mdp_cfg sdm845_mdp[] = {
69         {
70         .name = "top_0", .id = MDP_TOP,
71         .base = 0x0, .len = 0x45C,
72         .features = 0,
73         .highest_bank_bit = 0x2,
74         .has_dest_scaler = true,
75         .clk_ctrls[DPU_CLK_CTRL_VIG0] = {
76                         .reg_off = 0x2AC, .bit_off = 0},
77         .clk_ctrls[DPU_CLK_CTRL_VIG1] = {
78                         .reg_off = 0x2B4, .bit_off = 0},
79         .clk_ctrls[DPU_CLK_CTRL_VIG2] = {
80                         .reg_off = 0x2BC, .bit_off = 0},
81         .clk_ctrls[DPU_CLK_CTRL_VIG3] = {
82                         .reg_off = 0x2C4, .bit_off = 0},
83         .clk_ctrls[DPU_CLK_CTRL_DMA0] = {
84                         .reg_off = 0x2AC, .bit_off = 8},
85         .clk_ctrls[DPU_CLK_CTRL_DMA1] = {
86                         .reg_off = 0x2B4, .bit_off = 8},
87         .clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
88                         .reg_off = 0x2BC, .bit_off = 8},
89         .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
90                         .reg_off = 0x2C4, .bit_off = 8},
91         },
92 };
93
94 /*************************************************************
95  * CTL sub blocks config
96  *************************************************************/
97 static struct dpu_ctl_cfg sdm845_ctl[] = {
98         {
99         .name = "ctl_0", .id = CTL_0,
100         .base = 0x1000, .len = 0xE4,
101         .features = BIT(DPU_CTL_SPLIT_DISPLAY)
102         },
103         {
104         .name = "ctl_1", .id = CTL_1,
105         .base = 0x1200, .len = 0xE4,
106         .features = BIT(DPU_CTL_SPLIT_DISPLAY)
107         },
108         {
109         .name = "ctl_2", .id = CTL_2,
110         .base = 0x1400, .len = 0xE4,
111         .features = 0
112         },
113         {
114         .name = "ctl_3", .id = CTL_3,
115         .base = 0x1600, .len = 0xE4,
116         .features = 0
117         },
118         {
119         .name = "ctl_4", .id = CTL_4,
120         .base = 0x1800, .len = 0xE4,
121         .features = 0
122         },
123 };
124
125 /*************************************************************
126  * SSPP sub blocks config
127  *************************************************************/
128
129 /* SSPP common configuration */
130 static const struct dpu_sspp_blks_common sdm845_sspp_common = {
131         .maxlinewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
132         .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
133         .maxhdeciexp = MAX_HORZ_DECIMATION,
134         .maxvdeciexp = MAX_VERT_DECIMATION,
135 };
136
137 #define _VIG_SBLK(num, sdma_pri) \
138         { \
139         .common = &sdm845_sspp_common, \
140         .maxdwnscale = MAX_DOWNSCALE_RATIO, \
141         .maxupscale = MAX_UPSCALE_RATIO, \
142         .smart_dma_priority = sdma_pri, \
143         .src_blk = {.name = STRCAT("sspp_src_", num), \
144                 .id = DPU_SSPP_SRC, .base = 0x00, .len = 0x150,}, \
145         .scaler_blk = {.name = STRCAT("sspp_scaler", num), \
146                 .id = DPU_SSPP_SCALER_QSEED3, \
147                 .base = 0xa00, .len = 0xa0,}, \
148         .csc_blk = {.name = STRCAT("sspp_csc", num), \
149                 .id = DPU_SSPP_CSC_10BIT, \
150                 .base = 0x1a00, .len = 0x100,}, \
151         .format_list = plane_formats_yuv, \
152         .virt_format_list = plane_formats, \
153         }
154
155 #define _DMA_SBLK(num, sdma_pri) \
156         { \
157         .common = &sdm845_sspp_common, \
158         .maxdwnscale = SSPP_UNITY_SCALE, \
159         .maxupscale = SSPP_UNITY_SCALE, \
160         .smart_dma_priority = sdma_pri, \
161         .src_blk = {.name = STRCAT("sspp_src_", num), \
162                 .id = DPU_SSPP_SRC, .base = 0x00, .len = 0x150,}, \
163         .format_list = plane_formats, \
164         .virt_format_list = plane_formats, \
165         }
166
167 static const struct dpu_sspp_sub_blks sdm845_vig_sblk_0 = _VIG_SBLK("0", 5);
168 static const struct dpu_sspp_sub_blks sdm845_vig_sblk_1 = _VIG_SBLK("1", 6);
169 static const struct dpu_sspp_sub_blks sdm845_vig_sblk_2 = _VIG_SBLK("2", 7);
170 static const struct dpu_sspp_sub_blks sdm845_vig_sblk_3 = _VIG_SBLK("3", 8);
171
172 static const struct dpu_sspp_sub_blks sdm845_dma_sblk_0 = _DMA_SBLK("8", 1);
173 static const struct dpu_sspp_sub_blks sdm845_dma_sblk_1 = _DMA_SBLK("9", 2);
174 static const struct dpu_sspp_sub_blks sdm845_dma_sblk_2 = _DMA_SBLK("10", 3);
175 static const struct dpu_sspp_sub_blks sdm845_dma_sblk_3 = _DMA_SBLK("11", 4);
176
177 #define SSPP_VIG_BLK(_name, _id, _base, _sblk, _xinid, _clkctrl) \
178         { \
179         .name = _name, .id = _id, \
180         .base = _base, .len = 0x1c8, \
181         .features = VIG_SDM845_MASK, \
182         .sblk = &_sblk, \
183         .xin_id = _xinid, \
184         .type = SSPP_TYPE_VIG, \
185         .clk_ctrl = _clkctrl \
186         }
187
188 #define SSPP_DMA_BLK(_name, _id, _base, _sblk, _xinid, _clkctrl) \
189         { \
190         .name = _name, .id = _id, \
191         .base = _base, .len = 0x1c8, \
192         .features = DMA_SDM845_MASK, \
193         .sblk = &_sblk, \
194         .xin_id = _xinid, \
195         .type = SSPP_TYPE_DMA, \
196         .clk_ctrl = _clkctrl \
197         }
198
199 static struct dpu_sspp_cfg sdm845_sspp[] = {
200         SSPP_VIG_BLK("sspp_0", SSPP_VIG0, 0x4000,
201                 sdm845_vig_sblk_0, 0, DPU_CLK_CTRL_VIG0),
202         SSPP_VIG_BLK("sspp_1", SSPP_VIG1, 0x6000,
203                 sdm845_vig_sblk_1, 4, DPU_CLK_CTRL_VIG1),
204         SSPP_VIG_BLK("sspp_2", SSPP_VIG2, 0x8000,
205                 sdm845_vig_sblk_2, 8, DPU_CLK_CTRL_VIG2),
206         SSPP_VIG_BLK("sspp_3", SSPP_VIG3, 0xa000,
207                 sdm845_vig_sblk_3, 12, DPU_CLK_CTRL_VIG3),
208         SSPP_DMA_BLK("sspp_8", SSPP_DMA0, 0x24000,
209                 sdm845_dma_sblk_0, 1, DPU_CLK_CTRL_DMA0),
210         SSPP_DMA_BLK("sspp_9", SSPP_DMA1, 0x26000,
211                 sdm845_dma_sblk_1, 5, DPU_CLK_CTRL_DMA1),
212         SSPP_DMA_BLK("sspp_10", SSPP_DMA2, 0x28000,
213                 sdm845_dma_sblk_2, 9, DPU_CLK_CTRL_CURSOR0),
214         SSPP_DMA_BLK("sspp_11", SSPP_DMA3, 0x2a000,
215                 sdm845_dma_sblk_3, 13, DPU_CLK_CTRL_CURSOR1),
216 };
217
218 /*************************************************************
219  * MIXER sub blocks config
220  *************************************************************/
221 static const struct dpu_lm_sub_blks sdm845_lm_sblk = {
222         .maxwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
223         .maxblendstages = 11, /* excluding base layer */
224         .blendstage_base = { /* offsets relative to mixer base */
225                 0x20, 0x38, 0x50, 0x68, 0x80, 0x98,
226                 0xb0, 0xc8, 0xe0, 0xf8, 0x110
227         },
228 };
229
230 #define LM_BLK(_name, _id, _base, _ds, _pp, _lmpair) \
231         { \
232         .name = _name, .id = _id, \
233         .base = _base, .len = 0x320, \
234         .features = MIXER_SDM845_MASK, \
235         .sblk = &sdm845_lm_sblk, \
236         .ds = _ds, \
237         .pingpong = _pp, \
238         .lm_pair_mask = (1 << _lmpair) \
239         }
240
241 static struct dpu_lm_cfg sdm845_lm[] = {
242         LM_BLK("lm_0", LM_0, 0x44000, DS_0, PINGPONG_0, LM_1),
243         LM_BLK("lm_1", LM_1, 0x45000, DS_1, PINGPONG_1, LM_0),
244         LM_BLK("lm_2", LM_2, 0x46000, DS_MAX, PINGPONG_2, LM_5),
245         LM_BLK("lm_3", LM_3, 0x0, DS_MAX, PINGPONG_MAX, 0),
246         LM_BLK("lm_4", LM_4, 0x0, DS_MAX, PINGPONG_MAX, 0),
247         LM_BLK("lm_5", LM_5, 0x49000, DS_MAX, PINGPONG_3, LM_2),
248 };
249
250 /*************************************************************
251  * DS sub blocks config
252  *************************************************************/
253 static const struct dpu_ds_top_cfg sdm845_ds_top = {
254         .name = "ds_top_0", .id = DS_TOP,
255         .base = 0x60000, .len = 0xc,
256         .maxinputwidth = DEFAULT_DPU_LINE_WIDTH,
257         .maxoutputwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
258         .maxupscale = MAX_UPSCALE_RATIO,
259 };
260
261 #define DS_BLK(_name, _id, _base) \
262         {\
263         .name = _name, .id = _id, \
264         .base = _base, .len = 0x800, \
265         .features = DPU_SSPP_SCALER_QSEED3, \
266         .top = &sdm845_ds_top \
267         }
268
269 static struct dpu_ds_cfg sdm845_ds[] = {
270         DS_BLK("ds_0", DS_0, 0x800),
271         DS_BLK("ds_1", DS_1, 0x1000),
272 };
273
274 /*************************************************************
275  * PINGPONG sub blocks config
276  *************************************************************/
277 static const struct dpu_pingpong_sub_blks sdm845_pp_sblk_te = {
278         .te2 = {.id = DPU_PINGPONG_TE2, .base = 0x2000, .len = 0x0,
279                 .version = 0x1},
280         .dither = {.id = DPU_PINGPONG_DITHER, .base = 0x30e0,
281                 .len = 0x20, .version = 0x10000},
282 };
283
284 static const struct dpu_pingpong_sub_blks sdm845_pp_sblk = {
285         .dither = {.id = DPU_PINGPONG_DITHER, .base = 0x30e0,
286                 .len = 0x20, .version = 0x10000},
287 };
288
289 #define PP_BLK_TE(_name, _id, _base) \
290         {\
291         .name = _name, .id = _id, \
292         .base = _base, .len = 0xd4, \
293         .features = PINGPONG_SDM845_SPLIT_MASK, \
294         .sblk = &sdm845_pp_sblk_te \
295         }
296 #define PP_BLK(_name, _id, _base) \
297         {\
298         .name = _name, .id = _id, \
299         .base = _base, .len = 0xd4, \
300         .features = PINGPONG_SDM845_MASK, \
301         .sblk = &sdm845_pp_sblk \
302         }
303
304 static struct dpu_pingpong_cfg sdm845_pp[] = {
305         PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000),
306         PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800),
307         PP_BLK("pingpong_2", PINGPONG_2, 0x71000),
308         PP_BLK("pingpong_3", PINGPONG_3, 0x71800),
309 };
310
311 /*************************************************************
312  * INTF sub blocks config
313  *************************************************************/
314 #define INTF_BLK(_name, _id, _base, _type, _ctrl_id) \
315         {\
316         .name = _name, .id = _id, \
317         .base = _base, .len = 0x280, \
318         .type = _type, \
319         .controller_id = _ctrl_id, \
320         .prog_fetch_lines_worst_case = 24 \
321         }
322
323 static struct dpu_intf_cfg sdm845_intf[] = {
324         INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0),
325         INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0),
326         INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1),
327         INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 1),
328 };
329
330 /*************************************************************
331  * CDM sub blocks config
332  *************************************************************/
333 static struct dpu_cdm_cfg sdm845_cdm[] = {
334         {
335         .name = "cdm_0", .id = CDM_0,
336         .base = 0x79200, .len = 0x224,
337         .features = 0,
338         .intf_connect = BIT(INTF_3),
339         },
340 };
341
342 /*************************************************************
343  * VBIF sub blocks config
344  *************************************************************/
345 /* VBIF QOS remap */
346 static u32 sdm845_rt_pri_lvl[] = {3, 3, 4, 4, 5, 5, 6, 6};
347 static u32 sdm845_nrt_pri_lvl[] = {3, 3, 3, 3, 3, 3, 3, 3};
348
349 static struct dpu_vbif_cfg sdm845_vbif[] = {
350         {
351         .name = "vbif_0", .id = VBIF_0,
352         .base = 0, .len = 0x1040,
353         .features = BIT(DPU_VBIF_QOS_REMAP),
354         .xin_halt_timeout = 0x4000,
355         .qos_rt_tbl = {
356                 .npriority_lvl = ARRAY_SIZE(sdm845_rt_pri_lvl),
357                 .priority_lvl = sdm845_rt_pri_lvl,
358                 },
359         .qos_nrt_tbl = {
360                 .npriority_lvl = ARRAY_SIZE(sdm845_nrt_pri_lvl),
361                 .priority_lvl = sdm845_nrt_pri_lvl,
362                 },
363         .memtype_count = 14,
364         .memtype = {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
365         },
366 };
367
368 static struct dpu_reg_dma_cfg sdm845_regdma = {
369         .base = 0x0, .version = 0x1, .trigger_sel_off = 0x119c
370 };
371
372 /*************************************************************
373  * PERF data config
374  *************************************************************/
375
376 /* SSPP QOS LUTs */
377 static struct dpu_qos_lut_entry sdm845_qos_linear[] = {
378         {.fl = 4, .lut = 0x357},
379         {.fl = 5, .lut = 0x3357},
380         {.fl = 6, .lut = 0x23357},
381         {.fl = 7, .lut = 0x223357},
382         {.fl = 8, .lut = 0x2223357},
383         {.fl = 9, .lut = 0x22223357},
384         {.fl = 10, .lut = 0x222223357},
385         {.fl = 11, .lut = 0x2222223357},
386         {.fl = 12, .lut = 0x22222223357},
387         {.fl = 13, .lut = 0x222222223357},
388         {.fl = 14, .lut = 0x1222222223357},
389         {.fl = 0, .lut = 0x11222222223357}
390 };
391
392 static struct dpu_qos_lut_entry sdm845_qos_macrotile[] = {
393         {.fl = 10, .lut = 0x344556677},
394         {.fl = 11, .lut = 0x3344556677},
395         {.fl = 12, .lut = 0x23344556677},
396         {.fl = 13, .lut = 0x223344556677},
397         {.fl = 14, .lut = 0x1223344556677},
398         {.fl = 0, .lut = 0x112233344556677},
399 };
400
401 static struct dpu_qos_lut_entry sdm845_qos_nrt[] = {
402         {.fl = 0, .lut = 0x0},
403 };
404
405 static struct dpu_perf_cfg sdm845_perf_data = {
406         .max_bw_low = 6800000,
407         .max_bw_high = 6800000,
408         .min_core_ib = 2400000,
409         .min_llcc_ib = 800000,
410         .min_dram_ib = 800000,
411         .core_ib_ff = "6.0",
412         .core_clk_ff = "1.0",
413         .comp_ratio_rt =
414         "NV12/5/1/1.23 AB24/5/1/1.23 XB24/5/1/1.23",
415         .comp_ratio_nrt =
416         "NV12/5/1/1.25 AB24/5/1/1.25 XB24/5/1/1.25",
417         .undersized_prefill_lines = 2,
418         .xtra_prefill_lines = 2,
419         .dest_scale_prefill_lines = 3,
420         .macrotile_prefill_lines = 4,
421         .yuv_nv12_prefill_lines = 8,
422         .linear_prefill_lines = 1,
423         .downscaling_prefill_lines = 1,
424         .amortizable_threshold = 25,
425         .min_prefill_lines = 24,
426         .danger_lut_tbl = {0xf, 0xffff, 0x0},
427         .qos_lut_tbl = {
428                 {.nentry = ARRAY_SIZE(sdm845_qos_linear),
429                 .entries = sdm845_qos_linear
430                 },
431                 {.nentry = ARRAY_SIZE(sdm845_qos_macrotile),
432                 .entries = sdm845_qos_macrotile
433                 },
434                 {.nentry = ARRAY_SIZE(sdm845_qos_nrt),
435                 .entries = sdm845_qos_nrt
436                 },
437         },
438         .cdp_cfg = {
439                 {.rd_enable = 1, .wr_enable = 1},
440                 {.rd_enable = 1, .wr_enable = 0}
441         },
442 };
443
444 /*************************************************************
445  * Hardware catalog init
446  *************************************************************/
447
448 /*
449  * sdm845_cfg_init(): populate sdm845 dpu sub-blocks reg offsets
450  * and instance counts.
451  */
452 static void sdm845_cfg_init(struct dpu_mdss_cfg *dpu_cfg)
453 {
454         *dpu_cfg = (struct dpu_mdss_cfg){
455                 .caps = &sdm845_dpu_caps,
456                 .mdp_count = ARRAY_SIZE(sdm845_mdp),
457                 .mdp = sdm845_mdp,
458                 .ctl_count = ARRAY_SIZE(sdm845_ctl),
459                 .ctl = sdm845_ctl,
460                 .sspp_count = ARRAY_SIZE(sdm845_sspp),
461                 .sspp = sdm845_sspp,
462                 .mixer_count = ARRAY_SIZE(sdm845_lm),
463                 .mixer = sdm845_lm,
464                 .ds_count = ARRAY_SIZE(sdm845_ds),
465                 .ds = sdm845_ds,
466                 .pingpong_count = ARRAY_SIZE(sdm845_pp),
467                 .pingpong = sdm845_pp,
468                 .cdm_count = ARRAY_SIZE(sdm845_cdm),
469                 .cdm = sdm845_cdm,
470                 .intf_count = ARRAY_SIZE(sdm845_intf),
471                 .intf = sdm845_intf,
472                 .vbif_count = ARRAY_SIZE(sdm845_vbif),
473                 .vbif = sdm845_vbif,
474                 .reg_dma_count = 1,
475                 .dma_cfg = sdm845_regdma,
476                 .perf = sdm845_perf_data,
477         };
478 }
479
480 static struct dpu_mdss_hw_cfg_handler cfg_handler[] = {
481         { .hw_rev = DPU_HW_VER_400, .cfg_init = sdm845_cfg_init},
482         { .hw_rev = DPU_HW_VER_401, .cfg_init = sdm845_cfg_init},
483 };
484
485 void dpu_hw_catalog_deinit(struct dpu_mdss_cfg *dpu_cfg)
486 {
487         kfree(dpu_cfg);
488 }
489
490 struct dpu_mdss_cfg *dpu_hw_catalog_init(u32 hw_rev)
491 {
492         int i;
493         struct dpu_mdss_cfg *dpu_cfg;
494
495         dpu_cfg = kzalloc(sizeof(*dpu_cfg), GFP_KERNEL);
496         if (!dpu_cfg)
497                 return ERR_PTR(-ENOMEM);
498
499         for (i = 0; i < ARRAY_SIZE(cfg_handler); i++) {
500                 if (cfg_handler[i].hw_rev == hw_rev) {
501                         cfg_handler[i].cfg_init(dpu_cfg);
502                         dpu_cfg->hwversion = hw_rev;
503                         return dpu_cfg;
504                 }
505         }
506
507         DPU_ERROR("unsupported chipset id:%X\n", hw_rev);
508         dpu_hw_catalog_deinit(dpu_cfg);
509         return ERR_PTR(-ENODEV);
510 }
511