mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 15:14:43 +00:00
phy: sun4i-usb: Use CLK and RESET support
Now clock and reset drivers are available for respective SoC's so use clk and reset ops on phy driver. Signed-off-by: Jagan Teki <jagan@amarulasolutions.com> Acked-by: Maxime Ripard <maxime.ripard@bootlin.com> Reviewed-by: Marek Vasut <marex@denx.de>
This commit is contained in:
parent
e236ff0a51
commit
089ffd0aed
1 changed files with 57 additions and 20 deletions
|
@ -11,10 +11,12 @@
|
|||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <clk.h>
|
||||
#include <dm.h>
|
||||
#include <dm/device.h>
|
||||
#include <generic-phy.h>
|
||||
#include <phy-sun4i-usb.h>
|
||||
#include <reset.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/clock.h>
|
||||
|
@ -80,6 +82,7 @@ struct sun4i_usb_phy_cfg {
|
|||
enum sun4i_usb_phy_type type;
|
||||
u32 disc_thresh;
|
||||
u8 phyctl_offset;
|
||||
bool dedicated_clocks;
|
||||
bool enable_pmu_unk1;
|
||||
bool phy0_dual_route;
|
||||
};
|
||||
|
@ -88,30 +91,21 @@ struct sun4i_usb_phy_info {
|
|||
const char *gpio_vbus;
|
||||
const char *gpio_vbus_det;
|
||||
const char *gpio_id_det;
|
||||
int rst_mask;
|
||||
} phy_info[] = {
|
||||
{
|
||||
.gpio_vbus = CONFIG_USB0_VBUS_PIN,
|
||||
.gpio_vbus_det = CONFIG_USB0_VBUS_DET,
|
||||
.gpio_id_det = CONFIG_USB0_ID_DET,
|
||||
.rst_mask = (CCM_USB_CTRL_PHY0_RST | CCM_USB_CTRL_PHY0_CLK),
|
||||
},
|
||||
{
|
||||
.gpio_vbus = CONFIG_USB1_VBUS_PIN,
|
||||
.gpio_vbus_det = NULL,
|
||||
.gpio_id_det = NULL,
|
||||
.rst_mask = (CCM_USB_CTRL_PHY1_RST | CCM_USB_CTRL_PHY1_CLK),
|
||||
},
|
||||
{
|
||||
.gpio_vbus = CONFIG_USB2_VBUS_PIN,
|
||||
.gpio_vbus_det = NULL,
|
||||
.gpio_id_det = NULL,
|
||||
#ifdef CONFIG_MACH_SUN8I_A83T
|
||||
.rst_mask = (CCM_USB_CTRL_HSIC_RST | CCM_USB_CTRL_HSIC_CLK |
|
||||
CCM_USB_CTRL_12M_CLK),
|
||||
#else
|
||||
.rst_mask = (CCM_USB_CTRL_PHY2_RST | CCM_USB_CTRL_PHY2_CLK),
|
||||
#endif
|
||||
},
|
||||
{
|
||||
.gpio_vbus = CONFIG_USB3_VBUS_PIN,
|
||||
|
@ -126,13 +120,13 @@ struct sun4i_usb_phy_plat {
|
|||
int gpio_vbus;
|
||||
int gpio_vbus_det;
|
||||
int gpio_id_det;
|
||||
int rst_mask;
|
||||
struct clk clocks;
|
||||
struct reset_ctl resets;
|
||||
int id;
|
||||
};
|
||||
|
||||
struct sun4i_usb_phy_data {
|
||||
void __iomem *base;
|
||||
struct sunxi_ccm_reg *ccm;
|
||||
const struct sun4i_usb_phy_cfg *cfg;
|
||||
struct sun4i_usb_phy_plat *usb_phy;
|
||||
};
|
||||
|
@ -266,8 +260,19 @@ static int sun4i_usb_phy_init(struct phy *phy)
|
|||
struct sun4i_usb_phy_data *data = dev_get_priv(phy->dev);
|
||||
struct sun4i_usb_phy_plat *usb_phy = &data->usb_phy[phy->id];
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
setbits_le32(&data->ccm->usb_clk_cfg, usb_phy->rst_mask);
|
||||
ret = clk_enable(&usb_phy->clocks);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to enable usb_%ldphy clock\n", phy->id);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = reset_deassert(&usb_phy->resets);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to deassert usb_%ldreset reset\n", phy->id);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (data->cfg->type == sun8i_a83t_phy) {
|
||||
if (phy->id == 0) {
|
||||
|
@ -308,6 +313,7 @@ static int sun4i_usb_phy_exit(struct phy *phy)
|
|||
{
|
||||
struct sun4i_usb_phy_data *data = dev_get_priv(phy->dev);
|
||||
struct sun4i_usb_phy_plat *usb_phy = &data->usb_phy[phy->id];
|
||||
int ret;
|
||||
|
||||
if (phy->id == 0) {
|
||||
if (data->cfg->type == sun8i_a83t_phy) {
|
||||
|
@ -320,7 +326,17 @@ static int sun4i_usb_phy_exit(struct phy *phy)
|
|||
|
||||
sun4i_usb_phy_passby(phy, false);
|
||||
|
||||
clrbits_le32(&data->ccm->usb_clk_cfg, usb_phy->rst_mask);
|
||||
ret = clk_disable(&usb_phy->clocks);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to disable usb_%ldphy clock\n", phy->id);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = reset_assert(&usb_phy->resets);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to assert usb_%ldreset reset\n", phy->id);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -407,10 +423,6 @@ static int sun4i_usb_phy_probe(struct udevice *dev)
|
|||
if (IS_ERR(data->base))
|
||||
return PTR_ERR(data->base);
|
||||
|
||||
data->ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
|
||||
if (IS_ERR(data->ccm))
|
||||
return PTR_ERR(data->ccm);
|
||||
|
||||
data->usb_phy = plat;
|
||||
for (i = 0; i < data->cfg->num_phys; i++) {
|
||||
struct sun4i_usb_phy_plat *phy = &plat[i];
|
||||
|
@ -448,6 +460,24 @@ static int sun4i_usb_phy_probe(struct udevice *dev)
|
|||
sunxi_gpio_set_pull(phy->gpio_id_det, SUNXI_GPIO_PULL_UP);
|
||||
}
|
||||
|
||||
if (data->cfg->dedicated_clocks)
|
||||
snprintf(name, sizeof(name), "usb%d_phy", i);
|
||||
else
|
||||
strlcpy(name, "usb_phy", sizeof(name));
|
||||
|
||||
ret = clk_get_by_name(dev, name, &phy->clocks);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to get usb%d_phy clock phandle\n", i);
|
||||
return ret;
|
||||
}
|
||||
|
||||
snprintf(name, sizeof(name), "usb%d_reset", i);
|
||||
ret = reset_get_by_name(dev, name, &phy->resets);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to get usb%d_reset reset phandle\n", i);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (i || data->cfg->phy0_dual_route) {
|
||||
snprintf(name, sizeof(name), "pmu%d", i);
|
||||
phy->pmu = (void __iomem *)devfdt_get_addr_name(dev, name);
|
||||
|
@ -456,9 +486,6 @@ static int sun4i_usb_phy_probe(struct udevice *dev)
|
|||
}
|
||||
|
||||
phy->id = i;
|
||||
phy->rst_mask = info->rst_mask;
|
||||
if ((data->cfg->type == sun8i_h3_phy) && (phy->id == 3))
|
||||
phy->rst_mask = (BIT(3) | BIT(11));
|
||||
};
|
||||
|
||||
debug("Allwinner Sun4I USB PHY driver loaded\n");
|
||||
|
@ -470,6 +497,7 @@ static const struct sun4i_usb_phy_cfg sun4i_a10_cfg = {
|
|||
.type = sun4i_a10_phy,
|
||||
.disc_thresh = 3,
|
||||
.phyctl_offset = REG_PHYCTL_A10,
|
||||
.dedicated_clocks = false,
|
||||
.enable_pmu_unk1 = false,
|
||||
};
|
||||
|
||||
|
@ -478,6 +506,7 @@ static const struct sun4i_usb_phy_cfg sun5i_a13_cfg = {
|
|||
.type = sun4i_a10_phy,
|
||||
.disc_thresh = 2,
|
||||
.phyctl_offset = REG_PHYCTL_A10,
|
||||
.dedicated_clocks = false,
|
||||
.enable_pmu_unk1 = false,
|
||||
};
|
||||
|
||||
|
@ -486,6 +515,7 @@ static const struct sun4i_usb_phy_cfg sun6i_a31_cfg = {
|
|||
.type = sun6i_a31_phy,
|
||||
.disc_thresh = 3,
|
||||
.phyctl_offset = REG_PHYCTL_A10,
|
||||
.dedicated_clocks = true,
|
||||
.enable_pmu_unk1 = false,
|
||||
};
|
||||
|
||||
|
@ -494,6 +524,7 @@ static const struct sun4i_usb_phy_cfg sun7i_a20_cfg = {
|
|||
.type = sun4i_a10_phy,
|
||||
.disc_thresh = 2,
|
||||
.phyctl_offset = REG_PHYCTL_A10,
|
||||
.dedicated_clocks = false,
|
||||
.enable_pmu_unk1 = false,
|
||||
};
|
||||
|
||||
|
@ -502,6 +533,7 @@ static const struct sun4i_usb_phy_cfg sun8i_a23_cfg = {
|
|||
.type = sun4i_a10_phy,
|
||||
.disc_thresh = 3,
|
||||
.phyctl_offset = REG_PHYCTL_A10,
|
||||
.dedicated_clocks = true,
|
||||
.enable_pmu_unk1 = false,
|
||||
};
|
||||
|
||||
|
@ -510,6 +542,7 @@ static const struct sun4i_usb_phy_cfg sun8i_a33_cfg = {
|
|||
.type = sun8i_a33_phy,
|
||||
.disc_thresh = 3,
|
||||
.phyctl_offset = REG_PHYCTL_A33,
|
||||
.dedicated_clocks = true,
|
||||
.enable_pmu_unk1 = false,
|
||||
};
|
||||
|
||||
|
@ -517,6 +550,7 @@ static const struct sun4i_usb_phy_cfg sun8i_a83t_cfg = {
|
|||
.num_phys = 3,
|
||||
.type = sun8i_a83t_phy,
|
||||
.phyctl_offset = REG_PHYCTL_A33,
|
||||
.dedicated_clocks = true,
|
||||
};
|
||||
|
||||
static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = {
|
||||
|
@ -524,6 +558,7 @@ static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = {
|
|||
.type = sun8i_h3_phy,
|
||||
.disc_thresh = 3,
|
||||
.phyctl_offset = REG_PHYCTL_A33,
|
||||
.dedicated_clocks = true,
|
||||
.enable_pmu_unk1 = true,
|
||||
.phy0_dual_route = true,
|
||||
};
|
||||
|
@ -533,6 +568,7 @@ static const struct sun4i_usb_phy_cfg sun8i_v3s_cfg = {
|
|||
.type = sun8i_v3s_phy,
|
||||
.disc_thresh = 3,
|
||||
.phyctl_offset = REG_PHYCTL_A33,
|
||||
.dedicated_clocks = true,
|
||||
.enable_pmu_unk1 = true,
|
||||
.phy0_dual_route = true,
|
||||
};
|
||||
|
@ -542,6 +578,7 @@ static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = {
|
|||
.type = sun50i_a64_phy,
|
||||
.disc_thresh = 3,
|
||||
.phyctl_offset = REG_PHYCTL_A33,
|
||||
.dedicated_clocks = true,
|
||||
.enable_pmu_unk1 = true,
|
||||
.phy0_dual_route = true,
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue