return vscalednmult;
}
+
+static int rk3368_set_cabc_lut(struct rk_lcdc_driver *dev_drv, int *cabc_lut)
+{
+ int i;
+ int __iomem *c;
+ u32 v;
+ struct lcdc_device *lcdc_dev =
+ container_of(dev_drv, struct lcdc_device, driver);
+
+ lcdc_msk_reg(lcdc_dev, CABC_CTRL1, m_CABC_LUT_EN,
+ v_CABC_LUT_EN(0));
+ lcdc_cfg_done(lcdc_dev);
+ mdelay(25);
+ for (i = 0; i < 256; i++) {
+ v = cabc_lut[i];
+ c = lcdc_dev->cabc_lut_addr_base + i;
+ writel_relaxed(v, c);
+ }
+ lcdc_msk_reg(lcdc_dev, CABC_CTRL1, m_CABC_LUT_EN,
+ v_CABC_LUT_EN(1));
+ return 0;
+}
+
+
static int rk3368_lcdc_set_lut(struct rk_lcdc_driver *dev_drv, int *dsp_lut)
{
int i;
u32 v;
struct lcdc_device *lcdc_dev =
container_of(dev_drv, struct lcdc_device, driver);
- lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN, v_DSP_LUT_EN(0));
+
+ lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN,
+ v_DSP_LUT_EN(0));
lcdc_cfg_done(lcdc_dev);
mdelay(25);
for (i = 0; i < 256; i++) {
c = lcdc_dev->dsp_lut_addr_base + i;
writel_relaxed(v, c);
}
- lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN, v_DSP_LUT_EN(1));
+ lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN,
+ v_DSP_LUT_EN(1));
return 0;
}
mask = m_AUTO_GATING_EN;
val = v_AUTO_GATING_EN(0);
+ lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
lcdc_cfg_done(lcdc_dev);
/*disable win0 to workaround iommu pagefault */
/*if (dev_drv->iommu_enabled) */
else
lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN,
v_DSP_LUT_EN(1));
+ if (screen->cabc_lut == NULL) {
+ lcdc_msk_reg(lcdc_dev, CABC_CTRL0, m_CABC_EN,
+ v_CABC_EN(0));
+ } else {
+ lcdc_msk_reg(lcdc_dev, CABC_CTRL1, m_CABC_LUT_EN,
+ v_CABC_LUT_EN(1));
+ }
rk3368_lcdc_bcsh_path_sel(dev_drv);
rk3368_config_timing(dev_drv);
}
if (dev_drv->cur_screen->dsp_lut)
rk3368_lcdc_set_lut(dev_drv,
dev_drv->cur_screen->dsp_lut);
+ if (dev_drv->cur_screen->cabc_lut)
+ rk3368_set_cabc_lut(dev_drv,
+ dev_drv->cur_screen->cabc_lut);
spin_unlock(&lcdc_dev->reg_lock);
}
if (dev_drv->cur_screen->dsp_lut)
rk3368_lcdc_set_lut(dev_drv,
dev_drv->cur_screen->dsp_lut);
+ if (dev_drv->cur_screen->cabc_lut)
+ rk3368_set_cabc_lut(dev_drv,
+ dev_drv->cur_screen->cabc_lut);
lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_OUT_ZERO,
v_DSP_OUT_ZERO(0));
}
static struct lcdc_cabc_mode cabc_mode[4] = {
- /* pixel_num,8 stage_up, stage_down */
- {5, 282, 171, 300}, /*mode 1 */
- {10, 282, 171, 300}, /*mode 2 */
- {15, 282, 171, 300}, /*mode 3 */
- {20, 282, 171, 300}, /*mode 4 */
+ /* calc, up, down, global_limit */
+ {5, 256, 256, 256}, /*mode 1 0*/
+ {5, 258, 253, 277}, /*mode 2 15%*/
+ {5, 259, 252, 330}, /*mode 3 40%*/
+ {5, 267, 244, 400}, /*mode 4 60%*/
};
static int rk3368_lcdc_set_dsp_cabc(struct rk_lcdc_driver *dev_drv, int mode)
struct rk_screen *screen = dev_drv->cur_screen;
u32 total_pixel, calc_pixel, stage_up, stage_down;
u32 pixel_num, global_su;
- u32 stage_up_rec, stage_down_rec, global_su_rec;
+ u32 stage_up_rec, stage_down_rec, global_su_rec, gamma_global_su_rec;
u32 mask = 0, val = 0, cabc_en = 0;
+ int *cabc_lut = NULL;
+
+ if (!screen->cabc_lut) {
+ pr_err("screen cabc lut not config, so not open cabc\n");
+ return 0;
+ } else {
+ cabc_lut = screen->cabc_lut;
+ }
dev_drv->cabc_mode = mode;
cabc_en = (mode > 0) ? 1 : 0;
stage_up_rec = 256 * 256 / stage_up;
stage_down_rec = 256 * 256 / stage_down;
- global_su_rec = 256 * 256 / global_su;
+ global_su_rec = (256 * 256 / global_su) - 1;
+ gamma_global_su_rec = cabc_lut[global_su_rec];
spin_lock(&lcdc_dev->reg_lock);
if (lcdc_dev->clk_on) {
lcdc_msk_reg(lcdc_dev, CABC_CTRL0, mask, val);
mask = m_CABC_TOTAL_PIXEL_NUM | m_CABC_LUT_EN;
- val = v_CABC_TOTAL_PIXEL_NUM(total_pixel) | v_CABC_LUT_EN(0);
+ val = v_CABC_TOTAL_PIXEL_NUM(total_pixel) | v_CABC_LUT_EN(1);
lcdc_msk_reg(lcdc_dev, CABC_CTRL1, mask, val);
mask = m_CABC_STAGE_UP | m_CABC_STAGE_UP_REC |
val = v_CABC_STAGE_UP(stage_up) |
v_CABC_STAGE_UP_REC(stage_up_rec) |
v_CABC_GLOBAL_SU_LIMIT_EN(1) |
- v_CABC_GLOBAL_SU_REC(global_su_rec);
+ v_CABC_GLOBAL_SU_REC(gamma_global_su_rec);
lcdc_msk_reg(lcdc_dev, CABC_CTRL2, mask, val);
mask = m_CABC_STAGE_DOWN | m_CABC_STAGE_DOWN_REC |
.fb_get_win_id = rk3368_lcdc_get_win_id,
.fb_win_remap = rk3368_fb_win_remap,
.set_dsp_lut = rk3368_lcdc_set_lut,
+ .set_cabc_lut = rk3368_set_cabc_lut,
.poll_vblank = rk3368_lcdc_poll_vblank,
.dpi_open = rk3368_lcdc_dpi_open,
.dpi_win_sel = rk3368_lcdc_dpi_win_sel,
if (IS_ERR(lcdc_dev->regsbak))
return PTR_ERR(lcdc_dev->regsbak);
lcdc_dev->dsp_lut_addr_base = (lcdc_dev->regs + GAMMA_LUT_ADDR);
+ lcdc_dev->cabc_lut_addr_base = (lcdc_dev->regs + CABC_GAMMA_LUT_ADDR);
lcdc_dev->grf_base =
syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
if (IS_ERR(lcdc_dev->grf_base)) {
return count;
}
+static ssize_t show_cabc_lut(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return 0;
+}
+
+static ssize_t set_cabc_lut(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int cabc_lut[256];
+ const char *start = buf;
+ int i = 256, temp;
+ int space_max = 10;
+
+ struct fb_info *fbi = dev_get_drvdata(dev);
+ struct rk_fb_par *fb_par = (struct rk_fb_par *)fbi->par;
+ struct rk_lcdc_driver *dev_drv = fb_par->lcdc_drv;
+
+ for (i = 0; i < 256; i++) {
+ temp = i;
+ /*init by default value*/
+ cabc_lut[i] = temp + (temp << 8) + (temp << 16);
+ }
+ for (i = 0; i < 256; i++) {
+ space_max = 10; /*max space number 10*/
+ temp = simple_strtoul(start, NULL, 10);
+ cabc_lut[i] = temp;
+ do {
+ start++;
+ space_max--;
+ } while ((*start != ' ') && space_max);
+
+ if (!space_max)
+ break;
+ else
+ start++;
+ }
+ if (dev_drv->ops->set_cabc_lut)
+ dev_drv->ops->set_cabc_lut(dev_drv, cabc_lut);
+
+ return count;
+}
+
+
static ssize_t show_dsp_lut(struct device *dev,
struct device_attribute *attr, char *buf)
{
__ATTR(fps, S_IRUGO | S_IWUSR, show_fps, set_fps),
__ATTR(map, S_IRUGO | S_IWUSR, show_fb_win_map, set_fb_win_map),
__ATTR(dsp_lut, S_IRUGO | S_IWUSR, show_dsp_lut, set_dsp_lut),
+ __ATTR(cabc_lut, S_IRUGO | S_IWUSR, show_cabc_lut, set_cabc_lut),
__ATTR(hwc_lut, S_IRUGO | S_IWUSR, show_hwc_lut, set_hwc_lut),
__ATTR(cabc, S_IRUGO | S_IWUSR, show_dsp_cabc, set_dsp_cabc),
__ATTR(bcsh, S_IRUGO | S_IWUSR, show_dsp_bcsh, set_dsp_bcsh),