[U-Boot] [PATCH 6/6] powerpc/85xx: p1022ds: use the saveenv board preparation functions

Timur Tabi
2012-05-04T22:21:32Z

On the P1022, the DIU video signals are muxed with the localbus, so when
the DIU is active, the localbus is unavailable. The saveenv command
now supports board-specific functions that allow the DIU/LBC mux to
be switched while saving the environment.

This is much more efficient than switching the mux for each NOR flash
transaction (which is what the current code does), and it also allows
us to support any localbus device, not just NOR flash.

Signed-off-by: Timur Tabi <timur@freescale.com>
---
board/freescale/p1022ds/diu.c | 173 +++++++----------------------------------
include/configs/P1022DS.h | 6 --
2 files changed, 28 insertions(+), 151 deletions(-)

diff --git a/board/freescale/p1022ds/diu.c b/board/freescale/p1022ds/diu.c
index d5428ea..1dd0e1f 100644
--- a/board/freescale/p1022ds/diu.c
+++ b/board/freescale/p1022ds/diu.c
@@ -147,10 +147,7 @@ int platform_diu_init(unsigned int xres, unsigned int yres, const char *port)
*
* On the Freescale P1022, the DIU video signal and the LBC address/data lines
* share the same pins, which means that when the DIU is active (e.g. the
- * console is on the DVI display), NOR flash cannot be accessed. So we use the
- * weak accessor feature of the CFI flash code to temporarily switch the pin
- * mux from DIU to LBC whenever we want to read or write flash. This has a
- * significant performance penalty, but it's the only way to make it work.
+ * console is on the DVI display), NOR flash cannot be accessed.
*
* There are two muxes: one on the chip, and one on the board. The chip mux
* controls whether the pins are used for the DIU or the LBC, and it is
@@ -213,6 +210,33 @@ static void set_mux_to_diu(void)
}

/*
+ * While the DIU is active, the localbus is not available. Therefore, in
+ * order to support the saveenv command, we need to temporarily disable the
+ * DIU and enable the localbus. To do this, we provide our own
+ * implementations of the board_start_saveenv() and board_finish_saveenv()
+ * weak functions. These functions are called by do_env_save() before and
+ * after the environment is saved.
+ */
+
+/* Remember if we switched the MUX, so that we know to switch it back */
+static int switched;
+
+int board_start_saveenv(void)
+{
+ switched = set_mux_to_lbc();
+
+ return 0;
+}
+
+void board_finish_saveenv(void)
+{
+ if (switched)
+ set_mux_to_diu();
+
+ switched = 0;
+}
+
+/*
* pixis_read - board-specific function to read from the PIXIS
*
* This function overrides the generic pixis_read() function, so that it can
@@ -271,144 +295,3 @@ void pixis_bank_reset(void)

while (1);
}
-
-#ifdef CONFIG_CFI_FLASH_USE_WEAK_ACCESSORS
-
-void flash_write8(u8 value, void *addr)
-{
- int sw = set_mux_to_lbc();
-
- __raw_writeb(value, addr);
- if (sw) {
- /*
- * To ensure the post-write is completed to eLBC, software must
- * perform a dummy read from one valid address from eLBC space
- * before changing the eLBC_DIU from NOR mode to DIU mode.
- * set_mux_to_diu() includes a sync that will ensure the
- * __raw_readb() completes before it switches the mux.
- */
- __raw_readb(addr);
- set_mux_to_diu();
- }
-}
-
-void flash_write16(u16 value, void *addr)
-{
- int sw = set_mux_to_lbc();
-
- __raw_writew(value, addr);
- if (sw) {
- /*
- * To ensure the post-write is completed to eLBC, software must
- * perform a dummy read from one valid address from eLBC space
- * before changing the eLBC_DIU from NOR mode to DIU mode.
- * set_mux_to_diu() includes a sync that will ensure the
- * __raw_readb() completes before it switches the mux.
- */
- __raw_readb(addr);
- set_mux_to_diu();
- }
-}
-
-void flash_write32(u32 value, void *addr)
-{
- int sw = set_mux_to_lbc();
-
- __raw_writel(value, addr);
- if (sw) {
- /*
- * To ensure the post-write is completed to eLBC, software must
- * perform a dummy read from one valid address from eLBC space
- * before changing the eLBC_DIU from NOR mode to DIU mode.
- * set_mux_to_diu() includes a sync that will ensure the
- * __raw_readb() completes before it switches the mux.
- */
- __raw_readb(addr);
- set_mux_to_diu();
- }
-}
-
-void flash_write64(u64 value, void *addr)
-{
- int sw = set_mux_to_lbc();
- uint32_t *p = addr;
-
- /*
- * There is no __raw_writeq(), so do the write manually. We don't trust
- * the compiler, so we use inline assembly.
- */
- __asm__ __volatile__(
- "stw%U0%X0 %2,%0;\n"
- "stw%U1%X1 %3,%1;\n"
- : "=m" (*p), "=m" (*(p + 1))
- : "r" ((uint32_t) (value >> 32)), "r" ((uint32_t) (value)));
-
- if (sw) {
- /*
- * To ensure the post-write is completed to eLBC, software must
- * perform a dummy read from one valid address from eLBC space
- * before changing the eLBC_DIU from NOR mode to DIU mode. We
- * read addr+4 because we just wrote to addr+4, so that's how we
- * maintain execution order. set_mux_to_diu() includes a sync
- * that will ensure the __raw_readb() completes before it
- * switches the mux.
- */
- __raw_readb(addr + 4);
- set_mux_to_diu();
- }
-}
-
-u8 flash_read8(void *addr)
-{
- u8 ret;
-
- int sw = set_mux_to_lbc();
-
- ret = __raw_readb(addr);
- if (sw)
- set_mux_to_diu();
-
- return ret;
-}
-
-u16 flash_read16(void *addr)
-{
- u16 ret;
-
- int sw = set_mux_to_lbc();
-
- ret = __raw_readw(addr);
- if (sw)
- set_mux_to_diu();
-
- return ret;
-}
-
-u32 flash_read32(void *addr)
-{
- u32 ret;
-
- int sw = set_mux_to_lbc();
-
- ret = __raw_readl(addr);
- if (sw)
- set_mux_to_diu();
-
- return ret;
-}
-
-u64 flash_read64(void *addr)
-{
- u64 ret;
-
- int sw = set_mux_to_lbc();
-
- /* There is no __raw_readq(), so do the read manually */
- ret = *(volatile u64 *)addr;
- if (sw)
- set_mux_to_diu();
-
- return ret;
-}
-
-#endif
diff --git a/include/configs/P1022DS.h b/include/configs/P1022DS.h
index 9d2f8ea..89e8663 100644
--- a/include/configs/P1022DS.h
+++ b/include/configs/P1022DS.h
@@ -206,12 +206,6 @@
#define CONFIG_VGA_AS_SINGLE_DEVICE
#define CONFIG_VIDEO_LOGO
#define CONFIG_VIDEO_BMP_LOGO
-#define CONFIG_CFI_FLASH_USE_WEAK_ACCESSORS
-/*
- * With CONFIG_CFI_FLASH_USE_WEAK_ACCESSORS, flash I/O is really slow, so
- * disable empty flash sector detection, which is I/O-intensive.
- */
-#undef CONFIG_SYS_FLASH_EMPTY_INFO
#endif

#ifndef CONFIG_FSL_DIU_FB
--
1.7.3.4