All of lore.kernel.org
 help / color / mirror / Atom feed
From: Bin Liu <b-liu@ti.com>
To: Min Guo <min.guo@mediatek.com>
Cc: Rob Herring <robh+dt@kernel.org>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Mark Rutland <mark.rutland@arm.com>,
	Matthias Brugger <matthias.bgg@gmail.com>,
	Alan Stern <stern@rowland.harvard.edu>,
	<chunfeng.yun@mediatek.com>, <linux-usb@vger.kernel.org>,
	<devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
	<linux-arm-kernel@lists.infradead.org>,
	<linux-mediatek@lists.infradead.org>,
	Yonglong Wu <yonglong.wu@mediatek.com>
Subject: Re: [PATCH 4/4] usb: musb: Add support for MediaTek musb controller
Date: Wed, 9 Jan 2019 08:01:44 -0600	[thread overview]
Message-ID: <20190109140144.GI25910@uda0271908> (raw)
In-Reply-To: <1547037068.4433.122.camel@mhfsdcap03>

Hi Min,

On Wed, Jan 09, 2019 at 08:31:08PM +0800, Min Guo wrote:
> Hi Bin,
> On Tue, 2019-01-08 at 09:44 -0600, Bin Liu wrote:
> > Hi,
> > 
> > On Thu, Dec 27, 2018 at 03:34:26PM +0800, min.guo@mediatek.com wrote:
> > > From: Min Guo <min.guo@mediatek.com>
> > > 
> > > This adds support for MediaTek musb controller in
> > > host, peripheral and otg mode
> > > 
> > > Signed-off-by: Min Guo <min.guo@mediatek.com>
> > > Signed-off-by: Yonglong Wu <yonglong.wu@mediatek.com>
> > > ---
> > >  drivers/usb/musb/Kconfig     |   8 +-
> > >  drivers/usb/musb/Makefile    |   1 +
> > >  drivers/usb/musb/mediatek.c  | 562 +++++++++++++++++++++++++++++++++++++++++++
> > >  drivers/usb/musb/musb_core.c |  10 +
> > >  drivers/usb/musb/musb_core.h |   1 +
> > >  drivers/usb/musb/musb_dma.h  |   1 +
> > >  drivers/usb/musb/musb_host.c |  79 ++++--
> > >  drivers/usb/musb/musb_regs.h |   6 +
> > >  drivers/usb/musb/musbhsdma.c |  34 ++-
> > >  9 files changed, 671 insertions(+), 31 deletions(-)
> > >  create mode 100644 drivers/usb/musb/mediatek.c
> > > 
> > > diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
> > > index ad08895..540fc9f 100644
> > > --- a/drivers/usb/musb/Kconfig
> > > +++ b/drivers/usb/musb/Kconfig
> > > @@ -115,6 +115,12 @@ config USB_MUSB_JZ4740
> > >  	depends on USB_MUSB_GADGET
> > >  	depends on USB_OTG_BLACKLIST_HUB
> > >  
> > > +config USB_MUSB_MEDIATEK
> > > +	tristate "MediaTek platforms"
> > > +	depends on ARCH_MEDIATEK
> > 
> > Please also add '|| COMPILE_TEST' to make testing easier.
> 
> Ok
> 
> > > +	depends on NOP_USB_XCEIV
> > > +	depends on GENERIC_PHY
> > > +
> > >  config USB_MUSB_AM335X_CHILD
> > >  	tristate
> > >  
> > > @@ -141,7 +147,7 @@ config USB_UX500_DMA
> > >  
> > >  config USB_INVENTRA_DMA
> > >  	bool 'Inventra'
> > > -	depends on USB_MUSB_OMAP2PLUS
> > > +	depends on USB_MUSB_OMAP2PLUS || USB_MUSB_MEDIATEK
> > >  	help
> > >  	  Enable DMA transfers using Mentor's engine.
> > >  
> > > diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile
> > > index 3a88c79..63d82d0 100644
> > > --- a/drivers/usb/musb/Makefile
> > > +++ b/drivers/usb/musb/Makefile
> > > @@ -24,6 +24,7 @@ obj-$(CONFIG_USB_MUSB_DA8XX)			+= da8xx.o
> > >  obj-$(CONFIG_USB_MUSB_UX500)			+= ux500.o
> > >  obj-$(CONFIG_USB_MUSB_JZ4740)			+= jz4740.o
> > >  obj-$(CONFIG_USB_MUSB_SUNXI)			+= sunxi.o
> > > +obj-$(CONFIG_USB_MUSB_MEDIATEK)      		+= mediatek.o
> > >  
> > >  
> > >  obj-$(CONFIG_USB_MUSB_AM335X_CHILD)		+= musb_am335x.o
> > > diff --git a/drivers/usb/musb/mediatek.c b/drivers/usb/musb/mediatek.c
> > > new file mode 100644
> > > index 0000000..15a6460
> > > --- /dev/null
> > > +++ b/drivers/usb/musb/mediatek.c
> > 
> > [snip]
> > I will review this section later after we sorted out other things.
> > 
> > > diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
> > > index b7d5627..d60f76f 100644
> > > --- a/drivers/usb/musb/musb_core.c
> > > +++ b/drivers/usb/musb/musb_core.c
> > > @@ -1028,6 +1028,16 @@ static void musb_disable_interrupts(struct musb *musb)
> > >  	temp = musb_readb(mbase, MUSB_INTRUSB);
> > >  	temp = musb_readw(mbase, MUSB_INTRTX);
> > >  	temp = musb_readw(mbase, MUSB_INTRRX);
> > > +
> > > +	/*  MediaTek controller interrupt status is W1C */
> > 
> > This W1C doesn't match to the MUSB Programming Guide that I have. Those
> > registers are read-only.
> > Is the difference due to the IP intergration in the mtk platforms? or is
> > it a new version of the MUSB controller? If latter, what is the version?
> 
> This is difference due to the IP intergration in mtk platforms. W1C is
> easy for CpdeViser debug.
> 
> > > +	if (musb->ops->quirks & MUSB_MTK_QUIRKS) {
> > 
> > Basically we don't want to use this type of platform specific quirks if
> > possible, so let's try to not use it.
> 
> I will try my best to avoid using it.

Thanks.

> 
> > > +		musb_writeb(mbase, MUSB_INTRUSB,
> > > +			musb_readb(mbase, MUSB_INTRUSB));
> > 
> > For this clearing register bit operation, please create platform hooks
> > musb_clearb() and musb_clearw() in struct musb_platform_ops instead,
> > then follow how musb_readb() pointer is assigned in
> > musb_init_controller() to use the W1C version for mtk platform.
> 
> I have tried implementing musb_readb(), musb_readw() interface with
> interrupt status W1C function in struct musb_platform_ops. But this
> interface will require a global variable to hold MAC basic address for
> judgment, and then special handling of the interrupt state. A global
> variable will make the driver work with only a single instance, so it
> can't work on some MTK platforms which have two instances.

I didn't mean to modify musb_read*(), but

> How about creating musb_clearb/w() as following:
> void (*clearb)(void __iomem *addr, unsigned offset, u8 data);
> void (*clearw)(void __iomem *addr, unsigned offset, u16 data);

this is what I was asking for, similar to what musb_readb/w() is
implemented.

> 
> 
> > > +		musb_writew(mbase, MUSB_INTRRX,
> > > +			musb_readw(mbase, MUSB_INTRRX));
> > > +		musb_writew(mbase, MUSB_INTRTX,
> > > +			musb_readw(mbase, MUSB_INTRTX));
> > > +	}
> > >  }
> > >  
> > >  static void musb_enable_interrupts(struct musb *musb)
> > > diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
> > > index 04203b7..1bf4e9a 100644
> > > --- a/drivers/usb/musb/musb_core.h
> > > +++ b/drivers/usb/musb/musb_core.h
> > > @@ -138,6 +138,7 @@ enum musb_g_ep0_state {
> > >   */
> > >  struct musb_platform_ops {
> > >  
> > > +#define MUSB_MTK_QUIRKS	BIT(10)
> > >  #define MUSB_G_NO_SKB_RESERVE	BIT(9)
> > >  #define MUSB_DA8XX		BIT(8)
> > >  #define MUSB_PRESERVE_SESSION	BIT(7)
> > > diff --git a/drivers/usb/musb/musb_dma.h b/drivers/usb/musb/musb_dma.h
> > > index 281e75d3..b218210 100644
> > > --- a/drivers/usb/musb/musb_dma.h
> > > +++ b/drivers/usb/musb/musb_dma.h
> > > @@ -197,6 +197,7 @@ static inline void musb_dma_controller_destroy(struct dma_controller *d) { }
> > >  extern struct dma_controller *
> > >  musbhs_dma_controller_create(struct musb *musb, void __iomem *base);
> > >  extern void musbhs_dma_controller_destroy(struct dma_controller *c);
> > > +extern irqreturn_t dma_controller_irq(int irq, void *private_data);
> > >  
> > >  extern struct dma_controller *
> > >  tusb_dma_controller_create(struct musb *musb, void __iomem *base);
> > > diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
> > > index b59ce9a..b1b0216 100644
> > > --- a/drivers/usb/musb/musb_host.c
> > > +++ b/drivers/usb/musb/musb_host.c
> > > @@ -292,20 +292,73 @@ static inline void musb_save_toggle(struct musb_qh *qh, int is_in,
> > >  {
> > >  	void __iomem		*epio = qh->hw_ep->regs;
> > >  	u16			csr;
> > > +	struct musb *musb = qh->hw_ep->musb;
> > >  
> > >  	/*
> > >  	 * FIXME: the current Mentor DMA code seems to have
> > >  	 * problems getting toggle correct.
> > >  	 */
> > >  
> > > -	if (is_in)
> > > -		csr = musb_readw(epio, MUSB_RXCSR) & MUSB_RXCSR_H_DATATOGGLE;
> > > -	else
> > > -		csr = musb_readw(epio, MUSB_TXCSR) & MUSB_TXCSR_H_DATATOGGLE;
> > > +	/* MediaTek controller has private toggle register */
> > 
> > only one toggle register for all endpoints? how does it handle
> > difference toggle values for different endpoints?
> 
> MediaTek controller has separate registers to describe TX/RX toggle.

Is it one register per endpoint?

> 
> > > +	if (musb->ops->quirks & MUSB_MTK_QUIRKS) {
> > > +		u16 toggle;
> > > +		u8 epnum = qh->hw_ep->epnum;
> > > +
> > > +		if (is_in)
> > > +			toggle = musb_readl(musb->mregs, MUSB_RXTOG);

this line seems telling there is just *one* register for all endpoints.

> > 
> > should use musb_readw() instead? MUSB_RXTOG seems to be 16bit.
> 
> Ok
> 
> > > +		else
> > > +			toggle = musb_readl(musb->mregs, MUSB_TXTOG);
> > > +
> > > +		csr = toggle & (1 << epnum);
> > > +	} else {
> > > +		if (is_in)
> > > +			csr = musb_readw(epio, MUSB_RXCSR)
> > > +				& MUSB_RXCSR_H_DATATOGGLE;
> > > +		else
> > > +			csr = musb_readw(epio, MUSB_TXCSR)
> > > +				& MUSB_TXCSR_H_DATATOGGLE;
> > 
> > Does this logic still work for the mtk platform even if it has its own
> > private toggle register? If so, we don't need to change here.
> 
> Sorry, this logic can not work on mtk platform, bit
> MUSB_RXCSR_H_DATATOGGLE and MUSB_TXCSR_H_DATATOGGLE are used for other
> function.

Is there a different controller RTL version we can use to
differentiate?

> 
> > If not, let's try to not use this quirk flag. Please create a hook
> > musb_platform_get_toggle() in struct musb_platform_ops.
> 
> Does the method of implement musb_platform_get_toggle() is prepare
> musb_default_get_toggle with common function, then follow how
> musb_readb() pointer is assigned in musb_init_controller()?

Yes, similar to musb_readb() implementation.

> How about creating musb_platform_get_toggle() as following:
> u16 (*get_toggle)(struct musb* musb, struct musb_qh *qh, int is_in);

yes, it is part of the implementation, then add it in struct musb_io.

> 
> > > +	}
> > >  
> > >  	usb_settoggle(urb->dev, qh->epnum, !is_in, csr ? 1 : 0);
> > >  }
> > >  
> > > +static inline u16 musb_set_toggle(struct musb_qh *qh, int is_in,
> > > +					struct urb *urb)
> > > +{
> > > +	u16 csr = 0;
> > > +	u16 toggle = 0;
> > > +	struct musb *musb = qh->hw_ep->musb;
> > > +	u8 epnum = qh->hw_ep->epnum;
> > > +
> > > +	toggle = usb_gettoggle(urb->dev, qh->epnum, !is_in);
> > > +
> > > +	/* MediaTek controller has private toggle register */
> > > +	if (musb->ops->quirks & MUSB_MTK_QUIRKS) {
> > > +		if (is_in) {
> > > +			musb_writel(musb->mregs, MUSB_RXTOGEN, (1 << epnum));
> > > +			musb_writel(musb->mregs, MUSB_RXTOG, (toggle << epnum));
> > > +		} else {
> > > +			musb_writel(musb->mregs, MUSB_TXTOGEN, (1 << epnum));
> > > +			musb_writel(musb->mregs, MUSB_TXTOG, (toggle << epnum));
> > > +		}
> > > +	} else {
> > > +		if (is_in) {
> > > +			if (toggle)
> > > +				csr = MUSB_RXCSR_H_WR_DATATOGGLE
> > > +						| MUSB_RXCSR_H_DATATOGGLE;
> > > +			else
> > > +				csr = 0;
> > > +		} else {
> > > +			if (toggle)
> > > +				csr |= MUSB_TXCSR_H_WR_DATATOGGLE
> > > +						| MUSB_TXCSR_H_DATATOGGLE;
> > > +			else
> > > +				csr |= MUSB_TXCSR_CLRDATATOG;

'? :' operation probably is better than 'if else' here.

> > > +		}
> > > +	}
> > > +	return csr;
> > 
> > Please create a seperate patch for this musb_set_toggle() without adding
> > the mtk logic. It is a nice cleanup.
> 
> Does this like get toggle implementation, create a hook
> musb_platform_set_toggle() in struct musb_platform_ops?

You did the code cleanup by creating musb_set_toggle(), please make it
in a separate patch, like

static u16 musb_set_toggle(struct musb_qh *qh, int is_in, struct urb *urb)
{
	toggle = usb_gettoggle(urb->dev, qh->epnum, !is_in);
	if (is_in)
		csr = toggle ? 
			(MUSB_RXCSR_H_WR_DATATOGGLE | MUSB_RXCSR_H_DATATOGGLE) :
			0;
	else
		csr = toggle ?
			MUSB_TXCSR_H_WR_DATATOGGLE | MUSB_TXCSR_H_DATATOGGLE :
			MUSB_TXCSR_CLRDATATOG;
	return csr;
}

/* use musb_set_toggle() in the two instances */

then in this patch you add the mtk implementation similar as
*get_toggle() discussed above.

> 
> > > +}
> > > +
> > >  /*
> > >   * Advance this hardware endpoint's queue, completing the specified URB and
> > >   * advancing to either the next URB queued to that qh, or else invalidating
> > > @@ -772,13 +825,8 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
> > >  					);
> > >  			csr |= MUSB_TXCSR_MODE;
> > >  
> > > -			if (!hw_ep->tx_double_buffered) {
> > > -				if (usb_gettoggle(urb->dev, qh->epnum, 1))
> > > -					csr |= MUSB_TXCSR_H_WR_DATATOGGLE
> > > -						| MUSB_TXCSR_H_DATATOGGLE;
> > > -				else
> > > -					csr |= MUSB_TXCSR_CLRDATATOG;
> > > -			}
> > > +			if (!hw_ep->tx_double_buffered)
> > > +				csr |= musb_set_toggle(qh, !is_out, urb);
> > >  
> > >  			musb_writew(epio, MUSB_TXCSR, csr);
> > >  			/* REVISIT may need to clear FLUSHFIFO ... */
> > > @@ -860,17 +908,12 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
> > >  
> > >  	/* IN/receive */
> > >  	} else {
> > > -		u16	csr;
> > > +		u16	csr = 0;
> > >  
> > >  		if (hw_ep->rx_reinit) {
> > >  			musb_rx_reinit(musb, qh, epnum);
> > > +			csr |= musb_set_toggle(qh, !is_out, urb);
> > >  
> > > -			/* init new state: toggle and NYET, maybe DMA later */
> > > -			if (usb_gettoggle(urb->dev, qh->epnum, 0))
> > > -				csr = MUSB_RXCSR_H_WR_DATATOGGLE
> > > -					| MUSB_RXCSR_H_DATATOGGLE;
> > > -			else
> > > -				csr = 0;
> > >  			if (qh->type == USB_ENDPOINT_XFER_INT)
> > >  				csr |= MUSB_RXCSR_DISNYET;
> > >  
> > > diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h
> > > index 5cd7264..ffbe267 100644
> > > --- a/drivers/usb/musb/musb_regs.h
> > > +++ b/drivers/usb/musb/musb_regs.h
> > > @@ -273,6 +273,12 @@
> > >  #define MUSB_RXHUBADDR		0x06
> > >  #define MUSB_RXHUBPORT		0x07
> > >  
> > > +/* MediaTek controller toggle enable and status reg */
> > > +#define MUSB_RXTOG		0x80
> > > +#define MUSB_RXTOGEN		0x82
> > > +#define MUSB_TXTOG		0x84
> > > +#define MUSB_TXTOGEN		0x86
> > 
> > Again, these offsets are for different registers in the MUSB version I
> > have, please let me know if you have different version of the MUSB IP.
> 
> Sorry, these are MediaTek controller private registers used for control
> toggle.

Okay. Once the platform get/set_toggle() are implemented, those
registers can be defined in the mtk glue driver instead of here.

Regards,
-Bin.

WARNING: multiple messages have this Message-ID (diff)
From: Bin Liu <b-liu@ti.com>
To: Min Guo <min.guo@mediatek.com>
Cc: Mark Rutland <mark.rutland@arm.com>,
	devicetree@vger.kernel.org,
	Yonglong Wu <yonglong.wu@mediatek.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org,
	Matthias Brugger <matthias.bgg@gmail.com>,
	Rob Herring <robh+dt@kernel.org>,
	Alan Stern <stern@rowland.harvard.edu>,
	chunfeng.yun@mediatek.com, linux-mediatek@lists.infradead.org,
	linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH 4/4] usb: musb: Add support for MediaTek musb controller
Date: Wed, 9 Jan 2019 08:01:44 -0600	[thread overview]
Message-ID: <20190109140144.GI25910@uda0271908> (raw)
In-Reply-To: <1547037068.4433.122.camel@mhfsdcap03>

Hi Min,

On Wed, Jan 09, 2019 at 08:31:08PM +0800, Min Guo wrote:
> Hi Bin,
> On Tue, 2019-01-08 at 09:44 -0600, Bin Liu wrote:
> > Hi,
> > 
> > On Thu, Dec 27, 2018 at 03:34:26PM +0800, min.guo@mediatek.com wrote:
> > > From: Min Guo <min.guo@mediatek.com>
> > > 
> > > This adds support for MediaTek musb controller in
> > > host, peripheral and otg mode
> > > 
> > > Signed-off-by: Min Guo <min.guo@mediatek.com>
> > > Signed-off-by: Yonglong Wu <yonglong.wu@mediatek.com>
> > > ---
> > >  drivers/usb/musb/Kconfig     |   8 +-
> > >  drivers/usb/musb/Makefile    |   1 +
> > >  drivers/usb/musb/mediatek.c  | 562 +++++++++++++++++++++++++++++++++++++++++++
> > >  drivers/usb/musb/musb_core.c |  10 +
> > >  drivers/usb/musb/musb_core.h |   1 +
> > >  drivers/usb/musb/musb_dma.h  |   1 +
> > >  drivers/usb/musb/musb_host.c |  79 ++++--
> > >  drivers/usb/musb/musb_regs.h |   6 +
> > >  drivers/usb/musb/musbhsdma.c |  34 ++-
> > >  9 files changed, 671 insertions(+), 31 deletions(-)
> > >  create mode 100644 drivers/usb/musb/mediatek.c
> > > 
> > > diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
> > > index ad08895..540fc9f 100644
> > > --- a/drivers/usb/musb/Kconfig
> > > +++ b/drivers/usb/musb/Kconfig
> > > @@ -115,6 +115,12 @@ config USB_MUSB_JZ4740
> > >  	depends on USB_MUSB_GADGET
> > >  	depends on USB_OTG_BLACKLIST_HUB
> > >  
> > > +config USB_MUSB_MEDIATEK
> > > +	tristate "MediaTek platforms"
> > > +	depends on ARCH_MEDIATEK
> > 
> > Please also add '|| COMPILE_TEST' to make testing easier.
> 
> Ok
> 
> > > +	depends on NOP_USB_XCEIV
> > > +	depends on GENERIC_PHY
> > > +
> > >  config USB_MUSB_AM335X_CHILD
> > >  	tristate
> > >  
> > > @@ -141,7 +147,7 @@ config USB_UX500_DMA
> > >  
> > >  config USB_INVENTRA_DMA
> > >  	bool 'Inventra'
> > > -	depends on USB_MUSB_OMAP2PLUS
> > > +	depends on USB_MUSB_OMAP2PLUS || USB_MUSB_MEDIATEK
> > >  	help
> > >  	  Enable DMA transfers using Mentor's engine.
> > >  
> > > diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile
> > > index 3a88c79..63d82d0 100644
> > > --- a/drivers/usb/musb/Makefile
> > > +++ b/drivers/usb/musb/Makefile
> > > @@ -24,6 +24,7 @@ obj-$(CONFIG_USB_MUSB_DA8XX)			+= da8xx.o
> > >  obj-$(CONFIG_USB_MUSB_UX500)			+= ux500.o
> > >  obj-$(CONFIG_USB_MUSB_JZ4740)			+= jz4740.o
> > >  obj-$(CONFIG_USB_MUSB_SUNXI)			+= sunxi.o
> > > +obj-$(CONFIG_USB_MUSB_MEDIATEK)      		+= mediatek.o
> > >  
> > >  
> > >  obj-$(CONFIG_USB_MUSB_AM335X_CHILD)		+= musb_am335x.o
> > > diff --git a/drivers/usb/musb/mediatek.c b/drivers/usb/musb/mediatek.c
> > > new file mode 100644
> > > index 0000000..15a6460
> > > --- /dev/null
> > > +++ b/drivers/usb/musb/mediatek.c
> > 
> > [snip]
> > I will review this section later after we sorted out other things.
> > 
> > > diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
> > > index b7d5627..d60f76f 100644
> > > --- a/drivers/usb/musb/musb_core.c
> > > +++ b/drivers/usb/musb/musb_core.c
> > > @@ -1028,6 +1028,16 @@ static void musb_disable_interrupts(struct musb *musb)
> > >  	temp = musb_readb(mbase, MUSB_INTRUSB);
> > >  	temp = musb_readw(mbase, MUSB_INTRTX);
> > >  	temp = musb_readw(mbase, MUSB_INTRRX);
> > > +
> > > +	/*  MediaTek controller interrupt status is W1C */
> > 
> > This W1C doesn't match to the MUSB Programming Guide that I have. Those
> > registers are read-only.
> > Is the difference due to the IP intergration in the mtk platforms? or is
> > it a new version of the MUSB controller? If latter, what is the version?
> 
> This is difference due to the IP intergration in mtk platforms. W1C is
> easy for CpdeViser debug.
> 
> > > +	if (musb->ops->quirks & MUSB_MTK_QUIRKS) {
> > 
> > Basically we don't want to use this type of platform specific quirks if
> > possible, so let's try to not use it.
> 
> I will try my best to avoid using it.

Thanks.

> 
> > > +		musb_writeb(mbase, MUSB_INTRUSB,
> > > +			musb_readb(mbase, MUSB_INTRUSB));
> > 
> > For this clearing register bit operation, please create platform hooks
> > musb_clearb() and musb_clearw() in struct musb_platform_ops instead,
> > then follow how musb_readb() pointer is assigned in
> > musb_init_controller() to use the W1C version for mtk platform.
> 
> I have tried implementing musb_readb(), musb_readw() interface with
> interrupt status W1C function in struct musb_platform_ops. But this
> interface will require a global variable to hold MAC basic address for
> judgment, and then special handling of the interrupt state. A global
> variable will make the driver work with only a single instance, so it
> can't work on some MTK platforms which have two instances.

I didn't mean to modify musb_read*(), but

> How about creating musb_clearb/w() as following:
> void (*clearb)(void __iomem *addr, unsigned offset, u8 data);
> void (*clearw)(void __iomem *addr, unsigned offset, u16 data);

this is what I was asking for, similar to what musb_readb/w() is
implemented.

> 
> 
> > > +		musb_writew(mbase, MUSB_INTRRX,
> > > +			musb_readw(mbase, MUSB_INTRRX));
> > > +		musb_writew(mbase, MUSB_INTRTX,
> > > +			musb_readw(mbase, MUSB_INTRTX));
> > > +	}
> > >  }
> > >  
> > >  static void musb_enable_interrupts(struct musb *musb)
> > > diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
> > > index 04203b7..1bf4e9a 100644
> > > --- a/drivers/usb/musb/musb_core.h
> > > +++ b/drivers/usb/musb/musb_core.h
> > > @@ -138,6 +138,7 @@ enum musb_g_ep0_state {
> > >   */
> > >  struct musb_platform_ops {
> > >  
> > > +#define MUSB_MTK_QUIRKS	BIT(10)
> > >  #define MUSB_G_NO_SKB_RESERVE	BIT(9)
> > >  #define MUSB_DA8XX		BIT(8)
> > >  #define MUSB_PRESERVE_SESSION	BIT(7)
> > > diff --git a/drivers/usb/musb/musb_dma.h b/drivers/usb/musb/musb_dma.h
> > > index 281e75d3..b218210 100644
> > > --- a/drivers/usb/musb/musb_dma.h
> > > +++ b/drivers/usb/musb/musb_dma.h
> > > @@ -197,6 +197,7 @@ static inline void musb_dma_controller_destroy(struct dma_controller *d) { }
> > >  extern struct dma_controller *
> > >  musbhs_dma_controller_create(struct musb *musb, void __iomem *base);
> > >  extern void musbhs_dma_controller_destroy(struct dma_controller *c);
> > > +extern irqreturn_t dma_controller_irq(int irq, void *private_data);
> > >  
> > >  extern struct dma_controller *
> > >  tusb_dma_controller_create(struct musb *musb, void __iomem *base);
> > > diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
> > > index b59ce9a..b1b0216 100644
> > > --- a/drivers/usb/musb/musb_host.c
> > > +++ b/drivers/usb/musb/musb_host.c
> > > @@ -292,20 +292,73 @@ static inline void musb_save_toggle(struct musb_qh *qh, int is_in,
> > >  {
> > >  	void __iomem		*epio = qh->hw_ep->regs;
> > >  	u16			csr;
> > > +	struct musb *musb = qh->hw_ep->musb;
> > >  
> > >  	/*
> > >  	 * FIXME: the current Mentor DMA code seems to have
> > >  	 * problems getting toggle correct.
> > >  	 */
> > >  
> > > -	if (is_in)
> > > -		csr = musb_readw(epio, MUSB_RXCSR) & MUSB_RXCSR_H_DATATOGGLE;
> > > -	else
> > > -		csr = musb_readw(epio, MUSB_TXCSR) & MUSB_TXCSR_H_DATATOGGLE;
> > > +	/* MediaTek controller has private toggle register */
> > 
> > only one toggle register for all endpoints? how does it handle
> > difference toggle values for different endpoints?
> 
> MediaTek controller has separate registers to describe TX/RX toggle.

Is it one register per endpoint?

> 
> > > +	if (musb->ops->quirks & MUSB_MTK_QUIRKS) {
> > > +		u16 toggle;
> > > +		u8 epnum = qh->hw_ep->epnum;
> > > +
> > > +		if (is_in)
> > > +			toggle = musb_readl(musb->mregs, MUSB_RXTOG);

this line seems telling there is just *one* register for all endpoints.

> > 
> > should use musb_readw() instead? MUSB_RXTOG seems to be 16bit.
> 
> Ok
> 
> > > +		else
> > > +			toggle = musb_readl(musb->mregs, MUSB_TXTOG);
> > > +
> > > +		csr = toggle & (1 << epnum);
> > > +	} else {
> > > +		if (is_in)
> > > +			csr = musb_readw(epio, MUSB_RXCSR)
> > > +				& MUSB_RXCSR_H_DATATOGGLE;
> > > +		else
> > > +			csr = musb_readw(epio, MUSB_TXCSR)
> > > +				& MUSB_TXCSR_H_DATATOGGLE;
> > 
> > Does this logic still work for the mtk platform even if it has its own
> > private toggle register? If so, we don't need to change here.
> 
> Sorry, this logic can not work on mtk platform, bit
> MUSB_RXCSR_H_DATATOGGLE and MUSB_TXCSR_H_DATATOGGLE are used for other
> function.

Is there a different controller RTL version we can use to
differentiate?

> 
> > If not, let's try to not use this quirk flag. Please create a hook
> > musb_platform_get_toggle() in struct musb_platform_ops.
> 
> Does the method of implement musb_platform_get_toggle() is prepare
> musb_default_get_toggle with common function, then follow how
> musb_readb() pointer is assigned in musb_init_controller()?

Yes, similar to musb_readb() implementation.

> How about creating musb_platform_get_toggle() as following:
> u16 (*get_toggle)(struct musb* musb, struct musb_qh *qh, int is_in);

yes, it is part of the implementation, then add it in struct musb_io.

> 
> > > +	}
> > >  
> > >  	usb_settoggle(urb->dev, qh->epnum, !is_in, csr ? 1 : 0);
> > >  }
> > >  
> > > +static inline u16 musb_set_toggle(struct musb_qh *qh, int is_in,
> > > +					struct urb *urb)
> > > +{
> > > +	u16 csr = 0;
> > > +	u16 toggle = 0;
> > > +	struct musb *musb = qh->hw_ep->musb;
> > > +	u8 epnum = qh->hw_ep->epnum;
> > > +
> > > +	toggle = usb_gettoggle(urb->dev, qh->epnum, !is_in);
> > > +
> > > +	/* MediaTek controller has private toggle register */
> > > +	if (musb->ops->quirks & MUSB_MTK_QUIRKS) {
> > > +		if (is_in) {
> > > +			musb_writel(musb->mregs, MUSB_RXTOGEN, (1 << epnum));
> > > +			musb_writel(musb->mregs, MUSB_RXTOG, (toggle << epnum));
> > > +		} else {
> > > +			musb_writel(musb->mregs, MUSB_TXTOGEN, (1 << epnum));
> > > +			musb_writel(musb->mregs, MUSB_TXTOG, (toggle << epnum));
> > > +		}
> > > +	} else {
> > > +		if (is_in) {
> > > +			if (toggle)
> > > +				csr = MUSB_RXCSR_H_WR_DATATOGGLE
> > > +						| MUSB_RXCSR_H_DATATOGGLE;
> > > +			else
> > > +				csr = 0;
> > > +		} else {
> > > +			if (toggle)
> > > +				csr |= MUSB_TXCSR_H_WR_DATATOGGLE
> > > +						| MUSB_TXCSR_H_DATATOGGLE;
> > > +			else
> > > +				csr |= MUSB_TXCSR_CLRDATATOG;

'? :' operation probably is better than 'if else' here.

> > > +		}
> > > +	}
> > > +	return csr;
> > 
> > Please create a seperate patch for this musb_set_toggle() without adding
> > the mtk logic. It is a nice cleanup.
> 
> Does this like get toggle implementation, create a hook
> musb_platform_set_toggle() in struct musb_platform_ops?

You did the code cleanup by creating musb_set_toggle(), please make it
in a separate patch, like

static u16 musb_set_toggle(struct musb_qh *qh, int is_in, struct urb *urb)
{
	toggle = usb_gettoggle(urb->dev, qh->epnum, !is_in);
	if (is_in)
		csr = toggle ? 
			(MUSB_RXCSR_H_WR_DATATOGGLE | MUSB_RXCSR_H_DATATOGGLE) :
			0;
	else
		csr = toggle ?
			MUSB_TXCSR_H_WR_DATATOGGLE | MUSB_TXCSR_H_DATATOGGLE :
			MUSB_TXCSR_CLRDATATOG;
	return csr;
}

/* use musb_set_toggle() in the two instances */

then in this patch you add the mtk implementation similar as
*get_toggle() discussed above.

> 
> > > +}
> > > +
> > >  /*
> > >   * Advance this hardware endpoint's queue, completing the specified URB and
> > >   * advancing to either the next URB queued to that qh, or else invalidating
> > > @@ -772,13 +825,8 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
> > >  					);
> > >  			csr |= MUSB_TXCSR_MODE;
> > >  
> > > -			if (!hw_ep->tx_double_buffered) {
> > > -				if (usb_gettoggle(urb->dev, qh->epnum, 1))
> > > -					csr |= MUSB_TXCSR_H_WR_DATATOGGLE
> > > -						| MUSB_TXCSR_H_DATATOGGLE;
> > > -				else
> > > -					csr |= MUSB_TXCSR_CLRDATATOG;
> > > -			}
> > > +			if (!hw_ep->tx_double_buffered)
> > > +				csr |= musb_set_toggle(qh, !is_out, urb);
> > >  
> > >  			musb_writew(epio, MUSB_TXCSR, csr);
> > >  			/* REVISIT may need to clear FLUSHFIFO ... */
> > > @@ -860,17 +908,12 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
> > >  
> > >  	/* IN/receive */
> > >  	} else {
> > > -		u16	csr;
> > > +		u16	csr = 0;
> > >  
> > >  		if (hw_ep->rx_reinit) {
> > >  			musb_rx_reinit(musb, qh, epnum);
> > > +			csr |= musb_set_toggle(qh, !is_out, urb);
> > >  
> > > -			/* init new state: toggle and NYET, maybe DMA later */
> > > -			if (usb_gettoggle(urb->dev, qh->epnum, 0))
> > > -				csr = MUSB_RXCSR_H_WR_DATATOGGLE
> > > -					| MUSB_RXCSR_H_DATATOGGLE;
> > > -			else
> > > -				csr = 0;
> > >  			if (qh->type == USB_ENDPOINT_XFER_INT)
> > >  				csr |= MUSB_RXCSR_DISNYET;
> > >  
> > > diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h
> > > index 5cd7264..ffbe267 100644
> > > --- a/drivers/usb/musb/musb_regs.h
> > > +++ b/drivers/usb/musb/musb_regs.h
> > > @@ -273,6 +273,12 @@
> > >  #define MUSB_RXHUBADDR		0x06
> > >  #define MUSB_RXHUBPORT		0x07
> > >  
> > > +/* MediaTek controller toggle enable and status reg */
> > > +#define MUSB_RXTOG		0x80
> > > +#define MUSB_RXTOGEN		0x82
> > > +#define MUSB_TXTOG		0x84
> > > +#define MUSB_TXTOGEN		0x86
> > 
> > Again, these offsets are for different registers in the MUSB version I
> > have, please let me know if you have different version of the MUSB IP.
> 
> Sorry, these are MediaTek controller private registers used for control
> toggle.

Okay. Once the platform get/set_toggle() are implemented, those
registers can be defined in the mtk glue driver instead of here.

Regards,
-Bin.

WARNING: multiple messages have this Message-ID (diff)
From: Bin Liu <b-liu@ti.com>
To: Min Guo <min.guo@mediatek.com>
Cc: Rob Herring <robh+dt@kernel.org>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Mark Rutland <mark.rutland@arm.com>,
	Matthias Brugger <matthias.bgg@gmail.com>,
	Alan Stern <stern@rowland.harvard.edu>,
	chunfeng.yun@mediatek.com, linux-usb@vger.kernel.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-mediatek@lists.infradead.org,
	Yonglong Wu <yonglong.wu@mediatek.com>
Subject: [4/4] usb: musb: Add support for MediaTek musb controller
Date: Wed, 9 Jan 2019 08:01:44 -0600	[thread overview]
Message-ID: <20190109140144.GI25910@uda0271908> (raw)

Hi Min,

On Wed, Jan 09, 2019 at 08:31:08PM +0800, Min Guo wrote:
> Hi Bin,
> On Tue, 2019-01-08 at 09:44 -0600, Bin Liu wrote:
> > Hi,
> > 
> > On Thu, Dec 27, 2018 at 03:34:26PM +0800, min.guo@mediatek.com wrote:
> > > From: Min Guo <min.guo@mediatek.com>
> > > 
> > > This adds support for MediaTek musb controller in
> > > host, peripheral and otg mode
> > > 
> > > Signed-off-by: Min Guo <min.guo@mediatek.com>
> > > Signed-off-by: Yonglong Wu <yonglong.wu@mediatek.com>
> > > ---
> > >  drivers/usb/musb/Kconfig     |   8 +-
> > >  drivers/usb/musb/Makefile    |   1 +
> > >  drivers/usb/musb/mediatek.c  | 562 +++++++++++++++++++++++++++++++++++++++++++
> > >  drivers/usb/musb/musb_core.c |  10 +
> > >  drivers/usb/musb/musb_core.h |   1 +
> > >  drivers/usb/musb/musb_dma.h  |   1 +
> > >  drivers/usb/musb/musb_host.c |  79 ++++--
> > >  drivers/usb/musb/musb_regs.h |   6 +
> > >  drivers/usb/musb/musbhsdma.c |  34 ++-
> > >  9 files changed, 671 insertions(+), 31 deletions(-)
> > >  create mode 100644 drivers/usb/musb/mediatek.c
> > > 
> > > diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
> > > index ad08895..540fc9f 100644
> > > --- a/drivers/usb/musb/Kconfig
> > > +++ b/drivers/usb/musb/Kconfig
> > > @@ -115,6 +115,12 @@ config USB_MUSB_JZ4740
> > >  	depends on USB_MUSB_GADGET
> > >  	depends on USB_OTG_BLACKLIST_HUB
> > >  
> > > +config USB_MUSB_MEDIATEK
> > > +	tristate "MediaTek platforms"
> > > +	depends on ARCH_MEDIATEK
> > 
> > Please also add '|| COMPILE_TEST' to make testing easier.
> 
> Ok
> 
> > > +	depends on NOP_USB_XCEIV
> > > +	depends on GENERIC_PHY
> > > +
> > >  config USB_MUSB_AM335X_CHILD
> > >  	tristate
> > >  
> > > @@ -141,7 +147,7 @@ config USB_UX500_DMA
> > >  
> > >  config USB_INVENTRA_DMA
> > >  	bool 'Inventra'
> > > -	depends on USB_MUSB_OMAP2PLUS
> > > +	depends on USB_MUSB_OMAP2PLUS || USB_MUSB_MEDIATEK
> > >  	help
> > >  	  Enable DMA transfers using Mentor's engine.
> > >  
> > > diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile
> > > index 3a88c79..63d82d0 100644
> > > --- a/drivers/usb/musb/Makefile
> > > +++ b/drivers/usb/musb/Makefile
> > > @@ -24,6 +24,7 @@ obj-$(CONFIG_USB_MUSB_DA8XX)			+= da8xx.o
> > >  obj-$(CONFIG_USB_MUSB_UX500)			+= ux500.o
> > >  obj-$(CONFIG_USB_MUSB_JZ4740)			+= jz4740.o
> > >  obj-$(CONFIG_USB_MUSB_SUNXI)			+= sunxi.o
> > > +obj-$(CONFIG_USB_MUSB_MEDIATEK)      		+= mediatek.o
> > >  
> > >  
> > >  obj-$(CONFIG_USB_MUSB_AM335X_CHILD)		+= musb_am335x.o
> > > diff --git a/drivers/usb/musb/mediatek.c b/drivers/usb/musb/mediatek.c
> > > new file mode 100644
> > > index 0000000..15a6460
> > > --- /dev/null
> > > +++ b/drivers/usb/musb/mediatek.c
> > 
> > [snip]
> > I will review this section later after we sorted out other things.
> > 
> > > diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
> > > index b7d5627..d60f76f 100644
> > > --- a/drivers/usb/musb/musb_core.c
> > > +++ b/drivers/usb/musb/musb_core.c
> > > @@ -1028,6 +1028,16 @@ static void musb_disable_interrupts(struct musb *musb)
> > >  	temp = musb_readb(mbase, MUSB_INTRUSB);
> > >  	temp = musb_readw(mbase, MUSB_INTRTX);
> > >  	temp = musb_readw(mbase, MUSB_INTRRX);
> > > +
> > > +	/*  MediaTek controller interrupt status is W1C */
> > 
> > This W1C doesn't match to the MUSB Programming Guide that I have. Those
> > registers are read-only.
> > Is the difference due to the IP intergration in the mtk platforms? or is
> > it a new version of the MUSB controller? If latter, what is the version?
> 
> This is difference due to the IP intergration in mtk platforms. W1C is
> easy for CpdeViser debug.
> 
> > > +	if (musb->ops->quirks & MUSB_MTK_QUIRKS) {
> > 
> > Basically we don't want to use this type of platform specific quirks if
> > possible, so let's try to not use it.
> 
> I will try my best to avoid using it.

Thanks.

> 
> > > +		musb_writeb(mbase, MUSB_INTRUSB,
> > > +			musb_readb(mbase, MUSB_INTRUSB));
> > 
> > For this clearing register bit operation, please create platform hooks
> > musb_clearb() and musb_clearw() in struct musb_platform_ops instead,
> > then follow how musb_readb() pointer is assigned in
> > musb_init_controller() to use the W1C version for mtk platform.
> 
> I have tried implementing musb_readb(), musb_readw() interface with
> interrupt status W1C function in struct musb_platform_ops. But this
> interface will require a global variable to hold MAC basic address for
> judgment, and then special handling of the interrupt state. A global
> variable will make the driver work with only a single instance, so it
> can't work on some MTK platforms which have two instances.

I didn't mean to modify musb_read*(), but

> How about creating musb_clearb/w() as following:
> void (*clearb)(void __iomem *addr, unsigned offset, u8 data);
> void (*clearw)(void __iomem *addr, unsigned offset, u16 data);

this is what I was asking for, similar to what musb_readb/w() is
implemented.

> 
> 
> > > +		musb_writew(mbase, MUSB_INTRRX,
> > > +			musb_readw(mbase, MUSB_INTRRX));
> > > +		musb_writew(mbase, MUSB_INTRTX,
> > > +			musb_readw(mbase, MUSB_INTRTX));
> > > +	}
> > >  }
> > >  
> > >  static void musb_enable_interrupts(struct musb *musb)
> > > diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
> > > index 04203b7..1bf4e9a 100644
> > > --- a/drivers/usb/musb/musb_core.h
> > > +++ b/drivers/usb/musb/musb_core.h
> > > @@ -138,6 +138,7 @@ enum musb_g_ep0_state {
> > >   */
> > >  struct musb_platform_ops {
> > >  
> > > +#define MUSB_MTK_QUIRKS	BIT(10)
> > >  #define MUSB_G_NO_SKB_RESERVE	BIT(9)
> > >  #define MUSB_DA8XX		BIT(8)
> > >  #define MUSB_PRESERVE_SESSION	BIT(7)
> > > diff --git a/drivers/usb/musb/musb_dma.h b/drivers/usb/musb/musb_dma.h
> > > index 281e75d3..b218210 100644
> > > --- a/drivers/usb/musb/musb_dma.h
> > > +++ b/drivers/usb/musb/musb_dma.h
> > > @@ -197,6 +197,7 @@ static inline void musb_dma_controller_destroy(struct dma_controller *d) { }
> > >  extern struct dma_controller *
> > >  musbhs_dma_controller_create(struct musb *musb, void __iomem *base);
> > >  extern void musbhs_dma_controller_destroy(struct dma_controller *c);
> > > +extern irqreturn_t dma_controller_irq(int irq, void *private_data);
> > >  
> > >  extern struct dma_controller *
> > >  tusb_dma_controller_create(struct musb *musb, void __iomem *base);
> > > diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
> > > index b59ce9a..b1b0216 100644
> > > --- a/drivers/usb/musb/musb_host.c
> > > +++ b/drivers/usb/musb/musb_host.c
> > > @@ -292,20 +292,73 @@ static inline void musb_save_toggle(struct musb_qh *qh, int is_in,
> > >  {
> > >  	void __iomem		*epio = qh->hw_ep->regs;
> > >  	u16			csr;
> > > +	struct musb *musb = qh->hw_ep->musb;
> > >  
> > >  	/*
> > >  	 * FIXME: the current Mentor DMA code seems to have
> > >  	 * problems getting toggle correct.
> > >  	 */
> > >  
> > > -	if (is_in)
> > > -		csr = musb_readw(epio, MUSB_RXCSR) & MUSB_RXCSR_H_DATATOGGLE;
> > > -	else
> > > -		csr = musb_readw(epio, MUSB_TXCSR) & MUSB_TXCSR_H_DATATOGGLE;
> > > +	/* MediaTek controller has private toggle register */
> > 
> > only one toggle register for all endpoints? how does it handle
> > difference toggle values for different endpoints?
> 
> MediaTek controller has separate registers to describe TX/RX toggle.

Is it one register per endpoint?

> 
> > > +	if (musb->ops->quirks & MUSB_MTK_QUIRKS) {
> > > +		u16 toggle;
> > > +		u8 epnum = qh->hw_ep->epnum;
> > > +
> > > +		if (is_in)
> > > +			toggle = musb_readl(musb->mregs, MUSB_RXTOG);

this line seems telling there is just *one* register for all endpoints.

> > 
> > should use musb_readw() instead? MUSB_RXTOG seems to be 16bit.
> 
> Ok
> 
> > > +		else
> > > +			toggle = musb_readl(musb->mregs, MUSB_TXTOG);
> > > +
> > > +		csr = toggle & (1 << epnum);
> > > +	} else {
> > > +		if (is_in)
> > > +			csr = musb_readw(epio, MUSB_RXCSR)
> > > +				& MUSB_RXCSR_H_DATATOGGLE;
> > > +		else
> > > +			csr = musb_readw(epio, MUSB_TXCSR)
> > > +				& MUSB_TXCSR_H_DATATOGGLE;
> > 
> > Does this logic still work for the mtk platform even if it has its own
> > private toggle register? If so, we don't need to change here.
> 
> Sorry, this logic can not work on mtk platform, bit
> MUSB_RXCSR_H_DATATOGGLE and MUSB_TXCSR_H_DATATOGGLE are used for other
> function.

Is there a different controller RTL version we can use to
differentiate?

> 
> > If not, let's try to not use this quirk flag. Please create a hook
> > musb_platform_get_toggle() in struct musb_platform_ops.
> 
> Does the method of implement musb_platform_get_toggle() is prepare
> musb_default_get_toggle with common function, then follow how
> musb_readb() pointer is assigned in musb_init_controller()?

Yes, similar to musb_readb() implementation.

> How about creating musb_platform_get_toggle() as following:
> u16 (*get_toggle)(struct musb* musb, struct musb_qh *qh, int is_in);

yes, it is part of the implementation, then add it in struct musb_io.

> 
> > > +	}
> > >  
> > >  	usb_settoggle(urb->dev, qh->epnum, !is_in, csr ? 1 : 0);
> > >  }
> > >  
> > > +static inline u16 musb_set_toggle(struct musb_qh *qh, int is_in,
> > > +					struct urb *urb)
> > > +{
> > > +	u16 csr = 0;
> > > +	u16 toggle = 0;
> > > +	struct musb *musb = qh->hw_ep->musb;
> > > +	u8 epnum = qh->hw_ep->epnum;
> > > +
> > > +	toggle = usb_gettoggle(urb->dev, qh->epnum, !is_in);
> > > +
> > > +	/* MediaTek controller has private toggle register */
> > > +	if (musb->ops->quirks & MUSB_MTK_QUIRKS) {
> > > +		if (is_in) {
> > > +			musb_writel(musb->mregs, MUSB_RXTOGEN, (1 << epnum));
> > > +			musb_writel(musb->mregs, MUSB_RXTOG, (toggle << epnum));
> > > +		} else {
> > > +			musb_writel(musb->mregs, MUSB_TXTOGEN, (1 << epnum));
> > > +			musb_writel(musb->mregs, MUSB_TXTOG, (toggle << epnum));
> > > +		}
> > > +	} else {
> > > +		if (is_in) {
> > > +			if (toggle)
> > > +				csr = MUSB_RXCSR_H_WR_DATATOGGLE
> > > +						| MUSB_RXCSR_H_DATATOGGLE;
> > > +			else
> > > +				csr = 0;
> > > +		} else {
> > > +			if (toggle)
> > > +				csr |= MUSB_TXCSR_H_WR_DATATOGGLE
> > > +						| MUSB_TXCSR_H_DATATOGGLE;
> > > +			else
> > > +				csr |= MUSB_TXCSR_CLRDATATOG;

'? :' operation probably is better than 'if else' here.

> > > +		}
> > > +	}
> > > +	return csr;
> > 
> > Please create a seperate patch for this musb_set_toggle() without adding
> > the mtk logic. It is a nice cleanup.
> 
> Does this like get toggle implementation, create a hook
> musb_platform_set_toggle() in struct musb_platform_ops?

You did the code cleanup by creating musb_set_toggle(), please make it
in a separate patch, like

static u16 musb_set_toggle(struct musb_qh *qh, int is_in, struct urb *urb)
{
	toggle = usb_gettoggle(urb->dev, qh->epnum, !is_in);
	if (is_in)
		csr = toggle ? 
			(MUSB_RXCSR_H_WR_DATATOGGLE | MUSB_RXCSR_H_DATATOGGLE) :
			0;
	else
		csr = toggle ?
			MUSB_TXCSR_H_WR_DATATOGGLE | MUSB_TXCSR_H_DATATOGGLE :
			MUSB_TXCSR_CLRDATATOG;
	return csr;
}

/* use musb_set_toggle() in the two instances */

then in this patch you add the mtk implementation similar as
*get_toggle() discussed above.

> 
> > > +}
> > > +
> > >  /*
> > >   * Advance this hardware endpoint's queue, completing the specified URB and
> > >   * advancing to either the next URB queued to that qh, or else invalidating
> > > @@ -772,13 +825,8 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
> > >  					);
> > >  			csr |= MUSB_TXCSR_MODE;
> > >  
> > > -			if (!hw_ep->tx_double_buffered) {
> > > -				if (usb_gettoggle(urb->dev, qh->epnum, 1))
> > > -					csr |= MUSB_TXCSR_H_WR_DATATOGGLE
> > > -						| MUSB_TXCSR_H_DATATOGGLE;
> > > -				else
> > > -					csr |= MUSB_TXCSR_CLRDATATOG;
> > > -			}
> > > +			if (!hw_ep->tx_double_buffered)
> > > +				csr |= musb_set_toggle(qh, !is_out, urb);
> > >  
> > >  			musb_writew(epio, MUSB_TXCSR, csr);
> > >  			/* REVISIT may need to clear FLUSHFIFO ... */
> > > @@ -860,17 +908,12 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
> > >  
> > >  	/* IN/receive */
> > >  	} else {
> > > -		u16	csr;
> > > +		u16	csr = 0;
> > >  
> > >  		if (hw_ep->rx_reinit) {
> > >  			musb_rx_reinit(musb, qh, epnum);
> > > +			csr |= musb_set_toggle(qh, !is_out, urb);
> > >  
> > > -			/* init new state: toggle and NYET, maybe DMA later */
> > > -			if (usb_gettoggle(urb->dev, qh->epnum, 0))
> > > -				csr = MUSB_RXCSR_H_WR_DATATOGGLE
> > > -					| MUSB_RXCSR_H_DATATOGGLE;
> > > -			else
> > > -				csr = 0;
> > >  			if (qh->type == USB_ENDPOINT_XFER_INT)
> > >  				csr |= MUSB_RXCSR_DISNYET;
> > >  
> > > diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h
> > > index 5cd7264..ffbe267 100644
> > > --- a/drivers/usb/musb/musb_regs.h
> > > +++ b/drivers/usb/musb/musb_regs.h
> > > @@ -273,6 +273,12 @@
> > >  #define MUSB_RXHUBADDR		0x06
> > >  #define MUSB_RXHUBPORT		0x07
> > >  
> > > +/* MediaTek controller toggle enable and status reg */
> > > +#define MUSB_RXTOG		0x80
> > > +#define MUSB_RXTOGEN		0x82
> > > +#define MUSB_TXTOG		0x84
> > > +#define MUSB_TXTOGEN		0x86
> > 
> > Again, these offsets are for different registers in the MUSB version I
> > have, please let me know if you have different version of the MUSB IP.
> 
> Sorry, these are MediaTek controller private registers used for control
> toggle.

Okay. Once the platform get/set_toggle() are implemented, those
registers can be defined in the mtk glue driver instead of here.

Regards,
-Bin.

WARNING: multiple messages have this Message-ID (diff)
From: Bin Liu <b-liu@ti.com>
To: Min Guo <min.guo@mediatek.com>
Cc: Mark Rutland <mark.rutland@arm.com>,
	devicetree@vger.kernel.org,
	Yonglong Wu <yonglong.wu@mediatek.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org,
	Matthias Brugger <matthias.bgg@gmail.com>,
	Rob Herring <robh+dt@kernel.org>,
	Alan Stern <stern@rowland.harvard.edu>,
	chunfeng.yun@mediatek.com, linux-mediatek@lists.infradead.org,
	linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH 4/4] usb: musb: Add support for MediaTek musb controller
Date: Wed, 9 Jan 2019 08:01:44 -0600	[thread overview]
Message-ID: <20190109140144.GI25910@uda0271908> (raw)
In-Reply-To: <1547037068.4433.122.camel@mhfsdcap03>

Hi Min,

On Wed, Jan 09, 2019 at 08:31:08PM +0800, Min Guo wrote:
> Hi Bin,
> On Tue, 2019-01-08 at 09:44 -0600, Bin Liu wrote:
> > Hi,
> > 
> > On Thu, Dec 27, 2018 at 03:34:26PM +0800, min.guo@mediatek.com wrote:
> > > From: Min Guo <min.guo@mediatek.com>
> > > 
> > > This adds support for MediaTek musb controller in
> > > host, peripheral and otg mode
> > > 
> > > Signed-off-by: Min Guo <min.guo@mediatek.com>
> > > Signed-off-by: Yonglong Wu <yonglong.wu@mediatek.com>
> > > ---
> > >  drivers/usb/musb/Kconfig     |   8 +-
> > >  drivers/usb/musb/Makefile    |   1 +
> > >  drivers/usb/musb/mediatek.c  | 562 +++++++++++++++++++++++++++++++++++++++++++
> > >  drivers/usb/musb/musb_core.c |  10 +
> > >  drivers/usb/musb/musb_core.h |   1 +
> > >  drivers/usb/musb/musb_dma.h  |   1 +
> > >  drivers/usb/musb/musb_host.c |  79 ++++--
> > >  drivers/usb/musb/musb_regs.h |   6 +
> > >  drivers/usb/musb/musbhsdma.c |  34 ++-
> > >  9 files changed, 671 insertions(+), 31 deletions(-)
> > >  create mode 100644 drivers/usb/musb/mediatek.c
> > > 
> > > diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
> > > index ad08895..540fc9f 100644
> > > --- a/drivers/usb/musb/Kconfig
> > > +++ b/drivers/usb/musb/Kconfig
> > > @@ -115,6 +115,12 @@ config USB_MUSB_JZ4740
> > >  	depends on USB_MUSB_GADGET
> > >  	depends on USB_OTG_BLACKLIST_HUB
> > >  
> > > +config USB_MUSB_MEDIATEK
> > > +	tristate "MediaTek platforms"
> > > +	depends on ARCH_MEDIATEK
> > 
> > Please also add '|| COMPILE_TEST' to make testing easier.
> 
> Ok
> 
> > > +	depends on NOP_USB_XCEIV
> > > +	depends on GENERIC_PHY
> > > +
> > >  config USB_MUSB_AM335X_CHILD
> > >  	tristate
> > >  
> > > @@ -141,7 +147,7 @@ config USB_UX500_DMA
> > >  
> > >  config USB_INVENTRA_DMA
> > >  	bool 'Inventra'
> > > -	depends on USB_MUSB_OMAP2PLUS
> > > +	depends on USB_MUSB_OMAP2PLUS || USB_MUSB_MEDIATEK
> > >  	help
> > >  	  Enable DMA transfers using Mentor's engine.
> > >  
> > > diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile
> > > index 3a88c79..63d82d0 100644
> > > --- a/drivers/usb/musb/Makefile
> > > +++ b/drivers/usb/musb/Makefile
> > > @@ -24,6 +24,7 @@ obj-$(CONFIG_USB_MUSB_DA8XX)			+= da8xx.o
> > >  obj-$(CONFIG_USB_MUSB_UX500)			+= ux500.o
> > >  obj-$(CONFIG_USB_MUSB_JZ4740)			+= jz4740.o
> > >  obj-$(CONFIG_USB_MUSB_SUNXI)			+= sunxi.o
> > > +obj-$(CONFIG_USB_MUSB_MEDIATEK)      		+= mediatek.o
> > >  
> > >  
> > >  obj-$(CONFIG_USB_MUSB_AM335X_CHILD)		+= musb_am335x.o
> > > diff --git a/drivers/usb/musb/mediatek.c b/drivers/usb/musb/mediatek.c
> > > new file mode 100644
> > > index 0000000..15a6460
> > > --- /dev/null
> > > +++ b/drivers/usb/musb/mediatek.c
> > 
> > [snip]
> > I will review this section later after we sorted out other things.
> > 
> > > diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
> > > index b7d5627..d60f76f 100644
> > > --- a/drivers/usb/musb/musb_core.c
> > > +++ b/drivers/usb/musb/musb_core.c
> > > @@ -1028,6 +1028,16 @@ static void musb_disable_interrupts(struct musb *musb)
> > >  	temp = musb_readb(mbase, MUSB_INTRUSB);
> > >  	temp = musb_readw(mbase, MUSB_INTRTX);
> > >  	temp = musb_readw(mbase, MUSB_INTRRX);
> > > +
> > > +	/*  MediaTek controller interrupt status is W1C */
> > 
> > This W1C doesn't match to the MUSB Programming Guide that I have. Those
> > registers are read-only.
> > Is the difference due to the IP intergration in the mtk platforms? or is
> > it a new version of the MUSB controller? If latter, what is the version?
> 
> This is difference due to the IP intergration in mtk platforms. W1C is
> easy for CpdeViser debug.
> 
> > > +	if (musb->ops->quirks & MUSB_MTK_QUIRKS) {
> > 
> > Basically we don't want to use this type of platform specific quirks if
> > possible, so let's try to not use it.
> 
> I will try my best to avoid using it.

Thanks.

> 
> > > +		musb_writeb(mbase, MUSB_INTRUSB,
> > > +			musb_readb(mbase, MUSB_INTRUSB));
> > 
> > For this clearing register bit operation, please create platform hooks
> > musb_clearb() and musb_clearw() in struct musb_platform_ops instead,
> > then follow how musb_readb() pointer is assigned in
> > musb_init_controller() to use the W1C version for mtk platform.
> 
> I have tried implementing musb_readb(), musb_readw() interface with
> interrupt status W1C function in struct musb_platform_ops. But this
> interface will require a global variable to hold MAC basic address for
> judgment, and then special handling of the interrupt state. A global
> variable will make the driver work with only a single instance, so it
> can't work on some MTK platforms which have two instances.

I didn't mean to modify musb_read*(), but

> How about creating musb_clearb/w() as following:
> void (*clearb)(void __iomem *addr, unsigned offset, u8 data);
> void (*clearw)(void __iomem *addr, unsigned offset, u16 data);

this is what I was asking for, similar to what musb_readb/w() is
implemented.

> 
> 
> > > +		musb_writew(mbase, MUSB_INTRRX,
> > > +			musb_readw(mbase, MUSB_INTRRX));
> > > +		musb_writew(mbase, MUSB_INTRTX,
> > > +			musb_readw(mbase, MUSB_INTRTX));
> > > +	}
> > >  }
> > >  
> > >  static void musb_enable_interrupts(struct musb *musb)
> > > diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
> > > index 04203b7..1bf4e9a 100644
> > > --- a/drivers/usb/musb/musb_core.h
> > > +++ b/drivers/usb/musb/musb_core.h
> > > @@ -138,6 +138,7 @@ enum musb_g_ep0_state {
> > >   */
> > >  struct musb_platform_ops {
> > >  
> > > +#define MUSB_MTK_QUIRKS	BIT(10)
> > >  #define MUSB_G_NO_SKB_RESERVE	BIT(9)
> > >  #define MUSB_DA8XX		BIT(8)
> > >  #define MUSB_PRESERVE_SESSION	BIT(7)
> > > diff --git a/drivers/usb/musb/musb_dma.h b/drivers/usb/musb/musb_dma.h
> > > index 281e75d3..b218210 100644
> > > --- a/drivers/usb/musb/musb_dma.h
> > > +++ b/drivers/usb/musb/musb_dma.h
> > > @@ -197,6 +197,7 @@ static inline void musb_dma_controller_destroy(struct dma_controller *d) { }
> > >  extern struct dma_controller *
> > >  musbhs_dma_controller_create(struct musb *musb, void __iomem *base);
> > >  extern void musbhs_dma_controller_destroy(struct dma_controller *c);
> > > +extern irqreturn_t dma_controller_irq(int irq, void *private_data);
> > >  
> > >  extern struct dma_controller *
> > >  tusb_dma_controller_create(struct musb *musb, void __iomem *base);
> > > diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
> > > index b59ce9a..b1b0216 100644
> > > --- a/drivers/usb/musb/musb_host.c
> > > +++ b/drivers/usb/musb/musb_host.c
> > > @@ -292,20 +292,73 @@ static inline void musb_save_toggle(struct musb_qh *qh, int is_in,
> > >  {
> > >  	void __iomem		*epio = qh->hw_ep->regs;
> > >  	u16			csr;
> > > +	struct musb *musb = qh->hw_ep->musb;
> > >  
> > >  	/*
> > >  	 * FIXME: the current Mentor DMA code seems to have
> > >  	 * problems getting toggle correct.
> > >  	 */
> > >  
> > > -	if (is_in)
> > > -		csr = musb_readw(epio, MUSB_RXCSR) & MUSB_RXCSR_H_DATATOGGLE;
> > > -	else
> > > -		csr = musb_readw(epio, MUSB_TXCSR) & MUSB_TXCSR_H_DATATOGGLE;
> > > +	/* MediaTek controller has private toggle register */
> > 
> > only one toggle register for all endpoints? how does it handle
> > difference toggle values for different endpoints?
> 
> MediaTek controller has separate registers to describe TX/RX toggle.

Is it one register per endpoint?

> 
> > > +	if (musb->ops->quirks & MUSB_MTK_QUIRKS) {
> > > +		u16 toggle;
> > > +		u8 epnum = qh->hw_ep->epnum;
> > > +
> > > +		if (is_in)
> > > +			toggle = musb_readl(musb->mregs, MUSB_RXTOG);

this line seems telling there is just *one* register for all endpoints.

> > 
> > should use musb_readw() instead? MUSB_RXTOG seems to be 16bit.
> 
> Ok
> 
> > > +		else
> > > +			toggle = musb_readl(musb->mregs, MUSB_TXTOG);
> > > +
> > > +		csr = toggle & (1 << epnum);
> > > +	} else {
> > > +		if (is_in)
> > > +			csr = musb_readw(epio, MUSB_RXCSR)
> > > +				& MUSB_RXCSR_H_DATATOGGLE;
> > > +		else
> > > +			csr = musb_readw(epio, MUSB_TXCSR)
> > > +				& MUSB_TXCSR_H_DATATOGGLE;
> > 
> > Does this logic still work for the mtk platform even if it has its own
> > private toggle register? If so, we don't need to change here.
> 
> Sorry, this logic can not work on mtk platform, bit
> MUSB_RXCSR_H_DATATOGGLE and MUSB_TXCSR_H_DATATOGGLE are used for other
> function.

Is there a different controller RTL version we can use to
differentiate?

> 
> > If not, let's try to not use this quirk flag. Please create a hook
> > musb_platform_get_toggle() in struct musb_platform_ops.
> 
> Does the method of implement musb_platform_get_toggle() is prepare
> musb_default_get_toggle with common function, then follow how
> musb_readb() pointer is assigned in musb_init_controller()?

Yes, similar to musb_readb() implementation.

> How about creating musb_platform_get_toggle() as following:
> u16 (*get_toggle)(struct musb* musb, struct musb_qh *qh, int is_in);

yes, it is part of the implementation, then add it in struct musb_io.

> 
> > > +	}
> > >  
> > >  	usb_settoggle(urb->dev, qh->epnum, !is_in, csr ? 1 : 0);
> > >  }
> > >  
> > > +static inline u16 musb_set_toggle(struct musb_qh *qh, int is_in,
> > > +					struct urb *urb)
> > > +{
> > > +	u16 csr = 0;
> > > +	u16 toggle = 0;
> > > +	struct musb *musb = qh->hw_ep->musb;
> > > +	u8 epnum = qh->hw_ep->epnum;
> > > +
> > > +	toggle = usb_gettoggle(urb->dev, qh->epnum, !is_in);
> > > +
> > > +	/* MediaTek controller has private toggle register */
> > > +	if (musb->ops->quirks & MUSB_MTK_QUIRKS) {
> > > +		if (is_in) {
> > > +			musb_writel(musb->mregs, MUSB_RXTOGEN, (1 << epnum));
> > > +			musb_writel(musb->mregs, MUSB_RXTOG, (toggle << epnum));
> > > +		} else {
> > > +			musb_writel(musb->mregs, MUSB_TXTOGEN, (1 << epnum));
> > > +			musb_writel(musb->mregs, MUSB_TXTOG, (toggle << epnum));
> > > +		}
> > > +	} else {
> > > +		if (is_in) {
> > > +			if (toggle)
> > > +				csr = MUSB_RXCSR_H_WR_DATATOGGLE
> > > +						| MUSB_RXCSR_H_DATATOGGLE;
> > > +			else
> > > +				csr = 0;
> > > +		} else {
> > > +			if (toggle)
> > > +				csr |= MUSB_TXCSR_H_WR_DATATOGGLE
> > > +						| MUSB_TXCSR_H_DATATOGGLE;
> > > +			else
> > > +				csr |= MUSB_TXCSR_CLRDATATOG;

'? :' operation probably is better than 'if else' here.

> > > +		}
> > > +	}
> > > +	return csr;
> > 
> > Please create a seperate patch for this musb_set_toggle() without adding
> > the mtk logic. It is a nice cleanup.
> 
> Does this like get toggle implementation, create a hook
> musb_platform_set_toggle() in struct musb_platform_ops?

You did the code cleanup by creating musb_set_toggle(), please make it
in a separate patch, like

static u16 musb_set_toggle(struct musb_qh *qh, int is_in, struct urb *urb)
{
	toggle = usb_gettoggle(urb->dev, qh->epnum, !is_in);
	if (is_in)
		csr = toggle ? 
			(MUSB_RXCSR_H_WR_DATATOGGLE | MUSB_RXCSR_H_DATATOGGLE) :
			0;
	else
		csr = toggle ?
			MUSB_TXCSR_H_WR_DATATOGGLE | MUSB_TXCSR_H_DATATOGGLE :
			MUSB_TXCSR_CLRDATATOG;
	return csr;
}

/* use musb_set_toggle() in the two instances */

then in this patch you add the mtk implementation similar as
*get_toggle() discussed above.

> 
> > > +}
> > > +
> > >  /*
> > >   * Advance this hardware endpoint's queue, completing the specified URB and
> > >   * advancing to either the next URB queued to that qh, or else invalidating
> > > @@ -772,13 +825,8 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
> > >  					);
> > >  			csr |= MUSB_TXCSR_MODE;
> > >  
> > > -			if (!hw_ep->tx_double_buffered) {
> > > -				if (usb_gettoggle(urb->dev, qh->epnum, 1))
> > > -					csr |= MUSB_TXCSR_H_WR_DATATOGGLE
> > > -						| MUSB_TXCSR_H_DATATOGGLE;
> > > -				else
> > > -					csr |= MUSB_TXCSR_CLRDATATOG;
> > > -			}
> > > +			if (!hw_ep->tx_double_buffered)
> > > +				csr |= musb_set_toggle(qh, !is_out, urb);
> > >  
> > >  			musb_writew(epio, MUSB_TXCSR, csr);
> > >  			/* REVISIT may need to clear FLUSHFIFO ... */
> > > @@ -860,17 +908,12 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
> > >  
> > >  	/* IN/receive */
> > >  	} else {
> > > -		u16	csr;
> > > +		u16	csr = 0;
> > >  
> > >  		if (hw_ep->rx_reinit) {
> > >  			musb_rx_reinit(musb, qh, epnum);
> > > +			csr |= musb_set_toggle(qh, !is_out, urb);
> > >  
> > > -			/* init new state: toggle and NYET, maybe DMA later */
> > > -			if (usb_gettoggle(urb->dev, qh->epnum, 0))
> > > -				csr = MUSB_RXCSR_H_WR_DATATOGGLE
> > > -					| MUSB_RXCSR_H_DATATOGGLE;
> > > -			else
> > > -				csr = 0;
> > >  			if (qh->type == USB_ENDPOINT_XFER_INT)
> > >  				csr |= MUSB_RXCSR_DISNYET;
> > >  
> > > diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h
> > > index 5cd7264..ffbe267 100644
> > > --- a/drivers/usb/musb/musb_regs.h
> > > +++ b/drivers/usb/musb/musb_regs.h
> > > @@ -273,6 +273,12 @@
> > >  #define MUSB_RXHUBADDR		0x06
> > >  #define MUSB_RXHUBPORT		0x07
> > >  
> > > +/* MediaTek controller toggle enable and status reg */
> > > +#define MUSB_RXTOG		0x80
> > > +#define MUSB_RXTOGEN		0x82
> > > +#define MUSB_TXTOG		0x84
> > > +#define MUSB_TXTOGEN		0x86
> > 
> > Again, these offsets are for different registers in the MUSB version I
> > have, please let me know if you have different version of the MUSB IP.
> 
> Sorry, these are MediaTek controller private registers used for control
> toggle.

Okay. Once the platform get/set_toggle() are implemented, those
registers can be defined in the mtk glue driver instead of here.

Regards,
-Bin.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2019-01-09 14:02 UTC|newest]

Thread overview: 71+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-27  7:34 [PATCH 0/4] Add MediaTek MUSB Controller Driver min.guo
2018-12-27  7:34 ` min.guo
2018-12-27  7:34 ` min.guo
2018-12-27  7:34 ` [PATCH 1/4] dt-bindings: usb: musb: Add support for MediaTek musb controller min.guo
2018-12-27  7:34   ` min.guo
2018-12-27  7:34   ` [1/4] " min.guo
2018-12-27  7:34   ` [PATCH 1/4] " min.guo
2019-01-03 22:14   ` Rob Herring
2019-01-03 22:14     ` Rob Herring
2019-01-03 22:14     ` [1/4] " Rob Herring
2019-01-04  3:00     ` [PATCH 1/4] " Min Guo
2019-01-04  3:00       ` Min Guo
2019-01-04  3:00       ` [1/4] " min.guo
2019-01-04  3:00       ` [PATCH 1/4] " Min Guo
2019-01-04 16:10       ` Rob Herring
2019-01-04 16:10         ` Rob Herring
2019-01-04 16:10         ` [1/4] " Rob Herring
2019-01-04 16:10         ` [PATCH 1/4] " Rob Herring
2019-01-07  7:31         ` Min Guo
2019-01-07  7:31           ` Min Guo
2019-01-07  7:31           ` [1/4] " min.guo
2019-01-07  7:31           ` [PATCH 1/4] " Min Guo
2019-01-08 14:05           ` Rob Herring
2019-01-07 20:40   ` Bin Liu
2019-01-07 20:40     ` Bin Liu
2019-01-07 20:40     ` [1/4] " Bin Liu
2019-01-07 20:40     ` [PATCH 1/4] " Bin Liu
2019-01-08  1:30     ` Min Guo
2019-01-08  1:30       ` Min Guo
2019-01-08  1:30       ` [1/4] " min.guo
2019-01-08  1:30       ` [PATCH 1/4] " Min Guo
2018-12-27  7:34 ` [PATCH 2/4] arm: dts: mt2701: Add usb2 device nodes min.guo
2018-12-27  7:34   ` min.guo
2018-12-27  7:34   ` [2/4] " min.guo
2018-12-27  7:34   ` [PATCH 2/4] " min.guo
2018-12-27  7:34 ` [PATCH 3/4] usb: musb: Move musbhsdma macro definition to musb_dma.h min.guo
2018-12-27  7:34   ` min.guo
2018-12-27  7:34   ` [3/4] " min.guo
2018-12-27  7:34   ` [PATCH 3/4] " min.guo
2018-12-27  7:34 ` [PATCH 4/4] usb: musb: Add support for MediaTek musb controller min.guo
2018-12-27  7:34   ` min.guo
2018-12-27  7:34   ` [4/4] " min.guo
2018-12-27  7:34   ` [PATCH 4/4] " min.guo
2019-01-08 15:44   ` Bin Liu
2019-01-08 15:44     ` Bin Liu
2019-01-08 15:44     ` [4/4] " Bin Liu
2019-01-08 15:44     ` [PATCH 4/4] " Bin Liu
2019-01-09 12:31     ` Min Guo
2019-01-09 12:31       ` Min Guo
2019-01-09 12:31       ` [4/4] " min.guo
2019-01-09 12:31       ` [PATCH 4/4] " Min Guo
2019-01-09 14:01       ` Bin Liu [this message]
2019-01-09 14:01         ` Bin Liu
2019-01-09 14:01         ` [4/4] " Bin Liu
2019-01-09 14:01         ` [PATCH 4/4] " Bin Liu
2019-01-10  7:24         ` Min Guo
2019-01-10  7:24           ` Min Guo
2019-01-10  7:24           ` [4/4] " min.guo
2019-01-10  7:24           ` [PATCH 4/4] " Min Guo
2019-01-10 14:18           ` Bin Liu
2019-01-10 14:18             ` Bin Liu
2019-01-10 14:18             ` [4/4] " Bin Liu
2019-01-10 14:18             ` [PATCH 4/4] " Bin Liu
2019-01-11  1:18             ` Min Guo
2019-01-11  1:18               ` Min Guo
2019-01-11  1:18               ` [4/4] " min.guo
2019-01-11  1:18               ` [PATCH 4/4] " Min Guo
2019-01-11  5:24     ` Min Guo
2019-01-11  5:24       ` Min Guo
2019-01-11  5:24       ` [4/4] " min.guo
2019-01-11  5:24       ` [PATCH 4/4] " Min Guo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190109140144.GI25910@uda0271908 \
    --to=b-liu@ti.com \
    --cc=chunfeng.yun@mediatek.com \
    --cc=devicetree@vger.kernel.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mediatek@lists.infradead.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=matthias.bgg@gmail.com \
    --cc=min.guo@mediatek.com \
    --cc=robh+dt@kernel.org \
    --cc=stern@rowland.harvard.edu \
    --cc=yonglong.wu@mediatek.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.