Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(310)

Unified Diff: drivers/media/video/samsung/tv20/vprocessor_s5pv210.c

Issue 2036011: V4L/DVB : Add S5PV210 TV out driver support (Closed) Base URL: swsolcc@12.23.106.100:kernel-samsung.git
Patch Set: Created 10 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « drivers/media/video/samsung/tv20/vp_coeff_s5pv210.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: drivers/media/video/samsung/tv20/vprocessor_s5pv210.c
diff --git a/drivers/media/video/samsung/tv20/vprocessor_s5pv210.c b/drivers/media/video/samsung/tv20/vprocessor_s5pv210.c
new file mode 100644
index 0000000000000000000000000000000000000000..f90ed3bec63e6aff91962809eb373af1fab57a61
--- /dev/null
+++ b/drivers/media/video/samsung/tv20/vprocessor_s5pv210.c
@@ -0,0 +1,804 @@
+/* linux/drivers/media/video/samsung/tv20/vprocessor_s5pv210.c
+*
+* Copyright (c) 2010 Samsung Electronics Co., Ltd.
+* http://www.samsung.com/
+*
+* S5PV210 - Video Processor raw ftn file for Samsung TVOut driver
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+
+#include <plat/clock.h>
+#include <linux/io.h>
+
+#include "tv_out_s5pv210.h"
+
+#include <mach/regs-vprocessor.h>
+#include "vp_coeff_s5pv210.h"
+
+#ifdef CONFIG_TVOUT_RAW_DBG
+#define S5P_VP_DEBUG 1
+#endif
+
+#ifdef S5P_VP_DEBUG
+#define VPPRINTK(fmt, args...) \
+ printk(KERN_INFO "\t\t[VP] %s: " fmt, __func__ , ## args)
+#else
+#define VPPRINTK(fmt, args...)
+#endif
+
+static struct resource *vp_mem;
+void __iomem *vp_base;
+
+/*
+* set
+* - set functions are only called under running video processor
+* - after running set functions,
+* it is need to run tv_vp_update() function
+* for update shadow registers
+*/
+void tv_vp_set_field_id(enum s5p_vp_field mode)
+{
+ VPPRINTK("%d\n\r", mode);
+
+ writel((mode == VPROC_TOP_FIELD) ?
+ vp_base + S5P_VP_FIELD_ID_TOP :
+ vp_base + S5P_VP_FIELD_ID_BOTTOM,
+ vp_base + S5P_VP_FIELD_ID);
+
+ VPPRINTK("0x%08x\n\r", readl(vp_base + S5P_VP_FIELD_ID));
+}
+
+enum s5p_tv_vp_err tv_vp_set_top_field_address(u32 top_y_addr, u32 top_c_addr)
+{
+ VPPRINTK("0x%x,0x%x\n\r", top_y_addr, top_c_addr);
+
+ if (VP_PTR_ILLEGAL(top_y_addr) || VP_PTR_ILLEGAL(top_c_addr)) {
+ VPPRINTK(" address is not double word align = 0x%x,0x%x\n\r",
+ top_y_addr, top_c_addr);
+ return S5P_TV_VP_ERR_BASE_ADDRESS_MUST_DOUBLE_WORD_ALIGN;
+ }
+
+ writel(top_y_addr, vp_base + S5P_VP_TOP_Y_PTR);
+
+ writel(top_c_addr, vp_base + S5P_VP_TOP_C_PTR);
+
+ VPPRINTK("0x%x,0x%x\n\r", readl(vp_base + S5P_VP_TOP_Y_PTR),
+ readl(vp_base + S5P_VP_TOP_C_PTR));
+
+ return VPROC_NO_ERROR;
+}
+
+enum s5p_tv_vp_err tv_vp_set_bottom_field_address(
+ u32 bottom_y_addr, u32 bottom_c_addr)
+{
+ VPPRINTK("0x%x,0x%x\n\r", bottom_y_addr, bottom_c_addr);
+
+ if (VP_PTR_ILLEGAL(bottom_y_addr) || VP_PTR_ILLEGAL(bottom_c_addr)) {
+ VPPRINTK(" address is not double word align = 0x%x,0x%x\n\r",
+ bottom_y_addr, bottom_c_addr);
+ return S5P_TV_VP_ERR_BASE_ADDRESS_MUST_DOUBLE_WORD_ALIGN;
+ }
+
+ writel(bottom_y_addr, vp_base + S5P_VP_BOT_Y_PTR);
+
+ writel(bottom_c_addr, vp_base + S5P_VP_BOT_C_PTR);
+
+ VPPRINTK("0x%x,0x%x\n\r", readl(vp_base + S5P_VP_BOT_Y_PTR),
+ readl(vp_base + S5P_VP_BOT_C_PTR));
+
+ return VPROC_NO_ERROR;
+}
+
+/* TO-DO :: VP_TILE_SIZE_Y, vp_base+S5P_VP_IMG_SIZE_Y --> what is diff.? */
+enum s5p_tv_vp_err tv_vp_set_img_size(u32 img_width, u32 img_height)
+{
+ VPPRINTK("%d,%d\n\r", img_width, img_height);
+
+ if (VP_IMG_SIZE_ILLEGAL(img_width) ||
+ VP_IMG_SIZE_ILLEGAL(img_height)) {
+ VPPRINTK("image full size is not double word align = %d,%d\n\r",
+ img_width, img_height);
+ return S5P_TV_VP_ERR_BASE_ADDRESS_MUST_DOUBLE_WORD_ALIGN;
+ }
+
+ writel(VP_IMG_HSIZE(img_width) | VP_IMG_VSIZE(img_height),
+ vp_base + S5P_VP_IMG_SIZE_Y);
+
+ writel(VP_IMG_HSIZE(img_width) | VP_IMG_VSIZE(img_height / 2),
+ vp_base + S5P_VP_IMG_SIZE_C);
+
+ VPPRINTK("0x%x,0x%x\n\r", readl(vp_base + S5P_VP_IMG_SIZE_Y),
+ readl(vp_base + S5P_VP_IMG_SIZE_C));
+
+ return VPROC_NO_ERROR;
+}
+
+void tv_vp_set_src_position(u32 src_off_x,
+ u32 src_x_fract_step,
+ u32 src_off_y)
+{
+ VPPRINTK("%d,%d,%d)\n\r", src_off_x, src_x_fract_step, src_off_y);
+
+ writel(VP_SRC_H_POSITION(src_off_x) |
+ VP_SRC_X_FRACT_STEP(src_x_fract_step),
+ vp_base + S5P_VP_SRC_H_POSITION);
+ writel(VP_SRC_V_POSITION(src_off_y), vp_base + S5P_VP_SRC_V_POSITION);
+
+ VPPRINTK("0x%x,0x%x\n\r", readl(vp_base + S5P_VP_SRC_H_POSITION),
+ readl(vp_base + S5P_VP_SRC_V_POSITION));
+}
+
+void tv_vp_set_dest_position(u32 dst_off_x,
+ u32 dst_off_y)
+{
+ VPPRINTK("%d,%d)\n\r", dst_off_x, dst_off_y);
+
+
+ writel(VP_DST_H_POSITION(dst_off_x), vp_base + S5P_VP_DST_H_POSITION);
+ writel(VP_DST_V_POSITION(dst_off_y), vp_base + S5P_VP_DST_V_POSITION);
+
+ VPPRINTK("0x%x,0x%x\n\r", readl(vp_base + S5P_VP_DST_H_POSITION),
+ readl(vp_base + S5P_VP_DST_V_POSITION));
+}
+
+void tv_vp_set_src_dest_size(u32 src_width,
+ u32 src_height,
+ u32 dst_width,
+ u32 dst_height,
+ bool ipc_2d)
+{
+ u32 h_ratio = (src_width << 16) / dst_width;
+ u32 v_ratio = (ipc_2d) ?
+ ((src_height << 17) / dst_height) :
+ ((src_height << 16) / dst_height);
+
+ VPPRINTK("(%d,%d,%d,%d)++\n\r", src_width, src_height,
+ dst_width, dst_height);
+
+ writel(VP_SRC_WIDTH(src_width), vp_base + S5P_VP_SRC_WIDTH);
+ writel(VP_SRC_HEIGHT(src_height), vp_base + S5P_VP_SRC_HEIGHT);
+ writel(VP_DST_WIDTH(dst_width), vp_base + S5P_VP_DST_WIDTH);
+ writel(VP_DST_HEIGHT(dst_height), vp_base + S5P_VP_DST_HEIGHT) ;
+ writel(VP_H_RATIO(h_ratio), vp_base + S5P_VP_H_RATIO);
+ writel(VP_V_RATIO(v_ratio), vp_base + S5P_VP_V_RATIO);
+
+ writel((ipc_2d) ? (readl(vp_base + S5P_VP_MODE) | VP_2D_IPC_ON) :
+ (readl(vp_base + S5P_VP_MODE) & ~VP_2D_IPC_ON),
+ vp_base + S5P_VP_MODE);
+
+ VPPRINTK("%d,%d,%d,%d,0x%x,0x%x\n\r", readl(vp_base + S5P_VP_SRC_WIDTH),
+ readl(vp_base + S5P_VP_SRC_HEIGHT),
+ readl(vp_base + S5P_VP_DST_WIDTH),
+ readl(vp_base + S5P_VP_DST_HEIGHT),
+ readl(vp_base + S5P_VP_H_RATIO),
+ readl(vp_base + S5P_VP_V_RATIO));
+}
+
+enum s5p_tv_vp_err tv_vp_set_poly_filter_coef(enum s5p_vp_poly_coeff poly_coeff,
+ signed char ch0,
+ signed char ch1,
+ signed char ch2,
+ signed char ch3)
+{
+ VPPRINTK("%d,%d,%d,%d,%d)\n\r", poly_coeff, ch0, ch1, ch2, ch3);
+
+ if (poly_coeff > VPROC_POLY4_C1_HH || poly_coeff < VPROC_POLY8_Y0_LL ||
+ (poly_coeff > VPROC_POLY8_Y3_HH &&
+ poly_coeff < VPROC_POLY4_Y0_LL)) {
+
+ VPPRINTK("invaild poly_coeff parameter \n\r");
+ return S5P_TV_VP_ERR_INVALID_PARAM;
+ }
+
+ writel((((0xff&ch0) << 24) | ((0xff&ch1) << 16) |
+ ((0xff&ch2) << 8) | (0xff&ch3)),
+ vp_base + S5P_VP_POLY8_Y0_LL + poly_coeff*4);
+
+ VPPRINTK("0x%08x, 0x%08x\n\r",
+ readl(vp_base + S5P_VP_POLY8_Y0_LL + poly_coeff*4),
+ vp_base + S5P_VP_POLY8_Y0_LL + poly_coeff*4);
+
+ return VPROC_NO_ERROR;
+}
+
+void tv_vp_set_poly_filter_coef_default(u32 h_ratio, u32 v_ratio)
+{
+ enum s5p_tv_vp_filter_h_pp e_h_filter;
+ enum s5p_tv_vp_filter_v_pp e_v_filter;
+ u8 *poly_flt_coeff;
+ int i, j;
+
+ VPPRINTK("%d,%d\n\r", h_ratio, v_ratio);
+
+ /*
+ * For the real interlace mode,
+ * the vertical ratio should be used after divided by 2.
+ * Because in the interlace mode,
+ * all the VP output is used for SDOUT display
+ * and it should be the same as one field of the progressive mode.
+ * Therefore the same filter coefficients should be used
+ * for the same the final output video.
+ * When half of the interlace V_RATIO is
+ * same as the progressive V_RATIO,
+ * the final output video scale is same. (20051104,ishan)
+ */
+
+ /*Horizontal Y 8tap */
+ /*Horizontal C 4tap */
+ /* if (h_ratio <= 0x200) */ /* 720->720 or zoom in */
+
+ if (h_ratio <= (0x1 << 16)) { /* 720->720 or zoom in */
+ e_h_filter = VPROC_PP_H_NORMAL;
+ }
+
+ /* else if (h_ratio <= 0x240) */ /* 720->640 */ /* ?? */
+ else if (h_ratio <= (0x9 << 13)) /* 720->640 */ /* ?? */
+ e_h_filter = VPROC_PP_H_8_9 ;
+
+ /* else if(h_ratio <= 0x400) */ /* 2->1 */ /* 2 */
+ else if (h_ratio <= (0x1 << 17)) /* 2->1 */ /* 2 */
+ e_h_filter = VPROC_PP_H_1_2;
+
+ /* else if (h_ratio <= 0x600) */ /* 3->1 */ /* 3 */
+ else if (h_ratio <= (0x3 << 16)) /* 2->1 */ /* 2 */
+ e_h_filter = VPROC_PP_H_1_3;
+ else /* 0x800 */
+ e_h_filter = VPROC_PP_H_1_4; /* 4->1 */ /* 4 */
+
+ /* Vertical Y 4tap */
+ /* if (v_ratio <= 0x100) */ /* 720->720 or zoom in*/
+ if (v_ratio <= (0x1 << 16)) /* 720->720 or zoom in*/
+ e_v_filter = VPROC_PP_V_NORMAL;
+ else if (v_ratio <= (0x5 << 14)) /* 4->3*/
+ e_v_filter = VPROC_PP_V_3_4;
+ else if (v_ratio <= (0x3 << 15)) /*6->5*/
+ e_v_filter = VPROC_PP_V_5_6;
+ else if (v_ratio <= (0x1 << 17)) /* 2->1*/
+ e_v_filter = VPROC_PP_V_1_2;
+ else if (v_ratio <= (0x3 << 16)) /* 3->1*/
+ e_v_filter = VPROC_PP_V_1_3;
+ else /* 0x400 */ /* 4->1*/
+ e_v_filter = VPROC_PP_V_1_4;
+
+ poly_flt_coeff = (u8 *)(g_s_vp8tap_coef_y_h + e_h_filter * 16 * 8);
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ tv_vp_set_poly_filter_coef(
+ VPROC_POLY8_Y0_LL + (i*4) + j,
+ *(poly_flt_coeff + 4*j*8 + (7 - i)),
+ *(poly_flt_coeff + (4*j + 1)*8 + (7 - i)),
+ *(poly_flt_coeff + (4*j + 2)*8 + (7 - i)),
+ *(poly_flt_coeff + (4*j + 3)*8 + (7 - i)));
+ }
+ }
+
+ poly_flt_coeff = (u8 *)(g_s_vp4tap_coef_c_h + e_h_filter * 16 * 4);
+
+ for (i = 0; i < 2; i++) {
+ for (j = 0; j < 4; j++) {
+ tv_vp_set_poly_filter_coef(
+ VPROC_POLY4_C0_LL + (i*4) + j,
+ *(poly_flt_coeff + 4*j*4 + (3 - i)),
+ *(poly_flt_coeff + (4*j + 1)*4 + (3 - i)),
+ *(poly_flt_coeff + (4*j + 2)*4 + (3 - i)),
+ *(poly_flt_coeff + (4*j + 3)*4 + (3 - i)));
+ }
+ }
+
+ poly_flt_coeff = (u8 *)(g_s_vp4tap_coef_y_v + e_v_filter * 16 * 4);
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ tv_vp_set_poly_filter_coef(
+ VPROC_POLY4_Y0_LL + (i*4) + j,
+ *(poly_flt_coeff + 4*j*4 + (3 - i)),
+ *(poly_flt_coeff + (4*j + 1)*4 + (3 - i)),
+ *(poly_flt_coeff + (4*j + 2)*4 + (3 - i)),
+ *(poly_flt_coeff + (4*j + 3)*4 + (3 - i)));
+ }
+ }
+
+ VPPRINTK("%d,%d\n\r", e_h_filter, e_v_filter);
+}
+
+void tv_vp_set_src_dest_size_with_default_poly_filter_coef(u32 src_width,
+ u32 src_height,
+ u32 dst_width,
+ u32 dst_height,
+ bool ipc_2d)
+{
+ u32 h_ratio = (src_width << 16) / dst_width;
+ u32 v_ratio = (ipc_2d) ? ((src_height << 17) / dst_height) :
+ ((src_height << 16) / dst_height);
+
+ tv_vp_set_src_dest_size(src_width, src_height,
+ dst_width, dst_height, ipc_2d);
+ tv_vp_set_poly_filter_coef_default(h_ratio, v_ratio);
+}
+
+enum s5p_tv_vp_err tv_vp_set_brightness_contrast_control(
+ enum s5p_vp_line_eq eq_num,
+ u32 intc,
+ u32 slope)
+{
+ VPPRINTK("%d,%d,%d\n\r", eq_num, intc, slope);
+
+ if (eq_num > VProc_LINE_EQ_7 || eq_num < VProc_LINE_EQ_0) {
+ VPPRINTK("invaild eq_num parameter \n\r");
+ return S5P_TV_VP_ERR_INVALID_PARAM;
+ }
+
+ writel(VP_LINE_INTC(intc) | VP_LINE_SLOPE(slope),
+
+ vp_base + S5P_PP_LINE_EQ0 + eq_num*4);
+
+ VPPRINTK("0x%08x, 0x%08x\n\r",
+ readl(vp_base + S5P_PP_LINE_EQ0 + eq_num*4),
+ vp_base + S5P_PP_LINE_EQ0 + eq_num*4);
+
+ return VPROC_NO_ERROR;
+}
+
+void tv_vp_set_brightness(bool brightness)
+{
+ unsigned short i;
+
+ VPPRINTK("%d\n\r", brightness);
+
+ g_vp_contrast_brightness =
+ VP_LINE_INTC_CLEAR(g_vp_contrast_brightness) |
+ VP_LINE_INTC(brightness);
+
+ for (i = 0; i < 8; i++) {
+ writel(g_vp_contrast_brightness,
+ vp_base + S5P_PP_LINE_EQ0 + i*4);
+ }
+
+ VPPRINTK("%d\n\r", g_vp_contrast_brightness);
+}
+
+void tv_vp_set_contrast(u8 contrast)
+{
+ unsigned short i;
+
+ VPPRINTK("%d\n\r", contrast);
+
+ g_vp_contrast_brightness =
+ VP_LINE_SLOPE_CLEAR(g_vp_contrast_brightness) |
+ VP_LINE_SLOPE(contrast);
+
+ for (i = 0; i < 8; i++) {
+ writel(g_vp_contrast_brightness,
+ vp_base + S5P_PP_LINE_EQ0 + i*4);
+ }
+
+ VPPRINTK("%d\n\r", g_vp_contrast_brightness);
+}
+
+enum s5p_tv_vp_err tv_vp_update(void)
+{
+ VPPRINTK("()\n\r");
+
+ writel(readl(vp_base + S5P_VP_SHADOW_UPDATE) |
+ S5P_VP_SHADOW_UPDATE_ENABLE,
+ vp_base + S5P_VP_SHADOW_UPDATE);
+
+ VPPRINTK("()\n\r");
+
+ return VPROC_NO_ERROR;
+}
+
+enum s5p_vp_field tv_vp_get_field_id(void)
+{
+ VPPRINTK("()\n\r");
+ return ((readl(vp_base + S5P_VP_FIELD_ID) == S5P_VP_FIELD_ID_BOTTOM) ?
+ VPROC_BOTTOM_FIELD : VPROC_TOP_FIELD);
+}
+
+unsigned short tv_vp_get_update_status(void)
+{
+ VPPRINTK("()\n\r");
+ return readl(vp_base + S5P_VP_SHADOW_UPDATE) &
+ S5P_VP_SHADOW_UPDATE_ENABLE;
+}
+
+/*
+* initialization - iniization functions are
+ only called under stopping video processor
+*/
+void tv_vp_init_field_id(enum s5p_vp_field mode)
+{
+ tv_vp_set_field_id(mode);
+}
+
+void tv_vp_init_op_mode(bool line_skip,
+ enum s5p_vp_mem_mode mem_mode,
+ enum s5p_vp_chroma_expansion chroma_exp,
+ enum s5p_vp_filed_id_toggle toggle_id)
+{
+ u32 temp_reg;
+ VPPRINTK("%d,%d,%d,%d\n\r", line_skip, mem_mode, chroma_exp, toggle_id);
+
+ temp_reg = (line_skip) ? VP_LINE_SKIP_ON : VP_LINE_SKIP_OFF;
+ temp_reg |= (mem_mode == VPROC_2D_TILE_MODE) ?
+ VP_MEM_2D_MODE : VP_MEM_LINEAR_MODE;
+ temp_reg |= (chroma_exp == VPROC_USING_C_TOP_BOTTOM) ?
+ VP_CHROMA_USE_TOP_BOTTOM : VP_CHROMA_USE_TOP;
+ temp_reg |= (toggle_id == S5P_TV_VP_FILED_ID_TOGGLE_VSYNC) ?
+ VP_FIELD_ID_TOGGLE_VSYNC : VP_FIELD_ID_TOGGLE_USER;
+
+ writel(temp_reg, vp_base + S5P_VP_MODE);
+ VPPRINTK("0x%08x\n\r", readl(vp_base + S5P_VP_MODE));
+}
+
+void tv_vp_init_pixel_rate_control(enum s5p_vp_pxl_rate rate)
+{
+ VPPRINTK("%d\n\r", rate);
+
+ writel(VP_PEL_RATE_CTRL(rate), vp_base + S5P_VP_PER_RATE_CTRL);
+
+ VPPRINTK("0x%08x\n\r", readl(vp_base + S5P_VP_PER_RATE_CTRL));
+}
+
+enum s5p_tv_vp_err tv_vp_init_layer(u32 top_y_addr,
+ u32 top_c_addr,
+ u32 bottom_y_addr,
+ u32 bottom_c_addr,
+ enum s5p_endian_type src_img_endian,
+ u32 img_width,
+ u32 img_height,
+ u32 src_off_x,
+ u32 src_x_fract_step,
+ u32 src_off_y,
+ u32 src_width,
+ u32 src_height,
+ u32 dst_off_x,
+ u32 dst_off_y,
+ u32 dst_width,
+ u32 dst_height,
+ bool ipc_2d)
+{
+ enum s5p_tv_vp_err error = VPROC_NO_ERROR;
+
+ VPPRINTK("%d\n\r", src_img_endian);
+
+ writel(1, vp_base + S5P_VP_ENDIAN_MODE);
+
+ error = tv_vp_set_top_field_address(top_y_addr, top_c_addr);
+
+ if (error != VPROC_NO_ERROR)
+ return error;
+
+ error = tv_vp_set_bottom_field_address(bottom_y_addr, bottom_c_addr);
+
+ if (error != VPROC_NO_ERROR)
+ return error;
+
+ error = tv_vp_set_img_size(img_width, img_height);
+
+ if (error != VPROC_NO_ERROR)
+ return error;
+
+ tv_vp_set_src_position(src_off_x, src_x_fract_step, src_off_y);
+
+ tv_vp_set_dest_position(dst_off_x, dst_off_y);
+
+ tv_vp_set_src_dest_size(
+ src_width, src_height, dst_width, dst_height, ipc_2d);
+
+ VPPRINTK("0x%08x\n\r", readl(vp_base + S5P_VP_ENDIAN_MODE));
+
+ return error;
+
+}
+
+enum s5p_tv_vp_err tv_vp_init_layer_def_poly_filter_coef(
+ u32 top_y_addr,
+ u32 top_c_addr,
+ u32 bottom_y_addr,
+ u32 bottom_c_addr,
+ enum s5p_endian_type src_img_endian,
+ u32 img_width,
+ u32 img_height,
+ u32 src_off_x,
+ u32 src_x_fract_step,
+ u32 src_off_y,
+ u32 src_width,
+ u32 src_height,
+ u32 dst_off_x,
+ u32 dst_off_y,
+ u32 dst_width,
+ u32 dst_height,
+ bool ipc_2d)
+{
+ enum s5p_tv_vp_err error = VPROC_NO_ERROR;
+
+ u32 h_ratio = (src_width << 16) / dst_width;
+ u32 v_ratio = (ipc_2d) ? ((src_height << 17) / dst_height) :
+ ((src_height << 16) / dst_height);
+
+ tv_vp_set_poly_filter_coef_default(h_ratio, v_ratio);
+ error = tv_vp_init_layer(top_y_addr, top_c_addr,
+ bottom_y_addr, bottom_c_addr,
+ src_img_endian,
+ img_width, img_height,
+ src_off_x, src_x_fract_step, src_off_y,
+ src_width, src_height,
+ dst_off_x, dst_off_y,
+ dst_width, dst_height,
+ ipc_2d);
+ return error;
+}
+
+enum s5p_tv_vp_err tv_vp_init_poly_filter_coef(
+ enum s5p_vp_poly_coeff poly_coeff,
+ signed char ch0,
+ signed char ch1,
+ signed char ch2,
+ signed char ch3)
+{
+ return tv_vp_set_poly_filter_coef(poly_coeff, ch0, ch1, ch2, ch3);
+}
+
+void tv_vp_init_bypass_post_process(bool bypass)
+{
+ VPPRINTK("%d\n\r", bypass);
+
+ writel((bypass) ? VP_BY_PASS_ENABLE : VP_BY_PASS_DISABLE,
+ vp_base + S5P_PP_BYPASS);
+
+ VPPRINTK("0x%08x\n\r", readl(vp_base + S5P_PP_BYPASS));
+}
+
+enum s5p_tv_vp_err tv_vp_init_csc_coef(
+ enum s5p_vp_csc_coeff csc_coeff, u32 coeff)
+{
+ VPPRINTK("%d,%d\n\r", csc_coeff, coeff);
+
+ if (csc_coeff > VPROC_CSC_CR2CR_COEF ||
+ csc_coeff < VPROC_CSC_Y2Y_COEF) {
+ VPPRINTK("invaild csc_coeff parameter \n\r");
+ return S5P_TV_VP_ERR_INVALID_PARAM;
+ }
+
+ writel(VP_CSC_COEF(coeff),
+ vp_base + S5P_PP_CSC_Y2Y_COEF + csc_coeff*4);
+
+ VPPRINTK("0x%08x\n\r",
+ readl(vp_base + S5P_PP_CSC_Y2Y_COEF + csc_coeff*4));
+
+ return VPROC_NO_ERROR;
+}
+
+void tv_vp_init_saturation(u32 sat)
+{
+ VPPRINTK("%d\n\r", sat);
+
+ writel(VP_SATURATION(sat), vp_base + S5P_PP_SATURATION);
+
+ VPPRINTK("0x%08x\n\r", readl(vp_base + S5P_PP_SATURATION));
+}
+
+void tv_vp_init_sharpness(u32 th_h_noise,
+ enum s5p_vp_sharpness_control sharpness)
+{
+ VPPRINTK("%d,%d\n\r", th_h_noise, sharpness);
+
+ writel(VP_TH_HNOISE(th_h_noise) | VP_SHARPNESS(sharpness),
+ vp_base + S5P_PP_SHARPNESS);
+
+ VPPRINTK("0x%08x\n\r", readl(vp_base + S5P_PP_SHARPNESS));
+}
+
+enum s5p_tv_vp_err tv_vp_init_brightness_contrast_control(
+ enum s5p_vp_line_eq eq_num,
+ u32 intc,
+ u32 slope)
+{
+ return tv_vp_set_brightness_contrast_control(eq_num, intc, slope);
+}
+
+void tv_vp_init_brightness(bool brightness)
+{
+ tv_vp_set_brightness(brightness);
+}
+
+
+void tv_vp_init_contrast(u8 contrast)
+{
+ tv_vp_set_contrast(contrast);
+}
+
+void tv_vp_init_brightness_offset(u32 offset)
+{
+ VPPRINTK("%d\n\r", offset);
+
+ writel(VP_BRIGHT_OFFSET(offset), vp_base + S5P_PP_BRIGHT_OFFSET);
+
+ VPPRINTK("0x%08x\n\r", readl(vp_base + S5P_PP_BRIGHT_OFFSET));
+}
+
+void tv_vp_init_csc_control(bool sub_y_offset_en, bool csc_en)
+{
+ u32 temp_reg;
+ VPPRINTK("%d,%d\n\r", sub_y_offset_en, csc_en);
+
+ temp_reg = (sub_y_offset_en) ? VP_SUB_Y_OFFSET_ENABLE :
+ VP_SUB_Y_OFFSET_DISABLE;
+ temp_reg |= (csc_en) ? VP_CSC_ENABLE : VP_CSC_DISABLE;
+ writel(temp_reg, vp_base + S5P_PP_CSC_EN);
+
+ VPPRINTK("0x%08x\n\r", readl(vp_base + S5P_PP_CSC_EN));
+}
+
+enum s5p_tv_vp_err tv_vp_init_csc_coef_default(enum s5p_vp_csc_type csc_type)
+{
+ VPPRINTK("%d\n\r", csc_type);
+
+ switch (csc_type) {
+
+ case VPROC_CSC_SD_HD:
+ writel(Y2Y_COEF_601_TO_709, vp_base + S5P_PP_CSC_Y2Y_COEF);
+ writel(CB2Y_COEF_601_TO_709, vp_base + S5P_PP_CSC_CB2Y_COEF);
+ writel(CR2Y_COEF_601_TO_709, vp_base + S5P_PP_CSC_CR2Y_COEF);
+ writel(Y2CB_COEF_601_TO_709, vp_base + S5P_PP_CSC_Y2CB_COEF);
+ writel(CB2CB_COEF_601_TO_709, vp_base + S5P_PP_CSC_CB2CB_COEF);
+ writel(CR2CB_COEF_601_TO_709, vp_base + S5P_PP_CSC_CR2CB_COEF);
+ writel(Y2CR_COEF_601_TO_709, vp_base + S5P_PP_CSC_Y2CR_COEF);
+ writel(CB2CR_COEF_601_TO_709, vp_base + S5P_PP_CSC_CB2CR_COEF);
+ writel(CR2CR_COEF_601_TO_709, vp_base + S5P_PP_CSC_CR2CR_COEF);
+ break;
+
+ case VPROC_CSC_HD_SD:
+ writel(Y2Y_COEF_709_TO_601, vp_base + S5P_PP_CSC_Y2Y_COEF);
+ writel(CB2Y_COEF_709_TO_601, vp_base + S5P_PP_CSC_CB2Y_COEF);
+ writel(CR2Y_COEF_709_TO_601, vp_base + S5P_PP_CSC_CR2Y_COEF);
+ writel(Y2CB_COEF_709_TO_601, vp_base + S5P_PP_CSC_Y2CB_COEF);
+ writel(CB2CB_COEF_709_TO_601, vp_base + S5P_PP_CSC_CB2CB_COEF);
+ writel(CR2CB_COEF_709_TO_601, vp_base + S5P_PP_CSC_CR2CB_COEF);
+ writel(Y2CR_COEF_709_TO_601, vp_base + S5P_PP_CSC_Y2CR_COEF);
+ writel(CB2CR_COEF_709_TO_601, vp_base + S5P_PP_CSC_CB2CR_COEF);
+ writel(CR2CR_COEF_709_TO_601, vp_base + S5P_PP_CSC_CR2CR_COEF);
+ break;
+
+ default:
+ VPPRINTK("invalid csc_type parameter = %d\n\r", csc_type);
+ return S5P_TV_VP_ERR_INVALID_PARAM;
+ }
+
+ VPPRINTK("0x%08x,0x%08x,0x%08x,0x%08x,0x%08x, \
+ 0x%08x,0x%08x,0x%08x,0x%08x)\n\r",
+ readl(vp_base + S5P_PP_CSC_Y2Y_COEF),
+ readl(vp_base + S5P_PP_CSC_CB2Y_COEF),
+ readl(vp_base + S5P_PP_CSC_CR2Y_COEF),
+ readl(vp_base + S5P_PP_CSC_Y2CB_COEF),
+ readl(vp_base + S5P_PP_CSC_CB2CB_COEF),
+ readl(vp_base + S5P_PP_CSC_CR2CB_COEF),
+ readl(vp_base + S5P_PP_CSC_Y2CR_COEF),
+ readl(vp_base + S5P_PP_CSC_CB2CR_COEF),
+ readl(vp_base + S5P_PP_CSC_CR2CR_COEF));
+
+ return VPROC_NO_ERROR;
+}
+
+/*
+* start - start functions are only called under stopping video processor
+*/
+enum s5p_tv_vp_err tv_vp_start(void)
+{
+ enum s5p_tv_vp_err error = VPROC_NO_ERROR;
+
+ VPPRINTK("()\n\r");
+
+ writel(VP_ON_ENABLE, vp_base + S5P_VP_ENABLE);
+
+ error = tv_vp_update();
+
+ VPPRINTK("()\n\r");
+ return error;
+}
+
+/*
+* stop - stop functions are only called under running video processor
+*/
+enum s5p_tv_vp_err tv_vp_stop(void)
+{
+ enum s5p_tv_vp_err error = VPROC_NO_ERROR;
+
+ VPPRINTK("()\n\r");
+
+ writel((readl(vp_base + S5P_VP_ENABLE) & ~VP_ON_ENABLE),
+ vp_base + S5P_VP_ENABLE);
+
+ error = tv_vp_update();
+
+ while (!(readl(vp_base + S5P_VP_ENABLE) & VP_POWER_DOWN_RDY))
+ msleep(1);
+
+ return error;
+}
+
+void tv_vp_sw_reset(void)
+{
+ VPPRINTK("()\n\r");
+
+ writel((readl(vp_base + S5P_VP_SRESET) | VP_SOFT_RESET),
+ vp_base + S5P_VP_SRESET);
+
+ while (readl(vp_base + S5P_VP_SRESET) & VP_SOFT_RESET)
+ msleep(10);
+
+ VPPRINTK("()\n\r");
+}
+
+int __init tv_vp_probe(struct platform_device *pdev, u32 res_num)
+{
+ struct resource *res;
+ size_t size;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, res_num);
+
+ if (res == NULL) {
+ dev_err(&pdev->dev,
+ "failed to get memory region resource\n");
+ goto error;
+
+ }
+
+ size = (res->end - res->start) + 1;
+
+ vp_mem = request_mem_region(res->start, size, pdev->name);
+
+ if (vp_mem == NULL) {
+ dev_err(&pdev->dev,
+ "failed to get memory region\n");
+ goto error;
+
+ }
+
+ vp_base = ioremap(res->start, size);
+
+ if (vp_base == NULL) {
+ dev_err(&pdev->dev,
+ "failed to ioremap address region\n");
+ goto error;
+
+
+ }
+
+ return 0;
+error:
+ return -ENOENT;
+
+}
+
+int __init tv_vp_release(struct platform_device *pdev)
+{
+ iounmap(vp_base);
+
+ /* remove memory region */
+ if (vp_mem != NULL) {
+ if (release_resource(vp_mem))
+ dev_err(&pdev->dev,
+ "Can't remove tvout drv !!\n");
+
+ kfree(vp_mem);
+
+ vp_mem = NULL;
+ }
+
+ return 0;
+}
+
« no previous file with comments | « drivers/media/video/samsung/tv20/vp_coeff_s5pv210.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698