Re: [PATCH v1 10/10] bus: mhi: core: Mark device inactive soon after host issues a shutdown

2020-10-10 Thread Manu Gautam


On 9/19/2020 7:32 AM, Bhaumik Bhatt wrote:
> Clients on the host may see the device in an active state for a short
> period of time after the host detects a device error or power down.

What scenario is referred as 'device error' here?
And power down is the non-graceful power_down by controller?

> Prevent any further host activity which could lead to race conditions
> or multiple callbacks to the controller or any timeouts seen by
> clients attempting to push data as they must be notified of the host
> intent sooner rather than later. This also allows the host and device
> states to be in sync with one another and prevents unnecessary host
> operations.
>
> Signed-off-by: Bhaumik Bhatt 
> ---
>  drivers/bus/mhi/core/main.c |  4 
>  drivers/bus/mhi/core/pm.c   | 31 +++
>  2 files changed, 23 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/bus/mhi/core/main.c b/drivers/bus/mhi/core/main.c
> index 1c8e332..5ec89e9 100644
> --- a/drivers/bus/mhi/core/main.c
> +++ b/drivers/bus/mhi/core/main.c
> @@ -400,6 +400,10 @@ irqreturn_t mhi_intvec_threaded_handler(int irq_number, 
> void *priv)
>  
>/* If device supports RDDM don't bother processing SYS error */
>   if (mhi_cntrl->rddm_image) {
> + /* host may be performing a device power down already */
> + if (!mhi_is_active(mhi_cntrl))
> + goto exit_intvec;
> +
>   if (mhi_cntrl->ee == MHI_EE_RDDM && mhi_cntrl->ee != ee) {
>   /* prevent clients from queueing any more packets */
>   write_lock_irq(&mhi_cntrl->pm_lock);
> diff --git a/drivers/bus/mhi/core/pm.c b/drivers/bus/mhi/core/pm.c
> index 16c04ab..4e2cb41 100644
> --- a/drivers/bus/mhi/core/pm.c
> +++ b/drivers/bus/mhi/core/pm.c
> @@ -469,15 +469,10 @@ static void mhi_pm_disable_transition(struct 
> mhi_controller *mhi_cntrl,
>   write_lock_irq(&mhi_cntrl->pm_lock);
>   prev_state = mhi_cntrl->pm_state;
>   cur_state = mhi_tryset_pm_state(mhi_cntrl, transition_state);
> - if (cur_state == transition_state) {
> - mhi_cntrl->ee = MHI_EE_DISABLE_TRANSITION;
> + if (cur_state == MHI_PM_SYS_ERR_PROCESS)
>   mhi_cntrl->dev_state = MHI_STATE_RESET;
> - }
>   write_unlock_irq(&mhi_cntrl->pm_lock);
>  
> - /* Wake up threads waiting for state transition */
> - wake_up_all(&mhi_cntrl->state_event);
> -
>   if (cur_state != transition_state) {
>   dev_err(dev, "Failed to transition to state: %s from: %s\n",
>   to_mhi_pm_state_str(transition_state),
> @@ -486,6 +481,11 @@ static void mhi_pm_disable_transition(struct 
> mhi_controller *mhi_cntrl,
>   return;
>   }
>  
> + mhi_cntrl->ee = MHI_EE_DISABLE_TRANSITION;
> +
> + /* Wake up threads waiting for state transition */
> + wake_up_all(&mhi_cntrl->state_event);
> +
>   /* Trigger MHI RESET so that the device will not access host memory */
>   if (MHI_REG_ACCESS_VALID(prev_state)) {
>   u32 in_reset = -1;
> @@ -1051,22 +1051,29 @@ void mhi_power_down(struct mhi_controller *mhi_cntrl, 
> bool graceful)
>   enum dev_st_transition next_state = DEV_ST_TRANSITION_DISABLE;
>   struct device *dev = &mhi_cntrl->mhi_dev->dev;
>  
> + mutex_lock(&mhi_cntrl->pm_mutex);
> + write_lock_irq(&mhi_cntrl->pm_lock);
> +
>   /* If it's not a graceful shutdown, force MHI to linkdown state */
>   if (!graceful) {
> - mutex_lock(&mhi_cntrl->pm_mutex);
> - write_lock_irq(&mhi_cntrl->pm_lock);
>   cur_state = mhi_tryset_pm_state(mhi_cntrl,
>   MHI_PM_LD_ERR_FATAL_DETECT);
> - write_unlock_irq(&mhi_cntrl->pm_lock);
> - mutex_unlock(&mhi_cntrl->pm_mutex);
> - if (cur_state != MHI_PM_LD_ERR_FATAL_DETECT)
> + if (cur_state != MHI_PM_LD_ERR_FATAL_DETECT) {
>   dev_dbg(dev, "Failed to move to state: %s from: %s\n",
>   to_mhi_pm_state_str(MHI_PM_LD_ERR_FATAL_DETECT),
>   to_mhi_pm_state_str(mhi_cntrl->pm_state));
> - else
> + } else {
>   next_state = DEV_ST_TRANSITION_FATAL;
> + wake_up_all(&mhi_cntrl->state_event);
> + }
>   }
>  
> + /* mark device inactive to avoid any further host processing */
> + mhi_cntrl->dev_state = MHI_STATE_RESET;
> +
> + write_unlock_irq(&mhi_cntrl->pm_lock);
> + mutex_unlock(&mhi_cntrl->pm_mutex);
> +
>   mhi_queue_state_transition(mhi_cntrl, next_state);
>  
>   /* Wait for shutdown to complete */

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v1 06/10] bus: mhi: core: Improve shutdown handling after link down detection

2020-10-10 Thread Manu Gautam


On 9/19/2020 7:32 AM, Bhaumik Bhatt wrote:
> If MHI were to attempt a device shutdown following an assumption
> that the device is inaccessible, the host currently moves to a state
> where device register accesses are allowed when they should not be.
> This would end up allowing accesses to the device register space when
> the link is inaccessible and can result in bus errors observed on the
> host. Improve shutdown handling to prevent these outcomes and do not
> move the MHI PM state to a register accessible state after device is

Which state are you referring to when you say 'register accessible state'?
Would it be possible to provide more details on current handling here?


> assumed to be inaccessible.
>
> Signed-off-by: Bhaumik Bhatt 
> ---
>  drivers/bus/mhi/core/init.c |  1 +
>  drivers/bus/mhi/core/internal.h |  1 +
>  drivers/bus/mhi/core/pm.c   | 18 +-
>  3 files changed, 15 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/bus/mhi/core/init.c b/drivers/bus/mhi/core/init.c
> index 9ae4c19..fa33dde 100644
> --- a/drivers/bus/mhi/core/init.c
> +++ b/drivers/bus/mhi/core/init.c
> @@ -37,6 +37,7 @@ const char * const 
> dev_state_tran_str[DEV_ST_TRANSITION_MAX] = {
>   [DEV_ST_TRANSITION_MISSION_MODE] = "MISSION_MODE",
>   [DEV_ST_TRANSITION_SYS_ERR] = "SYS_ERR",
>   [DEV_ST_TRANSITION_DISABLE] = "DISABLE",
> + [DEV_ST_TRANSITION_FATAL] = "FATAL SHUTDOWN",
>  };
>  
>  const char * const mhi_state_str[MHI_STATE_MAX] = {
> diff --git a/drivers/bus/mhi/core/internal.h b/drivers/bus/mhi/core/internal.h
> index 7989269..f3b9e5a 100644
> --- a/drivers/bus/mhi/core/internal.h
> +++ b/drivers/bus/mhi/core/internal.h
> @@ -388,6 +388,7 @@ enum dev_st_transition {
>   DEV_ST_TRANSITION_MISSION_MODE,
>   DEV_ST_TRANSITION_SYS_ERR,
>   DEV_ST_TRANSITION_DISABLE,
> + DEV_ST_TRANSITION_FATAL,
>   DEV_ST_TRANSITION_MAX,
>  };
>  
> diff --git a/drivers/bus/mhi/core/pm.c b/drivers/bus/mhi/core/pm.c
> index 3462d82..bce1f62 100644
> --- a/drivers/bus/mhi/core/pm.c
> +++ b/drivers/bus/mhi/core/pm.c
> @@ -37,9 +37,10 @@
>   * M0 -> FW_DL_ERR
>   * M0 -> M3_ENTER -> M3 -> M3_EXIT --> M0
>   * L1: SYS_ERR_DETECT -> SYS_ERR_PROCESS --> POR
> - * L2: SHUTDOWN_PROCESS -> DISABLE
> + * L2: SHUTDOWN_PROCESS -> LD_ERR_FATAL_DETECT
> + * SHUTDOWN_PROCESS -> DISABLE
>   * L3: LD_ERR_FATAL_DETECT <--> LD_ERR_FATAL_DETECT
> - * LD_ERR_FATAL_DETECT -> SHUTDOWN_PROCESS
> + * LD_ERR_FATAL_DETECT -> DISABLE
>   */
>  static struct mhi_pm_transitions const dev_state_transitions[] = {
>   /* L0 States */
> @@ -72,7 +73,7 @@ static struct mhi_pm_transitions const 
> dev_state_transitions[] = {
>   {
>   MHI_PM_M3,
>   MHI_PM_M3_EXIT | MHI_PM_SYS_ERR_DETECT |
> - MHI_PM_SHUTDOWN_PROCESS | MHI_PM_LD_ERR_FATAL_DETECT
> + MHI_PM_LD_ERR_FATAL_DETECT
>   },
>   {
>   MHI_PM_M3_EXIT,
> @@ -103,7 +104,7 @@ static struct mhi_pm_transitions const 
> dev_state_transitions[] = {
>   /* L3 States */
>   {
>   MHI_PM_LD_ERR_FATAL_DETECT,
> - MHI_PM_LD_ERR_FATAL_DETECT | MHI_PM_SHUTDOWN_PROCESS
> + MHI_PM_LD_ERR_FATAL_DETECT | MHI_PM_DISABLE
>   },
>  };
>  
> @@ -670,6 +671,10 @@ void mhi_pm_st_worker(struct work_struct *work)
>   mhi_pm_disable_transition
>   (mhi_cntrl, MHI_PM_SHUTDOWN_PROCESS);
>   break;
> + case DEV_ST_TRANSITION_FATAL:
> + mhi_pm_disable_transition
> + (mhi_cntrl, MHI_PM_LD_ERR_FATAL_DETECT);
> + break;
>   default:
>   break;
>   }
> @@ -1039,6 +1044,7 @@ EXPORT_SYMBOL_GPL(mhi_async_power_up);
>  void mhi_power_down(struct mhi_controller *mhi_cntrl, bool graceful)
>  {
>   enum mhi_pm_state cur_state;
> + enum dev_st_transition next_state = DEV_ST_TRANSITION_DISABLE;
>   struct device *dev = &mhi_cntrl->mhi_dev->dev;
>  
>   /* If it's not a graceful shutdown, force MHI to linkdown state */
> @@ -1053,9 +1059,11 @@ void mhi_power_down(struct mhi_controller *mhi_cntrl, 
> bool graceful)
>   dev_dbg(dev, "Failed to move to state: %s from: %s\n",
>   to_mhi_pm_state_str(MHI_PM_LD_ERR_FATAL_DETECT),
>   to_mhi_pm_state_str(mhi_cntrl->pm_state));
> + else
> + next_state = DEV_ST_TRANSITION_FATAL;
>   }
>  
> - mhi_queue_state_transition(mhi_cntrl, DEV_ST_TRANSITION_DISABLE);
> + mhi_queue_state_transition(mhi_cntrl, next_state);
>  
>   /* Wait for shutdown to complete */
>   flush_work(&mhi_cntrl->st_worker);

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v1 05/10] bus: mhi: core: Disable IRQs when powering down

2020-10-10 Thread Manu Gautam
Hi

On 9/19/2020 7:32 AM, Bhaumik Bhatt wrote:
> While powering down, the device may or may not acknowledge the MHI
> RESET issued by host for graceful shutdown scenario which can lead
> to a rogue device sending an interrupt after the clean-up has been
> done. This can result in a tasklet being scheduled after it has
> been killed and access already freed memory causing a NULL pointer
> exception. Avoid this corner case by disabling the interrupts as a
> part of host clean up.
>
> Signed-off-by: Bhaumik Bhatt 
> ---
>  drivers/bus/mhi/core/pm.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/bus/mhi/core/pm.c b/drivers/bus/mhi/core/pm.c
> index 1862960..3462d82 100644
> --- a/drivers/bus/mhi/core/pm.c
> +++ b/drivers/bus/mhi/core/pm.c
> @@ -517,6 +517,7 @@ static void mhi_pm_disable_transition(struct 
> mhi_controller *mhi_cntrl,
>   for (i = 0; i < mhi_cntrl->total_ev_rings; i++, mhi_event++) {
>   if (mhi_event->offload_ev)
>   continue;
> + disable_irq(mhi_cntrl->irq[mhi_event->irq]);
>   tasklet_kill(&mhi_event->task);
>   }
>  

What about sys_err handling? IRQ may be left disabled?


-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH 2/2] usb: dwc3: Host wake up support from system suspend

2020-08-11 Thread Manu Gautam
Hi,

On 6/11/2020 7:58 PM, Sandeep Maheswaram wrote:
> Avoiding phy powerdown in host mode so that it can be wake up by devices.
> Set usb controller wakeup capable when wakeup capable devices are
> connected to the host.
>
> Signed-off-by: Sandeep Maheswaram 
> ---
>  drivers/usb/dwc3/core.c  | 47 ++-
>  drivers/usb/dwc3/core.h  |  1 +
>  drivers/usb/dwc3/dwc3-qcom.c | 66 
> +---
>  3 files changed, 91 insertions(+), 23 deletions(-)
>
> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index 25c686a7..8370350 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -31,15 +31,19 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include "core.h"
>  #include "gadget.h"
>  #include "io.h"
>  
>  #include "debug.h"
> +#include "../host/xhci.h"
>  
>  #define DWC3_DEFAULT_AUTOSUSPEND_DELAY   5000 /* ms */
>  
> +bool need_phy_for_wakeup;
> +
>  /**
>   * dwc3_get_dr_mode - Validates and sets dr_mode
>   * @dwc: pointer to our context structure
> @@ -1627,10 +1631,36 @@ static int dwc3_core_init_for_resume(struct dwc3 *dwc)
>   return ret;
>  }
>  
> +static void dwc3_set_phy_speed_flags(struct dwc3 *dwc)
> +{
> +
> + int i, num_ports;
> + u32 reg;
> + struct usb_hcd  *hcd = platform_get_drvdata(dwc->xhci);

dwc->xhci could be NULL for DR_MODE = PERIPHERAL.


> + struct xhci_hcd *xhci_hcd = hcd_to_xhci(hcd);
> +
> + dwc->hs_phy_flags &= ~(PHY_MODE_USB_HOST_HS | PHY_MODE_USB_HOST_LS);
> +
> + reg = readl(&xhci_hcd->cap_regs->hcs_params1);
> +
> + num_ports = HCS_MAX_PORTS(reg);
> + for (i = 0; i < num_ports; i++) {
> + reg = readl(&xhci_hcd->op_regs->port_status_base + i*0x10);
> + if (reg & PORT_PE) {
> + if (DEV_HIGHSPEED(reg) || DEV_FULLSPEED(reg))
> + dwc->hs_phy_flags |= PHY_MODE_USB_HOST_HS;
> + else if (DEV_LOWSPEED(reg))
> + dwc->hs_phy_flags |= PHY_MODE_USB_HOST_LS;
> + }
> + }
> + phy_set_mode(dwc->usb2_generic_phy, dwc->hs_phy_flags);


Can we move this logic to xhci driver instead?

> +}
> +
..
> @@ -240,6 +267,11 @@ static int dwc3_qcom_suspend(struct dwc3_qcom *qcom)
>  {
>   u32 val;
>   int i;
> + struct dwc3 *dwc = platform_get_drvdata(qcom->dwc3);
> + struct usb_hcd  *hcd = platform_get_drvdata(dwc->xhci);

dwc->xhci could be NULL


> +
> + if (usb_wakeup_enabled_descendants(hcd->self.root_hub))
> + device_init_wakeup(qcom->dev, 1);
>  
>   if (qcom->is_suspended)
>   return 0;
> @@ -262,6 +294,8 @@ static int dwc3_qcom_resume(struct dwc3_qcom *qcom)
>   int ret;
>   int i;
>  
> + device_init_wakeup(qcom->dev, 0);
> +
>   if (!qcom->is_suspended)
>   return 0;
>  

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v7 2/4] usb: dwc3: qcom: Add interconnect support in dwc3 driver

2020-05-14 Thread Manu Gautam
Hi,

On 5/15/2020 9:27 AM, Viresh Kumar wrote:
> On Fri, 15 May 2020 at 02:33, Georgi Djakov  wrote:
>
>> ---8<---
>> diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
>> index 206caa0ea1c6..6661788b1a76 100644
>> --- a/drivers/usb/dwc3/Kconfig
>> +++ b/drivers/usb/dwc3/Kconfig
>> @@ -129,6 +129,7 @@ config USB_DWC3_QCOM
>> tristate "Qualcomm Platform"
>> depends on ARCH_QCOM || COMPILE_TEST
>> depends on EXTCON || !EXTCON
>> +   depends on INTERCONNECT || !INTERCONNECT
> Again, as I said yesterday. This looks incorrect and may not fix the problem..
>
> With this we will be able to select USB_DWC3_QCOM even when INTERCONNECT=m.

DWC3_QCOM in that case would be 'm' if INTERCONNECT =m and
that should be fine?


> What we perhaps need here is:
> depends on INTERCONNECT != m
>
> --
> viresh

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH] usb: dwc3: gadget: Fail request submission if it was already queued

2019-01-15 Thread Manu Gautam
Hi,

On 1/11/2019 2:51 PM, Felipe Balbi wrote:
> Hi,
>
> Manu Gautam  writes:
>>> Manu Gautam  writes:
>>>> If a function driver tries to re-submit an already queued request,
>>>> it can results in corruption of pending/started request lists.
>>>> Catch such conditions and fail the request submission to DCD.
>>>>
>>>> Signed-off-by: Manu Gautam 
>>>> ---
>>>>  drivers/usb/dwc3/gadget.c | 6 ++
>>>>  1 file changed, 6 insertions(+)
>>>>
>>>> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
>>>> index 679c12e14522..51716c6b286a 100644
>>>> --- a/drivers/usb/dwc3/gadget.c
>>>> +++ b/drivers/usb/dwc3/gadget.c
>>>> @@ -1290,6 +1290,12 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep 
>>>> *dep, struct dwc3_request *req)
>>>>&req->request, req->dep->name))
>>>>return -EINVAL;
>>>>  
>>>> +  if (req->request.status == -EINPROGRESS) {
>>> this test is really not enough. What if gadget driver set status to
>>> EINPROGRESS before submission? A better check would involve making sure
>>> req isn't part of dep->pending_list or dep->started_list or
>>> dep->cancelled_list. It's clear that this won't work very well as the
>>> amount of requests grow.
>> Thanks for quick review.
>> 'request.status' check can be replaced:
>> +if (!list_empty(&req->list) {
>>
>> And replace list_del with list_del_init from dwc3_gadget_giveback()
> I would rather avoid this. We could start tracking our own internal
> dwc3_request status. Something along the lines of:

Thanks for this quick patch.

[snip]

>  
> With this, we can remove some of the other request flags, such as "started".
>
>>> Anyway, which gadget driver did this? Why is it only affecting dwc3?
>> Function driver is not in upstream (f_mtp.c).
> So this could happen with any UDC, right? Why is f_mtp.c queueing the
> same request twice?


Looks like chipidea UDC already has such a check.
It is not yet clear that why f_mtp queued same request twice.
However, having a safeguard check in UDC should be helpful.


>
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH] usb: dwc3: gadget: Fail request submission if it was already queued

2019-01-11 Thread Manu Gautam
Hi,

On 1/11/2019 1:13 PM, Felipe Balbi wrote:
> Hi,
>
> Manu Gautam  writes:
>> If a function driver tries to re-submit an already queued request,
>> it can results in corruption of pending/started request lists.
>> Catch such conditions and fail the request submission to DCD.
>>
>> Signed-off-by: Manu Gautam 
>> ---
>>  drivers/usb/dwc3/gadget.c | 6 ++
>>  1 file changed, 6 insertions(+)
>>
>> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
>> index 679c12e14522..51716c6b286a 100644
>> --- a/drivers/usb/dwc3/gadget.c
>> +++ b/drivers/usb/dwc3/gadget.c
>> @@ -1290,6 +1290,12 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep 
>> *dep, struct dwc3_request *req)
>>  &req->request, req->dep->name))
>>  return -EINVAL;
>>  
>> +if (req->request.status == -EINPROGRESS) {
> this test is really not enough. What if gadget driver set status to
> EINPROGRESS before submission? A better check would involve making sure
> req isn't part of dep->pending_list or dep->started_list or
> dep->cancelled_list. It's clear that this won't work very well as the
> amount of requests grow.

Thanks for quick review.
'request.status' check can be replaced:
+if (!list_empty(&req->list) {

And replace list_del with list_del_init from dwc3_gadget_giveback()


>
> Anyway, which gadget driver did this? Why is it only affecting dwc3?

Function driver is not in upstream (f_mtp.c).

>
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH] usb: dwc3: gadget: Fail request submission if it was already queued

2019-01-10 Thread Manu Gautam
If a function driver tries to re-submit an already queued request,
it can results in corruption of pending/started request lists.
Catch such conditions and fail the request submission to DCD.

Signed-off-by: Manu Gautam 
---
 drivers/usb/dwc3/gadget.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 679c12e14522..51716c6b286a 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1290,6 +1290,12 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, 
struct dwc3_request *req)
&req->request, req->dep->name))
return -EINVAL;
 
+   if (req->request.status == -EINPROGRESS) {
+   dev_err(dwc->dev, "%s: %pK request already in queue\n",
+   dep->name, req);
+   return -EBUSY;
+   }
+
pm_runtime_get(dwc->dev);
 
req->request.actual = 0;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v1] arm64: dts: qcom: msm8996: Disable USB2 PHY suspend by core

2019-01-03 Thread Manu Gautam
QUSB2 PHY on msm8996 doesn't work well when autosuspend by
dwc3 core using USB2PHYCFG register is enabled. One of the
issue seen is that PHY driver reports PLL lock failure and
fails phy_init() if dwc3 core has USB2 PHY suspend enabled.
Fix this by using quirks to disable USB2 PHY LPM/suspend and
dwc3 core already takes care of explicitly suspending PHY
during suspend if quirks are specified.

Signed-off-by: Manu Gautam 
---
 arch/arm64/boot/dts/qcom/msm8996.dtsi | 4 
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi 
b/arch/arm64/boot/dts/qcom/msm8996.dtsi
index b29fe80d7288..1f14ca35afc2 100644
--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
@@ -911,6 +911,8 @@
interrupts = <0 138 IRQ_TYPE_LEVEL_HIGH>;
phys = <&hsusb_phy2>;
phy-names = "usb2-phy";
+   snps,dis_u2_susphy_quirk;
+   snps,dis_enblslpm_quirk;
};
};
 
@@ -940,6 +942,8 @@
interrupts = <0 131 IRQ_TYPE_LEVEL_HIGH>;
phys = <&hsusb_phy1>, <&ssusb_phy_0>;
phy-names = "usb2-phy", "usb3-phy";
+   snps,dis_u2_susphy_quirk;
+   snps,dis_enblslpm_quirk;
};
};
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v6 2/2] phy: qualcomm: Add Synopsys High-Speed USB PHY driver

2018-12-21 Thread Manu Gautam
Hi,

On 12/20/2018 4:39 PM, Shawn Guo wrote:
> Hi Manu,
>
> On Thu, Dec 20, 2018 at 09:33:43AM +0530, mgau...@codeaurora.org wrote:
>> Hi Shawn,
>>
>> On 2018-12-20 06:31, Shawn Guo wrote:
>>> It adds Synopsys 28nm Femto High-Speed USB PHY driver support, which
>>> is usually paired with Synopsys DWC3 USB controllers on Qualcomm SoCs.
>>>
>>> Signed-off-by: Shawn Guo 
>>> ---
>>
...
>>> +struct hsphy_priv {
>> nit-pick - indentation for following structure members?
> Hmm, my personal taste says no, because I found that it's hard to keep
> the indentation when adding new members later.
ok
>
>>> +   void __iomem *base;
>>> +   struct clk_bulk_data *clks;
>>> +   int num_clks;
>>> +   struct reset_control *phy_reset;
>>> +   struct reset_control *por_reset;
>>> +   struct regulator_bulk_data vregs[VREG_NUM];
>>> +   unsigned int voltages[VREG_NUM][VOL_NUM];
>>> +   const struct hsphy_data *data;
>>> +   bool cable_connected;
>> You can get cable-connected state from "enum phy_mode mode" which
>> is present in this driver.
>> E.g. cable_connected is false if mode is neither HOST nor DEVICE.
>>
>>
>>> +   struct extcon_dev *vbus_edev;
>>> +   struct notifier_block vbus_notify;
>> extcons not needed if you use "mode" for the same purpose.
> The extcon is there for indicating cable connection status.  I'm not
> sure that phy_mode can be used for that purpose.  For example, what
> value would phy core set phy_mode to, if we disconnect the cable from
> phy_mode being HOST or DEVICE?

it depends how it is used. Looks like it is used to decide whether to turn-off
regulators or not. Unless you plan to add low power support as part of
runtime-suspend of PHY during host mode, there is no reason to not turn-off
regulators on pm_suspend(). Please refer to my comments below.

>
>>
>>> +   enum phy_mode mode;
>>> +};
>>> +
>>
>>> +
>>> +static int qcom_snps_hsphy_vbus_notifier(struct notifier_block *nb,
>>> +unsigned long event, void *ptr)
>>> +{
>>> +   struct hsphy_priv *priv = container_of(nb, struct hsphy_priv,
>>> +   vbus_notify);
>>> +   priv->cable_connected = !!event;
>>> +   return 0;
>>> +}
>>> +
>>> +static int qcom_snps_hsphy_power_on(struct phy *phy)
>> Can you instead merge this power_on function with phy_init?
> I can do that, but what's the gain/advantage from doing that?

dwc3 core calls phy_init() before power_on(). AFAIK, PHY regulators
need to be ON before initializing it.

>
>>> +{
>>> +   struct hsphy_priv *priv = phy_get_drvdata(phy);
>>> +   int ret;
>>> +
>>> +   if (priv->cable_connected) {
>> Why distinguish between cable connected vs not-connected?
> This is based on the vendor driver implementation.  It does a more
> aggressive low power management in case that cable is not connected,
> i.e. turning off regulator and entering retention mode.

I believe 'aggressive low power management' will be triggered on
pm_suspend?
And dwc3 core will in any case perform phy_exit()->phy_init() across
pm_suspend/resume which will reset PHYs. Hence, there is no need to check
for cable connected state here.


>
>>> +   ret = clk_bulk_prepare_enable(priv->num_clks, priv->clks);
>>> +   if (ret)
>>> +   return ret;
>>> +   qcom_snps_hsphy_disable_hv_interrupts(priv);
>>> +   } else {
>>> +   ret = qcom_snps_hsphy_enable_regulators(priv);
>>> +   if (ret)
>>> +   return ret;
>>> +   ret = clk_bulk_prepare_enable(priv->num_clks, priv->clks);
>>> +   if (ret)
>>> +   return ret;
>>> +   qcom_snps_hsphy_exit_retention(priv);
>>> +   }
>>> +
>>> +   return 0;
>>> +}
>>> +
>>> +static int qcom_snps_hsphy_power_off(struct phy *phy)
>>> +{
>>> +   struct hsphy_priv *priv = phy_get_drvdata(phy);
>>> +
>>> +   if (priv->cable_connected) {
>>> +   qcom_snps_hsphy_enable_hv_interrupts(priv);
>>> +   clk_bulk_disable_unprepare(priv->num_clks, priv->clks);
>>> +   } else {
>>> +   qcom_snps_hsphy_enter_retention(priv);
>>> +   clk_bulk_disable_unprepare(priv->num_clks, priv->clks);
>>> +   qcom_snps_hsphy_disable_regulators(priv);
>>> +   }
>>> +
>>> +   return 0;
>>> +}
>>> +
>>
>>
>> ..
>>> +static const struct phy_ops qcom_snps_hsphy_ops = {
>>> +   .init = qcom_snps_hsphy_init,
>>> +   .power_on = qcom_snps_hsphy_power_on,
>>> +   .power_off = qcom_snps_hsphy_power_off,
>>> +   .set_mode = qcom_snps_hsphy_set_mode,
>> .phy_exit()?
>> I believe that is needed as dwc3 core driver performs
>> phy_exit/phy_init across pm_suspend/resume.
> I just do not see anything that we should be doing in .exit hook right
> now.

After you merge power_on() with phy_init() as per my previous comment,
you can rely on phy_exit() to take care of putting PHY in low power state
and turn off regulators as well.

>
> Shawn
>
>>
>>> +   .owner = THIS_MODULE,
>>> +};
>>> +

-- 
The Qualcomm Innovation Center, Inc. is a memb

[PATCH v1] arm64: dts: qcom: sdm845: Fix pcs_misc region address for UNI PHY

2018-10-25 Thread Manu Gautam
Correct address for pcs_misc register region of USB3 QMP UNI PHY.
These registers are used during runtime-suspend/resume routines
of phy.

Fixes: ca4db2b538a1 ("arm64: dts: qcom: sdm845: Add USB-related nodes")
Signed-off-by: Manu Gautam 
---
 arch/arm64/boot/dts/qcom/sdm845.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi 
b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index b72bdb0a31a5..84bee81562a5 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -1156,7 +1156,7 @@
reg = <0x88eb200 0x128>,
  <0x88eb400 0x1fc>,
  <0x88eb800 0x218>,
- <0x88e9600 0x70>;
+ <0x88eb600 0x70>;
#phy-cells = <0>;
clocks = <&gcc GCC_USB3_SEC_PHY_PIPE_CLK>;
clock-names = "pipe0";
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v2 2/2] phy: qcom-qusb2: Fix HSTX_TRIM tuning with fused value for SDM845

2018-10-16 Thread Manu Gautam
Tune1 register on sdm845 is used to update HSTX_TRIM with fused
setting. Enable same by specifying update_tune1_with_efuse flag
for sdm845, otherwise driver ends up programming tune2 register.

Fixes: ef17f6e212ca ("phy: qcom-qusb2: Add QUSB2 PHYs support for sdm845")
Signed-off-by: Manu Gautam 
Reviewed-by: Douglas Anderson 
---
 drivers/phy/qualcomm/phy-qcom-qusb2.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c 
b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index 9d6c88064158..69c92843eb3b 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -231,6 +231,7 @@ static const struct qusb2_phy_cfg sdm845_phy_cfg = {
.mask_core_ready = CORE_READY_STATUS,
.has_pll_override = true,
.autoresume_en= BIT(0),
+   .update_tune1_with_efuse = true,
 };
 
 static const char * const qusb2_phy_vreg_names[] = {
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v2 1/2] phy: qcom-qusb2: Use HSTX_TRIM fused value as is

2018-10-16 Thread Manu Gautam
Fix HSTX_TRIM tuning logic which instead of using fused value
as HSTX_TRIM, incorrectly performs bitwise OR operation with
existing default value.

Fixes: ca04d9d3e1b1 ("phy: qcom-qusb2: New driver for QUSB2 PHY on Qcom chips")
Signed-off-by: Manu Gautam 
Reviewed-by: Douglas Anderson 
---
 drivers/phy/qualcomm/phy-qcom-qusb2.c | 19 ++-
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c 
b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index e70e425f26f5..9d6c88064158 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -402,10 +402,10 @@ static void qusb2_phy_set_tune2_param(struct qusb2_phy 
*qphy)
 
/*
 * Read efuse register having TUNE2/1 parameter's high nibble.
-* If efuse register shows value as 0x0, or if we fail to find
-* a valid efuse register settings, then use default value
-* as 0xB for high nibble that we have already set while
-* configuring phy.
+* If efuse register shows value as 0x0 (indicating value is not
+* fused), or if we fail to find a valid efuse register setting,
+* then use default value for high nibble that we have already
+* set while configuring the phy.
 */
val = nvmem_cell_read(qphy->cell, NULL);
if (IS_ERR(val) || !val[0]) {
@@ -415,12 +415,13 @@ static void qusb2_phy_set_tune2_param(struct qusb2_phy 
*qphy)
 
/* Fused TUNE1/2 value is the higher nibble only */
if (cfg->update_tune1_with_efuse)
-   qusb2_setbits(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE1],
- val[0] << 0x4);
+   qusb2_write_mask(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE1],
+val[0] << HSTX_TRIM_SHIFT,
+HSTX_TRIM_MASK);
else
-   qusb2_setbits(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE2],
- val[0] << 0x4);
-
+   qusb2_write_mask(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE2],
+val[0] << HSTX_TRIM_SHIFT,
+HSTX_TRIM_MASK);
 }
 
 static int qusb2_phy_set_mode(struct phy *phy, enum phy_mode mode)
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v1] phy: qcom-qusb2: Fix HSTX_TRIM tuning with fused value for SDM845

2018-10-05 Thread Manu Gautam
Tune1 register on sdm845 is used to update HSTX_TRIM with fused
setting. Enable same by specifying update_tune1_with_efuse flag
for sdm845, otherwise driver ends up programming tune2 register.
While at it, also fix HSTX_TRIM tuning logic which instead of
using fused value as HSTX_TRIM, incorrectly performs bitwise OR
operation with existing default value.

Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qusb2.c | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c 
b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index e70e425f26f5..defeb0b7cfa0 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -231,6 +231,7 @@ static const struct qusb2_phy_cfg sdm845_phy_cfg = {
.mask_core_ready = CORE_READY_STATUS,
.has_pll_override = true,
.autoresume_en= BIT(0),
+   .update_tune1_with_efuse = true,
 };
 
 static const char * const qusb2_phy_vreg_names[] = {
@@ -415,12 +416,13 @@ static void qusb2_phy_set_tune2_param(struct qusb2_phy 
*qphy)
 
/* Fused TUNE1/2 value is the higher nibble only */
if (cfg->update_tune1_with_efuse)
-   qusb2_setbits(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE1],
- val[0] << 0x4);
+   qusb2_write_mask(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE1],
+val[0] << HSTX_TRIM_SHIFT,
+HSTX_TRIM_MASK);
else
-   qusb2_setbits(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE2],
- val[0] << 0x4);
-
+   qusb2_write_mask(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE2],
+val[0] << HSTX_TRIM_SHIFT,
+HSTX_TRIM_MASK);
 }
 
 static int qusb2_phy_set_mode(struct phy *phy, enum phy_mode mode)
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v2 2/2] Embedded USB Debugger (EUD) driver

2018-09-05 Thread Manu Gautam
Hi,


On 9/5/2018 3:04 AM, Prakruthi Deepak Heragu wrote:
> Add support for control peripheral of EUD (Embedded USB Debugger) to
> listen to events such as USB attach/detach, charger enable/disable, pet
> EUD to indicate software is functional.
>
> Signed-off-by: Satya Durga Srinivasu Prabhala 
> Signed-off-by: Prakruthi Deepak Heragu 
> ---
>  drivers/soc/qcom/Kconfig  |  12 ++
>  drivers/soc/qcom/Makefile |   1 +
>  drivers/soc/qcom/eud.c| 338 
> ++
>  3 files changed, 351 insertions(+)
>  create mode 100644 drivers/soc/qcom/eud.c
>
> diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
[snip]
> +
> +#define EUD_ENABLE_CMD 1
> +#define EUD_DISABLE_CMD 0

Why not use module param as boolean? I mean zero to disable and non-zero to 
enable?
> +
> +#define EUD_REG_INT1_EN_MASK 0x0024
> +#define EUD_REG_INT_STATUS_1 0x0044
> +#define EUD_REG_CTL_OUT_10x0074
> +#define EUD_REG_VBUS_INT_CLR 0x0080
> +#define EUD_REG_CHGR_INT_CLR 0x0084
> +#define EUD_REG_CSR_EUD_EN   0x1014
> +#define EUD_REG_SW_ATTACH_DET0x1018
> +
> +#define EUD_INT_VBUS BIT(2)
> +#define EUD_INT_CHGR BIT(3)
> +#define EUD_INT_SAFE_MODEBIT(4)
> +
> +struct eud_chip {
> + struct device   *dev;
> + int eud_irq;
> + unsigned intextcon_id;
> + unsigned intint_status;
> + boolusb_attach;
> + boolchgr_enable;
> + void __iomem*eud_reg_base;
> + struct extcon_dev   *extcon;
> + struct work_struct  eud_work;
> +};
> +
> +static const unsigned int eud_extcon_cable[] = {
> + EXTCON_USB,
> + EXTCON_CHG_USB_SDP,
> + EXTCON_NONE,
> +};
> +
> +/*
> + * On the kernel command line specify eud.enable=1 to enable EUD.
> + * EUD is disabled by default.
> + */
> +static int enable;
> +static bool eud_ready;
> +static struct eud_chip *eud_private;
> +
> +static void enable_eud(struct eud_chip *priv)
> +{
> + struct power_supply *usb_psy = NULL;
> + union power_supply_propval pval = {0};
> + union power_supply_propval tval = {0};
> + int ret;
> +
> + usb_psy = power_supply_get_by_name("usb");
> + if (!usb_psy)
> + return;
> +
> + ret = power_supply_get_property(usb_psy,
> + POWER_SUPPLY_PROP_PRESENT, &pval);
> + if (ret)
> + return;
> +
> + ret = power_supply_get_property(usb_psy,
> + POWER_SUPPLY_PROP_REAL_TYPE, &tval);
> + if (ret)
> + return;
> +

if(!pval.intval || (tval.intval != POWER_SUPPLY_TYPE_USB &&
tval.intval != POWER_SUPPLY_TYPE_USB_CDP))
    return;

/* following if-else can be removed */
 

> + if (pval.intval && (tval.intval == POWER_SUPPLY_TYPE_USB ||
> + tval.intval == POWER_SUPPLY_TYPE_USB_CDP)) {
> + /* write into CSR to enable EUD */
> + writel_relaxed(BIT(0), priv->eud_reg_base + EUD_REG_CSR_EUD_EN);
> + /* Enable vbus, chgr & safe mode warning interrupts */
> + writel_relaxed(EUD_INT_VBUS | EUD_INT_CHGR | EUD_INT_SAFE_MODE,
> + priv->eud_reg_base + EUD_REG_INT1_EN_MASK);
> +
> + /* Ensure Register Writes Complete */
> + wmb();
> +
> + /*
> +  * Set the default cable state to usb connect and charger
> +  * enable
> +  */
> + ret = extcon_set_state_sync(priv->extcon, EXTCON_USB, true);
> + if (ret)
> + return;
> + ret = extcon_set_state_sync(priv->extcon,
> + EXTCON_CHG_USB_SDP, true);
> + if (ret)
> + return;
> + } else {
> + return;
> + }
> +
> +}
> +
> +static void disable_eud(struct eud_chip *priv)
> +{
> + /* write into CSR to disable EUD */
> + writel_relaxed(0, priv->eud_reg_base + EUD_REG_CSR_EUD_EN);
> +}
> +
> +static int param_eud_set(const char *val, const struct kernel_param *kp)
> +{
> + int enable = 0;
> +
> + if (sscanf(val, "%du", &enable) != 1)
> + return -EINVAL;
> +
> + if (enable != EUD_ENABLE_CMD && enable != EUD_DISABLE_CMD)
> + return -EINVAL;
Do we really need to worry about it? 'enable' could just be treated as bool

[snip]
> +
> +
> +static irqreturn_t handle_eud_irq(int irq, void *data)
> +{
> + struct eud_chip *chip = data;
> + u32 reg;
> +
> + /* read status register and find out which interrupt triggered */
> + reg = readl_relaxed(chip->eud_reg_base + EUD_REG_INT_STATUS_1);
> + if (reg & EUD_INT_VBUS) {
> + chip->int_status = EUD_INT_VBUS;
> + usb_attach_detach(chip);
> + } else if (reg & EUD_INT_CHGR) {
> + chip->int_status = EUD_INT_CHGR;
> +   

Re: [PATCH v7 1/4] phy: Update PHY power control sequence

2018-06-27 Thread Manu Gautam



On 6/19/2018 2:06 PM, Can Guo wrote:
> All PHYs should be powered on before register configuration starts. And
> only PCIe PHYs need an extra power control before deasserts reset state.
> 
> Signed-off-by: Can Guo 
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp.c | 19 ---
>  1 file changed, 12 insertions(+), 7 deletions(-)

Reviewed-by: Manu Gautam 

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation


Re: [PATCH v7 2/4] phy: General struct and field cleanup

2018-06-27 Thread Manu Gautam



On 6/19/2018 2:06 PM, Can Guo wrote:
> Move MSM8996 specific PHY vreg list struct name to a genernal one as it is
> used by all PHYs. Add a specific field to handle dual lane situation.
> 
> Signed-off-by: Can Guo 
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp.c | 25 ++---
>  1 file changed, 14 insertions(+), 11 deletions(-)

Reviewed-by: Manu Gautam 

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation


Re: [PATCH v7 3/4] phy: Add QMP phy based UFS phy support for sdm845

2018-06-27 Thread Manu Gautam
Hi,

On 6/19/2018 2:06 PM, Can Guo wrote:
> +static int qcom_qmp_phy_poweron(struct phy *phy)
> +{
> + struct qmp_phy *qphy = phy_get_drvdata(phy);
> + struct qcom_qmp *qmp = qphy->qmp;
> + const struct qmp_phy_cfg *cfg = qmp->cfg;
> + void __iomem *pcs = qphy->pcs;
> + void __iomem *status;
> + unsigned int mask, val;
> + int ret = 0;
> +
> + if (cfg->type != PHY_TYPE_UFS)
> + return 0;
> +
> + /*
> +  * For UFS PHY that has not software reset control, serdes start
> +  * should only happen when UFS driver explicitly calls phy_power_on
> +  * after it deasserts software reset.
> +  */

Instead of relying on UFS glue driver to assert/de-assert PHY
which requires UFS PHY initialization to be split in init() and
poweron(), we can rather register reset_controller from ufs-qcom
driver.
PHY driver can then assert/de-assert as per UFS PHY requirement
in init() function itself and there won't be any need to have
poweron() routine for UFS as init can perform complete PHY
initialization without any dependency on ufs-qcom glue driver.

-Manu

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation


Re: [PATCH v6 1/3] phy: Update PHY power control sequence

2018-06-07 Thread Manu Gautam
Hi,

On 5/29/2018 10:07 AM, Can Guo wrote:
> All PHYs should be powered on before register configuration starts. And
> only PCIe PHYs need an extra power control before deasserts reset state.
>
> Signed-off-by: Can Guo 
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp.c | 5 -
>  1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
> b/drivers/phy/qualcomm/phy-qcom-qmp.c
> index 97ef942..f779b0f 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
> @@ -982,6 +982,8 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
>   if (cfg->has_phy_com_ctrl)
>   qphy_setbits(serdes, cfg->regs[QPHY_COM_POWER_DOWN_CONTROL],
>SW_PWRDN);
> + else
> + qphy_setbits(pcs, QPHY_POWER_DOWN_CONTROL, cfg->pwrdn_ctrl);

We should power-up PHYs after following dp_com_ctrl programming which
powers-off USB-DP combo PHY when it brings DP_COM block out of reset reset.


>  
>   if (cfg->has_phy_dp_com_ctrl) {
>   qphy_setbits(dp_com, QPHY_V3_DP_COM_POWER_DOWN_CTRL,
> @@ -1127,7 +1129,8 @@ static int qcom_qmp_phy_init(struct phy *phy)
>* Pull out PHY from POWER DOWN state.
>* This is active low enable signal to power-down PHY.
>*/
> - qphy_setbits(pcs, QPHY_POWER_DOWN_CONTROL, cfg->pwrdn_ctrl);
> + if (cfg->type == PHY_TYPE_PCIE)
> + qphy_setbits(pcs, QPHY_POWER_DOWN_CONTROL, cfg->pwrdn_ctrl);
>  
>   if (cfg->has_pwrdn_delay)
>   usleep_range(cfg->pwrdn_delay_min, cfg->pwrdn_delay_max);

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH] usb: dwc3: Remove DEBUG define from Qualcomm DWC3 glue driver

2018-05-26 Thread Manu Gautam
Hi,


On 5/26/2018 3:37 AM, Douglas Anderson wrote:
> It appears that a "#define DEBUG" was left in on the recent patch
> landed for the Qualcomm DWC3 glue driver.  Let's remove it.
>
> Fixes: a4333c3a6ba9 ("usb: dwc3: Add Qualcomm DWC3 glue driver")
> Signed-off-by: Douglas Anderson 
> ---
>
>  drivers/usb/dwc3/dwc3-qcom.c | 1 -
>  1 file changed, 1 deletion(-)
>
> diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c
> index 8abb6f31389d..b0e67ab2f98c 100644
> --- a/drivers/usb/dwc3/dwc3-qcom.c
> +++ b/drivers/usb/dwc3/dwc3-qcom.c
> @@ -3,7 +3,6 @@
>   *
>   * Inspired by dwc3-of-simple.c
>   */
> -#define DEBUG

:(.. Sorry about that.. Thanks for fixing it.

>  
>  #include 
>  #include 

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v4 1/3] dt-bindings: usb: Update documentation for Qualcomm DWC3 driver

2018-05-09 Thread Manu Gautam
Existing documentation has lot of incorrect information as it
was originally added for a driver that no longer exists.

Signed-off-by: Manu Gautam 
Reviewed-by: Rob Herring 
---
 .../devicetree/bindings/usb/qcom,dwc3.txt  | 85 --
 1 file changed, 63 insertions(+), 22 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/qcom,dwc3.txt 
b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
index bc8a2fa..95afdcf 100644
--- a/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
+++ b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
@@ -1,54 +1,95 @@
 Qualcomm SuperSpeed DWC3 USB SoC controller
 
 Required properties:
-- compatible:  should contain "qcom,dwc3"
+- compatible:  Compatible list, contains
+   "qcom,dwc3"
+   "qcom,msm8996-dwc3" for msm8996 SOC.
+   "qcom,sdm845-dwc3" for sdm845 SOC.
+- reg: Offset and length of register set for QSCRATCH wrapper
+- power-domains:   specifies a phandle to PM domain provider node
 - clocks:  A list of phandle + clock-specifier pairs for the
clocks listed in clock-names
-- clock-names: Should contain the following:
+- clock-names: Should contain the following:
   "core"   Master/Core clock, have to be >= 125 MHz for SS
operation and >= 60MHz for HS operation
+  "mock_utmi"  Mock utmi clock needed for ITP/SOF generation in
+   host mode. Its frequency should be 19.2MHz.
+  "sleep"  Sleep clock, used for wakeup when USB3 core goes
+   into low power mode (U3).
 
 Optional clocks:
-  "iface"  System bus AXI clock.  Not present on all platforms
-  "sleep"  Sleep clock, used when USB3 core goes into low
-   power mode (U3).
+  "iface"  System bus AXI clock.
+   Not present on "qcom,msm8996-dwc3" compatible.
+  "cfg_noc"System Config NOC clock.
+   Not present on "qcom,msm8996-dwc3" compatible.
+- assigned-clocks: Should be:
+   MOCK_UTMI_CLK
+   MASTER_CLK
+- assigned-clock-rates: Should be:
+19.2Mhz (19200) for MOCK_UTMI_CLK
+>=125Mhz (12500) for MASTER_CLK in SS mode
+>=60Mhz (6000) for MASTER_CLK in HS mode
+
+Optional properties:
+- resets:  Phandle to reset control that resets core and wrapper.
+- interrupts:  specifies interrupts from controller wrapper used
+   to wakeup from low power/susepnd state. Must contain
+   one or more entry for interrupt-names property
+- interrupt-names: Must include the following entries:
+   - "hs_phy_irq": The interrupt that is asserted when a
+  wakeup event is received on USB2 bus
+   - "ss_phy_irq": The interrupt that is asserted when a
+  wakeup event is received on USB3 bus
+   - "dm_hs_phy_irq" and "dp_hs_phy_irq": Separate
+  interrupts for any wakeup event on DM and DP lines
+- qcom,select-utmi-as-pipe-clk: if present, disable USB3 pipe_clk requirement.
+   Used when dwc3 operates without SSPHY and only
+   HS/FS/LS modes are supported.
 
 Required child node:
 A child node must exist to represent the core DWC3 IP block. The name of
 the node is not important. The content of the node is defined in dwc3.txt.
 
 Phy documentation is provided in the following places:
-Documentation/devicetree/bindings/phy/qcom-dwc3-usb-phy.txt
+Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt   - USB3 QMP PHY
+Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt - USB2 QUSB2 PHY
 
 Example device nodes:
 
hs_phy: phy@100f8800 {
-   compatible = "qcom,dwc3-hs-usb-phy";
-   reg = <0x100f8800 0x30>;
-   clocks = <&gcc USB30_0_UTMI_CLK>;
-   clock-names = "ref";
-   #phy-cells = <0>;
-
+   compatible = "qcom,qusb2-v2-phy";
+   ...
};
 
ss_phy: phy@100f8830 {
-   compatible = "qcom,dwc3-ss-usb-phy";
-   reg = <0x100f8830 0x30>;
-   clocks = <&gcc USB30_0_MASTER_CLK>;
-   clock-names = "ref";

[PATCH v4 3/3] usb: dwc3: core: Suspend PHYs on runtime suspend in host mode

2018-05-09 Thread Manu Gautam
Some PHY drivers (e.g. for Qualcomm QUSB2 and QMP PHYs) support
runtime PM to reduce PHY power consumption during bus_suspend.
Add changes to let core auto-suspend PHYs on host bus-suspend
using GUSB2PHYCFG register if needed for a platform. Also perform
PHYs runtime suspend/resume and let platform glue drivers e.g.
dwc3-qcom handle remote wakeup during bus suspend by waking up
devices on receiving wakeup event from PHY.

Signed-off-by: Manu Gautam 
---
 drivers/usb/dwc3/core.c | 36 +---
 1 file changed, 33 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index a15648d..449a098 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -1394,6 +1394,7 @@ static int dwc3_remove(struct platform_device *pdev)
 static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg)
 {
unsigned long   flags;
+   u32 reg;
 
switch (dwc->current_dr_role) {
case DWC3_GCTL_PRTCAP_DEVICE:
@@ -1403,9 +1404,25 @@ static int dwc3_suspend_common(struct dwc3 *dwc, 
pm_message_t msg)
dwc3_core_exit(dwc);
break;
case DWC3_GCTL_PRTCAP_HOST:
-   /* do nothing during host runtime_suspend */
-   if (!PMSG_IS_AUTO(msg))
+   if (!PMSG_IS_AUTO(msg)) {
dwc3_core_exit(dwc);
+   break;
+   }
+
+   /* Let controller to suspend HSPHY before PHY driver suspends */
+   if (dwc->dis_u2_susphy_quirk ||
+   dwc->dis_enblslpm_quirk) {
+   reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+   reg |=  DWC3_GUSB2PHYCFG_ENBLSLPM |
+   DWC3_GUSB2PHYCFG_SUSPHY;
+   dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+
+   /* Give some time for USB2 PHY to suspend */
+   usleep_range(5000, 6000);
+   }
+
+   phy_pm_runtime_put_sync(dwc->usb2_generic_phy);
+   phy_pm_runtime_put_sync(dwc->usb3_generic_phy);
break;
case DWC3_GCTL_PRTCAP_OTG:
/* do nothing during runtime_suspend */
@@ -1433,6 +1450,7 @@ static int dwc3_resume_common(struct dwc3 *dwc, 
pm_message_t msg)
 {
unsigned long   flags;
int ret;
+   u32 reg;
 
switch (dwc->current_dr_role) {
case DWC3_GCTL_PRTCAP_DEVICE:
@@ -1446,13 +1464,25 @@ static int dwc3_resume_common(struct dwc3 *dwc, 
pm_message_t msg)
spin_unlock_irqrestore(&dwc->lock, flags);
break;
case DWC3_GCTL_PRTCAP_HOST:
-   /* nothing to do on host runtime_resume */
if (!PMSG_IS_AUTO(msg)) {
ret = dwc3_core_init(dwc);
if (ret)
return ret;
dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST);
+   break;
}
+   /* Restore GUSB2PHYCFG bits that were modified in suspend */
+   reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+   if (dwc->dis_u2_susphy_quirk)
+   reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
+
+   if (dwc->dis_enblslpm_quirk)
+   reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
+
+   dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+
+   phy_pm_runtime_get_sync(dwc->usb2_generic_phy);
+   phy_pm_runtime_get_sync(dwc->usb3_generic_phy);
break;
case DWC3_GCTL_PRTCAP_OTG:
/* nothing to do on runtime_resume */
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v4 0/3] usb: dwc3: support for Qualcomm DWC3 glue

2018-05-09 Thread Manu Gautam
Add separate dwc3-qcom glue driver for Qualcomm SOCs having dwc3 core.
It is needed to support peripheral mode.
Patches also add support to invoke PHY runtime PM functions on host
mode bus-suspend.

Changes since v3:
 - Added SOC specific compatibles in driver.

Changes since v2:
 - Addressed Rob's comments for DT binding documentation.

Changes since v1:
 - Move dwc3 core register accesses from glue driver to dwc3 core as
   per review comment from Felipe.
 - Addressed other review comments from Felipe and Rob.
 - Some other minor code changes related to redability.
 - Add reset_control assert in driver probe to ensure core registers
   are reset to POR value in case of any initalization by boot code. 

Manu Gautam (3):
  dt-bindings: usb: Update documentation for Qualcomm DWC3 driver
  usb: dwc3: Add Qualcomm DWC3 glue driver
  usb: dwc3: core: Suspend PHYs on runtime suspend in host mode

 .../devicetree/bindings/usb/qcom,dwc3.txt  |  85 ++-
 drivers/usb/dwc3/Kconfig   |  12 +
 drivers/usb/dwc3/Makefile  |   1 +
 drivers/usb/dwc3/core.c|  36 +-
 drivers/usb/dwc3/dwc3-of-simple.c  |   1 -
 drivers/usb/dwc3/dwc3-qcom.c   | 620 +
 6 files changed, 729 insertions(+), 26 deletions(-)
 create mode 100644 drivers/usb/dwc3/dwc3-qcom.c

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v4 2/3] usb: dwc3: Add Qualcomm DWC3 glue driver

2018-05-09 Thread Manu Gautam
DWC3 controller on Qualcomm SOCs has a Qscratch wrapper.
Some of its uses are described below resulting in need to
have a separate glue driver instead of using dwc3-of-simple:
 - It exposes register interface to override vbus-override
   and lane0-pwr-present signals going to hardware. These
   must be updated in peripheral mode for DWC3 if vbus lines
   are not connected to hardware block. Otherwise RX termination
   in SS mode or DP pull-up is not applied by device controller.
 - pwr_events_irq_stat support to check if USB2 PHY is in L2 state
   before glue driver proceeds with suspend.
 - Support for wakeup interrupts lines that are asserted whenever
   there is any wakeup event on USB3 or USB2 bus.
 - Support to replace pip3 clock going to DWC3 with utmi clock
   for hardware configuration where SSPHY is not used with DWC3.

Signed-off-by: Manu Gautam 
---
 drivers/usb/dwc3/Kconfig  |  12 +
 drivers/usb/dwc3/Makefile |   1 +
 drivers/usb/dwc3/dwc3-of-simple.c |   1 -
 drivers/usb/dwc3/dwc3-qcom.c  | 620 ++
 4 files changed, 633 insertions(+), 1 deletion(-)
 create mode 100644 drivers/usb/dwc3/dwc3-qcom.c

diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index ab8c0e0..451012e 100644
--- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig
@@ -106,4 +106,16 @@ config USB_DWC3_ST
  inside (i.e. STiH407).
  Say 'Y' or 'M' if you have one such device.
 
+config USB_DWC3_QCOM
+   tristate "Qualcomm Platform"
+   depends on ARCH_QCOM || COMPILE_TEST
+   depends on OF
+   default USB_DWC3
+   help
+ Some Qualcomm SoCs use DesignWare Core IP for USB2/3
+ functionality.
+ This driver also handles Qscratch wrapper which is needed
+ for peripheral mode support.
+ Say 'Y' or 'M' if you have one such device.
+
 endif
diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
index 025bc68..5c07d8f 100644
--- a/drivers/usb/dwc3/Makefile
+++ b/drivers/usb/dwc3/Makefile
@@ -48,3 +48,4 @@ obj-$(CONFIG_USB_DWC3_PCI)+= dwc3-pci.o
 obj-$(CONFIG_USB_DWC3_KEYSTONE)+= dwc3-keystone.o
 obj-$(CONFIG_USB_DWC3_OF_SIMPLE)   += dwc3-of-simple.o
 obj-$(CONFIG_USB_DWC3_ST)  += dwc3-st.o
+obj-$(CONFIG_USB_DWC3_QCOM)+= dwc3-qcom.o
diff --git a/drivers/usb/dwc3/dwc3-of-simple.c 
b/drivers/usb/dwc3/dwc3-of-simple.c
index cb2ee96..0fd0e8e 100644
--- a/drivers/usb/dwc3/dwc3-of-simple.c
+++ b/drivers/usb/dwc3/dwc3-of-simple.c
@@ -208,7 +208,6 @@ static int dwc3_of_simple_runtime_resume(struct device *dev)
 };
 
 static const struct of_device_id of_dwc3_simple_match[] = {
-   { .compatible = "qcom,dwc3" },
{ .compatible = "rockchip,rk3399-dwc3" },
{ .compatible = "xlnx,zynqmp-dwc3" },
{ .compatible = "cavium,octeon-7130-usb-uctl" },
diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c
new file mode 100644
index 000..8abb6f3
--- /dev/null
+++ b/drivers/usb/dwc3/dwc3-qcom.c
@@ -0,0 +1,620 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * Inspired by dwc3-of-simple.c
+ */
+#define DEBUG
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "core.h"
+
+/* USB QSCRATCH Hardware registers */
+#define QSCRATCH_HS_PHY_CTRL   0x10
+#define UTMI_OTG_VBUS_VALIDBIT(20)
+#define SW_SESSVLD_SEL BIT(28)
+
+#define QSCRATCH_SS_PHY_CTRL   0x30
+#define LANE0_PWR_PRESENT  BIT(24)
+
+#define QSCRATCH_GENERAL_CFG   0x08
+#define PIPE_UTMI_CLK_SEL  BIT(0)
+#define PIPE3_PHYSTATUS_SW BIT(3)
+#define PIPE_UTMI_CLK_DIS  BIT(8)
+
+#define PWR_EVNT_IRQ_STAT_REG  0x58
+#define PWR_EVNT_LPM_IN_L2_MASKBIT(4)
+#define PWR_EVNT_LPM_OUT_L2_MASK   BIT(5)
+
+struct dwc3_qcom {
+   struct device   *dev;
+   void __iomem*qscratch_base;
+   struct platform_device  *dwc3;
+   struct clk  **clks;
+   int num_clocks;
+   struct reset_control*resets;
+
+   int hs_phy_irq;
+   int dp_hs_phy_irq;
+   int dm_hs_phy_irq;
+   int ss_phy_irq;
+
+   struct extcon_dev   *edev;
+   struct extcon_dev   *host_edev;
+   struct notifier_block   vbus_nb;
+   struct notifier_block   host_nb;
+
+   enum usb_dr_modemode;
+   boolis_suspended;
+   boolpm_suspended;
+};
+
+static inli

Re: [PATCH v3 2/3] usb: dwc3: Add Qualcomm DWC3 glue driver

2018-05-07 Thread Manu Gautam


On 5/5/2018 12:18 AM, Manu Gautam wrote:
> DWC3 controller on Qualcomm SOCs has a Qscratch wrapper.
> Some of its uses are described below resulting in need to
> have a separate glue driver instead of using dwc3-of-simple:
>  - It exposes register interface to override vbus-override
>and lane0-pwr-present signals going to hardware. These
>must be updated in peripheral mode for DWC3 if vbus lines
>are not connected to hardware block. Otherwise RX termination
>in SS mode or DP pull-up is not applied by device controller.
>  - pwr_events_irq_stat support to check if USB2 PHY is in L2 state
>before glue driver proceeds with suspend.
>  - Support for wakeup interrupts lines that are asserted whenever
>there is any wakeup event on USB3 or USB2 bus.
>  - Support to replace pip3 clock going to DWC3 with utmi clock
>for hardware configuration where SSPHY is not used with DWC3.
>
> Signed-off-by: Manu Gautam 
[snip]
> +static const struct of_device_id dwc3_qcom_of_match[] = {
> + { .compatible = "qcom,dwc3" },

I should also add SOC specific compatibles.
Will do that in next patch.


-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v3 2/3] usb: dwc3: Add Qualcomm DWC3 glue driver

2018-05-04 Thread Manu Gautam
DWC3 controller on Qualcomm SOCs has a Qscratch wrapper.
Some of its uses are described below resulting in need to
have a separate glue driver instead of using dwc3-of-simple:
 - It exposes register interface to override vbus-override
   and lane0-pwr-present signals going to hardware. These
   must be updated in peripheral mode for DWC3 if vbus lines
   are not connected to hardware block. Otherwise RX termination
   in SS mode or DP pull-up is not applied by device controller.
 - pwr_events_irq_stat support to check if USB2 PHY is in L2 state
   before glue driver proceeds with suspend.
 - Support for wakeup interrupts lines that are asserted whenever
   there is any wakeup event on USB3 or USB2 bus.
 - Support to replace pip3 clock going to DWC3 with utmi clock
   for hardware configuration where SSPHY is not used with DWC3.

Signed-off-by: Manu Gautam 
---
 drivers/usb/dwc3/Kconfig  |  12 +
 drivers/usb/dwc3/Makefile |   1 +
 drivers/usb/dwc3/dwc3-of-simple.c |   1 -
 drivers/usb/dwc3/dwc3-qcom.c  | 618 ++
 4 files changed, 631 insertions(+), 1 deletion(-)
 create mode 100644 drivers/usb/dwc3/dwc3-qcom.c

diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index ab8c0e0..451012e 100644
--- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig
@@ -106,4 +106,16 @@ config USB_DWC3_ST
  inside (i.e. STiH407).
  Say 'Y' or 'M' if you have one such device.
 
+config USB_DWC3_QCOM
+   tristate "Qualcomm Platform"
+   depends on ARCH_QCOM || COMPILE_TEST
+   depends on OF
+   default USB_DWC3
+   help
+ Some Qualcomm SoCs use DesignWare Core IP for USB2/3
+ functionality.
+ This driver also handles Qscratch wrapper which is needed
+ for peripheral mode support.
+ Say 'Y' or 'M' if you have one such device.
+
 endif
diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
index 025bc68..5c07d8f 100644
--- a/drivers/usb/dwc3/Makefile
+++ b/drivers/usb/dwc3/Makefile
@@ -48,3 +48,4 @@ obj-$(CONFIG_USB_DWC3_PCI)+= dwc3-pci.o
 obj-$(CONFIG_USB_DWC3_KEYSTONE)+= dwc3-keystone.o
 obj-$(CONFIG_USB_DWC3_OF_SIMPLE)   += dwc3-of-simple.o
 obj-$(CONFIG_USB_DWC3_ST)  += dwc3-st.o
+obj-$(CONFIG_USB_DWC3_QCOM)+= dwc3-qcom.o
diff --git a/drivers/usb/dwc3/dwc3-of-simple.c 
b/drivers/usb/dwc3/dwc3-of-simple.c
index cb2ee96..0fd0e8e 100644
--- a/drivers/usb/dwc3/dwc3-of-simple.c
+++ b/drivers/usb/dwc3/dwc3-of-simple.c
@@ -208,7 +208,6 @@ static int dwc3_of_simple_runtime_resume(struct device *dev)
 };
 
 static const struct of_device_id of_dwc3_simple_match[] = {
-   { .compatible = "qcom,dwc3" },
{ .compatible = "rockchip,rk3399-dwc3" },
{ .compatible = "xlnx,zynqmp-dwc3" },
{ .compatible = "cavium,octeon-7130-usb-uctl" },
diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c
new file mode 100644
index 000..ecb2218
--- /dev/null
+++ b/drivers/usb/dwc3/dwc3-qcom.c
@@ -0,0 +1,618 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * Inspired by dwc3-of-simple.c
+ */
+#define DEBUG
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "core.h"
+
+/* USB QSCRATCH Hardware registers */
+#define QSCRATCH_HS_PHY_CTRL   0x10
+#define UTMI_OTG_VBUS_VALIDBIT(20)
+#define SW_SESSVLD_SEL BIT(28)
+
+#define QSCRATCH_SS_PHY_CTRL   0x30
+#define LANE0_PWR_PRESENT  BIT(24)
+
+#define QSCRATCH_GENERAL_CFG   0x08
+#define PIPE_UTMI_CLK_SEL  BIT(0)
+#define PIPE3_PHYSTATUS_SW BIT(3)
+#define PIPE_UTMI_CLK_DIS  BIT(8)
+
+#define PWR_EVNT_IRQ_STAT_REG  0x58
+#define PWR_EVNT_LPM_IN_L2_MASKBIT(4)
+#define PWR_EVNT_LPM_OUT_L2_MASK   BIT(5)
+
+struct dwc3_qcom {
+   struct device   *dev;
+   void __iomem*qscratch_base;
+   struct platform_device  *dwc3;
+   struct clk  **clks;
+   int num_clocks;
+   struct reset_control*resets;
+
+   int hs_phy_irq;
+   int dp_hs_phy_irq;
+   int dm_hs_phy_irq;
+   int ss_phy_irq;
+
+   struct extcon_dev   *edev;
+   struct extcon_dev   *host_edev;
+   struct notifier_block   vbus_nb;
+   struct notifier_block   host_nb;
+
+   enum usb_dr_modemode;
+   boolis_suspended;
+   boolpm_suspended;
+};
+
+static inli

[PATCH v3 3/3] usb: dwc3: core: Suspend PHYs on runtime suspend in host mode

2018-05-04 Thread Manu Gautam
Some PHY drivers (e.g. for Qualcomm QUSB2 and QMP PHYs) support
runtime PM to reduce PHY power consumption during bus_suspend.
Add changes to let core auto-suspend PHYs on host bus-suspend
using GUSB2PHYCFG register if needed for a platform. Also perform
PHYs runtime suspend/resume and let platform glue drivers e.g.
dwc3-qcom handle remote wakeup during bus suspend by waking up
devices on receiving wakeup event from PHY.

Signed-off-by: Manu Gautam 
---
 drivers/usb/dwc3/core.c | 36 +---
 1 file changed, 33 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index a15648d..449a098 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -1394,6 +1394,7 @@ static int dwc3_remove(struct platform_device *pdev)
 static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg)
 {
unsigned long   flags;
+   u32 reg;
 
switch (dwc->current_dr_role) {
case DWC3_GCTL_PRTCAP_DEVICE:
@@ -1403,9 +1404,25 @@ static int dwc3_suspend_common(struct dwc3 *dwc, 
pm_message_t msg)
dwc3_core_exit(dwc);
break;
case DWC3_GCTL_PRTCAP_HOST:
-   /* do nothing during host runtime_suspend */
-   if (!PMSG_IS_AUTO(msg))
+   if (!PMSG_IS_AUTO(msg)) {
dwc3_core_exit(dwc);
+   break;
+   }
+
+   /* Let controller to suspend HSPHY before PHY driver suspends */
+   if (dwc->dis_u2_susphy_quirk ||
+   dwc->dis_enblslpm_quirk) {
+   reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+   reg |=  DWC3_GUSB2PHYCFG_ENBLSLPM |
+   DWC3_GUSB2PHYCFG_SUSPHY;
+   dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+
+   /* Give some time for USB2 PHY to suspend */
+   usleep_range(5000, 6000);
+   }
+
+   phy_pm_runtime_put_sync(dwc->usb2_generic_phy);
+   phy_pm_runtime_put_sync(dwc->usb3_generic_phy);
break;
case DWC3_GCTL_PRTCAP_OTG:
/* do nothing during runtime_suspend */
@@ -1433,6 +1450,7 @@ static int dwc3_resume_common(struct dwc3 *dwc, 
pm_message_t msg)
 {
unsigned long   flags;
int ret;
+   u32 reg;
 
switch (dwc->current_dr_role) {
case DWC3_GCTL_PRTCAP_DEVICE:
@@ -1446,13 +1464,25 @@ static int dwc3_resume_common(struct dwc3 *dwc, 
pm_message_t msg)
spin_unlock_irqrestore(&dwc->lock, flags);
break;
case DWC3_GCTL_PRTCAP_HOST:
-   /* nothing to do on host runtime_resume */
if (!PMSG_IS_AUTO(msg)) {
ret = dwc3_core_init(dwc);
if (ret)
return ret;
dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST);
+   break;
}
+   /* Restore GUSB2PHYCFG bits that were modified in suspend */
+   reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+   if (dwc->dis_u2_susphy_quirk)
+   reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
+
+   if (dwc->dis_enblslpm_quirk)
+   reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
+
+   dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+
+   phy_pm_runtime_get_sync(dwc->usb2_generic_phy);
+   phy_pm_runtime_get_sync(dwc->usb3_generic_phy);
break;
case DWC3_GCTL_PRTCAP_OTG:
/* nothing to do on runtime_resume */
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v3 1/3] dt-bindings: usb: Update documentation for Qualcomm DWC3 driver

2018-05-04 Thread Manu Gautam
Existing documentation has lot of incorrect information as it
was originally added for a driver that no longer exists.

Signed-off-by: Manu Gautam 
---
 .../devicetree/bindings/usb/qcom,dwc3.txt  | 85 --
 1 file changed, 63 insertions(+), 22 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/qcom,dwc3.txt 
b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
index bc8a2fa..95afdcf 100644
--- a/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
+++ b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
@@ -1,54 +1,95 @@
 Qualcomm SuperSpeed DWC3 USB SoC controller
 
 Required properties:
-- compatible:  should contain "qcom,dwc3"
+- compatible:  Compatible list, contains
+   "qcom,dwc3"
+   "qcom,msm8996-dwc3" for msm8996 SOC.
+   "qcom,sdm845-dwc3" for sdm845 SOC.
+- reg: Offset and length of register set for QSCRATCH wrapper
+- power-domains:   specifies a phandle to PM domain provider node
 - clocks:  A list of phandle + clock-specifier pairs for the
clocks listed in clock-names
-- clock-names: Should contain the following:
+- clock-names: Should contain the following:
   "core"   Master/Core clock, have to be >= 125 MHz for SS
operation and >= 60MHz for HS operation
+  "mock_utmi"  Mock utmi clock needed for ITP/SOF generation in
+   host mode. Its frequency should be 19.2MHz.
+  "sleep"  Sleep clock, used for wakeup when USB3 core goes
+   into low power mode (U3).
 
 Optional clocks:
-  "iface"  System bus AXI clock.  Not present on all platforms
-  "sleep"  Sleep clock, used when USB3 core goes into low
-   power mode (U3).
+  "iface"  System bus AXI clock.
+   Not present on "qcom,msm8996-dwc3" compatible.
+  "cfg_noc"System Config NOC clock.
+   Not present on "qcom,msm8996-dwc3" compatible.
+- assigned-clocks: Should be:
+   MOCK_UTMI_CLK
+   MASTER_CLK
+- assigned-clock-rates: Should be:
+19.2Mhz (19200) for MOCK_UTMI_CLK
+>=125Mhz (12500) for MASTER_CLK in SS mode
+>=60Mhz (6000) for MASTER_CLK in HS mode
+
+Optional properties:
+- resets:  Phandle to reset control that resets core and wrapper.
+- interrupts:  specifies interrupts from controller wrapper used
+   to wakeup from low power/susepnd state. Must contain
+   one or more entry for interrupt-names property
+- interrupt-names: Must include the following entries:
+   - "hs_phy_irq": The interrupt that is asserted when a
+  wakeup event is received on USB2 bus
+   - "ss_phy_irq": The interrupt that is asserted when a
+  wakeup event is received on USB3 bus
+   - "dm_hs_phy_irq" and "dp_hs_phy_irq": Separate
+  interrupts for any wakeup event on DM and DP lines
+- qcom,select-utmi-as-pipe-clk: if present, disable USB3 pipe_clk requirement.
+   Used when dwc3 operates without SSPHY and only
+   HS/FS/LS modes are supported.
 
 Required child node:
 A child node must exist to represent the core DWC3 IP block. The name of
 the node is not important. The content of the node is defined in dwc3.txt.
 
 Phy documentation is provided in the following places:
-Documentation/devicetree/bindings/phy/qcom-dwc3-usb-phy.txt
+Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt   - USB3 QMP PHY
+Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt - USB2 QUSB2 PHY
 
 Example device nodes:
 
hs_phy: phy@100f8800 {
-   compatible = "qcom,dwc3-hs-usb-phy";
-   reg = <0x100f8800 0x30>;
-   clocks = <&gcc USB30_0_UTMI_CLK>;
-   clock-names = "ref";
-   #phy-cells = <0>;
-
+   compatible = "qcom,qusb2-v2-phy";
+   ...
};
 
ss_phy: phy@100f8830 {
-   compatible = "qcom,dwc3-ss-usb-phy";
-   reg = <0x100f8830 0x30>;
-   clocks = <&gcc USB30_0_MASTER_CLK>;
-   clock-names = "ref";
-

[PATCH v3 0/3] usb: dwc3: support for Qualcomm DWC3 glue

2018-05-04 Thread Manu Gautam
Add separate dwc3-qcom glue driver for Qualcomm SOCs having dwc3 core.
It is needed to support peripheral mode.
Patches also add support to invoke PHY runtime PM functions on host
mode bus-suspend.

Changes since v2:
 - Addressed Rob's comments for DT binding documentation.

Changes since v1:
 - Move dwc3 core register accesses from glue driver to dwc3 core as
   per review comment from Felipe.
 - Addressed other review comments from Felipe and Rob.
 - Some other minor code changes related to redability.
 - Add reset_control assert in driver probe to ensure core registers
   are reset to POR value in case of any initalization by boot code. 

Manu Gautam (3):
  dt-bindings: usb: Update documentation for Qualcomm DWC3 driver
  usb: dwc3: Add Qualcomm DWC3 glue driver
  usb: dwc3: core: Suspend PHYs on runtime suspend in host mode

 .../devicetree/bindings/usb/qcom,dwc3.txt  |  85 ++-
 drivers/usb/dwc3/Kconfig   |  12 +
 drivers/usb/dwc3/Makefile  |   1 +
 drivers/usb/dwc3/core.c|  36 +-
 drivers/usb/dwc3/dwc3-of-simple.c  |   1 -
 drivers/usb/dwc3/dwc3-qcom.c   | 618 +
 6 files changed, 727 insertions(+), 26 deletions(-)
 create mode 100644 drivers/usb/dwc3/dwc3-qcom.c

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v5 1/7] clk: msm8996-gcc: Mark halt check as no-op for USB/PCIE pipe_clk

2018-05-02 Thread Manu Gautam
The USB and PCIE pipe clocks are sourced from external clocks
inside the QMP USB/PCIE PHYs. Enabling or disabling of PIPE RCG
clocks is dependent on PHY initialization sequence hence
update halt_check to BRANCH_HALT_SKIP for these clocks so
that clock status bit is not polled when enabling or disabling
the clocks. It allows to simplify PHY client driver code which
is both user and source of the pipe_clk and avoid error logging
related status check on clk_disable/enable.

Signed-off-by: Manu Gautam 
---
 drivers/clk/qcom/gcc-msm8996.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c
index 3d64529..b73e7f1 100644
--- a/drivers/clk/qcom/gcc-msm8996.c
+++ b/drivers/clk/qcom/gcc-msm8996.c
@@ -1418,6 +1418,7 @@ enum {
 
 static struct clk_branch gcc_usb3_phy_pipe_clk = {
.halt_reg = 0x50004,
+   .halt_check = BRANCH_HALT_SKIP,
.clkr = {
.enable_reg = 0x50004,
.enable_mask = BIT(0),
@@ -2472,6 +2473,7 @@ enum {
 
 static struct clk_branch gcc_pcie_0_pipe_clk = {
.halt_reg = 0x6b018,
+   .halt_check = BRANCH_HALT_SKIP,
.clkr = {
.enable_reg = 0x6b018,
.enable_mask = BIT(0),
@@ -2547,6 +2549,7 @@ enum {
 
 static struct clk_branch gcc_pcie_1_pipe_clk = {
.halt_reg = 0x6d018,
+   .halt_check = BRANCH_HALT_SKIP,
.clkr = {
.enable_reg = 0x6d018,
.enable_mask = BIT(0),
@@ -2622,6 +2625,7 @@ enum {
 
 static struct clk_branch gcc_pcie_2_pipe_clk = {
.halt_reg = 0x6e018,
+   .halt_check = BRANCH_HALT_SKIP,
.clkr = {
.enable_reg = 0x6e018,
.enable_mask = BIT(0),
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v5 3/7] phy: qcom-qusb2: Fix crash if nvmem cell not specified

2018-05-02 Thread Manu Gautam
Driver currently crashes due to NULL pointer deference
while updating PHY tune register if nvmem cell is NULL.
Since, fused value for Tune1/2 register is optional,
we'd rather bail out.

Fixes: ca04d9d3e1b1 ("phy: qcom-qusb2: New driver for QUSB2 PHY on Qcom chips")
Reviewed-by: Vivek Gautam 
Reviewed-by: Evan Green 
Cc: stable  # 4.14+
Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qusb2.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c 
b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index 94afeac..40fdef8 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -315,6 +315,10 @@ static void qusb2_phy_set_tune2_param(struct qusb2_phy 
*qphy)
const struct qusb2_phy_cfg *cfg = qphy->cfg;
u8 *val;
 
+   /* efuse register is optional */
+   if (!qphy->cell)
+   return;
+
/*
 * Read efuse register having TUNE2/1 parameter's high nibble.
 * If efuse register shows value as 0x0, or if we fail to find
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v5 4/7] dt-bindings: phy-qcom-qmp: Update bindings for sdm845

2018-05-02 Thread Manu Gautam
Update compatible strings for USB3 PHYs on SDM845.
One is QMPv3 DisplayPort-USB combo PHY and other one
is USB UNI PHY which is single lane USB3 PHY without
DP capability. While at it also remove "qcom,qmp-v3-usb3-phy"
compatible string which was earlier added for sdm845
only as there wouldn't be any user of same.

Reviewed-by: Douglas Anderson 
Signed-off-by: Manu Gautam 
---
 Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt 
b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
index dcf1b8f..266a1bb 100644
--- a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
+++ b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
@@ -9,7 +9,8 @@ Required properties:
   "qcom,ipq8074-qmp-pcie-phy" for PCIe phy on IPQ8074
   "qcom,msm8996-qmp-pcie-phy" for 14nm PCIe phy on msm8996,
   "qcom,msm8996-qmp-usb3-phy" for 14nm USB3 phy on msm8996,
-  "qcom,qmp-v3-usb3-phy" for USB3 QMP V3 phy.
+  "qcom,sdm845-qmp-usb3-phy" for USB3 QMP V3 phy on sdm845,
+  "qcom,sdm845-qmp-usb3-uni-phy" for USB3 QMP V3 UNI phy on sdm845.
 
  - reg: offset and length of register set for PHY's common serdes block.
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v5 5/7] phy: qcom-qmp: Add QMP V3 USB3 UNI PHY support for sdm845

2018-05-02 Thread Manu Gautam
QMP V3 UNI PHY is a single lane USB3 PHY without support
for DisplayPort (DP).
Main difference from DP combo QMPv3 PHY is that UNI PHY
doesn't have dual RX/TX lanes and no separate DP_COM
block for configuration related to type-c or DP.
Also remove "qcom,qmp-v3-usb3-phy" compatible string which
was earlier added for sdm845 only as there wouldn't be
any user of same.
While at it, fix has_pwrdn_delay attribute for USB-DP
PHY configuration and.

Reviewed-by: Evan Green 
Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 147 +++-
 drivers/phy/qualcomm/phy-qcom-qmp.h |   5 ++
 2 files changed, 151 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
b/drivers/phy/qualcomm/phy-qcom-qmp.c
index fddb1c9..4c47010 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -490,6 +490,118 @@ enum qphy_reg_layout {
QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
 };
 
+static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_serdes_tbl[] = {
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL2, 0x08),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x80),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x34),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x15),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x04),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_CFG, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x0a),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x31),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x85),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x07),
+};
+
+static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_tx_tbl[] = {
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0xc6),
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x06),
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x06),
+};
+
+static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_rx_tbl[] = {
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x0c),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x50),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1c),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
+};
+
+static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_pcs_tbl[] = {
+   /* FLL settings */
+   QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
+   QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
+   QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
+   QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40),
+   QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
+

[PATCH v5 7/7] phy: qcom-qusb2: Add QUSB2 PHYs support for sdm845

2018-05-02 Thread Manu Gautam
There are two QUSB2 PHYs present on sdm845. In order
to improve eye diagram for both the PHYs some parameters
need to be changed. Provide device tree properties to
override these from board specific device tree files.

Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qusb2.c | 126 +++---
 1 file changed, 118 insertions(+), 8 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c 
b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index 40fdef8..e70e425 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -20,6 +20,8 @@
 #include 
 #include 
 
+#include 
+
 #define QUSB2PHY_PLL_TEST  0x04
 #define CLK_REF_SELBIT(7)
 
@@ -60,6 +62,17 @@
 #define CORE_RESET BIT(5)
 #define CORE_RESET_MUX BIT(6)
 
+/* QUSB2PHY_IMP_CTRL1 register bits */
+#define IMP_RES_OFFSET_MASKGENMASK(5, 0)
+#define IMP_RES_OFFSET_SHIFT   0x0
+
+/* QUSB2PHY_PORT_TUNE1 register bits */
+#define HSTX_TRIM_MASK GENMASK(7, 4)
+#define HSTX_TRIM_SHIFT0x4
+#define PREEMPH_WIDTH_HALF_BIT BIT(2)
+#define PREEMPHASIS_EN_MASKGENMASK(1, 0)
+#define PREEMPHASIS_EN_SHIFT   0x0
+
 #define QUSB2PHY_PLL_ANALOG_CONTROLS_TWO   0x04
 #define QUSB2PHY_PLL_CLOCK_INVERTERS   0x18c
 #define QUSB2PHY_PLL_CMODE 0x2c
@@ -139,7 +152,7 @@ enum qusb2phy_reg_layout {
QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_PWR_CTRL, 0x00),
 };
 
-static const unsigned int qusb2_v2_regs_layout[] = {
+static const unsigned int sdm845_regs_layout[] = {
[QUSB2PHY_PLL_CORE_INPUT_OVERRIDE] = 0xa8,
[QUSB2PHY_PLL_STATUS]   = 0x1a0,
[QUSB2PHY_PORT_TUNE1]   = 0x240,
@@ -153,7 +166,7 @@ enum qusb2phy_reg_layout {
[QUSB2PHY_INTR_CTRL]= 0x230,
 };
 
-static const struct qusb2_phy_init_tbl qusb2_v2_init_tbl[] = {
+static const struct qusb2_phy_init_tbl sdm845_init_tbl[] = {
QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_ANALOG_CONTROLS_TWO, 0x03),
QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_CLOCK_INVERTERS, 0x7c),
QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_CMODE, 0x80),
@@ -208,10 +221,10 @@ struct qusb2_phy_cfg {
.autoresume_en   = BIT(3),
 };
 
-static const struct qusb2_phy_cfg qusb2_v2_phy_cfg = {
-   .tbl= qusb2_v2_init_tbl,
-   .tbl_num= ARRAY_SIZE(qusb2_v2_init_tbl),
-   .regs   = qusb2_v2_regs_layout,
+static const struct qusb2_phy_cfg sdm845_phy_cfg = {
+   .tbl= sdm845_init_tbl,
+   .tbl_num= ARRAY_SIZE(sdm845_init_tbl),
+   .regs   = sdm845_regs_layout,
 
.disable_ctrl   = (PWR_CTRL1_VREF_SUPPLY_TRIM | PWR_CTRL1_CLAMP_N_EN |
   POWER_DOWN),
@@ -241,6 +254,15 @@ struct qusb2_phy_cfg {
  * @tcsr: TCSR syscon register map
  * @cell: nvmem cell containing phy tuning value
  *
+ * @override_imp_res_offset: PHY should use different rescode offset
+ * @imp_res_offset_value: rescode offset to be updated in IMP_CTRL1 register
+ * @override_hstx_trim: PHY should use different HSTX o/p current value
+ * @hstx_trim_value: HSTX_TRIM value to be updated in TUNE1 register
+ * @override_preemphasis: PHY should use different pre-amphasis amplitude
+ * @preemphasis_level: Amplitude Pre-Emphasis to be updated in TUNE1 register
+ * @override_preemphasis_width: PHY should use different pre-emphasis duration
+ * @preemphasis_width: half/full-width Pre-Emphasis updated via TUNE1
+ *
  * @cfg: phy config data
  * @has_se_clk_scheme: indicate if PHY has single-ended ref clock scheme
  * @phy_initialized: indicate if PHY has been initialized
@@ -259,12 +281,35 @@ struct qusb2_phy {
struct regmap *tcsr;
struct nvmem_cell *cell;
 
+   bool override_imp_res_offset;
+   u8 imp_res_offset_value;
+   bool override_hstx_trim;
+   u8 hstx_trim_value;
+   bool override_preemphasis;
+   u8 preemphasis_level;
+   bool override_preemphasis_width;
+   u8 preemphasis_width;
+
const struct qusb2_phy_cfg *cfg;
bool has_se_clk_scheme;
bool phy_initialized;
enum phy_mode mode;
 };
 
+static inline void qusb2_write_mask(void __iomem *base, u32 offset,
+   u32 val, u32 mask)
+{
+   u32 reg;
+
+   reg = readl(base + offset);
+   reg &= ~mask;
+   reg |= val & mask;
+   writel(reg, base + offset);
+
+   /* Ensure above write is completed */
+   readl(base + offset);
+}
+
 static inline void qusb2_setbits(void __iomem *base, u32 offset, u32 val)
 {
u32 reg;
@@ -305,6 +350,42 @@ void qcom_qusb2_phy_configure(void __iomem *base,
 }
 
 /*
+ * Update board specific PHY tuning override values if specified from
+ * device tree.
+ */
+static void qusb2_phy_override_phy_params(struct q

[PATCH v5 2/7] phy: qcom-qmp: Enable pipe_clk before PHY initialization

2018-05-02 Thread Manu Gautam
QMP PHY for USB/PCIE requires pipe_clk for locking of
retime buffers at the pipe interface. Driver checks for
PHY_STATUS without enabling pipe_clk due to which
phy_init() fails with initialization timeout.
Though pipe_clk is output from PHY (after PLL is programmed
during initialization sequence) to GCC clock_ctl and then fed
back to PHY but for PHY_STATUS register to reflect successful
initialization pipe_clk from GCC must be present.
Since, clock driver now ignores status_check for pipe_clk on
clk_enable/disable, driver can safely enable/disable pipe_clk
from phy_init/exit.

Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 22 --
 1 file changed, 8 insertions(+), 14 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 6470c5d..fddb1c9 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -793,19 +793,6 @@ static void qcom_qmp_phy_configure(void __iomem *base,
}
 }
 
-static int qcom_qmp_phy_poweron(struct phy *phy)
-{
-   struct qmp_phy *qphy = phy_get_drvdata(phy);
-   struct qcom_qmp *qmp = qphy->qmp;
-   int ret;
-
-   ret = clk_prepare_enable(qphy->pipe_clk);
-   if (ret)
-   dev_err(qmp->dev, "pipe_clk enable failed, err=%d\n", ret);
-
-   return ret;
-}
-
 static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
 {
const struct qmp_phy_cfg *cfg = qmp->cfg;
@@ -974,6 +961,12 @@ static int qcom_qmp_phy_init(struct phy *phy)
}
}
 
+   ret = clk_prepare_enable(qphy->pipe_clk);
+   if (ret) {
+   dev_err(qmp->dev, "pipe_clk enable failed err=%d\n", ret);
+   goto err_clk_enable;
+   }
+
/* Tx, Rx, and PCS configurations */
qcom_qmp_phy_configure(tx, cfg->regs, cfg->tx_tbl, cfg->tx_tbl_num);
/* Configuration for other LANE for USB-DP combo PHY */
@@ -1019,6 +1012,8 @@ static int qcom_qmp_phy_init(struct phy *phy)
return ret;
 
 err_pcs_ready:
+   clk_disable_unprepare(qphy->pipe_clk);
+err_clk_enable:
if (cfg->has_lane_rst)
reset_control_assert(qphy->lane_rst);
 err_lane_rst:
@@ -1283,7 +1278,6 @@ static int phy_pipe_clk_register(struct qcom_qmp *qmp, 
struct device_node *np)
 static const struct phy_ops qcom_qmp_phy_gen_ops = {
.init   = qcom_qmp_phy_init,
.exit   = qcom_qmp_phy_exit,
-   .power_on   = qcom_qmp_phy_poweron,
.set_mode   = qcom_qmp_phy_set_mode,
.owner  = THIS_MODULE,
 };
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v5 6/7] dt-bindings: phy-qcom-usb2: Add support to override tuning values

2018-05-02 Thread Manu Gautam
To improve eye diagram for PHYs on different boards of same SOC,
some parameters may need to be changed. Provide device tree
properties to override these from board specific device tree
files. While at it, replace "qcom,qusb2-v2-phy" with compatible
string for USB2 PHY on sdm845 which was earlier added for
sdm845 only.

Signed-off-by: Manu Gautam 
---
 .../devicetree/bindings/phy/qcom-qusb2-phy.txt | 23 +-
 include/dt-bindings/phy/phy-qcom-qusb2.h   | 37 ++
 2 files changed, 59 insertions(+), 1 deletion(-)
 create mode 100644 include/dt-bindings/phy/phy-qcom-qusb2.h

diff --git a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt 
b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
index 42c9742..03025d9 100644
--- a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
+++ b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
@@ -6,7 +6,7 @@ QUSB2 controller supports LS/FS/HS usb connectivity on Qualcomm 
chipsets.
 Required properties:
  - compatible: compatible list, contains
   "qcom,msm8996-qusb2-phy" for 14nm PHY on msm8996,
-  "qcom,qusb2-v2-phy" for QUSB2 V2 PHY.
+  "qcom,sdm845-qusb2-phy" for 10nm PHY on sdm845.
 
  - reg: offset and length of the PHY register set.
  - #phy-cells: must be 0.
@@ -27,6 +27,27 @@ Optional properties:
tuning parameter value for qusb2 phy.
 
  - qcom,tcsr-syscon: Phandle to TCSR syscon register region.
+ - qcom,imp-res-offset-value: It is a 6 bit value that specifies offset to be
+   added to PHY refgen RESCODE via IMP_CTRL1 register. It is a PHY
+   tuning parameter that may vary for different boards of same SOC.
+   This property is applicable to only QUSB2 v2 PHY (sdm845).
+ - qcom,hstx-trim-value: It is a 4 bit value that specifies tuning for HSTX
+   output current.
+   Possible range is - 15mA to 24mA (stepsize of 600 uA).
+   See dt-bindings/phy/phy-qcom-qusb2.h for applicable values.
+   This property is applicable to only QUSB2 v2 PHY (sdm845).
+   Default value is 22.2mA for sdm845.
+ - qcom,preemphasis-level: It is a 2 bit value that specifies pre-emphasis 
level.
+   Possible range is 0 to 15% (stepsize of 5%).
+   See dt-bindings/phy/phy-qcom-qusb2.h for applicable values.
+   This property is applicable to only QUSB2 v2 PHY (sdm845).
+   Default value is 10% for sdm845.
+- qcom,preemphasis-width: It is a 1 bit value that specifies how long the HSTX
+   pre-emphasis (specified using qcom,preemphasis-level) must be in
+   effect. Duration could be half-bit of full-bit.
+   See dt-bindings/phy/phy-qcom-qusb2.h for applicable values.
+   This property is applicable to only QUSB2 v2 PHY (sdm845).
+   Default value is full-bit width for sdm845.
 
 Example:
hsusb_phy: phy@7411000 {
diff --git a/include/dt-bindings/phy/phy-qcom-qusb2.h 
b/include/dt-bindings/phy/phy-qcom-qusb2.h
new file mode 100644
index 000..aea814a
--- /dev/null
+++ b/include/dt-bindings/phy/phy-qcom-qusb2.h
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_QCOM_PHY_QUSB2_H_
+#define _DT_BINDINGS_QCOM_PHY_QUSB2_H_
+
+/* PHY HSTX TRIM bit values (24mA to 15mA) */
+#define QUSB2_V2_HSTX_TRIM_24_0_MA 0x0
+#define QUSB2_V2_HSTX_TRIM_23_4_MA 0x1
+#define QUSB2_V2_HSTX_TRIM_22_8_MA 0x2
+#define QUSB2_V2_HSTX_TRIM_22_2_MA 0x3
+#define QUSB2_V2_HSTX_TRIM_21_6_MA 0x4
+#define QUSB2_V2_HSTX_TRIM_21_0_MA 0x5
+#define QUSB2_V2_HSTX_TRIM_20_4_MA 0x6
+#define QUSB2_V2_HSTX_TRIM_19_8_MA 0x7
+#define QUSB2_V2_HSTX_TRIM_19_2_MA 0x8
+#define QUSB2_V2_HSTX_TRIM_18_6_MA 0x9
+#define QUSB2_V2_HSTX_TRIM_18_0_MA 0xa
+#define QUSB2_V2_HSTX_TRIM_17_4_MA 0xb
+#define QUSB2_V2_HSTX_TRIM_16_8_MA 0xc
+#define QUSB2_V2_HSTX_TRIM_16_2_MA 0xd
+#define QUSB2_V2_HSTX_TRIM_15_6_MA 0xe
+#define QUSB2_V2_HSTX_TRIM_15_0_MA 0xf
+
+/* PHY PREEMPHASIS bit values */
+#define QUSB2_V2_PREEMPHASIS_NONE  0
+#define QUSB2_V2_PREEMPHASIS_5_PERCENT 1
+#define QUSB2_V2_PREEMPHASIS_10_PERCENT2
+#define QUSB2_V2_PREEMPHASIS_15_PERCENT3
+
+/* PHY PREEMPHASIS-WIDTH bit values */
+#define QUSB2_V2_PREEMPHASIS_WIDTH_FULL_BIT0
+#define QUSB2_V2_PREEMPHASIS_WIDTH_HALF_BIT1
+
+#endif
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v5 0/7] phy: qcom: Updates for USB PHYs on SDM845

2018-05-02 Thread Manu Gautam
SDM845 has two USB instances each with QUSB2 and QMP PHYs.
One of the QMP PHY is USB-DP (DisplayPort) combo PHY where
as other one is single lane UNI-PHY (without DP support).
Changes are related to PHY configuration for electrical
parameters tuning to improve eye-diagram and some fixes.

First gcc-msm8996 driver patch is dependent on following
patch which is now applied by Stephen.
https://patchwork.kernel.org/patch/10375043/


Changes since v4:
 - Addressed Doug's review comments to have QUSB2 PHY tuning
   values in header file.
 - Updated msm8996-gcc patch to use BRANCH_HALT_SKIP flag
   added by patch - https://patchwork.kernel.org/patch/10375041/
   
Changes since v3:
 - As per Doug's review comments added device tree parameters
   to handle board level differences in PHY tuning values instead
   of adding separate device tree bindings.
 - Replace PHY version specific bindings names with SOC name as
   no one is going to use generic binding names.
 - Update halt_check to not check for pipe clock status that
   allows to simplify pipe_clk handling in QMP driver.

Changes since v2:
 - Use separate phy_ops for USB to not register power_on op.
 - And other minor changes as per review comments from Stephen.

Changes since v1:
 - Updated qusb2 compatibility name as per comment from Vivek.

Manu Gautam (7):
  clk: msm8996-gcc: Mark halt check as no-op for USB/PCIE pipe_clk
  phy: qcom-qmp: Enable pipe_clk before PHY initialization
  phy: qcom-qusb2: Fix crash if nvmem cell not specified
  dt-bindings: phy-qcom-qmp: Update bindings for sdm845
  phy: qcom-qmp: Add QMP V3 USB3 UNI PHY support for sdm845
  dt-bindings: phy-qcom-usb2: Add support to override tuning values
  phy: qcom-qusb2: Add QUSB2 PHYs support for sdm845

 .../devicetree/bindings/phy/qcom-qmp-phy.txt   |   3 +-
 .../devicetree/bindings/phy/qcom-qusb2-phy.txt |  23 ++-
 drivers/clk/qcom/gcc-msm8996.c |   4 +
 drivers/phy/qualcomm/phy-qcom-qmp.c| 169 +++--
 drivers/phy/qualcomm/phy-qcom-qmp.h|   5 +
 drivers/phy/qualcomm/phy-qcom-qusb2.c  | 130 +++-
 include/dt-bindings/phy/phy-qcom-qusb2.h   |  37 +
 7 files changed, 346 insertions(+), 25 deletions(-)
 create mode 100644 include/dt-bindings/phy/phy-qcom-qusb2.h

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v5 0/7] phy: qcom: Updates for USB PHYs on SDM845

2018-05-02 Thread Manu Gautam
SDM845 has two USB instances each with QUSB2 and QMP PHYs.
One of the QMP PHY is USB-DP (DisplayPort) combo PHY where
as other one is single lane UNI-PHY (without DP support).
Changes are related to PHY configuration for electrical
parameters tuning to improve eye-diagram and some fixes.

First gcc-msm8996 driver patch is dependent on following
patch which is now applied by Stephen.
https://patchwork.kernel.org/patch/10375043/


Changes since v4:
 - Addressed Doug's review comments to have QUSB2 PHY tuning
   values in header file.
 - Updated msm8996-gcc patch to use BRANCH_HALT_SKIP flag
   added by patch - https://patchwork.kernel.org/patch/10375041/
   
Changes since v3:
 - As per Doug's review comments added device tree parameters
   to handle board level differences in PHY tuning values instead
   of adding separate device tree bindings.
 - Replace PHY version specific bindings names with SOC name as
   no one is going to use generic binding names.
 - Update halt_check to not check for pipe clock status that
   allows to simplify pipe_clk handling in QMP driver.

Changes since v2:
 - Use separate phy_ops for USB to not register power_on op.
 - And other minor changes as per review comments from Stephen.

Changes since v1:
 - Updated qusb2 compatibility name as per comment from Vivek.

Manu Gautam (7):
  clk: msm8996-gcc: Mark halt check as no-op for USB/PCIE pipe_clk
  phy: qcom-qmp: Enable pipe_clk before PHY initialization
  phy: qcom-qusb2: Fix crash if nvmem cell not specified
  dt-bindings: phy-qcom-qmp: Update bindings for sdm845
  phy: qcom-qmp: Add QMP V3 USB3 UNI PHY support for sdm845
  dt-bindings: phy-qcom-usb2: Add support to override tuning values
  phy: qcom-qusb2: Add QUSB2 PHYs support for sdm845

 .../devicetree/bindings/phy/qcom-qmp-phy.txt   |   3 +-
 .../devicetree/bindings/phy/qcom-qusb2-phy.txt |  23 ++-
 drivers/clk/qcom/gcc-msm8996.c |   4 +
 drivers/phy/qualcomm/phy-qcom-qmp.c| 169 +++--
 drivers/phy/qualcomm/phy-qcom-qmp.h|   5 +
 drivers/phy/qualcomm/phy-qcom-qusb2.c  | 130 +++-
 include/dt-bindings/phy/phy-qcom-qusb2.h   |  37 +
 7 files changed, 346 insertions(+), 25 deletions(-)
 create mode 100644 include/dt-bindings/phy/phy-qcom-qusb2.h

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v2 0/2] usb: dwc3: support clocks and resets for DWC3 core

2018-04-23 Thread Manu Gautam
HI,


On 4/19/2018 4:03 AM, Masahiro Yamada wrote:
> In the current design of DWC3 driver,
> the DT typically becomes a nested structure like follows:
>
>   dwc3-glue {
>   compatible = "foo,dwc3";
>   ...
>
>   dwc3 {
>   compatible = "snps,dwc3";
>   ...
>   };
>   }
>
> The current DWC3 core (drivers/usb/dwc3/core.c) can not handle
> clocks / resets at all.
>
> The only solution we have now, is to put DWC3 core node under
> the glue layer node, then add clocks and resets there.
> Actually, dwc3-of-simple.c exists to handle clocks and resets.
>
> As always for digital circuits, DWC3 core IP itself needs clock input.
> This is specific to this IP.  So, supporting clocks and resets in
> dwc3/core.c makes sense.

Why can't dwc3-of-simple be used with this IP?
Adding core/reset handling in both core and glue drivers might
only add to confusion and I cant think of a reason why having a parent
node representing dwc3-of-simple glue would be any concern.
Or are you planning to remove dwc3-of-simple.c driver?

>
> In this version, the number of clocks (and names) is specific
> to this IP, with clock names taken from Synopsys datasheet.

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v3 3/3] clk: qcom: Add Global Clock controller (GCC) driver for SDM845

2018-04-18 Thread Manu Gautam
Hi Amit,


On 4/18/2018 6:33 PM, Amit Nischal wrote:
>>> +   /* Disable the GPLL0 active input to MMSS and GPU via MISC 
>>> registers */
>>> +   regmap_update_bits(regmap, 0x09ffc, 0x3, 0x3);
>>> +   regmap_update_bits(regmap, 0x71028, 0x3, 0x3);
>>
>> I think we'll have to throw in the pipe clk branch stuff in here too?
>> And then drop the pipe clks from the driver?
>
> All the USB pipe clocks would be taken care. The PCIE pipe branch
> clocks would have to be explicitly disabled so as to retain the
> memory logic. Otherwise, it would lead to memory corruption in case
> the external source is directly disabled without disabling the branch clock. 

PHY driver is same for both USB and PCIE and both PHYs use pipe_clk.
If there is indeed some limitation and pipe_clk cant be left enabled
always then I will suggest to not change pipe_clk handling for USB as well.

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v2 1/3] dt-bindings: usb: Update documentation for Qualcomm DWC3 driver

2018-04-16 Thread Manu Gautam
Hi Rob,


On 4/17/2018 2:08 AM, Rob Herring wrote:
> On Fri, Apr 13, 2018 at 10:21:22PM +0530, Manu Gautam wrote:
>> Existing documentation has lot of incorrect information as it
>> was originally added for a driver that no longer exists.
>>
>> Signed-off-by: Manu Gautam 
>> ---
>>  .../devicetree/bindings/usb/qcom,dwc3.txt  | 78 
>> --
>>  1 file changed, 57 insertions(+), 21 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/usb/qcom,dwc3.txt 
>> b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
>> index bc8a2fa..fdc574a 100644
>> --- a/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
>> +++ b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
>> @@ -1,54 +1,90 @@
>>  Qualcomm SuperSpeed DWC3 USB SoC controller
>>  
>>  Required properties:
>> -- compatible:   should contain "qcom,dwc3"
>> +- compatible:   should contain "qcom,dwc3"
> Needs an SoC specific compatible string.

Thanks for review.
Sure. Will add that.

>
>> +- reg:  offset and length of register set for QSCRATCH 
>> wrapper
>> +- power-domains:specifies a phandle to PM domain provider node
>>  - clocks:   A list of phandle + clock-specifier pairs for the
>>  clocks listed in clock-names
>> -- clock-names:  Should contain the following:
>> +- clock-names:  Should contain the following:
>>"core"Master/Core clock, have to be >= 125 MHz for SS
>>  operation and >= 60MHz for HS operation
>> +  "mock_utmi"   Mock utmi clock needed for ITP/SOF generation in
>> +host mode. Its frequency should be 19.2MHz.
>> +  "sleep"   Sleep clock, used for wakeup when USB3 core goes
>> +into low power mode (U3).
>>  
>>  Optional clocks:
>>"iface"   System bus AXI clock.  Not present on all platforms
>> -  "sleep"   Sleep clock, used when USB3 core goes into low
>> -power mode (U3).
>> +  "cfg_noc" System Config NOC clock. Not present on all platforms
> These need to be specific as to which compatible properties have or 
> don't have these clocks.
ok

>
>> +- assigned-clocks:  should be:
>> +MOCK_UTMI_CLK
>> +MASTER_CLK
>> +- assigned-clock-rates: should be:
>> +19.2Mhz (19200) for MOCK_UTMI_CLK
>> +>=125Mhz (12500) for MASTER_CLK in SS 
>> mode
>> +>=60Mhz (6000) for MASTER_CLK in HS mode
>> +
>> +Optional properties:
>> +- resets:   list of phandle and reset specifier pairs
> How many?
I will provide exact detail for each compatible property.
>
>> +- interrupts:   specifies interrupts from controller wrapper 
>> used
>> +to wakeup from low power/susepnd state. Must contain
>> +one or more entry for interrupt-names property
>> +- interrupt-names:  Must include the following entries:
>> +- "hs_phy_irq": The interrupt that is asserted when a
>> +   wakeup event is received on USB2 bus
>> +- "ss_phy_irq": The interrupt that is asserted when a
>> +   wakeup event is received on USB3 bus
>> +- "dm_hs_phy_irq" and "dp_hs_phy_irq": Separate
>> +   interrupts for any wakeup event on DM and DP lines
> Sounds like the irqs are actually part of the PHYs? If so, then that's 
> where they should be in the DT.
No. These are actually part of controller wrapper called - qscratch which
has connectivity to phy outputs signals. Also, these are abstracted from PHY
and are present irrespective of type of phy present. I will add soc specific
info also in comments specifying which interrupts are not present on particular
soc/compatible.

>
>> +- qcom,select-utmi-as-pipe-clk: if present, disable USB3 pipe_clk 
>> requirement.
>> +Used when dwc3 operates without SSPHY and only
>> +HS/FS/LS modes are supported.
>>  
>>  Required child node:
>>  A child node must exist to represent the core DWC3 IP block. The name of
>>  the node is not important. The content of the node is defined in dwc3.txt.
>> 

Re: [PATCH v4 6/7] dt-bindings: phy-qcom-usb2: Add support to override tuning values

2018-04-15 Thread Manu Gautam
Hi,


On 4/13/2018 2:17 AM, Doug Anderson wrote:
>> Thanks for review Rob. I too agree with both the viewpoints.
>> Doug, if it is not of much concern then can I stick with current approach?
> I certainly would appreciate the #defines and believe they add to the
> readability, but if you're dead set against it and Rob says it's OK, I
> won't yell too loudly.
>
Agree to the readability part. Will add #defines as you suggested.
-thanks

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v2] phy: core: Allow phy_pm_runtime_xxx API calls with NULL phy

2018-04-15 Thread Manu Gautam
Hi Kishon,


On 3/20/2018 11:31 AM, Manu Gautam wrote:
> phy_init() and phy_exit() calls, and phy_power_on() and
> phy_power_off() already accept NULL as valid PHY reference
> and act as NOP. Extend same concept to phy runtime_pm APIs
> to keep drivers (e.g. dwc3) code simple while dealing with
> optional PHYs.

Wondering if you had a chance to review this.

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v2 2/3] usb: dwc3: Add Qualcomm DWC3 glue driver

2018-04-13 Thread Manu Gautam
Hi Jack,


On 4/13/2018 11:03 PM, Jack Pham wrote:
> Hi Manu,
>
> On Fri, Apr 13, 2018 at 10:21:23PM +0530, Manu Gautam wrote:
>> DWC3 controller on Qualcomm SOCs has a Qscratch wrapper.
>> Some of its uses are described below resulting in need to
>> have a separate glue driver instead of using dwc3-of-simple:
>>  - It exposes register interface to override vbus-override
>>and lane0-pwr-present signals going to hardware. These
>>must be updated in peripheral mode for DWC3 if vbus lines
>>are not connected to hardware block. Otherwise RX termination
>>in SS mode or DP pull-up is not applied by device controller.
>>  - pwr_events_irq_stat support to check if USB2 PHY is in L2 state
>>before glue driver proceeds with suspend.
>>  - Support for wakeup interrupts lines that are asserted whenever
>>there is any wakeup event on USB3 or USB2 bus.
>>  - Support to replace pip3 clock going to DWC3 with utmi clock
>>for hardware configuration where SSPHY is not used with DWC3.
>>
>> Signed-off-by: Manu Gautam 
> 
>
>> +static int dwc3_qcom_register_extcon(struct dwc3_qcom *qcom)
>> +{
>> +struct device   *dev = qcom->dev;
>> +struct extcon_dev   *host_edev;
>> +int ret;
>> +
>> +if (!of_property_read_bool(dev->of_node, "extcon"))
>> +return 0;
>> +
>> +qcom->edev = extcon_get_edev_by_phandle(dev, 0);
> Are the extcon phandles bound to the glue node? I don't see the
> description in the bindings doc in PATCH 1/3. And if so, would it be
> a duplicate of the child node's extcon binding? Then again, the
> alternative would be to grab it directly from the child (i.e.
> qcom->dwc3->dev.of_node) which I'm not sure is ok to do or not.
>

Yes these are bound to glue node. I missed to add it to documentation, will do
so.
I kept it separate for couple of reasons - one is to not peek too-much into 
child
node. Another reason is that doing so allows to have extcon in "peripheral"
only mode as well (not just drd mode which is the case with dwc3 core).
It allows to notify h/w when vbus is not there in device mode which IMO is
right thing to do.



-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v2 3/3] usb: dwc3: core: Suspend PHYs on runtime suspend in host mode

2018-04-13 Thread Manu Gautam
Some PHY drivers (e.g. for Qualcomm QUSB2 and QMP PHYs) support
runtime PM to reduce PHY power consumption during bus_suspend.
Add changes to let core auto-suspend PHYs on host bus-suspend
using GUSB2PHYCFG register if needed for a platform. Also perform
PHYs runtime suspend/resume and let platform glue drivers e.g.
dwc3-qcom handle remote wakeup during bus suspend by waking up
devices on receiving wakeup event from PHY.

Signed-off-by: Manu Gautam 
---
 drivers/usb/dwc3/core.c | 36 +---
 1 file changed, 33 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index a15648d..449a098 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -1394,6 +1394,7 @@ static int dwc3_remove(struct platform_device *pdev)
 static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg)
 {
unsigned long   flags;
+   u32 reg;
 
switch (dwc->current_dr_role) {
case DWC3_GCTL_PRTCAP_DEVICE:
@@ -1403,9 +1404,25 @@ static int dwc3_suspend_common(struct dwc3 *dwc, 
pm_message_t msg)
dwc3_core_exit(dwc);
break;
case DWC3_GCTL_PRTCAP_HOST:
-   /* do nothing during host runtime_suspend */
-   if (!PMSG_IS_AUTO(msg))
+   if (!PMSG_IS_AUTO(msg)) {
dwc3_core_exit(dwc);
+   break;
+   }
+
+   /* Let controller to suspend HSPHY before PHY driver suspends */
+   if (dwc->dis_u2_susphy_quirk ||
+   dwc->dis_enblslpm_quirk) {
+   reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+   reg |=  DWC3_GUSB2PHYCFG_ENBLSLPM |
+   DWC3_GUSB2PHYCFG_SUSPHY;
+   dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+
+   /* Give some time for USB2 PHY to suspend */
+   usleep_range(5000, 6000);
+   }
+
+   phy_pm_runtime_put_sync(dwc->usb2_generic_phy);
+   phy_pm_runtime_put_sync(dwc->usb3_generic_phy);
break;
case DWC3_GCTL_PRTCAP_OTG:
/* do nothing during runtime_suspend */
@@ -1433,6 +1450,7 @@ static int dwc3_resume_common(struct dwc3 *dwc, 
pm_message_t msg)
 {
unsigned long   flags;
int ret;
+   u32 reg;
 
switch (dwc->current_dr_role) {
case DWC3_GCTL_PRTCAP_DEVICE:
@@ -1446,13 +1464,25 @@ static int dwc3_resume_common(struct dwc3 *dwc, 
pm_message_t msg)
spin_unlock_irqrestore(&dwc->lock, flags);
break;
case DWC3_GCTL_PRTCAP_HOST:
-   /* nothing to do on host runtime_resume */
if (!PMSG_IS_AUTO(msg)) {
ret = dwc3_core_init(dwc);
if (ret)
return ret;
dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST);
+   break;
}
+   /* Restore GUSB2PHYCFG bits that were modified in suspend */
+   reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+   if (dwc->dis_u2_susphy_quirk)
+   reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
+
+   if (dwc->dis_enblslpm_quirk)
+   reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
+
+   dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+
+   phy_pm_runtime_get_sync(dwc->usb2_generic_phy);
+   phy_pm_runtime_get_sync(dwc->usb3_generic_phy);
break;
case DWC3_GCTL_PRTCAP_OTG:
/* nothing to do on runtime_resume */
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v2 2/3] usb: dwc3: Add Qualcomm DWC3 glue driver

2018-04-13 Thread Manu Gautam
DWC3 controller on Qualcomm SOCs has a Qscratch wrapper.
Some of its uses are described below resulting in need to
have a separate glue driver instead of using dwc3-of-simple:
 - It exposes register interface to override vbus-override
   and lane0-pwr-present signals going to hardware. These
   must be updated in peripheral mode for DWC3 if vbus lines
   are not connected to hardware block. Otherwise RX termination
   in SS mode or DP pull-up is not applied by device controller.
 - pwr_events_irq_stat support to check if USB2 PHY is in L2 state
   before glue driver proceeds with suspend.
 - Support for wakeup interrupts lines that are asserted whenever
   there is any wakeup event on USB3 or USB2 bus.
 - Support to replace pip3 clock going to DWC3 with utmi clock
   for hardware configuration where SSPHY is not used with DWC3.

Signed-off-by: Manu Gautam 
---
 drivers/usb/dwc3/Kconfig  |  12 +
 drivers/usb/dwc3/Makefile |   1 +
 drivers/usb/dwc3/dwc3-of-simple.c |   1 -
 drivers/usb/dwc3/dwc3-qcom.c  | 618 ++
 4 files changed, 631 insertions(+), 1 deletion(-)
 create mode 100644 drivers/usb/dwc3/dwc3-qcom.c

diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index ab8c0e0..451012e 100644
--- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig
@@ -106,4 +106,16 @@ config USB_DWC3_ST
  inside (i.e. STiH407).
  Say 'Y' or 'M' if you have one such device.
 
+config USB_DWC3_QCOM
+   tristate "Qualcomm Platform"
+   depends on ARCH_QCOM || COMPILE_TEST
+   depends on OF
+   default USB_DWC3
+   help
+ Some Qualcomm SoCs use DesignWare Core IP for USB2/3
+ functionality.
+ This driver also handles Qscratch wrapper which is needed
+ for peripheral mode support.
+ Say 'Y' or 'M' if you have one such device.
+
 endif
diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
index 025bc68..5c07d8f 100644
--- a/drivers/usb/dwc3/Makefile
+++ b/drivers/usb/dwc3/Makefile
@@ -48,3 +48,4 @@ obj-$(CONFIG_USB_DWC3_PCI)+= dwc3-pci.o
 obj-$(CONFIG_USB_DWC3_KEYSTONE)+= dwc3-keystone.o
 obj-$(CONFIG_USB_DWC3_OF_SIMPLE)   += dwc3-of-simple.o
 obj-$(CONFIG_USB_DWC3_ST)  += dwc3-st.o
+obj-$(CONFIG_USB_DWC3_QCOM)+= dwc3-qcom.o
diff --git a/drivers/usb/dwc3/dwc3-of-simple.c 
b/drivers/usb/dwc3/dwc3-of-simple.c
index cb2ee96..0fd0e8e 100644
--- a/drivers/usb/dwc3/dwc3-of-simple.c
+++ b/drivers/usb/dwc3/dwc3-of-simple.c
@@ -208,7 +208,6 @@ static int dwc3_of_simple_runtime_resume(struct device *dev)
 };
 
 static const struct of_device_id of_dwc3_simple_match[] = {
-   { .compatible = "qcom,dwc3" },
{ .compatible = "rockchip,rk3399-dwc3" },
{ .compatible = "xlnx,zynqmp-dwc3" },
{ .compatible = "cavium,octeon-7130-usb-uctl" },
diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c
new file mode 100644
index 000..ecb2218
--- /dev/null
+++ b/drivers/usb/dwc3/dwc3-qcom.c
@@ -0,0 +1,618 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * Inspired by dwc3-of-simple.c
+ */
+#define DEBUG
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "core.h"
+
+/* USB QSCRATCH Hardware registers */
+#define QSCRATCH_HS_PHY_CTRL   0x10
+#define UTMI_OTG_VBUS_VALIDBIT(20)
+#define SW_SESSVLD_SEL BIT(28)
+
+#define QSCRATCH_SS_PHY_CTRL   0x30
+#define LANE0_PWR_PRESENT  BIT(24)
+
+#define QSCRATCH_GENERAL_CFG   0x08
+#define PIPE_UTMI_CLK_SEL  BIT(0)
+#define PIPE3_PHYSTATUS_SW BIT(3)
+#define PIPE_UTMI_CLK_DIS  BIT(8)
+
+#define PWR_EVNT_IRQ_STAT_REG  0x58
+#define PWR_EVNT_LPM_IN_L2_MASKBIT(4)
+#define PWR_EVNT_LPM_OUT_L2_MASK   BIT(5)
+
+struct dwc3_qcom {
+   struct device   *dev;
+   void __iomem*qscratch_base;
+   struct platform_device  *dwc3;
+   struct clk  **clks;
+   int num_clocks;
+   struct reset_control*resets;
+
+   int hs_phy_irq;
+   int dp_hs_phy_irq;
+   int dm_hs_phy_irq;
+   int ss_phy_irq;
+
+   struct extcon_dev   *edev;
+   struct extcon_dev   *host_edev;
+   struct notifier_block   vbus_nb;
+   struct notifier_block   host_nb;
+
+   enum usb_dr_modemode;
+   boolis_suspended;
+   boolpm_suspended;
+};
+
+static inli

[PATCH v2 1/3] dt-bindings: usb: Update documentation for Qualcomm DWC3 driver

2018-04-13 Thread Manu Gautam
Existing documentation has lot of incorrect information as it
was originally added for a driver that no longer exists.

Signed-off-by: Manu Gautam 
---
 .../devicetree/bindings/usb/qcom,dwc3.txt  | 78 --
 1 file changed, 57 insertions(+), 21 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/qcom,dwc3.txt 
b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
index bc8a2fa..fdc574a 100644
--- a/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
+++ b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
@@ -1,54 +1,90 @@
 Qualcomm SuperSpeed DWC3 USB SoC controller
 
 Required properties:
-- compatible:  should contain "qcom,dwc3"
+- compatible:  should contain "qcom,dwc3"
+- reg: offset and length of register set for QSCRATCH wrapper
+- power-domains:   specifies a phandle to PM domain provider node
 - clocks:  A list of phandle + clock-specifier pairs for the
clocks listed in clock-names
-- clock-names: Should contain the following:
+- clock-names: Should contain the following:
   "core"   Master/Core clock, have to be >= 125 MHz for SS
operation and >= 60MHz for HS operation
+  "mock_utmi"  Mock utmi clock needed for ITP/SOF generation in
+   host mode. Its frequency should be 19.2MHz.
+  "sleep"  Sleep clock, used for wakeup when USB3 core goes
+   into low power mode (U3).
 
 Optional clocks:
   "iface"  System bus AXI clock.  Not present on all platforms
-  "sleep"  Sleep clock, used when USB3 core goes into low
-   power mode (U3).
+  "cfg_noc"System Config NOC clock. Not present on all platforms
+- assigned-clocks: should be:
+   MOCK_UTMI_CLK
+   MASTER_CLK
+- assigned-clock-rates: should be:
+19.2Mhz (19200) for MOCK_UTMI_CLK
+>=125Mhz (12500) for MASTER_CLK in SS mode
+>=60Mhz (6000) for MASTER_CLK in HS mode
+
+Optional properties:
+- resets:  list of phandle and reset specifier pairs
+- interrupts:  specifies interrupts from controller wrapper used
+   to wakeup from low power/susepnd state. Must contain
+   one or more entry for interrupt-names property
+- interrupt-names: Must include the following entries:
+   - "hs_phy_irq": The interrupt that is asserted when a
+  wakeup event is received on USB2 bus
+   - "ss_phy_irq": The interrupt that is asserted when a
+  wakeup event is received on USB3 bus
+   - "dm_hs_phy_irq" and "dp_hs_phy_irq": Separate
+  interrupts for any wakeup event on DM and DP lines
+- qcom,select-utmi-as-pipe-clk: if present, disable USB3 pipe_clk requirement.
+   Used when dwc3 operates without SSPHY and only
+   HS/FS/LS modes are supported.
 
 Required child node:
 A child node must exist to represent the core DWC3 IP block. The name of
 the node is not important. The content of the node is defined in dwc3.txt.
 
 Phy documentation is provided in the following places:
-Documentation/devicetree/bindings/phy/qcom-dwc3-usb-phy.txt
+Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt   - USB3 QMP PHY
+Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt - USB2 QUSB2 PHY
 
 Example device nodes:
 
hs_phy: phy@100f8800 {
-   compatible = "qcom,dwc3-hs-usb-phy";
-   reg = <0x100f8800 0x30>;
-   clocks = <&gcc USB30_0_UTMI_CLK>;
-   clock-names = "ref";
-   #phy-cells = <0>;
-
+   compatible = "qcom,qusb2-v2-phy";
+   ...
};
 
ss_phy: phy@100f8830 {
-   compatible = "qcom,dwc3-ss-usb-phy";
-   reg = <0x100f8830 0x30>;
-   clocks = <&gcc USB30_0_MASTER_CLK>;
-   clock-names = "ref";
-   #phy-cells = <0>;
-
+   compatible = "qcom,qmp-v3-usb3-phy";
+   ...
};
 
-   usb3_0: usb30@0 {
+   usb3_0: usb30@a6f8800 {
compatible = "qcom,dwc3";
+   reg = <0xa6f8800 0x400>;
#address-cells = <

[PATCH v2 0/3] usb: dwc3: support for Qualcomm DWC3 glue

2018-04-13 Thread Manu Gautam
Add separate dwc3-qcom glue driver for Qualcomm SOCs having dwc3 core.
It is needed to support peripheral mode.
Patches also add support to invoke PHY runtime PM functions on host
mode bus-suspend.

Changes since v1:
 - Move dwc3 core register accesses from glue driver to dwc3 core as
   per review comment from Felipe.
 - Addressed other review comments from Felipe and Rob.
 - Some other minor code changes related to redability.
 - Add reset_control assert in driver probe to ensure core registers
   are reset to POR value in case of any initalization by boot code. 

Manu Gautam (3):
  dt-bindings: usb: Update documentation for Qualcomm DWC3 driver
  usb: dwc3: Add Qualcomm DWC3 glue driver
  usb: dwc3: core: Suspend PHYs on runtime suspend in host mode

 .../devicetree/bindings/usb/qcom,dwc3.txt  |  78 ++-
 drivers/usb/dwc3/Kconfig   |  12 +
 drivers/usb/dwc3/Makefile  |   1 +
 drivers/usb/dwc3/core.c|  36 +-
 drivers/usb/dwc3/dwc3-of-simple.c  |   1 -
 drivers/usb/dwc3/dwc3-qcom.c   | 618 +
 6 files changed, 721 insertions(+), 25 deletions(-)
 create mode 100644 drivers/usb/dwc3/dwc3-qcom.c

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v4 2/7] phy: qcom-qmp: Enable pipe_clk before PHY initialization

2018-04-13 Thread Manu Gautam
Hi,


On 4/13/2018 2:08 AM, Stephen Boyd wrote:
> Quoting Manu Gautam (2018-04-11 08:37:38)
>>> I ask because it may be easier to never expose these clks in Linux, hit
>>> the enable bits in the branches during clk driver probe, and then act
>>> like they never exist because we don't really use them.
>> This sounds better idea. Let me check if I can get a patch for same in 
>> msm8996
>> and sdm845 clock drivers.
>>
> Ok! Presumably the PHY has a way to tell if it failed to turn on right?
> Put another way, I'm hoping these branch bits aren't there to help us
> debug and figure out when the PHY PLL fails to lock.

Yes, PHY has a PCS_STATUS3 register that indicates whether pipe_clk got enabled 
or
not.


-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v4 2/7] phy: qcom-qmp: Enable pipe_clk before PHY initialization

2018-04-11 Thread Manu Gautam
Hi,


On 4/11/2018 12:02 AM, Stephen Boyd wrote:
> Quoting Doug Anderson (2018-04-10 08:05:27)
>> On Mon, Apr 9, 2018 at 11:36 PM, Manu Gautam  wrote:
>>> On 3/30/2018 2:24 AM, Doug Anderson wrote:
>>>> Oh!  This is what you did in the previous version of the patch, then you 
>>>> said:
>>>>
>>>> "That is still needed as PHY might take some time to generate pipe_clk
>>>> after its PLL is locked".
>>>>
>>>> It's really going to take more than the 200 us that the clock driver
>>>> is giving it?  If so, I'd prefer to increase the amount of time waited
>>>> in the clock driver, or adding a fixed delay _before_ the clk_enable()
>>>> so that the 200 us that the clock driver gives it would be enough.
>>>>
>>>> I'm just not a fan of ignoring status bits if it can be helped.
>>> I too would want to do that but it is not just about the delay.
>>> As per QMP PHY hardware designers, pipe_clk should be enabled in GCC
>>> as first thing in the PHY initialization sequence. Same sequence also has
>>> been used in downstream phy driver always.
>>> Changing the sequence might work but I would like to stick to the HPG
>>> recommendation and avoid any deviation as PHY issues are very hard to
>>> debug.
>> So hardware guys tell you that you're _supposed to_ ignore the clock
>> ready bit for that clock and just hope it turns on and settles in time
>> once power comes on for the clock?  That doesn't seem ideal.  My guess
>> is that it's a bug in the specification that the QMP PHY hardware
>> designers gave you.
It could be a bug in specification. But same sequence has been well tested on 
both
msm8996 and sdm845, so I would for now like to stick with that for now.
>> Stephen can feel free to override me if he disagrees since he's in
>> charge of the clock part of this, but IMHO we should get the
>> specification fixed and turn things on in the order that lets us check
>> the status bits.
>>
> Presumably there's a PLL "enable" bit in the QMP phy init sequence that
> we can use to enable the PLL output at a bypass rate and then enable the
> clk in GCC and then resume the PLL enable sequence. That would allow us
> to make sure the clk is working.
>
> Are the branches in GCC ever turned on or off at runtime though? Or do
> we just turn them on because they're defaulted off out of reset and then
> leave them on?
It can be left on always.
>
> I ask because it may be easier to never expose these clks in Linux, hit
> the enable bits in the branches during clk driver probe, and then act
> like they never exist because we don't really use them.
This sounds better idea. Let me check if I can get a patch for same in msm8996
and sdm845 clock drivers.


-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v4 6/7] dt-bindings: phy-qcom-usb2: Add support to override tuning values

2018-04-10 Thread Manu Gautam


On 4/10/2018 1:48 AM, Rob Herring wrote:
> On Thu, Mar 29, 2018 at 01:38:23PM -0700, Doug Anderson wrote:
>> Hi,
>>
>> On Thu, Mar 29, 2018 at 4:04 AM, Manu Gautam  wrote:
>>> To improve eye diagram for PHYs on different boards of same SOC,
>>> some parameters may need to be changed. Provide device tree
>>> properties to override these from board specific device tree
>>> files. While at it, replace "qcom,qusb2-v2-phy" with compatible
>>> string for USB2 PHY on sdm845 which was earlier added for
>>> sdm845 only.
>>>
>>> Signed-off-by: Manu Gautam 
>>> ---
>>>  .../devicetree/bindings/phy/qcom-qusb2-phy.txt| 19 
>>> ++-
>>>  1 file changed, 18 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt 
>>> b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
>>> index 42c9742..0ed140a 100644
>>> --- a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
>>> +++ b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
>>> @@ -6,7 +6,7 @@ QUSB2 controller supports LS/FS/HS usb connectivity on 
>>> Qualcomm chipsets.
>>>  Required properties:
>>>   - compatible: compatible list, contains
>>>"qcom,msm8996-qusb2-phy" for 14nm PHY on msm8996,
>>> -  "qcom,qusb2-v2-phy" for QUSB2 V2 PHY.
>>> +  "qcom,sdm845-qusb2-phy" for 10nm PHY on sdm845.
>>>
>>>   - reg: offset and length of the PHY register set.
>>>   - #phy-cells: must be 0.
>>> @@ -27,6 +27,23 @@ Optional properties:
>>> tuning parameter value for qusb2 phy.
>>>
>>>   - qcom,tcsr-syscon: Phandle to TCSR syscon register region.
>> Just to confirm: the new properties below work just fine on the old
>> msm8996 PHY too, right?
No it won't as register layouts and bit fields are different. Also IMP_CTRL
register doesnt exist for msm8996. I will mention that explicitly here.

>>
>>
>>> + - qcom,imp-res-offset-value: It is a 6 bit value that specifies offset to 
>>> be
>>> +   added to PHY refgen RESCODE via IMP_CTRL1 register. It is a 
>>> PHY
>>> +   tuning paramter that may vary for different boards of same 
>>> SOC.
>>> + - qcom,hstx-trim-value: It is a 4 bit value that specifies tuning for HSTX
>>> +   output current. 0x0 value corresponding to 24mA which is 
>>> maximum
>>> +   current and 0xf corresponds to lowest current which is 15mA.
>>> + - qcom,preemphasis-level: It is a 2 bit value that specifies pre-emphasis 
>>> level.
>>> +   Possible values are:
>>> +   00: NONE
>>> +   01: +5%
>>> +   10: +10%
>>> +   11: +15%
>> The user of the device tree will expect to specify this in decimal,
>> right?  So list the above as 0, 1, 2, 3.  ...not 00, 01, 10, 11.
Fine.
>> (though below I suggest that specifying 0, 1, 2, 3 is probably not
>> quite the right way to describe this property).
>>
>>
>>> +- qcom,preemphasis-width: It is a 1 bit value that specifies how long the 
>>> HSTX
>>> +   pre-emphasis (specified using qcom,preemphasis-level) must 
>>> be in
>>> +   effect. Possible values are:
>>> +   0: Full-bit width
>>> +   1: Half-bit width
>> Perhaps just make this a boolean property.  If it exists then you get
>> the non-default case.  AKA: if the default is full bit width, then
>> you'd allow a boolean property "qcom,preemphasis-half-width" to
>> override.  If the default is half bit width then you'd allow
>> "qcom,preemphasis-full-width" to override.

Default property value for an SOC is specified in driver and could vary from
soc to soc. Hence, from board devicetree for different SOCs we might need
to select separate widths overriding default driver values.
Alternative is to have two bool properties each for half and full-width. Did
you actually mean that?

>>
>>
>> For all the above optional bits, please indicate what the default is
>> if they aren't specified.  If you have to specify a different default
>> for sdm845 vs. msm8996 then so be it (though it would be nice to avoid
>> it by changing the default for sdm845 unless that's totally crazy).
Sure.
>>
>>
>> Overall this looks pretty good to me.  Certainly the descrip

Re: [PATCH v4 7/7] phy: qcom-qusb2: Add QUSB2 PHYs support for sdm845

2018-04-09 Thread Manu Gautam
Hi,


On 3/30/2018 2:08 AM, Doug Anderson wrote:
> Hi,
>
> On Thu, Mar 29, 2018 at 4:04 AM, Manu Gautam  wrote:
>> @@ -241,6 +252,18 @@ struct qusb2_phy_cfg {
>>   * @tcsr: TCSR syscon register map
>>   * @cell: nvmem cell containing phy tuning value
>>   *
>> + * @override_imp_res_offset: PHY should use different rescode offset
>> + * @imp_res_offset_value: rescode offset to be updated in IMP_CTRL1 register
>> + *
>> + * @override_hstx_trim: PHY should use different HSTX o/p current value
>> + * @hstx_trim_value: HSTX_TRIM value to be updated in TUNE1 register
>> + *
>> + * @override_preemphasis: PHY should use different pre-amphasis amplitude
>> + * @preemphasis_level: Amplitude Pre-Emphasis to be updated in TUNE1 
>> register
>> + *
>> + * @override_preemphasis_width: PHY should use different pre-emphasis 
>> duration
>> + * @preemphasis_width: half/full-width Pre-Emphasis updated via TUNE1
>> + *
> nit: spacing here doesn't match spacing in the structure.  AKA: you've
> smashed together all 8 properties in the structure but not in the
> description.
Will fix it.
>
>
>>   * @cfg: phy config data
>>   * @has_se_clk_scheme: indicate if PHY has single-ended ref clock scheme
>>   * @phy_initialized: indicate if PHY has been initialized
>> @@ -259,12 +282,35 @@ struct qusb2_phy {
>> struct regmap *tcsr;
>> struct nvmem_cell *cell;
>>
>> +   bool override_imp_res_offset;
>> +   u8 imp_res_offset_value;
>> +   bool override_hstx_trim;
>> +   u8 hstx_trim_value;
>> +   bool override_preemphasis;
>> +   u8 preemphasis_level;
>> +   bool override_preemphasis_width;
>> +   u8 preemphasis_width;
>> +
>> const struct qusb2_phy_cfg *cfg;
>> bool has_se_clk_scheme;
>> bool phy_initialized;
>> enum phy_mode mode;
>>  };
>>
>> +static inline void qusb2_write_mask(void __iomem *base, u32 offset,
>> +   u32 val, u32 mask)
>> +{
>> +   u32 reg;
>> +
>> +   reg = readl(base + offset);
>> +   reg &= ~mask;
>> +   reg |= val;
> "reg |= (val & mask)" instead of just "reg |= val"
>
> You don't do any bounds checking of the device tree entries and this
> will at least make sure that a bad value for a field won't screw up
> other fields (and so, presumably, it will be easier to find the bug).
>
It makes sense. Will change accordingly.

>
>> +   writel(reg, base + offset);
>> +
>> +   /* Ensure above write is completed */
>> +   readl(base + offset);
> You're using readl() and writel() which have barriers.  Why do you
> need this extra readl()?

This requirement comes from AHB2PHY wrapper designers and HPG.
Also existing qusb2_setbits/clrbits() wrapper already have similar handling.

>
>
>> +}
>> +
>>  static inline void qusb2_setbits(void __iomem *base, u32 offset, u32 val)
>>  {
>> u32 reg;
>> @@ -305,6 +351,42 @@ void qcom_qusb2_phy_configure(void __iomem *base,
>>  }
>>
>>  /*
>> + * Update board specific PHY tuning override values if specified from
>> + * device tree.
>> + *
> nit: remove extra comment line with just a "*" on it.
Sure.
>
>
>> + */
>> +static void qusb2_phy_override_phy_params(struct qusb2_phy *qphy)
>> +{
>> +   const struct qusb2_phy_cfg *cfg = qphy->cfg;
>> +
>> +   if (qphy->override_imp_res_offset)
>> +   qusb2_write_mask(qphy->base, QUSB2PHY_IMP_CTRL1,
>> +qphy->imp_res_offset_value << 
>> IMP_RES_OFFSET_SHIFT,
>> +IMP_RES_OFFSET_MASK);
>> +
>> +   if (qphy->override_hstx_trim)
>> +   qusb2_write_mask(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE1],
>> +qphy->hstx_trim_value << HSTX_TRIM_SHIFT,
>> +HSTX_TRIM_MASK);
>> +
>> +   if (qphy->override_preemphasis)
>> +   qusb2_write_mask(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE1],
>> +   qphy->preemphasis_level << 
>> PREEMPHASIS_EN_SHIFT,
>> +   PREEMPHASIS_EN_MASK);
>> +
>> +   if (qphy->override_preemphasis_width) {
>> +   if (qphy->preemphasis_width)
>> +   qusb2_setbits(qphy->base,
>> + cfg->regs

Re: [PATCH v4 1/7] clk: msm8996-gcc: change halt check for USB/PCIE pipe_clk

2018-04-09 Thread Manu Gautam
Hi,


On 4/6/2018 1:37 AM, Stephen Boyd wrote:
> Quoting Doug Anderson (2018-03-29 13:55:55)
>> Hi,
>>
>> On Thu, Mar 29, 2018 at 4:04 AM, Manu Gautam  wrote:
>>> The USB and PCIE pipe clocks are sourced from external clocks
>>> inside the QMP USB/PCIE PHYs. Enabling or disabling of PIPE RCG
>>> clocks is dependent on PHY initialization sequence hence
>>> update halt_check to BRANCH_HALT_DELAY for these clocks so
>>> that clock status bit is not polled when enabling or disabling
>>> the clocks. It allows to simplify PHY client driver code which
>>> is both user and source of the pipe_clk and avoid error logging
>>> related status check on clk_disable/enable.
>>>
>>> Signed-off-by: Manu Gautam 
>>> ---
>>>  drivers/clk/qcom/gcc-msm8996.c | 4 
>>>  1 file changed, 4 insertions(+)
>> As per my feedback on <https://patchwork.kernel.org/patch/10314937/>,
>> I'm not a fan of this.  Hopefully we can adjust the PHY driver so it's
>> not needed.
>>
> Agreed. We should be able to enable the clks at the right time and halt
> bits should work. From what I can recall we had that working before on
> db820c, so has something changed?

As replied in other patch IMO it is better to stick to the recommended
sequence and have this change as it would allow to cleanup PHY driver
and align with HPG. One reason I can think of why it works
on db820c is that there is some code in bootloader that enables
all USB clocks (including pipe_clk). Same is the case with SDM845.
And I start seeing errors if bootloader is changed or skip pipe_clk enable.



-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v4 2/7] phy: qcom-qmp: Enable pipe_clk before PHY initialization

2018-04-09 Thread Manu Gautam
Hi,


On 3/30/2018 2:24 AM, Doug Anderson wrote:
> Hi,
>
> On Thu, Mar 29, 2018 at 11:44 AM, Doug Anderson  wrote:
>> Hi,
>>
>> On Thu, Mar 29, 2018 at 4:04 AM, Manu Gautam  wrote:
>>> QMP PHY for USB/PCIE requires pipe_clk for locking of
>>> retime buffers at the pipe interface. Driver checks for
>>> PHY_STATUS without enabling pipe_clk due to which
>>> phy_init() fails with initialization timeout.
>>> Though pipe_clk is output from PHY (after PLL is programmed
>>> during initialization sequence) to GCC clock_ctl and then fed
>>> back to PHY but for PHY_STATUS register to reflect successful
>>> initialization pipe_clk from GCC must be present.
>>> Since, clock driver now ignores status_check for pipe_clk on
>>> clk_enable/disable, driver can safely enable/disable pipe_clk
>>> from phy_init/exit.
>>>
>>> Signed-off-by: Manu Gautam 
>>> ---
>>>  drivers/phy/qualcomm/phy-qcom-qmp.c | 22 --
>>>  1 file changed, 8 insertions(+), 14 deletions(-)
>> Overall this looks much better than the previous version.  Thanks!  :)
>>
>> I wonder one thing though.  You describe the original problem as this:
>>
>> 1. If you don't turn the clock on in qcom_qmp_phy_init() then the PHY
>> never sets the "ready" status.
>>
>> 2. If you don't have the PHY powered on / out of reset (which happens
>> in qcom_qmp_phy_init()) then when you enable/disable the clock it
>> doesn't properly update the status.  That's why you needed patch #1 in
>> this series.
>>
>>
>> I wonder: could you solve the above _without_ needing to use
>> BRANCH_HALT_DELAY in the clock driver?  Specifically, can you tell me
>> what happens if you put the clk_prepare_enable() after you've powered
>> on the PHY and taken it out of reset but before you check the status?
>> Said another way, put the "clk_prepare_enable(qphy->pipe_clk)" call
>> right before the "readl_poll_timeout" of the ready status?
>>
>>
>> If you do that, you'll turn everything on.  Then you'll check that the
>> clock's status is OK and then that the PHY's status is OK.
> Oh!  This is what you did in the previous version of the patch, then you said:
>
> "That is still needed as PHY might take some time to generate pipe_clk
> after its PLL is locked".
>
> It's really going to take more than the 200 us that the clock driver
> is giving it?  If so, I'd prefer to increase the amount of time waited
> in the clock driver, or adding a fixed delay _before_ the clk_enable()
> so that the 200 us that the clock driver gives it would be enough.
>
> I'm just not a fan of ignoring status bits if it can be helped.

I too would want to do that but it is not just about the delay.
As per QMP PHY hardware designers, pipe_clk should be enabled in GCC
as first thing in the PHY initialization sequence. Same sequence also has
been used in downstream phy driver always.
Changing the sequence might work but I would like to stick to the HPG
recommendation and avoid any deviation as PHY issues are very hard to
debug.


-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v4 7/7] phy: qcom-qusb2: Add QUSB2 PHYs support for sdm845

2018-03-29 Thread Manu Gautam
There are two QUSB2 PHYs present on sdm845. In order
to improve eye diagram for both the PHYs some parameters
need to be changed. Provide device tree properties to
override these from board specific device tree files.

Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qusb2.c | 112 +-
 1 file changed, 111 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c 
b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index 40fdef8..adcc3f8 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -60,6 +60,17 @@
 #define CORE_RESET BIT(5)
 #define CORE_RESET_MUX BIT(6)
 
+/* QUSB2PHY_IMP_CTRL1 register bits */
+#define IMP_RES_OFFSET_MASKGENMASK(5, 0)
+#define IMP_RES_OFFSET_SHIFT   0x0
+
+/* QUSB2PHY_PORT_TUNE1 register bits */
+#define HSTX_TRIM_MASK GENMASK(7, 4)
+#define HSTX_TRIM_SHIFT0x4
+#define PREEMPH_HALF_WIDTH BIT(2)
+#define PREEMPHASIS_EN_MASKGENMASK(1, 0)
+#define PREEMPHASIS_EN_SHIFT   0x0
+
 #define QUSB2PHY_PLL_ANALOG_CONTROLS_TWO   0x04
 #define QUSB2PHY_PLL_CLOCK_INVERTERS   0x18c
 #define QUSB2PHY_PLL_CMODE 0x2c
@@ -241,6 +252,18 @@ struct qusb2_phy_cfg {
  * @tcsr: TCSR syscon register map
  * @cell: nvmem cell containing phy tuning value
  *
+ * @override_imp_res_offset: PHY should use different rescode offset
+ * @imp_res_offset_value: rescode offset to be updated in IMP_CTRL1 register
+ *
+ * @override_hstx_trim: PHY should use different HSTX o/p current value
+ * @hstx_trim_value: HSTX_TRIM value to be updated in TUNE1 register
+ *
+ * @override_preemphasis: PHY should use different pre-amphasis amplitude
+ * @preemphasis_level: Amplitude Pre-Emphasis to be updated in TUNE1 register
+ *
+ * @override_preemphasis_width: PHY should use different pre-emphasis duration
+ * @preemphasis_width: half/full-width Pre-Emphasis updated via TUNE1
+ *
  * @cfg: phy config data
  * @has_se_clk_scheme: indicate if PHY has single-ended ref clock scheme
  * @phy_initialized: indicate if PHY has been initialized
@@ -259,12 +282,35 @@ struct qusb2_phy {
struct regmap *tcsr;
struct nvmem_cell *cell;
 
+   bool override_imp_res_offset;
+   u8 imp_res_offset_value;
+   bool override_hstx_trim;
+   u8 hstx_trim_value;
+   bool override_preemphasis;
+   u8 preemphasis_level;
+   bool override_preemphasis_width;
+   u8 preemphasis_width;
+
const struct qusb2_phy_cfg *cfg;
bool has_se_clk_scheme;
bool phy_initialized;
enum phy_mode mode;
 };
 
+static inline void qusb2_write_mask(void __iomem *base, u32 offset,
+   u32 val, u32 mask)
+{
+   u32 reg;
+
+   reg = readl(base + offset);
+   reg &= ~mask;
+   reg |= val;
+   writel(reg, base + offset);
+
+   /* Ensure above write is completed */
+   readl(base + offset);
+}
+
 static inline void qusb2_setbits(void __iomem *base, u32 offset, u32 val)
 {
u32 reg;
@@ -305,6 +351,42 @@ void qcom_qusb2_phy_configure(void __iomem *base,
 }
 
 /*
+ * Update board specific PHY tuning override values if specified from
+ * device tree.
+ *
+ */
+static void qusb2_phy_override_phy_params(struct qusb2_phy *qphy)
+{
+   const struct qusb2_phy_cfg *cfg = qphy->cfg;
+
+   if (qphy->override_imp_res_offset)
+   qusb2_write_mask(qphy->base, QUSB2PHY_IMP_CTRL1,
+qphy->imp_res_offset_value << IMP_RES_OFFSET_SHIFT,
+IMP_RES_OFFSET_MASK);
+
+   if (qphy->override_hstx_trim)
+   qusb2_write_mask(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE1],
+qphy->hstx_trim_value << HSTX_TRIM_SHIFT,
+HSTX_TRIM_MASK);
+
+   if (qphy->override_preemphasis)
+   qusb2_write_mask(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE1],
+   qphy->preemphasis_level << PREEMPHASIS_EN_SHIFT,
+   PREEMPHASIS_EN_MASK);
+
+   if (qphy->override_preemphasis_width) {
+   if (qphy->preemphasis_width)
+   qusb2_setbits(qphy->base,
+ cfg->regs[QUSB2PHY_PORT_TUNE1],
+ PREEMPH_HALF_WIDTH);
+   else
+   qusb2_clrbits(qphy->base,
+ cfg->regs[QUSB2PHY_PORT_TUNE1],
+ PREEMPH_HALF_WIDTH);
+   }
+}
+
+/*
  * Fetches HS Tx tuning value from nvmem and sets the
  * QUSB2PHY_PORT_TUNE1/2 register.
  * For error case, skip setting the value and use the 

[PATCH v4 3/7] phy: qcom-qusb2: Fix crash if nvmem cell not specified

2018-03-29 Thread Manu Gautam
Driver currently crashes due to NULL pointer deference
while updating PHY tune register if nvmem cell is NULL.
Since, fused value for Tune1/2 register is optional,
we'd rather bail out.

Fixes: ca04d9d3e1b1 ("phy: qcom-qusb2: New driver for QUSB2 PHY on Qcom chips")
Reviewed-by: Vivek Gautam 
Reviewed-by: Evan Green 
Cc: stable  # 4.14+
Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qusb2.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c 
b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index 94afeac..40fdef8 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -315,6 +315,10 @@ static void qusb2_phy_set_tune2_param(struct qusb2_phy 
*qphy)
const struct qusb2_phy_cfg *cfg = qphy->cfg;
u8 *val;
 
+   /* efuse register is optional */
+   if (!qphy->cell)
+   return;
+
/*
 * Read efuse register having TUNE2/1 parameter's high nibble.
 * If efuse register shows value as 0x0, or if we fail to find
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v4 4/7] dt-bindings: phy-qcom-qmp: Update bindings for sdm845

2018-03-29 Thread Manu Gautam
Update compatible strings for USB3 PHYs on SDM845.
One is QMPv3 DisplayPort-USB combo PHY and other one
is USB UNI PHY which is single lane USB3 PHY without
DP capability. While at it also remove "qcom,qmp-v3-usb3-phy"
compatible string which was earlier added for sdm845
only as there wouldn't be any user of same.

Reviewed-by: Rob Herring 
Signed-off-by: Manu Gautam 
---
 Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt 
b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
index dcf1b8f..266a1bb 100644
--- a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
+++ b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
@@ -9,7 +9,8 @@ Required properties:
   "qcom,ipq8074-qmp-pcie-phy" for PCIe phy on IPQ8074
   "qcom,msm8996-qmp-pcie-phy" for 14nm PCIe phy on msm8996,
   "qcom,msm8996-qmp-usb3-phy" for 14nm USB3 phy on msm8996,
-  "qcom,qmp-v3-usb3-phy" for USB3 QMP V3 phy.
+  "qcom,sdm845-qmp-usb3-phy" for USB3 QMP V3 phy on sdm845,
+  "qcom,sdm845-qmp-usb3-uni-phy" for USB3 QMP V3 UNI phy on sdm845.
 
  - reg: offset and length of register set for PHY's common serdes block.
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v4 6/7] dt-bindings: phy-qcom-usb2: Add support to override tuning values

2018-03-29 Thread Manu Gautam
To improve eye diagram for PHYs on different boards of same SOC,
some parameters may need to be changed. Provide device tree
properties to override these from board specific device tree
files. While at it, replace "qcom,qusb2-v2-phy" with compatible
string for USB2 PHY on sdm845 which was earlier added for
sdm845 only.

Signed-off-by: Manu Gautam 
---
 .../devicetree/bindings/phy/qcom-qusb2-phy.txt| 19 ++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt 
b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
index 42c9742..0ed140a 100644
--- a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
+++ b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
@@ -6,7 +6,7 @@ QUSB2 controller supports LS/FS/HS usb connectivity on Qualcomm 
chipsets.
 Required properties:
  - compatible: compatible list, contains
   "qcom,msm8996-qusb2-phy" for 14nm PHY on msm8996,
-  "qcom,qusb2-v2-phy" for QUSB2 V2 PHY.
+  "qcom,sdm845-qusb2-phy" for 10nm PHY on sdm845.
 
  - reg: offset and length of the PHY register set.
  - #phy-cells: must be 0.
@@ -27,6 +27,23 @@ Optional properties:
tuning parameter value for qusb2 phy.
 
  - qcom,tcsr-syscon: Phandle to TCSR syscon register region.
+ - qcom,imp-res-offset-value: It is a 6 bit value that specifies offset to be
+   added to PHY refgen RESCODE via IMP_CTRL1 register. It is a PHY
+   tuning paramter that may vary for different boards of same SOC.
+ - qcom,hstx-trim-value: It is a 4 bit value that specifies tuning for HSTX
+   output current. 0x0 value corresponding to 24mA which is maximum
+   current and 0xf corresponds to lowest current which is 15mA.
+ - qcom,preemphasis-level: It is a 2 bit value that specifies pre-emphasis 
level.
+   Possible values are:
+   00: NONE
+   01: +5%
+   10: +10%
+   11: +15%
+- qcom,preemphasis-width: It is a 1 bit value that specifies how long the HSTX
+   pre-emphasis (specified using qcom,preemphasis-level) must be in
+   effect. Possible values are:
+   0: Full-bit width
+   1: Half-bit width
 
 Example:
hsusb_phy: phy@7411000 {
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v4 2/7] phy: qcom-qmp: Enable pipe_clk before PHY initialization

2018-03-29 Thread Manu Gautam
QMP PHY for USB/PCIE requires pipe_clk for locking of
retime buffers at the pipe interface. Driver checks for
PHY_STATUS without enabling pipe_clk due to which
phy_init() fails with initialization timeout.
Though pipe_clk is output from PHY (after PLL is programmed
during initialization sequence) to GCC clock_ctl and then fed
back to PHY but for PHY_STATUS register to reflect successful
initialization pipe_clk from GCC must be present.
Since, clock driver now ignores status_check for pipe_clk on
clk_enable/disable, driver can safely enable/disable pipe_clk
from phy_init/exit.

Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 22 --
 1 file changed, 8 insertions(+), 14 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 6470c5d..fddb1c9 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -793,19 +793,6 @@ static void qcom_qmp_phy_configure(void __iomem *base,
}
 }
 
-static int qcom_qmp_phy_poweron(struct phy *phy)
-{
-   struct qmp_phy *qphy = phy_get_drvdata(phy);
-   struct qcom_qmp *qmp = qphy->qmp;
-   int ret;
-
-   ret = clk_prepare_enable(qphy->pipe_clk);
-   if (ret)
-   dev_err(qmp->dev, "pipe_clk enable failed, err=%d\n", ret);
-
-   return ret;
-}
-
 static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
 {
const struct qmp_phy_cfg *cfg = qmp->cfg;
@@ -974,6 +961,12 @@ static int qcom_qmp_phy_init(struct phy *phy)
}
}
 
+   ret = clk_prepare_enable(qphy->pipe_clk);
+   if (ret) {
+   dev_err(qmp->dev, "pipe_clk enable failed err=%d\n", ret);
+   goto err_clk_enable;
+   }
+
/* Tx, Rx, and PCS configurations */
qcom_qmp_phy_configure(tx, cfg->regs, cfg->tx_tbl, cfg->tx_tbl_num);
/* Configuration for other LANE for USB-DP combo PHY */
@@ -1019,6 +1012,8 @@ static int qcom_qmp_phy_init(struct phy *phy)
return ret;
 
 err_pcs_ready:
+   clk_disable_unprepare(qphy->pipe_clk);
+err_clk_enable:
if (cfg->has_lane_rst)
reset_control_assert(qphy->lane_rst);
 err_lane_rst:
@@ -1283,7 +1278,6 @@ static int phy_pipe_clk_register(struct qcom_qmp *qmp, 
struct device_node *np)
 static const struct phy_ops qcom_qmp_phy_gen_ops = {
.init   = qcom_qmp_phy_init,
.exit   = qcom_qmp_phy_exit,
-   .power_on   = qcom_qmp_phy_poweron,
.set_mode   = qcom_qmp_phy_set_mode,
.owner  = THIS_MODULE,
 };
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v4 5/7] phy: qcom-qmp: Add QMP V3 USB3 UNI PHY support for sdm845

2018-03-29 Thread Manu Gautam
QMP V3 UNI PHY is a single lane USB3 PHY without support
for DisplayPort (DP).
Main difference from DP combo QMPv3 PHY is that UNI PHY
doesn't have dual RX/TX lanes and no separate DP_COM
block for configuration related to type-c or DP.
Also remove "qcom,qmp-v3-usb3-phy" compatible string which
was earlier added for sdm845 only as there wouldn't be
any user of same.
While at it, fix has_pwrdn_delay attribute for USB-DP
PHY configuration and.

Reviewed-by: Evan Green 
Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 147 +++-
 drivers/phy/qualcomm/phy-qcom-qmp.h |   5 ++
 2 files changed, 151 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
b/drivers/phy/qualcomm/phy-qcom-qmp.c
index fddb1c9..4c47010 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -490,6 +490,118 @@ enum qphy_reg_layout {
QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
 };
 
+static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_serdes_tbl[] = {
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL2, 0x08),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x80),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x34),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x15),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x04),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_CFG, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x0a),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x31),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x85),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x07),
+};
+
+static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_tx_tbl[] = {
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0xc6),
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x06),
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x06),
+};
+
+static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_rx_tbl[] = {
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x0c),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x50),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1c),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
+};
+
+static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_pcs_tbl[] = {
+   /* FLL settings */
+   QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
+   QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
+   QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
+   QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40),
+   QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
+

[PATCH v4 1/7] clk: msm8996-gcc: change halt check for USB/PCIE pipe_clk

2018-03-29 Thread Manu Gautam
The USB and PCIE pipe clocks are sourced from external clocks
inside the QMP USB/PCIE PHYs. Enabling or disabling of PIPE RCG
clocks is dependent on PHY initialization sequence hence
update halt_check to BRANCH_HALT_DELAY for these clocks so
that clock status bit is not polled when enabling or disabling
the clocks. It allows to simplify PHY client driver code which
is both user and source of the pipe_clk and avoid error logging
related status check on clk_disable/enable.

Signed-off-by: Manu Gautam 
---
 drivers/clk/qcom/gcc-msm8996.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c
index 5d74512..336d12d 100644
--- a/drivers/clk/qcom/gcc-msm8996.c
+++ b/drivers/clk/qcom/gcc-msm8996.c
@@ -1418,6 +1418,7 @@ enum {
 
 static struct clk_branch gcc_usb3_phy_pipe_clk = {
.halt_reg = 0x50004,
+   .halt_check = BRANCH_HALT_DELAY,
.clkr = {
.enable_reg = 0x50004,
.enable_mask = BIT(0),
@@ -2472,6 +2473,7 @@ enum {
 
 static struct clk_branch gcc_pcie_0_pipe_clk = {
.halt_reg = 0x6b018,
+   .halt_check = BRANCH_HALT_DELAY,
.clkr = {
.enable_reg = 0x6b018,
.enable_mask = BIT(0),
@@ -2547,6 +2549,7 @@ enum {
 
 static struct clk_branch gcc_pcie_1_pipe_clk = {
.halt_reg = 0x6d018,
+   .halt_check = BRANCH_HALT_DELAY,
.clkr = {
.enable_reg = 0x6d018,
.enable_mask = BIT(0),
@@ -2622,6 +2625,7 @@ enum {
 
 static struct clk_branch gcc_pcie_2_pipe_clk = {
.halt_reg = 0x6e018,
+   .halt_check = BRANCH_HALT_DELAY,
.clkr = {
.enable_reg = 0x6e018,
.enable_mask = BIT(0),
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v4 0/7] phy: qcom: Updates for USB PHYs on SDM845

2018-03-29 Thread Manu Gautam
SDM845 has two USB instances each with QUSB2 and QMP PHYs.
One of the QMP PHY is USB-DP (DisplayPort) combo PHY where
as other one is single lane UNI-PHY (without DP support).
Changes are related to PHY configuration for electrical
parameters tuning to improve eye-diagram and some fixes.

Changes since v3:
 - As per Doug's review comments added device tree parameters
   to handle board level differences in PHY tuning values instead
   of adding separate device tree bindings.
 - Replace PHY version specific bindings names with SOC name as
   no one is going to use generic binding names.
 - Update halt_check to not check for pipe clock status that
   allows to simplify pipe_clk handling in QMP driver.

Changes since v2:
 - Use separate phy_ops for USB to not register power_on op.
 - And other minor changes as per review comments from Stephen.

Changes since v1:
 - Updated qusb2 compatibility name as per comment from Vivek.

Manu Gautam (7):
  clk: msm8996-gcc: change halt check for USB/PCIE pipe_clk
  phy: qcom-qmp: Enable pipe_clk before PHY initialization
  phy: qcom-qusb2: Fix crash if nvmem cell not specified
  dt-bindings: phy-qcom-qmp: Update bindings for sdm845
  phy: qcom-qmp: Add QMP V3 USB3 UNI PHY support for sdm845
  dt-bindings: phy-qcom-usb2: Add support to override tuning values
  phy: qcom-qusb2: Add QUSB2 PHYs support for sdm845

 .../devicetree/bindings/phy/qcom-qmp-phy.txt   |   3 +-
 .../devicetree/bindings/phy/qcom-qusb2-phy.txt |  19 ++-
 drivers/clk/qcom/gcc-msm8996.c |   4 +
 drivers/phy/qualcomm/phy-qcom-qmp.c| 169 +++--
 drivers/phy/qualcomm/phy-qcom-qmp.h|   5 +
 drivers/phy/qualcomm/phy-qcom-qusb2.c  | 116 +-
 6 files changed, 298 insertions(+), 18 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v3 6/6] phy: qcom-qusb2: Add QUSB2 PHYs support for sdm845

2018-03-28 Thread Manu Gautam
Hi,


On 3/28/2018 4:22 AM, Doug Anderson wrote:
> Hi,
>
> On Thu, Mar 22, 2018 at 11:11 PM, Manu Gautam  wrote:
>> There are two QUSB2 PHYs present on sdm845. Update PHY
>> registers programming for both the PHYs related to
>> electrical parameters to improve eye diagram.
> This tuning difference is truly associated with the SoC itself?  Are
> you sure?  Are the two different PHYs in the SoC somehow using
> different silicon processes?  ...or is one close to another IP block
> that is noisy?  ...or something else to account for this difference?
>
> It seems more likely that this tuning difference is associated with
> the board.  If you're _certain_ this is really due to internal SoC
> differences you'll have to come up with some darn good evidence to
> convince me...

This difference must be due to board only.

>
> If the tuning is truly associated with the board then:
>
> 1. You should have a single device tree compatible string.  IMHO it
> should contain the name of the SoC in it, so "qcom,sdm845-qusb2-phy".
> It's generally OK to name something in Linux using the name of the
> first thing that happened to support it in Linux (even if later
> processors use the exact same component).  Leaving it as just
> "qcom,qusb2-v2-phy" is OK with me too if that's what everyone wants.
I will remove "qcom,qusb2-v2-phy" as I don't expect any users of that.
>
>
> 2. You should figure out how to describe the needed board-to-board
> tuning in device tree.
>
> The only two differences you have right now are:
>
> QUSB2PHY_IMP_CTRL1: 0 => 0x8
> QUSB2PHY_PORT_TUNE1: 0x30 => 0x48
>
> I'm not sure I found all the correct documentation for the PHY (the
> docs I have say that "TUNE1" bit 3 is "reserved") so I can't come up
> with all of these for you.  But I think I found the difference
> accounting for the upper nybble of TUNE1 changing from 0x3 to 0x4.
> For this, I think you'd want a device tree property like:
>
> qcom,hstx_trim_mv
>
> ...and the values of that property would be the values from 800 to 950
> in 8 steps, or [800, 821, 842, 864, 885, 907, 928, 950].
>
> You'd want to do similar things for the other differences.
>
> You don't need to encode every possible difference right now.  When
> you come up with something that needs to be different you add a new
> optional device tree property (defaulting to whatever the driver used
> to do) to describe your new property.

Sure. I will come up with separate device tree properties to specify
board-to-board differences in PHY tuning.


>
> -Doug

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v3 5/6] dt-bindings: phy-qcom-usb2: Update bindings for sdm845

2018-03-28 Thread Manu Gautam
Hi,


On 3/28/2018 3:27 AM, Doug Anderson wrote:
> Hi,
>
> On Thu, Mar 22, 2018 at 11:11 PM, Manu Gautam  wrote:
>> Update compatible strings for USB2 PHYs on sdm845.
>> There are two QUSB2 PHYs present on sdm845. Few PHY registers
>> programming is different for these PHYs related to electrical
>> parameters, otherwise both are same.
>>
>> Signed-off-by: Manu Gautam 
>> ---
>>  Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt | 4 +++-
>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>
>> diff --git a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt 
>> b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
>> index 42c9742..b99a57f 100644
>> --- a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
>> +++ b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
>> @@ -6,7 +6,9 @@ QUSB2 controller supports LS/FS/HS usb connectivity on 
>> Qualcomm chipsets.
>>  Required properties:
>>   - compatible: compatible list, contains
>>"qcom,msm8996-qusb2-phy" for 14nm PHY on msm8996,
>> -  "qcom,qusb2-v2-phy" for QUSB2 V2 PHY.
>> +  "qcom,qusb2-v2-phy" for QUSB2 V2 PHY,
>> +  "qcom,sdm845-qusb2-phy-1" for primary PHY on sdm845,
>> +  "qcom,sdm845-qusb2-phy-2" for secondary PHY on sdm845.
> Similar question to the one I posed on
> <https://patchwork.kernel.org/patch/10302761/> for the QMP PHY.  What
> is "qcom,qusb2-v2-phy"?  Is it some ideal abstract version of the PHY?
>  Do we expect that anyone would actually use that compatible string?
>
> In this case in <https://patchwork.kernel.org/patch/10302755/> it
> looks as if you're using the same settings as
> "qcom,sdm845-qusb2-phy-2", so presumably "qcom,qusb2-v2-phy" should
> just be deleted.
>

I will remove "qcom,qusb2-v2-phy".


> -Doug

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v3 3/6] dt-bindings: phy-qcom-qmp: Update bindings for sdm845

2018-03-28 Thread Manu Gautam
Hi,


On 3/28/2018 3:07 AM, Doug Anderson wrote:
> Hi,
>
> On Thu, Mar 22, 2018 at 11:11 PM, Manu Gautam  wrote:
>> Update compatible strings for USB3 PHYs on SDM845.
>> One is QMPv3 DisplayPort-USB combo PHY and other one
>> is USB UNI PHY which is single lane USB3 PHY without
>> DP capability.
>>
>> Reviewed-by: Rob Herring 
>> Signed-off-by: Manu Gautam 
>> ---
>>  Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt | 4 +++-
>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>
>> diff --git a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt 
>> b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
>> index dcf1b8f..cef8765 100644
>> --- a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
>> +++ b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
>> @@ -9,7 +9,9 @@ Required properties:
>>"qcom,ipq8074-qmp-pcie-phy" for PCIe phy on IPQ8074
>>"qcom,msm8996-qmp-pcie-phy" for 14nm PCIe phy on msm8996,
>>"qcom,msm8996-qmp-usb3-phy" for 14nm USB3 phy on msm8996,
>> -  "qcom,qmp-v3-usb3-phy" for USB3 QMP V3 phy.
>> +  "qcom,qmp-v3-usb3-phy" for USB3 QMP V3 phy,
>> +  "qcom,sdm845-qmp-usb3-phy" for USB3 QMP V3 phy on sdm845,
>> +  "qcom,sdm845-qmp-usb3-uni-phy" for USB3 QMP V3 UNI phy on 
>> sdm845.
> I'm confused.  What value does "qcom,qmp-v3-usb3-phy" have as a
> separate entry from "qcom,sdm845-qmp-usb3-phy"?  Is
> "qcom,qmp-v3-usb3-phy" expected to work on some non-SDM845 based
> device?
>
> Personally I think you should remove "qcom,qmp-v3-usb3-phy" from the
> bindings as part of this patch (replacing it with the new string
> qcom,sdm845-qmp-usb3-phy)".  Yeah, yeah bindings are forever.  ...but
> that particular string was added about a month ago and (I believe) it
> was intended for SDM845 anyway.  As per
> <https://patchwork.kernel.org/patch/10302759/> match to the exact same
> PHY data which leads extra credence to my belief.
>
> If later on you find that some future chip can use the exact same
> driver / settings as the SDM845 you can always list the
> "qcom,sdm845-qmp-usb3-phy" string as a secondary compatible anyway.
>

I agree. Will just remove "qcom,sdm845-qmp-usb3-phy"

> -Doug

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v3 1/6] phy: qcom-qmp: Enable pipe_clk before checking USB3 PHY_STATUS

2018-03-28 Thread Manu Gautam
Hi,


On 3/28/2018 1:44 AM, Doug Anderson wrote:
> Hi,
>
> On Tue, Mar 27, 2018 at 12:50 AM, Manu Gautam  wrote:
>> Hi,
>>
>>
>> On 3/27/2018 12:26 PM, Vivek Gautam wrote:
>>>
>>> On 3/27/2018 10:37 AM, Manu Gautam wrote:
>>>> Hi Doug,
>>>>
>>>>
>>>> On 3/27/2018 9:56 AM, Doug Anderson wrote:
>>>>> Manu
>>>>>
>>>>> On Thu, Mar 22, 2018 at 11:11 PM, Manu Gautam  
>>>>> wrote:
>>>>>> QMP PHY for USB mode requires pipe_clk for calibration and PLL lock
>>>>>> to take place. This clock is output from PHY to GCC clock_ctl and then
>>>>>> fed back to QMP PHY and is available from PHY only after PHY is reset
>>>>>> and initialized, hence it can't be enabled too early in initialization
>>>>>> sequence.
>>>>>>
>>>>>> Signed-off-by: Manu Gautam 
>>>>>> ---
>>>>>>   drivers/phy/qualcomm/phy-qcom-qmp.c | 33 
>>>>>> -
>>>>>>   1 file changed, 32 insertions(+), 1 deletion(-)
>>>>> So it's now new with this patch, but it's more obvious with this
>>>>> patch.  It seems like "UFS/PCIE" is kinda broken w/ respect to how it
>>>>> controls its clock.  Specifically:
>>>>>
>>>>> * If you init the PHY but don't power it on, then you "exit" the PHY:
>>>>> you'll disable/unprepare "pipe_clk" even though you never
>>>>> prepare/enabled it.
>>>>>
>>>>> * If you init the PHY, power it on, power it off, power it on, and
>>>>> exit the PHY: you'll leave the clock prepared one extra time.
>>>>>
>>>>> Specifically I'd expect: for UFS/PCIE the disable/unprepare should be
>>>>> symmetric with the enable/prepare and should be in "power off", not in
>>>>> exit.
>>>>>
>>>>> ...or did I miss something?
>>>>>
>>>>>
>>>>> Interestingly, your patch fixes this problem for USB3 (where init/exit
>>>>> are now symmetric), but leaves the problem there for UFS/PCIE.
>>>>>
>>>> Thanks for review.
>>>> One of the reason why pipe_clk is disabled as part of phy_exit is that
>>>> halt_check from clk_disable reports error if called after PHY has been
>>>> powered down or phy_exit.
>>>> I believe that warning should be ignored in qcom gcc-clock driver
>>>> (for applicable platforms) by using BRANCH_HALT_DELAY as halt_check
>>>> for pipe_clk and performing clk_disable from power_off for UFS/PCIE.
>>> UFS doesn't use PIPE clock.
> Just to confirm: we no longer need to do this "BRANCH_HALT_DELAY" now
> that we've figured everything out, right?

That is still needed as PHY might take some time to generate pipe_clk
after its PLL is locked (or while initialization sequence is carried out).
Performing clk_enable will throw a warning. Hence, it is better to
have halt_check that will allow to club pipe_clk with other clocks and
enable it at the beginning of phy_init.

>
>
>> Yes, UFS PHY doesn't use one. But similar to pipe_clk there are rx/tx 
>> symbol_clk
>> output from PHY that is used by UFS controller. I will update code comments
>> to not refer UFS for pipe_clk.
>>
>>> But considering for PCIe, if we disable pipe clock when phy is still 
>>> running, then
>>> it shouldn't be a problem. We should also not see the halt warning as the 
>>> gcc
>>> driver should be able to just turn the gate off.
>>> The reason why it will throw that error is when the parent clock to that 
>>> gate
>>> is gated, i.e. the pipe clock is not flowing on that branch.
>> I got the confirmation that pipe_clk is needed for PCIE as well for its
>> initialization to happen successfully. So we do need clock driver change
>> to fix this in PHY driver.
> So basically if I'm understanding this correctly:
>
> * Both USB and PCIE need the clk_enable() in qcom_qmp_phy_init()
>
> * UFS doesn't even use a pipe clock (pipe_clk is NULL and thus these
> calls are no-ops).
>
> So that means the next version of this code will simply get rid of
> qcom_qmp_phy_poweron() and we can now use the same phy_ops for both
> everything again?  That also makes everything symmetric and gets rid
> of the possible imbalance of clock enable/disable, so I'

Re: [PATCH v3 1/6] phy: qcom-qmp: Enable pipe_clk before checking USB3 PHY_STATUS

2018-03-27 Thread Manu Gautam
Hi,


On 3/27/2018 12:26 PM, Vivek Gautam wrote:
>
>
> On 3/27/2018 10:37 AM, Manu Gautam wrote:
>> Hi Doug,
>>
>>
>> On 3/27/2018 9:56 AM, Doug Anderson wrote:
>>> Manu
>>>
>>> On Thu, Mar 22, 2018 at 11:11 PM, Manu Gautam  
>>> wrote:
>>>> QMP PHY for USB mode requires pipe_clk for calibration and PLL lock
>>>> to take place. This clock is output from PHY to GCC clock_ctl and then
>>>> fed back to QMP PHY and is available from PHY only after PHY is reset
>>>> and initialized, hence it can't be enabled too early in initialization
>>>> sequence.
>>>>
>>>> Signed-off-by: Manu Gautam 
>>>> ---
>>>>   drivers/phy/qualcomm/phy-qcom-qmp.c | 33 
>>>> -
>>>>   1 file changed, 32 insertions(+), 1 deletion(-)
>>> So it's now new with this patch, but it's more obvious with this
>>> patch.  It seems like "UFS/PCIE" is kinda broken w/ respect to how it
>>> controls its clock.  Specifically:
>>>
>>> * If you init the PHY but don't power it on, then you "exit" the PHY:
>>> you'll disable/unprepare "pipe_clk" even though you never
>>> prepare/enabled it.
>>>
>>> * If you init the PHY, power it on, power it off, power it on, and
>>> exit the PHY: you'll leave the clock prepared one extra time.
>>>
>>> Specifically I'd expect: for UFS/PCIE the disable/unprepare should be
>>> symmetric with the enable/prepare and should be in "power off", not in
>>> exit.
>>>
>>> ...or did I miss something?
>>>
>>>
>>> Interestingly, your patch fixes this problem for USB3 (where init/exit
>>> are now symmetric), but leaves the problem there for UFS/PCIE.
>>>
>> Thanks for review.
>> One of the reason why pipe_clk is disabled as part of phy_exit is that
>> halt_check from clk_disable reports error if called after PHY has been
>> powered down or phy_exit.
>> I believe that warning should be ignored in qcom gcc-clock driver
>> (for applicable platforms) by using BRANCH_HALT_DELAY as halt_check
>> for pipe_clk and performing clk_disable from power_off for UFS/PCIE.
> UFS doesn't use PIPE clock.

Yes, UFS PHY doesn't use one. But similar to pipe_clk there are rx/tx symbol_clk
output from PHY that is used by UFS controller. I will update code comments
to not refer UFS for pipe_clk.

> But considering for PCIe, if we disable pipe clock when phy is still running, 
> then
> it shouldn't be a problem. We should also not see the halt warning as the gcc
> driver should be able to just turn the gate off.
> The reason why it will throw that error is when the parent clock to that gate
> is gated, i.e. the pipe clock is not flowing on that branch.

I got the confirmation that pipe_clk is needed for PCIE as well for its
initialization to happen successfully. So we do need clock driver change
to fix this in PHY driver.

>
> Best regards
> Vivek
>
>>
>> I can implement that as separate patch once dependent gcc driver
>> patch(es) gets in. Would that be ok?
>>
>> -Manu
>>
>

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v3 1/6] phy: qcom-qmp: Enable pipe_clk before checking USB3 PHY_STATUS

2018-03-27 Thread Manu Gautam
Hi Vivek,


On 3/27/2018 12:21 PM, Vivek Gautam wrote:
> Hi Manu,
>
>
> On 3/23/2018 11:41 AM, Manu Gautam wrote:
>> QMP PHY for USB mode requires pipe_clk for calibration and PLL lock
>> to take place.
>
> AFAIK, that's not true. The pipe clock is the *output* of the PLL, and it's 
> should not
> be needed for PLL calibration and locking. The PLL locking happens when the 
> phy is
> configured and powered on.
> Atleast that's what the PIPE spec also says.
>
>    CLK
>  |
>  |
>  Y
>    
>   |  PLL    |> PCLK (this is pipe clock 125/250/... MHz 
> corresponding to the data width)
>    
>
> That's the reason we were enabling it after the PLL was locked.

I got this clarified by QMP PHY hardware designer that pipe_clk is indeed
needed for PHY to complete init sequence and reflect in PHY_STATUS (mainly
for calibration and I should remove PLL lock from commit subject).
It might work on some platforms without this change if boot code
leaves pipe clock enabled during bootup.


>
>> This clock is output from PHY to GCC clock_ctl and then
>> fed back to QMP PHY and is available from PHY only after PHY is reset
>> and initialized, hence it can't be enabled too early in initialization
>> sequence.
>>
>> Signed-off-by: Manu Gautam 
>> ---
>>   drivers/phy/qualcomm/phy-qcom-qmp.c | 33 -
>>   1 file changed, 32 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
>> b/drivers/phy/qualcomm/phy-qcom-qmp.c
>> index 6470c5d..5d8df6a 100644
>> --- a/drivers/phy/qualcomm/phy-qcom-qmp.c
>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
>> @@ -1008,6 +1008,19 @@ static int qcom_qmp_phy_init(struct phy *phy)
>>   status = pcs + cfg->regs[QPHY_PCS_READY_STATUS];
>>   mask = cfg->mask_pcs_ready;
>>   +    /*
>> + * USB3 PHY requires pipe_clk for PLL lock and calibration.
>> + * Enable it from here for USB. For UFS/PCIE, it gets enabled
>> + * from poweron.
>> + */
>> +    if (cfg->type == PHY_TYPE_USB3) {
>> +    ret = clk_prepare_enable(qphy->pipe_clk);
>
> As mentioned before AFAIU, pipe clock is just an output coming out of the 
> PHY's PLL
> and we shouldn't try to enable pipe clock before PHY even gets initialized.
> We should may just try to first fix the unbalanced pipe clock enable/disable 
> problem.
>
> Moreover, lets take care of all USB, PCIe and DP phys when we want to 
> enable/disbale
> pipe clock as all of them use this clock.

I will get the pipe_clk requirement for PCIE as well and do it for both
(depending on gcc change).

>
> Best regards
> Vivek
>
>> +    if (ret) {
>> +    dev_err(qmp->dev, "pipe_clk enable err=%d\n", ret);
>> +    goto err_clk_enable;
>> +    }
>> +    }
>> +
>>   ret = readl_poll_timeout(status, val, !(val & mask), 1,
>>    PHY_INIT_COMPLETE_TIMEOUT);
>>   if (ret) {
>> @@ -1019,6 +1032,9 @@ static int qcom_qmp_phy_init(struct phy *phy)
>>   return ret;
>>     err_pcs_ready:
>> +    if (cfg->type == PHY_TYPE_USB3)
>> +    clk_disable_unprepare(qphy->pipe_clk);
>> +err_clk_enable:
>>   if (cfg->has_lane_rst)
>>   reset_control_assert(qphy->lane_rst);
>>   err_lane_rst:
>> @@ -1288,10 +1304,19 @@ static int phy_pipe_clk_register(struct qcom_qmp 
>> *qmp, struct device_node *np)
>>   .owner    = THIS_MODULE,
>>   };
>>   +/* USB PHY doesn't require power_on op */
>> +static const struct phy_ops qcom_qmp_usb_phy_gen_ops = {
>> +    .init    = qcom_qmp_phy_init,
>> +    .exit    = qcom_qmp_phy_exit,
>> +    .set_mode    = qcom_qmp_phy_set_mode,
>> +    .owner    = THIS_MODULE,
>> +};
>> +
>>   static
>>   int qcom_qmp_phy_create(struct device *dev, struct device_node *np, int id)
>>   {
>>   struct qcom_qmp *qmp = dev_get_drvdata(dev);
>> +    const struct phy_ops *ops;
>>   struct phy *generic_phy;
>>   struct qmp_phy *qphy;
>>   char prop_name[MAX_PROP_NAME];
>> @@ -1354,7 +1379,13 @@ int qcom_qmp_phy_create(struct device *dev, struct 
>> device_node *np, int id)
>>   }
>>   }
>>   -    generic_phy = devm_phy_create(dev, np, &qcom_qmp_phy_gen_ops);
>> +    /* USB PHY doesn't use power_on op */
>> +    if (qmp->cfg->type == PHY_TYPE_USB3)
>> +    ops = &qcom_qmp_usb_phy_gen_ops;
>> +    else
>> +    ops = &qcom_qmp_phy_gen_ops;
>> +
>> +    generic_phy = devm_phy_create(dev, np, ops);
>>   if (IS_ERR(generic_phy)) {
>>   ret = PTR_ERR(generic_phy);
>>   dev_err(dev, "failed to create qphy %d\n", ret);
>

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v3 1/6] phy: qcom-qmp: Enable pipe_clk before checking USB3 PHY_STATUS

2018-03-26 Thread Manu Gautam
Hi Doug,


On 3/27/2018 9:56 AM, Doug Anderson wrote:
> Manu
>
> On Thu, Mar 22, 2018 at 11:11 PM, Manu Gautam  wrote:
>> QMP PHY for USB mode requires pipe_clk for calibration and PLL lock
>> to take place. This clock is output from PHY to GCC clock_ctl and then
>> fed back to QMP PHY and is available from PHY only after PHY is reset
>> and initialized, hence it can't be enabled too early in initialization
>> sequence.
>>
>> Signed-off-by: Manu Gautam 
>> ---
>>  drivers/phy/qualcomm/phy-qcom-qmp.c | 33 -
>>  1 file changed, 32 insertions(+), 1 deletion(-)
> So it's now new with this patch, but it's more obvious with this
> patch.  It seems like "UFS/PCIE" is kinda broken w/ respect to how it
> controls its clock.  Specifically:
>
> * If you init the PHY but don't power it on, then you "exit" the PHY:
> you'll disable/unprepare "pipe_clk" even though you never
> prepare/enabled it.
>
> * If you init the PHY, power it on, power it off, power it on, and
> exit the PHY: you'll leave the clock prepared one extra time.
>
> Specifically I'd expect: for UFS/PCIE the disable/unprepare should be
> symmetric with the enable/prepare and should be in "power off", not in
> exit.
>
> ...or did I miss something?
>
>
> Interestingly, your patch fixes this problem for USB3 (where init/exit
> are now symmetric), but leaves the problem there for UFS/PCIE.
>

Thanks for review.
One of the reason why pipe_clk is disabled as part of phy_exit is that
halt_check from clk_disable reports error if called after PHY has been
powered down or phy_exit.
I believe that warning should be ignored in qcom gcc-clock driver
(for applicable platforms) by using BRANCH_HALT_DELAY as halt_check
for pipe_clk and performing clk_disable from power_off for UFS/PCIE.

I can implement that as separate patch once dependent gcc driver
patch(es) gets in. Would that be ok?

-Manu

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v3 5/6] dt-bindings: phy-qcom-usb2: Update bindings for sdm845

2018-03-22 Thread Manu Gautam
Update compatible strings for USB2 PHYs on sdm845.
There are two QUSB2 PHYs present on sdm845. Few PHY registers
programming is different for these PHYs related to electrical
parameters, otherwise both are same.

Signed-off-by: Manu Gautam 
---
 Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt 
b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
index 42c9742..b99a57f 100644
--- a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
+++ b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
@@ -6,7 +6,9 @@ QUSB2 controller supports LS/FS/HS usb connectivity on Qualcomm 
chipsets.
 Required properties:
  - compatible: compatible list, contains
   "qcom,msm8996-qusb2-phy" for 14nm PHY on msm8996,
-  "qcom,qusb2-v2-phy" for QUSB2 V2 PHY.
+  "qcom,qusb2-v2-phy" for QUSB2 V2 PHY,
+  "qcom,sdm845-qusb2-phy-1" for primary PHY on sdm845,
+  "qcom,sdm845-qusb2-phy-2" for secondary PHY on sdm845.
 
  - reg: offset and length of the PHY register set.
  - #phy-cells: must be 0.
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v3 4/6] phy: qcom-qmp: Add QMP V3 USB3 UNI PHY support for sdm845

2018-03-22 Thread Manu Gautam
QMP V3 UNI PHY is a single lane USB3 PHY without support
for DisplayPort (DP).
Main difference from DP combo QMPv3 PHY is that UNI PHY
doesn't have dual RX/TX lanes and no separate DP_COM
block for configuration related to type-c or DP.
While at it, fix has_pwrdn_delay attribute for USB-DP
PHY configuration.

Reviewed-by: Evan Green 
Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 148 
 drivers/phy/qualcomm/phy-qcom-qmp.h |   5 ++
 2 files changed, 153 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 5d8df6a..d88331b 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -490,6 +490,118 @@ enum qphy_reg_layout {
QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
 };
 
+static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_serdes_tbl[] = {
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL2, 0x08),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x80),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x34),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x15),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x04),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_CFG, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x0a),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x31),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x85),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x07),
+};
+
+static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_tx_tbl[] = {
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0xc6),
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x06),
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x06),
+};
+
+static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_rx_tbl[] = {
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x0c),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x50),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1c),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
+};
+
+static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_pcs_tbl[] = {
+   /* FLL settings */
+   QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
+   QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
+   QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
+   QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40),
+   QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
+
+   /* Lock Det settings */
+   QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
+   QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2,

[PATCH v3 6/6] phy: qcom-qusb2: Add QUSB2 PHYs support for sdm845

2018-03-22 Thread Manu Gautam
There are two QUSB2 PHYs present on sdm845. Update PHY
registers programming for both the PHYs related to
electrical parameters to improve eye diagram.

Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qusb2.c | 39 +++
 1 file changed, 39 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c 
b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index 40fdef8..020cbb2 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -174,6 +174,27 @@ enum qusb2phy_reg_layout {
QUSB2_PHY_INIT_CFG(QUSB2PHY_CHG_CTRL2, 0x0),
 };
 
+static const struct qusb2_phy_init_tbl sdm845_init_tbl_1[] = {
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_ANALOG_CONTROLS_TWO, 0x03),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_CLOCK_INVERTERS, 0x7c),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_CMODE, 0x80),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_LOCK_DELAY, 0x0a),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_DIGITAL_TIMERS_TWO, 0x19),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_BIAS_CONTROL_1, 0x40),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_BIAS_CONTROL_2, 0x20),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_PWR_CTRL2, 0x21),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_IMP_CTRL1, 0x8),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_IMP_CTRL2, 0x58),
+
+   QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE1, 0x45),
+   QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE2, 0x29),
+   QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE3, 0xca),
+   QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE4, 0x04),
+   QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE5, 0x03),
+
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_CHG_CTRL2, 0x0),
+};
+
 struct qusb2_phy_cfg {
const struct qusb2_phy_init_tbl *tbl;
/* number of entries in the table */
@@ -220,6 +241,18 @@ struct qusb2_phy_cfg {
.autoresume_en= BIT(0),
 };
 
+static const struct qusb2_phy_cfg sdm845_phy_cfg_1 = {
+   .tbl= sdm845_init_tbl_1,
+   .tbl_num= ARRAY_SIZE(sdm845_init_tbl_1),
+   .regs   = qusb2_v2_regs_layout,
+
+   .disable_ctrl   = (PWR_CTRL1_VREF_SUPPLY_TRIM | PWR_CTRL1_CLAMP_N_EN |
+  POWER_DOWN),
+   .mask_core_ready = CORE_READY_STATUS,
+   .has_pll_override = true,
+   .autoresume_en= BIT(0),
+};
+
 static const char * const qusb2_phy_vreg_names[] = {
"vdda-pll", "vdda-phy-dpdm",
 };
@@ -649,6 +682,12 @@ static int qusb2_phy_exit(struct phy *phy)
}, {
.compatible = "qcom,qusb2-v2-phy",
.data   = &qusb2_v2_phy_cfg,
+   }, {
+   .compatible = "qcom,sdm845-qusb2-phy-1",
+   .data   = &sdm845_phy_cfg_1,
+   }, {
+   .compatible = "qcom,sdm845-qusb2-phy-2",
+   .data   = &qusb2_v2_phy_cfg,
},
{ },
 };
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v3 2/6] phy: qcom-qusb2: Fix crash if nvmem cell not specified

2018-03-22 Thread Manu Gautam
Driver currently crashes due to NULL pointer deference
while updating PHY tune register if nvmem cell is NULL.
Since, fused value for Tune1/2 register is optional,
we'd rather bail out.

Fixes: ca04d9d3e1b1 ("phy: qcom-qusb2: New driver for QUSB2 PHY on Qcom chips")
Reviewed-by: Vivek Gautam 
Cc: stable  # 4.14+
Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qusb2.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c 
b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index 94afeac..40fdef8 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -315,6 +315,10 @@ static void qusb2_phy_set_tune2_param(struct qusb2_phy 
*qphy)
const struct qusb2_phy_cfg *cfg = qphy->cfg;
u8 *val;
 
+   /* efuse register is optional */
+   if (!qphy->cell)
+   return;
+
/*
 * Read efuse register having TUNE2/1 parameter's high nibble.
 * If efuse register shows value as 0x0, or if we fail to find
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v3 3/6] dt-bindings: phy-qcom-qmp: Update bindings for sdm845

2018-03-22 Thread Manu Gautam
Update compatible strings for USB3 PHYs on SDM845.
One is QMPv3 DisplayPort-USB combo PHY and other one
is USB UNI PHY which is single lane USB3 PHY without
DP capability.

Reviewed-by: Rob Herring 
Signed-off-by: Manu Gautam 
---
 Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt 
b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
index dcf1b8f..cef8765 100644
--- a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
+++ b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
@@ -9,7 +9,9 @@ Required properties:
   "qcom,ipq8074-qmp-pcie-phy" for PCIe phy on IPQ8074
   "qcom,msm8996-qmp-pcie-phy" for 14nm PCIe phy on msm8996,
   "qcom,msm8996-qmp-usb3-phy" for 14nm USB3 phy on msm8996,
-  "qcom,qmp-v3-usb3-phy" for USB3 QMP V3 phy.
+  "qcom,qmp-v3-usb3-phy" for USB3 QMP V3 phy,
+  "qcom,sdm845-qmp-usb3-phy" for USB3 QMP V3 phy on sdm845,
+  "qcom,sdm845-qmp-usb3-uni-phy" for USB3 QMP V3 UNI phy on sdm845.
 
  - reg: offset and length of register set for PHY's common serdes block.
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v3 0/6] phy: qcom: Updates for USB PHYs on SDM845

2018-03-22 Thread Manu Gautam
SDM845 has two USB instances each with QUSB2 and QMP PHYs.
One of the QMP PHY is USB-DP (DisplayPort) combo PHY where
as other one is single lane UNI-PHY (without DP support).
Changes are related to PHY configuration for electrical
parameters tuning to improve eye-diagram and some fixes.

Changes since v2:
 - Use separate phy_ops for USB to not register power_on op.
 - And other minor changes as per review comments from Stephen.

Changes since v1:
 - Updated qusb2 compatibility name as per comment from Vivek.

Manu Gautam (6):
  phy: qcom-qmp: Enable pipe_clk before checking USB3 PHY_STATUS
  phy: qcom-qusb2: Fix crash if nvmem cell not specified
  dt-bindings: phy-qcom-qmp: Update bindings for sdm845
  phy: qcom-qmp: Add QMP V3 USB3 UNI PHY support for sdm845
  dt-bindings: phy-qcom-usb2: Update bindings for sdm845
  phy: qcom-qusb2: Add QUSB2 PHYs support for sdm845

 .../devicetree/bindings/phy/qcom-qmp-phy.txt   |   4 +-
 .../devicetree/bindings/phy/qcom-qusb2-phy.txt |   4 +-
 drivers/phy/qualcomm/phy-qcom-qmp.c| 181 -
 drivers/phy/qualcomm/phy-qcom-qmp.h|   5 +
 drivers/phy/qualcomm/phy-qcom-qusb2.c  |  43 +
 5 files changed, 234 insertions(+), 3 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v3 1/6] phy: qcom-qmp: Enable pipe_clk before checking USB3 PHY_STATUS

2018-03-22 Thread Manu Gautam
QMP PHY for USB mode requires pipe_clk for calibration and PLL lock
to take place. This clock is output from PHY to GCC clock_ctl and then
fed back to QMP PHY and is available from PHY only after PHY is reset
and initialized, hence it can't be enabled too early in initialization
sequence.

Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 33 -
 1 file changed, 32 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 6470c5d..5d8df6a 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -1008,6 +1008,19 @@ static int qcom_qmp_phy_init(struct phy *phy)
status = pcs + cfg->regs[QPHY_PCS_READY_STATUS];
mask = cfg->mask_pcs_ready;
 
+   /*
+* USB3 PHY requires pipe_clk for PLL lock and calibration.
+* Enable it from here for USB. For UFS/PCIE, it gets enabled
+* from poweron.
+*/
+   if (cfg->type == PHY_TYPE_USB3) {
+   ret = clk_prepare_enable(qphy->pipe_clk);
+   if (ret) {
+   dev_err(qmp->dev, "pipe_clk enable err=%d\n", ret);
+   goto err_clk_enable;
+   }
+   }
+
ret = readl_poll_timeout(status, val, !(val & mask), 1,
 PHY_INIT_COMPLETE_TIMEOUT);
if (ret) {
@@ -1019,6 +1032,9 @@ static int qcom_qmp_phy_init(struct phy *phy)
return ret;
 
 err_pcs_ready:
+   if (cfg->type == PHY_TYPE_USB3)
+   clk_disable_unprepare(qphy->pipe_clk);
+err_clk_enable:
if (cfg->has_lane_rst)
reset_control_assert(qphy->lane_rst);
 err_lane_rst:
@@ -1288,10 +1304,19 @@ static int phy_pipe_clk_register(struct qcom_qmp *qmp, 
struct device_node *np)
.owner  = THIS_MODULE,
 };
 
+/* USB PHY doesn't require power_on op */
+static const struct phy_ops qcom_qmp_usb_phy_gen_ops = {
+   .init   = qcom_qmp_phy_init,
+   .exit   = qcom_qmp_phy_exit,
+   .set_mode   = qcom_qmp_phy_set_mode,
+   .owner  = THIS_MODULE,
+};
+
 static
 int qcom_qmp_phy_create(struct device *dev, struct device_node *np, int id)
 {
struct qcom_qmp *qmp = dev_get_drvdata(dev);
+   const struct phy_ops *ops;
struct phy *generic_phy;
struct qmp_phy *qphy;
char prop_name[MAX_PROP_NAME];
@@ -1354,7 +1379,13 @@ int qcom_qmp_phy_create(struct device *dev, struct 
device_node *np, int id)
}
}
 
-   generic_phy = devm_phy_create(dev, np, &qcom_qmp_phy_gen_ops);
+   /* USB PHY doesn't use power_on op */
+   if (qmp->cfg->type == PHY_TYPE_USB3)
+   ops = &qcom_qmp_usb_phy_gen_ops;
+   else
+   ops = &qcom_qmp_phy_gen_ops;
+
+   generic_phy = devm_phy_create(dev, np, ops);
if (IS_ERR(generic_phy)) {
ret = PTR_ERR(generic_phy);
dev_err(dev, "failed to create qphy %d\n", ret);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v2 1/6] phy: qcom-qmp: Enable pipe_clk before checking USB3 PHY_STATUS

2018-03-22 Thread Manu Gautam
Hi Stephen,


On 3/23/2018 12:13 AM, Stephen Boyd wrote:
> Quoting Manu Gautam (2018-03-22 01:50:41)
>> QMP PHY for USB mode requires pipe_clk for calibration and PLL lock
>> to take place. This lock is output from PHY to GCC clock_ctl and then
> s/lock/clock/
Yes, will fix typo.
>> fed back to QMP PHY and is output from PHY only after PHY is reset
>> and initialized, hence it can't be enabled too early in initialization
>> sequence.
>>
>> Signed-off-by: Manu Gautam 
>> ---
>>  drivers/phy/qualcomm/phy-qcom-qmp.c | 18 ++
>>  1 file changed, 18 insertions(+)
>>
>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
>> b/drivers/phy/qualcomm/phy-qcom-qmp.c
>> index 6470c5d..73aa282 100644
>> --- a/drivers/phy/qualcomm/phy-qcom-qmp.c
>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
>> @@ -797,8 +797,13 @@ static int qcom_qmp_phy_poweron(struct phy *phy)
>>  {
>> struct qmp_phy *qphy = phy_get_drvdata(phy);
>> struct qcom_qmp *qmp = qphy->qmp;
>> +   const struct qmp_phy_cfg *cfg = qmp->cfg;
>> int ret;
>>  
>> +   /* Not needed for USB3 PHY as pipe_clk is enabled from phy_init */
>> +   if (cfg->type == PHY_TYPE_USB3)
>> +   return 0;
> Would be nice to not even assign phy_poweron when the PHY is USB3 type.
Yes, that should be better.

>
>> +
>> ret = clk_prepare_enable(qphy->pipe_clk);
>> if (ret)
>> dev_err(qmp->dev, "pipe_clk enable failed, err=%d\n", ret);
>> @@ -1008,6 +1013,19 @@ static int qcom_qmp_phy_init(struct phy *phy)
>> status = pcs + cfg->regs[QPHY_PCS_READY_STATUS];
>> mask = cfg->mask_pcs_ready;
>>  
>> +   /* USB3 PHY requires pipe_clk for PLL lock and calibration */
>> +   if (cfg->type == PHY_TYPE_USB3) {
>> +   ret = clk_prepare_enable(qphy->pipe_clk);
>> +   if (ret)
>> +   dev_err(qmp->dev, "pipe_clk enable err=%d\n", ret);
>> +   /*
>> +* Ignore this error as pipe_clk might take some time to get
>> +* enabled. In any case following check for PHY PLL lock 
>> would
>> +* timeout below if there is a fatal error and clock is not 
>> fed
>> +* to PHY
>> +*/
>> +
> This is odd. If clk_enable() fails then we don't keep parent clks (or
> the clk that's being operated on) up refcounted and enabled. How is that
> going to work?

I agree. My intent was to ignore only halt_check errors from clock driver.
In any case this condition (to ignore clk_enable error) should probably
be handled in clock driver. And I see that clock driver is already using
halt_check as BRANCH_HALT_DELAY, so I don't need to worry about that
in phy driver.



-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v2 5/6] dt-bindings: phy-qcom-usb2: Update bindings for sdm845

2018-03-22 Thread Manu Gautam
Update compatible strings for USB2 PHYs on sdm845.
There are two QUSB2 PHYs present on sdm845. Few PHY registers
programming is different for these PHYs related to electrical
parameters, otherwise both are same.

Signed-off-by: Manu Gautam 
---
 Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt 
b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
index 42c9742..b99a57f 100644
--- a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
+++ b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
@@ -6,7 +6,9 @@ QUSB2 controller supports LS/FS/HS usb connectivity on Qualcomm 
chipsets.
 Required properties:
  - compatible: compatible list, contains
   "qcom,msm8996-qusb2-phy" for 14nm PHY on msm8996,
-  "qcom,qusb2-v2-phy" for QUSB2 V2 PHY.
+  "qcom,qusb2-v2-phy" for QUSB2 V2 PHY,
+  "qcom,sdm845-qusb2-phy-1" for primary PHY on sdm845,
+  "qcom,sdm845-qusb2-phy-2" for secondary PHY on sdm845.
 
  - reg: offset and length of the PHY register set.
  - #phy-cells: must be 0.
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v2 4/6] phy: qcom-qmp: Add QMP V3 USB3 UNI PHY support for sdm845

2018-03-22 Thread Manu Gautam
QMP V3 UNI PHY is a single lane USB3 PHY without support
for DisplayPort (DP).
Main difference from DP combo QMPv3 PHY is that UNI PHY
doesn't have dual RX/TX lanes and no separate DP_COM
block for configuration related to type-c or DP.
While at it, fix has_pwrdn_delay attribute for USB-DP
PHY configuration.

Reviewed-by: Evan Green 
Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 148 
 drivers/phy/qualcomm/phy-qcom-qmp.h |   5 ++
 2 files changed, 153 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 73aa282..689951d 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -490,6 +490,118 @@ enum qphy_reg_layout {
QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
 };
 
+static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_serdes_tbl[] = {
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL2, 0x08),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x80),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x34),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x15),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x04),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_CFG, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x0a),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x31),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x85),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x07),
+};
+
+static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_tx_tbl[] = {
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0xc6),
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x06),
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x06),
+};
+
+static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_rx_tbl[] = {
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x0c),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x50),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1c),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
+};
+
+static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_pcs_tbl[] = {
+   /* FLL settings */
+   QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
+   QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
+   QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
+   QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40),
+   QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
+
+   /* Lock Det settings */
+   QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
+   QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2,

[PATCH v2 6/6] phy: qcom-qusb2: Add QUSB2 PHYs support for sdm845

2018-03-22 Thread Manu Gautam
There are two QUSB2 PHYs present on sdm845. Update PHY
registers programming for both the PHYs related to
electrical parameters to improve eye diagram.

Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qusb2.c | 39 +++
 1 file changed, 39 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c 
b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index 40fdef8..020cbb2 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -174,6 +174,27 @@ enum qusb2phy_reg_layout {
QUSB2_PHY_INIT_CFG(QUSB2PHY_CHG_CTRL2, 0x0),
 };
 
+static const struct qusb2_phy_init_tbl sdm845_init_tbl_1[] = {
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_ANALOG_CONTROLS_TWO, 0x03),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_CLOCK_INVERTERS, 0x7c),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_CMODE, 0x80),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_LOCK_DELAY, 0x0a),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_DIGITAL_TIMERS_TWO, 0x19),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_BIAS_CONTROL_1, 0x40),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_BIAS_CONTROL_2, 0x20),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_PWR_CTRL2, 0x21),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_IMP_CTRL1, 0x8),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_IMP_CTRL2, 0x58),
+
+   QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE1, 0x45),
+   QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE2, 0x29),
+   QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE3, 0xca),
+   QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE4, 0x04),
+   QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE5, 0x03),
+
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_CHG_CTRL2, 0x0),
+};
+
 struct qusb2_phy_cfg {
const struct qusb2_phy_init_tbl *tbl;
/* number of entries in the table */
@@ -220,6 +241,18 @@ struct qusb2_phy_cfg {
.autoresume_en= BIT(0),
 };
 
+static const struct qusb2_phy_cfg sdm845_phy_cfg_1 = {
+   .tbl= sdm845_init_tbl_1,
+   .tbl_num= ARRAY_SIZE(sdm845_init_tbl_1),
+   .regs   = qusb2_v2_regs_layout,
+
+   .disable_ctrl   = (PWR_CTRL1_VREF_SUPPLY_TRIM | PWR_CTRL1_CLAMP_N_EN |
+  POWER_DOWN),
+   .mask_core_ready = CORE_READY_STATUS,
+   .has_pll_override = true,
+   .autoresume_en= BIT(0),
+};
+
 static const char * const qusb2_phy_vreg_names[] = {
"vdda-pll", "vdda-phy-dpdm",
 };
@@ -649,6 +682,12 @@ static int qusb2_phy_exit(struct phy *phy)
}, {
.compatible = "qcom,qusb2-v2-phy",
.data   = &qusb2_v2_phy_cfg,
+   }, {
+   .compatible = "qcom,sdm845-qusb2-phy-1",
+   .data   = &sdm845_phy_cfg_1,
+   }, {
+   .compatible = "qcom,sdm845-qusb2-phy-2",
+   .data   = &qusb2_v2_phy_cfg,
},
{ },
 };
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v2 2/6] phy: qcom-qusb2: Fix crash if nvmem cell not specified

2018-03-22 Thread Manu Gautam
Driver currently crashes due to NULL pointer deference
while updating PHY tune register if nvmem cell is NULL.
Since, fused value for Tune1/2 register is optional,
we'd rather bail out.

Fixes: ca04d9d3e1b1 ("phy: qcom-qusb2: New driver for QUSB2 PHY on Qcom chips")
Reviewed-by: Vivek Gautam 
Cc: stable  # 4.14+
Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qusb2.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c 
b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index 94afeac..40fdef8 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -315,6 +315,10 @@ static void qusb2_phy_set_tune2_param(struct qusb2_phy 
*qphy)
const struct qusb2_phy_cfg *cfg = qphy->cfg;
u8 *val;
 
+   /* efuse register is optional */
+   if (!qphy->cell)
+   return;
+
/*
 * Read efuse register having TUNE2/1 parameter's high nibble.
 * If efuse register shows value as 0x0, or if we fail to find
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v2 3/6] dt-bindings: phy-qcom-qmp: Update bindings for sdm845

2018-03-22 Thread Manu Gautam
Update compatible strings for USB3 PHYs on SDM845.
One is QMPv3 DisplayPort-USB combo PHY and other one
is USB UNI PHY which is single lane USB3 PHY without
DP capability.

Reviewed-by: Rob Herring 
Signed-off-by: Manu Gautam 
---
 Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt 
b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
index dcf1b8f..cef8765 100644
--- a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
+++ b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
@@ -9,7 +9,9 @@ Required properties:
   "qcom,ipq8074-qmp-pcie-phy" for PCIe phy on IPQ8074
   "qcom,msm8996-qmp-pcie-phy" for 14nm PCIe phy on msm8996,
   "qcom,msm8996-qmp-usb3-phy" for 14nm USB3 phy on msm8996,
-  "qcom,qmp-v3-usb3-phy" for USB3 QMP V3 phy.
+  "qcom,qmp-v3-usb3-phy" for USB3 QMP V3 phy,
+  "qcom,sdm845-qmp-usb3-phy" for USB3 QMP V3 phy on sdm845,
+  "qcom,sdm845-qmp-usb3-uni-phy" for USB3 QMP V3 UNI phy on sdm845.
 
  - reg: offset and length of register set for PHY's common serdes block.
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v2 1/6] phy: qcom-qmp: Enable pipe_clk before checking USB3 PHY_STATUS

2018-03-22 Thread Manu Gautam
QMP PHY for USB mode requires pipe_clk for calibration and PLL lock
to take place. This lock is output from PHY to GCC clock_ctl and then
fed back to QMP PHY and is output from PHY only after PHY is reset
and initialized, hence it can't be enabled too early in initialization
sequence.

Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 6470c5d..73aa282 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -797,8 +797,13 @@ static int qcom_qmp_phy_poweron(struct phy *phy)
 {
struct qmp_phy *qphy = phy_get_drvdata(phy);
struct qcom_qmp *qmp = qphy->qmp;
+   const struct qmp_phy_cfg *cfg = qmp->cfg;
int ret;
 
+   /* Not needed for USB3 PHY as pipe_clk is enabled from phy_init */
+   if (cfg->type == PHY_TYPE_USB3)
+   return 0;
+
ret = clk_prepare_enable(qphy->pipe_clk);
if (ret)
dev_err(qmp->dev, "pipe_clk enable failed, err=%d\n", ret);
@@ -1008,6 +1013,19 @@ static int qcom_qmp_phy_init(struct phy *phy)
status = pcs + cfg->regs[QPHY_PCS_READY_STATUS];
mask = cfg->mask_pcs_ready;
 
+   /* USB3 PHY requires pipe_clk for PLL lock and calibration */
+   if (cfg->type == PHY_TYPE_USB3) {
+   ret = clk_prepare_enable(qphy->pipe_clk);
+   if (ret)
+   dev_err(qmp->dev, "pipe_clk enable err=%d\n", ret);
+   /*
+* Ignore this error as pipe_clk might take some time to get
+* enabled. In any case following check for PHY PLL lock would
+* timeout below if there is a fatal error and clock is not fed
+* to PHY
+*/
+   }
+
ret = readl_poll_timeout(status, val, !(val & mask), 1,
 PHY_INIT_COMPLETE_TIMEOUT);
if (ret) {
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v2 0/6] phy: qcom: Updates for USB PHYs on SDM845

2018-03-22 Thread Manu Gautam
SDM845 has two USB instances each with QUSB2 and QMP PHYs.
One of the QMP PHY is USB-DP (DisplayPort) combo PHY where
as other one is single lane UNI-PHY (without DP support).
Changes are related to PHY configuration for electrical
parameters tuning to improve eye-diagram and some fixes.

Changes since v1:
 - Updated qusb2 compatibility name as per comment from Vivek.

Manu Gautam (6):
  phy: qcom-qmp: Enable pipe_clk before checking USB3 PHY_STATUS
  phy: qcom-qusb2: Fix crash if nvmem cell not specified
  dt-bindings: phy-qcom-qmp: Update bindings for sdm845
  phy: qcom-qmp: Add QMP V3 USB3 UNI PHY support for sdm845
  dt-bindings: phy-qcom-usb2: Update bindings for sdm845
  phy: qcom-qusb2: Add QUSB2 PHYs support for sdm845

 .../devicetree/bindings/phy/qcom-qmp-phy.txt   |   4 +-
 .../devicetree/bindings/phy/qcom-qusb2-phy.txt |   4 +-
 drivers/phy/qualcomm/phy-qcom-qmp.c| 166 +
 drivers/phy/qualcomm/phy-qcom-qmp.h|   5 +
 drivers/phy/qualcomm/phy-qcom-qusb2.c  |  43 ++
 5 files changed, 220 insertions(+), 2 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v1 1/2] phy: Add QMP phy based UFS phy support for sdm845

2018-03-20 Thread Manu Gautam
Hi Can,


On 3/21/2018 8:12 AM, c...@codeaurora.org wrote:
> On 2018-03-20 19:30, Can Guo wrote:
>> Add UFS PHY support to make SDM845 UFS work with common PHY framework.
>>
>> Signed-off-by: Can Guo 
>> ---
>>  drivers/phy/qualcomm/phy-qcom-qmp.c | 120 
>> +++-
>>  drivers/phy/qualcomm/phy-qcom-qmp.h |   8 +++
>>  2 files changed, 126 insertions(+), 2 deletions(-)
>>
[snip]
>> +    /* true, if PCS block has a separate SW_RESET register */
>> +    bool has_sw_rst;
>>  };
>>

You should set this for qmp_v3_usb3_uniphy_cfg as well.
Please also mention dependency on my patches [1] and [2] in your cover letter

[1] 
http://lists-archives.com/linux-kernel/29071659-dt-bindings-phy-qcom-qmp-update-bindings-for-sdm845.html
[2] 
lists-archives.com/linux-kernel/29071660-phy-qcom-qmp-add-qmp-v3-usb3-uni-phy-support-for-sdm845.html


>>  /**
>> @@ -636,6 +712,10 @@ static inline void qphy_clrbits(void __iomem
>> *base, u32 offset, u32 val)
>>  "aux", "cfg_ahb", "ref", "com_aux",
>>  };
>>
>> +static const char * const sdm845_ufs_phy_clk_l[] = {
>> +    "ref_clk", "ref_aux_clk",
>> +};
>> +
>>  /* list of resets */
>>  static const char * const msm8996_pciephy_reset_l[] = {
>>  "phy", "common", "cfg",
>> @@ -650,6 +730,10 @@ static inline void qphy_clrbits(void __iomem
>> *base, u32 offset, u32 val)
>>  "vdda-phy", "vdda-pll",
>>  };
>>
>> +static const char * const sdm845_phy_vreg_l[] = {
>> +    "vdda-phy", "vdda-pll",
>> +};
>> +
>>  static const struct qmp_phy_cfg msm8996_pciephy_cfg = {
>>  .type    = PHY_TYPE_PCIE,
>>  .nlanes    = 3,
>> @@ -679,6 +763,7 @@ static inline void qphy_clrbits(void __iomem
>> *base, u32 offset, u32 val)
>>  .has_pwrdn_delay    = true,
>>  .pwrdn_delay_min    = POWER_DOWN_DELAY_US_MIN,
>>  .pwrdn_delay_max    = POWER_DOWN_DELAY_US_MAX,
>> +    .has_sw_rst    = true,
>>  };
>>
>>  static const struct qmp_phy_cfg msm8996_usb3phy_cfg = {
>> @@ -704,6 +789,7 @@ static inline void qphy_clrbits(void __iomem
>> *base, u32 offset, u32 val)
>>  .start_ctrl    = SERDES_START | PCS_START,
>>  .pwrdn_ctrl    = SW_PWRDN,
>>  .mask_pcs_ready    = PHYSTATUS,
>> +    .has_sw_rst    = true,
>>  };
>>
>>  /* list of resets */
>> @@ -740,6 +826,7 @@ static inline void qphy_clrbits(void __iomem
>> *base, u32 offset, u32 val)
>>  .has_pwrdn_delay    = true,
>>  .pwrdn_delay_min    = 995,    /* us */
>>  .pwrdn_delay_max    = 1005,    /* us */
>> +    .has_sw_rst    = true,
>>  };
>>
>>  static const struct qmp_phy_cfg qmp_v3_usb3phy_cfg = {
>> @@ -772,6 +859,30 @@ static inline void qphy_clrbits(void __iomem
>> *base, u32 offset, u32 val)
>>  .has_phy_dp_com_ctrl    = true,
>>  .tx_b_lane_offset    = 0x400,
>>  .rx_b_lane_offset    = 0x400,
>> +    .has_sw_rst    = true,
>> +};
>> +
>> +static const struct qmp_phy_cfg sdm845_ufsphy_cfg = {
>> +    .type    = PHY_TYPE_UFS,
>> +    .nlanes    = 2,
>> +
>> +    .serdes_tbl    = sdm845_ufsphy_serdes_tbl,
>> +    .serdes_tbl_num    = ARRAY_SIZE(sdm845_ufsphy_serdes_tbl),
>> +    .tx_tbl    = sdm845_ufsphy_tx_tbl,
>> +    .tx_tbl_num    = ARRAY_SIZE(sdm845_ufsphy_tx_tbl),
>> +    .rx_tbl    = sdm845_ufsphy_rx_tbl,
>> +    .rx_tbl_num    = ARRAY_SIZE(sdm845_ufsphy_rx_tbl),
>> +    .pcs_tbl    = sdm845_ufsphy_pcs_tbl,
>> +    .pcs_tbl_num    = ARRAY_SIZE(sdm845_ufsphy_pcs_tbl),
>> +    .clk_list    = sdm845_ufs_phy_clk_l,
>> +    .num_clks    = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
>> +    .vreg_list    = sdm845_phy_vreg_l,
>> +    .num_vregs    = ARRAY_SIZE(sdm845_phy_vreg_l),
>> +    .regs    = sdm845_ufsphy_regs_layout,
>> +
>> +    .start_ctrl    = SERDES_START,
>> +    .pwrdn_ctrl    = SW_PWRDN,
>> +    .mask_pcs_ready    = PCS_READY,
>>  };
>>
>>  static void qcom_qmp_phy_configure(void __iomem *base,
>> @@ -998,7 +1109,8 @@ static int qcom_qmp_phy_init(struct phy *phy)
>>  usleep_range(cfg->pwrdn_delay_min, cfg->pwrdn_delay_max);
>>
>>  /* Pull PHY out of reset state */
>> -    qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
>> +    if (cfg->has_sw_rst)
>> +    qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
>>  if (cfg->has_phy_dp_com_ctrl)
>>  qphy_clrbits(dp_com, QPHY_V3_DP_COM_SW_RESET, SW_RESET);
>>
>> @@ -1036,7 +1148,8 @@ static int qcom_qmp_phy_exit(struct phy *phy)
>>  clk_disable_unprepare(qphy->pipe_clk);
>>
>>  /* PHY reset */
>> -    qphy_setbits(qphy->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
>> +    if (cfg->has_sw_rst)
>> +    qphy_setbits(qphy->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
>>
>>  /* stop SerDes and Phy-Coding-Sublayer */
>>  qphy_clrbits(qphy->pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
>> @@ -1383,6 +1496,9 @@ int qcom_qmp_phy_create(struct device *dev,
>> struct device_node *np, int id)
>>  }, {
>>  .compatible

Re: [PATCH 5/6] dt-bindings: phy-qcom-usb2: Update bindings for sdm845

2018-03-20 Thread Manu Gautam
Hi,


On 3/20/2018 3:53 PM, Vivek Gautam wrote:
> Hi Manu,
>
>
> On 3/16/2018 3:14 PM, Manu Gautam wrote:
>> Update compatible strings for USB2 PHYs on sdm845.
>> There are two QUSB2 PHYs present on sdm845. Few PHY registers
>> programming is different for these PHYs related to electrical
>> parameters, otherwise both are same.
>>
>> Signed-off-by: Manu Gautam 
>> ---
>>   Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt | 4 +++-
>>   1 file changed, 3 insertions(+), 1 deletion(-)
>>
>> diff --git a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt 
>> b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
>> index 42c9742..20deaeb 100644
>> --- a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
>> +++ b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
>> @@ -6,7 +6,9 @@ QUSB2 controller supports LS/FS/HS usb connectivity on 
>> Qualcomm chipsets.
>>   Required properties:
>>    - compatible: compatible list, contains
>>  "qcom,msm8996-qusb2-phy" for 14nm PHY on msm8996,
>> -   "qcom,qusb2-v2-phy" for QUSB2 V2 PHY.
>> +   "qcom,qusb2-v2-phy" for QUSB2 V2 PHY,
>> +   "qcom,sdm845-1-qusb2-phy" for primary PHY on sdm845,
>> +   "qcom,sdm845-2-qusb2-phy" for secondary PHY on sdm845.
>
> Thanks for the patch.
>
> "qcom,sdm845-1/2-qusb2-phy" gives an impression that it is different versions 
> of SoC,
> and not like two numbers of phy.
> May be - "qcom,sdm845-qusb2-phy-1/2"

I agree with that. Will update.

>
> Regards
> Vivek
>  
>
>>      - reg: offset and length of the PHY register set.
>>    - #phy-cells: must be 0.
>

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH 4/6] phy: qcom-qmp: Add QMP V3 USB3 UNI PHY support for sdm845

2018-03-20 Thread Manu Gautam
Hi,


On 3/19/2018 11:21 PM, Evan Green wrote:
> Hi Manu,
>
> On Fri, Mar 16, 2018 at 2:46 AM Manu Gautam  wrote:
[snip]
>> index d1c6905..5d78d43 100644
>> --- a/drivers/phy/qualcomm/phy-qcom-qmp.h
>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp.h
>> @@ -214,6 +214,8 @@
>>   #define QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN0x030
>>   #define QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE0x034
>>   #define QSERDES_V3_RX_RX_TERM_BW   0x07c
>> +#define QSERDES_V3_RX_VGA_CAL_CNTRL1   0x0bc
> I noticed you add this definition, but never use it. Are you missing a
> QMP_PHY_INIT_CFG line for this register in qmp_v3_usb3_uniphy_rx_tbl[], or
> is that register "don't care"? It looks important, and while its default
> value out of reset might be valid, you never know what nutty value boot
> firmware might set it to.
>

Yes POR value of this register is valid for this soc.
QMP driver resets (asserts and de-asserts reset_control) in probe. So, that 
should
ensure that PHY registers are indeed set to POR value. Left the definition there
if different setting needed to be done for a different variant of h/w in future.

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v2] phy: core: Allow phy_pm_runtime_xxx API calls with NULL phy

2018-03-19 Thread Manu Gautam
phy_init() and phy_exit() calls, and phy_power_on() and
phy_power_off() already accept NULL as valid PHY reference
and act as NOP. Extend same concept to phy runtime_pm APIs
to keep drivers (e.g. dwc3) code simple while dealing with
optional PHYs.

Signed-off-by: Manu Gautam 
---
Changes for v2:
 - Fixed compilation warning

 drivers/phy/phy-core.c | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index 3c31ce5..1fda576 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -153,6 +153,9 @@ int phy_pm_runtime_get(struct phy *phy)
 {
int ret;
 
+   if (!phy)
+   return 0;
+
if (!pm_runtime_enabled(&phy->dev))
return -ENOTSUPP;
 
@@ -168,6 +171,9 @@ int phy_pm_runtime_get_sync(struct phy *phy)
 {
int ret;
 
+   if (!phy)
+   return 0;
+
if (!pm_runtime_enabled(&phy->dev))
return -ENOTSUPP;
 
@@ -181,6 +187,9 @@ int phy_pm_runtime_get_sync(struct phy *phy)
 
 int phy_pm_runtime_put(struct phy *phy)
 {
+   if (!phy)
+   return 0;
+
if (!pm_runtime_enabled(&phy->dev))
return -ENOTSUPP;
 
@@ -190,6 +199,9 @@ int phy_pm_runtime_put(struct phy *phy)
 
 int phy_pm_runtime_put_sync(struct phy *phy)
 {
+   if (!phy)
+   return 0;
+
if (!pm_runtime_enabled(&phy->dev))
return -ENOTSUPP;
 
@@ -199,6 +211,9 @@ int phy_pm_runtime_put_sync(struct phy *phy)
 
 void phy_pm_runtime_allow(struct phy *phy)
 {
+   if (!phy)
+   return;
+
if (!pm_runtime_enabled(&phy->dev))
return;
 
@@ -208,6 +223,9 @@ void phy_pm_runtime_allow(struct phy *phy)
 
 void phy_pm_runtime_forbid(struct phy *phy)
 {
+   if (!phy)
+   return;
+
if (!pm_runtime_enabled(&phy->dev))
return;
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH 5/6] dt-bindings: phy-qcom-usb2: Update bindings for sdm845

2018-03-18 Thread Manu Gautam
Hi,


On 3/18/2018 6:22 PM, Rob Herring wrote:
> On Fri, Mar 16, 2018 at 03:14:58PM +0530, Manu Gautam wrote:
>> Update compatible strings for USB2 PHYs on sdm845.
>> There are two QUSB2 PHYs present on sdm845. Few PHY registers
>> programming is different for these PHYs related to electrical
>> parameters, otherwise both are same.
> Register locations are different or tuning values are different? For the 
> latter, is that something that could be DT properties?

There are only register values changes. Corresponding driver change:
https://patchwork.kernel.org/patch/10286803/


-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v1 1/2] dt-bindings: usb: Update documentation for Qualcomm DWC3 driver

2018-03-18 Thread Manu Gautam
Hi,


On 3/18/2018 6:19 PM, Rob Herring wrote:
> On Tue, Mar 13, 2018 at 04:06:00PM +0530, Manu Gautam wrote:
>> Existing documentation has lot of incorrect information as it
>> was originally added for a driver that no longer exists.
>>
>> Signed-off-by: Manu Gautam 
>> ---
>>  .../devicetree/bindings/usb/qcom,dwc3.txt  | 87 
>> +++---
>>  1 file changed, 59 insertions(+), 28 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/usb/qcom,dwc3.txt 
>> b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
>> index bc8a2fa..df312f7 100644
>> --- a/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
>> +++ b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
>> @@ -1,54 +1,85 @@
>>  Qualcomm SuperSpeed DWC3 USB SoC controller
>>  
>>  Required properties:
>> -- compatible:   should contain "qcom,dwc3"
>> -- clocks:   A list of phandle + clock-specifier pairs for the
>> -clocks listed in clock-names
>> -- clock-names:  Should contain the following:
>> -  "core"Master/Core clock, have to be >= 125 MHz for SS
>> -operation and >= 60MHz for HS operation
>> -
>> -Optional clocks:
>> -  "iface"   System bus AXI clock.  Not present on all platforms
>> -  "sleep"   Sleep clock, used when USB3 core goes into low
>> -power mode (U3).
>> +- compatible:   should contain "qcom,dwc3"
>> +- reg:  offset and length of register set for QSCRATCH 
>> wrapper
>> +- reg-names:should be "qscratch"
> reg-names is pointless for a single range.
Ok. Will change this.

>
>> +- power-domains:specifies a phandle to PM domain provider node
>> +- clocks:   list of phandle + clock-specifier pairs
> How many clocks and what are they?
I will add description of the clocks in next version of patchset.


>
>> +- assigned-clocks:  should be:
>> +MOCK_UTMI_CLK
>> +MASTER_CLK
>> +- assigned-clock-rates: should be:
>> +19.2Mhz (19200) for MOCK_UTMI_CLK
>> +>=125Mhz (12500) for MASTER_CLK in SS 
>> mode
>> +>=60Mhz (6000) for MASTER_CLK in HS mode
>> +
>> +Optional properties:
>> +- resets:   list of phandle and reset specifier pairs
>> +- interrupts:   specifies interrupts from controller wrapper 
>> used
>> +to wakeup from low power/susepnd state. Must contain
>> +one or more entry for interrupt-names property
>> +- interrupt-names:  Must include the following entries:
>> +- "hs_phy_irq": The interrupt that is asserted when a
>> +   wakeup event is received on USB2 bus
>> +- "ss_phy_irq": The interrupt that is asserted when a
>> +   wakeup event is received on USB3 bus
>> +- "dm_hs_phy_irq" and "dp_hs_phy_irq": Separate
>> +   interrupts for any wakeup event on DM and DP lines
>> +- qcom,select-utmi-as-pipe-clk: if present, disable USB3 pipe_clk 
>> requirement.
>> +Used when dwc3 operates without SSPHY and only
>> +HS/FS/LS modes are supported.
>>  
>>  Required child node:
>>  A child node must exist to represent the core DWC3 IP block. The name of
>>  the node is not important. The content of the node is defined in dwc3.txt.
>>  
>>  Phy documentation is provided in the following places:
>> -Documentation/devicetree/bindings/phy/qcom-dwc3-usb-phy.txt
>> +Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt   - USB3 QMP PHY
>> +Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt - USB2 QUSB2 PHY

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH 5/6] dt-bindings: phy-qcom-usb2: Update bindings for sdm845

2018-03-16 Thread Manu Gautam
Update compatible strings for USB2 PHYs on sdm845.
There are two QUSB2 PHYs present on sdm845. Few PHY registers
programming is different for these PHYs related to electrical
parameters, otherwise both are same.

Signed-off-by: Manu Gautam 
---
 Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt 
b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
index 42c9742..20deaeb 100644
--- a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
+++ b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
@@ -6,7 +6,9 @@ QUSB2 controller supports LS/FS/HS usb connectivity on Qualcomm 
chipsets.
 Required properties:
  - compatible: compatible list, contains
   "qcom,msm8996-qusb2-phy" for 14nm PHY on msm8996,
-  "qcom,qusb2-v2-phy" for QUSB2 V2 PHY.
+  "qcom,qusb2-v2-phy" for QUSB2 V2 PHY,
+  "qcom,sdm845-1-qusb2-phy" for primary PHY on sdm845,
+  "qcom,sdm845-2-qusb2-phy" for secondary PHY on sdm845.
 
  - reg: offset and length of the PHY register set.
  - #phy-cells: must be 0.
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH 6/6] phy: qcom-qusb2: Add QUSB2 PHYs support for sdm845

2018-03-16 Thread Manu Gautam
There are two QUSB2 PHYs present on sdm845. Update PHY
registers programming for both the PHYs related to
electrical parameters to improve eye diagram.

Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qusb2.c | 39 +++
 1 file changed, 39 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c 
b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index 40fdef8..1a608a9 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -174,6 +174,27 @@ enum qusb2phy_reg_layout {
QUSB2_PHY_INIT_CFG(QUSB2PHY_CHG_CTRL2, 0x0),
 };
 
+static const struct qusb2_phy_init_tbl sdm845_init_tbl_1[] = {
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_ANALOG_CONTROLS_TWO, 0x03),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_CLOCK_INVERTERS, 0x7c),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_CMODE, 0x80),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_LOCK_DELAY, 0x0a),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_DIGITAL_TIMERS_TWO, 0x19),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_BIAS_CONTROL_1, 0x40),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_BIAS_CONTROL_2, 0x20),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_PWR_CTRL2, 0x21),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_IMP_CTRL1, 0x8),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_IMP_CTRL2, 0x58),
+
+   QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE1, 0x45),
+   QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE2, 0x29),
+   QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE3, 0xca),
+   QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE4, 0x04),
+   QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE5, 0x03),
+
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_CHG_CTRL2, 0x0),
+};
+
 struct qusb2_phy_cfg {
const struct qusb2_phy_init_tbl *tbl;
/* number of entries in the table */
@@ -220,6 +241,18 @@ struct qusb2_phy_cfg {
.autoresume_en= BIT(0),
 };
 
+static const struct qusb2_phy_cfg sdm845_phy_cfg_1 = {
+   .tbl= sdm845_init_tbl_1,
+   .tbl_num= ARRAY_SIZE(sdm845_init_tbl_1),
+   .regs   = qusb2_v2_regs_layout,
+
+   .disable_ctrl   = (PWR_CTRL1_VREF_SUPPLY_TRIM | PWR_CTRL1_CLAMP_N_EN |
+  POWER_DOWN),
+   .mask_core_ready = CORE_READY_STATUS,
+   .has_pll_override = true,
+   .autoresume_en= BIT(0),
+};
+
 static const char * const qusb2_phy_vreg_names[] = {
"vdda-pll", "vdda-phy-dpdm",
 };
@@ -649,6 +682,12 @@ static int qusb2_phy_exit(struct phy *phy)
}, {
.compatible = "qcom,qusb2-v2-phy",
.data   = &qusb2_v2_phy_cfg,
+   }, {
+   .compatible = "qcom,sdm845-1-qusb2-phy",
+   .data   = &sdm845_phy_cfg_1,
+   }, {
+   .compatible = "qcom,sdm845-2-qusb2-phy",
+   .data   = &qusb2_v2_phy_cfg,
},
{ },
 };
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH 4/6] phy: qcom-qmp: Add QMP V3 USB3 UNI PHY support for sdm845

2018-03-16 Thread Manu Gautam
QMP V3 UNI PHY is a single lane USB3 PHY without support
for DisplayPort (DP).
Main difference from DP combo QMPv3 PHY is that UNI PHY
doesn't have dual RX/TX lanes and no separate DP_COM
block for configuration related to type-c or DP.
While at it, fix has_pwrdn_delay attribute for USB-DP
PHY configuration.

Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 148 
 drivers/phy/qualcomm/phy-qcom-qmp.h |   5 ++
 2 files changed, 153 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 73aa282..689951d 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -490,6 +490,118 @@ enum qphy_reg_layout {
QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
 };
 
+static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_serdes_tbl[] = {
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL2, 0x08),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x80),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x34),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x15),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x04),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_CFG, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x0a),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x31),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x85),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x07),
+};
+
+static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_tx_tbl[] = {
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0xc6),
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x06),
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x06),
+};
+
+static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_rx_tbl[] = {
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x0c),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x50),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1c),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
+};
+
+static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_pcs_tbl[] = {
+   /* FLL settings */
+   QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
+   QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
+   QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
+   QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40),
+   QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
+
+   /* Lock Det settings */
+   QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
+   QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
+   QMP_PHY_INI

[PATCH 3/6] dt-bindings: phy-qcom-qmp: Update bindings for sdm845

2018-03-16 Thread Manu Gautam
Update compatible strings for USB3 PHYs on SDM845.
One is QMPv3 DisplayPort-USB combo PHY and other one
is USB UNI PHY which is single lane USB3 PHY without
DP capability.

Signed-off-by: Manu Gautam 
---
 Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt 
b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
index dcf1b8f..cef8765 100644
--- a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
+++ b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
@@ -9,7 +9,9 @@ Required properties:
   "qcom,ipq8074-qmp-pcie-phy" for PCIe phy on IPQ8074
   "qcom,msm8996-qmp-pcie-phy" for 14nm PCIe phy on msm8996,
   "qcom,msm8996-qmp-usb3-phy" for 14nm USB3 phy on msm8996,
-  "qcom,qmp-v3-usb3-phy" for USB3 QMP V3 phy.
+  "qcom,qmp-v3-usb3-phy" for USB3 QMP V3 phy,
+  "qcom,sdm845-qmp-usb3-phy" for USB3 QMP V3 phy on sdm845,
+  "qcom,sdm845-qmp-usb3-uni-phy" for USB3 QMP V3 UNI phy on sdm845.
 
  - reg: offset and length of register set for PHY's common serdes block.
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH 1/6] phy: qcom-qmp: Enable pipe_clk before checking USB3 PHY_STATUS

2018-03-16 Thread Manu Gautam
QMP PHY for USB mode requires pipe_clk for calibration and PLL lock
to take place. This lock is output from PHY to GCC clock_ctl and then
fed back to QMP PHY and is output from PHY only after PHY is reset
and initialized, hence it can't be enabled too early in initialization
sequence.

Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 6470c5d..73aa282 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -797,8 +797,13 @@ static int qcom_qmp_phy_poweron(struct phy *phy)
 {
struct qmp_phy *qphy = phy_get_drvdata(phy);
struct qcom_qmp *qmp = qphy->qmp;
+   const struct qmp_phy_cfg *cfg = qmp->cfg;
int ret;
 
+   /* Not needed for USB3 PHY as pipe_clk is enabled from phy_init */
+   if (cfg->type == PHY_TYPE_USB3)
+   return 0;
+
ret = clk_prepare_enable(qphy->pipe_clk);
if (ret)
dev_err(qmp->dev, "pipe_clk enable failed, err=%d\n", ret);
@@ -1008,6 +1013,19 @@ static int qcom_qmp_phy_init(struct phy *phy)
status = pcs + cfg->regs[QPHY_PCS_READY_STATUS];
mask = cfg->mask_pcs_ready;
 
+   /* USB3 PHY requires pipe_clk for PLL lock and calibration */
+   if (cfg->type == PHY_TYPE_USB3) {
+   ret = clk_prepare_enable(qphy->pipe_clk);
+   if (ret)
+   dev_err(qmp->dev, "pipe_clk enable err=%d\n", ret);
+   /*
+* Ignore this error as pipe_clk might take some time to get
+* enabled. In any case following check for PHY PLL lock would
+* timeout below if there is a fatal error and clock is not fed
+* to PHY
+*/
+   }
+
ret = readl_poll_timeout(status, val, !(val & mask), 1,
 PHY_INIT_COMPLETE_TIMEOUT);
if (ret) {
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH 2/6] phy: qcom-qusb2: Fix crash if nvmem cell not specified

2018-03-16 Thread Manu Gautam
Driver currently crashes due to NULL pointer deference
while updating PHY tune register if nvmem cell is NULL.
Since, fused value for Tune1/2 register is optional,
we'd rather bail out.

Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qusb2.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c 
b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index 94afeac..40fdef8 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -315,6 +315,10 @@ static void qusb2_phy_set_tune2_param(struct qusb2_phy 
*qphy)
const struct qusb2_phy_cfg *cfg = qphy->cfg;
u8 *val;
 
+   /* efuse register is optional */
+   if (!qphy->cell)
+   return;
+
/*
 * Read efuse register having TUNE2/1 parameter's high nibble.
 * If efuse register shows value as 0x0, or if we fail to find
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH] phy: core: Allow phy_pm_runtime_xxx API calls with NULL phy

2018-03-16 Thread Manu Gautam
phy_init() and phy_exit() calls, and phy_power_on() and
phy_power_off() already accept NULL as valid PHY refernece
and act as NOP. Extend same concept to phy runtime_pm APIs
to keep drivers (e.g. dwc3) code simple while dealing with
optional PHYs.

Signed-off-by: Manu Gautam 
---
 drivers/phy/phy-core.c | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index 09ac8af..48b9615 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -153,6 +153,9 @@ int phy_pm_runtime_get(struct phy *phy)
 {
int ret;
 
+   if (!phy)
+   return 0;
+
if (!pm_runtime_enabled(&phy->dev))
return -ENOTSUPP;
 
@@ -168,6 +171,9 @@ int phy_pm_runtime_get_sync(struct phy *phy)
 {
int ret;
 
+   if (!phy)
+   return 0;
+
if (!pm_runtime_enabled(&phy->dev))
return -ENOTSUPP;
 
@@ -181,6 +187,9 @@ int phy_pm_runtime_get_sync(struct phy *phy)
 
 int phy_pm_runtime_put(struct phy *phy)
 {
+   if (!phy)
+   return 0;
+
if (!pm_runtime_enabled(&phy->dev))
return -ENOTSUPP;
 
@@ -190,6 +199,9 @@ int phy_pm_runtime_put(struct phy *phy)
 
 int phy_pm_runtime_put_sync(struct phy *phy)
 {
+   if (!phy)
+   return 0;
+
if (!pm_runtime_enabled(&phy->dev))
return -ENOTSUPP;
 
@@ -199,6 +211,9 @@ int phy_pm_runtime_put_sync(struct phy *phy)
 
 void phy_pm_runtime_allow(struct phy *phy)
 {
+   if (!phy)
+   return 0;
+
if (!pm_runtime_enabled(&phy->dev))
return;
 
@@ -208,6 +223,9 @@ void phy_pm_runtime_allow(struct phy *phy)
 
 void phy_pm_runtime_forbid(struct phy *phy)
 {
+   if (!phy)
+   return 0;
+
if (!pm_runtime_enabled(&phy->dev))
return;
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v1 2/2] usb: dwc3: Add Qualcomm DWC3 glue driver

2018-03-15 Thread Manu Gautam
Hi,


On 3/14/2018 2:20 PM, Felipe Balbi wrote:
> Hi,
>
> Manu Gautam  writes:
>
[snip]
>>>>  - Support to replace pip3 clock going to DWC3 with utmi clock
>>>>for hardware configuration where SSPHY is not used with DWC3.
>>> Is that SW configurable? Really? In any case seems like this and SESSVLD
>>> valid should be handled using Hans' and Heikki's mux support.
>> Yes, with this we can use dwc3 without using SSPHY. Please point me to
>> those patches. There are only bunch of register writes in glue wrapper to
>> achieve the same.
> https://www.spinics.net/lists/linux-usb/msg160868.html

I looked at the patchset and thinking that adding mux for this may
not be of much help here. Qscratch is part of dwc3 wrapper
and uses same clock domain for its registers. Hence, I can't
have a separate mux driver for same. Will have to register
mux controller from this driver for these and use only in this driver
as I dont expect any other client for same. So, can I proceed with
existing logic?

>
>>>> +static int dwc3_qcom_suspend(struct dwc3_qcom *qcom)
>>>> +{
>>>> +  struct dwc3 *dwc = platform_get_drvdata(qcom->dwc3);
>>> nope! Glue shouldn't touch dwc3 at all.
>> Other than PHY handles, need this to fail runtime suspend if dwc3 hasn't
>> probed yet.
> Will that even happen? You should pm_runtime_forbid() by default,
> anyway and expect it to be enabled via sysfs later, no?

It happens if I enable runtime_pm from probe which is the case right now.
I will disable it from probe as you suggested.
In any case dwc3 uses pm_runtime_forbid and expects it to be enabled from sysfs,
so I dont get any benefit of enabling it from glue driver probe.

Other than this, I need to access 'dwc->xhci' to resume root hub on remote 
wakeup.
That I missed to mention earlier.

>
>>>> +  dwc3_qcom_suspend_hsphy(qcom);
>>>> +
>>>> +  if (dwc->usb2_generic_phy)
>>>> +  phy_pm_runtime_put_sync(dwc->usb2_generic_phy);
>>>> +  if (dwc->usb3_generic_phy)
>>>> +  phy_pm_runtime_put_sync(dwc->usb3_generic_phy);
>>> core.c should do this.
>> Recommended sequence from h/w programming guide is that:
>> 1. PHY autosuspend must be left disabled - 
>> snps,dis_u2_susphy_quirk/dis_enblslpm_quirk
>> 2. During runtime-suspend (say on xhci bus_suspend) , PHY should be suspended
>>     using GUSB2PHYCFG register
> this is something that dwc3 core can do on its own suspend implementation.
>
>> 3. Wait until pwr_event_irq_stat in qscratch reflects PHY transition to L2.
> this is interesting part. Is this register accessible by the PHY driver?
> Seems like that would be the best place to stuff this...

This register is in controller wrapper which PHY driver can't access.
Also clock domain is different.

>
>> 3. USB2 PHY driver can suspend - enable wakeup events and turns off clocks 
>> etc.
> ... together with this.
>
>> 4. dwc3 glue driver can suspend.
>>
>> Since, pwr_event_irq stat can't be checked in core driver, I added this 
>> handling
>> in glue driver. Alternative approach I can think of is to let dwc3 core 
>> suspend
>> PHY using GUSBPHYCFG register on suspend,  add some delay before
>> suspending PHY. Glue driver can check for pwr_event_irq stat and throw a
>> warning if PHY not in L2.
> almost :-) core_suspend fiddles with GUSB2PHYCFG for suspend and calls
> phy_suspend() (or whatever the function is called heh), that will go to
> your phy driver's suspend callback, which checks pwr_event_irq_stat and
> then pm_runtime_put() to schedule ->runtime_suspend() so that can enable
> wakeups and switch off clocks.

Since phy driver can not access pwr_event_irq_stat, should I just use some delay
and assume PHY gets suspended?

>
>>>> +  irq = platform_get_irq_byname(pdev, "dp_hs_phy_irq");
>>>> +  if (irq > 0) {
>>>> +  irq_set_status_flags(irq, IRQ_NOAUTOEN);
>>> why do you need to set this flag?
>> These wakeup_irqs should be enabled only during suspend. With this flag I
>> don't need to disable irq immediately after requesting it.
> oh, okay. You may want to add a comment here :-)
Sure.

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v1 2/2] usb: dwc3: Add Qualcomm DWC3 glue driver

2018-03-13 Thread Manu Gautam
Hi,


On 3/13/2018 4:38 PM, Felipe Balbi wrote:
> Hi,
>
> +Andy
>
> Manu Gautam  writes:
>> DWC3 controller on Qualcomm SOCs has a Qscratch wrapper.
>> Some of its uses are described below resulting in need to
>> have a separate glue driver instead of using dwc3-of-simple:
>>  - It exposes register interface to override vbus-override
>>and lane0-pwr-present signals going to hardware. These
>>must be updated in peripheral mode for DWC3 if vbus lines
>>are not connected to hardware block. Otherwise RX termination
>>in SS mode or DP pull-up is not applied by device controller.
> right, core needs to know that VBUS is above 4.4V. Why wasn't this a
> problem when the original glue layer was first published?

Thanks for reviewing.
Original glue layer supported only host mode, hence this wasn't needed.

>
>>  - pwr_events_irq_stat support to ensure USB2 PHY is in L2 state
>>before glue driver can turn-off clocks and suspend PHY.
> Core manages PHY suspend automatically. Isn't that working for you? Why?

Yes, it is not supported with QUSB2 PHY (usb2-phy on Qualcomm SOCs).
Issue is that If core suspends USB2 PHY (say in host mode if some SS device 
connected),
USB2 PHY stops responding to any attach event as it can't exit suspend state by 
itself.
But in case of driver suspend, along with PHY suspend wakeup events are enabled.
Glue driver can register for wakeup interrupts to exit suspend.

>
>>  - Support for wakeup interrupts lines that are asserted whenever
>>there is any wakeup event on USB3 or USB2 bus.
> ok
>
>>  - Support to replace pip3 clock going to DWC3 with utmi clock
>>for hardware configuration where SSPHY is not used with DWC3.
> Is that SW configurable? Really? In any case seems like this and SESSVLD
> valid should be handled using Hans' and Heikki's mux support.

Yes, with this we can use dwc3 without using SSPHY. Please point me to
those patches. There are only bunch of register writes in glue wrapper to
achieve the same.

>
>> Other than above hardware features in Qscratch wrapper there
>> are some limitations on QCOM SOCs that require special handling
>> of power management e.g. suspending PHY using GUSB2PHYCFG
>> register and ensuring PHY enters L2 before turning off clocks etc.
>>
>> Signed-off-by: Manu Gautam 
>> ---
>>  drivers/usb/dwc3/Kconfig  |  11 +
>>  drivers/usb/dwc3/Makefile |   1 +
>>  drivers/usb/dwc3/dwc3-of-simple.c |   1 -
>>  drivers/usb/dwc3/dwc3-qcom.c  | 635 
>> ++
>>  4 files changed, 647 insertions(+), 1 deletion(-)
>>  create mode 100644 drivers/usb/dwc3/dwc3-qcom.c
>>
>> diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
>> index ab8c0e0..f5bb4f1 100644
>> --- a/drivers/usb/dwc3/Kconfig
>> +++ b/drivers/usb/dwc3/Kconfig
>> @@ -106,4 +106,15 @@ config USB_DWC3_ST
>>inside (i.e. STiH407).
>>Say 'Y' or 'M' if you have one such device.
>>  
>> +config USB_DWC3_QCOM
>> +tristate "Qualcomm Platform"
>> +depends on ARCH_QCOM || COMPILE_TEST
>> +depends on OF
>> +default USB_DWC3
>> +help
>> +  Some Qualcomm SoCs use DesignWare Core IP for USB2/3
>> +  functionality.
>> +
>> +  Say 'Y' or 'M' if you have one such device.
>> +
>>  endif
>> diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
>> index 7ac7250..c3ce697 100644
>> --- a/drivers/usb/dwc3/Makefile
>> +++ b/drivers/usb/dwc3/Makefile
>> @@ -48,3 +48,4 @@ obj-$(CONFIG_USB_DWC3_PCI) += dwc3-pci.o
>>  obj-$(CONFIG_USB_DWC3_KEYSTONE) += dwc3-keystone.o
>>  obj-$(CONFIG_USB_DWC3_OF_SIMPLE)+= dwc3-of-simple.o
>>  obj-$(CONFIG_USB_DWC3_ST)   += dwc3-st.o
>> +obj-$(CONFIG_USB_DWC3_QCOM) += dwc3-qcom.o
>> diff --git a/drivers/usb/dwc3/dwc3-of-simple.c 
>> b/drivers/usb/dwc3/dwc3-of-simple.c
>> index cb2ee96..0fd0e8e 100644
>> --- a/drivers/usb/dwc3/dwc3-of-simple.c
>> +++ b/drivers/usb/dwc3/dwc3-of-simple.c
>> @@ -208,7 +208,6 @@ static int dwc3_of_simple_runtime_resume(struct device 
>> *dev)
>>  };
>>  
>>  static const struct of_device_id of_dwc3_simple_match[] = {
>> -{ .compatible = "qcom,dwc3" },
>>  { .compatible = "rockchip,rk3399-dwc3" },
>>  { .compatible = "xlnx,zynqmp-dwc3" },
>>  { .compatible = "cavium,octeon-7130-usb-uctl" },
>> diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c
>&

[PATCH v1 2/2] usb: dwc3: Add Qualcomm DWC3 glue driver

2018-03-13 Thread Manu Gautam
DWC3 controller on Qualcomm SOCs has a Qscratch wrapper.
Some of its uses are described below resulting in need to
have a separate glue driver instead of using dwc3-of-simple:
 - It exposes register interface to override vbus-override
   and lane0-pwr-present signals going to hardware. These
   must be updated in peripheral mode for DWC3 if vbus lines
   are not connected to hardware block. Otherwise RX termination
   in SS mode or DP pull-up is not applied by device controller.
 - pwr_events_irq_stat support to ensure USB2 PHY is in L2 state
   before glue driver can turn-off clocks and suspend PHY.
 - Support for wakeup interrupts lines that are asserted whenever
   there is any wakeup event on USB3 or USB2 bus.
 - Support to replace pip3 clock going to DWC3 with utmi clock
   for hardware configuration where SSPHY is not used with DWC3.

Other than above hardware features in Qscratch wrapper there
are some limitations on QCOM SOCs that require special handling
of power management e.g. suspending PHY using GUSB2PHYCFG
register and ensuring PHY enters L2 before turning off clocks etc.

Signed-off-by: Manu Gautam 
---
 drivers/usb/dwc3/Kconfig  |  11 +
 drivers/usb/dwc3/Makefile |   1 +
 drivers/usb/dwc3/dwc3-of-simple.c |   1 -
 drivers/usb/dwc3/dwc3-qcom.c  | 635 ++
 4 files changed, 647 insertions(+), 1 deletion(-)
 create mode 100644 drivers/usb/dwc3/dwc3-qcom.c

diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index ab8c0e0..f5bb4f1 100644
--- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig
@@ -106,4 +106,15 @@ config USB_DWC3_ST
  inside (i.e. STiH407).
  Say 'Y' or 'M' if you have one such device.
 
+config USB_DWC3_QCOM
+   tristate "Qualcomm Platform"
+   depends on ARCH_QCOM || COMPILE_TEST
+   depends on OF
+   default USB_DWC3
+   help
+ Some Qualcomm SoCs use DesignWare Core IP for USB2/3
+ functionality.
+
+ Say 'Y' or 'M' if you have one such device.
+
 endif
diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
index 7ac7250..c3ce697 100644
--- a/drivers/usb/dwc3/Makefile
+++ b/drivers/usb/dwc3/Makefile
@@ -48,3 +48,4 @@ obj-$(CONFIG_USB_DWC3_PCI)+= dwc3-pci.o
 obj-$(CONFIG_USB_DWC3_KEYSTONE)+= dwc3-keystone.o
 obj-$(CONFIG_USB_DWC3_OF_SIMPLE)   += dwc3-of-simple.o
 obj-$(CONFIG_USB_DWC3_ST)  += dwc3-st.o
+obj-$(CONFIG_USB_DWC3_QCOM)+= dwc3-qcom.o
diff --git a/drivers/usb/dwc3/dwc3-of-simple.c 
b/drivers/usb/dwc3/dwc3-of-simple.c
index cb2ee96..0fd0e8e 100644
--- a/drivers/usb/dwc3/dwc3-of-simple.c
+++ b/drivers/usb/dwc3/dwc3-of-simple.c
@@ -208,7 +208,6 @@ static int dwc3_of_simple_runtime_resume(struct device *dev)
 };
 
 static const struct of_device_id of_dwc3_simple_match[] = {
-   { .compatible = "qcom,dwc3" },
{ .compatible = "rockchip,rk3399-dwc3" },
{ .compatible = "xlnx,zynqmp-dwc3" },
{ .compatible = "cavium,octeon-7130-usb-uctl" },
diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c
new file mode 100644
index 000..917199e
--- /dev/null
+++ b/drivers/usb/dwc3/dwc3-qcom.c
@@ -0,0 +1,635 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * Inspired by dwc3-of-simple.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "core.h"
+#include "io.h"
+
+/* USB QSCRATCH Hardware registers */
+#define QSCRATCH_HS_PHY_CTRL   0x10
+#define UTMI_OTG_VBUS_VALIDBIT(20)
+#define SW_SESSVLD_SEL BIT(28)
+
+#define QSCRATCH_SS_PHY_CTRL   0x30
+#define LANE0_PWR_PRESENT  BIT(24)
+
+#define QSCRATCH_GENERAL_CFG   0x08
+#define PIPE_UTMI_CLK_SEL  BIT(0)
+#define PIPE3_PHYSTATUS_SW BIT(3)
+#define PIPE_UTMI_CLK_DIS  BIT(8)
+
+#define PWR_EVNT_IRQ_STAT_REG  0x58
+#define PWR_EVNT_LPM_IN_L2_MASKBIT(4)
+#define PWR_EVNT_LPM_OUT_L2_MASK   BIT(5)
+
+#define HSPHY_L2_ENTER_TIMEOUT_US  5000
+
+struct dwc3_qcom {
+   struct device   *dev;
+   void __iomem*qscratch_base;
+   struct platform_device  *dwc3;
+   struct clk  **clks;
+   int num_clocks;
+   struct reset_control*resets;
+
+   int dp_hs_phy_irq;
+   int dm_hs_phy_irq;
+   int ss_phy_irq;
+
+   struct extcon_dev   *edev;
+   struct extcon_dev   *host_edev;
+   struct notifier_

  1   2   3   >