cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

gsc-regs.c (10196B)


      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}