brintos

brintos / linux-shallow public Read only

0
0
Text · 11.5 KiB · 637a510 Raw
487 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/* linux/drivers/media/platform/exynos3250-jpeg/jpeg-hw.h3 *4 * Copyright (c) 2014 Samsung Electronics Co., Ltd.5 *		http://www.samsung.com6 *7 * Author: Jacek Anaszewski <j.anaszewski@samsung.com>8 */9 10#include <linux/io.h>11#include <linux/videodev2.h>12#include <linux/delay.h>13 14#include "jpeg-core.h"15#include "jpeg-regs.h"16#include "jpeg-hw-exynos3250.h"17 18void exynos3250_jpeg_reset(void __iomem *regs)19{20	u32 reg = 1;21	int count = 1000;22 23	writel(1, regs + EXYNOS3250_SW_RESET);24	/* no other way but polling for when JPEG IP becomes operational */25	while (reg != 0 && --count > 0) {26		udelay(1);27		cpu_relax();28		reg = readl(regs + EXYNOS3250_SW_RESET);29	}30 31	reg = 0;32	count = 1000;33 34	while (reg != 1 && --count > 0) {35		writel(1, regs + EXYNOS3250_JPGDRI);36		udelay(1);37		cpu_relax();38		reg = readl(regs + EXYNOS3250_JPGDRI);39	}40 41	writel(0, regs + EXYNOS3250_JPGDRI);42}43 44void exynos3250_jpeg_poweron(void __iomem *regs)45{46	writel(EXYNOS3250_POWER_ON, regs + EXYNOS3250_JPGCLKCON);47}48 49void exynos3250_jpeg_set_dma_num(void __iomem *regs)50{51	writel(((EXYNOS3250_DMA_MO_COUNT << EXYNOS3250_WDMA_ISSUE_NUM_SHIFT) &52			EXYNOS3250_WDMA_ISSUE_NUM_MASK) |53	       ((EXYNOS3250_DMA_MO_COUNT << EXYNOS3250_RDMA_ISSUE_NUM_SHIFT) &54			EXYNOS3250_RDMA_ISSUE_NUM_MASK) |55	       ((EXYNOS3250_DMA_MO_COUNT << EXYNOS3250_ISSUE_GATHER_NUM_SHIFT) &56			EXYNOS3250_ISSUE_GATHER_NUM_MASK),57		regs + EXYNOS3250_DMA_ISSUE_NUM);58}59 60void exynos3250_jpeg_clk_set(void __iomem *base)61{62	u32 reg;63 64	reg = readl(base + EXYNOS3250_JPGCMOD) & ~EXYNOS3250_HALF_EN_MASK;65 66	writel(reg | EXYNOS3250_HALF_EN, base + EXYNOS3250_JPGCMOD);67}68 69void exynos3250_jpeg_input_raw_fmt(void __iomem *regs, unsigned int fmt)70{71	u32 reg;72 73	reg = readl(regs + EXYNOS3250_JPGCMOD) &74			EXYNOS3250_MODE_Y16_MASK;75 76	switch (fmt) {77	case V4L2_PIX_FMT_RGB32:78		reg |= EXYNOS3250_MODE_SEL_ARGB8888;79		break;80	case V4L2_PIX_FMT_BGR32:81		reg |= EXYNOS3250_MODE_SEL_ARGB8888 | EXYNOS3250_SRC_SWAP_RGB;82		break;83	case V4L2_PIX_FMT_RGB565:84		reg |= EXYNOS3250_MODE_SEL_RGB565;85		break;86	case V4L2_PIX_FMT_RGB565X:87		reg |= EXYNOS3250_MODE_SEL_RGB565 | EXYNOS3250_SRC_SWAP_RGB;88		break;89	case V4L2_PIX_FMT_YUYV:90		reg |= EXYNOS3250_MODE_SEL_422_1P_LUM_CHR;91		break;92	case V4L2_PIX_FMT_YVYU:93		reg |= EXYNOS3250_MODE_SEL_422_1P_LUM_CHR |94			EXYNOS3250_SRC_SWAP_UV;95		break;96	case V4L2_PIX_FMT_UYVY:97		reg |= EXYNOS3250_MODE_SEL_422_1P_CHR_LUM;98		break;99	case V4L2_PIX_FMT_VYUY:100		reg |= EXYNOS3250_MODE_SEL_422_1P_CHR_LUM |101			EXYNOS3250_SRC_SWAP_UV;102		break;103	case V4L2_PIX_FMT_NV12:104		reg |= EXYNOS3250_MODE_SEL_420_2P | EXYNOS3250_SRC_NV12;105		break;106	case V4L2_PIX_FMT_NV21:107		reg |= EXYNOS3250_MODE_SEL_420_2P | EXYNOS3250_SRC_NV21;108		break;109	case V4L2_PIX_FMT_YUV420:110		reg |= EXYNOS3250_MODE_SEL_420_3P;111		break;112	default:113		break;114 115	}116 117	writel(reg, regs + EXYNOS3250_JPGCMOD);118}119 120void exynos3250_jpeg_set_y16(void __iomem *regs, bool y16)121{122	u32 reg;123 124	reg = readl(regs + EXYNOS3250_JPGCMOD);125	if (y16)126		reg |= EXYNOS3250_MODE_Y16;127	else128		reg &= ~EXYNOS3250_MODE_Y16_MASK;129	writel(reg, regs + EXYNOS3250_JPGCMOD);130}131 132void exynos3250_jpeg_proc_mode(void __iomem *regs, unsigned int mode)133{134	u32 reg, m;135 136	if (mode == S5P_JPEG_ENCODE)137		m = EXYNOS3250_PROC_MODE_COMPR;138	else139		m = EXYNOS3250_PROC_MODE_DECOMPR;140	reg = readl(regs + EXYNOS3250_JPGMOD);141	reg &= ~EXYNOS3250_PROC_MODE_MASK;142	reg |= m;143	writel(reg, regs + EXYNOS3250_JPGMOD);144}145 146void exynos3250_jpeg_subsampling_mode(void __iomem *regs, unsigned int mode)147{148	u32 reg, m = 0;149 150	switch (mode) {151	case V4L2_JPEG_CHROMA_SUBSAMPLING_444:152		m = EXYNOS3250_SUBSAMPLING_MODE_444;153		break;154	case V4L2_JPEG_CHROMA_SUBSAMPLING_422:155		m = EXYNOS3250_SUBSAMPLING_MODE_422;156		break;157	case V4L2_JPEG_CHROMA_SUBSAMPLING_420:158		m = EXYNOS3250_SUBSAMPLING_MODE_420;159		break;160	}161 162	reg = readl(regs + EXYNOS3250_JPGMOD);163	reg &= ~EXYNOS3250_SUBSAMPLING_MODE_MASK;164	reg |= m;165	writel(reg, regs + EXYNOS3250_JPGMOD);166}167 168unsigned int exynos3250_jpeg_get_subsampling_mode(void __iomem *regs)169{170	return readl(regs + EXYNOS3250_JPGMOD) &171				EXYNOS3250_SUBSAMPLING_MODE_MASK;172}173 174void exynos3250_jpeg_dri(void __iomem *regs, unsigned int dri)175{176	u32 reg;177 178	reg = dri & EXYNOS3250_JPGDRI_MASK;179	writel(reg, regs + EXYNOS3250_JPGDRI);180}181 182void exynos3250_jpeg_qtbl(void __iomem *regs, unsigned int t, unsigned int n)183{184	unsigned long reg;185 186	reg = readl(regs + EXYNOS3250_QHTBL);187	reg &= ~EXYNOS3250_QT_NUM_MASK(t);188	reg |= (n << EXYNOS3250_QT_NUM_SHIFT(t)) &189					EXYNOS3250_QT_NUM_MASK(t);190	writel(reg, regs + EXYNOS3250_QHTBL);191}192 193void exynos3250_jpeg_htbl_ac(void __iomem *regs, unsigned int t)194{195	unsigned long reg;196 197	reg = readl(regs + EXYNOS3250_QHTBL);198	reg &= ~EXYNOS3250_HT_NUM_AC_MASK(t);199	/* this driver uses table 0 for all color components */200	reg |= (0 << EXYNOS3250_HT_NUM_AC_SHIFT(t)) &201					EXYNOS3250_HT_NUM_AC_MASK(t);202	writel(reg, regs + EXYNOS3250_QHTBL);203}204 205void exynos3250_jpeg_htbl_dc(void __iomem *regs, unsigned int t)206{207	unsigned long reg;208 209	reg = readl(regs + EXYNOS3250_QHTBL);210	reg &= ~EXYNOS3250_HT_NUM_DC_MASK(t);211	/* this driver uses table 0 for all color components */212	reg |= (0 << EXYNOS3250_HT_NUM_DC_SHIFT(t)) &213					EXYNOS3250_HT_NUM_DC_MASK(t);214	writel(reg, regs + EXYNOS3250_QHTBL);215}216 217void exynos3250_jpeg_set_y(void __iomem *regs, unsigned int y)218{219	u32 reg;220 221	reg = y & EXYNOS3250_JPGY_MASK;222	writel(reg, regs + EXYNOS3250_JPGY);223}224 225void exynos3250_jpeg_set_x(void __iomem *regs, unsigned int x)226{227	u32 reg;228 229	reg = x & EXYNOS3250_JPGX_MASK;230	writel(reg, regs + EXYNOS3250_JPGX);231}232 233#if 0	/* Currently unused */234unsigned int exynos3250_jpeg_get_y(void __iomem *regs)235{236	return readl(regs + EXYNOS3250_JPGY);237}238 239unsigned int exynos3250_jpeg_get_x(void __iomem *regs)240{241	return readl(regs + EXYNOS3250_JPGX);242}243#endif244 245void exynos3250_jpeg_interrupts_enable(void __iomem *regs)246{247	u32 reg;248 249	reg = readl(regs + EXYNOS3250_JPGINTSE);250	reg |= (EXYNOS3250_JPEG_DONE_EN |251		EXYNOS3250_WDMA_DONE_EN |252		EXYNOS3250_RDMA_DONE_EN |253		EXYNOS3250_ENC_STREAM_INT_EN |254		EXYNOS3250_CORE_DONE_EN |255		EXYNOS3250_ERR_INT_EN |256		EXYNOS3250_HEAD_INT_EN);257	writel(reg, regs + EXYNOS3250_JPGINTSE);258}259 260void exynos3250_jpeg_enc_stream_bound(void __iomem *regs, unsigned int size)261{262	u32 reg;263 264	reg = size & EXYNOS3250_ENC_STREAM_BOUND_MASK;265	writel(reg, regs + EXYNOS3250_ENC_STREAM_BOUND);266}267 268void exynos3250_jpeg_output_raw_fmt(void __iomem *regs, unsigned int fmt)269{270	u32 reg;271 272	switch (fmt) {273	case V4L2_PIX_FMT_RGB32:274		reg = EXYNOS3250_OUT_FMT_ARGB8888;275		break;276	case V4L2_PIX_FMT_BGR32:277		reg = EXYNOS3250_OUT_FMT_ARGB8888 | EXYNOS3250_OUT_SWAP_RGB;278		break;279	case V4L2_PIX_FMT_RGB565:280		reg = EXYNOS3250_OUT_FMT_RGB565;281		break;282	case V4L2_PIX_FMT_RGB565X:283		reg = EXYNOS3250_OUT_FMT_RGB565 | EXYNOS3250_OUT_SWAP_RGB;284		break;285	case V4L2_PIX_FMT_YUYV:286		reg = EXYNOS3250_OUT_FMT_422_1P_LUM_CHR;287		break;288	case V4L2_PIX_FMT_YVYU:289		reg = EXYNOS3250_OUT_FMT_422_1P_LUM_CHR |290			EXYNOS3250_OUT_SWAP_UV;291		break;292	case V4L2_PIX_FMT_UYVY:293		reg = EXYNOS3250_OUT_FMT_422_1P_CHR_LUM;294		break;295	case V4L2_PIX_FMT_VYUY:296		reg = EXYNOS3250_OUT_FMT_422_1P_CHR_LUM |297			EXYNOS3250_OUT_SWAP_UV;298		break;299	case V4L2_PIX_FMT_NV12:300		reg = EXYNOS3250_OUT_FMT_420_2P | EXYNOS3250_OUT_NV12;301		break;302	case V4L2_PIX_FMT_NV21:303		reg = EXYNOS3250_OUT_FMT_420_2P | EXYNOS3250_OUT_NV21;304		break;305	case V4L2_PIX_FMT_YUV420:306		reg = EXYNOS3250_OUT_FMT_420_3P;307		break;308	default:309		reg = 0;310		break;311	}312 313	writel(reg, regs + EXYNOS3250_OUTFORM);314}315 316void exynos3250_jpeg_jpgadr(void __iomem *regs, unsigned int addr)317{318	writel(addr, regs + EXYNOS3250_JPG_JPGADR);319}320 321void exynos3250_jpeg_imgadr(void __iomem *regs, struct s5p_jpeg_addr *img_addr)322{323	writel(img_addr->y, regs + EXYNOS3250_LUMA_BASE);324	writel(img_addr->cb, regs + EXYNOS3250_CHROMA_BASE);325	writel(img_addr->cr, regs + EXYNOS3250_CHROMA_CR_BASE);326}327 328void exynos3250_jpeg_stride(void __iomem *regs, unsigned int img_fmt,329			    unsigned int width)330{331	u32 reg_luma = 0, reg_cr = 0, reg_cb = 0;332 333	switch (img_fmt) {334	case V4L2_PIX_FMT_RGB32:335		reg_luma = 4 * width;336		break;337	case V4L2_PIX_FMT_RGB565:338	case V4L2_PIX_FMT_RGB565X:339	case V4L2_PIX_FMT_YUYV:340	case V4L2_PIX_FMT_YVYU:341	case V4L2_PIX_FMT_UYVY:342	case V4L2_PIX_FMT_VYUY:343		reg_luma = 2 * width;344		break;345	case V4L2_PIX_FMT_NV12:346	case V4L2_PIX_FMT_NV21:347		reg_luma = width;348		reg_cb = reg_luma;349		break;350	case V4L2_PIX_FMT_YUV420:351		reg_luma = width;352		reg_cb = reg_cr = reg_luma / 2;353		break;354	default:355		break;356	}357 358	writel(reg_luma, regs + EXYNOS3250_LUMA_STRIDE);359	writel(reg_cb, regs + EXYNOS3250_CHROMA_STRIDE);360	writel(reg_cr, regs + EXYNOS3250_CHROMA_CR_STRIDE);361}362 363void exynos3250_jpeg_offset(void __iomem *regs, unsigned int x_offset,364				unsigned int y_offset)365{366	u32 reg;367 368	reg = (y_offset << EXYNOS3250_LUMA_YY_OFFSET_SHIFT) &369			EXYNOS3250_LUMA_YY_OFFSET_MASK;370	reg |= (x_offset << EXYNOS3250_LUMA_YX_OFFSET_SHIFT) &371			EXYNOS3250_LUMA_YX_OFFSET_MASK;372 373	writel(reg, regs + EXYNOS3250_LUMA_XY_OFFSET);374 375	reg = (y_offset << EXYNOS3250_CHROMA_YY_OFFSET_SHIFT) &376			EXYNOS3250_CHROMA_YY_OFFSET_MASK;377	reg |= (x_offset << EXYNOS3250_CHROMA_YX_OFFSET_SHIFT) &378			EXYNOS3250_CHROMA_YX_OFFSET_MASK;379 380	writel(reg, regs + EXYNOS3250_CHROMA_XY_OFFSET);381 382	reg = (y_offset << EXYNOS3250_CHROMA_CR_YY_OFFSET_SHIFT) &383			EXYNOS3250_CHROMA_CR_YY_OFFSET_MASK;384	reg |= (x_offset << EXYNOS3250_CHROMA_CR_YX_OFFSET_SHIFT) &385			EXYNOS3250_CHROMA_CR_YX_OFFSET_MASK;386 387	writel(reg, regs + EXYNOS3250_CHROMA_CR_XY_OFFSET);388}389 390void exynos3250_jpeg_coef(void __iomem *base, unsigned int mode)391{392	if (mode == S5P_JPEG_ENCODE) {393		writel(EXYNOS3250_JPEG_ENC_COEF1,394					base + EXYNOS3250_JPG_COEF(1));395		writel(EXYNOS3250_JPEG_ENC_COEF2,396					base + EXYNOS3250_JPG_COEF(2));397		writel(EXYNOS3250_JPEG_ENC_COEF3,398					base + EXYNOS3250_JPG_COEF(3));399	} else {400		writel(EXYNOS3250_JPEG_DEC_COEF1,401					base + EXYNOS3250_JPG_COEF(1));402		writel(EXYNOS3250_JPEG_DEC_COEF2,403					base + EXYNOS3250_JPG_COEF(2));404		writel(EXYNOS3250_JPEG_DEC_COEF3,405					base + EXYNOS3250_JPG_COEF(3));406	}407}408 409void exynos3250_jpeg_start(void __iomem *regs)410{411	writel(1, regs + EXYNOS3250_JSTART);412}413 414void exynos3250_jpeg_rstart(void __iomem *regs)415{416	writel(1, regs + EXYNOS3250_JRSTART);417}418 419unsigned int exynos3250_jpeg_get_int_status(void __iomem *regs)420{421	return readl(regs + EXYNOS3250_JPGINTST);422}423 424void exynos3250_jpeg_clear_int_status(void __iomem *regs,425				      unsigned int value)426{427	writel(value, regs + EXYNOS3250_JPGINTST);428}429 430unsigned int exynos3250_jpeg_operating(void __iomem *regs)431{432	return readl(regs + S5P_JPGOPR) & EXYNOS3250_JPGOPR_MASK;433}434 435unsigned int exynos3250_jpeg_compressed_size(void __iomem *regs)436{437	return readl(regs + EXYNOS3250_JPGCNT) & EXYNOS3250_JPGCNT_MASK;438}439 440void exynos3250_jpeg_dec_stream_size(void __iomem *regs,441						unsigned int size)442{443	writel(size & EXYNOS3250_DEC_STREAM_MASK,444				regs + EXYNOS3250_DEC_STREAM_SIZE);445}446 447void exynos3250_jpeg_dec_scaling_ratio(void __iomem *regs,448						unsigned int sratio)449{450	switch (sratio) {451	case 1:452	default:453		sratio = EXYNOS3250_DEC_SCALE_FACTOR_8_8;454		break;455	case 2:456		sratio = EXYNOS3250_DEC_SCALE_FACTOR_4_8;457		break;458	case 4:459		sratio = EXYNOS3250_DEC_SCALE_FACTOR_2_8;460		break;461	case 8:462		sratio = EXYNOS3250_DEC_SCALE_FACTOR_1_8;463		break;464	}465 466	writel(sratio & EXYNOS3250_DEC_SCALE_FACTOR_MASK,467				regs + EXYNOS3250_DEC_SCALING_RATIO);468}469 470void exynos3250_jpeg_set_timer(void __iomem *regs, unsigned int time_value)471{472	time_value &= EXYNOS3250_TIMER_INIT_MASK;473 474	writel(EXYNOS3250_TIMER_INT_STAT | time_value,475					regs + EXYNOS3250_TIMER_SE);476}477 478unsigned int exynos3250_jpeg_get_timer_status(void __iomem *regs)479{480	return readl(regs + EXYNOS3250_TIMER_ST);481}482 483void exynos3250_jpeg_clear_timer_status(void __iomem *regs)484{485	writel(EXYNOS3250_TIMER_INT_STAT, regs + EXYNOS3250_TIMER_ST);486}487