blob: 929c59a85bbf416f90e3f2d5fe8a34806b2d2436 [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
50#define SSPP_FETCH_CONFIG 0x048
51#define SSPP_DANGER_LUT 0x60
52#define SSPP_SAFE_LUT 0x64
53#define SSPP_CREQ_LUT 0x68
Alan Kwong1a00e4d2016-07-18 09:42:30 -040054#define SSPP_QOS_CTRL 0x6C
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070055#define SSPP_DECIMATION_CONFIG 0xB4
56#define SSPP_SRC_ADDR_SW_STATUS 0x70
57#define SSPP_SW_PIX_EXT_C0_LR 0x100
58#define SSPP_SW_PIX_EXT_C0_TB 0x104
59#define SSPP_SW_PIX_EXT_C0_REQ_PIXELS 0x108
60#define SSPP_SW_PIX_EXT_C1C2_LR 0x110
61#define SSPP_SW_PIX_EXT_C1C2_TB 0x114
62#define SSPP_SW_PIX_EXT_C1C2_REQ_PIXELS 0x118
63#define SSPP_SW_PIX_EXT_C3_LR 0x120
64#define SSPP_SW_PIX_EXT_C3_TB 0x124
65#define SSPP_SW_PIX_EXT_C3_REQ_PIXELS 0x128
66#define SSPP_UBWC_ERROR_STATUS 0x138
Clarence Ipe78efb72016-06-24 18:35:21 -040067#define SSPP_VIG_OP_MODE 0x0
abeykun62576142016-08-25 17:44:05 -040068#define SSPP_VIG_CSC_10_OP_MODE 0x0
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070069
Alan Kwong1a00e4d2016-07-18 09:42:30 -040070/* SSPP_QOS_CTRL */
71#define SSPP_QOS_CTRL_VBLANK_EN BIT(16)
72#define SSPP_QOS_CTRL_DANGER_SAFE_EN BIT(0)
73#define SSPP_QOS_CTRL_DANGER_VBLANK_MASK 0x3
74#define SSPP_QOS_CTRL_DANGER_VBLANK_OFF 4
75#define SSPP_QOS_CTRL_CREQ_VBLANK_MASK 0x3
76#define SSPP_QOS_CTRL_CREQ_VBLANK_OFF 20
77
Clarence Ipe78efb72016-06-24 18:35:21 -040078/* SDE_SSPP_SCALER_QSEED2 */
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070079#define SCALE_CONFIG 0x04
80#define COMP0_3_PHASE_STEP_X 0x10
81#define COMP0_3_PHASE_STEP_Y 0x14
82#define COMP1_2_PHASE_STEP_X 0x18
83#define COMP1_2_PHASE_STEP_Y 0x1c
84#define COMP0_3_INIT_PHASE_X 0x20
85#define COMP0_3_INIT_PHASE_Y 0x24
86#define COMP1_2_INIT_PHASE_X 0x28
87#define COMP1_2_INIT_PHASE_Y 0x2C
88#define VIG_0_QSEED2_SHARP 0x30
89
abeykun48f407a2016-08-25 12:06:44 -040090/* SDE_SSPP_SCALER_QSEED3 */
91#define QSEED3_HW_VERSION 0x00
92#define QSEED3_OP_MODE 0x04
93#define QSEED3_RGB2Y_COEFF 0x08
94#define QSEED3_PHASE_INIT 0x0C
95#define QSEED3_PHASE_STEP_Y_H 0x10
96#define QSEED3_PHASE_STEP_Y_V 0x14
97#define QSEED3_PHASE_STEP_UV_H 0x18
98#define QSEED3_PHASE_STEP_UV_V 0x1C
99#define QSEED3_PRELOAD 0x20
100#define QSEED3_DE_SHARPEN 0x24
101#define QSEED3_DE_SHARPEN_CTL 0x28
102#define QSEED3_DE_SHAPE_CTL 0x2C
103#define QSEED3_DE_THRESHOLD 0x30
104#define QSEED3_DE_ADJUST_DATA_0 0x34
105#define QSEED3_DE_ADJUST_DATA_1 0x38
106#define QSEED3_DE_ADJUST_DATA_2 0x3C
107#define QSEED3_SRC_SIZE_Y_RGB_A 0x40
108#define QSEED3_SRC_SIZE_UV 0x44
109#define QSEED3_DST_SIZE 0x48
110#define QSEED3_COEF_LUT_CTRL 0x4C
111#define QSEED3_COEF_LUT_SWAP_BIT 0
112#define QSEED3_COEF_LUT_DIR_BIT 1
113#define QSEED3_COEF_LUT_Y_CIR_BIT 2
114#define QSEED3_COEF_LUT_UV_CIR_BIT 3
115#define QSEED3_COEF_LUT_Y_SEP_BIT 4
116#define QSEED3_COEF_LUT_UV_SEP_BIT 5
117#define QSEED3_BUFFER_CTRL 0x50
118#define QSEED3_CLK_CTRL0 0x54
119#define QSEED3_CLK_CTRL1 0x58
120#define QSEED3_CLK_STATUS 0x5C
121#define QSEED3_MISR_CTRL 0x70
122#define QSEED3_MISR_SIGNATURE_0 0x74
123#define QSEED3_MISR_SIGNATURE_1 0x78
124#define QSEED3_PHASE_INIT_Y_H 0x90
125#define QSEED3_PHASE_INIT_Y_V 0x94
126#define QSEED3_PHASE_INIT_UV_H 0x98
127#define QSEED3_PHASE_INIT_UV_V 0x9C
128#define QSEED3_COEF_LUT 0x100
129#define QSEED3_FILTERS 5
130#define QSEED3_LUT_REGIONS 4
131#define QSEED3_CIRCULAR_LUTS 9
132#define QSEED3_SEPARABLE_LUTS 10
133#define QSEED3_LUT_SIZE 60
134#define QSEED3_ENABLE 2
135#define QSEED3_DIR_LUT_SIZE (200 * sizeof(u32))
136#define QSEED3_CIR_LUT_SIZE \
137 (QSEED3_LUT_SIZE * QSEED3_CIRCULAR_LUTS * sizeof(u32))
138#define QSEED3_SEP_LUT_SIZE \
139 (QSEED3_LUT_SIZE * QSEED3_SEPARABLE_LUTS * sizeof(u32))
140
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700141/*
Clarence Ipe78efb72016-06-24 18:35:21 -0400142 * Definitions for ViG op modes
143 */
144#define VIG_OP_CSC_DST_DATAFMT BIT(19)
145#define VIG_OP_CSC_SRC_DATAFMT BIT(18)
146#define VIG_OP_CSC_EN BIT(17)
147#define VIG_OP_MEM_PROT_CONT BIT(15)
148#define VIG_OP_MEM_PROT_VAL BIT(14)
149#define VIG_OP_MEM_PROT_SAT BIT(13)
150#define VIG_OP_MEM_PROT_HUE BIT(12)
151#define VIG_OP_HIST BIT(8)
152#define VIG_OP_SKY_COL BIT(7)
153#define VIG_OP_FOIL BIT(6)
154#define VIG_OP_SKIN_COL BIT(5)
155#define VIG_OP_PA_EN BIT(4)
156#define VIG_OP_PA_SAT_ZERO_EXP BIT(2)
157#define VIG_OP_MEM_PROT_BLEND BIT(1)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700158
abeykun62576142016-08-25 17:44:05 -0400159/*
160 * Definitions for CSC 10 op modes
161 */
162#define VIG_CSC_10_SRC_DATAFMT BIT(1)
163#define VIG_CSC_10_EN BIT(0)
164#define CSC_10BIT_OFFSET 4
165
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700166static inline int _sspp_subblk_offset(struct sde_hw_pipe *ctx,
167 int s_id,
168 u32 *idx)
169{
170 int rc = 0;
171 const struct sde_sspp_sub_blks *sblk = ctx->cap->sblk;
172
Clarence Ipe78efb72016-06-24 18:35:21 -0400173 if (!ctx)
174 return -EINVAL;
175
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700176 switch (s_id) {
177 case SDE_SSPP_SRC:
178 *idx = sblk->src_blk.base;
179 break;
Clarence Ipe78efb72016-06-24 18:35:21 -0400180 case SDE_SSPP_SCALER_QSEED2:
181 case SDE_SSPP_SCALER_QSEED3:
182 case SDE_SSPP_SCALER_RGB:
183 *idx = sblk->scaler_blk.base;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700184 break;
185 case SDE_SSPP_CSC:
abeykun62576142016-08-25 17:44:05 -0400186 case SDE_SSPP_CSC_10BIT:
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700187 *idx = sblk->csc_blk.base;
188 break;
Gopikrishnaiah Anandane3842f32015-11-05 12:18:41 -0800189 case SDE_SSPP_HSIC:
Benet Clark37809e62016-10-24 10:14:00 -0700190 *idx = sblk->hsic_blk.base;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700191 break;
192 case SDE_SSPP_PCC:
193 *idx = sblk->pcc_blk.base;
194 break;
Gopikrishnaiah Anandane3842f32015-11-05 12:18:41 -0800195 case SDE_SSPP_MEMCOLOR:
Benet Clark37809e62016-10-24 10:14:00 -0700196 *idx = sblk->memcolor_blk.base;
Gopikrishnaiah Anandane3842f32015-11-05 12:18:41 -0800197 break;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700198 default:
199 rc = -EINVAL;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700200 }
201
202 return rc;
203}
204
205static void _sspp_setup_opmode(struct sde_hw_pipe *ctx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400206 u32 mask, u8 en)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700207{
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700208 u32 idx;
209 u32 opmode;
210
abeykun48f407a2016-08-25 12:06:44 -0400211 if (!test_bit(SDE_SSPP_SCALER_QSEED2, &ctx->cap->features) ||
212 _sspp_subblk_offset(ctx, SDE_SSPP_SCALER_QSEED2, &idx) ||
213 !test_bit(SDE_SSPP_CSC, &ctx->cap->features))
214 return;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700215
abeykun48f407a2016-08-25 12:06:44 -0400216 opmode = SDE_REG_READ(&ctx->hw, SSPP_VIG_OP_MODE + idx);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700217
abeykun48f407a2016-08-25 12:06:44 -0400218 if (en)
219 opmode |= mask;
220 else
221 opmode &= ~mask;
222
223 SDE_REG_WRITE(&ctx->hw, SSPP_VIG_OP_MODE + idx, opmode);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700224}
abeykun62576142016-08-25 17:44:05 -0400225
226static void _sspp_setup_csc10_opmode(struct sde_hw_pipe *ctx,
227 u32 mask, u8 en)
228{
229 u32 idx;
230 u32 opmode;
231
232 if (_sspp_subblk_offset(ctx, SDE_SSPP_CSC_10BIT, &idx))
233 return;
234
235 opmode = SDE_REG_READ(&ctx->hw, SSPP_VIG_CSC_10_OP_MODE + idx);
236 if (en)
237 opmode |= mask;
238 else
239 opmode &= ~mask;
240
241 SDE_REG_WRITE(&ctx->hw, SSPP_VIG_CSC_10_OP_MODE + idx, opmode);
242}
243
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700244/**
245 * Setup source pixel format, flip,
246 */
247static void sde_hw_sspp_setup_format(struct sde_hw_pipe *ctx,
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400248 const struct sde_format *fmt, u32 flags)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700249{
Clarence Ipe78efb72016-06-24 18:35:21 -0400250 struct sde_hw_blk_reg_map *c;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700251 u32 chroma_samp, unpack, src_format;
252 u32 secure = 0;
253 u32 opmode = 0;
254 u32 idx;
255
Clarence Ipcb410d42016-06-26 22:52:33 -0400256 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx) || !fmt)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700257 return;
258
Clarence Ipe78efb72016-06-24 18:35:21 -0400259 c = &ctx->hw;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700260 opmode = SDE_REG_READ(c, SSPP_SRC_OP_MODE + idx);
Clarence Ip5e2a9222016-06-26 22:38:24 -0400261 opmode &= ~(MDSS_MDP_OP_FLIP_LR | MDSS_MDP_OP_FLIP_UD |
262 MDSS_MDP_OP_BWC_EN | MDSS_MDP_OP_PE_OVERRIDE);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700263
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700264 if (flags & SDE_SSPP_SECURE_OVERLAY_SESSION)
265 secure = 0xF;
266
267 if (flags & SDE_SSPP_FLIP_LR)
268 opmode |= MDSS_MDP_OP_FLIP_LR;
269 if (flags & SDE_SSPP_FLIP_UD)
270 opmode |= MDSS_MDP_OP_FLIP_UD;
271
272 chroma_samp = fmt->chroma_sample;
273 if (flags & SDE_SSPP_SOURCE_ROTATED_90) {
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400274 if (chroma_samp == SDE_CHROMA_H2V1)
275 chroma_samp = SDE_CHROMA_H1V2;
276 else if (chroma_samp == SDE_CHROMA_H1V2)
277 chroma_samp = SDE_CHROMA_H2V1;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700278 }
279
280 src_format = (chroma_samp << 23) | (fmt->fetch_planes << 19) |
281 (fmt->bits[C3_ALPHA] << 6) | (fmt->bits[C2_R_Cr] << 4) |
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400282 (fmt->bits[C1_B_Cb] << 2) | (fmt->bits[C0_G_Y] << 0);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700283
284 if (flags & SDE_SSPP_ROT_90)
285 src_format |= BIT(11); /* ROT90 */
286
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400287 if (fmt->alpha_enable && fmt->fetch_planes == SDE_PLANE_INTERLEAVED)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700288 src_format |= BIT(8); /* SRCC3_EN */
289
Clarence Ipcb410d42016-06-26 22:52:33 -0400290 if (flags & SDE_SSPP_SOLID_FILL)
291 src_format |= BIT(22);
292
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700293 unpack = (fmt->element[3] << 24) | (fmt->element[2] << 16) |
294 (fmt->element[1] << 8) | (fmt->element[0] << 0);
295 src_format |= ((fmt->unpack_count - 1) << 12) |
296 (fmt->unpack_tight << 17) |
297 (fmt->unpack_align_msb << 18) |
298 ((fmt->bpp - 1) << 9);
299
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400300 if (fmt->fetch_mode != SDE_FETCH_LINEAR) {
Clarence Ipcb410d42016-06-26 22:52:33 -0400301 if (SDE_FORMAT_IS_UBWC(fmt))
302 opmode |= MDSS_MDP_OP_BWC_EN;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700303 src_format |= (fmt->fetch_mode & 3) << 30; /*FRAME_FORMAT */
304 SDE_REG_WRITE(c, SSPP_FETCH_CONFIG,
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400305 SDE_FETCH_CONFIG_RESET_VALUE |
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700306 ctx->highest_bank_bit << 18);
307 }
308
Clarence Ipe78efb72016-06-24 18:35:21 -0400309 opmode |= MDSS_MDP_OP_PE_OVERRIDE;
310
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700311 /* if this is YUV pixel format, enable CSC */
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400312 if (SDE_FORMAT_IS_YUV(fmt))
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700313 src_format |= BIT(15);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700314
abeykun5ed42e12016-08-24 17:09:26 -0400315 if (SDE_FORMAT_IS_DX(fmt))
316 src_format |= BIT(14);
317
Clarence Ipe78efb72016-06-24 18:35:21 -0400318 /* update scaler opmode, if appropriate */
abeykun62576142016-08-25 17:44:05 -0400319 if (test_bit(SDE_SSPP_CSC, &ctx->cap->features))
320 _sspp_setup_opmode(ctx, VIG_OP_CSC_EN | VIG_OP_CSC_SRC_DATAFMT,
321 SDE_FORMAT_IS_YUV(fmt));
322 else if (test_bit(SDE_SSPP_CSC_10BIT, &ctx->cap->features))
323 _sspp_setup_csc10_opmode(ctx,
324 VIG_CSC_10_EN | VIG_CSC_10_SRC_DATAFMT,
325 SDE_FORMAT_IS_YUV(fmt));
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700326
327 SDE_REG_WRITE(c, SSPP_SRC_FORMAT + idx, src_format);
328 SDE_REG_WRITE(c, SSPP_SRC_UNPACK_PATTERN + idx, unpack);
329 SDE_REG_WRITE(c, SSPP_SRC_OP_MODE + idx, opmode);
330 SDE_REG_WRITE(c, SSPP_SRC_ADDR_SW_STATUS + idx, secure);
331
332 /* clear previous UBWC error */
333 SDE_REG_WRITE(c, SSPP_UBWC_ERROR_STATUS + idx, BIT(31));
334}
335
336static void sde_hw_sspp_setup_pe_config(struct sde_hw_pipe *ctx,
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700337 struct sde_hw_pixel_ext *pe_ext)
338{
Clarence Ipe78efb72016-06-24 18:35:21 -0400339 struct sde_hw_blk_reg_map *c;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700340 u8 color;
341 u32 lr_pe[4], tb_pe[4], tot_req_pixels[4];
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400342 const u32 bytemask = 0xff;
343 const u32 shortmask = 0xffff;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700344 u32 idx;
345
Clarence Ipe78efb72016-06-24 18:35:21 -0400346 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx) || !pe_ext)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700347 return;
348
Clarence Ipe78efb72016-06-24 18:35:21 -0400349 c = &ctx->hw;
350
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700351 /* program SW pixel extension override for all pipes*/
Clarence Ipe78efb72016-06-24 18:35:21 -0400352 for (color = 0; color < SDE_MAX_PLANES; color++) {
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700353 /* color 2 has the same set of registers as color 1 */
354 if (color == 2)
355 continue;
356
357 lr_pe[color] = ((pe_ext->right_ftch[color] & bytemask) << 24)|
358 ((pe_ext->right_rpt[color] & bytemask) << 16)|
359 ((pe_ext->left_ftch[color] & bytemask) << 8)|
360 (pe_ext->left_rpt[color] & bytemask);
361
362 tb_pe[color] = ((pe_ext->btm_ftch[color] & bytemask) << 24)|
363 ((pe_ext->btm_rpt[color] & bytemask) << 16)|
364 ((pe_ext->top_ftch[color] & bytemask) << 8)|
365 (pe_ext->top_rpt[color] & bytemask);
366
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400367 tot_req_pixels[color] = (((pe_ext->roi_h[color] +
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700368 pe_ext->num_ext_pxls_top[color] +
369 pe_ext->num_ext_pxls_btm[color]) & shortmask) << 16) |
370 ((pe_ext->roi_w[color] +
371 pe_ext->num_ext_pxls_left[color] +
372 pe_ext->num_ext_pxls_right[color]) & shortmask);
373 }
374
375 /* color 0 */
376 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C0_LR + idx, lr_pe[0]);
377 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C0_TB + idx, tb_pe[0]);
378 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C0_REQ_PIXELS + idx,
379 tot_req_pixels[0]);
380
381 /* color 1 and color 2 */
382 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C1C2_LR + idx, lr_pe[1]);
383 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C1C2_TB + idx, tb_pe[1]);
384 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C1C2_REQ_PIXELS + idx,
385 tot_req_pixels[1]);
386
387 /* color 3 */
388 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C3_LR + idx, lr_pe[3]);
389 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C3_TB + idx, lr_pe[3]);
390 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C3_REQ_PIXELS + idx,
391 tot_req_pixels[3]);
392}
393
Clarence Ipe78efb72016-06-24 18:35:21 -0400394static void _sde_hw_sspp_setup_scaler(struct sde_hw_pipe *ctx,
abeykun48f407a2016-08-25 12:06:44 -0400395 struct sde_hw_pipe_cfg *sspp,
396 struct sde_hw_pixel_ext *pe,
397 void *scaler_cfg)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700398{
Clarence Ipe78efb72016-06-24 18:35:21 -0400399 struct sde_hw_blk_reg_map *c;
400 int config_h = 0x0;
401 int config_v = 0x0;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700402 u32 idx;
403
abeykun48f407a2016-08-25 12:06:44 -0400404 (void)sspp;
405 (void)scaler_cfg;
Clarence Ipe78efb72016-06-24 18:35:21 -0400406 if (_sspp_subblk_offset(ctx, SDE_SSPP_SCALER_QSEED2, &idx) || !pe)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700407 return;
408
Clarence Ipe78efb72016-06-24 18:35:21 -0400409 c = &ctx->hw;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700410
Clarence Ipe78efb72016-06-24 18:35:21 -0400411 /* enable scaler(s) if valid filter set */
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400412 if (pe->horz_filter[SDE_SSPP_COMP_0] < SDE_SCALE_FILTER_MAX)
Clarence Ipe78efb72016-06-24 18:35:21 -0400413 config_h |= pe->horz_filter[SDE_SSPP_COMP_0] << 8;
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400414 if (pe->horz_filter[SDE_SSPP_COMP_1_2] < SDE_SCALE_FILTER_MAX)
Clarence Ipe78efb72016-06-24 18:35:21 -0400415 config_h |= pe->horz_filter[SDE_SSPP_COMP_1_2] << 12;
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400416 if (pe->horz_filter[SDE_SSPP_COMP_3] < SDE_SCALE_FILTER_MAX)
Clarence Ipe78efb72016-06-24 18:35:21 -0400417 config_h |= pe->horz_filter[SDE_SSPP_COMP_3] << 16;
418
419 if (config_h)
420 config_h |= BIT(0);
421
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400422 if (pe->vert_filter[SDE_SSPP_COMP_0] < SDE_SCALE_FILTER_MAX)
Clarence Ipe78efb72016-06-24 18:35:21 -0400423 config_v |= pe->vert_filter[SDE_SSPP_COMP_0] << 10;
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400424 if (pe->vert_filter[SDE_SSPP_COMP_1_2] < SDE_SCALE_FILTER_MAX)
Clarence Ipe78efb72016-06-24 18:35:21 -0400425 config_v |= pe->vert_filter[SDE_SSPP_COMP_1_2] << 14;
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400426 if (pe->vert_filter[SDE_SSPP_COMP_3] < SDE_SCALE_FILTER_MAX)
Clarence Ipe78efb72016-06-24 18:35:21 -0400427 config_v |= pe->vert_filter[SDE_SSPP_COMP_3] << 18;
428
429 if (config_v)
430 config_v |= BIT(1);
431
432 SDE_REG_WRITE(c, SCALE_CONFIG + idx, config_h | config_v);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700433 SDE_REG_WRITE(c, COMP0_3_INIT_PHASE_X + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400434 pe->init_phase_x[SDE_SSPP_COMP_0]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700435 SDE_REG_WRITE(c, COMP0_3_INIT_PHASE_Y + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400436 pe->init_phase_y[SDE_SSPP_COMP_0]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700437 SDE_REG_WRITE(c, COMP0_3_PHASE_STEP_X + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400438 pe->phase_step_x[SDE_SSPP_COMP_0]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700439 SDE_REG_WRITE(c, COMP0_3_PHASE_STEP_Y + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400440 pe->phase_step_y[SDE_SSPP_COMP_0]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700441
442 SDE_REG_WRITE(c, COMP1_2_INIT_PHASE_X + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400443 pe->init_phase_x[SDE_SSPP_COMP_1_2]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700444 SDE_REG_WRITE(c, COMP1_2_INIT_PHASE_Y + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400445 pe->init_phase_y[SDE_SSPP_COMP_1_2]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700446 SDE_REG_WRITE(c, COMP1_2_PHASE_STEP_X + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400447 pe->phase_step_x[SDE_SSPP_COMP_1_2]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700448 SDE_REG_WRITE(c, COMP1_2_PHASE_STEP_Y + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400449 pe->phase_step_y[SDE_SSPP_COMP_1_2]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700450}
451
abeykun48f407a2016-08-25 12:06:44 -0400452static void _sde_hw_sspp_setup_scaler3_lut(struct sde_hw_pipe *ctx,
453 struct sde_hw_scaler3_cfg *scaler3_cfg)
454{
455 u32 idx;
456 int i, j, filter;
457 int config_lut = 0x0;
458 unsigned long lut_flags;
459 u32 lut_addr, lut_offset, lut_len;
460 u32 *lut[QSEED3_FILTERS] = {NULL, NULL, NULL, NULL, NULL};
461 static const uint32_t offset[QSEED3_FILTERS][QSEED3_LUT_REGIONS][2] = {
462 {{18, 0x000}, {12, 0x120}, {12, 0x1E0}, {8, 0x2A0} },
463 {{6, 0x320}, {3, 0x3E0}, {3, 0x440}, {3, 0x4A0} },
464 {{6, 0x500}, {3, 0x5c0}, {3, 0x620}, {3, 0x680} },
465 {{6, 0x380}, {3, 0x410}, {3, 0x470}, {3, 0x4d0} },
466 {{6, 0x560}, {3, 0x5f0}, {3, 0x650}, {3, 0x6b0} },
467 };
468
469 if (_sspp_subblk_offset(ctx, SDE_SSPP_SCALER_QSEED3, &idx) ||
470 !scaler3_cfg)
471 return;
472
473 lut_flags = (unsigned long) scaler3_cfg->lut_flag;
474 if (test_bit(QSEED3_COEF_LUT_DIR_BIT, &lut_flags) &&
475 (scaler3_cfg->dir_len == QSEED3_DIR_LUT_SIZE)) {
476 lut[0] = scaler3_cfg->dir_lut;
477 config_lut = 1;
478 }
479 if (test_bit(QSEED3_COEF_LUT_Y_CIR_BIT, &lut_flags) &&
480 (scaler3_cfg->y_rgb_cir_lut_idx < QSEED3_CIRCULAR_LUTS) &&
481 (scaler3_cfg->cir_len == QSEED3_CIR_LUT_SIZE)) {
482 lut[1] = scaler3_cfg->cir_lut +
483 scaler3_cfg->y_rgb_cir_lut_idx * QSEED3_LUT_SIZE;
484 config_lut = 1;
485 }
486 if (test_bit(QSEED3_COEF_LUT_UV_CIR_BIT, &lut_flags) &&
487 (scaler3_cfg->uv_cir_lut_idx < QSEED3_CIRCULAR_LUTS) &&
488 (scaler3_cfg->cir_len == QSEED3_CIR_LUT_SIZE)) {
489 lut[2] = scaler3_cfg->cir_lut +
490 scaler3_cfg->uv_cir_lut_idx * QSEED3_LUT_SIZE;
491 config_lut = 1;
492 }
493 if (test_bit(QSEED3_COEF_LUT_Y_SEP_BIT, &lut_flags) &&
494 (scaler3_cfg->y_rgb_sep_lut_idx < QSEED3_SEPARABLE_LUTS) &&
495 (scaler3_cfg->sep_len == QSEED3_SEP_LUT_SIZE)) {
496 lut[3] = scaler3_cfg->sep_lut +
497 scaler3_cfg->y_rgb_sep_lut_idx * QSEED3_LUT_SIZE;
498 config_lut = 1;
499 }
500 if (test_bit(QSEED3_COEF_LUT_UV_SEP_BIT, &lut_flags) &&
501 (scaler3_cfg->uv_sep_lut_idx < QSEED3_SEPARABLE_LUTS) &&
502 (scaler3_cfg->sep_len == QSEED3_SEP_LUT_SIZE)) {
503 lut[4] = scaler3_cfg->sep_lut +
504 scaler3_cfg->uv_sep_lut_idx * QSEED3_LUT_SIZE;
505 config_lut = 1;
506 }
507
508 if (config_lut) {
509 for (filter = 0; filter < QSEED3_FILTERS; filter++) {
510 if (!lut[filter])
511 continue;
512 lut_offset = 0;
513 for (i = 0; i < QSEED3_LUT_REGIONS; i++) {
514 lut_addr = QSEED3_COEF_LUT + idx
515 + offset[filter][i][1];
516 lut_len = offset[filter][i][0] << 2;
517 for (j = 0; j < lut_len; j++) {
518 SDE_REG_WRITE(&ctx->hw,
519 lut_addr,
520 (lut[filter])[lut_offset++]);
521 lut_addr += 4;
522 }
523 }
524 }
525 }
526
527 if (test_bit(QSEED3_COEF_LUT_SWAP_BIT, &lut_flags))
528 SDE_REG_WRITE(&ctx->hw, QSEED3_COEF_LUT_CTRL + idx, BIT(0));
529
530}
531
532static void _sde_hw_sspp_setup_scaler3_de(struct sde_hw_pipe *ctx,
533 struct sde_hw_scaler3_de_cfg *de_cfg)
534{
535 u32 idx;
536 u32 sharp_lvl, sharp_ctl, shape_ctl, de_thr;
537 u32 adjust_a, adjust_b, adjust_c;
538 struct sde_hw_blk_reg_map *hw;
539
540 if (_sspp_subblk_offset(ctx, SDE_SSPP_SCALER_QSEED3, &idx) || !de_cfg)
541 return;
542
543 if (!de_cfg->enable)
544 return;
545
546 hw = &ctx->hw;
547 sharp_lvl = (de_cfg->sharpen_level1 & 0x1FF) |
548 ((de_cfg->sharpen_level2 & 0x1FF) << 16);
549
550 sharp_ctl = ((de_cfg->limit & 0xF) << 9) |
551 ((de_cfg->prec_shift & 0x7) << 13) |
552 ((de_cfg->clip & 0x7) << 16);
553
554 shape_ctl = (de_cfg->thr_quiet & 0xFF) |
555 ((de_cfg->thr_dieout & 0x3FF) << 16);
556
557 de_thr = (de_cfg->thr_low & 0x3FF) |
558 ((de_cfg->thr_high & 0x3FF) << 16);
559
560 adjust_a = (de_cfg->adjust_a[0] & 0x3FF) |
561 ((de_cfg->adjust_a[1] & 0x3FF) << 10) |
562 ((de_cfg->adjust_a[2] & 0x3FF) << 20);
563
564 adjust_b = (de_cfg->adjust_b[0] & 0x3FF) |
565 ((de_cfg->adjust_b[1] & 0x3FF) << 10) |
566 ((de_cfg->adjust_b[2] & 0x3FF) << 20);
567
568 adjust_c = (de_cfg->adjust_c[0] & 0x3FF) |
569 ((de_cfg->adjust_c[1] & 0x3FF) << 10) |
570 ((de_cfg->adjust_c[2] & 0x3FF) << 20);
571
572 SDE_REG_WRITE(hw, QSEED3_DE_SHARPEN + idx, sharp_lvl);
573 SDE_REG_WRITE(hw, QSEED3_DE_SHARPEN_CTL + idx, sharp_ctl);
574 SDE_REG_WRITE(hw, QSEED3_DE_SHAPE_CTL + idx, shape_ctl);
575 SDE_REG_WRITE(hw, QSEED3_DE_THRESHOLD + idx, de_thr);
576 SDE_REG_WRITE(hw, QSEED3_DE_ADJUST_DATA_0 + idx, adjust_a);
577 SDE_REG_WRITE(hw, QSEED3_DE_ADJUST_DATA_1 + idx, adjust_b);
578 SDE_REG_WRITE(hw, QSEED3_DE_ADJUST_DATA_2 + idx, adjust_c);
579
580}
581
582static void _sde_hw_sspp_setup_scaler3(struct sde_hw_pipe *ctx,
583 struct sde_hw_pipe_cfg *sspp,
584 struct sde_hw_pixel_ext *pe,
585 void *scaler_cfg)
586{
587 u32 idx;
588 u32 op_mode = 0;
589 u32 phase_init, preload, src_y_rgb, src_uv, dst;
590 struct sde_hw_scaler3_cfg *scaler3_cfg = scaler_cfg;
591
592 (void)pe;
593 if (_sspp_subblk_offset(ctx, SDE_SSPP_SCALER_QSEED3, &idx) || !sspp
594 || !scaler3_cfg || !ctx || !ctx->cap || !ctx->cap->sblk)
595 return;
596
597 if (!scaler3_cfg->enable) {
598 SDE_REG_WRITE(&ctx->hw, QSEED3_OP_MODE + idx, 0x0);
599 return;
600 }
601
602 op_mode |= BIT(0);
603 op_mode |= (scaler3_cfg->y_rgb_filter_cfg & 0x3) << 16;
604
605 if (SDE_FORMAT_IS_YUV(sspp->layout.format)) {
606 op_mode |= BIT(12);
607 op_mode |= (scaler3_cfg->uv_filter_cfg & 0x3) << 24;
608 }
609
610 if (!SDE_FORMAT_IS_DX(sspp->layout.format))
611 op_mode |= BIT(14);
612
613 op_mode |= (scaler3_cfg->blend_cfg & 1) << 31;
614 op_mode |= (scaler3_cfg->dir_en) ? BIT(4) : 0;
615
616 preload =
617 ((scaler3_cfg->preload_x[0] & 0x7F) << 0) |
618 ((scaler3_cfg->preload_y[0] & 0x7F) << 8) |
619 ((scaler3_cfg->preload_x[1] & 0x7F) << 16) |
620 ((scaler3_cfg->preload_y[1] & 0x7F) << 24);
621
622 src_y_rgb = (scaler3_cfg->src_width[0] & 0x1FFFF) |
623 ((scaler3_cfg->src_height[0] & 0x1FFFF) << 16);
624
625 src_uv = (scaler3_cfg->src_width[1] & 0x1FFFF) |
626 ((scaler3_cfg->src_height[1] & 0x1FFFF) << 16);
627
628 dst = (scaler3_cfg->dst_width & 0x1FFFF) |
629 ((scaler3_cfg->dst_height & 0x1FFFF) << 16);
630
631 if (scaler3_cfg->de.enable) {
632 _sde_hw_sspp_setup_scaler3_de(ctx, &scaler3_cfg->de);
633 op_mode |= BIT(8);
634 }
635
636 if (scaler3_cfg->lut_flag)
637 _sde_hw_sspp_setup_scaler3_lut(ctx, scaler3_cfg);
638
639 if (ctx->cap->sblk->scaler_blk.version == 0x1002) {
640 if (sspp->layout.format->alpha_enable) {
641 op_mode |= BIT(10);
642 op_mode |= (scaler3_cfg->alpha_filter_cfg & 0x1) << 30;
643 }
644 phase_init =
645 ((scaler3_cfg->init_phase_x[0] & 0x3F) << 0) |
646 ((scaler3_cfg->init_phase_y[0] & 0x3F) << 8) |
647 ((scaler3_cfg->init_phase_x[1] & 0x3F) << 16) |
648 ((scaler3_cfg->init_phase_y[1] & 0x3F) << 24);
649 SDE_REG_WRITE(&ctx->hw, QSEED3_PHASE_INIT + idx, phase_init);
650 } else {
651 if (sspp->layout.format->alpha_enable) {
652 op_mode |= BIT(10);
653 op_mode |= (scaler3_cfg->alpha_filter_cfg & 0x3) << 29;
654 }
655 SDE_REG_WRITE(&ctx->hw, QSEED3_PHASE_INIT_Y_H + idx,
656 scaler3_cfg->init_phase_x[0] & 0x1FFFFF);
657 SDE_REG_WRITE(&ctx->hw, QSEED3_PHASE_INIT_Y_V + idx,
658 scaler3_cfg->init_phase_y[0] & 0x1FFFFF);
659 SDE_REG_WRITE(&ctx->hw, QSEED3_PHASE_INIT_UV_H + idx,
660 scaler3_cfg->init_phase_x[1] & 0x1FFFFF);
661 SDE_REG_WRITE(&ctx->hw, QSEED3_PHASE_INIT_UV_V + idx,
662 scaler3_cfg->init_phase_y[1] & 0x1FFFFF);
663 }
664
665 SDE_REG_WRITE(&ctx->hw, QSEED3_PHASE_STEP_Y_H + idx,
666 scaler3_cfg->phase_step_x[0] & 0xFFFFFF);
667
668 SDE_REG_WRITE(&ctx->hw, QSEED3_PHASE_STEP_Y_V + idx,
669 scaler3_cfg->phase_step_y[0] & 0xFFFFFF);
670
671 SDE_REG_WRITE(&ctx->hw, QSEED3_PHASE_STEP_UV_H + idx,
672 scaler3_cfg->phase_step_x[1] & 0xFFFFFF);
673
674 SDE_REG_WRITE(&ctx->hw, QSEED3_PHASE_STEP_UV_V + idx,
675 scaler3_cfg->phase_step_y[1] & 0xFFFFFF);
676
677 SDE_REG_WRITE(&ctx->hw, QSEED3_PRELOAD + idx, preload);
678
679 SDE_REG_WRITE(&ctx->hw, QSEED3_SRC_SIZE_Y_RGB_A + idx, src_y_rgb);
680
681 SDE_REG_WRITE(&ctx->hw, QSEED3_SRC_SIZE_UV + idx, src_uv);
682
683 SDE_REG_WRITE(&ctx->hw, QSEED3_DST_SIZE + idx, dst);
684
685 SDE_REG_WRITE(&ctx->hw, QSEED3_OP_MODE + idx, op_mode);
686}
687
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700688/**
689 * sde_hw_sspp_setup_rects()
690 */
691static void sde_hw_sspp_setup_rects(struct sde_hw_pipe *ctx,
692 struct sde_hw_pipe_cfg *cfg,
abeykun48f407a2016-08-25 12:06:44 -0400693 struct sde_hw_pixel_ext *pe_ext,
694 void *scale_cfg)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700695{
Clarence Ipe78efb72016-06-24 18:35:21 -0400696 struct sde_hw_blk_reg_map *c;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700697 u32 src_size, src_xy, dst_size, dst_xy, ystride0, ystride1;
698 u32 decimation = 0;
699 u32 idx;
700
Clarence Ipe78efb72016-06-24 18:35:21 -0400701 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx) || !cfg)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700702 return;
703
Clarence Ipe78efb72016-06-24 18:35:21 -0400704 c = &ctx->hw;
705
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700706 /* program pixel extension override */
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400707 if (pe_ext)
Clarence Ipe78efb72016-06-24 18:35:21 -0400708 sde_hw_sspp_setup_pe_config(ctx, pe_ext);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700709
710 /* src and dest rect programming */
Clarence Ipcb410d42016-06-26 22:52:33 -0400711 src_xy = (cfg->src_rect.y << 16) | (cfg->src_rect.x);
712 src_size = (cfg->src_rect.h << 16) | (cfg->src_rect.w);
713 dst_xy = (cfg->dst_rect.y << 16) | (cfg->dst_rect.x);
714 dst_size = (cfg->dst_rect.h << 16) | (cfg->dst_rect.w);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700715
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400716 ystride0 = (cfg->layout.plane_pitch[0]) |
717 (cfg->layout.plane_pitch[1] << 16);
718 ystride1 = (cfg->layout.plane_pitch[2]) |
719 (cfg->layout.plane_pitch[3] << 16);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700720
Clarence Ipe78efb72016-06-24 18:35:21 -0400721 /* program scaler, phase registers, if pipes supporting scaling */
722 if (ctx->cap->features & SDE_SSPP_SCALER) {
723 /* program decimation */
724 decimation = ((1 << cfg->horz_decimation) - 1) << 8;
725 decimation |= ((1 << cfg->vert_decimation) - 1);
abeykun48f407a2016-08-25 12:06:44 -0400726 ctx->ops.setup_scaler(ctx, cfg, pe_ext, scale_cfg);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700727 }
728
Clarence Ipcb410d42016-06-26 22:52:33 -0400729 /* rectangle register programming */
730 SDE_REG_WRITE(c, SSPP_SRC_SIZE + idx, src_size);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700731 SDE_REG_WRITE(c, SSPP_SRC_XY + idx, src_xy);
732 SDE_REG_WRITE(c, SSPP_OUT_SIZE + idx, dst_size);
733 SDE_REG_WRITE(c, SSPP_OUT_XY + idx, dst_xy);
734
735 SDE_REG_WRITE(c, SSPP_SRC_YSTRIDE0 + idx, ystride0);
736 SDE_REG_WRITE(c, SSPP_SRC_YSTRIDE1 + idx, ystride1);
737 SDE_REG_WRITE(c, SSPP_DECIMATION_CONFIG + idx, decimation);
738}
739
740static void sde_hw_sspp_setup_sourceaddress(struct sde_hw_pipe *ctx,
741 struct sde_hw_pipe_cfg *cfg)
742{
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700743 int i;
744 u32 idx;
745
746 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
747 return;
748
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400749 for (i = 0; i < ARRAY_SIZE(cfg->layout.plane_addr); i++)
750 SDE_REG_WRITE(&ctx->hw, SSPP_SRC0_ADDR + idx + i * 0x4,
751 cfg->layout.plane_addr[i]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700752}
753
Clarence Ipe78efb72016-06-24 18:35:21 -0400754static void sde_hw_sspp_setup_csc(struct sde_hw_pipe *ctx,
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700755 struct sde_csc_cfg *data)
756{
Clarence Ipe78efb72016-06-24 18:35:21 -0400757 u32 idx;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700758
Clarence Ipe78efb72016-06-24 18:35:21 -0400759 if (_sspp_subblk_offset(ctx, SDE_SSPP_CSC, &idx) || !data)
760 return;
761
abeykun62576142016-08-25 17:44:05 -0400762 if (test_bit(SDE_SSPP_CSC_10BIT, &ctx->cap->features))
763 idx += CSC_10BIT_OFFSET;
764
Clarence Ipe78efb72016-06-24 18:35:21 -0400765 sde_hw_csc_setup(&ctx->hw, idx, data);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700766}
767
768static void sde_hw_sspp_setup_sharpening(struct sde_hw_pipe *ctx,
769 struct sde_hw_sharp_cfg *cfg)
770{
Clarence Ipe78efb72016-06-24 18:35:21 -0400771 struct sde_hw_blk_reg_map *c;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700772 u32 idx;
773
Clarence Ip4c1d9772016-06-26 09:35:38 -0400774 if (_sspp_subblk_offset(ctx, SDE_SSPP_SCALER_QSEED2, &idx) || !cfg ||
775 !test_bit(SDE_SSPP_SCALER_QSEED2, &ctx->cap->features))
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700776 return;
777
Clarence Ipe78efb72016-06-24 18:35:21 -0400778 c = &ctx->hw;
779
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700780 SDE_REG_WRITE(c, VIG_0_QSEED2_SHARP + idx, cfg->strength);
781 SDE_REG_WRITE(c, VIG_0_QSEED2_SHARP + idx + 0x4, cfg->edge_thr);
782 SDE_REG_WRITE(c, VIG_0_QSEED2_SHARP + idx + 0x8, cfg->smooth_thr);
783 SDE_REG_WRITE(c, VIG_0_QSEED2_SHARP + idx + 0xC, cfg->noise_thr);
784}
785
Clarence Ipcb410d42016-06-26 22:52:33 -0400786static void sde_hw_sspp_setup_solidfill(struct sde_hw_pipe *ctx, u32 color)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700787{
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700788 u32 idx;
789
790 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
791 return;
792
Clarence Ipcb410d42016-06-26 22:52:33 -0400793 SDE_REG_WRITE(&ctx->hw, SSPP_SRC_CONSTANT_COLOR + idx, color);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700794}
795
Alan Kwong1a00e4d2016-07-18 09:42:30 -0400796static void sde_hw_sspp_setup_danger_safe_lut(struct sde_hw_pipe *ctx,
797 struct sde_hw_pipe_qos_cfg *cfg)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700798{
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700799 u32 idx;
800
801 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
802 return;
803
Alan Kwong1a00e4d2016-07-18 09:42:30 -0400804 SDE_REG_WRITE(&ctx->hw, SSPP_DANGER_LUT + idx, cfg->danger_lut);
805 SDE_REG_WRITE(&ctx->hw, SSPP_SAFE_LUT + idx, cfg->safe_lut);
806}
807
808static void sde_hw_sspp_setup_creq_lut(struct sde_hw_pipe *ctx,
809 struct sde_hw_pipe_qos_cfg *cfg)
810{
811 u32 idx;
812
813 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
814 return;
815
816 SDE_REG_WRITE(&ctx->hw, SSPP_CREQ_LUT + idx, cfg->creq_lut);
817}
818
819static void sde_hw_sspp_setup_qos_ctrl(struct sde_hw_pipe *ctx,
820 struct sde_hw_pipe_qos_cfg *cfg)
821{
822 u32 idx;
823 u32 qos_ctrl = 0;
824
825 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
826 return;
827
828 if (cfg->vblank_en) {
829 qos_ctrl |= ((cfg->creq_vblank &
830 SSPP_QOS_CTRL_CREQ_VBLANK_MASK) <<
831 SSPP_QOS_CTRL_CREQ_VBLANK_OFF);
832 qos_ctrl |= ((cfg->danger_vblank &
833 SSPP_QOS_CTRL_DANGER_VBLANK_MASK) <<
834 SSPP_QOS_CTRL_DANGER_VBLANK_OFF);
835 qos_ctrl |= SSPP_QOS_CTRL_VBLANK_EN;
836 }
837
838 if (cfg->danger_safe_en)
839 qos_ctrl |= SSPP_QOS_CTRL_DANGER_SAFE_EN;
840
841 SDE_REG_WRITE(&ctx->hw, SSPP_QOS_CTRL + idx, qos_ctrl);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700842}
843
Benet Clarkeb1b4462016-06-27 14:43:06 -0700844static void _setup_layer_ops(struct sde_hw_pipe *c,
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700845 unsigned long features)
846{
847 if (test_bit(SDE_SSPP_SRC, &features)) {
Benet Clarkeb1b4462016-06-27 14:43:06 -0700848 c->ops.setup_format = sde_hw_sspp_setup_format;
849 c->ops.setup_rects = sde_hw_sspp_setup_rects;
850 c->ops.setup_sourceaddress = sde_hw_sspp_setup_sourceaddress;
851 c->ops.setup_solidfill = sde_hw_sspp_setup_solidfill;
Alan Kwong1a00e4d2016-07-18 09:42:30 -0400852 }
853 if (test_bit(SDE_SSPP_QOS, &features)) {
Benet Clarkeb1b4462016-06-27 14:43:06 -0700854 c->ops.setup_danger_safe_lut =
855 sde_hw_sspp_setup_danger_safe_lut;
856 c->ops.setup_creq_lut = sde_hw_sspp_setup_creq_lut;
857 c->ops.setup_qos_ctrl = sde_hw_sspp_setup_qos_ctrl;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700858 }
Benet Clarkeb1b4462016-06-27 14:43:06 -0700859
abeykun62576142016-08-25 17:44:05 -0400860 if (test_bit(SDE_SSPP_CSC, &features) ||
861 test_bit(SDE_SSPP_CSC_10BIT, &features))
Benet Clarkeb1b4462016-06-27 14:43:06 -0700862 c->ops.setup_csc = sde_hw_sspp_setup_csc;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700863
Gopikrishnaiah Anandane3842f32015-11-05 12:18:41 -0800864 if (test_bit(SDE_SSPP_SCALER_QSEED2, &features))
Benet Clarkeb1b4462016-06-27 14:43:06 -0700865 c->ops.setup_sharpening = sde_hw_sspp_setup_sharpening;
abeykun48f407a2016-08-25 12:06:44 -0400866
867 if (test_bit(SDE_SSPP_SCALER_QSEED3, &features))
Benet Clarkeb1b4462016-06-27 14:43:06 -0700868 c->ops.setup_scaler = _sde_hw_sspp_setup_scaler3;
abeykun48f407a2016-08-25 12:06:44 -0400869 else
Benet Clarkeb1b4462016-06-27 14:43:06 -0700870 c->ops.setup_scaler = _sde_hw_sspp_setup_scaler;
871
872 if (test_bit(SDE_SSPP_HSIC, &features)) {
873 /* TODO: add version based assignment here as inline or macro */
874 if (c->cap->sblk->hsic_blk.version ==
875 (SDE_COLOR_PROCESS_VER(0x1, 0x7))) {
876 c->ops.setup_pa_hue = sde_setup_pipe_pa_hue_v1_7;
877 c->ops.setup_pa_sat = sde_setup_pipe_pa_sat_v1_7;
878 c->ops.setup_pa_val = sde_setup_pipe_pa_val_v1_7;
879 c->ops.setup_pa_cont = sde_setup_pipe_pa_cont_v1_7;
880 }
881 }
Benet Clarkd009b1d2016-06-27 14:45:59 -0700882
883 if (test_bit(SDE_SSPP_MEMCOLOR, &features)) {
884 if (c->cap->sblk->memcolor_blk.version ==
885 (SDE_COLOR_PROCESS_VER(0x1, 0x7)))
886 c->ops.setup_pa_memcolor =
887 sde_setup_pipe_pa_memcol_v1_7;
888 }
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700889}
890
891static struct sde_sspp_cfg *_sspp_offset(enum sde_sspp sspp,
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700892 void __iomem *addr,
Clarence Ipe78efb72016-06-24 18:35:21 -0400893 struct sde_mdss_cfg *catalog,
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700894 struct sde_hw_blk_reg_map *b)
895{
896 int i;
897
Clarence Ipe78efb72016-06-24 18:35:21 -0400898 if ((sspp < SSPP_MAX) && catalog && addr && b) {
899 for (i = 0; i < catalog->sspp_count; i++) {
900 if (sspp == catalog->sspp[i].id) {
901 b->base_off = addr;
902 b->blk_off = catalog->sspp[i].base;
903 b->hwversion = catalog->hwversion;
Clarence Ip4ce59322016-06-26 22:27:51 -0400904 b->log_mask = SDE_DBG_MASK_SSPP;
Clarence Ipe78efb72016-06-24 18:35:21 -0400905 return &catalog->sspp[i];
906 }
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700907 }
908 }
909
910 return ERR_PTR(-ENOMEM);
911}
912
913struct sde_hw_pipe *sde_hw_sspp_init(enum sde_sspp idx,
914 void __iomem *addr,
Clarence Ipe78efb72016-06-24 18:35:21 -0400915 struct sde_mdss_cfg *catalog)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700916{
Clarence Ipe78efb72016-06-24 18:35:21 -0400917 struct sde_hw_pipe *ctx;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700918 struct sde_sspp_cfg *cfg;
919
Clarence Ipe78efb72016-06-24 18:35:21 -0400920 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
921 if (!ctx)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700922 return ERR_PTR(-ENOMEM);
923
Clarence Ipe78efb72016-06-24 18:35:21 -0400924 cfg = _sspp_offset(idx, addr, catalog, &ctx->hw);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700925 if (IS_ERR_OR_NULL(cfg)) {
Clarence Ipe78efb72016-06-24 18:35:21 -0400926 kfree(ctx);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700927 return ERR_PTR(-EINVAL);
928 }
929
930 /* Assign ops */
Clarence Ipe78efb72016-06-24 18:35:21 -0400931 ctx->idx = idx;
932 ctx->cap = cfg;
Benet Clarkeb1b4462016-06-27 14:43:06 -0700933 _setup_layer_ops(ctx, ctx->cap->features);
Clarence Ipe78efb72016-06-24 18:35:21 -0400934 ctx->highest_bank_bit = catalog->mdp[0].highest_bank_bit;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700935
Clarence Ipe78efb72016-06-24 18:35:21 -0400936 return ctx;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700937}
938
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400939void sde_hw_sspp_destroy(struct sde_hw_pipe *ctx)
940{
941 kfree(ctx);
942}
943