[U-Boot-Users] [PATCH] QE IO: Add initial data to pin configuration + read/write functions

Description: On the MPC83xx & MPC85xx architectures that have QE, add initial data to the pin configuration table (qe_iop_conf_tab). Note that this is not mandatory - boards that don't add this field can remain unchanged (as it's the last one). In addition, add IO pin read & write functions.
Signed-off-by: David Saada david.saada@ecitele.com
diff -purN include/ioports.h.orig include/ioports.h
--- include/ioports.h.orig 2008-01-02 13:39:04.000000000 +0200 +++ include/ioports.h 2008-01-06 10:20:40.342453000 +0200 @@ -60,6 +60,7 @@ typedef struct { int dir; int open_drain; int assign; + int data; } qe_iop_conf_t;
#define QE_IOP_TAB_END (-1)
diff -purN cpu/mpc85xx/cpu_init.c.orig cpu/mpc85xx/cpu_init.c
--- cpu/mpc85xx/cpu_init.c.orig 2008-01-02 13:39:04.000000000 +0200 +++ cpu/mpc85xx/cpu_init.c 2008-01-06 10:27:18.963593000 +0200 @@ -37,14 +37,14 @@ DECLARE_GLOBAL_DATA_PTR; #ifdef CONFIG_QE extern qe_iop_conf_t qe_iop_conf_tab[]; extern void qe_config_iopin(u8 port, u8 pin, int dir, - int open_drain, int assign); + int open_drain, int assign, int data); extern void qe_init(uint qe_base); extern void qe_reset(void);
static void config_qe_ioports(void) { u8 port, pin; - int dir, open_drain, assign; + int dir, open_drain, assign, data; int i;
for (i = 0; qe_iop_conf_tab[i].assign != QE_IOP_TAB_END; i++) { @@ -53,7 +53,8 @@ static void config_qe_ioports(void) dir = qe_iop_conf_tab[i].dir; open_drain = qe_iop_conf_tab[i].open_drain; assign = qe_iop_conf_tab[i].assign; - qe_config_iopin(port, pin, dir, open_drain, assign); + data = qe_iop_conf_tab[i].data; + qe_config_iopin(port, pin, dir, open_drain, assign, data); } } #endif
diff -purN cpu/mpc85xx/qe_io.c.orig cpu/mpc85xx/qe_io.c
--- cpu/mpc85xx/qe_io.c.orig 2008-01-02 13:39:04.000000000 +0200 +++ cpu/mpc85xx/qe_io.c 2008-01-06 10:54:24.201604000 +0200 @@ -27,7 +27,7 @@
#if defined(CONFIG_QE) #define NUM_OF_PINS 32 -void qe_config_iopin(u8 port, u8 pin, int dir, int open_drain, int assign) +void qe_config_iopin(u8 port, u8 pin, int dir, int open_drain, int assign, int data) { u32 pin_2bit_mask; u32 pin_2bit_dir; @@ -38,6 +38,16 @@ void qe_config_iopin(u8 port, u8 pin, in volatile par_io_t *par_io = (volatile par_io_t *) &(gur->qe_par_io);
+ /* Calculate pin location for 1bit mask */ + pin_1bit_mask = (u32)(1 << (NUM_OF_PINS - (pin+1))); + + /* Setup the data */ + tmp_val = in_be32(&par_io[port].cpdat); + if (data) + out_be32(&par_io[port].cpdat, pin_1bit_mask | tmp_val); + else + out_be32(&par_io[port].cpdat, ~pin_1bit_mask & tmp_val); + /* Caculate pin location and 2bit mask and dir */ pin_2bit_mask = (u32)(0x3 << (NUM_OF_PINS-(pin%(NUM_OF_PINS/2)+1)*2)); pin_2bit_dir = (u32)(dir << (NUM_OF_PINS-(pin%(NUM_OF_PINS/2)+1)*2)); @@ -55,9 +65,6 @@ void qe_config_iopin(u8 port, u8 pin, in out_be32(&par_io[port].cpdir1, pin_2bit_dir | tmp_val); }
- /* Calculate pin location for 1bit mask */ - pin_1bit_mask = (u32)(1 << (NUM_OF_PINS - (pin+1))); - /* Setup the open drain */ tmp_val = in_be32(&par_io[port].cpodr); if (open_drain) @@ -82,4 +89,39 @@ void qe_config_iopin(u8 port, u8 pin, in } }
+void qe_read_iopin(u8 port, u8 pin, int *data) +{ + u32 pin_1bit_mask; + u32 tmp_val; + volatile ccsr_gur_t *gur = (void *)(CFG_MPC85xx_GUTS_ADDR); + volatile par_io_t *par_io = (volatile par_io_t *) + &(gur->qe_par_io); + + /* Calculate pin location for 1bit mask */ + pin_1bit_mask = (u32)(1 << (NUM_OF_PINS - (pin+1))); + + /* Read the data */ + tmp_val = in_be32(&par_io[port].cpdat); + *data = (tmp_val >> (NUM_OF_PINS - (pin+1))) & 0x1; +} + +void qe_write_iopin(u8 port, u8 pin, int data) +{ + u32 pin_1bit_mask; + u32 tmp_val; + volatile ccsr_gur_t *gur = (void *)(CFG_MPC85xx_GUTS_ADDR); + volatile par_io_t *par_io = (volatile par_io_t *) + &(gur->qe_par_io); + + /* Calculate pin location for 1bit mask */ + pin_1bit_mask = (u32)(1 << (NUM_OF_PINS - (pin+1))); + + /* Write the data */ + tmp_val = in_be32(&par_io[port].cpdat); + if (data) + out_be32(&par_io[port].cpdat, pin_1bit_mask | tmp_val); + else + out_be32(&par_io[port].cpdat, ~pin_1bit_mask & tmp_val); +} + #endif /* CONFIG_QE */
diff -purN cpu/mpc83xx/cpu_init.c.orig cpu/mpc83xx/cpu_init.c
--- cpu/mpc83xx/cpu_init.c.orig 2008-01-02 13:39:04.000000000 +0200 +++ cpu/mpc83xx/cpu_init.c 2008-01-06 10:59:54.006108000 +0200 @@ -29,14 +29,14 @@ DECLARE_GLOBAL_DATA_PTR; #ifdef CONFIG_QE extern qe_iop_conf_t qe_iop_conf_tab[]; extern void qe_config_iopin(u8 port, u8 pin, int dir, - int open_drain, int assign); + int open_drain, int assign, int data); extern void qe_init(uint qe_base); extern void qe_reset(void);
static void config_qe_ioports(void) { u8 port, pin; - int dir, open_drain, assign; + int dir, open_drain, assign, data; int i;
for (i = 0; qe_iop_conf_tab[i].assign != QE_IOP_TAB_END; i++) { @@ -45,7 +45,8 @@ static void config_qe_ioports(void) dir = qe_iop_conf_tab[i].dir; open_drain = qe_iop_conf_tab[i].open_drain; assign = qe_iop_conf_tab[i].assign; - qe_config_iopin(port, pin, dir, open_drain, assign); + data = qe_iop_conf_tab[i].data; + qe_config_iopin(port, pin, dir, open_drain, assign, data); } } #endif
diff -purN cpu/mpc83xx/qe_io.c.orig cpu/mpc83xx/qe_io.c
--- cpu/mpc83xx/qe_io.c.orig 2008-01-02 13:39:04.000000000 +0200 +++ cpu/mpc83xx/qe_io.c 2008-01-06 10:59:54.410427000 +0200 @@ -27,7 +27,7 @@
#if defined(CONFIG_QE) #define NUM_OF_PINS 32 -void qe_config_iopin(u8 port, u8 pin, int dir, int open_drain, int assign) +void qe_config_iopin(u8 port, u8 pin, int dir, int open_drain, int assign, int data) { u32 pin_2bit_mask; u32 pin_2bit_dir; @@ -37,6 +37,17 @@ void qe_config_iopin(u8 port, u8 pin, in volatile immap_t *im = (volatile immap_t *)CFG_IMMR; volatile qepio83xx_t *par_io = (volatile qepio83xx_t *)&im->qepio;
+ /* Calculate pin location for 1bit mask */ + pin_1bit_mask = (u32)(1 << (NUM_OF_PINS - (pin+1))); + + /* Setup the data */ + tmp_val = in_be32(&par_io->ioport[port].pdat); + if (data) { + out_be32(&par_io->ioport[port].pdat, pin_1bit_mask | tmp_val); + } else { + out_be32(&par_io->ioport[port].pdat, ~pin_1bit_mask & tmp_val); + } + /* Caculate pin location and 2bit mask and dir */ pin_2bit_mask = (u32)(0x3 << (NUM_OF_PINS-(pin%(NUM_OF_PINS/2)+1)*2)); pin_2bit_dir = (u32)(dir << (NUM_OF_PINS-(pin%(NUM_OF_PINS/2)+1)*2)); @@ -54,9 +65,6 @@ void qe_config_iopin(u8 port, u8 pin, in out_be32(&par_io->ioport[port].dir1, pin_2bit_dir | tmp_val); }
- /* Calculate pin location for 1bit mask */ - pin_1bit_mask = (u32)(1 << (NUM_OF_PINS - (pin+1))); - /* Setup the open drain */ tmp_val = in_be32(&par_io->ioport[port].podr); if (open_drain) { @@ -82,4 +90,38 @@ void qe_config_iopin(u8 port, u8 pin, in } }
+void qe_read_iopin(u8 port, u8 pin, int *data) +{ + u32 pin_1bit_mask; + u32 tmp_val; + volatile immap_t *im = (volatile immap_t *)CFG_IMMR; + volatile qepio83xx_t *par_io = (volatile qepio83xx_t *)&im->qepio; + + /* Calculate pin location for 1bit mask */ + pin_1bit_mask = (u32)(1 << (NUM_OF_PINS - (pin+1))); + + /* Read the data */ + tmp_val = in_be32(&par_io->ioport[port].pdat); + *data = (tmp_val >> (NUM_OF_PINS - (pin+1))) & 0x1; +} + +void qe_write_iopin(u8 port, u8 pin, int data) +{ + u32 pin_1bit_mask; + u32 tmp_val; + volatile immap_t *im = (volatile immap_t *)CFG_IMMR; + volatile qepio83xx_t *par_io = (volatile qepio83xx_t *)&im->qepio; + + /* Calculate pin location for 1bit mask */ + pin_1bit_mask = (u32)(1 << (NUM_OF_PINS - (pin+1))); + + /* Setup the data */ + tmp_val = in_be32(&par_io->ioport[port].pdat); + if (data) { + out_be32(&par_io->ioport[port].pdat, pin_1bit_mask | tmp_val); + } else { + out_be32(&par_io->ioport[port].pdat, ~pin_1bit_mask & tmp_val); + } +} + #endif /* CONFIG_QE */

On 1/6/08, David Saada David.Saada@ecitele.com wrote:
Description: On the MPC83xx & MPC85xx architectures that have QE, add initial data to the pin configuration table (qe_iop_conf_tab). Note that this is not mandatory - boards that don't add this field can remain unchanged (as it's the last one). In addition, add IO pin read & write functions.
I'm not fundamentally against this patch in principle, but I'm concerned about your statement about boards that don't add the field not needing it. Wouldn't this open up potential bugs with uninitialized variables being written out to the hardware?
Andy

Andy, You are generally right. The good practice would be to modify the QE initialization tables for all relevant boards. There are 4 such boards, and I can resubmit the patch to include them. Just please note that this value is only relevant for general purpose I/O pins (defined as output). Looking at these 4 boards you can see that all their I/O pins are defined as special functions, so this patch is harmless there. BTW, I tested the patch on two of them (the MPC8568MDS and the MPC8360MDS).
Regards, David.
I'm not fundamentally against this patch in principle, but I'm concerned about your statement about boards that don't add the field not needing it. Wouldn't this open up potential bugs with uninitialized variables being written out to the hardware?
Andy

Andy, You are generally right. The good practice would be to modify the QE initialization tables for all relevant boards. There are 4 such
boards,
and I can resubmit the patch to include them. Just please note that
this
value is only relevant for general purpose I/O pins (defined as
output).
Looking at these 4 boards you can see that all their I/O pins are
defined
as special functions, so this patch is harmless there. BTW, I tested
the
patch on two of them (the MPC8568MDS and the MPC8360MDS).
Regards, David.
I'm not fundamentally against this patch in principle, but I'm concerned about your statement about boards that don't add the field not needing it. Wouldn't this open up potential bugs with uninitialized variables being written out to the hardware?
Andy
So, would you like me to repost this patch, with the added argument in all the relevant board tables? Another thing regarding this: I also have debug commands for reading/writing parallel I/O pins (pio read/write). I can add it as cmd_pio under the common folder. Question is whether this is not too much "Freescale oriented". If not - it can be added to this patch.
David.

On Jan 16, 2008 3:00 AM, David Saada David.Saada@ecitele.com wrote:
So, would you like me to repost this patch, with the added argument in all the relevant board tables?
Yes, that would be great.
Another thing regarding this: I also have debug commands for reading/writing parallel I/O pins (pio read/write). I can add it as cmd_pio under the common folder. Question is whether this is not too much "Freescale oriented". If not - it can be added to this patch.
Send it as a separate patch, and we can take a look.
Andy
participants (2)
-
Andy Fleming
-
David Saada