aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Griffin <peter.griffin@linaro.org>2014-07-01 12:01:34 +0100
committerPeter Griffin <peter.griffin@linaro.org>2014-07-01 12:01:34 +0100
commitf7661e2e8bc6a95ffd00084ae0db1b10fba3553d (patch)
treee40e63c72eaa061a4dfdfdf2e34811ceb6ea892d
parentaea64967e7870fb00fb1d354941198caa005dce3 (diff)
Got USB working, but need new PHY drivers!usb-picophy-usb-phy
-rw-r--r--Documentation/devicetree/bindings/mmc/sdhci-st.txt.reset33
-rw-r--r--Documentation/devicetree/bindings/usb/phy-st-usb3.txt36
-rw-r--r--Documentation/devicetree/bindings/usb/phy-stih407-usb2.txt23
-rw-r--r--arch/arm/boot/dts/stih407-b2120.dts4
-rw-r--r--arch/arm/boot/dts/stih407.dtsi52
-rw-r--r--arch/arm/configs/sti_defconfig154
-rw-r--r--arch/arm/mach-sti/Kconfig11
-rw-r--r--drivers/reset/sti/reset-stih407.c2
-rw-r--r--drivers/reset/sti/reset-syscfg.c23
-rw-r--r--drivers/reset/sti/reset-syscfg.h4
-rw-r--r--drivers/usb/dwc3/core.c24
-rw-r--r--drivers/usb/dwc3/dwc3-st.c28
-rw-r--r--drivers/usb/phy/Kconfig2
-rw-r--r--drivers/usb/phy/Makefile2
-rw-r--r--drivers/usb/phy/phy-st-usb3.c317
-rw-r--r--drivers/usb/phy/phy-stih407-usb2.c3
16 files changed, 713 insertions, 5 deletions
diff --git a/Documentation/devicetree/bindings/mmc/sdhci-st.txt.reset b/Documentation/devicetree/bindings/mmc/sdhci-st.txt.reset
new file mode 100644
index 000000000000..1fe852353e06
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/sdhci-st.txt.reset
@@ -0,0 +1,33 @@
+* STMicroelectronics sdhci-st MMC/SD controller
+
+This file documents the differences between the core properties in
+Documentation/devicetree/bindings/mmc/mmc.txt and the properties
+used by the sdhci-st driver.
+
+Required properties:
+- compatible : Must be "st,sdhci"
+- clock-names : Should be "mmc"
+ See: Documentation/devicetree/bindings/resource-names.txt
+- clocks : Phandle of the clock used by the sdhci controler
+ See: Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Optional properties:
+- reset: Phandle of the reset provider plus reset specifier
+ See: Documentation/devicetree/bindings/reset/reset.txt
+- non-removable: non-removable slot
+ See: Documentation/devicetree/bindings/mmc/mmc.txt
+
+Example:
+
+mmc0: sdhci@fe81e000 {
+ compatible = "st,sdhci";
+ status = "disabled";
+ reg = <0xfe81e000 0x1000>;
+ interrupts = <GIC_SPI 127 IRQ_TYPE_NONE>;
+ interrupt-names = "mmcirq";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mmc0>;
+ clock-names = "mmc";
+ clocks = <&clk_s_a1_ls 1>;
+ resets = <&softreset STIH416_MMC_SOFTRESET>
+};
diff --git a/Documentation/devicetree/bindings/usb/phy-st-usb3.txt b/Documentation/devicetree/bindings/usb/phy-st-usb3.txt
new file mode 100644
index 000000000000..341bb630be2f
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/phy-st-usb3.txt
@@ -0,0 +1,36 @@
+ST USB-PHY controllers
+
+The DWC3 port#2 can be used with a MiPHY2 to manage USB3 devices.
+
+This is to document the DT parameters to be passed from the blob in that case.
+
+Required properties:
+
+MiPHY2:
+- compatible : should be "st,stih407-usb3phy"
+- reg : base physical address of the phy registers and length of memory mapped
+ region.
+ It must have: "usb3-uport", "pipew";
+ So MiPHY and pipe wrapper.
+- st,syscfg: sysconfig register to manage the device.
+- resets: to reset the device.
+
+Optional property:
+- st,auto-calibration: boolean property to advice system to perform
+ autocalibration on device disconnection.
+ This will allow to setup the proper callback in the
+ phy-st-usb3.c source. To setup only for those socs that
+ support autocalibration.
+
+Example:
+
+/* miPHY2 */
+usb3_phy: usb3_phy@0 {
+ compatible = "st,stih407-usb3phy";
+ #phy-cells = <0>;
+ resets = <&softreset STIH407_USB3_MIPHY2_SOFTRESET>;
+ reg = <0x08f90000 0xff>, <0x08f95000 0xff>;
+ reg-names = "usb3-uport", "pipew";
+ st,syscfg = <&syscfg_core>;
+ st,auto-calibration;
+};
diff --git a/Documentation/devicetree/bindings/usb/phy-stih407-usb2.txt b/Documentation/devicetree/bindings/usb/phy-stih407-usb2.txt
new file mode 100644
index 000000000000..fcb207bb7db9
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/phy-stih407-usb2.txt
@@ -0,0 +1,23 @@
+ST STiH407 USB-PHY controller
+
+On STiH407, we have to use the DWC3 port#2 with a picoPHY to manage USB2
+devices.
+
+This is to document the DT parameters to be passed from the blob in that case.
+
+Required properties:
+
+picoPHY:
+- compatible : should be "st,stih407-usb2phy"
+- st,syscfg: sysconfig register to manage phy parameter at driver level.
+- resets: to reset the device.
+
+Example:
+
+/* picoPHY */
+usb2_phy: usb2phy@0 {
+ compatible = "st,stih407-usb2phy";
+ #phy-cells = <0>;
+ st,syscfg = <&syscfg_core>;
+ resets = <&softreset STIH407_PICOPHY_SOFTRESET>;
+};
diff --git a/arch/arm/boot/dts/stih407-b2120.dts b/arch/arm/boot/dts/stih407-b2120.dts
index fe69f92e5f82..181e9785df8a 100644
--- a/arch/arm/boot/dts/stih407-b2120.dts
+++ b/arch/arm/boot/dts/stih407-b2120.dts
@@ -74,5 +74,9 @@
st,i2c-min-scl-pulse-width-us = <0>;
st,i2c-min-sda-pulse-width-us = <5>;
};
+
+ st_dwc3: dwc3@8f94000 {
+ status = "okay";
+ };
};
};
diff --git a/arch/arm/boot/dts/stih407.dtsi b/arch/arm/boot/dts/stih407.dtsi
index 4f9024f19866..3cff212a8f97 100644
--- a/arch/arm/boot/dts/stih407.dtsi
+++ b/arch/arm/boot/dts/stih407.dtsi
@@ -8,6 +8,7 @@
*/
#include "stih407-clock.dtsi"
#include "stih407-pinctrl.dtsi"
+#include <dt-bindings/reset-controller/stih407-resets.h>
/ {
#address-cells = <1>;
#size-cells = <1>;
@@ -63,6 +64,16 @@
ranges;
compatible = "simple-bus";
+ powerdown: powerdown-controller {
+ #reset-cells = <1>;
+ compatible = "st,stih407-powerdown";
+ };
+
+ softreset: softreset-controller {
+ #reset-cells = <1>;
+ compatible = "st,stih407-softreset";
+ };
+
syscfg_sbc: sbc-syscfg@9620000 {
compatible = "st,stih407-sbc-syscfg", "syscon";
reg = <0x9620000 0x1000>;
@@ -259,5 +270,46 @@
status = "disabled";
};
+
+ /* picoPHY */
+ usb2_phy: usb2phy@0 {
+ compatible = "st,stih407-usb2phy";
+ #phy-cells = <0>;
+ st,syscfg = <&syscfg_core>;
+ resets = <&softreset STIH407_PICOPHY_SOFTRESET>;
+ };
+
+ /* miPHY2 */
+ usb3_phy: usb3_phy@0 {
+ compatible = "st,sti-usb3phy";
+ #phy-cells = <0>;
+ resets = <&softreset STIH407_USB3_MIPHY2_SOFTRESET>;
+ reg = <0x08f90000 0xff>, <0x08f95000 0xff>;
+ reg-names = "usb3-uport", "pipew";
+ st,syscfg = <&syscfg_core>;
+ st,auto-calibration;
+ };
+
+ st_dwc3: dwc3@8f94000 {
+ status = "disabled";
+ compatible = "st,stih407-dwc3";
+ reg = <0x08f94000 0x1000>, <0x110 0x4>;
+ reg-names = "reg-glue", "syscfg-reg";
+ st,syscfg = <&syscfg_core>;
+ resets = <&powerdown STIH407_USB3_POWERDOWN>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb3>;
+ ranges;
+
+ dwc3: dwc3@9900000 {
+ compatible = "synopsys,dwc3";
+ reg = <0x09900000 0x100000>;
+ interrupts = <GIC_SPI 155 IRQ_TYPE_NONE>;
+
+ usb-phy = <&usb2_phy>, <&usb3_phy>;
+ };
+ };
};
};
diff --git a/arch/arm/configs/sti_defconfig b/arch/arm/configs/sti_defconfig
new file mode 100644
index 000000000000..61feda50507f
--- /dev/null
+++ b/arch/arm/configs/sti_defconfig
@@ -0,0 +1,154 @@
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CPUSETS=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_MEMCG=y
+CONFIG_MEMCG_SWAP=y
+CONFIG_MEMCG_KMEM=y
+CONFIG_PERF_EVENTS=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_ARCH_STI=y
+CONFIG_PCI=y
+CONFIG_PCI_MSI=y
+CONFIG_PCI_ST=y
+CONFIG_SMP=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_HIGHPTE=y
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_CPU_FREQ=y
+CONFIG_GENERIC_CPUFREQ_CPU0=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+CONFIG_PM_OPP=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_SYN_COOKIES=y
+CONFIG_IPV6=y
+CONFIG_NETFILTER=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_NF_NAT_IPV4=y
+CONFIG_IP_NF_RAW=y
+CONFIG_NF_CONNTRACK_IPV6=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_RAW=y
+CONFIG_NF_NAT_IPV6=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_EEPROM_AT24=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_ATA=y
+CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_SATA_AHCI_ST=y
+CONFIG_NETDEVICES=y
+CONFIG_VETH=y
+CONFIG_NET_CALXEDA_XGMAC=y
+CONFIG_SMSC911X=y
+CONFIG_STMMAC_ETH=y
+CONFIG_ISVE_ST=m
+CONFIG_ICPLUS_PHY=y
+CONFIG_FIXED_PHY=y
+CONFIG_RTL8366_SMI=y
+CONFIG_RTL8366_SMI_DEBUG_FS=y
+CONFIG_RTL8367_PHY=y
+CONFIG_INPUT_MATRIXKMAP=y
+CONFIG_KEYBOARD_ST_KEYSCAN=y
+CONFIG_SERIAL_ST_ASC=y
+CONFIG_SERIAL_ST_ASC_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_ST=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_ST=y
+CONFIG_SPI=y
+CONFIG_SPI_ST=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_ST=y
+# CONFIG_HWMON is not set
+CONFIG_THERMAL=y
+CONFIG_ST_THERMAL=y
+CONFIG_ST_THERMAL_SYSCFG=y
+CONFIG_ST_THERMAL_MEMMAP=y
+CONFIG_WATCHDOG=y
+CONFIG_ST_LPC_WATCHDOG=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_ST_FLASHSS=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_RC_SUPPORT=y
+CONFIG_LIRC=y
+CONFIG_RC_DEVICES=y
+CONFIG_RC_ST=y
+CONFIG_DVB_TUNER_DIB0070=y
+CONFIG_DVB_TUNER_DIB0090=y
+CONFIG_FB=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_SIMPLE=y
+CONFIG_USB=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_HCD_ST=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_PHY=y
+CONFIG_PHY_STIH407_USB=y
+CONFIG_ST_USB3_MIPHY=y
+CONFIG_PHY_STI8416_USB2=y
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_ST=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_MALI400=y
+CONFIG_COMMON_CLK_DEBUG=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_ST_REMOTEPROC=m
+CONFIG_PWM=y
+CONFIG_PWM_ST=y
+CONFIG_PHY_STIH41X_USB=y
+CONFIG_PHY_MIPHY365X=y
+CONFIG_PHY_STID127_USB=y
+CONFIG_PHY_MIPHY28LP=y
+CONFIG_PHY_STI8416_USB=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT4_FS=y
+CONFIG_FUSE_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_NTFS_FS=y
+CONFIG_TMPFS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_DEBUG_SECTION_MISMATCH=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_FTRACE is not set
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_SEQIV=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+CONFIG_XZ_DEC=y
diff --git a/arch/arm/mach-sti/Kconfig b/arch/arm/mach-sti/Kconfig
index 7e33e9d2c42e..7bb7eaad1a25 100644
--- a/arch/arm/mach-sti/Kconfig
+++ b/arch/arm/mach-sti/Kconfig
@@ -42,4 +42,15 @@ config SOC_STIH416
and other digital audio/video applications using Flattened Device
Trees.
+config SOC_STIH407
+ bool "STiH407 STMicroelectronics Consumer Electronics family"
+ default y
+ select STIH407_RESET
+ select USB_ARCH_HAS_XHCI
+ help
+ This enables support for STMicroelectronics Digital Consumer
+ Electronics family StiH407 parts, targetted at set-top-box
+ and other digital audio/video applications using Flattened Device
+ Trees.
+
endif
diff --git a/drivers/reset/sti/reset-stih407.c b/drivers/reset/sti/reset-stih407.c
index 4a57742f4db6..214c3d87a393 100644
--- a/drivers/reset/sti/reset-stih407.c
+++ b/drivers/reset/sti/reset-stih407.c
@@ -104,6 +104,8 @@ static struct platform_driver stih407_reset_driver = {
static int __init stih407_reset_init(void)
{
+
+ printk("\n%s:%d\n",__FUNCTION__, __LINE__);
return platform_driver_register(&stih407_reset_driver);
}
diff --git a/drivers/reset/sti/reset-syscfg.c b/drivers/reset/sti/reset-syscfg.c
index a145cc066d4a..b05af15f17db 100644
--- a/drivers/reset/sti/reset-syscfg.c
+++ b/drivers/reset/sti/reset-syscfg.c
@@ -109,11 +109,34 @@ static int syscfg_reset_dev(struct reset_controller_dev *rcdev,
return syscfg_reset_deassert(rcdev, idx);
}
+#if 0
+static int syscfg_reset_is_asserted(struct reset_controller_dev *rcdev,
+ unsigned long idx)
+{
+ struct syscfg_reset_controller *rst = to_syscfg_reset_controller(rcdev);
+ const struct syscfg_reset_channel *ch;
+ u32 ret_val = 0;
+ int err;
+ if (idx >= rcdev->nr_resets)
+ return -EINVAL;
+
+ ch = &rst->channels[idx];
+ if (ch->ack)
+ err = regmap_field_read(ch->ack, &ret_val);
+ else
+ err = regmap_field_read(ch->reset, &ret_val);
+ if (err)
+ return err;
+
+ return rst->active_low ? !ret_val : !!ret_val;
+}
+#endif
static struct reset_control_ops syscfg_reset_ops = {
.reset = syscfg_reset_dev,
.assert = syscfg_reset_assert,
.deassert = syscfg_reset_deassert,
+// .is_asserted = syscfg_reset_is_asserted,
};
static int syscfg_reset_controller_register(struct device *dev,
diff --git a/drivers/reset/sti/reset-syscfg.h b/drivers/reset/sti/reset-syscfg.h
index 2cc2283bac40..e98e76462cc8 100644
--- a/drivers/reset/sti/reset-syscfg.h
+++ b/drivers/reset/sti/reset-syscfg.h
@@ -34,6 +34,10 @@ struct syscfg_reset_channel_data {
.reset = REG_FIELD(_rr, _rb, _rb), \
.ack = REG_FIELD(_ar, _ab, _ab), }
+#define SYSCFG_SRST(_c, _rr, _rb) \
+ { .compatible = _c, \
+ .reset = REG_FIELD(_rr, _rb, _rb), }
+
#define _SYSCFG_RST_CH_NO_ACK(_c, _rr, _rb) \
{ .compatible = _c, \
.reset = REG_FIELD(_rr, _rb, _rb), }
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index eb69eb9f06c8..03dfd19629fd 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -505,6 +505,7 @@ static int dwc3_core_get_phy(struct dwc3 *dwc)
if (ret == -ENXIO || ret == -ENODEV) {
dwc->usb2_phy = NULL;
} else if (ret == -EPROBE_DEFER) {
+ printk("%s:%d()+\n",__FUNCTION__, __LINE__);
return ret;
} else {
dev_err(dev, "no usb2 phy configured\n");
@@ -517,6 +518,7 @@ static int dwc3_core_get_phy(struct dwc3 *dwc)
if (ret == -ENXIO || ret == -ENODEV) {
dwc->usb3_phy = NULL;
} else if (ret == -EPROBE_DEFER) {
+ printk("%s:%d()+\n",__FUNCTION__, __LINE__);
return ret;
} else {
dev_err(dev, "no usb3 phy configured\n");
@@ -530,6 +532,7 @@ static int dwc3_core_get_phy(struct dwc3 *dwc)
if (ret == -ENOSYS || ret == -ENODEV) {
dwc->usb2_generic_phy = NULL;
} else if (ret == -EPROBE_DEFER) {
+ printk("%s:%d()+\n",__FUNCTION__, __LINE__);
return ret;
} else {
dev_err(dev, "no usb2 phy configured\n");
@@ -543,6 +546,7 @@ static int dwc3_core_get_phy(struct dwc3 *dwc)
if (ret == -ENOSYS || ret == -ENODEV) {
dwc->usb3_generic_phy = NULL;
} else if (ret == -EPROBE_DEFER) {
+ printk("%s:%d()+\n",__FUNCTION__, __LINE__);
return ret;
} else {
dev_err(dev, "no usb3 phy configured\n");
@@ -631,6 +635,8 @@ static int dwc3_probe(struct platform_device *pdev)
void __iomem *regs;
void *mem;
+ printk("%s:%d ()+\n",__FUNCTION__, __LINE__);
+
mem = devm_kzalloc(dev, sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL);
if (!mem) {
dev_err(dev, "not enough memory\n");
@@ -640,6 +646,8 @@ static int dwc3_probe(struct platform_device *pdev)
dwc->mem = mem;
dwc->dev = dev;
+ printk("%s:%d ()+\n",__FUNCTION__, __LINE__);
+
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!res) {
dev_err(dev, "missing IRQ\n");
@@ -656,6 +664,8 @@ static int dwc3_probe(struct platform_device *pdev)
return -ENODEV;
}
+ printk("%s:%d ()+\n",__FUNCTION__, __LINE__);
+
if (node) {
dwc->maximum_speed = of_usb_get_maximum_speed(node);
@@ -672,6 +682,8 @@ static int dwc3_probe(struct platform_device *pdev)
if (dwc->maximum_speed == USB_SPEED_UNKNOWN)
dwc->maximum_speed = USB_SPEED_SUPER;
+ printk("%s:%d ()+\n",__FUNCTION__, __LINE__);
+
ret = dwc3_core_get_phy(dwc);
if (ret)
return ret;
@@ -695,6 +707,8 @@ static int dwc3_probe(struct platform_device *pdev)
spin_lock_init(&dwc->lock);
platform_set_drvdata(pdev, dwc);
+ printk("%s:%d ()+\n",__FUNCTION__, __LINE__);
+
dwc->regs = regs;
dwc->regs_size = resource_size(res);
@@ -708,6 +722,8 @@ static int dwc3_probe(struct platform_device *pdev)
dwc3_cache_hwparams(dwc);
+ printk("%s:%d ()+\n",__FUNCTION__, __LINE__);
+
ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE);
if (ret) {
dev_err(dwc->dev, "failed to allocate event buffers\n");
@@ -735,6 +751,8 @@ static int dwc3_probe(struct platform_device *pdev)
if (ret < 0)
goto err1;
+ printk("%s:%d ()+\n",__FUNCTION__, __LINE__);
+
ret = phy_power_on(dwc->usb3_generic_phy);
if (ret < 0)
goto err_usb2phy_power;
@@ -749,12 +767,16 @@ static int dwc3_probe(struct platform_device *pdev)
if (ret)
goto err2;
+ printk("%s:%d ()+\n",__FUNCTION__, __LINE__);
+
ret = dwc3_debugfs_init(dwc);
if (ret) {
dev_err(dev, "failed to initialize debugfs\n");
goto err3;
}
+ printk("%s:%d ()+\n",__FUNCTION__, __LINE__);
+
pm_runtime_allow(dev);
return 0;
@@ -780,6 +802,8 @@ err0:
dwc3_free_event_buffers(dwc);
return ret;
+
+ printk("%s:%d ()-\n",__FUNCTION__, __LINE__);
}
static int dwc3_remove(struct platform_device *pdev)
diff --git a/drivers/usb/dwc3/dwc3-st.c b/drivers/usb/dwc3/dwc3-st.c
index 19ede8643c7b..14ee7bb5e7d1 100644
--- a/drivers/usb/dwc3/dwc3-st.c
+++ b/drivers/usb/dwc3/dwc3-st.c
@@ -92,6 +92,8 @@ static int st_dwc3_drd_init(struct st_dwc3 *dwc3_data)
{
u32 val;
+ printk("%s:%d ()+\n",__FUNCTION__, __LINE__);
+
regmap_read(dwc3_data->regmap, dwc3_data->syscfg_reg_off, &val);
if (dwc3_data->drd_device_conf)
@@ -99,6 +101,8 @@ static int st_dwc3_drd_init(struct st_dwc3 *dwc3_data)
else
val &= USB_HOST_DEFAULT_MASK;
+ printk("%s:%d ()-\n",__FUNCTION__, __LINE__);
+
return regmap_write(dwc3_data->regmap, dwc3_data->syscfg_reg_off, val);
}
@@ -108,6 +112,8 @@ static int st_dwc3_drd_init(struct st_dwc3 *dwc3_data)
*/
static void st_dwc3_init(struct st_dwc3 *dwc3_data)
{
+
+ printk("%s:%d ()+\n",__FUNCTION__, __LINE__);
u32 reg = st_dwc3_readl(dwc3_data->glue_base, USB2_CLKRST_CTRL);
reg |= aux_clk_en(1) | ext_cfg_reset_n(1) | xhci_revision(1);
@@ -123,6 +129,7 @@ static void st_dwc3_init(struct st_dwc3 *dwc3_data)
reg = st_dwc3_readl(dwc3_data->glue_base, USB2_CLKRST_CTRL);
reg |= sw_pipew_reset_n(1);
st_dwc3_writel(dwc3_data->glue_base, USB2_CLKRST_CTRL, reg);
+ printk("%s:%d ()-\n",__FUNCTION__, __LINE__);
}
static void st_dwc3_dt_get_pdata(struct platform_device *pdev,
@@ -150,6 +157,8 @@ static int st_dwc3_probe(struct platform_device *pdev)
struct regmap *regmap;
int ret = 0;
+ printk("%s:%d()+\n",__FUNCTION__, __LINE__);
+
dwc3_data = devm_kzalloc(dev, sizeof(*dwc3_data), GFP_KERNEL);
if (!dwc3_data)
return -ENOMEM;
@@ -206,12 +215,19 @@ static int st_dwc3_probe(struct platform_device *pdev)
if (IS_ERR(dwc3_data->rstc))
dwc3_data->rstc = NULL;
+ printk("%s:%d\n",__FUNCTION__, __LINE__);
+
/* Manage PowerDown */
- reset_control_deassert(dwc3_data->rstc);
+ if (dwc3_data->rstc)
+ reset_control_deassert(dwc3_data->rstc);
+
+ printk("%s:%d()+\n",__FUNCTION__, __LINE__);
if (node) {
+ printk("%s:%d()+\n",__FUNCTION__, __LINE__);
st_dwc3_dt_get_pdata(pdev, dwc3_data);
/* Allocate and initialize the core */
+ printk("%s:%d()+\n",__FUNCTION__, __LINE__);
ret = of_platform_populate(node, NULL, NULL, dev);
if (ret) {
dev_err(dev, "failed to add dwc3 core\n");
@@ -221,7 +237,7 @@ static int st_dwc3_probe(struct platform_device *pdev)
dev_err(dev, "no device node, failed to add dwc3 core\n");
return -ENODEV;
}
-
+ printk("%s:%d()+\n",__FUNCTION__, __LINE__);
/* ST glue logic init */
st_dwc3_init(dwc3_data);
@@ -242,6 +258,8 @@ static int st_dwc3_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "probe exits fine...\n");
+ printk("%s:d ()-\n",__FUNCTION__, __LINE__);
+
return ret;
}
@@ -259,7 +277,8 @@ static int st_dwc3_suspend(struct device *dev)
{
struct st_dwc3 *dwc3_data = dev_get_drvdata(dev);
- reset_control_assert(dwc3_data->rstc);
+ if (dwc3_data->rstc)
+ reset_control_assert(dwc3_data->rstc);
pinctrl_pm_select_sleep_state(dev);
@@ -272,7 +291,8 @@ static int st_dwc3_resume(struct device *dev)
pinctrl_pm_select_default_state(dev);
- reset_control_deassert(dwc3_data->rstc);
+ if (dwc3_data->rstc)
+ reset_control_deassert(dwc3_data->rstc);
return 0;
}
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
index a7f4a5a70438..895e72463165 100644
--- a/drivers/usb/phy/Kconfig
+++ b/drivers/usb/phy/Kconfig
@@ -232,6 +232,8 @@ config USB_ULPI_VIEWPORT
config PHY_STIH407_USB
tristate "STMicroelectronics picoPHY/MiPHY driver for STiH407 series"
depends on ARCH_STI
+ depends on RESET_CONTROLLER
+ select USB_PHY
help
Enable this to support the USB transceiver that is part of
STMicroelectronics STiH407 SoC series. This will provide the picoPHY
diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
index 4747e67656a1..7584d4894a4e 100644
--- a/drivers/usb/phy/Makefile
+++ b/drivers/usb/phy/Makefile
@@ -29,5 +29,5 @@ obj-$(CONFIG_USB_RCAR_GEN2_PHY) += phy-rcar-gen2-usb.o
obj-$(CONFIG_USB_ULPI) += phy-ulpi.o
obj-$(CONFIG_USB_ULPI_VIEWPORT) += phy-ulpi-viewport.o
obj-$(CONFIG_KEYSTONE_USB_PHY) += phy-keystone.o
-obj-$(CONFIG_PHY_STIH407_USB) += phy-stih407-usb2.o phy-stih407-usb3.o
+obj-$(CONFIG_PHY_STIH407_USB) += phy-stih407-usb2.o phy-st-usb3.o
diff --git a/drivers/usb/phy/phy-st-usb3.c b/drivers/usb/phy/phy-st-usb3.c
new file mode 100644
index 000000000000..205db9f0ab9c
--- /dev/null
+++ b/drivers/usb/phy/phy-st-usb3.c
@@ -0,0 +1,317 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics
+ *
+ * STMicroelectronics PHY driver for MiPHY LP28 (MiPHY2 for USB3 device)
+ *
+ * Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/clk.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <linux/delay.h>
+#include <linux/mfd/syscon.h>
+#include <linux/usb/phy.h>
+
+#define phy_to_priv(x) container_of((x), struct sti_usb3_miphy, phy)
+
+/* MiPHY_2 Control */
+#define SYSCFG5071 0x11c
+#define MIPHY2_PX_TX_POLARITY 1
+#define MIPHY2_PX_RX_POLARITY 2
+#define MIPHY2_PX_SYNC_DETECT_ENABLE 3
+
+/**
+ * struct sti_usb3_cfg - SoC specific PHY register mapping
+ * @syscfg: Offset in syscfg registers bank
+ * @cfg_mask: Bits mask for PHY configuration
+ * @cfg: Static configuration value for PHY
+ */
+struct sti_usb3_cfg {
+ u32 syscfg;
+ u32 cfg_mask;
+ u32 cfg;
+};
+
+struct sti_usb3_miphy {
+ struct usb_phy phy;
+ struct device *dev;
+ struct regmap *regmap;
+ const struct sti_usb3_cfg *cfg;
+ struct reset_control *rstc;
+ void __iomem *usb3_base;
+ void __iomem *pipe_base;
+};
+
+static struct sti_usb3_cfg sti_usb3_miphy_cfg = {
+ .syscfg = SYSCFG5071,
+ .cfg_mask = 0x7,
+ .cfg = MIPHY2_PX_SYNC_DETECT_ENABLE,
+};
+
+struct miphy_initval {
+ u16 reg;
+ u16 val;
+};
+
+/* That is a magic sequence of register settings provided at
+ * verification level to setup the MiPHY2 for USB3 DWC3 device on STiH407.
+ */
+static const struct miphy_initval initvals[] = {
+ /* Putting Macro in reset */
+ {0x00, 0x01}, {0x00, 0x03},
+ /* Wait for a while */
+ {0x00, 0x01}, {0x04, 0x1C},
+ /* PLL calibration */
+ {0xEB, 0x1D}, {0x0D, 0x1E}, {0x0F, 0x00}, {0xC4, 0x70},
+ {0xC9, 0x02}, {0xCA, 0x02}, {0xCB, 0x02}, {0xCC, 0x0A},
+ /* Writing The PLL Ratio */
+ {0xD4, 0xA6}, {0xD5, 0xAA}, {0xD6, 0xAA}, {0xD7, 0x04},
+ {0xD3, 0x00},
+ /* Writing The Speed Rate */
+ {0x0F, 0x00}, {0x0E, 0x0A},
+ /* RX Channel compensation and calibration */
+ {0xC2, 0x1C}, {0x97, 0x51}, {0x98, 0x70}, {0x99, 0x5F},
+ {0x9A, 0x22}, {0x9F, 0x0E},
+
+ {0x7A, 0x05}, {0x7F, 0x78}, {0x30, 0x1B},
+ /* Enable GENSEL_SEL and SSC */
+ /* TX_SEL=0 swing preemp forced by pipe registres */
+ {0x0A, 0x11},
+ /* MIPHY Bias boost */
+ {0x63, 0x00}, {0x64, 0xA7},
+ /* TX compensation offset to re-center TX impedance */
+ {0x42, 0x02},
+ /* SSC modulation */
+ {0x0C, 0x04},
+ /* MIPHY TX control */
+ {0x0F, 0x00}, {0xE5, 0x5A}, {0xE6, 0xA0}, {0xE4, 0x3C},
+ {0xE6, 0xA1}, {0xE3, 0x00}, {0xE3, 0x02}, {0xE3, 0x00},
+ /* Rx PI controller settings */
+ {0x78, 0xCA},
+ /* MIPHY RX input bridge control */
+ /* INPUT_BRIDGE_EN_SW=1, manual input bridge control[0]=1 */
+ {0xCD, 0x21}, {0xCD, 0x29}, {0xCE, 0x1A},
+ /* MIPHY Reset */
+ {0x00, 0x01}, {0x00, 0x00}, {0x01, 0x04}, {0x01, 0x05},
+ {0xE9, 0x00}, {0x0D, 0x1E}, {0x3A, 0x40}, {0x01, 0x01},
+ {0x01, 0x00}, {0xE9, 0x40}, {0x0F, 0x00}, {0x0B, 0x00},
+ {0x62, 0x00}, {0x0F, 0x00}, {0xE3, 0x02}, {0x26, 0xA5},
+ {0x0F, 0x00},
+};
+
+static int sti_usb3_miphy_autocalibration(struct usb_phy *phy_dev,
+ enum usb_device_speed speed)
+{
+ struct sti_usb3_miphy *miphy = phy_to_priv(phy_dev);
+
+ writeb_relaxed(0x40, miphy->usb3_base + 0x01);
+ writeb_relaxed(0x00, miphy->usb3_base + 0x01);
+ dev_dbg(miphy->dev, "miphy autocalibration done\n");
+
+ /*
+ * Set a safe delay after calibration; we use the same range as in the
+ * phy-miphy28lp driver, where a delay is set after miphy reset.
+ * Here we are in the same case given that we are
+ * performing a reset to allow miphy to re-calibrate itself.
+ */
+ usleep_range(10, 20);
+
+ /* Check status */
+ if ((readb_relaxed(miphy->usb3_base + 0x83)) ||
+ (readb_relaxed(miphy->usb3_base + 0x84)))
+ dev_err(miphy->dev, "miphy autocalibration failed!\n");
+
+ return 0;
+}
+
+static void sti_usb3_miphy28lp(struct sti_usb3_miphy *phy_dev)
+{
+ int i;
+
+ dev_info(phy_dev->dev, "MiPHY28LP setup\n");
+
+ for (i = 0; i < ARRAY_SIZE(initvals); i++) {
+ dev_dbg(phy_dev->dev, "reg: 0x%x=0x%x\n", initvals[i].reg,
+ initvals[i].val);
+ writeb_relaxed(initvals[i].val,
+ phy_dev->usb3_base + initvals[i].reg);
+ }
+
+ /* PIPE Wrapper Configuration */
+ writeb_relaxed(0X68, phy_dev->pipe_base + 0x23);
+ writeb_relaxed(0X61, phy_dev->pipe_base + 0x24);
+ writeb_relaxed(0X68, phy_dev->pipe_base + 0x26);
+ writeb_relaxed(0X61, phy_dev->pipe_base + 0x27);
+ writeb_relaxed(0X18, phy_dev->pipe_base + 0x29);
+ writeb_relaxed(0X61, phy_dev->pipe_base + 0x2A);
+
+ /*pipe Wrapper usb3 TX swing de-emph margin PREEMPH[7:4], SWING[3:0] */
+ writeb_relaxed(0X67, phy_dev->pipe_base + 0x68);
+ writeb_relaxed(0X0D, phy_dev->pipe_base + 0x69);
+ writeb_relaxed(0X67, phy_dev->pipe_base + 0x6A);
+ writeb_relaxed(0X0D, phy_dev->pipe_base + 0x6B);
+ writeb_relaxed(0X67, phy_dev->pipe_base + 0x6C);
+ writeb_relaxed(0X0D, phy_dev->pipe_base + 0x6D);
+ writeb_relaxed(0X67, phy_dev->pipe_base + 0x6E);
+ writeb_relaxed(0X0D, phy_dev->pipe_base + 0x6F);
+}
+
+static int sti_usb3_miphy_init(struct usb_phy *phy)
+{
+ struct sti_usb3_miphy *phy_dev = phy_to_priv(phy);
+ int ret;
+
+ ret = regmap_update_bits(phy_dev->regmap, phy_dev->cfg->syscfg,
+ phy_dev->cfg->cfg_mask, phy_dev->cfg->cfg);
+ if (ret)
+ return ret;
+
+ reset_control_deassert(phy_dev->rstc);
+
+ /* Program the MiPHY2 internal registers */
+ sti_usb3_miphy28lp(phy_dev);
+
+ return 0;
+}
+
+static void sti_usb3_miphy_shutdown(struct usb_phy *phy)
+{
+ struct sti_usb3_miphy *phy_dev = phy_to_priv(phy);
+
+ reset_control_assert(phy_dev->rstc);
+}
+
+static const struct of_device_id sti_usb3_miphy_of_match[];
+
+static int sti_usb3_miphy_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ const struct of_device_id *match;
+ struct sti_usb3_miphy *phy_dev;
+ struct device *dev = &pdev->dev;
+ struct usb_phy *phy;
+ struct resource *res;
+
+ phy_dev = devm_kzalloc(dev, sizeof(*phy_dev), GFP_KERNEL);
+ if (!phy_dev)
+ return -ENOMEM;
+
+ match = of_match_device(sti_usb3_miphy_of_match, &pdev->dev);
+ if (!match)
+ return -ENODEV;
+
+ phy_dev->cfg = match->data;
+ phy_dev->dev = dev;
+
+ phy_dev->rstc = devm_reset_control_get(dev, NULL);
+ if (IS_ERR(phy_dev->rstc)) {
+ dev_err(dev, "failed to ctrl MiPHY2 USB3 reset ret = %d\n",phy_dev->rstc);
+ return PTR_ERR(phy_dev->rstc);
+ }
+
+ dev_info(dev, "reset MiPHY\n");
+ reset_control_deassert(phy_dev->rstc);
+
+ phy_dev->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
+ if (IS_ERR(phy_dev->regmap)) {
+ dev_err(dev, "No syscfg phandle specified\n");
+ return PTR_ERR(phy_dev->regmap);
+ }
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "usb3-uport");
+ if (res) {
+ phy_dev->usb3_base = devm_request_and_ioremap(&pdev->dev, res);
+ if (!phy_dev->usb3_base) {
+ dev_err(&pdev->dev, "Unable to map base registers\n");
+ return -ENOMEM;
+ }
+ }
+ /* Check for PIPE registers */
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pipew");
+ if (res) {
+ phy_dev->pipe_base = devm_request_and_ioremap(&pdev->dev, res);
+ if (!phy_dev->pipe_base) {
+ dev_err(&pdev->dev, "Unable to map PIPE registers\n");
+ return -ENOMEM;
+ }
+ }
+
+ dev_info(dev, "usb3 ioaddr 0x%p, pipew ioaddr 0x%p\n",
+ phy_dev->usb3_base, phy_dev->pipe_base);
+
+ phy = &phy_dev->phy;
+ phy->dev = dev;
+ phy->label = "USB3 MiPHY2 (LP28)";
+ phy->init = sti_usb3_miphy_init;
+ phy->type = USB_PHY_TYPE_USB3;
+ phy->shutdown = sti_usb3_miphy_shutdown;
+ if (of_property_read_bool(np, "st,auto-calibration"))
+ phy->notify_disconnect = sti_usb3_miphy_autocalibration;
+
+ usb_add_phy_dev(phy);
+
+ platform_set_drvdata(pdev, phy_dev);
+
+ dev_info(dev, "USB3 MiPHY2 probed\n");
+
+ return 0;
+}
+
+static int sti_usb3_miphy_remove(struct platform_device *pdev)
+{
+ struct sti_usb3_miphy *phy_dev = platform_get_drvdata(pdev);
+
+ reset_control_assert(phy_dev->rstc);
+
+ usb_remove_phy(&phy_dev->phy);
+
+ return 0;
+}
+
+static const struct of_device_id sti_usb3_miphy_of_match[] = {
+ {
+ .compatible = "st,sti-usb3phy",
+ .data = &sti_usb3_miphy_cfg},
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, sti_usb3_miphy_of_match);
+
+static struct platform_driver sti_usb3_miphy_driver = {
+ .probe = sti_usb3_miphy_probe,
+ .remove = sti_usb3_miphy_remove,
+ .driver = {
+ .name = "sti-usb3-phy",
+ .owner = THIS_MODULE,
+ .of_match_table = sti_usb3_miphy_of_match,
+ }
+};
+
+//module_platform_driver(sti_usb3_miphy_driver);
+
+static int __init sti_usb3_miphy_drive_init(void)
+{
+ return platform_driver_register(&sti_usb3_miphy_driver);
+}
+
+subsys_initcall(sti_usb3_miphy_drive_init);
+
+static void __exit sti_usb3_miphy_drive_exit(void)
+{
+ return platform_driver_unregister(&sti_usb3_miphy_driver);
+}
+
+MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
+MODULE_DESCRIPTION("STMicroelectronics USB3 MiPHY for STiH407/STi8416 SoC");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/phy/phy-stih407-usb2.c b/drivers/usb/phy/phy-stih407-usb2.c
index 2cb7751ec93e..7160f80eeff3 100644
--- a/drivers/usb/phy/phy-stih407-usb2.c
+++ b/drivers/usb/phy/phy-stih407-usb2.c
@@ -93,6 +93,8 @@ static int stih407_usb2_picophy_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct usb_phy *phy;
+ printk("%s:%d()+\n",__FUNCTION__, __LINE__);
+
phy_dev = devm_kzalloc(dev, sizeof(*phy_dev), GFP_KERNEL);
if (!phy_dev)
return -ENOMEM;
@@ -129,6 +131,7 @@ static int stih407_usb2_picophy_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, phy_dev);
dev_info(dev, "USB2 picoPHY probed\n");
+ printk("%s:%d()-\n",__FUNCTION__, __LINE__);
return 0;
}