#include <asm/div64.h>
#include <asm/uaccess.h>
#include "../../../arch/arm/mach-rockchip/cpu.h"
+#include "../../../arch/arm/mach-rockchip/iomap.h"
+#include "../../../arch/arm/mach-rockchip/grf.h"
+
#include "rk3188_lcdc.h"
#if defined(CONFIG_HAS_EARLYSUSPEND)
static int dbg_thresd;
module_param(dbg_thresd, int, S_IRUGO | S_IWUSR);
-#define DBG(level,x...) do { \
- if(unlikely(dbg_thresd >= level)) \
- printk(KERN_INFO x);} while (0)
+#define DBG(level, x...) do { \
+ if (unlikely(dbg_thresd >= level)) \
+ printk(KERN_INFO x); } while (0)
//#define WAIT_FOR_SYNC 1
static int rk3188_lcdc_get_id(u32 phy_base)
{
if (cpu_is_rk319x()) {
- if(phy_base == 0xffc40000)
+ if (phy_base == 0xffc40000)
return 0;
else if (phy_base == 0xffc50000)
return 1;
else
return -EINVAL;
- } else if (cpu_is_rk3188( )) {
+ } else if (cpu_is_rk3188()) {
if (phy_base == 0x1010c000)
return 0;
- else if(phy_base == 0x0101e000)
+ else if (phy_base == 0x1010e000)
return 1;
else
return -EINVAL;
} else if (cpu_is_rk3026()) {
if (phy_base == 0x1010e000)
return 0;
- else if(phy_base == 0x01110000)
+ else if (phy_base == 0x01110000)
return 1;
else
return -EINVAL;
pr_err("un supported platform \n");
return -EINVAL;
}
-
+
+}
+
+static int rk3188_lcdc_set_lut(struct rk_lcdc_driver *dev_drv)
+{
+ int i = 0;
+ int __iomem *c;
+ int v;
+ struct lcdc_device *lcdc_dev = container_of(dev_drv,
+ struct
+ lcdc_device,
+ driver);
+ lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN, v_DSP_LUT_EN(0));
+ lcdc_cfg_done(lcdc_dev);
+ mdelay(25);
+ for (i = 0; i < 256; i++) {
+ v = dev_drv->cur_screen->dsp_lut[i];
+ c = lcdc_dev->dsp_lut_addr_base + i;
+ writel_relaxed(v, c);
+
+ }
+ lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN, v_DSP_LUT_EN(1));
+
+ return 0;
+
}
-static int rk3188_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen);
-static int rk3188_lcdc_clk_enable(struct rk3188_lcdc_device *lcdc_dev)
+
+static int rk3188_lcdc_clk_enable(struct lcdc_device *lcdc_dev)
{
if (!lcdc_dev->clk_on) {
spin_unlock(&lcdc_dev->reg_lock);
}
-
return 0;
}
-static int rk3188_lcdc_clk_disable(struct rk3188_lcdc_device *lcdc_dev)
+static int rk3188_lcdc_clk_disable(struct lcdc_device *lcdc_dev)
{
if (lcdc_dev->clk_on) {
spin_lock(&lcdc_dev->reg_lock);
//clk_disable(lcdc_dev->pd);
}
-
return 0;
}
-static void rk3188_lcdc_reg_dump(struct rk3188_lcdc_device *lcdc_dev)
+static void rk3188_lcdc_reg_dump(struct lcdc_device *lcdc_dev)
{
int *cbase = (int *)lcdc_dev->regs;
int *regsbak = (int *)lcdc_dev->regsbak;
}
-static void rk3188_lcdc_read_reg_defalut_cfg(struct rk3188_lcdc_device
+static void rk3188_lcdc_read_reg_defalut_cfg(struct lcdc_device
*lcdc_dev)
{
int reg = 0;
u32 value = 0;
- struct layer_par *win0 = lcdc_dev->driver.layer_par[0];
- struct layer_par *win1 = lcdc_dev->driver.layer_par[1];
+ struct rk_lcdc_win *win0 = lcdc_dev->driver.win[0];
+ struct rk_lcdc_win *win1 = lcdc_dev->driver.win[1];
spin_lock(&lcdc_dev->reg_lock);
for (reg = 0; reg < REG_CFG_DONE; reg += 4) {
spin_unlock(&lcdc_dev->reg_lock);
}
-static int rk3188_lcdc_alpha_cfg(struct rk3188_lcdc_device *lcdc_dev)
+/********do basic init*********/
+static int rk3188_lcdc_pre_init(struct rk_lcdc_driver *dev_drv)
+{
+ int v;
+ struct lcdc_device *lcdc_dev = container_of(dev_drv,
+ struct
+ lcdc_device,
+ driver);
+
+ if (lcdc_dev->pre_init)
+ return 0;
+
+ if (lcdc_dev->id == 0) {
+ //lcdc_dev->pd = clk_get(NULL,"pd_lcdc0");
+ lcdc_dev->hclk = clk_get(NULL, "g_h_lcdc0");
+ lcdc_dev->aclk = clk_get(NULL, "aclk_lcdc0");
+ lcdc_dev->dclk = clk_get(NULL, "dclk_lcdc0");
+ } else if (lcdc_dev->id == 1) {
+ //lcdc_dev->pd = clk_get(NULL,"pd_lcdc1");
+ lcdc_dev->hclk = clk_get(NULL, "g_h_lcdc1");
+ lcdc_dev->aclk = clk_get(NULL, "aclk_lcdc1");
+ lcdc_dev->dclk = clk_get(NULL, "dclk_lcdc1");
+ } else {
+ dev_err(lcdc_dev->dev, "invalid lcdc device!\n");
+ return -EINVAL;
+ }
+ if (IS_ERR(lcdc_dev->pd) || (IS_ERR(lcdc_dev->aclk)) ||
+ (IS_ERR(lcdc_dev->dclk)) || (IS_ERR(lcdc_dev->hclk))) {
+ dev_err(lcdc_dev->dev, "failed to get lcdc%d clk source\n",
+ lcdc_dev->id);
+ }
+
+ /*uboot display has enabled lcdc in boot */
+ if (!support_uboot_display()) {
+ rk_disp_pwr_enable(dev_drv);
+ rk3188_lcdc_clk_enable(lcdc_dev);
+ } else {
+ lcdc_dev->clk_on = 1;
+ }
+
+ rk3188_lcdc_read_reg_defalut_cfg(lcdc_dev);
+
+ if (lcdc_dev->id == 0) {
+ if (lcdc_dev->pwr18 == true) {
+ v = 0x40004000; /*bit14: 1,1.8v;0,3.3v*/
+ writel_relaxed(v, RK_GRF_VIRT + RK3188_GRF_IO_CON4);
+ } else {
+ v = 0x40000000;
+ writel_relaxed(v, RK_GRF_VIRT + RK3188_GRF_IO_CON4);
+ }
+ }
+
+ if (lcdc_dev->id == 1) {
+ if (lcdc_dev->pwr18 == true) {
+ v = 0x80008000; /*bit14: 1,1.8v;0,3.3v*/
+ writel_relaxed(v, RK_GRF_VIRT + RK3188_GRF_IO_CON4);
+ } else {
+ v = 0x80000000;
+ writel_relaxed(v, RK_GRF_VIRT + RK3188_GRF_IO_CON4);
+ }
+ pinctrl_select_state(lcdc_dev->dev->pins->p,
+ lcdc_dev->dev->pins->default_state);
+ }
+
+ lcdc_set_bit(lcdc_dev, SYS_CTRL, m_AUTO_GATING_EN);
+ lcdc_cfg_done(lcdc_dev);
+ lcdc_dev->pre_init = true;
+
+ return 0;
+}
+
+static void rk3188_lcdc_deint(struct lcdc_device *lcdc_dev)
+{
+ u32 mask, val;
+ spin_lock(&lcdc_dev->reg_lock);
+ if (likely(lcdc_dev->clk_on)) {
+ lcdc_dev->clk_on = 0;
+ lcdc_msk_reg(lcdc_dev, INT_STATUS, m_FS_INT_CLEAR,
+ v_FS_INT_CLEAR(1));
+ mask = m_HS_INT_EN | m_FS_INT_EN | m_LF_INT_EN |
+ m_BUS_ERR_INT_EN;
+ val = v_HS_INT_EN(0) | v_FS_INT_EN(0) |
+ v_LF_INT_EN(0) | v_BUS_ERR_INT_EN(0);
+ lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
+ lcdc_set_bit(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY);
+ lcdc_cfg_done(lcdc_dev);
+ spin_unlock(&lcdc_dev->reg_lock);
+ } else {
+ spin_unlock(&lcdc_dev->reg_lock);
+ }
+ mdelay(1);
+
+}
+
+static int rk3188_lcdc_alpha_cfg(struct lcdc_device *lcdc_dev)
{
int win0_top = 0;
- enum data_format win0_format = lcdc_dev->driver.layer_par[0]->format;
- enum data_format win1_format = lcdc_dev->driver.layer_par[1]->format;
+ 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;
int win0_alpha_en = ((win0_format == ARGB888)
|| (win0_format == ABGR888)) ? 1 : 0;
win0_top = ((*_pv) & (m_WIN0_TOP)) >> 8;
if (win0_top && (lcdc_dev->atv_layer_cnt >= 2) && (win0_alpha_en)) {
- lcdc_msk_reg(lcdc_dev, ALPHA_CTRL,
- m_WIN0_ALPHA_EN | m_WIN1_ALPHA_EN,
- v_WIN0_ALPHA_EN(1) | v_WIN1_ALPHA_EN(0));
- lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_WIN0_ALPHA_MODE | m_ALPHA_MODE_SEL0 | m_ALPHA_MODE_SEL1, v_WIN0_ALPHA_MODE(1) | v_ALPHA_MODE_SEL0(1) | v_ALPHA_MODE_SEL1(0)); //default set to per-pixel alpha
+ lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, m_WIN0_ALPHA_EN |
+ m_WIN1_ALPHA_EN, v_WIN0_ALPHA_EN(1) |
+ v_WIN1_ALPHA_EN(0));
+ mask = m_WIN0_ALPHA_MODE | m_ALPHA_MODE_SEL0 | m_ALPHA_MODE_SEL1;
+ val = v_WIN0_ALPHA_MODE(1) | v_ALPHA_MODE_SEL0(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)
&& (win1_alpha_en)) {
- lcdc_msk_reg(lcdc_dev, ALPHA_CTRL,
- m_WIN0_ALPHA_EN | m_WIN1_ALPHA_EN,
- v_WIN0_ALPHA_EN(0) | v_WIN1_ALPHA_EN(1));
- lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_WIN1_ALPHA_MODE | m_ALPHA_MODE_SEL0 | m_ALPHA_MODE_SEL1, v_WIN1_ALPHA_MODE(1) | v_ALPHA_MODE_SEL0(1) | v_ALPHA_MODE_SEL1(0)); //default set to per-pixel alpha
+ mask = m_WIN0_ALPHA_EN | m_WIN1_ALPHA_EN;
+ val = v_WIN0_ALPHA_EN(0) | v_WIN1_ALPHA_EN(1);
+ lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, mask, val);
+
+ mask = m_WIN1_ALPHA_MODE | m_ALPHA_MODE_SEL0 | m_ALPHA_MODE_SEL1;
+ val = v_WIN1_ALPHA_MODE(1) | v_ALPHA_MODE_SEL0(1) | v_ALPHA_MODE_SEL1(0);
+ lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
} else {
- lcdc_msk_reg(lcdc_dev, ALPHA_CTRL,
- m_WIN0_ALPHA_EN | m_WIN1_ALPHA_EN,
- v_WIN0_ALPHA_EN(0) | v_WIN1_ALPHA_EN(0));
+ mask = m_WIN0_ALPHA_EN | m_WIN1_ALPHA_EN;
+ val = v_WIN0_ALPHA_EN(0) | v_WIN1_ALPHA_EN(0);
+ lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, mask, val);
}
return 0;
static int rk3188_lcdc_reg_update(struct rk_lcdc_driver *dev_drv)
{
- struct rk3188_lcdc_device *lcdc_dev =
- container_of(dev_drv, struct rk3188_lcdc_device, driver);
- struct layer_par *win0 = lcdc_dev->driver.layer_par[0];
- struct layer_par *win1 = lcdc_dev->driver.layer_par[1];
+ struct lcdc_device *lcdc_dev =
+ container_of(dev_drv, struct lcdc_device, driver);
+ struct rk_lcdc_win *win0 = lcdc_dev->driver.win[0];
+ struct rk_lcdc_win *win1 = lcdc_dev->driver.win[1];
int timeout;
unsigned long flags;
lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_CBR,
v_X_SCL_FACTOR(win0->scale_cbcr_x) |
v_Y_SCL_FACTOR(win0->scale_cbcr_y));
- lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN0_FORMAT, v_WIN0_FORMAT(win0->fmt_cfg)); //(inf->video_mode==0)
- lcdc_writel(lcdc_dev, WIN0_ACT_INFO,
- v_ACT_WIDTH(win0->xact) | v_ACT_HEIGHT(win0->yact));
- lcdc_writel(lcdc_dev, WIN0_DSP_ST,
- v_DSP_STX(win0->
- dsp_stx) | v_DSP_STY(win0->dsp_sty));
- lcdc_writel(lcdc_dev, WIN0_DSP_INFO,
- v_DSP_WIDTH(win0->
- xsize) | v_DSP_HEIGHT(win0->ysize));
+ lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN0_FORMAT, v_WIN0_FORMAT(win0->fmt_cfg));
+ lcdc_writel(lcdc_dev, WIN0_ACT_INFO, v_ACT_WIDTH(win0->xact) |
+ v_ACT_HEIGHT(win0->yact));
+ lcdc_writel(lcdc_dev, WIN0_DSP_ST, v_DSP_STX(win0->dsp_stx) |
+ v_DSP_STY(win0->dsp_sty));
+ lcdc_writel(lcdc_dev, WIN0_DSP_INFO, v_DSP_WIDTH(win0->xsize) |
+ v_DSP_HEIGHT(win0->ysize));
lcdc_msk_reg(lcdc_dev, WIN_VIR, m_WIN0_VIR,
v_WIN0_VIR_VAL(win0->vir_stride));
lcdc_writel(lcdc_dev, WIN0_YRGB_MST0, win0->y_addr);
lcdc_writel(lcdc_dev, WIN0_CBR_MST0, win0->uv_addr);
- lcdc_writel(lcdc_dev, WIN1_DSP_INFO,
- v_DSP_WIDTH(win1->
- xsize) | v_DSP_HEIGHT(win1->ysize));
- lcdc_writel(lcdc_dev, WIN1_DSP_ST,
- v_DSP_STX(win1->
- dsp_stx) | v_DSP_STY(win1->dsp_sty));
+ lcdc_writel(lcdc_dev, WIN1_DSP_INFO, v_DSP_WIDTH(win1->xsize) |
+ v_DSP_HEIGHT(win1->ysize));
+ lcdc_writel(lcdc_dev, WIN1_DSP_ST, v_DSP_STX(win1->dsp_stx) |
+ v_DSP_STY(win1->dsp_sty));
lcdc_msk_reg(lcdc_dev, WIN_VIR, m_WIN1_VIR, win1->vir_stride);
lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN1_FORMAT,
v_WIN1_FORMAT(win1->fmt_cfg));
spin_lock_irqsave(&dev_drv->cpl_lock, flags);
init_completion(&dev_drv->frame_done);
spin_unlock_irqrestore(&dev_drv->cpl_lock, flags);
- timeout =
- wait_for_completion_timeout(&dev_drv->frame_done,
- msecs_to_jiffies
- (dev_drv->cur_screen->ft + 5));
+ timeout = wait_for_completion_timeout(&dev_drv->frame_done,
+ msecs_to_jiffies
+ (dev_drv->cur_screen->ft +
+ 5));
if (!timeout && (!dev_drv->frame_done.done)) {
- printk(KERN_ERR "wait for new frame start time out!\n");
+ dev_warn(lcdc_dev->dev, "wait for new frame start time out!\n");
return -ETIMEDOUT;
}
}
}
-static int rk3188_lcdc_reg_resume(struct rk3188_lcdc_device *lcdc_dev)
+static int rk3188_lcdc_reg_restore(struct lcdc_device *lcdc_dev)
{
memcpy((u8 *) lcdc_dev->regs, (u8 *) lcdc_dev->regsbak, 0x84);
return 0;
}
-//enable layer,open:1,enable;0 disable
-static int win0_open(struct rk3188_lcdc_device *lcdc_dev, bool open)
+
+static int rk3188_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
+{
+ int ret = -EINVAL;
+ int fps;
+ u16 face = 0;
+ struct lcdc_device *lcdc_dev =
+ container_of(dev_drv, struct lcdc_device, driver);
+ struct rk_screen *screen = dev_drv->cur_screen;
+ u16 right_margin = screen->mode.right_margin;
+ u16 left_margin = screen->mode.left_margin;
+ u16 lower_margin = screen->mode.lower_margin;
+ u16 upper_margin = screen->mode.upper_margin;
+ u16 x_res = screen->mode.xres;
+ u16 y_res = screen->mode.yres;
+ u32 mask, val;
+
+ spin_lock(&lcdc_dev->reg_lock);
+ if (likely(lcdc_dev->clk_on)) {
+ switch (screen->face) {
+ case OUT_P565:
+ face = OUT_P565;
+ mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
+ m_DITHER_DOWN_SEL;
+ val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0) |
+ v_DITHER_DOWN_SEL(1);
+ lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
+ break;
+ case OUT_P666:
+ face = OUT_P666;
+ mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
+ m_DITHER_DOWN_SEL;
+ val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) |
+ v_DITHER_DOWN_SEL(1);
+ lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
+ break;
+ case OUT_D888_P565:
+ face = OUT_P888;
+ mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
+ m_DITHER_DOWN_SEL;
+ val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0) |
+ v_DITHER_DOWN_SEL(1);
+ lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
+ break;
+ case OUT_D888_P666:
+ face = OUT_P888;
+ mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
+ m_DITHER_DOWN_SEL;
+ val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) |
+ v_DITHER_DOWN_SEL(1);
+ lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
+ break;
+ case OUT_P888:
+ face = OUT_P888;
+ mask = m_DITHER_DOWN_EN | m_DITHER_UP_EN;
+ val = v_DITHER_DOWN_EN(0) | v_DITHER_UP_EN(0);
+ lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
+ break;
+ default:
+ dev_err(lcdc_dev->dev, "un supported interface!\n");
+ break;
+ }
+
+ mask = m_DSP_OUT_FORMAT | m_HSYNC_POL | m_VSYNC_POL |
+ m_DEN_POL | m_DCLK_POL;
+ val = v_DSP_OUT_FORMAT(face) | v_HSYNC_POL(screen->pin_hsync) |
+ v_VSYNC_POL(screen->pin_vsync) | v_DEN_POL(screen->pin_den) |
+ v_DCLK_POL(screen->pin_dclk);
+ lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
+
+ mask = m_BG_COLOR | m_DSP_BG_SWAP | m_DSP_RB_SWAP |
+ m_DSP_RG_SWAP | m_DSP_DELTA_SWAP |
+ m_DSP_DUMMY_SWAP | m_BLANK_EN;
+ val = v_BG_COLOR(0x000000) | v_DSP_BG_SWAP(screen->swap_gb) |
+ v_DSP_RB_SWAP(screen->swap_rb) | v_DSP_RG_SWAP(screen->
+ swap_rg) |
+ v_DSP_DELTA_SWAP(screen->
+ swap_delta) | v_DSP_DUMMY_SWAP(screen->
+ swap_dumy) |
+ v_BLANK_EN(0) | v_BLACK_EN(0);
+ lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
+ val =
+ v_HSYNC(screen->mode.hsync_len) | v_HORPRD(screen->mode.
+ hsync_len +
+ left_margin +
+ x_res +
+ right_margin);
+ lcdc_writel(lcdc_dev, DSP_HTOTAL_HS_END, val);
+ val = v_HAEP(screen->mode.hsync_len + left_margin + x_res) |
+ v_HASP(screen->mode.hsync_len + left_margin);
+ lcdc_writel(lcdc_dev, DSP_HACT_ST_END, val);
+
+ val =
+ v_VSYNC(screen->mode.vsync_len) | v_VERPRD(screen->mode.
+ vsync_len +
+ upper_margin +
+ y_res +
+ lower_margin);
+ lcdc_writel(lcdc_dev, DSP_VTOTAL_VS_END, val);
+
+ val = v_VAEP(screen->mode.vsync_len + upper_margin + y_res) |
+ v_VASP(screen->mode.vsync_len + screen->mode.upper_margin);
+ lcdc_writel(lcdc_dev, DSP_VACT_ST_END, val);
+ }
+ spin_unlock(&lcdc_dev->reg_lock);
+
+ ret = clk_set_rate(lcdc_dev->dclk, screen->mode.pixclock);
+ if (ret)
+ dev_err(dev_drv->dev, "set lcdc%d dclk failed\n", lcdc_dev->id);
+ lcdc_dev->pixclock =
+ div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
+ lcdc_dev->driver.pixclock = lcdc_dev->pixclock;
+
+ fps = rk_fb_calc_fps(screen, lcdc_dev->pixclock);
+ screen->ft = 1000 / fps;
+ dev_info(lcdc_dev->dev, "%s: dclk:%lu>>fps:%d ",
+ lcdc_dev->driver.name, clk_get_rate(lcdc_dev->dclk), fps);
+
+ if (screen->init)
+ screen->init();
+
+ return 0;
+}
+
+/*enable layer,open:1,enable;0 disable*/
+static int win0_open(struct lcdc_device *lcdc_dev, bool open)
{
spin_lock(&lcdc_dev->reg_lock);
if (likely(lcdc_dev->clk_on)) {
if (open) {
if (!lcdc_dev->atv_layer_cnt) {
- printk(KERN_INFO
- "lcdc%d wakeup from standby!\n",
- lcdc_dev->id);
+ dev_info(lcdc_dev->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->driver.layer_par[0]->state = open;
- if (!lcdc_dev->atv_layer_cnt) //if no layer used,disable lcdc
- {
- printk(KERN_INFO
- "no layer of lcdc%d is used,go to standby!\n",
- lcdc_dev->id);
+ lcdc_dev->driver.win[0]->state = open;
+ if (!lcdc_dev->atv_layer_cnt) {
+ dev_info(lcdc_dev->dev, "no layer is used,go to standby!\n");
lcdc_dev->standby = 1;
}
- //lcdc_cfg_done(lcdc_dev);
}
spin_unlock(&lcdc_dev->reg_lock);
return 0;
}
-static int win1_open(struct rk3188_lcdc_device *lcdc_dev, bool open)
+static int win1_open(struct lcdc_device *lcdc_dev, bool open)
{
spin_lock(&lcdc_dev->reg_lock);
if (likely(lcdc_dev->clk_on)) {
if (open) {
if (!lcdc_dev->atv_layer_cnt) {
- printk(KERN_INFO
- "lcdc%d wakeup from standby!\n",
- lcdc_dev->id);
+ dev_info(lcdc_dev->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->driver.layer_par[1]->state = open;
+ lcdc_dev->driver.win[1]->state = open;
- if (!lcdc_dev->atv_layer_cnt) //if no layer used,disable lcdc
- {
- printk(KERN_INFO
- "no layer of lcdc%d is used,go to standby!\n",
- lcdc_dev->id);
+ /*if no layer used,disable lcdc*/
+ if (!lcdc_dev->atv_layer_cnt) {
+ dev_info(lcdc_dev->dev, "no layer is used,go to standby!\n");
lcdc_dev->standby = 1;
}
- //lcdc_cfg_done(lcdc_dev);
}
spin_unlock(&lcdc_dev->reg_lock);
return 0;
}
-static int rk3188_lcdc_open(struct rk_lcdc_driver *dev_drv, int layer_id,
+static int rk3188_lcdc_open(struct rk_lcdc_driver *dev_drv, int win_id,
bool open)
{
- int i = 0;
- int __iomem *c;
- int v;
- struct rk3188_lcdc_device *lcdc_dev =
- container_of(dev_drv, struct rk3188_lcdc_device, driver);
+ struct lcdc_device *lcdc_dev = container_of(dev_drv,
+ struct lcdc_device, driver);
- if ((open) && (!lcdc_dev->atv_layer_cnt)) //enable clk,when first layer open
- {
+ /*enable clk,when first layer open */
+ if ((open) && (!lcdc_dev->atv_layer_cnt)) {
+ rk3188_lcdc_pre_init(dev_drv);
rk3188_lcdc_clk_enable(lcdc_dev);
- rk3188_lcdc_reg_resume(lcdc_dev); //resume reg
+ rk3188_lcdc_reg_restore(lcdc_dev);
rk3188_load_screen(dev_drv, 1);
spin_lock(&lcdc_dev->reg_lock);
- if (dev_drv->cur_screen->dsp_lut) //resume dsp lut
- {
- lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN,
- v_DSP_LUT_EN(0));
- lcdc_cfg_done(lcdc_dev);
- mdelay(25); //wait for dsp lut disabled
- for (i = 0; i < 256; i++) {
- v = dev_drv->cur_screen->dsp_lut[i];
- c = lcdc_dev->dsp_lut_addr_base + i;
- writel_relaxed(v, c);
-
- }
- lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN, v_DSP_LUT_EN(1)); //enable dsp lut
- }
+ if (dev_drv->cur_screen->dsp_lut)
+ rk3188_lcdc_set_lut(dev_drv);
spin_unlock(&lcdc_dev->reg_lock);
}
- if (layer_id == 0) {
+ if (win_id == 0)
win0_open(lcdc_dev, open);
- } else if (layer_id == 1) {
+ else if (win_id == 1)
win1_open(lcdc_dev, open);
- } else {
- printk("invalid win number:%d\n", layer_id);
- }
+ else
+ dev_err(lcdc_dev->dev, "invalid win id:%d\n", win_id);
- if ((!open) && (!lcdc_dev->atv_layer_cnt)) //when all layer closed,disable clk
- {
- lcdc_msk_reg(lcdc_dev, INT_STATUS, m_FS_INT_CLEAR,
- v_FS_INT_CLEAR(1));
+ /*when all layer closed,disable clk */
+ if ((!open) && (!lcdc_dev->atv_layer_cnt)) {
+ lcdc_msk_reg(lcdc_dev, INT_STATUS,
+ m_FS_INT_CLEAR, v_FS_INT_CLEAR(1));
rk3188_lcdc_reg_update(dev_drv);
rk3188_lcdc_clk_disable(lcdc_dev);
}
- printk(KERN_INFO "lcdc%d win%d %s,atv layer:%d\n",
- lcdc_dev->id, layer_id, open ? "open" : "closed",
- lcdc_dev->atv_layer_cnt);
return 0;
}
-static int rk3188_lcdc_init(struct rk_lcdc_driver *dev_drv)
-{
- int i = 0;
- int __iomem *c;
- int v;
- struct rk3188_lcdc_device *lcdc_dev =
- container_of(dev_drv, struct rk3188_lcdc_device, driver);
- if (lcdc_dev->id == 0) //lcdc0
- {
- //lcdc_dev->pd = clk_get(NULL,"pd_lcdc0");
- lcdc_dev->hclk = clk_get(NULL, "g_h_lcdc0");
- lcdc_dev->aclk = clk_get(NULL, "aclk_lcdc0");
- lcdc_dev->dclk = clk_get(NULL, "dclk_lcdc0");
- } else if (lcdc_dev->id == 1) {
- //lcdc_dev->pd = clk_get(NULL,"pd_lcdc1");
- lcdc_dev->hclk = clk_get(NULL, "g_h_lcdc1");
- lcdc_dev->aclk = clk_get(NULL, "aclk_lcdc1");
- lcdc_dev->dclk = clk_get(NULL, "dclk_lcdc1");
- } else {
- printk(KERN_ERR "invalid lcdc device!\n");
- return -EINVAL;
- }
- if (IS_ERR(lcdc_dev->pd) || (IS_ERR(lcdc_dev->aclk))
- || (IS_ERR(lcdc_dev->dclk)) || (IS_ERR(lcdc_dev->hclk))) {
- printk(KERN_ERR "failed to get lcdc%d clk source\n",
- lcdc_dev->id);
- }
- if (!support_uboot_display()) {
- rk3188_lcdc_clk_enable(lcdc_dev);
- } else {
- lcdc_dev->clk_on = 1;
- }
-
- rk3188_lcdc_read_reg_defalut_cfg(lcdc_dev);
-#if defined(CONFIG_ARCH_RK3188)
- if (lcdc_dev->id == 0) {
-#if defined(CONFIG_LCDC0_IO_18V)
- v = 0x40004000; //bit14: 1,1.8v;0,3.3v
- writel_relaxed(v, RK30_GRF_BASE + GRF_IO_CON4);
-#else
- v = 0x40000000;
- writel_relaxed(v, RK30_GRF_BASE + GRF_IO_CON4);
-#endif
- }
- if (lcdc_dev->id == 1) //iomux for lcdc1
- {
-#if defined(CONFIG_LCDC1_IO_18V)
- v = 0x80008000; //bit14: 1,1.8v;0,3.3v
- writel_relaxed(v, RK30_GRF_BASE + GRF_IO_CON4);
-#else
- v = 0x80000000;
- writel_relaxed(v, RK30_GRF_BASE + GRF_IO_CON4);
-#endif
- iomux_set(LCDC1_DCLK);
- iomux_set(LCDC1_DEN);
- iomux_set(LCDC1_HSYNC);
- iomux_set(LCDC1_VSYNC);
- iomux_set(LCDC1_D0);
- iomux_set(LCDC1_D1);
- iomux_set(LCDC1_D2);
- iomux_set(LCDC1_D3);
- iomux_set(LCDC1_D4);
- iomux_set(LCDC1_D5);
- iomux_set(LCDC1_D6);
- iomux_set(LCDC1_D7);
- iomux_set(LCDC1_D8);
- iomux_set(LCDC1_D9);
- iomux_set(LCDC1_D10);
- iomux_set(LCDC1_D11);
- iomux_set(LCDC1_D12);
- iomux_set(LCDC1_D13);
- iomux_set(LCDC1_D14);
- iomux_set(LCDC1_D15);
- iomux_set(LCDC1_D16);
- iomux_set(LCDC1_D17);
- iomux_set(LCDC1_D18);
- iomux_set(LCDC1_D19);
- iomux_set(LCDC1_D20);
- iomux_set(LCDC1_D21);
- iomux_set(LCDC1_D22);
- iomux_set(LCDC1_D23);
- }
-#endif
- lcdc_set_bit(lcdc_dev, SYS_CTRL, m_AUTO_GATING_EN); //eanble axi-clk auto gating for low power
- //lcdc_set_bit(lcdc_dev,DSP_CTRL0,m_WIN0_TOP);
- if (dev_drv->cur_screen->dsp_lut) {
- lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN, v_DSP_LUT_EN(0));
- lcdc_cfg_done(lcdc_dev);
- msleep(25);
- for (i = 0; i < 256; i++) {
- v = dev_drv->cur_screen->dsp_lut[i];
- c = lcdc_dev->dsp_lut_addr_base + i;
- writel_relaxed(v, c);
-
- }
- lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN, v_DSP_LUT_EN(1));
- }
-
- lcdc_cfg_done(lcdc_dev); // write any value to REG_CFG_DONE let config become effective
- /*if((!support_uboot_display())||(dev_drv->screen_ctr_info->prop == EXTEND))
- {
- rk3188_lcdc_clk_disable(lcdc_dev);
- } */
-
- return 0;
-}
-
-static void rk3188_lcdc_deint(struct rk3188_lcdc_device *lcdc_dev)
-{
- spin_lock(&lcdc_dev->reg_lock);
- if (likely(lcdc_dev->clk_on)) {
- lcdc_dev->clk_on = 0;
- lcdc_msk_reg(lcdc_dev, INT_STATUS, m_FS_INT_CLEAR,
- v_FS_INT_CLEAR(1));
- lcdc_msk_reg(lcdc_dev, INT_STATUS, m_HS_INT_EN | m_FS_INT_EN | m_LF_INT_EN | m_BUS_ERR_INT_EN, v_HS_INT_EN(0) | v_FS_INT_EN(0) | v_LF_INT_EN(0) | v_BUS_ERR_INT_EN(0)); //disable all lcdc interrupt
- lcdc_set_bit(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY);
- lcdc_cfg_done(lcdc_dev);
- spin_unlock(&lcdc_dev->reg_lock);
- } else //clk already disabled
- {
- spin_unlock(&lcdc_dev->reg_lock);
- }
- mdelay(1);
-
-}
-
-//set lcdc according the screen info
-static int rk3188_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
-{
- int ret = -EINVAL;
- int fps;
- u16 face = 0;
- struct rk3188_lcdc_device *lcdc_dev =
- container_of(dev_drv, struct rk3188_lcdc_device, driver);
- rk_screen *screen = dev_drv->cur_screen;
- u16 right_margin = screen->right_margin;
- u16 left_margin = screen->left_margin;
- u16 lower_margin = screen->lower_margin;
- u16 upper_margin = screen->upper_margin;
- u16 x_res = screen->x_res;
- u16 y_res = screen->y_res;
-
- spin_lock(&lcdc_dev->reg_lock);
- if (likely(lcdc_dev->clk_on)) {
- if (screen->type == SCREEN_MCU) {
- printk("MUC¡¡screen not supported now!\n");
- return -EINVAL;
- }
-
- switch (screen->face) {
- case OUT_P565:
- face = OUT_P565; //dither down to rgb565
- lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
- m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
- m_DITHER_DOWN_SEL,
- v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0)
- | v_DITHER_DOWN_SEL(1));
- break;
- case OUT_P666:
- face = OUT_P666; //dither down to rgb666
- lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
- m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
- m_DITHER_DOWN_SEL,
- v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1)
- | v_DITHER_DOWN_SEL(1));
- break;
- case OUT_D888_P565:
- face = OUT_P888;
- lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
- m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
- m_DITHER_DOWN_SEL,
- v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0)
- | v_DITHER_DOWN_SEL(1));
- break;
- case OUT_D888_P666:
- face = OUT_P888;
- lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
- m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
- m_DITHER_DOWN_SEL,
- v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1)
- | v_DITHER_DOWN_SEL(1));
- break;
- case OUT_P888:
- face = OUT_P888;
- lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
- m_DITHER_DOWN_EN | m_DITHER_UP_EN,
- v_DITHER_DOWN_EN(0) | v_DITHER_UP_EN(0));
- break;
- default:
- printk("unsupported display output interface!\n");
- break;
- }
-
- //use default overlay,set vsyn hsync den dclk polarity
- lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
- m_DSP_OUT_FORMAT | m_HSYNC_POL | m_VSYNC_POL |
- m_DEN_POL | m_DCLK_POL,
- v_DSP_OUT_FORMAT(face) |
- v_HSYNC_POL(screen->pin_hsync) |
- v_VSYNC_POL(screen->
- pin_vsync) | v_DEN_POL(screen->pin_den)
- | v_DCLK_POL(screen->pin_dclk));
-
- //set background color to black,set swap according to the screen panel,disable blank mode
- lcdc_msk_reg(lcdc_dev, DSP_CTRL1,
- m_BG_COLOR | m_DSP_BG_SWAP | m_DSP_RB_SWAP |
- m_DSP_RG_SWAP | m_DSP_DELTA_SWAP | m_DSP_DUMMY_SWAP
- | m_BLANK_EN,
- v_BG_COLOR(0x000000) |
- v_DSP_BG_SWAP(screen->swap_gb) |
- v_DSP_RB_SWAP(screen->swap_rb) |
- v_DSP_RG_SWAP(screen->swap_rg) |
- v_DSP_DELTA_SWAP(screen->swap_delta) |
- v_DSP_DUMMY_SWAP(screen->swap_dumy) | v_BLANK_EN(0)
- | v_BLACK_EN(0));
- lcdc_writel(lcdc_dev, DSP_HTOTAL_HS_END,
- v_HSYNC(screen->
- hsync_len) | v_HORPRD(screen->hsync_len +
- left_margin + x_res +
- right_margin));
- lcdc_writel(lcdc_dev, DSP_HACT_ST_END,
- v_HAEP(screen->hsync_len + left_margin +
- x_res) | v_HASP(screen->hsync_len +
- left_margin));
-
- lcdc_writel(lcdc_dev, DSP_VTOTAL_VS_END,
- v_VSYNC(screen->
- vsync_len) | v_VERPRD(screen->vsync_len +
- upper_margin + y_res +
- lower_margin));
- lcdc_writel(lcdc_dev, DSP_VACT_ST_END,
- v_VAEP(screen->vsync_len + upper_margin +
- y_res) | v_VASP(screen->vsync_len +
- screen->upper_margin));
- }
- spin_unlock(&lcdc_dev->reg_lock);
-#if defined(CONFIG_ARCH_RK3026)
- if (dev_drv->screen0->type == SCREEN_RGB) //iomux for RGB screen
- {
- iomux_set(LCDC0_DCLK);
- iomux_set(LCDC0_HSYNC);
- iomux_set(LCDC0_VSYNC);
- iomux_set(LCDC0_DEN);
- iomux_set(LCDC0_D10);
- iomux_set(LCDC0_D11);
- iomux_set(LCDC0_D12);
- iomux_set(LCDC0_D13);
- iomux_set(LCDC0_D14);
- iomux_set(LCDC0_D15);
- iomux_set(LCDC0_D16);
- iomux_set(LCDC0_D17);
- if (!((dev_drv->screen0->face == OUT_P666)
- || (dev_drv->screen0->face == OUT_P565))) {
- iomux_set(LCDC0_D18);
- iomux_set(LCDC0_D19);
- iomux_set(LCDC0_D20); //iomux uart2 in
- iomux_set(LCDC0_D21); //iomux uart2 out
- iomux_set(LCDC0_D22);
- iomux_set(LCDC0_D23);
- }
- }
-#endif
- ret = clk_set_rate(lcdc_dev->dclk, screen->pixclock);
- if (ret) {
- dev_err(dev_drv->dev, "set lcdc%d dclk failed\n", lcdc_dev->id);
- }
- lcdc_dev->driver.pixclock = lcdc_dev->pixclock =
- div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
-
- fps = rk_fb_calc_fps(screen, lcdc_dev->pixclock);
- screen->ft = 1000 / fps;
- printk("%s: dclk:%lu>>fps:%d ", lcdc_dev->driver.name,
- clk_get_rate(lcdc_dev->dclk), fps);
-
- if (screen->init) {
- screen->init();
- }
-
- dev_info(dev_drv->dev, "%s for lcdc%d ok!\n", __func__, lcdc_dev->id);
- return 0;
-}
-
-static int win0_set_par(struct rk3188_lcdc_device *lcdc_dev, rk_screen * screen,
- struct layer_par *par)
+static int win0_set_par(struct lcdc_device *lcdc_dev,
+ struct rk_screen *screen, struct rk_lcdc_win *win)
{
u32 xact, yact, xvir, yvir, xpos, ypos;
u32 ScaleYrgbX = 0x1000;
u32 ScaleYrgbY = 0x1000;
u32 ScaleCbrX = 0x1000;
u32 ScaleCbrY = 0x1000;
- u8 fmt_cfg = 0; //data format register config value
+ u8 fmt_cfg = 0;
char fmt[9] = "NULL";
- xact = par->xact; //active (origin) picture window width/height
- yact = par->yact;
- xvir = par->xvir; // virtual resolution
- yvir = par->yvir;
- xpos = par->xpos + screen->left_margin + screen->hsync_len;
- ypos = par->ypos + screen->upper_margin + screen->vsync_len;
-
- ScaleYrgbX = CalScale(xact, par->xsize); //both RGB and yuv need this two factor
- ScaleYrgbY = CalScale(yact, par->ysize);
- switch (par->format) {
+ xact = win->xact;
+ yact = win->yact;
+ xvir = win->xvir;
+ yvir = win->yvir;
+ xpos = win->xpos + screen->mode.left_margin + screen->mode.hsync_len;
+ ypos = win->ypos + screen->mode.upper_margin + screen->mode.vsync_len;
+
+ ScaleYrgbX = CalScale(xact, win->xsize);
+ ScaleYrgbY = CalScale(yact, win->ysize);
+ switch (win->format) {
case ARGB888:
case XBGR888:
case ABGR888:
case RGB565:
fmt_cfg = 2;
break;
- case YUV422: // yuv422
+ case YUV422:
fmt_cfg = 5;
- ScaleCbrX = CalScale((xact / 2), par->xsize);
- ScaleCbrY = CalScale(yact, par->ysize);
+ ScaleCbrX = CalScale((xact / 2), win->xsize);
+ ScaleCbrY = CalScale(yact, win->ysize);
break;
- case YUV420: // yuv420
+ case YUV420:
fmt_cfg = 4;
- ScaleCbrX = CalScale(xact / 2, par->xsize);
- ScaleCbrY = CalScale(yact / 2, par->ysize);
+ ScaleCbrX = CalScale(xact / 2, win->xsize);
+ ScaleCbrY = CalScale(yact / 2, win->ysize);
break;
- case YUV444: // yuv444
+ case YUV444:
fmt_cfg = 6;
- ScaleCbrX = CalScale(xact, par->xsize);
- ScaleCbrY = CalScale(yact, par->ysize);
+ ScaleCbrX = CalScale(xact, win->xsize);
+ ScaleCbrY = CalScale(yact, win->ysize);
break;
default:
dev_err(lcdc_dev->driver.dev, "%s:un supported format!\n",
break;
}
- DBG(1,
- "lcdc%d>>%s>>format:%s>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d>>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n",
- lcdc_dev->id, __func__, get_format_string(par->format, fmt), xact,
- yact, par->xsize, par->ysize, xvir, yvir, xpos, ypos);
+ DBG(1, "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), xact,
+ yact, win->xsize, win->ysize, xvir, yvir, xpos, ypos);
spin_lock(&lcdc_dev->reg_lock);
if (likely(lcdc_dev->clk_on)) {
- par->scale_yrgb_x = ScaleYrgbX;
- par->scale_yrgb_y = ScaleYrgbY;
- par->scale_cbcr_x = ScaleCbrX;
- par->scale_cbcr_y = ScaleCbrY;
- par->fmt_cfg = fmt_cfg;
- par->dsp_stx = xpos;
- par->dsp_sty = ypos;
- switch (par->format) {
+ win->scale_yrgb_x = ScaleYrgbX;
+ win->scale_yrgb_y = ScaleYrgbY;
+ win->scale_cbcr_x = ScaleCbrX;
+ win->scale_cbcr_y = ScaleCbrY;
+ win->fmt_cfg = fmt_cfg;
+ win->dsp_stx = xpos;
+ win->dsp_sty = ypos;
+ switch (win->format) {
case XBGR888:
case ABGR888:
- par->vir_stride = v_ARGB888_VIRWIDTH(xvir);
- par->swap_rb = 1;
+ win->vir_stride = v_ARGB888_VIRWIDTH(xvir);
+ win->swap_rb = 1;
break;
case ARGB888:
- par->vir_stride = v_ARGB888_VIRWIDTH(xvir);
- par->swap_rb = 0;
+ win->vir_stride = v_ARGB888_VIRWIDTH(xvir);
+ win->swap_rb = 0;
break;
- case RGB888: //rgb888
- par->vir_stride = v_RGB888_VIRWIDTH(xvir);
- par->swap_rb = 0;
+ case RGB888:
+ win->vir_stride = v_RGB888_VIRWIDTH(xvir);
+ win->swap_rb = 0;
break;
- case RGB565: //rgb565
- par->vir_stride = v_RGB565_VIRWIDTH(xvir);
- par->swap_rb = 0;
+ case RGB565:
+ win->vir_stride = v_RGB565_VIRWIDTH(xvir);
+ win->swap_rb = 0;
break;
case YUV422:
case YUV420:
case YUV444:
- par->vir_stride = v_YUV_VIRWIDTH(xvir);
- par->swap_rb = 0;
+ win->vir_stride = v_YUV_VIRWIDTH(xvir);
+ win->swap_rb = 0;
break;
default:
dev_err(lcdc_dev->driver.dev,
}
-static int win1_set_par(struct rk3188_lcdc_device *lcdc_dev, rk_screen * screen,
- struct layer_par *par)
+static int win1_set_par(struct lcdc_device *lcdc_dev,
+ struct rk_screen *screen, struct rk_lcdc_win *win)
{
u32 xact, yact, xvir, yvir, xpos, ypos;
u8 fmt_cfg;
char fmt[9] = "NULL";
- xact = par->xact;
- yact = par->yact;
- xvir = par->xvir;
- yvir = par->yvir;
- xpos = par->xpos + screen->left_margin + screen->hsync_len;
- ypos = par->ypos + screen->upper_margin + screen->vsync_len;
-
- DBG(1,
- "lcdc%d>>%s>>format:%s>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d>>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n",
- lcdc_dev->id, __func__, get_format_string(par->format, fmt), xact,
- yact, par->xsize, par->ysize, xvir, yvir, xpos, ypos);
+ xact = win->xact;
+ yact = win->yact;
+ xvir = win->xvir;
+ yvir = win->yvir;
+ xpos = win->xpos + screen->mode.left_margin + screen->mode.hsync_len;
+ ypos = win->ypos + screen->mode.upper_margin + screen->mode.vsync_len;
+
+ DBG(1, "lcdc%d>>%s>>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), xact, yact,
+ win->xsize, win->ysize, xvir, yvir, xpos, ypos);
spin_lock(&lcdc_dev->reg_lock);
if (likely(lcdc_dev->clk_on)) {
- par->dsp_stx = xpos;
- par->dsp_sty = ypos;
- switch (par->format) {
+ win->dsp_stx = xpos;
+ win->dsp_sty = ypos;
+ switch (win->format) {
case XBGR888:
case ABGR888:
fmt_cfg = 0;
- par->vir_stride = v_WIN1_ARGB888_VIRWIDTH(xvir);
- par->swap_rb = 1;
+ win->vir_stride = v_WIN1_ARGB888_VIRWIDTH(xvir);
+ win->swap_rb = 1;
break;
case ARGB888:
fmt_cfg = 0;
- par->vir_stride = v_WIN1_ARGB888_VIRWIDTH(xvir);
- par->swap_rb = 0;
+ win->vir_stride = v_WIN1_ARGB888_VIRWIDTH(xvir);
+ win->swap_rb = 0;
break;
- case RGB888: //rgb888
+ case RGB888:
fmt_cfg = 1;
- par->vir_stride = v_WIN1_RGB888_VIRWIDTH(xvir);
- par->swap_rb = 0;
+ win->vir_stride = v_WIN1_RGB888_VIRWIDTH(xvir);
+ win->swap_rb = 0;
break;
- case RGB565: //rgb565
+ case RGB565:
fmt_cfg = 2;
- par->vir_stride = v_WIN1_RGB565_VIRWIDTH(xvir);
- par->swap_rb = 0;
+ win->vir_stride = v_WIN1_RGB565_VIRWIDTH(xvir);
+ win->swap_rb = 0;
break;
default:
dev_err(lcdc_dev->driver.dev,
"%s:un supported format!\n", __func__);
break;
}
- par->fmt_cfg = fmt_cfg;
+ win->fmt_cfg = fmt_cfg;
}
spin_unlock(&lcdc_dev->reg_lock);
return 0;
}
-static int rk3188_lcdc_set_par(struct rk_lcdc_driver *dev_drv, int layer_id)
+static int rk3188_lcdc_set_par(struct rk_lcdc_driver *dev_drv, int win_id)
{
- struct rk3188_lcdc_device *lcdc_dev =
- container_of(dev_drv, struct rk3188_lcdc_device, driver);
- struct layer_par *par = NULL;
- rk_screen *screen = dev_drv->cur_screen;
+ struct lcdc_device *lcdc_dev =
+ container_of(dev_drv, struct lcdc_device, driver);
+ struct rk_lcdc_win *win = NULL;
+ struct rk_screen *screen = dev_drv->cur_screen;
if (!screen) {
dev_err(dev_drv->dev, "screen is null!\n");
return -ENOENT;
}
- if (layer_id == 0) {
- par = dev_drv->layer_par[0];
- win0_set_par(lcdc_dev, screen, par);
- } else if (layer_id == 1) {
- par = dev_drv->layer_par[1];
- win1_set_par(lcdc_dev, screen, par);
+ if (win_id == 0) {
+ win = dev_drv->win[0];
+ win0_set_par(lcdc_dev, screen, win);
+ } else if (win_id == 1) {
+ win = dev_drv->win[1];
+ win1_set_par(lcdc_dev, screen, win);
} else {
- dev_err(dev_drv->dev, "unsupported win number:%d\n", layer_id);
+ dev_err(dev_drv->dev, "unsupported win number:%d\n", win_id);
return -EINVAL;
}
return 0;
}
-static int win0_display(struct rk3188_lcdc_device *lcdc_dev,
- struct layer_par *par)
+static int win0_display(struct lcdc_device *lcdc_dev,
+ struct rk_lcdc_win *win)
{
u32 y_addr;
u32 uv_addr;
- y_addr = par->smem_start + par->y_offset;
- uv_addr = par->cbr_start + par->c_offset;
- DBG(2, "lcdc%d>>%s:y_addr:0x%x>>uv_addr:0x%x\n", lcdc_dev->id, __func__,
- y_addr, uv_addr);
+ y_addr = win->smem_start + win->y_offset;
+ uv_addr = win->cbr_start + win->c_offset;
+ DBG(2, "lcdc%d>>%s:y_addr:0x%x>>uv_addr:0x%x\n",
+ lcdc_dev->id, __func__, y_addr, uv_addr);
spin_lock(&lcdc_dev->reg_lock);
if (likely(lcdc_dev->clk_on)) {
- par->y_addr = y_addr;
- par->uv_addr = uv_addr;
+ win->y_addr = y_addr;
+ win->uv_addr = uv_addr;
}
spin_unlock(&lcdc_dev->reg_lock);
}
-static int win1_display(struct rk3188_lcdc_device *lcdc_dev,
- struct layer_par *par)
+static int win1_display(struct lcdc_device *lcdc_dev,
+ struct rk_lcdc_win *win)
{
u32 y_addr;
u32 uv_addr;
- y_addr = par->smem_start + par->y_offset;
- uv_addr = par->cbr_start + par->c_offset;
- DBG(2, "lcdc%d>>%s>>y_addr:0x%x>>uv_addr:0x%x\n", lcdc_dev->id,
- __func__, y_addr, uv_addr);
+ y_addr = win->smem_start + win->y_offset;
+ uv_addr = win->cbr_start + win->c_offset;
+ DBG(2, "lcdc%d>>%s>>y_addr:0x%x>>uv_addr:0x%x\n",
+ lcdc_dev->id, __func__, y_addr, uv_addr);
spin_lock(&lcdc_dev->reg_lock);
- if (likely(lcdc_dev->clk_on)) {
- par->y_addr = y_addr;
- }
+ if (likely(lcdc_dev->clk_on))
+ win->y_addr = y_addr;
spin_unlock(&lcdc_dev->reg_lock);
return 0;
}
-static int rk3188_lcdc_pan_display(struct rk_lcdc_driver *dev_drv, int layer_id)
+static int rk3188_lcdc_pan_display(struct rk_lcdc_driver *dev_drv, int win_id)
{
- struct rk3188_lcdc_device *lcdc_dev =
- container_of(dev_drv, struct rk3188_lcdc_device, driver);
- struct layer_par *par = NULL;
- rk_screen *screen = dev_drv->cur_screen;
+ struct lcdc_device *lcdc_dev = container_of(dev_drv,
+ struct lcdc_device, driver);
+ struct rk_lcdc_win *win = NULL;
+ struct rk_screen *screen = dev_drv->cur_screen;
+ u32 mask, val;
#if defined(WAIT_FOR_SYNC)
int timeout;
unsigned long flags;
dev_err(dev_drv->dev, "screen is null!\n");
return -ENOENT;
}
- if (layer_id == 0) {
- par = dev_drv->layer_par[0];
- win0_display(lcdc_dev, par);
- } else if (layer_id == 1) {
- par = dev_drv->layer_par[1];
- win1_display(lcdc_dev, par);
+ if (win_id == 0) {
+ win = dev_drv->win[0];
+ win0_display(lcdc_dev, win);
+ } else if (win_id == 1) {
+ win = dev_drv->win[1];
+ win1_display(lcdc_dev, win);
} else {
- dev_err(dev_drv->dev, "invalid win number:%d!\n", layer_id);
+ dev_err(dev_drv->dev, "invalid win number:%d!\n", win_id);
return -EINVAL;
}
- /*this is the first frame of the system ,enable frame start interrupt*/
+ /*this is the first frame of the system ,enable frame start interrupt */
if ((dev_drv->first_frame)) {
dev_drv->first_frame = 0;
- lcdc_msk_reg(lcdc_dev, INT_STATUS,
- m_HS_INT_CLEAR | m_HS_INT_EN | m_FS_INT_CLEAR |
- m_FS_INT_EN | m_LF_INT_EN | m_LF_INT_CLEAR |
- m_LF_INT_NUM | m_BUS_ERR_INT_CLEAR |
- m_BUS_ERR_INT_EN,
- v_FS_INT_CLEAR(1) | v_FS_INT_EN(1) |
- v_HS_INT_CLEAR(1) | v_HS_INT_EN(0) |
- v_LF_INT_CLEAR(1) | v_LF_INT_EN(1) |
- v_LF_INT_NUM(screen->vsync_len +
- screen->upper_margin + screen->y_res -
- 1));
+ mask = m_HS_INT_CLEAR | m_HS_INT_EN | m_FS_INT_CLEAR |
+ m_FS_INT_EN | m_LF_INT_EN | m_LF_INT_CLEAR |
+ m_LF_INT_NUM | m_BUS_ERR_INT_CLEAR | m_BUS_ERR_INT_EN;
+ val = v_FS_INT_CLEAR(1) | v_FS_INT_EN(1) | v_HS_INT_CLEAR(1) |
+ v_HS_INT_EN(0) | v_LF_INT_CLEAR(1) | v_LF_INT_EN(1) |
+ v_LF_INT_NUM(screen->mode.vsync_len + screen->mode.upper_margin +
+ screen->mode.yres -1);
+ lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
lcdc_cfg_done(lcdc_dev);
}
#if defined(WAIT_FOR_SYNC)
spin_lock_irqsave(&dev_drv->cpl_lock, flags);
init_completion(&dev_drv->frame_done);
spin_unlock_irqrestore(&dev_drv->cpl_lock, flags);
- timeout =
- wait_for_completion_timeout(&dev_drv->frame_done,
- msecs_to_jiffies(dev_drv->
- cur_screen->ft + 5));
+ timeout = wait_for_completion_timeout(&dev_drv->frame_done,
+ msecs_to_jiffies(dev_drv->
+ cur_screen->ft +
+ 5));
if (!timeout && (!dev_drv->frame_done.done)) {
dev_info(dev_drv->dev, "wait for new frame start time out!\n");
return -ETIMEDOUT;
}
static int rk3188_lcdc_blank(struct rk_lcdc_driver *dev_drv,
- int layer_id, int blank_mode)
+ int win_id, int blank_mode)
{
- struct rk3188_lcdc_device *lcdc_dev =
- container_of(dev_drv, struct rk3188_lcdc_device, driver);
+ struct lcdc_device *lcdc_dev =
+ container_of(dev_drv, struct lcdc_device, driver);
spin_lock(&lcdc_dev->reg_lock);
if (likely(lcdc_dev->clk_on)) {
}
static int rk3188_lcdc_ioctl(struct rk_lcdc_driver *dev_drv, unsigned int cmd,
- unsigned long arg, int layer_id)
+ unsigned long arg, int win_id)
{
- struct rk3188_lcdc_device *lcdc_dev =
- container_of(dev_drv, struct rk3188_lcdc_device, driver);
+ struct lcdc_device *lcdc_dev = container_of(dev_drv,
+ struct
+ lcdc_device,
+ driver);
u32 panel_size[2];
void __user *argp = (void __user *)arg;
struct color_key_cfg clr_key_cfg;
switch (cmd) {
case RK_FBIOGET_PANEL_SIZE:
- panel_size[0] = lcdc_dev->screen->x_res;
- panel_size[1] = lcdc_dev->screen->y_res;
+ panel_size[0] = lcdc_dev->screen->mode.xres;
+ panel_size[1] = lcdc_dev->screen->mode.yres;
if (copy_to_user(argp, panel_size, 8))
return -EFAULT;
break;
case RK_FBIOPUT_COLOR_KEY_CFG:
- if (copy_from_user
- (&clr_key_cfg, argp, sizeof(struct color_key_cfg)))
+ if (copy_from_user(&clr_key_cfg, argp,
+ sizeof(struct color_key_cfg)))
return -EFAULT;
lcdc_writel(lcdc_dev, WIN0_COLOR_KEY,
clr_key_cfg.win0_color_key_cfg);
static int rk3188_lcdc_early_suspend(struct rk_lcdc_driver *dev_drv)
{
- struct rk3188_lcdc_device *lcdc_dev =
- container_of(dev_drv, struct rk3188_lcdc_device, driver);
+ struct lcdc_device *lcdc_dev =
+ container_of(dev_drv, struct lcdc_device, driver);
if (dev_drv->screen0->standby)
dev_drv->screen0->standby(1);
static int rk3188_lcdc_early_resume(struct rk_lcdc_driver *dev_drv)
{
- struct rk3188_lcdc_device *lcdc_dev =
- container_of(dev_drv, struct rk3188_lcdc_device, driver);
+ struct lcdc_device *lcdc_dev =
+ container_of(dev_drv, struct lcdc_device, driver);
int i = 0;
int __iomem *c;
int v;
if (lcdc_dev->atv_layer_cnt) {
rk3188_lcdc_clk_enable(lcdc_dev);
- rk3188_lcdc_reg_resume(lcdc_dev);
+ rk3188_lcdc_reg_restore(lcdc_dev);
spin_lock(&lcdc_dev->reg_lock);
if (dev_drv->cur_screen->dsp_lut) {
return 0;
}
-static int rk3188_lcdc_get_layer_state(struct rk_lcdc_driver *dev_drv,
- int layer_id)
+static int rk3188_lcdc_get_win_state(struct rk_lcdc_driver *dev_drv, int win_id)
{
return 0;
}
static int rk3188_lcdc_ovl_mgr(struct rk_lcdc_driver *dev_drv, int swap,
bool set)
{
- struct rk3188_lcdc_device *lcdc_dev =
- container_of(dev_drv, struct rk3188_lcdc_device, driver);
+ struct lcdc_device *lcdc_dev =
+ container_of(dev_drv, struct lcdc_device, driver);
int ovl;
spin_lock(&lcdc_dev->reg_lock);
if (lcdc_dev->clk_on) {
}
static ssize_t rk3188_lcdc_get_disp_info(struct rk_lcdc_driver *dev_drv,
- char *buf, int layer_id)
+ char *buf, int win_id)
{
-
- struct rk3188_lcdc_device *lcdc_dev =
- container_of(dev_drv, struct rk3188_lcdc_device, driver);
+ struct lcdc_device *lcdc_dev = container_of(dev_drv,
+ struct
+ lcdc_device,
+ driver);
char format_w0[9] = "NULL";
char format_w1[9] = "NULL";
char status_w0[9] = "NULL";
char status_w1[9] = "NULL";
- u32 fmt_id = lcdc_readl(lcdc_dev, SYS_CTRL);
- u32 act_info, dsp_info, dsp_st, factor;
- u16 xvir_w0, x_act_w0, y_act_w0, x_dsp_w0, y_dsp_w0, x_st_w0, y_st_w0,
- x_factor, y_factor;
+ u32 fmt_id, act_info, dsp_info, dsp_st, factor;
+ u16 xvir_w0, x_act_w0, y_act_w0, x_dsp_w0, y_dsp_w0;
+ u16 x_st_w0, y_st_w0, x_factor, y_factor;
u16 xvir_w1, x_dsp_w1, y_dsp_w1, x_st_w1, y_st_w1;
- u16 x_scale, y_scale;
- int ovl = lcdc_read_bit(lcdc_dev, DSP_CTRL0, m_WIN0_TOP);
-
- switch ((fmt_id & m_WIN0_FORMAT) >> 3) {
- case 0:
- strcpy(format_w0, "ARGB888");
- break;
- case 1:
- strcpy(format_w0, "RGB888");
- break;
- case 2:
- strcpy(format_w0, "RGB565");
- break;
- case 4:
- strcpy(format_w0, "YCbCr420");
- break;
- case 5:
- strcpy(format_w0, "YCbCr422");
- break;
- case 6:
- strcpy(format_w0, "YCbCr444");
- break;
- default:
- strcpy(format_w0, "invalid\n");
- break;
- }
+ u16 x_scale, y_scale, ovl;
+ spin_lock(&lcdc_dev->reg_lock);
+ if (lcdc_dev->clk_on) {
+ fmt_id = lcdc_readl(lcdc_dev, SYS_CTRL);
+ ovl = lcdc_read_bit(lcdc_dev, DSP_CTRL0, m_WIN0_TOP);
+ switch ((fmt_id & m_WIN0_FORMAT) >> 3) {
+ case 0:
+ strcpy(format_w0, "ARGB888");
+ break;
+ case 1:
+ strcpy(format_w0, "RGB888");
+ break;
+ case 2:
+ strcpy(format_w0, "RGB565");
+ break;
+ case 4:
+ strcpy(format_w0, "YCbCr420");
+ break;
+ case 5:
+ strcpy(format_w0, "YCbCr422");
+ break;
+ case 6:
+ strcpy(format_w0, "YCbCr444");
+ break;
+ default:
+ strcpy(format_w0, "invalid\n");
+ break;
+ }
- switch ((fmt_id & m_WIN1_FORMAT) >> 6) {
- case 0:
- strcpy(format_w1, "ARGB888");
- break;
- case 1:
- strcpy(format_w1, "RGB888");
- break;
- case 2:
- strcpy(format_w1, "RGB565");
- break;
- case 4:
- strcpy(format_w1, "8bpp");
- break;
- case 5:
- strcpy(format_w1, "4bpp");
- break;
- case 6:
- strcpy(format_w1, "2bpp");
- break;
- case 7:
- strcpy(format_w1, "1bpp");
- break;
- default:
- strcpy(format_w1, "invalid\n");
- break;
- }
+ switch ((fmt_id & m_WIN1_FORMAT) >> 6) {
+ case 0:
+ strcpy(format_w1, "ARGB888");
+ break;
+ case 1:
+ strcpy(format_w1, "RGB888");
+ break;
+ case 2:
+ strcpy(format_w1, "RGB565");
+ break;
+ case 4:
+ strcpy(format_w1, "8bpp");
+ break;
+ case 5:
+ strcpy(format_w1, "4bpp");
+ break;
+ case 6:
+ strcpy(format_w1, "2bpp");
+ break;
+ case 7:
+ strcpy(format_w1, "1bpp");
+ break;
+ default:
+ strcpy(format_w1, "invalid\n");
+ break;
+ }
- if (fmt_id & m_WIN0_EN)
- strcpy(status_w0, "enabled");
- else
- strcpy(status_w0, "disabled");
+ if (fmt_id & m_WIN0_EN)
+ strcpy(status_w0, "enabled");
+ else
+ strcpy(status_w0, "disabled");
- if ((fmt_id & m_WIN1_EN) >> 1)
- strcpy(status_w1, "enabled");
- else
- strcpy(status_w1, "disabled");
-
- xvir_w0 = lcdc_readl(lcdc_dev, WIN_VIR) & 0x1fff;
- act_info = lcdc_readl(lcdc_dev, WIN0_ACT_INFO);
- dsp_info = lcdc_readl(lcdc_dev, WIN0_DSP_INFO);
- dsp_st = lcdc_readl(lcdc_dev, WIN0_DSP_ST);
- factor = lcdc_readl(lcdc_dev, WIN0_SCL_FACTOR_YRGB);
- x_act_w0 = (act_info & 0x1fff) + 1;
- y_act_w0 = ((act_info >> 16) & 0x1fff) + 1;
- x_dsp_w0 = (dsp_info & 0x7ff) + 1;
- y_dsp_w0 = ((dsp_info >> 16) & 0x7ff) + 1;
- x_st_w0 = dsp_st & 0xffff;
- y_st_w0 = dsp_st >> 16;
- x_factor = factor & 0xffff;
- y_factor = factor >> 16;
- x_scale = 4096 * 100 / x_factor;
- y_scale = 4096 * 100 / y_factor;
-
- xvir_w1 = (lcdc_readl(lcdc_dev, WIN_VIR) >> 16) & 0x1fff;
- dsp_info = lcdc_readl(lcdc_dev, WIN1_DSP_INFO);
- dsp_st = lcdc_readl(lcdc_dev, WIN1_DSP_ST);
- x_dsp_w1 = (dsp_info & 0x7ff) + 1;
- y_dsp_w1 = ((dsp_info >> 16) & 0x7ff) + 1;
- x_st_w1 = dsp_st & 0xffff;
- y_st_w1 = dsp_st >> 16;
+ if ((fmt_id & m_WIN1_EN) >> 1)
+ strcpy(status_w1, "enabled");
+ else
+ strcpy(status_w1, "disabled");
+
+ xvir_w0 = lcdc_readl(lcdc_dev, WIN_VIR) & 0x1fff;
+ act_info = lcdc_readl(lcdc_dev, WIN0_ACT_INFO);
+ dsp_info = lcdc_readl(lcdc_dev, WIN0_DSP_INFO);
+ dsp_st = lcdc_readl(lcdc_dev, WIN0_DSP_ST);
+ factor = lcdc_readl(lcdc_dev, WIN0_SCL_FACTOR_YRGB);
+ x_act_w0 = (act_info & 0x1fff) + 1;
+ y_act_w0 = ((act_info >> 16) & 0x1fff) + 1;
+ x_dsp_w0 = (dsp_info & 0x7ff) + 1;
+ y_dsp_w0 = ((dsp_info >> 16) & 0x7ff) + 1;
+ x_st_w0 = dsp_st & 0xffff;
+ y_st_w0 = dsp_st >> 16;
+ x_factor = factor & 0xffff;
+ y_factor = factor >> 16;
+ x_scale = 4096 * 100 / x_factor;
+ y_scale = 4096 * 100 / y_factor;
+ xvir_w1 = (lcdc_readl(lcdc_dev, WIN_VIR) >> 16) & 0x1fff;
+ dsp_info = lcdc_readl(lcdc_dev, WIN1_DSP_INFO);
+ dsp_st = lcdc_readl(lcdc_dev, WIN1_DSP_ST);
+ x_dsp_w1 = (dsp_info & 0x7ff) + 1;
+ y_dsp_w1 = ((dsp_info >> 16) & 0x7ff) + 1;
+ x_st_w1 = dsp_st & 0xffff;
+ y_st_w1 = dsp_st >> 16;
+ } else {
+ spin_unlock(&lcdc_dev->reg_lock);
+ return -EPERM;
+ }
+ spin_unlock(&lcdc_dev->reg_lock);
return snprintf(buf, PAGE_SIZE,
"win0:%s\n"
"xvir:%d\n"
lcdc_readl(lcdc_dev, WIN1_MST),
ovl ? "win0 on the top of win1\n" :
"win1 on the top of win0\n");
-
}
static int rk3188_lcdc_fps_mgr(struct rk_lcdc_driver *dev_drv, int fps,
bool set)
{
- struct rk3188_lcdc_device *lcdc_dev =
- container_of(dev_drv, struct rk3188_lcdc_device, driver);
- rk_screen *screen = dev_drv->cur_screen;
+ struct lcdc_device *lcdc_dev =
+ container_of(dev_drv, struct lcdc_device, driver);
+ struct rk_screen *screen = dev_drv->cur_screen;
u64 ft = 0;
u32 dotclk;
int ret;
u32 x_total, y_total;
if (set) {
ft = div_u64(1000000000000llu, fps);
- x_total = screen->upper_margin + screen->lower_margin +
- screen->y_res + screen->vsync_len;
- y_total = screen->left_margin + screen->right_margin +
- screen->x_res + screen->hsync_len;
+ x_total =
+ screen->mode.upper_margin + screen->mode.lower_margin +
+ screen->mode.yres + screen->mode.vsync_len;
+ y_total =
+ screen->mode.left_margin + screen->mode.right_margin +
+ screen->mode.xres + screen->mode.hsync_len;
dev_drv->pixclock = div_u64(ft, x_total * y_total);
dotclk = div_u64(1000000000000llu, dev_drv->pixclock);
ret = clk_set_rate(lcdc_dev->dclk, dotclk);
pixclock = div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
dev_drv->pixclock = lcdc_dev->pixclock = pixclock;
fps = rk_fb_calc_fps(lcdc_dev->screen, pixclock);
- screen->ft = 1000 / fps; /*one frame time in ms*/
+ screen->ft = 1000 / fps; /*one frame time in ms */
if (set)
dev_info(dev_drv->dev, "%s:dclk:%lu,fps:%d\n", __func__,
return fps;
}
-static int rk3188_fb_layer_remap(struct rk_lcdc_driver *dev_drv,
- enum fb_win_map_order order)
+static int rk3188_fb_win_remap(struct rk_lcdc_driver *dev_drv,
+ enum fb_win_map_order order)
{
mutex_lock(&dev_drv->fb_win_id_mutex);
if (order == FB_DEFAULT_ORDER)
dev_drv->fb0_win_id = order % 10;
mutex_unlock(&dev_drv->fb_win_id_mutex);
- dev_info(dev_drv->dev, "fb0:win%d\n"
- "fb1:win%d\n"
- "fb2:win%d\n",
- dev_drv->fb0_win_id,
- dev_drv->fb1_win_id,
- dev_drv->fb2_win_id);
return 0;
}
-static int rk3188_fb_get_layer(struct rk_lcdc_driver *dev_drv, const char *id)
+static int rk3188_lcdc_get_win_id(struct rk_lcdc_driver *dev_drv,
+ const char *id)
{
- int layer_id = 0;
+ int win_id = 0;
mutex_lock(&dev_drv->fb_win_id_mutex);
if (!strcmp(id, "fb0") || !strcmp(id, "fb2"))
- layer_id = dev_drv->fb0_win_id;
+ win_id = dev_drv->fb0_win_id;
else if (!strcmp(id, "fb1") || !strcmp(id, "fb3"))
- layer_id = dev_drv->fb1_win_id;
+ win_id = dev_drv->fb1_win_id;
mutex_unlock(&dev_drv->fb_win_id_mutex);
- return layer_id;
+ return win_id;
}
static int rk3188_set_dsp_lut(struct rk_lcdc_driver *dev_drv, int *lut)
int v;
int ret = 0;
- struct rk3188_lcdc_device *lcdc_dev =
- container_of(dev_drv, struct rk3188_lcdc_device, driver);
+ struct lcdc_device *lcdc_dev =
+ container_of(dev_drv, struct lcdc_device, driver);
lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN, v_DSP_LUT_EN(0));
lcdc_cfg_done(lcdc_dev);
msleep(25);
static int rk3188_lcdc_dpi_open(struct rk_lcdc_driver *dev_drv, bool open)
{
- struct rk3188_lcdc_device *lcdc_dev =
- container_of(dev_drv, struct rk3188_lcdc_device, driver);
+ struct lcdc_device *lcdc_dev =
+ container_of(dev_drv, struct lcdc_device, driver);
lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATCH_EN,
v_DIRECT_PATCH_EN(open));
lcdc_cfg_done(lcdc_dev);
return 0;
}
-static int rk3188_lcdc_dpi_layer_sel(struct rk_lcdc_driver *dev_drv,
- int layer_id)
+static int rk3188_lcdc_dpi_win_sel(struct rk_lcdc_driver *dev_drv, int win_id)
{
- struct rk3188_lcdc_device *lcdc_dev =
- container_of(dev_drv, struct rk3188_lcdc_device, driver);
+ struct lcdc_device *lcdc_dev = container_of(dev_drv,
+ struct lcdc_device, driver);
lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_LAY_SEL,
- v_DIRECT_PATH_LAY_SEL(layer_id));
+ v_DIRECT_PATH_LAY_SEL(win_id));
lcdc_cfg_done(lcdc_dev);
return 0;
static int rk3188_lcdc_dpi_status(struct rk_lcdc_driver *dev_drv)
{
- struct rk3188_lcdc_device *lcdc_dev =
- container_of(dev_drv, struct rk3188_lcdc_device, driver);
+ struct lcdc_device *lcdc_dev =
+ container_of(dev_drv, struct lcdc_device, driver);
int ovl = lcdc_read_bit(lcdc_dev, SYS_CTRL, m_DIRECT_PATCH_EN);
return ovl;
}
int rk3188_lcdc_poll_vblank(struct rk_lcdc_driver *dev_drv)
{
- struct rk3188_lcdc_device *lcdc_dev =
- container_of(dev_drv, struct rk3188_lcdc_device, driver);
+ struct lcdc_device *lcdc_dev =
+ container_of(dev_drv, struct lcdc_device, driver);
u32 int_reg;
int ret;
return ret;
}
-static struct layer_par lcdc_layer[] = {
+static struct rk_lcdc_win lcdc_win[] = {
[0] = {
.name = "win0",
.id = 0,
static struct rk_lcdc_drv_ops lcdc_drv_ops = {
.open = rk3188_lcdc_open,
- .init_lcdc = rk3188_lcdc_init,
.load_screen = rk3188_load_screen,
.set_par = rk3188_lcdc_set_par,
.pan_display = rk3188_lcdc_pan_display,
.ioctl = rk3188_lcdc_ioctl,
.suspend = rk3188_lcdc_early_suspend,
.resume = rk3188_lcdc_early_resume,
- .get_layer_state = rk3188_lcdc_get_layer_state,
+ .get_win_state = rk3188_lcdc_get_win_state,
.ovl_mgr = rk3188_lcdc_ovl_mgr,
.get_disp_info = rk3188_lcdc_get_disp_info,
.fps_mgr = rk3188_lcdc_fps_mgr,
- .fb_get_layer = rk3188_fb_get_layer,
- .fb_layer_remap = rk3188_fb_layer_remap,
+ .fb_get_win_id = rk3188_lcdc_get_win_id,
+ .fb_win_remap = rk3188_fb_win_remap,
.set_dsp_lut = rk3188_set_dsp_lut,
.poll_vblank = rk3188_lcdc_poll_vblank,
.dpi_open = rk3188_lcdc_dpi_open,
- .dpi_layer_sel = rk3188_lcdc_dpi_layer_sel,
+ .dpi_win_sel = rk3188_lcdc_dpi_win_sel,
.dpi_status = rk3188_lcdc_dpi_status,
};
static irqreturn_t rk3188_lcdc_isr(int irq, void *dev_id)
{
- struct rk3188_lcdc_device *lcdc_dev = (struct rk3188_lcdc_device *)dev_id;
+ struct lcdc_device *lcdc_dev =
+ (struct lcdc_device *)dev_id;
ktime_t timestamp = ktime_get();
u32 int_reg = lcdc_readl(lcdc_dev, INT_STATUS);
if (int_reg & m_FS_INT_STA) {
timestamp = ktime_get();
- lcdc_msk_reg(lcdc_dev, INT_STATUS, m_FS_INT_CLEAR, v_FS_INT_CLEAR(1));
+ lcdc_msk_reg(lcdc_dev, INT_STATUS, m_FS_INT_CLEAR,
+ v_FS_INT_CLEAR(1));
if (lcdc_dev->driver.wait_fs) {
spin_lock(&(lcdc_dev->driver.cpl_lock));
complete(&(lcdc_dev->driver.frame_done));
wake_up_interruptible_all(&lcdc_dev->driver.vsync_info.wait);
} else if (int_reg & m_LF_INT_STA) {
- lcdc_msk_reg(lcdc_dev, INT_STATUS, m_LF_INT_CLEAR, v_LF_INT_CLEAR(1));
+ lcdc_msk_reg(lcdc_dev, INT_STATUS, m_LF_INT_CLEAR,
+ v_LF_INT_CLEAR(1));
}
return IRQ_HANDLED;
}
#define rk3188_lcdc_resume NULL
#endif
+static int rk3188_lcdc_parse_dt(struct lcdc_device *lcdc_dev)
+{
+ struct device_node *np = lcdc_dev->dev->of_node;
+ int val;
+ if (of_property_read_u32(np, "rockchip,prop", &val))
+ lcdc_dev->prop = PRMRY; /*default set it as primary */
+ else
+ lcdc_dev->prop = val;
+
+ if (of_property_read_u32(np, "rockchip,pwr18", &val))
+ lcdc_dev->pwr18 = false; /*default set it as 3.xv power supply */
+ else
+ lcdc_dev->pwr18 = (val ? true : false);
+ return 0;
+}
+
static int rk3188_lcdc_probe(struct platform_device *pdev)
{
- struct rk3188_lcdc_device *lcdc_dev = NULL;
+ struct lcdc_device *lcdc_dev = NULL;
struct rk_lcdc_driver *dev_drv;
struct device *dev = &pdev->dev;
struct resource *res;
int prop;
int ret = 0;
- /*if the primary lcdc has not registered ,the extend lcdc register later*/
+ /*if the primary lcdc has not registered ,the extend
+ lcdc register later */
of_property_read_u32(np, "rockchip,prop", &prop);
- if (prop == EXTEND) {
+ if (prop == EXTEND) {
if (!is_prmry_rk_lcdc_registered())
return -EPROBE_DEFER;
}
- lcdc_dev = devm_kzalloc(dev, sizeof(struct rk3188_lcdc_device), GFP_KERNEL);
+ lcdc_dev = devm_kzalloc(dev,
+ sizeof(struct lcdc_device), GFP_KERNEL);
if (!lcdc_dev) {
dev_err(&pdev->dev, "rk3188 lcdc device kmalloc fail!");
return -ENOMEM;
}
platform_set_drvdata(pdev, lcdc_dev);
-
+ lcdc_dev->dev = dev;
+ rk3188_lcdc_parse_dt(lcdc_dev);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
lcdc_dev->reg_phy_base = res->start;
lcdc_dev->len = resource_size(res);
if (IS_ERR(lcdc_dev->regsbak))
return PTR_ERR(lcdc_dev->regsbak);
lcdc_dev->dsp_lut_addr_base = (lcdc_dev->regs + DSP_LUT_ADDR);
- dev_info(dev, "lcdc%d:reg_phy_base = 0x%08x,reg_vir_base:0x%p\n",
- lcdc_dev->id, lcdc_dev->reg_phy_base, lcdc_dev->regs);
-
- lcdc_dev->dev = dev;
lcdc_dev->id = rk3188_lcdc_get_id(lcdc_dev->reg_phy_base);
+ if (lcdc_dev->id < 0) {
+ dev_err(&pdev->dev, "no such lcdc device!\n");
+ return -ENXIO;
+ }
+ dev_set_name(lcdc_dev->dev, "lcdc%d", lcdc_dev->id);
dev_drv = &lcdc_dev->driver;
dev_drv->dev = dev;
dev_drv->prop = prop;
dev_drv->id = lcdc_dev->id;
dev_drv->ops = &lcdc_drv_ops;
- dev_drv->num_layer = ARRAY_SIZE(lcdc_layer);
+ dev_drv->num_win = ARRAY_SIZE(lcdc_win);
spin_lock_init(&lcdc_dev->reg_lock);
lcdc_dev->irq = platform_get_irq(pdev, 0);
if (lcdc_dev->irq < 0) {
- dev_err(&pdev->dev, "cannot find IRQ for lcdc%d\n", lcdc_dev->id);
+ dev_err(&pdev->dev, "cannot find IRQ for lcdc%d\n",
+ lcdc_dev->id);
return -ENXIO;
}
return ret;
}
- ret = rk_fb_register(dev_drv, lcdc_layer, lcdc_dev->id);
+ ret = rk_fb_register(dev_drv, lcdc_win, lcdc_dev->id);
if (ret < 0) {
dev_err(dev, "register fb for lcdc%d failed!\n", lcdc_dev->id);
return ret;
static int rk3188_lcdc_remove(struct platform_device *pdev)
{
- struct rk3188_lcdc_device *lcdc_dev = platform_get_drvdata(pdev);
- rk3188_lcdc_deint(lcdc_dev);
- rk_fb_unregister(&(lcdc_dev->driver));
return 0;
}
static void rk3188_lcdc_shutdown(struct platform_device *pdev)
{
- struct rk3188_lcdc_device *lcdc_dev = platform_get_drvdata(pdev);
- if (lcdc_dev->driver.cur_screen->standby) /*standby the screen if necessary */
- lcdc_dev->driver.cur_screen->standby(1);
- if (lcdc_dev->driver.screen_ctr_info->io_disable) /*power off the screen if necessary */
- lcdc_dev->driver.screen_ctr_info->io_disable();
+ struct lcdc_device *lcdc_dev = platform_get_drvdata(pdev);
+
rk3188_lcdc_deint(lcdc_dev);
- /*rk_fb_unregister(&(lcdc_dev->driver)); */
+ rk_disp_pwr_disable(&lcdc_dev->driver);
}
#if defined(CONFIG_OF)
#include <linux/rk_fb.h>
#include <linux/linux_logo.h>
#include <linux/dma-mapping.h>
+
+
+#if defined(CONFIG_RK_HDMI)
#include "hdmi/rk_hdmi.h"
+#endif
#ifdef CONFIG_OF
#include <linux/of.h>
*/
int rk_disp_pwr_ctr_parse_dt(struct rk_lcdc_driver *dev_drv)
{
- struct device_node *root = of_find_node_by_name(dev_drv->dev->of_node,
- "power_ctr");
+ struct device_node *root = of_parse_phandle(dev_drv->dev->of_node,
+ "power_ctr", 0);
struct device_node *child;
struct rk_disp_pwr_ctr_list *pwr_ctr;
struct list_head *pos;
INIT_LIST_HEAD(&dev_drv->pwrlist_head);
if (!root) {
- dev_err(dev_drv->dev, "can't find power_ctr node for lcdc:%d\n",dev_drv->id);
+ dev_err(dev_drv->dev, "can't find power_ctr node for lcdc%d\n",dev_drv->id);
return -ENODEV;
}
if (!gpio_is_valid(pwr_ctr->pwr_ctr.gpio)) {
dev_err(dev_drv->dev, "%s ivalid gpio\n", child->name);
return -EINVAL;
- }
+ }
pwr_ctr->pwr_ctr.atv_val = flags & OF_GPIO_ACTIVE_LOW;
ret = gpio_request(pwr_ctr->pwr_ctr.gpio,child->name);
if (ret) {
- dev_err(dev_drv->dev, "request %s gpio fail\n",
- child->name);
+ dev_err(dev_drv->dev, "request %s gpio fail:%d\n",
+ child->name,ret);
}
-
+
} else {
pwr_ctr->pwr_ctr.type = REGULATOR;
-
+
}
};
of_property_read_u32(child, "rockchip,delay", &val);
pwr_ctr->pwr_ctr.delay);
}
}
-
+
return 0;
-
+
}
int rk_disp_pwr_enable(struct rk_lcdc_driver *dev_drv)
struct list_head *pos;
struct rk_disp_pwr_ctr_list *pwr_ctr_list;
struct pwr_ctr *pwr_ctr;
- if (list_empty(&dev_drv->pwrlist_head))
+ if (list_empty(&dev_drv->pwrlist_head))
return 0;
list_for_each(pos, &dev_drv->pwrlist_head) {
pwr_ctr_list = list_entry(pos, struct rk_disp_pwr_ctr_list, list);
struct list_head *pos;
struct rk_disp_pwr_ctr_list *pwr_ctr_list;
struct pwr_ctr *pwr_ctr;
- if (list_empty(&dev_drv->pwrlist_head))
+ if (list_empty(&dev_drv->pwrlist_head))
return 0;
list_for_each(pos, &dev_drv->pwrlist_head) {
pwr_ctr_list = list_entry(pos, struct rk_disp_pwr_ctr_list, list);
{
struct display_timings *disp_timing;
struct display_timing *dt;
- rk_screen *screen = dev_drv->cur_screen;
+ struct rk_screen *screen = dev_drv->cur_screen;
disp_timing = of_get_display_timings(dev_drv->dev->of_node);
if (!disp_timing) {
dev_err(dev_drv->dev, "parse display timing err\n");
return -EINVAL;
}
dt = display_timings_get(disp_timing, 0);
-
- screen->pixclock = dt->pixelclock.typ;
- screen->left_margin = dt->hback_porch.typ;
- screen->right_margin = dt->hfront_porch.typ;
- screen->x_res = dt->hactive.typ;
- screen->hsync_len = dt->hsync_len.typ;
- screen->upper_margin = dt->vback_porch.typ;
- screen->lower_margin = dt->vfront_porch.typ;
- screen->y_res = dt->vactive.typ;
- screen->vsync_len = dt->vsync_len.typ;
- printk(KERN_INFO "dclk:%d\n"
+
+ screen->mode.pixclock = dt->pixelclock.typ;
+ screen->mode.left_margin = dt->hback_porch.typ;
+ screen->mode.right_margin = dt->hfront_porch.typ;
+ screen->mode.xres = dt->hactive.typ;
+ screen->mode.hsync_len = dt->hsync_len.typ;
+ screen->mode.upper_margin = dt->vback_porch.typ;
+ screen->mode.lower_margin = dt->vfront_porch.typ;
+ screen->mode.yres = dt->vactive.typ;
+ screen->mode.vsync_len = dt->vsync_len.typ;
+ printk(KERN_DEBUG "dclk:%d\n"
"hactive:%d\n"
"hback_porch:%d\n"
"hfront_porch:%d\n"
dt->vfront_porch.typ,
dt->vsync_len.typ);
return 0;
-
+
}
+
+int rk_fb_calc_fps(struct rk_screen * screen, u32 pixclock)
+{
+ int x, y;
+ unsigned long long hz;
+ if (!screen) {
+ printk(KERN_ERR "%s:null screen!\n", __func__);
+ return 0;
+ }
+ x = screen->mode.xres + screen->mode.left_margin + screen->mode.right_margin +
+ screen->mode.hsync_len;
+ y = screen->mode.yres + screen->mode.upper_margin + screen->mode.lower_margin +
+ screen->mode.vsync_len;
+
+ hz = 1000000000000ULL; /* 1e12 picoseconds per second */
+
+ hz += (x * y) / 2;
+ do_div(hz, x * y); /* divide by x * y with rounding */
+
+ hz += pixclock / 2;
+ do_div(hz, pixclock); /* divide by pixclock with rounding */
+
+ return hz;
+}
+
char *get_format_string(enum data_format format, char *fmt)
{
if (!fmt)
dclk_mhz = dev_drv->pixclock/(1000*1000);
- htotal = (dev_drv->cur_screen->upper_margin + dev_drv->cur_screen->lower_margin +
- dev_drv->cur_screen->y_res + dev_drv->cur_screen->vsync_len);
- vtotal = (dev_drv->cur_screen->left_margin + dev_drv->cur_screen->right_margin +
- dev_drv->cur_screen->x_res + dev_drv->cur_screen->hsync_len);
+ htotal = (dev_drv->cur_screen->mode.upper_margin + dev_drv->cur_screen->mode.lower_margin +
+ dev_drv->cur_screen->mode.yres + dev_drv->cur_screen->mode.vsync_len);
+ vtotal = (dev_drv->cur_screen->mode.left_margin + dev_drv->cur_screen->mode.right_margin +
+ dev_drv->cur_screen->mode.xres + dev_drv->cur_screen->mode.hsync_len);
pix_total = htotal*vtotal;
ft_us = pix_total / dclk_mhz;
return dev_drv;
}
-rk_screen *rk_fb_get_prmry_screen(void)
+struct rk_screen *rk_fb_get_prmry_screen(void)
{
struct rk_lcdc_driver *dev_drv = rk_get_prmry_lcdc_drv();
return dev_drv->screen0;
static int rk_fb_open(struct fb_info *info, int user)
{
struct rk_lcdc_driver *dev_drv = (struct rk_lcdc_driver *)info->par;
- int layer_id;
+ int win_id;
- layer_id = dev_drv->ops->fb_get_layer(dev_drv, info->fix.id);
- if (dev_drv->layer_par[layer_id]->state)
- return 0; /* if this layer aready opened ,no need to reopen*/
+ win_id = dev_drv->ops->fb_get_win_id(dev_drv, info->fix.id);
+ if (dev_drv->win[win_id]->state)
+ return 0; /* if this win aready opened ,no need to reopen*/
else
- dev_drv->ops->open(dev_drv, layer_id, 1);
+ dev_drv->ops->open(dev_drv, win_id, 1);
return 0;
}
fb_id = 0;
else if (!strcmp(id, "fb1"))
fb_id = 1;
- else if (!strcmp(id, "fb2") && (dev_drv->num_layer > 2))
+ else if (!strcmp(id, "fb2") && (dev_drv->num_win > 2))
fb_id = 2;
return fb_id;
}
static int rk_fb_close(struct fb_info *info, int user)
{
struct rk_lcdc_driver *dev_drv = (struct rk_lcdc_driver *)info->par;
- struct layer_par *par = NULL;
- int layer_id = dev_drv->ops->fb_get_layer(dev_drv, info->fix.id);
- if (layer_id >= 0) {
- par = dev_drv->layer_par[layer_id];
- info->fix.smem_start = par->reserved;
-
- info->var.xres = dev_drv->screen0->x_res;
- info->var.yres = dev_drv->screen0->y_res;
+ struct rk_lcdc_win *win = NULL;
+ int win_id = dev_drv->ops->fb_get_win_id(dev_drv, info->fix.id);
+ if (win_id >= 0) {
+ win = dev_drv->win[win_id];
+ info->fix.smem_start = win->reserved;
+
+ info->var.xres = dev_drv->screen0->mode.xres;
+ info->var.yres = dev_drv->screen0->mode.yres;
info->var.grayscale |= (info->var.xres<<8) + (info->var.yres<<20);
#if defined(CONFIG_LOGO_LINUX_BMP)
info->var.bits_per_pixel = 32;
info->var.width = dev_drv->screen0->width;
info->var.height = dev_drv->screen0->height;
info->var.pixclock = dev_drv->pixclock;
- info->var.left_margin = dev_drv->screen0->left_margin;
- info->var.right_margin = dev_drv->screen0->right_margin;
- info->var.upper_margin = dev_drv->screen0->upper_margin;
- info->var.lower_margin = dev_drv->screen0->lower_margin;
- info->var.vsync_len = dev_drv->screen0->vsync_len;
- info->var.hsync_len = dev_drv->screen0->hsync_len;
+ info->var.left_margin = dev_drv->screen0->mode.left_margin;
+ info->var.right_margin = dev_drv->screen0->mode.right_margin;
+ info->var.upper_margin = dev_drv->screen0->mode.upper_margin;
+ info->var.lower_margin = dev_drv->screen0->mode.lower_margin;
+ info->var.vsync_len = dev_drv->screen0->mode.vsync_len;
+ info->var.hsync_len = dev_drv->screen0->mode.hsync_len;
}
return 0;
return ipp_fmt;
}
-static void ipp_par_check(int *dst_w, int *dst_h, int *dst_vir_w,
+static void ipp_win_check(int *dst_w, int *dst_h, int *dst_vir_w,
int rotation, int fmt)
{
int align16 = 2;
dst_h = dst_info->var.yres;
dst_vir_w = dst_info->var.xres_virtual;
ipp_fmt = get_ipp_format(data_format);
- ipp_par_check(&dst_w, &dst_h, &dst_vir_w, rotation, ipp_fmt);
+ ipp_win_check(&dst_w, &dst_h, &dst_vir_w, rotation, ipp_fmt);
ipp_req.src0.YrgbMst = src_info->fix.smem_start + offset;
ipp_req.src0.w = src_info->var.xres;
ipp_req.src0.h = src_info->var.yres;
{
struct rk_fb *rk_fb = dev_get_drvdata(info->device);
struct rk_lcdc_driver *dev_drv = (struct rk_lcdc_driver *)info->par;
- int fb_id = 0;
struct fb_info *extend_info = NULL;
struct rk_lcdc_driver *extend_dev_drv = NULL;
- int extend_layer_id = 0;
- struct layer_par *extend_par = NULL;
- struct layer_par *par = NULL;
-
+ int win_id = 0, extend_win_id = 0;
+ struct rk_lcdc_win *extend_win = NULL;
+ struct rk_lcdc_win *win = NULL;
+ int fb_id = 0;
+
- int layer_id = 0;
u32 xoffset = var->xoffset;
u32 yoffset = var->yoffset;
u32 xvir = var->xres_virtual;
u8 data_format = var->nonstd&0xff;
- layer_id = dev_drv->ops->fb_get_layer(dev_drv, info->fix.id);
- if (layer_id < 0)
+ win_id = dev_drv->ops->fb_get_win_id(dev_drv, info->fix.id);
+ if (win_id < 0)
return -ENODEV;
else
- par = dev_drv->layer_par[layer_id];
-
+ win = dev_drv->win[win_id];
+
if (rk_fb->disp_mode == DUAL) {
fb_id = get_extend_fb_id(info);
extend_info = rk_fb->fb[(rk_fb->num_fb>>1) + fb_id];
extend_dev_drv = (struct rk_lcdc_driver *)extend_info->par;
- extend_layer_id = dev_drv->ops->fb_get_layer(extend_dev_drv, extend_info->fix.id);
- extend_par= extend_dev_drv->layer_par[extend_layer_id];
+ extend_win_id = dev_drv->ops->fb_get_win_id(extend_dev_drv,
+ extend_info->fix.id);
+ extend_win = extend_dev_drv->win[extend_win_id];
}
-
- switch (par->format) {
+
+ switch (win->format) {
case XBGR888:
case ARGB888:
case ABGR888:
- par->y_offset = (yoffset*xvir + xoffset)*4;
+ win->y_offset = (yoffset*xvir + xoffset)*4;
break;
case RGB888:
- par->y_offset = (yoffset*xvir + xoffset)*3;
+ win->y_offset = (yoffset*xvir + xoffset)*3;
break;
case RGB565:
- par->y_offset = (yoffset*xvir + xoffset)*2;
+ win->y_offset = (yoffset*xvir + xoffset)*2;
break;
case YUV422:
- par->y_offset = yoffset*xvir + xoffset;
- par->c_offset = par->y_offset;
+ win->y_offset = yoffset*xvir + xoffset;
+ win->c_offset = win->y_offset;
break;
case YUV420:
- par->y_offset = yoffset*xvir + xoffset;
- par->c_offset = (yoffset>>1)*xvir + xoffset;
+ win->y_offset = yoffset*xvir + xoffset;
+ win->c_offset = (yoffset>>1)*xvir + xoffset;
break;
case YUV444:
- par->y_offset = yoffset*xvir + xoffset;
- par->c_offset = yoffset*2*xvir + (xoffset<<1);
+ win->y_offset = yoffset*xvir + xoffset;
+ win->c_offset = yoffset*2*xvir + (xoffset<<1);
break;
default:
printk(KERN_ERR "%s un supported format:0x%x\n",
return -EINVAL;
}
- dev_drv->ops->pan_display(dev_drv, layer_id);
+ dev_drv->ops->pan_display(dev_drv, win_id);
if (rk_fb->disp_mode == DUAL) {
- if (extend_par->state && (hdmi_switch_complete)) {
- extend_par->y_offset = par->y_offset;
+ if (extend_win->state && (hdmi_switch_complete)) {
+ extend_win->y_offset = win->y_offset;
#if defined(CONFIG_FB_ROTATE) || !defined(CONFIG_THREE_FB_BUFFER)
- rk_fb_rotate(extend_info, info, par->y_offset);
+ rk_fb_rotate(extend_info, info, win->y_offset);
#endif
- extend_dev_drv->ops->pan_display(extend_dev_drv, extend_layer_id);
+ extend_dev_drv->ops->pan_display(extend_dev_drv, extend_win_id);
}
}
struct rk_fb *rk_fb = dev_get_drvdata(info->device);
struct fb_fix_screeninfo *fix = &info->fix;
struct rk_lcdc_driver *dev_drv = (struct rk_lcdc_driver *)info->par;
- int fb_id = 0;
+ int fb_id = 0, extend_win_id = 0;
struct fb_info *extend_info = NULL;
struct rk_lcdc_driver *extend_dev_drv = NULL;
- struct layer_par *extend_par = NULL;
- int extend_layer_id = 0;
-
+ struct rk_lcdc_win *extend_win = NULL;
+
+
u32 yuv_phy[2];
- int layer_id = dev_drv->ops->fb_get_layer(dev_drv, info->fix.id);
+ int win_id = dev_drv->ops->fb_get_win_id(dev_drv, info->fix.id);
int enable; /* enable fb:1 enable;0 disable*/
int ovl; /*overlay:0 win1 on the top of win0;1,win0 on the top of win1*/
int num_buf; /*buffer_number*/
fb_id = get_extend_fb_id(info);
extend_info = rk_fb->fb[(rk_fb->num_fb>>1) + fb_id];
extend_dev_drv = (struct rk_lcdc_driver *)extend_info->par;
- extend_layer_id = dev_drv->ops->fb_get_layer(extend_dev_drv, extend_info->fix.id);
- extend_par= extend_dev_drv->layer_par[extend_layer_id];
+ extend_win_id = dev_drv->ops->fb_get_win_id(extend_dev_drv,
+ extend_info->fix.id);
+ extend_win = extend_dev_drv->win[extend_win_id];
}
switch (cmd) {
case RK_FBIOSET_ENABLE:
if (copy_from_user(&enable, argp, sizeof(enable)))
return -EFAULT;
- dev_drv->ops->open(dev_drv, layer_id, enable);
+ dev_drv->ops->open(dev_drv, win_id, enable);
break;
case RK_FBIOGET_ENABLE:
- enable = dev_drv->ops->get_layer_state(dev_drv, layer_id);
+ enable = dev_drv->ops->get_win_state(dev_drv, win_id);
if (copy_to_user(argp, &enable, sizeof(enable)))
return -EFAULT;
break;
if (dev_drv->ops->lcdc_reg_update)
dev_drv->ops->lcdc_reg_update(dev_drv);
if (rk_fb->disp_mode == DUAL) {
- if (extend_par->state && (hdmi_switch_complete)) {
+ if (extend_win->state && (hdmi_switch_complete)) {
if (rk_fb->num_fb >= 2) {
if (extend_dev_drv->ops->lcdc_reg_update)
extend_dev_drv->ops->lcdc_reg_update(extend_dev_drv);
}
break;
default:
- dev_drv->ops->ioctl(dev_drv, cmd, arg, layer_id);
+ dev_drv->ops->ioctl(dev_drv, cmd, arg, win_id);
break;
}
return 0;
{
struct rk_lcdc_driver *dev_drv = (struct rk_lcdc_driver *)info->par;
struct fb_fix_screeninfo *fix = &info->fix;
- int layer_id;
+ int win_id;
- layer_id = dev_drv->ops->fb_get_layer(dev_drv, fix->id);
- if (layer_id < 0)
+ win_id = dev_drv->ops->fb_get_win_id(dev_drv, fix->id);
+ if (win_id < 0)
return -ENODEV;
#if defined(CONFIG_RK_HDMI)
- if ((rk_fb->disp_mode == ONE_DUAL ) && (hdmi_get_hotplug() == HDMI_HPD_ACTIVED)) {
+ if ((rk_fb->disp_mode == ONE_DUAL) && (hdmi_get_hotplug() == HDMI_HPD_ACTIVED)) {
printk(KERN_INFO "hdmi is connect , not blank lcdc\n");
} else
#endif
{
- dev_drv->ops->blank(dev_drv, layer_id, blank_mode);
+ dev_drv->ops->blank(dev_drv, win_id, blank_mode);
}
return 0;
}
u8 __iomem *src;
int c, cnt = 0, err = 0;
unsigned long total_size;
- struct rk_lcdc_driver *dev_drv =
- (struct rk_lcdc_driver *)info->par;
- struct layer_par *par = NULL;
- int layer_id = 0;
+ struct rk_lcdc_driver *dev_drv = (struct rk_lcdc_driver *)info->par;
+ struct rk_lcdc_win *win = NULL;
+ int win_id = 0;
- layer_id = dev_drv->ops->fb_get_layer(dev_drv, info->fix.id);
- if (layer_id < 0)
+ win_id = dev_drv->ops->fb_get_win_id(dev_drv, info->fix.id);
+ if (win_id < 0)
return -ENODEV;
else
- par = dev_drv->layer_par[layer_id];
+ win = dev_drv->win[win_id];
- if (par->format == RGB565)
- total_size = par->xact*par->yact<<1; /*only read the current frame buffer*/
+ if (win->format == RGB565)
+ total_size = win->xact*win->yact<<1; /*only read the current frame buffer*/
else
- total_size = par->xact*par->yact<<2;
+ total_size = win->xact*win->yact<<2;
if (p >= total_size)
if (!buffer)
return -ENOMEM;
- src = (u8 __iomem *) (info->screen_base + p + par->y_offset);
+ src = (u8 __iomem *) (info->screen_base + p + win->y_offset);
while (count) {
c = (count > PAGE_SIZE) ? PAGE_SIZE : count;
u8 __iomem *dst;
int c, cnt = 0, err = 0;
unsigned long total_size;
- struct rk_lcdc_driver *dev_drv =(struct rk_lcdc_driver *)info->par;
- struct layer_par *par = NULL;
- int layer_id = 0;
+ struct rk_lcdc_driver *dev_drv = (struct rk_lcdc_driver *)info->par;
+ struct rk_lcdc_win *win = NULL;
+ int win_id = 0;
- layer_id = dev_drv->ops->fb_get_layer(dev_drv, info->fix.id);
- if (layer_id < 0)
+ win_id = dev_drv->ops->fb_get_win_id(dev_drv, info->fix.id);
+ if (win_id < 0)
return -ENODEV;
else
- par = dev_drv->layer_par[layer_id];
+ win = dev_drv->win[win_id];
- if (par->format == RGB565)
- total_size = par->xact*par->yact<<1; /*write the current frame buffer*/
+ if (win->format == RGB565)
+ total_size = win->xact*win->yact<<1; /*write the current frame buffer*/
else
- total_size = par->xact*par->yact<<2;
+ total_size = win->xact*win->yact<<2;
if (p > total_size)
return -EFBIG;
if (!buffer)
return -ENOMEM;
- dst = (u8 __iomem *) (info->screen_base + p + par->y_offset);
+ dst = (u8 __iomem *) (info->screen_base + p + win->y_offset);
while (count) {
c = (count > PAGE_SIZE) ? PAGE_SIZE : count;
struct fb_fix_screeninfo *fix = &info->fix;
struct rk_lcdc_driver *dev_drv = (struct rk_lcdc_driver *)info->par;
struct rk_fb *rk_fb = dev_get_drvdata(info->device);
- int fb_id;
+ int fb_id, extend_win_id = 0;
struct fb_info *extend_info = NULL;
struct rk_lcdc_driver *extend_dev_drv = NULL;
- int extend_layer_id = 0;
- struct layer_par *extend_par = NULL;
- struct layer_par *par = NULL;
- rk_screen *screen = dev_drv->cur_screen;
- int layer_id = 0;
+ struct rk_lcdc_win *extend_win = NULL;
+ struct rk_lcdc_win *win = NULL;
+ struct rk_screen *screen = dev_drv->cur_screen;
+ int win_id = 0;
u32 cblen = 0, crlen = 0;
u16 xsize = 0, ysize = 0; /*winx display window height/width --->LCDC_WINx_DSP_INFO*/
u32 xoffset = var->xoffset; /* offset from virtual to visible*/
u8 data_format = var->nonstd&0xff;
-
+
var->pixclock = dev_drv->pixclock;
- layer_id = dev_drv->ops->fb_get_layer(dev_drv, info->fix.id);
- if (layer_id < 0)
+ win_id = dev_drv->ops->fb_get_win_id(dev_drv, info->fix.id);
+ if (win_id < 0)
return -ENODEV;
else
- par = dev_drv->layer_par[layer_id];
+ win = dev_drv->win[win_id];
if (rk_fb->disp_mode == DUAL) {
fb_id = get_extend_fb_id(info);
extend_info = rk_fb->fb[(rk_fb->num_fb>>1) + fb_id];
extend_dev_drv = (struct rk_lcdc_driver *)extend_info->par;
- extend_layer_id = dev_drv->ops->fb_get_layer(extend_dev_drv, extend_info->fix.id);
- extend_par= extend_dev_drv->layer_par[extend_layer_id];
+ extend_win_id = dev_drv->ops->fb_get_win_id(extend_dev_drv,
+ extend_info->fix.id);
+ extend_win = extend_dev_drv->win[extend_win_id];
}
if (var->grayscale>>8) { /*if the application has specific the horizontal and vertical display size*/
xsize = (var->grayscale>>8) & 0xfff;
ysize = (var->grayscale>>20) & 0xfff;
} else { /*ohterwise full screen display*/
- xsize = screen->x_res;
- ysize = screen->y_res;
+ xsize = screen->mode.xres;
+ ysize = screen->mode.yres;
}
/*this is for device like rk2928 ,whic have one lcdc but two display outputs*/
-/*save parameter set by android*/
+/*save winameter set by android*/
if (rk_fb->disp_mode != DUAL) {
- if (screen->screen_id == 0) {
-
+ if (screen->screen_id == 0) {
+
dev_drv->screen0->xsize = xsize;
dev_drv->screen0->ysize = ysize;
dev_drv->screen0->xpos = xpos;
#if 1
switch (data_format) {
case HAL_PIXEL_FORMAT_RGBX_8888:
- par->format = XBGR888;
+ win->format = XBGR888;
fix->line_length = 4 * xvir;
- par->y_offset = (yoffset*xvir + xoffset)*4;
+ win->y_offset = (yoffset*xvir + xoffset)*4;
break;
case HAL_PIXEL_FORMAT_RGBA_8888:
- par->format = ABGR888;
+ win->format = ABGR888;
fix->line_length = 4 * xvir;
- par->y_offset = (yoffset*xvir + xoffset)*4;
+ win->y_offset = (yoffset*xvir + xoffset)*4;
break;
case HAL_PIXEL_FORMAT_BGRA_8888:
- par->format = ARGB888;
+ win->format = ARGB888;
fix->line_length = 4 * xvir;
- par->y_offset = (yoffset*xvir + xoffset)*4;
+ win->y_offset = (yoffset*xvir + xoffset)*4;
break;
case HAL_PIXEL_FORMAT_RGB_888:
- par->format = RGB888;
+ win->format = RGB888;
fix->line_length = 3 * xvir;
- par->y_offset = (yoffset*xvir + xoffset)*3;
+ win->y_offset = (yoffset*xvir + xoffset)*3;
break;
case HAL_PIXEL_FORMAT_RGB_565:
- par->format = RGB565;
+ win->format = RGB565;
fix->line_length = 2 * xvir;
- par->y_offset = (yoffset*xvir + xoffset)*2;
+ win->y_offset = (yoffset*xvir + xoffset)*2;
break;
case HAL_PIXEL_FORMAT_YCbCr_422_SP:
- par->format = YUV422;
+ win->format = YUV422;
fix->line_length = xvir;
cblen = crlen = (xvir*yvir)>>1;
- par->y_offset = yoffset*xvir + xoffset;
- par->c_offset = par->y_offset;
+ win->y_offset = yoffset*xvir + xoffset;
+ win->c_offset = win->y_offset;
break;
case HAL_PIXEL_FORMAT_YCrCb_NV12:
- par->format = YUV420;
+ win->format = YUV420;
fix->line_length = xvir;
cblen = crlen = (xvir*yvir)>>2;
- par->y_offset = yoffset*xvir + xoffset;
- par->c_offset = (yoffset>>1)*xvir + xoffset;
+ win->y_offset = yoffset*xvir + xoffset;
+ win->c_offset = (yoffset>>1)*xvir + xoffset;
break;
case HAL_PIXEL_FORMAT_YCrCb_444:
- par->format = 5;
+ win->format = 5;
fix->line_length = xvir<<2;
- par->y_offset = yoffset*xvir + xoffset;
- par->c_offset = yoffset*2*xvir + (xoffset<<1);
+ win->y_offset = yoffset*xvir + xoffset;
+ win->c_offset = yoffset*2*xvir + (xoffset<<1);
cblen = crlen = (xvir*yvir);
break;
default:
#else
switch (var->bits_per_pixel) {
case 32:
- par->format = ARGB888;
+ win->format = ARGB888;
fix->line_length = 4 * xvir;
- par->y_offset = (yoffset*xvir + xoffset)*4;
+ win->y_offset = (yoffset*xvir + xoffset)*4;
break;
case 16:
- par->format = RGB565;
+ win->format = RGB565;
fix->line_length = 2 * xvir;
- par->y_offset = (yoffset*xvir + xoffset)*2;
+ win->y_offset = (yoffset*xvir + xoffset)*2;
break;
}
#endif
- par->xpos = xpos;
- par->ypos = ypos;
- par->xsize = xsize;
- par->ysize = ysize;
-
- par->smem_start = fix->smem_start;
- par->cbr_start = fix->mmio_start;
- par->xact = var->xres; /*winx active window height,is a part of vir*/
- par->yact = var->yres;
- par->xvir = var->xres_virtual; /*virtual resolution stride --->LCDC_WINx_VIR*/
- par->yvir = var->yres_virtual;
+ win->xpos = xpos;
+ win->ypos = ypos;
+ win->xsize = xsize;
+ win->ysize = ysize;
+
+ win->smem_start = fix->smem_start;
+ win->cbr_start = fix->mmio_start;
+ win->xact = var->xres; /*winx active window height,is a wint of vir*/
+ win->yact = var->yres;
+ win->xvir = var->xres_virtual; /*virtual resolution stride --->LCDC_WINx_VIR*/
+ win->yvir = var->yres_virtual;
if (rk_fb->disp_mode == DUAL) {
- if (extend_par->state && (hdmi_switch_complete)) {
+ if (extend_win->state && (hdmi_switch_complete)) {
if (info != extend_info) {
- if (par->xact < par->yact) {
- extend_par->xact = par->yact;
- extend_par->yact = par->xact;
- extend_par->xvir = par->yact;
+ if (win->xact < win->yact) {
+ extend_win->xact = win->yact;
+ extend_win->yact = win->xact;
+ extend_win->xvir = win->yact;
extend_info->var.xres = var->yres;
extend_info->var.yres = var->xres;
extend_info->var.xres_virtual = var->yres;
} else {
- extend_par->xact = par->xact;
- extend_par->yact = par->yact;
- extend_par->xvir = par->xvir;
+ extend_win->xact = win->xact;
+ extend_win->yact = win->yact;
+ extend_win->xvir = win->xvir;
extend_info->var.xres = var->xres;
extend_info->var.yres = var->yres;
extend_info->var.xres_virtual = var->xres_virtual;
}
- extend_par->format = par->format;
+ extend_win->format = win->format;
extend_info->var.nonstd &= 0xffffff00;
extend_info->var.nonstd |= data_format;
- extend_dev_drv->ops->set_par(extend_dev_drv, extend_layer_id);
+ extend_dev_drv->ops->set_par(extend_dev_drv, extend_win_id);
}
}
}
- dev_drv->ops->set_par(dev_drv, layer_id);
+ dev_drv->ops->set_par(dev_drv, win_id);
return 0;
}
return 0;
}
-int rk_fb_dpi_layer_sel(int layer_id)
+int rk_fb_dpi_win_sel(int win_id)
{
struct rk_lcdc_driver *dev_drv = NULL;
dev_drv = rk_get_prmry_lcdc_drv();
- dev_drv->ops->dpi_layer_sel(dev_drv, layer_id);
+ dev_drv->ops->dpi_win_sel(dev_drv, win_id);
return 0;
}
*enable: 1,hdmi plug in,0,hdmi plug out
*lcdc_id: the lcdc id the hdmi attached ,0 or 1
******************************************/
-int rk_fb_switch_screen(rk_screen *screen , int enable, int lcdc_id)
+int rk_fb_switch_screen(struct rk_screen *screen , int enable, int lcdc_id)
{
struct rk_fb *rk_fb = platform_get_drvdata(fb_pdev);
struct fb_info *info = NULL;
struct fb_fix_screeninfo *hdmi_fix = NULL;
char name[6];
int ret;
- int layer_id;
+ int win_id;
if (rk_fb->disp_mode != DUAL)
rk29_backlight_set(0);
if (rk_fb->num_lcdc == 1)
info = rk_fb->fb[0];
else if (rk_fb->num_lcdc == 2)
- info = rk_fb->fb[dev_drv->num_layer]; /*the main fb of lcdc1*/
+ info = rk_fb->fb[dev_drv->num_win]; /*the main fb of lcdc1*/
if (dev_drv->screen1) { /*device like rk2928 ,have only one lcdc but two outputs*/
if (enable) {
- memcpy(dev_drv->screen1, screen, sizeof(rk_screen));
+ memcpy(dev_drv->screen1, screen, sizeof(struct rk_screen));
dev_drv->screen1->lcdc_id = 0; /*connect screen1 to output interface 0*/
dev_drv->screen1->screen_id = 1;
dev_drv->screen0->lcdc_id = 1; /*connect screen0 to output interface 1*/
}
} else{
if (enable)
- memcpy(dev_drv->cur_screen, screen, sizeof(rk_screen));
+ memcpy(dev_drv->cur_screen, screen, sizeof(struct rk_screen));
}
- layer_id = dev_drv->ops->fb_get_layer(dev_drv, info->fix.id);
+ win_id = dev_drv->ops->fb_get_win_id(dev_drv, info->fix.id);
if (!enable && !dev_drv->screen1) { /*only double lcdc device need to close*/
- if (dev_drv->layer_par[layer_id]->state)
- dev_drv->ops->open(dev_drv, layer_id, enable); /*disable the layer which attached to this fb*/
+ if (dev_drv->win[win_id]->state)
+ dev_drv->ops->open(dev_drv, win_id, enable); /*disable the win which attached to this fb*/
hdmi_switch_complete = 0;
return 0;
}
}
hdmi_var->grayscale &= 0xff;
- hdmi_var->grayscale |= (dev_drv->cur_screen->x_res<<8) + (dev_drv->cur_screen->y_res<<20);
+ hdmi_var->grayscale |= (dev_drv->cur_screen->mode.xres<<8) + (dev_drv->cur_screen->mode.yres<<20);
if (dev_drv->screen1) { /*device like rk2928,whic have one lcdc but two outputs*/
/* info->var.nonstd &= 0xff;
- info->var.nonstd |= (dev_drv->cur_screen->xpos<<8) + (dev_drv->cur_screen->ypos<<20);
+ info->var.nonstd |= (dev_drv->cur_screen->mode.xpos<<8) + (dev_drv->cur_screen->mode.ypos<<20);
info->var.grayscale &= 0xff;
- info->var.grayscale |= (dev_drv->cur_screen->x_res<<8) + (dev_drv->cur_screen->y_res<<20);*/
- dev_drv->screen1->xsize = dev_drv->cur_screen->x_res;
- dev_drv->screen1->ysize = dev_drv->cur_screen->y_res;
+ info->var.grayscale |= (dev_drv->cur_screen->mode.x_res<<8) + (dev_drv->cur_screen->mode.y_res<<20);*/
+ dev_drv->screen1->xsize = dev_drv->cur_screen->mode.xres;
+ dev_drv->screen1->ysize = dev_drv->cur_screen->mode.yres;
dev_drv->screen1->xpos = 0;
dev_drv->screen1->ypos = 0;
}
if (inf->num_lcdc == 1)
info = inf->fb[0];
else if (inf->num_lcdc == 2)
- info = inf->fb[dev_drv->num_layer];
+ info = inf->fb[dev_drv->num_win];
var = &info->var;
- screen_x = dev_drv->cur_screen->x_res;
- screen_y = dev_drv->cur_screen->y_res;
+ screen_x = dev_drv->cur_screen->mode.xres;
+ screen_y = dev_drv->cur_screen->mode.yres;
#if defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF) || defined(CONFIG_NO_DUAL_DISP)
if (dev_drv->cur_screen->screen_id == 1) {
}
-static int rk_request_fb_buffer(struct fb_info *fbi, int fb_id)
+static int rk_fb_alloc_buffer(struct fb_info *fbi, int fb_id)
{
- struct rk_lcdc_driver *dev_drv =
- (struct rk_lcdc_driver *)fbi->par;
- struct layer_par *par = NULL;
- int layer_id;
- struct resource *res;
- struct resource *mem;
- int ret = 0;
struct rk_fb *fb_inf = platform_get_drvdata(fb_pdev);
+ struct rk_lcdc_driver *dev_drv = (struct rk_lcdc_driver *)fbi->par;
+ struct rk_lcdc_win *win = NULL;
+ int win_id;
+ int ret = 0;
+ dma_addr_t fb_mem_phys;
+ void *fb_mem_virt;
+ unsigned long fb_mem_size;
+
+ win_id = dev_drv->ops->fb_get_win_id(dev_drv, fbi->fix.id);
+ if (win_id < 0)
+ return -ENODEV;
+ else
+ win = dev_drv->win[win_id];
+
if (!strcmp(fbi->fix.id, "fb0")) {
- #if 1
- dma_addr_t fb_mem_phys;
- unsigned long fb_mem_len;
- void *fb_mem_virt;
- fb_mem_len = 3 * (fbi->var.xres * fbi->var.yres) << 2;
- fb_mem_virt = dma_alloc_writecombine(fbi->dev, fb_mem_len, &fb_mem_phys,
+ fb_mem_size = 3 * (fbi->var.xres * fbi->var.yres) << 2;
+ fb_mem_size = ALIGN(fb_mem_size, SZ_1M);
+#if 0 //defined(CONFIG_ION)
+ struct ion_handle *handle;
+ struct dma_buf *buf;
+ handle = ion_alloc(win->ion_client, (size_t)fb_mem_size, 0,0, 0);
+ if (IS_ERR(handle)) {
+ dev_err(fbi->device, "failed to ion_alloc\n");
+ return -ENOMEM;
+ }
+
+ buf = ion_share_dma_buf(win->ion_client, handle);
+ if (IS_ERR_OR_NULL(buf)) {
+ dev_err(fbi->dev, "ion_share_dma_buf() failed\n");
+ return PTR_ERR(buf);
+
+ }
+
+ ret = map_ion_handle(sfb, &win->dma_buf_data, handle, buf);
+ if (!ret)
+ goto err_map;
+ map_dma = win->dma_buf_data.dma_addr;
+#else
+
+ fb_mem_virt = dma_alloc_writecombine(fbi->dev, fb_mem_size, &fb_mem_phys,
GFP_KERNEL);
if (!fb_mem_virt) {
pr_err("%s: Failed to allocate framebuffer\n", __func__);
return -ENOMEM;
}
- fbi->fix.smem_len = fb_mem_len;
+ fbi->fix.smem_len = fb_mem_size;
fbi->fix.smem_start = fb_mem_phys;
fbi->screen_base = fb_mem_virt;
memset(fbi->screen_base, 0, fbi->fix.smem_len);
printk(KERN_INFO "fb%d:phy:%lx>>vir:%p>>len:0x%x\n", fb_id,
fbi->fix.smem_start, fbi->screen_base, fbi->fix.smem_len);
- #else
- res = platform_get_resource_byname(fb_pdev,
- IORESOURCE_MEM, "fb0 buf");
- if (res == NULL) {
- dev_err(&fb_pdev->dev, "failed to get memory for fb0 \n");
- ret = -ENOENT;
- }
- fbi->fix.smem_start = res->start;
- fbi->fix.smem_len = res->end - res->start + 1;
- mem = request_mem_region(res->start, resource_size(res),
- fb_pdev->name);
- fbi->screen_base = ioremap(res->start, fbi->fix.smem_len);
- memset(fbi->screen_base, 0, fbi->fix.smem_len);
- printk(KERN_INFO "fb%d:phy:%lx>>vir:%p>>len:0x%x\n", fb_id,
- fbi->fix.smem_start, fbi->screen_base, fbi->fix.smem_len);
- #endif
+#endif
} else {
#if defined(CONFIG_FB_ROTATE) || !defined(CONFIG_THREE_FB_BUFFER)
res = platform_get_resource_byname(fb_pdev,
}
fbi->screen_size = fbi->fix.smem_len;
- layer_id = dev_drv->ops->fb_get_layer(dev_drv, fbi->fix.id);
- if (layer_id >= 0) {
- par = dev_drv->layer_par[layer_id];
- par->reserved = fbi->fix.smem_start;
+ win_id = dev_drv->ops->fb_get_win_id(dev_drv, fbi->fix.id);
+ if (win_id >= 0) {
+ win = dev_drv->win[win_id];
+ win->reserved = fbi->fix.smem_start;
}
return ret;
return 0;
}
-static int init_layer_par(struct rk_lcdc_driver *dev_drv,struct layer_par *def_layer)
+static int init_lcdc_win(struct rk_lcdc_driver *dev_drv, struct rk_lcdc_win *def_win)
{
int i;
- struct layer_par *def_par = NULL;
- int num_par = dev_drv->num_layer;
- for (i = 0; i < num_par; i++) {
- struct layer_par *par = NULL;
- par = kzalloc(sizeof(struct layer_par), GFP_KERNEL);
- if (!par) {
- dev_err(dev_drv->dev, "kzmalloc for layer_par fail!");
+ int num_win = dev_drv->num_win;
+ for (i = 0; i < num_win; i++) {
+ struct rk_lcdc_win *win = NULL;
+ win = kzalloc(sizeof(struct rk_lcdc_win), GFP_KERNEL);
+ if (!win) {
+ dev_err(dev_drv->dev, "kzmalloc for win fail!");
return -ENOMEM;
}
- def_par = &def_layer[i];
- strcpy(par->name, def_par->name);
- par->id = def_par->id;
- par->support_3d = def_par->support_3d;
- dev_drv->layer_par[i] = par;
+ win = &def_win[i];
+ strcpy(win->name, def_win->name);
+ win->id = def_win->id;
+ win->support_3d = def_win->support_3d;
+ dev_drv->win[i] = win;
}
return 0;
static int init_lcdc_device_driver(struct rk_fb *rk_fb,
- struct layer_par *def_layer, int index)
+ struct rk_lcdc_win *def_win, int index)
{
struct rk_lcdc_driver *dev_drv = rk_fb->lcdc_dev_drv[index];
- rk_screen *screen = devm_kzalloc(dev_drv->dev, sizeof(rk_screen), GFP_KERNEL);
- rk_screen *screen1;
+ struct rk_screen *screen = devm_kzalloc(dev_drv->dev,
+ sizeof(struct rk_screen), GFP_KERNEL);
if (!screen) {
- dev_err(dev_drv->dev, "malloc screen for lcdc%d fail!", dev_drv->id);
+ dev_err(dev_drv->dev, "malloc screen for lcdc%d fail!",
+ dev_drv->id);
return -ENOMEM;
}
+
screen->screen_id = 0;
screen->lcdc_id = dev_drv->id;
dev_drv->screen0 = screen;
dev_drv->cur_screen = screen;
/* devie use one lcdc + rk61x scaler for dual display*/
if (rk_fb->disp_mode == ONE_DUAL) {
- rk_screen *screen1 = devm_kzalloc(dev_drv->dev,
- sizeof(rk_screen), GFP_KERNEL);
+ struct rk_screen *screen1 = devm_kzalloc(dev_drv->dev,
+ sizeof(struct rk_screen), GFP_KERNEL);
if (screen1) {
- dev_err(dev_drv->dev, "malloc screen1 for lcdc%d fail!", dev_drv->id);
+ dev_err(dev_drv->dev, "malloc screen1 for lcdc%d fail!",
+ dev_drv->id);
return -ENOMEM;
}
screen1->screen_id = 1;
dev_drv->screen1 = screen1;
}
sprintf(dev_drv->name, "lcdc%d", dev_drv->id);
- init_layer_par(dev_drv,def_layer);
+ init_lcdc_win(dev_drv, def_win);
init_completion(&dev_drv->frame_done);
spin_lock_init(&dev_drv->cpl_lock);
mutex_init(&dev_drv->fb_win_id_mutex);
- dev_drv->ops->fb_layer_remap(dev_drv, FB_DEFAULT_ORDER);
+ dev_drv->ops->fb_win_remap(dev_drv, FB_DEFAULT_ORDER);
dev_drv->first_frame = 1;
rk_disp_pwr_ctr_parse_dt(dev_drv);
- rk_disp_pwr_enable(dev_drv);
rk_disp_prase_timing_dt(dev_drv);
return 0;
#ifdef CONFIG_LOGO_LINUX_BMP
static struct linux_logo *bmp_logo;
-static int fb_prepare_bmp_logo(struct fb_info *info, int rotate)
+static int fb_prewine_bmp_logo(struct fb_info *info, int rotate)
{
bmp_logo = fb_find_logo(24);
if (bmp_logo == NULL) {
return true;
else
return false;
-
-
+
+
}
int rk_fb_register(struct rk_lcdc_driver *dev_drv,
- struct layer_par *layer_par,int id)
+ struct rk_lcdc_win *win, int id)
{
struct rk_fb *rk_fb = platform_get_drvdata(fb_pdev);
struct fb_info *fbi;
if (rk_fb->num_lcdc == RK30_MAX_LCDC_SUPPORT)
return -ENXIO;
-
+
for (i = 0; i < RK30_MAX_LCDC_SUPPORT; i++) {
if (!rk_fb->lcdc_dev_drv[i]) {
rk_fb->lcdc_dev_drv[i] = dev_drv;
}
index = i;
- init_lcdc_device_driver(rk_fb, layer_par, index);
- dev_drv->ops->init_lcdc(dev_drv);
+ init_lcdc_device_driver(rk_fb, win, index);
dev_drv->fb_index_base = rk_fb->num_fb;
- for (i = 0; i < dev_drv->num_layer; i++) {
+ for (i = 0; i < dev_drv->num_win; i++) {
fbi = framebuffer_alloc(0, &fb_pdev->dev);
if (!fbi) {
dev_err(&fb_pdev->dev, "fb framebuffer_alloc fail!");
fbi->var = def_var;
fbi->fix = def_fix;
sprintf(fbi->fix.id, "fb%d", rk_fb->num_fb);
- fbi->var.xres = dev_drv->cur_screen->x_res;
- fbi->var.yres = dev_drv->cur_screen->y_res;
+ fbi->var.xres = dev_drv->cur_screen->mode.xres;
+ fbi->var.yres = dev_drv->cur_screen->mode.yres;
fbi->var.grayscale |= (fbi->var.xres<<8) + (fbi->var.yres<<20);
#if defined(CONFIG_LOGO_LINUX_BMP)
fbi->var.bits_per_pixel = 32;
fbi->var.width = dev_drv->cur_screen->width;
fbi->var.height = dev_drv->cur_screen->height;
fbi->var.pixclock = dev_drv->pixclock;
- fbi->var.left_margin = dev_drv->cur_screen->left_margin;
- fbi->var.right_margin = dev_drv->cur_screen->right_margin;
- fbi->var.upper_margin = dev_drv->cur_screen->upper_margin;
- fbi->var.lower_margin = dev_drv->cur_screen->lower_margin;
- fbi->var.vsync_len = dev_drv->cur_screen->vsync_len;
- fbi->var.hsync_len = dev_drv->cur_screen->hsync_len;
+ fbi->var.left_margin = dev_drv->cur_screen->mode.left_margin;
+ fbi->var.right_margin = dev_drv->cur_screen->mode.right_margin;
+ fbi->var.upper_margin = dev_drv->cur_screen->mode.upper_margin;
+ fbi->var.lower_margin = dev_drv->cur_screen->mode.lower_margin;
+ fbi->var.vsync_len = dev_drv->cur_screen->mode.vsync_len;
+ fbi->var.hsync_len = dev_drv->cur_screen->mode.hsync_len;
fbi->fbops = &fb_ops;
fbi->flags = FBINFO_FLAG_DEFAULT;
- fbi->pseudo_palette = dev_drv->layer_par[i]->pseudo_pal;
+ fbi->pseudo_palette = dev_drv->win[i]->pseudo_pal;
if (i == 0) /* only alloc memory for main fb*/
- rk_request_fb_buffer(fbi, rk_fb->num_fb);
+ rk_fb_alloc_buffer(fbi, rk_fb->num_fb);
ret = register_framebuffer(fbi);
if (ret < 0) {
dev_err(&fb_pdev->dev, "%s fb%d register_framebuffer fail!\n",
}
rkfb_create_sysfs(fbi);
rk_fb->fb[rk_fb->num_fb] = fbi;
- dev_info(&fb_pdev->dev, "rockchip framebuffer registerd:%s\n", fbi->fix.id);
+ dev_info(&fb_pdev->dev, "rockchip framebuffer registerd:%s\n",
+ fbi->fix.id);
rk_fb->num_fb++;
if (i == 0) {
/*show logo for primary display device*/
#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
if (dev_drv->prop == PRMRY) {
- rk_fb->fb[0]->fbops->fb_open(rk_fb->fb[0], 1);
- rk_fb->fb[0]->fbops->fb_set_par(rk_fb->fb[0]);
-
+ struct fb_info *main_fbi = rk_fb->fb[0];
+ main_fbi->fbops->fb_open(main_fbi, 1);
+ main_fbi->fbops->fb_set_par(main_fbi);
#if defined(CONFIG_LOGO_LINUX_BMP)
- if (fb_prepare_bmp_logo(rk_fb->fb[0], FB_ROTATE_UR)) {
- fb_set_cmap(&rk_fb->fb[0]->cmap, rk_fb->fb[0]);
- fb_show_bmp_logo(rk_fb->fb[0], FB_ROTATE_UR);
- rk_fb->fb[0]->fbops->fb_pan_display(&(rk_fb->fb[0]->var),
- rk_fb->fb[0]);
- }
+ if (fb_prewine_bmp_logo(main_fbi, FB_ROTATE_UR)) {
+ fb_set_cmap(&main_fbi->cmap, main_fbi);
+ fb_show_bmp_logo(main_fbi, FB_ROTATE_UR);
+ main_fbi->fbops->fb_pan_display(&main_fbi->var, main_fbi);
+ }
#else
- if (fb_prepare_logo(rk_fb->fb[0], FB_ROTATE_UR)) {
- fb_set_cmap(&rk_fb->fb[0]->cmap, rk_fb->fb[0]);
- fb_show_logo(rk_fb->fb[0], FB_ROTATE_UR);
- rk_fb->fb[0]->fbops->fb_pan_display(&(rk_fb->fb[0]->var),
- rk_fb->fb[0]);
- }
+ if (fb_prepare_logo(main_fbi, FB_ROTATE_UR)) {
+ fb_set_cmap(&main_fbi->cmap, main_fbi);
+ fb_show_logo(main_fbi, FB_ROTATE_UR);
+ main_fbi->fbops->fb_pan_display(&main_fbi->var, main_fbi);
+ }
#endif
- rk_fb->fb[0]->fbops->fb_ioctl(rk_fb->fb[0],RK_FBIOSET_CONFIG_DONE, 0);
+ main_fbi->fbops->fb_ioctl(main_fbi, RK_FBIOSET_CONFIG_DONE, 0);
}
#endif
return 0;
struct rk_fb *fb_inf = platform_get_drvdata(fb_pdev);
struct fb_info *fbi;
int fb_index_base = dev_drv->fb_index_base;
- int fb_num = dev_drv->num_layer;
+ int fb_num = dev_drv->num_win;
int i = 0;
if (fb_inf->lcdc_dev_drv[i]->vsync_info.thread) {
}
for (i = 0; i < fb_num; i++)
- kfree(dev_drv->layer_par[i]);
+ kfree(dev_drv->win[i]);
for (i = fb_index_base; i < (fb_index_base+fb_num); i++) {
fbi = fb_inf->fb[i];
dev_err(&pdev->dev, "Missing device tree node.\n");
return -EINVAL;
}
-
+
rk_fb = devm_kzalloc(&pdev->dev, sizeof(struct rk_fb), GFP_KERNEL);
if (!rk_fb) {
dev_err(&pdev->dev, "kmalloc for rk fb fail!");
if (!of_property_read_u32(np, "rockchip,disp-mode", &mode)) {
rk_fb->disp_mode = mode;
-
+
} else {
dev_err(&pdev->dev, "no disp-mode node found!");
return -ENODEV;
}
+ dev_set_name(&pdev->dev, "rockchip-fb");
#if defined(CONFIG_HAS_EARLYSUSPEND)
suspend_info.inf = rk_fb;
register_early_suspend(&suspend_info.early_suspend);