Linux Audio

Check our new training course

Loading...
v5.9
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * Copyright (c) 2011 - 2012 Samsung Electronics Co., Ltd.
  4 *		http://www.samsung.com
  5 *
  6 * Samsung EXYNOS5 SoC series G-Scaler driver
  7 */
  8
  9#include <linux/io.h>
 10#include <linux/delay.h>
 11
 12#include "gsc-core.h"
 13
 14void gsc_hw_set_sw_reset(struct gsc_dev *dev)
 15{
 16	writel(GSC_SW_RESET_SRESET, dev->regs + GSC_SW_RESET);
 17}
 18
 19int gsc_wait_reset(struct gsc_dev *dev)
 20{
 21	unsigned long end = jiffies + msecs_to_jiffies(50);
 22	u32 cfg;
 23
 24	while (time_before(jiffies, end)) {
 25		cfg = readl(dev->regs + GSC_SW_RESET);
 26		if (!cfg)
 27			return 0;
 28		usleep_range(10, 20);
 29	}
 30
 31	return -EBUSY;
 32}
 33
 34void gsc_hw_set_frm_done_irq_mask(struct gsc_dev *dev, bool mask)
 35{
 36	u32 cfg;
 37
 38	cfg = readl(dev->regs + GSC_IRQ);
 39	if (mask)
 40		cfg |= GSC_IRQ_FRMDONE_MASK;
 41	else
 42		cfg &= ~GSC_IRQ_FRMDONE_MASK;
 43	writel(cfg, dev->regs + GSC_IRQ);
 44}
 45
 46void gsc_hw_set_gsc_irq_enable(struct gsc_dev *dev, bool mask)
 47{
 48	u32 cfg;
 49
 50	cfg = readl(dev->regs + GSC_IRQ);
 51	if (mask)
 52		cfg |= GSC_IRQ_ENABLE;
 53	else
 54		cfg &= ~GSC_IRQ_ENABLE;
 55	writel(cfg, dev->regs + GSC_IRQ);
 56}
 57
 58void gsc_hw_set_input_buf_masking(struct gsc_dev *dev, u32 shift,
 59				bool enable)
 60{
 61	u32 cfg = readl(dev->regs + GSC_IN_BASE_ADDR_Y_MASK);
 62	u32 mask = 1 << shift;
 63
 64	cfg &= ~mask;
 65	cfg |= enable << shift;
 66
 67	writel(cfg, dev->regs + GSC_IN_BASE_ADDR_Y_MASK);
 68	writel(cfg, dev->regs + GSC_IN_BASE_ADDR_CB_MASK);
 69	writel(cfg, dev->regs + GSC_IN_BASE_ADDR_CR_MASK);
 70}
 71
 72void gsc_hw_set_output_buf_masking(struct gsc_dev *dev, u32 shift,
 73				bool enable)
 74{
 75	u32 cfg = readl(dev->regs + GSC_OUT_BASE_ADDR_Y_MASK);
 76	u32 mask = 1 << shift;
 77
 78	cfg &= ~mask;
 79	cfg |= enable << shift;
 80
 81	writel(cfg, dev->regs + GSC_OUT_BASE_ADDR_Y_MASK);
 82	writel(cfg, dev->regs + GSC_OUT_BASE_ADDR_CB_MASK);
 83	writel(cfg, dev->regs + GSC_OUT_BASE_ADDR_CR_MASK);
 84}
 85
 86void gsc_hw_set_input_addr(struct gsc_dev *dev, struct gsc_addr *addr,
 87				int index)
 88{
 89	pr_debug("src_buf[%d]: %pad, cb: %pad, cr: %pad", index,
 90			&addr->y, &addr->cb, &addr->cr);
 91	writel(addr->y, dev->regs + GSC_IN_BASE_ADDR_Y(index));
 92	writel(addr->cb, dev->regs + GSC_IN_BASE_ADDR_CB(index));
 93	writel(addr->cr, dev->regs + GSC_IN_BASE_ADDR_CR(index));
 94
 95}
 96
 97void gsc_hw_set_output_addr(struct gsc_dev *dev,
 98			     struct gsc_addr *addr, int index)
 99{
100	pr_debug("dst_buf[%d]: %pad, cb: %pad, cr: %pad",
101			index, &addr->y, &addr->cb, &addr->cr);
102	writel(addr->y, dev->regs + GSC_OUT_BASE_ADDR_Y(index));
103	writel(addr->cb, dev->regs + GSC_OUT_BASE_ADDR_CB(index));
104	writel(addr->cr, dev->regs + GSC_OUT_BASE_ADDR_CR(index));
105}
106
107void gsc_hw_set_input_path(struct gsc_ctx *ctx)
108{
109	struct gsc_dev *dev = ctx->gsc_dev;
110
111	u32 cfg = readl(dev->regs + GSC_IN_CON);
112	cfg &= ~(GSC_IN_PATH_MASK | GSC_IN_LOCAL_SEL_MASK);
113
114	if (ctx->in_path == GSC_DMA)
115		cfg |= GSC_IN_PATH_MEMORY;
116
117	writel(cfg, dev->regs + GSC_IN_CON);
118}
119
120void gsc_hw_set_in_size(struct gsc_ctx *ctx)
121{
122	struct gsc_dev *dev = ctx->gsc_dev;
123	struct gsc_frame *frame = &ctx->s_frame;
124	u32 cfg;
125
126	/* Set input pixel offset */
127	cfg = GSC_SRCIMG_OFFSET_X(frame->crop.left);
128	cfg |= GSC_SRCIMG_OFFSET_Y(frame->crop.top);
129	writel(cfg, dev->regs + GSC_SRCIMG_OFFSET);
130
131	/* Set input original size */
132	cfg = GSC_SRCIMG_WIDTH(frame->f_width);
133	cfg |= GSC_SRCIMG_HEIGHT(frame->f_height);
134	writel(cfg, dev->regs + GSC_SRCIMG_SIZE);
135
136	/* Set input cropped size */
137	cfg = GSC_CROPPED_WIDTH(frame->crop.width);
138	cfg |= GSC_CROPPED_HEIGHT(frame->crop.height);
139	writel(cfg, dev->regs + GSC_CROPPED_SIZE);
140}
141
142void gsc_hw_set_in_image_rgb(struct gsc_ctx *ctx)
143{
144	struct gsc_dev *dev = ctx->gsc_dev;
145	struct gsc_frame *frame = &ctx->s_frame;
146	u32 cfg;
147
148	cfg = readl(dev->regs + GSC_IN_CON);
149	if (frame->colorspace == V4L2_COLORSPACE_REC709)
150		cfg |= GSC_IN_RGB_HD_WIDE;
151	else
152		cfg |= GSC_IN_RGB_SD_WIDE;
153
154	if (frame->fmt->pixelformat == V4L2_PIX_FMT_RGB565X)
155		cfg |= GSC_IN_RGB565;
156	else if (frame->fmt->pixelformat == V4L2_PIX_FMT_RGB32)
157		cfg |= GSC_IN_XRGB8888;
158
159	writel(cfg, dev->regs + GSC_IN_CON);
160}
161
162void gsc_hw_set_in_image_format(struct gsc_ctx *ctx)
163{
164	struct gsc_dev *dev = ctx->gsc_dev;
165	struct gsc_frame *frame = &ctx->s_frame;
166	u32 i, depth = 0;
167	u32 cfg;
168
169	cfg = readl(dev->regs + GSC_IN_CON);
170	cfg &= ~(GSC_IN_RGB_TYPE_MASK | GSC_IN_YUV422_1P_ORDER_MASK |
171		 GSC_IN_CHROMA_ORDER_MASK | GSC_IN_FORMAT_MASK |
172		 GSC_IN_TILE_TYPE_MASK | GSC_IN_TILE_MODE);
173	writel(cfg, dev->regs + GSC_IN_CON);
174
175	if (is_rgb(frame->fmt->color)) {
176		gsc_hw_set_in_image_rgb(ctx);
177		return;
178	}
179	for (i = 0; i < frame->fmt->num_planes; i++)
180		depth += frame->fmt->depth[i];
181
182	switch (frame->fmt->num_comp) {
183	case 1:
184		cfg |= GSC_IN_YUV422_1P;
185		if (frame->fmt->yorder == GSC_LSB_Y)
186			cfg |= GSC_IN_YUV422_1P_ORDER_LSB_Y;
187		else
188			cfg |= GSC_IN_YUV422_1P_OEDER_LSB_C;
189		if (frame->fmt->corder == GSC_CBCR)
190			cfg |= GSC_IN_CHROMA_ORDER_CBCR;
191		else
192			cfg |= GSC_IN_CHROMA_ORDER_CRCB;
193		break;
194	case 2:
195		if (depth == 12)
196			cfg |= GSC_IN_YUV420_2P;
197		else
198			cfg |= GSC_IN_YUV422_2P;
199		if (frame->fmt->corder == GSC_CBCR)
200			cfg |= GSC_IN_CHROMA_ORDER_CBCR;
201		else
202			cfg |= GSC_IN_CHROMA_ORDER_CRCB;
203		break;
204	case 3:
205		if (depth == 12)
206			cfg |= GSC_IN_YUV420_3P;
207		else
208			cfg |= GSC_IN_YUV422_3P;
209		break;
210	}
211
212	if (is_tiled(frame->fmt))
213		cfg |= GSC_IN_TILE_C_16x8 | GSC_IN_TILE_MODE;
214
215	writel(cfg, dev->regs + GSC_IN_CON);
216}
217
218void gsc_hw_set_output_path(struct gsc_ctx *ctx)
219{
220	struct gsc_dev *dev = ctx->gsc_dev;
221
222	u32 cfg = readl(dev->regs + GSC_OUT_CON);
223	cfg &= ~GSC_OUT_PATH_MASK;
224
225	if (ctx->out_path == GSC_DMA)
226		cfg |= GSC_OUT_PATH_MEMORY;
227	else
228		cfg |= GSC_OUT_PATH_LOCAL;
229
230	writel(cfg, dev->regs + GSC_OUT_CON);
231}
232
233void gsc_hw_set_out_size(struct gsc_ctx *ctx)
234{
235	struct gsc_dev *dev = ctx->gsc_dev;
236	struct gsc_frame *frame = &ctx->d_frame;
237	u32 cfg;
238
239	/* Set output original size */
240	if (ctx->out_path == GSC_DMA) {
241		cfg = GSC_DSTIMG_OFFSET_X(frame->crop.left);
242		cfg |= GSC_DSTIMG_OFFSET_Y(frame->crop.top);
243		writel(cfg, dev->regs + GSC_DSTIMG_OFFSET);
244
245		cfg = GSC_DSTIMG_WIDTH(frame->f_width);
246		cfg |= GSC_DSTIMG_HEIGHT(frame->f_height);
247		writel(cfg, dev->regs + GSC_DSTIMG_SIZE);
248	}
249
250	/* Set output scaled size */
251	if (ctx->gsc_ctrls.rotate->val == 90 ||
252	    ctx->gsc_ctrls.rotate->val == 270) {
253		cfg = GSC_SCALED_WIDTH(frame->crop.height);
254		cfg |= GSC_SCALED_HEIGHT(frame->crop.width);
255	} else {
256		cfg = GSC_SCALED_WIDTH(frame->crop.width);
257		cfg |= GSC_SCALED_HEIGHT(frame->crop.height);
258	}
259	writel(cfg, dev->regs + GSC_SCALED_SIZE);
260}
261
262void gsc_hw_set_out_image_rgb(struct gsc_ctx *ctx)
263{
264	struct gsc_dev *dev = ctx->gsc_dev;
265	struct gsc_frame *frame = &ctx->d_frame;
266	u32 cfg;
267
268	cfg = readl(dev->regs + GSC_OUT_CON);
269	if (frame->colorspace == V4L2_COLORSPACE_REC709)
270		cfg |= GSC_OUT_RGB_HD_WIDE;
271	else
272		cfg |= GSC_OUT_RGB_SD_WIDE;
273
274	if (frame->fmt->pixelformat == V4L2_PIX_FMT_RGB565X)
275		cfg |= GSC_OUT_RGB565;
276	else if (frame->fmt->pixelformat == V4L2_PIX_FMT_RGB32)
277		cfg |= GSC_OUT_XRGB8888;
278
279	writel(cfg, dev->regs + GSC_OUT_CON);
280}
281
282void gsc_hw_set_out_image_format(struct gsc_ctx *ctx)
283{
284	struct gsc_dev *dev = ctx->gsc_dev;
285	struct gsc_frame *frame = &ctx->d_frame;
286	u32 i, depth = 0;
287	u32 cfg;
288
289	cfg = readl(dev->regs + GSC_OUT_CON);
290	cfg &= ~(GSC_OUT_RGB_TYPE_MASK | GSC_OUT_YUV422_1P_ORDER_MASK |
291		 GSC_OUT_CHROMA_ORDER_MASK | GSC_OUT_FORMAT_MASK |
292		 GSC_OUT_TILE_TYPE_MASK | GSC_OUT_TILE_MODE);
293	writel(cfg, dev->regs + GSC_OUT_CON);
294
295	if (is_rgb(frame->fmt->color)) {
296		gsc_hw_set_out_image_rgb(ctx);
297		return;
298	}
299
300	if (ctx->out_path != GSC_DMA) {
301		cfg |= GSC_OUT_YUV444;
302		goto end_set;
303	}
304
305	for (i = 0; i < frame->fmt->num_planes; i++)
306		depth += frame->fmt->depth[i];
307
308	switch (frame->fmt->num_comp) {
309	case 1:
310		cfg |= GSC_OUT_YUV422_1P;
311		if (frame->fmt->yorder == GSC_LSB_Y)
312			cfg |= GSC_OUT_YUV422_1P_ORDER_LSB_Y;
313		else
314			cfg |= GSC_OUT_YUV422_1P_OEDER_LSB_C;
315		if (frame->fmt->corder == GSC_CBCR)
316			cfg |= GSC_OUT_CHROMA_ORDER_CBCR;
317		else
318			cfg |= GSC_OUT_CHROMA_ORDER_CRCB;
319		break;
320	case 2:
321		if (depth == 12)
322			cfg |= GSC_OUT_YUV420_2P;
323		else
324			cfg |= GSC_OUT_YUV422_2P;
325		if (frame->fmt->corder == GSC_CBCR)
326			cfg |= GSC_OUT_CHROMA_ORDER_CBCR;
327		else
328			cfg |= GSC_OUT_CHROMA_ORDER_CRCB;
329		break;
330	case 3:
331		cfg |= GSC_OUT_YUV420_3P;
332		break;
333	}
334
335	if (is_tiled(frame->fmt))
336		cfg |= GSC_OUT_TILE_C_16x8 | GSC_OUT_TILE_MODE;
337
338end_set:
339	writel(cfg, dev->regs + GSC_OUT_CON);
340}
341
342void gsc_hw_set_prescaler(struct gsc_ctx *ctx)
343{
344	struct gsc_dev *dev = ctx->gsc_dev;
345	struct gsc_scaler *sc = &ctx->scaler;
346	u32 cfg;
347
348	cfg = GSC_PRESC_SHFACTOR(sc->pre_shfactor);
349	cfg |= GSC_PRESC_H_RATIO(sc->pre_hratio);
350	cfg |= GSC_PRESC_V_RATIO(sc->pre_vratio);
351	writel(cfg, dev->regs + GSC_PRE_SCALE_RATIO);
352}
353
354void gsc_hw_set_mainscaler(struct gsc_ctx *ctx)
355{
356	struct gsc_dev *dev = ctx->gsc_dev;
357	struct gsc_scaler *sc = &ctx->scaler;
358	u32 cfg;
359
360	cfg = GSC_MAIN_H_RATIO_VALUE(sc->main_hratio);
361	writel(cfg, dev->regs + GSC_MAIN_H_RATIO);
362
363	cfg = GSC_MAIN_V_RATIO_VALUE(sc->main_vratio);
364	writel(cfg, dev->regs + GSC_MAIN_V_RATIO);
365}
366
367void gsc_hw_set_rotation(struct gsc_ctx *ctx)
368{
369	struct gsc_dev *dev = ctx->gsc_dev;
370	u32 cfg;
371
372	cfg = readl(dev->regs + GSC_IN_CON);
373	cfg &= ~GSC_IN_ROT_MASK;
374
375	switch (ctx->gsc_ctrls.rotate->val) {
376	case 270:
377		cfg |= GSC_IN_ROT_270;
378		break;
379	case 180:
380		cfg |= GSC_IN_ROT_180;
381		break;
382	case 90:
383		if (ctx->gsc_ctrls.hflip->val)
384			cfg |= GSC_IN_ROT_90_XFLIP;
385		else if (ctx->gsc_ctrls.vflip->val)
386			cfg |= GSC_IN_ROT_90_YFLIP;
387		else
388			cfg |= GSC_IN_ROT_90;
389		break;
390	case 0:
391		if (ctx->gsc_ctrls.hflip->val)
392			cfg |= GSC_IN_ROT_XFLIP;
393		else if (ctx->gsc_ctrls.vflip->val)
394			cfg |= GSC_IN_ROT_YFLIP;
395	}
396
397	writel(cfg, dev->regs + GSC_IN_CON);
398}
399
400void gsc_hw_set_global_alpha(struct gsc_ctx *ctx)
401{
402	struct gsc_dev *dev = ctx->gsc_dev;
403	struct gsc_frame *frame = &ctx->d_frame;
404	u32 cfg;
405
406	if (!is_rgb(frame->fmt->color)) {
407		pr_debug("Not a RGB format");
408		return;
409	}
410
411	cfg = readl(dev->regs + GSC_OUT_CON);
412	cfg &= ~GSC_OUT_GLOBAL_ALPHA_MASK;
413
414	cfg |= GSC_OUT_GLOBAL_ALPHA(ctx->gsc_ctrls.global_alpha->val);
415	writel(cfg, dev->regs + GSC_OUT_CON);
416}
417
418void gsc_hw_set_sfr_update(struct gsc_ctx *ctx)
419{
420	struct gsc_dev *dev = ctx->gsc_dev;
421	u32 cfg;
422
423	cfg = readl(dev->regs + GSC_ENABLE);
424	cfg |= GSC_ENABLE_SFR_UPDATE;
425	writel(cfg, dev->regs + GSC_ENABLE);
426}
v5.14.15
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * Copyright (c) 2011 - 2012 Samsung Electronics Co., Ltd.
  4 *		http://www.samsung.com
  5 *
  6 * Samsung EXYNOS5 SoC series G-Scaler driver
  7 */
  8
  9#include <linux/io.h>
 10#include <linux/delay.h>
 11
 12#include "gsc-core.h"
 13
 14void gsc_hw_set_sw_reset(struct gsc_dev *dev)
 15{
 16	writel(GSC_SW_RESET_SRESET, dev->regs + GSC_SW_RESET);
 17}
 18
 19int gsc_wait_reset(struct gsc_dev *dev)
 20{
 21	unsigned long end = jiffies + msecs_to_jiffies(50);
 22	u32 cfg;
 23
 24	while (time_before(jiffies, end)) {
 25		cfg = readl(dev->regs + GSC_SW_RESET);
 26		if (!cfg)
 27			return 0;
 28		usleep_range(10, 20);
 29	}
 30
 31	return -EBUSY;
 32}
 33
 34void gsc_hw_set_frm_done_irq_mask(struct gsc_dev *dev, bool mask)
 35{
 36	u32 cfg;
 37
 38	cfg = readl(dev->regs + GSC_IRQ);
 39	if (mask)
 40		cfg |= GSC_IRQ_FRMDONE_MASK;
 41	else
 42		cfg &= ~GSC_IRQ_FRMDONE_MASK;
 43	writel(cfg, dev->regs + GSC_IRQ);
 44}
 45
 46void gsc_hw_set_gsc_irq_enable(struct gsc_dev *dev, bool mask)
 47{
 48	u32 cfg;
 49
 50	cfg = readl(dev->regs + GSC_IRQ);
 51	if (mask)
 52		cfg |= GSC_IRQ_ENABLE;
 53	else
 54		cfg &= ~GSC_IRQ_ENABLE;
 55	writel(cfg, dev->regs + GSC_IRQ);
 56}
 57
 58void gsc_hw_set_input_buf_masking(struct gsc_dev *dev, u32 shift,
 59				bool enable)
 60{
 61	u32 cfg = readl(dev->regs + GSC_IN_BASE_ADDR_Y_MASK);
 62	u32 mask = 1 << shift;
 63
 64	cfg &= ~mask;
 65	cfg |= enable << shift;
 66
 67	writel(cfg, dev->regs + GSC_IN_BASE_ADDR_Y_MASK);
 68	writel(cfg, dev->regs + GSC_IN_BASE_ADDR_CB_MASK);
 69	writel(cfg, dev->regs + GSC_IN_BASE_ADDR_CR_MASK);
 70}
 71
 72void gsc_hw_set_output_buf_masking(struct gsc_dev *dev, u32 shift,
 73				bool enable)
 74{
 75	u32 cfg = readl(dev->regs + GSC_OUT_BASE_ADDR_Y_MASK);
 76	u32 mask = 1 << shift;
 77
 78	cfg &= ~mask;
 79	cfg |= enable << shift;
 80
 81	writel(cfg, dev->regs + GSC_OUT_BASE_ADDR_Y_MASK);
 82	writel(cfg, dev->regs + GSC_OUT_BASE_ADDR_CB_MASK);
 83	writel(cfg, dev->regs + GSC_OUT_BASE_ADDR_CR_MASK);
 84}
 85
 86void gsc_hw_set_input_addr(struct gsc_dev *dev, struct gsc_addr *addr,
 87				int index)
 88{
 89	pr_debug("src_buf[%d]: %pad, cb: %pad, cr: %pad", index,
 90			&addr->y, &addr->cb, &addr->cr);
 91	writel(addr->y, dev->regs + GSC_IN_BASE_ADDR_Y(index));
 92	writel(addr->cb, dev->regs + GSC_IN_BASE_ADDR_CB(index));
 93	writel(addr->cr, dev->regs + GSC_IN_BASE_ADDR_CR(index));
 94
 95}
 96
 97void gsc_hw_set_output_addr(struct gsc_dev *dev,
 98			     struct gsc_addr *addr, int index)
 99{
100	pr_debug("dst_buf[%d]: %pad, cb: %pad, cr: %pad",
101			index, &addr->y, &addr->cb, &addr->cr);
102	writel(addr->y, dev->regs + GSC_OUT_BASE_ADDR_Y(index));
103	writel(addr->cb, dev->regs + GSC_OUT_BASE_ADDR_CB(index));
104	writel(addr->cr, dev->regs + GSC_OUT_BASE_ADDR_CR(index));
105}
106
107void gsc_hw_set_input_path(struct gsc_ctx *ctx)
108{
109	struct gsc_dev *dev = ctx->gsc_dev;
110
111	u32 cfg = readl(dev->regs + GSC_IN_CON);
112	cfg &= ~(GSC_IN_PATH_MASK | GSC_IN_LOCAL_SEL_MASK);
113
114	if (ctx->in_path == GSC_DMA)
115		cfg |= GSC_IN_PATH_MEMORY;
116
117	writel(cfg, dev->regs + GSC_IN_CON);
118}
119
120void gsc_hw_set_in_size(struct gsc_ctx *ctx)
121{
122	struct gsc_dev *dev = ctx->gsc_dev;
123	struct gsc_frame *frame = &ctx->s_frame;
124	u32 cfg;
125
126	/* Set input pixel offset */
127	cfg = GSC_SRCIMG_OFFSET_X(frame->crop.left);
128	cfg |= GSC_SRCIMG_OFFSET_Y(frame->crop.top);
129	writel(cfg, dev->regs + GSC_SRCIMG_OFFSET);
130
131	/* Set input original size */
132	cfg = GSC_SRCIMG_WIDTH(frame->f_width);
133	cfg |= GSC_SRCIMG_HEIGHT(frame->f_height);
134	writel(cfg, dev->regs + GSC_SRCIMG_SIZE);
135
136	/* Set input cropped size */
137	cfg = GSC_CROPPED_WIDTH(frame->crop.width);
138	cfg |= GSC_CROPPED_HEIGHT(frame->crop.height);
139	writel(cfg, dev->regs + GSC_CROPPED_SIZE);
140}
141
142void gsc_hw_set_in_image_rgb(struct gsc_ctx *ctx)
143{
144	struct gsc_dev *dev = ctx->gsc_dev;
145	struct gsc_frame *frame = &ctx->s_frame;
146	u32 cfg;
147
148	cfg = readl(dev->regs + GSC_IN_CON);
149	if (frame->colorspace == V4L2_COLORSPACE_REC709)
150		cfg |= GSC_IN_RGB_HD_WIDE;
151	else
152		cfg |= GSC_IN_RGB_SD_WIDE;
153
154	if (frame->fmt->pixelformat == V4L2_PIX_FMT_RGB565X)
155		cfg |= GSC_IN_RGB565;
156	else if (frame->fmt->pixelformat == V4L2_PIX_FMT_RGB32)
157		cfg |= GSC_IN_XRGB8888;
158
159	writel(cfg, dev->regs + GSC_IN_CON);
160}
161
162void gsc_hw_set_in_image_format(struct gsc_ctx *ctx)
163{
164	struct gsc_dev *dev = ctx->gsc_dev;
165	struct gsc_frame *frame = &ctx->s_frame;
166	u32 i, depth = 0;
167	u32 cfg;
168
169	cfg = readl(dev->regs + GSC_IN_CON);
170	cfg &= ~(GSC_IN_RGB_TYPE_MASK | GSC_IN_YUV422_1P_ORDER_MASK |
171		 GSC_IN_CHROMA_ORDER_MASK | GSC_IN_FORMAT_MASK |
172		 GSC_IN_TILE_TYPE_MASK | GSC_IN_TILE_MODE);
173	writel(cfg, dev->regs + GSC_IN_CON);
174
175	if (is_rgb(frame->fmt->color)) {
176		gsc_hw_set_in_image_rgb(ctx);
177		return;
178	}
179	for (i = 0; i < frame->fmt->num_planes; i++)
180		depth += frame->fmt->depth[i];
181
182	switch (frame->fmt->num_comp) {
183	case 1:
184		cfg |= GSC_IN_YUV422_1P;
185		if (frame->fmt->yorder == GSC_LSB_Y)
186			cfg |= GSC_IN_YUV422_1P_ORDER_LSB_Y;
187		else
188			cfg |= GSC_IN_YUV422_1P_OEDER_LSB_C;
189		if (frame->fmt->corder == GSC_CBCR)
190			cfg |= GSC_IN_CHROMA_ORDER_CBCR;
191		else
192			cfg |= GSC_IN_CHROMA_ORDER_CRCB;
193		break;
194	case 2:
195		if (depth == 12)
196			cfg |= GSC_IN_YUV420_2P;
197		else
198			cfg |= GSC_IN_YUV422_2P;
199		if (frame->fmt->corder == GSC_CBCR)
200			cfg |= GSC_IN_CHROMA_ORDER_CBCR;
201		else
202			cfg |= GSC_IN_CHROMA_ORDER_CRCB;
203		break;
204	case 3:
205		if (depth == 12)
206			cfg |= GSC_IN_YUV420_3P;
207		else
208			cfg |= GSC_IN_YUV422_3P;
209		break;
210	}
211
212	if (is_tiled(frame->fmt))
213		cfg |= GSC_IN_TILE_C_16x8 | GSC_IN_TILE_MODE;
214
215	writel(cfg, dev->regs + GSC_IN_CON);
216}
217
218void gsc_hw_set_output_path(struct gsc_ctx *ctx)
219{
220	struct gsc_dev *dev = ctx->gsc_dev;
221
222	u32 cfg = readl(dev->regs + GSC_OUT_CON);
223	cfg &= ~GSC_OUT_PATH_MASK;
224
225	if (ctx->out_path == GSC_DMA)
226		cfg |= GSC_OUT_PATH_MEMORY;
227	else
228		cfg |= GSC_OUT_PATH_LOCAL;
229
230	writel(cfg, dev->regs + GSC_OUT_CON);
231}
232
233void gsc_hw_set_out_size(struct gsc_ctx *ctx)
234{
235	struct gsc_dev *dev = ctx->gsc_dev;
236	struct gsc_frame *frame = &ctx->d_frame;
237	u32 cfg;
238
239	/* Set output original size */
240	if (ctx->out_path == GSC_DMA) {
241		cfg = GSC_DSTIMG_OFFSET_X(frame->crop.left);
242		cfg |= GSC_DSTIMG_OFFSET_Y(frame->crop.top);
243		writel(cfg, dev->regs + GSC_DSTIMG_OFFSET);
244
245		cfg = GSC_DSTIMG_WIDTH(frame->f_width);
246		cfg |= GSC_DSTIMG_HEIGHT(frame->f_height);
247		writel(cfg, dev->regs + GSC_DSTIMG_SIZE);
248	}
249
250	/* Set output scaled size */
251	if (ctx->gsc_ctrls.rotate->val == 90 ||
252	    ctx->gsc_ctrls.rotate->val == 270) {
253		cfg = GSC_SCALED_WIDTH(frame->crop.height);
254		cfg |= GSC_SCALED_HEIGHT(frame->crop.width);
255	} else {
256		cfg = GSC_SCALED_WIDTH(frame->crop.width);
257		cfg |= GSC_SCALED_HEIGHT(frame->crop.height);
258	}
259	writel(cfg, dev->regs + GSC_SCALED_SIZE);
260}
261
262void gsc_hw_set_out_image_rgb(struct gsc_ctx *ctx)
263{
264	struct gsc_dev *dev = ctx->gsc_dev;
265	struct gsc_frame *frame = &ctx->d_frame;
266	u32 cfg;
267
268	cfg = readl(dev->regs + GSC_OUT_CON);
269	if (frame->colorspace == V4L2_COLORSPACE_REC709)
270		cfg |= GSC_OUT_RGB_HD_WIDE;
271	else
272		cfg |= GSC_OUT_RGB_SD_WIDE;
273
274	if (frame->fmt->pixelformat == V4L2_PIX_FMT_RGB565X)
275		cfg |= GSC_OUT_RGB565;
276	else if (frame->fmt->pixelformat == V4L2_PIX_FMT_RGB32)
277		cfg |= GSC_OUT_XRGB8888;
278
279	writel(cfg, dev->regs + GSC_OUT_CON);
280}
281
282void gsc_hw_set_out_image_format(struct gsc_ctx *ctx)
283{
284	struct gsc_dev *dev = ctx->gsc_dev;
285	struct gsc_frame *frame = &ctx->d_frame;
286	u32 i, depth = 0;
287	u32 cfg;
288
289	cfg = readl(dev->regs + GSC_OUT_CON);
290	cfg &= ~(GSC_OUT_RGB_TYPE_MASK | GSC_OUT_YUV422_1P_ORDER_MASK |
291		 GSC_OUT_CHROMA_ORDER_MASK | GSC_OUT_FORMAT_MASK |
292		 GSC_OUT_TILE_TYPE_MASK | GSC_OUT_TILE_MODE);
293	writel(cfg, dev->regs + GSC_OUT_CON);
294
295	if (is_rgb(frame->fmt->color)) {
296		gsc_hw_set_out_image_rgb(ctx);
297		return;
298	}
299
300	if (ctx->out_path != GSC_DMA) {
301		cfg |= GSC_OUT_YUV444;
302		goto end_set;
303	}
304
305	for (i = 0; i < frame->fmt->num_planes; i++)
306		depth += frame->fmt->depth[i];
307
308	switch (frame->fmt->num_comp) {
309	case 1:
310		cfg |= GSC_OUT_YUV422_1P;
311		if (frame->fmt->yorder == GSC_LSB_Y)
312			cfg |= GSC_OUT_YUV422_1P_ORDER_LSB_Y;
313		else
314			cfg |= GSC_OUT_YUV422_1P_OEDER_LSB_C;
315		if (frame->fmt->corder == GSC_CBCR)
316			cfg |= GSC_OUT_CHROMA_ORDER_CBCR;
317		else
318			cfg |= GSC_OUT_CHROMA_ORDER_CRCB;
319		break;
320	case 2:
321		if (depth == 12)
322			cfg |= GSC_OUT_YUV420_2P;
323		else
324			cfg |= GSC_OUT_YUV422_2P;
325		if (frame->fmt->corder == GSC_CBCR)
326			cfg |= GSC_OUT_CHROMA_ORDER_CBCR;
327		else
328			cfg |= GSC_OUT_CHROMA_ORDER_CRCB;
329		break;
330	case 3:
331		cfg |= GSC_OUT_YUV420_3P;
332		break;
333	}
334
335	if (is_tiled(frame->fmt))
336		cfg |= GSC_OUT_TILE_C_16x8 | GSC_OUT_TILE_MODE;
337
338end_set:
339	writel(cfg, dev->regs + GSC_OUT_CON);
340}
341
342void gsc_hw_set_prescaler(struct gsc_ctx *ctx)
343{
344	struct gsc_dev *dev = ctx->gsc_dev;
345	struct gsc_scaler *sc = &ctx->scaler;
346	u32 cfg;
347
348	cfg = GSC_PRESC_SHFACTOR(sc->pre_shfactor);
349	cfg |= GSC_PRESC_H_RATIO(sc->pre_hratio);
350	cfg |= GSC_PRESC_V_RATIO(sc->pre_vratio);
351	writel(cfg, dev->regs + GSC_PRE_SCALE_RATIO);
352}
353
354void gsc_hw_set_mainscaler(struct gsc_ctx *ctx)
355{
356	struct gsc_dev *dev = ctx->gsc_dev;
357	struct gsc_scaler *sc = &ctx->scaler;
358	u32 cfg;
359
360	cfg = GSC_MAIN_H_RATIO_VALUE(sc->main_hratio);
361	writel(cfg, dev->regs + GSC_MAIN_H_RATIO);
362
363	cfg = GSC_MAIN_V_RATIO_VALUE(sc->main_vratio);
364	writel(cfg, dev->regs + GSC_MAIN_V_RATIO);
365}
366
367void gsc_hw_set_rotation(struct gsc_ctx *ctx)
368{
369	struct gsc_dev *dev = ctx->gsc_dev;
370	u32 cfg;
371
372	cfg = readl(dev->regs + GSC_IN_CON);
373	cfg &= ~GSC_IN_ROT_MASK;
374
375	switch (ctx->gsc_ctrls.rotate->val) {
376	case 270:
377		cfg |= GSC_IN_ROT_270;
378		break;
379	case 180:
380		cfg |= GSC_IN_ROT_180;
381		break;
382	case 90:
383		if (ctx->gsc_ctrls.hflip->val)
384			cfg |= GSC_IN_ROT_90_XFLIP;
385		else if (ctx->gsc_ctrls.vflip->val)
386			cfg |= GSC_IN_ROT_90_YFLIP;
387		else
388			cfg |= GSC_IN_ROT_90;
389		break;
390	case 0:
391		if (ctx->gsc_ctrls.hflip->val)
392			cfg |= GSC_IN_ROT_XFLIP;
393		else if (ctx->gsc_ctrls.vflip->val)
394			cfg |= GSC_IN_ROT_YFLIP;
395	}
396
397	writel(cfg, dev->regs + GSC_IN_CON);
398}
399
400void gsc_hw_set_global_alpha(struct gsc_ctx *ctx)
401{
402	struct gsc_dev *dev = ctx->gsc_dev;
403	struct gsc_frame *frame = &ctx->d_frame;
404	u32 cfg;
405
406	if (!is_rgb(frame->fmt->color)) {
407		pr_debug("Not a RGB format");
408		return;
409	}
410
411	cfg = readl(dev->regs + GSC_OUT_CON);
412	cfg &= ~GSC_OUT_GLOBAL_ALPHA_MASK;
413
414	cfg |= GSC_OUT_GLOBAL_ALPHA(ctx->gsc_ctrls.global_alpha->val);
415	writel(cfg, dev->regs + GSC_OUT_CON);
416}
417
418void gsc_hw_set_sfr_update(struct gsc_ctx *ctx)
419{
420	struct gsc_dev *dev = ctx->gsc_dev;
421	u32 cfg;
422
423	cfg = readl(dev->regs + GSC_ENABLE);
424	cfg |= GSC_ENABLE_SFR_UPDATE;
425	writel(cfg, dev->regs + GSC_ENABLE);
426}