summaryrefslogtreecommitdiff
path: root/drivers/video
diff options
context:
space:
mode:
authorXiubo Li <Li.Xiubo@freescale.com>2014-10-13 03:00:19 (GMT)
committerMatthew Weigel <Matthew.Weigel@freescale.com>2014-12-11 18:38:05 (GMT)
commitfca0ba73f6eb14cd5905b6f712c44d6010f45ba3 (patch)
tree92729f9d09e49669decdfa6e0c7931bc920eef3c /drivers/video
parent1f5acf90b02785901ad11ca0eed4d251d48d339b (diff)
downloadlinux-fsl-qoriq-fca0ba73f6eb14cd5905b6f712c44d6010f45ba3.tar.xz
fb: dcu: convert to use regmap API.
The regmap framework has one feature of register cache, which will be more easy to add big endian mode and PM support. Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com> -- The first DRM version will be send out to the community before 15 Dec 2014. Change-Id: I3aa3c30f4ab42b64b80669b483b45a62ae31d6bb Reviewed-on: http://git.am.freescale.net:8181/21571 Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com> Reviewed-by: Dongsheng Wang <dongsheng.wang@freescale.com> Reviewed-by: Zhengxiong Jin <Jason.Jin@freescale.com>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/Kconfig1
-rw-r--r--drivers/video/fsl-dcu-fb.c406
2 files changed, 211 insertions, 196 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 1d2d7db..76eff63 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1987,6 +1987,7 @@ config FB_FSL_DCU
select FB_CFB_IMAGEBLIT
select FB_MODE_HELPERS
select VIDEOMODE_HELPERS
+ select REGMAP_MMIO
---help---
Framebuffer driver for the Freescale SoC DCU.
diff --git a/drivers/video/fsl-dcu-fb.c b/drivers/video/fsl-dcu-fb.c
index 2fc9994..57a42f2 100644
--- a/drivers/video/fsl-dcu-fb.c
+++ b/drivers/video/fsl-dcu-fb.c
@@ -19,6 +19,7 @@
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
#include <linux/uaccess.h>
#include <video/of_display_timing.h>
#include <video/videomode.h>
@@ -145,10 +146,12 @@
struct dcu_fb_data {
struct fb_info *fsl_dcu_info[DCU_LAYER_NUM_MAX];
struct device *dev;
- void __iomem *reg_base;
- bool big_endian;
+ struct regmap *regmap;
+ struct regmap *tcon_regmap;
+ struct regmap *scfg_regmap;
unsigned int irq;
struct clk *clk;
+ struct clk *tcon_clk;
};
struct layer_display_offset {
@@ -234,44 +237,26 @@ static struct mfb_info mfb_template[] = {
},
};
-static inline u32 dcu_readl(bool big_endian, void __iomem *addr)
-{
- if (big_endian)
- return ioread32be(addr);
- else
- return ioread32(addr);
-}
-
-static inline void dcu_writel(bool big_endian, u32 val, void __iomem *addr)
-{
- if (big_endian)
- iowrite32be(val, addr);
- else
- iowrite32(val, addr);
-}
-
static void reset_total_layers(struct device_node *np,
struct dcu_fb_data *dcufb)
{
- void __iomem *base = dcufb->reg_base;
- bool big_endian = dcufb->big_endian;
int i;
for (i = 0; i < DCU_TOTAL_LAYER_NUM; i++) {
- dcu_writel(big_endian, 0, base + DCU_CTRLDESCLN_1(i));
- dcu_writel(big_endian, 0, base + DCU_CTRLDESCLN_2(i));
- dcu_writel(big_endian, 0, base + DCU_CTRLDESCLN_3(i));
- dcu_writel(big_endian, 0, base + DCU_CTRLDESCLN_4(i));
- dcu_writel(big_endian, 0, base + DCU_CTRLDESCLN_5(i));
- dcu_writel(big_endian, 0, base + DCU_CTRLDESCLN_6(i));
- dcu_writel(big_endian, 0, base + DCU_CTRLDESCLN_7(i));
- dcu_writel(big_endian, 0, base + DCU_CTRLDESCLN_8(i));
- dcu_writel(big_endian, 0, base + DCU_CTRLDESCLN_9(i));
+ regmap_write(dcufb->regmap, DCU_CTRLDESCLN_1(i), 0);
+ regmap_write(dcufb->regmap, DCU_CTRLDESCLN_2(i), 0);
+ regmap_write(dcufb->regmap, DCU_CTRLDESCLN_3(i), 0);
+ regmap_write(dcufb->regmap, DCU_CTRLDESCLN_4(i), 0);
+ regmap_write(dcufb->regmap, DCU_CTRLDESCLN_5(i), 0);
+ regmap_write(dcufb->regmap, DCU_CTRLDESCLN_6(i), 0);
+ regmap_write(dcufb->regmap, DCU_CTRLDESCLN_7(i), 0);
+ regmap_write(dcufb->regmap, DCU_CTRLDESCLN_8(i), 0);
+ regmap_write(dcufb->regmap, DCU_CTRLDESCLN_9(i), 0);
if (of_device_is_compatible(np, "fsl,ls1021a-dcu"))
- dcu_writel(big_endian, 0, base + DCU_CTRLDESCLN_10(i));
+ regmap_write(dcufb->regmap, DCU_CTRLDESCLN_10(i), 0);
}
- dcu_writel(big_endian, DCU_UPDATE_MODE_READREG, base + DCU_UPDATE_MODE);
+ regmap_write(dcufb->regmap, DCU_UPDATE_MODE, DCU_UPDATE_MODE_READREG);
}
static int enable_panel(struct fb_info *info)
@@ -279,19 +264,17 @@ static int enable_panel(struct fb_info *info)
struct fb_var_screeninfo *var = &info->var;
struct mfb_info *mfbi = info->par;
struct dcu_fb_data *dcufb = mfbi->parent;
- bool big_endian = dcufb->big_endian;
- void __iomem *base = dcufb->reg_base;
unsigned int bpp;
- dcu_writel(big_endian, DCU_CTRLDESCLN_1_HEIGHT(var->yres) |
- DCU_CTRLDESCLN_1_WIDTH(var->xres),
- base + DCU_CTRLDESCLN_1(mfbi->index));
- dcu_writel(big_endian, DCU_CTRLDESCLN_2_POSY(mfbi->y_layer_d) |
- DCU_CTRLDESCLN_2_POSX(mfbi->x_layer_d),
- base + DCU_CTRLDESCLN_2(mfbi->index));
+ regmap_write(dcufb->regmap, DCU_CTRLDESCLN_1(mfbi->index),
+ DCU_CTRLDESCLN_1_HEIGHT(var->yres) |
+ DCU_CTRLDESCLN_1_WIDTH(var->xres));
+ regmap_write(dcufb->regmap, DCU_CTRLDESCLN_2(mfbi->index),
+ DCU_CTRLDESCLN_2_POSY(mfbi->y_layer_d) |
+ DCU_CTRLDESCLN_2_POSX(mfbi->x_layer_d));
- dcu_writel(big_endian, info->fix.smem_start,
- base + DCU_CTRLDESCLN_3(mfbi->index));
+ regmap_write(dcufb->regmap, DCU_CTRLDESCLN_3(mfbi->index),
+ info->fix.smem_start);
switch (var->bits_per_pixel) {
case 16:
@@ -309,32 +292,31 @@ static int enable_panel(struct fb_info *info)
return -EINVAL;
}
- dcu_writel(big_endian, DCU_CTRLDESCLN_4_EN |
- DCU_CTRLDESCLN_4_TRANS(mfbi->alpha) |
- DCU_CTRLDESCLN_4_BPP(bpp) |
- DCU_CTRLDESCLN_4_AB(mfbi->blend),
- base + DCU_CTRLDESCLN_4(mfbi->index));
-
- dcu_writel(big_endian, DCU_CTRLDESCLN_5_CKMAX_R(0xff) |
- DCU_CTRLDESCLN_5_CKMAX_G(0xff) |
- DCU_CTRLDESCLN_5_CKMAX_B(0xff),
- base + DCU_CTRLDESCLN_5(mfbi->index));
- dcu_writel(big_endian, DCU_CTRLDESCLN_6_CKMIN_R(0) |
- DCU_CTRLDESCLN_6_CKMIN_G(0) |
- DCU_CTRLDESCLN_6_CKMIN_B(0),
- base + DCU_CTRLDESCLN_6(mfbi->index));
-
- dcu_writel(big_endian, DCU_CTRLDESCLN_7_TILE_VER(0) |
- DCU_CTRLDESCLN_7_TILE_HOR(0),
- base + DCU_CTRLDESCLN_7(mfbi->index));
-
- dcu_writel(big_endian, DCU_CTRLDESCLN_8_FG_FCOLOR(0),
- base + DCU_CTRLDESCLN_8(mfbi->index));
- dcu_writel(big_endian, DCU_CTRLDESCLN_9_BG_BCOLOR(0),
- base + DCU_CTRLDESCLN_9(mfbi->index));
-
- dcu_writel(big_endian, DCU_UPDATE_MODE_READREG,
- base + DCU_UPDATE_MODE);
+ regmap_write(dcufb->regmap, DCU_CTRLDESCLN_4(mfbi->index),
+ DCU_CTRLDESCLN_4_EN |
+ DCU_CTRLDESCLN_4_TRANS(mfbi->alpha) |
+ DCU_CTRLDESCLN_4_BPP(bpp) |
+ DCU_CTRLDESCLN_4_AB(mfbi->blend));
+
+ regmap_write(dcufb->regmap, DCU_CTRLDESCLN_5(mfbi->index),
+ DCU_CTRLDESCLN_5_CKMAX_R(0xff) |
+ DCU_CTRLDESCLN_5_CKMAX_G(0xff) |
+ DCU_CTRLDESCLN_5_CKMAX_B(0xff));
+ regmap_write(dcufb->regmap, DCU_CTRLDESCLN_6(mfbi->index),
+ DCU_CTRLDESCLN_6_CKMIN_R(0) |
+ DCU_CTRLDESCLN_6_CKMIN_G(0) |
+ DCU_CTRLDESCLN_6_CKMIN_B(0));
+
+ regmap_write(dcufb->regmap, DCU_CTRLDESCLN_7(mfbi->index),
+ DCU_CTRLDESCLN_7_TILE_VER(0) |
+ DCU_CTRLDESCLN_7_TILE_HOR(0));
+
+ regmap_write(dcufb->regmap, DCU_CTRLDESCLN_8(mfbi->index),
+ DCU_CTRLDESCLN_8_FG_FCOLOR(0));
+ regmap_write(dcufb->regmap, DCU_CTRLDESCLN_9(mfbi->index),
+ DCU_CTRLDESCLN_9_BG_BCOLOR(0));
+
+ regmap_write(dcufb->regmap, DCU_UPDATE_MODE, DCU_UPDATE_MODE_READREG);
return 0;
}
@@ -343,41 +325,36 @@ static int disable_panel(struct fb_info *info)
{
struct mfb_info *mfbi = info->par;
struct dcu_fb_data *dcufb = mfbi->parent;
- bool big_endian = dcufb->big_endian;
- void __iomem *base = dcufb->reg_base;
-
- dcu_writel(big_endian, DCU_CTRLDESCLN_1_HEIGHT(0) |
- DCU_CTRLDESCLN_1_WIDTH(0),
- base + DCU_CTRLDESCLN_1(mfbi->index));
- dcu_writel(big_endian, DCU_CTRLDESCLN_2_POSY(0) |
- DCU_CTRLDESCLN_2_POSX(0),
- base + DCU_CTRLDESCLN_2(mfbi->index));
-
- dcu_writel(big_endian, 0,
- base + DCU_CTRLDESCLN_3(mfbi->index));
- dcu_writel(big_endian, 0,
- base + DCU_CTRLDESCLN_4(mfbi->index));
-
- dcu_writel(big_endian, DCU_CTRLDESCLN_5_CKMAX_R(0) |
- DCU_CTRLDESCLN_5_CKMAX_G(0) |
- DCU_CTRLDESCLN_5_CKMAX_B(0),
- base + DCU_CTRLDESCLN_5(mfbi->index));
- dcu_writel(big_endian, DCU_CTRLDESCLN_6_CKMIN_R(0) |
- DCU_CTRLDESCLN_6_CKMIN_G(0) |
- DCU_CTRLDESCLN_6_CKMIN_B(0),
- base + DCU_CTRLDESCLN_6(mfbi->index));
-
- dcu_writel(big_endian, DCU_CTRLDESCLN_7_TILE_VER(0) |
- DCU_CTRLDESCLN_7_TILE_HOR(0),
- base + DCU_CTRLDESCLN_7(mfbi->index));
-
- dcu_writel(big_endian, DCU_CTRLDESCLN_8_FG_FCOLOR(0),
- base + DCU_CTRLDESCLN_8(mfbi->index));
- dcu_writel(big_endian, DCU_CTRLDESCLN_9_BG_BCOLOR(0),
- base + DCU_CTRLDESCLN_9(mfbi->index));
-
- dcu_writel(big_endian, DCU_UPDATE_MODE_READREG,
- base + DCU_UPDATE_MODE);
+ regmap_write(dcufb->regmap, DCU_CTRLDESCLN_1(mfbi->index),
+ DCU_CTRLDESCLN_1_HEIGHT(0) |
+ DCU_CTRLDESCLN_1_WIDTH(0));
+ regmap_write(dcufb->regmap, DCU_CTRLDESCLN_2(mfbi->index),
+ DCU_CTRLDESCLN_2_POSY(0) |
+ DCU_CTRLDESCLN_2_POSX(0));
+
+ regmap_write(dcufb->regmap, DCU_CTRLDESCLN_3(mfbi->index), 0);
+ regmap_write(dcufb->regmap, DCU_CTRLDESCLN_4(mfbi->index), 0);
+
+ regmap_write(dcufb->regmap, DCU_CTRLDESCLN_5(mfbi->index),
+ DCU_CTRLDESCLN_5_CKMAX_R(0) |
+ DCU_CTRLDESCLN_5_CKMAX_G(0) |
+ DCU_CTRLDESCLN_5_CKMAX_B(0));
+ regmap_write(dcufb->regmap, DCU_CTRLDESCLN_6(mfbi->index),
+ DCU_CTRLDESCLN_6_CKMIN_R(0) |
+ DCU_CTRLDESCLN_6_CKMIN_G(0) |
+ DCU_CTRLDESCLN_6_CKMIN_B(0));
+
+ regmap_write(dcufb->regmap, DCU_CTRLDESCLN_7(mfbi->index),
+ DCU_CTRLDESCLN_7_TILE_VER(0) |
+ DCU_CTRLDESCLN_7_TILE_HOR(0));
+
+ regmap_write(dcufb->regmap, DCU_CTRLDESCLN_8(mfbi->index),
+ DCU_CTRLDESCLN_8_FG_FCOLOR(0));
+ regmap_write(dcufb->regmap, DCU_CTRLDESCLN_9(mfbi->index),
+ DCU_CTRLDESCLN_9_BG_BCOLOR(0));
+
+ regmap_write(dcufb->regmap, DCU_UPDATE_MODE,
+ DCU_UPDATE_MODE_READREG);
return 0;
}
@@ -385,14 +362,10 @@ static void enable_controller(struct fb_info *info)
{
struct mfb_info *mfbi = info->par;
struct dcu_fb_data *dcufb = mfbi->parent;
- unsigned int dcu_mode;
-
- dcu_mode = dcu_readl(dcufb->big_endian,
- dcufb->reg_base + DCU_DCU_MODE);
- dcu_mode &= ~DCU_MODE_DCU_MODE_MASK;
- dcu_writel(dcufb->big_endian, dcu_mode |
- DCU_MODE_DCU_MODE(DCU_MODE_NORMAL),
- dcufb->reg_base + DCU_DCU_MODE);
+
+ regmap_update_bits(dcufb->regmap, DCU_DCU_MODE,
+ DCU_MODE_DCU_MODE_MASK,
+ DCU_MODE_DCU_MODE(DCU_MODE_NORMAL));
}
static void disable_controller(struct fb_info *info)
@@ -400,8 +373,9 @@ static void disable_controller(struct fb_info *info)
struct mfb_info *mfbi = info->par;
struct dcu_fb_data *dcufb = mfbi->parent;
- dcu_writel(dcufb->big_endian, DCU_MODE_DCU_MODE(DCU_MODE_OFF),
- dcufb->reg_base + DCU_DCU_MODE);
+ regmap_update_bits(dcufb->regmap, DCU_DCU_MODE,
+ DCU_MODE_DCU_MODE_MASK,
+ DCU_MODE_DCU_MODE(DCU_MODE_OFF));
}
static int fsl_dcu_check_var(struct fb_var_screeninfo *var,
@@ -500,45 +474,43 @@ static void update_controller(struct fb_info *info)
struct fb_var_screeninfo *var = &info->var;
struct mfb_info *mfbi = info->par;
struct dcu_fb_data *dcufb = mfbi->parent;
- bool big_endian = dcufb->big_endian;
- void __iomem *base = dcufb->reg_base;
unsigned int div;
div = fsl_dcu_calc_div(info);
- dcu_writel(big_endian, div, base + DCU_DIV_RATIO);
+ regmap_write(dcufb->regmap, DCU_DIV_RATIO, div);
- dcu_writel(big_endian, DCU_DISP_SIZE_DELTA_Y(var->yres) |
- DCU_DISP_SIZE_DELTA_X(var->xres / 16),
- base + DCU_DISP_SIZE);
+ regmap_write(dcufb->regmap, DCU_DISP_SIZE,
+ DCU_DISP_SIZE_DELTA_Y(var->yres) |
+ DCU_DISP_SIZE_DELTA_X(var->xres / 16));
/* Horizontal and vertical sync parameters */
- dcu_writel(big_endian, DCU_HSYN_PARA_BP(var->left_margin) |
- DCU_HSYN_PARA_PW(var->hsync_len) |
- DCU_HSYN_PARA_FP(var->right_margin),
- base + DCU_HSYN_PARA);
+ regmap_write(dcufb->regmap, DCU_HSYN_PARA,
+ DCU_HSYN_PARA_BP(var->left_margin) |
+ DCU_HSYN_PARA_PW(var->hsync_len) |
+ DCU_HSYN_PARA_FP(var->right_margin));
- dcu_writel(big_endian, DCU_VSYN_PARA_BP(var->upper_margin) |
- DCU_VSYN_PARA_PW(var->vsync_len) |
- DCU_VSYN_PARA_FP(var->lower_margin),
- base + DCU_VSYN_PARA);
+ regmap_write(dcufb->regmap, DCU_VSYN_PARA,
+ DCU_VSYN_PARA_BP(var->upper_margin) |
+ DCU_VSYN_PARA_PW(var->vsync_len) |
+ DCU_VSYN_PARA_FP(var->lower_margin));
- dcu_writel(big_endian, DCU_SYN_POL_INV_PXCK_FALL |
- DCU_SYN_POL_NEG_REMAIN | DCU_SYN_POL_INV_VS_LOW |
- DCU_SYN_POL_INV_HS_LOW, base + DCU_SYN_POL);
+ regmap_write(dcufb->regmap, DCU_SYN_POL,
+ DCU_SYN_POL_INV_PXCK_FALL | DCU_SYN_POL_NEG_REMAIN |
+ DCU_SYN_POL_INV_VS_LOW | DCU_SYN_POL_INV_HS_LOW);
- dcu_writel(big_endian, DCU_BGND_R(0) | DCU_BGND_G(0) |
- DCU_BGND_B(0), base + DCU_BGND);
+ regmap_write(dcufb->regmap, DCU_BGND, DCU_BGND_R(0) |
+ DCU_BGND_G(0) | DCU_BGND_B(0));
- dcu_writel(big_endian, DCU_MODE_BLEND_ITER(DCU_LAYER_NUM_MAX) |
- DCU_MODE_RASTER_EN, base + DCU_DCU_MODE);
+ regmap_write(dcufb->regmap, DCU_DCU_MODE,
+ DCU_MODE_BLEND_ITER(DCU_LAYER_NUM_MAX) |
+ DCU_MODE_RASTER_EN);
- dcu_writel(big_endian, DCU_THRESHOLD_LS_BF_VS(0x3) |
- DCU_THRESHOLD_OUT_BUF_HIGH(0x78) |
- DCU_THRESHOLD_OUT_BUF_LOW(0xa),
- base + DCU_THRESHOLD);
+ regmap_write(dcufb->regmap, DCU_THRESHOLD,
+ DCU_THRESHOLD_LS_BF_VS(0x3) |
+ DCU_THRESHOLD_OUT_BUF_HIGH(0x78) |
+ DCU_THRESHOLD_OUT_BUF_LOW(0xa));
- dcu_writel(big_endian, DCU_UPDATE_MODE_READREG,
- base + DCU_UPDATE_MODE);
+ regmap_write(dcufb->regmap, DCU_UPDATE_MODE, DCU_UPDATE_MODE_READREG);
}
static int map_video_memory(struct fb_info *info)
@@ -587,10 +559,8 @@ static int fsl_dcu_set_layer(struct fb_info *info)
addr = info->fix.smem_start +
(pixel_offset * (var->bits_per_pixel >> 3));
- dcu_writel(dcufb->big_endian, addr,
- dcufb->reg_base + DCU_CTRLDESCLN_3(mfbi->index));
- dcu_writel(dcufb->big_endian, DCU_UPDATE_MODE_READREG,
- dcufb->reg_base + DCU_UPDATE_MODE);
+ regmap_write(dcufb->regmap, DCU_CTRLDESCLN_3(mfbi->index), addr);
+ regmap_write(dcufb->regmap, DCU_UPDATE_MODE, DCU_UPDATE_MODE_READREG);
return 0;
}
@@ -770,8 +740,6 @@ static int fsl_dcu_open(struct fb_info *info, int user)
{
struct mfb_info *mfbi = info->par;
struct dcu_fb_data *dcufb = mfbi->parent;
- u32 int_mask = dcu_readl(dcufb->big_endian,
- dcufb->reg_base + DCU_INT_MASK);
int ret = 0;
mfbi->index = info->node;
@@ -783,9 +751,8 @@ static int fsl_dcu_open(struct fb_info *info, int user)
if (ret < 0)
mfbi->count--;
else
- dcu_writel(dcufb->big_endian,
- int_mask & DCU_INT_MASK_ALL,
- dcufb->reg_base + DCU_INT_MASK);
+ regmap_update_bits(dcufb->regmap, DCU_INT_MASK,
+ DCU_INT_MASK_ALL, DCU_INT_MASK_ALL);
}
return ret;
@@ -928,25 +895,22 @@ static void uninstall_framebuffer(struct fb_info *info)
static irqreturn_t fsl_dcu_irq(int irq, void *dev_id)
{
struct dcu_fb_data *dcufb = dev_id;
- unsigned int status = dcu_readl(dcufb->big_endian,
- dcufb->reg_base + DCU_INT_STATUS);
- u32 dcu_mode;
+ unsigned int status;
+
+ regmap_read(dcufb->regmap, DCU_INT_STATUS, &status);
if (status & DCU_INT_STATUS_UNDRUN) {
- dcu_mode = dcu_readl(dcufb->big_endian,
- dcufb->reg_base + DCU_DCU_MODE);
- dcu_mode &= ~DCU_MODE_DCU_MODE_MASK;
- dcu_writel(dcufb->big_endian, dcu_mode |
- DCU_MODE_DCU_MODE(DCU_MODE_OFF),
- dcufb->reg_base + DCU_DCU_MODE);
+ regmap_update_bits(dcufb->regmap, DCU_DCU_MODE,
+ DCU_MODE_DCU_MODE_MASK,
+ DCU_MODE_DCU_MODE(DCU_MODE_OFF));
udelay(1);
- dcu_writel(dcufb->big_endian, dcu_mode |
- DCU_MODE_DCU_MODE(DCU_MODE_NORMAL),
- dcufb->reg_base + DCU_DCU_MODE);
+ regmap_update_bits(dcufb->regmap, DCU_DCU_MODE,
+ DCU_MODE_DCU_MODE_MASK,
+ DCU_MODE_DCU_MODE(DCU_MODE_NORMAL));
}
- dcu_writel(dcufb->big_endian, status,
- dcufb->reg_base + DCU_INT_STATUS);
+ regmap_write(dcufb->regmap, DCU_INT_STATUS, status);
+
return IRQ_HANDLED;
}
@@ -956,6 +920,7 @@ static int fsl_dcu_runtime_suspend(struct device *dev)
struct dcu_fb_data *dcufb = dev_get_drvdata(dev);
clk_disable_unprepare(dcufb->clk);
+ clk_disable_unprepare(dcufb->tcon_clk);
return 0;
}
@@ -964,83 +929,126 @@ static int fsl_dcu_runtime_resume(struct device *dev)
{
struct dcu_fb_data *dcufb = dev_get_drvdata(dev);
+ clk_prepare_enable(dcufb->tcon_clk);
clk_prepare_enable(dcufb->clk);
return 0;
}
#endif
-static int bypass_tcon(struct device_node *np, bool big_endian)
+static const struct regmap_config fsl_tcon_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+
+ .max_register = TCON_CTRL1,
+ .cache_type = REGCACHE_FLAT,
+};
+
+static int bypass_tcon(struct dcu_fb_data *dcufb, struct device_node *np)
{
struct device_node *tcon_np;
- struct platform_device *tcon_pdev;
- struct clk *tcon_clk;
+ struct platform_device *pdev;
struct resource *res;
- void __iomem *tcon_reg;
+ void __iomem *base;
tcon_np = of_parse_phandle(np, "tcon-controller", 0);
if (!tcon_np)
return 0;
- tcon_pdev = of_find_device_by_node(tcon_np);
- if (!tcon_pdev)
+ pdev = of_find_device_by_node(tcon_np);
+ if (!pdev)
return -EINVAL;
- tcon_clk = devm_clk_get(&tcon_pdev->dev, "tcon");
- if (IS_ERR(tcon_clk))
- return PTR_ERR(tcon_clk);
- clk_prepare_enable(tcon_clk);
-
- res = platform_get_resource(tcon_pdev, IORESOURCE_MEM, 0);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -ENODEV;
- tcon_reg = ioremap(res->start, resource_size(res));
- if (IS_ERR(tcon_reg))
- return PTR_ERR(tcon_reg);
+ base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(base)) {
+ dev_err(&pdev->dev, "could not ioremap resource\n");
+ return PTR_ERR(base);
+ }
+
+ dcufb->tcon_clk = devm_clk_get(&pdev->dev, "tcon");
+ if (IS_ERR(dcufb->tcon_clk))
+ return PTR_ERR(dcufb->tcon_clk);
+ clk_prepare_enable(dcufb->tcon_clk);
- dcu_writel(big_endian, TCON_BYPASS_ENABLE, tcon_reg + TCON_CTRL1);
+ dcufb->tcon_regmap = devm_regmap_init_mmio_clk(&pdev->dev,
+ "tcon", base, &fsl_tcon_regmap_config);
+ if (IS_ERR(dcufb->tcon_regmap)) {
+ dev_err(&pdev->dev, "regmap init failed\n");
+ return PTR_ERR(dcufb->tcon_regmap);
+ }
- iounmap(tcon_reg);
+ regmap_write(dcufb->tcon_regmap, TCON_CTRL1, TCON_BYPASS_ENABLE);
return 0;
}
-static int scfg_config(struct device_node *np, bool big_endian)
+static const struct regmap_config fsl_scfg_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+
+ .max_register = 0x28,
+ .cache_type = REGCACHE_FLAT,
+};
+
+static int scfg_config(struct dcu_fb_data *dcufb, struct device_node *np)
{
struct device_node *scfg_np;
- struct platform_device *scfg_pdev;
+ struct platform_device *pdev;
struct resource *res;
- void __iomem *scfg_reg;
+ void __iomem *base;
scfg_np = of_parse_phandle(np, "scfg-controller", 0);
if (!scfg_np)
return 0;
- scfg_pdev = of_find_device_by_node(scfg_np);
- if (!scfg_pdev)
+ pdev = of_find_device_by_node(scfg_np);
+ if (!pdev)
return -EINVAL;
- res = platform_get_resource(scfg_pdev, IORESOURCE_MEM, 0);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -ENODEV;
- scfg_reg = ioremap(res->start, resource_size(res));
- if (IS_ERR(scfg_reg))
- return PTR_ERR(scfg_reg);
+ base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(base)) {
+ dev_err(&pdev->dev, "could not ioremap resource\n");
+ return PTR_ERR(base);
+ }
- dcu_writel(big_endian, 0x80000000, scfg_reg + 0x028);
+ dcufb->scfg_regmap = devm_regmap_init_mmio_clk(&pdev->dev,
+ NULL, base, &fsl_scfg_regmap_config);
+ if (IS_ERR(dcufb->scfg_regmap)) {
+ dev_err(&pdev->dev, "regmap init failed\n");
+ return PTR_ERR(dcufb->scfg_regmap);
+ }
- iounmap(scfg_reg);
+ regmap_write(dcufb->scfg_regmap, 0x028, 0x80000000);
return 0;
}
+
+static const struct regmap_config fsl_dcu_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+
+ .max_register = 0x5e8,
+ .cache_type = REGCACHE_RBTREE,
+};
+
static int fsl_dcu_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct dcu_fb_data *dcufb;
struct mfb_info *mfbi;
struct resource *res;
+ void __iomem *base;
int ret = 0;
int i;
@@ -1058,13 +1066,18 @@ static int fsl_dcu_probe(struct platform_device *pdev)
return -ENODEV;
}
- dcufb->reg_base = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(dcufb->reg_base)) {
+ base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(base)) {
dev_err(&pdev->dev, "could not ioremap resource\n");
- return PTR_ERR(dcufb->reg_base);
+ return PTR_ERR(base);
}
- dcufb->big_endian = of_property_read_bool(np, "big-endian");
+ dcufb->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
+ NULL, base, &fsl_dcu_regmap_config);
+ if (IS_ERR(dcufb->regmap)) {
+ dev_err(&pdev->dev, "regmap init failed\n");
+ return PTR_ERR(dcufb->regmap);
+ }
dcufb->irq = platform_get_irq(pdev, 0);
if (!dcufb->irq) {
@@ -1081,13 +1094,13 @@ static int fsl_dcu_probe(struct platform_device *pdev)
/* Put TCON in bypass mode, so the input signals from DCU are passed
* through TCON unchanged */
- ret = bypass_tcon(np, dcufb->big_endian);
+ ret = bypass_tcon(dcufb, np);
if (ret) {
dev_err(&pdev->dev, "could not bypass TCON\n");
return -EINVAL;
}
- ret = scfg_config(np, dcufb->big_endian);
+ ret = scfg_config(dcufb, np);
if (ret) {
dev_err(&pdev->dev, "could not config scfg\n");
return -EINVAL;
@@ -1151,6 +1164,7 @@ static int fsl_dcu_remove(struct platform_device *pdev)
disable_controller(dcufb->fsl_dcu_info[0]);
+ clk_disable_unprepare(dcufb->tcon_clk);
clk_disable_unprepare(dcufb->clk);
free_irq(dcufb->irq, dcufb);