mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-27 17:41:34 +00:00
Merge branch 'master' of git://git.denx.de/u-boot-sh
This commit is contained in:
commit
8297e648b8
5 changed files with 202 additions and 1 deletions
|
@ -6,6 +6,8 @@ config ARCH_RMOBILE_BOARD_STRING
|
||||||
|
|
||||||
config RCAR_GEN2
|
config RCAR_GEN2
|
||||||
bool "Renesas RCar Gen2"
|
bool "Renesas RCar Gen2"
|
||||||
|
select PHY
|
||||||
|
select PHY_RCAR_GEN2
|
||||||
|
|
||||||
config R8A7740
|
config R8A7740
|
||||||
bool "Renesas SoC R8A7740"
|
bool "Renesas SoC R8A7740"
|
||||||
|
|
|
@ -110,6 +110,14 @@ config STI_USB_PHY
|
||||||
used by USB2 and USB3 Host controllers available on
|
used by USB2 and USB3 Host controllers available on
|
||||||
STiH407 SoC families.
|
STiH407 SoC families.
|
||||||
|
|
||||||
|
config PHY_RCAR_GEN2
|
||||||
|
tristate "Renesas R-Car Gen2 USB PHY"
|
||||||
|
depends on PHY && RCAR_GEN2
|
||||||
|
help
|
||||||
|
Support for the Renesas R-Car Gen2 USB PHY. This driver operates the
|
||||||
|
PHY connected to USBHS module, PCI EHCI module and USB3.0 module and
|
||||||
|
allows configuring the module multiplexing.
|
||||||
|
|
||||||
config PHY_STM32_USBPHYC
|
config PHY_STM32_USBPHYC
|
||||||
tristate "STMicroelectronics STM32 SoC USB HS PHY driver"
|
tristate "STMicroelectronics STM32 SoC USB HS PHY driver"
|
||||||
depends on PHY && ARCH_STM32MP
|
depends on PHY && ARCH_STM32MP
|
||||||
|
|
|
@ -12,5 +12,6 @@ obj-$(CONFIG_BCM6368_USBH_PHY) += bcm6368-usbh-phy.o
|
||||||
obj-$(CONFIG_PHY_SANDBOX) += sandbox-phy.o
|
obj-$(CONFIG_PHY_SANDBOX) += sandbox-phy.o
|
||||||
obj-$(CONFIG_$(SPL_)PIPE3_PHY) += ti-pipe3-phy.o
|
obj-$(CONFIG_$(SPL_)PIPE3_PHY) += ti-pipe3-phy.o
|
||||||
obj-$(CONFIG_STI_USB_PHY) += sti_usb_phy.o
|
obj-$(CONFIG_STI_USB_PHY) += sti_usb_phy.o
|
||||||
|
obj-$(CONFIG_PHY_RCAR_GEN2) += phy-rcar-gen2.o
|
||||||
obj-$(CONFIG_PHY_STM32_USBPHYC) += phy-stm32-usbphyc.o
|
obj-$(CONFIG_PHY_STM32_USBPHYC) += phy-stm32-usbphyc.o
|
||||||
obj-$(CONFIG_MESON_GXL_USB_PHY) += meson-gxl-usb2.o meson-gxl-usb3.o
|
obj-$(CONFIG_MESON_GXL_USB_PHY) += meson-gxl-usb2.o meson-gxl-usb3.o
|
||||||
|
|
190
drivers/phy/phy-rcar-gen2.c
Normal file
190
drivers/phy/phy-rcar-gen2.c
Normal file
|
@ -0,0 +1,190 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
/*
|
||||||
|
* Renesas RCar Gen2 USB PHY driver
|
||||||
|
*
|
||||||
|
* Copyright (C) 2018 Marek Vasut <marek.vasut@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <clk.h>
|
||||||
|
#include <div64.h>
|
||||||
|
#include <dm.h>
|
||||||
|
#include <fdtdec.h>
|
||||||
|
#include <generic-phy.h>
|
||||||
|
#include <reset.h>
|
||||||
|
#include <syscon.h>
|
||||||
|
#include <usb.h>
|
||||||
|
#include <asm/io.h>
|
||||||
|
#include <linux/bitops.h>
|
||||||
|
#include <power/regulator.h>
|
||||||
|
|
||||||
|
#define USBHS_LPSTS 0x02
|
||||||
|
#define USBHS_UGCTRL 0x80
|
||||||
|
#define USBHS_UGCTRL2 0x84
|
||||||
|
#define USBHS_UGSTS 0x88 /* From technical update */
|
||||||
|
|
||||||
|
/* Low Power Status register (LPSTS) */
|
||||||
|
#define USBHS_LPSTS_SUSPM 0x4000
|
||||||
|
|
||||||
|
/* USB General control register (UGCTRL) */
|
||||||
|
#define USBHS_UGCTRL_CONNECT BIT(2)
|
||||||
|
#define USBHS_UGCTRL_PLLRESET BIT(0)
|
||||||
|
|
||||||
|
/* USB General control register 2 (UGCTRL2) */
|
||||||
|
#define USBHS_UGCTRL2_USB2SEL 0x80000000
|
||||||
|
#define USBHS_UGCTRL2_USB2SEL_PCI 0x00000000
|
||||||
|
#define USBHS_UGCTRL2_USB2SEL_USB30 0x80000000
|
||||||
|
#define USBHS_UGCTRL2_USB0SEL 0x00000030
|
||||||
|
#define USBHS_UGCTRL2_USB0SEL_PCI 0x00000010
|
||||||
|
#define USBHS_UGCTRL2_USB0SEL_HS_USB 0x00000030
|
||||||
|
|
||||||
|
/* USB General status register (UGSTS) */
|
||||||
|
#define USBHS_UGSTS_LOCK 0x00000100 /* From technical update */
|
||||||
|
|
||||||
|
#define PHYS_PER_CHANNEL 2
|
||||||
|
|
||||||
|
struct rcar_gen2_phy {
|
||||||
|
fdt_addr_t regs;
|
||||||
|
struct clk clk;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int rcar_gen2_phy_phy_init(struct phy *phy)
|
||||||
|
{
|
||||||
|
struct rcar_gen2_phy *priv = dev_get_priv(phy->dev);
|
||||||
|
u16 chan = phy->id & 0xffff;
|
||||||
|
u16 mode = (phy->id >> 16) & 0xffff;
|
||||||
|
u32 clrmask, setmask;
|
||||||
|
|
||||||
|
if (chan == 0) {
|
||||||
|
clrmask = USBHS_UGCTRL2_USB0SEL;
|
||||||
|
setmask = mode ? USBHS_UGCTRL2_USB0SEL_HS_USB :
|
||||||
|
USBHS_UGCTRL2_USB0SEL_PCI;
|
||||||
|
} else {
|
||||||
|
clrmask = USBHS_UGCTRL2_USB2SEL;
|
||||||
|
setmask = mode ? USBHS_UGCTRL2_USB2SEL_USB30 :
|
||||||
|
USBHS_UGCTRL2_USB2SEL_PCI;
|
||||||
|
}
|
||||||
|
clrsetbits_le32(priv->regs + USBHS_UGCTRL2, clrmask, setmask);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rcar_gen2_phy_phy_power_on(struct phy *phy)
|
||||||
|
{
|
||||||
|
struct rcar_gen2_phy *priv = dev_get_priv(phy->dev);
|
||||||
|
int i;
|
||||||
|
u32 value;
|
||||||
|
|
||||||
|
/* Power on USBHS PHY */
|
||||||
|
clrbits_le32(priv->regs + USBHS_UGCTRL, USBHS_UGCTRL_PLLRESET);
|
||||||
|
|
||||||
|
setbits_le16(priv->regs + USBHS_LPSTS, USBHS_LPSTS_SUSPM);
|
||||||
|
|
||||||
|
for (i = 0; i < 20; i++) {
|
||||||
|
value = readl(priv->regs + USBHS_UGSTS);
|
||||||
|
if ((value & USBHS_UGSTS_LOCK) == USBHS_UGSTS_LOCK) {
|
||||||
|
setbits_le32(priv->regs + USBHS_UGCTRL,
|
||||||
|
USBHS_UGCTRL_CONNECT);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
udelay(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -ETIMEDOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rcar_gen2_phy_phy_power_off(struct phy *phy)
|
||||||
|
{
|
||||||
|
struct rcar_gen2_phy *priv = dev_get_priv(phy->dev);
|
||||||
|
|
||||||
|
/* Power off USBHS PHY */
|
||||||
|
clrbits_le32(priv->regs + USBHS_UGCTRL, USBHS_UGCTRL_CONNECT);
|
||||||
|
|
||||||
|
clrbits_le16(priv->regs + USBHS_LPSTS, USBHS_LPSTS_SUSPM);
|
||||||
|
|
||||||
|
setbits_le32(priv->regs + USBHS_UGCTRL, USBHS_UGCTRL_PLLRESET);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rcar_gen2_phy_of_xlate(struct phy *phy,
|
||||||
|
struct ofnode_phandle_args *args)
|
||||||
|
{
|
||||||
|
if (args->args_count != 2) {
|
||||||
|
dev_err(phy->dev, "Invalid DT PHY argument count: %d\n",
|
||||||
|
args->args_count);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args->args[0] != 0 && args->args[0] != 2) {
|
||||||
|
dev_err(phy->dev, "Invalid DT PHY channel: %d\n",
|
||||||
|
args->args[0]);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args->args[1] != 0 && args->args[1] != 1) {
|
||||||
|
dev_err(phy->dev, "Invalid DT PHY mode: %d\n",
|
||||||
|
args->args[1]);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args->args_count)
|
||||||
|
phy->id = args->args[0] | (args->args[1] << 16);
|
||||||
|
else
|
||||||
|
phy->id = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct phy_ops rcar_gen2_phy_phy_ops = {
|
||||||
|
.init = rcar_gen2_phy_phy_init,
|
||||||
|
.power_on = rcar_gen2_phy_phy_power_on,
|
||||||
|
.power_off = rcar_gen2_phy_phy_power_off,
|
||||||
|
.of_xlate = rcar_gen2_phy_of_xlate,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int rcar_gen2_phy_probe(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct rcar_gen2_phy *priv = dev_get_priv(dev);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
priv->regs = dev_read_addr(dev);
|
||||||
|
if (priv->regs == FDT_ADDR_T_NONE)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* Enable clock */
|
||||||
|
ret = clk_get_by_index(dev, 0, &priv->clk);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = clk_enable(&priv->clk);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rcar_gen2_phy_remove(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct rcar_gen2_phy *priv = dev_get_priv(dev);
|
||||||
|
|
||||||
|
clk_disable(&priv->clk);
|
||||||
|
clk_free(&priv->clk);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct udevice_id rcar_gen2_phy_of_match[] = {
|
||||||
|
{ .compatible = "renesas,rcar-gen2-usb-phy", },
|
||||||
|
{ },
|
||||||
|
};
|
||||||
|
|
||||||
|
U_BOOT_DRIVER(rcar_gen2_phy) = {
|
||||||
|
.name = "rcar-gen2-phy",
|
||||||
|
.id = UCLASS_PHY,
|
||||||
|
.of_match = rcar_gen2_phy_of_match,
|
||||||
|
.ops = &rcar_gen2_phy_phy_ops,
|
||||||
|
.probe = rcar_gen2_phy_probe,
|
||||||
|
.remove = rcar_gen2_phy_remove,
|
||||||
|
.priv_auto_alloc_size = sizeof(struct rcar_gen2_phy),
|
||||||
|
};
|
|
@ -64,7 +64,7 @@ int generic_phy_get_by_index(struct udevice *dev, int index,
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* insert phy idx at first position into args array */
|
/* insert phy idx at first position into args array */
|
||||||
for (i = args.args_count; i > 1 ; i--)
|
for (i = args.args_count; i >= 1 ; i--)
|
||||||
args.args[i] = args.args[i - 1];
|
args.args[i] = args.args[i - 1];
|
||||||
|
|
||||||
args.args_count++;
|
args.args_count++;
|
||||||
|
|
Loading…
Add table
Reference in a new issue