#include <linux/rockchip/common.h>
#include <dt-bindings/clock/rk_system_status.h>
#if defined(CONFIG_ION_ROCKCHIP)
-#include <linux/rockchip/iovmm.h>
-#include <linux/rockchip/sysmmu.h>
+#include <linux/rockchip-iovmm.h>
#endif
#include "rk3036_lcdc.h"
lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
return 0;
}
-
+/*
static int rk3036_lcdc_disable_irq(struct lcdc_device *lcdc_dev)
{
u32 mask, val;
}
mdelay(1);
return 0;
-}
+}*/
static void rk_lcdc_read_reg_defalut_cfg(struct lcdc_device
*lcdc_dev)
u32 value = 0;
spin_lock(&lcdc_dev->reg_lock);
- for (reg = 0; reg < 0xdc; reg += 4)
+ for (reg = 0; reg < 0xe0; reg += 4)
value = lcdc_readl(lcdc_dev, reg);
spin_unlock(&lcdc_dev->reg_lock);
{
int win0_top = 0;
u32 mask, val;
- enum data_format win0_format = lcdc_dev->driver.win[0]->format;
- enum data_format win1_format = lcdc_dev->driver.win[1]->format;
+ enum data_format win0_format = lcdc_dev->driver.win[0]->area[0].format;
+ enum data_format win1_format = lcdc_dev->driver.win[1]->area[0].format;
int win0_alpha_en = ((win0_format == ARGB888) ||
(win0_format == ABGR888)) ? 1 : 0;
int win1_alpha_en = ((win1_format == ARGB888) ||
(win1_format == ABGR888)) ? 1 : 0;
+ int atv_layer_cnt = lcdc_dev->driver.win[0]->state +
+ lcdc_dev->driver.win[1]->state;
u32 *_pv = (u32 *)lcdc_dev->regsbak;
_pv += (DSP_CTRL0 >> 2);
win0_top = ((*_pv) & (m_WIN0_TOP)) >> 8;
- if (win0_top && (lcdc_dev->atv_layer_cnt >= 2) && (win0_alpha_en)) {
+
+ if (win0_top && (atv_layer_cnt >= 2) && (win0_alpha_en)) {
mask = m_WIN0_ALPHA_EN | m_WIN1_ALPHA_EN |
m_WIN1_PREMUL_SCALE;
val = v_WIN0_ALPHA_EN(1) | v_WIN1_ALPHA_EN(0) |
val = v_WIN0_ALPHA_MODE(1) | v_PREMUL_ALPHA_ENABLE(1) |
v_ALPHA_MODE_SEL1(0);
lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
- } else if ((!win0_top) && (lcdc_dev->atv_layer_cnt >= 2) &&
+ } else if ((!win0_top) && (atv_layer_cnt >= 2) &&
(win1_alpha_en)) {
mask = m_WIN0_ALPHA_EN | m_WIN1_ALPHA_EN |
m_WIN1_PREMUL_SCALE;
val = v_WIN0_ALPHA_EN(0) | v_WIN1_ALPHA_EN(0);
lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, mask, val);
}
+
+ if (lcdc_dev->driver.win[2]->state == 1) {
+ mask = m_HWC_ALPAH_EN;
+ val = v_HWC_ALPAH_EN(1);
+ lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, mask, val);
+
+ mask = m_HWC_ALPHA_MODE;
+ val = v_HWC_ALPHA_MODE(1);
+ lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
+ } else {
+ mask = m_HWC_ALPAH_EN;
+ val = v_HWC_ALPAH_EN(0);
+ lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, mask, val);
+ }
+
return 0;
}
struct rk_lcdc_win *win)
{
u32 mask, val;
+ int hwc_size;
if (win->state == 1) {
if (win->id == 0) {
mask = m_WIN0_EN | m_WIN0_FORMAT | m_WIN0_RB_SWAP;
val = v_WIN0_EN(win->state) |
- v_WIN0_FORMAT(win->fmt_cfg) |
- v_WIN0_RB_SWAP(win->swap_rb);
+ v_WIN0_FORMAT(win->area[0].fmt_cfg) |
+ v_WIN0_RB_SWAP(win->area[0].swap_rb);
lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
-
lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_YRGB,
v_X_SCL_FACTOR(win->scale_yrgb_x) |
v_Y_SCL_FACTOR(win->scale_yrgb_y));
v_DSP_STX(win->area[0].dsp_stx) |
v_DSP_STY(win->area[0].dsp_sty));
lcdc_writel(lcdc_dev, WIN0_DSP_INFO,
- v_DSP_WIDTH(win->area[0].xsize) |
- v_DSP_HEIGHT(win->area[0].ysize));
+ v_DSP_WIDTH(win->post_cfg.xsize) |
+ v_DSP_HEIGHT(win->post_cfg.ysize));
lcdc_writel(lcdc_dev, WIN0_YRGB_MST,
win->area[0].y_addr);
} else if (win->id == 1) {
mask = m_WIN1_EN | m_WIN1_FORMAT | m_WIN1_RB_SWAP;
val = v_WIN1_EN(win->state) |
- v_WIN1_FORMAT(win->fmt_cfg) |
- v_WIN1_RB_SWAP(win->swap_rb);
+ v_WIN1_FORMAT(win->area[0].fmt_cfg) |
+ v_WIN1_RB_SWAP(win->area[0].swap_rb);
lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
-
lcdc_writel(lcdc_dev, WIN1_SCL_FACTOR_YRGB,
v_X_SCL_FACTOR(win->scale_yrgb_x) |
v_Y_SCL_FACTOR(win->scale_yrgb_y));
v_ACT_WIDTH(win->area[0].xact) |
v_ACT_HEIGHT(win->area[0].yact));
lcdc_writel(lcdc_dev, WIN1_DSP_INFO,
- v_DSP_WIDTH(win->area[0].xsize) |
- v_DSP_HEIGHT(win->area[0].ysize));
+ v_DSP_WIDTH(win->post_cfg.xsize) |
+ v_DSP_HEIGHT(win->post_cfg.ysize));
lcdc_writel(lcdc_dev, WIN1_DSP_ST,
v_DSP_STX(win->area[0].dsp_stx) |
v_DSP_STY(win->area[0].dsp_sty));
lcdc_writel(lcdc_dev, WIN1_MST, win->area[0].y_addr);
- } /* else if (win->id == 2) {
- }*/
+ } else if (win->id == 2) {
+ mask = m_HWC_EN | m_HWC_LODAD_EN;
+ val = v_HWC_EN(win->state) | v_HWC_LODAD_EN(1);
+ lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
+ if ((win->area[0].xsize == 32) &&
+ (win->area[0].ysize == 32))
+ hwc_size = 0;
+ else if ((win->area[0].xsize == 64) &&
+ (win->area[0].ysize == 64))
+ hwc_size = 1;
+ else
+ dev_err(lcdc_dev->dev,
+ "unsupport hwc size:x=%d,y=%d\n",
+ win->area[0].xsize,
+ win->area[0].ysize);
+ lcdc_writel(lcdc_dev, HWC_DSP_ST,
+ v_DSP_STX(win->area[0].dsp_stx) |
+ v_DSP_STY(win->area[0].dsp_sty));
+ lcdc_writel(lcdc_dev, HWC_MST, win->area[0].y_addr);
+ }
} else {
win->area[0].y_addr = 0;
win->area[0].uv_addr = 0;
- if (win->id == 0)
+ if (win->id == 0) {
lcdc_msk_reg(lcdc_dev,
SYS_CTRL, m_WIN0_EN, v_WIN0_EN(0));
- else if (win->id == 1)
+ lcdc_writel(lcdc_dev, WIN0_YRGB_MST,
+ win->area[0].y_addr);
+ lcdc_writel(lcdc_dev, WIN0_CBR_MST,
+ win->area[0].uv_addr);
+ } else if (win->id == 1) {
lcdc_msk_reg(lcdc_dev,
SYS_CTRL, m_WIN1_EN, v_WIN1_EN(0));
- else if (win->id == 2)
+ lcdc_writel(lcdc_dev, WIN1_MST, win->area[0].y_addr);
+ } else if (win->id == 2) {
lcdc_msk_reg(lcdc_dev,
- SYS_CTRL, m_HWC_EN, v_HWC_EN(0));
+ SYS_CTRL, m_HWC_EN | m_HWC_LODAD_EN,
+ v_HWC_EN(0) | v_HWC_LODAD_EN(0));
+ lcdc_writel(lcdc_dev, HWC_MST, win->area[0].y_addr);
+ }
}
rk3036_lcdc_alpha_cfg(lcdc_dev);
}
"wakeup from standby!\n");
lcdc_dev->standby = 0;
}
- lcdc_dev->atv_layer_cnt++;
- } else if ((lcdc_dev->atv_layer_cnt > 0) && (!open)) {
- lcdc_dev->atv_layer_cnt--;
+ lcdc_dev->atv_layer_cnt |= (1 << win_id);
+ } else if ((lcdc_dev->atv_layer_cnt & (1 << win_id)) && (!open)) {
+ lcdc_dev->atv_layer_cnt &= ~(1 << win_id);
}
lcdc_dev->driver.win[win_id]->state = open;
if (!open) {
}
spin_unlock(&lcdc_dev->reg_lock);
}
-
+/*
static int rk3036_lcdc_reg_update(struct rk_lcdc_driver *dev_drv)
{
struct lcdc_device *lcdc_dev =
lcdc_cfg_done(lcdc_dev);
}
spin_unlock(&lcdc_dev->reg_lock);
- /* if (dev_drv->wait_fs) { */
if (0) {
spin_lock_irqsave(&dev_drv->cpl_lock, flags);
init_completion(&dev_drv->frame_done);
DBG(2, "%s for lcdc%d\n", __func__, lcdc_dev->id);
return 0;
}
-
+*/
static void rk3036_lcdc_reg_restore(struct lcdc_device *lcdc_dev)
{
- memcpy((u8 *)lcdc_dev->regs, (u8 *)lcdc_dev->regsbak, 0xdc);
+ memcpy((u8 *)lcdc_dev->regs, (u8 *)lcdc_dev->regsbak, 0xe0);
}
static void rk3036_lcdc_mmu_en(struct rk_lcdc_driver *dev_drv)
struct lcdc_device *lcdc_dev =
container_of(dev_drv, struct lcdc_device, driver);
- spin_lock(&lcdc_dev->reg_lock);
+ /*spin_lock(&lcdc_dev->reg_lock);*/
if (likely(lcdc_dev->clk_on)) {
mask = m_MMU_EN | m_AXI_MAX_OUTSTANDING_EN |
m_AXI_OUTSTANDING_MAX_NUM;
v_AXI_MAX_OUTSTANDING_EN(1);
lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
}
+ /*spin_unlock(&lcdc_dev->reg_lock);*/
+}
+
+static int rk3036_lcdc_set_hwc_lut(struct rk_lcdc_driver *dev_drv,
+ int *hwc_lut, int mode)
+{
+ int i = 0;
+ int __iomem *c;
+ int v;
+ int len = 256*4;
+
+ struct lcdc_device *lcdc_dev =
+ container_of(dev_drv, struct lcdc_device, driver);
+ if (dev_drv->hwc_lut == NULL)
+ dev_drv->hwc_lut = devm_kzalloc(lcdc_dev->dev, len, GFP_KERNEL);
+
+ spin_lock(&lcdc_dev->reg_lock);
+ lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_HWC_LUT_EN, v_HWC_LUT_EN(0));
+ lcdc_cfg_done(lcdc_dev);
+ mdelay(25);
+ for (i = 0; i < 256; i++) {
+ if (mode == 1)
+ dev_drv->hwc_lut[i] = hwc_lut[i];
+ v = dev_drv->hwc_lut[i];
+ c = lcdc_dev->hwc_lut_addr_base + i;
+ writel_relaxed(v, c);
+ }
+ lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_HWC_LUT_EN, v_HWC_LUT_EN(1));
+ lcdc_cfg_done(lcdc_dev);
spin_unlock(&lcdc_dev->reg_lock);
+ return 0;
}
+#if 0
static int rk3036_lcdc_set_dclk(struct rk_lcdc_driver *dev_drv)
{
#ifdef CONFIG_RK_FPGA
lcdc_dev->driver.name, clk_get_rate(lcdc_dev->dclk), fps);
return 0;
}
-
+#endif
/********do basic init*********/
static int rk3036_lcdc_pre_init(struct rk_lcdc_driver *dev_drv)
{
/*backup reg config at uboot*/
rk_lcdc_read_reg_defalut_cfg(lcdc_dev);
+ if (lcdc_readl(lcdc_dev, AXI_BUS_CTRL) & m_TVE_DAC_DCLK_EN)
+ dev_drv->cur_screen->type = SCREEN_TVOUT;
+
lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_AUTO_GATING_EN,
v_AUTO_GATING_EN(0));
lcdc_cfg_done(lcdc_dev);
v_HASP(screen->mode.hsync_len + left_margin);
lcdc_writel(lcdc_dev, DSP_HACT_ST_END, val);
- if (screen->mode.vmode == FB_VMODE_INTERLACED) {
+ if (screen->mode.vmode & FB_VMODE_INTERLACED) {
/*First Field Timing*/
lcdc_writel(lcdc_dev, DSP_VTOTAL_VS_END,
v_VSYNC(screen->mode.vsync_len) |
m_INTERLACE_DSP_POL |
m_WIN1_DIFF_DCLK_EN |
m_WIN0_YRGB_DEFLICK_EN |
- m_WIN0_CBR_DEFLICK_EN,
+ m_WIN0_CBR_DEFLICK_EN |
+ m_WIN0_INTERLACE_EN |
+ m_WIN1_INTERLACE_EN,
v_INTERLACE_DSP_EN(1) |
v_INTERLACE_DSP_POL(0) |
v_WIN1_DIFF_DCLK_EN(1) |
v_WIN0_YRGB_DEFLICK_EN(1) |
- v_WIN0_CBR_DEFLICK_EN(1));
+ v_WIN0_CBR_DEFLICK_EN(1) |
+ v_WIN0_INTERLACE_EN(1) |
+ v_WIN1_INTERLACE_EN(1));
} else {
val = v_VSYNC(screen->mode.vsync_len) |
v_VERPRD(screen->mode.vsync_len + upper_margin +
m_INTERLACE_DSP_EN |
m_WIN1_DIFF_DCLK_EN |
m_WIN0_YRGB_DEFLICK_EN |
- m_WIN0_CBR_DEFLICK_EN,
+ m_WIN0_CBR_DEFLICK_EN |
+ m_WIN0_INTERLACE_EN |
+ m_WIN1_INTERLACE_EN,
v_INTERLACE_DSP_EN(0) |
v_WIN1_DIFF_DCLK_EN(0) |
v_WIN0_YRGB_DEFLICK_EN(0) |
- v_WIN0_CBR_DEFLICK_EN(0));
+ v_WIN0_CBR_DEFLICK_EN(0) |
+ v_WIN0_INTERLACE_EN(1) |
+ v_WIN1_INTERLACE_EN(1));
}
}
spin_unlock(&lcdc_dev->reg_lock);
if ((open) && (!lcdc_dev->atv_layer_cnt)) {
rk3036_lcdc_pre_init(dev_drv);
rk3036_lcdc_clk_enable(lcdc_dev);
- #if defined(CONFIG_ROCKCHIP_IOMMU)
if (dev_drv->iommu_enabled) {
if (!dev_drv->mmu_dev) {
dev_drv->mmu_dev =
- rockchip_get_sysmmu_device_by_compatible(
+ rk_fb_get_sysmmu_device_by_compatible(
dev_drv->mmu_dts_name);
if (dev_drv->mmu_dev) {
- platform_set_sysmmu(dev_drv->mmu_dev,
- dev_drv->dev);
+ rk_fb_platform_set_sysmmu(dev_drv->mmu_dev,
+ dev_drv->dev);
} else {
dev_err(dev_drv->dev,
"failed to get iommu device\n"
return -1;
}
}
- iovmm_activate(dev_drv->dev);
}
- #endif
rk3036_lcdc_reg_restore(lcdc_dev);
- if (dev_drv->iommu_enabled)
- rk3036_lcdc_mmu_en(dev_drv);
+ /*if (dev_drv->iommu_enabled)
+ rk3036_lcdc_mmu_en(dev_drv);*/
if ((support_uboot_display() && (lcdc_dev->prop == PRMRY))) {
- rk3036_lcdc_set_dclk(dev_drv);
+ /*rk3036_lcdc_set_dclk(dev_drv);*/
rk3036_lcdc_enable_irq(dev_drv);
} else {
rk3036_load_screen(dev_drv, 1);
dev_err(lcdc_dev->dev, "invalid win id:%d\n", win_id);
/*when all layer closed,disable clk */
+/*
if ((!open) && (!lcdc_dev->atv_layer_cnt)) {
rk3036_lcdc_disable_irq(lcdc_dev);
rk3036_lcdc_reg_update(dev_drv);
- #if defined(CONFIG_ROCKCHIP_IOMMU)
if (dev_drv->iommu_enabled) {
if (dev_drv->mmu_dev)
- iovmm_deactivate(dev_drv->dev);
+ rockchip_iovmm_deactivate(dev_drv->dev);
}
- #endif
rk3036_lcdc_clk_disable(lcdc_dev);
}
-
+*/
return 0;
}
win = dev_drv->win[0];
} else if (win_id == 1) {
win = dev_drv->win[1];
+ } else if (win_id == 2) {
+ win = dev_drv->win[2];
} else {
dev_err(dev_drv->dev, "un supported win number:%d\n", win_id);
return -EINVAL;
}
spin_lock(&lcdc_dev->reg_lock);
- win->area[0].dsp_stx = win->area[0].xpos +
- screen->mode.left_margin +
+ win->post_cfg.xpos = win->area[0].xpos * (dev_drv->overscan.left +
+ dev_drv->overscan.right)/200 + screen->mode.xres *
+ (100 - dev_drv->overscan.left) / 200;
+
+ win->post_cfg.ypos = win->area[0].ypos * (dev_drv->overscan.top +
+ dev_drv->overscan.bottom)/200 +
+ screen->mode.yres *
+ (100 - dev_drv->overscan.top) / 200;
+ win->post_cfg.xsize = win->area[0].xsize *
+ (dev_drv->overscan.left +
+ dev_drv->overscan.right)/200;
+ win->post_cfg.ysize = win->area[0].ysize *
+ (dev_drv->overscan.top +
+ dev_drv->overscan.bottom)/200;
+
+ win->area[0].dsp_stx = win->post_cfg.xpos + screen->mode.left_margin +
screen->mode.hsync_len;
- if (screen->mode.vmode == FB_VMODE_INTERLACED) {
- win->area[0].ysize /= 2;
- win->area[0].dsp_sty = win->area[0].ypos/2 +
+ if (screen->mode.vmode & FB_VMODE_INTERLACED) {
+ win->post_cfg.ysize /= 2;
+ win->area[0].dsp_sty = win->post_cfg.ypos/2 +
screen->mode.upper_margin +
screen->mode.vsync_len;
} else {
- win->area[0].dsp_sty = win->area[0].ypos +
+ win->area[0].dsp_sty = win->post_cfg.ypos +
screen->mode.upper_margin +
screen->mode.vsync_len;
}
- win->scale_yrgb_x = calscale(win->area[0].xact, win->area[0].xsize);
- win->scale_yrgb_y = calscale(win->area[0].yact, win->area[0].ysize);
- switch (win->format) {
+ win->scale_yrgb_x = calscale(win->area[0].xact, win->post_cfg.xsize);
+ win->scale_yrgb_y = calscale(win->area[0].yact, win->post_cfg.ysize);
+
+ switch (win->area[0].format) {
case ARGB888:
- win->fmt_cfg = VOP_FORMAT_ARGB888;
- win->swap_rb = 0;
+ win->area[0].fmt_cfg = VOP_FORMAT_ARGB888;
+ win->area[0].swap_rb = 0;
break;
case XBGR888:
- win->fmt_cfg = VOP_FORMAT_ARGB888;
- win->swap_rb = 1;
+ win->area[0].fmt_cfg = VOP_FORMAT_ARGB888;
+ win->area[0].swap_rb = 1;
break;
case ABGR888:
- win->fmt_cfg = VOP_FORMAT_ARGB888;
- win->swap_rb = 1;
+ win->area[0].fmt_cfg = VOP_FORMAT_ARGB888;
+ win->area[0].swap_rb = 1;
break;
case RGB888:
- win->fmt_cfg = VOP_FORMAT_RGB888;
- win->swap_rb = 0;
+ win->area[0].fmt_cfg = VOP_FORMAT_RGB888;
+ win->area[0].swap_rb = 0;
break;
case RGB565:
- win->fmt_cfg = VOP_FORMAT_RGB565;
- win->swap_rb = 0;
+ win->area[0].fmt_cfg = VOP_FORMAT_RGB565;
+ win->area[0].swap_rb = 0;
break;
case YUV444:
if (win_id == 0) {
- win->fmt_cfg = VOP_FORMAT_YCBCR444;
+ win->area[0].fmt_cfg = VOP_FORMAT_YCBCR444;
win->scale_cbcr_x = calscale(win->area[0].xact,
- win->area[0].xsize);
+ win->post_cfg.xsize);
win->scale_cbcr_y = calscale(win->area[0].yact,
- win->area[0].ysize);
- win->swap_rb = 0;
+ win->post_cfg.ysize);
+ win->area[0].swap_rb = 0;
} else {
dev_err(lcdc_dev->driver.dev,
"%s:un supported format!\n",
break;
case YUV422:
if (win_id == 0) {
- win->fmt_cfg = VOP_FORMAT_YCBCR422;
+ win->area[0].fmt_cfg = VOP_FORMAT_YCBCR422;
win->scale_cbcr_x = calscale((win->area[0].xact / 2),
- win->area[0].xsize);
+ win->post_cfg.xsize);
win->scale_cbcr_y = calscale(win->area[0].yact,
- win->area[0].ysize);
- win->swap_rb = 0;
+ win->post_cfg.ysize);
+ win->area[0].swap_rb = 0;
} else {
dev_err(lcdc_dev->driver.dev,
"%s:un supported format!\n",
break;
case YUV420:
if (win_id == 0) {
- win->fmt_cfg = VOP_FORMAT_YCBCR420;
+ win->area[0].fmt_cfg = VOP_FORMAT_YCBCR420;
win->scale_cbcr_x = calscale(win->area[0].xact / 2,
- win->area[0].xsize);
+ win->post_cfg.xsize);
win->scale_cbcr_y = calscale(win->area[0].yact / 2,
- win->area[0].ysize);
- win->swap_rb = 0;
+ win->post_cfg.ysize);
+ win->area[0].swap_rb = 0;
} else {
dev_err(lcdc_dev->driver.dev,
"%s:un supported format!\n",
}
spin_unlock(&lcdc_dev->reg_lock);
- DBG(1, "lcdc%d>>%s\n"
+ DBG(2, "lcdc%d>>%s\n"
">>format:%s>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d\n"
">>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n", lcdc_dev->id,
- __func__, get_format_string(win->format, fmt),
- win->area[0].xact, win->area[0].yact, win->area[0].xsize,
- win->area[0].ysize, win->area[0].xvir, win->area[0].yvir,
- win->area[0].xpos, win->area[0].ypos);
+ __func__, get_format_string(win->area[0].format, fmt),
+ win->area[0].xact, win->area[0].yact, win->post_cfg.xsize,
+ win->post_cfg.ysize, win->area[0].xvir, win->area[0].yvir,
+ win->post_cfg.xpos, win->post_cfg.ypos);
return 0;
}
win = dev_drv->win[0];
} else if (win_id == 1) {
win = dev_drv->win[1];
+ } else if (win_id == 2) {
+ win = dev_drv->win[2];
} else {
dev_err(dev_drv->dev, "invalid win number:%d!\n", win_id);
return -EINVAL;
}
static int rk3036_lcdc_get_win_state(struct rk_lcdc_driver *dev_drv,
- int win_id)
+ int win_id,
+ int area_id)
{
return dev_drv->win[win_id]->state;
}
{
struct lcdc_device *lcdc_dev =
container_of(dev_drv, struct lcdc_device, driver);
- int ovl;
-
+ struct rk_lcdc_win *win0 = lcdc_dev->driver.win[0];
+ struct rk_lcdc_win *win1 = lcdc_dev->driver.win[1];
+ int ovl, needswap = 0;
+
+ if (!swap) {
+ if (win0->z_order >= 0 &&
+ win1->z_order >= 0 &&
+ win0->z_order > win1->z_order)
+ needswap = 1;
+ else
+ needswap = 0;
+ } else {
+ needswap = swap;
+ }
spin_lock(&lcdc_dev->reg_lock);
if (lcdc_dev->clk_on) {
if (set) {
lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_WIN0_TOP,
- v_WIN0_TOP(swap));
+ v_WIN0_TOP(needswap));
ovl = swap;
} else {
ovl = lcdc_read_bit(lcdc_dev, DSP_CTRL0, m_WIN0_TOP);
lcdc_cfg_done(lcdc_dev);
if (dev_drv->iommu_enabled) {
if (dev_drv->mmu_dev)
- iovmm_deactivate(dev_drv->dev);
+ rockchip_iovmm_deactivate(dev_drv->dev);
}
spin_unlock(&lcdc_dev->reg_lock);
} else {
if (lcdc_dev->atv_layer_cnt) {
rk3036_lcdc_clk_enable(lcdc_dev);
rk3036_lcdc_reg_restore(lcdc_dev);
+ /*set hwc lut*/
+ rk3036_lcdc_set_hwc_lut(dev_drv, dev_drv->hwc_lut, 0);
spin_lock(&lcdc_dev->reg_lock);
lcdc_cfg_done(lcdc_dev);
if (dev_drv->iommu_enabled) {
if (dev_drv->mmu_dev)
- iovmm_activate(dev_drv->dev);
+ rockchip_iovmm_activate(dev_drv->dev);
}
spin_unlock(&lcdc_dev->reg_lock);
}
static int rk3036_lcdc_cfg_done(struct rk_lcdc_driver *dev_drv)
{
- struct lcdc_device *lcdc_dev = container_of(dev_drv,
- struct lcdc_device, driver);
+ struct lcdc_device *lcdc_dev =
+ container_of(dev_drv, struct lcdc_device, driver);
+ int i;
+ struct rk_lcdc_win *win = NULL;
spin_lock(&lcdc_dev->reg_lock);
if (lcdc_dev->clk_on) {
+ if (dev_drv->iommu_enabled) {
+ if (!lcdc_dev->iommu_status && dev_drv->mmu_dev) {
+ lcdc_dev->iommu_status = 1;
+ if (support_uboot_display() &&
+ lcdc_dev->prop == PRMRY) {
+ lcdc_msk_reg(lcdc_dev, SYS_CTRL,
+ m_WIN0_EN,
+ v_WIN0_EN(0));
+ }
+ lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
+ v_LCDC_STANDBY(1));
+ lcdc_cfg_done(lcdc_dev);
+ mdelay(50);
+ rockchip_iovmm_activate(dev_drv->dev);
+ rk3036_lcdc_mmu_en(dev_drv);
+ }
+ }
lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
v_LCDC_STANDBY(lcdc_dev->standby));
+ for (i = 0; i < ARRAY_SIZE(lcdc_win); i++) {
+ win = dev_drv->win[i];
+ if ((win->state == 0) && (win->last_state == 1))
+ lcdc_layer_update_regs(lcdc_dev, win);
+ win->last_state = win->state;
+ }
lcdc_cfg_done(lcdc_dev);
}
spin_unlock(&lcdc_dev->reg_lock);
return 0;
}
-static int rk3036_fb_win_remap(struct rk_lcdc_driver *dev_drv,
- enum fb_win_map_order order)
+static int rk3036_lcdc_set_overscan(struct rk_lcdc_driver *dev_drv,
+ struct overscan *overscan)
+{
+ int i;
+
+ dev_drv->overscan = *overscan;
+ for (i = 0; i < dev_drv->lcdc_win_num; i++) {
+ if (dev_drv->win[i] && dev_drv->win[i]->state) {
+ rk3036_lcdc_set_par(dev_drv, i);
+ rk3036_lcdc_pan_display(dev_drv, i);
+ }
+ }
+ rk3036_lcdc_cfg_done(dev_drv);
+ return 0;
+}
+
+static int rk3036_fb_win_remap(struct rk_lcdc_driver *dev_drv, u16 order)
{
+ struct rk_lcdc_win_area area;
+ int fb2_win_id, fb1_win_id, fb0_win_id;
+
mutex_lock(&dev_drv->fb_win_id_mutex);
if (order == FB_DEFAULT_ORDER)
- order = FB0_WIN1_FB1_WIN0_FB2_WIN2;
- dev_drv->fb2_win_id = order / 100;
- dev_drv->fb1_win_id = (order / 10) % 10;
- dev_drv->fb0_win_id = order % 10;
+ order = FB0_WIN0_FB1_WIN1_FB2_WIN2;
+
+ fb2_win_id = order / 100;
+ fb1_win_id = (order / 10) % 10;
+ fb0_win_id = order % 10;
+
+ if (fb0_win_id != dev_drv->fb0_win_id) {
+ area = dev_drv->win[(int)dev_drv->fb0_win_id]->area[0];
+ dev_drv->win[(int)dev_drv->fb0_win_id]->area[0] =
+ dev_drv->win[fb0_win_id]->area[0];
+ dev_drv->win[fb0_win_id]->area[0] = area;
+ dev_drv->fb0_win_id = fb0_win_id;
+ }
+ dev_drv->fb1_win_id = fb1_win_id;
+ dev_drv->fb2_win_id = fb2_win_id;
+
mutex_unlock(&dev_drv->fb_win_id_mutex);
return 0;
}
static int rk3036_lcdc_get_dsp_addr(struct rk_lcdc_driver *dev_drv,
- unsigned int *dsp_addr)
+ unsigned int dsp_addr[][4])
{
struct lcdc_device *lcdc_dev =
container_of(dev_drv, struct lcdc_device, driver);
if (lcdc_dev->clk_on) {
- dsp_addr[0] = lcdc_readl(lcdc_dev, WIN0_YRGB_MST);
- dsp_addr[1] = lcdc_readl(lcdc_dev, WIN1_MST);
+ dsp_addr[0][0] = lcdc_readl(lcdc_dev, WIN0_YRGB_MST);
+ dsp_addr[1][0] = lcdc_readl(lcdc_dev, WIN1_MST);
}
return 0;
}
}
size = snprintf(buf, PAGE_SIZE, "win%d: %s\n", win_id,
- get_format_string(win->format, fmt));
+ get_format_string(win->area[0].format, fmt));
size += snprintf(buf + size, PAGE_SIZE - size,
" xact %d yact %d xvir %d yvir %d\n",
win->area[0].xact, win->area[0].yact,
.get_dsp_bcsh_hue = rk3036_lcdc_get_bcsh_hue,
.get_dsp_bcsh_bcs = rk3036_lcdc_get_bcsh_bcs,
.open_bcsh = rk3036_lcdc_open_bcsh,
+ .set_overscan = rk3036_lcdc_set_overscan,
+ .set_hwc_lut = rk3036_lcdc_set_hwc_lut,
};
static int rk3036_lcdc_parse_dt(struct lcdc_device *lcdc_dev)
{
-#if defined(CONFIG_ROCKCHIP_IOMMU)
struct device_node *np = lcdc_dev->dev->of_node;
int val;
lcdc_dev->driver.iommu_enabled = 0;
else
lcdc_dev->driver.iommu_enabled = val;
-#else
- lcdc_dev->driver.iommu_enabled = 0;
-#endif
+ if (of_property_read_u32(np, "rockchip,fb-win-map", &val))
+ lcdc_dev->driver.fb_win_map = FB_DEFAULT_ORDER;
+ else
+ lcdc_dev->driver.fb_win_map = val;
+
return 0;
}
if (IS_ERR(lcdc_dev->regsbak))
return PTR_ERR(lcdc_dev->regsbak);
+ lcdc_dev->hwc_lut_addr_base = (lcdc_dev->regs + HWC_LUT_ADDR);
+ lcdc_dev->prop = PRMRY;
dev_set_name(lcdc_dev->dev, "lcdc%d", lcdc_dev->id);
dev_drv = &lcdc_dev->driver;
dev_drv->dev = dev;
}
if (dev_drv->iommu_enabled)
- strcpy(dev_drv->mmu_dts_name, "iommu,vop_mmu");
+ strcpy(dev_drv->mmu_dts_name, VOP_IOMMU_COMPATIBLE_NAME);
ret = rk_fb_register(dev_drv, lcdc_win, lcdc_dev->id);
if (ret < 0) {
}
fs_initcall(rk3036_lcdc_module_init);
-module_exit(rk3036_lcdc_module_exit);
\ No newline at end of file
+module_exit(rk3036_lcdc_module_exit);