blob: 65a0f0f86a3a33fab4a8ab80c5b120b07ced0cc9 [file] [log] [blame]
Narendra Muppalla1b0b3352015-09-29 10:16:51 -07001/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
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"
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070017
Lloyd Atkinson9a673492016-07-05 11:41:57 -040018#define SDE_FETCH_CONFIG_RESET_VALUE 0x00000087
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070019
20/* SDE_SSPP_SRC */
21#define SSPP_SRC_SIZE 0x00
22#define SSPP_SRC_XY 0x08
23#define SSPP_OUT_SIZE 0x0c
24#define SSPP_OUT_XY 0x10
25#define SSPP_SRC0_ADDR 0x14
26#define SSPP_SRC1_ADDR 0x18
27#define SSPP_SRC2_ADDR 0x1C
28#define SSPP_SRC3_ADDR 0x20
29#define SSPP_SRC_YSTRIDE0 0x24
30#define SSPP_SRC_YSTRIDE1 0x28
31#define SSPP_SRC_FORMAT 0x30
32#define SSPP_SRC_UNPACK_PATTERN 0x34
33#define SSPP_SRC_OP_MODE 0x38
34#define MDSS_MDP_OP_DEINTERLACE BIT(22)
35
36#define MDSS_MDP_OP_DEINTERLACE_ODD BIT(23)
37#define MDSS_MDP_OP_IGC_ROM_1 BIT(18)
38#define MDSS_MDP_OP_IGC_ROM_0 BIT(17)
39#define MDSS_MDP_OP_IGC_EN BIT(16)
40#define MDSS_MDP_OP_FLIP_UD BIT(14)
41#define MDSS_MDP_OP_FLIP_LR BIT(13)
42#define MDSS_MDP_OP_BWC_EN BIT(0)
43#define MDSS_MDP_OP_PE_OVERRIDE BIT(31)
44#define MDSS_MDP_OP_BWC_LOSSLESS (0 << 1)
45#define MDSS_MDP_OP_BWC_Q_HIGH (1 << 1)
46#define MDSS_MDP_OP_BWC_Q_MED (2 << 1)
47
48#define SSPP_SRC_CONSTANT_COLOR 0x3c
49#define SSPP_FETCH_CONFIG 0x048
50#define SSPP_DANGER_LUT 0x60
51#define SSPP_SAFE_LUT 0x64
52#define SSPP_CREQ_LUT 0x68
Alan Kwong1a00e4d2016-07-18 09:42:30 -040053#define SSPP_QOS_CTRL 0x6C
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070054#define SSPP_DECIMATION_CONFIG 0xB4
55#define SSPP_SRC_ADDR_SW_STATUS 0x70
56#define SSPP_SW_PIX_EXT_C0_LR 0x100
57#define SSPP_SW_PIX_EXT_C0_TB 0x104
58#define SSPP_SW_PIX_EXT_C0_REQ_PIXELS 0x108
59#define SSPP_SW_PIX_EXT_C1C2_LR 0x110
60#define SSPP_SW_PIX_EXT_C1C2_TB 0x114
61#define SSPP_SW_PIX_EXT_C1C2_REQ_PIXELS 0x118
62#define SSPP_SW_PIX_EXT_C3_LR 0x120
63#define SSPP_SW_PIX_EXT_C3_TB 0x124
64#define SSPP_SW_PIX_EXT_C3_REQ_PIXELS 0x128
65#define SSPP_UBWC_ERROR_STATUS 0x138
Clarence Ipe78efb72016-06-24 18:35:21 -040066#define SSPP_VIG_OP_MODE 0x0
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070067
Alan Kwong1a00e4d2016-07-18 09:42:30 -040068/* SSPP_QOS_CTRL */
69#define SSPP_QOS_CTRL_VBLANK_EN BIT(16)
70#define SSPP_QOS_CTRL_DANGER_SAFE_EN BIT(0)
71#define SSPP_QOS_CTRL_DANGER_VBLANK_MASK 0x3
72#define SSPP_QOS_CTRL_DANGER_VBLANK_OFF 4
73#define SSPP_QOS_CTRL_CREQ_VBLANK_MASK 0x3
74#define SSPP_QOS_CTRL_CREQ_VBLANK_OFF 20
75
Clarence Ipe78efb72016-06-24 18:35:21 -040076/* SDE_SSPP_SCALER_QSEED2 */
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070077#define SCALE_CONFIG 0x04
78#define COMP0_3_PHASE_STEP_X 0x10
79#define COMP0_3_PHASE_STEP_Y 0x14
80#define COMP1_2_PHASE_STEP_X 0x18
81#define COMP1_2_PHASE_STEP_Y 0x1c
82#define COMP0_3_INIT_PHASE_X 0x20
83#define COMP0_3_INIT_PHASE_Y 0x24
84#define COMP1_2_INIT_PHASE_X 0x28
85#define COMP1_2_INIT_PHASE_Y 0x2C
86#define VIG_0_QSEED2_SHARP 0x30
87
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070088/*
Clarence Ipe78efb72016-06-24 18:35:21 -040089 * Definitions for ViG op modes
90 */
91#define VIG_OP_CSC_DST_DATAFMT BIT(19)
92#define VIG_OP_CSC_SRC_DATAFMT BIT(18)
93#define VIG_OP_CSC_EN BIT(17)
94#define VIG_OP_MEM_PROT_CONT BIT(15)
95#define VIG_OP_MEM_PROT_VAL BIT(14)
96#define VIG_OP_MEM_PROT_SAT BIT(13)
97#define VIG_OP_MEM_PROT_HUE BIT(12)
98#define VIG_OP_HIST BIT(8)
99#define VIG_OP_SKY_COL BIT(7)
100#define VIG_OP_FOIL BIT(6)
101#define VIG_OP_SKIN_COL BIT(5)
102#define VIG_OP_PA_EN BIT(4)
103#define VIG_OP_PA_SAT_ZERO_EXP BIT(2)
104#define VIG_OP_MEM_PROT_BLEND BIT(1)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700105
106static inline int _sspp_subblk_offset(struct sde_hw_pipe *ctx,
107 int s_id,
108 u32 *idx)
109{
110 int rc = 0;
111 const struct sde_sspp_sub_blks *sblk = ctx->cap->sblk;
112
Clarence Ipe78efb72016-06-24 18:35:21 -0400113 if (!ctx)
114 return -EINVAL;
115
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700116 switch (s_id) {
117 case SDE_SSPP_SRC:
118 *idx = sblk->src_blk.base;
119 break;
Clarence Ipe78efb72016-06-24 18:35:21 -0400120 case SDE_SSPP_SCALER_QSEED2:
121 case SDE_SSPP_SCALER_QSEED3:
122 case SDE_SSPP_SCALER_RGB:
123 *idx = sblk->scaler_blk.base;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700124 break;
125 case SDE_SSPP_CSC:
126 *idx = sblk->csc_blk.base;
127 break;
128 case SDE_SSPP_PA_V1:
129 *idx = sblk->pa_blk.base;
130 break;
131 case SDE_SSPP_HIST_V1:
132 *idx = sblk->hist_lut.base;
133 break;
134 case SDE_SSPP_PCC:
135 *idx = sblk->pcc_blk.base;
136 break;
137 default:
138 rc = -EINVAL;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700139 }
140
141 return rc;
142}
143
144static void _sspp_setup_opmode(struct sde_hw_pipe *ctx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400145 u32 mask, u8 en)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700146{
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700147 u32 idx;
148 u32 opmode;
149
Clarence Ipe78efb72016-06-24 18:35:21 -0400150 if (!_sspp_subblk_offset(ctx, SDE_SSPP_SCALER_QSEED2, &idx) &&
151 (test_bit(SDE_SSPP_CSC, &ctx->cap->features) ||
152 test_bit(SDE_SSPP_PA_V1, &ctx->cap->features))) {
153 opmode = SDE_REG_READ(&ctx->hw, SSPP_VIG_OP_MODE + idx);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700154
Clarence Ipe78efb72016-06-24 18:35:21 -0400155 if (en)
156 opmode |= mask;
157 else
158 opmode &= ~mask;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700159
Clarence Ipe78efb72016-06-24 18:35:21 -0400160 SDE_REG_WRITE(&ctx->hw, SSPP_VIG_OP_MODE + idx, opmode);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700161 }
162}
163/**
164 * Setup source pixel format, flip,
165 */
166static void sde_hw_sspp_setup_format(struct sde_hw_pipe *ctx,
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400167 const struct sde_format *fmt, u32 flags)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700168{
Clarence Ipe78efb72016-06-24 18:35:21 -0400169 struct sde_hw_blk_reg_map *c;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700170 u32 chroma_samp, unpack, src_format;
171 u32 secure = 0;
172 u32 opmode = 0;
173 u32 idx;
174
Clarence Ipcb410d42016-06-26 22:52:33 -0400175 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx) || !fmt)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700176 return;
177
Clarence Ipe78efb72016-06-24 18:35:21 -0400178 c = &ctx->hw;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700179 opmode = SDE_REG_READ(c, SSPP_SRC_OP_MODE + idx);
Clarence Ip5e2a9222016-06-26 22:38:24 -0400180 opmode &= ~(MDSS_MDP_OP_FLIP_LR | MDSS_MDP_OP_FLIP_UD |
181 MDSS_MDP_OP_BWC_EN | MDSS_MDP_OP_PE_OVERRIDE);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700182
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700183 if (flags & SDE_SSPP_SECURE_OVERLAY_SESSION)
184 secure = 0xF;
185
186 if (flags & SDE_SSPP_FLIP_LR)
187 opmode |= MDSS_MDP_OP_FLIP_LR;
188 if (flags & SDE_SSPP_FLIP_UD)
189 opmode |= MDSS_MDP_OP_FLIP_UD;
190
191 chroma_samp = fmt->chroma_sample;
192 if (flags & SDE_SSPP_SOURCE_ROTATED_90) {
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400193 if (chroma_samp == SDE_CHROMA_H2V1)
194 chroma_samp = SDE_CHROMA_H1V2;
195 else if (chroma_samp == SDE_CHROMA_H1V2)
196 chroma_samp = SDE_CHROMA_H2V1;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700197 }
198
199 src_format = (chroma_samp << 23) | (fmt->fetch_planes << 19) |
200 (fmt->bits[C3_ALPHA] << 6) | (fmt->bits[C2_R_Cr] << 4) |
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400201 (fmt->bits[C1_B_Cb] << 2) | (fmt->bits[C0_G_Y] << 0);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700202
203 if (flags & SDE_SSPP_ROT_90)
204 src_format |= BIT(11); /* ROT90 */
205
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400206 if (fmt->alpha_enable && fmt->fetch_planes == SDE_PLANE_INTERLEAVED)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700207 src_format |= BIT(8); /* SRCC3_EN */
208
Clarence Ipcb410d42016-06-26 22:52:33 -0400209 if (flags & SDE_SSPP_SOLID_FILL)
210 src_format |= BIT(22);
211
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700212 unpack = (fmt->element[3] << 24) | (fmt->element[2] << 16) |
213 (fmt->element[1] << 8) | (fmt->element[0] << 0);
214 src_format |= ((fmt->unpack_count - 1) << 12) |
215 (fmt->unpack_tight << 17) |
216 (fmt->unpack_align_msb << 18) |
217 ((fmt->bpp - 1) << 9);
218
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400219 if (fmt->fetch_mode != SDE_FETCH_LINEAR) {
Clarence Ipcb410d42016-06-26 22:52:33 -0400220 if (SDE_FORMAT_IS_UBWC(fmt))
221 opmode |= MDSS_MDP_OP_BWC_EN;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700222 src_format |= (fmt->fetch_mode & 3) << 30; /*FRAME_FORMAT */
223 SDE_REG_WRITE(c, SSPP_FETCH_CONFIG,
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400224 SDE_FETCH_CONFIG_RESET_VALUE |
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700225 ctx->highest_bank_bit << 18);
226 }
227
Clarence Ipe78efb72016-06-24 18:35:21 -0400228 opmode |= MDSS_MDP_OP_PE_OVERRIDE;
229
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700230 /* if this is YUV pixel format, enable CSC */
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400231 if (SDE_FORMAT_IS_YUV(fmt))
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700232 src_format |= BIT(15);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700233
Clarence Ipe78efb72016-06-24 18:35:21 -0400234 /* update scaler opmode, if appropriate */
235 _sspp_setup_opmode(ctx,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400236 VIG_OP_CSC_EN | VIG_OP_CSC_SRC_DATAFMT, SDE_FORMAT_IS_YUV(fmt));
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700237
238 SDE_REG_WRITE(c, SSPP_SRC_FORMAT + idx, src_format);
239 SDE_REG_WRITE(c, SSPP_SRC_UNPACK_PATTERN + idx, unpack);
240 SDE_REG_WRITE(c, SSPP_SRC_OP_MODE + idx, opmode);
241 SDE_REG_WRITE(c, SSPP_SRC_ADDR_SW_STATUS + idx, secure);
242
243 /* clear previous UBWC error */
244 SDE_REG_WRITE(c, SSPP_UBWC_ERROR_STATUS + idx, BIT(31));
245}
246
247static void sde_hw_sspp_setup_pe_config(struct sde_hw_pipe *ctx,
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700248 struct sde_hw_pixel_ext *pe_ext)
249{
Clarence Ipe78efb72016-06-24 18:35:21 -0400250 struct sde_hw_blk_reg_map *c;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700251 u8 color;
252 u32 lr_pe[4], tb_pe[4], tot_req_pixels[4];
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400253 const u32 bytemask = 0xff;
254 const u32 shortmask = 0xffff;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700255 u32 idx;
256
Clarence Ipe78efb72016-06-24 18:35:21 -0400257 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx) || !pe_ext)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700258 return;
259
Clarence Ipe78efb72016-06-24 18:35:21 -0400260 c = &ctx->hw;
261
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700262 /* program SW pixel extension override for all pipes*/
Clarence Ipe78efb72016-06-24 18:35:21 -0400263 for (color = 0; color < SDE_MAX_PLANES; color++) {
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700264 /* color 2 has the same set of registers as color 1 */
265 if (color == 2)
266 continue;
267
268 lr_pe[color] = ((pe_ext->right_ftch[color] & bytemask) << 24)|
269 ((pe_ext->right_rpt[color] & bytemask) << 16)|
270 ((pe_ext->left_ftch[color] & bytemask) << 8)|
271 (pe_ext->left_rpt[color] & bytemask);
272
273 tb_pe[color] = ((pe_ext->btm_ftch[color] & bytemask) << 24)|
274 ((pe_ext->btm_rpt[color] & bytemask) << 16)|
275 ((pe_ext->top_ftch[color] & bytemask) << 8)|
276 (pe_ext->top_rpt[color] & bytemask);
277
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400278 tot_req_pixels[color] = (((pe_ext->roi_h[color] +
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700279 pe_ext->num_ext_pxls_top[color] +
280 pe_ext->num_ext_pxls_btm[color]) & shortmask) << 16) |
281 ((pe_ext->roi_w[color] +
282 pe_ext->num_ext_pxls_left[color] +
283 pe_ext->num_ext_pxls_right[color]) & shortmask);
284 }
285
286 /* color 0 */
287 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C0_LR + idx, lr_pe[0]);
288 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C0_TB + idx, tb_pe[0]);
289 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C0_REQ_PIXELS + idx,
290 tot_req_pixels[0]);
291
292 /* color 1 and color 2 */
293 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C1C2_LR + idx, lr_pe[1]);
294 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C1C2_TB + idx, tb_pe[1]);
295 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C1C2_REQ_PIXELS + idx,
296 tot_req_pixels[1]);
297
298 /* color 3 */
299 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C3_LR + idx, lr_pe[3]);
300 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C3_TB + idx, lr_pe[3]);
301 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C3_REQ_PIXELS + idx,
302 tot_req_pixels[3]);
303}
304
Clarence Ipe78efb72016-06-24 18:35:21 -0400305static void _sde_hw_sspp_setup_scaler(struct sde_hw_pipe *ctx,
306 struct sde_hw_pixel_ext *pe)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700307{
Clarence Ipe78efb72016-06-24 18:35:21 -0400308 struct sde_hw_blk_reg_map *c;
309 int config_h = 0x0;
310 int config_v = 0x0;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700311 u32 idx;
312
Clarence Ipe78efb72016-06-24 18:35:21 -0400313 if (_sspp_subblk_offset(ctx, SDE_SSPP_SCALER_QSEED2, &idx) || !pe)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700314 return;
315
Clarence Ipe78efb72016-06-24 18:35:21 -0400316 c = &ctx->hw;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700317
Clarence Ipe78efb72016-06-24 18:35:21 -0400318 /* enable scaler(s) if valid filter set */
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400319 if (pe->horz_filter[SDE_SSPP_COMP_0] < SDE_SCALE_FILTER_MAX)
Clarence Ipe78efb72016-06-24 18:35:21 -0400320 config_h |= pe->horz_filter[SDE_SSPP_COMP_0] << 8;
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400321 if (pe->horz_filter[SDE_SSPP_COMP_1_2] < SDE_SCALE_FILTER_MAX)
Clarence Ipe78efb72016-06-24 18:35:21 -0400322 config_h |= pe->horz_filter[SDE_SSPP_COMP_1_2] << 12;
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400323 if (pe->horz_filter[SDE_SSPP_COMP_3] < SDE_SCALE_FILTER_MAX)
Clarence Ipe78efb72016-06-24 18:35:21 -0400324 config_h |= pe->horz_filter[SDE_SSPP_COMP_3] << 16;
325
326 if (config_h)
327 config_h |= BIT(0);
328
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400329 if (pe->vert_filter[SDE_SSPP_COMP_0] < SDE_SCALE_FILTER_MAX)
Clarence Ipe78efb72016-06-24 18:35:21 -0400330 config_v |= pe->vert_filter[SDE_SSPP_COMP_0] << 10;
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400331 if (pe->vert_filter[SDE_SSPP_COMP_1_2] < SDE_SCALE_FILTER_MAX)
Clarence Ipe78efb72016-06-24 18:35:21 -0400332 config_v |= pe->vert_filter[SDE_SSPP_COMP_1_2] << 14;
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400333 if (pe->vert_filter[SDE_SSPP_COMP_3] < SDE_SCALE_FILTER_MAX)
Clarence Ipe78efb72016-06-24 18:35:21 -0400334 config_v |= pe->vert_filter[SDE_SSPP_COMP_3] << 18;
335
336 if (config_v)
337 config_v |= BIT(1);
338
339 SDE_REG_WRITE(c, SCALE_CONFIG + idx, config_h | config_v);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700340 SDE_REG_WRITE(c, COMP0_3_INIT_PHASE_X + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400341 pe->init_phase_x[SDE_SSPP_COMP_0]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700342 SDE_REG_WRITE(c, COMP0_3_INIT_PHASE_Y + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400343 pe->init_phase_y[SDE_SSPP_COMP_0]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700344 SDE_REG_WRITE(c, COMP0_3_PHASE_STEP_X + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400345 pe->phase_step_x[SDE_SSPP_COMP_0]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700346 SDE_REG_WRITE(c, COMP0_3_PHASE_STEP_Y + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400347 pe->phase_step_y[SDE_SSPP_COMP_0]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700348
349 SDE_REG_WRITE(c, COMP1_2_INIT_PHASE_X + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400350 pe->init_phase_x[SDE_SSPP_COMP_1_2]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700351 SDE_REG_WRITE(c, COMP1_2_INIT_PHASE_Y + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400352 pe->init_phase_y[SDE_SSPP_COMP_1_2]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700353 SDE_REG_WRITE(c, COMP1_2_PHASE_STEP_X + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400354 pe->phase_step_x[SDE_SSPP_COMP_1_2]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700355 SDE_REG_WRITE(c, COMP1_2_PHASE_STEP_Y + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400356 pe->phase_step_y[SDE_SSPP_COMP_1_2]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700357}
358
359/**
360 * sde_hw_sspp_setup_rects()
361 */
362static void sde_hw_sspp_setup_rects(struct sde_hw_pipe *ctx,
363 struct sde_hw_pipe_cfg *cfg,
364 struct sde_hw_pixel_ext *pe_ext)
365{
Clarence Ipe78efb72016-06-24 18:35:21 -0400366 struct sde_hw_blk_reg_map *c;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700367 u32 src_size, src_xy, dst_size, dst_xy, ystride0, ystride1;
368 u32 decimation = 0;
369 u32 idx;
370
Clarence Ipe78efb72016-06-24 18:35:21 -0400371 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx) || !cfg)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700372 return;
373
Clarence Ipe78efb72016-06-24 18:35:21 -0400374 c = &ctx->hw;
375
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700376 /* program pixel extension override */
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400377 if (pe_ext)
Clarence Ipe78efb72016-06-24 18:35:21 -0400378 sde_hw_sspp_setup_pe_config(ctx, pe_ext);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700379
380 /* src and dest rect programming */
Clarence Ipcb410d42016-06-26 22:52:33 -0400381 src_xy = (cfg->src_rect.y << 16) | (cfg->src_rect.x);
382 src_size = (cfg->src_rect.h << 16) | (cfg->src_rect.w);
383 dst_xy = (cfg->dst_rect.y << 16) | (cfg->dst_rect.x);
384 dst_size = (cfg->dst_rect.h << 16) | (cfg->dst_rect.w);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700385
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400386 ystride0 = (cfg->layout.plane_pitch[0]) |
387 (cfg->layout.plane_pitch[1] << 16);
388 ystride1 = (cfg->layout.plane_pitch[2]) |
389 (cfg->layout.plane_pitch[3] << 16);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700390
Clarence Ipe78efb72016-06-24 18:35:21 -0400391 /* program scaler, phase registers, if pipes supporting scaling */
392 if (ctx->cap->features & SDE_SSPP_SCALER) {
393 /* program decimation */
394 decimation = ((1 << cfg->horz_decimation) - 1) << 8;
395 decimation |= ((1 << cfg->vert_decimation) - 1);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700396
Clarence Ipe78efb72016-06-24 18:35:21 -0400397 _sde_hw_sspp_setup_scaler(ctx, pe_ext);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700398 }
399
Clarence Ipcb410d42016-06-26 22:52:33 -0400400 /* rectangle register programming */
401 SDE_REG_WRITE(c, SSPP_SRC_SIZE + idx, src_size);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700402 SDE_REG_WRITE(c, SSPP_SRC_XY + idx, src_xy);
403 SDE_REG_WRITE(c, SSPP_OUT_SIZE + idx, dst_size);
404 SDE_REG_WRITE(c, SSPP_OUT_XY + idx, dst_xy);
405
406 SDE_REG_WRITE(c, SSPP_SRC_YSTRIDE0 + idx, ystride0);
407 SDE_REG_WRITE(c, SSPP_SRC_YSTRIDE1 + idx, ystride1);
408 SDE_REG_WRITE(c, SSPP_DECIMATION_CONFIG + idx, decimation);
409}
410
411static void sde_hw_sspp_setup_sourceaddress(struct sde_hw_pipe *ctx,
412 struct sde_hw_pipe_cfg *cfg)
413{
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700414 int i;
415 u32 idx;
416
417 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
418 return;
419
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400420 for (i = 0; i < ARRAY_SIZE(cfg->layout.plane_addr); i++)
421 SDE_REG_WRITE(&ctx->hw, SSPP_SRC0_ADDR + idx + i * 0x4,
422 cfg->layout.plane_addr[i]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700423}
424
Clarence Ipe78efb72016-06-24 18:35:21 -0400425static void sde_hw_sspp_setup_csc(struct sde_hw_pipe *ctx,
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700426 struct sde_csc_cfg *data)
427{
Clarence Ipe78efb72016-06-24 18:35:21 -0400428 u32 idx;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700429
Clarence Ipe78efb72016-06-24 18:35:21 -0400430 if (_sspp_subblk_offset(ctx, SDE_SSPP_CSC, &idx) || !data)
431 return;
432
433 sde_hw_csc_setup(&ctx->hw, idx, data);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700434}
435
436static void sde_hw_sspp_setup_sharpening(struct sde_hw_pipe *ctx,
437 struct sde_hw_sharp_cfg *cfg)
438{
Clarence Ipe78efb72016-06-24 18:35:21 -0400439 struct sde_hw_blk_reg_map *c;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700440 u32 idx;
441
Clarence Ip4c1d9772016-06-26 09:35:38 -0400442 if (_sspp_subblk_offset(ctx, SDE_SSPP_SCALER_QSEED2, &idx) || !cfg ||
443 !test_bit(SDE_SSPP_SCALER_QSEED2, &ctx->cap->features))
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700444 return;
445
Clarence Ipe78efb72016-06-24 18:35:21 -0400446 c = &ctx->hw;
447
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700448 SDE_REG_WRITE(c, VIG_0_QSEED2_SHARP + idx, cfg->strength);
449 SDE_REG_WRITE(c, VIG_0_QSEED2_SHARP + idx + 0x4, cfg->edge_thr);
450 SDE_REG_WRITE(c, VIG_0_QSEED2_SHARP + idx + 0x8, cfg->smooth_thr);
451 SDE_REG_WRITE(c, VIG_0_QSEED2_SHARP + idx + 0xC, cfg->noise_thr);
452}
453
Clarence Ipcb410d42016-06-26 22:52:33 -0400454static void sde_hw_sspp_setup_solidfill(struct sde_hw_pipe *ctx, u32 color)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700455{
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700456 u32 idx;
457
458 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
459 return;
460
Clarence Ipcb410d42016-06-26 22:52:33 -0400461 SDE_REG_WRITE(&ctx->hw, SSPP_SRC_CONSTANT_COLOR + idx, color);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700462}
463
464static void sde_hw_sspp_setup_histogram_v1(struct sde_hw_pipe *ctx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400465 void *cfg)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700466{
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700467}
468
469static void sde_hw_sspp_setup_memcolor(struct sde_hw_pipe *ctx,
470 u32 memcolortype, u8 en)
471{
472}
473
474static void sde_hw_sspp_setup_igc(struct sde_hw_pipe *ctx)
475{
476}
477
478void sde_sspp_setup_pa(struct sde_hw_pipe *c)
479{
480}
481
Alan Kwong1a00e4d2016-07-18 09:42:30 -0400482static void sde_hw_sspp_setup_danger_safe_lut(struct sde_hw_pipe *ctx,
483 struct sde_hw_pipe_qos_cfg *cfg)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700484{
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700485 u32 idx;
486
487 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
488 return;
489
Alan Kwong1a00e4d2016-07-18 09:42:30 -0400490 SDE_REG_WRITE(&ctx->hw, SSPP_DANGER_LUT + idx, cfg->danger_lut);
491 SDE_REG_WRITE(&ctx->hw, SSPP_SAFE_LUT + idx, cfg->safe_lut);
492}
493
494static void sde_hw_sspp_setup_creq_lut(struct sde_hw_pipe *ctx,
495 struct sde_hw_pipe_qos_cfg *cfg)
496{
497 u32 idx;
498
499 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
500 return;
501
502 SDE_REG_WRITE(&ctx->hw, SSPP_CREQ_LUT + idx, cfg->creq_lut);
503}
504
505static void sde_hw_sspp_setup_qos_ctrl(struct sde_hw_pipe *ctx,
506 struct sde_hw_pipe_qos_cfg *cfg)
507{
508 u32 idx;
509 u32 qos_ctrl = 0;
510
511 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
512 return;
513
514 if (cfg->vblank_en) {
515 qos_ctrl |= ((cfg->creq_vblank &
516 SSPP_QOS_CTRL_CREQ_VBLANK_MASK) <<
517 SSPP_QOS_CTRL_CREQ_VBLANK_OFF);
518 qos_ctrl |= ((cfg->danger_vblank &
519 SSPP_QOS_CTRL_DANGER_VBLANK_MASK) <<
520 SSPP_QOS_CTRL_DANGER_VBLANK_OFF);
521 qos_ctrl |= SSPP_QOS_CTRL_VBLANK_EN;
522 }
523
524 if (cfg->danger_safe_en)
525 qos_ctrl |= SSPP_QOS_CTRL_DANGER_SAFE_EN;
526
527 SDE_REG_WRITE(&ctx->hw, SSPP_QOS_CTRL + idx, qos_ctrl);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700528}
529
530static void sde_hw_sspp_qseed2_coeff(void *ctx)
531{
532}
533
534static void _setup_layer_ops(struct sde_hw_sspp_ops *ops,
535 unsigned long features)
536{
537 if (test_bit(SDE_SSPP_SRC, &features)) {
Clarence Ip4c1d9772016-06-26 09:35:38 -0400538 ops->setup_format = sde_hw_sspp_setup_format;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700539 ops->setup_rects = sde_hw_sspp_setup_rects;
540 ops->setup_sourceaddress = sde_hw_sspp_setup_sourceaddress;
541 ops->setup_solidfill = sde_hw_sspp_setup_solidfill;
Alan Kwong1a00e4d2016-07-18 09:42:30 -0400542 }
543 if (test_bit(SDE_SSPP_QOS, &features)) {
544 ops->setup_danger_safe_lut = sde_hw_sspp_setup_danger_safe_lut;
545 ops->setup_creq_lut = sde_hw_sspp_setup_creq_lut;
546 ops->setup_qos_ctrl = sde_hw_sspp_setup_qos_ctrl;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700547 }
548 if (test_bit(SDE_SSPP_CSC, &features))
Clarence Ipe78efb72016-06-24 18:35:21 -0400549 ops->setup_csc = sde_hw_sspp_setup_csc;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700550
551 if (test_bit(SDE_SSPP_PA_V1, &features)) {
552 ops->setup_sharpening = sde_hw_sspp_setup_sharpening;
553 ops->setup_pa_memcolor = sde_hw_sspp_setup_memcolor;
554 }
555 if (test_bit(SDE_SSPP_HIST_V1, &features))
556 ops->setup_histogram = sde_hw_sspp_setup_histogram_v1;
557
558 if (test_bit(SDE_SSPP_IGC, &features))
559 ops->setup_igc = sde_hw_sspp_setup_igc;
560}
561
562static struct sde_sspp_cfg *_sspp_offset(enum sde_sspp sspp,
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700563 void __iomem *addr,
Clarence Ipe78efb72016-06-24 18:35:21 -0400564 struct sde_mdss_cfg *catalog,
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700565 struct sde_hw_blk_reg_map *b)
566{
567 int i;
568
Clarence Ipe78efb72016-06-24 18:35:21 -0400569 if ((sspp < SSPP_MAX) && catalog && addr && b) {
570 for (i = 0; i < catalog->sspp_count; i++) {
571 if (sspp == catalog->sspp[i].id) {
572 b->base_off = addr;
573 b->blk_off = catalog->sspp[i].base;
574 b->hwversion = catalog->hwversion;
Clarence Ip4ce59322016-06-26 22:27:51 -0400575 b->log_mask = SDE_DBG_MASK_SSPP;
Clarence Ipe78efb72016-06-24 18:35:21 -0400576 return &catalog->sspp[i];
577 }
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700578 }
579 }
580
581 return ERR_PTR(-ENOMEM);
582}
583
584struct sde_hw_pipe *sde_hw_sspp_init(enum sde_sspp idx,
585 void __iomem *addr,
Clarence Ipe78efb72016-06-24 18:35:21 -0400586 struct sde_mdss_cfg *catalog)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700587{
Clarence Ipe78efb72016-06-24 18:35:21 -0400588 struct sde_hw_pipe *ctx;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700589 struct sde_sspp_cfg *cfg;
590
Clarence Ipe78efb72016-06-24 18:35:21 -0400591 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
592 if (!ctx)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700593 return ERR_PTR(-ENOMEM);
594
Clarence Ipe78efb72016-06-24 18:35:21 -0400595 cfg = _sspp_offset(idx, addr, catalog, &ctx->hw);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700596 if (IS_ERR_OR_NULL(cfg)) {
Clarence Ipe78efb72016-06-24 18:35:21 -0400597 kfree(ctx);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700598 return ERR_PTR(-EINVAL);
599 }
600
601 /* Assign ops */
Clarence Ipe78efb72016-06-24 18:35:21 -0400602 ctx->idx = idx;
603 ctx->cap = cfg;
604 _setup_layer_ops(&ctx->ops, ctx->cap->features);
605 ctx->highest_bank_bit = catalog->mdp[0].highest_bank_bit;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700606
607 /*
608 * Perform any default initialization for the sspp blocks
609 */
Clarence Ipe78efb72016-06-24 18:35:21 -0400610 if (test_bit(SDE_SSPP_SCALER_QSEED2, &cfg->features))
611 sde_hw_sspp_qseed2_coeff(ctx);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700612
Clarence Ipe78efb72016-06-24 18:35:21 -0400613 return ctx;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700614}
615
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400616void sde_hw_sspp_destroy(struct sde_hw_pipe *ctx)
617{
618 kfree(ctx);
619}
620