summaryrefslogtreecommitdiff
path: root/cpu/ppc4xx
diff options
context:
space:
mode:
Diffstat (limited to 'cpu/ppc4xx')
-rw-r--r--cpu/ppc4xx/44x_spd_ddr.c4
-rw-r--r--cpu/ppc4xx/44x_spd_ddr2.c4
-rw-r--r--cpu/ppc4xx/gpio.c42
-rw-r--r--cpu/ppc4xx/tlb.c77
4 files changed, 88 insertions, 39 deletions
diff --git a/cpu/ppc4xx/44x_spd_ddr.c b/cpu/ppc4xx/44x_spd_ddr.c
index c500d3f..fe7bbab 100644
--- a/cpu/ppc4xx/44x_spd_ddr.c
+++ b/cpu/ppc4xx/44x_spd_ddr.c
@@ -262,7 +262,7 @@ typedef struct bank_param BANKPARMS;
#ifdef CFG_SIMULATE_SPD_EEPROM
extern unsigned char cfg_simulate_spd_eeprom[128];
#endif
-void program_tlb(u32 start, u32 size, u32 tlb_word2_i_value);
+void program_tlb(u32 phys_addr, u32 virt_addr, u32 size, u32 tlb_word2_i_value);
static unsigned char spd_read(uchar chip, uint addr);
static void get_spd_info(unsigned long *dimm_populated,
@@ -373,7 +373,7 @@ long int spd_sdram(void) {
#ifdef CONFIG_PROG_SDRAM_TLB /* this define should eventually be removed */
/* and program tlb entries for this size (dynamic) */
- program_tlb(0, total_size, MY_TLB_WORD2_I_ENABLE);
+ program_tlb(0, 0, total_size, MY_TLB_WORD2_I_ENABLE);
#endif
/*
diff --git a/cpu/ppc4xx/44x_spd_ddr2.c b/cpu/ppc4xx/44x_spd_ddr2.c
index 48b9ee2..874cec0 100644
--- a/cpu/ppc4xx/44x_spd_ddr2.c
+++ b/cpu/ppc4xx/44x_spd_ddr2.c
@@ -144,7 +144,7 @@ typedef enum ddr_cas_id {
* Prototypes
*-----------------------------------------------------------------------------*/
static unsigned long sdram_memsize(void);
-void program_tlb(u32 start, u32 size, u32 tlb_word2_i_value);
+void program_tlb(u32 phys_addr, u32 virt_addr, u32 size, u32 tlb_word2_i_value);
static void get_spd_info(unsigned long *dimm_populated,
unsigned char *iic0_dimm_addr,
unsigned long num_dimm_banks);
@@ -528,7 +528,7 @@ long int initdram(int board_type)
dram_size = sdram_memsize();
/* and program tlb entries for this size (dynamic) */
- program_tlb(0, dram_size, MY_TLB_WORD2_I_ENABLE);
+ program_tlb(0, 0, dram_size, MY_TLB_WORD2_I_ENABLE);
/*------------------------------------------------------------------
* DQS calibration.
diff --git a/cpu/ppc4xx/gpio.c b/cpu/ppc4xx/gpio.c
index dd84e58..5235203 100644
--- a/cpu/ppc4xx/gpio.c
+++ b/cpu/ppc4xx/gpio.c
@@ -103,6 +103,18 @@ void gpio_write_bit(int pin, int val)
out32(GPIO0_OR + offs, in32(GPIO0_OR + offs) & ~GPIO_VAL(pin));
}
+int gpio_read_out_bit(int pin)
+{
+ u32 offs = 0;
+
+ if (pin >= GPIO_MAX) {
+ offs = 0x100;
+ pin -= GPIO_MAX;
+ }
+
+ return (in32(GPIO0_OR + offs) & GPIO_VAL(pin) ? 1 : 0);
+}
+
#if defined(CFG_440_GPIO_TABLE)
void gpio_set_chip_configuration(void)
{
@@ -157,12 +169,38 @@ void gpio_set_chip_configuration(void)
switch (gpio_tab[gpio_core][i].alt_nb) {
case GPIO_SEL:
if (gpio_core == GPIO0) {
- reg = in32(GPIO0_TCR) | (0x80000000 >> (j));
+ /*
+ * Setup output value
+ * 1 -> high level
+ * 0 -> low level
+ * else -> don't touch
+ */
+ reg = in32(GPIO0_OR);
+ if (gpio_tab[gpio_core][i].out_val == GPIO_OUT_1)
+ reg |= (0x80000000 >> (i));
+ else if (gpio_tab[gpio_core][i].out_val == GPIO_OUT_0)
+ reg &= ~(0x80000000 >> (i));
+ out32(GPIO0_OR, reg);
+
+ reg = in32(GPIO0_TCR) | (0x80000000 >> (i));
out32(GPIO0_TCR, reg);
}
if (gpio_core == GPIO1) {
- reg = in32(GPIO1_TCR) | (0x80000000 >> (j));
+ /*
+ * Setup output value
+ * 1 -> high level
+ * 0 -> low level
+ * else -> don't touch
+ */
+ reg = in32(GPIO0_OR);
+ if (gpio_tab[gpio_core][i].out_val == GPIO_OUT_1)
+ reg |= (0x80000000 >> (i));
+ else if (gpio_tab[gpio_core][i].out_val == GPIO_OUT_0)
+ reg &= ~(0x80000000 >> (i));
+ out32(GPIO0_OR, reg);
+
+ reg = in32(GPIO1_TCR) | (0x80000000 >> (i));
out32(GPIO1_TCR, reg);
}
diff --git a/cpu/ppc4xx/tlb.c b/cpu/ppc4xx/tlb.c
index 50344a4..6c916ef 100644
--- a/cpu/ppc4xx/tlb.c
+++ b/cpu/ppc4xx/tlb.c
@@ -36,7 +36,8 @@ typedef struct region {
unsigned long tlb_word2_i_value;
} region_t;
-static int add_tlb_entry(unsigned long base_addr,
+static int add_tlb_entry(unsigned long phys_addr,
+ unsigned long virt_addr,
unsigned long tlb_word0_size_value,
unsigned long tlb_word2_i_value)
{
@@ -55,9 +56,9 @@ static int add_tlb_entry(unsigned long base_addr,
return -1;
/* Second, create the TLB entry */
- tlb_word0_value = TLB_WORD0_EPN_ENCODE(base_addr) | TLB_WORD0_V_ENABLE |
+ tlb_word0_value = TLB_WORD0_EPN_ENCODE(virt_addr) | TLB_WORD0_V_ENABLE |
TLB_WORD0_TS_0 | tlb_word0_size_value;
- tlb_word1_value = TLB_WORD1_RPN_ENCODE(base_addr) | TLB_WORD1_ERPN_ENCODE(0);
+ tlb_word1_value = TLB_WORD1_RPN_ENCODE(phys_addr) | TLB_WORD1_ERPN_ENCODE(0);
tlb_word2_value = TLB_WORD2_U0_DISABLE | TLB_WORD2_U1_DISABLE |
TLB_WORD2_U2_DISABLE | TLB_WORD2_U3_DISABLE |
TLB_WORD2_W_DISABLE | tlb_word2_i_value |
@@ -81,7 +82,9 @@ static int add_tlb_entry(unsigned long base_addr,
return 0;
}
-static void program_tlb_addr(unsigned long base_addr, unsigned long mem_size,
+static void program_tlb_addr(unsigned long phys_addr,
+ unsigned long virt_addr,
+ unsigned long mem_size,
unsigned long tlb_word2_i_value)
{
int rc;
@@ -91,70 +94,78 @@ static void program_tlb_addr(unsigned long base_addr, unsigned long mem_size,
while (mem_size != 0) {
rc = 0;
/* Add the TLB entries in to map the region. */
- if (((base_addr & TLB_256MB_ALIGN_MASK) == base_addr) &&
+ if (((phys_addr & TLB_256MB_ALIGN_MASK) == phys_addr) &&
(mem_size >= TLB_256MB_SIZE)) {
/* Add a 256MB TLB entry */
- if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_256MB, tlb_i)) == 0) {
+ if ((rc = add_tlb_entry(phys_addr, virt_addr,
+ TLB_WORD0_SIZE_256MB, tlb_i)) == 0) {
mem_size -= TLB_256MB_SIZE;
- base_addr += TLB_256MB_SIZE;
+ phys_addr += TLB_256MB_SIZE;
}
- } else if (((base_addr & TLB_16MB_ALIGN_MASK) == base_addr) &&
+ } else if (((phys_addr & TLB_16MB_ALIGN_MASK) == phys_addr) &&
(mem_size >= TLB_16MB_SIZE)) {
/* Add a 16MB TLB entry */
- if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_16MB, tlb_i)) == 0) {
+ if ((rc = add_tlb_entry(phys_addr, virt_addr,
+ TLB_WORD0_SIZE_16MB, tlb_i)) == 0) {
mem_size -= TLB_16MB_SIZE;
- base_addr += TLB_16MB_SIZE;
+ phys_addr += TLB_16MB_SIZE;
}
- } else if (((base_addr & TLB_1MB_ALIGN_MASK) == base_addr) &&
+ } else if (((phys_addr & TLB_1MB_ALIGN_MASK) == phys_addr) &&
(mem_size >= TLB_1MB_SIZE)) {
/* Add a 1MB TLB entry */
- if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_1MB, tlb_i)) == 0) {
+ if ((rc = add_tlb_entry(phys_addr, virt_addr,
+ TLB_WORD0_SIZE_1MB, tlb_i)) == 0) {
mem_size -= TLB_1MB_SIZE;
- base_addr += TLB_1MB_SIZE;
+ phys_addr += TLB_1MB_SIZE;
}
- } else if (((base_addr & TLB_256KB_ALIGN_MASK) == base_addr) &&
+ } else if (((phys_addr & TLB_256KB_ALIGN_MASK) == phys_addr) &&
(mem_size >= TLB_256KB_SIZE)) {
/* Add a 256KB TLB entry */
- if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_256KB, tlb_i)) == 0) {
+ if ((rc = add_tlb_entry(phys_addr, virt_addr,
+ TLB_WORD0_SIZE_256KB, tlb_i)) == 0) {
mem_size -= TLB_256KB_SIZE;
- base_addr += TLB_256KB_SIZE;
+ phys_addr += TLB_256KB_SIZE;
}
- } else if (((base_addr & TLB_64KB_ALIGN_MASK) == base_addr) &&
+ } else if (((phys_addr & TLB_64KB_ALIGN_MASK) == phys_addr) &&
(mem_size >= TLB_64KB_SIZE)) {
/* Add a 64KB TLB entry */
- if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_64KB, tlb_i)) == 0) {
+ if ((rc = add_tlb_entry(phys_addr, virt_addr,
+ TLB_WORD0_SIZE_64KB, tlb_i)) == 0) {
mem_size -= TLB_64KB_SIZE;
- base_addr += TLB_64KB_SIZE;
+ phys_addr += TLB_64KB_SIZE;
}
- } else if (((base_addr & TLB_16KB_ALIGN_MASK) == base_addr) &&
+ } else if (((phys_addr & TLB_16KB_ALIGN_MASK) == phys_addr) &&
(mem_size >= TLB_16KB_SIZE)) {
/* Add a 16KB TLB entry */
- if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_16KB, tlb_i)) == 0) {
+ if ((rc = add_tlb_entry(phys_addr, virt_addr,
+ TLB_WORD0_SIZE_16KB, tlb_i)) == 0) {
mem_size -= TLB_16KB_SIZE;
- base_addr += TLB_16KB_SIZE;
+ phys_addr += TLB_16KB_SIZE;
}
- } else if (((base_addr & TLB_4KB_ALIGN_MASK) == base_addr) &&
+ } else if (((phys_addr & TLB_4KB_ALIGN_MASK) == phys_addr) &&
(mem_size >= TLB_4KB_SIZE)) {
/* Add a 4KB TLB entry */
- if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_4KB, tlb_i)) == 0) {
+ if ((rc = add_tlb_entry(phys_addr, virt_addr,
+ TLB_WORD0_SIZE_4KB, tlb_i)) == 0) {
mem_size -= TLB_4KB_SIZE;
- base_addr += TLB_4KB_SIZE;
+ phys_addr += TLB_4KB_SIZE;
}
- } else if (((base_addr & TLB_1KB_ALIGN_MASK) == base_addr) &&
+ } else if (((phys_addr & TLB_1KB_ALIGN_MASK) == phys_addr) &&
(mem_size >= TLB_1KB_SIZE)) {
/* Add a 1KB TLB entry */
- if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_1KB, tlb_i)) == 0) {
+ if ((rc = add_tlb_entry(phys_addr, virt_addr,
+ TLB_WORD0_SIZE_1KB, tlb_i)) == 0) {
mem_size -= TLB_1KB_SIZE;
- base_addr += TLB_1KB_SIZE;
+ phys_addr += TLB_1KB_SIZE;
}
} else {
printf("ERROR: no TLB size exists for the base address 0x%0X.\n",
- base_addr);
+ phys_addr);
}
if (rc != 0)
printf("ERROR: no TLB entries available for the base addr 0x%0X.\n",
- base_addr);
+ phys_addr);
}
return;
@@ -166,16 +177,16 @@ static void program_tlb_addr(unsigned long base_addr, unsigned long mem_size,
* Common usage for boards with SDRAM DIMM modules to dynamically
* configure the TLB's for the SDRAM
*/
-void program_tlb(u32 start, u32 size, u32 tlb_word2_i_value)
+void program_tlb(u32 phys_addr, u32 virt_addr, u32 size, u32 tlb_word2_i_value)
{
region_t region_array;
- region_array.base = start;
+ region_array.base = phys_addr;
region_array.size = size;
region_array.tlb_word2_i_value = tlb_word2_i_value; /* en-/disable cache */
/* Call the routine to add in the tlb entries for the memory regions */
- program_tlb_addr(region_array.base, region_array.size,
+ program_tlb_addr(region_array.base, virt_addr, region_array.size,
region_array.tlb_word2_i_value);
return;