From f4104b7851a8d8b9a70899dcbecdb393eb16cd8a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 13 Mar 2022 11:18:17 +0100 Subject: media: platform: rename s5p-jpeg/ to samsung/s5p-jpeg/ As the end goal is to have platform drivers split by vendor, rename s5p-jpeg/ to samsung/s5p-jpeg/. Acked-by: Andrzej Pietrasiewicz Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-jpeg/Kconfig | 12 - drivers/media/platform/s5p-jpeg/Makefile | 3 - drivers/media/platform/s5p-jpeg/jpeg-core.c | 3182 -------------------- drivers/media/platform/s5p-jpeg/jpeg-core.h | 267 -- .../media/platform/s5p-jpeg/jpeg-hw-exynos3250.c | 486 --- .../media/platform/s5p-jpeg/jpeg-hw-exynos3250.h | 57 - drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c | 321 -- drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.h | 44 - drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.c | 306 -- drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.h | 57 - drivers/media/platform/s5p-jpeg/jpeg-regs.h | 646 ---- 11 files changed, 5381 deletions(-) delete mode 100644 drivers/media/platform/s5p-jpeg/Kconfig delete mode 100644 drivers/media/platform/s5p-jpeg/Makefile delete mode 100644 drivers/media/platform/s5p-jpeg/jpeg-core.c delete mode 100644 drivers/media/platform/s5p-jpeg/jpeg-core.h delete mode 100644 drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.c delete mode 100644 drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.h delete mode 100644 drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c delete mode 100644 drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.h delete mode 100644 drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.c delete mode 100644 drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.h delete mode 100644 drivers/media/platform/s5p-jpeg/jpeg-regs.h (limited to 'drivers/media/platform/s5p-jpeg') diff --git a/drivers/media/platform/s5p-jpeg/Kconfig b/drivers/media/platform/s5p-jpeg/Kconfig deleted file mode 100644 index e522860d2b15..000000000000 --- a/drivers/media/platform/s5p-jpeg/Kconfig +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only - -config VIDEO_SAMSUNG_S5P_JPEG - tristate "Samsung S5P/Exynos3250/Exynos4 JPEG codec driver" - depends on V4L_MEM2MEM_DRIVERS - depends on VIDEO_DEV && VIDEO_V4L2 - depends on ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST - select VIDEOBUF2_DMA_CONTIG - select V4L2_MEM2MEM_DEV - help - This is a v4l2 driver for Samsung S5P, EXYNOS3250 - and EXYNOS4 JPEG codec diff --git a/drivers/media/platform/s5p-jpeg/Makefile b/drivers/media/platform/s5p-jpeg/Makefile deleted file mode 100644 index 8b0f92e27e70..000000000000 --- a/drivers/media/platform/s5p-jpeg/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -s5p-jpeg-objs := jpeg-core.o jpeg-hw-exynos3250.o jpeg-hw-exynos4.o jpeg-hw-s5p.o -obj-$(CONFIG_VIDEO_SAMSUNG_S5P_JPEG) += s5p-jpeg.o diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c deleted file mode 100644 index a8d9159d5ed8..000000000000 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ /dev/null @@ -1,3182 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* linux/drivers/media/platform/s5p-jpeg/jpeg-core.c - * - * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * Author: Andrzej Pietrasiewicz - * Author: Jacek Anaszewski - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "jpeg-core.h" -#include "jpeg-hw-s5p.h" -#include "jpeg-hw-exynos4.h" -#include "jpeg-hw-exynos3250.h" -#include "jpeg-regs.h" - -static struct s5p_jpeg_fmt sjpeg_formats[] = { - { - .fourcc = V4L2_PIX_FMT_JPEG, - .flags = SJPEG_FMT_FLAG_ENC_CAPTURE | - SJPEG_FMT_FLAG_DEC_OUTPUT | - SJPEG_FMT_FLAG_S5P | - SJPEG_FMT_FLAG_EXYNOS3250 | - SJPEG_FMT_FLAG_EXYNOS4, - }, - { - .fourcc = V4L2_PIX_FMT_YUYV, - .depth = 16, - .colplanes = 1, - .h_align = 4, - .v_align = 3, - .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | - SJPEG_FMT_FLAG_DEC_CAPTURE | - SJPEG_FMT_FLAG_S5P | - SJPEG_FMT_NON_RGB, - .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422, - }, - { - .fourcc = V4L2_PIX_FMT_YUYV, - .depth = 16, - .colplanes = 1, - .h_align = 1, - .v_align = 0, - .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | - SJPEG_FMT_FLAG_DEC_CAPTURE | - SJPEG_FMT_FLAG_EXYNOS4 | - SJPEG_FMT_NON_RGB, - .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422, - }, - { - .fourcc = V4L2_PIX_FMT_YUYV, - .depth = 16, - .colplanes = 1, - .h_align = 2, - .v_align = 0, - .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | - SJPEG_FMT_FLAG_DEC_CAPTURE | - SJPEG_FMT_FLAG_EXYNOS3250 | - SJPEG_FMT_NON_RGB, - .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422, - }, - { - .fourcc = V4L2_PIX_FMT_YVYU, - .depth = 16, - .colplanes = 1, - .h_align = 1, - .v_align = 0, - .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | - SJPEG_FMT_FLAG_DEC_CAPTURE | - SJPEG_FMT_FLAG_EXYNOS4 | - SJPEG_FMT_NON_RGB, - .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422, - }, - { - .fourcc = V4L2_PIX_FMT_YVYU, - .depth = 16, - .colplanes = 1, - .h_align = 2, - .v_align = 0, - .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | - SJPEG_FMT_FLAG_DEC_CAPTURE | - SJPEG_FMT_FLAG_EXYNOS3250 | - SJPEG_FMT_NON_RGB, - .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422, - }, - { - .fourcc = V4L2_PIX_FMT_UYVY, - .depth = 16, - .colplanes = 1, - .h_align = 2, - .v_align = 0, - .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | - SJPEG_FMT_FLAG_DEC_CAPTURE | - SJPEG_FMT_FLAG_EXYNOS3250 | - SJPEG_FMT_NON_RGB, - .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422, - }, - { - .fourcc = V4L2_PIX_FMT_VYUY, - .depth = 16, - .colplanes = 1, - .h_align = 2, - .v_align = 0, - .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | - SJPEG_FMT_FLAG_DEC_CAPTURE | - SJPEG_FMT_FLAG_EXYNOS3250 | - SJPEG_FMT_NON_RGB, - .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422, - }, - { - .fourcc = V4L2_PIX_FMT_RGB565, - .depth = 16, - .colplanes = 1, - .h_align = 0, - .v_align = 0, - .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | - SJPEG_FMT_FLAG_DEC_CAPTURE | - SJPEG_FMT_FLAG_EXYNOS4 | - SJPEG_FMT_RGB, - .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444, - }, - { - .fourcc = V4L2_PIX_FMT_RGB565, - .depth = 16, - .colplanes = 1, - .h_align = 2, - .v_align = 0, - .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | - SJPEG_FMT_FLAG_DEC_CAPTURE | - SJPEG_FMT_FLAG_EXYNOS3250 | - SJPEG_FMT_RGB, - .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444, - }, - { - .fourcc = V4L2_PIX_FMT_RGB565X, - .depth = 16, - .colplanes = 1, - .h_align = 2, - .v_align = 0, - .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | - SJPEG_FMT_FLAG_DEC_CAPTURE | - SJPEG_FMT_FLAG_EXYNOS3250 | - SJPEG_FMT_RGB, - .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444, - }, - { - .fourcc = V4L2_PIX_FMT_RGB565, - .depth = 16, - .colplanes = 1, - .h_align = 0, - .v_align = 0, - .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | - SJPEG_FMT_FLAG_S5P | - SJPEG_FMT_RGB, - .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444, - }, - { - .fourcc = V4L2_PIX_FMT_RGB32, - .depth = 32, - .colplanes = 1, - .h_align = 0, - .v_align = 0, - .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | - SJPEG_FMT_FLAG_DEC_CAPTURE | - SJPEG_FMT_FLAG_EXYNOS4 | - SJPEG_FMT_RGB, - .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444, - }, - { - .fourcc = V4L2_PIX_FMT_RGB32, - .depth = 32, - .colplanes = 1, - .h_align = 2, - .v_align = 0, - .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | - SJPEG_FMT_FLAG_DEC_CAPTURE | - SJPEG_FMT_FLAG_EXYNOS3250 | - SJPEG_FMT_RGB, - .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444, - }, - { - .fourcc = V4L2_PIX_FMT_NV24, - .depth = 24, - .colplanes = 2, - .h_align = 0, - .v_align = 0, - .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | - SJPEG_FMT_FLAG_DEC_CAPTURE | - SJPEG_FMT_FLAG_EXYNOS4 | - SJPEG_FMT_NON_RGB, - .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444, - }, - { - .fourcc = V4L2_PIX_FMT_NV42, - .depth = 24, - .colplanes = 2, - .h_align = 0, - .v_align = 0, - .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | - SJPEG_FMT_FLAG_DEC_CAPTURE | - SJPEG_FMT_FLAG_EXYNOS4 | - SJPEG_FMT_NON_RGB, - .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444, - }, - { - .fourcc = V4L2_PIX_FMT_NV61, - .depth = 16, - .colplanes = 2, - .h_align = 1, - .v_align = 0, - .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | - SJPEG_FMT_FLAG_DEC_CAPTURE | - SJPEG_FMT_FLAG_EXYNOS4 | - SJPEG_FMT_NON_RGB, - .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422, - }, - { - .fourcc = V4L2_PIX_FMT_NV16, - .depth = 16, - .colplanes = 2, - .h_align = 1, - .v_align = 0, - .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | - SJPEG_FMT_FLAG_DEC_CAPTURE | - SJPEG_FMT_FLAG_EXYNOS4 | - SJPEG_FMT_NON_RGB, - .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422, - }, - { - .fourcc = V4L2_PIX_FMT_NV12, - .depth = 12, - .colplanes = 2, - .h_align = 1, - .v_align = 1, - .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | - SJPEG_FMT_FLAG_DEC_CAPTURE | - SJPEG_FMT_FLAG_EXYNOS4 | - SJPEG_FMT_NON_RGB, - .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, - }, - { - .fourcc = V4L2_PIX_FMT_NV12, - .depth = 12, - .colplanes = 2, - .h_align = 3, - .v_align = 3, - .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | - SJPEG_FMT_FLAG_DEC_CAPTURE | - SJPEG_FMT_FLAG_EXYNOS3250 | - SJPEG_FMT_NON_RGB, - .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, - }, - { - .fourcc = V4L2_PIX_FMT_NV12, - .depth = 12, - .colplanes = 2, - .h_align = 4, - .v_align = 4, - .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | - SJPEG_FMT_FLAG_DEC_CAPTURE | - SJPEG_FMT_FLAG_S5P | - SJPEG_FMT_NON_RGB, - .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, - }, - { - .fourcc = V4L2_PIX_FMT_NV21, - .depth = 12, - .colplanes = 2, - .h_align = 3, - .v_align = 3, - .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | - SJPEG_FMT_FLAG_DEC_CAPTURE | - SJPEG_FMT_FLAG_EXYNOS3250 | - SJPEG_FMT_NON_RGB, - .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, - }, - { - .fourcc = V4L2_PIX_FMT_NV21, - .depth = 12, - .colplanes = 2, - .h_align = 1, - .v_align = 1, - .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | - SJPEG_FMT_FLAG_DEC_CAPTURE | - SJPEG_FMT_FLAG_EXYNOS3250 | - SJPEG_FMT_FLAG_EXYNOS4 | - SJPEG_FMT_NON_RGB, - .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, - }, - { - .fourcc = V4L2_PIX_FMT_YUV420, - .depth = 12, - .colplanes = 3, - .h_align = 1, - .v_align = 1, - .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | - SJPEG_FMT_FLAG_DEC_CAPTURE | - SJPEG_FMT_FLAG_EXYNOS4 | - SJPEG_FMT_NON_RGB, - .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, - }, - { - .fourcc = V4L2_PIX_FMT_YUV420, - .depth = 12, - .colplanes = 3, - .h_align = 4, - .v_align = 4, - .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | - SJPEG_FMT_FLAG_DEC_CAPTURE | - SJPEG_FMT_FLAG_EXYNOS3250 | - SJPEG_FMT_NON_RGB, - .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, - }, - { - .fourcc = V4L2_PIX_FMT_GREY, - .depth = 8, - .colplanes = 1, - .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | - SJPEG_FMT_FLAG_DEC_CAPTURE | - SJPEG_FMT_FLAG_EXYNOS4 | - SJPEG_FMT_NON_RGB, - .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY, - }, -}; -#define SJPEG_NUM_FORMATS ARRAY_SIZE(sjpeg_formats) - -static const unsigned char qtbl_luminance[4][64] = { - {/*level 0 - high compression quality */ - 20, 16, 25, 39, 50, 46, 62, 68, - 16, 18, 23, 38, 38, 53, 65, 68, - 25, 23, 31, 38, 53, 65, 68, 68, - 39, 38, 38, 53, 65, 68, 68, 68, - 50, 38, 53, 65, 68, 68, 68, 68, - 46, 53, 65, 68, 68, 68, 68, 68, - 62, 65, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68 - }, - {/* level 1 */ - 16, 11, 11, 16, 23, 27, 31, 30, - 11, 12, 12, 15, 20, 23, 23, 30, - 11, 12, 13, 16, 23, 26, 35, 47, - 16, 15, 16, 23, 26, 37, 47, 64, - 23, 20, 23, 26, 39, 51, 64, 64, - 27, 23, 26, 37, 51, 64, 64, 64, - 31, 23, 35, 47, 64, 64, 64, 64, - 30, 30, 47, 64, 64, 64, 64, 64 - }, - {/* level 2 */ - 12, 8, 8, 12, 17, 21, 24, 23, - 8, 9, 9, 11, 15, 19, 18, 23, - 8, 9, 10, 12, 19, 20, 27, 36, - 12, 11, 12, 21, 20, 28, 36, 53, - 17, 15, 19, 20, 30, 39, 51, 59, - 21, 19, 20, 28, 39, 51, 59, 59, - 24, 18, 27, 36, 51, 59, 59, 59, - 23, 23, 36, 53, 59, 59, 59, 59 - }, - {/* level 3 - low compression quality */ - 8, 6, 6, 8, 12, 14, 16, 17, - 6, 6, 6, 8, 10, 13, 12, 15, - 6, 6, 7, 8, 13, 14, 18, 24, - 8, 8, 8, 14, 13, 19, 24, 35, - 12, 10, 13, 13, 20, 26, 34, 39, - 14, 13, 14, 19, 26, 34, 39, 39, - 16, 12, 18, 24, 34, 39, 39, 39, - 17, 15, 24, 35, 39, 39, 39, 39 - } -}; - -static const unsigned char qtbl_chrominance[4][64] = { - {/*level 0 - high compression quality */ - 21, 25, 32, 38, 54, 68, 68, 68, - 25, 28, 24, 38, 54, 68, 68, 68, - 32, 24, 32, 43, 66, 68, 68, 68, - 38, 38, 43, 53, 68, 68, 68, 68, - 54, 54, 66, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68 - }, - {/* level 1 */ - 17, 15, 17, 21, 20, 26, 38, 48, - 15, 19, 18, 17, 20, 26, 35, 43, - 17, 18, 20, 22, 26, 30, 46, 53, - 21, 17, 22, 28, 30, 39, 53, 64, - 20, 20, 26, 30, 39, 48, 64, 64, - 26, 26, 30, 39, 48, 63, 64, 64, - 38, 35, 46, 53, 64, 64, 64, 64, - 48, 43, 53, 64, 64, 64, 64, 64 - }, - {/* level 2 */ - 13, 11, 13, 16, 20, 20, 29, 37, - 11, 14, 14, 14, 16, 20, 26, 32, - 13, 14, 15, 17, 20, 23, 35, 40, - 16, 14, 17, 21, 23, 30, 40, 50, - 20, 16, 20, 23, 30, 37, 50, 59, - 20, 20, 23, 30, 37, 48, 59, 59, - 29, 26, 35, 40, 50, 59, 59, 59, - 37, 32, 40, 50, 59, 59, 59, 59 - }, - {/* level 3 - low compression quality */ - 9, 8, 9, 11, 14, 17, 19, 24, - 8, 10, 9, 11, 14, 13, 17, 22, - 9, 9, 13, 14, 13, 15, 23, 26, - 11, 11, 14, 14, 15, 20, 26, 33, - 14, 14, 13, 15, 20, 24, 33, 39, - 17, 13, 15, 20, 24, 32, 39, 39, - 19, 17, 23, 26, 33, 39, 39, 39, - 24, 22, 26, 33, 39, 39, 39, 39 - } -}; - -static const unsigned char hdctbl0[16] = { - 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 -}; - -static const unsigned char hdctblg0[12] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb -}; -static const unsigned char hactbl0[16] = { - 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d -}; -static const unsigned char hactblg0[162] = { - 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, - 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, - 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, - 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, - 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, - 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, - 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, - 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, - 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, - 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, - 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, - 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, - 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, - 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, - 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, - 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, - 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa -}; - -/* - * Fourcc downgrade schema lookup tables for 422 and 420 - * chroma subsampling - fourcc on each position maps on the - * fourcc from the table fourcc_to_dwngrd_schema_id which allows - * to get the most suitable fourcc counterpart for the given - * downgraded subsampling property. - */ -static const u32 subs422_fourcc_dwngrd_schema[] = { - V4L2_PIX_FMT_NV16, - V4L2_PIX_FMT_NV61, -}; - -static const u32 subs420_fourcc_dwngrd_schema[] = { - V4L2_PIX_FMT_NV12, - V4L2_PIX_FMT_NV21, - V4L2_PIX_FMT_NV12, - V4L2_PIX_FMT_NV21, - V4L2_PIX_FMT_NV12, - V4L2_PIX_FMT_NV21, - V4L2_PIX_FMT_GREY, - V4L2_PIX_FMT_GREY, - V4L2_PIX_FMT_GREY, - V4L2_PIX_FMT_GREY, -}; - -/* - * Lookup table for translation of a fourcc to the position - * of its downgraded counterpart in the *fourcc_dwngrd_schema - * tables. - */ -static const u32 fourcc_to_dwngrd_schema_id[] = { - V4L2_PIX_FMT_NV24, - V4L2_PIX_FMT_NV42, - V4L2_PIX_FMT_NV16, - V4L2_PIX_FMT_NV61, - V4L2_PIX_FMT_YUYV, - V4L2_PIX_FMT_YVYU, - V4L2_PIX_FMT_NV12, - V4L2_PIX_FMT_NV21, - V4L2_PIX_FMT_YUV420, - V4L2_PIX_FMT_GREY, -}; - -static int s5p_jpeg_get_dwngrd_sch_id_by_fourcc(u32 fourcc) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(fourcc_to_dwngrd_schema_id); ++i) { - if (fourcc_to_dwngrd_schema_id[i] == fourcc) - return i; - } - - return -EINVAL; -} - -static int s5p_jpeg_adjust_fourcc_to_subsampling( - enum v4l2_jpeg_chroma_subsampling subs, - u32 in_fourcc, - u32 *out_fourcc, - struct s5p_jpeg_ctx *ctx) -{ - int dwngrd_sch_id; - - if (ctx->subsampling != V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY) { - dwngrd_sch_id = - s5p_jpeg_get_dwngrd_sch_id_by_fourcc(in_fourcc); - if (dwngrd_sch_id < 0) - return -EINVAL; - } - - switch (ctx->subsampling) { - case V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY: - *out_fourcc = V4L2_PIX_FMT_GREY; - break; - case V4L2_JPEG_CHROMA_SUBSAMPLING_420: - if (dwngrd_sch_id > - ARRAY_SIZE(subs420_fourcc_dwngrd_schema) - 1) - return -EINVAL; - *out_fourcc = subs420_fourcc_dwngrd_schema[dwngrd_sch_id]; - break; - case V4L2_JPEG_CHROMA_SUBSAMPLING_422: - if (dwngrd_sch_id > - ARRAY_SIZE(subs422_fourcc_dwngrd_schema) - 1) - return -EINVAL; - *out_fourcc = subs422_fourcc_dwngrd_schema[dwngrd_sch_id]; - break; - default: - *out_fourcc = V4L2_PIX_FMT_GREY; - break; - } - - return 0; -} - -static int exynos4x12_decoded_subsampling[] = { - V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY, - V4L2_JPEG_CHROMA_SUBSAMPLING_444, - V4L2_JPEG_CHROMA_SUBSAMPLING_422, - V4L2_JPEG_CHROMA_SUBSAMPLING_420, -}; - -static int exynos3250_decoded_subsampling[] = { - V4L2_JPEG_CHROMA_SUBSAMPLING_444, - V4L2_JPEG_CHROMA_SUBSAMPLING_422, - V4L2_JPEG_CHROMA_SUBSAMPLING_420, - V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY, - -1, - -1, - V4L2_JPEG_CHROMA_SUBSAMPLING_411, -}; - -static inline struct s5p_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *c) -{ - return container_of(c->handler, struct s5p_jpeg_ctx, ctrl_handler); -} - -static inline struct s5p_jpeg_ctx *fh_to_ctx(struct v4l2_fh *fh) -{ - return container_of(fh, struct s5p_jpeg_ctx, fh); -} - -static int s5p_jpeg_to_user_subsampling(struct s5p_jpeg_ctx *ctx) -{ - switch (ctx->jpeg->variant->version) { - case SJPEG_S5P: - WARN_ON(ctx->subsampling > 3); - if (ctx->subsampling > 2) - return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY; - return ctx->subsampling; - case SJPEG_EXYNOS3250: - case SJPEG_EXYNOS5420: - WARN_ON(ctx->subsampling > 6); - if (ctx->subsampling > 3) - return V4L2_JPEG_CHROMA_SUBSAMPLING_411; - return exynos3250_decoded_subsampling[ctx->subsampling]; - case SJPEG_EXYNOS4: - WARN_ON(ctx->subsampling > 3); - if (ctx->subsampling > 2) - return V4L2_JPEG_CHROMA_SUBSAMPLING_420; - return exynos4x12_decoded_subsampling[ctx->subsampling]; - case SJPEG_EXYNOS5433: - return ctx->subsampling; /* parsed from header */ - default: - WARN_ON(ctx->subsampling > 3); - return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY; - } -} - -static inline void s5p_jpeg_set_qtbl(void __iomem *regs, - const unsigned char *qtbl, - unsigned long tab, int len) -{ - int i; - - for (i = 0; i < len; i++) - writel((unsigned int)qtbl[i], regs + tab + (i * 0x04)); -} - -static inline void s5p_jpeg_set_qtbl_lum(void __iomem *regs, int quality) -{ - /* this driver fills quantisation table 0 with data for luma */ - s5p_jpeg_set_qtbl(regs, qtbl_luminance[quality], - S5P_JPG_QTBL_CONTENT(0), - ARRAY_SIZE(qtbl_luminance[quality])); -} - -static inline void s5p_jpeg_set_qtbl_chr(void __iomem *regs, int quality) -{ - /* this driver fills quantisation table 1 with data for chroma */ - s5p_jpeg_set_qtbl(regs, qtbl_chrominance[quality], - S5P_JPG_QTBL_CONTENT(1), - ARRAY_SIZE(qtbl_chrominance[quality])); -} - -static inline void s5p_jpeg_set_htbl(void __iomem *regs, - const unsigned char *htbl, - unsigned long tab, int len) -{ - int i; - - for (i = 0; i < len; i++) - writel((unsigned int)htbl[i], regs + tab + (i * 0x04)); -} - -static inline void s5p_jpeg_set_hdctbl(void __iomem *regs) -{ - /* this driver fills table 0 for this component */ - s5p_jpeg_set_htbl(regs, hdctbl0, S5P_JPG_HDCTBL(0), - ARRAY_SIZE(hdctbl0)); -} - -static inline void s5p_jpeg_set_hdctblg(void __iomem *regs) -{ - /* this driver fills table 0 for this component */ - s5p_jpeg_set_htbl(regs, hdctblg0, S5P_JPG_HDCTBLG(0), - ARRAY_SIZE(hdctblg0)); -} - -static inline void s5p_jpeg_set_hactbl(void __iomem *regs) -{ - /* this driver fills table 0 for this component */ - s5p_jpeg_set_htbl(regs, hactbl0, S5P_JPG_HACTBL(0), - ARRAY_SIZE(hactbl0)); -} - -static inline void s5p_jpeg_set_hactblg(void __iomem *regs) -{ - /* this driver fills table 0 for this component */ - s5p_jpeg_set_htbl(regs, hactblg0, S5P_JPG_HACTBLG(0), - ARRAY_SIZE(hactblg0)); -} - -static inline void exynos4_jpeg_set_tbl(void __iomem *regs, - const unsigned char *tbl, - unsigned long tab, int len) -{ - int i; - unsigned int dword; - - for (i = 0; i < len; i += 4) { - dword = tbl[i] | - (tbl[i + 1] << 8) | - (tbl[i + 2] << 16) | - (tbl[i + 3] << 24); - writel(dword, regs + tab + i); - } -} - -static inline void exynos4_jpeg_set_qtbl_lum(void __iomem *regs, int quality) -{ - /* this driver fills quantisation table 0 with data for luma */ - exynos4_jpeg_set_tbl(regs, qtbl_luminance[quality], - EXYNOS4_QTBL_CONTENT(0), - ARRAY_SIZE(qtbl_luminance[quality])); -} - -static inline void exynos4_jpeg_set_qtbl_chr(void __iomem *regs, int quality) -{ - /* this driver fills quantisation table 1 with data for chroma */ - exynos4_jpeg_set_tbl(regs, qtbl_chrominance[quality], - EXYNOS4_QTBL_CONTENT(1), - ARRAY_SIZE(qtbl_chrominance[quality])); -} - -static void exynos4_jpeg_set_huff_tbl(void __iomem *base) -{ - exynos4_jpeg_set_tbl(base, hdctbl0, EXYNOS4_HUFF_TBL_HDCLL, - ARRAY_SIZE(hdctbl0)); - exynos4_jpeg_set_tbl(base, hdctbl0, EXYNOS4_HUFF_TBL_HDCCL, - ARRAY_SIZE(hdctbl0)); - exynos4_jpeg_set_tbl(base, hdctblg0, EXYNOS4_HUFF_TBL_HDCLV, - ARRAY_SIZE(hdctblg0)); - exynos4_jpeg_set_tbl(base, hdctblg0, EXYNOS4_HUFF_TBL_HDCCV, - ARRAY_SIZE(hdctblg0)); - exynos4_jpeg_set_tbl(base, hactbl0, EXYNOS4_HUFF_TBL_HACLL, - ARRAY_SIZE(hactbl0)); - exynos4_jpeg_set_tbl(base, hactbl0, EXYNOS4_HUFF_TBL_HACCL, - ARRAY_SIZE(hactbl0)); - exynos4_jpeg_set_tbl(base, hactblg0, EXYNOS4_HUFF_TBL_HACLV, - ARRAY_SIZE(hactblg0)); - exynos4_jpeg_set_tbl(base, hactblg0, EXYNOS4_HUFF_TBL_HACCV, - ARRAY_SIZE(hactblg0)); -} - -static inline int __exynos4_huff_tbl(int class, int id, bool lenval) -{ - /* - * class: 0 - DC, 1 - AC - * id: 0 - Y, 1 - Cb/Cr - */ - if (class) { - if (id) - return lenval ? EXYNOS4_HUFF_TBL_HACCL : - EXYNOS4_HUFF_TBL_HACCV; - return lenval ? EXYNOS4_HUFF_TBL_HACLL : EXYNOS4_HUFF_TBL_HACLV; - - } - /* class == 0 */ - if (id) - return lenval ? EXYNOS4_HUFF_TBL_HDCCL : EXYNOS4_HUFF_TBL_HDCCV; - - return lenval ? EXYNOS4_HUFF_TBL_HDCLL : EXYNOS4_HUFF_TBL_HDCLV; -} - -static inline int exynos4_huff_tbl_len(int class, int id) -{ - return __exynos4_huff_tbl(class, id, true); -} - -static inline int exynos4_huff_tbl_val(int class, int id) -{ - return __exynos4_huff_tbl(class, id, false); -} - -static int get_byte(struct s5p_jpeg_buffer *buf); -static int get_word_be(struct s5p_jpeg_buffer *buf, unsigned int *word); -static void skip(struct s5p_jpeg_buffer *buf, long len); - -static void exynos4_jpeg_parse_decode_h_tbl(struct s5p_jpeg_ctx *ctx) -{ - struct s5p_jpeg *jpeg = ctx->jpeg; - struct vb2_v4l2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); - struct s5p_jpeg_buffer jpeg_buffer; - unsigned int word; - int c, x, components; - - jpeg_buffer.size = 2; /* Ls */ - jpeg_buffer.data = - (unsigned long)vb2_plane_vaddr(&vb->vb2_buf, 0) + ctx->out_q.sos + 2; - jpeg_buffer.curr = 0; - - word = 0; - - if (get_word_be(&jpeg_buffer, &word)) - return; - jpeg_buffer.size = (long)word - 2; - jpeg_buffer.data += 2; - jpeg_buffer.curr = 0; - - components = get_byte(&jpeg_buffer); - if (components == -1) - return; - while (components--) { - c = get_byte(&jpeg_buffer); - if (c == -1) - return; - x = get_byte(&jpeg_buffer); - if (x == -1) - return; - exynos4_jpeg_select_dec_h_tbl(jpeg->regs, c, - (((x >> 4) & 0x1) << 1) | (x & 0x1)); - } - -} - -static void exynos4_jpeg_parse_huff_tbl(struct s5p_jpeg_ctx *ctx) -{ - struct s5p_jpeg *jpeg = ctx->jpeg; - struct vb2_v4l2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); - struct s5p_jpeg_buffer jpeg_buffer; - unsigned int word; - int c, i, n, j; - - for (j = 0; j < ctx->out_q.dht.n; ++j) { - jpeg_buffer.size = ctx->out_q.dht.len[j]; - jpeg_buffer.data = (unsigned long)vb2_plane_vaddr(&vb->vb2_buf, 0) + - ctx->out_q.dht.marker[j]; - jpeg_buffer.curr = 0; - - word = 0; - while (jpeg_buffer.curr < jpeg_buffer.size) { - char id, class; - - c = get_byte(&jpeg_buffer); - if (c == -1) - return; - id = c & 0xf; - class = (c >> 4) & 0xf; - n = 0; - for (i = 0; i < 16; ++i) { - c = get_byte(&jpeg_buffer); - if (c == -1) - return; - word |= c << ((i % 4) * 8); - if ((i + 1) % 4 == 0) { - writel(word, jpeg->regs + - exynos4_huff_tbl_len(class, id) + - (i / 4) * 4); - word = 0; - } - n += c; - } - word = 0; - for (i = 0; i < n; ++i) { - c = get_byte(&jpeg_buffer); - if (c == -1) - return; - word |= c << ((i % 4) * 8); - if ((i + 1) % 4 == 0) { - writel(word, jpeg->regs + - exynos4_huff_tbl_val(class, id) + - (i / 4) * 4); - word = 0; - } - } - if (i % 4) { - writel(word, jpeg->regs + - exynos4_huff_tbl_val(class, id) + (i / 4) * 4); - } - word = 0; - } - } -} - -static void exynos4_jpeg_parse_decode_q_tbl(struct s5p_jpeg_ctx *ctx) -{ - struct s5p_jpeg *jpeg = ctx->jpeg; - struct vb2_v4l2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); - struct s5p_jpeg_buffer jpeg_buffer; - int c, x, components; - - jpeg_buffer.size = ctx->out_q.sof_len; - jpeg_buffer.data = - (unsigned long)vb2_plane_vaddr(&vb->vb2_buf, 0) + ctx->out_q.sof; - jpeg_buffer.curr = 0; - - skip(&jpeg_buffer, 5); /* P, Y, X */ - components = get_byte(&jpeg_buffer); - if (components == -1) - return; - - exynos4_jpeg_set_dec_components(jpeg->regs, components); - - while (components--) { - c = get_byte(&jpeg_buffer); - if (c == -1) - return; - skip(&jpeg_buffer, 1); - x = get_byte(&jpeg_buffer); - if (x == -1) - return; - exynos4_jpeg_select_dec_q_tbl(jpeg->regs, c, x); - } -} - -static void exynos4_jpeg_parse_q_tbl(struct s5p_jpeg_ctx *ctx) -{ - struct s5p_jpeg *jpeg = ctx->jpeg; - struct vb2_v4l2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); - struct s5p_jpeg_buffer jpeg_buffer; - unsigned int word; - int c, i, j; - - for (j = 0; j < ctx->out_q.dqt.n; ++j) { - jpeg_buffer.size = ctx->out_q.dqt.len[j]; - jpeg_buffer.data = (unsigned long)vb2_plane_vaddr(&vb->vb2_buf, 0) + - ctx->out_q.dqt.marker[j]; - jpeg_buffer.curr = 0; - - word = 0; - while (jpeg_buffer.size - jpeg_buffer.curr >= 65) { - char id; - - c = get_byte(&jpeg_buffer); - if (c == -1) - return; - id = c & 0xf; - /* nonzero means extended mode - not supported */ - if ((c >> 4) & 0xf) - return; - for (i = 0; i < 64; ++i) { - c = get_byte(&jpeg_buffer); - if (c == -1) - return; - word |= c << ((i % 4) * 8); - if ((i + 1) % 4 == 0) { - writel(word, jpeg->regs + - EXYNOS4_QTBL_CONTENT(id) + (i / 4) * 4); - word = 0; - } - } - word = 0; - } - } -} - -/* - * ============================================================================ - * Device file operations - * ============================================================================ - */ - -static int queue_init(void *priv, struct vb2_queue *src_vq, - struct vb2_queue *dst_vq); -static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx, - __u32 pixelformat, unsigned int fmt_type); -static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx); - -static int s5p_jpeg_open(struct file *file) -{ - struct s5p_jpeg *jpeg = video_drvdata(file); - struct video_device *vfd = video_devdata(file); - struct s5p_jpeg_ctx *ctx; - struct s5p_jpeg_fmt *out_fmt, *cap_fmt; - int ret = 0; - - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; - - if (mutex_lock_interruptible(&jpeg->lock)) { - ret = -ERESTARTSYS; - goto free; - } - - v4l2_fh_init(&ctx->fh, vfd); - /* Use separate control handler per file handle */ - ctx->fh.ctrl_handler = &ctx->ctrl_handler; - file->private_data = &ctx->fh; - v4l2_fh_add(&ctx->fh); - - ctx->jpeg = jpeg; - if (vfd == jpeg->vfd_encoder) { - ctx->mode = S5P_JPEG_ENCODE; - out_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_RGB565, - FMT_TYPE_OUTPUT); - cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG, - FMT_TYPE_CAPTURE); - } else { - ctx->mode = S5P_JPEG_DECODE; - out_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG, - FMT_TYPE_OUTPUT); - cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_YUYV, - FMT_TYPE_CAPTURE); - ctx->scale_factor = EXYNOS3250_DEC_SCALE_FACTOR_8_8; - } - - ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, queue_init); - if (IS_ERR(ctx->fh.m2m_ctx)) { - ret = PTR_ERR(ctx->fh.m2m_ctx); - goto error; - } - - ctx->out_q.fmt = out_fmt; - ctx->cap_q.fmt = cap_fmt; - - ret = s5p_jpeg_controls_create(ctx); - if (ret < 0) - goto error; - - mutex_unlock(&jpeg->lock); - return 0; - -error: - v4l2_fh_del(&ctx->fh); - v4l2_fh_exit(&ctx->fh); - mutex_unlock(&jpeg->lock); -free: - kfree(ctx); - return ret; -} - -static int s5p_jpeg_release(struct file *file) -{ - struct s5p_jpeg *jpeg = video_drvdata(file); - struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data); - - mutex_lock(&jpeg->lock); - v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); - v4l2_ctrl_handler_free(&ctx->ctrl_handler); - v4l2_fh_del(&ctx->fh); - v4l2_fh_exit(&ctx->fh); - kfree(ctx); - mutex_unlock(&jpeg->lock); - - return 0; -} - -static const struct v4l2_file_operations s5p_jpeg_fops = { - .owner = THIS_MODULE, - .open = s5p_jpeg_open, - .release = s5p_jpeg_release, - .poll = v4l2_m2m_fop_poll, - .unlocked_ioctl = video_ioctl2, - .mmap = v4l2_m2m_fop_mmap, -}; - -/* - * ============================================================================ - * video ioctl operations - * ============================================================================ - */ - -static int get_byte(struct s5p_jpeg_buffer *buf) -{ - if (buf->curr >= buf->size) - return -1; - - return ((unsigned char *)buf->data)[buf->curr++]; -} - -static int get_word_be(struct s5p_jpeg_buffer *buf, unsigned int *word) -{ - unsigned int temp; - int byte; - - byte = get_byte(buf); - if (byte == -1) - return -1; - temp = byte << 8; - byte = get_byte(buf); - if (byte == -1) - return -1; - *word = (unsigned int)byte | temp; - return 0; -} - -static void skip(struct s5p_jpeg_buffer *buf, long len) -{ - if (len <= 0) - return; - - while (len--) - get_byte(buf); -} - -static bool s5p_jpeg_subsampling_decode(struct s5p_jpeg_ctx *ctx, - unsigned int subsampling) -{ - unsigned int version; - - switch (subsampling) { - case 0x11: - ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444; - break; - case 0x21: - ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422; - break; - case 0x22: - ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420; - break; - case 0x33: - ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY; - break; - case 0x41: - /* - * 4:1:1 subsampling only supported by 3250, 5420, and 5433 - * variants - */ - version = ctx->jpeg->variant->version; - if (version != SJPEG_EXYNOS3250 && - version != SJPEG_EXYNOS5420 && - version != SJPEG_EXYNOS5433) - return false; - - ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_411; - break; - default: - return false; - } - - return true; -} - -static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result, - unsigned long buffer, unsigned long size, - struct s5p_jpeg_ctx *ctx) -{ - int c, components = 0, notfound, n_dht = 0, n_dqt = 0; - unsigned int height = 0, width = 0, word, subsampling = 0; - unsigned int sos = 0, sof = 0, sof_len = 0; - unsigned int dht[S5P_JPEG_MAX_MARKER], dht_len[S5P_JPEG_MAX_MARKER]; - unsigned int dqt[S5P_JPEG_MAX_MARKER], dqt_len[S5P_JPEG_MAX_MARKER]; - long length; - struct s5p_jpeg_buffer jpeg_buffer; - - jpeg_buffer.size = size; - jpeg_buffer.data = buffer; - jpeg_buffer.curr = 0; - - notfound = 1; - while (notfound || !sos) { - c = get_byte(&jpeg_buffer); - if (c == -1) - return false; - if (c != 0xff) - continue; - do - c = get_byte(&jpeg_buffer); - while (c == 0xff); - if (c == -1) - return false; - if (c == 0) - continue; - length = 0; - switch (c) { - /* JPEG_MARKER_SOF0: baseline JPEG */ - case JPEG_MARKER_SOF0: - if (get_word_be(&jpeg_buffer, &word)) - break; - length = (long)word - 2; - if (!length) - return false; - sof = jpeg_buffer.curr; /* after 0xffc0 */ - sof_len = length; - if (get_byte(&jpeg_buffer) == -1) - break; - if (get_word_be(&jpeg_buffer, &height)) - break; - if (get_word_be(&jpeg_buffer, &width)) - break; - components = get_byte(&jpeg_buffer); - if (components == -1) - break; - - if (components == 1) { - subsampling = 0x33; - } else { - skip(&jpeg_buffer, 1); - subsampling = get_byte(&jpeg_buffer); - skip(&jpeg_buffer, 1); - } - if (components > 3) - return false; - skip(&jpeg_buffer, components * 2); - notfound = 0; - break; - - case JPEG_MARKER_DQT: - if (get_word_be(&jpeg_buffer, &word)) - break; - length = (long)word - 2; - if (!length) - return false; - if (n_dqt >= S5P_JPEG_MAX_MARKER) - return false; - dqt[n_dqt] = jpeg_buffer.curr; /* after 0xffdb */ - dqt_len[n_dqt++] = length; - skip(&jpeg_buffer, length); - break; - - case JPEG_MARKER_DHT: - if (get_word_be(&jpeg_buffer, &word)) - break; - length = (long)word - 2; - if (!length) - return false; - if (n_dht >= S5P_JPEG_MAX_MARKER) - return false; - dht[n_dht] = jpeg_buffer.curr; /* after 0xffc4 */ - dht_len[n_dht++] = length; - skip(&jpeg_buffer, length); - break; - - case JPEG_MARKER_SOS: - sos = jpeg_buffer.curr - 2; /* 0xffda */ - break; - - /* skip payload-less markers */ - case JPEG_MARKER_RST ... JPEG_MARKER_RST + 7: - case JPEG_MARKER_SOI: - case JPEG_MARKER_EOI: - case JPEG_MARKER_TEM: - break; - - /* skip uninteresting payload markers */ - default: - if (get_word_be(&jpeg_buffer, &word)) - break; - length = (long)word - 2; - skip(&jpeg_buffer, length); - break; - } - } - - if (notfound || !sos || !s5p_jpeg_subsampling_decode(ctx, subsampling)) - return false; - - result->w = width; - result->h = height; - result->sos = sos; - result->dht.n = n_dht; - while (n_dht--) { - result->dht.marker[n_dht] = dht[n_dht]; - result->dht.len[n_dht] = dht_len[n_dht]; - } - result->dqt.n = n_dqt; - while (n_dqt--) { - result->dqt.marker[n_dqt] = dqt[n_dqt]; - result->dqt.len[n_dqt] = dqt_len[n_dqt]; - } - result->sof = sof; - result->sof_len = sof_len; - - return true; -} - -static int s5p_jpeg_querycap(struct file *file, void *priv, - struct v4l2_capability *cap) -{ - struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv); - - if (ctx->mode == S5P_JPEG_ENCODE) { - strscpy(cap->driver, S5P_JPEG_M2M_NAME, - sizeof(cap->driver)); - strscpy(cap->card, S5P_JPEG_M2M_NAME " encoder", - sizeof(cap->card)); - } else { - strscpy(cap->driver, S5P_JPEG_M2M_NAME, - sizeof(cap->driver)); - strscpy(cap->card, S5P_JPEG_M2M_NAME " decoder", - sizeof(cap->card)); - } - snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", - dev_name(ctx->jpeg->dev)); - return 0; -} - -static int enum_fmt(struct s5p_jpeg_ctx *ctx, - struct s5p_jpeg_fmt *sjpeg_formats, int n, - struct v4l2_fmtdesc *f, u32 type) -{ - int i, num = 0; - unsigned int fmt_ver_flag = ctx->jpeg->variant->fmt_ver_flag; - - for (i = 0; i < n; ++i) { - if (sjpeg_formats[i].flags & type && - sjpeg_formats[i].flags & fmt_ver_flag) { - /* index-th format of type type found ? */ - if (num == f->index) - break; - /* Correct type but haven't reached our index yet, - * just increment per-type index - */ - ++num; - } - } - - /* Format not found */ - if (i >= n) - return -EINVAL; - - f->pixelformat = sjpeg_formats[i].fourcc; - - return 0; -} - -static int s5p_jpeg_enum_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_fmtdesc *f) -{ - struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv); - - if (ctx->mode == S5P_JPEG_ENCODE) - return enum_fmt(ctx, sjpeg_formats, SJPEG_NUM_FORMATS, f, - SJPEG_FMT_FLAG_ENC_CAPTURE); - - return enum_fmt(ctx, sjpeg_formats, SJPEG_NUM_FORMATS, f, - SJPEG_FMT_FLAG_DEC_CAPTURE); -} - -static int s5p_jpeg_enum_fmt_vid_out(struct file *file, void *priv, - struct v4l2_fmtdesc *f) -{ - struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv); - - if (ctx->mode == S5P_JPEG_ENCODE) - return enum_fmt(ctx, sjpeg_formats, SJPEG_NUM_FORMATS, f, - SJPEG_FMT_FLAG_ENC_OUTPUT); - - return enum_fmt(ctx, sjpeg_formats, SJPEG_NUM_FORMATS, f, - SJPEG_FMT_FLAG_DEC_OUTPUT); -} - -static struct s5p_jpeg_q_data *get_q_data(struct s5p_jpeg_ctx *ctx, - enum v4l2_buf_type type) -{ - if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT) - return &ctx->out_q; - if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) - return &ctx->cap_q; - - return NULL; -} - -static int s5p_jpeg_g_fmt(struct file *file, void *priv, struct v4l2_format *f) -{ - struct vb2_queue *vq; - struct s5p_jpeg_q_data *q_data = NULL; - struct v4l2_pix_format *pix = &f->fmt.pix; - struct s5p_jpeg_ctx *ct = fh_to_ctx(priv); - - vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type); - if (!vq) - return -EINVAL; - - if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && - ct->mode == S5P_JPEG_DECODE && !ct->hdr_parsed) - return -EINVAL; - q_data = get_q_data(ct, f->type); - BUG_ON(q_data == NULL); - - pix->width = q_data->w; - pix->height = q_data->h; - pix->field = V4L2_FIELD_NONE; - pix->pixelformat = q_data->fmt->fourcc; - pix->bytesperline = 0; - if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) { - u32 bpl = q_data->w; - - if (q_data->fmt->colplanes == 1) - bpl = (bpl * q_data->fmt->depth) >> 3; - pix->bytesperline = bpl; - } - pix->sizeimage = q_data->size; - - return 0; -} - -static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx, - u32 pixelformat, unsigned int fmt_type) -{ - unsigned int k, fmt_flag; - - if (ctx->mode == S5P_JPEG_ENCODE) - fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ? - SJPEG_FMT_FLAG_ENC_OUTPUT : - SJPEG_FMT_FLAG_ENC_CAPTURE; - else - fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ? - SJPEG_FMT_FLAG_DEC_OUTPUT : - SJPEG_FMT_FLAG_DEC_CAPTURE; - - for (k = 0; k < ARRAY_SIZE(sjpeg_formats); k++) { - struct s5p_jpeg_fmt *fmt = &sjpeg_formats[k]; - - if (fmt->fourcc == pixelformat && - fmt->flags & fmt_flag && - fmt->flags & ctx->jpeg->variant->fmt_ver_flag) { - return fmt; - } - } - - return NULL; -} - -static void jpeg_bound_align_image(struct s5p_jpeg_ctx *ctx, - u32 *w, unsigned int wmin, unsigned int wmax, - unsigned int walign, - u32 *h, unsigned int hmin, unsigned int hmax, - unsigned int halign) -{ - int width, height, w_step, h_step; - - width = *w; - height = *h; - - w_step = 1 << walign; - h_step = 1 << halign; - - if (ctx->jpeg->variant->hw3250_compat) { - /* - * Rightmost and bottommost pixels are cropped by the - * Exynos3250/compatible JPEG IP for RGB formats, for the - * specific width and height values respectively. This - * assignment will result in v4l_bound_align_image returning - * dimensions reduced by 1 for the aforementioned cases. - */ - if (w_step == 4 && ((width & 3) == 1)) { - wmax = width; - hmax = height; - } - } - - v4l_bound_align_image(w, wmin, wmax, walign, h, hmin, hmax, halign, 0); - - if (*w < width && (*w + w_step) < wmax) - *w += w_step; - if (*h < height && (*h + h_step) < hmax) - *h += h_step; -} - -static int vidioc_try_fmt(struct v4l2_format *f, struct s5p_jpeg_fmt *fmt, - struct s5p_jpeg_ctx *ctx, int q_type) -{ - struct v4l2_pix_format *pix = &f->fmt.pix; - - if (pix->field == V4L2_FIELD_ANY) - pix->field = V4L2_FIELD_NONE; - else if (pix->field != V4L2_FIELD_NONE) - return -EINVAL; - - /* V4L2 specification suggests the driver corrects the format struct - * if any of the dimensions is unsupported - */ - if (q_type == FMT_TYPE_OUTPUT) - jpeg_bound_align_image(ctx, &pix->width, S5P_JPEG_MIN_WIDTH, - S5P_JPEG_MAX_WIDTH, 0, - &pix->height, S5P_JPEG_MIN_HEIGHT, - S5P_JPEG_MAX_HEIGHT, 0); - else - jpeg_bound_align_image(ctx, &pix->width, S5P_JPEG_MIN_WIDTH, - S5P_JPEG_MAX_WIDTH, fmt->h_align, - &pix->height, S5P_JPEG_MIN_HEIGHT, - S5P_JPEG_MAX_HEIGHT, fmt->v_align); - - if (fmt->fourcc == V4L2_PIX_FMT_JPEG) { - if (pix->sizeimage <= 0) - pix->sizeimage = PAGE_SIZE; - pix->bytesperline = 0; - } else { - u32 bpl = pix->bytesperline; - - if (fmt->colplanes > 1 && bpl < pix->width) - bpl = pix->width; /* planar */ - - if (fmt->colplanes == 1 && /* packed */ - (bpl << 3) / fmt->depth < pix->width) - bpl = (pix->width * fmt->depth) >> 3; - - pix->bytesperline = bpl; - pix->sizeimage = (pix->width * pix->height * fmt->depth) >> 3; - } - - return 0; -} - -static int s5p_jpeg_try_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv); - struct v4l2_pix_format *pix = &f->fmt.pix; - struct s5p_jpeg_fmt *fmt; - int ret; - - fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat, - FMT_TYPE_CAPTURE); - if (!fmt) { - v4l2_err(&ctx->jpeg->v4l2_dev, - "Fourcc format (0x%08x) invalid.\n", - f->fmt.pix.pixelformat); - return -EINVAL; - } - - if (!ctx->jpeg->variant->hw_ex4_compat || ctx->mode != S5P_JPEG_DECODE) - goto exit; - - /* - * The exynos4x12 device requires resulting YUV image - * subsampling not to be lower than the input jpeg subsampling. - * If this requirement is not met then downgrade the requested - * capture format to the one with subsampling equal to the input jpeg. - */ - if ((fmt->flags & SJPEG_FMT_NON_RGB) && - (fmt->subsampling < ctx->subsampling)) { - ret = s5p_jpeg_adjust_fourcc_to_subsampling(ctx->subsampling, - fmt->fourcc, - &pix->pixelformat, - ctx); - if (ret < 0) - pix->pixelformat = V4L2_PIX_FMT_GREY; - - fmt = s5p_jpeg_find_format(ctx, pix->pixelformat, - FMT_TYPE_CAPTURE); - } - - /* - * Decompression of a JPEG file with 4:2:0 subsampling and odd - * width to the YUV 4:2:0 compliant formats produces a raw image - * with broken luma component. Adjust capture format to RGB565 - * in such a case. - */ - if (ctx->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_420 && - (ctx->out_q.w & 1) && - (pix->pixelformat == V4L2_PIX_FMT_NV12 || - pix->pixelformat == V4L2_PIX_FMT_NV21 || - pix->pixelformat == V4L2_PIX_FMT_YUV420)) { - pix->pixelformat = V4L2_PIX_FMT_RGB565; - fmt = s5p_jpeg_find_format(ctx, pix->pixelformat, - FMT_TYPE_CAPTURE); - } - -exit: - return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_CAPTURE); -} - -static int s5p_jpeg_try_fmt_vid_out(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv); - struct s5p_jpeg_fmt *fmt; - - fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat, - FMT_TYPE_OUTPUT); - if (!fmt) { - v4l2_err(&ctx->jpeg->v4l2_dev, - "Fourcc format (0x%08x) invalid.\n", - f->fmt.pix.pixelformat); - return -EINVAL; - } - - return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_OUTPUT); -} - -static int exynos4_jpeg_get_output_buffer_size(struct s5p_jpeg_ctx *ctx, - struct v4l2_format *f, - int fmt_depth) -{ - struct v4l2_pix_format *pix = &f->fmt.pix; - u32 pix_fmt = f->fmt.pix.pixelformat; - int w = pix->width, h = pix->height, wh_align; - int padding = 0; - - if (pix_fmt == V4L2_PIX_FMT_RGB32 || - pix_fmt == V4L2_PIX_FMT_RGB565 || - pix_fmt == V4L2_PIX_FMT_NV24 || - pix_fmt == V4L2_PIX_FMT_NV42 || - pix_fmt == V4L2_PIX_FMT_NV12 || - pix_fmt == V4L2_PIX_FMT_NV21 || - pix_fmt == V4L2_PIX_FMT_YUV420) - wh_align = 4; - else - wh_align = 1; - - jpeg_bound_align_image(ctx, &w, S5P_JPEG_MIN_WIDTH, - S5P_JPEG_MAX_WIDTH, wh_align, - &h, S5P_JPEG_MIN_HEIGHT, - S5P_JPEG_MAX_HEIGHT, wh_align); - - if (ctx->jpeg->variant->version == SJPEG_EXYNOS4) - padding = PAGE_SIZE; - - return (w * h * fmt_depth >> 3) + padding; -} - -static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx *ctx, - struct v4l2_rect *r); - -static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f) -{ - struct vb2_queue *vq; - struct s5p_jpeg_q_data *q_data = NULL; - struct v4l2_pix_format *pix = &f->fmt.pix; - struct v4l2_ctrl *ctrl_subs; - struct v4l2_rect scale_rect; - unsigned int f_type; - - vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type); - if (!vq) - return -EINVAL; - - q_data = get_q_data(ct, f->type); - BUG_ON(q_data == NULL); - - if (vb2_is_busy(vq)) { - v4l2_err(&ct->jpeg->v4l2_dev, "%s queue busy\n", __func__); - return -EBUSY; - } - - f_type = V4L2_TYPE_IS_OUTPUT(f->type) ? - FMT_TYPE_OUTPUT : FMT_TYPE_CAPTURE; - - q_data->fmt = s5p_jpeg_find_format(ct, pix->pixelformat, f_type); - if (ct->mode == S5P_JPEG_ENCODE || - (ct->mode == S5P_JPEG_DECODE && - q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG)) { - q_data->w = pix->width; - q_data->h = pix->height; - } - if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) { - /* - * During encoding Exynos4x12 SoCs access wider memory area - * than it results from Image_x and Image_y values written to - * the JPEG_IMAGE_SIZE register. In order to avoid sysmmu - * page fault calculate proper buffer size in such a case. - */ - if (ct->jpeg->variant->hw_ex4_compat && - f_type == FMT_TYPE_OUTPUT && ct->mode == S5P_JPEG_ENCODE) - q_data->size = exynos4_jpeg_get_output_buffer_size(ct, - f, - q_data->fmt->depth); - else - q_data->size = q_data->w * q_data->h * - q_data->fmt->depth >> 3; - } else { - q_data->size = pix->sizeimage; - } - - if (f_type == FMT_TYPE_OUTPUT) { - ctrl_subs = v4l2_ctrl_find(&ct->ctrl_handler, - V4L2_CID_JPEG_CHROMA_SUBSAMPLING); - if (ctrl_subs) - v4l2_ctrl_s_ctrl(ctrl_subs, q_data->fmt->subsampling); - ct->crop_altered = false; - } - - /* - * For decoding init crop_rect with capture buffer dimmensions which - * contain aligned dimensions of the input JPEG image and do it only - * if crop rectangle hasn't been altered by the user space e.g. with - * S_SELECTION ioctl. For encoding assign output buffer dimensions. - */ - if (!ct->crop_altered && - ((ct->mode == S5P_JPEG_DECODE && f_type == FMT_TYPE_CAPTURE) || - (ct->mode == S5P_JPEG_ENCODE && f_type == FMT_TYPE_OUTPUT))) { - ct->crop_rect.width = pix->width; - ct->crop_rect.height = pix->height; - } - - /* - * Prevent downscaling to YUV420 format by more than 2 - * for Exynos3250/compatible SoC as it produces broken raw image - * in such cases. - */ - if (ct->mode == S5P_JPEG_DECODE && - f_type == FMT_TYPE_CAPTURE && - ct->jpeg->variant->hw3250_compat && - pix->pixelformat == V4L2_PIX_FMT_YUV420 && - ct->scale_factor > 2) { - scale_rect.width = ct->out_q.w / 2; - scale_rect.height = ct->out_q.h / 2; - exynos3250_jpeg_try_downscale(ct, &scale_rect); - } - - return 0; -} - -static int s5p_jpeg_s_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - int ret; - - ret = s5p_jpeg_try_fmt_vid_cap(file, priv, f); - if (ret) - return ret; - - return s5p_jpeg_s_fmt(fh_to_ctx(priv), f); -} - -static int s5p_jpeg_s_fmt_vid_out(struct file *file, void *priv, - struct v4l2_format *f) -{ - int ret; - - ret = s5p_jpeg_try_fmt_vid_out(file, priv, f); - if (ret) - return ret; - - return s5p_jpeg_s_fmt(fh_to_ctx(priv), f); -} - -static int s5p_jpeg_subscribe_event(struct v4l2_fh *fh, - const struct v4l2_event_subscription *sub) -{ - if (sub->type == V4L2_EVENT_SOURCE_CHANGE) - return v4l2_src_change_event_subscribe(fh, sub); - - return -EINVAL; -} - -static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx *ctx, - struct v4l2_rect *r) -{ - int w_ratio, h_ratio, scale_factor, cur_ratio, i; - - w_ratio = ctx->out_q.w / r->width; - h_ratio = ctx->out_q.h / r->height; - - scale_factor = w_ratio > h_ratio ? w_ratio : h_ratio; - scale_factor = clamp_val(scale_factor, 1, 8); - - /* Align scale ratio to the nearest power of 2 */ - for (i = 0; i <= 3; ++i) { - cur_ratio = 1 << i; - if (scale_factor <= cur_ratio) { - ctx->scale_factor = cur_ratio; - break; - } - } - - r->width = round_down(ctx->out_q.w / ctx->scale_factor, 2); - r->height = round_down(ctx->out_q.h / ctx->scale_factor, 2); - - ctx->crop_rect.width = r->width; - ctx->crop_rect.height = r->height; - ctx->crop_rect.left = 0; - ctx->crop_rect.top = 0; - - ctx->crop_altered = true; - - return 0; -} - -static int exynos3250_jpeg_try_crop(struct s5p_jpeg_ctx *ctx, - struct v4l2_rect *r) -{ - struct v4l2_rect base_rect; - int w_step, h_step; - - switch (ctx->cap_q.fmt->fourcc) { - case V4L2_PIX_FMT_NV12: - case V4L2_PIX_FMT_NV21: - w_step = 1; - h_step = 2; - break; - case V4L2_PIX_FMT_YUV420: - w_step = 2; - h_step = 2; - break; - default: - w_step = 1; - h_step = 1; - break; - } - - base_rect.top = 0; - base_rect.left = 0; - base_rect.width = ctx->out_q.w; - base_rect.height = ctx->out_q.h; - - r->width = round_down(r->width, w_step); - r->height = round_down(r->height, h_step); - r->left = round_down(r->left, 2); - r->top = round_down(r->top, 2); - - if (!v4l2_rect_enclosed(r, &base_rect)) - return -EINVAL; - - ctx->crop_rect.left = r->left; - ctx->crop_rect.top = r->top; - ctx->crop_rect.width = r->width; - ctx->crop_rect.height = r->height; - - ctx->crop_altered = true; - - return 0; -} - -/* - * V4L2 controls - */ - -static int s5p_jpeg_g_selection(struct file *file, void *priv, - struct v4l2_selection *s) -{ - struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv); - - if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && - s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - /* For JPEG blob active == default == bounds */ - switch (s->target) { - case V4L2_SEL_TGT_CROP: - case V4L2_SEL_TGT_CROP_BOUNDS: - case V4L2_SEL_TGT_CROP_DEFAULT: - case V4L2_SEL_TGT_COMPOSE_DEFAULT: - s->r.width = ctx->out_q.w; - s->r.height = ctx->out_q.h; - s->r.left = 0; - s->r.top = 0; - break; - case V4L2_SEL_TGT_COMPOSE: - case V4L2_SEL_TGT_COMPOSE_BOUNDS: - case V4L2_SEL_TGT_COMPOSE_PADDED: - s->r.width = ctx->crop_rect.width; - s->r.height = ctx->crop_rect.height; - s->r.left = ctx->crop_rect.left; - s->r.top = ctx->crop_rect.top; - break; - default: - return -EINVAL; - } - return 0; -} - -/* - * V4L2 controls - */ -static int s5p_jpeg_s_selection(struct file *file, void *fh, - struct v4l2_selection *s) -{ - struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data); - struct v4l2_rect *rect = &s->r; - int ret = -EINVAL; - - if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - if (s->target == V4L2_SEL_TGT_COMPOSE) { - if (ctx->mode != S5P_JPEG_DECODE) - return -EINVAL; - if (ctx->jpeg->variant->hw3250_compat) - ret = exynos3250_jpeg_try_downscale(ctx, rect); - } else if (s->target == V4L2_SEL_TGT_CROP) { - if (ctx->mode != S5P_JPEG_ENCODE) - return -EINVAL; - if (ctx->jpeg->variant->hw3250_compat) - ret = exynos3250_jpeg_try_crop(ctx, rect); - } - - return ret; -} - -static int s5p_jpeg_g_volatile_ctrl(struct v4l2_ctrl *ctrl) -{ - struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl); - struct s5p_jpeg *jpeg = ctx->jpeg; - unsigned long flags; - - switch (ctrl->id) { - case V4L2_CID_JPEG_CHROMA_SUBSAMPLING: - spin_lock_irqsave(&jpeg->slock, flags); - ctrl->val = s5p_jpeg_to_user_subsampling(ctx); - spin_unlock_irqrestore(&jpeg->slock, flags); - break; - } - - return 0; -} - -static int s5p_jpeg_adjust_subs_ctrl(struct s5p_jpeg_ctx *ctx, int *ctrl_val) -{ - switch (ctx->jpeg->variant->version) { - case SJPEG_S5P: - return 0; - case SJPEG_EXYNOS3250: - case SJPEG_EXYNOS5420: - /* - * The exynos3250/compatible device can produce JPEG image only - * of 4:4:4 subsampling when given RGB32 source image. - */ - if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB32) - *ctrl_val = 0; - break; - case SJPEG_EXYNOS4: - /* - * The exynos4x12 device requires input raw image fourcc - * to be V4L2_PIX_FMT_GREY if gray jpeg format - * is to be set. - */ - if (ctx->out_q.fmt->fourcc != V4L2_PIX_FMT_GREY && - *ctrl_val == V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY) - return -EINVAL; - break; - } - - /* - * The exynos4x12 and exynos3250/compatible devices require resulting - * jpeg subsampling not to be lower than the input raw image - * subsampling. - */ - if (ctx->out_q.fmt->subsampling > *ctrl_val) - *ctrl_val = ctx->out_q.fmt->subsampling; - - return 0; -} - -static int s5p_jpeg_try_ctrl(struct v4l2_ctrl *ctrl) -{ - struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl); - unsigned long flags; - int ret = 0; - - spin_lock_irqsave(&ctx->jpeg->slock, flags); - - if (ctrl->id == V4L2_CID_JPEG_CHROMA_SUBSAMPLING) - ret = s5p_jpeg_adjust_subs_ctrl(ctx, &ctrl->val); - - spin_unlock_irqrestore(&ctx->jpeg->slock, flags); - return ret; -} - -static int s5p_jpeg_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl); - unsigned long flags; - - spin_lock_irqsave(&ctx->jpeg->slock, flags); - - switch (ctrl->id) { - case V4L2_CID_JPEG_COMPRESSION_QUALITY: - ctx->compr_quality = ctrl->val; - break; - case V4L2_CID_JPEG_RESTART_INTERVAL: - ctx->restart_interval = ctrl->val; - break; - case V4L2_CID_JPEG_CHROMA_SUBSAMPLING: - ctx->subsampling = ctrl->val; - break; - } - - spin_unlock_irqrestore(&ctx->jpeg->slock, flags); - return 0; -} - -static const struct v4l2_ctrl_ops s5p_jpeg_ctrl_ops = { - .g_volatile_ctrl = s5p_jpeg_g_volatile_ctrl, - .try_ctrl = s5p_jpeg_try_ctrl, - .s_ctrl = s5p_jpeg_s_ctrl, -}; - -static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx) -{ - unsigned int mask = ~0x27; /* 444, 422, 420, GRAY */ - struct v4l2_ctrl *ctrl; - int ret; - - v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3); - - if (ctx->mode == S5P_JPEG_ENCODE) { - v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops, - V4L2_CID_JPEG_COMPRESSION_QUALITY, - 0, 3, 1, S5P_JPEG_COMPR_QUAL_WORST); - - v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops, - V4L2_CID_JPEG_RESTART_INTERVAL, - 0, 0xffff, 1, 0); - if (ctx->jpeg->variant->version == SJPEG_S5P) - mask = ~0x06; /* 422, 420 */ - } - - ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops, - V4L2_CID_JPEG_CHROMA_SUBSAMPLING, - V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY, mask, - V4L2_JPEG_CHROMA_SUBSAMPLING_422); - - if (ctx->ctrl_handler.error) { - ret = ctx->ctrl_handler.error; - goto error_free; - } - - if (ctx->mode == S5P_JPEG_DECODE) - ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE | - V4L2_CTRL_FLAG_READ_ONLY; - - ret = v4l2_ctrl_handler_setup(&ctx->ctrl_handler); - if (ret < 0) - goto error_free; - - return ret; - -error_free: - v4l2_ctrl_handler_free(&ctx->ctrl_handler); - return ret; -} - -static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = { - .vidioc_querycap = s5p_jpeg_querycap, - - .vidioc_enum_fmt_vid_cap = s5p_jpeg_enum_fmt_vid_cap, - .vidioc_enum_fmt_vid_out = s5p_jpeg_enum_fmt_vid_out, - - .vidioc_g_fmt_vid_cap = s5p_jpeg_g_fmt, - .vidioc_g_fmt_vid_out = s5p_jpeg_g_fmt, - - .vidioc_try_fmt_vid_cap = s5p_jpeg_try_fmt_vid_cap, - .vidioc_try_fmt_vid_out = s5p_jpeg_try_fmt_vid_out, - - .vidioc_s_fmt_vid_cap = s5p_jpeg_s_fmt_vid_cap, - .vidioc_s_fmt_vid_out = s5p_jpeg_s_fmt_vid_out, - - .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, - .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, - .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, - .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, - - .vidioc_streamon = v4l2_m2m_ioctl_streamon, - .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, - - .vidioc_g_selection = s5p_jpeg_g_selection, - .vidioc_s_selection = s5p_jpeg_s_selection, - - .vidioc_subscribe_event = s5p_jpeg_subscribe_event, - .vidioc_unsubscribe_event = v4l2_event_unsubscribe, -}; - -/* - * ============================================================================ - * mem2mem callbacks - * ============================================================================ - */ - -static void s5p_jpeg_device_run(void *priv) -{ - struct s5p_jpeg_ctx *ctx = priv; - struct s5p_jpeg *jpeg = ctx->jpeg; - struct vb2_v4l2_buffer *src_buf, *dst_buf; - unsigned long src_addr, dst_addr, flags; - - spin_lock_irqsave(&ctx->jpeg->slock, flags); - - src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); - dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); - src_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0); - dst_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0); - - s5p_jpeg_reset(jpeg->regs); - s5p_jpeg_poweron(jpeg->regs); - s5p_jpeg_proc_mode(jpeg->regs, ctx->mode); - if (ctx->mode == S5P_JPEG_ENCODE) { - if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565) - s5p_jpeg_input_raw_mode(jpeg->regs, - S5P_JPEG_RAW_IN_565); - else - s5p_jpeg_input_raw_mode(jpeg->regs, - S5P_JPEG_RAW_IN_422); - s5p_jpeg_subsampling_mode(jpeg->regs, ctx->subsampling); - s5p_jpeg_dri(jpeg->regs, ctx->restart_interval); - s5p_jpeg_x(jpeg->regs, ctx->out_q.w); - s5p_jpeg_y(jpeg->regs, ctx->out_q.h); - s5p_jpeg_imgadr(jpeg->regs, src_addr); - s5p_jpeg_jpgadr(jpeg->regs, dst_addr); - - /* ultimately comes from sizeimage from userspace */ - s5p_jpeg_enc_stream_int(jpeg->regs, ctx->cap_q.size); - - /* JPEG RGB to YCbCr conversion matrix */ - s5p_jpeg_coef(jpeg->regs, 1, 1, S5P_JPEG_COEF11); - s5p_jpeg_coef(jpeg->regs, 1, 2, S5P_JPEG_COEF12); - s5p_jpeg_coef(jpeg->regs, 1, 3, S5P_JPEG_COEF13); - s5p_jpeg_coef(jpeg->regs, 2, 1, S5P_JPEG_COEF21); - s5p_jpeg_coef(jpeg->regs, 2, 2, S5P_JPEG_COEF22); - s5p_jpeg_coef(jpeg->regs, 2, 3, S5P_JPEG_COEF23); - s5p_jpeg_coef(jpeg->regs, 3, 1, S5P_JPEG_COEF31); - s5p_jpeg_coef(jpeg->regs, 3, 2, S5P_JPEG_COEF32); - s5p_jpeg_coef(jpeg->regs, 3, 3, S5P_JPEG_COEF33); - - /* - * JPEG IP allows storing 4 quantization tables - * We fill table 0 for luma and table 1 for chroma - */ - s5p_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality); - s5p_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality); - /* use table 0 for Y */ - s5p_jpeg_qtbl(jpeg->regs, 1, 0); - /* use table 1 for Cb and Cr*/ - s5p_jpeg_qtbl(jpeg->regs, 2, 1); - s5p_jpeg_qtbl(jpeg->regs, 3, 1); - - /* Y, Cb, Cr use Huffman table 0 */ - s5p_jpeg_htbl_ac(jpeg->regs, 1); - s5p_jpeg_htbl_dc(jpeg->regs, 1); - s5p_jpeg_htbl_ac(jpeg->regs, 2); - s5p_jpeg_htbl_dc(jpeg->regs, 2); - s5p_jpeg_htbl_ac(jpeg->regs, 3); - s5p_jpeg_htbl_dc(jpeg->regs, 3); - } else { /* S5P_JPEG_DECODE */ - s5p_jpeg_rst_int_enable(jpeg->regs, true); - s5p_jpeg_data_num_int_enable(jpeg->regs, true); - s5p_jpeg_final_mcu_num_int_enable(jpeg->regs, true); - if (ctx->cap_q.fmt->fourcc == V4L2_PIX_FMT_YUYV) - s5p_jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_422); - else - s5p_jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_420); - s5p_jpeg_jpgadr(jpeg->regs, src_addr); - s5p_jpeg_imgadr(jpeg->regs, dst_addr); - } - - s5p_jpeg_start(jpeg->regs); - - spin_unlock_irqrestore(&ctx->jpeg->slock, flags); -} - -static void exynos4_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx) -{ - struct s5p_jpeg *jpeg = ctx->jpeg; - struct s5p_jpeg_fmt *fmt; - struct vb2_v4l2_buffer *vb; - struct s5p_jpeg_addr jpeg_addr = {}; - u32 pix_size, padding_bytes = 0; - - jpeg_addr.cb = 0; - jpeg_addr.cr = 0; - - pix_size = ctx->cap_q.w * ctx->cap_q.h; - - if (ctx->mode == S5P_JPEG_ENCODE) { - vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); - fmt = ctx->out_q.fmt; - if (ctx->out_q.w % 2 && fmt->h_align > 0) - padding_bytes = ctx->out_q.h; - } else { - fmt = ctx->cap_q.fmt; - vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); - } - - jpeg_addr.y = vb2_dma_contig_plane_dma_addr(&vb->vb2_buf, 0); - - if (fmt->colplanes == 2) { - jpeg_addr.cb = jpeg_addr.y + pix_size - padding_bytes; - } else if (fmt->colplanes == 3) { - jpeg_addr.cb = jpeg_addr.y + pix_size; - if (fmt->fourcc == V4L2_PIX_FMT_YUV420) - jpeg_addr.cr = jpeg_addr.cb + pix_size / 4; - else - jpeg_addr.cr = jpeg_addr.cb + pix_size / 2; - } - - exynos4_jpeg_set_frame_buf_address(jpeg->regs, &jpeg_addr); -} - -static void exynos4_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx) -{ - struct s5p_jpeg *jpeg = ctx->jpeg; - struct vb2_v4l2_buffer *vb; - unsigned int jpeg_addr = 0; - - if (ctx->mode == S5P_JPEG_ENCODE) - vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); - else - vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); - - jpeg_addr = vb2_dma_contig_plane_dma_addr(&vb->vb2_buf, 0); - if (jpeg->variant->version == SJPEG_EXYNOS5433 && - ctx->mode == S5P_JPEG_DECODE) - jpeg_addr += ctx->out_q.sos; - exynos4_jpeg_set_stream_buf_address(jpeg->regs, jpeg_addr); -} - -static inline void exynos4_jpeg_set_img_fmt(void __iomem *base, - unsigned int img_fmt) -{ - __exynos4_jpeg_set_img_fmt(base, img_fmt, SJPEG_EXYNOS4); -} - -static inline void exynos5433_jpeg_set_img_fmt(void __iomem *base, - unsigned int img_fmt) -{ - __exynos4_jpeg_set_img_fmt(base, img_fmt, SJPEG_EXYNOS5433); -} - -static inline void exynos4_jpeg_set_enc_out_fmt(void __iomem *base, - unsigned int out_fmt) -{ - __exynos4_jpeg_set_enc_out_fmt(base, out_fmt, SJPEG_EXYNOS4); -} - -static inline void exynos5433_jpeg_set_enc_out_fmt(void __iomem *base, - unsigned int out_fmt) -{ - __exynos4_jpeg_set_enc_out_fmt(base, out_fmt, SJPEG_EXYNOS5433); -} - -static void exynos4_jpeg_device_run(void *priv) -{ - struct s5p_jpeg_ctx *ctx = priv; - struct s5p_jpeg *jpeg = ctx->jpeg; - unsigned int bitstream_size; - unsigned long flags; - - spin_lock_irqsave(&jpeg->slock, flags); - - if (ctx->mode == S5P_JPEG_ENCODE) { - exynos4_jpeg_sw_reset(jpeg->regs); - exynos4_jpeg_set_interrupt(jpeg->regs, jpeg->variant->version); - exynos4_jpeg_set_huf_table_enable(jpeg->regs, 1); - - exynos4_jpeg_set_huff_tbl(jpeg->regs); - - /* - * JPEG IP allows storing 4 quantization tables - * We fill table 0 for luma and table 1 for chroma - */ - exynos4_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality); - exynos4_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality); - - exynos4_jpeg_set_encode_tbl_select(jpeg->regs, - ctx->compr_quality); - exynos4_jpeg_set_stream_size(jpeg->regs, ctx->cap_q.w, - ctx->cap_q.h); - - if (ctx->jpeg->variant->version == SJPEG_EXYNOS4) { - exynos4_jpeg_set_enc_out_fmt(jpeg->regs, - ctx->subsampling); - exynos4_jpeg_set_img_fmt(jpeg->regs, - ctx->out_q.fmt->fourcc); - } else { - exynos5433_jpeg_set_enc_out_fmt(jpeg->regs, - ctx->subsampling); - exynos5433_jpeg_set_img_fmt(jpeg->regs, - ctx->out_q.fmt->fourcc); - } - exynos4_jpeg_set_img_addr(ctx); - exynos4_jpeg_set_jpeg_addr(ctx); - exynos4_jpeg_set_encode_hoff_cnt(jpeg->regs, - ctx->out_q.fmt->fourcc); - } else { - exynos4_jpeg_sw_reset(jpeg->regs); - exynos4_jpeg_set_interrupt(jpeg->regs, - jpeg->variant->version); - exynos4_jpeg_set_img_addr(ctx); - exynos4_jpeg_set_jpeg_addr(ctx); - - if (jpeg->variant->version == SJPEG_EXYNOS5433) { - exynos4_jpeg_parse_huff_tbl(ctx); - exynos4_jpeg_parse_decode_h_tbl(ctx); - - exynos4_jpeg_parse_q_tbl(ctx); - exynos4_jpeg_parse_decode_q_tbl(ctx); - - exynos4_jpeg_set_huf_table_enable(jpeg->regs, 1); - - exynos4_jpeg_set_stream_size(jpeg->regs, ctx->cap_q.w, - ctx->cap_q.h); - exynos5433_jpeg_set_enc_out_fmt(jpeg->regs, - ctx->subsampling); - exynos5433_jpeg_set_img_fmt(jpeg->regs, - ctx->cap_q.fmt->fourcc); - bitstream_size = DIV_ROUND_UP(ctx->out_q.size, 16); - } else { - exynos4_jpeg_set_img_fmt(jpeg->regs, - ctx->cap_q.fmt->fourcc); - bitstream_size = DIV_ROUND_UP(ctx->out_q.size, 32); - } - - exynos4_jpeg_set_dec_bitstream_size(jpeg->regs, bitstream_size); - } - - exynos4_jpeg_set_sys_int_enable(jpeg->regs, 1); - exynos4_jpeg_set_enc_dec_mode(jpeg->regs, ctx->mode); - - spin_unlock_irqrestore(&jpeg->slock, flags); -} - -static void exynos3250_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx) -{ - struct s5p_jpeg *jpeg = ctx->jpeg; - struct s5p_jpeg_fmt *fmt; - struct vb2_v4l2_buffer *vb; - struct s5p_jpeg_addr jpeg_addr = {}; - u32 pix_size; - - pix_size = ctx->cap_q.w * ctx->cap_q.h; - - if (ctx->mode == S5P_JPEG_ENCODE) { - vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); - fmt = ctx->out_q.fmt; - } else { - vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); - fmt = ctx->cap_q.fmt; - } - - jpeg_addr.y = vb2_dma_contig_plane_dma_addr(&vb->vb2_buf, 0); - - if (fmt->colplanes == 2) { - jpeg_addr.cb = jpeg_addr.y + pix_size; - } else if (fmt->colplanes == 3) { - jpeg_addr.cb = jpeg_addr.y + pix_size; - if (fmt->fourcc == V4L2_PIX_FMT_YUV420) - jpeg_addr.cr = jpeg_addr.cb + pix_size / 4; - else - jpeg_addr.cr = jpeg_addr.cb + pix_size / 2; - } - - exynos3250_jpeg_imgadr(jpeg->regs, &jpeg_addr); -} - -static void exynos3250_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx) -{ - struct s5p_jpeg *jpeg = ctx->jpeg; - struct vb2_v4l2_buffer *vb; - unsigned int jpeg_addr = 0; - - if (ctx->mode == S5P_JPEG_ENCODE) - vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); - else - vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); - - jpeg_addr = vb2_dma_contig_plane_dma_addr(&vb->vb2_buf, 0); - exynos3250_jpeg_jpgadr(jpeg->regs, jpeg_addr); -} - -static void exynos3250_jpeg_device_run(void *priv) -{ - struct s5p_jpeg_ctx *ctx = priv; - struct s5p_jpeg *jpeg = ctx->jpeg; - unsigned long flags; - - spin_lock_irqsave(&ctx->jpeg->slock, flags); - - exynos3250_jpeg_reset(jpeg->regs); - exynos3250_jpeg_set_dma_num(jpeg->regs); - exynos3250_jpeg_poweron(jpeg->regs); - exynos3250_jpeg_clk_set(jpeg->regs); - exynos3250_jpeg_proc_mode(jpeg->regs, ctx->mode); - - if (ctx->mode == S5P_JPEG_ENCODE) { - exynos3250_jpeg_input_raw_fmt(jpeg->regs, - ctx->out_q.fmt->fourcc); - exynos3250_jpeg_dri(jpeg->regs, ctx->restart_interval); - - /* - * JPEG IP allows storing 4 quantization tables - * We fill table 0 for luma and table 1 for chroma - */ - s5p_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality); - s5p_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality); - /* use table 0 for Y */ - exynos3250_jpeg_qtbl(jpeg->regs, 1, 0); - /* use table 1 for Cb and Cr*/ - exynos3250_jpeg_qtbl(jpeg->regs, 2, 1); - exynos3250_jpeg_qtbl(jpeg->regs, 3, 1); - - /* - * Some SoCs require setting Huffman tables before each run - */ - if (jpeg->variant->htbl_reinit) { - s5p_jpeg_set_hdctbl(jpeg->regs); - s5p_jpeg_set_hdctblg(jpeg->regs); - s5p_jpeg_set_hactbl(jpeg->regs); - s5p_jpeg_set_hactblg(jpeg->regs); - } - - /* Y, Cb, Cr use Huffman table 0 */ - exynos3250_jpeg_htbl_ac(jpeg->regs, 1); - exynos3250_jpeg_htbl_dc(jpeg->regs, 1); - exynos3250_jpeg_htbl_ac(jpeg->regs, 2); - exynos3250_jpeg_htbl_dc(jpeg->regs, 2); - exynos3250_jpeg_htbl_ac(jpeg->regs, 3); - exynos3250_jpeg_htbl_dc(jpeg->regs, 3); - - exynos3250_jpeg_set_x(jpeg->regs, ctx->crop_rect.width); - exynos3250_jpeg_set_y(jpeg->regs, ctx->crop_rect.height); - exynos3250_jpeg_stride(jpeg->regs, ctx->out_q.fmt->fourcc, - ctx->out_q.w); - exynos3250_jpeg_offset(jpeg->regs, ctx->crop_rect.left, - ctx->crop_rect.top); - exynos3250_jpeg_set_img_addr(ctx); - exynos3250_jpeg_set_jpeg_addr(ctx); - exynos3250_jpeg_subsampling_mode(jpeg->regs, ctx->subsampling); - - /* ultimately comes from sizeimage from userspace */ - exynos3250_jpeg_enc_stream_bound(jpeg->regs, ctx->cap_q.size); - - if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565 || - ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565X || - ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB32) - exynos3250_jpeg_set_y16(jpeg->regs, true); - } else { - exynos3250_jpeg_set_img_addr(ctx); - exynos3250_jpeg_set_jpeg_addr(ctx); - exynos3250_jpeg_stride(jpeg->regs, ctx->cap_q.fmt->fourcc, - ctx->cap_q.w); - exynos3250_jpeg_offset(jpeg->regs, 0, 0); - exynos3250_jpeg_dec_scaling_ratio(jpeg->regs, - ctx->scale_factor); - exynos3250_jpeg_dec_stream_size(jpeg->regs, ctx->out_q.size); - exynos3250_jpeg_output_raw_fmt(jpeg->regs, - ctx->cap_q.fmt->fourcc); - } - - exynos3250_jpeg_interrupts_enable(jpeg->regs); - - /* JPEG RGB to YCbCr conversion matrix */ - exynos3250_jpeg_coef(jpeg->regs, ctx->mode); - - exynos3250_jpeg_set_timer(jpeg->regs, EXYNOS3250_IRQ_TIMEOUT); - jpeg->irq_status = 0; - exynos3250_jpeg_start(jpeg->regs); - - spin_unlock_irqrestore(&ctx->jpeg->slock, flags); -} - -static int s5p_jpeg_job_ready(void *priv) -{ - struct s5p_jpeg_ctx *ctx = priv; - - if (ctx->mode == S5P_JPEG_DECODE) { - /* - * We have only one input buffer and one output buffer. If there - * is a resolution change event, no need to continue decoding. - */ - if (ctx->state == JPEGCTX_RESOLUTION_CHANGE) - return 0; - - return ctx->hdr_parsed; - } - - return 1; -} - -static const struct v4l2_m2m_ops s5p_jpeg_m2m_ops = { - .device_run = s5p_jpeg_device_run, - .job_ready = s5p_jpeg_job_ready, -}; - -static const struct v4l2_m2m_ops exynos3250_jpeg_m2m_ops = { - .device_run = exynos3250_jpeg_device_run, - .job_ready = s5p_jpeg_job_ready, -}; - -static const struct v4l2_m2m_ops exynos4_jpeg_m2m_ops = { - .device_run = exynos4_jpeg_device_run, - .job_ready = s5p_jpeg_job_ready, -}; - -/* - * ============================================================================ - * Queue operations - * ============================================================================ - */ - -static int s5p_jpeg_queue_setup(struct vb2_queue *vq, - unsigned int *nbuffers, unsigned int *nplanes, - unsigned int sizes[], struct device *alloc_devs[]) -{ - struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq); - struct s5p_jpeg_q_data *q_data = NULL; - unsigned int size, count = *nbuffers; - - q_data = get_q_data(ctx, vq->type); - BUG_ON(q_data == NULL); - - size = q_data->size; - - /* - * header is parsed during decoding and parsed information stored - * in the context so we do not allow another buffer to overwrite it - */ - if (ctx->mode == S5P_JPEG_DECODE) - count = 1; - - *nbuffers = count; - *nplanes = 1; - sizes[0] = size; - - return 0; -} - -static int s5p_jpeg_buf_prepare(struct vb2_buffer *vb) -{ - struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); - struct s5p_jpeg_q_data *q_data = NULL; - - q_data = get_q_data(ctx, vb->vb2_queue->type); - BUG_ON(q_data == NULL); - - if (vb2_plane_size(vb, 0) < q_data->size) { - pr_err("%s data will not fit into plane (%lu < %lu)\n", - __func__, vb2_plane_size(vb, 0), - (long)q_data->size); - return -EINVAL; - } - - vb2_set_plane_payload(vb, 0, q_data->size); - - return 0; -} - -static void s5p_jpeg_set_capture_queue_data(struct s5p_jpeg_ctx *ctx) -{ - struct s5p_jpeg_q_data *q_data = &ctx->cap_q; - - q_data->w = ctx->out_q.w; - q_data->h = ctx->out_q.h; - - /* - * This call to jpeg_bound_align_image() takes care of width and - * height values alignment when user space calls the QBUF of - * OUTPUT buffer after the S_FMT of CAPTURE buffer. - * Please note that on Exynos4x12 SoCs, resigning from executing - * S_FMT on capture buffer for each JPEG image can result in a - * hardware hangup if subsampling is lower than the one of input - * JPEG. - */ - jpeg_bound_align_image(ctx, &q_data->w, S5P_JPEG_MIN_WIDTH, - S5P_JPEG_MAX_WIDTH, q_data->fmt->h_align, - &q_data->h, S5P_JPEG_MIN_HEIGHT, - S5P_JPEG_MAX_HEIGHT, q_data->fmt->v_align); - - q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3; -} - -static void s5p_jpeg_buf_queue(struct vb2_buffer *vb) -{ - struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); - struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); - - if (ctx->mode == S5P_JPEG_DECODE && - vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { - static const struct v4l2_event ev_src_ch = { - .type = V4L2_EVENT_SOURCE_CHANGE, - .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION, - }; - struct vb2_queue *dst_vq; - u32 ori_w; - u32 ori_h; - - dst_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, - V4L2_BUF_TYPE_VIDEO_CAPTURE); - ori_w = ctx->out_q.w; - ori_h = ctx->out_q.h; - - ctx->hdr_parsed = s5p_jpeg_parse_hdr(&ctx->out_q, - (unsigned long)vb2_plane_vaddr(vb, 0), - min((unsigned long)ctx->out_q.size, - vb2_get_plane_payload(vb, 0)), ctx); - if (!ctx->hdr_parsed) { - vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); - return; - } - - /* - * If there is a resolution change event, only update capture - * queue when it is not streaming. Otherwise, update it in - * STREAMOFF. See s5p_jpeg_stop_streaming for detail. - */ - if (ctx->out_q.w != ori_w || ctx->out_q.h != ori_h) { - v4l2_event_queue_fh(&ctx->fh, &ev_src_ch); - if (vb2_is_streaming(dst_vq)) - ctx->state = JPEGCTX_RESOLUTION_CHANGE; - else - s5p_jpeg_set_capture_queue_data(ctx); - } - } - - v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); -} - -static int s5p_jpeg_start_streaming(struct vb2_queue *q, unsigned int count) -{ - struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q); - - return pm_runtime_resume_and_get(ctx->jpeg->dev); -} - -static void s5p_jpeg_stop_streaming(struct vb2_queue *q) -{ - struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q); - - /* - * STREAMOFF is an acknowledgment for resolution change event. - * Before STREAMOFF, we still have to return the old resolution and - * subsampling. Update capture queue when the stream is off. - */ - if (ctx->state == JPEGCTX_RESOLUTION_CHANGE && - q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { - s5p_jpeg_set_capture_queue_data(ctx); - ctx->state = JPEGCTX_RUNNING; - } - - pm_runtime_put(ctx->jpeg->dev); -} - -static const struct vb2_ops s5p_jpeg_qops = { - .queue_setup = s5p_jpeg_queue_setup, - .buf_prepare = s5p_jpeg_buf_prepare, - .buf_queue = s5p_jpeg_buf_queue, - .wait_prepare = vb2_ops_wait_prepare, - .wait_finish = vb2_ops_wait_finish, - .start_streaming = s5p_jpeg_start_streaming, - .stop_streaming = s5p_jpeg_stop_streaming, -}; - -static int queue_init(void *priv, struct vb2_queue *src_vq, - struct vb2_queue *dst_vq) -{ - struct s5p_jpeg_ctx *ctx = priv; - int ret; - - src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; - src_vq->io_modes = VB2_MMAP | VB2_USERPTR; - src_vq->drv_priv = ctx; - src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); - src_vq->ops = &s5p_jpeg_qops; - src_vq->mem_ops = &vb2_dma_contig_memops; - src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; - src_vq->lock = &ctx->jpeg->lock; - src_vq->dev = ctx->jpeg->dev; - - ret = vb2_queue_init(src_vq); - if (ret) - return ret; - - dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - dst_vq->io_modes = VB2_MMAP | VB2_USERPTR; - dst_vq->drv_priv = ctx; - dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); - dst_vq->ops = &s5p_jpeg_qops; - dst_vq->mem_ops = &vb2_dma_contig_memops; - dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; - dst_vq->lock = &ctx->jpeg->lock; - dst_vq->dev = ctx->jpeg->dev; - - return vb2_queue_init(dst_vq); -} - -/* - * ============================================================================ - * ISR - * ============================================================================ - */ - -static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id) -{ - struct s5p_jpeg *jpeg = dev_id; - struct s5p_jpeg_ctx *curr_ctx; - struct vb2_v4l2_buffer *src_buf, *dst_buf; - unsigned long payload_size = 0; - enum vb2_buffer_state state = VB2_BUF_STATE_DONE; - bool enc_jpeg_too_large = false; - bool timer_elapsed = false; - bool op_completed = false; - - spin_lock(&jpeg->slock); - - curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev); - - src_buf = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx); - dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx); - - if (curr_ctx->mode == S5P_JPEG_ENCODE) - enc_jpeg_too_large = s5p_jpeg_enc_stream_stat(jpeg->regs); - timer_elapsed = s5p_jpeg_timer_stat(jpeg->regs); - op_completed = s5p_jpeg_result_stat_ok(jpeg->regs); - if (curr_ctx->mode == S5P_JPEG_DECODE) - op_completed = op_completed && - s5p_jpeg_stream_stat_ok(jpeg->regs); - - if (enc_jpeg_too_large) { - state = VB2_BUF_STATE_ERROR; - s5p_jpeg_clear_enc_stream_stat(jpeg->regs); - } else if (timer_elapsed) { - state = VB2_BUF_STATE_ERROR; - s5p_jpeg_clear_timer_stat(jpeg->regs); - } else if (!op_completed) { - state = VB2_BUF_STATE_ERROR; - } else { - payload_size = s5p_jpeg_compressed_size(jpeg->regs); - } - - dst_buf->timecode = src_buf->timecode; - dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp; - dst_buf->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK; - dst_buf->flags |= - src_buf->flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK; - - v4l2_m2m_buf_done(src_buf, state); - if (curr_ctx->mode == S5P_JPEG_ENCODE) - vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload_size); - v4l2_m2m_buf_done(dst_buf, state); - - curr_ctx->subsampling = s5p_jpeg_get_subsampling_mode(jpeg->regs); - spin_unlock(&jpeg->slock); - - s5p_jpeg_clear_int(jpeg->regs); - - v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx); - return IRQ_HANDLED; -} - -static irqreturn_t exynos4_jpeg_irq(int irq, void *priv) -{ - unsigned int int_status; - struct vb2_v4l2_buffer *src_vb, *dst_vb; - struct s5p_jpeg *jpeg = priv; - struct s5p_jpeg_ctx *curr_ctx; - unsigned long payload_size = 0; - - spin_lock(&jpeg->slock); - - exynos4_jpeg_set_sys_int_enable(jpeg->regs, 0); - - curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev); - - src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx); - dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx); - - int_status = exynos4_jpeg_get_int_status(jpeg->regs); - - if (int_status) { - switch (int_status & 0x1f) { - case 0x1: - jpeg->irq_ret = ERR_PROT; - break; - case 0x2: - jpeg->irq_ret = OK_ENC_OR_DEC; - break; - case 0x4: - jpeg->irq_ret = ERR_DEC_INVALID_FORMAT; - break; - case 0x8: - jpeg->irq_ret = ERR_MULTI_SCAN; - break; - case 0x10: - jpeg->irq_ret = ERR_FRAME; - break; - default: - jpeg->irq_ret = ERR_UNKNOWN; - break; - } - } else { - jpeg->irq_ret = ERR_UNKNOWN; - } - - if (jpeg->irq_ret == OK_ENC_OR_DEC) { - if (curr_ctx->mode == S5P_JPEG_ENCODE) { - payload_size = exynos4_jpeg_get_stream_size(jpeg->regs); - vb2_set_plane_payload(&dst_vb->vb2_buf, - 0, payload_size); - } - v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE); - v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE); - } else { - v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_ERROR); - v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_ERROR); - } - - if (jpeg->variant->version == SJPEG_EXYNOS4) - curr_ctx->subsampling = exynos4_jpeg_get_frame_fmt(jpeg->regs); - - exynos4_jpeg_set_enc_dec_mode(jpeg->regs, S5P_JPEG_DISABLE); - - spin_unlock(&jpeg->slock); - - v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx); - return IRQ_HANDLED; -} - -static irqreturn_t exynos3250_jpeg_irq(int irq, void *dev_id) -{ - struct s5p_jpeg *jpeg = dev_id; - struct s5p_jpeg_ctx *curr_ctx; - struct vb2_v4l2_buffer *src_buf, *dst_buf; - unsigned long payload_size = 0; - enum vb2_buffer_state state = VB2_BUF_STATE_DONE; - bool interrupt_timeout = false; - bool stream_error = false; - u32 irq_status; - - spin_lock(&jpeg->slock); - - irq_status = exynos3250_jpeg_get_timer_status(jpeg->regs); - if (irq_status & EXYNOS3250_TIMER_INT_STAT) { - exynos3250_jpeg_clear_timer_status(jpeg->regs); - interrupt_timeout = true; - dev_err(jpeg->dev, "Interrupt timeout occurred.\n"); - } - - irq_status = exynos3250_jpeg_get_int_status(jpeg->regs); - exynos3250_jpeg_clear_int_status(jpeg->regs, irq_status); - - jpeg->irq_status |= irq_status; - - if (jpeg->variant->version == SJPEG_EXYNOS5420 && - irq_status & EXYNOS3250_STREAM_STAT) { - stream_error = true; - dev_err(jpeg->dev, "Syntax error or unrecoverable error occurred.\n"); - } - - curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev); - - if (!curr_ctx) - goto exit_unlock; - - if ((irq_status & EXYNOS3250_HEADER_STAT) && - (curr_ctx->mode == S5P_JPEG_DECODE)) { - exynos3250_jpeg_rstart(jpeg->regs); - goto exit_unlock; - } - - if (jpeg->irq_status & (EXYNOS3250_JPEG_DONE | - EXYNOS3250_WDMA_DONE | - EXYNOS3250_RDMA_DONE | - EXYNOS3250_RESULT_STAT)) - payload_size = exynos3250_jpeg_compressed_size(jpeg->regs); - else if (interrupt_timeout || stream_error) - state = VB2_BUF_STATE_ERROR; - else - goto exit_unlock; - - src_buf = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx); - dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx); - - dst_buf->timecode = src_buf->timecode; - dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp; - - v4l2_m2m_buf_done(src_buf, state); - if (curr_ctx->mode == S5P_JPEG_ENCODE) - vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload_size); - v4l2_m2m_buf_done(dst_buf, state); - - curr_ctx->subsampling = - exynos3250_jpeg_get_subsampling_mode(jpeg->regs); - - spin_unlock(&jpeg->slock); - - v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx); - return IRQ_HANDLED; - -exit_unlock: - spin_unlock(&jpeg->slock); - return IRQ_HANDLED; -} - -static void *jpeg_get_drv_data(struct device *dev); - -/* - * ============================================================================ - * Driver basic infrastructure - * ============================================================================ - */ - -static int s5p_jpeg_probe(struct platform_device *pdev) -{ - struct s5p_jpeg *jpeg; - int i, ret; - - /* JPEG IP abstraction struct */ - jpeg = devm_kzalloc(&pdev->dev, sizeof(struct s5p_jpeg), GFP_KERNEL); - if (!jpeg) - return -ENOMEM; - - jpeg->variant = jpeg_get_drv_data(&pdev->dev); - if (!jpeg->variant) - return -ENODEV; - - mutex_init(&jpeg->lock); - spin_lock_init(&jpeg->slock); - jpeg->dev = &pdev->dev; - - /* memory-mapped registers */ - jpeg->regs = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(jpeg->regs)) - return PTR_ERR(jpeg->regs); - - /* interrupt service routine registration */ - jpeg->irq = ret = platform_get_irq(pdev, 0); - if (ret < 0) { - dev_err(&pdev->dev, "cannot find IRQ\n"); - return ret; - } - - ret = devm_request_irq(&pdev->dev, jpeg->irq, jpeg->variant->jpeg_irq, - 0, dev_name(&pdev->dev), jpeg); - if (ret) { - dev_err(&pdev->dev, "cannot claim IRQ %d\n", jpeg->irq); - return ret; - } - - /* clocks */ - for (i = 0; i < jpeg->variant->num_clocks; i++) { - jpeg->clocks[i] = devm_clk_get(&pdev->dev, - jpeg->variant->clk_names[i]); - if (IS_ERR(jpeg->clocks[i])) { - dev_err(&pdev->dev, "failed to get clock: %s\n", - jpeg->variant->clk_names[i]); - return PTR_ERR(jpeg->clocks[i]); - } - } - - /* v4l2 device */ - ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev); - if (ret) { - dev_err(&pdev->dev, "Failed to register v4l2 device\n"); - return ret; - } - - /* mem2mem device */ - jpeg->m2m_dev = v4l2_m2m_init(jpeg->variant->m2m_ops); - if (IS_ERR(jpeg->m2m_dev)) { - v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n"); - ret = PTR_ERR(jpeg->m2m_dev); - goto device_register_rollback; - } - - vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32)); - - /* JPEG encoder /dev/videoX node */ - jpeg->vfd_encoder = video_device_alloc(); - if (!jpeg->vfd_encoder) { - v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n"); - ret = -ENOMEM; - goto m2m_init_rollback; - } - snprintf(jpeg->vfd_encoder->name, sizeof(jpeg->vfd_encoder->name), - "%s-enc", S5P_JPEG_M2M_NAME); - jpeg->vfd_encoder->fops = &s5p_jpeg_fops; - jpeg->vfd_encoder->ioctl_ops = &s5p_jpeg_ioctl_ops; - jpeg->vfd_encoder->minor = -1; - jpeg->vfd_encoder->release = video_device_release; - jpeg->vfd_encoder->lock = &jpeg->lock; - jpeg->vfd_encoder->v4l2_dev = &jpeg->v4l2_dev; - jpeg->vfd_encoder->vfl_dir = VFL_DIR_M2M; - jpeg->vfd_encoder->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M; - - ret = video_register_device(jpeg->vfd_encoder, VFL_TYPE_VIDEO, -1); - if (ret) { - v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n"); - video_device_release(jpeg->vfd_encoder); - goto m2m_init_rollback; - } - - video_set_drvdata(jpeg->vfd_encoder, jpeg); - v4l2_info(&jpeg->v4l2_dev, - "encoder device registered as /dev/video%d\n", - jpeg->vfd_encoder->num); - - /* JPEG decoder /dev/videoX node */ - jpeg->vfd_decoder = video_device_alloc(); - if (!jpeg->vfd_decoder) { - v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n"); - ret = -ENOMEM; - goto enc_vdev_register_rollback; - } - snprintf(jpeg->vfd_decoder->name, sizeof(jpeg->vfd_decoder->name), - "%s-dec", S5P_JPEG_M2M_NAME); - jpeg->vfd_decoder->fops = &s5p_jpeg_fops; - jpeg->vfd_decoder->ioctl_ops = &s5p_jpeg_ioctl_ops; - jpeg->vfd_decoder->minor = -1; - jpeg->vfd_decoder->release = video_device_release; - jpeg->vfd_decoder->lock = &jpeg->lock; - jpeg->vfd_decoder->v4l2_dev = &jpeg->v4l2_dev; - jpeg->vfd_decoder->vfl_dir = VFL_DIR_M2M; - jpeg->vfd_decoder->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M; - - ret = video_register_device(jpeg->vfd_decoder, VFL_TYPE_VIDEO, -1); - if (ret) { - v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n"); - video_device_release(jpeg->vfd_decoder); - goto enc_vdev_register_rollback; - } - - video_set_drvdata(jpeg->vfd_decoder, jpeg); - v4l2_info(&jpeg->v4l2_dev, - "decoder device registered as /dev/video%d\n", - jpeg->vfd_decoder->num); - - /* final statements & power management */ - platform_set_drvdata(pdev, jpeg); - - pm_runtime_enable(&pdev->dev); - - v4l2_info(&jpeg->v4l2_dev, "Samsung S5P JPEG codec\n"); - - return 0; - -enc_vdev_register_rollback: - video_unregister_device(jpeg->vfd_encoder); - -m2m_init_rollback: - v4l2_m2m_release(jpeg->m2m_dev); - -device_register_rollback: - v4l2_device_unregister(&jpeg->v4l2_dev); - - return ret; -} - -static int s5p_jpeg_remove(struct platform_device *pdev) -{ - struct s5p_jpeg *jpeg = platform_get_drvdata(pdev); - int i; - - pm_runtime_disable(jpeg->dev); - - video_unregister_device(jpeg->vfd_decoder); - video_unregister_device(jpeg->vfd_encoder); - vb2_dma_contig_clear_max_seg_size(&pdev->dev); - v4l2_m2m_release(jpeg->m2m_dev); - v4l2_device_unregister(&jpeg->v4l2_dev); - - if (!pm_runtime_status_suspended(&pdev->dev)) { - for (i = jpeg->variant->num_clocks - 1; i >= 0; i--) - clk_disable_unprepare(jpeg->clocks[i]); - } - - return 0; -} - -#ifdef CONFIG_PM -static int s5p_jpeg_runtime_suspend(struct device *dev) -{ - struct s5p_jpeg *jpeg = dev_get_drvdata(dev); - int i; - - for (i = jpeg->variant->num_clocks - 1; i >= 0; i--) - clk_disable_unprepare(jpeg->clocks[i]); - - return 0; -} - -static int s5p_jpeg_runtime_resume(struct device *dev) -{ - struct s5p_jpeg *jpeg = dev_get_drvdata(dev); - unsigned long flags; - int i, ret; - - for (i = 0; i < jpeg->variant->num_clocks; i++) { - ret = clk_prepare_enable(jpeg->clocks[i]); - if (ret) { - while (--i >= 0) - clk_disable_unprepare(jpeg->clocks[i]); - return ret; - } - } - - spin_lock_irqsave(&jpeg->slock, flags); - - /* - * JPEG IP allows storing two Huffman tables for each component. - * We fill table 0 for each component and do this here only - * for S5PC210 and Exynos3250 SoCs. Exynos4x12 and Exynos542x SoC - * require programming their Huffman tables each time the encoding - * process is initialized, and thus it is accomplished in the - * device_run callback of m2m_ops. - */ - if (!jpeg->variant->htbl_reinit) { - s5p_jpeg_set_hdctbl(jpeg->regs); - s5p_jpeg_set_hdctblg(jpeg->regs); - s5p_jpeg_set_hactbl(jpeg->regs); - s5p_jpeg_set_hactblg(jpeg->regs); - } - - spin_unlock_irqrestore(&jpeg->slock, flags); - - return 0; -} -#endif /* CONFIG_PM */ - -static const struct dev_pm_ops s5p_jpeg_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) - SET_RUNTIME_PM_OPS(s5p_jpeg_runtime_suspend, s5p_jpeg_runtime_resume, - NULL) -}; - -static struct s5p_jpeg_variant s5p_jpeg_drvdata = { - .version = SJPEG_S5P, - .jpeg_irq = s5p_jpeg_irq, - .m2m_ops = &s5p_jpeg_m2m_ops, - .fmt_ver_flag = SJPEG_FMT_FLAG_S5P, - .clk_names = {"jpeg"}, - .num_clocks = 1, -}; - -static struct s5p_jpeg_variant exynos3250_jpeg_drvdata = { - .version = SJPEG_EXYNOS3250, - .jpeg_irq = exynos3250_jpeg_irq, - .m2m_ops = &exynos3250_jpeg_m2m_ops, - .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS3250, - .hw3250_compat = 1, - .clk_names = {"jpeg", "sclk"}, - .num_clocks = 2, -}; - -static struct s5p_jpeg_variant exynos4_jpeg_drvdata = { - .version = SJPEG_EXYNOS4, - .jpeg_irq = exynos4_jpeg_irq, - .m2m_ops = &exynos4_jpeg_m2m_ops, - .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS4, - .htbl_reinit = 1, - .clk_names = {"jpeg"}, - .num_clocks = 1, - .hw_ex4_compat = 1, -}; - -static struct s5p_jpeg_variant exynos5420_jpeg_drvdata = { - .version = SJPEG_EXYNOS5420, - .jpeg_irq = exynos3250_jpeg_irq, /* intentionally 3250 */ - .m2m_ops = &exynos3250_jpeg_m2m_ops, /* intentionally 3250 */ - .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS3250, /* intentionally 3250 */ - .hw3250_compat = 1, - .htbl_reinit = 1, - .clk_names = {"jpeg"}, - .num_clocks = 1, -}; - -static struct s5p_jpeg_variant exynos5433_jpeg_drvdata = { - .version = SJPEG_EXYNOS5433, - .jpeg_irq = exynos4_jpeg_irq, - .m2m_ops = &exynos4_jpeg_m2m_ops, - .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS4, - .htbl_reinit = 1, - .clk_names = {"pclk", "aclk", "aclk_xiu", "sclk"}, - .num_clocks = 4, - .hw_ex4_compat = 1, -}; - -static const struct of_device_id samsung_jpeg_match[] = { - { - .compatible = "samsung,s5pv210-jpeg", - .data = &s5p_jpeg_drvdata, - }, { - .compatible = "samsung,exynos3250-jpeg", - .data = &exynos3250_jpeg_drvdata, - }, { - .compatible = "samsung,exynos4210-jpeg", - .data = &exynos4_jpeg_drvdata, - }, { - .compatible = "samsung,exynos4212-jpeg", - .data = &exynos4_jpeg_drvdata, - }, { - .compatible = "samsung,exynos5420-jpeg", - .data = &exynos5420_jpeg_drvdata, - }, { - .compatible = "samsung,exynos5433-jpeg", - .data = &exynos5433_jpeg_drvdata, - }, - {}, -}; - -MODULE_DEVICE_TABLE(of, samsung_jpeg_match); - -static void *jpeg_get_drv_data(struct device *dev) -{ - struct s5p_jpeg_variant *driver_data = NULL; - const struct of_device_id *match; - - if (!IS_ENABLED(CONFIG_OF) || !dev->of_node) - return &s5p_jpeg_drvdata; - - match = of_match_node(samsung_jpeg_match, dev->of_node); - - if (match) - driver_data = (struct s5p_jpeg_variant *)match->data; - - return driver_data; -} - -static struct platform_driver s5p_jpeg_driver = { - .probe = s5p_jpeg_probe, - .remove = s5p_jpeg_remove, - .driver = { - .of_match_table = of_match_ptr(samsung_jpeg_match), - .name = S5P_JPEG_M2M_NAME, - .pm = &s5p_jpeg_pm_ops, - }, -}; - -module_platform_driver(s5p_jpeg_driver); - -MODULE_AUTHOR("Andrzej Pietrasiewicz "); -MODULE_AUTHOR("Jacek Anaszewski "); -MODULE_DESCRIPTION("Samsung JPEG codec driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.h b/drivers/media/platform/s5p-jpeg/jpeg-core.h deleted file mode 100644 index 4a5fb1b15455..000000000000 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.h +++ /dev/null @@ -1,267 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* linux/drivers/media/platform/s5p-jpeg/jpeg-core.h - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * Author: Andrzej Pietrasiewicz - */ - -#ifndef JPEG_CORE_H_ -#define JPEG_CORE_H_ - -#include -#include -#include -#include - -#define S5P_JPEG_M2M_NAME "s5p-jpeg" - -#define JPEG_MAX_CLOCKS 4 - -/* JPEG compression quality setting */ -#define S5P_JPEG_COMPR_QUAL_BEST 0 -#define S5P_JPEG_COMPR_QUAL_WORST 3 - -/* JPEG RGB to YCbCr conversion matrix coefficients */ -#define S5P_JPEG_COEF11 0x4d -#define S5P_JPEG_COEF12 0x97 -#define S5P_JPEG_COEF13 0x1e -#define S5P_JPEG_COEF21 0x2c -#define S5P_JPEG_COEF22 0x57 -#define S5P_JPEG_COEF23 0x83 -#define S5P_JPEG_COEF31 0x83 -#define S5P_JPEG_COEF32 0x6e -#define S5P_JPEG_COEF33 0x13 - -#define EXYNOS3250_IRQ_TIMEOUT 0x10000000 - -/* a selection of JPEG markers */ -#define JPEG_MARKER_TEM 0x01 -#define JPEG_MARKER_SOF0 0xc0 -#define JPEG_MARKER_DHT 0xc4 -#define JPEG_MARKER_RST 0xd0 -#define JPEG_MARKER_SOI 0xd8 -#define JPEG_MARKER_EOI 0xd9 -#define JPEG_MARKER_SOS 0xda -#define JPEG_MARKER_DQT 0xdb -#define JPEG_MARKER_DHP 0xde - -/* Flags that indicate a format can be used for capture/output */ -#define SJPEG_FMT_FLAG_ENC_CAPTURE (1 << 0) -#define SJPEG_FMT_FLAG_ENC_OUTPUT (1 << 1) -#define SJPEG_FMT_FLAG_DEC_CAPTURE (1 << 2) -#define SJPEG_FMT_FLAG_DEC_OUTPUT (1 << 3) -#define SJPEG_FMT_FLAG_S5P (1 << 4) -#define SJPEG_FMT_FLAG_EXYNOS3250 (1 << 5) -#define SJPEG_FMT_FLAG_EXYNOS4 (1 << 6) -#define SJPEG_FMT_RGB (1 << 7) -#define SJPEG_FMT_NON_RGB (1 << 8) - -#define S5P_JPEG_ENCODE 0 -#define S5P_JPEG_DECODE 1 -#define S5P_JPEG_DISABLE -1 - -#define FMT_TYPE_OUTPUT 0 -#define FMT_TYPE_CAPTURE 1 - -#define SJPEG_SUBSAMPLING_444 0x11 -#define SJPEG_SUBSAMPLING_422 0x21 -#define SJPEG_SUBSAMPLING_420 0x22 - -#define S5P_JPEG_MAX_MARKER 4 - -/* Version numbers */ -enum sjpeg_version { - SJPEG_S5P, - SJPEG_EXYNOS3250, - SJPEG_EXYNOS4, - SJPEG_EXYNOS5420, - SJPEG_EXYNOS5433, -}; - -enum exynos4_jpeg_result { - OK_ENC_OR_DEC, - ERR_PROT, - ERR_DEC_INVALID_FORMAT, - ERR_MULTI_SCAN, - ERR_FRAME, - ERR_UNKNOWN, -}; - -enum exynos4_jpeg_img_quality_level { - QUALITY_LEVEL_1 = 0, /* high */ - QUALITY_LEVEL_2, - QUALITY_LEVEL_3, - QUALITY_LEVEL_4, /* low */ -}; - -enum s5p_jpeg_ctx_state { - JPEGCTX_RUNNING = 0, - JPEGCTX_RESOLUTION_CHANGE, -}; - -/** - * struct s5p_jpeg - JPEG IP abstraction - * @lock: the mutex protecting this structure - * @slock: spinlock protecting the device contexts - * @v4l2_dev: v4l2 device for mem2mem mode - * @vfd_encoder: video device node for encoder mem2mem mode - * @vfd_decoder: video device node for decoder mem2mem mode - * @m2m_dev: v4l2 mem2mem device data - * @regs: JPEG IP registers mapping - * @irq: JPEG IP irq - * @irq_ret: JPEG IP irq result value - * @clocks: JPEG IP clock(s) - * @dev: JPEG IP struct device - * @variant: driver variant to be used - * @irq_status: interrupt flags set during single encode/decode - * operation - */ -struct s5p_jpeg { - struct mutex lock; - spinlock_t slock; - - struct v4l2_device v4l2_dev; - struct video_device *vfd_encoder; - struct video_device *vfd_decoder; - struct v4l2_m2m_dev *m2m_dev; - - void __iomem *regs; - unsigned int irq; - enum exynos4_jpeg_result irq_ret; - struct clk *clocks[JPEG_MAX_CLOCKS]; - struct device *dev; - struct s5p_jpeg_variant *variant; - u32 irq_status; -}; - -struct s5p_jpeg_variant { - unsigned int version; - unsigned int fmt_ver_flag; - unsigned int hw3250_compat:1; - unsigned int htbl_reinit:1; - unsigned int hw_ex4_compat:1; - const struct v4l2_m2m_ops *m2m_ops; - irqreturn_t (*jpeg_irq)(int irq, void *priv); - const char *clk_names[JPEG_MAX_CLOCKS]; - int num_clocks; -}; - -/** - * struct s5p_jpeg_fmt - driver's internal color format data - * @fourcc: the fourcc code, 0 if not applicable - * @depth: number of bits per pixel - * @colplanes: number of color planes (1 for packed formats) - * @memplanes: number of memory planes (1 for packed formats) - * @h_align: horizontal alignment order (align to 2^h_align) - * @v_align: vertical alignment order (align to 2^v_align) - * @subsampling:subsampling of a raw format or a JPEG - * @flags: flags describing format applicability - */ -struct s5p_jpeg_fmt { - u32 fourcc; - int depth; - int colplanes; - int memplanes; - int h_align; - int v_align; - int subsampling; - u32 flags; -}; - -/** - * struct s5p_jpeg_marker - collection of markers from jpeg header - * @marker: markers' positions relative to the buffer beginning - * @len: markers' payload lengths (without length field) - * @n: number of markers in collection - */ -struct s5p_jpeg_marker { - u32 marker[S5P_JPEG_MAX_MARKER]; - u32 len[S5P_JPEG_MAX_MARKER]; - u32 n; -}; - -/** - * struct s5p_jpeg_q_data - parameters of one queue - * @fmt: driver-specific format of this queue - * @w: image width - * @h: image height - * @sos: JPEG_MARKER_SOS's position relative to the buffer beginning - * @dht: JPEG_MARKER_DHT' positions relative to the buffer beginning - * @dqt: JPEG_MARKER_DQT' positions relative to the buffer beginning - * @sof: JPEG_MARKER_SOF0's position relative to the buffer beginning - * @sof_len: JPEG_MARKER_SOF0's payload length (without length field itself) - * @size: image buffer size in bytes - */ -struct s5p_jpeg_q_data { - struct s5p_jpeg_fmt *fmt; - u32 w; - u32 h; - u32 sos; - struct s5p_jpeg_marker dht; - struct s5p_jpeg_marker dqt; - u32 sof; - u32 sof_len; - u32 size; -}; - -/** - * struct s5p_jpeg_ctx - the device context data - * @jpeg: JPEG IP device for this context - * @mode: compression (encode) operation or decompression (decode) - * @compr_quality: destination image quality in compression (encode) mode - * @restart_interval: JPEG restart interval for JPEG encoding - * @subsampling: subsampling of a raw format or a JPEG - * @out_q: source (output) queue information - * @cap_q: destination (capture) queue queue information - * @scale_factor: scale factor for JPEG decoding - * @crop_rect: a rectangle representing crop area of the output buffer - * @fh: V4L2 file handle - * @hdr_parsed: set if header has been parsed during decompression - * @crop_altered: set if crop rectangle has been altered by the user space - * @ctrl_handler: controls handler - * @state: state of the context - */ -struct s5p_jpeg_ctx { - struct s5p_jpeg *jpeg; - unsigned int mode; - unsigned short compr_quality; - unsigned short restart_interval; - unsigned short subsampling; - struct s5p_jpeg_q_data out_q; - struct s5p_jpeg_q_data cap_q; - unsigned int scale_factor; - struct v4l2_rect crop_rect; - struct v4l2_fh fh; - bool hdr_parsed; - bool crop_altered; - struct v4l2_ctrl_handler ctrl_handler; - enum s5p_jpeg_ctx_state state; -}; - -/** - * struct s5p_jpeg_buffer - description of memory containing input JPEG data - * @size: buffer size - * @curr: current position in the buffer - * @data: pointer to the data - */ -struct s5p_jpeg_buffer { - unsigned long size; - unsigned long curr; - unsigned long data; -}; - -/** - * struct s5p_jpeg_addr - JPEG converter physical address set for DMA - * @y: luminance plane physical address - * @cb: Cb plane physical address - * @cr: Cr plane physical address - */ -struct s5p_jpeg_addr { - u32 y; - u32 cb; - u32 cr; -}; - -#endif /* JPEG_CORE_H */ diff --git a/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.c b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.c deleted file mode 100644 index 637a5104d948..000000000000 --- a/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.c +++ /dev/null @@ -1,486 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* linux/drivers/media/platform/exynos3250-jpeg/jpeg-hw.h - * - * Copyright (c) 2014 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * Author: Jacek Anaszewski - */ - -#include -#include -#include - -#include "jpeg-core.h" -#include "jpeg-regs.h" -#include "jpeg-hw-exynos3250.h" - -void exynos3250_jpeg_reset(void __iomem *regs) -{ - u32 reg = 1; - int count = 1000; - - writel(1, regs + EXYNOS3250_SW_RESET); - /* no other way but polling for when JPEG IP becomes operational */ - while (reg != 0 && --count > 0) { - udelay(1); - cpu_relax(); - reg = readl(regs + EXYNOS3250_SW_RESET); - } - - reg = 0; - count = 1000; - - while (reg != 1 && --count > 0) { - writel(1, regs + EXYNOS3250_JPGDRI); - udelay(1); - cpu_relax(); - reg = readl(regs + EXYNOS3250_JPGDRI); - } - - writel(0, regs + EXYNOS3250_JPGDRI); -} - -void exynos3250_jpeg_poweron(void __iomem *regs) -{ - writel(EXYNOS3250_POWER_ON, regs + EXYNOS3250_JPGCLKCON); -} - -void exynos3250_jpeg_set_dma_num(void __iomem *regs) -{ - writel(((EXYNOS3250_DMA_MO_COUNT << EXYNOS3250_WDMA_ISSUE_NUM_SHIFT) & - EXYNOS3250_WDMA_ISSUE_NUM_MASK) | - ((EXYNOS3250_DMA_MO_COUNT << EXYNOS3250_RDMA_ISSUE_NUM_SHIFT) & - EXYNOS3250_RDMA_ISSUE_NUM_MASK) | - ((EXYNOS3250_DMA_MO_COUNT << EXYNOS3250_ISSUE_GATHER_NUM_SHIFT) & - EXYNOS3250_ISSUE_GATHER_NUM_MASK), - regs + EXYNOS3250_DMA_ISSUE_NUM); -} - -void exynos3250_jpeg_clk_set(void __iomem *base) -{ - u32 reg; - - reg = readl(base + EXYNOS3250_JPGCMOD) & ~EXYNOS3250_HALF_EN_MASK; - - writel(reg | EXYNOS3250_HALF_EN, base + EXYNOS3250_JPGCMOD); -} - -void exynos3250_jpeg_input_raw_fmt(void __iomem *regs, unsigned int fmt) -{ - u32 reg; - - reg = readl(regs + EXYNOS3250_JPGCMOD) & - EXYNOS3250_MODE_Y16_MASK; - - switch (fmt) { - case V4L2_PIX_FMT_RGB32: - reg |= EXYNOS3250_MODE_SEL_ARGB8888; - break; - case V4L2_PIX_FMT_BGR32: - reg |= EXYNOS3250_MODE_SEL_ARGB8888 | EXYNOS3250_SRC_SWAP_RGB; - break; - case V4L2_PIX_FMT_RGB565: - reg |= EXYNOS3250_MODE_SEL_RGB565; - break; - case V4L2_PIX_FMT_RGB565X: - reg |= EXYNOS3250_MODE_SEL_RGB565 | EXYNOS3250_SRC_SWAP_RGB; - break; - case V4L2_PIX_FMT_YUYV: - reg |= EXYNOS3250_MODE_SEL_422_1P_LUM_CHR; - break; - case V4L2_PIX_FMT_YVYU: - reg |= EXYNOS3250_MODE_SEL_422_1P_LUM_CHR | - EXYNOS3250_SRC_SWAP_UV; - break; - case V4L2_PIX_FMT_UYVY: - reg |= EXYNOS3250_MODE_SEL_422_1P_CHR_LUM; - break; - case V4L2_PIX_FMT_VYUY: - reg |= EXYNOS3250_MODE_SEL_422_1P_CHR_LUM | - EXYNOS3250_SRC_SWAP_UV; - break; - case V4L2_PIX_FMT_NV12: - reg |= EXYNOS3250_MODE_SEL_420_2P | EXYNOS3250_SRC_NV12; - break; - case V4L2_PIX_FMT_NV21: - reg |= EXYNOS3250_MODE_SEL_420_2P | EXYNOS3250_SRC_NV21; - break; - case V4L2_PIX_FMT_YUV420: - reg |= EXYNOS3250_MODE_SEL_420_3P; - break; - default: - break; - - } - - writel(reg, regs + EXYNOS3250_JPGCMOD); -} - -void exynos3250_jpeg_set_y16(void __iomem *regs, bool y16) -{ - u32 reg; - - reg = readl(regs + EXYNOS3250_JPGCMOD); - if (y16) - reg |= EXYNOS3250_MODE_Y16; - else - reg &= ~EXYNOS3250_MODE_Y16_MASK; - writel(reg, regs + EXYNOS3250_JPGCMOD); -} - -void exynos3250_jpeg_proc_mode(void __iomem *regs, unsigned int mode) -{ - u32 reg, m; - - if (mode == S5P_JPEG_ENCODE) - m = EXYNOS3250_PROC_MODE_COMPR; - else - m = EXYNOS3250_PROC_MODE_DECOMPR; - reg = readl(regs + EXYNOS3250_JPGMOD); - reg &= ~EXYNOS3250_PROC_MODE_MASK; - reg |= m; - writel(reg, regs + EXYNOS3250_JPGMOD); -} - -void exynos3250_jpeg_subsampling_mode(void __iomem *regs, unsigned int mode) -{ - u32 reg, m = 0; - - switch (mode) { - case V4L2_JPEG_CHROMA_SUBSAMPLING_444: - m = EXYNOS3250_SUBSAMPLING_MODE_444; - break; - case V4L2_JPEG_CHROMA_SUBSAMPLING_422: - m = EXYNOS3250_SUBSAMPLING_MODE_422; - break; - case V4L2_JPEG_CHROMA_SUBSAMPLING_420: - m = EXYNOS3250_SUBSAMPLING_MODE_420; - break; - } - - reg = readl(regs + EXYNOS3250_JPGMOD); - reg &= ~EXYNOS3250_SUBSAMPLING_MODE_MASK; - reg |= m; - writel(reg, regs + EXYNOS3250_JPGMOD); -} - -unsigned int exynos3250_jpeg_get_subsampling_mode(void __iomem *regs) -{ - return readl(regs + EXYNOS3250_JPGMOD) & - EXYNOS3250_SUBSAMPLING_MODE_MASK; -} - -void exynos3250_jpeg_dri(void __iomem *regs, unsigned int dri) -{ - u32 reg; - - reg = dri & EXYNOS3250_JPGDRI_MASK; - writel(reg, regs + EXYNOS3250_JPGDRI); -} - -void exynos3250_jpeg_qtbl(void __iomem *regs, unsigned int t, unsigned int n) -{ - unsigned long reg; - - reg = readl(regs + EXYNOS3250_QHTBL); - reg &= ~EXYNOS3250_QT_NUM_MASK(t); - reg |= (n << EXYNOS3250_QT_NUM_SHIFT(t)) & - EXYNOS3250_QT_NUM_MASK(t); - writel(reg, regs + EXYNOS3250_QHTBL); -} - -void exynos3250_jpeg_htbl_ac(void __iomem *regs, unsigned int t) -{ - unsigned long reg; - - reg = readl(regs + EXYNOS3250_QHTBL); - reg &= ~EXYNOS3250_HT_NUM_AC_MASK(t); - /* this driver uses table 0 for all color components */ - reg |= (0 << EXYNOS3250_HT_NUM_AC_SHIFT(t)) & - EXYNOS3250_HT_NUM_AC_MASK(t); - writel(reg, regs + EXYNOS3250_QHTBL); -} - -void exynos3250_jpeg_htbl_dc(void __iomem *regs, unsigned int t) -{ - unsigned long reg; - - reg = readl(regs + EXYNOS3250_QHTBL); - reg &= ~EXYNOS3250_HT_NUM_DC_MASK(t); - /* this driver uses table 0 for all color components */ - reg |= (0 << EXYNOS3250_HT_NUM_DC_SHIFT(t)) & - EXYNOS3250_HT_NUM_DC_MASK(t); - writel(reg, regs + EXYNOS3250_QHTBL); -} - -void exynos3250_jpeg_set_y(void __iomem *regs, unsigned int y) -{ - u32 reg; - - reg = y & EXYNOS3250_JPGY_MASK; - writel(reg, regs + EXYNOS3250_JPGY); -} - -void exynos3250_jpeg_set_x(void __iomem *regs, unsigned int x) -{ - u32 reg; - - reg = x & EXYNOS3250_JPGX_MASK; - writel(reg, regs + EXYNOS3250_JPGX); -} - -#if 0 /* Currently unused */ -unsigned int exynos3250_jpeg_get_y(void __iomem *regs) -{ - return readl(regs + EXYNOS3250_JPGY); -} - -unsigned int exynos3250_jpeg_get_x(void __iomem *regs) -{ - return readl(regs + EXYNOS3250_JPGX); -} -#endif - -void exynos3250_jpeg_interrupts_enable(void __iomem *regs) -{ - u32 reg; - - reg = readl(regs + EXYNOS3250_JPGINTSE); - reg |= (EXYNOS3250_JPEG_DONE_EN | - EXYNOS3250_WDMA_DONE_EN | - EXYNOS3250_RDMA_DONE_EN | - EXYNOS3250_ENC_STREAM_INT_EN | - EXYNOS3250_CORE_DONE_EN | - EXYNOS3250_ERR_INT_EN | - EXYNOS3250_HEAD_INT_EN); - writel(reg, regs + EXYNOS3250_JPGINTSE); -} - -void exynos3250_jpeg_enc_stream_bound(void __iomem *regs, unsigned int size) -{ - u32 reg; - - reg = size & EXYNOS3250_ENC_STREAM_BOUND_MASK; - writel(reg, regs + EXYNOS3250_ENC_STREAM_BOUND); -} - -void exynos3250_jpeg_output_raw_fmt(void __iomem *regs, unsigned int fmt) -{ - u32 reg; - - switch (fmt) { - case V4L2_PIX_FMT_RGB32: - reg = EXYNOS3250_OUT_FMT_ARGB8888; - break; - case V4L2_PIX_FMT_BGR32: - reg = EXYNOS3250_OUT_FMT_ARGB8888 | EXYNOS3250_OUT_SWAP_RGB; - break; - case V4L2_PIX_FMT_RGB565: - reg = EXYNOS3250_OUT_FMT_RGB565; - break; - case V4L2_PIX_FMT_RGB565X: - reg = EXYNOS3250_OUT_FMT_RGB565 | EXYNOS3250_OUT_SWAP_RGB; - break; - case V4L2_PIX_FMT_YUYV: - reg = EXYNOS3250_OUT_FMT_422_1P_LUM_CHR; - break; - case V4L2_PIX_FMT_YVYU: - reg = EXYNOS3250_OUT_FMT_422_1P_LUM_CHR | - EXYNOS3250_OUT_SWAP_UV; - break; - case V4L2_PIX_FMT_UYVY: - reg = EXYNOS3250_OUT_FMT_422_1P_CHR_LUM; - break; - case V4L2_PIX_FMT_VYUY: - reg = EXYNOS3250_OUT_FMT_422_1P_CHR_LUM | - EXYNOS3250_OUT_SWAP_UV; - break; - case V4L2_PIX_FMT_NV12: - reg = EXYNOS3250_OUT_FMT_420_2P | EXYNOS3250_OUT_NV12; - break; - case V4L2_PIX_FMT_NV21: - reg = EXYNOS3250_OUT_FMT_420_2P | EXYNOS3250_OUT_NV21; - break; - case V4L2_PIX_FMT_YUV420: - reg = EXYNOS3250_OUT_FMT_420_3P; - break; - default: - reg = 0; - break; - } - - writel(reg, regs + EXYNOS3250_OUTFORM); -} - -void exynos3250_jpeg_jpgadr(void __iomem *regs, unsigned int addr) -{ - writel(addr, regs + EXYNOS3250_JPG_JPGADR); -} - -void exynos3250_jpeg_imgadr(void __iomem *regs, struct s5p_jpeg_addr *img_addr) -{ - writel(img_addr->y, regs + EXYNOS3250_LUMA_BASE); - writel(img_addr->cb, regs + EXYNOS3250_CHROMA_BASE); - writel(img_addr->cr, regs + EXYNOS3250_CHROMA_CR_BASE); -} - -void exynos3250_jpeg_stride(void __iomem *regs, unsigned int img_fmt, - unsigned int width) -{ - u32 reg_luma = 0, reg_cr = 0, reg_cb = 0; - - switch (img_fmt) { - case V4L2_PIX_FMT_RGB32: - reg_luma = 4 * width; - break; - case V4L2_PIX_FMT_RGB565: - case V4L2_PIX_FMT_RGB565X: - case V4L2_PIX_FMT_YUYV: - case V4L2_PIX_FMT_YVYU: - case V4L2_PIX_FMT_UYVY: - case V4L2_PIX_FMT_VYUY: - reg_luma = 2 * width; - break; - case V4L2_PIX_FMT_NV12: - case V4L2_PIX_FMT_NV21: - reg_luma = width; - reg_cb = reg_luma; - break; - case V4L2_PIX_FMT_YUV420: - reg_luma = width; - reg_cb = reg_cr = reg_luma / 2; - break; - default: - break; - } - - writel(reg_luma, regs + EXYNOS3250_LUMA_STRIDE); - writel(reg_cb, regs + EXYNOS3250_CHROMA_STRIDE); - writel(reg_cr, regs + EXYNOS3250_CHROMA_CR_STRIDE); -} - -void exynos3250_jpeg_offset(void __iomem *regs, unsigned int x_offset, - unsigned int y_offset) -{ - u32 reg; - - reg = (y_offset << EXYNOS3250_LUMA_YY_OFFSET_SHIFT) & - EXYNOS3250_LUMA_YY_OFFSET_MASK; - reg |= (x_offset << EXYNOS3250_LUMA_YX_OFFSET_SHIFT) & - EXYNOS3250_LUMA_YX_OFFSET_MASK; - - writel(reg, regs + EXYNOS3250_LUMA_XY_OFFSET); - - reg = (y_offset << EXYNOS3250_CHROMA_YY_OFFSET_SHIFT) & - EXYNOS3250_CHROMA_YY_OFFSET_MASK; - reg |= (x_offset << EXYNOS3250_CHROMA_YX_OFFSET_SHIFT) & - EXYNOS3250_CHROMA_YX_OFFSET_MASK; - - writel(reg, regs + EXYNOS3250_CHROMA_XY_OFFSET); - - reg = (y_offset << EXYNOS3250_CHROMA_CR_YY_OFFSET_SHIFT) & - EXYNOS3250_CHROMA_CR_YY_OFFSET_MASK; - reg |= (x_offset << EXYNOS3250_CHROMA_CR_YX_OFFSET_SHIFT) & - EXYNOS3250_CHROMA_CR_YX_OFFSET_MASK; - - writel(reg, regs + EXYNOS3250_CHROMA_CR_XY_OFFSET); -} - -void exynos3250_jpeg_coef(void __iomem *base, unsigned int mode) -{ - if (mode == S5P_JPEG_ENCODE) { - writel(EXYNOS3250_JPEG_ENC_COEF1, - base + EXYNOS3250_JPG_COEF(1)); - writel(EXYNOS3250_JPEG_ENC_COEF2, - base + EXYNOS3250_JPG_COEF(2)); - writel(EXYNOS3250_JPEG_ENC_COEF3, - base + EXYNOS3250_JPG_COEF(3)); - } else { - writel(EXYNOS3250_JPEG_DEC_COEF1, - base + EXYNOS3250_JPG_COEF(1)); - writel(EXYNOS3250_JPEG_DEC_COEF2, - base + EXYNOS3250_JPG_COEF(2)); - writel(EXYNOS3250_JPEG_DEC_COEF3, - base + EXYNOS3250_JPG_COEF(3)); - } -} - -void exynos3250_jpeg_start(void __iomem *regs) -{ - writel(1, regs + EXYNOS3250_JSTART); -} - -void exynos3250_jpeg_rstart(void __iomem *regs) -{ - writel(1, regs + EXYNOS3250_JRSTART); -} - -unsigned int exynos3250_jpeg_get_int_status(void __iomem *regs) -{ - return readl(regs + EXYNOS3250_JPGINTST); -} - -void exynos3250_jpeg_clear_int_status(void __iomem *regs, - unsigned int value) -{ - writel(value, regs + EXYNOS3250_JPGINTST); -} - -unsigned int exynos3250_jpeg_operating(void __iomem *regs) -{ - return readl(regs + S5P_JPGOPR) & EXYNOS3250_JPGOPR_MASK; -} - -unsigned int exynos3250_jpeg_compressed_size(void __iomem *regs) -{ - return readl(regs + EXYNOS3250_JPGCNT) & EXYNOS3250_JPGCNT_MASK; -} - -void exynos3250_jpeg_dec_stream_size(void __iomem *regs, - unsigned int size) -{ - writel(size & EXYNOS3250_DEC_STREAM_MASK, - regs + EXYNOS3250_DEC_STREAM_SIZE); -} - -void exynos3250_jpeg_dec_scaling_ratio(void __iomem *regs, - unsigned int sratio) -{ - switch (sratio) { - case 1: - default: - sratio = EXYNOS3250_DEC_SCALE_FACTOR_8_8; - break; - case 2: - sratio = EXYNOS3250_DEC_SCALE_FACTOR_4_8; - break; - case 4: - sratio = EXYNOS3250_DEC_SCALE_FACTOR_2_8; - break; - case 8: - sratio = EXYNOS3250_DEC_SCALE_FACTOR_1_8; - break; - } - - writel(sratio & EXYNOS3250_DEC_SCALE_FACTOR_MASK, - regs + EXYNOS3250_DEC_SCALING_RATIO); -} - -void exynos3250_jpeg_set_timer(void __iomem *regs, unsigned int time_value) -{ - time_value &= EXYNOS3250_TIMER_INIT_MASK; - - writel(EXYNOS3250_TIMER_INT_STAT | time_value, - regs + EXYNOS3250_TIMER_SE); -} - -unsigned int exynos3250_jpeg_get_timer_status(void __iomem *regs) -{ - return readl(regs + EXYNOS3250_TIMER_ST); -} - -void exynos3250_jpeg_clear_timer_status(void __iomem *regs) -{ - writel(EXYNOS3250_TIMER_INT_STAT, regs + EXYNOS3250_TIMER_ST); -} diff --git a/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.h b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.h deleted file mode 100644 index 68160befce39..000000000000 --- a/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.h +++ /dev/null @@ -1,57 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* linux/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.h - * - * Copyright (c) 2014 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * Author: Jacek Anaszewski - */ -#ifndef JPEG_HW_EXYNOS3250_H_ -#define JPEG_HW_EXYNOS3250_H_ - -#include -#include - -#include "jpeg-regs.h" - -void exynos3250_jpeg_reset(void __iomem *regs); -void exynos3250_jpeg_poweron(void __iomem *regs); -void exynos3250_jpeg_set_dma_num(void __iomem *regs); -void exynos3250_jpeg_clk_set(void __iomem *base); -void exynos3250_jpeg_input_raw_fmt(void __iomem *regs, unsigned int fmt); -void exynos3250_jpeg_output_raw_fmt(void __iomem *regs, unsigned int fmt); -void exynos3250_jpeg_set_y16(void __iomem *regs, bool y16); -void exynos3250_jpeg_proc_mode(void __iomem *regs, unsigned int mode); -void exynos3250_jpeg_subsampling_mode(void __iomem *regs, unsigned int mode); -unsigned int exynos3250_jpeg_get_subsampling_mode(void __iomem *regs); -void exynos3250_jpeg_dri(void __iomem *regs, unsigned int dri); -void exynos3250_jpeg_qtbl(void __iomem *regs, unsigned int t, unsigned int n); -void exynos3250_jpeg_htbl_ac(void __iomem *regs, unsigned int t); -void exynos3250_jpeg_htbl_dc(void __iomem *regs, unsigned int t); -void exynos3250_jpeg_set_y(void __iomem *regs, unsigned int y); -void exynos3250_jpeg_set_x(void __iomem *regs, unsigned int x); -void exynos3250_jpeg_interrupts_enable(void __iomem *regs); -void exynos3250_jpeg_enc_stream_bound(void __iomem *regs, unsigned int size); -void exynos3250_jpeg_outform_raw(void __iomem *regs, unsigned long format); -void exynos3250_jpeg_jpgadr(void __iomem *regs, unsigned int addr); -void exynos3250_jpeg_imgadr(void __iomem *regs, struct s5p_jpeg_addr *img_addr); -void exynos3250_jpeg_stride(void __iomem *regs, unsigned int img_fmt, - unsigned int width); -void exynos3250_jpeg_offset(void __iomem *regs, unsigned int x_offset, - unsigned int y_offset); -void exynos3250_jpeg_coef(void __iomem *base, unsigned int mode); -void exynos3250_jpeg_start(void __iomem *regs); -void exynos3250_jpeg_rstart(void __iomem *regs); -unsigned int exynos3250_jpeg_get_int_status(void __iomem *regs); -void exynos3250_jpeg_clear_int_status(void __iomem *regs, - unsigned int value); -unsigned int exynos3250_jpeg_operating(void __iomem *regs); -unsigned int exynos3250_jpeg_compressed_size(void __iomem *regs); -void exynos3250_jpeg_dec_stream_size(void __iomem *regs, unsigned int size); -void exynos3250_jpeg_dec_scaling_ratio(void __iomem *regs, unsigned int sratio); -void exynos3250_jpeg_set_timer(void __iomem *regs, unsigned int time_value); -unsigned int exynos3250_jpeg_get_timer_status(void __iomem *regs); -void exynos3250_jpeg_set_timer_status(void __iomem *regs); -void exynos3250_jpeg_clear_timer_status(void __iomem *regs); - -#endif /* JPEG_HW_EXYNOS3250_H_ */ diff --git a/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c deleted file mode 100644 index 0828cfa783fe..000000000000 --- a/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c +++ /dev/null @@ -1,321 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2013 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * Author: Jacek Anaszewski - * - * Register interface file for JPEG driver on Exynos4x12. - */ -#include -#include - -#include "jpeg-core.h" -#include "jpeg-hw-exynos4.h" -#include "jpeg-regs.h" - -void exynos4_jpeg_sw_reset(void __iomem *base) -{ - unsigned int reg; - - reg = readl(base + EXYNOS4_JPEG_CNTL_REG); - writel(reg & ~(EXYNOS4_DEC_MODE | EXYNOS4_ENC_MODE), - base + EXYNOS4_JPEG_CNTL_REG); - - reg = readl(base + EXYNOS4_JPEG_CNTL_REG); - writel(reg & ~EXYNOS4_SOFT_RESET_HI, base + EXYNOS4_JPEG_CNTL_REG); - - udelay(100); - - writel(reg | EXYNOS4_SOFT_RESET_HI, base + EXYNOS4_JPEG_CNTL_REG); -} - -void exynos4_jpeg_set_enc_dec_mode(void __iomem *base, unsigned int mode) -{ - unsigned int reg; - - reg = readl(base + EXYNOS4_JPEG_CNTL_REG); - /* set exynos4_jpeg mod register */ - if (mode == S5P_JPEG_DECODE) { - writel((reg & EXYNOS4_ENC_DEC_MODE_MASK) | - EXYNOS4_DEC_MODE, - base + EXYNOS4_JPEG_CNTL_REG); - } else if (mode == S5P_JPEG_ENCODE) {/* encode */ - writel((reg & EXYNOS4_ENC_DEC_MODE_MASK) | - EXYNOS4_ENC_MODE, - base + EXYNOS4_JPEG_CNTL_REG); - } else { /* disable both */ - writel(reg & EXYNOS4_ENC_DEC_MODE_MASK, - base + EXYNOS4_JPEG_CNTL_REG); - } -} - -void __exynos4_jpeg_set_img_fmt(void __iomem *base, unsigned int img_fmt, - unsigned int version) -{ - unsigned int reg; - unsigned int exynos4_swap_chroma_cbcr; - unsigned int exynos4_swap_chroma_crcb; - - if (version == SJPEG_EXYNOS4) { - exynos4_swap_chroma_cbcr = EXYNOS4_SWAP_CHROMA_CBCR; - exynos4_swap_chroma_crcb = EXYNOS4_SWAP_CHROMA_CRCB; - } else { - exynos4_swap_chroma_cbcr = EXYNOS5433_SWAP_CHROMA_CBCR; - exynos4_swap_chroma_crcb = EXYNOS5433_SWAP_CHROMA_CRCB; - } - - reg = readl(base + EXYNOS4_IMG_FMT_REG) & - EXYNOS4_ENC_IN_FMT_MASK; /* clear except enc format */ - - switch (img_fmt) { - case V4L2_PIX_FMT_GREY: - reg = reg | EXYNOS4_ENC_GRAY_IMG | EXYNOS4_GRAY_IMG_IP; - break; - case V4L2_PIX_FMT_RGB32: - reg = reg | EXYNOS4_ENC_RGB_IMG | - EXYNOS4_RGB_IP_RGB_32BIT_IMG; - break; - case V4L2_PIX_FMT_RGB565: - reg = reg | EXYNOS4_ENC_RGB_IMG | - EXYNOS4_RGB_IP_RGB_16BIT_IMG; - break; - case V4L2_PIX_FMT_NV24: - reg = reg | EXYNOS4_ENC_YUV_444_IMG | - EXYNOS4_YUV_444_IP_YUV_444_2P_IMG | - exynos4_swap_chroma_cbcr; - break; - case V4L2_PIX_FMT_NV42: - reg = reg | EXYNOS4_ENC_YUV_444_IMG | - EXYNOS4_YUV_444_IP_YUV_444_2P_IMG | - exynos4_swap_chroma_crcb; - break; - case V4L2_PIX_FMT_YUYV: - reg = reg | EXYNOS4_DEC_YUV_422_IMG | - EXYNOS4_YUV_422_IP_YUV_422_1P_IMG | - exynos4_swap_chroma_cbcr; - break; - - case V4L2_PIX_FMT_YVYU: - reg = reg | EXYNOS4_DEC_YUV_422_IMG | - EXYNOS4_YUV_422_IP_YUV_422_1P_IMG | - exynos4_swap_chroma_crcb; - break; - case V4L2_PIX_FMT_NV16: - reg = reg | EXYNOS4_DEC_YUV_422_IMG | - EXYNOS4_YUV_422_IP_YUV_422_2P_IMG | - exynos4_swap_chroma_cbcr; - break; - case V4L2_PIX_FMT_NV61: - reg = reg | EXYNOS4_DEC_YUV_422_IMG | - EXYNOS4_YUV_422_IP_YUV_422_2P_IMG | - exynos4_swap_chroma_crcb; - break; - case V4L2_PIX_FMT_NV12: - reg = reg | EXYNOS4_DEC_YUV_420_IMG | - EXYNOS4_YUV_420_IP_YUV_420_2P_IMG | - exynos4_swap_chroma_cbcr; - break; - case V4L2_PIX_FMT_NV21: - reg = reg | EXYNOS4_DEC_YUV_420_IMG | - EXYNOS4_YUV_420_IP_YUV_420_2P_IMG | - exynos4_swap_chroma_crcb; - break; - case V4L2_PIX_FMT_YUV420: - reg = reg | EXYNOS4_DEC_YUV_420_IMG | - EXYNOS4_YUV_420_IP_YUV_420_3P_IMG | - exynos4_swap_chroma_cbcr; - break; - default: - break; - - } - - writel(reg, base + EXYNOS4_IMG_FMT_REG); -} - -void __exynos4_jpeg_set_enc_out_fmt(void __iomem *base, unsigned int out_fmt, - unsigned int version) -{ - unsigned int reg; - - reg = readl(base + EXYNOS4_IMG_FMT_REG) & - ~(version == SJPEG_EXYNOS4 ? EXYNOS4_ENC_FMT_MASK : - EXYNOS5433_ENC_FMT_MASK); /* clear enc format */ - - switch (out_fmt) { - case V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY: - reg = reg | EXYNOS4_ENC_FMT_GRAY; - break; - - case V4L2_JPEG_CHROMA_SUBSAMPLING_444: - reg = reg | EXYNOS4_ENC_FMT_YUV_444; - break; - - case V4L2_JPEG_CHROMA_SUBSAMPLING_422: - reg = reg | EXYNOS4_ENC_FMT_YUV_422; - break; - - case V4L2_JPEG_CHROMA_SUBSAMPLING_420: - reg = reg | EXYNOS4_ENC_FMT_YUV_420; - break; - - default: - break; - } - - writel(reg, base + EXYNOS4_IMG_FMT_REG); -} - -void exynos4_jpeg_set_interrupt(void __iomem *base, unsigned int version) -{ - unsigned int reg; - - if (version == SJPEG_EXYNOS4) { - reg = readl(base + EXYNOS4_INT_EN_REG) & ~EXYNOS4_INT_EN_MASK; - writel(reg | EXYNOS4_INT_EN_ALL, base + EXYNOS4_INT_EN_REG); - } else { - reg = readl(base + EXYNOS4_INT_EN_REG) & - ~EXYNOS5433_INT_EN_MASK; - writel(reg | EXYNOS5433_INT_EN_ALL, base + EXYNOS4_INT_EN_REG); - } -} - -unsigned int exynos4_jpeg_get_int_status(void __iomem *base) -{ - return readl(base + EXYNOS4_INT_STATUS_REG); -} - -unsigned int exynos4_jpeg_get_fifo_status(void __iomem *base) -{ - return readl(base + EXYNOS4_FIFO_STATUS_REG); -} - -void exynos4_jpeg_set_huf_table_enable(void __iomem *base, int value) -{ - unsigned int reg; - - reg = readl(base + EXYNOS4_JPEG_CNTL_REG) & ~EXYNOS4_HUF_TBL_EN; - - if (value == 1) - writel(reg | EXYNOS4_HUF_TBL_EN, - base + EXYNOS4_JPEG_CNTL_REG); - else - writel(reg & ~EXYNOS4_HUF_TBL_EN, - base + EXYNOS4_JPEG_CNTL_REG); -} - -void exynos4_jpeg_set_sys_int_enable(void __iomem *base, int value) -{ - unsigned int reg; - - reg = readl(base + EXYNOS4_JPEG_CNTL_REG) & ~(EXYNOS4_SYS_INT_EN); - - if (value == 1) - writel(reg | EXYNOS4_SYS_INT_EN, base + EXYNOS4_JPEG_CNTL_REG); - else - writel(reg & ~EXYNOS4_SYS_INT_EN, base + EXYNOS4_JPEG_CNTL_REG); -} - -void exynos4_jpeg_set_stream_buf_address(void __iomem *base, - unsigned int address) -{ - writel(address, base + EXYNOS4_OUT_MEM_BASE_REG); -} - -void exynos4_jpeg_set_stream_size(void __iomem *base, - unsigned int x_value, unsigned int y_value) -{ - writel(0x0, base + EXYNOS4_JPEG_IMG_SIZE_REG); /* clear */ - writel(EXYNOS4_X_SIZE(x_value) | EXYNOS4_Y_SIZE(y_value), - base + EXYNOS4_JPEG_IMG_SIZE_REG); -} - -void exynos4_jpeg_set_frame_buf_address(void __iomem *base, - struct s5p_jpeg_addr *exynos4_jpeg_addr) -{ - writel(exynos4_jpeg_addr->y, base + EXYNOS4_IMG_BA_PLANE_1_REG); - writel(exynos4_jpeg_addr->cb, base + EXYNOS4_IMG_BA_PLANE_2_REG); - writel(exynos4_jpeg_addr->cr, base + EXYNOS4_IMG_BA_PLANE_3_REG); -} - -void exynos4_jpeg_set_encode_tbl_select(void __iomem *base, - enum exynos4_jpeg_img_quality_level level) -{ - unsigned int reg; - - reg = EXYNOS4_Q_TBL_COMP1_0 | EXYNOS4_Q_TBL_COMP2_1 | - EXYNOS4_Q_TBL_COMP3_1 | - EXYNOS4_HUFF_TBL_COMP1_AC_0_DC_1 | - EXYNOS4_HUFF_TBL_COMP2_AC_0_DC_0 | - EXYNOS4_HUFF_TBL_COMP3_AC_1_DC_1; - - writel(reg, base + EXYNOS4_TBL_SEL_REG); -} - -void exynos4_jpeg_set_dec_components(void __iomem *base, int n) -{ - unsigned int reg; - - reg = readl(base + EXYNOS4_TBL_SEL_REG); - - reg |= EXYNOS4_NF(n); - writel(reg, base + EXYNOS4_TBL_SEL_REG); -} - -void exynos4_jpeg_select_dec_q_tbl(void __iomem *base, char c, char x) -{ - unsigned int reg; - - reg = readl(base + EXYNOS4_TBL_SEL_REG); - - reg |= EXYNOS4_Q_TBL_COMP(c, x); - writel(reg, base + EXYNOS4_TBL_SEL_REG); -} - -void exynos4_jpeg_select_dec_h_tbl(void __iomem *base, char c, char x) -{ - unsigned int reg; - - reg = readl(base + EXYNOS4_TBL_SEL_REG); - - reg |= EXYNOS4_HUFF_TBL_COMP(c, x); - writel(reg, base + EXYNOS4_TBL_SEL_REG); -} - -void exynos4_jpeg_set_encode_hoff_cnt(void __iomem *base, unsigned int fmt) -{ - if (fmt == V4L2_PIX_FMT_GREY) - writel(0xd2, base + EXYNOS4_HUFF_CNT_REG); - else - writel(0x1a2, base + EXYNOS4_HUFF_CNT_REG); -} - -unsigned int exynos4_jpeg_get_stream_size(void __iomem *base) -{ - return readl(base + EXYNOS4_BITSTREAM_SIZE_REG); -} - -void exynos4_jpeg_set_dec_bitstream_size(void __iomem *base, unsigned int size) -{ - writel(size, base + EXYNOS4_BITSTREAM_SIZE_REG); -} - -void exynos4_jpeg_get_frame_size(void __iomem *base, - unsigned int *width, unsigned int *height) -{ - *width = (readl(base + EXYNOS4_DECODE_XY_SIZE_REG) & - EXYNOS4_DECODED_SIZE_MASK); - *height = (readl(base + EXYNOS4_DECODE_XY_SIZE_REG) >> 16) & - EXYNOS4_DECODED_SIZE_MASK; -} - -unsigned int exynos4_jpeg_get_frame_fmt(void __iomem *base) -{ - return readl(base + EXYNOS4_DECODE_IMG_FMT_REG) & - EXYNOS4_JPEG_DECODED_IMG_FMT_MASK; -} - -void exynos4_jpeg_set_timer_count(void __iomem *base, unsigned int size) -{ - writel(size, base + EXYNOS4_INT_TIMER_COUNT_REG); -} diff --git a/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.h b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.h deleted file mode 100644 index 3e2887526960..000000000000 --- a/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.h +++ /dev/null @@ -1,44 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2013 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * Author: Jacek Anaszewski - * - * Header file of the register interface for JPEG driver on Exynos4x12. -*/ - -#ifndef JPEG_HW_EXYNOS4_H_ -#define JPEG_HW_EXYNOS4_H_ - -void exynos4_jpeg_sw_reset(void __iomem *base); -void exynos4_jpeg_set_enc_dec_mode(void __iomem *base, unsigned int mode); -void __exynos4_jpeg_set_img_fmt(void __iomem *base, unsigned int img_fmt, - unsigned int version); -void __exynos4_jpeg_set_enc_out_fmt(void __iomem *base, unsigned int out_fmt, - unsigned int version); -void exynos4_jpeg_set_enc_tbl(void __iomem *base); -void exynos4_jpeg_set_interrupt(void __iomem *base, unsigned int version); -unsigned int exynos4_jpeg_get_int_status(void __iomem *base); -void exynos4_jpeg_set_huf_table_enable(void __iomem *base, int value); -void exynos4_jpeg_set_sys_int_enable(void __iomem *base, int value); -void exynos4_jpeg_set_stream_buf_address(void __iomem *base, - unsigned int address); -void exynos4_jpeg_set_stream_size(void __iomem *base, - unsigned int x_value, unsigned int y_value); -void exynos4_jpeg_set_frame_buf_address(void __iomem *base, - struct s5p_jpeg_addr *jpeg_addr); -void exynos4_jpeg_set_encode_tbl_select(void __iomem *base, - enum exynos4_jpeg_img_quality_level level); -void exynos4_jpeg_set_dec_components(void __iomem *base, int n); -void exynos4_jpeg_select_dec_q_tbl(void __iomem *base, char c, char x); -void exynos4_jpeg_select_dec_h_tbl(void __iomem *base, char c, char x); -void exynos4_jpeg_set_encode_hoff_cnt(void __iomem *base, unsigned int fmt); -void exynos4_jpeg_set_dec_bitstream_size(void __iomem *base, unsigned int size); -unsigned int exynos4_jpeg_get_stream_size(void __iomem *base); -void exynos4_jpeg_get_frame_size(void __iomem *base, - unsigned int *width, unsigned int *height); -unsigned int exynos4_jpeg_get_frame_fmt(void __iomem *base); -unsigned int exynos4_jpeg_get_fifo_status(void __iomem *base); -void exynos4_jpeg_set_timer_count(void __iomem *base, unsigned int size); - -#endif /* JPEG_HW_EXYNOS4_H_ */ diff --git a/drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.c b/drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.c deleted file mode 100644 index 491e9248286c..000000000000 --- a/drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.c +++ /dev/null @@ -1,306 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* linux/drivers/media/platform/s5p-jpeg/jpeg-hw.h - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * Author: Andrzej Pietrasiewicz - */ - -#include -#include - -#include "jpeg-core.h" -#include "jpeg-regs.h" -#include "jpeg-hw-s5p.h" - -void s5p_jpeg_reset(void __iomem *regs) -{ - unsigned long reg; - - writel(1, regs + S5P_JPG_SW_RESET); - reg = readl(regs + S5P_JPG_SW_RESET); - /* no other way but polling for when JPEG IP becomes operational */ - while (reg != 0) { - cpu_relax(); - reg = readl(regs + S5P_JPG_SW_RESET); - } -} - -void s5p_jpeg_poweron(void __iomem *regs) -{ - writel(S5P_POWER_ON, regs + S5P_JPGCLKCON); -} - -void s5p_jpeg_input_raw_mode(void __iomem *regs, unsigned long mode) -{ - unsigned long reg, m; - - m = S5P_MOD_SEL_565; - if (mode == S5P_JPEG_RAW_IN_565) - m = S5P_MOD_SEL_565; - else if (mode == S5P_JPEG_RAW_IN_422) - m = S5P_MOD_SEL_422; - - reg = readl(regs + S5P_JPGCMOD); - reg &= ~S5P_MOD_SEL_MASK; - reg |= m; - writel(reg, regs + S5P_JPGCMOD); -} - -void s5p_jpeg_proc_mode(void __iomem *regs, unsigned long mode) -{ - unsigned long reg, m; - - m = S5P_PROC_MODE_DECOMPR; - if (mode == S5P_JPEG_ENCODE) - m = S5P_PROC_MODE_COMPR; - else - m = S5P_PROC_MODE_DECOMPR; - reg = readl(regs + S5P_JPGMOD); - reg &= ~S5P_PROC_MODE_MASK; - reg |= m; - writel(reg, regs + S5P_JPGMOD); -} - -void s5p_jpeg_subsampling_mode(void __iomem *regs, unsigned int mode) -{ - unsigned long reg, m; - - if (mode == V4L2_JPEG_CHROMA_SUBSAMPLING_420) - m = S5P_SUBSAMPLING_MODE_420; - else - m = S5P_SUBSAMPLING_MODE_422; - - reg = readl(regs + S5P_JPGMOD); - reg &= ~S5P_SUBSAMPLING_MODE_MASK; - reg |= m; - writel(reg, regs + S5P_JPGMOD); -} - -unsigned int s5p_jpeg_get_subsampling_mode(void __iomem *regs) -{ - return readl(regs + S5P_JPGMOD) & S5P_SUBSAMPLING_MODE_MASK; -} - -void s5p_jpeg_dri(void __iomem *regs, unsigned int dri) -{ - unsigned long reg; - - reg = readl(regs + S5P_JPGDRI_U); - reg &= ~0xff; - reg |= (dri >> 8) & 0xff; - writel(reg, regs + S5P_JPGDRI_U); - - reg = readl(regs + S5P_JPGDRI_L); - reg &= ~0xff; - reg |= dri & 0xff; - writel(reg, regs + S5P_JPGDRI_L); -} - -void s5p_jpeg_qtbl(void __iomem *regs, unsigned int t, unsigned int n) -{ - unsigned long reg; - - reg = readl(regs + S5P_JPG_QTBL); - reg &= ~S5P_QT_NUMt_MASK(t); - reg |= (n << S5P_QT_NUMt_SHIFT(t)) & S5P_QT_NUMt_MASK(t); - writel(reg, regs + S5P_JPG_QTBL); -} - -void s5p_jpeg_htbl_ac(void __iomem *regs, unsigned int t) -{ - unsigned long reg; - - reg = readl(regs + S5P_JPG_HTBL); - reg &= ~S5P_HT_NUMt_AC_MASK(t); - /* this driver uses table 0 for all color components */ - reg |= (0 << S5P_HT_NUMt_AC_SHIFT(t)) & S5P_HT_NUMt_AC_MASK(t); - writel(reg, regs + S5P_JPG_HTBL); -} - -void s5p_jpeg_htbl_dc(void __iomem *regs, unsigned int t) -{ - unsigned long reg; - - reg = readl(regs + S5P_JPG_HTBL); - reg &= ~S5P_HT_NUMt_DC_MASK(t); - /* this driver uses table 0 for all color components */ - reg |= (0 << S5P_HT_NUMt_DC_SHIFT(t)) & S5P_HT_NUMt_DC_MASK(t); - writel(reg, regs + S5P_JPG_HTBL); -} - -void s5p_jpeg_y(void __iomem *regs, unsigned int y) -{ - unsigned long reg; - - reg = readl(regs + S5P_JPGY_U); - reg &= ~0xff; - reg |= (y >> 8) & 0xff; - writel(reg, regs + S5P_JPGY_U); - - reg = readl(regs + S5P_JPGY_L); - reg &= ~0xff; - reg |= y & 0xff; - writel(reg, regs + S5P_JPGY_L); -} - -void s5p_jpeg_x(void __iomem *regs, unsigned int x) -{ - unsigned long reg; - - reg = readl(regs + S5P_JPGX_U); - reg &= ~0xff; - reg |= (x >> 8) & 0xff; - writel(reg, regs + S5P_JPGX_U); - - reg = readl(regs + S5P_JPGX_L); - reg &= ~0xff; - reg |= x & 0xff; - writel(reg, regs + S5P_JPGX_L); -} - -void s5p_jpeg_rst_int_enable(void __iomem *regs, bool enable) -{ - unsigned long reg; - - reg = readl(regs + S5P_JPGINTSE); - reg &= ~S5P_RSTm_INT_EN_MASK; - if (enable) - reg |= S5P_RSTm_INT_EN; - writel(reg, regs + S5P_JPGINTSE); -} - -void s5p_jpeg_data_num_int_enable(void __iomem *regs, bool enable) -{ - unsigned long reg; - - reg = readl(regs + S5P_JPGINTSE); - reg &= ~S5P_DATA_NUM_INT_EN_MASK; - if (enable) - reg |= S5P_DATA_NUM_INT_EN; - writel(reg, regs + S5P_JPGINTSE); -} - -void s5p_jpeg_final_mcu_num_int_enable(void __iomem *regs, bool enbl) -{ - unsigned long reg; - - reg = readl(regs + S5P_JPGINTSE); - reg &= ~S5P_FINAL_MCU_NUM_INT_EN_MASK; - if (enbl) - reg |= S5P_FINAL_MCU_NUM_INT_EN; - writel(reg, regs + S5P_JPGINTSE); -} - -int s5p_jpeg_timer_stat(void __iomem *regs) -{ - return (int)((readl(regs + S5P_JPG_TIMER_ST) & S5P_TIMER_INT_STAT_MASK) - >> S5P_TIMER_INT_STAT_SHIFT); -} - -void s5p_jpeg_clear_timer_stat(void __iomem *regs) -{ - unsigned long reg; - - reg = readl(regs + S5P_JPG_TIMER_SE); - reg &= ~S5P_TIMER_INT_STAT_MASK; - writel(reg, regs + S5P_JPG_TIMER_SE); -} - -void s5p_jpeg_enc_stream_int(void __iomem *regs, unsigned long size) -{ - unsigned long reg; - - reg = readl(regs + S5P_JPG_ENC_STREAM_INTSE); - reg &= ~S5P_ENC_STREAM_BOUND_MASK; - reg |= S5P_ENC_STREAM_INT_EN; - reg |= size & S5P_ENC_STREAM_BOUND_MASK; - writel(reg, regs + S5P_JPG_ENC_STREAM_INTSE); -} - -int s5p_jpeg_enc_stream_stat(void __iomem *regs) -{ - return (int)(readl(regs + S5P_JPG_ENC_STREAM_INTST) & - S5P_ENC_STREAM_INT_STAT_MASK); -} - -void s5p_jpeg_clear_enc_stream_stat(void __iomem *regs) -{ - unsigned long reg; - - reg = readl(regs + S5P_JPG_ENC_STREAM_INTSE); - reg &= ~S5P_ENC_STREAM_INT_MASK; - writel(reg, regs + S5P_JPG_ENC_STREAM_INTSE); -} - -void s5p_jpeg_outform_raw(void __iomem *regs, unsigned long format) -{ - unsigned long reg, f; - - f = S5P_DEC_OUT_FORMAT_422; - if (format == S5P_JPEG_RAW_OUT_422) - f = S5P_DEC_OUT_FORMAT_422; - else if (format == S5P_JPEG_RAW_OUT_420) - f = S5P_DEC_OUT_FORMAT_420; - reg = readl(regs + S5P_JPG_OUTFORM); - reg &= ~S5P_DEC_OUT_FORMAT_MASK; - reg |= f; - writel(reg, regs + S5P_JPG_OUTFORM); -} - -void s5p_jpeg_jpgadr(void __iomem *regs, unsigned long addr) -{ - writel(addr, regs + S5P_JPG_JPGADR); -} - -void s5p_jpeg_imgadr(void __iomem *regs, unsigned long addr) -{ - writel(addr, regs + S5P_JPG_IMGADR); -} - -void s5p_jpeg_coef(void __iomem *regs, unsigned int i, - unsigned int j, unsigned int coef) -{ - unsigned long reg; - - reg = readl(regs + S5P_JPG_COEF(i)); - reg &= ~S5P_COEFn_MASK(j); - reg |= (coef << S5P_COEFn_SHIFT(j)) & S5P_COEFn_MASK(j); - writel(reg, regs + S5P_JPG_COEF(i)); -} - -void s5p_jpeg_start(void __iomem *regs) -{ - writel(1, regs + S5P_JSTART); -} - -int s5p_jpeg_result_stat_ok(void __iomem *regs) -{ - return (int)((readl(regs + S5P_JPGINTST) & S5P_RESULT_STAT_MASK) - >> S5P_RESULT_STAT_SHIFT); -} - -int s5p_jpeg_stream_stat_ok(void __iomem *regs) -{ - return !(int)((readl(regs + S5P_JPGINTST) & S5P_STREAM_STAT_MASK) - >> S5P_STREAM_STAT_SHIFT); -} - -void s5p_jpeg_clear_int(void __iomem *regs) -{ - readl(regs + S5P_JPGINTST); - writel(S5P_INT_RELEASE, regs + S5P_JPGCOM); - readl(regs + S5P_JPGOPR); -} - -unsigned int s5p_jpeg_compressed_size(void __iomem *regs) -{ - unsigned long jpeg_size = 0; - - jpeg_size |= (readl(regs + S5P_JPGCNT_U) & 0xff) << 16; - jpeg_size |= (readl(regs + S5P_JPGCNT_M) & 0xff) << 8; - jpeg_size |= (readl(regs + S5P_JPGCNT_L) & 0xff); - - return (unsigned int)jpeg_size; -} diff --git a/drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.h b/drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.h deleted file mode 100644 index 98ddf7097562..000000000000 --- a/drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.h +++ /dev/null @@ -1,57 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* linux/drivers/media/platform/s5p-jpeg/jpeg-hw.h - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * Author: Andrzej Pietrasiewicz - */ -#ifndef JPEG_HW_S5P_H_ -#define JPEG_HW_S5P_H_ - -#include -#include - -#include "jpeg-regs.h" - -#define S5P_JPEG_MIN_WIDTH 32 -#define S5P_JPEG_MIN_HEIGHT 32 -#define S5P_JPEG_MAX_WIDTH 8192 -#define S5P_JPEG_MAX_HEIGHT 8192 -#define S5P_JPEG_RAW_IN_565 0 -#define S5P_JPEG_RAW_IN_422 1 -#define S5P_JPEG_RAW_OUT_422 0 -#define S5P_JPEG_RAW_OUT_420 1 - -void s5p_jpeg_reset(void __iomem *regs); -void s5p_jpeg_poweron(void __iomem *regs); -void s5p_jpeg_input_raw_mode(void __iomem *regs, unsigned long mode); -void s5p_jpeg_proc_mode(void __iomem *regs, unsigned long mode); -void s5p_jpeg_subsampling_mode(void __iomem *regs, unsigned int mode); -unsigned int s5p_jpeg_get_subsampling_mode(void __iomem *regs); -void s5p_jpeg_dri(void __iomem *regs, unsigned int dri); -void s5p_jpeg_qtbl(void __iomem *regs, unsigned int t, unsigned int n); -void s5p_jpeg_htbl_ac(void __iomem *regs, unsigned int t); -void s5p_jpeg_htbl_dc(void __iomem *regs, unsigned int t); -void s5p_jpeg_y(void __iomem *regs, unsigned int y); -void s5p_jpeg_x(void __iomem *regs, unsigned int x); -void s5p_jpeg_rst_int_enable(void __iomem *regs, bool enable); -void s5p_jpeg_data_num_int_enable(void __iomem *regs, bool enable); -void s5p_jpeg_final_mcu_num_int_enable(void __iomem *regs, bool enbl); -int s5p_jpeg_timer_stat(void __iomem *regs); -void s5p_jpeg_clear_timer_stat(void __iomem *regs); -void s5p_jpeg_enc_stream_int(void __iomem *regs, unsigned long size); -int s5p_jpeg_enc_stream_stat(void __iomem *regs); -void s5p_jpeg_clear_enc_stream_stat(void __iomem *regs); -void s5p_jpeg_outform_raw(void __iomem *regs, unsigned long format); -void s5p_jpeg_jpgadr(void __iomem *regs, unsigned long addr); -void s5p_jpeg_imgadr(void __iomem *regs, unsigned long addr); -void s5p_jpeg_coef(void __iomem *regs, unsigned int i, - unsigned int j, unsigned int coef); -void s5p_jpeg_start(void __iomem *regs); -int s5p_jpeg_result_stat_ok(void __iomem *regs); -int s5p_jpeg_stream_stat_ok(void __iomem *regs); -void s5p_jpeg_clear_int(void __iomem *regs); -unsigned int s5p_jpeg_compressed_size(void __iomem *regs); - -#endif /* JPEG_HW_S5P_H_ */ diff --git a/drivers/media/platform/s5p-jpeg/jpeg-regs.h b/drivers/media/platform/s5p-jpeg/jpeg-regs.h deleted file mode 100644 index 86f376b50581..000000000000 --- a/drivers/media/platform/s5p-jpeg/jpeg-regs.h +++ /dev/null @@ -1,646 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* linux/drivers/media/platform/s5p-jpeg/jpeg-regs.h - * - * Register definition file for Samsung JPEG codec driver - * - * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * Author: Andrzej Pietrasiewicz - * Author: Jacek Anaszewski - */ - -#ifndef JPEG_REGS_H_ -#define JPEG_REGS_H_ - -/* Register and bit definitions for S5PC210 */ - -/* JPEG mode register */ -#define S5P_JPGMOD 0x00 -#define S5P_PROC_MODE_MASK (0x1 << 3) -#define S5P_PROC_MODE_DECOMPR (0x1 << 3) -#define S5P_PROC_MODE_COMPR (0x0 << 3) -#define S5P_SUBSAMPLING_MODE_MASK 0x7 -#define S5P_SUBSAMPLING_MODE_444 (0x0 << 0) -#define S5P_SUBSAMPLING_MODE_422 (0x1 << 0) -#define S5P_SUBSAMPLING_MODE_420 (0x2 << 0) -#define S5P_SUBSAMPLING_MODE_GRAY (0x3 << 0) - -/* JPEG operation status register */ -#define S5P_JPGOPR 0x04 - -/* Quantization tables*/ -#define S5P_JPG_QTBL 0x08 -#define S5P_QT_NUMt_SHIFT(t) (((t) - 1) << 1) -#define S5P_QT_NUMt_MASK(t) (0x3 << S5P_QT_NUMt_SHIFT(t)) - -/* Huffman tables */ -#define S5P_JPG_HTBL 0x0c -#define S5P_HT_NUMt_AC_SHIFT(t) (((t) << 1) - 1) -#define S5P_HT_NUMt_AC_MASK(t) (0x1 << S5P_HT_NUMt_AC_SHIFT(t)) - -#define S5P_HT_NUMt_DC_SHIFT(t) (((t) - 1) << 1) -#define S5P_HT_NUMt_DC_MASK(t) (0x1 << S5P_HT_NUMt_DC_SHIFT(t)) - -/* JPEG restart interval register upper byte */ -#define S5P_JPGDRI_U 0x10 - -/* JPEG restart interval register lower byte */ -#define S5P_JPGDRI_L 0x14 - -/* JPEG vertical resolution register upper byte */ -#define S5P_JPGY_U 0x18 - -/* JPEG vertical resolution register lower byte */ -#define S5P_JPGY_L 0x1c - -/* JPEG horizontal resolution register upper byte */ -#define S5P_JPGX_U 0x20 - -/* JPEG horizontal resolution register lower byte */ -#define S5P_JPGX_L 0x24 - -/* JPEG byte count register upper byte */ -#define S5P_JPGCNT_U 0x28 - -/* JPEG byte count register middle byte */ -#define S5P_JPGCNT_M 0x2c - -/* JPEG byte count register lower byte */ -#define S5P_JPGCNT_L 0x30 - -/* JPEG interrupt setting register */ -#define S5P_JPGINTSE 0x34 -#define S5P_RSTm_INT_EN_MASK (0x1 << 7) -#define S5P_RSTm_INT_EN (0x1 << 7) -#define S5P_DATA_NUM_INT_EN_MASK (0x1 << 6) -#define S5P_DATA_NUM_INT_EN (0x1 << 6) -#define S5P_FINAL_MCU_NUM_INT_EN_MASK (0x1 << 5) -#define S5P_FINAL_MCU_NUM_INT_EN (0x1 << 5) - -/* JPEG interrupt status register */ -#define S5P_JPGINTST 0x38 -#define S5P_RESULT_STAT_SHIFT 6 -#define S5P_RESULT_STAT_MASK (0x1 << S5P_RESULT_STAT_SHIFT) -#define S5P_STREAM_STAT_SHIFT 5 -#define S5P_STREAM_STAT_MASK (0x1 << S5P_STREAM_STAT_SHIFT) - -/* JPEG command register */ -#define S5P_JPGCOM 0x4c -#define S5P_INT_RELEASE (0x1 << 2) - -/* Raw image data r/w address register */ -#define S5P_JPG_IMGADR 0x50 - -/* JPEG file r/w address register */ -#define S5P_JPG_JPGADR 0x58 - -/* Coefficient for RGB-to-YCbCr converter register */ -#define S5P_JPG_COEF(n) (0x5c + (((n) - 1) << 2)) -#define S5P_COEFn_SHIFT(j) ((3 - (j)) << 3) -#define S5P_COEFn_MASK(j) (0xff << S5P_COEFn_SHIFT(j)) - -/* JPEG color mode register */ -#define S5P_JPGCMOD 0x68 -#define S5P_MOD_SEL_MASK (0x7 << 5) -#define S5P_MOD_SEL_422 (0x1 << 5) -#define S5P_MOD_SEL_565 (0x2 << 5) -#define S5P_MODE_Y16_MASK (0x1 << 1) -#define S5P_MODE_Y16 (0x1 << 1) - -/* JPEG clock control register */ -#define S5P_JPGCLKCON 0x6c -#define S5P_CLK_DOWN_READY (0x1 << 1) -#define S5P_POWER_ON (0x1 << 0) - -/* JPEG start register */ -#define S5P_JSTART 0x70 - -/* JPEG SW reset register */ -#define S5P_JPG_SW_RESET 0x78 - -/* JPEG timer setting register */ -#define S5P_JPG_TIMER_SE 0x7c -#define S5P_TIMER_INT_EN_MASK (0x1UL << 31) -#define S5P_TIMER_INT_EN (0x1UL << 31) -#define S5P_TIMER_INIT_MASK 0x7fffffff - -/* JPEG timer status register */ -#define S5P_JPG_TIMER_ST 0x80 -#define S5P_TIMER_INT_STAT_SHIFT 31 -#define S5P_TIMER_INT_STAT_MASK (0x1UL << S5P_TIMER_INT_STAT_SHIFT) -#define S5P_TIMER_CNT_SHIFT 0 -#define S5P_TIMER_CNT_MASK 0x7fffffff - -/* JPEG decompression output format register */ -#define S5P_JPG_OUTFORM 0x88 -#define S5P_DEC_OUT_FORMAT_MASK (0x1 << 0) -#define S5P_DEC_OUT_FORMAT_422 (0x0 << 0) -#define S5P_DEC_OUT_FORMAT_420 (0x1 << 0) - -/* JPEG version register */ -#define S5P_JPG_VERSION 0x8c - -/* JPEG compressed stream size interrupt setting register */ -#define S5P_JPG_ENC_STREAM_INTSE 0x98 -#define S5P_ENC_STREAM_INT_MASK (0x1 << 24) -#define S5P_ENC_STREAM_INT_EN (0x1 << 24) -#define S5P_ENC_STREAM_BOUND_MASK 0xffffff - -/* JPEG compressed stream size interrupt status register */ -#define S5P_JPG_ENC_STREAM_INTST 0x9c -#define S5P_ENC_STREAM_INT_STAT_MASK 0x1 - -/* JPEG quantizer table register */ -#define S5P_JPG_QTBL_CONTENT(n) (0x400 + (n) * 0x100) - -/* JPEG DC Huffman table register */ -#define S5P_JPG_HDCTBL(n) (0x800 + (n) * 0x400) - -/* JPEG DC Huffman table register */ -#define S5P_JPG_HDCTBLG(n) (0x840 + (n) * 0x400) - -/* JPEG AC Huffman table register */ -#define S5P_JPG_HACTBL(n) (0x880 + (n) * 0x400) - -/* JPEG AC Huffman table register */ -#define S5P_JPG_HACTBLG(n) (0x8c0 + (n) * 0x400) - - -/* Register and bit definitions for Exynos 4x12 */ - -/* JPEG Codec Control Registers */ -#define EXYNOS4_JPEG_CNTL_REG 0x00 -#define EXYNOS4_INT_EN_REG 0x04 -#define EXYNOS4_INT_TIMER_COUNT_REG 0x08 -#define EXYNOS4_INT_STATUS_REG 0x0c -#define EXYNOS4_OUT_MEM_BASE_REG 0x10 -#define EXYNOS4_JPEG_IMG_SIZE_REG 0x14 -#define EXYNOS4_IMG_BA_PLANE_1_REG 0x18 -#define EXYNOS4_IMG_SO_PLANE_1_REG 0x1c -#define EXYNOS4_IMG_PO_PLANE_1_REG 0x20 -#define EXYNOS4_IMG_BA_PLANE_2_REG 0x24 -#define EXYNOS4_IMG_SO_PLANE_2_REG 0x28 -#define EXYNOS4_IMG_PO_PLANE_2_REG 0x2c -#define EXYNOS4_IMG_BA_PLANE_3_REG 0x30 -#define EXYNOS4_IMG_SO_PLANE_3_REG 0x34 -#define EXYNOS4_IMG_PO_PLANE_3_REG 0x38 - -#define EXYNOS4_TBL_SEL_REG 0x3c - -#define EXYNOS4_IMG_FMT_REG 0x40 - -#define EXYNOS4_BITSTREAM_SIZE_REG 0x44 -#define EXYNOS4_PADDING_REG 0x48 -#define EXYNOS4_HUFF_CNT_REG 0x4c -#define EXYNOS4_FIFO_STATUS_REG 0x50 -#define EXYNOS4_DECODE_XY_SIZE_REG 0x54 -#define EXYNOS4_DECODE_IMG_FMT_REG 0x58 - -#define EXYNOS4_QUAN_TBL_ENTRY_REG 0x100 -#define EXYNOS4_HUFF_TBL_ENTRY_REG 0x200 - - -/****************************************************************/ -/* Bit definition part */ -/****************************************************************/ - -/* JPEG CNTL Register bit */ -#define EXYNOS4_ENC_DEC_MODE_MASK (0xfffffffc << 0) -#define EXYNOS4_DEC_MODE (1 << 0) -#define EXYNOS4_ENC_MODE (1 << 1) -#define EXYNOS4_AUTO_RST_MARKER (1 << 2) -#define EXYNOS4_RST_INTERVAL_SHIFT 3 -#define EXYNOS4_RST_INTERVAL(x) (((x) & 0xffff) \ - << EXYNOS4_RST_INTERVAL_SHIFT) -#define EXYNOS4_HUF_TBL_EN (1 << 19) -#define EXYNOS4_HOR_SCALING_SHIFT 20 -#define EXYNOS4_HOR_SCALING_MASK (3 << EXYNOS4_HOR_SCALING_SHIFT) -#define EXYNOS4_HOR_SCALING(x) (((x) & 0x3) \ - << EXYNOS4_HOR_SCALING_SHIFT) -#define EXYNOS4_VER_SCALING_SHIFT 22 -#define EXYNOS4_VER_SCALING_MASK (3 << EXYNOS4_VER_SCALING_SHIFT) -#define EXYNOS4_VER_SCALING(x) (((x) & 0x3) \ - << EXYNOS4_VER_SCALING_SHIFT) -#define EXYNOS4_PADDING (1 << 27) -#define EXYNOS4_SYS_INT_EN (1 << 28) -#define EXYNOS4_SOFT_RESET_HI (1 << 29) - -/* JPEG INT Register bit */ -#define EXYNOS4_INT_EN_MASK (0x1f << 0) -#define EXYNOS5433_INT_EN_MASK (0x1ff << 0) -#define EXYNOS4_PROT_ERR_INT_EN (1 << 0) -#define EXYNOS4_IMG_COMPLETION_INT_EN (1 << 1) -#define EXYNOS4_DEC_INVALID_FORMAT_EN (1 << 2) -#define EXYNOS4_MULTI_SCAN_ERROR_EN (1 << 3) -#define EXYNOS4_FRAME_ERR_EN (1 << 4) -#define EXYNOS4_INT_EN_ALL (0x1f << 0) -#define EXYNOS5433_INT_EN_ALL (0x1b6 << 0) - -#define EXYNOS4_MOD_REG_PROC_ENC (0 << 3) -#define EXYNOS4_MOD_REG_PROC_DEC (1 << 3) - -#define EXYNOS4_MOD_REG_SUBSAMPLE_444 (0 << 0) -#define EXYNOS4_MOD_REG_SUBSAMPLE_422 (1 << 0) -#define EXYNOS4_MOD_REG_SUBSAMPLE_420 (2 << 0) -#define EXYNOS4_MOD_REG_SUBSAMPLE_GRAY (3 << 0) - - -/* JPEG IMAGE SIZE Register bit */ -#define EXYNOS4_X_SIZE_SHIFT 0 -#define EXYNOS4_X_SIZE_MASK (0xffff << EXYNOS4_X_SIZE_SHIFT) -#define EXYNOS4_X_SIZE(x) (((x) & 0xffff) << EXYNOS4_X_SIZE_SHIFT) -#define EXYNOS4_Y_SIZE_SHIFT 16 -#define EXYNOS4_Y_SIZE_MASK (0xffff << EXYNOS4_Y_SIZE_SHIFT) -#define EXYNOS4_Y_SIZE(x) (((x) & 0xffff) << EXYNOS4_Y_SIZE_SHIFT) - -/* JPEG IMAGE FORMAT Register bit */ -#define EXYNOS4_ENC_IN_FMT_MASK 0xffff0000 -#define EXYNOS4_ENC_GRAY_IMG (0 << 0) -#define EXYNOS4_ENC_RGB_IMG (1 << 0) -#define EXYNOS4_ENC_YUV_444_IMG (2 << 0) -#define EXYNOS4_ENC_YUV_422_IMG (3 << 0) -#define EXYNOS4_ENC_YUV_440_IMG (4 << 0) - -#define EXYNOS4_DEC_GRAY_IMG (0 << 0) -#define EXYNOS4_DEC_RGB_IMG (1 << 0) -#define EXYNOS4_DEC_YUV_444_IMG (2 << 0) -#define EXYNOS4_DEC_YUV_422_IMG (3 << 0) -#define EXYNOS4_DEC_YUV_420_IMG (4 << 0) - -#define EXYNOS4_GRAY_IMG_IP_SHIFT 3 -#define EXYNOS4_GRAY_IMG_IP_MASK (7 << EXYNOS4_GRAY_IMG_IP_SHIFT) -#define EXYNOS4_GRAY_IMG_IP (4 << EXYNOS4_GRAY_IMG_IP_SHIFT) - -#define EXYNOS4_RGB_IP_SHIFT 6 -#define EXYNOS4_RGB_IP_MASK (7 << EXYNOS4_RGB_IP_SHIFT) -#define EXYNOS4_RGB_IP_RGB_16BIT_IMG (4 << EXYNOS4_RGB_IP_SHIFT) -#define EXYNOS4_RGB_IP_RGB_32BIT_IMG (5 << EXYNOS4_RGB_IP_SHIFT) - -#define EXYNOS4_YUV_444_IP_SHIFT 9 -#define EXYNOS4_YUV_444_IP_MASK (7 << EXYNOS4_YUV_444_IP_SHIFT) -#define EXYNOS4_YUV_444_IP_YUV_444_2P_IMG (4 << EXYNOS4_YUV_444_IP_SHIFT) -#define EXYNOS4_YUV_444_IP_YUV_444_3P_IMG (5 << EXYNOS4_YUV_444_IP_SHIFT) - -#define EXYNOS4_YUV_422_IP_SHIFT 12 -#define EXYNOS4_YUV_422_IP_MASK (7 << EXYNOS4_YUV_422_IP_SHIFT) -#define EXYNOS4_YUV_422_IP_YUV_422_1P_IMG (4 << EXYNOS4_YUV_422_IP_SHIFT) -#define EXYNOS4_YUV_422_IP_YUV_422_2P_IMG (5 << EXYNOS4_YUV_422_IP_SHIFT) -#define EXYNOS4_YUV_422_IP_YUV_422_3P_IMG (6 << EXYNOS4_YUV_422_IP_SHIFT) - -#define EXYNOS4_YUV_420_IP_SHIFT 15 -#define EXYNOS4_YUV_420_IP_MASK (7 << EXYNOS4_YUV_420_IP_SHIFT) -#define EXYNOS4_YUV_420_IP_YUV_420_2P_IMG (4 << EXYNOS4_YUV_420_IP_SHIFT) -#define EXYNOS4_YUV_420_IP_YUV_420_3P_IMG (5 << EXYNOS4_YUV_420_IP_SHIFT) - -#define EXYNOS4_ENC_FMT_SHIFT 24 -#define EXYNOS4_ENC_FMT_MASK (3 << EXYNOS4_ENC_FMT_SHIFT) -#define EXYNOS5433_ENC_FMT_MASK (7 << EXYNOS4_ENC_FMT_SHIFT) - -#define EXYNOS4_ENC_FMT_GRAY (0 << EXYNOS4_ENC_FMT_SHIFT) -#define EXYNOS4_ENC_FMT_YUV_444 (1 << EXYNOS4_ENC_FMT_SHIFT) -#define EXYNOS4_ENC_FMT_YUV_422 (2 << EXYNOS4_ENC_FMT_SHIFT) -#define EXYNOS4_ENC_FMT_YUV_420 (3 << EXYNOS4_ENC_FMT_SHIFT) - -#define EXYNOS4_JPEG_DECODED_IMG_FMT_MASK 0x03 - -#define EXYNOS4_SWAP_CHROMA_CRCB (1 << 26) -#define EXYNOS4_SWAP_CHROMA_CBCR (0 << 26) -#define EXYNOS5433_SWAP_CHROMA_CRCB (1 << 27) -#define EXYNOS5433_SWAP_CHROMA_CBCR (0 << 27) - -/* JPEG HUFF count Register bit */ -#define EXYNOS4_HUFF_COUNT_MASK 0xffff - -/* JPEG Decoded_img_x_y_size Register bit */ -#define EXYNOS4_DECODED_SIZE_MASK 0x0000ffff - -/* JPEG Decoded image format Register bit */ -#define EXYNOS4_DECODED_IMG_FMT_MASK 0x3 - -/* JPEG TBL SEL Register bit */ -#define EXYNOS4_Q_TBL_COMP(c, n) ((n) << (((c) - 1) << 1)) - -#define EXYNOS4_Q_TBL_COMP1_0 EXYNOS4_Q_TBL_COMP(1, 0) -#define EXYNOS4_Q_TBL_COMP1_1 EXYNOS4_Q_TBL_COMP(1, 1) -#define EXYNOS4_Q_TBL_COMP1_2 EXYNOS4_Q_TBL_COMP(1, 2) -#define EXYNOS4_Q_TBL_COMP1_3 EXYNOS4_Q_TBL_COMP(1, 3) - -#define EXYNOS4_Q_TBL_COMP2_0 EXYNOS4_Q_TBL_COMP(2, 0) -#define EXYNOS4_Q_TBL_COMP2_1 EXYNOS4_Q_TBL_COMP(2, 1) -#define EXYNOS4_Q_TBL_COMP2_2 EXYNOS4_Q_TBL_COMP(2, 2) -#define EXYNOS4_Q_TBL_COMP2_3 EXYNOS4_Q_TBL_COMP(2, 3) - -#define EXYNOS4_Q_TBL_COMP3_0 EXYNOS4_Q_TBL_COMP(3, 0) -#define EXYNOS4_Q_TBL_COMP3_1 EXYNOS4_Q_TBL_COMP(3, 1) -#define EXYNOS4_Q_TBL_COMP3_2 EXYNOS4_Q_TBL_COMP(3, 2) -#define EXYNOS4_Q_TBL_COMP3_3 EXYNOS4_Q_TBL_COMP(3, 3) - -#define EXYNOS4_HUFF_TBL_COMP(c, n) ((n) << ((((c) - 1) << 1) + 6)) - -#define EXYNOS4_HUFF_TBL_COMP1_AC_0_DC_0 \ - EXYNOS4_HUFF_TBL_COMP(1, 0) -#define EXYNOS4_HUFF_TBL_COMP1_AC_0_DC_1 \ - EXYNOS4_HUFF_TBL_COMP(1, 1) -#define EXYNOS4_HUFF_TBL_COMP1_AC_1_DC_0 \ - EXYNOS4_HUFF_TBL_COMP(1, 2) -#define EXYNOS4_HUFF_TBL_COMP1_AC_1_DC_1 \ - EXYNOS4_HUFF_TBL_COMP(1, 3) - -#define EXYNOS4_HUFF_TBL_COMP2_AC_0_DC_0 \ - EXYNOS4_HUFF_TBL_COMP(2, 0) -#define EXYNOS4_HUFF_TBL_COMP2_AC_0_DC_1 \ - EXYNOS4_HUFF_TBL_COMP(2, 1) -#define EXYNOS4_HUFF_TBL_COMP2_AC_1_DC_0 \ - EXYNOS4_HUFF_TBL_COMP(2, 2) -#define EXYNOS4_HUFF_TBL_COMP2_AC_1_DC_1 \ - EXYNOS4_HUFF_TBL_COMP(2, 3) - -#define EXYNOS4_HUFF_TBL_COMP3_AC_0_DC_0 \ - EXYNOS4_HUFF_TBL_COMP(3, 0) -#define EXYNOS4_HUFF_TBL_COMP3_AC_0_DC_1 \ - EXYNOS4_HUFF_TBL_COMP(3, 1) -#define EXYNOS4_HUFF_TBL_COMP3_AC_1_DC_0 \ - EXYNOS4_HUFF_TBL_COMP(3, 2) -#define EXYNOS4_HUFF_TBL_COMP3_AC_1_DC_1 \ - EXYNOS4_HUFF_TBL_COMP(3, 3) - -#define EXYNOS4_NF_SHIFT 16 -#define EXYNOS4_NF_MASK 0xff -#define EXYNOS4_NF(x) \ - (((x) & EXYNOS4_NF_MASK) << EXYNOS4_NF_SHIFT) - -/* JPEG quantizer table register */ -#define EXYNOS4_QTBL_CONTENT(n) (0x100 + (n) * 0x40) - -/* JPEG DC luminance (code length) Huffman table register */ -#define EXYNOS4_HUFF_TBL_HDCLL 0x200 - -/* JPEG DC luminance (values) Huffman table register */ -#define EXYNOS4_HUFF_TBL_HDCLV 0x210 - -/* JPEG DC chrominance (code length) Huffman table register */ -#define EXYNOS4_HUFF_TBL_HDCCL 0x220 - -/* JPEG DC chrominance (values) Huffman table register */ -#define EXYNOS4_HUFF_TBL_HDCCV 0x230 - -/* JPEG AC luminance (code length) Huffman table register */ -#define EXYNOS4_HUFF_TBL_HACLL 0x240 - -/* JPEG AC luminance (values) Huffman table register */ -#define EXYNOS4_HUFF_TBL_HACLV 0x250 - -/* JPEG AC chrominance (code length) Huffman table register */ -#define EXYNOS4_HUFF_TBL_HACCL 0x300 - -/* JPEG AC chrominance (values) Huffman table register */ -#define EXYNOS4_HUFF_TBL_HACCV 0x310 - -/* Register and bit definitions for Exynos 3250 */ - -/* JPEG mode register */ -#define EXYNOS3250_JPGMOD 0x00 -#define EXYNOS3250_PROC_MODE_MASK (0x1 << 3) -#define EXYNOS3250_PROC_MODE_DECOMPR (0x1 << 3) -#define EXYNOS3250_PROC_MODE_COMPR (0x0 << 3) -#define EXYNOS3250_SUBSAMPLING_MODE_MASK (0x7 << 0) -#define EXYNOS3250_SUBSAMPLING_MODE_444 (0x0 << 0) -#define EXYNOS3250_SUBSAMPLING_MODE_422 (0x1 << 0) -#define EXYNOS3250_SUBSAMPLING_MODE_420 (0x2 << 0) -#define EXYNOS3250_SUBSAMPLING_MODE_411 (0x6 << 0) -#define EXYNOS3250_SUBSAMPLING_MODE_GRAY (0x3 << 0) - -/* JPEG operation status register */ -#define EXYNOS3250_JPGOPR 0x04 -#define EXYNOS3250_JPGOPR_MASK 0x01 - -/* Quantization and Huffman tables register */ -#define EXYNOS3250_QHTBL 0x08 -#define EXYNOS3250_QT_NUM_SHIFT(t) ((((t) - 1) << 1) + 8) -#define EXYNOS3250_QT_NUM_MASK(t) (0x3 << EXYNOS3250_QT_NUM_SHIFT(t)) - -/* Huffman tables */ -#define EXYNOS3250_HT_NUM_AC_SHIFT(t) (((t) << 1) - 1) -#define EXYNOS3250_HT_NUM_AC_MASK(t) (0x1 << EXYNOS3250_HT_NUM_AC_SHIFT(t)) - -#define EXYNOS3250_HT_NUM_DC_SHIFT(t) (((t) - 1) << 1) -#define EXYNOS3250_HT_NUM_DC_MASK(t) (0x1 << EXYNOS3250_HT_NUM_DC_SHIFT(t)) - -/* JPEG restart interval register */ -#define EXYNOS3250_JPGDRI 0x0c -#define EXYNOS3250_JPGDRI_MASK 0xffff - -/* JPEG vertical resolution register */ -#define EXYNOS3250_JPGY 0x10 -#define EXYNOS3250_JPGY_MASK 0xffff - -/* JPEG horizontal resolution register */ -#define EXYNOS3250_JPGX 0x14 -#define EXYNOS3250_JPGX_MASK 0xffff - -/* JPEG byte count register */ -#define EXYNOS3250_JPGCNT 0x18 -#define EXYNOS3250_JPGCNT_MASK 0xffffff - -/* JPEG interrupt mask register */ -#define EXYNOS3250_JPGINTSE 0x1c -#define EXYNOS3250_JPEG_DONE_EN (1 << 11) -#define EXYNOS3250_WDMA_DONE_EN (1 << 10) -#define EXYNOS3250_RDMA_DONE_EN (1 << 9) -#define EXYNOS3250_ENC_STREAM_INT_EN (1 << 8) -#define EXYNOS3250_CORE_DONE_EN (1 << 5) -#define EXYNOS3250_ERR_INT_EN (1 << 4) -#define EXYNOS3250_HEAD_INT_EN (1 << 3) - -/* JPEG interrupt status register */ -#define EXYNOS3250_JPGINTST 0x20 -#define EXYNOS3250_JPEG_DONE (1 << 11) -#define EXYNOS3250_WDMA_DONE (1 << 10) -#define EXYNOS3250_RDMA_DONE (1 << 9) -#define EXYNOS3250_ENC_STREAM_STAT (1 << 8) -#define EXYNOS3250_RESULT_STAT (1 << 5) -#define EXYNOS3250_STREAM_STAT (1 << 4) -#define EXYNOS3250_HEADER_STAT (1 << 3) - -/* - * Base address of the luma component DMA buffer - * of the raw input or output image. - */ -#define EXYNOS3250_LUMA_BASE 0x100 -#define EXYNOS3250_SRC_TILE_EN_MASK 0x100 - -/* Stride of source or destination luma raw image buffer */ -#define EXYNOS3250_LUMA_STRIDE 0x104 - -/* Horizontal/vertical offset of active region in luma raw image buffer */ -#define EXYNOS3250_LUMA_XY_OFFSET 0x108 -#define EXYNOS3250_LUMA_YY_OFFSET_SHIFT 18 -#define EXYNOS3250_LUMA_YY_OFFSET_MASK (0x1fff << EXYNOS3250_LUMA_YY_OFFSET_SHIFT) -#define EXYNOS3250_LUMA_YX_OFFSET_SHIFT 2 -#define EXYNOS3250_LUMA_YX_OFFSET_MASK (0x1fff << EXYNOS3250_LUMA_YX_OFFSET_SHIFT) - -/* - * Base address of the chroma(Cb) component DMA buffer - * of the raw input or output image. - */ -#define EXYNOS3250_CHROMA_BASE 0x10c - -/* Stride of source or destination chroma(Cb) raw image buffer */ -#define EXYNOS3250_CHROMA_STRIDE 0x110 - -/* Horizontal/vertical offset of active region in chroma(Cb) raw image buffer */ -#define EXYNOS3250_CHROMA_XY_OFFSET 0x114 -#define EXYNOS3250_CHROMA_YY_OFFSET_SHIFT 18 -#define EXYNOS3250_CHROMA_YY_OFFSET_MASK (0x1fff << EXYNOS3250_CHROMA_YY_OFFSET_SHIFT) -#define EXYNOS3250_CHROMA_YX_OFFSET_SHIFT 2 -#define EXYNOS3250_CHROMA_YX_OFFSET_MASK (0x1fff << EXYNOS3250_CHROMA_YX_OFFSET_SHIFT) - -/* - * Base address of the chroma(Cr) component DMA buffer - * of the raw input or output image. - */ -#define EXYNOS3250_CHROMA_CR_BASE 0x118 - -/* Stride of source or destination chroma(Cr) raw image buffer */ -#define EXYNOS3250_CHROMA_CR_STRIDE 0x11c - -/* Horizontal/vertical offset of active region in chroma(Cb) raw image buffer */ -#define EXYNOS3250_CHROMA_CR_XY_OFFSET 0x120 -#define EXYNOS3250_CHROMA_CR_YY_OFFSET_SHIFT 18 -#define EXYNOS3250_CHROMA_CR_YY_OFFSET_MASK (0x1fff << EXYNOS3250_CHROMA_CR_YY_OFFSET_SHIFT) -#define EXYNOS3250_CHROMA_CR_YX_OFFSET_SHIFT 2 -#define EXYNOS3250_CHROMA_CR_YX_OFFSET_MASK (0x1fff << EXYNOS3250_CHROMA_CR_YX_OFFSET_SHIFT) - -/* Raw image data r/w address register */ -#define EXYNOS3250_JPG_IMGADR 0x50 - -/* Source or destination JPEG file DMA buffer address */ -#define EXYNOS3250_JPG_JPGADR 0x124 - -/* Coefficients for RGB-to-YCbCr converter register */ -#define EXYNOS3250_JPG_COEF(n) (0x128 + (((n) - 1) << 2)) -#define EXYNOS3250_COEF_SHIFT(j) ((3 - (j)) << 3) -#define EXYNOS3250_COEF_MASK(j) (0xff << EXYNOS3250_COEF_SHIFT(j)) - -/* Raw input format setting */ -#define EXYNOS3250_JPGCMOD 0x134 -#define EXYNOS3250_SRC_TILE_EN (0x1 << 10) -#define EXYNOS3250_SRC_NV_MASK (0x1 << 9) -#define EXYNOS3250_SRC_NV12 (0x0 << 9) -#define EXYNOS3250_SRC_NV21 (0x1 << 9) -#define EXYNOS3250_SRC_BIG_ENDIAN_MASK (0x1 << 8) -#define EXYNOS3250_SRC_BIG_ENDIAN (0x1 << 8) -#define EXYNOS3250_MODE_SEL_MASK (0x7 << 5) -#define EXYNOS3250_MODE_SEL_420_2P (0x0 << 5) -#define EXYNOS3250_MODE_SEL_422_1P_LUM_CHR (0x1 << 5) -#define EXYNOS3250_MODE_SEL_RGB565 (0x2 << 5) -#define EXYNOS3250_MODE_SEL_422_1P_CHR_LUM (0x3 << 5) -#define EXYNOS3250_MODE_SEL_ARGB8888 (0x4 << 5) -#define EXYNOS3250_MODE_SEL_420_3P (0x5 << 5) -#define EXYNOS3250_SRC_SWAP_RGB (0x1 << 3) -#define EXYNOS3250_SRC_SWAP_UV (0x1 << 2) -#define EXYNOS3250_MODE_Y16_MASK (0x1 << 1) -#define EXYNOS3250_MODE_Y16 (0x1 << 1) -#define EXYNOS3250_HALF_EN_MASK (0x1 << 0) -#define EXYNOS3250_HALF_EN (0x1 << 0) - -/* Power on/off and clock down control */ -#define EXYNOS3250_JPGCLKCON 0x138 -#define EXYNOS3250_CLK_DOWN_READY (0x1 << 1) -#define EXYNOS3250_POWER_ON (0x1 << 0) - -/* Start compression or decompression */ -#define EXYNOS3250_JSTART 0x13c - -/* Restart decompression after header analysis */ -#define EXYNOS3250_JRSTART 0x140 - -/* JPEG SW reset register */ -#define EXYNOS3250_SW_RESET 0x144 - -/* JPEG timer setting register */ -#define EXYNOS3250_TIMER_SE 0x148 -#define EXYNOS3250_TIMER_INT_EN_SHIFT 31 -#define EXYNOS3250_TIMER_INT_EN (1UL << EXYNOS3250_TIMER_INT_EN_SHIFT) -#define EXYNOS3250_TIMER_INIT_MASK 0x7fffffff - -/* JPEG timer status register */ -#define EXYNOS3250_TIMER_ST 0x14c -#define EXYNOS3250_TIMER_INT_STAT_SHIFT 31 -#define EXYNOS3250_TIMER_INT_STAT (1UL << EXYNOS3250_TIMER_INT_STAT_SHIFT) -#define EXYNOS3250_TIMER_CNT_SHIFT 0 -#define EXYNOS3250_TIMER_CNT_MASK 0x7fffffff - -/* Command status register */ -#define EXYNOS3250_COMSTAT 0x150 -#define EXYNOS3250_CUR_PROC_MODE (0x1 << 1) -#define EXYNOS3250_CUR_COM_MODE (0x1 << 0) - -/* JPEG decompression output format register */ -#define EXYNOS3250_OUTFORM 0x154 -#define EXYNOS3250_OUT_ALPHA_MASK (0xff << 24) -#define EXYNOS3250_OUT_TILE_EN (0x1 << 10) -#define EXYNOS3250_OUT_NV_MASK (0x1 << 9) -#define EXYNOS3250_OUT_NV12 (0x0 << 9) -#define EXYNOS3250_OUT_NV21 (0x1 << 9) -#define EXYNOS3250_OUT_BIG_ENDIAN_MASK (0x1 << 8) -#define EXYNOS3250_OUT_BIG_ENDIAN (0x1 << 8) -#define EXYNOS3250_OUT_SWAP_RGB (0x1 << 7) -#define EXYNOS3250_OUT_SWAP_UV (0x1 << 6) -#define EXYNOS3250_OUT_FMT_MASK (0x7 << 0) -#define EXYNOS3250_OUT_FMT_420_2P (0x0 << 0) -#define EXYNOS3250_OUT_FMT_422_1P_LUM_CHR (0x1 << 0) -#define EXYNOS3250_OUT_FMT_422_1P_CHR_LUM (0x3 << 0) -#define EXYNOS3250_OUT_FMT_420_3P (0x4 << 0) -#define EXYNOS3250_OUT_FMT_RGB565 (0x5 << 0) -#define EXYNOS3250_OUT_FMT_ARGB8888 (0x6 << 0) - -/* Input JPEG stream byte size for decompression */ -#define EXYNOS3250_DEC_STREAM_SIZE 0x158 -#define EXYNOS3250_DEC_STREAM_MASK 0x1fffffff - -/* The upper bound of the byte size of output compressed stream */ -#define EXYNOS3250_ENC_STREAM_BOUND 0x15c -#define EXYNOS3250_ENC_STREAM_BOUND_MASK 0xffffc0 - -/* Scale-down ratio when decoding */ -#define EXYNOS3250_DEC_SCALING_RATIO 0x160 -#define EXYNOS3250_DEC_SCALE_FACTOR_MASK 0x3 -#define EXYNOS3250_DEC_SCALE_FACTOR_8_8 0x0 -#define EXYNOS3250_DEC_SCALE_FACTOR_4_8 0x1 -#define EXYNOS3250_DEC_SCALE_FACTOR_2_8 0x2 -#define EXYNOS3250_DEC_SCALE_FACTOR_1_8 0x3 - -/* Error check */ -#define EXYNOS3250_CRC_RESULT 0x164 - -/* RDMA and WDMA operation status register */ -#define EXYNOS3250_DMA_OPER_STATUS 0x168 -#define EXYNOS3250_WDMA_OPER_STATUS (0x1 << 1) -#define EXYNOS3250_RDMA_OPER_STATUS (0x1 << 0) - -/* DMA issue gathering number and issue number settings */ -#define EXYNOS3250_DMA_ISSUE_NUM 0x16c -#define EXYNOS3250_WDMA_ISSUE_NUM_SHIFT 16 -#define EXYNOS3250_WDMA_ISSUE_NUM_MASK (0x7 << EXYNOS3250_WDMA_ISSUE_NUM_SHIFT) -#define EXYNOS3250_RDMA_ISSUE_NUM_SHIFT 8 -#define EXYNOS3250_RDMA_ISSUE_NUM_MASK (0x7 << EXYNOS3250_RDMA_ISSUE_NUM_SHIFT) -#define EXYNOS3250_ISSUE_GATHER_NUM_SHIFT 0 -#define EXYNOS3250_ISSUE_GATHER_NUM_MASK (0x7 << EXYNOS3250_ISSUE_GATHER_NUM_SHIFT) -#define EXYNOS3250_DMA_MO_COUNT 0x7 - -/* Version register */ -#define EXYNOS3250_VERSION 0x1fc - -/* RGB <-> YUV conversion coefficients */ -#define EXYNOS3250_JPEG_ENC_COEF1 0x01352e1e -#define EXYNOS3250_JPEG_ENC_COEF2 0x00b0ae83 -#define EXYNOS3250_JPEG_ENC_COEF3 0x020cdc13 - -#define EXYNOS3250_JPEG_DEC_COEF1 0x04a80199 -#define EXYNOS3250_JPEG_DEC_COEF2 0x04a9a064 -#define EXYNOS3250_JPEG_DEC_COEF3 0x04a80102 - -#endif /* JPEG_REGS_H_ */ - -- cgit v1.2.3