18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (c) 2011 - 2012 Samsung Electronics Co., Ltd. 48c2ecf20Sopenharmony_ci * http://www.samsung.com 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Samsung EXYNOS5 SoC series G-Scaler driver 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <linux/io.h> 108c2ecf20Sopenharmony_ci#include <linux/delay.h> 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#include "gsc-core.h" 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_civoid gsc_hw_set_sw_reset(struct gsc_dev *dev) 158c2ecf20Sopenharmony_ci{ 168c2ecf20Sopenharmony_ci writel(GSC_SW_RESET_SRESET, dev->regs + GSC_SW_RESET); 178c2ecf20Sopenharmony_ci} 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ciint gsc_wait_reset(struct gsc_dev *dev) 208c2ecf20Sopenharmony_ci{ 218c2ecf20Sopenharmony_ci unsigned long end = jiffies + msecs_to_jiffies(50); 228c2ecf20Sopenharmony_ci u32 cfg; 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci while (time_before(jiffies, end)) { 258c2ecf20Sopenharmony_ci cfg = readl(dev->regs + GSC_SW_RESET); 268c2ecf20Sopenharmony_ci if (!cfg) 278c2ecf20Sopenharmony_ci return 0; 288c2ecf20Sopenharmony_ci usleep_range(10, 20); 298c2ecf20Sopenharmony_ci } 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci return -EBUSY; 328c2ecf20Sopenharmony_ci} 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_civoid gsc_hw_set_frm_done_irq_mask(struct gsc_dev *dev, bool mask) 358c2ecf20Sopenharmony_ci{ 368c2ecf20Sopenharmony_ci u32 cfg; 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci cfg = readl(dev->regs + GSC_IRQ); 398c2ecf20Sopenharmony_ci if (mask) 408c2ecf20Sopenharmony_ci cfg |= GSC_IRQ_FRMDONE_MASK; 418c2ecf20Sopenharmony_ci else 428c2ecf20Sopenharmony_ci cfg &= ~GSC_IRQ_FRMDONE_MASK; 438c2ecf20Sopenharmony_ci writel(cfg, dev->regs + GSC_IRQ); 448c2ecf20Sopenharmony_ci} 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_civoid gsc_hw_set_gsc_irq_enable(struct gsc_dev *dev, bool mask) 478c2ecf20Sopenharmony_ci{ 488c2ecf20Sopenharmony_ci u32 cfg; 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci cfg = readl(dev->regs + GSC_IRQ); 518c2ecf20Sopenharmony_ci if (mask) 528c2ecf20Sopenharmony_ci cfg |= GSC_IRQ_ENABLE; 538c2ecf20Sopenharmony_ci else 548c2ecf20Sopenharmony_ci cfg &= ~GSC_IRQ_ENABLE; 558c2ecf20Sopenharmony_ci writel(cfg, dev->regs + GSC_IRQ); 568c2ecf20Sopenharmony_ci} 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_civoid gsc_hw_set_input_buf_masking(struct gsc_dev *dev, u32 shift, 598c2ecf20Sopenharmony_ci bool enable) 608c2ecf20Sopenharmony_ci{ 618c2ecf20Sopenharmony_ci u32 cfg = readl(dev->regs + GSC_IN_BASE_ADDR_Y_MASK); 628c2ecf20Sopenharmony_ci u32 mask = 1 << shift; 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci cfg &= ~mask; 658c2ecf20Sopenharmony_ci cfg |= enable << shift; 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci writel(cfg, dev->regs + GSC_IN_BASE_ADDR_Y_MASK); 688c2ecf20Sopenharmony_ci writel(cfg, dev->regs + GSC_IN_BASE_ADDR_CB_MASK); 698c2ecf20Sopenharmony_ci writel(cfg, dev->regs + GSC_IN_BASE_ADDR_CR_MASK); 708c2ecf20Sopenharmony_ci} 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_civoid gsc_hw_set_output_buf_masking(struct gsc_dev *dev, u32 shift, 738c2ecf20Sopenharmony_ci bool enable) 748c2ecf20Sopenharmony_ci{ 758c2ecf20Sopenharmony_ci u32 cfg = readl(dev->regs + GSC_OUT_BASE_ADDR_Y_MASK); 768c2ecf20Sopenharmony_ci u32 mask = 1 << shift; 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci cfg &= ~mask; 798c2ecf20Sopenharmony_ci cfg |= enable << shift; 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci writel(cfg, dev->regs + GSC_OUT_BASE_ADDR_Y_MASK); 828c2ecf20Sopenharmony_ci writel(cfg, dev->regs + GSC_OUT_BASE_ADDR_CB_MASK); 838c2ecf20Sopenharmony_ci writel(cfg, dev->regs + GSC_OUT_BASE_ADDR_CR_MASK); 848c2ecf20Sopenharmony_ci} 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_civoid gsc_hw_set_input_addr(struct gsc_dev *dev, struct gsc_addr *addr, 878c2ecf20Sopenharmony_ci int index) 888c2ecf20Sopenharmony_ci{ 898c2ecf20Sopenharmony_ci pr_debug("src_buf[%d]: %pad, cb: %pad, cr: %pad", index, 908c2ecf20Sopenharmony_ci &addr->y, &addr->cb, &addr->cr); 918c2ecf20Sopenharmony_ci writel(addr->y, dev->regs + GSC_IN_BASE_ADDR_Y(index)); 928c2ecf20Sopenharmony_ci writel(addr->cb, dev->regs + GSC_IN_BASE_ADDR_CB(index)); 938c2ecf20Sopenharmony_ci writel(addr->cr, dev->regs + GSC_IN_BASE_ADDR_CR(index)); 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci} 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_civoid gsc_hw_set_output_addr(struct gsc_dev *dev, 988c2ecf20Sopenharmony_ci struct gsc_addr *addr, int index) 998c2ecf20Sopenharmony_ci{ 1008c2ecf20Sopenharmony_ci pr_debug("dst_buf[%d]: %pad, cb: %pad, cr: %pad", 1018c2ecf20Sopenharmony_ci index, &addr->y, &addr->cb, &addr->cr); 1028c2ecf20Sopenharmony_ci writel(addr->y, dev->regs + GSC_OUT_BASE_ADDR_Y(index)); 1038c2ecf20Sopenharmony_ci writel(addr->cb, dev->regs + GSC_OUT_BASE_ADDR_CB(index)); 1048c2ecf20Sopenharmony_ci writel(addr->cr, dev->regs + GSC_OUT_BASE_ADDR_CR(index)); 1058c2ecf20Sopenharmony_ci} 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_civoid gsc_hw_set_input_path(struct gsc_ctx *ctx) 1088c2ecf20Sopenharmony_ci{ 1098c2ecf20Sopenharmony_ci struct gsc_dev *dev = ctx->gsc_dev; 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci u32 cfg = readl(dev->regs + GSC_IN_CON); 1128c2ecf20Sopenharmony_ci cfg &= ~(GSC_IN_PATH_MASK | GSC_IN_LOCAL_SEL_MASK); 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci if (ctx->in_path == GSC_DMA) 1158c2ecf20Sopenharmony_ci cfg |= GSC_IN_PATH_MEMORY; 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci writel(cfg, dev->regs + GSC_IN_CON); 1188c2ecf20Sopenharmony_ci} 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_civoid gsc_hw_set_in_size(struct gsc_ctx *ctx) 1218c2ecf20Sopenharmony_ci{ 1228c2ecf20Sopenharmony_ci struct gsc_dev *dev = ctx->gsc_dev; 1238c2ecf20Sopenharmony_ci struct gsc_frame *frame = &ctx->s_frame; 1248c2ecf20Sopenharmony_ci u32 cfg; 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci /* Set input pixel offset */ 1278c2ecf20Sopenharmony_ci cfg = GSC_SRCIMG_OFFSET_X(frame->crop.left); 1288c2ecf20Sopenharmony_ci cfg |= GSC_SRCIMG_OFFSET_Y(frame->crop.top); 1298c2ecf20Sopenharmony_ci writel(cfg, dev->regs + GSC_SRCIMG_OFFSET); 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci /* Set input original size */ 1328c2ecf20Sopenharmony_ci cfg = GSC_SRCIMG_WIDTH(frame->f_width); 1338c2ecf20Sopenharmony_ci cfg |= GSC_SRCIMG_HEIGHT(frame->f_height); 1348c2ecf20Sopenharmony_ci writel(cfg, dev->regs + GSC_SRCIMG_SIZE); 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci /* Set input cropped size */ 1378c2ecf20Sopenharmony_ci cfg = GSC_CROPPED_WIDTH(frame->crop.width); 1388c2ecf20Sopenharmony_ci cfg |= GSC_CROPPED_HEIGHT(frame->crop.height); 1398c2ecf20Sopenharmony_ci writel(cfg, dev->regs + GSC_CROPPED_SIZE); 1408c2ecf20Sopenharmony_ci} 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_civoid gsc_hw_set_in_image_rgb(struct gsc_ctx *ctx) 1438c2ecf20Sopenharmony_ci{ 1448c2ecf20Sopenharmony_ci struct gsc_dev *dev = ctx->gsc_dev; 1458c2ecf20Sopenharmony_ci struct gsc_frame *frame = &ctx->s_frame; 1468c2ecf20Sopenharmony_ci u32 cfg; 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci cfg = readl(dev->regs + GSC_IN_CON); 1498c2ecf20Sopenharmony_ci if (frame->colorspace == V4L2_COLORSPACE_REC709) 1508c2ecf20Sopenharmony_ci cfg |= GSC_IN_RGB_HD_WIDE; 1518c2ecf20Sopenharmony_ci else 1528c2ecf20Sopenharmony_ci cfg |= GSC_IN_RGB_SD_WIDE; 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci if (frame->fmt->pixelformat == V4L2_PIX_FMT_RGB565X) 1558c2ecf20Sopenharmony_ci cfg |= GSC_IN_RGB565; 1568c2ecf20Sopenharmony_ci else if (frame->fmt->pixelformat == V4L2_PIX_FMT_RGB32) 1578c2ecf20Sopenharmony_ci cfg |= GSC_IN_XRGB8888; 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci writel(cfg, dev->regs + GSC_IN_CON); 1608c2ecf20Sopenharmony_ci} 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_civoid gsc_hw_set_in_image_format(struct gsc_ctx *ctx) 1638c2ecf20Sopenharmony_ci{ 1648c2ecf20Sopenharmony_ci struct gsc_dev *dev = ctx->gsc_dev; 1658c2ecf20Sopenharmony_ci struct gsc_frame *frame = &ctx->s_frame; 1668c2ecf20Sopenharmony_ci u32 i, depth = 0; 1678c2ecf20Sopenharmony_ci u32 cfg; 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_ci cfg = readl(dev->regs + GSC_IN_CON); 1708c2ecf20Sopenharmony_ci cfg &= ~(GSC_IN_RGB_TYPE_MASK | GSC_IN_YUV422_1P_ORDER_MASK | 1718c2ecf20Sopenharmony_ci GSC_IN_CHROMA_ORDER_MASK | GSC_IN_FORMAT_MASK | 1728c2ecf20Sopenharmony_ci GSC_IN_TILE_TYPE_MASK | GSC_IN_TILE_MODE); 1738c2ecf20Sopenharmony_ci writel(cfg, dev->regs + GSC_IN_CON); 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_ci if (is_rgb(frame->fmt->color)) { 1768c2ecf20Sopenharmony_ci gsc_hw_set_in_image_rgb(ctx); 1778c2ecf20Sopenharmony_ci return; 1788c2ecf20Sopenharmony_ci } 1798c2ecf20Sopenharmony_ci for (i = 0; i < frame->fmt->num_planes; i++) 1808c2ecf20Sopenharmony_ci depth += frame->fmt->depth[i]; 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ci switch (frame->fmt->num_comp) { 1838c2ecf20Sopenharmony_ci case 1: 1848c2ecf20Sopenharmony_ci cfg |= GSC_IN_YUV422_1P; 1858c2ecf20Sopenharmony_ci if (frame->fmt->yorder == GSC_LSB_Y) 1868c2ecf20Sopenharmony_ci cfg |= GSC_IN_YUV422_1P_ORDER_LSB_Y; 1878c2ecf20Sopenharmony_ci else 1888c2ecf20Sopenharmony_ci cfg |= GSC_IN_YUV422_1P_OEDER_LSB_C; 1898c2ecf20Sopenharmony_ci if (frame->fmt->corder == GSC_CBCR) 1908c2ecf20Sopenharmony_ci cfg |= GSC_IN_CHROMA_ORDER_CBCR; 1918c2ecf20Sopenharmony_ci else 1928c2ecf20Sopenharmony_ci cfg |= GSC_IN_CHROMA_ORDER_CRCB; 1938c2ecf20Sopenharmony_ci break; 1948c2ecf20Sopenharmony_ci case 2: 1958c2ecf20Sopenharmony_ci if (depth == 12) 1968c2ecf20Sopenharmony_ci cfg |= GSC_IN_YUV420_2P; 1978c2ecf20Sopenharmony_ci else 1988c2ecf20Sopenharmony_ci cfg |= GSC_IN_YUV422_2P; 1998c2ecf20Sopenharmony_ci if (frame->fmt->corder == GSC_CBCR) 2008c2ecf20Sopenharmony_ci cfg |= GSC_IN_CHROMA_ORDER_CBCR; 2018c2ecf20Sopenharmony_ci else 2028c2ecf20Sopenharmony_ci cfg |= GSC_IN_CHROMA_ORDER_CRCB; 2038c2ecf20Sopenharmony_ci break; 2048c2ecf20Sopenharmony_ci case 3: 2058c2ecf20Sopenharmony_ci if (depth == 12) 2068c2ecf20Sopenharmony_ci cfg |= GSC_IN_YUV420_3P; 2078c2ecf20Sopenharmony_ci else 2088c2ecf20Sopenharmony_ci cfg |= GSC_IN_YUV422_3P; 2098c2ecf20Sopenharmony_ci break; 2108c2ecf20Sopenharmony_ci } 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_ci if (is_tiled(frame->fmt)) 2138c2ecf20Sopenharmony_ci cfg |= GSC_IN_TILE_C_16x8 | GSC_IN_TILE_MODE; 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ci writel(cfg, dev->regs + GSC_IN_CON); 2168c2ecf20Sopenharmony_ci} 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_civoid gsc_hw_set_output_path(struct gsc_ctx *ctx) 2198c2ecf20Sopenharmony_ci{ 2208c2ecf20Sopenharmony_ci struct gsc_dev *dev = ctx->gsc_dev; 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci u32 cfg = readl(dev->regs + GSC_OUT_CON); 2238c2ecf20Sopenharmony_ci cfg &= ~GSC_OUT_PATH_MASK; 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci if (ctx->out_path == GSC_DMA) 2268c2ecf20Sopenharmony_ci cfg |= GSC_OUT_PATH_MEMORY; 2278c2ecf20Sopenharmony_ci else 2288c2ecf20Sopenharmony_ci cfg |= GSC_OUT_PATH_LOCAL; 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_ci writel(cfg, dev->regs + GSC_OUT_CON); 2318c2ecf20Sopenharmony_ci} 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_civoid gsc_hw_set_out_size(struct gsc_ctx *ctx) 2348c2ecf20Sopenharmony_ci{ 2358c2ecf20Sopenharmony_ci struct gsc_dev *dev = ctx->gsc_dev; 2368c2ecf20Sopenharmony_ci struct gsc_frame *frame = &ctx->d_frame; 2378c2ecf20Sopenharmony_ci u32 cfg; 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_ci /* Set output original size */ 2408c2ecf20Sopenharmony_ci if (ctx->out_path == GSC_DMA) { 2418c2ecf20Sopenharmony_ci cfg = GSC_DSTIMG_OFFSET_X(frame->crop.left); 2428c2ecf20Sopenharmony_ci cfg |= GSC_DSTIMG_OFFSET_Y(frame->crop.top); 2438c2ecf20Sopenharmony_ci writel(cfg, dev->regs + GSC_DSTIMG_OFFSET); 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci cfg = GSC_DSTIMG_WIDTH(frame->f_width); 2468c2ecf20Sopenharmony_ci cfg |= GSC_DSTIMG_HEIGHT(frame->f_height); 2478c2ecf20Sopenharmony_ci writel(cfg, dev->regs + GSC_DSTIMG_SIZE); 2488c2ecf20Sopenharmony_ci } 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_ci /* Set output scaled size */ 2518c2ecf20Sopenharmony_ci if (ctx->gsc_ctrls.rotate->val == 90 || 2528c2ecf20Sopenharmony_ci ctx->gsc_ctrls.rotate->val == 270) { 2538c2ecf20Sopenharmony_ci cfg = GSC_SCALED_WIDTH(frame->crop.height); 2548c2ecf20Sopenharmony_ci cfg |= GSC_SCALED_HEIGHT(frame->crop.width); 2558c2ecf20Sopenharmony_ci } else { 2568c2ecf20Sopenharmony_ci cfg = GSC_SCALED_WIDTH(frame->crop.width); 2578c2ecf20Sopenharmony_ci cfg |= GSC_SCALED_HEIGHT(frame->crop.height); 2588c2ecf20Sopenharmony_ci } 2598c2ecf20Sopenharmony_ci writel(cfg, dev->regs + GSC_SCALED_SIZE); 2608c2ecf20Sopenharmony_ci} 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_civoid gsc_hw_set_out_image_rgb(struct gsc_ctx *ctx) 2638c2ecf20Sopenharmony_ci{ 2648c2ecf20Sopenharmony_ci struct gsc_dev *dev = ctx->gsc_dev; 2658c2ecf20Sopenharmony_ci struct gsc_frame *frame = &ctx->d_frame; 2668c2ecf20Sopenharmony_ci u32 cfg; 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_ci cfg = readl(dev->regs + GSC_OUT_CON); 2698c2ecf20Sopenharmony_ci if (frame->colorspace == V4L2_COLORSPACE_REC709) 2708c2ecf20Sopenharmony_ci cfg |= GSC_OUT_RGB_HD_WIDE; 2718c2ecf20Sopenharmony_ci else 2728c2ecf20Sopenharmony_ci cfg |= GSC_OUT_RGB_SD_WIDE; 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci if (frame->fmt->pixelformat == V4L2_PIX_FMT_RGB565X) 2758c2ecf20Sopenharmony_ci cfg |= GSC_OUT_RGB565; 2768c2ecf20Sopenharmony_ci else if (frame->fmt->pixelformat == V4L2_PIX_FMT_RGB32) 2778c2ecf20Sopenharmony_ci cfg |= GSC_OUT_XRGB8888; 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ci writel(cfg, dev->regs + GSC_OUT_CON); 2808c2ecf20Sopenharmony_ci} 2818c2ecf20Sopenharmony_ci 2828c2ecf20Sopenharmony_civoid gsc_hw_set_out_image_format(struct gsc_ctx *ctx) 2838c2ecf20Sopenharmony_ci{ 2848c2ecf20Sopenharmony_ci struct gsc_dev *dev = ctx->gsc_dev; 2858c2ecf20Sopenharmony_ci struct gsc_frame *frame = &ctx->d_frame; 2868c2ecf20Sopenharmony_ci u32 i, depth = 0; 2878c2ecf20Sopenharmony_ci u32 cfg; 2888c2ecf20Sopenharmony_ci 2898c2ecf20Sopenharmony_ci cfg = readl(dev->regs + GSC_OUT_CON); 2908c2ecf20Sopenharmony_ci cfg &= ~(GSC_OUT_RGB_TYPE_MASK | GSC_OUT_YUV422_1P_ORDER_MASK | 2918c2ecf20Sopenharmony_ci GSC_OUT_CHROMA_ORDER_MASK | GSC_OUT_FORMAT_MASK | 2928c2ecf20Sopenharmony_ci GSC_OUT_TILE_TYPE_MASK | GSC_OUT_TILE_MODE); 2938c2ecf20Sopenharmony_ci writel(cfg, dev->regs + GSC_OUT_CON); 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_ci if (is_rgb(frame->fmt->color)) { 2968c2ecf20Sopenharmony_ci gsc_hw_set_out_image_rgb(ctx); 2978c2ecf20Sopenharmony_ci return; 2988c2ecf20Sopenharmony_ci } 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_ci if (ctx->out_path != GSC_DMA) { 3018c2ecf20Sopenharmony_ci cfg |= GSC_OUT_YUV444; 3028c2ecf20Sopenharmony_ci goto end_set; 3038c2ecf20Sopenharmony_ci } 3048c2ecf20Sopenharmony_ci 3058c2ecf20Sopenharmony_ci for (i = 0; i < frame->fmt->num_planes; i++) 3068c2ecf20Sopenharmony_ci depth += frame->fmt->depth[i]; 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_ci switch (frame->fmt->num_comp) { 3098c2ecf20Sopenharmony_ci case 1: 3108c2ecf20Sopenharmony_ci cfg |= GSC_OUT_YUV422_1P; 3118c2ecf20Sopenharmony_ci if (frame->fmt->yorder == GSC_LSB_Y) 3128c2ecf20Sopenharmony_ci cfg |= GSC_OUT_YUV422_1P_ORDER_LSB_Y; 3138c2ecf20Sopenharmony_ci else 3148c2ecf20Sopenharmony_ci cfg |= GSC_OUT_YUV422_1P_OEDER_LSB_C; 3158c2ecf20Sopenharmony_ci if (frame->fmt->corder == GSC_CBCR) 3168c2ecf20Sopenharmony_ci cfg |= GSC_OUT_CHROMA_ORDER_CBCR; 3178c2ecf20Sopenharmony_ci else 3188c2ecf20Sopenharmony_ci cfg |= GSC_OUT_CHROMA_ORDER_CRCB; 3198c2ecf20Sopenharmony_ci break; 3208c2ecf20Sopenharmony_ci case 2: 3218c2ecf20Sopenharmony_ci if (depth == 12) 3228c2ecf20Sopenharmony_ci cfg |= GSC_OUT_YUV420_2P; 3238c2ecf20Sopenharmony_ci else 3248c2ecf20Sopenharmony_ci cfg |= GSC_OUT_YUV422_2P; 3258c2ecf20Sopenharmony_ci if (frame->fmt->corder == GSC_CBCR) 3268c2ecf20Sopenharmony_ci cfg |= GSC_OUT_CHROMA_ORDER_CBCR; 3278c2ecf20Sopenharmony_ci else 3288c2ecf20Sopenharmony_ci cfg |= GSC_OUT_CHROMA_ORDER_CRCB; 3298c2ecf20Sopenharmony_ci break; 3308c2ecf20Sopenharmony_ci case 3: 3318c2ecf20Sopenharmony_ci cfg |= GSC_OUT_YUV420_3P; 3328c2ecf20Sopenharmony_ci break; 3338c2ecf20Sopenharmony_ci } 3348c2ecf20Sopenharmony_ci 3358c2ecf20Sopenharmony_ci if (is_tiled(frame->fmt)) 3368c2ecf20Sopenharmony_ci cfg |= GSC_OUT_TILE_C_16x8 | GSC_OUT_TILE_MODE; 3378c2ecf20Sopenharmony_ci 3388c2ecf20Sopenharmony_ciend_set: 3398c2ecf20Sopenharmony_ci writel(cfg, dev->regs + GSC_OUT_CON); 3408c2ecf20Sopenharmony_ci} 3418c2ecf20Sopenharmony_ci 3428c2ecf20Sopenharmony_civoid gsc_hw_set_prescaler(struct gsc_ctx *ctx) 3438c2ecf20Sopenharmony_ci{ 3448c2ecf20Sopenharmony_ci struct gsc_dev *dev = ctx->gsc_dev; 3458c2ecf20Sopenharmony_ci struct gsc_scaler *sc = &ctx->scaler; 3468c2ecf20Sopenharmony_ci u32 cfg; 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_ci cfg = GSC_PRESC_SHFACTOR(sc->pre_shfactor); 3498c2ecf20Sopenharmony_ci cfg |= GSC_PRESC_H_RATIO(sc->pre_hratio); 3508c2ecf20Sopenharmony_ci cfg |= GSC_PRESC_V_RATIO(sc->pre_vratio); 3518c2ecf20Sopenharmony_ci writel(cfg, dev->regs + GSC_PRE_SCALE_RATIO); 3528c2ecf20Sopenharmony_ci} 3538c2ecf20Sopenharmony_ci 3548c2ecf20Sopenharmony_civoid gsc_hw_set_mainscaler(struct gsc_ctx *ctx) 3558c2ecf20Sopenharmony_ci{ 3568c2ecf20Sopenharmony_ci struct gsc_dev *dev = ctx->gsc_dev; 3578c2ecf20Sopenharmony_ci struct gsc_scaler *sc = &ctx->scaler; 3588c2ecf20Sopenharmony_ci u32 cfg; 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_ci cfg = GSC_MAIN_H_RATIO_VALUE(sc->main_hratio); 3618c2ecf20Sopenharmony_ci writel(cfg, dev->regs + GSC_MAIN_H_RATIO); 3628c2ecf20Sopenharmony_ci 3638c2ecf20Sopenharmony_ci cfg = GSC_MAIN_V_RATIO_VALUE(sc->main_vratio); 3648c2ecf20Sopenharmony_ci writel(cfg, dev->regs + GSC_MAIN_V_RATIO); 3658c2ecf20Sopenharmony_ci} 3668c2ecf20Sopenharmony_ci 3678c2ecf20Sopenharmony_civoid gsc_hw_set_rotation(struct gsc_ctx *ctx) 3688c2ecf20Sopenharmony_ci{ 3698c2ecf20Sopenharmony_ci struct gsc_dev *dev = ctx->gsc_dev; 3708c2ecf20Sopenharmony_ci u32 cfg; 3718c2ecf20Sopenharmony_ci 3728c2ecf20Sopenharmony_ci cfg = readl(dev->regs + GSC_IN_CON); 3738c2ecf20Sopenharmony_ci cfg &= ~GSC_IN_ROT_MASK; 3748c2ecf20Sopenharmony_ci 3758c2ecf20Sopenharmony_ci switch (ctx->gsc_ctrls.rotate->val) { 3768c2ecf20Sopenharmony_ci case 270: 3778c2ecf20Sopenharmony_ci cfg |= GSC_IN_ROT_270; 3788c2ecf20Sopenharmony_ci break; 3798c2ecf20Sopenharmony_ci case 180: 3808c2ecf20Sopenharmony_ci cfg |= GSC_IN_ROT_180; 3818c2ecf20Sopenharmony_ci break; 3828c2ecf20Sopenharmony_ci case 90: 3838c2ecf20Sopenharmony_ci if (ctx->gsc_ctrls.hflip->val) 3848c2ecf20Sopenharmony_ci cfg |= GSC_IN_ROT_90_XFLIP; 3858c2ecf20Sopenharmony_ci else if (ctx->gsc_ctrls.vflip->val) 3868c2ecf20Sopenharmony_ci cfg |= GSC_IN_ROT_90_YFLIP; 3878c2ecf20Sopenharmony_ci else 3888c2ecf20Sopenharmony_ci cfg |= GSC_IN_ROT_90; 3898c2ecf20Sopenharmony_ci break; 3908c2ecf20Sopenharmony_ci case 0: 3918c2ecf20Sopenharmony_ci if (ctx->gsc_ctrls.hflip->val) 3928c2ecf20Sopenharmony_ci cfg |= GSC_IN_ROT_XFLIP; 3938c2ecf20Sopenharmony_ci else if (ctx->gsc_ctrls.vflip->val) 3948c2ecf20Sopenharmony_ci cfg |= GSC_IN_ROT_YFLIP; 3958c2ecf20Sopenharmony_ci } 3968c2ecf20Sopenharmony_ci 3978c2ecf20Sopenharmony_ci writel(cfg, dev->regs + GSC_IN_CON); 3988c2ecf20Sopenharmony_ci} 3998c2ecf20Sopenharmony_ci 4008c2ecf20Sopenharmony_civoid gsc_hw_set_global_alpha(struct gsc_ctx *ctx) 4018c2ecf20Sopenharmony_ci{ 4028c2ecf20Sopenharmony_ci struct gsc_dev *dev = ctx->gsc_dev; 4038c2ecf20Sopenharmony_ci struct gsc_frame *frame = &ctx->d_frame; 4048c2ecf20Sopenharmony_ci u32 cfg; 4058c2ecf20Sopenharmony_ci 4068c2ecf20Sopenharmony_ci if (!is_rgb(frame->fmt->color)) { 4078c2ecf20Sopenharmony_ci pr_debug("Not a RGB format"); 4088c2ecf20Sopenharmony_ci return; 4098c2ecf20Sopenharmony_ci } 4108c2ecf20Sopenharmony_ci 4118c2ecf20Sopenharmony_ci cfg = readl(dev->regs + GSC_OUT_CON); 4128c2ecf20Sopenharmony_ci cfg &= ~GSC_OUT_GLOBAL_ALPHA_MASK; 4138c2ecf20Sopenharmony_ci 4148c2ecf20Sopenharmony_ci cfg |= GSC_OUT_GLOBAL_ALPHA(ctx->gsc_ctrls.global_alpha->val); 4158c2ecf20Sopenharmony_ci writel(cfg, dev->regs + GSC_OUT_CON); 4168c2ecf20Sopenharmony_ci} 4178c2ecf20Sopenharmony_ci 4188c2ecf20Sopenharmony_civoid gsc_hw_set_sfr_update(struct gsc_ctx *ctx) 4198c2ecf20Sopenharmony_ci{ 4208c2ecf20Sopenharmony_ci struct gsc_dev *dev = ctx->gsc_dev; 4218c2ecf20Sopenharmony_ci u32 cfg; 4228c2ecf20Sopenharmony_ci 4238c2ecf20Sopenharmony_ci cfg = readl(dev->regs + GSC_ENABLE); 4248c2ecf20Sopenharmony_ci cfg |= GSC_ENABLE_SFR_UPDATE; 4258c2ecf20Sopenharmony_ci writel(cfg, dev->regs + GSC_ENABLE); 4268c2ecf20Sopenharmony_ci} 427