18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* linux/drivers/media/platform/s5p-jpeg/jpeg-hw.h 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Copyright (c) 2011 Samsung Electronics Co., Ltd. 58c2ecf20Sopenharmony_ci * http://www.samsung.com 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Author: Andrzej Pietrasiewicz <andrzejtp2010@gmail.com> 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/io.h> 118c2ecf20Sopenharmony_ci#include <linux/videodev2.h> 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include "jpeg-core.h" 148c2ecf20Sopenharmony_ci#include "jpeg-regs.h" 158c2ecf20Sopenharmony_ci#include "jpeg-hw-s5p.h" 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_civoid s5p_jpeg_reset(void __iomem *regs) 188c2ecf20Sopenharmony_ci{ 198c2ecf20Sopenharmony_ci unsigned long reg; 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci writel(1, regs + S5P_JPG_SW_RESET); 228c2ecf20Sopenharmony_ci reg = readl(regs + S5P_JPG_SW_RESET); 238c2ecf20Sopenharmony_ci /* no other way but polling for when JPEG IP becomes operational */ 248c2ecf20Sopenharmony_ci while (reg != 0) { 258c2ecf20Sopenharmony_ci cpu_relax(); 268c2ecf20Sopenharmony_ci reg = readl(regs + S5P_JPG_SW_RESET); 278c2ecf20Sopenharmony_ci } 288c2ecf20Sopenharmony_ci} 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_civoid s5p_jpeg_poweron(void __iomem *regs) 318c2ecf20Sopenharmony_ci{ 328c2ecf20Sopenharmony_ci writel(S5P_POWER_ON, regs + S5P_JPGCLKCON); 338c2ecf20Sopenharmony_ci} 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_civoid s5p_jpeg_input_raw_mode(void __iomem *regs, unsigned long mode) 368c2ecf20Sopenharmony_ci{ 378c2ecf20Sopenharmony_ci unsigned long reg, m; 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci m = S5P_MOD_SEL_565; 408c2ecf20Sopenharmony_ci if (mode == S5P_JPEG_RAW_IN_565) 418c2ecf20Sopenharmony_ci m = S5P_MOD_SEL_565; 428c2ecf20Sopenharmony_ci else if (mode == S5P_JPEG_RAW_IN_422) 438c2ecf20Sopenharmony_ci m = S5P_MOD_SEL_422; 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci reg = readl(regs + S5P_JPGCMOD); 468c2ecf20Sopenharmony_ci reg &= ~S5P_MOD_SEL_MASK; 478c2ecf20Sopenharmony_ci reg |= m; 488c2ecf20Sopenharmony_ci writel(reg, regs + S5P_JPGCMOD); 498c2ecf20Sopenharmony_ci} 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_civoid s5p_jpeg_proc_mode(void __iomem *regs, unsigned long mode) 528c2ecf20Sopenharmony_ci{ 538c2ecf20Sopenharmony_ci unsigned long reg, m; 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci m = S5P_PROC_MODE_DECOMPR; 568c2ecf20Sopenharmony_ci if (mode == S5P_JPEG_ENCODE) 578c2ecf20Sopenharmony_ci m = S5P_PROC_MODE_COMPR; 588c2ecf20Sopenharmony_ci else 598c2ecf20Sopenharmony_ci m = S5P_PROC_MODE_DECOMPR; 608c2ecf20Sopenharmony_ci reg = readl(regs + S5P_JPGMOD); 618c2ecf20Sopenharmony_ci reg &= ~S5P_PROC_MODE_MASK; 628c2ecf20Sopenharmony_ci reg |= m; 638c2ecf20Sopenharmony_ci writel(reg, regs + S5P_JPGMOD); 648c2ecf20Sopenharmony_ci} 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_civoid s5p_jpeg_subsampling_mode(void __iomem *regs, unsigned int mode) 678c2ecf20Sopenharmony_ci{ 688c2ecf20Sopenharmony_ci unsigned long reg, m; 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci if (mode == V4L2_JPEG_CHROMA_SUBSAMPLING_420) 718c2ecf20Sopenharmony_ci m = S5P_SUBSAMPLING_MODE_420; 728c2ecf20Sopenharmony_ci else 738c2ecf20Sopenharmony_ci m = S5P_SUBSAMPLING_MODE_422; 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci reg = readl(regs + S5P_JPGMOD); 768c2ecf20Sopenharmony_ci reg &= ~S5P_SUBSAMPLING_MODE_MASK; 778c2ecf20Sopenharmony_ci reg |= m; 788c2ecf20Sopenharmony_ci writel(reg, regs + S5P_JPGMOD); 798c2ecf20Sopenharmony_ci} 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ciunsigned int s5p_jpeg_get_subsampling_mode(void __iomem *regs) 828c2ecf20Sopenharmony_ci{ 838c2ecf20Sopenharmony_ci return readl(regs + S5P_JPGMOD) & S5P_SUBSAMPLING_MODE_MASK; 848c2ecf20Sopenharmony_ci} 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_civoid s5p_jpeg_dri(void __iomem *regs, unsigned int dri) 878c2ecf20Sopenharmony_ci{ 888c2ecf20Sopenharmony_ci unsigned long reg; 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci reg = readl(regs + S5P_JPGDRI_U); 918c2ecf20Sopenharmony_ci reg &= ~0xff; 928c2ecf20Sopenharmony_ci reg |= (dri >> 8) & 0xff; 938c2ecf20Sopenharmony_ci writel(reg, regs + S5P_JPGDRI_U); 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci reg = readl(regs + S5P_JPGDRI_L); 968c2ecf20Sopenharmony_ci reg &= ~0xff; 978c2ecf20Sopenharmony_ci reg |= dri & 0xff; 988c2ecf20Sopenharmony_ci writel(reg, regs + S5P_JPGDRI_L); 998c2ecf20Sopenharmony_ci} 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_civoid s5p_jpeg_qtbl(void __iomem *regs, unsigned int t, unsigned int n) 1028c2ecf20Sopenharmony_ci{ 1038c2ecf20Sopenharmony_ci unsigned long reg; 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci reg = readl(regs + S5P_JPG_QTBL); 1068c2ecf20Sopenharmony_ci reg &= ~S5P_QT_NUMt_MASK(t); 1078c2ecf20Sopenharmony_ci reg |= (n << S5P_QT_NUMt_SHIFT(t)) & S5P_QT_NUMt_MASK(t); 1088c2ecf20Sopenharmony_ci writel(reg, regs + S5P_JPG_QTBL); 1098c2ecf20Sopenharmony_ci} 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_civoid s5p_jpeg_htbl_ac(void __iomem *regs, unsigned int t) 1128c2ecf20Sopenharmony_ci{ 1138c2ecf20Sopenharmony_ci unsigned long reg; 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ci reg = readl(regs + S5P_JPG_HTBL); 1168c2ecf20Sopenharmony_ci reg &= ~S5P_HT_NUMt_AC_MASK(t); 1178c2ecf20Sopenharmony_ci /* this driver uses table 0 for all color components */ 1188c2ecf20Sopenharmony_ci reg |= (0 << S5P_HT_NUMt_AC_SHIFT(t)) & S5P_HT_NUMt_AC_MASK(t); 1198c2ecf20Sopenharmony_ci writel(reg, regs + S5P_JPG_HTBL); 1208c2ecf20Sopenharmony_ci} 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_civoid s5p_jpeg_htbl_dc(void __iomem *regs, unsigned int t) 1238c2ecf20Sopenharmony_ci{ 1248c2ecf20Sopenharmony_ci unsigned long reg; 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci reg = readl(regs + S5P_JPG_HTBL); 1278c2ecf20Sopenharmony_ci reg &= ~S5P_HT_NUMt_DC_MASK(t); 1288c2ecf20Sopenharmony_ci /* this driver uses table 0 for all color components */ 1298c2ecf20Sopenharmony_ci reg |= (0 << S5P_HT_NUMt_DC_SHIFT(t)) & S5P_HT_NUMt_DC_MASK(t); 1308c2ecf20Sopenharmony_ci writel(reg, regs + S5P_JPG_HTBL); 1318c2ecf20Sopenharmony_ci} 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_civoid s5p_jpeg_y(void __iomem *regs, unsigned int y) 1348c2ecf20Sopenharmony_ci{ 1358c2ecf20Sopenharmony_ci unsigned long reg; 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci reg = readl(regs + S5P_JPGY_U); 1388c2ecf20Sopenharmony_ci reg &= ~0xff; 1398c2ecf20Sopenharmony_ci reg |= (y >> 8) & 0xff; 1408c2ecf20Sopenharmony_ci writel(reg, regs + S5P_JPGY_U); 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci reg = readl(regs + S5P_JPGY_L); 1438c2ecf20Sopenharmony_ci reg &= ~0xff; 1448c2ecf20Sopenharmony_ci reg |= y & 0xff; 1458c2ecf20Sopenharmony_ci writel(reg, regs + S5P_JPGY_L); 1468c2ecf20Sopenharmony_ci} 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_civoid s5p_jpeg_x(void __iomem *regs, unsigned int x) 1498c2ecf20Sopenharmony_ci{ 1508c2ecf20Sopenharmony_ci unsigned long reg; 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci reg = readl(regs + S5P_JPGX_U); 1538c2ecf20Sopenharmony_ci reg &= ~0xff; 1548c2ecf20Sopenharmony_ci reg |= (x >> 8) & 0xff; 1558c2ecf20Sopenharmony_ci writel(reg, regs + S5P_JPGX_U); 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci reg = readl(regs + S5P_JPGX_L); 1588c2ecf20Sopenharmony_ci reg &= ~0xff; 1598c2ecf20Sopenharmony_ci reg |= x & 0xff; 1608c2ecf20Sopenharmony_ci writel(reg, regs + S5P_JPGX_L); 1618c2ecf20Sopenharmony_ci} 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_civoid s5p_jpeg_rst_int_enable(void __iomem *regs, bool enable) 1648c2ecf20Sopenharmony_ci{ 1658c2ecf20Sopenharmony_ci unsigned long reg; 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci reg = readl(regs + S5P_JPGINTSE); 1688c2ecf20Sopenharmony_ci reg &= ~S5P_RSTm_INT_EN_MASK; 1698c2ecf20Sopenharmony_ci if (enable) 1708c2ecf20Sopenharmony_ci reg |= S5P_RSTm_INT_EN; 1718c2ecf20Sopenharmony_ci writel(reg, regs + S5P_JPGINTSE); 1728c2ecf20Sopenharmony_ci} 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_civoid s5p_jpeg_data_num_int_enable(void __iomem *regs, bool enable) 1758c2ecf20Sopenharmony_ci{ 1768c2ecf20Sopenharmony_ci unsigned long reg; 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_ci reg = readl(regs + S5P_JPGINTSE); 1798c2ecf20Sopenharmony_ci reg &= ~S5P_DATA_NUM_INT_EN_MASK; 1808c2ecf20Sopenharmony_ci if (enable) 1818c2ecf20Sopenharmony_ci reg |= S5P_DATA_NUM_INT_EN; 1828c2ecf20Sopenharmony_ci writel(reg, regs + S5P_JPGINTSE); 1838c2ecf20Sopenharmony_ci} 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_civoid s5p_jpeg_final_mcu_num_int_enable(void __iomem *regs, bool enbl) 1868c2ecf20Sopenharmony_ci{ 1878c2ecf20Sopenharmony_ci unsigned long reg; 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci reg = readl(regs + S5P_JPGINTSE); 1908c2ecf20Sopenharmony_ci reg &= ~S5P_FINAL_MCU_NUM_INT_EN_MASK; 1918c2ecf20Sopenharmony_ci if (enbl) 1928c2ecf20Sopenharmony_ci reg |= S5P_FINAL_MCU_NUM_INT_EN; 1938c2ecf20Sopenharmony_ci writel(reg, regs + S5P_JPGINTSE); 1948c2ecf20Sopenharmony_ci} 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ciint s5p_jpeg_timer_stat(void __iomem *regs) 1978c2ecf20Sopenharmony_ci{ 1988c2ecf20Sopenharmony_ci return (int)((readl(regs + S5P_JPG_TIMER_ST) & S5P_TIMER_INT_STAT_MASK) 1998c2ecf20Sopenharmony_ci >> S5P_TIMER_INT_STAT_SHIFT); 2008c2ecf20Sopenharmony_ci} 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_civoid s5p_jpeg_clear_timer_stat(void __iomem *regs) 2038c2ecf20Sopenharmony_ci{ 2048c2ecf20Sopenharmony_ci unsigned long reg; 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci reg = readl(regs + S5P_JPG_TIMER_SE); 2078c2ecf20Sopenharmony_ci reg &= ~S5P_TIMER_INT_STAT_MASK; 2088c2ecf20Sopenharmony_ci writel(reg, regs + S5P_JPG_TIMER_SE); 2098c2ecf20Sopenharmony_ci} 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_civoid s5p_jpeg_enc_stream_int(void __iomem *regs, unsigned long size) 2128c2ecf20Sopenharmony_ci{ 2138c2ecf20Sopenharmony_ci unsigned long reg; 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ci reg = readl(regs + S5P_JPG_ENC_STREAM_INTSE); 2168c2ecf20Sopenharmony_ci reg &= ~S5P_ENC_STREAM_BOUND_MASK; 2178c2ecf20Sopenharmony_ci reg |= S5P_ENC_STREAM_INT_EN; 2188c2ecf20Sopenharmony_ci reg |= size & S5P_ENC_STREAM_BOUND_MASK; 2198c2ecf20Sopenharmony_ci writel(reg, regs + S5P_JPG_ENC_STREAM_INTSE); 2208c2ecf20Sopenharmony_ci} 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ciint s5p_jpeg_enc_stream_stat(void __iomem *regs) 2238c2ecf20Sopenharmony_ci{ 2248c2ecf20Sopenharmony_ci return (int)(readl(regs + S5P_JPG_ENC_STREAM_INTST) & 2258c2ecf20Sopenharmony_ci S5P_ENC_STREAM_INT_STAT_MASK); 2268c2ecf20Sopenharmony_ci} 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_civoid s5p_jpeg_clear_enc_stream_stat(void __iomem *regs) 2298c2ecf20Sopenharmony_ci{ 2308c2ecf20Sopenharmony_ci unsigned long reg; 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ci reg = readl(regs + S5P_JPG_ENC_STREAM_INTSE); 2338c2ecf20Sopenharmony_ci reg &= ~S5P_ENC_STREAM_INT_MASK; 2348c2ecf20Sopenharmony_ci writel(reg, regs + S5P_JPG_ENC_STREAM_INTSE); 2358c2ecf20Sopenharmony_ci} 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_civoid s5p_jpeg_outform_raw(void __iomem *regs, unsigned long format) 2388c2ecf20Sopenharmony_ci{ 2398c2ecf20Sopenharmony_ci unsigned long reg, f; 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci f = S5P_DEC_OUT_FORMAT_422; 2428c2ecf20Sopenharmony_ci if (format == S5P_JPEG_RAW_OUT_422) 2438c2ecf20Sopenharmony_ci f = S5P_DEC_OUT_FORMAT_422; 2448c2ecf20Sopenharmony_ci else if (format == S5P_JPEG_RAW_OUT_420) 2458c2ecf20Sopenharmony_ci f = S5P_DEC_OUT_FORMAT_420; 2468c2ecf20Sopenharmony_ci reg = readl(regs + S5P_JPG_OUTFORM); 2478c2ecf20Sopenharmony_ci reg &= ~S5P_DEC_OUT_FORMAT_MASK; 2488c2ecf20Sopenharmony_ci reg |= f; 2498c2ecf20Sopenharmony_ci writel(reg, regs + S5P_JPG_OUTFORM); 2508c2ecf20Sopenharmony_ci} 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_civoid s5p_jpeg_jpgadr(void __iomem *regs, unsigned long addr) 2538c2ecf20Sopenharmony_ci{ 2548c2ecf20Sopenharmony_ci writel(addr, regs + S5P_JPG_JPGADR); 2558c2ecf20Sopenharmony_ci} 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_civoid s5p_jpeg_imgadr(void __iomem *regs, unsigned long addr) 2588c2ecf20Sopenharmony_ci{ 2598c2ecf20Sopenharmony_ci writel(addr, regs + S5P_JPG_IMGADR); 2608c2ecf20Sopenharmony_ci} 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_civoid s5p_jpeg_coef(void __iomem *regs, unsigned int i, 2638c2ecf20Sopenharmony_ci unsigned int j, unsigned int coef) 2648c2ecf20Sopenharmony_ci{ 2658c2ecf20Sopenharmony_ci unsigned long reg; 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ci reg = readl(regs + S5P_JPG_COEF(i)); 2688c2ecf20Sopenharmony_ci reg &= ~S5P_COEFn_MASK(j); 2698c2ecf20Sopenharmony_ci reg |= (coef << S5P_COEFn_SHIFT(j)) & S5P_COEFn_MASK(j); 2708c2ecf20Sopenharmony_ci writel(reg, regs + S5P_JPG_COEF(i)); 2718c2ecf20Sopenharmony_ci} 2728c2ecf20Sopenharmony_ci 2738c2ecf20Sopenharmony_civoid s5p_jpeg_start(void __iomem *regs) 2748c2ecf20Sopenharmony_ci{ 2758c2ecf20Sopenharmony_ci writel(1, regs + S5P_JSTART); 2768c2ecf20Sopenharmony_ci} 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_ciint s5p_jpeg_result_stat_ok(void __iomem *regs) 2798c2ecf20Sopenharmony_ci{ 2808c2ecf20Sopenharmony_ci return (int)((readl(regs + S5P_JPGINTST) & S5P_RESULT_STAT_MASK) 2818c2ecf20Sopenharmony_ci >> S5P_RESULT_STAT_SHIFT); 2828c2ecf20Sopenharmony_ci} 2838c2ecf20Sopenharmony_ci 2848c2ecf20Sopenharmony_ciint s5p_jpeg_stream_stat_ok(void __iomem *regs) 2858c2ecf20Sopenharmony_ci{ 2868c2ecf20Sopenharmony_ci return !(int)((readl(regs + S5P_JPGINTST) & S5P_STREAM_STAT_MASK) 2878c2ecf20Sopenharmony_ci >> S5P_STREAM_STAT_SHIFT); 2888c2ecf20Sopenharmony_ci} 2898c2ecf20Sopenharmony_ci 2908c2ecf20Sopenharmony_civoid s5p_jpeg_clear_int(void __iomem *regs) 2918c2ecf20Sopenharmony_ci{ 2928c2ecf20Sopenharmony_ci readl(regs + S5P_JPGINTST); 2938c2ecf20Sopenharmony_ci writel(S5P_INT_RELEASE, regs + S5P_JPGCOM); 2948c2ecf20Sopenharmony_ci readl(regs + S5P_JPGOPR); 2958c2ecf20Sopenharmony_ci} 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_ciunsigned int s5p_jpeg_compressed_size(void __iomem *regs) 2988c2ecf20Sopenharmony_ci{ 2998c2ecf20Sopenharmony_ci unsigned long jpeg_size = 0; 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_ci jpeg_size |= (readl(regs + S5P_JPGCNT_U) & 0xff) << 16; 3028c2ecf20Sopenharmony_ci jpeg_size |= (readl(regs + S5P_JPGCNT_M) & 0xff) << 8; 3038c2ecf20Sopenharmony_ci jpeg_size |= (readl(regs + S5P_JPGCNT_L) & 0xff); 3048c2ecf20Sopenharmony_ci 3058c2ecf20Sopenharmony_ci return (unsigned int)jpeg_size; 3068c2ecf20Sopenharmony_ci} 307