return 0;
}
+static void lcdc_layer_csc_mode(struct lcdc_device *lcdc_dev,
+ struct rk_lcdc_win *win)
+{
+ struct rk_screen *screen = lcdc_dev->driver.cur_screen;
+
+ if (lcdc_dev->overlay_mode == VOP_YUV_DOMAIN) {
+ switch (win->fmt_cfg) {
+ case VOP_FORMAT_ARGB888:
+ case VOP_FORMAT_RGB888:
+ case VOP_FORMAT_RGB565:
+ if ((screen->mode.xres < 1280 ) &&
+ (screen->mode.yres < 720)) {
+ win->csc_mode = VOP_R2Y_CSC_BT601;
+ } else {
+ win->csc_mode = VOP_R2Y_CSC_BT709;
+ }
+ break;
+ default:
+ break;
+ }
+ if (win->id == 0) {
+ lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_WIN0_CSC_MODE,
+ v_WIN0_CSC_MODE(win->csc_mode));
+ } else if (win->id == 1) {
+ lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_WIN1_CSC_MODE,
+ v_WIN1_CSC_MODE(win->csc_mode));
+ }
+ } else if (lcdc_dev->overlay_mode == VOP_RGB_DOMAIN) {
+ switch (win->fmt_cfg) {
+ case VOP_FORMAT_YCBCR420:
+ if (win->id == 0) {
+ win->csc_mode = VOP_Y2R_CSC_MPEG;
+ lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_WIN0_CSC_MODE,
+ v_WIN0_CSC_MODE(win->csc_mode));
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+}
+
+
static void lcdc_layer_update_regs(struct lcdc_device *lcdc_dev,
struct rk_lcdc_win *win)
{
u32 mask, val;
if (win->state == 1) {
+ if (lcdc_dev->soc_type == VOP_RK312X)
+ lcdc_layer_csc_mode(lcdc_dev,win);
+
if (win->id == 0) {
mask = m_WIN0_EN | m_WIN0_FORMAT | m_WIN0_RB_SWAP;
val = v_WIN0_EN(win->state) |
mask = m_RGB_DCLK_EN | m_RGB_DCLK_INVERT;
val = v_RGB_DCLK_EN(1) | v_RGB_DCLK_INVERT(0);
lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
+ lcdc_dev->overlay_mode = VOP_RGB_DOMAIN;
}
break;
case SCREEN_LVDS:
mask = m_LVDS_DCLK_EN | m_LVDS_DCLK_INVERT;
val = v_LVDS_DCLK_EN(1) | v_LVDS_DCLK_INVERT(0);
lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
+ lcdc_dev->overlay_mode = VOP_RGB_DOMAIN;
}
break;
case SCREEN_MIPI:
mask = m_MIPI_DCLK_EN | m_MIPI_DCLK_INVERT;
val = v_MIPI_DCLK_EN(1) | v_MIPI_DCLK_INVERT(0);
lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
+ lcdc_dev->overlay_mode = VOP_RGB_DOMAIN;
}
break;
case SCREEN_HDMI:
val |= v_CORE_CLK_DIV_EN(1);
}
lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
+ if (lcdc_dev->soc_type == VOP_RK312X) {
+ lcdc_dev->overlay_mode = VOP_YUV_DOMAIN;
+ }
break;
case SCREEN_TVOUT:
mask = m_TVE_DAC_DCLK_EN;
"unsupported video timing!\n");
return -1;
}
+ if (lcdc_dev->soc_type == VOP_RK312X) {
+ lcdc_dev->overlay_mode = VOP_YUV_DOMAIN;
+ }
break;
default:
dev_err(lcdc_dev->dev, "un supported interface!\n");
break;
}
-
if (lcdc_dev->soc_type == VOP_RK312X) {
switch (screen->face) {
case OUT_P565:
default:
dev_err(lcdc_dev->dev, "un supported interface!\n");
break;
- }
+ }
+ lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_SW_OVERLAY_MODE,
+ v_SW_OVERLAY_MODE(lcdc_dev->overlay_mode));
}
mask = m_DSP_OUT_FORMAT | m_HSYNC_POL | m_VSYNC_POL |
spin_lock(&lcdc_dev->reg_lock);
if (lcdc_dev->clk_on) {
if (open) {
- lcdc_writel(lcdc_dev, BCSH_CTRL, 0x1);
- lcdc_writel(lcdc_dev, BCSH_BCS, 0xd0010000);
- lcdc_writel(lcdc_dev, BCSH_H, 0x01000000);
+ lcdc_writel(lcdc_dev, BCSH_CTRL,
+ v_BCSH_EN(1) | v_BCSH_OUT_MODE(3));
+ lcdc_writel(lcdc_dev, BCSH_BCS,
+ v_BCSH_BRIGHTNESS(0x00) |
+ v_BCSH_CONTRAST(0x80) |
+ v_BCSH_SAT_CON(0x80));
+ lcdc_writel(lcdc_dev, BCSH_H, v_BCSH_COS_HUE(0x80));
} else {
mask = m_BCSH_EN;
val = v_BCSH_EN(0);
}
lcdc_cfg_done(lcdc_dev);
}
+
+ if (lcdc_dev->overlay_mode == VOP_YUV_DOMAIN) {
+ lcdc_msk_reg(lcdc_dev, BCSH_CTRL, m_BCSH_R2Y_CSC_MODE,
+ v_BCSH_R2Y_CSC_MODE(VOP_Y2R_CSC_BYPASS));
+ } else {
+ lcdc_msk_reg(lcdc_dev, BCSH_CTRL, m_BCSH_R2Y_CSC_MODE,
+ v_BCSH_R2Y_CSC_MODE(VOP_Y2R_CSC_MPEG));
+ }
+
spin_unlock(&lcdc_dev->reg_lock);
return 0;
}
#define m_WIN0_ALPHA_MODE BITS(1, 18)
#define m_WIN1_ALPHA_MODE BITS(1, 19)
#define m_WIN0_CSC_MODE BITS(3, 20)
+ #define m_WIN1_CSC_MODE BITS(1, 22)
#define m_WIN0_YUV_CLIP BITS(1, 23)
#define m_TVE_MODE BITS(1, 25)
#define m_SW_UV_OFFSET_EN BITS(1, 26) /* use for rk312x */
#define v_WIN0_ALPHA_MODE(x) BITS_MASK(x, 1, 18)
#define v_WIN1_ALPHA_MODE(x) BITS_MASK(x, 1, 19)
#define v_WIN0_CSC_MODE(x) BITS_MASK(x, 3, 20)
+ #define v_WIN1_CSC_MODE(x) BITS_MASK(x, 1, 22)
#define v_WIN0_YUV_CLIP(x) BITS_MASK(x, 1, 23)
#define v_TVE_MODE(x) BITS_MASK(x, 1, 25)
#define v_SW_UV_OFFSET_EN(x) BITS_MASK(x, 1, 26) /* rk312x */
#define BCSH_H (0xdc)
#define m_BCSH_SIN_HUE BITS(0xff, 0)
- #define m_BCSH_COS_HUE BITS(0xff, 16)
+ #define m_BCSH_COS_HUE BITS(0xff, 8)
#define v_BCSH_SIN_HUE(x) BITS_MASK(x, 0xff, 0)
- #define v_BCSH_COS_HUE(x) BITS_MASK(x, 0xff, 16)
+ #define v_BCSH_COS_HUE(x) BITS_MASK(x, 0xff, 8)
#define FRC_LOWER01_0 (0xe0)
#define FRC_LOWER01_1 (0xe4)
TV_PAL,
};
-enum _vop_csc_mode {
- VOP_CSC_BT601 = 0,
- VOP_CSC_JPEG,
- VOP_CSC_BT709
+enum _vop_r2y_csc_mode {
+ VOP_R2Y_CSC_BT601 = 0,
+ VOP_R2Y_CSC_BT709
+};
+
+enum _vop_y2r_csc_mode {
+ VOP_Y2R_CSC_MPEG = 0,
+ VOP_Y2R_CSC_JPEG,
+ VOP_Y2R_CSC_HD,
+ VOP_Y2R_CSC_BYPASS
};
enum _vop_hwc_size {
VOP_HWC_SIZE_64
};
+enum _vop_overlay_mode {
+ VOP_RGB_DOMAIN,
+ VOP_YUV_DOMAIN
+};
+
+
#define CalScale(x, y) ((((u32)(x - 1)) * 0x1000) / (y - 1))
struct rk_lcdc_drvdata {
u32 s_pixclock;
u32 standby; /* 1:standby,0:work */
+ u16 overlay_mode;
};
static inline void lcdc_writel(struct lcdc_device *lcdc_dev, u32 offset, u32 v)