diff options
author | Xiubo Li <Li.Xiubo@freescale.com> | 2014-10-13 03:00:19 (GMT) |
---|---|---|
committer | Matthew Weigel <Matthew.Weigel@freescale.com> | 2014-12-11 18:38:05 (GMT) |
commit | fca0ba73f6eb14cd5905b6f712c44d6010f45ba3 (patch) | |
tree | 92729f9d09e49669decdfa6e0c7931bc920eef3c /drivers/video/fsl-dcu-fb.c | |
parent | 1f5acf90b02785901ad11ca0eed4d251d48d339b (diff) | |
download | linux-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/fsl-dcu-fb.c')
-rw-r--r-- | drivers/video/fsl-dcu-fb.c | 406 |
1 files changed, 210 insertions, 196 deletions
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); |