ARM: omap: merge GPMC initialization code for all platform

Most of TI's SoC platform have in-buit GPMC (General Purpose Memory Controller)
which can be used to interface different types of external memories like:
 - parallel NOR flash
 - parallel NAND flash
 - OneNand flash
 - SDR RAM

This patch:
 - As the GPMC hardware engine is common across all OMAPx and AMxxxx platforms,
   so GPMC initialization code from all platforms is merged into single file:
     arch/arm/cpu/armv7/omap-common/mem-common.c

 - But as different platforms support different operating clock frequencies,
   So, same memory device can have different GPMC configuration values on
   different platforms (like memory signal timing values of same device may
   differ on different platforms). Hence actual GPMC configuration parameters
   are still kept separately in following platform specific header files:
     AM33xx: [unchanged] arch/arm/include/asm/arch-am33xx/mem.h
     OMAP3:  [modified]  arch/arm/include/asm/arch-omap3/mem.h
     OMAP4:  [new] arch/arm/include/asm/arch-omap4/mem.h
     OMAP5:  [new] arch/arm/include/asm/arch-omap5/mem.h

Signed-off-by: Pekon Gupta <pekon@ti.com>
This commit is contained in:
Pekon Gupta 2013-11-29 15:41:43 +05:30
parent 35a50ea51c
commit f9519b4a1b
8 changed files with 223 additions and 261 deletions

View File

@ -18,7 +18,6 @@ endif
COBJS-$(CONFIG_TI816X) += clock_ti816x.o
COBJS += sys_info.o
COBJS += mem.o
COBJS += board.o
COBJS += mux.o

View File

@ -1,98 +0,0 @@
/*
* (C) Copyright 2010
* Texas Instruments, <www.ti.com>
*
* Author :
* Mansoor Ahamed <mansoor.ahamed@ti.com>
*
* Initial Code from:
* Manikandan Pillai <mani.pillai@ti.com>
* Richard Woodruff <r-woodruff2@ti.com>
* Syed Mohammed Khasim <khasim@ti.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/io.h>
#include <asm/arch/cpu.h>
#include <asm/arch/mem.h>
#include <asm/arch/sys_proto.h>
#include <command.h>
struct gpmc *gpmc_cfg;
void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base,
u32 size)
{
writel(0, &cs->config7);
sdelay(1000);
/* Delay for settling */
writel(gpmc_config[0], &cs->config1);
writel(gpmc_config[1], &cs->config2);
writel(gpmc_config[2], &cs->config3);
writel(gpmc_config[3], &cs->config4);
writel(gpmc_config[4], &cs->config5);
writel(gpmc_config[5], &cs->config6);
/* Enable the config */
writel((((size & 0xF) << 8) | ((base >> 24) & 0x3F) |
(1 << 6)), &cs->config7);
sdelay(2000);
}
/*****************************************************
* gpmc_init(): init gpmc bus
* Init GPMC for x16, MuxMode (SDRAM in x32).
* This code can only be executed from SRAM or SDRAM.
*****************************************************/
void gpmc_init(void)
{
/* putting a blanket check on GPMC based on ZeBu for now */
gpmc_cfg = (struct gpmc *)GPMC_BASE;
#if defined(CONFIG_NOR)
/* configure GPMC for NOR */
const u32 gpmc_regs[GPMC_MAX_REG] = { STNOR_GPMC_CONFIG1,
STNOR_GPMC_CONFIG2,
STNOR_GPMC_CONFIG3,
STNOR_GPMC_CONFIG4,
STNOR_GPMC_CONFIG5,
STNOR_GPMC_CONFIG6,
STNOR_GPMC_CONFIG7
};
u32 size = GPMC_SIZE_16M;
u32 base = CONFIG_SYS_FLASH_BASE;
#elif defined(CONFIG_NAND)
/* configure GPMC for NAND */
const u32 gpmc_regs[GPMC_MAX_REG] = { M_NAND_GPMC_CONFIG1,
M_NAND_GPMC_CONFIG2,
M_NAND_GPMC_CONFIG3,
M_NAND_GPMC_CONFIG4,
M_NAND_GPMC_CONFIG5,
M_NAND_GPMC_CONFIG6,
0
};
u32 size = GPMC_SIZE_256M;
u32 base = CONFIG_SYS_NAND_BASE;
#else
const u32 gpmc_regs[GPMC_MAX_REG] = { 0, 0, 0, 0, 0, 0, 0 };
u32 size = 0;
u32 base = 0;
#endif
/* global settings */
writel(0x00000008, &gpmc_cfg->sysconfig);
writel(0x00000000, &gpmc_cfg->irqstatus);
writel(0x00000000, &gpmc_cfg->irqenable);
#ifdef CONFIG_NOR
writel(0x00000200, &gpmc_cfg->config);
#else
writel(0x00000012, &gpmc_cfg->config);
#endif
/*
* Disable the GPMC0 config set by ROM code
*/
writel(0, &gpmc_cfg->cs[0].config7);
sdelay(1000);
/* enable chip-select specific configurations */
enable_gpmc_cs_config(gpmc_regs, &gpmc_cfg->cs[0], base, size);
}

View File

@ -33,11 +33,7 @@ COBJS += boot-common.o
SOBJS += lowlevel_init.o
endif
ifndef CONFIG_SPL_BUILD
ifneq ($(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),)
COBJS += mem-common.o
endif
endif
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))

View File

@ -2,31 +2,124 @@
* (C) Copyright 2010
* Texas Instruments, <www.ti.com>
*
* Steve Sakoman <steve@sakoman.com>
* Author :
* Mansoor Ahamed <mansoor.ahamed@ti.com>
*
* Initial Code from:
* Manikandan Pillai <mani.pillai@ti.com>
* Richard Woodruff <r-woodruff2@ti.com>
* Syed Mohammed Khasim <khasim@ti.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/io.h>
#include <asm/arch/cpu.h>
#include <asm/arch/mem.h>
#include <asm/arch/sys_proto.h>
#include <command.h>
#include <linux/mtd/omap_gpmc.h>
struct gpmc *gpmc_cfg;
#if defined(CONFIG_OMAP34XX)
/********************************************************
* mem_ok() - test used to see if timings are correct
* for a part. Helps in guessing which part
* we are currently using.
*******************************************************/
u32 mem_ok(u32 cs)
{
u32 val1, val2, addr;
u32 pattern = 0x12345678;
addr = OMAP34XX_SDRC_CS0 + get_sdr_cs_offset(cs);
writel(0x0, addr + 0x400); /* clear pos A */
writel(pattern, addr); /* pattern to pos B */
writel(0x0, addr + 4); /* remove pattern off the bus */
val1 = readl(addr + 0x400); /* get pos A value */
val2 = readl(addr); /* get val2 */
writel(0x0, addr + 0x400); /* clear pos A */
if ((val1 != 0) || (val2 != pattern)) /* see if pos A val changed */
return 0;
else
return 1;
}
#endif
void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base,
u32 size)
{
writel(0, &cs->config7);
sdelay(1000);
/* Delay for settling */
writel(gpmc_config[0], &cs->config1);
writel(gpmc_config[1], &cs->config2);
writel(gpmc_config[2], &cs->config3);
writel(gpmc_config[3], &cs->config4);
writel(gpmc_config[4], &cs->config5);
writel(gpmc_config[5], &cs->config6);
/* Enable the config */
writel((((size & 0xF) << 8) | ((base >> 24) & 0x3F) |
(1 << 6)), &cs->config7);
sdelay(2000);
}
/*****************************************************
* gpmc_init(): init gpmc bus
* Init GPMC for x16, MuxMode (SDRAM in x32).
* This code can only be executed from SRAM or SDRAM.
*****************************************************/
void gpmc_init(void)
{
/* putting a blanket check on GPMC based on ZeBu for now */
gpmc_cfg = (struct gpmc *)GPMC_BASE;
#if defined(CONFIG_NOR)
/* configure GPMC for NOR */
const u32 gpmc_regs[GPMC_MAX_REG] = { STNOR_GPMC_CONFIG1,
STNOR_GPMC_CONFIG2,
STNOR_GPMC_CONFIG3,
STNOR_GPMC_CONFIG4,
STNOR_GPMC_CONFIG5,
STNOR_GPMC_CONFIG6,
STNOR_GPMC_CONFIG7
};
u32 size = GPMC_SIZE_16M;
u32 base = CONFIG_SYS_FLASH_BASE;
#elif defined(CONFIG_NAND)
/* configure GPMC for NAND */
const u32 gpmc_regs[GPMC_MAX_REG] = { M_NAND_GPMC_CONFIG1,
M_NAND_GPMC_CONFIG2,
M_NAND_GPMC_CONFIG3,
M_NAND_GPMC_CONFIG4,
M_NAND_GPMC_CONFIG5,
M_NAND_GPMC_CONFIG6,
0
};
u32 size = GPMC_SIZE_256M;
u32 base = CONFIG_SYS_NAND_BASE;
#else
const u32 gpmc_regs[GPMC_MAX_REG] = { 0, 0, 0, 0, 0, 0, 0 };
u32 size = 0;
u32 base = 0;
#endif
/* global settings */
writel(0, &gpmc_cfg->irqenable); /* isr's sources masked */
writel(0, &gpmc_cfg->timeout_control);/* timeout disable */
writel(0x00000008, &gpmc_cfg->sysconfig);
writel(0x00000000, &gpmc_cfg->irqstatus);
writel(0x00000000, &gpmc_cfg->irqenable);
#ifdef CONFIG_NOR
writel(0x00000200, &gpmc_cfg->config);
#else
writel(0x00000012, &gpmc_cfg->config);
#endif
/*
* Disable the GPMC0 config set by ROM code
* It conflicts with our MPDB (both at 0x08000000)
*/
writel(0, &gpmc_cfg->cs[0].config7);
sdelay(1000);
/* enable chip-select specific configurations */
enable_gpmc_cs_config(gpmc_regs, &gpmc_cfg->cs[0], base, size);
}

View File

@ -13,7 +13,6 @@ SOBJS := lowlevel_init.o
COBJS += board.o
COBJS += clock.o
COBJS += mem.o
COBJS += sys_info.o
ifdef CONFIG_SPL_BUILD
COBJS-$(CONFIG_SPL_OMAP3_ID_NAND) += spl_id_nand.o

View File

@ -1,151 +0,0 @@
/*
* (C) Copyright 2008
* Texas Instruments, <www.ti.com>
*
* Author :
* Manikandan Pillai <mani.pillai@ti.com>
*
* Initial Code from:
* Richard Woodruff <r-woodruff2@ti.com>
* Syed Mohammed Khasim <khasim@ti.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/io.h>
#include <asm/arch/mem.h>
#include <asm/arch/sys_proto.h>
#include <command.h>
struct gpmc *gpmc_cfg;
#if defined(CONFIG_CMD_NAND)
#if defined(GPMC_NAND_ECC_SP_x8_LAYOUT) || defined(GPMC_NAND_ECC_LP_x8_LAYOUT)
static const u32 gpmc_m_nand[GPMC_MAX_REG] = {
SMNAND_GPMC_CONFIG1,
SMNAND_GPMC_CONFIG2,
SMNAND_GPMC_CONFIG3,
SMNAND_GPMC_CONFIG4,
SMNAND_GPMC_CONFIG5,
SMNAND_GPMC_CONFIG6,
0,
};
#else
static const u32 gpmc_m_nand[GPMC_MAX_REG] = {
M_NAND_GPMC_CONFIG1,
M_NAND_GPMC_CONFIG2,
M_NAND_GPMC_CONFIG3,
M_NAND_GPMC_CONFIG4,
M_NAND_GPMC_CONFIG5,
M_NAND_GPMC_CONFIG6, 0
};
#endif
#endif /* CONFIG_CMD_NAND */
#if defined(CONFIG_CMD_ONENAND)
static const u32 gpmc_onenand[GPMC_MAX_REG] = {
ONENAND_GPMC_CONFIG1,
ONENAND_GPMC_CONFIG2,
ONENAND_GPMC_CONFIG3,
ONENAND_GPMC_CONFIG4,
ONENAND_GPMC_CONFIG5,
ONENAND_GPMC_CONFIG6, 0
};
#endif /* CONFIG_CMD_ONENAND */
/********************************************************
* mem_ok() - test used to see if timings are correct
* for a part. Helps in guessing which part
* we are currently using.
*******************************************************/
u32 mem_ok(u32 cs)
{
u32 val1, val2, addr;
u32 pattern = 0x12345678;
addr = OMAP34XX_SDRC_CS0 + get_sdr_cs_offset(cs);
writel(0x0, addr + 0x400); /* clear pos A */
writel(pattern, addr); /* pattern to pos B */
writel(0x0, addr + 4); /* remove pattern off the bus */
val1 = readl(addr + 0x400); /* get pos A value */
val2 = readl(addr); /* get val2 */
writel(0x0, addr + 0x400); /* clear pos A */
if ((val1 != 0) || (val2 != pattern)) /* see if pos A val changed */
return 0;
else
return 1;
}
void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base,
u32 size)
{
writel(0, &cs->config7);
sdelay(1000);
/* Delay for settling */
writel(gpmc_config[0], &cs->config1);
writel(gpmc_config[1], &cs->config2);
writel(gpmc_config[2], &cs->config3);
writel(gpmc_config[3], &cs->config4);
writel(gpmc_config[4], &cs->config5);
writel(gpmc_config[5], &cs->config6);
/*
* Enable the config. size is the CS size and goes in
* bits 11:8. We set bit 6 to enable this CS and the base
* address goes into bits 5:0.
*/
writel((size << 8) | (GPMC_CS_ENABLE << 6) |
((base >> 24) & GPMC_BASEADDR_MASK),
&cs->config7);
sdelay(2000);
}
/*****************************************************
* gpmc_init(): init gpmc bus
* Init GPMC for x16, MuxMode (SDRAM in x32).
* This code can only be executed from SRAM or SDRAM.
*****************************************************/
void gpmc_init(void)
{
/* putting a blanket check on GPMC based on ZeBu for now */
gpmc_cfg = (struct gpmc *)GPMC_BASE;
#if defined(CONFIG_CMD_NAND) || defined(CONFIG_CMD_ONENAND)
const u32 *gpmc_config = NULL;
u32 base = 0;
u32 size = 0;
#endif
u32 config = 0;
/* global settings */
writel(0, &gpmc_cfg->irqenable); /* isr's sources masked */
writel(0, &gpmc_cfg->timeout_control);/* timeout disable */
config = readl(&gpmc_cfg->config);
config &= (~0xf00);
writel(config, &gpmc_cfg->config);
/*
* Disable the GPMC0 config set by ROM code
* It conflicts with our MPDB (both at 0x08000000)
*/
writel(0, &gpmc_cfg->cs[0].config7);
sdelay(1000);
#if defined(CONFIG_CMD_NAND) /* CS 0 */
gpmc_config = gpmc_m_nand;
base = PISMO1_NAND_BASE;
size = PISMO1_NAND_SIZE;
enable_gpmc_cs_config(gpmc_config, &gpmc_cfg->cs[0], base, size);
#endif
#if defined(CONFIG_CMD_ONENAND)
gpmc_config = gpmc_onenand;
base = PISMO1_ONEN_BASE;
size = PISMO1_ONEN_SIZE;
enable_gpmc_cs_config(gpmc_config, &gpmc_cfg->cs[0], base, size);
#endif
}

View File

@ -0,0 +1,62 @@
/*
* (C) Copyright 2006-2008
* Texas Instruments, <www.ti.com>
*
* Author
* Mansoor Ahamed <mansoor.ahamed@ti.com>
*
* Initial Code from:
* Richard Woodruff <r-woodruff2@ti.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _MEM_H_
#define _MEM_H_
/*
* GPMC settings -
* Definitions is as per the following format
* #define <PART>_GPMC_CONFIG<x> <value>
* Where:
* PART is the part name e.g. STNOR - Intel Strata Flash
* x is GPMC config registers from 1 to 6 (there will be 6 macros)
* Value is corresponding value
*
* For every valid PRCM configuration there should be only one definition of
* the same. if values are independent of the board, this definition will be
* present in this file if values are dependent on the board, then this should
* go into corresponding mem-boardName.h file
*
* Currently valid part Names are (PART):
* M_NAND - Micron NAND
* STNOR - STMicrolelctronics M29W128GL
*/
#define GPMC_SIZE_256M 0x0
#define GPMC_SIZE_128M 0x8
#define GPMC_SIZE_64M 0xC
#define GPMC_SIZE_32M 0xE
#define GPMC_SIZE_16M 0xF
#define M_NAND_GPMC_CONFIG1 0x00000800
#define M_NAND_GPMC_CONFIG2 0x001e1e00
#define M_NAND_GPMC_CONFIG3 0x001e1e00
#define M_NAND_GPMC_CONFIG4 0x16051807
#define M_NAND_GPMC_CONFIG5 0x00151e1e
#define M_NAND_GPMC_CONFIG6 0x16000f80
#define M_NAND_GPMC_CONFIG7 0x00000008
#define STNOR_GPMC_CONFIG1 0x00001200
#define STNOR_GPMC_CONFIG2 0x00101000
#define STNOR_GPMC_CONFIG3 0x00030301
#define STNOR_GPMC_CONFIG4 0x10041004
#define STNOR_GPMC_CONFIG5 0x000C1010
#define STNOR_GPMC_CONFIG6 0x08070280
#define STNOR_GPMC_CONFIG7 0x00000F48
/* max number of GPMC Chip Selects */
#define GPMC_MAX_CS 8
/* max number of GPMC regs */
#define GPMC_MAX_REG 7
#endif /* endif _MEM_H_ */

View File

@ -0,0 +1,62 @@
/*
* (C) Copyright 2006-2008
* Texas Instruments, <www.ti.com>
*
* Author
* Mansoor Ahamed <mansoor.ahamed@ti.com>
*
* Initial Code from:
* Richard Woodruff <r-woodruff2@ti.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _MEM_H_
#define _MEM_H_
/*
* GPMC settings -
* Definitions is as per the following format
* #define <PART>_GPMC_CONFIG<x> <value>
* Where:
* PART is the part name e.g. STNOR - Intel Strata Flash
* x is GPMC config registers from 1 to 6 (there will be 6 macros)
* Value is corresponding value
*
* For every valid PRCM configuration there should be only one definition of
* the same. if values are independent of the board, this definition will be
* present in this file if values are dependent on the board, then this should
* go into corresponding mem-boardName.h file
*
* Currently valid part Names are (PART):
* M_NAND - Micron NAND
* STNOR - STMicrolelctronics M29W128GL
*/
#define GPMC_SIZE_256M 0x0
#define GPMC_SIZE_128M 0x8
#define GPMC_SIZE_64M 0xC
#define GPMC_SIZE_32M 0xE
#define GPMC_SIZE_16M 0xF
#define M_NAND_GPMC_CONFIG1 0x00000800
#define M_NAND_GPMC_CONFIG2 0x001e1e00
#define M_NAND_GPMC_CONFIG3 0x001e1e00
#define M_NAND_GPMC_CONFIG4 0x16051807
#define M_NAND_GPMC_CONFIG5 0x00151e1e
#define M_NAND_GPMC_CONFIG6 0x16000f80
#define M_NAND_GPMC_CONFIG7 0x00000008
#define STNOR_GPMC_CONFIG1 0x00001200
#define STNOR_GPMC_CONFIG2 0x00101000
#define STNOR_GPMC_CONFIG3 0x00030301
#define STNOR_GPMC_CONFIG4 0x10041004
#define STNOR_GPMC_CONFIG5 0x000C1010
#define STNOR_GPMC_CONFIG6 0x08070280
#define STNOR_GPMC_CONFIG7 0x00000F48
/* max number of GPMC Chip Selects */
#define GPMC_MAX_CS 8
/* max number of GPMC regs */
#define GPMC_MAX_REG 7
#endif /* endif _MEM_H_ */