diff options
-rw-r--r-- | board/freescale/common/ngpixis.c | 56 | ||||
-rw-r--r-- | board/freescale/common/ngpixis.h | 8 | ||||
-rw-r--r-- | board/freescale/p1022ds/diu.c | 66 |
3 files changed, 112 insertions, 18 deletions
diff --git a/board/freescale/common/ngpixis.c b/board/freescale/common/ngpixis.c index a135fbe..4e01e5a 100644 --- a/board/freescale/common/ngpixis.c +++ b/board/freescale/common/ngpixis.c @@ -1,5 +1,5 @@ /** - * Copyright 2010 Freescale Semiconductor + * Copyright 2010-2011 Freescale Semiconductor * Author: Timur Tabi <timur@freescale.com> * * This program is free software; you can redistribute it and/or modify it @@ -35,61 +35,89 @@ #include <common.h> #include <command.h> -#include <watchdog.h> -#include <asm/cache.h> #include <asm/io.h> #include "ngpixis.h" +static u8 __pixis_read(unsigned int reg) +{ + void *p = (void *)PIXIS_BASE; + + return in_8(p + reg); +} +u8 pixis_read(unsigned int reg) __attribute__((weak, alias("__pixis_read"))); + +static void __pixis_write(unsigned int reg, u8 value) +{ + void *p = (void *)PIXIS_BASE; + + out_8(p + reg, value); +} +void pixis_write(unsigned int reg, u8 value) + __attribute__((weak, alias("__pixis_write"))); + /* * Reset the board. This ignores the ENx registers. */ -void pixis_reset(void) +void __pixis_reset(void) { - out_8(&pixis->rst, 0); + PIXIS_WRITE(rst, 0); while (1); } +void pixis_reset(void) __attribute__((weak, alias("__pixis_reset"))); /* * Reset the board. Like pixis_reset(), but it honors the ENx registers. */ -void pixis_bank_reset(void) +void __pixis_bank_reset(void) { - out_8(&pixis->vctl, 0); - out_8(&pixis->vctl, 1); + PIXIS_WRITE(vctl, 0); + PIXIS_WRITE(vctl, 1); while (1); } +void pixis_bank_reset(void) __attribute__((weak, alias("__pixis_bank_reset"))); /** * Set the boot bank to the power-on default bank */ -void clear_altbank(void) +void __clear_altbank(void) { + u8 reg; + /* Tell the ngPIXIS to use this the bits in the physical switch for the * boot bank value, instead of the SWx register. We need to be careful * only to set the bits in SWx that correspond to the boot bank. */ - clrbits_8(&PIXIS_EN(PIXIS_LBMAP_SWITCH), PIXIS_LBMAP_MASK); + reg = PIXIS_READ(s[PIXIS_LBMAP_SWITCH - 1].en); + reg &= ~PIXIS_LBMAP_MASK; + PIXIS_WRITE(s[PIXIS_LBMAP_SWITCH - 1].en, reg); } +void clear_altbank(void) __attribute__((weak, alias("__clear_altbank"))); /** * Set the boot bank to the alternate bank */ -void set_altbank(void) +void __set_altbank(void) { + u8 reg; + /* Program the alternate bank number into the SWx register. */ - clrsetbits_8(&PIXIS_SW(PIXIS_LBMAP_SWITCH), PIXIS_LBMAP_MASK, - PIXIS_LBMAP_ALTBANK); + reg = PIXIS_READ(s[PIXIS_LBMAP_SWITCH - 1].sw); + reg = (reg & ~PIXIS_LBMAP_MASK) | PIXIS_LBMAP_ALTBANK; + PIXIS_WRITE(s[PIXIS_LBMAP_SWITCH - 1].sw, reg); /* Tell the ngPIXIS to use this the bits in the SWx register for the * boot bank value, instead of the physical switch. We need to be * careful only to set the bits in SWx that correspond to the boot bank. */ - setbits_8(&PIXIS_EN(PIXIS_LBMAP_SWITCH), PIXIS_LBMAP_MASK); + reg = PIXIS_READ(s[PIXIS_LBMAP_SWITCH - 1].en); + reg |= PIXIS_LBMAP_MASK; + PIXIS_WRITE(s[PIXIS_LBMAP_SWITCH - 1].en, reg); } +void set_altbank(void) __attribute__((weak, alias("__set_altbank"))); int pixis_reset_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) diff --git a/board/freescale/common/ngpixis.h b/board/freescale/common/ngpixis.h index 089408b..681b0d0 100644 --- a/board/freescale/common/ngpixis.h +++ b/board/freescale/common/ngpixis.h @@ -1,5 +1,5 @@ /** - * Copyright 2010 Freescale Semiconductor + * Copyright 2010-2011 Freescale Semiconductor * Author: Timur Tabi <timur@freescale.com> * * This program is free software; you can redistribute it and/or modify it @@ -55,3 +55,9 @@ typedef struct ngpixis { /* The PIXIS EN register that corresponds to board switch X, where x >= 1 */ #define PIXIS_EN(x) (pixis->s[(x) - 1].en) + +u8 pixis_read(unsigned int reg); +void pixis_write(unsigned int reg, u8 value); + +#define PIXIS_READ(reg) pixis_read(offsetof(ngpixis_t, reg)) +#define PIXIS_WRITE(reg, value) pixis_write(offsetof(ngpixis_t, reg), value) diff --git a/board/freescale/p1022ds/diu.c b/board/freescale/p1022ds/diu.c index 8f5305c..b37e0e2 100644 --- a/board/freescale/p1022ds/diu.c +++ b/board/freescale/p1022ds/diu.c @@ -1,5 +1,5 @@ /* - * Copyright 2010 Freescale Semiconductor, Inc. + * Copyright 2010-2011 Freescale Semiconductor, Inc. * Authors: Timur Tabi <timur@freescale.com> * * FSL DIU Framebuffer driver @@ -139,8 +139,6 @@ int platform_diu_init(unsigned int *xres, unsigned int *yres) return fsl_diu_init(*xres, pixel_format, 0); } -#ifdef CONFIG_CFI_FLASH_USE_WEAK_ACCESSORS - /* * set_mux_to_lbc - disable the DIU so that we can read/write to elbc * @@ -211,6 +209,68 @@ static void set_mux_to_diu(void) in_be32(&gur->pmuxcr); } +/* + * pixis_read - board-specific function to read from the PIXIS + * + * This function overrides the generic pixis_read() function, so that it can + * use PIXIS indirect mode if necessary. + */ +u8 pixis_read(unsigned int reg) +{ + ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; + + /* Use indirect mode if the mux is currently set to DIU mode */ + if ((in_be32(&gur->pmuxcr) & PMUXCR_ELBCDIU_MASK) != + PMUXCR_ELBCDIU_NOR16) { + out_8(lbc_lcs0_ba, reg); + return in_8(lbc_lcs1_ba); + } else { + void *p = (void *)PIXIS_BASE; + + return in_8(p + reg); + } +} + +/* + * pixis_write - board-specific function to write to the PIXIS + * + * This function overrides the generic pixis_write() function, so that it can + * use PIXIS indirect mode if necessary. + */ +void pixis_write(unsigned int reg, u8 value) +{ + ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; + + /* Use indirect mode if the mux is currently set to DIU mode */ + if ((in_be32(&gur->pmuxcr) & PMUXCR_ELBCDIU_MASK) != + PMUXCR_ELBCDIU_NOR16) { + out_8(lbc_lcs0_ba, reg); + out_8(lbc_lcs1_ba, value); + /* Do a read-back to ensure the write completed */ + in_8(lbc_lcs1_ba); + } else { + void *p = (void *)PIXIS_BASE; + + out_8(p + reg, value); + } +} + +void pixis_bank_reset(void) +{ + /* + * For some reason, a PIXIS bank reset does not work if the PIXIS is + * in indirect mode, so switch to direct mode first. + */ + set_mux_to_lbc(); + + out_8(&pixis->vctl, 0); + out_8(&pixis->vctl, 1); + + while (1); +} + +#ifdef CONFIG_CFI_FLASH_USE_WEAK_ACCESSORS + void flash_write8(u8 value, void *addr) { int sw = set_mux_to_lbc(); |