linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* Re: commproc.c
  2000-03-02 20:20 commproc.c Steve Calfee
@ 2000-03-02 16:22 ` Dan Malek
  2000-03-03 23:22   ` commproc.c Steve Calfee
  2000-03-04 20:10 ` commproc.c Björn Lundberg
  1 sibling, 1 reply; 8+ messages in thread
From: Dan Malek @ 2000-03-02 16:22 UTC (permalink / raw)
  To: Steve Calfee; +Cc: linuxppc-embedded


Steve Calfee wrote:

> I have been working on doing a 823 USB driver.


I find it interesting there is a sudden interest in the 8xx USB
interface.......

I recently hired someone to do this work for a customer.  We have
slave working fine, and host mostly works (some hubs give us fits).
The goal is an isochronous connection for some device to stream
data over a variety of communication links (it's an 850).

We still have a little distance to cover.  If someone needs this
for a product and wants to invest in speeding up the develpment,
let me know.  Once it is more useful I suppose it will find its
way into the source tree.

> m8xx_cpm_dpalloc(uint size)

> This is a primitive routine to allocate CPM memory. It allocates size bytes
> of CPM memory. Even a good citizen that lives by the CPM imposed
> constraints of alignment


I had some pretty bad hacks for ATM interfaces due to its alignment
restrictions, and have since added a second parameter to define alignment.
I have played with masks and byte counts, one will win.  This will
be in an upcoming patch.


> .... We also need a m8xx_cpm_free() function to give back CPM
> memory when we are done.


For lack of a better thought, I have resurrected the old *NIX resource
map allocator.  Seems to work.



> .... I agree that it is a rare use,

It's not only rare, but I don't see any use for it.


> .... but if I want to
> backtrace the interrupted stack from my interrupt routine for profiling...


You have to explain this one to me.  I don't understand how passing
the register set pointer has any effect on this operation.

Show me you need it and we can add it as a parameter.  There aren't
that many places to change the code.  I just didn't need it, and due
to your rant about interrupt overhead why add something not needed?


	-- Dan

** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 8+ messages in thread

* commproc.c
@ 2000-03-02 20:20 Steve Calfee
  2000-03-02 16:22 ` commproc.c Dan Malek
  2000-03-04 20:10 ` commproc.c Björn Lundberg
  0 siblings, 2 replies; 8+ messages in thread
From: Steve Calfee @ 2000-03-02 20:20 UTC (permalink / raw)
  To: linuxppc-embedded


Hi all,

I have been working on doing a 823 USB driver. It is my first driver for
Linux, and generally I am impressed with the ease of adding a driver and
with modules in general. Documentation and examples of how to do simple
programming is weak. The "Linux Device Drivers" book is good, but mostly
obsolete for people working for 2.2.x and beyond kernels. At least with the
kernel source it is possible to figure stuff out, but not easy. We are
using a relatively stable kernel v2.2.5 for the MPC823.

In the interest of improving the 823 implementation, I have some comments
on commproc.c. I tried to download the latest kernel source, but the ftp
sites wont let me in anonymously, so if someone has already addressed these
things in later versions, nevermind.... How do I get the latest kernel sources?


/* Allocate some memory from the dual ported ram.  We may want to
  * enforce alignment restrictions, but right now everyone is a good
  * citizen.
  */
uint
m8xx_cpm_dpalloc(uint size)
{
	uint	retloc;
	if ((dp_alloc_base + size) >= dp_alloc_top)
		return(CPM_DP_NOSPACE);
	retloc = dp_alloc_base;
	dp_alloc_base += size;
	return(retloc);
}

This is a primitive routine to allocate CPM memory. It allocates size bytes
of CPM memory. Even a good citizen that lives by the CPM imposed
constraints of alignment (usually on a 8 byte boundary, but sometimes up to
on a 32 byte boundary), needs help with getting properly aligned memory.
The only way is to get more than you need and then adjust the pointer to be
aligned. It needs to maintain a main memory data structure for memory
allocations. We also need a m8xx_cpm_free() function to give back CPM
memory when we are done. This is especially the case for kernel drivers,
once I insmod and rmmod a few times, I run out of CPM memory and have to
reboot.

/* CPM interrupt controller interrupt.
*/
static	void
cpm_interrupt(int irq, void * dev, struct pt_regs * regs)
{
	uint	vec;
	/* Get the vector by setting the ACK bit and then reading
	 * the register.
	 */
	((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_civr = 1;
	vec = ((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_civr;
	vec >>= 11;
	if (cpm_vecs[vec].handler != 0)
		(*cpm_vecs[vec].handler)(cpm_vecs[vec].dev_id);
	else
		((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr &= ~(1 << vec);
	/* After servicing the interrupt, we have to remove the status
	 * indicator.
	 */
	((immap_t *)IMAP_ADDR)->im_cpic.cpic_cisr |= (1 << vec);

}

Above is the interrupt routine, called by the main PPC interrupt routine.
Note that the caller regs are not passed to the user installed cpm
interrupt routine. I agree that it is a rare use, but if I want to
backtrace the interrupted stack from my interrupt routine for profiling or
finding someone who shuts interrupts of for too long, it is necessary.
Changing the user interrupt routine calls to include the regs will affect
all existing cpm interrupt routines though...






A GOOFY IDEA to make Linux run realtime:

I have done some timings using the hardware timers. It takes a minimum of
about 3000 cpu cycles to get to my interrupt routine, sometimes up to 12000
cycles, and if NFS is running it can be 40000 cycles. This makes it tough
to do some timing critical stuff, like USB frame timing in software. I
realize that Linux is not a real time operating system, but this is the
embedded group, so better real time response should be a legitimate desire.
I looked at RTLinux, but it seems to be a hack, where another realtime OS
is run under Linux which is another task of the realtime system. This seems
kind of overkill, when all you need is real time interrupts and a way to
communicate with the regular Linux tasks.

The one good idea in RTLinux is the idea to redefine CLI(); to not shut off
interrupts, just tell the realtime system that the Linux kernel should not
be reentered. Right now CLI() clears the EA bit on the 823 ppc. What
exactly is an external interrupt? presumably it is all CPM interrupts, but
what about the Decrementer or timebase interrrupt, are they external? The
823 manual, while huge, does not communicate information well.

Anyway, what if we redefined CLI to be saveregs, and then clear all but a
system wide mask of the CPM interrupts in ((immap_t
*)IMAP_ADDR)->im_cpic.cpic_cimr (from above). This would still allow
interrupts that were requested in the mask to occur even though the kernel
has requested all ints off. These realtime interrupts would NOT be allowed
to call system functions or data structures, and could only communicate
with Linux tasks via common memory areas. Restructuring the system
interrupt entry routines to minimize overhead with such things as remapping
virtual memory to physical etc would be required.

This scheme would impose more restrictions on interrupt routine writers,
but it would make realtime interrupts possible.

Steve Calfee	--	embedded systems consultant
calfee@home.com
Kerbango phone: (408) 517-3355
home office ph: (510) 657-6039

** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: commproc.c
  2000-03-02 16:22 ` commproc.c Dan Malek
@ 2000-03-03 23:22   ` Steve Calfee
  0 siblings, 0 replies; 8+ messages in thread
From: Steve Calfee @ 2000-03-03 23:22 UTC (permalink / raw)
  To: Dan Malek; +Cc: linuxppc-embedded


At 11:22 AM 3/2/00 -0500, Dan Malek wrote:
>Steve Calfee wrote:
>
> > I have been working on doing a 823 USB driver.
>
>
>I find it interesting there is a sudden interest in the 8xx USB
>interface.......
>
>I recently hired someone to do this work for a customer.  We have
>slave working fine, and host mostly works (some hubs give us fits).
>The goal is an isochronous connection for some device to stream
>data over a variety of communication links (it's an 850).

Yeah, slave is easy, host is hard. Does 850 have host usb built in or are
you using an external host chipset? I am using the 823 with its built in
support.

 > m8xx_cpm_dpalloc(uint size)

> > This is a primitive routine to allocate CPM memory. It allocates size bytes
> > of CPM memory. Even a good citizen that lives by the CPM imposed
> > constraints of alignment
>
>
>I had some pretty bad hacks for ATM interfaces due to its alignment
>restrictions, and have since added a second parameter to define alignment.
>I have played with masks and byte counts, one will win.  This will
>be in an upcoming patch.
>
>
> > .... We also need a m8xx_cpm_free() function to give back CPM
> > memory when we are done.
>
>
>For lack of a better thought, I have resurrected the old *NIX resource
>map allocator.  Seems to work.
>

Great, that will be useful.


> > .... I agree that it is a rare use,
>
>It's not only rare, but I don't see any use for it.
>
>
> > .... but if I want to
> > backtrace the interrupted stack from my interrupt routine for profiling...
>
>
>You have to explain this one to me.  I don't understand how passing
>the register set pointer has any effect on this operation.
>
>Show me you need it and we can add it as a parameter.  There aren't
>that many places to change the code.  I just didn't need it, and due
>to your rant about interrupt overhead why add something not needed?
>

Sorry, didn't mean to rant, only suggest how to get 90% of the use of
rtLinux with 10% of the effort.

The profiling use was for someone who wanted to sample where his app was
running say every 500 microseconds or every ms or... So you need the
registers to extract the PC where the application was interrupted. Then
over a "long" period of time you can tell where the program is spending its
time. For my use, I hacked in a store of the regs to an external variable
in the commproc.c interrupt routine. Then my timer interrupt routine would
dump the pc where the interrupts were reenabled. Most of the addresses were
in the STI() or restoreregs routines, but it did point to a possible
culprit in the NFS system where ints were off a long time. Ultimately I
gave up, I didn't want to change code I didn't fully understand....

Passing the regs parameter on to CPM interrupt routines shouldn't add much,
if any, overhead, the parameter is already in a register when the
cpm_interrupt routine is called, so just passing it on to vectored
interrupt routines is all that is required.

Regards, Steve

Steve Calfee	--	embedded systems consultant
calfee@home.com
Kerbango phone: (408) 517-3355
home office ph: (510) 657-6039


** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: commproc.c
  2000-03-02 20:20 commproc.c Steve Calfee
  2000-03-02 16:22 ` commproc.c Dan Malek
@ 2000-03-04 20:10 ` Björn Lundberg
  2000-03-05 15:58   ` commproc.c Brad Hards
  1 sibling, 1 reply; 8+ messages in thread
From: Björn Lundberg @ 2000-03-04 20:10 UTC (permalink / raw)
  To: linuxppc-embedded

[-- Attachment #1: Type: text/plain, Size: 583 bytes --]

Steve Calfee wrote:
>
> Hi all,
>
> I have been working on doing a 823 USB driver. It is my first driver for
snip

We've got an USB host driver in alpha stage for the 850 (done with the
823 manual since 850 lacked documentation).
I'll try to clean it up and submit it to the list in a few days.

Changes we've done to commproc.c and .h against 2.2.5 are attached.
These concern _dpalloc alignment and increased size (microcode alert)
plus RISC-timer IRQ (used to generate SOF in the USB driver).

As stated earlier we haven't moved to 2.2.13 due to performance issues.

Cheers
 Bjorn

[-- Attachment #2: commproc.c.diff --]
[-- Type: text/plain, Size: 5521 bytes --]

--- linux-org/linux-2.2.5-embedded/arch/ppc/8xx_io/commproc.c	Fri Apr  9 06:46:08 1999
+++ linux-york/arch/ppc/8xx_io/commproc.c	Thu Feb 10 13:25:35 2000
@@ -3,6 +3,7 @@
  * General Purpose functions for the global management of the
  * Communication Processor Module.
  * Copyright (c) 1997 Dan Malek (dmalek@jlc.net)
+ * Copyright (c) 1999 Honeywell INUcontrol (bjorn.lundberg@inu.se)
  *
  * In addition to the individual control of the communication
  * channels, there are a few functions that globally affect the
@@ -20,6 +21,9 @@
  * memory that can never be used for microcode.  If there are
  * applications that require more DP ram, we can expand the boundaries
  * but then we have to be careful of any downloaded microcode.
+ *
+ * Added support for RISC-timer IRQ and more DP ram (microcode alert).
+ * bjorn.lundberg@inu.se
  */
 #include <linux/config.h>
 #include <linux/errno.h>
@@ -49,6 +53,7 @@
 	void	*dev_id;
 };
 static	struct	cpm_action cpm_vecs[CPMVEC_NR];
+static	struct	cpm_action cpm_risctimer_vecs[16];
 static	void	cpm_interrupt(int irq, void * dev, struct pt_regs * regs);
 static	void	cpm_error_interrupt(void *);

@@ -104,12 +109,16 @@
 	cpmp = (cpm8xx_t *)commproc;
 }

+static	void cpm_risctimer_interrupt(void *dev);
+
 /* This is called during init_IRQ.  We used to do it above, but this
  * was too early since init_IRQ was not yet called.
  */
 void
-cpm_interrupt_init()
+cpm_interrupt_init(void)
 {
+	cprtt_t *rtt_pramp = (cprtt_t *)(&cpmp->cp_dparam[PROFF_RISCTT]);
+
 	/* Initialize the CPM interrupt controller.
 	*/
 	((immap_t *)IMAP_ADDR)->im_cpic.cpic_cicr =
@@ -122,6 +131,19 @@
 	if (request_8xxirq(CPM_INTERRUPT, cpm_interrupt, 0, "cpm", NULL) != 0)
 		panic("Could not allocate CPM IRQ!");

+	/* Install our own timer handler.
+	*/
+	((volatile immap_t *)IMAP_ADDR)->im_cpm.cp_rccr &= 0x00ff;	/* stop, clear TIMEP */
+	cpm_install_handler(CPMVEC_RISCTIMER, cpm_risctimer_interrupt, NULL);
+	rtt_pramp->tm_base = m8xx_cpm_dpalloc(4*16);
+
+	/* want timer period = 0.1ms -> timep = 4800/1024 = 4.69
+	 * timep = 4 -> 4096 = 0.08533 ms -> 11719Hz
+	 */
+#define RISCTIMER_FREQ	11719
+	((volatile immap_t *)IMAP_ADDR)->im_cpm.cp_rccr |= (4 << 8);
+	((volatile immap_t *)IMAP_ADDR)->im_cpm.cp_rccr |= (0x8000);	/* enable */
+
 	/* Install our own error handler.
 	*/
 	cpm_install_handler(CPMVEC_ERROR, cpm_error_interrupt, NULL);
@@ -144,8 +166,10 @@

 	if (cpm_vecs[vec].handler != 0)
 		(*cpm_vecs[vec].handler)(cpm_vecs[vec].dev_id);
-	else
+	else {
+		printk("CPM : No handler for irq %x.\n", vec);
 		((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr &= ~(1 << vec);
+	}

 	/* After servicing the interrupt, we have to remove the status
 	 * indicator.
@@ -164,6 +188,35 @@
 {
 }

+/* The CPM RISC timer interrupt handler.
+ */
+static	void
+cpm_risctimer_interrupt(void *dev)
+{
+	uint	i, rter;
+
+	/* first save then clear eventregister
+	 */
+	rter = ((volatile immap_t *)IMAP_ADDR)->im_cpm.cp_rter;
+	((volatile immap_t *)IMAP_ADDR)->im_cpm.cp_rter = 0xffff;
+
+/*  	printk("CPM : RISC-irq rtmr = %x  rter = %x.\n", ((immap_t *)IMAP_ADDR)->im_cpm.cp_rtmr, rter); */
+	for (i=0; i<16; i++) {
+		if (rter & 0x0001) {
+/*    			printk("CPM : cpm_risctimer_vecs[%d].handler=%x.\n", i, cpm_risctimer_vecs[i].handler); */
+			if (cpm_risctimer_vecs[i].handler != 0) {
+				/*  printk("CPM : calling %x.\n", cpm_risctimer_vecs[i].handler); */
+				(*cpm_risctimer_vecs[i].handler)(cpm_risctimer_vecs[i].dev_id);
+				/*  printk("CPM : called %x.\n", cpm_risctimer_vecs[i].handler); */
+			} else {
+				printk("CPM : No handler for RISC timer %x.\n", i);
+				((immap_t *)IMAP_ADDR)->im_cpm.cp_rtmr &= ~(1 << i);
+			}
+		}
+		rter >>= 1;
+	}
+}
+
 /* Install a CPM interrupt handler.
 */
 void
@@ -177,17 +230,46 @@
 	((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr |= (1 << vec);
 }

-/* Allocate some memory from the dual ported ram.  We may want to
- * enforce alignment restrictions, but right now everyone is a good
- * citizen.
+/* Install a CPM RISC timer interrupt handler.
+*/
+void
+cpm_install_risctimer_handler(int timer, int n_ms, void (*handler)(void *), void *dev_id)
+{
+	volatile cpm8xx_t *cp = cpmp;	/* Get pointer to Communication Processor */
+	volatile cprtt_t  *rtt_pramp = (cprtt_t *)(&cpmp->cp_dparam[PROFF_RISCTT]);
+
+	if (cpm_risctimer_vecs[timer].handler != 0)
+		printk("CPM RISC timer interrupt %x replacing %x\n",
+			(uint)handler, (uint)cpm_risctimer_vecs[timer].handler);
+	printk("CPM RISC timer interrupt %x\n", (uint)handler);
+	cpm_risctimer_vecs[timer].handler = handler;
+	cpm_risctimer_vecs[timer].dev_id = dev_id;
+	rtt_pramp->tm_cmd = (0xC0000000 | (timer<<16) | n_ms*RISCTIMER_FREQ/1000);
+	while (cp->cp_cpcr & CPM_CR_FLG);
+	cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SPI, CPM_CR_SET_TIMER) | CPM_CR_FLG;
+	while (cp->cp_cpcr & CPM_CR_FLG);
+	((immap_t *)IMAP_ADDR)->im_cpm.cp_rtmr |= (1 << timer);
+}
+
+/* Allocate some memory from the dual ported ram.
+ * We enforce 32 byte alignment restrictions.
  */
 uint
-m8xx_cpm_dpalloc(uint size)
+m8xx_cpm_dpalloc(uint size_non_align)
 {
 	uint	retloc;
+	uint	size = (((size_non_align - 1) / 32) + 1) * 32;

-	if ((dp_alloc_base + size) >= dp_alloc_top)
+	if ((dp_alloc_base + size) >= dp_alloc_top) {
+		if(dp_alloc_base == CPM_DATAONLY_BASE &&
+		   size < CPM_DATA2_SIZE) {
+			printk("Switching to DPRAM DATA2\n");
+			dp_alloc_base = CPM_DATA2_BASE;
+			dp_alloc_top = dp_alloc_base + CPM_DATA2_SIZE;
+		}
+		else
 		return(CPM_DP_NOSPACE);
+	}

 	retloc = dp_alloc_base;
 	dp_alloc_base += size;

[-- Attachment #3: commproc.h.diff --]
[-- Type: text/plain, Size: 6474 bytes --]

--- linux-org/linux-2.2.5-embedded/arch/ppc/8xx_io/commproc.h	Thu Apr 15 17:47:36 1999
+++ linux-york/arch/ppc/8xx_io/commproc.h	Tue Feb 22 09:01:05 2000
@@ -14,6 +14,9 @@
  * bytes of the DP RAM and relocates the I2C parameter area to the
  * IDMA1 space.  The remaining DP RAM is available for buffer descriptors
  * or other use.
+ *
+ * Added some I2C info and cleaned out IIC (both I2C and IIC were used)
+ *	--Bjorn (bjorn.lundberg@inu.se)
  */
 #ifndef __CPM_8XX__
 #define __CPM_8XX__
@@ -36,10 +39,12 @@
 #define CPM_CR_STOP_TX		((ushort)0x0004)
 #define CPM_CR_RESTART_TX	((ushort)0x0006)
 #define CPM_CR_SET_GADDR	((ushort)0x0008)
+#define CPM_CR_SET_TIMER	((ushort)0x0008)

 /* Channel numbers.
 */
 #define CPM_CR_CH_SCC1	((ushort)0x0000)
+#define CPM_CR_CH_USB	((ushort)0x0000)
 #define CPM_CR_CH_I2C	((ushort)0x0001)	/* I2C and IDMA1 */
 #define CPM_CR_CH_SCC2	((ushort)0x0004)
 #define CPM_CR_CH_SPI	((ushort)0x0005)	/* SPI / IDMA2 / Timers */
@@ -57,6 +62,8 @@
  */
 #define CPM_DATAONLY_BASE	((uint)0x0800)
 #define CPM_DATAONLY_SIZE	((uint)0x0700)
+#define CPM_DATA2_BASE		((uint)0x1000)
+#define CPM_DATA2_SIZE		((uint)0x0A00)
 #define CPM_DP_NOSPACE		((uint)0x7fffffff)

 /* Export the base address of the communication processor registers
@@ -92,8 +99,9 @@
 /* Parameter RAM offsets.
 */
 #define PROFF_SCC1	((uint)0x0000)
-#define PROFF_IIC	((uint)0x0080)
+#define PROFF_I2C	((uint)0x0080)
 #define PROFF_SCC2	((uint)0x0100)
+#define PROFF_RISCTT	((uint)0x01B0)
 #define PROFF_SCC3	((uint)0x0200)
 #define PROFF_SMC1	((uint)0x0280)
 #define PROFF_SCC4	((uint)0x0300)
@@ -398,6 +406,33 @@
 #define SICR_ENET_CLKRT	((uint)0x0000003d)
 #endif

+#ifdef CONFIG_YORK
+/* This ENET stuff is for the MPC850 with ethernet on SCC2.  Some of
+ * this may be unique to the YORK.
+ */
+#define PA_ENET_RXD	((ushort)0x0004) /* RXD2 */
+#define PA_ENET_TXD	((ushort)0x0008) /* TXD2 */
+#define PA_ENET_TCLK	((ushort)0x0200) /* CLK2 */
+#define PA_ENET_RCLK	((ushort)0x0800) /* CLK4 */
+#define PB_ENET_TENA	((uint)0x00002000) /* RTS2 */
+#define PC_ENET_CLSN	((ushort)0x0080) /* CD2 */
+#define PC_ENET_RENA	((ushort)0x0040) /* CTS2 */
+
+#define PB_YORK_LBK     ((uint)0x00000008)
+#define PB_YORK_DSQE    ((uint)0x00000004)
+#define PB_YORK_FDE     ((uint)0x00000002)
+
+#define SICR_ENET_MASK	((uint)0x00007f00)
+#define SICR_ENET_CLKRT	((uint)0x00003d00)
+
+#define SICR_USB_MASK	((uint)0x00000038)
+#define SICR_USB_CLKRT	((uint)0x00000008) /* BRG2 */
+
+#define PB_I2C_SDA	((uint)0x00000010)
+#define PB_I2C_SCL	((uint)0x00000020)
+
+#endif
+
 #ifdef CONFIG_RPXLITE
 /* This ENET stuff is for the MPC850 with ethernet on SCC2.  Some of
  * this may be unique to the RPX-Lite configuration.
@@ -585,27 +620,86 @@

 #define BD_SCC_TX_LAST		((ushort)0x0800)

-/* IIC parameter RAM.
-*/
-typedef struct iic {
-	ushort	iic_rbase;	/* Rx Buffer descriptor base address */
-	ushort	iic_tbase;	/* Tx Buffer descriptor base address */
-	u_char	iic_rfcr;	/* Rx function code */
-	u_char	iic_tfcr;	/* Tx function code */
-	ushort	iic_mrblr;	/* Max receive buffer length */
-	uint	iic_rstate;	/* Internal */
-	uint	iic_rdp;	/* Internal */
-	ushort	iic_rbptr;	/* Internal */
-	ushort	iic_rbc;	/* Internal */
-	uint	iic_rxtmp;	/* Internal */
-	uint	iic_tstate;	/* Internal */
-	uint	iic_tdp;	/* Internal */
-	ushort	iic_tbptr;	/* Internal */
-	ushort	iic_tbc;	/* Internal */
-	uint	iic_txtmp;	/* Internal */
-} iic_t;

-#define BD_IIC_START		((ushort)0x0400)
+/*
+ * I2C parameter RAM.
+ * Both IIC and I2C are used, let's stick with I2C -- Bjorn
+ */
+typedef struct i2c_pram {
+	ushort	i2c_rbase;		/* RX BD base address */
+	ushort	i2c_tbase;		/* TX BD base address */
+	u_char	i2c_rfcr;		/* Rx function code */
+	u_char	i2c_tfcr;		/* Tx function code */
+	ushort	i2c_mrblr;		/* Rx buffer length */
+	uint	i2c_rstate;		/* Rx internal state */
+	uint	i2c_rptr;		/* Rx internal data pointer */
+	ushort	i2c_rbptr;		/* rb BD Pointer */
+	ushort	i2c_rcount;		/* Rx internal byte count */
+	uint	i2c_rtemp;		/* Rx temp */
+	uint	i2c_tstate;		/* Tx internal state */
+	uint	i2c_tptr;		/* Tx internal data pointer */
+	ushort	i2c_tbptr;		/* Tx BD pointer */
+	ushort	i2c_tcount;		/* Tx byte count */
+	uint	i2c_ttemp;		/* Tx temp */
+} i2cp_t;
+
+#define BD_I2C_START		((ushort)0x0400)
+
+/* Buffer descriptor control/status used by I2C receive.
+ */
+#define BD_I2C_RX_EMPTY		((ushort)0x8000)
+#define BD_I2C_RX_WRAP		((ushort)0x2000)
+#define BD_I2C_RX_INTR		((ushort)0x1000)
+#define BD_I2C_RX_LAST		((ushort)0x0800)
+#define BD_I2C_RX_OV		((ushort)0x0002)
+#define BD_I2C_RX_STATS		((ushort)0x0002)	/* All status bits */
+
+/* Buffer descriptor control/status used by I2C transmit.
+ */
+#define BD_I2C_TX_READY		((ushort)0x8000)
+#define BD_I2C_TX_PAD		((ushort)0x4000)
+#define BD_I2C_TX_WRAP		((ushort)0x2000)
+#define BD_I2C_TX_INTR		((ushort)0x1000)
+#define BD_I2C_TX_LAST		((ushort)0x0800)
+#define BD_I2C_TX_START		((ushort)0x0400)
+#define BD_I2C_TX_NAK		((ushort)0x0004)
+#define BD_I2C_TX_UN		((ushort)0x0002)
+#define BD_I2C_TX_CL		((ushort)0x0001)
+#define BD_I2C_TX_STATS		((ushort)0x0007)	/* All status bits */
+
+/* I2C Event and Mask register.
+ */
+#define	I2CM_TXE	((unsigned char)0x10)
+#define	I2CM_BSY	((unsigned char)0x04)
+#define	I2CM_TXB	((unsigned char)0x02)
+#define	I2CM_RXB	((unsigned char)0x01)
+
+/* I2C Mode register
+ */
+#define	I2MOD_EN	((unsigned char)0x01)
+
+/* I2C byte ordering
+ */
+#define I2C_xFCR_BO_PPC		((ushort)0x0010)
+#define I2C_xFCR_BO_OTHER	((ushort)0x0020)
+
+/* I2C Command register
+ */
+#define	I2COM_START	((unsigned char)0x80)
+#define I2COM_MASTER	((unsigned char)0x01)
+
+/*
+ * Communication Processor
+ * RISC Timer Table Parameter RAM
+ */
+typedef struct cprtt_pram {
+	__u16	tm_base;		/* RISC timer table base address */
+	__u16	tm_ptr;			/* RISC timer table pointer */
+	__u16	r_tmr;			/* RISC timer mode register */
+	__u16	r_tmv;			/* RISC timer valid register */
+	__u32	tm_cmd;			/* RISC timer command register */
+	__u32	tm_cnt;			/* RISC timer internal count */
+} cprtt_t;

 /* CPM interrupts.  There are nearly 32 interrupts generated by CPM
  * channels or devices.  All of these are presented to the PPC core
@@ -646,6 +740,7 @@
 #define	CPMVEC_ERROR		((ushort)0x00)

 extern void cpm_install_handler(int vec, void (*handler)(void *), void *dev_id);
+extern void cpm_install_risctimer_handler(int timer, int n_ms, void (*handler)(void *), void *dev_id);

 /* CPM interrupt configuration vector.
 */

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: commproc.c
  2000-03-04 20:10 ` commproc.c Björn Lundberg
@ 2000-03-05 15:58   ` Brad Hards
  2000-03-06 10:37     ` commproc.c Björn Lundberg
  2000-03-06 16:22     ` commproc.c Brad Parker
  0 siblings, 2 replies; 8+ messages in thread
From: Brad Hards @ 2000-03-05 15:58 UTC (permalink / raw)
  To: Björn Lundberg, linuxppc-embedded


Björn Lundberg wrote:
>
> Steve Calfee wrote:
> >
> > Hi all,
> >
> > I have been working on doing a 823 USB driver. It is my first driver for
> snip
>
> We've got an USB host driver in alpha stage for the 850 (done with the
> 823 manual since 850 lacked documentation).
The 850 Users Manual contains info (including how to program) on the USB
host as part of CPM doco - it is chapter 32, and has been recently
updated:
http://www.mot.com/SPS/RISC/netcomm/aesop/mpc8XX/850/32_USB.pdf

The whole users manual is linked off:
http://www.mot.com/SPS/RISC/netcomm/docs/pubs/850UM.html


Brad

** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: commproc.c
  2000-03-05 15:58   ` commproc.c Brad Hards
@ 2000-03-06 10:37     ` Björn Lundberg
  2000-03-06 16:22     ` commproc.c Brad Parker
  1 sibling, 0 replies; 8+ messages in thread
From: Björn Lundberg @ 2000-03-06 10:37 UTC (permalink / raw)
  To: Brad Hards; +Cc: linuxppc-embedded


Brad Hards wrote:
>
> Björn Lundberg wrote:
> >
> > Steve Calfee wrote:
> > >
> > > Hi all,
> > >
> > > I have been working on doing a 823 USB driver. It is my first driver for
> > snip
> >
> > We've got an USB host driver in alpha stage for the 850 (done with the
> > 823 manual since 850 lacked documentation).
> The 850 Users Manual contains info (including how to program) on the USB
> host as part of CPM doco - it is chapter 32, and has been recently
> updated:
> http://www.mot.com/SPS/RISC/netcomm/aesop/mpc8XX/850/32_USB.pdf
>
> The whole users manual is linked off:
> http://www.mot.com/SPS/RISC/netcomm/docs/pubs/850UM.html
>
> Brad
>

I'm sorry I was unclear. What I ment was: Only USB function mode was
documented in 850 manuals when we started doing the host mode. This was
however freshly published for the 823.

The USB parts are the same as far as I've discovered, reading most
everything coming out from Motorola on both 850 and 823.

The bottomline is: If there is something that differs, it should be easy
to adjust.

Cheers
  Bjorn

** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: commproc.c
  2000-03-05 15:58   ` commproc.c Brad Hards
  2000-03-06 10:37     ` commproc.c Björn Lundberg
@ 2000-03-06 16:22     ` Brad Parker
  2000-03-06 19:45       ` commproc.c Steve Calfee
  1 sibling, 1 reply; 8+ messages in thread
From: Brad Parker @ 2000-03-06 16:22 UTC (permalink / raw)
  To: Brad Hards; +Cc: Björn Lundberg, linuxppc-embedded



Brad Hards wrote:
...
>The 850 Users Manual contains info (including how to program) on the USB
>host as part of CPM doco - it is chapter 32, and has been recently
>updated:
>http://www.mot.com/SPS/RISC/netcomm/aesop/mpc8XX/850/32_USB.pdf
>
>The whole users manual is linked off:
>http://www.mot.com/SPS/RISC/netcomm/docs/pubs/850UM.html

I beg to differ - the docs don't really cover host mode at all and
don't explain a number of things you might need to know to make it
work.  I've sent feedback to MOT about this already.  The docs are
really minimal and not very helpful for host mode.  They are just
barely enough for function mode.

-brad


** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: commproc.c
  2000-03-06 16:22     ` commproc.c Brad Parker
@ 2000-03-06 19:45       ` Steve Calfee
  0 siblings, 0 replies; 8+ messages in thread
From: Steve Calfee @ 2000-03-06 19:45 UTC (permalink / raw)
  To: Brad Parker, Brad Hards; +Cc: Björn Lundberg, linuxppc-embedded


At 11:22 AM 3/6/00 -0500, Brad Parker wrote:


>Brad Hards wrote:
>...
> >The 850 Users Manual contains info (including how to program) on the USB
> >host as part of CPM doco - it is chapter 32, and has been recently
> >updated:
> >http://www.mot.com/SPS/RISC/netcomm/aesop/mpc8XX/850/32_USB.pdf
> >
> >The whole users manual is linked off:
> >http://www.mot.com/SPS/RISC/netcomm/docs/pubs/850UM.html
>
>I beg to differ - the docs don't really cover host mode at all and
>don't explain a number of things you might need to know to make it
>work.  I've sent feedback to MOT about this already.  The docs are
>really minimal and not very helpful for host mode.  They are just
>barely enough for function mode.
>
>-brad
I eagerly read these docs, but they just repeat the info in the PPC 823
manual.

The whole USB host architecture is bizarre, it looks like it was crafted by
someone who understood uarts and serial I/O very well, but USB only
marginally. For example, the idea of having separate areas for receive and
transmit BDs, for a host controlled half-duplex communication line adds
complexity and makes no sense. At least you can get around it in software.
Also, the idea that a NAK or STAL is an error that should stop transmission
of a BD list is a major roadblock to getting any bandwidth out of the USB
Bus. Right now I am trying to figure out why I don't get a TX interrupt
after sending a IN PID with the I bit set in the BD.....

Software timers for SOF can get to USB spec +- .5 microseconds 99.9% of the
time (NFS shuts off interrupts for long periods of time occasionally). The
SOF timing will probably be good enough for most devices. Philips audio
Isochronous devices require +- 1 USB bit times (=1/12,000,000=.083
microseconds), too tight for Linux timer interrupts.

Enough complaining, I am convinced that a reasonably functional USB host
stack is possible.

Steve

Steve Calfee	--	embedded systems consultant
calfee@home.com
Kerbango phone: (408) 517-3355
home office ph: (510) 657-6039


** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2000-03-06 19:45 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2000-03-02 20:20 commproc.c Steve Calfee
2000-03-02 16:22 ` commproc.c Dan Malek
2000-03-03 23:22   ` commproc.c Steve Calfee
2000-03-04 20:10 ` commproc.c Björn Lundberg
2000-03-05 15:58   ` commproc.c Brad Hards
2000-03-06 10:37     ` commproc.c Björn Lundberg
2000-03-06 16:22     ` commproc.c Brad Parker
2000-03-06 19:45       ` commproc.c Steve Calfee

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).