This patch adds support for enabling NAND flash even if it hasn't been set up by coreboot. Since DIVIL_LBAR_FLSH[x], NANDF_DATA and NANDF_CTL are likely to be incorrect, they can be specified in Kconfig as well.
Signed-off-by: Nathan Williams nathan@traverse.com.au
Index: Config.in =================================================================== --- Config.in (revision 143) +++ Config.in (working copy) @@ -141,6 +141,46 @@ help Driver for Geode NAND flash storage
+config FORCE_NAND_FLASH + bool "Enable NAND flash automatically" + default n + depends on FLASH_DISK + help + If Geode is currently set to IDE mode, change + to NAND flash mode. + +config DIVIL_LBAR_FLSH_HI + hex "LBAR_FLSH[x] (hi)" + default "0xfffff007" + depends on FORCE_NAND_FLASH + help + Local BAR Flash Chip Select. See AMD Geode CS5536 Companion + Device Data Book section 6.6.2.8 for details. + +config DIVIL_LBAR_FLSH_LO + hex "LBAR_FLSH[x] (lo)" + default "0x20000000" + depends on FORCE_NAND_FLASH + help + Local BAR Flash Chip Select. See AMD Geode CS5536 Companion + Device Data Book section 6.6.2.8 for details. + +config NANDF_DATA + hex "Initial NANDF_DATA" + default "0x00100010" + depends on FORCE_NAND_FLASH + help + Specify NAND Flash Data Timing MSR value. See AMD Geode + CS5536 Companion Device Data Book section 6.19.1.3 for details. + +config NANDF_CTL + hex "Initial NANDF_CTL" + default "0x00000010" + depends on FORCE_NAND_FLASH + help + Specify NAND Flash Control Timing MSR value. See AMD Geode + CS5536 Companion Device Data Book section 6.19.1.4 for details. + config SUPPORT_PCI bool "PCI support" default y Index: drivers/flash/lxflash.c =================================================================== --- drivers/flash/lxflash.c (revision 143) +++ drivers/flash/lxflash.c (working copy) @@ -523,8 +523,21 @@
int NAND_close(void) { - if (g_chipID >= 0) + if (g_chipID >= 0) { wrmsr(MSR_DIVIL_LBAR_FLSH0 + g_chipID, g_orig_flsh); +#ifdef CONFIG_FORCE_NAND_FLASH + // Set up NAND data and control timing for OS + msr_t tmp; + + tmp = rdmsr(MSR_NANDF_DATA); + tmp.lo = CONFIG_NANDF_DATA; + wrmsr(MSR_NANDF_DATA, tmp); + + tmp = rdmsr(MSR_NANDF_CTL); + tmp.lo = CONFIG_NANDF_CTL; + wrmsr(MSR_NANDF_CTL, tmp); +#endif + } }
//////////////////////////////////////////////////////////////////////////////// @@ -547,19 +560,31 @@ msr = rdmsr(MSR_DIVIL_BALL_OPTS); if (msr.lo & PIN_OPT_IDE) { +#ifndef CONFIG_FORCE_NAND_FLASH printf("NAND controller not enabled!\n"); return -1; +#else + printf("Enabling NAND controller\n"); + msr.lo &= ~PIN_OPT_IDE; + wrmsr(MSR_DIVIL_BALL_OPTS, msr); +#endif } /////////////////////////////////////////////////////////////////////////////////// // init the MSR_DIVIL_LBAR_FLSHx register, I/O mapped mode, set a hardcoded base address // Later we restore initial state +#ifdef CONFIG_FORCE_NAND_FLASH + // When we NAND_close() restore to these values instead + g_orig_flsh.hi = CONFIG_DIVIL_LBAR_FLSH_HI; + g_orig_flsh.lo = CONFIG_DIVIL_LBAR_FLSH_LO; +#else g_orig_flsh = rdmsr(MSR_DIVIL_LBAR_FLSH0 + chipNum); if (!(g_orig_flsh.hi & NOR_NAND)) { printf("CS%d set up for NOR, aborting!\n", chipNum); return -1; } +#endif msr.hi = SET_FLSH_HIGH; msr.lo = SET_FLSH_LOW;