Hi Brad,
patch 1 for the MPC850 host driver.
(m8xxhci_mc.c is the optional microcode patch,
if someone needs it)
Roman
--- mpc850/m8xxhci.c Wed Mar 14 10:24:45 2001
+++ mpc850p1/m8xxhci.c Wed Mar 14 10:27:13 2001
@@ -121,6 +121,12 @@
#include "m8xxhci.h"
#endif
+//#define INCLUDE_USB_UCODE_PATCH
+#ifdef INCLUDE_USB_UCODE_PATCH
+#include "m8xxhci_mc.c"
+#endif
+
+
#define USB_UCODE_PATCH /* SOF via external 1Khz signal */
#define DEBUG_CHECKS
#define CONFIG_RPXLITE_CW
@@ -472,12 +478,12 @@
static volatile int m8xxhci_debug = 0;
static volatile int m8xxhci_verbose = 0;
-void cleanup_drivers(void);
-void m8xxhci_kick_xmit(void);
-void m8xxhci_flush_xmit(void);
-void m8xxhci_flush_recv(void);
-void m8xxhci_stop_controller(void);
-int m8xxhci_start_controller(void);
+static void cleanup_drivers(void);
+static void m8xxhci_kick_xmit(void);
+static void m8xxhci_flush_xmit(void);
+static void m8xxhci_flush_recv(void);
+static void m8xxhci_stop_controller(void);
+static int m8xxhci_start_controller(void);
static void m8xxhci_interrupt(void *);
static int m8xxhci_unlink_urb(urb_t *urb);
@@ -515,7 +521,7 @@
#if 1
/* this is really poor 'asm()' use, but hey, it works... */
//extern long long _get_TBR(void);
-long long _get_TBR(void)
+static long long _get_TBR(void)
{
asm volatile ("1: mftbu %r3");
asm volatile ("mftb %r4");
@@ -565,7 +571,7 @@
spin_unlock_irqrestore(&event_lock, flags);
}
-void
+static void
m8xxhci_dump_events(void)
{
if (0) dump_events();
@@ -2212,7 +2218,7 @@
usbregs->usb_usmod |= USMOD_EN;
}
-void
+static void
m8xxhci_tx_err(int ber)
{
struct m8xxhci_private *hp = (struct m8xxhci_private *)m8xxhci_ptr;
@@ -2408,7 +2414,7 @@
}
#endif
-void
+static void
m8xxhci_dump(void)
{
dump_delay_qe_list();
@@ -2416,6 +2422,7 @@
dump_frame_lists();
}
+#if defined(CONFIG_RPXLITE)
static int dumpthem;
static void
check_switches(void)
@@ -2432,11 +2439,19 @@
dump_events();
}
}
+#endif
#ifndef USB_UCODE_PATCH
static spinlock_t need_sof_lock = SPIN_LOCK_UNLOCKED;
#endif
+#ifdef USB_UCODE_PATCH
+#define USE_TIMER1_FOR_SOF
+// #define USE_BRG3_FOR_SOF
+// #define USE_BRG1_FOR_SOF
+// #define FIX_SMC1_BRG1
+#endif
+
/* called every 1 ms to generate SOF frames */
static void
m8xxhci_timer_interrupt(void *context)
@@ -2447,9 +2462,14 @@
m8xxhci_timer_ticks++;
/* reset the interrupt */
+#if (defined(USE_BRG1_FOR_SOF) || defined(USE_BRG3_FOR_SOF))
immap->im_cpmtimer.cpmt_ter4 = 0xffff;
+#endif
+#ifdef USE_TIMER1_FOR_SOF
+ immap->im_cpmtimer.cpmt_ter1 = 0xffff;
+#endif
-#if 1
+#if defined(CONFIG_RPXLITE)
check_switches();
#endif
@@ -2550,12 +2570,47 @@
//#define MIN_BYTES_LEFT 100
//#define MIN_BYTES_LEFT 300
+#ifdef USE_TIMER1_FOR_SOF
-#ifdef USB_UCODE_PATCH
-//#define USE_BRG3_FOR_SOF
-#define USE_BRG1_FOR_SOF
-#define FIX_SMC1_BRG1
+#define CPMTIMER_TGCR_CAS1 0x0008 /* cascade timer */
+#define CPMTIMER_TGCR_FRZ1 0x0004 /* freeze timer */
+#define CPMTIMER_TGCR_STP1 0x0002 /* stop timer */
+#define CPMTIMER_TGCR_RST1 0x0001 /* restart timer */
+ if (m8xxhci_verbose)
+ printk("m8xxhci: USING TIMER1 FOR SOF!\n");
+
+ /* reset timer1 */
+ immap->im_cpmtimer.cpmt_tgcr &= ~(CPMTIMER_TGCR_CAS1 |
+ CPMTIMER_TGCR_FRZ1 |
+ CPMTIMER_TGCR_STP1);
+
+ immap->im_cpmtimer.cpmt_tmr1 =
+#if 1
+ CPMTIMER_TMR_ORI |
#endif
+ CPMTIMER_TMR_FRR | CPMTIMER_TMR_ICLK_INT16;
+
+ /* (GCLK2[50Mhz] / 16) / 3125 = 1ms */
+ immap->im_cpmtimer.cpmt_trr1 = count;
+ immap->im_cpmtimer.cpmt_tcr1 = 0;
+ immap->im_cpmtimer.cpmt_tcn1 = 0;
+ immap->im_cpmtimer.cpmt_ter1 = 0xffff;
+
+#if 1
+ /* set up interrupt handler */
+ cpm_install_handler(CPMVEC_TIMER1, m8xxhci_timer_interrupt, (void *)0);
+#endif
+
+#define PA_DR6 0x0200
+ immap->im_ioport.iop_padir |= PA_DR6;
+ immap->im_ioport.iop_papar |= PA_DR6;
+// immap->im_ioport.iop_padir &= ~PA_DR6;
+
+ /* and start timer */
+ immap->im_cpmtimer.cpmt_tgcr |= CPMTIMER_TGCR_RST1;
+#endif /* USE_TIMER1_FOR_SOF */
+
+#if (defined(USE_BRG1_FOR_SOF) || defined(USE_BRG3_FOR_SOF))
#define CPMTIMER_TGCR_CAS4 0x8000 /* cascade timer */
#define CPMTIMER_TGCR_FRZ4 0x4000 /* freeze timer */
@@ -2657,6 +2712,7 @@
/* and start timer */
immap->im_cpmtimer.cpmt_tgcr |= CPMTIMER_TGCR_RST4;
+#endif /* (defined(USE_BRG1_FOR_SOF) || defined(USE_BRG3_FOR_SOF)) */
}
static void
@@ -3220,7 +3276,7 @@
hp->rxnext = 0;
}
-void
+static void
m8xxhci_flush_recv(void)
{
struct m8xxhci_private *hp = (struct m8xxhci_private *)m8xxhci_ptr;
@@ -3232,7 +3288,7 @@
reset_rx_ring();
}
-void
+static void
m8xxhci_flush_xmit(void)
{
struct m8xxhci_private *hp = (struct m8xxhci_private *)m8xxhci_ptr;
@@ -3267,7 +3323,7 @@
if (0) printk("m8xxhci_flush_xmit() done\n");
}
-void
+static void
m8xxhci_kick_xmit(void)
{
volatile immap_t *immap = (immap_t *)IMAP_ADDR;
@@ -4076,7 +4132,7 @@
immap->im_ioport.iop_padir &= ~PA_USB_OE;
immap->im_ioport.iop_papar |= PA_USB_OE;
- immap->im_ioport.iop_padat = 0;
+// immap->im_ioport.iop_padat = 0;
unlock_tx_ring(hp);
@@ -4084,7 +4140,7 @@
}
-int
+static int
m8xxhci_setup_usb_clock(void)
{
volatile cpm8xx_t *cp;
@@ -4095,15 +4151,34 @@
/* Get pointer to Communication Processor */
cp = cpmp;
-
-#define USE_PA5_CLK3
+
+#define USE_PA4_CLK4
+//#define USE_PA5_CLK3
//#define USE_PA7_CLK1
//#define USE_BRG3
//#define USE_BRG4
+#ifdef USE_PA4_CLK4
+#define PA_DR4 ((ushort)0x0800)
+ if (m8xxhci_verbose)
+ printk("m8xxhci: USING CLK4 for USB clock!\n");
+
+ /* we assume a 48Mhz system clock connected to CLK4 via PA4 */
+ immap->im_ioport.iop_padir &= ~PA_DR4;
+ immap->im_ioport.iop_papar |= PA_DR4;
+
+ /* control bits in SICR to route CLK4 to USB (R1CS) */
+#define SICR_USB_MASK ((uint)0x000000ff)
+#define SICR_USB_CLKRT ((uint)0x00000038)
+
+ /* configure Serial Interface clock routing */
+ cp->cp_sicr &= ~SICR_USB_MASK;
+ cp->cp_sicr |= SICR_USB_CLKRT;
+#endif
+
#ifdef USE_PA7_CLK1
#define PA_DR7 ((ushort)0x0100)
- printk("m8xxhci: USING CLK1 for SOF timer!\n");
+ printk("m8xxhci: USING CLK1 for USB clock!\n");
/* we assume a 48Mhz system clock connected to CLK1 via PA7 */
immap->im_ioport.iop_padir &= ~PA_DR7;
@@ -4120,7 +4195,7 @@
#ifdef USE_PA5_CLK3
#define PA_DR5 ((ushort)0x0400)
- printk("m8xxhci: USING CLK3 for SOF timer!\n");
+ printk("m8xxhci: USING CLK3 for USB clock!\n");
/* we assume a 48Mhz system clock connected to CLK3 via PA5 */
immap->im_ioport.iop_padir &= ~PA_DR5;
@@ -4137,7 +4212,7 @@
#ifdef USE_BRG3
if (m8xxhci_verbose)
- printk("m8xxhci: USING BRG3 for SOF patch!\n");
+ printk("m8xxhci: USING BRG3 for USB clock!\n");
/* we assume a 48Mhz system clock */
cp->cp_brgc3 = 0x00010000;
@@ -4157,7 +4232,7 @@
#ifdef USE_BRG4
if (m8xxhci_verbose)
- printk("m8xxhci: USING BRG4 for SOF patch!\n");
+ printk("m8xxhci: USING BRG4 for USB clock!\n");
/* we assume a 48Mhz system clock */
printk("cp_brgc4 0x%x before\n", cp->cp_brgc4);
@@ -4176,7 +4251,7 @@
return 0;
}
-int
+static int
m8xxhci_setup_usb_pins(void)
{
volatile immap_t *immap;
@@ -4188,7 +4263,7 @@
immap->im_ioport.iop_padir &= ~(PA_USB_RXD | PA_USB_OE);
immap->im_ioport.iop_papar |= (PA_USB_RXD | PA_USB_OE);
immap->im_ioport.iop_paodr &= ~PA_USB_OE;
- immap->im_ioport.iop_padat = 0;
+// immap->im_ioport.iop_padat = 0;
immap->im_ioport.iop_padat = PA_USB_OE;
/* select USBRXP & USBRXN */
@@ -4222,7 +4297,7 @@
return 0;
}
-int
+static int
m8xxhci_setup_board_specific(void)
{
#ifdef CONFIG_RPXLITE_AW
@@ -4265,7 +4340,7 @@
return 0;
}
-void
+static void
m8xxhci_stop_controller(void)
{
volatile immap_t *immap;
@@ -4283,7 +4358,7 @@
usbregs->usb_usmod = USMOD_HOST | USMOD_TEST;
}
-int
+static int
m8xxhci_start_controller(void)
{
volatile struct m8xxhci_private *hp = m8xxhci_ptr;
@@ -4345,8 +4420,8 @@
break;
}
- if (bad)
- return -1;
+// if (bad)
+// return -1;
}
/* set up USB section of chip */
@@ -4459,6 +4534,12 @@
/* turn on board specific bits */
m8xxhci_setup_board_specific();
+#ifdef INCLUDE_USB_UCODE_PATCH
+#ifdef USB_UCODE_PATCH
+ cpm_load_patch(immap);
+#endif
+#endif
+
/* wait for powerup */
wait_ms(200);
@@ -4730,6 +4811,7 @@
{
int pid;
+#if defined(CONFIG_RPXLITE)
if (m8xxhci_verbose)
printk("m8xxhci: dip switches %x\n",
(*((volatile uint *)RPX_CSR_ADDR) & 0xf0));
@@ -4738,7 +4820,7 @@
printk("m8xxhci_init() disabled via dip switches\n");
return 0;
}
-
+#endif
printk("m8xxhci: initializing controller\n");
if (m8xxhci_setup()) {
/* USB Microcode patches for the CPM as supplied by Motorola.
*/
uint patch_2000[] = {
0x7fff0000,
0x7ffd0000,
0x7ffb0000,
0x49f7ba5b,
0xba383ffb,
0xf9b8b46d,
0xe5ab4e07,
0xaf77bffe,
0x3f7bbf79,
0xba5bba38,
0xe7676076,
0x60750000
};
uint patch_2f00 [] = {
0x3030304c,
0xcab9e441,
0xa1aaf220
};
/* Load the microcode patch.
*/
void cpm_load_patch (volatile immap_t *immr)
{
volatile uint *dp;
volatile cpm8xx_t *commproc;
int i;
commproc = (cpm8xx_t *) &immr->im_cpm;
dp = (uint *) (commproc->cp_dpmem);
for (i = 0; i < (sizeof(patch_2000)/4); i++)
*dp++ = patch_2000[i];
dp = (uint *) &(commproc->cp_dpmem[0x0f00]);
for (i = 0; i < (sizeof(patch_2f00)/4); i++)
*dp++ = patch_2f00[i];
commproc->cp_rccr = 0x0009;
printk ("USB microcode patch installed\n");
}