MLK-13570-5 usb: chipidea: imx: introduce pmqos for imx7ulp

At imx7ulp, if the system enters idle, it will close some clocks and affect
USB transfer. In order to avoid it, we request pmqos to avoid system
entering idle when the USB is in use.

Signed-off-by: Peter Chen <peter.chen@nxp.com>
This commit is contained in:
Peter Chen
2016-12-06 10:06:31 +08:00
committed by Anson Huang
parent ee8b2bb518
commit a125eea07c
2 changed files with 30 additions and 2 deletions

View File

@ -24,6 +24,7 @@
#include <linux/mfd/syscon.h>
#include <linux/regulator/consumer.h>
#include <linux/busfreq-imx.h>
#include <linux/pm_qos.h>
#include "ci.h"
#include "ci_hdrc_imx.h"
@ -79,6 +80,12 @@ static const struct ci_hdrc_imx_platform_flag imx7d_usb_data = {
.flags = CI_HDRC_SUPPORTS_RUNTIME_PM,
};
static const struct ci_hdrc_imx_platform_flag imx7ulp_usb_data = {
.flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
CI_HDRC_IMX_EHCI_QUIRK |
CI_HDRC_PMQOS,
};
static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
{ .compatible = "fsl,imx23-usb", .data = &imx23_usb_data},
{ .compatible = "fsl,imx28-usb", .data = &imx28_usb_data},
@ -88,6 +95,7 @@ static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
{ .compatible = "fsl,imx6sx-usb", .data = &imx6sx_usb_data},
{ .compatible = "fsl,imx6ul-usb", .data = &imx6ul_usb_data},
{ .compatible = "fsl,imx7d-usb", .data = &imx7d_usb_data},
{ .compatible = "fsl,imx7ulp-usb", .data = &imx7ulp_usb_data},
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, ci_hdrc_imx_dt_ids);
@ -112,6 +120,7 @@ struct ci_hdrc_imx_data {
struct clk *clk_ahb;
struct clk *clk_per;
/* --------------------------------- */
struct pm_qos_request pm_qos_req;
};
static char *imx_usb_charger_supplied_to[] = {
@ -476,6 +485,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, data);
data->data = imx_platform_flag;
pdata.flags |= imx_platform_flag->flags;
data->usbmisc_data = usbmisc_get_init_data(&pdev->dev);
if (IS_ERR(data->usbmisc_data))
return PTR_ERR(data->usbmisc_data);
@ -514,6 +524,10 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
return ret;
request_bus_freq(BUS_FREQ_HIGH);
if (pdata.flags & CI_HDRC_PMQOS)
pm_qos_add_request(&data->pm_qos_req,
PM_QOS_CPU_DMA_LATENCY, 0);
ret = imx_prepare_enable_clks(&pdev->dev);
if (ret)
goto err_bus_freq;
@ -528,7 +542,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
}
pdata.usb_phy = data->phy;
pdata.flags |= imx_platform_flag->flags;
if (pdata.flags & CI_HDRC_SUPPORTS_RUNTIME_PM)
data->supports_runtime_pm = true;
@ -638,6 +651,8 @@ disable_hsic_regulator:
err_clk:
imx_disable_unprepare_clks(&pdev->dev);
err_bus_freq:
if (pdata.flags & CI_HDRC_PMQOS)
pm_qos_remove_request(&data->pm_qos_req);
release_bus_freq(BUS_FREQ_HIGH);
return ret;
}
@ -653,6 +668,8 @@ static int ci_hdrc_imx_remove(struct platform_device *pdev)
}
ci_hdrc_remove_device(data->ci_pdev);
imx_disable_unprepare_clks(&pdev->dev);
if (data->data->flags & CI_HDRC_PMQOS)
pm_qos_remove_request(&data->pm_qos_req);
release_bus_freq(BUS_FREQ_HIGH);
if (data->hsic_pad_regulator)
regulator_disable(data->hsic_pad_regulator);
@ -683,6 +700,8 @@ static int imx_controller_suspend(struct device *dev)
}
imx_disable_unprepare_clks(dev);
if (data->data->flags & CI_HDRC_PMQOS)
pm_qos_remove_request(&data->pm_qos_req);
release_bus_freq(BUS_FREQ_HIGH);
data->in_lpm = true;
@ -702,9 +721,12 @@ static int imx_controller_resume(struct device *dev)
}
request_bus_freq(BUS_FREQ_HIGH);
if (data->data->flags & CI_HDRC_PMQOS)
pm_qos_add_request(&data->pm_qos_req,
PM_QOS_CPU_DMA_LATENCY, 0);
ret = imx_prepare_enable_clks(dev);
if (ret)
return ret;
goto err_bus_freq;
data->in_lpm = false;
@ -736,6 +758,10 @@ hsic_set_clk_fail:
imx_usbmisc_set_wakeup(data->usbmisc_data, true);
clk_disable:
imx_disable_unprepare_clks(dev);
err_bus_freq:
if (data->data->flags & CI_HDRC_PMQOS)
pm_qos_remove_request(&data->pm_qos_req);
release_bus_freq(BUS_FREQ_HIGH);
return ret;
}

View File

@ -59,6 +59,8 @@ struct ci_hdrc_platform_data {
#define CI_HDRC_OVERRIDE_RX_BURST BIT(11)
#define CI_HDRC_IMX_EHCI_QUIRK BIT(12)
#define CI_HDRC_IMX_IS_HSIC BIT(13)
/* need request pmqos during low power */
#define CI_HDRC_PMQOS BIT(14)
enum usb_dr_mode dr_mode;
#define CI_HDRC_CONTROLLER_RESET_EVENT 0
#define CI_HDRC_CONTROLLER_STOPPED_EVENT 1