162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* Copyright (c) 2013 Samsung Electronics Co., Ltd. 362306a36Sopenharmony_ci * http://www.samsung.com/ 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Author: Jacek Anaszewski <j.anaszewski@samsung.com> 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Register interface file for JPEG driver on Exynos4x12. 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci#include <linux/io.h> 1062306a36Sopenharmony_ci#include <linux/delay.h> 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include "jpeg-core.h" 1362306a36Sopenharmony_ci#include "jpeg-hw-exynos4.h" 1462306a36Sopenharmony_ci#include "jpeg-regs.h" 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_civoid exynos4_jpeg_sw_reset(void __iomem *base) 1762306a36Sopenharmony_ci{ 1862306a36Sopenharmony_ci unsigned int reg; 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci reg = readl(base + EXYNOS4_JPEG_CNTL_REG); 2162306a36Sopenharmony_ci writel(reg & ~(EXYNOS4_DEC_MODE | EXYNOS4_ENC_MODE), 2262306a36Sopenharmony_ci base + EXYNOS4_JPEG_CNTL_REG); 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci reg = readl(base + EXYNOS4_JPEG_CNTL_REG); 2562306a36Sopenharmony_ci writel(reg & ~EXYNOS4_SOFT_RESET_HI, base + EXYNOS4_JPEG_CNTL_REG); 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci udelay(100); 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci writel(reg | EXYNOS4_SOFT_RESET_HI, base + EXYNOS4_JPEG_CNTL_REG); 3062306a36Sopenharmony_ci} 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_civoid exynos4_jpeg_set_enc_dec_mode(void __iomem *base, unsigned int mode) 3362306a36Sopenharmony_ci{ 3462306a36Sopenharmony_ci unsigned int reg; 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci reg = readl(base + EXYNOS4_JPEG_CNTL_REG); 3762306a36Sopenharmony_ci /* set exynos4_jpeg mod register */ 3862306a36Sopenharmony_ci if (mode == S5P_JPEG_DECODE) { 3962306a36Sopenharmony_ci writel((reg & EXYNOS4_ENC_DEC_MODE_MASK) | 4062306a36Sopenharmony_ci EXYNOS4_DEC_MODE, 4162306a36Sopenharmony_ci base + EXYNOS4_JPEG_CNTL_REG); 4262306a36Sopenharmony_ci } else if (mode == S5P_JPEG_ENCODE) {/* encode */ 4362306a36Sopenharmony_ci writel((reg & EXYNOS4_ENC_DEC_MODE_MASK) | 4462306a36Sopenharmony_ci EXYNOS4_ENC_MODE, 4562306a36Sopenharmony_ci base + EXYNOS4_JPEG_CNTL_REG); 4662306a36Sopenharmony_ci } else { /* disable both */ 4762306a36Sopenharmony_ci writel(reg & EXYNOS4_ENC_DEC_MODE_MASK, 4862306a36Sopenharmony_ci base + EXYNOS4_JPEG_CNTL_REG); 4962306a36Sopenharmony_ci } 5062306a36Sopenharmony_ci} 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_civoid __exynos4_jpeg_set_img_fmt(void __iomem *base, unsigned int img_fmt, 5362306a36Sopenharmony_ci unsigned int version) 5462306a36Sopenharmony_ci{ 5562306a36Sopenharmony_ci unsigned int reg; 5662306a36Sopenharmony_ci unsigned int exynos4_swap_chroma_cbcr; 5762306a36Sopenharmony_ci unsigned int exynos4_swap_chroma_crcb; 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci if (version == SJPEG_EXYNOS4) { 6062306a36Sopenharmony_ci exynos4_swap_chroma_cbcr = EXYNOS4_SWAP_CHROMA_CBCR; 6162306a36Sopenharmony_ci exynos4_swap_chroma_crcb = EXYNOS4_SWAP_CHROMA_CRCB; 6262306a36Sopenharmony_ci } else { 6362306a36Sopenharmony_ci exynos4_swap_chroma_cbcr = EXYNOS5433_SWAP_CHROMA_CBCR; 6462306a36Sopenharmony_ci exynos4_swap_chroma_crcb = EXYNOS5433_SWAP_CHROMA_CRCB; 6562306a36Sopenharmony_ci } 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci reg = readl(base + EXYNOS4_IMG_FMT_REG) & 6862306a36Sopenharmony_ci EXYNOS4_ENC_IN_FMT_MASK; /* clear except enc format */ 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci switch (img_fmt) { 7162306a36Sopenharmony_ci case V4L2_PIX_FMT_GREY: 7262306a36Sopenharmony_ci reg = reg | EXYNOS4_ENC_GRAY_IMG | EXYNOS4_GRAY_IMG_IP; 7362306a36Sopenharmony_ci break; 7462306a36Sopenharmony_ci case V4L2_PIX_FMT_RGB32: 7562306a36Sopenharmony_ci reg = reg | EXYNOS4_ENC_RGB_IMG | 7662306a36Sopenharmony_ci EXYNOS4_RGB_IP_RGB_32BIT_IMG; 7762306a36Sopenharmony_ci break; 7862306a36Sopenharmony_ci case V4L2_PIX_FMT_RGB565: 7962306a36Sopenharmony_ci reg = reg | EXYNOS4_ENC_RGB_IMG | 8062306a36Sopenharmony_ci EXYNOS4_RGB_IP_RGB_16BIT_IMG; 8162306a36Sopenharmony_ci break; 8262306a36Sopenharmony_ci case V4L2_PIX_FMT_NV24: 8362306a36Sopenharmony_ci reg = reg | EXYNOS4_ENC_YUV_444_IMG | 8462306a36Sopenharmony_ci EXYNOS4_YUV_444_IP_YUV_444_2P_IMG | 8562306a36Sopenharmony_ci exynos4_swap_chroma_cbcr; 8662306a36Sopenharmony_ci break; 8762306a36Sopenharmony_ci case V4L2_PIX_FMT_NV42: 8862306a36Sopenharmony_ci reg = reg | EXYNOS4_ENC_YUV_444_IMG | 8962306a36Sopenharmony_ci EXYNOS4_YUV_444_IP_YUV_444_2P_IMG | 9062306a36Sopenharmony_ci exynos4_swap_chroma_crcb; 9162306a36Sopenharmony_ci break; 9262306a36Sopenharmony_ci case V4L2_PIX_FMT_YUYV: 9362306a36Sopenharmony_ci reg = reg | EXYNOS4_DEC_YUV_422_IMG | 9462306a36Sopenharmony_ci EXYNOS4_YUV_422_IP_YUV_422_1P_IMG | 9562306a36Sopenharmony_ci exynos4_swap_chroma_cbcr; 9662306a36Sopenharmony_ci break; 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci case V4L2_PIX_FMT_YVYU: 9962306a36Sopenharmony_ci reg = reg | EXYNOS4_DEC_YUV_422_IMG | 10062306a36Sopenharmony_ci EXYNOS4_YUV_422_IP_YUV_422_1P_IMG | 10162306a36Sopenharmony_ci exynos4_swap_chroma_crcb; 10262306a36Sopenharmony_ci break; 10362306a36Sopenharmony_ci case V4L2_PIX_FMT_NV16: 10462306a36Sopenharmony_ci reg = reg | EXYNOS4_DEC_YUV_422_IMG | 10562306a36Sopenharmony_ci EXYNOS4_YUV_422_IP_YUV_422_2P_IMG | 10662306a36Sopenharmony_ci exynos4_swap_chroma_cbcr; 10762306a36Sopenharmony_ci break; 10862306a36Sopenharmony_ci case V4L2_PIX_FMT_NV61: 10962306a36Sopenharmony_ci reg = reg | EXYNOS4_DEC_YUV_422_IMG | 11062306a36Sopenharmony_ci EXYNOS4_YUV_422_IP_YUV_422_2P_IMG | 11162306a36Sopenharmony_ci exynos4_swap_chroma_crcb; 11262306a36Sopenharmony_ci break; 11362306a36Sopenharmony_ci case V4L2_PIX_FMT_NV12: 11462306a36Sopenharmony_ci reg = reg | EXYNOS4_DEC_YUV_420_IMG | 11562306a36Sopenharmony_ci EXYNOS4_YUV_420_IP_YUV_420_2P_IMG | 11662306a36Sopenharmony_ci exynos4_swap_chroma_cbcr; 11762306a36Sopenharmony_ci break; 11862306a36Sopenharmony_ci case V4L2_PIX_FMT_NV21: 11962306a36Sopenharmony_ci reg = reg | EXYNOS4_DEC_YUV_420_IMG | 12062306a36Sopenharmony_ci EXYNOS4_YUV_420_IP_YUV_420_2P_IMG | 12162306a36Sopenharmony_ci exynos4_swap_chroma_crcb; 12262306a36Sopenharmony_ci break; 12362306a36Sopenharmony_ci case V4L2_PIX_FMT_YUV420: 12462306a36Sopenharmony_ci reg = reg | EXYNOS4_DEC_YUV_420_IMG | 12562306a36Sopenharmony_ci EXYNOS4_YUV_420_IP_YUV_420_3P_IMG | 12662306a36Sopenharmony_ci exynos4_swap_chroma_cbcr; 12762306a36Sopenharmony_ci break; 12862306a36Sopenharmony_ci default: 12962306a36Sopenharmony_ci break; 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci } 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci writel(reg, base + EXYNOS4_IMG_FMT_REG); 13462306a36Sopenharmony_ci} 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_civoid __exynos4_jpeg_set_enc_out_fmt(void __iomem *base, unsigned int out_fmt, 13762306a36Sopenharmony_ci unsigned int version) 13862306a36Sopenharmony_ci{ 13962306a36Sopenharmony_ci unsigned int reg; 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci reg = readl(base + EXYNOS4_IMG_FMT_REG) & 14262306a36Sopenharmony_ci ~(version == SJPEG_EXYNOS4 ? EXYNOS4_ENC_FMT_MASK : 14362306a36Sopenharmony_ci EXYNOS5433_ENC_FMT_MASK); /* clear enc format */ 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci switch (out_fmt) { 14662306a36Sopenharmony_ci case V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY: 14762306a36Sopenharmony_ci reg = reg | EXYNOS4_ENC_FMT_GRAY; 14862306a36Sopenharmony_ci break; 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci case V4L2_JPEG_CHROMA_SUBSAMPLING_444: 15162306a36Sopenharmony_ci reg = reg | EXYNOS4_ENC_FMT_YUV_444; 15262306a36Sopenharmony_ci break; 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci case V4L2_JPEG_CHROMA_SUBSAMPLING_422: 15562306a36Sopenharmony_ci reg = reg | EXYNOS4_ENC_FMT_YUV_422; 15662306a36Sopenharmony_ci break; 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci case V4L2_JPEG_CHROMA_SUBSAMPLING_420: 15962306a36Sopenharmony_ci reg = reg | EXYNOS4_ENC_FMT_YUV_420; 16062306a36Sopenharmony_ci break; 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci default: 16362306a36Sopenharmony_ci break; 16462306a36Sopenharmony_ci } 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci writel(reg, base + EXYNOS4_IMG_FMT_REG); 16762306a36Sopenharmony_ci} 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_civoid exynos4_jpeg_set_interrupt(void __iomem *base, unsigned int version) 17062306a36Sopenharmony_ci{ 17162306a36Sopenharmony_ci unsigned int reg; 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci if (version == SJPEG_EXYNOS4) { 17462306a36Sopenharmony_ci reg = readl(base + EXYNOS4_INT_EN_REG) & ~EXYNOS4_INT_EN_MASK; 17562306a36Sopenharmony_ci writel(reg | EXYNOS4_INT_EN_ALL, base + EXYNOS4_INT_EN_REG); 17662306a36Sopenharmony_ci } else { 17762306a36Sopenharmony_ci reg = readl(base + EXYNOS4_INT_EN_REG) & 17862306a36Sopenharmony_ci ~EXYNOS5433_INT_EN_MASK; 17962306a36Sopenharmony_ci writel(reg | EXYNOS5433_INT_EN_ALL, base + EXYNOS4_INT_EN_REG); 18062306a36Sopenharmony_ci } 18162306a36Sopenharmony_ci} 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ciunsigned int exynos4_jpeg_get_int_status(void __iomem *base) 18462306a36Sopenharmony_ci{ 18562306a36Sopenharmony_ci return readl(base + EXYNOS4_INT_STATUS_REG); 18662306a36Sopenharmony_ci} 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ciunsigned int exynos4_jpeg_get_fifo_status(void __iomem *base) 18962306a36Sopenharmony_ci{ 19062306a36Sopenharmony_ci return readl(base + EXYNOS4_FIFO_STATUS_REG); 19162306a36Sopenharmony_ci} 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_civoid exynos4_jpeg_set_huf_table_enable(void __iomem *base, int value) 19462306a36Sopenharmony_ci{ 19562306a36Sopenharmony_ci unsigned int reg; 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci reg = readl(base + EXYNOS4_JPEG_CNTL_REG) & ~EXYNOS4_HUF_TBL_EN; 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci if (value == 1) 20062306a36Sopenharmony_ci writel(reg | EXYNOS4_HUF_TBL_EN, 20162306a36Sopenharmony_ci base + EXYNOS4_JPEG_CNTL_REG); 20262306a36Sopenharmony_ci else 20362306a36Sopenharmony_ci writel(reg & ~EXYNOS4_HUF_TBL_EN, 20462306a36Sopenharmony_ci base + EXYNOS4_JPEG_CNTL_REG); 20562306a36Sopenharmony_ci} 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_civoid exynos4_jpeg_set_sys_int_enable(void __iomem *base, int value) 20862306a36Sopenharmony_ci{ 20962306a36Sopenharmony_ci unsigned int reg; 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ci reg = readl(base + EXYNOS4_JPEG_CNTL_REG) & ~(EXYNOS4_SYS_INT_EN); 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_ci if (value == 1) 21462306a36Sopenharmony_ci writel(reg | EXYNOS4_SYS_INT_EN, base + EXYNOS4_JPEG_CNTL_REG); 21562306a36Sopenharmony_ci else 21662306a36Sopenharmony_ci writel(reg & ~EXYNOS4_SYS_INT_EN, base + EXYNOS4_JPEG_CNTL_REG); 21762306a36Sopenharmony_ci} 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_civoid exynos4_jpeg_set_stream_buf_address(void __iomem *base, 22062306a36Sopenharmony_ci unsigned int address) 22162306a36Sopenharmony_ci{ 22262306a36Sopenharmony_ci writel(address, base + EXYNOS4_OUT_MEM_BASE_REG); 22362306a36Sopenharmony_ci} 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_civoid exynos4_jpeg_set_stream_size(void __iomem *base, 22662306a36Sopenharmony_ci unsigned int x_value, unsigned int y_value) 22762306a36Sopenharmony_ci{ 22862306a36Sopenharmony_ci writel(0x0, base + EXYNOS4_JPEG_IMG_SIZE_REG); /* clear */ 22962306a36Sopenharmony_ci writel(EXYNOS4_X_SIZE(x_value) | EXYNOS4_Y_SIZE(y_value), 23062306a36Sopenharmony_ci base + EXYNOS4_JPEG_IMG_SIZE_REG); 23162306a36Sopenharmony_ci} 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_civoid exynos4_jpeg_set_frame_buf_address(void __iomem *base, 23462306a36Sopenharmony_ci struct s5p_jpeg_addr *exynos4_jpeg_addr) 23562306a36Sopenharmony_ci{ 23662306a36Sopenharmony_ci writel(exynos4_jpeg_addr->y, base + EXYNOS4_IMG_BA_PLANE_1_REG); 23762306a36Sopenharmony_ci writel(exynos4_jpeg_addr->cb, base + EXYNOS4_IMG_BA_PLANE_2_REG); 23862306a36Sopenharmony_ci writel(exynos4_jpeg_addr->cr, base + EXYNOS4_IMG_BA_PLANE_3_REG); 23962306a36Sopenharmony_ci} 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_civoid exynos4_jpeg_set_encode_tbl_select(void __iomem *base, 24262306a36Sopenharmony_ci enum exynos4_jpeg_img_quality_level level) 24362306a36Sopenharmony_ci{ 24462306a36Sopenharmony_ci unsigned int reg; 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci reg = EXYNOS4_Q_TBL_COMP1_0 | EXYNOS4_Q_TBL_COMP2_1 | 24762306a36Sopenharmony_ci EXYNOS4_Q_TBL_COMP3_1 | 24862306a36Sopenharmony_ci EXYNOS4_HUFF_TBL_COMP1_AC_0_DC_1 | 24962306a36Sopenharmony_ci EXYNOS4_HUFF_TBL_COMP2_AC_0_DC_0 | 25062306a36Sopenharmony_ci EXYNOS4_HUFF_TBL_COMP3_AC_1_DC_1; 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ci writel(reg, base + EXYNOS4_TBL_SEL_REG); 25362306a36Sopenharmony_ci} 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_civoid exynos4_jpeg_set_dec_components(void __iomem *base, int n) 25662306a36Sopenharmony_ci{ 25762306a36Sopenharmony_ci unsigned int reg; 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ci reg = readl(base + EXYNOS4_TBL_SEL_REG); 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci reg |= EXYNOS4_NF(n); 26262306a36Sopenharmony_ci writel(reg, base + EXYNOS4_TBL_SEL_REG); 26362306a36Sopenharmony_ci} 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_civoid exynos4_jpeg_select_dec_q_tbl(void __iomem *base, char c, char x) 26662306a36Sopenharmony_ci{ 26762306a36Sopenharmony_ci unsigned int reg; 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci reg = readl(base + EXYNOS4_TBL_SEL_REG); 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ci reg |= EXYNOS4_Q_TBL_COMP(c, x); 27262306a36Sopenharmony_ci writel(reg, base + EXYNOS4_TBL_SEL_REG); 27362306a36Sopenharmony_ci} 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_civoid exynos4_jpeg_select_dec_h_tbl(void __iomem *base, char c, char x) 27662306a36Sopenharmony_ci{ 27762306a36Sopenharmony_ci unsigned int reg; 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci reg = readl(base + EXYNOS4_TBL_SEL_REG); 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_ci reg |= EXYNOS4_HUFF_TBL_COMP(c, x); 28262306a36Sopenharmony_ci writel(reg, base + EXYNOS4_TBL_SEL_REG); 28362306a36Sopenharmony_ci} 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_civoid exynos4_jpeg_set_encode_hoff_cnt(void __iomem *base, unsigned int fmt) 28662306a36Sopenharmony_ci{ 28762306a36Sopenharmony_ci if (fmt == V4L2_PIX_FMT_GREY) 28862306a36Sopenharmony_ci writel(0xd2, base + EXYNOS4_HUFF_CNT_REG); 28962306a36Sopenharmony_ci else 29062306a36Sopenharmony_ci writel(0x1a2, base + EXYNOS4_HUFF_CNT_REG); 29162306a36Sopenharmony_ci} 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ciunsigned int exynos4_jpeg_get_stream_size(void __iomem *base) 29462306a36Sopenharmony_ci{ 29562306a36Sopenharmony_ci return readl(base + EXYNOS4_BITSTREAM_SIZE_REG); 29662306a36Sopenharmony_ci} 29762306a36Sopenharmony_ci 29862306a36Sopenharmony_civoid exynos4_jpeg_set_dec_bitstream_size(void __iomem *base, unsigned int size) 29962306a36Sopenharmony_ci{ 30062306a36Sopenharmony_ci writel(size, base + EXYNOS4_BITSTREAM_SIZE_REG); 30162306a36Sopenharmony_ci} 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_civoid exynos4_jpeg_get_frame_size(void __iomem *base, 30462306a36Sopenharmony_ci unsigned int *width, unsigned int *height) 30562306a36Sopenharmony_ci{ 30662306a36Sopenharmony_ci *width = (readl(base + EXYNOS4_DECODE_XY_SIZE_REG) & 30762306a36Sopenharmony_ci EXYNOS4_DECODED_SIZE_MASK); 30862306a36Sopenharmony_ci *height = (readl(base + EXYNOS4_DECODE_XY_SIZE_REG) >> 16) & 30962306a36Sopenharmony_ci EXYNOS4_DECODED_SIZE_MASK; 31062306a36Sopenharmony_ci} 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ciunsigned int exynos4_jpeg_get_frame_fmt(void __iomem *base) 31362306a36Sopenharmony_ci{ 31462306a36Sopenharmony_ci return readl(base + EXYNOS4_DECODE_IMG_FMT_REG) & 31562306a36Sopenharmony_ci EXYNOS4_JPEG_DECODED_IMG_FMT_MASK; 31662306a36Sopenharmony_ci} 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_civoid exynos4_jpeg_set_timer_count(void __iomem *base, unsigned int size) 31962306a36Sopenharmony_ci{ 32062306a36Sopenharmony_ci writel(size, base + EXYNOS4_INT_TIMER_COUNT_REG); 32162306a36Sopenharmony_ci} 322