2008-07-24 13:27:36 +04:00
/*
* Copyright ( C ) 2005 - 2006 by Texas Instruments
*
* This file is part of the Inventra Controller Driver for Linux .
*
* The Inventra Controller Driver for Linux is free software ; you
* can redistribute it and / or modify it under the terms of the GNU
* General Public License version 2 as published by the Free Software
* Foundation .
*
* The Inventra Controller Driver for Linux is distributed in
* the hope that it will be useful , but WITHOUT ANY WARRANTY ;
* without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public
* License for more details .
*
* You should have received a copy of the GNU General Public License
* along with The Inventra Controller Driver for Linux ; if not ,
* write to the Free Software Foundation , Inc . , 59 Temple Place ,
* Suite 330 , Boston , MA 02111 - 1307 USA
*
*/
# include <linux/module.h>
# include <linux/kernel.h>
# include <linux/sched.h>
# include <linux/slab.h>
# include <linux/init.h>
# include <linux/list.h>
# include <linux/delay.h>
# include <linux/clk.h>
# include <linux/io.h>
2008-09-11 12:53:23 +04:00
# include <linux/gpio.h>
2008-07-24 13:27:36 +04:00
2009-01-25 04:56:17 +03:00
# include <mach/hardware.h>
# include <mach/memory.h>
# include <mach/gpio.h>
2008-07-24 13:27:36 +04:00
# include <asm/mach-types.h>
# include "musb_core.h"
# ifdef CONFIG_MACH_DAVINCI_EVM
2008-09-11 12:53:23 +04:00
# define GPIO_nVBUS_DRV 87
2008-07-24 13:27:36 +04:00
# endif
# include "davinci.h"
# include "cppi_dma.h"
/* REVISIT (PM) we should be able to keep the PHY in low power mode most
* of the time ( 24 MHZ oscillator and PLL off , etc ) by setting POWER . D0
* and , when in host mode , autosuspending idle root ports . . . PHYPLLON
* ( overriding SUSPENDM ? ) then likely needs to stay off .
*/
static inline void phy_on ( void )
{
/* start the on-chip PHY and its PLL */
__raw_writel ( USBPHY_SESNDEN | USBPHY_VBDTCTEN | USBPHY_PHYPLLON ,
( void __force __iomem * ) IO_ADDRESS ( USBPHY_CTL_PADDR ) ) ;
while ( ( __raw_readl ( ( void __force __iomem * )
IO_ADDRESS ( USBPHY_CTL_PADDR ) )
& USBPHY_PHYCLKGD ) = = 0 )
cpu_relax ( ) ;
}
static inline void phy_off ( void )
{
/* powerdown the on-chip PHY and its oscillator */
__raw_writel ( USBPHY_OSCPDWN | USBPHY_PHYPDWN , ( void __force __iomem * )
IO_ADDRESS ( USBPHY_CTL_PADDR ) ) ;
}
static int dma_off = 1 ;
void musb_platform_enable ( struct musb * musb )
{
u32 tmp , old , val ;
/* workaround: setup irqs through both register sets */
tmp = ( musb - > epmask & DAVINCI_USB_TX_ENDPTS_MASK )
< < DAVINCI_USB_TXINT_SHIFT ;
musb_writel ( musb - > ctrl_base , DAVINCI_USB_INT_MASK_SET_REG , tmp ) ;
old = tmp ;
tmp = ( musb - > epmask & ( 0xfffe & DAVINCI_USB_RX_ENDPTS_MASK ) )
< < DAVINCI_USB_RXINT_SHIFT ;
musb_writel ( musb - > ctrl_base , DAVINCI_USB_INT_MASK_SET_REG , tmp ) ;
tmp | = old ;
val = ~ MUSB_INTR_SOF ;
tmp | = ( ( val & 0x01ff ) < < DAVINCI_USB_USBINT_SHIFT ) ;
musb_writel ( musb - > ctrl_base , DAVINCI_USB_INT_MASK_SET_REG , tmp ) ;
if ( is_dma_capable ( ) & & ! dma_off )
printk ( KERN_WARNING " %s %s: dma not reactivated \n " ,
__FILE__ , __func__ ) ;
else
dma_off = 0 ;
/* force a DRVVBUS irq so we can start polling for ID change */
if ( is_otg_enabled ( musb ) )
musb_writel ( musb - > ctrl_base , DAVINCI_USB_INT_SET_REG ,
DAVINCI_INTR_DRVVBUS < < DAVINCI_USB_USBINT_SHIFT ) ;
}
/*
* Disable the HDRC and flush interrupts
*/
void musb_platform_disable ( struct musb * musb )
{
/* because we don't set CTRLR.UINT, "important" to:
* - not read / write INTRUSB / INTRUSBE
* - ( except during initial setup , as workaround )
* - use INTSETR / INTCLRR instead
*/
musb_writel ( musb - > ctrl_base , DAVINCI_USB_INT_MASK_CLR_REG ,
DAVINCI_USB_USBINT_MASK
| DAVINCI_USB_TXINT_MASK
| DAVINCI_USB_RXINT_MASK ) ;
musb_writeb ( musb - > mregs , MUSB_DEVCTL , 0 ) ;
musb_writel ( musb - > ctrl_base , DAVINCI_USB_EOI_REG , 0 ) ;
if ( is_dma_capable ( ) & & ! dma_off )
WARNING ( " dma still active \n " ) ;
}
/* REVISIT it's not clear whether DaVinci can support full OTG. */
static int vbus_state = - 1 ;
# ifdef CONFIG_USB_MUSB_HDRC_HCD
# define portstate(stmt) stmt
# else
# define portstate(stmt)
# endif
/* VBUS SWITCHING IS BOARD-SPECIFIC */
# ifdef CONFIG_MACH_DAVINCI_EVM
/* I2C operations are always synchronous, and require a task context.
* With unloaded systems , using the shared workqueue seems to suffice
* to satisfy the 100 msec A_WAIT_VRISE timeout . . .
*/
static void evm_deferred_drvvbus ( struct work_struct * ignored )
{
2008-09-11 12:53:23 +04:00
gpio_set_value_cansleep ( GPIO_nVBUS_DRV , vbus_state ) ;
2008-07-24 13:27:36 +04:00
vbus_state = ! vbus_state ;
}
static DECLARE_WORK ( evm_vbus_work , evm_deferred_drvvbus ) ;
# endif /* EVM */
static void davinci_source_power ( struct musb * musb , int is_on , int immediate )
{
if ( is_on )
is_on = 1 ;
if ( vbus_state = = is_on )
return ;
vbus_state = ! is_on ; /* 0/1 vs "-1 == unknown/init" */
# ifdef CONFIG_MACH_DAVINCI_EVM
if ( machine_is_davinci_evm ( ) ) {
if ( immediate )
2008-09-11 12:53:23 +04:00
gpio_set_value_cansleep ( GPIO_nVBUS_DRV , vbus_state ) ;
2008-07-24 13:27:36 +04:00
else
schedule_work ( & evm_vbus_work ) ;
}
# endif
if ( immediate )
vbus_state = is_on ;
}
static void davinci_set_vbus ( struct musb * musb , int is_on )
{
WARN_ON ( is_on & & is_peripheral_active ( musb ) ) ;
davinci_source_power ( musb , is_on , 0 ) ;
}
# define POLL_SECONDS 2
static struct timer_list otg_workaround ;
static void otg_timer ( unsigned long _musb )
{
struct musb * musb = ( void * ) _musb ;
void __iomem * mregs = musb - > mregs ;
u8 devctl ;
unsigned long flags ;
/* We poll because DaVinci's won't expose several OTG-critical
* status change events ( from the transceiver ) otherwise .
*/
devctl = musb_readb ( mregs , MUSB_DEVCTL ) ;
DBG ( 7 , " poll devctl %02x (%s) \n " , devctl , otg_state_string ( musb ) ) ;
spin_lock_irqsave ( & musb - > lock , flags ) ;
switch ( musb - > xceiv . state ) {
case OTG_STATE_A_WAIT_VFALL :
/* Wait till VBUS falls below SessionEnd (~0.2V); the 1.3 RTL
* seems to mis - handle session " start " otherwise ( or in our
* case " recover " ) , in routine " VBUS was valid by the time
* VBUSERR got reported during enumeration " cases.
*/
if ( devctl & MUSB_DEVCTL_VBUS ) {
mod_timer ( & otg_workaround , jiffies + POLL_SECONDS * HZ ) ;
break ;
}
musb - > xceiv . state = OTG_STATE_A_WAIT_VRISE ;
musb_writel ( musb - > ctrl_base , DAVINCI_USB_INT_SET_REG ,
MUSB_INTR_VBUSERROR < < DAVINCI_USB_USBINT_SHIFT ) ;
break ;
case OTG_STATE_B_IDLE :
if ( ! is_peripheral_enabled ( musb ) )
break ;
/* There's no ID-changed IRQ, so we have no good way to tell
* when to switch to the A - Default state machine ( by setting
* the DEVCTL . SESSION flag ) .
*
* Workaround : whenever we ' re in B_IDLE , try setting the
* session flag every few seconds . If it works , ID was
* grounded and we ' re now in the A - Default state machine .
*
* NOTE setting the session flag is _supposed_ to trigger
* SRP , but clearly it doesn ' t .
*/
musb_writeb ( mregs , MUSB_DEVCTL ,
devctl | MUSB_DEVCTL_SESSION ) ;
devctl = musb_readb ( mregs , MUSB_DEVCTL ) ;
if ( devctl & MUSB_DEVCTL_BDEVICE )
mod_timer ( & otg_workaround , jiffies + POLL_SECONDS * HZ ) ;
else
musb - > xceiv . state = OTG_STATE_A_IDLE ;
break ;
default :
break ;
}
spin_unlock_irqrestore ( & musb - > lock , flags ) ;
}
static irqreturn_t davinci_interrupt ( int irq , void * __hci )
{
unsigned long flags ;
irqreturn_t retval = IRQ_NONE ;
struct musb * musb = __hci ;
void __iomem * tibase = musb - > ctrl_base ;
u32 tmp ;
spin_lock_irqsave ( & musb - > lock , flags ) ;
/* NOTE: DaVinci shadows the Mentor IRQs. Don't manage them through
* the Mentor registers ( except for setup ) , use the TI ones and EOI .
*
* Docs describe irq " vector " registers asociated with the CPPI and
* USB EOI registers . These hold a bitmask corresponding to the
* current IRQ , not an irq handler address . Would using those bits
* resolve some of the races observed in this dispatch code ? ?
*/
/* CPPI interrupts share the same IRQ line, but have their own
* mask , state , " vector " , and EOI registers .
*/
if ( is_cppi_enabled ( ) ) {
u32 cppi_tx = musb_readl ( tibase , DAVINCI_TXCPPI_MASKED_REG ) ;
u32 cppi_rx = musb_readl ( tibase , DAVINCI_RXCPPI_MASKED_REG ) ;
if ( cppi_tx | | cppi_rx ) {
DBG ( 4 , " CPPI IRQ t%x r%x \n " , cppi_tx , cppi_rx ) ;
cppi_completion ( musb , cppi_rx , cppi_tx ) ;
retval = IRQ_HANDLED ;
}
}
/* ack and handle non-CPPI interrupts */
tmp = musb_readl ( tibase , DAVINCI_USB_INT_SRC_MASKED_REG ) ;
musb_writel ( tibase , DAVINCI_USB_INT_SRC_CLR_REG , tmp ) ;
DBG ( 4 , " IRQ %08x \n " , tmp ) ;
musb - > int_rx = ( tmp & DAVINCI_USB_RXINT_MASK )
> > DAVINCI_USB_RXINT_SHIFT ;
musb - > int_tx = ( tmp & DAVINCI_USB_TXINT_MASK )
> > DAVINCI_USB_TXINT_SHIFT ;
musb - > int_usb = ( tmp & DAVINCI_USB_USBINT_MASK )
> > DAVINCI_USB_USBINT_SHIFT ;
/* DRVVBUS irqs are the only proxy we have (a very poor one!) for
* DaVinci ' s missing ID change IRQ . We need an ID change IRQ to
* switch appropriately between halves of the OTG state machine .
* Managing DEVCTL . SESSION per Mentor docs requires we know its
* value , but DEVCTL . BDEVICE is invalid without DEVCTL . SESSION set .
* Also , DRVVBUS pulses for SRP ( but not at 5 V ) . . .
*/
if ( tmp & ( DAVINCI_INTR_DRVVBUS < < DAVINCI_USB_USBINT_SHIFT ) ) {
int drvvbus = musb_readl ( tibase , DAVINCI_USB_STAT_REG ) ;
void __iomem * mregs = musb - > mregs ;
u8 devctl = musb_readb ( mregs , MUSB_DEVCTL ) ;
int err = musb - > int_usb & MUSB_INTR_VBUSERROR ;
err = is_host_enabled ( musb )
& & ( musb - > int_usb & MUSB_INTR_VBUSERROR ) ;
if ( err ) {
/* The Mentor core doesn't debounce VBUS as needed
* to cope with device connect current spikes . This
* means it ' s not uncommon for bus - powered devices
* to get VBUS errors during enumeration .
*
* This is a workaround , but newer RTL from Mentor
* seems to allow a better one : " re " starting sessions
* without waiting ( on EVM , a * * long * * time ) for VBUS
* to stop registering in devctl .
*/
musb - > int_usb & = ~ MUSB_INTR_VBUSERROR ;
musb - > xceiv . state = OTG_STATE_A_WAIT_VFALL ;
mod_timer ( & otg_workaround , jiffies + POLL_SECONDS * HZ ) ;
WARNING ( " VBUS error workaround (delay coming) \n " ) ;
} else if ( is_host_enabled ( musb ) & & drvvbus ) {
musb - > is_active = 1 ;
MUSB_HST_MODE ( musb ) ;
musb - > xceiv . default_a = 1 ;
musb - > xceiv . state = OTG_STATE_A_WAIT_VRISE ;
portstate ( musb - > port1_status | = USB_PORT_STAT_POWER ) ;
del_timer ( & otg_workaround ) ;
} else {
musb - > is_active = 0 ;
MUSB_DEV_MODE ( musb ) ;
musb - > xceiv . default_a = 0 ;
musb - > xceiv . state = OTG_STATE_B_IDLE ;
portstate ( musb - > port1_status & = ~ USB_PORT_STAT_POWER ) ;
}
/* NOTE: this must complete poweron within 100 msec */
davinci_source_power ( musb , drvvbus , 0 ) ;
DBG ( 2 , " VBUS %s (%s)%s, devctl %02x \n " ,
drvvbus ? " on " : " off " ,
otg_state_string ( musb ) ,
err ? " ERROR " : " " ,
devctl ) ;
retval = IRQ_HANDLED ;
}
if ( musb - > int_tx | | musb - > int_rx | | musb - > int_usb )
retval | = musb_interrupt ( musb ) ;
/* irq stays asserted until EOI is written */
musb_writel ( tibase , DAVINCI_USB_EOI_REG , 0 ) ;
/* poll for ID change */
if ( is_otg_enabled ( musb )
& & musb - > xceiv . state = = OTG_STATE_B_IDLE )
mod_timer ( & otg_workaround , jiffies + POLL_SECONDS * HZ ) ;
spin_unlock_irqrestore ( & musb - > lock , flags ) ;
/* REVISIT we sometimes get unhandled IRQs
* ( e . g . ep0 ) . not clear why . . .
*/
if ( retval ! = IRQ_HANDLED )
DBG ( 5 , " unhandled? %08x \n " , tmp ) ;
return IRQ_HANDLED ;
}
2008-11-24 14:06:47 +03:00
int musb_platform_set_mode ( struct musb * musb , u8 mode )
{
/* EVM can't do this (right?) */
return - EIO ;
}
2008-07-24 13:27:36 +04:00
int __init musb_platform_init ( struct musb * musb )
{
void __iomem * tibase = musb - > ctrl_base ;
u32 revision ;
musb - > mregs + = DAVINCI_BASE_OFFSET ;
#if 0
/* REVISIT there's something odd about clocking, this
* didn ' t appear do the job . . .
*/
musb - > clock = clk_get ( pDevice , " usb " ) ;
if ( IS_ERR ( musb - > clock ) )
return PTR_ERR ( musb - > clock ) ;
status = clk_enable ( musb - > clock ) ;
if ( status < 0 )
return - ENODEV ;
# endif
/* returns zero if e.g. not clocked */
revision = musb_readl ( tibase , DAVINCI_USB_VERSION_REG ) ;
if ( revision = = 0 )
return - ENODEV ;
if ( is_host_enabled ( musb ) )
setup_timer ( & otg_workaround , otg_timer , ( unsigned long ) musb ) ;
musb - > board_set_vbus = davinci_set_vbus ;
davinci_source_power ( musb , 0 , 1 ) ;
/* reset the controller */
musb_writel ( tibase , DAVINCI_USB_CTRL_REG , 0x1 ) ;
/* start the on-chip PHY and its PLL */
phy_on ( ) ;
msleep ( 5 ) ;
/* NOTE: irqs are in mixed mode, not bypass to pure-musb */
pr_debug ( " DaVinci OTG revision %08x phy %03x control %02x \n " ,
revision , __raw_readl ( ( void __force __iomem * )
IO_ADDRESS ( USBPHY_CTL_PADDR ) ) ,
musb_readb ( tibase , DAVINCI_USB_CTRL_REG ) ) ;
musb - > isr = davinci_interrupt ;
return 0 ;
}
int musb_platform_exit ( struct musb * musb )
{
if ( is_host_enabled ( musb ) )
del_timer_sync ( & otg_workaround ) ;
davinci_source_power ( musb , 0 /*off*/ , 1 ) ;
/* delay, to avoid problems with module reload */
if ( is_host_enabled ( musb ) & & musb - > xceiv . default_a ) {
int maxdelay = 30 ;
u8 devctl , warn = 0 ;
/* if there's no peripheral connected, this can take a
* long time to fall , especially on EVM with huge C133 .
*/
do {
devctl = musb_readb ( musb - > mregs , MUSB_DEVCTL ) ;
if ( ! ( devctl & MUSB_DEVCTL_VBUS ) )
break ;
if ( ( devctl & MUSB_DEVCTL_VBUS ) ! = warn ) {
warn = devctl & MUSB_DEVCTL_VBUS ;
DBG ( 1 , " VBUS %d \n " ,
warn > > MUSB_DEVCTL_VBUS_SHIFT ) ;
}
msleep ( 1000 ) ;
maxdelay - - ;
} while ( maxdelay > 0 ) ;
/* in OTG mode, another host might be connected */
if ( devctl & MUSB_DEVCTL_VBUS )
DBG ( 1 , " VBUS off timeout (devctl %02x) \n " , devctl ) ;
}
phy_off ( ) ;
return 0 ;
}