aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorRobby Cai <R63905@freescale.com>2014-02-18 22:37:33 -0500
committerNitin Garg <nitin.garg@freescale.com>2014-04-16 09:57:38 -0400
commit5a062b2edf4e91b91bf282ab1c9fca28d9a68d3f (patch)
tree96039eb0959d136ab6054b340af068d5f67ec0c9 /drivers/video
parenta5f76c96ceb4e6faa3ff6c9aec6a50ef3fde708f (diff)
ENGR00299746-3 imx: lcdif: add disp_axi clock handling for imx6sx
The display axi clock is a clock gating newly added on imx6sx. It need to be enabled for lcdif/pxp/csi/pcie to work. It should be set as a placeholder on other SoCs. This patch also simplifies the sanity check for axi and pixel clock. Signed-off-by: Sandor Yu <R01008@freescale.com> Signed-off-by: Robby Cai <R63905@freescale.com>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/mxsfb.c43
1 files changed, 39 insertions, 4 deletions
diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c
index 7b0304af8665..cbca5c65d2e4 100644
--- a/drivers/video/mxsfb.c
+++ b/drivers/video/mxsfb.c
@@ -187,7 +187,9 @@ struct mxsfb_info {
187 struct platform_device *pdev; 187 struct platform_device *pdev;
188 struct clk *clk_pix; 188 struct clk *clk_pix;
189 struct clk *clk_axi; 189 struct clk *clk_axi;
190 struct clk *clk_disp_axi;
190 bool clk_axi_enabled; 191 bool clk_axi_enabled;
192 bool clk_disp_axi_enabled;
191 void __iomem *base; /* registers */ 193 void __iomem *base; /* registers */
192 unsigned allocated_size; 194 unsigned allocated_size;
193 int enabled; 195 int enabled;
@@ -234,8 +236,7 @@ static int mxsfb_unmap_videomem(struct fb_info *info);
234/* enable lcdif axi clock */ 236/* enable lcdif axi clock */
235static inline void clk_enable_axi(struct mxsfb_info *host) 237static inline void clk_enable_axi(struct mxsfb_info *host)
236{ 238{
237 if (!host->clk_axi_enabled && host && 239 if (!host->clk_axi_enabled && (host->clk_axi != NULL)) {
238 host->clk_axi && !IS_ERR(host->clk_axi)) {
239 clk_prepare_enable(host->clk_axi); 240 clk_prepare_enable(host->clk_axi);
240 host->clk_axi_enabled = true; 241 host->clk_axi_enabled = true;
241 } 242 }
@@ -244,13 +245,30 @@ static inline void clk_enable_axi(struct mxsfb_info *host)
244/* disable lcdif axi clock */ 245/* disable lcdif axi clock */
245static inline void clk_disable_axi(struct mxsfb_info *host) 246static inline void clk_disable_axi(struct mxsfb_info *host)
246{ 247{
247 if (host->clk_axi_enabled && host && 248 if (host->clk_axi_enabled && (host->clk_axi != NULL)) {
248 host->clk_axi && !IS_ERR(host->clk_axi)) {
249 clk_disable_unprepare(host->clk_axi); 249 clk_disable_unprepare(host->clk_axi);
250 host->clk_axi_enabled = false; 250 host->clk_axi_enabled = false;
251 } 251 }
252} 252}
253 253
254/* enable DISP axi clock */
255static inline void clk_enable_disp_axi(struct mxsfb_info *host)
256{
257 if (!host->clk_disp_axi_enabled && (host->clk_disp_axi != NULL)) {
258 clk_prepare_enable(host->clk_disp_axi);
259 host->clk_disp_axi_enabled = true;
260 }
261}
262
263/* disable DISP axi clock */
264static inline void clk_disable_disp_axi(struct mxsfb_info *host)
265{
266 if (host->clk_disp_axi_enabled && (host->clk_disp_axi != NULL)) {
267 clk_disable_unprepare(host->clk_disp_axi);
268 host->clk_disp_axi_enabled = false;
269 }
270}
271
254/* mask and shift depends on architecture */ 272/* mask and shift depends on architecture */
255static inline u32 set_hsync_pulse_width(struct mxsfb_info *host, unsigned val) 273static inline u32 set_hsync_pulse_width(struct mxsfb_info *host, unsigned val)
256{ 274{
@@ -430,6 +448,7 @@ static void mxsfb_enable_controller(struct fb_info *fb_info)
430 pm_runtime_get_sync(&host->pdev->dev); 448 pm_runtime_get_sync(&host->pdev->dev);
431 449
432 clk_enable_axi(host); 450 clk_enable_axi(host);
451 clk_enable_disp_axi(host);
433 452
434 clk_prepare_enable(host->clk_pix); 453 clk_prepare_enable(host->clk_pix);
435 clk_set_rate(host->clk_pix, PICOS2KHZ(fb_info->var.pixclock) * 1000U); 454 clk_set_rate(host->clk_pix, PICOS2KHZ(fb_info->var.pixclock) * 1000U);
@@ -464,6 +483,7 @@ static void mxsfb_disable_controller(struct fb_info *fb_info)
464 dev_dbg(&host->pdev->dev, "%s\n", __func__); 483 dev_dbg(&host->pdev->dev, "%s\n", __func__);
465 484
466 clk_enable_axi(host); 485 clk_enable_axi(host);
486 clk_enable_disp_axi(host);
467 /* 487 /*
468 * Even if we disable the controller here, it will still continue 488 * Even if we disable the controller here, it will still continue
469 * until its FIFOs are running out of data 489 * until its FIFOs are running out of data
@@ -505,6 +525,7 @@ static int mxsfb_set_par(struct fb_info *fb_info)
505 int reenable = 0; 525 int reenable = 0;
506 526
507 clk_enable_axi(host); 527 clk_enable_axi(host);
528 clk_enable_disp_axi(host);
508 529
509 dev_dbg(&host->pdev->dev, "%s\n", __func__); 530 dev_dbg(&host->pdev->dev, "%s\n", __func__);
510 /* 531 /*
@@ -726,6 +747,7 @@ static int mxsfb_blank(int blank, struct fb_info *fb_info)
726 if (host->enabled) 747 if (host->enabled)
727 mxsfb_disable_controller(fb_info); 748 mxsfb_disable_controller(fb_info);
728 749
750 clk_disable_disp_axi(host);
729 clk_disable_axi(host); 751 clk_disable_axi(host);
730 break; 752 break;
731 753
@@ -761,6 +783,7 @@ static int mxsfb_pan_display(struct fb_var_screeninfo *var,
761 } 783 }
762 784
763 clk_enable_axi(host); 785 clk_enable_axi(host);
786 clk_enable_disp_axi(host);
764 787
765 offset = fb_info->fix.line_length * var->yoffset; 788 offset = fb_info->fix.line_length * var->yoffset;
766 789
@@ -834,6 +857,7 @@ static int mxsfb_restore_mode(struct mxsfb_info *host)
834 struct fb_videomode vmode; 857 struct fb_videomode vmode;
835 858
836 clk_enable_axi(host); 859 clk_enable_axi(host);
860 clk_enable_disp_axi(host);
837 861
838 /* Only restore the mode when the controller is running */ 862 /* Only restore the mode when the controller is running */
839 ctrl = readl(host->base + LCDC_CTRL); 863 ctrl = readl(host->base + LCDC_CTRL);
@@ -1190,16 +1214,25 @@ static int mxsfb_probe(struct platform_device *pdev)
1190 1214
1191 host->clk_pix = devm_clk_get(&host->pdev->dev, "pix"); 1215 host->clk_pix = devm_clk_get(&host->pdev->dev, "pix");
1192 if (IS_ERR(host->clk_pix)) { 1216 if (IS_ERR(host->clk_pix)) {
1217 host->clk_pix = NULL;
1193 ret = PTR_ERR(host->clk_pix); 1218 ret = PTR_ERR(host->clk_pix);
1194 goto fb_release; 1219 goto fb_release;
1195 } 1220 }
1196 1221
1197 host->clk_axi = devm_clk_get(&host->pdev->dev, "axi"); 1222 host->clk_axi = devm_clk_get(&host->pdev->dev, "axi");
1198 if (IS_ERR(host->clk_axi)) { 1223 if (IS_ERR(host->clk_axi)) {
1224 host->clk_axi = NULL;
1199 ret = PTR_ERR(host->clk_axi); 1225 ret = PTR_ERR(host->clk_axi);
1200 goto fb_release; 1226 goto fb_release;
1201 } 1227 }
1202 1228
1229 host->clk_disp_axi = devm_clk_get(&host->pdev->dev, "disp_axi");
1230 if (IS_ERR(host->clk_disp_axi)) {
1231 host->clk_disp_axi = NULL;
1232 ret = PTR_ERR(host->clk_disp_axi);
1233 goto fb_release;
1234 }
1235
1203 host->reg_lcd = devm_regulator_get(&pdev->dev, "lcd"); 1236 host->reg_lcd = devm_regulator_get(&pdev->dev, "lcd");
1204 if (IS_ERR(host->reg_lcd)) 1237 if (IS_ERR(host->reg_lcd))
1205 host->reg_lcd = NULL; 1238 host->reg_lcd = NULL;
@@ -1274,12 +1307,14 @@ static void mxsfb_shutdown(struct platform_device *pdev)
1274 struct mxsfb_info *host = to_imxfb_host(fb_info); 1307 struct mxsfb_info *host = to_imxfb_host(fb_info);
1275 1308
1276 clk_enable_axi(host); 1309 clk_enable_axi(host);
1310 clk_enable_disp_axi(host);
1277 /* 1311 /*
1278 * Force stop the LCD controller as keeping it running during reboot 1312 * Force stop the LCD controller as keeping it running during reboot
1279 * might interfere with the BootROM's boot mode pads sampling. 1313 * might interfere with the BootROM's boot mode pads sampling.
1280 */ 1314 */
1281 writel(CTRL_RUN, host->base + LCDC_CTRL + REG_CLR); 1315 writel(CTRL_RUN, host->base + LCDC_CTRL + REG_CLR);
1282 writel(CTRL_MASTER, host->base + LCDC_CTRL + REG_CLR); 1316 writel(CTRL_MASTER, host->base + LCDC_CTRL + REG_CLR);
1317 clk_disable_disp_axi(host);
1283 clk_disable_axi(host); 1318 clk_disable_axi(host);
1284} 1319}
1285 1320