All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv3 00/12] usb: ulpi bus
@ 2015-04-28 13:24 Heikki Krogerus
  2015-04-28 13:24 ` [PATCHv3 01/11] usb: add bus type for USB ULPI Heikki Krogerus
                   ` (11 more replies)
  0 siblings, 12 replies; 32+ messages in thread
From: Heikki Krogerus @ 2015-04-28 13:24 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: David Cohen, Greg Kroah-Hartman, Stephen Boyd, Baolu Lu,
	Paul Bolle, linux-usb, linux-kernel

Hi,

I took the liberty of adding David's ACK to everything except 9/12, including to
the 1/12 (removing the module handling has no functional affect).

Changes since v2:
- remove module handling from the bus driver as suggested by Paul Bolle.
- reordered the gpio requests in BYT quirk as suggested by David Cohen.

Major changes since v1:
- calling dwc3_phy_setup earlier and registering the ULPI interface there.
- new property to dwc3 for selecting the interface in case of UTMI+ and ULPI as
  suggested by Felipe
- dwc3 soft reset before registration of the ULPI interface to sync the clocks
  as suggested by David
- Including support for the BYT boards that have the GPIOs controlling the reset
  and cs signals.

Heikki Krogerus (12):
  usb: add bus type for USB ULPI
  usb: dwc3: USB2 PHY register access bits
  usb: dwc3: ULPI or UTMI+ select
  usb: dwc3: store driver data earlier
  usb: dwc3: cache hwparams earlier
  usb: dwc3: soft reset to it's own function
  usb: dwc3: setup phys earlier
  usb: dwc3: add hsphy_interface property
  usb: dwc3: pci: add quirk for Baytrails
  usb: dwc3: add ULPI interface support
  phy: helpers for USB ULPI PHY registering
  phy: add driver for TI TUSB1210 ULPI PHY

 Documentation/devicetree/bindings/usb/dwc3.txt |   2 +
 MAINTAINERS                                    |   7 +
 drivers/phy/Kconfig                            |   7 +
 drivers/phy/Makefile                           |   1 +
 drivers/phy/phy-tusb1210.c                     | 153 +++++++++++++++
 drivers/phy/ulpi_phy.h                         |  31 ++++
 drivers/usb/common/Makefile                    |   1 +
 drivers/usb/common/ulpi.c                      | 246 +++++++++++++++++++++++++
 drivers/usb/core/Kconfig                       |   8 +
 drivers/usb/dwc3/Kconfig                       |   7 +
 drivers/usb/dwc3/Makefile                      |   4 +
 drivers/usb/dwc3/core.c                        |  99 +++++++---
 drivers/usb/dwc3/core.h                        |  26 +++
 drivers/usb/dwc3/dwc3-pci.c                    |  36 ++++
 drivers/usb/dwc3/platform_data.h               |   2 +
 drivers/usb/dwc3/ulpi.c                        |  91 +++++++++
 include/linux/mod_devicetable.h                |   6 +
 include/linux/ulpi/driver.h                    |  62 +++++++
 include/linux/ulpi/interface.h                 |  23 +++
 include/linux/ulpi/regs.h                      | 130 +++++++++++++
 include/linux/usb/ulpi.h                       | 134 +-------------
 scripts/mod/devicetable-offsets.c              |   4 +
 scripts/mod/file2alias.c                       |  13 ++
 23 files changed, 936 insertions(+), 157 deletions(-)
 create mode 100644 drivers/phy/phy-tusb1210.c
 create mode 100644 drivers/phy/ulpi_phy.h
 create mode 100644 drivers/usb/common/ulpi.c
 create mode 100644 drivers/usb/dwc3/ulpi.c
 create mode 100644 include/linux/ulpi/driver.h
 create mode 100644 include/linux/ulpi/interface.h
 create mode 100644 include/linux/ulpi/regs.h

-- 
2.1.4


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCHv3 01/11] usb: add bus type for USB ULPI
  2015-04-28 13:24 [PATCHv3 00/12] usb: ulpi bus Heikki Krogerus
@ 2015-04-28 13:24 ` Heikki Krogerus
  2015-04-29 20:13   ` Felipe Balbi
  2015-04-28 13:24 ` [PATCHv3 02/11] usb: dwc3: USB2 PHY register access bits Heikki Krogerus
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 32+ messages in thread
From: Heikki Krogerus @ 2015-04-28 13:24 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: David Cohen, Greg Kroah-Hartman, Stephen Boyd, Baolu Lu,
	Paul Bolle, linux-usb, linux-kernel

UTMI+ Low Pin Interface (ULPI) is a commonly used PHY
interface for USB 2.0. The ULPI specification describes a
standard set of registers which the vendors can extend for
their specific needs. ULPI PHYs provide often functions
such as charger detection and ADP sensing and probing.

There are two major issues that the bus type is meant to
tackle:

Firstly, ULPI registers are accessed from the controller.
The bus provides convenient method for the controller
drivers to share that access with the actual PHY drivers.

Secondly, there are already platforms that assume ULPI PHYs
are runtime detected, such as many Intel Baytrail based
platforms. They do not provide any kind of hardware
description for the ULPI PHYs like separate ACPI device
object that could be used to enumerate a device from.

Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Acked-by: David Cohen <david.a.cohen@linux.intel.com>
---
 MAINTAINERS                       |   7 ++
 drivers/usb/common/Makefile       |   1 +
 drivers/usb/common/ulpi.c         | 246 ++++++++++++++++++++++++++++++++++++++
 drivers/usb/core/Kconfig          |   7 ++
 include/linux/mod_devicetable.h   |   6 +
 include/linux/ulpi/driver.h       |  62 ++++++++++
 include/linux/ulpi/interface.h    |  23 ++++
 include/linux/ulpi/regs.h         | 130 ++++++++++++++++++++
 include/linux/usb/ulpi.h          | 134 +--------------------
 scripts/mod/devicetable-offsets.c |   4 +
 scripts/mod/file2alias.c          |  13 ++
 11 files changed, 501 insertions(+), 132 deletions(-)
 create mode 100644 drivers/usb/common/ulpi.c
 create mode 100644 include/linux/ulpi/driver.h
 create mode 100644 include/linux/ulpi/interface.h
 create mode 100644 include/linux/ulpi/regs.h

diff --git a/MAINTAINERS b/MAINTAINERS
index be26fc5..cfbdb8c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10470,6 +10470,13 @@ S:	Maintained
 F:	Documentation/video4linux/zr364xx.txt
 F:	drivers/media/usb/zr364xx/
 
+ULPI BUS
+M:	Heikki Krogerus <heikki.krogerus@linux.intel.com>
+L:	linux-usb@vger.kernel.org
+S:	Maintained
+F:	drivers/usb/common/ulpi.c
+F:	include/linux/ulpi/
+
 USER-MODE LINUX (UML)
 M:	Jeff Dike <jdike@addtoit.com>
 M:	Richard Weinberger <richard@nod.at>
diff --git a/drivers/usb/common/Makefile b/drivers/usb/common/Makefile
index ca2f8bd..6bbb3ec 100644
--- a/drivers/usb/common/Makefile
+++ b/drivers/usb/common/Makefile
@@ -7,3 +7,4 @@ usb-common-y			  += common.o
 usb-common-$(CONFIG_USB_LED_TRIG) += led.o
 
 obj-$(CONFIG_USB_OTG_FSM) += usb-otg-fsm.o
+obj-$(CONFIG_USB_ULPI_BUS)	+= ulpi.o
diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c
new file mode 100644
index 0000000..84dcd2e
--- /dev/null
+++ b/drivers/usb/common/ulpi.c
@@ -0,0 +1,246 @@
+/**
+ * ulpi.c - USB ULPI PHY bus
+ *
+ * Copyright (C) 2015 Intel Corporation
+ *
+ * Author: Heikki Krogerus <heikki.krogerus@linux.intel.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/ulpi/interface.h>
+#include <linux/ulpi/driver.h>
+#include <linux/ulpi/regs.h>
+#include <linux/kmod.h>
+#include <linux/slab.h>
+#include <linux/acpi.h>
+
+/* -------------------------------------------------------------------------- */
+
+int ulpi_read(struct ulpi *ulpi, u8 addr)
+{
+	return ulpi->ops->read(ulpi->ops, addr);
+}
+EXPORT_SYMBOL_GPL(ulpi_read);
+
+int ulpi_write(struct ulpi *ulpi, u8 addr, u8 val)
+{
+	return ulpi->ops->write(ulpi->ops, addr, val);
+}
+EXPORT_SYMBOL_GPL(ulpi_write);
+
+/* -------------------------------------------------------------------------- */
+
+static int ulpi_match(struct device *dev, struct device_driver *driver)
+{
+	struct ulpi_driver *drv = to_ulpi_driver(driver);
+	struct ulpi *ulpi = to_ulpi_dev(dev);
+	const struct ulpi_device_id *id;
+
+	for (id = drv->id_table; id->vendor; id++)
+		if (id->vendor == ulpi->id.vendor &&
+		    id->product == ulpi->id.product)
+			return 1;
+
+	return 0;
+}
+
+static int ulpi_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+	struct ulpi *ulpi = to_ulpi_dev(dev);
+
+	if (add_uevent_var(env, "MODALIAS=ulpi:v%04xp%04x",
+			   ulpi->id.vendor, ulpi->id.product))
+		return -ENOMEM;
+	return 0;
+}
+
+static int ulpi_probe(struct device *dev)
+{
+	struct ulpi_driver *drv = to_ulpi_driver(dev->driver);
+
+	return drv->probe(to_ulpi_dev(dev));
+}
+
+static int ulpi_remove(struct device *dev)
+{
+	struct ulpi_driver *drv = to_ulpi_driver(dev->driver);
+
+	if (drv->remove)
+		drv->remove(to_ulpi_dev(dev));
+
+	return 0;
+}
+
+struct bus_type ulpi_bus = {
+	.name = "ulpi",
+	.match = ulpi_match,
+	.uevent = ulpi_uevent,
+	.probe = ulpi_probe,
+	.remove = ulpi_remove,
+};
+EXPORT_SYMBOL_GPL(ulpi_bus);
+
+/* -------------------------------------------------------------------------- */
+
+static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
+			     char *buf)
+{
+	struct ulpi *ulpi = to_ulpi_dev(dev);
+
+	return sprintf(buf, "ulpi:v%04xp%04x\n",
+		       ulpi->id.vendor, ulpi->id.product);
+}
+static DEVICE_ATTR_RO(modalias);
+
+static struct attribute *ulpi_dev_attrs[] = {
+	&dev_attr_modalias.attr,
+	NULL
+};
+
+static struct attribute_group ulpi_dev_attr_group = {
+	.attrs = ulpi_dev_attrs,
+};
+
+static const struct attribute_group *ulpi_dev_attr_groups[] = {
+	&ulpi_dev_attr_group,
+	NULL
+};
+
+static void ulpi_dev_release(struct device *dev)
+{
+	kfree(to_ulpi_dev(dev));
+}
+
+struct device_type ulpi_dev_type = {
+	.name = "ulpi_device",
+	.groups = ulpi_dev_attr_groups,
+	.release = ulpi_dev_release,
+};
+
+/* -------------------------------------------------------------------------- */
+
+/**
+ * ulpi_register_driver - register a driver with the ULPI bus
+ * @drv: driver being registered
+ *
+ * Registers a driver with the ULPI bus.
+ */
+int ulpi_register_driver(struct ulpi_driver *drv)
+{
+	if (!drv->probe)
+		return -EINVAL;
+
+	drv->driver.bus = &ulpi_bus;
+
+	return driver_register(&drv->driver);
+}
+EXPORT_SYMBOL_GPL(ulpi_register_driver);
+
+/**
+ * ulpi_unregister_driver - unregister a driver with the ULPI bus
+ * @drv: driver to unregister
+ *
+ * Unregisters a driver with the ULPI bus.
+ */
+void ulpi_unregister_driver(struct ulpi_driver *drv)
+{
+	driver_unregister(&drv->driver);
+}
+EXPORT_SYMBOL_GPL(ulpi_unregister_driver);
+
+/* -------------------------------------------------------------------------- */
+
+static int ulpi_register(struct device *dev, struct ulpi *ulpi)
+{
+	int ret;
+
+	/* Test the interface */
+	ret = ulpi_write(ulpi, ULPI_SCRATCH, 0xaa);
+	if (ret < 0)
+		return ret;
+
+	ret = ulpi_read(ulpi, ULPI_SCRATCH);
+	if (ret < 0)
+		return ret;
+
+	if (ret != 0xaa)
+		return -ENODEV;
+
+	ulpi->id.vendor = ulpi_read(ulpi, ULPI_VENDOR_ID_LOW);
+	ulpi->id.vendor |= ulpi_read(ulpi, ULPI_VENDOR_ID_HIGH) << 8;
+
+	ulpi->id.product = ulpi_read(ulpi, ULPI_PRODUCT_ID_LOW);
+	ulpi->id.product |= ulpi_read(ulpi, ULPI_PRODUCT_ID_HIGH) << 8;
+
+	ulpi->dev.parent = dev;
+	ulpi->dev.bus = &ulpi_bus;
+	ulpi->dev.type = &ulpi_dev_type;
+	dev_set_name(&ulpi->dev, "%s.ulpi", dev_name(dev));
+
+	ACPI_COMPANION_SET(&ulpi->dev, ACPI_COMPANION(dev));
+
+	request_module("ulpi:v%04xp%04x", ulpi->id.vendor, ulpi->id.product);
+
+	ret = device_register(&ulpi->dev);
+	if (ret)
+		return ret;
+
+	dev_dbg(&ulpi->dev, "registered ULPI PHY: vendor %04x, product %04x\n",
+		ulpi->id.vendor, ulpi->id.product);
+
+	return 0;
+}
+
+/**
+ * ulpi_register_interface - instantiate new ULPI device
+ * @dev: USB controller's device interface
+ * @ops: ULPI register access
+ *
+ * Allocates and registers a ULPI device and an interface for it. Called from
+ * the USB controller that provides the ULPI interface.
+ */
+struct ulpi *ulpi_register_interface(struct device *dev, struct ulpi_ops *ops)
+{
+	struct ulpi *ulpi;
+	int ret;
+
+	ulpi = kzalloc(sizeof(*ulpi), GFP_KERNEL);
+	if (!ulpi)
+		return ERR_PTR(-ENOMEM);
+
+	ulpi->ops = ops;
+	ops->dev = dev;
+
+	ret = ulpi_register(dev, ulpi);
+	if (ret) {
+		kfree(ulpi);
+		return ERR_PTR(ret);
+	}
+
+	return ulpi;
+}
+EXPORT_SYMBOL_GPL(ulpi_register_interface);
+
+/**
+ * ulpi_unregister_interface - unregister ULPI interface
+ * @intrf: struct ulpi_interface
+ *
+ * Unregisters a ULPI device and it's interface that was created with
+ * ulpi_create_interface().
+ */
+void ulpi_unregister_interface(struct ulpi *ulpi)
+{
+	device_unregister(&ulpi->dev);
+}
+EXPORT_SYMBOL_GPL(ulpi_unregister_interface);
+
+/* -------------------------------------------------------------------------- */
+
+static int __init ulpi_init(void)
+{
+	return bus_register(&ulpi_bus);
+}
+subsys_initcall(ulpi_init);
diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig
index cc0ced0..2cdb4fc 100644
--- a/drivers/usb/core/Kconfig
+++ b/drivers/usb/core/Kconfig
@@ -84,3 +84,10 @@ config USB_OTG_FSM
 	  Implements OTG Finite State Machine as specified in On-The-Go
 	  and Embedded Host Supplement to the USB Revision 2.0 Specification.
 
+config USB_ULPI_BUS
+	bool "USB ULPI PHY interface support"
+	depends on USB_SUPPORT
+	help
+	  Say yes if you have ULPI PHY attached to your USB controller.
+
+	  If unsure, say N.
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 3bfd567..7ab00d6 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -629,4 +629,10 @@ struct mcb_device_id {
 	kernel_ulong_t driver_data;
 };
 
+struct ulpi_device_id {
+	__u16 vendor;
+	__u16 product;
+	kernel_ulong_t driver_data;
+};
+
 #endif /* LINUX_MOD_DEVICETABLE_H */
diff --git a/include/linux/ulpi/driver.h b/include/linux/ulpi/driver.h
new file mode 100644
index 0000000..1f5657b
--- /dev/null
+++ b/include/linux/ulpi/driver.h
@@ -0,0 +1,62 @@
+#ifndef __LINUX_ULPI_DRIVER_H
+#define __LINUX_ULPI_DRIVER_H
+
+#include <linux/mod_devicetable.h>
+
+#include <linux/device.h>
+
+struct ulpi_ops;
+
+/**
+ * struct ulpi - describes ULPI PHY device
+ * @id: vendor and product ids for ULPI device
+ * @ops: I/O access
+ * @dev: device interface
+ */
+struct ulpi {
+	struct ulpi_device_id id;
+	struct ulpi_ops *ops;
+	struct device dev;
+};
+
+#define to_ulpi_dev(d) container_of(d, struct ulpi, dev)
+
+static inline void ulpi_set_drvdata(struct ulpi *ulpi, void *data)
+{
+	dev_set_drvdata(&ulpi->dev, data);
+}
+
+static inline void *ulpi_get_drvdata(struct ulpi *ulpi)
+{
+	return dev_get_drvdata(&ulpi->dev);
+}
+
+/**
+ * struct ulpi_driver - describes a ULPI PHY driver
+ * @id_table: array of device identifiers supported by this driver
+ * @probe: binds this driver to ULPI device
+ * @remove: unbinds this driver from ULPI device
+ * @driver: the name and owner members must be initialized by the drivers
+ */
+struct ulpi_driver {
+	const struct ulpi_device_id *id_table;
+	int (*probe)(struct ulpi *ulpi);
+	void (*remove)(struct ulpi *ulpi);
+	struct device_driver driver;
+};
+
+#define to_ulpi_driver(d) container_of(d, struct ulpi_driver, driver)
+
+int ulpi_register_driver(struct ulpi_driver *drv);
+void ulpi_unregister_driver(struct ulpi_driver *drv);
+
+#define module_ulpi_driver(__ulpi_driver) \
+	module_driver(__ulpi_driver, ulpi_register_driver, \
+		      ulpi_unregister_driver)
+
+int ulpi_read(struct ulpi *ulpi, u8 addr);
+int ulpi_write(struct ulpi *ulpi, u8 addr, u8 val);
+
+extern struct device_type ulpi_dev_type;
+
+#endif /* __LINUX_ULPI_DRIVER_H */
diff --git a/include/linux/ulpi/interface.h b/include/linux/ulpi/interface.h
new file mode 100644
index 0000000..08753f7
--- /dev/null
+++ b/include/linux/ulpi/interface.h
@@ -0,0 +1,23 @@
+#ifndef __LINUX_ULPI_INTERFACE_H
+#define __LINUX_ULPI_INTERFACE_H
+
+#include <linux/types.h>
+
+struct ulpi;
+
+/**
+ * struct ulpi_ops - ULPI register access
+ * @dev: the interface provider
+ * @read: read opearation for ULPI register access
+ * @write: write opearation for ULPI register access
+ */
+struct ulpi_ops {
+	struct device *dev;
+	int (*read)(struct ulpi_ops *ops, u8 addr);
+	int (*write)(struct ulpi_ops *ops, u8 addr, u8 val);
+};
+
+struct ulpi *ulpi_register_interface(struct device *, struct ulpi_ops *);
+void ulpi_unregister_interface(struct ulpi *);
+
+#endif /* __LINUX_ULPI_INTERFACE_H */
diff --git a/include/linux/ulpi/regs.h b/include/linux/ulpi/regs.h
new file mode 100644
index 0000000..b5b8b88
--- /dev/null
+++ b/include/linux/ulpi/regs.h
@@ -0,0 +1,130 @@
+#ifndef __LINUX_ULPI_REGS_H
+#define __LINUX_ULPI_REGS_H
+
+/*
+ * Macros for Set and Clear
+ * See ULPI 1.1 specification to find the registers with Set and Clear offsets
+ */
+#define ULPI_SET(a)				(a + 1)
+#define ULPI_CLR(a)				(a + 2)
+
+/*
+ * Register Map
+ */
+#define ULPI_VENDOR_ID_LOW			0x00
+#define ULPI_VENDOR_ID_HIGH			0x01
+#define ULPI_PRODUCT_ID_LOW			0x02
+#define ULPI_PRODUCT_ID_HIGH			0x03
+#define ULPI_FUNC_CTRL				0x04
+#define ULPI_IFC_CTRL				0x07
+#define ULPI_OTG_CTRL				0x0a
+#define ULPI_USB_INT_EN_RISE			0x0d
+#define ULPI_USB_INT_EN_FALL			0x10
+#define ULPI_USB_INT_STS			0x13
+#define ULPI_USB_INT_LATCH			0x14
+#define ULPI_DEBUG				0x15
+#define ULPI_SCRATCH				0x16
+/* Optional Carkit Registers */
+#define ULPI_CARKIT_CTRL			0x19
+#define ULPI_CARKIT_INT_DELAY			0x1c
+#define ULPI_CARKIT_INT_EN			0x1d
+#define ULPI_CARKIT_INT_STS			0x20
+#define ULPI_CARKIT_INT_LATCH			0x21
+#define ULPI_CARKIT_PLS_CTRL			0x22
+/* Other Optional Registers */
+#define ULPI_TX_POS_WIDTH			0x25
+#define ULPI_TX_NEG_WIDTH			0x26
+#define ULPI_POLARITY_RECOVERY			0x27
+/* Access Extended Register Set */
+#define ULPI_ACCESS_EXTENDED			0x2f
+/* Vendor Specific */
+#define ULPI_VENDOR_SPECIFIC			0x30
+/* Extended Registers */
+#define ULPI_EXT_VENDOR_SPECIFIC		0x80
+
+/*
+ * Register Bits
+ */
+
+/* Function Control */
+#define ULPI_FUNC_CTRL_XCVRSEL			BIT(0)
+#define  ULPI_FUNC_CTRL_XCVRSEL_MASK		0x3
+#define  ULPI_FUNC_CTRL_HIGH_SPEED		0x0
+#define  ULPI_FUNC_CTRL_FULL_SPEED		0x1
+#define  ULPI_FUNC_CTRL_LOW_SPEED		0x2
+#define  ULPI_FUNC_CTRL_FS4LS			0x3
+#define ULPI_FUNC_CTRL_TERMSELECT		BIT(2)
+#define ULPI_FUNC_CTRL_OPMODE			BIT(3)
+#define  ULPI_FUNC_CTRL_OPMODE_MASK		(0x3 << 3)
+#define  ULPI_FUNC_CTRL_OPMODE_NORMAL		(0x0 << 3)
+#define  ULPI_FUNC_CTRL_OPMODE_NONDRIVING	(0x1 << 3)
+#define  ULPI_FUNC_CTRL_OPMODE_DISABLE_NRZI	(0x2 << 3)
+#define  ULPI_FUNC_CTRL_OPMODE_NOSYNC_NOEOP	(0x3 << 3)
+#define ULPI_FUNC_CTRL_RESET			BIT(5)
+#define ULPI_FUNC_CTRL_SUSPENDM			BIT(6)
+
+/* Interface Control */
+#define ULPI_IFC_CTRL_6_PIN_SERIAL_MODE		BIT(0)
+#define ULPI_IFC_CTRL_3_PIN_SERIAL_MODE		BIT(1)
+#define ULPI_IFC_CTRL_CARKITMODE		BIT(2)
+#define ULPI_IFC_CTRL_CLOCKSUSPENDM		BIT(3)
+#define ULPI_IFC_CTRL_AUTORESUME		BIT(4)
+#define ULPI_IFC_CTRL_EXTERNAL_VBUS		BIT(5)
+#define ULPI_IFC_CTRL_PASSTHRU			BIT(6)
+#define ULPI_IFC_CTRL_PROTECT_IFC_DISABLE	BIT(7)
+
+/* OTG Control */
+#define ULPI_OTG_CTRL_ID_PULLUP			BIT(0)
+#define ULPI_OTG_CTRL_DP_PULLDOWN		BIT(1)
+#define ULPI_OTG_CTRL_DM_PULLDOWN		BIT(2)
+#define ULPI_OTG_CTRL_DISCHRGVBUS		BIT(3)
+#define ULPI_OTG_CTRL_CHRGVBUS			BIT(4)
+#define ULPI_OTG_CTRL_DRVVBUS			BIT(5)
+#define ULPI_OTG_CTRL_DRVVBUS_EXT		BIT(6)
+#define ULPI_OTG_CTRL_EXTVBUSIND		BIT(7)
+
+/* USB Interrupt Enable Rising,
+ * USB Interrupt Enable Falling,
+ * USB Interrupt Status and
+ * USB Interrupt Latch
+ */
+#define ULPI_INT_HOST_DISCONNECT		BIT(0)
+#define ULPI_INT_VBUS_VALID			BIT(1)
+#define ULPI_INT_SESS_VALID			BIT(2)
+#define ULPI_INT_SESS_END			BIT(3)
+#define ULPI_INT_IDGRD				BIT(4)
+
+/* Debug */
+#define ULPI_DEBUG_LINESTATE0			BIT(0)
+#define ULPI_DEBUG_LINESTATE1			BIT(1)
+
+/* Carkit Control */
+#define ULPI_CARKIT_CTRL_CARKITPWR		BIT(0)
+#define ULPI_CARKIT_CTRL_IDGNDDRV		BIT(1)
+#define ULPI_CARKIT_CTRL_TXDEN			BIT(2)
+#define ULPI_CARKIT_CTRL_RXDEN			BIT(3)
+#define ULPI_CARKIT_CTRL_SPKLEFTEN		BIT(4)
+#define ULPI_CARKIT_CTRL_SPKRIGHTEN		BIT(5)
+#define ULPI_CARKIT_CTRL_MICEN			BIT(6)
+
+/* Carkit Interrupt Enable */
+#define ULPI_CARKIT_INT_EN_IDFLOAT_RISE		BIT(0)
+#define ULPI_CARKIT_INT_EN_IDFLOAT_FALL		BIT(1)
+#define ULPI_CARKIT_INT_EN_CARINTDET		BIT(2)
+#define ULPI_CARKIT_INT_EN_DP_RISE		BIT(3)
+#define ULPI_CARKIT_INT_EN_DP_FALL		BIT(4)
+
+/* Carkit Interrupt Status and
+ * Carkit Interrupt Latch
+ */
+#define ULPI_CARKIT_INT_IDFLOAT			BIT(0)
+#define ULPI_CARKIT_INT_CARINTDET		BIT(1)
+#define ULPI_CARKIT_INT_DP			BIT(2)
+
+/* Carkit Pulse Control*/
+#define ULPI_CARKIT_PLS_CTRL_TXPLSEN		BIT(0)
+#define ULPI_CARKIT_PLS_CTRL_RXPLSEN		BIT(1)
+#define ULPI_CARKIT_PLS_CTRL_SPKRLEFT_BIASEN	BIT(2)
+#define ULPI_CARKIT_PLS_CTRL_SPKRRIGHT_BIASEN	BIT(3)
+
+#endif /* __LINUX_ULPI_REGS_H */
diff --git a/include/linux/usb/ulpi.h b/include/linux/usb/ulpi.h
index 5c295c2..5f07407 100644
--- a/include/linux/usb/ulpi.h
+++ b/include/linux/usb/ulpi.h
@@ -12,6 +12,8 @@
 #define __LINUX_USB_ULPI_H
 
 #include <linux/usb/otg.h>
+#include <linux/ulpi/regs.h>
+
 /*-------------------------------------------------------------------------*/
 
 /*
@@ -49,138 +51,6 @@
 
 /*-------------------------------------------------------------------------*/
 
-/*
- * Macros for Set and Clear
- * See ULPI 1.1 specification to find the registers with Set and Clear offsets
- */
-#define ULPI_SET(a)				(a + 1)
-#define ULPI_CLR(a)				(a + 2)
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * Register Map
- */
-#define ULPI_VENDOR_ID_LOW			0x00
-#define ULPI_VENDOR_ID_HIGH			0x01
-#define ULPI_PRODUCT_ID_LOW			0x02
-#define ULPI_PRODUCT_ID_HIGH			0x03
-#define ULPI_FUNC_CTRL				0x04
-#define ULPI_IFC_CTRL				0x07
-#define ULPI_OTG_CTRL				0x0a
-#define ULPI_USB_INT_EN_RISE			0x0d
-#define ULPI_USB_INT_EN_FALL			0x10
-#define ULPI_USB_INT_STS			0x13
-#define ULPI_USB_INT_LATCH			0x14
-#define ULPI_DEBUG				0x15
-#define ULPI_SCRATCH				0x16
-/* Optional Carkit Registers */
-#define ULPI_CARCIT_CTRL			0x19
-#define ULPI_CARCIT_INT_DELAY			0x1c
-#define ULPI_CARCIT_INT_EN			0x1d
-#define ULPI_CARCIT_INT_STS			0x20
-#define ULPI_CARCIT_INT_LATCH			0x21
-#define ULPI_CARCIT_PLS_CTRL			0x22
-/* Other Optional Registers */
-#define ULPI_TX_POS_WIDTH			0x25
-#define ULPI_TX_NEG_WIDTH			0x26
-#define ULPI_POLARITY_RECOVERY			0x27
-/* Access Extended Register Set */
-#define ULPI_ACCESS_EXTENDED			0x2f
-/* Vendor Specific */
-#define ULPI_VENDOR_SPECIFIC			0x30
-/* Extended Registers */
-#define ULPI_EXT_VENDOR_SPECIFIC		0x80
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * Register Bits
- */
-
-/* Function Control */
-#define ULPI_FUNC_CTRL_XCVRSEL			(1 << 0)
-#define  ULPI_FUNC_CTRL_XCVRSEL_MASK		(3 << 0)
-#define  ULPI_FUNC_CTRL_HIGH_SPEED		(0 << 0)
-#define  ULPI_FUNC_CTRL_FULL_SPEED		(1 << 0)
-#define  ULPI_FUNC_CTRL_LOW_SPEED		(2 << 0)
-#define  ULPI_FUNC_CTRL_FS4LS			(3 << 0)
-#define ULPI_FUNC_CTRL_TERMSELECT		(1 << 2)
-#define ULPI_FUNC_CTRL_OPMODE			(1 << 3)
-#define  ULPI_FUNC_CTRL_OPMODE_MASK		(3 << 3)
-#define  ULPI_FUNC_CTRL_OPMODE_NORMAL		(0 << 3)
-#define  ULPI_FUNC_CTRL_OPMODE_NONDRIVING	(1 << 3)
-#define  ULPI_FUNC_CTRL_OPMODE_DISABLE_NRZI	(2 << 3)
-#define  ULPI_FUNC_CTRL_OPMODE_NOSYNC_NOEOP	(3 << 3)
-#define ULPI_FUNC_CTRL_RESET			(1 << 5)
-#define ULPI_FUNC_CTRL_SUSPENDM			(1 << 6)
-
-/* Interface Control */
-#define ULPI_IFC_CTRL_6_PIN_SERIAL_MODE		(1 << 0)
-#define ULPI_IFC_CTRL_3_PIN_SERIAL_MODE		(1 << 1)
-#define ULPI_IFC_CTRL_CARKITMODE		(1 << 2)
-#define ULPI_IFC_CTRL_CLOCKSUSPENDM		(1 << 3)
-#define ULPI_IFC_CTRL_AUTORESUME		(1 << 4)
-#define ULPI_IFC_CTRL_EXTERNAL_VBUS		(1 << 5)
-#define ULPI_IFC_CTRL_PASSTHRU			(1 << 6)
-#define ULPI_IFC_CTRL_PROTECT_IFC_DISABLE	(1 << 7)
-
-/* OTG Control */
-#define ULPI_OTG_CTRL_ID_PULLUP			(1 << 0)
-#define ULPI_OTG_CTRL_DP_PULLDOWN		(1 << 1)
-#define ULPI_OTG_CTRL_DM_PULLDOWN		(1 << 2)
-#define ULPI_OTG_CTRL_DISCHRGVBUS		(1 << 3)
-#define ULPI_OTG_CTRL_CHRGVBUS			(1 << 4)
-#define ULPI_OTG_CTRL_DRVVBUS			(1 << 5)
-#define ULPI_OTG_CTRL_DRVVBUS_EXT		(1 << 6)
-#define ULPI_OTG_CTRL_EXTVBUSIND		(1 << 7)
-
-/* USB Interrupt Enable Rising,
- * USB Interrupt Enable Falling,
- * USB Interrupt Status and
- * USB Interrupt Latch
- */
-#define ULPI_INT_HOST_DISCONNECT		(1 << 0)
-#define ULPI_INT_VBUS_VALID			(1 << 1)
-#define ULPI_INT_SESS_VALID			(1 << 2)
-#define ULPI_INT_SESS_END			(1 << 3)
-#define ULPI_INT_IDGRD				(1 << 4)
-
-/* Debug */
-#define ULPI_DEBUG_LINESTATE0			(1 << 0)
-#define ULPI_DEBUG_LINESTATE1			(1 << 1)
-
-/* Carkit Control */
-#define ULPI_CARKIT_CTRL_CARKITPWR		(1 << 0)
-#define ULPI_CARKIT_CTRL_IDGNDDRV		(1 << 1)
-#define ULPI_CARKIT_CTRL_TXDEN			(1 << 2)
-#define ULPI_CARKIT_CTRL_RXDEN			(1 << 3)
-#define ULPI_CARKIT_CTRL_SPKLEFTEN		(1 << 4)
-#define ULPI_CARKIT_CTRL_SPKRIGHTEN		(1 << 5)
-#define ULPI_CARKIT_CTRL_MICEN			(1 << 6)
-
-/* Carkit Interrupt Enable */
-#define ULPI_CARKIT_INT_EN_IDFLOAT_RISE		(1 << 0)
-#define ULPI_CARKIT_INT_EN_IDFLOAT_FALL		(1 << 1)
-#define ULPI_CARKIT_INT_EN_CARINTDET		(1 << 2)
-#define ULPI_CARKIT_INT_EN_DP_RISE		(1 << 3)
-#define ULPI_CARKIT_INT_EN_DP_FALL		(1 << 4)
-
-/* Carkit Interrupt Status and
- * Carkit Interrupt Latch
- */
-#define ULPI_CARKIT_INT_IDFLOAT			(1 << 0)
-#define ULPI_CARKIT_INT_CARINTDET		(1 << 1)
-#define ULPI_CARKIT_INT_DP			(1 << 2)
-
-/* Carkit Pulse Control*/
-#define ULPI_CARKIT_PLS_CTRL_TXPLSEN		(1 << 0)
-#define ULPI_CARKIT_PLS_CTRL_RXPLSEN		(1 << 1)
-#define ULPI_CARKIT_PLS_CTRL_SPKRLEFT_BIASEN	(1 << 2)
-#define ULPI_CARKIT_PLS_CTRL_SPKRRIGHT_BIASEN	(1 << 3)
-
-/*-------------------------------------------------------------------------*/
-
 #if IS_ENABLED(CONFIG_USB_ULPI)
 struct usb_phy *otg_ulpi_create(struct usb_phy_io_ops *ops,
 					unsigned int flags);
diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c
index fce36d0..ada8417 100644
--- a/scripts/mod/devicetable-offsets.c
+++ b/scripts/mod/devicetable-offsets.c
@@ -189,5 +189,9 @@ int main(void)
 	DEVID_FIELD(rio_device_id, asm_did);
 	DEVID_FIELD(rio_device_id, asm_vid);
 
+	DEVID(ulpi_device_id);
+	DEVID_FIELD(ulpi_device_id, vendor);
+	DEVID_FIELD(ulpi_device_id, product);
+
 	return 0;
 }
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 78691d5..a7a8560 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -1192,6 +1192,19 @@ static int do_rio_entry(const char *filename,
 }
 ADD_TO_DEVTABLE("rapidio", rio_device_id, do_rio_entry);
 
+/* Looks like: ulpi:vNpN */
+static int do_ulpi_entry(const char *filename, void *symval,
+			 char *alias)
+{
+	DEF_FIELD(symval, ulpi_device_id, vendor);
+	DEF_FIELD(symval, ulpi_device_id, product);
+
+	sprintf(alias, "ulpi:v%04xp%04x", vendor, product);
+
+	return 1;
+}
+ADD_TO_DEVTABLE("ulpi", ulpi_device_id, do_ulpi_entry);
+
 /* Does namelen bytes of name exactly match the symbol? */
 static bool sym_is(const char *name, unsigned namelen, const char *symbol)
 {
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCHv3 02/11] usb: dwc3: USB2 PHY register access bits
  2015-04-28 13:24 [PATCHv3 00/12] usb: ulpi bus Heikki Krogerus
  2015-04-28 13:24 ` [PATCHv3 01/11] usb: add bus type for USB ULPI Heikki Krogerus
@ 2015-04-28 13:24 ` Heikki Krogerus
  2015-04-28 13:24 ` [PATCHv3 03/11] usb: dwc3: ULPI or UTMI+ select Heikki Krogerus
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 32+ messages in thread
From: Heikki Krogerus @ 2015-04-28 13:24 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: David Cohen, Greg Kroah-Hartman, Stephen Boyd, Baolu Lu,
	Paul Bolle, linux-usb, linux-kernel

Definitions for Global USB2 PHY Vendor Control Register
bits. We will need them to access ULPI PHY registers later.

Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Acked-by: David Cohen <david.a.cohen@linux.intel.com>
---
 drivers/usb/dwc3/core.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index fdab715..747805d 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -174,6 +174,14 @@
 #define DWC3_GUSB2PHYCFG_PHYSOFTRST	(1 << 31)
 #define DWC3_GUSB2PHYCFG_SUSPHY		(1 << 6)
 
+/* Global USB2 PHY Vendor Control Register */
+#define DWC3_GUSB2PHYACC_NEWREGREQ	(1 << 25)
+#define DWC3_GUSB2PHYACC_BUSY		(1 << 23)
+#define DWC3_GUSB2PHYACC_WRITE		(1 << 22)
+#define DWC3_GUSB2PHYACC_ADDR(n)	(n << 16)
+#define DWC3_GUSB2PHYACC_EXTEND_ADDR(n)	(n << 8)
+#define DWC3_GUSB2PHYACC_DATA(n)	(n & 0xff)
+
 /* Global USB3 PIPE Control Register */
 #define DWC3_GUSB3PIPECTL_PHYSOFTRST	(1 << 31)
 #define DWC3_GUSB3PIPECTL_U2SSINP3OK	(1 << 29)
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCHv3 03/11] usb: dwc3: ULPI or UTMI+ select
  2015-04-28 13:24 [PATCHv3 00/12] usb: ulpi bus Heikki Krogerus
  2015-04-28 13:24 ` [PATCHv3 01/11] usb: add bus type for USB ULPI Heikki Krogerus
  2015-04-28 13:24 ` [PATCHv3 02/11] usb: dwc3: USB2 PHY register access bits Heikki Krogerus
@ 2015-04-28 13:24 ` Heikki Krogerus
  2015-04-28 13:24 ` [PATCHv3 04/11] usb: dwc3: store driver data earlier Heikki Krogerus
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 32+ messages in thread
From: Heikki Krogerus @ 2015-04-28 13:24 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: David Cohen, Greg Kroah-Hartman, Stephen Boyd, Baolu Lu,
	Paul Bolle, linux-usb, linux-kernel

Make selection between ULPI and UTMI+ interfaces possible by
providing definition for the bit in Global USB2 PHY
Configuration Register that controls it.

Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Acked-by: David Cohen <david.a.cohen@linux.intel.com>
---
 drivers/usb/dwc3/core.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 747805d..c6eafaa 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -173,6 +173,7 @@
 /* Global USB2 PHY Configuration Register */
 #define DWC3_GUSB2PHYCFG_PHYSOFTRST	(1 << 31)
 #define DWC3_GUSB2PHYCFG_SUSPHY		(1 << 6)
+#define DWC3_GUSB2PHYCFG_ULPI_UTMI	(1 << 4)
 
 /* Global USB2 PHY Vendor Control Register */
 #define DWC3_GUSB2PHYACC_NEWREGREQ	(1 << 25)
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCHv3 04/11] usb: dwc3: store driver data earlier
  2015-04-28 13:24 [PATCHv3 00/12] usb: ulpi bus Heikki Krogerus
                   ` (2 preceding siblings ...)
  2015-04-28 13:24 ` [PATCHv3 03/11] usb: dwc3: ULPI or UTMI+ select Heikki Krogerus
@ 2015-04-28 13:24 ` Heikki Krogerus
  2015-04-28 13:24 ` [PATCHv3 05/11] usb: dwc3: cache hwparams earlier Heikki Krogerus
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 32+ messages in thread
From: Heikki Krogerus @ 2015-04-28 13:24 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: David Cohen, Greg Kroah-Hartman, Stephen Boyd, Baolu Lu,
	Paul Bolle, linux-usb, linux-kernel

We need to store it before phys are handled, so we can later
use it in ULPI interface support code.

Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Acked-by: David Cohen <david.a.cohen@linux.intel.com>
---
 drivers/usb/dwc3/core.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 2bbab3d..c7734ed 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -875,12 +875,13 @@ static int dwc3_probe(struct platform_device *pdev)
 	dwc->hird_threshold = hird_threshold
 		| (dwc->is_utmi_l1_suspend << 4);
 
+	platform_set_drvdata(pdev, dwc);
+
 	ret = dwc3_core_get_phy(dwc);
 	if (ret)
 		goto err0;
 
 	spin_lock_init(&dwc->lock);
-	platform_set_drvdata(pdev, dwc);
 
 	if (!dev->dma_mask) {
 		dev->dma_mask = dev->parent->dma_mask;
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCHv3 05/11] usb: dwc3: cache hwparams earlier
  2015-04-28 13:24 [PATCHv3 00/12] usb: ulpi bus Heikki Krogerus
                   ` (3 preceding siblings ...)
  2015-04-28 13:24 ` [PATCHv3 04/11] usb: dwc3: store driver data earlier Heikki Krogerus
@ 2015-04-28 13:24 ` Heikki Krogerus
  2015-04-28 13:24 ` [PATCHv3 06/11] usb: dwc3: soft reset to it's own function Heikki Krogerus
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 32+ messages in thread
From: Heikki Krogerus @ 2015-04-28 13:24 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: David Cohen, Greg Kroah-Hartman, Stephen Boyd, Baolu Lu,
	Paul Bolle, linux-usb, linux-kernel

So they are available when ULPI interface support is added.

Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Acked-by: David Cohen <david.a.cohen@linux.intel.com>
---
 drivers/usb/dwc3/core.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index c7734ed..104b236 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -876,6 +876,7 @@ static int dwc3_probe(struct platform_device *pdev)
 		| (dwc->is_utmi_l1_suspend << 4);
 
 	platform_set_drvdata(pdev, dwc);
+	dwc3_cache_hwparams(dwc);
 
 	ret = dwc3_core_get_phy(dwc);
 	if (ret)
@@ -893,8 +894,6 @@ static int dwc3_probe(struct platform_device *pdev)
 	pm_runtime_get_sync(dev);
 	pm_runtime_forbid(dev);
 
-	dwc3_cache_hwparams(dwc);
-
 	ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE);
 	if (ret) {
 		dev_err(dwc->dev, "failed to allocate event buffers\n");
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCHv3 06/11] usb: dwc3: soft reset to it's own function
  2015-04-28 13:24 [PATCHv3 00/12] usb: ulpi bus Heikki Krogerus
                   ` (4 preceding siblings ...)
  2015-04-28 13:24 ` [PATCHv3 05/11] usb: dwc3: cache hwparams earlier Heikki Krogerus
@ 2015-04-28 13:24 ` Heikki Krogerus
  2015-04-28 17:22   ` Felipe Balbi
  2015-04-28 13:24 ` [PATCHv3 07/11] usb: dwc3: setup phys earlier Heikki Krogerus
                   ` (5 subsequent siblings)
  11 siblings, 1 reply; 32+ messages in thread
From: Heikki Krogerus @ 2015-04-28 13:24 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: David Cohen, Greg Kroah-Hartman, Stephen Boyd, Baolu Lu,
	Paul Bolle, linux-usb, linux-kernel

So it can be called from other places later.

Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Acked-by: David Cohen <david.a.cohen@linux.intel.com>
---
 drivers/usb/dwc3/core.c | 46 ++++++++++++++++++++++++++++++----------------
 1 file changed, 30 insertions(+), 16 deletions(-)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 104b236..921f181 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -117,6 +117,33 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc)
 }
 
 /**
+ * dwc3_soft_reset - Issue soft reset
+ * @dwc: Pointer to our controller context structure
+ */
+static int dwc3_soft_reset(struct dwc3 *dwc)
+{
+	unsigned long timeout;
+	u32 reg;
+
+	timeout = jiffies + msecs_to_jiffies(500);
+	dwc3_writel(dwc->regs, DWC3_DCTL, DWC3_DCTL_CSFTRST);
+	do {
+		reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+		if (!(reg & DWC3_DCTL_CSFTRST))
+			break;
+
+		if (time_after(jiffies, timeout)) {
+			dev_err(dwc->dev, "Reset Timed Out\n");
+			return -ETIMEDOUT;
+		}
+
+		cpu_relax();
+	} while (true);
+
+	return 0;
+}
+
+/**
  * dwc3_free_one_event_buffer - Frees one event buffer
  * @dwc: Pointer to our controller context structure
  * @evt: Pointer to event buffer to be freed
@@ -438,7 +465,6 @@ static void dwc3_phy_setup(struct dwc3 *dwc)
  */
 static int dwc3_core_init(struct dwc3 *dwc)
 {
-	unsigned long		timeout;
 	u32			hwparams4 = dwc->hwparams.hwparams4;
 	u32			reg;
 	int			ret;
@@ -466,21 +492,9 @@ static int dwc3_core_init(struct dwc3 *dwc)
 	}
 
 	/* issue device SoftReset too */
-	timeout = jiffies + msecs_to_jiffies(500);
-	dwc3_writel(dwc->regs, DWC3_DCTL, DWC3_DCTL_CSFTRST);
-	do {
-		reg = dwc3_readl(dwc->regs, DWC3_DCTL);
-		if (!(reg & DWC3_DCTL_CSFTRST))
-			break;
-
-		if (time_after(jiffies, timeout)) {
-			dev_err(dwc->dev, "Reset Timed Out\n");
-			ret = -ETIMEDOUT;
-			goto err0;
-		}
-
-		cpu_relax();
-	} while (true);
+	ret = dwc3_soft_reset(dwc);
+	if (ret)
+		goto err0;
 
 	ret = dwc3_core_soft_reset(dwc);
 	if (ret)
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCHv3 07/11] usb: dwc3: setup phys earlier
  2015-04-28 13:24 [PATCHv3 00/12] usb: ulpi bus Heikki Krogerus
                   ` (5 preceding siblings ...)
  2015-04-28 13:24 ` [PATCHv3 06/11] usb: dwc3: soft reset to it's own function Heikki Krogerus
@ 2015-04-28 13:24 ` Heikki Krogerus
  2015-04-28 13:24 ` [PATCHv3 08/11] usb: dwc3: add hsphy_interface property Heikki Krogerus
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 32+ messages in thread
From: Heikki Krogerus @ 2015-04-28 13:24 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: David Cohen, Greg Kroah-Hartman, Stephen Boyd, Baolu Lu,
	Paul Bolle, linux-usb, linux-kernel

This allows dwc3_phy_setup() to be more useful later. There
is nothing preventing the PHY configuration registers from
being programmed early. They do not loose their context in
soft reset.

There are however other PHY related operations that should
be executed before the driver request handles to the PHYs,
such as registering DWC3's ULPI interface, which can now be
done in dwc3_phy_setup().

Also, if there ever was need for the two 100ms delays in
dwc3_phy_setup() there isn't anymore. The PHYs are now reset
after the PHY interfaces are setup.

Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Acked-by: David Cohen <david.a.cohen@linux.intel.com>
---
 drivers/usb/dwc3/core.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 921f181..6b02e12 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -436,8 +436,6 @@ static void dwc3_phy_setup(struct dwc3 *dwc)
 
 	dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
 
-	mdelay(100);
-
 	reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
 
 	/*
@@ -453,8 +451,6 @@ static void dwc3_phy_setup(struct dwc3 *dwc)
 		reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
 
 	dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
-
-	mdelay(100);
 }
 
 /**
@@ -569,8 +565,6 @@ static int dwc3_core_init(struct dwc3 *dwc)
 
 	dwc3_writel(dwc->regs, DWC3_GCTL, reg);
 
-	dwc3_phy_setup(dwc);
-
 	ret = dwc3_alloc_scratch_buffers(dwc);
 	if (ret)
 		goto err1;
@@ -892,6 +886,8 @@ static int dwc3_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, dwc);
 	dwc3_cache_hwparams(dwc);
 
+	dwc3_phy_setup(dwc);
+
 	ret = dwc3_core_get_phy(dwc);
 	if (ret)
 		goto err0;
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCHv3 08/11] usb: dwc3: add hsphy_interface property
  2015-04-28 13:24 [PATCHv3 00/12] usb: ulpi bus Heikki Krogerus
                   ` (6 preceding siblings ...)
  2015-04-28 13:24 ` [PATCHv3 07/11] usb: dwc3: setup phys earlier Heikki Krogerus
@ 2015-04-28 13:24 ` Heikki Krogerus
  2015-04-28 17:13   ` Felipe Balbi
  2015-04-28 13:24 ` [PATCHv3 09/11] usb: dwc3: pci: add quirk for Baytrails Heikki Krogerus
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 32+ messages in thread
From: Heikki Krogerus @ 2015-04-28 13:24 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: David Cohen, Greg Kroah-Hartman, Stephen Boyd, Baolu Lu,
	Paul Bolle, linux-usb, linux-kernel

Platforms that have configured DWC_USB3_HSPHY_INTERFACE with
value 3, i.e. UTMI+ and ULPI, need to inform the driver of
the actual HSPHY interface type with the property. "utmi" if
the interface is UTMI+ or "ulpi" if the interface is ULPI.

Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Acked-by: David Cohen <david.a.cohen@linux.intel.com>
---
 Documentation/devicetree/bindings/usb/dwc3.txt |  2 ++
 drivers/usb/dwc3/core.c                        | 29 ++++++++++++++++++++++++--
 drivers/usb/dwc3/core.h                        |  3 +++
 drivers/usb/dwc3/platform_data.h               |  2 ++
 4 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
index 5cc3643..0815eac 100644
--- a/Documentation/devicetree/bindings/usb/dwc3.txt
+++ b/Documentation/devicetree/bindings/usb/dwc3.txt
@@ -38,6 +38,8 @@ Optional properties:
  - snps,is-utmi-l1-suspend: true when DWC3 asserts output signal
 			utmi_l1_suspend_n, false when asserts utmi_sleep_n
  - snps,hird-threshold: HIRD threshold
+ - snps,hsphy_interface: High-Speed PHY interface selection between "utmi" for
+   UTMI+ and "ulpi" for ULPI when the DWC_USB3_HSPHY_INTERFACE has value 3.
 
 This is usually a subnode to DWC3 glue to which it is connected.
 
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 6b02e12..b229ba1 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -395,9 +395,10 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc)
  * dwc3_phy_setup - Configure USB PHY Interface of DWC3 Core
  * @dwc: Pointer to our controller context structure
  */
-static void dwc3_phy_setup(struct dwc3 *dwc)
+static int dwc3_phy_setup(struct dwc3 *dwc)
 {
 	u32 reg;
+	int ret;
 
 	reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
 
@@ -438,6 +439,22 @@ static void dwc3_phy_setup(struct dwc3 *dwc)
 
 	reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
 
+	/* Select the HS PHY interface */
+	switch (DWC3_GHWPARAMS3_HSPHY_IFC(dwc->hwparams.hwparams3)) {
+	case DWC3_GHWPARAMS3_HSPHY_IFC_UTMI_ULPI:
+		if (!strncmp(dwc->hsphy_interface, "utmi", 4)) {
+			reg &= ~DWC3_GUSB2PHYCFG_ULPI_UTMI;
+		} else if (!strncmp(dwc->hsphy_interface, "ulpi", 4)) {
+			reg |= DWC3_GUSB2PHYCFG_ULPI_UTMI;
+		} else {
+			dev_err(dwc->dev, "HSPHY Interface not defined\n");
+			return -EINVAL;
+		}
+		/* FALLTHROUGH */
+	default:
+		break;
+	}
+
 	/*
 	 * Above 1.94a, it is recommended to set DWC3_GUSB2PHYCFG_SUSPHY to
 	 * '0' during coreConsultant configuration. So default value will
@@ -451,6 +468,8 @@ static void dwc3_phy_setup(struct dwc3 *dwc)
 		reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
 
 	dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+
+	return 0;
 }
 
 /**
@@ -844,6 +863,8 @@ static int dwc3_probe(struct platform_device *pdev)
 				"snps,tx_de_emphasis_quirk");
 		of_property_read_u8(node, "snps,tx_de_emphasis",
 				&tx_de_emphasis);
+		of_property_read_string(node, "snps,hsphy_interface",
+					&dwc->hsphy_interface);
 	} else if (pdata) {
 		dwc->maximum_speed = pdata->maximum_speed;
 		dwc->has_lpm_erratum = pdata->has_lpm_erratum;
@@ -871,6 +892,8 @@ static int dwc3_probe(struct platform_device *pdev)
 		dwc->tx_de_emphasis_quirk = pdata->tx_de_emphasis_quirk;
 		if (pdata->tx_de_emphasis)
 			tx_de_emphasis = pdata->tx_de_emphasis;
+
+		dwc->hsphy_interface = pdata->hsphy_interface;
 	}
 
 	/* default to superspeed if no maximum_speed passed */
@@ -886,7 +909,9 @@ static int dwc3_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, dwc);
 	dwc3_cache_hwparams(dwc);
 
-	dwc3_phy_setup(dwc);
+	ret = dwc3_phy_setup(dwc);
+	if (ret)
+		goto err0;
 
 	ret = dwc3_core_get_phy(dwc);
 	if (ret)
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index c6eafaa..7b3ab64 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -682,6 +682,7 @@ struct dwc3_scratchpad_array {
  * @test_mode_nr: test feature selector
  * @lpm_nyet_threshold: LPM NYET response threshold
  * @hird_threshold: HIRD threshold
+ * @hsphy_interface: "utmi" or "ulpi"
  * @delayed_status: true when gadget driver asks for delayed status
  * @ep0_bounced: true when we used bounce buffer
  * @ep0_expect_in: true when we expect a DATA IN transfer
@@ -809,6 +810,8 @@ struct dwc3 {
 	u8			lpm_nyet_threshold;
 	u8			hird_threshold;
 
+	const char		*hsphy_interface;
+
 	unsigned		delayed_status:1;
 	unsigned		ep0_bounced:1;
 	unsigned		ep0_expect_in:1;
diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h
index a2bd464..d3614ec 100644
--- a/drivers/usb/dwc3/platform_data.h
+++ b/drivers/usb/dwc3/platform_data.h
@@ -45,4 +45,6 @@ struct dwc3_platform_data {
 
 	unsigned tx_de_emphasis_quirk:1;
 	unsigned tx_de_emphasis:2;
+
+	const char *hsphy_interface;
 };
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCHv3 09/11] usb: dwc3: pci: add quirk for Baytrails
  2015-04-28 13:24 [PATCHv3 00/12] usb: ulpi bus Heikki Krogerus
                   ` (7 preceding siblings ...)
  2015-04-28 13:24 ` [PATCHv3 08/11] usb: dwc3: add hsphy_interface property Heikki Krogerus
@ 2015-04-28 13:24 ` Heikki Krogerus
  2015-04-28 13:24 ` [PATCHv3 10/11] phy: helpers for USB ULPI PHY registering Heikki Krogerus
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 32+ messages in thread
From: Heikki Krogerus @ 2015-04-28 13:24 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: David Cohen, Greg Kroah-Hartman, Stephen Boyd, Baolu Lu,
	Paul Bolle, linux-usb, linux-kernel

On some BYT platforms the USB2 PHY needs to be put into
operational mode by the controller driver with GPIOs
controlling the PHYs reset and cs signals.

Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
---
 drivers/usb/dwc3/dwc3-pci.c | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index b773fb5..0235f46 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -21,6 +21,8 @@
 #include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/platform_device.h>
+#include <linux/gpio/consumer.h>
+#include <linux/acpi.h>
 
 #include "platform_data.h"
 
@@ -31,6 +33,15 @@
 #define PCI_DEVICE_ID_INTEL_SPTLP	0x9d30
 #define PCI_DEVICE_ID_INTEL_SPTH	0xa130
 
+static const struct acpi_gpio_params reset_gpios = { 0, 0, false };
+static const struct acpi_gpio_params cs_gpios = { 1, 0, false };
+
+static const struct acpi_gpio_mapping acpi_dwc3_byt_gpios[] = {
+	{ "reset-gpios", &reset_gpios, 1 },
+	{ "cs-gpios", &cs_gpios, 1 },
+	{ },
+};
+
 static int dwc3_pci_quirks(struct pci_dev *pdev)
 {
 	if (pdev->vendor == PCI_VENDOR_ID_AMD &&
@@ -65,6 +76,30 @@ static int dwc3_pci_quirks(struct pci_dev *pdev)
 						sizeof(pdata));
 	}
 
+	if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
+	    pdev->device == PCI_DEVICE_ID_INTEL_BYT) {
+		struct gpio_desc *gpio;
+
+		acpi_dev_add_driver_gpios(ACPI_COMPANION(&pdev->dev),
+					  acpi_dwc3_byt_gpios);
+
+		/* These GPIOs will turn on the USB2 PHY */
+		gpio = gpiod_get(&pdev->dev, "cs");
+		if (!IS_ERR(gpio)) {
+			gpiod_direction_output(gpio, 0);
+			gpiod_set_value_cansleep(gpio, 1);
+			gpiod_put(gpio);
+		}
+
+		gpio = gpiod_get(&pdev->dev, "reset");
+		if (!IS_ERR(gpio)) {
+			gpiod_direction_output(gpio, 0);
+			gpiod_set_value_cansleep(gpio, 1);
+			gpiod_put(gpio);
+			msleep(10);
+		}
+	}
+
 	return 0;
 }
 
@@ -128,6 +163,7 @@ err:
 
 static void dwc3_pci_remove(struct pci_dev *pci)
 {
+	acpi_dev_remove_driver_gpios(ACPI_COMPANION(&pci->dev));
 	platform_device_unregister(pci_get_drvdata(pci));
 }
 
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCHv3 10/11] phy: helpers for USB ULPI PHY registering
  2015-04-28 13:24 [PATCHv3 00/12] usb: ulpi bus Heikki Krogerus
                   ` (8 preceding siblings ...)
  2015-04-28 13:24 ` [PATCHv3 09/11] usb: dwc3: pci: add quirk for Baytrails Heikki Krogerus
@ 2015-04-28 13:24 ` Heikki Krogerus
  2015-04-28 13:24 ` [PATCHv3 11/11] phy: add driver for TI TUSB1210 ULPI PHY Heikki Krogerus
  2015-04-28 17:17 ` [PATCHv3 00/12] usb: ulpi bus Felipe Balbi
  11 siblings, 0 replies; 32+ messages in thread
From: Heikki Krogerus @ 2015-04-28 13:24 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: David Cohen, Greg Kroah-Hartman, Stephen Boyd, Baolu Lu,
	Paul Bolle, linux-usb, linux-kernel, Kishon Vijay Abraham I

ULPI PHYs need to be bound to their controllers with a
lookup. This adds helpers that the ULPI drivers can use to
do both, the registration of the PHY and the lookup, at the
same time.

Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Acked-by: David Cohen <david.a.cohen@linux.intel.com>
Cc: Kishon Vijay Abraham I <kishon@ti.com>
---
 drivers/phy/ulpi_phy.h | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)
 create mode 100644 drivers/phy/ulpi_phy.h

diff --git a/drivers/phy/ulpi_phy.h b/drivers/phy/ulpi_phy.h
new file mode 100644
index 0000000..ac49fb6
--- /dev/null
+++ b/drivers/phy/ulpi_phy.h
@@ -0,0 +1,31 @@
+#include <linux/phy/phy.h>
+
+/**
+ * Helper that registers PHY for a ULPI device and adds a lookup for binding it
+ * and it's controller, which is always the parent.
+ */
+static inline struct phy
+*ulpi_phy_create(struct ulpi *ulpi, struct phy_ops *ops)
+{
+	struct phy *phy;
+	int ret;
+
+	phy = phy_create(&ulpi->dev, NULL, ops);
+	if (IS_ERR(phy))
+		return phy;
+
+	ret = phy_create_lookup(phy, "usb2-phy", dev_name(ulpi->dev.parent));
+	if (ret) {
+		phy_destroy(phy);
+		return ERR_PTR(ret);
+	}
+
+	return phy;
+}
+
+/* Remove a PHY that was created with ulpi_phy_create() and it's lookup. */
+static inline void ulpi_phy_destroy(struct ulpi *ulpi, struct phy *phy)
+{
+	phy_remove_lookup(phy, "usb2-phy", dev_name(ulpi->dev.parent));
+	phy_destroy(phy);
+}
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCHv3 11/11] phy: add driver for TI TUSB1210 ULPI PHY
  2015-04-28 13:24 [PATCHv3 00/12] usb: ulpi bus Heikki Krogerus
                   ` (9 preceding siblings ...)
  2015-04-28 13:24 ` [PATCHv3 10/11] phy: helpers for USB ULPI PHY registering Heikki Krogerus
@ 2015-04-28 13:24 ` Heikki Krogerus
  2015-04-28 17:17 ` [PATCHv3 00/12] usb: ulpi bus Felipe Balbi
  11 siblings, 0 replies; 32+ messages in thread
From: Heikki Krogerus @ 2015-04-28 13:24 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: David Cohen, Greg Kroah-Hartman, Stephen Boyd, Baolu Lu,
	Paul Bolle, linux-usb, linux-kernel, Kishon Vijay Abraham I

TUSB1210 ULPI PHY has vendor specific register for eye
diagram tuning. On some platforms the system firmware has
set optimized value to it. In order to not loose the
optimized value, the driver stores it during probe and
restores it every time the PHY is powered back on.

Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Acked-by: David Cohen <david.a.cohen@linux.intel.com>
Cc: Kishon Vijay Abraham I <kishon@ti.com>
---
 drivers/phy/Kconfig        |   7 +++
 drivers/phy/Makefile       |   1 +
 drivers/phy/phy-tusb1210.c | 153 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 161 insertions(+)
 create mode 100644 drivers/phy/phy-tusb1210.c

diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index a53bd5b..fceac96 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -309,4 +309,11 @@ config PHY_QCOM_UFS
 	help
 	  Support for UFS PHY on QCOM chipsets.
 
+config PHY_TUSB1210
+	tristate "TI TUSB1210 ULPI PHY module"
+	depends on USB_ULPI_BUS
+	select GENERIC_PHY
+	help
+	  Support for TI TUSB1210 USB ULPI PHY.
+
 endmenu
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index f126251..0a20418 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -40,3 +40,4 @@ obj-$(CONFIG_PHY_STIH41X_USB)		+= phy-stih41x-usb.o
 obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs.o
 obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs-qmp-20nm.o
 obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs-qmp-14nm.o
+obj-$(CONFIG_PHY_TUSB1210)		+= phy-tusb1210.o
diff --git a/drivers/phy/phy-tusb1210.c b/drivers/phy/phy-tusb1210.c
new file mode 100644
index 0000000..07efdd3
--- /dev/null
+++ b/drivers/phy/phy-tusb1210.c
@@ -0,0 +1,153 @@
+/**
+ * tusb1210.c - TUSB1210 USB ULPI PHY driver
+ *
+ * Copyright (C) 2015 Intel Corporation
+ *
+ * Author: Heikki Krogerus <heikki.krogerus@linux.intel.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/module.h>
+#include <linux/ulpi/driver.h>
+#include <linux/gpio/consumer.h>
+
+#include "ulpi_phy.h"
+
+#define TUSB1210_VENDOR_SPECIFIC2		0x80
+#define TUSB1210_VENDOR_SPECIFIC2_IHSTX_SHIFT	0
+#define TUSB1210_VENDOR_SPECIFIC2_ZHSDRV_SHIFT	4
+#define TUSB1210_VENDOR_SPECIFIC2_DP_SHIFT	6
+
+struct tusb1210 {
+	struct ulpi *ulpi;
+	struct phy *phy;
+	struct gpio_desc *gpio_reset;
+	struct gpio_desc *gpio_cs;
+	u8 vendor_specific2;
+};
+
+static int tusb1210_power_on(struct phy *phy)
+{
+	struct tusb1210 *tusb = phy_get_drvdata(phy);
+
+	gpiod_set_value_cansleep(tusb->gpio_reset, 1);
+	gpiod_set_value_cansleep(tusb->gpio_cs, 1);
+
+	/* Restore the optional eye diagram optimization value */
+	if (tusb->vendor_specific2)
+		ulpi_write(tusb->ulpi, TUSB1210_VENDOR_SPECIFIC2,
+			   tusb->vendor_specific2);
+
+	return 0;
+}
+
+static int tusb1210_power_off(struct phy *phy)
+{
+	struct tusb1210 *tusb = phy_get_drvdata(phy);
+
+	gpiod_set_value_cansleep(tusb->gpio_reset, 0);
+	gpiod_set_value_cansleep(tusb->gpio_cs, 0);
+
+	return 0;
+}
+
+static struct phy_ops phy_ops = {
+	.power_on = tusb1210_power_on,
+	.power_off = tusb1210_power_off,
+	.owner = THIS_MODULE,
+};
+
+static int tusb1210_probe(struct ulpi *ulpi)
+{
+	struct gpio_desc *gpio;
+	struct tusb1210 *tusb;
+	u8 val, reg;
+	int ret;
+
+	tusb = devm_kzalloc(&ulpi->dev, sizeof(*tusb), GFP_KERNEL);
+	if (!tusb)
+		return -ENOMEM;
+
+	gpio = devm_gpiod_get(&ulpi->dev, "reset");
+	if (!IS_ERR(gpio)) {
+		ret = gpiod_direction_output(gpio, 0);
+		if (ret)
+			return ret;
+		gpiod_set_value_cansleep(gpio, 1);
+		tusb->gpio_reset = gpio;
+	}
+
+	gpio = devm_gpiod_get(&ulpi->dev, "cs");
+	if (!IS_ERR(gpio)) {
+		ret = gpiod_direction_output(gpio, 0);
+		if (ret)
+			return ret;
+		gpiod_set_value_cansleep(gpio, 1);
+		tusb->gpio_cs = gpio;
+	}
+
+	/*
+	 * VENDOR_SPECIFIC2 register in TUSB1210 can be used for configuring eye
+	 * diagram optimization and DP/DM swap.
+	 */
+
+	/* High speed output drive strength configuration */
+	device_property_read_u8(&ulpi->dev, "ihstx", &val);
+	reg = val << TUSB1210_VENDOR_SPECIFIC2_IHSTX_SHIFT;
+
+	/* High speed output impedance configuration */
+	device_property_read_u8(&ulpi->dev, "zhsdrv", &val);
+	reg |= val << TUSB1210_VENDOR_SPECIFIC2_ZHSDRV_SHIFT;
+
+	/* DP/DM swap control */
+	device_property_read_u8(&ulpi->dev, "datapolarity", &val);
+	reg |= val << TUSB1210_VENDOR_SPECIFIC2_DP_SHIFT;
+
+	if (reg) {
+		ulpi_write(ulpi, TUSB1210_VENDOR_SPECIFIC2, reg);
+		tusb->vendor_specific2 = reg;
+	}
+
+	tusb->phy = ulpi_phy_create(ulpi, &phy_ops);
+	if (IS_ERR(tusb->phy))
+		return PTR_ERR(tusb->phy);
+
+	tusb->ulpi = ulpi;
+
+	phy_set_drvdata(tusb->phy, tusb);
+	ulpi_set_drvdata(ulpi, tusb);
+	return 0;
+}
+
+static void tusb1210_remove(struct ulpi *ulpi)
+{
+	struct tusb1210 *tusb = ulpi_get_drvdata(ulpi);
+
+	ulpi_phy_destroy(ulpi, tusb->phy);
+}
+
+#define TI_VENDOR_ID 0x0451
+
+static const struct ulpi_device_id tusb1210_ulpi_id[] = {
+	{ TI_VENDOR_ID, 0x1507, },
+	{ },
+};
+MODULE_DEVICE_TABLE(ulpi, tusb1210_ulpi_id);
+
+static struct ulpi_driver tusb1210_driver = {
+	.id_table = tusb1210_ulpi_id,
+	.probe = tusb1210_probe,
+	.remove = tusb1210_remove,
+	.driver = {
+		.name = "tusb1210",
+		.owner = THIS_MODULE,
+	},
+};
+
+module_ulpi_driver(tusb1210_driver);
+
+MODULE_AUTHOR("Intel Corporation");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("TUSB1210 ULPI PHY driver");
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* Re: [PATCHv3 08/11] usb: dwc3: add hsphy_interface property
  2015-04-28 13:24 ` [PATCHv3 08/11] usb: dwc3: add hsphy_interface property Heikki Krogerus
@ 2015-04-28 17:13   ` Felipe Balbi
  2015-04-29  8:04     ` Heikki Krogerus
  0 siblings, 1 reply; 32+ messages in thread
From: Felipe Balbi @ 2015-04-28 17:13 UTC (permalink / raw)
  To: Heikki Krogerus
  Cc: Felipe Balbi, David Cohen, Greg Kroah-Hartman, Stephen Boyd,
	Baolu Lu, Paul Bolle, linux-usb, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2803 bytes --]

On Tue, Apr 28, 2015 at 04:24:43PM +0300, Heikki Krogerus wrote:
> Platforms that have configured DWC_USB3_HSPHY_INTERFACE with
> value 3, i.e. UTMI+ and ULPI, need to inform the driver of
> the actual HSPHY interface type with the property. "utmi" if
> the interface is UTMI+ or "ulpi" if the interface is ULPI.
> 
> Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> Acked-by: David Cohen <david.a.cohen@linux.intel.com>
> ---
>  Documentation/devicetree/bindings/usb/dwc3.txt |  2 ++
>  drivers/usb/dwc3/core.c                        | 29 ++++++++++++++++++++++++--
>  drivers/usb/dwc3/core.h                        |  3 +++
>  drivers/usb/dwc3/platform_data.h               |  2 ++
>  4 files changed, 34 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
> index 5cc3643..0815eac 100644
> --- a/Documentation/devicetree/bindings/usb/dwc3.txt
> +++ b/Documentation/devicetree/bindings/usb/dwc3.txt
> @@ -38,6 +38,8 @@ Optional properties:
>   - snps,is-utmi-l1-suspend: true when DWC3 asserts output signal
>  			utmi_l1_suspend_n, false when asserts utmi_sleep_n
>   - snps,hird-threshold: HIRD threshold
> + - snps,hsphy_interface: High-Speed PHY interface selection between "utmi" for
> +   UTMI+ and "ulpi" for ULPI when the DWC_USB3_HSPHY_INTERFACE has value 3.
>  
>  This is usually a subnode to DWC3 glue to which it is connected.
>  
> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index 6b02e12..b229ba1 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -395,9 +395,10 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc)
>   * dwc3_phy_setup - Configure USB PHY Interface of DWC3 Core
>   * @dwc: Pointer to our controller context structure
>   */
> -static void dwc3_phy_setup(struct dwc3 *dwc)
> +static int dwc3_phy_setup(struct dwc3 *dwc)
>  {
>  	u32 reg;
> +	int ret;
>  
>  	reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
>  
> @@ -438,6 +439,22 @@ static void dwc3_phy_setup(struct dwc3 *dwc)
>  
>  	reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
>  
> +	/* Select the HS PHY interface */
> +	switch (DWC3_GHWPARAMS3_HSPHY_IFC(dwc->hwparams.hwparams3)) {
> +	case DWC3_GHWPARAMS3_HSPHY_IFC_UTMI_ULPI:
> +		if (!strncmp(dwc->hsphy_interface, "utmi", 4)) {
> +			reg &= ~DWC3_GUSB2PHYCFG_ULPI_UTMI;
> +		} else if (!strncmp(dwc->hsphy_interface, "ulpi", 4)) {
> +			reg |= DWC3_GUSB2PHYCFG_ULPI_UTMI;
> +		} else {
> +			dev_err(dwc->dev, "HSPHY Interface not defined\n");
> +			return -EINVAL;

instead of erroring out, just leave default value and convert this to a
dev_warn() or something similar. That way, older DTS will continue to
work.

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCHv3 00/12] usb: ulpi bus
  2015-04-28 13:24 [PATCHv3 00/12] usb: ulpi bus Heikki Krogerus
                   ` (10 preceding siblings ...)
  2015-04-28 13:24 ` [PATCHv3 11/11] phy: add driver for TI TUSB1210 ULPI PHY Heikki Krogerus
@ 2015-04-28 17:17 ` Felipe Balbi
  2015-04-29  8:21   ` Heikki Krogerus
  11 siblings, 1 reply; 32+ messages in thread
From: Felipe Balbi @ 2015-04-28 17:17 UTC (permalink / raw)
  To: Heikki Krogerus
  Cc: Felipe Balbi, David Cohen, Greg Kroah-Hartman, Stephen Boyd,
	Baolu Lu, Paul Bolle, linux-usb, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1280 bytes --]

Hi,

On Tue, Apr 28, 2015 at 04:24:35PM +0300, Heikki Krogerus wrote:
> Hi,
> 
> I took the liberty of adding David's ACK to everything except 9/12, including to
> the 1/12 (removing the module handling has no functional affect).
> 
> Changes since v2:
> - remove module handling from the bus driver as suggested by Paul Bolle.
> - reordered the gpio requests in BYT quirk as suggested by David Cohen.
> 
> Major changes since v1:
> - calling dwc3_phy_setup earlier and registering the ULPI interface there.
> - new property to dwc3 for selecting the interface in case of UTMI+ and ULPI as
>   suggested by Felipe
> - dwc3 soft reset before registration of the ULPI interface to sync the clocks
>   as suggested by David
> - Including support for the BYT boards that have the GPIOs controlling the reset
>   and cs signals.
> 
> Heikki Krogerus (12):
>   usb: add bus type for USB ULPI
>   usb: dwc3: USB2 PHY register access bits
>   usb: dwc3: ULPI or UTMI+ select
>   usb: dwc3: store driver data earlier
>   usb: dwc3: cache hwparams earlier
>   usb: dwc3: soft reset to it's own function
>   usb: dwc3: setup phys earlier

up to patch 7/12, I've applied to my testing/next. I'll wait for a
revised 8/12 before applying the rest.

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCHv3 06/11] usb: dwc3: soft reset to it's own function
  2015-04-28 13:24 ` [PATCHv3 06/11] usb: dwc3: soft reset to it's own function Heikki Krogerus
@ 2015-04-28 17:22   ` Felipe Balbi
  2015-04-29  8:16     ` Heikki Krogerus
  0 siblings, 1 reply; 32+ messages in thread
From: Felipe Balbi @ 2015-04-28 17:22 UTC (permalink / raw)
  To: Heikki Krogerus
  Cc: Felipe Balbi, David Cohen, Greg Kroah-Hartman, Stephen Boyd,
	Baolu Lu, Paul Bolle, linux-usb, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1110 bytes --]

On Tue, Apr 28, 2015 at 04:24:41PM +0300, Heikki Krogerus wrote:
> So it can be called from other places later.
> 
> Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> Acked-by: David Cohen <david.a.cohen@linux.intel.com>
> ---
>  drivers/usb/dwc3/core.c | 46 ++++++++++++++++++++++++++++++----------------
>  1 file changed, 30 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index 104b236..921f181 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -117,6 +117,33 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc)
>  }
>  
>  /**
> + * dwc3_soft_reset - Issue soft reset
> + * @dwc: Pointer to our controller context structure
> + */
> +static int dwc3_soft_reset(struct dwc3 *dwc)

I don't see this being called anywhere else in your series and I would
really like to know when we would need to reset the core again ?

I don't oppose to having this split to own function because I rather
like how it looks, but I don't want to reset the IP needlessly either.

cheers

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCHv3 08/11] usb: dwc3: add hsphy_interface property
  2015-04-28 17:13   ` Felipe Balbi
@ 2015-04-29  8:04     ` Heikki Krogerus
  0 siblings, 0 replies; 32+ messages in thread
From: Heikki Krogerus @ 2015-04-29  8:04 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: David Cohen, Greg Kroah-Hartman, Stephen Boyd, Baolu Lu,
	Paul Bolle, linux-usb, linux-kernel

> > +	/* Select the HS PHY interface */
> > +	switch (DWC3_GHWPARAMS3_HSPHY_IFC(dwc->hwparams.hwparams3)) {
> > +	case DWC3_GHWPARAMS3_HSPHY_IFC_UTMI_ULPI:
> > +		if (!strncmp(dwc->hsphy_interface, "utmi", 4)) {
> > +			reg &= ~DWC3_GUSB2PHYCFG_ULPI_UTMI;
> > +		} else if (!strncmp(dwc->hsphy_interface, "ulpi", 4)) {
> > +			reg |= DWC3_GUSB2PHYCFG_ULPI_UTMI;
> > +		} else {
> > +			dev_err(dwc->dev, "HSPHY Interface not defined\n");
> > +			return -EINVAL;
> 
> instead of erroring out, just leave default value and convert this to a
> dev_warn() or something similar. That way, older DTS will continue to
> work.

OK, I'll change it.

Thanks,

-- 
heikki

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCHv3 06/11] usb: dwc3: soft reset to it's own function
  2015-04-28 17:22   ` Felipe Balbi
@ 2015-04-29  8:16     ` Heikki Krogerus
  0 siblings, 0 replies; 32+ messages in thread
From: Heikki Krogerus @ 2015-04-29  8:16 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: David Cohen, Greg Kroah-Hartman, Stephen Boyd, Baolu Lu,
	Paul Bolle, linux-usb, linux-kernel

> > + * dwc3_soft_reset - Issue soft reset
> > + * @dwc: Pointer to our controller context structure
> > + */
> > +static int dwc3_soft_reset(struct dwc3 *dwc)
> 
> I don't see this being called anywhere else in your series and I would
> really like to know when we would need to reset the core again ?
> 
> I don't oppose to having this split to own function because I rather
> like how it looks, but I don't want to reset the IP needlessly either.

This series seems to be missing the last patch for dwc3, where I
actually add the ULPI support to dwc3 :-p. How have I managed to
prepare this series with one patch from the middle missing?!?! The
cover letter seems to be correct.

I'll resend the patches 8-12/12.


Thanks,

-- 
heikki

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCHv3 00/12] usb: ulpi bus
  2015-04-28 17:17 ` [PATCHv3 00/12] usb: ulpi bus Felipe Balbi
@ 2015-04-29  8:21   ` Heikki Krogerus
  2015-04-29  8:30     ` [PATCHv3 08/12] usb: dwc3: add hsphy_interface property Heikki Krogerus
                       ` (4 more replies)
  0 siblings, 5 replies; 32+ messages in thread
From: Heikki Krogerus @ 2015-04-29  8:21 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: David Cohen, Greg Kroah-Hartman, Stephen Boyd, Baolu Lu,
	Paul Bolle, linux-usb, linux-kernel

On Tue, Apr 28, 2015 at 12:17:34PM -0500, Felipe Balbi wrote:
> Hi,
> 
> On Tue, Apr 28, 2015 at 04:24:35PM +0300, Heikki Krogerus wrote:
> > Hi,
> > 
> > I took the liberty of adding David's ACK to everything except 9/12, including to
> > the 1/12 (removing the module handling has no functional affect).
> > 
> > Changes since v2:
> > - remove module handling from the bus driver as suggested by Paul Bolle.
> > - reordered the gpio requests in BYT quirk as suggested by David Cohen.
> > 
> > Major changes since v1:
> > - calling dwc3_phy_setup earlier and registering the ULPI interface there.
> > - new property to dwc3 for selecting the interface in case of UTMI+ and ULPI as
> >   suggested by Felipe
> > - dwc3 soft reset before registration of the ULPI interface to sync the clocks
> >   as suggested by David
> > - Including support for the BYT boards that have the GPIOs controlling the reset
> >   and cs signals.
> > 
> > Heikki Krogerus (12):
> >   usb: add bus type for USB ULPI
> >   usb: dwc3: USB2 PHY register access bits
> >   usb: dwc3: ULPI or UTMI+ select
> >   usb: dwc3: store driver data earlier
> >   usb: dwc3: cache hwparams earlier
> >   usb: dwc3: soft reset to it's own function
> >   usb: dwc3: setup phys earlier
> 
> up to patch 7/12, I've applied to my testing/next. I'll wait for a
> revised 8/12 before applying the rest.

OK. I'll re-send the patches 8-12/12 here with the revised version of
8/12 and the missing 10/12 (usb: dwc3: add ULPI interface support).


Thanks,

-- 
heikki

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCHv3 08/12] usb: dwc3: add hsphy_interface property
  2015-04-29  8:21   ` Heikki Krogerus
@ 2015-04-29  8:30     ` Heikki Krogerus
  2015-04-29 15:03       ` Felipe Balbi
  2015-04-29  8:30     ` [PATCHv3 09/12] usb: dwc3: pci: add quirk for Baytrails Heikki Krogerus
                       ` (3 subsequent siblings)
  4 siblings, 1 reply; 32+ messages in thread
From: Heikki Krogerus @ 2015-04-29  8:30 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: David Cohen, Greg Kroah-Hartman, Stephen Boyd, Baolu Lu,
	Paul Bolle, linux-usb, linux-kernel

Platforms that have configured DWC_USB3_HSPHY_INTERFACE with
value 3, i.e. UTMI+ and ULPI, need to inform the driver of
the actual HSPHY interface type with the property. "utmi" if
the interface is UTMI+ or "ulpi" if the interface is ULPI.

Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Acked-by: David Cohen <david.a.cohen@linux.intel.com>
---
 Documentation/devicetree/bindings/usb/dwc3.txt |  2 ++
 drivers/usb/dwc3/core.c                        | 29 ++++++++++++++++++++++++--
 drivers/usb/dwc3/core.h                        |  3 +++
 drivers/usb/dwc3/platform_data.h               |  2 ++
 4 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
index 5cc3643..0815eac 100644
--- a/Documentation/devicetree/bindings/usb/dwc3.txt
+++ b/Documentation/devicetree/bindings/usb/dwc3.txt
@@ -38,6 +38,8 @@ Optional properties:
  - snps,is-utmi-l1-suspend: true when DWC3 asserts output signal
 			utmi_l1_suspend_n, false when asserts utmi_sleep_n
  - snps,hird-threshold: HIRD threshold
+ - snps,hsphy_interface: High-Speed PHY interface selection between "utmi" for
+   UTMI+ and "ulpi" for ULPI when the DWC_USB3_HSPHY_INTERFACE has value 3.
 
 This is usually a subnode to DWC3 glue to which it is connected.
 
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 6b02e12..fdeff5e 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -395,9 +395,10 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc)
  * dwc3_phy_setup - Configure USB PHY Interface of DWC3 Core
  * @dwc: Pointer to our controller context structure
  */
-static void dwc3_phy_setup(struct dwc3 *dwc)
+static int dwc3_phy_setup(struct dwc3 *dwc)
 {
 	u32 reg;
+	int ret;
 
 	reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
 
@@ -438,6 +439,22 @@ static void dwc3_phy_setup(struct dwc3 *dwc)
 
 	reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
 
+	/* Select the HS PHY interface */
+	switch (DWC3_GHWPARAMS3_HSPHY_IFC(dwc->hwparams.hwparams3)) {
+	case DWC3_GHWPARAMS3_HSPHY_IFC_UTMI_ULPI:
+		if (!strncmp(dwc->hsphy_interface, "utmi", 4)) {
+			reg &= ~DWC3_GUSB2PHYCFG_ULPI_UTMI;
+		} else if (!strncmp(dwc->hsphy_interface, "ulpi", 4)) {
+			reg |= DWC3_GUSB2PHYCFG_ULPI_UTMI;
+		} else {
+			dev_warn(dwc->dev, "HSPHY Interface not defined\n");
+			break;
+		}
+		/* FALLTHROUGH */
+	default:
+		break;
+	}
+
 	/*
 	 * Above 1.94a, it is recommended to set DWC3_GUSB2PHYCFG_SUSPHY to
 	 * '0' during coreConsultant configuration. So default value will
@@ -451,6 +468,8 @@ static void dwc3_phy_setup(struct dwc3 *dwc)
 		reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
 
 	dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+
+	return 0;
 }
 
 /**
@@ -844,6 +863,8 @@ static int dwc3_probe(struct platform_device *pdev)
 				"snps,tx_de_emphasis_quirk");
 		of_property_read_u8(node, "snps,tx_de_emphasis",
 				&tx_de_emphasis);
+		of_property_read_string(node, "snps,hsphy_interface",
+					&dwc->hsphy_interface);
 	} else if (pdata) {
 		dwc->maximum_speed = pdata->maximum_speed;
 		dwc->has_lpm_erratum = pdata->has_lpm_erratum;
@@ -871,6 +892,8 @@ static int dwc3_probe(struct platform_device *pdev)
 		dwc->tx_de_emphasis_quirk = pdata->tx_de_emphasis_quirk;
 		if (pdata->tx_de_emphasis)
 			tx_de_emphasis = pdata->tx_de_emphasis;
+
+		dwc->hsphy_interface = pdata->hsphy_interface;
 	}
 
 	/* default to superspeed if no maximum_speed passed */
@@ -886,7 +909,9 @@ static int dwc3_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, dwc);
 	dwc3_cache_hwparams(dwc);
 
-	dwc3_phy_setup(dwc);
+	ret = dwc3_phy_setup(dwc);
+	if (ret)
+		goto err0;
 
 	ret = dwc3_core_get_phy(dwc);
 	if (ret)
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index c6eafaa..7b3ab64 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -682,6 +682,7 @@ struct dwc3_scratchpad_array {
  * @test_mode_nr: test feature selector
  * @lpm_nyet_threshold: LPM NYET response threshold
  * @hird_threshold: HIRD threshold
+ * @hsphy_interface: "utmi" or "ulpi"
  * @delayed_status: true when gadget driver asks for delayed status
  * @ep0_bounced: true when we used bounce buffer
  * @ep0_expect_in: true when we expect a DATA IN transfer
@@ -809,6 +810,8 @@ struct dwc3 {
 	u8			lpm_nyet_threshold;
 	u8			hird_threshold;
 
+	const char		*hsphy_interface;
+
 	unsigned		delayed_status:1;
 	unsigned		ep0_bounced:1;
 	unsigned		ep0_expect_in:1;
diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h
index a2bd464..d3614ec 100644
--- a/drivers/usb/dwc3/platform_data.h
+++ b/drivers/usb/dwc3/platform_data.h
@@ -45,4 +45,6 @@ struct dwc3_platform_data {
 
 	unsigned tx_de_emphasis_quirk:1;
 	unsigned tx_de_emphasis:2;
+
+	const char *hsphy_interface;
 };
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCHv3 09/12] usb: dwc3: pci: add quirk for Baytrails
  2015-04-29  8:21   ` Heikki Krogerus
  2015-04-29  8:30     ` [PATCHv3 08/12] usb: dwc3: add hsphy_interface property Heikki Krogerus
@ 2015-04-29  8:30     ` Heikki Krogerus
  2015-04-29  8:30     ` [PATCHv3 10/12] usb: dwc3: add ULPI interface support Heikki Krogerus
                       ` (2 subsequent siblings)
  4 siblings, 0 replies; 32+ messages in thread
From: Heikki Krogerus @ 2015-04-29  8:30 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: David Cohen, Greg Kroah-Hartman, Stephen Boyd, Baolu Lu,
	Paul Bolle, linux-usb, linux-kernel

On some BYT platforms the USB2 PHY needs to be put into
operational mode by the controller driver with GPIOs
controlling the PHYs reset and cs signals.

Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
---
 drivers/usb/dwc3/dwc3-pci.c | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index b773fb5..0235f46 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -21,6 +21,8 @@
 #include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/platform_device.h>
+#include <linux/gpio/consumer.h>
+#include <linux/acpi.h>
 
 #include "platform_data.h"
 
@@ -31,6 +33,15 @@
 #define PCI_DEVICE_ID_INTEL_SPTLP	0x9d30
 #define PCI_DEVICE_ID_INTEL_SPTH	0xa130
 
+static const struct acpi_gpio_params reset_gpios = { 0, 0, false };
+static const struct acpi_gpio_params cs_gpios = { 1, 0, false };
+
+static const struct acpi_gpio_mapping acpi_dwc3_byt_gpios[] = {
+	{ "reset-gpios", &reset_gpios, 1 },
+	{ "cs-gpios", &cs_gpios, 1 },
+	{ },
+};
+
 static int dwc3_pci_quirks(struct pci_dev *pdev)
 {
 	if (pdev->vendor == PCI_VENDOR_ID_AMD &&
@@ -65,6 +76,30 @@ static int dwc3_pci_quirks(struct pci_dev *pdev)
 						sizeof(pdata));
 	}
 
+	if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
+	    pdev->device == PCI_DEVICE_ID_INTEL_BYT) {
+		struct gpio_desc *gpio;
+
+		acpi_dev_add_driver_gpios(ACPI_COMPANION(&pdev->dev),
+					  acpi_dwc3_byt_gpios);
+
+		/* These GPIOs will turn on the USB2 PHY */
+		gpio = gpiod_get(&pdev->dev, "cs");
+		if (!IS_ERR(gpio)) {
+			gpiod_direction_output(gpio, 0);
+			gpiod_set_value_cansleep(gpio, 1);
+			gpiod_put(gpio);
+		}
+
+		gpio = gpiod_get(&pdev->dev, "reset");
+		if (!IS_ERR(gpio)) {
+			gpiod_direction_output(gpio, 0);
+			gpiod_set_value_cansleep(gpio, 1);
+			gpiod_put(gpio);
+			msleep(10);
+		}
+	}
+
 	return 0;
 }
 
@@ -128,6 +163,7 @@ err:
 
 static void dwc3_pci_remove(struct pci_dev *pci)
 {
+	acpi_dev_remove_driver_gpios(ACPI_COMPANION(&pci->dev));
 	platform_device_unregister(pci_get_drvdata(pci));
 }
 
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCHv3 10/12] usb: dwc3: add ULPI interface support
  2015-04-29  8:21   ` Heikki Krogerus
  2015-04-29  8:30     ` [PATCHv3 08/12] usb: dwc3: add hsphy_interface property Heikki Krogerus
  2015-04-29  8:30     ` [PATCHv3 09/12] usb: dwc3: pci: add quirk for Baytrails Heikki Krogerus
@ 2015-04-29  8:30     ` Heikki Krogerus
  2015-04-29 15:04       ` Felipe Balbi
  2015-04-29  8:30     ` [PATCHv3 11/12] phy: helpers for USB ULPI PHY registering Heikki Krogerus
  2015-04-29  8:30     ` [PATCHv3 12/12] phy: add driver for TI TUSB1210 ULPI PHY Heikki Krogerus
  4 siblings, 1 reply; 32+ messages in thread
From: Heikki Krogerus @ 2015-04-29  8:30 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: David Cohen, Greg Kroah-Hartman, Stephen Boyd, Baolu Lu,
	Paul Bolle, linux-usb, linux-kernel

Registers DWC3's ULPI interface with the ULPI bus when it's
available.

Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Acked-by: David Cohen <david.a.cohen@linux.intel.com>
---
 drivers/usb/dwc3/Kconfig  |  7 ++++
 drivers/usb/dwc3/Makefile |  4 +++
 drivers/usb/dwc3/core.c   | 19 +++++++++-
 drivers/usb/dwc3/core.h   | 14 ++++++++
 drivers/usb/dwc3/ulpi.c   | 91 +++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 134 insertions(+), 1 deletion(-)
 create mode 100644 drivers/usb/dwc3/ulpi.c

diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index 827c4f8..6f92b36 100644
--- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig
@@ -11,6 +11,13 @@ config USB_DWC3
 
 if USB_DWC3
 
+config USB_DWC3_ULPI
+	bool "Register ULPI PHY Interface"
+	depends on USB_ULPI_BUS
+	help
+	  Select this if you have ULPI type PHY attached to your DWC3
+	  controller.
+
 choice
 	bool "DWC3 Mode Selection"
 	default USB_DWC3_DUAL_ROLE if (USB && USB_GADGET)
diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
index 46172f4..c7076e3 100644
--- a/drivers/usb/dwc3/Makefile
+++ b/drivers/usb/dwc3/Makefile
@@ -15,6 +15,10 @@ ifneq ($(filter y,$(CONFIG_USB_DWC3_GADGET) $(CONFIG_USB_DWC3_DUAL_ROLE)),)
 	dwc3-y				+= gadget.o ep0.o
 endif
 
+ifneq ($(CONFIG_USB_DWC3_ULPI),)
+	dwc3-y				+= ulpi.o
+endif
+
 ifneq ($(CONFIG_DEBUG_FS),)
 	dwc3-y				+= debugfs.o
 endif
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index fdeff5e..adff5ab 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -444,13 +444,28 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
 	case DWC3_GHWPARAMS3_HSPHY_IFC_UTMI_ULPI:
 		if (!strncmp(dwc->hsphy_interface, "utmi", 4)) {
 			reg &= ~DWC3_GUSB2PHYCFG_ULPI_UTMI;
+			break;
 		} else if (!strncmp(dwc->hsphy_interface, "ulpi", 4)) {
 			reg |= DWC3_GUSB2PHYCFG_ULPI_UTMI;
+			dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
 		} else {
 			dev_warn(dwc->dev, "HSPHY Interface not defined\n");
-			break;
+
+			/* Relying on default value. */
+			if (!(reg & DWC3_GUSB2PHYCFG_ULPI_UTMI))
+				break;
 		}
 		/* FALLTHROUGH */
+	case DWC3_GHWPARAMS3_HSPHY_IFC_ULPI:
+		/* Soft reset here to sync the clocks */
+		ret = dwc3_soft_reset(dwc);
+		if (ret)
+			return ret;
+
+		ret = dwc3_ulpi_init(dwc);
+		if (ret)
+			return ret;
+		/* FALLTHROUGH */
 	default:
 		break;
 	}
@@ -999,6 +1014,7 @@ err2:
 
 err1:
 	dwc3_free_event_buffers(dwc);
+	dwc3_ulpi_exit(dwc);
 
 err0:
 	/*
@@ -1034,6 +1050,7 @@ static int dwc3_remove(struct platform_device *pdev)
 	phy_power_off(dwc->usb3_generic_phy);
 
 	dwc3_core_exit(dwc);
+	dwc3_ulpi_exit(dwc);
 
 	pm_runtime_put_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 7b3ab64..d70da20 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -30,6 +30,7 @@
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
 #include <linux/usb/otg.h>
+#include <linux/ulpi/interface.h>
 
 #include <linux/phy/phy.h>
 
@@ -661,6 +662,7 @@ struct dwc3_scratchpad_array {
  * @usb3_phy: pointer to USB3 PHY
  * @usb2_generic_phy: pointer to USB2 PHY
  * @usb3_generic_phy: pointer to USB3 PHY
+ * @ulpi: pointer to ulpi interface
  * @dcfg: saved contents of DCFG register
  * @gctl: saved contents of GCTL register
  * @isoch_delay: wValue from Set Isochronous Delay request;
@@ -749,6 +751,8 @@ struct dwc3 {
 	struct phy		*usb2_generic_phy;
 	struct phy		*usb3_generic_phy;
 
+	struct ulpi		*ulpi;
+
 	void __iomem		*regs;
 	size_t			regs_size;
 
@@ -1047,4 +1051,14 @@ static inline int dwc3_gadget_resume(struct dwc3 *dwc)
 }
 #endif /* !IS_ENABLED(CONFIG_USB_DWC3_HOST) */
 
+#if IS_ENABLED(CONFIG_USB_DWC3_ULPI)
+int dwc3_ulpi_init(struct dwc3 *dwc);
+void dwc3_ulpi_exit(struct dwc3 *dwc);
+#else
+static inline int dwc3_ulpi_init(struct dwc3 *dwc)
+{ return 0; }
+static inline void dwc3_ulpi_exit(struct dwc3 *dwc)
+{ }
+#endif
+
 #endif /* __DRIVERS_USB_DWC3_CORE_H */
diff --git a/drivers/usb/dwc3/ulpi.c b/drivers/usb/dwc3/ulpi.c
new file mode 100644
index 0000000..4dfcc81
--- /dev/null
+++ b/drivers/usb/dwc3/ulpi.c
@@ -0,0 +1,91 @@
+/**
+ * ulpi.c - DesignWare USB3 Controller's ULPI PHY interface
+ *
+ * Copyright (C) 2015 Intel Corporation
+ *
+ * Author: Heikki Krogerus <heikki.krogerus@linux.intel.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/ulpi/regs.h>
+
+#include "core.h"
+#include "io.h"
+
+#define DWC3_ULPI_ADDR(a) \
+		((a >= ULPI_EXT_VENDOR_SPECIFIC) ? \
+		DWC3_GUSB2PHYACC_ADDR(ULPI_ACCESS_EXTENDED) | \
+		DWC3_GUSB2PHYACC_EXTEND_ADDR(a) : DWC3_GUSB2PHYACC_ADDR(a))
+
+static int dwc3_ulpi_busyloop(struct dwc3 *dwc)
+{
+	unsigned count = 1000;
+	u32 reg;
+
+	while (count--) {
+		reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYACC(0));
+		if (!(reg & DWC3_GUSB2PHYACC_BUSY))
+			return 0;
+		cpu_relax();
+	}
+
+	return -ETIMEDOUT;
+}
+
+static int dwc3_ulpi_read(struct ulpi_ops *ops, u8 addr)
+{
+	struct dwc3 *dwc = dev_get_drvdata(ops->dev);
+	u32 reg;
+	int ret;
+
+	reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr);
+	dwc3_writel(dwc->regs, DWC3_GUSB2PHYACC(0), reg);
+
+	ret = dwc3_ulpi_busyloop(dwc);
+	if (ret)
+		return ret;
+
+	reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYACC(0));
+
+	return DWC3_GUSB2PHYACC_DATA(reg);
+}
+
+static int dwc3_ulpi_write(struct ulpi_ops *ops, u8 addr, u8 val)
+{
+	struct dwc3 *dwc = dev_get_drvdata(ops->dev);
+	u32 reg;
+
+	reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr);
+	reg |= DWC3_GUSB2PHYACC_WRITE | val;
+	dwc3_writel(dwc->regs, DWC3_GUSB2PHYACC(0), reg);
+
+	return dwc3_ulpi_busyloop(dwc);
+}
+
+static struct ulpi_ops dwc3_ulpi = {
+	.read = dwc3_ulpi_read,
+	.write = dwc3_ulpi_write,
+};
+
+int dwc3_ulpi_init(struct dwc3 *dwc)
+{
+	/* Register the interface */
+	dwc->ulpi = ulpi_register_interface(dwc->dev, &dwc3_ulpi);
+	if (IS_ERR(dwc->ulpi)) {
+		dev_err(dwc->dev, "failed to register ULPI interface");
+		return PTR_ERR(dwc->ulpi);
+	}
+
+	return 0;
+}
+
+void dwc3_ulpi_exit(struct dwc3 *dwc)
+{
+	if (dwc->ulpi) {
+		ulpi_unregister_interface(dwc->ulpi);
+		dwc->ulpi = NULL;
+	}
+}
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCHv3 11/12] phy: helpers for USB ULPI PHY registering
  2015-04-29  8:21   ` Heikki Krogerus
                       ` (2 preceding siblings ...)
  2015-04-29  8:30     ` [PATCHv3 10/12] usb: dwc3: add ULPI interface support Heikki Krogerus
@ 2015-04-29  8:30     ` Heikki Krogerus
  2015-04-29  8:30     ` [PATCHv3 12/12] phy: add driver for TI TUSB1210 ULPI PHY Heikki Krogerus
  4 siblings, 0 replies; 32+ messages in thread
From: Heikki Krogerus @ 2015-04-29  8:30 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: David Cohen, Greg Kroah-Hartman, Stephen Boyd, Baolu Lu,
	Paul Bolle, linux-usb, linux-kernel, Kishon Vijay Abraham I

ULPI PHYs need to be bound to their controllers with a
lookup. This adds helpers that the ULPI drivers can use to
do both, the registration of the PHY and the lookup, at the
same time.

Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Acked-by: David Cohen <david.a.cohen@linux.intel.com>
Cc: Kishon Vijay Abraham I <kishon@ti.com>
---
 drivers/phy/ulpi_phy.h | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)
 create mode 100644 drivers/phy/ulpi_phy.h

diff --git a/drivers/phy/ulpi_phy.h b/drivers/phy/ulpi_phy.h
new file mode 100644
index 0000000..ac49fb6
--- /dev/null
+++ b/drivers/phy/ulpi_phy.h
@@ -0,0 +1,31 @@
+#include <linux/phy/phy.h>
+
+/**
+ * Helper that registers PHY for a ULPI device and adds a lookup for binding it
+ * and it's controller, which is always the parent.
+ */
+static inline struct phy
+*ulpi_phy_create(struct ulpi *ulpi, struct phy_ops *ops)
+{
+	struct phy *phy;
+	int ret;
+
+	phy = phy_create(&ulpi->dev, NULL, ops);
+	if (IS_ERR(phy))
+		return phy;
+
+	ret = phy_create_lookup(phy, "usb2-phy", dev_name(ulpi->dev.parent));
+	if (ret) {
+		phy_destroy(phy);
+		return ERR_PTR(ret);
+	}
+
+	return phy;
+}
+
+/* Remove a PHY that was created with ulpi_phy_create() and it's lookup. */
+static inline void ulpi_phy_destroy(struct ulpi *ulpi, struct phy *phy)
+{
+	phy_remove_lookup(phy, "usb2-phy", dev_name(ulpi->dev.parent));
+	phy_destroy(phy);
+}
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCHv3 12/12] phy: add driver for TI TUSB1210 ULPI PHY
  2015-04-29  8:21   ` Heikki Krogerus
                       ` (3 preceding siblings ...)
  2015-04-29  8:30     ` [PATCHv3 11/12] phy: helpers for USB ULPI PHY registering Heikki Krogerus
@ 2015-04-29  8:30     ` Heikki Krogerus
  4 siblings, 0 replies; 32+ messages in thread
From: Heikki Krogerus @ 2015-04-29  8:30 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: David Cohen, Greg Kroah-Hartman, Stephen Boyd, Baolu Lu,
	Paul Bolle, linux-usb, linux-kernel, Kishon Vijay Abraham I

TUSB1210 ULPI PHY has vendor specific register for eye
diagram tuning. On some platforms the system firmware has
set optimized value to it. In order to not loose the
optimized value, the driver stores it during probe and
restores it every time the PHY is powered back on.

Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Acked-by: David Cohen <david.a.cohen@linux.intel.com>
Cc: Kishon Vijay Abraham I <kishon@ti.com>
---
 drivers/phy/Kconfig        |   7 +++
 drivers/phy/Makefile       |   1 +
 drivers/phy/phy-tusb1210.c | 153 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 161 insertions(+)
 create mode 100644 drivers/phy/phy-tusb1210.c

diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index a53bd5b..fceac96 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -309,4 +309,11 @@ config PHY_QCOM_UFS
 	help
 	  Support for UFS PHY on QCOM chipsets.
 
+config PHY_TUSB1210
+	tristate "TI TUSB1210 ULPI PHY module"
+	depends on USB_ULPI_BUS
+	select GENERIC_PHY
+	help
+	  Support for TI TUSB1210 USB ULPI PHY.
+
 endmenu
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index f126251..0a20418 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -40,3 +40,4 @@ obj-$(CONFIG_PHY_STIH41X_USB)		+= phy-stih41x-usb.o
 obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs.o
 obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs-qmp-20nm.o
 obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs-qmp-14nm.o
+obj-$(CONFIG_PHY_TUSB1210)		+= phy-tusb1210.o
diff --git a/drivers/phy/phy-tusb1210.c b/drivers/phy/phy-tusb1210.c
new file mode 100644
index 0000000..07efdd3
--- /dev/null
+++ b/drivers/phy/phy-tusb1210.c
@@ -0,0 +1,153 @@
+/**
+ * tusb1210.c - TUSB1210 USB ULPI PHY driver
+ *
+ * Copyright (C) 2015 Intel Corporation
+ *
+ * Author: Heikki Krogerus <heikki.krogerus@linux.intel.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/module.h>
+#include <linux/ulpi/driver.h>
+#include <linux/gpio/consumer.h>
+
+#include "ulpi_phy.h"
+
+#define TUSB1210_VENDOR_SPECIFIC2		0x80
+#define TUSB1210_VENDOR_SPECIFIC2_IHSTX_SHIFT	0
+#define TUSB1210_VENDOR_SPECIFIC2_ZHSDRV_SHIFT	4
+#define TUSB1210_VENDOR_SPECIFIC2_DP_SHIFT	6
+
+struct tusb1210 {
+	struct ulpi *ulpi;
+	struct phy *phy;
+	struct gpio_desc *gpio_reset;
+	struct gpio_desc *gpio_cs;
+	u8 vendor_specific2;
+};
+
+static int tusb1210_power_on(struct phy *phy)
+{
+	struct tusb1210 *tusb = phy_get_drvdata(phy);
+
+	gpiod_set_value_cansleep(tusb->gpio_reset, 1);
+	gpiod_set_value_cansleep(tusb->gpio_cs, 1);
+
+	/* Restore the optional eye diagram optimization value */
+	if (tusb->vendor_specific2)
+		ulpi_write(tusb->ulpi, TUSB1210_VENDOR_SPECIFIC2,
+			   tusb->vendor_specific2);
+
+	return 0;
+}
+
+static int tusb1210_power_off(struct phy *phy)
+{
+	struct tusb1210 *tusb = phy_get_drvdata(phy);
+
+	gpiod_set_value_cansleep(tusb->gpio_reset, 0);
+	gpiod_set_value_cansleep(tusb->gpio_cs, 0);
+
+	return 0;
+}
+
+static struct phy_ops phy_ops = {
+	.power_on = tusb1210_power_on,
+	.power_off = tusb1210_power_off,
+	.owner = THIS_MODULE,
+};
+
+static int tusb1210_probe(struct ulpi *ulpi)
+{
+	struct gpio_desc *gpio;
+	struct tusb1210 *tusb;
+	u8 val, reg;
+	int ret;
+
+	tusb = devm_kzalloc(&ulpi->dev, sizeof(*tusb), GFP_KERNEL);
+	if (!tusb)
+		return -ENOMEM;
+
+	gpio = devm_gpiod_get(&ulpi->dev, "reset");
+	if (!IS_ERR(gpio)) {
+		ret = gpiod_direction_output(gpio, 0);
+		if (ret)
+			return ret;
+		gpiod_set_value_cansleep(gpio, 1);
+		tusb->gpio_reset = gpio;
+	}
+
+	gpio = devm_gpiod_get(&ulpi->dev, "cs");
+	if (!IS_ERR(gpio)) {
+		ret = gpiod_direction_output(gpio, 0);
+		if (ret)
+			return ret;
+		gpiod_set_value_cansleep(gpio, 1);
+		tusb->gpio_cs = gpio;
+	}
+
+	/*
+	 * VENDOR_SPECIFIC2 register in TUSB1210 can be used for configuring eye
+	 * diagram optimization and DP/DM swap.
+	 */
+
+	/* High speed output drive strength configuration */
+	device_property_read_u8(&ulpi->dev, "ihstx", &val);
+	reg = val << TUSB1210_VENDOR_SPECIFIC2_IHSTX_SHIFT;
+
+	/* High speed output impedance configuration */
+	device_property_read_u8(&ulpi->dev, "zhsdrv", &val);
+	reg |= val << TUSB1210_VENDOR_SPECIFIC2_ZHSDRV_SHIFT;
+
+	/* DP/DM swap control */
+	device_property_read_u8(&ulpi->dev, "datapolarity", &val);
+	reg |= val << TUSB1210_VENDOR_SPECIFIC2_DP_SHIFT;
+
+	if (reg) {
+		ulpi_write(ulpi, TUSB1210_VENDOR_SPECIFIC2, reg);
+		tusb->vendor_specific2 = reg;
+	}
+
+	tusb->phy = ulpi_phy_create(ulpi, &phy_ops);
+	if (IS_ERR(tusb->phy))
+		return PTR_ERR(tusb->phy);
+
+	tusb->ulpi = ulpi;
+
+	phy_set_drvdata(tusb->phy, tusb);
+	ulpi_set_drvdata(ulpi, tusb);
+	return 0;
+}
+
+static void tusb1210_remove(struct ulpi *ulpi)
+{
+	struct tusb1210 *tusb = ulpi_get_drvdata(ulpi);
+
+	ulpi_phy_destroy(ulpi, tusb->phy);
+}
+
+#define TI_VENDOR_ID 0x0451
+
+static const struct ulpi_device_id tusb1210_ulpi_id[] = {
+	{ TI_VENDOR_ID, 0x1507, },
+	{ },
+};
+MODULE_DEVICE_TABLE(ulpi, tusb1210_ulpi_id);
+
+static struct ulpi_driver tusb1210_driver = {
+	.id_table = tusb1210_ulpi_id,
+	.probe = tusb1210_probe,
+	.remove = tusb1210_remove,
+	.driver = {
+		.name = "tusb1210",
+		.owner = THIS_MODULE,
+	},
+};
+
+module_ulpi_driver(tusb1210_driver);
+
+MODULE_AUTHOR("Intel Corporation");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("TUSB1210 ULPI PHY driver");
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* Re: [PATCHv3 08/12] usb: dwc3: add hsphy_interface property
  2015-04-29  8:30     ` [PATCHv3 08/12] usb: dwc3: add hsphy_interface property Heikki Krogerus
@ 2015-04-29 15:03       ` Felipe Balbi
  2015-04-30 10:33         ` Heikki Krogerus
  0 siblings, 1 reply; 32+ messages in thread
From: Felipe Balbi @ 2015-04-29 15:03 UTC (permalink / raw)
  To: Heikki Krogerus
  Cc: Felipe Balbi, David Cohen, Greg Kroah-Hartman, Stephen Boyd,
	Baolu Lu, Paul Bolle, linux-usb, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2017 bytes --]

On Wed, Apr 29, 2015 at 11:30:29AM +0300, Heikki Krogerus wrote:
> Platforms that have configured DWC_USB3_HSPHY_INTERFACE with
> value 3, i.e. UTMI+ and ULPI, need to inform the driver of
> the actual HSPHY interface type with the property. "utmi" if
> the interface is UTMI+ or "ulpi" if the interface is ULPI.
> 
> Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> Acked-by: David Cohen <david.a.cohen@linux.intel.com>
> ---
>  Documentation/devicetree/bindings/usb/dwc3.txt |  2 ++
>  drivers/usb/dwc3/core.c                        | 29 ++++++++++++++++++++++++--
>  drivers/usb/dwc3/core.h                        |  3 +++
>  drivers/usb/dwc3/platform_data.h               |  2 ++
>  4 files changed, 34 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
> index 5cc3643..0815eac 100644
> --- a/Documentation/devicetree/bindings/usb/dwc3.txt
> +++ b/Documentation/devicetree/bindings/usb/dwc3.txt
> @@ -38,6 +38,8 @@ Optional properties:
>   - snps,is-utmi-l1-suspend: true when DWC3 asserts output signal
>  			utmi_l1_suspend_n, false when asserts utmi_sleep_n
>   - snps,hird-threshold: HIRD threshold
> + - snps,hsphy_interface: High-Speed PHY interface selection between "utmi" for
> +   UTMI+ and "ulpi" for ULPI when the DWC_USB3_HSPHY_INTERFACE has value 3.
>  
>  This is usually a subnode to DWC3 glue to which it is connected.
>  
> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index 6b02e12..fdeff5e 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -395,9 +395,10 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc)
>   * dwc3_phy_setup - Configure USB PHY Interface of DWC3 Core
>   * @dwc: Pointer to our controller context structure
>   */
> -static void dwc3_phy_setup(struct dwc3 *dwc)
> +static int dwc3_phy_setup(struct dwc3 *dwc)
>  {
>  	u32 reg;
> +	int ret;

unused variable

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCHv3 10/12] usb: dwc3: add ULPI interface support
  2015-04-29  8:30     ` [PATCHv3 10/12] usb: dwc3: add ULPI interface support Heikki Krogerus
@ 2015-04-29 15:04       ` Felipe Balbi
  2015-04-30 10:34         ` Heikki Krogerus
  0 siblings, 1 reply; 32+ messages in thread
From: Felipe Balbi @ 2015-04-29 15:04 UTC (permalink / raw)
  To: Heikki Krogerus
  Cc: Felipe Balbi, David Cohen, Greg Kroah-Hartman, Stephen Boyd,
	Baolu Lu, Paul Bolle, linux-usb, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2787 bytes --]

On Wed, Apr 29, 2015 at 11:30:31AM +0300, Heikki Krogerus wrote:
> Registers DWC3's ULPI interface with the ULPI bus when it's
> available.
> 
> Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> Acked-by: David Cohen <david.a.cohen@linux.intel.com>
> ---
>  drivers/usb/dwc3/Kconfig  |  7 ++++
>  drivers/usb/dwc3/Makefile |  4 +++
>  drivers/usb/dwc3/core.c   | 19 +++++++++-
>  drivers/usb/dwc3/core.h   | 14 ++++++++
>  drivers/usb/dwc3/ulpi.c   | 91 +++++++++++++++++++++++++++++++++++++++++++++++
>  5 files changed, 134 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/usb/dwc3/ulpi.c
> 
> diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
> index 827c4f8..6f92b36 100644
> --- a/drivers/usb/dwc3/Kconfig
> +++ b/drivers/usb/dwc3/Kconfig
> @@ -11,6 +11,13 @@ config USB_DWC3
>  
>  if USB_DWC3
>  
> +config USB_DWC3_ULPI
> +	bool "Register ULPI PHY Interface"
> +	depends on USB_ULPI_BUS
> +	help
> +	  Select this if you have ULPI type PHY attached to your DWC3
> +	  controller.
> +
>  choice
>  	bool "DWC3 Mode Selection"
>  	default USB_DWC3_DUAL_ROLE if (USB && USB_GADGET)
> diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
> index 46172f4..c7076e3 100644
> --- a/drivers/usb/dwc3/Makefile
> +++ b/drivers/usb/dwc3/Makefile
> @@ -15,6 +15,10 @@ ifneq ($(filter y,$(CONFIG_USB_DWC3_GADGET) $(CONFIG_USB_DWC3_DUAL_ROLE)),)
>  	dwc3-y				+= gadget.o ep0.o
>  endif
>  
> +ifneq ($(CONFIG_USB_DWC3_ULPI),)
> +	dwc3-y				+= ulpi.o
> +endif
> +
>  ifneq ($(CONFIG_DEBUG_FS),)
>  	dwc3-y				+= debugfs.o
>  endif
> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index fdeff5e..adff5ab 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -444,13 +444,28 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
>  	case DWC3_GHWPARAMS3_HSPHY_IFC_UTMI_ULPI:
>  		if (!strncmp(dwc->hsphy_interface, "utmi", 4)) {
>  			reg &= ~DWC3_GUSB2PHYCFG_ULPI_UTMI;
> +			break;
>  		} else if (!strncmp(dwc->hsphy_interface, "ulpi", 4)) {
>  			reg |= DWC3_GUSB2PHYCFG_ULPI_UTMI;
> +			dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
>  		} else {
>  			dev_warn(dwc->dev, "HSPHY Interface not defined\n");
> -			break;
> +
> +			/* Relying on default value. */
> +			if (!(reg & DWC3_GUSB2PHYCFG_ULPI_UTMI))
> +				break;
>  		}
>  		/* FALLTHROUGH */
> +	case DWC3_GHWPARAMS3_HSPHY_IFC_ULPI:
> +		/* Soft reset here to sync the clocks */
> +		ret = dwc3_soft_reset(dwc);

you just lost all DWC3_GUSB3PIPECTL(0) and DWC3_GUSB2PHYCFG(0)
configurations which happened right before this switch. Essentially
breaking anybody who needs any of those extra bits enabled even though
they're not enabled by default.

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCHv3 01/11] usb: add bus type for USB ULPI
  2015-04-28 13:24 ` [PATCHv3 01/11] usb: add bus type for USB ULPI Heikki Krogerus
@ 2015-04-29 20:13   ` Felipe Balbi
  2015-04-30 10:37     ` Heikki Krogerus
  0 siblings, 1 reply; 32+ messages in thread
From: Felipe Balbi @ 2015-04-29 20:13 UTC (permalink / raw)
  To: Heikki Krogerus
  Cc: Felipe Balbi, David Cohen, Greg Kroah-Hartman, Stephen Boyd,
	Baolu Lu, Paul Bolle, linux-usb, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 326 bytes --]

Hi,

On Tue, Apr 28, 2015 at 04:24:36PM +0300, Heikki Krogerus wrote:
> +struct bus_type ulpi_bus = {

non-static and undeclared anywhere, adds a sparse error. I'm dropping
the series for now :-)

"
drivers/usb/common/ulpi.c:77:17: warning: symbol 'ulpi_bus' was not
declared. Should it be static?
"

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCHv3 08/12] usb: dwc3: add hsphy_interface property
  2015-04-29 15:03       ` Felipe Balbi
@ 2015-04-30 10:33         ` Heikki Krogerus
  0 siblings, 0 replies; 32+ messages in thread
From: Heikki Krogerus @ 2015-04-30 10:33 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: David Cohen, Greg Kroah-Hartman, Stephen Boyd, Baolu Lu,
	Paul Bolle, linux-usb, linux-kernel

> > -static void dwc3_phy_setup(struct dwc3 *dwc)
> > +static int dwc3_phy_setup(struct dwc3 *dwc)
> >  {
> >  	u32 reg;
> > +	int ret;
> 
> unused variable

true,


-- 
heikki

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCHv3 10/12] usb: dwc3: add ULPI interface support
  2015-04-29 15:04       ` Felipe Balbi
@ 2015-04-30 10:34         ` Heikki Krogerus
  2015-04-30 14:54           ` Felipe Balbi
  0 siblings, 1 reply; 32+ messages in thread
From: Heikki Krogerus @ 2015-04-30 10:34 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: David Cohen, Greg Kroah-Hartman, Stephen Boyd, Baolu Lu,
	Paul Bolle, linux-usb, linux-kernel

Hi Felipe,

> > +	case DWC3_GHWPARAMS3_HSPHY_IFC_ULPI:
> > +		/* Soft reset here to sync the clocks */
> > +		ret = dwc3_soft_reset(dwc);
> 
> you just lost all DWC3_GUSB3PIPECTL(0) and DWC3_GUSB2PHYCFG(0)
> configurations which happened right before this switch. Essentially
> breaking anybody who needs any of those extra bits enabled even though
> they're not enabled by default.

Is this a problem we have with DWC3 cores older then 1.94? I don't
know anything about those. If it is, then I would imagine we just need
to soft reset here conditionally, only cores >= 1.94a, right?

With 1.94a and newer, DWC3_GUSB3PIPECTL(0) and DWC3_GUSB2PHYCFG(0)
keep their ctx over any kind of soft reset. And any configurations
done to them here will take affect the latest when
dwc3_core_soft_reset() is called.


Thanks,

-- 
heikki

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCHv3 01/11] usb: add bus type for USB ULPI
  2015-04-29 20:13   ` Felipe Balbi
@ 2015-04-30 10:37     ` Heikki Krogerus
  0 siblings, 0 replies; 32+ messages in thread
From: Heikki Krogerus @ 2015-04-30 10:37 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: David Cohen, Greg Kroah-Hartman, Stephen Boyd, Baolu Lu,
	Paul Bolle, linux-usb, linux-kernel

> > +struct bus_type ulpi_bus = {
> 
> non-static and undeclared anywhere, adds a sparse error. I'm dropping
> the series for now :-)
> 
> "
> drivers/usb/common/ulpi.c:77:17: warning: symbol 'ulpi_bus' was not
> declared. Should it be static?
> "

Need to fix that. I'll wait for your comment's to 10/12 before
preparing new version.


Thanks,


-- 
heikki

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCHv3 10/12] usb: dwc3: add ULPI interface support
  2015-04-30 10:34         ` Heikki Krogerus
@ 2015-04-30 14:54           ` Felipe Balbi
  2015-05-04 12:03             ` Heikki Krogerus
  0 siblings, 1 reply; 32+ messages in thread
From: Felipe Balbi @ 2015-04-30 14:54 UTC (permalink / raw)
  To: Heikki Krogerus
  Cc: Felipe Balbi, David Cohen, Greg Kroah-Hartman, Stephen Boyd,
	Baolu Lu, Paul Bolle, linux-usb, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 4609 bytes --]

Hi,

On Thu, Apr 30, 2015 at 01:34:22PM +0300, Heikki Krogerus wrote:
> Hi Felipe,
> 
> > > +	case DWC3_GHWPARAMS3_HSPHY_IFC_ULPI:
> > > +		/* Soft reset here to sync the clocks */
> > > +		ret = dwc3_soft_reset(dwc);
> > 
> > you just lost all DWC3_GUSB3PIPECTL(0) and DWC3_GUSB2PHYCFG(0)
> > configurations which happened right before this switch. Essentially
> > breaking anybody who needs any of those extra bits enabled even though
> > they're not enabled by default.
> 
> Is this a problem we have with DWC3 cores older then 1.94? I don't

no, it's a problem with anybody setting any of the quirks in this
function, I'll reproduce some of the code here so we can look at it
together.


| static int dwc3_phy_setup(struct dwc3 *dwc)
| {
| 	u32 reg;
| 	int ret;
| 
| 	reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
| 
| 	/*
| 	 * Above 1.94a, it is recommended to set DWC3_GUSB3PIPECTL_SUSPHY
| 	 * to '0' during coreConsultant configuration. So default value
| 	 * will be '0' when the core is reset. Application needs to set it
| 	 * to '1' after the core initialization is completed.
| 	 */
| 	if (dwc->revision > DWC3_REVISION_194A)
| 		reg |= DWC3_GUSB3PIPECTL_SUSPHY;
| 
| 	if (dwc->u2ss_inp3_quirk)
| 		reg |= DWC3_GUSB3PIPECTL_U2SSINP3OK;
| 
| 	if (dwc->req_p1p2p3_quirk)
| 		reg |= DWC3_GUSB3PIPECTL_REQP1P2P3;
| 
| 	if (dwc->del_p1p2p3_quirk)
| 		reg |= DWC3_GUSB3PIPECTL_DEP1P2P3_EN;
| 
| 	if (dwc->del_phy_power_chg_quirk)
| 		reg |= DWC3_GUSB3PIPECTL_DEPOCHANGE;
| 
| 	if (dwc->lfps_filter_quirk)
| 		reg |= DWC3_GUSB3PIPECTL_LFPSFILT;
| 
| 	if (dwc->rx_detect_poll_quirk)
| 		reg |= DWC3_GUSB3PIPECTL_RX_DETOPOLL;
| 
| 	if (dwc->tx_de_emphasis_quirk)
| 		reg |= DWC3_GUSB3PIPECTL_TX_DEEPH(dwc->tx_de_emphasis);
| 
| 	if (dwc->dis_u3_susphy_quirk)
| 		reg &= ~DWC3_GUSB3PIPECTL_SUSPHY;
| 
| 	dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);

right here we have potentially wrote quite a few quirks for the USB3
PHY...

| 	reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
| 
| 	/* Select the HS PHY interface */
| 	switch (DWC3_GHWPARAMS3_HSPHY_IFC(dwc->hwparams.hwparams3)) {
| 	case DWC3_GHWPARAMS3_HSPHY_IFC_UTMI_ULPI:
| 		if (!strncmp(dwc->hsphy_interface, "utmi", 4)) {
| 			reg &= ~DWC3_GUSB2PHYCFG_ULPI_UTMI;
| 			break;
| 		} else if (!strncmp(dwc->hsphy_interface, "ulpi", 4)) {
| 			reg |= DWC3_GUSB2PHYCFG_ULPI_UTMI;
| 			dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
| 		} else {
| 			dev_warn(dwc->dev, "HSPHY Interface not defined\n");
| 
| 			/* Relying on default value. */
| 			if (!(reg & DWC3_GUSB2PHYCFG_ULPI_UTMI))
| 				break;
| 		}
| 		/* FALLTHROUGH */
| 	case DWC3_GHWPARAMS3_HSPHY_IFC_ULPI:
| 		/* Soft reset here to sync the clocks */
| 		ret = dwc3_soft_reset(dwc);

and right here we loose those bits :-)

| 		if (ret)
| 			return ret;
| 
| 		ret = dwc3_ulpi_init(dwc);
| 		if (ret)
| 			return ret;
| 		/* FALLTHROUGH */
| 	default:
| 		break;
| 	}
| 
| 	/*
| 	 * Above 1.94a, it is recommended to set DWC3_GUSB2PHYCFG_SUSPHY to
| 	 * '0' during coreConsultant configuration. So default value will
| 	 * be '0' when the core is reset. Application needs to set it to
| 	 * '1' after the core initialization is completed.
| 	 */
| 	if (dwc->revision > DWC3_REVISION_194A)
| 		reg |= DWC3_GUSB2PHYCFG_SUSPHY;
| 
| 	if (dwc->dis_u2_susphy_quirk)
| 		reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
| 
| 	dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
| 
| 	return 0;
| }

> know anything about those. If it is, then I would imagine we just need
> to soft reset here conditionally, only cores >= 1.94a, right?

That's wrong, how do you support older core with ULPI vs UTMI selection
needs ?

> With 1.94a and newer, DWC3_GUSB3PIPECTL(0) and DWC3_GUSB2PHYCFG(0)
> keep their ctx over any kind of soft reset. And any configurations
> done to them here will take affect the latest when
> dwc3_core_soft_reset() is called.

/me goes read Databook again.

You're right. You're using the soft reset bit from DCTL, that only
resets the device side, not any global register. There are two details
which you don't appear to take care of, however.

According to Table 7-82 on Databook 2.93a (page 725), bit 30 CSFTRST,
it's said that "Once this bit is cleared, the software must wait at
least 3 PHY clocks before accessing the PHY domain". Futher down is
states that "Once a new clock is selected, the PHY domain must be reset
for proper operation".

So there you go, 2 details which should be taken care of :-)

cheers

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCHv3 10/12] usb: dwc3: add ULPI interface support
  2015-04-30 14:54           ` Felipe Balbi
@ 2015-05-04 12:03             ` Heikki Krogerus
  2015-05-05 15:02               ` Felipe Balbi
  0 siblings, 1 reply; 32+ messages in thread
From: Heikki Krogerus @ 2015-05-04 12:03 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: David Cohen, Greg Kroah-Hartman, Stephen Boyd, Baolu Lu,
	Paul Bolle, linux-usb, linux-kernel

Hi Felipe,

> > With 1.94a and newer, DWC3_GUSB3PIPECTL(0) and DWC3_GUSB2PHYCFG(0)
> > keep their ctx over any kind of soft reset. And any configurations
> > done to them here will take affect the latest when
> > dwc3_core_soft_reset() is called.
> 
> /me goes read Databook again.
> 
> You're right. You're using the soft reset bit from DCTL, that only
> resets the device side, not any global register. There are two details
> which you don't appear to take care of, however.
> 
> According to Table 7-82 on Databook 2.93a (page 725), bit 30 CSFTRST,
> it's said that "Once this bit is cleared, the software must wait at
> least 3 PHY clocks before accessing the PHY domain".

Ok, I'll add a delay for that.

> Futher down is
> states that "Once a new clock is selected, the PHY domain must be reset
> for proper operation".

All PHYs will be reset once we call dwc3_core_soft_reset() and we do
not need them to be operational before that, except in case of
ULPI in order to register the interface. To make sure the ULPI
interface and PHY are operational we call dwc3_soft_reset() which does
everything needed for us. When we use DCTL.SoftRst the core will reset
also the ULPI PHY (PHYSoftRst in DWC3_GUSB2PHYCFG(0) has no effect
with ULPI).

So dwc3_phy_setup() configures the PHY interfaces but it does not
initialize them or the PHYs. dwc3_core_soft_reset() continues to take
care of that in any case, so there is no reason to duplicate it. I
think we need to point this out in the description comment of
dwc3_phy_setup().


Thanks,

-- 
heikki

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCHv3 10/12] usb: dwc3: add ULPI interface support
  2015-05-04 12:03             ` Heikki Krogerus
@ 2015-05-05 15:02               ` Felipe Balbi
  0 siblings, 0 replies; 32+ messages in thread
From: Felipe Balbi @ 2015-05-05 15:02 UTC (permalink / raw)
  To: Heikki Krogerus
  Cc: Felipe Balbi, David Cohen, Greg Kroah-Hartman, Stephen Boyd,
	Baolu Lu, Paul Bolle, linux-usb, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1741 bytes --]

On Mon, May 04, 2015 at 03:03:45PM +0300, Heikki Krogerus wrote:
> Hi Felipe,
> 
> > > With 1.94a and newer, DWC3_GUSB3PIPECTL(0) and DWC3_GUSB2PHYCFG(0)
> > > keep their ctx over any kind of soft reset. And any configurations
> > > done to them here will take affect the latest when
> > > dwc3_core_soft_reset() is called.
> > 
> > /me goes read Databook again.
> > 
> > You're right. You're using the soft reset bit from DCTL, that only
> > resets the device side, not any global register. There are two details
> > which you don't appear to take care of, however.
> > 
> > According to Table 7-82 on Databook 2.93a (page 725), bit 30 CSFTRST,
> > it's said that "Once this bit is cleared, the software must wait at
> > least 3 PHY clocks before accessing the PHY domain".
> 
> Ok, I'll add a delay for that.
> 
> > Futher down is
> > states that "Once a new clock is selected, the PHY domain must be reset
> > for proper operation".
> 
> All PHYs will be reset once we call dwc3_core_soft_reset() and we do
> not need them to be operational before that, except in case of
> ULPI in order to register the interface. To make sure the ULPI
> interface and PHY are operational we call dwc3_soft_reset() which does
> everything needed for us. When we use DCTL.SoftRst the core will reset
> also the ULPI PHY (PHYSoftRst in DWC3_GUSB2PHYCFG(0) has no effect
> with ULPI).
> 
> So dwc3_phy_setup() configures the PHY interfaces but it does not
> initialize them or the PHYs. dwc3_core_soft_reset() continues to take
> care of that in any case, so there is no reason to duplicate it. I
> think we need to point this out in the description comment of
> dwc3_phy_setup().

sounds good to me :-)

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 32+ messages in thread

end of thread, other threads:[~2015-05-05 16:08 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-28 13:24 [PATCHv3 00/12] usb: ulpi bus Heikki Krogerus
2015-04-28 13:24 ` [PATCHv3 01/11] usb: add bus type for USB ULPI Heikki Krogerus
2015-04-29 20:13   ` Felipe Balbi
2015-04-30 10:37     ` Heikki Krogerus
2015-04-28 13:24 ` [PATCHv3 02/11] usb: dwc3: USB2 PHY register access bits Heikki Krogerus
2015-04-28 13:24 ` [PATCHv3 03/11] usb: dwc3: ULPI or UTMI+ select Heikki Krogerus
2015-04-28 13:24 ` [PATCHv3 04/11] usb: dwc3: store driver data earlier Heikki Krogerus
2015-04-28 13:24 ` [PATCHv3 05/11] usb: dwc3: cache hwparams earlier Heikki Krogerus
2015-04-28 13:24 ` [PATCHv3 06/11] usb: dwc3: soft reset to it's own function Heikki Krogerus
2015-04-28 17:22   ` Felipe Balbi
2015-04-29  8:16     ` Heikki Krogerus
2015-04-28 13:24 ` [PATCHv3 07/11] usb: dwc3: setup phys earlier Heikki Krogerus
2015-04-28 13:24 ` [PATCHv3 08/11] usb: dwc3: add hsphy_interface property Heikki Krogerus
2015-04-28 17:13   ` Felipe Balbi
2015-04-29  8:04     ` Heikki Krogerus
2015-04-28 13:24 ` [PATCHv3 09/11] usb: dwc3: pci: add quirk for Baytrails Heikki Krogerus
2015-04-28 13:24 ` [PATCHv3 10/11] phy: helpers for USB ULPI PHY registering Heikki Krogerus
2015-04-28 13:24 ` [PATCHv3 11/11] phy: add driver for TI TUSB1210 ULPI PHY Heikki Krogerus
2015-04-28 17:17 ` [PATCHv3 00/12] usb: ulpi bus Felipe Balbi
2015-04-29  8:21   ` Heikki Krogerus
2015-04-29  8:30     ` [PATCHv3 08/12] usb: dwc3: add hsphy_interface property Heikki Krogerus
2015-04-29 15:03       ` Felipe Balbi
2015-04-30 10:33         ` Heikki Krogerus
2015-04-29  8:30     ` [PATCHv3 09/12] usb: dwc3: pci: add quirk for Baytrails Heikki Krogerus
2015-04-29  8:30     ` [PATCHv3 10/12] usb: dwc3: add ULPI interface support Heikki Krogerus
2015-04-29 15:04       ` Felipe Balbi
2015-04-30 10:34         ` Heikki Krogerus
2015-04-30 14:54           ` Felipe Balbi
2015-05-04 12:03             ` Heikki Krogerus
2015-05-05 15:02               ` Felipe Balbi
2015-04-29  8:30     ` [PATCHv3 11/12] phy: helpers for USB ULPI PHY registering Heikki Krogerus
2015-04-29  8:30     ` [PATCHv3 12/12] phy: add driver for TI TUSB1210 ULPI PHY Heikki Krogerus

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.