blob: 88dc98f32ec2bf7cd8c5d4a3beeaf1e003cb2fe3 [file] [log] [blame]
Gopikrishnaiah Anandane3842f32015-11-05 12:18:41 -08001/* 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
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070013#include "sde_hwio.h"
14#include "sde_hw_catalog.h"
15#include "sde_hw_lm.h"
Clarence Ipe78efb72016-06-24 18:35:21 -040016#include "sde_hw_sspp.h"
Benet Clarkeb1b4462016-06-27 14:43:06 -070017#include "sde_hw_color_processing.h"
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070018
Lloyd Atkinson9a673492016-07-05 11:41:57 -040019#define SDE_FETCH_CONFIG_RESET_VALUE 0x00000087
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070020
21/* SDE_SSPP_SRC */
22#define SSPP_SRC_SIZE 0x00
23#define SSPP_SRC_XY 0x08
24#define SSPP_OUT_SIZE 0x0c
25#define SSPP_OUT_XY 0x10
26#define SSPP_SRC0_ADDR 0x14
27#define SSPP_SRC1_ADDR 0x18
28#define SSPP_SRC2_ADDR 0x1C
29#define SSPP_SRC3_ADDR 0x20
30#define SSPP_SRC_YSTRIDE0 0x24
31#define SSPP_SRC_YSTRIDE1 0x28
32#define SSPP_SRC_FORMAT 0x30
33#define SSPP_SRC_UNPACK_PATTERN 0x34
34#define SSPP_SRC_OP_MODE 0x38
35#define MDSS_MDP_OP_DEINTERLACE BIT(22)
36
37#define MDSS_MDP_OP_DEINTERLACE_ODD BIT(23)
38#define MDSS_MDP_OP_IGC_ROM_1 BIT(18)
39#define MDSS_MDP_OP_IGC_ROM_0 BIT(17)
40#define MDSS_MDP_OP_IGC_EN BIT(16)
41#define MDSS_MDP_OP_FLIP_UD BIT(14)
42#define MDSS_MDP_OP_FLIP_LR BIT(13)
43#define MDSS_MDP_OP_BWC_EN BIT(0)
44#define MDSS_MDP_OP_PE_OVERRIDE BIT(31)
45#define MDSS_MDP_OP_BWC_LOSSLESS (0 << 1)
46#define MDSS_MDP_OP_BWC_Q_HIGH (1 << 1)
47#define MDSS_MDP_OP_BWC_Q_MED (2 << 1)
48
49#define SSPP_SRC_CONSTANT_COLOR 0x3c
Veera Sundaram Sankaran02dd6ac2016-12-22 15:08:29 -080050#define SSPP_EXCL_REC_CTL 0x40
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070051#define SSPP_FETCH_CONFIG 0x048
52#define SSPP_DANGER_LUT 0x60
53#define SSPP_SAFE_LUT 0x64
54#define SSPP_CREQ_LUT 0x68
Alan Kwong1a00e4d2016-07-18 09:42:30 -040055#define SSPP_QOS_CTRL 0x6C
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070056#define SSPP_DECIMATION_CONFIG 0xB4
57#define SSPP_SRC_ADDR_SW_STATUS 0x70
58#define SSPP_SW_PIX_EXT_C0_LR 0x100
59#define SSPP_SW_PIX_EXT_C0_TB 0x104
60#define SSPP_SW_PIX_EXT_C0_REQ_PIXELS 0x108
61#define SSPP_SW_PIX_EXT_C1C2_LR 0x110
62#define SSPP_SW_PIX_EXT_C1C2_TB 0x114
63#define SSPP_SW_PIX_EXT_C1C2_REQ_PIXELS 0x118
64#define SSPP_SW_PIX_EXT_C3_LR 0x120
65#define SSPP_SW_PIX_EXT_C3_TB 0x124
66#define SSPP_SW_PIX_EXT_C3_REQ_PIXELS 0x128
67#define SSPP_UBWC_ERROR_STATUS 0x138
Veera Sundaram Sankaran02dd6ac2016-12-22 15:08:29 -080068#define SSPP_EXCL_REC_SIZE 0x1B4
69#define SSPP_EXCL_REC_XY 0x1B8
Clarence Ipe78efb72016-06-24 18:35:21 -040070#define SSPP_VIG_OP_MODE 0x0
abeykun62576142016-08-25 17:44:05 -040071#define SSPP_VIG_CSC_10_OP_MODE 0x0
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070072
Alan Kwong1a00e4d2016-07-18 09:42:30 -040073/* SSPP_QOS_CTRL */
74#define SSPP_QOS_CTRL_VBLANK_EN BIT(16)
75#define SSPP_QOS_CTRL_DANGER_SAFE_EN BIT(0)
76#define SSPP_QOS_CTRL_DANGER_VBLANK_MASK 0x3
77#define SSPP_QOS_CTRL_DANGER_VBLANK_OFF 4
78#define SSPP_QOS_CTRL_CREQ_VBLANK_MASK 0x3
79#define SSPP_QOS_CTRL_CREQ_VBLANK_OFF 20
80
Clarence Ipe78efb72016-06-24 18:35:21 -040081/* SDE_SSPP_SCALER_QSEED2 */
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070082#define SCALE_CONFIG 0x04
83#define COMP0_3_PHASE_STEP_X 0x10
84#define COMP0_3_PHASE_STEP_Y 0x14
85#define COMP1_2_PHASE_STEP_X 0x18
86#define COMP1_2_PHASE_STEP_Y 0x1c
87#define COMP0_3_INIT_PHASE_X 0x20
88#define COMP0_3_INIT_PHASE_Y 0x24
89#define COMP1_2_INIT_PHASE_X 0x28
90#define COMP1_2_INIT_PHASE_Y 0x2C
91#define VIG_0_QSEED2_SHARP 0x30
92
abeykun48f407a2016-08-25 12:06:44 -040093/* SDE_SSPP_SCALER_QSEED3 */
94#define QSEED3_HW_VERSION 0x00
95#define QSEED3_OP_MODE 0x04
96#define QSEED3_RGB2Y_COEFF 0x08
97#define QSEED3_PHASE_INIT 0x0C
98#define QSEED3_PHASE_STEP_Y_H 0x10
99#define QSEED3_PHASE_STEP_Y_V 0x14
100#define QSEED3_PHASE_STEP_UV_H 0x18
101#define QSEED3_PHASE_STEP_UV_V 0x1C
102#define QSEED3_PRELOAD 0x20
103#define QSEED3_DE_SHARPEN 0x24
104#define QSEED3_DE_SHARPEN_CTL 0x28
105#define QSEED3_DE_SHAPE_CTL 0x2C
106#define QSEED3_DE_THRESHOLD 0x30
107#define QSEED3_DE_ADJUST_DATA_0 0x34
108#define QSEED3_DE_ADJUST_DATA_1 0x38
109#define QSEED3_DE_ADJUST_DATA_2 0x3C
110#define QSEED3_SRC_SIZE_Y_RGB_A 0x40
111#define QSEED3_SRC_SIZE_UV 0x44
112#define QSEED3_DST_SIZE 0x48
113#define QSEED3_COEF_LUT_CTRL 0x4C
114#define QSEED3_COEF_LUT_SWAP_BIT 0
115#define QSEED3_COEF_LUT_DIR_BIT 1
116#define QSEED3_COEF_LUT_Y_CIR_BIT 2
117#define QSEED3_COEF_LUT_UV_CIR_BIT 3
118#define QSEED3_COEF_LUT_Y_SEP_BIT 4
119#define QSEED3_COEF_LUT_UV_SEP_BIT 5
120#define QSEED3_BUFFER_CTRL 0x50
121#define QSEED3_CLK_CTRL0 0x54
122#define QSEED3_CLK_CTRL1 0x58
123#define QSEED3_CLK_STATUS 0x5C
124#define QSEED3_MISR_CTRL 0x70
125#define QSEED3_MISR_SIGNATURE_0 0x74
126#define QSEED3_MISR_SIGNATURE_1 0x78
127#define QSEED3_PHASE_INIT_Y_H 0x90
128#define QSEED3_PHASE_INIT_Y_V 0x94
129#define QSEED3_PHASE_INIT_UV_H 0x98
130#define QSEED3_PHASE_INIT_UV_V 0x9C
131#define QSEED3_COEF_LUT 0x100
132#define QSEED3_FILTERS 5
133#define QSEED3_LUT_REGIONS 4
134#define QSEED3_CIRCULAR_LUTS 9
135#define QSEED3_SEPARABLE_LUTS 10
136#define QSEED3_LUT_SIZE 60
137#define QSEED3_ENABLE 2
138#define QSEED3_DIR_LUT_SIZE (200 * sizeof(u32))
139#define QSEED3_CIR_LUT_SIZE \
140 (QSEED3_LUT_SIZE * QSEED3_CIRCULAR_LUTS * sizeof(u32))
141#define QSEED3_SEP_LUT_SIZE \
142 (QSEED3_LUT_SIZE * QSEED3_SEPARABLE_LUTS * sizeof(u32))
143
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700144/*
Clarence Ipe78efb72016-06-24 18:35:21 -0400145 * Definitions for ViG op modes
146 */
147#define VIG_OP_CSC_DST_DATAFMT BIT(19)
148#define VIG_OP_CSC_SRC_DATAFMT BIT(18)
149#define VIG_OP_CSC_EN BIT(17)
150#define VIG_OP_MEM_PROT_CONT BIT(15)
151#define VIG_OP_MEM_PROT_VAL BIT(14)
152#define VIG_OP_MEM_PROT_SAT BIT(13)
153#define VIG_OP_MEM_PROT_HUE BIT(12)
154#define VIG_OP_HIST BIT(8)
155#define VIG_OP_SKY_COL BIT(7)
156#define VIG_OP_FOIL BIT(6)
157#define VIG_OP_SKIN_COL BIT(5)
158#define VIG_OP_PA_EN BIT(4)
159#define VIG_OP_PA_SAT_ZERO_EXP BIT(2)
160#define VIG_OP_MEM_PROT_BLEND BIT(1)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700161
abeykun62576142016-08-25 17:44:05 -0400162/*
163 * Definitions for CSC 10 op modes
164 */
165#define VIG_CSC_10_SRC_DATAFMT BIT(1)
166#define VIG_CSC_10_EN BIT(0)
167#define CSC_10BIT_OFFSET 4
168
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700169static inline int _sspp_subblk_offset(struct sde_hw_pipe *ctx,
170 int s_id,
171 u32 *idx)
172{
173 int rc = 0;
174 const struct sde_sspp_sub_blks *sblk = ctx->cap->sblk;
175
Clarence Ipe78efb72016-06-24 18:35:21 -0400176 if (!ctx)
177 return -EINVAL;
178
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700179 switch (s_id) {
180 case SDE_SSPP_SRC:
181 *idx = sblk->src_blk.base;
182 break;
Clarence Ipe78efb72016-06-24 18:35:21 -0400183 case SDE_SSPP_SCALER_QSEED2:
184 case SDE_SSPP_SCALER_QSEED3:
185 case SDE_SSPP_SCALER_RGB:
186 *idx = sblk->scaler_blk.base;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700187 break;
188 case SDE_SSPP_CSC:
abeykun62576142016-08-25 17:44:05 -0400189 case SDE_SSPP_CSC_10BIT:
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700190 *idx = sblk->csc_blk.base;
191 break;
Gopikrishnaiah Anandane3842f32015-11-05 12:18:41 -0800192 case SDE_SSPP_HSIC:
Benet Clark37809e62016-10-24 10:14:00 -0700193 *idx = sblk->hsic_blk.base;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700194 break;
195 case SDE_SSPP_PCC:
196 *idx = sblk->pcc_blk.base;
197 break;
Gopikrishnaiah Anandane3842f32015-11-05 12:18:41 -0800198 case SDE_SSPP_MEMCOLOR:
Benet Clark37809e62016-10-24 10:14:00 -0700199 *idx = sblk->memcolor_blk.base;
Gopikrishnaiah Anandane3842f32015-11-05 12:18:41 -0800200 break;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700201 default:
202 rc = -EINVAL;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700203 }
204
205 return rc;
206}
207
208static void _sspp_setup_opmode(struct sde_hw_pipe *ctx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400209 u32 mask, u8 en)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700210{
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700211 u32 idx;
212 u32 opmode;
213
abeykun48f407a2016-08-25 12:06:44 -0400214 if (!test_bit(SDE_SSPP_SCALER_QSEED2, &ctx->cap->features) ||
215 _sspp_subblk_offset(ctx, SDE_SSPP_SCALER_QSEED2, &idx) ||
216 !test_bit(SDE_SSPP_CSC, &ctx->cap->features))
217 return;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700218
abeykun48f407a2016-08-25 12:06:44 -0400219 opmode = SDE_REG_READ(&ctx->hw, SSPP_VIG_OP_MODE + idx);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700220
abeykun48f407a2016-08-25 12:06:44 -0400221 if (en)
222 opmode |= mask;
223 else
224 opmode &= ~mask;
225
226 SDE_REG_WRITE(&ctx->hw, SSPP_VIG_OP_MODE + idx, opmode);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700227}
abeykun62576142016-08-25 17:44:05 -0400228
229static void _sspp_setup_csc10_opmode(struct sde_hw_pipe *ctx,
230 u32 mask, u8 en)
231{
232 u32 idx;
233 u32 opmode;
234
235 if (_sspp_subblk_offset(ctx, SDE_SSPP_CSC_10BIT, &idx))
236 return;
237
238 opmode = SDE_REG_READ(&ctx->hw, SSPP_VIG_CSC_10_OP_MODE + idx);
239 if (en)
240 opmode |= mask;
241 else
242 opmode &= ~mask;
243
244 SDE_REG_WRITE(&ctx->hw, SSPP_VIG_CSC_10_OP_MODE + idx, opmode);
245}
246
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700247/**
248 * Setup source pixel format, flip,
249 */
250static void sde_hw_sspp_setup_format(struct sde_hw_pipe *ctx,
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400251 const struct sde_format *fmt, u32 flags)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700252{
Clarence Ipe78efb72016-06-24 18:35:21 -0400253 struct sde_hw_blk_reg_map *c;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700254 u32 chroma_samp, unpack, src_format;
255 u32 secure = 0;
256 u32 opmode = 0;
257 u32 idx;
258
Clarence Ipcb410d42016-06-26 22:52:33 -0400259 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx) || !fmt)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700260 return;
261
Clarence Ipe78efb72016-06-24 18:35:21 -0400262 c = &ctx->hw;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700263 opmode = SDE_REG_READ(c, SSPP_SRC_OP_MODE + idx);
Clarence Ip5e2a9222016-06-26 22:38:24 -0400264 opmode &= ~(MDSS_MDP_OP_FLIP_LR | MDSS_MDP_OP_FLIP_UD |
265 MDSS_MDP_OP_BWC_EN | MDSS_MDP_OP_PE_OVERRIDE);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700266
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700267 if (flags & SDE_SSPP_SECURE_OVERLAY_SESSION)
268 secure = 0xF;
269
270 if (flags & SDE_SSPP_FLIP_LR)
271 opmode |= MDSS_MDP_OP_FLIP_LR;
272 if (flags & SDE_SSPP_FLIP_UD)
273 opmode |= MDSS_MDP_OP_FLIP_UD;
274
275 chroma_samp = fmt->chroma_sample;
276 if (flags & SDE_SSPP_SOURCE_ROTATED_90) {
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400277 if (chroma_samp == SDE_CHROMA_H2V1)
278 chroma_samp = SDE_CHROMA_H1V2;
279 else if (chroma_samp == SDE_CHROMA_H1V2)
280 chroma_samp = SDE_CHROMA_H2V1;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700281 }
282
283 src_format = (chroma_samp << 23) | (fmt->fetch_planes << 19) |
284 (fmt->bits[C3_ALPHA] << 6) | (fmt->bits[C2_R_Cr] << 4) |
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400285 (fmt->bits[C1_B_Cb] << 2) | (fmt->bits[C0_G_Y] << 0);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700286
287 if (flags & SDE_SSPP_ROT_90)
288 src_format |= BIT(11); /* ROT90 */
289
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400290 if (fmt->alpha_enable && fmt->fetch_planes == SDE_PLANE_INTERLEAVED)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700291 src_format |= BIT(8); /* SRCC3_EN */
292
Clarence Ipcb410d42016-06-26 22:52:33 -0400293 if (flags & SDE_SSPP_SOLID_FILL)
294 src_format |= BIT(22);
295
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700296 unpack = (fmt->element[3] << 24) | (fmt->element[2] << 16) |
297 (fmt->element[1] << 8) | (fmt->element[0] << 0);
298 src_format |= ((fmt->unpack_count - 1) << 12) |
299 (fmt->unpack_tight << 17) |
300 (fmt->unpack_align_msb << 18) |
301 ((fmt->bpp - 1) << 9);
302
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400303 if (fmt->fetch_mode != SDE_FETCH_LINEAR) {
Clarence Ipcb410d42016-06-26 22:52:33 -0400304 if (SDE_FORMAT_IS_UBWC(fmt))
305 opmode |= MDSS_MDP_OP_BWC_EN;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700306 src_format |= (fmt->fetch_mode & 3) << 30; /*FRAME_FORMAT */
307 SDE_REG_WRITE(c, SSPP_FETCH_CONFIG,
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400308 SDE_FETCH_CONFIG_RESET_VALUE |
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700309 ctx->highest_bank_bit << 18);
310 }
311
Clarence Ipe78efb72016-06-24 18:35:21 -0400312 opmode |= MDSS_MDP_OP_PE_OVERRIDE;
313
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700314 /* if this is YUV pixel format, enable CSC */
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400315 if (SDE_FORMAT_IS_YUV(fmt))
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700316 src_format |= BIT(15);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700317
abeykun5ed42e12016-08-24 17:09:26 -0400318 if (SDE_FORMAT_IS_DX(fmt))
319 src_format |= BIT(14);
320
Clarence Ipe78efb72016-06-24 18:35:21 -0400321 /* update scaler opmode, if appropriate */
abeykun62576142016-08-25 17:44:05 -0400322 if (test_bit(SDE_SSPP_CSC, &ctx->cap->features))
323 _sspp_setup_opmode(ctx, VIG_OP_CSC_EN | VIG_OP_CSC_SRC_DATAFMT,
324 SDE_FORMAT_IS_YUV(fmt));
325 else if (test_bit(SDE_SSPP_CSC_10BIT, &ctx->cap->features))
326 _sspp_setup_csc10_opmode(ctx,
327 VIG_CSC_10_EN | VIG_CSC_10_SRC_DATAFMT,
328 SDE_FORMAT_IS_YUV(fmt));
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700329
330 SDE_REG_WRITE(c, SSPP_SRC_FORMAT + idx, src_format);
331 SDE_REG_WRITE(c, SSPP_SRC_UNPACK_PATTERN + idx, unpack);
332 SDE_REG_WRITE(c, SSPP_SRC_OP_MODE + idx, opmode);
333 SDE_REG_WRITE(c, SSPP_SRC_ADDR_SW_STATUS + idx, secure);
334
335 /* clear previous UBWC error */
336 SDE_REG_WRITE(c, SSPP_UBWC_ERROR_STATUS + idx, BIT(31));
337}
338
339static void sde_hw_sspp_setup_pe_config(struct sde_hw_pipe *ctx,
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700340 struct sde_hw_pixel_ext *pe_ext)
341{
Clarence Ipe78efb72016-06-24 18:35:21 -0400342 struct sde_hw_blk_reg_map *c;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700343 u8 color;
344 u32 lr_pe[4], tb_pe[4], tot_req_pixels[4];
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400345 const u32 bytemask = 0xff;
346 const u32 shortmask = 0xffff;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700347 u32 idx;
348
Clarence Ipe78efb72016-06-24 18:35:21 -0400349 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx) || !pe_ext)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700350 return;
351
Clarence Ipe78efb72016-06-24 18:35:21 -0400352 c = &ctx->hw;
353
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700354 /* program SW pixel extension override for all pipes*/
Clarence Ipe78efb72016-06-24 18:35:21 -0400355 for (color = 0; color < SDE_MAX_PLANES; color++) {
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700356 /* color 2 has the same set of registers as color 1 */
357 if (color == 2)
358 continue;
359
360 lr_pe[color] = ((pe_ext->right_ftch[color] & bytemask) << 24)|
361 ((pe_ext->right_rpt[color] & bytemask) << 16)|
362 ((pe_ext->left_ftch[color] & bytemask) << 8)|
363 (pe_ext->left_rpt[color] & bytemask);
364
365 tb_pe[color] = ((pe_ext->btm_ftch[color] & bytemask) << 24)|
366 ((pe_ext->btm_rpt[color] & bytemask) << 16)|
367 ((pe_ext->top_ftch[color] & bytemask) << 8)|
368 (pe_ext->top_rpt[color] & bytemask);
369
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400370 tot_req_pixels[color] = (((pe_ext->roi_h[color] +
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700371 pe_ext->num_ext_pxls_top[color] +
372 pe_ext->num_ext_pxls_btm[color]) & shortmask) << 16) |
373 ((pe_ext->roi_w[color] +
374 pe_ext->num_ext_pxls_left[color] +
375 pe_ext->num_ext_pxls_right[color]) & shortmask);
376 }
377
378 /* color 0 */
379 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C0_LR + idx, lr_pe[0]);
380 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C0_TB + idx, tb_pe[0]);
381 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C0_REQ_PIXELS + idx,
382 tot_req_pixels[0]);
383
384 /* color 1 and color 2 */
385 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C1C2_LR + idx, lr_pe[1]);
386 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C1C2_TB + idx, tb_pe[1]);
387 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C1C2_REQ_PIXELS + idx,
388 tot_req_pixels[1]);
389
390 /* color 3 */
391 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C3_LR + idx, lr_pe[3]);
392 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C3_TB + idx, lr_pe[3]);
393 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C3_REQ_PIXELS + idx,
394 tot_req_pixels[3]);
395}
396
Clarence Ipe78efb72016-06-24 18:35:21 -0400397static void _sde_hw_sspp_setup_scaler(struct sde_hw_pipe *ctx,
abeykun48f407a2016-08-25 12:06:44 -0400398 struct sde_hw_pipe_cfg *sspp,
399 struct sde_hw_pixel_ext *pe,
400 void *scaler_cfg)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700401{
Clarence Ipe78efb72016-06-24 18:35:21 -0400402 struct sde_hw_blk_reg_map *c;
403 int config_h = 0x0;
404 int config_v = 0x0;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700405 u32 idx;
406
abeykun48f407a2016-08-25 12:06:44 -0400407 (void)sspp;
408 (void)scaler_cfg;
Clarence Ipe78efb72016-06-24 18:35:21 -0400409 if (_sspp_subblk_offset(ctx, SDE_SSPP_SCALER_QSEED2, &idx) || !pe)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700410 return;
411
Clarence Ipe78efb72016-06-24 18:35:21 -0400412 c = &ctx->hw;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700413
Clarence Ipe78efb72016-06-24 18:35:21 -0400414 /* enable scaler(s) if valid filter set */
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400415 if (pe->horz_filter[SDE_SSPP_COMP_0] < SDE_SCALE_FILTER_MAX)
Clarence Ipe78efb72016-06-24 18:35:21 -0400416 config_h |= pe->horz_filter[SDE_SSPP_COMP_0] << 8;
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400417 if (pe->horz_filter[SDE_SSPP_COMP_1_2] < SDE_SCALE_FILTER_MAX)
Clarence Ipe78efb72016-06-24 18:35:21 -0400418 config_h |= pe->horz_filter[SDE_SSPP_COMP_1_2] << 12;
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400419 if (pe->horz_filter[SDE_SSPP_COMP_3] < SDE_SCALE_FILTER_MAX)
Clarence Ipe78efb72016-06-24 18:35:21 -0400420 config_h |= pe->horz_filter[SDE_SSPP_COMP_3] << 16;
421
422 if (config_h)
423 config_h |= BIT(0);
424
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400425 if (pe->vert_filter[SDE_SSPP_COMP_0] < SDE_SCALE_FILTER_MAX)
Clarence Ipe78efb72016-06-24 18:35:21 -0400426 config_v |= pe->vert_filter[SDE_SSPP_COMP_0] << 10;
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400427 if (pe->vert_filter[SDE_SSPP_COMP_1_2] < SDE_SCALE_FILTER_MAX)
Clarence Ipe78efb72016-06-24 18:35:21 -0400428 config_v |= pe->vert_filter[SDE_SSPP_COMP_1_2] << 14;
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400429 if (pe->vert_filter[SDE_SSPP_COMP_3] < SDE_SCALE_FILTER_MAX)
Clarence Ipe78efb72016-06-24 18:35:21 -0400430 config_v |= pe->vert_filter[SDE_SSPP_COMP_3] << 18;
431
432 if (config_v)
433 config_v |= BIT(1);
434
435 SDE_REG_WRITE(c, SCALE_CONFIG + idx, config_h | config_v);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700436 SDE_REG_WRITE(c, COMP0_3_INIT_PHASE_X + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400437 pe->init_phase_x[SDE_SSPP_COMP_0]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700438 SDE_REG_WRITE(c, COMP0_3_INIT_PHASE_Y + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400439 pe->init_phase_y[SDE_SSPP_COMP_0]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700440 SDE_REG_WRITE(c, COMP0_3_PHASE_STEP_X + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400441 pe->phase_step_x[SDE_SSPP_COMP_0]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700442 SDE_REG_WRITE(c, COMP0_3_PHASE_STEP_Y + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400443 pe->phase_step_y[SDE_SSPP_COMP_0]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700444
445 SDE_REG_WRITE(c, COMP1_2_INIT_PHASE_X + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400446 pe->init_phase_x[SDE_SSPP_COMP_1_2]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700447 SDE_REG_WRITE(c, COMP1_2_INIT_PHASE_Y + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400448 pe->init_phase_y[SDE_SSPP_COMP_1_2]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700449 SDE_REG_WRITE(c, COMP1_2_PHASE_STEP_X + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400450 pe->phase_step_x[SDE_SSPP_COMP_1_2]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700451 SDE_REG_WRITE(c, COMP1_2_PHASE_STEP_Y + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400452 pe->phase_step_y[SDE_SSPP_COMP_1_2]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700453}
454
abeykun48f407a2016-08-25 12:06:44 -0400455static void _sde_hw_sspp_setup_scaler3_lut(struct sde_hw_pipe *ctx,
456 struct sde_hw_scaler3_cfg *scaler3_cfg)
457{
458 u32 idx;
459 int i, j, filter;
460 int config_lut = 0x0;
461 unsigned long lut_flags;
462 u32 lut_addr, lut_offset, lut_len;
463 u32 *lut[QSEED3_FILTERS] = {NULL, NULL, NULL, NULL, NULL};
464 static const uint32_t offset[QSEED3_FILTERS][QSEED3_LUT_REGIONS][2] = {
465 {{18, 0x000}, {12, 0x120}, {12, 0x1E0}, {8, 0x2A0} },
466 {{6, 0x320}, {3, 0x3E0}, {3, 0x440}, {3, 0x4A0} },
467 {{6, 0x500}, {3, 0x5c0}, {3, 0x620}, {3, 0x680} },
468 {{6, 0x380}, {3, 0x410}, {3, 0x470}, {3, 0x4d0} },
469 {{6, 0x560}, {3, 0x5f0}, {3, 0x650}, {3, 0x6b0} },
470 };
471
472 if (_sspp_subblk_offset(ctx, SDE_SSPP_SCALER_QSEED3, &idx) ||
473 !scaler3_cfg)
474 return;
475
476 lut_flags = (unsigned long) scaler3_cfg->lut_flag;
477 if (test_bit(QSEED3_COEF_LUT_DIR_BIT, &lut_flags) &&
478 (scaler3_cfg->dir_len == QSEED3_DIR_LUT_SIZE)) {
479 lut[0] = scaler3_cfg->dir_lut;
480 config_lut = 1;
481 }
482 if (test_bit(QSEED3_COEF_LUT_Y_CIR_BIT, &lut_flags) &&
483 (scaler3_cfg->y_rgb_cir_lut_idx < QSEED3_CIRCULAR_LUTS) &&
484 (scaler3_cfg->cir_len == QSEED3_CIR_LUT_SIZE)) {
485 lut[1] = scaler3_cfg->cir_lut +
486 scaler3_cfg->y_rgb_cir_lut_idx * QSEED3_LUT_SIZE;
487 config_lut = 1;
488 }
489 if (test_bit(QSEED3_COEF_LUT_UV_CIR_BIT, &lut_flags) &&
490 (scaler3_cfg->uv_cir_lut_idx < QSEED3_CIRCULAR_LUTS) &&
491 (scaler3_cfg->cir_len == QSEED3_CIR_LUT_SIZE)) {
492 lut[2] = scaler3_cfg->cir_lut +
493 scaler3_cfg->uv_cir_lut_idx * QSEED3_LUT_SIZE;
494 config_lut = 1;
495 }
496 if (test_bit(QSEED3_COEF_LUT_Y_SEP_BIT, &lut_flags) &&
497 (scaler3_cfg->y_rgb_sep_lut_idx < QSEED3_SEPARABLE_LUTS) &&
498 (scaler3_cfg->sep_len == QSEED3_SEP_LUT_SIZE)) {
499 lut[3] = scaler3_cfg->sep_lut +
500 scaler3_cfg->y_rgb_sep_lut_idx * QSEED3_LUT_SIZE;
501 config_lut = 1;
502 }
503 if (test_bit(QSEED3_COEF_LUT_UV_SEP_BIT, &lut_flags) &&
504 (scaler3_cfg->uv_sep_lut_idx < QSEED3_SEPARABLE_LUTS) &&
505 (scaler3_cfg->sep_len == QSEED3_SEP_LUT_SIZE)) {
506 lut[4] = scaler3_cfg->sep_lut +
507 scaler3_cfg->uv_sep_lut_idx * QSEED3_LUT_SIZE;
508 config_lut = 1;
509 }
510
511 if (config_lut) {
512 for (filter = 0; filter < QSEED3_FILTERS; filter++) {
513 if (!lut[filter])
514 continue;
515 lut_offset = 0;
516 for (i = 0; i < QSEED3_LUT_REGIONS; i++) {
517 lut_addr = QSEED3_COEF_LUT + idx
518 + offset[filter][i][1];
519 lut_len = offset[filter][i][0] << 2;
520 for (j = 0; j < lut_len; j++) {
521 SDE_REG_WRITE(&ctx->hw,
522 lut_addr,
523 (lut[filter])[lut_offset++]);
524 lut_addr += 4;
525 }
526 }
527 }
528 }
529
530 if (test_bit(QSEED3_COEF_LUT_SWAP_BIT, &lut_flags))
531 SDE_REG_WRITE(&ctx->hw, QSEED3_COEF_LUT_CTRL + idx, BIT(0));
532
533}
534
535static void _sde_hw_sspp_setup_scaler3_de(struct sde_hw_pipe *ctx,
536 struct sde_hw_scaler3_de_cfg *de_cfg)
537{
538 u32 idx;
539 u32 sharp_lvl, sharp_ctl, shape_ctl, de_thr;
540 u32 adjust_a, adjust_b, adjust_c;
541 struct sde_hw_blk_reg_map *hw;
542
543 if (_sspp_subblk_offset(ctx, SDE_SSPP_SCALER_QSEED3, &idx) || !de_cfg)
544 return;
545
546 if (!de_cfg->enable)
547 return;
548
549 hw = &ctx->hw;
550 sharp_lvl = (de_cfg->sharpen_level1 & 0x1FF) |
551 ((de_cfg->sharpen_level2 & 0x1FF) << 16);
552
553 sharp_ctl = ((de_cfg->limit & 0xF) << 9) |
554 ((de_cfg->prec_shift & 0x7) << 13) |
555 ((de_cfg->clip & 0x7) << 16);
556
557 shape_ctl = (de_cfg->thr_quiet & 0xFF) |
558 ((de_cfg->thr_dieout & 0x3FF) << 16);
559
560 de_thr = (de_cfg->thr_low & 0x3FF) |
561 ((de_cfg->thr_high & 0x3FF) << 16);
562
563 adjust_a = (de_cfg->adjust_a[0] & 0x3FF) |
564 ((de_cfg->adjust_a[1] & 0x3FF) << 10) |
565 ((de_cfg->adjust_a[2] & 0x3FF) << 20);
566
567 adjust_b = (de_cfg->adjust_b[0] & 0x3FF) |
568 ((de_cfg->adjust_b[1] & 0x3FF) << 10) |
569 ((de_cfg->adjust_b[2] & 0x3FF) << 20);
570
571 adjust_c = (de_cfg->adjust_c[0] & 0x3FF) |
572 ((de_cfg->adjust_c[1] & 0x3FF) << 10) |
573 ((de_cfg->adjust_c[2] & 0x3FF) << 20);
574
575 SDE_REG_WRITE(hw, QSEED3_DE_SHARPEN + idx, sharp_lvl);
576 SDE_REG_WRITE(hw, QSEED3_DE_SHARPEN_CTL + idx, sharp_ctl);
577 SDE_REG_WRITE(hw, QSEED3_DE_SHAPE_CTL + idx, shape_ctl);
578 SDE_REG_WRITE(hw, QSEED3_DE_THRESHOLD + idx, de_thr);
579 SDE_REG_WRITE(hw, QSEED3_DE_ADJUST_DATA_0 + idx, adjust_a);
580 SDE_REG_WRITE(hw, QSEED3_DE_ADJUST_DATA_1 + idx, adjust_b);
581 SDE_REG_WRITE(hw, QSEED3_DE_ADJUST_DATA_2 + idx, adjust_c);
582
583}
584
585static void _sde_hw_sspp_setup_scaler3(struct sde_hw_pipe *ctx,
586 struct sde_hw_pipe_cfg *sspp,
587 struct sde_hw_pixel_ext *pe,
588 void *scaler_cfg)
589{
590 u32 idx;
591 u32 op_mode = 0;
592 u32 phase_init, preload, src_y_rgb, src_uv, dst;
593 struct sde_hw_scaler3_cfg *scaler3_cfg = scaler_cfg;
594
595 (void)pe;
596 if (_sspp_subblk_offset(ctx, SDE_SSPP_SCALER_QSEED3, &idx) || !sspp
597 || !scaler3_cfg || !ctx || !ctx->cap || !ctx->cap->sblk)
598 return;
599
Dhaval Patela64725e2017-02-09 16:06:03 -0800600 if (!scaler3_cfg->enable)
601 goto end;
abeykun48f407a2016-08-25 12:06:44 -0400602
603 op_mode |= BIT(0);
604 op_mode |= (scaler3_cfg->y_rgb_filter_cfg & 0x3) << 16;
605
606 if (SDE_FORMAT_IS_YUV(sspp->layout.format)) {
607 op_mode |= BIT(12);
608 op_mode |= (scaler3_cfg->uv_filter_cfg & 0x3) << 24;
609 }
610
abeykun48f407a2016-08-25 12:06:44 -0400611 op_mode |= (scaler3_cfg->blend_cfg & 1) << 31;
612 op_mode |= (scaler3_cfg->dir_en) ? BIT(4) : 0;
613
614 preload =
615 ((scaler3_cfg->preload_x[0] & 0x7F) << 0) |
616 ((scaler3_cfg->preload_y[0] & 0x7F) << 8) |
617 ((scaler3_cfg->preload_x[1] & 0x7F) << 16) |
618 ((scaler3_cfg->preload_y[1] & 0x7F) << 24);
619
620 src_y_rgb = (scaler3_cfg->src_width[0] & 0x1FFFF) |
621 ((scaler3_cfg->src_height[0] & 0x1FFFF) << 16);
622
623 src_uv = (scaler3_cfg->src_width[1] & 0x1FFFF) |
624 ((scaler3_cfg->src_height[1] & 0x1FFFF) << 16);
625
626 dst = (scaler3_cfg->dst_width & 0x1FFFF) |
627 ((scaler3_cfg->dst_height & 0x1FFFF) << 16);
628
629 if (scaler3_cfg->de.enable) {
630 _sde_hw_sspp_setup_scaler3_de(ctx, &scaler3_cfg->de);
631 op_mode |= BIT(8);
632 }
633
634 if (scaler3_cfg->lut_flag)
635 _sde_hw_sspp_setup_scaler3_lut(ctx, scaler3_cfg);
636
637 if (ctx->cap->sblk->scaler_blk.version == 0x1002) {
abeykun48f407a2016-08-25 12:06:44 -0400638 phase_init =
639 ((scaler3_cfg->init_phase_x[0] & 0x3F) << 0) |
640 ((scaler3_cfg->init_phase_y[0] & 0x3F) << 8) |
641 ((scaler3_cfg->init_phase_x[1] & 0x3F) << 16) |
642 ((scaler3_cfg->init_phase_y[1] & 0x3F) << 24);
643 SDE_REG_WRITE(&ctx->hw, QSEED3_PHASE_INIT + idx, phase_init);
644 } else {
abeykun48f407a2016-08-25 12:06:44 -0400645 SDE_REG_WRITE(&ctx->hw, QSEED3_PHASE_INIT_Y_H + idx,
646 scaler3_cfg->init_phase_x[0] & 0x1FFFFF);
647 SDE_REG_WRITE(&ctx->hw, QSEED3_PHASE_INIT_Y_V + idx,
648 scaler3_cfg->init_phase_y[0] & 0x1FFFFF);
649 SDE_REG_WRITE(&ctx->hw, QSEED3_PHASE_INIT_UV_H + idx,
650 scaler3_cfg->init_phase_x[1] & 0x1FFFFF);
651 SDE_REG_WRITE(&ctx->hw, QSEED3_PHASE_INIT_UV_V + idx,
652 scaler3_cfg->init_phase_y[1] & 0x1FFFFF);
653 }
654
655 SDE_REG_WRITE(&ctx->hw, QSEED3_PHASE_STEP_Y_H + idx,
656 scaler3_cfg->phase_step_x[0] & 0xFFFFFF);
657
658 SDE_REG_WRITE(&ctx->hw, QSEED3_PHASE_STEP_Y_V + idx,
659 scaler3_cfg->phase_step_y[0] & 0xFFFFFF);
660
661 SDE_REG_WRITE(&ctx->hw, QSEED3_PHASE_STEP_UV_H + idx,
662 scaler3_cfg->phase_step_x[1] & 0xFFFFFF);
663
664 SDE_REG_WRITE(&ctx->hw, QSEED3_PHASE_STEP_UV_V + idx,
665 scaler3_cfg->phase_step_y[1] & 0xFFFFFF);
666
667 SDE_REG_WRITE(&ctx->hw, QSEED3_PRELOAD + idx, preload);
668
669 SDE_REG_WRITE(&ctx->hw, QSEED3_SRC_SIZE_Y_RGB_A + idx, src_y_rgb);
670
671 SDE_REG_WRITE(&ctx->hw, QSEED3_SRC_SIZE_UV + idx, src_uv);
672
673 SDE_REG_WRITE(&ctx->hw, QSEED3_DST_SIZE + idx, dst);
674
Dhaval Patela64725e2017-02-09 16:06:03 -0800675end:
676 if (!SDE_FORMAT_IS_DX(sspp->layout.format))
677 op_mode |= BIT(14);
678
679 if (sspp->layout.format->alpha_enable) {
680 op_mode |= BIT(10);
681 if (ctx->cap->sblk->scaler_blk.version == 0x1002)
682 op_mode |= (scaler3_cfg->alpha_filter_cfg & 0x1) << 30;
683 else
684 op_mode |= (scaler3_cfg->alpha_filter_cfg & 0x3) << 29;
685 }
abeykun48f407a2016-08-25 12:06:44 -0400686 SDE_REG_WRITE(&ctx->hw, QSEED3_OP_MODE + idx, op_mode);
687}
688
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700689/**
690 * sde_hw_sspp_setup_rects()
691 */
692static void sde_hw_sspp_setup_rects(struct sde_hw_pipe *ctx,
693 struct sde_hw_pipe_cfg *cfg,
abeykun48f407a2016-08-25 12:06:44 -0400694 struct sde_hw_pixel_ext *pe_ext,
695 void *scale_cfg)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700696{
Clarence Ipe78efb72016-06-24 18:35:21 -0400697 struct sde_hw_blk_reg_map *c;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700698 u32 src_size, src_xy, dst_size, dst_xy, ystride0, ystride1;
699 u32 decimation = 0;
700 u32 idx;
701
Clarence Ipe78efb72016-06-24 18:35:21 -0400702 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx) || !cfg)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700703 return;
704
Clarence Ipe78efb72016-06-24 18:35:21 -0400705 c = &ctx->hw;
706
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700707 /* program pixel extension override */
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400708 if (pe_ext)
Clarence Ipe78efb72016-06-24 18:35:21 -0400709 sde_hw_sspp_setup_pe_config(ctx, pe_ext);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700710
711 /* src and dest rect programming */
Clarence Ipcb410d42016-06-26 22:52:33 -0400712 src_xy = (cfg->src_rect.y << 16) | (cfg->src_rect.x);
713 src_size = (cfg->src_rect.h << 16) | (cfg->src_rect.w);
714 dst_xy = (cfg->dst_rect.y << 16) | (cfg->dst_rect.x);
715 dst_size = (cfg->dst_rect.h << 16) | (cfg->dst_rect.w);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700716
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400717 ystride0 = (cfg->layout.plane_pitch[0]) |
718 (cfg->layout.plane_pitch[1] << 16);
719 ystride1 = (cfg->layout.plane_pitch[2]) |
720 (cfg->layout.plane_pitch[3] << 16);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700721
Clarence Ipe78efb72016-06-24 18:35:21 -0400722 /* program scaler, phase registers, if pipes supporting scaling */
723 if (ctx->cap->features & SDE_SSPP_SCALER) {
724 /* program decimation */
725 decimation = ((1 << cfg->horz_decimation) - 1) << 8;
726 decimation |= ((1 << cfg->vert_decimation) - 1);
abeykun48f407a2016-08-25 12:06:44 -0400727 ctx->ops.setup_scaler(ctx, cfg, pe_ext, scale_cfg);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700728 }
729
Clarence Ipcb410d42016-06-26 22:52:33 -0400730 /* rectangle register programming */
731 SDE_REG_WRITE(c, SSPP_SRC_SIZE + idx, src_size);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700732 SDE_REG_WRITE(c, SSPP_SRC_XY + idx, src_xy);
733 SDE_REG_WRITE(c, SSPP_OUT_SIZE + idx, dst_size);
734 SDE_REG_WRITE(c, SSPP_OUT_XY + idx, dst_xy);
735
736 SDE_REG_WRITE(c, SSPP_SRC_YSTRIDE0 + idx, ystride0);
737 SDE_REG_WRITE(c, SSPP_SRC_YSTRIDE1 + idx, ystride1);
738 SDE_REG_WRITE(c, SSPP_DECIMATION_CONFIG + idx, decimation);
739}
740
Veera Sundaram Sankaran02dd6ac2016-12-22 15:08:29 -0800741/**
742 * _sde_hw_sspp_setup_excl_rect() - set exclusion rect configs
743 * @ctx: Pointer to pipe context
744 * @excl_rect: Exclusion rect configs
745 */
746static void _sde_hw_sspp_setup_excl_rect(struct sde_hw_pipe *ctx,
747 struct sde_rect *excl_rect)
748{
749 struct sde_hw_blk_reg_map *c;
750 u32 size, xy;
751 u32 idx;
752
753 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx) || !excl_rect)
754 return;
755
756 c = &ctx->hw;
757
758 xy = (excl_rect->y << 16) | (excl_rect->x);
759 size = (excl_rect->h << 16) | (excl_rect->w);
760
761 if (!size) {
762 SDE_REG_WRITE(c, SSPP_EXCL_REC_CTL + idx, 0);
763 } else {
764 SDE_REG_WRITE(c, SSPP_EXCL_REC_CTL + idx, BIT(0));
765 SDE_REG_WRITE(c, SSPP_EXCL_REC_SIZE + idx, size);
766 SDE_REG_WRITE(c, SSPP_EXCL_REC_XY + idx, xy);
767 }
768}
769
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700770static void sde_hw_sspp_setup_sourceaddress(struct sde_hw_pipe *ctx,
771 struct sde_hw_pipe_cfg *cfg)
772{
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700773 int i;
774 u32 idx;
775
776 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
777 return;
778
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400779 for (i = 0; i < ARRAY_SIZE(cfg->layout.plane_addr); i++)
780 SDE_REG_WRITE(&ctx->hw, SSPP_SRC0_ADDR + idx + i * 0x4,
781 cfg->layout.plane_addr[i]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700782}
783
Clarence Ipe78efb72016-06-24 18:35:21 -0400784static void sde_hw_sspp_setup_csc(struct sde_hw_pipe *ctx,
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700785 struct sde_csc_cfg *data)
786{
Clarence Ipe78efb72016-06-24 18:35:21 -0400787 u32 idx;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700788
Clarence Ipe78efb72016-06-24 18:35:21 -0400789 if (_sspp_subblk_offset(ctx, SDE_SSPP_CSC, &idx) || !data)
790 return;
791
abeykun62576142016-08-25 17:44:05 -0400792 if (test_bit(SDE_SSPP_CSC_10BIT, &ctx->cap->features))
793 idx += CSC_10BIT_OFFSET;
794
Clarence Ipe78efb72016-06-24 18:35:21 -0400795 sde_hw_csc_setup(&ctx->hw, idx, data);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700796}
797
798static void sde_hw_sspp_setup_sharpening(struct sde_hw_pipe *ctx,
799 struct sde_hw_sharp_cfg *cfg)
800{
Clarence Ipe78efb72016-06-24 18:35:21 -0400801 struct sde_hw_blk_reg_map *c;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700802 u32 idx;
803
Clarence Ip4c1d9772016-06-26 09:35:38 -0400804 if (_sspp_subblk_offset(ctx, SDE_SSPP_SCALER_QSEED2, &idx) || !cfg ||
805 !test_bit(SDE_SSPP_SCALER_QSEED2, &ctx->cap->features))
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700806 return;
807
Clarence Ipe78efb72016-06-24 18:35:21 -0400808 c = &ctx->hw;
809
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700810 SDE_REG_WRITE(c, VIG_0_QSEED2_SHARP + idx, cfg->strength);
811 SDE_REG_WRITE(c, VIG_0_QSEED2_SHARP + idx + 0x4, cfg->edge_thr);
812 SDE_REG_WRITE(c, VIG_0_QSEED2_SHARP + idx + 0x8, cfg->smooth_thr);
813 SDE_REG_WRITE(c, VIG_0_QSEED2_SHARP + idx + 0xC, cfg->noise_thr);
814}
815
Clarence Ipcb410d42016-06-26 22:52:33 -0400816static void sde_hw_sspp_setup_solidfill(struct sde_hw_pipe *ctx, u32 color)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700817{
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700818 u32 idx;
819
820 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
821 return;
822
Clarence Ipcb410d42016-06-26 22:52:33 -0400823 SDE_REG_WRITE(&ctx->hw, SSPP_SRC_CONSTANT_COLOR + idx, color);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700824}
825
Alan Kwong1a00e4d2016-07-18 09:42:30 -0400826static void sde_hw_sspp_setup_danger_safe_lut(struct sde_hw_pipe *ctx,
827 struct sde_hw_pipe_qos_cfg *cfg)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700828{
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700829 u32 idx;
830
831 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
832 return;
833
Alan Kwong1a00e4d2016-07-18 09:42:30 -0400834 SDE_REG_WRITE(&ctx->hw, SSPP_DANGER_LUT + idx, cfg->danger_lut);
835 SDE_REG_WRITE(&ctx->hw, SSPP_SAFE_LUT + idx, cfg->safe_lut);
836}
837
838static void sde_hw_sspp_setup_creq_lut(struct sde_hw_pipe *ctx,
839 struct sde_hw_pipe_qos_cfg *cfg)
840{
841 u32 idx;
842
843 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
844 return;
845
846 SDE_REG_WRITE(&ctx->hw, SSPP_CREQ_LUT + idx, cfg->creq_lut);
847}
848
849static void sde_hw_sspp_setup_qos_ctrl(struct sde_hw_pipe *ctx,
850 struct sde_hw_pipe_qos_cfg *cfg)
851{
852 u32 idx;
853 u32 qos_ctrl = 0;
854
855 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
856 return;
857
858 if (cfg->vblank_en) {
859 qos_ctrl |= ((cfg->creq_vblank &
860 SSPP_QOS_CTRL_CREQ_VBLANK_MASK) <<
861 SSPP_QOS_CTRL_CREQ_VBLANK_OFF);
862 qos_ctrl |= ((cfg->danger_vblank &
863 SSPP_QOS_CTRL_DANGER_VBLANK_MASK) <<
864 SSPP_QOS_CTRL_DANGER_VBLANK_OFF);
865 qos_ctrl |= SSPP_QOS_CTRL_VBLANK_EN;
866 }
867
868 if (cfg->danger_safe_en)
869 qos_ctrl |= SSPP_QOS_CTRL_DANGER_SAFE_EN;
870
871 SDE_REG_WRITE(&ctx->hw, SSPP_QOS_CTRL + idx, qos_ctrl);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700872}
873
Benet Clarkeb1b4462016-06-27 14:43:06 -0700874static void _setup_layer_ops(struct sde_hw_pipe *c,
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700875 unsigned long features)
876{
877 if (test_bit(SDE_SSPP_SRC, &features)) {
Benet Clarkeb1b4462016-06-27 14:43:06 -0700878 c->ops.setup_format = sde_hw_sspp_setup_format;
879 c->ops.setup_rects = sde_hw_sspp_setup_rects;
880 c->ops.setup_sourceaddress = sde_hw_sspp_setup_sourceaddress;
881 c->ops.setup_solidfill = sde_hw_sspp_setup_solidfill;
Alan Kwong1a00e4d2016-07-18 09:42:30 -0400882 }
Veera Sundaram Sankaran02dd6ac2016-12-22 15:08:29 -0800883
884 if (test_bit(SDE_SSPP_EXCL_RECT, &features))
885 c->ops.setup_excl_rect = _sde_hw_sspp_setup_excl_rect;
886
Alan Kwong1a00e4d2016-07-18 09:42:30 -0400887 if (test_bit(SDE_SSPP_QOS, &features)) {
Benet Clarkeb1b4462016-06-27 14:43:06 -0700888 c->ops.setup_danger_safe_lut =
889 sde_hw_sspp_setup_danger_safe_lut;
890 c->ops.setup_creq_lut = sde_hw_sspp_setup_creq_lut;
891 c->ops.setup_qos_ctrl = sde_hw_sspp_setup_qos_ctrl;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700892 }
Benet Clarkeb1b4462016-06-27 14:43:06 -0700893
abeykun62576142016-08-25 17:44:05 -0400894 if (test_bit(SDE_SSPP_CSC, &features) ||
895 test_bit(SDE_SSPP_CSC_10BIT, &features))
Benet Clarkeb1b4462016-06-27 14:43:06 -0700896 c->ops.setup_csc = sde_hw_sspp_setup_csc;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700897
Gopikrishnaiah Anandane3842f32015-11-05 12:18:41 -0800898 if (test_bit(SDE_SSPP_SCALER_QSEED2, &features))
Benet Clarkeb1b4462016-06-27 14:43:06 -0700899 c->ops.setup_sharpening = sde_hw_sspp_setup_sharpening;
abeykun48f407a2016-08-25 12:06:44 -0400900
901 if (test_bit(SDE_SSPP_SCALER_QSEED3, &features))
Benet Clarkeb1b4462016-06-27 14:43:06 -0700902 c->ops.setup_scaler = _sde_hw_sspp_setup_scaler3;
abeykun48f407a2016-08-25 12:06:44 -0400903 else
Benet Clarkeb1b4462016-06-27 14:43:06 -0700904 c->ops.setup_scaler = _sde_hw_sspp_setup_scaler;
905
906 if (test_bit(SDE_SSPP_HSIC, &features)) {
907 /* TODO: add version based assignment here as inline or macro */
908 if (c->cap->sblk->hsic_blk.version ==
909 (SDE_COLOR_PROCESS_VER(0x1, 0x7))) {
910 c->ops.setup_pa_hue = sde_setup_pipe_pa_hue_v1_7;
911 c->ops.setup_pa_sat = sde_setup_pipe_pa_sat_v1_7;
912 c->ops.setup_pa_val = sde_setup_pipe_pa_val_v1_7;
913 c->ops.setup_pa_cont = sde_setup_pipe_pa_cont_v1_7;
914 }
915 }
Benet Clarkd009b1d2016-06-27 14:45:59 -0700916
917 if (test_bit(SDE_SSPP_MEMCOLOR, &features)) {
918 if (c->cap->sblk->memcolor_blk.version ==
919 (SDE_COLOR_PROCESS_VER(0x1, 0x7)))
920 c->ops.setup_pa_memcolor =
921 sde_setup_pipe_pa_memcol_v1_7;
922 }
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700923}
924
925static struct sde_sspp_cfg *_sspp_offset(enum sde_sspp sspp,
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700926 void __iomem *addr,
Clarence Ipe78efb72016-06-24 18:35:21 -0400927 struct sde_mdss_cfg *catalog,
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700928 struct sde_hw_blk_reg_map *b)
929{
930 int i;
931
Clarence Ipe78efb72016-06-24 18:35:21 -0400932 if ((sspp < SSPP_MAX) && catalog && addr && b) {
933 for (i = 0; i < catalog->sspp_count; i++) {
934 if (sspp == catalog->sspp[i].id) {
935 b->base_off = addr;
936 b->blk_off = catalog->sspp[i].base;
937 b->hwversion = catalog->hwversion;
Clarence Ip4ce59322016-06-26 22:27:51 -0400938 b->log_mask = SDE_DBG_MASK_SSPP;
Clarence Ipe78efb72016-06-24 18:35:21 -0400939 return &catalog->sspp[i];
940 }
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700941 }
942 }
943
944 return ERR_PTR(-ENOMEM);
945}
946
947struct sde_hw_pipe *sde_hw_sspp_init(enum sde_sspp idx,
948 void __iomem *addr,
Clarence Ipe78efb72016-06-24 18:35:21 -0400949 struct sde_mdss_cfg *catalog)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700950{
Clarence Ipe78efb72016-06-24 18:35:21 -0400951 struct sde_hw_pipe *ctx;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700952 struct sde_sspp_cfg *cfg;
953
Clarence Ipe78efb72016-06-24 18:35:21 -0400954 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
955 if (!ctx)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700956 return ERR_PTR(-ENOMEM);
957
Clarence Ipe78efb72016-06-24 18:35:21 -0400958 cfg = _sspp_offset(idx, addr, catalog, &ctx->hw);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700959 if (IS_ERR_OR_NULL(cfg)) {
Clarence Ipe78efb72016-06-24 18:35:21 -0400960 kfree(ctx);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700961 return ERR_PTR(-EINVAL);
962 }
963
964 /* Assign ops */
Clarence Ipe78efb72016-06-24 18:35:21 -0400965 ctx->idx = idx;
966 ctx->cap = cfg;
Benet Clarkeb1b4462016-06-27 14:43:06 -0700967 _setup_layer_ops(ctx, ctx->cap->features);
Clarence Ipe78efb72016-06-24 18:35:21 -0400968 ctx->highest_bank_bit = catalog->mdp[0].highest_bank_bit;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700969
Clarence Ipe78efb72016-06-24 18:35:21 -0400970 return ctx;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700971}
972
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400973void sde_hw_sspp_destroy(struct sde_hw_pipe *ctx)
974{
975 kfree(ctx);
976}
977