Hi,
A trivial question
Most of the read/write functions do this way
0:+ int sw = set_mux_to_lbc();
1:+
2:+ ret = __raw_readl(addr);
3:+ if (sw)
4:+ set_mux_to_diu();
compiler might reorder 2 before 3 and 0, read / write wont have any issue ,
right ?
-manish
-Original Message-
From: u-boot-release-boun...@linux.freescale.net on behalf of Tabi Timur-B04825
Sent: Fri 9/17/2010 3:05 AM
To: u-boot@lists.denx.de; Gala Kumar-B11780
Subject: [u-boot-release] [PATCH] [v3] p1022ds: use weak CFI flash
accessorswhen DIU is enabled
On the Freescale P1022, the DIU and the LBC share address 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 function 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.
This change allows the 'saveenv' command to work when the video display is
enabled. Erasing flash and writing to flash (with the 'cp' command) works,
but reading from flash (with the 'md' and 'cp' commands) does not. Also, while
flash is being written, the video display will be blank.
Signed-off-by: Timur Tabi ti...@freescale.com
---
v3: changes as requested
board/freescale/p1022ds/diu.c | 208 +++--
include/configs/P1022DS.h |6 +
2 files changed, 205 insertions(+), 9 deletions(-)
diff --git a/board/freescale/p1022ds/diu.c b/board/freescale/p1022ds/diu.c
index be6e9a8..c8bfdf0 100644
--- a/board/freescale/p1022ds/diu.c
+++ b/board/freescale/p1022ds/diu.c
@@ -14,8 +14,6 @@
#include command.h
#include asm/io.h
-#ifdef CONFIG_FSL_DIU_FB
-
#include ../common/ngpixis.h
#include ../common/fsl_diu_fb.h
@@ -24,13 +22,22 @@
#include video_fb.h
#endif
-#define PX_BRDCFG0_ELBC_DIU0x02
+/* The CTL register is called 'csr' in the ngpixis_t structure */
+#define PX_CTL_ALTACC 0x80
+
+#define PX_BRDCFG0_ELBC_SPI_MASK 0xc0
+#define PX_BRDCFG0_ELBC_SPI_ELBC 0x00
+#define PX_BRDCFG0_ELBC_SPI_NULL 0xc0
+#define PX_BRDCFG0_ELBC_DIU0x02
#define PX_BRDCFG1_DVIEN 0x80
#define PX_BRDCFG1_DFPEN 0x40
#define PX_BRDCFG1_BACKLIGHT 0x20
#define PX_BRDCFG1_DDCEN 0x10
+#define PMUXCR_ELBCDIU_MASK0xc000
+#define PMUXCR_ELBCDIU_NOR16 0x8000
+
/*
* DIU Area Descriptor
*
@@ -63,6 +70,16 @@
#define AD_DEFAULT
static int xres, yres;
+/*
+ * Variables used by the DIU/LBC switching code. It's safe to makes these
+ * global, because the DIU requires DDR, so we'll only run this code after
+ * relocation.
+ */
+static u8 px_brdcfg0;
+static u32 pmuxcr;
+static void *lbc_lcs0_ba;
+static void *lbc_lcs1_ba;
+
void diu_set_pixel_clock(unsigned int pixclock)
{
ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
@@ -88,6 +105,10 @@ int p1022ds_diu_init(void)
u32 pixel_format;
u8 temp;
+ /* Save the LBC LCS0 and LCS1 addresses for the DIU mux functions */
+ lbc_lcs0_ba = (void *)(get_lbc_br(0) get_lbc_or(0) 0x8000);
+ lbc_lcs1_ba = (void *)(get_lbc_br(1) get_lbc_or(1) 0x8000);
+
pixel_format = cpu_to_le32(AD_BYTE_F | (3 AD_ALPHA_C_SHIFT) |
(0 AD_BLUE_C_SHIFT) | (1 AD_GREEN_C_SHIFT) |
(2 AD_RED_C_SHIFT) | (8 AD_COMP_3_SHIFT) |
@@ -114,17 +135,24 @@ int p1022ds_diu_init(void)
out_8(pixis-brdcfg1, temp);
/*
+* Enable PIXIS indirect access mode. This is a hack that allows us to
+* access PIXIS registers even when the LBC pins have been muxed to the
+* DIU.
+*/
+ setbits_8(pixis-csr, PX_CTL_ALTACC);
+
+ /*
* Route the LAD pins to the DIU. This will disable access to the eLBC,
* which means we won't be able to read/write any NOR flash addresses!
*/
- out_8(pixis-brdcfg0, in_8(pixis-brdcfg0) | PX_BRDCFG0_ELBC_DIU);
- /* we must do the dummy read from eLBC to sync the write as above */
- in_8(pixis-brdcfg0);
+ out_8(lbc_lcs0_ba, offsetof(ngpixis_t, brdcfg0));
+ px_brdcfg0 = in_8(lbc_lcs1_ba);
+ out_8(lbc_lcs1_ba, px_brdcfg0 | PX_BRDCFG0_ELBC_DIU);
/* Setting PMUXCR to switch to DVI from ELBC */
- /* Set pmuxcr to allow both i2c1 and i2c2 */
- clrsetbits_be32(gur-pmuxcr, 0xc000, 0x4000);
- in_be32(gur-pmuxcr);
+ clrsetbits_be32(gur-pmuxcr,
+ PMUXCR_ELBCDIU_MASK, PMUXCR_ELBCDIU_NOR16);
+ pmuxcr = in_be32(gur-pmuxcr);
return fsl_diu_init(xres, pixel_format, 0);
}
@@ -169,4 +197,166 @@ void *video_hw_init(void)
#endif
+#ifdef CONFIG_CFI_FLASH_USE_WEAK_ACCESSORS
+
+/*
+ * set_mux_to_lbc - disable the DIU so that we can read/write to elbc
+ *
+ * On the Freescale P1022, the DIU video signal and the LBC address/data lines
+ *