mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 20:07:46 +09:00
rk3036 lcdc: add support hwc layer
This commit is contained in:
@@ -602,7 +602,7 @@
|
||||
|
||||
lcdc: lcdc@10118000 {
|
||||
compatible = "rockchip,rk3036-lcdc";
|
||||
reg = <0x10118000 0x200>;
|
||||
reg = <0x10118000 0x1000>;
|
||||
interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
|
||||
status = "disabled";
|
||||
clocks = <&clk_gates9 6>, <&dclk_lcdc1>, <&clk_gates9 5>;
|
||||
|
||||
@@ -221,6 +221,21 @@ static int rk3036_lcdc_alpha_cfg(struct lcdc_device *lcdc_dev)
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -228,6 +243,7 @@ static void lcdc_layer_update_regs(struct lcdc_device *lcdc_dev,
|
||||
struct rk_lcdc_win *win)
|
||||
{
|
||||
u32 mask, val;
|
||||
int hwc_size;
|
||||
|
||||
if (win->state == 1) {
|
||||
if (win->id == 0) {
|
||||
@@ -282,8 +298,22 @@ static void lcdc_layer_update_regs(struct lcdc_device *lcdc_dev,
|
||||
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;
|
||||
@@ -392,6 +422,35 @@ static void rk3036_lcdc_mmu_en(struct rk_lcdc_driver *dev_drv)
|
||||
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;
|
||||
|
||||
}
|
||||
static int rk3036_lcdc_set_dclk(struct rk_lcdc_driver *dev_drv)
|
||||
{
|
||||
#ifdef CONFIG_RK_FPGA
|
||||
@@ -718,6 +777,8 @@ static int rk3036_lcdc_set_par(struct rk_lcdc_driver *dev_drv, int win_id)
|
||||
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;
|
||||
@@ -850,7 +911,9 @@ static int rk3036_lcdc_pan_display(struct rk_lcdc_driver *dev_drv, int win_id)
|
||||
win = dev_drv->win[0];
|
||||
} else if (win_id == 1) {
|
||||
win = dev_drv->win[1];
|
||||
} else {
|
||||
} 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;
|
||||
}
|
||||
@@ -1007,6 +1070,8 @@ static int rk3036_lcdc_early_resume(struct rk_lcdc_driver *dev_drv)
|
||||
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);
|
||||
|
||||
@@ -1404,6 +1469,7 @@ static struct rk_lcdc_drv_ops lcdc_drv_ops = {
|
||||
.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)
|
||||
@@ -1456,6 +1522,8 @@ static int rk3036_lcdc_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(lcdc_dev->regsbak))
|
||||
return PTR_ERR(lcdc_dev->regsbak);
|
||||
|
||||
lcdc_dev->hwc_lut_addr_base = (lcdc_dev->regs + HWC_LUT_ADDR);
|
||||
|
||||
dev_set_name(lcdc_dev->dev, "lcdc%d", lcdc_dev->id);
|
||||
dev_drv = &lcdc_dev->driver;
|
||||
dev_drv->dev = dev;
|
||||
@@ -1553,4 +1621,4 @@ static void __exit rk3036_lcdc_module_exit(void)
|
||||
}
|
||||
|
||||
fs_initcall(rk3036_lcdc_module_init);
|
||||
module_exit(rk3036_lcdc_module_exit);
|
||||
module_exit(rk3036_lcdc_module_exit);
|
||||
|
||||
@@ -481,6 +481,7 @@ struct lcdc_device {
|
||||
spinlock_t reg_lock; /* one time only one process allowed to
|
||||
config the register*/
|
||||
|
||||
int __iomem *hwc_lut_addr_base;
|
||||
int __iomem *dsp_lut_addr_base;
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user