blob: 9f1b6cb8d41f1f1b3d583e1f30463ee1d03a2da8 [file] [log] [blame]
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
Narendra Muppalla1b0b3352015-09-29 10:16:51 -07002 *
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
Dhaval Patel8bf7ff32016-07-20 18:13:24 -070013#define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__
14#include <linux/slab.h>
15#include <linux/of_address.h>
Alan Kwong4dd64c82017-02-04 18:41:51 -080016#include <linux/platform_device.h>
17#include <linux/soc/qcom/llcc-qcom.h>
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070018
Dhaval Patel8bf7ff32016-07-20 18:13:24 -070019#include "sde_hw_mdss.h"
20#include "sde_hw_catalog.h"
21#include "sde_hw_catalog_format.h"
22#include "sde_kms.h"
23
24/*************************************************************
25 * MACRO DEFINITION
26 *************************************************************/
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070027
28/**
Dhaval Patel8bf7ff32016-07-20 18:13:24 -070029 * Max hardware block in certain hardware. For ex: sspp pipes
30 * can have QSEED, pcc, igc, pa, csc, etc. This count is max
31 * 12 based on software design. It should be increased if any of the
32 * hardware block has more subblocks.
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070033 */
Dhaval Patel8bf7ff32016-07-20 18:13:24 -070034#define MAX_SDE_HW_BLK 12
35
36/* each entry will have register address and bit offset in that register */
37#define MAX_BIT_OFFSET 2
38
39/* default line width for sspp */
40#define DEFAULT_SDE_LINE_WIDTH 2048
41
42/* max mixer blend stages */
43#define DEFAULT_SDE_MIXER_BLENDSTAGES 7
44
45/* max bank bit for macro tile and ubwc format */
46#define DEFAULT_SDE_HIGHEST_BANK_BIT 15
47
Clarence Ip32bcb002017-03-13 12:26:44 -070048/* default ubwc version */
49#define DEFAULT_SDE_UBWC_VERSION SDE_HW_UBWC_VER_10
50
51/* default ubwc static config register value */
52#define DEFAULT_SDE_UBWC_STATIC 0x0
53
54/* default ubwc swizzle register value */
55#define DEFAULT_SDE_UBWC_SWIZZLE 0x0
56
Dhaval Patel8bf7ff32016-07-20 18:13:24 -070057/* default hardware block size if dtsi entry is not present */
58#define DEFAULT_SDE_HW_BLOCK_LEN 0x100
59
Dhaval Patel8bf7ff32016-07-20 18:13:24 -070060/* total number of intf - dp, dsi, hdmi */
61#define INTF_COUNT 3
62
63#define MAX_SSPP_UPSCALE 20
64#define MAX_SSPP_DOWNSCALE 4
65#define SSPP_UNITY_SCALE 1
66
67#define MAX_HORZ_DECIMATION 4
68#define MAX_VERT_DECIMATION 4
69
70#define MAX_SPLIT_DISPLAY_CTL 2
71#define MAX_PP_SPLIT_DISPLAY_CTL 1
72
73#define MDSS_BASE_OFFSET 0x0
74
75#define ROT_LM_OFFSET 3
76#define LINE_LM_OFFSET 5
77#define LINE_MODE_WB_OFFSET 2
78
Alan Kwongb9d2f6f2016-10-12 00:27:07 -040079/* maximum XIN halt timeout in usec */
80#define VBIF_XIN_HALT_TIMEOUT 0x4000
81
Alan Kwong41b099e2016-10-12 17:10:11 -040082#define DEFAULT_PIXEL_RAM_SIZE (50 * 1024)
83
Clarence Ip613fd8a2016-11-29 19:01:39 -050084/* access property value based on prop_type and hardware index */
85#define PROP_VALUE_ACCESS(p, i, j) ((p + i)->value[j])
86
87/*
88 * access element within PROP_TYPE_BIT_OFFSET_ARRAYs based on prop_type,
89 * hardware index and offset array index
90 */
91#define PROP_BITVALUE_ACCESS(p, i, j, k) ((p + i)->bit_value[j][k])
Benet Clark37809e62016-10-24 10:14:00 -070092
Alan Kwong4dd64c82017-02-04 18:41:51 -080093#define DEFAULT_SBUF_HEADROOM (20)
94
Alan Kwong6259a382017-04-04 06:18:02 -070095/*
96 * Default parameter values
97 */
98#define DEFAULT_MAX_BW_HIGH 7000000
99#define DEFAULT_MAX_BW_LOW 7000000
100#define DEFAULT_UNDERSIZED_PREFILL_LINES 2
101#define DEFAULT_XTRA_PREFILL_LINES 2
102#define DEFAULT_DEST_SCALE_PREFILL_LINES 3
103#define DEFAULT_MACROTILE_PREFILL_LINES 4
104#define DEFAULT_YUV_NV12_PREFILL_LINES 8
105#define DEFAULT_LINEAR_PREFILL_LINES 1
106#define DEFAULT_DOWNSCALING_PREFILL_LINES 1
107#define DEFAULT_CORE_IB_FF "6.0"
108#define DEFAULT_CORE_CLK_FF "1.0"
109#define DEFAULT_COMP_RATIO_RT \
110 "NV12/5/1/1.23 AB24/5/1/1.23 XB24/5/1/1.23"
111#define DEFAULT_COMP_RATIO_NRT \
112 "NV12/5/1/1.25 AB24/5/1/1.25 XB24/5/1/1.25"
113#define DEFAULT_MAX_PER_PIPE_BW 2400000
114#define DEFAULT_AMORTIZABLE_THRESHOLD 25
115
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700116/*************************************************************
117 * DTSI PROPERTY INDEX
118 *************************************************************/
119enum {
120 HW_OFF,
121 HW_LEN,
Benet Clark37809e62016-10-24 10:14:00 -0700122 HW_PROP_MAX,
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700123};
124
125enum sde_prop {
126 SDE_OFF,
127 SDE_LEN,
128 SSPP_LINEWIDTH,
129 MIXER_LINEWIDTH,
130 MIXER_BLEND,
131 WB_LINEWIDTH,
132 BANK_BIT,
Clarence Ip32bcb002017-03-13 12:26:44 -0700133 UBWC_VERSION,
134 UBWC_STATIC,
135 UBWC_SWIZZLE,
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700136 QSEED_TYPE,
Dhaval Patel5aad7452017-01-12 09:59:31 -0800137 CSC_TYPE,
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700138 PANIC_PER_PIPE,
139 CDP,
Dhaval Patel1964fb92016-10-13 19:28:08 -0700140 SRC_SPLIT,
Veera Sundaram Sankaran3171ff82017-01-04 14:34:47 -0800141 DIM_LAYER,
Jeykumar Sankaran2e655032017-02-04 14:05:45 -0800142 SMART_DMA_REV,
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700143 IDLE_PC,
Benet Clark37809e62016-10-24 10:14:00 -0700144 SDE_PROP_MAX,
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700145};
146
147enum {
Alan Kwong9aa061c2016-11-06 21:17:12 -0500148 PERF_MAX_BW_LOW,
149 PERF_MAX_BW_HIGH,
Alan Kwong6259a382017-04-04 06:18:02 -0700150 PERF_CORE_IB_FF,
151 PERF_CORE_CLK_FF,
152 PERF_COMP_RATIO_RT,
153 PERF_COMP_RATIO_NRT,
154 PERF_UNDERSIZED_PREFILL_LINES,
155 PERF_DEST_SCALE_PREFILL_LINES,
156 PERF_MACROTILE_PREFILL_LINES,
157 PERF_YUV_NV12_PREFILL_LINES,
158 PERF_LINEAR_PREFILL_LINES,
159 PERF_DOWNSCALING_PREFILL_LINES,
160 PERF_XTRA_PREFILL_LINES,
161 PERF_AMORTIZABLE_THRESHOLD,
Alan Kwongdce56da2017-04-27 15:50:34 -0700162 PERF_DANGER_LUT,
163 PERF_SAFE_LUT,
164 PERF_QOS_LUT_LINEAR,
165 PERF_QOS_LUT_MACROTILE,
166 PERF_QOS_LUT_NRT,
167 PERF_QOS_LUT_CWB,
Alan Kwong9aa061c2016-11-06 21:17:12 -0500168 PERF_PROP_MAX,
169};
170
171enum {
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700172 SSPP_OFF,
173 SSPP_SIZE,
174 SSPP_TYPE,
175 SSPP_XIN,
176 SSPP_CLK_CTRL,
177 SSPP_CLK_STATUS,
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700178 SSPP_SCALE_SIZE,
Benet Clark37809e62016-10-24 10:14:00 -0700179 SSPP_VIG_BLOCKS,
180 SSPP_RGB_BLOCKS,
Veera Sundaram Sankaran02dd6ac2016-12-22 15:08:29 -0800181 SSPP_EXCL_RECT,
Jeykumar Sankaran2e655032017-02-04 14:05:45 -0800182 SSPP_SMART_DMA,
Alan Kwong6259a382017-04-04 06:18:02 -0700183 SSPP_MAX_PER_PIPE_BW,
Benet Clark37809e62016-10-24 10:14:00 -0700184 SSPP_PROP_MAX,
185};
186
187enum {
188 VIG_QSEED_OFF,
Lloyd Atkinson77158732016-10-23 13:02:00 -0400189 VIG_QSEED_LEN,
Benet Clark37809e62016-10-24 10:14:00 -0700190 VIG_CSC_OFF,
191 VIG_HSIC_PROP,
192 VIG_MEMCOLOR_PROP,
193 VIG_PCC_PROP,
194 VIG_PROP_MAX,
195};
196
197enum {
198 RGB_SCALER_OFF,
Lloyd Atkinson77158732016-10-23 13:02:00 -0400199 RGB_SCALER_LEN,
Benet Clark37809e62016-10-24 10:14:00 -0700200 RGB_PCC_PROP,
201 RGB_PROP_MAX,
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700202};
203
204enum {
205 INTF_OFF,
206 INTF_LEN,
207 INTF_PREFETCH,
208 INTF_TYPE,
Benet Clark37809e62016-10-24 10:14:00 -0700209 INTF_PROP_MAX,
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700210};
211
212enum {
213 PP_OFF,
214 PP_LEN,
215 TE_OFF,
216 TE_LEN,
217 TE2_OFF,
218 TE2_LEN,
Clarence Ip8e69ad02016-12-09 09:43:57 -0500219 PP_SLAVE,
Benet Clark37809e62016-10-24 10:14:00 -0700220 PP_PROP_MAX,
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700221};
222
223enum {
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800224 DSC_OFF,
225 DSC_LEN,
226 DSC_PROP_MAX,
227};
228
229enum {
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700230 DSPP_OFF,
231 DSPP_SIZE,
Benet Clark37809e62016-10-24 10:14:00 -0700232 DSPP_BLOCKS,
233 DSPP_PROP_MAX,
234};
235
236enum {
237 DSPP_IGC_PROP,
238 DSPP_PCC_PROP,
239 DSPP_GC_PROP,
240 DSPP_HSIC_PROP,
241 DSPP_MEMCOLOR_PROP,
242 DSPP_SIXZONE_PROP,
243 DSPP_GAMUT_PROP,
244 DSPP_DITHER_PROP,
245 DSPP_HIST_PROP,
246 DSPP_VLUT_PROP,
247 DSPP_BLOCKS_PROP_MAX,
248};
249
250enum {
251 AD_OFF,
252 AD_VERSION,
253 AD_PROP_MAX,
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700254};
255
256enum {
257 MIXER_OFF,
258 MIXER_LEN,
Veera Sundaram Sankaran370b9912017-01-10 18:03:42 -0800259 MIXER_PAIR_MASK,
Benet Clark37809e62016-10-24 10:14:00 -0700260 MIXER_BLOCKS,
261 MIXER_PROP_MAX,
262};
263
264enum {
265 MIXER_GC_PROP,
266 MIXER_BLOCKS_PROP_MAX,
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700267};
268
269enum {
Veera Sundaram Sankaran370b9912017-01-10 18:03:42 -0800270 MIXER_BLEND_OP_OFF,
271 MIXER_BLEND_PROP_MAX,
272};
273
274enum {
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700275 WB_OFF,
276 WB_LEN,
Alan Kwong14627332016-10-12 16:44:00 -0400277 WB_ID,
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700278 WB_XIN_ID,
Alan Kwong04780ec2016-10-12 16:05:17 -0400279 WB_CLK_CTRL,
Benet Clark37809e62016-10-24 10:14:00 -0700280 WB_PROP_MAX,
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700281};
282
Alan Kwongb9d2f6f2016-10-12 00:27:07 -0400283enum {
284 VBIF_OFF,
285 VBIF_LEN,
286 VBIF_ID,
287 VBIF_DEFAULT_OT_RD_LIMIT,
288 VBIF_DEFAULT_OT_WR_LIMIT,
289 VBIF_DYNAMIC_OT_RD_LIMIT,
290 VBIF_DYNAMIC_OT_WR_LIMIT,
Alan Kwonga62eeb82017-04-19 08:57:55 -0700291 VBIF_QOS_RT_REMAP,
292 VBIF_QOS_NRT_REMAP,
Benet Clark37809e62016-10-24 10:14:00 -0700293 VBIF_PROP_MAX,
Alan Kwongb9d2f6f2016-10-12 00:27:07 -0400294};
295
Gopikrishnaiah Anandan031d8ff2016-12-15 16:58:45 -0800296enum {
297 REG_DMA_OFF,
298 REG_DMA_VERSION,
299 REG_DMA_TRIGGER_OFF,
300 REG_DMA_PROP_MAX
301};
302
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700303/*************************************************************
304 * dts property definition
305 *************************************************************/
306enum prop_type {
307 PROP_TYPE_BOOL,
308 PROP_TYPE_U32,
309 PROP_TYPE_U32_ARRAY,
310 PROP_TYPE_STRING,
311 PROP_TYPE_STRING_ARRAY,
312 PROP_TYPE_BIT_OFFSET_ARRAY,
Benet Clark37809e62016-10-24 10:14:00 -0700313 PROP_TYPE_NODE,
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700314};
315
316struct sde_prop_type {
317 /* use property index from enum property for readability purpose */
318 u8 id;
319 /* it should be property name based on dtsi documentation */
320 char *prop_name;
321 /**
322 * if property is marked mandatory then it will fail parsing
323 * when property is not present
324 */
325 u32 is_mandatory;
326 /* property type based on "enum prop_type" */
327 enum prop_type type;
328};
329
Clarence Ip613fd8a2016-11-29 19:01:39 -0500330struct sde_prop_value {
331 u32 value[MAX_SDE_HW_BLK];
332 u32 bit_value[MAX_SDE_HW_BLK][MAX_BIT_OFFSET];
333};
334
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700335/*************************************************************
336 * dts property list
337 *************************************************************/
338static struct sde_prop_type sde_prop[] = {
339 {SDE_OFF, "qcom,sde-off", true, PROP_TYPE_U32},
340 {SDE_LEN, "qcom,sde-len", false, PROP_TYPE_U32},
341 {SSPP_LINEWIDTH, "qcom,sde-sspp-linewidth", false, PROP_TYPE_U32},
342 {MIXER_LINEWIDTH, "qcom,sde-mixer-linewidth", false, PROP_TYPE_U32},
343 {MIXER_BLEND, "qcom,sde-mixer-blendstages", false, PROP_TYPE_U32},
344 {WB_LINEWIDTH, "qcom,sde-wb-linewidth", false, PROP_TYPE_U32},
345 {BANK_BIT, "qcom,sde-highest-bank-bit", false, PROP_TYPE_U32},
Clarence Ip32bcb002017-03-13 12:26:44 -0700346 {UBWC_VERSION, "qcom,sde-ubwc-version", false, PROP_TYPE_U32},
347 {UBWC_STATIC, "qcom,sde-ubwc-static", false, PROP_TYPE_U32},
348 {UBWC_SWIZZLE, "qcom,sde-ubwc-swizzle", false, PROP_TYPE_U32},
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700349 {QSEED_TYPE, "qcom,sde-qseed-type", false, PROP_TYPE_STRING},
Dhaval Patel5aad7452017-01-12 09:59:31 -0800350 {CSC_TYPE, "qcom,sde-csc-type", false, PROP_TYPE_STRING},
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700351 {PANIC_PER_PIPE, "qcom,sde-panic-per-pipe", false, PROP_TYPE_BOOL},
352 {CDP, "qcom,sde-has-cdp", false, PROP_TYPE_BOOL},
Dhaval Patel1964fb92016-10-13 19:28:08 -0700353 {SRC_SPLIT, "qcom,sde-has-src-split", false, PROP_TYPE_BOOL},
Veera Sundaram Sankaran3171ff82017-01-04 14:34:47 -0800354 {DIM_LAYER, "qcom,sde-has-dim-layer", false, PROP_TYPE_BOOL},
Jeykumar Sankaran2e655032017-02-04 14:05:45 -0800355 {SMART_DMA_REV, "qcom,sde-smart-dma-rev", false, PROP_TYPE_STRING},
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700356 {IDLE_PC, "qcom,sde-has-idle-pc", false, PROP_TYPE_BOOL},
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700357};
358
Alan Kwong9aa061c2016-11-06 21:17:12 -0500359static struct sde_prop_type sde_perf_prop[] = {
360 {PERF_MAX_BW_LOW, "qcom,sde-max-bw-low-kbps", false, PROP_TYPE_U32},
361 {PERF_MAX_BW_HIGH, "qcom,sde-max-bw-high-kbps", false, PROP_TYPE_U32},
Alan Kwong6259a382017-04-04 06:18:02 -0700362 {PERF_CORE_IB_FF, "qcom,sde-core-ib-ff", false, PROP_TYPE_STRING},
363 {PERF_CORE_CLK_FF, "qcom,sde-core-clk-ff", false, PROP_TYPE_STRING},
364 {PERF_COMP_RATIO_RT, "qcom,sde-comp-ratio-rt", false,
365 PROP_TYPE_STRING},
366 {PERF_COMP_RATIO_NRT, "qcom,sde-comp-ratio-nrt", false,
367 PROP_TYPE_STRING},
368 {PERF_UNDERSIZED_PREFILL_LINES, "qcom,sde-undersizedprefill-lines",
369 false, PROP_TYPE_U32},
370 {PERF_DEST_SCALE_PREFILL_LINES, "qcom,sde-dest-scaleprefill-lines",
371 false, PROP_TYPE_U32},
372 {PERF_MACROTILE_PREFILL_LINES, "qcom,sde-macrotileprefill-lines",
373 false, PROP_TYPE_U32},
374 {PERF_YUV_NV12_PREFILL_LINES, "qcom,sde-yuv-nv12prefill-lines",
375 false, PROP_TYPE_U32},
376 {PERF_LINEAR_PREFILL_LINES, "qcom,sde-linearprefill-lines",
377 false, PROP_TYPE_U32},
378 {PERF_DOWNSCALING_PREFILL_LINES, "qcom,sde-downscalingprefill-lines",
379 false, PROP_TYPE_U32},
380 {PERF_XTRA_PREFILL_LINES, "qcom,sde-xtra-prefill-lines",
381 false, PROP_TYPE_U32},
382 {PERF_AMORTIZABLE_THRESHOLD, "qcom,sde-amortizable-threshold",
383 false, PROP_TYPE_U32},
Alan Kwongdce56da2017-04-27 15:50:34 -0700384 {PERF_DANGER_LUT, "qcom,sde-danger-lut", false, PROP_TYPE_U32_ARRAY},
385 {PERF_SAFE_LUT, "qcom,sde-safe-lut", false, PROP_TYPE_U32_ARRAY},
386 {PERF_QOS_LUT_LINEAR, "qcom,sde-qos-lut-linear", false,
387 PROP_TYPE_U32_ARRAY},
388 {PERF_QOS_LUT_MACROTILE, "qcom,sde-qos-lut-macrotile", false,
389 PROP_TYPE_U32_ARRAY},
390 {PERF_QOS_LUT_NRT, "qcom,sde-qos-lut-nrt", false,
391 PROP_TYPE_U32_ARRAY},
392 {PERF_QOS_LUT_CWB, "qcom,sde-qos-lut-cwb", false,
393 PROP_TYPE_U32_ARRAY},
Alan Kwong9aa061c2016-11-06 21:17:12 -0500394};
395
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700396static struct sde_prop_type sspp_prop[] = {
397 {SSPP_OFF, "qcom,sde-sspp-off", true, PROP_TYPE_U32_ARRAY},
398 {SSPP_SIZE, "qcom,sde-sspp-src-size", false, PROP_TYPE_U32},
399 {SSPP_TYPE, "qcom,sde-sspp-type", true, PROP_TYPE_STRING_ARRAY},
400 {SSPP_XIN, "qcom,sde-sspp-xin-id", true, PROP_TYPE_U32_ARRAY},
401 {SSPP_CLK_CTRL, "qcom,sde-sspp-clk-ctrl", false,
402 PROP_TYPE_BIT_OFFSET_ARRAY},
403 {SSPP_CLK_STATUS, "qcom,sde-sspp-clk-status", false,
404 PROP_TYPE_BIT_OFFSET_ARRAY},
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700405 {SSPP_SCALE_SIZE, "qcom,sde-sspp-scale-size", false, PROP_TYPE_U32},
Benet Clark37809e62016-10-24 10:14:00 -0700406 {SSPP_VIG_BLOCKS, "qcom,sde-sspp-vig-blocks", false, PROP_TYPE_NODE},
407 {SSPP_RGB_BLOCKS, "qcom,sde-sspp-rgb-blocks", false, PROP_TYPE_NODE},
Veera Sundaram Sankaran02dd6ac2016-12-22 15:08:29 -0800408 {SSPP_EXCL_RECT, "qcom,sde-sspp-excl-rect", false, PROP_TYPE_U32_ARRAY},
Jeykumar Sankaran2e655032017-02-04 14:05:45 -0800409 {SSPP_SMART_DMA, "qcom,sde-sspp-smart-dma-priority", false,
410 PROP_TYPE_U32_ARRAY},
Alan Kwong6259a382017-04-04 06:18:02 -0700411 {SSPP_MAX_PER_PIPE_BW, "qcom,sde-max-per-pipe-bw-kbps", false,
412 PROP_TYPE_U32_ARRAY},
Benet Clark37809e62016-10-24 10:14:00 -0700413};
414
415static struct sde_prop_type vig_prop[] = {
416 {VIG_QSEED_OFF, "qcom,sde-vig-qseed-off", false, PROP_TYPE_U32},
Lloyd Atkinson77158732016-10-23 13:02:00 -0400417 {VIG_QSEED_LEN, "qcom,sde-vig-qseed-size", false, PROP_TYPE_U32},
Benet Clark37809e62016-10-24 10:14:00 -0700418 {VIG_CSC_OFF, "qcom,sde-vig-csc-off", false, PROP_TYPE_U32},
419 {VIG_HSIC_PROP, "qcom,sde-vig-hsic", false, PROP_TYPE_U32_ARRAY},
420 {VIG_MEMCOLOR_PROP, "qcom,sde-vig-memcolor", false,
421 PROP_TYPE_U32_ARRAY},
422 {VIG_PCC_PROP, "qcom,sde-vig-pcc", false, PROP_TYPE_U32_ARRAY},
423};
424
425static struct sde_prop_type rgb_prop[] = {
426 {RGB_SCALER_OFF, "qcom,sde-rgb-scaler-off", false, PROP_TYPE_U32},
Lloyd Atkinson77158732016-10-23 13:02:00 -0400427 {RGB_SCALER_LEN, "qcom,sde-rgb-scaler-size", false, PROP_TYPE_U32},
Benet Clark37809e62016-10-24 10:14:00 -0700428 {RGB_PCC_PROP, "qcom,sde-rgb-pcc", false, PROP_TYPE_U32_ARRAY},
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700429};
430
431static struct sde_prop_type ctl_prop[] = {
432 {HW_OFF, "qcom,sde-ctl-off", true, PROP_TYPE_U32_ARRAY},
433 {HW_LEN, "qcom,sde-ctl-size", false, PROP_TYPE_U32},
434};
435
Veera Sundaram Sankaran370b9912017-01-10 18:03:42 -0800436struct sde_prop_type mixer_blend_prop[] = {
437 {MIXER_BLEND_OP_OFF, "qcom,sde-mixer-blend-op-off", true,
438 PROP_TYPE_U32_ARRAY},
439};
440
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700441static struct sde_prop_type mixer_prop[] = {
442 {MIXER_OFF, "qcom,sde-mixer-off", true, PROP_TYPE_U32_ARRAY},
443 {MIXER_LEN, "qcom,sde-mixer-size", false, PROP_TYPE_U32},
Veera Sundaram Sankaran370b9912017-01-10 18:03:42 -0800444 {MIXER_PAIR_MASK, "qcom,sde-mixer-pair-mask", true,
445 PROP_TYPE_U32_ARRAY},
Benet Clark37809e62016-10-24 10:14:00 -0700446 {MIXER_BLOCKS, "qcom,sde-mixer-blocks", false, PROP_TYPE_NODE},
447};
448
449static struct sde_prop_type mixer_blocks_prop[] = {
450 {MIXER_GC_PROP, "qcom,sde-mixer-gc", false, PROP_TYPE_U32_ARRAY},
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700451};
452
453static struct sde_prop_type dspp_prop[] = {
454 {DSPP_OFF, "qcom,sde-dspp-off", true, PROP_TYPE_U32_ARRAY},
455 {DSPP_SIZE, "qcom,sde-dspp-size", false, PROP_TYPE_U32},
Benet Clark37809e62016-10-24 10:14:00 -0700456 {DSPP_BLOCKS, "qcom,sde-dspp-blocks", false, PROP_TYPE_NODE},
457};
458
459static struct sde_prop_type dspp_blocks_prop[] = {
460 {DSPP_IGC_PROP, "qcom,sde-dspp-igc", false, PROP_TYPE_U32_ARRAY},
461 {DSPP_PCC_PROP, "qcom,sde-dspp-pcc", false, PROP_TYPE_U32_ARRAY},
462 {DSPP_GC_PROP, "qcom,sde-dspp-gc", false, PROP_TYPE_U32_ARRAY},
463 {DSPP_HSIC_PROP, "qcom,sde-dspp-hsic", false, PROP_TYPE_U32_ARRAY},
464 {DSPP_MEMCOLOR_PROP, "qcom,sde-dspp-memcolor", false,
465 PROP_TYPE_U32_ARRAY},
466 {DSPP_SIXZONE_PROP, "qcom,sde-dspp-sixzone", false,
467 PROP_TYPE_U32_ARRAY},
468 {DSPP_GAMUT_PROP, "qcom,sde-dspp-gamut", false, PROP_TYPE_U32_ARRAY},
469 {DSPP_DITHER_PROP, "qcom,sde-dspp-dither", false, PROP_TYPE_U32_ARRAY},
470 {DSPP_HIST_PROP, "qcom,sde-dspp-hist", false, PROP_TYPE_U32_ARRAY},
471 {DSPP_VLUT_PROP, "qcom,sde-dspp-vlut", false, PROP_TYPE_U32_ARRAY},
472};
473
474static struct sde_prop_type ad_prop[] = {
475 {AD_OFF, "qcom,sde-dspp-ad-off", false, PROP_TYPE_U32_ARRAY},
476 {AD_VERSION, "qcom,sde-dspp-ad-version", false, PROP_TYPE_U32},
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700477};
478
479static struct sde_prop_type pp_prop[] = {
480 {PP_OFF, "qcom,sde-pp-off", true, PROP_TYPE_U32_ARRAY},
481 {PP_LEN, "qcom,sde-pp-size", false, PROP_TYPE_U32},
482 {TE_OFF, "qcom,sde-te-off", false, PROP_TYPE_U32_ARRAY},
483 {TE_LEN, "qcom,sde-te-size", false, PROP_TYPE_U32},
484 {TE2_OFF, "qcom,sde-te2-off", false, PROP_TYPE_U32_ARRAY},
485 {TE2_LEN, "qcom,sde-te2-size", false, PROP_TYPE_U32},
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800486 {PP_SLAVE, "qcom,sde-pp-slave", false, PROP_TYPE_U32_ARRAY},
487};
488
489static struct sde_prop_type dsc_prop[] = {
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700490 {DSC_OFF, "qcom,sde-dsc-off", false, PROP_TYPE_U32_ARRAY},
491 {DSC_LEN, "qcom,sde-dsc-size", false, PROP_TYPE_U32},
492};
493
494static struct sde_prop_type cdm_prop[] = {
495 {HW_OFF, "qcom,sde-cdm-off", false, PROP_TYPE_U32_ARRAY},
496 {HW_LEN, "qcom,sde-cdm-size", false, PROP_TYPE_U32},
497};
498
499static struct sde_prop_type intf_prop[] = {
500 {INTF_OFF, "qcom,sde-intf-off", true, PROP_TYPE_U32_ARRAY},
501 {INTF_LEN, "qcom,sde-intf-size", false, PROP_TYPE_U32},
502 {INTF_PREFETCH, "qcom,sde-intf-max-prefetch-lines", false,
503 PROP_TYPE_U32_ARRAY},
504 {INTF_TYPE, "qcom,sde-intf-type", false, PROP_TYPE_STRING_ARRAY},
505};
506
507static struct sde_prop_type wb_prop[] = {
508 {WB_OFF, "qcom,sde-wb-off", true, PROP_TYPE_U32_ARRAY},
509 {WB_LEN, "qcom,sde-wb-size", false, PROP_TYPE_U32},
Alan Kwong14627332016-10-12 16:44:00 -0400510 {WB_ID, "qcom,sde-wb-id", true, PROP_TYPE_U32_ARRAY},
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700511 {WB_XIN_ID, "qcom,sde-wb-xin-id", false, PROP_TYPE_U32_ARRAY},
Alan Kwong04780ec2016-10-12 16:05:17 -0400512 {WB_CLK_CTRL, "qcom,sde-wb-clk-ctrl", false,
513 PROP_TYPE_BIT_OFFSET_ARRAY},
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700514};
515
Alan Kwongb9d2f6f2016-10-12 00:27:07 -0400516static struct sde_prop_type vbif_prop[] = {
517 {VBIF_OFF, "qcom,sde-vbif-off", true, PROP_TYPE_U32_ARRAY},
518 {VBIF_LEN, "qcom,sde-vbif-size", false, PROP_TYPE_U32},
519 {VBIF_ID, "qcom,sde-vbif-id", false, PROP_TYPE_U32_ARRAY},
520 {VBIF_DEFAULT_OT_RD_LIMIT, "qcom,sde-vbif-default-ot-rd-limit", false,
521 PROP_TYPE_U32},
522 {VBIF_DEFAULT_OT_WR_LIMIT, "qcom,sde-vbif-default-ot-wr-limit", false,
523 PROP_TYPE_U32},
524 {VBIF_DYNAMIC_OT_RD_LIMIT, "qcom,sde-vbif-dynamic-ot-rd-limit", false,
525 PROP_TYPE_U32_ARRAY},
526 {VBIF_DYNAMIC_OT_WR_LIMIT, "qcom,sde-vbif-dynamic-ot-wr-limit", false,
527 PROP_TYPE_U32_ARRAY},
Alan Kwonga62eeb82017-04-19 08:57:55 -0700528 {VBIF_QOS_RT_REMAP, "qcom,sde-vbif-qos-rt-remap", false,
529 PROP_TYPE_U32_ARRAY},
530 {VBIF_QOS_NRT_REMAP, "qcom,sde-vbif-qos-nrt-remap", false,
531 PROP_TYPE_U32_ARRAY},
Alan Kwongb9d2f6f2016-10-12 00:27:07 -0400532};
533
Gopikrishnaiah Anandan031d8ff2016-12-15 16:58:45 -0800534static struct sde_prop_type reg_dma_prop[REG_DMA_PROP_MAX] = {
535 [REG_DMA_OFF] = {REG_DMA_OFF, "qcom,sde-reg-dma-off", false,
536 PROP_TYPE_U32},
537 [REG_DMA_VERSION] = {REG_DMA_VERSION, "qcom,sde-reg-dma-version",
538 false, PROP_TYPE_U32},
539 [REG_DMA_TRIGGER_OFF] = {REG_DMA_TRIGGER_OFF,
540 "qcom,sde-reg-dma-trigger-off", false,
541 PROP_TYPE_U32},
542};
543
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700544/*************************************************************
545 * static API list
546 *************************************************************/
abeykunf35ff332016-12-20 13:06:09 -0500547
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700548static int _parse_dt_u32_handler(struct device_node *np,
549 char *prop_name, u32 *offsets, int len, bool mandatory)
550{
551 int rc = of_property_read_u32_array(np, prop_name, offsets, len);
552
553 if (rc && mandatory)
554 SDE_ERROR("mandatory prop: %s u32 array read len:%d\n",
555 prop_name, len);
556 else if (rc)
557 SDE_DEBUG("optional prop: %s u32 array read len:%d\n",
558 prop_name, len);
559
560 return rc;
561}
562
563static int _parse_dt_bit_offset(struct device_node *np,
Clarence Ip613fd8a2016-11-29 19:01:39 -0500564 char *prop_name, struct sde_prop_value *prop_value, u32 prop_index,
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700565 u32 count, bool mandatory)
566{
567 int rc = 0, len, i, j;
568 const u32 *arr;
569
570 arr = of_get_property(np, prop_name, &len);
571 if (arr) {
572 len /= sizeof(u32);
Clarence Ip613fd8a2016-11-29 19:01:39 -0500573 len &= ~0x1;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700574 for (i = 0, j = 0; i < len; j++) {
Clarence Ip613fd8a2016-11-29 19:01:39 -0500575 PROP_BITVALUE_ACCESS(prop_value, prop_index, j, 0) =
576 be32_to_cpu(arr[i]);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700577 i++;
Clarence Ip613fd8a2016-11-29 19:01:39 -0500578 PROP_BITVALUE_ACCESS(prop_value, prop_index, j, 1) =
579 be32_to_cpu(arr[i]);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700580 i++;
581 }
582 } else {
583 if (mandatory) {
584 SDE_ERROR("error mandatory property '%s' not found\n",
585 prop_name);
586 rc = -EINVAL;
587 } else {
588 SDE_DEBUG("error optional property '%s' not found\n",
589 prop_name);
590 }
591 }
592
593 return rc;
594}
595
596static int _validate_dt_entry(struct device_node *np,
597 struct sde_prop_type *sde_prop, u32 prop_size, int *prop_count,
598 int *off_count)
599{
600 int rc = 0, i, val;
Benet Clark37809e62016-10-24 10:14:00 -0700601 struct device_node *snp = NULL;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700602
Benet Clark37809e62016-10-24 10:14:00 -0700603 if (off_count) {
604 *off_count = of_property_count_u32_elems(np,
605 sde_prop[0].prop_name);
606 if ((*off_count > MAX_BLOCKS) || (*off_count < 0)) {
607 if (sde_prop[0].is_mandatory) {
608 SDE_ERROR("invalid hw offset prop name:%s\"\
609 count: %d\n",
Alan Kwong15cfbf92016-10-27 21:10:54 -0400610 sde_prop[0].prop_name, *off_count);
Benet Clark37809e62016-10-24 10:14:00 -0700611 rc = -EINVAL;
612 }
613 *off_count = 0;
Alan Kwongcbac0b32017-04-21 13:14:33 -0700614 memset(prop_count, 0, sizeof(int) * prop_size);
Benet Clark37809e62016-10-24 10:14:00 -0700615 return rc;
Alan Kwong15cfbf92016-10-27 21:10:54 -0400616 }
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700617 }
618
Clarence Ip613fd8a2016-11-29 19:01:39 -0500619 for (i = 0; i < prop_size; i++) {
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700620 switch (sde_prop[i].type) {
621 case PROP_TYPE_U32:
622 rc = of_property_read_u32(np, sde_prop[i].prop_name,
623 &val);
624 break;
625 case PROP_TYPE_U32_ARRAY:
626 prop_count[i] = of_property_count_u32_elems(np,
627 sde_prop[i].prop_name);
Benet Clark37809e62016-10-24 10:14:00 -0700628 if (prop_count[i] < 0)
629 rc = prop_count[i];
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700630 break;
631 case PROP_TYPE_STRING_ARRAY:
632 prop_count[i] = of_property_count_strings(np,
633 sde_prop[i].prop_name);
Benet Clark37809e62016-10-24 10:14:00 -0700634 if (prop_count[i] < 0)
635 rc = prop_count[i];
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700636 break;
637 case PROP_TYPE_BIT_OFFSET_ARRAY:
638 of_get_property(np, sde_prop[i].prop_name, &val);
639 prop_count[i] = val / (MAX_BIT_OFFSET * sizeof(u32));
640 break;
Benet Clark37809e62016-10-24 10:14:00 -0700641 case PROP_TYPE_NODE:
642 snp = of_get_child_by_name(np,
643 sde_prop[i].prop_name);
644 if (!snp)
645 rc = -EINVAL;
646 break;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700647 default:
648 SDE_DEBUG("invalid property type:%d\n",
649 sde_prop[i].type);
650 break;
651 }
652 SDE_DEBUG("prop id:%d prop name:%s prop type:%d \"\
653 prop_count:%d\n", i, sde_prop[i].prop_name,
654 sde_prop[i].type, prop_count[i]);
655
656 if (rc && sde_prop[i].is_mandatory &&
Benet Clark37809e62016-10-24 10:14:00 -0700657 ((sde_prop[i].type == PROP_TYPE_U32) ||
658 (sde_prop[i].type == PROP_TYPE_NODE))) {
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700659 SDE_ERROR("prop:%s not present\n",
660 sde_prop[i].prop_name);
661 goto end;
662 } else if (sde_prop[i].type == PROP_TYPE_U32 ||
Benet Clark37809e62016-10-24 10:14:00 -0700663 sde_prop[i].type == PROP_TYPE_BOOL ||
664 sde_prop[i].type == PROP_TYPE_NODE) {
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700665 rc = 0;
666 continue;
667 }
668
Benet Clark37809e62016-10-24 10:14:00 -0700669 if (off_count && (prop_count[i] != *off_count) &&
670 sde_prop[i].is_mandatory) {
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700671 SDE_ERROR("prop:%s count:%d is different compared to \"\
672 offset array:%d\n", sde_prop[i].prop_name,
673 prop_count[i], *off_count);
674 rc = -EINVAL;
675 goto end;
Benet Clark37809e62016-10-24 10:14:00 -0700676 } else if (off_count && prop_count[i] != *off_count) {
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700677 SDE_DEBUG("prop:%s count:%d is different compared to \"\
678 offset array:%d\n", sde_prop[i].prop_name,
679 prop_count[i], *off_count);
680 rc = 0;
681 prop_count[i] = 0;
682 }
Dhaval Patel5398f602017-03-25 18:25:18 -0700683 if (prop_count[i] < 0) {
Benet Clark37809e62016-10-24 10:14:00 -0700684 prop_count[i] = 0;
685 if (sde_prop[i].is_mandatory) {
686 SDE_ERROR("prop:%s count:%d is negative\n",
687 sde_prop[i].prop_name, prop_count[i]);
688 rc = -EINVAL;
689 } else {
690 rc = 0;
691 SDE_DEBUG("prop:%s count:%d is negative\n",
692 sde_prop[i].prop_name, prop_count[i]);
693 }
694 }
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700695 }
696
697end:
698 return rc;
699}
700
701static int _read_dt_entry(struct device_node *np,
Benet Clark37809e62016-10-24 10:14:00 -0700702 struct sde_prop_type *sde_prop, u32 prop_size, int *prop_count,
703 bool *prop_exists,
Clarence Ip613fd8a2016-11-29 19:01:39 -0500704 struct sde_prop_value *prop_value)
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700705{
706 int rc = 0, i, j;
707
Clarence Ip613fd8a2016-11-29 19:01:39 -0500708 for (i = 0; i < prop_size; i++) {
Benet Clark37809e62016-10-24 10:14:00 -0700709 prop_exists[i] = true;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700710 switch (sde_prop[i].type) {
711 case PROP_TYPE_U32:
Benet Clark37809e62016-10-24 10:14:00 -0700712 rc = of_property_read_u32(np, sde_prop[i].prop_name,
713 &PROP_VALUE_ACCESS(prop_value, i, 0));
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700714 SDE_DEBUG("prop id:%d prop name:%s prop type:%d \"\
715 value:0x%x\n", i, sde_prop[i].prop_name,
Benet Clark37809e62016-10-24 10:14:00 -0700716 sde_prop[i].type,
717 PROP_VALUE_ACCESS(prop_value, i, 0));
718 if (rc)
719 prop_exists[i] = false;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700720 break;
721 case PROP_TYPE_BOOL:
Benet Clark37809e62016-10-24 10:14:00 -0700722 PROP_VALUE_ACCESS(prop_value, i, 0) =
723 of_property_read_bool(np,
724 sde_prop[i].prop_name);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700725 SDE_DEBUG("prop id:%d prop name:%s prop type:%d \"\
726 value:0x%x\n", i, sde_prop[i].prop_name,
Benet Clark37809e62016-10-24 10:14:00 -0700727 sde_prop[i].type,
728 PROP_VALUE_ACCESS(prop_value, i, 0));
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700729 break;
730 case PROP_TYPE_U32_ARRAY:
731 rc = _parse_dt_u32_handler(np, sde_prop[i].prop_name,
Benet Clark37809e62016-10-24 10:14:00 -0700732 &PROP_VALUE_ACCESS(prop_value, i, 0),
733 prop_count[i], sde_prop[i].is_mandatory);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700734 if (rc && sde_prop[i].is_mandatory) {
735 SDE_ERROR("%s prop validation success but \"\
736 read failed\n", sde_prop[i].prop_name);
Benet Clark37809e62016-10-24 10:14:00 -0700737 prop_exists[i] = false;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700738 goto end;
739 } else {
Benet Clark37809e62016-10-24 10:14:00 -0700740 if (rc)
741 prop_exists[i] = false;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700742 /* only for debug purpose */
743 SDE_DEBUG("prop id:%d prop name:%s prop \"\
744 type:%d", i, sde_prop[i].prop_name,
745 sde_prop[i].type);
746 for (j = 0; j < prop_count[i]; j++)
747 SDE_DEBUG(" value[%d]:0x%x ", j,
Benet Clark37809e62016-10-24 10:14:00 -0700748 PROP_VALUE_ACCESS(prop_value, i,
749 j));
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700750 SDE_DEBUG("\n");
751 }
752 break;
753 case PROP_TYPE_BIT_OFFSET_ARRAY:
754 rc = _parse_dt_bit_offset(np, sde_prop[i].prop_name,
Clarence Ip613fd8a2016-11-29 19:01:39 -0500755 prop_value, i, prop_count[i],
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700756 sde_prop[i].is_mandatory);
757 if (rc && sde_prop[i].is_mandatory) {
758 SDE_ERROR("%s prop validation success but \"\
759 read failed\n", sde_prop[i].prop_name);
Benet Clark37809e62016-10-24 10:14:00 -0700760 prop_exists[i] = false;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700761 goto end;
762 } else {
Benet Clark37809e62016-10-24 10:14:00 -0700763 if (rc)
764 prop_exists[i] = false;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700765 SDE_DEBUG("prop id:%d prop name:%s prop \"\
766 type:%d", i, sde_prop[i].prop_name,
767 sde_prop[i].type);
768 for (j = 0; j < prop_count[i]; j++)
769 SDE_DEBUG(" count[%d]: bit:0x%x \"\
Clarence Ip613fd8a2016-11-29 19:01:39 -0500770 off:0x%x \n", j,
771 PROP_BITVALUE_ACCESS(prop_value,
772 i, j, 0),
773 PROP_BITVALUE_ACCESS(prop_value,
774 i, j, 1));
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700775 SDE_DEBUG("\n");
776 }
777 break;
Benet Clark37809e62016-10-24 10:14:00 -0700778 case PROP_TYPE_NODE:
779 /* Node will be parsed in calling function */
780 rc = 0;
781 break;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700782 default:
783 SDE_DEBUG("invalid property type:%d\n",
784 sde_prop[i].type);
785 break;
786 }
787 rc = 0;
788 }
789
790end:
791 return rc;
792}
793
794static void _sde_sspp_setup_vig(struct sde_mdss_cfg *sde_cfg,
795 struct sde_sspp_cfg *sspp, struct sde_sspp_sub_blks *sblk,
Clarence Ip613fd8a2016-11-29 19:01:39 -0500796 bool *prop_exists, struct sde_prop_value *prop_value, u32 *vig_count)
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700797{
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700798 sblk->maxupscale = MAX_SSPP_UPSCALE;
799 sblk->maxdwnscale = MAX_SSPP_DOWNSCALE;
800 sspp->id = SSPP_VIG0 + *vig_count;
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -0700801 snprintf(sspp->name, SDE_HW_BLK_NAME_LEN, "sspp_%u",
802 sspp->id - SSPP_VIG0);
Alan Kwong04780ec2016-10-12 16:05:17 -0400803 sspp->clk_ctrl = SDE_CLK_CTRL_VIG0 + *vig_count;
abeykunf35ff332016-12-20 13:06:09 -0500804 sspp->type = SSPP_TYPE_VIG;
Alan Kwong41b099e2016-10-12 17:10:11 -0400805 set_bit(SDE_SSPP_QOS, &sspp->features);
Alan Kwongdce56da2017-04-27 15:50:34 -0700806 if (sde_cfg->vbif_qos_nlvl == 8)
807 set_bit(SDE_SSPP_QOS_8LVL, &sspp->features);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700808 (*vig_count)++;
Benet Clark37809e62016-10-24 10:14:00 -0700809
810 if (!prop_value)
811 return;
812
813 if (sde_cfg->qseed_type == SDE_SSPP_SCALER_QSEED2) {
814 set_bit(SDE_SSPP_SCALER_QSEED2, &sspp->features);
815 sblk->scaler_blk.id = SDE_SSPP_SCALER_QSEED2;
816 sblk->scaler_blk.base = PROP_VALUE_ACCESS(prop_value,
817 VIG_QSEED_OFF, 0);
Lloyd Atkinson77158732016-10-23 13:02:00 -0400818 sblk->scaler_blk.len = PROP_VALUE_ACCESS(prop_value,
819 VIG_QSEED_LEN, 0);
820 snprintf(sblk->scaler_blk.name, SDE_HW_BLK_NAME_LEN,
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -0700821 "sspp_scaler%u", sspp->id - SSPP_VIG0);
Benet Clark37809e62016-10-24 10:14:00 -0700822 } else if (sde_cfg->qseed_type == SDE_SSPP_SCALER_QSEED3) {
823 set_bit(SDE_SSPP_SCALER_QSEED3, &sspp->features);
824 sblk->scaler_blk.id = SDE_SSPP_SCALER_QSEED3;
825 sblk->scaler_blk.base = PROP_VALUE_ACCESS(prop_value,
826 VIG_QSEED_OFF, 0);
Lloyd Atkinson77158732016-10-23 13:02:00 -0400827 sblk->scaler_blk.len = PROP_VALUE_ACCESS(prop_value,
828 VIG_QSEED_LEN, 0);
829 snprintf(sblk->scaler_blk.name, SDE_HW_BLK_NAME_LEN,
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -0700830 "sspp_scaler%u", sspp->id - SSPP_VIG0);
Benet Clark37809e62016-10-24 10:14:00 -0700831 }
832
Alan Kwong4dd64c82017-02-04 18:41:51 -0800833 if (sde_cfg->has_sbuf)
834 set_bit(SDE_SSPP_SBUF, &sspp->features);
835
Benet Clark37809e62016-10-24 10:14:00 -0700836 sblk->csc_blk.id = SDE_SSPP_CSC;
Lloyd Atkinson77158732016-10-23 13:02:00 -0400837 snprintf(sblk->csc_blk.name, SDE_HW_BLK_NAME_LEN,
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -0700838 "sspp_csc%u", sspp->id - SSPP_VIG0);
Dhaval Patel5aad7452017-01-12 09:59:31 -0800839 if (sde_cfg->csc_type == SDE_SSPP_CSC) {
840 set_bit(SDE_SSPP_CSC, &sspp->features);
841 sblk->csc_blk.base = PROP_VALUE_ACCESS(prop_value,
842 VIG_CSC_OFF, 0);
843 } else if (sde_cfg->csc_type == SDE_SSPP_CSC_10BIT) {
844 set_bit(SDE_SSPP_CSC_10BIT, &sspp->features);
845 sblk->csc_blk.base = PROP_VALUE_ACCESS(prop_value,
846 VIG_CSC_OFF, 0);
847 }
Benet Clark37809e62016-10-24 10:14:00 -0700848
849 sblk->hsic_blk.id = SDE_SSPP_HSIC;
Lloyd Atkinson77158732016-10-23 13:02:00 -0400850 snprintf(sblk->hsic_blk.name, SDE_HW_BLK_NAME_LEN,
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -0700851 "sspp_hsic%u", sspp->id - SSPP_VIG0);
Benet Clark37809e62016-10-24 10:14:00 -0700852 if (prop_exists[VIG_HSIC_PROP]) {
853 sblk->hsic_blk.base = PROP_VALUE_ACCESS(prop_value,
854 VIG_HSIC_PROP, 0);
855 sblk->hsic_blk.version = PROP_VALUE_ACCESS(prop_value,
856 VIG_HSIC_PROP, 1);
857 sblk->hsic_blk.len = 0;
858 set_bit(SDE_SSPP_HSIC, &sspp->features);
859 }
860
861 sblk->memcolor_blk.id = SDE_SSPP_MEMCOLOR;
Lloyd Atkinson77158732016-10-23 13:02:00 -0400862 snprintf(sblk->memcolor_blk.name, SDE_HW_BLK_NAME_LEN,
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -0700863 "sspp_memcolor%u", sspp->id - SSPP_VIG0);
Benet Clark37809e62016-10-24 10:14:00 -0700864 if (prop_exists[VIG_MEMCOLOR_PROP]) {
865 sblk->memcolor_blk.base = PROP_VALUE_ACCESS(prop_value,
866 VIG_MEMCOLOR_PROP, 0);
867 sblk->memcolor_blk.version = PROP_VALUE_ACCESS(prop_value,
868 VIG_MEMCOLOR_PROP, 1);
869 sblk->memcolor_blk.len = 0;
870 set_bit(SDE_SSPP_MEMCOLOR, &sspp->features);
871 }
872
873 sblk->pcc_blk.id = SDE_SSPP_PCC;
Lloyd Atkinson77158732016-10-23 13:02:00 -0400874 snprintf(sblk->pcc_blk.name, SDE_HW_BLK_NAME_LEN,
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -0700875 "sspp_pcc%u", sspp->id - SSPP_VIG0);
Benet Clark37809e62016-10-24 10:14:00 -0700876 if (prop_exists[VIG_PCC_PROP]) {
877 sblk->pcc_blk.base = PROP_VALUE_ACCESS(prop_value,
878 VIG_PCC_PROP, 0);
879 sblk->pcc_blk.version = PROP_VALUE_ACCESS(prop_value,
880 VIG_PCC_PROP, 1);
881 sblk->pcc_blk.len = 0;
882 set_bit(SDE_SSPP_PCC, &sspp->features);
883 }
Clarence Ip32bcb002017-03-13 12:26:44 -0700884
885 sblk->format_list = sde_cfg->vig_formats;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700886}
887
888static void _sde_sspp_setup_rgb(struct sde_mdss_cfg *sde_cfg,
889 struct sde_sspp_cfg *sspp, struct sde_sspp_sub_blks *sblk,
Clarence Ip613fd8a2016-11-29 19:01:39 -0500890 bool *prop_exists, struct sde_prop_value *prop_value, u32 *rgb_count)
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700891{
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700892 sblk->maxupscale = MAX_SSPP_UPSCALE;
893 sblk->maxdwnscale = MAX_SSPP_DOWNSCALE;
894 sspp->id = SSPP_RGB0 + *rgb_count;
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -0700895 snprintf(sspp->name, SDE_HW_BLK_NAME_LEN, "sspp_%u",
896 sspp->id - SSPP_VIG0);
Alan Kwong04780ec2016-10-12 16:05:17 -0400897 sspp->clk_ctrl = SDE_CLK_CTRL_RGB0 + *rgb_count;
abeykunf35ff332016-12-20 13:06:09 -0500898 sspp->type = SSPP_TYPE_RGB;
Alan Kwong41b099e2016-10-12 17:10:11 -0400899 set_bit(SDE_SSPP_QOS, &sspp->features);
Alan Kwongdce56da2017-04-27 15:50:34 -0700900 if (sde_cfg->vbif_qos_nlvl == 8)
901 set_bit(SDE_SSPP_QOS_8LVL, &sspp->features);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700902 (*rgb_count)++;
Benet Clark37809e62016-10-24 10:14:00 -0700903
904 if (!prop_value)
905 return;
906
907 if (sde_cfg->qseed_type == SDE_SSPP_SCALER_QSEED2) {
908 set_bit(SDE_SSPP_SCALER_RGB, &sspp->features);
909 sblk->scaler_blk.id = SDE_SSPP_SCALER_QSEED2;
910 sblk->scaler_blk.base = PROP_VALUE_ACCESS(prop_value,
911 RGB_SCALER_OFF, 0);
Lloyd Atkinson77158732016-10-23 13:02:00 -0400912 sblk->scaler_blk.len = PROP_VALUE_ACCESS(prop_value,
913 RGB_SCALER_LEN, 0);
914 snprintf(sblk->scaler_blk.name, SDE_HW_BLK_NAME_LEN,
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -0700915 "sspp_scaler%u", sspp->id - SSPP_VIG0);
Benet Clark37809e62016-10-24 10:14:00 -0700916 } else if (sde_cfg->qseed_type == SDE_SSPP_SCALER_QSEED3) {
917 set_bit(SDE_SSPP_SCALER_RGB, &sspp->features);
918 sblk->scaler_blk.id = SDE_SSPP_SCALER_QSEED3;
919 sblk->scaler_blk.base = PROP_VALUE_ACCESS(prop_value,
Lloyd Atkinson77158732016-10-23 13:02:00 -0400920 RGB_SCALER_LEN, 0);
921 sblk->scaler_blk.len = PROP_VALUE_ACCESS(prop_value,
922 SSPP_SCALE_SIZE, 0);
923 snprintf(sblk->scaler_blk.name, SDE_HW_BLK_NAME_LEN,
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -0700924 "sspp_scaler%u", sspp->id - SSPP_VIG0);
Benet Clark37809e62016-10-24 10:14:00 -0700925 }
926
927 sblk->pcc_blk.id = SDE_SSPP_PCC;
928 if (prop_exists[RGB_PCC_PROP]) {
929 sblk->pcc_blk.base = PROP_VALUE_ACCESS(prop_value,
930 RGB_PCC_PROP, 0);
931 sblk->pcc_blk.version = PROP_VALUE_ACCESS(prop_value,
932 RGB_PCC_PROP, 1);
933 sblk->pcc_blk.len = 0;
934 set_bit(SDE_SSPP_PCC, &sspp->features);
935 }
Clarence Ip32bcb002017-03-13 12:26:44 -0700936
937 sblk->format_list = sde_cfg->dma_formats;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700938}
939
940static void _sde_sspp_setup_cursor(struct sde_mdss_cfg *sde_cfg,
941 struct sde_sspp_cfg *sspp, struct sde_sspp_sub_blks *sblk,
Clarence Ip613fd8a2016-11-29 19:01:39 -0500942 struct sde_prop_value *prop_value, u32 *cursor_count)
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700943{
Clarence Ip32bcb002017-03-13 12:26:44 -0700944 if (!IS_SDE_MAJOR_MINOR_SAME(sde_cfg->hwversion, SDE_HW_VER_300))
945 SDE_ERROR("invalid sspp type %d, xin id %d\n",
946 sspp->type, sspp->xin_id);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700947 set_bit(SDE_SSPP_CURSOR, &sspp->features);
948 sblk->maxupscale = SSPP_UNITY_SCALE;
949 sblk->maxdwnscale = SSPP_UNITY_SCALE;
Clarence Ip32bcb002017-03-13 12:26:44 -0700950 sblk->format_list = sde_cfg->cursor_formats;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700951 sspp->id = SSPP_CURSOR0 + *cursor_count;
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -0700952 snprintf(sspp->name, SDE_HW_BLK_NAME_LEN, "sspp_%u",
953 sspp->id - SSPP_VIG0);
Alan Kwong04780ec2016-10-12 16:05:17 -0400954 sspp->clk_ctrl = SDE_CLK_CTRL_CURSOR0 + *cursor_count;
abeykunf35ff332016-12-20 13:06:09 -0500955 sspp->type = SSPP_TYPE_CURSOR;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700956 (*cursor_count)++;
957}
958
959static void _sde_sspp_setup_dma(struct sde_mdss_cfg *sde_cfg,
960 struct sde_sspp_cfg *sspp, struct sde_sspp_sub_blks *sblk,
Clarence Ip613fd8a2016-11-29 19:01:39 -0500961 struct sde_prop_value *prop_value, u32 *dma_count)
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700962{
963 sblk->maxupscale = SSPP_UNITY_SCALE;
964 sblk->maxdwnscale = SSPP_UNITY_SCALE;
Clarence Ip32bcb002017-03-13 12:26:44 -0700965 sblk->format_list = sde_cfg->dma_formats;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700966 sspp->id = SSPP_DMA0 + *dma_count;
Alan Kwong04780ec2016-10-12 16:05:17 -0400967 sspp->clk_ctrl = SDE_CLK_CTRL_DMA0 + *dma_count;
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -0700968 snprintf(sspp->name, SDE_HW_BLK_NAME_LEN, "sspp_%u",
969 sspp->id - SSPP_VIG0);
abeykunf35ff332016-12-20 13:06:09 -0500970 sspp->type = SSPP_TYPE_DMA;
Alan Kwong41b099e2016-10-12 17:10:11 -0400971 set_bit(SDE_SSPP_QOS, &sspp->features);
Alan Kwongdce56da2017-04-27 15:50:34 -0700972 if (sde_cfg->vbif_qos_nlvl == 8)
973 set_bit(SDE_SSPP_QOS_8LVL, &sspp->features);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700974 (*dma_count)++;
975}
976
977static int sde_sspp_parse_dt(struct device_node *np,
978 struct sde_mdss_cfg *sde_cfg)
979{
Benet Clark37809e62016-10-24 10:14:00 -0700980 int rc, prop_count[SSPP_PROP_MAX], off_count, i, j;
981 int vig_prop_count[VIG_PROP_MAX], rgb_prop_count[RGB_PROP_MAX];
982 bool prop_exists[SSPP_PROP_MAX], vig_prop_exists[VIG_PROP_MAX];
983 bool rgb_prop_exists[RGB_PROP_MAX];
Clarence Ip613fd8a2016-11-29 19:01:39 -0500984 struct sde_prop_value *prop_value = NULL;
985 struct sde_prop_value *vig_prop_value = NULL, *rgb_prop_value = NULL;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700986 const char *type;
987 struct sde_sspp_cfg *sspp;
988 struct sde_sspp_sub_blks *sblk;
989 u32 vig_count = 0, dma_count = 0, rgb_count = 0, cursor_count = 0;
Benet Clark37809e62016-10-24 10:14:00 -0700990 struct device_node *snp = NULL;
991
Clarence Ip613fd8a2016-11-29 19:01:39 -0500992 prop_value = kzalloc(SSPP_PROP_MAX *
993 sizeof(struct sde_prop_value), GFP_KERNEL);
Benet Clark37809e62016-10-24 10:14:00 -0700994 if (!prop_value) {
995 rc = -ENOMEM;
996 goto end;
997 }
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700998
999 rc = _validate_dt_entry(np, sspp_prop, ARRAY_SIZE(sspp_prop),
1000 prop_count, &off_count);
1001 if (rc)
1002 goto end;
1003
1004 rc = _read_dt_entry(np, sspp_prop, ARRAY_SIZE(sspp_prop), prop_count,
Clarence Ip613fd8a2016-11-29 19:01:39 -05001005 prop_exists, prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001006 if (rc)
1007 goto end;
1008
1009 sde_cfg->sspp_count = off_count;
1010
Benet Clark37809e62016-10-24 10:14:00 -07001011 /* get vig feature dt properties if they exist */
1012 snp = of_get_child_by_name(np, sspp_prop[SSPP_VIG_BLOCKS].prop_name);
1013 if (snp) {
Clarence Ip613fd8a2016-11-29 19:01:39 -05001014 vig_prop_value = kzalloc(VIG_PROP_MAX *
1015 sizeof(struct sde_prop_value), GFP_KERNEL);
Benet Clark37809e62016-10-24 10:14:00 -07001016 if (!vig_prop_value) {
1017 rc = -ENOMEM;
1018 goto end;
1019 }
1020 rc = _validate_dt_entry(snp, vig_prop, ARRAY_SIZE(vig_prop),
1021 vig_prop_count, NULL);
1022 if (rc)
1023 goto end;
1024 rc = _read_dt_entry(snp, vig_prop, ARRAY_SIZE(vig_prop),
Clarence Ip613fd8a2016-11-29 19:01:39 -05001025 vig_prop_count, vig_prop_exists,
1026 vig_prop_value);
Benet Clark37809e62016-10-24 10:14:00 -07001027 }
1028
1029 /* get rgb feature dt properties if they exist */
1030 snp = of_get_child_by_name(np, sspp_prop[SSPP_RGB_BLOCKS].prop_name);
1031 if (snp) {
Clarence Ip613fd8a2016-11-29 19:01:39 -05001032 rgb_prop_value = kzalloc(RGB_PROP_MAX *
1033 sizeof(struct sde_prop_value),
1034 GFP_KERNEL);
Benet Clark37809e62016-10-24 10:14:00 -07001035 if (!rgb_prop_value) {
1036 rc = -ENOMEM;
1037 goto end;
1038 }
1039 rc = _validate_dt_entry(snp, rgb_prop, ARRAY_SIZE(rgb_prop),
1040 rgb_prop_count, NULL);
1041 if (rc)
1042 goto end;
1043 rc = _read_dt_entry(snp, rgb_prop, ARRAY_SIZE(rgb_prop),
Clarence Ip613fd8a2016-11-29 19:01:39 -05001044 rgb_prop_count, rgb_prop_exists,
1045 rgb_prop_value);
Benet Clark37809e62016-10-24 10:14:00 -07001046 }
1047
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001048 for (i = 0; i < off_count; i++) {
1049 sspp = sde_cfg->sspp + i;
1050 sblk = kzalloc(sizeof(*sblk), GFP_KERNEL);
1051 if (!sblk) {
1052 rc = -ENOMEM;
1053 /* catalog deinit will release the allocated blocks */
1054 goto end;
1055 }
1056 sspp->sblk = sblk;
1057
Benet Clark37809e62016-10-24 10:14:00 -07001058 sspp->base = PROP_VALUE_ACCESS(prop_value, SSPP_OFF, i);
Lloyd Atkinson77158732016-10-23 13:02:00 -04001059 sspp->len = PROP_VALUE_ACCESS(prop_value, SSPP_SIZE, 0);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001060 sblk->maxlinewidth = sde_cfg->max_sspp_linewidth;
1061
1062 set_bit(SDE_SSPP_SRC, &sspp->features);
Jeykumar Sankaran2e655032017-02-04 14:05:45 -08001063
Alan Kwong2349d742017-04-20 08:27:30 -07001064 if (sde_cfg->ts_prefill_rev == 1) {
1065 set_bit(SDE_SSPP_TS_PREFILL, &sspp->features);
1066 } else if (sde_cfg->ts_prefill_rev == 2) {
1067 set_bit(SDE_SSPP_TS_PREFILL, &sspp->features);
1068 set_bit(SDE_SSPP_TS_PREFILL_REC1, &sspp->features);
1069 }
1070
Jeykumar Sankaran2e655032017-02-04 14:05:45 -08001071 sblk->smart_dma_priority =
1072 PROP_VALUE_ACCESS(prop_value, SSPP_SMART_DMA, i);
1073
1074 if (sblk->smart_dma_priority && sde_cfg->smart_dma_rev)
1075 set_bit(sde_cfg->smart_dma_rev, &sspp->features);
1076
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001077 sblk->src_blk.id = SDE_SSPP_SRC;
1078
1079 of_property_read_string_index(np,
1080 sspp_prop[SSPP_TYPE].prop_name, i, &type);
1081 if (!strcmp(type, "vig")) {
Benet Clark37809e62016-10-24 10:14:00 -07001082 _sde_sspp_setup_vig(sde_cfg, sspp, sblk,
1083 vig_prop_exists, vig_prop_value, &vig_count);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001084 } else if (!strcmp(type, "rgb")) {
Benet Clark37809e62016-10-24 10:14:00 -07001085 _sde_sspp_setup_rgb(sde_cfg, sspp, sblk,
1086 rgb_prop_exists, rgb_prop_value, &rgb_count);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001087 } else if (!strcmp(type, "cursor")) {
Benet Clark37809e62016-10-24 10:14:00 -07001088 /* No prop values for cursor pipes */
1089 _sde_sspp_setup_cursor(sde_cfg, sspp, sblk, NULL,
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001090 &cursor_count);
1091 } else if (!strcmp(type, "dma")) {
Benet Clark37809e62016-10-24 10:14:00 -07001092 /* No prop values for DMA pipes */
1093 _sde_sspp_setup_dma(sde_cfg, sspp, sblk, NULL,
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001094 &dma_count);
1095 } else {
1096 SDE_ERROR("invalid sspp type:%s\n", type);
1097 rc = -EINVAL;
1098 goto end;
1099 }
1100
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -07001101 snprintf(sblk->src_blk.name, SDE_HW_BLK_NAME_LEN, "sspp_src_%u",
1102 sspp->id - SSPP_VIG0);
1103
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001104 sblk->maxhdeciexp = MAX_HORZ_DECIMATION;
1105 sblk->maxvdeciexp = MAX_VERT_DECIMATION;
1106
Benet Clark37809e62016-10-24 10:14:00 -07001107 sspp->xin_id = PROP_VALUE_ACCESS(prop_value, SSPP_XIN, i);
Alan Kwong41b099e2016-10-12 17:10:11 -04001108 sblk->pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE;
Benet Clark37809e62016-10-24 10:14:00 -07001109 sblk->src_blk.len = PROP_VALUE_ACCESS(prop_value, SSPP_SIZE, 0);
Alan Kwong41b099e2016-10-12 17:10:11 -04001110
Veera Sundaram Sankaran02dd6ac2016-12-22 15:08:29 -08001111 if (PROP_VALUE_ACCESS(prop_value, SSPP_EXCL_RECT, i) == 1)
1112 set_bit(SDE_SSPP_EXCL_RECT, &sspp->features);
1113
Alan Kwong6259a382017-04-04 06:18:02 -07001114 if (prop_exists[SSPP_MAX_PER_PIPE_BW])
1115 sblk->max_per_pipe_bw = PROP_VALUE_ACCESS(prop_value,
1116 SSPP_MAX_PER_PIPE_BW, i);
1117 else
1118 sblk->max_per_pipe_bw = DEFAULT_MAX_PER_PIPE_BW;
1119
Alan Kwong04780ec2016-10-12 16:05:17 -04001120 for (j = 0; j < sde_cfg->mdp_count; j++) {
1121 sde_cfg->mdp[j].clk_ctrls[sspp->clk_ctrl].reg_off =
Clarence Ip613fd8a2016-11-29 19:01:39 -05001122 PROP_BITVALUE_ACCESS(prop_value,
1123 SSPP_CLK_CTRL, i, 0);
Alan Kwong04780ec2016-10-12 16:05:17 -04001124 sde_cfg->mdp[j].clk_ctrls[sspp->clk_ctrl].bit_off =
Clarence Ip613fd8a2016-11-29 19:01:39 -05001125 PROP_BITVALUE_ACCESS(prop_value,
1126 SSPP_CLK_CTRL, i, 1);
Alan Kwong04780ec2016-10-12 16:05:17 -04001127 }
1128
Alan Kwong41b099e2016-10-12 17:10:11 -04001129 SDE_DEBUG(
Alan Kwongdce56da2017-04-27 15:50:34 -07001130 "xin:%d ram:%d clk%d:%x/%d\n",
Alan Kwong41b099e2016-10-12 17:10:11 -04001131 sspp->xin_id,
Alan Kwong04780ec2016-10-12 16:05:17 -04001132 sblk->pixel_ram_size,
1133 sspp->clk_ctrl,
1134 sde_cfg->mdp[0].clk_ctrls[sspp->clk_ctrl].reg_off,
1135 sde_cfg->mdp[0].clk_ctrls[sspp->clk_ctrl].bit_off);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001136 }
1137
1138end:
Benet Clark37809e62016-10-24 10:14:00 -07001139 kfree(prop_value);
1140 kfree(vig_prop_value);
1141 kfree(rgb_prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001142 return rc;
1143}
1144
1145static int sde_ctl_parse_dt(struct device_node *np,
1146 struct sde_mdss_cfg *sde_cfg)
1147{
Benet Clark37809e62016-10-24 10:14:00 -07001148 int rc, prop_count[HW_PROP_MAX], i;
1149 bool prop_exists[HW_PROP_MAX];
Clarence Ip613fd8a2016-11-29 19:01:39 -05001150 struct sde_prop_value *prop_value = NULL;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001151 struct sde_ctl_cfg *ctl;
1152 u32 off_count;
1153
1154 if (!sde_cfg) {
1155 SDE_ERROR("invalid argument input param\n");
1156 rc = -EINVAL;
1157 goto end;
1158 }
1159
Clarence Ip613fd8a2016-11-29 19:01:39 -05001160 prop_value = kzalloc(HW_PROP_MAX *
1161 sizeof(struct sde_prop_value), GFP_KERNEL);
Benet Clark37809e62016-10-24 10:14:00 -07001162 if (!prop_value) {
1163 rc = -ENOMEM;
1164 goto end;
1165 }
1166
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001167 rc = _validate_dt_entry(np, ctl_prop, ARRAY_SIZE(ctl_prop), prop_count,
1168 &off_count);
1169 if (rc)
1170 goto end;
1171
1172 sde_cfg->ctl_count = off_count;
1173
1174 rc = _read_dt_entry(np, ctl_prop, ARRAY_SIZE(ctl_prop), prop_count,
Clarence Ip613fd8a2016-11-29 19:01:39 -05001175 prop_exists, prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001176 if (rc)
1177 goto end;
1178
1179 for (i = 0; i < off_count; i++) {
1180 ctl = sde_cfg->ctl + i;
Benet Clark37809e62016-10-24 10:14:00 -07001181 ctl->base = PROP_VALUE_ACCESS(prop_value, HW_OFF, i);
Lloyd Atkinson77158732016-10-23 13:02:00 -04001182 ctl->len = PROP_VALUE_ACCESS(prop_value, HW_LEN, 0);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001183 ctl->id = CTL_0 + i;
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -07001184 snprintf(ctl->name, SDE_HW_BLK_NAME_LEN, "ctl_%u",
1185 ctl->id - CTL_0);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001186
1187 if (i < MAX_SPLIT_DISPLAY_CTL)
1188 set_bit(SDE_CTL_SPLIT_DISPLAY, &ctl->features);
1189 if (i < MAX_PP_SPLIT_DISPLAY_CTL)
1190 set_bit(SDE_CTL_PINGPONG_SPLIT, &ctl->features);
Alan Kwong4dd64c82017-02-04 18:41:51 -08001191 if (sde_cfg->has_sbuf)
1192 set_bit(SDE_CTL_SBUF, &ctl->features);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001193 }
1194
1195end:
Benet Clark37809e62016-10-24 10:14:00 -07001196 kfree(prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001197 return rc;
1198}
1199
1200static int sde_mixer_parse_dt(struct device_node *np,
1201 struct sde_mdss_cfg *sde_cfg)
1202{
Veera Sundaram Sankaran370b9912017-01-10 18:03:42 -08001203 int rc, prop_count[MIXER_PROP_MAX], i, j;
Benet Clark37809e62016-10-24 10:14:00 -07001204 int blocks_prop_count[MIXER_BLOCKS_PROP_MAX];
Veera Sundaram Sankaran370b9912017-01-10 18:03:42 -08001205 int blend_prop_count[MIXER_BLEND_PROP_MAX];
Benet Clark37809e62016-10-24 10:14:00 -07001206 bool prop_exists[MIXER_PROP_MAX];
1207 bool blocks_prop_exists[MIXER_BLOCKS_PROP_MAX];
Veera Sundaram Sankaran370b9912017-01-10 18:03:42 -08001208 bool blend_prop_exists[MIXER_BLEND_PROP_MAX];
Clarence Ip613fd8a2016-11-29 19:01:39 -05001209 struct sde_prop_value *prop_value = NULL, *blocks_prop_value = NULL;
Veera Sundaram Sankaran370b9912017-01-10 18:03:42 -08001210 struct sde_prop_value *blend_prop_value = NULL;
1211 u32 off_count, blend_off_count, max_blendstages, lm_pair_mask;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001212 struct sde_lm_cfg *mixer;
1213 struct sde_lm_sub_blks *sblk;
1214 int pp_count, dspp_count;
1215 u32 pp_idx, dspp_idx;
Benet Clark37809e62016-10-24 10:14:00 -07001216 struct device_node *snp = NULL;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001217
1218 if (!sde_cfg) {
1219 SDE_ERROR("invalid argument input param\n");
1220 rc = -EINVAL;
1221 goto end;
1222 }
1223 max_blendstages = sde_cfg->max_mixer_blendstages;
1224
Clarence Ip613fd8a2016-11-29 19:01:39 -05001225 prop_value = kzalloc(MIXER_PROP_MAX *
1226 sizeof(struct sde_prop_value), GFP_KERNEL);
Benet Clark37809e62016-10-24 10:14:00 -07001227 if (!prop_value) {
1228 rc = -ENOMEM;
1229 goto end;
1230 }
1231
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001232 rc = _validate_dt_entry(np, mixer_prop, ARRAY_SIZE(mixer_prop),
1233 prop_count, &off_count);
1234 if (rc)
1235 goto end;
1236
1237 sde_cfg->mixer_count = off_count;
1238
1239 rc = _read_dt_entry(np, mixer_prop, ARRAY_SIZE(mixer_prop), prop_count,
Clarence Ip613fd8a2016-11-29 19:01:39 -05001240 prop_exists, prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001241 if (rc)
1242 goto end;
1243
1244 pp_count = sde_cfg->pingpong_count;
1245 dspp_count = sde_cfg->dspp_count;
1246
Benet Clark37809e62016-10-24 10:14:00 -07001247 /* get mixer feature dt properties if they exist */
1248 snp = of_get_child_by_name(np, mixer_prop[MIXER_BLOCKS].prop_name);
1249 if (snp) {
1250 blocks_prop_value = kzalloc(MIXER_BLOCKS_PROP_MAX *
Clarence Ip613fd8a2016-11-29 19:01:39 -05001251 MAX_SDE_HW_BLK * sizeof(struct sde_prop_value),
1252 GFP_KERNEL);
Benet Clark37809e62016-10-24 10:14:00 -07001253 if (!blocks_prop_value) {
1254 rc = -ENOMEM;
1255 goto end;
1256 }
1257 rc = _validate_dt_entry(snp, mixer_blocks_prop,
1258 ARRAY_SIZE(mixer_blocks_prop), blocks_prop_count, NULL);
1259 if (rc)
1260 goto end;
1261 rc = _read_dt_entry(snp, mixer_blocks_prop,
1262 ARRAY_SIZE(mixer_blocks_prop),
1263 blocks_prop_count, blocks_prop_exists,
Clarence Ip613fd8a2016-11-29 19:01:39 -05001264 blocks_prop_value);
Benet Clark37809e62016-10-24 10:14:00 -07001265 }
1266
Veera Sundaram Sankaran370b9912017-01-10 18:03:42 -08001267 /* get the blend_op register offsets */
1268 blend_prop_value = kzalloc(MIXER_BLEND_PROP_MAX *
1269 sizeof(struct sde_prop_value), GFP_KERNEL);
1270 if (!blend_prop_value) {
1271 rc = -ENOMEM;
1272 goto end;
1273 }
1274 rc = _validate_dt_entry(np, mixer_blend_prop,
1275 ARRAY_SIZE(mixer_blend_prop), blend_prop_count,
1276 &blend_off_count);
1277 if (rc)
1278 goto end;
1279
1280 rc = _read_dt_entry(np, mixer_blend_prop, ARRAY_SIZE(mixer_blend_prop),
1281 blend_prop_count, blend_prop_exists, blend_prop_value);
1282 if (rc)
1283 goto end;
1284
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001285 for (i = 0, pp_idx = 0, dspp_idx = 0; i < off_count; i++) {
1286 mixer = sde_cfg->mixer + i;
1287 sblk = kzalloc(sizeof(*sblk), GFP_KERNEL);
1288 if (!sblk) {
1289 rc = -ENOMEM;
1290 /* catalog deinit will release the allocated blocks */
1291 goto end;
1292 }
1293 mixer->sblk = sblk;
1294
Benet Clark37809e62016-10-24 10:14:00 -07001295 mixer->base = PROP_VALUE_ACCESS(prop_value, MIXER_OFF, i);
1296 mixer->len = PROP_VALUE_ACCESS(prop_value, MIXER_LEN, 0);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001297 mixer->id = LM_0 + i;
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -07001298 snprintf(mixer->name, SDE_HW_BLK_NAME_LEN, "lm_%u",
1299 mixer->id - LM_0);
Lloyd Atkinson77158732016-10-23 13:02:00 -04001300
Benet Clark37809e62016-10-24 10:14:00 -07001301 if (!prop_exists[MIXER_LEN])
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001302 mixer->len = DEFAULT_SDE_HW_BLOCK_LEN;
1303
Veera Sundaram Sankaran370b9912017-01-10 18:03:42 -08001304 lm_pair_mask = PROP_VALUE_ACCESS(prop_value,
1305 MIXER_PAIR_MASK, i);
1306 if (lm_pair_mask)
1307 mixer->lm_pair_mask = 1 << lm_pair_mask;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001308
1309 sblk->maxblendstages = max_blendstages;
1310 sblk->maxwidth = sde_cfg->max_mixer_width;
Veera Sundaram Sankaran370b9912017-01-10 18:03:42 -08001311
1312 for (j = 0; j < blend_off_count; j++)
1313 sblk->blendstage_base[j] =
1314 PROP_VALUE_ACCESS(blend_prop_value,
1315 MIXER_BLEND_OP_OFF, j);
1316
Dhaval Patel1964fb92016-10-13 19:28:08 -07001317 if (sde_cfg->has_src_split)
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001318 set_bit(SDE_MIXER_SOURCESPLIT, &mixer->features);
Veera Sundaram Sankaran3171ff82017-01-04 14:34:47 -08001319 if (sde_cfg->has_dim_layer)
1320 set_bit(SDE_DIM_LAYER, &mixer->features);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001321
1322 if ((i < ROT_LM_OFFSET) || (i >= LINE_LM_OFFSET)) {
1323 mixer->pingpong = pp_count > 0 ? pp_idx + PINGPONG_0
1324 : PINGPONG_MAX;
1325 mixer->dspp = dspp_count > 0 ? dspp_idx + DSPP_0
1326 : DSPP_MAX;
1327 pp_count--;
1328 dspp_count--;
1329 pp_idx++;
1330 dspp_idx++;
1331 } else {
1332 mixer->pingpong = PINGPONG_MAX;
1333 mixer->dspp = DSPP_MAX;
1334 }
Benet Clark37809e62016-10-24 10:14:00 -07001335
1336 sblk->gc.id = SDE_MIXER_GC;
1337 if (blocks_prop_value && blocks_prop_exists[MIXER_GC_PROP]) {
1338 sblk->gc.base = PROP_VALUE_ACCESS(blocks_prop_value,
1339 MIXER_GC_PROP, 0);
1340 sblk->gc.version = PROP_VALUE_ACCESS(blocks_prop_value,
1341 MIXER_GC_PROP, 1);
1342 sblk->gc.len = 0;
1343 set_bit(SDE_MIXER_GC, &mixer->features);
1344 }
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001345 }
1346
1347end:
Benet Clark37809e62016-10-24 10:14:00 -07001348 kfree(prop_value);
1349 kfree(blocks_prop_value);
Veera Sundaram Sankaran370b9912017-01-10 18:03:42 -08001350 kfree(blend_prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001351 return rc;
1352}
1353
1354static int sde_intf_parse_dt(struct device_node *np,
1355 struct sde_mdss_cfg *sde_cfg)
1356{
Benet Clark37809e62016-10-24 10:14:00 -07001357 int rc, prop_count[INTF_PROP_MAX], i;
Clarence Ip613fd8a2016-11-29 19:01:39 -05001358 struct sde_prop_value *prop_value = NULL;
Benet Clark37809e62016-10-24 10:14:00 -07001359 bool prop_exists[INTF_PROP_MAX];
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001360 u32 off_count;
1361 u32 dsi_count = 0, none_count = 0, hdmi_count = 0, dp_count = 0;
1362 const char *type;
1363 struct sde_intf_cfg *intf;
1364
1365 if (!sde_cfg) {
1366 SDE_ERROR("invalid argument\n");
1367 rc = -EINVAL;
1368 goto end;
1369 }
1370
Clarence Ip613fd8a2016-11-29 19:01:39 -05001371 prop_value = kzalloc(INTF_PROP_MAX *
1372 sizeof(struct sde_prop_value), GFP_KERNEL);
Benet Clark37809e62016-10-24 10:14:00 -07001373 if (!prop_value) {
1374 rc = -ENOMEM;
1375 goto end;
1376 }
1377
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001378 rc = _validate_dt_entry(np, intf_prop, ARRAY_SIZE(intf_prop),
1379 prop_count, &off_count);
1380 if (rc)
1381 goto end;
1382
1383 sde_cfg->intf_count = off_count;
1384
1385 rc = _read_dt_entry(np, intf_prop, ARRAY_SIZE(intf_prop), prop_count,
Clarence Ip613fd8a2016-11-29 19:01:39 -05001386 prop_exists, prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001387 if (rc)
1388 goto end;
1389
1390 for (i = 0; i < off_count; i++) {
1391 intf = sde_cfg->intf + i;
Benet Clark37809e62016-10-24 10:14:00 -07001392 intf->base = PROP_VALUE_ACCESS(prop_value, INTF_OFF, i);
1393 intf->len = PROP_VALUE_ACCESS(prop_value, INTF_LEN, 0);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001394 intf->id = INTF_0 + i;
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -07001395 snprintf(intf->name, SDE_HW_BLK_NAME_LEN, "intf_%u",
1396 intf->id - INTF_0);
Lloyd Atkinson77158732016-10-23 13:02:00 -04001397
Benet Clark37809e62016-10-24 10:14:00 -07001398 if (!prop_exists[INTF_LEN])
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001399 intf->len = DEFAULT_SDE_HW_BLOCK_LEN;
1400
1401 intf->prog_fetch_lines_worst_case =
Benet Clark37809e62016-10-24 10:14:00 -07001402 PROP_VALUE_ACCESS(prop_value, INTF_PREFETCH, i);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001403
1404 of_property_read_string_index(np,
1405 intf_prop[INTF_TYPE].prop_name, i, &type);
1406 if (!strcmp(type, "dsi")) {
1407 intf->type = INTF_DSI;
1408 intf->controller_id = dsi_count;
1409 dsi_count++;
1410 } else if (!strcmp(type, "hdmi")) {
1411 intf->type = INTF_HDMI;
1412 intf->controller_id = hdmi_count;
1413 hdmi_count++;
1414 } else if (!strcmp(type, "dp")) {
1415 intf->type = INTF_DP;
1416 intf->controller_id = dp_count;
1417 dp_count++;
1418 } else {
1419 intf->type = INTF_NONE;
1420 intf->controller_id = none_count;
1421 none_count++;
1422 }
Alan Kwong4aacd532017-02-04 18:51:33 -08001423
1424 if (sde_cfg->has_sbuf)
1425 set_bit(SDE_INTF_ROT_START, &intf->features);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001426 }
1427
1428end:
Benet Clark37809e62016-10-24 10:14:00 -07001429 kfree(prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001430 return rc;
1431}
1432
1433static int sde_wb_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg)
1434{
Benet Clark37809e62016-10-24 10:14:00 -07001435 int rc, prop_count[WB_PROP_MAX], i, j;
Clarence Ip613fd8a2016-11-29 19:01:39 -05001436 struct sde_prop_value *prop_value = NULL;
Benet Clark37809e62016-10-24 10:14:00 -07001437 bool prop_exists[WB_PROP_MAX];
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001438 u32 off_count;
1439 struct sde_wb_cfg *wb;
1440 struct sde_wb_sub_blocks *sblk;
1441
1442 if (!sde_cfg) {
1443 SDE_ERROR("invalid argument\n");
1444 rc = -EINVAL;
1445 goto end;
1446 }
1447
Clarence Ip613fd8a2016-11-29 19:01:39 -05001448 prop_value = kzalloc(WB_PROP_MAX *
1449 sizeof(struct sde_prop_value), GFP_KERNEL);
Benet Clark37809e62016-10-24 10:14:00 -07001450 if (!prop_value) {
1451 rc = -ENOMEM;
1452 goto end;
1453 }
1454
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001455 rc = _validate_dt_entry(np, wb_prop, ARRAY_SIZE(wb_prop), prop_count,
1456 &off_count);
1457 if (rc)
1458 goto end;
1459
1460 sde_cfg->wb_count = off_count;
1461
1462 rc = _read_dt_entry(np, wb_prop, ARRAY_SIZE(wb_prop), prop_count,
Clarence Ip613fd8a2016-11-29 19:01:39 -05001463 prop_exists, prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001464 if (rc)
1465 goto end;
1466
1467 for (i = 0; i < off_count; i++) {
1468 wb = sde_cfg->wb + i;
1469 sblk = kzalloc(sizeof(*sblk), GFP_KERNEL);
1470 if (!sblk) {
1471 rc = -ENOMEM;
1472 /* catalog deinit will release the allocated blocks */
1473 goto end;
1474 }
1475 wb->sblk = sblk;
1476
Benet Clark37809e62016-10-24 10:14:00 -07001477 wb->base = PROP_VALUE_ACCESS(prop_value, WB_OFF, i);
1478 wb->id = WB_0 + PROP_VALUE_ACCESS(prop_value, WB_ID, i);
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -07001479 snprintf(wb->name, SDE_HW_BLK_NAME_LEN, "wb_%u",
1480 wb->id - WB_0);
Benet Clark37809e62016-10-24 10:14:00 -07001481 wb->clk_ctrl = SDE_CLK_CTRL_WB0 +
1482 PROP_VALUE_ACCESS(prop_value, WB_ID, i);
1483 wb->xin_id = PROP_VALUE_ACCESS(prop_value, WB_XIN_ID, i);
Alan Kwongd22ecec2017-05-02 14:41:17 -07001484
1485 if (IS_SDE_MAJOR_MINOR_SAME((sde_cfg->hwversion),
1486 SDE_HW_VER_170))
1487 wb->vbif_idx = VBIF_NRT;
1488 else
1489 wb->vbif_idx = VBIF_RT;
1490
Benet Clark37809e62016-10-24 10:14:00 -07001491 wb->len = PROP_VALUE_ACCESS(prop_value, WB_LEN, 0);
Benet Clark37809e62016-10-24 10:14:00 -07001492 if (!prop_exists[WB_LEN])
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001493 wb->len = DEFAULT_SDE_HW_BLOCK_LEN;
1494 sblk->maxlinewidth = sde_cfg->max_wb_linewidth;
1495
Alan Kwong14627332016-10-12 16:44:00 -04001496 if (wb->id >= LINE_MODE_WB_OFFSET)
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001497 set_bit(SDE_WB_LINE_MODE, &wb->features);
1498 else
1499 set_bit(SDE_WB_BLOCK_MODE, &wb->features);
1500 set_bit(SDE_WB_TRAFFIC_SHAPER, &wb->features);
1501 set_bit(SDE_WB_YUV_CONFIG, &wb->features);
Alan Kwong04780ec2016-10-12 16:05:17 -04001502
Alan Kwongdce56da2017-04-27 15:50:34 -07001503 set_bit(SDE_WB_QOS, &wb->features);
1504 if (sde_cfg->vbif_qos_nlvl == 8)
1505 set_bit(SDE_WB_QOS_8LVL, &wb->features);
1506
Clarence Ip32bcb002017-03-13 12:26:44 -07001507 if (sde_cfg->has_wb_ubwc)
1508 set_bit(SDE_WB_UBWC, &wb->features);
1509
Alan Kwong04780ec2016-10-12 16:05:17 -04001510 for (j = 0; j < sde_cfg->mdp_count; j++) {
1511 sde_cfg->mdp[j].clk_ctrls[wb->clk_ctrl].reg_off =
Clarence Ip613fd8a2016-11-29 19:01:39 -05001512 PROP_BITVALUE_ACCESS(prop_value,
1513 WB_CLK_CTRL, i, 0);
Alan Kwong04780ec2016-10-12 16:05:17 -04001514 sde_cfg->mdp[j].clk_ctrls[wb->clk_ctrl].bit_off =
Clarence Ip613fd8a2016-11-29 19:01:39 -05001515 PROP_BITVALUE_ACCESS(prop_value,
1516 WB_CLK_CTRL, i, 1);
Alan Kwong04780ec2016-10-12 16:05:17 -04001517 }
1518
Clarence Ip32bcb002017-03-13 12:26:44 -07001519 wb->format_list = sde_cfg->wb_formats;
1520
Alan Kwong04780ec2016-10-12 16:05:17 -04001521 SDE_DEBUG(
1522 "wb:%d xin:%d vbif:%d clk%d:%x/%d\n",
1523 wb->id - WB_0,
1524 wb->xin_id,
1525 wb->vbif_idx,
1526 wb->clk_ctrl,
1527 sde_cfg->mdp[0].clk_ctrls[wb->clk_ctrl].reg_off,
1528 sde_cfg->mdp[0].clk_ctrls[wb->clk_ctrl].bit_off);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001529 }
1530
1531end:
Benet Clark37809e62016-10-24 10:14:00 -07001532 kfree(prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001533 return rc;
1534}
1535
Benet Clark37809e62016-10-24 10:14:00 -07001536static void _sde_dspp_setup_blocks(struct sde_mdss_cfg *sde_cfg,
1537 struct sde_dspp_cfg *dspp, struct sde_dspp_sub_blks *sblk,
Clarence Ip613fd8a2016-11-29 19:01:39 -05001538 bool *prop_exists, struct sde_prop_value *prop_value)
Benet Clark37809e62016-10-24 10:14:00 -07001539{
1540 sblk->igc.id = SDE_DSPP_IGC;
1541 if (prop_exists[DSPP_IGC_PROP]) {
1542 sblk->igc.base = PROP_VALUE_ACCESS(prop_value,
1543 DSPP_IGC_PROP, 0);
1544 sblk->igc.version = PROP_VALUE_ACCESS(prop_value,
1545 DSPP_IGC_PROP, 1);
1546 sblk->igc.len = 0;
1547 set_bit(SDE_DSPP_IGC, &dspp->features);
1548 }
1549
1550 sblk->pcc.id = SDE_DSPP_PCC;
1551 if (prop_exists[DSPP_PCC_PROP]) {
1552 sblk->pcc.base = PROP_VALUE_ACCESS(prop_value,
1553 DSPP_PCC_PROP, 0);
1554 sblk->pcc.version = PROP_VALUE_ACCESS(prop_value,
1555 DSPP_PCC_PROP, 1);
1556 sblk->pcc.len = 0;
1557 set_bit(SDE_DSPP_PCC, &dspp->features);
1558 }
1559
1560 sblk->gc.id = SDE_DSPP_GC;
1561 if (prop_exists[DSPP_GC_PROP]) {
1562 sblk->gc.base = PROP_VALUE_ACCESS(prop_value, DSPP_GC_PROP, 0);
1563 sblk->gc.version = PROP_VALUE_ACCESS(prop_value,
1564 DSPP_GC_PROP, 1);
1565 sblk->gc.len = 0;
1566 set_bit(SDE_DSPP_GC, &dspp->features);
1567 }
1568
1569 sblk->gamut.id = SDE_DSPP_GAMUT;
1570 if (prop_exists[DSPP_GAMUT_PROP]) {
1571 sblk->gamut.base = PROP_VALUE_ACCESS(prop_value,
1572 DSPP_GAMUT_PROP, 0);
1573 sblk->gamut.version = PROP_VALUE_ACCESS(prop_value,
1574 DSPP_GAMUT_PROP, 1);
1575 sblk->gamut.len = 0;
1576 set_bit(SDE_DSPP_GAMUT, &dspp->features);
1577 }
1578
1579 sblk->dither.id = SDE_DSPP_DITHER;
1580 if (prop_exists[DSPP_DITHER_PROP]) {
1581 sblk->dither.base = PROP_VALUE_ACCESS(prop_value,
1582 DSPP_DITHER_PROP, 0);
1583 sblk->dither.version = PROP_VALUE_ACCESS(prop_value,
1584 DSPP_DITHER_PROP, 1);
1585 sblk->dither.len = 0;
1586 set_bit(SDE_DSPP_DITHER, &dspp->features);
1587 }
1588
1589 sblk->hist.id = SDE_DSPP_HIST;
1590 if (prop_exists[DSPP_HIST_PROP]) {
1591 sblk->hist.base = PROP_VALUE_ACCESS(prop_value,
1592 DSPP_HIST_PROP, 0);
1593 sblk->hist.version = PROP_VALUE_ACCESS(prop_value,
1594 DSPP_HIST_PROP, 1);
1595 sblk->hist.len = 0;
1596 set_bit(SDE_DSPP_HIST, &dspp->features);
1597 }
1598
1599 sblk->hsic.id = SDE_DSPP_HSIC;
1600 if (prop_exists[DSPP_HSIC_PROP]) {
1601 sblk->hsic.base = PROP_VALUE_ACCESS(prop_value,
1602 DSPP_HSIC_PROP, 0);
1603 sblk->hsic.version = PROP_VALUE_ACCESS(prop_value,
1604 DSPP_HSIC_PROP, 1);
1605 sblk->hsic.len = 0;
1606 set_bit(SDE_DSPP_HSIC, &dspp->features);
1607 }
1608
1609 sblk->memcolor.id = SDE_DSPP_MEMCOLOR;
1610 if (prop_exists[DSPP_MEMCOLOR_PROP]) {
1611 sblk->memcolor.base = PROP_VALUE_ACCESS(prop_value,
1612 DSPP_MEMCOLOR_PROP, 0);
1613 sblk->memcolor.version = PROP_VALUE_ACCESS(prop_value,
1614 DSPP_MEMCOLOR_PROP, 1);
1615 sblk->memcolor.len = 0;
1616 set_bit(SDE_DSPP_MEMCOLOR, &dspp->features);
1617 }
1618
1619 sblk->sixzone.id = SDE_DSPP_SIXZONE;
1620 if (prop_exists[DSPP_SIXZONE_PROP]) {
1621 sblk->sixzone.base = PROP_VALUE_ACCESS(prop_value,
1622 DSPP_SIXZONE_PROP, 0);
1623 sblk->sixzone.version = PROP_VALUE_ACCESS(prop_value,
1624 DSPP_SIXZONE_PROP, 1);
1625 sblk->sixzone.len = 0;
1626 set_bit(SDE_DSPP_SIXZONE, &dspp->features);
1627 }
1628
1629 sblk->vlut.id = SDE_DSPP_VLUT;
1630 if (prop_exists[DSPP_VLUT_PROP]) {
1631 sblk->vlut.base = PROP_VALUE_ACCESS(prop_value,
1632 DSPP_VLUT_PROP, 0);
1633 sblk->vlut.version = PROP_VALUE_ACCESS(prop_value,
1634 DSPP_VLUT_PROP, 1);
1635 sblk->sixzone.len = 0;
1636 set_bit(SDE_DSPP_VLUT, &dspp->features);
1637 }
1638}
1639
Alan Kwong4dd64c82017-02-04 18:41:51 -08001640static int sde_rot_parse_dt(struct device_node *np,
1641 struct sde_mdss_cfg *sde_cfg)
1642{
1643 struct sde_rot_cfg *rot;
1644 struct platform_device *pdev;
1645 struct of_phandle_args phargs;
1646 struct llcc_slice_desc *slice;
1647 int rc = 0, i;
1648
1649 if (!sde_cfg) {
1650 SDE_ERROR("invalid argument\n");
1651 rc = -EINVAL;
1652 goto end;
1653 }
1654
1655 for (i = 0; i < ROT_MAX; i++) {
1656 rot = sde_cfg->rot + sde_cfg->rot_count;
1657 rot->base = 0;
1658 rot->len = 0;
1659
1660 rc = of_parse_phandle_with_args(np,
1661 "qcom,sde-inline-rotator", "#list-cells",
1662 i, &phargs);
1663 if (rc) {
1664 rc = 0;
1665 break;
1666 } else if (!phargs.np || !phargs.args_count) {
1667 rc = -EINVAL;
1668 break;
1669 }
1670
1671 rot->id = ROT_0 + phargs.args[0];
1672
1673 pdev = of_find_device_by_node(phargs.np);
1674 if (pdev) {
1675 slice = llcc_slice_getd(&pdev->dev, "rotator");
1676 if (IS_ERR_OR_NULL(slice)) {
1677 rot->pdev = NULL;
1678 SDE_ERROR("failed to get system cache %ld\n",
1679 PTR_ERR(slice));
1680 } else {
1681 rot->scid = llcc_get_slice_id(slice);
1682 rot->slice_size = llcc_get_slice_size(slice);
1683 rot->pdev = pdev;
1684 llcc_slice_putd(slice);
1685 sde_cfg->rot_count++;
1686 SDE_DEBUG("rot:%d scid:%d slice_size:%zukb\n",
1687 rot->id, rot->scid,
1688 rot->slice_size);
1689 }
1690 } else {
1691 rot->pdev = NULL;
1692 SDE_ERROR("invalid sde rotator node\n");
1693 }
1694
1695 of_node_put(phargs.np);
1696 }
1697
1698 if (sde_cfg->rot_count) {
1699 sde_cfg->has_sbuf = true;
1700 sde_cfg->sbuf_headroom = DEFAULT_SBUF_HEADROOM;
1701 }
1702
1703end:
1704 return rc;
1705}
1706
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001707static int sde_dspp_parse_dt(struct device_node *np,
1708 struct sde_mdss_cfg *sde_cfg)
1709{
Benet Clark37809e62016-10-24 10:14:00 -07001710 int rc, prop_count[DSPP_PROP_MAX], i;
1711 int ad_prop_count[AD_PROP_MAX];
1712 bool prop_exists[DSPP_PROP_MAX], ad_prop_exists[AD_PROP_MAX];
1713 bool blocks_prop_exists[DSPP_BLOCKS_PROP_MAX];
Clarence Ip613fd8a2016-11-29 19:01:39 -05001714 struct sde_prop_value *ad_prop_value = NULL;
Benet Clark37809e62016-10-24 10:14:00 -07001715 int blocks_prop_count[DSPP_BLOCKS_PROP_MAX];
Clarence Ip613fd8a2016-11-29 19:01:39 -05001716 struct sde_prop_value *prop_value = NULL, *blocks_prop_value = NULL;
Benet Clark37809e62016-10-24 10:14:00 -07001717 u32 off_count, ad_off_count;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001718 struct sde_dspp_cfg *dspp;
1719 struct sde_dspp_sub_blks *sblk;
Benet Clark37809e62016-10-24 10:14:00 -07001720 struct device_node *snp = NULL;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001721
1722 if (!sde_cfg) {
1723 SDE_ERROR("invalid argument\n");
1724 rc = -EINVAL;
1725 goto end;
1726 }
1727
Clarence Ip613fd8a2016-11-29 19:01:39 -05001728 prop_value = kzalloc(DSPP_PROP_MAX *
1729 sizeof(struct sde_prop_value), GFP_KERNEL);
Benet Clark37809e62016-10-24 10:14:00 -07001730 if (!prop_value) {
1731 rc = -ENOMEM;
1732 goto end;
1733 }
1734
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001735 rc = _validate_dt_entry(np, dspp_prop, ARRAY_SIZE(dspp_prop),
1736 prop_count, &off_count);
1737 if (rc)
1738 goto end;
1739
1740 sde_cfg->dspp_count = off_count;
1741
1742 rc = _read_dt_entry(np, dspp_prop, ARRAY_SIZE(dspp_prop), prop_count,
Clarence Ip613fd8a2016-11-29 19:01:39 -05001743 prop_exists, prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001744 if (rc)
1745 goto end;
1746
Benet Clark37809e62016-10-24 10:14:00 -07001747 /* Parse AD dtsi entries */
Clarence Ip613fd8a2016-11-29 19:01:39 -05001748 ad_prop_value = kzalloc(AD_PROP_MAX *
1749 sizeof(struct sde_prop_value), GFP_KERNEL);
Benet Clark37809e62016-10-24 10:14:00 -07001750 if (!ad_prop_value) {
1751 rc = -ENOMEM;
1752 goto end;
1753 }
1754 rc = _validate_dt_entry(np, ad_prop, ARRAY_SIZE(ad_prop),
1755 ad_prop_count, &ad_off_count);
1756 if (rc)
1757 goto end;
1758 rc = _read_dt_entry(np, ad_prop, ARRAY_SIZE(ad_prop), ad_prop_count,
Clarence Ip613fd8a2016-11-29 19:01:39 -05001759 ad_prop_exists, ad_prop_value);
Benet Clark37809e62016-10-24 10:14:00 -07001760 if (rc)
1761 goto end;
1762
1763 /* get DSPP feature dt properties if they exist */
1764 snp = of_get_child_by_name(np, dspp_prop[DSPP_BLOCKS].prop_name);
1765 if (snp) {
1766 blocks_prop_value = kzalloc(DSPP_BLOCKS_PROP_MAX *
Clarence Ip613fd8a2016-11-29 19:01:39 -05001767 MAX_SDE_HW_BLK * sizeof(struct sde_prop_value),
1768 GFP_KERNEL);
Benet Clark37809e62016-10-24 10:14:00 -07001769 if (!blocks_prop_value) {
1770 rc = -ENOMEM;
1771 goto end;
1772 }
1773 rc = _validate_dt_entry(snp, dspp_blocks_prop,
1774 ARRAY_SIZE(dspp_blocks_prop), blocks_prop_count, NULL);
1775 if (rc)
1776 goto end;
1777 rc = _read_dt_entry(snp, dspp_blocks_prop,
1778 ARRAY_SIZE(dspp_blocks_prop), blocks_prop_count,
Clarence Ip613fd8a2016-11-29 19:01:39 -05001779 blocks_prop_exists, blocks_prop_value);
Benet Clark37809e62016-10-24 10:14:00 -07001780 if (rc)
1781 goto end;
1782 }
1783
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001784 for (i = 0; i < off_count; i++) {
1785 dspp = sde_cfg->dspp + i;
Benet Clark37809e62016-10-24 10:14:00 -07001786 dspp->base = PROP_VALUE_ACCESS(prop_value, DSPP_OFF, i);
Lloyd Atkinson77158732016-10-23 13:02:00 -04001787 dspp->len = PROP_VALUE_ACCESS(prop_value, DSPP_SIZE, 0);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001788 dspp->id = DSPP_0 + i;
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -07001789 snprintf(dspp->name, SDE_HW_BLK_NAME_LEN, "dspp_%u",
1790 dspp->id - DSPP_0);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001791
1792 sblk = kzalloc(sizeof(*sblk), GFP_KERNEL);
1793 if (!sblk) {
1794 rc = -ENOMEM;
1795 /* catalog deinit will release the allocated blocks */
1796 goto end;
1797 }
1798 dspp->sblk = sblk;
1799
Benet Clark37809e62016-10-24 10:14:00 -07001800 if (blocks_prop_value)
1801 _sde_dspp_setup_blocks(sde_cfg, dspp, sblk,
1802 blocks_prop_exists, blocks_prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001803
Benet Clark37809e62016-10-24 10:14:00 -07001804 sblk->ad.id = SDE_DSPP_AD;
Gopikrishnaiah Anandan9ba43782017-01-31 18:23:08 -08001805 sde_cfg->ad_count = ad_off_count;
Benet Clark37809e62016-10-24 10:14:00 -07001806 if (ad_prop_value && (i < ad_off_count) &&
1807 ad_prop_exists[AD_OFF]) {
1808 sblk->ad.base = PROP_VALUE_ACCESS(ad_prop_value,
1809 AD_OFF, i);
1810 sblk->ad.version = PROP_VALUE_ACCESS(ad_prop_value,
1811 AD_VERSION, 0);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001812 set_bit(SDE_DSPP_AD, &dspp->features);
Benet Clark37809e62016-10-24 10:14:00 -07001813 }
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001814 }
1815
1816end:
Benet Clark37809e62016-10-24 10:14:00 -07001817 kfree(prop_value);
1818 kfree(ad_prop_value);
1819 kfree(blocks_prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001820 return rc;
1821}
1822
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001823static int sde_dsc_parse_dt(struct device_node *np,
1824 struct sde_mdss_cfg *sde_cfg)
1825{
1826 int rc, prop_count[MAX_BLOCKS], i;
1827 struct sde_prop_value *prop_value = NULL;
1828 bool prop_exists[DSC_PROP_MAX];
1829 u32 off_count;
1830 struct sde_dsc_cfg *dsc;
1831
1832 if (!sde_cfg) {
1833 SDE_ERROR("invalid argument\n");
1834 rc = -EINVAL;
1835 goto end;
1836 }
1837
1838 prop_value = kzalloc(DSC_PROP_MAX *
1839 sizeof(struct sde_prop_value), GFP_KERNEL);
1840 if (!prop_value) {
1841 rc = -ENOMEM;
1842 goto end;
1843 }
1844
1845 rc = _validate_dt_entry(np, dsc_prop, ARRAY_SIZE(dsc_prop), prop_count,
1846 &off_count);
1847 if (rc)
1848 goto end;
1849
1850 sde_cfg->dsc_count = off_count;
1851
1852 rc = _read_dt_entry(np, dsc_prop, ARRAY_SIZE(dsc_prop), prop_count,
1853 prop_exists, prop_value);
1854 if (rc)
1855 goto end;
1856
1857 for (i = 0; i < off_count; i++) {
1858 dsc = sde_cfg->dsc + i;
1859 dsc->base = PROP_VALUE_ACCESS(prop_value, DSC_OFF, i);
1860 dsc->id = DSC_0 + i;
1861 dsc->len = PROP_VALUE_ACCESS(prop_value, DSC_LEN, 0);
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -07001862 snprintf(dsc->name, SDE_HW_BLK_NAME_LEN, "dsc_%u",
1863 dsc->id - DSC_0);
1864
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001865 if (!prop_exists[DSC_LEN])
1866 dsc->len = DEFAULT_SDE_HW_BLOCK_LEN;
1867 }
1868
1869end:
1870 kfree(prop_value);
1871 return rc;
1872};
1873
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001874static int sde_cdm_parse_dt(struct device_node *np,
1875 struct sde_mdss_cfg *sde_cfg)
1876{
Benet Clark37809e62016-10-24 10:14:00 -07001877 int rc, prop_count[HW_PROP_MAX], i;
Clarence Ip613fd8a2016-11-29 19:01:39 -05001878 struct sde_prop_value *prop_value = NULL;
Benet Clark37809e62016-10-24 10:14:00 -07001879 bool prop_exists[HW_PROP_MAX];
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001880 u32 off_count;
1881 struct sde_cdm_cfg *cdm;
1882
1883 if (!sde_cfg) {
1884 SDE_ERROR("invalid argument\n");
1885 rc = -EINVAL;
1886 goto end;
1887 }
1888
Clarence Ip613fd8a2016-11-29 19:01:39 -05001889 prop_value = kzalloc(HW_PROP_MAX *
1890 sizeof(struct sde_prop_value), GFP_KERNEL);
Benet Clark37809e62016-10-24 10:14:00 -07001891 if (!prop_value) {
1892 rc = -ENOMEM;
1893 goto end;
1894 }
1895
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001896 rc = _validate_dt_entry(np, cdm_prop, ARRAY_SIZE(cdm_prop), prop_count,
1897 &off_count);
1898 if (rc)
1899 goto end;
1900
1901 sde_cfg->cdm_count = off_count;
1902
1903 rc = _read_dt_entry(np, cdm_prop, ARRAY_SIZE(cdm_prop), prop_count,
Clarence Ip613fd8a2016-11-29 19:01:39 -05001904 prop_exists, prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001905 if (rc)
1906 goto end;
1907
1908 for (i = 0; i < off_count; i++) {
1909 cdm = sde_cfg->cdm + i;
Benet Clark37809e62016-10-24 10:14:00 -07001910 cdm->base = PROP_VALUE_ACCESS(prop_value, HW_OFF, i);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001911 cdm->id = CDM_0 + i;
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -07001912 snprintf(cdm->name, SDE_HW_BLK_NAME_LEN, "cdm_%u",
1913 cdm->id - CDM_0);
Benet Clark37809e62016-10-24 10:14:00 -07001914 cdm->len = PROP_VALUE_ACCESS(prop_value, HW_LEN, 0);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001915
1916 /* intf3 and wb2 for cdm block */
1917 cdm->wb_connect = sde_cfg->wb_count ? BIT(WB_2) : BIT(31);
1918 cdm->intf_connect = sde_cfg->intf_count ? BIT(INTF_3) : BIT(31);
1919 }
1920
1921end:
Benet Clark37809e62016-10-24 10:14:00 -07001922 kfree(prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001923 return rc;
1924}
1925
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04001926static int sde_vbif_parse_dt(struct device_node *np,
1927 struct sde_mdss_cfg *sde_cfg)
1928{
Benet Clark37809e62016-10-24 10:14:00 -07001929 int rc, prop_count[VBIF_PROP_MAX], i, j, k;
Clarence Ip613fd8a2016-11-29 19:01:39 -05001930 struct sde_prop_value *prop_value = NULL;
Benet Clark37809e62016-10-24 10:14:00 -07001931 bool prop_exists[VBIF_PROP_MAX];
Alan Kwonga62eeb82017-04-19 08:57:55 -07001932 u32 off_count, vbif_len;
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04001933 struct sde_vbif_cfg *vbif;
1934
1935 if (!sde_cfg) {
1936 SDE_ERROR("invalid argument\n");
1937 rc = -EINVAL;
1938 goto end;
1939 }
1940
Clarence Ip613fd8a2016-11-29 19:01:39 -05001941 prop_value = kzalloc(VBIF_PROP_MAX *
1942 sizeof(struct sde_prop_value), GFP_KERNEL);
Benet Clark37809e62016-10-24 10:14:00 -07001943 if (!prop_value) {
1944 rc = -ENOMEM;
1945 goto end;
1946 }
1947
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04001948 rc = _validate_dt_entry(np, vbif_prop, ARRAY_SIZE(vbif_prop),
1949 prop_count, &off_count);
1950 if (rc)
1951 goto end;
1952
1953 rc = _validate_dt_entry(np, &vbif_prop[VBIF_DYNAMIC_OT_RD_LIMIT], 1,
Alan Kwonga62eeb82017-04-19 08:57:55 -07001954 &prop_count[VBIF_DYNAMIC_OT_RD_LIMIT], NULL);
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04001955 if (rc)
1956 goto end;
1957
1958 rc = _validate_dt_entry(np, &vbif_prop[VBIF_DYNAMIC_OT_WR_LIMIT], 1,
Alan Kwonga62eeb82017-04-19 08:57:55 -07001959 &prop_count[VBIF_DYNAMIC_OT_WR_LIMIT], NULL);
1960 if (rc)
1961 goto end;
1962
1963 rc = _validate_dt_entry(np, &vbif_prop[VBIF_QOS_RT_REMAP], 1,
1964 &prop_count[VBIF_QOS_RT_REMAP], NULL);
1965 if (rc)
1966 goto end;
1967
1968 rc = _validate_dt_entry(np, &vbif_prop[VBIF_QOS_NRT_REMAP], 1,
1969 &prop_count[VBIF_QOS_NRT_REMAP], NULL);
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04001970 if (rc)
1971 goto end;
1972
1973 sde_cfg->vbif_count = off_count;
1974
1975 rc = _read_dt_entry(np, vbif_prop, ARRAY_SIZE(vbif_prop), prop_count,
Clarence Ip613fd8a2016-11-29 19:01:39 -05001976 prop_exists, prop_value);
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04001977 if (rc)
1978 goto end;
1979
Benet Clark37809e62016-10-24 10:14:00 -07001980 vbif_len = PROP_VALUE_ACCESS(prop_value, VBIF_LEN, 0);
1981 if (!prop_exists[VBIF_LEN])
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04001982 vbif_len = DEFAULT_SDE_HW_BLOCK_LEN;
1983
1984 for (i = 0; i < off_count; i++) {
1985 vbif = sde_cfg->vbif + i;
Benet Clark37809e62016-10-24 10:14:00 -07001986 vbif->base = PROP_VALUE_ACCESS(prop_value, VBIF_OFF, i);
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04001987 vbif->len = vbif_len;
Benet Clark37809e62016-10-24 10:14:00 -07001988 vbif->id = VBIF_0 + PROP_VALUE_ACCESS(prop_value, VBIF_ID, i);
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -07001989 snprintf(vbif->name, SDE_HW_BLK_NAME_LEN, "vbif_%u",
1990 vbif->id - VBIF_0);
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04001991
1992 SDE_DEBUG("vbif:%d\n", vbif->id - VBIF_0);
1993
1994 vbif->xin_halt_timeout = VBIF_XIN_HALT_TIMEOUT;
1995
Benet Clark37809e62016-10-24 10:14:00 -07001996 vbif->default_ot_rd_limit = PROP_VALUE_ACCESS(prop_value,
1997 VBIF_DEFAULT_OT_RD_LIMIT, 0);
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04001998 SDE_DEBUG("default_ot_rd_limit=%u\n",
1999 vbif->default_ot_rd_limit);
2000
Benet Clark37809e62016-10-24 10:14:00 -07002001 vbif->default_ot_wr_limit = PROP_VALUE_ACCESS(prop_value,
2002 VBIF_DEFAULT_OT_WR_LIMIT, 0);
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04002003 SDE_DEBUG("default_ot_wr_limit=%u\n",
2004 vbif->default_ot_wr_limit);
2005
2006 vbif->dynamic_ot_rd_tbl.count =
2007 prop_count[VBIF_DYNAMIC_OT_RD_LIMIT] / 2;
2008 SDE_DEBUG("dynamic_ot_rd_tbl.count=%u\n",
2009 vbif->dynamic_ot_rd_tbl.count);
2010 if (vbif->dynamic_ot_rd_tbl.count) {
2011 vbif->dynamic_ot_rd_tbl.cfg = kcalloc(
2012 vbif->dynamic_ot_rd_tbl.count,
2013 sizeof(struct sde_vbif_dynamic_ot_cfg),
2014 GFP_KERNEL);
2015 if (!vbif->dynamic_ot_rd_tbl.cfg) {
2016 rc = -ENOMEM;
2017 goto end;
2018 }
2019 }
2020
2021 for (j = 0, k = 0; j < vbif->dynamic_ot_rd_tbl.count; j++) {
2022 vbif->dynamic_ot_rd_tbl.cfg[j].pps = (u64)
Benet Clark37809e62016-10-24 10:14:00 -07002023 PROP_VALUE_ACCESS(prop_value,
2024 VBIF_DYNAMIC_OT_RD_LIMIT, k++);
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04002025 vbif->dynamic_ot_rd_tbl.cfg[j].ot_limit =
Benet Clark37809e62016-10-24 10:14:00 -07002026 PROP_VALUE_ACCESS(prop_value,
2027 VBIF_DYNAMIC_OT_RD_LIMIT, k++);
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04002028 SDE_DEBUG("dynamic_ot_rd_tbl[%d].cfg=<%llu %u>\n", j,
2029 vbif->dynamic_ot_rd_tbl.cfg[j].pps,
2030 vbif->dynamic_ot_rd_tbl.cfg[j].ot_limit);
2031 }
2032
2033 vbif->dynamic_ot_wr_tbl.count =
2034 prop_count[VBIF_DYNAMIC_OT_WR_LIMIT] / 2;
2035 SDE_DEBUG("dynamic_ot_wr_tbl.count=%u\n",
2036 vbif->dynamic_ot_wr_tbl.count);
2037 if (vbif->dynamic_ot_wr_tbl.count) {
2038 vbif->dynamic_ot_wr_tbl.cfg = kcalloc(
2039 vbif->dynamic_ot_wr_tbl.count,
2040 sizeof(struct sde_vbif_dynamic_ot_cfg),
2041 GFP_KERNEL);
2042 if (!vbif->dynamic_ot_wr_tbl.cfg) {
2043 rc = -ENOMEM;
2044 goto end;
2045 }
2046 }
2047
2048 for (j = 0, k = 0; j < vbif->dynamic_ot_wr_tbl.count; j++) {
2049 vbif->dynamic_ot_wr_tbl.cfg[j].pps = (u64)
Benet Clark37809e62016-10-24 10:14:00 -07002050 PROP_VALUE_ACCESS(prop_value,
2051 VBIF_DYNAMIC_OT_WR_LIMIT, k++);
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04002052 vbif->dynamic_ot_wr_tbl.cfg[j].ot_limit =
Benet Clark37809e62016-10-24 10:14:00 -07002053 PROP_VALUE_ACCESS(prop_value,
2054 VBIF_DYNAMIC_OT_WR_LIMIT, k++);
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04002055 SDE_DEBUG("dynamic_ot_wr_tbl[%d].cfg=<%llu %u>\n", j,
2056 vbif->dynamic_ot_wr_tbl.cfg[j].pps,
2057 vbif->dynamic_ot_wr_tbl.cfg[j].ot_limit);
2058 }
2059
2060 if (vbif->default_ot_rd_limit || vbif->default_ot_wr_limit ||
2061 vbif->dynamic_ot_rd_tbl.count ||
2062 vbif->dynamic_ot_wr_tbl.count)
2063 set_bit(SDE_VBIF_QOS_OTLIM, &vbif->features);
Alan Kwonga62eeb82017-04-19 08:57:55 -07002064
2065 vbif->qos_rt_tbl.npriority_lvl =
2066 prop_count[VBIF_QOS_RT_REMAP];
2067 SDE_DEBUG("qos_rt_tbl.npriority_lvl=%u\n",
2068 vbif->qos_rt_tbl.npriority_lvl);
2069 if (vbif->qos_rt_tbl.npriority_lvl == sde_cfg->vbif_qos_nlvl) {
2070 vbif->qos_rt_tbl.priority_lvl = kcalloc(
2071 vbif->qos_rt_tbl.npriority_lvl, sizeof(u32),
2072 GFP_KERNEL);
2073 if (!vbif->qos_rt_tbl.priority_lvl) {
2074 rc = -ENOMEM;
2075 goto end;
2076 }
2077 } else if (vbif->qos_rt_tbl.npriority_lvl) {
2078 vbif->qos_rt_tbl.npriority_lvl = 0;
2079 vbif->qos_rt_tbl.priority_lvl = NULL;
2080 SDE_ERROR("invalid qos rt table\n");
2081 }
2082
2083 for (j = 0; j < vbif->qos_rt_tbl.npriority_lvl; j++) {
2084 vbif->qos_rt_tbl.priority_lvl[j] =
2085 PROP_VALUE_ACCESS(prop_value,
2086 VBIF_QOS_RT_REMAP, j);
2087 SDE_DEBUG("lvl[%d]=%u\n", j,
2088 vbif->qos_rt_tbl.priority_lvl[j]);
2089 }
2090
2091 vbif->qos_nrt_tbl.npriority_lvl =
2092 prop_count[VBIF_QOS_NRT_REMAP];
2093 SDE_DEBUG("qos_nrt_tbl.npriority_lvl=%u\n",
2094 vbif->qos_nrt_tbl.npriority_lvl);
2095
2096 if (vbif->qos_nrt_tbl.npriority_lvl == sde_cfg->vbif_qos_nlvl) {
2097 vbif->qos_nrt_tbl.priority_lvl = kcalloc(
2098 vbif->qos_nrt_tbl.npriority_lvl, sizeof(u32),
2099 GFP_KERNEL);
2100 if (!vbif->qos_nrt_tbl.priority_lvl) {
2101 rc = -ENOMEM;
2102 goto end;
2103 }
2104 } else if (vbif->qos_nrt_tbl.npriority_lvl) {
2105 vbif->qos_nrt_tbl.npriority_lvl = 0;
2106 vbif->qos_nrt_tbl.priority_lvl = NULL;
2107 SDE_ERROR("invalid qos nrt table\n");
2108 }
2109
2110 for (j = 0; j < vbif->qos_nrt_tbl.npriority_lvl; j++) {
2111 vbif->qos_nrt_tbl.priority_lvl[j] =
2112 PROP_VALUE_ACCESS(prop_value,
2113 VBIF_QOS_NRT_REMAP, j);
2114 SDE_DEBUG("lvl[%d]=%u\n", j,
2115 vbif->qos_nrt_tbl.priority_lvl[j]);
2116 }
2117
2118 if (vbif->qos_rt_tbl.npriority_lvl ||
2119 vbif->qos_nrt_tbl.npriority_lvl)
2120 set_bit(SDE_VBIF_QOS_REMAP, &vbif->features);
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04002121 }
2122
2123end:
Benet Clark37809e62016-10-24 10:14:00 -07002124 kfree(prop_value);
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04002125 return rc;
2126}
2127
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002128static int sde_pp_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg)
2129{
Benet Clark37809e62016-10-24 10:14:00 -07002130 int rc, prop_count[PP_PROP_MAX], i;
Clarence Ip613fd8a2016-11-29 19:01:39 -05002131 struct sde_prop_value *prop_value = NULL;
Benet Clark37809e62016-10-24 10:14:00 -07002132 bool prop_exists[PP_PROP_MAX];
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002133 u32 off_count;
2134 struct sde_pingpong_cfg *pp;
2135 struct sde_pingpong_sub_blks *sblk;
2136
2137 if (!sde_cfg) {
2138 SDE_ERROR("invalid argument\n");
2139 rc = -EINVAL;
2140 goto end;
2141 }
2142
Clarence Ip613fd8a2016-11-29 19:01:39 -05002143 prop_value = kzalloc(PP_PROP_MAX *
2144 sizeof(struct sde_prop_value), GFP_KERNEL);
Benet Clark37809e62016-10-24 10:14:00 -07002145 if (!prop_value) {
2146 rc = -ENOMEM;
2147 goto end;
2148 }
2149
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002150 rc = _validate_dt_entry(np, pp_prop, ARRAY_SIZE(pp_prop), prop_count,
2151 &off_count);
2152 if (rc)
2153 goto end;
2154
2155 sde_cfg->pingpong_count = off_count;
2156
2157 rc = _read_dt_entry(np, pp_prop, ARRAY_SIZE(pp_prop), prop_count,
Clarence Ip613fd8a2016-11-29 19:01:39 -05002158 prop_exists, prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002159 if (rc)
2160 goto end;
2161
2162 for (i = 0; i < off_count; i++) {
2163 pp = sde_cfg->pingpong + i;
2164 sblk = kzalloc(sizeof(*sblk), GFP_KERNEL);
2165 if (!sblk) {
2166 rc = -ENOMEM;
2167 /* catalog deinit will release the allocated blocks */
2168 goto end;
2169 }
2170 pp->sblk = sblk;
2171
Benet Clark37809e62016-10-24 10:14:00 -07002172 pp->base = PROP_VALUE_ACCESS(prop_value, PP_OFF, i);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002173 pp->id = PINGPONG_0 + i;
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -07002174 snprintf(pp->name, SDE_HW_BLK_NAME_LEN, "pingpong_%u",
2175 pp->id - PINGPONG_0);
Benet Clark37809e62016-10-24 10:14:00 -07002176 pp->len = PROP_VALUE_ACCESS(prop_value, PP_LEN, 0);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002177
Benet Clark37809e62016-10-24 10:14:00 -07002178 sblk->te.base = PROP_VALUE_ACCESS(prop_value, TE_OFF, i);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002179 sblk->te.id = SDE_PINGPONG_TE;
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -07002180 snprintf(sblk->te.name, SDE_HW_BLK_NAME_LEN, "te_%u",
2181 pp->id - PINGPONG_0);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002182 set_bit(SDE_PINGPONG_TE, &pp->features);
2183
Benet Clark37809e62016-10-24 10:14:00 -07002184 sblk->te2.base = PROP_VALUE_ACCESS(prop_value, TE2_OFF, i);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002185 if (sblk->te2.base) {
2186 sblk->te2.id = SDE_PINGPONG_TE2;
Lloyd Atkinson77158732016-10-23 13:02:00 -04002187 snprintf(sblk->te2.name, SDE_HW_BLK_NAME_LEN, "te2_%u",
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -07002188 pp->id - PINGPONG_0);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002189 set_bit(SDE_PINGPONG_TE2, &pp->features);
2190 set_bit(SDE_PINGPONG_SPLIT, &pp->features);
2191 }
2192
Clarence Ip8e69ad02016-12-09 09:43:57 -05002193 if (PROP_VALUE_ACCESS(prop_value, PP_SLAVE, i))
2194 set_bit(SDE_PINGPONG_SLAVE, &pp->features);
2195
Benet Clark37809e62016-10-24 10:14:00 -07002196 sblk->dsc.base = PROP_VALUE_ACCESS(prop_value, DSC_OFF, i);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002197 if (sblk->dsc.base) {
2198 sblk->dsc.id = SDE_PINGPONG_DSC;
Lloyd Atkinson77158732016-10-23 13:02:00 -04002199 snprintf(sblk->dsc.name, SDE_HW_BLK_NAME_LEN, "dsc_%u",
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -07002200 pp->id - PINGPONG_0);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002201 set_bit(SDE_PINGPONG_DSC, &pp->features);
2202 }
2203 }
2204
2205end:
Benet Clark37809e62016-10-24 10:14:00 -07002206 kfree(prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002207 return rc;
2208}
2209
2210static int sde_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg)
2211{
Jeykumar Sankaran2e655032017-02-04 14:05:45 -08002212 int rc, dma_rc, len, prop_count[SDE_PROP_MAX];
Clarence Ip613fd8a2016-11-29 19:01:39 -05002213 struct sde_prop_value *prop_value = NULL;
Benet Clark37809e62016-10-24 10:14:00 -07002214 bool prop_exists[SDE_PROP_MAX];
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002215 const char *type;
2216
2217 if (!cfg) {
2218 SDE_ERROR("invalid argument\n");
2219 rc = -EINVAL;
2220 goto end;
2221 }
2222
Clarence Ip613fd8a2016-11-29 19:01:39 -05002223 prop_value = kzalloc(SDE_PROP_MAX *
2224 sizeof(struct sde_prop_value), GFP_KERNEL);
Benet Clark37809e62016-10-24 10:14:00 -07002225 if (!prop_value) {
2226 rc = -ENOMEM;
2227 goto end;
2228 }
2229
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002230 rc = _validate_dt_entry(np, sde_prop, ARRAY_SIZE(sde_prop), prop_count,
2231 &len);
2232 if (rc)
2233 goto end;
2234
2235 rc = _read_dt_entry(np, sde_prop, ARRAY_SIZE(sde_prop), prop_count,
Clarence Ip613fd8a2016-11-29 19:01:39 -05002236 prop_exists, prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002237 if (rc)
2238 goto end;
2239
2240 cfg->mdss_count = 1;
2241 cfg->mdss[0].base = MDSS_BASE_OFFSET;
2242 cfg->mdss[0].id = MDP_TOP;
Lloyd Atkinson77158732016-10-23 13:02:00 -04002243 snprintf(cfg->mdss[0].name, SDE_HW_BLK_NAME_LEN, "mdss_%u",
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -07002244 cfg->mdss[0].id - MDP_TOP);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002245
2246 cfg->mdp_count = 1;
2247 cfg->mdp[0].id = MDP_TOP;
Lloyd Atkinson77158732016-10-23 13:02:00 -04002248 snprintf(cfg->mdp[0].name, SDE_HW_BLK_NAME_LEN, "top_%u",
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -07002249 cfg->mdp[0].id - MDP_TOP);
Benet Clark37809e62016-10-24 10:14:00 -07002250 cfg->mdp[0].base = PROP_VALUE_ACCESS(prop_value, SDE_OFF, 0);
2251 cfg->mdp[0].len = PROP_VALUE_ACCESS(prop_value, SDE_LEN, 0);
2252 if (!prop_exists[SDE_LEN])
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002253 cfg->mdp[0].len = DEFAULT_SDE_HW_BLOCK_LEN;
2254
Benet Clark37809e62016-10-24 10:14:00 -07002255 cfg->max_sspp_linewidth = PROP_VALUE_ACCESS(prop_value,
2256 SSPP_LINEWIDTH, 0);
2257 if (!prop_exists[SSPP_LINEWIDTH])
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002258 cfg->max_sspp_linewidth = DEFAULT_SDE_LINE_WIDTH;
2259
Benet Clark37809e62016-10-24 10:14:00 -07002260 cfg->max_mixer_width = PROP_VALUE_ACCESS(prop_value,
2261 MIXER_LINEWIDTH, 0);
2262 if (!prop_exists[MIXER_LINEWIDTH])
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002263 cfg->max_mixer_width = DEFAULT_SDE_LINE_WIDTH;
2264
Benet Clark37809e62016-10-24 10:14:00 -07002265 cfg->max_mixer_blendstages = PROP_VALUE_ACCESS(prop_value,
2266 MIXER_BLEND, 0);
2267 if (!prop_exists[MIXER_BLEND])
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002268 cfg->max_mixer_blendstages = DEFAULT_SDE_MIXER_BLENDSTAGES;
2269
Benet Clark37809e62016-10-24 10:14:00 -07002270 cfg->max_wb_linewidth = PROP_VALUE_ACCESS(prop_value, WB_LINEWIDTH, 0);
2271 if (!prop_exists[WB_LINEWIDTH])
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002272 cfg->max_wb_linewidth = DEFAULT_SDE_LINE_WIDTH;
2273
Benet Clark37809e62016-10-24 10:14:00 -07002274 cfg->mdp[0].highest_bank_bit = PROP_VALUE_ACCESS(prop_value,
2275 BANK_BIT, 0);
2276 if (!prop_exists[BANK_BIT])
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002277 cfg->mdp[0].highest_bank_bit = DEFAULT_SDE_HIGHEST_BANK_BIT;
2278
Clarence Ip32bcb002017-03-13 12:26:44 -07002279 cfg->ubwc_version = PROP_VALUE_ACCESS(prop_value, UBWC_VERSION, 0);
2280 if (!prop_exists[UBWC_VERSION])
2281 cfg->ubwc_version = DEFAULT_SDE_UBWC_VERSION;
2282
2283 cfg->mdp[0].ubwc_static = PROP_VALUE_ACCESS(prop_value, UBWC_STATIC, 0);
2284 if (!prop_exists[UBWC_STATIC])
2285 cfg->mdp[0].ubwc_static = DEFAULT_SDE_UBWC_STATIC;
2286
2287 cfg->mdp[0].ubwc_swizzle = PROP_VALUE_ACCESS(prop_value,
2288 UBWC_SWIZZLE, 0);
2289 if (!prop_exists[UBWC_SWIZZLE])
2290 cfg->mdp[0].ubwc_swizzle = DEFAULT_SDE_UBWC_SWIZZLE;
2291
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002292 rc = of_property_read_string(np, sde_prop[QSEED_TYPE].prop_name, &type);
Dhaval Patel0aee0972017-02-08 19:00:58 -08002293 if (!rc && !strcmp(type, "qseedv3")) {
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002294 cfg->qseed_type = SDE_SSPP_SCALER_QSEED3;
Dhaval Patel0aee0972017-02-08 19:00:58 -08002295 } else if (!rc && !strcmp(type, "qseedv2")) {
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002296 cfg->qseed_type = SDE_SSPP_SCALER_QSEED2;
Dhaval Patel0aee0972017-02-08 19:00:58 -08002297 } else if (rc) {
2298 SDE_DEBUG("invalid QSEED configuration\n");
2299 rc = 0;
2300 }
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002301
Dhaval Patel5aad7452017-01-12 09:59:31 -08002302 rc = of_property_read_string(np, sde_prop[CSC_TYPE].prop_name, &type);
Dhaval Patel0aee0972017-02-08 19:00:58 -08002303 if (!rc && !strcmp(type, "csc")) {
Dhaval Patel5aad7452017-01-12 09:59:31 -08002304 cfg->csc_type = SDE_SSPP_CSC;
Dhaval Patel0aee0972017-02-08 19:00:58 -08002305 } else if (!rc && !strcmp(type, "csc-10bit")) {
Dhaval Patel5aad7452017-01-12 09:59:31 -08002306 cfg->csc_type = SDE_SSPP_CSC_10BIT;
Dhaval Patel0aee0972017-02-08 19:00:58 -08002307 } else if (rc) {
2308 SDE_DEBUG("invalid csc configuration\n");
2309 rc = 0;
2310 }
Dhaval Patel5aad7452017-01-12 09:59:31 -08002311
Jeykumar Sankaran2e655032017-02-04 14:05:45 -08002312 /*
2313 * Current SDE support only Smart DMA 2.0.
2314 * No support for Smart DMA 1.0 yet.
2315 */
2316 cfg->smart_dma_rev = 0;
2317 dma_rc = of_property_read_string(np, sde_prop[SMART_DMA_REV].prop_name,
2318 &type);
2319 if (!dma_rc && !strcmp(type, "smart_dma_v2")) {
2320 cfg->smart_dma_rev = SDE_SSPP_SMART_DMA_V2;
2321 } else if (!dma_rc && !strcmp(type, "smart_dma_v1")) {
2322 SDE_ERROR("smart dma 1.0 is not supported in SDE\n");
2323 cfg->smart_dma_rev = 0;
2324 }
2325
Benet Clark37809e62016-10-24 10:14:00 -07002326 cfg->has_src_split = PROP_VALUE_ACCESS(prop_value, SRC_SPLIT, 0);
Veera Sundaram Sankaran3171ff82017-01-04 14:34:47 -08002327 cfg->has_dim_layer = PROP_VALUE_ACCESS(prop_value, DIM_LAYER, 0);
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002328 cfg->has_idle_pc = PROP_VALUE_ACCESS(prop_value, IDLE_PC, 0);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002329end:
Benet Clark37809e62016-10-24 10:14:00 -07002330 kfree(prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002331 return rc;
2332}
2333
Gopikrishnaiah Anandan031d8ff2016-12-15 16:58:45 -08002334static int sde_parse_reg_dma_dt(struct device_node *np,
2335 struct sde_mdss_cfg *sde_cfg)
2336{
2337 u32 val;
2338 int rc = 0;
2339 int i = 0;
2340
2341 sde_cfg->reg_dma_count = 0;
2342 for (i = 0; i < REG_DMA_PROP_MAX; i++) {
2343 rc = of_property_read_u32(np, reg_dma_prop[i].prop_name,
2344 &val);
2345 if (rc)
2346 break;
2347 switch (i) {
2348 case REG_DMA_OFF:
2349 sde_cfg->dma_cfg.base = val;
2350 break;
2351 case REG_DMA_VERSION:
2352 sde_cfg->dma_cfg.version = val;
2353 break;
2354 case REG_DMA_TRIGGER_OFF:
2355 sde_cfg->dma_cfg.trigger_sel_off = val;
2356 break;
2357 default:
2358 break;
2359 }
2360 }
2361 if (!rc && i == REG_DMA_PROP_MAX)
2362 sde_cfg->reg_dma_count = 1;
2363 /* reg dma is optional feature hence return 0 */
2364 return 0;
2365}
2366
Alan Kwong9aa061c2016-11-06 21:17:12 -05002367static int sde_perf_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg)
2368{
2369 int rc, len, prop_count[PERF_PROP_MAX];
2370 struct sde_prop_value *prop_value = NULL;
2371 bool prop_exists[PERF_PROP_MAX];
Alan Kwong6259a382017-04-04 06:18:02 -07002372 const char *str = NULL;
Alan Kwongdce56da2017-04-27 15:50:34 -07002373 int j, k;
Alan Kwong9aa061c2016-11-06 21:17:12 -05002374
2375 if (!cfg) {
2376 SDE_ERROR("invalid argument\n");
2377 rc = -EINVAL;
2378 goto end;
2379 }
2380
2381 prop_value = kzalloc(SDE_PROP_MAX *
2382 sizeof(struct sde_prop_value), GFP_KERNEL);
2383 if (!prop_value) {
2384 rc = -ENOMEM;
2385 goto end;
2386 }
2387
2388 rc = _validate_dt_entry(np, sde_perf_prop, ARRAY_SIZE(sde_perf_prop),
2389 prop_count, &len);
2390 if (rc)
2391 goto freeprop;
2392
Alan Kwongdce56da2017-04-27 15:50:34 -07002393 rc = _validate_dt_entry(np, &sde_perf_prop[PERF_DANGER_LUT], 1,
2394 &prop_count[PERF_DANGER_LUT], NULL);
2395 if (rc)
2396 goto freeprop;
2397
2398 rc = _validate_dt_entry(np, &sde_perf_prop[PERF_SAFE_LUT], 1,
2399 &prop_count[PERF_SAFE_LUT], NULL);
2400 if (rc)
2401 goto freeprop;
2402
2403 rc = _validate_dt_entry(np, &sde_perf_prop[PERF_QOS_LUT_LINEAR], 1,
2404 &prop_count[PERF_QOS_LUT_LINEAR], NULL);
2405 if (rc)
2406 goto freeprop;
2407
2408 rc = _validate_dt_entry(np, &sde_perf_prop[PERF_QOS_LUT_MACROTILE], 1,
2409 &prop_count[PERF_QOS_LUT_MACROTILE], NULL);
2410 if (rc)
2411 goto freeprop;
2412
2413 rc = _validate_dt_entry(np, &sde_perf_prop[PERF_QOS_LUT_NRT], 1,
2414 &prop_count[PERF_QOS_LUT_NRT], NULL);
2415 if (rc)
2416 goto freeprop;
2417
2418 rc = _validate_dt_entry(np, &sde_perf_prop[PERF_QOS_LUT_CWB], 1,
2419 &prop_count[PERF_QOS_LUT_CWB], NULL);
2420 if (rc)
2421 goto freeprop;
2422
Alan Kwong9aa061c2016-11-06 21:17:12 -05002423 rc = _read_dt_entry(np, sde_perf_prop, ARRAY_SIZE(sde_perf_prop),
2424 prop_count, prop_exists, prop_value);
2425 if (rc)
2426 goto freeprop;
2427
2428 cfg->perf.max_bw_low =
Alan Kwong6259a382017-04-04 06:18:02 -07002429 prop_exists[PERF_MAX_BW_LOW] ?
2430 PROP_VALUE_ACCESS(prop_value, PERF_MAX_BW_LOW, 0) :
2431 DEFAULT_MAX_BW_LOW;
Alan Kwong9aa061c2016-11-06 21:17:12 -05002432 cfg->perf.max_bw_high =
Alan Kwong6259a382017-04-04 06:18:02 -07002433 prop_exists[PERF_MAX_BW_HIGH] ?
2434 PROP_VALUE_ACCESS(prop_value, PERF_MAX_BW_HIGH, 0) :
2435 DEFAULT_MAX_BW_HIGH;
2436
2437 /*
2438 * The following performance parameters (e.g. core_ib_ff) are
2439 * mapped directly as device tree string constants.
2440 */
2441 rc = of_property_read_string(np,
2442 sde_perf_prop[PERF_CORE_IB_FF].prop_name, &str);
2443 cfg->perf.core_ib_ff = rc ? DEFAULT_CORE_IB_FF : str;
2444 rc = of_property_read_string(np,
2445 sde_perf_prop[PERF_CORE_CLK_FF].prop_name, &str);
2446 cfg->perf.core_clk_ff = rc ? DEFAULT_CORE_CLK_FF : str;
2447 rc = of_property_read_string(np,
2448 sde_perf_prop[PERF_COMP_RATIO_RT].prop_name, &str);
2449 cfg->perf.comp_ratio_rt = rc ? DEFAULT_COMP_RATIO_RT : str;
2450 rc = of_property_read_string(np,
2451 sde_perf_prop[PERF_COMP_RATIO_NRT].prop_name, &str);
2452 cfg->perf.comp_ratio_nrt = rc ? DEFAULT_COMP_RATIO_NRT : str;
2453 rc = 0;
2454
2455 cfg->perf.undersized_prefill_lines =
2456 prop_exists[PERF_UNDERSIZED_PREFILL_LINES] ?
2457 PROP_VALUE_ACCESS(prop_value,
2458 PERF_UNDERSIZED_PREFILL_LINES, 0) :
2459 DEFAULT_UNDERSIZED_PREFILL_LINES;
2460 cfg->perf.xtra_prefill_lines =
2461 prop_exists[PERF_XTRA_PREFILL_LINES] ?
2462 PROP_VALUE_ACCESS(prop_value,
2463 PERF_XTRA_PREFILL_LINES, 0) :
2464 DEFAULT_XTRA_PREFILL_LINES;
2465 cfg->perf.dest_scale_prefill_lines =
2466 prop_exists[PERF_DEST_SCALE_PREFILL_LINES] ?
2467 PROP_VALUE_ACCESS(prop_value,
2468 PERF_DEST_SCALE_PREFILL_LINES, 0) :
2469 DEFAULT_DEST_SCALE_PREFILL_LINES;
2470 cfg->perf.macrotile_prefill_lines =
2471 prop_exists[PERF_MACROTILE_PREFILL_LINES] ?
2472 PROP_VALUE_ACCESS(prop_value,
2473 PERF_MACROTILE_PREFILL_LINES, 0) :
2474 DEFAULT_MACROTILE_PREFILL_LINES;
2475 cfg->perf.yuv_nv12_prefill_lines =
2476 prop_exists[PERF_YUV_NV12_PREFILL_LINES] ?
2477 PROP_VALUE_ACCESS(prop_value,
2478 PERF_YUV_NV12_PREFILL_LINES, 0) :
2479 DEFAULT_YUV_NV12_PREFILL_LINES;
2480 cfg->perf.linear_prefill_lines =
2481 prop_exists[PERF_LINEAR_PREFILL_LINES] ?
2482 PROP_VALUE_ACCESS(prop_value,
2483 PERF_LINEAR_PREFILL_LINES, 0) :
2484 DEFAULT_LINEAR_PREFILL_LINES;
2485 cfg->perf.downscaling_prefill_lines =
2486 prop_exists[PERF_DOWNSCALING_PREFILL_LINES] ?
2487 PROP_VALUE_ACCESS(prop_value,
2488 PERF_DOWNSCALING_PREFILL_LINES, 0) :
2489 DEFAULT_DOWNSCALING_PREFILL_LINES;
2490 cfg->perf.amortizable_threshold =
2491 prop_exists[PERF_AMORTIZABLE_THRESHOLD] ?
2492 PROP_VALUE_ACCESS(prop_value,
2493 PERF_AMORTIZABLE_THRESHOLD, 0) :
2494 DEFAULT_AMORTIZABLE_THRESHOLD;
Alan Kwong9aa061c2016-11-06 21:17:12 -05002495
Alan Kwongdce56da2017-04-27 15:50:34 -07002496 if (prop_exists[PERF_DANGER_LUT] && prop_count[PERF_DANGER_LUT] <=
2497 SDE_QOS_LUT_USAGE_MAX) {
2498 for (j = 0; j < prop_count[PERF_DANGER_LUT]; j++) {
2499 cfg->perf.danger_lut_tbl[j] =
2500 PROP_VALUE_ACCESS(prop_value,
2501 PERF_DANGER_LUT, j);
2502 SDE_DEBUG("danger usage:%d lut:0x%x\n",
2503 j, cfg->perf.danger_lut_tbl[j]);
2504 }
2505 }
2506
2507 if (prop_exists[PERF_SAFE_LUT] && prop_count[PERF_SAFE_LUT] <=
2508 SDE_QOS_LUT_USAGE_MAX) {
2509 for (j = 0; j < prop_count[PERF_SAFE_LUT]; j++) {
2510 cfg->perf.safe_lut_tbl[j] =
2511 PROP_VALUE_ACCESS(prop_value,
2512 PERF_SAFE_LUT, j);
2513 SDE_DEBUG("safe usage:%d lut:0x%x\n",
2514 j, cfg->perf.safe_lut_tbl[j]);
2515 }
2516 }
2517
2518 for (j = 0; j < SDE_QOS_LUT_USAGE_MAX; j++) {
2519 static const u32 prop_key[SDE_QOS_LUT_USAGE_MAX] = {
2520 [SDE_QOS_LUT_USAGE_LINEAR] =
2521 PERF_QOS_LUT_LINEAR,
2522 [SDE_QOS_LUT_USAGE_MACROTILE] =
2523 PERF_QOS_LUT_MACROTILE,
2524 [SDE_QOS_LUT_USAGE_NRT] =
2525 PERF_QOS_LUT_NRT,
2526 [SDE_QOS_LUT_USAGE_CWB] =
2527 PERF_QOS_LUT_CWB,
2528 };
2529 const u32 entry_size = 3;
2530 int m, count;
2531 int key = prop_key[j];
2532
2533 if (!prop_exists[key])
2534 continue;
2535
2536 count = prop_count[key] / entry_size;
2537
2538 cfg->perf.qos_lut_tbl[j].entries = kcalloc(count,
2539 sizeof(struct sde_qos_lut_entry), GFP_KERNEL);
2540 if (!cfg->perf.qos_lut_tbl[j].entries) {
2541 rc = -ENOMEM;
2542 goto end;
2543 }
2544
2545 for (k = 0, m = 0; k < count; k++, m += entry_size) {
2546 u64 lut_hi, lut_lo;
2547
2548 cfg->perf.qos_lut_tbl[j].entries[k].fl =
2549 PROP_VALUE_ACCESS(prop_value, key, m);
2550 lut_hi = PROP_VALUE_ACCESS(prop_value, key, m + 1);
2551 lut_lo = PROP_VALUE_ACCESS(prop_value, key, m + 2);
2552 cfg->perf.qos_lut_tbl[j].entries[k].lut =
2553 (lut_hi << 32) | lut_lo;
2554 SDE_DEBUG("usage:%d.%d fl:%d lut:0x%llx\n",
2555 j, k,
2556 cfg->perf.qos_lut_tbl[j].entries[k].fl,
2557 cfg->perf.qos_lut_tbl[j].entries[k].lut);
2558 }
2559 cfg->perf.qos_lut_tbl[j].nentry = count;
2560 }
2561
Alan Kwong9aa061c2016-11-06 21:17:12 -05002562freeprop:
2563 kfree(prop_value);
2564end:
2565 return rc;
2566}
2567
abeykunf35ff332016-12-20 13:06:09 -05002568static int sde_hardware_format_caps(struct sde_mdss_cfg *sde_cfg,
2569 uint32_t hw_rev)
Dhaval Patel1964fb92016-10-13 19:28:08 -07002570{
Clarence Ip32bcb002017-03-13 12:26:44 -07002571 int rc = 0;
abeykunf35ff332016-12-20 13:06:09 -05002572 uint32_t dma_list_size, vig_list_size, wb2_list_size;
2573 uint32_t cursor_list_size = 0;
abeykunf35ff332016-12-20 13:06:09 -05002574 uint32_t index = 0;
2575
2576 if (IS_SDE_MAJOR_MINOR_SAME((hw_rev), SDE_HW_VER_300)) {
2577 cursor_list_size = ARRAY_SIZE(cursor_formats);
2578 sde_cfg->cursor_formats = kcalloc(cursor_list_size,
2579 sizeof(struct sde_format_extended), GFP_KERNEL);
2580 if (!sde_cfg->cursor_formats) {
2581 rc = -ENOMEM;
2582 goto end;
2583 }
Jeykumar Sankaranf55e65b2017-05-10 21:46:14 -07002584 index = sde_copy_formats(sde_cfg->cursor_formats,
abeykunf35ff332016-12-20 13:06:09 -05002585 cursor_list_size, 0, cursor_formats,
2586 ARRAY_SIZE(cursor_formats));
2587 }
2588
2589 dma_list_size = ARRAY_SIZE(plane_formats);
2590 vig_list_size = ARRAY_SIZE(plane_formats_yuv);
2591 wb2_list_size = ARRAY_SIZE(wb2_formats);
2592
2593 dma_list_size += ARRAY_SIZE(rgb_10bit_formats);
2594 vig_list_size += ARRAY_SIZE(rgb_10bit_formats)
2595 + ARRAY_SIZE(tp10_ubwc_formats)
2596 + ARRAY_SIZE(p010_formats);
abeykund2debcb2016-12-20 13:06:09 -05002597 if (IS_SDE_MAJOR_MINOR_SAME((hw_rev), SDE_HW_VER_400))
2598 vig_list_size += ARRAY_SIZE(p010_ubwc_formats);
2599
abeykunf35ff332016-12-20 13:06:09 -05002600 wb2_list_size += ARRAY_SIZE(rgb_10bit_formats)
2601 + ARRAY_SIZE(tp10_ubwc_formats);
2602
2603 sde_cfg->dma_formats = kcalloc(dma_list_size,
2604 sizeof(struct sde_format_extended), GFP_KERNEL);
2605 if (!sde_cfg->dma_formats) {
2606 rc = -ENOMEM;
2607 goto end;
2608 }
2609
2610 sde_cfg->vig_formats = kcalloc(vig_list_size,
2611 sizeof(struct sde_format_extended), GFP_KERNEL);
2612 if (!sde_cfg->vig_formats) {
2613 rc = -ENOMEM;
2614 goto end;
2615 }
2616
2617 sde_cfg->wb_formats = kcalloc(wb2_list_size,
2618 sizeof(struct sde_format_extended), GFP_KERNEL);
2619 if (!sde_cfg->wb_formats) {
2620 SDE_ERROR("failed to allocate wb format list\n");
2621 rc = -ENOMEM;
2622 goto end;
2623 }
2624
Jeykumar Sankaranf55e65b2017-05-10 21:46:14 -07002625 index = sde_copy_formats(sde_cfg->dma_formats, dma_list_size,
abeykunf35ff332016-12-20 13:06:09 -05002626 0, plane_formats, ARRAY_SIZE(plane_formats));
Jeykumar Sankaranf55e65b2017-05-10 21:46:14 -07002627 index += sde_copy_formats(sde_cfg->dma_formats, dma_list_size,
abeykunf35ff332016-12-20 13:06:09 -05002628 index, rgb_10bit_formats,
2629 ARRAY_SIZE(rgb_10bit_formats));
2630
Jeykumar Sankaranf55e65b2017-05-10 21:46:14 -07002631 index = sde_copy_formats(sde_cfg->vig_formats, vig_list_size,
abeykunf35ff332016-12-20 13:06:09 -05002632 0, plane_formats_yuv, ARRAY_SIZE(plane_formats_yuv));
Jeykumar Sankaranf55e65b2017-05-10 21:46:14 -07002633 index += sde_copy_formats(sde_cfg->vig_formats, vig_list_size,
abeykunf35ff332016-12-20 13:06:09 -05002634 index, rgb_10bit_formats,
2635 ARRAY_SIZE(rgb_10bit_formats));
Jeykumar Sankaranf55e65b2017-05-10 21:46:14 -07002636 index += sde_copy_formats(sde_cfg->vig_formats, vig_list_size,
abeykunf35ff332016-12-20 13:06:09 -05002637 index, p010_formats, ARRAY_SIZE(p010_formats));
abeykund2debcb2016-12-20 13:06:09 -05002638 if (IS_SDE_MAJOR_MINOR_SAME((hw_rev), SDE_HW_VER_400))
Jeykumar Sankaranf55e65b2017-05-10 21:46:14 -07002639 index += sde_copy_formats(sde_cfg->vig_formats,
abeykund2debcb2016-12-20 13:06:09 -05002640 vig_list_size, index, p010_ubwc_formats,
2641 ARRAY_SIZE(p010_ubwc_formats));
abeykunf35ff332016-12-20 13:06:09 -05002642
Jeykumar Sankaranf55e65b2017-05-10 21:46:14 -07002643 index += sde_copy_formats(sde_cfg->vig_formats, vig_list_size,
abeykunf35ff332016-12-20 13:06:09 -05002644 index, tp10_ubwc_formats,
2645 ARRAY_SIZE(tp10_ubwc_formats));
2646
Jeykumar Sankaranf55e65b2017-05-10 21:46:14 -07002647 index = sde_copy_formats(sde_cfg->wb_formats, wb2_list_size,
abeykunf35ff332016-12-20 13:06:09 -05002648 0, wb2_formats, ARRAY_SIZE(wb2_formats));
Jeykumar Sankaranf55e65b2017-05-10 21:46:14 -07002649 index += sde_copy_formats(sde_cfg->wb_formats, wb2_list_size,
abeykunf35ff332016-12-20 13:06:09 -05002650 index, rgb_10bit_formats,
2651 ARRAY_SIZE(rgb_10bit_formats));
Jeykumar Sankaranf55e65b2017-05-10 21:46:14 -07002652 index += sde_copy_formats(sde_cfg->wb_formats, wb2_list_size,
abeykunf35ff332016-12-20 13:06:09 -05002653 index, tp10_ubwc_formats,
2654 ARRAY_SIZE(tp10_ubwc_formats));
abeykunf35ff332016-12-20 13:06:09 -05002655end:
2656 return rc;
2657}
2658
Clarence Ip32bcb002017-03-13 12:26:44 -07002659static int _sde_hardware_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev)
abeykunf35ff332016-12-20 13:06:09 -05002660{
2661 int rc = 0;
2662
Clarence Ip32bcb002017-03-13 12:26:44 -07002663 if (!sde_cfg)
2664 return -EINVAL;
2665
Dhaval Patel5398f602017-03-25 18:25:18 -07002666 rc = sde_hardware_format_caps(sde_cfg, hw_rev);
2667
Dhaval Patel1964fb92016-10-13 19:28:08 -07002668 switch (hw_rev) {
2669 case SDE_HW_VER_170:
2670 case SDE_HW_VER_171:
2671 case SDE_HW_VER_172:
2672 /* update msm8996 target here */
Alan Kwong6259a382017-04-04 06:18:02 -07002673 sde_cfg->perf.min_prefill_lines = 21;
Dhaval Patel1964fb92016-10-13 19:28:08 -07002674 break;
2675 case SDE_HW_VER_300:
abeykunf35ff332016-12-20 13:06:09 -05002676 case SDE_HW_VER_301:
Alan Kwong6259a382017-04-04 06:18:02 -07002677 /* update msm8998 target here */
2678 sde_cfg->has_wb_ubwc = true;
2679 sde_cfg->perf.min_prefill_lines = 25;
Alan Kwonga62eeb82017-04-19 08:57:55 -07002680 sde_cfg->vbif_qos_nlvl = 4;
Alan Kwong2349d742017-04-20 08:27:30 -07002681 sde_cfg->ts_prefill_rev = 1;
2682 sde_cfg->perf.min_prefill_lines = 25;
Alan Kwong6259a382017-04-04 06:18:02 -07002683 break;
Dhaval Patel1964fb92016-10-13 19:28:08 -07002684 case SDE_HW_VER_400:
Alan Kwonga62eeb82017-04-19 08:57:55 -07002685 /* update sdm845 target here */
Clarence Ip32bcb002017-03-13 12:26:44 -07002686 sde_cfg->has_wb_ubwc = true;
Alan Kwong6259a382017-04-04 06:18:02 -07002687 sde_cfg->perf.min_prefill_lines = 24;
Alan Kwonga62eeb82017-04-19 08:57:55 -07002688 sde_cfg->vbif_qos_nlvl = 8;
Alan Kwong2349d742017-04-20 08:27:30 -07002689 sde_cfg->ts_prefill_rev = 2;
2690 sde_cfg->perf.min_prefill_lines = 24;
Dhaval Patel1964fb92016-10-13 19:28:08 -07002691 break;
Dhaval Patel5398f602017-03-25 18:25:18 -07002692 default:
Alan Kwong6259a382017-04-04 06:18:02 -07002693 sde_cfg->perf.min_prefill_lines = 0xffff;
Dhaval Patel5398f602017-03-25 18:25:18 -07002694 break;
Dhaval Patel1964fb92016-10-13 19:28:08 -07002695 }
abeykunf35ff332016-12-20 13:06:09 -05002696
2697 return rc;
Dhaval Patel1964fb92016-10-13 19:28:08 -07002698}
2699
Clarence Ip17162b52016-11-24 17:06:29 -05002700void sde_hw_catalog_deinit(struct sde_mdss_cfg *sde_cfg)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -07002701{
2702 int i;
2703
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002704 if (!sde_cfg)
2705 return;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -07002706
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002707 for (i = 0; i < sde_cfg->sspp_count; i++)
2708 kfree(sde_cfg->sspp[i].sblk);
2709
2710 for (i = 0; i < sde_cfg->mixer_count; i++)
2711 kfree(sde_cfg->mixer[i].sblk);
2712
2713 for (i = 0; i < sde_cfg->wb_count; i++)
2714 kfree(sde_cfg->wb[i].sblk);
2715
2716 for (i = 0; i < sde_cfg->dspp_count; i++)
2717 kfree(sde_cfg->dspp[i].sblk);
2718
2719 for (i = 0; i < sde_cfg->pingpong_count; i++)
2720 kfree(sde_cfg->pingpong[i].sblk);
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04002721
2722 for (i = 0; i < sde_cfg->vbif_count; i++) {
2723 kfree(sde_cfg->vbif[i].dynamic_ot_rd_tbl.cfg);
2724 kfree(sde_cfg->vbif[i].dynamic_ot_wr_tbl.cfg);
Alan Kwonga62eeb82017-04-19 08:57:55 -07002725 kfree(sde_cfg->vbif[i].qos_rt_tbl.priority_lvl);
2726 kfree(sde_cfg->vbif[i].qos_nrt_tbl.priority_lvl);
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04002727 }
abeykunf35ff332016-12-20 13:06:09 -05002728
Alan Kwongdce56da2017-04-27 15:50:34 -07002729 for (i = 0; i < SDE_QOS_LUT_USAGE_MAX; i++)
2730 kfree(sde_cfg->perf.qos_lut_tbl[i].entries);
2731
abeykunf35ff332016-12-20 13:06:09 -05002732 kfree(sde_cfg->dma_formats);
2733 kfree(sde_cfg->cursor_formats);
2734 kfree(sde_cfg->vig_formats);
2735 kfree(sde_cfg->wb_formats);
2736
Clarence Ip17162b52016-11-24 17:06:29 -05002737 kfree(sde_cfg);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002738}
2739
2740/*************************************************************
2741 * hardware catalog init
2742 *************************************************************/
2743struct sde_mdss_cfg *sde_hw_catalog_init(struct drm_device *dev, u32 hw_rev)
2744{
2745 int rc;
2746 struct sde_mdss_cfg *sde_cfg;
2747 struct device_node *np = dev->dev->of_node;
2748
2749 sde_cfg = kzalloc(sizeof(*sde_cfg), GFP_KERNEL);
2750 if (!sde_cfg)
2751 return ERR_PTR(-ENOMEM);
2752
2753 sde_cfg->hwversion = hw_rev;
2754
Clarence Ip32bcb002017-03-13 12:26:44 -07002755 rc = _sde_hardware_caps(sde_cfg, hw_rev);
2756 if (rc)
2757 goto end;
2758
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002759 rc = sde_parse_dt(np, sde_cfg);
2760 if (rc)
2761 goto end;
2762
Alan Kwong4dd64c82017-02-04 18:41:51 -08002763 rc = sde_rot_parse_dt(np, sde_cfg);
2764 if (rc)
2765 goto end;
2766
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002767 rc = sde_ctl_parse_dt(np, sde_cfg);
2768 if (rc)
2769 goto end;
2770
2771 rc = sde_sspp_parse_dt(np, sde_cfg);
2772 if (rc)
2773 goto end;
2774
2775 rc = sde_dspp_parse_dt(np, sde_cfg);
2776 if (rc)
2777 goto end;
2778
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08002779 rc = sde_dsc_parse_dt(np, sde_cfg);
2780 if (rc)
2781 goto end;
2782
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002783 rc = sde_pp_parse_dt(np, sde_cfg);
2784 if (rc)
2785 goto end;
2786
2787 /* mixer parsing should be done after dspp and pp for mapping setup */
2788 rc = sde_mixer_parse_dt(np, sde_cfg);
2789 if (rc)
2790 goto end;
2791
2792 rc = sde_intf_parse_dt(np, sde_cfg);
2793 if (rc)
2794 goto end;
2795
2796 rc = sde_wb_parse_dt(np, sde_cfg);
2797 if (rc)
2798 goto end;
2799
2800 /* cdm parsing should be done after intf and wb for mapping setup */
2801 rc = sde_cdm_parse_dt(np, sde_cfg);
2802 if (rc)
2803 goto end;
2804
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04002805 rc = sde_vbif_parse_dt(np, sde_cfg);
2806 if (rc)
2807 goto end;
2808
Gopikrishnaiah Anandan031d8ff2016-12-15 16:58:45 -08002809 rc = sde_parse_reg_dma_dt(np, sde_cfg);
2810 if (rc)
2811 goto end;
2812
Alan Kwong9aa061c2016-11-06 21:17:12 -05002813 rc = sde_perf_parse_dt(np, sde_cfg);
2814 if (rc)
2815 goto end;
2816
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002817 return sde_cfg;
2818
2819end:
2820 sde_hw_catalog_deinit(sde_cfg);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002821 return NULL;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -07002822}