[PATCH 1/4] usb: typec: ucsi: ccg: add get_fw_info function

2019-04-10 Thread Heikki Krogerus
From: Ajay Gupta 

Function is to get the details of ccg firmware and device version.
It will be useful in debugging and also during firmware update.

Signed-off-by: Ajay Gupta 
Signed-off-by: Heikki Krogerus 
---
 drivers/usb/typec/ucsi/ucsi_ccg.c | 66 ++-
 1 file changed, 64 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/typec/ucsi/ucsi_ccg.c 
b/drivers/usb/typec/ucsi/ucsi_ccg.c
index de8a43bdff68..3884fb41c72e 100644
--- a/drivers/usb/typec/ucsi/ucsi_ccg.c
+++ b/drivers/usb/typec/ucsi/ucsi_ccg.c
@@ -17,15 +17,54 @@
 #include 
 #include "ucsi.h"
 
+enum enum_fw_mode {
+   BOOT,   /* bootloader */
+   FW1,/* FW partition-1 (contains secondary fw) */
+   FW2,/* FW partition-2 (contains primary fw) */
+   FW_INVALID,
+};
+
+struct ccg_dev_info {
+#define CCG_DEVINFO_FWMODE_SHIFT (0)
+#define CCG_DEVINFO_FWMODE_MASK (0x3 << CCG_DEVINFO_FWMODE_SHIFT)
+#define CCG_DEVINFO_PDPORTS_SHIFT (2)
+#define CCG_DEVINFO_PDPORTS_MASK (0x3 << CCG_DEVINFO_PDPORTS_SHIFT)
+   u8 mode;
+   u8 bl_mode;
+   __le16 silicon_id;
+   __le16 bl_last_row;
+} __packed;
+
+struct version_format {
+   __le16 build;
+   u8 patch;
+   u8 ver;
+#define CCG_VERSION_MIN_SHIFT (0)
+#define CCG_VERSION_MIN_MASK (0xf << CCG_VERSION_MIN_SHIFT)
+#define CCG_VERSION_MAJ_SHIFT (4)
+#define CCG_VERSION_MAJ_MASK (0xf << CCG_VERSION_MAJ_SHIFT)
+} __packed;
+
+struct version_info {
+   struct version_format base;
+   struct version_format app;
+};
+
 struct ucsi_ccg {
struct device *dev;
struct ucsi *ucsi;
struct ucsi_ppm ppm;
struct i2c_client *client;
+   struct ccg_dev_info info;
+   /* version info for boot, primary and secondary */
+   struct version_info version[FW2 + 1];
 };
 
-#define CCGX_RAB_INTR_REG  0x06
-#define CCGX_RAB_UCSI_CONTROL  0x39
+#define CCGX_RAB_DEVICE_MODE   0x
+#define CCGX_RAB_INTR_REG  0x0006
+#define CCGX_RAB_READ_ALL_VER  0x0010
+#define CCGX_RAB_READ_FW2_VER  0x0020
+#define CCGX_RAB_UCSI_CONTROL  0x0039
 #define CCGX_RAB_UCSI_CONTROL_STARTBIT(0)
 #define CCGX_RAB_UCSI_CONTROL_STOP BIT(1)
 #define CCGX_RAB_UCSI_DATA_BLOCK(offset)   (0xf000 | ((offset) & 0xff))
@@ -220,6 +259,23 @@ static irqreturn_t ccg_irq_handler(int irq, void *data)
return IRQ_HANDLED;
 }
 
+static int get_fw_info(struct ucsi_ccg *uc)
+{
+   int err;
+
+   err = ccg_read(uc, CCGX_RAB_READ_ALL_VER, (u8 *)(&uc->version),
+  sizeof(uc->version));
+   if (err < 0)
+   return err;
+
+   err = ccg_read(uc, CCGX_RAB_DEVICE_MODE, (u8 *)(&uc->info),
+  sizeof(uc->info));
+   if (err < 0)
+   return err;
+
+   return 0;
+}
+
 static int ucsi_ccg_probe(struct i2c_client *client,
  const struct i2c_device_id *id)
 {
@@ -248,6 +304,12 @@ static int ucsi_ccg_probe(struct i2c_client *client,
return status;
}
 
+   status = get_fw_info(uc);
+   if (status < 0) {
+   dev_err(uc->dev, "get_fw_info failed - %d\n", status);
+   return status;
+   }
+
status = devm_request_threaded_irq(dev, client->irq, NULL,
   ccg_irq_handler,
   IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
-- 
2.20.1



[PATCH 2/4] usb: typec: ucsi: ccg: add firmware flashing support

2019-04-10 Thread Heikki Krogerus
From: Ajay Gupta 

CCGx has two copies of the firmware in addition to the bootloader.
If the device is running FW1, FW2 can be updated with the new version.
Dual firmware mode allows the CCG device to stay in a PD contract and
support USB PD and Type-C functionality while a firmware update is in
progress.

First we read the currently flashed firmware version of both
primary and secondary firmware and then compare it with
version of firmware file to determine if flashing is required.

Command framework is added to support sending commands to CCGx
controller. We wait for response after sending the command and then
read the response from RAB_RESPONSE register.

Below commands are supported,
- ENTER_FLASHING
- RESET
- PDPORT_ENABLE
- JUMP_TO_BOOT
- FLASH_ROW_RW
- VALIDATE_FW

Command specific mutex lock is also added to sync between driver
and user threads.

PD port number information is added which is required while sending
PD_PORT_ENABLE command

Signed-off-by: Ajay Gupta 
Signed-off-by: Heikki Krogerus 
---
 drivers/usb/typec/ucsi/ucsi_ccg.c | 828 +-
 1 file changed, 815 insertions(+), 13 deletions(-)

diff --git a/drivers/usb/typec/ucsi/ucsi_ccg.c 
b/drivers/usb/typec/ucsi/ucsi_ccg.c
index 3884fb41c72e..5508beec08e3 100644
--- a/drivers/usb/typec/ucsi/ucsi_ccg.c
+++ b/drivers/usb/typec/ucsi/ucsi_ccg.c
@@ -9,6 +9,7 @@
  */
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -24,6 +25,73 @@ enum enum_fw_mode {
FW_INVALID,
 };
 
+#define CCGX_RAB_DEVICE_MODE   0x
+#define CCGX_RAB_INTR_REG  0x0006
+#define  DEV_INT   BIT(0)
+#define  PORT0_INT BIT(1)
+#define  PORT1_INT BIT(2)
+#define  UCSI_READ_INT BIT(7)
+#define CCGX_RAB_JUMP_TO_BOOT  0x0007
+#define  TO_BOOT   'J'
+#define  TO_ALT_FW 'A'
+#define CCGX_RAB_RESET_REQ 0x0008
+#define  RESET_SIG 'R'
+#define  CMD_RESET_I2C 0x0
+#define  CMD_RESET_DEV 0x1
+#define CCGX_RAB_ENTER_FLASHING0x000A
+#define  FLASH_ENTER_SIG   'P'
+#define CCGX_RAB_VALIDATE_FW   0x000B
+#define CCGX_RAB_FLASH_ROW_RW  0x000C
+#define  FLASH_SIG 'F'
+#define  FLASH_RD_CMD  0x0
+#define  FLASH_WR_CMD  0x1
+#define  FLASH_FWCT1_WR_CMD0x2
+#define  FLASH_FWCT2_WR_CMD0x3
+#define  FLASH_FWCT_SIG_WR_CMD 0x4
+#define CCGX_RAB_READ_ALL_VER  0x0010
+#define CCGX_RAB_READ_FW2_VER  0x0020
+#define CCGX_RAB_UCSI_CONTROL  0x0039
+#define CCGX_RAB_UCSI_CONTROL_STARTBIT(0)
+#define CCGX_RAB_UCSI_CONTROL_STOP BIT(1)
+#define CCGX_RAB_UCSI_DATA_BLOCK(offset)   (0xf000 | ((offset) & 0xff))
+#define REG_FLASH_RW_MEM0x0200
+#define DEV_REG_IDXCCGX_RAB_DEVICE_MODE
+#define CCGX_RAB_PDPORT_ENABLE 0x002C
+#define  PDPORT_1  BIT(0)
+#define  PDPORT_2  BIT(1)
+#define CCGX_RAB_RESPONSE  0x007E
+#define  ASYNC_EVENT   BIT(7)
+
+/* CCGx events & async msg codes */
+#define RESET_COMPLETE 0x80
+#define EVENT_INDEXRESET_COMPLETE
+#define PORT_CONNECT_DET   0x84
+#define PORT_DISCONNECT_DET0x85
+#define ROLE_SWAP_COMPELETE0x87
+
+/* ccg firmware */
+#define CYACD_LINE_SIZE 527
+#define CCG4_ROW_SIZE   256
+#define FW1_METADATA_ROW0x1FF
+#define FW2_METADATA_ROW0x1FE
+#define FW_CFG_TABLE_SIG_SIZE  256
+
+static int secondary_fw_min_ver = 41;
+
+enum enum_flash_mode {
+   SECONDARY_BL,   /* update secondary using bootloader */
+   PRIMARY,/* update primary using secondary */
+   SECONDARY,  /* update secondary using primary */
+   FLASH_NOT_NEEDED,   /* update not required */
+   FLASH_INVALID,
+};
+
+static const char * const ccg_fw_names[] = {
+   "ccg_boot.cyacd",
+   "ccg_primary.cyacd",
+   "ccg_secondary.cyacd"
+};
+
 struct ccg_dev_info {
 #define CCG_DEVINFO_FWMODE_SHIFT (0)
 #define CCG_DEVINFO_FWMODE_MASK (0x3 << CCG_DEVINFO_FWMODE_SHIFT)
@@ -50,6 +118,50 @@ struct version_info {
struct version_format app;
 };
 
+struct fw_config_table {
+   u32 identity;
+   u16 table_size;
+   u8 fwct_version;
+   u8 is_key_change;
+   u8 guid[16];
+   struct version_format base;
+   struct version_format app;
+   u8 primary_fw_digest[32];
+   u32 key_exp_length;
+   u8 key_modulus[256];
+   u8 key_exp[4];
+};
+
+/* CCGx response codes */
+enum ccg_res

[PATCH 4/4] usb: typec: ucsi: Support for DisplayPort alt mode

2019-04-10 Thread Heikki Krogerus
This makes it possible to bind a driver to a DisplayPort
alt mode adapter devices.

The driver attempts to cope with the limitations of UCSI by
"emulating" behaviour and attempting to guess things when
ever possible in order to satisfy the requirements the
standard DisplayPort alt mode driver has.

Tested-by: Ajay Gupta 
Signed-off-by: Heikki Krogerus 
---
 drivers/usb/typec/ucsi/Makefile  |  15 +-
 drivers/usb/typec/ucsi/displayport.c | 297 +++
 drivers/usb/typec/ucsi/ucsi.c|  21 +-
 drivers/usb/typec/ucsi/ucsi.h|  21 ++
 4 files changed, 346 insertions(+), 8 deletions(-)
 create mode 100644 drivers/usb/typec/ucsi/displayport.c

diff --git a/drivers/usb/typec/ucsi/Makefile b/drivers/usb/typec/ucsi/Makefile
index 2f4900b26210..b35e15a1f02c 100644
--- a/drivers/usb/typec/ucsi/Makefile
+++ b/drivers/usb/typec/ucsi/Makefile
@@ -1,12 +1,15 @@
 # SPDX-License-Identifier: GPL-2.0
-CFLAGS_trace.o := -I$(src)
+CFLAGS_trace.o := -I$(src)
 
-obj-$(CONFIG_TYPEC_UCSI)   += typec_ucsi.o
+obj-$(CONFIG_TYPEC_UCSI)   += typec_ucsi.o
 
-typec_ucsi-y   := ucsi.o
+typec_ucsi-y   := ucsi.o
 
-typec_ucsi-$(CONFIG_TRACING)   += trace.o
+typec_ucsi-$(CONFIG_TRACING)   += trace.o
 
-obj-$(CONFIG_UCSI_ACPI)+= ucsi_acpi.o
+ifneq ($(CONFIG_TYPEC_DP_ALTMODE),)
+   typec_ucsi-y+= displayport.o
+endif
 
-obj-$(CONFIG_UCSI_CCG) += ucsi_ccg.o
+obj-$(CONFIG_UCSI_ACPI)+= ucsi_acpi.o
+obj-$(CONFIG_UCSI_CCG) += ucsi_ccg.o
diff --git a/drivers/usb/typec/ucsi/displayport.c 
b/drivers/usb/typec/ucsi/displayport.c
new file mode 100644
index ..2964103a6fc6
--- /dev/null
+++ b/drivers/usb/typec/ucsi/displayport.c
@@ -0,0 +1,297 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * UCSI DisplayPort Alternate Mode Support
+ *
+ * Copyright (C) 2018, Intel Corporation
+ * Author: Heikki Krogerus 
+ */
+
+#include 
+#include 
+
+#include "ucsi.h"
+
+#define UCSI_CMD_SET_NEW_CAM(_con_num_, _enter_, _cam_, _am_)  \
+(UCSI_SET_NEW_CAM | ((_con_num_) << 16) | ((_enter_) << 23) |  \
+ ((_cam_) << 24) | ((u64)(_am_) << 32))
+
+struct ucsi_dp {
+   struct typec_displayport_data data;
+   struct ucsi_connector *con;
+   struct typec_altmode *alt;
+   struct work_struct work;
+   int offset;
+
+   bool override;
+   bool initialized;
+
+   u32 header;
+   u32 *vdo_data;
+   u8 vdo_size;
+};
+
+/*
+ * Note. Alternate mode control is optional feature in UCSI. It means that even
+ * if the system supports alternate modes, the OS may not be aware of them.
+ *
+ * In most cases however, the OS will be able to see the supported alternate
+ * modes, but it may still not be able to configure them, not even enter or 
exit
+ * them. That is because UCSI defines alt mode details and alt mode 
"overriding"
+ * as separate options.
+ *
+ * In case alt mode details are supported, but overriding is not, the driver
+ * will still display the supported pin assignments and configuration, but any
+ * changes the user attempts to do will lead into failure with return value of
+ * -EOPNOTSUPP.
+ */
+
+static int ucsi_displayport_enter(struct typec_altmode *alt)
+{
+   struct ucsi_dp *dp = typec_altmode_get_drvdata(alt);
+
+   mutex_lock(&dp->con->lock);
+
+   if (!dp->override && dp->initialized) {
+   const struct typec_altmode *p = typec_altmode_get_partner(alt);
+
+   dev_warn(&p->dev,
+"firmware doesn't support alternate mode 
overriding\n");
+   mutex_unlock(&dp->con->lock);
+   return -EOPNOTSUPP;
+   }
+
+   /*
+* We can't send the New CAM command yet to the PPM as it needs the
+* configuration value as well. Pretending that we have now entered the
+* mode, and letting the alt mode driver continue.
+*/
+
+   dp->header = VDO(USB_TYPEC_DP_SID, 1, CMD_ENTER_MODE);
+   dp->header |= VDO_OPOS(USB_TYPEC_DP_MODE);
+   dp->header |= VDO_CMDT(CMDT_RSP_ACK);
+
+   dp->vdo_data = NULL;
+   dp->vdo_size = 1;
+
+   schedule_work(&dp->work);
+
+   mutex_unlock(&dp->con->lock);
+
+   return 0;
+}
+
+static int ucsi_displayport_exit(struct typec_altmode *alt)
+{
+   struct ucsi_dp *dp = typec_altmode_get_drvdata(alt);
+   struct ucsi_control ctrl;
+   int ret = 0;
+
+   mutex_lock(&dp->con->lock);
+
+   if (!dp->override) {
+   const struct typec_altmode *p = typec_altmode_get_partner(alt);
+
+   dev_warn(&p->dev,
+"firmware doesn't support alternate mode 
overriding\n");
+   ret = -EOPNOTSUPP;
+   goto out_unlock;
+   }
+
+   ctrl.raw_cmd = UCSI_CMD_SET_NEW_CAM(dp->con->num, 0, dp->offset, 0);
+   ret = ucsi_send_command(dp->con->uc

[PATCH 0/4] usb: typec: ucsi: Remaining changes for v5.2

2019-04-10 Thread Heikki Krogerus
Hi Greg,

Here are the remaining patches from me and Ajay for the UCSI driver. I
took the liberty of collecting them for you, and resending everything
together.

There are two patches from Ajay adding support for firmware upgrading
with the Cypress CCGx controllers [1], and two patches from me
enabling DisplayPort alt mode with the UCSI driver [2].

[1] https://marc.info/?l=linux-usb&m=154957412422108&w=2
[2] https://www.spinics.net/lists/linux-usb/msg178192.html

Let us know if there if you want anything to be changed.

thanks,

--
heikki

Ajay Gupta (2):
  usb: typec: ucsi: ccg: add get_fw_info function
  usb: typec: ucsi: ccg: add firmware flashing support

Heikki Krogerus (2):
  usb: typec: ucsi: Preliminary support for alternate modes
  usb: typec: ucsi: Support for DisplayPort alt mode

 drivers/usb/typec/ucsi/Makefile  |  15 +-
 drivers/usb/typec/ucsi/displayport.c | 297 +
 drivers/usb/typec/ucsi/trace.c   |  12 +
 drivers/usb/typec/ucsi/trace.h   |  26 +
 drivers/usb/typec/ucsi/ucsi.c| 371 +--
 drivers/usb/typec/ucsi/ucsi.h|  93 +++
 drivers/usb/typec/ucsi/ucsi_ccg.c| 884 ++-
 7 files changed, 1617 insertions(+), 81 deletions(-)
 create mode 100644 drivers/usb/typec/ucsi/displayport.c

-- 
2.20.1



[PATCH 3/4] usb: typec: ucsi: Preliminary support for alternate modes

2019-04-10 Thread Heikki Krogerus
With UCSI the alternate modes, just like everything else
related to USB Type-C connectors, are handled in firmware.
The operating system can see the status and is allowed to
request certain things, for example entering and exiting the
modes, but the support for alternate modes is very limited
in UCSI. The feature is also optional, which means that even
when the platform supports alternate modes, the operating
system may not be even made aware of them.

UCSI does not support direct VDM reading or writing.
Instead, alternate modes can be entered and exited using a
single custom command which takes also an optional SVID
specific configuration value as parameter. That means every
supported alternate mode has to be handled separately in
UCSI driver.

This commit does not include support for any specific
alternate mode. The discovered alternate modes are now
registered, but binding a driver to an alternate mode will
not be possible until support for that alternate mode is
added to the UCSI driver.

Tested-by: Ajay Gupta 
Signed-off-by: Heikki Krogerus 
---
 drivers/usb/typec/ucsi/trace.c |  12 ++
 drivers/usb/typec/ucsi/trace.h |  26 +++
 drivers/usb/typec/ucsi/ucsi.c  | 354 +++--
 drivers/usb/typec/ucsi/ucsi.h  |  72 +++
 4 files changed, 399 insertions(+), 65 deletions(-)

diff --git a/drivers/usb/typec/ucsi/trace.c b/drivers/usb/typec/ucsi/trace.c
index ffa3b4c3f338..1dabafb74320 100644
--- a/drivers/usb/typec/ucsi/trace.c
+++ b/drivers/usb/typec/ucsi/trace.c
@@ -60,3 +60,15 @@ const char *ucsi_cci_str(u32 cci)
 
return "";
 }
+
+static const char * const ucsi_recipient_strs[] = {
+   [UCSI_RECIPIENT_CON]= "port",
+   [UCSI_RECIPIENT_SOP]= "partner",
+   [UCSI_RECIPIENT_SOP_P]  = "plug (prime)",
+   [UCSI_RECIPIENT_SOP_PP] = "plug (double prime)",
+};
+
+const char *ucsi_recipient_str(u8 recipient)
+{
+   return ucsi_recipient_strs[recipient];
+}
diff --git a/drivers/usb/typec/ucsi/trace.h b/drivers/usb/typec/ucsi/trace.h
index 5e2906df2db7..783ec9c72055 100644
--- a/drivers/usb/typec/ucsi/trace.h
+++ b/drivers/usb/typec/ucsi/trace.h
@@ -7,6 +7,7 @@
 #define __UCSI_TRACE_H
 
 #include 
+#include 
 
 const char *ucsi_cmd_str(u64 raw_cmd);
 const char *ucsi_ack_str(u8 ack);
@@ -134,6 +135,31 @@ DEFINE_EVENT(ucsi_log_connector_status, ucsi_register_port,
TP_ARGS(port, status)
 );
 
+DECLARE_EVENT_CLASS(ucsi_log_register_altmode,
+   TP_PROTO(u8 recipient, struct typec_altmode *alt),
+   TP_ARGS(recipient, alt),
+   TP_STRUCT__entry(
+   __field(u8, recipient)
+   __field(u16, svid)
+   __field(u8, mode)
+   __field(u32, vdo)
+   ),
+   TP_fast_assign(
+   __entry->recipient = recipient;
+   __entry->svid = alt->svid;
+   __entry->mode = alt->mode;
+   __entry->vdo = alt->vdo;
+   ),
+   TP_printk("%s alt mode: svid %04x, mode %d vdo %x",
+ ucsi_recipient_str(__entry->recipient), __entry->svid,
+ __entry->mode, __entry->vdo)
+);
+
+DEFINE_EVENT(ucsi_log_register_altmode, ucsi_register_altmode,
+   TP_PROTO(u8 recipient, struct typec_altmode *alt),
+   TP_ARGS(recipient, alt)
+);
+
 #endif /* __UCSI_TRACE_H */
 
 /* This part must be outside protection */
diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
index 8d0a6fe748bd..11d1884322c2 100644
--- a/drivers/usb/typec/ucsi/ucsi.c
+++ b/drivers/usb/typec/ucsi/ucsi.c
@@ -12,7 +12,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 
 #include "ucsi.h"
 #include "trace.h"
@@ -45,22 +45,6 @@ enum ucsi_status {
UCSI_ERROR,
 };
 
-struct ucsi_connector {
-   int num;
-
-   struct ucsi *ucsi;
-   struct work_struct work;
-   struct completion complete;
-
-   struct typec_port *port;
-   struct typec_partner *partner;
-
-   struct typec_capability typec_cap;
-
-   struct ucsi_connector_status status;
-   struct ucsi_connector_capability cap;
-};
-
 struct ucsi {
struct device *dev;
struct ucsi_ppm *ppm;
@@ -238,8 +222,200 @@ static int ucsi_run_command(struct ucsi *ucsi, struct 
ucsi_control *ctrl,
return ret;
 }
 
+int ucsi_send_command(struct ucsi *ucsi, struct ucsi_control *ctrl,
+ void *retval, size_t size)
+{
+   int ret;
+
+   mutex_lock(&ucsi->ppm_lock);
+   ret = ucsi_run_command(ucsi, ctrl, retval, size);
+   mutex_unlock(&ucsi->ppm_lock);
+
+   return ret;
+}
+
 /* -- 
*/
 
+void ucsi_altmode_update_active(struct ucsi_connector *con)
+{
+   const struct typec_altmode *altmode = NULL;
+   struct ucsi_control ctrl;
+   int ret;
+   u8 cur;
+   int i;
+
+   UCSI_CMD_GET_CURRENT_CAM(ctrl, con->num);
+   ret = ucsi_run_command(con->ucsi, &ctrl, &cur, sizeof(cur));

Re: [PATCH v2 0/5] usb: dwc2: Improve gadget phy init

2019-04-10 Thread Minas Harutyunyan
On 4/5/2019 5:36 PM, Jules Maselbas wrote:
> Hi,
> 
> Theses patches tries to clean a bit dwc2's phy initialization and
> fix an issue in gadget mode where the utmi phy width is set
> regardless of utmi being used or not.
> 
> I believe that when using ulpi a phy width of 8 bits must be used,
> but this wasn't the case as the variable phyif was set by default
> to 16 bits.
> 
> In this second patch-set version the last two patches are optionnal,
> from my point of view they are not essential for me but I hope they
> can improve this driver.
> 
> Best regards,
> Jules
> ---
> Changes in v2:
>- Changed patches order
>- dwc2_init_fs_ls_pclk_sel is now declared in core.h (to be used in hcd.c)
>- Fix patch `Replace phyif with phy_utmi_width` (wrong value set to usbcfg)
>- Add check for utmi phy type in patch `Replace phyif with phy_utmi_width`
> 
> ---
> Jules Maselbas (5):
>usb: dwc2: Move UTMI_PHY_DATA defines closer
>usb: dwc2: gadget: Remove duplicated phy init
>usb: dwc2: gadget: Replace phyif with phy_utmi_width
>usb: dwc2: Move phy init into core
>usb: dwc2: gadget: Move gadget phy init into core phy init
> 
>   drivers/usb/dwc2/core.c | 199 
>   drivers/usb/dwc2/core.h |   4 +-
>   drivers/usb/dwc2/gadget.c   |  36 ++-
>   drivers/usb/dwc2/hcd.c  | 190 --
>   drivers/usb/dwc2/hw.h   |   6 +-
>   drivers/usb/dwc2/platform.c |   5 +-
>   6 files changed, 213 insertions(+), 227 deletions(-)
> 
Acked-by: Minas Harutyunyan 


Re: lan78xx: About 8000 usb interrupts per second when idle

2019-04-10 Thread Jisheng Zhang
On Tue, 9 Apr 2019 09:28:16 + Minas Harutyunyan wrote:


> 
> Hi Stefan,
> 
> > Hi Minas,
> >
> > Am 09.04.19 um 08:54 schrieb Jisheng Zhang:  
> >> On Mon, 8 Apr 2019 16:05:51 +0800 Jisheng Zhang wrote:
> >>  
> >>> Hi Stefan,
> >>>
> >>> On Mon, 8 Apr 2019 09:57:14 +0200 Stefan Wahren wrote:
> >>>  
> 
>  Hi Jisheng,
> 
> 
>  thanks for sending this patch.  I already reported this issue
>  last year [1], but Microchip wasn't able to provide a fix.
> 
>  I will give it a try.
>   
> > The second one: 8000 usb interrupts per second when idle.
> > This is abnormal. any idea? Is it due to the lan78xx?  
>  Does this downstream patch [2] improve your situation?  
> >>> Thanks a lot. Will try the patch tonight.  
> >> I tried this patch, it doesn't help. One more observation: if I
> >> ifconfig eth0 down, I can still get 8000 usb interrupts per second.
> >>  Not sure whether this is usb issue or not.  
> >
> > Jisheng reports a lot of USB interrupts while the lan78xx driver on
> > Raspberry Pi 3B+ is in idle.
> >
> > Any suggestions to narrow this down?  
> 
> dwc2 in host mode enable SOF interrupts if any periodic EP are in use.
> So, 8000 interrupts per second is expectant behavior.

Makes sense. 8 microframes each 1ms, so 8*1000 = 8000 interrupts/s


Re: lan78xx: About 8000 usb interrupts per second when idle

2019-04-10 Thread Oliver Neukum
On Mi, 2019-04-10 at 09:37 +, Jisheng Zhang wrote:
> On Tue, 9 Apr 2019 09:28:16 + Minas Harutyunyan wrote:

Hi,

> > dwc2 in host mode enable SOF interrupts if any periodic EP are in use.
> > So, 8000 interrupts per second is expectant behavior.
> 
> Makes sense. 8 microframes each 1ms, so 8*1000 = 8000 interrupts/s

The remedy for that would be using autosuspend. That just tells us that
support for autosuspend is not optional.

Regards
Oliver



Re: [PATCH 2/4] usb: typec: ucsi: ccg: add firmware flashing support

2019-04-10 Thread kbuild test robot
Hi Heikki,

I love your patch! Perhaps something to improve:

[auto build test WARNING on usb/usb-testing]
[also build test WARNING on v5.1-rc4 next-20190410]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Heikki-Krogerus/usb-typec-ucsi-Remaining-changes-for-v5-2/20190410-221455
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git 
usb-testing
reproduce:
# apt-get install sparse
make ARCH=x86_64 allmodconfig
make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'


sparse warnings: (new ones prefixed by >>)

   drivers/usb/typec/ucsi/ucsi_ccg.c:212:24: sparse: expression using 
sizeof(void)
   drivers/usb/typec/ucsi/ucsi_ccg.c:212:24: sparse: expression using 
sizeof(void)
>> drivers/usb/typec/ucsi/ucsi_ccg.c:690:16: sparse: restricted __le16 degrades 
>> to integer
   drivers/usb/typec/ucsi/ucsi_ccg.c:698:24: sparse: restricted __le16 degrades 
to integer
   drivers/usb/typec/ucsi/ucsi_ccg.c:735:26: sparse: restricted __le16 degrades 
to integer
   drivers/usb/typec/ucsi/ucsi_ccg.c:737:33: sparse: restricted __le16 degrades 
to integer
   drivers/usb/typec/ucsi/ucsi_ccg.c:777:37: sparse: restricted __le16 degrades 
to integer

vim +690 drivers/usb/typec/ucsi/ucsi_ccg.c

   680  
   681  static bool ccg_check_vendor_version(struct ucsi_ccg *uc,
   682   struct version_format *app,
   683   struct fw_config_table *fw_cfg)
   684  {
   685  struct device *dev = uc->dev;
   686  
   687  /* Check if the fw build is for supported vendors.
   688   * Add all supported vendors here.
   689   */
 > 690  if (app->build != (('n' << 8) | 'v')) {
   691  dev_info(dev, "current fw is not from supported 
vendor\n");
   692  return false;
   693  }
   694  
   695  /* Check if the new fw build is for supported vendors
   696   * Add all supported vendors here.
   697   */
   698  if (fw_cfg->app.build != (('n' << 8) | 'v')) {
   699  dev_info(dev, "new fw is not from supported vendor\n");
   700  return false;
   701  }
   702  return true;
   703  }
   704  

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


[PATCH 2/2] usb: typec: Add driver for NVIDIA Alt Modes

2019-04-10 Thread Ajay Gupta
From: Ajay Gupta 

Latest NVIDIA GPUs support VirtualLink device. Since USBIF
has not assigned a Standard ID (SID) for VirtualLink
so using NVIDA VID 0x955 as SVID.

Signed-off-by: Ajay Gupta 
---
 drivers/usb/typec/altmodes/Kconfig  | 10 +++
 drivers/usb/typec/altmodes/Makefile |  2 ++
 drivers/usb/typec/altmodes/nvidia.c | 44 +
 drivers/usb/typec/ucsi/ucsi.c   |  4 ++-
 include/linux/usb/typec_dp.h|  5 
 5 files changed, 64 insertions(+), 1 deletion(-)
 create mode 100644 drivers/usb/typec/altmodes/nvidia.c

diff --git a/drivers/usb/typec/altmodes/Kconfig 
b/drivers/usb/typec/altmodes/Kconfig
index ef2226eb7a33..187690fd1a5b 100644
--- a/drivers/usb/typec/altmodes/Kconfig
+++ b/drivers/usb/typec/altmodes/Kconfig
@@ -12,4 +12,14 @@ config TYPEC_DP_ALTMODE
  To compile this driver as a module, choose M here: the
  module will be called typec_displayport.
 
+config TYPEC_NVIDIA_ALTMODE
+   tristate "NVIDIA Alternate Mode driver"
+   depends on TYPEC_DP_ALTMODE
+   help
+ Latest NVIDIA GPUs support VirtualLink devices. Select this
+ to enable support for VirtualLink devices with NVIDIA GPUs.
+
+ To compile this driver as a module, choose M here: the
+ module will be called typec_displayport.
+
 endmenu
diff --git a/drivers/usb/typec/altmodes/Makefile 
b/drivers/usb/typec/altmodes/Makefile
index eda8456f1c92..45717548b396 100644
--- a/drivers/usb/typec/altmodes/Makefile
+++ b/drivers/usb/typec/altmodes/Makefile
@@ -2,3 +2,5 @@
 
 obj-$(CONFIG_TYPEC_DP_ALTMODE) += typec_displayport.o
 typec_displayport-y:= displayport.o
+obj-$(CONFIG_TYPEC_NVIDIA_ALTMODE) += typec_nvidia.o
+typec_nvidia-y := nvidia.o
diff --git a/drivers/usb/typec/altmodes/nvidia.c 
b/drivers/usb/typec/altmodes/nvidia.c
new file mode 100644
index ..c36769736405
--- /dev/null
+++ b/drivers/usb/typec/altmodes/nvidia.c
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 NVIDIA Corporation. All rights reserved.
+ *
+ * NVIDIA USB Type-C Alt Mode Driver
+ */
+#include 
+#include 
+#include 
+#include "displayport.h"
+
+static int nvidia_altmode_probe(struct typec_altmode *alt)
+{
+   if (alt->svid == USB_TYPEC_NVIDIA_VLINK_SID)
+   return dp_altmode_probe(alt);
+   else
+   return -ENOTSUPP;
+}
+
+static void nvidia_altmode_remove(struct typec_altmode *alt)
+{
+   if (alt->svid == USB_TYPEC_NVIDIA_VLINK_SID)
+   dp_altmode_remove(alt);
+}
+
+static const struct typec_device_id nvidia_typec_id[] = {
+   { USB_TYPEC_NVIDIA_VLINK_SID, TYPEC_ANY_MODE },
+   { },
+};
+MODULE_DEVICE_TABLE(typec, nvidia_typec_id);
+
+static struct typec_altmode_driver nvidia_altmode_driver = {
+   .id_table = nvidia_typec_id,
+   .probe = nvidia_altmode_probe,
+   .remove = nvidia_altmode_remove,
+   .driver = {
+   .name = "typec_nvidia",
+   .owner = THIS_MODULE,
+   },
+};
+module_typec_altmode_driver(nvidia_altmode_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("NVIDIA USB Type-C Alt Mode Driver");
diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
index 46feae074d8f..a8c8e66621ec 100644
--- a/drivers/usb/typec/ucsi/ucsi.c
+++ b/drivers/usb/typec/ucsi/ucsi.c
@@ -306,6 +306,7 @@ static int ucsi_register_altmode(struct ucsi_connector *con,
 
switch (desc->svid) {
case USB_TYPEC_DP_SID:
+   case USB_TYPEC_NVIDIA_VLINK_SID:
alt = ucsi_register_displayport(con, override, i, desc);
break;
default:
@@ -424,7 +425,8 @@ static void ucsi_unregister_altmodes(struct ucsi_connector 
*con, u8 recipient)
 
while (adev[i]) {
if (recipient == UCSI_RECIPIENT_SOP &&
-   adev[i]->svid == USB_TYPEC_DP_SID) {
+   (adev[i]->svid == USB_TYPEC_DP_SID ||
+   adev[i]->svid == USB_TYPEC_NVIDIA_VLINK_SID)) {
pdev = typec_altmode_get_partner(adev[i]);
ucsi_displayport_remove_partner((void *)pdev);
}
diff --git a/include/linux/usb/typec_dp.h b/include/linux/usb/typec_dp.h
index 7fa12ef8d09a..fc4c7edb2e8a 100644
--- a/include/linux/usb/typec_dp.h
+++ b/include/linux/usb/typec_dp.h
@@ -5,6 +5,11 @@
 #include 
 
 #define USB_TYPEC_DP_SID   0xff01
+/* USB IF has not assigned a Standard ID (SID) for VirtualLink,
+ * so the manufacturers of VirtualLink adapters use their Vendor
+ * IDs as the SVID.
+ */
+#define USB_TYPEC_NVIDIA_VLINK_SID 0x955   /* NVIDIA VirtualLink */
 #define USB_TYPEC_DP_MODE  1
 
 /*
-- 
2.17.1



[PATCH 1/2] usb: typec: displayport: Export probe and remove functions

2019-04-10 Thread Ajay Gupta
From: Heikki Krogerus 

VirtualLink standard extends the DisplayPort Alt Mode by
utilizing also the USB 2 pins on the USB Type-C connector.
It uses the same messages as DisplayPort, but not the DP
SVID. At the time of writing, USB IF has not assigned a
Standard ID (SID) for VirtualLink, so the manufacturers of
VirtualLink adapters use their Vendor IDs as the SVID.

Since the SVID specific communication is exactly the same as
with DisplayPort alternate mode, there is no need to
implement separate driver for VirtualLink. We'll handle the
current VirtualLink adapters with probe drivers, and once
there is SVID assigned for it, we add it to the displayport
alt mode driver.

To support probing drivers, exporting the probe and remove
functions, and also changing the DP_HEADER helper macro to
use the SVID of the alternate mode device instead of the
DisplayPort alt mode SVID.

[Fixed two warnings from checkpatch.pl script  -Ajay]
Signed-off-by: Heikki Krogerus 
Signed-off-by: Ajay Gupta 
Tested-by: Ajay Gupta 
---
 drivers/usb/typec/altmodes/displayport.c | 12 +++-
 drivers/usb/typec/altmodes/displayport.h |  8 
 2 files changed, 15 insertions(+), 5 deletions(-)
 create mode 100644 drivers/usb/typec/altmodes/displayport.h

diff --git a/drivers/usb/typec/altmodes/displayport.c 
b/drivers/usb/typec/altmodes/displayport.c
index 610d790bc9be..bbf317c838d3 100644
--- a/drivers/usb/typec/altmodes/displayport.c
+++ b/drivers/usb/typec/altmodes/displayport.c
@@ -14,7 +14,7 @@
 #include 
 #include 
 
-#define DP_HEADER(cmd) (VDO(USB_TYPEC_DP_SID, 1, cmd) | \
+#define DP_HEADER(_dp, cmd)(VDO((_dp)->alt->svid, 1, cmd) | \
 VDO_OPOS(USB_TYPEC_DP_MODE))
 
 enum {
@@ -155,7 +155,7 @@ static int dp_altmode_configured(struct dp_altmode *dp)
 
 static int dp_altmode_configure_vdm(struct dp_altmode *dp, u32 conf)
 {
-   u32 header = DP_HEADER(DP_CMD_CONFIGURE);
+   u32 header = DP_HEADER(dp, DP_CMD_CONFIGURE);
int ret;
 
ret = typec_altmode_notify(dp->alt, TYPEC_STATE_SAFE, &dp->data);
@@ -193,7 +193,7 @@ static void dp_altmode_work(struct work_struct *work)
dev_err(&dp->alt->dev, "failed to enter mode\n");
break;
case DP_STATE_UPDATE:
-   header = DP_HEADER(DP_CMD_STATUS_UPDATE);
+   header = DP_HEADER(dp, DP_CMD_STATUS_UPDATE);
vdo = 1;
ret = typec_altmode_vdm(dp->alt, header, &vdo, 2);
if (ret)
@@ -507,7 +507,7 @@ static const struct attribute_group dp_altmode_group = {
.attrs = dp_altmode_attrs,
 };
 
-static int dp_altmode_probe(struct typec_altmode *alt)
+int dp_altmode_probe(struct typec_altmode *alt)
 {
const struct typec_altmode *port = typec_altmode_get_partner(alt);
struct dp_altmode *dp;
@@ -545,14 +545,16 @@ static int dp_altmode_probe(struct typec_altmode *alt)
 
return 0;
 }
+EXPORT_SYMBOL_GPL(dp_altmode_probe);
 
-static void dp_altmode_remove(struct typec_altmode *alt)
+void dp_altmode_remove(struct typec_altmode *alt)
 {
struct dp_altmode *dp = typec_altmode_get_drvdata(alt);
 
sysfs_remove_group(&alt->dev.kobj, &dp_altmode_group);
cancel_work_sync(&dp->work);
 }
+EXPORT_SYMBOL_GPL(dp_altmode_remove);
 
 static const struct typec_device_id dp_typec_id[] = {
{ USB_TYPEC_DP_SID, USB_TYPEC_DP_MODE },
diff --git a/drivers/usb/typec/altmodes/displayport.h 
b/drivers/usb/typec/altmodes/displayport.h
new file mode 100644
index ..e120364da9fd
--- /dev/null
+++ b/drivers/usb/typec/altmodes/displayport.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#if IS_ENABLED(CONFIG_TYPEC_DP_ALTMODE)
+int dp_altmode_probe(struct typec_altmode *alt);
+void dp_altmode_remove(struct typec_altmode *alt);
+#else
+int dp_altmode_probe(struct typec_altmode *alt) { return -ENOTSUPP; }
+void dp_altmode_remove(struct typec_altmode *alt) { }
+#endif /* CONFIG_TYPEC_DP_ALTMODE */
-- 
2.17.1



[PATCH 0/2] Add VirtualLink display altmode support

2019-04-10 Thread Ajay Gupta
Hi Heikki,

Please help review these two changes which adds support for
VirtualLink display altmode devices using NVIDIA GPU.

You had shared the first patch during our offline discussion.
The second patch adds NVIDIA display altmode driver.

This set is created against latest Linus's kernel and patches
at [1] forwarded to Greg from you.

[1] https://marc.info/?l=linux-usb&m=155488414908414&w=2 

Thanks
Ajay

Ajay Gupta (1):
  usb: typec: Add driver for NVIDIA Alt Modes

Heikki Krogerus (1):
  usb: typec: displayport: Export probe and remove functions

 drivers/usb/typec/altmodes/Kconfig   | 10 ++
 drivers/usb/typec/altmodes/Makefile  |  2 ++
 drivers/usb/typec/altmodes/displayport.c | 12 ---
 drivers/usb/typec/altmodes/displayport.h |  8 +
 drivers/usb/typec/altmodes/nvidia.c  | 44 
 drivers/usb/typec/ucsi/ucsi.c|  4 ++-
 include/linux/usb/typec_dp.h |  5 +++
 7 files changed, 79 insertions(+), 6 deletions(-)
 create mode 100644 drivers/usb/typec/altmodes/displayport.h
 create mode 100644 drivers/usb/typec/altmodes/nvidia.c

-- 
2.17.1



Re: Kernel oops when using multiple V4L cameras on ODroid-C2 meson: 9600004f in dwc2_unmap_urb_for_dma+0x1c/0x28

2019-04-10 Thread Wayne Piekarski

Hi Minas,

Thanks for your reply. I did some more playing with this, and found that 
I can cause kernel oops and reboot even with just one camera and by just 
probing it with v4l2-ctl.


for each in `ls -1 /dev/video* /dev/v4l/by-id/* /dev/v4l/by-path/*`; do
    echo "scan: $each"
    v4l2-ctl --device $each --all | grep "H264" | grep "Pixel Format"
done

scan: 
/dev/v4l/by-id/usb-Sonix_Technology_Co.__Ltd._H264_USB_Camera_SN0001-video-index0

Message from syslogd@localhost at Apr 11 06:54:09 ...
 kernel:[  142.777649] Internal error: Oops: 964f [#1] PREEMPT SMP

I have attached the regdump output as a file captured just before 
running the v4l2-ctl command. Also, this is the output from dmesg --follow:


[  134.163768] usb 1-1.2: reset high-speed USB device number 3 using dwc2
[  136.891628] usb 1-1.2: reset high-speed USB device number 3 using dwc2
[  139.619463] usb 1-1.2: reset high-speed USB device number 3 using dwc2
[  142.595299] usb 1-1.2: reset high-speed USB device number 3 using dwc2
[  142.777478] Unable to handle kernel write to read-only memory at 
virtual address 80007e354ffe

[  142.777527] Mem abort info:
[  142.777538]   ESR = 0x964f
[  142.777548]   Exception class = DABT (current EL), IL = 32 bits
[  142.777556]   SET = 0, FnV = 0
[  142.777564]   EA = 0, S1PTW = 0
[  142.777571] Data abort info:
[  142.777579]   ISV = 0, ISS = 0x004f
[  142.777594]   CM = 0, WnR = 1
[  142.777609] swapper pgtable: 4k pages, 48-bit VAs, pgdp = 
a5dbde96
[  142.777626] [80007e354ffe] pgd=7fffa003, 
pud=7fe08003, pmd=7fc16003, pte=00e07e354793

[  142.777649] Internal error: Oops: 964f [#1] PREEMPT SMP

I hope this is helpful, thanks for your help!

regards,
Wayne


On 4/5/19 1:56 AM, Minas Harutyunyan wrote:

Hi Wayne,

On 4/4/2019 10:27 PM, Wayne Piekarski wrote:

Hi everyone,

I have three USB H.264 cameras connected to an ODroid-C2 running a
latest Armbian nightly build, with what appears to be kernel 5.0.5.

When trying to access these cameras via V4L, I immediately get a kernel
oops and the device reboots.

It appears as though the problem occurs in
dwc2_unmap_urb_for_dma+0x1c/0x28 which is in drivers/usb/dwc2.

I'm not a kernel developer so not sure what other information I can
provide apart from the oops dump. I can provide other information if needed.


Could you please provide register dump (debugfs: regdump) before start
playing and provide verbose debug log after start playing till oops.
Which is speed of your camera? Did you connected directly to root hub?

Thanks,
Minas


thanks!

[  204.624452] Internal error: Oops: 964f [#1] PREEMPT SMP
[  204.635515] Modules linked in: snd_soc_hdmi_codec dw_hdmi_i2s_audio
dw_hdmi_cec meson_vdec uvcvideo videobuf2_dma_contig videobuf2_vmalloc
v4l2_mem2mem videobuf2_memops lz4hc videobuf2_v4l2 lz4hc_compress ao_cec
videobuf2_common meson_dw_hdmi meson_rng meson_ir dw_hdmi meson_drm
rng_core rc_core videodev drm_kms_helper cec snd_soc_meson_aiu_spdif
snd_soc_meson_aiu_i2s drm media meson_canvas snd_soc_meson_audio_core
meson_gxbb_wdt drm_panel_orientation_quirks zram snd_usb_audio
snd_soc_simple_card snd_hwdep snd_usbmidi_lib snd_soc_simple_card_utils
snd_soc_core snd_rawmidi snd_seq_device snd_pcm_dmaengine snd_pcm
snd_timer snd scpi_hwmon soundcore ip_tables x_tables realtek
[  204.728202] CPU: 2 PID: 0 Comm: swapper/2 Tainted: G W
5.0.5-meson64 #5.77.190401
[  204.745037] Hardware name: Hardkernel ODROID-C2 (DT)
[  204.758748] pstate: 8005 (Nzcv daif -PAN -UAO)
[  204.772475] pc : __memcpy+0xa0/0x180
[  204.786168] lr : dwc2_free_dma_aligned_buffer+0x78/0x80
[  204.799988] sp : 10013da0
[  204.813726] x29: 10013da0 x28: 
[  204.827504] x27: 0038 x26: 10e960c0
[  204.841198] x25: 0101 x24: 0020
[  204.854820] x23: 10e9d000 x22: 80006b378594
[  204.868394] x21:  x20: 80006a124f79
[  204.881902] x19: 80007e6f1800 x18: 0098090c
[  204.895494] x17:  x16: 
[  204.909050] x15: 014d x14: 0400
[  204.922531] x13:  x12: 0001
[  204.935862] x11: 0047f7f9 x10: 0040
[  204.948999] x9 : 0002 x8 : 10eb82a0
[  204.962085] x7 : 0002 x6 : 80006a124f79
[  204.975122] x5 :  x4 : 00800200
[  204.988041] x3 : 01f4 x2 : 0002
[  205.000822] x1 : 80007edbf202 x0 : 80006a124f79
[  205.013627] Process swapper/2 (pid: 0, stack limit = 0x35e14788)
[  205.027581] Call trace:
[  205.040442]  __memcpy+0xa0/0x180
[  205.053332]  dwc2_unmap_urb_for_dma+0x1c/0x28
[  205.066319]  unmap_urb_for_dma+0x18/0x28
[  205.079213]  __usb_hcd_giveback_urb+0x38/0xe0
[  205.092009]  usb_giveback_urb_bh+0xac/0x108
[  205.104753]  tasklet_action_common.isra.2+0x7c/0x168
[  205.117479]  tasklet_action+0x24/0x30
[  205.