blob: 0e1ab5121f6c0ce509060b686a584b5aec0d4bb4 [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
Dhaval Patele4da9d742017-06-19 16:51:21 -070030 * can have QSEED, pcc, igc, pa, csc, qos entries, etc. This count is
31 * 64 based on software design. It should be increased if any of the
Dhaval Patel8bf7ff32016-07-20 18:13:24 -070032 * hardware block has more subblocks.
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070033 */
Dhaval Patele4da9d742017-06-19 16:51:21 -070034#define MAX_SDE_HW_BLK 64
Dhaval Patel8bf7ff32016-07-20 18:13:24 -070035
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,
Dhaval Patel1964fb92016-10-13 19:28:08 -0700139 SRC_SPLIT,
Veera Sundaram Sankaran3171ff82017-01-04 14:34:47 -0800140 DIM_LAYER,
Jeykumar Sankaran2e655032017-02-04 14:05:45 -0800141 SMART_DMA_REV,
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700142 IDLE_PC,
Benet Clark37809e62016-10-24 10:14:00 -0700143 SDE_PROP_MAX,
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700144};
145
146enum {
Alan Kwong9aa061c2016-11-06 21:17:12 -0500147 PERF_MAX_BW_LOW,
148 PERF_MAX_BW_HIGH,
Alan Kwong6259a382017-04-04 06:18:02 -0700149 PERF_CORE_IB_FF,
150 PERF_CORE_CLK_FF,
151 PERF_COMP_RATIO_RT,
152 PERF_COMP_RATIO_NRT,
153 PERF_UNDERSIZED_PREFILL_LINES,
154 PERF_DEST_SCALE_PREFILL_LINES,
155 PERF_MACROTILE_PREFILL_LINES,
156 PERF_YUV_NV12_PREFILL_LINES,
157 PERF_LINEAR_PREFILL_LINES,
158 PERF_DOWNSCALING_PREFILL_LINES,
159 PERF_XTRA_PREFILL_LINES,
160 PERF_AMORTIZABLE_THRESHOLD,
Alan Kwongdce56da2017-04-27 15:50:34 -0700161 PERF_DANGER_LUT,
162 PERF_SAFE_LUT,
163 PERF_QOS_LUT_LINEAR,
164 PERF_QOS_LUT_MACROTILE,
165 PERF_QOS_LUT_NRT,
166 PERF_QOS_LUT_CWB,
Alan Kwong143f50c2017-04-28 07:34:28 -0700167 PERF_CDP_SETTING,
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,
Ping Li8430ee12017-02-24 14:14:44 -0800220 DITHER_OFF,
221 DITHER_LEN,
222 DITHER_VER,
Benet Clark37809e62016-10-24 10:14:00 -0700223 PP_PROP_MAX,
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700224};
225
226enum {
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800227 DSC_OFF,
228 DSC_LEN,
229 DSC_PROP_MAX,
230};
231
232enum {
Rajesh Yadavec93afb2017-06-08 19:28:33 +0530233 DSPP_TOP_OFF,
234 DSPP_TOP_SIZE,
235 DSPP_TOP_PROP_MAX,
236};
237
238enum {
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700239 DSPP_OFF,
240 DSPP_SIZE,
Benet Clark37809e62016-10-24 10:14:00 -0700241 DSPP_BLOCKS,
242 DSPP_PROP_MAX,
243};
244
245enum {
246 DSPP_IGC_PROP,
247 DSPP_PCC_PROP,
248 DSPP_GC_PROP,
249 DSPP_HSIC_PROP,
250 DSPP_MEMCOLOR_PROP,
251 DSPP_SIXZONE_PROP,
252 DSPP_GAMUT_PROP,
253 DSPP_DITHER_PROP,
254 DSPP_HIST_PROP,
255 DSPP_VLUT_PROP,
256 DSPP_BLOCKS_PROP_MAX,
257};
258
259enum {
260 AD_OFF,
261 AD_VERSION,
262 AD_PROP_MAX,
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700263};
264
265enum {
266 MIXER_OFF,
267 MIXER_LEN,
Veera Sundaram Sankaran370b9912017-01-10 18:03:42 -0800268 MIXER_PAIR_MASK,
Benet Clark37809e62016-10-24 10:14:00 -0700269 MIXER_BLOCKS,
270 MIXER_PROP_MAX,
271};
272
273enum {
274 MIXER_GC_PROP,
275 MIXER_BLOCKS_PROP_MAX,
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700276};
277
278enum {
Veera Sundaram Sankaran370b9912017-01-10 18:03:42 -0800279 MIXER_BLEND_OP_OFF,
280 MIXER_BLEND_PROP_MAX,
281};
282
283enum {
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700284 WB_OFF,
285 WB_LEN,
Alan Kwong14627332016-10-12 16:44:00 -0400286 WB_ID,
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700287 WB_XIN_ID,
Alan Kwong04780ec2016-10-12 16:05:17 -0400288 WB_CLK_CTRL,
Benet Clark37809e62016-10-24 10:14:00 -0700289 WB_PROP_MAX,
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700290};
291
Alan Kwongb9d2f6f2016-10-12 00:27:07 -0400292enum {
293 VBIF_OFF,
294 VBIF_LEN,
295 VBIF_ID,
296 VBIF_DEFAULT_OT_RD_LIMIT,
297 VBIF_DEFAULT_OT_WR_LIMIT,
298 VBIF_DYNAMIC_OT_RD_LIMIT,
299 VBIF_DYNAMIC_OT_WR_LIMIT,
Alan Kwonga62eeb82017-04-19 08:57:55 -0700300 VBIF_QOS_RT_REMAP,
301 VBIF_QOS_NRT_REMAP,
Clarence Ip7f0de632017-05-31 14:59:14 -0400302 VBIF_MEMTYPE_0,
303 VBIF_MEMTYPE_1,
Benet Clark37809e62016-10-24 10:14:00 -0700304 VBIF_PROP_MAX,
Alan Kwongb9d2f6f2016-10-12 00:27:07 -0400305};
306
Gopikrishnaiah Anandan031d8ff2016-12-15 16:58:45 -0800307enum {
308 REG_DMA_OFF,
309 REG_DMA_VERSION,
310 REG_DMA_TRIGGER_OFF,
311 REG_DMA_PROP_MAX
312};
313
Veera Sundaram Sankaran1e71ccb2017-05-24 18:48:50 -0700314enum {
315 INLINE_ROT_XIN,
316 INLINE_ROT_XIN_TYPE,
317 INLINE_ROT_CLK_CTRL,
318 INLINE_ROT_PROP_MAX
319};
320
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700321/*************************************************************
322 * dts property definition
323 *************************************************************/
324enum prop_type {
325 PROP_TYPE_BOOL,
326 PROP_TYPE_U32,
327 PROP_TYPE_U32_ARRAY,
328 PROP_TYPE_STRING,
329 PROP_TYPE_STRING_ARRAY,
330 PROP_TYPE_BIT_OFFSET_ARRAY,
Benet Clark37809e62016-10-24 10:14:00 -0700331 PROP_TYPE_NODE,
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700332};
333
334struct sde_prop_type {
335 /* use property index from enum property for readability purpose */
336 u8 id;
337 /* it should be property name based on dtsi documentation */
338 char *prop_name;
339 /**
340 * if property is marked mandatory then it will fail parsing
341 * when property is not present
342 */
343 u32 is_mandatory;
344 /* property type based on "enum prop_type" */
345 enum prop_type type;
346};
347
Clarence Ip613fd8a2016-11-29 19:01:39 -0500348struct sde_prop_value {
349 u32 value[MAX_SDE_HW_BLK];
350 u32 bit_value[MAX_SDE_HW_BLK][MAX_BIT_OFFSET];
351};
352
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700353/*************************************************************
354 * dts property list
355 *************************************************************/
356static struct sde_prop_type sde_prop[] = {
357 {SDE_OFF, "qcom,sde-off", true, PROP_TYPE_U32},
358 {SDE_LEN, "qcom,sde-len", false, PROP_TYPE_U32},
359 {SSPP_LINEWIDTH, "qcom,sde-sspp-linewidth", false, PROP_TYPE_U32},
360 {MIXER_LINEWIDTH, "qcom,sde-mixer-linewidth", false, PROP_TYPE_U32},
361 {MIXER_BLEND, "qcom,sde-mixer-blendstages", false, PROP_TYPE_U32},
362 {WB_LINEWIDTH, "qcom,sde-wb-linewidth", false, PROP_TYPE_U32},
363 {BANK_BIT, "qcom,sde-highest-bank-bit", false, PROP_TYPE_U32},
Clarence Ip32bcb002017-03-13 12:26:44 -0700364 {UBWC_VERSION, "qcom,sde-ubwc-version", false, PROP_TYPE_U32},
365 {UBWC_STATIC, "qcom,sde-ubwc-static", false, PROP_TYPE_U32},
366 {UBWC_SWIZZLE, "qcom,sde-ubwc-swizzle", false, PROP_TYPE_U32},
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700367 {QSEED_TYPE, "qcom,sde-qseed-type", false, PROP_TYPE_STRING},
Dhaval Patel5aad7452017-01-12 09:59:31 -0800368 {CSC_TYPE, "qcom,sde-csc-type", false, PROP_TYPE_STRING},
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700369 {PANIC_PER_PIPE, "qcom,sde-panic-per-pipe", false, PROP_TYPE_BOOL},
Dhaval Patel1964fb92016-10-13 19:28:08 -0700370 {SRC_SPLIT, "qcom,sde-has-src-split", false, PROP_TYPE_BOOL},
Veera Sundaram Sankaran3171ff82017-01-04 14:34:47 -0800371 {DIM_LAYER, "qcom,sde-has-dim-layer", false, PROP_TYPE_BOOL},
Jeykumar Sankaran2e655032017-02-04 14:05:45 -0800372 {SMART_DMA_REV, "qcom,sde-smart-dma-rev", false, PROP_TYPE_STRING},
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700373 {IDLE_PC, "qcom,sde-has-idle-pc", false, PROP_TYPE_BOOL},
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700374};
375
Alan Kwong9aa061c2016-11-06 21:17:12 -0500376static struct sde_prop_type sde_perf_prop[] = {
377 {PERF_MAX_BW_LOW, "qcom,sde-max-bw-low-kbps", false, PROP_TYPE_U32},
378 {PERF_MAX_BW_HIGH, "qcom,sde-max-bw-high-kbps", false, PROP_TYPE_U32},
Alan Kwong6259a382017-04-04 06:18:02 -0700379 {PERF_CORE_IB_FF, "qcom,sde-core-ib-ff", false, PROP_TYPE_STRING},
380 {PERF_CORE_CLK_FF, "qcom,sde-core-clk-ff", false, PROP_TYPE_STRING},
381 {PERF_COMP_RATIO_RT, "qcom,sde-comp-ratio-rt", false,
382 PROP_TYPE_STRING},
383 {PERF_COMP_RATIO_NRT, "qcom,sde-comp-ratio-nrt", false,
384 PROP_TYPE_STRING},
385 {PERF_UNDERSIZED_PREFILL_LINES, "qcom,sde-undersizedprefill-lines",
386 false, PROP_TYPE_U32},
387 {PERF_DEST_SCALE_PREFILL_LINES, "qcom,sde-dest-scaleprefill-lines",
388 false, PROP_TYPE_U32},
389 {PERF_MACROTILE_PREFILL_LINES, "qcom,sde-macrotileprefill-lines",
390 false, PROP_TYPE_U32},
391 {PERF_YUV_NV12_PREFILL_LINES, "qcom,sde-yuv-nv12prefill-lines",
392 false, PROP_TYPE_U32},
393 {PERF_LINEAR_PREFILL_LINES, "qcom,sde-linearprefill-lines",
394 false, PROP_TYPE_U32},
395 {PERF_DOWNSCALING_PREFILL_LINES, "qcom,sde-downscalingprefill-lines",
396 false, PROP_TYPE_U32},
397 {PERF_XTRA_PREFILL_LINES, "qcom,sde-xtra-prefill-lines",
398 false, PROP_TYPE_U32},
399 {PERF_AMORTIZABLE_THRESHOLD, "qcom,sde-amortizable-threshold",
400 false, PROP_TYPE_U32},
Alan Kwongdce56da2017-04-27 15:50:34 -0700401 {PERF_DANGER_LUT, "qcom,sde-danger-lut", false, PROP_TYPE_U32_ARRAY},
402 {PERF_SAFE_LUT, "qcom,sde-safe-lut", false, PROP_TYPE_U32_ARRAY},
403 {PERF_QOS_LUT_LINEAR, "qcom,sde-qos-lut-linear", false,
404 PROP_TYPE_U32_ARRAY},
405 {PERF_QOS_LUT_MACROTILE, "qcom,sde-qos-lut-macrotile", false,
406 PROP_TYPE_U32_ARRAY},
407 {PERF_QOS_LUT_NRT, "qcom,sde-qos-lut-nrt", false,
408 PROP_TYPE_U32_ARRAY},
409 {PERF_QOS_LUT_CWB, "qcom,sde-qos-lut-cwb", false,
410 PROP_TYPE_U32_ARRAY},
Alan Kwong143f50c2017-04-28 07:34:28 -0700411 {PERF_CDP_SETTING, "qcom,sde-cdp-setting", false,
412 PROP_TYPE_U32_ARRAY},
Alan Kwong9aa061c2016-11-06 21:17:12 -0500413};
414
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700415static struct sde_prop_type sspp_prop[] = {
416 {SSPP_OFF, "qcom,sde-sspp-off", true, PROP_TYPE_U32_ARRAY},
417 {SSPP_SIZE, "qcom,sde-sspp-src-size", false, PROP_TYPE_U32},
418 {SSPP_TYPE, "qcom,sde-sspp-type", true, PROP_TYPE_STRING_ARRAY},
419 {SSPP_XIN, "qcom,sde-sspp-xin-id", true, PROP_TYPE_U32_ARRAY},
420 {SSPP_CLK_CTRL, "qcom,sde-sspp-clk-ctrl", false,
421 PROP_TYPE_BIT_OFFSET_ARRAY},
422 {SSPP_CLK_STATUS, "qcom,sde-sspp-clk-status", false,
423 PROP_TYPE_BIT_OFFSET_ARRAY},
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700424 {SSPP_SCALE_SIZE, "qcom,sde-sspp-scale-size", false, PROP_TYPE_U32},
Benet Clark37809e62016-10-24 10:14:00 -0700425 {SSPP_VIG_BLOCKS, "qcom,sde-sspp-vig-blocks", false, PROP_TYPE_NODE},
426 {SSPP_RGB_BLOCKS, "qcom,sde-sspp-rgb-blocks", false, PROP_TYPE_NODE},
Veera Sundaram Sankaran02dd6ac2016-12-22 15:08:29 -0800427 {SSPP_EXCL_RECT, "qcom,sde-sspp-excl-rect", false, PROP_TYPE_U32_ARRAY},
Jeykumar Sankaran2e655032017-02-04 14:05:45 -0800428 {SSPP_SMART_DMA, "qcom,sde-sspp-smart-dma-priority", false,
429 PROP_TYPE_U32_ARRAY},
Alan Kwong6259a382017-04-04 06:18:02 -0700430 {SSPP_MAX_PER_PIPE_BW, "qcom,sde-max-per-pipe-bw-kbps", false,
431 PROP_TYPE_U32_ARRAY},
Benet Clark37809e62016-10-24 10:14:00 -0700432};
433
434static struct sde_prop_type vig_prop[] = {
435 {VIG_QSEED_OFF, "qcom,sde-vig-qseed-off", false, PROP_TYPE_U32},
Lloyd Atkinson77158732016-10-23 13:02:00 -0400436 {VIG_QSEED_LEN, "qcom,sde-vig-qseed-size", false, PROP_TYPE_U32},
Benet Clark37809e62016-10-24 10:14:00 -0700437 {VIG_CSC_OFF, "qcom,sde-vig-csc-off", false, PROP_TYPE_U32},
438 {VIG_HSIC_PROP, "qcom,sde-vig-hsic", false, PROP_TYPE_U32_ARRAY},
439 {VIG_MEMCOLOR_PROP, "qcom,sde-vig-memcolor", false,
440 PROP_TYPE_U32_ARRAY},
441 {VIG_PCC_PROP, "qcom,sde-vig-pcc", false, PROP_TYPE_U32_ARRAY},
442};
443
444static struct sde_prop_type rgb_prop[] = {
445 {RGB_SCALER_OFF, "qcom,sde-rgb-scaler-off", false, PROP_TYPE_U32},
Lloyd Atkinson77158732016-10-23 13:02:00 -0400446 {RGB_SCALER_LEN, "qcom,sde-rgb-scaler-size", false, PROP_TYPE_U32},
Benet Clark37809e62016-10-24 10:14:00 -0700447 {RGB_PCC_PROP, "qcom,sde-rgb-pcc", false, PROP_TYPE_U32_ARRAY},
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700448};
449
450static struct sde_prop_type ctl_prop[] = {
451 {HW_OFF, "qcom,sde-ctl-off", true, PROP_TYPE_U32_ARRAY},
452 {HW_LEN, "qcom,sde-ctl-size", false, PROP_TYPE_U32},
453};
454
Veera Sundaram Sankaran370b9912017-01-10 18:03:42 -0800455struct sde_prop_type mixer_blend_prop[] = {
456 {MIXER_BLEND_OP_OFF, "qcom,sde-mixer-blend-op-off", true,
457 PROP_TYPE_U32_ARRAY},
458};
459
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700460static struct sde_prop_type mixer_prop[] = {
461 {MIXER_OFF, "qcom,sde-mixer-off", true, PROP_TYPE_U32_ARRAY},
462 {MIXER_LEN, "qcom,sde-mixer-size", false, PROP_TYPE_U32},
Veera Sundaram Sankaran370b9912017-01-10 18:03:42 -0800463 {MIXER_PAIR_MASK, "qcom,sde-mixer-pair-mask", true,
464 PROP_TYPE_U32_ARRAY},
Benet Clark37809e62016-10-24 10:14:00 -0700465 {MIXER_BLOCKS, "qcom,sde-mixer-blocks", false, PROP_TYPE_NODE},
466};
467
468static struct sde_prop_type mixer_blocks_prop[] = {
469 {MIXER_GC_PROP, "qcom,sde-mixer-gc", false, PROP_TYPE_U32_ARRAY},
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700470};
471
Rajesh Yadavec93afb2017-06-08 19:28:33 +0530472static struct sde_prop_type dspp_top_prop[] = {
473 {DSPP_TOP_OFF, "qcom,sde-dspp-top-off", true, PROP_TYPE_U32},
474 {DSPP_TOP_SIZE, "qcom,sde-dspp-top-size", false, PROP_TYPE_U32},
475};
476
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700477static struct sde_prop_type dspp_prop[] = {
478 {DSPP_OFF, "qcom,sde-dspp-off", true, PROP_TYPE_U32_ARRAY},
479 {DSPP_SIZE, "qcom,sde-dspp-size", false, PROP_TYPE_U32},
Benet Clark37809e62016-10-24 10:14:00 -0700480 {DSPP_BLOCKS, "qcom,sde-dspp-blocks", false, PROP_TYPE_NODE},
481};
482
483static struct sde_prop_type dspp_blocks_prop[] = {
484 {DSPP_IGC_PROP, "qcom,sde-dspp-igc", false, PROP_TYPE_U32_ARRAY},
485 {DSPP_PCC_PROP, "qcom,sde-dspp-pcc", false, PROP_TYPE_U32_ARRAY},
486 {DSPP_GC_PROP, "qcom,sde-dspp-gc", false, PROP_TYPE_U32_ARRAY},
487 {DSPP_HSIC_PROP, "qcom,sde-dspp-hsic", false, PROP_TYPE_U32_ARRAY},
488 {DSPP_MEMCOLOR_PROP, "qcom,sde-dspp-memcolor", false,
489 PROP_TYPE_U32_ARRAY},
490 {DSPP_SIXZONE_PROP, "qcom,sde-dspp-sixzone", false,
491 PROP_TYPE_U32_ARRAY},
492 {DSPP_GAMUT_PROP, "qcom,sde-dspp-gamut", false, PROP_TYPE_U32_ARRAY},
493 {DSPP_DITHER_PROP, "qcom,sde-dspp-dither", false, PROP_TYPE_U32_ARRAY},
494 {DSPP_HIST_PROP, "qcom,sde-dspp-hist", false, PROP_TYPE_U32_ARRAY},
495 {DSPP_VLUT_PROP, "qcom,sde-dspp-vlut", false, PROP_TYPE_U32_ARRAY},
496};
497
498static struct sde_prop_type ad_prop[] = {
499 {AD_OFF, "qcom,sde-dspp-ad-off", false, PROP_TYPE_U32_ARRAY},
500 {AD_VERSION, "qcom,sde-dspp-ad-version", false, PROP_TYPE_U32},
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700501};
502
503static struct sde_prop_type pp_prop[] = {
504 {PP_OFF, "qcom,sde-pp-off", true, PROP_TYPE_U32_ARRAY},
505 {PP_LEN, "qcom,sde-pp-size", false, PROP_TYPE_U32},
506 {TE_OFF, "qcom,sde-te-off", false, PROP_TYPE_U32_ARRAY},
507 {TE_LEN, "qcom,sde-te-size", false, PROP_TYPE_U32},
508 {TE2_OFF, "qcom,sde-te2-off", false, PROP_TYPE_U32_ARRAY},
509 {TE2_LEN, "qcom,sde-te2-size", false, PROP_TYPE_U32},
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800510 {PP_SLAVE, "qcom,sde-pp-slave", false, PROP_TYPE_U32_ARRAY},
Ping Li8430ee12017-02-24 14:14:44 -0800511 {DITHER_OFF, "qcom,sde-dither-off", false, PROP_TYPE_U32_ARRAY},
512 {DITHER_LEN, "qcom,sde-dither-size", false, PROP_TYPE_U32},
513 {DITHER_VER, "qcom,sde-dither-version", false, PROP_TYPE_U32},
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800514};
515
516static struct sde_prop_type dsc_prop[] = {
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700517 {DSC_OFF, "qcom,sde-dsc-off", false, PROP_TYPE_U32_ARRAY},
518 {DSC_LEN, "qcom,sde-dsc-size", false, PROP_TYPE_U32},
519};
520
521static struct sde_prop_type cdm_prop[] = {
522 {HW_OFF, "qcom,sde-cdm-off", false, PROP_TYPE_U32_ARRAY},
523 {HW_LEN, "qcom,sde-cdm-size", false, PROP_TYPE_U32},
524};
525
526static struct sde_prop_type intf_prop[] = {
527 {INTF_OFF, "qcom,sde-intf-off", true, PROP_TYPE_U32_ARRAY},
528 {INTF_LEN, "qcom,sde-intf-size", false, PROP_TYPE_U32},
529 {INTF_PREFETCH, "qcom,sde-intf-max-prefetch-lines", false,
530 PROP_TYPE_U32_ARRAY},
531 {INTF_TYPE, "qcom,sde-intf-type", false, PROP_TYPE_STRING_ARRAY},
532};
533
534static struct sde_prop_type wb_prop[] = {
535 {WB_OFF, "qcom,sde-wb-off", true, PROP_TYPE_U32_ARRAY},
536 {WB_LEN, "qcom,sde-wb-size", false, PROP_TYPE_U32},
Alan Kwong14627332016-10-12 16:44:00 -0400537 {WB_ID, "qcom,sde-wb-id", true, PROP_TYPE_U32_ARRAY},
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700538 {WB_XIN_ID, "qcom,sde-wb-xin-id", false, PROP_TYPE_U32_ARRAY},
Alan Kwong04780ec2016-10-12 16:05:17 -0400539 {WB_CLK_CTRL, "qcom,sde-wb-clk-ctrl", false,
540 PROP_TYPE_BIT_OFFSET_ARRAY},
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700541};
542
Alan Kwongb9d2f6f2016-10-12 00:27:07 -0400543static struct sde_prop_type vbif_prop[] = {
544 {VBIF_OFF, "qcom,sde-vbif-off", true, PROP_TYPE_U32_ARRAY},
545 {VBIF_LEN, "qcom,sde-vbif-size", false, PROP_TYPE_U32},
546 {VBIF_ID, "qcom,sde-vbif-id", false, PROP_TYPE_U32_ARRAY},
547 {VBIF_DEFAULT_OT_RD_LIMIT, "qcom,sde-vbif-default-ot-rd-limit", false,
548 PROP_TYPE_U32},
549 {VBIF_DEFAULT_OT_WR_LIMIT, "qcom,sde-vbif-default-ot-wr-limit", false,
550 PROP_TYPE_U32},
551 {VBIF_DYNAMIC_OT_RD_LIMIT, "qcom,sde-vbif-dynamic-ot-rd-limit", false,
552 PROP_TYPE_U32_ARRAY},
553 {VBIF_DYNAMIC_OT_WR_LIMIT, "qcom,sde-vbif-dynamic-ot-wr-limit", false,
554 PROP_TYPE_U32_ARRAY},
Alan Kwonga62eeb82017-04-19 08:57:55 -0700555 {VBIF_QOS_RT_REMAP, "qcom,sde-vbif-qos-rt-remap", false,
556 PROP_TYPE_U32_ARRAY},
557 {VBIF_QOS_NRT_REMAP, "qcom,sde-vbif-qos-nrt-remap", false,
558 PROP_TYPE_U32_ARRAY},
Clarence Ip7f0de632017-05-31 14:59:14 -0400559 {VBIF_MEMTYPE_0, "qcom,sde-vbif-memtype-0", false, PROP_TYPE_U32_ARRAY},
560 {VBIF_MEMTYPE_1, "qcom,sde-vbif-memtype-1", false, PROP_TYPE_U32_ARRAY},
Alan Kwongb9d2f6f2016-10-12 00:27:07 -0400561};
562
Gopikrishnaiah Anandan031d8ff2016-12-15 16:58:45 -0800563static struct sde_prop_type reg_dma_prop[REG_DMA_PROP_MAX] = {
564 [REG_DMA_OFF] = {REG_DMA_OFF, "qcom,sde-reg-dma-off", false,
565 PROP_TYPE_U32},
566 [REG_DMA_VERSION] = {REG_DMA_VERSION, "qcom,sde-reg-dma-version",
567 false, PROP_TYPE_U32},
568 [REG_DMA_TRIGGER_OFF] = {REG_DMA_TRIGGER_OFF,
569 "qcom,sde-reg-dma-trigger-off", false,
570 PROP_TYPE_U32},
571};
572
Veera Sundaram Sankaran1e71ccb2017-05-24 18:48:50 -0700573static struct sde_prop_type inline_rot_prop[INLINE_ROT_PROP_MAX] = {
574 {INLINE_ROT_XIN, "qcom,sde-inline-rot-xin", false,
575 PROP_TYPE_U32_ARRAY},
576 {INLINE_ROT_XIN_TYPE, "qcom,sde-inline-rot-xin-type", false,
577 PROP_TYPE_STRING_ARRAY},
578 {INLINE_ROT_CLK_CTRL, "qcom,sde-inline-rot-clk-ctrl", false,
579 PROP_TYPE_BIT_OFFSET_ARRAY},
580};
581
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700582/*************************************************************
583 * static API list
584 *************************************************************/
abeykunf35ff332016-12-20 13:06:09 -0500585
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700586static int _parse_dt_u32_handler(struct device_node *np,
587 char *prop_name, u32 *offsets, int len, bool mandatory)
588{
Dhaval Patele4da9d742017-06-19 16:51:21 -0700589 int rc = -EINVAL;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700590
Dhaval Patele4da9d742017-06-19 16:51:21 -0700591 if (len > MAX_SDE_HW_BLK) {
592 SDE_ERROR(
593 "prop: %s tries out of bound access for u32 array read len: %d\n",
594 prop_name, len);
595 return -E2BIG;
596 }
597
598 rc = of_property_read_u32_array(np, prop_name, offsets, len);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700599 if (rc && mandatory)
600 SDE_ERROR("mandatory prop: %s u32 array read len:%d\n",
601 prop_name, len);
602 else if (rc)
603 SDE_DEBUG("optional prop: %s u32 array read len:%d\n",
604 prop_name, len);
605
606 return rc;
607}
608
609static int _parse_dt_bit_offset(struct device_node *np,
Clarence Ip613fd8a2016-11-29 19:01:39 -0500610 char *prop_name, struct sde_prop_value *prop_value, u32 prop_index,
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700611 u32 count, bool mandatory)
612{
613 int rc = 0, len, i, j;
614 const u32 *arr;
615
616 arr = of_get_property(np, prop_name, &len);
617 if (arr) {
618 len /= sizeof(u32);
Clarence Ip613fd8a2016-11-29 19:01:39 -0500619 len &= ~0x1;
Dhaval Patele4da9d742017-06-19 16:51:21 -0700620
621 if (len > (MAX_SDE_HW_BLK * MAX_BIT_OFFSET)) {
622 SDE_ERROR(
623 "prop: %s len: %d will lead to out of bound access\n",
624 prop_name, len / MAX_BIT_OFFSET);
625 return -E2BIG;
626 }
627
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700628 for (i = 0, j = 0; i < len; j++) {
Clarence Ip613fd8a2016-11-29 19:01:39 -0500629 PROP_BITVALUE_ACCESS(prop_value, prop_index, j, 0) =
630 be32_to_cpu(arr[i]);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700631 i++;
Clarence Ip613fd8a2016-11-29 19:01:39 -0500632 PROP_BITVALUE_ACCESS(prop_value, prop_index, j, 1) =
633 be32_to_cpu(arr[i]);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700634 i++;
635 }
636 } else {
637 if (mandatory) {
638 SDE_ERROR("error mandatory property '%s' not found\n",
639 prop_name);
640 rc = -EINVAL;
641 } else {
642 SDE_DEBUG("error optional property '%s' not found\n",
643 prop_name);
644 }
645 }
646
647 return rc;
648}
649
650static int _validate_dt_entry(struct device_node *np,
651 struct sde_prop_type *sde_prop, u32 prop_size, int *prop_count,
652 int *off_count)
653{
654 int rc = 0, i, val;
Benet Clark37809e62016-10-24 10:14:00 -0700655 struct device_node *snp = NULL;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700656
Benet Clark37809e62016-10-24 10:14:00 -0700657 if (off_count) {
658 *off_count = of_property_count_u32_elems(np,
659 sde_prop[0].prop_name);
660 if ((*off_count > MAX_BLOCKS) || (*off_count < 0)) {
661 if (sde_prop[0].is_mandatory) {
Dhaval Patele4da9d742017-06-19 16:51:21 -0700662 SDE_ERROR(
663 "invalid hw offset prop name:%s count: %d\n",
Alan Kwong15cfbf92016-10-27 21:10:54 -0400664 sde_prop[0].prop_name, *off_count);
Benet Clark37809e62016-10-24 10:14:00 -0700665 rc = -EINVAL;
666 }
667 *off_count = 0;
Alan Kwongcbac0b32017-04-21 13:14:33 -0700668 memset(prop_count, 0, sizeof(int) * prop_size);
Benet Clark37809e62016-10-24 10:14:00 -0700669 return rc;
Alan Kwong15cfbf92016-10-27 21:10:54 -0400670 }
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700671 }
672
Clarence Ip613fd8a2016-11-29 19:01:39 -0500673 for (i = 0; i < prop_size; i++) {
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700674 switch (sde_prop[i].type) {
675 case PROP_TYPE_U32:
676 rc = of_property_read_u32(np, sde_prop[i].prop_name,
677 &val);
678 break;
679 case PROP_TYPE_U32_ARRAY:
680 prop_count[i] = of_property_count_u32_elems(np,
681 sde_prop[i].prop_name);
Benet Clark37809e62016-10-24 10:14:00 -0700682 if (prop_count[i] < 0)
683 rc = prop_count[i];
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700684 break;
685 case PROP_TYPE_STRING_ARRAY:
686 prop_count[i] = of_property_count_strings(np,
687 sde_prop[i].prop_name);
Benet Clark37809e62016-10-24 10:14:00 -0700688 if (prop_count[i] < 0)
689 rc = prop_count[i];
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700690 break;
691 case PROP_TYPE_BIT_OFFSET_ARRAY:
692 of_get_property(np, sde_prop[i].prop_name, &val);
693 prop_count[i] = val / (MAX_BIT_OFFSET * sizeof(u32));
694 break;
Benet Clark37809e62016-10-24 10:14:00 -0700695 case PROP_TYPE_NODE:
696 snp = of_get_child_by_name(np,
697 sde_prop[i].prop_name);
698 if (!snp)
699 rc = -EINVAL;
700 break;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700701 default:
702 SDE_DEBUG("invalid property type:%d\n",
703 sde_prop[i].type);
704 break;
705 }
Dhaval Patele4da9d742017-06-19 16:51:21 -0700706 SDE_DEBUG(
707 "prop id:%d prop name:%s prop type:%d prop_count:%d\n",
708 i, sde_prop[i].prop_name,
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700709 sde_prop[i].type, prop_count[i]);
710
711 if (rc && sde_prop[i].is_mandatory &&
Benet Clark37809e62016-10-24 10:14:00 -0700712 ((sde_prop[i].type == PROP_TYPE_U32) ||
713 (sde_prop[i].type == PROP_TYPE_NODE))) {
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700714 SDE_ERROR("prop:%s not present\n",
715 sde_prop[i].prop_name);
716 goto end;
717 } else if (sde_prop[i].type == PROP_TYPE_U32 ||
Benet Clark37809e62016-10-24 10:14:00 -0700718 sde_prop[i].type == PROP_TYPE_BOOL ||
719 sde_prop[i].type == PROP_TYPE_NODE) {
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700720 rc = 0;
721 continue;
722 }
723
Benet Clark37809e62016-10-24 10:14:00 -0700724 if (off_count && (prop_count[i] != *off_count) &&
725 sde_prop[i].is_mandatory) {
Dhaval Patele4da9d742017-06-19 16:51:21 -0700726 SDE_ERROR(
727 "prop:%s count:%d is different compared to offset array:%d\n",
728 sde_prop[i].prop_name,
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700729 prop_count[i], *off_count);
730 rc = -EINVAL;
731 goto end;
Benet Clark37809e62016-10-24 10:14:00 -0700732 } else if (off_count && prop_count[i] != *off_count) {
Dhaval Patele4da9d742017-06-19 16:51:21 -0700733 SDE_DEBUG(
734 "prop:%s count:%d is different compared to offset array:%d\n",
735 sde_prop[i].prop_name,
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700736 prop_count[i], *off_count);
737 rc = 0;
738 prop_count[i] = 0;
739 }
Dhaval Patel5398f602017-03-25 18:25:18 -0700740 if (prop_count[i] < 0) {
Benet Clark37809e62016-10-24 10:14:00 -0700741 prop_count[i] = 0;
742 if (sde_prop[i].is_mandatory) {
743 SDE_ERROR("prop:%s count:%d is negative\n",
744 sde_prop[i].prop_name, prop_count[i]);
745 rc = -EINVAL;
746 } else {
747 rc = 0;
748 SDE_DEBUG("prop:%s count:%d is negative\n",
749 sde_prop[i].prop_name, prop_count[i]);
750 }
751 }
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700752 }
753
754end:
755 return rc;
756}
757
758static int _read_dt_entry(struct device_node *np,
Benet Clark37809e62016-10-24 10:14:00 -0700759 struct sde_prop_type *sde_prop, u32 prop_size, int *prop_count,
760 bool *prop_exists,
Clarence Ip613fd8a2016-11-29 19:01:39 -0500761 struct sde_prop_value *prop_value)
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700762{
763 int rc = 0, i, j;
764
Clarence Ip613fd8a2016-11-29 19:01:39 -0500765 for (i = 0; i < prop_size; i++) {
Benet Clark37809e62016-10-24 10:14:00 -0700766 prop_exists[i] = true;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700767 switch (sde_prop[i].type) {
768 case PROP_TYPE_U32:
Benet Clark37809e62016-10-24 10:14:00 -0700769 rc = of_property_read_u32(np, sde_prop[i].prop_name,
770 &PROP_VALUE_ACCESS(prop_value, i, 0));
Dhaval Patele4da9d742017-06-19 16:51:21 -0700771 SDE_DEBUG(
772 "prop id:%d prop name:%s prop type:%d value:0x%x\n",
773 i, sde_prop[i].prop_name,
Benet Clark37809e62016-10-24 10:14:00 -0700774 sde_prop[i].type,
775 PROP_VALUE_ACCESS(prop_value, i, 0));
776 if (rc)
777 prop_exists[i] = false;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700778 break;
779 case PROP_TYPE_BOOL:
Benet Clark37809e62016-10-24 10:14:00 -0700780 PROP_VALUE_ACCESS(prop_value, i, 0) =
781 of_property_read_bool(np,
782 sde_prop[i].prop_name);
Dhaval Patele4da9d742017-06-19 16:51:21 -0700783 SDE_DEBUG(
784 "prop id:%d prop name:%s prop type:%d value:0x%x\n",
785 i, sde_prop[i].prop_name,
Benet Clark37809e62016-10-24 10:14:00 -0700786 sde_prop[i].type,
787 PROP_VALUE_ACCESS(prop_value, i, 0));
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700788 break;
789 case PROP_TYPE_U32_ARRAY:
790 rc = _parse_dt_u32_handler(np, sde_prop[i].prop_name,
Benet Clark37809e62016-10-24 10:14:00 -0700791 &PROP_VALUE_ACCESS(prop_value, i, 0),
792 prop_count[i], sde_prop[i].is_mandatory);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700793 if (rc && sde_prop[i].is_mandatory) {
Dhaval Patele4da9d742017-06-19 16:51:21 -0700794 SDE_ERROR(
795 "%s prop validation success but read failed\n",
796 sde_prop[i].prop_name);
Benet Clark37809e62016-10-24 10:14:00 -0700797 prop_exists[i] = false;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700798 goto end;
799 } else {
Benet Clark37809e62016-10-24 10:14:00 -0700800 if (rc)
801 prop_exists[i] = false;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700802 /* only for debug purpose */
803 SDE_DEBUG("prop id:%d prop name:%s prop \"\
804 type:%d", i, sde_prop[i].prop_name,
805 sde_prop[i].type);
806 for (j = 0; j < prop_count[i]; j++)
807 SDE_DEBUG(" value[%d]:0x%x ", j,
Benet Clark37809e62016-10-24 10:14:00 -0700808 PROP_VALUE_ACCESS(prop_value, i,
809 j));
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700810 SDE_DEBUG("\n");
811 }
812 break;
813 case PROP_TYPE_BIT_OFFSET_ARRAY:
814 rc = _parse_dt_bit_offset(np, sde_prop[i].prop_name,
Clarence Ip613fd8a2016-11-29 19:01:39 -0500815 prop_value, i, prop_count[i],
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700816 sde_prop[i].is_mandatory);
817 if (rc && sde_prop[i].is_mandatory) {
Dhaval Patele4da9d742017-06-19 16:51:21 -0700818 SDE_ERROR(
819 "%s prop validation success but read failed\n",
820 sde_prop[i].prop_name);
Benet Clark37809e62016-10-24 10:14:00 -0700821 prop_exists[i] = false;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700822 goto end;
823 } else {
Benet Clark37809e62016-10-24 10:14:00 -0700824 if (rc)
825 prop_exists[i] = false;
Dhaval Patele4da9d742017-06-19 16:51:21 -0700826 SDE_DEBUG(
827 "prop id:%d prop name:%s prop type:%d",
828 i, sde_prop[i].prop_name,
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700829 sde_prop[i].type);
830 for (j = 0; j < prop_count[i]; j++)
Dhaval Patele4da9d742017-06-19 16:51:21 -0700831 SDE_DEBUG(
832 "count[%d]: bit:0x%x off:0x%x\n", j,
Clarence Ip613fd8a2016-11-29 19:01:39 -0500833 PROP_BITVALUE_ACCESS(prop_value,
834 i, j, 0),
835 PROP_BITVALUE_ACCESS(prop_value,
836 i, j, 1));
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700837 SDE_DEBUG("\n");
838 }
839 break;
Benet Clark37809e62016-10-24 10:14:00 -0700840 case PROP_TYPE_NODE:
841 /* Node will be parsed in calling function */
842 rc = 0;
843 break;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700844 default:
845 SDE_DEBUG("invalid property type:%d\n",
846 sde_prop[i].type);
847 break;
848 }
849 rc = 0;
850 }
851
852end:
853 return rc;
854}
855
856static void _sde_sspp_setup_vig(struct sde_mdss_cfg *sde_cfg,
857 struct sde_sspp_cfg *sspp, struct sde_sspp_sub_blks *sblk,
Clarence Ip613fd8a2016-11-29 19:01:39 -0500858 bool *prop_exists, struct sde_prop_value *prop_value, u32 *vig_count)
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700859{
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700860 sblk->maxupscale = MAX_SSPP_UPSCALE;
861 sblk->maxdwnscale = MAX_SSPP_DOWNSCALE;
862 sspp->id = SSPP_VIG0 + *vig_count;
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -0700863 snprintf(sspp->name, SDE_HW_BLK_NAME_LEN, "sspp_%u",
864 sspp->id - SSPP_VIG0);
Alan Kwong04780ec2016-10-12 16:05:17 -0400865 sspp->clk_ctrl = SDE_CLK_CTRL_VIG0 + *vig_count;
abeykunf35ff332016-12-20 13:06:09 -0500866 sspp->type = SSPP_TYPE_VIG;
Alan Kwong41b099e2016-10-12 17:10:11 -0400867 set_bit(SDE_SSPP_QOS, &sspp->features);
Alan Kwongdce56da2017-04-27 15:50:34 -0700868 if (sde_cfg->vbif_qos_nlvl == 8)
869 set_bit(SDE_SSPP_QOS_8LVL, &sspp->features);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700870 (*vig_count)++;
Benet Clark37809e62016-10-24 10:14:00 -0700871
872 if (!prop_value)
873 return;
874
875 if (sde_cfg->qseed_type == SDE_SSPP_SCALER_QSEED2) {
876 set_bit(SDE_SSPP_SCALER_QSEED2, &sspp->features);
877 sblk->scaler_blk.id = SDE_SSPP_SCALER_QSEED2;
878 sblk->scaler_blk.base = PROP_VALUE_ACCESS(prop_value,
879 VIG_QSEED_OFF, 0);
Lloyd Atkinson77158732016-10-23 13:02:00 -0400880 sblk->scaler_blk.len = PROP_VALUE_ACCESS(prop_value,
881 VIG_QSEED_LEN, 0);
882 snprintf(sblk->scaler_blk.name, SDE_HW_BLK_NAME_LEN,
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -0700883 "sspp_scaler%u", sspp->id - SSPP_VIG0);
Benet Clark37809e62016-10-24 10:14:00 -0700884 } else if (sde_cfg->qseed_type == SDE_SSPP_SCALER_QSEED3) {
885 set_bit(SDE_SSPP_SCALER_QSEED3, &sspp->features);
886 sblk->scaler_blk.id = SDE_SSPP_SCALER_QSEED3;
887 sblk->scaler_blk.base = PROP_VALUE_ACCESS(prop_value,
888 VIG_QSEED_OFF, 0);
Lloyd Atkinson77158732016-10-23 13:02:00 -0400889 sblk->scaler_blk.len = PROP_VALUE_ACCESS(prop_value,
890 VIG_QSEED_LEN, 0);
891 snprintf(sblk->scaler_blk.name, SDE_HW_BLK_NAME_LEN,
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -0700892 "sspp_scaler%u", sspp->id - SSPP_VIG0);
Benet Clark37809e62016-10-24 10:14:00 -0700893 }
894
Alan Kwong4dd64c82017-02-04 18:41:51 -0800895 if (sde_cfg->has_sbuf)
896 set_bit(SDE_SSPP_SBUF, &sspp->features);
897
Benet Clark37809e62016-10-24 10:14:00 -0700898 sblk->csc_blk.id = SDE_SSPP_CSC;
Lloyd Atkinson77158732016-10-23 13:02:00 -0400899 snprintf(sblk->csc_blk.name, SDE_HW_BLK_NAME_LEN,
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -0700900 "sspp_csc%u", sspp->id - SSPP_VIG0);
Dhaval Patel5aad7452017-01-12 09:59:31 -0800901 if (sde_cfg->csc_type == SDE_SSPP_CSC) {
902 set_bit(SDE_SSPP_CSC, &sspp->features);
903 sblk->csc_blk.base = PROP_VALUE_ACCESS(prop_value,
904 VIG_CSC_OFF, 0);
905 } else if (sde_cfg->csc_type == SDE_SSPP_CSC_10BIT) {
906 set_bit(SDE_SSPP_CSC_10BIT, &sspp->features);
907 sblk->csc_blk.base = PROP_VALUE_ACCESS(prop_value,
908 VIG_CSC_OFF, 0);
909 }
Benet Clark37809e62016-10-24 10:14:00 -0700910
911 sblk->hsic_blk.id = SDE_SSPP_HSIC;
Lloyd Atkinson77158732016-10-23 13:02:00 -0400912 snprintf(sblk->hsic_blk.name, SDE_HW_BLK_NAME_LEN,
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -0700913 "sspp_hsic%u", sspp->id - SSPP_VIG0);
Benet Clark37809e62016-10-24 10:14:00 -0700914 if (prop_exists[VIG_HSIC_PROP]) {
915 sblk->hsic_blk.base = PROP_VALUE_ACCESS(prop_value,
916 VIG_HSIC_PROP, 0);
917 sblk->hsic_blk.version = PROP_VALUE_ACCESS(prop_value,
918 VIG_HSIC_PROP, 1);
919 sblk->hsic_blk.len = 0;
920 set_bit(SDE_SSPP_HSIC, &sspp->features);
921 }
922
923 sblk->memcolor_blk.id = SDE_SSPP_MEMCOLOR;
Lloyd Atkinson77158732016-10-23 13:02:00 -0400924 snprintf(sblk->memcolor_blk.name, SDE_HW_BLK_NAME_LEN,
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -0700925 "sspp_memcolor%u", sspp->id - SSPP_VIG0);
Benet Clark37809e62016-10-24 10:14:00 -0700926 if (prop_exists[VIG_MEMCOLOR_PROP]) {
927 sblk->memcolor_blk.base = PROP_VALUE_ACCESS(prop_value,
928 VIG_MEMCOLOR_PROP, 0);
929 sblk->memcolor_blk.version = PROP_VALUE_ACCESS(prop_value,
930 VIG_MEMCOLOR_PROP, 1);
931 sblk->memcolor_blk.len = 0;
932 set_bit(SDE_SSPP_MEMCOLOR, &sspp->features);
933 }
934
935 sblk->pcc_blk.id = SDE_SSPP_PCC;
Lloyd Atkinson77158732016-10-23 13:02:00 -0400936 snprintf(sblk->pcc_blk.name, SDE_HW_BLK_NAME_LEN,
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -0700937 "sspp_pcc%u", sspp->id - SSPP_VIG0);
Benet Clark37809e62016-10-24 10:14:00 -0700938 if (prop_exists[VIG_PCC_PROP]) {
939 sblk->pcc_blk.base = PROP_VALUE_ACCESS(prop_value,
940 VIG_PCC_PROP, 0);
941 sblk->pcc_blk.version = PROP_VALUE_ACCESS(prop_value,
942 VIG_PCC_PROP, 1);
943 sblk->pcc_blk.len = 0;
944 set_bit(SDE_SSPP_PCC, &sspp->features);
945 }
Clarence Ip32bcb002017-03-13 12:26:44 -0700946
947 sblk->format_list = sde_cfg->vig_formats;
Steve Cohen57428172017-07-18 10:57:17 -0400948 sblk->virt_format_list = sde_cfg->dma_formats;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700949}
950
951static void _sde_sspp_setup_rgb(struct sde_mdss_cfg *sde_cfg,
952 struct sde_sspp_cfg *sspp, struct sde_sspp_sub_blks *sblk,
Clarence Ip613fd8a2016-11-29 19:01:39 -0500953 bool *prop_exists, struct sde_prop_value *prop_value, u32 *rgb_count)
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700954{
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700955 sblk->maxupscale = MAX_SSPP_UPSCALE;
956 sblk->maxdwnscale = MAX_SSPP_DOWNSCALE;
957 sspp->id = SSPP_RGB0 + *rgb_count;
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -0700958 snprintf(sspp->name, SDE_HW_BLK_NAME_LEN, "sspp_%u",
959 sspp->id - SSPP_VIG0);
Alan Kwong04780ec2016-10-12 16:05:17 -0400960 sspp->clk_ctrl = SDE_CLK_CTRL_RGB0 + *rgb_count;
abeykunf35ff332016-12-20 13:06:09 -0500961 sspp->type = SSPP_TYPE_RGB;
Alan Kwong41b099e2016-10-12 17:10:11 -0400962 set_bit(SDE_SSPP_QOS, &sspp->features);
Alan Kwongdce56da2017-04-27 15:50:34 -0700963 if (sde_cfg->vbif_qos_nlvl == 8)
964 set_bit(SDE_SSPP_QOS_8LVL, &sspp->features);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700965 (*rgb_count)++;
Benet Clark37809e62016-10-24 10:14:00 -0700966
967 if (!prop_value)
968 return;
969
970 if (sde_cfg->qseed_type == SDE_SSPP_SCALER_QSEED2) {
971 set_bit(SDE_SSPP_SCALER_RGB, &sspp->features);
972 sblk->scaler_blk.id = SDE_SSPP_SCALER_QSEED2;
973 sblk->scaler_blk.base = PROP_VALUE_ACCESS(prop_value,
974 RGB_SCALER_OFF, 0);
Lloyd Atkinson77158732016-10-23 13:02:00 -0400975 sblk->scaler_blk.len = PROP_VALUE_ACCESS(prop_value,
976 RGB_SCALER_LEN, 0);
977 snprintf(sblk->scaler_blk.name, SDE_HW_BLK_NAME_LEN,
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -0700978 "sspp_scaler%u", sspp->id - SSPP_VIG0);
Benet Clark37809e62016-10-24 10:14:00 -0700979 } else if (sde_cfg->qseed_type == SDE_SSPP_SCALER_QSEED3) {
980 set_bit(SDE_SSPP_SCALER_RGB, &sspp->features);
981 sblk->scaler_blk.id = SDE_SSPP_SCALER_QSEED3;
982 sblk->scaler_blk.base = PROP_VALUE_ACCESS(prop_value,
Lloyd Atkinson77158732016-10-23 13:02:00 -0400983 RGB_SCALER_LEN, 0);
984 sblk->scaler_blk.len = PROP_VALUE_ACCESS(prop_value,
985 SSPP_SCALE_SIZE, 0);
986 snprintf(sblk->scaler_blk.name, SDE_HW_BLK_NAME_LEN,
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -0700987 "sspp_scaler%u", sspp->id - SSPP_VIG0);
Benet Clark37809e62016-10-24 10:14:00 -0700988 }
989
990 sblk->pcc_blk.id = SDE_SSPP_PCC;
991 if (prop_exists[RGB_PCC_PROP]) {
992 sblk->pcc_blk.base = PROP_VALUE_ACCESS(prop_value,
993 RGB_PCC_PROP, 0);
994 sblk->pcc_blk.version = PROP_VALUE_ACCESS(prop_value,
995 RGB_PCC_PROP, 1);
996 sblk->pcc_blk.len = 0;
997 set_bit(SDE_SSPP_PCC, &sspp->features);
998 }
Clarence Ip32bcb002017-03-13 12:26:44 -0700999
1000 sblk->format_list = sde_cfg->dma_formats;
Steve Cohen57428172017-07-18 10:57:17 -04001001 sblk->virt_format_list = NULL;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001002}
1003
1004static void _sde_sspp_setup_cursor(struct sde_mdss_cfg *sde_cfg,
1005 struct sde_sspp_cfg *sspp, struct sde_sspp_sub_blks *sblk,
Clarence Ip613fd8a2016-11-29 19:01:39 -05001006 struct sde_prop_value *prop_value, u32 *cursor_count)
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001007{
Clarence Ip32bcb002017-03-13 12:26:44 -07001008 if (!IS_SDE_MAJOR_MINOR_SAME(sde_cfg->hwversion, SDE_HW_VER_300))
1009 SDE_ERROR("invalid sspp type %d, xin id %d\n",
1010 sspp->type, sspp->xin_id);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001011 set_bit(SDE_SSPP_CURSOR, &sspp->features);
1012 sblk->maxupscale = SSPP_UNITY_SCALE;
1013 sblk->maxdwnscale = SSPP_UNITY_SCALE;
Clarence Ip32bcb002017-03-13 12:26:44 -07001014 sblk->format_list = sde_cfg->cursor_formats;
Steve Cohen57428172017-07-18 10:57:17 -04001015 sblk->virt_format_list = NULL;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001016 sspp->id = SSPP_CURSOR0 + *cursor_count;
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -07001017 snprintf(sspp->name, SDE_HW_BLK_NAME_LEN, "sspp_%u",
1018 sspp->id - SSPP_VIG0);
Alan Kwong04780ec2016-10-12 16:05:17 -04001019 sspp->clk_ctrl = SDE_CLK_CTRL_CURSOR0 + *cursor_count;
abeykunf35ff332016-12-20 13:06:09 -05001020 sspp->type = SSPP_TYPE_CURSOR;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001021 (*cursor_count)++;
1022}
1023
1024static void _sde_sspp_setup_dma(struct sde_mdss_cfg *sde_cfg,
1025 struct sde_sspp_cfg *sspp, struct sde_sspp_sub_blks *sblk,
Clarence Ip613fd8a2016-11-29 19:01:39 -05001026 struct sde_prop_value *prop_value, u32 *dma_count)
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001027{
1028 sblk->maxupscale = SSPP_UNITY_SCALE;
1029 sblk->maxdwnscale = SSPP_UNITY_SCALE;
Clarence Ip32bcb002017-03-13 12:26:44 -07001030 sblk->format_list = sde_cfg->dma_formats;
Steve Cohen57428172017-07-18 10:57:17 -04001031 sblk->virt_format_list = sde_cfg->dma_formats;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001032 sspp->id = SSPP_DMA0 + *dma_count;
Alan Kwong04780ec2016-10-12 16:05:17 -04001033 sspp->clk_ctrl = SDE_CLK_CTRL_DMA0 + *dma_count;
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -07001034 snprintf(sspp->name, SDE_HW_BLK_NAME_LEN, "sspp_%u",
1035 sspp->id - SSPP_VIG0);
abeykunf35ff332016-12-20 13:06:09 -05001036 sspp->type = SSPP_TYPE_DMA;
Alan Kwong41b099e2016-10-12 17:10:11 -04001037 set_bit(SDE_SSPP_QOS, &sspp->features);
Alan Kwongdce56da2017-04-27 15:50:34 -07001038 if (sde_cfg->vbif_qos_nlvl == 8)
1039 set_bit(SDE_SSPP_QOS_8LVL, &sspp->features);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001040 (*dma_count)++;
1041}
1042
1043static int sde_sspp_parse_dt(struct device_node *np,
1044 struct sde_mdss_cfg *sde_cfg)
1045{
Benet Clark37809e62016-10-24 10:14:00 -07001046 int rc, prop_count[SSPP_PROP_MAX], off_count, i, j;
1047 int vig_prop_count[VIG_PROP_MAX], rgb_prop_count[RGB_PROP_MAX];
1048 bool prop_exists[SSPP_PROP_MAX], vig_prop_exists[VIG_PROP_MAX];
1049 bool rgb_prop_exists[RGB_PROP_MAX];
Clarence Ip613fd8a2016-11-29 19:01:39 -05001050 struct sde_prop_value *prop_value = NULL;
1051 struct sde_prop_value *vig_prop_value = NULL, *rgb_prop_value = NULL;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001052 const char *type;
1053 struct sde_sspp_cfg *sspp;
1054 struct sde_sspp_sub_blks *sblk;
1055 u32 vig_count = 0, dma_count = 0, rgb_count = 0, cursor_count = 0;
Benet Clark37809e62016-10-24 10:14:00 -07001056 struct device_node *snp = NULL;
1057
Clarence Ip613fd8a2016-11-29 19:01:39 -05001058 prop_value = kzalloc(SSPP_PROP_MAX *
1059 sizeof(struct sde_prop_value), GFP_KERNEL);
Benet Clark37809e62016-10-24 10:14:00 -07001060 if (!prop_value) {
1061 rc = -ENOMEM;
1062 goto end;
1063 }
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001064
1065 rc = _validate_dt_entry(np, sspp_prop, ARRAY_SIZE(sspp_prop),
1066 prop_count, &off_count);
1067 if (rc)
1068 goto end;
1069
1070 rc = _read_dt_entry(np, sspp_prop, ARRAY_SIZE(sspp_prop), prop_count,
Clarence Ip613fd8a2016-11-29 19:01:39 -05001071 prop_exists, prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001072 if (rc)
1073 goto end;
1074
1075 sde_cfg->sspp_count = off_count;
1076
Benet Clark37809e62016-10-24 10:14:00 -07001077 /* get vig feature dt properties if they exist */
1078 snp = of_get_child_by_name(np, sspp_prop[SSPP_VIG_BLOCKS].prop_name);
1079 if (snp) {
Clarence Ip613fd8a2016-11-29 19:01:39 -05001080 vig_prop_value = kzalloc(VIG_PROP_MAX *
1081 sizeof(struct sde_prop_value), GFP_KERNEL);
Benet Clark37809e62016-10-24 10:14:00 -07001082 if (!vig_prop_value) {
1083 rc = -ENOMEM;
1084 goto end;
1085 }
1086 rc = _validate_dt_entry(snp, vig_prop, ARRAY_SIZE(vig_prop),
1087 vig_prop_count, NULL);
1088 if (rc)
1089 goto end;
1090 rc = _read_dt_entry(snp, vig_prop, ARRAY_SIZE(vig_prop),
Clarence Ip613fd8a2016-11-29 19:01:39 -05001091 vig_prop_count, vig_prop_exists,
1092 vig_prop_value);
Benet Clark37809e62016-10-24 10:14:00 -07001093 }
1094
1095 /* get rgb feature dt properties if they exist */
1096 snp = of_get_child_by_name(np, sspp_prop[SSPP_RGB_BLOCKS].prop_name);
1097 if (snp) {
Clarence Ip613fd8a2016-11-29 19:01:39 -05001098 rgb_prop_value = kzalloc(RGB_PROP_MAX *
1099 sizeof(struct sde_prop_value),
1100 GFP_KERNEL);
Benet Clark37809e62016-10-24 10:14:00 -07001101 if (!rgb_prop_value) {
1102 rc = -ENOMEM;
1103 goto end;
1104 }
1105 rc = _validate_dt_entry(snp, rgb_prop, ARRAY_SIZE(rgb_prop),
1106 rgb_prop_count, NULL);
1107 if (rc)
1108 goto end;
1109 rc = _read_dt_entry(snp, rgb_prop, ARRAY_SIZE(rgb_prop),
Clarence Ip613fd8a2016-11-29 19:01:39 -05001110 rgb_prop_count, rgb_prop_exists,
1111 rgb_prop_value);
Benet Clark37809e62016-10-24 10:14:00 -07001112 }
1113
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001114 for (i = 0; i < off_count; i++) {
1115 sspp = sde_cfg->sspp + i;
1116 sblk = kzalloc(sizeof(*sblk), GFP_KERNEL);
1117 if (!sblk) {
1118 rc = -ENOMEM;
1119 /* catalog deinit will release the allocated blocks */
1120 goto end;
1121 }
1122 sspp->sblk = sblk;
1123
Benet Clark37809e62016-10-24 10:14:00 -07001124 sspp->base = PROP_VALUE_ACCESS(prop_value, SSPP_OFF, i);
Lloyd Atkinson77158732016-10-23 13:02:00 -04001125 sspp->len = PROP_VALUE_ACCESS(prop_value, SSPP_SIZE, 0);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001126 sblk->maxlinewidth = sde_cfg->max_sspp_linewidth;
1127
1128 set_bit(SDE_SSPP_SRC, &sspp->features);
Jeykumar Sankaran2e655032017-02-04 14:05:45 -08001129
Alan Kwong143f50c2017-04-28 07:34:28 -07001130 if (sde_cfg->has_cdp)
1131 set_bit(SDE_SSPP_CDP, &sspp->features);
1132
Alan Kwong2349d742017-04-20 08:27:30 -07001133 if (sde_cfg->ts_prefill_rev == 1) {
1134 set_bit(SDE_SSPP_TS_PREFILL, &sspp->features);
1135 } else if (sde_cfg->ts_prefill_rev == 2) {
1136 set_bit(SDE_SSPP_TS_PREFILL, &sspp->features);
1137 set_bit(SDE_SSPP_TS_PREFILL_REC1, &sspp->features);
1138 }
1139
Jeykumar Sankaran2e655032017-02-04 14:05:45 -08001140 sblk->smart_dma_priority =
1141 PROP_VALUE_ACCESS(prop_value, SSPP_SMART_DMA, i);
1142
1143 if (sblk->smart_dma_priority && sde_cfg->smart_dma_rev)
1144 set_bit(sde_cfg->smart_dma_rev, &sspp->features);
1145
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001146 sblk->src_blk.id = SDE_SSPP_SRC;
1147
1148 of_property_read_string_index(np,
1149 sspp_prop[SSPP_TYPE].prop_name, i, &type);
1150 if (!strcmp(type, "vig")) {
Benet Clark37809e62016-10-24 10:14:00 -07001151 _sde_sspp_setup_vig(sde_cfg, sspp, sblk,
1152 vig_prop_exists, vig_prop_value, &vig_count);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001153 } else if (!strcmp(type, "rgb")) {
Benet Clark37809e62016-10-24 10:14:00 -07001154 _sde_sspp_setup_rgb(sde_cfg, sspp, sblk,
1155 rgb_prop_exists, rgb_prop_value, &rgb_count);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001156 } else if (!strcmp(type, "cursor")) {
Benet Clark37809e62016-10-24 10:14:00 -07001157 /* No prop values for cursor pipes */
1158 _sde_sspp_setup_cursor(sde_cfg, sspp, sblk, NULL,
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001159 &cursor_count);
1160 } else if (!strcmp(type, "dma")) {
Benet Clark37809e62016-10-24 10:14:00 -07001161 /* No prop values for DMA pipes */
1162 _sde_sspp_setup_dma(sde_cfg, sspp, sblk, NULL,
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001163 &dma_count);
1164 } else {
1165 SDE_ERROR("invalid sspp type:%s\n", type);
1166 rc = -EINVAL;
1167 goto end;
1168 }
1169
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -07001170 snprintf(sblk->src_blk.name, SDE_HW_BLK_NAME_LEN, "sspp_src_%u",
1171 sspp->id - SSPP_VIG0);
1172
Dhaval Patele4da9d742017-06-19 16:51:21 -07001173 if (sspp->clk_ctrl >= SDE_CLK_CTRL_MAX) {
1174 SDE_ERROR("%s: invalid clk ctrl: %d\n",
1175 sblk->src_blk.name, sspp->clk_ctrl);
1176 rc = -EINVAL;
1177 goto end;
1178 }
1179
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001180 sblk->maxhdeciexp = MAX_HORZ_DECIMATION;
1181 sblk->maxvdeciexp = MAX_VERT_DECIMATION;
1182
Benet Clark37809e62016-10-24 10:14:00 -07001183 sspp->xin_id = PROP_VALUE_ACCESS(prop_value, SSPP_XIN, i);
Alan Kwong41b099e2016-10-12 17:10:11 -04001184 sblk->pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE;
Benet Clark37809e62016-10-24 10:14:00 -07001185 sblk->src_blk.len = PROP_VALUE_ACCESS(prop_value, SSPP_SIZE, 0);
Alan Kwong41b099e2016-10-12 17:10:11 -04001186
Veera Sundaram Sankaran02dd6ac2016-12-22 15:08:29 -08001187 if (PROP_VALUE_ACCESS(prop_value, SSPP_EXCL_RECT, i) == 1)
1188 set_bit(SDE_SSPP_EXCL_RECT, &sspp->features);
1189
Alan Kwong6259a382017-04-04 06:18:02 -07001190 if (prop_exists[SSPP_MAX_PER_PIPE_BW])
1191 sblk->max_per_pipe_bw = PROP_VALUE_ACCESS(prop_value,
1192 SSPP_MAX_PER_PIPE_BW, i);
1193 else
1194 sblk->max_per_pipe_bw = DEFAULT_MAX_PER_PIPE_BW;
1195
Alan Kwong04780ec2016-10-12 16:05:17 -04001196 for (j = 0; j < sde_cfg->mdp_count; j++) {
1197 sde_cfg->mdp[j].clk_ctrls[sspp->clk_ctrl].reg_off =
Clarence Ip613fd8a2016-11-29 19:01:39 -05001198 PROP_BITVALUE_ACCESS(prop_value,
1199 SSPP_CLK_CTRL, i, 0);
Alan Kwong04780ec2016-10-12 16:05:17 -04001200 sde_cfg->mdp[j].clk_ctrls[sspp->clk_ctrl].bit_off =
Clarence Ip613fd8a2016-11-29 19:01:39 -05001201 PROP_BITVALUE_ACCESS(prop_value,
1202 SSPP_CLK_CTRL, i, 1);
Alan Kwong04780ec2016-10-12 16:05:17 -04001203 }
1204
Alan Kwong41b099e2016-10-12 17:10:11 -04001205 SDE_DEBUG(
Alan Kwongdce56da2017-04-27 15:50:34 -07001206 "xin:%d ram:%d clk%d:%x/%d\n",
Alan Kwong41b099e2016-10-12 17:10:11 -04001207 sspp->xin_id,
Alan Kwong04780ec2016-10-12 16:05:17 -04001208 sblk->pixel_ram_size,
1209 sspp->clk_ctrl,
1210 sde_cfg->mdp[0].clk_ctrls[sspp->clk_ctrl].reg_off,
1211 sde_cfg->mdp[0].clk_ctrls[sspp->clk_ctrl].bit_off);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001212 }
1213
1214end:
Benet Clark37809e62016-10-24 10:14:00 -07001215 kfree(prop_value);
1216 kfree(vig_prop_value);
1217 kfree(rgb_prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001218 return rc;
1219}
1220
1221static int sde_ctl_parse_dt(struct device_node *np,
1222 struct sde_mdss_cfg *sde_cfg)
1223{
Benet Clark37809e62016-10-24 10:14:00 -07001224 int rc, prop_count[HW_PROP_MAX], i;
1225 bool prop_exists[HW_PROP_MAX];
Clarence Ip613fd8a2016-11-29 19:01:39 -05001226 struct sde_prop_value *prop_value = NULL;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001227 struct sde_ctl_cfg *ctl;
1228 u32 off_count;
1229
1230 if (!sde_cfg) {
1231 SDE_ERROR("invalid argument input param\n");
1232 rc = -EINVAL;
1233 goto end;
1234 }
1235
Clarence Ip613fd8a2016-11-29 19:01:39 -05001236 prop_value = kzalloc(HW_PROP_MAX *
1237 sizeof(struct sde_prop_value), GFP_KERNEL);
Benet Clark37809e62016-10-24 10:14:00 -07001238 if (!prop_value) {
1239 rc = -ENOMEM;
1240 goto end;
1241 }
1242
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001243 rc = _validate_dt_entry(np, ctl_prop, ARRAY_SIZE(ctl_prop), prop_count,
1244 &off_count);
1245 if (rc)
1246 goto end;
1247
1248 sde_cfg->ctl_count = off_count;
1249
1250 rc = _read_dt_entry(np, ctl_prop, ARRAY_SIZE(ctl_prop), prop_count,
Clarence Ip613fd8a2016-11-29 19:01:39 -05001251 prop_exists, prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001252 if (rc)
1253 goto end;
1254
1255 for (i = 0; i < off_count; i++) {
1256 ctl = sde_cfg->ctl + i;
Benet Clark37809e62016-10-24 10:14:00 -07001257 ctl->base = PROP_VALUE_ACCESS(prop_value, HW_OFF, i);
Lloyd Atkinson77158732016-10-23 13:02:00 -04001258 ctl->len = PROP_VALUE_ACCESS(prop_value, HW_LEN, 0);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001259 ctl->id = CTL_0 + i;
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -07001260 snprintf(ctl->name, SDE_HW_BLK_NAME_LEN, "ctl_%u",
1261 ctl->id - CTL_0);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001262
1263 if (i < MAX_SPLIT_DISPLAY_CTL)
1264 set_bit(SDE_CTL_SPLIT_DISPLAY, &ctl->features);
1265 if (i < MAX_PP_SPLIT_DISPLAY_CTL)
1266 set_bit(SDE_CTL_PINGPONG_SPLIT, &ctl->features);
Alan Kwong4dd64c82017-02-04 18:41:51 -08001267 if (sde_cfg->has_sbuf)
1268 set_bit(SDE_CTL_SBUF, &ctl->features);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001269 }
1270
1271end:
Benet Clark37809e62016-10-24 10:14:00 -07001272 kfree(prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001273 return rc;
1274}
1275
1276static int sde_mixer_parse_dt(struct device_node *np,
1277 struct sde_mdss_cfg *sde_cfg)
1278{
Veera Sundaram Sankaran370b9912017-01-10 18:03:42 -08001279 int rc, prop_count[MIXER_PROP_MAX], i, j;
Benet Clark37809e62016-10-24 10:14:00 -07001280 int blocks_prop_count[MIXER_BLOCKS_PROP_MAX];
Veera Sundaram Sankaran370b9912017-01-10 18:03:42 -08001281 int blend_prop_count[MIXER_BLEND_PROP_MAX];
Benet Clark37809e62016-10-24 10:14:00 -07001282 bool prop_exists[MIXER_PROP_MAX];
1283 bool blocks_prop_exists[MIXER_BLOCKS_PROP_MAX];
Veera Sundaram Sankaran370b9912017-01-10 18:03:42 -08001284 bool blend_prop_exists[MIXER_BLEND_PROP_MAX];
Clarence Ip613fd8a2016-11-29 19:01:39 -05001285 struct sde_prop_value *prop_value = NULL, *blocks_prop_value = NULL;
Veera Sundaram Sankaran370b9912017-01-10 18:03:42 -08001286 struct sde_prop_value *blend_prop_value = NULL;
1287 u32 off_count, blend_off_count, max_blendstages, lm_pair_mask;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001288 struct sde_lm_cfg *mixer;
1289 struct sde_lm_sub_blks *sblk;
1290 int pp_count, dspp_count;
1291 u32 pp_idx, dspp_idx;
Benet Clark37809e62016-10-24 10:14:00 -07001292 struct device_node *snp = NULL;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001293
1294 if (!sde_cfg) {
1295 SDE_ERROR("invalid argument input param\n");
1296 rc = -EINVAL;
1297 goto end;
1298 }
1299 max_blendstages = sde_cfg->max_mixer_blendstages;
1300
Clarence Ip613fd8a2016-11-29 19:01:39 -05001301 prop_value = kzalloc(MIXER_PROP_MAX *
1302 sizeof(struct sde_prop_value), GFP_KERNEL);
Benet Clark37809e62016-10-24 10:14:00 -07001303 if (!prop_value) {
1304 rc = -ENOMEM;
1305 goto end;
1306 }
1307
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001308 rc = _validate_dt_entry(np, mixer_prop, ARRAY_SIZE(mixer_prop),
1309 prop_count, &off_count);
1310 if (rc)
1311 goto end;
1312
1313 sde_cfg->mixer_count = off_count;
1314
1315 rc = _read_dt_entry(np, mixer_prop, ARRAY_SIZE(mixer_prop), prop_count,
Clarence Ip613fd8a2016-11-29 19:01:39 -05001316 prop_exists, prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001317 if (rc)
1318 goto end;
1319
1320 pp_count = sde_cfg->pingpong_count;
1321 dspp_count = sde_cfg->dspp_count;
1322
Benet Clark37809e62016-10-24 10:14:00 -07001323 /* get mixer feature dt properties if they exist */
1324 snp = of_get_child_by_name(np, mixer_prop[MIXER_BLOCKS].prop_name);
1325 if (snp) {
1326 blocks_prop_value = kzalloc(MIXER_BLOCKS_PROP_MAX *
Clarence Ip613fd8a2016-11-29 19:01:39 -05001327 MAX_SDE_HW_BLK * sizeof(struct sde_prop_value),
1328 GFP_KERNEL);
Benet Clark37809e62016-10-24 10:14:00 -07001329 if (!blocks_prop_value) {
1330 rc = -ENOMEM;
1331 goto end;
1332 }
1333 rc = _validate_dt_entry(snp, mixer_blocks_prop,
1334 ARRAY_SIZE(mixer_blocks_prop), blocks_prop_count, NULL);
1335 if (rc)
1336 goto end;
1337 rc = _read_dt_entry(snp, mixer_blocks_prop,
1338 ARRAY_SIZE(mixer_blocks_prop),
1339 blocks_prop_count, blocks_prop_exists,
Clarence Ip613fd8a2016-11-29 19:01:39 -05001340 blocks_prop_value);
Benet Clark37809e62016-10-24 10:14:00 -07001341 }
1342
Veera Sundaram Sankaran370b9912017-01-10 18:03:42 -08001343 /* get the blend_op register offsets */
1344 blend_prop_value = kzalloc(MIXER_BLEND_PROP_MAX *
1345 sizeof(struct sde_prop_value), GFP_KERNEL);
1346 if (!blend_prop_value) {
1347 rc = -ENOMEM;
1348 goto end;
1349 }
1350 rc = _validate_dt_entry(np, mixer_blend_prop,
1351 ARRAY_SIZE(mixer_blend_prop), blend_prop_count,
1352 &blend_off_count);
1353 if (rc)
1354 goto end;
1355
1356 rc = _read_dt_entry(np, mixer_blend_prop, ARRAY_SIZE(mixer_blend_prop),
1357 blend_prop_count, blend_prop_exists, blend_prop_value);
1358 if (rc)
1359 goto end;
1360
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001361 for (i = 0, pp_idx = 0, dspp_idx = 0; i < off_count; i++) {
1362 mixer = sde_cfg->mixer + i;
1363 sblk = kzalloc(sizeof(*sblk), GFP_KERNEL);
1364 if (!sblk) {
1365 rc = -ENOMEM;
1366 /* catalog deinit will release the allocated blocks */
1367 goto end;
1368 }
1369 mixer->sblk = sblk;
1370
Benet Clark37809e62016-10-24 10:14:00 -07001371 mixer->base = PROP_VALUE_ACCESS(prop_value, MIXER_OFF, i);
1372 mixer->len = PROP_VALUE_ACCESS(prop_value, MIXER_LEN, 0);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001373 mixer->id = LM_0 + i;
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -07001374 snprintf(mixer->name, SDE_HW_BLK_NAME_LEN, "lm_%u",
1375 mixer->id - LM_0);
Lloyd Atkinson77158732016-10-23 13:02:00 -04001376
Benet Clark37809e62016-10-24 10:14:00 -07001377 if (!prop_exists[MIXER_LEN])
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001378 mixer->len = DEFAULT_SDE_HW_BLOCK_LEN;
1379
Veera Sundaram Sankaran370b9912017-01-10 18:03:42 -08001380 lm_pair_mask = PROP_VALUE_ACCESS(prop_value,
1381 MIXER_PAIR_MASK, i);
1382 if (lm_pair_mask)
1383 mixer->lm_pair_mask = 1 << lm_pair_mask;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001384
1385 sblk->maxblendstages = max_blendstages;
1386 sblk->maxwidth = sde_cfg->max_mixer_width;
Veera Sundaram Sankaran370b9912017-01-10 18:03:42 -08001387
1388 for (j = 0; j < blend_off_count; j++)
1389 sblk->blendstage_base[j] =
1390 PROP_VALUE_ACCESS(blend_prop_value,
1391 MIXER_BLEND_OP_OFF, j);
1392
Dhaval Patel1964fb92016-10-13 19:28:08 -07001393 if (sde_cfg->has_src_split)
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001394 set_bit(SDE_MIXER_SOURCESPLIT, &mixer->features);
Veera Sundaram Sankaran3171ff82017-01-04 14:34:47 -08001395 if (sde_cfg->has_dim_layer)
1396 set_bit(SDE_DIM_LAYER, &mixer->features);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001397
1398 if ((i < ROT_LM_OFFSET) || (i >= LINE_LM_OFFSET)) {
1399 mixer->pingpong = pp_count > 0 ? pp_idx + PINGPONG_0
1400 : PINGPONG_MAX;
1401 mixer->dspp = dspp_count > 0 ? dspp_idx + DSPP_0
1402 : DSPP_MAX;
1403 pp_count--;
1404 dspp_count--;
1405 pp_idx++;
1406 dspp_idx++;
1407 } else {
1408 mixer->pingpong = PINGPONG_MAX;
1409 mixer->dspp = DSPP_MAX;
1410 }
Benet Clark37809e62016-10-24 10:14:00 -07001411
1412 sblk->gc.id = SDE_MIXER_GC;
1413 if (blocks_prop_value && blocks_prop_exists[MIXER_GC_PROP]) {
1414 sblk->gc.base = PROP_VALUE_ACCESS(blocks_prop_value,
1415 MIXER_GC_PROP, 0);
1416 sblk->gc.version = PROP_VALUE_ACCESS(blocks_prop_value,
1417 MIXER_GC_PROP, 1);
1418 sblk->gc.len = 0;
1419 set_bit(SDE_MIXER_GC, &mixer->features);
1420 }
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001421 }
1422
1423end:
Benet Clark37809e62016-10-24 10:14:00 -07001424 kfree(prop_value);
1425 kfree(blocks_prop_value);
Veera Sundaram Sankaran370b9912017-01-10 18:03:42 -08001426 kfree(blend_prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001427 return rc;
1428}
1429
1430static int sde_intf_parse_dt(struct device_node *np,
1431 struct sde_mdss_cfg *sde_cfg)
1432{
Benet Clark37809e62016-10-24 10:14:00 -07001433 int rc, prop_count[INTF_PROP_MAX], i;
Clarence Ip613fd8a2016-11-29 19:01:39 -05001434 struct sde_prop_value *prop_value = NULL;
Benet Clark37809e62016-10-24 10:14:00 -07001435 bool prop_exists[INTF_PROP_MAX];
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001436 u32 off_count;
1437 u32 dsi_count = 0, none_count = 0, hdmi_count = 0, dp_count = 0;
1438 const char *type;
1439 struct sde_intf_cfg *intf;
1440
1441 if (!sde_cfg) {
1442 SDE_ERROR("invalid argument\n");
1443 rc = -EINVAL;
1444 goto end;
1445 }
1446
Clarence Ip613fd8a2016-11-29 19:01:39 -05001447 prop_value = kzalloc(INTF_PROP_MAX *
1448 sizeof(struct sde_prop_value), GFP_KERNEL);
Benet Clark37809e62016-10-24 10:14:00 -07001449 if (!prop_value) {
1450 rc = -ENOMEM;
1451 goto end;
1452 }
1453
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001454 rc = _validate_dt_entry(np, intf_prop, ARRAY_SIZE(intf_prop),
1455 prop_count, &off_count);
1456 if (rc)
1457 goto end;
1458
1459 sde_cfg->intf_count = off_count;
1460
1461 rc = _read_dt_entry(np, intf_prop, ARRAY_SIZE(intf_prop), prop_count,
Clarence Ip613fd8a2016-11-29 19:01:39 -05001462 prop_exists, prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001463 if (rc)
1464 goto end;
1465
1466 for (i = 0; i < off_count; i++) {
1467 intf = sde_cfg->intf + i;
Benet Clark37809e62016-10-24 10:14:00 -07001468 intf->base = PROP_VALUE_ACCESS(prop_value, INTF_OFF, i);
1469 intf->len = PROP_VALUE_ACCESS(prop_value, INTF_LEN, 0);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001470 intf->id = INTF_0 + i;
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -07001471 snprintf(intf->name, SDE_HW_BLK_NAME_LEN, "intf_%u",
1472 intf->id - INTF_0);
Lloyd Atkinson77158732016-10-23 13:02:00 -04001473
Benet Clark37809e62016-10-24 10:14:00 -07001474 if (!prop_exists[INTF_LEN])
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001475 intf->len = DEFAULT_SDE_HW_BLOCK_LEN;
1476
1477 intf->prog_fetch_lines_worst_case =
Alan Kwong8ff35402017-06-05 19:41:40 -04001478 !prop_exists[INTF_PREFETCH] ?
1479 sde_cfg->perf.min_prefill_lines :
Benet Clark37809e62016-10-24 10:14:00 -07001480 PROP_VALUE_ACCESS(prop_value, INTF_PREFETCH, i);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001481
1482 of_property_read_string_index(np,
1483 intf_prop[INTF_TYPE].prop_name, i, &type);
1484 if (!strcmp(type, "dsi")) {
1485 intf->type = INTF_DSI;
1486 intf->controller_id = dsi_count;
1487 dsi_count++;
1488 } else if (!strcmp(type, "hdmi")) {
1489 intf->type = INTF_HDMI;
1490 intf->controller_id = hdmi_count;
1491 hdmi_count++;
1492 } else if (!strcmp(type, "dp")) {
1493 intf->type = INTF_DP;
1494 intf->controller_id = dp_count;
1495 dp_count++;
1496 } else {
1497 intf->type = INTF_NONE;
1498 intf->controller_id = none_count;
1499 none_count++;
1500 }
Alan Kwong4aacd532017-02-04 18:51:33 -08001501
1502 if (sde_cfg->has_sbuf)
1503 set_bit(SDE_INTF_ROT_START, &intf->features);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001504 }
1505
1506end:
Benet Clark37809e62016-10-24 10:14:00 -07001507 kfree(prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001508 return rc;
1509}
1510
1511static int sde_wb_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg)
1512{
Benet Clark37809e62016-10-24 10:14:00 -07001513 int rc, prop_count[WB_PROP_MAX], i, j;
Clarence Ip613fd8a2016-11-29 19:01:39 -05001514 struct sde_prop_value *prop_value = NULL;
Benet Clark37809e62016-10-24 10:14:00 -07001515 bool prop_exists[WB_PROP_MAX];
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001516 u32 off_count;
1517 struct sde_wb_cfg *wb;
1518 struct sde_wb_sub_blocks *sblk;
1519
1520 if (!sde_cfg) {
1521 SDE_ERROR("invalid argument\n");
1522 rc = -EINVAL;
1523 goto end;
1524 }
1525
Clarence Ip613fd8a2016-11-29 19:01:39 -05001526 prop_value = kzalloc(WB_PROP_MAX *
1527 sizeof(struct sde_prop_value), GFP_KERNEL);
Benet Clark37809e62016-10-24 10:14:00 -07001528 if (!prop_value) {
1529 rc = -ENOMEM;
1530 goto end;
1531 }
1532
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001533 rc = _validate_dt_entry(np, wb_prop, ARRAY_SIZE(wb_prop), prop_count,
1534 &off_count);
1535 if (rc)
1536 goto end;
1537
1538 sde_cfg->wb_count = off_count;
1539
1540 rc = _read_dt_entry(np, wb_prop, ARRAY_SIZE(wb_prop), prop_count,
Clarence Ip613fd8a2016-11-29 19:01:39 -05001541 prop_exists, prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001542 if (rc)
1543 goto end;
1544
1545 for (i = 0; i < off_count; i++) {
1546 wb = sde_cfg->wb + i;
1547 sblk = kzalloc(sizeof(*sblk), GFP_KERNEL);
1548 if (!sblk) {
1549 rc = -ENOMEM;
1550 /* catalog deinit will release the allocated blocks */
1551 goto end;
1552 }
1553 wb->sblk = sblk;
1554
Benet Clark37809e62016-10-24 10:14:00 -07001555 wb->base = PROP_VALUE_ACCESS(prop_value, WB_OFF, i);
1556 wb->id = WB_0 + PROP_VALUE_ACCESS(prop_value, WB_ID, i);
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -07001557 snprintf(wb->name, SDE_HW_BLK_NAME_LEN, "wb_%u",
1558 wb->id - WB_0);
Benet Clark37809e62016-10-24 10:14:00 -07001559 wb->clk_ctrl = SDE_CLK_CTRL_WB0 +
1560 PROP_VALUE_ACCESS(prop_value, WB_ID, i);
1561 wb->xin_id = PROP_VALUE_ACCESS(prop_value, WB_XIN_ID, i);
Alan Kwongd22ecec2017-05-02 14:41:17 -07001562
Dhaval Patele4da9d742017-06-19 16:51:21 -07001563 if (wb->clk_ctrl >= SDE_CLK_CTRL_MAX) {
1564 SDE_ERROR("%s: invalid clk ctrl: %d\n",
1565 wb->name, wb->clk_ctrl);
1566 rc = -EINVAL;
1567 goto end;
1568 }
1569
Alan Kwongd22ecec2017-05-02 14:41:17 -07001570 if (IS_SDE_MAJOR_MINOR_SAME((sde_cfg->hwversion),
1571 SDE_HW_VER_170))
1572 wb->vbif_idx = VBIF_NRT;
1573 else
1574 wb->vbif_idx = VBIF_RT;
1575
Benet Clark37809e62016-10-24 10:14:00 -07001576 wb->len = PROP_VALUE_ACCESS(prop_value, WB_LEN, 0);
Benet Clark37809e62016-10-24 10:14:00 -07001577 if (!prop_exists[WB_LEN])
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001578 wb->len = DEFAULT_SDE_HW_BLOCK_LEN;
1579 sblk->maxlinewidth = sde_cfg->max_wb_linewidth;
1580
Alan Kwong14627332016-10-12 16:44:00 -04001581 if (wb->id >= LINE_MODE_WB_OFFSET)
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001582 set_bit(SDE_WB_LINE_MODE, &wb->features);
1583 else
1584 set_bit(SDE_WB_BLOCK_MODE, &wb->features);
1585 set_bit(SDE_WB_TRAFFIC_SHAPER, &wb->features);
1586 set_bit(SDE_WB_YUV_CONFIG, &wb->features);
Alan Kwong04780ec2016-10-12 16:05:17 -04001587
Alan Kwong143f50c2017-04-28 07:34:28 -07001588 if (sde_cfg->has_cdp)
1589 set_bit(SDE_WB_CDP, &wb->features);
1590
Alan Kwongdce56da2017-04-27 15:50:34 -07001591 set_bit(SDE_WB_QOS, &wb->features);
1592 if (sde_cfg->vbif_qos_nlvl == 8)
1593 set_bit(SDE_WB_QOS_8LVL, &wb->features);
1594
Clarence Ip32bcb002017-03-13 12:26:44 -07001595 if (sde_cfg->has_wb_ubwc)
1596 set_bit(SDE_WB_UBWC, &wb->features);
1597
Alan Kwong04780ec2016-10-12 16:05:17 -04001598 for (j = 0; j < sde_cfg->mdp_count; j++) {
1599 sde_cfg->mdp[j].clk_ctrls[wb->clk_ctrl].reg_off =
Clarence Ip613fd8a2016-11-29 19:01:39 -05001600 PROP_BITVALUE_ACCESS(prop_value,
1601 WB_CLK_CTRL, i, 0);
Alan Kwong04780ec2016-10-12 16:05:17 -04001602 sde_cfg->mdp[j].clk_ctrls[wb->clk_ctrl].bit_off =
Clarence Ip613fd8a2016-11-29 19:01:39 -05001603 PROP_BITVALUE_ACCESS(prop_value,
1604 WB_CLK_CTRL, i, 1);
Alan Kwong04780ec2016-10-12 16:05:17 -04001605 }
1606
Clarence Ip32bcb002017-03-13 12:26:44 -07001607 wb->format_list = sde_cfg->wb_formats;
1608
Alan Kwong04780ec2016-10-12 16:05:17 -04001609 SDE_DEBUG(
1610 "wb:%d xin:%d vbif:%d clk%d:%x/%d\n",
1611 wb->id - WB_0,
1612 wb->xin_id,
1613 wb->vbif_idx,
1614 wb->clk_ctrl,
1615 sde_cfg->mdp[0].clk_ctrls[wb->clk_ctrl].reg_off,
1616 sde_cfg->mdp[0].clk_ctrls[wb->clk_ctrl].bit_off);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001617 }
1618
1619end:
Benet Clark37809e62016-10-24 10:14:00 -07001620 kfree(prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001621 return rc;
1622}
1623
Benet Clark37809e62016-10-24 10:14:00 -07001624static void _sde_dspp_setup_blocks(struct sde_mdss_cfg *sde_cfg,
1625 struct sde_dspp_cfg *dspp, struct sde_dspp_sub_blks *sblk,
Clarence Ip613fd8a2016-11-29 19:01:39 -05001626 bool *prop_exists, struct sde_prop_value *prop_value)
Benet Clark37809e62016-10-24 10:14:00 -07001627{
1628 sblk->igc.id = SDE_DSPP_IGC;
1629 if (prop_exists[DSPP_IGC_PROP]) {
1630 sblk->igc.base = PROP_VALUE_ACCESS(prop_value,
1631 DSPP_IGC_PROP, 0);
1632 sblk->igc.version = PROP_VALUE_ACCESS(prop_value,
1633 DSPP_IGC_PROP, 1);
1634 sblk->igc.len = 0;
1635 set_bit(SDE_DSPP_IGC, &dspp->features);
1636 }
1637
1638 sblk->pcc.id = SDE_DSPP_PCC;
1639 if (prop_exists[DSPP_PCC_PROP]) {
1640 sblk->pcc.base = PROP_VALUE_ACCESS(prop_value,
1641 DSPP_PCC_PROP, 0);
1642 sblk->pcc.version = PROP_VALUE_ACCESS(prop_value,
1643 DSPP_PCC_PROP, 1);
1644 sblk->pcc.len = 0;
1645 set_bit(SDE_DSPP_PCC, &dspp->features);
1646 }
1647
1648 sblk->gc.id = SDE_DSPP_GC;
1649 if (prop_exists[DSPP_GC_PROP]) {
1650 sblk->gc.base = PROP_VALUE_ACCESS(prop_value, DSPP_GC_PROP, 0);
1651 sblk->gc.version = PROP_VALUE_ACCESS(prop_value,
1652 DSPP_GC_PROP, 1);
1653 sblk->gc.len = 0;
1654 set_bit(SDE_DSPP_GC, &dspp->features);
1655 }
1656
1657 sblk->gamut.id = SDE_DSPP_GAMUT;
1658 if (prop_exists[DSPP_GAMUT_PROP]) {
1659 sblk->gamut.base = PROP_VALUE_ACCESS(prop_value,
1660 DSPP_GAMUT_PROP, 0);
1661 sblk->gamut.version = PROP_VALUE_ACCESS(prop_value,
1662 DSPP_GAMUT_PROP, 1);
1663 sblk->gamut.len = 0;
1664 set_bit(SDE_DSPP_GAMUT, &dspp->features);
1665 }
1666
1667 sblk->dither.id = SDE_DSPP_DITHER;
1668 if (prop_exists[DSPP_DITHER_PROP]) {
1669 sblk->dither.base = PROP_VALUE_ACCESS(prop_value,
1670 DSPP_DITHER_PROP, 0);
1671 sblk->dither.version = PROP_VALUE_ACCESS(prop_value,
1672 DSPP_DITHER_PROP, 1);
1673 sblk->dither.len = 0;
1674 set_bit(SDE_DSPP_DITHER, &dspp->features);
1675 }
1676
1677 sblk->hist.id = SDE_DSPP_HIST;
1678 if (prop_exists[DSPP_HIST_PROP]) {
1679 sblk->hist.base = PROP_VALUE_ACCESS(prop_value,
1680 DSPP_HIST_PROP, 0);
1681 sblk->hist.version = PROP_VALUE_ACCESS(prop_value,
1682 DSPP_HIST_PROP, 1);
1683 sblk->hist.len = 0;
1684 set_bit(SDE_DSPP_HIST, &dspp->features);
1685 }
1686
1687 sblk->hsic.id = SDE_DSPP_HSIC;
1688 if (prop_exists[DSPP_HSIC_PROP]) {
1689 sblk->hsic.base = PROP_VALUE_ACCESS(prop_value,
1690 DSPP_HSIC_PROP, 0);
1691 sblk->hsic.version = PROP_VALUE_ACCESS(prop_value,
1692 DSPP_HSIC_PROP, 1);
1693 sblk->hsic.len = 0;
1694 set_bit(SDE_DSPP_HSIC, &dspp->features);
1695 }
1696
1697 sblk->memcolor.id = SDE_DSPP_MEMCOLOR;
1698 if (prop_exists[DSPP_MEMCOLOR_PROP]) {
1699 sblk->memcolor.base = PROP_VALUE_ACCESS(prop_value,
1700 DSPP_MEMCOLOR_PROP, 0);
1701 sblk->memcolor.version = PROP_VALUE_ACCESS(prop_value,
1702 DSPP_MEMCOLOR_PROP, 1);
1703 sblk->memcolor.len = 0;
1704 set_bit(SDE_DSPP_MEMCOLOR, &dspp->features);
1705 }
1706
1707 sblk->sixzone.id = SDE_DSPP_SIXZONE;
1708 if (prop_exists[DSPP_SIXZONE_PROP]) {
1709 sblk->sixzone.base = PROP_VALUE_ACCESS(prop_value,
1710 DSPP_SIXZONE_PROP, 0);
1711 sblk->sixzone.version = PROP_VALUE_ACCESS(prop_value,
1712 DSPP_SIXZONE_PROP, 1);
1713 sblk->sixzone.len = 0;
1714 set_bit(SDE_DSPP_SIXZONE, &dspp->features);
1715 }
1716
1717 sblk->vlut.id = SDE_DSPP_VLUT;
1718 if (prop_exists[DSPP_VLUT_PROP]) {
1719 sblk->vlut.base = PROP_VALUE_ACCESS(prop_value,
1720 DSPP_VLUT_PROP, 0);
1721 sblk->vlut.version = PROP_VALUE_ACCESS(prop_value,
1722 DSPP_VLUT_PROP, 1);
1723 sblk->sixzone.len = 0;
1724 set_bit(SDE_DSPP_VLUT, &dspp->features);
1725 }
1726}
1727
Veera Sundaram Sankaran1e71ccb2017-05-24 18:48:50 -07001728static void _sde_inline_rot_parse_dt(struct device_node *np,
1729 struct sde_mdss_cfg *sde_cfg, struct sde_rot_cfg *rot)
1730{
1731 int rc, prop_count[INLINE_ROT_PROP_MAX], i, j, index;
1732 struct sde_prop_value *prop_value = NULL;
1733 bool prop_exists[INLINE_ROT_PROP_MAX];
1734 u32 off_count, sspp_count = 0, wb_count = 0;
1735 const char *type;
1736
1737 prop_value = kzalloc(INLINE_ROT_PROP_MAX *
1738 sizeof(struct sde_prop_value), GFP_KERNEL);
1739 if (!prop_value)
1740 return;
1741
1742 rc = _validate_dt_entry(np, inline_rot_prop,
1743 ARRAY_SIZE(inline_rot_prop), prop_count, &off_count);
1744 if (rc)
1745 goto end;
1746
1747 rc = _read_dt_entry(np, inline_rot_prop, ARRAY_SIZE(inline_rot_prop),
1748 prop_count, prop_exists, prop_value);
1749 if (rc)
1750 goto end;
1751
1752 for (i = 0; i < off_count; i++) {
1753 rot->vbif_cfg[i].xin_id = PROP_VALUE_ACCESS(prop_value,
1754 INLINE_ROT_XIN, i);
1755 of_property_read_string_index(np,
1756 inline_rot_prop[INLINE_ROT_XIN_TYPE].prop_name,
1757 i, &type);
1758
1759 if (!strcmp(type, "sspp")) {
1760 rot->vbif_cfg[i].num = INLINE_ROT0_SSPP + sspp_count;
1761 rot->vbif_cfg[i].is_read = true;
1762 rot->vbif_cfg[i].clk_ctrl =
1763 SDE_CLK_CTRL_INLINE_ROT0_SSPP
1764 + sspp_count;
1765 sspp_count++;
1766 } else if (!strcmp(type, "wb")) {
1767 rot->vbif_cfg[i].num = INLINE_ROT0_WB + wb_count;
1768 rot->vbif_cfg[i].is_read = false;
1769 rot->vbif_cfg[i].clk_ctrl =
1770 SDE_CLK_CTRL_INLINE_ROT0_WB
1771 + wb_count;
1772 wb_count++;
1773 } else {
1774 SDE_ERROR("invalid rotator vbif type:%s\n", type);
1775 goto end;
1776 }
1777
1778 index = rot->vbif_cfg[i].clk_ctrl;
1779 if (index < 0 || index >= SDE_CLK_CTRL_MAX) {
1780 SDE_ERROR("invalid clk_ctrl enum:%d\n", index);
1781 goto end;
1782 }
1783
1784 for (j = 0; j < sde_cfg->mdp_count; j++) {
1785 sde_cfg->mdp[j].clk_ctrls[index].reg_off =
1786 PROP_BITVALUE_ACCESS(prop_value,
1787 INLINE_ROT_CLK_CTRL, i, 0);
1788 sde_cfg->mdp[j].clk_ctrls[index].bit_off =
1789 PROP_BITVALUE_ACCESS(prop_value,
1790 INLINE_ROT_CLK_CTRL, i, 1);
1791 }
1792
1793 SDE_DEBUG("rot- xin:%d, num:%d, rd:%d, clk:%d:0x%x/%d\n",
1794 rot->vbif_cfg[i].xin_id,
1795 rot->vbif_cfg[i].num,
1796 rot->vbif_cfg[i].is_read,
1797 rot->vbif_cfg[i].clk_ctrl,
1798 sde_cfg->mdp[0].clk_ctrls[index].reg_off,
1799 sde_cfg->mdp[0].clk_ctrls[index].bit_off);
1800 }
1801
1802 rot->vbif_idx = VBIF_RT;
1803 rot->xin_count = off_count;
1804
1805end:
1806 kfree(prop_value);
1807}
1808
Alan Kwong4dd64c82017-02-04 18:41:51 -08001809static int sde_rot_parse_dt(struct device_node *np,
1810 struct sde_mdss_cfg *sde_cfg)
1811{
1812 struct sde_rot_cfg *rot;
1813 struct platform_device *pdev;
1814 struct of_phandle_args phargs;
1815 struct llcc_slice_desc *slice;
1816 int rc = 0, i;
1817
1818 if (!sde_cfg) {
1819 SDE_ERROR("invalid argument\n");
1820 rc = -EINVAL;
1821 goto end;
1822 }
1823
1824 for (i = 0; i < ROT_MAX; i++) {
1825 rot = sde_cfg->rot + sde_cfg->rot_count;
1826 rot->base = 0;
1827 rot->len = 0;
1828
1829 rc = of_parse_phandle_with_args(np,
1830 "qcom,sde-inline-rotator", "#list-cells",
1831 i, &phargs);
1832 if (rc) {
1833 rc = 0;
1834 break;
1835 } else if (!phargs.np || !phargs.args_count) {
1836 rc = -EINVAL;
1837 break;
1838 }
1839
1840 rot->id = ROT_0 + phargs.args[0];
1841
1842 pdev = of_find_device_by_node(phargs.np);
1843 if (pdev) {
1844 slice = llcc_slice_getd(&pdev->dev, "rotator");
1845 if (IS_ERR_OR_NULL(slice)) {
1846 rot->pdev = NULL;
1847 SDE_ERROR("failed to get system cache %ld\n",
1848 PTR_ERR(slice));
1849 } else {
1850 rot->scid = llcc_get_slice_id(slice);
1851 rot->slice_size = llcc_get_slice_size(slice);
1852 rot->pdev = pdev;
1853 llcc_slice_putd(slice);
Alan Kwong4dd64c82017-02-04 18:41:51 -08001854 SDE_DEBUG("rot:%d scid:%d slice_size:%zukb\n",
1855 rot->id, rot->scid,
1856 rot->slice_size);
Veera Sundaram Sankaran1e71ccb2017-05-24 18:48:50 -07001857 _sde_inline_rot_parse_dt(np, sde_cfg, rot);
1858 sde_cfg->rot_count++;
Alan Kwong4dd64c82017-02-04 18:41:51 -08001859 }
1860 } else {
1861 rot->pdev = NULL;
1862 SDE_ERROR("invalid sde rotator node\n");
1863 }
1864
1865 of_node_put(phargs.np);
1866 }
1867
1868 if (sde_cfg->rot_count) {
1869 sde_cfg->has_sbuf = true;
1870 sde_cfg->sbuf_headroom = DEFAULT_SBUF_HEADROOM;
1871 }
1872
1873end:
1874 return rc;
1875}
1876
Rajesh Yadavec93afb2017-06-08 19:28:33 +05301877static int sde_dspp_top_parse_dt(struct device_node *np,
1878 struct sde_mdss_cfg *sde_cfg)
1879{
1880 int rc, prop_count[DSPP_TOP_PROP_MAX];
1881 bool prop_exists[DSPP_TOP_PROP_MAX];
1882 struct sde_prop_value *prop_value = NULL;
1883 u32 off_count;
1884
1885 if (!sde_cfg) {
1886 SDE_ERROR("invalid argument\n");
1887 rc = -EINVAL;
1888 goto end;
1889 }
1890
1891 prop_value = kzalloc(DSPP_TOP_PROP_MAX *
1892 sizeof(struct sde_prop_value), GFP_KERNEL);
1893 if (!prop_value) {
1894 rc = -ENOMEM;
1895 goto end;
1896 }
1897
1898 rc = _validate_dt_entry(np, dspp_top_prop, ARRAY_SIZE(dspp_top_prop),
1899 prop_count, &off_count);
1900 if (rc)
1901 goto end;
1902
1903 rc = _read_dt_entry(np, dspp_top_prop, ARRAY_SIZE(dspp_top_prop),
1904 prop_count, prop_exists, prop_value);
1905 if (rc)
1906 goto end;
1907
1908 if (off_count != 1) {
1909 SDE_ERROR("invalid dspp_top off_count:%d\n", off_count);
1910 rc = -EINVAL;
1911 goto end;
1912 }
1913
1914 sde_cfg->dspp_top.base =
1915 PROP_VALUE_ACCESS(prop_value, DSPP_TOP_OFF, 0);
1916 sde_cfg->dspp_top.len =
1917 PROP_VALUE_ACCESS(prop_value, DSPP_TOP_SIZE, 0);
1918 snprintf(sde_cfg->dspp_top.name, SDE_HW_BLK_NAME_LEN, "dspp_top");
1919
1920end:
1921 kfree(prop_value);
1922 return rc;
1923}
1924
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001925static int sde_dspp_parse_dt(struct device_node *np,
1926 struct sde_mdss_cfg *sde_cfg)
1927{
Benet Clark37809e62016-10-24 10:14:00 -07001928 int rc, prop_count[DSPP_PROP_MAX], i;
1929 int ad_prop_count[AD_PROP_MAX];
1930 bool prop_exists[DSPP_PROP_MAX], ad_prop_exists[AD_PROP_MAX];
1931 bool blocks_prop_exists[DSPP_BLOCKS_PROP_MAX];
Clarence Ip613fd8a2016-11-29 19:01:39 -05001932 struct sde_prop_value *ad_prop_value = NULL;
Benet Clark37809e62016-10-24 10:14:00 -07001933 int blocks_prop_count[DSPP_BLOCKS_PROP_MAX];
Clarence Ip613fd8a2016-11-29 19:01:39 -05001934 struct sde_prop_value *prop_value = NULL, *blocks_prop_value = NULL;
Benet Clark37809e62016-10-24 10:14:00 -07001935 u32 off_count, ad_off_count;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001936 struct sde_dspp_cfg *dspp;
1937 struct sde_dspp_sub_blks *sblk;
Benet Clark37809e62016-10-24 10:14:00 -07001938 struct device_node *snp = NULL;
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001939
1940 if (!sde_cfg) {
1941 SDE_ERROR("invalid argument\n");
1942 rc = -EINVAL;
1943 goto end;
1944 }
1945
Clarence Ip613fd8a2016-11-29 19:01:39 -05001946 prop_value = kzalloc(DSPP_PROP_MAX *
1947 sizeof(struct sde_prop_value), GFP_KERNEL);
Benet Clark37809e62016-10-24 10:14:00 -07001948 if (!prop_value) {
1949 rc = -ENOMEM;
1950 goto end;
1951 }
1952
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001953 rc = _validate_dt_entry(np, dspp_prop, ARRAY_SIZE(dspp_prop),
1954 prop_count, &off_count);
1955 if (rc)
1956 goto end;
1957
1958 sde_cfg->dspp_count = off_count;
1959
1960 rc = _read_dt_entry(np, dspp_prop, ARRAY_SIZE(dspp_prop), prop_count,
Clarence Ip613fd8a2016-11-29 19:01:39 -05001961 prop_exists, prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07001962 if (rc)
1963 goto end;
1964
Benet Clark37809e62016-10-24 10:14:00 -07001965 /* Parse AD dtsi entries */
Clarence Ip613fd8a2016-11-29 19:01:39 -05001966 ad_prop_value = kzalloc(AD_PROP_MAX *
1967 sizeof(struct sde_prop_value), GFP_KERNEL);
Benet Clark37809e62016-10-24 10:14:00 -07001968 if (!ad_prop_value) {
1969 rc = -ENOMEM;
1970 goto end;
1971 }
1972 rc = _validate_dt_entry(np, ad_prop, ARRAY_SIZE(ad_prop),
1973 ad_prop_count, &ad_off_count);
1974 if (rc)
1975 goto end;
1976 rc = _read_dt_entry(np, ad_prop, ARRAY_SIZE(ad_prop), ad_prop_count,
Clarence Ip613fd8a2016-11-29 19:01:39 -05001977 ad_prop_exists, ad_prop_value);
Benet Clark37809e62016-10-24 10:14:00 -07001978 if (rc)
1979 goto end;
1980
1981 /* get DSPP feature dt properties if they exist */
1982 snp = of_get_child_by_name(np, dspp_prop[DSPP_BLOCKS].prop_name);
1983 if (snp) {
1984 blocks_prop_value = kzalloc(DSPP_BLOCKS_PROP_MAX *
Clarence Ip613fd8a2016-11-29 19:01:39 -05001985 MAX_SDE_HW_BLK * sizeof(struct sde_prop_value),
1986 GFP_KERNEL);
Benet Clark37809e62016-10-24 10:14:00 -07001987 if (!blocks_prop_value) {
1988 rc = -ENOMEM;
1989 goto end;
1990 }
1991 rc = _validate_dt_entry(snp, dspp_blocks_prop,
1992 ARRAY_SIZE(dspp_blocks_prop), blocks_prop_count, NULL);
1993 if (rc)
1994 goto end;
1995 rc = _read_dt_entry(snp, dspp_blocks_prop,
1996 ARRAY_SIZE(dspp_blocks_prop), blocks_prop_count,
Clarence Ip613fd8a2016-11-29 19:01:39 -05001997 blocks_prop_exists, blocks_prop_value);
Benet Clark37809e62016-10-24 10:14:00 -07001998 if (rc)
1999 goto end;
2000 }
2001
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002002 for (i = 0; i < off_count; i++) {
2003 dspp = sde_cfg->dspp + i;
Benet Clark37809e62016-10-24 10:14:00 -07002004 dspp->base = PROP_VALUE_ACCESS(prop_value, DSPP_OFF, i);
Lloyd Atkinson77158732016-10-23 13:02:00 -04002005 dspp->len = PROP_VALUE_ACCESS(prop_value, DSPP_SIZE, 0);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002006 dspp->id = DSPP_0 + i;
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -07002007 snprintf(dspp->name, SDE_HW_BLK_NAME_LEN, "dspp_%u",
2008 dspp->id - DSPP_0);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002009
2010 sblk = kzalloc(sizeof(*sblk), GFP_KERNEL);
2011 if (!sblk) {
2012 rc = -ENOMEM;
2013 /* catalog deinit will release the allocated blocks */
2014 goto end;
2015 }
2016 dspp->sblk = sblk;
2017
Benet Clark37809e62016-10-24 10:14:00 -07002018 if (blocks_prop_value)
2019 _sde_dspp_setup_blocks(sde_cfg, dspp, sblk,
2020 blocks_prop_exists, blocks_prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002021
Benet Clark37809e62016-10-24 10:14:00 -07002022 sblk->ad.id = SDE_DSPP_AD;
Gopikrishnaiah Anandan9ba43782017-01-31 18:23:08 -08002023 sde_cfg->ad_count = ad_off_count;
Benet Clark37809e62016-10-24 10:14:00 -07002024 if (ad_prop_value && (i < ad_off_count) &&
2025 ad_prop_exists[AD_OFF]) {
2026 sblk->ad.base = PROP_VALUE_ACCESS(ad_prop_value,
2027 AD_OFF, i);
2028 sblk->ad.version = PROP_VALUE_ACCESS(ad_prop_value,
2029 AD_VERSION, 0);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002030 set_bit(SDE_DSPP_AD, &dspp->features);
Benet Clark37809e62016-10-24 10:14:00 -07002031 }
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002032 }
2033
2034end:
Benet Clark37809e62016-10-24 10:14:00 -07002035 kfree(prop_value);
2036 kfree(ad_prop_value);
2037 kfree(blocks_prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002038 return rc;
2039}
2040
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08002041static int sde_dsc_parse_dt(struct device_node *np,
2042 struct sde_mdss_cfg *sde_cfg)
2043{
2044 int rc, prop_count[MAX_BLOCKS], i;
2045 struct sde_prop_value *prop_value = NULL;
2046 bool prop_exists[DSC_PROP_MAX];
2047 u32 off_count;
2048 struct sde_dsc_cfg *dsc;
2049
2050 if (!sde_cfg) {
2051 SDE_ERROR("invalid argument\n");
2052 rc = -EINVAL;
2053 goto end;
2054 }
2055
2056 prop_value = kzalloc(DSC_PROP_MAX *
2057 sizeof(struct sde_prop_value), GFP_KERNEL);
2058 if (!prop_value) {
2059 rc = -ENOMEM;
2060 goto end;
2061 }
2062
2063 rc = _validate_dt_entry(np, dsc_prop, ARRAY_SIZE(dsc_prop), prop_count,
2064 &off_count);
2065 if (rc)
2066 goto end;
2067
2068 sde_cfg->dsc_count = off_count;
2069
2070 rc = _read_dt_entry(np, dsc_prop, ARRAY_SIZE(dsc_prop), prop_count,
2071 prop_exists, prop_value);
2072 if (rc)
2073 goto end;
2074
2075 for (i = 0; i < off_count; i++) {
2076 dsc = sde_cfg->dsc + i;
2077 dsc->base = PROP_VALUE_ACCESS(prop_value, DSC_OFF, i);
2078 dsc->id = DSC_0 + i;
2079 dsc->len = PROP_VALUE_ACCESS(prop_value, DSC_LEN, 0);
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -07002080 snprintf(dsc->name, SDE_HW_BLK_NAME_LEN, "dsc_%u",
2081 dsc->id - DSC_0);
2082
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08002083 if (!prop_exists[DSC_LEN])
2084 dsc->len = DEFAULT_SDE_HW_BLOCK_LEN;
2085 }
2086
2087end:
2088 kfree(prop_value);
2089 return rc;
2090};
2091
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002092static int sde_cdm_parse_dt(struct device_node *np,
2093 struct sde_mdss_cfg *sde_cfg)
2094{
Benet Clark37809e62016-10-24 10:14:00 -07002095 int rc, prop_count[HW_PROP_MAX], i;
Clarence Ip613fd8a2016-11-29 19:01:39 -05002096 struct sde_prop_value *prop_value = NULL;
Benet Clark37809e62016-10-24 10:14:00 -07002097 bool prop_exists[HW_PROP_MAX];
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002098 u32 off_count;
2099 struct sde_cdm_cfg *cdm;
2100
2101 if (!sde_cfg) {
2102 SDE_ERROR("invalid argument\n");
2103 rc = -EINVAL;
2104 goto end;
2105 }
2106
Clarence Ip613fd8a2016-11-29 19:01:39 -05002107 prop_value = kzalloc(HW_PROP_MAX *
2108 sizeof(struct sde_prop_value), GFP_KERNEL);
Benet Clark37809e62016-10-24 10:14:00 -07002109 if (!prop_value) {
2110 rc = -ENOMEM;
2111 goto end;
2112 }
2113
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002114 rc = _validate_dt_entry(np, cdm_prop, ARRAY_SIZE(cdm_prop), prop_count,
2115 &off_count);
2116 if (rc)
2117 goto end;
2118
2119 sde_cfg->cdm_count = off_count;
2120
2121 rc = _read_dt_entry(np, cdm_prop, ARRAY_SIZE(cdm_prop), prop_count,
Clarence Ip613fd8a2016-11-29 19:01:39 -05002122 prop_exists, prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002123 if (rc)
2124 goto end;
2125
2126 for (i = 0; i < off_count; i++) {
2127 cdm = sde_cfg->cdm + i;
Benet Clark37809e62016-10-24 10:14:00 -07002128 cdm->base = PROP_VALUE_ACCESS(prop_value, HW_OFF, i);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002129 cdm->id = CDM_0 + i;
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -07002130 snprintf(cdm->name, SDE_HW_BLK_NAME_LEN, "cdm_%u",
2131 cdm->id - CDM_0);
Benet Clark37809e62016-10-24 10:14:00 -07002132 cdm->len = PROP_VALUE_ACCESS(prop_value, HW_LEN, 0);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002133
2134 /* intf3 and wb2 for cdm block */
2135 cdm->wb_connect = sde_cfg->wb_count ? BIT(WB_2) : BIT(31);
2136 cdm->intf_connect = sde_cfg->intf_count ? BIT(INTF_3) : BIT(31);
2137 }
2138
2139end:
Benet Clark37809e62016-10-24 10:14:00 -07002140 kfree(prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002141 return rc;
2142}
2143
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04002144static int sde_vbif_parse_dt(struct device_node *np,
2145 struct sde_mdss_cfg *sde_cfg)
2146{
Benet Clark37809e62016-10-24 10:14:00 -07002147 int rc, prop_count[VBIF_PROP_MAX], i, j, k;
Clarence Ip613fd8a2016-11-29 19:01:39 -05002148 struct sde_prop_value *prop_value = NULL;
Benet Clark37809e62016-10-24 10:14:00 -07002149 bool prop_exists[VBIF_PROP_MAX];
Alan Kwonga62eeb82017-04-19 08:57:55 -07002150 u32 off_count, vbif_len;
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04002151 struct sde_vbif_cfg *vbif;
2152
2153 if (!sde_cfg) {
2154 SDE_ERROR("invalid argument\n");
2155 rc = -EINVAL;
2156 goto end;
2157 }
2158
Clarence Ip613fd8a2016-11-29 19:01:39 -05002159 prop_value = kzalloc(VBIF_PROP_MAX *
2160 sizeof(struct sde_prop_value), GFP_KERNEL);
Benet Clark37809e62016-10-24 10:14:00 -07002161 if (!prop_value) {
2162 rc = -ENOMEM;
2163 goto end;
2164 }
2165
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04002166 rc = _validate_dt_entry(np, vbif_prop, ARRAY_SIZE(vbif_prop),
2167 prop_count, &off_count);
2168 if (rc)
2169 goto end;
2170
2171 rc = _validate_dt_entry(np, &vbif_prop[VBIF_DYNAMIC_OT_RD_LIMIT], 1,
Alan Kwonga62eeb82017-04-19 08:57:55 -07002172 &prop_count[VBIF_DYNAMIC_OT_RD_LIMIT], NULL);
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04002173 if (rc)
2174 goto end;
2175
2176 rc = _validate_dt_entry(np, &vbif_prop[VBIF_DYNAMIC_OT_WR_LIMIT], 1,
Alan Kwonga62eeb82017-04-19 08:57:55 -07002177 &prop_count[VBIF_DYNAMIC_OT_WR_LIMIT], NULL);
2178 if (rc)
2179 goto end;
2180
2181 rc = _validate_dt_entry(np, &vbif_prop[VBIF_QOS_RT_REMAP], 1,
2182 &prop_count[VBIF_QOS_RT_REMAP], NULL);
2183 if (rc)
2184 goto end;
2185
2186 rc = _validate_dt_entry(np, &vbif_prop[VBIF_QOS_NRT_REMAP], 1,
2187 &prop_count[VBIF_QOS_NRT_REMAP], NULL);
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04002188 if (rc)
2189 goto end;
2190
Clarence Ip7f0de632017-05-31 14:59:14 -04002191 rc = _validate_dt_entry(np, &vbif_prop[VBIF_MEMTYPE_0], 1,
2192 &prop_count[VBIF_MEMTYPE_0], NULL);
2193 if (rc)
2194 goto end;
2195
2196 rc = _validate_dt_entry(np, &vbif_prop[VBIF_MEMTYPE_1], 1,
2197 &prop_count[VBIF_MEMTYPE_1], NULL);
2198 if (rc)
2199 goto end;
2200
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04002201 sde_cfg->vbif_count = off_count;
2202
2203 rc = _read_dt_entry(np, vbif_prop, ARRAY_SIZE(vbif_prop), prop_count,
Clarence Ip613fd8a2016-11-29 19:01:39 -05002204 prop_exists, prop_value);
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04002205 if (rc)
2206 goto end;
2207
Benet Clark37809e62016-10-24 10:14:00 -07002208 vbif_len = PROP_VALUE_ACCESS(prop_value, VBIF_LEN, 0);
2209 if (!prop_exists[VBIF_LEN])
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04002210 vbif_len = DEFAULT_SDE_HW_BLOCK_LEN;
2211
2212 for (i = 0; i < off_count; i++) {
2213 vbif = sde_cfg->vbif + i;
Benet Clark37809e62016-10-24 10:14:00 -07002214 vbif->base = PROP_VALUE_ACCESS(prop_value, VBIF_OFF, i);
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04002215 vbif->len = vbif_len;
Benet Clark37809e62016-10-24 10:14:00 -07002216 vbif->id = VBIF_0 + PROP_VALUE_ACCESS(prop_value, VBIF_ID, i);
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -07002217 snprintf(vbif->name, SDE_HW_BLK_NAME_LEN, "vbif_%u",
2218 vbif->id - VBIF_0);
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04002219
2220 SDE_DEBUG("vbif:%d\n", vbif->id - VBIF_0);
2221
2222 vbif->xin_halt_timeout = VBIF_XIN_HALT_TIMEOUT;
2223
Benet Clark37809e62016-10-24 10:14:00 -07002224 vbif->default_ot_rd_limit = PROP_VALUE_ACCESS(prop_value,
2225 VBIF_DEFAULT_OT_RD_LIMIT, 0);
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04002226 SDE_DEBUG("default_ot_rd_limit=%u\n",
2227 vbif->default_ot_rd_limit);
2228
Benet Clark37809e62016-10-24 10:14:00 -07002229 vbif->default_ot_wr_limit = PROP_VALUE_ACCESS(prop_value,
2230 VBIF_DEFAULT_OT_WR_LIMIT, 0);
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04002231 SDE_DEBUG("default_ot_wr_limit=%u\n",
2232 vbif->default_ot_wr_limit);
2233
2234 vbif->dynamic_ot_rd_tbl.count =
2235 prop_count[VBIF_DYNAMIC_OT_RD_LIMIT] / 2;
2236 SDE_DEBUG("dynamic_ot_rd_tbl.count=%u\n",
2237 vbif->dynamic_ot_rd_tbl.count);
2238 if (vbif->dynamic_ot_rd_tbl.count) {
2239 vbif->dynamic_ot_rd_tbl.cfg = kcalloc(
2240 vbif->dynamic_ot_rd_tbl.count,
2241 sizeof(struct sde_vbif_dynamic_ot_cfg),
2242 GFP_KERNEL);
2243 if (!vbif->dynamic_ot_rd_tbl.cfg) {
2244 rc = -ENOMEM;
2245 goto end;
2246 }
2247 }
2248
2249 for (j = 0, k = 0; j < vbif->dynamic_ot_rd_tbl.count; j++) {
2250 vbif->dynamic_ot_rd_tbl.cfg[j].pps = (u64)
Benet Clark37809e62016-10-24 10:14:00 -07002251 PROP_VALUE_ACCESS(prop_value,
2252 VBIF_DYNAMIC_OT_RD_LIMIT, k++);
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04002253 vbif->dynamic_ot_rd_tbl.cfg[j].ot_limit =
Benet Clark37809e62016-10-24 10:14:00 -07002254 PROP_VALUE_ACCESS(prop_value,
2255 VBIF_DYNAMIC_OT_RD_LIMIT, k++);
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04002256 SDE_DEBUG("dynamic_ot_rd_tbl[%d].cfg=<%llu %u>\n", j,
2257 vbif->dynamic_ot_rd_tbl.cfg[j].pps,
2258 vbif->dynamic_ot_rd_tbl.cfg[j].ot_limit);
2259 }
2260
2261 vbif->dynamic_ot_wr_tbl.count =
2262 prop_count[VBIF_DYNAMIC_OT_WR_LIMIT] / 2;
2263 SDE_DEBUG("dynamic_ot_wr_tbl.count=%u\n",
2264 vbif->dynamic_ot_wr_tbl.count);
2265 if (vbif->dynamic_ot_wr_tbl.count) {
2266 vbif->dynamic_ot_wr_tbl.cfg = kcalloc(
2267 vbif->dynamic_ot_wr_tbl.count,
2268 sizeof(struct sde_vbif_dynamic_ot_cfg),
2269 GFP_KERNEL);
2270 if (!vbif->dynamic_ot_wr_tbl.cfg) {
2271 rc = -ENOMEM;
2272 goto end;
2273 }
2274 }
2275
2276 for (j = 0, k = 0; j < vbif->dynamic_ot_wr_tbl.count; j++) {
2277 vbif->dynamic_ot_wr_tbl.cfg[j].pps = (u64)
Benet Clark37809e62016-10-24 10:14:00 -07002278 PROP_VALUE_ACCESS(prop_value,
2279 VBIF_DYNAMIC_OT_WR_LIMIT, k++);
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04002280 vbif->dynamic_ot_wr_tbl.cfg[j].ot_limit =
Benet Clark37809e62016-10-24 10:14:00 -07002281 PROP_VALUE_ACCESS(prop_value,
2282 VBIF_DYNAMIC_OT_WR_LIMIT, k++);
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04002283 SDE_DEBUG("dynamic_ot_wr_tbl[%d].cfg=<%llu %u>\n", j,
2284 vbif->dynamic_ot_wr_tbl.cfg[j].pps,
2285 vbif->dynamic_ot_wr_tbl.cfg[j].ot_limit);
2286 }
2287
2288 if (vbif->default_ot_rd_limit || vbif->default_ot_wr_limit ||
2289 vbif->dynamic_ot_rd_tbl.count ||
2290 vbif->dynamic_ot_wr_tbl.count)
2291 set_bit(SDE_VBIF_QOS_OTLIM, &vbif->features);
Alan Kwonga62eeb82017-04-19 08:57:55 -07002292
2293 vbif->qos_rt_tbl.npriority_lvl =
2294 prop_count[VBIF_QOS_RT_REMAP];
2295 SDE_DEBUG("qos_rt_tbl.npriority_lvl=%u\n",
2296 vbif->qos_rt_tbl.npriority_lvl);
2297 if (vbif->qos_rt_tbl.npriority_lvl == sde_cfg->vbif_qos_nlvl) {
2298 vbif->qos_rt_tbl.priority_lvl = kcalloc(
2299 vbif->qos_rt_tbl.npriority_lvl, sizeof(u32),
2300 GFP_KERNEL);
2301 if (!vbif->qos_rt_tbl.priority_lvl) {
2302 rc = -ENOMEM;
2303 goto end;
2304 }
2305 } else if (vbif->qos_rt_tbl.npriority_lvl) {
2306 vbif->qos_rt_tbl.npriority_lvl = 0;
2307 vbif->qos_rt_tbl.priority_lvl = NULL;
2308 SDE_ERROR("invalid qos rt table\n");
2309 }
2310
2311 for (j = 0; j < vbif->qos_rt_tbl.npriority_lvl; j++) {
2312 vbif->qos_rt_tbl.priority_lvl[j] =
2313 PROP_VALUE_ACCESS(prop_value,
2314 VBIF_QOS_RT_REMAP, j);
2315 SDE_DEBUG("lvl[%d]=%u\n", j,
2316 vbif->qos_rt_tbl.priority_lvl[j]);
2317 }
2318
2319 vbif->qos_nrt_tbl.npriority_lvl =
2320 prop_count[VBIF_QOS_NRT_REMAP];
2321 SDE_DEBUG("qos_nrt_tbl.npriority_lvl=%u\n",
2322 vbif->qos_nrt_tbl.npriority_lvl);
2323
2324 if (vbif->qos_nrt_tbl.npriority_lvl == sde_cfg->vbif_qos_nlvl) {
2325 vbif->qos_nrt_tbl.priority_lvl = kcalloc(
2326 vbif->qos_nrt_tbl.npriority_lvl, sizeof(u32),
2327 GFP_KERNEL);
2328 if (!vbif->qos_nrt_tbl.priority_lvl) {
2329 rc = -ENOMEM;
2330 goto end;
2331 }
2332 } else if (vbif->qos_nrt_tbl.npriority_lvl) {
2333 vbif->qos_nrt_tbl.npriority_lvl = 0;
2334 vbif->qos_nrt_tbl.priority_lvl = NULL;
2335 SDE_ERROR("invalid qos nrt table\n");
2336 }
2337
2338 for (j = 0; j < vbif->qos_nrt_tbl.npriority_lvl; j++) {
2339 vbif->qos_nrt_tbl.priority_lvl[j] =
2340 PROP_VALUE_ACCESS(prop_value,
2341 VBIF_QOS_NRT_REMAP, j);
2342 SDE_DEBUG("lvl[%d]=%u\n", j,
2343 vbif->qos_nrt_tbl.priority_lvl[j]);
2344 }
2345
2346 if (vbif->qos_rt_tbl.npriority_lvl ||
2347 vbif->qos_nrt_tbl.npriority_lvl)
2348 set_bit(SDE_VBIF_QOS_REMAP, &vbif->features);
Clarence Ip7f0de632017-05-31 14:59:14 -04002349
2350 vbif->memtype_count = prop_count[VBIF_MEMTYPE_0] +
2351 prop_count[VBIF_MEMTYPE_1];
2352 if (vbif->memtype_count > MAX_XIN_COUNT) {
2353 vbif->memtype_count = 0;
2354 SDE_ERROR("too many memtype defs, ignoring entries\n");
2355 }
2356 for (j = 0, k = 0; j < prop_count[VBIF_MEMTYPE_0]; j++)
2357 vbif->memtype[k++] = PROP_VALUE_ACCESS(
2358 prop_value, VBIF_MEMTYPE_0, j);
2359 for (j = 0; j < prop_count[VBIF_MEMTYPE_1]; j++)
2360 vbif->memtype[k++] = PROP_VALUE_ACCESS(
2361 prop_value, VBIF_MEMTYPE_1, j);
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04002362 }
2363
2364end:
Benet Clark37809e62016-10-24 10:14:00 -07002365 kfree(prop_value);
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04002366 return rc;
2367}
2368
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002369static int sde_pp_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg)
2370{
Benet Clark37809e62016-10-24 10:14:00 -07002371 int rc, prop_count[PP_PROP_MAX], i;
Clarence Ip613fd8a2016-11-29 19:01:39 -05002372 struct sde_prop_value *prop_value = NULL;
Benet Clark37809e62016-10-24 10:14:00 -07002373 bool prop_exists[PP_PROP_MAX];
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002374 u32 off_count;
2375 struct sde_pingpong_cfg *pp;
2376 struct sde_pingpong_sub_blks *sblk;
2377
2378 if (!sde_cfg) {
2379 SDE_ERROR("invalid argument\n");
2380 rc = -EINVAL;
2381 goto end;
2382 }
2383
Clarence Ip613fd8a2016-11-29 19:01:39 -05002384 prop_value = kzalloc(PP_PROP_MAX *
2385 sizeof(struct sde_prop_value), GFP_KERNEL);
Benet Clark37809e62016-10-24 10:14:00 -07002386 if (!prop_value) {
2387 rc = -ENOMEM;
2388 goto end;
2389 }
2390
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002391 rc = _validate_dt_entry(np, pp_prop, ARRAY_SIZE(pp_prop), prop_count,
2392 &off_count);
2393 if (rc)
2394 goto end;
2395
2396 sde_cfg->pingpong_count = off_count;
2397
2398 rc = _read_dt_entry(np, pp_prop, ARRAY_SIZE(pp_prop), prop_count,
Clarence Ip613fd8a2016-11-29 19:01:39 -05002399 prop_exists, prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002400 if (rc)
2401 goto end;
2402
2403 for (i = 0; i < off_count; i++) {
2404 pp = sde_cfg->pingpong + i;
2405 sblk = kzalloc(sizeof(*sblk), GFP_KERNEL);
2406 if (!sblk) {
2407 rc = -ENOMEM;
2408 /* catalog deinit will release the allocated blocks */
2409 goto end;
2410 }
2411 pp->sblk = sblk;
2412
Benet Clark37809e62016-10-24 10:14:00 -07002413 pp->base = PROP_VALUE_ACCESS(prop_value, PP_OFF, i);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002414 pp->id = PINGPONG_0 + i;
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -07002415 snprintf(pp->name, SDE_HW_BLK_NAME_LEN, "pingpong_%u",
2416 pp->id - PINGPONG_0);
Benet Clark37809e62016-10-24 10:14:00 -07002417 pp->len = PROP_VALUE_ACCESS(prop_value, PP_LEN, 0);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002418
Benet Clark37809e62016-10-24 10:14:00 -07002419 sblk->te.base = PROP_VALUE_ACCESS(prop_value, TE_OFF, i);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002420 sblk->te.id = SDE_PINGPONG_TE;
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -07002421 snprintf(sblk->te.name, SDE_HW_BLK_NAME_LEN, "te_%u",
2422 pp->id - PINGPONG_0);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002423 set_bit(SDE_PINGPONG_TE, &pp->features);
2424
Benet Clark37809e62016-10-24 10:14:00 -07002425 sblk->te2.base = PROP_VALUE_ACCESS(prop_value, TE2_OFF, i);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002426 if (sblk->te2.base) {
2427 sblk->te2.id = SDE_PINGPONG_TE2;
Lloyd Atkinson77158732016-10-23 13:02:00 -04002428 snprintf(sblk->te2.name, SDE_HW_BLK_NAME_LEN, "te2_%u",
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -07002429 pp->id - PINGPONG_0);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002430 set_bit(SDE_PINGPONG_TE2, &pp->features);
2431 set_bit(SDE_PINGPONG_SPLIT, &pp->features);
2432 }
2433
Clarence Ip8e69ad02016-12-09 09:43:57 -05002434 if (PROP_VALUE_ACCESS(prop_value, PP_SLAVE, i))
2435 set_bit(SDE_PINGPONG_SLAVE, &pp->features);
2436
Benet Clark37809e62016-10-24 10:14:00 -07002437 sblk->dsc.base = PROP_VALUE_ACCESS(prop_value, DSC_OFF, i);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002438 if (sblk->dsc.base) {
2439 sblk->dsc.id = SDE_PINGPONG_DSC;
Lloyd Atkinson77158732016-10-23 13:02:00 -04002440 snprintf(sblk->dsc.name, SDE_HW_BLK_NAME_LEN, "dsc_%u",
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -07002441 pp->id - PINGPONG_0);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002442 set_bit(SDE_PINGPONG_DSC, &pp->features);
2443 }
Ping Li8430ee12017-02-24 14:14:44 -08002444
2445 sblk->dither.base = PROP_VALUE_ACCESS(prop_value, DITHER_OFF,
2446 i);
2447 if (sblk->dither.base) {
2448 sblk->dither.id = SDE_PINGPONG_DITHER;
2449 snprintf(sblk->dither.name, SDE_HW_BLK_NAME_LEN,
2450 "dither_%u", pp->id);
2451 set_bit(SDE_PINGPONG_DITHER, &pp->features);
2452 }
2453 sblk->dither.len = PROP_VALUE_ACCESS(prop_value, DITHER_LEN, 0);
2454 sblk->dither.version = PROP_VALUE_ACCESS(prop_value, DITHER_VER,
2455 0);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002456 }
2457
2458end:
Benet Clark37809e62016-10-24 10:14:00 -07002459 kfree(prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002460 return rc;
2461}
2462
2463static int sde_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg)
2464{
Jeykumar Sankaran2e655032017-02-04 14:05:45 -08002465 int rc, dma_rc, len, prop_count[SDE_PROP_MAX];
Clarence Ip613fd8a2016-11-29 19:01:39 -05002466 struct sde_prop_value *prop_value = NULL;
Benet Clark37809e62016-10-24 10:14:00 -07002467 bool prop_exists[SDE_PROP_MAX];
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002468 const char *type;
2469
2470 if (!cfg) {
2471 SDE_ERROR("invalid argument\n");
2472 rc = -EINVAL;
2473 goto end;
2474 }
2475
Clarence Ip613fd8a2016-11-29 19:01:39 -05002476 prop_value = kzalloc(SDE_PROP_MAX *
2477 sizeof(struct sde_prop_value), GFP_KERNEL);
Benet Clark37809e62016-10-24 10:14:00 -07002478 if (!prop_value) {
2479 rc = -ENOMEM;
2480 goto end;
2481 }
2482
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002483 rc = _validate_dt_entry(np, sde_prop, ARRAY_SIZE(sde_prop), prop_count,
2484 &len);
2485 if (rc)
2486 goto end;
2487
2488 rc = _read_dt_entry(np, sde_prop, ARRAY_SIZE(sde_prop), prop_count,
Clarence Ip613fd8a2016-11-29 19:01:39 -05002489 prop_exists, prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002490 if (rc)
2491 goto end;
2492
2493 cfg->mdss_count = 1;
2494 cfg->mdss[0].base = MDSS_BASE_OFFSET;
2495 cfg->mdss[0].id = MDP_TOP;
Lloyd Atkinson77158732016-10-23 13:02:00 -04002496 snprintf(cfg->mdss[0].name, SDE_HW_BLK_NAME_LEN, "mdss_%u",
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -07002497 cfg->mdss[0].id - MDP_TOP);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002498
2499 cfg->mdp_count = 1;
2500 cfg->mdp[0].id = MDP_TOP;
Lloyd Atkinson77158732016-10-23 13:02:00 -04002501 snprintf(cfg->mdp[0].name, SDE_HW_BLK_NAME_LEN, "top_%u",
Lloyd Atkinsonac4b6e02017-03-23 11:43:48 -07002502 cfg->mdp[0].id - MDP_TOP);
Benet Clark37809e62016-10-24 10:14:00 -07002503 cfg->mdp[0].base = PROP_VALUE_ACCESS(prop_value, SDE_OFF, 0);
2504 cfg->mdp[0].len = PROP_VALUE_ACCESS(prop_value, SDE_LEN, 0);
2505 if (!prop_exists[SDE_LEN])
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002506 cfg->mdp[0].len = DEFAULT_SDE_HW_BLOCK_LEN;
2507
Benet Clark37809e62016-10-24 10:14:00 -07002508 cfg->max_sspp_linewidth = PROP_VALUE_ACCESS(prop_value,
2509 SSPP_LINEWIDTH, 0);
2510 if (!prop_exists[SSPP_LINEWIDTH])
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002511 cfg->max_sspp_linewidth = DEFAULT_SDE_LINE_WIDTH;
2512
Benet Clark37809e62016-10-24 10:14:00 -07002513 cfg->max_mixer_width = PROP_VALUE_ACCESS(prop_value,
2514 MIXER_LINEWIDTH, 0);
2515 if (!prop_exists[MIXER_LINEWIDTH])
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002516 cfg->max_mixer_width = DEFAULT_SDE_LINE_WIDTH;
2517
Benet Clark37809e62016-10-24 10:14:00 -07002518 cfg->max_mixer_blendstages = PROP_VALUE_ACCESS(prop_value,
2519 MIXER_BLEND, 0);
2520 if (!prop_exists[MIXER_BLEND])
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002521 cfg->max_mixer_blendstages = DEFAULT_SDE_MIXER_BLENDSTAGES;
2522
Benet Clark37809e62016-10-24 10:14:00 -07002523 cfg->max_wb_linewidth = PROP_VALUE_ACCESS(prop_value, WB_LINEWIDTH, 0);
2524 if (!prop_exists[WB_LINEWIDTH])
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002525 cfg->max_wb_linewidth = DEFAULT_SDE_LINE_WIDTH;
2526
Benet Clark37809e62016-10-24 10:14:00 -07002527 cfg->mdp[0].highest_bank_bit = PROP_VALUE_ACCESS(prop_value,
2528 BANK_BIT, 0);
2529 if (!prop_exists[BANK_BIT])
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002530 cfg->mdp[0].highest_bank_bit = DEFAULT_SDE_HIGHEST_BANK_BIT;
2531
Clarence Ip32bcb002017-03-13 12:26:44 -07002532 cfg->ubwc_version = PROP_VALUE_ACCESS(prop_value, UBWC_VERSION, 0);
2533 if (!prop_exists[UBWC_VERSION])
2534 cfg->ubwc_version = DEFAULT_SDE_UBWC_VERSION;
2535
2536 cfg->mdp[0].ubwc_static = PROP_VALUE_ACCESS(prop_value, UBWC_STATIC, 0);
2537 if (!prop_exists[UBWC_STATIC])
2538 cfg->mdp[0].ubwc_static = DEFAULT_SDE_UBWC_STATIC;
2539
2540 cfg->mdp[0].ubwc_swizzle = PROP_VALUE_ACCESS(prop_value,
2541 UBWC_SWIZZLE, 0);
2542 if (!prop_exists[UBWC_SWIZZLE])
2543 cfg->mdp[0].ubwc_swizzle = DEFAULT_SDE_UBWC_SWIZZLE;
2544
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002545 rc = of_property_read_string(np, sde_prop[QSEED_TYPE].prop_name, &type);
Dhaval Patel0aee0972017-02-08 19:00:58 -08002546 if (!rc && !strcmp(type, "qseedv3")) {
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002547 cfg->qseed_type = SDE_SSPP_SCALER_QSEED3;
Dhaval Patel0aee0972017-02-08 19:00:58 -08002548 } else if (!rc && !strcmp(type, "qseedv2")) {
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002549 cfg->qseed_type = SDE_SSPP_SCALER_QSEED2;
Dhaval Patel0aee0972017-02-08 19:00:58 -08002550 } else if (rc) {
2551 SDE_DEBUG("invalid QSEED configuration\n");
2552 rc = 0;
2553 }
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002554
Dhaval Patel5aad7452017-01-12 09:59:31 -08002555 rc = of_property_read_string(np, sde_prop[CSC_TYPE].prop_name, &type);
Dhaval Patel0aee0972017-02-08 19:00:58 -08002556 if (!rc && !strcmp(type, "csc")) {
Dhaval Patel5aad7452017-01-12 09:59:31 -08002557 cfg->csc_type = SDE_SSPP_CSC;
Dhaval Patel0aee0972017-02-08 19:00:58 -08002558 } else if (!rc && !strcmp(type, "csc-10bit")) {
Dhaval Patel5aad7452017-01-12 09:59:31 -08002559 cfg->csc_type = SDE_SSPP_CSC_10BIT;
Dhaval Patel0aee0972017-02-08 19:00:58 -08002560 } else if (rc) {
2561 SDE_DEBUG("invalid csc configuration\n");
2562 rc = 0;
2563 }
Dhaval Patel5aad7452017-01-12 09:59:31 -08002564
Jeykumar Sankaran2e655032017-02-04 14:05:45 -08002565 /*
2566 * Current SDE support only Smart DMA 2.0.
2567 * No support for Smart DMA 1.0 yet.
2568 */
2569 cfg->smart_dma_rev = 0;
2570 dma_rc = of_property_read_string(np, sde_prop[SMART_DMA_REV].prop_name,
2571 &type);
2572 if (!dma_rc && !strcmp(type, "smart_dma_v2")) {
2573 cfg->smart_dma_rev = SDE_SSPP_SMART_DMA_V2;
2574 } else if (!dma_rc && !strcmp(type, "smart_dma_v1")) {
2575 SDE_ERROR("smart dma 1.0 is not supported in SDE\n");
2576 cfg->smart_dma_rev = 0;
2577 }
2578
Benet Clark37809e62016-10-24 10:14:00 -07002579 cfg->has_src_split = PROP_VALUE_ACCESS(prop_value, SRC_SPLIT, 0);
Veera Sundaram Sankaran3171ff82017-01-04 14:34:47 -08002580 cfg->has_dim_layer = PROP_VALUE_ACCESS(prop_value, DIM_LAYER, 0);
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002581 cfg->has_idle_pc = PROP_VALUE_ACCESS(prop_value, IDLE_PC, 0);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002582end:
Benet Clark37809e62016-10-24 10:14:00 -07002583 kfree(prop_value);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002584 return rc;
2585}
2586
Gopikrishnaiah Anandan031d8ff2016-12-15 16:58:45 -08002587static int sde_parse_reg_dma_dt(struct device_node *np,
2588 struct sde_mdss_cfg *sde_cfg)
2589{
2590 u32 val;
2591 int rc = 0;
2592 int i = 0;
2593
2594 sde_cfg->reg_dma_count = 0;
2595 for (i = 0; i < REG_DMA_PROP_MAX; i++) {
2596 rc = of_property_read_u32(np, reg_dma_prop[i].prop_name,
2597 &val);
2598 if (rc)
2599 break;
2600 switch (i) {
2601 case REG_DMA_OFF:
2602 sde_cfg->dma_cfg.base = val;
2603 break;
2604 case REG_DMA_VERSION:
2605 sde_cfg->dma_cfg.version = val;
2606 break;
2607 case REG_DMA_TRIGGER_OFF:
2608 sde_cfg->dma_cfg.trigger_sel_off = val;
2609 break;
2610 default:
2611 break;
2612 }
2613 }
2614 if (!rc && i == REG_DMA_PROP_MAX)
2615 sde_cfg->reg_dma_count = 1;
2616 /* reg dma is optional feature hence return 0 */
2617 return 0;
2618}
2619
Alan Kwong9aa061c2016-11-06 21:17:12 -05002620static int sde_perf_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg)
2621{
2622 int rc, len, prop_count[PERF_PROP_MAX];
2623 struct sde_prop_value *prop_value = NULL;
2624 bool prop_exists[PERF_PROP_MAX];
Alan Kwong6259a382017-04-04 06:18:02 -07002625 const char *str = NULL;
Alan Kwongdce56da2017-04-27 15:50:34 -07002626 int j, k;
Alan Kwong9aa061c2016-11-06 21:17:12 -05002627
2628 if (!cfg) {
2629 SDE_ERROR("invalid argument\n");
2630 rc = -EINVAL;
2631 goto end;
2632 }
2633
Dhaval Patele4da9d742017-06-19 16:51:21 -07002634 prop_value = kzalloc(PERF_PROP_MAX *
Alan Kwong9aa061c2016-11-06 21:17:12 -05002635 sizeof(struct sde_prop_value), GFP_KERNEL);
2636 if (!prop_value) {
2637 rc = -ENOMEM;
2638 goto end;
2639 }
2640
2641 rc = _validate_dt_entry(np, sde_perf_prop, ARRAY_SIZE(sde_perf_prop),
2642 prop_count, &len);
2643 if (rc)
2644 goto freeprop;
2645
Alan Kwongdce56da2017-04-27 15:50:34 -07002646 rc = _validate_dt_entry(np, &sde_perf_prop[PERF_DANGER_LUT], 1,
2647 &prop_count[PERF_DANGER_LUT], NULL);
2648 if (rc)
2649 goto freeprop;
2650
2651 rc = _validate_dt_entry(np, &sde_perf_prop[PERF_SAFE_LUT], 1,
2652 &prop_count[PERF_SAFE_LUT], NULL);
2653 if (rc)
2654 goto freeprop;
2655
2656 rc = _validate_dt_entry(np, &sde_perf_prop[PERF_QOS_LUT_LINEAR], 1,
2657 &prop_count[PERF_QOS_LUT_LINEAR], NULL);
2658 if (rc)
2659 goto freeprop;
2660
2661 rc = _validate_dt_entry(np, &sde_perf_prop[PERF_QOS_LUT_MACROTILE], 1,
2662 &prop_count[PERF_QOS_LUT_MACROTILE], NULL);
2663 if (rc)
2664 goto freeprop;
2665
2666 rc = _validate_dt_entry(np, &sde_perf_prop[PERF_QOS_LUT_NRT], 1,
2667 &prop_count[PERF_QOS_LUT_NRT], NULL);
2668 if (rc)
2669 goto freeprop;
2670
2671 rc = _validate_dt_entry(np, &sde_perf_prop[PERF_QOS_LUT_CWB], 1,
2672 &prop_count[PERF_QOS_LUT_CWB], NULL);
2673 if (rc)
2674 goto freeprop;
2675
Alan Kwong143f50c2017-04-28 07:34:28 -07002676 rc = _validate_dt_entry(np, &sde_perf_prop[PERF_CDP_SETTING], 1,
2677 &prop_count[PERF_CDP_SETTING], NULL);
2678 if (rc)
2679 goto freeprop;
2680
Alan Kwong9aa061c2016-11-06 21:17:12 -05002681 rc = _read_dt_entry(np, sde_perf_prop, ARRAY_SIZE(sde_perf_prop),
2682 prop_count, prop_exists, prop_value);
2683 if (rc)
2684 goto freeprop;
2685
2686 cfg->perf.max_bw_low =
Alan Kwong6259a382017-04-04 06:18:02 -07002687 prop_exists[PERF_MAX_BW_LOW] ?
2688 PROP_VALUE_ACCESS(prop_value, PERF_MAX_BW_LOW, 0) :
2689 DEFAULT_MAX_BW_LOW;
Alan Kwong9aa061c2016-11-06 21:17:12 -05002690 cfg->perf.max_bw_high =
Alan Kwong6259a382017-04-04 06:18:02 -07002691 prop_exists[PERF_MAX_BW_HIGH] ?
2692 PROP_VALUE_ACCESS(prop_value, PERF_MAX_BW_HIGH, 0) :
2693 DEFAULT_MAX_BW_HIGH;
2694
2695 /*
2696 * The following performance parameters (e.g. core_ib_ff) are
2697 * mapped directly as device tree string constants.
2698 */
2699 rc = of_property_read_string(np,
2700 sde_perf_prop[PERF_CORE_IB_FF].prop_name, &str);
2701 cfg->perf.core_ib_ff = rc ? DEFAULT_CORE_IB_FF : str;
2702 rc = of_property_read_string(np,
2703 sde_perf_prop[PERF_CORE_CLK_FF].prop_name, &str);
2704 cfg->perf.core_clk_ff = rc ? DEFAULT_CORE_CLK_FF : str;
2705 rc = of_property_read_string(np,
2706 sde_perf_prop[PERF_COMP_RATIO_RT].prop_name, &str);
2707 cfg->perf.comp_ratio_rt = rc ? DEFAULT_COMP_RATIO_RT : str;
2708 rc = of_property_read_string(np,
2709 sde_perf_prop[PERF_COMP_RATIO_NRT].prop_name, &str);
2710 cfg->perf.comp_ratio_nrt = rc ? DEFAULT_COMP_RATIO_NRT : str;
2711 rc = 0;
2712
2713 cfg->perf.undersized_prefill_lines =
2714 prop_exists[PERF_UNDERSIZED_PREFILL_LINES] ?
2715 PROP_VALUE_ACCESS(prop_value,
2716 PERF_UNDERSIZED_PREFILL_LINES, 0) :
2717 DEFAULT_UNDERSIZED_PREFILL_LINES;
2718 cfg->perf.xtra_prefill_lines =
2719 prop_exists[PERF_XTRA_PREFILL_LINES] ?
2720 PROP_VALUE_ACCESS(prop_value,
2721 PERF_XTRA_PREFILL_LINES, 0) :
2722 DEFAULT_XTRA_PREFILL_LINES;
2723 cfg->perf.dest_scale_prefill_lines =
2724 prop_exists[PERF_DEST_SCALE_PREFILL_LINES] ?
2725 PROP_VALUE_ACCESS(prop_value,
2726 PERF_DEST_SCALE_PREFILL_LINES, 0) :
2727 DEFAULT_DEST_SCALE_PREFILL_LINES;
2728 cfg->perf.macrotile_prefill_lines =
2729 prop_exists[PERF_MACROTILE_PREFILL_LINES] ?
2730 PROP_VALUE_ACCESS(prop_value,
2731 PERF_MACROTILE_PREFILL_LINES, 0) :
2732 DEFAULT_MACROTILE_PREFILL_LINES;
2733 cfg->perf.yuv_nv12_prefill_lines =
2734 prop_exists[PERF_YUV_NV12_PREFILL_LINES] ?
2735 PROP_VALUE_ACCESS(prop_value,
2736 PERF_YUV_NV12_PREFILL_LINES, 0) :
2737 DEFAULT_YUV_NV12_PREFILL_LINES;
2738 cfg->perf.linear_prefill_lines =
2739 prop_exists[PERF_LINEAR_PREFILL_LINES] ?
2740 PROP_VALUE_ACCESS(prop_value,
2741 PERF_LINEAR_PREFILL_LINES, 0) :
2742 DEFAULT_LINEAR_PREFILL_LINES;
2743 cfg->perf.downscaling_prefill_lines =
2744 prop_exists[PERF_DOWNSCALING_PREFILL_LINES] ?
2745 PROP_VALUE_ACCESS(prop_value,
2746 PERF_DOWNSCALING_PREFILL_LINES, 0) :
2747 DEFAULT_DOWNSCALING_PREFILL_LINES;
2748 cfg->perf.amortizable_threshold =
2749 prop_exists[PERF_AMORTIZABLE_THRESHOLD] ?
2750 PROP_VALUE_ACCESS(prop_value,
2751 PERF_AMORTIZABLE_THRESHOLD, 0) :
2752 DEFAULT_AMORTIZABLE_THRESHOLD;
Alan Kwong9aa061c2016-11-06 21:17:12 -05002753
Alan Kwongdce56da2017-04-27 15:50:34 -07002754 if (prop_exists[PERF_DANGER_LUT] && prop_count[PERF_DANGER_LUT] <=
2755 SDE_QOS_LUT_USAGE_MAX) {
2756 for (j = 0; j < prop_count[PERF_DANGER_LUT]; j++) {
2757 cfg->perf.danger_lut_tbl[j] =
2758 PROP_VALUE_ACCESS(prop_value,
2759 PERF_DANGER_LUT, j);
2760 SDE_DEBUG("danger usage:%d lut:0x%x\n",
2761 j, cfg->perf.danger_lut_tbl[j]);
2762 }
2763 }
2764
2765 if (prop_exists[PERF_SAFE_LUT] && prop_count[PERF_SAFE_LUT] <=
2766 SDE_QOS_LUT_USAGE_MAX) {
2767 for (j = 0; j < prop_count[PERF_SAFE_LUT]; j++) {
2768 cfg->perf.safe_lut_tbl[j] =
2769 PROP_VALUE_ACCESS(prop_value,
2770 PERF_SAFE_LUT, j);
2771 SDE_DEBUG("safe usage:%d lut:0x%x\n",
2772 j, cfg->perf.safe_lut_tbl[j]);
2773 }
2774 }
2775
2776 for (j = 0; j < SDE_QOS_LUT_USAGE_MAX; j++) {
2777 static const u32 prop_key[SDE_QOS_LUT_USAGE_MAX] = {
2778 [SDE_QOS_LUT_USAGE_LINEAR] =
2779 PERF_QOS_LUT_LINEAR,
2780 [SDE_QOS_LUT_USAGE_MACROTILE] =
2781 PERF_QOS_LUT_MACROTILE,
2782 [SDE_QOS_LUT_USAGE_NRT] =
2783 PERF_QOS_LUT_NRT,
2784 [SDE_QOS_LUT_USAGE_CWB] =
2785 PERF_QOS_LUT_CWB,
2786 };
2787 const u32 entry_size = 3;
2788 int m, count;
2789 int key = prop_key[j];
2790
2791 if (!prop_exists[key])
2792 continue;
2793
2794 count = prop_count[key] / entry_size;
2795
2796 cfg->perf.qos_lut_tbl[j].entries = kcalloc(count,
2797 sizeof(struct sde_qos_lut_entry), GFP_KERNEL);
2798 if (!cfg->perf.qos_lut_tbl[j].entries) {
2799 rc = -ENOMEM;
Dhaval Patele4da9d742017-06-19 16:51:21 -07002800 goto freeprop;
Alan Kwongdce56da2017-04-27 15:50:34 -07002801 }
2802
2803 for (k = 0, m = 0; k < count; k++, m += entry_size) {
2804 u64 lut_hi, lut_lo;
2805
2806 cfg->perf.qos_lut_tbl[j].entries[k].fl =
2807 PROP_VALUE_ACCESS(prop_value, key, m);
2808 lut_hi = PROP_VALUE_ACCESS(prop_value, key, m + 1);
2809 lut_lo = PROP_VALUE_ACCESS(prop_value, key, m + 2);
2810 cfg->perf.qos_lut_tbl[j].entries[k].lut =
2811 (lut_hi << 32) | lut_lo;
2812 SDE_DEBUG("usage:%d.%d fl:%d lut:0x%llx\n",
2813 j, k,
2814 cfg->perf.qos_lut_tbl[j].entries[k].fl,
2815 cfg->perf.qos_lut_tbl[j].entries[k].lut);
2816 }
2817 cfg->perf.qos_lut_tbl[j].nentry = count;
2818 }
2819
Alan Kwong143f50c2017-04-28 07:34:28 -07002820 if (prop_exists[PERF_CDP_SETTING]) {
2821 const u32 prop_size = 2;
2822 u32 count = prop_count[PERF_CDP_SETTING] / prop_size;
2823
2824 count = min_t(u32, count, SDE_PERF_CDP_USAGE_MAX);
2825
2826 for (j = 0; j < count; j++) {
2827 cfg->perf.cdp_cfg[j].rd_enable =
2828 PROP_VALUE_ACCESS(prop_value,
2829 PERF_CDP_SETTING, j * prop_size);
2830 cfg->perf.cdp_cfg[j].wr_enable =
2831 PROP_VALUE_ACCESS(prop_value,
2832 PERF_CDP_SETTING, j * prop_size + 1);
2833 SDE_DEBUG("cdp usage:%d rd:%d wr:%d\n",
2834 j, cfg->perf.cdp_cfg[j].rd_enable,
2835 cfg->perf.cdp_cfg[j].wr_enable);
2836 }
2837
2838 cfg->has_cdp = true;
2839 }
2840
Alan Kwong9aa061c2016-11-06 21:17:12 -05002841freeprop:
2842 kfree(prop_value);
2843end:
2844 return rc;
2845}
2846
abeykunf35ff332016-12-20 13:06:09 -05002847static int sde_hardware_format_caps(struct sde_mdss_cfg *sde_cfg,
2848 uint32_t hw_rev)
Dhaval Patel1964fb92016-10-13 19:28:08 -07002849{
Clarence Ip32bcb002017-03-13 12:26:44 -07002850 int rc = 0;
abeykunf35ff332016-12-20 13:06:09 -05002851 uint32_t dma_list_size, vig_list_size, wb2_list_size;
2852 uint32_t cursor_list_size = 0;
abeykunf35ff332016-12-20 13:06:09 -05002853 uint32_t index = 0;
2854
2855 if (IS_SDE_MAJOR_MINOR_SAME((hw_rev), SDE_HW_VER_300)) {
2856 cursor_list_size = ARRAY_SIZE(cursor_formats);
2857 sde_cfg->cursor_formats = kcalloc(cursor_list_size,
2858 sizeof(struct sde_format_extended), GFP_KERNEL);
2859 if (!sde_cfg->cursor_formats) {
2860 rc = -ENOMEM;
2861 goto end;
2862 }
Jeykumar Sankaranf55e65b2017-05-10 21:46:14 -07002863 index = sde_copy_formats(sde_cfg->cursor_formats,
abeykunf35ff332016-12-20 13:06:09 -05002864 cursor_list_size, 0, cursor_formats,
2865 ARRAY_SIZE(cursor_formats));
2866 }
2867
2868 dma_list_size = ARRAY_SIZE(plane_formats);
2869 vig_list_size = ARRAY_SIZE(plane_formats_yuv);
2870 wb2_list_size = ARRAY_SIZE(wb2_formats);
2871
2872 dma_list_size += ARRAY_SIZE(rgb_10bit_formats);
2873 vig_list_size += ARRAY_SIZE(rgb_10bit_formats)
2874 + ARRAY_SIZE(tp10_ubwc_formats)
2875 + ARRAY_SIZE(p010_formats);
abeykund2debcb2016-12-20 13:06:09 -05002876 if (IS_SDE_MAJOR_MINOR_SAME((hw_rev), SDE_HW_VER_400))
2877 vig_list_size += ARRAY_SIZE(p010_ubwc_formats);
2878
abeykunf35ff332016-12-20 13:06:09 -05002879 wb2_list_size += ARRAY_SIZE(rgb_10bit_formats)
2880 + ARRAY_SIZE(tp10_ubwc_formats);
2881
2882 sde_cfg->dma_formats = kcalloc(dma_list_size,
2883 sizeof(struct sde_format_extended), GFP_KERNEL);
2884 if (!sde_cfg->dma_formats) {
2885 rc = -ENOMEM;
2886 goto end;
2887 }
2888
2889 sde_cfg->vig_formats = kcalloc(vig_list_size,
2890 sizeof(struct sde_format_extended), GFP_KERNEL);
2891 if (!sde_cfg->vig_formats) {
2892 rc = -ENOMEM;
2893 goto end;
2894 }
2895
2896 sde_cfg->wb_formats = kcalloc(wb2_list_size,
2897 sizeof(struct sde_format_extended), GFP_KERNEL);
2898 if (!sde_cfg->wb_formats) {
2899 SDE_ERROR("failed to allocate wb format list\n");
2900 rc = -ENOMEM;
2901 goto end;
2902 }
2903
Jeykumar Sankaranf55e65b2017-05-10 21:46:14 -07002904 index = sde_copy_formats(sde_cfg->dma_formats, dma_list_size,
abeykunf35ff332016-12-20 13:06:09 -05002905 0, plane_formats, ARRAY_SIZE(plane_formats));
Jeykumar Sankaranf55e65b2017-05-10 21:46:14 -07002906 index += sde_copy_formats(sde_cfg->dma_formats, dma_list_size,
abeykunf35ff332016-12-20 13:06:09 -05002907 index, rgb_10bit_formats,
2908 ARRAY_SIZE(rgb_10bit_formats));
2909
Jeykumar Sankaranf55e65b2017-05-10 21:46:14 -07002910 index = sde_copy_formats(sde_cfg->vig_formats, vig_list_size,
abeykunf35ff332016-12-20 13:06:09 -05002911 0, plane_formats_yuv, ARRAY_SIZE(plane_formats_yuv));
Jeykumar Sankaranf55e65b2017-05-10 21:46:14 -07002912 index += sde_copy_formats(sde_cfg->vig_formats, vig_list_size,
abeykunf35ff332016-12-20 13:06:09 -05002913 index, rgb_10bit_formats,
2914 ARRAY_SIZE(rgb_10bit_formats));
Jeykumar Sankaranf55e65b2017-05-10 21:46:14 -07002915 index += sde_copy_formats(sde_cfg->vig_formats, vig_list_size,
abeykunf35ff332016-12-20 13:06:09 -05002916 index, p010_formats, ARRAY_SIZE(p010_formats));
abeykund2debcb2016-12-20 13:06:09 -05002917 if (IS_SDE_MAJOR_MINOR_SAME((hw_rev), SDE_HW_VER_400))
Jeykumar Sankaranf55e65b2017-05-10 21:46:14 -07002918 index += sde_copy_formats(sde_cfg->vig_formats,
abeykund2debcb2016-12-20 13:06:09 -05002919 vig_list_size, index, p010_ubwc_formats,
2920 ARRAY_SIZE(p010_ubwc_formats));
abeykunf35ff332016-12-20 13:06:09 -05002921
Jeykumar Sankaranf55e65b2017-05-10 21:46:14 -07002922 index += sde_copy_formats(sde_cfg->vig_formats, vig_list_size,
abeykunf35ff332016-12-20 13:06:09 -05002923 index, tp10_ubwc_formats,
2924 ARRAY_SIZE(tp10_ubwc_formats));
2925
Jeykumar Sankaranf55e65b2017-05-10 21:46:14 -07002926 index = sde_copy_formats(sde_cfg->wb_formats, wb2_list_size,
abeykunf35ff332016-12-20 13:06:09 -05002927 0, wb2_formats, ARRAY_SIZE(wb2_formats));
Jeykumar Sankaranf55e65b2017-05-10 21:46:14 -07002928 index += sde_copy_formats(sde_cfg->wb_formats, wb2_list_size,
abeykunf35ff332016-12-20 13:06:09 -05002929 index, rgb_10bit_formats,
2930 ARRAY_SIZE(rgb_10bit_formats));
Jeykumar Sankaranf55e65b2017-05-10 21:46:14 -07002931 index += sde_copy_formats(sde_cfg->wb_formats, wb2_list_size,
abeykunf35ff332016-12-20 13:06:09 -05002932 index, tp10_ubwc_formats,
2933 ARRAY_SIZE(tp10_ubwc_formats));
abeykunf35ff332016-12-20 13:06:09 -05002934end:
2935 return rc;
2936}
2937
Clarence Ip32bcb002017-03-13 12:26:44 -07002938static int _sde_hardware_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev)
abeykunf35ff332016-12-20 13:06:09 -05002939{
2940 int rc = 0;
2941
Clarence Ip32bcb002017-03-13 12:26:44 -07002942 if (!sde_cfg)
2943 return -EINVAL;
2944
Dhaval Patel5398f602017-03-25 18:25:18 -07002945 rc = sde_hardware_format_caps(sde_cfg, hw_rev);
2946
Dhaval Patel1964fb92016-10-13 19:28:08 -07002947 switch (hw_rev) {
2948 case SDE_HW_VER_170:
2949 case SDE_HW_VER_171:
2950 case SDE_HW_VER_172:
2951 /* update msm8996 target here */
Alan Kwong6259a382017-04-04 06:18:02 -07002952 sde_cfg->perf.min_prefill_lines = 21;
Dhaval Patel1964fb92016-10-13 19:28:08 -07002953 break;
2954 case SDE_HW_VER_300:
abeykunf35ff332016-12-20 13:06:09 -05002955 case SDE_HW_VER_301:
Alan Kwong6259a382017-04-04 06:18:02 -07002956 /* update msm8998 target here */
2957 sde_cfg->has_wb_ubwc = true;
2958 sde_cfg->perf.min_prefill_lines = 25;
Alan Kwonga62eeb82017-04-19 08:57:55 -07002959 sde_cfg->vbif_qos_nlvl = 4;
Alan Kwong2349d742017-04-20 08:27:30 -07002960 sde_cfg->ts_prefill_rev = 1;
2961 sde_cfg->perf.min_prefill_lines = 25;
Alan Kwong6259a382017-04-04 06:18:02 -07002962 break;
Dhaval Patel1964fb92016-10-13 19:28:08 -07002963 case SDE_HW_VER_400:
Alan Kwonga62eeb82017-04-19 08:57:55 -07002964 /* update sdm845 target here */
Clarence Ip32bcb002017-03-13 12:26:44 -07002965 sde_cfg->has_wb_ubwc = true;
Alan Kwong6259a382017-04-04 06:18:02 -07002966 sde_cfg->perf.min_prefill_lines = 24;
Alan Kwonga62eeb82017-04-19 08:57:55 -07002967 sde_cfg->vbif_qos_nlvl = 8;
Alan Kwong2349d742017-04-20 08:27:30 -07002968 sde_cfg->ts_prefill_rev = 2;
2969 sde_cfg->perf.min_prefill_lines = 24;
Dhaval Patel1964fb92016-10-13 19:28:08 -07002970 break;
Dhaval Patel5398f602017-03-25 18:25:18 -07002971 default:
Alan Kwong6259a382017-04-04 06:18:02 -07002972 sde_cfg->perf.min_prefill_lines = 0xffff;
Dhaval Patel5398f602017-03-25 18:25:18 -07002973 break;
Dhaval Patel1964fb92016-10-13 19:28:08 -07002974 }
abeykunf35ff332016-12-20 13:06:09 -05002975
2976 return rc;
Dhaval Patel1964fb92016-10-13 19:28:08 -07002977}
2978
Clarence Ip17162b52016-11-24 17:06:29 -05002979void sde_hw_catalog_deinit(struct sde_mdss_cfg *sde_cfg)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -07002980{
2981 int i;
2982
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002983 if (!sde_cfg)
2984 return;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -07002985
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07002986 for (i = 0; i < sde_cfg->sspp_count; i++)
2987 kfree(sde_cfg->sspp[i].sblk);
2988
2989 for (i = 0; i < sde_cfg->mixer_count; i++)
2990 kfree(sde_cfg->mixer[i].sblk);
2991
2992 for (i = 0; i < sde_cfg->wb_count; i++)
2993 kfree(sde_cfg->wb[i].sblk);
2994
2995 for (i = 0; i < sde_cfg->dspp_count; i++)
2996 kfree(sde_cfg->dspp[i].sblk);
2997
2998 for (i = 0; i < sde_cfg->pingpong_count; i++)
2999 kfree(sde_cfg->pingpong[i].sblk);
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04003000
3001 for (i = 0; i < sde_cfg->vbif_count; i++) {
3002 kfree(sde_cfg->vbif[i].dynamic_ot_rd_tbl.cfg);
3003 kfree(sde_cfg->vbif[i].dynamic_ot_wr_tbl.cfg);
Alan Kwonga62eeb82017-04-19 08:57:55 -07003004 kfree(sde_cfg->vbif[i].qos_rt_tbl.priority_lvl);
3005 kfree(sde_cfg->vbif[i].qos_nrt_tbl.priority_lvl);
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04003006 }
abeykunf35ff332016-12-20 13:06:09 -05003007
Alan Kwongdce56da2017-04-27 15:50:34 -07003008 for (i = 0; i < SDE_QOS_LUT_USAGE_MAX; i++)
3009 kfree(sde_cfg->perf.qos_lut_tbl[i].entries);
3010
abeykunf35ff332016-12-20 13:06:09 -05003011 kfree(sde_cfg->dma_formats);
3012 kfree(sde_cfg->cursor_formats);
3013 kfree(sde_cfg->vig_formats);
3014 kfree(sde_cfg->wb_formats);
3015
Clarence Ip17162b52016-11-24 17:06:29 -05003016 kfree(sde_cfg);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07003017}
3018
3019/*************************************************************
3020 * hardware catalog init
3021 *************************************************************/
3022struct sde_mdss_cfg *sde_hw_catalog_init(struct drm_device *dev, u32 hw_rev)
3023{
3024 int rc;
3025 struct sde_mdss_cfg *sde_cfg;
3026 struct device_node *np = dev->dev->of_node;
3027
3028 sde_cfg = kzalloc(sizeof(*sde_cfg), GFP_KERNEL);
3029 if (!sde_cfg)
3030 return ERR_PTR(-ENOMEM);
3031
3032 sde_cfg->hwversion = hw_rev;
3033
Clarence Ip32bcb002017-03-13 12:26:44 -07003034 rc = _sde_hardware_caps(sde_cfg, hw_rev);
3035 if (rc)
3036 goto end;
3037
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07003038 rc = sde_parse_dt(np, sde_cfg);
3039 if (rc)
3040 goto end;
3041
Alan Kwong143f50c2017-04-28 07:34:28 -07003042 rc = sde_perf_parse_dt(np, sde_cfg);
3043 if (rc)
3044 goto end;
3045
Alan Kwong4dd64c82017-02-04 18:41:51 -08003046 rc = sde_rot_parse_dt(np, sde_cfg);
3047 if (rc)
3048 goto end;
3049
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07003050 rc = sde_ctl_parse_dt(np, sde_cfg);
3051 if (rc)
3052 goto end;
3053
3054 rc = sde_sspp_parse_dt(np, sde_cfg);
3055 if (rc)
3056 goto end;
3057
Rajesh Yadavec93afb2017-06-08 19:28:33 +05303058 rc = sde_dspp_top_parse_dt(np, sde_cfg);
3059 if (rc)
3060 goto end;
3061
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07003062 rc = sde_dspp_parse_dt(np, sde_cfg);
3063 if (rc)
3064 goto end;
3065
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08003066 rc = sde_dsc_parse_dt(np, sde_cfg);
3067 if (rc)
3068 goto end;
3069
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07003070 rc = sde_pp_parse_dt(np, sde_cfg);
3071 if (rc)
3072 goto end;
3073
3074 /* mixer parsing should be done after dspp and pp for mapping setup */
3075 rc = sde_mixer_parse_dt(np, sde_cfg);
3076 if (rc)
3077 goto end;
3078
3079 rc = sde_intf_parse_dt(np, sde_cfg);
3080 if (rc)
3081 goto end;
3082
3083 rc = sde_wb_parse_dt(np, sde_cfg);
3084 if (rc)
3085 goto end;
3086
3087 /* cdm parsing should be done after intf and wb for mapping setup */
3088 rc = sde_cdm_parse_dt(np, sde_cfg);
3089 if (rc)
3090 goto end;
3091
Alan Kwongb9d2f6f2016-10-12 00:27:07 -04003092 rc = sde_vbif_parse_dt(np, sde_cfg);
3093 if (rc)
3094 goto end;
3095
Gopikrishnaiah Anandan031d8ff2016-12-15 16:58:45 -08003096 rc = sde_parse_reg_dma_dt(np, sde_cfg);
3097 if (rc)
3098 goto end;
3099
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07003100 return sde_cfg;
3101
3102end:
3103 sde_hw_catalog_deinit(sde_cfg);
Dhaval Patel8bf7ff32016-07-20 18:13:24 -07003104 return NULL;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -07003105}