From 8eb5ffa7390c313273f6ca9a75360f130123de32 Mon Sep 17 00:00:00 2001 From: Per Forlin Date: Fri, 26 Aug 2011 12:17:30 +0200 Subject: snowball: igloo copy port of armv7/u8500 and include/asm/arch-u8500 Signed-off-by: Per Forlin --- arch/arm/cpu/armv7/u8500/Makefile | 9 +- arch/arm/cpu/armv7/u8500/clock.c | 225 ++++++++++- arch/arm/cpu/armv7/u8500/cpu.c | 114 ++++++ arch/arm/cpu/armv7/u8500/prcmu-fw-defs_v1.h | 586 ++++++++++++++++++++++++++++ arch/arm/cpu/armv7/u8500/prcmu.c | 269 +++++++++++++ arch/arm/include/asm/arch-u8500/ab8500.h | 510 ++++++++++++++++++++++++ arch/arm/include/asm/arch-u8500/clock.h | 49 +-- arch/arm/include/asm/arch-u8500/common.h | 131 +++++++ arch/arm/include/asm/arch-u8500/cpu.h | 85 ++++ arch/arm/include/asm/arch-u8500/hardware.h | 19 +- arch/arm/include/asm/arch-u8500/prcmu.h | 57 +++ 11 files changed, 2003 insertions(+), 51 deletions(-) create mode 100644 arch/arm/cpu/armv7/u8500/cpu.c create mode 100644 arch/arm/cpu/armv7/u8500/prcmu-fw-defs_v1.h create mode 100644 arch/arm/cpu/armv7/u8500/prcmu.c create mode 100644 arch/arm/include/asm/arch-u8500/ab8500.h create mode 100644 arch/arm/include/asm/arch-u8500/common.h create mode 100644 arch/arm/include/asm/arch-u8500/cpu.h create mode 100644 arch/arm/include/asm/arch-u8500/prcmu.h diff --git a/arch/arm/cpu/armv7/u8500/Makefile b/arch/arm/cpu/armv7/u8500/Makefile index 270aa40c8..2ce16f764 100644 --- a/arch/arm/cpu/armv7/u8500/Makefile +++ b/arch/arm/cpu/armv7/u8500/Makefile @@ -25,7 +25,14 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(SOC).o -COBJS = timer.o clock.o + +COBJS += clock.o +COBJS += cpu.o +#COBJS += interrupts.o +COBJS += prcmu.o +COBJS += timer.o + +#COBJS = timer.o clock.o prcmu.o SOBJS = lowlevel.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) diff --git a/arch/arm/cpu/armv7/u8500/clock.c b/arch/arm/cpu/armv7/u8500/clock.c index 9e3b87394..004228110 100644 --- a/arch/arm/cpu/armv7/u8500/clock.c +++ b/arch/arm/cpu/armv7/u8500/clock.c @@ -22,9 +22,59 @@ #include #include +#include #include +#include -DECLARE_GLOBAL_DATA_PTR; +/* PLLs for clock management registers */ +enum { + GATED = 0, + PLLSOC0, /* pllsw = 001, ffs() = 1 */ + PLLSOC1, /* pllsw = 010, ffs() = 2 */ + PLLDDR, /* pllsw = 100, ffs() = 3 */ + PLLARM, +}; + +static struct pll_freq_regs { + int idx; /* index fror pll_name and pll_khz arrays */ + uint32_t addr; +} pll_freq_regs[] = { + {PLLSOC0, PRCM_PLLSOC0_FREQ_REG}, + {PLLSOC1, PRCM_PLLSOC1_FREQ_REG}, + {PLLDDR, PRCM_PLLDDR_FREQ_REG}, + {PLLARM, PRCM_PLLARM_FREQ_REG}, + {0, 0}, +}; + +static const char *pll_name[5] = {"GATED", "SOC0", "SOC1", "DDR", "ARM"}; +static uint32_t pll_khz[5]; /* use ffs(pllsw(reg)) as index for 0..3 */ + +static struct clk_mgt_regs { + uint32_t addr; + uint32_t val; + const char *descr; +} clk_mgt_regs[] = { + /* register content taken from bootrom settings */ + {PRCM_ARMCLKFIX_MGT_REG, 0x0120, "ARMCLKFIX"}, /* ena, SOC0/0, ??? */ + {PRCM_ACLK_MGT_REG, 0x0125, "ACLK"}, /* ena, SOC0/5, 160 MHz */ + {PRCM_SVAMMDSPCLK_MGT_REG, 0x1122, "SVA"}, /* ena, SOC0/2, 400 MHz */ + {PRCM_SIAMMDSPCLK_MGT_REG, 0x0022, "SIA"}, /* dis, SOC0/2, 400 MHz */ + {PRCM_SAAMMDSPCLK_MGT_REG, 0x0822, "SAA"}, /* dis, SOC0/4, 200 MHz */ + {PRCM_SGACLK_MGT_REG, 0x0024, "SGA"}, /* dis, SOC0/4, 200 MHz */ + {PRCM_UARTCLK_MGT_REG, 0x0300, "UART"}, /* ena, GATED, CLK38 */ + {PRCM_MSPCLK_MGT_REG, 0x0200, "MSP"}, /* dis, GATED, CLK38 */ + {PRCM_I2CCLK_MGT_REG, 0x0130, "I2C"}, /* ena, SOC0/16, 50 MHz */ + {PRCM_SDMMCCLK_MGT_REG, 0x0130, "SDMMC"}, /* ena, SOC0/16, 50 MHz */ + {PRCM_PER1CLK_MGT_REG, 0x126, "PER1"}, /* ena, SOC0/6, 133 MHz */ + {PRCM_PER2CLK_MGT_REG, 0x126, "PER2"}, /* ena, SOC0/6, 133 MHz */ + {PRCM_PER3CLK_MGT_REG, 0x126, "PER3"}, /* ena, SOC0/6, 133 MHz */ + {PRCM_PER5CLK_MGT_REG, 0x126, "PER5"}, /* ena, SOC0/6, 133 MHz */ + {PRCM_PER6CLK_MGT_REG, 0x126, "PER6"}, /* ena, SOC0/6, 133 MHz */ + {PRCM_PER7CLK_MGT_REG, 0x128, "PER7"}, /* ena, SOC0/8, 100 MHz */ + {PRCM_DMACLK_MGT_REG, 0x125, "DMA"}, /* ena, SOC0/5, 160 MHz */ + {PRCM_B2R2CLK_MGT_REG, 0x025, "B2R2"}, /* dis, SOC0/5, 160 MHz */ + {0, 0, NULL}, +}; struct clkrst { unsigned int pcken; @@ -44,7 +94,7 @@ static unsigned int clkrst_base[] = { }; /* Turn on peripheral clock at PRCC level */ -void u8500_clock_enable(int periph, int cluster, int kern) +static void clock_enable(int periph, int cluster, int kern) { struct clkrst *clkrst = (struct clkrst *) clkrst_base[periph - 1]; @@ -54,3 +104,174 @@ void u8500_clock_enable(int periph, int cluster, int kern) if (cluster != -1) writel(1 << cluster, &clkrst->pcken); } + +/* Legacy function to allow drivers to enable their clock */ +void u8500_clock_enable(int periph, int cluster, int kern) +{ + clock_enable(periph, cluster, kern); +} + +/* Main clock init function. Called from arch_cpu_init() */ +void db8500_clocks_init(void) +{ + /* + * Enable all clocks. This is u-boot, we can enable it all. There is no + * powersave in u-boot. + */ + + clock_enable(1, 9, -1); /* GPIO0 */ + + if (u8500_is_earlydrop()) + clock_enable(2, 12, -1); /* GPIO1 */ + else + clock_enable(2, 11, -1); /* GPIO1 */ + + clock_enable(3, 8, -1); /* GPIO2 */ + clock_enable(5, 1, -1); /* GPIO3 */ + + clock_enable(3, 6, 6); /* UART2 */ + + clock_enable(3, 3, 3); /* I2C0 */ + + clock_enable(1, 5, 5); /* SDI0 */ + clock_enable(2, 4, 2); /* SDI4 */ + + if (u8500_is_earlydrop()) + clock_enable(7, 2, -1); /* MTU0 */ + else if (cpu_is_u8500v1()) + clock_enable(6, 7, -1); /* MTU0 */ + else if (cpu_is_u8500v2()) + clock_enable(6, 6, -1); /* MTU0 */ + + if (!u8500_is_earlydrop()) + clock_enable(3, 4, 4); /* SDI2 */ + + /* + * Enabling clocks for all devices which are AMBA devices in the + * kernel. Otherwise they will not get probe()'d because the + * peripheral ID register will not be powered. + */ + + /* XXX: some of these differ between ED/V1 */ + + clock_enable(1, 1, 1); /* UART1 */ + clock_enable(1, 0, 0); /* UART0 */ + + clock_enable(3, 2, 2); /* SSP1 */ + clock_enable(3, 1, 1); /* SSP0 */ + + clock_enable(2, 8, -1); /* SPI0 */ + clock_enable(2, 5, 3); /* MSP2 */ +} + +/* + * get_pll_freq_khz - return PLL frequency in kHz + */ +static uint32_t get_pll_freq_khz(uint32_t inclk_khz, uint32_t freq_reg) +{ + uint32_t idf, ldf, odf, seldiv, phi; + + /* + * PLLOUTCLK = PHI = (INCLK*LDF)/(2*ODF*IDF) if SELDIV2=0 + * PLLOUTCLK = PHI = (INCLK*LDF)/(4*ODF*IDF) if SELDIV2=1 + * where: + * IDF=R(2:0) (when R=000, IDF=1d) + * LDF = 2*D(7:0) (D must be greater than or equal to 6) + * ODF = N(5:0) (when N=000000, 0DF=1d) + */ + + idf = (freq_reg & 0x70000) >> 16; + ldf = (freq_reg & 0xff) * 2; + odf = (freq_reg & 0x3f00) >> 8; + seldiv = (freq_reg & 0x01000000) >> 24; + phi = (inclk_khz * ldf) / (2 * odf * idf); + if (seldiv) + phi = phi/2; + + return phi; +} + +u32 db8500_clock_cpu_khz(void) +{ + u32 reg, phi; + + reg = readl(PRCM_ARM_CHGCLKREQ_REG); + if (reg & 1) + return 0; /* External clock */ + + reg = readl(PRCM_PLLARM_FREQ_REG); + phi = get_pll_freq_khz(38400, reg); + + return phi; +} + +int do_clkinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + uint32_t inclk_khz; + uint32_t reg, phi; + uint32_t clk_khz; + unsigned int clk_sel; + struct clk_mgt_regs *clks = clk_mgt_regs; + struct pll_freq_regs *plls = pll_freq_regs; + + /* Parameters are not used */ + (void) cmdtp; + (void) flag; + (void) argc; + (void) argv; + + /* + * Go through list of PLLs. + * Initialise pll out frequency array (pll_khz) and print frequency. + */ + inclk_khz = 38400; /* 38.4 MHz */ + while (plls->addr) { + reg = readl(plls->addr); + phi = get_pll_freq_khz(inclk_khz, reg); + pll_khz[plls->idx] = phi; + printf("%s PLL out frequency: %d.%d Mhz\n", + pll_name[plls->idx], phi/1000, phi % 1000); + plls++; + } + + /* check ARM clock source */ + reg = readl(PRCM_ARM_CHGCLKREQ_REG); + printf("A9 running on "); + if (reg & 1) + printf("external clock"); + else + printf("ARM PLL"); + printf("\n"); + + /* go through list of clk_mgt_reg */ + printf("\n%19s %9s %7s %9s enabled\n", + "name(addr)", "value", "PLL", "CLK[MHz]"); + while (clks->addr) { + reg = readl(clks->addr); + /* convert bit position into array index */ + clk_sel = ffs((reg >> 5) & 0x7); /* PLLSW[2:0] */ + printf("%9s(%08x): %08x", clks->descr, clks->addr, reg); + printf(", %6s", pll_name[clk_sel]); + if (reg & 0x200) + clk_khz = 38400; /* CLK38 is set */ + else if ((reg & 0x1f) == 0) + /* ARMCLKFIX_MGT is 0x120, e.g. div = 0 ! */ + clk_khz = 0; + else + clk_khz = pll_khz[clk_sel] / (reg & 0x1f); + printf(", %4d.%03d", clk_khz / 1000, clk_khz % 1000); + printf(", %s\n", (reg & 0x100) ? "ena" : "dis"); + clks++; + } + + return 0; +} + +#if 0 +U_BOOT_CMD( + clkinfo, 1, 1, do_clkinfo, + "print clock info", + "" +); +#endif + diff --git a/arch/arm/cpu/armv7/u8500/cpu.c b/arch/arm/cpu/armv7/u8500/cpu.c new file mode 100644 index 000000000..e05eaad9b --- /dev/null +++ b/arch/arm/cpu/armv7/u8500/cpu.c @@ -0,0 +1,114 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * Author: Joakim Axelsson + * for ST-Ericsson. + * + * Origin: Most part are moved here from old board code for u8500. + * + * License terms: GNU General Public License (GPL), version 2. + */ + +#include +#include +#include +#include +#include + +#ifdef CONFIG_ARCH_CPU_INIT + +/* Old table to init ED version of db8500. Should be removed */ +unsigned int addr_vall_arr[] = { +0x8011F000, 0x0000FFFF, /* Clocks for HSI TODO Enable reqd only */ +0x8011F008, 0x00001CFF, /* Clocks for HSI TODO Enable reqd only */ +0x8000F000, 0x00007FFF, /* Clocks for I2C TODO Enable reqd only */ +0x8000F008, 0x00007FFF, /* Clocks for I2C TODO Enable reqd only */ +0x80157020, 0x00000150, /* I2C 48MHz clock */ +0x8012F000, 0x00007FFF, /* Clocks for SD TODO Enable reqd only */ +0x8012F008, 0x00007FFF, /* Clocks for SD TODO Enable reqd only */ +0xA03DF000, 0x0000000D, /* Clock for MTU Timers */ +0x8011E00C, 0x00000000, /* GPIO ALT FUNC for EMMC */ +0x8011E004, 0x0000FFE0, /* GPIO ALT FUNC for EMMC */ +0x8011E020, 0x0000FFE0, /* GPIO ALT FUNC for EMMC */ +0x8011E024, 0x00000000, /* GPIO ALT FUNC for EMMC */ +0x8012E000, 0x20000000, /* GPIO ALT FUNC for UART */ +0x8012E00C, 0x00000000, /* GPIO ALT FUNC for SD */ +0x8012E004, 0x0FFC0000, /* GPIO ALT FUNC for SD */ +0x8012E020, 0x60000000, /* GPIO ALT FUNC for SD */ +0x8012E024, 0x60000000, /* GPIO ALT FUNC for SD */ +0x801571E4, 0x0000000C, /* PRCMU settings for B2R2, PRCM_APE_RESETN_SET_REG */ +0x80157024, 0x00000130, /* PRCMU settings for EMMC/SD */ +0xA03FF000, 0x00000003, /* USB */ +0xA03FF008, 0x00000001, /* USB */ +0xA03FE00C, 0x00000000, /* USB */ +0xA03FE020, 0x00000FFF, /* USB */ +0xA03FE024, 0x00000000 /* USB */ +}; + +static void init_regs(void) +{ + /* FIXME Remove magic register array settings for ED also */ + if (u8500_is_earlydrop()) { + unsigned i; + + for (i = 0; i < ARRAY_SIZE(addr_vall_arr)/2; i++) + *((volatile unsigned int *)(addr_vall_arr[2 * i])) + = addr_vall_arr[(2 * i) + 1]; + } else { + db8500_prcmu_init(); + db8500_clocks_init(); + } +} + +/* + * SOC specific cpu init + */ +int arch_cpu_init(void) +{ + if (u8500_is_earlydrop()) + /* MTU timer clock always enabled (not clocked) */ + writel(0x20000, PRCM_TCR); + + icache_enable(); + init_regs(); + + return 0; +} +#endif /* CONFIG_ARCH_CPU_INIT */ + +#ifdef CONFIG_DISPLAY_CPUINFO +int print_cpuinfo(void) +{ + char *version, *clock; + char clockbuf[24]; + uint32_t arm_khz; + + /* CPU version: Match most likly CPU first */ + if (cpu_is_u8500v2()) + version = "v2"; + else if (cpu_is_u8500v11()) + version = "v1.1"; + else if (cpu_is_u8500v1()) + version = "v1"; + else if (u8500_is_earlydrop()) + version = "ED"; + else + version = "Unknown"; + + /* CPU clock speed */ + arm_khz = db8500_clock_cpu_khz(); + if (arm_khz == 0) + clock = "External clock"; + else { + sprintf(clockbuf, "%u.%u Mhz", + arm_khz / 1000, arm_khz % 1000); + clock = clockbuf; + } + + printf("CPU:\tST-Ericsson db8500 %s (Dual ARM Cortex A9) %s\n", + version, clock); + + return 0; +} +#endif /* CONFIG_DISPLAY_CPUINFO */ + diff --git a/arch/arm/cpu/armv7/u8500/prcmu-fw-defs_v1.h b/arch/arm/cpu/armv7/u8500/prcmu-fw-defs_v1.h new file mode 100644 index 000000000..27b6a3449 --- /dev/null +++ b/arch/arm/cpu/armv7/u8500/prcmu-fw-defs_v1.h @@ -0,0 +1,586 @@ +/* + * Copyright (c) 2009 ST-Ericsson SA + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * Copied from the Linux version: + * Author: Kumar Sanghvi + */ + +#ifndef __MACH_PRCMU_FW_DEFS_V1_H +#define __MACH_PRCMU_FW_DEFS_V1_H + +/** + * enum state_t - ON/OFF state definition + * @OFF: State is ON + * @ON: State is OFF + * + */ +enum state_t { + OFF = 0x0, + ON = 0x1, +}; + +/** + * enum ret_state_t - general purpose On/Off/Retention states + * + */ +enum ret_state_t { + OFFST = 0, + ONST = 1, + RETST = 2 +}; + + +/** + * enum clk_arm_t - ARM Cortex A9 clock schemes + * @A9_OFF: + * @A9_BOOT: + * @A9_OPPT1: + * @A9_OPPT2: + * @A9_EXTCLK: + */ +enum clk_arm_t { + A9_OFF, + A9_BOOT, + A9_OPPT1, + A9_OPPT2, + A9_EXTCLK +}; + +/** + * enum clk_gen_t - GEN#0/GEN#1 clock schemes + * @GEN_OFF: + * @GEN_BOOT: + * @GEN_OPPT1: + */ +enum clk_gen_t { + GEN_OFF, + GEN_BOOT, + GEN_OPPT1, +}; + +/* some information between arm and xp70 */ + +/** + * enum romcode_write_t - Romcode message written by A9 AND read by XP70 + * @RDY_2_DS: Value set when ApDeepSleep state can be executed by XP70 + * @RDY_2_XP70_RST: Value set when 0x0F has been successfully polled by the + * romcode. The xp70 will go into self-reset + */ +enum romcode_write_t { + RDY_2_DS = 0x09, + RDY_2_XP70_RST = 0x10 +}; + +/** + * enum romcode_read_t - Romcode message written by XP70 and read by A9 + * @INIT: Init value when romcode field is not used + * @FS_2_DS: Value set when power state is going from ApExecute to + * ApDeepSleep + * @END_DS: Value set when ApDeepSleep power state is reached coming from + * ApExecute state + * @DS_TO_FS: Value set when power state is going from ApDeepSleep to + * ApExecute + * @END_FS: Value set when ApExecute power state is reached coming from + * ApDeepSleep state + * @SWR: Value set when power state is going to ApReset + * @END_SWR: Value set when the xp70 finished executing ApReset actions and + * waits for romcode acknowledgment to go to self-reset + */ +enum romcode_read_t { + INIT = 0x00, + FS_2_DS = 0x0A, + END_DS = 0x0B, + DS_TO_FS = 0x0C, + END_FS = 0x0D, + SWR = 0x0E, + END_SWR = 0x0F +}; + + +/** + * enum pingpong_t + * @PING: value is 0 + * @PONG: value is 1 + * + * implementation issue: the values are chosen the way that + * we can change from ping to pong (resp. pong to ping) by + * simply using the 'not' operator in C, e.g. toggling operation: + * t_PingPong p = ping; p = ~p; + */ +enum pingpong_t { + PRCMU_PING = 0x00, + PRCMU_PONG = 0xFF +}; + +/** + * enum wkup_reason_fdst_t + * @EVTWR: event has been read by ARM + * @EVTST: event has been sent by PRCMU FW + * @EVTRD: event has been written by PRCMU FW + */ +enum wkup_reason_fdst_t { + /* WRF has been written but neither sent nor read by the arm */ + EVTWR = 1, + /* WRF has been written and sent, but not yet read by the arm */ + EVTST = 2, + /* WRF has been written, sent and read by the arm */ + EVTRD = 0 +}; /* Wake-up reason Field State */ + + + +/** + * enum ap_pwrst_t - current power states defined in PRCMU firmware + * @NO_PWRST: Current power state init + * @AP_BOOT: Current power state is apBoot + * @AP_EXECUTE: Current power state is apExecute + * @AP_DEEP_SLEEP: Current power state is apDeepSleep + * @AP_SLEEP: Current power state is apSleep + * @AP_IDLE: Current power state is apIdle + * @AP_RESET: Current power state is apReset + */ +enum ap_pwrst_t { + NO_PWRST = 0x00, + AP_BOOT = 0x01, + AP_EXECUTE = 0x02, + AP_DEEP_SLEEP = 0x03, + AP_SLEEP = 0x04, + AP_IDLE = 0x05, + AP_RESET = 0x06 +}; + +/** + * enum ap_pwrst_trans_t - Transition states defined in PRCMU firmware + * @NO_TRANSITION: No power state transition + * @APEXECUTE_TO_APSLEEP: Power state transition from ApExecute to ApSleep + * @APIDLE_TO_APSLEEP: Power state transition from ApIdle to ApSleep + * @APBOOT_TO_APEXECUTE: Power state transition from ApBoot to ApExecute + * @APEXECUTE_TO_APDEEPSLEEP: Power state transition from ApExecute to + * ApDeepSleep + * @APEXECUTE_TO_APIDLE: Power state transition from ApExecute to ApIdle + */ +enum ap_pwrst_trans_t { + NO_TRANSITION = 0x00, + APEXECUTE_TO_APSLEEP = 0x01, + APIDLE_TO_APSLEEP = 0x02, + APBOOT_TO_APEXECUTE = 0x03, + APEXECUTE_TO_APDEEPSLEEP = 0x04, + APEXECUTE_TO_APIDLE = 0x05 +}; + +/** + * enum ddr_pwrst_t - DDR power states definition + * @DDR_PWR_STATE_UNCHANGED: SDRAM and DDR controller state is unchanged + * @DDR_PWR_STATE_ON: + * @DDR_PWR_STATE_OFFLOWLAT: + * @DDR_PWR_STATE_OFFHIGHLAT: + */ +enum ddr_pwrst_t { + DDR_PWR_STATE_UNCHANGED = 0x00, + DDR_PWR_STATE_ON = 0x01, + DDR_PWR_STATE_OFFLOWLAT = 0x02, + DDR_PWR_STATE_OFFHIGHLAT = 0x03 +}; + +/** + * enum arm_opp_t - ARM OPP states definition + * @ARM_NO_CHANGE: The ARM operating point is unchanged + * @ARM_100_OPP: The new ARM operating point is arm100opp + * @ARM_50_OPP: The new ARM operating point is arm100opp + * @ARM_EXTCLK: The new ARM operating point is armExtClk + */ +enum arm_opp_t { + ARM_NO_CHANGE = 0x00, + ARM_100_OPP = 0x02, + ARM_50_OPP = 0x03, + ARM_EXTCLK = 0x07 +}; + +/** + * enum ape_opp_t - APE OPP states definition + * @APE_NO_CHANGE: The APE operating point is unchanged + * @APE_100_OPP: The new APE operating point is ape100opp + */ +enum ape_opp_t { + APE_NO_CHANGE = 0x00, + APE_100_OPP = 0x02, + APE_50_OPP = 0x03 +}; + +/** + * enum hw_accst_t - State definition for hardware accelerator + * @HW_NO_CHANGE: The hardware accelerator state must remain unchanged + * @HW_OFF: The hardware accelerator must be switched off + * @HW_OFF_RAMRET: The hardware accelerator must be switched off with its + * internal RAM in retention + * @HW_ON: The hwa hadware accelerator hwa must be switched on + */ +enum hw_accst_t { + HW_NO_CHANGE = 0x00, + HW_OFF = 0x01, + HW_OFF_RAMRET = 0x02, + HW_ON = 0x03 +}; + +/** + * enum mbox_2_arm_stat_t - Status messages definition for mbox_arm + * @BOOT_TO_EXECUTEOK: The apBoot to apExecute state transition has been + * completed + * @DEEPSLEEPOK: The apExecute to apDeepSleep state transition has been + * completed + * @SLEEPOK: The apExecute to apSleep state transition has been completed + * @IDLEOK: The apExecute to apIdle state transition has been completed + * @SOFTRESETOK: The A9 watchdog/ SoftReset state has been completed + * @SOFTRESETGO : The A9 watchdog/SoftReset state is on going + * @BOOT_TO_EXECUTE: The apBoot to apExecute state transition is on going + * @EXECUTE_TO_DEEPSLEEP: The apExecute to apDeepSleep state transition is on + * going + * @DEEPSLEEP_TO_EXECUTE: The apDeepSleep to apExecute state transition is on + * going + * @DEEPSLEEP_TO_EXECUTEOK: The apDeepSleep to apExecute state transition has + * been completed + * @EXECUTE_TO_SLEEP: The apExecute to apSleep state transition is on going + * @SLEEP_TO_EXECUTE: The apSleep to apExecute state transition is on going + * @SLEEP_TO_EXECUTEOK: The apSleep to apExecute state transition has been + * completed + * @EXECUTE_TO_IDLE: The apExecute to apIdle state transition is on going + * @IDLE_TO_EXECUTE: The apIdle to apExecute state transition is on going + * @IDLE_TO_EXECUTEOK: The apIdle to apExecute state transition has been + * completed + * @INIT_STATUS: Status init + */ +enum ap_pwrsttr_status_t { + BOOT_TO_EXECUTEOK = 0xFF, + DEEPSLEEPOK = 0xFE, + SLEEPOK = 0xFD, + IDLEOK = 0xFC, + SOFTRESETOK = 0xFB, + SOFTRESETGO = 0xFA, + BOOT_TO_EXECUTE = 0xF9, + EXECUTE_TO_DEEPSLEEP = 0xF8, + DEEPSLEEP_TO_EXECUTE = 0xF7, + DEEPSLEEP_TO_EXECUTEOK = 0xF6, + EXECUTE_TO_SLEEP = 0xF5, + SLEEP_TO_EXECUTE = 0xF4, + SLEEP_TO_EXECUTEOK = 0xF3, + EXECUTE_TO_IDLE = 0xF2, + IDLE_TO_EXECUTE = 0xF1, + IDLE_TO_EXECUTEOK = 0xF0, + RDYTODS_RETURNTOEXE = 0xEF, + NORDYTODS_RETURNTOEXE = 0xEE, + EXETOSLEEP_RETURNTOEXE = 0xED, + EXETOIDLE_RETURNTOEXE = 0xEC, + INIT_STATUS = 0xEB, + + /*error messages */ + INITERROR = 0x00, + PLLARMLOCKP_ER = 0x01, + PLLDDRLOCKP_ER = 0x02, + PLLSOCLOCKP_ER = 0x03, + PLLSOCK1LOCKP_ER = 0x04, + ARMWFI_ER = 0x05, + SYSCLKOK_ER = 0x06, + I2C_NACK_DATA_ER = 0x07, + BOOT_ER = 0x08, + I2C_STATUS_ALWAYS_1 = 0x0A, + I2C_NACK_REG_ADDR_ER = 0x0B, + I2C_NACK_DATA0123_ER = 0x1B, + I2C_NACK_ADDR_ER = 0x1F, + CURAPPWRSTISNOT_BOOT = 0x20, + CURAPPWRSTISNOT_EXECUTE = 0x21, + CURAPPWRSTISNOT_SLEEPMODE = 0x22, + CURAPPWRSTISNOT_CORRECTFORIT10 = 0x23, + FIFO4500WUISNOT_WUPEVENT = 0x24, + PLL32KLOCKP_ER = 0x29, + DDRDEEPSLEEPOK_ER = 0x2A, + ROMCODEREADY_ER = 0x50, + WUPBEFOREDS = 0x51, + DDRCONFIG_ER = 0x52, + WUPBEFORESLEEP = 0x53, + WUPBEFOREIDLE = 0x54 +}; /* earlier called as mbox_2_arm_stat_t */ + + +/** + * enum dvfs_stat_t - DVFS status messages definition + * @DVFS_GO: A state transition DVFS is on going + * @DVFS_ARM100OPPOK: The state transition DVFS has been completed for 100OPP + * @DVFS_ARM50OPPOK: The state transition DVFS has been completed for 50OPP + * @DVFS_ARMEXTCLKOK: The state transition DVFS has been completed for EXTCLK + * @DVFS_NOCHGTCLKOK: The state transition DVFS has been completed for + * NOCHGCLK + * @DVFS_INITSTATUS: Value init + */ +enum dvfs_stat_t { + DVFS_GO = 0xFF, + DVFS_ARM100OPPOK = 0xFE, + DVFS_ARM50OPPOK = 0xFD, + DVFS_ARMEXTCLKOK = 0xFC, + DVFS_NOCHGTCLKOK = 0xFB, + DVFS_INITSTATUS = 0x00 +}; + +/** + * enum mbox_2_arm_hwacc_pwr_stat_t - Hardware Accelarator status message + * @HWACC_PWRST_GO: A state transition on hardware accelerator is on going + * @HWACC_PWRST_OK: The state transition on hardware accelerator has been + * completed + * @HWACC_PWRSTATUS_INIT: Value init + */ +enum mbox_2_arm_hwacc_pwr_stat_t { + HWACC_PWRST_GO = 0xFF, + HWACC_PWRST_OK = 0xFE, + HWACC_PWRSTATUS_INIT = 0x00 +}; + +/** + * enum sva_mmdsp_stat_t - SVA MMDSP status messages + * @SVA_MMDSP_GO: SVAMMDSP interrupt has happened + * @SVA_MMDSP_INIT: Status init + */ +enum sva_mmdsp_stat_t { + SVA_MMDSP_GO = 0xFF, + SVA_MMDSP_INIT = 0x00 +}; + +/** + * enum sia_mmdsp_stat_t - SIA MMDSP status messages + * @SIA_MMDSP_GO: SIAMMDSP interrupt has happened + * @SIA_MMDSP_INIT: Status init + */ +enum sia_mmdsp_stat_t { + SIA_MMDSP_GO = 0xFF, + SIA_MMDSP_INIT = 0x00 +}; + +/** + * enum intr_wakeup_t - Configure STW4500 FIFO interrupt as wake-up + * @NTR_NOT_AS_WAKEUP: The 4500 fifo interrupt is not configured as a + * wake-up event + * @INTR_AS_WAKEUP: The 4500 fifo interrupt is configured as a wake-up event + */ +enum intr_wakeup_t { + INTR_NOT_AS_WAKEUP = 0x0, + INTR_AS_WAKEUP = 0x1 +}; + +/** + * enum mbox_to_arm_err_t - Error messages definition + * @INIT_ERR: Init value + * @PLLARMLOCKP_ERR: PLLARM has not been correctly locked in given time + * @PLLDDRLOCKP_ERR: PLLDDR has not been correctly locked in the given time + * @PLLSOC0LOCKP_ERR: PLLSOC0 has not been correctly locked in the given time + * @PLLSOC1LOCKP_ERR: PLLSOC1 has not been correctly locked in the given time + * @ARMWFI_ERR: The ARM WFI has not been correctly executed in the given time + * @SYSCLKOK_ERR: The SYSCLK is not available in the given time + * @BOOT_ERR: Romcode has not validated the XP70 self reset in the given time + * @ROMCODESAVECONTEXT: The Romcode didn.t correctly save it secure context + * @VARMHIGHSPEEDVALTO_ERR: The ARM high speed supply value transfered + * through I2C has not been correctly executed in the given time + * @VARMHIGHSPEEDACCESS_ERR: The command value of VarmHighSpeedVal transfered + * through I2C has not been correctly executed in the given time + * @VARMLOWSPEEDVALTO_ERR:The ARM low speed supply value transfered through + * I2C has not been correctly executed in the given time + * @VARMLOWSPEEDACCESS_ERR: The command value of VarmLowSpeedVal transfered + * through I2C has not been correctly executed in the given time + * @VARMRETENTIONVALTO_ERR: The ARM retention supply value transfered through + * I2C has not been correctly executed in the given time + * @VARMRETENTIONACCESS_ERR: The command value of VarmRetentionVal transfered + * through I2C has not been correctly executed in the given time + * @VAPEHIGHSPEEDVALTO_ERR: The APE highspeed supply value transfered through + * I2C has not been correctly executed in the given time + * @VSAFEHPVALTO_ERR: The SAFE high power supply value transfered through I2C + * has not been correctly executed in the given time + * @VMODSEL1VALTO_ERR: The MODEM sel1 supply value transfered through I2C has + * not been correctly executed in the given time + * @VMODSEL2VALTO_ERR: The MODEM sel2 supply value transfered through I2C has + * not been correctly executed in the given time + * @VARMOFFACCESS_ERR: The command value of Varm ON/OFF transfered through + * I2C has not been correctly executed in the given time + * @VAPEOFFACCESS_ERR: The command value of Vape ON/OFF transfered through + * I2C has not been correctly executed in the given time + * @VARMRETACCES_ERR: The command value of Varm retention ON/OFF transfered + * through I2C has not been correctly executed in the given time + * @CURAPPWRSTISNOTBOOT:Generated when Arm want to do power state transition + * ApBoot to ApExecute but the power current state is not Apboot + * @CURAPPWRSTISNOTEXECUTE: Generated when Arm want to do power state + * transition from ApExecute to others power state but the + * power current state is not ApExecute + * @CURAPPWRSTISNOTSLEEPMODE: Generated when wake up events are transmitted + * but the power current state is not ApDeepSleep/ApSleep/ApIdle + * @CURAPPWRSTISNOTCORRECTDBG: Generated when wake up events are transmitted + * but the power current state is not correct + * @ARMREGU1VALTO_ERR:The ArmRegu1 value transferred through I2C has not + * been correctly executed in the given time + * @ARMREGU2VALTO_ERR: The ArmRegu2 value transferred through I2C has not + * been correctly executed in the given time + * @VAPEREGUVALTO_ERR: The VApeRegu value transfered through I2C has not + * been correctly executed in the given time + * @VSMPS3REGUVALTO_ERR: The VSmps3Regu value transfered through I2C has not + * been correctly executed in the given time + * @VMODREGUVALTO_ERR: The VModemRegu value transfered through I2C has not + * been correctly executed in the given time + */ +enum mbox_to_arm_err_t { + INIT_ERR = 0x00, + PLLARMLOCKP_ERR = 0x01, + PLLDDRLOCKP_ERR = 0x02, + PLLSOC0LOCKP_ERR = 0x03, + PLLSOC1LOCKP_ERR = 0x04, + ARMWFI_ERR = 0x05, + SYSCLKOK_ERR = 0x06, + BOOT_ERR = 0x07, + ROMCODESAVECONTEXT = 0x08, + VARMHIGHSPEEDVALTO_ERR = 0x10, + VARMHIGHSPEEDACCESS_ERR = 0x11, + VARMLOWSPEEDVALTO_ERR = 0x12, + VARMLOWSPEEDACCESS_ERR = 0x13, + VARMRETENTIONVALTO_ERR = 0x14, + VARMRETENTIONACCESS_ERR = 0x15, + VAPEHIGHSPEEDVALTO_ERR = 0x16, + VSAFEHPVALTO_ERR = 0x17, + VMODSEL1VALTO_ERR = 0x18, + VMODSEL2VALTO_ERR = 0x19, + VARMOFFACCESS_ERR = 0x1A, + VAPEOFFACCESS_ERR = 0x1B, + VARMRETACCES_ERR = 0x1C, + CURAPPWRSTISNOTBOOT = 0x20, + CURAPPWRSTISNOTEXECUTE = 0x21, + CURAPPWRSTISNOTSLEEPMODE = 0x22, + CURAPPWRSTISNOTCORRECTDBG = 0x23, + ARMREGU1VALTO_ERR = 0x24, + ARMREGU2VALTO_ERR = 0x25, + VAPEREGUVALTO_ERR = 0x26, + VSMPS3REGUVALTO_ERR = 0x27, + VMODREGUVALTO_ERR = 0x28 +}; + +enum hw_acc_t { + SVAMMDSP = 0, + SVAPIPE = 1, + SIAMMDSP = 2, + SIAPIPE = 3, + SGA = 4, + B2R2MCDE = 5, + ESRAM1 = 6, + ESRAM2 = 7, + ESRAM3 = 8, + ESRAM4 = 9 +}; + +enum reqmb0_header_t { + PWRSTTRH = 0, + WKUPCFG_EXEH = 1, + WKUP_EXEH = 2, + RDWKUPACKH = 3, + WKUPCFG_SLEEPH = 4, + WKUP_SLEEPH = 5, +}; + +enum cs_pwrmgt_t { + PWRDNCS0 = 0, + WKUPCS0 = 1, + PWRDNCS1 = 2, + WKUPCS1 = 3 +}; + +enum reqmb2_header_t { + DPS_H = 0, + HW_ACCT_AUTO_PWR_H = 1, +}; + + +/* Defs related to autonomous power management */ + +/** + * enum sia_sva_pwr_policy_t - Power policy + * @NO_CHGT: No change + * @DSPOFF_HWPOFF: + * @DSPOFFRAMRET_HWPOFF: + * @DSPCLKOFF_HWPOFF: + * @DSPCLKOFF_HWPCLKOFF: + * + */ +enum sia_sva_pwr_policy_t { + NO_CHGT = 0x0, + DSPOFF_HWPOFF = 0x1, + DSPOFFRAMRET_HWPOFF = 0x2, + DSPCLKOFF_HWPOFF = 0x3, + DSPCLKOFF_HWPCLKOFF = 0x4, +}; + +/** + * enum auto_enable_t - Auto Power enable + * @AUTO_OFF: + * @AUTO_ON: + * + */ +enum auto_enable_t { + AUTO_OFF = 0x0, + AUTO_ON = 0x1, +}; + + +/** + * enum reqmb4_header_t -Header type for mail box 4 + * @MEMSTH: The ARM can set what are the expected memory states depending on + * the AP power states. + * @PARTIALREFRESHH: ARM has to update MR16 & MR17 of SDRAM register, for + * partial-refresh of SDRAM, via this mailbox + * @AUTOREFRESHH: Enable to change cycle count before enabling automatic + * DDR self-refresh + * @CSPWRDNH: Enables to lock/unlock one of SDRAM memory cut in self-refresh + * In V2,this service will enable to put CS in pwrdn + * @SYSCLKH: Enables to switch SYSCLK ON/OFF on the AP side + * @USBWKUPH: Used to enable USB wakeup event of PRCMU + */ +enum reqmb4_header_t { + MEM_ST_H = 0, + PARTIAL_S_REFRESH_H = 1, + AUTO_REFRESH_H = 2, + CS_PWRDN_H = 3, + SYSCLK_H = 5, + AUTO_PWR_H = 6, + USB_WKUP_H = 7 +}; + +enum ack_mb4_status_t { + ACKMB4_INIT = 0, + SYSCLKON_OK = 1, + DDRON_OK = 2 +}; + +enum I2C_op_t { + I2CWRITE = 0, + I2CREAD = 1 +}; + +enum ack_mb5_status_t { + ACKMB5_INIT = 0x00, + I2C_WR_OK = 0x01, + I2C_RD_OK = 0x02, + SYSCLK_OK = 0x03, + I2C_TIMEOUT = 0x11, + SYSCLK_ER = 0x12, + /*Error Status resent by PRCM_HWI2C_SR*/ + I2CWR_NACK_DATA_ER = 0x07, + I2CWR_NACK_REG_ADDR_ER = 0x0B, + I2CRDWR_NACK_DATA0123_ER = 0x1B, + I2CWR_NACK_ADDR_ER = 0x1F, + I2CRD_NACK_ADDR_INIT_ER = 0x0F, + I2CRD_NACK_REG_ADDR_INIT_ER = 0x13, + I2CRD_NACK_ADDR_ER = 0x17 +}; + +enum ack_mb7_status_t { + MOD_SW_RESET_REQ = 0x03, + CA_SLEEP_REQ = 0x02, + HOST_PORT_ACK = 0x01, + ACKMB7_INIT = 0x00 +}; + +#endif /* __MACH_PRCMU_FW_DEFS_V1_H */ diff --git a/arch/arm/cpu/armv7/u8500/prcmu.c b/arch/arm/cpu/armv7/u8500/prcmu.c new file mode 100644 index 000000000..d4337f739 --- /dev/null +++ b/arch/arm/cpu/armv7/u8500/prcmu.c @@ -0,0 +1,269 @@ +/* + * Copyright (C) 2009 ST-Ericsson SA + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * Adapted from the Linux version: + * Author: Kumar Sanghvi + */ + +/* + * NOTE: This currently does not support the I2C workaround access method. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include "prcmu-fw-defs_v1.h" + +#ifndef DEBUG +#define DEBUG 0 +#endif + +#define dbg_printk(format, arg...) \ + if (DEBUG) \ + printf("prcmu: " format, ##arg) \ + +#define PRCMU_BASE U8500_PRCMU_BASE + +#define PRCM_MBOX_CPU_VAL (PRCMU_BASE + 0x0fc) +#define PRCM_MBOX_CPU_SET (PRCMU_BASE + 0x100) +/* register for Ack mailbox interrupts */ +#define PRCM_ARM_IT1_CLEAR (PRCMU_BASE + 0x48C) +#define PRCM_ARM_IT1_VAL (PRCMU_BASE + 0x494) + +#define PRCM_XP70_CUR_PWR_STATE (tcdm_base + 0xFFC) + +#define PRCM_REQ_MB5 (tcdm_base + 0xE44) +#define PRCM_ACK_MB5 (tcdm_base + 0xDF4) + +/* Mailbox 5 Requests */ +#define PRCM_REQ_MB5_I2COPTYPE_REG (PRCM_REQ_MB5 + 0x0) +#define PRCM_REQ_MB5_BIT_FIELDS (PRCM_REQ_MB5 + 0x1) +#define PRCM_REQ_MB5_I2CSLAVE (PRCM_REQ_MB5 + 0x2) +#define PRCM_REQ_MB5_I2CVAL (PRCM_REQ_MB5 + 0x3) + +/* Mailbox 5 ACKs */ +#define PRCM_ACK_MB5_STATUS (PRCM_ACK_MB5 + 0x1) +#define PRCM_ACK_MB5_SLAVE (PRCM_ACK_MB5 + 0x2) +#define PRCM_ACK_MB5_VAL (PRCM_ACK_MB5 + 0x3) + +#define PRCMU_I2C_WRITE(slave) \ + (((slave) << 1) | I2CWRITE | (cpu_is_u8500v2() ? (1 << 6) : 0)) + +#define PRCMU_I2C_READ(slave) \ + (((slave) << 1) | I2CREAD | (cpu_is_u8500v2() ? (1 << 6) : 0)) + +#define I2C_MBOX_BIT (1 << 5) + +static void *tcdm_base; + +static int prcmu_is_ready(void) +{ + int ready; + + if (!tcdm_base) { + if (cpu_is_u8500v1()) + tcdm_base = (void *) U8500_PRCMU_TCDM_BASE_V1; + else if (cpu_is_u8500v2()) + tcdm_base = (void *) U8500_PRCMU_TCDM_BASE; + else { + printf("PRCMU: Unsupported chip version\n"); + return 0; + } + } + + ready = readb(PRCM_XP70_CUR_PWR_STATE) == AP_EXECUTE; + if (!ready) + printf("PRCMU firmware not ready\n"); + + return ready; +} + +static int wait_for_i2c_mbx_rdy(void) +{ + int timeout = 10000; + + if (readl(PRCM_ARM_IT1_VAL) & I2C_MBOX_BIT) { + printf("prcmu: warning i2c mailbox was not acked\n"); + /* clear mailbox 5 ack irq */ + writel(I2C_MBOX_BIT, PRCM_ARM_IT1_CLEAR); + } + + /* check any already on-going transaction */ + while ((readl(PRCM_MBOX_CPU_VAL) & I2C_MBOX_BIT) && timeout--) + ; + + if (timeout == 0) + return -1; + + return 0; +} + +static int wait_for_i2c_req_done(void) +{ + int timeout = 10000; + + /* Set an interrupt to XP70 */ + writel(I2C_MBOX_BIT, PRCM_MBOX_CPU_SET); + + /* wait for mailbox 5 (i2c) ack */ + while (!(readl(PRCM_ARM_IT1_VAL) & I2C_MBOX_BIT) && timeout--) + ; + + if (timeout == 0) + return -1; + + return 0; +} + +/** + * prcmu_i2c_read - PRCMU - 4500 communication using PRCMU I2C + * @reg: - db8500 register bank to be accessed + * @slave: - db8500 register to be accessed + * Returns: ACK_MB5 value containing the status + */ +int prcmu_i2c_read(u8 reg, u16 slave) +{ + uint8_t i2c_status; + uint8_t i2c_val; + int ret; + + if (!prcmu_is_ready()) + return -1; + + dbg_printk("\nprcmu_4500_i2c_read:bank=%x;reg=%x;\n", + reg, slave); + + ret = wait_for_i2c_mbx_rdy(); + if (ret) { + printf("prcmu_i2c_read: mailbox became not ready\n"); + return ret; + } + + /* prepare the data for mailbox 5 */ + writeb(PRCMU_I2C_READ(reg), PRCM_REQ_MB5_I2COPTYPE_REG); + writeb((1 << 3) | 0x0, PRCM_REQ_MB5_BIT_FIELDS); + writeb(slave, PRCM_REQ_MB5_I2CSLAVE); + writeb(0, PRCM_REQ_MB5_I2CVAL); + + ret = wait_for_i2c_req_done(); + if (ret) { + printf("prcmu_i2c_read: mailbox request timed out\n"); + return ret; + } + + /* retrieve values */ + dbg_printk("ack-mb5:transfer status = %x\n", + readb(PRCM_ACK_MB5_STATUS)); + dbg_printk("ack-mb5:reg bank = %x\n", readb(PRCM_ACK_MB5) >> 1); + dbg_printk("ack-mb5:slave_add = %x\n", + readb(PRCM_ACK_MB5_SLAVE)); + dbg_printk("ack-mb5:reg_val = %d\n", readb(PRCM_ACK_MB5_VAL)); + + i2c_status = readb(PRCM_ACK_MB5_STATUS); + i2c_val = readb(PRCM_ACK_MB5_VAL); + /* clear mailbox 5 ack irq */ + writel(I2C_MBOX_BIT, PRCM_ARM_IT1_CLEAR); + + if (i2c_status == I2C_RD_OK) + return i2c_val; + + printf("prcmu_i2c_read:read return status= %d\n", i2c_status); + return -1; +} + +/** + * prcmu_i2c_write - PRCMU-db8500 communication using PRCMU I2C + * @reg: - db8500 register bank to be accessed + * @slave: - db800 register to be written to + * @reg_data: - the data to write + * Returns: ACK_MB5 value containing the status + */ +int prcmu_i2c_write(u8 reg, u16 slave, u8 reg_data) +{ + uint8_t i2c_status; + int ret; + + if (!prcmu_is_ready()) + return -1; + + dbg_printk("\nprcmu_4500_i2c_write:bank=%x;reg=%x;\n", + reg, slave); + + ret = wait_for_i2c_mbx_rdy(); + if (ret) { + printf("prcmu_i2c_write: mailbox became not ready\n"); + return ret; + } + + /* prepare the data for mailbox 5 */ + writeb(PRCMU_I2C_WRITE(reg), PRCM_REQ_MB5_I2COPTYPE_REG); + writeb((1 << 3) | 0x0, PRCM_REQ_MB5_BIT_FIELDS); + writeb(slave, PRCM_REQ_MB5_I2CSLAVE); + writeb(reg_data, PRCM_REQ_MB5_I2CVAL); + + ret = wait_for_i2c_req_done(); + if (ret) { + printf("prcmu_i2c_write: mailbox request timed out\n"); + return ret; + } + + /* retrieve values */ + dbg_printk("ack-mb5:transfer status = %x\n", + readb(PRCM_ACK_MB5_STATUS)); + dbg_printk("ack-mb5:reg bank = %x\n", readb(PRCM_ACK_MB5) >> 1); + dbg_printk("ack-mb5:slave_add = %x\n", + readb(PRCM_ACK_MB5_SLAVE)); + dbg_printk("ack-mb5:reg_val = %d\n", readb(PRCM_ACK_MB5_VAL)); + + i2c_status = readb(PRCM_ACK_MB5_STATUS); + dbg_printk("\ni2c_status = %x\n", i2c_status); + /* clear mailbox 5 ack irq */ + writel(I2C_MBOX_BIT, PRCM_ARM_IT1_CLEAR); + + if (i2c_status == I2C_WR_OK) + return 0; + + printf("prcmu_i2c_write: i2c_status : 0x%x\n", i2c_status); + return -1; +} + +static void prcmu_enable(u32 *reg) +{ + writel(readl(reg) | (1 << 8), reg); +} + +void db8500_prcmu_init(void) +{ + /* Enable timers */ + writel(1 << 17, PRCM_TCR); + + prcmu_enable((u32 *)PRCM_PER1CLK_MGT_REG); + prcmu_enable((u32 *)PRCM_PER2CLK_MGT_REG); + prcmu_enable((u32 *)PRCM_PER3CLK_MGT_REG); + /* PER4CLK does not exist */ + prcmu_enable((u32 *)PRCM_PER5CLK_MGT_REG); + prcmu_enable((u32 *)PRCM_PER6CLK_MGT_REG); + /* Only exists in ED but is always ok to write to */ + prcmu_enable((u32 *)PRCM_PER7CLK_MGT_REG); + + prcmu_enable((u32 *)PRCM_UARTCLK_MGT_REG); + prcmu_enable((u32 *)PRCM_I2CCLK_MGT_REG); + + prcmu_enable((u32 *)PRCM_SDMMCCLK_MGT_REG); + + /* Clean up the mailbox interrupts after pre-u-boot code. */ + writel(I2C_MBOX_BIT, PRCM_ARM_IT1_CLEAR); +} diff --git a/arch/arm/include/asm/arch-u8500/ab8500.h b/arch/arm/include/asm/arch-u8500/ab8500.h new file mode 100644 index 000000000..5db047979 --- /dev/null +++ b/arch/arm/include/asm/arch-u8500/ab8500.h @@ -0,0 +1,510 @@ +/* + * Copyright (C) ST-Ericsson 2009. + * + * Author: Srinidhi Kasagar + * Licensed under GPLv2. + */ +#ifndef _AB8500_H +#define _AB8500_H + +/* + * AB8500 bank addresses + */ +#define AB8500_SYS_CTRL1_BLOCK 0x1 +#define AB8500_SYS_CTRL2_BLOCK 0x2 +#define AB8500_REGU_CTRL1 0x3 +#define AB8500_REGU_CTRL2 0x4 +#define AB8500_USB 0x5 +#define AB8500_TVOUT 0x6 +#define AB8500_DBI 0x7 +#define AB8500_ECI_AV_ACC 0x8 +#define AB8500_RESERVED 0x9 +#define STw4550_GPADC 0xA +#define AB8500_GPADC 0xA +#define AB8500_CHARGER 0xB +#define AB8500_GAS_GAUGE 0xC +#define AB8500_AUDIO 0xD +#define AB8500_INTERRUPT 0xE +#define AB8500_RTC 0xF +#define AB8500_MISC 0x10 +#define AB8500_DEBUG 0x12 +#define AB8500_PROD_TEST 0x13 +#define AB8500_OTP_EMUL 0x15 + +/* + * System control 1 register offsets. + * Bank = 0x01 + */ +#define AB8500_TURNON_STAT_REG 0x0100 +#define AB8500_RESET_STAT_REG 0x0101 +#define AB8500_PONKEY1_PRESS_STAT_REG 0x0102 + +#define AB8500_FSM_STAT1_REG 0x0140 +#define AB8500_FSM_STAT2_REG 0x0141 +#define AB8500_SYSCLK_REQ_STAT_REG 0x0142 +#define AB8500_USB_STAT1_REG 0x0143 +#define AB8500_USB_STAT2_REG 0x0144 +#define AB8500_STATUS_SPARE1_REG 0x0145 +#define AB8500_STATUS_SPARE2_REG 0x0146 + +#define AB8500_CTRL1_REG 0x0180 +#define AB8500_CTRL2_REG 0x0181 + +/* + * System control 2 register offsets. + * bank = 0x02 + */ +#define AB8500_CTRL3_REG 0x0200 +#define AB8500_CTRL3_RST_DENC_MASK 0x4 +#define AB8500_CTRL3_RST_DENC_SHIFT 2 +#define AB8500_CTRL3_RST_AUD_MASK 0x2 +#define AB8500_CTRL3_RST_AUD_SHIFT 1 +#define AB8500_MAIN_WDOG_CTRL_REG 0x0201 +#define AB8500_MAIN_WDOG_TIMER_REG 0x0202 +#define AB8500_LOW_BAT_REG 0x0203 +#define AB8500_BATT_OK_REG 0x0204 +#define AB8500_SYSCLK_TIMER_REG 0x0205 +#define AB8500_SMPSCLK_CTRL_REG 0x0206 +#define AB8500_SMPSCLK_SEL1_REG 0x0207 +#define AB8500_SMPSCLK_SEL2_REG 0x0208 +#define AB8500_SMPSCLK_SEL3_REG 0x0209 +#define AB8500_SYSULPCLK_CONF_REG 0x020A +#define AB8500_SYSULPCLK_CTRL1_REG 0x020B +#define AB8500_SYSCLK_CTRL_REG 0x020C +#define AB8500_SYSCLK_REQ1_VALID_REG 0x020D +#define AB8500_SYSCLK_REQ_VALID_REG 0x020E +#define AB8500_SYSCTRL_SPARE_REG 0x020F +#define AB8500_PAD_CONF_REG 0x0210 + +/* + * Regu control1 register offsets (SPI) + * Bank = 0x03 + */ +#define AB8500_REGU_SERIAL_CTRL1_REG 0x0300 +#define AB8500_REGU_SERIAL_CTRL2_REG 0x0301 +#define AB8500_REGU_SERIAL_CTRL3_REG 0x0302 +#define AB8500_REGU_REQ_CTRL1_REG 0x0303 +#define AB8500_REGU_REQ_CTRL2_REG 0x0304 +#define AB8500_REGU_REQ_CTRL3_REG 0x0305 +#define AB8500_REGU_REQ_CTRL4_REG 0x0306 +#define AB8500_REGU_SYSCLK_REQ1HP_VALID1_REG 0x0307 +#define AB8500_REGU_SYSCLK_REQ1HP_VALID2_REG 0x0308 +#define AB8500_REGU_HWHPREQ1_VALID1_REG 0x0309 +#define AB8500_REGU_HWHPREQ1_VALID2_REG 0x030A +#define AB8500_REGU_HWHPREQ2_VALID1_REG 0x030B +#define AB8500_REGU_HWHPREQ2_VALID2_REG 0x030C +#define AB8500_REGU_SWHPREQ_VALID1_REG 0x030D +#define AB8500_REGU_SWHPREQ_VALID2_REG 0x030E + +#define AB8500_REGU_SYSCLK_REQ1_VALID_REG 0x030F /* only for ED*/ +#define AB8500_REGU_SYSCLK_REQ2_VALID_REG 0x0310 /*only for ED*/ + +#define AB8500_REGU_MISC1_REG 0x0380 +#define AB8500_REGU_OTGSUPPLY_CTRL_REG 0x0381 +#define AB8500_REGU_VUSB_CTRL_REG 0x0382 /* see reg manaul*/ +#define AB8500_REGU_VAUDIO_SUPPLY_REG 0x0383 +#define AB8500_REGU_CTRL1_SPARE_REG 0x0384 + + /* + * Regu control2 register offsets (SPI/APE I2C) + * Bank = 0x04 + */ +#define AB8500_REGU_ARM_REGU1_REG 0x0400 +#define AB8500_REGU_ARM_REGU2_REG 0x0401 +#define AB8500_REGU_VAPE_REGU_REG 0x0402 +#define AB8500_REGU_VSMPS1_REGU_REG 0x0403 +#define AB8500_REGU_VSMPS2_REGU_REG 0x0404 +#define AB8500_REGU_VSMPS3_REGU_REG 0x0405 +#define AB8500_REGU_VPLLVANA_REGU_REG 0x0406 +#define AB8500_REGU_VREF_DDR_REG 0x0407 +#define AB8500_REGU_EXTSUPPLY_REGU_REG 0x0408 +#define AB8500_REGU_VAUX12_REGU_REG 0x0409 +#define AB8500_REGU_VAUX12_REGU_VAUX1_MASK 0x3 +#define AB8500_REGU_VAUX12_REGU_VAUX1_SHIFT 0 +#define AB8500_REGU_VAUX12_REGU_VAUX1_FORCE_HP 0x1 +#define AB8500_REGU_VRF1VAUX3_REGU_REG 0x040A +#define AB8500_REGU_VARM_SEL1_REG 0x040B +#define AB8500_REGU_VARM_SEL2_REG 0x040C +#define AB8500_REGU_VARM_SEL3_REG 0x040D +#define AB8500_REGU_VAPE_SEL1_REG 0x040E +#define AB8500_REGU_VAPE_SEL2_REG 0x040F +#define AB8500_REGU_VAPE_SEL3_REG 0x0410 +#define AB8500_REGU_VBB_SEL2_REG 0x0412 +#define AB8500_REGU_VSMPS1_SEL1_REG 0x0413 +#define AB8500_REGU_VSMPS1_SEL2_REG 0x0414 +#define AB8500_REGU_VSMPS1_SEL3_REG 0x0415 +#define AB8500_REGU_VSMPS2_SEL1_REG 0x0417 +#define AB8500_REGU_VSMPS2_SEL2_REG 0x0418 +#define AB8500_REGU_VSMPS2_SEL3_REG 0x0419 +#define AB8500_REGU_VSMPS3_SEL1_REG 0x041B +#define AB8500_REGU_VSMPS3_SEL2_REG 0x041C +#define AB8500_REGU_VSMPS3_SEL3_REG 0x041D +#define AB8500_REGU_VAUX1_SEL_REG 0x041F +#define AB8500_REGU_VAUX1_SEL_MASK 0xf +#define AB8500_REGU_VAUX1_SEL_SHIFT 0 +#define AB8500_REGU_VAUX1_SEL_1_5V 0x4 +#define AB8500_REGU_VAUX1_SEL_2_5V 0x8 +#define AB8500_REGU_VAUX2_SEL_REG 0x0420 +#define AB8500_REGU_VRF1VAUX3_SEL_REG 0x0421 +#define AB8500_REGU_CTRL2_SPARE_REG 0x0422 + +/* + * Regu control2 Vmod register offsets + */ +#define AB8500_REGU_VMOD_REGU_REG 0x0440 +#define AB8500_REGU_VMOD_SEL1_REG 0x0441 +#define AB8500_REGU_VMOD_SEL2_REG 0x0442 +#define AB8500_REGU_CTRL_DISCH_REG 0x0443 +#define AB8500_REGU_CTRL_DISCH2_REG 0x0444 + +/* + * Sim control register offsets + * Bank:0x4 + */ +#define AB8500_SIM_REG1_SGR1L_REG 0x0480 +#define AB8500_SIM_REG1_SGR1U_REG 0x0481 +#define AB8500_SIM_REG2_SCR1L_REG 0x0482 +#define AB8500_SIM_REG2_SCR1U_REG 0x0483 +#define AB8500_SIM_REG3_SCTRLRL_REG 0x0484 +#define AB8500_SIM_REG3_SCTRLRU_REG 0x0485 +#define AB8500_SIM_ISOUICCINT_SRC_REG 0x0486 +#define AB8500_SIM_ISOUICCINT_LATCH_REG 0x0487 +#define AB8500_SIM_ISOUICCINT_MASK_REG 0x0488 +#define AB8500_SIM_REG4_USBUICC_REG 0x0489 +#define AB8500_SIM_SDELAYSEL_REG 0x048A +#define AB8500_SIM_USBUICC_CTRL 0x048B /* bit 3 only for ED */ + +/* + * USB/ULPI register offsets + * Bank : 0x5 + */ +#define AB8500_USB_LINE_STAT_REG 0x0580 +#define AB8500_USB_LINE_CTRL1_REG 0x0581 +#define AB8500_USB_LINE_CTRL2_REG 0x0582 +#define AB8500_USB_LINE_CTRL3_REG 0x0583 +#define AB8500_USB_LINE_CTRL4_REG 0x0584 +#define AB8500_USB_LINE_CTRL5_REG 0x0585 +#define AB8500_USB_OTG_CTRL_REG 0x0587 +#define AB8500_USB_OTG_STAT_REG 0x0588 +#define AB8500_USB_OTG_STAT_REG 0x0588 +#define AB8500_USB_CTRL_SPARE_REG 0x0589 +#define AB8500_USB_PHY_CTRL_REG 0x058A /*only in Cut1.0*/ + +/* + * TVOUT / CTRL register offsets + * Bank : 0x06 + */ +#define AB8500_DENC_CONF0_REG 0x0600 +#define AB8500_DENC_CONF1_REG 0x0601 +#define AB8500_DENC_CONF2_REG 0x0602 +#define AB8500_DENC_CONF3_REG 0x0603 +#define AB8500_DENC_CONF4_REG 0x0604 +#define AB8500_DENC_CONF5_REG 0x0605 +#define AB8500_DENC_CONF6_REG 0x0606 +#define AB8500_DENC_CONF6_SOFT_RST_MASK 0x80 +#define AB8500_DENC_CONF6_SOFT_RST_SHIFT 7 +#define AB8500_DENC_CONF6_SOFT_RST_OFF 0x0 +#define AB8500_DENC_CONF6_SOFT_RST_ON 0x1 +#define AB8500_DENC_CONF7_REG 0x0607 +#define AB8500_DENC_CONF8_REG 0x0608 +#define AB8500_TVOUT_CTRL_REG 0x0680 +#define AB8500_TVOUT_CTRL2_REG 0x0681 +/* + * DBI register offsets + * Bank : 0x07 + */ +#define AB8500_DBI_REG1_REG 0x0700 +#define AB8500_DBI_REG2_REG 0x0701 +/* + * ECI regsiter offsets + * Bank : 0x08 + */ +#define AB8500_ECI_CTRL_REG 0x0800 +#define AB8500_ECI_HOOKLEVEL_REG 0x0801 +#define AB8500_ECI_DATAOUT_REG 0x0802 +#define AB8500_ECI_DATAIN_REG 0x0803 +/* + * AV Connector register offsets + * Bank : 0x08 + */ +#define AB8500_AV_CONN_REG 0x0840 +/* + * Accessory detection register offsets + * Bank : 0x08 + */ +#define AB8500_ACC_DET_DB1_REG 0x0880 +#define AB8500_ACC_DET_DB2_REG 0x0881 +/* + * GPADC register offsets + * Bank : 0x0A + */ +#define AB8500_GPADC_CTRL1_REG 0x0A00 +#define AB8500_GPADC_CTRL2_REG 0x0A01 +#define AB8500_GPADC_CTRL3_REG 0x0A02 +#define AB8500_GPADC_AUTO_TIMER_REG 0x0A03 +#define AB8500_GPADC_STAT_REG 0x0A04 +#define AB8500_GPADC_MANDATAL_REG 0x0A05 +#define AB8500_GPADC_MANDATAH_REG 0x0A06 +#define AB8500_GPADC_AUTODATAL_REG 0x0A07 +#define AB8500_GPADC_AUTODATAH_REG 0x0A08 +#define AB8500_GPADC_MUX_CTRL_REG 0x0A09 +/* + * Charger / status register offfsets + * Bank : 0x0B + */ +#define AB8500_CH_STATUS1_REG 0x0B00 +#define AB8500_CH_STATUS2_REG 0x0B01 +#define AB8500_CH_USBCH_STAT1_REG 0x0B02 +#define AB8500_CH_USBCH_STAT2_REG 0x0B03 +#define AB8500_CH_FSM_STAT_REG 0x0B04 +#define AB8500_CH_STAT_REG 0x0B05 +/* + * Charger / control register offfsets + * Bank : 0x0B + */ +#define AB8500_CH_VOLT_LVL_REG 0x0B40 +#define AB8500_CH_VOLT_LVL_MAX_REG 0x0B41 /*Only in Cut1.0*/ +#define AB8500_CH_OPT_CRNTLVL_REG 0x0B42 /*Only in Cut1.0*/ +#define AB8500_CH_OPT_CRNTLVL_MAX_REG 0x0B43 /*Only in Cut1.0*/ +#define AB8500_CH_WD_TIMER_REG 0x0B44 /*Only in Cut1.0*/ +#define AB8500_CH_WD_CTRL_REG 0x0B45 /*Only in Cut1.0*/ +#define AB8500_CHARG_WD_CTRL 0x0B51 +#define AB8500_LED_INDICATOR_PWM_CTRL 0x0B53 +#define AB8500_LED_INDICATOR_PWM_DUTY 0x0B54 +#define AB8500_BATT_OVV 0x0B55 +/* + * Charger / main control register offfsets + * Bank : 0x0B + */ +#define AB8500_MCH_CTRL1 0x0B80 +#define AB8500_MCH_CTRL2 0x0B81 +#define AB8500_MCH_IPT_CURLVL_REG 0x0B82 +#define AB8500_CH_WD_REG 0x0B83 +/* + * Charger / USB control register offsets + * Bank : 0x0B + */ +#define AB8500_USBCH_CTRL1_REG 0x0BC0 +#define AB8500_USBCH_CTRL2_REG 0x0BC1 +#define AB8500_USBCH_IPT_CRNTLVL_REG 0x0BC2 +/* + * Gas Gauge register offsets + * Bank : 0x0C + */ +#define AB8500_GASG_CC_CTRL_REG 0x0C00 +#define AB8500_GASG_CC_ACCU1_REG 0x0C01 +#define AB8500_GASG_CC_ACCU2_REG 0x0C02 +#define AB8500_GASG_CC_ACCU3_REG 0x0C03 +#define AB8500_GASG_CC_ACCU4_REG 0x0C04 +#define AB8500_GASG_CC_SMPL_CNTRL_REG 0x0C05 +#define AB8500_GASG_CC_SMPL_CNTRH_REG 0x0C06 +#define AB8500_GASG_CC_SMPL_CNVL_REG 0x0C07 +#define AB8500_GASG_CC_SMPL_CNVH_REG 0x0C08 +#define AB8500_GASG_CC_CNTR_AVGOFF_REG 0x0C09 +#define AB8500_GASG_CC_OFFSET_REG 0x0C0A +#define AB8500_GASG_CC_NCOV_ACCU 0x0C10 +#define AB8500_GASG_CC_NCOV_ACCU_CTRL 0x0C11 +#define AB8500_GASG_CC_NCOV_ACCU_LOW 0x0C12 +#define AB8500_GASG_CC_NCOV_ACCU_MED 0x0C13 +#define AB8500_GASG_CC_NCOV_ACCU_HIGH 0x0C14 + + + +/* + * Audio + * Bank : 0x0D + * Should be part of Audio codec driver + */ +#define AB8500_AUDIO_POWER_UP 0x0D00 +#define AB8500_AUDIO_ANA_CONF4 0x0D08 +#define AB8500_AUDIO_DA_PATH_CONF 0x0D09 +#define AB8500_AUDIO_PWM_GEN_CONF1 0x0D0F +#define AB8500_AUDIO_PWM_GEN_CONF2 0x0D10 +#define AB8500_AUDIO_PWM_GEN_CONF3 0x0D11 +#define AB8500_AUDIO_PWM_GEN_CONF4 0x0D12 +#define AB8500_AUDIO_PWM_GEN_CONF5 0x0D13 + +/* + * Interrupt register offsets + * Bank : 0x0E + */ +#define AB8500_IT_SOURCE1_REG 0x0E00 +#define AB8500_IT_SOURCE2_REG 0x0E01 +#define AB8500_IT_SOURCE3_REG 0x0E02 +#define AB8500_IT_SOURCE4_REG 0x0E03 +#define AB8500_IT_SOURCE5_REG 0x0E04 +#define AB8500_IT_SOURCE6_REG 0x0E05 + +/* available only in 1.0 */ +#define AB8500_IT_SOURCE7_REG 0x0E06 +#define AB8500_IT_SOURCE8_REG 0x0E07 +#define AB8500_IT_SOURCE19_REG 0x0E12 + +#define AB8500_IT_SOURCE20_REG 0x0E13 +#define AB8500_IT_SOURCE21_REG 0x0E14 +#define AB8500_IT_SOURCE22_REG 0x0E15 +#define AB8500_IT_SOURCE23_REG 0x0E16 +#define AB8500_IT_SOURCE24_REG 0x0E17 + +/* + * latch registers + */ +#define AB8500_IT_LATCH1_REG 0x0E20 +#define AB8500_IT_LATCH2_REG 0x0E21 +#define AB8500_IT_LATCH3_REG 0x0E22 +#define AB8500_IT_LATCH4_REG 0x0E23 +#define AB8500_IT_LATCH5_REG 0x0E24 +#define AB8500_IT_LATCH6_REG 0x0E25 + +/* available only in 1.0 */ +#define AB8500_IT_LATCH7_REG 0x0E26 +#define AB8500_IT_LATCH8_REG 0x0E27 +#define AB8500_IT_LATCH9_REG 0x0E28 +#define AB8500_IT_LATCH10_REG 0x0E29 +#define AB8500_IT_LATCH19_REG 0x0E32 + +#define AB8500_IT_LATCH20_REG 0x0E33 +#define AB8500_IT_LATCH21_REG 0x0E34 +#define AB8500_IT_LATCH22_REG 0x0E35 +#define AB8500_IT_LATCH23_REG 0x0E36 +#define AB8500_IT_LATCH24_REG 0x0E37 + +/* + * mask registers + */ + +#define AB8500_IT_MASK1_REG 0x0E40 +#define AB8500_IT_MASK2_REG 0x0E41 +#define AB8500_IT_MASK3_REG 0x0E42 +#define AB8500_IT_MASK4_REG 0x0E43 +#define AB8500_IT_MASK5_REG 0x0E44 +#define AB8500_IT_MASK6_REG 0x0E45 + + +/* available only in 1.0 */ +#define AB8500_IT_MASK7_REG 0x0E46 +#define AB8500_IT_MASK8_REG 0x0E47 +#define AB8500_IT_MASK9_REG 0x0E48 +#define AB8500_IT_MASK10_REG 0x0E49 +#define AB8500_IT_MASK11_REG 0x0E4A +#define AB8500_IT_MASK12_REG 0x0E4B +#define AB8500_IT_MASK13_REG 0x0E4C +#define AB8500_IT_MASK14_REG 0x0E4D +#define AB8500_IT_MASK15_REG 0x0E4E +#define AB8500_IT_MASK16_REG 0x0E4F +#define AB8500_IT_MASK17_REG 0x0E50 +#define AB8500_IT_MASK18_REG 0x0E51 +#define AB8500_IT_MASK19_REG 0x0E52 + +#define AB8500_IT_MASK20_REG 0x0E53 +#define AB8500_IT_MASK21_REG 0x0E54 +#define AB8500_IT_MASK22_REG 0x0E55 +#define AB8500_IT_MASK23_REG 0x0E56 +#define AB8500_IT_MASK24_REG 0x0E57 + +/* + * RTC bank register offsets + * Bank : 0xF + */ +#define AB8500_RTC_SWITCHOFF_STAT_REG 0x0F00 +#define AB8500_RTC_CC_CONF_REG 0x0F01 +#define AB8500_RTC_READ_REQ_REG 0x0F02 +#define AB8500_RTC_WATCH_TSECMID_REG 0x0F03 +#define AB8500_RTC_WATCH_TSECHI_REG 0x0F04 +#define AB8500_RTC_WATCH_TMIN_LOW_REG 0x0F05 +#define AB8500_RTC_WATCH_TMIN_MID_REG 0x0F06 +#define AB8500_RTC_WATCH_TMIN_HI_REG 0x0F07 +#define AB8500_RTC_ALRM_MIN_LOW_REG 0x0F08 +#define AB8500_RTC_ALRM_MIN_MID_REG 0x0F09 +#define AB8500_RTC_ALRM_MIN_HI_REG 0x0F0A +#define AB8500_RTC_STAT_REG 0x0F0B +#define AB8500_RTC_BKUP_CHG_REG 0x0F0C +#define AB8500_RTC_FORCE_BKUP_REG 0x0F0D +#define AB8500_RTC_CALIB_REG 0x0F0E +#define AB8500_RTC_SWITCH_STAT_REG 0x0F0F + +/* + * Misc block GPIO register offsets - Not for ED + * Bank : 0x10 + */ +/* available only in 1.0 */ +#define AB8500_GPIO_SEL1_REG 0x01000 +#define AB8500_GPIO_SEL2_REG 0x01001 +#define AB8500_GPIO_SEL3_REG 0x01002 +#define AB8500_GPIO_SEL4_REG 0x01003 +#define AB8500_GPIO_SEL5_REG 0x01004 +#define AB8500_GPIO_SEL6_REG 0x01005 +#define AB8500_GPIO_DIR1_REG 0x01010 +#define AB8500_GPIO_DIR2_REG 0x01011 +#define AB8500_GPIO_DIR3_REG 0x01012 +#define AB8500_GPIO_DIR4_REG 0x01013 +#define AB8500_GPIO_DIR5_REG 0x01014 +#define AB8500_GPIO_DIR6_REG 0x01015 + +#define AB8500_GPIO_OUT1_REG 0x01020 +#define AB8500_GPIO_OUT2_REG 0x01021 +#define AB8500_GPIO_OUT3_REG 0x01022 +#define AB8500_GPIO_OUT4_REG 0x01023 +#define AB8500_GPIO_OUT5_REG 0x01024 +#define AB8500_GPIO_OUT6_REG 0x01025 + +#define AB8500_GPIO_PUD1_REG 0x01030 +#define AB8500_GPIO_PUD2_REG 0x01031 +#define AB8500_GPIO_PUD3_REG 0x01032 +#define AB8500_GPIO_PUD4_REG 0x01033 +#define AB8500_GPIO_PUD5_REG 0x01034 +#define AB8500_GPIO_PUD6_REG 0x01035 + +#define AB8500_GPIO_IN1_REG 0x01040 +#define AB8500_GPIO_IN2_REG 0x01041 +#define AB8500_GPIO_IN3_REG 0x01042 +#define AB8500_GPIO_IN4_REG 0x01043 +#define AB8500_GPIO_IN5_REG 0x01044 +#define AB8500_GPIO_IN6_REG 0x01045 +#define AB8500_GPIO_ALT_FUNC 0x01050 + +/* + * PWM Out generators + * Bank: 0x10 + */ +#define AB8500_PWM_OUT_CTRL1_REG 0x1060 +#define AB8500_PWM_OUT_CTRL2_REG 0x1061 +#define AB8500_PWM_OUT_CTRL3_REG 0x1062 +#define AB8500_PWM_OUT_CTRL4_REG 0x1063 +#define AB8500_PWM_OUT_CTRL5_REG 0x1064 +#define AB8500_PWM_OUT_CTRL6_REG 0x1065 +#define AB8500_PWM_OUT_CTRL7_REG 0x1066 + +#define AB8500_I2C_PAD_CTRL_REG 0x1067 +#define AB8500_REV_REG 0x1080 + +/* + * Misc, Debug Test Configuration register + * Bank : 0x11 + */ +#define AB8500_DEBUG_TESTMODE_REG 0x01100 + +/* only in 1.0 */ +#define AB8500_I2C_TRIG1_ADR_REG 0x1101 +#define AB8500_I2C_TRIG1_ID_REG 0x1102 +#define AB8500_I2C_TRIG2_ADR_REG 0x1103 +#define AB8500_I2C_TRIG3_ID_REG 0x1104 +#define AB8500_I2C_NOACCESS_SUP_REG 0x1105 + +/* Offsets in TurnOnstatus register + */ + +#define AB8500_MAX_INT 192 +#define AB8500_MAX_FUTURE_USE 105 + +#define AB8500_MAX_INT_SOURCE 11 +#define AB8500_MAX_INT_LATCH 13 +#define AB8500_MAX_INT_MASK 21 + +#define ab8500_read prcmu_i2c_read +#define ab8500_write prcmu_i2c_write + +extern int prcmu_i2c_read(u8 reg, u16 slave); +extern int prcmu_i2c_write(u8 reg, u16 slave, u8 reg_data); + +#endif /* AB8500_H_ */ diff --git a/arch/arm/include/asm/arch-u8500/clock.h b/arch/arm/include/asm/arch-u8500/clock.h index b00ab0d21..f9deba524 100644 --- a/arch/arm/include/asm/arch-u8500/clock.h +++ b/arch/arm/include/asm/arch-u8500/clock.h @@ -23,50 +23,13 @@ #ifndef __ASM_ARCH_CLOCK #define __ASM_ARCH_CLOCK -struct prcmu { - unsigned int armclkfix_mgt; - unsigned int armclk_mgt; - unsigned int svammdspclk_mgt; - unsigned int siammdspclk_mgt; - unsigned int reserved; - unsigned int sgaclk_mgt; - unsigned int uartclk_mgt; - unsigned int msp02clk_mgt; - unsigned int i2cclk_mgt; - unsigned int sdmmcclk_mgt; - unsigned int slimclk_mgt; - unsigned int per1clk_mgt; - unsigned int per2clk_mgt; - unsigned int per3clk_mgt; - unsigned int per5clk_mgt; - unsigned int per6clk_mgt; - unsigned int per7clk_mgt; - unsigned int lcdclk_mgt; - unsigned int reserved1; - unsigned int bmlclk_mgt; - unsigned int hsitxclk_mgt; - unsigned int hsirxclk_mgt; - unsigned int hdmiclk_mgt; - unsigned int apeatclk_mgt; - unsigned int apetraceclk_mgt; - unsigned int mcdeclk_mgt; - unsigned int ipi2cclk_mgt; - unsigned int dsialtclk_mgt; - unsigned int spare2clk_mgt; - unsigned int dmaclk_mgt; - unsigned int b2r2clk_mgt; - unsigned int tvclk_mgt; - unsigned int unused[82]; - unsigned int tcr; - unsigned int unused1[23]; - unsigned int ape_softrst; -}; +/* Enable all clocks u-boot needs in db8500 SoC platform */ +void db8500_clocks_init(void); -extern void u8500_clock_enable(int periph, int kern, int cluster); +/* Legacy function to allow drivers to enable their clock */ +void u8500_clock_enable(int periph, int cluster, int kern); -static inline void u8500_prcmu_enable(unsigned int *reg) -{ - writel(readl(reg) | (1 << 8), reg); -} +/* Function to get the clock speed of ARM cpu */ +u32 db8500_clock_cpu_khz(void); #endif /* __ASM_ARCH_CLOCK */ diff --git a/arch/arm/include/asm/arch-u8500/common.h b/arch/arm/include/asm/arch-u8500/common.h new file mode 100644 index 000000000..42fb8928f --- /dev/null +++ b/arch/arm/include/asm/arch-u8500/common.h @@ -0,0 +1,131 @@ +/* + * Copyright (C) ST-Ericsson SA 2009 + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _DB8500_COMMON_H_ +#define _DB8500_COMMON_H_ +#include + +#define PASS (1) +#define FAIL (0) + +#define IO(addr) (*((u32*) (addr))) +#define HIO(addr) (*((u16*) (addr))) +#define BIO(addr) (*((u8*) (addr))) + +/* + * macro to get at IO space + */ +#define IO_ADDRESS(x) (x) + +#define REG_WRITE_BITS(reg,val,mask,sb) (writel(((readl(reg) & ~(mask)) | (((val)<<(sb)) & (mask))), reg)) + +#define nmdk_error(format, arg...) printf(": " format "\n" , ## arg) + +#if !defined(FALSE) && !defined(TRUE) +typedef enum {FALSE, TRUE} t_bool; +#else /* FALSE & TRUE already defined */ +typedef enum {BOOL_FALSE, BOOL_TRUE} t_bool; +#endif /* !defined(FALSE) && !defined(TRUE) */ + +/*----------------------------------------------------------------------------- + * Bit mask definition + *---------------------------------------------------------------------------*/ +#define MASK_NULL8 0x00 +#define MASK_NULL16 0x0000 +#define MASK_NULL32 0x00000000 +#define MASK_ALL8 0xFF +#define MASK_ALL16 0xFFFF +#define MASK_ALL32 0xFFFFFFFF + +#define MASK_BIT0 (1UL<<0) +#define MASK_BIT1 (1UL<<1) +#define MASK_BIT2 (1UL<<2) +#define MASK_BIT3 (1UL<<3) +#define MASK_BIT4 (1UL<<4) +#define MASK_BIT5 (1UL<<5) +#define MASK_BIT6 (1UL<<6) +#define MASK_BIT7 (1UL<<7) +#define MASK_BIT8 (1UL<<8) +#define MASK_BIT9 (1UL<<9) +#define MASK_BIT10 (1UL<<10) +#define MASK_BIT11 (1UL<<11) +#define MASK_BIT12 (1UL<<12) +#define MASK_BIT13 (1UL<<13) +#define MASK_BIT14 (1UL<<14) +#define MASK_BIT15 (1UL<<15) +#define MASK_BIT16 (1UL<<16) +#define MASK_BIT17 (1UL<<17) +#define MASK_BIT18 (1UL<<18) +#define MASK_BIT19 (1UL<<19) +#define MASK_BIT20 (1UL<<20) +#define MASK_BIT21 (1UL<<21) +#define MASK_BIT22 (1UL<<22) +#define MASK_BIT23 (1UL<<23) +#define MASK_BIT24 (1UL<<24) +#define MASK_BIT25 (1UL<<25) +#define MASK_BIT26 (1UL<<26) +#define MASK_BIT27 (1UL<<27) +#define MASK_BIT28 (1UL<<28) +#define MASK_BIT29 (1UL<<29) +#define MASK_BIT30 (1UL<<30) +#define MASK_BIT31 (1UL<<31) + +#define NOMADIK_INTERNAL_ERROR (-8) +#define NOMADIK_NOT_CONFIGURED (-7) +#define NOMADIK_REQUEST_PENDING (-6) +#define NOMADIK_REQUEST_NOT_APPLICABLE (-5) +#define NOMADIK_INVALID_PARAMETER (-4) +#define NOMADIK_UNSUPPORTED_FEATURE (-3) +#define NOMADIK_UNSUPPORTED_HW (-2) +#define NOMADIK_ERROR (-1) +#define NOMADIK_OK ( 0) +#define NOMADIK_INTERNAL_EVENT ( 1) +#define NOMADIK_REMAINING_PENDING_EVENTS ( 2) +#define NOMADIK_REMAINING_FILTER_PENDING_EVENTS ( 3) +#define NOMADIK_NO_MORE_PENDING_EVENT ( 4) +#define NOMADIK_NO_MORE_FILTER_PENDING_EVENT ( 5) +#define NOMADIK_NO_PENDING_EVENT_ERROR ( 7) + + +#define NOMADIK_MAX_ERROR_VALUE (-65) /* HW specific error codes + * should start from this offset + */ +/*----------------------------------------------------------------------------- + * Bit setting or clearing + *---------------------------------------------------------------------------*/ +#define NOMADIK_SET_BITS(reg,mask) ((reg) |= (mask)) +#define NOMADIK_CLEAR_BITS(reg,mask) ((reg) &= ~(mask)) +#define NOMADIK_READ_BITS(reg,mask) ((reg) & (mask)) +#define NOMADIK_WRITE_BITS(reg,val,mask) ((reg) = (((reg) & ~(mask)) | ((val) & (mask)))) +#define NOMADIK_READ_REG(reg) (reg) +#define NOMADIK_WRITE_REG(reg,val) ((reg) = (val)) + +/* + * Definition of the different kind of addresses manipulated into a system with MMU + * (handle physical AND logical addresses) + */ + +typedef u32 t_physical_address; +typedef u32 t_logical_address; + +/*function prototypes*/ +int board_early_access(block_dev_desc_t *block_dev); +#endif /* _DB8500_COMMON_H_ */ diff --git a/arch/arm/include/asm/arch-u8500/cpu.h b/arch/arm/include/asm/arch-u8500/cpu.h new file mode 100644 index 000000000..9c61240dd --- /dev/null +++ b/arch/arm/include/asm/arch-u8500/cpu.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * Author: Joakim Axelsson + * for ST-Ericsson + * + * Origin: Code split from board/st/u8500/u8500.c + * + * License terms: GNU General Public License (GPL), version 2. + */ + +#ifndef __DB8500_CPU_H__ +#define __DB8500_CPU_H__ + +#include +#include +#include + +#define CPUID_DB8500ED 0x410fc090 +#define CPUID_DB8500V1 0x411fc091 +#define CPUID_DB8500V2 0x412fc091 + +#define ASICID_DB8500V11 0x008500A1 + +/* + * Keep these CPU identity functions inline here because they are short + * and used by many. Will make for fast optimized compiled code. + */ + +static inline unsigned int read_cpuid(void) +{ + unsigned int val; + + /* Main ID register (MIDR) */ + asm("mrc p15, 0, %0, c0, c0, 0" + : "=r" (val) + : + : "cc"); + + return val; +} + +static inline int u8500_is_snowball(void) +{ + return 1; +} + +#define HREF_PRINTF(fmt, args...) \ + if (!u8500_is_snowball()) printf(fmt, ##args); + +static inline int u8500_is_earlydrop(void) +{ + return read_cpuid() == CPUID_DB8500ED; +} + +static inline int cpu_is_u8500v1(void) +{ + return read_cpuid() == CPUID_DB8500V1; +} + +static inline int cpu_is_u8500v2(void) +{ + return read_cpuid() == CPUID_DB8500V2; +} + +static inline unsigned int read_asicid(void) +{ + unsigned int *address; + + if (u8500_is_earlydrop() || cpu_is_u8500v1()) + address = (void *) U8500_ASIC_ID_LOC_ED_V1; + else + address = (void *) U8500_ASIC_ID_LOC_V2; + + return readl(address); +} + +static inline int cpu_is_u8500v11(void) +{ + return read_asicid() == ASICID_DB8500V11; +} + + +#endif /* __DB8500_CPU_H__ */ + diff --git a/arch/arm/include/asm/arch-u8500/hardware.h b/arch/arm/include/asm/arch-u8500/hardware.h index 6bb95ec07..990c062fb 100644 --- a/arch/arm/include/asm/arch-u8500/hardware.h +++ b/arch/arm/include/asm/arch-u8500/hardware.h @@ -50,11 +50,13 @@ #define U8500_GPIO8_BASE (U8500_PER5_BASE + 0x1E000) /* Per7 */ +#define U8500_MTU0_BASE_ED (U8500_PER7_BASE + 0xa000) +#define U8500_MTU1_BASE_ED (U8500_PER7_BASE + 0xb000) #define U8500_CLKRST7_BASE (U8500_PER7_BASE + 0xf000) /* Per6 */ #define U8500_MTU0_BASE_V1 (U8500_PER6_BASE + 0x6000) -#define U8500_MTU1_BASE_V1 (U8500_PER6_BASE + 0x7000) +#define U8500_MTU1_BASE_v1 (U8500_PER6_BASE + 0x7000) #define U8500_CLKRST6_BASE (U8500_PER6_BASE + 0xf000) /* Per5 */ @@ -62,22 +64,29 @@ /* Per4 */ #define U8500_PRCMU_BASE (U8500_PER4_BASE + 0x07000) -#define U8500_PRCMU_TCDM_BASE (U8500_PER4_BASE + 0x0f000) +#define U8500_PRCMU_TCDM_BASE_V1 (U8500_PER4_BASE + 0x0f000) +#define U8500_PRCMU_TCDM_BASE (U8500_PER4_BASE + 0x68000) /* Per3 */ #define U8500_UART2_BASE (U8500_PER3_BASE + 0x7000) #define U8500_CLKRST3_BASE (U8500_PER3_BASE + 0xf000) /* Per2 */ +#define U8500_SPI2_BASE (U8500_PER2_BASE + 0x1000) +#define U8500_SPI1_BASE (U8500_PER2_BASE + 0x2000) +#define U8500_SPI0_BASE (U8500_PER2_BASE + 0xa000) #define U8500_CLKRST2_BASE (U8500_PER2_BASE + 0xf000) /* Per1 */ #define U8500_UART0_BASE (U8500_PER1_BASE + 0x0000) #define U8500_UART1_BASE (U8500_PER1_BASE + 0x1000) +#define U8500_SPI3_BASE (U8500_PER2_BASE + 0x9000) #define U8500_CLKRST1_BASE (U8500_PER1_BASE + 0xf000) -/* Last page of Boot ROM */ -#define U8500_BOOTROM_BASE 0x9001f000 -#define U8500_BOOTROM_ASIC_ID_OFFSET 0x0ff4 +#define U8500_BOOTROM_BASE 0x90000000 +#define U8500_ASIC_ID_LOC_ED_V1 (U8500_BOOTROM_BASE + 0x1FFF4) +#define U8500_ASIC_ID_LOC_V2 (U8500_BOOTROM_BASE + 0x1DBF4) + +#define U8500_TWD_BASE 0xa0410600 #endif /* __ASM_ARCH_HARDWARE_H */ diff --git a/arch/arm/include/asm/arch-u8500/prcmu.h b/arch/arm/include/asm/arch-u8500/prcmu.h new file mode 100644 index 000000000..f7709e2d7 --- /dev/null +++ b/arch/arm/include/asm/arch-u8500/prcmu.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * Author: Joakim Axelsson + * for ST-Ericsson + * + * Origin: Code split from board/st/u8500/u8500.c + * + * License terms: GNU General Public License (GPL), version 2. + */ + +#ifndef __PRCMU_H__ +#define __PRCMU_H__ + +#include + +/* Power, Reset, Clock Management Unit */ +/* + * SVA: Smart Video Accelerator + * SIA: Smart Imaging Accelerator + * SGA: Smart Graphic accelerator + * B2R2: Graphic blitter + */ +#define PRCMU_BASE U8500_PRCMU_BASE +#define PRCM_ARMCLKFIX_MGT_REG (PRCMU_BASE + 0x000) +#define PRCM_ACLK_MGT_REG (PRCMU_BASE + 0x004) +#define PRCM_SVAMMDSPCLK_MGT_REG (PRCMU_BASE + 0x008) +#define PRCM_SIAMMDSPCLK_MGT_REG (PRCMU_BASE + 0x00C) +#define PRCM_SAAMMDSPCLK_MGT_REG (PRCMU_BASE + 0x010) +#define PRCM_SGACLK_MGT_REG (PRCMU_BASE + 0x014) +#define PRCM_UARTCLK_MGT_REG (PRCMU_BASE + 0x018) +#define PRCM_MSPCLK_MGT_REG (PRCMU_BASE + 0x01C) +#define PRCM_I2CCLK_MGT_REG (PRCMU_BASE + 0x020) +#define PRCM_SDMMCCLK_MGT_REG (PRCMU_BASE + 0x024) +#define PRCM_SLIMCLK_MGT_REG (PRCMU_BASE + 0x028) +#define PRCM_PER1CLK_MGT_REG (PRCMU_BASE + 0x02C) +#define PRCM_PER2CLK_MGT_REG (PRCMU_BASE + 0x030) +#define PRCM_PER3CLK_MGT_REG (PRCMU_BASE + 0x034) +#define PRCM_PER5CLK_MGT_REG (PRCMU_BASE + 0x038) +#define PRCM_PER6CLK_MGT_REG (PRCMU_BASE + 0x03C) +#define PRCM_PER7CLK_MGT_REG (PRCMU_BASE + 0x040) +#define PRCM_DMACLK_MGT_REG (PRCMU_BASE + 0x074) +#define PRCM_B2R2CLK_MGT_REG (PRCMU_BASE + 0x078) + +#define PRCM_PLLSOC0_FREQ_REG (PRCMU_BASE + 0x080) +#define PRCM_PLLSOC1_FREQ_REG (PRCMU_BASE + 0x084) +#define PRCM_PLLARM_FREQ_REG (PRCMU_BASE + 0x088) +#define PRCM_PLLDDR_FREQ_REG (PRCMU_BASE + 0x08C) +#define PRCM_ARM_CHGCLKREQ_REG (PRCMU_BASE + 0x114) + +#define PRCM_TCR (PRCMU_BASE + 0x1C8) + +/* Init PRCMU relatated things in db8500 SoC platform */ +void db8500_prcmu_init(void); + +#endif /* __PRCMU_H__ */ + -- cgit v1.2.3