usb: chipidea: imx: add imx7ulp support

In this commit, we add CI_HDRC_PMQOS to avoid system entering idle,
at imx7ulp, if the system enters idle, the DMA will stop, so the USB
transfer can't work at this case.

Signed-off-by: Peter Chen <peter.chen@nxp.com>
This commit is contained in:
Peter Chen 2019-04-28 10:35:31 +08:00
parent 8ea5b2abd0
commit d1609c312d
3 changed files with 32 additions and 1 deletions

View File

@ -13,6 +13,7 @@
#include <linux/usb/of.h> #include <linux/usb/of.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/pinctrl/consumer.h> #include <linux/pinctrl/consumer.h>
#include <linux/pm_qos.h>
#include "ci.h" #include "ci.h"
#include "ci_hdrc_imx.h" #include "ci_hdrc_imx.h"
@ -63,6 +64,11 @@ static const struct ci_hdrc_imx_platform_flag imx7d_usb_data = {
.flags = CI_HDRC_SUPPORTS_RUNTIME_PM, .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_PMQOS,
};
static const struct of_device_id ci_hdrc_imx_dt_ids[] = { static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
{ .compatible = "fsl,imx23-usb", .data = &imx23_usb_data}, { .compatible = "fsl,imx23-usb", .data = &imx23_usb_data},
{ .compatible = "fsl,imx28-usb", .data = &imx28_usb_data}, { .compatible = "fsl,imx28-usb", .data = &imx28_usb_data},
@ -72,6 +78,7 @@ static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
{ .compatible = "fsl,imx6sx-usb", .data = &imx6sx_usb_data}, { .compatible = "fsl,imx6sx-usb", .data = &imx6sx_usb_data},
{ .compatible = "fsl,imx6ul-usb", .data = &imx6ul_usb_data}, { .compatible = "fsl,imx6ul-usb", .data = &imx6ul_usb_data},
{ .compatible = "fsl,imx7d-usb", .data = &imx7d_usb_data}, { .compatible = "fsl,imx7d-usb", .data = &imx7d_usb_data},
{ .compatible = "fsl,imx7ulp-usb", .data = &imx7ulp_usb_data},
{ /* sentinel */ } { /* sentinel */ }
}; };
MODULE_DEVICE_TABLE(of, ci_hdrc_imx_dt_ids); MODULE_DEVICE_TABLE(of, ci_hdrc_imx_dt_ids);
@ -93,6 +100,8 @@ struct ci_hdrc_imx_data {
struct clk *clk_ahb; struct clk *clk_ahb;
struct clk *clk_per; struct clk *clk_per;
/* --------------------------------- */ /* --------------------------------- */
struct pm_qos_request pm_qos_req;
const struct ci_hdrc_imx_platform_flag *plat_data;
}; };
/* Common functions shared by usbmisc drivers */ /* Common functions shared by usbmisc drivers */
@ -309,6 +318,8 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
if (!data) if (!data)
return -ENOMEM; return -ENOMEM;
data->plat_data = imx_platform_flag;
pdata.flags |= imx_platform_flag->flags;
platform_set_drvdata(pdev, data); platform_set_drvdata(pdev, data);
data->usbmisc_data = usbmisc_get_init_data(dev); data->usbmisc_data = usbmisc_get_init_data(dev);
if (IS_ERR(data->usbmisc_data)) if (IS_ERR(data->usbmisc_data))
@ -369,6 +380,11 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
} }
} }
} }
if (pdata.flags & CI_HDRC_PMQOS)
pm_qos_add_request(&data->pm_qos_req,
PM_QOS_CPU_DMA_LATENCY, 0);
ret = imx_get_clks(dev); ret = imx_get_clks(dev);
if (ret) if (ret)
goto disable_hsic_regulator; goto disable_hsic_regulator;
@ -396,7 +412,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
usb_phy_init(pdata.usb_phy); usb_phy_init(pdata.usb_phy);
} }
pdata.flags |= imx_platform_flag->flags;
if (pdata.flags & CI_HDRC_SUPPORTS_RUNTIME_PM) if (pdata.flags & CI_HDRC_SUPPORTS_RUNTIME_PM)
data->supports_runtime_pm = true; data->supports_runtime_pm = true;
@ -439,6 +454,8 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
disable_hsic_regulator: disable_hsic_regulator:
if (data->hsic_pad_regulator) if (data->hsic_pad_regulator)
ret = regulator_disable(data->hsic_pad_regulator); ret = regulator_disable(data->hsic_pad_regulator);
if (pdata.flags & CI_HDRC_PMQOS)
pm_qos_remove_request(&data->pm_qos_req);
return ret; return ret;
} }
@ -455,6 +472,8 @@ static int ci_hdrc_imx_remove(struct platform_device *pdev)
if (data->override_phy_control) if (data->override_phy_control)
usb_phy_shutdown(data->phy); usb_phy_shutdown(data->phy);
imx_disable_unprepare_clks(&pdev->dev); imx_disable_unprepare_clks(&pdev->dev);
if (data->plat_data->flags & CI_HDRC_PMQOS)
pm_qos_remove_request(&data->pm_qos_req);
if (data->hsic_pad_regulator) if (data->hsic_pad_regulator)
regulator_disable(data->hsic_pad_regulator); regulator_disable(data->hsic_pad_regulator);
@ -480,6 +499,9 @@ static int __maybe_unused imx_controller_suspend(struct device *dev)
} }
imx_disable_unprepare_clks(dev); imx_disable_unprepare_clks(dev);
if (data->plat_data->flags & CI_HDRC_PMQOS)
pm_qos_remove_request(&data->pm_qos_req);
data->in_lpm = true; data->in_lpm = true;
return 0; return 0;
@ -497,6 +519,10 @@ static int __maybe_unused imx_controller_resume(struct device *dev)
return 0; return 0;
} }
if (data->plat_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); ret = imx_prepare_enable_clks(dev);
if (ret) if (ret)
return ret; return ret;

View File

@ -763,6 +763,10 @@ static const struct of_device_id usbmisc_imx_dt_ids[] = {
.compatible = "fsl,imx7d-usbmisc", .compatible = "fsl,imx7d-usbmisc",
.data = &imx7d_usbmisc_ops, .data = &imx7d_usbmisc_ops,
}, },
{
.compatible = "fsl,imx7ulp-usbmisc",
.data = &imx7d_usbmisc_ops,
},
{ /* sentinel */ } { /* sentinel */ }
}; };
MODULE_DEVICE_TABLE(of, usbmisc_imx_dt_ids); MODULE_DEVICE_TABLE(of, usbmisc_imx_dt_ids);

View File

@ -61,6 +61,7 @@ struct ci_hdrc_platform_data {
#define CI_HDRC_OVERRIDE_PHY_CONTROL BIT(12) /* Glue layer manages phy */ #define CI_HDRC_OVERRIDE_PHY_CONTROL BIT(12) /* Glue layer manages phy */
#define CI_HDRC_REQUIRES_ALIGNED_DMA BIT(13) #define CI_HDRC_REQUIRES_ALIGNED_DMA BIT(13)
#define CI_HDRC_IMX_IS_HSIC BIT(14) #define CI_HDRC_IMX_IS_HSIC BIT(14)
#define CI_HDRC_PMQOS BIT(15)
enum usb_dr_mode dr_mode; enum usb_dr_mode dr_mode;
#define CI_HDRC_CONTROLLER_RESET_EVENT 0 #define CI_HDRC_CONTROLLER_RESET_EVENT 0
#define CI_HDRC_CONTROLLER_STOPPED_EVENT 1 #define CI_HDRC_CONTROLLER_STOPPED_EVENT 1