diff options
author | Pawit Pornkitprasan <p.pawit@gmail.com> | 2011-12-24 09:34:37 +0700 |
---|---|---|
committer | Pawit Pornkitprasan <p.pawit@gmail.com> | 2011-12-24 09:35:11 +0700 |
commit | fdc19983538bec90010fa7f344a7417ff4731ba8 (patch) | |
tree | 8a84a1edd1c026b71fec4756caf27cbbb9e827d5 /drivers/media/video/samsung | |
parent | b55e9ac4df4d240b39eda4cd9c0198453dd59061 (diff) | |
download | kernel_samsung_aries-fdc19983538bec90010fa7f344a7417ff4731ba8.zip kernel_samsung_aries-fdc19983538bec90010fa7f344a7417ff4731ba8.tar.gz kernel_samsung_aries-fdc19983538bec90010fa7f344a7417ff4731ba8.tar.bz2 |
Added support for aries
Reverts "S5PC11X : FIMC apply v4l2 standard for asynchronous dequeue/queue"
5f4b037e6ebb18d65a3ac896032eb559d7fe2baf
Diffstat (limited to 'drivers/media/video/samsung')
55 files changed, 32626 insertions, 58 deletions
diff --git a/drivers/media/video/samsung/Kconfig b/drivers/media/video/samsung/Kconfig index 39ef521..15c0eb2 100644 --- a/drivers/media/video/samsung/Kconfig +++ b/drivers/media/video/samsung/Kconfig @@ -17,7 +17,7 @@ if CPU_S5PV210 source "drivers/media/video/samsung/fimc/Kconfig" source "drivers/media/video/samsung/mfc50/Kconfig" source "drivers/media/video/samsung/jpeg_v2/Kconfig" -#source "drivers/media/video/samsung/tv20/Kconfig" +source "drivers/media/video/samsung/tv20/Kconfig" #source "drivers/media/video/samsung/tsi/Kconfig" if CPU_S5PV210_EVT1 #source "drivers/media/video/samsung/rotator/Kconfig" diff --git a/drivers/media/video/samsung/Makefile b/drivers/media/video/samsung/Makefile index b363793..1f99c16 100644 --- a/drivers/media/video/samsung/Makefile +++ b/drivers/media/video/samsung/Makefile @@ -2,7 +2,7 @@ obj-$(CONFIG_VIDEO_FIMC) += fimc/ obj-$(CONFIG_VIDEO_MFC50) += mfc50/ obj-$(CONFIG_VIDEO_JPEG_V2) += jpeg_v2/ #obj-$(CONFIG_VIDEO_ROTATOR) += rotator/ -#obj-$(CONFIG_VIDEO_TV20) += tv20/ +obj-$(CONFIG_VIDEO_TV20) += tv20/ #obj-$(CONFIG_VIDEO_G2D) += g2d/ #obj-$(CONFIG_VIDEO_TSI) += tsi/ diff --git a/drivers/media/video/samsung/fimc/fimc.h b/drivers/media/video/samsung/fimc/fimc.h index 3e61a98..b3df54d 100644 --- a/drivers/media/video/samsung/fimc/fimc.h +++ b/drivers/media/video/samsung/fimc/fimc.h @@ -65,7 +65,10 @@ #define FIMC_SCLK 1 #define FIMC_OVLY_MODE FIMC_OVLY_DMA_AUTO +#define PINGPONG_2ADDR_MODE +#if defined(PINGPONG_2ADDR_MODE) #define FIMC_PINGPONG 2 +#endif /* * ENUMERATIONS @@ -483,7 +486,7 @@ extern void fimc_dma_free(struct fimc_control *ctrl, extern u32 fimc_mapping_rot_flip(u32 rot, u32 flip); extern int fimc_get_scaler_factor(u32 src, u32 tar, u32 *ratio, u32 *shift); extern void fimc_get_nv12t_size(int img_hres, int img_vres, - int *y_size, int *cb_size); + int *y_size, int *cb_size, int rotate); extern void fimc_clk_en(struct fimc_control *ctrl, bool on); /* camera */ diff --git a/drivers/media/video/samsung/fimc/fimc_capture.c b/drivers/media/video/samsung/fimc/fimc_capture.c index 2367bf6..09a9b22 100644 --- a/drivers/media/video/samsung/fimc/fimc_capture.c +++ b/drivers/media/video/samsung/fimc/fimc_capture.c @@ -40,6 +40,9 @@ #define fimc_dbg fimc_err #endif +static int vtmode = 0; +static int device_id = 0; + static const struct v4l2_fmtdesc capture_fmts[] = { { .index = 0, @@ -257,20 +260,34 @@ static int fimc_camera_start(struct fimc_control *ctrl) struct v4l2_frmsizeenum cam_frmsize; struct v4l2_control cam_ctrl; int ret; - ret = subdev_call(ctrl, video, enum_framesizes, &cam_frmsize); if (ret < 0) { fimc_err("%s: enum_framesizes failed\n", __func__); if (ret != -ENOIOCTLCMD) return ret; } else { - ctrl->cam->width = cam_frmsize.discrete.width; - ctrl->cam->height = cam_frmsize.discrete.height; - - ctrl->cam->window.left = 0; - ctrl->cam->window.top = 0; - ctrl->cam->window.width = ctrl->cam->width; - ctrl->cam->window.height = ctrl->cam->height; + if (vtmode == 1 && device_id != 0 && (ctrl->cap->rotate == 90 || ctrl->cap->rotate == 270)) { + ctrl->cam->window.left = 136; + ctrl->cam->window.top = 0; + ctrl->cam->window.width = 368; + ctrl->cam->window.height = 480; + ctrl->cam->width = cam_frmsize.discrete.width; + ctrl->cam->height = cam_frmsize.discrete.height; + dev_err(ctrl->dev, "vtmode = 1, rotate = %d, device = front, cam->width = %d, cam->height = %d\n", ctrl->cap->rotate, ctrl->cam->width, ctrl->cam->height); + } else if (device_id != 0 && vtmode != 1) { + ctrl->cam->window.left = 136; + ctrl->cam->window.top = 0; + ctrl->cam->window.width = 368; + ctrl->cam->window.height = 480; + ctrl->cam->width = cam_frmsize.discrete.width; + ctrl->cam->height = cam_frmsize.discrete.height; + dev_err(ctrl->dev, "%s, crop(368x480), vtmode = 0, device = front, cam->width = %d, cam->height = %d\n", __func__, ctrl->cam->width, ctrl->cam->height); + } else { + ctrl->cam->window.left = 0; + ctrl->cam->window.top = 0; + ctrl->cam->window.width = ctrl->cam->width; + ctrl->cam->window.height = ctrl->cam->height; + } } cam_ctrl.id = V4L2_CID_CAM_PREVIEW_ONOFF; @@ -389,34 +406,19 @@ static int fimc_add_outqueue(struct fimc_control *ctrl, int i) struct fimc_capinfo *cap = ctrl->cap; struct fimc_buf_set *buf; - unsigned int mask = 0x2; + if (cap->nr_bufs > FIMC_PHYBUFS) { + if (list_empty(&cap->inq)) + return -ENOENT; - /* PINGPONG_2ADDR_MODE Only */ - /* pair_buf_index stands for pair index of i. (0<->2) (1<->3) */ - - int pair_buf_index = (i^mask); - - /* FIMC have 4 h/w registers */ - if (i < 0 || i >= FIMC_PHYBUFS) { - fimc_err("%s: invalid queue index : %d\n", __func__, i); - return -ENOENT; + buf = list_first_entry(&cap->inq, struct fimc_buf_set, list); + list_del(&buf->list); + } else { + buf = &cap->bufs[i]; } - if (list_empty(&cap->inq)) - return -ENOENT; - - buf = list_first_entry(&cap->inq, struct fimc_buf_set, list); - - /* pair index buffer should be allocated first */ - cap->outq[pair_buf_index] = buf->id; - fimc_hwset_output_address(ctrl, buf, pair_buf_index); - cap->outq[i] = buf->id; fimc_hwset_output_address(ctrl, buf, i); - if (cap->nr_bufs != 1) - list_del(&buf->list); - return 0; } @@ -424,7 +426,7 @@ static int fimc_update_hwaddr(struct fimc_control *ctrl) { int i; - for (i = 0; i < FIMC_PINGPONG; i++) + for (i = 0; i < FIMC_PHYBUFS; i++) fimc_add_outqueue(ctrl, i); return 0; @@ -705,6 +707,7 @@ int fimc_enum_fmt_vid_capture(struct file *file, void *fh, return ret; } + memset(f, 0, sizeof(*f)); memcpy(f, &capture_fmts[i], sizeof(*f)); return 0; @@ -723,6 +726,7 @@ int fimc_g_fmt_vid_capture(struct file *file, void *fh, struct v4l2_format *f) mutex_lock(&ctrl->v4l2_lock); + memset(&f->fmt.pix, 0, sizeof(f->fmt.pix)); memcpy(&f->fmt.pix, &ctrl->cap->fmt, sizeof(f->fmt.pix)); mutex_unlock(&ctrl->v4l2_lock); @@ -823,20 +827,23 @@ int fimc_s_fmt_vid_capture(struct file *file, void *fh, struct v4l2_format *f) * released at the file close. * Anyone has better idea to do this? */ - mutex_lock(&ctrl->v4l2_lock); - - if (!ctrl->cap) { - ctrl->cap = kmalloc(sizeof(*cap), GFP_KERNEL); - if (!ctrl->cap) { - mutex_unlock(&ctrl->v4l2_lock); + if (!cap) { + cap = kzalloc(sizeof(*cap), GFP_KERNEL); + if (!cap) { fimc_err("%s: no memory for " "capture device info\n", __func__); return -ENOMEM; } + /* assign to ctrl */ + ctrl->cap = cap; + } else { + memset(cap, 0, sizeof(*cap)); } - cap = ctrl->cap; - memset(cap, 0, sizeof(*cap)); + + mutex_lock(&ctrl->v4l2_lock); + + memset(&cap->fmt, 0, sizeof(cap->fmt)); memcpy(&cap->fmt, &f->fmt.pix, sizeof(cap->fmt)); v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, 0); @@ -936,7 +943,7 @@ static void fimc_free_buffers(struct fimc_control *ctrl) return; - for (i = 0; i < cap->nr_bufs; i++) { + for (i = 0; i < FIMC_PHYBUFS; i++) { memset(&cap->bufs[i], 0, sizeof(cap->bufs[i])); cap->bufs[i].state = VIDEOBUF_NEEDS_INIT; } @@ -1214,6 +1221,11 @@ int fimc_s_ctrl_capture(void *fh, struct v4l2_control *c) ret = 0; break; + case V4L2_CID_CAMERA_VT_MODE: + vtmode = c->value; + ret = subdev_call(ctrl, core, s_ctrl, c); + break; + default: /* try on subdev */ mutex_unlock(&ctrl->v4l2_lock); @@ -1509,7 +1521,7 @@ static void fimc_reset_capture(struct fimc_control *ctrl) fimc_stop_capture(ctrl); - for (i = 0; i < FIMC_PINGPONG; i++) + for (i = 0; i < FIMC_PHYBUFS; i++) fimc_add_inqueue(ctrl, ctrl->cap->outq[i]); fimc_hwset_reset(ctrl); @@ -1525,10 +1537,14 @@ int fimc_streamon_capture(void *fh) { struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl; struct fimc_capinfo *cap = ctrl->cap; + struct v4l2_frmsizeenum cam_frmsize; int rot; int ret; fimc_dbg("%s\n", __func__); + char *ce147 = "CE147 0-003c"; + device_id = strcmp(ctrl->cam->sd->name, ce147); + fimc_dbg("%s, name(%s), device_id(%d), vtmode(%d)\n", __func__, ctrl->cam->sd->name , device_id, vtmode); if (!ctrl->cam || !ctrl->cam->sd) { fimc_err("%s: No capture device.\n", __func__); @@ -1553,6 +1569,36 @@ int fimc_streamon_capture(void *fh) if (!ctrl->cam->initialized) fimc_camera_init(ctrl); + ret = subdev_call(ctrl, video, enum_framesizes, &cam_frmsize); + if (ret < 0) { + dev_err(ctrl->dev, "%s: enum_framesizes failed\n", __func__); + if(ret != -ENOIOCTLCMD) + return ret; + } else { + if (vtmode == 1 && device_id != 0 && (cap->rotate == 90 || cap->rotate == 270)) { + ctrl->cam->window.left = 136; + ctrl->cam->window.top = 0;// + ctrl->cam->window.width = 368; + ctrl->cam->window.height = 480; + ctrl->cam->width = cam_frmsize.discrete.width; + ctrl->cam->height = cam_frmsize.discrete.height; + dev_err(ctrl->dev, "vtmode = 1, rotate = %d, device = front, cam->width = %d, cam->height = %d\n", cap->rotate, ctrl->cam->width, ctrl->cam->height); + } else if (device_id != 0 && vtmode != 1) { + ctrl->cam->window.left = 136; + ctrl->cam->window.top = 0; + ctrl->cam->window.width = 368; + ctrl->cam->window.height = 480; + ctrl->cam->width = cam_frmsize.discrete.width; + ctrl->cam->height =cam_frmsize.discrete.height; + dev_err(ctrl->dev, "%s, crop(368x480), vtmode = 0, device = front, cam->width = %d, cam->height = %d\n", __func__, ctrl->cam->width, ctrl->cam->height); + } else { + ctrl->cam->window.left = 0; + ctrl->cam->window.top = 0; + ctrl->cam->width = ctrl->cam->window.width = cam_frmsize.discrete.width; + ctrl->cam->height = ctrl->cam->window.height = cam_frmsize.discrete.height; + } + } + if (ctrl->id != 2 && ctrl->cap->fmt.colorspace != V4L2_COLORSPACE_JPEG) { ret = fimc_camera_start(ctrl); @@ -1587,6 +1633,11 @@ int fimc_streamon_capture(void *fh) fimc_hwset_output_size(ctrl, cap->fmt.width, cap->fmt.height); + if ((device_id != 0) && (vtmode != 1)) { + ctrl->cap->rotate = 90; + dev_err(ctrl->dev, "%s, rotate 90", __func__); + } + fimc_hwset_output_scan(ctrl, &cap->fmt); fimc_hwset_output_rot_flip(ctrl, cap->rotate, cap->flip); rot = fimc_mapping_rot_flip(cap->rotate, cap->flip); @@ -1654,19 +1705,16 @@ int fimc_qbuf_capture(void *fh, struct v4l2_buffer *b) { struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl; - if (!ctrl->cap || !ctrl->cap->nr_bufs) { - fimc_err("%s: Invalid capture setting.\n", __func__); - return -EINVAL; - } - if (b->memory != V4L2_MEMORY_MMAP) { fimc_err("%s: invalid memory type\n", __func__); return -EINVAL; } - mutex_lock(&ctrl->v4l2_lock); - fimc_add_inqueue(ctrl, b->index); - mutex_unlock(&ctrl->v4l2_lock); + if (ctrl->cap->nr_bufs > FIMC_PHYBUFS) { + mutex_lock(&ctrl->v4l2_lock); + fimc_add_inqueue(ctrl, b->index); + mutex_unlock(&ctrl->v4l2_lock); + } return 0; } @@ -1698,7 +1746,7 @@ int fimc_dqbuf_capture(void *fh, struct v4l2_buffer *b) } /* find out the real index */ - pp = ((fimc_hwget_frame_count(ctrl) + 2) % 4); + pp = ((fimc_hwget_frame_count(ctrl) + 2) % 4) % cap->nr_bufs; /* We have read the latest frame, hence should reset availability * flag @@ -1709,14 +1757,16 @@ int fimc_dqbuf_capture(void *fh, struct v4l2_buffer *b) if (cap->fmt.field == V4L2_FIELD_INTERLACED_TB) pp &= ~0x1; + if (cap->nr_bufs > FIMC_PHYBUFS) { b->index = cap->outq[pp]; - fimc_dbg("%s: buffer(%d) outq[%d]\n", __func__, b->index, pp); - ret = fimc_add_outqueue(ctrl, pp); if (ret) { b->index = -1; fimc_err("%s: no inqueue buffer\n", __func__); } + } else { + b->index = pp; + } mutex_unlock(&ctrl->v4l2_lock); diff --git a/drivers/media/video/samsung/fimc/fimc_dev.c b/drivers/media/video/samsung/fimc/fimc_dev.c index 1441367..2554d7e 100644 --- a/drivers/media/video/samsung/fimc/fimc_dev.c +++ b/drivers/media/video/samsung/fimc/fimc_dev.c @@ -797,7 +797,7 @@ int fimc_get_scaler_factor(u32 src, u32 tar, u32 *ratio, u32 *shift) } void fimc_get_nv12t_size(int img_hres, int img_vres, - int *y_size, int *cb_size) + int *y_size, int *cb_size, int rotate) { int remain; int y_hres_byte, y_vres_byte; @@ -805,6 +805,12 @@ void fimc_get_nv12t_size(int img_hres, int img_vres, int y_hres_roundup, y_vres_roundup; int cb_hres_roundup, cb_vres_roundup; + if (rotate == 90 || rotate == 270) { + int tmp = img_hres; + img_hres = img_vres; + img_vres = tmp; + } + /* to make 'img_hres and img_vres' be 16 multiple */ remain = img_hres % 16; if (remain != 0) { diff --git a/drivers/media/video/samsung/fimc/fimc_output.c b/drivers/media/video/samsung/fimc/fimc_output.c index c66f995..98ff74e 100644 --- a/drivers/media/video/samsung/fimc/fimc_output.c +++ b/drivers/media/video/samsung/fimc/fimc_output.c @@ -226,7 +226,7 @@ static int fimc_outdev_set_src_buf(struct fimc_control *ctrl, size = PAGE_ALIGN(y_size + cb_size); break; case V4L2_PIX_FMT_NV12T: - fimc_get_nv12t_size(width, height, &y_size, &cb_size); + fimc_get_nv12t_size(width, height, &y_size, &cb_size, 0); size = PAGE_ALIGN(y_size + cb_size); break; case V4L2_PIX_FMT_NV16: @@ -1774,7 +1774,7 @@ int fimc_output_set_dst_addr(struct fimc_control *ctrl, memset(&buf_set, 0x00, sizeof(buf_set)); if (V4L2_PIX_FMT_NV12T == format) - fimc_get_nv12t_size(width, height, &y_size, &c_size); + fimc_get_nv12t_size(width, height, &y_size, &c_size, ctx->rotate); switch (format) { case V4L2_PIX_FMT_RGB32: diff --git a/drivers/media/video/samsung/fimc/fimc_v4l2.c b/drivers/media/video/samsung/fimc/fimc_v4l2.c index 3632ded..73202f4 100644 --- a/drivers/media/video/samsung/fimc/fimc_v4l2.c +++ b/drivers/media/video/samsung/fimc/fimc_v4l2.c @@ -81,8 +81,15 @@ static int fimc_querybuf(struct file *filp, void *fh, struct v4l2_buffer *b) static int fimc_g_ctrl(struct file *filp, void *fh, struct v4l2_control *c) { struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl; + struct s3c_platform_fimc *pdata = to_fimc_plat(ctrl->dev); int ret = -1; + /* can get hw version at any time */ + if (c->id == V4L2_CID_FIMC_VERSION) { + c->value = pdata->hw_ver; + return 0; + } + if (ctrl->cap != NULL) { ret = fimc_g_ctrl_capture(fh, c); } else if (ctrl->out != NULL) { diff --git a/drivers/media/video/samsung/mfc50/mfc.c b/drivers/media/video/samsung/mfc50/mfc.c index 17a9da8..5472c9d 100755 --- a/drivers/media/video/samsung/mfc50/mfc.c +++ b/drivers/media/video/samsung/mfc50/mfc.c @@ -49,6 +49,9 @@ #include <plat/media.h> #include <mach/media.h> #include <plat/mfc.h> +#ifdef CONFIG_DVFS_LIMIT +#include <mach/cpu-freq-v210.h> +#endif #include "mfc_interface.h" #include "mfc_logmsg.h" @@ -81,6 +84,9 @@ static int mfc_open(struct inode *inode, struct file *file) goto err_open; } +#ifdef CONFIG_DVFS_LIMIT + s5pv210_lock_dvfs_high_level(DVFS_LOCK_TOKEN_1, L2); +#endif clk_enable(mfc_sclk); mfc_load_firmware(mfc_fw_info->data, mfc_fw_info->size); @@ -133,6 +139,9 @@ err_mem_inst: kfree(mfc_ctx); err_regulator: if (!mfc_is_running()) { +#ifdef CONFIG_DVFS_LIMIT + s5pv210_unlock_dvfs_high_level(DVFS_LOCK_TOKEN_1); +#endif /* Turn off mfc power domain regulator */ ret = regulator_disable(mfc_pd_regulator); if (ret < 0) @@ -175,6 +184,9 @@ static int mfc_release(struct inode *inode, struct file *file) ret = 0; if (!mfc_is_running()) { +#ifdef CONFIG_DVFS_LIMIT + s5pv210_unlock_dvfs_high_level(DVFS_LOCK_TOKEN_1); +#endif /* Turn off mfc power domain regulator */ ret = regulator_disable(mfc_pd_regulator); if (ret < 0) { diff --git a/drivers/media/video/samsung/tv20/Kconfig b/drivers/media/video/samsung/tv20/Kconfig new file mode 100644 index 0000000..e839ebc --- /dev/null +++ b/drivers/media/video/samsung/tv20/Kconfig @@ -0,0 +1,51 @@ +# +# Configuration for TV-OUT/HDMI +# + +config VIDEO_TV20 + bool "Samsung TV Driver" + depends on VIDEO_SAMSUNG + default y + ---help--- + This is a TV driver for Samsung S5P platform + +config HDMI_CEC + bool "HDMI CEC driver support." + depends on VIDEO_TV20 && CPU_S5PV210 + default n + ---help--- + This is a HDMI CEC driver for Samsung SMDK_S5PV210 + Check dev node (major 10, minor 242) + +config HDMI_HPD + bool "HDMI HPD driver support." + depends on VIDEO_TV20 && CPU_S5PV210 + default n + ---help--- + This is a HDMI HPD driver for Samsung SMDK_S5PV210 + Check dev node (major 10, minor 243) + +config TV_FB + bool "TV frame buffer driver support." + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + + depends on VIDEO_TV20 && FB && CPU_S5PV210 + default n + ---help--- + +config USER_ALLOC_TVOUT + bool "Support pre allocated frame buffer memory." + depends on VIDEO_TV20 && TV_FB + default n + ---help--- + TV Driver doesn't allocate memory for frame buffer. + So, before enabling TV out, the frame buffer should be allocated. + +config TV_FB_NUM + int "Index of TV frame buffer" + depends on VIDEO_TV20 && TV_FB && !USER_ALLOC_TVOUT + default 5 + ---help--- + diff --git a/drivers/media/video/samsung/tv20/Makefile b/drivers/media/video/samsung/tv20/Makefile new file mode 100644 index 0000000..3cd0c92 --- /dev/null +++ b/drivers/media/video/samsung/tv20/Makefile @@ -0,0 +1,50 @@ +################################################# +# Makefile for TVOut for S5PC100 +# 2010 (C) Samsung Electronics +# Author : sangpil moon <sangpil.moon@samsung.com> +################################################# + +obj-$(CONFIG_VIDEO_TV20) += s5p_tvout.o + +s5p_tvout-y += ddc.o + +ifeq ($(CONFIG_HDMI_HPD), y) +s5p_tvout-y += hpd.o +endif + +ifeq ($(CONFIG_HDMI_CEC), y) +s5p_tvout-y += cec.o \ + s5pv210/cec_s5pv210.o +endif + +ifeq ($(CONFIG_CPU_S5PC100), y) +s5p_tvout-y += s5pc100/hdcp_s5pc100.o \ + s5pc100/hdmi_s5pc100.o \ + s5pc100/sdout_s5pc100.o \ + s5pc100/tv_power_s5pc100.o \ + s5pc100/vmixer_s5pc100.o \ + s5pc100/vprocessor_s5pc100.o \ + s5pc100/tv_clock_s5pc100.o +endif + + +ifeq ($(CONFIG_CPU_S5PV210), y) +s5p_tvout-y += s5pv210/hdcp_s5pv210.o \ + s5pv210/hdmi_s5pv210.o \ + s5pv210/sdout_s5pv210.o \ + s5pv210/tv_power_s5pv210.o \ + s5pv210/vmixer_s5pv210.o \ + s5pv210/vprocessor_s5pv210.o +endif + + +s5p_tvout-y += s5p_stda_tvout_if.o \ + s5p_stda_grp.o \ + s5p_stda_hdmi.o \ + s5p_stda_video_layer.o \ + s5p_tv_v4l2.o \ + s5p_tv_base.o + +ifeq ($(CONFIG_VIDEO_TV20_DEBUG), y) +EXTRA_CFLAGS += -DDEBUG +endif diff --git a/drivers/media/video/samsung/tv20/cec.c b/drivers/media/video/samsung/tv20/cec.c new file mode 100644 index 0000000..1422823 --- /dev/null +++ b/drivers/media/video/samsung/tv20/cec.c @@ -0,0 +1,426 @@ +/* linux/drivers/media/video/samsung/tv20/cec.c + * + * cec interface file for Samsung TVOut driver (only s5pv210) + * + * Copyright (c) 2010 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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/interrupt.h> +#include <linux/fs.h> +#include <linux/miscdevice.h> +#include <linux/errno.h> +#include <linux/wait.h> +#include <linux/poll.h> +#include <linux/io.h> +#include <linux/uaccess.h> + +#include <mach/gpio.h> +#include <plat/gpio-cfg.h> +#include <mach/regs-gpio.h> + +#include "s5p_tv.h" +#include "cec.h" + +/*#define CECDEBUG*/ +#ifdef CECDEBUG +#define CECIFPRINTK(fmt, args...) \ + printk(KERN_INFO "\t[CEC_IF] %s: " fmt, __func__ , ## args) +#else +#define CECIFPRINTK(fmt, args...) +#endif + +static struct cec_rx_struct cec_rx_struct; +static struct cec_tx_struct cec_tx_struct; + +static bool hdmi_on; + +/** + * Change CEC Tx state to state + * @param state [in] new CEC Tx state. + */ +void __s5p_cec_set_tx_state(enum cec_state state) +{ + atomic_set(&cec_tx_struct.state, state); +} + +/** + * Change CEC Rx state to @c state. + * @param state [in] new CEC Rx state. + */ +void __s5p_cec_set_rx_state(enum cec_state state) +{ + atomic_set(&cec_rx_struct.state, state); +} + + +int s5p_cec_open(struct inode *inode, struct file *file) +{ + s5p_tv_clk_gate(true); + + hdmi_on = true; + + __s5p_cec_reset(); + + __s5p_cec_set_divider(); + + __s5p_cec_threshold(); + + __s5p_cec_unmask_tx_interrupts(); + + __s5p_cec_set_rx_state(STATE_RX); + __s5p_cec_unmask_rx_interrupts(); + __s5p_cec_enable_rx(); + + return 0; +} + +int s5p_cec_release(struct inode *inode, struct file *file) +{ + s5p_tv_clk_gate(false); + + hdmi_on = false; + + __s5p_cec_mask_tx_interrupts(); + __s5p_cec_mask_rx_interrupts(); + + + return 0; +} + +ssize_t s5p_cec_read(struct file *file, char __user *buffer, size_t count, + loff_t *ppos) +{ + ssize_t retval; + + if (wait_event_interruptible(cec_rx_struct.waitq, + atomic_read(&cec_rx_struct.state) + == STATE_DONE)) { + return -ERESTARTSYS; + } + + spin_lock_irq(&cec_rx_struct.lock); + + if (cec_rx_struct.size > count) { + spin_unlock_irq(&cec_rx_struct.lock); + return -1; + } + + if (copy_to_user(buffer, cec_rx_struct.buffer, cec_rx_struct.size)) { + spin_unlock_irq(&cec_rx_struct.lock); + printk(KERN_ERR " copy_to_user() failed!\n"); + return -EFAULT; + } + + retval = cec_rx_struct.size; + + __s5p_cec_set_rx_state(STATE_RX); + spin_unlock_irq(&cec_rx_struct.lock); + + return retval; +} + +ssize_t s5p_cec_write(struct file *file, const char __user *buffer, + size_t count, loff_t *ppos) +{ + char *data; + + /* check data size */ + + if (count > CEC_TX_BUFF_SIZE || count == 0) + return -1; + + data = kmalloc(count, GFP_KERNEL); + + if (!data) { + printk(KERN_ERR " kmalloc() failed!\n"); + return -1; + } + + if (copy_from_user(data, buffer, count)) { + printk(KERN_ERR " copy_from_user() failed!\n"); + kfree(data); + return -EFAULT; + } + + __s5p_cec_copy_packet(data, count); + + kfree(data); + + /* wait for interrupt */ + if (wait_event_interruptible(cec_tx_struct.waitq, + atomic_read(&cec_tx_struct.state) + != STATE_TX)) { + return -ERESTARTSYS; + } + + if (atomic_read(&cec_tx_struct.state) == STATE_ERROR) + return -1; + + return count; +} + +int s5p_cec_ioctl(struct inode *inode, struct file *file, u32 cmd, + unsigned long arg) +{ + u32 laddr; + + switch (cmd) { + + case CEC_IOC_SETLADDR: + CECIFPRINTK("ioctl(CEC_IOC_SETLADDR)\n"); + + if (get_user(laddr, (u32 __user *) arg)) + return -EFAULT; + + CECIFPRINTK("logical address = 0x%02x\n", laddr); + + __s5p_cec_set_addr(laddr); + + break; + + default: + return -EINVAL; + } + + return 0; +} + +u32 s5p_cec_poll(struct file *file, poll_table *wait) +{ + poll_wait(file, &cec_rx_struct.waitq, wait); + + if (atomic_read(&cec_rx_struct.state) == STATE_DONE) + return POLLIN | POLLRDNORM; + + return 0; +} + +static const struct file_operations cec_fops = { + .owner = THIS_MODULE, + .open = s5p_cec_open, + .release = s5p_cec_release, + .read = s5p_cec_read, + .write = s5p_cec_write, + .ioctl = s5p_cec_ioctl, + .poll = s5p_cec_poll, +}; + +static struct miscdevice cec_misc_device = { + .minor = CEC_MINOR, + .name = "CEC", + .fops = &cec_fops, +}; + + +/** + * @brief CEC interrupt handler + * + * Handles interrupt requests from CEC hardware. \n + * Action depends on current state of CEC hardware. + */ +irqreturn_t s5p_cec_irq_handler(int irq, void *dev_id) +{ + + u32 status = 0; + + /* read flag register */ + + + /* is this our interrupt? */ +/* + if (!(flag & (1 << HDMI_IRQ_CEC))) { + return IRQ_NONE; + } +*/ + status = __s5p_cec_get_status(); + + if (status & CEC_STATUS_TX_DONE) { + if (status & CEC_STATUS_TX_ERROR) { + CECIFPRINTK(" CEC_STATUS_TX_ERROR!\n"); + __s5p_cec_set_tx_state(STATE_ERROR); + } else { + CECIFPRINTK(" CEC_STATUS_TX_DONE!\n"); + __s5p_cec_set_tx_state(STATE_DONE); + } + + __s5p_clr_pending_tx(); + + + wake_up_interruptible(&cec_tx_struct.waitq); + } + + if (status & CEC_STATUS_RX_DONE) { + if (status & CEC_STATUS_RX_ERROR) { + CECIFPRINTK(" CEC_STATUS_RX_ERROR!\n"); + __s5p_cec_rx_reset(); + + } else { + u32 size; + + CECIFPRINTK(" CEC_STATUS_RX_DONE!\n"); + + /* copy data from internal buffer */ + size = status >> 24; + + spin_lock(&cec_rx_struct.lock); + + __s5p_cec_get_rx_buf(size, cec_rx_struct.buffer); + + cec_rx_struct.size = size; + + __s5p_cec_set_rx_state(STATE_DONE); + + spin_unlock(&cec_rx_struct.lock); + + __s5p_cec_enable_rx(); + } + + /* clear interrupt pending bit */ + __s5p_clr_pending_rx(); + + + wake_up_interruptible(&cec_rx_struct.waitq); + } + + return IRQ_HANDLED; +} + +static int __init s5p_cec_probe(struct platform_device *pdev) +{ + u8 *buffer; + int irq_num; + int ret; + + s3c_gpio_cfgpin(S5PV210_GPH1(4), S3C_GPIO_SFN(0x4)); + s3c_gpio_setpull(S5PV210_GPH1(4), S3C_GPIO_PULL_NONE); + + /* get ioremap addr */ + __s5p_cec_probe(pdev); + + if (misc_register(&cec_misc_device)) { + printk(KERN_WARNING " Couldn't register device 10, %d.\n", + CEC_MINOR); + return -EBUSY; + } + + irq_num = platform_get_irq(pdev, 0); + if (irq_num < 0) { + printk(KERN_ERR "failed to get %s irq resource\n", "cec"); + ret = -ENOENT; + return ret; + } + + ret = request_irq(irq_num, s5p_cec_irq_handler, IRQF_DISABLED, + pdev->name, &pdev->id); + if (ret != 0) { + printk(KERN_ERR "failed to install %s irq (%d)\n", "cec", ret); + return ret; + } + + + init_waitqueue_head(&cec_rx_struct.waitq); + spin_lock_init(&cec_rx_struct.lock); + init_waitqueue_head(&cec_tx_struct.waitq); + + buffer = kmalloc(CEC_TX_BUFF_SIZE, GFP_KERNEL); + + if (!buffer) { + printk(KERN_ERR " kmalloc() failed!\n"); + misc_deregister(&cec_misc_device); + return -EIO; + } + + cec_rx_struct.buffer = buffer; + + cec_rx_struct.size = 0; + + return 0; +} + +/* + * Remove + */ +static int s5p_cec_remove(struct platform_device *pdev) +{ + return 0; +} + +#ifdef CONFIG_PM +/* + * Suspend + */ +int s5p_cec_suspend(struct platform_device *dev, pm_message_t state) +{ + if (hdmi_on) + s5p_tv_clk_gate(false); + + return 0; +} + +/* + * Resume + */ +int s5p_cec_resume(struct platform_device *dev) +{ + if (hdmi_on) + s5p_tv_clk_gate(true); + + return 0; +} +#else +#define s5p_cec_suspend NULL +#define s5p_cec_resume NULL +#endif + +static struct platform_driver s5p_cec_driver = { + .probe = s5p_cec_probe, + .remove = s5p_cec_remove, + .suspend = s5p_cec_suspend, + .resume = s5p_cec_resume, + .driver = { + .name = "s5p-cec", + .owner = THIS_MODULE, + }, +}; + +static char banner[] __initdata = + "S5P CEC Driver, (c) 2010 Samsung Electronics\n"; + +int __init s5p_cec_init(void) +{ + int ret; + + printk(banner); + + ret = platform_driver_register(&s5p_cec_driver); + + if (ret) { + printk(KERN_ERR "Platform Device Register Failed %d\n", ret); + return -1; + } + + return 0; +} + +static void __exit s5p_cec_exit(void) +{ + kfree(cec_rx_struct.buffer); + + platform_driver_unregister(&s5p_cec_driver); + +} + +module_init(s5p_cec_init); +module_exit(s5p_cec_exit); + +MODULE_AUTHOR("SangPil Moon"); +MODULE_DESCRIPTION("SS5PC11X CEC driver"); +MODULE_LICENSE("GPL"); + diff --git a/drivers/media/video/samsung/tv20/cec.h b/drivers/media/video/samsung/tv20/cec.h new file mode 100644 index 0000000..58bcc6b --- /dev/null +++ b/drivers/media/video/samsung/tv20/cec.h @@ -0,0 +1,104 @@ +/* linux/drivers/media/video/samsung/tv20/cec.h + * + * cec interface header for Samsung TVOut driver + * + * Copyright (c) 2010 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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. +*/ + +/*#define CECDEBUG 1*/ + +#include <linux/platform_device.h> + +#define VERSION "1.0" /* Driver version number */ +#define CEC_MINOR 242 /* Major 10, Minor 242, /dev/cec */ + +#define CEC_MESSAGE_BROADCAST_MASK 0x0F +#define CEC_MESSAGE_BROADCAST 0x0F + +#define CEC_FILTER_THRESHOLD 0x15 + +/* + * @enum cec_state + * Defines all possible states of CEC software state machine + */ +enum cec_state { + STATE_RX, + STATE_TX, + STATE_DONE, + STATE_ERROR +}; + +/* + * @struct cec_rx_struct + * Holds CEC Rx state and data + */ + +struct cec_rx_struct { + spinlock_t lock; + wait_queue_head_t waitq; + atomic_t state; + u8 *buffer; + unsigned int size; +}; + +/* + * @struct cec_tx_struct + * Holds CEC Tx state and data + */ + +struct cec_tx_struct { + wait_queue_head_t waitq; + atomic_t state; +}; + +#define CEC_STATUS_TX_RUNNING (1<<0) +#define CEC_STATUS_TX_TRANSFERRING (1<<1) +#define CEC_STATUS_TX_DONE (1<<2) +#define CEC_STATUS_TX_ERROR (1<<3) +#define CEC_STATUS_TX_BYTES (0xFF<<8) +#define CEC_STATUS_RX_RUNNING (1<<16) +#define CEC_STATUS_RX_RECEIVING (1<<17) +#define CEC_STATUS_RX_DONE (1<<18) +#define CEC_STATUS_RX_ERROR (1<<19) +#define CEC_STATUS_RX_BCAST (1<<20) +#define CEC_STATUS_RX_BYTES (0xFF<<24) + + +#define CEC_IOC_MAGIC 'c' + +/* + * CEC device request code to set logical address. + */ +#define CEC_IOC_SETLADDR _IOW(CEC_IOC_MAGIC, 0, unsigned int) + + +/* CEC Rx buffer size */ +#define CEC_RX_BUFF_SIZE 16 +/* CEC Tx buffer size */ +#define CEC_TX_BUFF_SIZE 16 + +extern void __s5p_cec_set_divider(void); +extern void __s5p_cec_enable_rx(void); +extern void __s5p_cec_mask_rx_interrupts(void); +extern void __s5p_cec_unmask_rx_interrupts(void); +extern void __s5p_cec_mask_tx_interrupts(void); +extern void __s5p_cec_unmask_tx_interrupts(void); +extern void __s5p_cec_set_tx_state(enum cec_state state); +extern void __s5p_cec_set_rx_state(enum cec_state state); +extern void __s5p_cec_reset(void); +extern void __s5p_cec_tx_reset(void); +extern void __s5p_cec_rx_reset(void); +extern void __s5p_cec_threshold(void); +extern void __s5p_cec_copy_packet(char *data, size_t count); +extern void __s5p_cec_set_addr(u32 addr); +extern u32 __s5p_cec_get_status(void); +extern void __s5p_clr_pending_tx(void); +extern void __s5p_clr_pending_rx(void); +extern void __s5p_cec_get_rx_buf(u32 size, u8 *buffer); +extern void __init __s5p_cec_probe(struct platform_device *pdev); + diff --git a/drivers/media/video/samsung/tv20/ddc.c b/drivers/media/video/samsung/tv20/ddc.c new file mode 100644 index 0000000..2f949bc --- /dev/null +++ b/drivers/media/video/samsung/tv20/ddc.c @@ -0,0 +1,133 @@ +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/i2c.h> + +#define I2C_DRIVERID_S5P_HDCP 510 +#define S5P_HDCP_I2C_ADDR 0x74 + +const static u16 ignore[] = { I2C_CLIENT_END }; +const static u16 normal_addr[] = { + (S5P_HDCP_I2C_ADDR >> 1), + I2C_CLIENT_END +}; + +struct i2c_client *ddc_port; + +/* + * DDC read ftn. + */ +int ddc_read(u8 subaddr, u8 *data, u16 len) +{ + u8 addr = subaddr; + int ret = 0; + + struct i2c_msg msg[] = { + [0] = { + .addr = ddc_port->addr, + .flags = 0, + .len = 1, + .buf = &addr + }, + [1] = { + .addr = ddc_port->addr, + .flags = I2C_M_RD, + .len = len, + .buf = data + } + }; + + if (i2c_transfer(ddc_port->adapter, msg, 2) != 2) + ret = -EIO; + + return ret; +} +EXPORT_SYMBOL(ddc_read); + + +/* + * DDC_write ftn. + */ +int ddc_write(u8 *data, u16 len) +{ + int ret = 0; + + if (i2c_master_send(ddc_port, (const char *) data, len) != len) + ret = -EIO; + + return ret; +} +EXPORT_SYMBOL(ddc_write); + +/* + * i2c client ftn. + */ +static int __devinit ddc_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + int ret = 0; + + ddc_port = client; + + dev_info(&client->adapter->dev, "attached s5p_ddc " + "into i2c adapter successfully\n"); + + return ret; +} + +static int ddc_remove(struct i2c_client *client) +{ + dev_info(&client->adapter->dev, "detached s5p_ddc " + "from i2c adapter successfully\n"); + + return 0; +} + +static int ddc_suspend(struct i2c_client *cl, pm_message_t mesg) +{ + return 0; +}; + +static int ddc_resume(struct i2c_client *cl) +{ + return 0; +}; + + +static struct i2c_device_id ddc_idtable[] = { + {"s5p_ddc", 0}, +}; + +MODULE_DEVICE_TABLE(i2c, ddc_idtable); + +static struct i2c_driver ddc_driver = { + .driver = { + .name = "s5p_ddc", + }, + .id_table = ddc_idtable, + .probe = ddc_probe, + .remove = __devexit_p(ddc_remove), + .address_list = &normal_addr, + .suspend = ddc_suspend, + .resume = ddc_resume, +}; + +static int __init ddc_init(void) +{ + return i2c_add_driver(&ddc_driver); +} + +static void __exit ddc_exit(void) +{ + i2c_del_driver(&ddc_driver); +} + + +MODULE_AUTHOR("SangPil Moon <sangpil.moon@samsung.com>"); +MODULE_DESCRIPTION("Driver for SMDKV210 I2C DDC devices"); + +MODULE_LICENSE("GPL"); + +module_init(ddc_init); +module_exit(ddc_exit); + + diff --git a/drivers/media/video/samsung/tv20/ddc.h b/drivers/media/video/samsung/tv20/ddc.h new file mode 100644 index 0000000..8e6982b --- /dev/null +++ b/drivers/media/video/samsung/tv20/ddc.h @@ -0,0 +1,7 @@ +/* + * i2c ddc port + */ + + +extern int ddc_read(u8 subaddr, u8 *data, u16 len); +extern int ddc_write(u8 *data, u16 len); diff --git a/drivers/media/video/samsung/tv20/hpd.c b/drivers/media/video/samsung/tv20/hpd.c new file mode 100644 index 0000000..0edb72c --- /dev/null +++ b/drivers/media/video/samsung/tv20/hpd.c @@ -0,0 +1,394 @@ +/* linux/drivers/media/video/samsung/tv20/hpd.c + * + * hpd interface ftn file for Samsung TVOut driver + * + * Copyright (c) 2010 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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/interrupt.h> +#include <linux/fs.h> +#include <linux/miscdevice.h> +#include <linux/errno.h> +#include <linux/wait.h> +#include <linux/poll.h> +#include <linux/irq.h> +#include <linux/kobject.h> +#include <linux/io.h> + +#include <mach/gpio.h> +#include <plat/gpio-cfg.h> +#include <mach/gpio-p1.h> +#include <mach/regs-gpio.h> +#include <mach/gpio.h> +#include "s5p_tv.h" +#include "hpd.h" + +/*#define HPDDEBUG*/ +#ifdef HPDDEBUG +#define HPDIFPRINTK(fmt, args...) \ + printk(KERN_INFO "[HPD_IF] %s: " fmt, __func__ , ## args) +#else +#define HPDIFPRINTK(fmt, args...) +#endif + +static struct hpd_struct hpd_struct; + +static int last_hpd_state; +atomic_t hdmi_status; +atomic_t poll_state; + +static DECLARE_WORK(hpd_work, (void *)s5p_handle_cable); + +int s5p_hpd_get_state(void) +{ + return atomic_read(&hpd_struct.state); +} + +int s5p_hpd_open(struct inode *inode, struct file *file) +{ + atomic_set(&poll_state, 1); + + return 0; +} + +int s5p_hpd_release(struct inode *inode, struct file *file) +{ + return 0; +} + +ssize_t s5p_hpd_read(struct file *file, char __user *buffer, size_t count, + loff_t *ppos) +{ + ssize_t retval; + + spin_lock_irq(&hpd_struct.lock); + + retval = put_user(atomic_read(&hpd_struct.state), + (unsigned int __user *) buffer); + + atomic_set(&poll_state, -1); + + spin_unlock_irq(&hpd_struct.lock); + + return retval; +} + +unsigned int s5p_hpd_poll(struct file *file, poll_table *wait) +{ + poll_wait(file, &hpd_struct.waitq, wait); + + if (atomic_read(&poll_state) != -1) + return POLLIN | POLLRDNORM; + + return 0; +} + +static const struct file_operations hpd_fops = { + .owner = THIS_MODULE, + .open = s5p_hpd_open, + .release = s5p_hpd_release, + .read = s5p_hpd_read, + .poll = s5p_hpd_poll, +}; + +static struct miscdevice hpd_misc_device = { + HPD_MINOR, + "HPD", + &hpd_fops, +}; + +int s5p_hpd_set_hdmiint(void) +{ + /* EINT -> HDMI */ + + set_irq_type(IRQ_EINT13, IRQ_TYPE_NONE); + + if (last_hpd_state) + s5p_hdmi_disable_interrupts(HDMI_IRQ_HPD_UNPLUG); + else + s5p_hdmi_disable_interrupts(HDMI_IRQ_HPD_PLUG); + + atomic_set(&hdmi_status, HDMI_ON); + + s3c_gpio_cfgpin(S5PV210_GPH1(5), S5PV210_GPH1_5_HDMI_HPD); + s3c_gpio_setpull(S5PV210_GPH1(5), S3C_GPIO_PULL_DOWN); + s3c_gpio_set_drvstrength(S5PV210_GPH1(5), S3C_GPIO_DRVSTR_4X); + + s5p_hdmi_hpd_gen(); + + if (s5p_hdmi_get_hpd_status()) + s5p_hdmi_enable_interrupts(HDMI_IRQ_HPD_UNPLUG); + else { + s5p_hdmi_enable_interrupts(HDMI_IRQ_HPD_PLUG); + printk("\n++ %d", __LINE__); + } + return 0; +} +EXPORT_SYMBOL(s5p_hpd_set_hdmiint); + +int s5p_hpd_set_eint(void) +{ + /* HDMI -> EINT */ + atomic_set(&hdmi_status, HDMI_OFF); + + s5p_hdmi_clear_pending(HDMI_IRQ_HPD_PLUG); + s5p_hdmi_clear_pending(HDMI_IRQ_HPD_UNPLUG); + + s5p_hdmi_disable_interrupts(HDMI_IRQ_HPD_PLUG); + s5p_hdmi_disable_interrupts(HDMI_IRQ_HPD_UNPLUG); + + s3c_gpio_cfgpin(S5PV210_GPH1(5), S5PV210_GPH1_5_EXT_INT31_5); + s3c_gpio_setpull(S5PV210_GPH1(5), S3C_GPIO_PULL_DOWN); + s3c_gpio_set_drvstrength(S5PV210_GPH1(5), S3C_GPIO_DRVSTR_4X); + + printk(KERN_INFO "\n++ s5p_hpd_set_eint\n"); + return 0; +} +EXPORT_SYMBOL(s5p_hpd_set_eint); + +int irq_eint(int irq) +{ + if (gpio_get_value(S5PV210_GPH1(5))) { + atomic_set(&hpd_struct.state, HPD_HI); + atomic_set(&poll_state, 1); + + last_hpd_state = HPD_HI; + wake_up_interruptible(&hpd_struct.waitq); + } else { + atomic_set(&hpd_struct.state, HPD_LO); + atomic_set(&poll_state, 1); + + last_hpd_state = HPD_LO; + wake_up_interruptible(&hpd_struct.waitq); + } + + if (atomic_read(&hpd_struct.state)) + set_irq_type(IRQ_EINT13, IRQ_TYPE_EDGE_FALLING); + else + set_irq_type(IRQ_EINT13, IRQ_TYPE_EDGE_RISING); + + schedule_work(&hpd_work); + + HPDIFPRINTK("%s\n", atomic_read(&hpd_struct.state) == HPD_HI ? + "HPD HI" : "HPD LO"); + + return IRQ_HANDLED; + +} + +int irq_hdmi(int irq) +{ + u8 flag; + int ret = IRQ_HANDLED; + + /* read flag register */ + flag = s5p_hdmi_get_interrupts(); + + if (s5p_hdmi_get_hpd_status()) + s5p_hdmi_disable_interrupts(HDMI_IRQ_HPD_UNPLUG); + else + s5p_hdmi_disable_interrupts(HDMI_IRQ_HPD_PLUG); + + s5p_hdmi_clear_pending(HDMI_IRQ_HPD_PLUG); + s5p_hdmi_clear_pending(HDMI_IRQ_HPD_UNPLUG); + + + /* is this our interrupt? */ + + if (!(flag & (1 << HDMI_IRQ_HPD_PLUG | 1 << HDMI_IRQ_HPD_UNPLUG))) { + ret = IRQ_NONE; + goto out; + } + + if (flag == (1 << HDMI_IRQ_HPD_PLUG | 1 << HDMI_IRQ_HPD_UNPLUG)) { + + HPDIFPRINTK("HPD_HI && HPD_LO\n"); + + if (last_hpd_state == HPD_HI && s5p_hdmi_get_hpd_status()) + flag = 1 << HDMI_IRQ_HPD_UNPLUG; + else + flag = 1 << HDMI_IRQ_HPD_PLUG; + } + + if (flag & (1 << HDMI_IRQ_HPD_PLUG)) { + + s5p_hdmi_enable_interrupts(HDMI_IRQ_HPD_UNPLUG); + + atomic_set(&hpd_struct.state, HPD_HI); + atomic_set(&poll_state, 1); + + last_hpd_state = HPD_HI; + wake_up_interruptible(&hpd_struct.waitq); + + s5p_hdcp_encrypt_stop(true); + + HPDIFPRINTK("HPD_HI\n"); + + } else if (flag & (1 << HDMI_IRQ_HPD_UNPLUG)) { + + s5p_hdcp_encrypt_stop(false); + + s5p_hdmi_enable_interrupts(HDMI_IRQ_HPD_PLUG); + + atomic_set(&hpd_struct.state, HPD_LO); + atomic_set(&poll_state, 1); + + last_hpd_state = HPD_LO; + wake_up_interruptible(&hpd_struct.waitq); + + HPDIFPRINTK("HPD_LO\n"); + } + + schedule_work(&hpd_work); + +out: + return IRQ_HANDLED; +} + +/* + * HPD interrupt handler + * + * Handles interrupt requests from HPD hardware. + * Handler changes value of internal variable and notifies waiting thread. + */ +irqreturn_t s5p_hpd_irq_handler(int irq, void *dev_id) +{ + int ret = IRQ_HANDLED; + + spin_lock_irq(&hpd_struct.lock); + + /* check HDMI status */ + if (atomic_read(&hdmi_status)) { + /* HDMI on */ + ret = irq_hdmi(irq); + HPDIFPRINTK("HDMI HPD interrupt\n"); + } else { + /* HDMI off */ + ret = irq_eint(irq); + HPDIFPRINTK("EINT HPD interrupt\n"); + } + + spin_unlock_irq(&hpd_struct.lock); + + return ret; +} + +static int __init s5p_hpd_probe(struct platform_device *pdev) +{ + if (misc_register(&hpd_misc_device)) { + printk(KERN_WARNING " Couldn't register device 10, %d.\n", + HPD_MINOR); + return -EBUSY; + } + + init_waitqueue_head(&hpd_struct.waitq); + + spin_lock_init(&hpd_struct.lock); + + atomic_set(&hpd_struct.state, -1); + + atomic_set(&hdmi_status, HDMI_OFF); + + s3c_gpio_cfgpin(S5PV210_GPH1(5), S5PV210_GPH1_5_EXT_INT31_5); + s3c_gpio_setpull(S5PV210_GPH1(5), S3C_GPIO_PULL_DOWN); + s3c_gpio_set_drvstrength(S5PV210_GPH1(5), S3C_GPIO_DRVSTR_4X); + + if (gpio_get_value(S5PV210_GPH1(5))) { + atomic_set(&hpd_struct.state, HPD_HI); + last_hpd_state = HPD_HI; + } else { + atomic_set(&hpd_struct.state, HPD_LO); + last_hpd_state = HPD_LO; + } + + set_irq_type(IRQ_EINT13, IRQ_TYPE_EDGE_BOTH); + + if (request_irq(IRQ_EINT13, s5p_hpd_irq_handler, IRQF_DISABLED, + "hpd", s5p_hpd_irq_handler)) { + printk(KERN_ERR "failed to install %s irq\n", "hpd"); + misc_deregister(&hpd_misc_device); + return -EIO; + } + + s5p_hdmi_register_isr((void *) s5p_hpd_irq_handler, (u8)HDMI_IRQ_HPD_PLUG); + s5p_hdmi_register_isr((void *) s5p_hpd_irq_handler, (u8)HDMI_IRQ_HPD_UNPLUG); + + return 0; +} + +/* + * Remove + */ +static int s5p_hpd_remove(struct platform_device *pdev) +{ + return 0; +} + + +#ifdef CONFIG_PM +/* + * Suspend + */ +int s5p_hpd_suspend(struct platform_device *dev, pm_message_t state) +{ + return 0; +} + +/* + * Resume + */ +int s5p_hpd_resume(struct platform_device *dev) +{ + return 0; +} +#else +#define s5p_hpd_suspend NULL +#define s5p_hpd_resume NULL +#endif + +static struct platform_driver s5p_hpd_driver = { + .probe = s5p_hpd_probe, + .remove = s5p_hpd_remove, + .suspend = s5p_hpd_suspend, + .resume = s5p_hpd_resume, + .driver = { + .name = "s5p-hpd", + .owner = THIS_MODULE, + }, +}; + +static char banner[] __initdata = + "S5P HPD Driver, (c) 2010 Samsung Electronics\n"; + +int __init s5p_hpd_init(void) +{ + int ret; + + printk(banner); + + ret = platform_driver_register(&s5p_hpd_driver); + + if (ret) { + printk(KERN_ERR "Platform Device Register Failed %d\n", ret); + return -1; + } + + return 0; +} + +static void __exit s5p_hpd_exit(void) +{ + misc_deregister(&hpd_misc_device); +} + +module_init(s5p_hpd_init); +module_exit(s5p_hpd_exit); + + diff --git a/drivers/media/video/samsung/tv20/hpd.h b/drivers/media/video/samsung/tv20/hpd.h new file mode 100644 index 0000000..4fa4d27 --- /dev/null +++ b/drivers/media/video/samsung/tv20/hpd.h @@ -0,0 +1,36 @@ +/* linux/drivers/media/video/samsung/tv20/hpd.h + * + * hpd interface header file for Samsung TVOut driver + * + * Copyright (c) 2010 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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. +*/ + +#define VERSION "1.2" /* Driver version number */ +#define HPD_MINOR 243 /* Major 10, Minor 243, /dev/hpd */ + +#define HPD_LO 0 +#define HPD_HI 1 + +#define HDMI_ON 1 +#define HDMI_OFF 0 + +struct hpd_struct { + spinlock_t lock; + wait_queue_head_t waitq; + atomic_t state; +}; + +extern int s5p_hpd_set_eint(void); +extern int s5p_hpd_set_hdmiint(void); + +#define S5PV210_GPH1_4_HDMI_CEC (0x4 << 16) +#define S5PV210_GPH1_4_EXT_INT31_4 (0xf << 16) + +#define S5PV210_GPH1_5_HDMI_HPD (0x4 << 20) +#define S5PV210_GPH1_5_EXT_INT31_5 (0xf << 20) + diff --git a/drivers/media/video/samsung/tv20/s5p_stda_grp.c b/drivers/media/video/samsung/tv20/s5p_stda_grp.c new file mode 100644 index 0000000..61bfba0 --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5p_stda_grp.c @@ -0,0 +1,1103 @@ +/* linux/drivers/media/video/samsung/tv20/s5p_stda_grp.c + * + * Graphic Layer ftn. file for Samsung TVOut driver + * + * Copyright (c) 2010 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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/stddef.h> +#include <linux/ioctl.h> +#include <linux/dma-mapping.h> +#include <linux/io.h> +#include <linux/uaccess.h> + +#include "s5p_tv.h" + +#ifdef COFIG_TVOUT_DBG +#define S5P_GRP_DEBUG 1 +#endif + +#ifdef S5P_GRP_DEBUG +#define GRPPRINTK(fmt, args...) \ + printk(KERN_INFO "\t[GRP] %s: " fmt, __func__ , ## args) +#else +#define GRPPRINTK(fmt, args...) +#endif + + +bool _s5p_grp_start(enum s5p_tv_vmx_layer vm_layer) +{ + enum s5p_tv_vmx_err merr; + struct s5p_tv_status *st = &s5ptv_status; + + if (!(st->grp_layer_enable[0] || st->grp_layer_enable[1])) { + + merr = __s5p_vm_init_status_reg(st->grp_burst, + st->grp_endian); + + if (merr != VMIXER_NO_ERROR) + return false; + } + +#ifdef CONFIG_CPU_S5PC100 + merr = __s5p_vm_init_layer(vm_layer, + true, + s5ptv_overlay[vm_layer].win_blending, + s5ptv_overlay[vm_layer].win.global_alpha, + s5ptv_overlay[vm_layer].priority, + s5ptv_overlay[vm_layer].fb.fmt.pixelformat, + s5ptv_overlay[vm_layer].blank_change, + s5ptv_overlay[vm_layer].pixel_blending, + s5ptv_overlay[vm_layer].pre_mul, + s5ptv_overlay[vm_layer].blank_color, + s5ptv_overlay[vm_layer].base_addr, + s5ptv_overlay[vm_layer].fb.fmt.bytesperline, + s5ptv_overlay[vm_layer].win.w.width, + s5ptv_overlay[vm_layer].win.w.height, + s5ptv_overlay[vm_layer].win.w.left, + s5ptv_overlay[vm_layer].win.w.top, + s5ptv_overlay[vm_layer].dst_rect.left, + s5ptv_overlay[vm_layer].dst_rect.top); +#endif + +#ifdef CONFIG_CPU_S5PV210 + merr = __s5p_vm_init_layer(s5ptv_status.tvout_param.disp_mode, + vm_layer, + true, + s5ptv_overlay[vm_layer].win_blending, + s5ptv_overlay[vm_layer].win.global_alpha, + s5ptv_overlay[vm_layer].priority, + s5ptv_overlay[vm_layer].fb.fmt.pixelformat, + s5ptv_overlay[vm_layer].blank_change, + s5ptv_overlay[vm_layer].pixel_blending, + s5ptv_overlay[vm_layer].pre_mul, + s5ptv_overlay[vm_layer].blank_color, + s5ptv_overlay[vm_layer].base_addr, + s5ptv_overlay[vm_layer].fb.fmt.bytesperline, + s5ptv_overlay[vm_layer].win.w.width, + s5ptv_overlay[vm_layer].win.w.height, + s5ptv_overlay[vm_layer].win.w.left, + s5ptv_overlay[vm_layer].win.w.top, + s5ptv_overlay[vm_layer].dst_rect.left, + s5ptv_overlay[vm_layer].dst_rect.top, + s5ptv_overlay[vm_layer].dst_rect.width, + s5ptv_overlay[vm_layer].dst_rect.height); +#endif + + + if (merr != VMIXER_NO_ERROR) { + GRPPRINTK("can't initialize layer(%d)\n\r", merr); + return false; + } + + __s5p_vm_start(); + + + st->grp_layer_enable[vm_layer] = true; + + GRPPRINTK("()\n\r"); + + return true; +} + +bool _s5p_grp_stop(enum s5p_tv_vmx_layer vm_layer) +{ + enum s5p_tv_vmx_err merr; + struct s5p_tv_status *st = &s5ptv_status; + + GRPPRINTK("()\n\r"); + + merr = __s5p_vm_set_layer_show(vm_layer, false); + + if (merr != VMIXER_NO_ERROR) + return false; + + merr = __s5p_vm_set_layer_priority(vm_layer, 0); + + if (merr != VMIXER_NO_ERROR) + return false; + + __s5p_vm_start(); + + + st->grp_layer_enable[vm_layer] = false; + + GRPPRINTK("()\n\r"); + + return true; +} + +int s5ptvfb_set_output(struct s5p_tv_status *ctrl) { return 0; } + +int s5ptvfb_set_display_mode(struct s5p_tv_status *ctrl) +{ + enum s5p_tv_vmx_layer layer = VM_GPR0_LAYER; + bool premul = false; + bool pixel_blending = false; + bool blank_change = false; + bool win_blending = false; + u32 blank_color = 0x0; + enum s5p_tv_vmx_color_fmt color; + u32 bpp; + u32 alpha = 0; + + bpp = ((struct fb_var_screeninfo)(ctrl->fb->var)).bits_per_pixel; + + if (bpp == 32) + color = VM_DIRECT_RGB8888; + else + color = VM_DIRECT_RGB565; + + __s5p_vm_set_ctrl(layer, premul, pixel_blending, blank_change, + win_blending, color, alpha, blank_color); + + return 0; +} + +int s5ptvfb_display_on(struct s5p_tv_status *ctrl) +{ + __s5p_vm_set_layer_priority(VM_GPR0_LAYER, 10); + __s5p_vm_set_layer_show(VM_GPR0_LAYER, true); + + return 0; +} + +int s5ptvfb_display_off(struct s5p_tv_status *ctrl) +{ + __s5p_vm_set_layer_priority(VM_GPR0_LAYER, 10); + __s5p_vm_set_layer_show(VM_GPR0_LAYER, false); + + return 0; +} + +int s5ptvfb_frame_off(struct s5p_tv_status *ctrl) { return 0; } +int s5ptvfb_set_clock(struct s5p_tv_status *ctrl) { return 0; } +int s5ptvfb_set_polarity(struct s5p_tv_status *ctrl) { return 0; } +int s5ptvfb_set_timing(struct s5p_tv_status *ctrl) { return 0; } +int s5ptvfb_set_lcd_size(struct s5p_tv_status *ctrl) { return 0; } +int s5ptvfb_window_on(struct s5p_tv_status *ctrl, int id) +{ + __s5p_vm_set_layer_show(VM_GPR0_LAYER, true); + + return 0; +} + +int s5ptvfb_window_off(struct s5p_tv_status *ctrl, int id) +{ + __s5p_vm_set_layer_show(VM_GPR0_LAYER, false); + return 0; +} + +int s5ptvfb_set_window_control(struct s5p_tv_status *ctrl, int id) { return 0; } +int s5ptvfb_set_alpha_blending(struct s5p_tv_status *ctrl, int id) { return 0; } +int s5ptvfb_set_window_position(struct s5p_tv_status *ctrl, int id) +{ + u32 off_x, off_y; + u32 w_t, h_t; + u32 w, h; + + struct fb_var_screeninfo *var = &ctrl->fb->var; + struct s5ptvfb_window *win = ctrl->fb->par; + + off_x = (u32)win->x; + off_y = (u32)win->y; + + w = var->xres; + h = var->yres; + + /* + * When tvout resolution was overscanned, there is no + * adjust method in H/W. So, framebuffer should be resized. + * In this case - TV w/h is greater than FB w/h, grp layer's + * dst offset must be changed to fix tv screen. + */ + + switch (ctrl->tvout_param.disp_mode) { + + case TVOUT_NTSC_M: + case TVOUT_480P_60_16_9: + case TVOUT_480P_60_4_3: + case TVOUT_480P_59: + w_t = 720; + h_t = 480; + break; + + case TVOUT_576P_50_16_9: + case TVOUT_576P_50_4_3: + w_t = 720; + h_t = 576; + break; + + case TVOUT_720P_60: + case TVOUT_720P_59: + case TVOUT_720P_50: + w_t = 1280; + h_t = 720; + break; + + case TVOUT_1080I_60: + case TVOUT_1080I_59: + case TVOUT_1080I_50: + case TVOUT_1080P_60: + case TVOUT_1080P_59: + case TVOUT_1080P_50: + case TVOUT_1080P_30: + w_t = 1920; + h_t = 1080; + break; + + default: + w_t = 0; + h_t = 0; + break; + } + + if (w_t > w) + off_x = (w_t - w) / 2; + + if (h_t > h) + off_y = (h_t - h) / 2; + + __s5p_vm_set_grp_layer_position(VM_GPR0_LAYER, off_x, off_y); + + return 0; +} + +int s5ptvfb_set_window_size(struct s5p_tv_status *ctrl, int id) +{ + struct fb_var_screeninfo *var = &ctrl->fb->var; + int w, h, xo, yo; + + w = var->xres; + h = var->yres; + xo = var->xoffset; + yo = var->yoffset; + + __s5p_vm_set_grp_layer_size(VM_GPR0_LAYER, w, w, h, xo, yo); + + + dev_dbg(ctrl->dev_fb, "[fb%d] resolution: %d x %d\n", id, + var->xres, var->yres); + + return 0; +} +int s5ptvfb_set_buffer_address(struct s5p_tv_status *ctrl, int id) +{ + struct fb_fix_screeninfo *fix = &ctrl->fb->fix; + struct fb_var_screeninfo *var = &ctrl->fb->var; + dma_addr_t start_addr = 0, end_addr = 0; + + if (fix->smem_start) { + start_addr = fix->smem_start + (var->xres_virtual * + (var->bits_per_pixel / 8) * var->yoffset); + + end_addr = start_addr + (var->xres_virtual * + (var->bits_per_pixel / 8) * var->yres); + } + + __s5p_vm_set_grp_base_address(VM_GPR0_LAYER, start_addr); + return 0; +} + +int s5ptvfb_set_buffer_size(struct s5p_tv_status *ctrl, int id) { return 0; } + +int s5ptvfb_set_chroma_key(struct s5p_tv_status *ctrl, int id) +{ + struct s5ptvfb_window *win = ctrl->fb->par; + struct s5ptvfb_chroma *chroma = &win->chroma; + + enum s5p_tv_vmx_layer layer = VM_GPR0_LAYER; + + bool blank_change = (chroma->enabled) ? true : false; + u32 blank_color = chroma->key; + + bool win_blending = (chroma->blended) ? true : false; + bool alpha = chroma->alpha; + + enum s5p_tv_vmx_color_fmt color = VM_DIRECT_RGB8888; + + __s5p_vm_set_ctrl(layer, false, false, blank_change, + win_blending, color, alpha, blank_color); + + return 0; +} + + + + +static inline unsigned int __chan_to_field(unsigned int chan, + struct fb_bitfield bf) +{ + chan &= 0xffff; + chan >>= 16 - bf.length; + + return chan << bf.offset; +} + +static int s5ptvfb_set_alpha_info(struct fb_var_screeninfo *var, + struct s5ptvfb_window *win) +{ + if (var->transp.length > 0) + win->alpha.mode = PIXEL_BLENDING; + else { + win->alpha.mode = PLANE_BLENDING; + win->alpha.channel = 0; + win->alpha.value = S5PTVFB_AVALUE(0xf, 0xf, 0xf); + } + + return 0; +} + + +static int s5ptvfb_enable_window(int id) +{ + struct s5ptvfb_window *win = s5ptv_status.fb->par; + + if (s5ptvfb_window_on(&s5ptv_status, id)) { + win->enabled = 0; + return -EFAULT; + } else { + win->enabled = 1; + return 0; + } +} + + +static int s5ptvfb_disable_window(int id) +{ + struct s5ptvfb_window *win = s5ptv_status.fb->par; + + if (s5ptvfb_window_off(&s5ptv_status, id)) { + win->enabled = 1; + return -EFAULT; + } else { + win->enabled = 0; + return 0; + } +} + +int s5ptvfb_unmap_video_memory(struct fb_info *fb) +{ + struct fb_fix_screeninfo *fix = &fb->fix; + struct s5ptvfb_window *win = fb->par; + + if (fix->smem_start) { + dma_free_writecombine(s5ptv_status.dev_fb, fix->smem_len, + fb->screen_base, fix->smem_start); + fix->smem_start = 0; + fix->smem_len = 0; + dev_info(s5ptv_status.dev_fb, + "[fb%d] video memory released\n", win->id); + } + + return 0; +} + +static int s5ptvfb_release_window(struct fb_info *fb) +{ + struct s5ptvfb_window *win = fb->par; + + win->x = 0; + win->y = 0; + + return 0; +} + +int s5ptvfb_map_video_memory(struct fb_info *fb) +{ + struct fb_fix_screeninfo *fix = &fb->fix; + struct s5ptvfb_window *win = fb->par; + + if (win->path == DATA_PATH_FIFO) + return 0; + + fb->screen_base = dma_alloc_writecombine(s5ptv_status.dev_fb, + PAGE_ALIGN(fix->smem_len), + (unsigned int *) &fix->smem_start, GFP_KERNEL); + if (!fb->screen_base) + return -ENOMEM; + else + dev_info(s5ptv_status.dev_fb, + "[fb%d] dma: 0x%08x, cpu: 0x%08x,size: 0x%08x\n", + win->id, (unsigned int) fix->smem_start, + (unsigned int) fb->screen_base, + fix->smem_len); + + memset(fb->screen_base, 0, fix->smem_len); + + return 0; +} + + +static int s5ptvfb_set_bitfield(struct fb_var_screeninfo *var) +{ + switch (var->bits_per_pixel) { + case 16: + if (var->transp.length == 1) { + var->red.offset = 10; + var->red.length = 5; + var->green.offset = 5; + var->green.length = 5; + var->blue.offset = 0; + var->blue.length = 5; + var->transp.offset = 15; + } else if (var->transp.length == 4) { + var->red.offset = 8; + var->red.length = 4; + var->green.offset = 4; + var->green.length = 4; + var->blue.offset = 0; + var->blue.length = 4; + var->transp.offset = 12; + } else { + var->red.offset = 11; + var->red.length = 5; + var->green.offset = 5; + var->green.length = 6; + var->blue.offset = 0; + var->blue.length = 5; + var->transp.offset = 0; + } + break; + + case 24: + var->red.offset = 16; + var->red.length = 8; + var->green.offset = 8; + var->green.length = 8; + var->blue.offset = 0; + var->blue.length = 8; + var->transp.offset = 0; + var->transp.length = 0; + break; + + case 32: + var->red.offset = 16; + var->red.length = 8; + var->green.offset = 8; + var->green.length = 8; + var->blue.offset = 0; + var->blue.length = 8; + var->transp.offset = 24; + break; + } + + return 0; +} + +#define TV_LOGO_W 800 +#define TV_LOGO_H 480 + +int s5ptvfb_draw_logo(struct fb_info *fb) +{ +#if 0 + struct fb_fix_screeninfo *fix = &fb->fix; + int i; + +/* memcpy(s5ptv_status.fb->screen_base, + TV_LOGO_RGB24, fix->line_length * var->yres); + */ + char *base = s5ptv_status.fb->screen_base; + + for (i = 0; i < TV_LOGO_H; i++) { + memcpy(base, &TV_LOGO_RGB24[i*TV_LOGO_W], TV_LOGO_W * 4); + base += fix->line_length; + } +#endif + return 0; +} + +static int s5ptvfb_cursor(struct fb_info *info, struct fb_cursor *cursor) +{ + /* nothing to do for removing cursor */ + return 0; +} + + +static int s5ptvfb_setcolreg(unsigned int regno, unsigned int red, + unsigned int green, unsigned int blue, + unsigned int transp, struct fb_info *fb) +{ + unsigned int *pal = (unsigned int *) fb->pseudo_palette; + unsigned int val = 0; + + if (regno < 16) { + /* fake palette of 16 colors */ + val |= __chan_to_field(red, fb->var.red); + val |= __chan_to_field(green, fb->var.green); + val |= __chan_to_field(blue, fb->var.blue); + val |= __chan_to_field(transp, fb->var.transp); + + pal[regno] = val; + } + + return 0; +} + + +static int s5ptvfb_pan_display(struct fb_var_screeninfo *var, + struct fb_info *fb) +{ + struct s5ptvfb_window *win = fb->par; + + if (var->yoffset + var->yres > var->yres_virtual) { + dev_err(s5ptv_status.dev_fb, "invalid yoffset value\n"); + return -EINVAL; + } + + fb->var.yoffset = var->yoffset; + + dev_dbg(s5ptv_status.dev_fb, "[fb%d] yoffset for pan display: %d\n", + win->id, + var->yoffset); + + s5ptvfb_set_buffer_address(&s5ptv_status, win->id); + + return 0; +} + + +static int s5ptvfb_blank(int blank_mode, struct fb_info *fb) +{ + struct s5ptvfb_window *win = fb->par; + + dev_dbg(s5ptv_status.dev_fb, "change blank mode\n"); + + switch (blank_mode) { + case FB_BLANK_UNBLANK: + if (fb->fix.smem_start) { + s5ptvfb_display_on(&s5ptv_status); + s5ptvfb_enable_window(win->id); + } else + dev_info(s5ptv_status.dev_fb, + "[fb%d] no allocated memory for unblank\n", + win->id); + break; + + case FB_BLANK_POWERDOWN: + s5ptvfb_display_off(&s5ptv_status); + s5ptvfb_disable_window(win->id); + break; + + default: + dev_dbg(s5ptv_status.dev_fb, "unsupported blank mode\n"); + /* return -EINVAL; */ + } + + return 0; +} + +int s5ptvfb_set_par(struct fb_info *fb) +{ + struct s5ptvfb_window *win = fb->par; + + dev_dbg(s5ptv_status.dev_fb, "[fb%d] set_par\n", win->id); + + if (!fb->fix.smem_start) { +#ifndef CONFIG_USER_ALLOC_TVOUT + GRPPRINTK(" The frame buffer is allocated here\n"); + s5ptvfb_map_video_memory(fb); +#else + printk(KERN_ERR + "[Warning] The frame buffer should be allocated by ioctl\n"); +#endif + } + + ((struct fb_var_screeninfo) (s5ptv_status.fb->var)).bits_per_pixel = + ((struct fb_var_screeninfo) (fb->var)).bits_per_pixel; + + s5ptvfb_set_display_mode(&s5ptv_status); + + s5ptvfb_set_window_control(&s5ptv_status, win->id); + s5ptvfb_set_window_position(&s5ptv_status, win->id); + s5ptvfb_set_window_size(&s5ptv_status, win->id); + s5ptvfb_set_buffer_address(&s5ptv_status, win->id); + s5ptvfb_set_buffer_size(&s5ptv_status, win->id); + + if (win->id > 0) + s5ptvfb_set_alpha_blending(&s5ptv_status, win->id); + + return 0; +} + +int s5ptvfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fb) +{ + struct fb_fix_screeninfo *fix = &fb->fix; + struct s5ptvfb_window *win = fb->par; + struct s5ptvfb_lcd *lcd = s5ptv_status.lcd; + + dev_dbg(s5ptv_status.dev_fb, "[fb%d] check_var\n", win->id); + + if (var->bits_per_pixel != 16 && var->bits_per_pixel != 24 && + var->bits_per_pixel != 32) { + dev_err(s5ptv_status.dev_fb, "invalid bits per pixel\n"); + return -EINVAL; + } + + if (var->xres > lcd->width) + var->xres = lcd->width; + + if (var->yres > lcd->height) + var->yres = lcd->height; + + if (var->xres_virtual != var->xres) + var->xres_virtual = var->xres; + + if (var->yres_virtual > var->yres * (fb->fix.ypanstep + 1)) + var->yres_virtual = var->yres * (fb->fix.ypanstep + 1); + + if (var->xoffset != 0) + var->xoffset = 0; + + if (var->yoffset + var->yres > var->yres_virtual) + var->yoffset = var->yres_virtual - var->yres; + + if (win->x + var->xres > lcd->width) + win->x = lcd->width - var->xres; + + if (win->y + var->yres > lcd->height) + win->y = lcd->height - var->yres; + + /* modify the fix info */ + fix->line_length = var->xres_virtual * var->bits_per_pixel / 8; + fix->smem_len = fix->line_length * var->yres_virtual; + + + s5ptvfb_set_bitfield(var); + s5ptvfb_set_alpha_info(var, win); + + return 0; +} + +static int s5ptvfb_release(struct fb_info *fb, int user) +{ +/* + * Following block is deleted for enabling multiple open of TV frame buffer + * + * struct s5ptvfb_window *win = fb->par; + */ + int ret; + struct s5ptvfb_window *win = fb->par; + + s5ptvfb_release_window(fb); + +/* + * Following block is deleted for enabling multiple open of TV frame buffer + * + * mutex_lock(&s5ptv_status.fb_lock); + * atomic_dec(&win->in_use); + * mutex_unlock(&s5ptv_status.fb_lock); + */ + + _s5p_vlayer_stop(); + _s5p_tv_if_stop(); + + s5ptv_status.hdcp_en = false; + + s5ptv_status.tvout_output_enable = false; + + /* + * drv. release + * - just check drv. state reg. or not. + */ + + ret = s5p_tv_clk_gate(false); + if (ret < 0) { + printk(KERN_ERR "[Error]Cannot release\n"); + return -1; + } + tv_phy_power(false); + + mutex_lock(&s5ptv_status.fb_lock); + atomic_dec(&win->in_use); + mutex_unlock(&s5ptv_status.fb_lock); + + return 0; +} + +static int s5ptvfb_ioctl(struct fb_info *fb, unsigned int cmd, + unsigned long arg) +{ + struct fb_var_screeninfo *var = &fb->var; + struct s5ptvfb_window *win = fb->par; + struct s5ptvfb_lcd *lcd = s5ptv_status.lcd; + int ret = 0; + void *argp = (void *) arg; + + union { + struct s5ptvfb_user_window user_window; + struct s5ptvfb_user_plane_alpha user_alpha; + struct s5ptvfb_user_chroma user_chroma; + int vsync; + } p; + + switch (cmd) { + + case FBIO_ALLOC: + win->path = (enum s5ptvfb_data_path_t) argp; + break; + + case FBIOGET_FSCREENINFO: + ret = memcpy(argp, &fb->fix, sizeof(fb->fix)) ? 0 : -EFAULT; + break; + + case FBIOGET_VSCREENINFO: + ret = memcpy(argp, &fb->var, sizeof(fb->var)) ? 0 : -EFAULT; + break; + + case FBIOPUT_VSCREENINFO: + ret = s5ptvfb_check_var((struct fb_var_screeninfo *) argp, fb); + if (ret) { + dev_err(s5ptv_status.dev_fb, "invalid vscreeninfo\n"); + break; + } + + ret = memcpy(&fb->var, (struct fb_var_screeninfo *) argp, + sizeof(fb->var)) ? 0 : -EFAULT; + if (ret) { + dev_err(s5ptv_status.dev_fb, + "failed to put new vscreeninfo\n"); + break; + } + + ret = s5ptvfb_set_par(fb); + break; + + case S5PTVFB_WIN_POSITION: + if (copy_from_user(&p.user_window, + (struct s5ptvfb_user_window __user *) arg, + sizeof(p.user_window))) + ret = -EFAULT; + else { + if (p.user_window.x < 0) + p.user_window.x = 0; + + if (p.user_window.y < 0) + p.user_window.y = 0; + + if (p.user_window.x + var->xres > lcd->width) + win->x = lcd->width - var->xres; + else + win->x = p.user_window.x; + + if (p.user_window.y + var->yres > lcd->height) + win->y = lcd->height - var->yres; + else + win->y = p.user_window.y; + + s5ptvfb_set_window_position(&s5ptv_status, win->id); + } + break; + + case S5PTVFB_WIN_SET_PLANE_ALPHA: + if (copy_from_user(&p.user_alpha, + (struct s5ptvfb_user_plane_alpha __user *) arg, + sizeof(p.user_alpha))) + ret = -EFAULT; + else { + win->alpha.mode = PLANE_BLENDING; + win->alpha.channel = p.user_alpha.channel; + win->alpha.value = + S5PTVFB_AVALUE(p.user_alpha.red, + p.user_alpha.green, + p.user_alpha.blue); + + s5ptvfb_set_alpha_blending(&s5ptv_status, win->id); + } + break; + + case S5PTVFB_WIN_SET_CHROMA: + if (copy_from_user(&p.user_chroma, + (struct s5ptvfb_user_chroma __user *) arg, + sizeof(p.user_chroma))) + ret = -EFAULT; + else { + win->chroma.enabled = p.user_chroma.enabled; + win->chroma.key = S5PTVFB_CHROMA(p.user_chroma.red, + p.user_chroma.green, + p.user_chroma.blue); + + s5ptvfb_set_chroma_key(&s5ptv_status, win->id); + } + break; + + case S5PTVFB_WIN_SET_ADDR: + fb->fix.smem_start = (unsigned long)argp; + s5ptvfb_set_buffer_address(&s5ptv_status, win->id); + break; + + case S5PTVFB_SET_WIN_ON: +#ifdef CONFIG_USER_ALLOC_TVOUT + s5ptvfb_display_on(&s5ptv_status); + s5ptvfb_enable_window(0); +#endif + break; + + case S5PTVFB_SET_WIN_OFF: +#ifdef CONFIG_USER_ALLOC_TVOUT + s5ptvfb_display_off(&s5ptv_status); + s5ptvfb_disable_window(0); +#endif + break; + + } + + return 0; +} + +static int s5ptvfb_open(struct fb_info *fb, int user) +{ + struct s5ptvfb_window *win = fb->par; + int ret = 0; + + ret = s5p_tv_clk_gate(true); + if (ret < 0) { + printk(KERN_ERR "[Error]Cannot open it\n"); + return -1; + } + + tv_phy_power(true); + + _s5p_tv_if_init_param(); + + s5p_tv_v4l2_init_param(); + + /* s5ptv_status.tvout_param.disp_mode = TVOUT_720P_60; */ + s5ptv_status.tvout_param.out_mode = TVOUT_OUTPUT_HDMI_RGB; + + _s5p_tv_if_set_disp(); + +#ifndef CONFIG_USER_ALLOC_TVOUT + s5ptvfb_display_on(&s5ptv_status); + + s5ptvfb_enable_window(0); +#endif + + mutex_lock(&s5ptv_status.fb_lock); + + if (atomic_read(&win->in_use)) { + dev_dbg(s5ptv_status.dev_fb, + "do not allow multiple open " + "for window\n"); + ret = -EBUSY; + + } else + atomic_inc(&win->in_use); + + mutex_unlock(&s5ptv_status.fb_lock); + + return ret; + +} + +struct fb_ops s5ptvfb_ops = { + .owner = THIS_MODULE, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, + .fb_check_var = s5ptvfb_check_var, + .fb_set_par = s5ptvfb_set_par, + .fb_blank = s5ptvfb_blank, + .fb_pan_display = s5ptvfb_pan_display, + .fb_setcolreg = s5ptvfb_setcolreg, + .fb_cursor = s5ptvfb_cursor, + .fb_ioctl = s5ptvfb_ioctl, + .fb_open = s5ptvfb_open, + .fb_release = s5ptvfb_release, +}; + +int s5ptvfb_direct_ioctl(int id, unsigned int cmd, unsigned long arg) +{ + struct fb_info *fb = s5ptv_status.fb; + struct fb_fix_screeninfo *fix = &fb->fix; + struct s5ptvfb_window *win = fb->par; + void *argp = (void *) arg; + int ret = 0; + + switch (cmd) { + + case FBIO_ALLOC: + win->path = (enum s5ptvfb_data_path_t) argp; + break; + + case FBIOGET_FSCREENINFO: + ret = memcpy(argp, &fb->fix, sizeof(fb->fix)) ? 0 : -EFAULT; + break; + + case FBIOGET_VSCREENINFO: + ret = memcpy(argp, &fb->var, sizeof(fb->var)) ? 0 : -EFAULT; + break; + + case FBIOPUT_VSCREENINFO: + ret = s5ptvfb_check_var((struct fb_var_screeninfo *) argp, fb); + if (ret) { + dev_err(s5ptv_status.dev_fb, "invalid vscreeninfo\n"); + break; + } + + ret = memcpy(&fb->var, (struct fb_var_screeninfo *) argp, + sizeof(fb->var)) ? 0 : -EFAULT; + if (ret) { + dev_err(s5ptv_status.dev_fb, + "failed to put new vscreeninfo\n"); + break; + } + + ret = s5ptvfb_set_par(fb); + break; + + case S5PTVFB_SET_WIN_ON: +#ifdef CONFIG_USER_ALLOC_TVOUT + s5ptvfb_display_on(&s5ptv_status); + s5ptvfb_enable_window(0); +#endif + break; + + case S5PTVFB_SET_WIN_OFF: +#ifdef CONFIG_USER_ALLOC_TVOUT + s5ptvfb_display_off(&s5ptv_status); + s5ptvfb_disable_window(0); +#endif + break; + + case S5PTVFB_POWER_ON: + s5p_tv_clk_gate(true); + tv_phy_power(true); + + _s5p_tv_if_init_param(); + + s5p_tv_v4l2_init_param(); + + /* s5ptv_status.tvout_param.disp_mode = TVOUT_720P_60; */ + s5ptv_status.tvout_param.out_mode = TVOUT_OUTPUT_HDMI; + + _s5p_tv_if_set_disp(); + + break; + + case S5PTVFB_POWER_OFF: + _s5p_vlayer_stop(); + _s5p_tv_if_stop(); + + s5p_tv_clk_gate(false); + tv_phy_power(false); + break; + + case S5PTVFB_WIN_SET_ADDR: + fix->smem_start = (unsigned long)argp; + s5ptvfb_set_buffer_address(&s5ptv_status, win->id); + break; + + default: + ret = s5ptvfb_ioctl(fb, cmd, arg); + break; + } + + return ret; +} +EXPORT_SYMBOL(s5ptvfb_direct_ioctl); + +int s5ptvfb_init_fbinfo(int id) +{ + struct fb_info *fb = s5ptv_status.fb; + struct fb_fix_screeninfo *fix = &fb->fix; + struct fb_var_screeninfo *var = &fb->var; + struct s5ptvfb_window *win = fb->par; + struct s5ptvfb_alpha *alpha = &win->alpha; + struct s5ptvfb_lcd *lcd = s5ptv_status.lcd; + struct s5ptvfb_lcd_timing *timing = &lcd->timing; + + memset(win, 0, sizeof(struct s5ptvfb_window)); + + platform_set_drvdata(to_platform_device(s5ptv_status.dev_fb), fb); + + strcpy(fix->id, S5PTVFB_NAME); + + /* fimd specific */ + win->id = id; + win->path = DATA_PATH_DMA; + win->dma_burst = 16; + alpha->mode = PLANE_BLENDING; + + /* fbinfo */ + fb->fbops = &s5ptvfb_ops; + fb->flags = FBINFO_FLAG_DEFAULT; + fb->pseudo_palette = &win->pseudo_pal; + fix->xpanstep = 0; + fix->ypanstep = 0; + fix->type = FB_TYPE_PACKED_PIXELS; + fix->accel = FB_ACCEL_NONE; + fix->visual = FB_VISUAL_TRUECOLOR; + var->xres = lcd->width; + var->yres = lcd->height; + var->xres_virtual = var->xres; + var->yres_virtual = var->yres + (var->yres * fix->ypanstep); + var->bits_per_pixel = 32; + var->xoffset = 0; + var->yoffset = 0; + var->width = 0; + var->height = 0; + var->transp.length = 0; + + fix->line_length = var->xres_virtual * var->bits_per_pixel / 8; + fix->smem_len = fix->line_length * var->yres_virtual; + + var->nonstd = 0; + var->activate = FB_ACTIVATE_NOW; + var->vmode = FB_VMODE_NONINTERLACED; + var->hsync_len = timing->h_sw; + var->vsync_len = timing->v_sw; + var->left_margin = timing->h_fp; + var->right_margin = timing->h_bp; + var->upper_margin = timing->v_fp; + var->lower_margin = timing->v_bp; + + var->pixclock = lcd->freq * (var->left_margin + var->right_margin + + var->hsync_len + var->xres) * + (var->upper_margin + var->lower_margin + + var->vsync_len + var->yres); + + dev_dbg(s5ptv_status.dev_fb, "pixclock: %d\n", var->pixclock); + + s5ptvfb_set_bitfield(var); + s5ptvfb_set_alpha_info(var, win); + + return 0; +} + +static struct s5ptvfb_lcd max_tvfb = { + .width = 1920, + .height = 1080, + .bpp = 32, + .freq = 60, + + .timing = { + .h_fp = 49, + .h_bp = 17, + .h_sw = 33, + .v_fp = 4, + .v_fpe = 1, + .v_bp = 15, + .v_bpe = 1, + .v_sw = 6, + }, + + .polarity = { + .rise_vclk = 0, + .inv_hsync = 1, + .inv_vsync = 1, + .inv_vden = 0, + }, +}; + +void s5ptvfb_set_lcd_info(struct s5p_tv_status *ctrl) +{ + ctrl->lcd = &max_tvfb; +} diff --git a/drivers/media/video/samsung/tv20/s5p_stda_hdmi.c b/drivers/media/video/samsung/tv20/s5p_stda_hdmi.c new file mode 100644 index 0000000..15e90ad --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5p_stda_hdmi.c @@ -0,0 +1,242 @@ +/* linux/drivers/media/video/samsung/tv20/s5p_stda_hdmi.c + * + * HDMI ftn. file for Samsung TVOut driver + * + * Copyright (c) 2010 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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/stddef.h> +#include <linux/ioctl.h> +#include <linux/delay.h> +#include <linux/io.h> + +#include "s5p_tv.h" + +#include <mach/map.h> +#include <mach/regs-clock.h> + +#ifdef COFIG_TVOUT_DBG +#define S5P_STDA_HDMI_DEBUG 1 +#endif + +#ifdef S5P_STDA_HDMI_DEBUG +#define STHDPRINTK(fmt, args...) \ + printk(KERN_INFO "\t[STDA_HDMI] %s: " fmt, __func__ , ## args) +#else +#define STHDPRINTK(fmt, args...) +#endif + +/* +static bool _s5p_hdmi_spd_infoframe(unsigned long p_buf_in) +{ + STHDPRINTK("(0x%x)\n\r", (unsigned int)p_buf_in); + + if (!p_buf_in) + { + STHDPRINTK("(ERR) p_buf_in is NULL\n\r"); + return false; + } + + memcpy((void *)(&(s5ptv_status.hdmi_spd_info_frame)), + (const void *)p_buf_in, sizeof(s5p_hdmi_spd_infoframe)); + + memcpy((void *)(s5ptv_status.spd_header), + (const void *)(s5ptv_status.hdmi_spd_info_frame.spd_header), 3); + s5ptv_status.hdmi_spd_info_frame.spd_header = s5ptv_status.spd_header; + + memcpy((void *)(s5ptv_status.spd_data), + (const void *)(s5ptv_status.hdmi_spd_info_frame.spd_data), 28); + s5ptv_status.hdmi_spd_info_frame.spd_data = s5ptv_status.spd_data; + + STHDPRINTK("(0x%08x)\n\r", + (unsigned int)&s5ptv_status.hdmi_spd_info_frame); + + return true; +} +*/ + +#if 0 +static bool _s5p_hdmi_init_hdcp_en(unsigned long p_buf_in) +{ + if (!p_buf_in) { + STHDPRINTK("(ERR) p_buf_in is NULL\n\r"); + return false; + } + + STHDPRINTK("(%d)\n\r", (bool)p_buf_in); + + s5ptv_status.hdcp_en = (bool)p_buf_in; + + STHDPRINTK("(%d)\n\r", s5ptv_status.hdcp_en); + + return true; +} + +static bool _s5p_hdmi_init_audio(unsigned long p_buf_in) +{ + STHDPRINTK("(%d)\n\r", (bool)p_buf_in); + + if (!p_buf_in) { + STHDPRINTK("(ERR) p_buf_in is NULL\n\r"); + return false; + } + + s5ptv_status.hdmi_audio_type = (enum s5p_hdmi_audio_type)p_buf_in; + + STHDPRINTK("(%d)\n\r", s5ptv_status.hdmi_audio_type); + + return true; +} + +static bool _s5p_hdmi_get_hpd_status(unsigned long p_buf_out) +{ + bool *pOut; + + STHDPRINTK("()\n\r"); + + if (!p_buf_out) { + STHDPRINTK("(ERR) p_buf_out is NULL\n\r"); + return false; + } + + pOut = (bool *)p_buf_out; + + *pOut = s5ptv_status.hpd_status; + + STHDPRINTK("()\n\r"); + + return true; +} + +static bool _s5p_hdmi_wait_hpd_status_change(unsigned long p_buf_out) +{ + unsigned int *pOut; + + STHDPRINTK("()\n\r"); + + if (!p_buf_out) { + STHDPRINTK("(ERR) p_buf_out is NULL\n\r"); + return false; + } + + pOut = (unsigned int *)p_buf_out; + + + /* + if (*pOut == WAIT_TIMEOUT) + { + STHDPRINTK("(ERR) TIMEOUT~\n\r"); + } + else if (*pOut == WAIT_FAILED) + { + STHDPRINTK("(ERR) WAIT_FAILED\n\r"); + } + */ + + return true; +} + +#endif + +/*============================================================================*/ + +/* +static bool _s5p_hdmi_video_init_bluescreen(unsigned long p_buf_in) +{ + + STHDPRINTK("(0x%x)\n\r", (unsigned int)p_buf_in); + + if (!p_buf_in) + { + STHDPRINTK("(ERR) p_buf_in is NULL\n\r"); + return false; + } + + memcpy((void *)(&(s5ptv_status.hdmi_video_blue_screen)), + (const void *)p_buf_in, sizeof(s5p_hdmi_bluescreen)); + + STHDPRINTK("(0x%08x)\n\r", + (unsigned int)&s5ptv_status.hdmi_video_blue_screen); + + return true; +} + +static bool _s5p_hdmi_video_init_avi_infoframe(unsigned long p_buf_in) +{ + STHDPRINTK("(0x%x)\n\r", (unsigned int)p_buf_in); + + if (!p_buf_in) + { + STHDPRINTK("(ERR) p_buf_in is NULL\n\r"); + return false; + } + + memcpy((void *)(&(s5ptv_status.hdmi_av_info_frame)), + (const void *)p_buf_in, sizeof(s5p_hdmi_video_infoframe)); + + memcpy((void *)(s5ptv_status.avi_byte), + (const void *)(s5ptv_status.hdmi_av_info_frame.data), 13); + s5ptv_status.hdmi_av_info_frame.data = s5ptv_status.avi_byte; + + STHDPRINTK("(0x%08x)\n\r", + (unsigned int)&s5ptv_status.hdmi_av_info_frame); + + return true; +} + +static bool _s5p_hdmi_video_init_mpg_infoframe(unsigned long p_buf_in) +{ + STHDPRINTK("(0x%x)\n\r", (unsigned int)p_buf_in); + + if (!p_buf_in) + { + STHDPRINTK("(ERR) p_buf_in is NULL\n\r"); + return false; + } + + memcpy((void *)(&(s5ptv_status.hdmi_mpg_info_frame)), + (const void *)p_buf_in, sizeof(s5p_hdmi_video_infoframe)); + + memcpy((void *)(s5ptv_status.mpg_byte), + (const void *)(s5ptv_status.hdmi_mpg_info_frame.data), 5); + s5ptv_status.hdmi_mpg_info_frame.data = s5ptv_status.avi_byte; + + STHDPRINTK("(0x%08x)\n\r", + (unsigned int)&s5ptv_status.hdmi_mpg_info_frame); + + return true; +} + +static bool _s5p_hdmi_video_set_bluescreen(unsigned long p_buf_in) +{ + STHDPRINTK("(0x%x)\n\r", (unsigned int)p_buf_in); + + if (!p_buf_in) + { + STHDPRINTK("(ERR) p_buf_in is NULL\n\r"); + return false; + } + + memcpy((void *)(&(s5ptv_status.hdmi_video_blue_screen)), + (const void *)p_buf_in, sizeof(s5p_hdmi_bluescreen)); + + __s5p_hdmi_video_set_bluescreen(s5ptv_status.hdmi_video_blue_screen.en, + s5ptv_status.hdmi_video_blue_screen.cb_b, + s5ptv_status.hdmi_video_blue_screen.y_g, + s5ptv_status.hdmi_video_blue_screen.cr_r); + + STHDPRINTK("(0x%08x)\n\r", + (unsigned int)&s5ptv_status.hdmi_video_blue_screen); + + return true; +} + +*/ + diff --git a/drivers/media/video/samsung/tv20/s5p_stda_tvout_if.c b/drivers/media/video/samsung/tv20/s5p_stda_tvout_if.c new file mode 100644 index 0000000..2d22d9e --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5p_stda_tvout_if.c @@ -0,0 +1,1261 @@ +/* linux/drivers/media/video/samsung/tv20/s5p_stda_tvout_if.c + * + * TVOut interface ftn. file for Samsung TVOut driver + * + * Copyright (c) 2010 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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/stddef.h> +#include <linux/ioctl.h> +#include <linux/fs.h> +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/uaccess.h> +#include <linux/delay.h> + +#include <plat/clock.h> + +#include "s5p_tv.h" + +#ifdef COFIG_TVOUT_DBG +#define S5P_STDA_TVOUTIF_DEBUG 1 +#endif + +#ifdef S5P_STDA_TVOUTIF_DEBUG +#define TVOUTIFPRINTK(fmt, args...) \ + printk(KERN_INFO "\t[TVOUT_IF] %s: " fmt, __func__ , ## args) +#else +#define TVOUTIFPRINTK(fmt, args...) +#endif + +bool _s5p_tv_if_init_param(void) +{ + struct s5p_tv_status *st = &s5ptv_status; + + /* Initialize GRPx Layer Parameters to Default Values */ + st->grp_burst = VM_BURST_16; + st->grp_endian = TVOUT_LITTLE_ENDIAN_MODE; + + /* Initialize BG Layer Parameters to Default Values */ + st->bg_dither.cr_dither_en = false; + st->bg_dither.cb_dither_en = false; + st->bg_dither.y_dither_en = false; + + st->bg_color[0].color_y = 0; + st->bg_color[0].color_cb = 128; + st->bg_color[0].color_cr = 128; + st->bg_color[1].color_y = 0; + st->bg_color[1].color_cb = 128; + st->bg_color[1].color_cr = 128; + st->bg_color[2].color_y = 0; + st->bg_color[2].color_cb = 128; + st->bg_color[2].color_cr = 128; + + /* Initialize Video Mixer Parameters to Default Values */ + st->vm_csc_coeff_default = true; + + /* Initialize SDout Parameters to Default Values */ + st->sdout_sync_pin = SDOUT_SYNC_SIG_YG; + st->sdout_vbi.wss_cvbs = true; + st->sdout_vbi.caption_cvbs = SDOUT_INS_OTHERS; + st->sdout_vbi.wss_y_svideo = true; + st->sdout_vbi.caption_y_svideo = SDOUT_INS_OTHERS; + st->sdout_vbi.cgmsa_rgb = true; + st->sdout_vbi.wss_rgb = true; + st->sdout_vbi.caption_rgb = SDOUT_INS_OTHERS; + st->sdout_vbi.cgmsa_y_pb_pr = true; + st->sdout_vbi.wss_y_pb_pr = true; + st->sdout_vbi.caption_y_pb_pr = SDOUT_INS_OTHERS; + st->sdout_offset_gain[0].channel = SDOUT_CHANNEL_0; + st->sdout_offset_gain[0].offset = 0; + st->sdout_offset_gain[0].gain = 0x800; + st->sdout_offset_gain[1].channel = SDOUT_CHANNEL_1; + st->sdout_offset_gain[1].offset = 0; + st->sdout_offset_gain[1].gain = 0x800; + st->sdout_offset_gain[2].channel = SDOUT_CHANNEL_2; + st->sdout_offset_gain[2].offset = 0; + st->sdout_offset_gain[2].gain = 0x800; + st->sdout_delay.delay_y = 0x00; + st->sdout_delay.offset_video_start = 0xfa; + st->sdout_delay.offset_video_end = 0x00; + st->sdout_color_sub_carrier_phase_adj = false; + st->sdout_bri_hue_set.bright_hue_sat_adj = false; + st->sdout_bri_hue_set.gain_brightness = 0x80; + st->sdout_bri_hue_set.offset_brightness = 0x00; + st->sdout_bri_hue_set.gain0_cb_hue_saturation = 0x00; + st->sdout_bri_hue_set.gain1_cb_hue_saturation = 0x00; + st->sdout_bri_hue_set.gain0_cr_hue_saturation = 0x00; + st->sdout_bri_hue_set.gain1_cr_hue_saturation = 0x00; + st->sdout_bri_hue_set.offset_cb_hue_saturation = 0x00; + st->sdout_bri_hue_set.offset_cr_hue_saturation = 0x00; + st->sdout_y_pb_pr_comp = false; + st->sdout_rgb_compen.rgb_color_compensation = false; + st->sdout_rgb_compen.max_rgb_cube = 0xeb; + st->sdout_rgb_compen.min_rgb_cube = 0x10; + st->sdout_cvbs_compen.cvbs_color_compensation = false; + st->sdout_cvbs_compen.y_lower_mid = 0x200; + st->sdout_cvbs_compen.y_bottom = 0x000; + st->sdout_cvbs_compen.y_top = 0x3ff; + st->sdout_cvbs_compen.y_upper_mid = 0x200; + st->sdout_cvbs_compen.radius = 0x1ff; + st->sdout_svideo_compen.y_color_compensation = false; + st->sdout_svideo_compen.y_top = 0x3ff; + st->sdout_svideo_compen.y_bottom = 0x000; + st->sdout_svideo_compen.yc_cylinder = 0x1ff; + st->sdout_comp_porch.back_525 = 0x8a; + st->sdout_comp_porch.front_525 = 0x359; + st->sdout_comp_porch.back_625 = 0x96; + st->sdout_comp_porch.front_625 = 0x35c; + st->sdout_rgb_sync.sync_type = SDOUT_VESA_RGB_SYNC_COMPOSITE; + st->sdout_rgb_sync.vsync_active = TVOUT_POL_ACTIVE_HIGH; + st->sdout_rgb_sync.hsync_active = TVOUT_POL_ACTIVE_HIGH; + st->sdout_xtalk_cc[0].channel = SDOUT_CHANNEL_0; + st->sdout_xtalk_cc[0].coeff2 = 0; + st->sdout_xtalk_cc[0].coeff1 = 0; + st->sdout_xtalk_cc[1].channel = SDOUT_CHANNEL_1; + st->sdout_xtalk_cc[1].coeff2 = 0; + st->sdout_xtalk_cc[1].coeff1 = 0; + st->sdout_xtalk_cc[2].channel = SDOUT_CHANNEL_2; + st->sdout_xtalk_cc[2].coeff2 = 0; + st->sdout_xtalk_cc[2].coeff1 = 0; + st->sdout_closed_capt.display_cc = 0; + st->sdout_closed_capt.nondisplay_cc = 0; + st->sdout_wss_525.copy_permit = SDO_525_COPY_PERMIT; + st->sdout_wss_525.mv_psp = SDO_525_MV_PSP_OFF; + st->sdout_wss_525.copy_info = SDO_525_COPY_INFO; + st->sdout_wss_525.analog_on = false; + st->sdout_wss_525.display_ratio = SDO_525_4_3_NORMAL; + st->sdout_wss_625.surroun_f_sound = false; + st->sdout_wss_625.copyright = false; + st->sdout_wss_625.copy_protection = false; + st->sdout_wss_625.text_subtitles = false; + st->sdout_wss_625.open_subtitles = SDO_625_NO_OPEN_SUBTITLES; + st->sdout_wss_625.camera_film = SDO_625_CAMERA; + st->sdout_wss_625.color_encoding = SDO_625_NORMAL_PAL; + st->sdout_wss_625.helper_signal = false; + st->sdout_wss_625.display_ratio = SDO_625_4_3_FULL_576; + st->sdout_cgms_525.copy_permit = SDO_525_COPY_PERMIT; + st->sdout_cgms_525.mv_psp = SDO_525_MV_PSP_OFF; + st->sdout_cgms_525.copy_info = SDO_525_COPY_INFO; + st->sdout_cgms_525.analog_on = false; + st->sdout_cgms_525.display_ratio = SDO_525_4_3_NORMAL; + st->sdout_cgms_625.surroun_f_sound = false; + st->sdout_cgms_625.copyright = false; + st->sdout_cgms_625.copy_protection = false; + st->sdout_cgms_625.text_subtitles = false; + st->sdout_cgms_625.open_subtitles = SDO_625_NO_OPEN_SUBTITLES; + st->sdout_cgms_625.camera_film = SDO_625_CAMERA; + st->sdout_cgms_625.color_encoding = SDO_625_NORMAL_PAL; + st->sdout_cgms_625.helper_signal = false; + st->sdout_cgms_625.display_ratio = SDO_625_4_3_FULL_576; + + /* Initialize HDMI video Parameters to Default Values */ + st->hdmi_video_blue_screen.enable = false; + st->hdmi_color_range.y_min = 1; + st->hdmi_color_range.y_max = 254; + st->hdmi_color_range.c_min = 1; + st->hdmi_color_range.c_max = 254; + st->hdmi_av_info_frame.trans_type = HDMI_DO_NOT_TANS; + st->hdmi_av_info_frame.check_sum = 0; + st->hdmi_av_info_frame.data = st->avi_byte; + st->hdmi_mpg_info_frame.trans_type = HDMI_DO_NOT_TANS; + st->hdmi_mpg_info_frame.check_sum = 0; + st->hdmi_mpg_info_frame.data = st->mpg_byte; + memset((void *)(st->avi_byte), 0, 13); + memset((void *)(st->mpg_byte), 0, 5); + st->hdmi_tg_cmd.timing_correction_en = false; + st->hdmi_tg_cmd.bt656_sync_en = false; + st->hdmi_tg_cmd.tg_en = false; + + /* Initialize HDMI Parameters to Default Values */ + st->hdmi_spd_info_frame.trans_type = HDMI_TRANS_EVERY_SYNC; + st->hdmi_spd_info_frame.spd_header = NULL; + st->hdmi_spd_info_frame.spd_data = NULL; + + st->hdcp_en = false; + st->hdmi_audio_type = HDMI_AUDIO_PCM; + + st->tvout_param_available = true; + + return true; +} + + +bool _s5p_tv_if_init_vm_reg(void) +{ + u8 i = 0; + enum s5p_tv_vmx_err merr = 0; + struct s5p_tv_status *st = &s5ptv_status; + enum s5p_tv_o_mode out_mode = st->tvout_param.out_mode; + enum s5p_tv_disp_mode disp_mode = st->tvout_param.disp_mode; + + bool cr_en = st->bg_dither.cr_dither_en; + bool cb_en = st->bg_dither.cr_dither_en; + bool y_en = st->bg_dither.cr_dither_en; + + enum s5p_vmx_burst_mode burst = st->grp_burst; + enum s5p_endian_type endian = st->grp_endian; + + + merr = __s5p_vm_init_status_reg(burst, endian); + + if (merr != VMIXER_NO_ERROR) + return false; + + + merr = __s5p_vm_init_display_mode(disp_mode, out_mode); + + if (merr != VMIXER_NO_ERROR) + return false; + + + __s5p_vm_init_bg_dither_enable(cr_en, cb_en, y_en); + + for (i = VMIXER_BG_COLOR_0; i <= VMIXER_BG_COLOR_2; i++) { + merr = __s5p_vm_init_bg_color(i, + st->bg_color[i].color_y, + st->bg_color[i].color_cb, + st->bg_color[i].color_cr); + + if (merr != VMIXER_NO_ERROR) + return false; + } + + switch (out_mode) { + + case TVOUT_OUTPUT_COMPOSITE: + + case TVOUT_OUTPUT_SVIDEO: + + case TVOUT_OUTPUT_COMPONENT_YPBPR_INERLACED: + + case TVOUT_OUTPUT_COMPONENT_YPBPR_PROGRESSIVE: + + case TVOUT_OUTPUT_COMPONENT_RGB_PROGRESSIVE: + __s5p_vm_init_csc_coef_default(VMIXER_CSC_RGB_TO_YUV601_FR); + break; + + case TVOUT_OUTPUT_HDMI_RGB: + case TVOUT_OUTPUT_HDMI: + case TVOUT_OUTPUT_DVI: + + switch (disp_mode) { + + case TVOUT_NTSC_M: + + case TVOUT_PAL_BDGHI: + + case TVOUT_PAL_M: + + case TVOUT_PAL_N: + + case TVOUT_PAL_NC: + + case TVOUT_PAL_60: + + case TVOUT_NTSC_443: + break; + + case TVOUT_480P_60_16_9: + + case TVOUT_480P_60_4_3: +#ifdef CONFIG_CPU_S5PV210 + case TVOUT_480P_59: +#endif + case TVOUT_576P_50_16_9: + + case TVOUT_576P_50_4_3: + __s5p_vm_init_csc_coef_default( + VMIXER_CSC_RGB_TO_YUV601_FR); + break; + + case TVOUT_720P_60: + + case TVOUT_720P_50: + +#ifdef CONFIG_CPU_S5PV210 + case TVOUT_720P_59: + + case TVOUT_1080I_60: + + case TVOUT_1080I_59: + + case TVOUT_1080I_50: + + case TVOUT_1080P_60: + + case TVOUT_1080P_30: + + case TVOUT_1080P_59: + + case TVOUT_1080P_50: +#endif + __s5p_vm_init_csc_coef_default( + VMIXER_CSC_RGB_TO_YUV709_FR); + break; + } + + break; + + default: + TVOUTIFPRINTK("invalid tvout_param.out_mode parameter(%d)\n\r", + out_mode); + return false; + break; + } + + __s5p_vm_start(); + + return true; +} + +bool _s5p_tv_if_init_sd_reg(void) +{ + u8 i = 0; + enum s5p_tv_sd_err sderr = 0; + struct s5p_tv_status *st = &s5ptv_status; + enum s5p_tv_o_mode out_mode = st->tvout_param.out_mode; + enum s5p_tv_disp_mode disp_mode = st->tvout_param.disp_mode; + enum s5p_sd_order order = st->sdout_order; + + u32 delay = st->sdout_delay.delay_y; + u32 off_v_start = st->sdout_delay.offset_video_start; + u32 off_v_end = st->sdout_delay.offset_video_end; + + u32 g_bright = st->sdout_bri_hue_set.gain_brightness; + u32 off_bright = st->sdout_bri_hue_set.offset_brightness; + u32 g0_cb_h_sat = st->sdout_bri_hue_set.gain0_cb_hue_saturation; + u32 g1_cb_h_sat = st->sdout_bri_hue_set.gain1_cb_hue_saturation; + u32 g0_cr_h_sat = st->sdout_bri_hue_set.gain0_cr_hue_saturation; + u32 g1_cr_h_sat = st->sdout_bri_hue_set.gain1_cr_hue_saturation; + u32 off_cb_h_sat = st->sdout_bri_hue_set.offset_cb_hue_saturation; + u32 off_cr_h_sat = st->sdout_bri_hue_set.offset_cr_hue_saturation; + + u32 max_rgb_cube = st->sdout_rgb_compen.max_rgb_cube; + u32 min_rgb_cube = st->sdout_rgb_compen.min_rgb_cube; + u32 y_l_m_c = st->sdout_cvbs_compen.y_lower_mid; + u32 y_b_c = st->sdout_cvbs_compen.y_bottom; + u32 y_t_c = st->sdout_cvbs_compen.y_top; + u32 y_u_m_c = st->sdout_cvbs_compen.y_upper_mid; + u32 rad_c = st->sdout_cvbs_compen.radius; + u32 y_t_s = st->sdout_svideo_compen.y_top; + u32 y_b_s = st->sdout_svideo_compen.y_bottom; + u32 y_cylinder_s = st->sdout_svideo_compen.yc_cylinder; + + u32 back_525 = st->sdout_comp_porch.back_525; + u32 front_525 = st->sdout_comp_porch.front_525; + u32 back_625 = st->sdout_comp_porch.back_625; + u32 front_625 = st->sdout_comp_porch.front_625; + + u32 display_cc = st->sdout_closed_capt.display_cc; + u32 nondisplay_cc = st->sdout_closed_capt.nondisplay_cc; + + bool br_hue_sat_adj = st->sdout_bri_hue_set.bright_hue_sat_adj; + bool wss_cvbs = st->sdout_vbi.wss_cvbs; + bool wss_y_svideo = st->sdout_vbi.wss_y_svideo; + bool cgmsa_rgb = st->sdout_vbi.cgmsa_rgb; + bool wss_rgb = st->sdout_vbi.wss_rgb; + bool cgmsa_y = st->sdout_vbi.cgmsa_y_pb_pr; + bool wss_y = st->sdout_vbi.wss_y_pb_pr; + bool phase_adj = st->sdout_color_sub_carrier_phase_adj; + bool ypbpr_comp = st->sdout_y_pb_pr_comp; + bool rgb_compen = st->sdout_rgb_compen.rgb_color_compensation; + bool y_compen = st->sdout_svideo_compen.y_color_compensation; + bool cvbs_compen = st->sdout_cvbs_compen.cvbs_color_compensation; + + bool w5_analog_on = st->sdout_wss_525.analog_on; + bool w6_surroun_f_sound = st->sdout_wss_625.surroun_f_sound; + bool w6_copyright = st->sdout_wss_625.copyright; + bool w6_copy_protection = st->sdout_wss_625.copy_protection; + bool w6_text_subtitles = st->sdout_wss_625.text_subtitles; + bool w6_helper_signal = st->sdout_wss_625.helper_signal; + + bool c5_analog_on = st->sdout_cgms_525.analog_on; + bool c6_surroun_f_sound = st->sdout_cgms_625.surroun_f_sound; + bool c6_copyright = st->sdout_cgms_625.copyright; + bool c6_copy_protection = st->sdout_cgms_625.copy_protection; + bool c6_text_subtitles = st->sdout_cgms_625.text_subtitles; + bool c6_helper_signal = st->sdout_cgms_625.helper_signal; + + enum s5p_sd_level cpn_lev = st->sdout_video_scale_cfg.component_level; + enum s5p_sd_level cps_lev = st->sdout_video_scale_cfg.composite_level; + enum s5p_sd_vsync_ratio cpn_rat = + st->sdout_video_scale_cfg.component_ratio; + enum s5p_sd_vsync_ratio cps_rat = + st->sdout_video_scale_cfg.composite_ratio; + enum s5p_sd_closed_caption_type cap_cvbs = st->sdout_vbi.caption_cvbs; + enum s5p_sd_closed_caption_type cap_y_svideo = + st->sdout_vbi.caption_y_svideo; + enum s5p_sd_closed_caption_type cap_rgb = st->sdout_vbi.caption_rgb; + enum s5p_sd_closed_caption_type cap_y_pb_pr = + st->sdout_vbi.caption_y_pb_pr; + enum s5p_sd_sync_sig_pin sync_pin = st->sdout_sync_pin; + enum s5p_sd_vesa_rgb_sync_type sync_type = + st->sdout_rgb_sync.sync_type; + enum s5p_tv_active_polarity vsync_active = + st->sdout_rgb_sync.vsync_active; + enum s5p_tv_active_polarity hsync_active = + st->sdout_rgb_sync.hsync_active; + + enum s5p_sd_525_copy_permit w5_copy_permit = + st->sdout_wss_525.copy_permit; + enum s5p_sd_525_mv_psp w5_mv_psp = st->sdout_wss_525.mv_psp; + enum s5p_sd_525_copy_info w5_copy_info = st->sdout_wss_525.copy_info; + enum s5p_sd_525_aspect_ratio w5_display_ratio = + st->sdout_wss_525.display_ratio; + enum s5p_sd_625_subtitles w6_open_subtitles = + st->sdout_wss_625.open_subtitles; + enum s5p_sd_625_camera_film w6_camera_film = + st->sdout_wss_625.camera_film; + enum s5p_sd_625_color_encoding w6_color_encoding = + st->sdout_wss_625.color_encoding; + enum s5p_sd_625_aspect_ratio w6_display_ratio = + st->sdout_wss_625.display_ratio; + + enum s5p_sd_525_copy_permit c5_copy_permit = + st->sdout_cgms_525.copy_permit; + enum s5p_sd_525_mv_psp c5_mv_psp = st->sdout_cgms_525.mv_psp; + enum s5p_sd_525_copy_info c5_copy_info = + st->sdout_cgms_525.copy_info; + enum s5p_sd_525_aspect_ratio c5_display_ratio = + st->sdout_cgms_525.display_ratio; + enum s5p_sd_625_subtitles c6_open_subtitles = + st->sdout_cgms_625.open_subtitles; + enum s5p_sd_625_camera_film c6_camera_film = + st->sdout_cgms_625.camera_film; + enum s5p_sd_625_color_encoding c6_color_encoding = + st->sdout_cgms_625.color_encoding; + enum s5p_sd_625_aspect_ratio c6_display_ratio = + st->sdout_cgms_625.display_ratio; + + __s5p_sdout_sw_reset(true); + + sderr = __s5p_sdout_init_display_mode(disp_mode, out_mode, order); + + if (sderr != SDOUT_NO_ERROR) + return false; + + + sderr = __s5p_sdout_init_video_scale_cfg(cpn_lev, cpn_rat, + cps_lev, cps_rat); + + if (sderr != SDOUT_NO_ERROR) + return false; + + + sderr = __s5p_sdout_init_sync_signal_pin(sync_pin); + + if (sderr != SDOUT_NO_ERROR) + return false; + + + sderr = __s5p_sdout_init_vbi(wss_cvbs, cap_cvbs, wss_y_svideo, + cap_y_svideo, cgmsa_rgb, wss_rgb, cap_rgb, cgmsa_y, + wss_y, cap_y_pb_pr); + + if (sderr != SDOUT_NO_ERROR) + return false; + + + for (i = SDOUT_CHANNEL_0; i <= SDOUT_CHANNEL_2; i++) { + + u32 offset = st->sdout_offset_gain[i].offset; + u32 gain = st->sdout_offset_gain[i].gain; + + sderr = __s5p_sdout_init_offset_gain(i, offset, gain); + + if (sderr != SDOUT_NO_ERROR) + return false; + } + + + __s5p_sdout_init_delay(delay, off_v_start, off_v_end); + + __s5p_sdout_init_schlock(phase_adj); + + __s5p_sdout_init_color_compensaton_onoff(br_hue_sat_adj, ypbpr_comp, + rgb_compen, y_compen, cvbs_compen); + + __s5p_sdout_init_brightness_hue_saturation(g_bright, off_bright, + g0_cb_h_sat, g1_cb_h_sat, g0_cr_h_sat, + g1_cr_h_sat, off_cb_h_sat, + off_cr_h_sat); + + __s5p_sdout_init_rgb_color_compensation(max_rgb_cube, min_rgb_cube); + + __s5p_sdout_init_cvbs_color_compensation(y_l_m_c, y_b_c, y_t_c, + y_u_m_c, rad_c); + + __s5p_sdout_init_svideo_color_compensation(y_t_s, y_b_s, y_cylinder_s); + + __s5p_sdout_init_component_porch(back_525, front_525, back_625, + front_625); + + sderr = __s5p_sdout_init_vesa_rgb_sync(sync_type, vsync_active, + hsync_active); + + if (sderr != SDOUT_NO_ERROR) + return false; + + + for (i = SDOUT_CHANNEL_0; i <= SDOUT_CHANNEL_2; i++) { + enum s5p_sd_channel_sel channel = st->sdout_xtalk_cc[i].channel; + u32 coeff1 = st->sdout_xtalk_cc[i].coeff1; + u32 coeff2 = st->sdout_xtalk_cc[i].coeff2; + + sderr = __s5p_sdout_init_ch_xtalk_cancel_coef(channel, + coeff2, coeff1); + + if (sderr != SDOUT_NO_ERROR) + return false; + } + + __s5p_sdout_init_closed_caption(display_cc, nondisplay_cc); + + sderr = __s5p_sdout_init_wss525_data(w5_copy_permit, w5_mv_psp, + w5_copy_info, w5_analog_on, w5_display_ratio); + + if (sderr != SDOUT_NO_ERROR) + return false; + + + sderr = __s5p_sdout_init_wss625_data(w6_surroun_f_sound, w6_copyright, + w6_copy_protection, w6_text_subtitles, + w6_open_subtitles, w6_camera_film, + w6_color_encoding, w6_helper_signal, + w6_display_ratio); + + if (sderr != SDOUT_NO_ERROR) + return false; + + + sderr = __s5p_sdout_init_cgmsa525_data(c5_copy_permit, c5_mv_psp, + c5_copy_info, c5_analog_on, + c5_display_ratio); + + if (sderr != SDOUT_NO_ERROR) + return false; + + + sderr = __s5p_sdout_init_cgmsa625_data(c6_surroun_f_sound, c6_copyright, + c6_copy_protection, c6_text_subtitles, + c6_open_subtitles, c6_camera_film, + c6_color_encoding, c6_helper_signal, + c6_display_ratio); + + if (sderr != SDOUT_NO_ERROR) + return false; + + + /* Disable All Interrupt */ + __s5p_sdout_set_interrupt_enable(false); + + /* Clear All Interrupt Pending */ + __s5p_sdout_clear_interrupt_pending(); + + __s5p_sdout_start(); + + __s5p_tv_powerset_dac_onoff(true); + + for (i = SDOUT_CHANNEL_0; i <= SDOUT_CHANNEL_2; i++) { + + bool dac = st->sdout_dac_on[i]; + + sderr = __s5p_sdout_init_dac_power_onoff(i, dac); + + if (sderr != SDOUT_NO_ERROR) + return false; + } + + return true; +} + +unsigned char _s5p_tv_if_video_avi_checksum(void) +{ + u8 i; + u32 sum = 0; + struct s5p_tv_status *st = &s5ptv_status; + + for (i = 0; i < 13; i++) + sum += (u32)(st->avi_byte[i]); + + + return (u8)(0x100 - ((0x91 + sum) & 0xff)); +} + +bool _s5p_tv_if_init_avi_frame(struct tvout_output_if *tvout_if) +{ + struct s5p_tv_status *st = &s5ptv_status; + TVOUTIFPRINTK("(%d, %d)\n\r", tvout_if->disp_mode, + tvout_if->out_mode); + + st->hdmi_av_info_frame.trans_type = HDMI_TRANS_EVERY_SYNC; + st->avi_byte[1] = AVI_ITU709; + st->avi_byte[4] = AVI_NO_PIXEL_REPEAT; + + switch (tvout_if->disp_mode) { + +#ifdef CONFIG_CPU_S5PV210 + case TVOUT_480P_59: +#endif + case TVOUT_480P_60_16_9: + st->avi_byte[1] = AVI_PAR_16_9 | AVI_ITU601; + st->avi_byte[3] = AVI_VIC_3; + break; + + case TVOUT_480P_60_4_3: + st->avi_byte[1] = AVI_PAR_4_3 | AVI_ITU601; + st->avi_byte[3] = AVI_VIC_2; + break; + + case TVOUT_576P_50_16_9: + st->avi_byte[1] = AVI_PAR_16_9 | AVI_ITU601; + st->avi_byte[3] = AVI_VIC_18; + break; + + case TVOUT_576P_50_4_3: + st->avi_byte[1] = AVI_PAR_4_3 | AVI_ITU601; + st->avi_byte[3] = AVI_VIC_17; + break; + + case TVOUT_720P_50: + st->avi_byte[1] = AVI_PAR_16_9 | AVI_ITU709; + st->avi_byte[3] = AVI_VIC_19; + break; + + case TVOUT_720P_60: +#ifdef CONFIG_CPU_S5PV210 + case TVOUT_720P_59: + st->avi_byte[1] = AVI_PAR_16_9 | AVI_ITU709; + st->avi_byte[3] = AVI_VIC_4; + break; + + case TVOUT_1080I_50: + st->avi_byte[1] = AVI_PAR_16_9 | AVI_ITU709; + st->avi_byte[3] = AVI_VIC_20; + break; + + case TVOUT_1080I_59: + case TVOUT_1080I_60: + st->avi_byte[1] = AVI_PAR_16_9 | AVI_ITU709; + st->avi_byte[3] = AVI_VIC_5; + break; + + case TVOUT_1080P_50: + st->avi_byte[1] = AVI_PAR_16_9 | AVI_ITU709; + st->avi_byte[3] = AVI_VIC_31; + break; + + case TVOUT_1080P_30: + st->avi_byte[1] = AVI_PAR_16_9 | AVI_ITU709; + st->avi_byte[3] = AVI_VIC_34; + + case TVOUT_1080P_59: + case TVOUT_1080P_60: + st->avi_byte[1] = AVI_PAR_16_9 | AVI_ITU709; + st->avi_byte[3] = AVI_VIC_16; + break; +#endif + default: + TVOUTIFPRINTK("invalid disp_mode parameter(%d)\n\r", + tvout_if->out_mode); + return false; + break; + } + + switch (tvout_if->out_mode) { + + case TVOUT_OUTPUT_DVI: + st->hdmi_av_info_frame.trans_type = HDMI_DO_NOT_TANS; + st->avi_byte[0] = AVI_RGB_IF; + break; + + case TVOUT_OUTPUT_HDMI_RGB: + st->hdmi_av_info_frame.trans_type = HDMI_TRANS_EVERY_SYNC; + st->avi_byte[0] = AVI_RGB_IF; + break; + + case TVOUT_OUTPUT_HDMI: + st->hdmi_av_info_frame.trans_type = HDMI_TRANS_EVERY_SYNC; + st->avi_byte[0] = AVI_YCBCR444_IF; + break; + + default: + TVOUTIFPRINTK("invalid out_mode parameter(%d)\n\r", + tvout_if->out_mode); + return false; + break; + } + + st->avi_byte[1] |= AVI_SAME_WITH_PICTURE_AR; + + TVOUTIFPRINTK("()\n\r"); + return true; +} + +bool _s5p_tv_if_init_hd_video_reg(void) +{ + enum s5p_tv_hdmi_err herr = 0; + enum s5p_tv_hdmi_csc_type cscType; + struct s5p_tv_status *st = &s5ptv_status; + + u8 cb_b = st->hdmi_video_blue_screen.cb_b; + u8 y_g = st->hdmi_video_blue_screen.y_g; + u8 cr_r = st->hdmi_video_blue_screen.cr_r; + + u8 y_min = st->hdmi_color_range.y_min; + u8 y_max = st->hdmi_color_range.y_max; + u8 c_min = st->hdmi_color_range.c_min; + u8 c_max = st->hdmi_color_range.c_max; + + enum s5p_tv_disp_mode disp_mode = st->tvout_param.disp_mode; + enum s5p_tv_o_mode out_mode = st->tvout_param.out_mode; + + enum s5p_hdmi_transmit *a_trans_type = + &st->hdmi_av_info_frame.trans_type; + u8 *a_check_sum = &st->hdmi_av_info_frame.check_sum; + u8 *a_data = st->hdmi_av_info_frame.data; + + enum s5p_hdmi_transmit m_trans_type = + st->hdmi_mpg_info_frame.trans_type; + u8 m_check_sum = st->hdmi_mpg_info_frame.check_sum; + u8 *m_data = st->hdmi_mpg_info_frame.data; + + enum s5p_hdmi_transmit s_trans_type = + st->hdmi_spd_info_frame.trans_type; + u8 *spd_header = st->hdmi_spd_info_frame.spd_header; + u8 *spd_data = st->hdmi_spd_info_frame.spd_data; + + if (!_s5p_tv_if_init_avi_frame(&st->tvout_param)) { + st->tvout_param_available = false; + return false; + } + + herr = __s5p_hdmi_video_init_display_mode(disp_mode, out_mode, a_data); + + if (herr != HDMI_NO_ERROR) + return false; + + st->hdmi_av_info_frame.check_sum = _s5p_tv_if_video_avi_checksum(); + + if (!st->hdcp_en) + __s5p_hdmi_video_init_bluescreen( + st->hdmi_video_blue_screen.enable, + cb_b, y_g, cr_r); + + __s5p_hdmi_video_init_color_range(y_min, y_max, c_min, c_max); + + switch (out_mode) { + + case TVOUT_OUTPUT_HDMI_RGB: + case TVOUT_OUTPUT_HDMI: + cscType = HDMI_BYPASS; + break; + + case TVOUT_OUTPUT_DVI: + cscType = HDMI_CSC_YUV601_TO_RGB_LR; + s_trans_type = HDMI_DO_NOT_TANS; + break; + + default: + TVOUTIFPRINTK("invalid out_mode parameter(%d)\n\r", + out_mode); + return false; + break; + } + + herr = __s5p_hdmi_video_init_csc(cscType); + + if (herr != HDMI_NO_ERROR) + return false; + + + herr = __s5p_hdmi_video_init_avi_infoframe(*a_trans_type, + *a_check_sum, a_data); + + if (herr != HDMI_NO_ERROR) + return false; + + + herr = __s5p_hdmi_video_init_mpg_infoframe(m_trans_type, + m_check_sum, m_data); + + if (herr != HDMI_NO_ERROR) + return false; + + + herr = __s5p_hdmi_init_spd_infoframe(s_trans_type, + spd_header, spd_data); + + if (herr != HDMI_NO_ERROR) + return false; + + return true; +} + +bool _s5p_tv_if_init_hd_reg(void) +{ + struct s5p_tv_status *st = &s5ptv_status; + bool timing_correction_en = st->hdmi_tg_cmd.timing_correction_en; + bool bt656_sync_en = st->hdmi_tg_cmd.bt656_sync_en; + bool tg_en; + + TVOUTIFPRINTK("audio type : %d, hdcp : %s)\n\r", + st->hdmi_audio_type, st->hdcp_en ? "enabled" : "disabled"); + +/* C110_HDCP: + if (st->hdcp_en) { + if (!(st->hpd_status)) { + TVOUTIFPRINTK("HPD is not detected\n\r"); + return false; + } + } +*/ + + if (!_s5p_tv_if_init_hd_video_reg()) + return false; + + switch (st->hdmi_audio_type) { + + case HDMI_AUDIO_PCM: + /* + * PCM, Samplingrate 44100, 16bit, + * ignore framesize cuz stream is PCM. + */ + __s5p_hdmi_audio_init(PCM, 44100, 16, 0); + break; + + case HDMI_AUDIO_NO: + break; + + default: + TVOUTIFPRINTK("invalid hdmi_audio_type(%d)\n\r", + st->hdmi_audio_type); + return false; + break; + } + + if (!__s5p_hdmi_start(st->hdmi_audio_type, + st->hdcp_en, + st->hdcp_i2c_client)) { + return false; + } + + st->hdmi_tg_cmd.tg_en = true; + tg_en = st->hdmi_tg_cmd.tg_en; + + __s5p_hdmi_video_init_tg_cmd(timing_correction_en, + bt656_sync_en, tg_en); + + return true; +} + +bool _s5p_tv_if_start(void) +{ + struct s5p_tv_status *st = &s5ptv_status; + +#ifdef CONFIG_CPU_S5PC100 + enum s5p_tv_clk_err cerr = HDMI_NO_ERROR; +#endif + + enum s5p_tv_o_mode out_mode = st->tvout_param.out_mode; + +#if 0 + __s5p_vm_set_underflow_interrupt_enable(VM_VIDEO_LAYER, + false); + __s5p_vm_set_underflow_interrupt_enable(VM_GPR0_LAYER, + false); + __s5p_vm_set_underflow_interrupt_enable(VM_GPR1_LAYER, + false); + + _s5p_tv_if_stop(); + + if (st->vp_layer_enable) { + _s5p_vlayer_stop(); + /* In order to start video layer on the s5p_tv_resume() + * or handle_calbe() function*/ + st->vp_layer_enable = true; + } + + /* Clear All Interrupt Pending*/ + __s5p_vm_clear_pend_all(); + +#endif + /* + * have not to call + * another request function simultaneously + */ +#ifdef CONFIG_CPU_S5PC100 + + enum s5p_tv_disp_mode disp_mode = st->tvout_param.disp_mode; + + if (!__s5p_tv_power_get_power_status()) + __s5p_tv_poweron(); + +#endif +#ifdef CONFIG_CPU_S5PV210 + /* move to tv_phy_power()*/ + /*__s5p_tv_poweron();*/ +#endif + + switch (out_mode) { + + case TVOUT_OUTPUT_COMPOSITE: + + case TVOUT_OUTPUT_SVIDEO: + + case TVOUT_OUTPUT_COMPONENT_YPBPR_INERLACED: + + case TVOUT_OUTPUT_COMPONENT_YPBPR_PROGRESSIVE: + + case TVOUT_OUTPUT_COMPONENT_RGB_PROGRESSIVE: + +#ifdef CONFIG_CPU_S5PC100 + __s5p_tv_clk_init_video_mixer(TVOUT_CLK_VMIXER_SRCCLK_VCLK_54); + + __s5p_tv_clk_init_hpll(0xffff, 96, 6, 3); +#endif + +#ifdef CONFIG_CPU_S5PV210 + clk_set_parent(st->sclk_mixer, st->sclk_dac); +#endif + break; + + case TVOUT_OUTPUT_HDMI: + case TVOUT_OUTPUT_HDMI_RGB: + case TVOUT_OUTPUT_DVI: + +#ifdef CONFIG_CPU_S5PC100 + __s5p_tv_clk_init_video_mixer( + TVOUT_CLK_VMIXER_SRCCLK_MOUT_HPLL); + + cerr = __s5p_tv_clk_init_mout_hpll( + S5P_TV_CLK_MOUT_HPLL_FOUT_HPLL); + if (cerr != S5P_TV_CLK_ERR_NO_ERROR) + return false; +#endif + +#ifdef CONFIG_CPU_S5PV210 + clk_set_parent(st->sclk_mixer, st->sclk_hdmi); + clk_set_parent(st->sclk_hdmi, st->sclk_hdmiphy); +#endif + +#ifdef CONFIG_CPU_S5PC100 + + __s5p_tv_clk_init_hdmi_ratio(2); + + switch (disp_mode) { + + case TVOUT_480P_60_16_9: + + case TVOUT_480P_60_4_3: + + case TVOUT_576P_50_16_9: + + case TVOUT_576P_50_4_3: + __s5p_tv_clk_init_hpll(0xffff, 96, 6, 3); + break; + + + case TVOUT_720P_50: + + case TVOUT_720P_60: + __s5p_tv_clk_init_hpll(0xffff, 132, 6, 2); + break; + + default: + _s5p_tv_if_stop(); + TVOUTIFPRINTK("invalid out_mode parameter(%d)\n\r", + out_mode); + st->tvout_param_available = false; + return false; + break; + } +#endif + +#ifdef CONFIG_CPU_S5PC100 + __s5p_tv_poweroff(); + __s5p_tv_poweron(); +#endif + break; + + default: + _s5p_tv_if_stop(); + TVOUTIFPRINTK("invalid out_mode parameter(%d)\n\r", + st->tvout_param.out_mode); + st->tvout_param_available = false; + return false; + break; + } + + if (!_s5p_tv_if_init_vm_reg()) + return false; + + + switch (out_mode) { + + case TVOUT_OUTPUT_COMPOSITE: + + case TVOUT_OUTPUT_SVIDEO: + + case TVOUT_OUTPUT_COMPONENT_YPBPR_INERLACED: + + case TVOUT_OUTPUT_COMPONENT_YPBPR_PROGRESSIVE: + + case TVOUT_OUTPUT_COMPONENT_RGB_PROGRESSIVE: + + if (!_s5p_tv_if_init_sd_reg()) + return false; + + + break; + + case TVOUT_OUTPUT_DVI: + st->hdmi_audio_type = HDMI_AUDIO_NO; + + case TVOUT_OUTPUT_HDMI: + case TVOUT_OUTPUT_HDMI_RGB: + if (!_s5p_tv_if_init_hd_reg()) + return false; + + + break; + + default: + _s5p_tv_if_stop(); + TVOUTIFPRINTK("invalid out_mode parameter(%d)\n\r", + out_mode); + return false; + break; + } + + st->tvout_output_enable = true; +#if 0 + __s5p_vm_set_underflow_interrupt_enable(VM_VIDEO_LAYER, + true); + __s5p_vm_set_underflow_interrupt_enable(VM_GPR0_LAYER, + true); + __s5p_vm_set_underflow_interrupt_enable(VM_GPR1_LAYER, + true); + + /* Clear All Interrupt Pending */ + __s5p_vm_clear_pend_all(); +#endif + TVOUTIFPRINTK("()\n\r"); + + return true; +} + +/* + * TV cut off sequence + * VP stop -> Mixer stop -> HDMI stop -> HDMI TG stop + * Above sequence should be satisfied. + */ +bool _s5p_tv_if_stop(void) +{ + struct s5p_tv_status *st = &s5ptv_status; + + bool t_corr_en = st->hdmi_tg_cmd.timing_correction_en; + bool sync_en = st->hdmi_tg_cmd.bt656_sync_en; + enum s5p_tv_o_mode out_mode = st->tvout_param.out_mode; + + TVOUTIFPRINTK("tvout sub sys. stopped!!\n"); + + __s5p_vm_stop(); + + switch (out_mode) { + + case TVOUT_OUTPUT_COMPOSITE: + + case TVOUT_OUTPUT_SVIDEO: + + case TVOUT_OUTPUT_COMPONENT_YPBPR_INERLACED: + + case TVOUT_OUTPUT_COMPONENT_YPBPR_PROGRESSIVE: + + case TVOUT_OUTPUT_COMPONENT_RGB_PROGRESSIVE: + if (st->tvout_output_enable) + __s5p_sdout_stop(); + break; + + case TVOUT_OUTPUT_HDMI: + case TVOUT_OUTPUT_HDMI_RGB: + case TVOUT_OUTPUT_DVI: + if (st->tvout_output_enable) { + __s5p_hdmi_stop(); + __s5p_hdmi_video_init_tg_cmd(t_corr_en, sync_en, + false); + } + break; + + default: + TVOUTIFPRINTK("invalid out_mode parameter(%d)\n\r", out_mode); + return false; + break; + } + + +#ifdef CONFIG_CPU_S5PC100 + if (__s5p_tv_power_get_power_status()) { + __s5p_tv_clk_stop(); + __s5p_tv_poweroff(); + } +#endif + + st->tvout_output_enable = false; + st->tvout_param_available = false; + + return true; +} + +/* +* before call this ftn. set the status data!! +*/ +bool _s5p_tv_if_set_disp(void) +{ + struct s5p_tv_status *st = &s5ptv_status; + + enum s5p_tv_disp_mode disp_mode = st->tvout_param.disp_mode; + enum s5p_tv_o_mode out_mode = st->tvout_param.out_mode; + + TVOUTIFPRINTK("(%d, %d)\n\r", disp_mode, out_mode); + + switch (disp_mode) { + + case TVOUT_NTSC_M: + + case TVOUT_NTSC_443: + st->sdout_video_scale_cfg.component_level = + S5P_TV_SD_LEVEL_0IRE; + st->sdout_video_scale_cfg.component_ratio = + SDOUT_VTOS_RATIO_7_3; + st->sdout_video_scale_cfg.composite_level = + S5P_TV_SD_LEVEL_75IRE; + st->sdout_video_scale_cfg.composite_ratio = + SDOUT_VTOS_RATIO_10_4; + break; + + case TVOUT_PAL_BDGHI: + + case TVOUT_PAL_M: + + case TVOUT_PAL_N: + + case TVOUT_PAL_NC: + + case TVOUT_PAL_60: + st->sdout_video_scale_cfg.component_level = + S5P_TV_SD_LEVEL_0IRE; + st->sdout_video_scale_cfg.component_ratio = + SDOUT_VTOS_RATIO_7_3; + st->sdout_video_scale_cfg.composite_level = + S5P_TV_SD_LEVEL_0IRE; + st->sdout_video_scale_cfg.composite_ratio = + SDOUT_VTOS_RATIO_7_3; + break; + + case TVOUT_480P_60_16_9: + + case TVOUT_480P_60_4_3: + + case TVOUT_576P_50_16_9: + + case TVOUT_576P_50_4_3: + + case TVOUT_720P_50: + + case TVOUT_720P_60: + +#ifdef CONFIG_CPU_S5PV210 + + case TVOUT_1080I_50: + + case TVOUT_1080I_60: + + case TVOUT_1080P_50: + + case TVOUT_1080P_60: + + case TVOUT_1080P_30: + + case TVOUT_480P_59: + + case TVOUT_720P_59: + + case TVOUT_1080I_59: + + case TVOUT_1080P_59: +#endif + break; + default: + TVOUTIFPRINTK("invalid disp_mode parameter(%d)\n\r", + disp_mode); + st->tvout_param_available = false; + return false; + break; + } + + switch (out_mode) { + + case TVOUT_OUTPUT_COMPOSITE: + st->sdout_order = S5P_TV_SD_O_ORDER_COMPOSITE_Y_C_CVBS; + st->sdout_dac_on[2] = false; + st->sdout_dac_on[1] = false; + st->sdout_dac_on[0] = true; + break; + + case TVOUT_OUTPUT_SVIDEO: + st->sdout_order = S5P_TV_SD_O_ORDER_COMPOSITE_C_Y_CVBS; + st->sdout_dac_on[2] = true; + st->sdout_dac_on[1] = true; + st->sdout_dac_on[0] = false; + break; + + case TVOUT_OUTPUT_COMPONENT_YPBPR_INERLACED: + + case TVOUT_OUTPUT_COMPONENT_YPBPR_PROGRESSIVE: + + case TVOUT_OUTPUT_COMPONENT_RGB_PROGRESSIVE: + st->sdout_order = S5P_TV_SD_O_ORDER_COMPONENT_RBG_PRPBY; + st->sdout_dac_on[2] = true; + st->sdout_dac_on[1] = true; + st->sdout_dac_on[0] = true; + break; + + case TVOUT_OUTPUT_HDMI_RGB: + case TVOUT_OUTPUT_HDMI: + case TVOUT_OUTPUT_DVI: + st->hdmi_video_blue_screen.cb_b = 0;/* 128 */; + st->hdmi_video_blue_screen.y_g = 0; + st->hdmi_video_blue_screen.cr_r = 0;/* 128 */; + break; + + default: + TVOUTIFPRINTK("invalid out_mode parameter(%d)\n\r", + out_mode); + st->tvout_param_available = false; + return false; + break; + } +#if defined(CONFIG_CPU_S5PV210) && defined(CONFIG_PM) + if ((st->hpd_status) && st->suspend_status == false) { +#endif + _s5p_tv_if_start(); +#if defined(CONFIG_CPU_S5PV210) && defined(CONFIG_PM) + } + /* If the cable is not inserted or system is on suspend mode + Just set variable, _s5p_tv_if_start() function will be called + in resume or handle_cable function according to this variable*/ + else + st->tvout_output_enable = true; +#endif + return true; +} + diff --git a/drivers/media/video/samsung/tv20/s5p_stda_video_layer.c b/drivers/media/video/samsung/tv20/s5p_stda_video_layer.c new file mode 100644 index 0000000..05a937d --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5p_stda_video_layer.c @@ -0,0 +1,924 @@ +/* linux/drivers/media/video/samsung/tv20/s5p_stda_video_layer.c + * + * Video Layer ftn. file for Samsung TVOut driver + * + * Copyright (c) 2010 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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/stddef.h> +#include <linux/delay.h> +#include <linux/ioctl.h> +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/uaccess.h> + +#include "s5p_tv.h" + +#ifdef COFIG_TVOUT_DBG +#define S5P_VLAYER_DEBUG 1 +#endif + +#ifdef S5P_VLAYER_DEBUG +#define VLAYERPRINTK(fmt, args...) \ + printk(KERN_INFO "\t[VLAYER] %s: " fmt, __func__ , ## args) +#else +#define VLAYERPRINTK(fmt, args...) +#endif + +#define INTERLACED 0 +#define PROGRESSIVE 1 + +u8 check_input_mode(enum s5p_vp_src_color color) +{ + u8 ret = PROGRESSIVE; + + /* check i_mode */ + if (color == VPROC_SRC_COLOR_NV12IW || + color == VPROC_SRC_COLOR_TILE_NV12IW) + ret = INTERLACED; /* interlaced */ + else + ret = PROGRESSIVE; /* progressive */ + + return ret; +} + +u8 check_output_mode(enum s5p_tv_disp_mode display, + enum s5p_tv_o_mode out) +{ + u8 ret = PROGRESSIVE; + + switch (out) { + case TVOUT_OUTPUT_COMPOSITE: + case TVOUT_OUTPUT_SVIDEO: + case TVOUT_OUTPUT_COMPONENT_YPBPR_INERLACED: + ret = INTERLACED; + break; + case TVOUT_OUTPUT_COMPONENT_YPBPR_PROGRESSIVE: + case TVOUT_OUTPUT_COMPONENT_RGB_PROGRESSIVE: + case TVOUT_OUTPUT_HDMI_RGB: + case TVOUT_OUTPUT_HDMI: + case TVOUT_OUTPUT_DVI: +#ifdef CONFIG_CPU_S5PV210 + if (display == TVOUT_1080I_60 || + display == TVOUT_1080I_59 || + display == TVOUT_1080I_50) + + ret = INTERLACED; + else +#endif + ret = PROGRESSIVE; + break; + default: + break; + } + + return ret; + +} + + +static bool _s5p_vlayer_wait_previous_update(void) +{ + __s5p_vp_get_update_status(); + return false; +} + + +static void _s5p_vlayer_calc_inner_values(void) +{ + struct s5p_tv_status *st = &s5ptv_status; + struct s5p_vl_param *video = &(s5ptv_status.vl_basic_param); + u8 o_mode, i_mode; + + u32 t_y_addr = video->top_y_address; + u32 t_c_addr = video->top_c_address; + u32 img_w = video->img_width; + u32 s_ox = video->src_offset_x; + u32 s_oy = video->src_offset_y; + u32 d_ox = video->dest_offset_x; + u32 d_oy = video->dest_offset_y; + u32 s_w = video->src_width; + u32 s_h = video->src_height; + u32 d_w = video->dest_width; + u32 d_h = video->dest_height; + + i_mode = check_input_mode(st->src_color); + o_mode = check_output_mode(st->tvout_param.disp_mode, + st->tvout_param.out_mode); + + st->vl_top_y_address = t_y_addr; + st->vl_top_c_address = t_c_addr; + + if (st->src_color == VPROC_SRC_COLOR_NV12IW) { + st->vl_bottom_y_address = t_y_addr + img_w; + st->vl_bottom_c_address = t_c_addr + img_w; + } else if (st->src_color == VPROC_SRC_COLOR_TILE_NV12IW) { + st->vl_bottom_y_address = t_y_addr + 0x40; + st->vl_bottom_c_address = t_c_addr + 0x40; + } + + st->vl_src_offset_x = s_ox; + st->vl_src_offset_y = s_oy; + st->vl_src_width = s_w; + st->vl_src_height = s_h; + st->vl_dest_offset_x = d_ox; + st->vl_dest_offset_y = d_oy; + st->vl_dest_width = d_w; + st->vl_dest_height = d_h; + + + if (o_mode == INTERLACED) { + st->vl_src_height = s_h / 2; + st->vl_src_offset_y = s_oy / 2; + st->vl_dest_height = d_h / 2; + st->vl_dest_offset_y = d_oy / 2; + } else { + if (i_mode == INTERLACED) { + st->vl_src_height = s_h / 2; + st->vl_src_offset_y = s_oy / 2; + } + } +} + +bool _s5p_vlayer_start(void) +{ + int i; + + enum s5p_tv_vp_err verr; + enum s5p_tv_vmx_err merr; + struct s5p_video_img_address temp_addr; + struct s5p_img_size img_size; + + struct s5p_vl_param param = s5ptv_status.vl_basic_param; + + u8 contrast = s5ptv_status.vl_contrast; + + u32 ty_addr = s5ptv_status.vl_top_y_address; + u32 tc_addr = s5ptv_status.vl_top_c_address; + u32 by_addr = s5ptv_status.vl_bottom_y_address; + u32 bc_addr = s5ptv_status.vl_bottom_c_address; + u32 endian = param.src_img_endian; + u32 i_w = param.img_width; + u32 i_h = param.img_height; + u32 s_ox = s5ptv_status.vl_src_offset_x; + u32 s_xf = s5ptv_status.vl_src_x_fact_step; + u32 s_oy = s5ptv_status.vl_src_offset_y; + u32 s_w = s5ptv_status.vl_src_width; + u32 s_h = s5ptv_status.vl_src_height; + u32 d_ox = s5ptv_status.vl_dest_offset_x; + u32 d_oy = s5ptv_status.vl_dest_offset_y; + u32 d_w = s5ptv_status.vl_dest_width; + u32 d_h = s5ptv_status.vl_dest_height; + u32 noise = s5ptv_status.vl_sharpness.th_noise; + u32 saturation = s5ptv_status.vl_saturation; + u32 alpha = param.alpha; + u32 priority = param.priority; + u32 br_offset = s5ptv_status.vl_bright_offset; + + bool ipc = s5ptv_status.vl2d_ipc; + bool l_skip = s5ptv_status.vl_op_mode.line_skip; + bool bypass = s5ptv_status.vl_bypass_post_process; + bool po_def = s5ptv_status.vl_poly_filter_default; + bool bright = s5ptv_status.us_vl_brightness; + bool w_blend = param.win_blending; + bool csc_en = s5ptv_status.vl_csc_control.csc_en; + bool s_off_en = s5ptv_status.vl_csc_control.sub_y_offset_en; + bool csc_coef_def = s5ptv_status.vl_csc_coef_default; + + enum s5p_vp_field f_id = s5ptv_status.field_id; + enum s5p_vp_mem_mode m_mode = s5ptv_status.vl_op_mode.mem_mode; + enum s5p_vp_chroma_expansion cro_ex = + s5ptv_status.vl_op_mode.chroma_exp; + enum s5p_vp_filed_id_toggle f_id_tog = + s5ptv_status.vl_op_mode.toggle_id; + enum s5p_vp_pxl_rate p_rate = s5ptv_status.vl_rate; + enum s5p_vp_sharpness_control sharp = + s5ptv_status.vl_sharpness.sharpness; + enum s5p_vp_csc_type csc_type = s5ptv_status.vl_csc_type; + +#ifdef CONFIG_CPU_S5PC100 + __s5p_tv_clk_set_vp_clk_onoff(true); +#endif + __s5p_vp_sw_reset(); + __s5p_vp_init_field_id(f_id); + __s5p_vp_init_op_mode(l_skip, m_mode, cro_ex, f_id_tog); + __s5p_vp_init_pixel_rate_control(p_rate); + + temp_addr.y_address = param.top_y_address; + temp_addr.c_address = param.top_c_address; + img_size.img_width = param.img_width; + img_size.img_height = param.img_height; + + _s5p_vlayer_set_top_address((unsigned long)&temp_addr); + _s5p_vlayer_set_img_size((unsigned long)&img_size); + + img_size.img_width = param.src_width; + img_size.img_height = param.src_height; + _s5p_vlayer_set_src_size((unsigned long)&img_size); + + if (po_def) + verr = __s5p_vp_init_layer_def_poly_filter_coef(ty_addr, + tc_addr, by_addr, bc_addr, endian, i_w, i_h, s_ox, + s_xf, s_oy, s_w, s_h, d_ox, d_oy, d_w, d_h, ipc); + else + verr = __s5p_vp_init_layer(ty_addr, tc_addr, by_addr, bc_addr, + endian, i_w, i_h, s_ox, s_xf, s_oy, s_w, s_h, d_ox, + d_oy, d_w, d_h, ipc); + + if (verr != VPROC_NO_ERROR) + return false; + + __s5p_vp_init_bypass_post_process(bypass); + __s5p_vp_init_sharpness(noise, sharp); + __s5p_vp_init_saturation(saturation); + __s5p_vp_init_brightness(bright); + __s5p_vp_init_contrast(contrast); + + for (i = VProc_LINE_EQ_0; i <= VProc_LINE_EQ_7; i++) { + if (s5ptv_status.vl_bc_control[i].eq_num == i) + verr = __s5p_vp_init_brightness_contrast_control( + s5ptv_status.vl_bc_control[i].eq_num, + s5ptv_status.vl_bc_control[i].intc, + s5ptv_status.vl_bc_control[i].slope); + + if (verr != VPROC_NO_ERROR) + return false; + } + + __s5p_vp_init_brightness_offset(br_offset); + + __s5p_vp_init_csc_control(s_off_en, csc_en); + + if (csc_en && csc_coef_def) { + verr = __s5p_vp_init_csc_coef_default(csc_type); + + if (verr != VPROC_NO_ERROR) + return false; + } + + verr = __s5p_vp_start(); + + if (verr != VPROC_NO_ERROR) + return false; + +#ifdef CONFIG_CPU_S5PC100 + merr = __s5p_vm_init_layer(VM_VIDEO_LAYER, true, w_blend, alpha, + priority, VM_DIRECT_RGB565, false, + false, false, 0, 0, 0, 0, 0, 0, 0, 0, 0); +#endif + +#ifdef CONFIG_CPU_S5PV210 + merr = __s5p_vm_init_layer(s5ptv_status.tvout_param.disp_mode, + VM_VIDEO_LAYER, true, w_blend, alpha, priority, + VM_DIRECT_RGB565, false, false, false, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); +#endif + + if (merr != VPROC_NO_ERROR) + return false; + + __s5p_vm_start(); + + s5ptv_status.vp_layer_enable = true; + + return true; +} + +bool _s5p_vlayer_stop(void) +{ + enum s5p_tv_vp_err verr; + + __s5p_vm_set_layer_show(VM_VIDEO_LAYER, false); + + if (_s5p_vlayer_wait_previous_update()) + return false; + + verr = __s5p_vp_stop(); + + if (verr != VPROC_NO_ERROR) + return false; + +#ifdef CONFIG_CPU_S5PC100 + __s5p_tv_clk_set_vp_clk_onoff(false); +#endif + + s5ptv_status.vp_layer_enable = false; + + return true; +} + + +bool _s5p_vlayer_set_priority(unsigned long buf_in) +{ + enum s5p_tv_vmx_err merr; + u32 pri; + + s5ptv_status.vl_basic_param.priority = (unsigned int)(buf_in); + + pri = s5ptv_status.vl_basic_param.priority; + + merr = __s5p_vm_set_layer_priority(VM_VIDEO_LAYER, pri); + + if (merr != VMIXER_NO_ERROR) + return false; + + return true; +} + +bool _s5p_vlayer_set_blending(unsigned long buf_in) +{ + enum s5p_tv_vmx_err merr; + bool blend; + + s5ptv_status.vl_basic_param.win_blending = (bool)(buf_in); + blend = s5ptv_status.vl_basic_param.win_blending; + + merr = __s5p_vm_set_win_blend(VM_VIDEO_LAYER, blend); + + if (merr != VMIXER_NO_ERROR) + return false; + + return true; +} + +bool _s5p_vlayer_set_alpha(unsigned long buf_in) +{ + enum s5p_tv_vmx_err merr; + u32 alpha; + + s5ptv_status.vl_basic_param.alpha = (unsigned int)(buf_in); + alpha = s5ptv_status.vl_basic_param.alpha; + + merr = __s5p_vm_set_layer_alpha(VM_VIDEO_LAYER, alpha); + + if (merr != VMIXER_NO_ERROR) + return false; + + + return true; +} + +bool _s5p_vlayer_set_field_id(unsigned long buf_in) +{ + enum s5p_tv_vp_err verr; + + s5ptv_status.field_id = (enum s5p_vp_field)(buf_in); + + if (_s5p_vlayer_wait_previous_update()) + return false; + + + __s5p_vp_set_field_id(s5ptv_status.field_id); + + verr = __s5p_vp_update(); + + if (verr != VPROC_NO_ERROR) + return false; + + return true; +} + +bool _s5p_vlayer_set_top_address(unsigned long buf_in) +{ + u32 t_y_addr = 0; + u32 t_c_addr = 0; + u32 b_y_addr = 0; + u32 b_c_addr = 0; + + struct s5p_video_img_address *addr = + (struct s5p_video_img_address *)buf_in; + enum s5p_tv_vp_err verr; + + s5ptv_status.vl_basic_param.top_y_address = addr->y_address; + s5ptv_status.vl_basic_param.top_c_address = addr->c_address; + + _s5p_vlayer_calc_inner_values(); + + t_y_addr = s5ptv_status.vl_top_y_address; + t_c_addr = s5ptv_status.vl_top_c_address; + b_y_addr = s5ptv_status.vl_bottom_y_address; + b_c_addr = s5ptv_status.vl_bottom_c_address; + + if (_s5p_vlayer_wait_previous_update()) + return false; + + + verr = __s5p_vp_set_top_field_address(t_y_addr, t_c_addr); + + if (verr != VPROC_NO_ERROR) + return false; + + + if (check_input_mode(s5ptv_status.src_color) == INTERLACED) { + __s5p_vp_set_field_id(s5ptv_status.field_id); + verr = __s5p_vp_set_bottom_field_address(b_y_addr, b_c_addr); + + if (verr != VPROC_NO_ERROR) + return false; + } + + verr = __s5p_vp_update(); + + if (verr != VPROC_NO_ERROR) + return false; + + return true; +} + +bool _s5p_vlayer_set_bottom_address(unsigned long buf_in) +{ + u32 t_y_addr = 0; + u32 t_c_addr = 0; + u32 b_y_addr = 0; + u32 b_c_addr = 0; + + u32 img_width = s5ptv_status.vl_basic_param.img_width; + + struct s5p_video_img_address *addr = + (struct s5p_video_img_address *)buf_in; + enum s5p_tv_vp_err verr; + enum s5p_vp_src_color s_color = s5ptv_status.src_color; + + if (s_color == VPROC_SRC_COLOR_NV12IW) { + s5ptv_status.vl_basic_param.top_y_address = + addr->y_address - img_width; + s5ptv_status.vl_basic_param.top_c_address = + addr->c_address - img_width; + } + + _s5p_vlayer_calc_inner_values(); + + t_y_addr = s5ptv_status.vl_top_y_address; + t_c_addr = s5ptv_status.vl_top_c_address; + b_y_addr = s5ptv_status.vl_bottom_y_address; + b_c_addr = s5ptv_status.vl_bottom_c_address; + + if (_s5p_vlayer_wait_previous_update()) + return false; + + verr = __s5p_vp_set_bottom_field_address(b_y_addr, b_c_addr); + + if (verr != VPROC_NO_ERROR) + return false; + + + if (s5ptv_status.src_color == VPROC_SRC_COLOR_NV12IW) { + verr = __s5p_vp_set_top_field_address(t_y_addr, t_c_addr); + + if (verr != VPROC_NO_ERROR) + return false; + + } + + verr = __s5p_vp_update(); + + if (verr != VPROC_NO_ERROR) + return false; + + + return true; +} + +bool _s5p_vlayer_set_img_size(unsigned long buf_in) +{ + struct s5p_img_size *size = (struct s5p_img_size *)buf_in; + enum s5p_tv_vp_err verr; + + s5ptv_status.vl_basic_param.img_width = size->img_width; + s5ptv_status.vl_basic_param.img_height = size->img_height; + + if (_s5p_vlayer_wait_previous_update()) + return false; + + + verr = __s5p_vp_set_img_size(size->img_width, size->img_height); + + if (verr != VPROC_NO_ERROR) + return false; + + + verr = __s5p_vp_update(); + + if (verr != VPROC_NO_ERROR) + return false; + + + VLAYERPRINTK("()\n\r"); + + return true; +} + +bool _s5p_vlayer_set_src_position(unsigned long buf_in) +{ + struct s5p_img_offset *offset = (struct s5p_img_offset *)buf_in; + enum s5p_tv_vp_err verr; + + s5ptv_status.vl_basic_param.src_offset_x = offset->offset_x; + s5ptv_status.vl_basic_param.src_offset_y = offset->offset_y; + _s5p_vlayer_calc_inner_values(); + + if (_s5p_vlayer_wait_previous_update()) + return false; + + + __s5p_vp_set_src_position(s5ptv_status.vl_src_offset_x, + s5ptv_status.vl_src_x_fact_step, + s5ptv_status.vl_src_offset_y); + + verr = __s5p_vp_update(); + + if (verr != VPROC_NO_ERROR) + return false; + + + return true; +} + +bool _s5p_vlayer_set_dest_position(unsigned long buf_in) +{ + u32 d_ox = 0; + u32 d_oy = 0; + struct s5p_img_offset *offset = (struct s5p_img_offset *)buf_in; + enum s5p_tv_vp_err verr; + + s5ptv_status.vl_basic_param.dest_offset_x = offset->offset_x; + s5ptv_status.vl_basic_param.dest_offset_y = offset->offset_y; + _s5p_vlayer_calc_inner_values(); + + d_ox = s5ptv_status.vl_dest_offset_x; + d_oy = s5ptv_status.vl_dest_offset_y; + + if (_s5p_vlayer_wait_previous_update()) + return false; + + __s5p_vp_set_dest_position(d_ox, d_oy); + + verr = __s5p_vp_update(); + + if (verr != VPROC_NO_ERROR) + return false; + + return true; +} + +bool _s5p_vlayer_set_src_size(unsigned long buf_in) +{ + u32 s_w = 0; + u32 s_h = 0; + u32 d_w = 0; + u32 d_h = 0; + bool ipc = false; + + struct s5p_img_size *size = (struct s5p_img_size *)buf_in; + enum s5p_tv_vp_err verr; + + s5ptv_status.vl_basic_param.src_width = size->img_width; + s5ptv_status.vl_basic_param.src_height = size->img_height; + _s5p_vlayer_calc_inner_values(); + + s_w = s5ptv_status.vl_src_width; + s_h = s5ptv_status.vl_src_height; + d_w = s5ptv_status.vl_dest_width; + d_h = s5ptv_status.vl_dest_height; + ipc = s5ptv_status.vl2d_ipc; + + if (_s5p_vlayer_wait_previous_update()) + return false; + + __s5p_vp_set_src_dest_size(s_w, s_h, d_w, d_h, ipc); + + verr = __s5p_vp_update(); + + if (verr != VPROC_NO_ERROR) + return false; + + return true; +} + +bool _s5p_vlayer_set_dest_size(unsigned long buf_in) +{ + u32 s_w = 0; + u32 s_h = 0; + u32 d_w = 0; + u32 d_h = 0; + bool ipc = false; + + struct s5p_img_size *size = (struct s5p_img_size *)buf_in; + enum s5p_tv_vp_err verr; + + s5ptv_status.vl_basic_param.dest_width = size->img_width; + s5ptv_status.vl_basic_param.dest_height = size->img_height; + _s5p_vlayer_calc_inner_values(); + + s_w = s5ptv_status.vl_src_width; + s_h = s5ptv_status.vl_src_height; + d_w = s5ptv_status.vl_dest_width; + d_h = s5ptv_status.vl_dest_height; + ipc = s5ptv_status.vl2d_ipc; + + if (_s5p_vlayer_wait_previous_update()) + return false; + + __s5p_vp_set_src_dest_size(s_w, s_h, d_w, d_h, ipc); + + verr = __s5p_vp_update(); + + if (verr != VPROC_NO_ERROR) + return false; + + return true; +} + +bool _s5p_vlayer_set_brightness(unsigned long buf_in) +{ + enum s5p_tv_vp_err verr; + + s5ptv_status.us_vl_brightness = (unsigned short)buf_in; + + if (_s5p_vlayer_wait_previous_update()) + return false; + + + __s5p_vp_set_brightness(s5ptv_status.us_vl_brightness); + + + verr = __s5p_vp_update(); + + if (verr != VPROC_NO_ERROR) + return false; + + + return true; +} + +bool _s5p_vlayer_set_contrast(unsigned long buf_in) +{ + enum s5p_tv_vp_err verr; + + s5ptv_status.vl_contrast = (unsigned char)buf_in; + + if (_s5p_vlayer_wait_previous_update()) + return false; + + + __s5p_vp_set_contrast(s5ptv_status.vl_contrast); + + verr = __s5p_vp_update(); + + if (verr != VPROC_NO_ERROR) + return false; + + + return true; +} + +void _s5p_vlayer_get_priority(unsigned long buf_out) +{ + unsigned int *id = (unsigned int *)buf_out; + + *id = s5ptv_status.vl_basic_param.priority; +} + +bool _s5p_vlayer_set_brightness_contrast_control(unsigned long buf_in) +{ + u32 intc; + u32 slope; + + enum s5p_vp_line_eq eq_num; + enum s5p_tv_vp_err verr; + struct s5p_vl_bright_contrast_ctrl *ctrl = + (struct s5p_vl_bright_contrast_ctrl *)buf_in; + + if (ctrl->eq_num > VProc_LINE_EQ_7 || + ctrl->eq_num < VProc_LINE_EQ_0) { + VLAYERPRINTK("(ERR) : invalid eq_num(%d)\n\r", ctrl->eq_num); + return false; + } + + memcpy((void *)&(s5ptv_status.vl_bc_control[ctrl->eq_num]), + (const void *)ctrl, sizeof(struct s5p_vl_csc_ctrl)); + + eq_num = s5ptv_status.vl_bc_control[ctrl->eq_num].eq_num; + intc = s5ptv_status.vl_bc_control[ctrl->eq_num].intc; + slope = s5ptv_status.vl_bc_control[ctrl->eq_num].slope; + + if (_s5p_vlayer_wait_previous_update()) + return false; + + + verr = __s5p_vp_set_brightness_contrast_control(eq_num, intc, slope); + + if (verr != VPROC_NO_ERROR) + return false; + + + verr = __s5p_vp_update(); + + if (verr != VPROC_NO_ERROR) + return false; + + + return true; +} + +bool _s5p_vlayer_set_poly_filter_coef(unsigned long buf_in) +{ + struct s5p_video_poly_filter_coef *coef = + (struct s5p_video_poly_filter_coef *)buf_in; + enum s5p_tv_vp_err verr; + + if (coef->poly_coeff < VPROC_POLY8_Y0_LL || + (coef->poly_coeff > VPROC_POLY8_Y3_HH && + coef->poly_coeff < VPROC_POLY4_Y0_LL) || + coef->poly_coeff > VPROC_POLY4_C1_HH) { + VLAYERPRINTK("(ERR) : invalid poly_coeff(%d)\n\r", + coef->poly_coeff); + return false; + } + + if (_s5p_vlayer_wait_previous_update()) + return false; + + + verr = __s5p_vp_init_poly_filter_coef(coef->poly_coeff, + coef->ch0, coef->ch1, + coef->ch2, coef->ch3); + + if (verr != VPROC_NO_ERROR) + return false; + + verr = __s5p_vp_update(); + + if (verr != VPROC_NO_ERROR) + return false; + + s5ptv_status.vl_poly_filter_default = false; + + return true; +} + +bool _s5p_vlayer_set_csc_coef(unsigned long buf_in) +{ + struct s5p_video_csc_coef *coef = (struct s5p_video_csc_coef *)buf_in; + enum s5p_tv_vp_err verr; + + if (coef->csc_coeff < VPROC_CSC_Y2Y_COEF || + coef->csc_coeff > VPROC_CSC_CR2CR_COEF) { + VLAYERPRINTK("(ERR) : invalid csc_coeff(%d)\n\r", + coef->csc_coeff); + return false; + } + + if (_s5p_vlayer_wait_previous_update()) + return false; + + verr = __s5p_vp_init_csc_coef(coef->csc_coeff, coef->coeff); + + if (verr != VPROC_NO_ERROR) + return false; + + + verr = __s5p_vp_update(); + + if (verr != VPROC_NO_ERROR) + return false; + + + s5ptv_status.vl_csc_coef_default = false; + + return true; +} + +bool _s5p_vlayer_init_param(unsigned long buf_in) +{ + struct s5p_tv_status *st = &s5ptv_status; + + bool i_mode, o_mode; /* 0 for interlaced, 1 for progressive */ + + switch (st->tvout_param.disp_mode) { + + case TVOUT_480P_60_16_9: + + case TVOUT_480P_60_4_3: + + case TVOUT_576P_50_16_9: + + case TVOUT_576P_50_4_3: + +#ifdef CONFIG_CPU_S5PV210 + case TVOUT_480P_59: + st->vl_csc_type = VPROC_CSC_SD_HD; + break; + + case TVOUT_1080I_50: + + case TVOUT_1080I_60: + + case TVOUT_1080P_50: + + case TVOUT_1080P_30: + + case TVOUT_1080P_60: + + case TVOUT_720P_59: + + case TVOUT_1080I_59: + + case TVOUT_1080P_59: +#endif + case TVOUT_720P_50: + + case TVOUT_720P_60: + st->vl_csc_type = VPROC_CSC_HD_SD; + break; + + default: + break; + } + + st->vl_csc_control.csc_en = false; + + + i_mode = check_input_mode(st->src_color); + o_mode = check_output_mode(st->tvout_param.disp_mode, + st->tvout_param.out_mode); + + /* check o_mode */ + if (i_mode == INTERLACED) { + /* i to i : line skip 1, ipc 0, auto toggle 0 */ + if (o_mode == INTERLACED) { + st->vl_op_mode.line_skip = true; + st->vl2d_ipc = false; + st->vl_op_mode.toggle_id = false; + } else { + /* i to p : line skip 1, ipc 1, auto toggle 0 */ + st->vl_op_mode.line_skip = true; + st->vl2d_ipc = true; + st->vl_op_mode.toggle_id = false; + } + } else { + /* p to i : line skip 1, ipc 0, auto toggle 0 */ + if (o_mode == INTERLACED) { + st->vl_op_mode.line_skip = true; + st->vl2d_ipc = false; + st->vl_op_mode.toggle_id = false; + } else { + /* p to p : line skip 0, ipc 0, auto toggle 0 */ + st->vl_op_mode.line_skip = false; + st->vl2d_ipc = false; + st->vl_op_mode.toggle_id = false; + } + } + + + + st->vl_op_mode.mem_mode = ((st->src_color == VPROC_SRC_COLOR_NV12) || + st->src_color == VPROC_SRC_COLOR_NV12IW) ? + VPROC_LINEAR_MODE : VPROC_2D_TILE_MODE; +/* + st->vl_op_mode.chroma_exp = (pro) ? VPROC_USING_C_TOP + : VPROC_USING_C_TOP_BOTTOM; +*/ + st->vl_op_mode.chroma_exp = 0; /* use only top y addr */ + + _s5p_vlayer_calc_inner_values(); + + if (st->vl_mode) { + VLAYERPRINTK("(ERR) : Default values are already updated\n\r"); + return true; + } + + /* Initialize Video Layer Parameters to Default Values */ + st->vl_src_x_fact_step = 0; + st->field_id = VPROC_TOP_FIELD; + st->vl_rate = VPROC_PIXEL_PER_RATE_1_1; + st->vl_poly_filter_default = true; + st->vl_bypass_post_process = false; + st->vl_saturation = 0x80; + st->vl_sharpness.th_noise = 0; + st->vl_sharpness.sharpness = VPROC_SHARPNESS_NO; + st->us_vl_brightness = 0x00; + st->vl_contrast = 0x80; + st->vl_bright_offset = 0x00; + st->vl_csc_control.sub_y_offset_en = false; + st->vl_csc_coef_default = true; + st->vl_bc_control[0].eq_num = VProc_LINE_EQ_7 + 1; + st->vl_bc_control[1].eq_num = VProc_LINE_EQ_7 + 1; + st->vl_bc_control[2].eq_num = VProc_LINE_EQ_7 + 1; + st->vl_bc_control[3].eq_num = VProc_LINE_EQ_7 + 1; + st->vl_bc_control[4].eq_num = VProc_LINE_EQ_7 + 1; + st->vl_bc_control[5].eq_num = VProc_LINE_EQ_7 + 1; + st->vl_bc_control[6].eq_num = VProc_LINE_EQ_7 + 1; + st->vl_bc_control[7].eq_num = VProc_LINE_EQ_7 + 1; + st->vl_mode = true; + + return true; +} + diff --git a/drivers/media/video/samsung/tv20/s5p_tv.h b/drivers/media/video/samsung/tv20/s5p_tv.h new file mode 100644 index 0000000..ac3eab6 --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5p_tv.h @@ -0,0 +1,1099 @@ +/* linux/drivers/media/video/samsung/tv20/s5p_tv.h + * + * TV out driver header file for Samsung TVOut driver + * + * Copyright (c) 2010 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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/fs.h> +#include <linux/interrupt.h> +#include <linux/videodev2.h> +#include <linux/videodev2_samsung.h> +#include <linux/platform_device.h> +#include <linux/fb.h> + +#ifdef CONFIG_CPU_S5PV210 +#include "s5pv210/tv_out_s5pv210.h" +#endif + +#ifdef CONFIG_CPU_S5PC100 +#include "s5pc100/tv_out_s5pc100.h" +#endif + +/* #define COFIG_TVOUT_DBG */ + +#ifdef CONFIG_CPU_S5PC100 +#define FIX_27M_UNSTABLE_ISSUE +#define S5P_HDCP_I2C_ADDR 0x74 +#define I2C_DRIVERID_S5P_HDCP 510 +#endif + +#define V4L2_STD_ALL_HD ((v4l2_std_id)0xffffffff) + + +#ifdef CONFIG_TV_FB +#define TVOUT_MINOR_TVOUT 14 +#define TVOUT_MINOR_VID 21 +#else +#define TVOUT_MINOR_VIDEO 14 +#define TVOUT_MINOR_GRP0 21 +#define TVOUT_MINOR_GRP1 22 +#endif + +#define USE_VMIXER_INTERRUPT 1 + +#define AVI_SAME_WITH_PICTURE_AR (0x1<<3) + +#define AVI_RGB_IF (0x0<<5) +#define AVI_YCBCR444_IF (0x2<<5) + +#define AVI_ITU601 (0x1<<6) +#define AVI_ITU709 (0x2<<6) + +#define AVI_PAR_4_3 (0x1<<4) +#define AVI_PAR_16_9 (0x2<<4) + +#define AVI_NO_PIXEL_REPEAT (0x0<<0) + +#define AVI_VIC_2 (2<<0) +#define AVI_VIC_3 (3<<0) +#define AVI_VIC_4 (4<<0) +#define AVI_VIC_5 (5<<0) +#define AVI_VIC_16 (16<<0) +#define AVI_VIC_17 (17<<0) +#define AVI_VIC_18 (18<<0) +#define AVI_VIC_19 (19<<0) +#define AVI_VIC_20 (20<<0) +#define AVI_VIC_31 (31<<0) +#define AVI_VIC_34 (34<<0) + + +#define VP_UPDATE_RETRY_MAXIMUM 30 +#define VP_WAIT_UPDATE_SLEEP 3 + +struct tvout_output_if { + enum s5p_tv_disp_mode disp_mode; + enum s5p_tv_o_mode out_mode; +}; + +struct s5p_img_size { + u32 img_width; + u32 img_height; +}; + +struct s5p_img_offset { + u32 offset_x; + u32 offset_y; +}; + +struct s5p_video_img_address { + u32 y_address; + u32 c_address; +}; + +struct s5p_vl_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; +}; + +struct s5p_vl_sharpness { + u32 th_noise; + enum s5p_vp_sharpness_control sharpness; +}; + +struct s5p_vl_csc_ctrl { + bool sub_y_offset_en; + bool csc_en; +}; + +struct s5p_video_poly_filter_coef { + enum s5p_vp_poly_coeff poly_coeff; + signed char ch0; + signed char ch1; + signed char ch2; + signed char ch3; +}; + +struct s5p_vl_bright_contrast_ctrl { + enum s5p_vp_line_eq eq_num; + u32 intc; + u32 slope; +}; + +struct s5p_video_csc_coef { + enum s5p_vp_csc_coeff csc_coeff; + u32 coeff; +}; + +struct s5p_vl_param { + bool win_blending; + u32 alpha; + u32 priority; + u32 top_y_address; + u32 top_c_address; + enum s5p_endian_type src_img_endian; + u32 img_width; + u32 img_height; + u32 src_offset_x; + u32 src_offset_y; + u32 src_width; + u32 src_height; + u32 dest_offset_x; + u32 dest_offset_y; + u32 dest_width; + u32 dest_height; +}; + +struct s5p_tv_vo { + u32 index; + struct v4l2_framebuffer fb; + struct v4l2_window win; + struct v4l2_rect dst_rect; + bool win_blending; + bool blank_change; + bool pixel_blending; + bool pre_mul; + u32 blank_color; + u32 priority; + u32 base_addr; +}; + +struct s5p_bg_dither { + bool cr_dither_en; + bool cb_dither_en; + bool y_dither_en; +}; + + +struct s5p_bg_color { + u32 color_y; + u32 color_cb; + u32 color_cr; +}; + +struct s5p_vm_csc_coef { + enum s5p_yuv_fmt_component component; + enum s5p_tv_coef_y_mode mode; + u32 coeff_0; + u32 coeff_1; + u32 coeff_2; +}; + +struct s5p_sdout_order { + enum s5p_sd_order order; + bool dac[3]; +}; + +struct s5p_sd_vscale_cfg { + enum s5p_sd_level component_level; + enum s5p_sd_vsync_ratio component_ratio; + enum s5p_sd_level composite_level; + enum s5p_sd_vsync_ratio composite_ratio; +}; + +struct s5p_sd_vbi { + bool wss_cvbs; + enum s5p_sd_closed_caption_type caption_cvbs; + bool wss_y_svideo; + enum s5p_sd_closed_caption_type caption_y_svideo; + bool cgmsa_rgb; + bool wss_rgb; + enum s5p_sd_closed_caption_type caption_rgb; + bool cgmsa_y_pb_pr; + bool wss_y_pb_pr; + enum s5p_sd_closed_caption_type caption_y_pb_pr; +}; + +struct s5p_sd_offset_gain { + enum s5p_sd_channel_sel channel; + u32 offset; + u32 gain; +}; + +struct s5p_sd_delay { + u32 delay_y; + u32 offset_video_start; + u32 offset_video_end; +}; + +struct s5p_sd_bright_hue_saturat { + bool bright_hue_sat_adj; + u32 gain_brightness; + u32 offset_brightness; + u32 gain0_cb_hue_saturation; + u32 gain1_cb_hue_saturation; + u32 gain0_cr_hue_saturation; + u32 gain1_cr_hue_saturation; + u32 offset_cb_hue_saturation; + u32 offset_cr_hue_saturation; +}; + +struct s5p_sd_rgb_compensat { + bool rgb_color_compensation; + u32 max_rgb_cube; + u32 min_rgb_cube; +}; + +struct s5p_sd_cvbs_compensat { + bool cvbs_color_compensation; + u32 y_lower_mid; + u32 y_bottom; + u32 y_top; + u32 y_upper_mid; + u32 radius; +}; + +struct s5p_sd_svideo_compensat { + bool y_color_compensation; + u32 y_top; + u32 y_bottom; + u32 yc_cylinder; +}; + +struct s5p_sd_component_porch { + u32 back_525; + u32 front_525; + u32 back_625; + u32 front_625; +}; + +struct s5p_sd_vesa_rgb_sync { + enum s5p_sd_vesa_rgb_sync_type sync_type; + enum s5p_tv_active_polarity vsync_active; + enum s5p_tv_active_polarity hsync_active; +}; + +struct s5p_sd_ch_xtalk_cancellat_coeff { + enum s5p_sd_channel_sel channel; + u32 coeff1; + u32 coeff2; +}; + +struct s5p_sd_closed_caption { + u32 display_cc; + u32 nondisplay_cc; +}; + +struct s5p_sd_525_data { + bool analog_on; + enum s5p_sd_525_copy_permit copy_permit; + enum s5p_sd_525_mv_psp mv_psp; + enum s5p_sd_525_copy_info copy_info; + enum s5p_sd_525_aspect_ratio display_ratio; +}; + +struct s5p_sd_625_data { + bool surroun_f_sound; + bool copyright; + bool copy_protection; + bool text_subtitles; + enum s5p_sd_625_subtitles open_subtitles; + enum s5p_sd_625_camera_film camera_film; + enum s5p_sd_625_color_encoding color_encoding; + bool helper_signal; + enum s5p_sd_625_aspect_ratio display_ratio; +}; + +struct s5p_hdmi_bluescreen { + bool enable; + u8 cb_b; + u8 y_g; + u8 cr_r; +}; + +struct s5p_hdmi_color_range { + u8 y_min; + u8 y_max; + u8 c_min; + u8 c_max; +}; + +struct s5p_hdmi_video_infoframe { + enum s5p_hdmi_transmit trans_type; + u8 check_sum; + u8 *data; +}; + +struct s5p_hdmi_tg_cmd { + bool timing_correction_en; + bool bt656_sync_en; + bool tg_en; +}; + +struct s5p_hdmi_spd_infoframe { + enum s5p_hdmi_transmit trans_type; + u8 *spd_header; + u8 *spd_data; +}; + +struct s5p_tv_v4l2 { + struct v4l2_output *output; + struct v4l2_standard *std; + struct v4l2_format *fmt_v; + struct v4l2_format *fmt_vo_0; + struct v4l2_format *fmt_vo_1; +}; + + +#define S5PTVFB_AVALUE(r, g, b) \ + (((r & 0xf) << 8) | ((g & 0xf) << 4) | ((b & 0xf) << 0)) +#define S5PTVFB_CHROMA(r, g, b) \ + (((r & 0xff) << 16) | ((g & 0xff) << 8) | ((b & 0xff) << 0)) + +#define S5PTVFB_WIN_POSITION \ + _IOW('F', 213, struct s5ptvfb_user_window) +#define S5PTVFB_WIN_SET_PLANE_ALPHA \ + _IOW('F', 214, struct s5ptvfb_user_plane_alpha) +#define S5PTVFB_WIN_SET_CHROMA \ + _IOW('F', 215, struct s5ptvfb_user_chroma) + +enum s5ptvfb_data_path_t { + DATA_PATH_FIFO = 0, + DATA_PATH_DMA = 1, +}; + +enum s5ptvfb_alpha_t { + PLANE_BLENDING, + PIXEL_BLENDING, +}; + +enum s5ptvfb_chroma_dir_t { + CHROMA_FG, + CHROMA_BG, +}; + +struct s5ptvfb_alpha { + enum s5ptvfb_alpha_t mode; + int channel; + unsigned int value; +}; + +struct s5ptvfb_chroma { + int enabled; + int blended; + unsigned int key; + unsigned int comp_key; + unsigned int alpha; + enum s5ptvfb_chroma_dir_t dir; +}; + +struct s5ptvfb_user_window { + int x; + int y; +}; + +struct s5ptvfb_user_plane_alpha { + int channel; + unsigned char red; + unsigned char green; + unsigned char blue; +}; + +struct s5ptvfb_user_chroma { + int enabled; + unsigned char red; + unsigned char green; + unsigned char blue; +}; + + +struct s5ptvfb_window { + int id; + int enabled; + atomic_t in_use; + int x; + int y; + enum s5ptvfb_data_path_t path; + int local_channel; + int dma_burst; + unsigned int pseudo_pal[16]; + struct s5ptvfb_alpha alpha; + struct s5ptvfb_chroma chroma; + int (*suspend_fifo)(void); + int (*resume_fifo)(void); +}; + +struct s5ptvfb_lcd_timing { + int h_fp; + int h_bp; + int h_sw; + int v_fp; + int v_fpe; + int v_bp; + int v_bpe; + int v_sw; +}; + +struct s5ptvfb_lcd_polarity { + int rise_vclk; + int inv_hsync; + int inv_vsync; + int inv_vden; +}; + +struct s5ptvfb_lcd { + int width; + int height; + int bpp; + int freq; + struct s5ptvfb_lcd_timing timing; + struct s5ptvfb_lcd_polarity polarity; + + void (*init_ldi)(void); +}; + +struct s5p_tv_status { + /* TVOUT_SET_INTERFACE_PARAM */ + bool tvout_param_available; + struct tvout_output_if tvout_param; + + /* TVOUT_SET_OUTPUT_ENABLE/DISABLE */ + bool tvout_output_enable; + + /* TVOUT_SET_LAYER_MODE/POSITION */ + bool vl_mode; + bool grp_mode[2]; + + /* Video Layer Parameters */ + struct s5p_vl_param vl_basic_param; + struct s5p_vl_mode vl_op_mode; + struct s5p_vl_sharpness vl_sharpness; + struct s5p_vl_csc_ctrl vl_csc_control; + struct s5p_vl_bright_contrast_ctrl vl_bc_control[8]; + + enum s5p_vp_src_color src_color; + enum s5p_vp_field field_id; + enum s5p_vp_pxl_rate vl_rate; + enum s5p_vp_csc_type vl_csc_type; + + u32 vl_top_y_address; + u32 vl_top_c_address; + u32 vl_bottom_y_address; + u32 vl_bottom_c_address; + u32 vl_src_offset_x; + u32 vl_src_x_fact_step; + u32 vl_src_offset_y; + u32 vl_src_width; + u32 vl_src_height; + u32 vl_dest_offset_x; + u32 vl_dest_offset_y; + u32 vl_dest_width; + u32 vl_dest_height; + bool vl2d_ipc; + + bool vl_poly_filter_default; + bool vl_bypass_post_process; + u32 vl_saturation; + bool us_vl_brightness; + u8 vl_contrast; + u32 vl_bright_offset; + bool vl_csc_coef_default; + + /* GRP Layer Common Parameters */ + enum s5p_vmx_burst_mode grp_burst; + enum s5p_endian_type grp_endian; + + /* BackGroung Layer Parameters */ + struct s5p_bg_dither bg_dither; + struct s5p_bg_color bg_color[3]; + + /* Video Mixer Parameters */ + bool vm_csc_coeff_default; + + /* SDout Parameters */ + struct s5p_sd_vscale_cfg sdout_video_scale_cfg; + struct s5p_sd_vbi sdout_vbi; + struct s5p_sd_offset_gain sdout_offset_gain[3]; + struct s5p_sd_delay sdout_delay; + struct s5p_sd_bright_hue_saturat sdout_bri_hue_set; + struct s5p_sd_rgb_compensat sdout_rgb_compen; + struct s5p_sd_cvbs_compensat sdout_cvbs_compen; + struct s5p_sd_svideo_compensat sdout_svideo_compen; + struct s5p_sd_component_porch sdout_comp_porch; + struct s5p_sd_vesa_rgb_sync sdout_rgb_sync; + struct s5p_sd_ch_xtalk_cancellat_coeff sdout_xtalk_cc[3]; + struct s5p_sd_closed_caption sdout_closed_capt; + struct s5p_sd_525_data sdout_wss_525; + struct s5p_sd_625_data sdout_wss_625; + struct s5p_sd_525_data sdout_cgms_525; + struct s5p_sd_625_data sdout_cgms_625; + + enum s5p_sd_order sdout_order; + enum s5p_sd_sync_sig_pin sdout_sync_pin; + + bool sdout_color_sub_carrier_phase_adj; + bool sdout_dac_on[3]; + bool sdout_y_pb_pr_comp; + + /* HDMI video parameters */ + struct s5p_hdmi_bluescreen hdmi_video_blue_screen; + struct s5p_hdmi_color_range hdmi_color_range; + struct s5p_hdmi_video_infoframe hdmi_av_info_frame; + struct s5p_hdmi_video_infoframe hdmi_mpg_info_frame; + struct s5p_hdmi_tg_cmd hdmi_tg_cmd; + u8 avi_byte[13]; + u8 mpg_byte[5]; + + /* HDMI parameters */ + struct s5p_hdmi_spd_infoframe hdmi_spd_info_frame; + u8 spd_header[3]; + u8 spd_data[28]; + bool hdcp_en; + enum s5p_hdmi_audio_type hdmi_audio_type; + bool hpd_status; + bool suspend_status; + + /* TVOUT_SET_LAYER_ENABLE/DISABLE */ + bool vp_layer_enable; + bool grp_layer_enable[2]; + + /* i2c for hdcp port */ + struct i2c_client *hdcp_i2c_client; + + struct s5p_tv_vo overlay[2]; + + struct video_device *video_dev[3]; + + struct regulator *tv_tv; + struct regulator *tv_tvout; + struct regulator *tv_regulator; + + struct clk *tvenc_clk; + struct clk *vp_clk; + struct clk *mixer_clk; + struct clk *hdmi_clk; + struct clk *i2c_phy_clk; + struct clk *sclk_hdmiphy; + struct clk *sclk_pixel; + struct clk *sclk_dac; + struct clk *sclk_hdmi; + struct clk *sclk_mixer; + + struct s5p_tv_v4l2 v4l2; + + struct s5ptvfb_window win; + struct fb_info *fb; + struct device *dev_fb; + + struct s5ptvfb_lcd *lcd; + struct mutex fb_lock; +}; + +/* F R A M E B U F F E R */ +#define S5PTVFB_NAME "s5ptvfb" + +/* +* V4L2 TVOUT EXTENSIONS +* +*/ +#define V4L2_INPUT_TYPE_MSDMA 3 +#define V4L2_INPUT_TYPE_FIFO 4 + +#define V4L2_OUTPUT_TYPE_MSDMA 4 +#define V4L2_OUTPUT_TYPE_COMPOSITE 5 +#define V4L2_OUTPUT_TYPE_SVIDEO 6 +#define V4L2_OUTPUT_TYPE_YPBPR_INERLACED 7 +#define V4L2_OUTPUT_TYPE_YPBPR_PROGRESSIVE 8 +#define V4L2_OUTPUT_TYPE_RGB_PROGRESSIVE 9 +#define V4L2_OUTPUT_TYPE_DIGITAL 10 +#define V4L2_OUTPUT_TYPE_HDMI V4L2_OUTPUT_TYPE_DIGITAL +#define V4L2_OUTPUT_TYPE_HDMI_RGB 11 +#define V4L2_OUTPUT_TYPE_DVI 12 + +#define V4L2_STD_PAL_BDGHI (V4L2_STD_PAL_B| \ + V4L2_STD_PAL_D| \ + V4L2_STD_PAL_G| \ + V4L2_STD_PAL_H| \ + V4L2_STD_PAL_I) + +#define V4L2_STD_480P_60_16_9 ((v4l2_std_id)0x04000000) +#define V4L2_STD_480P_60_4_3 ((v4l2_std_id)0x05000000) +#define V4L2_STD_576P_50_16_9 ((v4l2_std_id)0x06000000) +#define V4L2_STD_576P_50_4_3 ((v4l2_std_id)0x07000000) +#define V4L2_STD_720P_60 ((v4l2_std_id)0x08000000) +#define V4L2_STD_720P_50 ((v4l2_std_id)0x09000000) +#define V4L2_STD_1080P_60 ((v4l2_std_id)0x0a000000) +#define V4L2_STD_1080P_50 ((v4l2_std_id)0x0b000000) +#define V4L2_STD_1080I_60 ((v4l2_std_id)0x0c000000) +#define V4L2_STD_1080I_50 ((v4l2_std_id)0x0d000000) +#define V4L2_STD_480P_59 ((v4l2_std_id)0x0e000000) +#define V4L2_STD_720P_59 ((v4l2_std_id)0x0f000000) +#define V4L2_STD_1080I_59 ((v4l2_std_id)0x10000000) +#define V4L2_STD_1080P_59 ((v4l2_std_id)0x11000000) +#define V4L2_STD_1080P_30 ((v4l2_std_id)0x12000000) + +#define FORMAT_FLAGS_DITHER 0x01 +#define FORMAT_FLAGS_PACKED 0x02 +#define FORMAT_FLAGS_PLANAR 0x04 +#define FORMAT_FLAGS_RAW 0x08 +#define FORMAT_FLAGS_CrCb 0x10 + +#define V4L2_FBUF_FLAG_PRE_MULTIPLY 0x0040 +#define V4L2_FBUF_CAP_PRE_MULTIPLY 0x0080 + +struct v4l2_window_s5p_tvout { + u32 capability; + u32 flags; + u32 priority; + + struct v4l2_window win; +}; + +struct v4l2_pix_format_s5p_tvout { + void *base_y; + void *base_c; + bool src_img_endian; + + struct v4l2_pix_format pix_fmt; +}; + +extern const struct v4l2_ioctl_ops s5p_tv_v4l2_v_ops; +extern const struct v4l2_ioctl_ops s5p_tv_v4l2_vo_ops; +extern const struct v4l2_ioctl_ops s5p_tv_v4l2_ops; +extern const struct v4l2_ioctl_ops s5p_tv_v4l2_vid_ops; + + +extern void s5p_tv_v4l2_init_param(void); + +extern long s5p_tv_ioctl(struct file *file, u32 cmd, unsigned long arg); +extern long s5p_tv_vid_ioctl(struct file *file, u32 cmd, unsigned long arg); +extern long s5p_tv_v_ioctl(struct file *file, u32 cmd, unsigned long arg); +extern long s5p_tv_vo_ioctl(struct file *file, u32 cmd, unsigned long arg); + + +#ifdef CONFIG_CPU_S5PC100 +int __init __s5p_hdmi_probe(struct platform_device *pdev, u32 res_num); +#endif + +#ifdef CONFIG_CPU_S5PV210 +int __init __s5p_hdmi_probe(struct platform_device *pdev, + u32 res_num, u32 res_num2); +int __s5p_hdmi_phy_power(bool on); +#endif + +int __init __s5p_sdout_probe(struct platform_device *pdev, u32 res_num); +int __init __s5p_mixer_probe(struct platform_device *pdev, u32 res_num); +int __init __s5p_vp_probe(struct platform_device *pdev, u32 res_num); +int __init __s5p_tvclk_probe(struct platform_device *pdev, u32 res_num); + +int __init __s5p_hdmi_release(struct platform_device *pdev); +int __init __s5p_sdout_release(struct platform_device *pdev); +int __init __s5p_mixer_release(struct platform_device *pdev); +int __init __s5p_vp_release(struct platform_device *pdev); +int __init __s5p_tvclk_release(struct platform_device *pdev); + + +extern bool _s5p_hdmi_api_proc(unsigned long arg, u32 cmd); +extern bool _s5p_hdmi_video_api_proc(unsigned long arg, u32 cmd); + +extern bool _s5p_grp_api_proc(unsigned long arg, u32 cmd); +extern bool _s5p_grp_init_param(enum s5p_tv_vmx_layer vm_layer, + unsigned long p_buf_in); +extern bool _s5p_grp_start(enum s5p_tv_vmx_layer vmLayer); +extern bool _s5p_grp_stop(enum s5p_tv_vmx_layer vmLayer); + +extern bool _s5p_tv_if_api_proc(unsigned long arg, u32 cmd); +extern bool _s5p_tv_if_init_param(void); +extern bool _s5p_tv_if_start(void); +extern bool _s5p_tv_if_stop(void); +extern bool _s5p_tv_if_set_disp(void); + +extern bool _s5p_bg_api_proc(unsigned long arg, u32 cmd); +extern bool _s5p_sdout_api_proc(unsigned long arg, u32 cmd); + +extern bool _s5p_vlayer_set_blending(unsigned long p_buf_in); +extern bool _s5p_vlayer_set_alpha(unsigned long p_buf_in); +extern bool _s5p_vlayer_api_proc(unsigned long arg, u32 cmd); +extern bool _s5p_vlayer_init_param(unsigned long p_buf_in); +extern bool _s5p_vlayer_set_priority(unsigned long p_buf_in); +extern bool _s5p_vlayer_set_field_id(unsigned long p_buf_in); +extern bool _s5p_vlayer_set_top_address(unsigned long p_buf_in); +extern bool _s5p_vlayer_set_bottom_address(unsigned long p_buf_in); +extern bool _s5p_vlayer_set_img_size(unsigned long p_buf_in); +extern bool _s5p_vlayer_set_src_position(unsigned long p_buf_in); +extern bool _s5p_vlayer_set_dest_position(unsigned long p_buf_in); +extern bool _s5p_vlayer_set_src_size(unsigned long p_buf_in); +extern bool _s5p_vlayer_set_dest_size(unsigned long p_buf_in); +extern bool _s5p_vlayer_set_brightness(unsigned long p_buf_in); +extern bool _s5p_vlayer_set_contrast(unsigned long p_buf_in); +extern void _s5p_vlayer_get_priority(unsigned long p_buf_out); +extern bool _s5p_vlayer_set_brightness_contrast_control(unsigned long + p_buf_in); +extern bool _s5p_vlayer_set_poly_filter_coef(unsigned long p_buf_in); +extern bool _s5p_vlayer_set_csc_coef(unsigned long p_buf_in); +extern bool _s5p_vlayer_start(void); +extern bool _s5p_vlayer_stop(void); + +void __s5p_read_hdcp_data(u8 reg_addr, u8 count, u8 *data); +void __s5p_write_hdcp_data(u8 reg_addr, u8 count, u8 *data); +void __s5p_write_ainfo(void); +void __s5p_write_an(void); +void __s5p_write_aksv(void); +void __s5p_read_bcaps(void); +void __s5p_read_bksv(void); +bool __s5p_compare_p_value(void); +bool __s5p_compare_r_value(void); +void __s5p_reset_authentication(void); +void __s5p_make_aes_key(void); +void __s5p_set_av_mute_on_off(u32 on_off); +void __s5p_start_encryption(void); +void __s5p_start_decrypting(const u8 *hdcp_key, u32 hdcp_key_size); +bool __s5p_check_repeater(void); +bool __s5p_is_occurred_hdcp_event(void); +irqreturn_t __s5p_hdmi_irq(int irq, void *dev_id); +bool __s5p_is_decrypting_done(void); +void __s5p_set_hpd_detection(u32 detection_type, bool hdcp_enabled, + struct i2c_client *client); + +#ifdef CONFIG_CPU_S5PC100 +bool __s5p_start_hdcp(void); +void __s5p_stop_hdcp(void); +void __s5p_hdcp_reset(void); +#endif + +void __s5p_hdmi_set_hpd_onoff(bool on_off); +void __s5p_hdmi_audio_set_config(enum s5p_tv_audio_codec_type audio_codec); +void __s5p_hdmi_audio_set_acr(u32 sample_rate); +void __s5p_hdmi_audio_set_asp(void); +void __s5p_hdmi_audio_clock_enable(void); +void __s5p_hdmi_audio_set_repetition_time( + enum s5p_tv_audio_codec_type audio_codec, + u32 bits, u32 frame_size_code); +void __s5p_hdmi_audio_irq_enable(u32 irq_en); +void __s5p_hdmi_audio_set_aui(enum s5p_tv_audio_codec_type audio_codec, + u32 sample_rate, u32 bits); +void __s5p_hdmi_video_set_bluescreen(bool en, u8 cb, u8 y_g, u8 cr_r); +enum s5p_tv_hdmi_err __s5p_hdmi_init_spd_infoframe( + enum s5p_hdmi_transmit trans_type, + u8 *spd_header, u8 *spd_data); +void __s5p_hdmi_init_hpd_onoff(bool on_off); +enum s5p_tv_hdmi_err __s5p_hdmi_audio_init( + enum s5p_tv_audio_codec_type audio_codec, + u32 sample_rate, u32 bits, u32 frame_size_code); +enum s5p_tv_hdmi_err __s5p_hdmi_video_init_display_mode( + enum s5p_tv_disp_mode disp_mode, + enum s5p_tv_o_mode out_mode, u8 *avidata); +void __s5p_hdmi_video_init_bluescreen(bool en, u8 cb, u8 y_g, u8 cr_r); +void __s5p_hdmi_video_init_color_range(u8 y_min, u8 y_max, u8 c_min, u8 c_max); +enum s5p_tv_hdmi_err __s5p_hdmi_video_init_csc( + enum s5p_tv_hdmi_csc_type csc_type); +enum s5p_tv_hdmi_err __s5p_hdmi_video_init_avi_infoframe( + enum s5p_hdmi_transmit trans_type, u8 check_sum, u8 *pavi_data); +enum s5p_tv_hdmi_err __s5p_hdmi_video_init_mpg_infoframe( + enum s5p_hdmi_transmit trans_type, u8 check_sum, u8 *pmpg_data); +void __s5p_hdmi_video_init_tg_cmd(bool t_correction_en, bool BT656_sync_en, + bool tg_en); +bool __s5p_hdmi_start(enum s5p_hdmi_audio_type hdmi_audio_type, bool HDCP_en, + struct i2c_client *ddc_port); +void __s5p_hdmi_stop(void); + +enum s5p_tv_sd_err __s5p_sdout_init_video_scale_cfg( + enum s5p_sd_level component_level, + enum s5p_sd_vsync_ratio component_ratio, + enum s5p_sd_level composite_level, + enum s5p_sd_vsync_ratio composite_ratio); +enum s5p_tv_sd_err __s5p_sdout_init_sync_signal_pin( + enum s5p_sd_sync_sig_pin pin); +enum s5p_tv_sd_err __s5p_sdout_init_vbi(bool wss_cvbs, + enum s5p_sd_closed_caption_type caption_cvbs, bool wss_y_sideo, + enum s5p_sd_closed_caption_type caption_y_sideo, bool cgmsa_rgb, + bool wss_rgb, enum s5p_sd_closed_caption_type caption_rgb, + bool cgmsa_y_ppr, bool wss_y_ppr, + enum s5p_sd_closed_caption_type caption_y_ppr); +enum s5p_tv_sd_err __s5p_sdout_init_offset_gain( + enum s5p_sd_channel_sel channel, + u32 offset, u32 gain); +void __s5p_sdout_init_delay(u32 delay_y, u32 offset_video_start, + u32 offset_video_end); +void __s5p_sdout_init_schlock(bool color_sucarrier_pha_adj); +enum s5p_tv_sd_err __s5p_sdout_init_dac_power_onoff( + enum s5p_sd_channel_sel channel, + bool dac_on); +void __s5p_sdout_init_color_compensaton_onoff(bool bright_hue_saturation_adj, + bool y_ppr_color_compensation, bool rgb_color_compensation, + bool y_c_color_compensation, bool y_cvbs_color_compensation); +void __s5p_sdout_init_brightness_hue_saturation(u32 gain_brightness, + u32 offset_brightness, u32 gain0_cb_hue_saturation, + u32 gain1_cb_hue_saturation, u32 gain0_cr_hue_saturation, + u32 gain1_cr_hue_saturation, u32 offset_cb_hue_saturation, + u32 offset_cr_hue_saturation); +void __s5p_sdout_init_rgb_color_compensation(u32 max_rgb_cube, + u32 min_rgb_cube); +void __s5p_sdout_init_cvbs_color_compensation(u32 y_lower_mid, + u32 y_bottom, u32 y_top, u32 y_upper_mid, u32 radius); +void __s5p_sdout_init_svideo_color_compensation(u32 y_top, u32 y_bottom, + u32 y_c_cylinder); +void __s5p_sdout_init_component_porch(u32 back_525, u32 front_525, + u32 back_625, u32 front_625); +enum s5p_tv_sd_err __s5p_sdout_init_vesa_rgb_sync( + enum s5p_sd_vesa_rgb_sync_type sync_type, + enum s5p_tv_active_polarity v_sync_active, + enum s5p_tv_active_polarity h_sync_active); +void __s5p_sdout_init_oversampling_filter_coeff(u32 size, u32 *pcoeff0, + u32 *pcoeff1, u32 *pcoeff2); +enum s5p_tv_sd_err __s5p_sdout_init_ch_xtalk_cancel_coef( + enum s5p_sd_channel_sel channel, + u32 coeff2, u32 coeff1); +void __s5p_sdout_init_closed_caption(u32 display_cc, u32 non_display_cc); +enum s5p_tv_sd_err __s5p_sdout_init_wss525_data( + enum s5p_sd_525_copy_permit copy_permit, + enum s5p_sd_525_mv_psp mv_psp, enum s5p_sd_525_copy_info copy_info, + bool analog_on, enum s5p_sd_525_aspect_ratio display_ratio); +enum s5p_tv_sd_err __s5p_sdout_init_wss625_data(bool surround_sound, + bool copyright, bool copy_protection, bool text_subtitles, + enum s5p_sd_625_subtitles open_subtitles, + enum s5p_sd_625_camera_film camera_film, + enum s5p_sd_625_color_encoding color_encoding, + bool helper_signal, enum s5p_sd_625_aspect_ratio display_ratio); +enum s5p_tv_sd_err __s5p_sdout_init_cgmsa525_data( + enum s5p_sd_525_copy_permit copy_permit, enum s5p_sd_525_mv_psp mv_psp, + enum s5p_sd_525_copy_info copy_info, bool analog_on, + enum s5p_sd_525_aspect_ratio display_ratio); +enum s5p_tv_sd_err __s5p_sdout_init_cgmsa625_data(bool surround_sound, + bool copyright, bool copy_protection, bool text_subtitles, + enum s5p_sd_625_subtitles open_subtitles, + enum s5p_sd_625_camera_film camera_film, + enum s5p_sd_625_color_encoding color_encoding, bool helper_signal, + enum s5p_sd_625_aspect_ratio display_ratio); +enum s5p_tv_sd_err __s5p_sdout_init_display_mode( + enum s5p_tv_disp_mode disp_mode, + enum s5p_tv_o_mode out_mode, enum s5p_sd_order order); +void __s5p_sdout_start(void); +void __s5p_sdout_stop(void); +void __s5p_sdout_sw_reset(bool active); +void __s5p_sdout_set_interrupt_enable(bool vsync_intr_en); +void __s5p_sdout_clear_interrupt_pending(void); +bool __s5p_sdout_get_interrupt_pending(void); + +enum s5p_tv_vmx_err __s5p_vm_set_win_blend(enum s5p_tv_vmx_layer layer, + bool enable); +enum s5p_tv_vmx_err __s5p_vm_set_layer_alpha(enum s5p_tv_vmx_layer layer, + u32 alpha); +enum s5p_tv_vmx_err __s5p_vm_set_layer_show(enum s5p_tv_vmx_layer layer, + bool show); +enum s5p_tv_vmx_err __s5p_vm_set_layer_priority(enum s5p_tv_vmx_layer layer, + u32 priority); +enum s5p_tv_vmx_err __s5p_vm_set_grp_base_address(enum s5p_tv_vmx_layer layer, + u32 baseaddr); +enum s5p_tv_vmx_err __s5p_vm_set_grp_layer_position( + enum s5p_tv_vmx_layer layer, + u32 dst_offs_x, u32 dst_offs_y); +enum s5p_tv_vmx_err __s5p_vm_set_grp_layer_size(enum s5p_tv_vmx_layer layer, + u32 span, u32 width, u32 height, u32 src_offs_x, u32 src_offs_y); +enum s5p_tv_vmx_err __s5p_vm_set_bg_color( + enum s5p_tv_vmx_bg_color_num colornum, + u32 color_y, u32 color_cb, u32 color_cr); +enum s5p_tv_vmx_err __s5p_vm_init_status_reg(enum s5p_vmx_burst_mode burst, + enum s5p_endian_type endian); +enum s5p_tv_vmx_err __s5p_vm_init_display_mode(enum s5p_tv_disp_mode mode, + enum s5p_tv_o_mode output_mode); + +#ifdef CONFIG_CPU_S5PC100 +enum s5p_tv_vmx_err __s5p_vm_init_layer(enum s5p_tv_vmx_layer layer, bool show, + bool winblending, u32 alpha, u32 priority, + enum s5p_tv_vmx_color_fmt color, bool blankchange, + bool pixelblending, bool premul, u32 blankcolor, + u32 baseaddr, u32 span, u32 width, u32 height, + u32 src_offs_x, u32 src_offs_y, u32 dst_offs_x, u32 dst_offs_y); +#endif + +#ifdef CONFIG_CPU_S5PV210 +enum s5p_tv_vmx_err __s5p_vm_init_layer(enum s5p_tv_disp_mode mode, + enum s5p_tv_vmx_layer layer, bool show, bool winblending, + u32 alpha, u32 priority, enum s5p_tv_vmx_color_fmt color, + bool blankchange, bool pixelblending, bool premul, + u32 blankcolor, u32 baseaddr, u32 span, u32 width, + u32 height, u32 src_offs_x, u32 src_offs_y, u32 dst_offs_x, + u32 dst_offs_y, u32 dst_x, u32 dst_y); +void __s5p_vm_set_ctrl(enum s5p_tv_vmx_layer layer, bool premul, + bool pixel_blending, bool blank_change, bool win_blending, + enum s5p_tv_vmx_color_fmt color, u32 alpha, u32 blank_color); +#endif + +void __s5p_vm_init_bg_dither_enable(bool cr_dither_enable, + bool cdither_enable, bool y_dither_enable); +enum s5p_tv_vmx_err __s5p_vm_init_bg_color( + enum s5p_tv_vmx_bg_color_num color_num, + u32 color_y, u32 color_cb, u32 color_cr); +enum s5p_tv_vmx_err __s5p_vm_init_csc_coef( + enum s5p_yuv_fmt_component component, + enum s5p_tv_coef_y_mode mode, u32 coeff0, u32 coeff1, u32 coeff2); +void __s5p_vm_init_csc_coef_default(enum s5p_tv_vmx_csc_type csc_type); +enum s5p_tv_vmx_err __s5p_vm_get_layer_info(enum s5p_tv_vmx_layer layer, + bool *show, + u32 *priority); +void __s5p_vm_start(void); +void __s5p_vm_stop(void); +enum s5p_tv_vmx_err __s5p_vm_set_underflow_interrupt_enable( + enum s5p_tv_vmx_layer layer, + bool en); +void __s5p_vm_clear_pend_all(void); +irqreturn_t __s5p_mixer_irq(int irq, void *dev_id); + +void __s5p_vp_set_field_id(enum s5p_vp_field mode); +enum s5p_tv_vp_err __s5p_vp_set_top_field_address(u32 top_y_addr, + u32 top_c_addr); +enum s5p_tv_vp_err __s5p_vp_set_bottom_field_address(u32 bottom_y_addr, + u32 bottom_c_addr); +enum s5p_tv_vp_err __s5p_vp_set_img_size(u32 img_width, u32 img_height); +void __s5p_vp_set_src_position(u32 src_off_x, u32 src_x_fract_step, + u32 src_off_y); +void __s5p_vp_set_dest_position(u32 dst_off_x, u32 dst_off_y); +void __s5p_vp_set_src_dest_size(u32 src_width, u32 src_height, + u32 dst_width, u32 dst_height, bool ipc_2d); +enum s5p_tv_vp_err __s5p_vp_set_poly_filter_coef( + enum s5p_vp_poly_coeff poly_coeff, + signed char ch0, signed char ch1, signed char ch2, signed char ch3); +void __s5p_vp_set_poly_filter_coef_default(u32 h_ratio, u32 v_ratio); +void __s5p_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); +enum s5p_tv_vp_err __s5p_vp_set_brightness_contrast_control( + enum s5p_vp_line_eq eq_num, + u32 intc, u32 slope); +void __s5p_vp_set_brightness(bool brightness); +void __s5p_vp_set_contrast(u8 contrast); +enum s5p_tv_vp_err __s5p_vp_update(void); +enum s5p_vp_field __s5p_vp_get_field_id(void); +bool __s5p_vp_get_update_status(void); +void __s5p_vp_init_field_id(enum s5p_vp_field mode); +void __s5p_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); +void __s5p_vp_init_pixel_rate_control(enum s5p_vp_pxl_rate rate); +enum s5p_tv_vp_err __s5p_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 __s5p_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 __s5p_vp_init_poly_filter_coef( + enum s5p_vp_poly_coeff poly_coeff, + signed char ch0, signed char ch1, signed char ch2, signed char ch3); +void __s5p_vp_init_bypass_post_process(bool bypass); +enum s5p_tv_vp_err __s5p_vp_init_csc_coef(enum s5p_vp_csc_coeff csc_coeff, + u32 coeff); +void __s5p_vp_init_saturation(u32 sat); +void __s5p_vp_init_sharpness(u32 th_h_noise, + enum s5p_vp_sharpness_control sharpness); +enum s5p_tv_vp_err __s5p_vp_init_brightness_contrast_control( + enum s5p_vp_line_eq eq_num, + u32 intc, u32 slope); +void __s5p_vp_init_brightness(bool brightness); +void __s5p_vp_init_contrast(u8 contrast); +void __s5p_vp_init_brightness_offset(u32 offset); +void __s5p_vp_init_csc_control(bool suy_offset_en, bool csc_en); +enum s5p_tv_vp_err __s5p_vp_init_csc_coef_default( + enum s5p_vp_csc_type csc_type); +enum s5p_tv_vp_err __s5p_vp_start(void); +enum s5p_tv_vp_err __s5p_vp_stop(void); +void __s5p_vp_sw_reset(void); + +#ifdef CONFIG_CPU_S5PC100 +void __s5p_tv_clk_init_hpll(u32 lock_time, u32 mdiv, u32 pdiv, u32 sdiv); +#endif + +#ifdef CONFIG_CPU_S5PV210 +int __s5p_tv_clk_change_internal(void); +#endif + +void __s5p_tv_clk_hpll_onoff(bool en); +#ifdef CONFIG_CPU_S5PC100 +enum s5p_tv_clk_err __s5p_tv_clk_init_href( + enum s5p_tv_clk_hpll_ref hpll_ref); +enum s5p_tv_clk_err __s5p_tv_clk_init_mout_hpll( + enum s5p_tv_clk_mout_hpll mout_hpll); +enum s5p_tv_clk_err __s5p_tv_clk_init_video_mixer( + enum s5p_tv_clk_vmiexr_srcclk src_clk); +#endif +void __s5p_tv_clk_init_hdmi_ratio(u32 clk_div); +void __s5p_tv_clk_set_vp_clk_onoff(bool clk_on); +void __s5p_tv_clk_set_vmixer_hclk_onoff(bool clk_on); +void __s5p_tv_clk_set_vmixer_sclk_onoff(bool clk_on); +void __s5p_tv_clk_set_sdout_hclk_onoff(bool clk_on); +void __s5p_tv_clk_set_sdout_sclk_onoff(bool clk_on); +void __s5p_tv_clk_set_hdmi_hclk_onoff(bool clk_on); +void __s5p_tv_clk_set_hdmi_sclk_onoff(bool clk_on); +void __s5p_tv_clk_set_hdmi_i2c_clk_onoff(bool clk_on); +void __s5p_tv_clk_start(bool vp_hclk_on, bool sdout_hclk_on, + bool hdmi_hclk_on); +void __s5p_tv_clk_stop(void); + +void __s5p_tv_power_init_mtc_stable_counter(u32 value); +void __s5p_tv_powerinitialize_dac_onoff(bool on); +void __s5p_tv_powerset_dac_onoff(bool on); +bool __s5p_tv_power_get_power_status(void); +bool __s5p_tv_power_get_dac_power_status(void); +void __s5p_tv_poweron(void); +void __s5p_tv_poweroff(void); + +extern struct s5p_tv_status s5ptv_status; +extern struct s5p_tv_vo s5ptv_overlay[2]; + +#ifdef CONFIG_CPU_S5PV210 +extern void s5p_hdmi_enable_interrupts(enum s5p_tv_hdmi_interrrupt intr); +extern void s5p_hdmi_disable_interrupts(enum s5p_tv_hdmi_interrrupt intr); +extern void s5p_hdmi_clear_pending(enum s5p_tv_hdmi_interrrupt intr); +extern u8 s5p_hdmi_get_interrupts(void); +extern int s5p_hdmi_register_isr(hdmi_isr isr, u8 irq_num); +extern int s5p_hpd_init(void); +extern u8 s5p_hdmi_get_swhpd_status(void); +extern u8 s5p_hdmi_get_hpd_status(void); +extern void s5p_hdmi_swhpd_disable(void); +extern void s5p_hdmi_hpd_gen(void); +extern int __init __s5p_hdcp_init(void); +extern int s5p_tv_clk_gate(bool on); +#endif + +extern int s5ptvfb_init_fbinfo(int id); +extern int s5ptvfb_map_video_memory(struct fb_info *fb); +extern int s5ptvfb_check_var(struct fb_var_screeninfo *var, + struct fb_info *fb); +extern int s5ptvfb_set_par(struct fb_info *fb); +extern int s5ptvfb_draw_logo(struct fb_info *fb); +extern void s5ptvfb_set_lcd_info(struct s5p_tv_status *ctrl); +extern int s5ptvfb_display_on(struct s5p_tv_status *ctrl); +extern int s5p_hpd_get_state(void); +extern void s5p_handle_cable(void); + +#define S5PTVFB_POWER_OFF _IOW('F', 217, u32) +#define S5PTVFB_POWER_ON _IOW('F', 218, u32) +#define S5PTVFB_WIN_SET_ADDR _IOW('F', 219, u32) +#define S5PTVFB_SET_WIN_ON _IOW('F', 220, u32) +#define S5PTVFB_SET_WIN_OFF _IOW('F', 221, u32) + +extern int s5p_tv_clk_gate(bool on); +extern int s5p_hdcp_is_reset(void); +extern int tv_phy_power(bool on); +extern int s5ptvfb_unmap_video_memory(struct fb_info *fb); + +extern struct s5p_tv_status s5ptv_status; +extern bool _s5p_tv_if_set_disp(void); +extern int s5p_hdcp_encrypt_stop(bool on); +extern int s5p_hdmi_set_dvi(bool en); +extern int s5p_hdmi_set_mute(bool en); +extern int s5p_hdmi_get_mute(void); +extern int s5p_hdmi_audio_enable(bool en); +extern void s5p_hdmi_set_audio(bool en); +extern void s5p_hdmi_mute_en(bool en); +extern bool __s5p_start_hdcp(void); +extern bool __s5p_stop_hdcp(void); + +#if defined(CONFIG_MACH_P1) +extern struct i2c_driver SII9234_i2c_driver; +extern struct i2c_driver SII9234A_i2c_driver; +extern struct i2c_driver SII9234B_i2c_driver; +extern struct i2c_driver SII9234C_i2c_driver; +#endif + diff --git a/drivers/media/video/samsung/tv20/s5p_tv_base.c b/drivers/media/video/samsung/tv20/s5p_tv_base.c new file mode 100644 index 0000000..89543d2 --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5p_tv_base.c @@ -0,0 +1,1431 @@ +/* linux/drivers/media/video/samsung/tv20/s5p_tv_base.c + * + * Entry file for Samsung TVOut driver + * + * Copyright (c) 2010 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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/init.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/fs.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/interrupt.h> +#include <linux/miscdevice.h> +#include <linux/platform_device.h> +#include <linux/workqueue.h> +#include <linux/wait.h> +#include <linux/ioctl.h> +#include <linux/device.h> +#include <linux/clk.h> +#include <linux/i2c.h> +#include <linux/delay.h> +#include <linux/irq.h> +#include <linux/io.h> +#include <linux/uaccess.h> +#include <linux/regulator/consumer.h> + +#include <media/v4l2-common.h> +#include <media/v4l2-ioctl.h> +#include <mach/map.h> + +#include <mach/gpio.h> +#include <plat/gpio-cfg.h> +#include <mach/regs-gpio.h> +/*#include <mach/max8998_function.h>*/ +#include <linux/earlysuspend.h> +#ifdef CONFIG_CPU_FREQ_S5PV210 +#include <mach/cpu-freq-v210.h> +#endif /* CONFIG_CPU_FREQ_S5PV210 */ + +#ifdef CONFIG_S5PV210_PM_LEGACY +#include <mach/pd.h> +#endif + +#include "s5p_tv.h" + +#ifdef COFIG_TVOUT_DBG +#define S5P_TV_BASE_DEBUG 1 +#endif + +#ifdef S5P_TV_BASE_DEBUG +#define BASEPRINTK(fmt, args...) \ + printk(KERN_INFO "[TVBASE] %s: " fmt, __func__ , ## args) +#else +#define BASEPRINTK(fmt, args...) +#endif + +#ifdef CONFIG_CPU_S5PV210 +#define TVOUT_CLK_INIT(dev, clk, name) +#else +#define TVOUT_CLK_INIT(dev, clk, name) \ + do { \ + clk = clk_get(dev, name); \ + if (clk == NULL) { \ + printk(KERN_ERR \ + "failed to find %s clock source\n", name); \ + return -ENOENT; \ + } \ + clk_enable(clk) \ + } while (0); +#endif + +#define TVOUT_IRQ_INIT(x, ret, dev, num, jump, ftn, m_name) \ + do { \ + x = platform_get_irq(dev, num); \ + if (x < 0) { \ + printk(KERN_ERR \ + "failed to get %s irq resource\n", m_name); \ + ret = -ENOENT; \ + goto jump; \ + } \ + ret = request_irq(x, ftn, IRQF_DISABLED, \ + dev->name, dev); \ + if (ret != 0) { \ + printk(KERN_ERR \ + "failed to install %s irq (%d)\n", m_name, ret);\ + goto jump; \ + } \ + } while (0); + + +#ifdef CONFIG_CPU_S5PC100 +#define I2C_BASE +#endif + +static struct mutex *mutex_for_fo; + + +struct s5p_tv_status s5ptv_status; +struct s5p_tv_vo s5ptv_overlay[2]; + +#ifdef I2C_BASE +static struct mutex *mutex_for_i2c; +static struct work_struct ws_hpd; +spinlock_t slock_hpd; + +static struct i2c_driver hdcp_i2c_driver; +static bool hdcp_i2c_drv_state; + +const static u16 ignore[] = { I2C_CLIENT_END }; +const static u16 normal_addr[] = {(S5P_HDCP_I2C_ADDR >> 1), I2C_CLIENT_END }; +const static u16 *forces[] = { NULL }; + +static struct i2c_client_address_data addr_data = { + .normal_i2c = normal_addr, + .probe = ignore, + .ignore = ignore, + .forces = forces, +}; + +/* + * i2c client drv. - register client drv + */ +static int hdcp_i2c_attach(struct i2c_adapter *adap, int addr, int kind) +{ + + struct i2c_client *c; + + c = kzalloc(sizeof(*c), GFP_KERNEL); + + if (!c) + return -ENOMEM; + + strcpy(c->name, "s5p_ddc_client"); + + c->addr = addr; + + c->adapter = adap; + + c->driver = &hdcp_i2c_driver; + + s5ptv_status.hdcp_i2c_client = c; + + dev_info(&adap->dev, "s5p_ddc_client attached " + "into s5p_ddc_port successfully\n"); + + return i2c_attach_client(c); +} + +static int hdcp_i2c_attach_adapter(struct i2c_adapter *adap) +{ + int ret = 0; + + ret = i2c_probe(adap, &addr_data, hdcp_i2c_attach); + + if (ret) { + dev_err(&adap->dev, + "failed to attach s5p_hdcp_port driver\n"); + ret = -ENODEV; + } + + return ret; +} + +static int hdcp_i2c_detach(struct i2c_client *client) +{ + dev_info(&client->adapter->dev, "s5p_ddc_client detached " + "from s5p_ddc_port successfully\n"); + + i2c_detach_client(client); + + return 0; +} + +static struct i2c_driver hdcp_i2c_driver = { + .driver = { + .name = "s5p_ddc_port", + }, + .id = I2C_DRIVERID_S5P_HDCP, + .attach_adapter = hdcp_i2c_attach_adapter, + .detach_client = hdcp_i2c_detach, +}; + +static void set_ddc_port(void) +{ + mutex_lock(mutex_for_i2c); + + if (s5ptv_status.hpd_status) { + + if (!hdcp_i2c_drv_state) + /* cable : plugged, drv : unregistered */ + if (i2c_add_driver(&hdcp_i2c_driver)) + printk(KERN_ERR "HDCP port add failed\n"); + + /* changed drv. status */ + hdcp_i2c_drv_state = true; + + + /* cable inserted -> removed */ + __s5p_set_hpd_detection(true, s5ptv_status.hdcp_en, + s5ptv_status.hdcp_i2c_client); + + } else { + + if (hdcp_i2c_drv_state) + /* cable : unplugged, drv : registered */ + i2c_del_driver(&hdcp_i2c_driver); + + /* changed drv. status */ + hdcp_i2c_drv_state = false; + + /* cable removed -> inserted */ + __s5p_set_hpd_detection(false, s5ptv_status.hdcp_en, + s5ptv_status.hdcp_i2c_client); + printk(KERN_INFO "%s cable removed\n", __func__); + } + + mutex_unlock(mutex_for_i2c); +} +#endif + +#ifdef CONFIG_CPU_S5PC100 +static irqreturn_t __s5p_hpd_irq(int irq, void *dev_id) +{ + + spin_lock_irq(&slock_hpd); + + s5ptv_status.hpd_status = gpio_get_value(S5PC1XX_GPH0(5)) + ? false : true; + + if (s5ptv_status.hpd_status) + set_irq_type(IRQ_EINT5, IRQ_TYPE_EDGE_RISING); + else + set_irq_type(IRQ_EINT5, IRQ_TYPE_EDGE_FALLING); + + + if (s5ptv_status.hdcp_en) + schedule_work(&ws_hpd); + + spin_unlock_irq(&slock_hpd); + + BASEPRINTK("hpd_status = %d\n", s5ptv_status.hpd_status); + + return IRQ_HANDLED; +} +#endif + +#ifdef CONFIG_CPU_S5PV210 +int tv_phy_power(bool on) +{ + if (on) { + __s5p_tv_poweron(); + /* on */ + clk_enable(s5ptv_status.i2c_phy_clk); + __s5p_hdmi_phy_power(true); + + } else { + /* + * for preventing hdmi hang up when restart + * switch to internal clk - SCLK_DAC, SCLK_PIXEL + */ + clk_set_parent(s5ptv_status.sclk_mixer, + s5ptv_status.sclk_dac); + clk_set_parent(s5ptv_status.sclk_hdmi, + s5ptv_status.sclk_pixel); + + __s5p_hdmi_phy_power(false); + clk_disable(s5ptv_status.i2c_phy_clk); + __s5p_tv_poweroff(); + } + + return 0; +} + + +int s5p_tv_clk_gate(bool on) +{ + if (on) { +#ifdef CONFIG_S5PV210_PM_LEGACY + if (s5pv210_pd_enable("vp_pd") < 0) { + printk(KERN_ERR "[Error]The power is not on for VP\n"); + goto err_pm; + } +#endif + clk_enable(s5ptv_status.vp_clk); + +#ifdef CONFIG_S5PV210_PM_LEGACY + if (s5pv210_pd_enable("mixer_pd") < 0) { + printk(KERN_ERR "[Error]The power is not on for mixer\n"); + goto err_pm; + } +#endif + clk_enable(s5ptv_status.mixer_clk); + +#ifdef CONFIG_S5PV210_PM_LEGACY + if (s5pv210_pd_enable("tv_enc_pd") < 0) { + printk(KERN_ERR "[Error]The power is not on for TV ENC\n"); + goto err_pm; + } +#endif + clk_enable(s5ptv_status.tvenc_clk); + +#ifdef CONFIG_S5PV210_PM_LEGACY + if (s5pv210_pd_enable("hdmi_pd") < 0) { + printk(KERN_ERR "[Error]The power is not on for HDMI\n"); + goto err_pm; + } +#endif + clk_enable(s5ptv_status.hdmi_clk); + } else { + + /* off */ + clk_disable(s5ptv_status.vp_clk); +#ifdef CONFIG_S5PV210_PM_LEGACY + if (s5pv210_pd_disable("vp_pd") < 0) { + printk(KERN_ERR "[Error]The power is not off for VP\n"); + goto err_pm; + } +#endif + clk_disable(s5ptv_status.mixer_clk); +#ifdef CONFIG_S5PV210_PM_LEGACY + if (0 != s5pv210_pd_disable("mixer_pd")) { + printk(KERN_ERR "[Error]The power is not off for mixer\n"); + goto err_pm; + } +#endif + clk_disable(s5ptv_status.tvenc_clk); +#ifdef CONFIG_S5PV210_PM_LEGACY + if (s5pv210_pd_disable("tv_enc_pd") < 0) { + printk(KERN_ERR "[Error]The power is not off for TV ENC\n"); + goto err_pm; + } +#endif + clk_disable(s5ptv_status.hdmi_clk); +#ifdef CONFIG_S5PV210_PM_LEGACY + if (s5pv210_pd_disable("hdmi_pd") < 0) { + printk(KERN_ERR "[Error]The power is not off for HDMI\n"); + goto err_pm; + } +#endif + } + + return 0; +#ifdef CONFIG_S5PV210_PM_LEGACY +err_pm: + return -1; +#endif +} +EXPORT_SYMBOL(s5p_tv_clk_gate); + +#define TV_CLK_GET_WITH_ERR_CHECK(clk, pdev, clk_name) \ + do { \ + clk = clk_get(&pdev->dev, clk_name); \ + if (IS_ERR(clk)) { \ + printk(KERN_ERR \ + "failed to find clock \"%s\"\n", clk_name); \ + return ENOENT; \ + } \ + } while (0); + +static int __devinit tv_clk_get(struct platform_device *pdev, + struct s5p_tv_status *ctrl) +{ + struct clk *ext_xtal_clk, + *mout_vpll_src, + *fout_vpll, + *mout_vpll; + + TV_CLK_GET_WITH_ERR_CHECK(ctrl->tvenc_clk, pdev, "tvenc"); + TV_CLK_GET_WITH_ERR_CHECK(ctrl->vp_clk, pdev, "vp"); + TV_CLK_GET_WITH_ERR_CHECK(ctrl->mixer_clk, pdev, "mixer"); + TV_CLK_GET_WITH_ERR_CHECK(ctrl->hdmi_clk, pdev, "hdmi"); + TV_CLK_GET_WITH_ERR_CHECK(ctrl->i2c_phy_clk, pdev, "i2c-hdmiphy"); + + TV_CLK_GET_WITH_ERR_CHECK(ctrl->sclk_dac, pdev, "sclk_dac"); + TV_CLK_GET_WITH_ERR_CHECK(ctrl->sclk_mixer, pdev, "sclk_mixer"); + TV_CLK_GET_WITH_ERR_CHECK(ctrl->sclk_hdmi, pdev, "sclk_hdmi"); + + TV_CLK_GET_WITH_ERR_CHECK(ctrl->sclk_pixel, pdev, "sclk_pixel"); + TV_CLK_GET_WITH_ERR_CHECK(ctrl->sclk_hdmiphy, pdev, "sclk_hdmiphy"); + + TV_CLK_GET_WITH_ERR_CHECK(ext_xtal_clk, pdev, "ext_xtal"); + TV_CLK_GET_WITH_ERR_CHECK(mout_vpll_src, pdev, "mout_vpll_src"); + TV_CLK_GET_WITH_ERR_CHECK(fout_vpll, pdev, "fout_vpll"); + TV_CLK_GET_WITH_ERR_CHECK(mout_vpll, pdev, "mout_vpll"); + + clk_set_parent(mout_vpll_src, ext_xtal_clk); + clk_set_parent(mout_vpll, fout_vpll); + + /* sclk_dac's parent is fixed as mout_vpll */ + clk_set_parent(ctrl->sclk_dac, mout_vpll); + + clk_set_rate(fout_vpll, 54000000); + clk_set_rate(ctrl->sclk_pixel, 54000000); + + clk_enable(ctrl->sclk_dac); + clk_enable(ctrl->sclk_mixer); + clk_enable(ctrl->sclk_hdmi); + + clk_enable(mout_vpll_src); + clk_enable(fout_vpll); + clk_enable(mout_vpll); + + clk_put(ext_xtal_clk); + clk_put(mout_vpll_src); + clk_put(fout_vpll); + clk_put(mout_vpll); + + return 0; +} +#else +#define s5p_tv_clk_gate NULL +#define tv_phy_power NULL +#define tv_clk_get NULL +#endif + +/* + * ftn for irq + */ +static irqreturn_t s5p_tvenc_irq(int irq, void *dev_id) +{ + return IRQ_HANDLED; +} + +#ifdef CONFIG_TV_FB +static int s5p_tv_open(struct file *file) +{ + return 0; +} + +static int s5p_tv_release(struct file *file) +{ + s5ptv_status.hdcp_en = false; + return 0; +} + +static int s5p_tv_vid_open(struct file *file) +{ + int ret = 0; + + mutex_lock(mutex_for_fo); + + if (s5ptv_status.vp_layer_enable) { + printk(KERN_ERR "video layer. already used !!\n"); + ret = -EBUSY; + } + + mutex_unlock(mutex_for_fo); + return ret; +} + +static int s5p_tv_vid_release(struct file *file) +{ + s5ptv_status.vp_layer_enable = false; + + _s5p_vlayer_stop(); + + return 0; +} +#else + +/* + * ftn for video + */ +static int s5p_tv_v_open(struct file *file) +{ + int ret = 0; + + printk(KERN_INFO "%s", __func__); + mutex_lock(mutex_for_fo); + + if (s5ptv_status.tvout_output_enable) { + BASEPRINTK("tvout drv. already used !!\n"); + ret = -EBUSY; + goto drv_used; + } + + s5p_tv_clk_gate(true); + tv_phy_power(true); + +#ifdef CONFIG_CPU_S5PV210 +#ifdef CONFIG_PM + if ((s5ptv_status.hpd_status) && !(s5ptv_status.suspend_status)) { + BASEPRINTK("tv is turned on\n"); +#endif +#ifdef CONFIG_CPU_FREQ_S5PV210 + if ((s5ptv_status.hpd_status)) + s5pv210_set_cpufreq_level(RESTRICT_TABLE); +#endif /* CONFIG_CPU_FREQ_S5PV210 */ +// s5p_tv_clk_gate(true); +/* + if ((s5ptv_status.tvout_param.out_mode == TVOUT_OUTPUT_HDMI)\ + || \ + (s5ptv_status.tvout_param.out_mode == TVOUT_OUTPUT_HDMI_RGB)) +*/ +// tv_phy_power(true); +#ifdef CONFIG_PM + } else + BASEPRINTK("tv is off\n"); +#endif +#endif + _s5p_tv_if_init_param(); + + s5p_tv_v4l2_init_param(); + + mutex_unlock(mutex_for_fo); + +#ifdef I2C_BASE + mutex_lock(mutex_for_i2c); + /* for ddc(hdcp port) */ + if (s5ptv_status.hpd_status) { + if (i2c_add_driver(&hdcp_i2c_driver)) + BASEPRINTK("HDCP port add failed\n"); + hdcp_i2c_drv_state = true; + } else + hdcp_i2c_drv_state = false; + + mutex_unlock(mutex_for_i2c); + /* for i2c probing */ + udelay(100); +#endif + + return 0; + +drv_used: + mutex_unlock(mutex_for_fo); + return ret; +} + +int s5p_tv_v_read(struct file *filp, char *buf, size_t count, + loff_t *f_pos) +{ + return 0; +} + +int s5p_tv_v_write(struct file *filp, const char *buf, size_t + count, loff_t *f_pos) +{ + return 0; +} + +int s5p_tv_v_mmap(struct file *filp, struct vm_area_struct *vma) +{ + return 0; +} + +int s5p_tv_v_release(struct file *filp) +{ + printk(KERN_INFO "%s", __func__); + +#if defined(CONFIG_CPU_S5PV210) && defined(CONFIG_PM) + if ((s5ptv_status.hpd_status) && !(s5ptv_status.suspend_status)) { +#endif + if (s5ptv_status.vp_layer_enable) + _s5p_vlayer_stop(); + if (s5ptv_status.tvout_output_enable) + _s5p_tv_if_stop(); +#if defined(CONFIG_CPU_S5PV210) && defined(CONFIG_PM) + } else + s5ptv_status.vp_layer_enable = false; +#endif + s5ptv_status.hdcp_en = false; + + s5ptv_status.tvout_output_enable = false; + + /* + * drv. release + * - just check drv. state reg. or not. + */ +#ifdef I2C_BASE + mutex_lock(mutex_for_i2c); + + if (hdcp_i2c_drv_state) { + i2c_del_driver(&hdcp_i2c_driver); + hdcp_i2c_drv_state = false; + } + + mutex_unlock(mutex_for_i2c); +#endif + +#ifdef CONFIG_CPU_S5PV210 +#ifdef CONFIG_PM + if ((s5ptv_status.hpd_status) && !(s5ptv_status.suspend_status)) { +#endif +// s5p_tv_clk_gate(false); +/* if (s5ptv_status.tvout_param.out_mode == TVOUT_OUTPUT_HDMI || \ + s5ptv_status.tvout_param.out_mode == TVOUT_OUTPUT_HDMI_RGB) +*/ +// tv_phy_power(false); +#ifdef CONFIG_CPU_FREQ_S5PV210 + if (s5ptv_status.hpd_status) + s5pv210_set_cpufreq_level(NORMAL_TABLE); +#endif /* CONFIG_CPU_FREQ_S5PV210 */ + +#ifdef CONFIG_PM + } +#endif +#endif + + s5p_tv_clk_gate(false); + tv_phy_power(false); + + return 0; +} + +static int vo_open(int layer, struct file *file) +{ + int ret = 0; + + mutex_lock(mutex_for_fo); + + /* check tvout path available!! */ + if (!s5ptv_status.tvout_output_enable) { + BASEPRINTK("check tvout start !!\n"); + ret = -EACCES; + goto resource_busy; + } + + if (s5ptv_status.grp_layer_enable[layer]) { + BASEPRINTK("grp %d layer is busy!!\n", layer); + ret = -EBUSY; + goto resource_busy; + } + + /* set layer info.!! */ + s5ptv_overlay[layer].index = layer; + + /* set file private data.!! */ + file->private_data = &s5ptv_overlay[layer]; + + mutex_unlock(mutex_for_fo); + + return 0; + +resource_busy: + mutex_unlock(mutex_for_fo); + + return ret; +} + +int vo_release(int layer, struct file *filp) +{ + _s5p_grp_stop(layer); + + return 0; +} + +/* modified for 2.6.29 v4l2-dev.c */ +static int s5p_tv_vo0_open(struct file *file) +{ + vo_open(0, file); + return 0; +} + +static int s5p_tv_vo0_release(struct file *file) +{ + vo_release(0, file); + return 0; +} + +static int s5p_tv_vo1_open(struct file *file) +{ + vo_open(1, file); + return 0; +} + +static int s5p_tv_vo1_release(struct file *file) +{ + vo_release(1, file); + return 0; +} +#endif + +#ifdef CONFIG_TV_FB +static int s5ptvfb_alloc_framebuffer(void) +{ + int ret; + + /* alloc for each framebuffer */ + s5ptv_status.fb = framebuffer_alloc(sizeof(struct s5ptvfb_window), + s5ptv_status.dev_fb); + if (!s5ptv_status.fb) { + dev_err(s5ptv_status.dev_fb, "not enough memory\n"); + ret = -ENOMEM; + goto err_alloc_fb; + } + + ret = s5ptvfb_init_fbinfo(5); + if (ret) { + dev_err(s5ptv_status.dev_fb, + "failed to allocate memory for fb for tv\n"); + ret = -ENOMEM; + goto err_alloc_fb; + } +#ifndef CONFIG_USER_ALLOC_TVOUT + if (s5ptvfb_map_video_memory(s5ptv_status.fb)) { + dev_err(s5ptv_status.dev_fb, + "failed to map video memory " + "for default window \n"); + ret = -ENOMEM; + goto err_alloc_fb; + } +#endif + return 0; + +err_alloc_fb: + if (s5ptv_status.fb) + framebuffer_release(s5ptv_status.fb); + + kfree(s5ptv_status.fb); + + return ret; +} + +int s5ptvfb_free_framebuffer(void) +{ +#ifndef CONFIG_USER_ALLOC_TVOUT + if (s5ptv_status.fb) + s5ptvfb_unmap_video_memory(s5ptv_status.fb); +#endif + + if (s5ptv_status.fb) + framebuffer_release(s5ptv_status.fb); + + return 0; +} + +int s5ptvfb_register_framebuffer(void) +{ + int ret; + + ret = register_framebuffer(s5ptv_status.fb); + if (ret) { + dev_err(s5ptv_status.dev_fb, "failed to register " + "framebuffer device\n"); + return -EINVAL; + } +#ifndef CONFIG_FRAMEBUFFER_CONSOLE +#ifndef CONFIG_USER_ALLOC_TVOUT + s5ptvfb_check_var(&s5ptv_status.fb->var, s5ptv_status.fb); + s5ptvfb_set_par(s5ptv_status.fb); + s5ptvfb_draw_logo(s5ptv_status.fb); +#endif +#endif + + return 0; +} +#endif + +/* + * struct for video + */ +#ifdef CONFIG_TV_FB +static struct v4l2_file_operations s5p_tv_fops = { + .owner = THIS_MODULE, + .open = s5p_tv_open, + .ioctl = s5p_tv_ioctl, + .release = s5p_tv_release +}; +static struct v4l2_file_operations s5p_tv_vid_fops = { + .owner = THIS_MODULE, + .open = s5p_tv_vid_open, + .ioctl = s5p_tv_vid_ioctl, + .release = s5p_tv_vid_release +}; + #else +static struct v4l2_file_operations s5p_tv_v_fops = { + .owner = THIS_MODULE, + .open = s5p_tv_v_open, + .read = s5p_tv_v_read, + .write = s5p_tv_v_write, + .ioctl = s5p_tv_v_ioctl, + .mmap = s5p_tv_v_mmap, + .release = s5p_tv_v_release +}; + +/* + * struct for graphic0 + */ +static struct v4l2_file_operations s5p_tv_vo0_fops = { + .owner = THIS_MODULE, + .open = s5p_tv_vo0_open, + .ioctl = s5p_tv_vo_ioctl, + .release = s5p_tv_vo0_release +}; + +/* + * struct for graphic1 + */ +static struct v4l2_file_operations s5p_tv_vo1_fops = { + .owner = THIS_MODULE, + .open = s5p_tv_vo1_open, + .ioctl = s5p_tv_vo_ioctl, + .release = s5p_tv_vo1_release +}; +#endif + +void s5p_tv_vdev_release(struct video_device *vdev) +{ + kfree(vdev); +} + +struct video_device s5p_tvout[] = { + +#ifdef CONFIG_TV_FB + [0] = { + .name = "S5PC1xx TVOUT ctrl", + .fops = &s5p_tv_fops, + .ioctl_ops = &s5p_tv_v4l2_ops, + .release = s5p_tv_vdev_release, + .minor = TVOUT_MINOR_TVOUT, + .tvnorms = V4L2_STD_ALL_HD, + }, + [1] = { + .name = "S5PC1xx TVOUT for Video", + .fops = &s5p_tv_vid_fops, + .ioctl_ops = &s5p_tv_v4l2_vid_ops, + .release = s5p_tv_vdev_release, + .minor = TVOUT_MINOR_VID, + .tvnorms = V4L2_STD_ALL_HD, + }, +#else + [0] = { + .name = "S5PC1xx TVOUT Video", + .fops = &s5p_tv_v_fops, + .ioctl_ops = &s5p_tv_v4l2_v_ops, + .release = s5p_tv_vdev_release, + .minor = TVOUT_MINOR_VIDEO, + .tvnorms = V4L2_STD_ALL_HD, + }, + [1] = { + .name = "S5PC1xx TVOUT Overlay0", + .fops = &s5p_tv_vo0_fops, + .ioctl_ops = &s5p_tv_v4l2_vo_ops, + .release = s5p_tv_vdev_release, + .minor = TVOUT_MINOR_GRP0, + .tvnorms = V4L2_STD_ALL_HD, + }, + [2] = { + .name = "S5PC1xx TVOUT Overlay1", + .fops = &s5p_tv_vo1_fops, + .ioctl_ops = &s5p_tv_v4l2_vo_ops, + .release = s5p_tv_vdev_release, + .minor = TVOUT_MINOR_GRP1, + .tvnorms = V4L2_STD_ALL_HD, + }, +#endif +}; + +void s5p_handle_cable(void) +{ + char env_buf[120]; + char *envp[2]; + int env_offset = 0; + + printk(KERN_INFO "%s....start", __func__); + + if ((s5ptv_status.tvout_param.out_mode != TVOUT_OUTPUT_HDMI) && \ + (s5ptv_status.tvout_param.out_mode != TVOUT_OUTPUT_HDMI_RGB) && \ + (s5ptv_status.tvout_param.out_mode != TVOUT_OUTPUT_DVI)) + return; + + bool previous_hpd_status = s5ptv_status.hpd_status; +#ifdef CONFIG_HDMI_HPD + s5ptv_status.hpd_status = s5p_hpd_get_state(); +#else + return; +#endif + + memset(env_buf, 0, sizeof(env_buf)); + + if (previous_hpd_status == s5ptv_status.hpd_status) { + BASEPRINTK("same hpd_status value: %d\n", previous_hpd_status); + return; + } + + if (s5ptv_status.hpd_status) { + BASEPRINTK("\n hdmi cable is connected \n"); + + if (s5ptv_status.suspend_status) + return; + +#ifdef CONFIG_CPU_FREQ_S5PV210 + s5pv210_set_cpufreq_level(RESTRICT_TABLE); +#endif /* CONFIG_CPU_FREQ_S5PV210 */ + +#ifdef CONFIG_PM + s5p_tv_clk_gate(true); +/* + if ((s5ptv_status.tvout_param.out_mode == TVOUT_OUTPUT_HDMI)\ + || (s5ptv_status.tvout_param.out_mode == TVOUT_OUTPUT_HDMI_RGB)) +*/ + tv_phy_power(true); +#endif + /* tv on */ + if (s5ptv_status.tvout_output_enable) + _s5p_tv_if_start(); + + /* video layer start */ + if (s5ptv_status.vp_layer_enable) + _s5p_vlayer_start(); + + /* grp0 layer start */ + if (s5ptv_status.grp_layer_enable[0]) + _s5p_grp_start(VM_GPR0_LAYER); + + /* grp1 layer start */ + if (s5ptv_status.grp_layer_enable[1]) + _s5p_grp_start(VM_GPR1_LAYER); + + sprintf(env_buf, "HDMI_STATE=online"); + envp[env_offset++] = env_buf; + envp[env_offset] = NULL; + kobject_uevent_env(&(s5p_tvout[0].dev.kobj), KOBJ_CHANGE, envp); + + } else { + BASEPRINTK("\n hdmi cable is disconnected \n"); + + if (s5ptv_status.suspend_status) + return; + + if (s5ptv_status.vp_layer_enable) { + _s5p_vlayer_stop(); + s5ptv_status.vp_layer_enable = true; + + } + + /* grp0 layer stop */ + if (s5ptv_status.grp_layer_enable[0]) { + _s5p_grp_stop(VM_GPR0_LAYER); + s5ptv_status.grp_layer_enable[VM_GPR0_LAYER] = true; + } + + /* grp1 layer stop */ + if (s5ptv_status.grp_layer_enable[1]) { + _s5p_grp_stop(VM_GPR1_LAYER); + s5ptv_status.grp_layer_enable[VM_GPR0_LAYER] = true; + } + + /* tv off */ + if (s5ptv_status.tvout_output_enable) { + _s5p_tv_if_stop(); + s5ptv_status.tvout_output_enable = true; + s5ptv_status.tvout_param_available = true; + } + +#ifdef CONFIG_PM + /* clk & power off */ + s5p_tv_clk_gate(false); +/* + if ((s5ptv_status.tvout_param.out_mode == TVOUT_OUTPUT_HDMI) ||\ + (s5ptv_status.tvout_param.out_mode == TVOUT_OUTPUT_HDMI_RGB)) +*/ + tv_phy_power(false); +#endif + + sprintf(env_buf, "HDMI_STATE=offline"); + envp[env_offset++] = env_buf; + envp[env_offset] = NULL; + kobject_uevent_env(&(s5p_tvout[0].dev.kobj), KOBJ_CHANGE, envp); + +#ifdef CONFIG_CPU_FREQ_S5PV210 + s5pv210_set_cpufreq_level(NORMAL_TABLE); +#endif /* CONFIG_CPU_FREQ_S5PV210 */ + } +} + +#define S5P_TVMAX_CTRLS ARRAY_SIZE(s5p_tvout) +/* + * Probe + */ + +static int __devinit s5p_tv_probe(struct platform_device *pdev) +{ + int irq_num; + int ret; + int i, retval; + + + /* Get csis power domain regulator */ + s5ptv_status.tv_regulator = regulator_get(&pdev->dev, "pd"); + if (IS_ERR(s5ptv_status.tv_regulator)) { + printk(KERN_ERR "%s %d: failed to get resource %s\n", + __func__, __LINE__, "s3c-tv20 pd"); + return PTR_ERR(s5ptv_status.tv_regulator); + } + + s5ptv_status.tv_tvout = regulator_get(NULL, "tvout"); + if (IS_ERR(s5ptv_status.tv_tvout)) { + printk(KERN_ERR "%s %d: failed to get resource %s\n", + __func__, __LINE__, "s3c-tv20 tvout"); + return PTR_ERR(s5ptv_status.tv_tvout); + } + +#ifdef CONFIG_MACH_P1 + s5ptv_status.tv_tv = regulator_get(NULL, "tv"); + if (IS_ERR(s5ptv_status.tv_tv)) { + printk(KERN_ERR "%s %d: failed to get resource %s\n", + __func__, __LINE__, "s3c-tv20 tv"); + return PTR_ERR(s5ptv_status.tv_tv); + } + regulator_enable(s5ptv_status.tv_tv); +#endif + s5ptv_status.dev_fb = &pdev->dev; + + __s5p_sdout_probe(pdev, 0); + __s5p_vp_probe(pdev, 1); + __s5p_mixer_probe(pdev, 2); + +#ifdef CONFIG_CPU_S5PC100 + __s5p_hdmi_probe(pdev, 3); + __s5p_tvclk_probe(pdev, 4); +#endif + +#ifdef CONFIG_CPU_S5PV210 + tv_clk_get(pdev, &s5ptv_status); + s5p_tv_clk_gate(true); + __s5p_hdmi_probe(pdev, 3, 4); + __s5p_hdcp_init(); +#endif +#if defined(CONFIG_MACH_P1) + retval = i2c_add_driver(&SII9234A_i2c_driver); + if (retval != 0) + printk(KERN_ERR "[MHL SII9234A] can't add i2c driver"); + + retval = i2c_add_driver(&SII9234B_i2c_driver); + if (retval != 0) + printk(KERN_ERR "[MHL SII9234B] can't add i2c driver"); + + retval = i2c_add_driver(&SII9234C_i2c_driver); + if (retval != 0) + printk(KERN_ERR "[MHL SII9234C] can't add i2c driver"); + + retval = i2c_add_driver(&SII9234_i2c_driver); + if (retval != 0) + printk(KERN_ERR "[MHL SII9234] can't add i2c driver"); +#endif + +#ifdef FIX_27M_UNSTABLE_ISSUE /* for smdkc100 pop */ + writel(0x1, S5PC1XX_GPA0_BASE + 0x56c); +#endif + +#ifdef I2C_BASE + /* for dev_dbg err. */ + spin_lock_init(&slock_hpd); + + /* for bh */ + INIT_WORK(&ws_hpd, (void *)set_ddc_port); +#endif + /* check EINT init state */ +#ifdef CONFIG_CPU_S5PC100 + s3c_gpio_cfgpin(S5PC1XX_GPH0(5), S3C_GPIO_SFN(2)); + s3c_gpio_setpull(S5PC1XX_GPH0(5), S3C_GPIO_PULL_UP); + + s5ptv_status.hpd_status = gpio_get_value(S5PC1XX_GPH0(5)) ? \ + false : true; +#endif + +#ifdef CONFIG_CPU_S5PV210 +#ifdef CONFIG_HDMI_HPD + s5ptv_status.hpd_status = 0; +#else + s5ptv_status.hpd_status = 0; +#endif +#endif + dev_info(&pdev->dev, "hpd status: cable %s\n",\ + s5ptv_status.hpd_status ? "inserted":"removed/not connected"); + + /* Interrupt */ + TVOUT_IRQ_INIT(irq_num, ret, pdev, 0, out, __s5p_mixer_irq, "mixer"); + TVOUT_IRQ_INIT(irq_num, ret, pdev, 1, out_hdmi_irq, __s5p_hdmi_irq , \ + "hdmi"); + TVOUT_IRQ_INIT(irq_num, ret, pdev, 2, out_tvenc_irq, s5p_tvenc_irq, \ + "tvenc"); + +#ifdef CONFIG_CPU_S5PC100 + TVOUT_IRQ_INIT(irq_num, ret, pdev, 3, out_hpd_irq, __s5p_hpd_irq, \ + "hpd"); + set_irq_type(IRQ_EINT5, IRQ_TYPE_LEVEL_LOW); +#endif + /* v4l2 video device registration */ + for (i = 0; i < S5P_TVMAX_CTRLS; i++) { + s5ptv_status.video_dev[i] = &s5p_tvout[i]; + + if (video_register_device(s5ptv_status.video_dev[i], + VFL_TYPE_GRABBER, s5p_tvout[i].minor) != 0) { + + dev_err(&pdev->dev, + "Couldn't register tvout driver.\n"); + return 0; + } + } + +#ifdef CONFIG_TV_FB + mutex_init(&s5ptv_status.fb_lock); + + /* for default start up */ + _s5p_tv_if_init_param(); + + s5ptv_status.tvout_param.disp_mode = TVOUT_720P_60; + s5ptv_status.tvout_param.out_mode = TVOUT_OUTPUT_HDMI; + +#ifndef CONFIG_USER_ALLOC_TVOUT + s5p_tv_clk_gate(true); +/* + if ((s5ptv_status.tvout_param.out_mode == TVOUT_OUTPUT_HDMI) || + (s5ptv_status.tvout_param.out_mode == TVOUT_OUTPUT_HDMI_RGB)) +*/ + tv_phy_power(true); + _s5p_tv_if_set_disp(); +#endif + s5ptvfb_set_lcd_info(&s5ptv_status); + + /* prepare memory */ + if (s5ptvfb_alloc_framebuffer()) + goto err_alloc; + + if (s5ptvfb_register_framebuffer()) + goto err_alloc; +#ifndef CONFIG_USER_ALLOC_TVOUT + s5ptvfb_display_on(&s5ptv_status); +#endif +#endif + mutex_for_fo = kmalloc(sizeof(struct mutex), + GFP_KERNEL); + + if (mutex_for_fo == NULL) { + dev_err(&pdev->dev, + "failed to create mutex handle\n"); + goto out; + } +#ifdef I2C_BASE + mutex_for_i2c = kmalloc(sizeof(struct mutex), + GFP_KERNEL); + + if (mutex_for_i2c == NULL) { + dev_err(&pdev->dev, + "failed to create mutex handle\n"); + goto out; + } + mutex_init(mutex_for_i2c); +#endif + mutex_init(mutex_for_fo); + +#ifdef CONFIG_CPU_S5PV210 + /* added for phy cut off when boot up */ + clk_enable(s5ptv_status.i2c_phy_clk); + + __s5p_hdmi_phy_power(false); + clk_disable(s5ptv_status.i2c_phy_clk); + + s5p_tv_clk_gate(false); +#endif + printk(KERN_INFO "%s TV Probing is done\n", __func__); + return 0; + +#ifdef CONFIG_TV_FB +err_alloc: +#endif + +#ifdef CONFIG_CPU_S5PC100 +out_hpd_irq: + free_irq(IRQ_TVENC, pdev); +#endif + +out_tvenc_irq: + free_irq(IRQ_HDMI, pdev); + +out_hdmi_irq: + free_irq(IRQ_MIXER, pdev); + +out: + printk(KERN_ERR "not found (%d). \n", ret); + + return ret; +} + +/* + * Remove + */ +static int s5p_tv_remove(struct platform_device *pdev) +{ + __s5p_hdmi_release(pdev); + __s5p_sdout_release(pdev); + __s5p_mixer_release(pdev); + __s5p_vp_release(pdev); +#ifdef CONFIG_CPU_S5PC100 + __s5p_tvclk_release(pdev); +#endif +#ifdef I2C_BASE + i2c_del_driver(&hdcp_i2c_driver); +#endif +#if defined(CONFIG_MACH_P1) + i2c_del_driver(&SII9234A_i2c_driver); + i2c_del_driver(&SII9234B_i2c_driver); + i2c_del_driver(&SII9234C_i2c_driver); + i2c_del_driver(&SII9234_i2c_driver); +#endif + clk_disable(s5ptv_status.tvenc_clk); + clk_disable(s5ptv_status.vp_clk); + clk_disable(s5ptv_status.mixer_clk); + clk_disable(s5ptv_status.hdmi_clk); + clk_disable(s5ptv_status.sclk_hdmi); + clk_disable(s5ptv_status.sclk_mixer); + clk_disable(s5ptv_status.sclk_dac); + + clk_put(s5ptv_status.tvenc_clk); + clk_put(s5ptv_status.vp_clk); + clk_put(s5ptv_status.mixer_clk); + clk_put(s5ptv_status.hdmi_clk); + clk_put(s5ptv_status.sclk_hdmi); + clk_put(s5ptv_status.sclk_mixer); + clk_put(s5ptv_status.sclk_dac); + clk_put(s5ptv_status.sclk_pixel); + clk_put(s5ptv_status.sclk_hdmiphy); + + free_irq(IRQ_MIXER, pdev); + free_irq(IRQ_HDMI, pdev); + free_irq(IRQ_TVENC, pdev); +#ifdef CONFIG_CPU_S5PC100 + free_irq(IRQ_EINT5, pdev); +#endif + + regulator_disable(s5ptv_status.tv_regulator); + regulator_put(s5ptv_status.tv_regulator); + + regulator_disable(s5ptv_status.tv_tvout); + regulator_put(s5ptv_status.tv_tvout); +#ifdef CONFIG_MACH_P1 + regulator_disable(s5ptv_status.tv_tv); + regulator_put(s5ptv_status.tv_tv); +#endif + mutex_destroy(mutex_for_fo); +#ifdef I2C_BASE + mutex_destroy(mutex_for_i2c); +#endif + + return 0; +} + + +#ifdef CONFIG_PM +/* + * Suspend + */ +void s5p_tv_early_suspend(struct early_suspend *h) +{ + BASEPRINTK("%s----------------start \n", __func__); + + mutex_lock(mutex_for_fo); + s5ptv_status.suspend_status = true; + + if (!(s5ptv_status.hpd_status)) { + printk(KERN_INFO "(hpd_status = %d)++\n", \ + s5ptv_status.hpd_status); + mutex_unlock(mutex_for_fo); + return ; + } else { + /* video layer stop */ + if (s5ptv_status.vp_layer_enable) { + _s5p_vlayer_stop(); + s5ptv_status.vp_layer_enable = true; + } + + /* grp0 layer stop */ + if (s5ptv_status.grp_layer_enable[0]) { + _s5p_grp_stop(VM_GPR0_LAYER); + s5ptv_status.grp_layer_enable[VM_GPR0_LAYER] = true; + } + + /* grp1 layer stop */ + if (s5ptv_status.grp_layer_enable[1]) { + _s5p_grp_stop(VM_GPR1_LAYER); + s5ptv_status.grp_layer_enable[VM_GPR0_LAYER] = true; + } + + /* tv off */ + if (s5ptv_status.tvout_output_enable) { + _s5p_tv_if_stop(); + s5ptv_status.tvout_output_enable = true; + s5ptv_status.tvout_param_available = true; + } + + /* clk & power off */ + s5p_tv_clk_gate(false); + if ((s5ptv_status.tvout_param.out_mode == TVOUT_OUTPUT_HDMI) ||\ + (s5ptv_status.tvout_param.out_mode == TVOUT_OUTPUT_HDMI_RGB)) + tv_phy_power(false); + +#ifdef CONFIG_CPU_FREQ_S5PV210 + s5pv210_set_cpufreq_level(NORMAL_TABLE); +#endif /* CONFIG_CPU_FREQ_S5PV210 */ + } + + mutex_unlock(mutex_for_fo); + BASEPRINTK("()--\n"); + return ; +} + +/* + * Resume + */ +void s5p_tv_late_resume(struct early_suspend *h) +{ + BASEPRINTK("%s----------------start \n", __func__); + + mutex_lock(mutex_for_fo); + s5ptv_status.suspend_status = false; + + if (!(s5ptv_status.hpd_status)) { + printk(KERN_INFO "(hpd_status = %d)++\n", \ + s5ptv_status.hpd_status); + mutex_unlock(mutex_for_fo); + return ; + } else { +#ifdef CONFIG_CPU_FREQ_S5PV210 + s5pv210_set_cpufreq_level(RESTRICT_TABLE); +#endif /* CONFIG_CPU_FREQ_S5PV210 */ + + /* clk & power on */ + s5p_tv_clk_gate(true); + if ((s5ptv_status.tvout_param.out_mode == TVOUT_OUTPUT_HDMI) ||\ + (s5ptv_status.tvout_param.out_mode == TVOUT_OUTPUT_HDMI_RGB)) + tv_phy_power(true); + + /* tv on */ + if (s5ptv_status.tvout_output_enable) + _s5p_tv_if_start(); + + /* video layer start */ + if (s5ptv_status.vp_layer_enable) + _s5p_vlayer_start(); + + /* grp0 layer start */ + if (s5ptv_status.grp_layer_enable[0]) + _s5p_grp_start(VM_GPR0_LAYER); + + /* grp1 layer start */ + if (s5ptv_status.grp_layer_enable[1]) + _s5p_grp_start(VM_GPR1_LAYER); + +#ifdef CONFIG_TV_FB + if (s5ptv_status.tvout_output_enable) { + s5ptvfb_display_on(&s5ptv_status); + s5ptvfb_set_par(s5ptv_status.fb); + } +#endif + } + mutex_unlock(mutex_for_fo); + BASEPRINTK("()--\n"); + return ; +} +#else +#define s5p_tv_suspend NULL +#define s5p_tv_resume NULL +#endif + +#ifdef CONFIG_PM +#ifdef CONFIG_HAS_EARLYSUSPEND +static struct early_suspend s5p_tv_early_suspend_desc = { + .level = EARLY_SUSPEND_LEVEL_STOP_DRAWING, + .suspend = s5p_tv_early_suspend, + .resume = s5p_tv_late_resume, +}; +#endif +#endif + +static struct platform_driver s5p_tv_driver = { + .probe = s5p_tv_probe, + .remove = s5p_tv_remove, +#ifdef CONFIG_PM +#ifndef CONFIG_HAS_EARLYSUSPEND + .suspend = s5p_tv_early_suspend, + .resume = s5p_tv_late_resume, +#endif +#else + .suspend = NULL, + .resume = NULL, +#endif + .driver = { + .name = "s5p-tvout", + .owner = THIS_MODULE, + }, +}; + +static char banner[] __initdata = + KERN_INFO "S5P TVOUT Driver, (c) 2010 Samsung Electronics\n"; + +int __init s5p_tv_init(void) +{ + int ret; + + printk(banner); + + ret = platform_driver_register(&s5p_tv_driver); + + if (ret) { + printk(KERN_ERR "Platform Device Register Failed %d\n", ret); + return -1; + } + +#ifdef CONFIG_PM +#ifdef CONFIG_HAS_EARLYSUSPEND + register_early_suspend(&s5p_tv_early_suspend_desc); +#endif +#endif + return 0; +} + +static void __exit s5p_tv_exit(void) +{ +#ifdef CONFIG_PM +#ifdef CONFIG_HAS_EARLYSUSPEND + unregister_early_suspend(&s5p_tv_early_suspend_desc); +#endif +#endif + platform_driver_unregister(&s5p_tv_driver); +} + +late_initcall(s5p_tv_init); +module_exit(s5p_tv_exit); + +MODULE_AUTHOR("SangPil Moon"); +MODULE_DESCRIPTION("SS5PC1XX TVOUT driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/video/samsung/tv20/s5p_tv_v4l2.c b/drivers/media/video/samsung/tv20/s5p_tv_v4l2.c new file mode 100644 index 0000000..2a2a5e5 --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5p_tv_v4l2.c @@ -0,0 +1,1822 @@ +/* linux/drivers/media/video/samsung/tv20/s5p_tv_v4l2.c + * + * Video4Linux API ftn. file for Samsung TVOut driver + * + * Copyright (c) 2010 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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/stddef.h> +#include <linux/string.h> +#include <linux/version.h> +#include <linux/io.h> +#include <linux/uaccess.h> +#include <linux/delay.h> + +#include <media/v4l2-common.h> +#include <media/v4l2-ioctl.h> + +#include "s5p_tv.h" + +#ifdef COFIG_TVOUT_DBG +#define S5P_V4L2_DEBUG 1 +#endif + +#ifdef S5P_V4L2_DEBUG +#define V4L2PRINTK(fmt, args...)\ + printk(KERN_INFO "[V4L2_IF] %s: " fmt, __func__ , ## args) +#else +#define V4L2PRINTK(fmt, args...) +#endif + +/* 0 - hdcp stopped, 1 - hdcp started, 2 - hdcp reset */ +u8 hdcp_protocol_status; + +#define CVBS_S_VIDEO (V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_JP| \ + V4L2_STD_PAL | V4L2_STD_PAL_M | V4L2_STD_PAL_N | V4L2_STD_PAL_Nc | \ + V4L2_STD_PAL_60 | V4L2_STD_NTSC_443) + +static struct v4l2_output s5p_tv_outputs[] = { + { + .index = 0, + .name = "Analog COMPOSITE", + .type = V4L2_OUTPUT_TYPE_COMPOSITE, + .audioset = 0, + .modulator = 0, + .std = CVBS_S_VIDEO, + }, { + .index = 1, + .name = "Analog SVIDEO", + .type = V4L2_OUTPUT_TYPE_SVIDEO, + .audioset = 0, + .modulator = 0, + .std = CVBS_S_VIDEO, + }, { + .index = 2, + .name = "Analog COMPONENT_YPBPR_I", + .type = V4L2_OUTPUT_TYPE_YPBPR_INERLACED, + .audioset = 0, + .modulator = 0, + .std = V4L2_STD_ALL, + }, { + .index = 3, + .name = "Analog COMPONENT_YPBPR_P", + .type = V4L2_OUTPUT_TYPE_YPBPR_PROGRESSIVE, + .audioset = 0, + .modulator = 0, + .std = V4L2_STD_ALL, + }, { + .index = 4, + .name = "Analog COMPONENT_RGB_P", + .type = V4L2_OUTPUT_TYPE_RGB_PROGRESSIVE, + .audioset = 0, + .modulator = 0, + .std = V4L2_STD_ALL, + }, { + .index = 5, + .name = "Digital HDMI(YCbCr)", + .type = V4L2_OUTPUT_TYPE_HDMI, + .audioset = 2, + .modulator = 0, + .std = V4L2_STD_480P_60_16_9 | + V4L2_STD_480P_60_16_9 | V4L2_STD_720P_60 | + V4L2_STD_720P_50 +#ifdef CONFIG_CPU_S5PV210 + | V4L2_STD_1080P_60 | V4L2_STD_1080P_50 | + V4L2_STD_1080I_60 | V4L2_STD_1080I_50 | + V4L2_STD_480P_59 | V4L2_STD_720P_59 | + V4L2_STD_1080I_59 | V4L2_STD_1080P_59 | + V4L2_STD_1080P_30, +#endif + }, { + .index = 6, + .name = "Digital HDMI(RGB)", + .type = V4L2_OUTPUT_TYPE_HDMI_RGB, + .audioset = 2, + .modulator = 0, + .std = V4L2_STD_480P_60_16_9 | + V4L2_STD_480P_60_16_9 | + V4L2_STD_720P_60 | V4L2_STD_720P_50 +#ifdef CONFIG_CPU_S5PV210 + | V4L2_STD_1080P_60 | V4L2_STD_1080P_50 | + V4L2_STD_1080I_60 | V4L2_STD_1080I_50 | + V4L2_STD_480P_59 | V4L2_STD_720P_59 | + V4L2_STD_1080I_59 | V4L2_STD_1080P_59 | + V4L2_STD_1080P_30, +#endif + }, { + .index = 7, + .name = "Digital DVI", + .type = V4L2_OUTPUT_TYPE_DVI, + .audioset = 2, + .modulator = 0, + .std = V4L2_STD_480P_60_16_9 | + V4L2_STD_480P_60_16_9 | + V4L2_STD_720P_60 | V4L2_STD_720P_50 +#ifdef CONFIG_CPU_S5PV210 + | V4L2_STD_1080P_60 | V4L2_STD_1080P_50 | + V4L2_STD_1080I_60 | V4L2_STD_1080I_50 | + V4L2_STD_480P_59 | V4L2_STD_720P_59 | + V4L2_STD_1080I_59 | V4L2_STD_1080P_59 | + V4L2_STD_1080P_30, +#endif + } + +}; + +const struct v4l2_fmtdesc s5p_tv_o_fmt_desc[] = { + { + .index = 0, + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT, + .description = "YUV420, NV12 (Video Processor)", + .pixelformat = V4L2_PIX_FMT_NV12, + .flags = FORMAT_FLAGS_CrCb, + } +}; + +const struct v4l2_fmtdesc s5p_tv_o_overlay_fmt_desc[] = { + { + .index = 0, + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY, + .description = "16bpp RGB, le - RGB[565]", + .pixelformat = V4L2_PIX_FMT_RGB565, + .flags = FORMAT_FLAGS_PACKED, + }, { + .index = 1, + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY, + .description = "16bpp RGB, le - ARGB[1555]", + .pixelformat = V4L2_PIX_FMT_RGB555, + .flags = FORMAT_FLAGS_PACKED, + }, { + .index = 2, + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY, + .description = "16bpp RGB, le - ARGB[4444]", + .pixelformat = V4L2_PIX_FMT_RGB444, + .flags = FORMAT_FLAGS_PACKED, + }, { + .index = 3, + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY, + .description = "32bpp RGB, le - ARGB[8888]", + .pixelformat = V4L2_PIX_FMT_RGB32, + .flags = FORMAT_FLAGS_PACKED, + } +}; + +const struct v4l2_standard s5p_tv_standards[] = { + { + .index = 0, + .id = V4L2_STD_NTSC_M, + .name = "NTSC_M", + }, { + + .index = 1, + .id = V4L2_STD_PAL_BDGHI, + .name = "PAL_BDGHI", + }, { + .index = 2, + .id = V4L2_STD_PAL_M, + .name = "PAL_M", + }, { + .index = 3, + .id = V4L2_STD_PAL_N, + .name = "PAL_N", + }, { + .index = 4, + .id = V4L2_STD_PAL_Nc, + .name = "PAL_Nc", + }, { + .index = 5, + .id = V4L2_STD_PAL_60, + .name = "PAL_60", + }, { + .index = 6, + .id = V4L2_STD_NTSC_443, + .name = "NTSC_443", + }, { + .index = 7, + .id = V4L2_STD_480P_60_16_9, + .name = "480P_60_16_9", + }, { + .index = 8, + .id = V4L2_STD_480P_60_4_3, + .name = "480P_60_4_3", + }, { + .index = 9, + .id = V4L2_STD_576P_50_16_9, + .name = "576P_50_16_9", + }, { + .index = 10, + .id = V4L2_STD_576P_50_4_3, + .name = "576P_50_4_3", + }, { + .index = 11, + .id = V4L2_STD_720P_60, + .name = "720P_60", + }, { + .index = 12, + .id = V4L2_STD_720P_50, + .name = "720P_50", + }, +#ifdef CONFIG_CPU_S5PV210 + { + .index = 13, + .id = V4L2_STD_1080P_60, + .name = "1080P_60", + }, { + .index = 14, + .id = V4L2_STD_1080P_50, + .name = "1080P_50", + }, { + .index = 15, + .id = V4L2_STD_1080I_60, + .name = "1080I_60", + }, { + .index = 16, + .id = V4L2_STD_1080I_50, + .name = "1080I_50", + }, { + .index = 17, + .id = V4L2_STD_480P_59, + .name = "480P_59", + }, { + .index = 18, + .id = V4L2_STD_720P_59, + .name = "720P_59", + }, { + .index = 19, + .id = V4L2_STD_1080I_59, + .name = "1080I_59", + }, { + .index = 20, + .id = V4L2_STD_1080P_59, + .name = "1080I_50", + }, { + .index = 21, + .id = V4L2_STD_1080P_30, + .name = "1080I_30", + } +#endif +}; + +/* TODO: set default format for v, vo0/1 */ + +const struct v4l2_format s5p_tv_format[] = { + { + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT, + }, { + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY, + }, { + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY, + }, +}; + +#define S5P_TVOUT_MAX_STANDARDS \ + ARRAY_SIZE(s5p_tv_standards) +#define S5P_TVOUT_MAX_O_TYPES \ + ARRAY_SIZE(s5p_tv_outputs) +#define S5P_TVOUT_MAX_O_FMT \ + ARRAY_SIZE(s5p_tv_format) +#define S5P_TVOUT_MAX_O_FMT_DESC \ + ARRAY_SIZE(s5p_tv_o_fmt_desc) +#define S5P_TVOUT_MAX_O_OVERLAY_FMT_DESC \ + ARRAY_SIZE(s5p_tv_o_overlay_fmt_desc) + + +void s5p_tv_v4l2_init_param(void) +{ + s5ptv_status.v4l2.output = (struct v4l2_output *)&s5p_tv_outputs[0]; + s5ptv_status.v4l2.std = (struct v4l2_standard *)&s5p_tv_standards[0]; + s5ptv_status.v4l2.fmt_v = (struct v4l2_format *)&s5p_tv_o_fmt_desc[0]; + s5ptv_status.v4l2.fmt_vo_0 = (struct v4l2_format *)&s5p_tv_format[1]; + s5ptv_status.v4l2.fmt_vo_1 = (struct v4l2_format *)&s5p_tv_format[2]; + s5ptv_status.hdmi_audio_type = HDMI_AUDIO_PCM; +} + +/* VIDIOC_QUERYCAP handler */ +static int s5p_tv_v4l2_querycap(struct file *file, void *fh, + struct v4l2_capability *cap) +{ + struct s5p_tv_vo *layer = (struct s5p_tv_vo *)fh; + u32 index; + + if (layer == NULL) { + index = 0; + strcpy(cap->driver, "S3C TV Vid drv"); + cap->capabilities = V4L2_CAP_VIDEO_OUTPUT; + } else { + index = layer->index + 1; + strcpy(cap->driver, "S3C TV Grp drv"); + cap->capabilities = V4L2_CAP_VIDEO_OUTPUT_OVERLAY; + } + + strlcpy(cap->card, s5ptv_status.video_dev[index]->name, + sizeof(cap->card)); + + sprintf(cap->bus_info, "ARM AHB BUS"); + cap->version = KERNEL_VERSION(2, 6, 29); + + return 0; +} + + +/* VIDIOC_ENUM_FMT handlers */ +static int s5p_tv_v4l2_enum_fmt_vid_out(struct file *file, void *fh, + struct v4l2_fmtdesc *f) +{ + int index = f->index; + + V4L2PRINTK("(%d)++\n", f->index); + + if (index >= S5P_TVOUT_MAX_O_FMT_DESC) { + V4L2PRINTK("exceeded S5P_TVOUT_MAX_O_FMT_DESC\n"); + return -EINVAL; + } + + memcpy(f, &s5p_tv_o_fmt_desc[index], sizeof(struct v4l2_fmtdesc)); + + V4L2PRINTK("()--\n"); + return 0; + +} + +static int s5p_tv_v4l2_enum_fmt_vid_out_overlay(struct file *file, + void *fh, struct v4l2_fmtdesc *f) +{ + int index = f->index; + + V4L2PRINTK("(%d)++\n", f->index); + + if (index >= S5P_TVOUT_MAX_O_OVERLAY_FMT_DESC) { + V4L2PRINTK("exceeded S5P_TVOUT_MAX_O_OVERLAY_FMT_DESC\n"); + return -EINVAL; + } + + memcpy(f, &s5p_tv_o_overlay_fmt_desc[index], + sizeof(struct v4l2_fmtdesc)); + + V4L2PRINTK("()--\n"); + + return 0; +} + + +/* VIDIOC_G_FMT handlers */ +static int s5p_tv_v4l2_g_fmt_vid_out(struct file *file, void *fh, + struct v4l2_format *f) +{ + + struct v4l2_format *vid_out_fmt = f; + + V4L2PRINTK("(0x%08x)++\n", f->type); + + switch (vid_out_fmt->type) { + + case V4L2_BUF_TYPE_VIDEO_OUTPUT: { + + struct v4l2_pix_format_s5p_tvout vparam; + memset(&vparam, 0, sizeof(struct v4l2_pix_format_s5p_tvout)); + + vparam.base_y = + (void *)s5ptv_status.vl_basic_param.top_y_address; + vparam.base_c = + (void *)s5ptv_status.vl_basic_param.top_c_address; + vparam.pix_fmt.pixelformat = + s5ptv_status.src_color; + vparam.pix_fmt.width = + s5ptv_status.vl_basic_param.src_width; + vparam.pix_fmt.height = + s5ptv_status.vl_basic_param.src_height; + V4L2PRINTK("[type 0x%08x] : addr_y: [0x%08x],\ + addr_c [0x%08x], width[%d], height[%d]\n", + f->type, + s5ptv_status.vl_basic_param.top_y_address, + s5ptv_status.vl_basic_param.top_c_address, + s5ptv_status.vl_basic_param.src_width, + s5ptv_status.vl_basic_param.src_height); + memcpy(vid_out_fmt->fmt.raw_data, &vparam, + sizeof(struct v4l2_pix_format_s5p_tvout)); + break; + } + + default: + break; + } + + return 0; +} + +static int s5p_tv_v4l2_g_fmt_vid_out_overlay(struct file *file, + void *fh, struct v4l2_format *f) +{ + + struct v4l2_format *vid_out_fmt = f; + + V4L2PRINTK("(0x%08x)++\n", f->type); + + switch (vid_out_fmt->type) { + + case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: { + + struct v4l2_window_s5p_tvout vparam; + memset(&vparam, 0, sizeof(struct v4l2_window_s5p_tvout)); + + if (s5ptv_status.vl_basic_param.win_blending) { + vparam.flags = V4L2_FBUF_FLAG_CHROMAKEY; + vparam.capability = V4L2_FBUF_CAP_CHROMAKEY; + } + + if (s5ptv_status.vl_basic_param.alpha) { + vparam.flags = V4L2_FBUF_FLAG_LOCAL_ALPHA; + vparam.capability = V4L2_FBUF_CAP_LOCAL_ALPHA; + } + + vparam.priority = + s5ptv_status.vl_basic_param.priority; + + vparam.win.w.left = + s5ptv_status.vl_basic_param.src_offset_x; + vparam.win.w.top = + s5ptv_status.vl_basic_param.src_offset_y; + vparam.win.w.width = + s5ptv_status.vl_basic_param.src_width; + vparam.win.w.height = + s5ptv_status.vl_basic_param.src_height; + V4L2PRINTK("[type 0x%08x] : left: [%d], top [%d],\ + width[%d], height[%d]\n", + f->type, + s5ptv_status.vl_basic_param.src_offset_x, + s5ptv_status.vl_basic_param.src_offset_y, + s5ptv_status.vl_basic_param.src_width, + s5ptv_status.vl_basic_param.src_height); + memcpy(vid_out_fmt->fmt.raw_data, &vparam, + sizeof(struct v4l2_window_s5p_tvout)); + break; + } + + default: + break; + } + + V4L2PRINTK("()--\n"); + + return 0; +} + +/* VIDIOC_S_FMT handlers */ +static int s5p_tv_v4l2_s_fmt_vid_out(struct file *file, void *fh, + struct v4l2_format *f) +{ + + struct v4l2_format *vid_out_fmt = f; + + V4L2PRINTK("(0x%08x)++\n", f->type); + + switch (vid_out_fmt->type) { + + case V4L2_BUF_TYPE_VIDEO_OUTPUT: { + + struct v4l2_pix_format_s5p_tvout vparam; + memcpy(&vparam, vid_out_fmt->fmt.raw_data, + sizeof(struct v4l2_pix_format_s5p_tvout)); + + s5ptv_status.vl_basic_param.img_width = + vparam.pix_fmt.width; + + s5ptv_status.vl_basic_param.img_height = + vparam.pix_fmt.height; + + s5ptv_status.vl_basic_param.src_width = + vparam.pix_fmt.width; + s5ptv_status.vl_basic_param.src_height = + vparam.pix_fmt.height; + s5ptv_status.src_color = + vparam.pix_fmt.pixelformat; + + s5ptv_status.vl_basic_param.top_y_address = + (unsigned int)vparam.base_y; + s5ptv_status.vl_basic_param.top_c_address = + (unsigned int)vparam.base_c; + + /* check progressive or not */ + if (vparam.pix_fmt.field == V4L2_FIELD_NONE) { + + /* progressive */ + + switch (vparam.pix_fmt.pixelformat) { + + case V4L2_PIX_FMT_NV12: + /* linear */ + s5ptv_status.src_color = + VPROC_SRC_COLOR_NV12; + break; + case V4L2_PIX_FMT_NV12T: + /* tiled */ + s5ptv_status.src_color = + VPROC_SRC_COLOR_TILE_NV12; + break; + default: + V4L2PRINTK("src img format not supported\n"); + break; + } + + s5ptv_status.field_id = VPROC_TOP_FIELD; + + if ((s5ptv_status.hpd_status) && \ + s5ptv_status.vp_layer_enable) { + struct s5p_video_img_address temp_addr; + struct s5p_img_size img_size; + + temp_addr.y_address = + (unsigned int)vparam.base_y; + temp_addr.c_address = + (unsigned int)vparam.base_c; + img_size.img_width = + (unsigned int)vparam.pix_fmt.width; + img_size.img_height = + (unsigned int)vparam.pix_fmt.height; + + _s5p_vlayer_set_top_address((unsigned long) + &temp_addr); + _s5p_vlayer_set_img_size((unsigned long) + &img_size); + + } + } else if (vparam.pix_fmt.field == V4L2_FIELD_INTERLACED_TB) { + + /* interlaced */ + + switch (vparam.pix_fmt.pixelformat) { + + case V4L2_PIX_FMT_NV12: + /* linear */ + s5ptv_status.src_color = + VPROC_SRC_COLOR_NV12IW; + break; + case V4L2_PIX_FMT_NV12T: + /* tiled */ + s5ptv_status.src_color = + VPROC_SRC_COLOR_TILE_NV12IW; + break; + default: + V4L2PRINTK("src img format not supported\n"); + break; + } + + if (vparam.pix_fmt.priv == V4L2_FIELD_BOTTOM) + s5ptv_status.field_id = VPROC_BOTTOM_FIELD; + else + s5ptv_status.field_id = VPROC_TOP_FIELD; + + if ((s5ptv_status.hpd_status) && \ + s5ptv_status.vp_layer_enable) { + struct s5p_video_img_address temp_addr; + struct s5p_img_size img_size; + + temp_addr.y_address = + (unsigned int)vparam.base_y; + temp_addr.c_address = + (unsigned int)vparam.base_c; + img_size.img_width = + (unsigned int)vparam.pix_fmt.width; + img_size.img_height = + (unsigned int)vparam.pix_fmt.height; + + _s5p_vlayer_set_top_address((unsigned long) + &temp_addr); + _s5p_vlayer_set_img_size((unsigned long) + &img_size); + + } + + } else { + V4L2PRINTK("this field id not supported\n"); + } + break; + } + + default: + break; + } + + V4L2PRINTK("[type 0x%08x] : addr_y: [0x%08x], addr_c [0x%08x],\ + width[%d], height[%d]\n", + f->type, + s5ptv_status.vl_basic_param.top_y_address, + s5ptv_status.vl_basic_param.top_c_address, + s5ptv_status.vl_basic_param.src_width, + s5ptv_status.vl_basic_param.src_height); + V4L2PRINTK("()--\n"); + + return 0; +} + + +static int s5p_tv_v4l2_s_fmt_vid_out_overlay(struct file *file, void *fh, + struct v4l2_format *f) +{ + + struct v4l2_format *vid_out_fmt = f; + + V4L2PRINTK("(0x%08x)++\n", f->type); + + switch (vid_out_fmt->type) { + + case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: { + + struct v4l2_window_s5p_tvout vparam; + memcpy(&vparam, vid_out_fmt->fmt.raw_data, + sizeof(struct v4l2_window_s5p_tvout)); + + s5ptv_status.vl_basic_param.win_blending = + (vparam.flags & V4L2_FBUF_FLAG_CHROMAKEY) ? 1 : 0; + s5ptv_status.vl_basic_param.alpha = + (vparam.flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) ? 1 : 0; + s5ptv_status.vl_basic_param.priority = + vparam.priority; + s5ptv_status.vl_basic_param.src_offset_x = + vparam.win.w.left; + s5ptv_status.vl_basic_param.src_offset_y = + vparam.win.w.top; + s5ptv_status.vl_basic_param.src_width = + vparam.win.w.width; + s5ptv_status.vl_basic_param.src_height = + vparam.win.w.height; + V4L2PRINTK("[type 0x%08x] : left: [%d], top [%d],\ + width[%d], height[%d]\n", + f->type, + s5ptv_status.vl_basic_param.src_offset_x , + s5ptv_status.vl_basic_param.src_offset_y , + s5ptv_status.vl_basic_param.src_width, + s5ptv_status.vl_basic_param.src_height); + + if ((s5ptv_status.hpd_status) && s5ptv_status.vp_layer_enable) { + struct s5p_img_offset img_offset; + struct s5p_img_size img_size; + + img_offset.offset_x = vparam.win.w.left; + img_offset.offset_y = vparam.win.w.top; + img_size.img_width = vparam.win.w.width; + img_size.img_height = vparam.win.w.height; + _s5p_vlayer_set_blending( + s5ptv_status.vl_basic_param.win_blending); + _s5p_vlayer_set_alpha( + s5ptv_status.vl_basic_param.alpha); + _s5p_vlayer_set_priority(vparam.priority); + _s5p_vlayer_set_src_position((unsigned long) + &img_offset); + _s5p_vlayer_set_src_size((unsigned long) + &img_size); + } + + break; + } + + default: + break; + } + + V4L2PRINTK("()--\n"); + + return 0; +} + +/* start overlay * */ +static int s5p_tv_v4l2_overlay(struct file *file, void *fh, unsigned int i) +{ + struct s5p_tv_vo *layer = (struct s5p_tv_vo *)fh; + int start = i; + V4L2PRINTK("(0x%08x)++\n", i); + + /* tv dirver is on suspend mode + Just set the status variable on this function + overlay will be enabled or disabled on resume or + handle_cable function according to this status variable*/ + if (s5ptv_status.suspend_status == true || !(s5ptv_status.hpd_status)) { + if (start) + s5ptv_status.grp_layer_enable[layer->index] = true; + else + s5ptv_status.grp_layer_enable[layer->index] = false; + + V4L2PRINTK("suspend mode/hdmi cable is not inserted\n"); + return 0; + } else { + if (start) + _s5p_grp_start(layer->index); + else + _s5p_grp_stop(layer->index); + } + V4L2PRINTK("()--\n"); + return 0; +} + +static int s5p_tv_v4l2_g_fbuf(struct file *file, void *fh, + struct v4l2_framebuffer *a) +{ + + struct v4l2_framebuffer *fbuf = a; + struct s5p_tv_vo *layer = (struct s5p_tv_vo *)fh; + + fbuf->base = (void *)s5ptv_overlay[layer->index].base_addr; + fbuf->fmt.pixelformat = s5ptv_overlay[layer->index].fb.fmt.pixelformat; + + return 0; +} + +static int s5p_tv_v4l2_s_fbuf(struct file *file, void *fh, + struct v4l2_framebuffer *a) +{ + + struct v4l2_framebuffer *fbuf = a; + struct s5p_tv_vo *layer = (struct s5p_tv_vo *)fh; + + s5ptv_overlay[layer->index].base_addr = (unsigned int)fbuf->base; + + switch (fbuf->fmt.pixelformat) { + + case V4L2_PIX_FMT_RGB565: + s5ptv_overlay[layer->index].fb.fmt.pixelformat = + VM_DIRECT_RGB565; + break; + + case V4L2_PIX_FMT_RGB555: + s5ptv_overlay[layer->index].fb.fmt.pixelformat = + VM_DIRECT_RGB1555; + break; + + case V4L2_PIX_FMT_RGB444: + s5ptv_overlay[layer->index].fb.fmt.pixelformat = + VM_DIRECT_RGB4444; + break; + + case V4L2_PIX_FMT_RGB32: + s5ptv_overlay[layer->index].fb.fmt.pixelformat = + VM_DIRECT_RGB8888; + break; + + default: + break; + } + + return 0; +} + +/* Stream on/off */ +static int s5p_tv_v4l2_streamon(struct file *file, void *fh, + enum v4l2_buf_type i) +{ + struct s5p_tv_vo *layer = (struct s5p_tv_vo *)fh; + + V4L2PRINTK("(0x%08x)++\n", i); + + /* tv dirver is on suspend mode or hdmi cable is not inserted + Just set the status variable on this function + overlay will be enabled or disabled on resume or handle_cable + function according to this status variable*/ + if (s5ptv_status.suspend_status == true || !(s5ptv_status.hpd_status)) { + switch (i) { + /* Vlayer */ + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + _s5p_vlayer_init_param(0); + s5ptv_status.vp_layer_enable = true; + break; + /* GRP0/1*/ + case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: + s5ptv_status.grp_layer_enable[layer->index] = true; + break; + + default: + break; + } + V4L2PRINTK("suspend mode/hdmi cable is not inserted\n"); + return 0; + } + + switch (i) { + /* Vlayer*/ + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + if (!(s5ptv_status.vp_layer_enable)) { + _s5p_vlayer_init_param(0); + _s5p_vlayer_start(); + s5ptv_status.vp_layer_enable = true; + + mdelay(50); + } else + return -EBUSY; + + break; + /* GRP0/1 */ + case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: + _s5p_grp_start(layer->index); + break; + + default: + break; + } + + V4L2PRINTK("()--\n"); + + return 0; +} + +static int s5p_tv_v4l2_streamoff(struct file *file, void *fh, + enum v4l2_buf_type i) +{ + struct s5p_tv_vo *layer = (struct s5p_tv_vo *)fh; + + V4L2PRINTK("(0x%08x)++\n", i); + + /* tv driver is on suspend mode or hdmi cable is not inserted + Each layer was disabled on suspend function already. + Just set the status variable on this function + Each layer will be enabled or disabled on resume or + handle_cable function according to this status variable*/ + if (s5ptv_status.suspend_status == true || !(s5ptv_status.hpd_status)) { + switch (i) { + /* Vlayer*/ + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + s5ptv_status.vp_layer_enable = false; + break; + /* GRP0/1*/ + case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: + s5ptv_status.grp_layer_enable[layer->index] = false; + break; + + default: + break; + } + V4L2PRINTK("suspend mode\hdmi cable is not inserted\n"); + return 0; + } + + switch (i) { + /* Vlayer */ + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + _s5p_vlayer_stop(); + break; + /* GRP0/1 */ + case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: + _s5p_grp_stop(layer->index); + break; + + default: + break; + } + + V4L2PRINTK("()--\n"); + + return 0; +} + +/* Standard handling ENUMSTD is handled by videodev.c */ +static int s5p_tv_v4l2_g_std(struct file *file, void *fh, v4l2_std_id *norm) +{ + V4L2PRINTK("()++\n"); + + *norm = s5ptv_status.v4l2.std->id; + + V4L2PRINTK("(%d)++\n", (int)(*norm)); + + return 0; +} + +static int s5p_tv_v4l2_s_std(struct file *file, void *fh, v4l2_std_id *norm) +{ + unsigned int i = 0; + v4l2_std_id std_id = *norm; + + V4L2PRINTK("(0x%08Lx)++\n", std_id); + + s5ptv_status.v4l2.std = NULL; + + do { + if (s5p_tv_standards[i].id == std_id) { + s5ptv_status.v4l2.std = (struct v4l2_standard *) + &s5p_tv_standards[i]; + break; + } + + i++; + } while (i < S5P_TVOUT_MAX_STANDARDS); + + if (i >= S5P_TVOUT_MAX_STANDARDS || s5ptv_status.v4l2.std == NULL) { + V4L2PRINTK("(ERR) There is no tv-out standards :\ + index = 0x%08Lx\n", std_id); + return -EINVAL; + } + + switch (std_id) { + + case V4L2_STD_NTSC_M: + s5ptv_status.tvout_param.disp_mode = TVOUT_NTSC_M; + break; + + case V4L2_STD_PAL_BDGHI: + s5ptv_status.tvout_param.disp_mode = TVOUT_PAL_BDGHI; + break; + + case V4L2_STD_PAL_M: + s5ptv_status.tvout_param.disp_mode = TVOUT_PAL_M; + break; + + case V4L2_STD_PAL_N: + s5ptv_status.tvout_param.disp_mode = TVOUT_PAL_N; + break; + + case V4L2_STD_PAL_Nc: + s5ptv_status.tvout_param.disp_mode = TVOUT_PAL_NC; + break; + + case V4L2_STD_PAL_60: + s5ptv_status.tvout_param.disp_mode = TVOUT_PAL_60; + break; + + case V4L2_STD_NTSC_443: + s5ptv_status.tvout_param.disp_mode = TVOUT_NTSC_443; + break; + + case V4L2_STD_480P_60_16_9: + s5ptv_status.tvout_param.disp_mode = TVOUT_480P_60_16_9; + break; + + case V4L2_STD_480P_60_4_3: + s5ptv_status.tvout_param.disp_mode = TVOUT_480P_60_4_3; + break; + +#ifdef CONFIG_CPU_S5PV210 + case V4L2_STD_480P_59: + s5ptv_status.tvout_param.disp_mode = TVOUT_480P_59; + break; +#endif + case V4L2_STD_576P_50_16_9: + s5ptv_status.tvout_param.disp_mode = TVOUT_576P_50_16_9; + break; + + case V4L2_STD_576P_50_4_3: + s5ptv_status.tvout_param.disp_mode = TVOUT_576P_50_4_3; + break; + + case V4L2_STD_720P_60: + s5ptv_status.tvout_param.disp_mode = TVOUT_720P_60; + break; + +#ifdef CONFIG_CPU_S5PV210 + case V4L2_STD_720P_59: + s5ptv_status.tvout_param.disp_mode = TVOUT_720P_59; + break; +#endif + + case V4L2_STD_720P_50: + s5ptv_status.tvout_param.disp_mode = TVOUT_720P_50; + break; + +#ifdef CONFIG_CPU_S5PV210 + case V4L2_STD_1080I_60: + s5ptv_status.tvout_param.disp_mode = TVOUT_1080I_60; + break; + + case V4L2_STD_1080I_59: + s5ptv_status.tvout_param.disp_mode = TVOUT_1080I_59; + break; + + case V4L2_STD_1080I_50: + s5ptv_status.tvout_param.disp_mode = TVOUT_1080I_50; + break; + + case V4L2_STD_1080P_30: + s5ptv_status.tvout_param.disp_mode = TVOUT_1080P_30; + break; + + case V4L2_STD_1080P_60: + s5ptv_status.tvout_param.disp_mode = TVOUT_1080P_60; + break; + + case V4L2_STD_1080P_59: + s5ptv_status.tvout_param.disp_mode = TVOUT_1080P_59; + break; + + case V4L2_STD_1080P_50: + s5ptv_status.tvout_param.disp_mode = TVOUT_1080P_50; + break; +#endif + default: + V4L2PRINTK("(ERR) not supported standard id :\ + index = 0x%08Lx\n", std_id); + return -EINVAL; + break; + } + + V4L2PRINTK("()--\n"); + + return 0; +} + +/* Output handling */ +static int s5p_tv_v4l2_enum_output(struct file *file, void *fh, + struct v4l2_output *a) +{ + unsigned int index = a->index; + V4L2PRINTK("(%d)++\n", a->index); + + if (index >= S5P_TVOUT_MAX_O_TYPES) { + V4L2PRINTK("exceeded supported output!!\n"); + return -EINVAL; + } + + memcpy(a, &s5p_tv_outputs[index], sizeof(struct v4l2_output)); + + V4L2PRINTK("()--\n"); + + return 0; +} + +static int s5p_tv_v4l2_g_output(struct file *file, void *fh, unsigned int *i) +{ + V4L2PRINTK("(%d)++\n", *i); + + *i = s5ptv_status.v4l2.output->index; + + V4L2PRINTK("()--\n"); + return 0; +} + +static int s5p_tv_v4l2_s_output(struct file *file, void *fh, unsigned int i) +{ + V4L2PRINTK("(%d)++\n", i); + + if (i >= S5P_TVOUT_MAX_O_TYPES) + return -EINVAL; + + s5ptv_status.v4l2.output = &s5p_tv_outputs[i]; + + switch (s5ptv_status.v4l2.output->type) { + + case V4L2_OUTPUT_TYPE_COMPOSITE: + s5ptv_status.tvout_param.out_mode = + TVOUT_OUTPUT_COMPOSITE; + break; + + case V4L2_OUTPUT_TYPE_SVIDEO: + s5ptv_status.tvout_param.out_mode = + TVOUT_OUTPUT_SVIDEO; + break; + + case V4L2_OUTPUT_TYPE_YPBPR_INERLACED: + s5ptv_status.tvout_param.out_mode = + TVOUT_OUTPUT_COMPONENT_YPBPR_INERLACED; + break; + + case V4L2_OUTPUT_TYPE_YPBPR_PROGRESSIVE: + s5ptv_status.tvout_param.out_mode = + TVOUT_OUTPUT_COMPONENT_YPBPR_PROGRESSIVE; + break; + + case V4L2_OUTPUT_TYPE_RGB_PROGRESSIVE: + s5ptv_status.tvout_param.out_mode = + TVOUT_OUTPUT_COMPOSITE; + break; + + case V4L2_OUTPUT_TYPE_HDMI: + s5ptv_status.tvout_param.out_mode = + TVOUT_OUTPUT_HDMI; + break; + + case V4L2_OUTPUT_TYPE_HDMI_RGB: + s5ptv_status.tvout_param.out_mode = + TVOUT_OUTPUT_HDMI_RGB; + break; + + case V4L2_OUTPUT_TYPE_DVI: + s5ptv_status.tvout_param.out_mode = + TVOUT_OUTPUT_DVI; + break; + + + default: + break; + } + + if ((s5ptv_status.tvout_param.out_mode != TVOUT_OUTPUT_HDMI) && \ + (s5ptv_status.tvout_param.out_mode != TVOUT_OUTPUT_HDMI_RGB) && + (s5ptv_status.tvout_param.out_mode != TVOUT_OUTPUT_DVI)) { + if (!(s5ptv_status.hpd_status)) + s5p_tv_clk_gate(true); + + s5ptv_status.hpd_status = 1; + } + + _s5p_tv_if_set_disp(); + + V4L2PRINTK("()--\n"); + + return 0; +}; + +/* Crop ioctls */ + +/* + * Video Format Name Pixel aspect ratio Description + * STD(4:3) Anamorphic(16:9) + * 640x480 4:3 Used on YouTube + * 720x576 576i 5:4 64:45 Used on D1/DV PAL + * 704x576 576p 12:11 16:11 Used on EDTV PAL + * 720x480 480i 8:9 32:27 Used on DV NTSC + * 720x486 480i 8:9 32:27 Used on D1 NTSC + * 704x480 480p 10:11 40:33 Used on EDTV NTSC + */ + +static int s5p_tv_v4l2_cropcap(struct file *file, void *fh, + struct v4l2_cropcap *a) +{ + + struct v4l2_cropcap *cropcap = a; + + switch (cropcap->type) { + + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + break; + + case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: + break; + + default: + return -1; + break; + } + + switch (s5ptv_status.tvout_param.disp_mode) { + + case TVOUT_NTSC_M: + + case TVOUT_NTSC_443: + + case TVOUT_480P_60_16_9: + + case TVOUT_480P_60_4_3: + +#ifdef CONFIG_CPU_S5PV210 + case TVOUT_480P_59: +#endif + cropcap->bounds.top = 0; + cropcap->bounds.left = 0; + cropcap->bounds.width = 720; + cropcap->bounds.height = 480; + + cropcap->defrect.top = 0; + cropcap->defrect.left = 0; + cropcap->defrect.width = 720; + cropcap->defrect.height = 480; + break; + + case TVOUT_PAL_M: + + case TVOUT_PAL_BDGHI: + + case TVOUT_PAL_N: + + case TVOUT_PAL_NC: + + case TVOUT_PAL_60: + + case TVOUT_576P_50_16_9: + + case TVOUT_576P_50_4_3: + + cropcap->bounds.top = 0; + cropcap->bounds.left = 0; + cropcap->bounds.width = 720; + cropcap->bounds.height = 576; + + cropcap->defrect.top = 0; + cropcap->defrect.left = 0; + cropcap->defrect.width = 720; + cropcap->defrect.height = 576; + break; + + case TVOUT_720P_60: +#ifdef CONFIG_CPU_S5PV210 + case TVOUT_720P_59: +#endif + case TVOUT_720P_50: + cropcap->bounds.top = 0; + cropcap->bounds.left = 0; + cropcap->bounds.width = 1280; + cropcap->bounds.height = 720; + + cropcap->defrect.top = 0; + cropcap->defrect.left = 0; + cropcap->defrect.width = 1280; + cropcap->defrect.height = 720; + break; + +#ifdef CONFIG_CPU_S5PV210 + + case TVOUT_1080I_60: + + case TVOUT_1080I_59: + + case TVOUT_1080I_50: + + case TVOUT_1080P_60: + + case TVOUT_1080P_59: + + case TVOUT_1080P_50: + + case TVOUT_1080P_30: + + cropcap->bounds.top = 0; + cropcap->bounds.left = 0; + cropcap->bounds.width = 1920; + cropcap->bounds.height = 1080; + + cropcap->defrect.top = 0; + cropcap->defrect.left = 0; + cropcap->defrect.width = 1920; + cropcap->defrect.height = 1080; + break; +#endif + + default: + return -1; + break; + + } + + V4L2PRINTK("[input type 0x%08x] : left: [%d], top [%d],\ + width[%d], height[%d]\n", + + s5ptv_status.tvout_param.disp_mode, + cropcap->bounds.top , + cropcap->bounds.left , + cropcap->bounds.width, + cropcap->bounds.height); + + return 0; +} + +static int s5p_tv_v4l2_g_crop(struct file *file, void *fh, struct v4l2_crop *a) +{ + + struct v4l2_crop *crop = a; + struct s5p_tv_vo *layer = (struct s5p_tv_vo *)fh; + + switch (crop->type) { + /* Vlayer */ + + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + crop->c.left = s5ptv_status.vl_basic_param.dest_offset_x; + crop->c.top = s5ptv_status.vl_basic_param.dest_offset_y; + crop->c.width = s5ptv_status.vl_basic_param.dest_width; + crop->c.height = s5ptv_status.vl_basic_param.dest_height; + break; + /* GRP0/1 */ + + case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: + crop->c.left = s5ptv_overlay[layer->index].dst_rect.left; + crop->c.top = s5ptv_overlay[layer->index].dst_rect.top; + crop->c.width = s5ptv_overlay[layer->index].dst_rect.width; + crop->c.height = s5ptv_overlay[layer->index].dst_rect.height; + + break; + + default: + break; + } + + return 0; +} + +static int s5p_tv_v4l2_s_crop(struct file *file, void *fh, struct v4l2_crop *a) +{ + + struct v4l2_crop *crop = a; + struct s5p_tv_vo *layer = (struct s5p_tv_vo *)fh; + + switch (crop->type) { + /* Vlayer - scaling!! */ + + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + + s5ptv_status.vl_basic_param.dest_offset_x = crop->c.left; + s5ptv_status.vl_basic_param.dest_offset_y = crop->c.top; + s5ptv_status.vl_basic_param.dest_width = crop->c.width; + s5ptv_status.vl_basic_param.dest_height = crop->c.height; + + if ((s5ptv_status.hpd_status) && s5ptv_status.vp_layer_enable) { + struct s5p_img_size img_size; + struct s5p_img_offset img_offset; + img_size.img_width = crop->c.width; + img_size.img_height = crop->c.height; + img_offset.offset_x = crop->c.left; + img_offset.offset_y = crop->c.top; + + _s5p_vlayer_set_dest_size((unsigned long) + &img_size); + _s5p_vlayer_set_dest_position((unsigned long) + &img_offset); + } + + break; + + /* GRP0/1 */ + + case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: + s5ptv_overlay[layer->index].dst_rect.left = crop->c.left; + s5ptv_overlay[layer->index].dst_rect.top = crop->c.top; + s5ptv_overlay[layer->index].dst_rect.width = crop->c.width; + s5ptv_overlay[layer->index].dst_rect.height = crop->c.height; + break; + + default: + break; + } + + return 0; +} + +/* Stream type-dependent parameter ioctls */ + +static int s5p_tv_v4l2_g_parm_v(struct file *file, void *fh, + struct v4l2_streamparm *a) +{ + + struct v4l2_streamparm *param = a; + + struct v4l2_window_s5p_tvout vparam; + + if (s5ptv_status.vl_basic_param.win_blending) { + vparam.flags = V4L2_FBUF_FLAG_GLOBAL_ALPHA; + vparam.capability = V4L2_FBUF_FLAG_GLOBAL_ALPHA; + } + + vparam.win.global_alpha = s5ptv_status.vl_basic_param.alpha; + + vparam.priority = s5ptv_status.vl_basic_param.priority; + vparam.win.w.left = s5ptv_status.vl_basic_param.src_offset_x; + vparam.win.w.top = s5ptv_status.vl_basic_param.src_offset_y; + vparam.win.w.width = s5ptv_status.vl_basic_param.src_width; + vparam.win.w.height = s5ptv_status.vl_basic_param.src_height; + + memcpy(param->parm.raw_data, &vparam, + sizeof(struct v4l2_window_s5p_tvout)); + + return 0; +} + +static int s5p_tv_v4l2_s_parm_v(struct file *file, void *fh, + struct v4l2_streamparm *a) +{ + + struct v4l2_streamparm *param = a; + + struct v4l2_window_s5p_tvout vparam; + + memcpy(&vparam, param->parm.raw_data, + sizeof(struct v4l2_window_s5p_tvout)); + + s5ptv_status.vl_basic_param.win_blending = + (vparam.flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) ? 1 : 0; + s5ptv_status.vl_basic_param.alpha = vparam.win.global_alpha; + s5ptv_status.vl_basic_param.priority = vparam.priority; + s5ptv_status.vl_basic_param.src_offset_x = vparam.win.w.left; + s5ptv_status.vl_basic_param.src_offset_y = vparam.win.w.top; + s5ptv_status.vl_basic_param.src_width = vparam.win.w.width; + s5ptv_status.vl_basic_param.src_height = vparam.win.w.height; + + V4L2PRINTK("[type 0x%08x] : left: [%d], top [%d],\ + width[%d], height[%d]\n", + a->type, + s5ptv_status.vl_basic_param.src_offset_x , + s5ptv_status.vl_basic_param.src_offset_y , + s5ptv_status.vl_basic_param.src_width, + s5ptv_status.vl_basic_param.src_height); + + if ((s5ptv_status.hpd_status) && s5ptv_status.vp_layer_enable) { + struct s5p_img_offset img_offset; + struct s5p_img_size img_size; + + img_offset.offset_x = vparam.win.w.left; + img_offset.offset_y = vparam.win.w.top; + img_size.img_width = vparam.win.w.width; + img_size.img_height = vparam.win.w.height; + _s5p_vlayer_set_blending( + s5ptv_status.vl_basic_param.win_blending); + _s5p_vlayer_set_alpha(s5ptv_status.vl_basic_param.alpha); + _s5p_vlayer_set_priority(vparam.priority); + _s5p_vlayer_set_src_position((unsigned long)&img_offset); + _s5p_vlayer_set_src_size((unsigned long)&img_size); + } + + return 0; +} + +static int s5p_tv_v4l2_g_parm_vo(struct file *file, void *fh, + struct v4l2_streamparm *a) +{ + + struct v4l2_streamparm *param = a; + + struct v4l2_window_s5p_tvout vparam; + struct s5p_tv_vo *layer = (struct s5p_tv_vo *)fh; + + memset(&vparam, 0, sizeof(struct v4l2_window_s5p_tvout)); + + V4L2PRINTK("entered\n"); + + if (s5ptv_overlay[layer->index].win_blending) { + vparam.flags = V4L2_FBUF_FLAG_GLOBAL_ALPHA; + vparam.capability = V4L2_FBUF_CAP_GLOBAL_ALPHA; + } + + if (s5ptv_overlay[layer->index].blank_change) { + vparam.flags |= V4L2_FBUF_FLAG_CHROMAKEY; + vparam.capability |= V4L2_FBUF_CAP_CHROMAKEY; + } + + if (s5ptv_overlay[layer->index].pixel_blending) { + vparam.flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA; + vparam.capability |= V4L2_FBUF_CAP_LOCAL_ALPHA; + } + + if (s5ptv_overlay[layer->index].pre_mul) { + vparam.flags |= V4L2_FBUF_FLAG_PRE_MULTIPLY; + vparam.capability |= V4L2_FBUF_CAP_PRE_MULTIPLY; + } + + vparam.priority = s5ptv_overlay[layer->index].priority; + + vparam.win.chromakey = s5ptv_overlay[layer->index].blank_color; + vparam.win.w.left = s5ptv_overlay[layer->index].dst_rect.left; + vparam.win.w.top = s5ptv_overlay[layer->index].dst_rect.top; + vparam.win.w.left = s5ptv_overlay[layer->index].win.w.left; + vparam.win.w.top = s5ptv_overlay[layer->index].win.w.top; + vparam.win.w.width = s5ptv_overlay[layer->index].win.w.width; + vparam.win.w.height = s5ptv_overlay[layer->index].win.w.height; + vparam.win.global_alpha = s5ptv_overlay[layer->index].win.global_alpha; + + vparam.win.w.width = + s5ptv_overlay[layer->index].fb.fmt.bytesperline; + + memcpy(param->parm.raw_data, &vparam, + sizeof(struct v4l2_window_s5p_tvout)); + + return 0; + +} + +static int s5p_tv_v4l2_s_parm_vo(struct file *file, void *fh, + struct v4l2_streamparm *a) +{ + + struct v4l2_streamparm *param = a; + + struct v4l2_window_s5p_tvout vparam; + + struct s5p_tv_vo *layer = (struct s5p_tv_vo *)fh; + memcpy(&vparam, param->parm.raw_data, + sizeof(struct v4l2_window_s5p_tvout)); + + s5ptv_overlay[layer->index].win_blending = + (vparam.flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) ? 1 : 0; + s5ptv_overlay[layer->index].blank_change = + (vparam.flags & V4L2_FBUF_FLAG_CHROMAKEY) ? 1 : 0; + s5ptv_overlay[layer->index].pixel_blending = + (vparam.flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) ? 1 : 0; + s5ptv_overlay[layer->index].pre_mul = + (vparam.flags & V4L2_FBUF_FLAG_PRE_MULTIPLY) ? 1 : 0; + s5ptv_overlay[layer->index].priority = + vparam.priority; + s5ptv_overlay[layer->index].blank_color = + vparam.win.chromakey; + s5ptv_overlay[layer->index].dst_rect.left = + vparam.win.w.left; + s5ptv_overlay[layer->index].dst_rect.top = + vparam.win.w.top; + s5ptv_overlay[layer->index].win.w.left = + vparam.win.w.left; + s5ptv_overlay[layer->index].win.w.top = + vparam.win.w.top; + s5ptv_overlay[layer->index].win.w.width = + vparam.win.w.width; + s5ptv_overlay[layer->index].win.w.height = + vparam.win.w.height; + s5ptv_overlay[layer->index].win.global_alpha = + vparam.win.global_alpha; + + s5ptv_overlay[layer->index].fb.fmt.bytesperline = + vparam.win.w.width; + + return 0; +} + +#define VIDIOC_HDCP_ENABLE _IOWR('V', 100, unsigned int) +#define VIDIOC_HDCP_STATUS _IOR('V', 101, unsigned int) +#define VIDIOC_HDCP_PROT_STATUS _IOR('V', 102, unsigned int) +#define VIDIOC_INIT_AUDIO _IOR('V', 103, unsigned int) +#define VIDIOC_AV_MUTE _IOR('V', 104, unsigned int) +#define VIDIOC_G_AVMUTE _IOR('V', 105, unsigned int) + +long s5p_tv_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + switch (cmd) { + + case VIDIOC_HDCP_ENABLE: + s5ptv_status.hdcp_en = (unsigned int) arg; + V4L2PRINTK("HDCP status is %s\n", + s5ptv_status.hdcp_en ? "enabled" : "disabled"); + return 0; + + case VIDIOC_HDCP_STATUS: { + + unsigned int *status = (unsigned int *)&arg; + + *status = 1; + + V4L2PRINTK("HPD status is %s\n", + s5ptv_status.hpd_status ? "plugged" : "unplugged"); + return 0; + } + + case VIDIOC_HDCP_PROT_STATUS: { + + unsigned int *prot = (unsigned int *)&arg; + + *prot = 1; + + V4L2PRINTK("hdcp prot status is %d\n", + hdcp_protocol_status); + return 0; + } + + case VIDIOC_ENUMSTD: { + + struct v4l2_standard *p = (struct v4l2_standard *)arg; + + if (p->index >= S5P_TVOUT_MAX_STANDARDS) { + V4L2PRINTK("exceeded S5P_TVOUT_MAX_STANDARDS\n"); + return -EINVAL; + } + + memcpy(p, &s5p_tv_standards[p->index], + sizeof(struct v4l2_standard)); + + return 0; +} + + default: + break; + } + + /* + * in 2.6.28 version Mauro Carvalho Chehab added for removing inode + * but 2.6.29 is not applied. what is it? + */ + return video_ioctl2(file, cmd, arg); +} + +long s5p_tv_vid_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct video_device *vfd = video_devdata(file); + const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops; + + switch (cmd) { + + case VIDIOC_S_FMT: { + struct v4l2_format *f = (struct v4l2_format *)arg; + void *fh = file->private_data; + long ret = -EINVAL; + + if (ops->vidioc_s_fmt_vid_out) + ret = ops->vidioc_s_fmt_vid_out(file, fh, f); + return ret; + } + + default: + break; + } + + /* + * in 2.6.28 version Mauro Carvalho Chehab added for removing inode + * but 2.6.29 is not applied. what is it? + */ + return video_ioctl2(file, cmd, arg); +} + + +long s5p_tv_v_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct video_device *vfd = video_devdata(file); + const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops; + + switch (cmd) { + + case VIDIOC_INIT_AUDIO: + s5ptv_status.hdmi_audio_type = (unsigned int) arg; + + if (arg) { + s5p_hdmi_set_audio(true); + if (s5ptv_status.tvout_output_enable) + s5p_hdmi_audio_enable(true); + } else { + s5p_hdmi_set_audio(false); + if (s5ptv_status.tvout_output_enable) + s5p_hdmi_audio_enable(false); + + } + + return 0; + + case VIDIOC_AV_MUTE: + if (arg) { + s5ptv_status.hdmi_audio_type = HDMI_AUDIO_NO; + if (s5ptv_status.tvout_output_enable) { + s5p_hdmi_audio_enable(false); + __s5p_hdmi_video_set_bluescreen(true, 0, 0, 0); + } + s5p_hdmi_set_mute(true); + } else { + s5ptv_status.hdmi_audio_type = HDMI_AUDIO_PCM; + if (s5ptv_status.tvout_output_enable) { + s5p_hdmi_audio_enable(true); + __s5p_hdmi_video_set_bluescreen(false, 0, 0, 0); + } + s5p_hdmi_set_mute(false); + } + return 0; + case VIDIOC_G_AVMUTE: + return s5p_hdmi_get_mute(); + + case VIDIOC_S_FMT: { + struct v4l2_format *f = (struct v4l2_format *)arg; + void *fh = file->private_data; + long ret = -EINVAL; + + if (ops->vidioc_s_fmt_vid_out) + ret = ops->vidioc_s_fmt_vid_out(file, fh, f); + return ret; + } + + case VIDIOC_HDCP_ENABLE: + s5ptv_status.hdcp_en = (unsigned int) arg; + V4L2PRINTK("HDCP status is %s\n", + s5ptv_status.hdcp_en ? "enabled" : "disabled"); + return 0; + + case VIDIOC_HDCP_STATUS: { + + unsigned int *status = (unsigned int *)arg; + + *status = s5ptv_status.hpd_status; + + V4L2PRINTK("HPD status is %s\n", + s5ptv_status.hpd_status ? "plugged" : "unplugged"); + return 0; + } + + case VIDIOC_HDCP_PROT_STATUS: { + + unsigned int *prot = (unsigned int *)&arg; + + *prot = 1; + + V4L2PRINTK("hdcp prot status is %d\n", + hdcp_protocol_status); + return 0; + } + + case VIDIOC_ENUMSTD: { + + struct v4l2_standard *p = (struct v4l2_standard *)arg; + + if (p->index >= S5P_TVOUT_MAX_STANDARDS) { + V4L2PRINTK("exceeded S5P_TVOUT_MAX_STANDARDS\n"); + return -EINVAL; + } + + memcpy(p, &s5p_tv_standards[p->index], + sizeof(struct v4l2_standard)); + + return 0; + } + + default: + break; + } + + /* + * in 2.6.28 version Mauro Carvalho Chehab added for removing inode + * but 2.6.29 is not applied. what is it? + */ + return video_ioctl2(file, cmd, arg); +} + +long s5p_tv_vo_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + void *fh = file->private_data; + + switch (cmd) { + + case VIDIOC_ENUM_FMT: { + + struct v4l2_fmtdesc *f = (struct v4l2_fmtdesc *)arg; + enum v4l2_buf_type type; + unsigned int index; + + index = f->index; + type = f->type; + + if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY) { + memset(f, 0, sizeof(*f)); + f->index = index; + f->type = type; + + return s5p_tv_v4l2_enum_fmt_vid_out_overlay(file, + fh, f); + } + + break; + } + + case VIDIOC_G_FMT: { + + struct v4l2_format *f = (struct v4l2_format *)arg; + + return s5p_tv_v4l2_g_fmt_vid_out_overlay(file, fh, f); + } + + break; + + default: + break; + } + + /* + * in 2.6.28 version Mauro Carvalho Chehab added for removing inode + * but 2.6.29 is not applied. what is it? + */ + return video_ioctl2(file, cmd, arg); +} + +const struct v4l2_ioctl_ops s5p_tv_v4l2_ops = { + .vidioc_querycap = s5p_tv_v4l2_querycap, + .vidioc_g_std = s5p_tv_v4l2_g_std, + .vidioc_s_std = s5p_tv_v4l2_s_std, + .vidioc_enum_output = s5p_tv_v4l2_enum_output, + .vidioc_g_output = s5p_tv_v4l2_g_output, + .vidioc_s_output = s5p_tv_v4l2_s_output, +}; + +const struct v4l2_ioctl_ops s5p_tv_v4l2_vid_ops = { + .vidioc_querycap = s5p_tv_v4l2_querycap, + .vidioc_enum_fmt_vid_out = s5p_tv_v4l2_enum_fmt_vid_out, + .vidioc_g_fmt_vid_out = s5p_tv_v4l2_g_fmt_vid_out, + .vidioc_s_fmt_vid_out = s5p_tv_v4l2_s_fmt_vid_out, + .vidioc_streamon = s5p_tv_v4l2_streamon, + .vidioc_streamoff = s5p_tv_v4l2_streamoff, + .vidioc_cropcap = s5p_tv_v4l2_cropcap, + .vidioc_g_crop = s5p_tv_v4l2_g_crop, + .vidioc_s_crop = s5p_tv_v4l2_s_crop, + .vidioc_g_parm = s5p_tv_v4l2_g_parm_v, + .vidioc_s_parm = s5p_tv_v4l2_s_parm_v, +}; + +const struct v4l2_ioctl_ops s5p_tv_v4l2_v_ops = { + .vidioc_querycap = s5p_tv_v4l2_querycap, + .vidioc_enum_fmt_vid_out = s5p_tv_v4l2_enum_fmt_vid_out, + .vidioc_g_fmt_vid_out = s5p_tv_v4l2_g_fmt_vid_out, + .vidioc_s_fmt_vid_out = s5p_tv_v4l2_s_fmt_vid_out, + .vidioc_streamon = s5p_tv_v4l2_streamon, + .vidioc_streamoff = s5p_tv_v4l2_streamoff, + .vidioc_g_std = s5p_tv_v4l2_g_std, + .vidioc_s_std = s5p_tv_v4l2_s_std, + .vidioc_enum_output = s5p_tv_v4l2_enum_output, + .vidioc_g_output = s5p_tv_v4l2_g_output, + .vidioc_s_output = s5p_tv_v4l2_s_output, + .vidioc_cropcap = s5p_tv_v4l2_cropcap, + .vidioc_g_crop = s5p_tv_v4l2_g_crop, + .vidioc_s_crop = s5p_tv_v4l2_s_crop, + .vidioc_g_parm = s5p_tv_v4l2_g_parm_v, + .vidioc_s_parm = s5p_tv_v4l2_s_parm_v, +}; + +const struct v4l2_ioctl_ops s5p_tv_v4l2_vo_ops = { + .vidioc_querycap = s5p_tv_v4l2_querycap, + .vidioc_g_fmt_vid_out_overlay = s5p_tv_v4l2_g_fmt_vid_out_overlay, + .vidioc_s_fmt_vid_out_overlay = s5p_tv_v4l2_s_fmt_vid_out_overlay, + .vidioc_overlay = s5p_tv_v4l2_overlay, + .vidioc_g_fbuf = s5p_tv_v4l2_g_fbuf, + .vidioc_s_fbuf = s5p_tv_v4l2_s_fbuf, + .vidioc_streamon = s5p_tv_v4l2_streamon, + .vidioc_streamoff = s5p_tv_v4l2_streamoff, + .vidioc_cropcap = s5p_tv_v4l2_cropcap, + .vidioc_g_crop = s5p_tv_v4l2_g_crop, + .vidioc_s_crop = s5p_tv_v4l2_s_crop, + .vidioc_g_parm = s5p_tv_v4l2_g_parm_vo, + .vidioc_s_parm = s5p_tv_v4l2_s_parm_vo, +}; + diff --git a/drivers/media/video/samsung/tv20/s5pc100/hdcp_s5pc100.c b/drivers/media/video/samsung/tv20/s5pc100/hdcp_s5pc100.c new file mode 100644 index 0000000..7ca9cf4 --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5pc100/hdcp_s5pc100.c @@ -0,0 +1,1596 @@ +/* linux/drivers/media/video/samsung/tv20/s5pc100/hdcp_s5pc100.c + * + * hdcp raw ftn file for Samsung TVOut driver + * + * Copyright (c) 2009 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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/delay.h> +#include <linux/i2c.h> +#include <linux/device.h> +#include <linux/wait.h> +#include <linux/interrupt.h> +#include <linux/workqueue.h> +#include <linux/delay.h> +#include <linux/irq.h> +#include <linux/io.h> + +#include <mach/gpio.h> + +#include "tv_out_s5pc100.h" +#include "regs/regs-hdmi.h" + +/* for Operation check */ +#ifdef COFIG_TVOUT_RAW_DBG +#define S5P_HDCP_DEBUG 1 +#define S5P_HDCP_I2C_DEBUG 1 +#define S5P_HDCP_AUTH_DEBUG 1 +#endif + +#ifdef S5P_HDCP_DEBUG +#define HDCPPRINTK(fmt, args...) \ + printk(KERN_INFO "\t\t[HDCP] %s: " fmt, __func__ , ## args) +#else +#define HDCPPRINTK(fmt, args...) +#endif + +/* for i2c bus check */ +#ifdef S5P_HDCP_I2C_DEBUG +#define I2CPRINTK(fmt, args...) \ + printk(KERN_INFO "\t\t\t\t[I2C] %s: " fmt, __func__ , ## args) +#else +#define I2CPRINTK(fmt, args...) +#endif + +/* for authentication key check */ +#ifdef S5P_HDCP_AUTH_DEBUG +#define AUTHPRINTK(fmt, args...) \ + printk(KERN_INFO "\t\t\t[AUTHKEY] %s: " fmt, __func__ , ## args) +#else +#define AUTHPRINTK(fmt, args...) +#endif + + + +enum hdmi_run_mode { + DVI_MODE, + HDMI_MODE +}; + +enum hdmi_resolution { + SD480P, + SD480I, + WWSD480P, + HD720P, + SD576P, + WWSD576P, + HD1080I +}; + +enum hdmi_color_bar_type { + HORIZONTAL, + VERTICAL +}; + +enum hdcp_event { + /* Stop HDCP */ + HDCP_EVENT_STOP, + /* Start HDCP*/ + HDCP_EVENT_START, + /* Start to read Bksv,Bcaps */ + HDCP_EVENT_READ_BKSV_START, + /* Start to write Aksv,An */ + HDCP_EVENT_WRITE_AKSV_START, + /* Start to check if Ri is equal to Rj */ + HDCP_EVENT_CHECK_RI_START, + /* Start 2nd authentication process */ + HDCP_EVENT_SECOND_AUTH_START +}; + +enum hdcp_state { + NOT_AUTHENTICATED, + RECEIVER_READ_READY, + BCAPS_READ_DONE, + BKSV_READ_DONE, + AN_WRITE_DONE, + AKSV_WRITE_DONE, + FIRST_AUTHENTICATION_DONE, + SECOND_AUTHENTICATION_RDY, + RECEIVER_FIFOLSIT_READY, + SECOND_AUTHENTICATION_DONE, +}; + +/* + * Below CSC_TYPE is temporary. CSC_TYPE enum. + * may be included in SetSD480pVars_60Hz etc. + * + * LR : Limited Range (16~235) + * FR : Full Range (0~255) + */ +enum hdmi_intr_src { + WAIT_FOR_ACTIVE_RX, + WDT_FOR_REPEATER, + EXCHANGE_KSV, + UPDATE_P_VAL, + UPDATE_R_VAL, + AUDIO_OVERFLOW, + AUTHEN_ACK, + UNKNOWN_INT +}; + +const u8 hdcp_key[288] = { + 0x48, 0xf8, 0x11, 0xb6, 0x85, 0x66, 0x9b, 0x65, 0x0b, 0x9f, + 0x5a, 0x01, 0xb4, 0x43, 0xaf, 0xd7, 0x34, 0xeb, 0xbe, 0xe0, + 0x52, 0xfb, 0x85, 0xfe, 0xfa, 0xb1, 0x2f, 0xe4, 0xc3, 0xce, + 0xa9, 0x27, 0x33, 0x74, 0x97, 0xd8, 0xfc, 0x62, 0xb8, 0x92, + 0x4a, 0xb6, 0xce, 0x7b, 0xb8, 0xda, 0x67, 0xbf, 0xda, 0xea, + 0xbf, 0xa9, 0xc0, 0x2a, 0xc8, 0xf6, 0x44, 0x41, 0x5a, 0x10, + 0x59, 0x88, 0x54, 0xcf, 0x51, 0x91, 0x12, 0xd5, 0xa8, 0x41, + 0x3a, 0x8a, 0x88, 0xd1, 0x5a, 0x9a, 0x55, 0xc1, 0xbb, 0x5e, + 0x8a, 0xa0, 0x84, 0x1b, 0xa8, 0xea, 0x31, 0x59, 0xea, 0x71, + 0x0c, 0xcf, 0x59, 0xf5, 0xa8, 0x32, 0x57, 0xbb, 0xd4, 0xa0, + 0x5b, 0x88, 0x44, 0x66, 0xd6, 0x80, 0xfa, 0xe9, 0x18, 0xe0, + 0x50, 0x73, 0x92, 0x63, 0xe1, 0x5c, 0x13, 0xbf, 0x7d, 0x0d, + 0x70, 0x0b, 0xf8, 0x25, 0x4a, 0x3b, 0x9c, 0x17, 0x56, 0xb3, + 0x71, 0x2b, 0xfe, 0x3c, 0xcb, 0x7c, 0x19, 0x28, 0x53, 0xa7, + 0x5c, 0x57, 0x47, 0xe3, 0xe1, 0x4c, 0x76, 0x62, 0x0a, 0x40, + 0x30, 0xcf, 0xbe, 0x51, 0xaf, 0x0d, 0x11, 0x73, 0xd6, 0x6a, + 0xc2, 0xbf, 0x4f, 0xc1, 0x88, 0x8d, 0x14, 0xa6, 0xd1, 0x92, + 0x6c, 0xf7, 0x8a, 0xe6, 0x9c, 0x96, 0xc5, 0xc4, 0x5c, 0x36, + 0xf6, 0xfb, 0x39, 0xf4, 0x79, 0x3f, 0x7a, 0x30, 0x71, 0x5e, + 0x3e, 0xfe, 0xf3, 0x4d, 0x0c, 0x02, 0x55, 0xeb, 0x08, 0x24, + 0x5f, 0x64, 0xd7, 0xcf, 0xf3, 0x48, 0x35, 0x03, 0xc4, 0xc8, + 0x29, 0xf7, 0x9d, 0xcf, 0x21, 0xb8, 0x67, 0x05, 0xc6, 0x47, + 0x05, 0x1b, 0x5f, 0xf3, 0xa7, 0xbc, 0x23, 0xf0, 0x09, 0xc4, + 0x90, 0x44, 0x5d, 0x3f, 0xf9, 0x79, 0x74, 0xea, 0x7b, 0x42, + 0x57, 0x88, 0xce, 0x32, 0x43, 0xa5, 0xf4, 0x4e, 0x05, 0xc9, + 0x73, 0xc2, 0x49, 0x94, 0x85, 0x5c, 0xa2, 0x11, 0x91, 0x1f, + 0x9e, 0xe3, 0x21, 0xbe, 0xe9, 0x36, 0x52, 0xec, 0x4b, 0xa6, + 0x7d, 0xf6, 0x8a, 0x85, 0xb9, 0xe1, 0xc7, 0x6e, 0x6b, 0x08, + 0x9d, 0xf2, 0xee, 0x7d, 0x28, 0xbd, 0xf0, 0x9d +}; + +struct s5p_hdcp_info { + bool is_repeater; + bool hpd_status; + u32 time_out; + u32 hdcp_enable; + + spinlock_t lock; + + struct i2c_client *client; + + wait_queue_head_t waitq; + enum hdcp_event event; + enum hdcp_state auth_status; + + struct work_struct work; +}; + +static struct s5p_hdcp_info hdcp_info = { + .is_repeater = false, + .time_out = 0, + .hdcp_enable = false, + .client = NULL, + .event = HDCP_EVENT_STOP, + .auth_status = NOT_AUTHENTICATED, + +}; + +#define HDCP_RI_OFFSET 0x08 +#define INFINITE 0xffffffff + +#define DO_NOT_TRANSMIT (0) +#define HDMI_SYS_ENABLE (1 << 0) +#define HDMI_ASP_ENABLE (1 << 2) +#define HDMI_ASP_DISABLE (~HDMI_ASP_ENABLE) + +#define MAX_DEVS_EXCEEDED (0x1 << 7) +#define MAX_CASCADE_EXCEEDED (0x1 << 3) + +#define MAX_CASCADE_EXCEEDED_ERROR (-1) +#define MAX_DEVS_EXCEEDED_ERROR (-2) +#define REPEATER_ILLEGAL_DEVICE_ERROR (-3) + +#define AINFO_SIZE 1 +#define BCAPS_SIZE 1 +#define BSTATUS_SIZE 2 +#define SHA_1_HASH_SIZE 20 + +#define KSV_FIFO_READY (0x1 << 5) + +#define SET_HDCP_KSV_WRITE_DONE (0x1 << 3) +#define CLEAR_HDCP_KSV_WRITE_DONE (~SET_HDCP_KSV_WRITE_DONE) + +#define SET_HDCP_KSV_LIST_EMPTY (0x1 << 2) +#define CLEAR_HDCP_KSV_LIST_EMPTY (~SET_HDCP_KSV_LIST_EMPTY) +#define SET_HDCP_KSV_END (0x1 << 1) +#define CLEAR_HDCP_KSV_END (~SET_HDCP_KSV_END) +#define SET_HDCP_KSV_READ (0x1 << 0) +#define CLEAR_HDCP_KSV_READ (~SET_HDCP_KSV_READ) + +#define SET_HDCP_SHA_VALID_READY (0x1 << 1) +#define CLEAR_HDCP_SHA_VALID_READY (~SET_HDCP_SHA_VALID_READY) +#define SET_HDCP_SHA_VALID (0x1 << 0) +#define CLEAR_HDCP_SHA_VALID (~SET_HDCP_SHA_VALID) + +#define TRANSMIT_EVERY_VSYNC (0x1 << 1) + +/* must be checked */ + +/* + * Read the HDCP data from Rx by using IIC + */ +static int hdcp_i2c_read(struct i2c_client *client, u8 subaddr, + u8 *data, u16 len) +{ + u8 addr = subaddr; + int ret = 0; + + struct i2c_msg msg[] = { + { client->addr, 0, 1, &addr}, + { client->addr, I2C_M_RD, len, data } + }; + + if (!hdcp_info.client) { + HDCPPRINTK("DDC port is not available!!" + "Check hdmi receiver's DDC Port \n"); + return -EIO; + } + + I2CPRINTK("sub addr = 0x%08x, data len = %d\n", subaddr, len); + + if (i2c_transfer(client->adapter, msg, 2) != 2) + ret = -EIO; + + I2CPRINTK("ret :%d\n", ret); + +#ifdef S5P_HDCP_I2C_DEBUG + { + int loop = 0; + HDCPPRINTK("read_data :: \n"); + printk(KERN_INFO "\t\t\t"); + + for (loop = 0; loop < len; loop++) + printk("0x%02x ", data[loop]); + + printk(KERN_INFO "\n"); + } +#endif + return ret; +} + +/* + * Write the HDCP data to receiver by using IIC + * - use i2c_master_send() + */ +static int hdcp_i2c_write(struct i2c_client *client, u8 *data, u16 len) +{ + int ret = 0; + + if (!hdcp_info.client) { + HDCPPRINTK("DDC port is not available!!" + "Check hdmi receiver's DDC Port \n"); + return -EIO; + } + + I2CPRINTK("sub addr = 0x%08x, data len = %d\n", + + data[0], len); + + if (i2c_master_send(client, (const char *) data, len) != len) + ret = -EIO; + + I2CPRINTK("ret :%d\n", ret); + + return ret; +} + +/* + * 1st Authentication step func. + * Write the Ainfo data to Rx + */ +static bool write_ainfo(void) +{ + int ret = 0; + u8 ainfo[2]; + + ainfo[0] = HDCP_Ainfo; + ainfo[1] = 0; + + ret = hdcp_i2c_write(hdcp_info.client, ainfo, 2); + + if (ret < 0) + HDCPPRINTK("Can't write ainfo data through i2c bus\n"); + + return (ret < 0) ? false : true; +} + +/* + * Write the An data to Rx + */ +static bool write_an(void) +{ + int ret = 0; + u8 an[AN_SIZE+1]; + + an[0] = HDCP_An; + + /* Read An from HDMI */ + an[1] = readb(hdmi_base + S5P_HDCP_An_0_0); + an[2] = readb(hdmi_base + S5P_HDCP_An_0_1); + an[3] = readb(hdmi_base + S5P_HDCP_An_0_2); + an[4] = readb(hdmi_base + S5P_HDCP_An_0_3); + an[5] = readb(hdmi_base + S5P_HDCP_An_1_0); + an[6] = readb(hdmi_base + S5P_HDCP_An_1_1); + an[7] = readb(hdmi_base + S5P_HDCP_An_1_2); + an[8] = readb(hdmi_base + S5P_HDCP_An_1_3); + + ret = hdcp_i2c_write(hdcp_info.client, an, AN_SIZE + 1); + + if (ret < 0) + HDCPPRINTK("Can't write an data through i2c bus\n"); + +#ifdef S5P_HDCP_AUTH_DEBUG + { + u16 i = 0; + + for (i = 1; i < AN_SIZE + 1; i++) + AUTHPRINTK("HDCPAn[%d]: 0x%x \n", i, an[i]); + + } +#endif + + return (ret < 0) ? false : true; +} + +/* + * Write the Aksv data to Rx + */ +static bool write_aksv(void) +{ + int ret = 0; + u8 aksv[AKSV_SIZE+1]; + + aksv[0] = HDCP_Aksv; + + /* Read Aksv from HDMI */ + aksv[1] = readb(hdmi_base + S5P_HDCP_AKSV_0_0); + aksv[2] = readb(hdmi_base + S5P_HDCP_AKSV_0_1); + aksv[3] = readb(hdmi_base + S5P_HDCP_AKSV_0_2); + aksv[4] = readb(hdmi_base + S5P_HDCP_AKSV_0_3); + aksv[5] = readb(hdmi_base + S5P_HDCP_AKSV_1); + + ret = hdcp_i2c_write(hdcp_info.client, aksv, AKSV_SIZE + 1); + + if (ret < 0) + HDCPPRINTK("Can't write aksv data through i2c bus\n"); + +#ifdef S5P_HDCP_AUTH_DEBUG + { + u16 i = 0; + + for (i = 1; i < AKSV_SIZE + 1; i++) + AUTHPRINTK("HDCPAksv[%d]: 0x%x\n", i, aksv[i]); + + } +#endif + + return (ret < 0) ? false : true; +} + +static bool read_bcaps(void) +{ + int ret = 0; + u8 bcaps[BCAPS_SIZE] = {0}; + + ret = hdcp_i2c_read(hdcp_info.client, HDCP_Bcaps, bcaps, BCAPS_SIZE); + + if (ret < 0) { + HDCPPRINTK("Can't read bcaps data from i2c bus\n"); + return false; + } + + writel(bcaps[0], hdmi_base + S5P_HDCP_BCAPS); + + HDCPPRINTK("BCAPS(from i2c) : 0x%08x\n", bcaps[0]); + + if (bcaps[0] & REPEATER_SET) + hdcp_info.is_repeater = true; + else + hdcp_info.is_repeater = false; + + HDCPPRINTK("attached device type : %s !! \n\r", + hdcp_info.is_repeater ? "REPEATER" : "SINK"); + + HDCPPRINTK("BCAPS(from sfr) = 0x%08x\n", + readl(hdmi_base + S5P_HDCP_BCAPS)); + + return true; +} + +static bool read_again_bksv(void) +{ + u8 bk_sv[BKSV_SIZE] = {0, 0, 0, 0, 0}; + u8 i = 0; + u8 j = 0; + u32 no_one = 0; + u32 no_zero = 0; + u32 result = 0; + int ret = 0; + + ret = hdcp_i2c_read(hdcp_info.client, HDCP_Bksv, bk_sv, BKSV_SIZE); + + if (ret < 0) { + HDCPPRINTK("Can't read bk_sv data from i2c bus\n"); + return false; + } + +#ifdef S5P_HDCP_AUTH_DEBUG + for (i = 0; i < BKSV_SIZE; i++) + AUTHPRINTK("i2c read : Bksv[%d]: 0x%x\n", i, bk_sv[i]); + +#endif + + for (i = 0; i < BKSV_SIZE; i++) { + + for (j = 0; j < 8; j++) { + + result = bk_sv[i] & (0x1 << j); + + if (result == 0) + no_zero += 1; + else + no_one += 1; + } + } + + if ((no_zero == 20) && (no_one == 20)) { + HDCPPRINTK("Suucess: no_zero, and no_one is 20\n"); + + writel(bk_sv[0], hdmi_base + S5P_HDCP_BKSV_0_0); + writel(bk_sv[1], hdmi_base + S5P_HDCP_BKSV_0_1); + writel(bk_sv[2], hdmi_base + S5P_HDCP_BKSV_0_2); + writel(bk_sv[3], hdmi_base + S5P_HDCP_BKSV_0_3); + writel(bk_sv[4], hdmi_base + S5P_HDCP_BKSV_1); + +#ifdef S5P_HDCP_AUTH_DEBUG + + for (i = 0; i < BKSV_SIZE; i++) + AUTHPRINTK("set reg : Bksv[%d]: 0x%x\n", i, bk_sv[i]); + +#endif + return true; + } else { + HDCPPRINTK("Failed: no_zero or no_one is NOT 20\n"); + return false; + } +} + +static bool read_bksv(void) +{ + u8 bk_sv[BKSV_SIZE] = {0, 0, 0, 0, 0}; + + int i = 0; + int j = 0; + + u32 no_one = 0; + u32 no_zero = 0; + u32 result = 0; + u32 count = 0; + int ret = 0; + + ret = hdcp_i2c_read(hdcp_info.client, HDCP_Bksv, bk_sv, BKSV_SIZE); + + if (ret < 0) { + HDCPPRINTK("Can't read bk_sv data from i2c bus\n"); + return false; + } + +#ifdef S5P_HDCP_AUTH_DEBUG + for (i = 0; i < BKSV_SIZE; i++) + AUTHPRINTK("i2c read : Bksv[%d]: 0x%x\n", i, bk_sv[i]); + +#endif + + for (i = 0; i < BKSV_SIZE; i++) { + + for (j = 0; j < 8; j++) { + + result = bk_sv[i] & (0x1 << j); + + if (result == 0) + no_zero++; + else + no_one++; + } + } + + if ((no_zero == 20) && (no_one == 20)) { + + writel(bk_sv[0], hdmi_base + S5P_HDCP_BKSV_0_0); + writel(bk_sv[1], hdmi_base + S5P_HDCP_BKSV_0_1); + writel(bk_sv[2], hdmi_base + S5P_HDCP_BKSV_0_2); + writel(bk_sv[3], hdmi_base + S5P_HDCP_BKSV_0_3); + writel(bk_sv[4], hdmi_base + S5P_HDCP_BKSV_1); + +#ifdef S5P_HDCP_AUTH_DEBUG + + for (i = 0; i < BKSV_SIZE; i++) + AUTHPRINTK("set reg : Bksv[%d]: 0x%x\n", i, bk_sv[i]); + +#endif + + HDCPPRINTK("Success: no_zero, and no_one is 20\n"); + + } else { + + HDCPPRINTK("Failed: no_zero or no_one is NOT 20\n"); + + + while (!read_again_bksv()) { + + count++; + + mdelay(20); + + if (count == 140) + return false; + } + } + + return true; +} + +/* + * Compare the R value of Tx with that of Rx + */ +static bool compare_r_val(void) +{ + int ret = 0; + u8 ri[2] = {0, 0}; + u8 rj[2] = {0, 0}; + u16 i; + + for (i = 0; i < R_VAL_RETRY_CNT; i++) { + /* Read R value from Tx */ + ri[0] = readl(hdmi_base + S5P_HDCP_Ri_0); + ri[1] = readl(hdmi_base + S5P_HDCP_Ri_1); + + /* Read R value from Rx */ + ret = hdcp_i2c_read(hdcp_info.client, HDCP_Ri, rj, 2); + + if (ret < 0) { + HDCPPRINTK("Can't read r data from i2c bus\n"); + return false; + } + +#ifdef S5P_HDCP_AUTH_DEBUG + AUTHPRINTK("retries :: %d\n", i); + + printk(KERN_INFO "\t\t\t Rx(ddc) ->"); + + printk(KERN_INFO "rj[0]: 0x%02x, rj[1]: 0x%02x\n", + rj[0], rj[1]); + + printk(KERN_INFO "\t\t\t Tx(register) ->"); + + printk(KERN_INFO "ri[0]: 0x%02x, ri[1]: 0x%02x\n", + ri[0], ri[1]); + +#endif + + /* Compare R value */ + if ((ri[0] == rj[0]) && (ri[1] == rj[1]) && (ri[0] | ri[1])) { + writel(Ri_MATCH_RESULT__YES, + hdmi_base + S5P_HDCP_CHECK_RESULT); + HDCPPRINTK("R0, R0' is matched!!\n"); + ret = true; + break; + } else { + writel(Ri_MATCH_RESULT__NO, + hdmi_base + S5P_HDCP_CHECK_RESULT); + HDCPPRINTK("R0, R0' is not matched!!\n"); + ret = false; + } + + } + + return ret ? true : false; +} + +static bool make_aes_key(void) +{ + u32 aes_reg_val; + + + aes_reg_val = readl(hdmi_base + S5P_HAES_CON); + aes_reg_val = SCRAMBLER_KEY_START_EN; + + /* Start generation of AES key */ + writel(aes_reg_val, hdmi_base + S5P_HAES_CON); + + do { + aes_reg_val = readl(hdmi_base + S5P_HAES_CON); + } while (!(aes_reg_val & SCRAMBLER_KEY_DONE)); + + return true; +} + +/* + * HAES function + */ +static void start_decrypting(const u8 *hdcp_key, u32 hdcp_key_size) +{ + u32 i = 0; + u32 aes_start = 0; + u32 aes_reg_val = 0; + + make_aes_key(); + + writel(hdcp_key_size, hdmi_base + S5P_HAES_DATA_SIZE_L); + + for (i = 0; i < hdcp_key_size; i++) + writel(hdcp_key[i], hdmi_base + S5P_HAES_DATA); + + + aes_reg_val = readl(hdmi_base + S5P_HAES_CON); + + aes_reg_val |= HAES_START_EN; + + writel(aes_reg_val, hdmi_base + S5P_HAES_CON); + + do { + aes_start = readl(hdmi_base + S5P_HAES_CON); + } while (aes_start & HAES_START_EN); +} + +/* + * Start encryption + */ +static void start_encryption(void) +{ + u32 hdcp_status; + + /* Ri == Ri' |Ready the compared result of Ri */ + writel(Ri_MATCH_RESULT__YES, hdmi_base + S5P_HDCP_CHECK_RESULT); + + do { + hdcp_status = readl(hdmi_base + S5P_STATUS); + /* Wait for STATUS[7] to '1'*/ + } while ((hdcp_status & AUTHENTICATED) != AUTHENTICATED); + + /* Start encryption */ + writel(HDCP_ENC_ENABLE, hdmi_base + S5P_ENC_EN); + +} + +/* + * Check whether Rx is repeater or not + */ +static int check_repeater(void) +{ + int ret = 0; + + u8 i = 0; + u16 j = 0; + + u8 bcaps[BCAPS_SIZE] = {0}; + u8 status[BSTATUS_SIZE] = {0, 0}; + u8 rx_v[SHA_1_HASH_SIZE]; + u8 ksv_list[HDCP_MAX_DEVS*HDCP_KSV_SIZE]; + + u32 hdcp_ctrl; + u32 dev_cnt; + u32 stat; + + bool ksv_fifo_ready = false; + + while (j <= 500) { + ret = hdcp_i2c_read(hdcp_info.client, HDCP_Bcaps, + bcaps, BCAPS_SIZE); + + if (ret < 0) { + HDCPPRINTK("Can't read bcaps data from i2c bus\n"); + return false; + } + + if (bcaps[0] & KSV_FIFO_READY) { + HDCPPRINTK("ksv fifo is ready\n"); + ksv_fifo_ready = true; + writel(bcaps[0], hdmi_base + S5P_HDCP_BCAPS); + break; + } else { + HDCPPRINTK("ksv fifo is not ready\n"); + ksv_fifo_ready = false; + mdelay(10); + j++; + } + + } + + if (j == 500) { + HDCPPRINTK("ksv fifo check timeout occurred!!\n"); + return false; + } + + if (ksv_fifo_ready) { + hdcp_ctrl = readl(hdmi_base + S5P_HDCP_CTRL); + hdcp_ctrl &= CLEAR_REPEATER_TIMEOUT; + writel(hdcp_ctrl, hdmi_base + S5P_HDCP_CTRL); + } else + return false; + + /* + * Check MAX_CASCADE_EXCEEDED + * or MAX_DEVS_EXCEEDED indicator + */ + ret = hdcp_i2c_read(hdcp_info.client, HDCP_BStatus, + status, BSTATUS_SIZE); + + if (ret < 0) { + HDCPPRINTK("Can't read status data from i2c bus\n"); + return false; + } + + /* MAX_CASCADE_EXCEEDED || MAX_DEVS_EXCEEDED */ + if (status[1] & MAX_CASCADE_EXCEEDED) { + HDCPPRINTK("MAX_CASCADE_EXCEEDED\n"); + return MAX_CASCADE_EXCEEDED_ERROR; + } else if (status[0] & MAX_DEVS_EXCEEDED) { + HDCPPRINTK("MAX_CASCADE_EXCEEDED\n"); + return MAX_DEVS_EXCEEDED_ERROR; + } + + + writel(status[0], hdmi_base + S5P_HDCP_BSTATUS_0); + + writel(status[1], hdmi_base + S5P_HDCP_BSTATUS_1); + + /* Read KSV list */ + dev_cnt = (*status) & 0x7f; + + HDCPPRINTK("status[0] :0x%08x, status[1] :0x%08x!!\n", + status[0], status[1]); + + if (dev_cnt) { + + u32 val; + + /* read ksv */ + ret = hdcp_i2c_read(hdcp_info.client, HDCP_KSVFIFO, ksv_list, + dev_cnt * HDCP_KSV_SIZE); + + if (ret < 0) { + HDCPPRINTK("Can't read ksv fifo!!\n"); + return false; + } + + /* write ksv */ + for (i = 0; i < dev_cnt; i++) { + + writel(ksv_list[(i*5) + 0], + hdmi_base + S5P_HDCP_RX_KSV_0_0); + writel(ksv_list[(i*5) + 1], + hdmi_base + S5P_HDCP_RX_KSV_0_1); + writel(ksv_list[(i*5) + 2], + hdmi_base + S5P_HDCP_RX_KSV_0_2); + writel(ksv_list[(i*5) + 3], + hdmi_base + S5P_HDCP_RX_KSV_0_3); + writel(ksv_list[(i*5) + 4], + hdmi_base + S5P_HDCP_RX_KSV_0_4); + + if (i != (dev_cnt - 1)) { /* if it's not end */ + /* it's not in manual */ + writel(SET_HDCP_KSV_WRITE_DONE, + S5P_HDCP_RX_KSV_LIST_CTRL); + + mdelay(20); + + /* check ksv readed */ + + do { + if (!hdcp_info.hdcp_enable) + return false; + + stat = readl(hdmi_base + + S5P_HDCP_RX_KSV_LIST_CTRL); + + } while (!(stat & SET_HDCP_KSV_READ)); + + + HDCPPRINTK("read complete\n"); + + } + + HDCPPRINTK("HDCP_RX_KSV_1 = 0x%x\n\r", + readl(hdmi_base + + S5P_HDCP_RX_KSV_LIST_CTRL)); + HDCPPRINTK("i : %d, dev_cnt : %d, val = 0x%08x\n", + i, dev_cnt, val); + } + + /* end of ksv */ + val = readl(hdmi_base + S5P_HDCP_RX_KSV_LIST_CTRL); + + val |= SET_HDCP_KSV_END | SET_HDCP_KSV_WRITE_DONE; + + writel(val, hdmi_base + S5P_HDCP_RX_KSV_LIST_CTRL); + + HDCPPRINTK("HDCP_RX_KSV_1 = 0x%x\n\r", + readl(hdmi_base + S5P_HDCP_RX_KSV_LIST_CTRL)); + + HDCPPRINTK("i : %d, dev_cnt : %d, val = 0x%08x\n", + i, dev_cnt, val); + + } else { + + writel(SET_HDCP_KSV_LIST_EMPTY, + hdmi_base + S5P_HDCP_RX_KSV_LIST_CTRL); + } + + + /* Read SHA-1 from receiver */ + ret = hdcp_i2c_read(hdcp_info.client, HDCP_SHA1, + rx_v, SHA_1_HASH_SIZE); + + if (ret < 0) { + HDCPPRINTK("Can't read sha_1_hash data from i2c bus\n"); + return false; + } + + for (i = 0; i < SHA_1_HASH_SIZE; i++) + HDCPPRINTK("SHA_1 rx :: %x\n", rx_v[i]); + + + /* write SHA-1 to register */ + writel(rx_v[0], hdmi_base + S5P_HDCP_RX_SHA1_0_0); + + writel(rx_v[1], hdmi_base + S5P_HDCP_RX_SHA1_0_1); + + writel(rx_v[2], hdmi_base + S5P_HDCP_RX_SHA1_0_2); + + writel(rx_v[3], hdmi_base + S5P_HDCP_RX_SHA1_0_3); + + writel(rx_v[4], hdmi_base + S5P_HDCP_RX_SHA1_1_0); + + writel(rx_v[5], hdmi_base + S5P_HDCP_RX_SHA1_1_1); + + writel(rx_v[6], hdmi_base + S5P_HDCP_RX_SHA1_1_2); + + writel(rx_v[7], hdmi_base + S5P_HDCP_RX_SHA1_1_3); + + writel(rx_v[8], hdmi_base + S5P_HDCP_RX_SHA1_2_0); + + writel(rx_v[9], hdmi_base + S5P_HDCP_RX_SHA1_2_1); + + writel(rx_v[10], hdmi_base + S5P_HDCP_RX_SHA1_2_2); + + writel(rx_v[11], hdmi_base + S5P_HDCP_RX_SHA1_2_3); + + writel(rx_v[12], hdmi_base + S5P_HDCP_RX_SHA1_3_0); + + writel(rx_v[13], hdmi_base + S5P_HDCP_RX_SHA1_3_1); + + writel(rx_v[14], hdmi_base + S5P_HDCP_RX_SHA1_3_2); + + writel(rx_v[15], hdmi_base + S5P_HDCP_RX_SHA1_3_3); + + writel(rx_v[16], hdmi_base + S5P_HDCP_RX_SHA1_4_0); + + writel(rx_v[17], hdmi_base + S5P_HDCP_RX_SHA1_4_1); + + writel(rx_v[18], hdmi_base + S5P_HDCP_RX_SHA1_4_2); + + writel(rx_v[19], hdmi_base + S5P_HDCP_RX_SHA1_4_3); + + /* SHA write done, and wait for SHA computation being done */ + mdelay(1); + + /* check authentication success or not */ + stat = readl(hdmi_base + S5P_HDCP_AUTH_STATUS); + + HDCPPRINTK("auth status %d\n", stat); + + if (stat & SET_HDCP_SHA_VALID_READY) { + + HDCPPRINTK("SHA valid ready 0x%x \n\r", stat); + + stat = readl(hdmi_base + S5P_HDCP_AUTH_STATUS); + + if (stat & SET_HDCP_SHA_VALID) { + + HDCPPRINTK("SHA valid 0x%x \n\r", stat); + + ret = true; + } else { + HDCPPRINTK("SHA valid ready, but not valid 0x%x \n\r", + stat); + ret = false; + } + + } else { + + HDCPPRINTK("SHA not ready 0x%x \n\r", stat); + ret = false; + } + + + /* clear all validate bit */ + writel(0x0, hdmi_base + S5P_HDCP_AUTH_STATUS); + + return ret; + +} + +/* + * Check whether the HDCP event occurred or not + */ +/* +static bool __s5p_is_occurred_hdcp_event(void) +{ + u32 status_val; + + status_val = readl(hdmi_base + S5P_STATUS); + + return (((status_val == (0x1 << 0) || status_val == (0x1 << 1) || + status_val == (0x1 << 2) || status_val == (0x1 << 3) || + status_val == (0x1 << 4))) ? true : false); +} +*/ + +static bool try_read_receiver(void) +{ + u8 i = 0; + bool ret = false; + + for (i = 0; i < 40; i++) { + + mdelay(250); + + if (hdcp_info.auth_status != RECEIVER_READ_READY) { + + HDCPPRINTK("hdcp stat. changed!!" + "failed attempt no = %d\n\r", i); + + return false; + } + + ret = read_bcaps(); + + if (ret) { + + HDCPPRINTK("succeeded at attempt no= %d \n\r", i); + + return true; + + } else + HDCPPRINTK("can't read bcaps!!" + "failed attempt no=%d\n\r", i); + } + + return false; +} + + +/* + * stop - stop functions are only called under running HDCP + */ +bool __s5p_stop_hdcp(void) +{ + u32 sfr_val; + + HDCPPRINTK("HDCP ftn. Stop!!\n"); + + hdcp_protocol_status = 0; + + hdcp_info.time_out = INFINITE; + hdcp_info.event = HDCP_EVENT_STOP; + hdcp_info.auth_status = NOT_AUTHENTICATED; + hdcp_info.hdcp_enable = false; + + + + /* 3. disable hdcp control reg. */ + sfr_val = readl(hdmi_base + S5P_HDCP_CTRL); + sfr_val &= (ENABLE_1_DOT_1_FEATURE_DIS + & CLEAR_REPEATER_TIMEOUT + & EN_PJ_DIS + & CP_DESIRED_DIS); + writel(sfr_val, hdmi_base + S5P_HDCP_CTRL); + + /* 2. disable aes_data_size & haes_con reg. */ + sfr_val = readl(hdmi_base + S5P_HAES_CON); + sfr_val &= SCRAMBLER_KEY_START_DIS; + writel(sfr_val, hdmi_base + S5P_HAES_CON); + + /* 1-3. disable hdmi hpd reg. */ + writel(CABLE_UNPLUGGED, hdmi_base + S5P_HPD); + + /* 1-2. disable hdmi status enable reg. */ + sfr_val = readl(hdmi_base + S5P_STATUS_EN); + sfr_val &= HDCP_STATUS_DIS_ALL; + writel(sfr_val, hdmi_base + S5P_STATUS_EN); + + /* 1-1. clear all status pending */ + sfr_val = readl(hdmi_base + S5P_STATUS); + sfr_val |= HDCP_STATUS_EN_ALL; + writel(sfr_val, hdmi_base + S5P_STATUS); + + /* disable encryption */ + writel(HDCP_ENC_DISABLE, hdmi_base + S5P_ENC_EN); + + /* clear result */ + writel(Ri_MATCH_RESULT__NO, hdmi_base + S5P_HDCP_CHECK_RESULT); + writel(readl(hdmi_base + S5P_HDMI_CON_0) & HDMI_DIS, + hdmi_base + S5P_HDMI_CON_0); + writel(readl(hdmi_base + S5P_HDMI_CON_0) | HDMI_EN, + hdmi_base + S5P_HDMI_CON_0); + writel(CLEAR_ALL_RESULTS, hdmi_base + S5P_HDCP_CHECK_RESULT); + + /* hdmi disable */ + /* + sfr_val = readl(hdmi_base + S5P_HDMI_CON_0); + sfr_val &= ~(PWDN_ENB_NORMAL | HDMI_EN | ASP_EN); + writel( sfr_val, hdmi_base + S5P_HDMI_CON_0); + */ + HDCPPRINTK("\tSTATUS \t0x%08x\n", readl(hdmi_base + S5P_STATUS)); + HDCPPRINTK("\tSTATUS_EN \t0x%08x\n", readl(hdmi_base + S5P_STATUS_EN)); + HDCPPRINTK("\tHPD \t0x%08x\n", readl(hdmi_base + S5P_HPD)); + HDCPPRINTK("\tHDCP_CTRL \t0x%08x\n", readl(hdmi_base + S5P_HDCP_CTRL)); + HDCPPRINTK("\tMODE_SEL \t0x%08x\n", readl(hdmi_base + S5P_MODE_SEL)); + HDCPPRINTK("\tENC_EN \t0x%08x\n", readl(hdmi_base + S5P_ENC_EN)); + HDCPPRINTK("\tHDMI_CON_0 \t0x%08x\n", + readl(hdmi_base + S5P_HDMI_CON_0)); + + return true; +} + + +void __s5p_hdcp_reset(void) +{ + + __s5p_stop_hdcp(); + + hdcp_protocol_status = 2; + + HDCPPRINTK("HDCP ftn. reset!!\n"); + +} + +/* + * start - start functions are only called under stopping HDCP + */ +bool __s5p_start_hdcp(void) +{ + u32 sfr_val; + + hdcp_info.event = HDCP_EVENT_STOP; + hdcp_info.time_out = INFINITE; + hdcp_info.auth_status = NOT_AUTHENTICATED; + + HDCPPRINTK("HDCP ftn. Start!!\n"); + + hdcp_protocol_status = 1; + + if (!read_bcaps()) { + HDCPPRINTK("can't read ddc port!\n"); + __s5p_hdcp_reset(); + } + + /* for av mute */ + writel(DO_NOT_TRANSMIT, hdmi_base + S5P_GCP_CON); + + /* + * 1-1. set hdmi status enable reg. + * Update_Ri_int_en should be enabled after + * s/w gets ExchangeKSV_int. + */ + writel(HDCP_STATUS_EN_ALL, hdmi_base + S5P_STATUS_EN); + + /* 1-2. set hdmi hpd reg. */ + writel(CABLE_PLUGGED, hdmi_base + S5P_HPD); + + /* + * 1-3. set hdmi offset & cycle_aa reg. + * HDCP memory read cycle count(0x4 is recommanded) + */ + writel(0x00, hdmi_base + S5P_HDCP_OFFSET_TX_0); + + writel(0xA0, hdmi_base + S5P_HDCP_OFFSET_TX_1); + + writel(0x00, hdmi_base + S5P_HDCP_OFFSET_TX_2); + + writel(0x00, hdmi_base + S5P_HDCP_OFFSET_TX_3); + + writel(0x04, hdmi_base + S5P_HDCP_CYCLE_AA); + + /* 2. set aes_data_size & haes_con reg. */ + start_decrypting(hdcp_key, 288); + + /* + * 3. set hdcp control reg. + * Disable advance cipher option, Enable CP(Content Protection), + * Disable time-out (This bit is only available in a REPEATER) + * Disable XOR shift,Disable Pj port update,Use external key + */ + sfr_val = 0; + + sfr_val |= CP_DESIRED_EN; + + writel(sfr_val, hdmi_base + S5P_HDCP_CTRL); + + hdcp_info.hdcp_enable = true; + + HDCPPRINTK("\tSTATUS \t0x%08x\n", readl(hdmi_base + S5P_STATUS)); + + HDCPPRINTK("\tSTATUS_EN \t0x%08x\n", readl(hdmi_base + S5P_STATUS_EN)); + + HDCPPRINTK("\tHPD \t0x%08x\n", readl(hdmi_base + S5P_HPD)); + + HDCPPRINTK("\tHDCP_CTRL \t0x%08x\n", readl(hdmi_base + S5P_HDCP_CTRL)); + + HDCPPRINTK("\tMODE_SEL \t0x%08x\n", readl(hdmi_base + S5P_MODE_SEL)); + + HDCPPRINTK("\tENC_EN \t0x%08x\n", readl(hdmi_base + S5P_ENC_EN)); + + HDCPPRINTK("\tHDMI_CON_0 \t0x%08x\n", + readl(hdmi_base + S5P_HDMI_CON_0)); + + + return true; +} + + +static void bksv_start_bh(void) +{ + bool ret = false; + + HDCPPRINTK("HDCP_EVENT_READ_BKSV_START bh\n"); + + hdcp_info.auth_status = RECEIVER_READ_READY; + + ret = read_bcaps(); + + if (!ret) { + + ret = try_read_receiver(); + + if (!ret) { + HDCPPRINTK("Can't read bcaps!! retry failed!!\n" + "\t\t\t\thdcp ftn. will be stopped\n"); + + __s5p_stop_hdcp(); + return; + } + } + + hdcp_info.auth_status = BCAPS_READ_DONE; + + ret = read_bksv(); + + if (!ret) { + HDCPPRINTK("Can't read bksv!!" + "hdcp ftn. will be reset\n"); + + __s5p_stop_hdcp(); + return; + } + + hdcp_info.auth_status = BKSV_READ_DONE; + + HDCPPRINTK("authentication status : bksv is done (0x%08x)\n", + hdcp_info.auth_status); +} + +static void second_auth_start_bh(void) +{ + u8 count = 0; + bool ret = false; + + int ret_err; + + u32 bcaps; + + HDCPPRINTK("HDCP_EVENT_SECOND_AUTH_START bh\n"); + + ret = read_bcaps(); + + if (!ret) { + + ret = try_read_receiver(); + + if (!ret) { + + HDCPPRINTK("Can't read bcaps!! retry failed!!\n" + "\t\t\t\thdcp ftn. will be stopped\n"); + + __s5p_stop_hdcp(); + return; + } + + } + + bcaps = readl(hdmi_base + S5P_HDCP_BCAPS); + + bcaps &= (KSV_FIFO_READY); + + if (!bcaps) { + + HDCPPRINTK("ksv fifo is not ready\n"); + + do { + count++; + + ret = read_bcaps(); + + if (!ret) { + + ret = try_read_receiver(); + + if (!ret) + __s5p_stop_hdcp(); + + return; + + } + + bcaps = readl(hdmi_base + S5P_HDCP_BCAPS); + + bcaps &= (KSV_FIFO_READY); + + if (bcaps) { + HDCPPRINTK("bcaps retries : %d\n", count); + break; + } + + mdelay(100); + + if (!hdcp_info.hdcp_enable) { + + __s5p_stop_hdcp(); + + return; + + } + + } while (count <= 50); + + /* wait times exceeded 5 seconds */ + if (count > 50) { + + hdcp_info.time_out = INFINITE; + + /* + * time-out (This bit is only available in a REPEATER) + */ + writel(readl(hdmi_base + S5P_HDCP_CTRL) | 0x1 << 2, + hdmi_base + S5P_HDCP_CTRL); + + __s5p_hdcp_reset(); + + return; + } + } + + HDCPPRINTK("ksv fifo ready\n"); + + ret_err = check_repeater(); + + if (ret_err == true) { + u32 flag; + + hdcp_info.auth_status = SECOND_AUTHENTICATION_DONE; + HDCPPRINTK("second authentication done!!\n"); + + flag = readb(hdmi_base + S5P_STATUS); + HDCPPRINTK("hdcp state : %s authenticated!!\n", + flag & AUTHENTICATED ? "" : "not not"); + + + start_encryption(); + } else if (ret_err == false) { + /* i2c error */ + HDCPPRINTK("repeater check error!!\n"); + __s5p_hdcp_reset(); + } else { + if (ret_err == REPEATER_ILLEGAL_DEVICE_ERROR) { + /* + * No need to start the HDCP + * in case of invalid KSV (revocation case) + */ + HDCPPRINTK("illegal dev. error!!\n"); + + __s5p_stop_hdcp(); + } else { + /* + * MAX_CASCADE_EXCEEDED_ERROR + * MAX_DEVS_EXCEEDED_ERROR + */ + HDCPPRINTK("repeater check error(MAX_EXCEEDED)!!\n"); + __s5p_hdcp_reset(); + } + } +} + +static bool write_aksv_start_bh(void) +{ + bool ret = false; + + HDCPPRINTK("HDCP_EVENT_WRITE_AKSV_START bh\n"); + + if (hdcp_info.auth_status != BKSV_READ_DONE) { + HDCPPRINTK("bksv is not ready!!\n"); + return false; + } + + ret = write_ainfo(); + + if (!ret) + return false; + + HDCPPRINTK("ainfo write done!!\n"); + + ret = write_an(); + + if (!ret) + return false; + + hdcp_info.auth_status = AN_WRITE_DONE; + + HDCPPRINTK("an write done!!\n"); + + ret = write_aksv(); + + if (!ret) + return false; + + /* + * Wait for 100ms. Transmitter must not read + * Ro' value sooner than 100ms after writing + * Aksv + */ + mdelay(100); + + hdcp_info.auth_status = AKSV_WRITE_DONE; + + HDCPPRINTK("aksv write done!!\n"); + + return ret; +} + +static bool check_ri_start_bh(void) +{ + bool ret = false; + + + HDCPPRINTK("HDCP_EVENT_CHECK_RI_START bh\n"); + + if (hdcp_info.auth_status == AKSV_WRITE_DONE || + hdcp_info.auth_status == FIRST_AUTHENTICATION_DONE || + hdcp_info.auth_status == SECOND_AUTHENTICATION_DONE) { + + ret = compare_r_val(); + + if (ret) { + + if (hdcp_info.auth_status == AKSV_WRITE_DONE) { + /* + * Check whether HDMI receiver is + * repeater or not + */ + if (hdcp_info.is_repeater) + hdcp_info.auth_status + = SECOND_AUTHENTICATION_RDY; + else { + hdcp_info.auth_status + = FIRST_AUTHENTICATION_DONE; + start_encryption(); + } + } + + } else { + + HDCPPRINTK("authentication reset\n"); + + __s5p_hdcp_reset(); + } + + HDCPPRINTK("auth_status = 0x%08x\n", + + hdcp_info.auth_status); + + + return true; + } + + HDCPPRINTK("aksv_write or first/second" + + " authentication is not done\n"); + + return false; +} + +/* + * bottom half for hdmi interrupt + * + */ +static void hdcp_work(void *arg) +{ + + /* + * I2C int. was occurred + * for reading Bksv and Bcaps + */ + + if (hdcp_info.event & (1 << HDCP_EVENT_READ_BKSV_START)) { + + bksv_start_bh(); + + /* clear event */ + hdcp_info.event &= ~(1 << HDCP_EVENT_READ_BKSV_START); + } + + /* + * Watchdog timer int. was occurred + * for checking repeater + */ + if (hdcp_info.event & (1 << HDCP_EVENT_SECOND_AUTH_START)) { + + second_auth_start_bh(); + + /* clear event */ + hdcp_info.event &= ~(1 << HDCP_EVENT_SECOND_AUTH_START); + } + + /* + * An_Write int. was occurred + * for writing Ainfo, An and Aksv + */ + if (hdcp_info.event & (1 << HDCP_EVENT_WRITE_AKSV_START)) { + + write_aksv_start_bh(); + + /* clear event */ + hdcp_info.event &= ~(1 << HDCP_EVENT_WRITE_AKSV_START); + } + + /* + * Ri int. was occurred + * for comparing Ri and Ri'(from HDMI sink) + */ + if (hdcp_info.event & (1 << HDCP_EVENT_CHECK_RI_START)) { + + + check_ri_start_bh(); + + /* clear event */ + hdcp_info.event &= ~(1 << HDCP_EVENT_CHECK_RI_START); + } + +} + +void __s5p_init_hdcp(bool hpd_status, struct i2c_client *ddc_port) +{ + + HDCPPRINTK("HDCP ftn. Init!!\n"); + + hdcp_info.client = ddc_port; + + /* for bh */ + INIT_WORK(&hdcp_info.work, (work_func_t)hdcp_work); + + init_waitqueue_head(&hdcp_info.waitq); + + /* for dev_dbg err. */ + spin_lock_init(&hdcp_info.lock); + +} + +/* + * HDCP ISR. + * If HDCP IRQ occurs, set hdcp_event and wake up the waitqueue. + */ +irqreturn_t __s5p_hdmi_irq(int irq, void *dev_id) +{ + u8 flag; + u32 event; + + event = 0; + + /* check HDCP Status */ + flag = readb(hdmi_base + S5P_STATUS); + HDCPPRINTK("irq_status : 0x%08x\n", readb(hdmi_base + S5P_STATUS)); + + HDCPPRINTK("hdcp state : %s authenticated!!\n", + flag & AUTHENTICATED ? "" : "not not"); + + spin_lock_irq(&hdcp_info.lock); + + /* + * processing interrupt + * interrupt processing seq. is firstly set event for workqueue, + * and interrupt pending clear. 'flag|' was used for preventing + * to clear AUTHEN_ACK.- it caused many problem. be careful. + */ + /* I2C INT */ + + if (flag & WTFORACTIVERX_INT_OCCURRED) { + event |= (1 << HDCP_EVENT_READ_BKSV_START); + writeb(flag | WTFORACTIVERX_INT_OCCURRED, + hdmi_base + S5P_STATUS); + } + + /* AN INT */ + if (flag & EXCHANGEKSV_INT_OCCURRED) { + event |= (1 << HDCP_EVENT_WRITE_AKSV_START); + writeb(flag | EXCHANGEKSV_INT_OCCURRED, + hdmi_base + S5P_STATUS); + } + + /* RI INT */ + if (flag & UPDATE_RI_INT_OCCURRED) { + event |= (1 << HDCP_EVENT_CHECK_RI_START); + writeb(flag | UPDATE_RI_INT_OCCURRED, + hdmi_base + S5P_STATUS); + } + + /* WATCHDOG INT */ + if (flag & WATCHDOG_INT_OCCURRED) { + event |= (1 << HDCP_EVENT_SECOND_AUTH_START); + writeb(flag | WATCHDOG_INT_OCCURRED, + hdmi_base + S5P_STATUS); + } + + if (!event) { + HDCPPRINTK("unknown irq.\n"); + return IRQ_HANDLED; + } + + hdcp_info.event |= event; + + schedule_work(&hdcp_info.work); + + spin_unlock_irq(&hdcp_info.lock); + + return IRQ_HANDLED; +} + +bool __s5p_set_hpd_detection(bool detection, bool hdcp_enabled, + struct i2c_client *client) +{ + u32 hpd_reg_val = 0; + + /* hdcp_enabled is status of tvout_sys */ + /* + if (hdcp_enabled) { + if (detection) { + hdcp_info.client = client; + __s5p_start_hdcp(); + } else { + hdcp_info.client = NULL; + __s5p_stop_hdcp(); + } + } else { + */ + + if (detection) + hpd_reg_val = CABLE_PLUGGED; + else + hpd_reg_val = CABLE_UNPLUGGED; + + + writel(hpd_reg_val, hdmi_base + S5P_HPD); + + HDCPPRINTK("HPD status :: 0x%08x\n\r", + readl(hdmi_base + S5P_HPD)); + + return true; +} diff --git a/drivers/media/video/samsung/tv20/s5pc100/hdmi_s5pc100.c b/drivers/media/video/samsung/tv20/s5pc100/hdmi_s5pc100.c new file mode 100644 index 0000000..8b41b8b --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5pc100/hdmi_s5pc100.c @@ -0,0 +1,1435 @@ +/* linux/drivers/media/video/samsung/tv20/s5pc100/hdmi_s5pc100.c + * + * hdmi raw ftn file for Samsung TVOut driver + * + * Copyright (c) 2009 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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/i2c.h> +#include <linux/platform_device.h> +#include <linux/io.h> + +#include "tv_out_s5pc100.h" + +#include "regs/regs-hdmi.h" + +#include "plat/regs-clock.h" + +#ifdef COFIG_TVOUT_RAW_DBG +#define S5P_HDMI_DEBUG 1 +#endif + +#ifdef S5P_HDMI_DEBUG +#define HDMIPRINTK(fmt, args...) \ + printk(KERN_INFO "\t\t[HDMI] %s: " fmt, __func__ , ## args) +#else +#define HDMIPRINTK(fmt, args...) +#endif + +static struct resource *hdmi_mem; +void __iomem *hdmi_base; + +static unsigned short g_hdmi_video_parm_tbl[] = { + /* 480P_60, 576P_50, 720P_60, 720P_50, 1080I_60, 1080I_50, VGAP_60*/ + 138, 144, 370, 700, 280, 720, 160, + 525, 625, 750, 750, 562, 562, 525, + 45, 49, 30, 30, 22, 22, 45, + 525, 625, 750, 750, 1125, 1125, 525, + 858, 864, 1650, 1980, 2200, 2640, 800, + 1, 1, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 585, 585, 0, + 0, 0, 0, 0, 1125, 1125, 0, + 14, 10, 108, 438, 86, 526, 14, + 76, 74, 148, 478, 130, 570, 110, + 1, 1, 0, 0, 0, 0, 1, + 15, 10, 10, 10, 7, 7, 12, + 9, 5, 5, 5, 2, 2, 10, + 0, 0, 0, 0, 569, 569, 0, + 0, 0, 0, 0, 564, 564, 0, + 0, 0, 0, 0, 1187, 1847, 0, + 0, 0, 0, 0, 1187, 1847, 0, + 858, 864, 1650, 1980, 2200, 2640, 800 + 138, 144, 370, 700, 280, 720, 160, + 720, 720, 1280, 1280, 1920, 1920, 640, + 525, 625, 750, 750, 1125, 1125, 525, + 7, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 563, 563, 0, + 45, 49, 30, 30, 22, 22, 45, + 480, 576, 720, 720, 540, 540, 480, + 0, 0, 0, 0, 563, 563, 0, + 0, 0, 0, 0, 584, 584, 0, + 7, 1, 1, 1, 1, 1, 1, + 7, 1, 1, 1, 563, 563, 1, + 7, 1, 1, 1, 1, 1, 1, + 7, 1, 1, 1, 563, 563, 1 +}; + + + +/* +* set - set functions are only called under running HDMI +*/ +void __s5p_hdmi_set_hpd_onoff(bool on_off) +{ + HDMIPRINTK("%d\n\r", on_off); + + if (on_off) + writel(SW_HPD_PLUGGED, hdmi_base + S5P_HPD); + else + writel(SW_HPD_UNPLUGGED, hdmi_base + S5P_HPD); + + + HDMIPRINTK("0x%08x\n\r", readl(hdmi_base + S5P_HPD)); +} + + +void __s5p_hdmi_audio_set_config(enum s5p_tv_audio_codec_type audio_codec) +{ + + u32 data_type = (audio_codec == PCM) ? CONFIG_LINEAR_PCM_TYPE : + (audio_codec == AC3) ? CONFIG_NON_LINEAR_PCM_TYPE : + 0xff; + + HDMIPRINTK("(%d)\n\r", audio_codec); + + writel(CONFIG_FILTER_2_SAMPLE | data_type + | CONFIG_PCPD_MANUAL_SET | CONFIG_WORD_LENGTH_MANUAL_SET + | CONFIG_U_V_C_P_REPORT | CONFIG_BURST_SIZE_2 + | CONFIG_DATA_ALIGN_32BIT + , hdmi_base + S5P_SPDIFIN_CONFIG_1); + writel(0, hdmi_base + S5P_SPDIFIN_CONFIG_2); + HDMIPRINTK("()\n\r"); +} + +void __s5p_hdmi_audio_set_acr(u32 sample_rate) +{ + u32 value_n = (sample_rate == 32000) ? 4096 : + (sample_rate == 44100) ? 6272 : + (sample_rate == 88200) ? 12544 : + (sample_rate == 176400) ? 25088 : + (sample_rate == 48000) ? 6144 : + (sample_rate == 96000) ? 12288 : + (sample_rate == 192000) ? 24576 : 0; + + u32 cts = (sample_rate == 32000) ? 27000 : + (sample_rate == 44100) ? 30000 : + (sample_rate == 88200) ? 30000 : + (sample_rate == 176400) ? 30000 : + (sample_rate == 48000) ? 27000 : + (sample_rate == 96000) ? 27000 : + (sample_rate == 192000) ? 27000 : 0; + + HDMIPRINTK("(%d)\n\r", sample_rate); + + writel(value_n & 0xff, hdmi_base + S5P_ACR_N0); + writel((value_n >> 8) & 0xff, hdmi_base + S5P_ACR_N1); + writel((value_n >> 16) & 0xff, hdmi_base + S5P_ACR_N2); + + writel(cts & 0xff, hdmi_base + S5P_ACR_MCTS0); + writel((cts >> 8) & 0xff, hdmi_base + S5P_ACR_MCTS1); + writel((cts >> 16) & 0xff, hdmi_base + S5P_ACR_MCTS2); + + writel(cts & 0xff, hdmi_base + S5P_ACR_CTS0); + writel((cts >> 8) & 0xff, hdmi_base + S5P_ACR_CTS1); + writel((cts >> 16) & 0xff, hdmi_base + S5P_ACR_CTS2); + + writel(4, hdmi_base + S5P_ACR_CON); + + HDMIPRINTK("()\n\r"); +} + +void __s5p_hdmi_audio_set_asp(void) +{ + HDMIPRINTK("()\n\r"); + writel(0x0, hdmi_base + S5P_ASP_CON); + writel(0x0, hdmi_base + S5P_ASP_SP_FLAT); + + writel(1 << 3 | 0, hdmi_base + S5P_ASP_CHCFG0); + writel(1 << 3 | 0, hdmi_base + S5P_ASP_CHCFG1); + writel(1 << 3 | 0, hdmi_base + S5P_ASP_CHCFG2); + writel(1 << 3 | 0, hdmi_base + S5P_ASP_CHCFG3); + HDMIPRINTK("()\n\r"); +} + +void __s5p_hdmi_audio_clock_enable(void) +{ + HDMIPRINTK("()\n\r"); + writel(0x1, hdmi_base + S5P_SPDIFIN_CLK_CTRL); + writel(0x3, hdmi_base + S5P_SPDIFIN_OP_CTRL); + HDMIPRINTK("()\n\r"); +} + +void __s5p_hdmi_audio_set_repetition_time( + enum s5p_tv_audio_codec_type audio_codec, + u32 bits, u32 frame_size_code) +{ + u32 wl = 5 << 1 | 1; + u32 rpt_cnt = (audio_codec == AC3) ? 1536 * 2 - 1 : 0; + + HDMIPRINTK("()\n\r"); + + writel(((rpt_cnt&0xf) << 4) | wl, + hdmi_base + S5P_SPDIFIN_USER_VALUE_1); + writel((rpt_cnt >> 4)&0xff, hdmi_base + S5P_SPDIFIN_USER_VALUE_2); + writel(frame_size_code&0xff, hdmi_base + S5P_SPDIFIN_USER_VALUE_3); + writel((frame_size_code >> 8)&0xff, + hdmi_base + S5P_SPDIFIN_USER_VALUE_4); + HDMIPRINTK("()\n\r"); +} + + + +void __s5p_hdmi_audio_irq_enable(u32 irq_en) +{ + writel(irq_en, hdmi_base + S5P_SPDIFIN_IRQ_MASK); +} + + +void __s5p_hdmi_audio_set_aui(enum s5p_tv_audio_codec_type audio_codec, + u32 sample_rate, + u32 bits) +{ + u8 sum_of_bits, bytes1, bytes2, bytes3, check_sum; + u32 bit_rate; + u32 bps = (audio_codec == PCM) ? bits : 16; + + u32 type = (audio_codec == PCM) ? 1 : + (audio_codec == AC3) ? 2 : 0; + u32 ch = (audio_codec == PCM) ? 1 : 0; + + u32 sample = (sample_rate == 32000) ? 1 : + (sample_rate == 44100) ? 2 : + (sample_rate == 48000) ? 3 : + (sample_rate == 88200) ? 4 : + (sample_rate == 96000) ? 5 : + (sample_rate == 176400) ? 6 : + (sample_rate == 192000) ? 7 : 0; + + u32 bpsType = (bps == 16) ? 1 : + (bps == 20) ? 2 : + (bps == 24) ? 3 : 0; + + HDMIPRINTK("()\n\r"); + + bpsType = (audio_codec == PCM) ? bpsType : 0; + + sum_of_bits = (0x84 + 0x1 + 10); + + bytes1 = (u8)((type << 4) | ch); + + bytes2 = (u8)((sample << 2) | bpsType); + + bit_rate = 256; + + bytes3 = (audio_codec == PCM) ? (u8)0 : (u8)(bit_rate / 8) ; + + + sum_of_bits += (bytes1 + bytes2 + bytes3); + check_sum = 256 - sum_of_bits; + + writel(check_sum , hdmi_base + S5P_AUI_CHECK_SUM); + writel(bytes1 , hdmi_base + S5P_AUI_BYTE1); + writel(bytes2 , hdmi_base + S5P_AUI_BYTE2); + writel(bytes3 , hdmi_base + S5P_AUI_BYTE3); + writel(0x00 , hdmi_base + S5P_AUI_BYTE4); + writel(0x00 , hdmi_base + S5P_AUI_BYTE5); + + + writel(2 , hdmi_base + S5P_ACP_CON); + writel(1 , hdmi_base + S5P_ACP_TYPE); + + writel(0x10 , hdmi_base + S5P_GCP_BYTE1); + writel(0x2 , hdmi_base + S5P_GCP_CON); + + HDMIPRINTK("()\n\r"); + +} + +void __s5p_hdmi_video_set_bluescreen(bool en, + u8 cb_b, + u8 y_g, + u8 cr_r) +{ + HDMIPRINTK("%d,%d,%d,%d\n\r", en, cb_b, y_g, cr_r); + + if (en) { + writel(SET_BLUESCREEN_0(cb_b), hdmi_base + S5P_BLUE_SCREEN_0); + writel(SET_BLUESCREEN_1(y_g), hdmi_base + S5P_BLUE_SCREEN_1); + writel(SET_BLUESCREEN_2(cr_r), hdmi_base + S5P_BLUE_SCREEN_2); + writel(readl(hdmi_base + S5P_HDMI_CON_0) | BLUE_SCR_EN, + hdmi_base + S5P_HDMI_CON_0); + + HDMIPRINTK("HDMI_BLUE_SCREEN0 = 0x%08x \n\r", + readl(hdmi_base + S5P_BLUE_SCREEN_0)); + HDMIPRINTK("HDMI_BLUE_SCREEN1 = 0x%08x \n\r", + readl(hdmi_base + S5P_BLUE_SCREEN_1)); + HDMIPRINTK("HDMI_BLUE_SCREEN2 = 0x%08x \n\r", + readl(hdmi_base + S5P_BLUE_SCREEN_2)); + } else { + writel(readl(hdmi_base + S5P_HDMI_CON_0)&~BLUE_SCR_EN, + hdmi_base + S5P_HDMI_CON_0); + } + + HDMIPRINTK("HDMI_CON0 = 0x%08x \n\r", + readl(hdmi_base + S5P_HDMI_CON_0)); +} + + +/* +* initialization - iniization functions are only called under stopping HDMI +*/ +enum s5p_tv_hdmi_err __s5p_hdmi_init_spd_infoframe( + enum s5p_hdmi_transmit trans_type, + u8 *spd_header, + u8 *spd_data) +{ + HDMIPRINTK("%d,%d,%d\n\r", (u32)trans_type, + (u32)spd_header, + (u32)spd_data); + + switch (trans_type) { + + case HDMI_DO_NOT_TANS: + writel(SPD_TX_CON_NO_TRANS, hdmi_base + S5P_SPD_CON); + break; + + case HDMI_TRANS_ONCE: + writel(SPD_TX_CON_TRANS_ONCE, hdmi_base + S5P_SPD_CON); + break; + + case HDMI_TRANS_EVERY_SYNC: + writel(SPD_TX_CON_TRANS_EVERY_VSYNC, hdmi_base + S5P_SPD_CON); + break; + + default: + HDMIPRINTK(" invalid out_mode parameter(%d)\n\r", trans_type); + return S5P_TV_HDMI_ERR_INVALID_PARAM; + break; + } + + writel(SET_SPD_HEADER(*(spd_header)), hdmi_base + S5P_SPD_HEADER0); + + writel(SET_SPD_HEADER(*(spd_header + 1)) , hdmi_base + S5P_SPD_HEADER1); + writel(SET_SPD_HEADER(*(spd_header + 2)) , hdmi_base + S5P_SPD_HEADER2); + + writel(SET_SPD_DATA(*(spd_data)), hdmi_base + S5P_SPD_DATA0); + writel(SET_SPD_DATA(*(spd_data + 1)) , hdmi_base + S5P_SPD_DATA1); + writel(SET_SPD_DATA(*(spd_data + 2)) , hdmi_base + S5P_SPD_DATA2); + writel(SET_SPD_DATA(*(spd_data + 3)) , hdmi_base + S5P_SPD_DATA3); + writel(SET_SPD_DATA(*(spd_data + 4)) , hdmi_base + S5P_SPD_DATA4); + writel(SET_SPD_DATA(*(spd_data + 5)) , hdmi_base + S5P_SPD_DATA5); + writel(SET_SPD_DATA(*(spd_data + 6)) , hdmi_base + S5P_SPD_DATA6); + writel(SET_SPD_DATA(*(spd_data + 7)) , hdmi_base + S5P_SPD_DATA7); + writel(SET_SPD_DATA(*(spd_data + 8)) , hdmi_base + S5P_SPD_DATA8); + writel(SET_SPD_DATA(*(spd_data + 9)) , hdmi_base + S5P_SPD_DATA9); + writel(SET_SPD_DATA(*(spd_data + 10)) , hdmi_base + S5P_SPD_DATA10); + writel(SET_SPD_DATA(*(spd_data + 11)) , hdmi_base + S5P_SPD_DATA11); + writel(SET_SPD_DATA(*(spd_data + 12)) , hdmi_base + S5P_SPD_DATA12); + writel(SET_SPD_DATA(*(spd_data + 13)) , hdmi_base + S5P_SPD_DATA13); + writel(SET_SPD_DATA(*(spd_data + 14)) , hdmi_base + S5P_SPD_DATA14); + writel(SET_SPD_DATA(*(spd_data + 15)) , hdmi_base + S5P_SPD_DATA15); + writel(SET_SPD_DATA(*(spd_data + 16)) , hdmi_base + S5P_SPD_DATA16); + writel(SET_SPD_DATA(*(spd_data + 17)) , hdmi_base + S5P_SPD_DATA17); + writel(SET_SPD_DATA(*(spd_data + 18)) , hdmi_base + S5P_SPD_DATA18); + writel(SET_SPD_DATA(*(spd_data + 19)) , hdmi_base + S5P_SPD_DATA19); + writel(SET_SPD_DATA(*(spd_data + 20)) , hdmi_base + S5P_SPD_DATA20); + writel(SET_SPD_DATA(*(spd_data + 21)) , hdmi_base + S5P_SPD_DATA21); + writel(SET_SPD_DATA(*(spd_data + 22)) , hdmi_base + S5P_SPD_DATA22); + writel(SET_SPD_DATA(*(spd_data + 23)) , hdmi_base + S5P_SPD_DATA23); + writel(SET_SPD_DATA(*(spd_data + 24)) , hdmi_base + S5P_SPD_DATA24); + writel(SET_SPD_DATA(*(spd_data + 25)) , hdmi_base + S5P_SPD_DATA25); + writel(SET_SPD_DATA(*(spd_data + 26)) , hdmi_base + S5P_SPD_DATA26); + writel(SET_SPD_DATA(*(spd_data + 27)) , hdmi_base + S5P_SPD_DATA27); + + HDMIPRINTK("SPD_CON = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_CON)); + HDMIPRINTK("SPD_HEADER0 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_HEADER0)); + HDMIPRINTK("SPD_HEADER1 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_HEADER1)); + HDMIPRINTK("SPD_HEADER2 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_HEADER2)); + HDMIPRINTK("SPD_DATA0 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA0)); + HDMIPRINTK("SPD_DATA1 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA1)); + HDMIPRINTK("SPD_DATA2 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA2)); + HDMIPRINTK("SPD_DATA3 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA3)); + HDMIPRINTK("SPD_DATA4 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA4)); + HDMIPRINTK("SPD_DATA5 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA5)); + HDMIPRINTK("SPD_DATA6 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA6)); + HDMIPRINTK("SPD_DATA7 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA7)); + HDMIPRINTK("SPD_DATA8 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA8)); + HDMIPRINTK("SPD_DATA9 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA9)); + HDMIPRINTK("SPD_DATA10 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA10)); + HDMIPRINTK("SPD_DATA11 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA11)); + HDMIPRINTK("SPD_DATA12 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA12)); + HDMIPRINTK("SPD_DATA13 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA13)); + HDMIPRINTK("SPD_DATA14 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA14)); + HDMIPRINTK("SPD_DATA15 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA15)); + HDMIPRINTK("SPD_DATA16 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA16)); + HDMIPRINTK("SPD_DATA17 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA17)); + HDMIPRINTK("SPD_DATA18 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA18)); + HDMIPRINTK("SPD_DATA19 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA19)); + HDMIPRINTK("SPD_DATA20 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA20)); + HDMIPRINTK("SPD_DATA21 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA21)); + HDMIPRINTK("SPD_DATA22 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA22)); + HDMIPRINTK("SPD_DATA23 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA23)); + HDMIPRINTK("SPD_DATA24 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA24)); + HDMIPRINTK("SPD_DATA25 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA25)); + HDMIPRINTK("SPD_DATA26 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA26)); + HDMIPRINTK("SPD_DATA27 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA27)); + + return HDMI_NO_ERROR; +} + +void __s5p_hdmi_init_hpd_onoff(bool on_off) +{ + HDMIPRINTK("%d\n\r", on_off); + __s5p_hdmi_set_hpd_onoff(on_off); + HDMIPRINTK("0x%08x\n\r", readl(hdmi_base + S5P_HPD)); +} + +enum s5p_tv_hdmi_err __s5p_hdmi_audio_init( + enum s5p_tv_audio_codec_type audio_codec, + u32 sample_rate, u32 bits, u32 frame_size_code) +{ + __s5p_hdmi_audio_set_config(audio_codec); + __s5p_hdmi_audio_set_repetition_time(audio_codec, bits, + frame_size_code); + __s5p_hdmi_audio_irq_enable(IRQ_BUFFER_OVERFLOW_ENABLE); + __s5p_hdmi_audio_clock_enable(); + __s5p_hdmi_audio_set_asp(); + __s5p_hdmi_audio_set_acr(sample_rate); + __s5p_hdmi_audio_set_aui(audio_codec, sample_rate, bits); + + return HDMI_NO_ERROR; +} + +enum s5p_tv_hdmi_err __s5p_hdmi_video_init_display_mode( + enum s5p_tv_disp_mode disp_mode, + enum s5p_tv_o_mode out_mode) +{ + enum s5p_tv_hdmi_disp_mode hdmi_disp_num; + + HDMIPRINTK("%d,%d\n\r", disp_mode, out_mode); + + switch (disp_mode) { + + case TVOUT_480P_60_16_9: + + case TVOUT_480P_60_4_3: + + case TVOUT_576P_50_16_9: + + case TVOUT_576P_50_4_3: + + case TVOUT_720P_60: + + case TVOUT_720P_50: + writel(INT_PRO_MODE_PROGRESSIVE, hdmi_base + S5P_INT_PRO_MODE); + break; + + default: + HDMIPRINTK("invalid disp_mode parameter(%d)\n\r", disp_mode); + return S5P_TV_HDMI_ERR_INVALID_PARAM; + break; + } + + switch (disp_mode) { + + case TVOUT_480P_60_16_9: + + case TVOUT_480P_60_4_3: + hdmi_disp_num = S5P_TV_HDMI_DISP_MODE_480P_60; + break; + + case TVOUT_576P_50_16_9: + + case TVOUT_576P_50_4_3: + hdmi_disp_num = S5P_TV_HDMI_DISP_MODE_576P_50; + break; + + case TVOUT_720P_60: + hdmi_disp_num = S5P_TV_HDMI_DISP_MODE_720P_60; + break; + + case TVOUT_720P_50: + hdmi_disp_num = S5P_TV_HDMI_DISP_MODE_720P_50; + break; + + default: + HDMIPRINTK(" invalid disp_mode parameter(%d)\n\r", disp_mode); + return S5P_TV_HDMI_ERR_INVALID_PARAM; + break; + } + + switch (out_mode) { + + case TVOUT_OUTPUT_HDMI: + writel(PX_LMT_CTRL_BYPASS, hdmi_base + S5P_HDMI_CON_1); + writel(VID_PREAMBLE_EN | GUARD_BAND_EN, + hdmi_base + S5P_HDMI_CON_2); + writel(HDMI_MODE_EN | DVI_MODE_DIS, hdmi_base + S5P_MODE_SEL); + break; + + default: + HDMIPRINTK("invalid out_mode parameter(%d)\n\r", out_mode); + return S5P_TV_HDMI_ERR_INVALID_PARAM; + break; + } + + writel(0x2b, hdmi_base + S5P_VACT_ST_MG); + + writel(0x30, hdmi_base + S5P_VACT_END_MG); + + writel(SET_H_BLANK_L(g_hdmi_video_parm_tbl + [H_BLANK*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_H_BLANK_0); + writel(SET_H_BLANK_H(g_hdmi_video_parm_tbl + [H_BLANK*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_H_BLANK_1); + + writel(SET_V2_BLANK_L(g_hdmi_video_parm_tbl + [V2_BLANK*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_V_BLANK_0); + writel(SET_V2_BLANK_H(g_hdmi_video_parm_tbl + [V2_BLANK*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]) | + SET_V1_BLANK_L(g_hdmi_video_parm_tbl + [V1_BLANK*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_V_BLANK_1); + writel(SET_V1_BLANK_H(g_hdmi_video_parm_tbl + [V1_BLANK*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_V_BLANK_2); + + writel(SET_V_LINE_L(g_hdmi_video_parm_tbl + [V_LINE*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_H_V_LINE_0); + writel(SET_V_LINE_H(g_hdmi_video_parm_tbl + [V_LINE*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]) | + SET_H_LINE_L(g_hdmi_video_parm_tbl + [H_LINE*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_H_V_LINE_1); + writel(SET_H_LINE_H(g_hdmi_video_parm_tbl + [H_LINE*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_H_V_LINE_2); + + writel(g_hdmi_video_parm_tbl + [VSYNC_POL*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num], + hdmi_base + S5P_SYNC_MODE); + + writel(0xfd, hdmi_base + S5P_SEND_PER_START0); + writel(0x01, hdmi_base + S5P_SEND_PER_START1); + writel(0x0d, hdmi_base + S5P_SEND_PER_END0); + writel(0x3a, hdmi_base + S5P_SEND_PER_END1); + writel(0x08, hdmi_base + S5P_SEND_PER_END2); + + writel(SET_V_BOT_ST_L(g_hdmi_video_parm_tbl + [V_BOT_ST*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_V_BLANK_F_0); + writel(SET_V_BOT_ST_H(g_hdmi_video_parm_tbl + [V_BOT_ST*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]) | + SET_V_BOT_END_L(g_hdmi_video_parm_tbl + [V_BOT_END*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_V_BLANK_F_1); + writel(SET_V_BOT_END_H(g_hdmi_video_parm_tbl + [V_BOT_END*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_V_BLANK_F_2); + + + writel(SET_HSYNC_START_L(g_hdmi_video_parm_tbl + [HSYNC_START*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_H_SYNC_GEN_0); + writel(SET_HSYNC_START_H(g_hdmi_video_parm_tbl + [HSYNC_START*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]) | + SET_HSYNC_END_L(g_hdmi_video_parm_tbl + [HSYNC_END*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_H_SYNC_GEN_1); + writel(SET_HSYNC_END_H(g_hdmi_video_parm_tbl + [HSYNC_END*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]) | + ((g_hdmi_video_parm_tbl + [HSYNC_POL*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]) ? + SET_HSYNC_POL_ACT_LOW : SET_HSYNC_POL_ACT_HIGH) , + hdmi_base + S5P_H_SYNC_GEN_2); + + + writel(SET_VSYNC_T_END_L(g_hdmi_video_parm_tbl + [VSYNC_T_END*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_V_SYNC_GEN_1_0); + writel(SET_VSYNC_T_END_H(g_hdmi_video_parm_tbl + [VSYNC_T_END*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]) | + SET_VSYNC_T_ST_L(g_hdmi_video_parm_tbl + [VSYNC_T_START*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + + hdmi_base + S5P_V_SYNC_GEN_1_1); + writel(SET_VSYNC_T_ST_H(g_hdmi_video_parm_tbl + [VSYNC_T_START*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_V_SYNC_GEN_1_2); + + writel(SET_VSYNC_B_END_L(g_hdmi_video_parm_tbl + [VSYNC_B_END*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_V_SYNC_GEN_2_0); + writel(SET_VSYNC_B_END_H(g_hdmi_video_parm_tbl + [VSYNC_B_END*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]) | + SET_VSYNC_B_ST_L(g_hdmi_video_parm_tbl + [VSYNC_B_START*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_V_SYNC_GEN_2_1); + writel(SET_VSYNC_B_ST_H(g_hdmi_video_parm_tbl + [VSYNC_B_START*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_V_SYNC_GEN_2_2); + + writel(SET_VSYNC_H_POST_END_L(g_hdmi_video_parm_tbl + [VSYNC_h_POS_END*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_V_SYNC_GEN_3_0); + + writel(SET_VSYNC_H_POST_END_H(g_hdmi_video_parm_tbl + [VSYNC_h_POS_END*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]) | + SET_VSYNC_H_POST_ST_L(g_hdmi_video_parm_tbl + [VSYNC_h_POS_START*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_V_SYNC_GEN_3_1); + + writel(SET_VSYNC_H_POST_ST_H(g_hdmi_video_parm_tbl + [VSYNC_h_POS_START*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_V_SYNC_GEN_3_2); + + + writel(0 , hdmi_base + S5P_TG_CMD); + writel(SET_TG_H_FSZ_L(g_hdmi_video_parm_tbl + [TG_H_FSZ*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]) , + hdmi_base + S5P_TG_H_FSZ_L); + writel(SET_TG_H_FSZ_H(g_hdmi_video_parm_tbl + [TG_H_FSZ*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]) , + hdmi_base + S5P_TG_H_FSZ_H); + + writel(SET_TG_HACT_ST_L(g_hdmi_video_parm_tbl + [TG_HACT_START*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]) , + hdmi_base + S5P_TG_HACT_ST_L); + writel(SET_TG_HACT_ST_H(g_hdmi_video_parm_tbl + [TG_HACT_START*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_TG_HACT_ST_H); + writel(SET_TG_HACT_SZ_L(g_hdmi_video_parm_tbl + [TG_HACT_SZ*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_TG_HACT_SZ_L); + writel(SET_TG_HACT_SZ_H(g_hdmi_video_parm_tbl + [TG_HACT_SZ*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_TG_HACT_SZ_H); + + + writel(SET_TG_V_FSZ_L(g_hdmi_video_parm_tbl + [TG_V_FSZ*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_TG_V_FSZ_L); + writel(SET_TG_V_FSZ_H(g_hdmi_video_parm_tbl + [TG_V_FSZ*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_TG_V_FSZ_H); + writel(SET_TG_VSYNC_L(g_hdmi_video_parm_tbl + [TG_VSYNC*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_TG_VSYNC_L); + writel(SET_TG_VSYNC_H(g_hdmi_video_parm_tbl + [TG_VSYNC*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_TG_VSYNC_H); + writel(SET_TG_VSYNC2_L(g_hdmi_video_parm_tbl + [TG_VSYNC2*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_TG_VSYNC2_L); + writel(SET_TG_VSYNC2_H(g_hdmi_video_parm_tbl + [TG_VSYNC2*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_TG_VSYNC2_H); + + writel(SET_TG_VACT_ST_L(g_hdmi_video_parm_tbl + [TG_VACT_START*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_TG_VACT_ST_L); + writel(SET_TG_VACT_ST_H(g_hdmi_video_parm_tbl + [TG_VACT_START*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_TG_VACT_ST_H); + writel(SET_TG_VACT_SZ_L(g_hdmi_video_parm_tbl + [TG_VACT_SZ*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_TG_VACT_SZ_L); + writel(SET_TG_VACT_SZ_H(g_hdmi_video_parm_tbl + [TG_VACT_SZ*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_TG_VACT_SZ_H); + + writel(SET_TG_FIELD_CHG_L(g_hdmi_video_parm_tbl + [TG_FIELD_CHG*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_TG_FIELD_CHG_L); + writel(SET_TG_FIELD_CHG_H(g_hdmi_video_parm_tbl + [TG_FIELD_CHG*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_TG_FIELD_CHG_H); + + writel(SET_TG_VACT_ST2_L(g_hdmi_video_parm_tbl + [TG_VACT_START2*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_TG_VACT_ST2_L); + writel(SET_TG_VACT_ST2_H(g_hdmi_video_parm_tbl + [TG_VACT_START2*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_TG_VACT_ST2_H); + + writel(SET_TG_VSYNC_TOP_HDMI_L(g_hdmi_video_parm_tbl + [TG_VSYNC_TOP_HDMI*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_TG_VSYNC_TOP_HDMI_L); + writel(SET_TG_VSYNC_TOP_HDMI_H(g_hdmi_video_parm_tbl + [TG_VSYNC_TOP_HDMI*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_TG_VSYNC_TOP_HDMI_H); + writel(SET_TG_VSYNC_BOT_HDMI_L(g_hdmi_video_parm_tbl + [TG_VSYNC_BOTTOM_HDMI*S5P_TV_HDMI_DISP_MODE_NUM + + hdmi_disp_num]), + hdmi_base + S5P_TG_VSYNC_BOT_HDMI_L); + writel(SET_TG_VSYNC_BOT_HDMI_H(g_hdmi_video_parm_tbl + [TG_VSYNC_BOTTOM_HDMI*S5P_TV_HDMI_DISP_MODE_NUM + + hdmi_disp_num]), + hdmi_base + S5P_TG_VSYNC_BOT_HDMI_H); + + writel(SET_TG_FIELD_TOP_HDMI_L(g_hdmi_video_parm_tbl + [TG_FIELD_TOP_HDMI*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_TG_FIELD_TOP_HDMI_L); + writel(SET_TG_FIELD_TOP_HDMI_H(g_hdmi_video_parm_tbl + [TG_FIELD_TOP_HDMI*S5P_TV_HDMI_DISP_MODE_NUM + hdmi_disp_num]), + hdmi_base + S5P_TG_FIELD_TOP_HDMI_H); + writel(SET_TG_FIELD_BOT_HDMI_L(g_hdmi_video_parm_tbl + [TG_FIELD_BOTTOM_HDMI*S5P_TV_HDMI_DISP_MODE_NUM + + hdmi_disp_num]), + hdmi_base + S5P_TG_FIELD_BOT_HDMI_L); + writel(SET_TG_FIELD_BOT_HDMI_H(g_hdmi_video_parm_tbl + [TG_FIELD_BOTTOM_HDMI*S5P_TV_HDMI_DISP_MODE_NUM + + hdmi_disp_num]), + hdmi_base + S5P_TG_FIELD_BOT_HDMI_H); + + HDMIPRINTK("HDMI_CON_1 = 0x%08x \n\r", + readl(hdmi_base + S5P_HDMI_CON_1)); + HDMIPRINTK("HDMI_CON_2 = 0x%08x \n\r", + readl(hdmi_base + S5P_HDMI_CON_2)); + HDMIPRINTK("MODE_SEL = 0x%08x \n\r", + readl(hdmi_base + S5P_MODE_SEL)); + HDMIPRINTK("BLUE_SCREEN_0 = 0x%08x \n\r", + readl(hdmi_base + S5P_BLUE_SCREEN_0)); + HDMIPRINTK("BLUE_SCREEN_1 = 0x%08x \n\r", + readl(hdmi_base + S5P_BLUE_SCREEN_1)); + HDMIPRINTK("BLUE_SCREEN_2 = 0x%08x \n\r", + readl(hdmi_base + S5P_BLUE_SCREEN_2)); + HDMIPRINTK("VBI_ST_MG = 0x%08x \n\r", + readl(hdmi_base + S5P_VBI_ST_MG)); + HDMIPRINTK("VBI_END_MG = 0x%08x \n\r", + readl(hdmi_base + S5P_VBI_END_MG)); + HDMIPRINTK("VACT_ST_MG = 0x%08x \n\r", + readl(hdmi_base + S5P_VACT_ST_MG)); + HDMIPRINTK("VACT_END_MG = 0x%08x \n\r", + readl(hdmi_base + S5P_VACT_END_MG)); + HDMIPRINTK("H_BLANK_0 = 0x%08x \n\r", + readl(hdmi_base + S5P_H_BLANK_0)); + HDMIPRINTK("H_BLANK_1 = 0x%08x \n\r", + readl(hdmi_base + S5P_H_BLANK_1)); + HDMIPRINTK("V_BLANK_0 = 0x%08x \n\r", + readl(hdmi_base + S5P_V_BLANK_0)); + HDMIPRINTK("V_BLANK_1 = 0x%08x \n\r", + readl(hdmi_base + S5P_V_BLANK_1)); + HDMIPRINTK("V_BLANK_2 = 0x%08x \n\r", + readl(hdmi_base + S5P_V_BLANK_2)); + HDMIPRINTK("H_V_LINE_0 = 0x%08x \n\r", + readl(hdmi_base + S5P_H_V_LINE_0)); + HDMIPRINTK("H_V_LINE_1 = 0x%08x \n\r", + readl(hdmi_base + S5P_H_V_LINE_1)); + HDMIPRINTK("H_V_LINE_2 = 0x%08x \n\r", + readl(hdmi_base + S5P_H_V_LINE_2)); + HDMIPRINTK("SYNC_MODE = 0x%08x \n\r", + readl(hdmi_base + S5P_SYNC_MODE)); + HDMIPRINTK("INT_PRO_MODE = 0x%08x \n\r", + readl(hdmi_base + S5P_INT_PRO_MODE)); + HDMIPRINTK("SEND_PER_START0 = 0x%08x \n\r", + readl(hdmi_base + S5P_SEND_PER_START0)); + HDMIPRINTK("SEND_PER_START1 = 0x%08x \n\r", + readl(hdmi_base + S5P_SEND_PER_START1)); + HDMIPRINTK("SEND_PER_END0 = 0x%08x \n\r", + readl(hdmi_base + S5P_SEND_PER_END0)); + HDMIPRINTK("SEND_PER_END1 = 0x%08x \n\r", + readl(hdmi_base + S5P_SEND_PER_END1)); + HDMIPRINTK("SEND_PER_END2 = 0x%08x \n\r", + readl(hdmi_base + S5P_SEND_PER_END2)); + HDMIPRINTK("V_BLANK_F_0 = 0x%08x \n\r", + readl(hdmi_base + S5P_V_BLANK_F_0)); + HDMIPRINTK("V_BLANK_F_1 = 0x%08x \n\r", + readl(hdmi_base + S5P_V_BLANK_F_1)); + HDMIPRINTK("V_BLANK_F_2 = 0x%08x \n\r", + readl(hdmi_base + S5P_V_BLANK_F_2)); + HDMIPRINTK("H_SYNC_GEN_0 = 0x%08x \n\r", + readl(hdmi_base + S5P_H_SYNC_GEN_0)); + HDMIPRINTK("H_SYNC_GEN_1 = 0x%08x \n\r", + readl(hdmi_base + S5P_H_SYNC_GEN_1)); + HDMIPRINTK("H_SYNC_GEN_2 = 0x%08x \n\r", + readl(hdmi_base + S5P_H_SYNC_GEN_2)); + HDMIPRINTK("V_SYNC_GEN_1_0 = 0x%08x \n\r", + readl(hdmi_base + S5P_V_SYNC_GEN_1_0)); + HDMIPRINTK("V_SYNC_GEN_1_1 = 0x%08x \n\r", + readl(hdmi_base + S5P_V_SYNC_GEN_1_1)); + HDMIPRINTK("V_SYNC_GEN_1_2 = 0x%08x \n\r", + readl(hdmi_base + S5P_V_SYNC_GEN_1_2)); + HDMIPRINTK("V_SYNC_GEN_2_0 = 0x%08x \n\r", + readl(hdmi_base + S5P_V_SYNC_GEN_2_0)); + HDMIPRINTK("V_SYNC_GEN_2_1 = 0x%08x \n\r", + readl(hdmi_base + S5P_V_SYNC_GEN_2_1)); + HDMIPRINTK("V_SYNC_GEN_2_2 = 0x%08x \n\r", + readl(hdmi_base + S5P_V_SYNC_GEN_2_2)); + HDMIPRINTK("V_SYNC_GEN_3_0 = 0x%08x \n\r", + readl(hdmi_base + S5P_V_SYNC_GEN_3_0)); + HDMIPRINTK("V_SYNC_GEN_3_1 = 0x%08x \n\r", + readl(hdmi_base + S5P_V_SYNC_GEN_3_1)); + HDMIPRINTK("V_SYNC_GEN_3_2 = 0x%08x \n\r", + readl(hdmi_base + S5P_V_SYNC_GEN_3_2)); + HDMIPRINTK("TG_CMD = 0x%08x \n\r", + readl(hdmi_base + S5P_TG_CMD)); + HDMIPRINTK("TG_H_FSZ_L = 0x%08x \n\r", + readl(hdmi_base + S5P_TG_H_FSZ_L)); + HDMIPRINTK("TG_H_FSZ_H = 0x%08x \n\r", + readl(hdmi_base + S5P_TG_H_FSZ_H)); + HDMIPRINTK("TG_HACT_ST_L = 0x%08x \n\r", + readl(hdmi_base + S5P_TG_HACT_ST_L)); + HDMIPRINTK("TG_HACT_ST_H = 0x%08x \n\r", + readl(hdmi_base + S5P_TG_HACT_ST_H)); + HDMIPRINTK("TG_HACT_SZ_L = 0x%08x \n\r", + readl(hdmi_base + S5P_TG_HACT_SZ_L)); + HDMIPRINTK("TG_HACT_SZ_H = 0x%08x \n\r", + readl(hdmi_base + S5P_TG_HACT_SZ_H)); + HDMIPRINTK("TG_V_FSZ_L = 0x%08x \n\r", + readl(hdmi_base + S5P_TG_V_FSZ_L)); + HDMIPRINTK("TG_V_FSZ_H = 0x%08x \n\r", + readl(hdmi_base + S5P_TG_V_FSZ_H)); + HDMIPRINTK("TG_VSYNC_L = 0x%08x \n\r", + readl(hdmi_base + S5P_TG_VSYNC_L)); + HDMIPRINTK("TG_VSYNC_H = 0x%08x \n\r", + readl(hdmi_base + S5P_TG_VSYNC_H)); + HDMIPRINTK("TG_VSYNC2_L = 0x%08x \n\r", + readl(hdmi_base + S5P_TG_VSYNC2_L)); + HDMIPRINTK("TG_VSYNC2_H = 0x%08x \n\r", + readl(hdmi_base + S5P_TG_VSYNC2_H)); + HDMIPRINTK("TG_VACT_ST_L = 0x%08x \n\r", + readl(hdmi_base + S5P_TG_VACT_ST_L)); + HDMIPRINTK("TG_VACT_ST_H = 0x%08x \n\r", + readl(hdmi_base + S5P_TG_VACT_ST_H)); + HDMIPRINTK("TG_VACT_SZ_L = 0x%08x \n\r", + readl(hdmi_base + S5P_TG_VACT_SZ_L)); + HDMIPRINTK("TG_VACT_SZ_H = 0x%08x \n\r", + readl(hdmi_base + S5P_TG_VACT_SZ_H)); + HDMIPRINTK("TG_FIELD_CHG_L = 0x%08x \n\r", + readl(hdmi_base + S5P_TG_FIELD_CHG_L)); + HDMIPRINTK("TG_FIELD_CHG_H = 0x%08x \n\r", + readl(hdmi_base + S5P_TG_FIELD_CHG_H)); + HDMIPRINTK("TG_VACT_ST2_L = 0x%08x \n\r", + readl(hdmi_base + S5P_TG_VACT_ST2_L)); + HDMIPRINTK("TG_VACT_ST2_H = 0x%08x \n\r", + readl(hdmi_base + S5P_TG_VACT_ST2_H)); + HDMIPRINTK("TG_VSYNC_TOP_HDMI_L = 0x%08x \n\r", + readl(hdmi_base + S5P_TG_VSYNC_TOP_HDMI_L)); + HDMIPRINTK("TG_VSYNC_TOP_HDMI_H = 0x%08x \n\r", + readl(hdmi_base + S5P_TG_VSYNC_TOP_HDMI_H)); + HDMIPRINTK("TG_VSYNC_BOT_HDMI_L = 0x%08x \n\r", + readl(hdmi_base + S5P_TG_VSYNC_BOT_HDMI_L)); + HDMIPRINTK("TG_VSYNC_BOT_HDMI_H = 0x%08x \n\r", + readl(hdmi_base + S5P_TG_VSYNC_BOT_HDMI_H)); + HDMIPRINTK("TG_FIELD_TOP_HDMI_L = 0x%08x \n\r", + readl(hdmi_base + S5P_TG_FIELD_TOP_HDMI_L)); + HDMIPRINTK("TG_FIELD_TOP_HDMI_H = 0x%08x \n\r", + readl(hdmi_base + S5P_TG_FIELD_TOP_HDMI_H)); + HDMIPRINTK("TG_FIELD_BOT_HDMI_L = 0x%08x \n\r", + readl(hdmi_base + S5P_TG_FIELD_BOT_HDMI_L)); + HDMIPRINTK("TG_FIELD_BOT_HDMI_H = 0x%08x \n\r", + readl(hdmi_base + S5P_TG_FIELD_BOT_HDMI_H)); + + return HDMI_NO_ERROR; +} + +void __s5p_hdmi_video_init_bluescreen(bool en, + u8 cb_b, + u8 y_g, + u8 cr_r) +{ + HDMIPRINTK("()\n\r"); + + __s5p_hdmi_video_set_bluescreen(en, cb_b, y_g, cr_r); + + HDMIPRINTK("()\n\r"); +} + +void __s5p_hdmi_video_init_color_range(u8 y_min, + u8 y_max, + u8 c_min, + u8 c_max) +{ + HDMIPRINTK("%d,%d,%d,%d\n\r", y_max, y_min, c_max, c_min); + + writel(y_max, hdmi_base + S5P_HDMI_YMAX); + writel(y_min, hdmi_base + S5P_HDMI_YMIN); + writel(c_max, hdmi_base + S5P_HDMI_CMAX); + writel(c_min, hdmi_base + S5P_HDMI_CMIN); + + HDMIPRINTK("HDMI_YMAX = 0x%08x \n\r", + readl(hdmi_base + S5P_HDMI_YMAX)); + HDMIPRINTK("HDMI_YMIN = 0x%08x \n\r", + readl(hdmi_base + S5P_HDMI_YMIN)); + HDMIPRINTK("HDMI_CMAX = 0x%08x \n\r", + readl(hdmi_base + S5P_HDMI_CMAX)); + HDMIPRINTK("HDMI_CMIN = 0x%08x \n\r", + readl(hdmi_base + S5P_HDMI_CMIN)); +} + +enum s5p_tv_hdmi_err __s5p_hdmi_video_init_csc( + enum s5p_tv_hdmi_csc_type csc_type) +{ + unsigned short us_csc_coeff[10]; + + HDMIPRINTK("%d)\n\r", csc_type); + + switch (csc_type) { + + case HDMI_CSC_YUV601_TO_RGB_LR: + us_csc_coeff[0] = 0x23; + us_csc_coeff[1] = 256; + us_csc_coeff[2] = 938; + us_csc_coeff[3] = 846; + us_csc_coeff[4] = 256; + us_csc_coeff[5] = 443; + us_csc_coeff[6] = 0; + us_csc_coeff[7] = 256; + us_csc_coeff[8] = 0; + us_csc_coeff[9] = 350; + break; + + case HDMI_CSC_YUV601_TO_RGB_FR: + us_csc_coeff[0] = 0x03; + us_csc_coeff[1] = 298; + us_csc_coeff[2] = 924; + us_csc_coeff[3] = 816; + us_csc_coeff[4] = 298; + us_csc_coeff[5] = 516; + us_csc_coeff[6] = 0; + us_csc_coeff[7] = 298; + us_csc_coeff[8] = 0; + us_csc_coeff[9] = 408; + break; + + case HDMI_CSC_YUV709_TO_RGB_LR: + us_csc_coeff[0] = 0x23; + us_csc_coeff[1] = 256; + us_csc_coeff[2] = 978; + us_csc_coeff[3] = 907; + us_csc_coeff[4] = 256; + us_csc_coeff[5] = 464; + us_csc_coeff[6] = 0; + us_csc_coeff[7] = 256; + us_csc_coeff[8] = 0; + us_csc_coeff[9] = 394; + break; + + case HDMI_CSC_YUV709_TO_RGB_FR: + us_csc_coeff[0] = 0x03; + us_csc_coeff[1] = 298; + us_csc_coeff[2] = 970; + us_csc_coeff[3] = 888; + us_csc_coeff[4] = 298; + us_csc_coeff[5] = 540; + us_csc_coeff[6] = 0; + us_csc_coeff[7] = 298; + us_csc_coeff[8] = 0; + us_csc_coeff[9] = 458; + break; + + case HDMI_CSC_YUV601_TO_YUV709: + us_csc_coeff[0] = 0x33; + us_csc_coeff[1] = 256; + us_csc_coeff[2] = 995; + us_csc_coeff[3] = 971; + us_csc_coeff[4] = 0; + us_csc_coeff[5] = 260; + us_csc_coeff[6] = 29; + us_csc_coeff[7] = 0; + us_csc_coeff[8] = 19; + us_csc_coeff[9] = 262; + break; + + case HDMI_CSC_RGB_FR_TO_RGB_LR: + us_csc_coeff[0] = 0x20; + us_csc_coeff[1] = 220; + us_csc_coeff[2] = 0; + us_csc_coeff[3] = 0; + us_csc_coeff[4] = 0; + us_csc_coeff[5] = 220; + us_csc_coeff[6] = 0; + us_csc_coeff[7] = 0; + us_csc_coeff[8] = 0; + us_csc_coeff[9] = 220; + break; + + case HDMI_CSC_RGB_FR_TO_YUV601: + us_csc_coeff[0] = 0x30; + us_csc_coeff[1] = 129; + us_csc_coeff[2] = 25; + us_csc_coeff[3] = 65; + us_csc_coeff[4] = 950; + us_csc_coeff[5] = 112; + us_csc_coeff[6] = 986; + us_csc_coeff[7] = 930; + us_csc_coeff[8] = 1006; + us_csc_coeff[9] = 112; + break; + + case HDMI_CSC_RGB_FR_TO_YUV709: + us_csc_coeff[0] = 0x30; + us_csc_coeff[1] = 157; + us_csc_coeff[2] = 16; + us_csc_coeff[3] = 47; + us_csc_coeff[4] = 937; + us_csc_coeff[5] = 112; + us_csc_coeff[6] = 999; + us_csc_coeff[7] = 922; + us_csc_coeff[8] = 1014; + us_csc_coeff[9] = 112; + break; + + case HDMI_BYPASS: + us_csc_coeff[0] = 0x33; + us_csc_coeff[1] = 256; + us_csc_coeff[2] = 0; + us_csc_coeff[3] = 0; + us_csc_coeff[4] = 0; + us_csc_coeff[5] = 256; + us_csc_coeff[6] = 0; + us_csc_coeff[7] = 0; + us_csc_coeff[8] = 0; + us_csc_coeff[9] = 256; + break; + + default: + HDMIPRINTK("invalid out_mode parameter(%d)\n\r", csc_type); + return S5P_TV_HDMI_ERR_INVALID_PARAM; + break; + } + + writel(us_csc_coeff[0], hdmi_base + S5P_HDMI_CSC_CON);; + + writel(SET_HDMI_CSC_COEF_L(us_csc_coeff[1]), + hdmi_base + S5P_HDMI_Y_G_COEF_L); + writel(SET_HDMI_CSC_COEF_H(us_csc_coeff[1]), + hdmi_base + S5P_HDMI_Y_G_COEF_H); + writel(SET_HDMI_CSC_COEF_L(us_csc_coeff[2]), + hdmi_base + S5P_HDMI_Y_B_COEF_L); + writel(SET_HDMI_CSC_COEF_H(us_csc_coeff[2]), + hdmi_base + S5P_HDMI_Y_B_COEF_H); + writel(SET_HDMI_CSC_COEF_L(us_csc_coeff[3]), + hdmi_base + S5P_HDMI_Y_R_COEF_L); + writel(SET_HDMI_CSC_COEF_H(us_csc_coeff[3]), + hdmi_base + S5P_HDMI_Y_R_COEF_H); + writel(SET_HDMI_CSC_COEF_L(us_csc_coeff[4]), + hdmi_base + S5P_HDMI_CB_G_COEF_L); + writel(SET_HDMI_CSC_COEF_H(us_csc_coeff[4]), + hdmi_base + S5P_HDMI_CB_G_COEF_H); + writel(SET_HDMI_CSC_COEF_L(us_csc_coeff[5]), + hdmi_base + S5P_HDMI_CB_B_COEF_L); + writel(SET_HDMI_CSC_COEF_H(us_csc_coeff[5]), + hdmi_base + S5P_HDMI_CB_B_COEF_H); + writel(SET_HDMI_CSC_COEF_L(us_csc_coeff[6]), + hdmi_base + S5P_HDMI_CB_R_COEF_L); + writel(SET_HDMI_CSC_COEF_H(us_csc_coeff[6]), + hdmi_base + S5P_HDMI_CB_R_COEF_H); + writel(SET_HDMI_CSC_COEF_L(us_csc_coeff[7]), + hdmi_base + S5P_HDMI_CR_G_COEF_L); + writel(SET_HDMI_CSC_COEF_H(us_csc_coeff[7]), + hdmi_base + S5P_HDMI_CR_G_COEF_H); + writel(SET_HDMI_CSC_COEF_L(us_csc_coeff[8]), + hdmi_base + S5P_HDMI_CR_B_COEF_L); + writel(SET_HDMI_CSC_COEF_H(us_csc_coeff[8]), + hdmi_base + S5P_HDMI_CR_B_COEF_H); + writel(SET_HDMI_CSC_COEF_L(us_csc_coeff[9]), + hdmi_base + S5P_HDMI_CR_R_COEF_L); + writel(SET_HDMI_CSC_COEF_H(us_csc_coeff[9]), + hdmi_base + S5P_HDMI_CR_R_COEF_H); + + HDMIPRINTK("HDMI_CSC_CON = 0x%08x \n\r", + readl(hdmi_base + S5P_HDMI_CSC_CON)); + HDMIPRINTK("HDMI_Y_G_COEF_L = 0x%08x \n\r", + readl(hdmi_base + S5P_HDMI_Y_G_COEF_L)); + HDMIPRINTK("HDMI_Y_G_COEF_H = 0x%08x \n\r", + readl(hdmi_base + S5P_HDMI_Y_G_COEF_H)); + HDMIPRINTK("HDMI_Y_B_COEF_L = 0x%08x \n\r", + readl(hdmi_base + S5P_HDMI_Y_B_COEF_L)); + HDMIPRINTK("HDMI_Y_B_COEF_H = 0x%08x \n\r", + readl(hdmi_base + S5P_HDMI_Y_B_COEF_H)); + HDMIPRINTK("HDMI_Y_R_COEF_L = 0x%08x \n\r", + readl(hdmi_base + S5P_HDMI_Y_R_COEF_L)); + HDMIPRINTK("HDMI_Y_R_COEF_H = 0x%08x \n\r", + readl(hdmi_base + S5P_HDMI_Y_R_COEF_H)); + HDMIPRINTK("HDMI_CB_G_COEF_L = 0x%08x \n\r", + readl(hdmi_base + S5P_HDMI_CB_G_COEF_L)); + HDMIPRINTK("HDMI_CB_G_COEF_H = 0x%08x \n\r", + readl(hdmi_base + S5P_HDMI_CB_G_COEF_H)); + HDMIPRINTK("HDMI_CB_B_COEF_L = 0x%08x \n\r", + readl(hdmi_base + S5P_HDMI_CB_B_COEF_L)); + HDMIPRINTK("HDMI_CB_B_COEF_H = 0x%08x \n\r", + readl(hdmi_base + S5P_HDMI_CB_B_COEF_H)); + HDMIPRINTK("HDMI_CB_R_COEF_L = 0x%08x \n\r", + readl(hdmi_base + S5P_HDMI_CB_R_COEF_L)); + HDMIPRINTK("HDMI_CB_R_COEF_H = 0x%08x \n\r", + readl(hdmi_base + S5P_HDMI_CB_R_COEF_H)); + HDMIPRINTK("HDMI_CR_G_COEF_L = 0x%08x \n\r", + readl(hdmi_base + S5P_HDMI_CR_G_COEF_L)); + HDMIPRINTK("HDMI_CR_G_COEF_H = 0x%08x \n\r", + readl(hdmi_base + S5P_HDMI_CR_G_COEF_H)); + HDMIPRINTK("HDMI_CR_B_COEF_L = 0x%08x \n\r", + readl(hdmi_base + S5P_HDMI_CR_B_COEF_L)); + HDMIPRINTK("HDMI_CR_B_COEF_H = 0x%08x \n\r", + readl(hdmi_base + S5P_HDMI_CR_B_COEF_H)); + HDMIPRINTK("HDMI_CR_R_COEF_L = 0x%08x \n\r", + readl(hdmi_base + S5P_HDMI_CR_R_COEF_L)); + HDMIPRINTK("HDMI_CR_R_COEF_H = 0x%08x \n\r", + readl(hdmi_base + S5P_HDMI_CR_R_COEF_H)); + + return HDMI_NO_ERROR; +} + +enum s5p_tv_hdmi_err __s5p_hdmi_video_init_avi_infoframe( + enum s5p_hdmi_transmit trans_type, u8 check_sum, u8 *avi_data) +{ + HDMIPRINTK("%d,%d,%d\n\r", (u32)trans_type, (u32)check_sum, + (u32)avi_data); + + switch (trans_type) { + + case HDMI_DO_NOT_TANS: + writel(AVI_TX_CON_NO_TRANS, hdmi_base + S5P_AVI_CON); + break; + + case HDMI_TRANS_ONCE: + writel(AVI_TX_CON_TRANS_ONCE, hdmi_base + S5P_AVI_CON); + break; + + case HDMI_TRANS_EVERY_SYNC: + writel(AVI_TX_CON_TRANS_EVERY_VSYNC, hdmi_base + S5P_AVI_CON); + break; + + default: + HDMIPRINTK(" invalid out_mode parameter(%d)\n\r", trans_type); + return S5P_TV_HDMI_ERR_INVALID_PARAM; + break; + } + + writel(SET_AVI_CHECK_SUM(check_sum), hdmi_base + S5P_AVI_CHECK_SUM); + + writel(SET_AVI_BYTE(*(avi_data)), hdmi_base + S5P_AVI_BYTE1); + writel(SET_AVI_BYTE(*(avi_data + 1)), hdmi_base + S5P_AVI_BYTE2); + writel(SET_AVI_BYTE(*(avi_data + 2)), hdmi_base + S5P_AVI_BYTE3); + writel(SET_AVI_BYTE(*(avi_data + 3)), hdmi_base + S5P_AVI_BYTE4); + writel(SET_AVI_BYTE(*(avi_data + 4)), hdmi_base + S5P_AVI_BYTE5); + writel(SET_AVI_BYTE(*(avi_data + 5)), hdmi_base + S5P_AVI_BYTE6); + writel(SET_AVI_BYTE(*(avi_data + 6)), hdmi_base + S5P_AVI_BYTE7); + writel(SET_AVI_BYTE(*(avi_data + 7)), hdmi_base + S5P_AVI_BYTE8); + writel(SET_AVI_BYTE(*(avi_data + 8)), hdmi_base + S5P_AVI_BYTE9); + writel(SET_AVI_BYTE(*(avi_data + 9)), hdmi_base + S5P_AVI_BYTE10); + writel(SET_AVI_BYTE(*(avi_data + 10)), hdmi_base + S5P_AVI_BYTE11); + writel(SET_AVI_BYTE(*(avi_data + 11)), hdmi_base + S5P_AVI_BYTE12); + writel(SET_AVI_BYTE(*(avi_data + 12)), hdmi_base + S5P_AVI_BYTE13); + + HDMIPRINTK("AVI_CON = 0x%08x \n\r", readl(hdmi_base + S5P_AVI_CON)); + HDMIPRINTK("AVI_CHECK_SUM = 0x%08x \n\r", + readl(hdmi_base + S5P_AVI_CHECK_SUM)); + HDMIPRINTK("AVI_BYTE1 = 0x%08x \n\r", + readl(hdmi_base + S5P_AVI_BYTE1)); + HDMIPRINTK("AVI_BYTE2 = 0x%08x \n\r", + readl(hdmi_base + S5P_AVI_BYTE2)); + HDMIPRINTK("AVI_BYTE3 = 0x%08x \n\r", + readl(hdmi_base + S5P_AVI_BYTE3)); + HDMIPRINTK("AVI_BYTE4 = 0x%08x \n\r", + readl(hdmi_base + S5P_AVI_BYTE4)); + HDMIPRINTK("AVI_BYTE5 = 0x%08x \n\r", + readl(hdmi_base + S5P_AVI_BYTE5)); + HDMIPRINTK("AVI_BYTE6 = 0x%08x \n\r", + readl(hdmi_base + S5P_AVI_BYTE6)); + HDMIPRINTK("AVI_BYTE7 = 0x%08x \n\r", + readl(hdmi_base + S5P_AVI_BYTE7)); + HDMIPRINTK("AVI_BYTE8 = 0x%08x \n\r", + readl(hdmi_base + S5P_AVI_BYTE8)); + HDMIPRINTK("AVI_BYTE9 = 0x%08x \n\r", + readl(hdmi_base + S5P_AVI_BYTE9)); + HDMIPRINTK("AVI_BYTE10 = 0x%08x \n\r", + readl(hdmi_base + S5P_AVI_BYTE10)); + HDMIPRINTK("AVI_BYTE11 = 0x%08x \n\r", + readl(hdmi_base + S5P_AVI_BYTE11)); + HDMIPRINTK("AVI_BYTE12 = 0x%08x \n\r", + readl(hdmi_base + S5P_AVI_BYTE12)); + HDMIPRINTK("AVI_BYTE13 = 0x%08x \n\r", + readl(hdmi_base + S5P_AVI_BYTE13)); + + /* + * for test color bar + */ + /* + { + + writel( 0xff&32,HDMI_TPGEN_1); + writel( (32>>8)&0xff,HDMI_TPGEN_2); + writel( 0xff&480,HDMI_TPGEN_3); + writel( (480>>8)&0xff,HDMI_TPGEN_4); + writel( 0xff&720,HDMI_TPGEN_5); + writel( (720>>8)&0xff,HDMI_TPGEN_6); + + u8 uTpGen0Reg = 0x1 | (0x1<<3) | (1<<4); + writel( uTpGen0Reg, HDMI_TPGEN_0); + + HDMIPRINTK("HDMI_TPGEN_0 0x%08x\n",readl(HDMI_TPGEN_0)); + HDMIPRINTK("HDMI_TPGEN_1 0x%08x\n",readl(HDMI_TPGEN_1)); + HDMIPRINTK("HDMI_TPGEN_2 0x%08x\n",readl(HDMI_TPGEN_2)); + HDMIPRINTK("HDMI_TPGEN_3 0x%08x\n",readl(HDMI_TPGEN_3)); + HDMIPRINTK("HDMI_TPGEN_5 0x%08x\n",readl(HDMI_TPGEN_4)); + HDMIPRINTK("HDMI_TPGEN_0 0x%08x\n",readl(HDMI_TPGEN_5)); + HDMIPRINTK("HDMI_TPGEN_1 0x%08x\n",readl(HDMI_TPGEN_6)); + } + */ + + return HDMI_NO_ERROR; +} + +enum s5p_tv_hdmi_err __s5p_hdmi_video_init_mpg_infoframe( + enum s5p_hdmi_transmit trans_type, u8 check_sum, u8 *mpg_data) +{ + HDMIPRINTK("trans_type : %d,%d,%d\n\r", (u32)trans_type, + (u32)check_sum, (u32)mpg_data); + + switch (trans_type) { + + case HDMI_DO_NOT_TANS: + writel(MPG_TX_CON_NO_TRANS, + hdmi_base + S5P_MPG_CON); + break; + + case HDMI_TRANS_ONCE: + writel(MPG_TX_CON_TRANS_ONCE, + hdmi_base + S5P_MPG_CON); + break; + + case HDMI_TRANS_EVERY_SYNC: + writel(MPG_TX_CON_TRANS_EVERY_VSYNC, + hdmi_base + S5P_MPG_CON); + break; + + default: + HDMIPRINTK("invalid out_mode parameter(%d)\n\r", + trans_type); + return S5P_TV_HDMI_ERR_INVALID_PARAM; + break; + } + + writel(SET_MPG_CHECK_SUM(check_sum), + + hdmi_base + S5P_MPG_CHECK_SUM); + + writel(SET_MPG_BYTE(*(mpg_data)), + hdmi_base + S5P_MPEG_BYTE1); + writel(SET_MPG_BYTE(*(mpg_data + 1)), + hdmi_base + S5P_MPEG_BYTE2); + writel(SET_MPG_BYTE(*(mpg_data + 2)), + hdmi_base + S5P_MPEG_BYTE3); + writel(SET_MPG_BYTE(*(mpg_data + 3)), + hdmi_base + S5P_MPEG_BYTE4); + writel(SET_MPG_BYTE(*(mpg_data + 4)), + hdmi_base + S5P_MPEG_BYTE5); + + HDMIPRINTK("MPG_CON = 0x%08x \n\r", + readl(hdmi_base + S5P_MPG_CON)); + HDMIPRINTK("MPG_CHECK_SUM = 0x%08x \n\r", + readl(hdmi_base + S5P_MPG_CHECK_SUM)); + HDMIPRINTK("MPEG_BYTE1 = 0x%08x \n\r", + readl(hdmi_base + S5P_MPEG_BYTE1)); + HDMIPRINTK("MPEG_BYTE2 = 0x%08x \n\r", + readl(hdmi_base + S5P_MPEG_BYTE2)); + HDMIPRINTK("MPEG_BYTE3 = 0x%08x \n\r", + readl(hdmi_base + S5P_MPEG_BYTE3)); + HDMIPRINTK("MPEG_BYTE4 = 0x%08x \n\r", + readl(hdmi_base + S5P_MPEG_BYTE4)); + HDMIPRINTK("MPEG_BYTE5 = 0x%08x \n\r", + readl(hdmi_base + S5P_MPEG_BYTE5)); + + return HDMI_NO_ERROR; +} + +void __s5p_hdmi_video_init_tg_cmd(bool time_c_e, + bool bt656_sync_en, + bool tg_en) +{ + u32 temp_reg = 0; + + temp_reg = readl(hdmi_base + S5P_TG_CMD); + + if (time_c_e) + temp_reg |= GETSYNC_TYPE_EN; + else + temp_reg &= GETSYNC_TYPE_DIS; + + if (bt656_sync_en) + temp_reg |= GETSYNC_EN; + else + temp_reg &= GETSYNC_DIS; + + if (tg_en) + temp_reg |= TG_EN; + else + temp_reg &= TG_DIS; + + writel(temp_reg, hdmi_base + S5P_TG_CMD); + + HDMIPRINTK("TG_CMD = 0x%08x \n\r", readl(hdmi_base + S5P_TG_CMD)); +} + + +/* +* start - start functions are only called under stopping HDMI +*/ +bool __s5p_hdmi_start(enum s5p_hdmi_audio_type hdmi_audio_type, + bool hdcp_en, + struct i2c_client *ddc_port) +{ + u32 temp_reg = PWDN_ENB_NORMAL | HDMI_EN;; + + HDMIPRINTK("aud type : %d, hdcp enable : %d\n\r", + hdmi_audio_type, hdcp_en); + + switch (hdmi_audio_type) { + + case HDMI_AUDIO_PCM: + temp_reg |= ASP_EN; + break; + + case HDMI_AUDIO_NO: + break; + + default: + HDMIPRINTK(" invalid hdmi_audio_type(%d)\n\r", + hdmi_audio_type); + return false; + break; + } + + writel(readl(hdmi_base + S5P_HDMI_CON_0) | temp_reg, + + hdmi_base + S5P_HDMI_CON_0); + + if (hdcp_en) { + __s5p_init_hdcp(true, ddc_port); + + if (!__s5p_start_hdcp()) + HDMIPRINTK("HDCP start failed\n"); + + } + + HDMIPRINTK("HDCP_CTRL : 0x%08x, HPD : 0x%08x, HDMI_CON_0 :\ + 0x%08x\n\r", + + readl(hdmi_base + S5P_HDCP_CTRL), + readl(hdmi_base + S5P_HPD), + readl(hdmi_base + S5P_HDMI_CON_0)); + + return true; +} + + + +/* +* stop - stop functions are only called under running HDMI +*/ +void __s5p_hdmi_stop(void) +{ + HDMIPRINTK("\n\r"); + + __s5p_stop_hdcp(); + + writel(readl(hdmi_base + S5P_HDMI_CON_0) & + ~(PWDN_ENB_NORMAL | HDMI_EN | ASP_EN), + hdmi_base + S5P_HDMI_CON_0); + + HDMIPRINTK("HDCP_CTRL 0x%08x, HPD 0x%08x,HDMI_CON_0 0x%08x\n\r", + readl(hdmi_base + S5P_HDCP_CTRL), + readl(hdmi_base + S5P_HPD), + readl(hdmi_base + S5P_HDMI_CON_0)); +} + +int __init __s5p_hdmi_probe(struct platform_device *pdev, u32 res_num) +{ + + struct resource *res; + size_t size; + int ret; + + res = platform_get_resource(pdev, IORESOURCE_MEM, res_num); + + if (res == NULL) { + dev_err(&pdev->dev, + "failed to get memory region resource\n"); + ret = -ENOENT; + } + + size = (res->end - res->start) + 1; + + hdmi_mem = request_mem_region(res->start, size, pdev->name); + + if (hdmi_mem == NULL) { + dev_err(&pdev->dev, + "failed to get memory region\n"); + ret = -ENOENT; + } + + hdmi_base = ioremap(res->start, size); + + if (hdmi_base == NULL) { + dev_err(&pdev->dev, + "failed to ioremap address region\n"); + ret = -ENOENT; + } + + return ret; + +} + +int __init __s5p_hdmi_release(struct platform_device *pdev) +{ + iounmap(hdmi_base); + + /* remove memory region */ + + if (hdmi_mem != NULL) { + if (release_resource(hdmi_mem)) + dev_err(&pdev->dev, + "Can't remove tvout drv !!\n"); + + kfree(hdmi_mem); + + hdmi_mem = NULL; + } + + return 0; +} + diff --git a/drivers/media/video/samsung/tv20/s5pc100/regs/regs-clock_extra.h b/drivers/media/video/samsung/tv20/s5pc100/regs/regs-clock_extra.h new file mode 100644 index 0000000..ff00b23 --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5pc100/regs/regs-clock_extra.h @@ -0,0 +1,79 @@ +/* linux/drivers/media/video/samsung/tv20/s5pc100/regs/regs-clock_extra.h + * + * Clock Other header file for Samsung TVOut driver + * + * Copyright (c) 2009 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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. +*/ + +#ifndef __ASM_ARCH_REGS_CLK_EXTRA_H +#define __ASM_ARCH_REGS_CLK_EXTRA_H + +#include <mach/map.h> + +#define S5P_CLK_OTHER_BASE(x) (x) + +#define S5P_CLK_OTHER_SWRESET S5P_CLK_OTHER_BASE(0x0000) +#define S5P_CLK_OTHER_ONENAND_SWRESET S5P_CLK_OTHER_BASE(0x0008) +#define S5P_CLK_OTHER_GENERAL_CTRL S5P_CLK_OTHER_BASE(0x0100) +#define S5P_CLK_OTHER_GENERAL_STATUS S5P_CLK_OTHER_BASE(0x0104) +#define S5P_CLK_OTHER_MEM_SYS_CFG S5P_CLK_OTHER_BASE(0x0200) +#define S5P_CLK_OTHER_CAM_MUX_SEL S5P_CLK_OTHER_BASE(0x0300) +#define S5P_CLK_OTHER_MIXER_OUT_SEL S5P_CLK_OTHER_BASE(0x0304) +#define S5P_CLK_OTHER_LPMP3_MODE_SEL S5P_CLK_OTHER_BASE(0x0308) +#define S5P_CLK_OTHER_MIPI_PHY_CON0 S5P_CLK_OTHER_BASE(0x0400) +#define S5P_CLK_OTHER_MIPI_PHY_CON1 S5P_CLK_OTHER_BASE(0x0414) +#define S5P_CLK_OTHER_HDMI_PHY_CON0 S5P_CLK_OTHER_BASE(0x0420) + + + +#define HPLL_LOCKTIME(a) (0xffff&a) + +#define HPLL_ENABLE (1<<31) +#define HPLL_DISABLE (0<<31) +#define HPLL_LOCKED(a) ((1<<30)&a) +#define MDIV(a) ((0xff&a)<<16) +#define PDIV(a) ((0x3f&a)<<8) +#define SDIV(a) (0x7&a) + +#define HREF_SEL_FIN_27M (0<<20) +#define HREF_SEL_SRCLK (1<<20) +#define HREF_SEL_MASK (~(1<<20)) +#define HPLL_SEL_CLK27M (0<<12) +#define HPLL_SEL_FOUT_HPLL (1<<12) +#define HPLL_SEL_MASK (~(1<<12)) + +#define VMIXER_SEL_CLK27M (0<<28) +#define VMIXER_SEL_VCLK_54 (1<<28) +#define VMIXER_SEL_MOUT_HPLL (2<<28) +#define VMIXER_SEL_MASK (~(3<<28)) + +#define HDMI_DIV_RATIO(a) ((0xf&((a)-1))<<28) +#define HDMI_DIV_RATIO_MASK (~(0xf<<28)) + +#define CLK_HCLK_HDMI_PASS (1<<3) +#define CLK_HCLK_VMIXER_PASS (1<<2) +#define CLK_HCLK_VP_PASS (1<<1) +#define CLK_HCLK_SDOUT_PASS (1<<0) +#define CLK_HCLK_MASK (~0xf) + +#define CLK_PCLK_IIC_HDMI_PASS (1<<5) +#define CLK_PCLK_IIC_HDMI_MASK (~(1<<5)) + +#define CLK_SCLK_HDMI_PASS (1<<7) +#define CLK_SCLK_VMIXER_PASS (1<<6) +#define CLK_SCLK_VDAC54_PASS (1<<5) +#define CLK_SCLK_TV54_PASS (1<<4) +#define CLK_SCLK_HDMI_MASK (~(1<<7)) +#define CLK_SCLK_VMIXER_MASK (~(1<<6)) +#define CLK_SCLK_VDAC54_MASK (~(1<<5)) +#define CLK_SCLK_TV54_MASK (~(1<<4)) + +#define VMIXER_OUT_SEL_SDOUT (0) +#define VMIXER_OUT_SEL_HDMI (1) + +#endif diff --git a/drivers/media/video/samsung/tv20/s5pc100/regs/regs-hdmi.h b/drivers/media/video/samsung/tv20/s5pc100/regs/regs-hdmi.h new file mode 100644 index 0000000..96c1958 --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5pc100/regs/regs-hdmi.h @@ -0,0 +1,978 @@ +/* linux/drivers/media/video/samsung/tv20/s5pc100/regs/regs-hdmi.h + * + * Hdmi register header file for Samsung TVOut driver + * + * Copyright (c) 2009 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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. +*/ + +#ifndef __ASM_ARCH_REGS_HDMI_H + +#include <mach/map.h> + +#define S5P_HDMI_BASE(x) (x) + +#define S5P_HDMI_CON_0 S5P_HDMI_BASE(0x0000) +#define S5P_HDMI_CON_1 S5P_HDMI_BASE(0x0004) +#define S5P_HDMI_CON_2 S5P_HDMI_BASE(0x0008) +#define S5P_STATUS S5P_HDMI_BASE(0x0010) +#define S5P_STATUS_EN S5P_HDMI_BASE(0x0020) +#define S5P_HPD S5P_HDMI_BASE(0x0030) +#define S5P_MODE_SEL S5P_HDMI_BASE(0x0040) +#define S5P_ENC_EN S5P_HDMI_BASE(0x0044) +#define S5P_BLUE_SCREEN_0 S5P_HDMI_BASE(0x0050) +#define S5P_BLUE_SCREEN_1 S5P_HDMI_BASE(0x0054) +#define S5P_BLUE_SCREEN_2 S5P_HDMI_BASE(0x0058) +#define S5P_HDMI_YMAX S5P_HDMI_BASE(0x0060) +#define S5P_HDMI_YMIN S5P_HDMI_BASE(0x0064) +#define S5P_HDMI_CMAX S5P_HDMI_BASE(0x0068) +#define S5P_HDMI_CMIN S5P_HDMI_BASE(0x006C) +#define S5P_VBI_ST_MG S5P_HDMI_BASE(0x0080) +#define S5P_VBI_END_MG S5P_HDMI_BASE(0x0084) +#define S5P_VACT_ST_MG S5P_HDMI_BASE(0x0088) +#define S5P_VACT_END_MG S5P_HDMI_BASE(0x008C) +#define S5P_H_BLANK_0 S5P_HDMI_BASE(0x00A0) +#define S5P_H_BLANK_1 S5P_HDMI_BASE(0x00A4) +#define S5P_V_BLANK_0 S5P_HDMI_BASE(0x00B0) +#define S5P_V_BLANK_1 S5P_HDMI_BASE(0x00B4) +#define S5P_V_BLANK_2 S5P_HDMI_BASE(0x00B8) +#define S5P_H_V_LINE_0 S5P_HDMI_BASE(0x00C0) +#define S5P_H_V_LINE_1 S5P_HDMI_BASE(0x00C4) +#define S5P_H_V_LINE_2 S5P_HDMI_BASE(0x00C8) +#define S5P_SYNC_MODE S5P_HDMI_BASE(0x00E4) +#define S5P_INT_PRO_MODE S5P_HDMI_BASE(0x00E8) +#define S5P_SEND_PER_START0 S5P_HDMI_BASE(0x00f0) +#define S5P_SEND_PER_START1 S5P_HDMI_BASE(0x00f4) +#define S5P_SEND_PER_END0 S5P_HDMI_BASE(0x0100) +#define S5P_SEND_PER_END1 S5P_HDMI_BASE(0x0104) +#define S5P_SEND_PER_END2 S5P_HDMI_BASE(0x0108) +#define S5P_V_BLANK_F_0 S5P_HDMI_BASE(0x0110) +#define S5P_V_BLANK_F_1 S5P_HDMI_BASE(0x0114) +#define S5P_V_BLANK_F_2 S5P_HDMI_BASE(0x0118) +#define S5P_H_SYNC_GEN_0 S5P_HDMI_BASE(0x0120) +#define S5P_H_SYNC_GEN_1 S5P_HDMI_BASE(0x0124) +#define S5P_H_SYNC_GEN_2 S5P_HDMI_BASE(0x0128) +#define S5P_V_SYNC_GEN_1_0 S5P_HDMI_BASE(0x0130) +#define S5P_V_SYNC_GEN_1_1 S5P_HDMI_BASE(0x0134) +#define S5P_V_SYNC_GEN_1_2 S5P_HDMI_BASE(0x0138) +#define S5P_V_SYNC_GEN_2_0 S5P_HDMI_BASE(0x0140) +#define S5P_V_SYNC_GEN_2_1 S5P_HDMI_BASE(0x0144) +#define S5P_V_SYNC_GEN_2_2 S5P_HDMI_BASE(0x0148) +#define S5P_V_SYNC_GEN_3_0 S5P_HDMI_BASE(0x0150) +#define S5P_V_SYNC_GEN_3_1 S5P_HDMI_BASE(0x0154) +#define S5P_V_SYNC_GEN_3_2 S5P_HDMI_BASE(0x0158) +#define S5P_ASP_CON S5P_HDMI_BASE(0x0160) +#define S5P_ASP_SP_FLAT S5P_HDMI_BASE(0x0164) +#define S5P_ASP_CHCFG0 S5P_HDMI_BASE(0x0170) +#define S5P_ASP_CHCFG1 S5P_HDMI_BASE(0x0174) +#define S5P_ASP_CHCFG2 S5P_HDMI_BASE(0x0178) +#define S5P_ASP_CHCFG3 S5P_HDMI_BASE(0x017C) +#define S5P_ACR_CON S5P_HDMI_BASE(0x0180) +#define S5P_ACR_MCTS0 S5P_HDMI_BASE(0x0184) +#define S5P_ACR_MCTS1 S5P_HDMI_BASE(0x0188) +#define S5P_ACR_MCTS2 S5P_HDMI_BASE(0x018C) +#define S5P_ACR_CTS0 S5P_HDMI_BASE(0x0190) +#define S5P_ACR_CTS1 S5P_HDMI_BASE(0x0194) +#define S5P_ACR_CTS2 S5P_HDMI_BASE(0x0198) +#define S5P_ACR_N0 S5P_HDMI_BASE(0x01A0) +#define S5P_ACR_N1 S5P_HDMI_BASE(0x01A4) +#define S5P_ACR_N2 S5P_HDMI_BASE(0x01A8) +#define S5P_ACR_LSB2 S5P_HDMI_BASE(0x01B0) +#define S5P_ACR_TXCNT S5P_HDMI_BASE(0x01B4) +#define S5P_ACR_TXINTERVAL S5P_HDMI_BASE(0x01B8) +#define S5P_ACR_CTS_OFFSET S5P_HDMI_BASE(0x01BC) +#define S5P_GCP_CON S5P_HDMI_BASE(0x01C0) +#define S5P_GCP_BYTE1 S5P_HDMI_BASE(0x01D0) +#define S5P_ACP_CON S5P_HDMI_BASE(0x01E0) +#define S5P_ACP_TYPE S5P_HDMI_BASE(0x01E4) + +#define S5P_ACP_DATA0 S5P_HDMI_BASE(0x0200) +#define S5P_ACP_DATA1 S5P_HDMI_BASE(0x0204) +#define S5P_ACP_DATA2 S5P_HDMI_BASE(0x0208) +#define S5P_ACP_DATA3 S5P_HDMI_BASE(0x020c) +#define S5P_ACP_DATA4 S5P_HDMI_BASE(0x0210) +#define S5P_ACP_DATA5 S5P_HDMI_BASE(0x0214) +#define S5P_ACP_DATA6 S5P_HDMI_BASE(0x0218) +#define S5P_ACP_DATA7 S5P_HDMI_BASE(0x021c) +#define S5P_ACP_DATA8 S5P_HDMI_BASE(0x0220) +#define S5P_ACP_DATA9 S5P_HDMI_BASE(0x0224) +#define S5P_ACP_DATA10 S5P_HDMI_BASE(0x0228) +#define S5P_ACP_DATA11 S5P_HDMI_BASE(0x022c) +#define S5P_ACP_DATA12 S5P_HDMI_BASE(0x0230) +#define S5P_ACP_DATA13 S5P_HDMI_BASE(0x0234) +#define S5P_ACP_DATA14 S5P_HDMI_BASE(0x0238) +#define S5P_ACP_DATA15 S5P_HDMI_BASE(0x023c) +#define S5P_ACP_DATA16 S5P_HDMI_BASE(0x0240) + +#define S5P_ISRC_CON S5P_HDMI_BASE(0x0250) +#define S5P_ISRC1_HEADER1 S5P_HDMI_BASE(0x0264) + +#define S5P_ISRC1_DATA0 S5P_HDMI_BASE(0x0270) +#define S5P_ISRC1_DATA1 S5P_HDMI_BASE(0x0274) +#define S5P_ISRC1_DATA2 S5P_HDMI_BASE(0x0278) +#define S5P_ISRC1_DATA3 S5P_HDMI_BASE(0x027c) +#define S5P_ISRC1_DATA4 S5P_HDMI_BASE(0x0280) +#define S5P_ISRC1_DATA5 S5P_HDMI_BASE(0x0284) +#define S5P_ISRC1_DATA6 S5P_HDMI_BASE(0x0288) +#define S5P_ISRC1_DATA7 S5P_HDMI_BASE(0x028c) +#define S5P_ISRC1_DATA8 S5P_HDMI_BASE(0x0290) +#define S5P_ISRC1_DATA9 S5P_HDMI_BASE(0x0294) +#define S5P_ISRC1_DATA10 S5P_HDMI_BASE(0x0298) +#define S5P_ISRC1_DATA11 S5P_HDMI_BASE(0x029c) +#define S5P_ISRC1_DATA12 S5P_HDMI_BASE(0x02a0) +#define S5P_ISRC1_DATA13 S5P_HDMI_BASE(0x02a4) +#define S5P_ISRC1_DATA14 S5P_HDMI_BASE(0x02a8) +#define S5P_ISRC1_DATA15 S5P_HDMI_BASE(0x02ac) + +#define S5P_ISRC2_DATA0 S5P_HDMI_BASE(0x02b0) +#define S5P_ISRC2_DATA1 S5P_HDMI_BASE(0x02b4) +#define S5P_ISRC2_DATA2 S5P_HDMI_BASE(0x02b8) +#define S5P_ISRC2_DATA3 S5P_HDMI_BASE(0x02bc) +#define S5P_ISRC2_DATA4 S5P_HDMI_BASE(0x02c0) +#define S5P_ISRC2_DATA5 S5P_HDMI_BASE(0x02c4) +#define S5P_ISRC2_DATA6 S5P_HDMI_BASE(0x02c8) +#define S5P_ISRC2_DATA7 S5P_HDMI_BASE(0x02cc) +#define S5P_ISRC2_DATA8 S5P_HDMI_BASE(0x02d0) +#define S5P_ISRC2_DATA9 S5P_HDMI_BASE(0x02d4) +#define S5P_ISRC2_DATA10 S5P_HDMI_BASE(0x02d8) +#define S5P_ISRC2_DATA11 S5P_HDMI_BASE(0x02dc) +#define S5P_ISRC2_DATA12 S5P_HDMI_BASE(0x02e0) +#define S5P_ISRC2_DATA13 S5P_HDMI_BASE(0x02e4) +#define S5P_ISRC2_DATA14 S5P_HDMI_BASE(0x02e8) +#define S5P_ISRC2_DATA15 S5P_HDMI_BASE(0x02ec) + +#define S5P_AVI_CON S5P_HDMI_BASE(0x0300) +#define S5P_AVI_CHECK_SUM S5P_HDMI_BASE(0x0310) + +#define S5P_AVI_BYTE1 S5P_HDMI_BASE(0x0320) +#define S5P_AVI_BYTE2 S5P_HDMI_BASE(0x0324) +#define S5P_AVI_BYTE3 S5P_HDMI_BASE(0x0328) +#define S5P_AVI_BYTE4 S5P_HDMI_BASE(0x032c) +#define S5P_AVI_BYTE5 S5P_HDMI_BASE(0x0330) +#define S5P_AVI_BYTE6 S5P_HDMI_BASE(0x0334) +#define S5P_AVI_BYTE7 S5P_HDMI_BASE(0x0338) +#define S5P_AVI_BYTE8 S5P_HDMI_BASE(0x033c) +#define S5P_AVI_BYTE9 S5P_HDMI_BASE(0x0340) +#define S5P_AVI_BYTE10 S5P_HDMI_BASE(0x0344) +#define S5P_AVI_BYTE11 S5P_HDMI_BASE(0x0348) +#define S5P_AVI_BYTE12 S5P_HDMI_BASE(0x034c) +#define S5P_AVI_BYTE13 S5P_HDMI_BASE(0x0350) + +#define S5P_AUI_CON S5P_HDMI_BASE(0x0360) +#define S5P_AUI_CHECK_SUM S5P_HDMI_BASE(0x0370) + +#define S5P_AUI_BYTE1 S5P_HDMI_BASE(0x0380) +#define S5P_AUI_BYTE2 S5P_HDMI_BASE(0x0384) +#define S5P_AUI_BYTE3 S5P_HDMI_BASE(0x0388) +#define S5P_AUI_BYTE4 S5P_HDMI_BASE(0x038c) +#define S5P_AUI_BYTE5 S5P_HDMI_BASE(0x0390) + +#define S5P_MPG_CON S5P_HDMI_BASE(0x03A0) +#define S5P_MPG_CHECK_SUM S5P_HDMI_BASE(0x03B0) + +#define S5P_MPEG_BYTE1 S5P_HDMI_BASE(0x03c0) +#define S5P_MPEG_BYTE2 S5P_HDMI_BASE(0x03c4) +#define S5P_MPEG_BYTE3 S5P_HDMI_BASE(0x03c8) +#define S5P_MPEG_BYTE4 S5P_HDMI_BASE(0x03cc) +#define S5P_MPEG_BYTE5 S5P_HDMI_BASE(0x03d0) + +#define S5P_SPD_CON S5P_HDMI_BASE(0x0400) +#define S5P_SPD_HEADER0 S5P_HDMI_BASE(0x0410) +#define S5P_SPD_HEADER1 S5P_HDMI_BASE(0x0414) +#define S5P_SPD_HEADER2 S5P_HDMI_BASE(0x0418) + +#define S5P_SPD_DATA0 S5P_HDMI_BASE(0x0420) +#define S5P_SPD_DATA1 S5P_HDMI_BASE(0x0424) +#define S5P_SPD_DATA2 S5P_HDMI_BASE(0x0428) +#define S5P_SPD_DATA3 S5P_HDMI_BASE(0x042c) +#define S5P_SPD_DATA4 S5P_HDMI_BASE(0x0430) +#define S5P_SPD_DATA5 S5P_HDMI_BASE(0x0434) +#define S5P_SPD_DATA6 S5P_HDMI_BASE(0x0438) +#define S5P_SPD_DATA7 S5P_HDMI_BASE(0x043c) +#define S5P_SPD_DATA8 S5P_HDMI_BASE(0x0440) +#define S5P_SPD_DATA9 S5P_HDMI_BASE(0x0444) +#define S5P_SPD_DATA10 S5P_HDMI_BASE(0x0448) +#define S5P_SPD_DATA11 S5P_HDMI_BASE(0x044c) +#define S5P_SPD_DATA12 S5P_HDMI_BASE(0x0450) +#define S5P_SPD_DATA13 S5P_HDMI_BASE(0x0454) +#define S5P_SPD_DATA14 S5P_HDMI_BASE(0x0458) +#define S5P_SPD_DATA15 S5P_HDMI_BASE(0x045c) +#define S5P_SPD_DATA16 S5P_HDMI_BASE(0x0460) +#define S5P_SPD_DATA17 S5P_HDMI_BASE(0x0464) +#define S5P_SPD_DATA18 S5P_HDMI_BASE(0x0468) +#define S5P_SPD_DATA19 S5P_HDMI_BASE(0x046c) +#define S5P_SPD_DATA20 S5P_HDMI_BASE(0x0470) +#define S5P_SPD_DATA21 S5P_HDMI_BASE(0x0474) +#define S5P_SPD_DATA22 S5P_HDMI_BASE(0x0478) +#define S5P_SPD_DATA23 S5P_HDMI_BASE(0x048c) +#define S5P_SPD_DATA24 S5P_HDMI_BASE(0x0480) +#define S5P_SPD_DATA25 S5P_HDMI_BASE(0x0484) +#define S5P_SPD_DATA26 S5P_HDMI_BASE(0x0488) +#define S5P_SPD_DATA27 S5P_HDMI_BASE(0x048c) +#define S5P_HDMI_CSC_CON S5P_HDMI_BASE(0x0490) +#define S5P_HDMI_Y_G_COEF_L S5P_HDMI_BASE(0x04A0) +#define S5P_HDMI_Y_G_COEF_H S5P_HDMI_BASE(0x04A4) +#define S5P_HDMI_Y_B_COEF_L S5P_HDMI_BASE(0x04A8) +#define S5P_HDMI_Y_B_COEF_H S5P_HDMI_BASE(0x04AC) +#define S5P_HDMI_Y_R_COEF_L S5P_HDMI_BASE(0x04B0) +#define S5P_HDMI_Y_R_COEF_H S5P_HDMI_BASE(0x04B4) +#define S5P_HDMI_CB_G_COEF_L S5P_HDMI_BASE(0x04B8) +#define S5P_HDMI_CB_G_COEF_H S5P_HDMI_BASE(0x04BC) +#define S5P_HDMI_CB_B_COEF_L S5P_HDMI_BASE(0x04C0) +#define S5P_HDMI_CB_B_COEF_H S5P_HDMI_BASE(0x04C4) +#define S5P_HDMI_CB_R_COEF_L S5P_HDMI_BASE(0x04C8) +#define S5P_HDMI_CB_R_COEF_H S5P_HDMI_BASE(0x04CC) +#define S5P_HDMI_CR_G_COEF_L S5P_HDMI_BASE(0x04D0) +#define S5P_HDMI_CR_G_COEF_H S5P_HDMI_BASE(0x04D4) +#define S5P_HDMI_CR_B_COEF_L S5P_HDMI_BASE(0x04D8) +#define S5P_HDMI_CR_B_COEF_H S5P_HDMI_BASE(0x04DC) +#define S5P_HDMI_CR_R_COEF_L S5P_HDMI_BASE(0x04E0) +#define S5P_HDMI_CR_R_COEF_H S5P_HDMI_BASE(0x04E4) + +#define S5P_HDCP_RX_SHA1_0_0 S5P_HDMI_BASE(0x0600) +#define S5P_HDCP_RX_SHA1_0_1 S5P_HDMI_BASE(0x0604) +#define S5P_HDCP_RX_SHA1_0_2 S5P_HDMI_BASE(0x0608) +#define S5P_HDCP_RX_SHA1_0_3 S5P_HDMI_BASE(0x060C) +#define S5P_HDCP_RX_SHA1_1_0 S5P_HDMI_BASE(0x0610) +#define S5P_HDCP_RX_SHA1_1_1 S5P_HDMI_BASE(0x0614) +#define S5P_HDCP_RX_SHA1_1_2 S5P_HDMI_BASE(0x0618) +#define S5P_HDCP_RX_SHA1_1_3 S5P_HDMI_BASE(0x061C) +#define S5P_HDCP_RX_SHA1_2_0 S5P_HDMI_BASE(0x0620) +#define S5P_HDCP_RX_SHA1_2_1 S5P_HDMI_BASE(0x0624) +#define S5P_HDCP_RX_SHA1_2_2 S5P_HDMI_BASE(0x0628) +#define S5P_HDCP_RX_SHA1_2_3 S5P_HDMI_BASE(0x062C) +#define S5P_HDCP_RX_SHA1_3_0 S5P_HDMI_BASE(0x0630) +#define S5P_HDCP_RX_SHA1_3_1 S5P_HDMI_BASE(0x0634) +#define S5P_HDCP_RX_SHA1_3_2 S5P_HDMI_BASE(0x0638) +#define S5P_HDCP_RX_SHA1_3_3 S5P_HDMI_BASE(0x063C) +#define S5P_HDCP_RX_SHA1_4_0 S5P_HDMI_BASE(0x0640) +#define S5P_HDCP_RX_SHA1_4_1 S5P_HDMI_BASE(0x0644) +#define S5P_HDCP_RX_SHA1_4_2 S5P_HDMI_BASE(0x0648) +#define S5P_HDCP_RX_SHA1_4_3 S5P_HDMI_BASE(0x064C) +#define S5P_HDCP_RX_KSV_0_0 S5P_HDMI_BASE(0x0650) +#define S5P_HDCP_RX_KSV_0_1 S5P_HDMI_BASE(0x0654) +#define S5P_HDCP_RX_KSV_0_2 S5P_HDMI_BASE(0x0658) +#define S5P_HDCP_RX_KSV_0_3 S5P_HDMI_BASE(0x065C) +#define S5P_HDCP_RX_KSV_0_4 S5P_HDMI_BASE(0x0660) +#define S5P_HDCP_RX_KSV_LIST_CTRL S5P_HDMI_BASE(0x0664) +#define S5P_HDCP_AUTH_STATUS S5P_HDMI_BASE(0x0670) +#define S5P_HDCP_CTRL S5P_HDMI_BASE(0x0680) +#define S5P_HDCP_CHECK_RESULT S5P_HDMI_BASE(0x0690) + +#define S5P_HDCP_BKSV_0_0 S5P_HDMI_BASE(0x06A0) +#define S5P_HDCP_BKSV_0_1 S5P_HDMI_BASE(0x06A4) +#define S5P_HDCP_BKSV_0_2 S5P_HDMI_BASE(0x06A8) +#define S5P_HDCP_BKSV_0_3 S5P_HDMI_BASE(0x06AC) +#define S5P_HDCP_BKSV_1 S5P_HDMI_BASE(0x06B0) +#define S5P_HDCP_AKSV_0_0 S5P_HDMI_BASE(0x06C0) +#define S5P_HDCP_AKSV_0_1 S5P_HDMI_BASE(0x06C4) +#define S5P_HDCP_AKSV_0_2 S5P_HDMI_BASE(0x06C8) +#define S5P_HDCP_AKSV_0_3 S5P_HDMI_BASE(0x06CC) +#define S5P_HDCP_AKSV_1 S5P_HDMI_BASE(0x06D0) +#define S5P_HDCP_An_0_0 S5P_HDMI_BASE(0x06E0) +#define S5P_HDCP_An_0_1 S5P_HDMI_BASE(0x06E4) +#define S5P_HDCP_An_0_2 S5P_HDMI_BASE(0x06E8) +#define S5P_HDCP_An_0_3 S5P_HDMI_BASE(0x06EC) +#define S5P_HDCP_An_1_0 S5P_HDMI_BASE(0x06F0) +#define S5P_HDCP_An_1_1 S5P_HDMI_BASE(0x06F4) +#define S5P_HDCP_An_1_2 S5P_HDMI_BASE(0x06F8) +#define S5P_HDCP_An_1_3 S5P_HDMI_BASE(0x06FC) +#define S5P_HDCP_BCAPS S5P_HDMI_BASE(0x0700) +#define S5P_HDCP_BSTATUS_0 S5P_HDMI_BASE(0x0710) +#define S5P_HDCP_BSTATUS_1 S5P_HDMI_BASE(0x0714) +#define S5P_HDCP_Ri_0 S5P_HDMI_BASE(0x0740) +#define S5P_HDCP_Ri_1 S5P_HDMI_BASE(0x0744) +#define S5P_HDCP_Pj S5P_HDMI_BASE(0x0750) +#define S5P_HDCP_OFFSET_TX_0 S5P_HDMI_BASE(0x0760) +#define S5P_HDCP_OFFSET_TX_1 S5P_HDMI_BASE(0x0764) +#define S5P_HDCP_OFFSET_TX_2 S5P_HDMI_BASE(0x0768) +#define S5P_HDCP_OFFSET_TX_3 S5P_HDMI_BASE(0x076C) +#define S5P_HDCP_CYCLE_AA S5P_HDMI_BASE(0x0770) +#define S5P_TG_CMD S5P_HDMI_BASE(0x1000) +#define S5P_TG_H_FSZ_L S5P_HDMI_BASE(0x1018) +#define S5P_TG_H_FSZ_H S5P_HDMI_BASE(0x101C) +#define S5P_TG_HACT_ST_L S5P_HDMI_BASE(0x1020) +#define S5P_TG_HACT_ST_H S5P_HDMI_BASE(0x1024) +#define S5P_TG_HACT_SZ_L S5P_HDMI_BASE(0x1028) +#define S5P_TG_HACT_SZ_H S5P_HDMI_BASE(0x102C) +#define S5P_TG_V_FSZ_L S5P_HDMI_BASE(0x1030) +#define S5P_TG_V_FSZ_H S5P_HDMI_BASE(0x1034) +#define S5P_TG_VSYNC_L S5P_HDMI_BASE(0x1038) +#define S5P_TG_VSYNC_H S5P_HDMI_BASE(0x103C) +#define S5P_TG_VSYNC2_L S5P_HDMI_BASE(0x1040) +#define S5P_TG_VSYNC2_H S5P_HDMI_BASE(0x1044) +#define S5P_TG_VACT_ST_L S5P_HDMI_BASE(0x1048) +#define S5P_TG_VACT_ST_H S5P_HDMI_BASE(0x104C) +#define S5P_TG_VACT_SZ_L S5P_HDMI_BASE(0x1050) +#define S5P_TG_VACT_SZ_H S5P_HDMI_BASE(0x1054) +#define S5P_TG_FIELD_CHG_L S5P_HDMI_BASE(0x1058) +#define S5P_TG_FIELD_CHG_H S5P_HDMI_BASE(0x105C) +#define S5P_TG_VACT_ST2_L S5P_HDMI_BASE(0x1060) +#define S5P_TG_VACT_ST2_H S5P_HDMI_BASE(0x1064) +#define S5P_TG_VSYNC_TOP_HDMI_L S5P_HDMI_BASE(0x1078) +#define S5P_TG_VSYNC_TOP_HDMI_H S5P_HDMI_BASE(0x107C) +#define S5P_TG_VSYNC_BOT_HDMI_L S5P_HDMI_BASE(0x1080) +#define S5P_TG_VSYNC_BOT_HDMI_H S5P_HDMI_BASE(0x1084) +#define S5P_TG_FIELD_TOP_HDMI_L S5P_HDMI_BASE(0x1088) +#define S5P_TG_FIELD_TOP_HDMI_H S5P_HDMI_BASE(0x108C) +#define S5P_TG_FIELD_BOT_HDMI_L S5P_HDMI_BASE(0x1090) +#define S5P_TG_FIELD_BOT_HDMI_H S5P_HDMI_BASE(0x1094) +#define S5P_SPDIFIN_CLK_CTRL S5P_HDMI_BASE(0x5000) +#define S5P_SPDIFIN_OP_CTRL S5P_HDMI_BASE(0x5004) +#define S5P_SPDIFIN_IRQ_MASK S5P_HDMI_BASE(0x5008) +#define S5P_SPDIFIN_IRQ_STATUS S5P_HDMI_BASE(0x500C) +#define S5P_SPDIFIN_CONFIG_1 S5P_HDMI_BASE(0x5010) +#define S5P_SPDIFIN_CONFIG_2 S5P_HDMI_BASE(0x5014) +#define S5P_SPDIFIN_USER_VALUE_1 S5P_HDMI_BASE(0x5020) +#define S5P_SPDIFIN_USER_VALUE_2 S5P_HDMI_BASE(0x5024) +#define S5P_SPDIFIN_USER_VALUE_3 S5P_HDMI_BASE(0x5028) +#define S5P_SPDIFIN_USER_VALUE_4 S5P_HDMI_BASE(0x502C) +#define S5P_SPDIFIN_CH_STATUS_0_1 S5P_HDMI_BASE(0x5030) +#define S5P_SPDIFIN_CH_STATUS_0_2 S5P_HDMI_BASE(0x5034) +#define S5P_SPDIFIN_CH_STATUS_0_3 S5P_HDMI_BASE(0x5038) +#define S5P_SPDIFIN_CH_STATUS_0_4 S5P_HDMI_BASE(0x503C) +#define S5P_SPDIFIN_CH_STATUS_1 S5P_HDMI_BASE(0x5040) +#define S5P_SPDIFIN_FRAME_PERIOD_1 S5P_HDMI_BASE(0x5048) +#define S5P_SPDIFIN_FRAME_PERIOD_2 S5P_HDMI_BASE(0x504C) +#define S5P_SPDIFIN_Pc_INFO_1 S5P_HDMI_BASE(0x5050) +#define S5P_SPDIFIN_Pc_INFO_2 S5P_HDMI_BASE(0x5054) +#define S5P_SPDIFIN_Pd_INFO_1 S5P_HDMI_BASE(0x5058) +#define S5P_SPDIFIN_Pd_INFO_2 S5P_HDMI_BASE(0x505C) +#define S5P_SPDIFIN_DATA_BUF_0_1 S5P_HDMI_BASE(0x5060) +#define S5P_SPDIFIN_DATA_BUF_0_2 S5P_HDMI_BASE(0x5064) +#define S5P_SPDIFIN_DATA_BUF_0_3 S5P_HDMI_BASE(0x5068) +#define S5P_SPDIFIN_USER_BUF_0 S5P_HDMI_BASE(0x506C) +#define S5P_SPDIFIN_DATA_BUF_1_1 S5P_HDMI_BASE(0x5070) +#define S5P_SPDIFIN_DATA_BUF_1_2 S5P_HDMI_BASE(0x5074) +#define S5P_SPDIFIN_DATA_BUF_1_3 S5P_HDMI_BASE(0x5078) +#define S5P_SPDIFIN_USER_BUF_1 S5P_HDMI_BASE(0x507C) +#define S5P_HAES_CON S5P_HDMI_BASE(0x6000) +#define S5P_HAES_DATA_SIZE_L S5P_HDMI_BASE(0x6020) +#define S5P_HAES_DATA_SIZE_H S5P_HDMI_BASE(0x6024) +#define S5P_HAES_DATA S5P_HDMI_BASE(0x6030) + +#define HDMI_TPGEN_0 S5P_HDMI_BASE(0x500) +#define HDMI_TPGEN_1 S5P_HDMI_BASE(0x504) +#define HDMI_TPGEN_2 S5P_HDMI_BASE(0x508) +#define HDMI_TPGEN_3 S5P_HDMI_BASE(0x50c) +#define HDMI_TPGEN_4 S5P_HDMI_BASE(0x510) +#define HDMI_TPGEN_5 S5P_HDMI_BASE(0x514) +#define HDMI_TPGEN_6 S5P_HDMI_BASE(0x518) + +#define BLUE_SCR_EN (1<<5) +#define BLUE_SCR_DIS (0<<5) +#define ASP_EN (1<<2) +#define ASP_DIS (0<<2) +#define PWDN_ENB_NORMAL (1<<1) +#define PWDN_ENB_PD (0<<1) +#define HDMI_EN (1<<0) +#define HDMI_DIS (~HDMI_EN) + +#define PX_LMT_CTRL_BYPASS (0<<5) +#define PX_LMT_CTRL_RGB (1<<5) +#define PX_LMT_CTRL_YPBPR (2<<5) +#define PX_LMT_CTRL_RESERVED (3<<5) + +#define VID_PREAMBLE_EN (0<<5) +#define VID_PREAMBLE_DIS (1<<5) +#define GUARD_BAND_EN (0<<1) +#define GUARD_BAND_DIS (1<<1) + + +#define AUTHEN_ACK_AUTH (1<<7) +#define AUTHEN_ACK_NOT (0<<7) +#define AUD_FIFO_OVF_FULL (1<<6) +#define AUD_FIFO_OVF_NOT (0<<6) +#define UPDATE_RI_INT_OCC (1<<4) +#define UPDATE_RI_INT_NOT (0<<4) +#define UPDATE_RI_INT_CLEAR (1<<4) +#define UPDATE_PJ_INT_OCC (1<<3) +#define UPDATE_PJ_INT_NOT (0<<3) +#define UPDATE_PJ_INT_CLEAR (1<<3) +#define EXCHANGEKSV_INT_OCC (1<<2) +#define EXCHANGEKSV_INT_NOT (0<<2) +#define EXCHANGEKSV_INT_CLEAR (1<<2) +#define WATCHDOG_INT_OCC (1<<1) +#define WATCHDOG_INT_NOT (0<<1) +#define WATCHDOG_INT_CLEAR (1<<1) +#define WTFORACTIVERX_INT_OCC (1) +#define WTFORACTIVERX_INT_NOT (0) +#define WTFORACTIVERX_INT_CLEAR (1) + +#define AUD_FIFO_OVF_EN (1<<6) +#define AUD_FIFO_OVF_DIS (0<<6) +#define UPDATE_RI_INT_EN (1<<4) +#define UPDATE_RI_INT_DIS (0<<4) +#define UPDATE_PJ_INT_EN (1<<3) +#define UPDATE_PJ_INT_DIS (0<<3) +#define EXCHANGEKSV_INT_EN (1<<2) +#define EXCHANGEKSV_INT_DIS (0<<2) +#define WATCHDOG_INT_EN (1<<1) +#define WATCHDOG_INT_DIS (0<<1) +#define WTFORACTIVERX_INT_EN (1) +#define WTFORACTIVERX_INT_DIS (0) +#define HDCP_STATUS_EN_ALL (UPDATE_RI_INT_EN|\ + UPDATE_PJ_INT_DIS|\ + EXCHANGEKSV_INT_EN|\ + WATCHDOG_INT_EN|\ + WTFORACTIVERX_INT_EN) + +#define HDCP_STATUS_DIS_ALL (~0x1f) + +#define SW_HPD_PLUGGED (1<<1) +#define SW_HPD_UNPLUGGED (0<<1) + +#define HDMI_MODE_EN (1<<1) +#define HDMI_MODE_DIS (0<<1) +#define DVI_MODE_EN (1) +#define DVI_MODE_DIS (0) + +#define HDCP_ENC_ENABLE (1) +#define HDCP_ENC_DISABLE (0) + +#define SET_BLUESCREEN_0(a) (0xff&(a)) + +#define SET_BLUESCREEN_1(a) (0xff&(a)) + +#define SET_BLUESCREEN_2(a) (0xff&(a)) + +#define SET_HDMI_YMAX(a) (0xff&(a)) + +#define SET_HDMI_YMIN(a) (0xff&(a)) + +#define SET_HDMI_CMAX(a) (0xff&(a)) + +#define SET_HDMI_CMIN(a) (0xff&(a)) + + +#define SET_VBI_ST_MG(a) (0xff&(a)) + +#define SET_VBI_END_MG(a) (0xff&(a)) + +#define SET_VACT_ST_MG(a) (0xff&(a)) + + +#define SET_H_BLANK_L(a) (0xff&(a)) + +#define SET_H_BLANK_H(a) (0x7&((a)>>8)) + +#define SET_V2_BLANK_L(a) (0xff&(a)) + +#define SET_V1_BLANK_L(a) ((0x1f&(a))<<3) +#define SET_V2_BLANK_H(a) (0x7&((a)>>8)) + +#define SET_V1_BLANK_H(a) (0x3f&((a)>>5)) + +#define SET_V_LINE_L(a) (0xff&(a)) + +#define SET_H_LINE_L(a) ((0xf&(a))<<4) +#define SET_V_LINE_H(a) (0xf&((a)>>8)) + +#define SET_H_LINE_H(a) (0xff&((a)>>4)) + +#define V_SYNC_POL_ACT_LOW (1) +#define V_SYNC_POL_ACT_HIGH (0) + +#define INT_PRO_MODE_INTERLACE (1) +#define INT_PRO_MODE_PROGRESSIVE (0) + +#define SET_V_BOT_ST_L(a) (0xff&(a)) + +#define SET_V_BOT_END_L(a) ((0x1f&(a))<<3) +#define SET_V_BOT_ST_H(a) (0x7&((a)>>8)) + +#define SET_V_BOT_END_H(a) (0x3f&((a)>>5)) + + +#define SET_HSYNC_START_L(a) (0xff&(a)) + +#define SET_HSYNC_END_L(a) ((0x3f&(a))<<2) +#define SET_HSYNC_START_H(a) (0x3&((a)>>8)) + +#define SET_HSYNC_POL_ACT_LOW (1<<4) +#define SET_HSYNC_POL_ACT_HIGH (0<<4) +#define SET_HSYNC_END_H(a) (0xf&((a)>>6)) + +#define SET_VSYNC_T_END_L(a) (0xff&(a)) + +#define SET_VSYNC_T_ST_L(a) ((0xf&(a))<<4) +#define SET_VSYNC_T_END_H(a) (0xf&((a)>>8)) + +#define SET_VSYNC_T_ST_H(a) (0xff&((a)>>4)) + +#define SET_VSYNC_B_END_L(a) (0xff&(a)) + +#define SET_VSYNC_B_ST_L(a) ((0xf&(a))<<4) +#define SET_VSYNC_B_END_H(a) (0xf&((a)>>8)) + +#define SET_VSYNC_B_ST_H(a) (0xff&((a)>>4)) + + +#define SET_VSYNC_H_POST_END_L(a) (0xff&(a)) + +#define SET_VSYNC_H_POST_ST_L(a) ((0xf&(a))<<4) +#define SET_VSYNC_H_POST_END_H(a) (0xf&((a)>>8)) + +#define SET_VSYNC_H_POST_ST_H(a) (0xff&((a)>>4)) + + +#define SACD_EN (1<<5) +#define SACD_DIS (0<<5) +#define AUD_MODE_MULTI_CH (1<<4) +#define AUD_MODE_2_CH (0<<4) +#define SET_SP_PRE(a) (0xf&(a)) + +#define SET_SP_FLAT(a) (0xf&(a)) + + +#define SPK3R_SEL_I_PCM0L (0<<27) +#define SPK3R_SEL_I_PCM0R (1<<27) +#define SPK3R_SEL_I_PCM1L (2<<27) +#define SPK3R_SEL_I_PCM1R (3<<27) +#define SPK3R_SEL_I_PCM2L (4<<27) +#define SPK3R_SEL_I_PCM2R (5<<27) +#define SPK3R_SEL_I_PCM3L (6<<27) +#define SPK3R_SEL_I_PCM3R (7<<27) +#define SPK3L_SEL_I_PCM0L (0<<24) +#define SPK3L_SEL_I_PCM0R (1<<24) +#define SPK3L_SEL_I_PCM1L (2<<24) +#define SPK3L_SEL_I_PCM1R (3<<24) +#define SPK3L_SEL_I_PCM2L (4<<24) +#define SPK3L_SEL_I_PCM2R (5<<24) +#define SPK3L_SEL_I_PCM3L (6<<24) +#define SPK3L_SEL_I_PCM3R (7<<24) +#define SPK2R_SEL_I_PCM0L (0<<19) +#define SPK2R_SEL_I_PCM0R (1<<19) +#define SPK2R_SEL_I_PCM1L (2<<19) +#define SPK2R_SEL_I_PCM1R (3<<19) +#define SPK2R_SEL_I_PCM2L (4<<19) +#define SPK2R_SEL_I_PCM2R (5<<19) +#define SPK2R_SEL_I_PCM3L (6<<19) +#define SPK2R_SEL_I_PCM3R (7<<19) +#define SPK2L_SEL_I_PCM0L (0<<16) +#define SPK2L_SEL_I_PCM0R (1<<16) +#define SPK2L_SEL_I_PCM1L (2<<16) +#define SPK2L_SEL_I_PCM1R (3<<16) +#define SPK2L_SEL_I_PCM2L (4<<16) +#define SPK2L_SEL_I_PCM2R (5<<16) +#define SPK2L_SEL_I_PCM3L (6<<16) +#define SPK2L_SEL_I_PCM3R (7<<16) +#define SPK1R_SEL_I_PCM0L (0<<11) +#define SPK1R_SEL_I_PCM0R (1<<11) +#define SPK1R_SEL_I_PCM1L (2<<11) +#define SPK1R_SEL_I_PCM1R (3<<11) +#define SPK1R_SEL_I_PCM2L (4<<11) +#define SPK1R_SEL_I_PCM2R (5<<11) +#define SPK1R_SEL_I_PCM3L (6<<11) +#define SPK1R_SEL_I_PCM3R (7<<11) +#define SPK1L_SEL_I_PCM0L (0<<8) +#define SPK1L_SEL_I_PCM0R (1<<8) +#define SPK1L_SEL_I_PCM1L (2<<8) +#define SPK1L_SEL_I_PCM1R (3<<8) +#define SPK1L_SEL_I_PCM2L (4<<8) +#define SPK1L_SEL_I_PCM2R (5<<8) +#define SPK1L_SEL_I_PCM3L (6<<8) +#define SPK1L_SEL_I_PCM3R (7<<8) +#define SPK0R_SEL_I_PCM0L (0<<3) +#define SPK0R_SEL_I_PCM0R (1<<3) +#define SPK0R_SEL_I_PCM1L (2<<3) +#define SPK0R_SEL_I_PCM1R (3<<3) +#define SPK0R_SEL_I_PCM2L (4<<3) +#define SPK0R_SEL_I_PCM2R (5<<3) +#define SPK0R_SEL_I_PCM3L (6<<3) +#define SPK0R_SEL_I_PCM3R (7<<3) +#define SPK0L_SEL_I_PCM0L (0) +#define SPK0L_SEL_I_PCM0R (1) +#define SPK0L_SEL_I_PCM1L (2) +#define SPK0L_SEL_I_PCM1R (3) +#define SPK0L_SEL_I_PCM2L (4) +#define SPK0L_SEL_I_PCM2R (5) +#define SPK0L_SEL_I_PCM3L (6) +#define SPK0L_SEL_I_PCM3R (7) + +#define ALT_CTS_RATE_CTS_1 (0<<3) +#define ALT_CTS_RATE_CTS_11 (1<<3) +#define ALT_CTS_RATE_CTS_21 (2<<3) +#define ALT_CTS_RATE_CTS_31 (3<<3) +#define ACR_TX_MODE_NO_TX (0) +#define ACR_TX_MODE_TX_ONCE (1) +#define ACR_TX_MODE_TXCNT_VBI (2) +#define ACR_TX_MODE_TX_VPC (3) +#define ACR_TX_MODE_MESURE_CTS (4) + + +#define SET_ACR_MCTS(a) (0xfffff&(a)) + + +#define SET_ACR_CTS(a) (0xfffff&(a)) + + +#define SET_ACR_N(a) (0xfffff&(a)) + +#define SET_ACR_LSB2(a) (0xff&(a)) + +#define SET_ACR_TXCNT(a) (0x1f&(a)) + +#define SET_ACR_TX_INTERNAL(a) (0xff&(a)) + +#define SET_ACR_CTS_OFFSET(a) (0xff&(a)) + +#define GCP_CON_NO_TRAN (0) +#define GCP_CON_TRANS_ONCE (1) +#define GCP_CON_TRANS_EVERY_VSYNC (2) + +#define SET_GCP_BYTE1(a) (0xff&(a)) + + +#define SET_ACP_FR_RATE(a) ((0x1f&(a))<<3) +#define ACP_CON_NO_TRAN (0) +#define ACP_CON_TRANS_ONCE (1) +#define ACP_CON_TRANS_EVERY_VSYNC (2) + +#define SET_ACP_TYPE(a) (0xff&(a)) + +#define SET_ACP_DATA(a) (0xff&(a)) + +#define SET_ISRC_FR_RATE(a) ((0x1f&(a))<<3) +#define ISRC_EN (1<<2) +#define ISRC_DIS (0<<2) +#define ISRC_TX_CON_NO_TRANS (0) +#define ISRC_TX_CON_TRANS_ONCE (1) +#define ISRC_TX_CON_TRANS_EVERY_VSYNC (2) + +#define SET_ISRC1_HEADER(a) (0xff&(a)) + +#define SET_ISRC1_DATA(a) (0xff&(a)) + +#define SET_ISRC2_DATA(a) (0xff&(a)) + + +#define AVI_TX_CON_NO_TRANS (0) +#define AVI_TX_CON_TRANS_ONCE (1) +#define AVI_TX_CON_TRANS_EVERY_VSYNC (2) + + +#define SET_AVI_CHECK_SUM(a) (0xff&(a)) + +#define SET_AVI_BYTE(a) (0xff&(a)) + + +#define AUI_TX_CON_NO_TRANS (0) +#define AUI_TX_CON_TRANS_ONCE (1) +#define AUI_TX_CON_TRANS_EVERY_VSYNC (2) + + +#define SET_AUI_CHECK_SUM(a) (0xff&(a)) + +#define SET_AUI_BYTE(a) (0xff&(a)) + + +#define MPG_TX_CON_NO_TRANS (0) +#define MPG_TX_CON_TRANS_ONCE (1) +#define MPG_TX_CON_TRANS_EVERY_VSYNC (2) + + +#define SET_MPG_CHECK_SUM(a) (0xff&(a)) + + +#define SET_MPG_BYTE(a) (0xff&(a)) + + +#define SPD_TX_CON_NO_TRANS (0) +#define SPD_TX_CON_TRANS_ONCE (1) +#define SPD_TX_CON_TRANS_EVERY_VSYNC (2) + + +#define SET_SPD_HEADER(a) (0xff&(a)) + +#define SET_SPD_DATA(a) (0xff&(a)) + + +#define OUT_OFFSET_SEL_RGB_FR (0<<4) +#define OUT_OFFSET_SEL_RGB_LR (2<<4) +#define OUT_OFFSET_SEL_YCBCR (3<<4) +#define IN_CLIP_EN (1<<2) +#define IN_CLIP_DIS (0<<2) +#define IN_OFFSET_SEL_RGB_FR (0) +#define IN_OFFSET_SEL_RGB_LR (2) +#define IN_OFFSET_SEL_YCBCR (3) + +#define SET_HDMI_CSC_COEF_L(a) (0xff&(a)) +#define SET_HDMI_CSC_COEF_H(a) (0x3&((a)>>8)) + +#define SET_HDMI_SHA1(a) (0xff&(a)) + +#define GETSYNC_TYPE_EN (1<<4) +#define GETSYNC_TYPE_DIS (0<<4) +#define GETSYNC_EN (1<<3) +#define GETSYNC_DIS (0<<3) +#define FIELD_EN (1<<2) +#define FIELD_DIS (0<<2) +#define TG_EN (1) +#define TG_DIS (0) + +#define SET_TG_H_FSZ_L(a) (0xff&(a)) + +#define SET_TG_H_FSZ_H(a) (0x1f&((a)>>8)) + +#define SET_TG_HACT_ST_L(a) (0xff&(a)) + +#define SET_TG_HACT_ST_H(a) (0xf&((a)>>8)) + +#define SET_TG_HACT_SZ_L(a) (0xff&(a)) + +#define SET_TG_HACT_SZ_H(a) (0xf&((a)>>8)) + +#define SET_TG_V_FSZ_L(a) (0xff&(a)) + +#define SET_TG_V_FSZ_H(a) (0x7&((a)>>8)) + +#define SET_TG_VSYNC_L(a) (0xff&(a)) + +#define SET_TG_VSYNC_H(a) (0x7&((a)>>8)) + +#define SET_TG_VSYNC2_L(a) (0xff&(a)) + +#define SET_TG_VSYNC2_H(a) (0x7&((a)>>8)) + +#define SET_TG_VACT_ST_L(a) (0xff&(a)) + +#define SET_TG_VACT_ST_H(a) (0x7&((a)>>8)) + +#define SET_TG_VACT_SZ_L(a) (0xff&(a)) + +#define SET_TG_VACT_SZ_H(a) (0x7&((a)>>8)) + +#define SET_TG_FIELD_CHG_L(a) (0xff&(a)) + +#define SET_TG_FIELD_CHG_H(a) (0x7&((a)>>8)) + +#define SET_TG_VACT_ST2_L(a) (0xff&(a)) + +#define SET_TG_VACT_ST2_H(a) (0x7&((a)>>8)) + +#define SET_TG_VSYNC_TOP_HDMI_L(a) (0xff&(a)) + +#define SET_TG_VSYNC_TOP_HDMI_H(a) (0x7&((a)>>8)) + +#define SET_TG_VSYNC_BOT_HDMI_L(a) (0xff&(a)) + +#define SET_TG_VSYNC_BOT_HDMI_H(a) (0x7&((a)>>8)) + +#define SET_TG_FIELD_TOP_HDMI_L(a) (0xff&(a)) + +#define SET_TG_FIELD_TOP_HDMI_H(a) (0x7&((a)>>8)) + +#define SET_TG_FIELD_BOT_HDMI_L(a) (0xff&(a)) + +#define SET_TG_FIELD_BOT_HDMI_H(a) (0x7&((a)>>8)) + + +#define IRQ_WRONG_SIGNAL_ENABLE (1<<0) +#define IRQ_CH_STATUS_RECOVERED_ENABLE (1<<1) +#define IRQ_WRONG_PREAMBLE_ENABLE (1<<2) +#define IRQ_STREAM_HEADER_NOT_DETECTED_ENABLE (1<<3) +#define IRQ_STREAM_HEADER_DETECTED_ENABLE (1<<4) +#define IRQ_STREAM_HEADER_NOT_DETECTED_AT_RIGHTTIME_ENABLE (1<<5) +#define IRQ_ABNORMAL_PD_ENABLE (1<<6) +#define IRQ_BUFFER_OVERFLOW_ENABLE (1<<7) + +#define CONFIG_FILTER_3_SAMPLE (0<<6) +#define CONFIG_FILTER_2_SAMPLE (1<<6) +#define CONFIG_LINEAR_PCM_TYPE (0<<5) +#define CONFIG_NON_LINEAR_PCM_TYPE (1<<5) +#define CONFIG_PCPD_AUTO_SET (0<<4) +#define CONFIG_PCPD_MANUAL_SET (1<<4) +#define CONFIG_WORD_LENGTH_AUTO_SET (0<<3) +#define CONFIG_WORD_LENGTH_MANUAL_SET (1<<3) +#define CONFIG_U_V_C_P_NEGLECT (0<<2) +#define CONFIG_U_V_C_P_REPORT (1<<2) +#define CONFIG_BURST_SIZE_1 (0<<1) +#define CONFIG_BURST_SIZE_2 (1<<1) +#define CONFIG_DATA_ALIGN_16BIT (0<<0) +#define CONFIG_DATA_ALIGN_32BIT (1<<0) + + +#define AUTHEN_ACK_POS 7 +#define AUD_FIFO_OVF_POS 6 + +#define UPDATE_RI_INT_POS 4 +#define UPDATE_PJ_INT_POS 3 +#define EXCHANGEKSV_INT_POS 2 +#define WATCHDOG_INT_POS 1 +#define WTFORACTIVERX_INT_POS 0 + +#define AUTHENTICATED (0x1<<7) +#define NOT_YET_AUTHENTICATED (0x0<<7) +#define AUD_FIFO_OVF_INT_OCCURRED (0x1<<6) +#define AUD_FIFO_OVF_INT_NOT_OCCURRED (0x0<<6) + +#define UPDATE_RI_INT_OCCURRED (0x1<<4) +#define UPDATE_RI_INT_NOT_OCCURRED (0x0<<4) +#define UPDATE_PJ_INT_OCCURRED (0x1<<3) +#define UPDATE_PJ_INT_NOT_OCCURRED (0x0<<3) +#define EXCHANGEKSV_INT_OCCURRED (0x1<<2) +#define EXCHANGEKSV_INT_NOT_OCCURRED (0x0<<2) +#define WATCHDOG_INT_OCCURRED (0x1<<1) +#define WATCHDOG_INT_NOT_OCCURRED (0x0<<1) +#define WTFORACTIVERX_INT_OCCURRED (0x1<<0) +#define WTFORACTIVERX_INT_NOT_OCCURRED (0x0<<0) + +#define AUD_FIFO_OVF_INT_EN (0x1<<6) +#define AUD_FIFO_OVF_INT_DIS (0x0<<6) + + + +#define EN_PJ_EN (0x1<<4) +#define EN_PJ_DIS (~EN_PJ_EN) + +#define SET_REPEATER_TIMEOUT (0x1<<2) +#define CLEAR_REPEATER_TIMEOUT (~SET_REPEATER_TIMEOUT) +#define CP_DESIRED_EN (0x1<<1) +#define CP_DESIRED_DIS (~CP_DESIRED_EN) +#define ENABLE_1_DOT_1_FEATURE_EN (0x1<<0) +#define ENABLE_1_DOT_1_FEATURE_DIS (~ENABLE_1_DOT_1_FEATURE_EN) + +#define Pi_MATCH_RESULT__YES ((0x1<<3)<<(0x1<<2)) +#define Pi_MATCH_RESULT__NO ((0x1<<3)<<(0x0<<2)) +#define Ri_MATCH_RESULT__YES ((0x1<<1)<<(0x1<<0)) +#define Ri_MATCH_RESULT__NO ((0x1<<1)<<(0x0<<0)) +#define CLEAR_ALL_RESULTS 0x0 + +#define HDCP_ENC_DIS (0x0<<0) + +#define REPEATER_SET (0x1<<6) +#define REPEATERP_CLEAR (0x1<<6) +#define READY_SET (0x1<<5) +#define READY_CLEAR (0x1<<5) +#define FAST_SET (0x1<<4) +#define FAST_CLEAR (0x1<<4) + +#define ONE_DOT_ONE_FEATURES_SET (0x1<<1) +#define ONE_DOT_ONE_FEATURES_CLEAR (0x1<<1) +#define FAST_REAUTHENTICATION_SET (0x1<<0) +#define FAST_REAUTHENTICATION_CLEAR (0x1<<0) + + +#define SCRAMBLER_KEY_START_EN (0x1<<7) +#define SCRAMBLER_KEY_START_DIS (~SCRAMBLER_KEY_START_EN) +#define SCRAMBLER_KEY_DONE (0x1<<6) +#define SCRAMBLER_KEY_GENERATING (0x0<<6) +#define HAES_START_EN (0x1<<0) +#define HAES_DECRYPTION_DONE (0x0<<0) + + +#define AN_SIZE 8 +#define AKSV_SIZE 5 +#define BKSV_SIZE 5 +#define HDCPLink_Addr 0x74 + + +#define CABLE_PLUGGED (1<<1) +#define CABLE_UNPLUGGED (0<<1) + +#define DDC_Addr 0xA0 +#define eDDC_Addr 0x60 +#define HDCPLink_Addr 0x74 + +#define HDCP_Bksv 0x00 +#define HDCP_Aksv 0x10 +#define HDCP_Ainfo 0x15 +#define HDCP_An 0x18 +#define HDCP_Ri 0x08 +#define HDCP_Bcaps 0x40 +#define HDCP_BStatus 0x41 +#define HDCP_Pj 0x0a + +#define HDCP_KSVFIFO 0x43 +#define HDCP_SHA1 0x20 + +#define HDMI_MODE_HDMI 0 +#define HDMI_MODE_DVI 1 + +#define EDID_SEGMENT_ID 0x60 +#define EDID_SEGMENT0 0x00 +#define EDID_SEGMENT1 0x01 + +#define EDID_DEVICE_ID 0xA0 +#define EDID_ADDR_START 0x00 +#define EDID_ADDR_EXT 0x80 +#define EDID_RCOUNT 127 + +#define EDID_POS_EXTENSION 0x7E +#define EDID_POS_CHECKSUM 0x7F +#define VALID_EDID 0xA5 +#define NO_VALID_EDID 0 + +#define EDID_POS_RBUFFER0 0x00 +#define EDID_POS_RBUFFER1 0x80 +#define EDID_POS_RBUFFER2 0x100 +#define EDID_POS_RBUFFER3 0x180 + +#define EDID_TIMING_EXT_TAG_ADDR_POS 0x80 +#define EDID_TIMING_EXT_REV_NUMBER 0x81 +#define EDID_DETAILED_TIMING_OFFSET_POS 0x82 +#define EDID_COLOR_SPACE_ADDR 0x83 +#define EDID_DATA_BLOCK_ADDRESS 0x84 +#define EDID_TIMING_EXT_TAG_VAL 0x02 +#define EDID_YCBCR444_CS_MASK 0x20 +#define EDID_YCBCR422_CS_MASK 0x10 +#define EDID_TAG_CODE_MASK 0xE0 +#define EDID_DATA_BLOCK_SIZE_MASK 0x1F +#define EDID_NATIVE_RESOLUTION_MASK 0x80 + +#define EDID_SHORT_AUD_DEC_TAG 0x20 +#define EDID_SHORT_VID_DEC_TAG 0x40 +#define EDID_HDMI_VSDB_TAG 0x60 +#define EDID_SPEAKER_ALLOCATION_TAG 0x80 + +#define COLOR_SPACE_RGB 0 +#define COLOR_SPACE_YCBCR444 1 +#define COLOR_SPACE_YCBCR422 2 + +#define SHORT_VID_720_480P_4_3_NT 0x01 +#define SHORT_VID_720_480P_16_9_NT 0x02 +#define SHORT_VID_1280_720P_16_9_NT 0x04 +#define SHORT_VID_1920_1080i_16_9_NT 0x08 +#define SHORT_VID_720_576P_4_3_PAL 0x10 +#define SHORT_VID_720_576P_16_9_PAL 0x20 +#define SHORT_VID_1280_720P_16_9_PAL 0x40 +#define SHORT_VID_1920_1080i_16_9_PAL 0x80 + +#define SET_HDMI_RESOLUTION_480P 0x00 +#define SET_HDMI_RESOLUTION_720P 0x01 +#define SET_HDMI_RESOLUTION_1080i 0x02 + + +#define HDMI_WAIT_TIMEOUT 20 +#define AUTHENTICATION_SUCCESS 0 +#define AUTHENTICATION_FAILURE 1 +#define AUTHENTICATION_FAIL_CNT 2 + + +#define HDCP_MAX_DEVS 128 +#define HDCP_KSV_SIZE 5 + +#define CMD_IIC_ADDRMODE_CHANGE 0xFF + +#define IIC_ADDRMODE_1 0 +#define IIC_ADDRMODE_2 1 +#define IIC_ADDRMODE_3 2 +#define HDMI_IIC_ADDRMODE IIC_ADDRMODE_1 + +#define IIC_ACK 0 +#define IIC_NOACK 1 + +#define EDID_POS_ERROR 512 +#define R_VAL_RETRY_CNT 5 + +#define CABLE_INSERT 1 +#define CABLE_REMOVE (~CABLE_INSERT) + +#endif + + diff --git a/drivers/media/video/samsung/tv20/s5pc100/regs/regs-sdaout.h b/drivers/media/video/samsung/tv20/s5pc100/regs/regs-sdaout.h new file mode 100644 index 0000000..02dacd0 --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5pc100/regs/regs-sdaout.h @@ -0,0 +1,455 @@ +/* linux/drivers/media/video/samsung/tv20/s5pc100/regs/regs-sdout.h + * + * TV Encoder register header file for Samsung TVOut driver + * + * Copyright (c) 2009 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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. +*/ + +#ifndef __ASM_ARCH_REGS_SDAOUT_H + +#include <mach/map.h> + +#define S5P_SDAOUT_BASE(x) (x) + +#define S5P_SDO_CLKCON S5P_SDAOUT_BASE(0x0000) +#define S5P_SDO_CONFIG S5P_SDAOUT_BASE(0x0008) +#define S5P_SDO_SCALE S5P_SDAOUT_BASE(0x000C) +#define S5P_SDO_SYNC S5P_SDAOUT_BASE(0x0010) +#define S5P_SDO_VBI S5P_SDAOUT_BASE(0x0014) +#define S5P_SDO_SCALE_CH0 S5P_SDAOUT_BASE(0x001C) +#define S5P_SDO_SCALE_CH1 S5P_SDAOUT_BASE(0x0020) +#define S5P_SDO_SCALE_CH2 S5P_SDAOUT_BASE(0x0024) +#define S5P_SDO_YCDELAY S5P_SDAOUT_BASE(0x0034) +#define S5P_SDO_SCHLOCK S5P_SDAOUT_BASE(0x0038) +#define S5P_SDO_DAC S5P_SDAOUT_BASE(0x003C) +#define S5P_SDO_FINFO S5P_SDAOUT_BASE(0x0040) +#define S5P_SDO_Y0 S5P_SDAOUT_BASE(0x0044) +#define S5P_SDO_Y1 S5P_SDAOUT_BASE(0x0048) +#define S5P_SDO_Y2 S5P_SDAOUT_BASE(0x004C) +#define S5P_SDO_Y3 S5P_SDAOUT_BASE(0x0050) +#define S5P_SDO_Y4 S5P_SDAOUT_BASE(0x0054) +#define S5P_SDO_Y5 S5P_SDAOUT_BASE(0x0058) +#define S5P_SDO_Y6 S5P_SDAOUT_BASE(0x005C) +#define S5P_SDO_Y7 S5P_SDAOUT_BASE(0x0060) +#define S5P_SDO_Y8 S5P_SDAOUT_BASE(0x0064) +#define S5P_SDO_Y9 S5P_SDAOUT_BASE(0x0068) +#define S5P_SDO_Y10 S5P_SDAOUT_BASE(0x006C) +#define S5P_SDO_Y11 S5P_SDAOUT_BASE(0x0070) +#define S5P_SDO_CB0 S5P_SDAOUT_BASE(0x0080) +#define S5P_SDO_CB1 S5P_SDAOUT_BASE(0x0084) +#define S5P_SDO_CB2 S5P_SDAOUT_BASE(0x0088) +#define S5P_SDO_CB3 S5P_SDAOUT_BASE(0x008C) +#define S5P_SDO_CB4 S5P_SDAOUT_BASE(0x0090) +#define S5P_SDO_CB5 S5P_SDAOUT_BASE(0x0094) +#define S5P_SDO_CB6 S5P_SDAOUT_BASE(0x0098) +#define S5P_SDO_CB7 S5P_SDAOUT_BASE(0x009C) +#define S5P_SDO_CB8 S5P_SDAOUT_BASE(0x00A0) +#define S5P_SDO_CB9 S5P_SDAOUT_BASE(0x00A4) +#define S5P_SDO_CB10 S5P_SDAOUT_BASE(0x00A8) +#define S5P_SDO_CB11 S5P_SDAOUT_BASE(0x00AC) +#define S5P_SDO_CR0 S5P_SDAOUT_BASE(0x00C0) +#define S5P_SDO_CR1 S5P_SDAOUT_BASE(0x00C4) +#define S5P_SDO_CR2 S5P_SDAOUT_BASE(0x00C8) +#define S5P_SDO_CR3 S5P_SDAOUT_BASE(0x00CC) +#define S5P_SDO_CR4 S5P_SDAOUT_BASE(0x00D0) +#define S5P_SDO_CR5 S5P_SDAOUT_BASE(0x00D4) +#define S5P_SDO_CR6 S5P_SDAOUT_BASE(0x00D8) +#define S5P_SDO_CR7 S5P_SDAOUT_BASE(0x00DC) +#define S5P_SDO_CR8 S5P_SDAOUT_BASE(0x00E0) +#define S5P_SDO_CR9 S5P_SDAOUT_BASE(0x00E4) +#define S5P_SDO_CR10 S5P_SDAOUT_BASE(0x00E8) +#define S5P_SDO_CR11 S5P_SDAOUT_BASE(0x00EC) +#define S5P_SDO_MV_ON S5P_SDAOUT_BASE(0x0100) +#define S5P_SDO_MV_SLINE_FIRST_EVEN S5P_SDAOUT_BASE(0x0104) +#define S5P_SDO_MV_SLINE_FIRST_SPACE_EVEN S5P_SDAOUT_BASE(0x0108) +#define S5P_SDO_MV_SLINE_FIRST_ODD S5P_SDAOUT_BASE(0x010C) +#define S5P_SDO_MV_SLINE_FIRST_SPACE_ODD S5P_SDAOUT_BASE(0x0110) +#define S5P_SDO_MV_SLINE_SPACING S5P_SDAOUT_BASE(0x0114) +#define S5P_SDO_MV_STRIPES_NUMBER S5P_SDAOUT_BASE(0x0118) +#define S5P_SDO_MV_STRIPES_THICKNESS S5P_SDAOUT_BASE(0x011C) +#define S5P_SDO_MV_PSP_DURATION S5P_SDAOUT_BASE(0x0120) +#define S5P_SDO_MV_PSP_FIRST S5P_SDAOUT_BASE(0x0124) +#define S5P_SDO_MV_PSP_SPACING S5P_SDAOUT_BASE(0x0128) +#define S5P_SDO_MV_SEL_LINE_PSP_AGC S5P_SDAOUT_BASE(0x012C) +#define S5P_SDO_MV_SEL_FORMAT_PSP_AGC S5P_SDAOUT_BASE(0x0130) +#define S5P_SDO_MV_PSP_AGC_A_ON S5P_SDAOUT_BASE(0x0134) +#define S5P_SDO_MV_PSP_AGC_B_ON S5P_SDAOUT_BASE(0x0138) +#define S5P_SDO_MV_BACK_PORCH S5P_SDAOUT_BASE(0x013C) +#define S5P_SDO_MV_BURST_ADVANCED_ON S5P_SDAOUT_BASE(0x0140) +#define S5P_SDO_MV_BURST_DURATION_ZONE1 S5P_SDAOUT_BASE(0x0144) +#define S5P_SDO_MV_BURST_DURATION_ZONE2 S5P_SDAOUT_BASE(0x0148) +#define S5P_SDO_MV_BURST_DURATION_ZONE3 S5P_SDAOUT_BASE(0x014C) +#define S5P_SDO_MV_BURST_PHASE_ZONE S5P_SDAOUT_BASE(0x0150) +#define S5P_SDO_MV_SLICE_PHASE_LINE S5P_SDAOUT_BASE(0x0154) +#define S5P_SDO_MV_RGB_PROTECTION_ON S5P_SDAOUT_BASE(0x0158) +#define S5P_SDO_MV_480P_PROTECTION_ON S5P_SDAOUT_BASE(0x015C) +#define S5P_SDO_CCCON S5P_SDAOUT_BASE(0x0180) +#define S5P_SDO_YSCALE S5P_SDAOUT_BASE(0x0184) +#define S5P_SDO_CBSCALE S5P_SDAOUT_BASE(0x0188) +#define S5P_SDO_CRSCALE S5P_SDAOUT_BASE(0x018C) +#define S5P_SDO_CB_CR_OFFSET S5P_SDAOUT_BASE(0x0190) +#define S5P_SDO_RGB_CC S5P_SDAOUT_BASE(0x0194) +#define S5P_SDO_CVBS_CC_Y1 S5P_SDAOUT_BASE(0x0198) +#define S5P_SDO_CVBS_CC_Y2 S5P_SDAOUT_BASE(0x019C) +#define S5P_SDO_CVBS_CC_C S5P_SDAOUT_BASE(0x01A0) +#define S5P_SDO_YC_CC_Y S5P_SDAOUT_BASE(0x01A4) +#define S5P_SDO_YC_CC_C S5P_SDAOUT_BASE(0x01A8) +#define S5P_SDO_CSC_525_PORCH S5P_SDAOUT_BASE(0x01B0) +#define S5P_SDO_CSC_625_PORCH S5P_SDAOUT_BASE(0x01B4) +#define S5P_SDO_RGBSYNC S5P_SDAOUT_BASE(0x01C0) +#define S5P_SDO_OSFC00_0 S5P_SDAOUT_BASE(0x0200) +#define S5P_SDO_OSFC01_0 S5P_SDAOUT_BASE(0x0204) +#define S5P_SDO_OSFC02_0 S5P_SDAOUT_BASE(0x0208) +#define S5P_SDO_OSFC03_0 S5P_SDAOUT_BASE(0x020C) +#define S5P_SDO_OSFC04_0 S5P_SDAOUT_BASE(0x0210) +#define S5P_SDO_OSFC05_0 S5P_SDAOUT_BASE(0x0214) +#define S5P_SDO_OSFC06_0 S5P_SDAOUT_BASE(0x0218) +#define S5P_SDO_OSFC07_0 S5P_SDAOUT_BASE(0x021C) +#define S5P_SDO_OSFC08_0 S5P_SDAOUT_BASE(0x0220) +#define S5P_SDO_OSFC09_0 S5P_SDAOUT_BASE(0x0224) +#define S5P_SDO_OSFC10_0 S5P_SDAOUT_BASE(0x0228) +#define S5P_SDO_OSFC11_0 S5P_SDAOUT_BASE(0x022C) +#define S5P_SDO_OSFC12_0 S5P_SDAOUT_BASE(0x0230) +#define S5P_SDO_OSFC13_0 S5P_SDAOUT_BASE(0x0234) +#define S5P_SDO_OSFC14_0 S5P_SDAOUT_BASE(0x0238) +#define S5P_SDO_OSFC15_0 S5P_SDAOUT_BASE(0x023C) +#define S5P_SDO_OSFC16_0 S5P_SDAOUT_BASE(0x0240) +#define S5P_SDO_OSFC17_0 S5P_SDAOUT_BASE(0x0244) +#define S5P_SDO_OSFC18_0 S5P_SDAOUT_BASE(0x0248) +#define S5P_SDO_OSFC19_0 S5P_SDAOUT_BASE(0x024C) +#define S5P_SDO_OSFC20_0 S5P_SDAOUT_BASE(0x0250) +#define S5P_SDO_OSFC21_0 S5P_SDAOUT_BASE(0x0254) +#define S5P_SDO_OSFC22_0 S5P_SDAOUT_BASE(0x0258) +#define S5P_SDO_OSFC23_0 S5P_SDAOUT_BASE(0x025C) +#define S5P_SDO_XTALK0 S5P_SDAOUT_BASE(0x0260) +#define S5P_SDO_XTALK1 S5P_SDAOUT_BASE(0x0264) +#define S5P_SDO_XTALK2 S5P_SDAOUT_BASE(0x0268) +#define S5P_SDO_BB_CTRL S5P_SDAOUT_BASE(0x026C) +#define S5P_SDO_IRQ S5P_SDAOUT_BASE(0x0280) +#define S5P_SDO_IRQMASK S5P_SDAOUT_BASE(0x0284) +#define S5P_SDO_OSFC00_1 S5P_SDAOUT_BASE(0x02C0) +#define S5P_SDO_OSFC01_1 S5P_SDAOUT_BASE(0x02C4) +#define S5P_SDO_OSFC02_1 S5P_SDAOUT_BASE(0x02C8) +#define S5P_SDO_OSFC03_1 S5P_SDAOUT_BASE(0x02CC) +#define S5P_SDO_OSFC04_1 S5P_SDAOUT_BASE(0x02D0) +#define S5P_SDO_OSFC05_1 S5P_SDAOUT_BASE(0x02D4) +#define S5P_SDO_OSFC06_1 S5P_SDAOUT_BASE(0x02D8) +#define S5P_SDO_OSFC07_1 S5P_SDAOUT_BASE(0x02DC) +#define S5P_SDO_OSFC08_1 S5P_SDAOUT_BASE(0x02E0) +#define S5P_SDO_OSFC09_1 S5P_SDAOUT_BASE(0x02E4) +#define S5P_SDO_OSFC10_1 S5P_SDAOUT_BASE(0x02E8) +#define S5P_SDO_OSFC11_1 S5P_SDAOUT_BASE(0x02EC) +#define S5P_SDO_OSFC12_1 S5P_SDAOUT_BASE(0x02E0) +#define S5P_SDO_OSFC13_1 S5P_SDAOUT_BASE(0x02F4) +#define S5P_SDO_OSFC14_1 S5P_SDAOUT_BASE(0x02F8) +#define S5P_SDO_OSFC15_1 S5P_SDAOUT_BASE(0x02FC) +#define S5P_SDO_OSFC16_1 S5P_SDAOUT_BASE(0x0300) +#define S5P_SDO_OSFC17_1 S5P_SDAOUT_BASE(0x0304) +#define S5P_SDO_OSFC18_1 S5P_SDAOUT_BASE(0x0308) +#define S5P_SDO_OSFC19_1 S5P_SDAOUT_BASE(0x030C) +#define S5P_SDO_OSFC20_1 S5P_SDAOUT_BASE(0x0310) +#define S5P_SDO_OSFC21_1 S5P_SDAOUT_BASE(0x0314) +#define S5P_SDO_OSFC22_1 S5P_SDAOUT_BASE(0x0318) +#define S5P_SDO_OSFC23_1 S5P_SDAOUT_BASE(0x031C) +#define S5P_SDO_OSFC00_2 S5P_SDAOUT_BASE(0x0320) +#define S5P_SDO_OSFC01_2 S5P_SDAOUT_BASE(0x0324) +#define S5P_SDO_OSFC02_2 S5P_SDAOUT_BASE(0x0328) +#define S5P_SDO_OSFC03_2 S5P_SDAOUT_BASE(0x032C) +#define S5P_SDO_OSFC04_2 S5P_SDAOUT_BASE(0x0330) +#define S5P_SDO_OSFC05_2 S5P_SDAOUT_BASE(0x0334) +#define S5P_SDO_OSFC06_2 S5P_SDAOUT_BASE(0x0338) +#define S5P_SDO_OSFC07_2 S5P_SDAOUT_BASE(0x033C) +#define S5P_SDO_OSFC08_2 S5P_SDAOUT_BASE(0x0340) +#define S5P_SDO_OSFC09_2 S5P_SDAOUT_BASE(0x0344) +#define S5P_SDO_OSFC10_2 S5P_SDAOUT_BASE(0x0348) +#define S5P_SDO_OSFC11_2 S5P_SDAOUT_BASE(0x034C) +#define S5P_SDO_OSFC12_2 S5P_SDAOUT_BASE(0x0350) +#define S5P_SDO_OSFC13_2 S5P_SDAOUT_BASE(0x0354) +#define S5P_SDO_OSFC14_2 S5P_SDAOUT_BASE(0x0358) +#define S5P_SDO_OSFC15_2 S5P_SDAOUT_BASE(0x035C) +#define S5P_SDO_OSFC16_2 S5P_SDAOUT_BASE(0x0360) +#define S5P_SDO_OSFC17_2 S5P_SDAOUT_BASE(0x0364) +#define S5P_SDO_OSFC18_2 S5P_SDAOUT_BASE(0x0368) +#define S5P_SDO_OSFC19_2 S5P_SDAOUT_BASE(0x036C) +#define S5P_SDO_OSFC20_2 S5P_SDAOUT_BASE(0x0370) +#define S5P_SDO_OSFC21_2 S5P_SDAOUT_BASE(0x0374) +#define S5P_SDO_OSFC22_2 S5P_SDAOUT_BASE(0x0378) +#define S5P_SDO_OSFC23_2 S5P_SDAOUT_BASE(0x037C) +#define S5P_SDO_ARMCC S5P_SDAOUT_BASE(0x03C0) +#define S5P_SDO_ARMWSS525 S5P_SDAOUT_BASE(0x03C4) +#define S5P_SDO_ARMWSS625 S5P_SDAOUT_BASE(0x03C8) +#define S5P_SDO_ARMCGMS525 S5P_SDAOUT_BASE(0x03CC) +#define S5P_SDO_ARMCGMS625 S5P_SDAOUT_BASE(0x03D4) +#define S5P_SDO_VERSION S5P_SDAOUT_BASE(0x03D8) +#define S5P_SDO_CC S5P_SDAOUT_BASE(0x0380) +#define S5P_SDO_WSS525 S5P_SDAOUT_BASE(0x0384) +#define S5P_SDO_WSS625 S5P_SDAOUT_BASE(0x0388) +#define S5P_SDO_CGMS525 S5P_SDAOUT_BASE(0x038C) +#define S5P_SDO_CGMS625 S5P_SDAOUT_BASE(0x0394) + +#define SDO_TVOUT_SW_RESET (1<<4) +#define SDO_TVOUT_CLOCK_ON (1) +#define SDO_TVOUT_CLOCK_OFF (0) + +#define SDO_DAC2_Y_G (0<<20) +#define SDO_DAC2_PB_B (1<<20) +#define SDO_DAC2_PR_R (2<<20) +#define SDO_DAC1_Y_G (0<<18) +#define SDO_DAC1_PB_B (1<<18) +#define SDO_DAC1_PR_R (2<<18) +#define SDO_DAC0_Y_G (0<<16) +#define SDO_DAC0_PB_B (1<<16) +#define SDO_DAC0_PR_R (2<<16) +#define SDO_DAC2_CVBS (0<<12) +#define SDO_DAC2_Y (1<<12) +#define SDO_DAC2_C (2<<12) +#define SDO_DAC1_CVBS (0<<10) +#define SDO_DAC1_Y (1<<10) +#define SDO_DAC1_C (2<<10) +#define SDO_DAC0_CVBS (0<<8) +#define SDO_DAC0_Y (1<<8) +#define SDO_DAC0_C (2<<8) +#define SDO_COMPOSITE (0<<6) +#define SDO_COMPONENT (1<<6) +#define SDO_RGB (0<<5) +#define SDO_YPBPR (1<<5) +#define SDO_INTERLACED (0<<4) +#define SDO_PROGRESSIVE (1<<4) +#define SDO_NTSC_M (0) +#define SDO_PAL_M (1) +#define SDO_PAL_BGHID (2) +#define SDO_PAL_N (3) +#define SDO_PAL_NC (4) +#define SDO_NTSC_443 (8) +#define SDO_PAL_60 (9) + +#define SDO_COMPONENT_LEVEL_SEL_0IRE (0<<3) +#define SDO_COMPONENT_LEVEL_SEL_75IRE (1<<3) +#define SDO_COMPONENT_VTOS_RATIO_10_4 (0<<2) +#define SDO_COMPONENT_VTOS_RATIO_7_3 (1<<2) +#define SDO_COMPOSITE_LEVEL_SEL_0IRE (0<<1) +#define SDO_COMPOSITE_LEVEL_SEL_75IRE (1<<1) +#define SDO_COMPOSITE_VTOS_RATIO_10_4 (0<<0) +#define SDO_COMPOSITE_VTOS_RATIO_7_3 (1<<0) + +#define SDO_COMPONENT_SYNC_ABSENT (0) +#define SDO_COMPONENT_SYNC_YG (1) +#define SDO_COMPONENT_SYNC_ALL (3) + +#define SDO_CVBS_NO_WSS (0<<14) +#define SDO_CVBS_WSS_INS (1<<14) +#define SDO_CVBS_NO_CLOSED_CAPTION (0<<12) +#define SDO_CVBS_21H_CLOSED_CAPTION (1<<12) +#define SDO_CVBS_21H_284H_CLOSED_CAPTION (2<<12) +#define SDO_CVBS_USE_OTHERS (3<<12) +#define SDO_SVIDEO_NO_WSS (0<<10) +#define SDO_SVIDEO_WSS_INS (1<<10) +#define SDO_SVIDEO_NO_CLOSED_CAPTION (0<<8) +#define SDO_SVIDEO_21H_CLOSED_CAPTION (1<<8) +#define SDO_SVIDEO_21H_284H_CLOSED_CAPTION (2<<8) +#define SDO_SVIDEO_USE_OTHERS (3<<8) +#define SDO_RGB_NO_CGMSA (0<<7) +#define SDO_RGB_CGMSA_INS (1<<7) +#define SDO_RGB_NO_WSS (0<<6) +#define SDO_RGB_WSS_INS (1<<6) +#define SDO_RGB_NO_CLOSED_CAPTION (0<<4) +#define SDO_RGB_21H_CLOSED_CAPTION (1<<4) +#define SDO_RGB_21H_284H_CLOSED_CAPTION (2<<4) +#define SDO_RGB_USE_OTHERS (3<<4) +#define SDO_YPBPR_NO_CGMSA (0<<3) +#define SDO_YPBPR_CGMSA_INS (1<<3) +#define SDO_YPBPR_NO_WSS (0<<2) +#define SDO_YPBPR_WSS_INS (1<<2) +#define SDO_YPBPR_NO_CLOSED_CAPTION (0) +#define SDO_YPBPR_21H_CLOSED_CAPTION (1) +#define SDO_YPBPR_21H_284H_CLOSED_CAPTION (2) +#define SDO_YPBPR_USE_OTHERS(3) + +#define SDO_SCALE_CONV_OFFSET(a) ((0x3ff&a)<<16) +#define SDO_SCALE_CONV_GAIN(a) (0xfff&a) + +#define SDO_DELAY_YTOC(a) ((0xf&a)<<16) +#define SDO_ACTIVE_START_OFFSET(a) ((0xff&a)<<8) +#define SDO_ACTIVE_END_OFFSET(a) (0xff&a) + +#define SDO_COLOR_SC_PHASE_ADJ (1) +#define SDO_COLOR_SC_PHASE_NOADJ (0) + +#define SDO_POWER_ON_DAC2 (1<<2) +#define SDO_POWER_DOWN_DAC2 (0<<2) +#define SDO_POWER_ON_DAC1 (1<<1) +#define SDO_POWER_DOWN_DAC1 (0<<1) +#define SDO_POWER_ON_DAC0 (1<<0) +#define SDO_POWER_DOWN_DAC0 (0<<0) + +#define SDO_FIELD_MOD_1001(a) (((0x3ff<<16)&a)>>16) +#define SDO_FIELD_ID_BOTTOM(a) ((1<<1)&a) +#define SDO_FIELD_ID_BOTTOM_PI_INCATION(a) (1) + +#define SDO_MV_AGC_103_ON (1) + +#define SDO_COMPONENT_BHS_ADJ_ON (0<<4) +#define SDO_COMPONENT_BHS_ADJ_OFF (1<<4) +#define SDO_COMPONENT_YPBPR_COMP_ON (0<<3) +#define SDO_COMPONENT_YPBPR_COMP_OFF (1<<3) +#define SDO_COMPONENT_RGB_COMP_ON (0<<2) +#define SDO_COMPONENT_RGB_COMP_OFF (1<<2) +#define SDO_COMPONENT_YC_COMP_ON (0<<1) +#define SDO_COMPONENT_YC_COMP_OFF (1<<1) +#define SDO_COMPONENT_CVBS_COMP_ON (0) +#define SDO_COMPONENT_CVBS_COMP_OFF (1) + +#define SDO_BRIGHTNESS_GAIN(a) ((0xff&a)<<16) +#define SDO_BRIGHTNESS_OFFSET(a) (0xff&a) + +#define SDO_HS_CB_GAIN0(a) ((0x1ff&a)<<16) +#define SDO_HS_CB_GAIN1(a) (0x1ff&a) + +#define SDO_HS_CR_GAIN0(a) ((0x1ff&a)<<16) +#define SDO_HS_CR_GAIN1(a) (0x1ff&a) + +#define SDO_HS_CR_OFFSET(a) ((0x3ff&a)<<16) +#define SDO_HS_CB_OFFSET(a) (0x3ff&a) + +#define SDO_MAX_RGB_CUBE(a) ((0xff&a)<<8) +#define SDO_MIN_RGB_CUBE(a) (0xff&a) + +#define SDO_Y_LOWER_MID_CVBS_CORN(a) ((0x3ff&a)<<16) +#define SDO_Y_BOTTOM_CVBS_CORN(a) (0x3ff&a) + +#define SDO_Y_TOP_CVBS_CORN(a) ((0x3ff&a)<<16) +#define SDO_Y_UPPER_MID_CVBS_CORN(a) (0x3ff&a) + +#define SDO_RADIUS_CVBS_CORN(a) (0x1ff&a) + +#define SDO_Y_TOP_YC_CYLINDER(a) ((0x3ff&a)<<16) +#define SDO_Y_BOTOM_YC_CYLINDER(a) (0x3ff&a) + +#define SDO_RADIUS_YC_CYLINDER(a) (0x1ff&a) + +#define SDO_COMPONENT_525_BP(a) ((0x3ff&a)<<16) +#define SDO_COMPONENT_525_FP(a) (0x3ff&a) + +#define SDO_COMPONENT_625_BP(a) ((0x3ff&a)<<16) +#define SDO_COMPONENT_625_FP(a) (0x3ff&a) + +#define SDO_RGB_SYNC_COMPOSITE (0<<8) +#define SDO_RGB_SYNC_SEPERATE (1<<8) +#define SDO_RGB_VSYNC_LOW_ACT (0<<4) +#define SDO_RGB_VSYNC_HIGH_ACT (1<<4) +#define SDO_RGB_HSYNC_LOW_ACT 0 +#define SDO_RGB_HSYNC_HIGH_ACT 1 + +#define SDO_OSF_COEF_ODD(a) ((0xfff&a)<<16) +#define SDO_OSF_COEF_EVEN(a) (0xfff&a) + +#define SDO_XTALK_COEF02(a) ((0xff&a)<<16) +#define SDO_XTALK_COEF01(a) (0xff&a) + +#define SDO_REF_BB_LEVEL_NTSC (0x11a<<8) +#define SDO_REF_BB_LEVEL_PAL (0xfb<<8) +#define SDO_SEL_BB_CJAN_CVBS0_BB1_BB2 (0<<4) +#define SDO_SEL_BB_CJAN_BB0_CVBS1_BB2 (1<<4) +#define SDO_SEL_BB_CJAN_BB0_BB1_CVBS2 (2<<4) +#define SDO_BB_MODE_ENABLE (1) +#define SDO_BB_MODE_DISABLE (0) + +#define SDO_VSYNC_IRQ_PEND (1) +#define SDO_VSYNC_NO_IRQ (0) + +#define SDO_VSYNC_IRQ_ENABLE (0) +#define SDO_VSYNC_IRQ_DISABLE (1) + +#define SDO_DISPLAY_CC_CAPTION(a) ((0xff&a)<<16) +#define SDO_NON_DISPLAY_CC_CAPTION(a) (0xff&a) + +#define SDO_CRC_WSS525(a) ((0x3f&a)<<14) +#define SDO_WORD2_WSS525_COPY_PERMIT (0<<6) +#define SDO_WORD2_WSS525_ONECOPY_PERMIT (1<<6) +#define SDO_WORD2_WSS525_NOCOPY_PERMIT (3<<6) +#define SDO_WORD2_WSS525_MV_PSP_OFF (0<<8) +#define SDO_WORD2_WSS525_MV_PSP_ON_2LINE_BURST (1<<8) +#define SDO_WORD2_WSS525_MV_PSP_ON_BURST_OFF (2<<8) +#define SDO_WORD2_WSS525_MV_PSP_ON_4LINE_BURST (3<<8) +#define SDO_WORD2_WSS525_ANALOG_OFF (0<<10) +#define SDO_WORD2_WSS525_ANALOG_ON (1<<10) +#define SDO_WORD1_WSS525_COPY_INFO (0<<2) +#define SDO_WORD1_WSS525_DEFAULT (0xf<<2) +#define SDO_WORD0_WSS525_4_3_NORMAL (0) +#define SDO_WORD0_WSS525_16_9_ANAMORPIC (1) +#define SDO_WORD0_WSS525_4_3_LETTERBOX (2) + +#define SDO_WSS625_SURROUND_SOUND_DISABLE (0<<11) +#define SDO_WSS625_SURROUND_SOUND_ENABLE (1<<11) +#define SDO_WSS625_NO_COPYRIGHT (0<<12) +#define SDO_WSS625_COPYRIGHT (1<<12) +#define SDO_WSS625_COPY_NOT_RESTRICTED (0<<13) +#define SDO_WSS625_COPY_RESTRICTED (1<<13) +#define SDO_WSS625_TELETEXT_NO_SUBTITLES (0<<8) +#define SDO_WSS625_TELETEXT_SUBTITLES (1<<8) +#define SDO_WSS625_NO_OPEN_SUBTITLES (0<<9) +#define SDO_WSS625_INACT_OPEN_SUBTITLES (1<<9) +#define SDO_WSS625_OUTACT_OPEN_SUBTITLES (2<<9) +#define SDO_WSS625_CAMERA (0<<4) +#define SDO_WSS625_FILM (1<<4) +#define SDO_WSS625_NORMAL_PAL (0<<5) +#define SDO_WSS625_MOTION_ADAPTIVE_COLORPLUS (1<<5) +#define SDO_WSS625_HELPER_NO_SIG (0<<6) +#define SDO_WSS625_HELPER_SIG (1<<6) +#define SDO_WSS625_4_3_FULL_576 (0x8) +#define SDO_WSS625_14_9_LETTERBOX_CENTER_504 (0x1) +#define SDO_WSS625_14_9_LETTERBOX_TOP_504 (0x2) +#define SDO_WSS625_16_9_LETTERBOX_CENTER_430 (0xb) +#define SDO_WSS625_16_9_LETTERBOX_TOP_430 (0x4) +#define SDO_WSS625_16_9_LETTERBOX_CENTER (0xd) +#define SDO_WSS625_14_9_FULL_CENTER_576 (0xe) +#define SDO_WSS625_16_9_ANAMORPIC_576 (0x7) + +#define SDO_CRC_CGMS525(a) ((0x3f&a)<<14) +#define SDO_WORD2_CGMS525_COPY_PERMIT (0<<6) +#define SDO_WORD2_CGMS525_ONECOPY_PERMIT (1<<6) +#define SDO_WORD2_CGMS525_NOCOPY_PERMIT (3<<6) +#define SDO_WORD2_CGMS525_MV_PSP_OFF (0<<8) +#define SDO_WORD2_CGMS525_MV_PSP_ON_2LINE_BURST (1<<8) +#define SDO_WORD2_CGMS525_MV_PSP_ON_BURST_OFF (2<<8) +#define SDO_WORD2_CGMS525_MV_PSP_ON_4LINE_BURST (3<<8) +#define SDO_WORD2_CGMS525_ANALOG_OFF (0<<10) +#define SDO_WORD2_CGMS525_ANALOG_ON (1<<10) +#define SDO_WORD1_CGMS525_COPY_INFO (0<<2) +#define SDO_WORD1_CGMS525_DEFAULT (0xf<<2) +#define SDO_WORD0_CGMS525_4_3_NORMAL (0) +#define SDO_WORD0_CGMS525_16_9_ANAMORPIC (1) +#define SDO_WORD0_CGMS525_4_3_LETTERBOX (2) + +#define SDO_CGMS625_SURROUND_SOUND_DISABLE (0<<11) +#define SDO_CGMS625_SURROUND_SOUND_ENABLE (1<<11) +#define SDO_CGMS625_NO_COPYRIGHT (0<<12) +#define SDO_CGMS625_COPYRIGHT (1<<12) +#define SDO_CGMS625_COPY_NOT_RESTRICTED (0<<13) +#define SDO_CGMS625_COPY_RESTRICTED (1<<13) +#define SDO_CGMS625_TELETEXT_NO_SUBTITLES (0<<8) +#define SDO_CGMS625_TELETEXT_SUBTITLES (1<<8) +#define SDO_CGMS625_NO_OPEN_SUBTITLES (0<<9) +#define SDO_CGMS625_INACT_OPEN_SUBTITLES (1<<9) +#define SDO_CGMS625_OUTACT_OPEN_SUBTITLES (2<<9) +#define SDO_CGMS625_CAMERA (0<<4) +#define SDO_CGMS625_FILM (1<<4) +#define SDO_CGMS625_NORMAL_PAL (0<<5) +#define SDO_CGMS625_MOTION_ADAPTIVE_COLORPLUS (1<<5) +#define SDO_CGMS625_HELPER_NO_SIG (0<<6) +#define SDO_CGMS625_HELPER_SIG (1<<6) +#define SDO_CGMS625_4_3_FULL_576 (0x8) +#define SDO_CGMS625_14_9_LETTERBOX_CENTER_504 (0x1) +#define SDO_CGMS625_14_9_LETTERBOX_TOP_504 (0x2) +#define SDO_CGMS625_16_9_LETTERBOX_CENTER_430 (0xb) +#define SDO_CGMS625_16_9_LETTERBOX_TOP_430 (0x4) +#define SDO_CGMS625_16_9_LETTERBOX_CENTER (0xd) +#define SDO_CGMS625_14_9_FULL_CENTER_576 (0xe) +#define SDO_CGMS625_16_9_ANAMORPIC_576 (0x7) + +#endif diff --git a/drivers/media/video/samsung/tv20/s5pc100/regs/regs-vmx.h b/drivers/media/video/samsung/tv20/s5pc100/regs/regs-vmx.h new file mode 100644 index 0000000..bd104342 --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5pc100/regs/regs-vmx.h @@ -0,0 +1,209 @@ +/* linux/drivers/media/video/samsung/tv20/s5pc100/regs/regs-vmx.h + * + * Mixer register header file for Samsung TVOut driver + * + * Copyright (c) 2009 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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 <mach/map.h> + +#define S5P_MIXER_BASE(x) (x) + +#define S5P_MXR_STATUS S5P_MIXER_BASE(0x0000) +#define S5P_MXR_CFG S5P_MIXER_BASE(0x0004) +#define S5P_MXR_INT_EN S5P_MIXER_BASE(0x0008) +#define S5P_MXR_INT_STATUS S5P_MIXER_BASE(0x000C) +#define S5P_MXR_LAYER_CFG S5P_MIXER_BASE(0x0010) +#define S5P_MXR_VIDEO_CFG S5P_MIXER_BASE(0x0014) +#define S5P_MXR_GRAPHIC0_CFG S5P_MIXER_BASE(0x0020) +#define S5P_MXR_GRAPHIC0_BASE S5P_MIXER_BASE(0x0024) +#define S5P_MXR_GRAPHIC0_SPAN S5P_MIXER_BASE(0x0028) +#define S5P_MXR_GRAPHIC0_SXY S5P_MIXER_BASE(0x002C) +#define S5P_MXR_GRAPHIC0_WH S5P_MIXER_BASE(0x0030) +#define S5P_MXR_GRAPHIC0_DXY S5P_MIXER_BASE(0x0034) +#define S5P_MXR_GRAPHIC0_BLANK S5P_MIXER_BASE(0x0038) +#define S5P_MXR_GRAPHIC1_CFG S5P_MIXER_BASE(0x0040) +#define S5P_MXR_GRAPHIC1_BASE S5P_MIXER_BASE(0x0044) +#define S5P_MXR_GRAPHIC1_SPAN S5P_MIXER_BASE(0x0048) +#define S5P_MXR_GRAPHIC1_SXY S5P_MIXER_BASE(0x004C) +#define S5P_MXR_GRAPHIC1_WH S5P_MIXER_BASE(0x0050) +#define S5P_MXR_GRAPHIC1_DXY S5P_MIXER_BASE(0x0054) +#define S5P_MXR_GRAPHIC1_BLANK S5P_MIXER_BASE(0x0058) +#define S5P_MXR_BG_CFG S5P_MIXER_BASE(0x0060) +#define S5P_MXR_BG_COLOR0 S5P_MIXER_BASE(0x0064) +#define S5P_MXR_BG_COLOR1 S5P_MIXER_BASE(0x0068) +#define S5P_MXR_BG_COLOR2 S5P_MIXER_BASE(0x006C) +#define S5P_MXR_CM_COEFF_Y S5P_MIXER_BASE(0x0080) +#define S5P_MXR_CM_COEFF_CB S5P_MIXER_BASE(0x0084) +#define S5P_MXR_CM_COEFF_CR S5P_MIXER_BASE(0x0088) +#define S5P_MXR_VER S5P_MIXER_BASE(0x0100) + + +#define S5P_MXR_STATUS_S S5P_MIXER_BASE(0x2000) +#define S5P_MXR_CFG_S S5P_MIXER_BASE(0x2004) +#define S5P_MXR_LAYER_CFG_S S5P_MIXER_BASE(0x2010) +#define S5P_MXR_VIDEO_CFG_S S5P_MIXER_BASE(0x2014) +#define S5P_MXR_GRAPHIC0_CFG_S S5P_MIXER_BASE(0x2020) +#define S5P_MXR_GRAPHIC0_BASE_S S5P_MIXER_BASE(0x2024) +#define S5P_MXR_GRAPHIC0_SPAN_S S5P_MIXER_BASE(0x2028) +#define S5P_MXR_GRAPHIC0_SXY_S S5P_MIXER_BASE(0x202C) +#define S5P_MXR_GRAPHIC0_WH_S S5P_MIXER_BASE(0x2030) +#define S5P_MXR_GRAPHIC0_DXY_S S5P_MIXER_BASE(0x2034) +#define S5P_MXR_GRAPHIC0_BLANK_PIXEL_S S5P_MIXER_BASE(0x2038) +#define S5P_MXR_GRAPHIC1_CFG_S S5P_MIXER_BASE(0x2040) +#define S5P_MXR_GRAPHIC1_BASE_S S5P_MIXER_BASE(0x2044) +#define S5P_MXR_GRAPHIC1_SPAN_S S5P_MIXER_BASE(0x2048) +#define S5P_MXR_GRAPHIC1_SXY_S S5P_MIXER_BASE(0x204C) +#define S5P_MXR_GRAPHIC1_WH_S S5P_MIXER_BASE(0x2050) +#define S5P_MXR_GRAPHIC1_DXY_S S5P_MIXER_BASE(0x2054) +#define S5P_MXR_GRAPHIC1_BLANK_PIXEL_S S5P_MIXER_BASE(0x2058) +#define S5P_MXR_BG_COLOR0_S S5P_MIXER_BASE(0x2064) +#define S5P_MXR_BG_COLOR1_S S5P_MIXER_BASE(0x2068) +#define S5P_MXR_BG_COLOR2_S S5P_MIXER_BASE(0x206C) + +#define S5P_MXR_STATUS_RUN (1<<0) +#define S5P_MXR_STATUS_STOP (0<<0) +#define S5P_MXR_STATUS_SYNC_DISABLE (0<<2) +#define S5P_MXR_STATUS_SYNC_ENABLE (1<<2) +#define S5P_MXR_STATUS_LITTLE (0<<3) +#define S5P_MXR_STATUS_BIT (1<<3) +#define S5P_MXR_STATUS_8_BURST (0<<7) +#define S5P_MXR_STATUS_16_BURST (1<<7) + +#define S5P_MXR_CFG_SD (0<<0) +#define S5P_MXR_CFG_HD (1<<0) +#define S5P_MXR_CFG_NTSC (0<<1) +#define S5P_MXR_CFG_PAL (1<<1) +#define S5P_MXR_CFG_INTERLACE (0<<2) +#define S5P_MXR_CFG_PROGRASSIVE (1<<2) +#define S5P_MXR_CFG_VIDEO_DISABLE (0<<3) +#define S5P_MXR_CFG_VIDEO_ENABLE (1<<4) +#define S5P_MXR_CFG_GRAPHIC0_DISABLE (0<<4) +#define S5P_MXR_CFG_GRAPHIC0_ENABLE (1<<4) +#define S5P_MXR_CFG_GRAPHIC1_DISABLE (0<<5) +#define S5P_MXR_CFG_GRAPHIC1_ENABLE (1<<5) +#define S5P_MXR_CFG_HD_720P (0<<6) +#define S5P_MXR_CFG_HD_1080I (1<<6) + +#define S5P_MXR_INT_EN_GRP0_DISABLE (0<<8) +#define S5P_MXR_INT_EN_GRP0_ENABLE (1<<8) +#define S5P_MXR_INT_EN_GRP1_DISABLE (0<<9) +#define S5P_MXR_INT_EN_GRP1_ENABLE (1<<9) +#define S5P_MXR_INT_EN_VP_DISABLE (0<<10) +#define S5P_MXR_INT_EN_VP_ENABLE (1<<10) + +#define S5P_MXR_STATUS_EN_GRP0_N_FIRED (0<<8) +#define S5P_MXR_STATUS_EN_GRP0_FIRED (1<<8) +#define S5P_MXR_STATUS_EN_GRP1_N_FIRED (0<<9) +#define S5P_MXR_STATUS_EN_GRP1_FIRED (1<<9) +#define S5P_MXR_STATUS_EN_VP_N_FIRED (0<<10) +#define S5P_MXR_STATUS_EN_VP_FIRED (1<<10) + +#define S5P_MXR_LAYER_CFG_VP_HIDE (0<<0) +#define S5P_MXR_LAYER_CFG_GRP0_HIDE (0<<4) +#define S5P_MXR_LAYER_CFG_GRP1_HIDE (0<<8) + +#define S5P_MXR_VIDEO_CFG_BLEND_EN (1<<16) + + +#define S5P_MXR_BURST16_MODE (1<<7) +#define S5P_MXR_BURST8_MODE (0<<7) +#define S5P_MXR_BIG_ENDIAN_SOURCE_FORMAT (1<<3) +#define S5P_MXR_LITTLE_ENDIAN_SOURCE_FORMAT (0<<3) +#define S5P_MXR_MIXER_RESERVED (1<<2) +#define S5P_MXR_CMU_STOP_CLOCK (1<<1) +#define S5P_MXR_CMU_CANNOT_STOP_CLOCK (0<<1) +#define S5P_MXR_MIXER_START (1<<0) +#define S5P_MXR_MIXER_STOP (0<<0) + +#define S5P_MXR_HD_1080I_MODE (1<<6) +#define S5P_MXR_HD_720P_MODE (0<<6) +#define S5P_MXR_GRAPHIC1_LAYER_SHOW (1<<5) +#define S5P_MXR_GRAPHIC1_LAYER_HIDE (0<<5) +#define S5P_MXR_GRAPHIC0_LAYER_SHOW (1<<4) +#define S5P_MXR_GRAPHIC0_LAYER_HIDE (0<<4) +#define S5P_MXR_VIDEO_LAYER_SHOW (1<<3) +#define S5P_MXR_VIDEO_LAYER_HIDE (0<<3) +#define S5P_MXR_PROGRESSVE_MODE (1<<2) +#define S5P_MXR_INTERLACE_MODE (0<<2) +#define S5P_MXR_PAL (1<<1) +#define S5P_MXR_NTSC (0<<1) +#define S5P_MXR_HD (1<<0) +#define S5P_MXR_SD (0<<0) + +#define S5P_MXR_VP_INT_ENABLE (1<<10) +#define S5P_MXR_VP_INT_DISABLE (0<<10) +#define S5P_MXR_GRP1_INT_ENABLE (1<<9) +#define S5P_MXR_GRP1_INT_DISABLE (0<<9) +#define S5P_MXR_GRP0_INT_ENABLE (1<<8) +#define S5P_MXR_GRP0_INT_DISABLE (0<<8) + +#define S5P_MXR_VP_INT_FIRED (1<<10) +#define S5P_MXR_GRP1_INT_FIRED (1<<9) +#define S5P_MXR_GRP0_INT_FIRED (1<<8) +#define S5P_MXR_INT_FIRED (1<<0) + +#define S5P_MXR_ALPHA (0xff) + +#define S5P_MXR_GRP1_LAYER_PRIORITY(a) ((0xf&a)<<8) +#define S5P_MXR_GRP0_LAYER_PRIORITY(a) ((0xf&a)<<4) +#define S5P_MXR_VP_LAYER_PRIORITY(a) ((0xf&a)<<0) +#define S5P_MXR_GRP1_LAYER_PRIORITY_CLEAR(a) ((~(0xf<<8))&a) +#define S5P_MXR_GRP0_LAYER_PRIORITY_CLEAR(a) ((~(0xf<<4))&a) +#define S5P_MXR_VP_LAYER_PRIORITY_CLEAR(a) ((~(0xf<<0))&a) +#define S5P_MXR_GRP1_LAYER_PRIORITY_INFO(a) ((0xf<<8)&a) +#define S5P_MXR_GRP0_LAYER_PRIORITY_INFO(a) ((0xf<<4)&a) +#define S5P_MXR_VP_LAYER_PRIORITY_INFO(a) ((0xf<<0)&a) + +#define S5P_MXR_VP_BLEND_ENABLE (1<<16) +#define S5P_MXR_VP_BLEND_DISABLE (0<<16) +#define S5P_MXR_VP_ALPHA_VALUE(a) ((0xff&a)<<0) +#define S5P_MXR_VP_ALPHA_VALUE_CLEAR(a) ((~(0xff<<0))&a) + +#define S5P_MXR_BLANK_CHANGE_NEW_PIXEL (1<<21) +#define S5P_MXR_BLANK_NOT_CHANGE_NEW_PIXEL (0<<21) +#define S5P_MXR_PRE_MUL_MODE (1<<20) +#define S5P_MXR_NORMAL_MODE (0<<20) +#define S5P_MXR_WIN_BLEND_ENABLE (1<<17) +#define S5P_MXR_WIN_BLEND_DISABLE (0<<17) +#define S5P_MXR_PIXEL_BLEND_ENABLE (1<<16) +#define S5P_MXR_PIXEL_BLEND_DISABLE (0<<16) +#define S5P_MXR_EG_COLOR_FORMAT(a) ((0xf&a)<<8) +#define S5P_MXR_EG_COLOR_FORMAT_CLEAR(a) ((~(0xf<<8))&a) +#define S5P_MXR_GRP_ALPHA_VALUE(a) ((0xff&a)<<0) +#define S5P_MXR_GRP_ALPHA_VALUE_CLEAR(a) ((~(0xff<<0))&a) + +#define S5P_MXR_GPR_BASE(a) (0xffffffff&a) +#define S5P_MXR_GRP_ADDR_ILLEGAL(a) (0x3&a) + +#define S5P_MXR_GRP_SPAN(a) (0x7fff&a) + +#define S5P_MXR_GRP_WIDTH(a) ((0x7ff&a)<<16) +#define S5P_MXR_GRP_HEIGHT(a) ((0x7ff&a)<<0) + +#define S5P_MXR_GRP_STARTX(a) ((0x7ff&a)<<16) +#define S5P_MXR_GRP_STARTY(a) ((0x7ff&a)<<0) + +#define S5P_MXR_GRP_DESTX(a) ((0x7ff&a)<<16) +#define S5P_MXR_GRP_DESTY(a) ((0x7ff&a)<<0) + +#define S5P_MXR_GPR_BLANK_COLOR(a) (0xffffffff&a) + +#define S5P_MXR_BG_CR_DIHER_EN (1<<19) +#define S5P_MXR_BG_CB_DIHER_EN (1<<18) +#define S5P_MXR_BG_Y_DIHER_EN (1<<17) + +#define S5P_MXR_BG_COLOR_Y(a) ((0xff&a)<<16) +#define S5P_MXR_BG_COLOR_CB(a) ((0xff&a)<<8) +#define S5P_MXR_BG_COLOR_CR(a) ((0xff&a)<<0) + +#define S5P_MXR_BG_COLOR_WIDE (1<<30) +#define S5P_MXR_BG_COLOR_NARROW (0<<30) +#define S5P_MXR_BG_COEFF_0(a) ((0x3f&a)<<20) +#define S5P_MXR_BG_COEFF_1(a) ((0x3f&a)<<10) +#define S5P_MXR_BG_COEFF_2(a) ((0x3f&a)<<0) + diff --git a/drivers/media/video/samsung/tv20/s5pc100/regs/regs-vprocessor.h b/drivers/media/video/samsung/tv20/s5pc100/regs/regs-vprocessor.h new file mode 100644 index 0000000..34c1d97 --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5pc100/regs/regs-vprocessor.h @@ -0,0 +1,366 @@ +/* linux/drivers/media/video/samsung/tv20/s5pc100/regs/regs-vprocessor.h + * + * Video Processor register header file for Samsung TVOut driver + * + * Copyright (c) 2009 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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. +*/ + +#ifndef __ASM_ARCH_REGS_VPROCESSOR_H + +#include <mach/map.h> + +#define S5P_VPROCESSOR_BASE(x) (x) + +#define S5P_VP_ENABLE S5P_VPROCESSOR_BASE(0x0000) +#define S5P_VP_SRESET S5P_VPROCESSOR_BASE(0x0004) +#define S5P_VP_SHADOW_UPDATE S5P_VPROCESSOR_BASE(0x0008) +#define S5P_VP_FIELD_ID S5P_VPROCESSOR_BASE(0x000C) +#define S5P_VP_MODE S5P_VPROCESSOR_BASE(0x0010) +#define S5P_VP_IMG_SIZE_Y S5P_VPROCESSOR_BASE(0x0014) +#define S5P_VP_IMG_SIZE_C S5P_VPROCESSOR_BASE(0x0018) +#define S5P_VP_PER_RATE_CTRL S5P_VPROCESSOR_BASE(0x001C) +#define S5P_VP_TOP_Y_PTR S5P_VPROCESSOR_BASE(0x0028) +#define S5P_VP_BOT_Y_PTR S5P_VPROCESSOR_BASE(0x002C) +#define S5P_VP_TOP_C_PTR S5P_VPROCESSOR_BASE(0x0030) +#define S5P_VP_BOT_C_PTR S5P_VPROCESSOR_BASE(0x0034) +#define S5P_VP_ENDIAN_MODE S5P_VPROCESSOR_BASE(0x03CC) +#define S5P_VP_SRC_H_POSITION S5P_VPROCESSOR_BASE(0x0044) +#define S5P_VP_SRC_V_POSITION S5P_VPROCESSOR_BASE(0x0048) +#define S5P_VP_SRC_WIDTH S5P_VPROCESSOR_BASE(0x004C) +#define S5P_VP_SRC_HEIGHT S5P_VPROCESSOR_BASE(0x0050) +#define S5P_VP_DST_H_POSITION S5P_VPROCESSOR_BASE(0x0054) +#define S5P_VP_DST_V_POSITION S5P_VPROCESSOR_BASE(0x0058) +#define S5P_VP_DST_WIDTH S5P_VPROCESSOR_BASE(0x005C) +#define S5P_VP_DST_HEIGHT S5P_VPROCESSOR_BASE(0x0060) +#define S5P_VP_H_RATIO S5P_VPROCESSOR_BASE(0x0064) +#define S5P_VP_V_RATIO S5P_VPROCESSOR_BASE(0x0068) +#define S5P_VP_POLY8_Y0_LL S5P_VPROCESSOR_BASE(0x006C) +#define S5P_VP_POLY8_Y0_LH S5P_VPROCESSOR_BASE(0x0070) +#define S5P_VP_POLY8_Y0_HL S5P_VPROCESSOR_BASE(0x0074) +#define S5P_VP_POLY8_Y0_HH S5P_VPROCESSOR_BASE(0x0078) +#define S5P_VP_POLY8_Y1_LL S5P_VPROCESSOR_BASE(0x007C) +#define S5P_VP_POLY8_Y1_LH S5P_VPROCESSOR_BASE(0x0080) +#define S5P_VP_POLY8_Y1_HL S5P_VPROCESSOR_BASE(0x0084) +#define S5P_VP_POLY8_Y1_HH S5P_VPROCESSOR_BASE(0x0088) +#define S5P_VP_POLY8_Y2_LL S5P_VPROCESSOR_BASE(0x008C) +#define S5P_VP_POLY8_Y2_LH S5P_VPROCESSOR_BASE(0x0090) +#define S5P_VP_POLY8_Y2_HL S5P_VPROCESSOR_BASE(0x0094) +#define S5P_VP_POLY8_Y2_HH S5P_VPROCESSOR_BASE(0x0098) +#define S5P_VP_POLY8_Y3_LL S5P_VPROCESSOR_BASE(0x009C) +#define S5P_VP_POLY8_Y3_LH S5P_VPROCESSOR_BASE(0x00A0) +#define S5P_VP_POLY8_Y3_HL S5P_VPROCESSOR_BASE(0x00A4) +#define S5P_VP_POLY8_Y3_HH S5P_VPROCESSOR_BASE(0x00A8) +#define S5P_VP_POLY4_Y0_LL S5P_VPROCESSOR_BASE(0x00EC) +#define S5P_VP_POLY4_Y0_LH S5P_VPROCESSOR_BASE(0x00F0) +#define S5P_VP_POLY4_Y0_HL S5P_VPROCESSOR_BASE(0x00F4) +#define S5P_VP_POLY4_Y0_HH S5P_VPROCESSOR_BASE(0x00F8) +#define S5P_VP_POLY4_Y1_LL S5P_VPROCESSOR_BASE(0x00FC) +#define S5P_VP_POLY4_Y1_LH S5P_VPROCESSOR_BASE(0x0100) +#define S5P_VP_POLY4_Y1_HL S5P_VPROCESSOR_BASE(0x0104) +#define S5P_VP_POLY4_Y1_HH S5P_VPROCESSOR_BASE(0x0108) +#define S5P_VP_POLY4_Y2_LL S5P_VPROCESSOR_BASE(0x010C) +#define S5P_VP_POLY4_Y2_LH S5P_VPROCESSOR_BASE(0x0110) +#define S5P_VP_POLY4_Y2_HL S5P_VPROCESSOR_BASE(0x0114) +#define S5P_VP_POLY4_Y2_HH S5P_VPROCESSOR_BASE(0x0118) +#define S5P_VP_POLY4_Y3_LL S5P_VPROCESSOR_BASE(0x011C) +#define S5P_VP_POLY4_Y3_LH S5P_VPROCESSOR_BASE(0x0120) +#define S5P_VP_POLY4_Y3_HL S5P_VPROCESSOR_BASE(0x0124) +#define S5P_VP_POLY4_Y3_HH S5P_VPROCESSOR_BASE(0x0128) +#define S5P_VP_POLY4_C0_LL S5P_VPROCESSOR_BASE(0x012C) +#define S5P_VP_POLY4_C0_LH S5P_VPROCESSOR_BASE(0x0130) +#define S5P_VP_POLY4_C0_HL S5P_VPROCESSOR_BASE(0x0134) +#define S5P_VP_POLY4_C0_HH S5P_VPROCESSOR_BASE(0x0138) +#define S5P_VP_POLY4_C1_LL S5P_VPROCESSOR_BASE(0x013C) +#define S5P_VP_POLY4_C1_LH S5P_VPROCESSOR_BASE(0x0140) +#define S5P_VP_POLY4_C1_HL S5P_VPROCESSOR_BASE(0x0144) +#define S5P_VP_POLY4_C1_HH S5P_VPROCESSOR_BASE(0x0148) +#define S5P_PP_CSC_Y2Y_COEF S5P_VPROCESSOR_BASE(0x01D4) +#define S5P_PP_CSC_CB2Y_COEF S5P_VPROCESSOR_BASE(0x01D8) +#define S5P_PP_CSC_CR2Y_COEF S5P_VPROCESSOR_BASE(0x01DC) +#define S5P_PP_CSC_Y2CB_COEF S5P_VPROCESSOR_BASE(0x01E0) +#define S5P_PP_CSC_CB2CB_COEF S5P_VPROCESSOR_BASE(0x01E4) +#define S5P_PP_CSC_CR2CB_COEF S5P_VPROCESSOR_BASE(0x01E8) +#define S5P_PP_CSC_Y2CR_COEF S5P_VPROCESSOR_BASE(0x01EC) +#define S5P_PP_CSC_CB2CR_COEF S5P_VPROCESSOR_BASE(0x01F0) +#define S5P_PP_CSC_CR2CR_COEF S5P_VPROCESSOR_BASE(0x01F4) +#define S5P_PP_BYPASS S5P_VPROCESSOR_BASE(0x0200) +#define S5P_PP_SATURATION S5P_VPROCESSOR_BASE(0x020C) +#define S5P_PP_SHARPNESS S5P_VPROCESSOR_BASE(0x0210) +#define S5P_PP_LINE_EQ0 S5P_VPROCESSOR_BASE(0x0218) +#define S5P_PP_LINE_EQ1 S5P_VPROCESSOR_BASE(0x021C) +#define S5P_PP_LINE_EQ2 S5P_VPROCESSOR_BASE(0x0220) +#define S5P_PP_LINE_EQ3 S5P_VPROCESSOR_BASE(0x0224) +#define S5P_PP_LINE_EQ4 S5P_VPROCESSOR_BASE(0x0228) +#define S5P_PP_LINE_EQ5 S5P_VPROCESSOR_BASE(0x022C) +#define S5P_PP_LINE_EQ6 S5P_VPROCESSOR_BASE(0x0230) +#define S5P_PP_LINE_EQ7 S5P_VPROCESSOR_BASE(0x0234) +#define S5P_PP_BRIGHT_OFFSET S5P_VPROCESSOR_BASE(0x0238) +#define S5P_PP_CSC_EN S5P_VPROCESSOR_BASE(0x023C) +#define S5P_VP_VERSION_INFO S5P_VPROCESSOR_BASE(0x03FC) + + +#define S5P_VP_FIELD_ID_S S5P_VPROCESSOR_BASE(0x016C) +#define S5P_VP_MODE_S S5P_VPROCESSOR_BASE(0x0170) +#define S5P_VP_IMG_SIZE_Y_S S5P_VPROCESSOR_BASE(0x0174) +#define S5P_VP_IMG_SIZE_C_S S5P_VPROCESSOR_BASE(0x0178) +#define S5P_VP_TOP_Y_PTR_S S5P_VPROCESSOR_BASE(0x0190) +#define S5P_VP_BOT_Y_PTR_S S5P_VPROCESSOR_BASE(0x0194) +#define S5P_VP_TOP_C_PTR_S S5P_VPROCESSOR_BASE(0x0198) +#define S5P_VP_BOT_C_PTR_S S5P_VPROCESSOR_BASE(0x019C) +#define S5P_VP_ENDIAN_MODE_S S5P_VPROCESSOR_BASE(0x03EC) +#define S5P_VP_SRC_H_POSITION_S S5P_VPROCESSOR_BASE(0x01AC) +#define S5P_VP_SRC_V_POSITION_S S5P_VPROCESSOR_BASE(0x01B0) +#define S5P_VP_SRC_WIDTH_S S5P_VPROCESSOR_BASE(0x01B4) +#define S5P_VP_SRC_HEIGHT_S S5P_VPROCESSOR_BASE(0x01B8) +#define S5P_VP_DST_H_POSITION_S S5P_VPROCESSOR_BASE(0x01BC) +#define S5P_VP_DST_V_POSITION_S S5P_VPROCESSOR_BASE(0x01C0) +#define S5P_VP_DST_WIDTH_S S5P_VPROCESSOR_BASE(0x01C4) +#define S5P_VP_DST_HEIGHT_S S5P_VPROCESSOR_BASE(0x01C8) +#define S5P_VP_H_RATIO_S S5P_VPROCESSOR_BASE(0x01CC) +#define S5P_VP_V_RATIO_S S5P_VPROCESSOR_BASE(0x01D0) +#define S5P_PP_BYPASS_S S5P_VPROCESSOR_BASE(0x0258) +#define S5P_PP_SATURATION_S S5P_VPROCESSOR_BASE(0x025C) +#define S5P_PP_SHARPNESS_S S5P_VPROCESSOR_BASE(0x0260) +#define S5P_PP_LINE_EQ0_S S5P_VPROCESSOR_BASE(0x0268) +#define S5P_PP_LINE_EQ1_S S5P_VPROCESSOR_BASE(0x026C) +#define S5P_PP_LINE_EQ2_S S5P_VPROCESSOR_BASE(0x0270) +#define S5P_PP_LINE_EQ3_S S5P_VPROCESSOR_BASE(0x0274) +#define S5P_PP_LINE_EQ4_S S5P_VPROCESSOR_BASE(0x0278) +#define S5P_PP_LINE_EQ5_S S5P_VPROCESSOR_BASE(0x027C) +#define S5P_PP_LINE_EQ6_S S5P_VPROCESSOR_BASE(0x0280) +#define S5P_PP_LINE_EQ7_S S5P_VPROCESSOR_BASE(0x0284) +#define S5P_PP_BRIGHT_OFFSET_S S5P_VPROCESSOR_BASE(0x0288) +#define S5P_PP_CSC_EN_S S5P_VPROCESSOR_BASE(0x028C) +#define S5P_PP_CSC_Y2Y_COEF_S S5P_VPROCESSOR_BASE(0x0290) +#define S5P_PP_CSC_CB2Y_COEF_S S5P_VPROCESSOR_BASE(0x0294) +#define S5P_PP_CSC_CR2Y_COEF_S S5P_VPROCESSOR_BASE(0x0298) +#define S5P_PP_CSC_Y2CB_COEF_S S5P_VPROCESSOR_BASE(0x029C) +#define S5P_PP_CSC_CB2CB_COEF_S S5P_VPROCESSOR_BASE(0x02A0) +#define S5P_PP_CSC_CR2CB_COEF_S S5P_VPROCESSOR_BASE(0x02A4) +#define S5P_PP_CSC_Y2CR_COEF_S S5P_VPROCESSOR_BASE(0x02A8) +#define S5P_PP_CSC_CB2CR_COEF_S S5P_VPROCESSOR_BASE(0x02AC) +#define S5P_PP_CSC_CR2CR_COEF_S S5P_VPROCESSOR_BASE(0x02B0) + + +#define S5P_VP_ENABLE_ON (1<<0) +#define S5P_VP_ENABLE_ON_S (1<<2) + +#define S5P_VP_SRESET_LAST_COMPLETE (0<<0) +#define S5P_VP_SRESET_PROCESSING (1<<0) + +#define S5P_VP_SHADOW_UPDATE_DISABLE (0<<0) +#define S5P_VP_SHADOW_UPDATE_ENABLE (1<<0) + +#define S5P_VP_FIELD_ID_TOP (0<<0) +#define S5P_VP_FIELD_ID_BOTTOM (1<<0) + +#define S5P_VP_MODE_2D_IPC_ENABLE (1<<1) +#define S5P_VP_MODE_2D_IPC_DISABLE (0<<1) +#define S5P_VP_MODE_FIELD_ID_MAN_TOGGLING (0<<2) +#define S5P_VP_MODE_FIELD_ID_AUTO_TOGGLING (1<<2) +#define S5P_VP_MODE_CROMA_EXPANSION_C_TOP_PTR (0<<3) +#define S5P_VP_MODE_CROMA_EXPANSION_C_TOPBOTTOM_PTR (1<<3) +#define S5P_VP_MODE_MEM_MODE_LINEAR (0<<4) +#define S5P_VP_MODE_MEM_MODE_2D_TILE (1<<4) +#define S5P_VP_MODE_LINE_SKIP_OFF (0<<5) +#define S5P_VP_MODE_LINE_SKIP_ON (1<<5) + +#define S5P_VP_ENDIAN_MODE_BIG (0<<0) +#define S5P_VP_ENDIAN_MODE_LITTLE (1<<0) + + +#define VP_ON_SW_RESET (1<<2) +#define VP_POWER_DOWN_RDY (1<<1) +#define VP_ON_ENABLE (1<<0) +#define VP_ON_DISABLE (0<<0) + +#define VP_SOFT_RESET (1<<0) + +#define VP_SHADOW_UPDATE_ENABLE (1<<0) +#define VP_SHADOW_UPDATE_DISABLE (0<<0) + +#define VP_FIELD_ID_BOTTOM (1<<0) +#define VP_FIELD_ID_TOP (0<<0) + +#define VP_LINE_SKIP_ON (1<<5) +#define VP_LINE_SKIP_OFF (0<<5) +#define VP_MEM_2D_MODE (1<<4) +#define VP_MEM_LINEAR_MODE (0<<4) +#define VP_CHROMA_USE_TOP_BOTTOM (1<<3) +#define VP_CHROMA_USE_TOP (0<<3) +#define VP_FIELD_ID_TOGGLE_VSYNC (1<<2) +#define VP_FIELD_ID_TOGGLE_USER (0<<2) +#define VP_2D_IPC_ON (1<<1) +#define VP_2D_IPC_OFF (0<<1) + +#define VP_IMG_HSIZE(a) ((0x3fff&a)<<16) +#define VP_IMG_VSIZE(a) ((0x3fff&a)<<0) +#define VP_IMG_SIZE_ILLEGAL(a) (0x7&a) + +#define VP_PEL_RATE_CTRL(a) ((0x3&a)<<0) + + +#define VP_PTR_ILLEGAL(a) (0x7&a) + +#define VP_LITTLE_ENDIAN_MODE (1<<0) +#define VP_BIG_ENDIAN_MODE (0<<0) + +#define VP_SRC_H_POSITION(a) ((0x7ff&a)<<4) +#define VP_SRC_X_FRACT_STEP(a) (0xf&a) + +#define VP_SRC_V_POSITION(a) (0x3ff&a) + +#define VP_SRC_WIDTH(a) (0x7ff&a) + +#define VP_SRC_HEIGHT(a) (0x3ff&a) + +#define VP_DST_H_POSITION(a) (0x7ff&a) + +#define VP_DST_V_POSITION(a) (0x3ff&a) + +#define VP_DST_WIDTH(a) (0x7ff&a) + +#define VP_DST_HEIGHT(a) (0x3ff&a) + +#define VP_H_RATIO(a) (0x7ffff&a) + +#define VP_V_RATIO(a) (0x7ffff&a) + +#define VP_POLY8_Y0_x0(a) ((0x7&a)<<24) +#define VP_POLY8_Y0_x1(a) ((0x7&a)<<16) +#define VP_POLY8_Y0_x2(a) ((0x7&a)<<8) +#define VP_POLY8_Y0_x3(a) ((0x7&a)<<0) + +#define VP_POLY8_Y1_x0(a) ((0x1f&a)<<24) +#define VP_POLY8_Y1_x1(a) ((0x1f&a)<<16) +#define VP_POLY8_Y1_x2(a) ((0x1f&a)<<8) +#define VP_POLY8_Y1_x3(a) ((0x1f&a)<<0) + +#define VP_POLY8_Y2_x0(a) ((0x7f&a)<<24) +#define VP_POLY8_Y2_x1(a) ((0x7f&a)<<16) +#define VP_POLY8_Y2_x2(a) ((0x7f&a)<<8) +#define VP_POLY8_Y2_x3(a) ((0x7f&a)<<0) + +#define VP_POLY8_Y3_x0(a) ((0x7f&a)<<24) +#define VP_POLY8_Y3_x1(a) ((0x7f&a)<<16) +#define VP_POLY8_Y3_x2(a) ((0x7f&a)<<8) +#define VP_POLY8_Y3_x3(a) ((0x7f&a)<<0) + +#define VP_POLY4_Y0_x0(a) ((0x3f&a)<<24) +#define VP_POLY4_Y0_x1(a) ((0x3f&a)<<16) +#define VP_POLY4_Y0_x2(a) ((0x3f&a)<<8) +#define VP_POLY4_Y0_x3(a) ((0x3f&a)<<0) + +#define VP_POLY4_Y1_x0(a) ((0x7f&a)<<24) +#define VP_POLY4_Y1_x1(a) ((0x7f&a)<<16) +#define VP_POLY4_Y1_x2(a) ((0x7f&a)<<8) +#define VP_POLY4_Y1_x3(a) ((0x7f&a)<<0) + +#define VP_POLY4_Y2_x0(a) ((0x7f&a)<<24) +#define VP_POLY4_Y2_x1(a) ((0x7f&a)<<16) +#define VP_POLY4_Y2_x2(a) ((0x7f&a)<<8) +#define VP_POLY4_Y2_x3(a) ((0x7f&a)<<0) + +#define VP_POLY4_Y3_x0(a) ((0x3f&a)<<24) +#define VP_POLY4_Y3_x1(a) ((0x3f&a)<<16) +#define VP_POLY4_Y3_x2(a) ((0x3f&a)<<8) +#define VP_POLY4_Y3_x3(a) ((0x3f&a)<<0) + +#define VP_POLY4_C0_PH0(a) ((0x7f&a)<<24) +#define VP_POLY4_C0_PH1(a) ((0x7f&a)<<16) +#define VP_POLY4_C0_PH2(a) ((0x7f&a)<<8) +#define VP_POLY4_C0_PH3(a) ((0x7f&a)<<0) + +#define VP_POLY4_C0_PH4(a) ((0x3f&a)<<24) +#define VP_POLY4_C0_PH5(a) ((0x3f&a)<<16) +#define VP_POLY4_C0_PH6(a) ((0x3f&a)<<8) +#define VP_POLY4_C0_PH7(a) ((0x3f&a)<<0) + +#define VP_POLY4_C0_PH8(a) ((0x3f&a)<<24) +#define VP_POLY4_C0_PH9(a) ((0x3f&a)<<16) +#define VP_POLY4_C0_PH10(a) ((0x3f&a)<<8) +#define VP_POLY4_C0_PH11(a) ((0x3f&a)<<0) + +#define VP_POLY4_C0_PH12(a) ((0x1f&a)<<24) +#define VP_POLY4_C0_PH13(a) ((0x1f&a)<<16) +#define VP_POLY4_C0_PH14(a) ((0x1f&a)<<8) +#define VP_POLY4_C0_PH15(a) ((0x1f&a)<<0) + +#define VP_POLY4_C1_PH0(a) ((0xff&a)<<24) +#define VP_POLY4_C1_PH1(a) ((0xff&a)<<16) +#define VP_POLY4_C1_PH2(a) ((0xff&a)<<8) +#define VP_POLY4_C1_PH3(a) ((0xff&a)<<0) + +#define VP_POLY4_C1_PH4(a) ((0xff&a)<<24) +#define VP_POLY4_C1_PH5(a) ((0xff&a)<<16) +#define VP_POLY4_C1_PH6(a) ((0xff&a)<<8) +#define VP_POLY4_C1_PH7(a) ((0xff&a)<<0) + +#define VP_POLY4_C1_PH8(a) ((0xff&a)<<24) +#define VP_POLY4_C1_PH9(a) ((0xff&a)<<16) +#define VP_POLY4_C1_PH10(a) ((0xff&a)<<8) +#define VP_POLY4_C1_PH11(a) ((0xff&a)<<0) + +#define VP_POLY4_C1_PH12(a) ((0x7f&a)<<24) +#define VP_POLY4_C1_PH13(a) ((0x7f&a)<<16) +#define VP_POLY4_C1_PH14(a) ((0x7f&a)<<8) +#define VP_POLY4_C1_PH15(a) ((0x7f&a)<<0) + +#define VP_CSC_COEF(a) (0xfff&a) + +#define VP_BY_PASS_ENABLE (0) +#define VP_BY_PASS_DISABLE (1) + +#define VP_SATURATION(a) (0xff&a) + +#define VP_TH_HNOISE(a) ((0xf&a)<<8) +#define VP_SHARPNESS(a) (0x3&a) + +#define VP_LINE_INTC(a) ((0xffff&a)<<8) +#define VP_LINE_SLOPE(a) (0xff&a) +#define VP_LINE_INTC_CLEAR(a) (~(0xffff<<8)&a) +#define VP_LINE_SLOPE_CLEAR(a) (~0xff&a) + +#define VP_BRIGHT_OFFSET(a) (0x1ff&a) + +#define VP_SUB_Y_OFFSET_ENABLE (1<<1) +#define VP_SUB_Y_OFFSET_DISABLE (0<<1) +#define VP_CSC_ENABLE (1) +#define VP_CSC_DISABLE (0) + +static unsigned int g_vp_contrast_brightness; + +#define Y2Y_COEF_601_TO_709 0x400 +#define CB2Y_COEF_601_TO_709 0x879 +#define CR2Y_COEF_601_TO_709 0x8d9 + +#define Y2CB_COEF_601_TO_709 0x0 +#define CB2CB_COEF_601_TO_709 0x413 +#define CR2CB_COEF_601_TO_709 0x875 + +#define Y2CR_COEF_601_TO_709 0x0 +#define CB2CR_COEF_601_TO_709 0x04d +#define CR2CR_COEF_601_TO_709 0x41a + +#define Y2Y_COEF_709_TO_601 0x400 +#define CB2Y_COEF_709_TO_601 0x068 +#define CR2Y_COEF_709_TO_601 0x0c9 + +#define Y2CB_COEF_709_TO_601 0x0 +#define CB2CB_COEF_709_TO_601 0x3f6 +#define CR2CB_COEF_709_TO_601 0x871 + +#define Y2CR_COEF_709_TO_601 0x0 +#define CB2CR_COEF_709_TO_601 0x84a +#define CR2CR_COEF_709_TO_601 0xbef + +#define TILE_WIDTH 0x40 +#define MAX_NUM_OF_FRM 34 + +#endif + diff --git a/drivers/media/video/samsung/tv20/s5pc100/sdout_s5pc100.c b/drivers/media/video/samsung/tv20/s5pc100/sdout_s5pc100.c new file mode 100644 index 0000000..4346348 --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5pc100/sdout_s5pc100.c @@ -0,0 +1,2031 @@ +/* linux/drivers/media/video/samsung/tv20/s5pc100/sdout_s5pc100.c + * + * tv encoder raw ftn file for Samsung TVOut driver + * + * Copyright (c) 2009 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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/platform_device.h> + +#include <linux/io.h> +#include <linux/uaccess.h> +#include <linux/sizes.h> +#include <linux/memory.h> + +#include "tv_out_s5pc100.h" + +#include "regs/regs-sdaout.h" + +#ifdef COFIG_TVOUT_RAW_DBG +#define S5P_SDAOUT_DEBUG 1 +#endif + +#ifdef S5P_SDAOUT_DEBUG +#define SDPRINTK(fmt, args...) \ + printk(KERN_INFO "\t\t[SDOUT] %s: " fmt, __func__ , ## args) +#else +#define SDPRINTK(fmt, args...) +#endif + +static struct resource *sdout_mem; +void __iomem *sdout_base; + +/* +* initialization - iniization functions are only called under stopping SDOUT +*/ +enum s5p_tv_sd_err __s5p_sdout_init_video_scale_cfg( + enum s5p_sd_level component_level, + enum s5p_sd_vsync_ratio component_ratio, + enum s5p_sd_level composite_level, + enum s5p_sd_vsync_ratio composite_ratio) +{ + u32 temp_reg = 0; + + SDPRINTK("%d, %d, %d, %d\n\r", component_level, component_ratio, + composite_level, composite_ratio); + + switch (component_level) { + + case S5P_TV_SD_LEVEL_0IRE: + temp_reg = SDO_COMPONENT_LEVEL_SEL_0IRE; + break; + + case S5P_TV_SD_LEVEL_75IRE: + temp_reg = SDO_COMPONENT_LEVEL_SEL_75IRE; + break; + + default: + SDPRINTK("invalid component_level parameter(%d)\n\r", + component_level); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + switch (composite_level) { + + case SDOUT_VTOS_RATIO_10_4: + temp_reg |= SDO_COMPONENT_VTOS_RATIO_10_4; + break; + + case SDOUT_VTOS_RATIO_7_3: + temp_reg |= SDO_COMPONENT_VTOS_RATIO_7_3; + break; + + default: + SDPRINTK(" invalid composite_level parameter(%d)\n\r", + composite_level); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + switch (composite_level) { + + case S5P_TV_SD_LEVEL_0IRE: + temp_reg |= SDO_COMPOSITE_LEVEL_SEL_0IRE; + break; + + case S5P_TV_SD_LEVEL_75IRE: + temp_reg |= SDO_COMPOSITE_LEVEL_SEL_75IRE; + break; + + default: + SDPRINTK("invalid composite_ratio parameter(%d)\n\r", + composite_ratio); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + switch (composite_ratio) { + + case SDOUT_VTOS_RATIO_10_4: + temp_reg |= SDO_COMPOSITE_VTOS_RATIO_10_4; + break; + + case SDOUT_VTOS_RATIO_7_3: + temp_reg |= SDO_COMPOSITE_VTOS_RATIO_7_3; + break; + + default: + SDPRINTK("invalid component_ratio parameter(%d)\n\r", + component_ratio); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + writel(temp_reg, sdout_base + S5P_SDO_SCALE); + + SDPRINTK("0x%08x)\n\r", readl(sdout_base + S5P_SDO_SCALE)); + + return SDOUT_NO_ERROR; +} + +enum s5p_tv_sd_err __s5p_sdout_init_sync_signal_pin( + enum s5p_sd_sync_sig_pin pin) +{ + SDPRINTK("%d\n\r", pin); + + switch (pin) { + + case SDOUT_SYNC_SIG_NO: + writel(SDO_COMPONENT_SYNC_ABSENT, sdout_base + S5P_SDO_SYNC); + break; + + case SDOUT_SYNC_SIG_YG: + writel(SDO_COMPONENT_SYNC_YG, sdout_base + S5P_SDO_SYNC); + break; + + case SDOUT_SYNC_SIG_ALL: + writel(SDO_COMPONENT_SYNC_ALL, sdout_base + S5P_SDO_SYNC); + break; + + default: + SDPRINTK("invalid pin parameter(%d)\n\r", pin); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + SDPRINTK("0x%08x\n\r", readl(sdout_base + S5P_SDO_SYNC)); + + return SDOUT_NO_ERROR; +} + +enum s5p_tv_sd_err __s5p_sdout_init_vbi(bool wss_cvbs, + enum s5p_sd_closed_caption_type caption_cvbs, + bool wss_y_sideo, + enum s5p_sd_closed_caption_type caption_y_sideo, + bool cgmsa_rgb, + bool wss_rgb, + enum s5p_sd_closed_caption_type caption_rgb, + bool cgmsa_y_ppr, + bool wss_y_ppr, + enum s5p_sd_closed_caption_type caption_y_ppr) +{ + u32 temp_reg = 0; + + SDPRINTK(" %d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n\r", + wss_cvbs, caption_cvbs, wss_y_sideo, caption_y_sideo, + cgmsa_rgb, wss_rgb, caption_rgb, cgmsa_y_ppr, wss_y_ppr, + caption_y_ppr); + + if (wss_cvbs) + temp_reg = SDO_CVBS_WSS_INS; + else + temp_reg = SDO_CVBS_NO_WSS; + + + switch (caption_cvbs) { + + case SDOUT_NO_INS: + temp_reg |= SDO_CVBS_NO_CLOSED_CAPTION; + break; + + case SDOUT_INS_1: + temp_reg |= SDO_CVBS_21H_CLOSED_CAPTION; + break; + + case SDOUT_INS_2: + temp_reg |= SDO_CVBS_21H_284H_CLOSED_CAPTION; + break; + + case SDOUT_INS_OTHERS: + temp_reg |= SDO_CVBS_USE_OTHERS; + break; + + default: + SDPRINTK(" invalid caption_cvbs parameter(%d)\n\r", + caption_cvbs); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + if (wss_y_sideo) + temp_reg |= SDO_SVIDEO_WSS_INS; + else + temp_reg |= SDO_SVIDEO_NO_WSS; + + + switch (caption_y_sideo) { + + case SDOUT_NO_INS: + temp_reg |= SDO_SVIDEO_NO_CLOSED_CAPTION; + break; + + case SDOUT_INS_1: + temp_reg |= SDO_SVIDEO_21H_CLOSED_CAPTION; + break; + + case SDOUT_INS_2: + temp_reg |= SDO_SVIDEO_21H_284H_CLOSED_CAPTION; + break; + + case SDOUT_INS_OTHERS: + temp_reg |= SDO_SVIDEO_USE_OTHERS; + break; + + default: + SDPRINTK("invalid caption_y_sideo parameter(%d)\n\r", + caption_y_sideo); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + if (cgmsa_rgb) + temp_reg |= SDO_RGB_CGMSA_INS; + else + temp_reg |= SDO_RGB_NO_CGMSA; + + + if (wss_rgb) + temp_reg |= SDO_RGB_WSS_INS; + else + temp_reg |= SDO_RGB_NO_WSS; + + + switch (caption_rgb) { + + case SDOUT_NO_INS: + temp_reg |= SDO_RGB_NO_CLOSED_CAPTION; + break; + + case SDOUT_INS_1: + temp_reg |= SDO_RGB_21H_CLOSED_CAPTION; + break; + + case SDOUT_INS_2: + temp_reg |= SDO_RGB_21H_284H_CLOSED_CAPTION; + break; + + case SDOUT_INS_OTHERS: + temp_reg |= SDO_RGB_USE_OTHERS; + break; + + default: + SDPRINTK(" invalid caption_rgb parameter(%d)\n\r", + caption_rgb); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + if (cgmsa_y_ppr) + temp_reg |= SDO_YPBPR_CGMSA_INS; + else + temp_reg |= SDO_YPBPR_NO_CGMSA; + + if (wss_y_ppr) + temp_reg |= SDO_YPBPR_WSS_INS; + else + temp_reg |= SDO_YPBPR_NO_WSS; + + + switch (caption_y_ppr) { + + case SDOUT_NO_INS: + temp_reg |= SDO_YPBPR_NO_CLOSED_CAPTION; + break; + + case SDOUT_INS_1: + temp_reg |= SDO_YPBPR_21H_CLOSED_CAPTION; + break; + + case SDOUT_INS_2: + temp_reg |= SDO_YPBPR_21H_284H_CLOSED_CAPTION; + break; + + case SDOUT_INS_OTHERS: + temp_reg |= SDO_YPBPR_USE_OTHERS; + break; + + default: + SDPRINTK("invalid caption_y_ppr parameter(%d)\n\r", + caption_y_ppr); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + writel(temp_reg, sdout_base + S5P_SDO_VBI); + + SDPRINTK("0x%08x\n\r", readl(sdout_base + S5P_SDO_VBI)); + + return SDOUT_NO_ERROR; +} + +enum s5p_tv_sd_err __s5p_sdout_init_offset_gain( + enum s5p_sd_channel_sel channel, + u32 offset, u32 gain) +{ + SDPRINTK("%d, %d, %d\n\r", channel, offset, gain); + + switch (channel) { + + case SDOUT_CHANNEL_0: + writel(SDO_SCALE_CONV_OFFSET(offset) | + SDO_SCALE_CONV_GAIN(gain), + sdout_base + S5P_SDO_SCALE_CH0); + SDPRINTK("0x%08x\n\r", readl(sdout_base + S5P_SDO_SCALE_CH0)); + break; + + case SDOUT_CHANNEL_1: + writel(SDO_SCALE_CONV_OFFSET(offset) | + SDO_SCALE_CONV_GAIN(gain), + sdout_base + S5P_SDO_SCALE_CH1); + SDPRINTK(" 0x%08x\n\r", readl(sdout_base + S5P_SDO_SCALE_CH1)); + break; + + case SDOUT_CHANNEL_2: + writel(SDO_SCALE_CONV_OFFSET(offset) | + SDO_SCALE_CONV_GAIN(gain), + sdout_base + S5P_SDO_SCALE_CH2); + SDPRINTK(" 0x%08x\n\r", readl(sdout_base + S5P_SDO_SCALE_CH2)); + break; + + default: + SDPRINTK(" invalid channel parameter(%d)\n\r", channel); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + return SDOUT_NO_ERROR; +} + +void __s5p_sdout_init_delay(u32 delay_y, + u32 offset_video_start, + u32 offset_video_end) +{ + SDPRINTK("%d, %d, %d\n\r", delay_y, + offset_video_start, offset_video_end); + + writel(SDO_DELAY_YTOC(delay_y) | + SDO_ACTIVE_START_OFFSET(offset_video_start) | + SDO_ACTIVE_END_OFFSET(offset_video_end), + sdout_base + S5P_SDO_YCDELAY); + + SDPRINTK("0x%08x\n\r", readl(sdout_base + S5P_SDO_YCDELAY)); +} + +void __s5p_sdout_init_schlock(bool color_sucarrier_pha_adj) +{ + SDPRINTK("%d\n\r", color_sucarrier_pha_adj); + + if (color_sucarrier_pha_adj) + writel(SDO_COLOR_SC_PHASE_ADJ, sdout_base + S5P_SDO_SCHLOCK); + else + writel(SDO_COLOR_SC_PHASE_NOADJ, sdout_base + S5P_SDO_SCHLOCK); + + + SDPRINTK("0x%08x\n\r", readl(sdout_base + S5P_SDO_SCHLOCK)); +} + +enum s5p_tv_sd_err __s5p_sdout_init_dac_power_onoff( + enum s5p_sd_channel_sel channel, bool dac_on) +{ + u32 temp_on_off; + + SDPRINTK("%d, %d)\n\r", channel, dac_on); + + switch (channel) { + + case SDOUT_CHANNEL_0: + temp_on_off = SDO_POWER_ON_DAC0; + break; + + case SDOUT_CHANNEL_1: + temp_on_off = SDO_POWER_ON_DAC1; + break; + + case SDOUT_CHANNEL_2: + temp_on_off = SDO_POWER_ON_DAC2; + break; + + default: + SDPRINTK("invalid channel parameter(%d)\n\r", channel); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + if (dac_on) + writel(readl(sdout_base + S5P_SDO_DAC) | temp_on_off, + sdout_base + S5P_SDO_DAC); + else + writel(readl(sdout_base + S5P_SDO_DAC) & ~temp_on_off, + sdout_base + S5P_SDO_DAC); + + + SDPRINTK("0x%08x\n\r", readl(sdout_base + S5P_SDO_DAC)); + + return SDOUT_NO_ERROR; +} + +void __s5p_sdout_init_color_compensaton_onoff(bool bright_hue_saturation_adj, + bool y_ppr_color_compensation, + bool rgcolor_compensation, + bool y_c_color_compensation, + bool y_cvbs_color_compensation) +{ + u32 temp_reg = 0; + + SDPRINTK("%d, %d, %d, %d, %d)\n\r", bright_hue_saturation_adj, + y_ppr_color_compensation, rgcolor_compensation, + y_c_color_compensation, y_cvbs_color_compensation); + + if (bright_hue_saturation_adj) + temp_reg &= ~SDO_COMPONENT_BHS_ADJ_OFF; + else + temp_reg |= SDO_COMPONENT_BHS_ADJ_OFF; + + + if (y_ppr_color_compensation) + temp_reg &= ~SDO_COMPONENT_YPBPR_COMP_OFF; + else + temp_reg |= SDO_COMPONENT_YPBPR_COMP_OFF; + + + if (rgcolor_compensation) + temp_reg &= ~SDO_COMPONENT_RGB_COMP_OFF; + else + temp_reg |= SDO_COMPONENT_RGB_COMP_OFF; + + + if (y_c_color_compensation) + temp_reg &= ~SDO_COMPONENT_YC_COMP_OFF; + else + temp_reg |= SDO_COMPONENT_YC_COMP_OFF; + + + if (y_cvbs_color_compensation) + temp_reg &= ~SDO_COMPONENT_CVBS_COMP_OFF; + else + temp_reg |= SDO_COMPONENT_CVBS_COMP_OFF; + + + writel(temp_reg, sdout_base + S5P_SDO_CCCON); + + SDPRINTK("0x%08x\n\r", readl(sdout_base + S5P_SDO_CCCON)); +} + +void __s5p_sdout_init_brightness_hue_saturation(u32 gain_brightness, + u32 offset_brightness, + u32 gain0_cb_hue_saturation, + u32 gain1_cb_hue_saturation, + u32 gain0_cr_hue_saturation, + u32 gain1_cr_hue_saturation, + u32 offset_cb_hue_saturation, + u32 offset_cr_hue_saturation) +{ + SDPRINTK(" %d, %d, %d, %d, %d, %d, %d, %d)\n\r", gain_brightness, + offset_brightness, gain0_cb_hue_saturation, + gain1_cb_hue_saturation, gain0_cr_hue_saturation, + gain1_cr_hue_saturation, offset_cb_hue_saturation, + offset_cr_hue_saturation); + + writel(SDO_BRIGHTNESS_GAIN(gain_brightness) | + SDO_BRIGHTNESS_OFFSET(offset_brightness), + sdout_base + S5P_SDO_YSCALE); + + writel(SDO_HS_CB_GAIN0(gain0_cb_hue_saturation) | + SDO_HS_CB_GAIN1(gain1_cb_hue_saturation), + sdout_base + S5P_SDO_CBSCALE); + + writel(SDO_HS_CR_GAIN0(gain0_cr_hue_saturation) | + SDO_HS_CR_GAIN1(gain1_cr_hue_saturation), + sdout_base + S5P_SDO_CRSCALE); + + writel(SDO_HS_CR_OFFSET(offset_cr_hue_saturation) | + SDO_HS_CB_OFFSET(offset_cb_hue_saturation), + sdout_base + S5P_SDO_CB_CR_OFFSET); + + SDPRINTK("0x%08x, 0x%08x, 0x%08x, 0x%08x)\n\r", + readl(sdout_base + S5P_SDO_YSCALE), + readl(sdout_base + S5P_SDO_CBSCALE), + readl(sdout_base + S5P_SDO_CRSCALE), + readl(sdout_base + S5P_SDO_CB_CR_OFFSET)); +} + +void __s5p_sdout_init_rgb_color_compensation(u32 max_rgbcube, + u32 min_rgbcube) +{ + SDPRINTK("0x%08x, 0x%08x\n\r", max_rgbcube, min_rgbcube); + + writel(SDO_MAX_RGB_CUBE(max_rgbcube) | SDO_MIN_RGB_CUBE(min_rgbcube), + sdout_base + S5P_SDO_RGB_CC); + + SDPRINTK("0x%08x)\n\r", readl(sdout_base + S5P_SDO_RGB_CC)); +} + +void __s5p_sdout_init_cvbs_color_compensation(u32 y_lower_mid, + u32 y_bottom, + u32 y_top, + u32 y_upper_mid, + u32 radius) +{ + SDPRINTK("%d, %d, %d, %d, %d\n\r", y_lower_mid, y_bottom, + y_top, y_upper_mid, radius); + + writel(SDO_Y_LOWER_MID_CVBS_CORN(y_lower_mid) | + SDO_Y_BOTTOM_CVBS_CORN(y_bottom), + sdout_base + S5P_SDO_CVBS_CC_Y1); + writel(SDO_Y_TOP_CVBS_CORN(y_top) | + SDO_Y_UPPER_MID_CVBS_CORN(y_upper_mid), + sdout_base + S5P_SDO_CVBS_CC_Y2); + writel(SDO_RADIUS_CVBS_CORN(radius), sdout_base + S5P_SDO_CVBS_CC_C); + + SDPRINTK("0x%08x, 0x%08x, 0x%08x)\n\r", + readl(sdout_base + S5P_SDO_CVBS_CC_Y1), + readl(sdout_base + S5P_SDO_CVBS_CC_Y2), + readl(sdout_base + S5P_SDO_CVBS_CC_C)); +} + +void __s5p_sdout_init_svideo_color_compensation(u32 y_top, + u32 y_bottom, + u32 y_c_cylinder) +{ + SDPRINTK(" %d, %d, %d)\n\r", y_top, y_bottom, y_c_cylinder); + + writel(SDO_Y_TOP_YC_CYLINDER(y_top) | + SDO_Y_BOTOM_YC_CYLINDER(y_bottom), + sdout_base + S5P_SDO_YC_CC_Y); + writel(SDO_RADIUS_YC_CYLINDER(y_c_cylinder), + sdout_base + S5P_SDO_YC_CC_C); + + SDPRINTK("0x%08x, 0x%08x)\n\r", readl(sdout_base + S5P_SDO_YC_CC_Y), + readl(sdout_base + S5P_SDO_YC_CC_C)); +} + +void __s5p_sdout_init_component_porch(u32 back_525, + u32 front_525, + u32 back_625, + u32 front_625) +{ + SDPRINTK(" %d, %d, %d, %d)\n\r", back_525, + front_525, back_625, front_625); + + writel(SDO_COMPONENT_525_BP(back_525) | + SDO_COMPONENT_525_FP(front_525), + sdout_base + S5P_SDO_CSC_525_PORCH); + writel(SDO_COMPONENT_625_BP(back_625) | + SDO_COMPONENT_625_FP(front_625), + sdout_base + S5P_SDO_CSC_625_PORCH); + + SDPRINTK(" 0x%08x, 0x%08x)\n\r", + readl(sdout_base + S5P_SDO_CSC_525_PORCH), + readl(sdout_base + S5P_SDO_CSC_625_PORCH)); +} + +enum s5p_tv_sd_err __s5p_sdout_init_vesa_rgb_sync( + enum s5p_sd_vesa_rgb_sync_type sync_type, + enum s5p_tv_active_polarity v_sync_active, + enum s5p_tv_active_polarity h_sync_active) +{ + u32 temp_reg = 0; + + SDPRINTK("%d, %d, %d\n\r", sync_type, v_sync_active, h_sync_active); + + switch (sync_type) { + + case SDOUT_VESA_RGB_SYNC_COMPOSITE: + temp_reg |= SDO_RGB_SYNC_COMPOSITE; + break; + + case SDOUT_VESA_RGB_SYNC_SEPARATE: + temp_reg |= SDO_RGB_SYNC_SEPERATE; + break; + + default: + SDPRINTK(" invalid sync_type parameter(%d)\n\r", sync_type); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + switch (v_sync_active) { + + case TVOUT_POL_ACTIVE_LOW: + temp_reg |= SDO_RGB_VSYNC_LOW_ACT; + break; + + case TVOUT_POL_ACTIVE_HIGH: + temp_reg |= SDO_RGB_VSYNC_HIGH_ACT; + break; + + default: + SDPRINTK(" invalid v_sync_active parameter(%d)\n\r", + v_sync_active); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + switch (h_sync_active) { + + case TVOUT_POL_ACTIVE_LOW: + temp_reg |= SDO_RGB_HSYNC_LOW_ACT; + break; + + case TVOUT_POL_ACTIVE_HIGH: + temp_reg |= SDO_RGB_HSYNC_HIGH_ACT; + break; + + default: + SDPRINTK(" invalid h_sync_active parameter(%d)\n\r", + h_sync_active); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + writel(temp_reg, sdout_base + S5P_SDO_RGBSYNC); + + SDPRINTK("0x%08x\n\r", readl(sdout_base + S5P_SDO_RGBSYNC)); + + return SDOUT_NO_ERROR; +} + +void __s5p_sdout_init_oversampling_filter_coeff(u32 size, + u32 *coeff, + u32 *coeff1, + u32 *coeff2) +{ + u32 *temp_reg = 0; + + SDPRINTK(" %d, 0x%x, 0x%x, 0x%x\n\r", (u32)size, (u32)coeff, + (u32)coeff1, (u32)coeff2); + + if (coeff != NULL) { + temp_reg = (u32 *)readl(sdout_base + S5P_SDO_OSFC00_0); + memcpy((void *)temp_reg, (const void *)coeff, size*4); + } + + if (coeff1 != NULL) { + temp_reg = (u32 *)readl(sdout_base + S5P_SDO_OSFC00_1); + memcpy((void *)temp_reg, (const void *)coeff1, size*4); + } + + if (coeff2 != NULL) { + temp_reg = (u32 *)readl(sdout_base + S5P_SDO_OSFC00_2); + memcpy((void *)temp_reg, (const void *)coeff2, size*4); + } + + SDPRINTK(" ()\n\r"); +} + +enum s5p_tv_sd_err __s5p_sdout_init_ch_xtalk_cancel_coef( + enum s5p_sd_channel_sel channel, + u32 coeff2, u32 coeff1) +{ + SDPRINTK(" %d, %d, %d\n\r", channel, coeff2, coeff1); + + switch (channel) { + + case SDOUT_CHANNEL_0: + writel(SDO_XTALK_COEF02(coeff2) | SDO_XTALK_COEF01(coeff1), + sdout_base + S5P_SDO_XTALK0); + SDPRINTK(" 0x%08x)\n\r", readl(sdout_base + S5P_SDO_XTALK0)); + break; + + case SDOUT_CHANNEL_1: + writel(SDO_XTALK_COEF02(coeff2) | SDO_XTALK_COEF01(coeff1), + sdout_base + S5P_SDO_XTALK1); + SDPRINTK(" 0x%08x)\n\r", readl(sdout_base + S5P_SDO_XTALK1)); + break; + + case SDOUT_CHANNEL_2: + writel(SDO_XTALK_COEF02(coeff2) | SDO_XTALK_COEF01(coeff1), + sdout_base + S5P_SDO_XTALK2); + SDPRINTK("0x%08x)\n\r", readl(sdout_base + S5P_SDO_XTALK2)); + break; + + default: + SDPRINTK(" invalid channel parameter(%d)\n\r", channel); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + return SDOUT_NO_ERROR; +} + +void __s5p_sdout_init_closed_caption(u32 display_cc, u32 non_display_cc) +{ + SDPRINTK("%d, %d\n\r", display_cc, non_display_cc); + + writel(SDO_DISPLAY_CC_CAPTION(display_cc) | + SDO_NON_DISPLAY_CC_CAPTION(non_display_cc), + sdout_base + S5P_SDO_ARMCC); + + SDPRINTK("0x%x\n\r", readl(sdout_base + S5P_SDO_ARMCC)); +} + + +static u32 __s5p_sdout_init_wss_cgms_crc(u32 value) +{ + u8 i; + u8 CGMS[14], CRC[6], OLD_CRC; + u32 temp_in; + + temp_in = value; + + for (i = 0; i < 14; i++) + CGMS[i] = (u8)(temp_in >> i) & 0x1 ; + + for (i = 0; i < 6; i++) + CRC[i] = 0x1; + + for (i = 0; i < 14; i++) { + OLD_CRC = CRC[0]; + CRC[0] = CRC[1]; + CRC[1] = CRC[2]; + CRC[2] = CRC[3]; + CRC[3] = CRC[4]; + CRC[4] = OLD_CRC ^ CGMS[i] ^ CRC[5]; + CRC[5] = OLD_CRC ^ CGMS[i]; + } + + temp_in &= 0x3fff; + + for (i = 0; i < 6; i++) + temp_in |= ((u32)(CRC[i] & 0x1) << i); + + + return temp_in; +} + + +enum s5p_tv_sd_err __s5p_sdout_init_wss525_data( + enum s5p_sd_525_copy_permit copy_permit, + enum s5p_sd_525_mv_psp mv_psp, + enum s5p_sd_525_copy_info copy_info, + bool analog_on, + enum s5p_sd_525_aspect_ratio display_ratio) +{ + u32 temp_reg = 0; + + SDPRINTK("%d, %d, %d, %d\n\r", copy_permit, mv_psp, copy_info, + display_ratio); + + switch (copy_permit) { + + case SDO_525_COPY_PERMIT: + temp_reg = SDO_WORD2_WSS525_COPY_PERMIT; + break; + + case SDO_525_ONECOPY_PERMIT: + temp_reg = SDO_WORD2_WSS525_ONECOPY_PERMIT; + break; + + case SDO_525_NOCOPY_PERMIT: + temp_reg = SDO_WORD2_WSS525_NOCOPY_PERMIT; + break; + + default: + SDPRINTK(" invalid copy_permit parameter(%d)\n\r", + copy_permit); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + switch (mv_psp) { + + case SDO_525_MV_PSP_OFF: + temp_reg |= SDO_WORD2_WSS525_MV_PSP_OFF; + break; + + case SDO_525_MV_PSP_ON_2LINE_BURST: + temp_reg |= SDO_WORD2_WSS525_MV_PSP_ON_2LINE_BURST; + break; + + case SDO_525_MV_PSP_ON_BURST_OFF: + temp_reg |= SDO_WORD2_WSS525_MV_PSP_ON_BURST_OFF; + break; + + case SDO_525_MV_PSP_ON_4LINE_BURST: + temp_reg |= SDO_WORD2_WSS525_MV_PSP_ON_4LINE_BURST; + break; + + default: + SDPRINTK(" invalid mv_psp parameter(%d)\n\r", mv_psp); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + switch (copy_info) { + + case SDO_525_COPY_INFO: + temp_reg |= SDO_WORD1_WSS525_COPY_INFO; + break; + + case SDO_525_DEFAULT: + temp_reg |= SDO_WORD1_WSS525_DEFAULT; + break; + + default: + SDPRINTK(" invalid copy_info parameter(%d)\n\r", copy_info); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + if (analog_on) + temp_reg |= SDO_WORD2_WSS525_ANALOG_ON; + else + temp_reg |= SDO_WORD2_WSS525_ANALOG_OFF; + + + switch (display_ratio) { + + case SDO_525_COPY_PERMIT: + temp_reg |= SDO_WORD0_WSS525_4_3_NORMAL; + break; + + case SDO_525_ONECOPY_PERMIT: + temp_reg |= SDO_WORD0_WSS525_16_9_ANAMORPIC; + break; + + case SDO_525_NOCOPY_PERMIT: + temp_reg |= SDO_WORD0_WSS525_4_3_LETTERBOX; + break; + + default: + SDPRINTK(" invalid display_ratio parameter(%d)\n\r", + display_ratio); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + writel(temp_reg | SDO_CRC_WSS525( + __s5p_sdout_init_wss_cgms_crc(temp_reg)), + sdout_base + S5P_SDO_WSS525); + + SDPRINTK("0x%08x)\n\r", readl(sdout_base + S5P_SDO_WSS525)); + + return SDOUT_NO_ERROR; +} + +enum s5p_tv_sd_err __s5p_sdout_init_wss625_data(bool surround_sound, + bool copyright, + bool copy_protection, + bool text_subtitles, + enum s5p_sd_625_subtitles open_subtitles, + enum s5p_sd_625_camera_film camera_film, + enum s5p_sd_625_color_encoding color_encoding, + bool helper_signal, + enum s5p_sd_625_aspect_ratio display_ratio) +{ + u32 temp_reg = 0; + + SDPRINTK("%d, %d, %d, %d, %d, %d, %d, %d, %d\n\r", + surround_sound, copyright, copy_protection, + text_subtitles, open_subtitles, camera_film, + color_encoding, helper_signal, display_ratio); + + if (surround_sound) + temp_reg = SDO_WSS625_SURROUND_SOUND_ENABLE; + else + temp_reg = SDO_WSS625_SURROUND_SOUND_DISABLE; + + + if (copyright) + temp_reg |= SDO_WSS625_COPYRIGHT; + else + temp_reg |= SDO_WSS625_NO_COPYRIGHT; + + + if (copy_protection) + temp_reg |= SDO_WSS625_COPY_RESTRICTED; + else + temp_reg |= SDO_WSS625_COPY_NOT_RESTRICTED; + + + if (text_subtitles) + temp_reg |= SDO_WSS625_TELETEXT_SUBTITLES; + else + temp_reg |= SDO_WSS625_TELETEXT_NO_SUBTITLES; + + + switch (open_subtitles) { + + case SDO_625_NO_OPEN_SUBTITLES: + temp_reg |= SDO_WSS625_NO_OPEN_SUBTITLES; + break; + + case SDO_625_INACT_OPEN_SUBTITLES: + temp_reg |= SDO_WSS625_INACT_OPEN_SUBTITLES; + break; + + case SDO_625_OUTACT_OPEN_SUBTITLES: + temp_reg |= SDO_WSS625_OUTACT_OPEN_SUBTITLES; + break; + + default: + SDPRINTK(" invalid open_subtitles parameter(%d)\n\r", + open_subtitles); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + switch (camera_film) { + + case SDO_625_CAMERA: + temp_reg |= SDO_WSS625_CAMERA; + break; + + case SDO_625_FILM: + temp_reg |= SDO_WSS625_FILM; + break; + + default: + SDPRINTK("invalid camera_film parameter(%d)\n\r", camera_film); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + switch (color_encoding) { + + case SDO_625_NORMAL_PAL: + temp_reg |= SDO_WSS625_NORMAL_PAL; + break; + + case SDO_625_MOTION_ADAPTIVE_COLORPLUS: + temp_reg |= SDO_WSS625_MOTION_ADAPTIVE_COLORPLUS; + break; + + default: + SDPRINTK("invalid color_encoding parameter(%d)\n\r", + color_encoding); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + if (helper_signal) + temp_reg |= SDO_WSS625_HELPER_SIG; + else + temp_reg |= SDO_WSS625_HELPER_NO_SIG; + + + switch (display_ratio) { + + case SDO_625_4_3_FULL_576: + temp_reg |= SDO_WSS625_4_3_FULL_576; + break; + + case SDO_625_14_9_LETTERBOX_CENTER_504: + temp_reg |= SDO_WSS625_14_9_LETTERBOX_CENTER_504; + break; + + case SDO_625_14_9_LETTERBOX_TOP_504: + temp_reg |= SDO_WSS625_14_9_LETTERBOX_TOP_504; + break; + + case SDO_625_16_9_LETTERBOX_CENTER_430: + temp_reg |= SDO_WSS625_16_9_LETTERBOX_CENTER_430; + break; + + case SDO_625_16_9_LETTERBOX_TOP_430: + temp_reg |= SDO_WSS625_16_9_LETTERBOX_TOP_430; + break; + + case SDO_625_16_9_LETTERBOX_CENTER: + temp_reg |= SDO_WSS625_16_9_LETTERBOX_CENTER; + break; + + case SDO_625_14_9_FULL_CENTER_576: + temp_reg |= SDO_WSS625_14_9_FULL_CENTER_576; + break; + + case SDO_625_16_9_ANAMORPIC_576: + temp_reg |= SDO_WSS625_16_9_ANAMORPIC_576; + break; + + default: + SDPRINTK("invalid display_ratio parameter(%d)\n\r", + display_ratio); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + writel(temp_reg, sdout_base + S5P_SDO_WSS625); + + SDPRINTK("0x%08x\n\r", readl(sdout_base + S5P_SDO_WSS625)); + + return SDOUT_NO_ERROR; +} + +enum s5p_tv_sd_err __s5p_sdout_init_cgmsa525_data( + enum s5p_sd_525_copy_permit copy_permit, + enum s5p_sd_525_mv_psp mv_psp, + enum s5p_sd_525_copy_info copy_info, + bool analog_on, + enum s5p_sd_525_aspect_ratio display_ratio) +{ + u32 temp_reg = 0; + + SDPRINTK("%d, %d, %d, %d)\n\r", copy_permit, mv_psp, + copy_info, display_ratio); + + switch (copy_permit) { + + case SDO_525_COPY_PERMIT: + temp_reg = SDO_WORD2_CGMS525_COPY_PERMIT; + break; + + case SDO_525_ONECOPY_PERMIT: + temp_reg = SDO_WORD2_CGMS525_ONECOPY_PERMIT; + break; + + case SDO_525_NOCOPY_PERMIT: + temp_reg = SDO_WORD2_CGMS525_NOCOPY_PERMIT; + break; + + default: + SDPRINTK("invalid copy_permit parameter(%d)\n\r", copy_permit); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + switch (mv_psp) { + + case SDO_525_MV_PSP_OFF: + temp_reg |= SDO_WORD2_CGMS525_MV_PSP_OFF; + break; + + case SDO_525_MV_PSP_ON_2LINE_BURST: + temp_reg |= SDO_WORD2_CGMS525_MV_PSP_ON_2LINE_BURST; + break; + + case SDO_525_MV_PSP_ON_BURST_OFF: + temp_reg |= SDO_WORD2_CGMS525_MV_PSP_ON_BURST_OFF; + break; + + case SDO_525_MV_PSP_ON_4LINE_BURST: + temp_reg |= SDO_WORD2_CGMS525_MV_PSP_ON_4LINE_BURST; + break; + + default: + SDPRINTK(" invalid mv_psp parameter(%d)\n\r", mv_psp); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + switch (copy_info) { + + case SDO_525_COPY_INFO: + temp_reg |= SDO_WORD1_CGMS525_COPY_INFO; + break; + + case SDO_525_DEFAULT: + temp_reg |= SDO_WORD1_CGMS525_DEFAULT; + break; + + default: + SDPRINTK("invalid copy_info parameter(%d)\n\r", copy_info); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + if (analog_on) + temp_reg |= SDO_WORD2_CGMS525_ANALOG_ON; + else + temp_reg |= SDO_WORD2_CGMS525_ANALOG_OFF; + + + switch (display_ratio) { + + case SDO_525_COPY_PERMIT: + temp_reg |= SDO_WORD0_CGMS525_4_3_NORMAL; + break; + + case SDO_525_ONECOPY_PERMIT: + temp_reg |= SDO_WORD0_CGMS525_16_9_ANAMORPIC; + break; + + case SDO_525_NOCOPY_PERMIT: + temp_reg |= SDO_WORD0_CGMS525_4_3_LETTERBOX; + break; + + default: + SDPRINTK(" invalid display_ratio parameter(%d)\n\r", + display_ratio); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + writel(temp_reg | + SDO_CRC_CGMS525(__s5p_sdout_init_wss_cgms_crc(temp_reg)), + sdout_base + S5P_SDO_CGMS525); + + SDPRINTK(" 0x%08x)\n\r", readl(sdout_base + S5P_SDO_CGMS525)); + + return SDOUT_NO_ERROR; +} + +enum s5p_tv_sd_err __s5p_sdout_init_cgmsa625_data(bool surround_sound, + bool copyright, + bool copy_protection, + bool text_subtitles, + enum s5p_sd_625_subtitles open_subtitles, + enum s5p_sd_625_camera_film camera_film, + enum s5p_sd_625_color_encoding color_encoding, + bool helper_signal, + enum s5p_sd_625_aspect_ratio display_ratio) +{ + u32 temp_reg = 0; + + SDPRINTK("%d, %d, %d, %d, %d, %d, %d, %d, %d)\n\r", + surround_sound, copyright, copy_protection, + text_subtitles, open_subtitles, camera_film, + color_encoding, helper_signal, display_ratio); + + if (surround_sound) + temp_reg = SDO_CGMS625_SURROUND_SOUND_ENABLE; + else + temp_reg = SDO_CGMS625_SURROUND_SOUND_DISABLE; + + + if (copyright) + temp_reg |= SDO_CGMS625_COPYRIGHT; + else + temp_reg |= SDO_CGMS625_NO_COPYRIGHT; + + + if (copy_protection) + temp_reg |= SDO_CGMS625_COPY_RESTRICTED; + else + temp_reg |= SDO_CGMS625_COPY_NOT_RESTRICTED; + + + if (text_subtitles) + temp_reg |= SDO_CGMS625_TELETEXT_SUBTITLES; + else + temp_reg |= SDO_CGMS625_TELETEXT_NO_SUBTITLES; + + switch (open_subtitles) { + + case SDO_625_NO_OPEN_SUBTITLES: + temp_reg |= SDO_CGMS625_NO_OPEN_SUBTITLES; + break; + + case SDO_625_INACT_OPEN_SUBTITLES: + temp_reg |= SDO_CGMS625_INACT_OPEN_SUBTITLES; + break; + + case SDO_625_OUTACT_OPEN_SUBTITLES: + temp_reg |= SDO_CGMS625_OUTACT_OPEN_SUBTITLES; + break; + + default: + SDPRINTK("invalid open_subtitles parameter(%d)\n\r", + open_subtitles); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + switch (camera_film) { + + case SDO_625_CAMERA: + temp_reg |= SDO_CGMS625_CAMERA; + break; + + case SDO_625_FILM: + temp_reg |= SDO_CGMS625_FILM; + break; + + default: + SDPRINTK(" invalid camera_film parameter(%d)\n\r", + camera_film); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + switch (color_encoding) { + + case SDO_625_NORMAL_PAL: + temp_reg |= SDO_CGMS625_NORMAL_PAL; + break; + + case SDO_625_MOTION_ADAPTIVE_COLORPLUS: + temp_reg |= SDO_CGMS625_MOTION_ADAPTIVE_COLORPLUS; + break; + + default: + SDPRINTK(" invalid color_encoding parameter(%d)\n\r", + color_encoding); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + if (helper_signal) + temp_reg |= SDO_CGMS625_HELPER_SIG; + else + temp_reg |= SDO_CGMS625_HELPER_NO_SIG; + + + switch (display_ratio) { + + case SDO_625_4_3_FULL_576: + temp_reg |= SDO_CGMS625_4_3_FULL_576; + break; + + case SDO_625_14_9_LETTERBOX_CENTER_504: + temp_reg |= SDO_CGMS625_14_9_LETTERBOX_CENTER_504; + break; + + case SDO_625_14_9_LETTERBOX_TOP_504: + temp_reg |= SDO_CGMS625_14_9_LETTERBOX_TOP_504; + break; + + case SDO_625_16_9_LETTERBOX_CENTER_430: + temp_reg |= SDO_CGMS625_16_9_LETTERBOX_CENTER_430; + break; + + case SDO_625_16_9_LETTERBOX_TOP_430: + temp_reg |= SDO_CGMS625_16_9_LETTERBOX_TOP_430; + break; + + case SDO_625_16_9_LETTERBOX_CENTER: + temp_reg |= SDO_CGMS625_16_9_LETTERBOX_CENTER; + break; + + case SDO_625_14_9_FULL_CENTER_576: + temp_reg |= SDO_CGMS625_14_9_FULL_CENTER_576; + break; + + case SDO_625_16_9_ANAMORPIC_576: + temp_reg |= SDO_CGMS625_16_9_ANAMORPIC_576; + break; + + default: + SDPRINTK("invalid display_ratio parameter(%d)\n\r", + display_ratio); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + writel(temp_reg, sdout_base + S5P_SDO_CGMS625); + + SDPRINTK("0x%08x\n\r", readl(sdout_base + S5P_SDO_CGMS625)); + + return SDOUT_NO_ERROR; +} + + +static enum s5p_tv_sd_err __s5p_sdout_init_antialias_filter_coeff_default( + enum s5p_sd_level composite_level, + enum s5p_sd_vsync_ratio composite_ratio, + enum s5p_tv_o_mode out_mode) +{ + SDPRINTK("%d, %d, %d\n\r", composite_level, composite_ratio, out_mode); + + switch (composite_level) { + + case S5P_TV_SD_LEVEL_0IRE: + + switch (composite_ratio) { + + case SDOUT_VTOS_RATIO_10_4: + + switch (out_mode) { + + case TVOUT_OUTPUT_COMPOSITE: + + case TVOUT_OUTPUT_SVIDEO: + writel(0x00000000 , sdout_base + S5P_SDO_Y3); + writel(0x00000000 , sdout_base + S5P_SDO_Y4); + writel(0x00000000 , sdout_base + S5P_SDO_Y5); + writel(0x00000000 , sdout_base + S5P_SDO_Y6); + writel(0x00000000 , sdout_base + S5P_SDO_Y7); + writel(0x00000000 , sdout_base + S5P_SDO_Y8); + writel(0x00000000 , sdout_base + S5P_SDO_Y9); + writel(0x00000000 , sdout_base + S5P_SDO_Y10); + writel(0x0000029a , sdout_base + S5P_SDO_Y11); + writel(0x00000000 , sdout_base + S5P_SDO_CB0); + writel(0x00000000 , sdout_base + S5P_SDO_CB1); + writel(0x00000000 , sdout_base + S5P_SDO_CB2); + writel(0x00000000 , sdout_base + S5P_SDO_CB3); + writel(0x00000000 , sdout_base + S5P_SDO_CB4); + writel(0x00000001 , sdout_base + S5P_SDO_CB5); + writel(0x00000007 , sdout_base + S5P_SDO_CB6); + writel(0x00000015 , sdout_base + S5P_SDO_CB7); + writel(0x0000002b , sdout_base + S5P_SDO_CB8); + writel(0x00000045 , sdout_base + S5P_SDO_CB9); + writel(0x00000059 , sdout_base + S5P_SDO_CB10); + writel(0x00000061 , sdout_base + S5P_SDO_CB11); + writel(0x00000000 , sdout_base + S5P_SDO_CR1); + writel(0x00000000 , sdout_base + S5P_SDO_CR2); + writel(0x00000000 , sdout_base + S5P_SDO_CR3); + writel(0x00000000 , sdout_base + S5P_SDO_CR4); + writel(0x00000002 , sdout_base + S5P_SDO_CR5); + writel(0x0000000a , sdout_base + S5P_SDO_CR6); + writel(0x0000001e , sdout_base + S5P_SDO_CR7); + writel(0x0000003d , sdout_base + S5P_SDO_CR8); + writel(0x00000061 , sdout_base + S5P_SDO_CR9); + writel(0x0000007a , sdout_base + S5P_SDO_CR10); + writel(0x0000008f , sdout_base + S5P_SDO_CR11); + break; + + case TVOUT_OUTPUT_COMPONENT_YPBPR_INERLACED: + + case TVOUT_OUTPUT_COMPONENT_YPBPR_PROGRESSIVE: + + case TVOUT_OUTPUT_COMPONENT_RGB_PROGRESSIVE: + writel(0x00000000, sdout_base + S5P_SDO_Y0); + writel(0x00000000, sdout_base + S5P_SDO_Y1); + writel(0x00000000, sdout_base + S5P_SDO_Y2); + writel(0x00000000, sdout_base + S5P_SDO_Y3); + writel(0x00000000, sdout_base + S5P_SDO_Y4); + writel(0x00000000, sdout_base + S5P_SDO_Y5); + writel(0x00000000, sdout_base + S5P_SDO_Y6); + writel(0x00000000, sdout_base + S5P_SDO_Y7); + writel(0x00000000, sdout_base + S5P_SDO_Y8); + writel(0x00000000, sdout_base + S5P_SDO_Y9); + writel(0x00000000, sdout_base + S5P_SDO_Y10); + writel(0x0000029a, sdout_base + S5P_SDO_Y11); + writel(0x00000000, sdout_base + S5P_SDO_CB0); + writel(0x00000000, sdout_base + S5P_SDO_CB1); + writel(0x00000000, sdout_base + S5P_SDO_CB2); + writel(0x00000000, sdout_base + S5P_SDO_CB3); + writel(0x00000000, sdout_base + S5P_SDO_CB4); + writel(0x00000001, sdout_base + S5P_SDO_CB5); + writel(0x00000007, sdout_base + S5P_SDO_CB6); + writel(0x00000015, sdout_base + S5P_SDO_CB7); + writel(0x0000002b, sdout_base + S5P_SDO_CB8); + writel(0x00000045, sdout_base + S5P_SDO_CB9); + writel(0x00000059, sdout_base + S5P_SDO_CB10); + writel(0x00000061, sdout_base + S5P_SDO_CB11); + writel(0x00000000, sdout_base + S5P_SDO_CR1); + writel(0x00000000, sdout_base + S5P_SDO_CR2); + writel(0x00000000, sdout_base + S5P_SDO_CR3); + writel(0x00000000, sdout_base + S5P_SDO_CR4); + writel(0x00000002, sdout_base + S5P_SDO_CR5); + writel(0x0000000a, sdout_base + S5P_SDO_CR6); + writel(0x0000001e, sdout_base + S5P_SDO_CR7); + writel(0x0000003d, sdout_base + S5P_SDO_CR8); + writel(0x00000061, sdout_base + S5P_SDO_CR9); + writel(0x0000007a, sdout_base + S5P_SDO_CR10); + writel(0x0000008f, sdout_base + S5P_SDO_CR11); + break; + + default: + SDPRINTK("invalid out_mode parameter(%d)\n\r", + out_mode); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + break; + + case SDOUT_VTOS_RATIO_7_3: + writel(0x00000000, sdout_base + S5P_SDO_Y0); + writel(0x00000000, sdout_base + S5P_SDO_Y1); + writel(0x00000000, sdout_base + S5P_SDO_Y2); + writel(0x00000000, sdout_base + S5P_SDO_Y3); + writel(0x00000000, sdout_base + S5P_SDO_Y4); + writel(0x00000000, sdout_base + S5P_SDO_Y5); + writel(0x00000000, sdout_base + S5P_SDO_Y6); + writel(0x00000000, sdout_base + S5P_SDO_Y7); + writel(0x00000000, sdout_base + S5P_SDO_Y8); + writel(0x00000000, sdout_base + S5P_SDO_Y9); + writel(0x00000000, sdout_base + S5P_SDO_Y10); + writel(0x00000281, sdout_base + S5P_SDO_Y11); + writel(0x00000000, sdout_base + S5P_SDO_CB0); + writel(0x00000000, sdout_base + S5P_SDO_CB1); + writel(0x00000000, sdout_base + S5P_SDO_CB2); + writel(0x00000000, sdout_base + S5P_SDO_CB3); + writel(0x00000000, sdout_base + S5P_SDO_CB4); + writel(0x00000001, sdout_base + S5P_SDO_CB5); + writel(0x00000007, sdout_base + S5P_SDO_CB6); + writel(0x00000015, sdout_base + S5P_SDO_CB7); + writel(0x0000002a, sdout_base + S5P_SDO_CB8); + writel(0x00000044, sdout_base + S5P_SDO_CB9); + writel(0x00000057, sdout_base + S5P_SDO_CB10); + writel(0x0000005f, sdout_base + S5P_SDO_CB11); + writel(0x00000000, sdout_base + S5P_SDO_CR1); + writel(0x00000000, sdout_base + S5P_SDO_CR2); + writel(0x00000000, sdout_base + S5P_SDO_CR3); + writel(0x00000000, sdout_base + S5P_SDO_CR4); + writel(0x00000002, sdout_base + S5P_SDO_CR5); + writel(0x0000000a, sdout_base + S5P_SDO_CR6); + writel(0x0000001d, sdout_base + S5P_SDO_CR7); + writel(0x0000003c, sdout_base + S5P_SDO_CR8); + writel(0x0000005f, sdout_base + S5P_SDO_CR9); + writel(0x0000007b, sdout_base + S5P_SDO_CR10); + writel(0x00000086, sdout_base + S5P_SDO_CR11); + break; + + default: + SDPRINTK("invalid composite_ratio parameter(%d)\n\r", + composite_ratio); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + break; + + case S5P_TV_SD_LEVEL_75IRE: + + switch (composite_ratio) { + + case SDOUT_VTOS_RATIO_10_4: + writel(0x00000000, sdout_base + S5P_SDO_Y0); + writel(0x00000000, sdout_base + S5P_SDO_Y1); + writel(0x00000000, sdout_base + S5P_SDO_Y2); + writel(0x00000000, sdout_base + S5P_SDO_Y3); + writel(0x00000000, sdout_base + S5P_SDO_Y4); + writel(0x00000000, sdout_base + S5P_SDO_Y5); + writel(0x00000000, sdout_base + S5P_SDO_Y6); + writel(0x00000000, sdout_base + S5P_SDO_Y7); + writel(0x00000000, sdout_base + S5P_SDO_Y8); + writel(0x00000000, sdout_base + S5P_SDO_Y9); + writel(0x00000000, sdout_base + S5P_SDO_Y10); + writel(0x0000025d, sdout_base + S5P_SDO_Y11); + writel(0x00000000, sdout_base + S5P_SDO_CB0); + writel(0x00000000, sdout_base + S5P_SDO_CB1); + writel(0x00000000, sdout_base + S5P_SDO_CB2); + writel(0x00000000, sdout_base + S5P_SDO_CB3); + writel(0x00000000, sdout_base + S5P_SDO_CB4); + writel(0x00000001, sdout_base + S5P_SDO_CB5); + writel(0x00000007, sdout_base + S5P_SDO_CB6); + writel(0x00000014, sdout_base + S5P_SDO_CB7); + writel(0x00000028, sdout_base + S5P_SDO_CB8); + writel(0x0000003f, sdout_base + S5P_SDO_CB9); + writel(0x00000052, sdout_base + S5P_SDO_CB10); + writel(0x0000005a, sdout_base + S5P_SDO_CB11); + writel(0x00000000, sdout_base + S5P_SDO_CR1); + writel(0x00000000, sdout_base + S5P_SDO_CR2); + writel(0x00000000, sdout_base + S5P_SDO_CR3); + writel(0x00000000, sdout_base + S5P_SDO_CR4); + writel(0x00000001, sdout_base + S5P_SDO_CR5); + writel(0x00000009, sdout_base + S5P_SDO_CR6); + writel(0x0000001c, sdout_base + S5P_SDO_CR7); + writel(0x00000039, sdout_base + S5P_SDO_CR8); + writel(0x0000005a, sdout_base + S5P_SDO_CR9); + writel(0x00000074, sdout_base + S5P_SDO_CR10); + writel(0x0000007e, sdout_base + S5P_SDO_CR11); + break; + + case SDOUT_VTOS_RATIO_7_3: + writel(0x00000000, sdout_base + S5P_SDO_Y0); + writel(0x00000000, sdout_base + S5P_SDO_Y1); + writel(0x00000000, sdout_base + S5P_SDO_Y2); + writel(0x00000000, sdout_base + S5P_SDO_Y3); + writel(0x00000000, sdout_base + S5P_SDO_Y4); + writel(0x00000000, sdout_base + S5P_SDO_Y5); + writel(0x00000000, sdout_base + S5P_SDO_Y6); + writel(0x00000000, sdout_base + S5P_SDO_Y7); + writel(0x00000000, sdout_base + S5P_SDO_Y8); + writel(0x00000000, sdout_base + S5P_SDO_Y9); + writel(0x00000000, sdout_base + S5P_SDO_Y10); + writel(0x00000251, sdout_base + S5P_SDO_Y11); + writel(0x00000000, sdout_base + S5P_SDO_CB0); + writel(0x00000000, sdout_base + S5P_SDO_CB1); + writel(0x00000000, sdout_base + S5P_SDO_CB2); + writel(0x00000000, sdout_base + S5P_SDO_CB3); + writel(0x00000000, sdout_base + S5P_SDO_CB4); + writel(0x00000001, sdout_base + S5P_SDO_CB5); + writel(0x00000006, sdout_base + S5P_SDO_CB6); + writel(0x00000013, sdout_base + S5P_SDO_CB7); + writel(0x00000028, sdout_base + S5P_SDO_CB8); + writel(0x0000003f, sdout_base + S5P_SDO_CB9); + writel(0x00000051, sdout_base + S5P_SDO_CB10); + writel(0x00000056, sdout_base + S5P_SDO_CB11); + writel(0x00000000, sdout_base + S5P_SDO_CR1); + writel(0x00000000, sdout_base + S5P_SDO_CR2); + writel(0x00000000, sdout_base + S5P_SDO_CR3); + writel(0x00000000, sdout_base + S5P_SDO_CR4); + writel(0x00000002, sdout_base + S5P_SDO_CR5); + writel(0x00000005, sdout_base + S5P_SDO_CR6); + writel(0x00000018, sdout_base + S5P_SDO_CR7); + writel(0x00000037, sdout_base + S5P_SDO_CR8); + writel(0x0000005A, sdout_base + S5P_SDO_CR9); + writel(0x00000076, sdout_base + S5P_SDO_CR10); + writel(0x0000007e, sdout_base + S5P_SDO_CR11); + break; + + default: + SDPRINTK(" invalid composite_ratio parameter(%d)\n\r", + composite_ratio); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + break; + + default: + SDPRINTK(" invalid composite_level parameter(%d)\n\r", + composite_level); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + SDPRINTK("()\n\r"); + + return SDOUT_NO_ERROR; + +} + + +static enum s5p_tv_sd_err __s5p_sdout_init_oversampling_filter_coeff_default( + enum s5p_tv_o_mode out_mode) +{ + u32 temp_reg = 0; + u8 i; + + SDPRINTK("%d\n\r", out_mode); + + switch (out_mode) { + + case TVOUT_OUTPUT_COMPOSITE: + + case TVOUT_OUTPUT_SVIDEO: + + case TVOUT_OUTPUT_COMPONENT_YPBPR_INERLACED: + temp_reg = (u32)(sdout_base + S5P_SDO_OSFC00_0); + + for (i = 0; i < 3; i++) { + temp_reg = (u32)((i == 0) ? + sdout_base + S5P_SDO_OSFC00_0 : + (i == 1) ? + sdout_base + S5P_SDO_OSFC00_1 : + sdout_base + S5P_SDO_OSFC00_2); + + writel(((-2&0xfff) << 0) | ((-3&0xfff) << 0), + temp_reg + 0); + writel(0, + temp_reg + 1); + writel((4 << 0) | (5 << 16), + temp_reg + 2); + writel(((-1&0xfff) << 0) | (0 << 16), + temp_reg + 3); + writel(((-6&0xfff) << 0) | ((-9&0xfff) << 16), + temp_reg + 4); + writel((1 << 0) | (0 << 16), + temp_reg + 5); + writel((10 << 0) | (14 << 16), + temp_reg + 6); + writel(((-1&0xfff) << 0) | (0 << 16), + temp_reg + 7); + writel(((-14&0xfff) << 0) | ((-20&0xfff) << 16), + temp_reg + 8); + writel((1 << 0) | (0 << 16), + temp_reg + 9); + writel((20 << 0) | (29 << 16), + temp_reg + 10); + writel(((-2&0xfff) << 0) | (0 << 16), + temp_reg + 11); + writel(((-28&0xfff) << 0) | ((-40&0xfff) << 16), + temp_reg + 12); + writel((2 << 0) | (0 << 16), + temp_reg + 13); + writel((40 << 0) | (56 << 16), + temp_reg + 14); + writel(((-3&0xfff) << 0) | (0 << 16), + temp_reg + 15); + writel(((-57&0xfff) << 0) | ((-80&0xfff) << 16), + temp_reg + 16); + writel((5 << 0) | (0 << 16), + temp_reg + 17); + writel((86 << 0) | (121 << 16), + temp_reg + 18); + writel(((-10&0xfff) << 0) | (0 << 16), + temp_reg + 19); + writel(((-154&0xfff) << 0) | ((-212&0xfff) << 16), + temp_reg + 20); + writel((27 << 0) | (0 << 16), + temp_reg + 21); + writel((613 << 0) | (651 << 16), + temp_reg + 22); + writel(((-308&0xfff) << 0) | (1024 << 16), + temp_reg + 23); + } + + break; + + default: + SDPRINTK("invalid out_mode parameter(%d)\n\r", out_mode); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + return SDOUT_NO_ERROR; +} + +/* +* initialization +* - iniization functions are only called under stopping sdout +*/ +enum s5p_tv_sd_err __s5p_sdout_init_display_mode( + enum s5p_tv_disp_mode disp_mode, + enum s5p_tv_o_mode out_mode, + enum s5p_sd_order order) +{ + u32 temp_reg = 0; + + SDPRINTK(" %d, %d, %d\n\r", disp_mode, out_mode, order); + + switch (disp_mode) { + + case TVOUT_NTSC_M: + temp_reg |= SDO_NTSC_M; + __s5p_sdout_init_video_scale_cfg(S5P_TV_SD_LEVEL_0IRE, + SDOUT_VTOS_RATIO_7_3, + S5P_TV_SD_LEVEL_75IRE, + SDOUT_VTOS_RATIO_10_4); + + __s5p_sdout_init_antialias_filter_coeff_default( + S5P_TV_SD_LEVEL_75IRE, + SDOUT_VTOS_RATIO_10_4, + out_mode); + break; + + case TVOUT_PAL_BDGHI: + temp_reg |= SDO_PAL_BGHID; + __s5p_sdout_init_video_scale_cfg(S5P_TV_SD_LEVEL_0IRE, + SDOUT_VTOS_RATIO_7_3, S5P_TV_SD_LEVEL_0IRE, + SDOUT_VTOS_RATIO_7_3); + + __s5p_sdout_init_antialias_filter_coeff_default( + S5P_TV_SD_LEVEL_0IRE, + SDOUT_VTOS_RATIO_7_3, + out_mode); + break; + + case TVOUT_PAL_M: + temp_reg |= SDO_PAL_M; + __s5p_sdout_init_video_scale_cfg(S5P_TV_SD_LEVEL_0IRE, + SDOUT_VTOS_RATIO_7_3, S5P_TV_SD_LEVEL_0IRE, + SDOUT_VTOS_RATIO_7_3); + + __s5p_sdout_init_antialias_filter_coeff_default( + S5P_TV_SD_LEVEL_0IRE, + SDOUT_VTOS_RATIO_7_3, + out_mode); + break; + + case TVOUT_PAL_N: + temp_reg |= SDO_PAL_N; + __s5p_sdout_init_video_scale_cfg(S5P_TV_SD_LEVEL_0IRE, + SDOUT_VTOS_RATIO_7_3, S5P_TV_SD_LEVEL_0IRE, + SDOUT_VTOS_RATIO_7_3); + + __s5p_sdout_init_antialias_filter_coeff_default( + S5P_TV_SD_LEVEL_75IRE, + SDOUT_VTOS_RATIO_10_4, + out_mode); + break; + + case TVOUT_PAL_NC: + temp_reg |= SDO_PAL_NC; + __s5p_sdout_init_video_scale_cfg(S5P_TV_SD_LEVEL_0IRE, + SDOUT_VTOS_RATIO_7_3, S5P_TV_SD_LEVEL_0IRE, + SDOUT_VTOS_RATIO_7_3); + + __s5p_sdout_init_antialias_filter_coeff_default( + S5P_TV_SD_LEVEL_0IRE, + DOUT_VTOS_RATIO_7_3, + ut_mode); + break; + + case TVOUT_PAL_60: + temp_reg |= SDO_PAL_60; + __s5p_sdout_init_video_scale_cfg(S5P_TV_SD_LEVEL_0IRE, + SDOUT_VTOS_RATIO_7_3, S5P_TV_SD_LEVEL_0IRE, + SDOUT_VTOS_RATIO_7_3); + __s5p_sdout_init_antialias_filter_coeff_default( + S5P_TV_SD_LEVEL_0IRE, + SDOUT_VTOS_RATIO_7_3, + out_mode); + break; + + case TVOUT_NTSC_443: + temp_reg |= SDO_NTSC_443; + __s5p_sdout_init_video_scale_cfg(S5P_TV_SD_LEVEL_0IRE, + SDOUT_VTOS_RATIO_7_3, S5P_TV_SD_LEVEL_75IRE, + SDOUT_VTOS_RATIO_10_4); + __s5p_sdout_init_antialias_filter_coeff_default( + S5P_TV_SD_LEVEL_75IRE, + SDOUT_VTOS_RATIO_10_4, + out_mode); + break; + + default: + SDPRINTK("invalid disp_mode parameter(%d)\n\r", disp_mode); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + switch (out_mode) { + + case TVOUT_OUTPUT_COMPOSITE: + + case TVOUT_OUTPUT_SVIDEO: + temp_reg |= SDO_COMPOSITE | SDO_INTERLACED; + + switch (order) { + + case S5P_TV_SD_O_ORDER_COMPOSITE_CVBS_Y_C: + temp_reg |= SDO_DAC2_CVBS | SDO_DAC1_Y | SDO_DAC0_C; + break; + + case S5P_TV_SD_O_ORDER_COMPOSITE_CVBS_C_Y: + temp_reg |= SDO_DAC2_CVBS | SDO_DAC1_C | SDO_DAC0_Y; + break; + + case S5P_TV_SD_O_ORDER_COMPOSITE_Y_C_CVBS: + temp_reg |= SDO_DAC2_Y | SDO_DAC1_C | SDO_DAC0_CVBS; + break; + + case S5P_TV_SD_O_ORDER_COMPOSITE_Y_CVBS_C: + temp_reg |= SDO_DAC2_Y | SDO_DAC1_CVBS | SDO_DAC0_C; + break; + + case S5P_TV_SD_O_ORDER_COMPOSITE_C_CVBS_Y: + temp_reg |= SDO_DAC2_C | SDO_DAC1_CVBS | SDO_DAC0_Y; + break; + + case S5P_TV_SD_O_ORDER_COMPOSITE_C_Y_CVBS: + temp_reg |= SDO_DAC2_C | SDO_DAC1_Y | SDO_DAC0_CVBS; + break; + + default: + SDPRINTK(" invalid order parameter(%d)\n\r", order); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + break; + + case TVOUT_OUTPUT_COMPONENT_YPBPR_INERLACED: + temp_reg |= SDO_COMPONENT | SDO_YPBPR | SDO_INTERLACED; + + switch (order) { + + case S5P_TV_SD_O_ORDER_COMPONENT_RGB_PRYPB: + temp_reg |= SDO_DAC2_PR_R | SDO_DAC1_Y_G | + SDO_DAC0_PB_B; + break; + + case S5P_TV_SD_O_ORDER_COMPONENT_RBG_PRPBY: + temp_reg |= SDO_DAC2_PR_R | SDO_DAC1_PB_B | + SDO_DAC0_Y_G; + break; + + case S5P_TV_SD_O_ORDER_COMPONENT_BGR_PBYPR: + temp_reg |= SDO_DAC2_PB_B | SDO_DAC1_Y_G | + SDO_DAC0_PR_R; + break; + + case S5P_TV_SD_O_ORDER_COMPONENT_BRG_PBPRY: + temp_reg |= SDO_DAC2_PB_B | SDO_DAC1_PR_R | + SDO_DAC0_Y_G; + break; + + case S5P_TV_SD_O_ORDER_COMPONENT_GRB_YPRPB: + temp_reg |= SDO_DAC2_Y_G | SDO_DAC1_PR_R | + SDO_DAC0_PB_B; + break; + + case S5P_TV_SD_O_ORDER_COMPONENT_GBR_YPBPR: + temp_reg |= SDO_DAC2_Y_G | SDO_DAC1_PB_B | + SDO_DAC0_PR_R; + break; + + default: + SDPRINTK(" invalid order parameter(%d)\n\r", order); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + break; + + case TVOUT_OUTPUT_COMPONENT_YPBPR_PROGRESSIVE: + temp_reg |= SDO_COMPONENT | SDO_YPBPR | SDO_PROGRESSIVE; + + switch (order) { + + case S5P_TV_SD_O_ORDER_COMPONENT_RGB_PRYPB: + temp_reg |= SDO_DAC2_PR_R | SDO_DAC1_Y_G | + SDO_DAC0_PB_B; + break; + + case S5P_TV_SD_O_ORDER_COMPONENT_RBG_PRPBY: + temp_reg |= SDO_DAC2_PR_R | SDO_DAC1_PB_B | + SDO_DAC0_Y_G; + break; + + case S5P_TV_SD_O_ORDER_COMPONENT_BGR_PBYPR: + temp_reg |= SDO_DAC2_PB_B | SDO_DAC1_Y_G | + SDO_DAC0_PR_R; + break; + + case S5P_TV_SD_O_ORDER_COMPONENT_BRG_PBPRY: + temp_reg |= SDO_DAC2_PB_B | SDO_DAC1_PR_R | + SDO_DAC0_Y_G; + break; + + case S5P_TV_SD_O_ORDER_COMPONENT_GRB_YPRPB: + temp_reg |= SDO_DAC2_Y_G | SDO_DAC1_PR_R | + SDO_DAC0_PB_B; + break; + + case S5P_TV_SD_O_ORDER_COMPONENT_GBR_YPBPR: + temp_reg |= SDO_DAC2_Y_G | SDO_DAC1_PB_B | + SDO_DAC0_PR_R; + break; + + default: + SDPRINTK(" invalid order parameter(%d)\n\r", order); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + break; + + case TVOUT_OUTPUT_COMPONENT_RGB_PROGRESSIVE: + temp_reg |= SDO_COMPONENT | SDO_RGB | SDO_PROGRESSIVE; + + switch (order) { + + case S5P_TV_SD_O_ORDER_COMPONENT_RGB_PRYPB: + temp_reg |= SDO_DAC2_PR_R | SDO_DAC1_Y_G | + SDO_DAC0_PB_B; + break; + + case S5P_TV_SD_O_ORDER_COMPONENT_RBG_PRPBY: + temp_reg |= SDO_DAC2_PR_R | SDO_DAC1_PB_B | + SDO_DAC0_Y_G; + break; + + case S5P_TV_SD_O_ORDER_COMPONENT_BGR_PBYPR: + temp_reg |= SDO_DAC2_PB_B | SDO_DAC1_Y_G | + SDO_DAC0_PR_R; + break; + + case S5P_TV_SD_O_ORDER_COMPONENT_BRG_PBPRY: + temp_reg |= SDO_DAC2_PB_B | SDO_DAC1_PR_R | + SDO_DAC0_Y_G; + break; + + case S5P_TV_SD_O_ORDER_COMPONENT_GRB_YPRPB: + temp_reg |= SDO_DAC2_Y_G | SDO_DAC1_PR_R | + SDO_DAC0_PB_B; + break; + + case S5P_TV_SD_O_ORDER_COMPONENT_GBR_YPBPR: + temp_reg |= SDO_DAC2_Y_G | SDO_DAC1_PB_B | + SDO_DAC0_PR_R; + break; + + default: + SDPRINTK("invalid order parameter(%d)\n\r", order); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + break; + + default: + SDPRINTK(" invalid out_mode parameter(%d)\n\r", out_mode); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + __s5p_sdout_init_oversampling_filter_coeff_default(out_mode); + + writel(temp_reg, sdout_base + S5P_SDO_CONFIG); + + SDPRINTK("0x%08x\n\r", readl(sdout_base + S5P_SDO_CONFIG)); + + return SDOUT_NO_ERROR; +} + +/* +* start - start functions are only called under stopping SDOUT +*/ +void __s5p_sdout_start(void) +{ + SDPRINTK("()\n\r"); + + writel(SDO_TVOUT_CLOCK_ON, sdout_base + S5P_SDO_CLKCON); + + SDPRINTK("0x%x\n\r", readl(sdout_base + S5P_SDO_CLKCON)); +} + +/* +/ stop - stop functions are only called under running SDOUT +*/ +void __s5p_sdout_stop(void) +{ + SDPRINTK("()\n\r"); + + writel(SDO_TVOUT_CLOCK_OFF, sdout_base + S5P_SDO_CLKCON); + + SDPRINTK(" 0x%x)\n\r", readl(sdout_base + S5P_SDO_CLKCON)); +} + +/* +* reset +* - reset function +*/ +void __s5p_sdout_sw_reset(bool active) +{ + SDPRINTK("%d\n\r", active); + + if (active) + writel(readl(sdout_base + S5P_SDO_CLKCON) | SDO_TVOUT_SW_RESET, + sdout_base + S5P_SDO_CLKCON); + else + writel(readl(sdout_base + S5P_SDO_CLKCON) & ~SDO_TVOUT_SW_RESET, + sdout_base + S5P_SDO_CLKCON); + + SDPRINTK(" 0x%x\n\r", readl(sdout_base + S5P_SDO_CLKCON)); +} + + +void __s5p_sdout_set_interrupt_enable(bool vsync_intr_en) +{ + SDPRINTK("%d)\n\r", vsync_intr_en); + + if (vsync_intr_en) + writel(readl(sdout_base + S5P_SDO_IRQMASK) & + ~SDO_VSYNC_IRQ_DISABLE, + sdout_base + S5P_SDO_IRQMASK); + else + writel(readl(sdout_base + S5P_SDO_IRQMASK) | + SDO_VSYNC_IRQ_DISABLE, + sdout_base + S5P_SDO_IRQMASK); + + SDPRINTK("0x%x)\n\r", readl(sdout_base + S5P_SDO_IRQMASK)); +} + +void __s5p_sdout_clear_interrupt_pending(void) +{ + SDPRINTK("0x%x\n\r", readl(sdout_base + S5P_SDO_IRQ)); + + writel(readl(sdout_base + S5P_SDO_IRQ) | SDO_VSYNC_IRQ_PEND, + sdout_base + S5P_SDO_IRQ); + + SDPRINTK("0x%x\n\r", readl(sdout_base + S5P_SDO_IRQ)); +} + +bool __s5p_sdout_get_interrupt_pending(void) +{ + SDPRINTK(" 0x%x\n\r", readl(sdout_base + S5P_SDO_IRQ)); + + return (readl(sdout_base + S5P_SDO_IRQ) | + SDO_VSYNC_IRQ_PEND) ? 1 : 0; +} + +int __init __s5p_sdout_probe(struct platform_device *pdev, u32 res_num) +{ + + struct resource *res; + size_t size; + int ret; + + res = platform_get_resource(pdev, IORESOURCE_MEM, res_num); + + if (res == NULL) { + dev_err(&pdev->dev, + "failed to get memory region resource\n"); + ret = -ENOENT; + } + + size = (res->end - res->start) + 1; + + sdout_mem = request_mem_region(res->start, size, pdev->name); + + if (sdout_mem == NULL) { + dev_err(&pdev->dev, + "failed to get memory region\n"); + ret = -ENOENT; + } + + sdout_base = ioremap(res->start, size); + + if (sdout_base == NULL) { + dev_err(&pdev->dev, + "failed to ioremap address region\n"); + ret = -ENOENT; + + } + + return ret; + +} + +int __init __s5p_sdout_release(struct platform_device *pdev) +{ + iounmap(sdout_base); + + /* remove memory region */ + + if (sdout_mem != NULL) { + if (release_resource(sdout_mem)) + dev_err(&pdev->dev, + "Can't remove tvout drv !!\n"); + + kfree(sdout_mem); + + sdout_mem = NULL; + } + + return 0; +} diff --git a/drivers/media/video/samsung/tv20/s5pc100/tv_clock_s5pc100.c b/drivers/media/video/samsung/tv20/s5pc100/tv_clock_s5pc100.c new file mode 100644 index 0000000..63f565a --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5pc100/tv_clock_s5pc100.c @@ -0,0 +1,406 @@ +/* linux/drivers/media/video/samsung/tv20/s5pc100/tv_clock_s5pc100.c + * + * clock raw ftn file for Samsung TVOut driver + * + * Copyright (c) 2009 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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/delay.h> +#include <linux/platform_device.h> +#include <linux/clk.h> + +#include <linux/uaccess.h> +#include <linux/io.h> + +#include <plat/map.h> +#include <plat/regs-clock.h> + +#include "tv_out_s5pc100.h" +#include "regs/regs-clock_extra.h" + +#ifdef COFIG_TVOUT_RAW_DBG +#define S5P_TVOUT_CLK_DEBUG 1 +#endif + +#ifdef S5P_TVOUT_CLK_DEBUG +#define TVCLKPRINTK(fmt, args...) \ + printk(KERN_INFO "\t\t[TVCLK] %s: " fmt, __func__ , ## args) +#else +#define TVCLKPRINTK(fmt, args...) +#endif + +static struct resource *tvclk_mem; +void __iomem *tvclk_base; + +/* +* initialization +* - iniization functions are only called under stopping tvout clock +*/ + +void __s5p_tv_clk_init_hpll(unsigned int lock_time, + unsigned int mdiv, + unsigned int pdiv, + unsigned int sdiv) +{ + TVCLKPRINTK("%d,%d,%d,%d\n\r", lock_time, mdiv, pdiv, sdiv); + + writel(HPLL_LOCKTIME(lock_time), S5P_HPLL_LOCK); + writel(MDIV(mdiv) | PDIV(pdiv) | SDIV(sdiv), S5P_HPLL_CON); + + TVCLKPRINTK("0x%08x,0x%08x\n\r", readl(S5P_HPLL_LOCK), + readl(S5P_HPLL_CON)); +} + +void __s5p_tv_clk_hpll_onoff(bool en) +{ + TVCLKPRINTK("%d\n\r", en); + + if (en) { + writel(readl(S5P_HPLL_CON) | HPLL_ENABLE, S5P_HPLL_CON) ; + + while (!HPLL_LOCKED(readl(S5P_HPLL_CON))) + msleep(1); + + } else + writel(readl(S5P_HPLL_CON) & ~HPLL_ENABLE, S5P_HPLL_CON); + + + TVCLKPRINTK("0x%08x,0x%08x\n\r", readl(S5P_HPLL_LOCK), + readl(S5P_HPLL_CON)); +} + +enum s5p_tv_clk_err __s5p_tv_clk_init_href(enum s5p_tv_clk_hpll_ref hpll_ref) +{ + TVCLKPRINTK("(%d)\n\r", hpll_ref); + + switch (hpll_ref) { + + case S5P_TV_CLK_HPLL_REF_27M: + writel(readl(S5P_CLK_SRC0) & HREF_SEL_MASK, S5P_CLK_SRC0); + break; + + case S5P_TV_CLK_HPLL_REF_SRCLK: + writel(readl(S5P_CLK_SRC0) | HREF_SEL_SRCLK, S5P_CLK_SRC0); + break; + + default: + TVCLKPRINTK("invalid hpll_ref parameter = %d\n\r", hpll_ref); + return S5P_TV_CLK_ERR_INVALID_PARAM; + break; + } + + TVCLKPRINTK("(0x%08x)\n\r", readl(S5P_CLK_SRC0)); + + return S5P_TV_CLK_ERR_NO_ERROR; +} + +enum s5p_tv_clk_err __s5p_tv_clk_init_mout_hpll( + enum s5p_tv_clk_mout_hpll mout_hpll) +{ + TVCLKPRINTK("(%d)\n\r", mout_hpll); + + switch (mout_hpll) { + + case S5P_TV_CLK_MOUT_HPLL_27M: + writel(readl(S5P_CLK_SRC0) & HPLL_SEL_MASK, S5P_CLK_SRC0); + break; + + case S5P_TV_CLK_MOUT_HPLL_FOUT_HPLL: + writel(readl(S5P_CLK_SRC0) | HPLL_SEL_FOUT_HPLL, S5P_CLK_SRC0); + break; + + default: + TVCLKPRINTK(" invalid mout_hpll parameter = %d\n\r", + mout_hpll); + return S5P_TV_CLK_ERR_INVALID_PARAM; + break; + } + + TVCLKPRINTK("(0x%08x)\n\r", readl(S5P_CLK_SRC0)); + + return S5P_TV_CLK_ERR_NO_ERROR; +} + +enum s5p_tv_clk_err __s5p_tv_clk_init_video_mixer( + enum s5p_tv_clk_vmiexr_srcclk src_clk) +{ + TVCLKPRINTK("(%d)\n\r", src_clk); + + switch (src_clk) { + + case TVOUT_CLK_VMIXER_SRCCLK_CLK27M: + writel(((readl(S5P_CLK_SRC2) & VMIXER_SEL_MASK) | + VMIXER_SEL_CLK27M), S5P_CLK_SRC2); + break; + + case TVOUT_CLK_VMIXER_SRCCLK_VCLK_54: + writel(((readl(S5P_CLK_SRC2) & VMIXER_SEL_MASK) | + VMIXER_SEL_VCLK_54), S5P_CLK_SRC2); + break; + + case TVOUT_CLK_VMIXER_SRCCLK_MOUT_HPLL: + writel(((readl(S5P_CLK_SRC2) & VMIXER_SEL_MASK) | + VMIXER_SEL_MOUT_HPLL), S5P_CLK_SRC2); + break; + + default: + TVCLKPRINTK("invalid src_clk parameter = %d\n\r", src_clk); + return S5P_TV_CLK_ERR_INVALID_PARAM; + break; + } + + TVCLKPRINTK("(0x%08x)\n\r", readl(S5P_CLK_SRC2)); + + return S5P_TV_CLK_ERR_NO_ERROR; +} + +void __s5p_tv_clk_init_hdmi_ratio(unsigned int clk_div) +{ + TVCLKPRINTK("(%d)\n\r", clk_div); + + writel((readl(S5P_CLK_DIV3) & HDMI_DIV_RATIO_MASK) | + HDMI_DIV_RATIO(clk_div), S5P_CLK_DIV3); + + TVCLKPRINTK("(0x%08x)\n\r", readl(S5P_CLK_DIV3)); +} + +/* +* set +* - set functions are only called under running tvout clock +*/ +void __s5p_tv_clk_set_vp_clk_onoff(bool clk_on) +{ + TVCLKPRINTK("(%d)\n\r", clk_on); + + if (clk_on) + writel(readl(S5P_CLKGATE_D12) | CLK_HCLK_VP_PASS, + S5P_CLKGATE_D12); + else + writel(readl(S5P_CLKGATE_D12) & ~CLK_HCLK_VP_PASS, + S5P_CLKGATE_D12); + + + TVCLKPRINTK("(0x%08x)\n\r", readl(S5P_CLKGATE_D12)); +} + +void __s5p_tv_clk_set_vmixer_hclk_onoff(bool clk_on) +{ + TVCLKPRINTK("(%d)\n\r", clk_on); + + if (clk_on) + writel(readl(S5P_CLKGATE_D12) | CLK_HCLK_VMIXER_PASS, + S5P_CLKGATE_D12); + else + writel(readl(S5P_CLKGATE_D12) & ~CLK_HCLK_VMIXER_PASS, + S5P_CLKGATE_D12); + + + TVCLKPRINTK("(0x%08x)\n\r", readl(S5P_CLKGATE_D12)); +} + +void __s5p_tv_clk_set_vmixer_sclk_onoff(bool clk_on) +{ + TVCLKPRINTK("(%d)\n\r", clk_on); + + if (clk_on) + writel(readl(S5P_SCLKGATE1) | CLK_SCLK_VMIXER_PASS, + S5P_SCLKGATE1); + else + writel(readl(S5P_SCLKGATE1) & ~CLK_SCLK_VMIXER_PASS, + S5P_SCLKGATE1); + + + TVCLKPRINTK("(0x%08x)\n\r", readl(S5P_SCLKGATE1)); +} + +void __s5p_tv_clk_set_sdout_hclk_onoff(bool clk_on) +{ + TVCLKPRINTK("(%d)\n\r", clk_on); + + if (clk_on) { + writel((readl(S5P_CLKGATE_D12) | CLK_HCLK_SDOUT_PASS), + S5P_CLKGATE_D12); + writel(readl(tvclk_base + 0x304) | VMIXER_OUT_SEL_SDOUT, + tvclk_base + 0x304); + } else + writel((readl(S5P_CLKGATE_D12) & ~CLK_HCLK_SDOUT_PASS), + S5P_CLKGATE_D12); + + + + TVCLKPRINTK("physical %p (0x%08x)\n\r", tvclk_base, + readl(tvclk_base + 0x304)); + + TVCLKPRINTK("after (0x%08x)\n\r", readl(S5P_CLKGATE_D12)); +} + +void __s5p_tv_clk_set_sdout_sclk_onoff(bool clk_on) +{ + TVCLKPRINTK("(%d)\n\r", clk_on); + + if (clk_on) + writel((readl(S5P_SCLKGATE1) | CLK_SCLK_TV54_PASS | + CLK_SCLK_VDAC54_PASS), + S5P_SCLKGATE1); + else + writel((readl(S5P_SCLKGATE1) & (~CLK_SCLK_TV54_PASS & + ~CLK_SCLK_VDAC54_PASS)), + S5P_SCLKGATE1); + + + TVCLKPRINTK("(0x%08x)\n\r", readl(S5P_SCLKGATE1)); +} + +void __s5p_tv_clk_set_hdmi_hclk_onoff(bool clk_on) +{ + TVCLKPRINTK("(%d)\n\r", clk_on); + + if (clk_on) { + writel((readl(S5P_CLKGATE_D12) | CLK_HCLK_HDMI_PASS), + S5P_CLKGATE_D12); + writel(readl(tvclk_base + 0x304) | VMIXER_OUT_SEL_HDMI, + tvclk_base + 0x304); + } else + writel((readl(S5P_CLKGATE_D12) & ~CLK_HCLK_HDMI_PASS), + S5P_CLKGATE_D12) ; + + + TVCLKPRINTK("physical %p (0x%08x)\n\r", tvclk_base, + readl(tvclk_base + 0x304)); + + TVCLKPRINTK("after (0x%08x)\n\r", readl(S5P_CLKGATE_D12)); +} + +void __s5p_tv_clk_set_hdmi_sclk_onoff(bool clk_on) +{ + TVCLKPRINTK("(%d)\n\r", clk_on); + + if (clk_on) + writel((readl(S5P_SCLKGATE1) | CLK_SCLK_HDMI_PASS), + S5P_SCLKGATE1); + else + writel((readl(S5P_SCLKGATE1) & ~CLK_SCLK_HDMI_PASS), + S5P_SCLKGATE1); + + + TVCLKPRINTK("(0x%08x)\n\r", readl(S5P_SCLKGATE1)); +} + +void __s5p_tv_clk_set_hdmi_i2c_clk_onoff(bool clk_on) +{ + TVCLKPRINTK("(%d)\n\r", clk_on); + + if (clk_on) + writel((readl(S5P_CLKGATE_D14) | CLK_PCLK_IIC_HDMI_PASS), + S5P_CLKGATE_D14); + else + writel((readl(S5P_CLKGATE_D14) & ~CLK_PCLK_IIC_HDMI_PASS), + S5P_CLKGATE_D14); + + + TVCLKPRINTK("(0x%08x)\n\r", readl(S5P_CLKGATE_D14)); +} + +/* +* start +* - start functions are only called under stopping tvout clock +*/ +void __s5p_tv_clk_start(bool vp_hclk_on, + bool sdout_hclk_on, + bool hdmi_hclk_on) +{ + TVCLKPRINTK("(%d,%d,%d)\n\r", vp_hclk_on, sdout_hclk_on, hdmi_hclk_on); + + __s5p_tv_clk_set_vp_clk_onoff(vp_hclk_on); + __s5p_tv_clk_set_sdout_hclk_onoff(sdout_hclk_on); + __s5p_tv_clk_set_sdout_sclk_onoff(sdout_hclk_on); + __s5p_tv_clk_set_hdmi_hclk_onoff(hdmi_hclk_on); + __s5p_tv_clk_set_vmixer_hclk_onoff(true); + __s5p_tv_clk_set_vmixer_sclk_onoff(true); + + if (hdmi_hclk_on) + __s5p_tv_clk_hpll_onoff(true); + +} + + +/* +* stop +* - stop functions are only called under running tvout clock +*/ +void __s5p_tv_clk_stop(void) +{ + __s5p_tv_clk_set_sdout_sclk_onoff(false); + __s5p_tv_clk_set_sdout_hclk_onoff(false); + __s5p_tv_clk_set_hdmi_sclk_onoff(false); + __s5p_tv_clk_set_hdmi_hclk_onoff(false); + __s5p_tv_clk_set_vp_clk_onoff(false); + __s5p_tv_clk_set_vmixer_sclk_onoff(false); + __s5p_tv_clk_set_vmixer_hclk_onoff(false); + __s5p_tv_clk_hpll_onoff(false); +} + +int __init __s5p_tvclk_probe(struct platform_device *pdev, u32 res_num) +{ + + struct resource *res; + size_t size; + int ret; + + res = platform_get_resource(pdev, IORESOURCE_MEM, res_num); + + if (res == NULL) { + dev_err(&pdev->dev, + "failed to get memory region resource\n"); + ret = -ENOENT; + + } + + size = (res->end - res->start) + 1; + + tvclk_mem = request_mem_region(res->start, size, pdev->name); + + if (tvclk_mem == NULL) { + dev_err(&pdev->dev, + "failed to get memory region\n"); + ret = -ENOENT; + + } + + tvclk_base = ioremap(res->start, size); + + if (tvclk_base == NULL) { + dev_err(&pdev->dev, + "failed to ioremap address region\n"); + ret = -ENOENT; + + } + + return ret; +} + +int __init __s5p_tvclk_release(struct platform_device *pdev) +{ + iounmap(tvclk_base); + + /* remove memory region */ + + if (tvclk_mem != NULL) { + if (release_resource(tvclk_mem)) + dev_err(&pdev->dev, + "Can't remove tvout drv !!\n"); + + kfree(tvclk_mem); + + tvclk_mem = NULL; + } + + return 0; +} diff --git a/drivers/media/video/samsung/tv20/s5pc100/tv_out_s5pc100.h b/drivers/media/video/samsung/tv20/s5pc100/tv_out_s5pc100.h new file mode 100644 index 0000000..19349be --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5pc100/tv_out_s5pc100.h @@ -0,0 +1,486 @@ +/* linux/drivers/media/video/samsung/tv20/s5pc100/tv_out_s5pc100.h + * + * tv out header file for Samsung TVOut driver + * + * Copyright (c) 2009 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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. +*/ +/*#define COFIG_TVOUT_RAW_DBG */ + + +#define HDMI_START_NUM 0x1000 + +enum s5p_tv_audio_codec_type { + PCM = 1, AC3, MP3, WMA +}; + +enum s5p_endian_type { + TVOUT_LITTLE_ENDIAN_MODE = 0, + TVOUT_BIG_ENDIAN_MODE = 1 +}; + +enum s5p_tv_disp_mode { + TVOUT_NTSC_M = 0, + TVOUT_PAL_BDGHI, + TVOUT_PAL_M, + TVOUT_PAL_N, + TVOUT_PAL_NC, + TVOUT_PAL_60, + TVOUT_NTSC_443, + TVOUT_480P_60_16_9 = HDMI_START_NUM, + TVOUT_480P_60_4_3, + TVOUT_576P_50_16_9, + TVOUT_576P_50_4_3, + TVOUT_720P_60, + TVOUT_720P_50 +}; + +enum s5p_tv_o_mode { + TVOUT_OUTPUT_COMPOSITE, + TVOUT_OUTPUT_SVIDEO, + TVOUT_OUTPUT_COMPONENT_YPBPR_INERLACED, + TVOUT_OUTPUT_COMPONENT_YPBPR_PROGRESSIVE, + TVOUT_OUTPUT_COMPONENT_RGB_PROGRESSIVE, + TVOUT_OUTPUT_HDMI, + TVOUT_OUTPUT_HDMI_RGB, + TVOUT_OUTPUT_DVI +}; + +enum s5p_tv_pwr_err { + S5P_TV_PWR_ERR_NO_ERROR = 0, + S5P_TV_PWR_ERR_NOT_INIT_PARAMETERS_UNDER_RUNNING = 0x5000, + S5P_TV_PWR_ERR_NOT_SET_PARAMETERS_UNDER_STOP, + S5P_TV_PWR_ERR_INVALID_PARAM +}; + +enum s5p_tv_clk_err { + S5P_TV_CLK_ERR_NO_ERROR = 0, + S5P_TV_CLK_ERR_NOT_INIT_PARAMETERS_UNDER_RUNNING = 0x4000, + S5P_TV_CLK_ERR_NOT_SET_PARAMETERS_UNDER_STOP, + S5P_TV_CLK_ERR_INVALID_PARAM +}; + +enum s5p_tv_vp_err { + VPROC_NO_ERROR = 0, + S5P_TV_VP_ERR_NOT_INIT_PARAMETERS_UNDER_RUNNING = 0x2000, + S5P_TV_VP_ERR_NOT_SET_PARAMETERS_UNDER_STOP, + S5P_TV_VP_ERR_BASE_ADDRESS_MUST_DOUBLE_WORD_ALIGN, + S5P_TV_VP_ERR_NOT_UPDATE_FOR_ANOTHER_UPDATE, + S5P_TV_VP_ERR_INVALID_PARAM +}; + +enum s5p_tv_vmx_err { + VMIXER_NO_ERROR = 0, + S5P_TV_VMX_ERR_NOT_INIT_PARAMETERS_UNDER_RUNNING = 0x1000, + S5P_TV_VMX_ERR_NOT_SET_PARAMETERS_UNDER_STOP, + S5P_TV_VMX_ERR_BASE_ADDRESS_MUST_WORD_ALIGN, + S5P_TV_VMX_ERR_INVALID_PARAM +}; + +enum s5p_tv_vmx_color_fmt { + VM_DIRECT_RGB565 = 4, + VM_DIRECT_RGB1555 = 5, + VM_DIRECT_RGB4444 = 6, + VM_DIRECT_RGB8888 = 7 +}; + +enum s5p_tv_sd_err { + SDOUT_NO_ERROR = 0, + S5P_TV_SD_ERR_NOT_INIT_PARAMETERS_UNDER_RUNNING = 0x3000, + S5P_TV_SD_ERR_NOT_SET_PARAMETERS_UNDER_STOP, + S5P_TV_SD_ERR_INVALID_PARAM +}; + +enum s5p_sd_order { + S5P_TV_SD_O_ORDER_COMPONENT_RGB_PRYPB, + S5P_TV_SD_O_ORDER_COMPONENT_RBG_PRPBY, + S5P_TV_SD_O_ORDER_COMPONENT_BGR_PBYPR, + S5P_TV_SD_O_ORDER_COMPONENT_BRG_PBPRY, + S5P_TV_SD_O_ORDER_COMPONENT_GRB_YPRPB, + S5P_TV_SD_O_ORDER_COMPONENT_GBR_YPBPR, + S5P_TV_SD_O_ORDER_COMPOSITE_CVBS_Y_C, + S5P_TV_SD_O_ORDER_COMPOSITE_CVBS_C_Y, + S5P_TV_SD_O_ORDER_COMPOSITE_Y_C_CVBS, + S5P_TV_SD_O_ORDER_COMPOSITE_Y_CVBS_C, + S5P_TV_SD_O_ORDER_COMPOSITE_C_CVBS_Y, + S5P_TV_SD_O_ORDER_COMPOSITE_C_Y_CVBS +}; + +enum s5p_tv_hdmi_err { + HDMI_NO_ERROR = 0, + S5P_TV_HDMI_ERR_NOT_INIT_PARAMETERS_UNDER_RUNNING = 0x6000, + S5P_TV_HDMI_ERR_NOT_SET_PARAMETERS_UNDER_STOP, + S5P_TV_HDMI_ERR_INVALID_PARAM +}; + +enum s5p_hdmi_transmit { + HDMI_DO_NOT_TANS = 0, + HDMI_TRANS_ONCE, + HDMI_TRANS_EVERY_SYNC +}; + +enum s5p_hdmi_audio_type { + HDMI_AUDIO_NO, + HDMI_AUDIO_PCM +}; + + +enum s5p_tv_stda_err { + STDA_NO_ERROR = 0, + S5P_TV_STDA_ERR_NOT_INIT_PARAMETERS_UNDER_RUNNING = 0x7000, + S5P_TV_STDA_ERR_NOT_SET_PARAMETERS_UNDER_STOP, + S5P_TV_STDA_ERR_INVALID_PARAM +}; + + +/* +* enum +*/ + +enum s5p_tv_active_polarity { + TVOUT_POL_ACTIVE_LOW, + TVOUT_POL_ACTIVE_HIGH +}; + +enum s5p_yuv_fmt_component { + TVOUT_YUV_Y, + TVOUT_YUV_CB, + TVOUT_YUV_CR +}; + +enum s5p_tv_clk_hpll_ref { + S5P_TV_CLK_HPLL_REF_27M, + S5P_TV_CLK_HPLL_REF_SRCLK +}; + +enum s5p_tv_clk_mout_hpll { + S5P_TV_CLK_MOUT_HPLL_27M, + S5P_TV_CLK_MOUT_HPLL_FOUT_HPLL +}; + +enum s5p_tv_clk_vmiexr_srcclk { + TVOUT_CLK_VMIXER_SRCCLK_CLK27M, + TVOUT_CLK_VMIXER_SRCCLK_VCLK_54, + TVOUT_CLK_VMIXER_SRCCLK_MOUT_HPLL +}; + +enum s5p_vp_src_color { + VPROC_SRC_COLOR_NV12 = 0, + VPROC_SRC_COLOR_NV12IW = 1, + VPROC_SRC_COLOR_TILE_NV12 = 2, + VPROC_SRC_COLOR_TILE_NV12IW = 3 +}; + +enum s5p_vp_pxl_rate { + VPROC_PIXEL_PER_RATE_1_1 = 0, + VPROC_PIXEL_PER_RATE_1_2 = 1, + VPROC_PIXEL_PER_RATE_1_3 = 2, + VPROC_PIXEL_PER_RATE_1_4 = 3 +}; + +enum s5p_vp_sharpness_control { + VPROC_SHARPNESS_NO = 0, + VPROC_SHARPNESS_MIN = 1, + VPROC_SHARPNESS_MOD = 2, + VPROC_SHARPNESS_MAX = 3 +}; + +enum s5p_vp_line_eq { + VProc_LINE_EQ_0 = 0, + VProc_LINE_EQ_1 = 1, + VProc_LINE_EQ_2 = 2, + VProc_LINE_EQ_3 = 3, + VProc_LINE_EQ_4 = 4, + VProc_LINE_EQ_5 = 5, + VProc_LINE_EQ_6 = 6, + VProc_LINE_EQ_7 = 7 +}; + +enum s5p_vp_mem_mode { + VPROC_LINEAR_MODE, + VPROC_2D_TILE_MODE +}; + +enum s5p_vp_chroma_expansion { + VPROC_USING_C_TOP, + VPROC_USING_C_TOP_BOTTOM +}; + +enum s5p_vp_filed_id_toggle { + S5P_TV_VP_FILED_ID_TOGGLE_USER, + S5P_TV_VP_FILED_ID_TOGGLE_VSYNC +}; + +enum s5p_vp_field { + VPROC_TOP_FIELD, + VPROC_BOTTOM_FIELD +}; + +enum s5p_vp_poly_coeff { + VPROC_POLY8_Y0_LL = 0, + VPROC_POLY8_Y0_LH, + VPROC_POLY8_Y0_HL, + VPROC_POLY8_Y0_HH, + VPROC_POLY8_Y1_LL, + VPROC_POLY8_Y1_LH, + VPROC_POLY8_Y1_HL, + VPROC_POLY8_Y1_HH, + VPROC_POLY8_Y2_LL, + VPROC_POLY8_Y2_LH, + VPROC_POLY8_Y2_HL, + VPROC_POLY8_Y2_HH, + VPROC_POLY8_Y3_LL, + VPROC_POLY8_Y3_LH, + VPROC_POLY8_Y3_HL, + VPROC_POLY8_Y3_HH, + VPROC_POLY4_Y0_LL = 32, + VPROC_POLY4_Y0_LH, + VPROC_POLY4_Y0_HL, + VPROC_POLY4_Y0_HH, + VPROC_POLY4_Y1_LL, + VPROC_POLY4_Y1_LH, + VPROC_POLY4_Y1_HL, + VPROC_POLY4_Y1_HH, + VPROC_POLY4_Y2_LL, + VPROC_POLY4_Y2_LH, + VPROC_POLY4_Y2_HL, + VPROC_POLY4_Y2_HH, + VPROC_POLY4_Y3_LL, + VPROC_POLY4_Y3_LH, + VPROC_POLY4_Y3_HL, + VPROC_POLY4_Y3_HH, + VPROC_POLY4_C0_LL, + VPROC_POLY4_C0_LH, + VPROC_POLY4_C0_HL, + VPROC_POLY4_C0_HH, + VPROC_POLY4_C1_LL, + VPROC_POLY4_C1_LH, + VPROC_POLY4_C1_HL, + VPROC_POLY4_C1_HH +}; + +enum s5p_vp_csc_coeff { + VPROC_CSC_Y2Y_COEF = 0, + VPROC_CSC_CB2Y_COEF, + VPROC_CSC_CR2Y_COEF, + VPROC_CSC_Y2CB_COEF, + VPROC_CSC_CB2CB_COEF, + VPROC_CSC_CR2CB_COEF, + VPROC_CSC_Y2CR_COEF, + VPROC_CSC_CB2CR_COEF, + VPROC_CSC_CR2CR_COEF +}; + +enum s5p_vp_csc_type { + VPROC_CSC_SD_HD, + VPROC_CSC_HD_SD +}; + +enum s5p_tv_vp_filter_h_pp { + /* Don't change the order and the value */ + VPROC_PP_H_NORMAL = 0, + VPROC_PP_H_8_9, /* 720 to 640 */ + VPROC_PP_H_1_2, + VPROC_PP_H_1_3, + VPROC_PP_H_1_4 +}; + +enum s5p_tv_vp_filter_v_pp { + /* Don't change the order and the value */ + VPROC_PP_V_NORMAL = 0, + VPROC_PP_V_5_6, /* PAL to NTSC */ + VPROC_PP_V_3_4, + VPROC_PP_V_1_2, + VPROC_PP_V_1_3, + VPROC_PP_V_1_4 +}; + +enum s5p_vmx_burst_mode { + VM_BURST_8 = 0, + VM_BURST_16 = 1 +}; + +enum s5p_tv_vmx_scan_mode { + VMIXER_INTERLACED_MODE = 0, + VMIXER_PROGRESSIVE_MODE = 1 +}; + +enum s5p_tv_vmx_layer { + VM_VIDEO_LAYER = 2, + VM_GPR0_LAYER = 0, + VM_GPR1_LAYER = 1 +}; + +enum s5p_tv_vmx_bg_color_num { + VMIXER_BG_COLOR_0 = 0, + VMIXER_BG_COLOR_1 = 1, + VMIXER_BG_COLOR_2 = 2 +}; + +enum s5p_tv_coef_y_mode { + VMIXER_COEF_Y_NARROW = 0, + VMIXER_COEF_Y_WIDE = 1 +}; + +enum s5p_tv_vmx_csc_type { + VMIXER_CSC_RGB_TO_YUV601_LR, + VMIXER_CSC_RGB_TO_YUV601_FR, + VMIXER_CSC_RGB_TO_YUV709_LR, + VMIXER_CSC_RGB_TO_YUV709_FR +}; + +enum s5p_sd_level { + S5P_TV_SD_LEVEL_0IRE, + S5P_TV_SD_LEVEL_75IRE +}; + +enum s5p_sd_vsync_ratio { + SDOUT_VTOS_RATIO_10_4, + SDOUT_VTOS_RATIO_7_3 +}; + +enum s5p_sd_sync_sig_pin { + SDOUT_SYNC_SIG_NO, + SDOUT_SYNC_SIG_YG, + SDOUT_SYNC_SIG_ALL +}; + +enum s5p_sd_closed_caption_type { + SDOUT_NO_INS, + SDOUT_INS_1, + SDOUT_INS_2, + SDOUT_INS_OTHERS +}; + +enum s5p_sd_channel_sel { + SDOUT_CHANNEL_0 = 0, + SDOUT_CHANNEL_1 = 1, + SDOUT_CHANNEL_2 = 2 +}; + +enum s5p_sd_vesa_rgb_sync_type { + SDOUT_VESA_RGB_SYNC_COMPOSITE, + SDOUT_VESA_RGB_SYNC_SEPARATE +}; + +enum s5p_sd_525_copy_permit { + SDO_525_COPY_PERMIT, + SDO_525_ONECOPY_PERMIT, + SDO_525_NOCOPY_PERMIT +}; + +enum s5p_sd_525_mv_psp { + SDO_525_MV_PSP_OFF, + SDO_525_MV_PSP_ON_2LINE_BURST, + SDO_525_MV_PSP_ON_BURST_OFF, + SDO_525_MV_PSP_ON_4LINE_BURST, +}; + +enum s5p_sd_525_copy_info { + SDO_525_COPY_INFO, + SDO_525_DEFAULT, +}; + +enum s5p_sd_525_aspect_ratio { + SDO_525_4_3_NORMAL, + SDO_525_16_9_ANAMORPIC, + SDO_525_4_3_LETTERBOX +}; + +enum s5p_sd_625_subtitles { + SDO_625_NO_OPEN_SUBTITLES, + SDO_625_INACT_OPEN_SUBTITLES, + SDO_625_OUTACT_OPEN_SUBTITLES +}; + +enum s5p_sd_625_camera_film { + SDO_625_CAMERA, + SDO_625_FILM +}; + +enum s5p_sd_625_color_encoding { + SDO_625_NORMAL_PAL, + SDO_625_MOTION_ADAPTIVE_COLORPLUS +}; + +enum s5p_sd_625_aspect_ratio { + SDO_625_4_3_FULL_576, + SDO_625_14_9_LETTERBOX_CENTER_504, + SDO_625_14_9_LETTERBOX_TOP_504, + SDO_625_16_9_LETTERBOX_CENTER_430, + SDO_625_16_9_LETTERBOX_TOP_430, + SDO_625_16_9_LETTERBOX_CENTER, + SDO_625_14_9_FULL_CENTER_576, + SDO_625_16_9_ANAMORPIC_576 +}; + +enum s5p_tv_hdmi_csc_type { + HDMI_CSC_YUV601_TO_RGB_LR, + HDMI_CSC_YUV601_TO_RGB_FR, + HDMI_CSC_YUV709_TO_RGB_LR, + HDMI_CSC_YUV709_TO_RGB_FR, + HDMI_CSC_YUV601_TO_YUV709, + HDMI_CSC_RGB_FR_TO_RGB_LR, + HDMI_CSC_RGB_FR_TO_YUV601, + HDMI_CSC_RGB_FR_TO_YUV709, + HDMI_BYPASS +}; + +enum s5p_tv_hdmi_tg_param { + H_BLANK = 0, + V2_BLANK, + V1_BLANK, + V_LINE, + H_LINE, + VSYNC_POL, + V_BOT_ST, + V_BOT_END, + HSYNC_START, + HSYNC_END, + HSYNC_POL, + VSYNC_T_END, + VSYNC_T_START, + VSYNC_B_END, + VSYNC_B_START, + VSYNC_h_POS_END, + VSYNC_h_POS_START, + TG_H_FSZ, + TG_HACT_START, + TG_HACT_SZ, + TG_V_FSZ, + TG_VSYNC, + TG_VSYNC2, + TG_VACT_START, + TG_VACT_SZ, + TG_FIELD_CHG, + TG_VACT_START2, + TG_VSYNC_TOP_HDMI, + TG_VSYNC_BOTTOM_HDMI, + TG_FIELD_TOP_HDMI, + TG_FIELD_BOTTOM_HDMI +}; + +enum s5p_tv_hdmi_disp_mode { + S5P_TV_HDMI_DISP_MODE_480P_60 = 0, + S5P_TV_HDMI_DISP_MODE_576P_50 = 1, + S5P_TV_HDMI_DISP_MODE_720P_60 = 2, + S5P_TV_HDMI_DISP_MODE_720P_50 = 3, + S5P_TV_HDMI_DISP_MODE_1080I_60 = 4, + S5P_TV_HDMI_DISP_MODE_1080I_50 = 5, + S5P_TV_HDMI_DISP_MODE_VGA_60 = 6, + S5P_TV_HDMI_DISP_MODE_NUM = 7 +}; + +extern void __iomem *hdmi_base; + +/* 0 - hdcp stopped, 1 - hdcp started, 2 - hdcp reset */ +extern u8 hdcp_protocol_status; + +extern bool __s5p_start_hdcp(void); +extern void __s5p_stop_hdcp(void); +extern void __s5p_init_hdcp(bool hpd_status, struct i2c_client *ddc_port); + diff --git a/drivers/media/video/samsung/tv20/s5pc100/tv_power_s5pc100.c b/drivers/media/video/samsung/tv20/s5pc100/tv_power_s5pc100.c new file mode 100644 index 0000000..cf7f0bd --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5pc100/tv_power_s5pc100.c @@ -0,0 +1,140 @@ +/* linux/drivers/media/video/samsung/tv20/s5pc100/tv_power_s5pc100.c + * + * power raw ftn file for Samsung TVOut driver + * + * Copyright (c) 2009 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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/delay.h> +#include <linux/platform_device.h> + +#include <linux/uaccess.h> +#include <linux/io.h> + +#include <mach/map.h> +#include <plat/regs-clock.h> +#include <plat/regs-power.h> + +#include "tv_out_s5pc100.h" + +#if defined USE_POWERCON_FUNCTION +#undef USE_POWERCON_FUNCTION +#endif + +#ifdef COFIG_TVOUT_RAW_DBG +#define S5P_TVOUT_PM_DEBUG 1 +#endif + +#ifdef S5P_TVOUT_PM_DEBUG +#define TVPMPRINTK(fmt, args...) \ + printk(KERN_INFO "\t\t[TVPM] %s: " fmt, __func__ , ## args) +#else +#define TVPMPRINTK(fmt, args...) +#endif + +#define TVPWR_SUBSYSTEM_ACTIVE (1<<4) +#define TVPWR_SUBSYSTEM_LP (0<<4) + +#define TVPWR_MTC_COUNTER_CLEAR(a) (((~0xf)<<16)&a) +#define TVPWR_MTC_COUNTER_SET(a) ((0xf&a)<<16) + +#define TVPWR_TV_BLOCK_STATUS(a) ((0x1<<4)&a) + +#define TVPWR_DAC_STATUS(a) ((0x1<<26)&a) +#define TVPWR_DAC_ON (1<<26) + +static unsigned short g_dacPwrOn; + + +void __s5p_tv_power_init_mtc_stable_counter(unsigned int value) +{ + TVPMPRINTK("(%d)\n\r", value); + + writel(TVPWR_MTC_COUNTER_CLEAR((readl(S5P_MTC_STABLE) | + TVPWR_MTC_COUNTER_SET(value))), + S5P_MTC_STABLE); + + TVPMPRINTK("(0x%08x)\n\r", readl(S5P_MTC_STABLE)); +} + +void __s5p_tv_powerinitialize_dac_onoff(unsigned short on) +{ + TVPMPRINTK("(%d)\n\r", on); + + g_dacPwrOn = on; + + TVPMPRINTK("(0x%08x)\n\r", g_dacPwrOn); +} + +void __s5p_tv_powerset_dac_onoff(unsigned short on) +{ + TVPMPRINTK("(%d)\n\r", on); + + if (on) + writel(readl(S5P_OTHERS) | TVPWR_DAC_ON, S5P_OTHERS); + else + writel(readl(S5P_OTHERS) & ~TVPWR_DAC_ON, S5P_OTHERS); + + + TVPMPRINTK("(0x%08x)\n\r", readl(S5P_OTHERS)); +} + + +unsigned short __s5p_tv_power_get_power_status(void) +{ + + TVPMPRINTK("()\n\r"); + + TVPMPRINTK("(0x%08x)\n\r", readl(S5P_BLK_PWR_STAT)); + + + return TVPWR_TV_BLOCK_STATUS(readl(S5P_BLK_PWR_STAT)) ? 1 : 0; +} + +unsigned short __s5p_tv_power_get_dac_power_status(void) +{ + TVPMPRINTK("()\n\r"); + + TVPMPRINTK("(0x%08x)\n\r", readl(S5P_OTHERS)); + + return TVPWR_DAC_STATUS(readl(S5P_OTHERS)) ? 1 : 0; +} + +void __s5p_tv_poweron(void) +{ + TVPMPRINTK("()\n\r"); + + writel(readl(S5P_NORMAL_CFG) | TVPWR_SUBSYSTEM_ACTIVE, + S5P_NORMAL_CFG); + + while (!TVPWR_TV_BLOCK_STATUS(readl(S5P_BLK_PWR_STAT))) + msleep(1); + + + TVPMPRINTK("0x%08x,0x%08x)\n\r", readl(S5P_NORMAL_CFG), + readl(S5P_BLK_PWR_STAT)); +} + + +void __s5p_tv_poweroff(void) +{ + TVPMPRINTK("()\n\r"); + + __s5p_tv_powerset_dac_onoff(0); + + writel(readl(S5P_NORMAL_CFG) & ~TVPWR_SUBSYSTEM_ACTIVE, + S5P_NORMAL_CFG); + + while (TVPWR_TV_BLOCK_STATUS(readl(S5P_BLK_PWR_STAT))) + msleep(1); + + + TVPMPRINTK("0x%08x,0x%08x)\n\r", readl(S5P_NORMAL_CFG), + readl(S5P_BLK_PWR_STAT)); +} diff --git a/drivers/media/video/samsung/tv20/s5pc100/vmixer_s5pc100.c b/drivers/media/video/samsung/tv20/s5pc100/vmixer_s5pc100.c new file mode 100644 index 0000000..046f44b --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5pc100/vmixer_s5pc100.c @@ -0,0 +1,1047 @@ +/* linux/drivers/media/video/samsung/tv20/s5pc100/vmixer_s5pc100.c + * + * Mixer raw ftn file for Samsung TVOut driver + * + * Copyright (c) 2009 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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/interrupt.h> +#include <linux/platform_device.h> + +#include <linux/io.h> + +#include "tv_out_s5pc100.h" + +#include "regs/regs-vmx.h" + +#ifdef COFIG_TVOUT_RAW_DBG +#define S5P_MXR_DEBUG 1 +#endif + +#ifdef S5P_MXR_DEBUG +#define VMPRINTK(fmt, args...) \ + printk(KERN_INFO "\t\t[VM] %s: " fmt, __func__ , ## args) +#else +#define VMPRINTK(fmt, args...) +#endif + +static struct resource *mixer_mem; +void __iomem *mixer_base; + +/* +*set - set functions are only called under running vmixer +*/ + +enum s5p_tv_vmx_err __s5p_vm_set_layer_show(enum s5p_tv_vmx_layer layer, + bool show) +{ + u32 mxr_config; + + VMPRINTK("%d, %d\n\r", layer, show); + + switch (layer) { + + case VM_VIDEO_LAYER: + mxr_config = (show) ? + (readl(mixer_base + S5P_MXR_CFG) | + S5P_MXR_VIDEO_LAYER_SHOW) : + (readl(mixer_base + S5P_MXR_CFG) & + ~S5P_MXR_VIDEO_LAYER_SHOW); + break; + + case VM_GPR0_LAYER: + mxr_config = (show) ? + (readl(mixer_base + S5P_MXR_CFG) | + S5P_MXR_GRAPHIC0_LAYER_SHOW) : + (readl(mixer_base + S5P_MXR_CFG) & + ~S5P_MXR_GRAPHIC0_LAYER_SHOW); + break; + + case VM_GPR1_LAYER: + mxr_config = (show) ? + (readl(mixer_base + S5P_MXR_CFG) | + S5P_MXR_GRAPHIC1_LAYER_SHOW) : + (readl(mixer_base + S5P_MXR_CFG) & + ~S5P_MXR_GRAPHIC1_LAYER_SHOW); + break; + + default: + VMPRINTK(" invalid layer parameter = %d\n\r", layer); + return S5P_TV_VMX_ERR_INVALID_PARAM; + break; + } + + writel(mxr_config, mixer_base + S5P_MXR_CFG); + + VMPRINTK("0x%x\n\r", readl(mixer_base + S5P_MXR_CFG)); + + return VMIXER_NO_ERROR; +} + +enum s5p_tv_vmx_err __s5p_vm_set_layer_priority(enum s5p_tv_vmx_layer layer, + u32 priority) +{ + u32 layer_cfg; + + VMPRINTK("%d, %d\n\r", layer, priority); + + switch (layer) { + + case VM_VIDEO_LAYER: + layer_cfg = S5P_MXR_VP_LAYER_PRIORITY_CLEAR( + readl(mixer_base + S5P_MXR_LAYER_CFG)) | + S5P_MXR_VP_LAYER_PRIORITY(priority); + break; + + case VM_GPR0_LAYER: + layer_cfg = S5P_MXR_GRP0_LAYER_PRIORITY_CLEAR( + readl(mixer_base + S5P_MXR_LAYER_CFG)) | + S5P_MXR_GRP0_LAYER_PRIORITY(priority); + break; + + case VM_GPR1_LAYER: + layer_cfg = S5P_MXR_GRP1_LAYER_PRIORITY_CLEAR( + readl(mixer_base + S5P_MXR_LAYER_CFG)) | + S5P_MXR_GRP1_LAYER_PRIORITY(priority); + break; + + default: + VMPRINTK(" invalid layer parameter = %d\n\r", layer); + return S5P_TV_VMX_ERR_INVALID_PARAM; + break; + } + + writel(layer_cfg, mixer_base + S5P_MXR_LAYER_CFG); + + return VMIXER_NO_ERROR; +} + +enum s5p_tv_vmx_err __s5p_vm_set_win_blend( + enum s5p_tv_vmx_layer layer, bool enable) +{ + u32 temp_reg; + VMPRINTK("%d, %d\n\r", layer, enable); + + switch (layer) { + + case VM_VIDEO_LAYER: + temp_reg = readl(mixer_base + S5P_MXR_VIDEO_CFG) + & (~S5P_MXR_VP_BLEND_ENABLE) ; + + if (enable) + temp_reg |= S5P_MXR_VP_BLEND_ENABLE; + else + temp_reg |= S5P_MXR_VP_BLEND_DISABLE; + + writel(temp_reg, mixer_base + S5P_MXR_VIDEO_CFG); + + break; + + case VM_GPR0_LAYER: + temp_reg = readl(mixer_base + S5P_MXR_GRAPHIC0_CFG) + & (~S5P_MXR_WIN_BLEND_ENABLE) ; + + if (enable) + temp_reg |= S5P_MXR_WIN_BLEND_ENABLE; + else + temp_reg |= S5P_MXR_WIN_BLEND_DISABLE; + + writel(temp_reg, mixer_base + S5P_MXR_GRAPHIC0_CFG); + + break; + + case VM_GPR1_LAYER: + temp_reg = readl(mixer_base + S5P_MXR_GRAPHIC1_CFG) + & (~S5P_MXR_WIN_BLEND_ENABLE) ; + + if (enable) + temp_reg |= S5P_MXR_WIN_BLEND_ENABLE; + else + temp_reg |= S5P_MXR_WIN_BLEND_DISABLE; + + writel(temp_reg, mixer_base + S5P_MXR_GRAPHIC1_CFG); + + break; + + default: + VMPRINTK(" invalid layer parameter = %d\n\r", layer); + + return S5P_TV_VMX_ERR_INVALID_PARAM; + + break; + } + + VMPRINTK("0x08%x\n\r", readl(mixer_base + S5P_MXR_VIDEO_CFG)); + + VMPRINTK("0x08%x\n\r", readl(mixer_base + S5P_MXR_GRAPHIC0_CFG)); + VMPRINTK("0x08%x\n\r", readl(mixer_base + S5P_MXR_GRAPHIC1_CFG)); + + return VMIXER_NO_ERROR; +} + + +enum s5p_tv_vmx_err __s5p_vm_set_layer_alpha(enum s5p_tv_vmx_layer layer, + u32 alpha) +{ + u32 temp_reg; + VMPRINTK("%d, %d\n\r", layer, alpha); + + switch (layer) { + + case VM_VIDEO_LAYER: + temp_reg = readl(mixer_base + S5P_MXR_VIDEO_CFG) + & (~S5P_MXR_ALPHA) ; + temp_reg |= S5P_MXR_VP_ALPHA_VALUE(alpha); + writel(temp_reg, mixer_base + S5P_MXR_VIDEO_CFG); + break; + + case VM_GPR0_LAYER: + temp_reg = readl(mixer_base + S5P_MXR_GRAPHIC0_CFG) + & (~S5P_MXR_ALPHA) ; + temp_reg |= S5P_MXR_GRP_ALPHA_VALUE(alpha); + writel(temp_reg, mixer_base + S5P_MXR_GRAPHIC0_CFG); + break; + + case VM_GPR1_LAYER: + temp_reg = readl(mixer_base + S5P_MXR_GRAPHIC1_CFG) + & (~S5P_MXR_ALPHA) ; + temp_reg |= S5P_MXR_GRP_ALPHA_VALUE(alpha); + writel(temp_reg, mixer_base + S5P_MXR_GRAPHIC1_CFG); + break; + + default: + VMPRINTK(" invalid layer parameter = %d\n\r", layer); + return S5P_TV_VMX_ERR_INVALID_PARAM; + break; + } + + VMPRINTK("0x08%x\n\r", readl(mixer_base + S5P_MXR_VIDEO_CFG)); + + VMPRINTK("0x08%x\n\r", readl(mixer_base + S5P_MXR_GRAPHIC0_CFG)); + VMPRINTK("0x08%x\n\r", readl(mixer_base + S5P_MXR_GRAPHIC1_CFG)); + + return VMIXER_NO_ERROR; +} + + +enum s5p_tv_vmx_err __s5p_vm_set_grp_base_address(enum s5p_tv_vmx_layer layer, + u32 base_addr) +{ + VMPRINTK("%d, 0x%x\n\r", layer, base_addr); + + if (S5P_MXR_GRP_ADDR_ILLEGAL(base_addr)) { + VMPRINTK(" address is not word align = %d\n\r", base_addr); + return S5P_TV_VMX_ERR_BASE_ADDRESS_MUST_WORD_ALIGN; + } + + switch (layer) { + + case VM_GPR0_LAYER: + writel(S5P_MXR_GPR_BASE(base_addr), + mixer_base + S5P_MXR_GRAPHIC0_BASE); + VMPRINTK("0x%x\n\r", + readl(mixer_base + S5P_MXR_GRAPHIC0_BASE)); + break; + + case VM_GPR1_LAYER: + writel(S5P_MXR_GPR_BASE(base_addr), + mixer_base + S5P_MXR_GRAPHIC1_BASE); + VMPRINTK("0x%x\n\r", + readl(mixer_base + S5P_MXR_GRAPHIC1_BASE)); + break; + + default: + VMPRINTK(" invalid layer parameter = %d\n\r", layer); + return S5P_TV_VMX_ERR_INVALID_PARAM; + break; + } + + return VMIXER_NO_ERROR; +} + +enum s5p_tv_vmx_err __s5p_vm_set_grp_layer_position(enum s5p_tv_vmx_layer + layer, u32 dst_offs_x, u32 dst_offs_y) +{ + VMPRINTK("%d, %d, %d)\n\r", layer, dst_offs_x, dst_offs_y); + + switch (layer) { + + case VM_GPR0_LAYER: + writel(S5P_MXR_GRP_DESTX(dst_offs_x) | + S5P_MXR_GRP_DESTY(dst_offs_y), + mixer_base + S5P_MXR_GRAPHIC0_DXY); + VMPRINTK("0x%x\n\r", readl(mixer_base + S5P_MXR_GRAPHIC0_DXY)); + break; + + case VM_GPR1_LAYER: + writel(S5P_MXR_GRP_DESTX(dst_offs_x) | + S5P_MXR_GRP_DESTY(dst_offs_y), + mixer_base + S5P_MXR_GRAPHIC1_DXY); + VMPRINTK("0x%x\n\r", readl(mixer_base + S5P_MXR_GRAPHIC1_DXY)); + break; + + default: + VMPRINTK("invalid layer parameter = %d\n\r", layer); + return S5P_TV_VMX_ERR_INVALID_PARAM; + break; + } + + return VMIXER_NO_ERROR; +} + +enum s5p_tv_vmx_err __s5p_vm_set_grp_layer_size(enum s5p_tv_vmx_layer layer, + u32 span, + u32 width, + u32 height, + u32 src_offs_x, + u32 src_offs_y) +{ + VMPRINTK("%d, %d, %d, %d, %d, %d)\n\r", layer, span, width, height, + src_offs_x, src_offs_y); + + switch (layer) { + + case VM_GPR0_LAYER: + writel(S5P_MXR_GRP_SPAN(span), + mixer_base + S5P_MXR_GRAPHIC0_SPAN); + writel(S5P_MXR_GRP_WIDTH(width) | + S5P_MXR_GRP_HEIGHT(height), + mixer_base + S5P_MXR_GRAPHIC0_WH); + writel(S5P_MXR_GRP_STARTX(src_offs_x) | + S5P_MXR_GRP_STARTY(src_offs_y), + mixer_base + S5P_MXR_GRAPHIC0_SXY); + VMPRINTK("0x%x, 0x%x, 0x%x\n\r", + readl(mixer_base + S5P_MXR_GRAPHIC0_SPAN), + readl(mixer_base + S5P_MXR_GRAPHIC0_WH), + readl(mixer_base + S5P_MXR_GRAPHIC0_SXY)); + break; + + case VM_GPR1_LAYER: + writel(S5P_MXR_GRP_SPAN(span), + mixer_base + S5P_MXR_GRAPHIC1_SPAN); + writel(S5P_MXR_GRP_WIDTH(width) | S5P_MXR_GRP_HEIGHT(height), + mixer_base + S5P_MXR_GRAPHIC1_WH); + writel(S5P_MXR_GRP_STARTX(src_offs_x) | + S5P_MXR_GRP_STARTY(src_offs_y), + mixer_base + S5P_MXR_GRAPHIC1_SXY); + VMPRINTK("0x%x, 0x%x, 0x%x\n\r", + readl(mixer_base + S5P_MXR_GRAPHIC1_SPAN), + readl(mixer_base + S5P_MXR_GRAPHIC1_WH), + readl(mixer_base + S5P_MXR_GRAPHIC1_SXY)); + break; + + default: + VMPRINTK(" invalid layer parameter = %d\n\r", layer); + return S5P_TV_VMX_ERR_INVALID_PARAM; + break; + } + + return VMIXER_NO_ERROR; +} + +enum s5p_tv_vmx_err __s5p_vm_set_bg_color( + enum s5p_tv_vmx_bg_color_num colornum, + u32 color_y, + u32 color_cb, + u32 color_cr) +{ + u32 reg_value; + VMPRINTK("%d, %d, %d, %d)\n\r", colornum, color_y, color_cb, color_cr); + + reg_value = S5P_MXR_BG_COLOR_Y(color_y) | + S5P_MXR_BG_COLOR_CB(color_cb) | + S5P_MXR_BG_COLOR_CR(color_cr); + + switch (colornum) { + + case VMIXER_BG_COLOR_0: + writel(reg_value, mixer_base + S5P_MXR_BG_COLOR0); + VMPRINTK("0x%x\n\r", readl(mixer_base + S5P_MXR_BG_COLOR0)); + break; + + case VMIXER_BG_COLOR_1: + writel(reg_value, mixer_base + S5P_MXR_BG_COLOR1); + VMPRINTK("0x%x\n\r", readl(mixer_base + S5P_MXR_BG_COLOR1)); + break; + + case VMIXER_BG_COLOR_2: + writel(reg_value, mixer_base + S5P_MXR_BG_COLOR2); + VMPRINTK("0x%x\n\r", readl(mixer_base + S5P_MXR_BG_COLOR2)); + break; + + default: + VMPRINTK(" invalid uiColorNum parameter = %d\n\r", colornum); + return S5P_TV_VMX_ERR_INVALID_PARAM; + break; + } + + return VMIXER_NO_ERROR; +} + + + +/* +* initialization - iniization functions are only called under stopping vmixer +*/ +enum s5p_tv_vmx_err __s5p_vm_init_status_reg(enum s5p_vmx_burst_mode burst, + enum s5p_endian_type endian) +{ + u32 temp_reg = 0; + + VMPRINTK("++(%d, %d)\n\r", burst, endian); + + temp_reg = S5P_MXR_MIXER_RESERVED | + S5P_MXR_CMU_CANNOT_STOP_CLOCK; + + switch (burst) { + + case VM_BURST_8: + temp_reg |= S5P_MXR_BURST8_MODE; + break; + + case VM_BURST_16: + temp_reg |= S5P_MXR_BURST16_MODE; + break; + + default: + VMPRINTK("[ERR] : invalid burst parameter = %d\n\r", burst); + return S5P_TV_VMX_ERR_INVALID_PARAM; + break; + } + + switch (endian) { + + case TVOUT_BIG_ENDIAN_MODE: + temp_reg |= S5P_MXR_BIG_ENDIAN_SOURCE_FORMAT; + break; + + case TVOUT_LITTLE_ENDIAN_MODE: + temp_reg |= S5P_MXR_LITTLE_ENDIAN_SOURCE_FORMAT; + break; + + default: + VMPRINTK("[ERR] : invalid endian parameter = %d\n\r", endian); + return S5P_TV_VMX_ERR_INVALID_PARAM; + break; + } + + writel(temp_reg, mixer_base + S5P_MXR_STATUS); + + VMPRINTK("--(0x%x)\n\r", readl(mixer_base + S5P_MXR_STATUS)); + + return VMIXER_NO_ERROR; +} + +enum s5p_tv_vmx_err __s5p_vm_init_display_mode(enum s5p_tv_disp_mode mode, + enum s5p_tv_o_mode output_mode) +{ + u32 temp_reg = 0; + + VMPRINTK("%d, %d)\n\r", mode, output_mode); + + switch (mode) { + + case TVOUT_NTSC_M: + + case TVOUT_NTSC_443: + temp_reg = S5P_MXR_SD | S5P_MXR_NTSC; + break; + + case TVOUT_PAL_BDGHI: + + case TVOUT_PAL_M: + + case TVOUT_PAL_N: + + case TVOUT_PAL_NC: + + case TVOUT_PAL_60: + temp_reg = S5P_MXR_SD | S5P_MXR_PAL; + break; + + case TVOUT_480P_60_16_9: + + case TVOUT_480P_60_4_3: + temp_reg = S5P_MXR_SD | S5P_MXR_NTSC; + break; + + case TVOUT_576P_50_16_9: + + case TVOUT_576P_50_4_3: + temp_reg = S5P_MXR_SD | S5P_MXR_PAL; + break; + + case TVOUT_720P_50: + + case TVOUT_720P_60: + temp_reg = S5P_MXR_HD | S5P_MXR_HD_720P_MODE; + break; + + default: + VMPRINTK(" invalid mode parameter = %d\n\r", mode); + return S5P_TV_VMX_ERR_INVALID_PARAM; + break; + } + + switch (output_mode) { + + case TVOUT_OUTPUT_COMPOSITE: + + case TVOUT_OUTPUT_SVIDEO: + + case TVOUT_OUTPUT_COMPONENT_YPBPR_INERLACED: + temp_reg |= S5P_MXR_INTERLACE_MODE; + break; + + case TVOUT_OUTPUT_COMPONENT_YPBPR_PROGRESSIVE: + + case TVOUT_OUTPUT_COMPONENT_RGB_PROGRESSIVE: + temp_reg |= S5P_MXR_PROGRESSVE_MODE; + break; + + case TVOUT_OUTPUT_HDMI: + temp_reg |= S5P_MXR_PROGRESSVE_MODE; + break; + + default: + VMPRINTK(" invalid mode parameter = %d\n\r", mode); + return S5P_TV_VMX_ERR_INVALID_PARAM; + break; + } + + writel(temp_reg, mixer_base + S5P_MXR_CFG); + + VMPRINTK("--(0x%x)\n\r", readl(mixer_base + S5P_MXR_CFG)); + + return VMIXER_NO_ERROR; +} + +enum s5p_tv_vmx_err __s5p_vm_init_layer(enum s5p_tv_vmx_layer layer, + bool show, + bool win_blending, + u32 alpha, + u32 priority, + enum s5p_tv_vmx_color_fmt color, + bool blank_change, + bool pixel_blending, + bool premul, + u32 blank_color, + u32 base_addr, + u32 span, + u32 width, + u32 height, + u32 src_offs_x, + u32 src_offs_y, + u32 dst_offs_x, + u32 dst_offs_y) +{ + u32 temp_reg = 0; + + VMPRINTK("%d, %d, %d, %d, %d, %d, %d, %d, %d, 0x%x,\ + 0x%x, %d, %d, %d, %d, %d, %d, %d)\n\r", + layer, show, win_blending, alpha, priority, + color, blank_change, pixel_blending, premul, + blank_color, base_addr, span, width, height, + src_offs_x, src_offs_y, dst_offs_x, dst_offs_y); + + switch (layer) { + + case VM_VIDEO_LAYER: + temp_reg = (win_blending) ? S5P_MXR_VP_BLEND_ENABLE : + S5P_MXR_VP_BLEND_DISABLE; + temp_reg |= S5P_MXR_VP_ALPHA_VALUE(alpha); + writel(temp_reg, mixer_base + S5P_MXR_VIDEO_CFG); + break; + + case VM_GPR0_LAYER: + temp_reg = (blank_change) ? + S5P_MXR_BLANK_NOT_CHANGE_NEW_PIXEL : + S5P_MXR_BLANK_CHANGE_NEW_PIXEL; + temp_reg |= (premul) ? S5P_MXR_PRE_MUL_MODE : + S5P_MXR_NORMAL_MODE; + temp_reg |= (win_blending) ? S5P_MXR_WIN_BLEND_ENABLE : + S5P_MXR_WIN_BLEND_DISABLE; + temp_reg |= (pixel_blending) ? S5P_MXR_PIXEL_BLEND_ENABLE : + S5P_MXR_PIXEL_BLEND_DISABLE; + temp_reg |= S5P_MXR_EG_COLOR_FORMAT(color); + temp_reg |= S5P_MXR_GRP_ALPHA_VALUE(alpha); + writel(temp_reg, mixer_base + S5P_MXR_GRAPHIC0_CFG); + writel(S5P_MXR_GPR_BLANK_COLOR(blank_color), + mixer_base + S5P_MXR_GRAPHIC0_BLANK); + + VMPRINTK("--(0x%x)\n\r", + readl(mixer_base + S5P_MXR_GRAPHIC0_CFG)); + VMPRINTK("--(0x%x)\n\r", + readl(mixer_base + S5P_MXR_GRAPHIC0_BLANK)); + + __s5p_vm_set_grp_layer_size(layer, span, width, height, + src_offs_x, src_offs_y); + + __s5p_vm_set_grp_base_address(layer, base_addr); + __s5p_vm_set_grp_layer_position(layer, dst_offs_x, dst_offs_y); + + break; + + case VM_GPR1_LAYER: + temp_reg = (blank_change) ? + S5P_MXR_BLANK_NOT_CHANGE_NEW_PIXEL : + S5P_MXR_BLANK_CHANGE_NEW_PIXEL; + temp_reg |= (premul) ? S5P_MXR_PRE_MUL_MODE : + S5P_MXR_NORMAL_MODE; + temp_reg |= (win_blending) ? S5P_MXR_WIN_BLEND_ENABLE : + S5P_MXR_WIN_BLEND_DISABLE; + temp_reg |= (pixel_blending) ? S5P_MXR_PIXEL_BLEND_ENABLE : + S5P_MXR_PIXEL_BLEND_DISABLE; + temp_reg |= S5P_MXR_EG_COLOR_FORMAT(color); + temp_reg |= S5P_MXR_GRP_ALPHA_VALUE(alpha); + + writel(temp_reg, mixer_base + S5P_MXR_GRAPHIC1_CFG); + writel(S5P_MXR_GPR_BLANK_COLOR(blank_color), + mixer_base + S5P_MXR_GRAPHIC1_BLANK); + + VMPRINTK("--(0x%x)\n\r", + readl(mixer_base + S5P_MXR_GRAPHIC1_CFG)); + VMPRINTK("--(0x%x)\n\r", + readl(mixer_base + S5P_MXR_GRAPHIC1_BLANK)); + + __s5p_vm_set_grp_layer_size(layer, span, width, height, + src_offs_x, src_offs_y); + + __s5p_vm_set_grp_base_address(layer, base_addr); + __s5p_vm_set_grp_layer_position(layer, dst_offs_x, dst_offs_y); + break; + + default: + VMPRINTK("invalid layer parameter = %d\n\r", layer); + return S5P_TV_VMX_ERR_INVALID_PARAM; + break; + } + + __s5p_vm_set_layer_priority(layer, priority); + + __s5p_vm_set_layer_show(layer, show); + + return VMIXER_NO_ERROR; +} + +void __s5p_vm_init_bg_dither_enable(bool cr_dither_enable, + bool cb_dither_enable, + bool y_dither_enable) +{ + u32 temp_reg = 0; + + VMPRINTK("%d, %d, %d\n\r", cr_dither_enable, + cb_dither_enable, y_dither_enable); + + temp_reg = (cr_dither_enable) ? + (temp_reg | S5P_MXR_BG_CR_DIHER_EN) : + (temp_reg & ~S5P_MXR_BG_CR_DIHER_EN); + temp_reg = (cb_dither_enable) ? + (temp_reg | S5P_MXR_BG_CB_DIHER_EN) : + (temp_reg & ~S5P_MXR_BG_CB_DIHER_EN); + temp_reg = (y_dither_enable) ? + (temp_reg | S5P_MXR_BG_Y_DIHER_EN) : + (temp_reg & ~S5P_MXR_BG_Y_DIHER_EN); + + writel(temp_reg, mixer_base + S5P_MXR_BG_CFG); + VMPRINTK("--(0x%x)\n\r", readl(mixer_base + S5P_MXR_BG_CFG)); + +} + + +enum s5p_tv_vmx_err __s5p_vm_init_bg_color( + enum s5p_tv_vmx_bg_color_num color_num, + u32 color_y, + u32 color_cb, + u32 color_cr) +{ + return __s5p_vm_set_bg_color(color_num, color_y, color_cb, color_cr); +} + +enum s5p_tv_vmx_err __s5p_vm_init_csc_coef(enum s5p_yuv_fmt_component component, + enum s5p_tv_coef_y_mode mode, + u32 coeff0, + u32 coeff1, + u32 coeff2) +{ + u32 mxr_cm; + + VMPRINTK("%d, %d, %d, %d, %d\n\r", component, mode, coeff0, + coeff1, coeff2); + + switch (component) { + + case TVOUT_YUV_Y: + mxr_cm = (mode == VMIXER_COEF_Y_WIDE) ? + S5P_MXR_BG_COLOR_WIDE : S5P_MXR_BG_COLOR_NARROW; + mxr_cm |= S5P_MXR_BG_COEFF_0(coeff0) | + S5P_MXR_BG_COEFF_1(coeff1) | + S5P_MXR_BG_COEFF_2(coeff2); + writel(mxr_cm, mixer_base + S5P_MXR_CM_COEFF_Y); + VMPRINTK("--(0x%x)\n\r", + readl(mixer_base + S5P_MXR_CM_COEFF_Y)); + break; + + case TVOUT_YUV_CB: + mxr_cm = S5P_MXR_BG_COEFF_0(coeff0) | + S5P_MXR_BG_COEFF_1(coeff1) | + S5P_MXR_BG_COEFF_2(coeff2); + writel(mxr_cm, mixer_base + S5P_MXR_CM_COEFF_CB); + VMPRINTK("--(0x%x)\n\r", + readl(mixer_base + S5P_MXR_CM_COEFF_CB)); + break; + + case TVOUT_YUV_CR: + mxr_cm = S5P_MXR_BG_COEFF_0(coeff0) | + S5P_MXR_BG_COEFF_1(coeff1) | + S5P_MXR_BG_COEFF_2(coeff2); + writel(mxr_cm, S5P_MXR_CM_COEFF_CR); + VMPRINTK("--(0x%x)\n\r", + readl(mixer_base + S5P_MXR_CM_COEFF_CR)); + break; + + default: + VMPRINTK("invalid component parameter = %d\n\r", component); + return S5P_TV_VMX_ERR_INVALID_PARAM; + break; + } + + return VMIXER_NO_ERROR; +} + +void __s5p_vm_init_csc_coef_default(enum s5p_tv_vmx_csc_type csc_type) +{ + VMPRINTK("%d\n\r", csc_type); + + switch (csc_type) { + + case VMIXER_CSC_RGB_TO_YUV601_LR: + writel((0 << 30) | (153 << 20) | (300 << 10) | (58 << 0), + mixer_base + S5P_MXR_CM_COEFF_Y); + writel((936 << 20) | (851 << 10) | (262 << 0), + mixer_base + S5P_MXR_CM_COEFF_CB); + writel((262 << 20) | (805 << 10) | (982 << 0), + mixer_base + S5P_MXR_CM_COEFF_CR); + break; + + case VMIXER_CSC_RGB_TO_YUV601_FR: + writel((1 << 30) | (132 << 20) | (258 << 10) | (50 << 0), + mixer_base + S5P_MXR_CM_COEFF_Y); + writel((948 << 20) | (875 << 10) | (225 << 0), + mixer_base + S5P_MXR_CM_COEFF_CB); + writel((225 << 20) | (836 << 10) | (988 << 0), + mixer_base + S5P_MXR_CM_COEFF_CR); + break; + + case VMIXER_CSC_RGB_TO_YUV709_LR: + writel((0 << 30) | (109 << 20) | (366 << 10) | (36 << 0), + mixer_base + S5P_MXR_CM_COEFF_Y); + writel((964 << 20) | (822 << 10) | (216 << 0), + mixer_base + S5P_MXR_CM_COEFF_CB); + writel((262 << 20) | (787 << 10) | (1000 << 0), + mixer_base + S5P_MXR_CM_COEFF_CR); + break; + + case VMIXER_CSC_RGB_TO_YUV709_FR: + writel((1 << 30) | (94 << 20) | (314 << 10) | (32 << 0), + mixer_base + S5P_MXR_CM_COEFF_Y); + writel((972 << 20) | (851 << 10) | (225 << 0), + mixer_base + S5P_MXR_CM_COEFF_CB); + writel((225 << 20) | (820 << 10) | (1004 << 0), + mixer_base + S5P_MXR_CM_COEFF_CR); + break; + + default: + VMPRINTK(" invalid csc_type parameter = %d\n\r", csc_type); + break; + } + + VMPRINTK("--(0x%x)\n\r", readl(mixer_base + S5P_MXR_CM_COEFF_Y)); + + VMPRINTK("--(0x%x)\n\r", readl(mixer_base + S5P_MXR_CM_COEFF_CB)); + VMPRINTK("--(0x%x)\n\r", readl(mixer_base + S5P_MXR_CM_COEFF_CR)); +} + +/* +* etc +*/ +enum s5p_tv_vmx_err __s5p_vm_get_layer_info(enum s5p_tv_vmx_layer layer, + bool *show, + u32 *priority) +{ + VMPRINTK("%d\n\r", layer); + + switch (layer) { + + case VM_VIDEO_LAYER: + *show = (readl(mixer_base + S5P_MXR_LAYER_CFG) & + S5P_MXR_VIDEO_LAYER_SHOW) ? 1 : 0; + *priority = S5P_MXR_VP_LAYER_PRIORITY_INFO( + readl(mixer_base + S5P_MXR_LAYER_CFG)); + break; + + case VM_GPR0_LAYER: + *show = (readl(mixer_base + S5P_MXR_LAYER_CFG) & + S5P_MXR_GRAPHIC0_LAYER_SHOW) ? 1 : 0; + *priority = S5P_MXR_GRP0_LAYER_PRIORITY_INFO( + readl(mixer_base + S5P_MXR_LAYER_CFG)); + break; + + case VM_GPR1_LAYER: + *show = (readl(mixer_base + S5P_MXR_LAYER_CFG) & + S5P_MXR_GRAPHIC1_LAYER_SHOW) ? 1 : 0; + *priority = S5P_MXR_GRP1_LAYER_PRIORITY_INFO( + readl(mixer_base + S5P_MXR_LAYER_CFG)); + break; + + default: + VMPRINTK("invalid layer parameter = %d\n\r", layer); + return S5P_TV_VMX_ERR_INVALID_PARAM; + break; + } + + VMPRINTK("%d, %d\n\r", *show, *priority); + + return VMIXER_NO_ERROR; +} + +/* +* start - start functions are only called under stopping vmixer +*/ + +void __s5p_vm_start(void) +{ + VMPRINTK("()\n\r"); + writel((readl(mixer_base + S5P_MXR_STATUS) | S5P_MXR_MIXER_START), + mixer_base + S5P_MXR_STATUS); + VMPRINTK("0x%x\n\r", readl(mixer_base + S5P_MXR_STATUS)); + + + VMPRINTK("S5P_MXR_STATUS \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_STATUS)); + VMPRINTK("S5P_MXR_INT_EN \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_INT_EN)); + VMPRINTK("S5P_MXR_BG_CFG \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_BG_CFG)); + VMPRINTK("S5P_MXR_BG_COLOR0 \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_BG_COLOR0)); + VMPRINTK("S5P_MXR_BG_COLOR1 \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_BG_COLOR1)); + VMPRINTK("S5P_MXR_BG_COLOR2 \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_BG_COLOR2)); + VMPRINTK("S5P_MXR_CM_COEFF_Y \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_CM_COEFF_Y)); + VMPRINTK("S5P_MXR_CM_COEFF_CB \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_CM_COEFF_CB)); + VMPRINTK("S5P_MXR_CM_COEFF_CR \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_CM_COEFF_CR)); + VMPRINTK("S5P_MXR_CM_COEFF_Y \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_CM_COEFF_Y)); + VMPRINTK("S5P_MXR_CM_COEFF_CB \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_CM_COEFF_CB)); + VMPRINTK("S5P_MXR_CM_COEFF_CR \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_CM_COEFF_CR)); + VMPRINTK("S5P_MXR_GRAPHIC0_CFG \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_GRAPHIC0_CFG)); + VMPRINTK("S5P_MXR_GRAPHIC0_BASE \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_GRAPHIC0_BASE)); + VMPRINTK("S5P_MXR_GRAPHIC0_SPAN \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_GRAPHIC0_SPAN)); + VMPRINTK("S5P_MXR_GRAPHIC0_WH \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_GRAPHIC0_WH)); + VMPRINTK("S5P_MXR_GRAPHIC0_SXY \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_GRAPHIC0_SXY)); + VMPRINTK("S5P_MXR_GRAPHIC0_DXY \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_GRAPHIC0_DXY)); + VMPRINTK("S5P_MXR_GRAPHIC0_BLANK \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_GRAPHIC0_BLANK)); + VMPRINTK("S5P_MXR_GRAPHIC1_BASE \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_GRAPHIC1_BASE)); + VMPRINTK("S5P_MXR_GRAPHIC1_SPAN \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_GRAPHIC1_SPAN)); + VMPRINTK("S5P_MXR_GRAPHIC1_WH \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_GRAPHIC1_WH)); + VMPRINTK("S5P_MXR_GRAPHIC1_SXY \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_GRAPHIC1_SXY)); + VMPRINTK("S5P_MXR_GRAPHIC1_DXY \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_GRAPHIC1_DXY)); + VMPRINTK("S5P_MXR_GRAPHIC1_BLANK \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_GRAPHIC1_BLANK)); + VMPRINTK("S5P_MXR_CFG \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_CFG)); + VMPRINTK("S5P_MXR_LAYER_CFG \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_LAYER_CFG)); + +} + +/* +* stop - stop functions are only called under running vmixer +*/ + +void __s5p_vm_stop(void) +{ + VMPRINTK("()\n\r"); + writel((readl(mixer_base + S5P_MXR_STATUS) & ~S5P_MXR_MIXER_START), + mixer_base + S5P_MXR_STATUS); + VMPRINTK("0x%x\n\r", readl(mixer_base + S5P_MXR_STATUS)); +} + +/* +* interrupt - for debug +*/ + +enum s5p_tv_vmx_err __s5p_vm_set_underflow_interrupt_enable( + enum s5p_tv_vmx_layer layer, bool en) +{ + u32 enablemaks; + + VMPRINTK("%d, %d\n\r", layer, en); + + switch (layer) { + + case VM_VIDEO_LAYER: + enablemaks = S5P_MXR_VP_INT_ENABLE; + break; + + case VM_GPR0_LAYER: + enablemaks = S5P_MXR_GRP0_INT_ENABLE; + break; + + case VM_GPR1_LAYER: + enablemaks = S5P_MXR_GRP1_INT_ENABLE; + break; + + default: + VMPRINTK("invalid layer parameter = %d\n\r", layer); + return S5P_TV_VMX_ERR_INVALID_PARAM; + break; + } + + if (en) { + writel((readl(mixer_base + S5P_MXR_INT_EN) | enablemaks), + mixer_base + S5P_MXR_INT_EN); + } else { + writel((readl(mixer_base + S5P_MXR_INT_EN) & ~enablemaks), + mixer_base + S5P_MXR_INT_EN); + } + + VMPRINTK("0x%x)\n\r", readl(mixer_base + S5P_MXR_INT_EN)); + + return VMIXER_NO_ERROR; +} + +void __s5p_vm_clear_pend_all(void) +{ + writel(S5P_MXR_INT_FIRED | S5P_MXR_VP_INT_FIRED | + S5P_MXR_GRP0_INT_FIRED | S5P_MXR_GRP1_INT_FIRED, + mixer_base + S5P_MXR_INT_EN); +} + +irqreturn_t __s5p_mixer_irq(int irq, void *dev_id) +{ + bool v_i_f; + bool g0_i_f; + bool g1_i_f; + bool mxr_i_f; + u32 temp_reg = 0; + + v_i_f = (readl(mixer_base + S5P_MXR_INT_STATUS) + & S5P_MXR_VP_INT_FIRED) ? true : false; + g0_i_f = (readl(mixer_base + S5P_MXR_INT_STATUS) + & S5P_MXR_GRP0_INT_FIRED) ? true : false; + g1_i_f = (readl(mixer_base + S5P_MXR_INT_STATUS) + & S5P_MXR_GRP1_INT_FIRED) ? true : false; + mxr_i_f = (readl(mixer_base + S5P_MXR_INT_STATUS) + & S5P_MXR_INT_FIRED) ? true : false; + + if (mxr_i_f) { + temp_reg |= S5P_MXR_INT_FIRED; + + if (v_i_f) { + temp_reg |= S5P_MXR_VP_INT_FIRED; + printk("VP fifo under run!!\n\r"); + } + + if (g0_i_f) { + temp_reg |= S5P_MXR_GRP0_INT_FIRED; + printk("GRP0 fifo under run!!\n\r"); + } + + if (g1_i_f) { + temp_reg |= S5P_MXR_GRP1_INT_FIRED; + printk("GRP1 fifo under run!!\n\r"); + } + + writel(temp_reg, mixer_base + S5P_MXR_INT_STATUS); + } + + return IRQ_HANDLED; +} + +int __init __s5p_mixer_probe(struct platform_device *pdev, u32 res_num) +{ + + struct resource *res; + size_t size; + int ret; + + res = platform_get_resource(pdev, IORESOURCE_MEM, res_num); + + if (res == NULL) { + dev_err(&pdev->dev, + "failed to get memory region resource\n"); + ret = -ENOENT; + + } + + size = (res->end - res->start) + 1; + + mixer_mem = request_mem_region(res->start, size, pdev->name); + + if (mixer_mem == NULL) { + dev_err(&pdev->dev, + "failed to get memory region\n"); + ret = -ENOENT; + + } + + mixer_base = ioremap(res->start, size); + + if (mixer_base == NULL) { + dev_err(&pdev->dev, + "failed to ioremap address region\n"); + ret = -ENOENT; + + + } + + return ret; + +} + +int __init __s5p_mixer_release(struct platform_device *pdev) +{ + iounmap(mixer_base); + + /* remove memory region */ + + if (mixer_mem != NULL) { + if (release_resource(mixer_mem)) + dev_err(&pdev->dev, + "Can't remove tvout drv !!\n"); + + kfree(mixer_mem); + + mixer_mem = NULL; + } + + return 0; +} diff --git a/drivers/media/video/samsung/tv20/s5pc100/vp_coeff_s5pc100.h b/drivers/media/video/samsung/tv20/s5pc100/vp_coeff_s5pc100.h new file mode 100644 index 0000000..3ec0343 --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5pc100/vp_coeff_s5pc100.h @@ -0,0 +1,310 @@ +/* linux/drivers/media/video/samsung/tv20/s5pc100/vp_coeff_s5pc100.h + * + * Video Processor coefficient header file for Samsung TVOut driver + * + * Copyright (c) 2009 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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. +*/ + +/* Horizontal Y 8tap */ +const signed char g_s_vp8tap_coef_y_h[] = { + /* VP_PP_H_NORMAL */ + 0, 0, 0, 0, 127, 0, 0, 0, + 0, 1, -2, 8, 126, -6, 2, -1, + 0, 1, -5, 16, 125, -12, 4, -1, + 0, 2, -8, 25, 121, -16, 5, -1, + -1, 3, -10, 35, 114, -18, 6, -1, + -1, 4, -13, 46, 107, -20, 6, -1, + -1, 5, -16, 57, 99, -21, 6, -1, + -1, 5, -18, 68, 89, -20, 6, -1, + -1, 6, -20, 79, 79, -20, 6, -1, + -1, 6, -20, 89, 68, -18, 5, -1, + -1, 6, -21, 99, 57, -16, 5, -1, + -1, 6, -20, 107, 46, -13, 4, -1, + -1, 6, -18, 114, 35, -10, 3, -1, + -1, 5, -16, 121, 25, -8, 2, 0, + -1, 4, -12, 125, 16, -5, 1, 0, + -1, 2, -6, 126, 8, -2, 1, 0, + + /* VP_PP_H_8_9 */ + 0, 3, -7, 12, 112, 12, -7, 3, + -1, 3, -9, 19, 113, 6, -5, 2, + -1, 3, -11, 27, 111, 0, -3, 2, + -1, 4, -13, 35, 108, -5, -1, 1, + -1, 4, -14, 43, 104, -9, 0, 1, + -1, 5, -16, 52, 99, -12, 1, 0, + -1, 5, -17, 61, 92, -14, 2, 0, + 0, 4, -17, 69, 85, -16, 3, 0, + 0, 4, -17, 77, 77, -17, 4, 0, + 0, 3, -16, 85, 69, -17, 4, 0, + 0, 2, -14, 92, 61, -17, 5, -1, + 0, 1, -12, 99, 52, -16, 5, -1, + 1, 0, -9, 104, 43, -14, 4, -1, + 1, -1, -5, 108, 35, -13, 4, -1, + 2, -3, 0, 111, 27, -11, 3, -1, + 2, -5, 6, 113, 19, -9, 3, -1, + + /* VP_PP_H_1_2 */ + 0, -3, 0, 35, 64, 35, 0, -3, + 0, -3, 1, 38, 64, 32, -1, -3, + 0, -3, 2, 41, 63, 29, -2, -2, + 0, -4, 4, 43, 63, 27, -3, -2, + 0, -4, 5, 46, 62, 24, -3, -2, + 0, -4, 7, 49, 60, 21, -3, -2, + -1, -4, 9, 51, 59, 19, -4, -1, + -1, -4, 12, 53, 57, 16, -4, -1, + -1, -4, 14, 55, 55, 14, -4, -1, + -1, -4, 16, 57, 53, 12, -4, -1, + -1, -4, 19, 59, 51, 9, -4, -1, + -2, -3, 21, 60, 49, 7, -4, 0, + -2, -3, 24, 62, 46, 5, -4, 0, + -2, -3, 27, 63, 43, 4, -4, 0, + -2, -2, 29, 63, 41, 2, -3, 0, + -3, -1, 32, 64, 38, 1, -3, 0, + + /* VP_PP_H_1_3 */ + 0, 0, 10, 32, 44, 32, 10, 0, + -1, 0, 11, 33, 45, 31, 9, 0, + -1, 0, 12, 35, 45, 29, 8, 0, + -1, 1, 13, 36, 44, 28, 7, 0, + -1, 1, 15, 37, 44, 26, 6, 0, + -1, 2, 16, 38, 43, 25, 5, 0, + -1, 2, 18, 39, 43, 23, 5, -1, + -1, 3, 19, 40, 42, 22, 4, -1, + -1, 3, 21, 41, 41, 21, 3, -1, + -1, 4, 22, 42, 40, 19, 3, -1, + -1, 5, 23, 43, 39, 18, 2, -1, + 0, 5, 25, 43, 38, 16, 2, -1, + 0, 6, 26, 44, 37, 15, 1, -1, + 0, 7, 28, 44, 36, 13, 1, -1, + 0, 8, 29, 45, 35, 12, 0, -1, + 0, 9, 31, 45, 33, 11, 0, -1, + + /* VP_PP_H_1_4 */ + 0, 2, 13, 30, 38, 30, 13, 2, + 0, 3, 14, 30, 38, 29, 12, 2, + 0, 3, 15, 31, 38, 28, 11, 2, + 0, 4, 16, 32, 38, 27, 10, 1, + 0, 4, 17, 33, 37, 26, 10, 1, + 0, 5, 18, 34, 37, 24, 9, 1, + 0, 5, 19, 34, 37, 24, 8, 1, + 1, 6, 20, 35, 36, 22, 7, 1, + 1, 6, 21, 36, 36, 21, 6, 1, + 1, 7, 22, 36, 35, 20, 6, 1, + 1, 8, 24, 37, 34, 19, 5, 0, + 1, 9, 24, 37, 34, 18, 5, 0, + 1, 10, 26, 37, 33, 17, 4, 0, + 1, 10, 27, 38, 32, 16, 4, 0, + 2, 11, 28, 38, 31, 15, 3, 0, + 2, 12, 29, 38, 30, 14, 3, 0 +}; + +/* Horizontal C 4tap */ +const signed char g_s_vp4tap_coef_c_h[] = { + /* VP_PP_H_NORMAL */ + 0, 0, 128, 0, + 0, 5, 126, -3, + -1, 11, 124, -6, + -1, 19, 118, -8, + -2, 27, 111, -8, + -3, 37, 102, -8, + -4, 48, 92, -8, + -5, 59, 81, -7, + -6, 70, 70, -6, + -7, 81, 59, -5, + -8, 92, 48, -4, + -8, 102, 37, -3, + -8, 111, 27, -2, + -8, 118, 19, -1, + -6, 124, 11, -1, + -3, 126, 5, 0, + + /* VP_PP_H_8_9 */ + 0, 8, 112, 8, + -1, 13, 113, 3, + -2, 19, 111, 0, + -2, 26, 107, -3, + -3, 34, 101, -4, + -3, 42, 94, -5, + -4, 51, 86, -5, + -5, 60, 78, -5, + -5, 69, 69, -5, + -5, 78, 60, -5, + -5, 86, 51, -4, + -5, 94, 42, -3, + -4, 101, 34, -3, + -3, 107, 26, -2, + 0, 111, 19, -2, + 3, 113, 13, -1, + + /* VP_PP_H_1_2 */ + 0, 26, 76, 26, + 0, 30, 76, 22, + 0, 34, 75, 19, + 1, 38, 73, 16, + 1, 43, 71, 13, + 2, 47, 69, 10, + 3, 51, 66, 8, + 4, 55, 63, 6, + 5, 59, 59, 5, + 6, 63, 55, 4, + 8, 66, 51, 3, + 10, 69, 47, 2, + 13, 71, 43, 1, + 16, 73, 38, 1, + 19, 75, 34, 0, + 22, 76, 30, 0, + + /* VP_PP_H_1_3 */ + 0, 30, 68, 30, + 2, 33, 66, 27, + 3, 36, 66, 23, + 3, 39, 65, 21, + 4, 43, 63, 18, + 5, 46, 62, 15, + 6, 49, 60, 13, + 8, 52, 57, 11, + 9, 55, 55, 9, + 11, 57, 52, 8, + 13, 60, 49, 6, + 15, 62, 46, 5, + 18, 63, 43, 4, + 21, 65, 39, 3, + 23, 66, 36, 3, + 27, 66, 33, 2, + + /* VP_PP_H_1_4 */ + 0, 31, 66, 31, + 3, 34, 63, 28, + 4, 37, 62, 25, + 4, 40, 62, 22, + 5, 43, 61, 19, + 6, 46, 59, 17, + 7, 48, 58, 15, + 9, 51, 55, 13, + 11, 53, 53, 11, + 13, 55, 51, 9, + 15, 58, 48, 7, + 17, 59, 46, 6, + 19, 61, 43, 5, + 22, 62, 40, 4, + 25, 62, 37, 4, + 28, 63, 34, 3, +}; + + +/* Vertical Y 8tap */ +const signed char g_s_vp4tap_coef_y_v[] = { + /* VP_PP_V_NORMAL */ + 0, 0, 127, 0, + 0, 5, 126, -3, + -1, 11, 124, -6, + -1, 19, 118, -8, + -2, 27, 111, -8, + -3, 37, 102, -8, + -4, 48, 92, -8, + -5, 59, 81, -7, + -6, 70, 70, -6, + -7, 81, 59, -5, + -8, 92, 48, -4, + -8, 102, 37, -3, + -8, 111, 27, -2, + -8, 118, 19, -1, + -6, 124, 11, -1, + -3, 126, 5, 0, + + /* VP_PP_V_5_6 */ + 0, 11, 106, 11, + -2, 16, 107, 7, + -2, 22, 105, 3, + -2, 29, 101, 0, + -3, 36, 96, -1, + -3, 44, 90, -3, + -4, 52, 84, -4, + -4, 60, 76, -4, + -4, 68, 68, -4, + -4, 76, 60, -4, + -4, 84, 52, -4, + -3, 90, 44, -3, + -1, 96, 36, -3, + 0, 101, 29, -2, + 3, 105, 22, -2, + 7, 107, 16, -2, + + /* VP_PP_V_3_4 */ + 0, 15, 98, 15, + -2, 21, 97, 12, + -2, 26, 96, 8, + -2, 32, 93, 5, + -2, 39, 89, 2, + -2, 46, 84, 0, + -3, 53, 79, -1, + -2, 59, 73, -2, + -2, 66, 66, -2, + -2, 73, 59, -2, + -1, 79, 53, -3, + 0, 84, 46, -2, + 2, 89, 39, -2, + 5, 93, 32, -2, + 8, 96, 26, -2, + 12, 97, 21, -2, + + /* VP_PP_V_1_2 */ + 0, 26, 76, 26, + 0, 30, 76, 22, + 0, 34, 75, 19, + 1, 38, 73, 16, + 1, 43, 71, 13, + 2, 47, 69, 10, + 3, 51, 66, 8, + 4, 55, 63, 6, + 5, 59, 59, 5, + 6, 63, 55, 4, + 8, 66, 51, 3, + 10, 69, 47, 2, + 13, 71, 43, 1, + 16, 73, 38, 1, + 19, 75, 34, 0, + 22, 76, 30, 0, + + /* VP_PP_V_1_3 */ + 0, 30, 68, 30, + 2, 33, 66, 27, + 3, 36, 66, 23, + 3, 39, 65, 21, + 4, 43, 63, 18, + 5, 46, 62, 15, + 6, 49, 60, 13, + 8, 52, 57, 11, + 9, 55, 55, 9, + 11, 57, 52, 8, + 13, 60, 49, 6, + 15, 62, 46, 5, + 18, 63, 43, 4, + 21, 65, 39, 3, + 23, 66, 36, 3, + 27, 66, 33, 2, + + /* VP_PP_V_1_4 */ + 0, 31, 66, 31, + 3, 34, 63, 28, + 4, 37, 62, 25, + 4, 40, 62, 22, + 5, 43, 61, 19, + 6, 46, 59, 17, + 7, 48, 58, 15, + 9, 51, 55, 13, + 11, 53, 53, 11, + 13, 55, 51, 9, + 15, 58, 48, 7, + 17, 59, 46, 6, + 19, 61, 43, 5, + 22, 62, 40, 4, + 25, 62, 37, 4, + 28, 63, 34, 3 +}; + diff --git a/drivers/media/video/samsung/tv20/s5pc100/vprocessor_s5pc100.c b/drivers/media/video/samsung/tv20/s5pc100/vprocessor_s5pc100.c new file mode 100644 index 0000000..6a2a7ef --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5pc100/vprocessor_s5pc100.c @@ -0,0 +1,809 @@ +/* linux/drivers/media/video/samsung/tv20/s5pc100/vprocessor_s5pc100.c + * + * Video Processor raw ftn file for Samsung TVOut driver + * + * Copyright (c) 2009 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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/io.h> + +#include "tv_out_s5pc100.h" + +#include "regs/regs-vprocessor.h" +#include "vp_coeff_s5pc100.h" + +#ifdef COFIG_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 __s5p_vp_update() function +* for update shadow registers +*/ +void __s5p_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 __s5p_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 __s5p_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; +} + + +enum s5p_tv_vp_err __s5p_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 / 2)) { + 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 __s5p_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 __s5p_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 __s5p_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 __s5p_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 __s5p_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 <= (0x1 << 16)) { /* 720->720 or zoom in */ + e_h_filter = VPROC_PP_H_NORMAL; + } + + else if (h_ratio <= (0x9 << 13)) /* 720->640 */ + e_h_filter = VPROC_PP_H_8_9 ; + + else if (h_ratio <= (0x1 << 17)) /* 2->1 */ + e_h_filter = VPROC_PP_H_1_2; + + else if (h_ratio <= (0x3 << 16)) /* 2->1 */ + e_h_filter = VPROC_PP_H_1_3; + else + e_h_filter = VPROC_PP_H_1_4; /* 4->1 */ + + /* Vertical Y 4tap */ + if (v_ratio <= (0x1 << 16)) /* 720->720 or zoom in*/ + e_v_filter = VPROC_PP_V_NORMAL; + else if (v_ratio <= (0x3 << 15)) /* 6->5*/ + e_v_filter = VPROC_PP_V_5_6; + else if (v_ratio <= (0x5 << 14)) /* 4->3*/ + e_v_filter = VPROC_PP_V_3_4; + 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 /* 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++) { + __s5p_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++) { + __s5p_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++) { + __s5p_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 __s5p_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); + + __s5p_vp_set_src_dest_size(src_width, src_height, dst_width, + dst_height, ipc_2d); + __s5p_vp_set_poly_filter_coef_default(h_ratio, v_ratio); +} + +enum s5p_tv_vp_err __s5p_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 __s5p_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 __s5p_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 __s5p_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; +} + +/* +* get - get info +*/ +enum s5p_vp_field __s5p_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; +} + +/* +* etc +*/ +unsigned short __s5p_vp_get_update_status(void) +{ + VPPRINTK("()\n\r"); + return readl(vp_base + S5P_VP_SHADOW_UPDATE) & + S5P_VP_SHADOW_UPDATE_ENABLE; +} + + +void __s5p_vp_init_field_id(enum s5p_vp_field mode) +{ + __s5p_vp_set_field_id(mode); +} + +void __s5p_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 __s5p_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 __s5p_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 = __s5p_vp_set_top_field_address(top_y_addr, top_c_addr); + + if (error != VPROC_NO_ERROR) + return error; + + error = __s5p_vp_set_bottom_field_address(bottom_y_addr, + bottom_c_addr); + + if (error != VPROC_NO_ERROR) + return error; + + error = __s5p_vp_set_img_size(img_width, img_height); + + if (error != VPROC_NO_ERROR) + return error; + + __s5p_vp_set_src_position(src_off_x, src_x_fract_step, src_off_y); + + __s5p_vp_set_dest_position(dst_off_x, dst_off_y); + + __s5p_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 __s5p_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); + + __s5p_vp_set_poly_filter_coef_default(h_ratio, v_ratio); + error = __s5p_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 __s5p_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 __s5p_vp_set_poly_filter_coef(poly_coeff, ch0, ch1, ch2, ch3); +} + +void __s5p_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 __s5p_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 __s5p_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 __s5p_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 __s5p_vp_init_brightness_contrast_control( + enum s5p_vp_line_eq eq_num, u32 intc, u32 slope) +{ + return __s5p_vp_set_brightness_contrast_control(eq_num, intc, slope); +} + +void __s5p_vp_init_brightness(bool brightness) +{ + __s5p_vp_set_brightness(brightness); +} + + +void __s5p_vp_init_contrast(u8 contrast) +{ + __s5p_vp_set_contrast(contrast); +} + +void __s5p_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 __s5p_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 __s5p_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; + break; + } + + 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 __s5p_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 = __s5p_vp_update(); + + VPPRINTK("()\n\r"); + return error; +} + +/* +* stop - stop functions are only called under running video processor +*/ +enum s5p_tv_vp_err __s5p_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 = __s5p_vp_update(); + + while (!(readl(vp_base + S5P_VP_ENABLE) & VP_POWER_DOWN_RDY)) + msleep(1); + + + return error; +} + +/* +* reset - reset function +*/ +void __s5p_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 __s5p_vp_probe(struct platform_device *pdev, u32 res_num) +{ + + struct resource *res; + size_t size; + int ret; + + res = platform_get_resource(pdev, IORESOURCE_MEM, res_num); + + if (res == NULL) { + dev_err(&pdev->dev, + "failed to get memory region resource\n"); + ret = -ENOENT; + + } + + 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"); + ret = -ENOENT; + + } + + vp_base = ioremap(res->start, size); + + if (vp_base == NULL) { + dev_err(&pdev->dev, + "failed to ioremap address region\n"); + ret = -ENOENT; + + + } + + return ret; + +} + +int __init __s5p_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; +} + diff --git a/drivers/media/video/samsung/tv20/s5pv210/cec_s5pv210.c b/drivers/media/video/samsung/tv20/s5pv210/cec_s5pv210.c new file mode 100644 index 0000000..91568d8 --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5pv210/cec_s5pv210.c @@ -0,0 +1,294 @@ +/* linux/drivers/media/video/samsung/tv20/s5pv210/cec_s5pv210.c + * + * cec ftn file for Samsung TVOut driver + * + * Copyright (c) 2010 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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/io.h> + +#include <mach/map.h> +#include <mach/regs-clock.h> +#include "regs/regs-cec.h" +#include <linux/slab.h> +#include <linux/mm.h> + +#include "../cec.h" + +#ifdef CECDEBUG +#define CECPRINTK(fmt, args...) \ + printk(KERN_INFO "\t\t[CEC] %s: " fmt, __func__ , ## args) +#else +#define CECPRINTK(fmt, args...) +#endif + +static struct resource *cec_mem; +void __iomem *cec_base; + +#define S5P_HDMI_FIN 24000000 +#define CEC_DIV_RATIO 187500 + +/** + * Set CEC divider value. + */ +void __s5p_cec_set_divider(void) +{ + u32 div_ratio, reg, div_val; + + div_ratio = S5P_HDMI_FIN/CEC_DIV_RATIO - 1; + + reg = readl(S5P_HDMI_PHY_CONTROL); + reg = (reg & ~(0x3FF<<16)) | (div_ratio << 16); + + writel(reg, S5P_HDMI_PHY_CONTROL); + + div_val = CEC_DIV_RATIO * 0.00005 - 1; + + writeb(0x0, cec_base + CEC_DIVISOR_3); + writeb(0x0, cec_base + CEC_DIVISOR_2); + writeb(0x0, cec_base + CEC_DIVISOR_1); + writeb(div_val, cec_base + CEC_DIVISOR_0); + + CECPRINTK("CEC_DIVISOR_3 = 0x%08x\n", readb(cec_base + CEC_DIVISOR_3)); + CECPRINTK("CEC_DIVISOR_2 = 0x%08x\n", readb(cec_base + CEC_DIVISOR_2)); + CECPRINTK("CEC_DIVISOR_1 = 0x%08x\n", readb(cec_base + CEC_DIVISOR_1)); + CECPRINTK("CEC_DIVISOR_0 = 0x%08x\n", readb(cec_base + CEC_DIVISOR_0)); +} + +/** + * Enable CEC Rx engine + */ +void __s5p_cec_enable_rx(void) +{ + u8 reg; + reg = readb(cec_base + CEC_RX_CTRL); + reg |= CEC_RX_CTRL_ENABLE; + writeb(reg, cec_base + CEC_RX_CTRL); + + CECPRINTK("CEC_RX_CTRL = 0x%08x \n", readb(cec_base + CEC_RX_CTRL)); +} + +/** + * Mask CEC Rx interrupts + */ +void __s5p_cec_mask_rx_interrupts(void) +{ + u8 reg; + reg = readb(cec_base + CEC_IRQ_MASK); + reg |= CEC_IRQ_RX_DONE; + reg |= CEC_IRQ_RX_ERROR; + writeb(reg, cec_base + CEC_IRQ_MASK); + + CECPRINTK("CEC_IRQ_MASK = 0x%08x \n", readb(cec_base + CEC_IRQ_MASK)); +} + +/** + * Unmask CEC Rx interrupts + */ +void __s5p_cec_unmask_rx_interrupts(void) +{ + u8 reg; + reg = readb(cec_base + CEC_IRQ_MASK); + reg &= ~CEC_IRQ_RX_DONE; + reg &= ~CEC_IRQ_RX_ERROR; + writeb(reg, cec_base + CEC_IRQ_MASK); + + CECPRINTK("CEC_IRQ_MASK = 0x%08x \n", readb(cec_base + CEC_IRQ_MASK)); +} + +/** + * Mask CEC Tx interrupts + */ +void __s5p_cec_mask_tx_interrupts(void) +{ + u8 reg; + reg = readb(cec_base + CEC_IRQ_MASK); + reg |= CEC_IRQ_TX_DONE; + reg |= CEC_IRQ_TX_ERROR; + writeb(reg, cec_base + CEC_IRQ_MASK); + + CECPRINTK("CEC_IRQ_MASK = 0x%08x \n", readb(cec_base + CEC_IRQ_MASK)); + +} + +/** + * Unmask CEC Tx interrupts + */ +void __s5p_cec_unmask_tx_interrupts(void) +{ + u8 reg; + reg = readb(cec_base + CEC_IRQ_MASK); + reg &= ~CEC_IRQ_TX_DONE; + reg &= ~CEC_IRQ_TX_ERROR; + writeb(reg, cec_base + CEC_IRQ_MASK); + + CECPRINTK("CEC_IRQ_MASK = 0x%08x \n", readb(cec_base + CEC_IRQ_MASK)); +} + +void __s5p_cec_reset(void) +{ + writeb(CEC_RX_CTRL_RESET, cec_base + CEC_RX_CTRL); + writeb(CEC_TX_CTRL_RESET, cec_base + CEC_TX_CTRL); + + CECPRINTK("CEC_RX_CTRL = 0x%08x \n", readb(cec_base + CEC_RX_CTRL)); + CECPRINTK("CEC_TX_CTRL = 0x%08x \n", readb(cec_base + CEC_TX_CTRL)); +} + +void __s5p_cec_tx_reset(void) +{ + writeb(CEC_TX_CTRL_RESET, cec_base + CEC_TX_CTRL); + + CECPRINTK("CEC_TX_CTRL = 0x%08x \n", readb(cec_base + CEC_TX_CTRL)); +} + +void __s5p_cec_rx_reset(void) +{ + writeb(CEC_RX_CTRL_RESET, cec_base + CEC_RX_CTRL); + CECPRINTK("CEC_RX_CTRL = 0x%08x \n", readb(cec_base + CEC_RX_CTRL)); +} + +void __s5p_cec_threshold(void) +{ + writeb(CEC_FILTER_THRESHOLD, cec_base + CEC_RX_FILTER_TH); + writeb(0, cec_base + CEC_RX_FILTER_CTRL); + CECPRINTK("CEC_RX_FILTER_TH = 0x%08x \n", + readb(cec_base + CEC_RX_FILTER_TH)); +} + +void __s5p_cec_copy_packet(char *data, size_t count) +{ + int i = 0; + u8 reg; + /* copy packet to hardware buffer */ + while (i < count) { + writeb(data[i], cec_base + (CEC_TX_BUFF0 + (i*4))); + i++; + } + + /* set number of bytes to transfer */ + writeb(count, cec_base + CEC_TX_BYTES); + + __s5p_cec_set_tx_state(STATE_TX); + + /* start transfer */ + reg = readb(cec_base + CEC_TX_CTRL); + + reg |= CEC_TX_CTRL_START; + + /* if message is broadcast message - set corresponding bit */ + if ((data[0] & CEC_MESSAGE_BROADCAST_MASK) == CEC_MESSAGE_BROADCAST) + reg |= CEC_TX_CTRL_BCAST; + else + reg &= ~CEC_TX_CTRL_BCAST; + + /* set number of retransmissions */ + reg |= 0x50; + + writeb(reg, cec_base + CEC_TX_CTRL); +} + +void __s5p_cec_set_addr(u32 addr) +{ + writeb(addr & 0x0F, cec_base + CEC_LOGIC_ADDR); + +} + +u32 __s5p_cec_get_status(void) +{ + u32 status = 0; + + status = readb(cec_base + CEC_STATUS_0); + status |= readb(cec_base + CEC_STATUS_1) << 8; + status |= readb(cec_base + CEC_STATUS_2) << 16; + status |= readb(cec_base + CEC_STATUS_3) << 24; + + CECPRINTK("status = 0x%x!\n", status); + + return status; +} + +void __s5p_clr_pending_tx(void) +{ + /* clear interrupt pending bit */ + writeb(CEC_IRQ_TX_DONE | CEC_IRQ_TX_ERROR, cec_base + CEC_IRQ_CLEAR); +} + +void __s5p_clr_pending_rx(void) +{ + /* clear interrupt pending bit */ + writeb(CEC_IRQ_RX_DONE | CEC_IRQ_RX_ERROR, cec_base + CEC_IRQ_CLEAR); +} + +void __s5p_cec_get_rx_buf(u32 size, u8 *buffer) +{ + u32 i = 0; + + while (i < size) { + buffer[i] = readb(cec_base + CEC_RX_BUFF0 + (i * 4)); + i++; + } +} + +void __init __s5p_cec_probe(struct platform_device *pdev) +{ + struct resource *res; + size_t size; + int ret; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + if (res == NULL) { + dev_err(&pdev->dev, + "failed to get memory region resource for cec\n"); + ret = -ENOENT; + + } + + size = (res->end - res->start) + 1; + + cec_mem = request_mem_region(res->start, size, pdev->name); + + if (cec_mem == NULL) { + dev_err(&pdev->dev, + "failed to get memory region for cec\n"); + ret = -ENOENT; + + } + + cec_base = ioremap(res->start, size); + + if (cec_base == NULL) { + dev_err(&pdev->dev, + "failed to ioremap address region for cec\n"); + ret = -ENOENT; + + + } + +} + +int __init __s5p_cec_release(struct platform_device *pdev) +{ + iounmap(cec_base); + + /* remove memory region */ + if (cec_mem != NULL) { + if (release_resource(cec_mem)) + dev_err(&pdev->dev, + "Can't remove tvout drv !!\n"); + + kfree(cec_mem); + + cec_mem = NULL; + } + + return 0; +} + diff --git a/drivers/media/video/samsung/tv20/s5pv210/cec_s5pv210.h b/drivers/media/video/samsung/tv20/s5pv210/cec_s5pv210.h new file mode 100644 index 0000000..a5e6abf --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5pv210/cec_s5pv210.h @@ -0,0 +1,23 @@ +/* linux/drivers/media/video/samsung/tv20/s5pv210/cec_s5pv210.h + * + * cec ftn header for Samsung TVOut driver + * + * Copyright (c) 2010 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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. +*/ + +#ifndef _LINUX_CEC_H_ +#define _LINUX_CEC_H_ + +#define CEC_IOC_MAGIC 'c' + +/** + * CEC device request code to set logical address. + */ +#define CEC_IOC_SETLADDR _IOW(CEC_IOC_MAGIC, 0, unsigned int) + +#endif /* _LINUX_CEC_H_ */ diff --git a/drivers/media/video/samsung/tv20/s5pv210/hdcp_s5pv210.c b/drivers/media/video/samsung/tv20/s5pv210/hdcp_s5pv210.c new file mode 100644 index 0000000..25ab4c5 --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5pv210/hdcp_s5pv210.c @@ -0,0 +1,1790 @@ +/* linux/drivers/media/video/samsung/tv20/s5pv210/hdcp_s5pv210.c + * + * hdcp raw ftn file for Samsung TVOut driver + * + * Copyright (c) 2010 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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/delay.h> +#include <linux/device.h> +#include <linux/wait.h> +#include <linux/interrupt.h> +#include <linux/workqueue.h> +#include <linux/delay.h> +#include <linux/i2c.h> +#include <linux/irq.h> +#include <linux/io.h> + +#include <plat/gpio-cfg.h> + +#include <mach/regs-gpio.h> +#include <mach/gpio.h> + +#include "../ddc.h" +#include "tv_out_s5pv210.h" +#include "regs/regs-hdmi.h" + +/* for Operation check */ +#ifdef COFIG_TVOUT_RAW_DBG +#define S5P_HDCP_DEBUG 1 +#define S5P_HDCP_I2C_DEBUG 1 +#define S5P_HDCP_AUTH_DEBUG 1 +#endif + +#ifdef S5P_HDCP_DEBUG +#define HDCPPRINTK(fmt, args...) \ + printk(KERN_INFO "\t\t[HDCP] %s: " fmt, __func__ , ## args) +#else +#define HDCPPRINTK(fmt, args...) +#endif + +/* for authentication key check */ +#ifdef S5P_HDCP_AUTH_DEBUG +#define AUTHPRINTK(fmt, args...) \ + printk("\t\t\t[AUTHKEY] %s: " fmt, __func__ , ## args) +#else +#define AUTHPRINTK(fmt, args...) +#endif + +enum hdmi_run_mode { + DVI_MODE, + HDMI_MODE +}; + +enum hdmi_resolution { + SD480P, + SD480I, + WWSD480P, + HD720P, + SD576P, + WWSD576P, + HD1080I +}; + +enum hdmi_color_bar_type { + HORIZONTAL, + VERTICAL +}; + +enum hdcp_event { + /* Stop HDCP */ + HDCP_EVENT_STOP, + /* Start HDCP*/ + HDCP_EVENT_START, + /* Start to read Bksv, Bcaps */ + HDCP_EVENT_READ_BKSV_START, + /* Start to write Aksv, An */ + HDCP_EVENT_WRITE_AKSV_START, + /* Start to check if Ri is equal to Rj */ + HDCP_EVENT_CHECK_RI_START, + /* Start 2nd authentication process */ + HDCP_EVENT_SECOND_AUTH_START +}; + +enum hdcp_state { + NOT_AUTHENTICATED, + RECEIVER_READ_READY, + BCAPS_READ_DONE, + BKSV_READ_DONE, + AN_WRITE_DONE, + AKSV_WRITE_DONE, + FIRST_AUTHENTICATION_DONE, + SECOND_AUTHENTICATION_RDY, + RECEIVER_FIFOLSIT_READY, + SECOND_AUTHENTICATION_DONE, +}; + +/* + * Below CSC_TYPE is temporary. CSC_TYPE enum. + * may be included in SetSD480pVars_60Hz etc. + * + * LR : Limited Range (16~235) + * FR : Full Range (0~255) + */ +enum hdmi_intr_src { + WAIT_FOR_ACTIVE_RX, + WDT_FOR_REPEATER, + EXCHANGE_KSV, + UPDATE_P_VAL, + UPDATE_R_VAL, + AUDIO_OVERFLOW, + AUTHEN_ACK, + UNKNOWN_INT +}; + +struct s5p_hdcp_info { + bool is_repeater; + bool hpd_status; + u32 time_out; + u32 hdcp_enable; + + spinlock_t lock; + spinlock_t reset_lock; + + struct i2c_client *client; + + wait_queue_head_t waitq; + enum hdcp_event event; + enum hdcp_state auth_status; + + struct work_struct work; +}; + +static struct s5p_hdcp_info hdcp_info = { + .is_repeater = false, + .time_out = 0, + .hdcp_enable = false, + .client = NULL, + .event = HDCP_EVENT_STOP, + .auth_status = NOT_AUTHENTICATED, + +}; + +#define HDCP_RI_OFFSET 0x08 +#define INFINITE 0xffffffff + +#define HDMI_SYS_ENABLE (1 << 0) +#define HDMI_ASP_ENABLE (1 << 2) +#define HDMI_ASP_DISABLE (~HDMI_ASP_ENABLE) + +#define MAX_DEVS_EXCEEDED (0x1 << 7) +#define MAX_CASCADE_EXCEEDED (0x1 << 3) + +#define MAX_CASCADE_EXCEEDED_ERROR (-1) +#define MAX_DEVS_EXCEEDED_ERROR (-2) +#define REPEATER_ILLEGAL_DEVICE_ERROR (-3) +#define REPEATER_TIMEOUT_ERROR (-4) + +#define AINFO_SIZE 1 +#define BCAPS_SIZE 1 +#define BSTATUS_SIZE 2 +#define SHA_1_HASH_SIZE 20 + +#define KSV_FIFO_READY (0x1 << 5) + +/* spmoon for test : it's not in manual */ +#define SET_HDCP_KSV_WRITE_DONE (0x1 << 3) +#define CLEAR_HDCP_KSV_WRITE_DONE (~SET_HDCP_KSV_WRITE_DONE) + +#define SET_HDCP_KSV_LIST_EMPTY (0x1 << 2) +#define CLEAR_HDCP_KSV_LIST_EMPTY (~SET_HDCP_KSV_LIST_EMPTY) +#define SET_HDCP_KSV_END (0x1 << 1) +#define CLEAR_HDCP_KSV_END (~SET_HDCP_KSV_END) +#define SET_HDCP_KSV_READ (0x1 << 0) +#define CLEAR_HDCP_KSV_READ (~SET_HDCP_KSV_READ) + +#define SET_HDCP_SHA_VALID_READY (0x1 << 1) +#define CLEAR_HDCP_SHA_VALID_READY (~SET_HDCP_SHA_VALID_READY) +#define SET_HDCP_SHA_VALID (0x1 << 0) +#define CLEAR_HDCP_SHA_VALID (~SET_HDCP_SHA_VALID) + +#define TRANSMIT_EVERY_VSYNC (0x1 << 1) + +/* must be checked */ +static bool sw_reset; +static bool is_dvi; +static bool av_mute; +static bool audio_en; + +void s5p_hdmi_set_audio(bool en) +{ + if (en) + audio_en = true; + else + audio_en = false; +} + +int s5p_hdcp_is_reset(void) +{ + int ret = 0; + + if (spin_is_locked(&hdcp_info.reset_lock)) + return 1; + + return ret; +} + +int s5p_hdmi_set_dvi(bool en) +{ + if (en) + is_dvi = true; + else + is_dvi = false; + + return 0; +} + +int s5p_hdmi_set_mute(bool en) +{ + if (en) + av_mute = true; + else + av_mute = false; + + return 0; +} + +int s5p_hdmi_get_mute(void) +{ + return av_mute ? true : false; +} + +int s5p_hdmi_audio_enable(bool en) +{ + u8 reg; + + if (!is_dvi) { + reg = readl(hdmi_base + S5P_HDMI_CON_0); + + if (en) { + reg |= ASP_EN; + writel(HDMI_TRANS_EVERY_SYNC , hdmi_base + S5P_AUI_CON); + } else { + reg &= ~ASP_EN; + writel(HDMI_DO_NOT_TANS , hdmi_base + S5P_AUI_CON); + } + + writel(reg, hdmi_base + S5P_HDMI_CON_0); + } + + return 0; +} + +void s5p_hdmi_mute_en(bool en) +{ + if (!av_mute) { + if (en) { + __s5p_hdmi_video_set_bluescreen(true, 0, 0, 0); + s5p_hdmi_audio_enable(false); + } else { + __s5p_hdmi_video_set_bluescreen(false, 0, 0, 0); + if (audio_en) + s5p_hdmi_audio_enable(true); + } + } +} + +/* + * 1st Authentication step func. + * Write the Ainfo data to Rx + */ +static bool write_ainfo(void) +{ + int ret = 0; + u8 ainfo[2]; + + ainfo[0] = HDCP_Ainfo; + ainfo[1] = 0; + + ret = ddc_write(ainfo, 2); + if (ret < 0) + HDCPPRINTK("Can't write ainfo data through i2c bus\n"); + + return (ret < 0) ? false : true; +} + +/* + * Write the An data to Rx + */ +static bool write_an(void) +{ + int ret = 0; + u8 an[AN_SIZE+1]; + + an[0] = HDCP_An; + + an[1] = readb(hdmi_base + S5P_HDCP_An_0_0); + an[2] = readb(hdmi_base + S5P_HDCP_An_0_1); + an[3] = readb(hdmi_base + S5P_HDCP_An_0_2); + an[4] = readb(hdmi_base + S5P_HDCP_An_0_3); + an[5] = readb(hdmi_base + S5P_HDCP_An_1_0); + an[6] = readb(hdmi_base + S5P_HDCP_An_1_1); + an[7] = readb(hdmi_base + S5P_HDCP_An_1_2); + an[8] = readb(hdmi_base + S5P_HDCP_An_1_3); + + ret = ddc_write(an, AN_SIZE + 1); + if (ret < 0) + HDCPPRINTK("Can't write an data through i2c bus\n"); + +#ifdef S5P_HDCP_AUTH_DEBUG + { + u16 i = 0; + for (i = 1; i < AN_SIZE + 1; i++) + AUTHPRINTK("HDCPAn[%d]: 0x%x \n", i, an[i]); + + } +#endif + + return (ret < 0) ? false : true; +} + +/* + * Write the Aksv data to Rx + */ +static bool write_aksv(void) +{ + int ret = 0; + u8 aksv[AKSV_SIZE+1]; + + aksv[0] = HDCP_Aksv; + + aksv[1] = readb(hdmi_base + S5P_HDCP_AKSV_0_0); + aksv[2] = readb(hdmi_base + S5P_HDCP_AKSV_0_1); + aksv[3] = readb(hdmi_base + S5P_HDCP_AKSV_0_2); + aksv[4] = readb(hdmi_base + S5P_HDCP_AKSV_0_3); + aksv[5] = readb(hdmi_base + S5P_HDCP_AKSV_1); + + if (aksv[1] == 0 && + aksv[2] == 0 && + aksv[3] == 0 && + aksv[4] == 0 && + aksv[5] == 0) + return false; + + ret = ddc_write(aksv, AKSV_SIZE + 1); + if (ret < 0) + HDCPPRINTK("Can't write aksv data through i2c bus\n"); + +#ifdef S5P_HDCP_AUTH_DEBUG + { + u16 i = 0; + for (i = 1; i < AKSV_SIZE + 1; i++) + AUTHPRINTK("HDCPAksv[%d]: 0x%x\n", i, aksv[i]); + + } +#endif + + return (ret < 0) ? false : true; +} + +static bool read_bcaps(void) +{ + int ret = 0; + u8 bcaps[BCAPS_SIZE] = {0}; + + ret = ddc_read(HDCP_Bcaps, bcaps, BCAPS_SIZE); + + if (ret < 0) { + HDCPPRINTK("Can't read bcaps data from i2c bus\n"); + return false; + } + + writel(bcaps[0], hdmi_base + S5P_HDCP_BCAPS); + + HDCPPRINTK("BCAPS(from i2c) : 0x%08x\n", bcaps[0]); + + if (bcaps[0] & REPEATER_SET) + hdcp_info.is_repeater = true; + else + hdcp_info.is_repeater = false; + + HDCPPRINTK("attached device type : %s !! \n\r", + hdcp_info.is_repeater ? "REPEATER" : "SINK"); + HDCPPRINTK("BCAPS(from sfr) = 0x%08x\n", + readl(hdmi_base + S5P_HDCP_BCAPS)); + + return true; +} + +static bool read_again_bksv(void) +{ + u8 bk_sv[BKSV_SIZE] = {0, 0, 0, 0, 0}; + u8 i = 0; + u8 j = 0; + u32 no_one = 0; + u32 no_zero = 0; + u32 result = 0; + int ret = 0; + + ret = ddc_read(HDCP_Bksv, bk_sv, BKSV_SIZE); + + if (ret < 0) { + HDCPPRINTK("Can't read bk_sv data from i2c bus\n"); + return false; + } + +#ifdef S5P_HDCP_AUTH_DEBUG + for (i = 0; i < BKSV_SIZE; i++) + AUTHPRINTK("i2c read : Bksv[%d]: 0x%x\n", i, bk_sv[i]); +#endif + + for (i = 0; i < BKSV_SIZE; i++) { + + for (j = 0; j < 8; j++) { + + result = bk_sv[i] & (0x1 << j); + + if (result == 0) + no_zero += 1; + else + no_one += 1; + } + } + + if ((no_zero == 20) && (no_one == 20)) { + HDCPPRINTK("Suucess: no_zero, and no_one is 20\n"); + + writel(bk_sv[0], hdmi_base + S5P_HDCP_BKSV_0_0); + writel(bk_sv[1], hdmi_base + S5P_HDCP_BKSV_0_1); + writel(bk_sv[2], hdmi_base + S5P_HDCP_BKSV_0_2); + writel(bk_sv[3], hdmi_base + S5P_HDCP_BKSV_0_3); + writel(bk_sv[4], hdmi_base + S5P_HDCP_BKSV_1); + +#ifdef S5P_HDCP_AUTH_DEBUG + for (i = 0; i < BKSV_SIZE; i++) + AUTHPRINTK("set reg : Bksv[%d]: 0x%x\n", i, bk_sv[i]); + + /* + writel(HDCP_ENC_ENABLE, hdmi_base + S5P_ENC_EN); + */ +#endif + return true; + } else { + HDCPPRINTK("Failed: no_zero or no_one is NOT 20\n"); + return false; + } +} + +static bool read_bksv(void) +{ + u8 bk_sv[BKSV_SIZE] = {0, 0, 0, 0, 0}; + + int i = 0; + int j = 0; + + u32 no_one = 0; + u32 no_zero = 0; + u32 result = 0; + u32 count = 0; + int ret = 0; + + ret = ddc_read(HDCP_Bksv, bk_sv, BKSV_SIZE); + + if (ret < 0) { + HDCPPRINTK("Can't read bk_sv data from i2c bus\n"); + return false; + } + +#ifdef S5P_HDCP_AUTH_DEBUG + for (i = 0; i < BKSV_SIZE; i++) + AUTHPRINTK("i2c read : Bksv[%d]: 0x%x\n", i, bk_sv[i]); +#endif + + for (i = 0; i < BKSV_SIZE; i++) { + + for (j = 0; j < 8; j++) { + + result = bk_sv[i] & (0x1 << j); + + if (result == 0) + no_zero++; + else + no_one++; + } + } + + if ((no_zero == 20) && (no_one == 20)) { + + writel(bk_sv[0], hdmi_base + S5P_HDCP_BKSV_0_0); + writel(bk_sv[1], hdmi_base + S5P_HDCP_BKSV_0_1); + writel(bk_sv[2], hdmi_base + S5P_HDCP_BKSV_0_2); + writel(bk_sv[3], hdmi_base + S5P_HDCP_BKSV_0_3); + writel(bk_sv[4], hdmi_base + S5P_HDCP_BKSV_1); + +#ifdef S5P_HDCP_AUTH_DEBUG + for (i = 0; i < BKSV_SIZE; i++) + AUTHPRINTK("set reg : Bksv[%d]: 0x%x\n", i, bk_sv[i]); +#endif + + HDCPPRINTK("Success: no_zero, and no_one is 20\n"); + + } else { + + HDCPPRINTK("Failed: no_zero or no_one is NOT 20\n"); + + while (!read_again_bksv()) { + + count++; + + mdelay(200); + + if (count == 14) + return false; + } + } + + return true; +} + +/* + * Compare the R value of Tx with that of Rx + */ +static bool compare_r_val(void) +{ + int ret = 0; + u8 ri[2] = {0, 0}; + u8 rj[2] = {0, 0}; + u16 i; + + for (i = 0; i < R_VAL_RETRY_CNT; i++) { + + if (hdcp_info.auth_status < AKSV_WRITE_DONE) { + ret = false; + break; + } + + /* Read R value from Tx */ + ri[0] = readl(hdmi_base + S5P_HDCP_Ri_0); + ri[1] = readl(hdmi_base + S5P_HDCP_Ri_1); + + /* Read R value from Rx */ + ret = ddc_read(HDCP_Ri, rj, 2); + if (ret < 0) { + HDCPPRINTK("Can't read r data from i2c bus\n"); + return false; + } + +#ifdef S5P_HDCP_AUTH_DEBUG + AUTHPRINTK("retries :: %d\n", i); + printk(KERN_INFO "\t\t\t Rx(ddc) ->"); + printk(KERN_INFO "rj[0]: 0x%02x, rj[1]: 0x%02x\n", + rj[0], rj[1]); + printk(KERN_INFO "\t\t\t Tx(register) ->"); + printk(KERN_INFO "ri[0]: 0x%02x, ri[1]: 0x%02x\n", + ri[0], ri[1]); +#endif + + /* Compare R value */ + if ((ri[0] == rj[0]) && (ri[1] == rj[1]) && (ri[0] | ri[1])) { + writel(Ri_MATCH_RESULT__YES, + hdmi_base + S5P_HDCP_CHECK_RESULT); + HDCPPRINTK("R0, R0' is matched!!\n"); + ret = true; + break; + } else { + writel(Ri_MATCH_RESULT__NO, + hdmi_base + S5P_HDCP_CHECK_RESULT); + HDCPPRINTK("R0, R0' is not matched!!\n"); + ret = false; + } + + ri[0] = 0; + ri[1] = 0; + rj[0] = 0; + rj[1] = 0; + + } + + if (!ret) { + hdcp_info.event = HDCP_EVENT_STOP; + hdcp_info.auth_status = NOT_AUTHENTICATED; + } + + return ret ? true : false; +} + + +/* + * Enable/Disable Software HPD control + */ +void sw_hpd_enable(bool enable) +{ + u8 reg; + + reg = readb(hdmi_base + S5P_HPD); + reg &= ~HPD_SW_ENABLE; + + if (enable) + writeb(reg | HPD_SW_ENABLE, hdmi_base + S5P_HPD); + else + writeb(reg, hdmi_base + S5P_HPD); +} + +/* + * Set Software HPD level + * + * @param level [in] if 0 - low;othewise, high + */ +void set_sw_hpd(bool level) +{ + u8 reg; + + reg = readb(hdmi_base + S5P_HPD); + reg &= ~HPD_ON; + + if (level) + writeb(reg | HPD_ON, hdmi_base + S5P_HPD); + else + writeb(reg, hdmi_base + S5P_HPD); +} + + +/* + * Reset Authentication + */ +void reset_authentication(void) +{ + u8 reg; + + spin_lock_irq(&hdcp_info.reset_lock); + + hdcp_info.time_out = INFINITE; + hdcp_info.event = HDCP_EVENT_STOP; + hdcp_info.auth_status = NOT_AUTHENTICATED; + + + /* Disable hdcp */ + writeb(0x0, hdmi_base + S5P_HDCP_CTRL1); + writeb(0x0, hdmi_base + S5P_HDCP_CTRL2); + + s5p_hdmi_mute_en(true); + + /* Disable encryption */ + HDCPPRINTK("Stop Encryption by reset!!\n"); + writeb(HDCP_ENC_DIS, hdmi_base + S5P_ENC_EN); + + HDCPPRINTK("Now reset authentication\n"); + + /* disable hdmi status enable reg. */ + reg = readb(hdmi_base + S5P_STATUS_EN); + reg &= HDCP_STATUS_DIS_ALL; + writeb(reg, hdmi_base + S5P_STATUS_EN); + + /* clear all result */ + + writeb(CLEAR_ALL_RESULTS, hdmi_base + S5P_HDCP_CHECK_RESULT); + + /* + * 1. Mask HPD plug and unplug interrupt + * disable HPD INT + */ + sw_reset = true; + reg = s5p_hdmi_get_enabled_interrupt(); + + s5p_hdmi_disable_interrupts(HDMI_IRQ_HPD_PLUG); + s5p_hdmi_disable_interrupts(HDMI_IRQ_HPD_UNPLUG); + + /* 2. Enable software HPD */ + sw_hpd_enable(true); + + /* 3. Make software HPD logical 0 */ + set_sw_hpd(false); + + /* 4. Make software HPD logical 1 */ + set_sw_hpd(true); + + /* 5. Disable software HPD */ + sw_hpd_enable(false); + + /* 6. Unmask HPD plug and unplug interrupt */ + if (reg & 1<<HDMI_IRQ_HPD_PLUG) + s5p_hdmi_enable_interrupts(HDMI_IRQ_HPD_PLUG); + if (reg & 1<<HDMI_IRQ_HPD_UNPLUG) + s5p_hdmi_enable_interrupts(HDMI_IRQ_HPD_UNPLUG); + + + sw_reset = false; + + /* clear result */ +#if 0 + writel(Ri_MATCH_RESULT__NO, hdmi_base + S5P_HDCP_CHECK_RESULT); + writel(readl(hdmi_base + S5P_HDMI_CON_0) & HDMI_DIS, + hdmi_base + S5P_HDMI_CON_0); + writel(readl(hdmi_base + S5P_HDMI_CON_0) | HDMI_EN, + hdmi_base + S5P_HDMI_CON_0); +#endif + writel(CLEAR_ALL_RESULTS, hdmi_base + S5P_HDCP_CHECK_RESULT); + + /* set hdcp_int enable */ + reg = readb(hdmi_base + S5P_STATUS_EN); + reg |= WTFORACTIVERX_INT_OCCURRED | + WATCHDOG_INT_OCCURRED | + EXCHANGEKSV_INT_OCCURRED | + UPDATE_RI_INT_OCCURRED; + writeb(reg, hdmi_base + S5P_STATUS_EN); + + /* HDCP Enable */ + writeb(CP_DESIRED_EN, hdmi_base + S5P_HDCP_CTRL1); + + spin_unlock_irq(&hdcp_info.reset_lock); +} + +/* + * Set the timing parameter for load e-fuse key. + */ + +/* TODO: must use clk_get for pclk rate */ +#define PCLK_D_RATE_FOR_HDCP 166000000 + +u32 efuse_ceil(u32 val, u32 time) +{ + u32 res; + + res = val / time; + + if (val % time) + res += 1; + + return res; +} + +#if 0 +static void hdcp_efuse_timing(void) +{ + u32 time, val; + + /* TODO: must use clk_get for pclk rate */ + time = 1000000000/PCLK_D_RATE_FOR_HDCP; + + val = efuse_ceil(EFUSE_ADDR_WIDTH, time); + writeb(val, hdmi_base + S5P_EFUSE_ADDR_WIDTH); + + val = efuse_ceil(EFUSE_SIGDEV_ASSERT, time); + writeb(val, hdmi_base + S5P_EFUSE_SIGDEV_ASSERT); + + val = efuse_ceil(EFUSE_SIGDEV_DEASSERT, time); + writeb(val, hdmi_base + S5P_EFUSE_SIGDEV_DEASSERT); + + val = efuse_ceil(EFUSE_PRCHG_ASSERT, time); + writeb(val, hdmi_base + S5P_EFUSE_PRCHG_ASSERT); + + val = efuse_ceil(EFUSE_PRCHG_DEASSERT, time); + writeb(val, hdmi_base + S5P_EFUSE_PRCHG_DEASSERT); + + val = efuse_ceil(EFUSE_FSET_ASSERT, time); + writeb(val, hdmi_base + S5P_EFUSE_FSET_ASSERT); + + val = efuse_ceil(EFUSE_FSET_DEASSERT, time); + writeb(val, hdmi_base + S5P_EFUSE_FSET_DEASSERT); + + val = efuse_ceil(EFUSE_SENSING, time); + writeb(val, hdmi_base + S5P_EFUSE_SENSING); + + val = efuse_ceil(EFUSE_SCK_ASSERT, time); + writeb(val, hdmi_base + S5P_EFUSE_SCK_ASSERT); + + val = efuse_ceil(EFUSE_SCK_DEASSERT, time); + writeb(val, hdmi_base + S5P_EFUSE_SCK_DEASSERT); + + val = efuse_ceil(EFUSE_SDOUT_OFFSET, time); + writeb(val, hdmi_base + S5P_EFUSE_SDOUT_OFFSET); + + val = efuse_ceil(EFUSE_READ_OFFSET, time); + writeb(val, hdmi_base + S5P_EFUSE_READ_OFFSET); + +} +#endif + +/* + * load hdcp key from e-fuse mem. + */ +static int hdcp_loadkey(void) +{ + u8 status; + +#if 0 + hdcp_efuse_timing(); +#endif + /* read HDCP key from E-Fuse */ + writeb(EFUSE_CTRL_ACTIVATE, hdmi_base + S5P_EFUSE_CTRL); + + do { + status = readb(hdmi_base + S5P_EFUSE_STATUS); + } while (!(status & EFUSE_ECC_DONE)); + + if (readb(hdmi_base + S5P_EFUSE_STATUS) & EFUSE_ECC_FAIL) { + HDCPPRINTK("Can't load key from fuse ctrl.\n"); + return -EINVAL; + } + + return 0; + +} + +/* + * Start encryption + */ +static void start_encryption(void) +{ + u32 time_out = 100; + + if (readl(hdmi_base + S5P_HDCP_CHECK_RESULT) == + Ri_MATCH_RESULT__YES) { + + while (time_out) { + + if (readl(hdmi_base + S5P_STATUS) & AUTHENTICATED) { + writel(HDCP_ENC_ENABLE, + hdmi_base + S5P_ENC_EN); + HDCPPRINTK("Encryption start!!\n"); + s5p_hdmi_mute_en(false); + break; + } else { + time_out--; + mdelay(1); + } + } + } else { + writel(HDCP_ENC_DISABLE, hdmi_base + S5P_ENC_EN); + s5p_hdmi_mute_en(true); + HDCPPRINTK("Encryption stop!!\n"); + } +} + +/* + * Check whether Rx is repeater or not + */ +static int check_repeater(void) +{ + int ret = 0; + + u8 i = 0; + u16 j = 0; + + u8 bcaps[BCAPS_SIZE] = {0}; + u8 status[BSTATUS_SIZE] = {0, 0}; + u8 rx_v[SHA_1_HASH_SIZE] = {0}; + u8 ksv_list[HDCP_MAX_DEVS*HDCP_KSV_SIZE] = {0}; + + u32 dev_cnt; + u32 stat; + + bool ksv_fifo_ready = false; + + memset(rx_v, 0x0, SHA_1_HASH_SIZE); + memset(ksv_list, 0x0, HDCP_MAX_DEVS*HDCP_KSV_SIZE); + + while (j <= 50) { + ret = ddc_read(HDCP_Bcaps, + bcaps, BCAPS_SIZE); + + if (ret < 0) { + HDCPPRINTK("Can't read bcaps data from i2c bus\n"); + return false; + } + + if (bcaps[0] & KSV_FIFO_READY) { + HDCPPRINTK("ksv fifo is ready\n"); + ksv_fifo_ready = true; + writel(bcaps[0], hdmi_base + S5P_HDCP_BCAPS); + break; + } else { + HDCPPRINTK("ksv fifo is not ready\n"); + ksv_fifo_ready = false; + mdelay(100); + j++; + } + + bcaps[0] = 0; + } + + if (!ksv_fifo_ready) + return REPEATER_TIMEOUT_ERROR; + + /* + * Check MAX_CASCADE_EXCEEDED + * or MAX_DEVS_EXCEEDED indicator + */ + ret = ddc_read(HDCP_BStatus, + status, BSTATUS_SIZE); + + if (ret < 0) { + HDCPPRINTK("Can't read status data from i2c bus\n"); + return false; + } + + /* MAX_CASCADE_EXCEEDED || MAX_DEVS_EXCEEDED */ + if (status[1] & MAX_CASCADE_EXCEEDED) { + HDCPPRINTK("MAX_CASCADE_EXCEEDED\n"); + return MAX_CASCADE_EXCEEDED_ERROR; + } else if (status[0] & MAX_DEVS_EXCEEDED) { + HDCPPRINTK("MAX_CASCADE_EXCEEDED\n"); + return MAX_DEVS_EXCEEDED_ERROR; + } + + writel(status[0], hdmi_base + S5P_HDCP_BSTATUS_0); + writel(status[1], hdmi_base + S5P_HDCP_BSTATUS_1); + + /* Read KSV list */ + dev_cnt = status[0] & 0x7f; + + HDCPPRINTK("status[0] :0x%08x, status[1] :0x%08x!!\n", + status[0], status[1]); + + if (dev_cnt) { + + u32 val = 0; + + /* read ksv */ + ret = ddc_read(HDCP_KSVFIFO, ksv_list, + dev_cnt * HDCP_KSV_SIZE); + if (ret < 0) { + HDCPPRINTK("Can't read ksv fifo!!\n"); + return false; + } + + /* write ksv */ + for (i = 0; i < dev_cnt - 1; i++) { + + writel(ksv_list[(i*5) + 0], + hdmi_base + S5P_HDCP_RX_KSV_0_0); + writel(ksv_list[(i*5) + 1], + hdmi_base + S5P_HDCP_RX_KSV_0_1); + writel(ksv_list[(i*5) + 2], + hdmi_base + S5P_HDCP_RX_KSV_0_2); + writel(ksv_list[(i*5) + 3], + hdmi_base + S5P_HDCP_RX_KSV_0_3); + writel(ksv_list[(i*5) + 4], + hdmi_base + S5P_HDCP_RX_KSV_0_4); + + mdelay(1); + writel(SET_HDCP_KSV_WRITE_DONE, + hdmi_base + S5P_HDCP_RX_KSV_LIST_CTRL); + mdelay(1); + + stat = readl(hdmi_base + S5P_HDCP_RX_KSV_LIST_CTRL); + + if (!(stat & SET_HDCP_KSV_READ)) + return false; + + HDCPPRINTK("HDCP_RX_KSV_1 = 0x%x\n\r", + readl(hdmi_base + S5P_HDCP_RX_KSV_LIST_CTRL)); + HDCPPRINTK("i : %d, dev_cnt : %d, val = 0x%08x\n", + i, dev_cnt, val); + } + + writel(ksv_list[(i*5) + 0], hdmi_base + S5P_HDCP_RX_KSV_0_0); + writel(ksv_list[(i*5) + 1], hdmi_base + S5P_HDCP_RX_KSV_0_1); + writel(ksv_list[(i*5) + 2], hdmi_base + S5P_HDCP_RX_KSV_0_2); + writel(ksv_list[(i*5) + 3], hdmi_base + S5P_HDCP_RX_KSV_0_3); + writel(ksv_list[(i*5) + 4], hdmi_base + S5P_HDCP_RX_KSV_0_4); + + mdelay(1); + + /* end of ksv */ + val = SET_HDCP_KSV_END|SET_HDCP_KSV_WRITE_DONE; + writel(val, hdmi_base + S5P_HDCP_RX_KSV_LIST_CTRL); + + HDCPPRINTK("HDCP_RX_KSV_1 = 0x%x\n\r", + readl(hdmi_base + S5P_HDCP_RX_KSV_LIST_CTRL)); + HDCPPRINTK("i : %d, dev_cnt : %d, val = 0x%08x\n", + i, dev_cnt, val); + + } else { + + /* + mdelay(200); + */ + + writel(SET_HDCP_KSV_LIST_EMPTY, + hdmi_base + S5P_HDCP_RX_KSV_LIST_CTRL); + } + + + /* Read SHA-1 from receiver */ + ret = ddc_read(HDCP_SHA1, + rx_v, SHA_1_HASH_SIZE); + + if (ret < 0) { + HDCPPRINTK("Can't read sha_1_hash data from i2c bus\n"); + return false; + } + +#ifdef S5P_HDCP_DEBUG + for (i = 0; i < SHA_1_HASH_SIZE; i++) + HDCPPRINTK("SHA_1 rx :: %x\n", rx_v[i]); +#endif + + /* write SHA-1 to register */ + writeb(rx_v[0], hdmi_base + S5P_HDCP_RX_SHA1_0_0); + writeb(rx_v[1], hdmi_base + S5P_HDCP_RX_SHA1_0_1); + writeb(rx_v[2], hdmi_base + S5P_HDCP_RX_SHA1_0_2); + writeb(rx_v[3], hdmi_base + S5P_HDCP_RX_SHA1_0_3); + writeb(rx_v[4], hdmi_base + S5P_HDCP_RX_SHA1_1_0); + writeb(rx_v[5], hdmi_base + S5P_HDCP_RX_SHA1_1_1); + writeb(rx_v[6], hdmi_base + S5P_HDCP_RX_SHA1_1_2); + writeb(rx_v[7], hdmi_base + S5P_HDCP_RX_SHA1_1_3); + writeb(rx_v[8], hdmi_base + S5P_HDCP_RX_SHA1_2_0); + writeb(rx_v[9], hdmi_base + S5P_HDCP_RX_SHA1_2_1); + writeb(rx_v[10], hdmi_base + S5P_HDCP_RX_SHA1_2_2); + writeb(rx_v[11], hdmi_base + S5P_HDCP_RX_SHA1_2_3); + writeb(rx_v[12], hdmi_base + S5P_HDCP_RX_SHA1_3_0); + writeb(rx_v[13], hdmi_base + S5P_HDCP_RX_SHA1_3_1); + writeb(rx_v[14], hdmi_base + S5P_HDCP_RX_SHA1_3_2); + writeb(rx_v[15], hdmi_base + S5P_HDCP_RX_SHA1_3_3); + writeb(rx_v[16], hdmi_base + S5P_HDCP_RX_SHA1_4_0); + writeb(rx_v[17], hdmi_base + S5P_HDCP_RX_SHA1_4_1); + writeb(rx_v[18], hdmi_base + S5P_HDCP_RX_SHA1_4_2); + writeb(rx_v[19], hdmi_base + S5P_HDCP_RX_SHA1_4_3); + + /* SHA write done, and wait for SHA computation being done */ + mdelay(1); + + /* check authentication success or not */ + stat = readb(hdmi_base + S5P_HDCP_AUTH_STATUS); + + HDCPPRINTK("auth status %d\n", stat); + + if (stat & SET_HDCP_SHA_VALID_READY) { + + stat = readb(hdmi_base + S5P_HDCP_AUTH_STATUS); + + if (stat & SET_HDCP_SHA_VALID) + ret = true; + else + ret = false; + } else { + HDCPPRINTK("SHA not ready 0x%x \n\r", stat); + ret = false; + } + + /* clear all validate bit */ + writeb(0x0, hdmi_base + S5P_HDCP_AUTH_STATUS); + + return ret; + +} + +static bool try_read_receiver(void) +{ + u16 i = 0; + bool ret = false; + + s5p_hdmi_mute_en(true); + + for (i = 0; i < 400; i++) { + + msleep(250); + + if (hdcp_info.auth_status != RECEIVER_READ_READY) { + + HDCPPRINTK("hdcp stat. changed!!" + "failed attempt no = %d\n\r", i); + + return false; + } + + ret = read_bcaps(); + + if (ret) { + HDCPPRINTK("succeeded at attempt no= %d \n\r", i); + + return true; + } else + HDCPPRINTK("can't read bcaps!!" + "failed attempt no=%d\n\r", i); + } + + return false; +} + +/* + * stop - stop functions are only called under running HDCP + */ +bool __s5p_stop_hdcp(void) +{ + u32 sfr_val = 0; + + HDCPPRINTK("HDCP ftn. Stop!!\n"); +#if 0 + s5p_hdmi_disable_interrupts(HDMI_IRQ_HPD_PLUG); + s5p_hdmi_disable_interrupts(HDMI_IRQ_HPD_UNPLUG); +#endif + s5p_hdmi_disable_interrupts(HDMI_IRQ_HDCP); + + hdcp_protocol_status = 0; + + hdcp_info.time_out = INFINITE; + hdcp_info.event = HDCP_EVENT_STOP; + hdcp_info.auth_status = NOT_AUTHENTICATED; + hdcp_info.hdcp_enable = false; + + /* + hdcp_info.client = NULL; + */ + + /* 3. disable hdcp control reg. */ + sfr_val = readl(hdmi_base + S5P_HDCP_CTRL1); + sfr_val &= (ENABLE_1_DOT_1_FEATURE_DIS + & CLEAR_REPEATER_TIMEOUT + & EN_PJ_DIS + & CP_DESIRED_DIS); + writel(sfr_val, hdmi_base + S5P_HDCP_CTRL1); + + /* 1-3. disable hdmi hpd reg. */ + sw_hpd_enable(false); + + /* 1-2. disable hdmi status enable reg. */ + sfr_val = readl(hdmi_base + S5P_STATUS_EN); + sfr_val &= HDCP_STATUS_DIS_ALL; + writel(sfr_val, hdmi_base + S5P_STATUS_EN); + + /* 1-1. clear all status pending */ + sfr_val = readl(hdmi_base + S5P_STATUS); + sfr_val |= HDCP_STATUS_EN_ALL; + writel(sfr_val, hdmi_base + S5P_STATUS); + + /* disable encryption */ + HDCPPRINTK("Stop Encryption by Stop!!\n"); + writel(HDCP_ENC_DISABLE, hdmi_base + S5P_ENC_EN); + s5p_hdmi_mute_en(true); + + /* clear result */ + writel(Ri_MATCH_RESULT__NO, hdmi_base + S5P_HDCP_CHECK_RESULT); + writel(CLEAR_ALL_RESULTS, hdmi_base + S5P_HDCP_CHECK_RESULT); + + /* hdmi disable */ +#if 0 + sfr_val = readl(hdmi_base + S5P_HDMI_CON_0); + sfr_val &= ~(PWDN_ENB_NORMAL | HDMI_EN | ASP_EN); + writel(sfr_val, hdmi_base + S5P_HDMI_CON_0); + */ + HDCPPRINTK("\tSTATUS \t0x%08x\n", readl(hdmi_base + S5P_STATUS)); + HDCPPRINTK("\tSTATUS_EN \t0x%08x\n", + readl(hdmi_base + S5P_STATUS_EN)); + HDCPPRINTK("\tHPD \t0x%08x\n", readl(hdmi_base + S5P_HPD)); + HDCPPRINTK("\tHDCP_CTRL \t0x%08x\n", + readl(hdmi_base + S5P_HDCP_CTRL1)); + HDCPPRINTK("\tMODE_SEL \t0x%08x\n", + readl(hdmi_base + S5P_MODE_SEL)); + HDCPPRINTK("\tENC_EN \t0x%08x\n", readl(hdmi_base + S5P_ENC_EN)); + HDCPPRINTK("\tHDMI_CON_0 \t0x%08x\n", + readl(hdmi_base + S5P_HDMI_CON_0)); + + writel(sfr_val, hdmi_base + S5P_HDMI_CON_0); +#endif + return true; +} + + +void __s5p_hdcp_reset(void) +{ + + __s5p_stop_hdcp(); + + hdcp_protocol_status = 2; + + HDCPPRINTK("HDCP ftn. reset!!\n"); +} + +/* + * start - start functions are only called under stopping HDCP + */ +bool __s5p_start_hdcp(void) +{ + u8 reg; + u32 sfr_val; + + hdcp_info.event = HDCP_EVENT_STOP; + hdcp_info.time_out = INFINITE; + hdcp_info.auth_status = NOT_AUTHENTICATED; + + HDCPPRINTK("HDCP ftn. Start!!\n"); + + sw_reset = true; + reg = s5p_hdmi_get_enabled_interrupt(); + + s5p_hdmi_disable_interrupts(HDMI_IRQ_HPD_PLUG); + s5p_hdmi_disable_interrupts(HDMI_IRQ_HPD_UNPLUG); + + /* 2. Enable software HPD */ + sw_hpd_enable(true); + + /* 3. Make software HPD logical */ + set_sw_hpd(false); + + /* 4. Make software HPD logical */ + set_sw_hpd(true); + + /* 5. Disable software HPD */ + sw_hpd_enable(false); + set_sw_hpd(false); + + /* 6. Unmask HPD plug and unplug interrupt */ + + if (reg & 1<<HDMI_IRQ_HPD_PLUG) + s5p_hdmi_enable_interrupts(HDMI_IRQ_HPD_PLUG); + if (reg & 1<<HDMI_IRQ_HPD_UNPLUG) + s5p_hdmi_enable_interrupts(HDMI_IRQ_HPD_UNPLUG); + + sw_reset = false; + HDCPPRINTK("Stop Encryption by Start!!\n"); + + writel(HDCP_ENC_DISABLE, hdmi_base + S5P_ENC_EN); + s5p_hdmi_mute_en(true); + + hdcp_protocol_status = 1; + + if (hdcp_loadkey() < 0) + return false; + + /* for av mute */ + writel(DO_NOT_TRANSMIT, hdmi_base + S5P_GCP_CON); + + /* + * 1-1. set hdmi status enable reg. + * Update_Ri_int_en should be enabled after + * s/w gets ExchangeKSV_int. + */ + writel(HDCP_STATUS_EN_ALL, hdmi_base + S5P_STATUS_EN); + + /* + * 3. set hdcp control reg. + * Disable advance cipher option, Enable CP(Content Protection), + * Disable time-out (This bit is only available in a REPEATER) + * Disable XOR shift, Disable Pj port update, Use external key + */ + sfr_val = 0; + sfr_val |= CP_DESIRED_EN; + writel(sfr_val, hdmi_base + S5P_HDCP_CTRL1); + + s5p_hdmi_enable_interrupts(HDMI_IRQ_HDCP); + + if (!read_bcaps()) { + HDCPPRINTK("can't read ddc port!\n"); + reset_authentication(); + } + + hdcp_info.hdcp_enable = true; + + HDCPPRINTK("\tSTATUS \t0x%08x\n", + readl(hdmi_base + S5P_STATUS)); + HDCPPRINTK("\tSTATUS_EN \t0x%08x\n", + readl(hdmi_base + S5P_STATUS_EN)); + HDCPPRINTK("\tHPD \t0x%08x\n", readl(hdmi_base + S5P_HPD)); + HDCPPRINTK("\tHDCP_CTRL \t0x%08x\n", + readl(hdmi_base + S5P_HDCP_CTRL1)); + HDCPPRINTK("\tMODE_SEL \t0x%08x\n", + readl(hdmi_base + S5P_MODE_SEL)); + HDCPPRINTK("\tENC_EN \t0x%08x\n", + readl(hdmi_base + S5P_ENC_EN)); + HDCPPRINTK("\tHDMI_CON_0 \t0x%08x\n", + readl(hdmi_base + S5P_HDMI_CON_0)); + + return true; +} + + +static void bksv_start_bh(void) +{ + bool ret = false; + + HDCPPRINTK("HDCP_EVENT_READ_BKSV_START bh\n"); + + hdcp_info.auth_status = RECEIVER_READ_READY; + + ret = read_bcaps(); + + if (!ret) { + + ret = try_read_receiver(); + + if (!ret) { + HDCPPRINTK("Can't read bcaps!! retry failed!!\n" + "\t\t\t\thdcp ftn. will be stopped\n"); + + reset_authentication(); + return; + } + } + + hdcp_info.auth_status = BCAPS_READ_DONE; + + ret = read_bksv(); + + if (!ret) { + HDCPPRINTK("Can't read bksv!!" + "hdcp ftn. will be reset\n"); + + reset_authentication(); + return; + } + + hdcp_info.auth_status = BKSV_READ_DONE; + + HDCPPRINTK("authentication status : bksv is done (0x%08x)\n", + hdcp_info.auth_status); +} + +static void second_auth_start_bh(void) +{ + u8 count = 0; + int reg; + bool ret = false; + + int ret_err; + + u32 bcaps; + + HDCPPRINTK("HDCP_EVENT_SECOND_AUTH_START bh\n"); + + ret = read_bcaps(); + + if (!ret) { + + ret = try_read_receiver(); + + if (!ret) { + + HDCPPRINTK("Can't read bcaps!! retry failed!!\n" + "\t\t\t\thdcp ftn. will be stopped\n"); + + reset_authentication(); + return; + } + + } + + bcaps = readl(hdmi_base + S5P_HDCP_BCAPS); + bcaps &= (KSV_FIFO_READY); + + if (!bcaps) { + + HDCPPRINTK("ksv fifo is not ready\n"); + + do { + count++; + + ret = read_bcaps(); + + if (!ret) { + + ret = try_read_receiver(); + if (!ret) + reset_authentication(); + return; + + } + + bcaps = readl(hdmi_base + S5P_HDCP_BCAPS); + bcaps &= (KSV_FIFO_READY); + + if (bcaps) { + HDCPPRINTK("bcaps retries : %d\n", count); + break; + } + + mdelay(100); + + if (!hdcp_info.hdcp_enable) { + + reset_authentication(); + return; + + } + + } while (count <= 50); + + /* wait times exceeded 5 seconds */ + if (count > 50) { + + hdcp_info.time_out = INFINITE; + + /* + * time-out (This bit is only available in a REPEATER) + */ + writel(readl(hdmi_base + S5P_HDCP_CTRL1) | 0x1 << 2, + hdmi_base + S5P_HDCP_CTRL1); + + reset_authentication(); + + return; + } + } + + HDCPPRINTK("ksv fifo ready\n"); + + ret_err = check_repeater(); + + if (ret_err == true) { + u32 flag; + + hdcp_info.auth_status = SECOND_AUTHENTICATION_DONE; + HDCPPRINTK("second authentication done!!\n"); + + flag = readb(hdmi_base + S5P_STATUS); + HDCPPRINTK("hdcp state : %s authenticated!!\n", + flag & AUTHENTICATED ? "" : "not not"); + + start_encryption(); + } else if (ret_err == false) { + /* i2c error */ + HDCPPRINTK("repeater check error!!\n"); + reset_authentication(); + } else { + if (ret_err == REPEATER_ILLEGAL_DEVICE_ERROR) { + /* + * No need to start the HDCP + * in case of invalid KSV (revocation case) + */ + HDCPPRINTK("illegal dev. error!!\n"); + reg = readl(hdmi_base + S5P_HDCP_CTRL2); + reg = 0x1; + writel(reg, hdmi_base + S5P_HDCP_CTRL2); + reg = 0x0; + writel(reg, hdmi_base + S5P_HDCP_CTRL2); + + hdcp_info.auth_status = NOT_AUTHENTICATED; + + } else if (ret_err == REPEATER_TIMEOUT_ERROR) { + reg = readl(hdmi_base + S5P_HDCP_CTRL1); + reg |= SET_REPEATER_TIMEOUT; + writel(reg, hdmi_base + S5P_HDCP_CTRL1); + reg &= ~SET_REPEATER_TIMEOUT; + writel(reg, hdmi_base + S5P_HDCP_CTRL1); + + hdcp_info.auth_status = NOT_AUTHENTICATED; + } else { + /* + * MAX_CASCADE_EXCEEDED_ERROR + * MAX_DEVS_EXCEEDED_ERROR + */ + HDCPPRINTK("repeater check error(MAX_EXCEEDED)!!\n"); + reset_authentication(); + } + } +} + +static bool write_aksv_start_bh(void) +{ + bool ret = false; + + HDCPPRINTK("HDCP_EVENT_WRITE_AKSV_START bh\n"); + + if (hdcp_info.auth_status != BKSV_READ_DONE) { + HDCPPRINTK("bksv is not ready!!\n"); + return false; + } + + ret = write_an(); + if (!ret) + return false; + + hdcp_info.auth_status = AN_WRITE_DONE; + + HDCPPRINTK("an write done!!\n"); + + ret = write_aksv(); + if (!ret) + return false; + + /* + * Wait for 100ms. Transmitter must not read + * Ro' value sooner than 100ms after writing + * Aksv + */ + mdelay(100); + + hdcp_info.auth_status = AKSV_WRITE_DONE; + + HDCPPRINTK("aksv write done!!\n"); + + return ret; +} + +static bool check_ri_start_bh(void) +{ + bool ret = false; + + + HDCPPRINTK("HDCP_EVENT_CHECK_RI_START bh\n"); + + if (hdcp_info.auth_status == AKSV_WRITE_DONE || + hdcp_info.auth_status == FIRST_AUTHENTICATION_DONE || + hdcp_info.auth_status == SECOND_AUTHENTICATION_DONE) { + + ret = compare_r_val(); + + if (ret) { + + if (hdcp_info.auth_status == AKSV_WRITE_DONE) { + /* + * Check whether HDMI receiver is + * repeater or not + */ + if (hdcp_info.is_repeater) + hdcp_info.auth_status + = SECOND_AUTHENTICATION_RDY; + else { + hdcp_info.auth_status + = FIRST_AUTHENTICATION_DONE; + start_encryption(); + } + } + + } else { + + HDCPPRINTK("authentication reset\n"); + reset_authentication(); + + } + + HDCPPRINTK("auth_status = 0x%08x\n", + hdcp_info.auth_status); + + + return true; + } else + reset_authentication(); + + HDCPPRINTK("aksv_write or first/second" + " authentication is not done\n"); + + return false; +} + +/* + * bottom half for hdmi interrupt + * + */ +static void hdcp_work(void *arg) +{ + /* + * I2C int. was occurred + * for reading Bksv and Bcaps + */ + if (hdcp_info.event & (1 << HDCP_EVENT_READ_BKSV_START)) { + + bksv_start_bh(); + + /* clear event */ + /* + spin_lock_bh(&hdcp_info.lock); + */ + hdcp_info.event &= ~(1 << HDCP_EVENT_READ_BKSV_START); + /* + spin_unlock_bh(&hdcp_info.lock); + */ + } + /* + * Watchdog timer int. was occurred + * for checking repeater + */ + if (hdcp_info.event & (1 << HDCP_EVENT_SECOND_AUTH_START)) { + + second_auth_start_bh(); + + /* clear event */ + /* + spin_lock_bh(&hdcp_info.lock); + */ + hdcp_info.event &= ~(1 << HDCP_EVENT_SECOND_AUTH_START); + /* + spin_unlock_bh(&hdcp_info.lock); + */ + } + + /* + * An_Write int. was occurred + * for writing Ainfo, An and Aksv + */ + if (hdcp_info.event & (1 << HDCP_EVENT_WRITE_AKSV_START)) { + + write_aksv_start_bh(); + + /* clear event */ + /* + spin_lock_bh(&hdcp_info.lock); + */ + hdcp_info.event &= ~(1 << HDCP_EVENT_WRITE_AKSV_START); + /* + spin_unlock_bh(&hdcp_info.lock); + */ + } + + /* + * Ri int. was occurred + * for comparing Ri and Ri'(from HDMI sink) + */ + if (hdcp_info.event & (1 << HDCP_EVENT_CHECK_RI_START)) { + + + check_ri_start_bh(); + + /* clear event */ + /* + spin_lock_bh(&hdcp_info.lock); + */ + hdcp_info.event &= ~(1 << HDCP_EVENT_CHECK_RI_START); + /* + spin_unlock_bh(&hdcp_info.lock); + */ + } + +} + +void __s5p_init_hdcp(bool hpd_status, struct i2c_client *ddc_port) +{ + + HDCPPRINTK("HDCP ftn. Init!!\n"); + + is_dvi = false; + av_mute = false; + audio_en = true; + + /* for bh */ + INIT_WORK(&hdcp_info.work, (work_func_t)hdcp_work); + + init_waitqueue_head(&hdcp_info.waitq); + + /* for dev_dbg err. */ + spin_lock_init(&hdcp_info.lock); + +} + + +irqreturn_t __s5p_hdcp_irq_handler(int irq) + +{ + u32 event = 0; + u8 flag; + + event = 0; + /* check HDCP Status */ + flag = readb(hdmi_base + S5P_STATUS); + + HDCPPRINTK("irq_status : 0x%08x\n", readb(hdmi_base + S5P_STATUS)); + + HDCPPRINTK("hdcp state : %s authenticated!!\n", + flag & AUTHENTICATED ? "" : "not"); + + spin_lock_irq(&hdcp_info.lock); + + /* + * processing interrupt + * interrupt processing seq. is firstly set event for workqueue, + * and interrupt pending clear. 'flag|' was used for preventing + * to clear AUTHEN_ACK.- it caused many problem. be careful. + */ + /* I2C INT */ + if (flag & WTFORACTIVERX_INT_OCCURRED) { + event |= (1 << HDCP_EVENT_READ_BKSV_START); + writeb(flag | WTFORACTIVERX_INT_OCCURRED, + hdmi_base + S5P_STATUS); + writeb(0x0, hdmi_base + S5P_HDCP_I2C_INT); + } + + /* AN INT */ + if (flag & EXCHANGEKSV_INT_OCCURRED) { + event |= (1 << HDCP_EVENT_WRITE_AKSV_START); + writeb(flag | EXCHANGEKSV_INT_OCCURRED, + hdmi_base + S5P_STATUS); + writeb(0x0, hdmi_base + S5P_HDCP_AN_INT); + } + + /* RI INT */ + if (flag & UPDATE_RI_INT_OCCURRED) { + event |= (1 << HDCP_EVENT_CHECK_RI_START); + writeb(flag | UPDATE_RI_INT_OCCURRED, + hdmi_base + S5P_STATUS); + writeb(0x0, hdmi_base + S5P_HDCP_RI_INT); + } + + /* WATCHDOG INT */ + if (flag & WATCHDOG_INT_OCCURRED) { + event |= (1 << HDCP_EVENT_SECOND_AUTH_START); + writeb(flag | WATCHDOG_INT_OCCURRED, + hdmi_base + S5P_STATUS); + writeb(0x0, hdmi_base + S5P_HDCP_WDT_INT); + } + + if (!event) { + HDCPPRINTK("unknown irq.\n"); + return IRQ_HANDLED; + } + + hdcp_info.event |= event; + + schedule_work(&hdcp_info.work); + + spin_unlock_irq(&hdcp_info.lock); + + return IRQ_HANDLED; +} + +bool __s5p_set_hpd_detection(bool detection, bool hdcp_enabled, + struct i2c_client *client) +{ + u32 hpd_reg_val = 0; + + if (detection) + hpd_reg_val = CABLE_PLUGGED; + else + hpd_reg_val = CABLE_UNPLUGGED; + + + writel(hpd_reg_val, hdmi_base + S5P_HPD); + + HDCPPRINTK("HPD status :: 0x%08x\n\r", + readl(hdmi_base + S5P_HPD)); + + return true; +} + +int __s5p_hdcp_init(void) +{ + /* for bh */ + INIT_WORK(&hdcp_info.work, (work_func_t)hdcp_work); + is_dvi = false; + av_mute = false; + audio_en = true; + + init_waitqueue_head(&hdcp_info.waitq); + + /* for dev_dbg err. */ + spin_lock_init(&hdcp_info.lock); + spin_lock_init(&hdcp_info.reset_lock); + + s5p_hdmi_register_isr((hdmi_isr)__s5p_hdcp_irq_handler, + (u8)HDMI_IRQ_HDCP); + + return 0; +} + +/* called by hpd */ +int s5p_hdcp_encrypt_stop(bool on) +{ + u32 reg; + + if (hdcp_info.hdcp_enable) { + /* clear interrupt pending all */ + writeb(0x0, hdmi_base + S5P_HDCP_I2C_INT); + writeb(0x0, hdmi_base + S5P_HDCP_AN_INT); + writeb(0x0, hdmi_base + S5P_HDCP_RI_INT); + writeb(0x0, hdmi_base + S5P_HDCP_WDT_INT); + + writel(HDCP_ENC_DISABLE, hdmi_base + S5P_ENC_EN); + s5p_hdmi_mute_en(true); + + if (!sw_reset) { + reg = readl(hdmi_base + S5P_HDCP_CTRL1); + + if (on) { + writel(reg | CP_DESIRED_EN, + hdmi_base + S5P_HDCP_CTRL1); + s5p_hdmi_enable_interrupts(HDMI_IRQ_HDCP); + } else { + hdcp_info.event + = HDCP_EVENT_STOP; + hdcp_info.auth_status + = NOT_AUTHENTICATED; + writel(reg & ~CP_DESIRED_EN, + hdmi_base + S5P_HDCP_CTRL1); + s5p_hdmi_disable_interrupts(HDMI_IRQ_HDCP); + } + } + + HDCPPRINTK("Stop Encryption by HPD Event!!\n"); + } + + return 0; +} +EXPORT_SYMBOL(s5p_hdcp_encrypt_stop); + diff --git a/drivers/media/video/samsung/tv20/s5pv210/hdmi_param.h b/drivers/media/video/samsung/tv20/s5pv210/hdmi_param.h new file mode 100644 index 0000000..a8c6338 --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5pv210/hdmi_param.h @@ -0,0 +1,414 @@ +/* linux/drivers/media/video/samsung/tv20/s5pv210/hdmi_param.h + * + * hdmi parameter header file for Samsung TVOut driver + * + * Copyright (c) 2010 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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. +*/ + +#define PHY_I2C_ADDRESS 0x70 +#define PHY_REG_MODE_SET_DONE 0x1F + +struct hdmi_v_params { + u16 h_blank; + u32 v_blank; + u32 hvline; + u32 h_sync_gen; + u32 v_sync_gen; + u8 avi_vic; + u8 avi_vic_16_9; + u8 interlaced; + u8 repetition; + u8 polarity; + u32 v_blank_f; + u32 v_sync_gen2; + u32 v_sync_gen3; + enum phy_freq pixel_clock; +}; + +struct _hdmi_tg_param { + u16 h_fsz; + u16 hact_st; + u16 hact_sz; + u16 v_fsz; + u16 vsync; + u16 vsync2; + u16 vact_st; + u16 vact_sz; + u16 field_chg; + u16 vact_st2; + u16 vsync_top_hdmi; + u16 vsync_bot_hdmi; + u16 field_top_hdmi; + u16 field_bot_hdmi; + u8 mhl_hsync_width; + u8 mhl_vsync_width; +}; + +static const struct hdmi_v_params video_params[] = { + { 0xA0 , 0x16A0D, 0x32020D, 0x11B80E, 0xA00C , 1 , 1 , 0, 0, 1, + 0, 0, 0, ePHY_FREQ_25_200,}, + { 0x8A , 0x16A0D, 0x35A20D, 0x11300E, 0x900F , 2 , 3 , 0, 0, 1, + 0, 0, 0, ePHY_FREQ_27_027,}, + { 0x172, 0xF2EE , 0x6722EE, 0x2506C , 0x500A , 4 , 4 , 0, 0, 0, + 0, 0, 0, ePHY_FREQ_74_250,}, + { 0x118, 0xB232 , 0x898465, 0x20856, 0x2007 , 5 , 5 , 1, 0, 0, + 0x232A49, 0x234239, 0x4A44A4, ePHY_FREQ_74_250,}, + { 0x114, 0xB106 , 0x6B420D, 0x128024, 0x4007 , 6 , 7 , 1, 1, 1, + 0x10691D, 0x10A10D, 0x380380, ePHY_FREQ_27_027,}, + { 0x114, 0xB106 , 0x6B4106, 0x128024, 0x4007 , 8 , 9 , 0, 1, 1, + 0, 0, 0, ePHY_FREQ_27_027,}, + { 0x228, 0xB106 , 0xD6820D, 0x15084A, 0x4007 , 10, 11, 1, 1, 1, + 0x10691D, 0x10A10D, 0x700700, ePHY_FREQ_54_054,}, + { 0x228, 0xB106 , 0x6B4106, 0x15084A, 0x4007 , 12, 13, 0, 1, 1, + 0, 0, 0, ePHY_FREQ_54_054,}, + { 0x114, 0x16A0D, 0x6B420D, 0x12681E, 0x900F , 14, 15, 0, 1, 1, + 0, 0, 0, ePHY_FREQ_54_054,}, + { 0x118, 0x16C65, 0x898465, 0x20856 , 0x4009 , 16, 16, 0, 0, 0, + 0, 0, 0, ePHY_FREQ_148_500}, + + + { 0x90 , 0x18A71, 0x360271, 0x11280A, 0x500A , 17, 18, 0, 0, 1, + 0, 0, 0, ePHY_FREQ_27, }, + { 0x2BC, 0xF2EE , 0x7BC2EE, 0x779B6 , 0x500A , 19, 19, 0, 0, 0, + 0, 0, 0, ePHY_FREQ_74_250,}, + { 0x2D0, 0xB232 , 0xA50465, 0x8EA0E , 0x2007 , 20, 20, 1, 0, 0, + 0x232A49, 0x234239, 0x738738, ePHY_FREQ_74_250,}, + { 0x120, 0xC138 , 0x6C0271, 0x125016, 0x2005 , 21, 22, 1, 1, 1, + 0x138951, 0x13A13D, 0x378378, ePHY_FREQ_27, }, + { 0x120, 0xC138 , 0x6C0138, 0x125016, 0x3006 , 23, 24, 0, 1, 1, + 0, 0, 0, ePHY_FREQ_27, }, + { 0x240, 0xC138 , 0xD80271, 0x14A82E, 0x2005 , 25, 26, 1, 1, 1, + 0x138951, 0x13A13D, 0x6F06F0, ePHY_FREQ_54, }, + { 0x240, 0xC138 , 0xD80138, 0x14A82E, 0x2005 , 27, 28, 0, 1, 1, + 0, 0, 0, ePHY_FREQ_54, }, + { 0x120, 0x18A71, 0x6C0271, 0x125816, 0x500A , 29, 30, 0, 1, 1, + 0, 0, 0, ePHY_FREQ_54, }, + { 0x2D0, 0x16C65, 0xA50465, 0x8EA0E , 0x4009 , 31, 31, 0, 0, 0, + 0, 0, 0, ePHY_FREQ_148_500,}, + { 0x33E, 0x16C65, 0xABE465, 0xAA27C , 0x4009 , 32, 32, 0, 0, 0, + 0, 0, 0, ePHY_FREQ_74_250,}, + + + { 0x2D0, 0x16C65, 0xA50465, 0x8EA0E , 0x4009 , 33, 33, 0, 0, 0, + 0, 0, 0, ePHY_FREQ_74_250, }, + { 0x118, 0x16C65, 0x898465, 0x20856 , 0x4009 , 34, 34, 0, 0, 0, + 0, 0, 0, ePHY_FREQ_74_250, }, + { 0x228, 0x16A0D, 0xD6820D, 0x14D83E, 0x900F , 35, 36, 0, 0, 1, + 0, 0, 0, ePHY_FREQ_108_108, }, + { 0x240, 0x18A71, 0xD80271, 0x14B82E, 0x500A , 37, 38, 0, 1, 1, + 0, 0, 0, ePHY_FREQ_108, }, + { 0x180, 0x2AA71, 0x9004E2, 0x3181E , 0x1701C, 39, 39, 0, 0, 0, + 0x2712C6, 0x28728F, 0x4a44a4, ePHY_FREQ_72, }, + { 0x2D0, 0xB232 , 0xA50465, 0x8EA0E , 0x2007 , 40, 40, 1, 0, 0, + 0x232A49, 0x234239, 0x738738, ePHY_FREQ_148_500, }, + { 0x2BC, 0xF2EE , 0x7BC2EE, 0x779B6 , 0x500A , 41, 41, 0, 0, 0, + 0, 0, 0, ePHY_FREQ_148_500, }, + { 0x90 , 0x18A71, 0x360271, 0x11280A, 0x500A , 42, 43, 0, 0, 1, + 0, 0, 0, ePHY_FREQ_54, }, + { 0x120, 0xC138 , 0x6C0271, 0x125016, 0x2005 , 44, 45, 1, 1, 1, + 0x138951, 0x13A13D, 0x378378, ePHY_FREQ_54, }, + { 0x118, 0xB232 , 0x898465, 0x20856 , 0x2007 , 46, 46, 1, 0, 0, + 0x232A49, 0x234239, 0x4A44A4, ePHY_FREQ_148_500, }, + + + { 0x172, 0xF2EE , 0x6722EE, 0x2506C , 0x500A , 47, 47, 0, 0, 0, + 0, 0, 0, ePHY_FREQ_148_500,}, + { 0x8A , 0x16A0D, 0x35A20D, 0x11300E, 0x900F , 48, 49, 0, 0, 1, + 0, 0, 0, ePHY_FREQ_54_054, }, + { 0x114, 0xB106 , 0x6B420D, 0x128024, 0x4007 , 50, 51, 1, 1, 1, + 0x10691D, 0x10A10D, 0x380380, ePHY_FREQ_54_054, }, + { 0x90 , 0x18A71, 0x360271, 0x11280A, 0x500A , 52, 53, 0, 0, 1, + 0, 0, 0, ePHY_FREQ_108, }, + { 0x120, 0xC138 , 0x6C0271, 0x125016, 0x2005 , 54, 55, 1, 1, 1, + 0x138951, 0x13A13D, 0x378378, ePHY_FREQ_108, }, + { 0x8A , 0x16A0D, 0x35A20D, 0x11300E, 0x900F , 56, 57, 0, 0, 1, + 0, 0, 0, ePHY_FREQ_108_108,}, + { 0x114, 0xB106 , 0x6B420D, 0x128024, 0x4007 , 58, 59, 1, 1, 1, + 0x10691D, 0x10A10D, 0x380380, ePHY_FREQ_108_108,}, + + { 0x8A , 0x16A0D, 0x35A20D, 0x11300E, 0x900F , 2 , 3 , 0, 0, 1, + 0, 0, 0, ePHY_FREQ_27, }, + { 0x172, 0xF2EE , 0x6722EE, 0x2506C , 0x500A , 4 , 4 , 0, 0, 0, + 0, 0, 0, ePHY_FREQ_74_176, }, + { 0x118, 0xB232 , 0x898465, 0x20856, 0x2007 , 5 , 5 , 1, 0, 0, + 0x232A49, 0x234239, 0x4A44A4, ePHY_FREQ_74_176, }, + { 0x118, 0x16C65, 0x898465, 0x20856 , 0x4009 , 16, 16, 0, 0, 0, + 0, 0, 0, ePHY_FREQ_148_352,}, +}; + +static const struct _hdmi_tg_param hdmi_tg_param[] = { + {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + + {0x35a , 0x8a , 0x2d0 , 0x20d , 0x1 , 0x233 , 0x2d , 0x1e0 , + 0x233 , 0x248 , 0x1 , 0x1 , 0x1 , 0x233 , 0xf , 0x1 }, + + {0x672 , 0x172 , 0x500 , 0x2ee , 0x1 , 0x233 , 0x1e , 0x2d0 , + 0x233 , 0x248 , 0x1 , 0x1 , 0x1 , 0x233 , 0xf , 0x1 }, + + {0x898 , 0x118 , 0x780 , 0x465 , 0x1 , 0x233 , 0x16 , 0x21c , + 0x233 , 0x249 , 0x1 , 0x233 , 0x1 , 0x233 , 0xf , 0x1 }, + + {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + + {0x898 , 0x118 , 0x780 , 0x465 , 0x1 , 0x233 , 0x2d , 0x438 , + 0x233 , 0x248 , 0x1 , 0x1 , 0x1 , 0x233 , 0xf , 0x1 }, + + {0x360 , 0x90 , 0x2d0 , 0x271 , 0x1 , 0x233 , 0x31 , 0x240 , + 0x233 , 0x248 , 0x1 , 0x1 , 0x1 , 0x233 , 0xf , 0x1 }, + + {0x7bc , 0x2bc , 0x500 , 0x2ee , 0x1 , 0x233 , 0x1e , 0x2d0 , + 0x233 , 0x248 , 0x1 , 0x1 , 0x1 , 0x233 , 0xf , 0x1 }, + + {0xa50 , 0x2d0 , 0x780 , 0x465 , 0x1 , 0x233 , 0x16 , 0x21c , + 0x233 , 0x249 , 0x1 , 0x233 , 0x1 , 0x233 , 0xf , 0x1 }, + + {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + + {0xa50 , 0x2d0 , 0x780 , 0x465 , 0x1 , 0x233 , 0x2d , 0x438 , + 0x233 , 0x248 , 0x1 , 0x1 , 0x1 , 0x233 , 0xf , 0x1 }, + + {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + + {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + + {0x898 , 0x118 , 0x780 , 0x465 , 0x1 , 0x233 , 0x2d , 0x438 , + 0x233 , 0x248 , 0x1 , 0x1 , 0x1 , 0x233 , 0xf , 0x1 }, + + {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + + {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + + {0x35a , 0x8a , 0x2d0 , 0x20d , 0x1 , 0x233 , 0x2d , 0x1e0 , + 0x233 , 0x248 , 0x1 , 0x1 , 0x1 , 0x233 , 0xf , 0x1 }, + + {0x672 , 0x172 , 0x500 , 0x2ee , 0x1 , 0x233 , 0x1e , 0x2d0 , + 0x233 , 0x248 , 0x1 , 0x1 , 0x1 , 0x233 , 0xf , 0x1 }, + + {0x898 , 0x118 , 0x780 , 0x465 , 0x1 , 0x233 , 0x16 , 0x21c , + 0x233 , 0x249 , 0x1 , 0x233 , 0x1 , 0x233 , 0xf , 0x1 }, + + {0x898 , 0x118 , 0x780 , 0x465 , 0x1 , 0x233 , 0x2d , 0x438 , + 0x233 , 0x248 , 0x1 , 0x1 , 0x1 , 0x233 , 0xf , 0x1 }, + +}; + +static const u8 phy_config[][3][32] = { + { /* freq = 25.200 MHz */ + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40, 0x6B, 0x10, 0x02, + 0x51, 0x5f, 0xF1, 0x54, 0x7e, 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, + 0x10, 0xE0, 0x22, 0x40, 0xf3, 0x26, 0x00, 0x00, 0x00, 0x80, }, + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40, 0x6B, 0x10, 0x02, + 0x51, 0x9f, 0xF6, 0x54, 0x9e, 0x84, 0x00, 0x32, 0x38, 0x00, 0xB8, + 0x10, 0xE0, 0x22, 0x40, 0xc2, 0x26, 0x00, 0x00, 0x00, 0x80, }, + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40, 0x6B, 0x10, 0x02, + 0x51, 0xFf, 0xF3, 0x54, 0xbd, 0x84, 0x00, 0x30, 0x38, 0x00, 0xA4, + 0x10, 0xE0, 0x22, 0x40, 0xa2, 0x26, 0x00, 0x00, 0x00, 0x80, }, + }, + + { /* freq = 25.175 MHz */ + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0x1e, 0x20, 0x6B, 0x50, 0x10, + 0x51, 0xf1, 0x31, 0x54, 0xbd, 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, + 0x10, 0xE0, 0x22, 0x40, 0xf3, 0x26, 0x00, 0x00, 0x00, 0x80, }, + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0x2b, 0x40, 0x6B, 0x50, 0x10, + 0x51, 0xF2, 0x32, 0x54, 0xec, 0x84, 0x00, 0x10, 0x38, 0x00, 0xB8, + 0x10, 0xE0, 0x22, 0x40, 0xc2, 0x26, 0x00, 0x00, 0x00, 0x80, }, + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0x1e, 0x20, 0x6B, 0x10, 0x02, + 0x51, 0xf1, 0x31, 0x54, 0xbd, 0x84, 0x00, 0x10, 0x38, 0x00, 0xA4, + 0x10, 0xE0, 0x22, 0x40, 0xa2, 0x26, 0x00, 0x00, 0x00, 0x80, }, + }, + + { /* freq = 27 MHz */ + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40, 0x6B, 0x10, 0x02, + 0x51, 0xDf, 0xF2, 0x54, 0x87, 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, + 0x10, 0xE0, 0x22, 0x40, 0xe3, 0x26, 0x00, 0x00, 0x00, 0x80, }, + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0x02, 0x08, 0x6A, 0x10, 0x02, + 0x51, 0xCf, 0xF1, 0x54, 0xa9, 0x84, 0x00, 0x10, 0x38, 0x00, 0xB8, + 0x10, 0xE0, 0x22, 0x40, 0xb5, 0x26, 0x00, 0x00, 0x00, 0x80, }, + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xfc, 0x08, 0x6B, 0x10, 0x02, + 0x51, 0x2f, 0xF2, 0x54, 0xcb, 0x84, 0x00, 0x10, 0x38, 0x00, 0xA4, + 0x10, 0xE0, 0x22, 0x40, 0x97, 0x26, 0x00, 0x00, 0x00, 0x80, }, + }, + + { /* freq = 27.027 MHz */ + { 0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64, 0x6B, 0x10, 0x02, + 0x51, 0xDf, 0xF2, 0x54, 0x87, 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, + 0x10, 0xE0, 0x22, 0x40, 0xe2, 0x26, 0x00, 0x00, 0x00, 0x80, }, + { 0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x31, 0x50, 0x6B, 0x10, 0x02, + 0x51, 0x8f, 0xF3, 0x54, 0xa9, 0x84, 0x00, 0x30, 0x38, 0x00, 0xB8, + 0x10, 0xE0, 0x22, 0x40, 0xb5, 0x26, 0x00, 0x00, 0x00, 0x80, }, + { 0x01, 0x05, 0x00, 0x10, 0x10, 0x9C, 0x1b, 0x64, 0x6F, 0x10, 0x02, + 0x51, 0x7f, 0xF8, 0x54, 0xcb, 0x84, 0x00, 0x32, 0x38, 0x00, 0xA4, + 0x10, 0xE0, 0x22, 0x40, 0x97, 0x26, 0x00, 0x00, 0x00, 0x80, }, + }, + + { /* freq = 54 MHz */ + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40, 0x6B, 0x10, 0x01, + 0x51, 0xDf, 0xF2, 0x54, 0x87, 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, + 0x10, 0xE0, 0x22, 0x40, 0xe3, 0x26, 0x01, 0x00, 0x00, 0x80, }, + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0x02, 0x08, 0x6A, 0x10, 0x01, + 0x51, 0xCf, 0xF1, 0x54, 0xa9, 0x84, 0x00, 0x10, 0x38, 0x00, 0xF8, + 0x10, 0xE0, 0x22, 0x40, 0xb5, 0x26, 0x01, 0x00, 0x00, 0x80, }, + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xfc, 0x08, 0x6B, 0x10, 0x01, + 0x51, 0x2f, 0xF2, 0x54, 0xcb, 0x84, 0x00, 0x10, 0x38, 0x00, 0xE4, + 0x10, 0xE0, 0x22, 0x40, 0x97, 0x26, 0x01, 0x00, 0x00, 0x80, }, + }, + + { /* freq = 54.054 MHz */ + { 0x01, 0x05, 0x00, 0xd4, 0x10, 0x9C, 0x09, 0x64, 0x6B, 0x10, 0x01, + 0x51, 0xDf, 0xF2, 0x54, 0x87, 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, + 0x10, 0xE0, 0x22, 0x40, 0xe2, 0x26, 0x01, 0x00, 0x00, 0x80, }, + { 0x01, 0x05, 0x00, 0xd4, 0x10, 0x9C, 0x31, 0x50, 0x6B, 0x10, 0x01, + 0x51, 0x8f, 0xF3, 0x54, 0xa9, 0x84, 0x00, 0x30, 0x38, 0x00, 0xF8, + 0x10, 0xE0, 0x22, 0x40, 0xb5, 0x26, 0x01, 0x00, 0x00, 0x80, }, + { 0x01, 0x05, 0x00, 0x10, 0x10, 0x9C, 0x1b, 0x64, 0x6F, 0x10, 0x01, + 0x51, 0x7f, 0xF8, 0x54, 0xcb, 0x84, 0x00, 0x32, 0x38, 0x00, 0xE4, + 0x10, 0xE0, 0x22, 0x40, 0x97, 0x26, 0x01, 0x00, 0x00, 0x80, }, + }, + + { /* freq = 74.250 MHz */ + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40, 0x6A, 0x10, 0x01, + 0x51, 0xff, 0xF1, 0x54, 0xba, 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, + 0x10, 0xE0, 0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x80, }, + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xd6, 0x40, 0x6B, 0x10, 0x01, + 0x51, 0x7f, 0xF2, 0x54, 0xe8, 0x84, 0x00, 0x10, 0x38, 0x00, 0xF8, + 0x10, 0xE0, 0x22, 0x40, 0x83, 0x26, 0x01, 0x00, 0x00, 0x80, }, + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0x34, 0x40, 0x6B, 0x10, 0x01, + 0x51, 0xef, 0xF2, 0x54, 0x16, 0x85, 0x00, 0x10, 0x38, 0x00, 0xE4, + 0x10, 0xE0, 0x22, 0x40, 0xdc, 0x26, 0x02, 0x00, 0x00, 0x80, }, + }, + + { /* freq = 74.176 MHz */ + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B, 0x6D, 0x10, 0x01, + 0x51, 0xef, 0xF3, 0x54, 0xb9, 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, + 0x10, 0xE0, 0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x80, }, + { 0x01, 0x05, 0x00, 0x10, 0x10, 0x9C, 0xab, 0x5B, 0x6F, 0x10, 0x01, + 0x51, 0xbf, 0xF9, 0x54, 0xe8, 0x84, 0x00, 0x32, 0x38, 0x00, 0xF8, + 0x10, 0xE0, 0x22, 0x40, 0x84, 0x26, 0x01, 0x00, 0x00, 0x80, }, + { 0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0xcd, 0x5B, 0x6F, 0x10, 0x01, + 0x51, 0xdf, 0xF5, 0x54, 0x16, 0x85, 0x00, 0x30, 0x38, 0x00, 0xE4, + 0x10, 0xE0, 0x22, 0x40, 0xdc, 0x26, 0x02, 0x00, 0x00, 0x80, }, + }, + + { /* freq = 148.500 MHz - Pre-emph + Higher Tx amp. */ + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40, 0x6A, 0x18, 0x00, + 0x51, 0xff, 0xF1, 0x54, 0xba, 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, + 0x10, 0xE0, 0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x80, }, + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xd6, 0x40, 0x6B, 0x18, 0x00, + 0x51, 0x7f, 0xF2, 0x54, 0xe8, 0x84, 0x00, 0x10, 0x38, 0x00, 0xF8, + 0x10, 0xE0, 0x23, 0x41, 0x83, 0x26, 0x02, 0x00, 0x00, 0x80, }, + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0x34, 0x40, 0x6B, 0x18, 0x00, + 0x51, 0xef, 0xF2, 0x54, 0x16, 0x85, 0x00, 0x10, 0x38, 0x00, 0xE4, + 0x10, 0xE0, 0x23, 0x41, 0x6d, 0x26, 0x02, 0x00, 0x00, 0x80, }, + }, + + { /* freq = 148.352 MHz */ + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B, 0x6D, 0x18, 0x00, + 0x51, 0xef, 0xF3, 0x54, 0xb9, 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, + 0x10, 0xE0, 0x22, 0x40, 0xa5, 0x26, 0x02, 0x00, 0x00, 0x80, }, + { 0x01, 0x05, 0x00, 0x10, 0x10, 0x9C, 0xab, 0x5B, 0x6F, 0x18, 0x00, + 0x51, 0xbf, 0xF9, 0x54, 0xe8, 0x84, 0x00, 0x32, 0x38, 0x00, 0xF8, + 0x10, 0xE0, 0x23, 0x41, 0x84, 0x26, 0x02, 0x00, 0x00, 0x80, }, + { 0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0xcd, 0x5B, 0x6F, 0x18, 0x00, + 0x51, 0xdf, 0xF5, 0x54, 0x16, 0x85, 0x00, 0x30, 0x38, 0x00, 0xE4, + 0x10, 0xE0, 0x23, 0x41, 0x6d, 0x26, 0x02, 0x00, 0x00, 0x80, }, + }, + + { /* freq = 108.108 MHz */ + { 0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64, 0x6B, 0x18, 0x00, + 0x51, 0xDf, 0xF2, 0x54, 0x87, 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, + 0x10, 0xE0, 0x22, 0x40, 0xe2, 0x26, 0x02, 0x00, 0x00, 0x80, }, + { 0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x31, 0x50, 0x6D, 0x18, 0x00, + 0x51, 0x8f, 0xF3, 0x54, 0xa9, 0x84, 0x00, 0x30, 0x38, 0x00, 0xF8, + 0x10, 0xE0, 0x22, 0x40, 0xb5, 0x26, 0x02, 0x00, 0x00, 0x80, }, + { 0x01, 0x05, 0x00, 0x10, 0x10, 0x9C, 0x1b, 0x64, 0x6F, 0x18, 0x00, + 0x51, 0x7f, 0xF8, 0x54, 0xcb, 0x84, 0x00, 0x32, 0x38, 0x00, 0xE4, + 0x10, 0xE0, 0x22, 0x40, 0x97, 0x26, 0x02, 0x00, 0x00, 0x80, }, + }, + + { /* freq = 72 MHz */ + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40, 0x6B, 0x10, 0x01, + 0x51, 0xEf, 0xF1, 0x54, 0xb4, 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, + 0x10, 0xE0, 0x22, 0x40, 0xaa, 0x26, 0x01, 0x00, 0x00, 0x80, }, + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40, 0x6F, 0x10, 0x01, + 0x51, 0xBf, 0xF4, 0x54, 0xe1, 0x84, 0x00, 0x30, 0x38, 0x00, 0xF8, + 0x10, 0xE0, 0x22, 0x40, 0x88, 0x26, 0x01, 0x00, 0x00, 0x80, }, + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40, 0x6B, 0x18, 0x00, + 0x51, 0xDf, 0xF2, 0x54, 0x87, 0x84, 0x00, 0x30, 0x38, 0x00, 0xE4, + 0x10, 0xE0, 0x22, 0x40, 0xe3, 0x26, 0x02, 0x00, 0x00, 0x80, }, + }, + + { /* freq = 25 MHz */ + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0x20, 0x40, 0x6B, 0x50, 0x10, + 0x51, 0xff, 0xF1, 0x54, 0xbc, 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, + 0x10, 0xE0, 0x22, 0x40, 0xf5, 0x26, 0x00, 0x00, 0x00, 0x80, }, + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0x08, 0x40, 0x6B, 0x50, 0x10, + 0x51, 0x7f, 0xF2, 0x54, 0xea, 0x84, 0x00, 0x10, 0x38, 0x00, 0xB8, + 0x10, 0xE0, 0x22, 0x40, 0xc4, 0x26, 0x00, 0x00, 0x00, 0x80, }, + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0x20, 0x40, 0x6B, 0x10, 0x02, + 0x51, 0xff, 0xF1, 0x54, 0xbc, 0x84, 0x00, 0x10, 0x38, 0x00, 0xA4, + 0x10, 0xE0, 0x22, 0x40, 0xa3, 0x26, 0x00, 0x00, 0x00, 0x80, }, + }, + + { /* freq = 65 MHz */ + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0x02, 0x0c, 0x6B, 0x10, 0x01, + 0x51, 0xBf, 0xF1, 0x54, 0xa3, 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, + 0x10, 0xE0, 0x22, 0x40, 0xbc, 0x26, 0x01, 0x00, 0x00, 0x80, }, + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf2, 0x30, 0x6A, 0x10, 0x01, + 0x51, 0x2f, 0xF2, 0x54, 0xcb, 0x84, 0x00, 0x10, 0x38, 0x00, 0xF8, + 0x10, 0xE0, 0x22, 0x40, 0x96, 0x26, 0x01, 0x00, 0x00, 0x80, }, + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xd0, 0x40, 0x6B, 0x10, 0x01, + 0x51, 0x9f, 0xF2, 0x54, 0xf4, 0x84, 0x00, 0x10, 0x38, 0x00, 0xE4, + 0x10, 0xE0, 0x22, 0x40, 0x7D, 0x26, 0x01, 0x00, 0x00, 0x80, }, + }, + + { /* freq = 108 MHz */ + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40, 0x6D, 0x18, 0x00, + 0x51, 0xDf, 0xF2, 0x54, 0x87, 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, + 0x10, 0xE0, 0x22, 0x40, 0xe3, 0x26, 0x02, 0x00, 0x00, 0x80, }, + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0x02, 0x08, 0x6A, 0x18, 0x00, + 0x51, 0xCf, 0xF1, 0x54, 0xa9, 0x84, 0x00, 0x10, 0x38, 0x00, 0xF8, + 0x10, 0xE0, 0x22, 0x40, 0xb5, 0x26, 0x02, 0x00, 0x00, 0x80, }, + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xfc, 0x08, 0x6B, 0x18, 0x00, + 0x51, 0x2f, 0xF2, 0x54, 0xcb, 0x84, 0x00, 0x10, 0x38, 0x00, 0xE4, + 0x10, 0xE0, 0x22, 0x40, 0x97, 0x26, 0x02, 0x00, 0x00, 0x80, }, + }, + + { /* freq = 162 MHz */ + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40, 0x6F, 0x18, 0x00, + 0x51, 0x7f, 0xF8, 0x54, 0xcb, 0x84, 0x00, 0x32, 0x38, 0x00, 0x08, + 0x10, 0xE0, 0x22, 0x40, 0x97, 0x26, 0x02, 0x00, 0x00, 0x80, }, + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0x18, 0x40, 0x6B, 0x18, 0x00, + 0x51, 0xAf, 0xF2, 0x54, 0xfd, 0x84, 0x00, 0x10, 0x38, 0x00, 0xF8, + 0x10, 0xE0, 0x23, 0x41, 0x78, 0x26, 0x02, 0x00, 0x00, 0x80, }, + { 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xd0, 0x40, 0x6B, 0x18, 0x00, + 0x51, 0x3f, 0xF3, 0x54, 0x30, 0x85, 0x00, 0x10, 0x38, 0x00, 0xE4, + 0x10, 0xE0, 0x23, 0x41, 0x64, 0x26, 0x02, 0x00, 0x00, 0x80, }, + }, +}; + diff --git a/drivers/media/video/samsung/tv20/s5pv210/hdmi_s5pv210.c b/drivers/media/video/samsung/tv20/s5pv210/hdmi_s5pv210.c new file mode 100644 index 0000000..58bdcad --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5pv210/hdmi_s5pv210.c @@ -0,0 +1,2131 @@ +/* linux/drivers/media/video/samsung/tv20/s5pv210/hdmi_s5pv210.c + * + * hdmi raw ftn file for Samsung TVOut driver + * + * Copyright (c) 2010 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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/i2c.h> +#include <linux/platform_device.h> +#include <linux/clk.h> +#include <linux/interrupt.h> +#include <linux/delay.h> +#include <linux/io.h> + +#include <plat/clock.h> + +#include "tv_out_s5pv210.h" + +#include "regs/regs-hdmi.h" +#include "hdmi_param.h" + +#include "../hpd.h" + +#ifdef COFIG_TVOUT_RAW_DBG +#define S5P_HDMI_DEBUG 1 +#endif + +#ifdef S5P_HDMI_DEBUG +#define HDMIPRINTK(fmt, args...) \ + printk(KERN_INFO "\t\t[HDMI] %s: " fmt, __func__ , ## args) +#else +#define HDMIPRINTK(fmt, args...) +#endif + +static struct resource *hdmi_mem; +void __iomem *hdmi_base; + +static struct resource *i2c_hdmi_phy_mem; +void __iomem *i2c_hdmi_phy_base; + +spinlock_t lock_hdmi; + +/* + * i2c_hdmi_phy related + */ + +#define PHY_I2C_ADDRESS 0x70 + +#define I2C_ACK (1<<7) +#define I2C_INT (1<<5) +#define I2C_PEND (1<<4) + +#define I2C_INT_CLEAR (0<<4) + +#define I2C_CLK (0<<6) +#define I2C_CLK_PEND_INT (I2C_CLK|I2C_INT_CLEAR|I2C_INT) + +#define I2C_ENABLE (1<<4) +#define I2C_START (1<<5) + +#define I2C_MODE_MTX (0x3<<6) +#define I2C_MODE_MRX (0x2<<6) +#define I2C_MODE_SRX (0x0<<6) + +#define I2C_IDLE 0 + +static struct { + s32 state; + u8 *buffer; + s32 bytes; +} i2c_hdmi_phy_context; + + +#define STATE_IDLE 0 +#define STATE_TX_EDDC_SEGADDR 1 +#define STATE_TX_EDDC_SEGNUM 2 +#define STATE_TX_DDC_ADDR 3 +#define STATE_TX_DDC_OFFSET 4 +#define STATE_RX_DDC_ADDR 5 +#define STATE_RX_DDC_DATA 6 +#define STATE_RX_ADDR 7 +#define STATE_RX_DATA 8 +#define STATE_TX_ADDR 9 +#define STATE_TX_DATA 10 +#define STATE_TX_STOP 11 +#define STATE_RX_STOP 12 + +static s32 i2c_hdmi_phy_interruptwait(void) +{ + u8 status, reg; + s32 retval = 0; + + do { + status = readb(i2c_hdmi_phy_base + I2C_HDMI_CON); + + if (status & I2C_PEND) { + /* check status flags */ + reg = readb(i2c_hdmi_phy_base + I2C_HDMI_STAT); + break; + } + } while (1); + + return retval; +} + +s32 i2c_hdmi_phy_read(u8 addr, u8 nbytes, u8 *buffer) +{ + u8 reg; + s32 ret = 0; + u32 proc = true; + + i2c_hdmi_phy_context.state = STATE_RX_ADDR; + i2c_hdmi_phy_context.buffer = buffer; + i2c_hdmi_phy_context.bytes = nbytes; + + writeb(I2C_CLK | I2C_INT | I2C_ACK, + i2c_hdmi_phy_base + I2C_HDMI_CON); + + writeb(I2C_ENABLE | I2C_MODE_MRX, + i2c_hdmi_phy_base + I2C_HDMI_STAT); + + writeb(addr & 0xFE, + i2c_hdmi_phy_base + I2C_HDMI_DS); + + writeb(I2C_ENABLE | I2C_START | I2C_MODE_MRX, + i2c_hdmi_phy_base + I2C_HDMI_STAT); + + while (proc) { + + if (i2c_hdmi_phy_context.state != STATE_RX_STOP) { + if (i2c_hdmi_phy_interruptwait() != 0) { + HDMIPRINTK("interrupt wait failed!!!\n"); + ret = EINVAL; + break; + } + } + + switch (i2c_hdmi_phy_context.state) { + + case STATE_RX_DATA: + + reg = readb(i2c_hdmi_phy_base + I2C_HDMI_DS); + *(i2c_hdmi_phy_context.buffer) = reg; + + i2c_hdmi_phy_context.buffer++; + --(i2c_hdmi_phy_context.bytes); + + if (i2c_hdmi_phy_context.bytes == 1) { + i2c_hdmi_phy_context.state = STATE_RX_STOP; + writeb(I2C_CLK_PEND_INT, + i2c_hdmi_phy_base + I2C_HDMI_CON); + } else { + writeb(I2C_CLK_PEND_INT | I2C_ACK, + i2c_hdmi_phy_base + I2C_HDMI_CON); + + } + break; + + case STATE_RX_ADDR: + i2c_hdmi_phy_context.state = STATE_RX_DATA; + + if (i2c_hdmi_phy_context.bytes == 1) { + i2c_hdmi_phy_context.state = STATE_RX_STOP; + writeb(I2C_CLK_PEND_INT, + i2c_hdmi_phy_base + I2C_HDMI_CON); + } else { + writeb(I2C_CLK_PEND_INT | I2C_ACK, + i2c_hdmi_phy_base + I2C_HDMI_CON); + } + + break; + + case STATE_RX_STOP: + + i2c_hdmi_phy_context.state = STATE_IDLE; + + reg = readb(i2c_hdmi_phy_base + I2C_HDMI_DS); + + *(i2c_hdmi_phy_context.buffer) = reg; + + writeb(I2C_MODE_MRX|I2C_ENABLE, + i2c_hdmi_phy_base + I2C_HDMI_STAT); + + writeb(I2C_CLK_PEND_INT, + i2c_hdmi_phy_base + I2C_HDMI_CON); + + writeb(I2C_MODE_MRX, + i2c_hdmi_phy_base + I2C_HDMI_STAT); + + while (readb(i2c_hdmi_phy_base + I2C_HDMI_STAT) & + (1<<5)) + msleep(1); + + proc = false; + + break; + + case STATE_IDLE: + + default: + HDMIPRINTK("error state!!!\n"); + + ret = EINVAL; + + proc = false; + + break; + } + } + + return ret; +} + +s32 i2c_hdmi_phy_write(u8 addr, u8 nbytes, u8 *buffer) +{ + u8 reg; + s32 ret = 0; + u32 proc = true; + + i2c_hdmi_phy_context.state = STATE_TX_ADDR; + i2c_hdmi_phy_context.buffer = buffer; + i2c_hdmi_phy_context.bytes = nbytes; + + writeb(I2C_CLK | I2C_INT | I2C_ACK, + i2c_hdmi_phy_base + I2C_HDMI_CON); + + writeb(I2C_ENABLE | I2C_MODE_MTX, + i2c_hdmi_phy_base + I2C_HDMI_STAT); + + writeb(addr & 0xFE, + i2c_hdmi_phy_base + I2C_HDMI_DS); + + writeb(I2C_ENABLE | I2C_START | I2C_MODE_MTX, + i2c_hdmi_phy_base + I2C_HDMI_STAT); + + while (proc) { + + if (i2c_hdmi_phy_interruptwait() != 0) { + HDMIPRINTK("interrupt wait failed!!!\n"); + ret = EINVAL; + break; + } + + switch (i2c_hdmi_phy_context.state) { + + case STATE_TX_ADDR: + + case STATE_TX_DATA: + i2c_hdmi_phy_context.state = STATE_TX_DATA; + + reg = *(i2c_hdmi_phy_context.buffer); + + writeb(reg, i2c_hdmi_phy_base + I2C_HDMI_DS); + + i2c_hdmi_phy_context.buffer++; + --(i2c_hdmi_phy_context.bytes); + + if (i2c_hdmi_phy_context.bytes == 0) { + i2c_hdmi_phy_context.state = STATE_TX_STOP; + writeb(I2C_CLK_PEND_INT, + i2c_hdmi_phy_base + I2C_HDMI_CON); + } else + writeb(I2C_CLK_PEND_INT | I2C_ACK, + i2c_hdmi_phy_base + I2C_HDMI_CON); + break; + + case STATE_TX_STOP: + i2c_hdmi_phy_context.state = STATE_IDLE; + + writeb(I2C_MODE_MTX | I2C_ENABLE, + i2c_hdmi_phy_base + I2C_HDMI_STAT); + + writeb(I2C_CLK_PEND_INT, + i2c_hdmi_phy_base + I2C_HDMI_CON); + + writeb(I2C_MODE_MTX, + i2c_hdmi_phy_base + I2C_HDMI_STAT); + + while (readb(i2c_hdmi_phy_base + I2C_HDMI_STAT) & + (1<<5)) + msleep(1); + + proc = false; + + break; + + case STATE_IDLE: + break; + + default: + HDMIPRINTK("error state!!!\n"); + + ret = EINVAL; + + proc = false; + + break; + } + } + + return ret; +} + +int hdmi_phy_down(bool on, u8 addr, u8 offset, u8 *read_buffer) +{ + u8 buff[2] = {0}; + + buff[0] = addr; + buff[1] = (on) ? (read_buffer[addr] & (~(1<<offset))) : + (read_buffer[addr] | (1<<offset)); + + if (i2c_hdmi_phy_write(PHY_I2C_ADDRESS, 2, buff) != 0) + return EINVAL; + + return 0; +} + +int __s5p_hdmi_phy_power(bool on) +{ +#if !defined(CONFIG_MACH_P1) + /* for the case that + - only analog tv is supported + - and the power for the hdmi phy is not supported*/ + return 0; +#endif + + u32 size; + u8 *buffer; + u8 read_buffer[0x40] = {0, }; + + size = sizeof(phy_config[0][0]) + / sizeof(phy_config[0][0][0]); + + buffer = (u8 *) phy_config[0][0]; + + /* write offset */ + if (i2c_hdmi_phy_write(PHY_I2C_ADDRESS, 1, buffer) != 0) { + HDMIPRINTK("%s I2C Write Error!...\n", __func__); + return EINVAL; + } + + /* read data */ + if (i2c_hdmi_phy_read(PHY_I2C_ADDRESS, size, read_buffer) != 0) { + HDMIPRINTK("i2c_hdmi_phy_read failed.\n"); + return EINVAL; + } + + /* i can't get the information about phy setting */ + if (on) { + /* on */ + /* biaspd */ + hdmi_phy_down(true, 0x1, 0x5, read_buffer); + /* clockgenpd */ + hdmi_phy_down(true, 0x1, 0x7, read_buffer); + /* pllpd */ + hdmi_phy_down(true, 0x5, 0x5, read_buffer); + /* pcgpd */ + hdmi_phy_down(true, 0x17, 0x0, read_buffer); + /* txpd */ + hdmi_phy_down(true, 0x17, 0x1, read_buffer); + } else { + /* off */ + /* biaspd */ + hdmi_phy_down(false, 0x1, 0x5, read_buffer); + /* clockgenpd */ + hdmi_phy_down(false, 0x1, 0x7, read_buffer); + /* pllpd */ + hdmi_phy_down(false, 0x5, 0x5, read_buffer); + /* pcgpd */ + hdmi_phy_down(false, 0x17, 0x0, read_buffer); + /* txpd */ + hdmi_phy_down(false, 0x17, 0x1, read_buffer); + } + + return 0; +} + +s32 hdmi_corereset(void) +{ + writeb(0x0, hdmi_base + S5P_HDMI_CTRL_CORE_RSTOUT); + + mdelay(10); + + writeb(0x1, hdmi_base + S5P_HDMI_CTRL_CORE_RSTOUT); + + return 0; +} + +s32 hdmi_phy_config(enum phy_freq freq, enum s5p_hdmi_color_depth cd) +{ + s32 index; + s32 size; + u8 buffer[32] = {0, }; + u8 reg; + + switch (cd) { + + case HDMI_CD_24: + index = 0; + break; + + case HDMI_CD_30: + index = 1; + break; + + case HDMI_CD_36: + index = 2; + break; + + default: + return false; + } + + /* i2c_hdmi init - set i2c filtering */ + buffer[0] = PHY_REG_MODE_SET_DONE; + buffer[1] = 0x00; + + if (i2c_hdmi_phy_write(PHY_I2C_ADDRESS, 2, buffer) != 0) { + HDMIPRINTK("i2c_hdmi_phy_write failed.\n"); + return EINVAL; + } + + writeb(0x5, i2c_hdmi_phy_base + I2C_HDMI_LC); + + size = sizeof(phy_config[freq][index]) + / sizeof(phy_config[freq][index][0]); + + memcpy(buffer, phy_config[freq][index], sizeof(buffer)); + + if (i2c_hdmi_phy_write(PHY_I2C_ADDRESS, size, buffer) != 0) + return EINVAL; + + /* write offset */ + buffer[0] = 0x01; + + if (i2c_hdmi_phy_write(PHY_I2C_ADDRESS, 1, buffer) != 0) { + HDMIPRINTK("i2c_hdmi_phy_write failed.\n"); + return EINVAL; + } + +#ifdef S5P_HDMI_DEBUG + { + int i = 0; + u8 read_buffer[0x40] = {0, }; + + /* read data */ + if (i2c_hdmi_phy_read(PHY_I2C_ADDRESS, size, read_buffer) != 0) { + HDMIPRINTK("i2c_hdmi_phy_read failed.\n"); + return EINVAL; + } + + HDMIPRINTK("read buffer :\n\t\t"); + + for (i = 1; i < size; i++) { + + printk("0x%02x", read_buffer[i]); + + if (i % 8) + printk(" "); + else + printk("\n\t\t"); + } + printk("\n"); +} +#endif + hdmi_corereset(); + + do { + reg = readb(hdmi_base + HDMI_PHY_STATUS); + } while (!(reg & HDMI_PHY_READY)); + + writeb(I2C_CLK_PEND_INT, i2c_hdmi_phy_base + I2C_HDMI_CON); + /* disable */ + writeb(I2C_IDLE, i2c_hdmi_phy_base + I2C_HDMI_STAT); + + return 0; +} + +s32 hdmi_set_tg(enum s5p_hdmi_v_fmt mode) +{ + u16 temp_reg; + u8 tc_cmd; + + temp_reg = hdmi_tg_param[mode].h_fsz; + writeb((u8)(temp_reg&0xff) , hdmi_base + S5P_TG_H_FSZ_L); + writeb((u8)(temp_reg >> 8) , hdmi_base + S5P_TG_H_FSZ_H); + + /* set Horizontal Active Start Position */ + temp_reg = hdmi_tg_param[mode].hact_st ; + writeb((u8)(temp_reg&0xff) , hdmi_base + S5P_TG_HACT_ST_L); + writeb((u8)(temp_reg >> 8) , hdmi_base + S5P_TG_HACT_ST_H); + + /* set Horizontal Active Size */ + temp_reg = hdmi_tg_param[mode].hact_sz ; + writeb((u8)(temp_reg&0xff) , hdmi_base + S5P_TG_HACT_SZ_L); + writeb((u8)(temp_reg >> 8) , hdmi_base + S5P_TG_HACT_SZ_H); + + /* set Vertical Full Size */ + temp_reg = hdmi_tg_param[mode].v_fsz ; + writeb((u8)(temp_reg&0xff) , hdmi_base + S5P_TG_V_FSZ_L); + writeb((u8)(temp_reg >> 8) , hdmi_base + S5P_TG_V_FSZ_H); + + /* set VSYNC Position */ + temp_reg = hdmi_tg_param[mode].vsync ; + writeb((u8)(temp_reg&0xff) , hdmi_base + S5P_TG_VSYNC_L); + writeb((u8)(temp_reg >> 8) , hdmi_base + S5P_TG_VSYNC_H); + + /* set Bottom Field VSYNC Position */ + temp_reg = hdmi_tg_param[mode].vsync2; + writeb((u8)(temp_reg&0xff) , hdmi_base + S5P_TG_VSYNC2_L); + writeb((u8)(temp_reg >> 8) , hdmi_base + S5P_TG_VSYNC2_H); + + /* set Vertical Active Start Position */ + temp_reg = hdmi_tg_param[mode].vact_st ; + writeb((u8)(temp_reg&0xff) , hdmi_base + S5P_TG_VACT_ST_L); + writeb((u8)(temp_reg >> 8) , hdmi_base + S5P_TG_VACT_ST_H); + + /* set Vertical Active Size */ + temp_reg = hdmi_tg_param[mode].vact_sz ; + writeb((u8)(temp_reg&0xff) , hdmi_base + S5P_TG_VACT_SZ_L); + writeb((u8)(temp_reg >> 8) , hdmi_base + S5P_TG_VACT_SZ_H); + + /* set Field Change Position */ + temp_reg = hdmi_tg_param[mode].field_chg ; + writeb((u8)(temp_reg&0xff) , hdmi_base + S5P_TG_FIELD_CHG_L); + writeb((u8)(temp_reg >> 8) , hdmi_base + S5P_TG_FIELD_CHG_H); + + /* set Bottom Field Vertical Active Start Position */ + temp_reg = hdmi_tg_param[mode].vact_st2; + writeb((u8)(temp_reg&0xff) , hdmi_base + S5P_TG_VACT_ST2_L); + writeb((u8)(temp_reg >> 8) , hdmi_base + S5P_TG_VACT_ST2_H); + + /* set VSYNC Position for HDMI */ + temp_reg = hdmi_tg_param[mode].vsync_top_hdmi; + writeb((u8)(temp_reg&0xff) , hdmi_base + S5P_TG_VSYNC_TOP_HDMI_L); + writeb((u8)(temp_reg >> 8) , hdmi_base + S5P_TG_VSYNC_TOP_HDMI_H); + + /* set Bottom Field VSYNC Position */ + temp_reg = hdmi_tg_param[mode].vsync_bot_hdmi; + writeb((u8)(temp_reg&0xff) , hdmi_base + S5P_TG_VSYNC_BOT_HDMI_L); + writeb((u8)(temp_reg >> 8) , hdmi_base + S5P_TG_VSYNC_BOT_HDMI_H); + + /* set Top Field Change Position for HDMI */ + temp_reg = hdmi_tg_param[mode].field_top_hdmi ; + writeb((u8)(temp_reg&0xff) , hdmi_base + S5P_TG_FIELD_TOP_HDMI_L); + writeb((u8)(temp_reg >> 8) , hdmi_base + S5P_TG_FIELD_TOP_HDMI_H); + + /* set Bottom Field Change Position for HDMI */ + temp_reg = hdmi_tg_param[mode].field_bot_hdmi ; + writeb((u8)(temp_reg&0xff) , hdmi_base + S5P_TG_FIELD_BOT_HDMI_L); + writeb((u8)(temp_reg >> 8) , hdmi_base + S5P_TG_FIELD_BOT_HDMI_H); + + tc_cmd = readb(hdmi_base + S5P_TG_CMD); + + if (video_params[mode].interlaced == 1) + /* Field Mode enable(interlace mode) */ + tc_cmd |= (1<<1); + else + /* Field Mode disable */ + tc_cmd &= ~(1<<1); + + writeb(tc_cmd, hdmi_base + S5P_TG_CMD); + + return 0; +} + +/** + * Set registers related to color depth. + */ +static s32 hdmi_set_clr_depth(enum s5p_hdmi_color_depth cd) +{ + /* if color depth is supported by RX, set GCP packet */ + switch (cd) { + + case HDMI_CD_48: + writeb(GCP_CD_48BPP, hdmi_base + S5P_GCP_BYTE2); + break; + + case HDMI_CD_36: + writeb(GCP_CD_36BPP, hdmi_base + S5P_GCP_BYTE2); + /* set DC register */ + writeb(HDMI_DC_CTL_12, hdmi_base + S5P_HDMI_DC_CONTROL); + break; + + case HDMI_CD_30: + writeb(GCP_CD_30BPP, hdmi_base + S5P_GCP_BYTE2); + /* set DC register */ + writeb(HDMI_DC_CTL_10, hdmi_base + S5P_HDMI_DC_CONTROL); + break; + + case HDMI_CD_24: + writeb(GCP_CD_24BPP, hdmi_base + S5P_GCP_BYTE2); + /* set DC register */ + writeb(HDMI_DC_CTL_8, hdmi_base + S5P_HDMI_DC_CONTROL); + /* disable GCP */ + writeb(DO_NOT_TRANSMIT, hdmi_base + S5P_GCP_CON); + break; + + default: + HDMIPRINTK("HDMI core does not support \ + requested Deep Color mode\n"); + return -EINVAL; + } + + return 0; +} + +s32 hdmi_set_video_mode(enum s5p_hdmi_v_fmt mode, enum s5p_hdmi_color_depth cd, + enum s5p_tv_hdmi_pxl_aspect pxl_ratio, u8 *avidata) +{ + u8 temp_reg8; + u16 temp_reg16; + u32 temp_reg32, temp_sync2, temp_sync3; + + /* check if HDMI code support that mode */ + if (mode > (sizeof(video_params)/sizeof(struct hdmi_v_params)) || + (s32)mode < 0) { + HDMIPRINTK("This video mode is not Supported\n"); + return -EINVAL; + } + + hdmi_set_tg(mode); + + /* set HBlank */ + temp_reg16 = video_params[mode].h_blank; + writeb((u8)(temp_reg16&0xff), hdmi_base + S5P_H_BLANK_0); + writeb((u8)(temp_reg16 >> 8), hdmi_base + S5P_H_BLANK_1); + + /* set VBlank */ + temp_reg32 = video_params[mode].v_blank; + writeb((u8)(temp_reg32&0xff), hdmi_base + S5P_V_BLANK_0); + writeb((u8)(temp_reg32 >> 8), hdmi_base + S5P_V_BLANK_1); + writeb((u8)(temp_reg32 >> 16), hdmi_base + S5P_V_BLANK_2); + + /* set HVLine */ + temp_reg32 = video_params[mode].hvline; + writeb((u8)(temp_reg32&0xff), hdmi_base + S5P_H_V_LINE_0); + writeb((u8)(temp_reg32 >> 8), hdmi_base + S5P_H_V_LINE_1); + writeb((u8)(temp_reg32 >> 16), hdmi_base + S5P_H_V_LINE_2); + + /* set VSYNC polarity */ + writeb(video_params[mode].polarity, hdmi_base + S5P_SYNC_MODE); + + /* set HSyncGen */ + temp_reg32 = video_params[mode].h_sync_gen; + writeb((u8)(temp_reg32&0xff), hdmi_base + S5P_H_SYNC_GEN_0); + writeb((u8)(temp_reg32 >> 8), hdmi_base + S5P_H_SYNC_GEN_1); + writeb((u8)(temp_reg32 >> 16), hdmi_base + S5P_H_SYNC_GEN_2); + + /* set VSyncGen1 */ + temp_reg32 = video_params[mode].v_sync_gen; + writeb((u8)(temp_reg32&0xff), hdmi_base + S5P_V_SYNC_GEN_1_0); + writeb((u8)(temp_reg32 >> 8), hdmi_base + S5P_V_SYNC_GEN_1_1); + writeb((u8)(temp_reg32 >> 16), hdmi_base + S5P_V_SYNC_GEN_1_2); + + if (video_params[mode].interlaced) { + /* set up v_blank_f, v_sync_gen2, v_sync_gen3 */ + temp_reg32 = video_params[mode].v_blank_f; + temp_sync2 = video_params[mode].v_sync_gen2; + temp_sync3 = video_params[mode].v_sync_gen3; + + writeb((u8)(temp_reg32 & 0xff), hdmi_base + S5P_V_BLANK_F_0); + writeb((u8)(temp_reg32 >> 8), hdmi_base + S5P_V_BLANK_F_1); + writeb((u8)(temp_reg32 >> 16), hdmi_base + S5P_V_BLANK_F_2); + + writeb((u8)(temp_sync2 & 0xff), + hdmi_base + S5P_V_SYNC_GEN_2_0); + writeb((u8)(temp_sync2 >> 8), hdmi_base + S5P_V_SYNC_GEN_2_1); + writeb((u8)(temp_sync2 >> 16), hdmi_base + S5P_V_SYNC_GEN_2_2); + + writeb((u8)(temp_sync3 & 0xff), + hdmi_base + S5P_V_SYNC_GEN_3_0); + writeb((u8)(temp_sync3 >> 8), hdmi_base + S5P_V_SYNC_GEN_3_1); + writeb((u8)(temp_sync3 >> 16), hdmi_base + S5P_V_SYNC_GEN_3_2); + } else { + /* progressive mode */ + writeb(0x00, hdmi_base + S5P_V_BLANK_F_0); + writeb(0x00, hdmi_base + S5P_V_BLANK_F_1); + writeb(0x00, hdmi_base + S5P_V_BLANK_F_2); + + writeb(0x01, hdmi_base + S5P_V_SYNC_GEN_2_0); + writeb(0x10, hdmi_base + S5P_V_SYNC_GEN_2_1); + writeb(0x00, hdmi_base + S5P_V_SYNC_GEN_2_2); + + writeb(0x01, hdmi_base + S5P_V_SYNC_GEN_3_0); + writeb(0x10, hdmi_base + S5P_V_SYNC_GEN_3_1); + writeb(0x00, hdmi_base + S5P_V_SYNC_GEN_3_2); + } + + /* set interlaced mode */ + writeb(video_params[mode].interlaced, hdmi_base + S5P_INT_PRO_MODE); + + /* pixel repetition */ + temp_reg8 = readb(hdmi_base + S5P_HDMI_CON_1); + + /* clear */ + temp_reg8 &= ~HDMI_CON_PXL_REP_RATIO_MASK; + + if (video_params[mode].repetition) { + /* set pixel repetition */ + temp_reg8 |= HDMI_DOUBLE_PIXEL_REPETITION; + /* AVI Packet */ + avidata[4] = AVI_PIXEL_REPETITION_DOUBLE; + } else { /* clear pixel repetition */ + /* AVI Packet */ + avidata[4] = 0; + } + + /* set pixel repetition */ + writeb(temp_reg8, hdmi_base + S5P_HDMI_CON_1); + + /* set AVI packet VIC */ + + if (pxl_ratio == HDMI_PIXEL_RATIO_16_9) + avidata[3] = video_params[mode].avi_vic_16_9; + else + avidata[3] = video_params[mode].avi_vic; + + /* clear */ + temp_reg8 = readb(hdmi_base + S5P_AVI_BYTE2) & + ~(AVI_PICTURE_ASPECT_4_3 | AVI_PICTURE_ASPECT_16_9); + + if (pxl_ratio == HDMI_PIXEL_RATIO_16_9) + temp_reg8 |= AVI_PICTURE_ASPECT_16_9; + else + temp_reg8 |= AVI_PICTURE_ASPECT_4_3; + + /* set color depth */ + if (hdmi_set_clr_depth(cd) != 0) { + HDMIPRINTK("[ERR] Can't set hdmi clr. depth.\n"); + return -EINVAL; + } + + if (video_params[mode].interlaced == 1) { + u32 gcp_con; + + gcp_con = readb(hdmi_base + S5P_GCP_CON); + gcp_con |= (3<<2); + + writeb(gcp_con, hdmi_base + S5P_GCP_CON); + } else { + u32 gcp_con; + + gcp_con = readb(hdmi_base + S5P_GCP_CON); + gcp_con &= (~(3<<2)); + + writeb(gcp_con, hdmi_base + S5P_GCP_CON); + } + +#if 0 + /* config Phy */ + if (hdmi_phy_config(video_params[mode].pixel_clock, cd) == EINVAL) { + HDMIPRINTK("[ERR] hdmi_phy_config() failed.\n"); + return EINVAL; + } +#endif + return 0; +} + +void __s5p_hdmi_set_hpd_onoff(bool on_off) +{ + HDMIPRINTK("hpd is %s\n\r", on_off ? "on" : "off"); + + if (on_off) + writel(SW_HPD_PLUGGED, hdmi_base + S5P_HPD); + else + writel(SW_HPD_UNPLUGGED, hdmi_base + S5P_HPD); + + + HDMIPRINTK("0x%08x\n\r", readl(hdmi_base + S5P_HPD)); +} + +void __s5p_hdmi_audio_set_config(enum s5p_tv_audio_codec_type audio_codec) +{ + + u32 data_type = (audio_codec == PCM) ? CONFIG_LINEAR_PCM_TYPE : + (audio_codec == AC3) ? CONFIG_NON_LINEAR_PCM_TYPE : + 0xff; + + HDMIPRINTK("audio codec type = %s\n\r", + (audio_codec&PCM) ? "PCM" : + (audio_codec&AC3) ? "AC3" : + (audio_codec&MP3) ? "MP3" : + (audio_codec&WMA) ? "WMA" : "Unknown"); + + /* open SPDIF path on HDMI_I2S */ + writel(0x01, hdmi_base + S5P_HDMI_I2S_CLK_CON); + writel(readl(hdmi_base + S5P_HDMI_I2S_MUX_CON) | 0x11, + hdmi_base + S5P_HDMI_I2S_MUX_CON); + writel(0xFF, hdmi_base + S5P_HDMI_I2S_MUX_CH); + writel(0x03, hdmi_base + S5P_HDMI_I2S_MUX_CUV); + + writel(CONFIG_FILTER_2_SAMPLE | data_type + | CONFIG_PCPD_MANUAL_SET | CONFIG_WORD_LENGTH_MANUAL_SET + | CONFIG_U_V_C_P_REPORT | CONFIG_BURST_SIZE_2 + | CONFIG_DATA_ALIGN_32BIT + , hdmi_base + S5P_SPDIFIN_CONFIG_1); + writel(0, hdmi_base + S5P_SPDIFIN_CONFIG_2); +} + +void __s5p_hdmi_audio_set_acr(u32 sample_rate) +{ + u32 value_n = (sample_rate == 32000) ? 4096 : + (sample_rate == 44100) ? 6272 : + (sample_rate == 88200) ? 12544 : + (sample_rate == 176400) ? 25088 : + (sample_rate == 48000) ? 6144 : + (sample_rate == 96000) ? 12288 : + (sample_rate == 192000) ? 24576 : 0; + + u32 cts = (sample_rate == 32000) ? 27000 : + (sample_rate == 44100) ? 30000 : + (sample_rate == 88200) ? 30000 : + (sample_rate == 176400) ? 30000 : + (sample_rate == 48000) ? 27000 : + (sample_rate == 96000) ? 27000 : + (sample_rate == 192000) ? 27000 : 0; + + HDMIPRINTK("sample rate = %d\n\r", sample_rate); + HDMIPRINTK("cts = %d\n\r", cts); + + writel(value_n & 0xff, hdmi_base + S5P_ACR_N0); + writel((value_n >> 8) & 0xff, hdmi_base + S5P_ACR_N1); + writel((value_n >> 16) & 0xff, hdmi_base + S5P_ACR_N2); + + writel(cts & 0xff, hdmi_base + S5P_ACR_MCTS0); + writel((cts >> 8) & 0xff, hdmi_base + S5P_ACR_MCTS1); + writel((cts >> 16) & 0xff, hdmi_base + S5P_ACR_MCTS2); + + writel(cts & 0xff, hdmi_base + S5P_ACR_CTS0); + writel((cts >> 8) & 0xff, hdmi_base + S5P_ACR_CTS1); + writel((cts >> 16) & 0xff, hdmi_base + S5P_ACR_CTS2); + + writel(4, hdmi_base + S5P_ACR_CON); +} + +void __s5p_hdmi_audio_set_asp(void) +{ + writel(0x0, hdmi_base + S5P_ASP_CON); + /* All Subpackets contain audio samples */ + writel(0x0, hdmi_base + S5P_ASP_SP_FLAT); + + writel(1 << 3 | 0, hdmi_base + S5P_ASP_CHCFG0); + writel(1 << 3 | 0, hdmi_base + S5P_ASP_CHCFG1); + writel(1 << 3 | 0, hdmi_base + S5P_ASP_CHCFG2); + writel(1 << 3 | 0, hdmi_base + S5P_ASP_CHCFG3); +} + +void __s5p_hdmi_audio_clock_enable(void) +{ + writel(0x1, hdmi_base + S5P_SPDIFIN_CLK_CTRL); + /* HDMI operation mode */ + writel(0x3, hdmi_base + S5P_SPDIFIN_OP_CTRL); +} + + +void __s5p_hdmi_audio_set_repetition_time( + enum s5p_tv_audio_codec_type audio_codec, + u32 bits, u32 frame_size_code) +{ + /* Only 4'b1011 24bit */ + u32 wl = 5 << 1 | 1; + u32 rpt_cnt = (audio_codec == AC3) ? 1536 * 2 - 1 : 0; + + HDMIPRINTK("repetition count = %d\n\r", rpt_cnt); + + /* 24bit and manual mode */ + writel(((rpt_cnt&0xf) << 4) | wl, + hdmi_base + S5P_SPDIFIN_USER_VALUE_1); + /* if PCM this value is 0 */ + writel((rpt_cnt >> 4)&0xff, + hdmi_base + S5P_SPDIFIN_USER_VALUE_2); + /* if PCM this value is 0 */ + writel(frame_size_code&0xff, + hdmi_base + S5P_SPDIFIN_USER_VALUE_3); + /* if PCM this value is 0 */ + writel((frame_size_code >> 8)&0xff, + hdmi_base + S5P_SPDIFIN_USER_VALUE_4); +} + +void __s5p_hdmi_audio_irq_enable(u32 irq_en) +{ + writel(irq_en, hdmi_base + S5P_SPDIFIN_IRQ_MASK); +} + + +void __s5p_hdmi_audio_set_aui(enum s5p_tv_audio_codec_type audio_codec, + u32 sample_rate, + u32 bits) +{ + u8 sum_of_bits, bytes1, bytes2, bytes3, check_sum; +#if 1 + /* Fix TestID 7-31 Audio InfoFrame issue*/ + u32 bit_rate; + u32 type = 0; + u32 ch = (audio_codec == PCM) ? 1 : 0; + u32 sample = 0; + u32 bpsType = 0; +#else + /* Ac3 16bit only */ + u32 bps = (audio_codec == PCM) ? bits : 16; + + /* AUI Packet set. */ + u32 type = (audio_codec == PCM) ? 1 : /* PCM */ + (audio_codec == AC3) ? 2 : 0; + /* AC3 or Refer stream header */ + u32 ch = (audio_codec == PCM) ? 1 : 0; + /* 2ch or refer to stream header */ + + u32 sample = (sample_rate == 32000) ? 1 : + (sample_rate == 44100) ? 2 : + (sample_rate == 48000) ? 3 : + (sample_rate == 88200) ? 4 : + (sample_rate == 96000) ? 5 : + (sample_rate == 176400) ? 6 : + (sample_rate == 192000) ? 7 : 0; + + u32 bpsType = (bps == 16) ? 1 : + (bps == 20) ? 2 : + (bps == 24) ? 3 : 0; +#endif + + bpsType = (audio_codec == PCM) ? bpsType : 0; + + sum_of_bits = (0x84 + 0x1 + 10); + + bytes1 = (u8)((type << 4) | ch); + + bytes2 = (u8)((sample << 2) | bpsType); + + bit_rate = 256; + + bytes3 = (audio_codec == PCM) ? (u8)0 : (u8)(bit_rate / 8) ; + + + sum_of_bits += (bytes1 + bytes2 + bytes3); + check_sum = 256 - sum_of_bits; + + /* AUI Packet set. */ + writel(check_sum , hdmi_base + S5P_AUI_CHECK_SUM); + writel(bytes1 , hdmi_base + S5P_AUI_BYTE1); + writel(bytes2 , hdmi_base + S5P_AUI_BYTE2); + writel(bytes3 , hdmi_base + S5P_AUI_BYTE3);/* Pcm or stream */ + writel(0x00 , hdmi_base + S5P_AUI_BYTE4); /* 2ch pcm or Stream */ + writel(0x00 , hdmi_base + S5P_AUI_BYTE5); /* 2ch pcm or Stream */ + + writel(HDMI_DO_NOT_TANS, hdmi_base + S5P_ACP_CON); + writel(1 , hdmi_base + S5P_ACP_TYPE); + + writel(0x10 , hdmi_base + S5P_GCP_BYTE1); + /* + * packet will be transmitted within 384 cycles + * after active sync. + */ +} + +void __s5p_hdmi_video_set_bluescreen(bool en, + u8 cb_b, + u8 y_g, + u8 cr_r) +{ + HDMIPRINTK("%d, %d, %d, %d\n\r", en, cb_b, y_g, cr_r); + + if (en) { + writel(SET_BLUESCREEN_0(cb_b), hdmi_base + S5P_BLUE_SCREEN_0); + writel(SET_BLUESCREEN_1(y_g), hdmi_base + S5P_BLUE_SCREEN_1); + writel(SET_BLUESCREEN_2(cr_r), hdmi_base + S5P_BLUE_SCREEN_2); + writel(readl(hdmi_base + S5P_HDMI_CON_0) | BLUE_SCR_EN, + hdmi_base + S5P_HDMI_CON_0); + + HDMIPRINTK("HDMI_BLUE_SCREEN0 = 0x%08x \n\r", + readl(hdmi_base + S5P_BLUE_SCREEN_0)); + HDMIPRINTK("HDMI_BLUE_SCREEN1 = 0x%08x \n\r", + readl(hdmi_base + S5P_BLUE_SCREEN_1)); + HDMIPRINTK("HDMI_BLUE_SCREEN2 = 0x%08x \n\r", + readl(hdmi_base + S5P_BLUE_SCREEN_2)); + } else + writel(readl(hdmi_base + S5P_HDMI_CON_0)&~BLUE_SCR_EN, + hdmi_base + S5P_HDMI_CON_0); + + HDMIPRINTK("HDMI_CON0 = 0x%08x \n\r", + readl(hdmi_base + S5P_HDMI_CON_0)); +} + +enum s5p_tv_hdmi_err __s5p_hdmi_init_spd_infoframe( + enum s5p_hdmi_transmit trans_type, + u8 *spd_header, + u8 *spd_data) +{ + HDMIPRINTK("%d, %d, %d\n\r", (u32)trans_type, + (u32)spd_header, + (u32)spd_data); + + switch (trans_type) { + + case HDMI_DO_NOT_TANS: + writel(SPD_TX_CON_NO_TRANS, hdmi_base + S5P_SPD_CON); + break; + + case HDMI_TRANS_ONCE: + writel(SPD_TX_CON_TRANS_ONCE, hdmi_base + S5P_SPD_CON); + break; + + case HDMI_TRANS_EVERY_SYNC: + writel(SPD_TX_CON_TRANS_EVERY_VSYNC, hdmi_base + S5P_SPD_CON); + break; + + default: + HDMIPRINTK(" invalid out_mode parameter(%d)\n\r", trans_type); + return S5P_TV_HDMI_ERR_INVALID_PARAM; + break; + } + + /* + * spd_data, spd_header be specified by Vendor's specific + * data. below codes is sample usage + */ + + if (spd_data == NULL || spd_header == NULL) { + HDMIPRINTK("Set default SPD\n"); + writel(SET_SPD_HEADER(0x83), hdmi_base + S5P_SPD_HEADER0); + writel(SET_SPD_HEADER(0x01), hdmi_base + S5P_SPD_HEADER1); + writel(SET_SPD_HEADER(0x19), hdmi_base + S5P_SPD_HEADER2); + + writel(0x0, hdmi_base + S5P_SPD_DATA0); + writel(SET_SPD_DATA('S'), hdmi_base + S5P_SPD_DATA1); + writel(SET_SPD_DATA('A'), hdmi_base + S5P_SPD_DATA2); + writel(SET_SPD_DATA('M'), hdmi_base + S5P_SPD_DATA3); + writel(SET_SPD_DATA('S'), hdmi_base + S5P_SPD_DATA4); + writel(SET_SPD_DATA('U'), hdmi_base + S5P_SPD_DATA5); + writel(SET_SPD_DATA('N'), hdmi_base + S5P_SPD_DATA6); + writel(SET_SPD_DATA('G'), hdmi_base + S5P_SPD_DATA7); + + writel(0x0, hdmi_base + S5P_SPD_DATA8); + writel(SET_SPD_DATA('S'), hdmi_base + S5P_SPD_DATA9); + writel(SET_SPD_DATA('5'), hdmi_base + S5P_SPD_DATA10); + writel(SET_SPD_DATA('P'), hdmi_base + S5P_SPD_DATA11); + writel(SET_SPD_DATA('C'), hdmi_base + S5P_SPD_DATA12); + writel(SET_SPD_DATA('1'), hdmi_base + S5P_SPD_DATA13); + writel(SET_SPD_DATA('1'), hdmi_base + S5P_SPD_DATA14); + writel(SET_SPD_DATA('0'), hdmi_base + S5P_SPD_DATA15); + writel(0x0, hdmi_base + S5P_SPD_DATA16); + writel(0x0, hdmi_base + S5P_SPD_DATA17); + writel(0x0, hdmi_base + S5P_SPD_DATA18); + writel(0x0, hdmi_base + S5P_SPD_DATA19); + writel(0x0, hdmi_base + S5P_SPD_DATA20); + writel(0x0, hdmi_base + S5P_SPD_DATA21); + writel(0x0, hdmi_base + S5P_SPD_DATA22); + writel(0x0, hdmi_base + S5P_SPD_DATA23); + writel(0x0, hdmi_base + S5P_SPD_DATA24); + writel(0x0, hdmi_base + S5P_SPD_DATA25); + writel(SET_SPD_DATA(0x2), hdmi_base + S5P_SPD_DATA26); + writel(0x0, hdmi_base + S5P_SPD_DATA27); + } else { + + writel(SET_SPD_HEADER(*(spd_header)), + hdmi_base + S5P_SPD_HEADER0); + + writel(SET_SPD_HEADER(*(spd_header + 1)) , + hdmi_base + S5P_SPD_HEADER1); + writel(SET_SPD_HEADER(*(spd_header + 2)) , + hdmi_base + S5P_SPD_HEADER2); + + writel(SET_SPD_DATA(*(spd_data)) , + hdmi_base + S5P_SPD_DATA0); + writel(SET_SPD_DATA(*(spd_data + 1)) , + hdmi_base + S5P_SPD_DATA1); + writel(SET_SPD_DATA(*(spd_data + 2)) , + hdmi_base + S5P_SPD_DATA2); + writel(SET_SPD_DATA(*(spd_data + 3)) , + hdmi_base + S5P_SPD_DATA3); + writel(SET_SPD_DATA(*(spd_data + 4)) , + hdmi_base + S5P_SPD_DATA4); + writel(SET_SPD_DATA(*(spd_data + 5)) , + hdmi_base + S5P_SPD_DATA5); + writel(SET_SPD_DATA(*(spd_data + 6)) , + hdmi_base + S5P_SPD_DATA6); + writel(SET_SPD_DATA(*(spd_data + 7)) , + hdmi_base + S5P_SPD_DATA7); + writel(SET_SPD_DATA(*(spd_data + 8)) , + hdmi_base + S5P_SPD_DATA8); + writel(SET_SPD_DATA(*(spd_data + 9)) , + hdmi_base + S5P_SPD_DATA9); + writel(SET_SPD_DATA(*(spd_data + 10)) , + hdmi_base + S5P_SPD_DATA10); + writel(SET_SPD_DATA(*(spd_data + 11)) , + hdmi_base + S5P_SPD_DATA11); + writel(SET_SPD_DATA(*(spd_data + 12)) , + hdmi_base + S5P_SPD_DATA12); + writel(SET_SPD_DATA(*(spd_data + 13)) , + hdmi_base + S5P_SPD_DATA13); + writel(SET_SPD_DATA(*(spd_data + 14)) , + hdmi_base + S5P_SPD_DATA14); + writel(SET_SPD_DATA(*(spd_data + 15)) , + hdmi_base + S5P_SPD_DATA15); + writel(SET_SPD_DATA(*(spd_data + 16)) , + hdmi_base + S5P_SPD_DATA16); + writel(SET_SPD_DATA(*(spd_data + 17)) , + hdmi_base + S5P_SPD_DATA17); + writel(SET_SPD_DATA(*(spd_data + 18)) , + hdmi_base + S5P_SPD_DATA18); + writel(SET_SPD_DATA(*(spd_data + 19)) , + hdmi_base + S5P_SPD_DATA19); + writel(SET_SPD_DATA(*(spd_data + 20)) , + hdmi_base + S5P_SPD_DATA20); + writel(SET_SPD_DATA(*(spd_data + 21)) , + hdmi_base + S5P_SPD_DATA21); + writel(SET_SPD_DATA(*(spd_data + 22)) , + hdmi_base + S5P_SPD_DATA22); + writel(SET_SPD_DATA(*(spd_data + 23)) , + hdmi_base + S5P_SPD_DATA23); + writel(SET_SPD_DATA(*(spd_data + 24)) , + hdmi_base + S5P_SPD_DATA24); + writel(SET_SPD_DATA(*(spd_data + 25)) , + hdmi_base + S5P_SPD_DATA25); + writel(SET_SPD_DATA(*(spd_data + 26)) , + hdmi_base + S5P_SPD_DATA26); + writel(SET_SPD_DATA(*(spd_data + 27)) , + hdmi_base + S5P_SPD_DATA27); + } + + HDMIPRINTK("SPD_CON = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_CON)); + HDMIPRINTK("SPD_HEADER0 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_HEADER0)); + HDMIPRINTK("SPD_HEADER1 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_HEADER1)); + HDMIPRINTK("SPD_HEADER2 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_HEADER2)); + HDMIPRINTK("SPD_DATA0 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA0)); + HDMIPRINTK("SPD_DATA1 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA1)); + HDMIPRINTK("SPD_DATA2 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA2)); + HDMIPRINTK("SPD_DATA3 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA3)); + HDMIPRINTK("SPD_DATA4 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA4)); + HDMIPRINTK("SPD_DATA5 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA5)); + HDMIPRINTK("SPD_DATA6 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA6)); + HDMIPRINTK("SPD_DATA7 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA7)); + HDMIPRINTK("SPD_DATA8 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA8)); + HDMIPRINTK("SPD_DATA9 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA9)); + HDMIPRINTK("SPD_DATA10 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA10)); + HDMIPRINTK("SPD_DATA11 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA11)); + HDMIPRINTK("SPD_DATA12 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA12)); + HDMIPRINTK("SPD_DATA13 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA13)); + HDMIPRINTK("SPD_DATA14 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA14)); + HDMIPRINTK("SPD_DATA15 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA15)); + HDMIPRINTK("SPD_DATA16 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA16)); + HDMIPRINTK("SPD_DATA17 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA17)); + HDMIPRINTK("SPD_DATA18 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA18)); + HDMIPRINTK("SPD_DATA19 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA19)); + HDMIPRINTK("SPD_DATA20 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA20)); + HDMIPRINTK("SPD_DATA21 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA21)); + HDMIPRINTK("SPD_DATA22 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA22)); + HDMIPRINTK("SPD_DATA23 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA23)); + HDMIPRINTK("SPD_DATA24 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA24)); + HDMIPRINTK("SPD_DATA25 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA25)); + HDMIPRINTK("SPD_DATA26 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA26)); + HDMIPRINTK("SPD_DATA27 = 0x%08x \n\r", + readl(hdmi_base + S5P_SPD_DATA27)); + + return HDMI_NO_ERROR; +} + +void __s5p_hdmi_init_hpd_onoff(bool on_off) +{ + HDMIPRINTK("%d\n\r", on_off); + __s5p_hdmi_set_hpd_onoff(on_off); + HDMIPRINTK("0x%08x\n\r", readl(hdmi_base + S5P_HPD)); +} + +#ifndef CONFIG_SND_S5P_SPDIF +static void __s5p_hdmi_audio_i2s_config( + enum s5p_tv_audio_codec_type audio_codec, + u32 sample_rate, + u32 bits_per_sample, + u32 frame_size_code) +{ + u32 data_num, bit_ch, sample_frq; + + if (bits_per_sample == 20) { + data_num = 2; + bit_ch = 1; + } else if (bits_per_sample == 24) { + data_num = 3; + bit_ch = 1; + } else { + data_num = 1; + bit_ch = 0; + } + sample_frq = (sample_rate == 44100) ? 0 : + (sample_rate == 48000) ? 2 : + (sample_rate == 32000) ? 3 : + (sample_rate == 96000) ? 0xa : 0x0; + + /* readl(hdmi_base + S5P_HDMI_YMAX) */ + writel(0x00, hdmi_base + S5P_HDMI_I2S_CLK_CON); + writel(0x01, hdmi_base + S5P_HDMI_I2S_CLK_CON); + + writel(readl(hdmi_base + S5P_HDMI_I2S_DSD_CON) | 0x01, + hdmi_base + S5P_HDMI_I2S_DSD_CON); + + /* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */ + writel((readl(hdmi_base + S5P_HDMI_I2S_PIN_SEL_0) & + ~(7<<4 | 7<<0)) | (5<<4|6<<0), + hdmi_base + S5P_HDMI_I2S_PIN_SEL_0); + writel((readl(hdmi_base + S5P_HDMI_I2S_PIN_SEL_1) & + ~(7<<4 | 7<<0)) | (1<<4|4<<0), + hdmi_base + S5P_HDMI_I2S_PIN_SEL_1); + writel((readl(hdmi_base + S5P_HDMI_I2S_PIN_SEL_2) & + ~(7<<4 | 7<<0)) | (1<<4|2<<0), + hdmi_base + S5P_HDMI_I2S_PIN_SEL_2); + writel((readl(hdmi_base + S5P_HDMI_I2S_PIN_SEL_3) & + ~(7<<0)) | (0<<0), + hdmi_base + S5P_HDMI_I2S_PIN_SEL_3); + + /* I2S_CON_1 & 2 */ + writel((readl(hdmi_base + S5P_HDMI_I2S_CON_1) & + ~(1<<1 | 1<<0)) | (1<<1|0<<0), + hdmi_base + S5P_HDMI_I2S_CON_1); + writel((readl(hdmi_base + S5P_HDMI_I2S_CON_2) & + ~(1<<6 | 3<<4 | 3<<2 | 3<<0)) + | (0<<6 | bit_ch<<4 | data_num<<2 | 0<<0), + hdmi_base + S5P_HDMI_I2S_CON_2); + + /* Configure register related to CUV information */ + writel((readl(hdmi_base + S5P_HDMI_I2S_CH_ST_0) & + ~(3<<6 | 7<<3 | 1<<2 | 1<<1 | 1<<0)) + | (0<<6 | 0<<3 | 0<<2 | 0<<1 | 1<<0), + hdmi_base + S5P_HDMI_I2S_CH_ST_0); + writel((readl(hdmi_base + S5P_HDMI_I2S_CH_ST_1) & + ~(0xff<<0)) | (0<<0), + hdmi_base + S5P_HDMI_I2S_CH_ST_1); + writel((readl(hdmi_base + S5P_HDMI_I2S_CH_ST_2) & + ~(0xff<<0)) | (0<<0), + hdmi_base + S5P_HDMI_I2S_CH_ST_2); + writel((readl(hdmi_base + S5P_HDMI_I2S_CH_ST_3) & + ~(3<<4 | 0xf<<0)) + | (0<<4 | sample_frq<<0), + hdmi_base + S5P_HDMI_I2S_CH_ST_3); + writel((readl(hdmi_base + S5P_HDMI_I2S_CH_ST_4) & + ~(0xf<<4 | 7<<1 | 1<<0)) + | (0xf<<4 | 5<<1 | 1<<0), + hdmi_base + S5P_HDMI_I2S_CH_ST_4); + + writel(0x00, hdmi_base + S5P_HDMI_I2S_CH_ST_SH_0); + writel(0x00, hdmi_base + S5P_HDMI_I2S_CH_ST_SH_1); + writel(0x00, hdmi_base + S5P_HDMI_I2S_CH_ST_SH_2); + writel(0x00, hdmi_base + S5P_HDMI_I2S_CH_ST_SH_3); + writel(0x00, hdmi_base + S5P_HDMI_I2S_CH_ST_SH_4); + + writel((readl(hdmi_base + S5P_HDMI_I2S_CH_ST_CON) & + ~(1<<0)) | (1<<0), + hdmi_base + S5P_HDMI_I2S_CH_ST_CON); + + writel((readl(hdmi_base + S5P_HDMI_I2S_MUX_CON) & + ~(1<<4 | 3<<2 | 1<<1 | 1<<0)) + | (1<<4 | 1<<2 | 1<<1 | 1<<0), + hdmi_base + S5P_HDMI_I2S_MUX_CON); + + writel((readl(hdmi_base + S5P_HDMI_I2S_MUX_CH) & + ~(0xff<<0)) | (0x3f<<0), + hdmi_base + S5P_HDMI_I2S_MUX_CH); + + writel((readl(hdmi_base + S5P_HDMI_I2S_MUX_CUV) & + ~(0x3<<0)) | (0x3<<0), + hdmi_base + S5P_HDMI_I2S_MUX_CUV); +} +#endif + +enum s5p_tv_hdmi_err __s5p_hdmi_audio_init( + enum s5p_tv_audio_codec_type audio_codec, + u32 sample_rate, u32 bits, u32 frame_size_code) +{ +#ifdef CONFIG_SND_S5P_SPDIF + __s5p_hdmi_audio_set_config(audio_codec); + __s5p_hdmi_audio_set_repetition_time(audio_codec, bits, + frame_size_code); + __s5p_hdmi_audio_irq_enable(IRQ_BUFFER_OVERFLOW_ENABLE); + __s5p_hdmi_audio_clock_enable(); +#else + __s5p_hdmi_audio_i2s_config(audio_codec, sample_rate, bits, + frame_size_code); +#endif + __s5p_hdmi_audio_set_asp(); + __s5p_hdmi_audio_set_acr(sample_rate); + + __s5p_hdmi_audio_set_aui(audio_codec, sample_rate, bits); + + return HDMI_NO_ERROR; +} + +enum s5p_tv_hdmi_err __s5p_hdmi_video_init_display_mode( + enum s5p_tv_disp_mode disp_mode, + enum s5p_tv_o_mode out_mode, u8 *avidata) +{ + enum s5p_hdmi_v_fmt hdmi_v_fmt; + enum s5p_tv_hdmi_pxl_aspect aspect; + + HDMIPRINTK("disp mode %d, output mode%d\n\r", disp_mode, out_mode); + + aspect = HDMI_PIXEL_RATIO_16_9; + + switch (disp_mode) { + /* 480p */ + case TVOUT_480P_60_16_9: + hdmi_v_fmt = v720x480p_60Hz; + break; + + case TVOUT_480P_60_4_3: + hdmi_v_fmt = v720x480p_60Hz; + aspect = HDMI_PIXEL_RATIO_4_3; + break; + + case TVOUT_480P_59: + hdmi_v_fmt = v720x480p_59Hz; + break; + + /* 576p */ + case TVOUT_576P_50_16_9: + hdmi_v_fmt = v720x576p_50Hz; + break; + + case TVOUT_576P_50_4_3: + hdmi_v_fmt = v720x576p_50Hz; + aspect = HDMI_PIXEL_RATIO_4_3; + break; + + /* 720p */ + case TVOUT_720P_60: + hdmi_v_fmt = v1280x720p_60Hz; + break; + + case TVOUT_720P_59: + hdmi_v_fmt = v1280x720p_59Hz; + break; + + case TVOUT_720P_50: + hdmi_v_fmt = v1280x720p_50Hz; + break; + + /* 1080p */ + case TVOUT_1080P_30: + hdmi_v_fmt = v1920x1080p_30Hz; + break; + + case TVOUT_1080P_60: + hdmi_v_fmt = v1920x1080p_60Hz; + break; + + case TVOUT_1080P_59: + hdmi_v_fmt = v1920x1080p_59Hz; + break; + + case TVOUT_1080P_50: + hdmi_v_fmt = v1920x1080p_50Hz; + break; + + /* 1080i */ + case TVOUT_1080I_60: + hdmi_v_fmt = v1920x1080i_60Hz; + break; + + case TVOUT_1080I_59: + hdmi_v_fmt = v1920x1080i_59Hz; + break; + + case TVOUT_1080I_50: + hdmi_v_fmt = v1920x1080i_50Hz; + break; + + default: + HDMIPRINTK(" invalid disp_mode parameter(%d)\n\r", disp_mode); + return S5P_TV_HDMI_ERR_INVALID_PARAM; + break; + } + + if (hdmi_phy_config(video_params[hdmi_v_fmt].pixel_clock, HDMI_CD_24) + == EINVAL) { + HDMIPRINTK("[ERR] hdmi_phy_config() failed.\n"); + return EINVAL; + } + + switch (out_mode) { + case TVOUT_OUTPUT_HDMI_RGB: + s5p_hdmi_set_dvi(false); + writel(PX_LMT_CTRL_RGB, hdmi_base + S5P_HDMI_CON_1); + writel(VID_PREAMBLE_EN | GUARD_BAND_EN, + hdmi_base + S5P_HDMI_CON_2); + writel(HDMI_MODE_EN | DVI_MODE_DIS, + hdmi_base + S5P_MODE_SEL); + + /* there's no ACP packet api */ + writel(HDMI_DO_NOT_TANS , hdmi_base + S5P_ACP_CON); + writel(HDMI_TRANS_EVERY_SYNC , hdmi_base + S5P_AUI_CON); + break; + + case TVOUT_OUTPUT_HDMI: + s5p_hdmi_set_dvi(false); + writel(PX_LMT_CTRL_BYPASS, hdmi_base + S5P_HDMI_CON_1); + writel(VID_PREAMBLE_EN | GUARD_BAND_EN, + hdmi_base + S5P_HDMI_CON_2); + writel(HDMI_MODE_EN | DVI_MODE_DIS, + hdmi_base + S5P_MODE_SEL); + + /* there's no ACP packet api */ + writel(HDMI_DO_NOT_TANS , hdmi_base + S5P_ACP_CON); + writel(HDMI_TRANS_EVERY_SYNC , hdmi_base + S5P_AUI_CON); + break; + + + case TVOUT_OUTPUT_DVI: + s5p_hdmi_set_dvi(true); + writel(PX_LMT_CTRL_RGB, hdmi_base + S5P_HDMI_CON_1); + writel(VID_PREAMBLE_DIS | GUARD_BAND_DIS, + hdmi_base + S5P_HDMI_CON_2); + writel(HDMI_MODE_DIS | DVI_MODE_EN, + hdmi_base + S5P_MODE_SEL); + + /* disable ACP & Audio Info.frame packet */ + writel(HDMI_DO_NOT_TANS , hdmi_base + S5P_ACP_CON); + writel(HDMI_DO_NOT_TANS , hdmi_base + S5P_AUI_CON); + break; + + default: + HDMIPRINTK("invalid out_mode parameter(%d)\n\r", out_mode); + return S5P_TV_HDMI_ERR_INVALID_PARAM; + break; + } + + hdmi_set_video_mode(hdmi_v_fmt, HDMI_CD_24, aspect, avidata); + + return HDMI_NO_ERROR; +} + +void __s5p_hdmi_video_init_bluescreen(bool en, + u8 cb_b, + u8 y_g, + u8 cr_r) +{ + __s5p_hdmi_video_set_bluescreen(en, cb_b, y_g, cr_r); + +} + +void __s5p_hdmi_video_init_color_range(u8 y_min, + u8 y_max, + u8 c_min, + u8 c_max) +{ + HDMIPRINTK("%d, %d, %d, %d\n\r", y_max, y_min, c_max, c_min); + + writel(y_max, hdmi_base + S5P_HDMI_YMAX); + writel(y_min, hdmi_base + S5P_HDMI_YMIN); + writel(c_max, hdmi_base + S5P_HDMI_CMAX); + writel(c_min, hdmi_base + S5P_HDMI_CMIN); + + HDMIPRINTK("HDMI_YMAX = 0x%08x \n\r", + readl(hdmi_base + S5P_HDMI_YMAX)); + HDMIPRINTK("HDMI_YMIN = 0x%08x \n\r", + readl(hdmi_base + S5P_HDMI_YMIN)); + HDMIPRINTK("HDMI_CMAX = 0x%08x \n\r", + readl(hdmi_base + S5P_HDMI_CMAX)); + HDMIPRINTK("HDMI_CMIN = 0x%08x \n\r", + readl(hdmi_base + S5P_HDMI_CMIN)); +} + +enum s5p_tv_hdmi_err __s5p_hdmi_video_init_csc( + enum s5p_tv_hdmi_csc_type csc_type) +{ + unsigned short us_csc_coeff[10]; + + HDMIPRINTK("%d)\n\r", csc_type); + + switch (csc_type) { + + case HDMI_CSC_YUV601_TO_RGB_LR: + us_csc_coeff[0] = 0x23; + us_csc_coeff[1] = 256; + us_csc_coeff[2] = 938; + us_csc_coeff[3] = 846; + us_csc_coeff[4] = 256; + us_csc_coeff[5] = 443; + us_csc_coeff[6] = 0; + us_csc_coeff[7] = 256; + us_csc_coeff[8] = 0; + us_csc_coeff[9] = 350; + break; + + case HDMI_CSC_YUV601_TO_RGB_FR: + us_csc_coeff[0] = 0x03; + us_csc_coeff[1] = 298; + us_csc_coeff[2] = 924; + us_csc_coeff[3] = 816; + us_csc_coeff[4] = 298; + us_csc_coeff[5] = 516; + us_csc_coeff[6] = 0; + us_csc_coeff[7] = 298; + us_csc_coeff[8] = 0; + us_csc_coeff[9] = 408; + break; + + case HDMI_CSC_YUV709_TO_RGB_LR: + us_csc_coeff[0] = 0x23; + us_csc_coeff[1] = 256; + us_csc_coeff[2] = 978; + us_csc_coeff[3] = 907; + us_csc_coeff[4] = 256; + us_csc_coeff[5] = 464; + us_csc_coeff[6] = 0; + us_csc_coeff[7] = 256; + us_csc_coeff[8] = 0; + us_csc_coeff[9] = 394; + break; + + case HDMI_CSC_YUV709_TO_RGB_FR: + us_csc_coeff[0] = 0x03; + us_csc_coeff[1] = 298; + us_csc_coeff[2] = 970; + us_csc_coeff[3] = 888; + us_csc_coeff[4] = 298; + us_csc_coeff[5] = 540; + us_csc_coeff[6] = 0; + us_csc_coeff[7] = 298; + us_csc_coeff[8] = 0; + us_csc_coeff[9] = 458; + break; + + case HDMI_CSC_YUV601_TO_YUV709: + us_csc_coeff[0] = 0x33; + us_csc_coeff[1] = 256; + us_csc_coeff[2] = 995; + us_csc_coeff[3] = 971; + us_csc_coeff[4] = 0; + us_csc_coeff[5] = 260; + us_csc_coeff[6] = 29; + us_csc_coeff[7] = 0; + us_csc_coeff[8] = 19; + us_csc_coeff[9] = 262; + break; + + case HDMI_CSC_RGB_FR_TO_RGB_LR: + us_csc_coeff[0] = 0x20; + us_csc_coeff[1] = 220; + us_csc_coeff[2] = 0; + us_csc_coeff[3] = 0; + us_csc_coeff[4] = 0; + us_csc_coeff[5] = 220; + us_csc_coeff[6] = 0; + us_csc_coeff[7] = 0; + us_csc_coeff[8] = 0; + us_csc_coeff[9] = 220; + break; + + case HDMI_CSC_RGB_FR_TO_YUV601: + us_csc_coeff[0] = 0x30; + us_csc_coeff[1] = 129; + us_csc_coeff[2] = 25; + us_csc_coeff[3] = 65; + us_csc_coeff[4] = 950; + us_csc_coeff[5] = 112; + us_csc_coeff[6] = 986; + us_csc_coeff[7] = 930; + us_csc_coeff[8] = 1006; + us_csc_coeff[9] = 112; + break; + + case HDMI_CSC_RGB_FR_TO_YUV709: + us_csc_coeff[0] = 0x30; + us_csc_coeff[1] = 157; + us_csc_coeff[2] = 16; + us_csc_coeff[3] = 47; + us_csc_coeff[4] = 937; + us_csc_coeff[5] = 112; + us_csc_coeff[6] = 999; + us_csc_coeff[7] = 922; + us_csc_coeff[8] = 1014; + us_csc_coeff[9] = 112; + break; + + case HDMI_BYPASS: + us_csc_coeff[0] = 0x33; + us_csc_coeff[1] = 256; + us_csc_coeff[2] = 0; + us_csc_coeff[3] = 0; + us_csc_coeff[4] = 0; + us_csc_coeff[5] = 256; + us_csc_coeff[6] = 0; + us_csc_coeff[7] = 0; + us_csc_coeff[8] = 0; + us_csc_coeff[9] = 256; + break; + + default: + HDMIPRINTK("invalid out_mode parameter(%d)\n\r", csc_type); + return S5P_TV_HDMI_ERR_INVALID_PARAM; + break; + } + return HDMI_NO_ERROR; +} + +enum s5p_tv_hdmi_err __s5p_hdmi_video_init_avi_infoframe( + enum s5p_hdmi_transmit trans_type, u8 check_sum, u8 *avi_data) +{ + HDMIPRINTK("%d, %d, %d\n\r", (u32)trans_type, (u32)check_sum, + (u32)avi_data); + + switch (trans_type) { + + case HDMI_DO_NOT_TANS: + writel(AVI_TX_CON_NO_TRANS, hdmi_base + S5P_AVI_CON); + break; + + case HDMI_TRANS_ONCE: + writel(AVI_TX_CON_TRANS_ONCE, hdmi_base + S5P_AVI_CON); + break; + + case HDMI_TRANS_EVERY_SYNC: + writel(AVI_TX_CON_TRANS_EVERY_VSYNC, hdmi_base + S5P_AVI_CON); + break; + + default: + HDMIPRINTK(" invalid out_mode parameter(%d)\n\r", trans_type); + return S5P_TV_HDMI_ERR_INVALID_PARAM; + break; + } + + writel(SET_AVI_CHECK_SUM(check_sum), hdmi_base + S5P_AVI_CHECK_SUM); + + writel(SET_AVI_BYTE(*(avi_data)), hdmi_base + S5P_AVI_BYTE1); + writel(SET_AVI_BYTE(*(avi_data + 1)), hdmi_base + S5P_AVI_BYTE2); + writel(SET_AVI_BYTE(*(avi_data + 2)), hdmi_base + S5P_AVI_BYTE3); + writel(SET_AVI_BYTE(*(avi_data + 3)), hdmi_base + S5P_AVI_BYTE4); + writel(SET_AVI_BYTE(*(avi_data + 4)), hdmi_base + S5P_AVI_BYTE5); + writel(SET_AVI_BYTE(*(avi_data + 5)), hdmi_base + S5P_AVI_BYTE6); + writel(SET_AVI_BYTE(*(avi_data + 6)), hdmi_base + S5P_AVI_BYTE7); + writel(SET_AVI_BYTE(*(avi_data + 7)), hdmi_base + S5P_AVI_BYTE8); + writel(SET_AVI_BYTE(*(avi_data + 8)), hdmi_base + S5P_AVI_BYTE9); + writel(SET_AVI_BYTE(*(avi_data + 9)), hdmi_base + S5P_AVI_BYTE10); + writel(SET_AVI_BYTE(*(avi_data + 10)), hdmi_base + S5P_AVI_BYTE11); + writel(SET_AVI_BYTE(*(avi_data + 11)), hdmi_base + S5P_AVI_BYTE12); + writel(SET_AVI_BYTE(*(avi_data + 12)), hdmi_base + S5P_AVI_BYTE13); + + HDMIPRINTK("AVI_CON = 0x%08x \n\r", readl(hdmi_base + S5P_AVI_CON)); + HDMIPRINTK("AVI_CHECK_SUM = 0x%08x \n\r", + readl(hdmi_base + S5P_AVI_CHECK_SUM)); + HDMIPRINTK("AVI_BYTE1 = 0x%08x \n\r", + readl(hdmi_base + S5P_AVI_BYTE1)); + HDMIPRINTK("AVI_BYTE2 = 0x%08x \n\r", + readl(hdmi_base + S5P_AVI_BYTE2)); + HDMIPRINTK("AVI_BYTE3 = 0x%08x \n\r", + readl(hdmi_base + S5P_AVI_BYTE3)); + HDMIPRINTK("AVI_BYTE4 = 0x%08x \n\r", + readl(hdmi_base + S5P_AVI_BYTE4)); + HDMIPRINTK("AVI_BYTE5 = 0x%08x \n\r", + readl(hdmi_base + S5P_AVI_BYTE5)); + HDMIPRINTK("AVI_BYTE6 = 0x%08x \n\r", + readl(hdmi_base + S5P_AVI_BYTE6)); + HDMIPRINTK("AVI_BYTE7 = 0x%08x \n\r", + readl(hdmi_base + S5P_AVI_BYTE7)); + HDMIPRINTK("AVI_BYTE8 = 0x%08x \n\r", + readl(hdmi_base + S5P_AVI_BYTE8)); + HDMIPRINTK("AVI_BYTE9 = 0x%08x \n\r", + readl(hdmi_base + S5P_AVI_BYTE9)); + HDMIPRINTK("AVI_BYTE10 = 0x%08x \n\r", + readl(hdmi_base + S5P_AVI_BYTE10)); + HDMIPRINTK("AVI_BYTE11 = 0x%08x \n\r", + readl(hdmi_base + S5P_AVI_BYTE11)); + HDMIPRINTK("AVI_BYTE12 = 0x%08x \n\r", + readl(hdmi_base + S5P_AVI_BYTE12)); + HDMIPRINTK("AVI_BYTE13 = 0x%08x \n\r", + readl(hdmi_base + S5P_AVI_BYTE13)); + + return HDMI_NO_ERROR; +} + +enum s5p_tv_hdmi_err __s5p_hdmi_video_init_mpg_infoframe( + enum s5p_hdmi_transmit trans_type, u8 check_sum, u8 *mpg_data) +{ + HDMIPRINTK("trans_type : %d, %d, %d\n\r", (u32)trans_type, + (u32)check_sum, (u32)mpg_data); + + switch (trans_type) { + + case HDMI_DO_NOT_TANS: + writel(MPG_TX_CON_NO_TRANS, + hdmi_base + S5P_MPG_CON); + break; + + case HDMI_TRANS_ONCE: + writel(MPG_TX_CON_TRANS_ONCE, + hdmi_base + S5P_MPG_CON); + break; + + case HDMI_TRANS_EVERY_SYNC: + writel(MPG_TX_CON_TRANS_EVERY_VSYNC, + hdmi_base + S5P_MPG_CON); + break; + + default: + HDMIPRINTK("invalid out_mode parameter(%d)\n\r", + trans_type); + return S5P_TV_HDMI_ERR_INVALID_PARAM; + break; + } + + writel(SET_MPG_CHECK_SUM(check_sum), + + hdmi_base + S5P_MPG_CHECK_SUM); + + writel(SET_MPG_BYTE(*(mpg_data)), + hdmi_base + S5P_MPEG_BYTE1); + writel(SET_MPG_BYTE(*(mpg_data + 1)), + hdmi_base + S5P_MPEG_BYTE2); + writel(SET_MPG_BYTE(*(mpg_data + 2)), + hdmi_base + S5P_MPEG_BYTE3); + writel(SET_MPG_BYTE(*(mpg_data + 3)), + hdmi_base + S5P_MPEG_BYTE4); + writel(SET_MPG_BYTE(*(mpg_data + 4)), + hdmi_base + S5P_MPEG_BYTE5); + + HDMIPRINTK("MPG_CON = 0x%08x \n\r", + readl(hdmi_base + S5P_MPG_CON)); + HDMIPRINTK("MPG_CHECK_SUM = 0x%08x \n\r", + readl(hdmi_base + S5P_MPG_CHECK_SUM)); + HDMIPRINTK("MPEG_BYTE1 = 0x%08x \n\r", + readl(hdmi_base + S5P_MPEG_BYTE1)); + HDMIPRINTK("MPEG_BYTE2 = 0x%08x \n\r", + readl(hdmi_base + S5P_MPEG_BYTE2)); + HDMIPRINTK("MPEG_BYTE3 = 0x%08x \n\r", + readl(hdmi_base + S5P_MPEG_BYTE3)); + HDMIPRINTK("MPEG_BYTE4 = 0x%08x \n\r", + readl(hdmi_base + S5P_MPEG_BYTE4)); + HDMIPRINTK("MPEG_BYTE5 = 0x%08x \n\r", + readl(hdmi_base + S5P_MPEG_BYTE5)); + + return HDMI_NO_ERROR; +} + +void __s5p_hdmi_video_init_tg_cmd(bool time_c_e, + bool bt656_sync_en, + bool tg_en) +{ + u32 temp_reg = 0; + + temp_reg = readl(hdmi_base + S5P_TG_CMD); + + if (time_c_e) + temp_reg |= GETSYNC_TYPE_EN; + else + temp_reg &= GETSYNC_TYPE_DIS; + + if (bt656_sync_en) + temp_reg |= GETSYNC_EN; + else + temp_reg &= GETSYNC_DIS; + + if (tg_en) + temp_reg |= TG_EN; + else + temp_reg &= TG_DIS; + + writel(temp_reg, hdmi_base + S5P_TG_CMD); + + HDMIPRINTK("TG_CMD = 0x%08x \n\r", readl(hdmi_base + S5P_TG_CMD)); +} + +bool __s5p_hdmi_start(enum s5p_hdmi_audio_type hdmi_audio_type, + bool hdcp_en, + struct i2c_client *ddc_port) +{ + u32 temp_reg = HDMI_EN; + + HDMIPRINTK("aud type : %d, hdcp enable : %d\n\r", + hdmi_audio_type, hdcp_en); + + switch (hdmi_audio_type) { + + case HDMI_AUDIO_PCM: + temp_reg |= ASP_EN; + break; + + case HDMI_AUDIO_NO: + break; + + default: + HDMIPRINTK(" invalid hdmi_audio_type(%d)\n\r", + hdmi_audio_type); + return false; + break; + } + if (hdcp_en) { + writel(HDCP_ENC_DISABLE, hdmi_base + S5P_ENC_EN); + s5p_hdmi_mute_en(true); + } + + writel(readl(hdmi_base + S5P_HDMI_CON_0) | temp_reg, + hdmi_base + S5P_HDMI_CON_0); + +#ifdef CONFIG_HDMI_HPD + s5p_hpd_set_hdmiint(); +#endif + +#if 1 + if (hdcp_en) { + + + if (!__s5p_start_hdcp()) + HDMIPRINTK("HDCP start failed\n"); + + } + +#endif + HDMIPRINTK("HPD : 0x%08x, HDMI_CON_0 : 0x%08x\n\r", + readl(hdmi_base + S5P_HPD), + readl(hdmi_base + S5P_HDMI_CON_0)); + + return true; +} + +/* +* stop - stop functions are only called under running HDMI +*/ +void __s5p_hdmi_stop(void) +{ + u32 temp = 0, result = 0; + + HDMIPRINTK("\n\r"); + + __s5p_stop_hdcp(); + + /* + * Before stopping hdmi, stop the hdcp first. However, + * if there's no delay between hdcp stop & hdmi stop, + * re-opening would be failed. + */ + mdelay(100); + + temp = readl(hdmi_base + S5P_HDMI_CON_0); + result = temp & HDMI_EN; + + if (result) + writel(temp & ~(HDMI_EN | ASP_EN), + hdmi_base + S5P_HDMI_CON_0); + + do { + temp = readl(hdmi_base + S5P_HDMI_CON_0); + } while (temp & HDMI_EN); + +#ifdef CONFIG_HDMI_HPD + s5p_hpd_set_eint(); +#endif + HDMIPRINTK("HPD 0x%08x, HDMI_CON_0 0x%08x\n\r", + readl(hdmi_base + S5P_HPD), + readl(hdmi_base + S5P_HDMI_CON_0)); +} + +int __init __s5p_hdmi_probe(struct platform_device *pdev, + u32 res_num, u32 res_num2) +{ + struct resource *res; + size_t size; + u32 reg; + + spin_lock_init(&lock_hdmi); + + 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; + + hdmi_mem = request_mem_region(res->start, size, pdev->name); + + if (hdmi_mem == NULL) { + dev_err(&pdev->dev, + "failed to get memory region\n"); + goto error; + } + + hdmi_base = ioremap(res->start, size); + + if (hdmi_base == NULL) { + dev_err(&pdev->dev, + "failed to ioremap address region\n"); + goto error; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, res_num2); + + if (res == NULL) { + dev_err(&pdev->dev, + "failed to get memory region resource\n"); + goto error; + } + + size = (res->end - res->start) + 1; + + i2c_hdmi_phy_mem = request_mem_region(res->start, size, pdev->name); + + if (i2c_hdmi_phy_mem == NULL) { + dev_err(&pdev->dev, + "failed to get memory region\n"); + goto error; + } + + i2c_hdmi_phy_base = ioremap(res->start, size); + + if (i2c_hdmi_phy_base == NULL) { + dev_err(&pdev->dev, + "failed to ioremap address region\n"); + goto error; + } + + /* PMU Block : HDMI PHY Enable */ + reg = readl(S3C_VA_SYS+0xE804); + reg |= (1<<0); + writel(reg, S3C_VA_SYS+0xE804); + + /* i2c_hdmi init - set i2c filtering */ + writeb(0x5, i2c_hdmi_phy_base + I2C_HDMI_LC); + + /* temp for test - hdmi intr. global enable */ + reg = readb(hdmi_base+S5P_HDMI_CTRL_INTC_CON); + writeb(reg | (1<<HDMI_IRQ_GLOBAL), hdmi_base+S5P_HDMI_CTRL_INTC_CON); + + return 0; +error: + return -ENOENT; +} + +int __init __s5p_hdmi_release(struct platform_device *pdev) +{ + iounmap(hdmi_base); + + /* remove memory region */ + if (hdmi_mem != NULL) { + if (release_resource(hdmi_mem)) + dev_err(&pdev->dev, + "Can't remove tvout drv !!\n"); + + kfree(hdmi_mem); + + hdmi_mem = NULL; + } + + return 0; +} + +/* + * HDCP ISR. + * If HDCP IRQ occurs, set hdcp_event and wake up the waitqueue. + */ + +#define HDMI_IRQ_TOTAL_NUM 6 + +hdmi_isr hdmi_isr_ftn[HDMI_IRQ_TOTAL_NUM]; + +int s5p_hdmi_register_isr(hdmi_isr isr, u8 irq_num) +{ + HDMIPRINTK("Try to register ISR for IRQ number (%d)\n", irq_num); + + if (isr == NULL) { + HDMIPRINTK("Invaild ISR\n"); + return -EINVAL; + } + + /* check IRQ number */ + if (irq_num > HDMI_IRQ_TOTAL_NUM) { + HDMIPRINTK("irq_num exceeds allowed IRQ number(%d)\n", + HDMI_IRQ_TOTAL_NUM); + return -EINVAL; + } + + /* check if is the number already registered? */ + if (hdmi_isr_ftn[irq_num]) { + HDMIPRINTK("the %d th ISR is already registered\n", + irq_num); + } + + hdmi_isr_ftn[irq_num] = isr; + + HDMIPRINTK("Success to register ISR for IRQ number (%d)\n", + irq_num); + + return 0; +} +EXPORT_SYMBOL(s5p_hdmi_register_isr); + +irqreturn_t __s5p_hdmi_irq(int irq, void *dev_id) +{ + u8 irq_state, irq_num; + + spin_lock_irq(&lock_hdmi); + + irq_state = readb(hdmi_base+S5P_HDMI_CTRL_INTC_FLAG); + + HDMIPRINTK("S5P_HDMI_CTRL_INTC_FLAG = 0x%02x\n", irq_state); + + /* Check interrupt happened */ + /* Priority of Interrupt HDCP> I2C > Audio > CEC (Not implemented) */ + + if (irq_state) { + /* HDCP IRQ*/ + irq_num = 0; + /* check if ISR is null or not */ + while (irq_num < HDMI_IRQ_TOTAL_NUM) { + if (irq_state & (1<<irq_num)) { + if (hdmi_isr_ftn[irq_num] != NULL) + (hdmi_isr_ftn[irq_num])(irq_num); + else + HDMIPRINTK( + "No registered ISR for IRQ[%d]\n", + irq_num); + + } + ++irq_num; + } + + } else { + HDMIPRINTK("Undefined IRQ happened[%x]\n", irq_state); + } + + spin_unlock_irq(&lock_hdmi); + + return IRQ_HANDLED; +} + +u8 s5p_hdmi_get_enabled_interrupt(void) +{ + u8 reg; + reg = readb(hdmi_base+S5P_HDMI_CTRL_INTC_CON); + return reg; +} + +void s5p_hdmi_enable_interrupts(enum s5p_tv_hdmi_interrrupt intr) +{ + u8 reg; + reg = readb(hdmi_base+S5P_HDMI_CTRL_INTC_CON); + writeb(reg | (1<<intr) | (1<<HDMI_IRQ_GLOBAL), + hdmi_base+S5P_HDMI_CTRL_INTC_CON); +} +EXPORT_SYMBOL(s5p_hdmi_enable_interrupts); + +void s5p_hdmi_disable_interrupts(enum s5p_tv_hdmi_interrrupt intr) +{ + u8 reg; + reg = readb(hdmi_base+S5P_HDMI_CTRL_INTC_CON); + writeb(reg & ~(1<<intr), hdmi_base+S5P_HDMI_CTRL_INTC_CON); +} +EXPORT_SYMBOL(s5p_hdmi_disable_interrupts); + +void s5p_hdmi_clear_pending(enum s5p_tv_hdmi_interrrupt intr) +{ + u8 reg; + reg = readb(hdmi_base+S5P_HDMI_CTRL_INTC_FLAG); + writeb(reg | (1<<intr), hdmi_base+S5P_HDMI_CTRL_INTC_FLAG); +} +EXPORT_SYMBOL(s5p_hdmi_clear_pending); + +u8 s5p_hdmi_get_interrupts(void) +{ + u8 reg; + reg = readb(hdmi_base+S5P_HDMI_CTRL_INTC_FLAG); + return reg; +} +EXPORT_SYMBOL(s5p_hdmi_get_interrupts); + +u8 s5p_hdmi_get_swhpd_status(void) +{ + u8 reg; + reg = readb(hdmi_base+S5P_HPD) & HPD_SW_ENABLE; + return reg; +} +EXPORT_SYMBOL(s5p_hdmi_get_swhpd_status); + +u8 s5p_hdmi_get_hpd_status(void) +{ + u8 reg; + reg = readb(hdmi_base+S5P_HDMI_CTRL_HPD); + return reg; +} +EXPORT_SYMBOL(s5p_hdmi_get_hpd_status); + +void s5p_hdmi_swhpd_disable(void) +{ + writeb(HPD_SW_DISABLE, hdmi_base+S5P_HPD); +} +EXPORT_SYMBOL(s5p_hdmi_swhpd_disable); + +void s5p_hdmi_hpd_gen(void) +{ + writeb(0xFF, hdmi_base+S5P_HDMI_HPD_GEN); +} +EXPORT_SYMBOL(s5p_hdmi_hpd_gen); + diff --git a/drivers/media/video/samsung/tv20/s5pv210/regs/regs-cec.h b/drivers/media/video/samsung/tv20/s5pv210/regs/regs-cec.h new file mode 100644 index 0000000..9e29d0e --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5pv210/regs/regs-cec.h @@ -0,0 +1,101 @@ +/* linux/drivers/media/video/samsung/tv20/s5pc110/regs/regs-cec.h + * + * CEC register header file for Samsung TVOut driver + * + * Copyright (c) 2010 Samsung Electronics + * http://www.samsung.com/ + * + * 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. +*/ + +#ifndef __REGS_CEC_H +#define __REGS_CEC_H + +#define HDMIDP_CECREG(x) (x) + +/** + * @name CEC config/status registers + */ +#define CEC_STATUS_0 HDMIDP_CECREG(0x0000) +#define CEC_STATUS_1 HDMIDP_CECREG(0x0004) +#define CEC_STATUS_2 HDMIDP_CECREG(0x0008) +#define CEC_STATUS_3 HDMIDP_CECREG(0x000C) +#define CEC_IRQ_MASK HDMIDP_CECREG(0x0010) +#define CEC_IRQ_CLEAR HDMIDP_CECREG(0x0014) +#define CEC_LOGIC_ADDR HDMIDP_CECREG(0x0020) +#define CEC_DIVISOR_0 HDMIDP_CECREG(0x0030) +#define CEC_DIVISOR_1 HDMIDP_CECREG(0x0034) +#define CEC_DIVISOR_2 HDMIDP_CECREG(0x0038) +#define CEC_DIVISOR_3 HDMIDP_CECREG(0x003C) + +/** + * @name CEC Tx related registers + */ +#define CEC_TX_CTRL HDMIDP_CECREG(0x0040) +#define CEC_TX_BYTES HDMIDP_CECREG(0x0044) +#define CEC_TX_STAT0 HDMIDP_CECREG(0x0060) +#define CEC_TX_STAT1 HDMIDP_CECREG(0x0064) +#define CEC_TX_BUFF0 HDMIDP_CECREG(0x0080) +#define CEC_TX_BUFF1 HDMIDP_CECREG(0x0084) +#define CEC_TX_BUFF2 HDMIDP_CECREG(0x0088) +#define CEC_TX_BUFF3 HDMIDP_CECREG(0x008C) +#define CEC_TX_BUFF4 HDMIDP_CECREG(0x0090) +#define CEC_TX_BUFF5 HDMIDP_CECREG(0x0094) +#define CEC_TX_BUFF6 HDMIDP_CECREG(0x0098) +#define CEC_TX_BUFF7 HDMIDP_CECREG(0x009C) +#define CEC_TX_BUFF8 HDMIDP_CECREG(0x00A0) +#define CEC_TX_BUFF9 HDMIDP_CECREG(0x00A4) +#define CEC_TX_BUFF10 HDMIDP_CECREG(0x00A8) +#define CEC_TX_BUFF11 HDMIDP_CECREG(0x00AC) +#define CEC_TX_BUFF12 HDMIDP_CECREG(0x00B0) +#define CEC_TX_BUFF13 HDMIDP_CECREG(0x00B4) +#define CEC_TX_BUFF14 HDMIDP_CECREG(0x00B8) +#define CEC_TX_BUFF15 HDMIDP_CECREG(0x00BC) + +/** + * @name CEC Rx related registers + */ +#define CEC_RX_CTRL HDMIDP_CECREG(0x00C0) +#define CEC_RX_STAT0 HDMIDP_CECREG(0x00E0) +#define CEC_RX_STAT1 HDMIDP_CECREG(0x00E4) +#define CEC_RX_BUFF0 HDMIDP_CECREG(0x0100) +#define CEC_RX_BUFF1 HDMIDP_CECREG(0x0104) +#define CEC_RX_BUFF2 HDMIDP_CECREG(0x0108) +#define CEC_RX_BUFF3 HDMIDP_CECREG(0x010C) +#define CEC_RX_BUFF4 HDMIDP_CECREG(0x0110) +#define CEC_RX_BUFF5 HDMIDP_CECREG(0x0114) +#define CEC_RX_BUFF6 HDMIDP_CECREG(0x0118) +#define CEC_RX_BUFF7 HDMIDP_CECREG(0x011C) +#define CEC_RX_BUFF8 HDMIDP_CECREG(0x0120) +#define CEC_RX_BUFF9 HDMIDP_CECREG(0x0124) +#define CEC_RX_BUFF10 HDMIDP_CECREG(0x0128) +#define CEC_RX_BUFF11 HDMIDP_CECREG(0x012C) +#define CEC_RX_BUFF12 HDMIDP_CECREG(0x0130) +#define CEC_RX_BUFF13 HDMIDP_CECREG(0x0134) +#define CEC_RX_BUFF14 HDMIDP_CECREG(0x0138) +#define CEC_RX_BUFF15 HDMIDP_CECREG(0x013C) + +#define CEC_RX_FILTER_CTRL HDMIDP_CECREG(0x0180) +#define CEC_RX_FILTER_TH HDMIDP_CECREG(0x0184) + +/** + * @name Bit values + */ +#define CEC_IRQ_TX_DONE (1<<0) +#define CEC_IRQ_TX_ERROR (1<<1) +#define CEC_IRQ_RX_DONE (1<<4) +#define CEC_IRQ_RX_ERROR (1<<5) + +#define CEC_TX_CTRL_START (1<<0) +#define CEC_TX_CTRL_BCAST (1<<1) +#define CEC_TX_CTRL_RETRY (0x04<<4) +#define CEC_TX_CTRL_RESET (1<<7) + +#define CEC_RX_CTRL_ENABLE (1<<0) +#define CEC_RX_CTRL_RESET (1<<7) + +#define CEC_LOGIC_ADDR_MASK 0x0F + +#endif /* __REGS_CEC_H */ diff --git a/drivers/media/video/samsung/tv20/s5pv210/regs/regs-clock_extra.h b/drivers/media/video/samsung/tv20/s5pv210/regs/regs-clock_extra.h new file mode 100644 index 0000000..d4cede6 --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5pv210/regs/regs-clock_extra.h @@ -0,0 +1,103 @@ +/* linux/drivers/media/video/samsung/tv20/s5pc100/regs/regs-clock_extra.h + * + * Clock Other header file for Samsung TVOut driver + * + * Copyright (c) 2010 Samsung Electronics + * http://www.samsung.com/ + * + * 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. +*/ + +#ifndef __ASM_ARCH_REGS_CLK_EXTRA_H +#define __ASM_ARCH_REGS_CLK_EXTRA_H + +#include <mach/map.h> + +#define S5P_CLK_OTHER_BASE(x) (x) +/* + * Registers + * */ +/* Generate software reset 0x0000_0000 */ +#define S5P_CLK_OTHER_SWRESET S5P_CLK_OTHER_BASE(0x0000) +/* OneNAND controller setting 0x0000_0000 */ +#define S5P_CLK_OTHER_ONENAND_SWRESET S5P_CLK_OTHER_BASE(0x0008) +/* General Control Register 0x0000_0000 */ +#define S5P_CLK_OTHER_GENERAL_CTRL S5P_CLK_OTHER_BASE(0x0100) +/* General Status Register 0x0000_0000 */ +#define S5P_CLK_OTHER_GENERAL_STATUS S5P_CLK_OTHER_BASE(0x0104) +/* ENDIAN & EBI configuration 0x0000_0000 */ +#define S5P_CLK_OTHER_MEM_SYS_CFG S5P_CLK_OTHER_BASE(0x0200) +/* Camera mapping to FIMC selection 0x0000_0000 */ +#define S5P_CLK_OTHER_CAM_MUX_SEL S5P_CLK_OTHER_BASE(0x0300) +/* Video Mixer output to TVENC / HDMI selection 0x0000_0000*/ +#define S5P_CLK_OTHER_MIXER_OUT_SEL S5P_CLK_OTHER_BASE(0x0304) +/* Low power MP3 mode selection 0x0000_0000 */ +#define S5P_CLK_OTHER_LPMP3_MODE_SEL S5P_CLK_OTHER_BASE(0x0308) +/* MIPI D-PHY control register0 0x0000_0000 */ +#define S5P_CLK_OTHER_MIPI_PHY_CON0 S5P_CLK_OTHER_BASE(0x0400) +/* MIPI D-PHY control register1 0x0000_0000 */ +#define S5P_CLK_OTHER_MIPI_PHY_CON1 S5P_CLK_OTHER_BASE(0x0414) +/* HDMI PHY control register0 0x0000_0000 */ +#define S5P_CLK_OTHER_HDMI_PHY_CON0 S5P_CLK_OTHER_BASE(0x0420) + +/* + * Macros + * */ +/* VPLL_LOCK */ +#define VPLL_LOCKTIME(a) (0xffff&a) + +/* VPLL_CON */ +#define VPLL_ENABLE (1<<31) +#define VPLL_DISABLE (0<<31) +#define VPLL_LOCKED(a) ((1<<29)&a) +#define VCO_FREQ_SEL (1<<27) +#define MDIV(a) ((0xff&a)<<16) +#define PDIV(a) ((0x3f&a)<<8) +#define SDIV(a) (0x7&a) + +/* CLK_SRC0 */ +#define HREF_SEL_FIN_27M (0<<20) +#define HREF_SEL_SRCLK (1<<20) +#define HREF_SEL_MASK (~(1<<20)) +#define VPLL_SEL_CLK27M (0<<12) +#define VPLL_SEL_FOUT_VPLL (1<<12) +#define VPLL_SEL_MASK (~(1<<12)) + +/* CLK_SRC2 */ +#define VMIXER_SEL_MOUT_VPLL (1<<4) +#define VMIXER_SEL_MASK (~(1<<4)) +#define HDMI_SEL_HDMIPHY (1<<0) +#define HDMI_SEL_MASK (~(1<<0)) + +/* CLK_DIV3 */ +#define HDMI_DIV_RATIO(a) (0xf&(a)) +#define HDMI_DIV_RATIO_MASK (~(0xf)) + +/* CLK_GATE_D1_2 */ +#define CLK_HCLK_HDMI_PASS (1<<11) +#define CLK_HCLK_SDOUT_PASS (1<<10) +#define CLK_HCLK_VMIXER_PASS (1<<9) +#define CLK_HCLK_VP_PASS (1<<8) +#define CLK_HCLK_MASK (~0xf) + +/* CLK_GATE_D1_4 */ +#define CLK_PCLK_IIC_HDMI_PASS (1<<5) +#define CLK_PCLK_IIC_HDMI_MASK (~(1<<5)) + +/* CLK_GATE_SCLK_1 */ +#define CLK_SCLK_HDMI_PASS (1<<19) +#define CLK_SCLK_VMIXER_PASS (1<<20) +#define CLK_SCLK_VDAC54_PASS (1<<21) +#define CLK_SCLK_TV54_PASS (1<<22) +#define CLK_SCLK_HDMI_MASK (~(1<<19)) +#define CLK_SCLK_VMIXER_MASK (~(1<<20)) +#define CLK_SCLK_VDAC54_MASK (~(1<<21)) +#define CLK_SCLK_TV54_MASK (~(1<<22)) + +/* MIXER_OUT_SEL */ +#define VMIXER_OUT_SEL_SDOUT (0) +#define VMIXER_OUT_SEL_HDMI (1) + +#endif /*__ASM_ARCH_REGS_CLK_EXTRA_H */ diff --git a/drivers/media/video/samsung/tv20/s5pv210/regs/regs-hdmi.h b/drivers/media/video/samsung/tv20/s5pv210/regs/regs-hdmi.h new file mode 100644 index 0000000..8094417 --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5pv210/regs/regs-hdmi.h @@ -0,0 +1,1552 @@ +/* linux/drivers/media/video/samsung/tv20/s5pc100/regs/regs-hdmi.h + * + * Hdmi register header file for Samsung TVOut driver + * + * Copyright (c) 2010 Samsung Electronics + * http://www.samsung.com/ + * + * 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. +*/ + +#ifndef __ASM_ARCH_REGS_HDMI_H + +#include <mach/map.h> + +#define S5P_I2C_HDMI_PHY_BASE(x) (x) + +/* + * HDMI PHY is configured through the dedicated I2C. + * The dedicated I2C for HDMI PHY is only used as TX mode + * I2C-BUS Interface for HDMI PHY is internally connected + */ +#define I2C_HDMI_CON S5P_I2C_HDMI_PHY_BASE(0x0000) +#define I2C_HDMI_STAT S5P_I2C_HDMI_PHY_BASE(0x0004) +#define I2C_HDMI_ADD S5P_I2C_HDMI_PHY_BASE(0x0008) +#define I2C_HDMI_DS S5P_I2C_HDMI_PHY_BASE(0x000c) +#define I2C_HDMI_LC S5P_I2C_HDMI_PHY_BASE(0x0010) + +#define S5P_HDMI_CTRL_BASE(x) (x) +#define S5P_HDMI_BASE(x) (x + 0x00010000) +#define S5P_HDMI_SPDIF_BASE(x) (x + 0x00030000) +#define S5P_HDMI_I2S_BASE(x) (x + 0x00040000) +#define S5P_HDMI_TG_BASE(x) (x + 0x00050000) +#define S5P_HDMI_EFUSE_BASE(x) (x + 0x00060000) + +#define S5P_HDMI_CTRL_INTC_CON S5P_HDMI_CTRL_BASE(0x0000) /* Interrupt Control Register */ +#define S5P_HDMI_CTRL_INTC_FLAG S5P_HDMI_CTRL_BASE(0x0004) /* Interrupt Flag Register */ +#define S5P_HDMI_CTRL_HDCP_KEY_LOAD S5P_HDMI_CTRL_BASE(0x0008) /* HDCP KEY Status */ +#define S5P_HDMI_CTRL_HPD S5P_HDMI_CTRL_BASE(0x000C) /* HPD signal */ +#define S5P_HDMI_CTRL_AUDIO_CLKSEL S5P_HDMI_CTRL_BASE(0x0010) /* Audio system clock selection */ +#define S5P_HDMI_CTRL_PHY_RSTOUT S5P_HDMI_CTRL_BASE(0x0014) /* HDMI PHY Reset Out */ +#define S5P_HDMI_CTRL_PHY_VPLL S5P_HDMI_CTRL_BASE(0x0018) /* HDMI PHY VPLL Monitor */ +#define S5P_HDMI_CTRL_PHY_CMU S5P_HDMI_CTRL_BASE(0x001C) /* HDMI PHY CMU Monitor */ +#define S5P_HDMI_CTRL_CORE_RSTOUT S5P_HDMI_CTRL_BASE(0x0020) /* HDMI TX Core S/W reset */ + +#define S5P_HDMI_CON_0 S5P_HDMI_BASE(0x0000) /* HDMI System Control Register 0 0x00 */ +#define S5P_HDMI_CON_1 S5P_HDMI_BASE(0x0004) /* HDMI System Control Register 1 0x00 */ +#define S5P_HDMI_CON_2 S5P_HDMI_BASE(0x0008) /* HDMI System Control Register 2. 0x00 */ +#define S5P_STATUS S5P_HDMI_BASE(0x0010) /* HDMI System Status Register 0x00 */ +#define HDMI_PHY_STATUS S5P_HDMI_BASE(0x0014) /* HDMI Phy Status */ +#define S5P_STATUS_EN S5P_HDMI_BASE(0x0020) /* HDMI System Status Enable Register 0x00 */ +#define S5P_HPD S5P_HDMI_BASE(0x0030) /* Hot Plug Detection Control Register 0x00 */ +#define S5P_MODE_SEL S5P_HDMI_BASE(0x0040) /* HDMI/DVI Mode Selection 0x00 */ +#define S5P_ENC_EN S5P_HDMI_BASE(0x0044) /* HDCP Encryption Enable Register 0x00 */ + +#define S5P_BLUE_SCREEN_0 S5P_HDMI_BASE(0x0050) /* Pixel Values for Blue Screen 0x00 */ +#define S5P_BLUE_SCREEN_1 S5P_HDMI_BASE(0x0054) /* Pixel Values for Blue Screen 0x00 */ +#define S5P_BLUE_SCREEN_2 S5P_HDMI_BASE(0x0058) /* Pixel Values for Blue Screen 0x00 */ + +#define S5P_HDMI_YMAX S5P_HDMI_BASE(0x0060) /* Maximum Y (or R,G,B) Pixel Value 0xEB */ +#define S5P_HDMI_YMIN S5P_HDMI_BASE(0x0064) /* Minimum Y (or R,G,B) Pixel Value 0x10 */ +#define S5P_HDMI_CMAX S5P_HDMI_BASE(0x0068) /* Maximum Cb/ Cr Pixel Value 0xF0 */ +#define S5P_HDMI_CMIN S5P_HDMI_BASE(0x006C) /* Minimum Cb/ Cr Pixel Value 0x10 */ + +#define S5P_H_BLANK_0 S5P_HDMI_BASE(0x00A0) /* Horizontal Blanking Setting 0x00 */ +#define S5P_H_BLANK_1 S5P_HDMI_BASE(0x00A4) /* Horizontal Blanking Setting 0x00 */ +#define S5P_V_BLANK_0 S5P_HDMI_BASE(0x00B0) /* Vertical Blanking Setting 0x00 */ +#define S5P_V_BLANK_1 S5P_HDMI_BASE(0x00B4) /* Vertical Blanking Setting 0x00 */ +#define S5P_V_BLANK_2 S5P_HDMI_BASE(0x00B8) /* Vertical Blanking Setting 0x00 */ +#define S5P_H_V_LINE_0 S5P_HDMI_BASE(0x00C0) /* Hori. Line and Ver. Line 0x00 */ +#define S5P_H_V_LINE_1 S5P_HDMI_BASE(0x00C4) /* Hori. Line and Ver. Line 0x00 */ +#define S5P_H_V_LINE_2 S5P_HDMI_BASE(0x00C8) /* Hori. Line and Ver. Line 0x00 */ + +#define S5P_SYNC_MODE S5P_HDMI_BASE(0x00E4) /* Vertical Sync Polarity Control Register 0x00 */ +#define S5P_INT_PRO_MODE S5P_HDMI_BASE(0x00E8) /* Interlace/ Progressive Control Register 0x00 */ + +#define S5P_V_BLANK_F_0 S5P_HDMI_BASE(0x0110) /* Vertical Blanking Setting for Bottom Field 0x00 */ +#define S5P_V_BLANK_F_1 S5P_HDMI_BASE(0x0114) /* Vertical Blanking Setting for Bottom Field 0x00 */ +#define S5P_V_BLANK_F_2 S5P_HDMI_BASE(0x0118) /* Vertical Blanking Setting for Bottom Field 0x00 */ +#define S5P_H_SYNC_GEN_0 S5P_HDMI_BASE(0x0120) /* Horizontal Sync Generation Setting 0x00 */ +#define S5P_H_SYNC_GEN_1 S5P_HDMI_BASE(0x0124) /* Horizontal Sync Generation Setting 0x00 */ +#define S5P_H_SYNC_GEN_2 S5P_HDMI_BASE(0x0128) /* Horizontal Sync Generation Setting 0x00 */ +#define S5P_V_SYNC_GEN_1_0 S5P_HDMI_BASE(0x0130) /* Vertical Sync Generation for Top Field or Frame. 0x01 */ +#define S5P_V_SYNC_GEN_1_1 S5P_HDMI_BASE(0x0134) /* Vertical Sync Generation for Top Field or Frame. 0x10 */ +#define S5P_V_SYNC_GEN_1_2 S5P_HDMI_BASE(0x0138) /* Vertical Sync Generation for Top Field or Frame. 0x00 */ +#define S5P_V_SYNC_GEN_2_0 S5P_HDMI_BASE(0x0140) /* Vertical Sync Generation for Bottom field ? Vertical position. 0x01 */ +#define S5P_V_SYNC_GEN_2_1 S5P_HDMI_BASE(0x0144) /* Vertical Sync Generation for Bottom field ? Vertical position. 0x10 */ +#define S5P_V_SYNC_GEN_2_2 S5P_HDMI_BASE(0x0148) /* Vertical Sync Generation for Bottom field ? Vertical position. 0x00 */ +#define S5P_V_SYNC_GEN_3_0 S5P_HDMI_BASE(0x0150) /* Vertical Sync Generation for Bottom field ? Horizontal position. 0x01 */ +#define S5P_V_SYNC_GEN_3_1 S5P_HDMI_BASE(0x0154) /* Vertical Sync Generation for Bottom field ? Horizontal position. 0x10 */ +#define S5P_V_SYNC_GEN_3_2 S5P_HDMI_BASE(0x0158) /* Vertical Sync Generation for Bottom field ? Horizontal position. 0x00 */ + +#define S5P_ASP_CON S5P_HDMI_BASE(0x0160) /* ASP Packet Control Register 0x00 */ +#define S5P_ASP_SP_FLAT S5P_HDMI_BASE(0x0164) /* ASP Packet sp_flat Bit Control 0x00 */ +#define S5P_ASP_CHCFG0 S5P_HDMI_BASE(0x0170) /* ASP Audio Channel Configuration 0x04 */ +#define S5P_ASP_CHCFG1 S5P_HDMI_BASE(0x0174) /* ASP Audio Channel Configuration 0x1A */ +#define S5P_ASP_CHCFG2 S5P_HDMI_BASE(0x0178) /* ASP Audio Channel Configuration 0x2C */ +#define S5P_ASP_CHCFG3 S5P_HDMI_BASE(0x017C) /* ASP Audio Channel Configuration 0x3E */ + +#define S5P_ACR_CON S5P_HDMI_BASE(0x0180) /* ACR Packet Control Register 0x00 */ +#define S5P_ACR_MCTS0 S5P_HDMI_BASE(0x0184) /* Measured CTS Value 0x01 */ +#define S5P_ACR_MCTS1 S5P_HDMI_BASE(0x0188) /* Measured CTS Value 0x00 */ +#define S5P_ACR_MCTS2 S5P_HDMI_BASE(0x018C) /* Measured CTS Value 0x00 */ +#define S5P_ACR_CTS0 S5P_HDMI_BASE(0x0190) /* CTS Value for Fixed CTS Transmission Mode. 0xE8 */ +#define S5P_ACR_CTS1 S5P_HDMI_BASE(0x0194) /* CTS Value for Fixed CTS Transmission Mode. 0x03 */ +#define S5P_ACR_CTS2 S5P_HDMI_BASE(0x0198) /* CTS Value for Fixed CTS Transmission Mode. 0x00 */ +#define S5P_ACR_N0 S5P_HDMI_BASE(0x01A0) /* N Value for ACR Packet. 0xE8 */ +#define S5P_ACR_N1 S5P_HDMI_BASE(0x01A4) /* N Value for ACR Packet. 0x03 */ +#define S5P_ACR_N2 S5P_HDMI_BASE(0x01A8) /* N Value for ACR Packet. 0x00 */ +#define S5P_ACR_LSB2 S5P_HDMI_BASE(0x01B0) /* Altenate LSB for Fixed CTS Transmission Mode 0x00 */ +#define S5P_ACR_TXCNT S5P_HDMI_BASE(0x01B4) /* Number of ACR Packet Transmission per frame 0x1F */ +#define S5P_ACR_TXINTERVAL S5P_HDMI_BASE(0x01B8) /* Interval for ACR Packet Transmission 0x63 */ +#define S5P_ACR_CTS_OFFSET S5P_HDMI_BASE(0x01BC) /* CTS Offset for Measured CTS mode. 0x00 */ + +#define S5P_GCP_CON S5P_HDMI_BASE(0x01C0) /* ACR Packet Control register 0x00 */ +#define S5P_GCP_BYTE1 S5P_HDMI_BASE(0x01D0) /* GCP Packet Body 0x00 */ +#define S5P_GCP_BYTE2 S5P_HDMI_BASE(0x01D4) /* GCP Packet Body 0x01 */ +#define S5P_GCP_BYTE3 S5P_HDMI_BASE(0x01D8) /* GCP Packet Body 0x02 */ + +#define S5P_ACP_CON S5P_HDMI_BASE(0x01E0) /* ACP Packet Control register 0x00 */ +#define S5P_ACP_TYPE S5P_HDMI_BASE(0x01E4) /* ACP Packet Header 0x00 */ + +#define S5P_ACP_DATA0 S5P_HDMI_BASE(0x0200) /* ACP Packet Body 0x00 */ +#define S5P_ACP_DATA1 S5P_HDMI_BASE(0x0204) /* ACP Packet Body 0x00 */ +#define S5P_ACP_DATA2 S5P_HDMI_BASE(0x0208) /* ACP Packet Body 0x00 */ +#define S5P_ACP_DATA3 S5P_HDMI_BASE(0x020c) /* ACP Packet Body 0x00 */ +#define S5P_ACP_DATA4 S5P_HDMI_BASE(0x0210) /* ACP Packet Body 0x00 */ +#define S5P_ACP_DATA5 S5P_HDMI_BASE(0x0214) /* ACP Packet Body 0x00 */ +#define S5P_ACP_DATA6 S5P_HDMI_BASE(0x0218) /* ACP Packet Body 0x00 */ +#define S5P_ACP_DATA7 S5P_HDMI_BASE(0x021c) /* ACP Packet Body 0x00 */ +#define S5P_ACP_DATA8 S5P_HDMI_BASE(0x0220) /* ACP Packet Body 0x00 */ +#define S5P_ACP_DATA9 S5P_HDMI_BASE(0x0224) /* ACP Packet Body 0x00 */ +#define S5P_ACP_DATA10 S5P_HDMI_BASE(0x0228) /* ACP Packet Body 0x00 */ +#define S5P_ACP_DATA11 S5P_HDMI_BASE(0x022c) /* ACP Packet Body 0x00 */ +#define S5P_ACP_DATA12 S5P_HDMI_BASE(0x0230) /* ACP Packet Body 0x00 */ +#define S5P_ACP_DATA13 S5P_HDMI_BASE(0x0234) /* ACP Packet Body 0x00 */ +#define S5P_ACP_DATA14 S5P_HDMI_BASE(0x0238) /* ACP Packet Body 0x00 */ +#define S5P_ACP_DATA15 S5P_HDMI_BASE(0x023c) /* ACP Packet Body 0x00 */ +#define S5P_ACP_DATA16 S5P_HDMI_BASE(0x0240) /* ACP Packet Body 0x00 */ + +#define S5P_ISRC_CON S5P_HDMI_BASE(0x0250) /* ACR Packet Control Register 0x00 */ +#define S5P_ISRC1_HEADER1 S5P_HDMI_BASE(0x0264) /* ISCR1 Packet Header 0x00 */ + +#define S5P_ISRC1_DATA0 S5P_HDMI_BASE(0x0270) /* ISRC1 Packet Body 0x00 */ +#define S5P_ISRC1_DATA1 S5P_HDMI_BASE(0x0274) /* ISRC1 Packet Body 0x00 */ +#define S5P_ISRC1_DATA2 S5P_HDMI_BASE(0x0278) /* ISRC1 Packet Body 0x00 */ +#define S5P_ISRC1_DATA3 S5P_HDMI_BASE(0x027c) /* ISRC1 Packet Body 0x00 */ +#define S5P_ISRC1_DATA4 S5P_HDMI_BASE(0x0280) /* ISRC1 Packet Body 0x00 */ +#define S5P_ISRC1_DATA5 S5P_HDMI_BASE(0x0284) /* ISRC1 Packet Body 0x00 */ +#define S5P_ISRC1_DATA6 S5P_HDMI_BASE(0x0288) /* ISRC1 Packet Body 0x00 */ +#define S5P_ISRC1_DATA7 S5P_HDMI_BASE(0x028c) /* ISRC1 Packet Body 0x00 */ +#define S5P_ISRC1_DATA8 S5P_HDMI_BASE(0x0290) /* ISRC1 Packet Body 0x00 */ +#define S5P_ISRC1_DATA9 S5P_HDMI_BASE(0x0294) /* ISRC1 Packet Body 0x00 */ +#define S5P_ISRC1_DATA10 S5P_HDMI_BASE(0x0298) /* ISRC1 Packet Body 0x00 */ +#define S5P_ISRC1_DATA11 S5P_HDMI_BASE(0x029c) /* ISRC1 Packet Body 0x00 */ +#define S5P_ISRC1_DATA12 S5P_HDMI_BASE(0x02a0) /* ISRC1 Packet Body 0x00 */ +#define S5P_ISRC1_DATA13 S5P_HDMI_BASE(0x02a4) /* ISRC1 Packet Body 0x00 */ +#define S5P_ISRC1_DATA14 S5P_HDMI_BASE(0x02a8) /* ISRC1 Packet Body 0x00 */ +#define S5P_ISRC1_DATA15 S5P_HDMI_BASE(0x02ac) /* ISRC1 Packet Body 0x00 */ + +#define S5P_ISRC2_DATA0 S5P_HDMI_BASE(0x02b0) /* ISRC2 Packet Body 0x00 */ +#define S5P_ISRC2_DATA1 S5P_HDMI_BASE(0x02b4) /* ISRC2 Packet Body 0x00 */ +#define S5P_ISRC2_DATA2 S5P_HDMI_BASE(0x02b8) /* ISRC2 Packet Body 0x00 */ +#define S5P_ISRC2_DATA3 S5P_HDMI_BASE(0x02bc) /* ISRC2 Packet Body 0x00 */ +#define S5P_ISRC2_DATA4 S5P_HDMI_BASE(0x02c0) /* ISRC2 Packet Body 0x00 */ +#define S5P_ISRC2_DATA5 S5P_HDMI_BASE(0x02c4) /* ISRC2 Packet Body 0x00 */ +#define S5P_ISRC2_DATA6 S5P_HDMI_BASE(0x02c8) /* ISRC2 Packet Body 0x00 */ +#define S5P_ISRC2_DATA7 S5P_HDMI_BASE(0x02cc) /* ISRC2 Packet Body 0x00 */ +#define S5P_ISRC2_DATA8 S5P_HDMI_BASE(0x02d0) /* ISRC2 Packet Body 0x00 */ +#define S5P_ISRC2_DATA9 S5P_HDMI_BASE(0x02d4) /* ISRC2 Packet Body 0x00 */ +#define S5P_ISRC2_DATA10 S5P_HDMI_BASE(0x02d8) /* ISRC2 Packet Body 0x00 */ +#define S5P_ISRC2_DATA11 S5P_HDMI_BASE(0x02dc) /* ISRC2 Packet Body 0x00 */ +#define S5P_ISRC2_DATA12 S5P_HDMI_BASE(0x02e0) /* ISRC2 Packet Body 0x00 */ +#define S5P_ISRC2_DATA13 S5P_HDMI_BASE(0x02e4) /* ISRC2 Packet Body 0x00 */ +#define S5P_ISRC2_DATA14 S5P_HDMI_BASE(0x02e8) /* ISRC2 Packet Body 0x00 */ +#define S5P_ISRC2_DATA15 S5P_HDMI_BASE(0x02ec) /* ISRC2 Packet Body 0x00 */ + +#define S5P_AVI_CON S5P_HDMI_BASE(0x0300) /* AVI Packet Control Register 0x00 */ +#define S5P_AVI_CHECK_SUM S5P_HDMI_BASE(0x0310) /* AVI Packet Checksum 0x00 */ + +#define S5P_AVI_BYTE1 S5P_HDMI_BASE(0x0320) /* AVI Packet Body 0x00 */ +#define S5P_AVI_BYTE2 S5P_HDMI_BASE(0x0324) /* AVI Packet Body 0x00 */ +#define S5P_AVI_BYTE3 S5P_HDMI_BASE(0x0328) /* AVI Packet Body 0x00 */ +#define S5P_AVI_BYTE4 S5P_HDMI_BASE(0x032c) /* AVI Packet Body 0x00 */ +#define S5P_AVI_BYTE5 S5P_HDMI_BASE(0x0330) /* AVI Packet Body 0x00 */ +#define S5P_AVI_BYTE6 S5P_HDMI_BASE(0x0334) /* AVI Packet Body 0x00 */ +#define S5P_AVI_BYTE7 S5P_HDMI_BASE(0x0338) /* AVI Packet Body 0x00 */ +#define S5P_AVI_BYTE8 S5P_HDMI_BASE(0x033c) /* AVI Packet Body 0x00 */ +#define S5P_AVI_BYTE9 S5P_HDMI_BASE(0x0340) /* AVI Packet Body 0x00 */ +#define S5P_AVI_BYTE10 S5P_HDMI_BASE(0x0344) /* AVI Packet Body 0x00 */ +#define S5P_AVI_BYTE11 S5P_HDMI_BASE(0x0348) /* AVI Packet Body 0x00 */ +#define S5P_AVI_BYTE12 S5P_HDMI_BASE(0x034c) /* AVI Packet Body 0x00 */ +#define S5P_AVI_BYTE13 S5P_HDMI_BASE(0x0350) /* AVI Packet Body 0x00 */ + +#define S5P_AUI_CON S5P_HDMI_BASE(0x0360) /* AUI Packet Control Register 0x00 */ +#define S5P_AUI_CHECK_SUM S5P_HDMI_BASE(0x0370) /* AUI Packet Checksum 0x00 */ + +#define S5P_AUI_BYTE1 S5P_HDMI_BASE(0x0380) /* AUI Packet Body 0x00 */ +#define S5P_AUI_BYTE2 S5P_HDMI_BASE(0x0384) /* AUI Packet Body 0x00 */ +#define S5P_AUI_BYTE3 S5P_HDMI_BASE(0x0388) /* AUI Packet Body 0x00 */ +#define S5P_AUI_BYTE4 S5P_HDMI_BASE(0x038c) /* AUI Packet Body 0x00 */ +#define S5P_AUI_BYTE5 S5P_HDMI_BASE(0x0390) /* AUI Packet Body 0x00 */ + +#define S5P_MPG_CON S5P_HDMI_BASE(0x03A0) /* ACR Packet Control Register 0x00 */ +#define S5P_MPG_CHECK_SUM S5P_HDMI_BASE(0x03B0) /* MPG Packet Checksum 0x00 */ + +#define S5P_MPEG_BYTE1 S5P_HDMI_BASE(0x03c0) /* MPEG Packet Body 0x00 */ +#define S5P_MPEG_BYTE2 S5P_HDMI_BASE(0x03c4) /* MPEG Packet Body 0x00 */ +#define S5P_MPEG_BYTE3 S5P_HDMI_BASE(0x03c8) /* MPEG Packet Body 0x00 */ +#define S5P_MPEG_BYTE4 S5P_HDMI_BASE(0x03cc) /* MPEG Packet Body 0x00 */ +#define S5P_MPEG_BYTE5 S5P_HDMI_BASE(0x03d0) /* MPEG Packet Body 0x00 */ + +#define S5P_SPD_CON S5P_HDMI_BASE(0x0400) /* SPD Packet Control Register 0x00 */ +#define S5P_SPD_HEADER0 S5P_HDMI_BASE(0x0410) /* SPD Packet Header 0x00 */ +#define S5P_SPD_HEADER1 S5P_HDMI_BASE(0x0414) /* SPD Packet Header 0x00 */ +#define S5P_SPD_HEADER2 S5P_HDMI_BASE(0x0418) /* SPD Packet Header 0x00 */ + +#define S5P_SPD_DATA0 S5P_HDMI_BASE(0x0420) /* SPD Packet Body 0x00 */ +#define S5P_SPD_DATA1 S5P_HDMI_BASE(0x0424) /* SPD Packet Body 0x00 */ +#define S5P_SPD_DATA2 S5P_HDMI_BASE(0x0428) /* SPD Packet Body 0x00 */ +#define S5P_SPD_DATA3 S5P_HDMI_BASE(0x042c) /* SPD Packet Body 0x00 */ +#define S5P_SPD_DATA4 S5P_HDMI_BASE(0x0430) /* SPD Packet Body 0x00 */ +#define S5P_SPD_DATA5 S5P_HDMI_BASE(0x0434) /* SPD Packet Body 0x00 */ +#define S5P_SPD_DATA6 S5P_HDMI_BASE(0x0438) /* SPD Packet Body 0x00 */ +#define S5P_SPD_DATA7 S5P_HDMI_BASE(0x043c) /* SPD Packet Body 0x00 */ +#define S5P_SPD_DATA8 S5P_HDMI_BASE(0x0440) /* SPD Packet Body 0x00 */ +#define S5P_SPD_DATA9 S5P_HDMI_BASE(0x0444) /* SPD Packet Body 0x00 */ +#define S5P_SPD_DATA10 S5P_HDMI_BASE(0x0448) /* SPD Packet Body 0x00 */ +#define S5P_SPD_DATA11 S5P_HDMI_BASE(0x044c) /* SPD Packet Body 0x00 */ +#define S5P_SPD_DATA12 S5P_HDMI_BASE(0x0450) /* SPD Packet Body 0x00 */ +#define S5P_SPD_DATA13 S5P_HDMI_BASE(0x0454) /* SPD Packet Body 0x00 */ +#define S5P_SPD_DATA14 S5P_HDMI_BASE(0x0458) /* SPD Packet Body 0x00 */ +#define S5P_SPD_DATA15 S5P_HDMI_BASE(0x045c) /* SPD Packet Body 0x00 */ +#define S5P_SPD_DATA16 S5P_HDMI_BASE(0x0460) /* SPD Packet Body 0x00 */ +#define S5P_SPD_DATA17 S5P_HDMI_BASE(0x0464) /* SPD Packet Body 0x00 */ +#define S5P_SPD_DATA18 S5P_HDMI_BASE(0x0468) /* SPD Packet Body 0x00 */ +#define S5P_SPD_DATA19 S5P_HDMI_BASE(0x046c) /* SPD Packet Body 0x00 */ +#define S5P_SPD_DATA20 S5P_HDMI_BASE(0x0470) /* SPD Packet Body 0x00 */ +#define S5P_SPD_DATA21 S5P_HDMI_BASE(0x0474) /* SPD Packet Body 0x00 */ +#define S5P_SPD_DATA22 S5P_HDMI_BASE(0x0478) /* SPD Packet Body 0x00 */ +#define S5P_SPD_DATA23 S5P_HDMI_BASE(0x048c) /* SPD Packet Body 0x00 */ +#define S5P_SPD_DATA24 S5P_HDMI_BASE(0x0480) /* SPD Packet Body 0x00 */ +#define S5P_SPD_DATA25 S5P_HDMI_BASE(0x0484) /* SPD Packet Body 0x00 */ +#define S5P_SPD_DATA26 S5P_HDMI_BASE(0x0488) /* SPD Packet Body 0x00 */ +#define S5P_SPD_DATA27 S5P_HDMI_BASE(0x048c) /* SPD Packet Body 0x00 */ + +#define S5P_HDCP_RX_SHA1_0_0 S5P_HDMI_BASE(0x0600) /* SHA-1 Value from Repeater 0x00 */ +#define S5P_HDCP_RX_SHA1_0_1 S5P_HDMI_BASE(0x0604) /* SHA-1 Value from Repeater 0x00 */ +#define S5P_HDCP_RX_SHA1_0_2 S5P_HDMI_BASE(0x0608) /* SHA-1 value from Repeater 0x00 */ +#define S5P_HDCP_RX_SHA1_0_3 S5P_HDMI_BASE(0x060C) /* SHA-1 value from Repeater 0x00 */ +#define S5P_HDCP_RX_SHA1_1_0 S5P_HDMI_BASE(0x0610) /* SHA-1 value from Repeater 0x00 */ +#define S5P_HDCP_RX_SHA1_1_1 S5P_HDMI_BASE(0x0614) /* SHA-1 value from Repeater 0x00 */ +#define S5P_HDCP_RX_SHA1_1_2 S5P_HDMI_BASE(0x0618) /* SHA-1 value from Repeater 0x00 */ +#define S5P_HDCP_RX_SHA1_1_3 S5P_HDMI_BASE(0x061C) /* SHA-1 value from Repeater 0x00 */ +#define S5P_HDCP_RX_SHA1_2_0 S5P_HDMI_BASE(0x0620) /* SHA-1 value from Repeater 0x00 */ +#define S5P_HDCP_RX_SHA1_2_1 S5P_HDMI_BASE(0x0624) /* SHA-1 value from Repeater 0x00 */ +#define S5P_HDCP_RX_SHA1_2_2 S5P_HDMI_BASE(0x0628) /* SHA-1 value from Repeater 0x00 */ +#define S5P_HDCP_RX_SHA1_2_3 S5P_HDMI_BASE(0x062C) /* SHA-1 value from Repeater 0x00 */ +#define S5P_HDCP_RX_SHA1_3_0 S5P_HDMI_BASE(0x0630) /* SHA-1 value from Repeater 0x00 */ +#define S5P_HDCP_RX_SHA1_3_1 S5P_HDMI_BASE(0x0634) /* SHA-1 value from Repeater 0x00 */ +#define S5P_HDCP_RX_SHA1_3_2 S5P_HDMI_BASE(0x0638) /* SHA-1 value from Repeater 0x00 */ +#define S5P_HDCP_RX_SHA1_3_3 S5P_HDMI_BASE(0x063C) /* SHA-1 value from Repeater 0x00 */ +#define S5P_HDCP_RX_SHA1_4_0 S5P_HDMI_BASE(0x0640) /* SHA-1 value from Repeater 0x00 */ +#define S5P_HDCP_RX_SHA1_4_1 S5P_HDMI_BASE(0x0644) /* SHA-1 value from Repeater 0x00 */ +#define S5P_HDCP_RX_SHA1_4_2 S5P_HDMI_BASE(0x0648) /* SHA-1 value from Repeater 0x00 */ +#define S5P_HDCP_RX_SHA1_4_3 S5P_HDMI_BASE(0x064C) /* SHA-1 value from Repeater 0x00 */ + +#define S5P_HDCP_RX_KSV_0_0 S5P_HDMI_BASE(0x0650) /* Receiver¡¯s KSV 0 0x00 */ +#define S5P_HDCP_RX_KSV_0_1 S5P_HDMI_BASE(0x0654) /* Receiver¡¯s KSV 0 0x00 */ +#define S5P_HDCP_RX_KSV_0_2 S5P_HDMI_BASE(0x0658) /* Receiver¡¯s KSV 0 0x00 */ +#define S5P_HDCP_RX_KSV_0_3 S5P_HDMI_BASE(0x065C) /* Receiver¡¯s KSV 0 0x00 */ +#define S5P_HDCP_RX_KSV_0_4 S5P_HDMI_BASE(0x0660) /* Receiver¡¯s KSV 1 0x00 */ + +#define S5P_HDCP_RX_KSV_LIST_CTRL S5P_HDMI_BASE(0x0664) /* Receiver¡¯s KSV 1 0x00 */ +#define S5P_HDCP_AUTH_STATUS S5P_HDMI_BASE(0x0670) /* 2nd authentication status 0x00 */ +#define S5P_HDCP_CTRL1 S5P_HDMI_BASE(0x0680) /* HDCP Control 0x00 */ +#define S5P_HDCP_CTRL2 S5P_HDMI_BASE(0x0684) /* HDCP Control 0x00 */ +#define S5P_HDCP_CHECK_RESULT S5P_HDMI_BASE(0x0690) /* HDCP Ri, Pj, V result 0x00 */ + +#define S5P_HDCP_BKSV_0_0 S5P_HDMI_BASE(0x06A0) /* Receiver¡¯s BKSV 0x00 */ +#define S5P_HDCP_BKSV_0_1 S5P_HDMI_BASE(0x06A4) /* Receiver¡¯s BKSV 0x00 */ +#define S5P_HDCP_BKSV_0_2 S5P_HDMI_BASE(0x06A8) /* Receiver¡¯s BKSV 0x00 */ +#define S5P_HDCP_BKSV_0_3 S5P_HDMI_BASE(0x06AC) /* Receiver¡¯s BKSV 0x00 */ +#define S5P_HDCP_BKSV_1 S5P_HDMI_BASE(0x06B0) /* Receiver¡¯s BKSV 0x00 */ + +#define S5P_HDCP_AKSV_0_0 S5P_HDMI_BASE(0x06C0) /* Transmitter¡¯s AKSV 0x00 */ +#define S5P_HDCP_AKSV_0_1 S5P_HDMI_BASE(0x06C4) /* Transmitter¡¯s AKSV 0x00 */ +#define S5P_HDCP_AKSV_0_2 S5P_HDMI_BASE(0x06C8) /* Transmitter¡¯s AKSV 0x00 */ +#define S5P_HDCP_AKSV_0_3 S5P_HDMI_BASE(0x06CC) /* Transmitter¡¯s AKSV 0x00 */ +#define S5P_HDCP_AKSV_1 S5P_HDMI_BASE(0x06D0) /* Transmitter¡¯s AKSV 0x00 */ + +#define S5P_HDCP_An_0_0 S5P_HDMI_BASE(0x06E0) /* Transmitter¡¯s An 0x00 */ +#define S5P_HDCP_An_0_1 S5P_HDMI_BASE(0x06E4) /* Transmitter¡¯s An 0x00 */ +#define S5P_HDCP_An_0_2 S5P_HDMI_BASE(0x06E8) /* Transmitter¡¯s An 0x00 */ +#define S5P_HDCP_An_0_3 S5P_HDMI_BASE(0x06EC) /* Transmitter¡¯s An 0x00 */ +#define S5P_HDCP_An_1_0 S5P_HDMI_BASE(0x06F0) /* Transmitter¡¯s An 0x00 */ +#define S5P_HDCP_An_1_1 S5P_HDMI_BASE(0x06F4) /* Transmitter¡¯s An 0x00 */ +#define S5P_HDCP_An_1_2 S5P_HDMI_BASE(0x06F8) /* Transmitter¡¯s An 0x00 */ +#define S5P_HDCP_An_1_3 S5P_HDMI_BASE(0x06FC) /* Transmitter¡¯s An 0x00 */ + +#define S5P_HDCP_BCAPS S5P_HDMI_BASE(0x0700) /* Receiver¡¯s BCAPS 0x00 */ +#define S5P_HDCP_BSTATUS_0 S5P_HDMI_BASE(0x0710) /* Receiver¡¯s BSTATUS 0x00 */ +#define S5P_HDCP_BSTATUS_1 S5P_HDMI_BASE(0x0714) /* Receiver¡¯s BSTATUS 0x00 */ +#define S5P_HDCP_Ri_0 S5P_HDMI_BASE(0x0740) /* Transmitter¡¯s Ri 0x00 */ +#define S5P_HDCP_Ri_1 S5P_HDMI_BASE(0x0744) /* Transmitter¡¯s Ri 0x00 */ + +#define S5P_HDCP_I2C_INT S5P_HDMI_BASE(0x0780) /* HDCP I2C interrupt status */ +#define S5P_HDCP_AN_INT S5P_HDMI_BASE(0x0790) /* HDCP An interrupt status */ +#define S5P_HDCP_WDT_INT S5P_HDMI_BASE(0x07a0) /* HDCP Watchdog interrupt status */ +#define S5P_HDCP_RI_INT S5P_HDMI_BASE(0x07b0) /* HDCP RI interrupt status */ + +#define S5P_HDCP_RI_COMPARE_0 S5P_HDMI_BASE(0x07d0) /* HDCP Ri Interrupt Frame number index register 0 */ +#define S5P_HDCP_RI_COMPARE_1 S5P_HDMI_BASE(0x07d4) /* HDCP Ri Interrupt Frame number index register 1 */ +#define S5P_HDCP_FRAME_COUNT S5P_HDMI_BASE(0x07e0) /* Current value of the frame count index in the hardware */ + +#define HDMI_GAMUT_CON S5P_HDMI_BASE(0x0500) /* Gamut Metadata packet transmission control register */ +#define HDMI_GAMUT_HEADER0 S5P_HDMI_BASE(0x0504) /* Gamut metadata packet header */ +#define HDMI_GAMUT_HEADER1 S5P_HDMI_BASE(0x0508) /* Gamut metadata packet header */ +#define HDMI_GAMUT_HEADER2 S5P_HDMI_BASE(0x050c) /* Gamut metadata packet header */ +#define HDMI_GAMUT_DATA00 S5P_HDMI_BASE(0x0510) /* Gamut Metadata packet body data */ +#define HDMI_GAMUT_DATA01 S5P_HDMI_BASE(0x0514) /* Gamut Metadata packet body data */ +#define HDMI_GAMUT_DATA02 S5P_HDMI_BASE(0x0518) /* Gamut Metadata packet body data */ +#define HDMI_GAMUT_DATA03 S5P_HDMI_BASE(0x051c) /* Gamut Metadata packet body data */ +#define HDMI_GAMUT_DATA04 S5P_HDMI_BASE(0x0520) /* Gamut Metadata packet body data */ +#define HDMI_GAMUT_DATA05 S5P_HDMI_BASE(0x0524) /* Gamut Metadata packet body data */ +#define HDMI_GAMUT_DATA06 S5P_HDMI_BASE(0x0528) /* Gamut Metadata packet body data */ +#define HDMI_GAMUT_DATA07 S5P_HDMI_BASE(0x052c) /* Gamut Metadata packet body data */ +#define HDMI_GAMUT_DATA08 S5P_HDMI_BASE(0x0530) /* Gamut Metadata packet body data */ +#define HDMI_GAMUT_DATA09 S5P_HDMI_BASE(0x0534) /* Gamut Metadata packet body data */ +#define HDMI_GAMUT_DATA10 S5P_HDMI_BASE(0x0538) /* Gamut Metadata packet body data */ +#define HDMI_GAMUT_DATA11 S5P_HDMI_BASE(0x053c) /* Gamut Metadata packet body data */ +#define HDMI_GAMUT_DATA12 S5P_HDMI_BASE(0x0540) /* Gamut Metadata packet body data */ +#define HDMI_GAMUT_DATA13 S5P_HDMI_BASE(0x0544) /* Gamut Metadata packet body data */ +#define HDMI_GAMUT_DATA14 S5P_HDMI_BASE(0x0548) /* Gamut Metadata packet body data */ +#define HDMI_GAMUT_DATA15 S5P_HDMI_BASE(0x054c) /* Gamut Metadata packet body data */ +#define HDMI_GAMUT_DATA16 S5P_HDMI_BASE(0x0550) /* Gamut Metadata packet body data */ +#define HDMI_GAMUT_DATA17 S5P_HDMI_BASE(0x0554) /* Gamut Metadata packet body data */ +#define HDMI_GAMUT_DATA18 S5P_HDMI_BASE(0x0558) /* Gamut Metadata packet body data */ +#define HDMI_GAMUT_DATA19 S5P_HDMI_BASE(0x055c) /* Gamut Metadata packet body data */ +#define HDMI_GAMUT_DATA20 S5P_HDMI_BASE(0x0560) /* Gamut Metadata packet body data */ +#define HDMI_GAMUT_DATA21 S5P_HDMI_BASE(0x0564) /* Gamut Metadata packet body data */ +#define HDMI_GAMUT_DATA22 S5P_HDMI_BASE(0x0568) /* Gamut Metadata packet body data */ +#define HDMI_GAMUT_DATA23 S5P_HDMI_BASE(0x056c) /* Gamut Metadata packet body data */ +#define HDMI_GAMUT_DATA24 S5P_HDMI_BASE(0x0570) /* Gamut Metadata packet body data */ +#define HDMI_GAMUT_DATA25 S5P_HDMI_BASE(0x0574) /* Gamut Metadata packet body data */ +#define HDMI_GAMUT_DATA26 S5P_HDMI_BASE(0x0578) /* Gamut Metadata packet body data */ +#define HDMI_GAMUT_DATA27 S5P_HDMI_BASE(0x057c) /* Gamut Metadata packet body data */ + +#define S5P_HDMI_DC_CONTROL S5P_HDMI_BASE(0x05C0) /* Gamut Metadata packet body data */ +#define S5P_HDMI_VIDEO_PATTERN_GEN S5P_HDMI_BASE(0x05C4) /* Gamut Metadata packet body data */ +#define S5P_HDMI_HPD_GEN S5P_HDMI_BASE(0x05C8) /* Gamut Metadata packet body data */ + +#define S5P_TG_CMD S5P_HDMI_TG_BASE(0x0000) /* Command Register 0x00 */ +#define S5P_TG_H_FSZ_L S5P_HDMI_TG_BASE(0x0018) /* Horizontal Full Size 0x72 */ +#define S5P_TG_H_FSZ_H S5P_HDMI_TG_BASE(0x001C) /* Horizontal Full Size 0x06 */ +#define S5P_TG_HACT_ST_L S5P_HDMI_TG_BASE(0x0020) /* Horizontal Active Start 0x05 */ +#define S5P_TG_HACT_ST_H S5P_HDMI_TG_BASE(0x0024) /* Horizontal Active Start 0x01 */ +#define S5P_TG_HACT_SZ_L S5P_HDMI_TG_BASE(0x0028) /* Horizontal Active Size 0x00 */ +#define S5P_TG_HACT_SZ_H S5P_HDMI_TG_BASE(0x002C) /* Horizontal Active Size 0x05 */ +#define S5P_TG_V_FSZ_L S5P_HDMI_TG_BASE(0x0030) /* Vertical Full Line Size 0xEE */ +#define S5P_TG_V_FSZ_H S5P_HDMI_TG_BASE(0x0034) /* Vertical Full Line Size 0x02 */ +#define S5P_TG_VSYNC_L S5P_HDMI_TG_BASE(0x0038) /* Vertical Sync Position 0x01 */ +#define S5P_TG_VSYNC_H S5P_HDMI_TG_BASE(0x003C) /* Vertical Sync Position 0x00 */ +#define S5P_TG_VSYNC2_L S5P_HDMI_TG_BASE(0x0040) /* Vertical Sync Position for Bottom Field 0x33 */ +#define S5P_TG_VSYNC2_H S5P_HDMI_TG_BASE(0x0044) /* Vertical Sync Position for Bottom Field 0x02 */ +#define S5P_TG_VACT_ST_L S5P_HDMI_TG_BASE(0x0048) /* Vertical Sync Active Start Position 0x1a */ +#define S5P_TG_VACT_ST_H S5P_HDMI_TG_BASE(0x004C) /* Vertical Sync Active Start Position 0x00 */ +#define S5P_TG_VACT_SZ_L S5P_HDMI_TG_BASE(0x0050) /* Vertical Active Size 0xd0 */ +#define S5P_TG_VACT_SZ_H S5P_HDMI_TG_BASE(0x0054) /* Vertical Active Size 0x02 */ +#define S5P_TG_FIELD_CHG_L S5P_HDMI_TG_BASE(0x0058) /* Field Change Position 0x33 */ +#define S5P_TG_FIELD_CHG_H S5P_HDMI_TG_BASE(0x005C) /* Field Change Position 0x02 */ +#define S5P_TG_VACT_ST2_L S5P_HDMI_TG_BASE(0x0060) /* Vertical Sync Active Start Position for Bottom Field 0x48 */ +#define S5P_TG_VACT_ST2_H S5P_HDMI_TG_BASE(0x0064) /* Vertical Sync Active Start Position for Bottom Field 0x02 */ + +#define S5P_TG_VSYNC_TOP_HDMI_L S5P_HDMI_TG_BASE(0x0078) /* HDMI Vsync Positon for Top Field 0x01 */ +#define S5P_TG_VSYNC_TOP_HDMI_H S5P_HDMI_TG_BASE(0x007C) /* HDMI Vsync Positon for Top Field 0x00 */ +#define S5P_TG_VSYNC_BOT_HDMI_L S5P_HDMI_TG_BASE(0x0080) /* HDMI Vsync Positon for Bottom Field 0x33 */ +#define S5P_TG_VSYNC_BOT_HDMI_H S5P_HDMI_TG_BASE(0x0084) /* HDMI Vsync Positon for Bottom Field 0x02 */ +#define S5P_TG_FIELD_TOP_HDMI_L S5P_HDMI_TG_BASE(0x0088) /* HDMI Top Field Start Position 0x01 */ +#define S5P_TG_FIELD_TOP_HDMI_H S5P_HDMI_TG_BASE(0x008C) /* HDMI Top Field Start Position 0x00 */ +#define S5P_TG_FIELD_BOT_HDMI_L S5P_HDMI_TG_BASE(0x0090) /* HDMI Bottom Field Start Position 0x33 */ +#define S5P_TG_FIELD_BOT_HDMI_H S5P_HDMI_TG_BASE(0x0094) /* HDMI Bottom Field Start Position 0x02 */ + +#define S5P_EFUSE_CTRL S5P_HDMI_EFUSE_BASE(0x0000) +#define S5P_EFUSE_STATUS S5P_HDMI_EFUSE_BASE(0x0004) +#define S5P_EFUSE_ADDR_WIDTH S5P_HDMI_EFUSE_BASE(0x0008) +#define S5P_EFUSE_SIGDEV_ASSERT S5P_HDMI_EFUSE_BASE(0x000c) +#define S5P_EFUSE_SIGDEV_DEASSERT S5P_HDMI_EFUSE_BASE(0x0010) +#define S5P_EFUSE_PRCHG_ASSERT S5P_HDMI_EFUSE_BASE(0x0014) +#define S5P_EFUSE_PRCHG_DEASSERT S5P_HDMI_EFUSE_BASE(0x0018) +#define S5P_EFUSE_FSET_ASSERT S5P_HDMI_EFUSE_BASE(0x001c) +#define S5P_EFUSE_FSET_DEASSERT S5P_HDMI_EFUSE_BASE(0x0020) +#define S5P_EFUSE_SENSING S5P_HDMI_EFUSE_BASE(0x0024) +#define S5P_EFUSE_SCK_ASSERT S5P_HDMI_EFUSE_BASE(0x0028) +#define S5P_EFUSE_SCK_DEASSERT S5P_HDMI_EFUSE_BASE(0x002c) +#define S5P_EFUSE_SDOUT_OFFSET S5P_HDMI_EFUSE_BASE(0x0030) +#define S5P_EFUSE_READ_OFFSET S5P_HDMI_EFUSE_BASE(0x0034) + +#define S5P_HDMI_I2S_CLK_CON S5P_HDMI_I2S_BASE(0x0000) /* I2S Clock Enable Register0x00 */ +#define S5P_HDMI_I2S_CON_1 S5P_HDMI_I2S_BASE(0x0004) /* I2S Control Register 10x00 */ +#define S5P_HDMI_I2S_CON_2 S5P_HDMI_I2S_BASE(0x0008) /* I2S Control Register 20x00 */ +#define S5P_HDMI_I2S_PIN_SEL_0 S5P_HDMI_I2S_BASE(0x000C) /* I2S Input Pin Selection Register 0 0x77 */ +#define S5P_HDMI_I2S_PIN_SEL_1 S5P_HDMI_I2S_BASE(0x0010) /* I2S Input Pin Selection Register 1 0x77 */ +#define S5P_HDMI_I2S_PIN_SEL_2 S5P_HDMI_I2S_BASE(0x0014) /* I2S Input Pin Selection Register 2 0x77 */ +#define S5P_HDMI_I2S_PIN_SEL_3 S5P_HDMI_I2S_BASE(0x0018) /* I2S Input Pin Selection Register 30x07 */ +#define S5P_HDMI_I2S_DSD_CON S5P_HDMI_I2S_BASE(0x001C) /* I2S DSD Control Register0x02 */ +#define S5P_HDMI_I2S_MUX_CON S5P_HDMI_I2S_BASE(0x0020) /* I2S In/Mux Control Register 0x60 */ +#define S5P_HDMI_I2S_CH_ST_CON S5P_HDMI_I2S_BASE(0x0024) /* I2S Channel Status Control Register0x00 */ +#define S5P_HDMI_I2S_CH_ST_0 S5P_HDMI_I2S_BASE(0x0028) /* I2S Channel Status Block 00x00 */ +#define S5P_HDMI_I2S_CH_ST_1 S5P_HDMI_I2S_BASE(0x002C) /* I2S Channel Status Block 10x00 */ +#define S5P_HDMI_I2S_CH_ST_2 S5P_HDMI_I2S_BASE(0x0030) /* I2S Channel Status Block 20x00 */ +#define S5P_HDMI_I2S_CH_ST_3 S5P_HDMI_I2S_BASE(0x0034) /* I2S Channel Status Block 30x00 */ +#define S5P_HDMI_I2S_CH_ST_4 S5P_HDMI_I2S_BASE(0x0038) /* I2S Channel Status Block 40x00 */ +#define S5P_HDMI_I2S_CH_ST_SH_0 S5P_HDMI_I2S_BASE(0x003C) /* I2S Channel Status Block Shadow Register 00x00 */ +#define S5P_HDMI_I2S_CH_ST_SH_1 S5P_HDMI_I2S_BASE(0x0040) /* I2S Channel Status Block Shadow Register 10x00 */ +#define S5P_HDMI_I2S_CH_ST_SH_2 S5P_HDMI_I2S_BASE(0x0044) /* I2S Channel Status Block Shadow Register 20x00 */ +#define S5P_HDMI_I2S_CH_ST_SH_3 S5P_HDMI_I2S_BASE(0x0048) /* I2S Channel Status Block Shadow Register 30x00 */ +#define S5P_HDMI_I2S_CH_ST_SH_4 S5P_HDMI_I2S_BASE(0x004C) /* I2S Channel Status Block Shadow Register 40x00 */ +#define S5P_HDMI_I2S_VD_DATA S5P_HDMI_I2S_BASE(0x0050) /* I2S Audio Sample Validity Register0x00 */ +#define S5P_HDMI_I2S_MUX_CH S5P_HDMI_I2S_BASE(0x0054) /* I2S Channel Enable Register0x03 */ +#define S5P_HDMI_I2S_MUX_CUV S5P_HDMI_I2S_BASE(0x0058) /* I2S CUV Enable Register0x03 */ +#define S5P_HDMI_I2S_IRQ_MASK S5P_HDMI_I2S_BASE(0x005C) /* I2S Interrupt Request Mask Register0x03 */ +#define S5P_HDMI_I2S_IRQ_STATUS S5P_HDMI_I2S_BASE(0x0060) /* I2S Interrupt Request Status Register0x00 */ +#define S5P_HDMI_I2S_CH0_L_0 S5P_HDMI_I2S_BASE(0x0064) /* I2S PCM Output Data Register0x00 */ +#define S5P_HDMI_I2S_CH0_L_1 S5P_HDMI_I2S_BASE(0x0068) /* I2S PCM Output Data Register0x00 */ +#define S5P_HDMI_I2S_CH0_L_2 S5P_HDMI_I2S_BASE(0x006C) /* I2S PCM Output Data Register0x00 */ +#define S5P_HDMI_I2S_CH0_L_3 S5P_HDMI_I2S_BASE(0x0070) /* I2S PCM Output Data Register0x00 */ +#define S5P_HDMI_I2S_CH0_R_0 S5P_HDMI_I2S_BASE(0x0074) /* I2S PCM Output Data Register0x00 */ +#define S5P_HDMI_I2S_CH0_R_1 S5P_HDMI_I2S_BASE(0x0078) /* I2S PCM Output Data Register0x00 */ +#define S5P_HDMI_I2S_CH0_R_2 S5P_HDMI_I2S_BASE(0x007C) /* I2S PCM Output Data Register0x00 */ +#define S5P_HDMI_I2S_CH0_R_3 S5P_HDMI_I2S_BASE(0x0080) /* I2S PCM Output Data Register0x00 */ +#define S5P_HDMI_I2S_CH1_L_0 S5P_HDMI_I2S_BASE(0x0084) /* I2S PCM Output Data Register0x00 */ +#define S5P_HDMI_I2S_CH1_L_1 S5P_HDMI_I2S_BASE(0x0088) /* I2S PCM Output Data Register0x00 */ +#define S5P_HDMI_I2S_CH1_L_2 S5P_HDMI_I2S_BASE(0x008C) /* I2S PCM Output Data Register0x00 */ +#define S5P_HDMI_I2S_CH1_L_3 S5P_HDMI_I2S_BASE(0x0090) /* I2S PCM Output Data Register0x00 */ +#define S5P_HDMI_I2S_CH1_R_0 S5P_HDMI_I2S_BASE(0x0094) /* I2S PCM Output Data Register0x00 */ +#define S5P_HDMI_I2S_CH1_R_1 S5P_HDMI_I2S_BASE(0x0098) /* I2S PCM Output Data Register0x00 */ +#define S5P_HDMI_I2S_CH1_R_2 S5P_HDMI_I2S_BASE(0x009C) /* I2S PCM Output Data Register0x00 */ +#define S5P_HDMI_I2S_CH1_R_3 S5P_HDMI_I2S_BASE(0x00A0) /* I2S PCM Output Data Register0x00 */ +#define S5P_HDMI_I2S_CH2_L_0 S5P_HDMI_I2S_BASE(0x00A4) /* I2S PCM Output Data Register0x00 */ +#define S5P_HDMI_I2S_CH2_L_1 S5P_HDMI_I2S_BASE(0x00A8) /* I2S PCM Output Data Register0x00 */ +#define S5P_HDMI_I2S_CH2_L_2 S5P_HDMI_I2S_BASE(0x00AC) /* I2S PCM Output Data Register0x00 */ +#define S5P_HDMI_I2S_CH2_L_3 S5P_HDMI_I2S_BASE(0x00B0) /* I2S PCM Output Data Register0x00 */ +#define S5P_HDMI_I2S_CH2_R_0 S5P_HDMI_I2S_BASE(0x00B4) /* I2S PCM Output Data Register0x00 */ +#define S5P_HDMI_I2S_CH2_R_1 S5P_HDMI_I2S_BASE(0x00B8) /* I2S PCM Output Data Register0x00 */ +#define S5P_HDMI_I2S_CH2_R_2 S5P_HDMI_I2S_BASE(0x00BC) /* I2S PCM Output Data Register0x00 */ +#define S5P_HDMI_I2S_Ch2_R_3 S5P_HDMI_I2S_BASE(0x00C0) /* I2S PCM Output Data Register0x00 */ +#define S5P_HDMI_I2S_CH3_L_0 S5P_HDMI_I2S_BASE(0x00C4) /* I2S PCM Output Data Register0x00 */ +#define S5P_HDMI_I2S_CH3_L_1 S5P_HDMI_I2S_BASE(0x00C8) /* I2S PCM Output Data Register0x00 */ +#define S5P_HDMI_I2S_CH3_L_2 S5P_HDMI_I2S_BASE(0x00CC) /* I2S PCM Output Data Register0x00 */ +#define S5P_HDMI_I2S_CH3_R_0 S5P_HDMI_I2S_BASE(0x00D0) /* I2S PCM Output Data Register0x00 */ +#define S5P_HDMI_I2S_CH3_R_1 S5P_HDMI_I2S_BASE(0x00D4) /* I2S PCM Output Data Register0x00 */ +#define S5P_HDMI_I2S_CH3_R_2 S5P_HDMI_I2S_BASE(0x00D8) /* I2S PCM Output Data Register0x00 */ +#define S5P_HDMI_I2S_CUV_L_R S5P_HDMI_I2S_BASE(0x00DC) /* I2S CUV Output Data Register0x00 */ + +#define S5P_SPDIFIN_CLK_CTRL S5P_HDMI_SPDIF_BASE(0x0000) /* SPDIFIN_CLK_CTRL [1:0] 0x02 */ +#define S5P_SPDIFIN_OP_CTRL S5P_HDMI_SPDIF_BASE(0x0004) /* SPDIFIN_OP_CTRL [1:0] 0x00 */ +#define S5P_SPDIFIN_IRQ_MASK S5P_HDMI_SPDIF_BASE(0x0008) /* SPDIFIN_IRQ_MASK[7:0] 0x00 */ +#define S5P_SPDIFIN_IRQ_STATUS S5P_HDMI_SPDIF_BASE(0x000C) /* SPDIFIN_IRQ_STATUS [7:0] 0x00 */ +#define S5P_SPDIFIN_CONFIG_1 S5P_HDMI_SPDIF_BASE(0x0010) /* SPDIFIN_CONFIG [7:0] 0x00 */ +#define S5P_SPDIFIN_CONFIG_2 S5P_HDMI_SPDIF_BASE(0x0014) /* SPDIFIN_CONFIG [11:8] 0x00 */ +#define S5P_SPDIFIN_USER_VALUE_1 S5P_HDMI_SPDIF_BASE(0x0020) /* SPDIFIN_USER_VALUE [7:0] 0x00 */ +#define S5P_SPDIFIN_USER_VALUE_2 S5P_HDMI_SPDIF_BASE(0x0024) /* SPDIFIN_USER_VALUE [15:8] 0x00 */ +#define S5P_SPDIFIN_USER_VALUE_3 S5P_HDMI_SPDIF_BASE(0x0028) /* SPDIFIN_USER_VALUE [23:16] 0x00 */ +#define S5P_SPDIFIN_USER_VALUE_4 S5P_HDMI_SPDIF_BASE(0x002C) /* SPDIFIN_USER_VALUE [31:24] 0x00 */ +#define S5P_SPDIFIN_CH_STATUS_0_1 S5P_HDMI_SPDIF_BASE(0x0030) /* SPDIFIN_CH_STATUS_0 [7:0] 0x00 */ +#define S5P_SPDIFIN_CH_STATUS_0_2 S5P_HDMI_SPDIF_BASE(0x0034) /* SPDIFIN_CH_STATUS_0 [15:8] 0x00 */ +#define S5P_SPDIFIN_CH_STATUS_0_3 S5P_HDMI_SPDIF_BASE(0x0038) /* SPDIFIN_CH_STATUS_0 [23:16] 0x00 */ +#define S5P_SPDIFIN_CH_STATUS_0_4 S5P_HDMI_SPDIF_BASE(0x003C) /* SPDIFIN_CH_STATUS_0 [31:24] 0x00 */ +#define S5P_SPDIFIN_CH_STATUS_1 S5P_HDMI_SPDIF_BASE(0x0040) /* SPDIFIN_CH_STATUS_1 0x00 */ +#define S5P_SPDIFIN_FRAME_PERIOD_1 S5P_HDMI_SPDIF_BASE(0x0048) /* SPDIF_FRAME_PERIOD [7:0] 0x00 */ +#define S5P_SPDIFIN_FRAME_PERIOD_2 S5P_HDMI_SPDIF_BASE(0x004C) /* SPDIF_FRAME_PERIOD [15:8] 0x00 */ +#define S5P_SPDIFIN_Pc_INFO_1 S5P_HDMI_SPDIF_BASE(0x0050) /* SPDIFIN_Pc_INFO [7:0] 0x00 */ +#define S5P_SPDIFIN_Pc_INFO_2 S5P_HDMI_SPDIF_BASE(0x0054) /* SPDIFIN_Pc_INFO [15:8] 0x00 */ +#define S5P_SPDIFIN_Pd_INFO_1 S5P_HDMI_SPDIF_BASE(0x0058) /* SPDIFIN_Pd_INFO [7:0] 0x00 */ +#define S5P_SPDIFIN_Pd_INFO_2 S5P_HDMI_SPDIF_BASE(0x005C) /* SPDIFIN_Pd_INFO [15:8] 0x00 */ +#define S5P_SPDIFIN_DATA_BUF_0_1 S5P_HDMI_SPDIF_BASE(0x0060) /* SPDIFIN_DATA_BUF_0 [7:0] 0x00 */ +#define S5P_SPDIFIN_DATA_BUF_0_2 S5P_HDMI_SPDIF_BASE(0x0064) /* SPDIFIN_DATA_BUF_0 [15:8] 0x00 */ +#define S5P_SPDIFIN_DATA_BUF_0_3 S5P_HDMI_SPDIF_BASE(0x0068) /* SPDIFIN_DATA_BUF_0 [23:16] 0x00 */ +#define S5P_SPDIFIN_USER_BUF_0 S5P_HDMI_SPDIF_BASE(0x006C) /* SPDIFIN_DATA_BUF_0 [31:28] 0x00 */ +#define S5P_SPDIFIN_DATA_BUF_1_1 S5P_HDMI_SPDIF_BASE(0x0070) /* SPDIFIN_DATA_BUF_1 [7:0] 0x00 */ +#define S5P_SPDIFIN_DATA_BUF_1_2 S5P_HDMI_SPDIF_BASE(0x0074) /* SPDIFIN_DATA_BUF_1 [15:8] 0x00 */ +#define S5P_SPDIFIN_DATA_BUF_1_3 S5P_HDMI_SPDIF_BASE(0x0078) /* SPDIFIN_DATA_BUF_1 [23:16] 0x00 */ +#define S5P_SPDIFIN_USER_BUF_1 S5P_HDMI_SPDIF_BASE(0x007C) /* SPDIFIN_DATA_BUF_1 [31:28] 0x00 */ + +/* HDMI_CON0 */ +#define BLUE_SCR_EN (1<<5) +#define BLUE_SCR_DIS (0<<5) +#define ASP_EN (1<<2) +#define ASP_DIS (0<<2) +#define PWDN_ENB_NORMAL (1<<1) +#define PWDN_ENB_PD (0<<1) +#define HDMI_EN (1<<0) +#define HDMI_DIS (~HDMI_EN) + +/* HDMI_CON1 */ +#define PX_LMT_CTRL_BYPASS (0<<5) +#define PX_LMT_CTRL_RGB (1<<5) +#define PX_LMT_CTRL_YPBPR (2<<5) +#define PX_LMT_CTRL_RESERVED (3<<5) + +/* HDMI_CON2 */ +#define VID_PREAMBLE_EN (0<<5) +#define VID_PREAMBLE_DIS (1<<5) +#define GUARD_BAND_EN (0<<1) +#define GUARD_BAND_DIS (1<<1) + +/* HDMI_STATUS */ +#define AUTHEN_ACK_AUTH (1<<7) +#define AUTHEN_ACK_NOT (0<<7) +#define AUD_FIFO_OVF_FULL (1<<6) +#define AUD_FIFO_OVF_NOT (0<<6) +#define UPDATE_RI_INT_OCC (1<<4) +#define UPDATE_RI_INT_NOT (0<<4) +#define UPDATE_RI_INT_CLEAR (1<<4) +#define UPDATE_PJ_INT_OCC (1<<3) +#define UPDATE_PJ_INT_NOT (0<<3) +#define UPDATE_PJ_INT_CLEAR (1<<3) +#define EXCHANGEKSV_INT_OCC (1<<2) +#define EXCHANGEKSV_INT_NOT (0<<2) +#define EXCHANGEKSV_INT_CLEAR (1<<2) +#define WATCHDOG_INT_OCC (1<<1) +#define WATCHDOG_INT_NOT (0<<1) +#define WATCHDOG_INT_CLEAR (1<<1) +#define WTFORACTIVERX_INT_OCC (1) +#define WTFORACTIVERX_INT_NOT (0) +#define WTFORACTIVERX_INT_CLEAR (1) + +/* HDMI_STATUS_EN */ +#define AUD_FIFO_OVF_EN (1<<6) +#define AUD_FIFO_OVF_DIS (0<<6) +#define UPDATE_RI_INT_EN (1<<4) +#define UPDATE_RI_INT_DIS (0<<4) +#define UPDATE_PJ_INT_EN (1<<3) +#define UPDATE_PJ_INT_DIS (0<<3) +#define EXCHANGEKSV_INT_EN (1<<2) +#define EXCHANGEKSV_INT_DIS (0<<2) +#define WATCHDOG_INT_EN (1<<1) +#define WATCHDOG_INT_DIS (0<<1) +#define WTFORACTIVERX_INT_EN (1) +#define WTFORACTIVERX_INT_DIS (0) +#define HDCP_STATUS_EN_ALL UPDATE_RI_INT_EN|\ + UPDATE_PJ_INT_DIS|\ + EXCHANGEKSV_INT_EN|\ + WATCHDOG_INT_EN|\ + WTFORACTIVERX_INT_EN + +#define HDCP_STATUS_DIS_ALL (~0x1f) + +/* HDMI_HPD */ +#define SW_HPD_PLUGGED (1<<1) +#define SW_HPD_UNPLUGGED (0<<1) + +/* HDMI_MODE_SEL */ +#define HDMI_MODE_EN (1<<1) +#define HDMI_MODE_DIS (0<<1) +#define DVI_MODE_EN (1) +#define DVI_MODE_DIS (0) + +/* HDCP_ENC_EN */ +#define HDCP_ENC_ENABLE (1) +#define HDCP_ENC_DISABLE (0) + +/* HDMI_BLUE_SCREEN0 */ +#define SET_BLUESCREEN_0(a) (0xff&(a)) + +/* HDMI_BLUE_SCREEN1 */ +#define SET_BLUESCREEN_1(a) (0xff&(a)) + +/* HDMI_BLUE_SCREEN2 */ +#define SET_BLUESCREEN_2(a) (0xff&(a)) + +/* HDMI_YMAX */ +#define SET_HDMI_YMAX(a) (0xff&(a)) + +/* HDMI_YMIN */ +#define SET_HDMI_YMIN(a) (0xff&(a)) + +/* HDMI_CMAX */ +#define SET_HDMI_CMAX(a) (0xff&(a)) + +/* HDMI_CMIN */ +#define SET_HDMI_CMIN(a) (0xff&(a)) + +/* HDMI_DI_PREFIX */ + +/* HDMI_VBI_ST_MG */ +#define SET_VBI_ST_MG(a) (0xff&(a)) + +/* HDMI_VBI_END_MG */ +#define SET_VBI_END_MG(a) (0xff&(a)) + +/* HDMI_VACT_ST_MG */ +#define SET_VACT_ST_MG(a) (0xff&(a)) + +/* HDMI_VACT_END_MG + HDMI_AUTH_ST_MG0 + HDMI_AUTH_ST_MG1 + HDMI_AUTH_END_MG0 + HDMI_AUTH_END_MG1 */ + +/* HDMI_H_BLANK0 */ +#define SET_H_BLANK_L(a) (0xff&(a)) + +/* HDMI_H_BLANK1 */ +#define SET_H_BLANK_H(a) (0x7&((a)>>8)) + +/* HDMI_V_BLANK0 */ +#define SET_V2_BLANK_L(a) (0xff&(a)) + +/* HDMI_V_BLANK1 */ +#define SET_V1_BLANK_L(a) ((0x1f&(a))<<3) +#define SET_V2_BLANK_H(a) (0x7&((a)>>8)) + +/* HDMI_V_BLANK2 */ +#define SET_V1_BLANK_H(a) (0x3f&((a)>>5)) + +/* HDMI_H_V_LINE0 */ +#define SET_V_LINE_L(a) (0xff&(a)) + +/* HDMI_H_V_LINE1 */ +#define SET_H_LINE_L(a) ((0xf&(a))<<4) +#define SET_V_LINE_H(a) (0xf&((a)>>8)) + +/* HDMI_H_V_LINE2 */ +#define SET_H_LINE_H(a) (0xff&((a)>>4)) + +/* HDMI_SYNC_MODE */ +#define V_SYNC_POL_ACT_LOW (1) +#define V_SYNC_POL_ACT_HIGH (0) + +/* HDMI_INT_PRO_MODE */ +#define INT_PRO_MODE_INTERLACE (1) +#define INT_PRO_MODE_PROGRESSIVE (0) + +/* HDMI_SEND_PER_START0 + HDMI_SEND_PER_START1 + HDMI_SEND_PER_END0 */ +#define SET_V_BOT_ST_L(a) (0xff&(a)) + +/* HDMI_SEND_PER_END1 */ +#define SET_V_BOT_END_L(a) ((0x1f&(a))<<3) +#define SET_V_BOT_ST_H(a) (0x7&((a)>>8)) + +/* HDMI_SEND_PER_END2 */ +#define SET_V_BOT_END_H(a) (0x3f&((a)>>5)) + +/* HDMI_V_BLANK_INTERLACE + HDMI_V_BLANK_INTERLACE + HDMI_V_BLANK_INTERLACE */ + +/* HDMI_H_SYNC_GEN0 */ +#define SET_HSYNC_START_L(a) (0xff&(a)) + +/* HDMI_H_SYNC_GEN1 */ +#define SET_HSYNC_END_L(a) ((0x3f&(a))<<2) +#define SET_HSYNC_START_H(a) (0x3&((a)>>8)) + +/* HDMI_H_SYNC_GEN2 */ +#define SET_HSYNC_POL_ACT_LOW (1<<4) +#define SET_HSYNC_POL_ACT_HIGH (0<<4) +#define SET_HSYNC_END_H(a) (0xf&((a)>>6)) + +/* HDMI_V_SYNC_GEN1_0 */ +#define SET_VSYNC_T_END_L(a) (0xff&(a)) + +/* HDMI_V_SYNC_GEN1_1 */ +#define SET_VSYNC_T_ST_L(a) ((0xf&(a))<<4) +#define SET_VSYNC_T_END_H(a) (0xf&((a)>>8)) + +/* HDMI_V_SYNC_GEN1_2 */ +#define SET_VSYNC_T_ST_H(a) (0xff&((a)>>4)) + +/* HDMI_V_SYNC_GEN2_0 */ +#define SET_VSYNC_B_END_L(a) (0xff&(a)) + +/* HDMI_V_SYNC_GEN2_1 */ +#define SET_VSYNC_B_ST_L(a) ((0xf&(a))<<4) +#define SET_VSYNC_B_END_H(a) (0xf&((a)>>8)) + +/* HDMI_V_SYNC_GEN2_2 */ +#define SET_VSYNC_B_ST_H(a) (0xff&((a)>>4)) + + +/* HDMI_V_SYNC_GEN3_0 */ +#define SET_VSYNC_H_POST_END_L(a) (0xff&(a)) + +/* HDMI_V_SYNC_GEN3_1 */ +#define SET_VSYNC_H_POST_ST_L(a) ((0xf&(a))<<4) +#define SET_VSYNC_H_POST_END_H(a) (0xf&((a)>>8)) + +/* HDMI_V_SYNC_GEN3_2 */ +#define SET_VSYNC_H_POST_ST_H(a) (0xff&((a)>>4)) + + +/* Audio releated packet register + HDMI_ASP_CON */ +#define SACD_EN (1<<5) +#define SACD_DIS (0<<5) +#define AUD_MODE_MULTI_CH (1<<4) +#define AUD_MODE_2_CH (0<<4) +#define SET_SP_PRE(a) (0xf&(a)) + +/* HDMI_ASP_SP_FLAT */ +#define SET_SP_FLAT(a) (0xf&(a)) + +/* HDMI_ASP_CHCFG0 + HDMI_ASP_CHCFG1 + HDMI_ASP_CHCFG2 + HDMI_ASP_CHCFG3 */ +#define SPK3R_SEL_I_PCM0L (0<<27) +#define SPK3R_SEL_I_PCM0R (1<<27) +#define SPK3R_SEL_I_PCM1L (2<<27) +#define SPK3R_SEL_I_PCM1R (3<<27) +#define SPK3R_SEL_I_PCM2L (4<<27) +#define SPK3R_SEL_I_PCM2R (5<<27) +#define SPK3R_SEL_I_PCM3L (6<<27) +#define SPK3R_SEL_I_PCM3R (7<<27) +#define SPK3L_SEL_I_PCM0L (0<<24) +#define SPK3L_SEL_I_PCM0R (1<<24) +#define SPK3L_SEL_I_PCM1L (2<<24) +#define SPK3L_SEL_I_PCM1R (3<<24) +#define SPK3L_SEL_I_PCM2L (4<<24) +#define SPK3L_SEL_I_PCM2R (5<<24) +#define SPK3L_SEL_I_PCM3L (6<<24) +#define SPK3L_SEL_I_PCM3R (7<<24) +#define SPK2R_SEL_I_PCM0L (0<<19) +#define SPK2R_SEL_I_PCM0R (1<<19) +#define SPK2R_SEL_I_PCM1L (2<<19) +#define SPK2R_SEL_I_PCM1R (3<<19) +#define SPK2R_SEL_I_PCM2L (4<<19) +#define SPK2R_SEL_I_PCM2R (5<<19) +#define SPK2R_SEL_I_PCM3L (6<<19) +#define SPK2R_SEL_I_PCM3R (7<<19) +#define SPK2L_SEL_I_PCM0L (0<<16) +#define SPK2L_SEL_I_PCM0R (1<<16) +#define SPK2L_SEL_I_PCM1L (2<<16) +#define SPK2L_SEL_I_PCM1R (3<<16) +#define SPK2L_SEL_I_PCM2L (4<<16) +#define SPK2L_SEL_I_PCM2R (5<<16) +#define SPK2L_SEL_I_PCM3L (6<<16) +#define SPK2L_SEL_I_PCM3R (7<<16) +#define SPK1R_SEL_I_PCM0L (0<<11) +#define SPK1R_SEL_I_PCM0R (1<<11) +#define SPK1R_SEL_I_PCM1L (2<<11) +#define SPK1R_SEL_I_PCM1R (3<<11) +#define SPK1R_SEL_I_PCM2L (4<<11) +#define SPK1R_SEL_I_PCM2R (5<<11) +#define SPK1R_SEL_I_PCM3L (6<<11) +#define SPK1R_SEL_I_PCM3R (7<<11) +#define SPK1L_SEL_I_PCM0L (0<<8) +#define SPK1L_SEL_I_PCM0R (1<<8) +#define SPK1L_SEL_I_PCM1L (2<<8) +#define SPK1L_SEL_I_PCM1R (3<<8) +#define SPK1L_SEL_I_PCM2L (4<<8) +#define SPK1L_SEL_I_PCM2R (5<<8) +#define SPK1L_SEL_I_PCM3L (6<<8) +#define SPK1L_SEL_I_PCM3R (7<<8) +#define SPK0R_SEL_I_PCM0L (0<<3) +#define SPK0R_SEL_I_PCM0R (1<<3) +#define SPK0R_SEL_I_PCM1L (2<<3) +#define SPK0R_SEL_I_PCM1R (3<<3) +#define SPK0R_SEL_I_PCM2L (4<<3) +#define SPK0R_SEL_I_PCM2R (5<<3) +#define SPK0R_SEL_I_PCM3L (6<<3) +#define SPK0R_SEL_I_PCM3R (7<<3) +#define SPK0L_SEL_I_PCM0L (0) +#define SPK0L_SEL_I_PCM0R (1) +#define SPK0L_SEL_I_PCM1L (2) +#define SPK0L_SEL_I_PCM1R (3) +#define SPK0L_SEL_I_PCM2L (4) +#define SPK0L_SEL_I_PCM2R (5) +#define SPK0L_SEL_I_PCM3L (6) +#define SPK0L_SEL_I_PCM3R (7) + +/* HDMI_ACR_CON */ +#define ALT_CTS_RATE_CTS_1 (0<<3) +#define ALT_CTS_RATE_CTS_11 (1<<3) +#define ALT_CTS_RATE_CTS_21 (2<<3) +#define ALT_CTS_RATE_CTS_31 (3<<3) +#define ACR_TX_MODE_NO_TX (0) +#define ACR_TX_MODE_TX_ONCE (1) +#define ACR_TX_MODE_TXCNT_VBI (2) +#define ACR_TX_MODE_TX_VPC (3) +#define ACR_TX_MODE_MESURE_CTS (4) + +/* HDMI_ACR_MCTS0 + HDMI_ACR_MCTS1 + HDMI_ACR_MCTS2 */ +#define SET_ACR_MCTS(a) (0xfffff&(a)) + +/* HDMI_ACR_CTS0 + HDMI_ACR_CTS1 + HDMI_ACR_CTS2 */ +#define SET_ACR_CTS(a) (0xfffff&(a)) + +/* HDMI_ACR_N0 + HDMI_ACR_N1 + HDMI_ACR_N2 */ +#define SET_ACR_N(a) (0xfffff&(a)) + +/* HDMI_ACR_LSB2 */ +#define SET_ACR_LSB2(a) (0xff&(a)) + +/* HDMI_ACR_TXCNT */ +#define SET_ACR_TXCNT(a) (0x1f&(a)) + +/* HDMI_ACR_TXINTERNAL */ +#define SET_ACR_TX_INTERNAL(a) (0xff&(a)) + +/* HDMI_ACR_CTS_OFFSET */ +#define SET_ACR_CTS_OFFSET(a) (0xff&(a)) + +/* HDMI_GCP_CON */ +#define GCP_CON_NO_TRAN (0) +#define GCP_CON_TRANS_ONCE (1) +#define GCP_CON_TRANS_EVERY_VSYNC (2) + +/* HDMI_GCP_BYTE1 */ +#define SET_GCP_BYTE1(a) (0xff&(a)) + + +/* ACP and ISRC1/2 packet registers + HDMI_ACP_CON */ +#define SET_ACP_FR_RATE(a) ((0x1f&(a))<<3) +#define ACP_CON_NO_TRAN (0) +#define ACP_CON_TRANS_ONCE (1) +#define ACP_CON_TRANS_EVERY_VSYNC (2) + +/* HDMI_ACP_TYPE */ +#define SET_ACP_TYPE(a) (0xff&(a)) + + +/* HDMI_ACP_DATA0 + HDMI_ACP_DATA1 + HDMI_ACP_DATA2 + HDMI_ACP_DATA3 + HDMI_ACP_DATA4 + HDMI_ACP_DATA5 + HDMI_ACP_DATA6 + HDMI_ACP_DATA7 + HDMI_ACP_DATA8 + HDMI_ACP_DATA9 + HDMI_ACP_DATA10 + HDMI_ACP_DATA11 + HDMI_ACP_DATA12 + HDMI_ACP_DATA13 + HDMI_ACP_DATA14 + HDMI_ACP_DATA15 + HDMI_ACP_DATA16 */ +#define SET_ACP_DATA(a) (0xff&(a)) + + +/* HDMI_ISRC_CON */ +#define SET_ISRC_FR_RATE(a) ((0x1f&(a))<<3) +#define ISRC_EN (1<<2) +#define ISRC_DIS (0<<2) +#define ISRC_TX_CON_NO_TRANS (0) +#define ISRC_TX_CON_TRANS_ONCE (1) +#define ISRC_TX_CON_TRANS_EVERY_VSYNC (2) + +/* HDMI_ISRC1_HEADER1 */ +#define SET_ISRC1_HEADER(a) (0xff&(a)) + +/* HDMI_ISRC1_DATA0 + HDMI_ISRC1_DATA1 + HDMI_ISRC1_DATA2 + HDMI_ISRC1_DATA3 + HDMI_ISRC1_DATA4 + HDMI_ISRC1_DATA5 + HDMI_ISRC1_DATA6 + HDMI_ISRC1_DATA7 + HDMI_ISRC1_DATA8 + HDMI_ISRC1_DATA9 + HDMI_ISRC1_DATA10 + HDMI_ISRC1_DATA11 + HDMI_ISRC1_DATA12 + HDMI_ISRC1_DATA13 + HDMI_ISRC1_DATA14 + HDMI_ISRC1_DATA15 */ +#define SET_ISRC1_DATA(a) (0xff&(a)) + +/* HDMI_ISRC2_DATA0 + HDMI_ISRC2_DATA1 + HDMI_ISRC2_DATA2 + HDMI_ISRC2_DATA3 + HDMI_ISRC2_DATA4 + HDMI_ISRC2_DATA5 + HDMI_ISRC2_DATA6 + HDMI_ISRC2_DATA7 + HDMI_ISRC2_DATA8 + HDMI_ISRC2_DATA9 + HDMI_ISRC2_DATA10 + HDMI_ISRC2_DATA11 + HDMI_ISRC2_DATA12 + HDMI_ISRC2_DATA13 + HDMI_ISRC2_DATA14 + HDMI_ISRC2_DATA15 */ +#define SET_ISRC2_DATA(a) (0xff&(a)) + + +/* AVI info-frame registers + HDMI_AVI_CON */ +#define AVI_TX_CON_NO_TRANS (0) +#define AVI_TX_CON_TRANS_ONCE (1) +#define AVI_TX_CON_TRANS_EVERY_VSYNC (2) + + +/* HDMI_AVI_CHECK_SUM */ +#define SET_AVI_CHECK_SUM(a) (0xff&(a)) + +#define HDMI_CON_PXL_REP_RATIO_MASK (1<<1 | 1<<0) +#define HDMI_DOUBLE_PIXEL_REPETITION (0x01) +#define AVI_PIXEL_REPETITION_DOUBLE (1<<0) +#define AVI_PICTURE_ASPECT_4_3 (1<<4) +#define AVI_PICTURE_ASPECT_16_9 (1<<5) + +/* HDMI_AVI_BYTE1 + HDMI_AVI_BYTE2 + HDMI_AVI_BYTE3 + HDMI_AVI_BYTE4 + HDMI_AVI_BYTE5 + HDMI_AVI_BYTE6 + HDMI_AVI_BYTE7 + HDMI_AVI_BYTE8 + HDMI_AVI_BYTE9 + HDMI_AVI_BYTE10 + HDMI_AVI_BYTE11 + HDMI_AVI_BYTE12 + HDMI_AVI_BYTE13 */ +#define SET_AVI_BYTE(a) (0xff&(a)) + +/* Audio info-frame registers + HDMI_AUI_CON */ +#define AUI_TX_CON_NO_TRANS (0) +#define AUI_TX_CON_TRANS_ONCE (1) +#define AUI_TX_CON_TRANS_EVERY_VSYNC (2) + +/* HDMI_AUI_CHECK_SUM + HDMI_AVI_CHECK_SUM */ +#define SET_AUI_CHECK_SUM(a) (0xff&(a)) + +/* HDMI_AUI_BYTE1 + HDMI_AUI_BYTE2 + HDMI_AUI_BYTE3 + HDMI_AUI_BYTE4 + HDMI_AUI_BYTE5 */ +#define SET_AUI_BYTE(a) (0xff&(a)) + +/* MPEG source info-frame registers + HDMI_MPG_CON */ +#define MPG_TX_CON_NO_TRANS (0) +#define MPG_TX_CON_TRANS_ONCE (1) +#define MPG_TX_CON_TRANS_EVERY_VSYNC (2) + +/* HDMI_MPG_CHECK_SUM */ +#define SET_MPG_CHECK_SUM(a) (0xff&(a)) + +/* HDMI_MPG_BYTE1 + HDMI_MPG_BYTE2 + HDMI_MPG_BYTE3 + HDMI_MPG_BYTE4 + HDMI_MPG_BYTE5 */ +#define SET_MPG_BYTE(a) (0xff&(a)) + +/* Souerce product desciptor info-f + HDMI_SPD_CON */ +#define SPD_TX_CON_NO_TRANS (0) +#define SPD_TX_CON_TRANS_ONCE (1) +#define SPD_TX_CON_TRANS_EVERY_VSYNC (2) + +/* HDMI_SPD_HEADER0 + HDMI_SPD_HEADER1 + HDMI_SPD_HEADER2 */ +#define SET_SPD_HEADER(a) (0xff&(a)) + +/* HDMI_SPD_DATA0 + HDMI_SPD_DATA1 + HDMI_SPD_DATA2 + HDMI_SPD_DATA3 + HDMI_SPD_DATA4 + HDMI_SPD_DATA5 + HDMI_SPD_DATA6 + HDMI_SPD_DATA7 + HDMI_SPD_DATA8 + HDMI_SPD_DATA9 + HDMI_SPD_DATA10 + HDMI_SPD_DATA11 + HDMI_SPD_DATA12 + HDMI_SPD_DATA13 + HDMI_SPD_DATA14 + HDMI_SPD_DATA15 + HDMI_SPD_DATA16 + HDMI_SPD_DATA17 + HDMI_SPD_DATA18 + HDMI_SPD_DATA19 + HDMI_SPD_DATA20 + HDMI_SPD_DATA21 + HDMI_SPD_DATA22 + HDMI_SPD_DATA23 + HDMI_SPD_DATA24 + HDMI_SPD_DATA25 + HDMI_SPD_DATA26 + HDMI_SPD_DATA27 */ +#define SET_SPD_DATA(a) (0xff&(a)) + + +/* HDMI_CSC_CON */ +#define OUT_OFFSET_SEL_RGB_FR (0<<4) +#define OUT_OFFSET_SEL_RGB_LR (2<<4) +#define OUT_OFFSET_SEL_YCBCR (3<<4) +#define IN_CLIP_EN (1<<2) +#define IN_CLIP_DIS (0<<2) +#define IN_OFFSET_SEL_RGB_FR (0) +#define IN_OFFSET_SEL_RGB_LR (2) +#define IN_OFFSET_SEL_YCBCR (3) + +/* HDMI_Y_G_COEF_L + HDMI_Y_G_COEF_H + HDMI_Y_B_COEF_L + HDMI_Y_B_COEF_H + HDMI_Y_R_COEF_L + HDMI_Y_R_COEF_H + HDMI_CB_G_COEF_L + HDMI_CB_G_COEF_H + HDMI_CB_B_COEF_L + HDMI_CB_B_COEF_H + HDMI_CB_R_COEF_L + HDMI_CB_R_COEF_H + HDMI_CR_G_COEF_L + HDMI_CR_G_COEF_H + HDMI_CR_B_COEF_L + HDMI_CR_B_COEF_H + HDMI_CR_R_COEF_L + HDMI_CR_R_COEF_H */ +#define SET_HDMI_CSC_COEF_L(a) (0xff&(a)) +#define SET_HDMI_CSC_COEF_H(a) (0x3&((a)>>8)) + +/* Test pattern generation register + HDMI_TPGEN_0 + HDMI_TPGEN_1 + HDMI_TPGEN_2 + HDMI_TPGEN_3 + HDMI_TPGEN_4 + HDMI_TPGEN_5 + HDMI_TPGEN_6 + + HDCP_RX_SHA_1_0_0 + HDCP_RX_SHA_1_0_1 + HDCP_RX_SHA_1_0_2 + HDCP_RX_SHA_1_0_3 + HDCP_RX_SHA_1_1_0 + HDCP_RX_SHA_1_1_1 + HDCP_RX_SHA_1_1_2 + HDCP_RX_SHA_1_1_3 + HDCP_RX_SHA_1_2_0 + HDCP_RX_SHA_1_2_1 + HDCP_RX_SHA_1_2_2 + HDCP_RX_SHA_1_2_3 + HDCP_RX_SHA_1_3_0 + HDCP_RX_SHA_1_3_1 + HDCP_RX_SHA_1_3_2 + HDCP_RX_SHA_1_3_3 + HDCP_RX_SHA_1_4_0 + HDCP_RX_SHA_1_4_1 + HDCP_RX_SHA_1_4_2 + HDCP_RX_SHA_1_4_3 */ +#define SET_HDMI_SHA1(a) (0xff&(a)) + +/* HDCP_RX_KSV_0_0 + HDCP_RX_KSV_0_1 + HDCP_RX_KSV_0_2 + HDCP_RX_KSV_0_3 + HDCP_RX_KSV_1_0 + HDCP_RX_KSV_1_1 + + HDCP_AUTH_STAT + + HDCP_CTRL + + HDCP_CHECK_RESULT + + HDCP_BKSV0_0 + HDCP_BKSV0_1 + HDCP_BKSV0_2 + HDCP_BKSV0_3 + HDCP_BKSV1 + HDCP_AKSV0_0 + HDCP_AKSV0_1 + HDCP_AKSV0_2 + HDCP_AKSV0_3 + HDCP_AKSV1 + + HDCP_AN0_0 + HDCP_AN0_1 + HDCP_AN0_2 + HDCP_AN0_3 + HDCP_AN1_0 + HDCP_AN1_1 + HDCP_AN1_2 + HDCP_AN1_3 + + HDCP_BCAPS + HDCP_BSTATUS0 + HDCP_BSTATUS1 + + HDCP_RI_0 + HDCP_RI_1 + HDCP_PJ + + HDCP_OFFSET_TX0 + HDCP_OFFSET_TX1 + HDCP_OFFSET_TX2 + HDCP_OFFSET_TX3 + HDCP_CYCLE_AA + HDCP_I2C_INT + HDCP_AN_INT + HDCP_WATCHDOG_INT + HDCP_RI_INT + HDCP_PJ_INT + + TG SFR + TG_CMD */ +#define GETSYNC_TYPE_EN (1<<4) +#define GETSYNC_TYPE_DIS (~GETSYNC_TYPE_EN) +#define GETSYNC_EN (1<<3) +#define GETSYNC_DIS (~GETSYNC_EN) +#define FIELD_EN (1<<1) +#define FIELD_DIS (~FIELD_EN) +#define TG_EN (1) +#define TG_DIS (~TG_EN) + +/* TG_CFG + TG_CB_SZ + TG_INDELAY_L + TG_INDELAY_H + TG_POL_CTRL + + TG_H_FSZ_L */ +#define SET_TG_H_FSZ_L(a) (0xff&(a)) + +/* TG_H_FSZ_H */ +#define SET_TG_H_FSZ_H(a) (0x1f&((a)>>8)) + +/* TG_HACT_ST_L */ +#define SET_TG_HACT_ST_L(a) (0xff&(a)) + +/* TG_HACT_ST_H */ +#define SET_TG_HACT_ST_H(a) (0xf&((a)>>8)) + +/* TG_HACT_SZ_L */ +#define SET_TG_HACT_SZ_L(a) (0xff&(a)) + +/* TG_HACT_SZ_H */ +#define SET_TG_HACT_SZ_H(a) (0xf&((a)>>8)) + +/* TG_V_FSZ_L */ +#define SET_TG_V_FSZ_L(a) (0xff&(a)) + +/* TG_V_FSZ_H */ +#define SET_TG_V_FSZ_H(a) (0x7&((a)>>8)) + +/* TG_VSYNC_L */ +#define SET_TG_VSYNC_L(a) (0xff&(a)) + +/* TG_VSYNC_H */ +#define SET_TG_VSYNC_H(a) (0x7&((a)>>8)) + +/* TG_VSYNC2_L */ +#define SET_TG_VSYNC2_L(a) (0xff&(a)) + +/* TG_VSYNC2_H */ +#define SET_TG_VSYNC2_H(a) (0x7&((a)>>8)) + +/* TG_VACT_ST_L */ +#define SET_TG_VACT_ST_L(a) (0xff&(a)) + +/* TG_VACT_ST_H */ +#define SET_TG_VACT_ST_H(a) (0x7&((a)>>8)) + +/* TG_VACT_SZ_L */ +#define SET_TG_VACT_SZ_L(a) (0xff&(a)) + +/* TG_VACT_SZ_H */ +#define SET_TG_VACT_SZ_H(a) (0x7&((a)>>8)) + +/* TG_FIELD_CHG_L */ +#define SET_TG_FIELD_CHG_L(a) (0xff&(a)) + +/* TG_FIELD_CHG_H */ +#define SET_TG_FIELD_CHG_H(a) (0x7&((a)>>8)) + +/* TG_VACT_ST2_L */ +#define SET_TG_VACT_ST2_L(a) (0xff&(a)) + +/* TG_VACT_ST2_H */ +#define SET_TG_VACT_ST2_H(a) (0x7&((a)>>8)) + +/* TG_VACT_SC_ST_L + TG_VACT_SC_ST_H + TG_VACT_SC_SZ_L + TG_VACT_SC_SZ_H + + TG_VSYNC_TOP_HDMI_L */ +#define SET_TG_VSYNC_TOP_HDMI_L(a) (0xff&(a)) + +/* TG_VSYNC_TOP_HDMI_H */ +#define SET_TG_VSYNC_TOP_HDMI_H(a) (0x7&((a)>>8)) + +/* TG_VSYNC_BOT_HDMI_L */ +#define SET_TG_VSYNC_BOT_HDMI_L(a) (0xff&(a)) + +/* TG_VSYNC_BOT_HDMI_H */ +#define SET_TG_VSYNC_BOT_HDMI_H(a) (0x7&((a)>>8)) + +/* TG_FIELD_TOP_HDMI_L */ +#define SET_TG_FIELD_TOP_HDMI_L(a) (0xff&(a)) + +/* TG_FIELD_TOP_HDMI_H */ +#define SET_TG_FIELD_TOP_HDMI_H(a) (0x7&((a)>>8)) + +/* TG_FIELD_BOT_HDMI_L */ +#define SET_TG_FIELD_BOT_HDMI_L(a) (0xff&(a)) + +/* TG_FIELD_BOT_HDMI_H */ +#define SET_TG_FIELD_BOT_HDMI_H(a) (0x7&((a)>>8)) + +/* TG_HSYNC_HDOUT_ST_L + TG_HSYNC_HDOUT_ST_H + TG_HSYNC_HDOUT_END_L + TG_HSYNC_HDOUT_END_H + TG_VSYNC_HDOUT_ST_L + TG_VSYNC_HDOUT_ST_H + TG_VSYNC_HDOUT_END_L + TG_VSYNC_HDOUT_END_H + TG_VSYNC_HDOUT_DLY_L + TG_VSYNC_HDOUT_DLY_H + TG_BT_ERR_RANGE + TG_BT_ERR_RESULT + TG_COR_THR + TG_COR_NUM + TG_BT_CON + TG_BT_H_FSZ_L + TG_BT_H_FSZ_H + TG_BT_HSYNC_ST + TG_BT_HSYNC_SZ + TG_BT_FSZ_L + TG_BT_FSZ_H + TG_BT_VACT_T_ST_L + TG_BT_VACT_T_ST_H + TG_BT_VACT_B_ST_L + TG_BT_VACT_B_ST_H + TG_BT_VACT_SZ_L + TG_BT_VACT_SZ_H + TG_BT_VSYNC_SZ + SPDIFIN_CLK_CTRL + SPDIFIN_OP_CTRL + + SPDIFIN_IRQ_MASK */ +#define IRQ_WRONG_SIGNAL_ENABLE (1<<0) +#define IRQ_CH_STATUS_RECOVERED_ENABLE (1<<1) +#define IRQ_WRONG_PREAMBLE_ENABLE (1<<2) +#define IRQ_STREAM_HEADER_NOT_DETECTED_ENABLE (1<<3) +#define IRQ_STREAM_HEADER_DETECTED_ENABLE (1<<4) +#define IRQ_STREAM_HEADER_NOT_DETECTED_AT_RIGHTTIME_ENABLE (1<<5) +#define IRQ_ABNORMAL_PD_ENABLE (1<<6) +#define IRQ_BUFFER_OVERFLOW_ENABLE (1<<7) + +/* SPDIFIN_IRQ_STATUS +SPDIFIN_CONFIG_1 */ + +#define CONFIG_FILTER_3_SAMPLE (0<<6) +#define CONFIG_FILTER_2_SAMPLE (1<<6) +#define CONFIG_LINEAR_PCM_TYPE (0<<5) +#define CONFIG_NON_LINEAR_PCM_TYPE (1<<5) +#define CONFIG_PCPD_AUTO_SET (0<<4) +#define CONFIG_PCPD_MANUAL_SET (1<<4) +#define CONFIG_WORD_LENGTH_AUTO_SET (0<<3) +#define CONFIG_WORD_LENGTH_MANUAL_SET (1<<3) +#define CONFIG_U_V_C_P_NEGLECT (0<<2) +#define CONFIG_U_V_C_P_REPORT (1<<2) +#define CONFIG_BURST_SIZE_1 (0<<1) +#define CONFIG_BURST_SIZE_2 (1<<1) +#define CONFIG_DATA_ALIGN_16BIT (0<<0) +#define CONFIG_DATA_ALIGN_32BIT (1<<0) + +/* SPDIFIN_CONFIG_2 + SPDIFIN_USER_VALUE_1 + SPDIFIN_USER_VALUE_2 + SPDIFIN_USER_VALUE_3 + SPDIFIN_USER_VALUE_4 + SPDIFIN_CH_STATUS_0_1 + SPDIFIN_CH_STATUS_0_2 + SPDIFIN_CH_STATUS_0_3 + SPDIFIN_CH_STATUS_0_4 + SPDIFIN_CH_STATUS_1 + SPDIFIN_FRAME_PERIOD_1 + SPDIFIN_FRAME_PERIOD_2 + SPDIFIN_PC_INFO_1 + SPDIFIN_PC_INFO_2 + SPDIFIN_PD_INFO_1 + SPDIFIN_PD_INFO_2 + SPDIFIN_DATA_BUF_0_1 + SPDIFIN_DATA_BUF_0_2 + SPDIFIN_DATA_BUF_0_3 + SPDIFIN_USER_BUF_0 + SPDIFIN_USER_BUF_1_1 + SPDIFIN_USER_BUF_1_2 + SPDIFIN_USER_BUF_1_3 + SPDIFIN_USER_BUF_1 + + HAES_START + HAES_DATA_SIZE_L + HAES_DATA_SIZE_H + HAES_DATA */ + +/* Macros - for HDCP */ + +/* HDMI SYSTEM STATUS FLAG REGISTER (STATUS, R/W, ADDRESS = 0XF030_0010) */ +#define AUTHEN_ACK_POS 7 +#define AUD_FIFO_OVF_POS 6 +/* RESERVED 5 */ +#define UPDATE_RI_INT_POS 4 +#define UPDATE_PJ_INT_POS 3 +#define EXCHANGEKSV_INT_POS 2 +#define WATCHDOG_INT_POS 1 +#define WTFORACTIVERX_INT_POS 0 + +#define AUTHENTICATED (0x1 << 7) +#define NOT_YET_AUTHENTICATED (0x0 << 7) +#define AUD_FIFO_OVF_INT_OCCURRED (0x1 << 6) +#define AUD_FIFO_OVF_INT_NOT_OCCURRED (0x0 << 6) +/* RESERVED 5 */ +#define UPDATE_RI_INT_OCCURRED (0x1 << 4) +#define UPDATE_RI_INT_NOT_OCCURRED (0x0 << 4) +#define UPDATE_PJ_INT_OCCURRED (0x1 << 3) +#define UPDATE_PJ_INT_NOT_OCCURRED (0x0 << 3) +#define EXCHANGEKSV_INT_OCCURRED (0x1 << 2) +#define EXCHANGEKSV_INT_NOT_OCCURRED (0x0 << 2) +#define WATCHDOG_INT_OCCURRED (0x1 << 1) +#define WATCHDOG_INT_NOT_OCCURRED (0x0 << 1) +#define WTFORACTIVERX_INT_OCCURRED (0x1 << 0) +#define WTFORACTIVERX_INT_NOT_OCCURRED (0x0 << 0) + +/* HDMI SYSTEM STATUS ENABLE REGISTER (STATUS_EN, R/W, ADDRESS = 0XF030_0020) */ +/* RESERVED 7 */ +#define AUD_FIFO_OVF_INT_EN (0x1 << 6) +#define AUD_FIFO_OVF_INT_DIS (0x0 << 6) +/* RESERVED 5 */ + +/* EFUSE CONTROL REGISTER */ +#define EFUSE_CTRL_ACTIVATE (1) +#define EFUSE_ADDR_WIDTH (240) +#define EFUSE_SIGDEV_ASSERT (0) +#define EFUSE_SIGDEV_DEASSERT (96) +#define EFUSE_PRCHG_ASSERT (0) +#define EFUSE_PRCHG_DEASSERT (144) +#define EFUSE_FSET_ASSERT (48) +#define EFUSE_FSET_DEASSERT (192) +#define EFUSE_SENSING (240) +#define EFUSE_SCK_ASSERT (48) +#define EFUSE_SCK_DEASSERT (144) +#define EFUSE_SDOUT_OFFSET (192) +#define EFUSE_READ_OFFSET (192) + +#define EFUSE_ECC_DONE (1<<0) +#define EFUSE_ECC_BUSY (1<<1) +#define EFUSE_ECC_FAIL (1<<2) + +/* HDCP CONTROL REGISTER (HDCP_CTRL1, R/W, ADDRESS = 0XF030_ 0680) */ +#define EN_PJ_EN (0x1 << 4) +#define EN_PJ_DIS (~EN_PJ_EN) +/* RESERVED 3 */ +#define SET_REPEATER_TIMEOUT (0x1 << 2) +#define CLEAR_REPEATER_TIMEOUT (~SET_REPEATER_TIMEOUT) +#define CP_DESIRED_EN (0x1 << 1) +#define CP_DESIRED_DIS (~CP_DESIRED_EN) +#define ENABLE_1_DOT_1_FEATURE_EN (0x1 << 0) +#define ENABLE_1_DOT_1_FEATURE_DIS (~ENABLE_1_DOT_1_FEATURE_EN) + +/* HDCP_CHECK_RESULT, R/W, ADDRESS = 0XF030_ 0690 */ +#define Pi_MATCH_RESULT__YES ((0x1<<3) | (0x1<<2)) +#define Pi_MATCH_RESULT__NO ((0x1<<3) | (0x0<<2)) +#define Ri_MATCH_RESULT__YES ((0x1<<1) | (0x1<<0)) +#define Ri_MATCH_RESULT__NO ((0x1<<1) | (0x0<<0)) +#define CLEAR_ALL_RESULTS 0x0 + +/* HDCP ENCRYPTION ENABLE REGISTER (ENC_EN, R/W, ADDRESS = 0XF030_0044) */ +#define HDCP_ENC_DIS (0x0 << 0) + +/* BCAPS INFORMATION FROM RX. THIS VALUE IS THE DATA READ FROM RX + * (HDCP_BCAPS, R/W,ADDRESS = 0XF030_0700) + RESERVED 7 */ +#define REPEATER_SET (0x1 << 6) +#define REPEATERP_CLEAR (0x1 << 6) +#define READY_SET (0x1 << 5) +#define READY_CLEAR (0x1 << 5) +#define FAST_SET (0x1 << 4) +#define FAST_CLEAR (0x1 << 4) +/* RESERVED 3 + RESERVED 2 */ +#define ONE_DOT_ONE_FEATURES_SET (0x1 << 1) +#define ONE_DOT_ONE_FEATURES_CLEAR (0x1 << 1) +#define FAST_REAUTHENTICATION_SET (0x1 << 0) +#define FAST_REAUTHENTICATION_CLEAR (0x1 << 0) + +/* HAES REGISTERS + HAES CONTROL */ +#define SCRAMBLER_KEY_START_EN (0x1 << 7) +#define SCRAMBLER_KEY_START_DIS (~SCRAMBLER_KEY_START_EN) +#define SCRAMBLER_KEY_DONE (0x1 << 6) +#define SCRAMBLER_KEY_GENERATING (0x0 << 6) +/* RESERVED 1<-->5 */ +#define HAES_START_EN (0x1 << 0) +#define HAES_DECRYPTION_DONE (0x0 << 0) + +#define AN_SIZE 8 +#define AKSV_SIZE 5 +#define BKSV_SIZE 5 +#define HDCPLink_Addr 0x74 + +#define CABLE_PLUGGED 1<<1 +#define CABLE_UNPLUGGED 0<<1 + +#define DDC_Addr 0xA0 +#define eDDC_Addr 0x60 +#define HDCPLink_Addr 0x74 + +#define HDCP_Bksv 0x00 +#define HDCP_Aksv 0x10 +#define HDCP_Ainfo 0x15 +#define HDCP_An 0x18 +#define HDCP_Ri 0x08 +#define HDCP_Bcaps 0x40 +#define HDCP_BStatus 0x41 +#define HDCP_Pj 0x0a + +#define HDCP_KSVFIFO 0x43 +#define HDCP_SHA1 0x20 + +#define HDMI_MODE_HDMI 0 +#define HDMI_MODE_DVI 1 + +#define EDID_SEGMENT_ID 0x60 +#define EDID_SEGMENT0 0x00 +#define EDID_SEGMENT1 0x01 + +#define EDID_DEVICE_ID 0xA0 +#define EDID_ADDR_START 0x00 +#define EDID_ADDR_EXT 0x80 +#define EDID_RCOUNT 127 + +#define EDID_POS_EXTENSION 0x7E +#define EDID_POS_CHECKSUM 0x7F +/* #define EDID_POS_ERROR 516 // 512+1 // move to hdmi.h by shin...1229 */ +#define VALID_EDID 0xA5 +#define NO_VALID_EDID 0 + +#define EDID_POS_RBUFFER0 0x00 //segment0, 128-byte +#define EDID_POS_RBUFFER1 0x80 //segment0, 256-byte +#define EDID_POS_RBUFFER2 0x100 //segment1, 128-byte +#define EDID_POS_RBUFFER3 0x180 //segment1, 256-byte + +#define EDID_TIMING_EXT_TAG_ADDR_POS 0x80 +#define EDID_TIMING_EXT_REV_NUMBER 0x81 +#define EDID_DETAILED_TIMING_OFFSET_POS 0x82 +#define EDID_COLOR_SPACE_ADDR 0x83 +#define EDID_DATA_BLOCK_ADDRESS 0x84 +#define EDID_TIMING_EXT_TAG_VAL 0x02 +#define EDID_YCBCR444_CS_MASK 0x20 +#define EDID_YCBCR422_CS_MASK 0x10 +#define EDID_TAG_CODE_MASK 0xE0 +#define EDID_DATA_BLOCK_SIZE_MASK 0x1F +#define EDID_NATIVE_RESOLUTION_MASK 0x80 + +#define EDID_SHORT_AUD_DEC_TAG 0x20 +#define EDID_SHORT_VID_DEC_TAG 0x40 +#define EDID_HDMI_VSDB_TAG 0x60 +#define EDID_SPEAKER_ALLOCATION_TAG 0x80 + +#define COLOR_SPACE_RGB 0 +#define COLOR_SPACE_YCBCR444 1 +#define COLOR_SPACE_YCBCR422 2 + +#define SHORT_VID_720_480P_4_3_NT 0x01 +#define SHORT_VID_720_480P_16_9_NT 0x02 +#define SHORT_VID_1280_720P_16_9_NT 0x04 +#define SHORT_VID_1920_1080i_16_9_NT 0x08 +#define SHORT_VID_720_576P_4_3_PAL 0x10 +#define SHORT_VID_720_576P_16_9_PAL 0x20 +#define SHORT_VID_1280_720P_16_9_PAL 0x40 +#define SHORT_VID_1920_1080i_16_9_PAL 0x80 + +#define SET_HDMI_RESOLUTION_480P 0x00 +#define SET_HDMI_RESOLUTION_720P 0x01 +#define SET_HDMI_RESOLUTION_1080i 0x02 + +#define HDMI_WAIT_TIMEOUT 20 +#define AUTHENTICATION_SUCCESS 0 +#define AUTHENTICATION_FAILURE 1 +#define AUTHENTICATION_FAIL_CNT 2 + +#define HDCP_MAX_DEVS 128 +#define HDCP_KSV_SIZE 5 + +#define CMD_IIC_ADDRMODE_CHANGE 0xFF + +/* IIC Addressing Mode Definition */ +#define IIC_ADDRMODE_1 0 +#define IIC_ADDRMODE_2 1 +#define IIC_ADDRMODE_3 2 +#define HDMI_IIC_ADDRMODE IIC_ADDRMODE_1 + +#define IIC_ACK 0 +#define IIC_NOACK 1 + +#define EDID_POS_ERROR 512 +#define R_VAL_RETRY_CNT 5 + +#define CABLE_INSERT 1 +#define CABLE_REMOVE (~CABLE_INSERT) + +#define HDMI_PHY_READY (1<<0) + +/* Color Depth + CD0, CD1, CD2, CD3 */ + +#define GCP_CD_NOT_INDICATED 0 +#define GCP_CD_24BPP (1<<2) +#define GCP_CD_30BPP (1<<0 | 1<<2) +#define GCP_CD_36BPP (1<<1 | 1<<2) +#define GCP_CD_48BPP (1<<0 | 1<<1 | 1<<2) + +#define GCP_DEFAULT_PHASE 1 + +/* for DC_CONTRAL */ +#define HDMI_DC_CTL_8 0 +#define HDMI_DC_CTL_10 (1<<0) +#define HDMI_DC_CTL_12 (1<<1) + +#define DO_NOT_TRANSMIT (0) + +#define HPD_SW_ENABLE (1<<0) +#define HPD_SW_DISABLE (0) +#define HPD_ON (1<<1) +#define HPD_OFF (0) + + +#endif /* __ASM_ARCH_REGS_HDMI_H */ + + diff --git a/drivers/media/video/samsung/tv20/s5pv210/regs/regs-sdaout.h b/drivers/media/video/samsung/tv20/s5pv210/regs/regs-sdaout.h new file mode 100644 index 0000000..2553b57 --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5pv210/regs/regs-sdaout.h @@ -0,0 +1,517 @@ +/* linux/drivers/media/video/samsung/tv20/s5pc100/regs/regs-sdout.h + * + * TV Encoder register header file for Samsung TVOut driver + * + * Copyright (c) 2010 Samsung Electronics + * http://www.samsung.com/ + * + * 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. +*/ + +#ifndef __ASM_ARCH_REGS_SDAOUT_H + +#include <mach/map.h> + +#define S5P_SDAOUT_BASE(x) (x) +/* + Registers +*/ +#define S5P_SDO_CLKCON S5P_SDAOUT_BASE(0x0000) // Clock Control Register 0x0000_0000 +#define S5P_SDO_CONFIG S5P_SDAOUT_BASE(0x0008) // Video Standard Configuration Register 0x0024_2430 +#define S5P_SDO_SCALE S5P_SDAOUT_BASE(0x000C) // Video Scale Configuration Register 0x0000_0006 +#define S5P_SDO_SYNC S5P_SDAOUT_BASE(0x0010) // Video Sync Configuration Register 0x0000_0001 +#define S5P_SDO_VBI S5P_SDAOUT_BASE(0x0014) // VBI Configuration Register 0x0007_77FF +#define S5P_SDO_SCALE_CH0 S5P_SDAOUT_BASE(0x001C) // Scale Control Register for DAC Channel0 0x0000_0800 +#define S5P_SDO_SCALE_CH1 S5P_SDAOUT_BASE(0x0020) // Scale Control Register for DAC Channel1 0x0000_0800 +#define S5P_SDO_SCALE_CH2 S5P_SDAOUT_BASE(0x0024) // Scale Control Register for DAC Channel2 0x0000_0800 +#define S5P_SDO_YCDELAY S5P_SDAOUT_BASE(0x0034) // Video Delay Control Register 0x0000_FA00 +#define S5P_SDO_SCHLOCK S5P_SDAOUT_BASE(0x0038) // SCH Phase Control Register 0x0000_0000 +#define S5P_SDO_DAC S5P_SDAOUT_BASE(0x003C) // DAC Configuration Register 0x0000_0000 +#define S5P_SDO_FINFO S5P_SDAOUT_BASE(0x0040) // Status Register 0x0000_0002 +#define S5P_SDO_Y0 S5P_SDAOUT_BASE(0x0044) // Y- AAF 1¡¯st and 23¡¯th Coefficient (AAF : Anti-Aliasing Filter) 0x0000_0000 +#define S5P_SDO_Y1 S5P_SDAOUT_BASE(0x0048) // Y- AAF 2¡¯nd and 22¡¯th Coefficient 0x0000_0000 +#define S5P_SDO_Y2 S5P_SDAOUT_BASE(0x004C) // Y- AAF 3¡¯rd and 21¡¯th Coefficient 0x0000_0000 +#define S5P_SDO_Y3 S5P_SDAOUT_BASE(0x0050) // Y- AAF 4¡¯th and 20¡¯th Coefficient 0x0000_0000 +#define S5P_SDO_Y4 S5P_SDAOUT_BASE(0x0054) // Y- AAF 5¡¯th and 19¡¯th Coefficient 0x0000_0000 +#define S5P_SDO_Y5 S5P_SDAOUT_BASE(0x0058) // Y- AAF 6¡¯th and 18¡¯th Coefficient 0x0000_0000 +#define S5P_SDO_Y6 S5P_SDAOUT_BASE(0x005C) // Y- AAF 7¡¯th and 17¡¯th Coefficient 0x0000_0000 +#define S5P_SDO_Y7 S5P_SDAOUT_BASE(0x0060) // Y- AAF 8¡¯th and 16¡¯th Coefficient 0x0000_0000 +#define S5P_SDO_Y8 S5P_SDAOUT_BASE(0x0064) // Y - AAF 9¡¯th and 15¡¯th Coefficient 0x0000_0000 +#define S5P_SDO_Y9 S5P_SDAOUT_BASE(0x0068) // Y- AAF 10¡¯th and 14¡¯th Coefficient 0x0000_0000 +#define S5P_SDO_Y10 S5P_SDAOUT_BASE(0x006C) // Y- AAF 11¡¯th and 13¡¯th Coefficient 0x0000_0000 +#define S5P_SDO_Y11 S5P_SDAOUT_BASE(0x0070) // Y- AAF 12¡¯th Coefficient 0x0000_025D +#define S5P_SDO_CB0 S5P_SDAOUT_BASE(0x0080) // CB- AAF 1¡¯st and 23¡¯th Coefficient 0x0000_0000 +#define S5P_SDO_CB1 S5P_SDAOUT_BASE(0x0084) // CB- AAF 2¡¯nd and 22¡¯th Coefficient 0x0000_0000 +#define S5P_SDO_CB2 S5P_SDAOUT_BASE(0x0088) // CB- AAF 3¡¯rd and 21¡¯th Coefficient 0x0000_0000 +#define S5P_SDO_CB3 S5P_SDAOUT_BASE(0x008C) // CB-AAF 4¡¯th and 20¡¯th Coefficient 0x0000_0000 +#define S5P_SDO_CB4 S5P_SDAOUT_BASE(0x0090) // CB- AAF 5¡¯th and 19¡¯th Coefficient 0x0000_0000 +#define S5P_SDO_CB5 S5P_SDAOUT_BASE(0x0094) // CB- AAF 6¡¯th and 18¡¯th Coefficient 0x0000_0001 +#define S5P_SDO_CB6 S5P_SDAOUT_BASE(0x0098) // CB- AAF 7¡¯th and 17¡¯th Coefficient 0x0000_0007 +#define S5P_SDO_CB7 S5P_SDAOUT_BASE(0x009C) // CB- AAF 8¡¯th and 16¡¯th Coefficient 0x0000_0014 +#define S5P_SDO_CB8 S5P_SDAOUT_BASE(0x00A0) // CB- AAF 9¡¯th and 15¡¯th Coefficient 0x0000_0028 +#define S5P_SDO_CB9 S5P_SDAOUT_BASE(0x00A4) // CB- AAF 10¡¯th and 14¡¯th Coefficient 0x0000_003F +#define S5P_SDO_CB10 S5P_SDAOUT_BASE(0x00A8) // CB- AAF 11¡¯th and 13¡¯th Coefficient 0x0000_0052 +#define S5P_SDO_CB11 S5P_SDAOUT_BASE(0x00AC) // CB- AAF 12¡¯th Coefficient 0x0000_005A +#define S5P_SDO_CR0 S5P_SDAOUT_BASE(0x00C0) // CR- AAF 1¡¯st and 23¡¯th Coefficient 0x0000_0000 +#define S5P_SDO_CR1 S5P_SDAOUT_BASE(0x00C4) // CR- AAF 2¡¯nd and 22¡¯th Coefficient 0x0000_0000 +#define S5P_SDO_CR2 S5P_SDAOUT_BASE(0x00C8) // CR- AAF 3¡¯rd and 21¡¯th Coefficient 0x0000_0000 +#define S5P_SDO_CR3 S5P_SDAOUT_BASE(0x00CC) // CR-AAF 4¡¯th and 20¡¯th Coefficient 0x0000_0000 +#define S5P_SDO_CR4 S5P_SDAOUT_BASE(0x00D0) // CR- AAF 5¡¯th and 19¡¯th Coefficient 0x0000_0000 +#define S5P_SDO_CR5 S5P_SDAOUT_BASE(0x00D4) // CR- AAF 6¡¯th and 18¡¯th Coefficient 0x0000_0001 +#define S5P_SDO_CR6 S5P_SDAOUT_BASE(0x00D8) // CR- AAF 7¡¯th and 17¡¯th Coefficient 0x0000_0009 +#define S5P_SDO_CR7 S5P_SDAOUT_BASE(0x00DC) // CR- AAF 8¡¯th and 16¡¯th Coefficient 0x0000_001C +#define S5P_SDO_CR8 S5P_SDAOUT_BASE(0x00E0) // CR- AAF 9¡¯th and 15¡¯th Coefficient 0x0000_0039 +#define S5P_SDO_CR9 S5P_SDAOUT_BASE(0x00E4) // CR- AAF 10¡¯th and 14¡¯th Coefficient 0x0000_005A +#define S5P_SDO_CR10 S5P_SDAOUT_BASE(0x00E8) // CR- AAF 11¡¯th and 13¡¯th Coefficient 0x0000_0074 +#define S5P_SDO_CR11 S5P_SDAOUT_BASE(0x00EC) // CR- AAF 12¡¯th Coefficient 0x0000_007E +#define S5P_SDO_MV_ON S5P_SDAOUT_BASE(0x0100) +#define S5P_SDO_MV_SLINE_FIRST_EVEN S5P_SDAOUT_BASE(0x0104) +#define S5P_SDO_MV_SLINE_FIRST_SPACE_EVEN S5P_SDAOUT_BASE(0x0108) +#define S5P_SDO_MV_SLINE_FIRST_ODD S5P_SDAOUT_BASE(0x010C) +#define S5P_SDO_MV_SLINE_FIRST_SPACE_ODD S5P_SDAOUT_BASE(0x0110) +#define S5P_SDO_MV_SLINE_SPACING S5P_SDAOUT_BASE(0x0114) +#define S5P_SDO_MV_STRIPES_NUMBER S5P_SDAOUT_BASE(0x0118) +#define S5P_SDO_MV_STRIPES_THICKNESS S5P_SDAOUT_BASE(0x011C) +#define S5P_SDO_MV_PSP_DURATION S5P_SDAOUT_BASE(0x0120) +#define S5P_SDO_MV_PSP_FIRST S5P_SDAOUT_BASE(0x0124) +#define S5P_SDO_MV_PSP_SPACING S5P_SDAOUT_BASE(0x0128) +#define S5P_SDO_MV_SEL_LINE_PSP_AGC S5P_SDAOUT_BASE(0x012C) +#define S5P_SDO_MV_SEL_FORMAT_PSP_AGC S5P_SDAOUT_BASE(0x0130) +#define S5P_SDO_MV_PSP_AGC_A_ON S5P_SDAOUT_BASE(0x0134) +#define S5P_SDO_MV_PSP_AGC_B_ON S5P_SDAOUT_BASE(0x0138) +#define S5P_SDO_MV_BACK_PORCH S5P_SDAOUT_BASE(0x013C) +#define S5P_SDO_MV_BURST_ADVANCED_ON S5P_SDAOUT_BASE(0x0140) +#define S5P_SDO_MV_BURST_DURATION_ZONE1 S5P_SDAOUT_BASE(0x0144) +#define S5P_SDO_MV_BURST_DURATION_ZONE2 S5P_SDAOUT_BASE(0x0148) +#define S5P_SDO_MV_BURST_DURATION_ZONE3 S5P_SDAOUT_BASE(0x014C) +#define S5P_SDO_MV_BURST_PHASE_ZONE S5P_SDAOUT_BASE(0x0150) +#define S5P_SDO_MV_SLICE_PHASE_LINE S5P_SDAOUT_BASE(0x0154) +#define S5P_SDO_MV_RGB_PROTECTION_ON S5P_SDAOUT_BASE(0x0158) +#define S5P_SDO_MV_480P_PROTECTION_ON S5P_SDAOUT_BASE(0x015C) +#define S5P_SDO_CCCON S5P_SDAOUT_BASE(0x0180) // Color Compensation On/ Off Control 0x0000_0000 +#define S5P_SDO_YSCALE S5P_SDAOUT_BASE(0x0184) // Brightness Control for Y 0x0080_0000 +#define S5P_SDO_CBSCALE S5P_SDAOUT_BASE(0x0188) // Hue/ Saturation Control for CB 0x0080_0000 +#define S5P_SDO_CRSCALE S5P_SDAOUT_BASE(0x018C) // Hue/ Saturation Control for CR 0x0000_0080 +#define S5P_SDO_CB_CR_OFFSET S5P_SDAOUT_BASE(0x0190) // Hue/ Sat Offset Control for CB/CR 0x0000_0000 +#define S5P_SDO_RGB_CC S5P_SDAOUT_BASE(0x0194) // Color Compensation of RGB Output 0x0000_EB10 +#define S5P_SDO_CVBS_CC_Y1 S5P_SDAOUT_BASE(0x0198) // Color Compensation of CVBS Output 0x0200_0000 +#define S5P_SDO_CVBS_CC_Y2 S5P_SDAOUT_BASE(0x019C) // Color Compensation of CVBS Output 0x03FF_0200 +#define S5P_SDO_CVBS_CC_C S5P_SDAOUT_BASE(0x01A0) // Color Compensation of CVBS Output 0x0000_01FF +#define S5P_SDO_YC_CC_Y S5P_SDAOUT_BASE(0x01A4) // Color Compensation of S-video Output 0x03FF_0000 +#define S5P_SDO_YC_CC_C S5P_SDAOUT_BASE(0x01A8) // Color Compensation of S-video Output 0x0000_01FF +#define S5P_SDO_CSC_525_PORCH S5P_SDAOUT_BASE(0x01B0) // Porch Position Control of CSC in 525 Line 0x008A_0359 +#define S5P_SDO_CSC_625_PORCH S5P_SDAOUT_BASE(0x01B4) // Porch Position Control of CSC in 625 Line 0x0096_035C +#define S5P_SDO_RGBSYNC S5P_SDAOUT_BASE(0x01C0) // VESA RGB Sync Control Register 0x0000_0000 +#define S5P_SDO_OSFC00_0 S5P_SDAOUT_BASE(0x0200) // OverSampling Filter (OSF) Coefficient 1 & 0. of channel #0 0x00FD_00FE +#define S5P_SDO_OSFC01_0 S5P_SDAOUT_BASE(0x0204) // OSF Coefficient 3 & 2 of Channel #0 0x0000_0000 +#define S5P_SDO_OSFC02_0 S5P_SDAOUT_BASE(0x0208) // OSF Coefficient 5 & 4 of Channel #0 0x0005_0004 +#define S5P_SDO_OSFC03_0 S5P_SDAOUT_BASE(0x020C) // OSF Coefficient 7 & 6 of Channel #0 0x0000_00FF +#define S5P_SDO_OSFC04_0 S5P_SDAOUT_BASE(0x0210) // OSF Coefficient 9 & 8 of Channel #0 0x00F7_00FA +#define S5P_SDO_OSFC05_0 S5P_SDAOUT_BASE(0x0214) // OSF Coefficient 11 & 10 of Channel #0 0x0000_0001 +#define S5P_SDO_OSFC06_0 S5P_SDAOUT_BASE(0x0218) // OSF Coefficient 13 & 12 of Channel #0 0x000E_000A +#define S5P_SDO_OSFC07_0 S5P_SDAOUT_BASE(0x021C) // OSF Coefficient 15 & 14 of Channel #0 0x0000_01FF +#define S5P_SDO_OSFC08_0 S5P_SDAOUT_BASE(0x0220) // OSF Coefficient 17 & 16 of Channel #0 0x01EC_01F2 +#define S5P_SDO_OSFC09_0 S5P_SDAOUT_BASE(0x0224) // OSF Coefficient 19 & 18 of Channel #0 0x0000_0001 +#define S5P_SDO_OSFC10_0 S5P_SDAOUT_BASE(0x0228) // OSF Coefficient 21 & 20 of Channel #0 0x001D_0014 +#define S5P_SDO_OSFC11_0 S5P_SDAOUT_BASE(0x022C) // OSF Coefficient 23 & 22 of Channel #0 0x0000_01FE +#define S5P_SDO_OSFC12_0 S5P_SDAOUT_BASE(0x0230) // OSF Coefficient 25 & 24 of Channel #0 0x03D8_03E4 +#define S5P_SDO_OSFC13_0 S5P_SDAOUT_BASE(0x0234) // OSF Coefficient 27 & 26 of Channel #0 0x0000_0002 +#define S5P_SDO_OSFC14_0 S5P_SDAOUT_BASE(0x0238) // OSF Coefficient 29 & 28 of Channel #0 0x0038_0028 +#define S5P_SDO_OSFC15_0 S5P_SDAOUT_BASE(0x023C) // OSF Coefficient 31 & 30 of Channel #0 0x0000_03FD +#define S5P_SDO_OSFC16_0 S5P_SDAOUT_BASE(0x0240) // OSF Coefficient 33 & 32 of Channel #0 0x03B0_03C7 +#define S5P_SDO_OSFC17_0 S5P_SDAOUT_BASE(0x0244) // OSF Coefficient 35 & 34 of Channel #0 0x0000_0005 +#define S5P_SDO_OSFC18_0 S5P_SDAOUT_BASE(0x0248) // OSF Coefficient 37 & 36 of Channel #0 0x0079_0056 +#define S5P_SDO_OSFC19_0 S5P_SDAOUT_BASE(0x024C) // OSF Coefficient 39 & 38 of Channel #0 0x0000_03F6 +#define S5P_SDO_OSFC20_0 S5P_SDAOUT_BASE(0x0250) // OSF Coefficient 41 & 40 of Channel #0 0x072C_0766 +#define S5P_SDO_OSFC21_0 S5P_SDAOUT_BASE(0x0254) // OSF Coefficient 43 & 42 of Channel #0 0x0000_001B +#define S5P_SDO_OSFC22_0 S5P_SDAOUT_BASE(0x0258) // OSF Coefficient 45 & 44 of Channel #0 0x028B_0265 +#define S5P_SDO_OSFC23_0 S5P_SDAOUT_BASE(0x025C) // OSF Coefficient 47 & 46 of Channel #0 0x0400_0ECC +#define S5P_SDO_XTALK0 S5P_SDAOUT_BASE(0x0260) // Crosstalk Cancel Coefficient for Ch.0 0x0000_0000 +#define S5P_SDO_XTALK1 S5P_SDAOUT_BASE(0x0264) // Crosstalk Cancel Coefficient for Ch.1 0x0000_0000 +#define S5P_SDO_XTALK2 S5P_SDAOUT_BASE(0x0268) // Crosstalk Cancel Coefficient for Ch.2 0x0000_0000 +#define S5P_SDO_BB_CTRL S5P_SDAOUT_BASE(0x026C) // Blackburst Test Control 0x0001_1A00 +#define S5P_SDO_IRQ S5P_SDAOUT_BASE(0x0280) // Interrupt Request Register 0x0000_0000 +#define S5P_SDO_IRQMASK S5P_SDAOUT_BASE(0x0284) // Interrupt Request Enable Register 0x0000_0000 +#define S5P_SDO_OSFC00_1 S5P_SDAOUT_BASE(0x02C0) // OverSampling Filter (OSF) Coefficient 1 & 0. of Channel #1 0x00FD_00FE +#define S5P_SDO_OSFC01_1 S5P_SDAOUT_BASE(0x02C4) // OSF Coefficient 3 & 2 of Channel #1 0x0000_0000 +#define S5P_SDO_OSFC02_1 S5P_SDAOUT_BASE(0x02C8) // OSF Coefficient 5 & 4 of Channel #1 0x0005_0004 +#define S5P_SDO_OSFC03_1 S5P_SDAOUT_BASE(0x02CC) // OSF Coefficient 7 & 6 of Channel #1 0x0000_00FF +#define S5P_SDO_OSFC04_1 S5P_SDAOUT_BASE(0x02D0) // OSF Coefficient 9 & 8 of Channel #1 0x00F7_00FA +#define S5P_SDO_OSFC05_1 S5P_SDAOUT_BASE(0x02D4) // OSF Coefficient 11 & 10 of Channel #1 0x0000_0001 +#define S5P_SDO_OSFC06_1 S5P_SDAOUT_BASE(0x02D8) // OSF Coefficient 13 & 12 of Channel #1 0x000E_000A +#define S5P_SDO_OSFC07_1 S5P_SDAOUT_BASE(0x02DC) // OSF Coefficient 15 & 14 of Channel #1 0x0000_01FF +#define S5P_SDO_OSFC08_1 S5P_SDAOUT_BASE(0x02E0) // OSF Coefficient 17 & 16 of Channel #1 0x01EC_01F2 +#define S5P_SDO_OSFC09_1 S5P_SDAOUT_BASE(0x02E4) // OSF Coefficient 19 & 18 of Channel #1 0x0000_0001 +#define S5P_SDO_OSFC10_1 S5P_SDAOUT_BASE(0x02E8) // OSF Coefficient 21 & 20 of Channel #1 0x001D_0014 +#define S5P_SDO_OSFC11_1 S5P_SDAOUT_BASE(0x02EC) // OSF Coefficient 23 & 22 of Channel #1 0x0000_01FE +#define S5P_SDO_OSFC12_1 S5P_SDAOUT_BASE(0x02E0) // OSF Coefficient 25 & 24 of Channel #1 0x03D8_03E4 +#define S5P_SDO_OSFC13_1 S5P_SDAOUT_BASE(0x02F4) // OSF Coefficient 27 & 26 of Channel #1 0x0000_0002 +#define S5P_SDO_OSFC14_1 S5P_SDAOUT_BASE(0x02F8) // OSF Coefficient 29 & 28 of Channel #1 0x0038_0028 +#define S5P_SDO_OSFC15_1 S5P_SDAOUT_BASE(0x02FC) // OSF Coefficient 31 & 30 of Channel #1 0x0000_03FD +#define S5P_SDO_OSFC16_1 S5P_SDAOUT_BASE(0x0300) // OSF Coefficient 33 & 32 of Channel #1 0x03B0_03C7 +#define S5P_SDO_OSFC17_1 S5P_SDAOUT_BASE(0x0304) // OSF Coefficient 35 & 34 of Channel #1 0x0000_0005 +#define S5P_SDO_OSFC18_1 S5P_SDAOUT_BASE(0x0308) // OSF Coefficient 37 & 36 of Channel #1 0x0079_0056 +#define S5P_SDO_OSFC19_1 S5P_SDAOUT_BASE(0x030C) // OSF Coefficient 39 & 38 of Channel #1 0x0000_03F6 +#define S5P_SDO_OSFC20_1 S5P_SDAOUT_BASE(0x0310) // OSF Coefficient 41 & 40 of Channel #1 0x072C_0766 +#define S5P_SDO_OSFC21_1 S5P_SDAOUT_BASE(0x0314) // OSF Coefficient 43 & 42 of Channel #1 0x0000_001B +#define S5P_SDO_OSFC22_1 S5P_SDAOUT_BASE(0x0318) // OSF Coefficient 45 & 44 of Channel #1 0x028B_0265 +#define S5P_SDO_OSFC23_1 S5P_SDAOUT_BASE(0x031C) // OSF Coefficient 47 & 46 of Channel #1 0x0400_0ECC +#define S5P_SDO_OSFC00_2 S5P_SDAOUT_BASE(0x0320) // OverSampling Filter (OSF) Coefficient 1 & 0. of Channel #2 0x00FD_00FE +#define S5P_SDO_OSFC01_2 S5P_SDAOUT_BASE(0x0324) // OSF Coefficient 3 & 2 of Channel #2 0x0000_0000 +#define S5P_SDO_OSFC02_2 S5P_SDAOUT_BASE(0x0328) // OSF Coefficient 5 & 4 of Channel #2 0x0005_0004 +#define S5P_SDO_OSFC03_2 S5P_SDAOUT_BASE(0x032C) // OSF Coefficient 7 & 6 of Channel #2 0x0000_00FF +#define S5P_SDO_OSFC04_2 S5P_SDAOUT_BASE(0x0330) // OSF Coefficient 9 & 8 of Channel #2 0x00F7_00FA +#define S5P_SDO_OSFC05_2 S5P_SDAOUT_BASE(0x0334) // OSF Coefficient 11 & 10 of Channel #2 0x0000_0001 +#define S5P_SDO_OSFC06_2 S5P_SDAOUT_BASE(0x0338) // OSF Coefficient 13 & 12 of Channel #2 0x000E_000A +#define S5P_SDO_OSFC07_2 S5P_SDAOUT_BASE(0x033C) // OSF Coefficient 15 & 14 of Channel #2 0x0000_01FF +#define S5P_SDO_OSFC08_2 S5P_SDAOUT_BASE(0x0340) // OSF Coefficient 17 & 16 of Channel #2 0x01EC_01F2 +#define S5P_SDO_OSFC09_2 S5P_SDAOUT_BASE(0x0344) // OSF Coefficient 19 & 18 of Channel #2 0x0000_0001 +#define S5P_SDO_OSFC10_2 S5P_SDAOUT_BASE(0x0348) // OSF Coefficient 21 & 20 of Channel #2 0x001D_0014 +#define S5P_SDO_OSFC11_2 S5P_SDAOUT_BASE(0x034C) // OSF Coefficient 23 & 22 of Channel #2 0x0000_01FE +#define S5P_SDO_OSFC12_2 S5P_SDAOUT_BASE(0x0350) // OSF Coefficient 25 & 24 of Channel #2 0x03D8_03E4 +#define S5P_SDO_OSFC13_2 S5P_SDAOUT_BASE(0x0354) // OSF Coefficient 27 & 26 of Channel #2 0x0000_0002 +#define S5P_SDO_OSFC14_2 S5P_SDAOUT_BASE(0x0358) // OSF Coefficient 29 & 28 of Channel #2 0x0038_0028 +#define S5P_SDO_OSFC15_2 S5P_SDAOUT_BASE(0x035C) // OSF Coefficient 31 & 30 of Channel #2 0x0000_03FD +#define S5P_SDO_OSFC16_2 S5P_SDAOUT_BASE(0x0360) // OSF Coefficient 33 & 32 of Channel #2 0x03B0_03C7 +#define S5P_SDO_OSFC17_2 S5P_SDAOUT_BASE(0x0364) // OSF Coefficient 35 & 34 of Channel #2 0x0000_0005 +#define S5P_SDO_OSFC18_2 S5P_SDAOUT_BASE(0x0368) // OSF Coefficient 37 & 36 of Channel #2 0x0079_0056 +#define S5P_SDO_OSFC19_2 S5P_SDAOUT_BASE(0x036C) // OSF Coefficient 39 & 38 of Channel #2 0x0000_03F6 +#define S5P_SDO_OSFC20_2 S5P_SDAOUT_BASE(0x0370) // OSF Coefficient 41 & 40 of Channel #2 0x072C_0766 +#define S5P_SDO_OSFC21_2 S5P_SDAOUT_BASE(0x0374) // OSF Coefficient 43 & 42 of Channel #2 0x0000_001B +#define S5P_SDO_OSFC22_2 S5P_SDAOUT_BASE(0x0378) // OSF Coefficient 45 & 44 of Channel #2 0x028B_0265 +#define S5P_SDO_OSFC23_2 S5P_SDAOUT_BASE(0x037C) // OSF Coefficient 47 & 46 of Channel #2 0x0400_0ECC +#define S5P_SDO_ARMCC S5P_SDAOUT_BASE(0x03C0) // Closed Caption Data Register 0x0000_0000 +#define S5P_SDO_ARMWSS525 S5P_SDAOUT_BASE(0x03C4) // WSS 525 Data Register 0x0000_0000 +#define S5P_SDO_ARMWSS625 S5P_SDAOUT_BASE(0x03C8) // WSS 625 Data Register 0x0000_0000 +#define S5P_SDO_ARMCGMS525 S5P_SDAOUT_BASE(0x03CC) // CGMS-A 525 Data Register 0x0000_0000 +#define S5P_SDO_ARMCGMS625 S5P_SDAOUT_BASE(0x03D4) // CGMS-A 625 Data Register 0x0000_0000 +#define S5P_SDO_VERSION S5P_SDAOUT_BASE(0x03D8) // TVOUT Version Number Read Register 0x0000_000C +#define S5P_SDO_CC S5P_SDAOUT_BASE(0x0380) // Closed Caption Data Shadow register 0x0000_0000 +#define S5P_SDO_WSS525 S5P_SDAOUT_BASE(0x0384) // WSS 525 Data Shadow Register 0x0000_0000 +#define S5P_SDO_WSS625 S5P_SDAOUT_BASE(0x0388) // WSS 625 Data Shadow Register 0x0000_0000 +#define S5P_SDO_CGMS525 S5P_SDAOUT_BASE(0x038C) // CGMS-A 525 Data Shadow Register 0x0000_0000 +#define S5P_SDO_CGMS625 S5P_SDAOUT_BASE(0x0394) // CGMS-A 625 Data Shadow Register 0x0000_0000 + +/* + Shadow Registers +*/ + +/* + Registers Bit Description +*/ +/* + Macros +*/ +/* SDO_CLKCON */ +#define SDO_TVOUT_SW_RESET (1<<4) +#define SDO_TVOUT_CLK_DOWN_RDY (1<<1) +#define SDO_TVOUT_CLOCK_ON (1) +#define SDO_TVOUT_CLOCK_OFF (0) + +/* SDO_CONFIG */ +#define SDO_DAC2_Y_G (0<<20) +#define SDO_DAC2_PB_B (1<<20) +#define SDO_DAC2_PR_R (2<<20) +#define SDO_DAC1_Y_G (0<<18) +#define SDO_DAC1_PB_B (1<<18) +#define SDO_DAC1_PR_R (2<<18) +#define SDO_DAC0_Y_G (0<<16) +#define SDO_DAC0_PB_B (1<<16) +#define SDO_DAC0_PR_R (2<<16) +#define SDO_DAC2_CVBS (0<<12) +#define SDO_DAC2_Y (1<<12) +#define SDO_DAC2_C (2<<12) +#define SDO_DAC1_CVBS (0<<10) +#define SDO_DAC1_Y (1<<10) +#define SDO_DAC1_C (2<<10) +#define SDO_DAC0_CVBS (0<<8) +#define SDO_DAC0_Y (1<<8) +#define SDO_DAC0_C (2<<8) +#define SDO_COMPOSITE (0<<6) +#define SDO_COMPONENT (1<<6) +#define SDO_RGB (0<<5) +#define SDO_YPBPR (1<<5) +#define SDO_INTERLACED (0<<4) +#define SDO_PROGRESSIVE (1<<4) +#define SDO_NTSC_M (0) +#define SDO_PAL_M (1) +#define SDO_PAL_BGHID (2) +#define SDO_PAL_N (3) +#define SDO_PAL_NC (4) +#define SDO_NTSC_443 (8) +#define SDO_PAL_60 (9) + +/* SDO_SCALE */ +#define SDO_COMPONENT_LEVEL_SEL_0IRE (0<<3) +#define SDO_COMPONENT_LEVEL_SEL_75IRE (1<<3) +#define SDO_COMPONENT_VTOS_RATIO_10_4 (0<<2) +#define SDO_COMPONENT_VTOS_RATIO_7_3 (1<<2) +#define SDO_COMPOSITE_LEVEL_SEL_0IRE (0<<1) +#define SDO_COMPOSITE_LEVEL_SEL_75IRE (1<<1) +#define SDO_COMPOSITE_VTOS_RATIO_10_4 (0<<0) +#define SDO_COMPOSITE_VTOS_RATIO_7_3 (1<<0) + +/* SDO_SYNC */ +#define SDO_COMPONENT_SYNC_ABSENT (0) +#define SDO_COMPONENT_SYNC_YG (1) +#define SDO_COMPONENT_SYNC_ALL (3) + +/* SDO_VBI */ +#define SDO_CVBS_NO_WSS (0<<14) +#define SDO_CVBS_WSS_INS (1<<14) +#define SDO_CVBS_NO_CLOSED_CAPTION (0<<12) +#define SDO_CVBS_21H_CLOSED_CAPTION (1<<12) +#define SDO_CVBS_21H_284H_CLOSED_CAPTION (2<<12) +#define SDO_CVBS_USE_OTHERS (3<<12) +#define SDO_SVIDEO_NO_WSS (0<<10) +#define SDO_SVIDEO_WSS_INS (1<<10) +#define SDO_SVIDEO_NO_CLOSED_CAPTION (0<<8) +#define SDO_SVIDEO_21H_CLOSED_CAPTION (1<<8) +#define SDO_SVIDEO_21H_284H_CLOSED_CAPTION (2<<8) +#define SDO_SVIDEO_USE_OTHERS (3<<8) +#define SDO_RGB_NO_CGMSA (0<<7) +#define SDO_RGB_CGMSA_INS (1<<7) +#define SDO_RGB_NO_WSS (0<<6) +#define SDO_RGB_WSS_INS (1<<6) +#define SDO_RGB_NO_CLOSED_CAPTION (0<<4) +#define SDO_RGB_21H_CLOSED_CAPTION (1<<4) +#define SDO_RGB_21H_284H_CLOSED_CAPTION (2<<4) +#define SDO_RGB_USE_OTHERS (3<<4) +#define SDO_YPBPR_NO_CGMSA (0<<3) +#define SDO_YPBPR_CGMSA_INS (1<<3) +#define SDO_YPBPR_NO_WSS (0<<2) +#define SDO_YPBPR_WSS_INS (1<<2) +#define SDO_YPBPR_NO_CLOSED_CAPTION (0) +#define SDO_YPBPR_21H_CLOSED_CAPTION (1) +#define SDO_YPBPR_21H_284H_CLOSED_CAPTION (2) +#define SDO_YPBPR_USE_OTHERS (3) + +/* SDO_SCALE_CHx */ +#define SDO_SCALE_CONV_OFFSET(a) ((0x3ff&a)<<16) +#define SDO_SCALE_CONV_GAIN(a) (0xfff&a) + +/* SDO_YCDELAY */ +#define SDO_DELAY_YTOC(a) ((0xf&a)<<16) +#define SDO_ACTIVE_START_OFFSET(a) ((0xff&a)<<8) +#define SDO_ACTIVE_END_OFFSET(a) (0xff&a) + +/* SDO_SCHLOCK */ +#define SDO_COLOR_SC_PHASE_ADJ (1) +#define SDO_COLOR_SC_PHASE_NOADJ (0) + +/* SDO_DAC */ +#define SDO_POWER_ON_DAC2 (1<<2) +#define SDO_POWER_DOWN_DAC2 (0<<2) +#define SDO_POWER_ON_DAC1 (1<<1) +#define SDO_POWER_DOWN_DAC1 (0<<1) +#define SDO_POWER_ON_DAC0 (1<<0) +#define SDO_POWER_DOWN_DAC0 (0<<0) + +/* SDO_FINFO */ +#define SDO_FIELD_MOD_1001(a) (((0x3ff<<16)&a)>>16) +#define SDO_FIELD_ID_BOTTOM(a) ((1<<1)&a) +#define SDO_FIELD_ID_BOTTOM_PI_INCATION(a) (1) +/* SDO_Y0 */ +/* +#define SDO_AA_75_73_CB (0x251) +#define SDO_AA_75_104_CB (0x25d) +#define SDO_AA_75_73_CB (0x281) +#define SDO_AA_0_73_CB (0x28f) +#define SDO_AA_75_73_CR (0x1f3) +#define SDO_AA_75_104_CR (0x200) +#define SDO_AA_75_73_CR (0x21e) +#define SDO_AA_0_73_CR (0x228) +#define SDO_AA_75_73 (0x2c0) +#define SDO_AA_75_104 (0x2d1) +#define SDO_AA_75_73 (0x2c0) +#define SDO_AA_0_73 (0x30d) +*/ +/* SDO_MV_480P_PROTECTION_ON */ +#define SDO_MV_AGC_103_ON (1) + +/* SDO_CCCON */ +#define SDO_COMPONENT_BHS_ADJ_ON (0<<4) +#define SDO_COMPONENT_BHS_ADJ_OFF (1<<4) +#define SDO_COMPONENT_YPBPR_COMP_ON (0<<3) +#define SDO_COMPONENT_YPBPR_COMP_OFF (1<<3) +#define SDO_COMPONENT_RGB_COMP_ON (0<<2) +#define SDO_COMPONENT_RGB_COMP_OFF (1<<2) +#define SDO_COMPONENT_YC_COMP_ON (0<<1) +#define SDO_COMPONENT_YC_COMP_OFF (1<<1) +#define SDO_COMPONENT_CVBS_COMP_ON (0) +#define SDO_COMPONENT_CVBS_COMP_OFF (1) + +/* SDO_YSCALE */ +#define SDO_BRIGHTNESS_GAIN(a) ((0xff&a)<<16) +#define SDO_BRIGHTNESS_OFFSET(a) (0xff&a) + +/* SDO_CBSCALE */ +#define SDO_HS_CB_GAIN0(a) ((0x1ff&a)<<16) +#define SDO_HS_CB_GAIN1(a) (0x1ff&a) + +/* SDO_CRSCALE */ +#define SDO_HS_CR_GAIN0(a) ((0x1ff&a)<<16) +#define SDO_HS_CR_GAIN1(a) (0x1ff&a) + +/* SDO_CB_CR_OFFSET */ +#define SDO_HS_CR_OFFSET(a) ((0x3ff&a)<<16) +#define SDO_HS_CB_OFFSET(a) (0x3ff&a) + +/* SDO_RGB_CC */ +#define SDO_MAX_RGB_CUBE(a) ((0xff&a)<<8) +#define SDO_MIN_RGB_CUBE(a) (0xff&a) + +/* SDO_CVBS_CC_Y1 */ +#define SDO_Y_LOWER_MID_CVBS_CORN(a) ((0x3ff&a)<<16) +#define SDO_Y_BOTTOM_CVBS_CORN(a) (0x3ff&a) + +/* SDO_CVBS_CC_Y2 */ +#define SDO_Y_TOP_CVBS_CORN(a) ((0x3ff&a)<<16) +#define SDO_Y_UPPER_MID_CVBS_CORN(a) (0x3ff&a) + +/* SDO_CVBS_CC_C */ +#define SDO_RADIUS_CVBS_CORN(a) (0x1ff&a) + +/* SDO_YC_CC_Y */ +#define SDO_Y_TOP_YC_CYLINDER(a) ((0x3ff&a)<<16) +#define SDO_Y_BOTOM_YC_CYLINDER(a) (0x3ff&a) + +/* SDO_CVBS_CC_C */ +#define SDO_RADIUS_YC_CYLINDER(a) (0x1ff&a) + +/* SDO_CSC_525_PORCH */ +#define SDO_COMPONENT_525_BP(a) ((0x3ff&a)<<16) +#define SDO_COMPONENT_525_FP(a) (0x3ff&a) + +/* SDO_CSC_525_PORCH */ +#define SDO_COMPONENT_625_BP(a) ((0x3ff&a)<<16) +#define SDO_COMPONENT_625_FP(a) (0x3ff&a) + +/* SDO_RGBSYNC */ +#define SDO_RGB_SYNC_COMPOSITE (0<<8) +#define SDO_RGB_SYNC_SEPERATE (1<<8) +#define SDO_RGB_VSYNC_LOW_ACT (0<<4) +#define SDO_RGB_VSYNC_HIGH_ACT (1<<4) +#define SDO_RGB_HSYNC_LOW_ACT 0 +#define SDO_RGB_HSYNC_HIGH_ACT 1 + +/* SDO_OSFCxx_x */ +#define SDO_OSF_COEF_ODD(a) ((0xfff&a)<<16) +#define SDO_OSF_COEF_EVEN(a) (0xfff&a) + +/* SDO_XTALKx */ +#define SDO_XTALK_COEF02(a) ((0xff&a)<<16) +#define SDO_XTALK_COEF01(a) (0xff&a) + +/* SDO_BB_CTRL */ +#define SDO_REF_BB_LEVEL_NTSC (0x11a<<8) +#define SDO_REF_BB_LEVEL_PAL (0xfb<<8) +#define SDO_SEL_BB_CJAN_CVBS0_BB1_BB2 (0<<4) +#define SDO_SEL_BB_CJAN_BB0_CVBS1_BB2 (1<<4) +#define SDO_SEL_BB_CJAN_BB0_BB1_CVBS2 (2<<4) +#define SDO_BB_MODE_ENABLE (1) +#define SDO_BB_MODE_DISABLE (0) + +/* SDO_IRQ */ +#define SDO_VSYNC_IRQ_PEND (1) +#define SDO_VSYNC_NO_IRQ (0) + +/* SDO_IRQMASK */ +#define SDO_VSYNC_IRQ_ENABLE (0) +#define SDO_VSYNC_IRQ_DISABLE (1) + +/* SDO_ARMCC */ +#define SDO_DISPLAY_CC_CAPTION(a) ((0xff&a)<<16) +#define SDO_NON_DISPLAY_CC_CAPTION(a) (0xff&a) + +/* SDO_WSS525 */ +#define SDO_CRC_WSS525(a) ((0x3f&a)<<14) +#define SDO_WORD2_WSS525_COPY_PERMIT (0<<6) +#define SDO_WORD2_WSS525_ONECOPY_PERMIT (1<<6) +#define SDO_WORD2_WSS525_NOCOPY_PERMIT (3<<6) +#define SDO_WORD2_WSS525_MV_PSP_OFF (0<<8) +#define SDO_WORD2_WSS525_MV_PSP_ON_2LINE_BURST (1<<8) +#define SDO_WORD2_WSS525_MV_PSP_ON_BURST_OFF (2<<8) +#define SDO_WORD2_WSS525_MV_PSP_ON_4LINE_BURST (3<<8) +#define SDO_WORD2_WSS525_ANALOG_OFF (0<<10) +#define SDO_WORD2_WSS525_ANALOG_ON (1<<10) +#define SDO_WORD1_WSS525_COPY_INFO (0<<2) +#define SDO_WORD1_WSS525_DEFAULT (0xf<<2) +#define SDO_WORD0_WSS525_4_3_NORMAL (0) +#define SDO_WORD0_WSS525_16_9_ANAMORPIC (1) +#define SDO_WORD0_WSS525_4_3_LETTERBOX (2) + +/* SDO_WSS625 */ +#define SDO_WSS625_SURROUND_SOUND_DISABLE (0<<11) +#define SDO_WSS625_SURROUND_SOUND_ENABLE (1<<11) +#define SDO_WSS625_NO_COPYRIGHT (0<<12) +#define SDO_WSS625_COPYRIGHT (1<<12) +#define SDO_WSS625_COPY_NOT_RESTRICTED (0<<13) +#define SDO_WSS625_COPY_RESTRICTED (1<<13) +#define SDO_WSS625_TELETEXT_NO_SUBTITLES (0<<8) +#define SDO_WSS625_TELETEXT_SUBTITLES (1<<8) +#define SDO_WSS625_NO_OPEN_SUBTITLES (0<<9) +#define SDO_WSS625_INACT_OPEN_SUBTITLES (1<<9) +#define SDO_WSS625_OUTACT_OPEN_SUBTITLES (2<<9) +#define SDO_WSS625_CAMERA (0<<4) +#define SDO_WSS625_FILM (1<<4) +#define SDO_WSS625_NORMAL_PAL (0<<5) +#define SDO_WSS625_MOTION_ADAPTIVE_COLORPLUS (1<<5) +#define SDO_WSS625_HELPER_NO_SIG (0<<6) +#define SDO_WSS625_HELPER_SIG (1<<6) +#define SDO_WSS625_4_3_FULL_576 (0x8) +#define SDO_WSS625_14_9_LETTERBOX_CENTER_504 (0x1) +#define SDO_WSS625_14_9_LETTERBOX_TOP_504 (0x2) +#define SDO_WSS625_16_9_LETTERBOX_CENTER_430 (0xb) +#define SDO_WSS625_16_9_LETTERBOX_TOP_430 (0x4) +#define SDO_WSS625_16_9_LETTERBOX_CENTER (0xd) +#define SDO_WSS625_14_9_FULL_CENTER_576 (0xe) +#define SDO_WSS625_16_9_ANAMORPIC_576 (0x7) + +/* SDO_CGMS525 */ +#define SDO_CRC_CGMS525(a) ((0x3f&a)<<14) +#define SDO_WORD2_CGMS525_COPY_PERMIT (0<<6) +#define SDO_WORD2_CGMS525_ONECOPY_PERMIT (1<<6) +#define SDO_WORD2_CGMS525_NOCOPY_PERMIT (3<<6) +#define SDO_WORD2_CGMS525_MV_PSP_OFF (0<<8) +#define SDO_WORD2_CGMS525_MV_PSP_ON_2LINE_BURST (1<<8) +#define SDO_WORD2_CGMS525_MV_PSP_ON_BURST_OFF (2<<8) +#define SDO_WORD2_CGMS525_MV_PSP_ON_4LINE_BURST (3<<8) +#define SDO_WORD2_CGMS525_ANALOG_OFF (0<<10) +#define SDO_WORD2_CGMS525_ANALOG_ON (1<<10) +#define SDO_WORD1_CGMS525_COPY_INFO (0<<2) +#define SDO_WORD1_CGMS525_DEFAULT (0xf<<2) +#define SDO_WORD0_CGMS525_4_3_NORMAL (0) +#define SDO_WORD0_CGMS525_16_9_ANAMORPIC (1) +#define SDO_WORD0_CGMS525_4_3_LETTERBOX (2) + +/* SDO_CGMS625 */ +#define SDO_CGMS625_SURROUND_SOUND_DISABLE (0<<11) +#define SDO_CGMS625_SURROUND_SOUND_ENABLE (1<<11) +#define SDO_CGMS625_NO_COPYRIGHT (0<<12) +#define SDO_CGMS625_COPYRIGHT (1<<12) +#define SDO_CGMS625_COPY_NOT_RESTRICTED (0<<13) +#define SDO_CGMS625_COPY_RESTRICTED (1<<13) +#define SDO_CGMS625_TELETEXT_NO_SUBTITLES (0<<8) +#define SDO_CGMS625_TELETEXT_SUBTITLES (1<<8) +#define SDO_CGMS625_NO_OPEN_SUBTITLES (0<<9) +#define SDO_CGMS625_INACT_OPEN_SUBTITLES (1<<9) +#define SDO_CGMS625_OUTACT_OPEN_SUBTITLES (2<<9) +#define SDO_CGMS625_CAMERA (0<<4) +#define SDO_CGMS625_FILM (1<<4) +#define SDO_CGMS625_NORMAL_PAL (0<<5) +#define SDO_CGMS625_MOTION_ADAPTIVE_COLORPLUS (1<<5) +#define SDO_CGMS625_HELPER_NO_SIG (0<<6) +#define SDO_CGMS625_HELPER_SIG (1<<6) +#define SDO_CGMS625_4_3_FULL_576 (0x8) +#define SDO_CGMS625_14_9_LETTERBOX_CENTER_504 (0x1) +#define SDO_CGMS625_14_9_LETTERBOX_TOP_504 (0x2) +#define SDO_CGMS625_16_9_LETTERBOX_CENTER_430 (0xb) +#define SDO_CGMS625_16_9_LETTERBOX_TOP_430 (0x4) +#define SDO_CGMS625_16_9_LETTERBOX_CENTER (0xd) +#define SDO_CGMS625_14_9_FULL_CENTER_576 (0xe) +#define SDO_CGMS625_16_9_ANAMORPIC_576 (0x7) + +#endif /*__ASM_ARCH_REGS_SDAOUT_H */ diff --git a/drivers/media/video/samsung/tv20/s5pv210/regs/regs-vmx.h b/drivers/media/video/samsung/tv20/s5pv210/regs/regs-vmx.h new file mode 100644 index 0000000..24126cb --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5pv210/regs/regs-vmx.h @@ -0,0 +1,254 @@ +/* linux/drivers/media/video/samsung/tv20/s5pc100/regs/regs-vmx.h + * + * Mixer register header file for Samsung TVOut driver + * + * Copyright (c) 2010 Samsung Electronics + * http://www.samsung.com/ + * + * 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 <mach/map.h> + +#define S5P_MIXER_BASE(x) (x) +/* + Registers +*/ +#define S5P_MXR_STATUS S5P_MIXER_BASE(0x0000) //Status of MIXER Operation +#define S5P_MXR_CFG S5P_MIXER_BASE(0x0004) //MIXER Mode Setting +#define S5P_MXR_INT_EN S5P_MIXER_BASE(0x0008) //Interrupt Enable +#define S5P_MXR_INT_STATUS S5P_MIXER_BASE(0x000C) //Interrupt Status +#define S5P_MXR_LAYER_CFG S5P_MIXER_BASE(0x0010) //Video & Graphic Layer Priority and On// Off +#define S5P_MXR_VIDEO_CFG S5P_MIXER_BASE(0x0014) //Video Layer Configuration +#define S5P_MXR_GRAPHIC0_CFG S5P_MIXER_BASE(0x0020) //Graphic Layer0 Configuration +#define S5P_MXR_GRAPHIC0_BASE S5P_MIXER_BASE(0x0024) //Base Address for Graphic Layer0 +#define S5P_MXR_GRAPHIC0_SPAN S5P_MIXER_BASE(0x0028) //Span for Graphic Layer0 +#define S5P_MXR_GRAPHIC0_SXY S5P_MIXER_BASE(0x002C) //Source X//Y Positions for Graphic Layer0 +#define S5P_MXR_GRAPHIC0_WH S5P_MIXER_BASE(0x0030) //Width// Height for Graphic Layer0 +#define S5P_MXR_GRAPHIC0_DXY S5P_MIXER_BASE(0x0034) //Destination X//Y Positions for Graphic Layer0 +#define S5P_MXR_GRAPHIC0_BLANK S5P_MIXER_BASE(0x0038) //Blank Pixel Value for Graphic Layer0 +#define S5P_MXR_GRAPHIC1_CFG S5P_MIXER_BASE(0x0040) //Graphic Layer1 Configuration +#define S5P_MXR_GRAPHIC1_BASE S5P_MIXER_BASE(0x0044) //Base Address for Graphic Layer1 +#define S5P_MXR_GRAPHIC1_SPAN S5P_MIXER_BASE(0x0048) //Span for Graphic Layer1 +#define S5P_MXR_GRAPHIC1_SXY S5P_MIXER_BASE(0x004C) //Source X//Y Positions for Graphic Layer1 +#define S5P_MXR_GRAPHIC1_WH S5P_MIXER_BASE(0x0050) //Width// Height for Graphic Layer1 +#define S5P_MXR_GRAPHIC1_DXY S5P_MIXER_BASE(0x0054) //Destination X//Y Positions for Graphic Layer1 +#define S5P_MXR_GRAPHIC1_BLANK S5P_MIXER_BASE(0x0058) //Blank Pixel Value for Graphic Layer1 +#define S5P_MXR_BG_CFG S5P_MIXER_BASE(0x0060) +#define S5P_MXR_BG_COLOR0 S5P_MIXER_BASE(0x0064) //Background Color of First Point +#define S5P_MXR_BG_COLOR1 S5P_MIXER_BASE(0x0068) //Background Color of Second Point +#define S5P_MXR_BG_COLOR2 S5P_MIXER_BASE(0x006C) //Background Color of Last Point +#define S5P_MXR_CM_COEFF_Y S5P_MIXER_BASE(0x0080) //Scaled Color Space Conversion (RGB to Y) Coefficient for Graphic Layer +#define S5P_MXR_CM_COEFF_CB S5P_MIXER_BASE(0x0084) //Scaled Color Space Conversion (RGB to CB) Coefficient for Graphic Layer +#define S5P_MXR_CM_COEFF_CR S5P_MIXER_BASE(0x0088) //Scaled Color Space Conversion (RGB to Cr) Coefficient for Graphic Layer +#define S5P_MXR_VER S5P_MIXER_BASE(0x0100) //Mixer Version + +/* + Shadow Registers +*/ +#define S5P_MXR_STATUS_S S5P_MIXER_BASE(0x2000) //Status of MIXER Operation (Shadow) +#define S5P_MXR_CFG_S S5P_MIXER_BASE(0x2004) //MIXER Mode Setting (Shadow) +#define S5P_MXR_LAYER_CFG_S S5P_MIXER_BASE(0x2010) //Video & Graphic Layer Priority and On// Off (Shadow) +#define S5P_MXR_VIDEO_CFG_S S5P_MIXER_BASE(0x2014) //Video Layer Configuration (Shadow) +#define S5P_MXR_GRAPHIC0_CFG_S S5P_MIXER_BASE(0x2020) //Graphic Layer0 Configuration (Shadow) +#define S5P_MXR_GRAPHIC0_BASE_S S5P_MIXER_BASE(0x2024) //Graphic0 Base Address (Shadow) +#define S5P_MXR_GRAPHIC0_SPAN_S S5P_MIXER_BASE(0x2028) //Graphic0 Span (Shadow) +#define S5P_MXR_GRAPHIC0_SXY_S S5P_MIXER_BASE(0x202C) //Graphic0 Source X//Y Coordinates (Shadow) +#define S5P_MXR_GRAPHIC0_WH_S S5P_MIXER_BASE(0x2030) //Graphic0 Width// Height (Shadow) +#define S5P_MXR_GRAPHIC0_DXY_S S5P_MIXER_BASE(0x2034) //Graphic0 Destination X//Y Coordinates (Shadow) +#define S5P_MXR_GRAPHIC0_BLANK_PIXEL_S S5P_MIXER_BASE(0x2038) //Graphic0 Blank Pixel (Shadow) +#define S5P_MXR_GRAPHIC1_CFG_S S5P_MIXER_BASE(0x2040) //Graphic Layer1 Configuration (Shadow) +#define S5P_MXR_GRAPHIC1_BASE_S S5P_MIXER_BASE(0x2044) //Graphic1 Base Address (Shadow) +#define S5P_MXR_GRAPHIC1_SPAN_S S5P_MIXER_BASE(0x2048) //Graphic1 Span (Shadow) +#define S5P_MXR_GRAPHIC1_SXY_S S5P_MIXER_BASE(0x204C) //Graphic1 Source X//Y Coordinates (Shadow) +#define S5P_MXR_GRAPHIC1_WH_S S5P_MIXER_BASE(0x2050) //Graphic1 Width// Height (Shadow) +#define S5P_MXR_GRAPHIC1_DXY_S S5P_MIXER_BASE(0x2054) //Graphic1 Destination X//YCoordinates (Shadow) +#define S5P_MXR_GRAPHIC1_BLANK_PIXEL_S S5P_MIXER_BASE(0x2058) //Graphic1 Blank Pixel (Shadow) +#define S5P_MXR_BG_COLOR0_S S5P_MIXER_BASE(0x2064) //Background First Color (Shadow) +#define S5P_MXR_BG_COLOR1_S S5P_MIXER_BASE(0x2068) //Background Second Color (Shadow) +#define S5P_MXR_BG_COLOR2_S S5P_MIXER_BASE(0x206C) //Background Last Color (Shadow) + +/* + Registers Bit Description +*/ +/* S5P_MXR_STATUS */ +#define S5P_MXR_STATUS_RUN (1<<0) +#define S5P_MXR_STATUS_STOP (0<<0) +#define S5P_MXR_STATUS_SYNC_DISABLE (0<<2) +#define S5P_MXR_STATUS_SYNC_ENABLE (1<<2) +#define S5P_MXR_STATUS_LITTLE (0<<3) +#define S5P_MXR_STATUS_BIT (1<<3) +#define S5P_MXR_STATUS_8_BURST (0<<7) +#define S5P_MXR_STATUS_16_BURST (1<<7) + +/* S5P_MXR_CFG */ +#define S5P_MXR_CFG_SD (0<<0) +#define S5P_MXR_CFG_HD (1<<0) +#define S5P_MXR_CFG_NTSC (0<<1) +#define S5P_MXR_CFG_PAL (1<<1) +#define S5P_MXR_CFG_INTERLACE (0<<2) +#define S5P_MXR_CFG_PROGRASSIVE (1<<2) +#define S5P_MXR_CFG_VIDEO_DISABLE (0<<3) +#define S5P_MXR_CFG_VIDEO_ENABLE (1<<4) +#define S5P_MXR_CFG_GRAPHIC0_DISABLE (0<<4) +#define S5P_MXR_CFG_GRAPHIC0_ENABLE (1<<4) +#define S5P_MXR_CFG_GRAPHIC1_DISABLE (0<<5) +#define S5P_MXR_CFG_GRAPHIC1_ENABLE (1<<5) +#define S5P_MXR_CFG_HD_720P (0<<6) +#define S5P_MXR_CFG_HD_1080I (1<<6) +#define S5P_MXR_CFG_TV_OUT (0<<7) +#define S5P_MXR_CFG_HDMI_OUT (1<<7) + +/* S5P_MXR_INT_EN */ +#define S5P_MXR_INT_EN_GRP0_DISABLE (0<<8) +#define S5P_MXR_INT_EN_GRP0_ENABLE (1<<8) +#define S5P_MXR_INT_EN_GRP1_DISABLE (0<<9) +#define S5P_MXR_INT_EN_GRP1_ENABLE (1<<9) +#define S5P_MXR_INT_EN_VP_DISABLE (0<<10) +#define S5P_MXR_INT_EN_VP_ENABLE (1<<10) + +/* S5P_MXR_INT_STATUS */ +#define S5P_MXR_STATUS_EN_GRP0_N_FIRED (0<<8) +#define S5P_MXR_STATUS_EN_GRP0_FIRED (1<<8) +#define S5P_MXR_STATUS_EN_GRP1_N_FIRED (0<<9) +#define S5P_MXR_STATUS_EN_GRP1_FIRED (1<<9) +#define S5P_MXR_STATUS_EN_VP_N_FIRED (0<<10) +#define S5P_MXR_STATUS_EN_VP_FIRED (1<<10) + +/* S5P_MXR_LAYER_CFG */ +#define S5P_MXR_LAYER_CFG_VP_HIDE (0<<0) +#define S5P_MXR_LAYER_CFG_GRP0_HIDE (0<<4) +#define S5P_MXR_LAYER_CFG_GRP1_HIDE (0<<8) + +/* S5P_MXR_VIDEO_CFG */ +#define S5P_MXR_VIDEO_CFG_BLEND_EN (1<<16) + +/* Macros */ +/* MIXER_STATUS */ +#define S5P_MXR_BURST16_MODE (1<<7) +#define S5P_MXR_BURST8_MODE (0<<7) +#define S5P_MXR_BIG_ENDIAN_SOURCE_FORMAT (1<<3) +#define S5P_MXR_LITTLE_ENDIAN_SOURCE_FORMAT (0<<3) +#define S5P_MXR_MIXER_RESERVED (1<<2) +#define S5P_MXR_CMU_STOP_CLOCK (1<<1) +#define S5P_MXR_CMU_CANNOT_STOP_CLOCK (0<<1) +#define S5P_MXR_MIXER_START (1<<0) +#define S5P_MXR_MIXER_STOP (0<<0) + +/* MIXER_CFG */ +#define S5P_MXR_DST_SEL_HDMI (1<<7) +#define S5P_MXR_DST_SEL_ANALOG ~(1<<7) +#define S5P_MXR_HD_1080I_MODE (1<<6) +/* C110 */ +#define S5P_MXR_HD_1080P_MODE S5P_MXR_HD_1080I_MODE + +#define S5P_MXR_HD_720P_MODE (0<<6) +#define S5P_MXR_GRAPHIC1_LAYER_SHOW (1<<5) +#define S5P_MXR_GRAPHIC1_LAYER_HIDE (0<<5) +#define S5P_MXR_GRAPHIC0_LAYER_SHOW (1<<4) +#define S5P_MXR_GRAPHIC0_LAYER_HIDE (0<<4) +#define S5P_MXR_VIDEO_LAYER_SHOW (1<<3) +#define S5P_MXR_VIDEO_LAYER_HIDE (0<<3) +#define S5P_MXR_PROGRESSVE_MODE (1<<2) +#define S5P_MXR_INTERLACE_MODE ~(1<<2) +#define S5P_MXR_PAL (1<<1) +#define S5P_MXR_NTSC (0<<1) +#define S5P_MXR_HD (1<<0) +#define S5P_MXR_SD (0<<0) + +/* MIXER_INT_EN */ +#define S5P_MXR_VP_INT_ENABLE (1<<10) +#define S5P_MXR_VP_INT_DISABLE (0<<10) +#define S5P_MXR_GRP1_INT_ENABLE (1<<9) +#define S5P_MXR_GRP1_INT_DISABLE (0<<9) +#define S5P_MXR_GRP0_INT_ENABLE (1<<8) +#define S5P_MXR_GRP0_INT_DISABLE (0<<8) + +/* MIXER_INT_STATUS */ +#define S5P_MXR_VP_INT_FIRED (1<<10) +#define S5P_MXR_GRP1_INT_FIRED (1<<9) +#define S5P_MXR_GRP0_INT_FIRED (1<<8) +#define S5P_MXR_INT_FIRED (1<<0) + +#define S5P_MXR_ALPHA (0xff) + +/* MIXER_LAYER_CFG */ +#define S5P_MXR_GRP1_LAYER_PRIORITY(a) ((0xf&a)<<8) +#define S5P_MXR_GRP0_LAYER_PRIORITY(a) ((0xf&a)<<4) +#define S5P_MXR_VP_LAYER_PRIORITY(a) ((0xf&a)<<0) +#define S5P_MXR_GRP1_LAYER_PRIORITY_CLEAR(a) ((~(0xf<<8))&a) +#define S5P_MXR_GRP0_LAYER_PRIORITY_CLEAR(a) ((~(0xf<<4))&a) +#define S5P_MXR_VP_LAYER_PRIORITY_CLEAR(a) ((~(0xf<<0))&a) +#define S5P_MXR_GRP1_LAYER_PRIORITY_INFO(a) ((0xf<<8)&a) +#define S5P_MXR_GRP0_LAYER_PRIORITY_INFO(a) ((0xf<<4)&a) +#define S5P_MXR_VP_LAYER_PRIORITY_INFO(a) ((0xf<<0)&a) + +/* MIXER_VIDEO_CFG */ +#define S5P_MXR_VP_BLEND_ENABLE (1<<16) +#define S5P_MXR_VP_BLEND_DISABLE (0<<16) +#define S5P_MXR_VP_ALPHA_VALUE(a) ((0xff&a)<<0) +#define S5P_MXR_VP_ALPHA_VALUE_CLEAR(a) ((~(0xff<<0))&a) + +/* MIXER_GRAPHx_CFG */ +#define S5P_MXR_BLANK_CHANGE_NEW_PIXEL (1<<21) +#define S5P_MXR_BLANK_NOT_CHANGE_NEW_PIXEL (0<<21) +#define S5P_MXR_PRE_MUL_MODE (1<<20) +#define S5P_MXR_NORMAL_MODE (0<<20) +#define S5P_MXR_WIN_BLEND_ENABLE (1<<17) +#define S5P_MXR_WIN_BLEND_DISABLE (0<<17) +#define S5P_MXR_PIXEL_BLEND_ENABLE (1<<16) +#define S5P_MXR_PIXEL_BLEND_DISABLE (0<<16) +#define S5P_MXR_EG_COLOR_FORMAT(a) ((0xf&a)<<8) +#define S5P_MXR_EG_COLOR_FORMAT_CLEAR(a) ((~(0xf<<8))&a) +#define S5P_MXR_GRP_ALPHA_VALUE(a) ((0xff&a)<<0) +#define S5P_MXR_GRP_ALPHA_VALUE_CLEAR(a) ((~(0xff<<0))&a) +/* +enum s5p_tv_vmx_color_fmt +{ + S5P_MXR_DIRECT_RGB565 = 4, + S5P_MXR_DIRECT_RGB1555 = 5, + S5P_MXR_DIRECT_RGB4444 = 6, + S5P_MXR_DIRECT_RGB8888 = 7 +} +*/ + +/* MIXER_GRAPHx_BASE */ +#define S5P_MXR_GPR_BASE(a) (0xffffffff&a) +#define S5P_MXR_GRP_ADDR_ILLEGAL(a) (0x3&a) + +/* MIXER_GRAPH1_SPAN */ +#define S5P_MXR_GRP_SPAN(a) (0x7fff&a) + +/* MIXER_GRAPH1_WH */ +#define S5P_MXR_GRP_WIDTH(a) ((0x7ff&a)<<16) +#define S5P_MXR_GRP_HEIGHT(a) ((0x7ff&a)<<0) + +/* MIXER_GRAPH1_SXY */ +#define S5P_MXR_GRP_STARTX(a) ((0x7ff&a)<<16) +#define S5P_MXR_GRP_STARTY(a) ((0x7ff&a)<<0) + +/* MIXER_GRAPH1_DXY */ +#define S5P_MXR_GRP_DESTX(a) ((0x7ff&a)<<16) +#define S5P_MXR_GRP_DESTY(a) ((0x7ff&a)<<0) + +/* MIXER_GRAPH1_BLANK */ +#define S5P_MXR_GPR_BLANK_COLOR(a) (0xffffffff&a) + +/* MIXER_BG_CFG */ +#define S5P_MXR_BG_CR_DIHER_EN (1<<19) +#define S5P_MXR_BG_CB_DIHER_EN (1<<18) +#define S5P_MXR_BG_Y_DIHER_EN (1<<17) + +/* MIXER_BG_COLORx */ +#define S5P_MXR_BG_COLOR_Y(a) ((0xff&a)<<16) +#define S5P_MXR_BG_COLOR_CB(a) ((0xff&a)<<8) +#define S5P_MXR_BG_COLOR_CR(a) ((0xff&a)<<0) + +/* MIXER_CM_COEFF_x */ +#define S5P_MXR_BG_COLOR_WIDE (1<<30) +#define S5P_MXR_BG_COLOR_NARROW (0<<30) +#define S5P_MXR_BG_COEFF_0(a) ((0x3f&a)<<20) +#define S5P_MXR_BG_COEFF_1(a) ((0x3f&a)<<10) +#define S5P_MXR_BG_COEFF_2(a) ((0x3f&a)<<0) + diff --git a/drivers/media/video/samsung/tv20/s5pv210/regs/regs-vprocessor.h b/drivers/media/video/samsung/tv20/s5pv210/regs/regs-vprocessor.h new file mode 100644 index 0000000..a450018 --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5pv210/regs/regs-vprocessor.h @@ -0,0 +1,447 @@ +/* linux/drivers/media/video/samsung/tv20/s5pc100/regs/regs-vprocessor.h + * + * Video Processor register header file for Samsung TVOut driver + * + * Copyright (c) 2010 Samsung Electronics + * http://www.samsung.com/ + * + * 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. +*/ + +#ifndef __ASM_ARCH_REGS_VPROCESSOR_H + +#include <mach/map.h> + +#define S5P_VPROCESSOR_BASE(x) (x) +/* + Registers +*/ +#define S5P_VP_ENABLE S5P_VPROCESSOR_BASE(0x0000) // Power-Down Ready & Enable +#define S5P_VP_SRESET S5P_VPROCESSOR_BASE(0x0004) // Software Reset +#define S5P_VP_SHADOW_UPDATE S5P_VPROCESSOR_BASE(0x0008) // Shadow Register Update Enable +#define S5P_VP_FIELD_ID S5P_VPROCESSOR_BASE(0x000C) // Field ID of the "Source" Image +#define S5P_VP_MODE S5P_VPROCESSOR_BASE(0x0010) // VP Operation Mode +#define S5P_VP_IMG_SIZE_Y S5P_VPROCESSOR_BASE(0x0014) // Luminance Date Size +#define S5P_VP_IMG_SIZE_C S5P_VPROCESSOR_BASE(0x0018) // Chrominance Date Size +#define S5P_VP_PER_RATE_CTRL S5P_VPROCESSOR_BASE(0x001C) +#define S5P_VP_TOP_Y_PTR S5P_VPROCESSOR_BASE(0x0028) // Base Address for Y of Top Field (Frame) +#define S5P_VP_BOT_Y_PTR S5P_VPROCESSOR_BASE(0x002C) // Base Address for Y of Bottom Field +#define S5P_VP_TOP_C_PTR S5P_VPROCESSOR_BASE(0x0030) // Base Address for C of Top +#define S5P_VP_BOT_C_PTR S5P_VPROCESSOR_BASE(0x0034) // Base Address for C of Bottom Field +#define S5P_VP_ENDIAN_MODE S5P_VPROCESSOR_BASE(0x03CC) // Big/Little Endian Mode Selection +#define S5P_VP_SRC_H_POSITION S5P_VPROCESSOR_BASE(0x0044) // Horizontal Offset in the Source Image +#define S5P_VP_SRC_V_POSITION S5P_VPROCESSOR_BASE(0x0048) // Vertical Offset in the Source Image +#define S5P_VP_SRC_WIDTH S5P_VPROCESSOR_BASE(0x004C) // Width of the Source Image +#define S5P_VP_SRC_HEIGHT S5P_VPROCESSOR_BASE(0x0050) // Height of the Source Image +#define S5P_VP_DST_H_POSITION S5P_VPROCESSOR_BASE(0x0054) // Horizontal Offset in the Display +#define S5P_VP_DST_V_POSITION S5P_VPROCESSOR_BASE(0x0058) // Vertical Offset in the Display +#define S5P_VP_DST_WIDTH S5P_VPROCESSOR_BASE(0x005C) // Width of the Display +#define S5P_VP_DST_HEIGHT S5P_VPROCESSOR_BASE(0x0060) // Height of the Display +#define S5P_VP_H_RATIO S5P_VPROCESSOR_BASE(0x0064) // Horizontal Zoom Ratio of SRC:DST +#define S5P_VP_V_RATIO S5P_VPROCESSOR_BASE(0x0068) // Vertical Zoom Ratio of SRC:DST +#define S5P_VP_POLY8_Y0_LL S5P_VPROCESSOR_BASE(0x006C) // 8-Tap Poly-phase Filter Coefficients for Luminance Horizontal Scaling +#define S5P_VP_POLY8_Y0_LH S5P_VPROCESSOR_BASE(0x0070) // 8-Tap Poly-phase Filter Coefficients for Luminance Horizontal Scaling +#define S5P_VP_POLY8_Y0_HL S5P_VPROCESSOR_BASE(0x0074) // 8-Tap Poly-phase Filter Coefficients for Luminance Horizontal Scaling +#define S5P_VP_POLY8_Y0_HH S5P_VPROCESSOR_BASE(0x0078) // 8-Tap Poly-phase Filter Coefficients for Luminance Horizontal Scaling +#define S5P_VP_POLY8_Y1_LL S5P_VPROCESSOR_BASE(0x007C) // 8-Tap Poly-phase Filter Coefficients for Luminance Horizontal Scaling +#define S5P_VP_POLY8_Y1_LH S5P_VPROCESSOR_BASE(0x0080) // 8-Tap Poly-phase Filter Coefficients for Luminance Horizontal Scaling +#define S5P_VP_POLY8_Y1_HL S5P_VPROCESSOR_BASE(0x0084) // 8-Tap Poly-phase Filter Coefficients for Luminance Horizontal Scaling +#define S5P_VP_POLY8_Y1_HH S5P_VPROCESSOR_BASE(0x0088) // 8-Tap Poly-phase Filter Coefficients for Luminance Horizontal Scaling +#define S5P_VP_POLY8_Y2_LL S5P_VPROCESSOR_BASE(0x008C) // 8-Tap Poly-phase Filter Coefficients for Luminance Horizontal Scaling +#define S5P_VP_POLY8_Y2_LH S5P_VPROCESSOR_BASE(0x0090) // 8-Tap Poly-phase Filter Coefficients for Luminance Horizontal Scaling +#define S5P_VP_POLY8_Y2_HL S5P_VPROCESSOR_BASE(0x0094) // 8-Tap Poly-phase Filter Coefficients for Luminance Horizontal Scaling +#define S5P_VP_POLY8_Y2_HH S5P_VPROCESSOR_BASE(0x0098) // 8-Tap Poly-phase Filter Coefficients for Luminance Horizontal Scaling +#define S5P_VP_POLY8_Y3_LL S5P_VPROCESSOR_BASE(0x009C) // 8-Tap Poly-phase Filter Coefficients for Luminance Horizontal Scaling +#define S5P_VP_POLY8_Y3_LH S5P_VPROCESSOR_BASE(0x00A0) // 8-Tap Poly-phase Filter Coefficients for Luminance Horizontal Scaling +#define S5P_VP_POLY8_Y3_HL S5P_VPROCESSOR_BASE(0x00A4) // 8-Tap Poly-phase Filter Coefficients for Luminance Horizontal Scaling +#define S5P_VP_POLY8_Y3_HH S5P_VPROCESSOR_BASE(0x00A8) // 8-Tap Poly-phase Filter Coefficients for Luminance Horizontal Scaling +#define S5P_VP_POLY4_Y0_LL S5P_VPROCESSOR_BASE(0x00EC) // 4-Tap Poly-phase Filter Coefficients for Luminance Horizontal Scaling +#define S5P_VP_POLY4_Y0_LH S5P_VPROCESSOR_BASE(0x00F0) // 4-Tap Poly-phase Filter Coefficients for Luminance Vertical Scaling +#define S5P_VP_POLY4_Y0_HL S5P_VPROCESSOR_BASE(0x00F4) // 4-Tap Poly-phase Filter Coefficients for Luminance Vertical Scaling +#define S5P_VP_POLY4_Y0_HH S5P_VPROCESSOR_BASE(0x00F8) // 4-Tap Poly-phase Filter Coefficients for Luminance Vertical Scaling +#define S5P_VP_POLY4_Y1_LL S5P_VPROCESSOR_BASE(0x00FC) // 4-Tap Poly-phase Filter Coefficients for Luminance Vertical Scaling +#define S5P_VP_POLY4_Y1_LH S5P_VPROCESSOR_BASE(0x0100) // 4-Tap Poly-phase Filter Coefficients for Luminance Vertical Scaling +#define S5P_VP_POLY4_Y1_HL S5P_VPROCESSOR_BASE(0x0104) // 4-Tap Poly-phase Filter Coefficients for Luminance Vertical Scaling +#define S5P_VP_POLY4_Y1_HH S5P_VPROCESSOR_BASE(0x0108) // 4-Tap Poly-phase Filter Coefficients for Luminance Vertical Scaling +#define S5P_VP_POLY4_Y2_LL S5P_VPROCESSOR_BASE(0x010C) // 4-Tap Poly-phase Filter Coefficients for Luminance Vertical Scaling +#define S5P_VP_POLY4_Y2_LH S5P_VPROCESSOR_BASE(0x0110) // 4-Tap Poly-phase Filter Coefficients for Luminance Vertical Scaling +#define S5P_VP_POLY4_Y2_HL S5P_VPROCESSOR_BASE(0x0114) // 4-Tap Poly-phase Filter Coefficients for Luminance Vertical Scaling +#define S5P_VP_POLY4_Y2_HH S5P_VPROCESSOR_BASE(0x0118) // 4-Tap Poly-phase Filter Coefficients for Luminance Vertical Scaling +#define S5P_VP_POLY4_Y3_LL S5P_VPROCESSOR_BASE(0x011C) // 4-Tap Poly-phase Filter Coefficients for Luminance Vertical Scaling +#define S5P_VP_POLY4_Y3_LH S5P_VPROCESSOR_BASE(0x0120) // 4-Tap Poly-phase Filter Coefficients for Luminance Vertical Scaling +#define S5P_VP_POLY4_Y3_HL S5P_VPROCESSOR_BASE(0x0124) // 4-Tap Poly-phase Filter Coefficients for Luminance Vertical Scaling +#define S5P_VP_POLY4_Y3_HH S5P_VPROCESSOR_BASE(0x0128) // 4-Tap Poly-phase Filter Coefficients for Luminance Vertical Scaling +#define S5P_VP_POLY4_C0_LL S5P_VPROCESSOR_BASE(0x012C) // 4-Tap Poly-phase Filter Coefficients for Luminance Vertical Scaling +#define S5P_VP_POLY4_C0_LH S5P_VPROCESSOR_BASE(0x0130) // 4-Tap Poly-phase Filter Coefficients for Chrominance Horizontal Scaling +#define S5P_VP_POLY4_C0_HL S5P_VPROCESSOR_BASE(0x0134) // 4-Tap Poly-phase Filter Coefficients for Chrominance Horizontal Scaling +#define S5P_VP_POLY4_C0_HH S5P_VPROCESSOR_BASE(0x0138) // 4-Tap Poly-phase Filter Coefficients for Chrominance Horizontal Scaling +#define S5P_VP_POLY4_C1_LL S5P_VPROCESSOR_BASE(0x013C) // 4-Tap Poly-phase Filter Coefficients for Chrominance Horizontal Scaling +#define S5P_VP_POLY4_C1_LH S5P_VPROCESSOR_BASE(0x0140) // 4-Tap Poly-phase Filter Coefficients for Chrominance Horizontal Scaling +#define S5P_VP_POLY4_C1_HL S5P_VPROCESSOR_BASE(0x0144) // 4-Tap Poly-phase Filter Coefficients for Chrominance Horizontal Scaling +#define S5P_VP_POLY4_C1_HH S5P_VPROCESSOR_BASE(0x0148) // 4-Tap Poly-phase Filter Coefficients for Chrominance Horizontal Scaling +#define S5P_PP_CSC_Y2Y_COEF S5P_VPROCESSOR_BASE(0x01D4) // Y to Y CSC Coefficient Setting +#define S5P_PP_CSC_CB2Y_COEF S5P_VPROCESSOR_BASE(0x01D8) // CB to Y CSC Coefficient Setting +#define S5P_PP_CSC_CR2Y_COEF S5P_VPROCESSOR_BASE(0x01DC) // CR to Y CSC Coefficient Setting +#define S5P_PP_CSC_Y2CB_COEF S5P_VPROCESSOR_BASE(0x01E0) // Y to Y CSC Coefficient Setting +#define S5P_PP_CSC_CB2CB_COEF S5P_VPROCESSOR_BASE(0x01E4) // CB to Y CSC Coefficient Setting +#define S5P_PP_CSC_CR2CB_COEF S5P_VPROCESSOR_BASE(0x01E8) // CR to Y CSC Coefficient Setting +#define S5P_PP_CSC_Y2CR_COEF S5P_VPROCESSOR_BASE(0x01EC) // Y to Y CSC Coefficient Setting +#define S5P_PP_CSC_CB2CR_COEF S5P_VPROCESSOR_BASE(0x01F0) // CB to Y CSC Coefficient Setting +#define S5P_PP_CSC_CR2CR_COEF S5P_VPROCESSOR_BASE(0x01F4) // CR to Y CSC Coefficient Setting +#define S5P_PP_BYPASS S5P_VPROCESSOR_BASE(0x0200) // Disable the Post Image Processor +#define S5P_PP_SATURATION S5P_VPROCESSOR_BASE(0x020C) // Color Saturation Factor +#define S5P_PP_SHARPNESS S5P_VPROCESSOR_BASE(0x0210) // Control for the Edge Enhancement +#define S5P_PP_LINE_EQ0 S5P_VPROCESSOR_BASE(0x0218) // Line Equation for Contrast Duration "0" +#define S5P_PP_LINE_EQ1 S5P_VPROCESSOR_BASE(0x021C) // Line Equation for Contrast Duration "1" +#define S5P_PP_LINE_EQ2 S5P_VPROCESSOR_BASE(0x0220) // Line Equation for Contrast Duration "2" +#define S5P_PP_LINE_EQ3 S5P_VPROCESSOR_BASE(0x0224) // Line Equation for Contrast Duration "3" +#define S5P_PP_LINE_EQ4 S5P_VPROCESSOR_BASE(0x0228) // Line Equation for Contrast Duration "4" +#define S5P_PP_LINE_EQ5 S5P_VPROCESSOR_BASE(0x022C) // Line Equation for Contrast Duration "5" +#define S5P_PP_LINE_EQ6 S5P_VPROCESSOR_BASE(0x0230) // Line Equation for Contrast Duration "6" +#define S5P_PP_LINE_EQ7 S5P_VPROCESSOR_BASE(0x0234) // Line Equation for Contrast Duration "7" +#define S5P_PP_BRIGHT_OFFSET S5P_VPROCESSOR_BASE(0x0238) // Brightness Offset Control for Y +#define S5P_PP_CSC_EN S5P_VPROCESSOR_BASE(0x023C) // Color Space Conversion Control +#define S5P_VP_VERSION_INFO S5P_VPROCESSOR_BASE(0x03FC) // VP Version Information + +/* + Shadow Registers +*/ +#define S5P_VP_FIELD_ID_S S5P_VPROCESSOR_BASE(0x016C) // Field ID of the "Source" Image +#define S5P_VP_MODE_S S5P_VPROCESSOR_BASE(0x0170) // VP Operation Mode +#define S5P_VP_IMG_SIZE_Y_S S5P_VPROCESSOR_BASE(0x0174) // Luminance Date Tiled Size +#define S5P_VP_IMG_SIZE_C_S S5P_VPROCESSOR_BASE(0x0178) // Chrominance Date Tiled Size +#define S5P_VP_TOP_Y_PTR_S S5P_VPROCESSOR_BASE(0x0190) // Base Address for Y of Top Field +#define S5P_VP_BOT_Y_PTR_S S5P_VPROCESSOR_BASE(0x0194) // Base Address for Y of Bottom Field +#define S5P_VP_TOP_C_PTR_S S5P_VPROCESSOR_BASE(0x0198) // Base Address for C of Top Frame +#define S5P_VP_BOT_C_PTR_S S5P_VPROCESSOR_BASE(0x019C) // Base Address for C of Bottom field +#define S5P_VP_ENDIAN_MODE_S S5P_VPROCESSOR_BASE(0x03EC) // Big/ Little Endian Mode Selection +#define S5P_VP_SRC_H_POSITION_S S5P_VPROCESSOR_BASE(0x01AC) // Horizontal Offset in the Source Image +#define S5P_VP_SRC_V_POSITION_S S5P_VPROCESSOR_BASE(0x01B0) // Vertical Offset in the Source Image +#define S5P_VP_SRC_WIDTH_S S5P_VPROCESSOR_BASE(0x01B4) // Width of the Source Image +#define S5P_VP_SRC_HEIGHT_S S5P_VPROCESSOR_BASE(0x01B8) // Height of the Source Image +#define S5P_VP_DST_H_POSITION_S S5P_VPROCESSOR_BASE(0x01BC) // Horizontal Offset in the Display +#define S5P_VP_DST_V_POSITION_S S5P_VPROCESSOR_BASE(0x01C0) // Vertical Offset in the Display +#define S5P_VP_DST_WIDTH_S S5P_VPROCESSOR_BASE(0x01C4) // Width of the Display +#define S5P_VP_DST_HEIGHT_S S5P_VPROCESSOR_BASE(0x01C8) // Height of the Display +#define S5P_VP_H_RATIO_S S5P_VPROCESSOR_BASE(0x01CC) // Horizontal Zoom Ratio of SRC:DST +#define S5P_VP_V_RATIO_S S5P_VPROCESSOR_BASE(0x01D0) // Vertical Zoom Ratio of SRC:DST +#define S5P_PP_BYPASS_S S5P_VPROCESSOR_BASE(0x0258) // Disable the Post Image Processor +#define S5P_PP_SATURATION_S S5P_VPROCESSOR_BASE(0x025C) // Color Saturation Factor +#define S5P_PP_SHARPNESS_S S5P_VPROCESSOR_BASE(0x0260) // Control for the Edge Enhancement +#define S5P_PP_LINE_EQ0_S S5P_VPROCESSOR_BASE(0x0268) // Line Equation for Contrast Duration "0" +#define S5P_PP_LINE_EQ1_S S5P_VPROCESSOR_BASE(0x026C) // Line Equation for Contrast Duration "1" +#define S5P_PP_LINE_EQ2_S S5P_VPROCESSOR_BASE(0x0270) // Line Equation for Contrast Duration "2" +#define S5P_PP_LINE_EQ3_S S5P_VPROCESSOR_BASE(0x0274) // Line Equation for Contrast Duration "3" +#define S5P_PP_LINE_EQ4_S S5P_VPROCESSOR_BASE(0x0278) // Line Equation for Contrast Duration "4" +#define S5P_PP_LINE_EQ5_S S5P_VPROCESSOR_BASE(0x027C) // Line Equation for Contrast Duration "5" +#define S5P_PP_LINE_EQ6_S S5P_VPROCESSOR_BASE(0x0280) // Line Equation for Contrast Duration "6" +#define S5P_PP_LINE_EQ7_S S5P_VPROCESSOR_BASE(0x0284) // Line Equation for Contrast Duration "7" +#define S5P_PP_BRIGHT_OFFSET_S S5P_VPROCESSOR_BASE(0x0288) // Brightness Offset Control for Y +#define S5P_PP_CSC_EN_S S5P_VPROCESSOR_BASE(0x028C) // Color Space Conversion Control +#define S5P_PP_CSC_Y2Y_COEF_S S5P_VPROCESSOR_BASE(0x0290) // Y to Y CSC Coefficient Setting +#define S5P_PP_CSC_CB2Y_COEF_S S5P_VPROCESSOR_BASE(0x0294) // CB to Y CSC Coefficient Setting +#define S5P_PP_CSC_CR2Y_COEF_S S5P_VPROCESSOR_BASE(0x0298) // CR to Y CSC Coefficient Setting +#define S5P_PP_CSC_Y2CB_COEF_S S5P_VPROCESSOR_BASE(0x029C) // Y to Y CSC Coefficient Setting +#define S5P_PP_CSC_CB2CB_COEF_S S5P_VPROCESSOR_BASE(0x02A0) // CB to Y CSC Coefficient Setting +#define S5P_PP_CSC_CR2CB_COEF_S S5P_VPROCESSOR_BASE(0x02A4) // CR to Y CSC Coefficient Setting +#define S5P_PP_CSC_Y2CR_COEF_S S5P_VPROCESSOR_BASE(0x02A8) // Y to Y CSC Coefficient Setting +#define S5P_PP_CSC_CB2CR_COEF_S S5P_VPROCESSOR_BASE(0x02AC) // CB to Y CSC Coefficient Setting +#define S5P_PP_CSC_CR2CR_COEF_S S5P_VPROCESSOR_BASE(0x02B0) // CR to Y CSC Coefficient Setting + +/* + Registers Bit Description +*/ +/* S5P_VP_ENABLE */ +#define S5P_VP_ENABLE_ON (1<<0) +#define S5P_VP_ENABLE_ON_S (1<<2) /* R_ONLY, Shadow bit of the bit [0]*/ + +/* S5P_VP_SRESET */ +#define S5P_VP_SRESET_LAST_COMPLETE (0<<0) +#define S5P_VP_SRESET_PROCESSING (1<<0) + +/* S5P_VP_SHADOW_UPDATE */ +#define S5P_VP_SHADOW_UPDATE_DISABLE (0<<0) +#define S5P_VP_SHADOW_UPDATE_ENABLE (1<<0) + +/* S5P_VP_FIELD_ID */ +#define S5P_VP_FIELD_ID_TOP (0<<0) +#define S5P_VP_FIELD_ID_BOTTOM (1<<0) + +/* S5P_VP_MODE */ +#define S5P_VP_MODE_2D_IPC_ENABLE (1<<1) +#define S5P_VP_MODE_2D_IPC_DISABLE (0<<1) +#define S5P_VP_MODE_FIELD_ID_MAN_TOGGLING (0<<2) +#define S5P_VP_MODE_FIELD_ID_AUTO_TOGGLING (1<<2) +#define S5P_VP_MODE_CROMA_EXPANSION_C_TOP_PTR (0<<3) +#define S5P_VP_MODE_CROMA_EXPANSION_C_TOPBOTTOM_PTR (1<<3) +#define S5P_VP_MODE_MEM_MODE_LINEAR (0<<4) +#define S5P_VP_MODE_MEM_MODE_2D_TILE (1<<4) +#define S5P_VP_MODE_LINE_SKIP_OFF (0<<5) +#define S5P_VP_MODE_LINE_SKIP_ON (1<<5) + +/* S5P_VP_ENDIAN_MODE */ +#define S5P_VP_ENDIAN_MODE_BIG (0<<0) +#define S5P_VP_ENDIAN_MODE_LITTLE (1<<0) + +/* Macros */ +/* S5P_VP_ENABLE */ +#define VP_ON_SW_RESET (1<<2) +#define VP_POWER_DOWN_RDY (1<<1) +#define VP_ON_ENABLE (1<<0) +#define VP_ON_DISABLE (0<<0) + +/* S5P_VP_SRESET */ +#define VP_SOFT_RESET (1<<0) + +/* S5P_VP_SHADOW_UPDATA */ +#define VP_SHADOW_UPDATE_ENABLE (1<<0) +#define VP_SHADOW_UPDATE_DISABLE (0<<0) + +/* S5P_VP_FIELD_ID */ +#define VP_FIELD_ID_BOTTOM (1<<0) +#define VP_FIELD_ID_TOP (0<<0) + +/* S5P_VP_MODE */ +#define VP_LINE_SKIP_ON (1<<5) +#define VP_LINE_SKIP_OFF (0<<5) +#define VP_MEM_2D_MODE (1<<4) +#define VP_MEM_LINEAR_MODE (0<<4) +#define VP_CHROMA_USE_TOP_BOTTOM (1<<3) +#define VP_CHROMA_USE_TOP (0<<3) +#define VP_FIELD_ID_TOGGLE_VSYNC (1<<2) +#define VP_FIELD_ID_TOGGLE_USER (0<<2) +#define VP_2D_IPC_ON (1<<1) +#define VP_2D_IPC_OFF (0<<1) + +/* S5P_VP_TILE_SIZE_x */ +#define VP_IMG_HSIZE(a) ((0x3fff&a)<<16) +#define VP_IMG_VSIZE(a) ((0x3fff&a)<<0) +#define VP_IMG_SIZE_ILLEGAL(a) (0x7&a) + +/* S5P_VP_PER_RATE_CTRL */ +#define VP_PEL_RATE_CTRL(a) ((0x3&a)<<0) +/* +enum VP_PIXEL_RATE +{ + VP_PIXEL_PER_RATE_1_1 = 0, + VP_PIXEL_PER_RATE_1_2 = 1, + VP_PIXEL_PER_RATE_1_3 = 2, + VP_PIXEL_PER_RATE_1_4 = 3 +} +*/ + +/* S5P_VP_TOP_x_PTR , VP_BOT_x_PTR */ +#define VP_PTR_ILLEGAL(a) (0x7&a) + +/* S5P_ VP_ENDIAN_MODE */ +#define VP_LITTLE_ENDIAN_MODE (1<<0) +#define VP_BIG_ENDIAN_MODE (0<<0) + +/* S5P_VP_SRC_H_POSITION */ +#define VP_SRC_H_POSITION(a) ((0x7ff&a)<<4) +#define VP_SRC_X_FRACT_STEP(a) (0xf&a) + +/* S5P_VP_SRC_V_POSITION */ +#define VP_SRC_V_POSITION(a) (0x7ff&a) + +/* S5P_VP_SRC_WIDTH */ +#define VP_SRC_WIDTH(a) (0x7ff&a) + +/* S5P_VP_SRC_WIDTH */ +#define VP_SRC_HEIGHT(a) (0x7ff&a) + +/* S5P_VP_DST_H_POSITION */ +#define VP_DST_H_POSITION(a) (0x7ff&a) + +/* S5P_VP_DST_V_POSITION */ +#define VP_DST_V_POSITION(a) (0x7ff&a) + +/* S5P_VP_DST_WIDTH */ +#define VP_DST_WIDTH(a) (0x7ff&a) + +/* S5P_VP_DST_WIDTH +#define VP_DST_HEIGHT(a) (0x3ff&a) +C110:*/ +#define VP_DST_HEIGHT(a) (0x7ff&a) + +/* S5P_VP_H_RATIO */ +#define VP_H_RATIO(a) (0x7ffff&a) + +/* S5P_VP_V_RATIO */ +#define VP_V_RATIO(a) (0x7ffff&a) + +/* S5P_VP_POLY8_Y0_xx */ +#define VP_POLY8_Y0_x0(a) ((0x7&a)<<24) +#define VP_POLY8_Y0_x1(a) ((0x7&a)<<16) +#define VP_POLY8_Y0_x2(a) ((0x7&a)<<8) +#define VP_POLY8_Y0_x3(a) ((0x7&a)<<0) + +/* S5P_VP_POLY8_Y1_xx */ +#define VP_POLY8_Y1_x0(a) ((0x1f&a)<<24) +#define VP_POLY8_Y1_x1(a) ((0x1f&a)<<16) +#define VP_POLY8_Y1_x2(a) ((0x1f&a)<<8) +#define VP_POLY8_Y1_x3(a) ((0x1f&a)<<0) + +/* VP_POLY8_Y2_xx */ +#define VP_POLY8_Y2_x0(a) ((0x7f&a)<<24) +#define VP_POLY8_Y2_x1(a) ((0x7f&a)<<16) +#define VP_POLY8_Y2_x2(a) ((0x7f&a)<<8) +#define VP_POLY8_Y2_x3(a) ((0x7f&a)<<0) + +/* VP_POLY8_Y3_xx */ +#define VP_POLY8_Y3_x0(a) ((0x7f&a)<<24) +#define VP_POLY8_Y3_x1(a) ((0x7f&a)<<16) +#define VP_POLY8_Y3_x2(a) ((0x7f&a)<<8) +#define VP_POLY8_Y3_x3(a) ((0x7f&a)<<0) + +/* VP_POLY4_Y0_xx */ +#define VP_POLY4_Y0_x0(a) ((0x3f&a)<<24) +#define VP_POLY4_Y0_x1(a) ((0x3f&a)<<16) +#define VP_POLY4_Y0_x2(a) ((0x3f&a)<<8) +#define VP_POLY4_Y0_x3(a) ((0x3f&a)<<0) + +/* VP_POLY4_Y1_xx */ +#define VP_POLY4_Y1_x0(a) ((0x7f&a)<<24) +#define VP_POLY4_Y1_x1(a) ((0x7f&a)<<16) +#define VP_POLY4_Y1_x2(a) ((0x7f&a)<<8) +#define VP_POLY4_Y1_x3(a) ((0x7f&a)<<0) + +/* VP_POLY4_Y2_xx */ +#define VP_POLY4_Y2_x0(a) ((0x7f&a)<<24) +#define VP_POLY4_Y2_x1(a) ((0x7f&a)<<16) +#define VP_POLY4_Y2_x2(a) ((0x7f&a)<<8) +#define VP_POLY4_Y2_x3(a) ((0x7f&a)<<0) + +/* VP_POLY4_Y3_xx */ +#define VP_POLY4_Y3_x0(a) ((0x3f&a)<<24) +#define VP_POLY4_Y3_x1(a) ((0x3f&a)<<16) +#define VP_POLY4_Y3_x2(a) ((0x3f&a)<<8) +#define VP_POLY4_Y3_x3(a) ((0x3f&a)<<0) + +/* VP_POLY4_C0_LL */ +#define VP_POLY4_C0_PH0(a) ((0x7f&a)<<24) +#define VP_POLY4_C0_PH1(a) ((0x7f&a)<<16) +#define VP_POLY4_C0_PH2(a) ((0x7f&a)<<8) +#define VP_POLY4_C0_PH3(a) ((0x7f&a)<<0) + +/* VP_POLY4_C0_LH */ +#define VP_POLY4_C0_PH4(a) ((0x3f&a)<<24) +#define VP_POLY4_C0_PH5(a) ((0x3f&a)<<16) +#define VP_POLY4_C0_PH6(a) ((0x3f&a)<<8) +#define VP_POLY4_C0_PH7(a) ((0x3f&a)<<0) + +/* VP_POLY4_C0_HL */ +#define VP_POLY4_C0_PH8(a) ((0x3f&a)<<24) +#define VP_POLY4_C0_PH9(a) ((0x3f&a)<<16) +#define VP_POLY4_C0_PH10(a) ((0x3f&a)<<8) +#define VP_POLY4_C0_PH11(a) ((0x3f&a)<<0) + +/* VP_POLY4_C0_HH */ +#define VP_POLY4_C0_PH12(a) ((0x1f&a)<<24) +#define VP_POLY4_C0_PH13(a) ((0x1f&a)<<16) +#define VP_POLY4_C0_PH14(a) ((0x1f&a)<<8) +#define VP_POLY4_C0_PH15(a) ((0x1f&a)<<0) + +/* VP_POLY4_C1_LL */ +#define VP_POLY4_C1_PH0(a) ((0xff&a)<<24) +#define VP_POLY4_C1_PH1(a) ((0xff&a)<<16) +#define VP_POLY4_C1_PH2(a) ((0xff&a)<<8) +#define VP_POLY4_C1_PH3(a) ((0xff&a)<<0) + +/* VP_POLY4_C1_LH */ +#define VP_POLY4_C1_PH4(a) ((0xff&a)<<24) +#define VP_POLY4_C1_PH5(a) ((0xff&a)<<16) +#define VP_POLY4_C1_PH6(a) ((0xff&a)<<8) +#define VP_POLY4_C1_PH7(a) ((0xff&a)<<0) + +/* VP_POLY4_C1_HL */ +#define VP_POLY4_C1_PH8(a) ((0xff&a)<<24) +#define VP_POLY4_C1_PH9(a) ((0xff&a)<<16) +#define VP_POLY4_C1_PH10(a) ((0xff&a)<<8) +#define VP_POLY4_C1_PH11(a) ((0xff&a)<<0) + +/* VP_POLY4_C1_HH */ +#define VP_POLY4_C1_PH12(a) ((0x7f&a)<<24) +#define VP_POLY4_C1_PH13(a) ((0x7f&a)<<16) +#define VP_POLY4_C1_PH14(a) ((0x7f&a)<<8) +#define VP_POLY4_C1_PH15(a) ((0x7f&a)<<0) + +/* PP_CSC_COEF */ +#define VP_CSC_COEF(a) (0xfff&a) + +/* PP_BYPASS */ +#define VP_BY_PASS_ENABLE (0) +#define VP_BY_PASS_DISABLE (1) + +/* PP_SATURATION */ +#define VP_SATURATION(a) (0xff&a) + +/* PP_SHARPNESS */ +#define VP_TH_HNOISE(a) ((0xf&a)<<8) +#define VP_SHARPNESS(a) (0x3&a) +/* +enum VP_SHARPNESS_CONTROL +{ + VP_SHARPNESS_NO = 0, + VP_SHARPNESS_MIN = 1, + VP_SHARPNESS_MOD = 2, + VP_SHARPNESS_MAX = 3 +} +*/ + +/* PP_LINE_EQx */ +#define VP_LINE_INTC(a) ((0xffff&a)<<8) +#define VP_LINE_SLOPE(a) (0xff&a) +#define VP_LINE_INTC_CLEAR(a) (~(0xffff<<8)&a) +#define VP_LINE_SLOPE_CLEAR(a) (~0xff&a) + +/* PP_BRIGHT_OFFSET */ +#define VP_BRIGHT_OFFSET(a) (0x1ff&a) + +/* PP_CSC_EN */ +#define VP_SUB_Y_OFFSET_ENABLE (1<<1) +#define VP_SUB_Y_OFFSET_DISABLE (0<<1) +#define VP_CSC_ENABLE (1) +#define VP_CSC_DISABLE (0) + +/* global variables */ +static unsigned int g_vp_contrast_brightness = 0; + +/*#define VP_UPDATE_RETRY_MAXIMUM 30 +#define VP_WAIT_UPDATE_SLEEP 3 */ + +/* Ref. to VP manual p37-39 + [11] : sign bit, [10] : integer bit, [9:0] : fraction bit + CSC from BT.601(SD) to BT.709(HD) */ +#define Y2Y_COEF_601_TO_709 0x400 // 1.0 +#define CB2Y_COEF_601_TO_709 0x879 // about -0.118188 ex) 0.118188*1024 = 121.024512 --> about 121 convert to hex(0x79) +#define CR2Y_COEF_601_TO_709 0x8d9 // about -0.212685 + +#define Y2CB_COEF_601_TO_709 0x0 // 0 +#define CB2CB_COEF_601_TO_709 0x413 // about 1.018640 +#define CR2CB_COEF_601_TO_709 0x875 // about -0.114618 + +#define Y2CR_COEF_601_TO_709 0x0 +#define CB2CR_COEF_601_TO_709 0x04d // about 0.075049 +#define CR2CR_COEF_601_TO_709 0x41a // about 1.025327 + +/* CSC from BT.709(HD) to BT.601(SD) */ +#define Y2Y_COEF_709_TO_601 0x400 +#define CB2Y_COEF_709_TO_601 0x068 // about 0.101579 +#define CR2Y_COEF_709_TO_601 0x0c9 // about 0.196076 + +#define Y2CB_COEF_709_TO_601 0x0 +#define CB2CB_COEF_709_TO_601 0x3f6 // about 0.989854 +#define CR2CB_COEF_709_TO_601 0x871 // about -0.110653 + +#define Y2CR_COEF_709_TO_601 0x0 +#define CB2CR_COEF_709_TO_601 0x84a // about -0.072453 +#define CR2CR_COEF_709_TO_601 0xbef // about -0.983398 + +#define TILE_WIDTH 0x40 +#define MAX_NUM_OF_FRM 34 // according to MFC + +#endif /* __ASM_ARCH_REGS_VPROCESSOR_H */ + diff --git a/drivers/media/video/samsung/tv20/s5pv210/sdout_s5pv210.c b/drivers/media/video/samsung/tv20/s5pv210/sdout_s5pv210.c new file mode 100644 index 0000000..4a4ea66 --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5pv210/sdout_s5pv210.c @@ -0,0 +1,2038 @@ +/* linux/drivers/media/video/samsung/tv20/s5pv210/sdout_s5pv210.c + * + * tv encoder raw ftn file for Samsung TVOut driver + * + * Copyright (c) 2010 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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/platform_device.h> +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/io.h> +#include <linux/uaccess.h> +#include <linux/memory.h> +#include <linux/mm.h> + +#include <plat/clock.h> +#include "tv_out_s5pv210.h" + +#include "regs/regs-sdaout.h" + +#ifdef COFIG_TVOUT_RAW_DBG +#define S5P_SDAOUT_DEBUG 1 +#endif + +#ifdef S5P_SDAOUT_DEBUG +#define SDPRINTK(fmt, args...) \ + printk(KERN_INFO "\t\t[SDOUT] %s: " fmt, __func__ , ## args) +#else +#define SDPRINTK(fmt, args...) +#endif + +static struct resource *sdout_mem; +void __iomem *sdout_base; + +/* +* initialization - iniization functions are only called under stopping SDOUT +*/ +enum s5p_tv_sd_err __s5p_sdout_init_video_scale_cfg( + enum s5p_sd_level component_level, + enum s5p_sd_vsync_ratio component_ratio, + enum s5p_sd_level composite_level, + enum s5p_sd_vsync_ratio composite_ratio) +{ + u32 temp_reg = 0; + + SDPRINTK("%d, %d, %d, %d\n\r", component_level, component_ratio, + composite_level, composite_ratio); + + switch (component_level) { + + case S5P_TV_SD_LEVEL_0IRE: + temp_reg = SDO_COMPONENT_LEVEL_SEL_0IRE; + break; + + case S5P_TV_SD_LEVEL_75IRE: + temp_reg = SDO_COMPONENT_LEVEL_SEL_75IRE; + break; + + default: + SDPRINTK("invalid component_level parameter(%d)\n\r", + component_level); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + switch (composite_level) { + + case SDOUT_VTOS_RATIO_10_4: + temp_reg |= SDO_COMPONENT_VTOS_RATIO_10_4; + break; + + case SDOUT_VTOS_RATIO_7_3: + temp_reg |= SDO_COMPONENT_VTOS_RATIO_7_3; + break; + + default: + SDPRINTK(" invalid composite_level parameter(%d)\n\r", + composite_level); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + switch (composite_level) { + + case S5P_TV_SD_LEVEL_0IRE: + temp_reg |= SDO_COMPOSITE_LEVEL_SEL_0IRE; + break; + + case S5P_TV_SD_LEVEL_75IRE: + temp_reg |= SDO_COMPOSITE_LEVEL_SEL_75IRE; + break; + + default: + SDPRINTK("invalid composite_ratio parameter(%d)\n\r", + composite_ratio); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + switch (composite_ratio) { + + case SDOUT_VTOS_RATIO_10_4: + temp_reg |= SDO_COMPOSITE_VTOS_RATIO_10_4; + break; + + case SDOUT_VTOS_RATIO_7_3: + temp_reg |= SDO_COMPOSITE_VTOS_RATIO_7_3; + break; + + default: + SDPRINTK("invalid component_ratio parameter(%d)\n\r", + component_ratio); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + writel(temp_reg, sdout_base + S5P_SDO_SCALE); + + SDPRINTK("0x%08x)\n\r", readl(sdout_base + S5P_SDO_SCALE)); + + return SDOUT_NO_ERROR; +} + +enum s5p_tv_sd_err __s5p_sdout_init_sync_signal_pin( + enum s5p_sd_sync_sig_pin pin) +{ + SDPRINTK("%d\n\r", pin); + + switch (pin) { + + case SDOUT_SYNC_SIG_NO: + writel(SDO_COMPONENT_SYNC_ABSENT, sdout_base + S5P_SDO_SYNC); + break; + + case SDOUT_SYNC_SIG_YG: + writel(SDO_COMPONENT_SYNC_YG, sdout_base + S5P_SDO_SYNC); + break; + + case SDOUT_SYNC_SIG_ALL: + writel(SDO_COMPONENT_SYNC_ALL, sdout_base + S5P_SDO_SYNC); + break; + + default: + SDPRINTK("invalid pin parameter(%d)\n\r", pin); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + SDPRINTK("0x%08x\n\r", readl(sdout_base + S5P_SDO_SYNC)); + + return SDOUT_NO_ERROR; +} + +enum s5p_tv_sd_err __s5p_sdout_init_vbi(bool wss_cvbs, + enum s5p_sd_closed_caption_type caption_cvbs, + bool wss_y_sideo, + enum s5p_sd_closed_caption_type caption_y_sideo, + bool cgmsa_rgb, + bool wss_rgb, + enum s5p_sd_closed_caption_type caption_rgb, + bool cgmsa_y_ppr, + bool wss_y_ppr, + enum s5p_sd_closed_caption_type caption_y_ppr) +{ + u32 temp_reg = 0; + + SDPRINTK(" %d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n\r", + wss_cvbs, caption_cvbs, + wss_y_sideo, caption_y_sideo, cgmsa_rgb, wss_rgb, caption_rgb, + cgmsa_y_ppr, wss_y_ppr, caption_y_ppr); + + if (wss_cvbs) + temp_reg = SDO_CVBS_WSS_INS; + else + temp_reg = SDO_CVBS_NO_WSS; + + + switch (caption_cvbs) { + + case SDOUT_NO_INS: + temp_reg |= SDO_CVBS_NO_CLOSED_CAPTION; + break; + + case SDOUT_INS_1: + temp_reg |= SDO_CVBS_21H_CLOSED_CAPTION; + break; + + case SDOUT_INS_2: + temp_reg |= SDO_CVBS_21H_284H_CLOSED_CAPTION; + break; + + case SDOUT_INS_OTHERS: + temp_reg |= SDO_CVBS_USE_OTHERS; + break; + + default: + SDPRINTK(" invalid caption_cvbs parameter(%d)\n\r", + caption_cvbs); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + if (wss_y_sideo) + temp_reg |= SDO_SVIDEO_WSS_INS; + else + temp_reg |= SDO_SVIDEO_NO_WSS; + + + switch (caption_y_sideo) { + + case SDOUT_NO_INS: + temp_reg |= SDO_SVIDEO_NO_CLOSED_CAPTION; + break; + + case SDOUT_INS_1: + temp_reg |= SDO_SVIDEO_21H_CLOSED_CAPTION; + break; + + case SDOUT_INS_2: + temp_reg |= SDO_SVIDEO_21H_284H_CLOSED_CAPTION; + break; + + case SDOUT_INS_OTHERS: + temp_reg |= SDO_SVIDEO_USE_OTHERS; + break; + + default: + SDPRINTK("invalid caption_y_sideo parameter(%d)\n\r", + caption_y_sideo); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + if (cgmsa_rgb) + temp_reg |= SDO_RGB_CGMSA_INS; + else + temp_reg |= SDO_RGB_NO_CGMSA; + + + if (wss_rgb) + temp_reg |= SDO_RGB_WSS_INS; + else + temp_reg |= SDO_RGB_NO_WSS; + + + switch (caption_rgb) { + + case SDOUT_NO_INS: + temp_reg |= SDO_RGB_NO_CLOSED_CAPTION; + break; + + case SDOUT_INS_1: + temp_reg |= SDO_RGB_21H_CLOSED_CAPTION; + break; + + case SDOUT_INS_2: + temp_reg |= SDO_RGB_21H_284H_CLOSED_CAPTION; + break; + + case SDOUT_INS_OTHERS: + temp_reg |= SDO_RGB_USE_OTHERS; + break; + + default: + SDPRINTK(" invalid caption_rgb parameter(%d)\n\r", + caption_rgb); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + if (cgmsa_y_ppr) + temp_reg |= SDO_YPBPR_CGMSA_INS; + else + temp_reg |= SDO_YPBPR_NO_CGMSA; + + + if (wss_y_ppr) + temp_reg |= SDO_YPBPR_WSS_INS; + else + temp_reg |= SDO_YPBPR_NO_WSS; + + + switch (caption_y_ppr) { + + case SDOUT_NO_INS: + temp_reg |= SDO_YPBPR_NO_CLOSED_CAPTION; + break; + + case SDOUT_INS_1: + temp_reg |= SDO_YPBPR_21H_CLOSED_CAPTION; + break; + + case SDOUT_INS_2: + temp_reg |= SDO_YPBPR_21H_284H_CLOSED_CAPTION; + break; + + case SDOUT_INS_OTHERS: + temp_reg |= SDO_YPBPR_USE_OTHERS; + break; + + default: + SDPRINTK("invalid caption_y_ppr parameter(%d)\n\r", + caption_y_ppr); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + writel(temp_reg, sdout_base + S5P_SDO_VBI); + + SDPRINTK("0x%08x\n\r", readl(sdout_base + S5P_SDO_VBI)); + + return SDOUT_NO_ERROR; +} + +enum s5p_tv_sd_err __s5p_sdout_init_offset_gain( + enum s5p_sd_channel_sel channel, + u32 offset, u32 gain) +{ + SDPRINTK("%d, %d, %d\n\r", channel, offset, gain); + + switch (channel) { + + case SDOUT_CHANNEL_0: + writel(SDO_SCALE_CONV_OFFSET(offset) | + SDO_SCALE_CONV_GAIN(gain), + sdout_base + S5P_SDO_SCALE_CH0); + SDPRINTK("0x%08x\n\r", readl(sdout_base + S5P_SDO_SCALE_CH0)); + break; + + case SDOUT_CHANNEL_1: + writel(SDO_SCALE_CONV_OFFSET(offset) | + SDO_SCALE_CONV_GAIN(gain), + sdout_base + S5P_SDO_SCALE_CH1); + SDPRINTK(" 0x%08x\n\r", readl(sdout_base + S5P_SDO_SCALE_CH1)); + break; + + case SDOUT_CHANNEL_2: + writel(SDO_SCALE_CONV_OFFSET(offset) | + SDO_SCALE_CONV_GAIN(gain), + sdout_base + S5P_SDO_SCALE_CH2); + SDPRINTK(" 0x%08x\n\r", readl(sdout_base + S5P_SDO_SCALE_CH2)); + break; + + default: + SDPRINTK(" invalid channel parameter(%d)\n\r", channel); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + return SDOUT_NO_ERROR; +} + +void __s5p_sdout_init_delay(u32 delay_y, + u32 offset_video_start, + u32 offset_video_end) +{ + SDPRINTK("%d, %d, %d\n\r", delay_y, offset_video_start, + offset_video_end); + + writel(SDO_DELAY_YTOC(delay_y) | + SDO_ACTIVE_START_OFFSET(offset_video_start) | + SDO_ACTIVE_END_OFFSET(offset_video_end), + sdout_base + S5P_SDO_YCDELAY); + + SDPRINTK("0x%08x\n\r", readl(sdout_base + S5P_SDO_YCDELAY)); +} + +void __s5p_sdout_init_schlock(bool color_sucarrier_pha_adj) +{ + SDPRINTK("%d\n\r", color_sucarrier_pha_adj); + + if (color_sucarrier_pha_adj) + writel(SDO_COLOR_SC_PHASE_ADJ, sdout_base + S5P_SDO_SCHLOCK); + else + writel(SDO_COLOR_SC_PHASE_NOADJ, sdout_base + S5P_SDO_SCHLOCK); + + + SDPRINTK("0x%08x\n\r", readl(sdout_base + S5P_SDO_SCHLOCK)); +} + +enum s5p_tv_sd_err __s5p_sdout_init_dac_power_onoff( + enum s5p_sd_channel_sel channel, bool dac_on) +{ + u32 temp_on_off; + + SDPRINTK("%d, %d)\n\r", channel, dac_on); + + switch (channel) { + + case SDOUT_CHANNEL_0: + temp_on_off = SDO_POWER_ON_DAC0; + break; + + case SDOUT_CHANNEL_1: + temp_on_off = SDO_POWER_ON_DAC1; + break; + + case SDOUT_CHANNEL_2: + temp_on_off = SDO_POWER_ON_DAC2; + break; + + default: + SDPRINTK("invalid channel parameter(%d)\n\r", channel); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + if (dac_on) + writel(readl(sdout_base + S5P_SDO_DAC) | temp_on_off, + sdout_base + S5P_SDO_DAC); + else + writel(readl(sdout_base + S5P_SDO_DAC) & ~temp_on_off, + sdout_base + S5P_SDO_DAC); + + + SDPRINTK("0x%08x\n\r", readl(sdout_base + S5P_SDO_DAC)); + + return SDOUT_NO_ERROR; +} + +void __s5p_sdout_init_color_compensaton_onoff(bool bright_hue_saturation_adj, + bool y_ppr_color_compensation, + bool rgcolor_compensation, + bool y_c_color_compensation, + bool y_cvbs_color_compensation) +{ + u32 temp_reg = 0; + + SDPRINTK("%d, %d, %d, %d, %d)\n\r", bright_hue_saturation_adj, + y_ppr_color_compensation, rgcolor_compensation, + y_c_color_compensation, y_cvbs_color_compensation); + + if (bright_hue_saturation_adj) + temp_reg &= ~SDO_COMPONENT_BHS_ADJ_OFF; + else + temp_reg |= SDO_COMPONENT_BHS_ADJ_OFF; + + + if (y_ppr_color_compensation) + temp_reg &= ~SDO_COMPONENT_YPBPR_COMP_OFF; + else + temp_reg |= SDO_COMPONENT_YPBPR_COMP_OFF; + + + if (rgcolor_compensation) + temp_reg &= ~SDO_COMPONENT_RGB_COMP_OFF; + else + temp_reg |= SDO_COMPONENT_RGB_COMP_OFF; + + + if (y_c_color_compensation) + temp_reg &= ~SDO_COMPONENT_YC_COMP_OFF; + else + temp_reg |= SDO_COMPONENT_YC_COMP_OFF; + + + if (y_cvbs_color_compensation) + temp_reg &= ~SDO_COMPONENT_CVBS_COMP_OFF; + else + temp_reg |= SDO_COMPONENT_CVBS_COMP_OFF; + + + writel(temp_reg, sdout_base + S5P_SDO_CCCON); + + SDPRINTK("0x%08x\n\r", readl(sdout_base + S5P_SDO_CCCON)); +} + +void __s5p_sdout_init_brightness_hue_saturation(u32 gain_brightness, + u32 offset_brightness, + u32 gain0_cb_hue_saturation, + u32 gain1_cb_hue_saturation, + u32 gain0_cr_hue_saturation, + u32 gain1_cr_hue_saturation, + u32 offset_cb_hue_saturation, + u32 offset_cr_hue_saturation) +{ + SDPRINTK(" %d, %d, %d, %d, %d, %d, %d, %d)\n\r", gain_brightness, + offset_brightness, gain0_cb_hue_saturation, + gain1_cb_hue_saturation, gain0_cr_hue_saturation, + gain1_cr_hue_saturation, offset_cb_hue_saturation, + offset_cr_hue_saturation); + + writel(SDO_BRIGHTNESS_GAIN(gain_brightness) | + SDO_BRIGHTNESS_OFFSET(offset_brightness), + sdout_base + S5P_SDO_YSCALE); + + writel(SDO_HS_CB_GAIN0(gain0_cb_hue_saturation) | + SDO_HS_CB_GAIN1(gain1_cb_hue_saturation), + sdout_base + S5P_SDO_CBSCALE); + + writel(SDO_HS_CR_GAIN0(gain0_cr_hue_saturation) | + SDO_HS_CR_GAIN1(gain1_cr_hue_saturation), + sdout_base + S5P_SDO_CRSCALE); + + writel(SDO_HS_CR_OFFSET(offset_cr_hue_saturation) | + SDO_HS_CB_OFFSET(offset_cb_hue_saturation), + sdout_base + S5P_SDO_CB_CR_OFFSET); + + SDPRINTK("0x%08x, 0x%08x, 0x%08x, 0x%08x)\n\r", + readl(sdout_base + S5P_SDO_YSCALE), + readl(sdout_base + S5P_SDO_CBSCALE), + readl(sdout_base + S5P_SDO_CRSCALE), + readl(sdout_base + S5P_SDO_CB_CR_OFFSET)); +} + +void __s5p_sdout_init_rgb_color_compensation(u32 max_rgbcube, + u32 min_rgbcube) +{ + SDPRINTK("0x%08x, 0x%08x\n\r", max_rgbcube, min_rgbcube); + + writel(SDO_MAX_RGB_CUBE(max_rgbcube) | SDO_MIN_RGB_CUBE(min_rgbcube), + sdout_base + S5P_SDO_RGB_CC); + + SDPRINTK("0x%08x)\n\r", readl(sdout_base + S5P_SDO_RGB_CC)); +} + +void __s5p_sdout_init_cvbs_color_compensation(u32 y_lower_mid, + u32 y_bottom, + u32 y_top, + u32 y_upper_mid, + u32 radius) +{ + SDPRINTK("%d, %d, %d, %d, %d\n\r", y_lower_mid, y_bottom, y_top, + y_upper_mid, radius); + + writel(SDO_Y_LOWER_MID_CVBS_CORN(y_lower_mid) | + SDO_Y_BOTTOM_CVBS_CORN(y_bottom), + sdout_base + S5P_SDO_CVBS_CC_Y1); + writel(SDO_Y_TOP_CVBS_CORN(y_top) | + SDO_Y_UPPER_MID_CVBS_CORN(y_upper_mid), + sdout_base + S5P_SDO_CVBS_CC_Y2); + writel(SDO_RADIUS_CVBS_CORN(radius), sdout_base + S5P_SDO_CVBS_CC_C); + + SDPRINTK("0x%08x, 0x%08x, 0x%08x)\n\r", + readl(sdout_base + S5P_SDO_CVBS_CC_Y1), + readl(sdout_base + S5P_SDO_CVBS_CC_Y2), + readl(sdout_base + S5P_SDO_CVBS_CC_C)); +} + +void __s5p_sdout_init_svideo_color_compensation(u32 y_top, + u32 y_bottom, + u32 y_c_cylinder) +{ + SDPRINTK(" %d, %d, %d)\n\r", y_top, y_bottom, y_c_cylinder); + + writel(SDO_Y_TOP_YC_CYLINDER(y_top) | + SDO_Y_BOTOM_YC_CYLINDER(y_bottom), + sdout_base + S5P_SDO_YC_CC_Y); + writel(SDO_RADIUS_YC_CYLINDER(y_c_cylinder), + sdout_base + S5P_SDO_YC_CC_C); + + SDPRINTK("0x%08x, 0x%08x)\n\r", readl(sdout_base + S5P_SDO_YC_CC_Y), + readl(sdout_base + S5P_SDO_YC_CC_C)); +} + +void __s5p_sdout_init_component_porch(u32 back_525, + u32 front_525, + u32 back_625, + u32 front_625) +{ + SDPRINTK(" %d, %d, %d, %d)\n\r", back_525, + front_525, back_625, front_625); + + writel(SDO_COMPONENT_525_BP(back_525) | + SDO_COMPONENT_525_FP(front_525), + sdout_base + S5P_SDO_CSC_525_PORCH); + writel(SDO_COMPONENT_625_BP(back_625) | + SDO_COMPONENT_625_FP(front_625), + sdout_base + S5P_SDO_CSC_625_PORCH); + + SDPRINTK(" 0x%08x, 0x%08x)\n\r", + readl(sdout_base + S5P_SDO_CSC_525_PORCH), + readl(sdout_base + S5P_SDO_CSC_625_PORCH)); +} + +enum s5p_tv_sd_err __s5p_sdout_init_vesa_rgb_sync( + enum s5p_sd_vesa_rgb_sync_type sync_type, + enum s5p_tv_active_polarity v_sync_active, + enum s5p_tv_active_polarity h_sync_active) +{ + u32 temp_reg = 0; + + SDPRINTK("%d, %d, %d\n\r", sync_type, v_sync_active, h_sync_active); + + switch (sync_type) { + + case SDOUT_VESA_RGB_SYNC_COMPOSITE: + temp_reg |= SDO_RGB_SYNC_COMPOSITE; + break; + + case SDOUT_VESA_RGB_SYNC_SEPARATE: + temp_reg |= SDO_RGB_SYNC_SEPERATE; + break; + + default: + SDPRINTK(" invalid sync_type parameter(%d)\n\r", sync_type); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + switch (v_sync_active) { + + case TVOUT_POL_ACTIVE_LOW: + temp_reg |= SDO_RGB_VSYNC_LOW_ACT; + break; + + case TVOUT_POL_ACTIVE_HIGH: + temp_reg |= SDO_RGB_VSYNC_HIGH_ACT; + break; + + default: + SDPRINTK(" invalid v_sync_active parameter(%d)\n\r", + v_sync_active); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + switch (h_sync_active) { + + case TVOUT_POL_ACTIVE_LOW: + temp_reg |= SDO_RGB_HSYNC_LOW_ACT; + break; + + case TVOUT_POL_ACTIVE_HIGH: + temp_reg |= SDO_RGB_HSYNC_HIGH_ACT; + break; + + default: + SDPRINTK(" invalid h_sync_active parameter(%d)\n\r", + h_sync_active); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + writel(temp_reg, sdout_base + S5P_SDO_RGBSYNC); + + SDPRINTK("0x%08x\n\r", readl(sdout_base + S5P_SDO_RGBSYNC)); + + return SDOUT_NO_ERROR; +} + +void __s5p_sdout_init_oversampling_filter_coeff(u32 size, + u32 *coeff, + u32 *coeff1, + u32 *coeff2) +{ + u32 *temp_reg = 0; + + SDPRINTK(" %d, 0x%x, 0x%x, 0x%x\n\r", (u32)size, (u32)coeff, + (u32)coeff1, (u32)coeff2); + + if (coeff != NULL) { + temp_reg = (u32 *)readl(sdout_base + S5P_SDO_OSFC00_0); + memcpy((void *)temp_reg, (const void *)coeff, size*4); + } + + if (coeff1 != NULL) { + temp_reg = (u32 *)readl(sdout_base + S5P_SDO_OSFC00_1); + memcpy((void *)temp_reg, (const void *)coeff1, size*4); + } + + if (coeff2 != NULL) { + temp_reg = (u32 *)readl(sdout_base + S5P_SDO_OSFC00_2); + memcpy((void *)temp_reg, (const void *)coeff2, size*4); + } + + SDPRINTK(" ()\n\r"); +} + +enum s5p_tv_sd_err __s5p_sdout_init_ch_xtalk_cancel_coef( + enum s5p_sd_channel_sel channel, + u32 coeff2, u32 coeff1) +{ + SDPRINTK(" %d, %d, %d\n\r", channel, coeff2, coeff1); + + switch (channel) { + + case SDOUT_CHANNEL_0: + writel(SDO_XTALK_COEF02(coeff2) | SDO_XTALK_COEF01(coeff1), + sdout_base + S5P_SDO_XTALK0); + SDPRINTK(" 0x%08x)\n\r", readl(sdout_base + S5P_SDO_XTALK0)); + break; + + case SDOUT_CHANNEL_1: + writel(SDO_XTALK_COEF02(coeff2) | SDO_XTALK_COEF01(coeff1), + sdout_base + S5P_SDO_XTALK1); + SDPRINTK(" 0x%08x)\n\r", readl(sdout_base + S5P_SDO_XTALK1)); + break; + + case SDOUT_CHANNEL_2: + writel(SDO_XTALK_COEF02(coeff2) | SDO_XTALK_COEF01(coeff1), + sdout_base + S5P_SDO_XTALK2); + SDPRINTK("0x%08x)\n\r", readl(sdout_base + S5P_SDO_XTALK2)); + break; + + default: + SDPRINTK(" invalid channel parameter(%d)\n\r", channel); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + return SDOUT_NO_ERROR; +} + +void __s5p_sdout_init_closed_caption(u32 display_cc, u32 non_display_cc) +{ + SDPRINTK("%d, %d\n\r", display_cc, non_display_cc); + + writel(SDO_DISPLAY_CC_CAPTION(display_cc) | + SDO_NON_DISPLAY_CC_CAPTION(non_display_cc), + sdout_base + S5P_SDO_ARMCC); + + SDPRINTK("0x%x\n\r", readl(sdout_base + S5P_SDO_ARMCC)); +} + + +/* static functions */ +static u32 __s5p_sdout_init_wss_cgms_crc(u32 value) +{ + u8 i; + u8 CGMS[14], CRC[6], OLD_CRC; + u32 temp_in; + + temp_in = value; + + for (i = 0; i < 14; i++) + CGMS[i] = (u8)(temp_in >> i) & 0x1 ; + + /* initialize state */ + for (i = 0; i < 6; i++) + CRC[i] = 0x1; + + /* round 20 */ + for (i = 0; i < 14; i++) { + OLD_CRC = CRC[0]; + CRC[0] = CRC[1]; + CRC[1] = CRC[2]; + CRC[2] = CRC[3]; + CRC[3] = CRC[4]; + CRC[4] = OLD_CRC ^ CGMS[i] ^ CRC[5]; + CRC[5] = OLD_CRC ^ CGMS[i]; + } + + /* recompose to return crc */ + temp_in &= 0x3fff; + + for (i = 0; i < 6; i++) + temp_in |= ((u32)(CRC[i] & 0x1) << i); + + + return temp_in; +} + + +enum s5p_tv_sd_err __s5p_sdout_init_wss525_data( + enum s5p_sd_525_copy_permit copy_permit, + enum s5p_sd_525_mv_psp mv_psp, + enum s5p_sd_525_copy_info copy_info, + bool analog_on, + enum s5p_sd_525_aspect_ratio display_ratio) +{ + u32 temp_reg = 0; + + SDPRINTK("%d, %d, %d, %d\n\r", copy_permit, mv_psp, copy_info, + display_ratio); + + switch (copy_permit) { + + case SDO_525_COPY_PERMIT: + temp_reg = SDO_WORD2_WSS525_COPY_PERMIT; + break; + + case SDO_525_ONECOPY_PERMIT: + temp_reg = SDO_WORD2_WSS525_ONECOPY_PERMIT; + break; + + case SDO_525_NOCOPY_PERMIT: + temp_reg = SDO_WORD2_WSS525_NOCOPY_PERMIT; + break; + + default: + SDPRINTK(" invalid copy_permit parameter(%d)\n\r", copy_permit); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + switch (mv_psp) { + + case SDO_525_MV_PSP_OFF: + temp_reg |= SDO_WORD2_WSS525_MV_PSP_OFF; + break; + + case SDO_525_MV_PSP_ON_2LINE_BURST: + temp_reg |= SDO_WORD2_WSS525_MV_PSP_ON_2LINE_BURST; + break; + + case SDO_525_MV_PSP_ON_BURST_OFF: + temp_reg |= SDO_WORD2_WSS525_MV_PSP_ON_BURST_OFF; + break; + + case SDO_525_MV_PSP_ON_4LINE_BURST: + temp_reg |= SDO_WORD2_WSS525_MV_PSP_ON_4LINE_BURST; + break; + + default: + SDPRINTK(" invalid mv_psp parameter(%d)\n\r", mv_psp); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + switch (copy_info) { + + case SDO_525_COPY_INFO: + temp_reg |= SDO_WORD1_WSS525_COPY_INFO; + break; + + case SDO_525_DEFAULT: + temp_reg |= SDO_WORD1_WSS525_DEFAULT; + break; + + default: + SDPRINTK(" invalid copy_info parameter(%d)\n\r", copy_info); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + if (analog_on) + temp_reg |= SDO_WORD2_WSS525_ANALOG_ON; + else + temp_reg |= SDO_WORD2_WSS525_ANALOG_OFF; + + + switch (display_ratio) { + + case SDO_525_COPY_PERMIT: + temp_reg |= SDO_WORD0_WSS525_4_3_NORMAL; + break; + + case SDO_525_ONECOPY_PERMIT: + temp_reg |= SDO_WORD0_WSS525_16_9_ANAMORPIC; + break; + + case SDO_525_NOCOPY_PERMIT: + temp_reg |= SDO_WORD0_WSS525_4_3_LETTERBOX; + break; + + default: + SDPRINTK(" invalid display_ratio parameter(%d)\n\r", + display_ratio); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + writel(temp_reg | + SDO_CRC_WSS525(__s5p_sdout_init_wss_cgms_crc(temp_reg)), + sdout_base + S5P_SDO_WSS525); + + SDPRINTK("0x%08x)\n\r", readl(sdout_base + S5P_SDO_WSS525)); + + return SDOUT_NO_ERROR; +} + +enum s5p_tv_sd_err __s5p_sdout_init_wss625_data(bool surround_sound, + bool copyright, + bool copy_protection, + bool text_subtitles, + enum s5p_sd_625_subtitles open_subtitles, + enum s5p_sd_625_camera_film camera_film, + enum s5p_sd_625_color_encoding color_encoding, + bool helper_signal, + enum s5p_sd_625_aspect_ratio display_ratio) +{ + u32 temp_reg = 0; + + SDPRINTK("%d, %d, %d, %d, %d, %d, %d, %d, %d\n\r", + surround_sound, copyright, copy_protection, + text_subtitles, open_subtitles, camera_film, + color_encoding, helper_signal, display_ratio); + + if (surround_sound) + temp_reg = SDO_WSS625_SURROUND_SOUND_ENABLE; + else + temp_reg = SDO_WSS625_SURROUND_SOUND_DISABLE; + + + if (copyright) + temp_reg |= SDO_WSS625_COPYRIGHT; + else + temp_reg |= SDO_WSS625_NO_COPYRIGHT; + + + if (copy_protection) + temp_reg |= SDO_WSS625_COPY_RESTRICTED; + else + temp_reg |= SDO_WSS625_COPY_NOT_RESTRICTED; + + + if (text_subtitles) + temp_reg |= SDO_WSS625_TELETEXT_SUBTITLES; + else + temp_reg |= SDO_WSS625_TELETEXT_NO_SUBTITLES; + + + switch (open_subtitles) { + + case SDO_625_NO_OPEN_SUBTITLES: + temp_reg |= SDO_WSS625_NO_OPEN_SUBTITLES; + break; + + case SDO_625_INACT_OPEN_SUBTITLES: + temp_reg |= SDO_WSS625_INACT_OPEN_SUBTITLES; + break; + + case SDO_625_OUTACT_OPEN_SUBTITLES: + temp_reg |= SDO_WSS625_OUTACT_OPEN_SUBTITLES; + break; + + default: + SDPRINTK(" invalid open_subtitles parameter(%d)\n\r", + open_subtitles); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + switch (camera_film) { + + case SDO_625_CAMERA: + temp_reg |= SDO_WSS625_CAMERA; + break; + + case SDO_625_FILM: + temp_reg |= SDO_WSS625_FILM; + break; + + default: + SDPRINTK("invalid camera_film parameter(%d)\n\r", + camera_film); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + switch (color_encoding) { + + case SDO_625_NORMAL_PAL: + temp_reg |= SDO_WSS625_NORMAL_PAL; + break; + + case SDO_625_MOTION_ADAPTIVE_COLORPLUS: + temp_reg |= SDO_WSS625_MOTION_ADAPTIVE_COLORPLUS; + break; + + default: + SDPRINTK("invalid color_encoding parameter(%d)\n\r", + color_encoding); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + if (helper_signal) + temp_reg |= SDO_WSS625_HELPER_SIG; + else + temp_reg |= SDO_WSS625_HELPER_NO_SIG; + + + switch (display_ratio) { + + case SDO_625_4_3_FULL_576: + temp_reg |= SDO_WSS625_4_3_FULL_576; + break; + + case SDO_625_14_9_LETTERBOX_CENTER_504: + temp_reg |= SDO_WSS625_14_9_LETTERBOX_CENTER_504; + break; + + case SDO_625_14_9_LETTERBOX_TOP_504: + temp_reg |= SDO_WSS625_14_9_LETTERBOX_TOP_504; + break; + + case SDO_625_16_9_LETTERBOX_CENTER_430: + temp_reg |= SDO_WSS625_16_9_LETTERBOX_CENTER_430; + break; + + case SDO_625_16_9_LETTERBOX_TOP_430: + temp_reg |= SDO_WSS625_16_9_LETTERBOX_TOP_430; + break; + + case SDO_625_16_9_LETTERBOX_CENTER: + temp_reg |= SDO_WSS625_16_9_LETTERBOX_CENTER; + break; + + case SDO_625_14_9_FULL_CENTER_576: + temp_reg |= SDO_WSS625_14_9_FULL_CENTER_576; + break; + + case SDO_625_16_9_ANAMORPIC_576: + temp_reg |= SDO_WSS625_16_9_ANAMORPIC_576; + break; + + default: + SDPRINTK("invalid display_ratio parameter(%d)\n\r", + display_ratio); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + writel(temp_reg, sdout_base + S5P_SDO_WSS625); + + SDPRINTK("0x%08x\n\r", readl(sdout_base + S5P_SDO_WSS625)); + + return SDOUT_NO_ERROR; +} + +enum s5p_tv_sd_err __s5p_sdout_init_cgmsa525_data( + enum s5p_sd_525_copy_permit copy_permit, + enum s5p_sd_525_mv_psp mv_psp, + enum s5p_sd_525_copy_info copy_info, + bool analog_on, + enum s5p_sd_525_aspect_ratio display_ratio) +{ + u32 temp_reg = 0; + + SDPRINTK("%d, %d, %d, %d)\n\r", copy_permit, mv_psp, copy_info, + display_ratio); + + switch (copy_permit) { + + case SDO_525_COPY_PERMIT: + temp_reg = SDO_WORD2_CGMS525_COPY_PERMIT; + break; + + case SDO_525_ONECOPY_PERMIT: + temp_reg = SDO_WORD2_CGMS525_ONECOPY_PERMIT; + break; + + case SDO_525_NOCOPY_PERMIT: + temp_reg = SDO_WORD2_CGMS525_NOCOPY_PERMIT; + break; + + default: + SDPRINTK("invalid copy_permit parameter(%d)\n\r", copy_permit); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + switch (mv_psp) { + + case SDO_525_MV_PSP_OFF: + temp_reg |= SDO_WORD2_CGMS525_MV_PSP_OFF; + break; + + case SDO_525_MV_PSP_ON_2LINE_BURST: + temp_reg |= SDO_WORD2_CGMS525_MV_PSP_ON_2LINE_BURST; + break; + + case SDO_525_MV_PSP_ON_BURST_OFF: + temp_reg |= SDO_WORD2_CGMS525_MV_PSP_ON_BURST_OFF; + break; + + case SDO_525_MV_PSP_ON_4LINE_BURST: + temp_reg |= SDO_WORD2_CGMS525_MV_PSP_ON_4LINE_BURST; + break; + + default: + SDPRINTK(" invalid mv_psp parameter(%d)\n\r", mv_psp); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + switch (copy_info) { + + case SDO_525_COPY_INFO: + temp_reg |= SDO_WORD1_CGMS525_COPY_INFO; + break; + + case SDO_525_DEFAULT: + temp_reg |= SDO_WORD1_CGMS525_DEFAULT; + break; + + default: + SDPRINTK("invalid copy_info parameter(%d)\n\r", copy_info); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + if (analog_on) + temp_reg |= SDO_WORD2_CGMS525_ANALOG_ON; + else + temp_reg |= SDO_WORD2_CGMS525_ANALOG_OFF; + + + switch (display_ratio) { + + case SDO_525_COPY_PERMIT: + temp_reg |= SDO_WORD0_CGMS525_4_3_NORMAL; + break; + + case SDO_525_ONECOPY_PERMIT: + temp_reg |= SDO_WORD0_CGMS525_16_9_ANAMORPIC; + break; + + case SDO_525_NOCOPY_PERMIT: + temp_reg |= SDO_WORD0_CGMS525_4_3_LETTERBOX; + break; + + default: + SDPRINTK(" invalid display_ratio parameter(%d)\n\r", + display_ratio); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + writel(temp_reg | SDO_CRC_CGMS525( + __s5p_sdout_init_wss_cgms_crc(temp_reg)), + sdout_base + S5P_SDO_CGMS525); + + SDPRINTK(" 0x%08x)\n\r", readl(sdout_base + S5P_SDO_CGMS525)); + + return SDOUT_NO_ERROR; +} + +enum s5p_tv_sd_err __s5p_sdout_init_cgmsa625_data(bool surround_sound, + bool copyright, + bool copy_protection, + bool text_subtitles, + enum s5p_sd_625_subtitles open_subtitles, + enum s5p_sd_625_camera_film camera_film, + enum s5p_sd_625_color_encoding color_encoding, + bool helper_signal, + enum s5p_sd_625_aspect_ratio display_ratio) +{ + u32 temp_reg = 0; + + SDPRINTK("%d, %d, %d, %d, %d, %d, %d, %d, %d)\n\r", surround_sound, + copyright, copy_protection, + text_subtitles, open_subtitles, + camera_film, color_encoding, helper_signal, + display_ratio); + + if (surround_sound) + temp_reg = SDO_CGMS625_SURROUND_SOUND_ENABLE; + else + temp_reg = SDO_CGMS625_SURROUND_SOUND_DISABLE; + + + if (copyright) + temp_reg |= SDO_CGMS625_COPYRIGHT; + else + temp_reg |= SDO_CGMS625_NO_COPYRIGHT; + + + if (copy_protection) + temp_reg |= SDO_CGMS625_COPY_RESTRICTED; + else + temp_reg |= SDO_CGMS625_COPY_NOT_RESTRICTED; + + + if (text_subtitles) + temp_reg |= SDO_CGMS625_TELETEXT_SUBTITLES; + else + temp_reg |= SDO_CGMS625_TELETEXT_NO_SUBTITLES; + + + switch (open_subtitles) { + + case SDO_625_NO_OPEN_SUBTITLES: + temp_reg |= SDO_CGMS625_NO_OPEN_SUBTITLES; + break; + + case SDO_625_INACT_OPEN_SUBTITLES: + temp_reg |= SDO_CGMS625_INACT_OPEN_SUBTITLES; + break; + + case SDO_625_OUTACT_OPEN_SUBTITLES: + temp_reg |= SDO_CGMS625_OUTACT_OPEN_SUBTITLES; + break; + + default: + SDPRINTK("invalid open_subtitles parameter(%d)\n\r", + open_subtitles); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + switch (camera_film) { + + case SDO_625_CAMERA: + temp_reg |= SDO_CGMS625_CAMERA; + break; + + case SDO_625_FILM: + temp_reg |= SDO_CGMS625_FILM; + break; + + default: + SDPRINTK(" invalid camera_film parameter(%d)\n\r", + camera_film); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + switch (color_encoding) { + + case SDO_625_NORMAL_PAL: + temp_reg |= SDO_CGMS625_NORMAL_PAL; + break; + + case SDO_625_MOTION_ADAPTIVE_COLORPLUS: + temp_reg |= SDO_CGMS625_MOTION_ADAPTIVE_COLORPLUS; + break; + + default: + SDPRINTK(" invalid color_encoding parameter(%d)\n\r", + color_encoding); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + if (helper_signal) + temp_reg |= SDO_CGMS625_HELPER_SIG; + else + temp_reg |= SDO_CGMS625_HELPER_NO_SIG; + + + switch (display_ratio) { + + case SDO_625_4_3_FULL_576: + temp_reg |= SDO_CGMS625_4_3_FULL_576; + break; + + case SDO_625_14_9_LETTERBOX_CENTER_504: + temp_reg |= SDO_CGMS625_14_9_LETTERBOX_CENTER_504; + break; + + case SDO_625_14_9_LETTERBOX_TOP_504: + temp_reg |= SDO_CGMS625_14_9_LETTERBOX_TOP_504; + break; + + case SDO_625_16_9_LETTERBOX_CENTER_430: + temp_reg |= SDO_CGMS625_16_9_LETTERBOX_CENTER_430; + break; + + case SDO_625_16_9_LETTERBOX_TOP_430: + temp_reg |= SDO_CGMS625_16_9_LETTERBOX_TOP_430; + break; + + case SDO_625_16_9_LETTERBOX_CENTER: + temp_reg |= SDO_CGMS625_16_9_LETTERBOX_CENTER; + break; + + case SDO_625_14_9_FULL_CENTER_576: + temp_reg |= SDO_CGMS625_14_9_FULL_CENTER_576; + break; + + case SDO_625_16_9_ANAMORPIC_576: + temp_reg |= SDO_CGMS625_16_9_ANAMORPIC_576; + break; + + default: + SDPRINTK("invalid display_ratio parameter(%d)\n\r", + display_ratio); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + writel(temp_reg, sdout_base + S5P_SDO_CGMS625); + + SDPRINTK("0x%08x\n\r", readl(sdout_base + S5P_SDO_CGMS625)); + + return SDOUT_NO_ERROR; +} + + +static enum s5p_tv_sd_err __s5p_sdout_init_antialias_filter_coeff_default( + enum s5p_sd_level composite_level, + enum s5p_sd_vsync_ratio composite_ratio, + enum s5p_tv_o_mode out_mode) +{ + SDPRINTK("%d, %d, %d\n\r", composite_level, composite_ratio, out_mode); + + switch (composite_level) { + + case S5P_TV_SD_LEVEL_0IRE: + + switch (composite_ratio) { + + case SDOUT_VTOS_RATIO_10_4: + + switch (out_mode) { + + case TVOUT_OUTPUT_COMPOSITE: + + case TVOUT_OUTPUT_SVIDEO: + writel(0x00000000 , sdout_base + S5P_SDO_Y3); + writel(0x00000000 , sdout_base + S5P_SDO_Y4); + writel(0x00000000 , sdout_base + S5P_SDO_Y5); + writel(0x00000000 , sdout_base + S5P_SDO_Y6); + writel(0x00000000 , sdout_base + S5P_SDO_Y7); + writel(0x00000000 , sdout_base + S5P_SDO_Y8); + writel(0x00000000 , sdout_base + S5P_SDO_Y9); + writel(0x00000000 , sdout_base + S5P_SDO_Y10); + writel(0x0000029a , sdout_base + S5P_SDO_Y11); + writel(0x00000000 , sdout_base + S5P_SDO_CB0); + writel(0x00000000 , sdout_base + S5P_SDO_CB1); + writel(0x00000000 , sdout_base + S5P_SDO_CB2); + writel(0x00000000 , sdout_base + S5P_SDO_CB3); + writel(0x00000000 , sdout_base + S5P_SDO_CB4); + writel(0x00000001 , sdout_base + S5P_SDO_CB5); + writel(0x00000007 , sdout_base + S5P_SDO_CB6); + writel(0x00000015 , sdout_base + S5P_SDO_CB7); + writel(0x0000002b , sdout_base + S5P_SDO_CB8); + writel(0x00000045 , sdout_base + S5P_SDO_CB9); + writel(0x00000059 , sdout_base + S5P_SDO_CB10); + writel(0x00000061 , sdout_base + S5P_SDO_CB11); + writel(0x00000000 , sdout_base + S5P_SDO_CR1); + writel(0x00000000 , sdout_base + S5P_SDO_CR2); + writel(0x00000000 , sdout_base + S5P_SDO_CR3); + writel(0x00000000 , sdout_base + S5P_SDO_CR4); + writel(0x00000002 , sdout_base + S5P_SDO_CR5); + writel(0x0000000a , sdout_base + S5P_SDO_CR6); + writel(0x0000001e , sdout_base + S5P_SDO_CR7); + writel(0x0000003d , sdout_base + S5P_SDO_CR8); + writel(0x00000061 , sdout_base + S5P_SDO_CR9); + writel(0x0000007a , sdout_base + S5P_SDO_CR10); + writel(0x0000008f , sdout_base + S5P_SDO_CR11); + break; + + case TVOUT_OUTPUT_COMPONENT_YPBPR_INERLACED: + + case TVOUT_OUTPUT_COMPONENT_YPBPR_PROGRESSIVE: + + case TVOUT_OUTPUT_COMPONENT_RGB_PROGRESSIVE: + writel(0x00000000, sdout_base + S5P_SDO_Y0); + writel(0x00000000, sdout_base + S5P_SDO_Y1); + writel(0x00000000, sdout_base + S5P_SDO_Y2); + writel(0x00000000, sdout_base + S5P_SDO_Y3); + writel(0x00000000, sdout_base + S5P_SDO_Y4); + writel(0x00000000, sdout_base + S5P_SDO_Y5); + writel(0x00000000, sdout_base + S5P_SDO_Y6); + writel(0x00000000, sdout_base + S5P_SDO_Y7); + writel(0x00000000, sdout_base + S5P_SDO_Y8); + writel(0x00000000, sdout_base + S5P_SDO_Y9); + writel(0x00000000, sdout_base + S5P_SDO_Y10); + writel(0x0000029a, sdout_base + S5P_SDO_Y11); + writel(0x00000000, sdout_base + S5P_SDO_CB0); + writel(0x00000000, sdout_base + S5P_SDO_CB1); + writel(0x00000000, sdout_base + S5P_SDO_CB2); + writel(0x00000000, sdout_base + S5P_SDO_CB3); + writel(0x00000000, sdout_base + S5P_SDO_CB4); + writel(0x00000001, sdout_base + S5P_SDO_CB5); + writel(0x00000007, sdout_base + S5P_SDO_CB6); + writel(0x00000015, sdout_base + S5P_SDO_CB7); + writel(0x0000002b, sdout_base + S5P_SDO_CB8); + writel(0x00000045, sdout_base + S5P_SDO_CB9); + writel(0x00000059, sdout_base + S5P_SDO_CB10); + writel(0x00000061, sdout_base + S5P_SDO_CB11); + writel(0x00000000, sdout_base + S5P_SDO_CR1); + writel(0x00000000, sdout_base + S5P_SDO_CR2); + writel(0x00000000, sdout_base + S5P_SDO_CR3); + writel(0x00000000, sdout_base + S5P_SDO_CR4); + writel(0x00000002, sdout_base + S5P_SDO_CR5); + writel(0x0000000a, sdout_base + S5P_SDO_CR6); + writel(0x0000001e, sdout_base + S5P_SDO_CR7); + writel(0x0000003d, sdout_base + S5P_SDO_CR8); + writel(0x00000061, sdout_base + S5P_SDO_CR9); + writel(0x0000007a, sdout_base + S5P_SDO_CR10); + writel(0x0000008f, sdout_base + S5P_SDO_CR11); + break; + + default: + SDPRINTK("invalid out_mode parameter(%d)\n\r", + out_mode); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + break; + + case SDOUT_VTOS_RATIO_7_3: + writel(0x00000000, sdout_base + S5P_SDO_Y0); + writel(0x00000000, sdout_base + S5P_SDO_Y1); + writel(0x00000000, sdout_base + S5P_SDO_Y2); + writel(0x00000000, sdout_base + S5P_SDO_Y3); + writel(0x00000000, sdout_base + S5P_SDO_Y4); + writel(0x00000000, sdout_base + S5P_SDO_Y5); + writel(0x00000000, sdout_base + S5P_SDO_Y6); + writel(0x00000000, sdout_base + S5P_SDO_Y7); + writel(0x00000000, sdout_base + S5P_SDO_Y8); + writel(0x00000000, sdout_base + S5P_SDO_Y9); + writel(0x00000000, sdout_base + S5P_SDO_Y10); + writel(0x00000281, sdout_base + S5P_SDO_Y11); + writel(0x00000000, sdout_base + S5P_SDO_CB0); + writel(0x00000000, sdout_base + S5P_SDO_CB1); + writel(0x00000000, sdout_base + S5P_SDO_CB2); + writel(0x00000000, sdout_base + S5P_SDO_CB3); + writel(0x00000000, sdout_base + S5P_SDO_CB4); + writel(0x00000001, sdout_base + S5P_SDO_CB5); + writel(0x00000007, sdout_base + S5P_SDO_CB6); + writel(0x00000015, sdout_base + S5P_SDO_CB7); + writel(0x0000002a, sdout_base + S5P_SDO_CB8); + writel(0x00000044, sdout_base + S5P_SDO_CB9); + writel(0x00000057, sdout_base + S5P_SDO_CB10); + writel(0x0000005f, sdout_base + S5P_SDO_CB11); + writel(0x00000000, sdout_base + S5P_SDO_CR1); + writel(0x00000000, sdout_base + S5P_SDO_CR2); + writel(0x00000000, sdout_base + S5P_SDO_CR3); + writel(0x00000000, sdout_base + S5P_SDO_CR4); + writel(0x00000002, sdout_base + S5P_SDO_CR5); + writel(0x0000000a, sdout_base + S5P_SDO_CR6); + writel(0x0000001d, sdout_base + S5P_SDO_CR7); + writel(0x0000003c, sdout_base + S5P_SDO_CR8); + writel(0x0000005f, sdout_base + S5P_SDO_CR9); + writel(0x0000007b, sdout_base + S5P_SDO_CR10); + writel(0x00000086, sdout_base + S5P_SDO_CR11); + break; + + default: + SDPRINTK("invalid composite_ratio parameter(%d)\n\r", + composite_ratio); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + break; + + case S5P_TV_SD_LEVEL_75IRE: + + switch (composite_ratio) { + + case SDOUT_VTOS_RATIO_10_4: + writel(0x00000000, sdout_base + S5P_SDO_Y0); + writel(0x00000000, sdout_base + S5P_SDO_Y1); + writel(0x00000000, sdout_base + S5P_SDO_Y2); + writel(0x00000000, sdout_base + S5P_SDO_Y3); + writel(0x00000000, sdout_base + S5P_SDO_Y4); + writel(0x00000000, sdout_base + S5P_SDO_Y5); + writel(0x00000000, sdout_base + S5P_SDO_Y6); + writel(0x00000000, sdout_base + S5P_SDO_Y7); + writel(0x00000000, sdout_base + S5P_SDO_Y8); + writel(0x00000000, sdout_base + S5P_SDO_Y9); + writel(0x00000000, sdout_base + S5P_SDO_Y10); + writel(0x0000025d, sdout_base + S5P_SDO_Y11); + writel(0x00000000, sdout_base + S5P_SDO_CB0); + writel(0x00000000, sdout_base + S5P_SDO_CB1); + writel(0x00000000, sdout_base + S5P_SDO_CB2); + writel(0x00000000, sdout_base + S5P_SDO_CB3); + writel(0x00000000, sdout_base + S5P_SDO_CB4); + writel(0x00000001, sdout_base + S5P_SDO_CB5); + writel(0x00000007, sdout_base + S5P_SDO_CB6); + writel(0x00000014, sdout_base + S5P_SDO_CB7); + writel(0x00000028, sdout_base + S5P_SDO_CB8); + writel(0x0000003f, sdout_base + S5P_SDO_CB9); + writel(0x00000052, sdout_base + S5P_SDO_CB10); + writel(0x0000005a, sdout_base + S5P_SDO_CB11); + writel(0x00000000, sdout_base + S5P_SDO_CR1); + writel(0x00000000, sdout_base + S5P_SDO_CR2); + writel(0x00000000, sdout_base + S5P_SDO_CR3); + writel(0x00000000, sdout_base + S5P_SDO_CR4); + writel(0x00000001, sdout_base + S5P_SDO_CR5); + writel(0x00000009, sdout_base + S5P_SDO_CR6); + writel(0x0000001c, sdout_base + S5P_SDO_CR7); + writel(0x00000039, sdout_base + S5P_SDO_CR8); + writel(0x0000005a, sdout_base + S5P_SDO_CR9); + writel(0x00000074, sdout_base + S5P_SDO_CR10); + writel(0x0000007e, sdout_base + S5P_SDO_CR11); + break; + + case SDOUT_VTOS_RATIO_7_3: + writel(0x00000000, sdout_base + S5P_SDO_Y0); + writel(0x00000000, sdout_base + S5P_SDO_Y1); + writel(0x00000000, sdout_base + S5P_SDO_Y2); + writel(0x00000000, sdout_base + S5P_SDO_Y3); + writel(0x00000000, sdout_base + S5P_SDO_Y4); + writel(0x00000000, sdout_base + S5P_SDO_Y5); + writel(0x00000000, sdout_base + S5P_SDO_Y6); + writel(0x00000000, sdout_base + S5P_SDO_Y7); + writel(0x00000000, sdout_base + S5P_SDO_Y8); + writel(0x00000000, sdout_base + S5P_SDO_Y9); + writel(0x00000000, sdout_base + S5P_SDO_Y10); + writel(0x00000251, sdout_base + S5P_SDO_Y11); + writel(0x00000000, sdout_base + S5P_SDO_CB0); + writel(0x00000000, sdout_base + S5P_SDO_CB1); + writel(0x00000000, sdout_base + S5P_SDO_CB2); + writel(0x00000000, sdout_base + S5P_SDO_CB3); + writel(0x00000000, sdout_base + S5P_SDO_CB4); + writel(0x00000001, sdout_base + S5P_SDO_CB5); + writel(0x00000006, sdout_base + S5P_SDO_CB6); + writel(0x00000013, sdout_base + S5P_SDO_CB7); + writel(0x00000028, sdout_base + S5P_SDO_CB8); + writel(0x0000003f, sdout_base + S5P_SDO_CB9); + writel(0x00000051, sdout_base + S5P_SDO_CB10); + writel(0x00000056, sdout_base + S5P_SDO_CB11); + writel(0x00000000, sdout_base + S5P_SDO_CR1); + writel(0x00000000, sdout_base + S5P_SDO_CR2); + writel(0x00000000, sdout_base + S5P_SDO_CR3); + writel(0x00000000, sdout_base + S5P_SDO_CR4); + writel(0x00000002, sdout_base + S5P_SDO_CR5); + writel(0x00000005, sdout_base + S5P_SDO_CR6); + writel(0x00000018, sdout_base + S5P_SDO_CR7); + writel(0x00000037, sdout_base + S5P_SDO_CR8); + writel(0x0000005A, sdout_base + S5P_SDO_CR9); + writel(0x00000076, sdout_base + S5P_SDO_CR10); + writel(0x0000007e, sdout_base + S5P_SDO_CR11); + break; + + default: + SDPRINTK(" invalid composite_ratio parameter(%d)\n\r", + composite_ratio); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + break; + + default: + SDPRINTK(" invalid composite_level parameter(%d)\n\r", + composite_level); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + SDPRINTK("()\n\r"); + + return SDOUT_NO_ERROR; + +} + + +static enum s5p_tv_sd_err __s5p_sdout_init_oversampling_filter_coeff_default( + enum s5p_tv_o_mode out_mode) +{ + + SDPRINTK("%d\n\r", out_mode); + + switch (out_mode) { + + case TVOUT_OUTPUT_COMPOSITE: + + case TVOUT_OUTPUT_SVIDEO: + + case TVOUT_OUTPUT_COMPONENT_YPBPR_INERLACED: + /* + temp_reg = (u32)(sdout_base + S5P_SDO_OSFC00_0); + + for (i = 0; i < 3; i++) { + + temp_reg = (u32)((i == 0) ? + sdout_base + S5P_SDO_OSFC00_0 : + (i == 1) ? sdout_base + S5P_SDO_OSFC00_1 : + sdout_base + S5P_SDO_OSFC00_2); + + writel(((-2&0xfff) << 0) | ((-3&0xfff) << 0), + temp_reg + 0); + writel(0, + temp_reg + 1); + writel((4 << 0) | (5 << 16), + temp_reg + 2); + writel(((-1&0xfff) << 0) | (0 << 16), + temp_reg + 3); + writel(((-6&0xfff) << 0) | ((-9&0xfff) << 16), + temp_reg + 4); + writel((1 << 0) | (0 << 16), + temp_reg + 5); + writel((10 << 0) | (14 << 16), + temp_reg + 6); + writel(((-1&0xfff) << 0) | (0 << 16), + temp_reg + 7); + writel(((-14&0xfff) << 0) | ((-20&0xfff) << 16), + temp_reg + 8); + writel((1 << 0) | (0 << 16), + temp_reg + 9); + writel((20 << 0) | (29 << 16), + temp_reg + 10); + writel(((-2&0xfff) << 0) | (0 << 16), + temp_reg + 11); + writel(((-28&0xfff) << 0) | ((-40&0xfff) << 16), + temp_reg + 12); + writel((2 << 0) | (0 << 16), + temp_reg + 13); + writel((40 << 0) | (56 << 16), + temp_reg + 14); + writel(((-3&0xfff) << 0) | (0 << 16), + temp_reg + 15); + writel(((-57&0xfff) << 0) | ((-80&0xfff) << 16), + temp_reg + 16); + writel((5 << 0) | (0 << 16), + temp_reg + 17); + writel((86 << 0) | (121 << 16), + temp_reg + 18); + writel(((-10&0xfff) << 0) | (0 << 16), + temp_reg + 19); + writel(((-154&0xfff) << 0) | ((-212&0xfff) << 16), + temp_reg + 20); + writel((27 << 0) | (0 << 16), + temp_reg + 21); + writel((613 << 0) | (651 << 16), + temp_reg + 22); + writel(((-308&0xfff) << 0) | (1024 << 16), + temp_reg + 23); + } +*/ + break; + + default: + SDPRINTK("invalid out_mode parameter(%d)\n\r", out_mode); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + return SDOUT_NO_ERROR; +} + +/* +* initialization +* - iniization functions are only called under stopping sdout +*/ +enum s5p_tv_sd_err __s5p_sdout_init_display_mode( + enum s5p_tv_disp_mode disp_mode, + enum s5p_tv_o_mode out_mode, + enum s5p_sd_order order) +{ + u32 temp_reg = 0; + + SDPRINTK(" %d, %d, %d\n\r", disp_mode, out_mode, order); + + switch (disp_mode) { + + case TVOUT_NTSC_M: + temp_reg |= SDO_NTSC_M; + __s5p_sdout_init_video_scale_cfg(S5P_TV_SD_LEVEL_0IRE, + SDOUT_VTOS_RATIO_7_3, S5P_TV_SD_LEVEL_75IRE, + SDOUT_VTOS_RATIO_10_4); + + __s5p_sdout_init_antialias_filter_coeff_default( + S5P_TV_SD_LEVEL_75IRE, + SDOUT_VTOS_RATIO_10_4, + out_mode); + break; + + case TVOUT_PAL_BDGHI: + temp_reg |= SDO_PAL_BGHID; + __s5p_sdout_init_video_scale_cfg(S5P_TV_SD_LEVEL_0IRE, + SDOUT_VTOS_RATIO_7_3, S5P_TV_SD_LEVEL_0IRE, + SDOUT_VTOS_RATIO_7_3); + + __s5p_sdout_init_antialias_filter_coeff_default( + S5P_TV_SD_LEVEL_0IRE, + SDOUT_VTOS_RATIO_7_3, out_mode); + break; + + case TVOUT_PAL_M: + temp_reg |= SDO_PAL_M; + __s5p_sdout_init_video_scale_cfg(S5P_TV_SD_LEVEL_0IRE, + SDOUT_VTOS_RATIO_7_3, S5P_TV_SD_LEVEL_0IRE, + SDOUT_VTOS_RATIO_7_3); + + __s5p_sdout_init_antialias_filter_coeff_default( + S5P_TV_SD_LEVEL_0IRE, + SDOUT_VTOS_RATIO_7_3, + out_mode); + break; + + case TVOUT_PAL_N: + temp_reg |= SDO_PAL_N; + __s5p_sdout_init_video_scale_cfg(S5P_TV_SD_LEVEL_0IRE, + SDOUT_VTOS_RATIO_7_3, S5P_TV_SD_LEVEL_0IRE, + SDOUT_VTOS_RATIO_7_3); + + __s5p_sdout_init_antialias_filter_coeff_default( + S5P_TV_SD_LEVEL_75IRE, + SDOUT_VTOS_RATIO_10_4, + out_mode); + break; + + case TVOUT_PAL_NC: + temp_reg |= SDO_PAL_NC; + __s5p_sdout_init_video_scale_cfg(S5P_TV_SD_LEVEL_0IRE, + SDOUT_VTOS_RATIO_7_3, S5P_TV_SD_LEVEL_0IRE, + SDOUT_VTOS_RATIO_7_3); + + __s5p_sdout_init_antialias_filter_coeff_default( + S5P_TV_SD_LEVEL_0IRE, + SDOUT_VTOS_RATIO_7_3, + out_mode); + break; + + case TVOUT_PAL_60: + temp_reg |= SDO_PAL_60; + __s5p_sdout_init_video_scale_cfg(S5P_TV_SD_LEVEL_0IRE, + SDOUT_VTOS_RATIO_7_3, S5P_TV_SD_LEVEL_0IRE, + SDOUT_VTOS_RATIO_7_3); + __s5p_sdout_init_antialias_filter_coeff_default( + S5P_TV_SD_LEVEL_0IRE, + SDOUT_VTOS_RATIO_7_3, + out_mode); + break; + + case TVOUT_NTSC_443: + temp_reg |= SDO_NTSC_443; + __s5p_sdout_init_video_scale_cfg(S5P_TV_SD_LEVEL_0IRE, + SDOUT_VTOS_RATIO_7_3, S5P_TV_SD_LEVEL_75IRE, + SDOUT_VTOS_RATIO_10_4); + __s5p_sdout_init_antialias_filter_coeff_default( + S5P_TV_SD_LEVEL_75IRE, + SDOUT_VTOS_RATIO_10_4, + out_mode); + break; + + default: + SDPRINTK("invalid disp_mode parameter(%d)\n\r", disp_mode); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + switch (out_mode) { + + case TVOUT_OUTPUT_COMPOSITE: + + case TVOUT_OUTPUT_SVIDEO: + temp_reg |= SDO_COMPOSITE | SDO_INTERLACED; + + switch (order) { + + case S5P_TV_SD_O_ORDER_COMPOSITE_CVBS_Y_C: + temp_reg |= SDO_DAC2_CVBS | SDO_DAC1_Y | SDO_DAC0_C; + break; + + case S5P_TV_SD_O_ORDER_COMPOSITE_CVBS_C_Y: + temp_reg |= SDO_DAC2_CVBS | SDO_DAC1_C | SDO_DAC0_Y; + break; + + case S5P_TV_SD_O_ORDER_COMPOSITE_Y_C_CVBS: + temp_reg |= SDO_DAC2_Y | SDO_DAC1_C | SDO_DAC0_CVBS; + break; + + case S5P_TV_SD_O_ORDER_COMPOSITE_Y_CVBS_C: + temp_reg |= SDO_DAC2_Y | SDO_DAC1_CVBS | SDO_DAC0_C; + break; + + case S5P_TV_SD_O_ORDER_COMPOSITE_C_CVBS_Y: + temp_reg |= SDO_DAC2_C | SDO_DAC1_CVBS | SDO_DAC0_Y; + break; + + case S5P_TV_SD_O_ORDER_COMPOSITE_C_Y_CVBS: + temp_reg |= SDO_DAC2_C | SDO_DAC1_Y | SDO_DAC0_CVBS; + break; + + default: + SDPRINTK(" invalid order parameter(%d)\n\r", order); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + break; + + case TVOUT_OUTPUT_COMPONENT_YPBPR_INERLACED: + temp_reg |= SDO_COMPONENT | SDO_YPBPR | SDO_INTERLACED; + + switch (order) { + + case S5P_TV_SD_O_ORDER_COMPONENT_RGB_PRYPB: + temp_reg |= SDO_DAC2_PR_R | SDO_DAC1_Y_G | + SDO_DAC0_PB_B; + break; + + case S5P_TV_SD_O_ORDER_COMPONENT_RBG_PRPBY: + temp_reg |= SDO_DAC2_PR_R | SDO_DAC1_PB_B | + SDO_DAC0_Y_G; + break; + + case S5P_TV_SD_O_ORDER_COMPONENT_BGR_PBYPR: + temp_reg |= SDO_DAC2_PB_B | SDO_DAC1_Y_G | + SDO_DAC0_PR_R; + break; + + case S5P_TV_SD_O_ORDER_COMPONENT_BRG_PBPRY: + temp_reg |= SDO_DAC2_PB_B | SDO_DAC1_PR_R | + SDO_DAC0_Y_G; + break; + + case S5P_TV_SD_O_ORDER_COMPONENT_GRB_YPRPB: + temp_reg |= SDO_DAC2_Y_G | SDO_DAC1_PR_R | + SDO_DAC0_PB_B; + break; + + case S5P_TV_SD_O_ORDER_COMPONENT_GBR_YPBPR: + temp_reg |= SDO_DAC2_Y_G | SDO_DAC1_PB_B | + SDO_DAC0_PR_R; + break; + + default: + SDPRINTK(" invalid order parameter(%d)\n\r", order); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + break; + + case TVOUT_OUTPUT_COMPONENT_YPBPR_PROGRESSIVE: + temp_reg |= SDO_COMPONENT | SDO_YPBPR | SDO_PROGRESSIVE; + + switch (order) { + + case S5P_TV_SD_O_ORDER_COMPONENT_RGB_PRYPB: + temp_reg |= SDO_DAC2_PR_R | SDO_DAC1_Y_G | + SDO_DAC0_PB_B; + break; + + case S5P_TV_SD_O_ORDER_COMPONENT_RBG_PRPBY: + temp_reg |= SDO_DAC2_PR_R | SDO_DAC1_PB_B | + SDO_DAC0_Y_G; + break; + + case S5P_TV_SD_O_ORDER_COMPONENT_BGR_PBYPR: + temp_reg |= SDO_DAC2_PB_B | SDO_DAC1_Y_G | + SDO_DAC0_PR_R; + break; + + case S5P_TV_SD_O_ORDER_COMPONENT_BRG_PBPRY: + temp_reg |= SDO_DAC2_PB_B | SDO_DAC1_PR_R | + SDO_DAC0_Y_G; + break; + + case S5P_TV_SD_O_ORDER_COMPONENT_GRB_YPRPB: + temp_reg |= SDO_DAC2_Y_G | SDO_DAC1_PR_R | + SDO_DAC0_PB_B; + break; + + case S5P_TV_SD_O_ORDER_COMPONENT_GBR_YPBPR: + temp_reg |= SDO_DAC2_Y_G | SDO_DAC1_PB_B | + SDO_DAC0_PR_R; + break; + + default: + SDPRINTK(" invalid order parameter(%d)\n\r", order); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + break; + + case TVOUT_OUTPUT_COMPONENT_RGB_PROGRESSIVE: + temp_reg |= SDO_COMPONENT | SDO_RGB | SDO_PROGRESSIVE; + + switch (order) { + + case S5P_TV_SD_O_ORDER_COMPONENT_RGB_PRYPB: + temp_reg |= SDO_DAC2_PR_R | SDO_DAC1_Y_G | + SDO_DAC0_PB_B; + break; + + case S5P_TV_SD_O_ORDER_COMPONENT_RBG_PRPBY: + temp_reg |= SDO_DAC2_PR_R | SDO_DAC1_PB_B | + SDO_DAC0_Y_G; + break; + + case S5P_TV_SD_O_ORDER_COMPONENT_BGR_PBYPR: + temp_reg |= SDO_DAC2_PB_B | SDO_DAC1_Y_G | + SDO_DAC0_PR_R; + break; + + case S5P_TV_SD_O_ORDER_COMPONENT_BRG_PBPRY: + temp_reg |= SDO_DAC2_PB_B | SDO_DAC1_PR_R | + SDO_DAC0_Y_G; + break; + + case S5P_TV_SD_O_ORDER_COMPONENT_GRB_YPRPB: + temp_reg |= SDO_DAC2_Y_G | SDO_DAC1_PR_R | + SDO_DAC0_PB_B; + break; + + case S5P_TV_SD_O_ORDER_COMPONENT_GBR_YPBPR: + temp_reg |= SDO_DAC2_Y_G | SDO_DAC1_PB_B | + SDO_DAC0_PR_R; + break; + + default: + SDPRINTK("invalid order parameter(%d)\n\r", order); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + break; + + default: + SDPRINTK(" invalid out_mode parameter(%d)\n\r", out_mode); + return S5P_TV_SD_ERR_INVALID_PARAM; + break; + } + + __s5p_sdout_init_oversampling_filter_coeff_default(out_mode); + + writel(temp_reg, sdout_base + S5P_SDO_CONFIG); + + SDPRINTK("0x%08x\n\r", readl(sdout_base + S5P_SDO_CONFIG)); + + return SDOUT_NO_ERROR; +} + +/* +* start - start functions are only called under stopping SDOUT +*/ +void __s5p_sdout_start(void) +{ + SDPRINTK("()\n\r"); + + writel(SDO_TVOUT_CLOCK_ON, sdout_base + S5P_SDO_CLKCON); + + SDPRINTK("0x%x\n\r", readl(sdout_base + S5P_SDO_CLKCON)); +} + +/* +/ stop - stop functions are only called under running SDOUT +*/ +void __s5p_sdout_stop(void) +{ + SDPRINTK("()\n\r"); + + mdelay(100); + + writel(SDO_TVOUT_CLOCK_OFF, sdout_base + S5P_SDO_CLKCON); + + SDPRINTK(" 0x%x)\n\r", readl(sdout_base + S5P_SDO_CLKCON)); +} + +/* +* reset +* - reset function +*/ +void __s5p_sdout_sw_reset(bool active) +{ + SDPRINTK("%d\n\r", active); + + if (active) + writel(readl(sdout_base + S5P_SDO_CLKCON) | SDO_TVOUT_SW_RESET, + sdout_base + S5P_SDO_CLKCON); + else + writel(readl(sdout_base + S5P_SDO_CLKCON) & + ~SDO_TVOUT_SW_RESET, + sdout_base + S5P_SDO_CLKCON); + + SDPRINTK(" 0x%x\n\r", readl(sdout_base + S5P_SDO_CLKCON)); +} + + +void __s5p_sdout_set_interrupt_enable(bool vsync_intr_en) +{ + SDPRINTK("%d)\n\r", vsync_intr_en); + + if (vsync_intr_en) + writel(readl(sdout_base + S5P_SDO_IRQMASK) & + ~SDO_VSYNC_IRQ_DISABLE, + sdout_base + S5P_SDO_IRQMASK); + else + writel(readl(sdout_base + S5P_SDO_IRQMASK) | + SDO_VSYNC_IRQ_DISABLE, + sdout_base + S5P_SDO_IRQMASK); + + SDPRINTK("0x%x)\n\r", readl(sdout_base + S5P_SDO_IRQMASK)); +} + +void __s5p_sdout_clear_interrupt_pending(void) +{ + SDPRINTK("0x%x\n\r", readl(sdout_base + S5P_SDO_IRQ)); + + writel(readl(sdout_base + S5P_SDO_IRQ) | SDO_VSYNC_IRQ_PEND, + sdout_base + S5P_SDO_IRQ); + + SDPRINTK("0x%x\n\r", readl(sdout_base + S5P_SDO_IRQ)); +} + +bool __s5p_sdout_get_interrupt_pending(void) +{ + SDPRINTK(" 0x%x\n\r", readl(sdout_base + S5P_SDO_IRQ)); + + return (readl(sdout_base + S5P_SDO_IRQ) | SDO_VSYNC_IRQ_PEND) ? 1 : 0; +} + +int __init __s5p_sdout_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; + + sdout_mem = request_mem_region(res->start, size, pdev->name); + + if (sdout_mem == NULL) { + dev_err(&pdev->dev, + "failed to get memory region\n"); + goto error; + } + + sdout_base = ioremap(res->start, size); + + if (sdout_base == NULL) { + dev_err(&pdev->dev, + "failed to ioremap address region\n"); + goto error; + + } + + return 0; +error: + return -ENOENT; + +} + +int __init __s5p_sdout_release(struct platform_device *pdev) +{ + iounmap(sdout_base); + + /* remove memory region */ + if (sdout_mem != NULL) { + if (release_resource(sdout_mem)) + dev_err(&pdev->dev, + "Can't remove tvout drv !!\n"); + + kfree(sdout_mem); + + sdout_mem = NULL; + } + + return 0; +} diff --git a/drivers/media/video/samsung/tv20/s5pv210/tv_clock_s5pv210.c b/drivers/media/video/samsung/tv20/s5pv210/tv_clock_s5pv210.c new file mode 100644 index 0000000..c0de6b3 --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5pv210/tv_clock_s5pv210.c @@ -0,0 +1,286 @@ +/* linux/drivers/media/video/samsung/tv20/s5pv210/tv_clock_s5pc110.c + * + * Copyright (c) 2010 Samsung Electronics + * http://www.samsung.com/ + * + * clock 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/delay.h> +#include <linux/platform_device.h> +#include <linux/clk.h> +#include <linux/uaccess.h> +#include <linux/io.h> + +#include <mach/map.h> +#include <mach/regs-clock.h> + +#include "tv_out_s5pv210.h" +#include "regs/regs-clock_extra.h" + +#ifdef COFIG_TVOUT_RAW_DBG +#define S5P_TVOUT_CLK_DEBUG 1 +#endif + +#ifdef S5P_TVOUT_CLK_DEBUG +#define TVCLKPRINTK(fmt, args...) \ + printk(KERN_INFO "\t\t[TVCLK] %s: " fmt, __func__ , ## args) +#else +#define TVCLKPRINTK(fmt, args...) +#endif + +void __s5p_tv_clk_init_hpll(unsigned int lock_time, + bool vsel, + unsigned int mdiv, + unsigned int pdiv, + unsigned int sdiv) +{ + u32 temp; + + TVCLKPRINTK("%d,%d,%d,%d\n\r", lock_time, mdiv, pdiv, sdiv); + + temp = readl(S5P_VPLL_CON); + + temp &= ~VPLL_ENABLE; + + writel(temp, S5P_VPLL_CON); + + temp = 0; + + if (vsel) + temp |= VCO_FREQ_SEL; + + temp |= VPLL_ENABLE; + temp |= MDIV(mdiv) | PDIV(pdiv) | SDIV(sdiv); + + writel(VPLL_LOCKTIME(lock_time), S5P_VPLL_LOCK); + writel(temp, S5P_VPLL_CON); + + while (!VPLL_LOCKED(readl(S5P_VPLL_CON))); + + TVCLKPRINTK("0x%08x,0x%08x\n\r", readl(S5P_VPLL_LOCK), \ + readl(S5P_VPLL_CON)); +} + +void __s5p_tv_clk_hpll_onoff(bool en) +{ +} + +s5p_tv_clk_err __s5p_tv_clk_init_href(s5p_tv_clk_hpll_ref hpll_ref) +{ + return S5P_TV_CLK_ERR_NO_ERROR; +} + +/* prevent hdmi hang-up when reboot */ +int __s5p_tv_clk_change_internal(void) +{ + u32 reg = readl(S5P_CLK_SRC1); + /* set to SCLK_DAC */ + reg &= HDMI_SEL_MASK; + /* set to SCLK_PIXEL */ + reg &= VMIXER_SEL_MASK; + + writel(reg, S5P_CLK_SRC1); + + return 0; +} + +s5p_tv_clk_err __s5p_tv_clk_init_mout_hpll(s5p_tv_clk_mout_hpll mout_hpll) +{ + TVCLKPRINTK("(%d)\n\r", mout_hpll); + + writel(readl(S5P_CLK_SRC1) | HDMI_SEL_HDMIPHY, S5P_CLK_SRC1); + + TVCLKPRINTK("S5P_CLK_SRC1 :0x%08x\n", readl(S5P_CLK_SRC1)); + return S5P_TV_CLK_ERR_NO_ERROR; +} + +s5p_tv_clk_err __s5p_tv_clk_init_video_mixer(s5p_tv_clk_vmiexr_srcclk src_clk) +{ + switch (src_clk) { + + /* for analog tv out 0:SCLK_DAC */ + case TVOUT_CLK_VMIXER_SRCCLK_VCLK_54: + writel(readl(S5P_CLK_SRC1) & VMIXER_SEL_MASK, S5P_CLK_SRC1); + break; + + /* for digital hdmi_phy 1: SCLK_HDMI */ + case TVOUT_CLK_VMIXER_SRCCLK_MOUT_HPLL: + writel(readl(S5P_CLK_SRC1) | VMIXER_SEL_MOUT_VPLL, \ + S5P_CLK_SRC1); + break; + + default: + TVCLKPRINTK("[ERR] invalid src_clk parameter = %d\n", src_clk); + return S5P_TV_CLK_ERR_INVALID_PARAM; + break; + } + + TVCLKPRINTK("S5P_CLK_SRC1 :0x%08x\n", readl(S5P_CLK_SRC1)); + + return S5P_TV_CLK_ERR_NO_ERROR; +} + +void __s5p_tv_clk_init_hdmi_ratio(unsigned int clk_div) +{ + TVCLKPRINTK("(%d)\n\r", clk_div); + + writel((readl(S5P_CLK_DIV1) & HDMI_DIV_RATIO_MASK) | \ + HDMI_DIV_RATIO(clk_div), S5P_CLK_DIV1); + + TVCLKPRINTK("(0x%08x)\n\r", readl(S5P_CLK_DIV3)); +} + +/* + * hclk gating + */ + +/* VP */ +void __s5p_tv_clk_set_vp_clk_onoff(bool clk_on) +{ + /* + TVCLKPRINTK("VP hclk : %s\n\r", clk_on ? "on":"off"); + + if (clk_on) + bit_add_l(S5P_CLKGATE_IP1_VP, S5P_CLKGATE_IP1); + else + bit_del_l(S5P_CLKGATE_IP1_VP, S5P_CLKGATE_IP1); + + TVCLKPRINTK("S5P_CLKGATE_MAIN1 :0x%08x\n\r", readl(S5P_CLKGATE_MAIN1)); + */ +} + +/* MIXER */ +void __s5p_tv_clk_set_vmixer_hclk_onoff(bool clk_on) +{ + /* + TVCLKPRINTK("MIXER hclk : %s\n\r", clk_on ? "on":"off"); + + if (clk_on) + bit_add_l(S5P_CLKGATE_IP1_MIXER, S5P_CLKGATE_IP1); + else + bit_del_l(S5P_CLKGATE_IP1_MIXER, S5P_CLKGATE_IP1); + + TVCLKPRINTK("S5P_CLKGATE_MAIN1 :0x%08x\n\r", readl(S5P_CLKGATE_MAIN1)); + */ +} + +/* TVENC */ +void __s5p_tv_clk_set_sdout_hclk_onoff(bool clk_on) +{ + /* + TVCLKPRINTK("TVENC hclk : %s\n\r", clk_on ? "on":"off"); + + if (clk_on) + bit_add_l(S5P_CLKGATE_IP1_TVENC, S5P_CLKGATE_IP1); + else + bit_del_l(S5P_CLKGATE_IP1_TVENC, S5P_CLKGATE_IP1); + */ +} + +/* HDMI */ +void __s5p_tv_clk_set_hdmi_hclk_onoff(bool clk_on) +{ + /* + TVCLKPRINTK("HDMI hclk : %s\n\r", clk_on ? "on":"off"); + + if (clk_on) { + bit_add_l(S5P_CLKGATE_IP1_HDMI, S5P_CLKGATE_IP1); + bit_add_l(VMIXER_OUT_SEL_HDMI, S5P_MIXER_OUT_SEL); + } else + bit_del_l(S5P_CLKGATE_IP1_HDMI, S5P_CLKGATE_IP1); + + TVCLKPRINTK("S5P_CLKGATE_PERI1 :0x%08x\n\r", readl(S5P_CLKGATE_PERI1)); + TVCLKPRINTK("clk output is %s\n\r", readl(S5P_MIXER_OUT_SEL) ? "HDMI":"SDOUT"); + */ +} + +/* + * sclk gating + */ + +/* MIXER */ +void __s5p_tv_clk_set_vmixer_sclk_onoff(bool clk_on) +{ +#if 0 + TVCLKPRINTK("MIXER sclk : %s\n\r", clk_on ? "on":"off"); + + if (clk_on) + bit_add_l(CLK_SCLK_VMIXER_PASS, S5P_SCLKGATE0); + else + bit_del_l(CLK_SCLK_VMIXER_PASS, S5P_SCLKGATE0); + + TVCLKPRINTK("S5P_SCLKGATE0 :0x%08x\n\r", readl(S5P_SCLKGATE0)); +#endif +} + +/* TVENC */ +void __s5p_tv_clk_set_sdout_sclk_onoff(bool clk_on) +{ +#if 0 + TVCLKPRINTK("TVENC sclk : %s\n\r", clk_on ? "on":"off"); + + if (clk_on) + bit_add_l(CLK_SCLK_TV54_PASS | CLK_SCLK_VDAC54_PASS, S5P_SCLKGATE0); + else + bit_del_l(CLK_SCLK_TV54_PASS | CLK_SCLK_VDAC54_PASS, S5P_SCLKGATE0); + + TVCLKPRINTK("S5P_SCLKGATE0 :0x%08x\n\r", readl(S5P_SCLKGATE0)); +#endif +} + +/* HDMI */ +void __s5p_tv_clk_set_hdmi_sclk_onoff(bool clk_on) +{ +#if 0 + TVCLKPRINTK("HDMI sclk : %s\n\r", clk_on ? "on":"off"); + + if (clk_on) + bit_add_l(CLK_SCLK_HDMI_PASS, S5P_SCLKGATE0); + else + bit_del_l(CLK_SCLK_HDMI_PASS, S5P_SCLKGATE0); + + TVCLKPRINTK("S5P_SCLKGATE0 :0x%08x\n\r", readl(S5P_SCLKGATE0)); +#endif +} + +void __s5p_tv_clk_start(bool vp, bool sdout, bool hdmi) +{ + __s5p_tv_clk_set_vp_clk_onoff(vp); + __s5p_tv_clk_set_sdout_hclk_onoff(sdout); + __s5p_tv_clk_set_sdout_sclk_onoff(sdout); + __s5p_tv_clk_set_hdmi_hclk_onoff(hdmi); + __s5p_tv_clk_set_vmixer_hclk_onoff(true); + __s5p_tv_clk_set_vmixer_sclk_onoff(true); + + if (hdmi) + __s5p_tv_clk_hpll_onoff(true); +} + +void __s5p_tv_clk_stop(void) +{ + __s5p_tv_clk_set_sdout_sclk_onoff(false); + __s5p_tv_clk_set_sdout_hclk_onoff(false); + __s5p_tv_clk_set_hdmi_sclk_onoff(false); + __s5p_tv_clk_set_hdmi_hclk_onoff(false); + __s5p_tv_clk_set_vp_clk_onoff(false); + __s5p_tv_clk_set_vmixer_sclk_onoff(false); + __s5p_tv_clk_set_vmixer_hclk_onoff(false); + __s5p_tv_clk_hpll_onoff(false); +} + +int __init __s5p_tvclk_probe(struct platform_device *pdev, u32 res_num) +{ + return 0; +} + +int __init __s5p_tvclk_release(struct platform_device *pdev) +{ + return 0; +} diff --git a/drivers/media/video/samsung/tv20/s5pv210/tv_out_s5pv210.h b/drivers/media/video/samsung/tv20/s5pv210/tv_out_s5pv210.h new file mode 100644 index 0000000..fd326dd --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5pv210/tv_out_s5pv210.h @@ -0,0 +1,597 @@ +/* linux/drivers/media/video/samsung/tv20/s5pv210/tv_out_s5pv210.h + * + * tv out header file for Samsung TVOut driver + * + * Copyright (c) 2010 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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/i2c.h> +#include <linux/slab.h> +#include <linux/mm.h> +/* #define COFIG_TVOUT_RAW_DBG */ + + +#define HDMI_START_NUM 0x1000 + +#define bit_add_l(val, addr) writel(readl(addr) | val, addr) +#define bit_add_s(val, addr) writes(reads(addr) | val, addr) +#define bit_add_b(val, addr) writeb(readb(addr) | val, addr) +#define bit_del_l(val, addr) writel(readl(addr) & ~val, addr) +#define bit_del_s(val, addr) writes(reads(addr) & ~val, addr) +#define bit_del_b(val, addr) writeb(readb(addr) & ~val, addr) + + +enum s5p_tv_audio_codec_type { + PCM = 1, AC3, MP3, WMA +}; + +enum s5p_endian_type { + TVOUT_LITTLE_ENDIAN_MODE = 0, + TVOUT_BIG_ENDIAN_MODE = 1 +}; + +enum s5p_tv_disp_mode { + TVOUT_NTSC_M = 0, + TVOUT_PAL_BDGHI, + TVOUT_PAL_M, + TVOUT_PAL_N, + TVOUT_PAL_NC, + TVOUT_PAL_60, + TVOUT_NTSC_443, + + TVOUT_480P_60_16_9 = HDMI_START_NUM, + TVOUT_480P_60_4_3, + TVOUT_480P_59, + + TVOUT_576P_50_16_9, + TVOUT_576P_50_4_3, + + TVOUT_720P_60, + TVOUT_720P_50, + TVOUT_720P_59, + + TVOUT_1080P_60, + TVOUT_1080P_50, + TVOUT_1080P_59, + TVOUT_1080P_30, + + TVOUT_1080I_60, + TVOUT_1080I_50, + TVOUT_1080I_59, +}; + +enum s5p_tv_o_mode { + TVOUT_OUTPUT_COMPOSITE, + TVOUT_OUTPUT_SVIDEO, + TVOUT_OUTPUT_COMPONENT_YPBPR_INERLACED, + TVOUT_OUTPUT_COMPONENT_YPBPR_PROGRESSIVE, + TVOUT_OUTPUT_COMPONENT_RGB_PROGRESSIVE, + TVOUT_OUTPUT_HDMI, + TVOUT_OUTPUT_HDMI_RGB, + TVOUT_OUTPUT_DVI +}; + +enum s5p_tv_pwr_err { + S5P_TV_PWR_ERR_NO_ERROR = 0, + S5P_TV_PWR_ERR_NOT_INIT_PARAMETERS_UNDER_RUNNING = 0x5000, + S5P_TV_PWR_ERR_NOT_SET_PARAMETERS_UNDER_STOP, + S5P_TV_PWR_ERR_INVALID_PARAM +}; + +enum s5p_tv_clk_err { + S5P_TV_CLK_ERR_NO_ERROR = 0, + S5P_TV_CLK_ERR_NOT_INIT_PARAMETERS_UNDER_RUNNING = 0x4000, + S5P_TV_CLK_ERR_NOT_SET_PARAMETERS_UNDER_STOP, + S5P_TV_CLK_ERR_INVALID_PARAM +}; + +enum s5p_tv_vp_err { + VPROC_NO_ERROR = 0, + S5P_TV_VP_ERR_NOT_INIT_PARAMETERS_UNDER_RUNNING = 0x2000, + S5P_TV_VP_ERR_NOT_SET_PARAMETERS_UNDER_STOP, + S5P_TV_VP_ERR_BASE_ADDRESS_MUST_DOUBLE_WORD_ALIGN, + S5P_TV_VP_ERR_NOT_UPDATE_FOR_ANOTHER_UPDATE, + S5P_TV_VP_ERR_INVALID_PARAM +}; + +enum s5p_tv_vmx_err { + VMIXER_NO_ERROR = 0, + S5P_TV_VMX_ERR_NOT_INIT_PARAMETERS_UNDER_RUNNING = 0x1000, + S5P_TV_VMX_ERR_NOT_SET_PARAMETERS_UNDER_STOP, + S5P_TV_VMX_ERR_BASE_ADDRESS_MUST_WORD_ALIGN, + S5P_TV_VMX_ERR_INVALID_PARAM +}; + +enum s5p_tv_vmx_color_fmt { + VM_DIRECT_RGB565 = 4, + VM_DIRECT_RGB1555 = 5, + VM_DIRECT_RGB4444 = 6, + VM_DIRECT_RGB8888 = 7 +}; + +enum s5p_tv_sd_err { + SDOUT_NO_ERROR = 0, + S5P_TV_SD_ERR_NOT_INIT_PARAMETERS_UNDER_RUNNING = 0x3000, + S5P_TV_SD_ERR_NOT_SET_PARAMETERS_UNDER_STOP, + S5P_TV_SD_ERR_INVALID_PARAM +}; + +enum s5p_sd_order { + S5P_TV_SD_O_ORDER_COMPONENT_RGB_PRYPB, + S5P_TV_SD_O_ORDER_COMPONENT_RBG_PRPBY, + S5P_TV_SD_O_ORDER_COMPONENT_BGR_PBYPR, + S5P_TV_SD_O_ORDER_COMPONENT_BRG_PBPRY, + S5P_TV_SD_O_ORDER_COMPONENT_GRB_YPRPB, + S5P_TV_SD_O_ORDER_COMPONENT_GBR_YPBPR, + S5P_TV_SD_O_ORDER_COMPOSITE_CVBS_Y_C, + S5P_TV_SD_O_ORDER_COMPOSITE_CVBS_C_Y, + S5P_TV_SD_O_ORDER_COMPOSITE_Y_C_CVBS, + S5P_TV_SD_O_ORDER_COMPOSITE_Y_CVBS_C, + S5P_TV_SD_O_ORDER_COMPOSITE_C_CVBS_Y, + S5P_TV_SD_O_ORDER_COMPOSITE_C_Y_CVBS +}; + +enum s5p_tv_hdmi_err { + HDMI_NO_ERROR = 0, + S5P_TV_HDMI_ERR_NOT_INIT_PARAMETERS_UNDER_RUNNING = 0x6000, + S5P_TV_HDMI_ERR_NOT_SET_PARAMETERS_UNDER_STOP, + S5P_TV_HDMI_ERR_INVALID_PARAM +}; + +enum s5p_hdmi_transmit { + HDMI_DO_NOT_TANS = 0, + HDMI_TRANS_ONCE, + HDMI_TRANS_EVERY_SYNC +}; + +enum s5p_hdmi_audio_type { + HDMI_AUDIO_NO, + HDMI_AUDIO_PCM +}; + + +enum s5p_tv_stda_err { + STDA_NO_ERROR = 0, + S5P_TV_STDA_ERR_NOT_INIT_PARAMETERS_UNDER_RUNNING = 0x7000, + S5P_TV_STDA_ERR_NOT_SET_PARAMETERS_UNDER_STOP, + S5P_TV_STDA_ERR_INVALID_PARAM +}; + + +/* +* enum +*/ + +enum s5p_tv_active_polarity { + TVOUT_POL_ACTIVE_LOW, + TVOUT_POL_ACTIVE_HIGH +}; + +enum s5p_yuv_fmt_component { + TVOUT_YUV_Y, + TVOUT_YUV_CB, + TVOUT_YUV_CR +}; + +enum s5p_tv_clk_hpll_ref { + S5P_TV_CLK_HPLL_REF_27M, + S5P_TV_CLK_HPLL_REF_SRCLK +}; + +enum s5p_tv_clk_mout_hpll { + S5P_TV_CLK_MOUT_HPLL_27M, + S5P_TV_CLK_MOUT_HPLL_FOUT_HPLL +}; + +enum s5p_tv_clk_vmiexr_srcclk { + TVOUT_CLK_VMIXER_SRCCLK_CLK27M, + TVOUT_CLK_VMIXER_SRCCLK_VCLK_54, + TVOUT_CLK_VMIXER_SRCCLK_MOUT_HPLL +}; + +enum s5p_vp_src_color { + VPROC_SRC_COLOR_NV12 = 0, + VPROC_SRC_COLOR_NV12IW = 1, + VPROC_SRC_COLOR_TILE_NV12 = 2, + VPROC_SRC_COLOR_TILE_NV12IW = 3 +}; + +enum s5p_vp_pxl_rate { + VPROC_PIXEL_PER_RATE_1_1 = 0, + VPROC_PIXEL_PER_RATE_1_2 = 1, + VPROC_PIXEL_PER_RATE_1_3 = 2, + VPROC_PIXEL_PER_RATE_1_4 = 3 +}; + +enum s5p_vp_sharpness_control { + VPROC_SHARPNESS_NO = 0, + VPROC_SHARPNESS_MIN = 1, + VPROC_SHARPNESS_MOD = 2, + VPROC_SHARPNESS_MAX = 3 +}; + +enum s5p_vp_line_eq { + VProc_LINE_EQ_0 = 0, + VProc_LINE_EQ_1 = 1, + VProc_LINE_EQ_2 = 2, + VProc_LINE_EQ_3 = 3, + VProc_LINE_EQ_4 = 4, + VProc_LINE_EQ_5 = 5, + VProc_LINE_EQ_6 = 6, + VProc_LINE_EQ_7 = 7 +}; + +enum s5p_vp_mem_mode { + VPROC_LINEAR_MODE, + VPROC_2D_TILE_MODE +}; + +enum s5p_vp_chroma_expansion { + VPROC_USING_C_TOP, + VPROC_USING_C_TOP_BOTTOM +}; + +enum s5p_vp_filed_id_toggle { + S5P_TV_VP_FILED_ID_TOGGLE_USER, + S5P_TV_VP_FILED_ID_TOGGLE_VSYNC +}; + +enum s5p_vp_field { + VPROC_TOP_FIELD, + VPROC_BOTTOM_FIELD +}; + +enum s5p_vp_poly_coeff { + VPROC_POLY8_Y0_LL = 0, + VPROC_POLY8_Y0_LH, + VPROC_POLY8_Y0_HL, + VPROC_POLY8_Y0_HH, + VPROC_POLY8_Y1_LL, + VPROC_POLY8_Y1_LH, + VPROC_POLY8_Y1_HL, + VPROC_POLY8_Y1_HH, + VPROC_POLY8_Y2_LL, + VPROC_POLY8_Y2_LH, + VPROC_POLY8_Y2_HL, + VPROC_POLY8_Y2_HH, + VPROC_POLY8_Y3_LL, + VPROC_POLY8_Y3_LH, + VPROC_POLY8_Y3_HL, + VPROC_POLY8_Y3_HH, + VPROC_POLY4_Y0_LL = 32, + VPROC_POLY4_Y0_LH, + VPROC_POLY4_Y0_HL, + VPROC_POLY4_Y0_HH, + VPROC_POLY4_Y1_LL, + VPROC_POLY4_Y1_LH, + VPROC_POLY4_Y1_HL, + VPROC_POLY4_Y1_HH, + VPROC_POLY4_Y2_LL, + VPROC_POLY4_Y2_LH, + VPROC_POLY4_Y2_HL, + VPROC_POLY4_Y2_HH, + VPROC_POLY4_Y3_LL, + VPROC_POLY4_Y3_LH, + VPROC_POLY4_Y3_HL, + VPROC_POLY4_Y3_HH, + VPROC_POLY4_C0_LL, + VPROC_POLY4_C0_LH, + VPROC_POLY4_C0_HL, + VPROC_POLY4_C0_HH, + VPROC_POLY4_C1_LL, + VPROC_POLY4_C1_LH, + VPROC_POLY4_C1_HL, + VPROC_POLY4_C1_HH +}; + +enum s5p_vp_csc_coeff { + VPROC_CSC_Y2Y_COEF = 0, + VPROC_CSC_CB2Y_COEF, + VPROC_CSC_CR2Y_COEF, + VPROC_CSC_Y2CB_COEF, + VPROC_CSC_CB2CB_COEF, + VPROC_CSC_CR2CB_COEF, + VPROC_CSC_Y2CR_COEF, + VPROC_CSC_CB2CR_COEF, + VPROC_CSC_CR2CR_COEF +}; + +enum s5p_vp_csc_type { + VPROC_CSC_SD_HD, + VPROC_CSC_HD_SD +}; + +enum s5p_tv_vp_filter_h_pp { + /* Don't change the order and the value */ + VPROC_PP_H_NORMAL = 0, + VPROC_PP_H_8_9, /* 720 to 640 */ + VPROC_PP_H_1_2, + VPROC_PP_H_1_3, + VPROC_PP_H_1_4 +}; + +enum s5p_tv_vp_filter_v_pp { + /* Don't change the order and the value */ + VPROC_PP_V_NORMAL = 0, + VPROC_PP_V_5_6, /* PAL to NTSC */ + VPROC_PP_V_3_4, + VPROC_PP_V_1_2, + VPROC_PP_V_1_3, + VPROC_PP_V_1_4 +}; + +enum s5p_vmx_burst_mode { + VM_BURST_8 = 0, + VM_BURST_16 = 1 +}; + +enum s5p_tv_vmx_scan_mode { + VMIXER_INTERLACED_MODE = 0, + VMIXER_PROGRESSIVE_MODE = 1 +}; + +enum s5p_tv_vmx_layer { + VM_VIDEO_LAYER = 2, + VM_GPR0_LAYER = 0, + VM_GPR1_LAYER = 1 +}; + +enum s5p_tv_vmx_bg_color_num { + VMIXER_BG_COLOR_0 = 0, + VMIXER_BG_COLOR_1 = 1, + VMIXER_BG_COLOR_2 = 2 +}; + +enum s5p_tv_coef_y_mode { + VMIXER_COEF_Y_NARROW = 0, + VMIXER_COEF_Y_WIDE = 1 +}; + +enum s5p_tv_vmx_csc_type { + VMIXER_CSC_RGB_TO_YUV601_LR, + VMIXER_CSC_RGB_TO_YUV601_FR, + VMIXER_CSC_RGB_TO_YUV709_LR, + VMIXER_CSC_RGB_TO_YUV709_FR +}; + +enum s5p_tv_vmx_rgb { + RGB601_0_255, + RGB601_16_235, + RGB709_0_255, + RGB709_16_235 +}; + +enum s5p_tv_vmx_out_type { + MX_YUV444, + MX_RGB888 +}; + +enum s5p_sd_level { + S5P_TV_SD_LEVEL_0IRE, + S5P_TV_SD_LEVEL_75IRE +}; + +enum s5p_sd_vsync_ratio { + SDOUT_VTOS_RATIO_10_4, + SDOUT_VTOS_RATIO_7_3 +}; + +enum s5p_sd_sync_sig_pin { + SDOUT_SYNC_SIG_NO, + SDOUT_SYNC_SIG_YG, + SDOUT_SYNC_SIG_ALL +}; + +enum s5p_sd_closed_caption_type { + SDOUT_NO_INS, + SDOUT_INS_1, + SDOUT_INS_2, + SDOUT_INS_OTHERS +}; + +enum s5p_sd_channel_sel { + SDOUT_CHANNEL_0 = 0, + SDOUT_CHANNEL_1 = 1, + SDOUT_CHANNEL_2 = 2 +}; + +enum s5p_sd_vesa_rgb_sync_type { + SDOUT_VESA_RGB_SYNC_COMPOSITE, + SDOUT_VESA_RGB_SYNC_SEPARATE +}; + +enum s5p_sd_525_copy_permit { + SDO_525_COPY_PERMIT, + SDO_525_ONECOPY_PERMIT, + SDO_525_NOCOPY_PERMIT +}; + +enum s5p_sd_525_mv_psp { + SDO_525_MV_PSP_OFF, + SDO_525_MV_PSP_ON_2LINE_BURST, + SDO_525_MV_PSP_ON_BURST_OFF, + SDO_525_MV_PSP_ON_4LINE_BURST, +}; + +enum s5p_sd_525_copy_info { + SDO_525_COPY_INFO, + SDO_525_DEFAULT, +}; + +enum s5p_sd_525_aspect_ratio { + SDO_525_4_3_NORMAL, + SDO_525_16_9_ANAMORPIC, + SDO_525_4_3_LETTERBOX +}; + +enum s5p_sd_625_subtitles { + SDO_625_NO_OPEN_SUBTITLES, + SDO_625_INACT_OPEN_SUBTITLES, + SDO_625_OUTACT_OPEN_SUBTITLES +}; + +enum s5p_sd_625_camera_film { + SDO_625_CAMERA, + SDO_625_FILM +}; + +enum s5p_sd_625_color_encoding { + SDO_625_NORMAL_PAL, + SDO_625_MOTION_ADAPTIVE_COLORPLUS +}; + +enum s5p_sd_625_aspect_ratio { + SDO_625_4_3_FULL_576, + SDO_625_14_9_LETTERBOX_CENTER_504, + SDO_625_14_9_LETTERBOX_TOP_504, + SDO_625_16_9_LETTERBOX_CENTER_430, + SDO_625_16_9_LETTERBOX_TOP_430, + SDO_625_16_9_LETTERBOX_CENTER, + SDO_625_14_9_FULL_CENTER_576, + SDO_625_16_9_ANAMORPIC_576 +}; + +enum s5p_tv_hdmi_csc_type { + HDMI_CSC_YUV601_TO_RGB_LR, + HDMI_CSC_YUV601_TO_RGB_FR, + HDMI_CSC_YUV709_TO_RGB_LR, + HDMI_CSC_YUV709_TO_RGB_FR, + HDMI_CSC_YUV601_TO_YUV709, + HDMI_CSC_RGB_FR_TO_RGB_LR, + HDMI_CSC_RGB_FR_TO_YUV601, + HDMI_CSC_RGB_FR_TO_YUV709, + HDMI_BYPASS +}; + +/* + * Color Depth for HDMI HW (settings and GCP packet), + * EDID and PHY HW + */ +enum s5p_hdmi_color_depth { + HDMI_CD_48, + HDMI_CD_36, + HDMI_CD_30, + HDMI_CD_24 +}; + +enum phy_freq { + ePHY_FREQ_25_200, + ePHY_FREQ_25_175, + ePHY_FREQ_27, + ePHY_FREQ_27_027, + ePHY_FREQ_54, + ePHY_FREQ_54_054, + ePHY_FREQ_74_250, + ePHY_FREQ_74_176, + ePHY_FREQ_148_500, + ePHY_FREQ_148_352, + ePHY_FREQ_108_108, + ePHY_FREQ_72, + ePHY_FREQ_25, + ePHY_FREQ_65, + ePHY_FREQ_108, + ePHY_FREQ_162 +}; + +/* video format for HDMI HW (timings and AVI) and EDID */ +enum s5p_hdmi_v_fmt { + v640x480p_60Hz = 0, + v720x480p_60Hz, + v1280x720p_60Hz, + v1920x1080i_60Hz, + v720x480i_60Hz, + v720x240p_60Hz, + v2880x480i_60Hz, + v2880x240p_60Hz, + v1440x480p_60Hz, + v1920x1080p_60Hz, + v720x576p_50Hz, + v1280x720p_50Hz, + v1920x1080i_50Hz, + v720x576i_50Hz, + v720x288p_50Hz, + v2880x576i_50Hz, + v2880x288p_50Hz, + v1440x576p_50Hz, + v1920x1080p_50Hz, + v1920x1080p_24Hz, + v1920x1080p_25Hz, + v1920x1080p_30Hz, + v2880x480p_60Hz, + v2880x576p_50Hz, + v1920x1080i_50Hz_1250, + v1920x1080i_100Hz, + v1280x720p_100Hz, + v720x576p_100Hz, + v720x576i_100Hz, + v1920x1080i_120Hz, + v1280x720p_120Hz, + v720x480p_120Hz, + v720x480i_120Hz, + v720x576p_200Hz, + v720x576i_200Hz, + v720x480p_240Hz, + v720x480i_240Hz, + v720x480p_59Hz, + v1280x720p_59Hz, + v1920x1080i_59Hz, + v1920x1080p_59Hz, + +}; + + +enum s5p_tv_hdmi_disp_mode { + S5P_TV_HDMI_DISP_MODE_480P_60 = 0, + S5P_TV_HDMI_DISP_MODE_576P_50 = 1, + S5P_TV_HDMI_DISP_MODE_720P_60 = 2, + S5P_TV_HDMI_DISP_MODE_720P_50 = 3, + S5P_TV_HDMI_DISP_MODE_1080I_60 = 4, + S5P_TV_HDMI_DISP_MODE_1080I_50 = 5, + S5P_TV_HDMI_DISP_MODE_VGA_60 = 6, + S5P_TV_HDMI_DISP_MODE_1080P_60 = 7, + S5P_TV_HDMI_DISP_MODE_1080P_50 = 8, + S5P_TV_HDMI_DISP_MODE_NUM = 9 +}; + +/* pixel aspect ratio for HDMI HW (AVI packet and EDID) */ +enum s5p_tv_hdmi_pxl_aspect { + HDMI_PIXEL_RATIO_4_3, + HDMI_PIXEL_RATIO_16_9 +}; + +enum s5p_tv_hdmi_interrrupt { + HDMI_IRQ_PIN_POLAR_CTL = 7, + HDMI_IRQ_GLOBAL = 6, + HDMI_IRQ_I2S = 5, + HDMI_IRQ_CEC = 4, + HDMI_IRQ_HPD_PLUG = 3, + HDMI_IRQ_HPD_UNPLUG = 2, + HDMI_IRQ_SPDIF = 1, + HDMI_IRQ_HDCP = 0 +}; + +typedef int (*hdmi_isr)(int irq); + + +extern int s5p_hdmi_register_isr(hdmi_isr isr, u8 irq_num); +extern void s5p_hdmi_enable_interrupts(enum s5p_tv_hdmi_interrrupt intr); +extern void s5p_hdmi_disable_interrupts(enum s5p_tv_hdmi_interrrupt intr); +extern void s5p_hdmi_hpd_gen(void); +extern u8 s5p_hdmi_get_interrupts(void); +extern u8 s5p_hdmi_get_enabled_interrupt(void); +extern int s5p_hdmi_set_dvi(bool en); +extern void s5p_hdmi_mute_en(bool en); + +extern void __iomem *hdmi_base; +extern bool __s5p_start_hdcp(void); +extern bool __s5p_stop_hdcp(void); +extern void __s5p_init_hdcp(bool hpd_status, struct i2c_client *ddc_port); + + /* 0 - hdcp stopped, 1 - hdcp started, 2 - hdcp reset */ +extern u8 hdcp_protocol_status; + +void __s5p_hdmi_video_set_bluescreen(bool en, u8 cb, u8 y_g, u8 cr_r); diff --git a/drivers/media/video/samsung/tv20/s5pv210/tv_power_s5pv210.c b/drivers/media/video/samsung/tv20/s5pv210/tv_power_s5pv210.c new file mode 100644 index 0000000..4276df2 --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5pv210/tv_power_s5pv210.c @@ -0,0 +1,133 @@ +/* linux/drivers/media/video/samsung/tv20/s5pv210/tv_power_s5pv210.c + * + * power raw ftn file for Samsung TVOut driver + * + * Copyright (c) 2010 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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/delay.h> +#include <linux/uaccess.h> +#include <linux/io.h> +#include <linux/regulator/consumer.h> + +#include <mach/map.h> +#include <mach/regs-clock.h> + +#include "../s5p_tv.h" + + +#if defined USE_POWERCON_FUNCTION +#undef USE_POWERCON_FUNCTION +#endif + +#ifdef COFIG_TVOUT_RAW_DBG +#define S5P_TVOUT_PM_DEBUG 1 +#endif + +#ifdef S5P_TVOUT_PM_DEBUG +#define TVPMPRINTK(fmt, args...) \ + printk(KERN_INFO "\t\t[TVPM] %s: " fmt, __func__ , ## args) +#else +#define TVPMPRINTK(fmt, args...) +#endif + +/* NORMAL_CFG */ +#define TVPWR_SUBSYSTEM_ACTIVE (1<<4) +#define TVPWR_SUBSYSTEM_LP (0<<4) + +/* MTC_STABLE */ +#define TVPWR_MTC_COUNTER_CLEAR(a) (((~0xf)<<16)&a) +#define TVPWR_MTC_COUNTER_SET(a) ((0xf&a)<<16) + +/* BLK_PWR_STAT */ +#define TVPWR_TV_BLOCK_STATUS(a) ((0x1<<4)&a) + +static unsigned short g_dacPwrOn; +extern struct s5p_tv_status s5ptv_status; + +void __s5p_tv_power_init_mtc_stable_counter(unsigned int value) +{ + TVPMPRINTK("(%d)\n\r", value); + + writel(TVPWR_MTC_COUNTER_CLEAR((readl(S5P_MTC_STABLE) | + TVPWR_MTC_COUNTER_SET(value))), + S5P_MTC_STABLE); + + TVPMPRINTK("(0x%08x)\n\r", readl(S5P_MTC_STABLE)); +} + +void __s5p_tv_powerinitialize_dac_onoff(bool on) +{ + TVPMPRINTK("(%d)\n\r", on); + + g_dacPwrOn = on; + + TVPMPRINTK("(0x%08x)\n\r", g_dacPwrOn); +} + +void __s5p_tv_powerset_dac_onoff(bool on) +{ + TVPMPRINTK("(%d)\n\r", on); + + if (on) { + regulator_enable(s5ptv_status.tv_tvout); + writel(S5P_DAC_ENABLE, S5P_DAC_CONTROL); + } else { + writel(S5P_DAC_DISABLE, S5P_DAC_CONTROL); + regulator_disable(s5ptv_status.tv_tvout); + } + + TVPMPRINTK("(0x%08x)\n\r", readl(S5P_DAC_CONTROL)); +} + + +bool __s5p_tv_power_get_power_status(void) +{ + TVPMPRINTK("(0x%08x)\n\r", readl(S5P_BLK_PWR_STAT)); + + + return TVPWR_TV_BLOCK_STATUS(readl(S5P_BLK_PWR_STAT)) ? 1 : 0; +} + +bool __s5p_tv_power_get_dac_power_status(void) +{ + TVPMPRINTK("()\n\r"); + + TVPMPRINTK("(0x%08x)\n\r", readl(S5P_DAC_CONTROL)); + + return (readl(S5P_DAC_CONTROL) & S5P_DAC_ENABLE) ? 1 : 0; +} + + +void __s5p_tv_poweron(void) +{ + TVPMPRINTK("0x%08x\n\r", readl(S3C_VA_SYS + 0xE804)); + + writel(readl(S3C_VA_SYS + 0xE804) | 0x1, S3C_VA_SYS + 0xE804); + + if (regulator_enable(s5ptv_status.tv_regulator)) + pr_err("%s : failed to turn tv-power-domain on\n", __func__); + + TVPMPRINTK("0x%08x, 0x%08x)\n\r", readl(S5P_NORMAL_CFG), + readl(S5P_BLK_PWR_STAT)); +} + + +void __s5p_tv_poweroff(void) +{ + TVPMPRINTK("()\n\r"); + + __s5p_tv_powerset_dac_onoff(0); + + if (regulator_disable(s5ptv_status.tv_regulator)) + pr_err("%s : failed to turn tv-power-domain off\n", __func__); + + TVPMPRINTK("0x%08x, 0x%08x)\n\r", readl(S5P_NORMAL_CFG), + readl(S5P_BLK_PWR_STAT)); +} diff --git a/drivers/media/video/samsung/tv20/s5pv210/vmixer_s5pv210.c b/drivers/media/video/samsung/tv20/s5pv210/vmixer_s5pv210.c new file mode 100644 index 0000000..b38f57a --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5pv210/vmixer_s5pv210.c @@ -0,0 +1,1256 @@ +/* linux/drivers/media/video/samsung/tv20/s5pv210/vmixer_s5pv210.c + * + * Mixer raw ftn file for Samsung TVOut driver + * + * Copyright (c) 2010 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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/interrupt.h> +#include <linux/platform_device.h> +#include <linux/clk.h> +#include <linux/io.h> + +#include <plat/clock.h> + +/* #include <mach/regs-vmx.h> */ + +#include "tv_out_s5pv210.h" + +#include "regs/regs-vmx.h" +#ifdef COFIG_TVOUT_RAW_DBG +#define S5P_MXR_DEBUG 1 +#endif + +#ifdef S5P_MXR_DEBUG +#define VMPRINTK(fmt, args...) \ + printk(KERN_INFO "\t\t[VM] %s: " fmt, __func__ , ## args) +#else +#define VMPRINTK(fmt, args...) +#endif + +static struct resource *mixer_mem; +void __iomem *mixer_base; + +/* +*set - set functions are only called under running vmixer +*/ + +enum s5p_tv_vmx_err __s5p_vm_set_layer_show( + enum s5p_tv_vmx_layer layer, bool show) +{ + u32 mxr_config; + + VMPRINTK("%d, %d\n\r", layer, show); + + switch (layer) { + + case VM_VIDEO_LAYER: + mxr_config = (show) ? + (readl(mixer_base + S5P_MXR_CFG) | + S5P_MXR_VIDEO_LAYER_SHOW) : + (readl(mixer_base + S5P_MXR_CFG) & + ~S5P_MXR_VIDEO_LAYER_SHOW); + break; + + case VM_GPR0_LAYER: + mxr_config = (show) ? + (readl(mixer_base + S5P_MXR_CFG) | + S5P_MXR_GRAPHIC0_LAYER_SHOW) : + (readl(mixer_base + S5P_MXR_CFG) & + ~S5P_MXR_GRAPHIC0_LAYER_SHOW); + break; + + case VM_GPR1_LAYER: + mxr_config = (show) ? + (readl(mixer_base + S5P_MXR_CFG) | + S5P_MXR_GRAPHIC1_LAYER_SHOW) : + (readl(mixer_base + S5P_MXR_CFG) & + ~S5P_MXR_GRAPHIC1_LAYER_SHOW); + break; + + default: + VMPRINTK(" invalid layer parameter = %d\n\r", layer); + return S5P_TV_VMX_ERR_INVALID_PARAM; + break; + } + + writel(mxr_config, mixer_base + S5P_MXR_CFG); + + VMPRINTK("0x%x\n\r", readl(mixer_base + S5P_MXR_CFG)); + + return VMIXER_NO_ERROR; +} + +enum s5p_tv_vmx_err __s5p_vm_set_layer_priority(enum s5p_tv_vmx_layer layer, + u32 priority) +{ + u32 layer_cfg; + + VMPRINTK("%d, %d\n\r", layer, priority); + + switch (layer) { + + case VM_VIDEO_LAYER: + layer_cfg = S5P_MXR_VP_LAYER_PRIORITY_CLEAR( + readl(mixer_base + S5P_MXR_LAYER_CFG)) | + S5P_MXR_VP_LAYER_PRIORITY(priority); + break; + + case VM_GPR0_LAYER: + layer_cfg = S5P_MXR_GRP0_LAYER_PRIORITY_CLEAR( + readl(mixer_base + S5P_MXR_LAYER_CFG)) | + S5P_MXR_GRP0_LAYER_PRIORITY(priority); + break; + + case VM_GPR1_LAYER: + layer_cfg = S5P_MXR_GRP1_LAYER_PRIORITY_CLEAR( + readl(mixer_base + S5P_MXR_LAYER_CFG)) | + S5P_MXR_GRP1_LAYER_PRIORITY(priority); + break; + + default: + VMPRINTK(" invalid layer parameter = %d\n\r", layer); + return S5P_TV_VMX_ERR_INVALID_PARAM; + break; + } + + writel(layer_cfg, mixer_base + S5P_MXR_LAYER_CFG); + + return VMIXER_NO_ERROR; +} + +enum s5p_tv_vmx_err __s5p_vm_set_win_blend(enum s5p_tv_vmx_layer layer, + bool enable) +{ + u32 temp_reg; + VMPRINTK("%d, %d\n\r", layer, enable); + + switch (layer) { + + case VM_VIDEO_LAYER: + temp_reg = readl(mixer_base + S5P_MXR_VIDEO_CFG) + & (~S5P_MXR_VP_BLEND_ENABLE) ; + + if (enable) + temp_reg |= S5P_MXR_VP_BLEND_ENABLE; + else + temp_reg |= S5P_MXR_VP_BLEND_DISABLE; + + writel(temp_reg, mixer_base + S5P_MXR_VIDEO_CFG); + + break; + + case VM_GPR0_LAYER: + temp_reg = readl(mixer_base + S5P_MXR_GRAPHIC0_CFG) + & (~S5P_MXR_WIN_BLEND_ENABLE) ; + + if (enable) + temp_reg |= S5P_MXR_WIN_BLEND_ENABLE; + else + temp_reg |= S5P_MXR_WIN_BLEND_DISABLE; + + writel(temp_reg, mixer_base + S5P_MXR_GRAPHIC0_CFG); + + break; + + case VM_GPR1_LAYER: + temp_reg = readl(mixer_base + S5P_MXR_GRAPHIC1_CFG) + & (~S5P_MXR_WIN_BLEND_ENABLE) ; + + if (enable) + temp_reg |= S5P_MXR_WIN_BLEND_ENABLE; + else + temp_reg |= S5P_MXR_WIN_BLEND_DISABLE; + + writel(temp_reg, mixer_base + S5P_MXR_GRAPHIC1_CFG); + + break; + + default: + VMPRINTK(" invalid layer parameter = %d\n\r", layer); + + return S5P_TV_VMX_ERR_INVALID_PARAM; + + break; + } + + VMPRINTK("0x08%x\n\r", readl(mixer_base + S5P_MXR_VIDEO_CFG)); + VMPRINTK("0x08%x\n\r", readl(mixer_base + S5P_MXR_GRAPHIC0_CFG)); + VMPRINTK("0x08%x\n\r", readl(mixer_base + S5P_MXR_GRAPHIC1_CFG)); + + return VMIXER_NO_ERROR; +} + + +enum s5p_tv_vmx_err __s5p_vm_set_layer_alpha(enum s5p_tv_vmx_layer layer, + u32 alpha) +{ + u32 temp_reg; + VMPRINTK("%d, %d\n\r", layer, alpha); + + switch (layer) { + + case VM_VIDEO_LAYER: + temp_reg = readl(mixer_base + S5P_MXR_VIDEO_CFG) + & (~S5P_MXR_ALPHA) ; + temp_reg |= S5P_MXR_VP_ALPHA_VALUE(alpha); + writel(temp_reg, mixer_base + S5P_MXR_VIDEO_CFG); + break; + + case VM_GPR0_LAYER: + temp_reg = readl(mixer_base + S5P_MXR_GRAPHIC0_CFG) + & (~S5P_MXR_ALPHA) ; + temp_reg |= S5P_MXR_GRP_ALPHA_VALUE(alpha); + writel(temp_reg, mixer_base + S5P_MXR_GRAPHIC0_CFG); + break; + + case VM_GPR1_LAYER: + temp_reg = readl(mixer_base + S5P_MXR_GRAPHIC1_CFG) + & (~S5P_MXR_ALPHA) ; + temp_reg |= S5P_MXR_GRP_ALPHA_VALUE(alpha); + writel(temp_reg, mixer_base + S5P_MXR_GRAPHIC1_CFG); + break; + + default: + VMPRINTK(" invalid layer parameter = %d\n\r", layer); + return S5P_TV_VMX_ERR_INVALID_PARAM; + break; + } + + VMPRINTK("0x08%x\n\r", readl(mixer_base + S5P_MXR_VIDEO_CFG)); + VMPRINTK("0x08%x\n\r", readl(mixer_base + S5P_MXR_GRAPHIC0_CFG)); + VMPRINTK("0x08%x\n\r", readl(mixer_base + S5P_MXR_GRAPHIC1_CFG)); + + return VMIXER_NO_ERROR; +} + + +enum s5p_tv_vmx_err __s5p_vm_set_grp_base_address(enum s5p_tv_vmx_layer layer, + u32 base_addr) +{ + VMPRINTK("%d, 0x%x\n\r", layer, base_addr); + + if (S5P_MXR_GRP_ADDR_ILLEGAL(base_addr)) { + VMPRINTK(" address is not word align = %d\n\r", base_addr); + return S5P_TV_VMX_ERR_BASE_ADDRESS_MUST_WORD_ALIGN; + } + + switch (layer) { + + case VM_GPR0_LAYER: + writel(S5P_MXR_GPR_BASE(base_addr), + mixer_base + S5P_MXR_GRAPHIC0_BASE); + VMPRINTK("0x%x\n\r", + readl(mixer_base + S5P_MXR_GRAPHIC0_BASE)); + break; + + case VM_GPR1_LAYER: + writel(S5P_MXR_GPR_BASE(base_addr), + mixer_base + S5P_MXR_GRAPHIC1_BASE); + VMPRINTK("0x%x\n\r", + readl(mixer_base + S5P_MXR_GRAPHIC1_BASE)); + break; + + default: + VMPRINTK(" invalid layer parameter = %d\n\r", layer); + return S5P_TV_VMX_ERR_INVALID_PARAM; + break; + } + + return VMIXER_NO_ERROR; +} + +enum s5p_tv_vmx_err __s5p_vm_set_grp_layer_position(enum s5p_tv_vmx_layer layer, + u32 dst_offs_x, u32 dst_offs_y) +{ + VMPRINTK("%d, %d, %d)\n\r", layer, dst_offs_x, dst_offs_y); + + switch (layer) { + + case VM_GPR0_LAYER: + writel(S5P_MXR_GRP_DESTX(dst_offs_x) | + S5P_MXR_GRP_DESTY(dst_offs_y), + mixer_base + S5P_MXR_GRAPHIC0_DXY); + VMPRINTK("0x%x\n\r", + readl(mixer_base + S5P_MXR_GRAPHIC0_DXY)); + break; + + case VM_GPR1_LAYER: + writel(S5P_MXR_GRP_DESTX(dst_offs_x) | + S5P_MXR_GRP_DESTY(dst_offs_y), + mixer_base + S5P_MXR_GRAPHIC1_DXY); + VMPRINTK("0x%x\n\r", + readl(mixer_base + S5P_MXR_GRAPHIC1_DXY)); + break; + + default: + VMPRINTK("invalid layer parameter = %d\n\r", layer); + return S5P_TV_VMX_ERR_INVALID_PARAM; + break; + } + + return VMIXER_NO_ERROR; +} + +enum s5p_tv_vmx_err __s5p_vm_set_grp_layer_size(enum s5p_tv_vmx_layer layer, + u32 span, + u32 width, + u32 height, + u32 src_offs_x, + u32 src_offs_y) +{ + VMPRINTK("%d, %d, %d, %d, %d, %d)\n\r", layer, span, width, height, + src_offs_x, src_offs_y); + + switch (layer) { + + case VM_GPR0_LAYER: + writel(S5P_MXR_GRP_SPAN(span), + mixer_base + S5P_MXR_GRAPHIC0_SPAN); + writel(S5P_MXR_GRP_WIDTH(width) | S5P_MXR_GRP_HEIGHT(height), + mixer_base + S5P_MXR_GRAPHIC0_WH); + writel(S5P_MXR_GRP_STARTX(src_offs_x) | + S5P_MXR_GRP_STARTY(src_offs_y), + mixer_base + S5P_MXR_GRAPHIC0_SXY); + VMPRINTK("0x%x, 0x%x, 0x%x\n\r", + readl(mixer_base + S5P_MXR_GRAPHIC0_SPAN), + readl(mixer_base + S5P_MXR_GRAPHIC0_WH), + readl(mixer_base + S5P_MXR_GRAPHIC0_SXY)); + break; + + case VM_GPR1_LAYER: + writel(S5P_MXR_GRP_SPAN(span), + mixer_base + S5P_MXR_GRAPHIC1_SPAN); + writel(S5P_MXR_GRP_WIDTH(width) | S5P_MXR_GRP_HEIGHT(height), + mixer_base + S5P_MXR_GRAPHIC1_WH); + writel(S5P_MXR_GRP_STARTX(src_offs_x) | + S5P_MXR_GRP_STARTY(src_offs_y), + mixer_base + S5P_MXR_GRAPHIC1_SXY); + VMPRINTK("0x%x, 0x%x, 0x%x\n\r", + readl(mixer_base + S5P_MXR_GRAPHIC1_SPAN), + readl(mixer_base + S5P_MXR_GRAPHIC1_WH), + readl(mixer_base + S5P_MXR_GRAPHIC1_SXY)); + break; + + default: + VMPRINTK(" invalid layer parameter = %d\n\r", layer); + return S5P_TV_VMX_ERR_INVALID_PARAM; + break; + } + + return VMIXER_NO_ERROR; +} + +enum s5p_tv_vmx_err __s5p_vm_set_bg_color(enum s5p_tv_vmx_bg_color_num colornum, + u32 color_y, + u32 color_cb, + u32 color_cr) +{ + u32 reg_value; + VMPRINTK("%d, %d, %d, %d)\n\r", colornum, color_y, color_cb, color_cr); + + reg_value = S5P_MXR_BG_COLOR_Y(color_y) | + S5P_MXR_BG_COLOR_CB(color_cb) | + S5P_MXR_BG_COLOR_CR(color_cr); + + switch (colornum) { + + case VMIXER_BG_COLOR_0: + writel(reg_value, mixer_base + S5P_MXR_BG_COLOR0); + VMPRINTK("0x%x\n\r", readl(mixer_base + S5P_MXR_BG_COLOR0)); + break; + + case VMIXER_BG_COLOR_1: + writel(reg_value, mixer_base + S5P_MXR_BG_COLOR1); + VMPRINTK("0x%x\n\r", readl(mixer_base + S5P_MXR_BG_COLOR1)); + break; + + case VMIXER_BG_COLOR_2: + writel(reg_value, mixer_base + S5P_MXR_BG_COLOR2); + VMPRINTK("0x%x\n\r", readl(mixer_base + S5P_MXR_BG_COLOR2)); + break; + + default: + VMPRINTK(" invalid uiColorNum parameter = %d\n\r", colornum); + return S5P_TV_VMX_ERR_INVALID_PARAM; + break; + } + + return VMIXER_NO_ERROR; +} + + + +/* +* initialization - iniization functions are only called under stopping vmixer +*/ +enum s5p_tv_vmx_err __s5p_vm_init_status_reg(enum s5p_vmx_burst_mode burst, + enum s5p_endian_type endian) +{ + u32 temp_reg = 0; + + VMPRINTK("++(%d, %d)\n\r", burst, endian); + + temp_reg = S5P_MXR_MIXER_RESERVED | S5P_MXR_CMU_CANNOT_STOP_CLOCK; + + switch (burst) { + + case VM_BURST_8: + temp_reg |= S5P_MXR_BURST8_MODE; + break; + + case VM_BURST_16: + temp_reg |= S5P_MXR_BURST16_MODE; + break; + + default: + VMPRINTK("[ERR] : invalid burst parameter = %d\n\r", burst); + return S5P_TV_VMX_ERR_INVALID_PARAM; + break; + } + + switch (endian) { + + case TVOUT_BIG_ENDIAN_MODE: + temp_reg |= S5P_MXR_BIG_ENDIAN_SOURCE_FORMAT; + break; + + case TVOUT_LITTLE_ENDIAN_MODE: + temp_reg |= S5P_MXR_LITTLE_ENDIAN_SOURCE_FORMAT; + break; + + default: + VMPRINTK("[ERR] : invalid endian parameter = %d\n\r", endian); + return S5P_TV_VMX_ERR_INVALID_PARAM; + break; + } + + writel(temp_reg, mixer_base + S5P_MXR_STATUS); + + VMPRINTK("--(0x%x)\n\r", readl(mixer_base + S5P_MXR_STATUS)); + + return VMIXER_NO_ERROR; +} + +enum s5p_tv_vmx_err __s5p_vm_init_display_mode(enum s5p_tv_disp_mode mode, + enum s5p_tv_o_mode output_mode) +{ + u32 temp_reg = readl(mixer_base + S5P_MXR_CFG); + + VMPRINTK("%d, %d)\n\r", mode, output_mode); + + switch (mode) { + + case TVOUT_NTSC_M: + + case TVOUT_NTSC_443: + temp_reg &= ~S5P_MXR_HD; + temp_reg &= ~S5P_MXR_PAL; + temp_reg &= S5P_MXR_INTERLACE_MODE; + break; + + case TVOUT_PAL_BDGHI: + + case TVOUT_PAL_M: + + case TVOUT_PAL_N: + + case TVOUT_PAL_NC: + + case TVOUT_PAL_60: + temp_reg &= ~S5P_MXR_HD; + temp_reg |= S5P_MXR_PAL; + temp_reg &= S5P_MXR_INTERLACE_MODE; + break; + + case TVOUT_480P_60_16_9: + + case TVOUT_480P_60_4_3: + + case TVOUT_480P_59: + temp_reg &= ~S5P_MXR_HD; + temp_reg &= ~S5P_MXR_PAL; + temp_reg |= S5P_MXR_PROGRESSVE_MODE; + temp_reg |= RGB601_16_235<<9; + break; + + case TVOUT_576P_50_16_9: + + case TVOUT_576P_50_4_3: + temp_reg &= ~S5P_MXR_HD; + temp_reg |= S5P_MXR_PAL; + temp_reg |= S5P_MXR_PROGRESSVE_MODE; + temp_reg |= RGB601_16_235<<9; + break; + + case TVOUT_720P_50: + + case TVOUT_720P_59: + + case TVOUT_720P_60: + temp_reg |= S5P_MXR_HD; + temp_reg &= ~S5P_MXR_HD_1080I_MODE; + temp_reg |= S5P_MXR_PROGRESSVE_MODE; + temp_reg |= RGB709_16_235<<9; + break; + + case TVOUT_1080I_50: + + case TVOUT_1080I_59: + + case TVOUT_1080I_60: + temp_reg |= S5P_MXR_HD; + temp_reg |= S5P_MXR_HD_1080I_MODE; + temp_reg &= S5P_MXR_INTERLACE_MODE; + temp_reg |= RGB709_16_235<<9; + break; + + case TVOUT_1080P_50: + + case TVOUT_1080P_59: + + case TVOUT_1080P_60: + + case TVOUT_1080P_30: + temp_reg |= S5P_MXR_HD; + temp_reg |= S5P_MXR_HD_1080P_MODE; + temp_reg |= S5P_MXR_PROGRESSVE_MODE; + temp_reg |= RGB709_16_235<<9; + break; + + default: + VMPRINTK(" invalid mode parameter = %d\n\r", mode); + return S5P_TV_VMX_ERR_INVALID_PARAM; + break; + } + + switch (output_mode) { + + case TVOUT_OUTPUT_COMPOSITE: + case TVOUT_OUTPUT_SVIDEO: + case TVOUT_OUTPUT_COMPONENT_YPBPR_INERLACED: + case TVOUT_OUTPUT_COMPONENT_YPBPR_PROGRESSIVE: + case TVOUT_OUTPUT_COMPONENT_RGB_PROGRESSIVE: + temp_reg &= S5P_MXR_DST_SEL_ANALOG; + break; + + case TVOUT_OUTPUT_HDMI_RGB: + case TVOUT_OUTPUT_DVI: + temp_reg |= S5P_MXR_DST_SEL_HDMI; + temp_reg &= ~(0x1<<8); + temp_reg |= MX_RGB888<<8; + break; + + case TVOUT_OUTPUT_HDMI: + temp_reg |= S5P_MXR_DST_SEL_HDMI; + temp_reg &= ~(0x1<<8); + temp_reg |= MX_YUV444<<8; + break; + + default: + VMPRINTK(" invalid mode parameter = %d\n\r", mode); + return S5P_TV_VMX_ERR_INVALID_PARAM; + break; + } + + writel(temp_reg, mixer_base + S5P_MXR_CFG); + + VMPRINTK("--(0x%x)\n\r", readl(mixer_base + S5P_MXR_CFG)); + + return VMIXER_NO_ERROR; +} + +u32 grp_scaling_factor(u32 src, u32 dst, u32 h_v) +{ + u32 factor; /* for scaling factor */ + + /* check scale or not */ + if (src == dst) + factor = 0; + + if (dst % src) { + factor = 0; + + VMPRINTK(" can't %s scaling src(%d) into dst(%d)\n" + , h_v ? "horizontal" : "vertical" + , src_w, dst_w); + VMPRINTK(" scaling vector must be 2/4/8x\n"); + } + + factor = dst / src; + + switch (factor) { + case 2: + factor = 1; + break; + case 4: + factor = 2; + break; + case 8: + factor = 3; + break; + default: + VMPRINTK(" scaling vector must be 2/4/8x\n"); + factor = 0; + break; + } + + return factor; +} + +void __s5p_vm_set_ctrl(enum s5p_tv_vmx_layer layer, + bool premul, + bool pixel_blending, + bool blank_change, + bool win_blending, + enum s5p_tv_vmx_color_fmt color, + u32 alpha, u32 blank_color) +{ + u32 reg = readl(mixer_base + S5P_MXR_GRAPHIC0_CFG); + + if (blank_change) + reg &= ~S5P_MXR_BLANK_CHANGE_NEW_PIXEL; + else + reg |= S5P_MXR_BLANK_CHANGE_NEW_PIXEL; + + + if (premul) + reg |= S5P_MXR_PRE_MUL_MODE; + else + reg &= ~S5P_MXR_PRE_MUL_MODE; + + if (win_blending) + reg |= S5P_MXR_WIN_BLEND_ENABLE; + else + reg &= ~S5P_MXR_WIN_BLEND_ENABLE; + + reg &= ~S5P_MXR_EG_COLOR_FORMAT(0xf); + reg |= S5P_MXR_EG_COLOR_FORMAT(color); + reg |= S5P_MXR_GRP_ALPHA_VALUE(alpha); + + writel(reg, mixer_base + S5P_MXR_GRAPHIC0_CFG); + writel(S5P_MXR_GPR_BLANK_COLOR(blank_color), + mixer_base + S5P_MXR_GRAPHIC0_BLANK); + +} + +enum s5p_tv_vmx_err __s5p_vm_init_layer(enum s5p_tv_disp_mode mode, + enum s5p_tv_vmx_layer layer, + bool show, + bool win_blending, + u32 alpha, + u32 priority, + enum s5p_tv_vmx_color_fmt color, + bool blank_change, + bool pixel_blending, + bool premul, + u32 blank_color, + u32 base_addr, + u32 span, + u32 width, + u32 height, + u32 src_offs_x, + u32 src_offs_y, + u32 dst_offs_x, + u32 dst_offs_y, + u32 dst_width, + u32 dst_height) +{ + u32 temp_reg = 0; + u32 h_factor = 0, v_factor = 0; + + VMPRINTK("%d, %d, %d, %d, %d, %d, %d, %d, %d, 0x%x,\ + 0x%x, %d, %d, %d, %d, %d, %d, %d)\n\r", + layer, show, win_blending, alpha, priority, + color, blank_change, pixel_blending, premul, + blank_color, base_addr, span, width, height, + src_offs_x, src_offs_y, dst_offs_x, dst_offs_y); + + switch (layer) { + + case VM_VIDEO_LAYER: + temp_reg = (win_blending) ? S5P_MXR_VP_BLEND_ENABLE : + S5P_MXR_VP_BLEND_DISABLE; + temp_reg |= S5P_MXR_VP_ALPHA_VALUE(alpha); + /* temp yuv pxl limiter setting*/ + temp_reg &= ~(1<<17); + writel(temp_reg, mixer_base + S5P_MXR_VIDEO_CFG); + break; + + case VM_GPR0_LAYER: + temp_reg = (blank_change) ? + S5P_MXR_BLANK_NOT_CHANGE_NEW_PIXEL : + S5P_MXR_BLANK_CHANGE_NEW_PIXEL; + temp_reg |= (premul) ? S5P_MXR_PRE_MUL_MODE : + S5P_MXR_NORMAL_MODE; + temp_reg |= (win_blending) ? S5P_MXR_WIN_BLEND_ENABLE : + S5P_MXR_WIN_BLEND_DISABLE; + temp_reg |= (pixel_blending) ? S5P_MXR_PIXEL_BLEND_ENABLE : + S5P_MXR_PIXEL_BLEND_DISABLE; + temp_reg |= S5P_MXR_EG_COLOR_FORMAT(color); + temp_reg |= S5P_MXR_GRP_ALPHA_VALUE(alpha); + writel(temp_reg, mixer_base + S5P_MXR_GRAPHIC0_CFG); + writel(S5P_MXR_GPR_BLANK_COLOR(blank_color), + mixer_base + S5P_MXR_GRAPHIC0_BLANK); + + VMPRINTK("--(0x%x)\n\r", + readl(mixer_base + S5P_MXR_GRAPHIC0_CFG)); + VMPRINTK("--(0x%x)\n\r", + readl(mixer_base + S5P_MXR_GRAPHIC0_BLANK)); + + __s5p_vm_set_grp_layer_size(layer, span, width, height, + src_offs_x, src_offs_y); + + __s5p_vm_set_grp_base_address(layer, base_addr); + __s5p_vm_set_grp_layer_position(layer, dst_offs_x, + dst_offs_y); + + temp_reg = readl(mixer_base + S5P_MXR_GRAPHIC0_WH); + h_factor = grp_scaling_factor(width, dst_width, 1); + v_factor = grp_scaling_factor(height, dst_height, 0); + + temp_reg &= ~((0x3<<28)|(0x3<<12)); + + if (v_factor) { + + u32 reg = readl(mixer_base + S5P_MXR_CFG); + + /* In interlaced mode, vertical scaling must be + * replaced by PROGRESSIVE_MODE - pixel duplication + */ + if (mode == TVOUT_1080I_50 || + mode == TVOUT_1080I_59 || + mode == TVOUT_1080I_60) { + /* scaled up by progressive setting */ + reg |= S5P_MXR_PROGRESSVE_MODE; + writel(reg, mixer_base + S5P_MXR_CFG); + } else + /* scaled up by scale factor */ + temp_reg |= v_factor << 12; + } else { + u32 reg = readl(mixer_base + S5P_MXR_CFG); + + /* + * if v_factor is 0, recover the original mode + */ + if (mode == TVOUT_1080I_50 || + mode == TVOUT_1080I_59 || + mode == TVOUT_1080I_60) { + reg &= S5P_MXR_INTERLACE_MODE; + writel(reg, mixer_base + S5P_MXR_CFG); + } + } + + temp_reg |= h_factor << 28; + + writel(temp_reg , mixer_base + S5P_MXR_GRAPHIC0_WH); + + + break; + + case VM_GPR1_LAYER: + temp_reg = (blank_change) ? + S5P_MXR_BLANK_NOT_CHANGE_NEW_PIXEL : + S5P_MXR_BLANK_CHANGE_NEW_PIXEL; + temp_reg |= (premul) ? S5P_MXR_PRE_MUL_MODE : + S5P_MXR_NORMAL_MODE; + temp_reg |= (win_blending) ? S5P_MXR_WIN_BLEND_ENABLE : + S5P_MXR_WIN_BLEND_DISABLE; + temp_reg |= (pixel_blending) ? S5P_MXR_PIXEL_BLEND_ENABLE : + S5P_MXR_PIXEL_BLEND_DISABLE; + temp_reg |= S5P_MXR_EG_COLOR_FORMAT(color); + temp_reg |= S5P_MXR_GRP_ALPHA_VALUE(alpha); + + writel(temp_reg, mixer_base + S5P_MXR_GRAPHIC1_CFG); + writel(S5P_MXR_GPR_BLANK_COLOR(blank_color), + mixer_base + S5P_MXR_GRAPHIC1_BLANK); + + VMPRINTK("--(0x%x)\n\r", + readl(mixer_base + S5P_MXR_GRAPHIC1_CFG)); + VMPRINTK("--(0x%x)\n\r", + readl(mixer_base + S5P_MXR_GRAPHIC1_BLANK)); + + __s5p_vm_set_grp_layer_size(layer, span, width, height, + src_offs_x, src_offs_y); + + __s5p_vm_set_grp_base_address(layer, base_addr); + __s5p_vm_set_grp_layer_position(layer, dst_offs_x, dst_offs_y); + + temp_reg = readl(mixer_base + S5P_MXR_GRAPHIC1_WH); + h_factor = grp_scaling_factor(width, dst_width, 1); + v_factor = grp_scaling_factor(height, dst_height, 0); + + temp_reg &= ~((0x3<<28)|(0x3<<12)); + + if (v_factor) { + + u32 reg = readl(mixer_base + S5P_MXR_CFG); + + /* In interlaced mode, vertical scaling must be + * replaced by PROGRESSIVE_MODE - pixel duplication + */ + if (mode == TVOUT_1080I_50 || + mode == TVOUT_1080I_59 || + mode == TVOUT_1080I_60) { + /* scaled up by progressive setting */ + reg |= S5P_MXR_PROGRESSVE_MODE; + writel(reg, mixer_base + S5P_MXR_CFG); + } else + /* scaled up by scale factor */ + temp_reg |= v_factor << 12; + } else { + u32 reg = readl(mixer_base + S5P_MXR_CFG); + + /* + * if v_factor is 0, recover the original mode + */ + if (mode == TVOUT_1080I_50 || + mode == TVOUT_1080I_59 || + mode == TVOUT_1080I_60) { + reg &= S5P_MXR_INTERLACE_MODE; + writel(reg, mixer_base + S5P_MXR_CFG); + } + } + + temp_reg |= h_factor << 28; + + writel(temp_reg , mixer_base + S5P_MXR_GRAPHIC1_WH); + break; + + default: + VMPRINTK("invalid layer parameter = %d\n\r", layer); + return S5P_TV_VMX_ERR_INVALID_PARAM; + break; + } + + __s5p_vm_set_layer_priority(layer, priority); + + __s5p_vm_set_layer_show(layer, show); + + return VMIXER_NO_ERROR; +} + +void __s5p_vm_init_bg_dither_enable(bool cr_dither_enable, + bool cb_dither_enable, + bool y_dither_enable) +{ + u32 temp_reg = 0; + + VMPRINTK("%d, %d, %d\n\r", cr_dither_enable, cb_dither_enable, + y_dither_enable); + + temp_reg = (cr_dither_enable) ? + (temp_reg | S5P_MXR_BG_CR_DIHER_EN) : + (temp_reg & ~S5P_MXR_BG_CR_DIHER_EN); + temp_reg = (cb_dither_enable) ? + (temp_reg | S5P_MXR_BG_CB_DIHER_EN) : + (temp_reg & ~S5P_MXR_BG_CB_DIHER_EN); + temp_reg = (y_dither_enable) ? + (temp_reg | S5P_MXR_BG_Y_DIHER_EN) : + (temp_reg & ~S5P_MXR_BG_Y_DIHER_EN); + + writel(temp_reg, mixer_base + S5P_MXR_BG_CFG); + VMPRINTK("--(0x%x)\n\r", readl(mixer_base + S5P_MXR_BG_CFG)); + +} + + +enum s5p_tv_vmx_err __s5p_vm_init_bg_color( + enum s5p_tv_vmx_bg_color_num color_num, + u32 color_y, + u32 color_cb, + u32 color_cr) +{ + return __s5p_vm_set_bg_color(color_num, color_y, color_cb, color_cr); +} + +enum s5p_tv_vmx_err __s5p_vm_init_csc_coef(enum s5p_yuv_fmt_component component, + enum s5p_tv_coef_y_mode mode, + u32 coeff0, + u32 coeff1, + u32 coeff2) +{ + u32 mxr_cm; + + VMPRINTK("%d, %d, %d, %d, %d\n\r", component, mode, coeff0, coeff1, + coeff2); + + switch (component) { + + case TVOUT_YUV_Y: + mxr_cm = (mode == VMIXER_COEF_Y_WIDE) ? + S5P_MXR_BG_COLOR_WIDE : S5P_MXR_BG_COLOR_NARROW; + mxr_cm |= S5P_MXR_BG_COEFF_0(coeff0) | + S5P_MXR_BG_COEFF_1(coeff1) | + S5P_MXR_BG_COEFF_2(coeff2); + writel(mxr_cm, mixer_base + S5P_MXR_CM_COEFF_Y); + VMPRINTK("--(0x%x)\n\r", + readl(mixer_base + S5P_MXR_CM_COEFF_Y)); + break; + + case TVOUT_YUV_CB: + mxr_cm = S5P_MXR_BG_COEFF_0(coeff0) | + S5P_MXR_BG_COEFF_1(coeff1) | + S5P_MXR_BG_COEFF_2(coeff2); + writel(mxr_cm, mixer_base + S5P_MXR_CM_COEFF_CB); + VMPRINTK("--(0x%x)\n\r", + readl(mixer_base + S5P_MXR_CM_COEFF_CB)); + break; + + case TVOUT_YUV_CR: + mxr_cm = S5P_MXR_BG_COEFF_0(coeff0) | + S5P_MXR_BG_COEFF_1(coeff1) | + S5P_MXR_BG_COEFF_2(coeff2); + writel(mxr_cm, S5P_MXR_CM_COEFF_CR); + VMPRINTK("--(0x%x)\n\r", + readl(mixer_base + S5P_MXR_CM_COEFF_CR)); + break; + + default: + VMPRINTK("invalid component parameter = %d\n\r", component); + return S5P_TV_VMX_ERR_INVALID_PARAM; + break; + } + + return VMIXER_NO_ERROR; +} + +void __s5p_vm_init_csc_coef_default(enum s5p_tv_vmx_csc_type csc_type) +{ + VMPRINTK("%d\n\r", csc_type); + + switch (csc_type) { + + case VMIXER_CSC_RGB_TO_YUV601_LR: + writel((0 << 30) | (153 << 20) | (300 << 10) | (58 << 0), + mixer_base + S5P_MXR_CM_COEFF_Y); + writel((936 << 20) | (851 << 10) | (262 << 0), + mixer_base + S5P_MXR_CM_COEFF_CB); + writel((262 << 20) | (805 << 10) | (982 << 0), + mixer_base + S5P_MXR_CM_COEFF_CR); + break; + + case VMIXER_CSC_RGB_TO_YUV601_FR: + writel((1 << 30) | (132 << 20) | (258 << 10) | (50 << 0), + mixer_base + S5P_MXR_CM_COEFF_Y); + writel((948 << 20) | (875 << 10) | (225 << 0), + mixer_base + S5P_MXR_CM_COEFF_CB); + writel((225 << 20) | (836 << 10) | (988 << 0), + mixer_base + S5P_MXR_CM_COEFF_CR); + break; + + case VMIXER_CSC_RGB_TO_YUV709_LR: + writel((0 << 30) | (109 << 20) | (366 << 10) | (36 << 0), + mixer_base + S5P_MXR_CM_COEFF_Y); + writel((964 << 20) | (822 << 10) | (216 << 0), + mixer_base + S5P_MXR_CM_COEFF_CB); + writel((262 << 20) | (787 << 10) | (1000 << 0), + mixer_base + S5P_MXR_CM_COEFF_CR); + break; + + case VMIXER_CSC_RGB_TO_YUV709_FR: + writel((1 << 30) | (94 << 20) | (314 << 10) | (32 << 0), + mixer_base + S5P_MXR_CM_COEFF_Y); + writel((972 << 20) | (851 << 10) | (225 << 0), + mixer_base + S5P_MXR_CM_COEFF_CB); + writel((225 << 20) | (820 << 10) | (1004 << 0), + mixer_base + S5P_MXR_CM_COEFF_CR); + break; + + default: + VMPRINTK(" invalid csc_type parameter = %d\n\r", csc_type); + break; + } + + VMPRINTK("--(0x%x)\n\r", readl(mixer_base + S5P_MXR_CM_COEFF_Y)); + + VMPRINTK("--(0x%x)\n\r", readl(mixer_base + S5P_MXR_CM_COEFF_CB)); + VMPRINTK("--(0x%x)\n\r", readl(mixer_base + S5P_MXR_CM_COEFF_CR)); +} + +/* +* etc +*/ +enum s5p_tv_vmx_err __s5p_vm_get_layer_info(enum s5p_tv_vmx_layer layer, + bool *show, + u32 *priority) +{ + VMPRINTK("%d\n\r", layer); + + switch (layer) { + + case VM_VIDEO_LAYER: + *show = (readl(mixer_base + S5P_MXR_LAYER_CFG) & + S5P_MXR_VIDEO_LAYER_SHOW) ? 1 : 0; + *priority = S5P_MXR_VP_LAYER_PRIORITY_INFO( + readl(mixer_base + S5P_MXR_LAYER_CFG)); + break; + + case VM_GPR0_LAYER: + *show = (readl(mixer_base + S5P_MXR_LAYER_CFG) & + S5P_MXR_GRAPHIC0_LAYER_SHOW) ? 1 : 0; + *priority = S5P_MXR_GRP0_LAYER_PRIORITY_INFO( + readl(mixer_base + S5P_MXR_LAYER_CFG)); + break; + + case VM_GPR1_LAYER: + *show = (readl(mixer_base + S5P_MXR_LAYER_CFG) & + S5P_MXR_GRAPHIC1_LAYER_SHOW) ? 1 : 0; + *priority = S5P_MXR_GRP1_LAYER_PRIORITY_INFO( + readl(mixer_base + S5P_MXR_LAYER_CFG)); + break; + + default: + VMPRINTK("invalid layer parameter = %d\n\r", layer); + return S5P_TV_VMX_ERR_INVALID_PARAM; + break; + } + + VMPRINTK("%d, %d\n\r", *show, *priority); + + return VMIXER_NO_ERROR; +} + +/* +* start - start functions are only called under stopping vmixer +*/ + +void __s5p_vm_start(void) +{ + VMPRINTK("()\n\r"); + writel((readl(mixer_base + S5P_MXR_STATUS) | S5P_MXR_MIXER_START), + mixer_base + S5P_MXR_STATUS); + VMPRINTK("0x%x\n\r", readl(mixer_base + S5P_MXR_STATUS)); + + + VMPRINTK("S5P_MXR_STATUS \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_STATUS)); + VMPRINTK("S5P_MXR_INT_EN \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_INT_EN)); + VMPRINTK("S5P_MXR_BG_CFG \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_BG_CFG)); + VMPRINTK("S5P_MXR_BG_COLOR0 \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_BG_COLOR0)); + VMPRINTK("S5P_MXR_BG_COLOR1 \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_BG_COLOR1)); + VMPRINTK("S5P_MXR_BG_COLOR2 \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_BG_COLOR2)); + VMPRINTK("S5P_MXR_CM_COEFF_Y \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_CM_COEFF_Y)); + VMPRINTK("S5P_MXR_CM_COEFF_CB \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_CM_COEFF_CB)); + VMPRINTK("S5P_MXR_CM_COEFF_CR \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_CM_COEFF_CR)); + VMPRINTK("S5P_MXR_CM_COEFF_Y \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_CM_COEFF_Y)); + VMPRINTK("S5P_MXR_CM_COEFF_CB \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_CM_COEFF_CB)); + VMPRINTK("S5P_MXR_CM_COEFF_CR \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_CM_COEFF_CR)); + VMPRINTK("S5P_MXR_GRAPHIC0_CFG \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_GRAPHIC0_CFG)); + VMPRINTK("S5P_MXR_GRAPHIC0_BASE \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_GRAPHIC0_BASE)); + VMPRINTK("S5P_MXR_GRAPHIC0_SPAN \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_GRAPHIC0_SPAN)); + VMPRINTK("S5P_MXR_GRAPHIC0_WH \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_GRAPHIC0_WH)); + VMPRINTK("S5P_MXR_GRAPHIC0_SXY \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_GRAPHIC0_SXY)); + VMPRINTK("S5P_MXR_GRAPHIC0_DXY \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_GRAPHIC0_DXY)); + VMPRINTK("S5P_MXR_GRAPHIC0_BLANK \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_GRAPHIC0_BLANK)); + VMPRINTK("S5P_MXR_GRAPHIC1_BASE \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_GRAPHIC1_BASE)); + VMPRINTK("S5P_MXR_GRAPHIC1_SPAN \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_GRAPHIC1_SPAN)); + VMPRINTK("S5P_MXR_GRAPHIC1_WH \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_GRAPHIC1_WH)); + VMPRINTK("S5P_MXR_GRAPHIC1_SXY \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_GRAPHIC1_SXY)); + VMPRINTK("S5P_MXR_GRAPHIC1_DXY \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_GRAPHIC1_DXY)); + VMPRINTK("S5P_MXR_GRAPHIC1_BLANK \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_GRAPHIC1_BLANK)); + VMPRINTK("S5P_MXR_CFG \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_CFG)); + VMPRINTK("S5P_MXR_LAYER_CFG \t\t 0x%08x\n ", + readl(mixer_base + S5P_MXR_LAYER_CFG)); + +} + +/* +* stop - stop functions are only called under running vmixer +*/ + +void __s5p_vm_stop(void) +{ + u32 reg = readl(mixer_base + S5P_MXR_STATUS); + + reg &= ~S5P_MXR_MIXER_START; + + writel(reg, mixer_base + S5P_MXR_STATUS); + + do { + reg = readl(mixer_base + S5P_MXR_STATUS); + } while (reg & S5P_MXR_MIXER_START); +} + +/* +* interrupt - for debug +*/ + +enum s5p_tv_vmx_err __s5p_vm_set_underflow_interrupt_enable( + enum s5p_tv_vmx_layer layer, bool en) +{ + u32 enablemaks; + + VMPRINTK("%d, %d\n\r", layer, en); + + switch (layer) { + + case VM_VIDEO_LAYER: + enablemaks = S5P_MXR_VP_INT_ENABLE; + break; + + case VM_GPR0_LAYER: + enablemaks = S5P_MXR_GRP0_INT_ENABLE; + break; + + case VM_GPR1_LAYER: + enablemaks = S5P_MXR_GRP1_INT_ENABLE; + break; + + default: + VMPRINTK("invalid layer parameter = %d\n\r", layer); + return S5P_TV_VMX_ERR_INVALID_PARAM; + break; + } + + if (en) { + writel((readl(mixer_base + S5P_MXR_INT_EN) | enablemaks), + mixer_base + S5P_MXR_INT_EN); + } else { + writel((readl(mixer_base + S5P_MXR_INT_EN) & ~enablemaks), + mixer_base + S5P_MXR_INT_EN); + } + + VMPRINTK("0x%x)\n\r", readl(mixer_base + S5P_MXR_INT_EN)); + + return VMIXER_NO_ERROR; +} + +void __s5p_vm_clear_pend_all(void) +{ + writel(S5P_MXR_INT_FIRED | S5P_MXR_VP_INT_FIRED | + S5P_MXR_GRP0_INT_FIRED | S5P_MXR_GRP1_INT_FIRED, + mixer_base + S5P_MXR_INT_STATUS); +} + +irqreturn_t __s5p_mixer_irq(int irq, void *dev_id) +{ + bool v_i_f; + bool g0_i_f; + bool g1_i_f; + bool mxr_i_f; + u32 temp_reg = 0; + + v_i_f = (readl(mixer_base + S5P_MXR_INT_STATUS) + & S5P_MXR_VP_INT_FIRED) ? true : false; + g0_i_f = (readl(mixer_base + S5P_MXR_INT_STATUS) + & S5P_MXR_GRP0_INT_FIRED) ? true : false; + g1_i_f = (readl(mixer_base + S5P_MXR_INT_STATUS) + & S5P_MXR_GRP1_INT_FIRED) ? true : false; + mxr_i_f = (readl(mixer_base + S5P_MXR_INT_STATUS) + & S5P_MXR_INT_FIRED) ? true : false; + + if (mxr_i_f) { + temp_reg |= S5P_MXR_INT_FIRED; + + if (v_i_f) { + temp_reg |= S5P_MXR_VP_INT_FIRED; + printk("VP fifo under run!!\n\r"); + } + + if (g0_i_f) { + temp_reg |= S5P_MXR_GRP0_INT_FIRED; + printk("GRP0 fifo under run!!\n\r"); + } + + if (g1_i_f) { + temp_reg |= S5P_MXR_GRP1_INT_FIRED; + printk("GRP1 fifo under run!!\n\r"); + } + + writel(temp_reg, mixer_base + S5P_MXR_INT_STATUS); + } + + return IRQ_HANDLED; +} + +int __init __s5p_mixer_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; + + mixer_mem = request_mem_region(res->start, size, pdev->name); + + if (mixer_mem == NULL) { + dev_err(&pdev->dev, + "failed to get memory region\n"); + goto error; + + } + + mixer_base = ioremap(res->start, size); + + if (mixer_base == NULL) { + dev_err(&pdev->dev, + "failed to ioremap address region\n"); + goto error; + + + } + return 0; +error: + return -ENOENT; + +} + +int __init __s5p_mixer_release(struct platform_device *pdev) +{ + iounmap(mixer_base); + + /* remove memory region */ + if (mixer_mem != NULL) { + if (release_resource(mixer_mem)) + dev_err(&pdev->dev, + "Can't remove tvout drv !!\n"); + + kfree(mixer_mem); + + mixer_mem = NULL; + } + + return 0; +} diff --git a/drivers/media/video/samsung/tv20/s5pv210/vp_coeff_s5pv210.h b/drivers/media/video/samsung/tv20/s5pv210/vp_coeff_s5pv210.h new file mode 100644 index 0000000..fb939fe --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5pv210/vp_coeff_s5pv210.h @@ -0,0 +1,310 @@ +/* linux/drivers/media/video/samsung/tv20/s5pv210/vp_coeff_s5pv210.h + * + * Video Processor coefficient header file for Samsung TVOut driver + * + * Copyright (c) 2010 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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. +*/ + +/* Horizontal Y 8tap */ +const signed char g_s_vp8tap_coef_y_h[] = { + /* VP_PP_H_NORMAL */ + 0, 0, 0, 0, 127, 0, 0, 0, + 0, 1, -2, 8, 126, -6, 2, -1, + 0, 1, -5, 16, 125, -12, 4, -1, + 0, 2, -8, 25, 121, -16, 5, -1, + -1, 3, -10, 35, 114, -18, 6, -1, + -1, 4, -13, 46, 107, -20, 6, -1, + -1, 5, -16, 57, 99, -21, 6, -1, + -1, 5, -18, 68, 89, -20, 6, -1, + -1, 6, -20, 79, 79, -20, 6, -1, + -1, 6, -20, 89, 68, -18, 5, -1, + -1, 6, -21, 99, 57, -16, 5, -1, + -1, 6, -20, 107, 46, -13, 4, -1, + -1, 6, -18, 114, 35, -10, 3, -1, + -1, 5, -16, 121, 25, -8, 2, 0, + -1, 4, -12, 125, 16, -5, 1, 0, + -1, 2, -6, 126, 8, -2, 1, 0, + + /* VP_PP_H_8_9 */ + 0, 3, -7, 12, 112, 12, -7, 3, + -1, 3, -9, 19, 113, 6, -5, 2, + -1, 3, -11, 27, 111, 0, -3, 2, + -1, 4, -13, 35, 108, -5, -1, 1, + -1, 4, -14, 43, 104, -9, 0, 1, + -1, 5, -16, 52, 99, -12, 1, 0, + -1, 5, -17, 61, 92, -14, 2, 0, + 0, 4, -17, 69, 85, -16, 3, 0, + 0, 4, -17, 77, 77, -17, 4, 0, + 0, 3, -16, 85, 69, -17, 4, 0, + 0, 2, -14, 92, 61, -17, 5, -1, + 0, 1, -12, 99, 52, -16, 5, -1, + 1, 0, -9, 104, 43, -14, 4, -1, + 1, -1, -5, 108, 35, -13, 4, -1, + 2, -3, 0, 111, 27, -11, 3, -1, + 2, -5, 6, 113, 19, -9, 3, -1, + + /* VP_PP_H_1_2 */ + 0, -3, 0, 35, 64, 35, 0, -3, + 0, -3, 1, 38, 64, 32, -1, -3, + 0, -3, 2, 41, 63, 29, -2, -2, + 0, -4, 4, 43, 63, 27, -3, -2, + 0, -4, 5, 46, 62, 24, -3, -2, + 0, -4, 7, 49, 60, 21, -3, -2, + -1, -4, 9, 51, 59, 19, -4, -1, + -1, -4, 12, 53, 57, 16, -4, -1, + -1, -4, 14, 55, 55, 14, -4, -1, + -1, -4, 16, 57, 53, 12, -4, -1, + -1, -4, 19, 59, 51, 9, -4, -1, + -2, -3, 21, 60, 49, 7, -4, 0, + -2, -3, 24, 62, 46, 5, -4, 0, + -2, -3, 27, 63, 43, 4, -4, 0, + -2, -2, 29, 63, 41, 2, -3, 0, + -3, -1, 32, 64, 38, 1, -3, 0, + + /* VP_PP_H_1_3 */ + 0, 0, 10, 32, 44, 32, 10, 0, + -1, 0, 11, 33, 45, 31, 9, 0, + -1, 0, 12, 35, 45, 29, 8, 0, + -1, 1, 13, 36, 44, 28, 7, 0, + -1, 1, 15, 37, 44, 26, 6, 0, + -1, 2, 16, 38, 43, 25, 5, 0, + -1, 2, 18, 39, 43, 23, 5, -1, + -1, 3, 19, 40, 42, 22, 4, -1, + -1, 3, 21, 41, 41, 21, 3, -1, + -1, 4, 22, 42, 40, 19, 3, -1, + -1, 5, 23, 43, 39, 18, 2, -1, + 0, 5, 25, 43, 38, 16, 2, -1, + 0, 6, 26, 44, 37, 15, 1, -1, + 0, 7, 28, 44, 36, 13, 1, -1, + 0, 8, 29, 45, 35, 12, 0, -1, + 0, 9, 31, 45, 33, 11, 0, -1, + + /* VP_PP_H_1_4 */ + 0, 2, 13, 30, 38, 30, 13, 2, + 0, 3, 14, 30, 38, 29, 12, 2, + 0, 3, 15, 31, 38, 28, 11, 2, + 0, 4, 16, 32, 38, 27, 10, 1, + 0, 4, 17, 33, 37, 26, 10, 1, + 0, 5, 18, 34, 37, 24, 9, 1, + 0, 5, 19, 34, 37, 24, 8, 1, + 1, 6, 20, 35, 36, 22, 7, 1, + 1, 6, 21, 36, 36, 21, 6, 1, + 1, 7, 22, 36, 35, 20, 6, 1, + 1, 8, 24, 37, 34, 19, 5, 0, + 1, 9, 24, 37, 34, 18, 5, 0, + 1, 10, 26, 37, 33, 17, 4, 0, + 1, 10, 27, 38, 32, 16, 4, 0, + 2, 11, 28, 38, 31, 15, 3, 0, + 2, 12, 29, 38, 30, 14, 3, 0 +}; + +/* Horizontal C 4tap */ +const signed char g_s_vp4tap_coef_c_h[] = { + /* VP_PP_H_NORMAL */ + 0, 0, 128, 0, + 0, 5, 126, -3, + -1, 11, 124, -6, + -1, 19, 118, -8, + -2, 27, 111, -8, + -3, 37, 102, -8, + -4, 48, 92, -8, + -5, 59, 81, -7, + -6, 70, 70, -6, + -7, 81, 59, -5, + -8, 92, 48, -4, + -8, 102, 37, -3, + -8, 111, 27, -2, + -8, 118, 19, -1, + -6, 124, 11, -1, + -3, 126, 5, 0, + + /* VP_PP_H_8_9 */ + 0, 8, 112, 8, + -1, 13, 113, 3, + -2, 19, 111, 0, + -2, 26, 107, -3, + -3, 34, 101, -4, + -3, 42, 94, -5, + -4, 51, 86, -5, + -5, 60, 78, -5, + -5, 69, 69, -5, + -5, 78, 60, -5, + -5, 86, 51, -4, + -5, 94, 42, -3, + -4, 101, 34, -3, + -3, 107, 26, -2, + 0, 111, 19, -2, + 3, 113, 13, -1, + + /* VP_PP_H_1_2 */ + 0, 26, 76, 26, + 0, 30, 76, 22, + 0, 34, 75, 19, + 1, 38, 73, 16, + 1, 43, 71, 13, + 2, 47, 69, 10, + 3, 51, 66, 8, + 4, 55, 63, 6, + 5, 59, 59, 5, + 6, 63, 55, 4, + 8, 66, 51, 3, + 10, 69, 47, 2, + 13, 71, 43, 1, + 16, 73, 38, 1, + 19, 75, 34, 0, + 22, 76, 30, 0, + + /* VP_PP_H_1_3 */ + 0, 30, 68, 30, + 2, 33, 66, 27, + 3, 36, 66, 23, + 3, 39, 65, 21, + 4, 43, 63, 18, + 5, 46, 62, 15, + 6, 49, 60, 13, + 8, 52, 57, 11, + 9, 55, 55, 9, + 11, 57, 52, 8, + 13, 60, 49, 6, + 15, 62, 46, 5, + 18, 63, 43, 4, + 21, 65, 39, 3, + 23, 66, 36, 3, + 27, 66, 33, 2, + + /* VP_PP_H_1_4 */ + 0, 31, 66, 31, + 3, 34, 63, 28, + 4, 37, 62, 25, + 4, 40, 62, 22, + 5, 43, 61, 19, + 6, 46, 59, 17, + 7, 48, 58, 15, + 9, 51, 55, 13, + 11, 53, 53, 11, + 13, 55, 51, 9, + 15, 58, 48, 7, + 17, 59, 46, 6, + 19, 61, 43, 5, + 22, 62, 40, 4, + 25, 62, 37, 4, + 28, 63, 34, 3, +}; + + +/* Vertical Y 8tap */ +const signed char g_s_vp4tap_coef_y_v[] = { + /* VP_PP_V_NORMAL */ + 0, 0, 127, 0, + 0, 5, 126, -3, + -1, 11, 124, -6, + -1, 19, 118, -8, + -2, 27, 111, -8, + -3, 37, 102, -8, + -4, 48, 92, -8, + -5, 59, 81, -7, + -6, 70, 70, -6, + -7, 81, 59, -5, + -8, 92, 48, -4, + -8, 102, 37, -3, + -8, 111, 27, -2, + -8, 118, 19, -1, + -6, 124, 11, -1, + -3, 126, 5, 0, + + /* VP_PP_V_5_6 */ + 0, 11, 106, 11, + -2, 16, 107, 7, + -2, 22, 105, 3, + -2, 29, 101, 0, + -3, 36, 96, -1, + -3, 44, 90, -3, + -4, 52, 84, -4, + -4, 60, 76, -4, + -4, 68, 68, -4, + -4, 76, 60, -4, + -4, 84, 52, -4, + -3, 90, 44, -3, + -1, 96, 36, -3, + 0, 101, 29, -2, + 3, 105, 22, -2, + 7, 107, 16, -2, + + /* VP_PP_V_3_4 */ + 0, 15, 98, 15, + -2, 21, 97, 12, + -2, 26, 96, 8, + -2, 32, 93, 5, + -2, 39, 89, 2, + -2, 46, 84, 0, + -3, 53, 79, -1, + -2, 59, 73, -2, + -2, 66, 66, -2, + -2, 73, 59, -2, + -1, 79, 53, -3, + 0, 84, 46, -2, + 2, 89, 39, -2, + 5, 93, 32, -2, + 8, 96, 26, -2, + 12, 97, 21, -2, + + /* VP_PP_V_1_2 */ + 0, 26, 76, 26, + 0, 30, 76, 22, + 0, 34, 75, 19, + 1, 38, 73, 16, + 1, 43, 71, 13, + 2, 47, 69, 10, + 3, 51, 66, 8, + 4, 55, 63, 6, + 5, 59, 59, 5, + 6, 63, 55, 4, + 8, 66, 51, 3, + 10, 69, 47, 2, + 13, 71, 43, 1, + 16, 73, 38, 1, + 19, 75, 34, 0, + 22, 76, 30, 0, + + /* VP_PP_V_1_3 */ + 0, 30, 68, 30, + 2, 33, 66, 27, + 3, 36, 66, 23, + 3, 39, 65, 21, + 4, 43, 63, 18, + 5, 46, 62, 15, + 6, 49, 60, 13, + 8, 52, 57, 11, + 9, 55, 55, 9, + 11, 57, 52, 8, + 13, 60, 49, 6, + 15, 62, 46, 5, + 18, 63, 43, 4, + 21, 65, 39, 3, + 23, 66, 36, 3, + 27, 66, 33, 2, + + /* VP_PP_V_1_4 */ + 0, 31, 66, 31, + 3, 34, 63, 28, + 4, 37, 62, 25, + 4, 40, 62, 22, + 5, 43, 61, 19, + 6, 46, 59, 17, + 7, 48, 58, 15, + 9, 51, 55, 13, + 11, 53, 53, 11, + 13, 55, 51, 9, + 15, 58, 48, 7, + 17, 59, 46, 6, + 19, 61, 43, 5, + 22, 62, 40, 4, + 25, 62, 37, 4, + 28, 63, 34, 3 +}; + diff --git a/drivers/media/video/samsung/tv20/s5pv210/vprocessor_s5pv210.c b/drivers/media/video/samsung/tv20/s5pv210/vprocessor_s5pv210.c new file mode 100644 index 0000000..34bcdf2 --- /dev/null +++ b/drivers/media/video/samsung/tv20/s5pv210/vprocessor_s5pv210.c @@ -0,0 +1,814 @@ +/* linux/drivers/media/video/samsung/tv20/s5pv210/vprocessor_s5pv210.c + * + * Video Processor raw ftn file for Samsung TVOut driver + * + * Copyright (c) 2010 Samsung Electronics + * http://www.samsungsemi.com/ + * + * 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 <linux/io.h> + +#include <plat/clock.h> + +#include "tv_out_s5pv210.h" + +#include "regs/regs-vprocessor.h" +#include "vp_coeff_s5pv210.h" + +#ifdef COFIG_TVOUT_RAW_DBG +#define S5P_VP_DEBUG 1 +#endif + +#ifdef S5P_VP_DEBUG +#define VPPRINTK(fmt, args...)\ + printk(KERN_ERR "\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 __s5p_vp_update() function +* for update shadow registers +*/ +void __s5p_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 __s5p_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 __s5p_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; +} + + +enum s5p_tv_vp_err __s5p_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 __s5p_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 __s5p_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 __s5p_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 __s5p_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 __s5p_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. + */ + + /*Horizontal Y 8tap */ + /*Horizontal C 4tap */ + + + if (h_ratio <= (0x1 << 16)) /* 720->720 or zoom in */ + e_h_filter = VPROC_PP_H_NORMAL; + + + + else if (h_ratio <= (0x9 << 13)) /* 720->640 */ + e_h_filter = VPROC_PP_H_8_9; + + + else if (h_ratio <= (0x1 << 17)) /* 2->1 */ + e_h_filter = VPROC_PP_H_1_2; + + + else if (h_ratio <= (0x3 << 16)) /* 2->1 */ + e_h_filter = VPROC_PP_H_1_3; + else + e_h_filter = VPROC_PP_H_1_4; /* 4->1 */ + + /* Vertical Y 4tap */ + + 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 + 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++) { + __s5p_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++) { + __s5p_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++) { + __s5p_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 __s5p_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); + + __s5p_vp_set_src_dest_size(src_width, src_height, dst_width, + dst_height, ipc_2d); + __s5p_vp_set_poly_filter_coef_default(h_ratio, v_ratio); +} + +enum s5p_tv_vp_err __s5p_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 __s5p_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 __s5p_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 __s5p_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; +} + +/* +* get - get info +*/ +enum s5p_vp_field __s5p_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; +} + +/* +* etc +*/ +unsigned short __s5p_vp_get_update_status(void) +{ + VPPRINTK("()\n\r"); + return readl(vp_base + S5P_VP_SHADOW_UPDATE) & + S5P_VP_SHADOW_UPDATE_ENABLE; +} + + +void __s5p_vp_init_field_id(enum s5p_vp_field mode) +{ + __s5p_vp_set_field_id(mode); +} + +void __s5p_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 __s5p_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 __s5p_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 = __s5p_vp_set_top_field_address(top_y_addr, top_c_addr); + + if (error != VPROC_NO_ERROR) + return error; + + error = __s5p_vp_set_bottom_field_address(bottom_y_addr, + bottom_c_addr); + + if (error != VPROC_NO_ERROR) + return error; + + error = __s5p_vp_set_img_size(img_width, img_height); + + if (error != VPROC_NO_ERROR) + return error; + + __s5p_vp_set_src_position(src_off_x, src_x_fract_step, src_off_y); + + __s5p_vp_set_dest_position(dst_off_x, dst_off_y); + + __s5p_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 __s5p_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); + + __s5p_vp_set_poly_filter_coef_default(h_ratio, v_ratio); + error = __s5p_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 __s5p_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 __s5p_vp_set_poly_filter_coef(poly_coeff, ch0, ch1, ch2, ch3); +} + +void __s5p_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 __s5p_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 __s5p_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 __s5p_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 __s5p_vp_init_brightness_contrast_control( + enum s5p_vp_line_eq eq_num, + u32 intc, + u32 slope) +{ + return __s5p_vp_set_brightness_contrast_control(eq_num, intc, slope); +} + +void __s5p_vp_init_brightness(bool brightness) +{ + __s5p_vp_set_brightness(brightness); +} + + +void __s5p_vp_init_contrast(u8 contrast) +{ + __s5p_vp_set_contrast(contrast); +} + +void __s5p_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 __s5p_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 __s5p_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; + break; + } + + 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 __s5p_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 = __s5p_vp_update(); + + VPPRINTK("()\n\r"); + return error; +} + +/* +* stop - stop functions are only called under running video processor +*/ +enum s5p_tv_vp_err __s5p_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 = __s5p_vp_update(); + + while (!(readl(vp_base + S5P_VP_ENABLE) & VP_POWER_DOWN_RDY)) + msleep(1); + + + return error; +} + +/* +* reset - reset function +*/ +void __s5p_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 __s5p_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 __s5p_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; +} + |