diff options
author | Fancy Fang <chen.fang@nxp.com> | 2016-12-08 16:15:45 +0800 |
---|---|---|
committer | Anson Huang <Anson.Huang@nxp.com> | 2017-06-08 19:28:11 +0800 |
commit | 1c75d7a599ccf190894672005ba136e1f8853e6b (patch) | |
tree | 7d76f325005c3724794340c5d427e5ec5af77ae6 /drivers/video | |
parent | 432d9df8f831700901dceb570201f35db7bc2602 (diff) |
MLK-13607-3 video: mxsfb: add pm_qos to interact with cpuidle
In imx7ulp board, it doesn't support busfreq but pm_qos to
interact with cpuidle.
Signed-off-by: Fancy Fang <chen.fang@nxp.com>
(cherry picked from commit d33f95300aae724fc0f0bbff5444f24022f7a38c)
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/fbdev/mxsfb.c | 48 |
1 files changed, 45 insertions, 3 deletions
diff --git a/drivers/video/fbdev/mxsfb.c b/drivers/video/fbdev/mxsfb.c index 0fd6daaaa10c..41f4ed190a50 100644 --- a/drivers/video/fbdev/mxsfb.c +++ b/drivers/video/fbdev/mxsfb.c @@ -45,6 +45,7 @@ #include <linux/kernel.h> #include <linux/of_device.h> #include <linux/of_gpio.h> +#include <linux/pm_qos.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/interrupt.h> @@ -185,6 +186,7 @@ enum mxsfb_devtype { MXSFB_V3, MXSFB_V4, + MXSFB_V5, }; /* CPU dependent register offsets */ @@ -196,6 +198,7 @@ struct mxsfb_devdata { unsigned hs_wdth_mask; unsigned hs_wdth_shift; unsigned ipversion; + u32 flags; }; struct mxsfb_info { @@ -224,10 +227,16 @@ struct mxsfb_info { struct mxc_dispdrv_handle *dispdrv; int id; struct fb_var_screeninfo var; + struct pm_qos_request pm_qos_req; }; #define mxsfb_is_v3(host) (host->devdata->ipversion == 3) #define mxsfb_is_v4(host) (host->devdata->ipversion == 4) +#define mxsfb_is_v5(host) (host->devdata->ipversion == 5) + +#define MXSFB_FLAG_NULL 0x0 +#define MXSFB_FLAG_BUSFREQ 0x1 +#define MXSFB_FLAG_PMQOS 0x2 static const struct mxsfb_devdata mxsfb_devdata[] = { [MXSFB_V3] = { @@ -238,6 +247,7 @@ static const struct mxsfb_devdata mxsfb_devdata[] = { .hs_wdth_mask = 0xff, .hs_wdth_shift = 24, .ipversion = 3, + .flags = MXSFB_FLAG_NULL, }, [MXSFB_V4] = { .transfer_count = LCDC_V4_TRANSFER_COUNT, @@ -247,6 +257,17 @@ static const struct mxsfb_devdata mxsfb_devdata[] = { .hs_wdth_mask = 0x3fff, .hs_wdth_shift = 18, .ipversion = 4, + .flags = MXSFB_FLAG_BUSFREQ, + }, + [MXSFB_V5] = { + .transfer_count = LCDC_V4_TRANSFER_COUNT, + .cur_buf = LCDC_V4_CUR_BUF, + .next_buf = LCDC_V4_NEXT_BUF, + .debug0 = LCDC_V4_DEBUG0, + .hs_wdth_mask = 0x3fff, + .hs_wdth_shift = 18, + .ipversion = 4, + .flags = MXSFB_FLAG_PMQOS, }, }; @@ -1354,6 +1375,9 @@ static const struct platform_device_id mxsfb_devtype[] = { .name = "imx28-fb", .driver_data = MXSFB_V4, }, { + .name = "imx7ulp-fb", + .driver_data = MXSFB_V5, + }, { /* sentinel */ } }; @@ -1362,7 +1386,7 @@ MODULE_DEVICE_TABLE(platform, mxsfb_devtype); static const struct of_device_id mxsfb_dt_ids[] = { { .compatible = "fsl,imx23-lcdif", .data = &mxsfb_devtype[0], }, { .compatible = "fsl,imx28-lcdif", .data = &mxsfb_devtype[1], }, - { .compatible = "fsl,imx7ulp-lcdif", .data = &mxsfb_devtype[1], }, + { .compatible = "fsl,imx7ulp-lcdif", .data = &mxsfb_devtype[2], }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, mxsfb_dt_ids); @@ -1534,6 +1558,9 @@ static int mxsfb_remove(struct platform_device *pdev) if (host->enabled) mxsfb_disable_controller(fb_info); + if (host->devdata->flags & MXSFB_FLAG_PMQOS) + pm_qos_remove_request(&host->pm_qos_req); + pm_runtime_disable(&host->pdev->dev); unregister_framebuffer(fb_info); mxsfb_free_videomem(host); @@ -1564,7 +1591,14 @@ static void mxsfb_shutdown(struct platform_device *pdev) #ifdef CONFIG_PM static int mxsfb_runtime_suspend(struct device *dev) { - release_bus_freq(BUS_FREQ_HIGH); + struct mxsfb_info *host = dev_get_drvdata(dev); + + if (host->devdata->flags & MXSFB_FLAG_BUSFREQ) + release_bus_freq(BUS_FREQ_HIGH); + + if (host->devdata->flags & MXSFB_FLAG_PMQOS) + pm_qos_remove_request(&host->pm_qos_req); + dev_dbg(dev, "mxsfb busfreq high release.\n"); return 0; @@ -1572,7 +1606,15 @@ static int mxsfb_runtime_suspend(struct device *dev) static int mxsfb_runtime_resume(struct device *dev) { - request_bus_freq(BUS_FREQ_HIGH); + struct mxsfb_info *host = dev_get_drvdata(dev); + + if (host->devdata->flags & MXSFB_FLAG_BUSFREQ) + request_bus_freq(BUS_FREQ_HIGH); + + if (host->devdata->flags & MXSFB_FLAG_PMQOS) + pm_qos_add_request(&host->pm_qos_req, + PM_QOS_CPU_DMA_LATENCY, 0); + dev_dbg(dev, "mxsfb busfreq high request.\n"); return 0; |