blob: a478a7ca4468d90328576fcd5b96e4fa27969e80 [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"
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;
Gopikrishnaiah Anandane3842f32015-11-05 12:18:41 -0800128 case SDE_SSPP_HSIC:
129 *idx = sblk->hsic.base;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700130 break;
131 case SDE_SSPP_PCC:
132 *idx = sblk->pcc_blk.base;
133 break;
Gopikrishnaiah Anandane3842f32015-11-05 12:18:41 -0800134 case SDE_SSPP_MEMCOLOR:
135 *idx = sblk->memcolor.base;
136 break;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700137 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) &&
Gopikrishnaiah Anandane3842f32015-11-05 12:18:41 -0800151 test_bit(SDE_SSPP_CSC, &ctx->cap->features)) {
Clarence Ipe78efb72016-06-24 18:35:21 -0400152 opmode = SDE_REG_READ(&ctx->hw, SSPP_VIG_OP_MODE + idx);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700153
Clarence Ipe78efb72016-06-24 18:35:21 -0400154 if (en)
155 opmode |= mask;
156 else
157 opmode &= ~mask;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700158
Clarence Ipe78efb72016-06-24 18:35:21 -0400159 SDE_REG_WRITE(&ctx->hw, SSPP_VIG_OP_MODE + idx, opmode);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700160 }
161}
162/**
163 * Setup source pixel format, flip,
164 */
165static void sde_hw_sspp_setup_format(struct sde_hw_pipe *ctx,
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400166 const struct sde_format *fmt, u32 flags)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700167{
Clarence Ipe78efb72016-06-24 18:35:21 -0400168 struct sde_hw_blk_reg_map *c;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700169 u32 chroma_samp, unpack, src_format;
170 u32 secure = 0;
171 u32 opmode = 0;
172 u32 idx;
173
Clarence Ipcb410d42016-06-26 22:52:33 -0400174 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx) || !fmt)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700175 return;
176
Clarence Ipe78efb72016-06-24 18:35:21 -0400177 c = &ctx->hw;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700178 opmode = SDE_REG_READ(c, SSPP_SRC_OP_MODE + idx);
Clarence Ip5e2a9222016-06-26 22:38:24 -0400179 opmode &= ~(MDSS_MDP_OP_FLIP_LR | MDSS_MDP_OP_FLIP_UD |
180 MDSS_MDP_OP_BWC_EN | MDSS_MDP_OP_PE_OVERRIDE);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700181
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700182 if (flags & SDE_SSPP_SECURE_OVERLAY_SESSION)
183 secure = 0xF;
184
185 if (flags & SDE_SSPP_FLIP_LR)
186 opmode |= MDSS_MDP_OP_FLIP_LR;
187 if (flags & SDE_SSPP_FLIP_UD)
188 opmode |= MDSS_MDP_OP_FLIP_UD;
189
190 chroma_samp = fmt->chroma_sample;
191 if (flags & SDE_SSPP_SOURCE_ROTATED_90) {
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400192 if (chroma_samp == SDE_CHROMA_H2V1)
193 chroma_samp = SDE_CHROMA_H1V2;
194 else if (chroma_samp == SDE_CHROMA_H1V2)
195 chroma_samp = SDE_CHROMA_H2V1;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700196 }
197
198 src_format = (chroma_samp << 23) | (fmt->fetch_planes << 19) |
199 (fmt->bits[C3_ALPHA] << 6) | (fmt->bits[C2_R_Cr] << 4) |
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400200 (fmt->bits[C1_B_Cb] << 2) | (fmt->bits[C0_G_Y] << 0);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700201
202 if (flags & SDE_SSPP_ROT_90)
203 src_format |= BIT(11); /* ROT90 */
204
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400205 if (fmt->alpha_enable && fmt->fetch_planes == SDE_PLANE_INTERLEAVED)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700206 src_format |= BIT(8); /* SRCC3_EN */
207
Clarence Ipcb410d42016-06-26 22:52:33 -0400208 if (flags & SDE_SSPP_SOLID_FILL)
209 src_format |= BIT(22);
210
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700211 unpack = (fmt->element[3] << 24) | (fmt->element[2] << 16) |
212 (fmt->element[1] << 8) | (fmt->element[0] << 0);
213 src_format |= ((fmt->unpack_count - 1) << 12) |
214 (fmt->unpack_tight << 17) |
215 (fmt->unpack_align_msb << 18) |
216 ((fmt->bpp - 1) << 9);
217
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400218 if (fmt->fetch_mode != SDE_FETCH_LINEAR) {
Clarence Ipcb410d42016-06-26 22:52:33 -0400219 if (SDE_FORMAT_IS_UBWC(fmt))
220 opmode |= MDSS_MDP_OP_BWC_EN;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700221 src_format |= (fmt->fetch_mode & 3) << 30; /*FRAME_FORMAT */
222 SDE_REG_WRITE(c, SSPP_FETCH_CONFIG,
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400223 SDE_FETCH_CONFIG_RESET_VALUE |
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700224 ctx->highest_bank_bit << 18);
225 }
226
Clarence Ipe78efb72016-06-24 18:35:21 -0400227 opmode |= MDSS_MDP_OP_PE_OVERRIDE;
228
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700229 /* if this is YUV pixel format, enable CSC */
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400230 if (SDE_FORMAT_IS_YUV(fmt))
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700231 src_format |= BIT(15);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700232
Clarence Ipe78efb72016-06-24 18:35:21 -0400233 /* update scaler opmode, if appropriate */
234 _sspp_setup_opmode(ctx,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400235 VIG_OP_CSC_EN | VIG_OP_CSC_SRC_DATAFMT, SDE_FORMAT_IS_YUV(fmt));
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700236
237 SDE_REG_WRITE(c, SSPP_SRC_FORMAT + idx, src_format);
238 SDE_REG_WRITE(c, SSPP_SRC_UNPACK_PATTERN + idx, unpack);
239 SDE_REG_WRITE(c, SSPP_SRC_OP_MODE + idx, opmode);
240 SDE_REG_WRITE(c, SSPP_SRC_ADDR_SW_STATUS + idx, secure);
241
242 /* clear previous UBWC error */
243 SDE_REG_WRITE(c, SSPP_UBWC_ERROR_STATUS + idx, BIT(31));
244}
245
246static void sde_hw_sspp_setup_pe_config(struct sde_hw_pipe *ctx,
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700247 struct sde_hw_pixel_ext *pe_ext)
248{
Clarence Ipe78efb72016-06-24 18:35:21 -0400249 struct sde_hw_blk_reg_map *c;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700250 u8 color;
251 u32 lr_pe[4], tb_pe[4], tot_req_pixels[4];
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400252 const u32 bytemask = 0xff;
253 const u32 shortmask = 0xffff;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700254 u32 idx;
255
Clarence Ipe78efb72016-06-24 18:35:21 -0400256 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx) || !pe_ext)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700257 return;
258
Clarence Ipe78efb72016-06-24 18:35:21 -0400259 c = &ctx->hw;
260
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700261 /* program SW pixel extension override for all pipes*/
Clarence Ipe78efb72016-06-24 18:35:21 -0400262 for (color = 0; color < SDE_MAX_PLANES; color++) {
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700263 /* color 2 has the same set of registers as color 1 */
264 if (color == 2)
265 continue;
266
267 lr_pe[color] = ((pe_ext->right_ftch[color] & bytemask) << 24)|
268 ((pe_ext->right_rpt[color] & bytemask) << 16)|
269 ((pe_ext->left_ftch[color] & bytemask) << 8)|
270 (pe_ext->left_rpt[color] & bytemask);
271
272 tb_pe[color] = ((pe_ext->btm_ftch[color] & bytemask) << 24)|
273 ((pe_ext->btm_rpt[color] & bytemask) << 16)|
274 ((pe_ext->top_ftch[color] & bytemask) << 8)|
275 (pe_ext->top_rpt[color] & bytemask);
276
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400277 tot_req_pixels[color] = (((pe_ext->roi_h[color] +
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700278 pe_ext->num_ext_pxls_top[color] +
279 pe_ext->num_ext_pxls_btm[color]) & shortmask) << 16) |
280 ((pe_ext->roi_w[color] +
281 pe_ext->num_ext_pxls_left[color] +
282 pe_ext->num_ext_pxls_right[color]) & shortmask);
283 }
284
285 /* color 0 */
286 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C0_LR + idx, lr_pe[0]);
287 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C0_TB + idx, tb_pe[0]);
288 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C0_REQ_PIXELS + idx,
289 tot_req_pixels[0]);
290
291 /* color 1 and color 2 */
292 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C1C2_LR + idx, lr_pe[1]);
293 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C1C2_TB + idx, tb_pe[1]);
294 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C1C2_REQ_PIXELS + idx,
295 tot_req_pixels[1]);
296
297 /* color 3 */
298 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C3_LR + idx, lr_pe[3]);
299 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C3_TB + idx, lr_pe[3]);
300 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C3_REQ_PIXELS + idx,
301 tot_req_pixels[3]);
302}
303
Clarence Ipe78efb72016-06-24 18:35:21 -0400304static void _sde_hw_sspp_setup_scaler(struct sde_hw_pipe *ctx,
305 struct sde_hw_pixel_ext *pe)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700306{
Clarence Ipe78efb72016-06-24 18:35:21 -0400307 struct sde_hw_blk_reg_map *c;
308 int config_h = 0x0;
309 int config_v = 0x0;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700310 u32 idx;
311
Clarence Ipe78efb72016-06-24 18:35:21 -0400312 if (_sspp_subblk_offset(ctx, SDE_SSPP_SCALER_QSEED2, &idx) || !pe)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700313 return;
314
Clarence Ipe78efb72016-06-24 18:35:21 -0400315 c = &ctx->hw;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700316
Clarence Ipe78efb72016-06-24 18:35:21 -0400317 /* enable scaler(s) if valid filter set */
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400318 if (pe->horz_filter[SDE_SSPP_COMP_0] < SDE_SCALE_FILTER_MAX)
Clarence Ipe78efb72016-06-24 18:35:21 -0400319 config_h |= pe->horz_filter[SDE_SSPP_COMP_0] << 8;
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400320 if (pe->horz_filter[SDE_SSPP_COMP_1_2] < SDE_SCALE_FILTER_MAX)
Clarence Ipe78efb72016-06-24 18:35:21 -0400321 config_h |= pe->horz_filter[SDE_SSPP_COMP_1_2] << 12;
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400322 if (pe->horz_filter[SDE_SSPP_COMP_3] < SDE_SCALE_FILTER_MAX)
Clarence Ipe78efb72016-06-24 18:35:21 -0400323 config_h |= pe->horz_filter[SDE_SSPP_COMP_3] << 16;
324
325 if (config_h)
326 config_h |= BIT(0);
327
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400328 if (pe->vert_filter[SDE_SSPP_COMP_0] < SDE_SCALE_FILTER_MAX)
Clarence Ipe78efb72016-06-24 18:35:21 -0400329 config_v |= pe->vert_filter[SDE_SSPP_COMP_0] << 10;
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400330 if (pe->vert_filter[SDE_SSPP_COMP_1_2] < SDE_SCALE_FILTER_MAX)
Clarence Ipe78efb72016-06-24 18:35:21 -0400331 config_v |= pe->vert_filter[SDE_SSPP_COMP_1_2] << 14;
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400332 if (pe->vert_filter[SDE_SSPP_COMP_3] < SDE_SCALE_FILTER_MAX)
Clarence Ipe78efb72016-06-24 18:35:21 -0400333 config_v |= pe->vert_filter[SDE_SSPP_COMP_3] << 18;
334
335 if (config_v)
336 config_v |= BIT(1);
337
338 SDE_REG_WRITE(c, SCALE_CONFIG + idx, config_h | config_v);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700339 SDE_REG_WRITE(c, COMP0_3_INIT_PHASE_X + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400340 pe->init_phase_x[SDE_SSPP_COMP_0]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700341 SDE_REG_WRITE(c, COMP0_3_INIT_PHASE_Y + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400342 pe->init_phase_y[SDE_SSPP_COMP_0]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700343 SDE_REG_WRITE(c, COMP0_3_PHASE_STEP_X + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400344 pe->phase_step_x[SDE_SSPP_COMP_0]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700345 SDE_REG_WRITE(c, COMP0_3_PHASE_STEP_Y + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400346 pe->phase_step_y[SDE_SSPP_COMP_0]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700347
348 SDE_REG_WRITE(c, COMP1_2_INIT_PHASE_X + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400349 pe->init_phase_x[SDE_SSPP_COMP_1_2]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700350 SDE_REG_WRITE(c, COMP1_2_INIT_PHASE_Y + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400351 pe->init_phase_y[SDE_SSPP_COMP_1_2]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700352 SDE_REG_WRITE(c, COMP1_2_PHASE_STEP_X + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400353 pe->phase_step_x[SDE_SSPP_COMP_1_2]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700354 SDE_REG_WRITE(c, COMP1_2_PHASE_STEP_Y + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400355 pe->phase_step_y[SDE_SSPP_COMP_1_2]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700356}
357
358/**
359 * sde_hw_sspp_setup_rects()
360 */
361static void sde_hw_sspp_setup_rects(struct sde_hw_pipe *ctx,
362 struct sde_hw_pipe_cfg *cfg,
363 struct sde_hw_pixel_ext *pe_ext)
364{
Clarence Ipe78efb72016-06-24 18:35:21 -0400365 struct sde_hw_blk_reg_map *c;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700366 u32 src_size, src_xy, dst_size, dst_xy, ystride0, ystride1;
367 u32 decimation = 0;
368 u32 idx;
369
Clarence Ipe78efb72016-06-24 18:35:21 -0400370 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx) || !cfg)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700371 return;
372
Clarence Ipe78efb72016-06-24 18:35:21 -0400373 c = &ctx->hw;
374
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700375 /* program pixel extension override */
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400376 if (pe_ext)
Clarence Ipe78efb72016-06-24 18:35:21 -0400377 sde_hw_sspp_setup_pe_config(ctx, pe_ext);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700378
379 /* src and dest rect programming */
Clarence Ipcb410d42016-06-26 22:52:33 -0400380 src_xy = (cfg->src_rect.y << 16) | (cfg->src_rect.x);
381 src_size = (cfg->src_rect.h << 16) | (cfg->src_rect.w);
382 dst_xy = (cfg->dst_rect.y << 16) | (cfg->dst_rect.x);
383 dst_size = (cfg->dst_rect.h << 16) | (cfg->dst_rect.w);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700384
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400385 ystride0 = (cfg->layout.plane_pitch[0]) |
386 (cfg->layout.plane_pitch[1] << 16);
387 ystride1 = (cfg->layout.plane_pitch[2]) |
388 (cfg->layout.plane_pitch[3] << 16);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700389
Clarence Ipe78efb72016-06-24 18:35:21 -0400390 /* program scaler, phase registers, if pipes supporting scaling */
391 if (ctx->cap->features & SDE_SSPP_SCALER) {
392 /* program decimation */
393 decimation = ((1 << cfg->horz_decimation) - 1) << 8;
394 decimation |= ((1 << cfg->vert_decimation) - 1);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700395
Clarence Ipe78efb72016-06-24 18:35:21 -0400396 _sde_hw_sspp_setup_scaler(ctx, pe_ext);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700397 }
398
Clarence Ipcb410d42016-06-26 22:52:33 -0400399 /* rectangle register programming */
400 SDE_REG_WRITE(c, SSPP_SRC_SIZE + idx, src_size);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700401 SDE_REG_WRITE(c, SSPP_SRC_XY + idx, src_xy);
402 SDE_REG_WRITE(c, SSPP_OUT_SIZE + idx, dst_size);
403 SDE_REG_WRITE(c, SSPP_OUT_XY + idx, dst_xy);
404
405 SDE_REG_WRITE(c, SSPP_SRC_YSTRIDE0 + idx, ystride0);
406 SDE_REG_WRITE(c, SSPP_SRC_YSTRIDE1 + idx, ystride1);
407 SDE_REG_WRITE(c, SSPP_DECIMATION_CONFIG + idx, decimation);
408}
409
410static void sde_hw_sspp_setup_sourceaddress(struct sde_hw_pipe *ctx,
411 struct sde_hw_pipe_cfg *cfg)
412{
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700413 int i;
414 u32 idx;
415
416 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
417 return;
418
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400419 for (i = 0; i < ARRAY_SIZE(cfg->layout.plane_addr); i++)
420 SDE_REG_WRITE(&ctx->hw, SSPP_SRC0_ADDR + idx + i * 0x4,
421 cfg->layout.plane_addr[i]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700422}
423
Clarence Ipe78efb72016-06-24 18:35:21 -0400424static void sde_hw_sspp_setup_csc(struct sde_hw_pipe *ctx,
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700425 struct sde_csc_cfg *data)
426{
Clarence Ipe78efb72016-06-24 18:35:21 -0400427 u32 idx;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700428
Clarence Ipe78efb72016-06-24 18:35:21 -0400429 if (_sspp_subblk_offset(ctx, SDE_SSPP_CSC, &idx) || !data)
430 return;
431
432 sde_hw_csc_setup(&ctx->hw, idx, data);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700433}
434
435static void sde_hw_sspp_setup_sharpening(struct sde_hw_pipe *ctx,
436 struct sde_hw_sharp_cfg *cfg)
437{
Clarence Ipe78efb72016-06-24 18:35:21 -0400438 struct sde_hw_blk_reg_map *c;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700439 u32 idx;
440
Clarence Ip4c1d9772016-06-26 09:35:38 -0400441 if (_sspp_subblk_offset(ctx, SDE_SSPP_SCALER_QSEED2, &idx) || !cfg ||
442 !test_bit(SDE_SSPP_SCALER_QSEED2, &ctx->cap->features))
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700443 return;
444
Clarence Ipe78efb72016-06-24 18:35:21 -0400445 c = &ctx->hw;
446
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700447 SDE_REG_WRITE(c, VIG_0_QSEED2_SHARP + idx, cfg->strength);
448 SDE_REG_WRITE(c, VIG_0_QSEED2_SHARP + idx + 0x4, cfg->edge_thr);
449 SDE_REG_WRITE(c, VIG_0_QSEED2_SHARP + idx + 0x8, cfg->smooth_thr);
450 SDE_REG_WRITE(c, VIG_0_QSEED2_SHARP + idx + 0xC, cfg->noise_thr);
451}
452
Clarence Ipcb410d42016-06-26 22:52:33 -0400453static void sde_hw_sspp_setup_solidfill(struct sde_hw_pipe *ctx, u32 color)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700454{
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700455 u32 idx;
456
457 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
458 return;
459
Clarence Ipcb410d42016-06-26 22:52:33 -0400460 SDE_REG_WRITE(&ctx->hw, SSPP_SRC_CONSTANT_COLOR + idx, color);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700461}
462
Alan Kwong1a00e4d2016-07-18 09:42:30 -0400463static void sde_hw_sspp_setup_danger_safe_lut(struct sde_hw_pipe *ctx,
464 struct sde_hw_pipe_qos_cfg *cfg)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700465{
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700466 u32 idx;
467
468 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
469 return;
470
Alan Kwong1a00e4d2016-07-18 09:42:30 -0400471 SDE_REG_WRITE(&ctx->hw, SSPP_DANGER_LUT + idx, cfg->danger_lut);
472 SDE_REG_WRITE(&ctx->hw, SSPP_SAFE_LUT + idx, cfg->safe_lut);
473}
474
475static void sde_hw_sspp_setup_creq_lut(struct sde_hw_pipe *ctx,
476 struct sde_hw_pipe_qos_cfg *cfg)
477{
478 u32 idx;
479
480 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
481 return;
482
483 SDE_REG_WRITE(&ctx->hw, SSPP_CREQ_LUT + idx, cfg->creq_lut);
484}
485
486static void sde_hw_sspp_setup_qos_ctrl(struct sde_hw_pipe *ctx,
487 struct sde_hw_pipe_qos_cfg *cfg)
488{
489 u32 idx;
490 u32 qos_ctrl = 0;
491
492 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
493 return;
494
495 if (cfg->vblank_en) {
496 qos_ctrl |= ((cfg->creq_vblank &
497 SSPP_QOS_CTRL_CREQ_VBLANK_MASK) <<
498 SSPP_QOS_CTRL_CREQ_VBLANK_OFF);
499 qos_ctrl |= ((cfg->danger_vblank &
500 SSPP_QOS_CTRL_DANGER_VBLANK_MASK) <<
501 SSPP_QOS_CTRL_DANGER_VBLANK_OFF);
502 qos_ctrl |= SSPP_QOS_CTRL_VBLANK_EN;
503 }
504
505 if (cfg->danger_safe_en)
506 qos_ctrl |= SSPP_QOS_CTRL_DANGER_SAFE_EN;
507
508 SDE_REG_WRITE(&ctx->hw, SSPP_QOS_CTRL + idx, qos_ctrl);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700509}
510
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700511static void _setup_layer_ops(struct sde_hw_sspp_ops *ops,
512 unsigned long features)
513{
514 if (test_bit(SDE_SSPP_SRC, &features)) {
Clarence Ip4c1d9772016-06-26 09:35:38 -0400515 ops->setup_format = sde_hw_sspp_setup_format;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700516 ops->setup_rects = sde_hw_sspp_setup_rects;
517 ops->setup_sourceaddress = sde_hw_sspp_setup_sourceaddress;
518 ops->setup_solidfill = sde_hw_sspp_setup_solidfill;
Alan Kwong1a00e4d2016-07-18 09:42:30 -0400519 }
520 if (test_bit(SDE_SSPP_QOS, &features)) {
521 ops->setup_danger_safe_lut = sde_hw_sspp_setup_danger_safe_lut;
522 ops->setup_creq_lut = sde_hw_sspp_setup_creq_lut;
523 ops->setup_qos_ctrl = sde_hw_sspp_setup_qos_ctrl;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700524 }
525 if (test_bit(SDE_SSPP_CSC, &features))
Clarence Ipe78efb72016-06-24 18:35:21 -0400526 ops->setup_csc = sde_hw_sspp_setup_csc;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700527
Gopikrishnaiah Anandane3842f32015-11-05 12:18:41 -0800528 if (test_bit(SDE_SSPP_SCALER_QSEED2, &features))
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700529 ops->setup_sharpening = sde_hw_sspp_setup_sharpening;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700530}
531
532static struct sde_sspp_cfg *_sspp_offset(enum sde_sspp sspp,
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700533 void __iomem *addr,
Clarence Ipe78efb72016-06-24 18:35:21 -0400534 struct sde_mdss_cfg *catalog,
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700535 struct sde_hw_blk_reg_map *b)
536{
537 int i;
538
Clarence Ipe78efb72016-06-24 18:35:21 -0400539 if ((sspp < SSPP_MAX) && catalog && addr && b) {
540 for (i = 0; i < catalog->sspp_count; i++) {
541 if (sspp == catalog->sspp[i].id) {
542 b->base_off = addr;
543 b->blk_off = catalog->sspp[i].base;
544 b->hwversion = catalog->hwversion;
Clarence Ip4ce59322016-06-26 22:27:51 -0400545 b->log_mask = SDE_DBG_MASK_SSPP;
Clarence Ipe78efb72016-06-24 18:35:21 -0400546 return &catalog->sspp[i];
547 }
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700548 }
549 }
550
551 return ERR_PTR(-ENOMEM);
552}
553
554struct sde_hw_pipe *sde_hw_sspp_init(enum sde_sspp idx,
555 void __iomem *addr,
Clarence Ipe78efb72016-06-24 18:35:21 -0400556 struct sde_mdss_cfg *catalog)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700557{
Clarence Ipe78efb72016-06-24 18:35:21 -0400558 struct sde_hw_pipe *ctx;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700559 struct sde_sspp_cfg *cfg;
560
Clarence Ipe78efb72016-06-24 18:35:21 -0400561 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
562 if (!ctx)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700563 return ERR_PTR(-ENOMEM);
564
Clarence Ipe78efb72016-06-24 18:35:21 -0400565 cfg = _sspp_offset(idx, addr, catalog, &ctx->hw);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700566 if (IS_ERR_OR_NULL(cfg)) {
Clarence Ipe78efb72016-06-24 18:35:21 -0400567 kfree(ctx);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700568 return ERR_PTR(-EINVAL);
569 }
570
571 /* Assign ops */
Clarence Ipe78efb72016-06-24 18:35:21 -0400572 ctx->idx = idx;
573 ctx->cap = cfg;
574 _setup_layer_ops(&ctx->ops, ctx->cap->features);
575 ctx->highest_bank_bit = catalog->mdp[0].highest_bank_bit;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700576
Clarence Ipe78efb72016-06-24 18:35:21 -0400577 return ctx;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700578}
579
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400580void sde_hw_sspp_destroy(struct sde_hw_pipe *ctx)
581{
582 kfree(ctx);
583}
584