From 03c609f69b12dca47b9422595fdde29be1fb35c9 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 21 Sep 2011 12:40:02 +0000 Subject: tegra2: Rename CLOCK_PLL_ID to CLOCK_ID Rename CLOCK_PLL_ID to CLOCK_ID which takes account of the fact that the code now deals with both PLL clocks and source clocks. This also tidied up the assert() to match the one sent upstream, and fixes an error in the PWM id. Signed-off-by: Simon Glass Tested-by: Tom Warren --- arch/arm/cpu/armv7/tegra2/ap20.c | 2 +- arch/arm/cpu/armv7/tegra2/clock.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/armv7/tegra2/ap20.c b/arch/arm/cpu/armv7/tegra2/ap20.c index dc5f984d6f..64d4c69d24 100644 --- a/arch/arm/cpu/armv7/tegra2/ap20.c +++ b/arch/arm/cpu/armv7/tegra2/ap20.c @@ -36,7 +36,7 @@ u32 s_first_boot = 1; void init_pllx(void) { struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - struct clk_pll *pll = &clkrst->crc_pll[CLOCK_PLL_ID_XCPU]; + struct clk_pll *pll = &clkrst->crc_pll[CLOCK_ID_XCPU]; u32 reg; /* If PLLX is already enabled, just return */ diff --git a/arch/arm/cpu/armv7/tegra2/clock.c b/arch/arm/cpu/armv7/tegra2/clock.c index 0aaed7d948..5aa64821e4 100644 --- a/arch/arm/cpu/armv7/tegra2/clock.c +++ b/arch/arm/cpu/armv7/tegra2/clock.c @@ -42,7 +42,7 @@ enum clock_osc_freq clock_get_osc_freq(void) return (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT; } -unsigned long clock_start_pll(enum clock_pll_id clkid, u32 divm, u32 divn, +unsigned long clock_start_pll(enum clock_id clkid, u32 divm, u32 divn, u32 divp, u32 cpcon, u32 lfcon) { struct clk_rst_ctlr *clkrst = @@ -50,7 +50,7 @@ unsigned long clock_start_pll(enum clock_pll_id clkid, u32 divm, u32 divn, u32 data; struct clk_pll *pll; - assert(clock_pll_id_isvalid(clkid)); + assert(clock_id_isvalid(clkid)); pll = &clkrst->crc_pll[clkid]; /* @@ -66,7 +66,7 @@ unsigned long clock_start_pll(enum clock_pll_id clkid, u32 divm, u32 divn, data = (divm << PLL_DIVM_SHIFT) | (divn << PLL_DIVN_SHIFT) | (0 << PLL_BYPASS_SHIFT) | (1 << PLL_ENABLE_SHIFT); - if (clkid == CLOCK_PLL_ID_USB) + if (clkid == CLOCK_ID_USB) data |= divp << PLLU_VCO_FREQ_SHIFT; else data |= divp << PLL_DIVP_SHIFT; -- cgit From 4ed59e70e4e0309794d532120d8c357b308b0e23 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 21 Sep 2011 12:40:04 +0000 Subject: tegra2: Add more clock functions This adds most of the clock functions required by board and driver code: -query and adjust peripheral clocks -query and adjust PLLs -reset and enable control These functions are plumbed in as required. Signed-off-by: Simon Glass Tested-by: Tom Warren --- arch/arm/cpu/armv7/tegra2/ap20.c | 3 +- arch/arm/cpu/armv7/tegra2/clock.c | 821 +++++++++++++++++++++++++++++++++++++- 2 files changed, 817 insertions(+), 7 deletions(-) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/armv7/tegra2/ap20.c b/arch/arm/cpu/armv7/tegra2/ap20.c index 64d4c69d24..5cb4b1b6a0 100644 --- a/arch/arm/cpu/armv7/tegra2/ap20.c +++ b/arch/arm/cpu/armv7/tegra2/ap20.c @@ -189,7 +189,6 @@ static void reset_A9_cpu(int reset) static void clock_enable_coresight(int enable) { - struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; u32 rst, src; clock_set_enable(PERIPH_ID_CORESIGHT, enable); @@ -203,7 +202,7 @@ static void clock_enable_coresight(int enable) * (bits 7:0), so 00000001b == 1.5 (n+1 + .5) */ src = CLK_DIVIDER(NVBL_PLLP_KHZ, 144000); - writel(src, &clkrst->crc_clk_src_csite); + clock_ll_set_source_divisor(PERIPH_ID_CSI, 0, src); /* Unlock the CPU CoreSight interfaces */ rst = 0xC5ACCE55; diff --git a/arch/arm/cpu/armv7/tegra2/clock.c b/arch/arm/cpu/armv7/tegra2/clock.c index 5aa64821e4..03ac1e3ed0 100644 --- a/arch/arm/cpu/armv7/tegra2/clock.c +++ b/arch/arm/cpu/armv7/tegra2/clock.c @@ -27,6 +27,371 @@ #include #include #include +#include + +/* + * This is our record of the current clock rate of each clock. We don't + * fill all of these in since we are only really interested in clocks which + * we use as parents. + */ +static unsigned pll_rate[CLOCK_ID_COUNT]; + +/* + * The oscillator frequency is fixed to one of four set values. Based on this + * the other clocks are set up appropriately. + */ +static unsigned osc_freq[CLOCK_OSC_FREQ_COUNT] = { + 13000000, + 19200000, + 12000000, + 26000000, +}; + +/* + * Clock types that we can use as a source. The Tegra2 has muxes for the + * peripheral clocks, and in most cases there are four options for the clock + * source. This gives us a clock 'type' and exploits what commonality exists + * in the device. + * + * Letters are obvious, except for T which means CLK_M, and S which means the + * clock derived from 32KHz. Beware that CLK_M (also called OSC in the + * datasheet) and PLL_M are different things. The former is the basic + * clock supplied to the SOC from an external oscillator. The latter is the + * memory clock PLL. + * + * See definitions in clock_id in the header file. + */ +enum clock_type_id { + CLOCK_TYPE_AXPT, /* PLL_A, PLL_X, PLL_P, CLK_M */ + CLOCK_TYPE_MCPA, /* and so on */ + CLOCK_TYPE_MCPT, + CLOCK_TYPE_PCM, + CLOCK_TYPE_PCMT, + CLOCK_TYPE_PCXTS, + CLOCK_TYPE_PDCT, + + CLOCK_TYPE_COUNT, + CLOCK_TYPE_NONE = -1, /* invalid clock type */ +}; + +/* return 1 if a peripheral ID is in range */ +#define clock_type_id_isvalid(id) ((id) >= 0 && \ + (id) < CLOCK_TYPE_COUNT) + +char pllp_valid = 1; /* PLLP is set up correctly */ + +enum { + CLOCK_MAX_MUX = 4 /* number of source options for each clock */ +}; + +/* + * Clock source mux for each clock type. This just converts our enum into + * a list of mux sources for use by the code. Note that CLOCK_TYPE_PCXTS + * is special as it has 5 sources. Since it also has a different number of + * bits in its register for the source, we just handle it with a special + * case in the code. + */ +#define CLK(x) CLOCK_ID_ ## x +static enum clock_id clock_source[CLOCK_TYPE_COUNT][CLOCK_MAX_MUX] = { + { CLK(AUDIO), CLK(XCPU), CLK(PERIPH), CLK(OSC) }, + { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(AUDIO) }, + { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(OSC) }, + { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(NONE) }, + { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC) }, + { CLK(PERIPH), CLK(CGENERAL), CLK(XCPU), CLK(OSC) }, + { CLK(PERIPH), CLK(DISPLAY), CLK(CGENERAL), CLK(OSC) }, +}; + +/* + * Clock peripheral IDs which sadly don't match up with PERIPH_ID. This is + * not in the header file since it is for purely internal use - we want + * callers to use the PERIPH_ID for all access to peripheral clocks to avoid + * confusion bewteen PERIPH_ID_... and PERIPHC_... + * + * We don't call this CLOCK_PERIPH_ID or PERIPH_CLOCK_ID as it would just be + * confusing. + * + * Note to SOC vendors: perhaps define a unified numbering for peripherals and + * use it for reset, clock enable, clock source/divider and even pinmuxing + * if you can. + */ +enum periphc_internal_id { + /* 0x00 */ + PERIPHC_I2S1, + PERIPHC_I2S2, + PERIPHC_SPDIF_OUT, + PERIPHC_SPDIF_IN, + PERIPHC_PWM, + PERIPHC_SPI1, + PERIPHC_SPI2, + PERIPHC_SPI3, + + /* 0x08 */ + PERIPHC_XIO, + PERIPHC_I2C1, + PERIPHC_DVC_I2C, + PERIPHC_TWC, + PERIPHC_0c, + PERIPHC_10, /* PERIPHC_SPI1, what is this really? */ + PERIPHC_DISP1, + PERIPHC_DISP2, + + /* 0x10 */ + PERIPHC_CVE, + PERIPHC_IDE0, + PERIPHC_VI, + PERIPHC_1c, + PERIPHC_SDMMC1, + PERIPHC_SDMMC2, + PERIPHC_G3D, + PERIPHC_G2D, + + /* 0x18 */ + PERIPHC_NDFLASH, + PERIPHC_SDMMC4, + PERIPHC_VFIR, + PERIPHC_EPP, + PERIPHC_MPE, + PERIPHC_MIPI, + PERIPHC_UART1, + PERIPHC_UART2, + + /* 0x20 */ + PERIPHC_HOST1X, + PERIPHC_21, + PERIPHC_TVO, + PERIPHC_HDMI, + PERIPHC_24, + PERIPHC_TVDAC, + PERIPHC_I2C2, + PERIPHC_EMC, + + /* 0x28 */ + PERIPHC_UART3, + PERIPHC_29, + PERIPHC_VI_SENSOR, + PERIPHC_2b, + PERIPHC_2c, + PERIPHC_SPI4, + PERIPHC_I2C3, + PERIPHC_SDMMC3, + + /* 0x30 */ + PERIPHC_UART4, + PERIPHC_UART5, + PERIPHC_VDE, + PERIPHC_OWR, + PERIPHC_NOR, + PERIPHC_CSITE, + + PERIPHC_COUNT, + + PERIPHC_NONE = -1, +}; + +/* return 1 if a periphc_internal_id is in range */ +#define periphc_internal_id_isvalid(id) ((id) >= 0 && \ + (id) < PERIPHC_COUNT) + +/* + * Clock type for each peripheral clock source. We put the name in each + * record just so it is easy to match things up + */ +#define TYPE(name, type) type +static enum clock_type_id clock_periph_type[PERIPHC_COUNT] = { + /* 0x00 */ + TYPE(PERIPHC_I2S1, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_I2S2, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_SPDIF_OUT, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_SPDIF_IN, CLOCK_TYPE_PCM), + TYPE(PERIPHC_PWM, CLOCK_TYPE_PCXTS), + TYPE(PERIPHC_SPI1, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SPI22, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SPI3, CLOCK_TYPE_PCMT), + + /* 0x08 */ + TYPE(PERIPHC_XIO, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_I2C1, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_DVC_I2C, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_TWC, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SPI1, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_DISP1, CLOCK_TYPE_PDCT), + TYPE(PERIPHC_DISP2, CLOCK_TYPE_PDCT), + + /* 0x10 */ + TYPE(PERIPHC_CVE, CLOCK_TYPE_PDCT), + TYPE(PERIPHC_IDE0, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_VI, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SDMMC1, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SDMMC2, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_G3D, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_G2D, CLOCK_TYPE_MCPA), + + /* 0x18 */ + TYPE(PERIPHC_NDFLASH, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SDMMC4, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_VFIR, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_EPP, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_MPE, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_MIPI, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_UART1, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_UART2, CLOCK_TYPE_PCMT), + + /* 0x20 */ + TYPE(PERIPHC_HOST1X, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_TVO, CLOCK_TYPE_PDCT), + TYPE(PERIPHC_HDMI, CLOCK_TYPE_PDCT), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_TVDAC, CLOCK_TYPE_PDCT), + TYPE(PERIPHC_I2C2, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_EMC, CLOCK_TYPE_MCPT), + + /* 0x28 */ + TYPE(PERIPHC_UART3, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_VI, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SPI4, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_I2C3, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SDMMC3, CLOCK_TYPE_PCMT), + + /* 0x30 */ + TYPE(PERIPHC_UART4, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_UART5, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_VDE, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_OWR, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_NOR, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_CSITE, CLOCK_TYPE_PCMT), +}; + +/* + * This array translates a periph_id to a periphc_internal_id + * + * Not present/matched up: + * uint vi_sensor; _VI_SENSOR_0, 0x1A8 + * SPDIF - which is both 0x08 and 0x0c + * + */ +#define NONE(name) (-1) +#define OFFSET(name, value) PERIPHC_ ## name +static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = { + /* Low word: 31:0 */ + NONE(CPU), + NONE(RESERVED1), + NONE(RESERVED2), + NONE(AC97), + NONE(RTC), + NONE(TMR), + PERIPHC_UART1, + PERIPHC_UART2, /* and vfir 0x68 */ + + /* 0x08 */ + NONE(GPIO), + PERIPHC_SDMMC2, + NONE(SPDIF), /* 0x08 and 0x0c, unclear which to use */ + PERIPHC_I2S1, + PERIPHC_I2C1, + PERIPHC_NDFLASH, + PERIPHC_SDMMC1, + PERIPHC_SDMMC4, + + /* 0x10 */ + PERIPHC_TWC, + PERIPHC_PWM, + PERIPHC_I2S2, + PERIPHC_EPP, + PERIPHC_VI, + PERIPHC_G2D, + NONE(USBD), + NONE(ISP), + + /* 0x18 */ + PERIPHC_G3D, + PERIPHC_IDE0, + PERIPHC_DISP2, + PERIPHC_DISP1, + PERIPHC_HOST1X, + NONE(VCP), + NONE(RESERVED30), + NONE(CACHE2), + + /* Middle word: 63:32 */ + NONE(MEM), + NONE(AHBDMA), + NONE(APBDMA), + NONE(RESERVED35), + NONE(KBC), + NONE(STAT_MON), + NONE(PMC), + NONE(FUSE), + + /* 0x28 */ + NONE(KFUSE), + NONE(SBC1), /* SBC1, 0x34, is this SPI1? */ + PERIPHC_NOR, + PERIPHC_SPI1, + PERIPHC_SPI2, + PERIPHC_XIO, + PERIPHC_SPI3, + PERIPHC_DVC_I2C, + + /* 0x30 */ + NONE(DSI), + PERIPHC_TVO, /* also CVE 0x40 */ + PERIPHC_MIPI, + PERIPHC_HDMI, + PERIPHC_CSITE, + PERIPHC_TVDAC, + PERIPHC_I2C2, + PERIPHC_UART3, + + /* 0x38 */ + NONE(RESERVED56), + PERIPHC_EMC, + NONE(USB2), + NONE(USB3), + PERIPHC_MPE, + PERIPHC_VDE, + NONE(BSEA), + NONE(BSEV), + + /* Upper word 95:64 */ + NONE(SPEEDO), + PERIPHC_UART4, + PERIPHC_UART5, + PERIPHC_I2C3, + PERIPHC_SPI4, + PERIPHC_SDMMC3, + NONE(PCIE), + PERIPHC_OWR, + + /* 0x48 */ + NONE(AFI), + NONE(CORESIGHT), + NONE(RESERVED74), + NONE(AVPUCQ), + NONE(RESERVED76), + NONE(RESERVED77), + NONE(RESERVED78), + NONE(RESERVED79), + + /* 0x50 */ + NONE(RESERVED80), + NONE(RESERVED81), + NONE(RESERVED82), + NONE(RESERVED83), + NONE(IRAMA), + NONE(IRAMB), + NONE(IRAMC), + NONE(IRAMD), + + /* 0x58 */ + NONE(CRAM2), +}; /* * Get the oscillator frequency, from the corresponding hardware configuration @@ -42,16 +407,21 @@ enum clock_osc_freq clock_get_osc_freq(void) return (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT; } -unsigned long clock_start_pll(enum clock_id clkid, u32 divm, u32 divn, - u32 divp, u32 cpcon, u32 lfcon) +/* Returns a pointer to the registers of the given pll */ +static struct clk_pll *get_pll(enum clock_id clkid) { struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 data; - struct clk_pll *pll; assert(clock_id_isvalid(clkid)); - pll = &clkrst->crc_pll[clkid]; + return &clkrst->crc_pll[clkid]; +} + +unsigned long clock_start_pll(enum clock_id clkid, u32 divm, u32 divn, + u32 divp, u32 cpcon, u32 lfcon) +{ + struct clk_pll *pll = get_pll(clkid); + u32 data; /* * We cheat by treating all PLL (except PLLU) in the same fashion. @@ -76,6 +446,294 @@ unsigned long clock_start_pll(enum clock_id clkid, u32 divm, u32 divn, return timer_get_us() + CLOCK_PLL_STABLE_DELAY_US; } +/* return 1 if a peripheral ID is in range and valid */ +static int clock_periph_id_isvalid(enum periph_id id) +{ + if (id < PERIPH_ID_FIRST || id >= PERIPH_ID_COUNT) + printf("Peripheral id %d out of range\n", id); + else { + switch (id) { + case PERIPH_ID_RESERVED1: + case PERIPH_ID_RESERVED2: + case PERIPH_ID_RESERVED30: + case PERIPH_ID_RESERVED35: + case PERIPH_ID_RESERVED56: + case PERIPH_ID_RESERVED74: + case PERIPH_ID_RESERVED76: + case PERIPH_ID_RESERVED77: + case PERIPH_ID_RESERVED78: + case PERIPH_ID_RESERVED79: + case PERIPH_ID_RESERVED80: + case PERIPH_ID_RESERVED81: + case PERIPH_ID_RESERVED82: + case PERIPH_ID_RESERVED83: + printf("Peripheral id %d is reserved\n", id); + break; + default: + return 1; + } + } + return 0; +} + +/* Returns a pointer to the clock source register for a peripheral */ +static u32 *get_periph_source_reg(enum periph_id periph_id) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + enum periphc_internal_id internal_id; + + assert(clock_periph_id_isvalid(periph_id)); + internal_id = periph_id_to_internal_id[periph_id]; + assert(internal_id != -1); + return &clkrst->crc_clk_src[internal_id]; +} + +void clock_ll_set_source_divisor(enum periph_id periph_id, unsigned source, + unsigned divisor) +{ + u32 *reg = get_periph_source_reg(periph_id); + u32 value; + + value = readl(reg); + + value &= ~OUT_CLK_SOURCE_MASK; + value |= source << OUT_CLK_SOURCE_SHIFT; + + value &= ~OUT_CLK_DIVISOR_MASK; + value |= divisor << OUT_CLK_DIVISOR_SHIFT; + + writel(value, reg); +} + +void clock_ll_set_source(enum periph_id periph_id, unsigned source) +{ + u32 *reg = get_periph_source_reg(periph_id); + + clrsetbits_le32(reg, OUT_CLK_SOURCE_MASK, + source << OUT_CLK_SOURCE_SHIFT); +} + +/** + * Given the parent's rate and the required rate for the children, this works + * out the peripheral clock divider to use, in 7.1 binary format. + * + * @param parent_rate clock rate of parent clock in Hz + * @param rate required clock rate for this clock + * @return divider which should be used + */ +static int clk_div7_1_get_divider(unsigned long parent_rate, + unsigned long rate) +{ + u64 divider = parent_rate * 2; + + divider += rate - 1; + do_div(divider, rate); + + if ((s64)divider - 2 < 0) + return 0; + + if ((s64)divider - 2 > 255) + return -1; + + return divider - 2; +} + +/** + * Given the parent's rate and the divider in 7.1 format, this works out the + * resulting peripheral clock rate. + * + * @param parent_rate clock rate of parent clock in Hz + * @param divider which should be used in 7.1 format + * @return effective clock rate of peripheral + */ +static unsigned long get_rate_from_divider(unsigned long parent_rate, + int divider) +{ + u64 rate; + + rate = (u64)parent_rate * 2; + do_div(rate, divider + 2); + return rate; +} + +unsigned long clock_get_periph_rate(enum periph_id periph_id, + enum clock_id parent) +{ + u32 *reg = get_periph_source_reg(periph_id); + + return get_rate_from_divider(pll_rate[parent], + (readl(reg) & OUT_CLK_DIVISOR_MASK) >> OUT_CLK_DIVISOR_SHIFT); +} + +/** + * Find the best available 7.1 format divisor given a parent clock rate and + * required child clock rate. This function assumes that a second-stage + * divisor is available which can divide by powers of 2 from 1 to 256. + * + * @param parent_rate clock rate of parent clock in Hz + * @param rate required clock rate for this clock + * @param extra_div value for the second-stage divisor (not set if this + * function returns -1. + * @return divider which should be used, or -1 if nothing is valid + * + */ +static int find_best_divider(unsigned long parent_rate, unsigned long rate, + int *extra_div) +{ + int shift; + int best_divider = -1; + int best_error = rate; + + /* try dividers from 1 to 256 and find closest match */ + for (shift = 0; shift <= 8 && best_error > 0; shift++) { + unsigned divided_parent = parent_rate >> shift; + int divider = clk_div7_1_get_divider(divided_parent, rate); + unsigned effective_rate = get_rate_from_divider(divided_parent, + divider); + int error = rate - effective_rate; + + /* Given a valid divider, look for the lowest error */ + if (divider != -1 && error < best_error) { + best_error = error; + *extra_div = 1 << shift; + best_divider = divider; + } + } + + /* return what we found - *extra_div will already be set */ + return best_divider; +} + +/** + * Given a peripheral ID and the required source clock, this returns which + * value should be programmed into the source mux for that peripheral. + * + * There is special code here to handle the one source type with 5 sources. + * + * @param periph_id peripheral to start + * @param source PLL id of required parent clock + * @param mux_bits Set to number of bits in mux register: 2 or 4 + * @return mux value (0-4, or -1 if not found) + */ +static int get_periph_clock_source(enum periph_id periph_id, + enum clock_id parent, int *mux_bits) +{ + enum clock_type_id type; + enum periphc_internal_id internal_id; + int mux; + + assert(clock_periph_id_isvalid(periph_id)); + + internal_id = periph_id_to_internal_id[periph_id]; + assert(periphc_internal_id_isvalid(internal_id)); + + type = clock_periph_type[internal_id]; + assert(clock_type_id_isvalid(type)); + + /* Special case here for the clock with a 4-bit source mux */ + if (type == CLOCK_TYPE_PCXTS) + *mux_bits = 4; + else + *mux_bits = 2; + + for (mux = 0; mux < CLOCK_MAX_MUX; mux++) + if (clock_source[type][mux] == parent) + return mux; + + /* + * Not found: it might be looking for the 'S' in CLOCK_TYPE_PCXTS + * which is not in our table. If not, then they are asking for a + * source which this peripheral can't access through its mux. + */ + assert(type == CLOCK_TYPE_PCXTS); + assert(parent == CLOCK_ID_SFROM32KHZ); + if (type == CLOCK_TYPE_PCXTS && parent == CLOCK_ID_SFROM32KHZ) + return 4; /* mux value for this clock */ + + /* if we get here, either us or the caller has made a mistake */ + printf("Caller requested bad clock: periph=%d, parent=%d\n", periph_id, + parent); + return -1; +} + +/** + * Adjust peripheral PLL to use the given divider and source. + * + * @param periph_id peripheral to adjust + * @param parent Required parent clock (for source mux) + * @param divider Required divider in 7.1 format + * @return 0 if ok, -1 on error (requesting a parent clock which is not valid + * for this peripheral) + */ +static int adjust_periph_pll(enum periph_id periph_id, + enum clock_id parent, unsigned divider) +{ + u32 *reg = get_periph_source_reg(periph_id); + unsigned source; + int mux_bits; + + clrsetbits_le32(reg, OUT_CLK_DIVISOR_MASK, + divider << OUT_CLK_DIVISOR_SHIFT); + udelay(1); + + /* work out the source clock and set it */ + source = get_periph_clock_source(periph_id, parent, &mux_bits); + if (source < 0) + return -1; + if (mux_bits == 4) { + clrsetbits_le32(reg, OUT_CLK_SOURCE4_MASK, + source << OUT_CLK_SOURCE4_SHIFT); + } else { + clrsetbits_le32(reg, OUT_CLK_SOURCE_MASK, + source << OUT_CLK_SOURCE_SHIFT); + } + udelay(2); + return 0; +} + +unsigned clock_adjust_periph_pll_div(enum periph_id periph_id, + enum clock_id parent, unsigned rate, int *extra_div) +{ + unsigned effective_rate; + int divider; + + if (extra_div) + divider = find_best_divider(pll_rate[parent], rate, extra_div); + else + divider = clk_div7_1_get_divider(pll_rate[parent], rate); + assert(divider >= 0); + if (adjust_periph_pll(periph_id, parent, divider)) + return -1U; + debug("periph %d, rate=%d, reg=%p = %x\n", periph_id, rate, + get_periph_source_reg(periph_id), + readl(get_periph_source_reg(periph_id))); + + /* Check what we ended up with. This shouldn't matter though */ + effective_rate = clock_get_periph_rate(periph_id, parent); + if (extra_div) + effective_rate /= *extra_div; + if (rate != effective_rate) + debug("Requested clock rate %u not honored (got %u)\n", + rate, effective_rate); + return effective_rate; +} + +unsigned clock_start_periph_pll(enum periph_id periph_id, + enum clock_id parent, unsigned rate) +{ + unsigned effective_rate; + + reset_set_enable(periph_id, 1); + clock_enable(periph_id); + + effective_rate = clock_adjust_periph_pll_div(periph_id, parent, rate, + NULL); + + reset_set_enable(periph_id, 0); + return effective_rate; +} + void clock_set_enable(enum periph_id periph_id, int enable) { struct clk_rst_ctlr *clkrst = @@ -148,3 +806,156 @@ void reset_cmplx_set_enable(int cpu, int which, int reset) else writel(mask, &clkrst->crc_cpu_cmplx_clr); } + +unsigned clock_get_rate(enum clock_id clkid) +{ + struct clk_pll *pll; + u32 base; + u32 divm; + u64 parent_rate; + u64 rate; + + parent_rate = osc_freq[clock_get_osc_freq()]; + if (clkid == CLOCK_ID_OSC) + return parent_rate; + + pll = get_pll(clkid); + base = readl(&pll->pll_base); + + /* Oh for bf_unpack()... */ + rate = parent_rate * ((base & PLL_DIVN_MASK) >> PLL_DIVN_SHIFT); + divm = (base & PLL_DIVM_MASK) >> PLL_DIVM_SHIFT; + if (clkid == CLOCK_ID_USB) + divm <<= (base & PLLU_VCO_FREQ_MASK) >> PLLU_VCO_FREQ_SHIFT; + else + divm <<= (base & PLL_DIVP_MASK) >> PLL_DIVP_SHIFT; + do_div(rate, divm); + return rate; +} + +/** + * Set the output frequency you want for each PLL clock. + * PLL output frequencies are programmed by setting their N, M and P values. + * The governing equations are: + * VCO = (Fi / m) * n, Fo = VCO / (2^p) + * where Fo is the output frequency from the PLL. + * Example: Set the output frequency to 216Mhz(Fo) with 12Mhz OSC(Fi) + * 216Mhz = ((12Mhz / m) * n) / (2^p) so n=432,m=12,p=1 + * Please see Tegra TRM section 5.3 to get the detail for PLL Programming + * + * @param n PLL feedback divider(DIVN) + * @param m PLL input divider(DIVN) + * @param p post divider(DIVP) + * @param cpcon base PLL charge pump(CPCON) + * @return 0 if ok, -1 on error (the requested PLL is incorrect and cannot + * be overriden), 1 if PLL is already correct + */ +static int clock_set_rate(enum clock_id clkid, u32 n, u32 m, u32 p, u32 cpcon) +{ + u32 base_reg; + u32 misc_reg; + struct clk_pll *pll; + + pll = get_pll(clkid); + + base_reg = readl(&pll->pll_base); + + /* Set BYPASS, m, n and p to PLL_BASE */ + base_reg &= ~PLL_DIVM_MASK; + base_reg |= m << PLL_DIVM_SHIFT; + + base_reg &= ~PLL_DIVN_MASK; + base_reg |= n << PLL_DIVN_SHIFT; + + base_reg &= ~PLL_DIVP_MASK; + base_reg |= p << PLL_DIVP_SHIFT; + + if (clkid == CLOCK_ID_PERIPH) { + /* + * If the PLL is already set up, check that it is correct + * and record this info for clock_verify() to check. + */ + if (base_reg & PLL_BASE_OVRRIDE_MASK) { + base_reg |= PLL_ENABLE_MASK; + if (base_reg != readl(&pll->pll_base)) + pllp_valid = 0; + return pllp_valid ? 1 : -1; + } + base_reg |= PLL_BASE_OVRRIDE_MASK; + } + + base_reg |= PLL_BYPASS_MASK; + writel(base_reg, &pll->pll_base); + + /* Set cpcon to PLL_MISC */ + misc_reg = readl(&pll->pll_misc); + misc_reg &= ~PLL_CPCON_MASK; + misc_reg |= cpcon << PLL_CPCON_SHIFT; + writel(misc_reg, &pll->pll_misc); + + /* Enable PLL */ + base_reg |= PLL_ENABLE_MASK; + writel(base_reg, &pll->pll_base); + + /* Disable BYPASS */ + base_reg &= ~PLL_BYPASS_MASK; + writel(base_reg, &pll->pll_base); + + return 0; +} + +int clock_verify(void) +{ + struct clk_pll *pll = get_pll(CLOCK_ID_PERIPH); + u32 reg = readl(&pll->pll_base); + + if (!pllp_valid) { + printf("Warning: PLLP %x is not correct\n", reg); + return -1; + } + debug("PLLX %x is correct\n", reg); + return 0; +} + +void clock_early_init(void) +{ + /* + * PLLP output frequency set to 216MHz + * PLLC output frequency set to 600Mhz + * + * TODO: Can we calculate these values instead of hard-coding? + */ + switch (clock_get_osc_freq()) { + case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */ + clock_set_rate(CLOCK_ID_PERIPH, 432, 12, 1, 8); + clock_set_rate(CLOCK_ID_CGENERAL, 600, 12, 0, 8); + break; + + case CLOCK_OSC_FREQ_26_0: /* OSC is 26Mhz */ + clock_set_rate(CLOCK_ID_PERIPH, 432, 26, 1, 8); + clock_set_rate(CLOCK_ID_CGENERAL, 600, 26, 0, 8); + break; + + case CLOCK_OSC_FREQ_13_0: + case CLOCK_OSC_FREQ_19_2: + default: + /* + * These are not supported. It is too early to print a + * message and the UART likely won't work anyway due to the + * oscillator being wrong. + */ + break; + } +} + +void clock_init(void) +{ + pll_rate[CLOCK_ID_MEMORY] = clock_get_rate(CLOCK_ID_MEMORY); + pll_rate[CLOCK_ID_PERIPH] = clock_get_rate(CLOCK_ID_PERIPH); + pll_rate[CLOCK_ID_CGENERAL] = clock_get_rate(CLOCK_ID_CGENERAL); + pll_rate[CLOCK_ID_OSC] = clock_get_rate(CLOCK_ID_OSC); + pll_rate[CLOCK_ID_SFROM32KHZ] = 32768; + debug("Osc = %d\n", pll_rate[CLOCK_ID_OSC]); + debug("PLLM = %d\n", pll_rate[CLOCK_ID_MEMORY]); + debug("PLLP = %d\n", pll_rate[CLOCK_ID_PERIPH]); +} -- cgit From c3cf49d247d6749bdb65d9538ecd2738195e6a21 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 21 Sep 2011 12:40:05 +0000 Subject: tegra2: Rename PIN_ to PINGRP_ The pin groupings are better named PINGRP, since on Tegra2 they refer to multiple pins. Sorry about this, but better to get it right now when there is only a small amount of code affected. Signed-off-by: Simon Glass Tested-by: Tom Warren --- arch/arm/cpu/armv7/tegra2/pinmux.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/armv7/tegra2/pinmux.c b/arch/arm/cpu/armv7/tegra2/pinmux.c index 5594ab80f6..01a3d841b8 100644 --- a/arch/arm/cpu/armv7/tegra2/pinmux.c +++ b/arch/arm/cpu/armv7/tegra2/pinmux.c @@ -27,7 +27,7 @@ #include -void pinmux_set_tristate(enum pmux_pin pin, int enable) +void pinmux_set_tristate(enum pmux_pingrp pin, int enable) { struct pmux_tri_ctlr *pmt = (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; u32 *tri = &pmt->pmt_tri[TRISTATE_REG(pin)]; @@ -41,12 +41,12 @@ void pinmux_set_tristate(enum pmux_pin pin, int enable) writel(reg, tri); } -void pinmux_tristate_enable(enum pmux_pin pin) +void pinmux_tristate_enable(enum pmux_pingrp pin) { pinmux_set_tristate(pin, 1); } -void pinmux_tristate_disable(enum pmux_pin pin) +void pinmux_tristate_disable(enum pmux_pingrp pin) { pinmux_set_tristate(pin, 0); } -- cgit From 20e18e051fc42774c27f07200a389edfd4606c67 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 21 Sep 2011 12:40:06 +0000 Subject: tegra2: Add more pinmux functions This adds support for changing pinmux functions of pin groups. This is done by defining a PMUX_FUNC_... enum which can be used to select the function for each group using pinmux_set_func(). It is also possible to enable pullup/pulldown, and the existing tristate functionality is retained. Also provided is a means of configuring a list of pingroups by providing a configuration table to pinmux_config_table(). Signed-off-by: Simon Glass Tested-by: Tom Warren --- arch/arm/cpu/armv7/tegra2/pinmux.c | 522 ++++++++++++++++++++++++++++++++++++- 1 file changed, 521 insertions(+), 1 deletion(-) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/armv7/tegra2/pinmux.c b/arch/arm/cpu/armv7/tegra2/pinmux.c index 01a3d841b8..b053f90608 100644 --- a/arch/arm/cpu/armv7/tegra2/pinmux.c +++ b/arch/arm/cpu/armv7/tegra2/pinmux.c @@ -27,9 +27,463 @@ #include +/* + * This defines the order of the pin mux control bits in the registers. For + * some reason there is no correspendence between the tristate, pin mux and + * pullup/pulldown registers. + */ +enum pmux_ctlid { + /* 0: APB_MISC_PP_PIN_MUX_CTL_A_0 */ + MUXCTL_UAA, + MUXCTL_UAB, + MUXCTL_UAC, + MUXCTL_UAD, + MUXCTL_UDA, + MUXCTL_RESERVED5, + MUXCTL_ATE, + MUXCTL_RM, + + MUXCTL_ATB, + MUXCTL_RESERVED9, + MUXCTL_ATD, + MUXCTL_ATC, + MUXCTL_ATA, + MUXCTL_KBCF, + MUXCTL_KBCE, + MUXCTL_SDMMC1, + + /* 16: APB_MISC_PP_PIN_MUX_CTL_B_0 */ + MUXCTL_GMA, + MUXCTL_GMC, + MUXCTL_HDINT, + MUXCTL_SLXA, + MUXCTL_OWC, + MUXCTL_SLXC, + MUXCTL_SLXD, + MUXCTL_SLXK, + + MUXCTL_UCA, + MUXCTL_UCB, + MUXCTL_DTA, + MUXCTL_DTB, + MUXCTL_RESERVED28, + MUXCTL_DTC, + MUXCTL_DTD, + MUXCTL_DTE, + + /* 32: APB_MISC_PP_PIN_MUX_CTL_C_0 */ + MUXCTL_DDC, + MUXCTL_CDEV1, + MUXCTL_CDEV2, + MUXCTL_CSUS, + MUXCTL_I2CP, + MUXCTL_KBCA, + MUXCTL_KBCB, + MUXCTL_KBCC, + + MUXCTL_IRTX, + MUXCTL_IRRX, + MUXCTL_DAP1, + MUXCTL_DAP2, + MUXCTL_DAP3, + MUXCTL_DAP4, + MUXCTL_GMB, + MUXCTL_GMD, + + /* 48: APB_MISC_PP_PIN_MUX_CTL_D_0 */ + MUXCTL_GME, + MUXCTL_GPV, + MUXCTL_GPU, + MUXCTL_SPDO, + MUXCTL_SPDI, + MUXCTL_SDB, + MUXCTL_SDC, + MUXCTL_SDD, + + MUXCTL_SPIH, + MUXCTL_SPIG, + MUXCTL_SPIF, + MUXCTL_SPIE, + MUXCTL_SPID, + MUXCTL_SPIC, + MUXCTL_SPIB, + MUXCTL_SPIA, + + /* 64: APB_MISC_PP_PIN_MUX_CTL_E_0 */ + MUXCTL_LPW0, + MUXCTL_LPW1, + MUXCTL_LPW2, + MUXCTL_LSDI, + MUXCTL_LSDA, + MUXCTL_LSPI, + MUXCTL_LCSN, + MUXCTL_LDC, + + MUXCTL_LSCK, + MUXCTL_LSC0, + MUXCTL_LSC1, + MUXCTL_LHS, + MUXCTL_LVS, + MUXCTL_LM0, + MUXCTL_LM1, + MUXCTL_LVP0, + + /* 80: APB_MISC_PP_PIN_MUX_CTL_F_0 */ + MUXCTL_LD0, + MUXCTL_LD1, + MUXCTL_LD2, + MUXCTL_LD3, + MUXCTL_LD4, + MUXCTL_LD5, + MUXCTL_LD6, + MUXCTL_LD7, + + MUXCTL_LD8, + MUXCTL_LD9, + MUXCTL_LD10, + MUXCTL_LD11, + MUXCTL_LD12, + MUXCTL_LD13, + MUXCTL_LD14, + MUXCTL_LD15, + + /* 96: APB_MISC_PP_PIN_MUX_CTL_G_0 */ + MUXCTL_LD16, + MUXCTL_LD17, + MUXCTL_LHP1, + MUXCTL_LHP2, + MUXCTL_LVP1, + MUXCTL_LHP0, + MUXCTL_RESERVED102, + MUXCTL_LPP, + + MUXCTL_LDI, + MUXCTL_PMC, + MUXCTL_CRTP, + MUXCTL_PTA, + MUXCTL_RESERVED108, + MUXCTL_KBCD, + MUXCTL_GPU7, + MUXCTL_DTF, + + MUXCTL_NONE = -1, +}; + +/* + * And this defines the order of the pullup/pulldown controls which are again + * in a different order + */ +enum pmux_pullid { + /* 0: APB_MISC_PP_PULLUPDOWN_REG_A_0 */ + PUCTL_ATA, + PUCTL_ATB, + PUCTL_ATC, + PUCTL_ATD, + PUCTL_ATE, + PUCTL_DAP1, + PUCTL_DAP2, + PUCTL_DAP3, + + PUCTL_DAP4, + PUCTL_DTA, + PUCTL_DTB, + PUCTL_DTC, + PUCTL_DTD, + PUCTL_DTE, + PUCTL_DTF, + PUCTL_GPV, + + /* 16: APB_MISC_PP_PULLUPDOWN_REG_B_0 */ + PUCTL_RM, + PUCTL_I2CP, + PUCTL_PTA, + PUCTL_GPU7, + PUCTL_KBCA, + PUCTL_KBCB, + PUCTL_KBCC, + PUCTL_KBCD, + + PUCTL_SPDI, + PUCTL_SPDO, + PUCTL_GPSLXAU, + PUCTL_CRTP, + PUCTL_SLXC, + PUCTL_SLXD, + PUCTL_SLXK, + + /* 32: APB_MISC_PP_PULLUPDOWN_REG_C_0 */ + PUCTL_CDEV1, + PUCTL_CDEV2, + PUCTL_SPIA, + PUCTL_SPIB, + PUCTL_SPIC, + PUCTL_SPID, + PUCTL_SPIE, + PUCTL_SPIF, + + PUCTL_SPIG, + PUCTL_SPIH, + PUCTL_IRTX, + PUCTL_IRRX, + PUCTL_GME, + PUCTL_RESERVED45, + PUCTL_XM2D, + PUCTL_XM2C, + + /* 48: APB_MISC_PP_PULLUPDOWN_REG_D_0 */ + PUCTL_UAA, + PUCTL_UAB, + PUCTL_UAC, + PUCTL_UAD, + PUCTL_UCA, + PUCTL_UCB, + PUCTL_LD17, + PUCTL_LD19_18, + + PUCTL_LD21_20, + PUCTL_LD23_22, + PUCTL_LS, + PUCTL_LC, + PUCTL_CSUS, + PUCTL_DDRC, + PUCTL_SDC, + PUCTL_SDD, + + /* 64: APB_MISC_PP_PULLUPDOWN_REG_E_0 */ + PUCTL_KBCF, + PUCTL_KBCE, + PUCTL_PMCA, + PUCTL_PMCB, + PUCTL_PMCC, + PUCTL_PMCD, + PUCTL_PMCE, + PUCTL_CK32, + + PUCTL_UDA, + PUCTL_SDMMC1, + PUCTL_GMA, + PUCTL_GMB, + PUCTL_GMC, + PUCTL_GMD, + PUCTL_DDC, + PUCTL_OWC, + + PUCTL_NONE = -1 +}; + +struct tegra_pingroup_desc { + const char *name; + enum pmux_func funcs[4]; + enum pmux_func func_safe; + enum pmux_vddio vddio; + enum pmux_ctlid ctl_id; + enum pmux_pullid pull_id; +}; + + +/* Converts a pmux_pingrp number to a tristate register: 0=A, 1=B, 2=C, 3=D */ +#define TRISTATE_REG(pmux_pingrp) ((pmux_pingrp) >> 5) + +/* Mask value for a tristate (within TRISTATE_REG(id)) */ +#define TRISTATE_MASK(pmux_pingrp) (1 << ((pmux_pingrp) & 0x1f)) + +/* Converts a PUCTL id to a pull register: 0=A, 1=B...4=E */ +#define PULL_REG(pmux_pullid) ((pmux_pullid) >> 4) + +/* Converts a PUCTL id to a shift position */ +#define PULL_SHIFT(pmux_pullid) ((pmux_pullid << 1) & 0x1f) + +/* Converts a MUXCTL id to a ctl register: 0=A, 1=B...6=G */ +#define MUXCTL_REG(pmux_ctlid) ((pmux_ctlid) >> 4) + +/* Converts a MUXCTL id to a shift position */ +#define MUXCTL_SHIFT(pmux_ctlid) ((pmux_ctlid << 1) & 0x1f) + +/* Convenient macro for defining pin group properties */ +#define PINALL(pg_name, vdd, f0, f1, f2, f3, f_safe, mux, pupd) \ + { \ + .vddio = PMUX_VDDIO_ ## vdd, \ + .funcs = { \ + PMUX_FUNC_ ## f0, \ + PMUX_FUNC_ ## f1, \ + PMUX_FUNC_ ## f2, \ + PMUX_FUNC_ ## f3, \ + }, \ + .func_safe = PMUX_FUNC_ ## f_safe, \ + .ctl_id = mux, \ + .pull_id = pupd \ + } + +/* A normal pin group where the mux name and pull-up name match */ +#define PIN(pg_name, vdd, f0, f1, f2, f3, f_safe) \ + PINALL(pg_name, vdd, f0, f1, f2, f3, f_safe, \ + MUXCTL_ ## pg_name, PUCTL_ ## pg_name) + +/* A pin group where the pull-up name doesn't have a 1-1 mapping */ +#define PINP(pg_name, vdd, f0, f1, f2, f3, f_safe, pupd) \ + PINALL(pg_name, vdd, f0, f1, f2, f3, f_safe, \ + MUXCTL_ ## pg_name, PUCTL_ ## pupd) + +/* A pin group number which is not used */ +#define PIN_RESERVED \ + PIN(NONE, NONE, NONE, NONE, NONE, NONE, NONE) + +const struct tegra_pingroup_desc tegra_soc_pingroups[PINGRP_COUNT] = { + PIN(ATA, NAND, IDE, NAND, GMI, RSVD, IDE), + PIN(ATB, NAND, IDE, NAND, GMI, SDIO4, IDE), + PIN(ATC, NAND, IDE, NAND, GMI, SDIO4, IDE), + PIN(ATD, NAND, IDE, NAND, GMI, SDIO4, IDE), + PIN(CDEV1, AUDIO, OSC, PLLA_OUT, PLLM_OUT1, AUDIO_SYNC, OSC), + PIN(CDEV2, AUDIO, OSC, AHB_CLK, APB_CLK, PLLP_OUT4, OSC), + PIN(CSUS, VI, PLLC_OUT1, PLLP_OUT2, PLLP_OUT3, VI_SENSOR_CLK, + PLLC_OUT1), + PIN(DAP1, AUDIO, DAP1, RSVD, GMI, SDIO2, DAP1), + + PIN(DAP2, AUDIO, DAP2, TWC, RSVD, GMI, DAP2), + PIN(DAP3, BB, DAP3, RSVD, RSVD, RSVD, DAP3), + PIN(DAP4, UART, DAP4, RSVD, GMI, RSVD, DAP4), + PIN(DTA, VI, RSVD, SDIO2, VI, RSVD, RSVD4), + PIN(DTB, VI, RSVD, RSVD, VI, SPI1, RSVD1), + PIN(DTC, VI, RSVD, RSVD, VI, RSVD, RSVD1), + PIN(DTD, VI, RSVD, SDIO2, VI, RSVD, RSVD1), + PIN(DTE, VI, RSVD, RSVD, VI, SPI1, RSVD1), + + PINP(GPU, UART, PWM, UARTA, GMI, RSVD, RSVD4, + GPSLXAU), + PIN(GPV, SD, PCIE, RSVD, RSVD, RSVD, PCIE), + PIN(I2CP, SYS, I2C, RSVD, RSVD, RSVD, RSVD4), + PIN(IRTX, UART, UARTA, UARTB, GMI, SPI4, UARTB), + PIN(IRRX, UART, UARTA, UARTB, GMI, SPI4, UARTB), + PIN(KBCB, SYS, KBC, NAND, SDIO2, MIO, KBC), + PIN(KBCA, SYS, KBC, NAND, SDIO2, EMC_TEST0_DLL, KBC), + PINP(PMC, SYS, PWR_ON, PWR_INTR, RSVD, RSVD, PWR_ON, NONE), + + PIN(PTA, NAND, I2C2, HDMI, GMI, RSVD, RSVD4), + PIN(RM, UART, I2C, RSVD, RSVD, RSVD, RSVD4), + PIN(KBCE, SYS, KBC, NAND, OWR, RSVD, KBC), + PIN(KBCF, SYS, KBC, NAND, TRACE, MIO, KBC), + PIN(GMA, NAND, UARTE, SPI3, GMI, SDIO4, SPI3), + PIN(GMC, NAND, UARTD, SPI4, GMI, SFLASH, SPI4), + PIN(SDMMC1, BB, SDIO1, RSVD, UARTE, UARTA, RSVD2), + PIN(OWC, SYS, OWR, RSVD, RSVD, RSVD, OWR), + + PIN(GME, NAND, RSVD, DAP5, GMI, SDIO4, GMI), + PIN(SDC, SD, PWM, TWC, SDIO3, SPI3, TWC), + PIN(SDD, SD, UARTA, PWM, SDIO3, SPI3, PWM), + PIN_RESERVED, + PINP(SLXA, SD, PCIE, SPI4, SDIO3, SPI2, PCIE, CRTP), + PIN(SLXC, SD, SPDIF, SPI4, SDIO3, SPI2, SPI4), + PIN(SLXD, SD, SPDIF, SPI4, SDIO3, SPI2, SPI4), + PIN(SLXK, SD, PCIE, SPI4, SDIO3, SPI2, PCIE), + + PIN(SPDI, AUDIO, SPDIF, RSVD, I2C, SDIO2, RSVD2), + PIN(SPDO, AUDIO, SPDIF, RSVD, I2C, SDIO2, RSVD2), + PIN(SPIA, AUDIO, SPI1, SPI2, SPI3, GMI, GMI), + PIN(SPIB, AUDIO, SPI1, SPI2, SPI3, GMI, GMI), + PIN(SPIC, AUDIO, SPI1, SPI2, SPI3, GMI, GMI), + PIN(SPID, AUDIO, SPI2, SPI1, SPI2_ALT, GMI, GMI), + PIN(SPIE, AUDIO, SPI2, SPI1, SPI2_ALT, GMI, GMI), + PIN(SPIF, AUDIO, SPI3, SPI1, SPI2, RSVD, RSVD4), + + PIN(SPIG, AUDIO, SPI3, SPI2, SPI2_ALT, I2C, SPI2_ALT), + PIN(SPIH, AUDIO, SPI3, SPI2, SPI2_ALT, I2C, SPI2_ALT), + PIN(UAA, BB, SPI3, MIPI_HS, UARTA, ULPI, MIPI_HS), + PIN(UAB, BB, SPI2, MIPI_HS, UARTA, ULPI, MIPI_HS), + PIN(UAC, BB, OWR, RSVD, RSVD, RSVD, RSVD4), + PIN(UAD, UART, IRDA, SPDIF, UARTA, SPI4, SPDIF), + PIN(UCA, UART, UARTC, RSVD, GMI, RSVD, RSVD4), + PIN(UCB, UART, UARTC, PWM, GMI, RSVD, RSVD4), + + PIN_RESERVED, + PIN(ATE, NAND, IDE, NAND, GMI, RSVD, IDE), + PIN(KBCC, SYS, KBC, NAND, TRACE, EMC_TEST1_DLL, KBC), + PIN_RESERVED, + PIN_RESERVED, + PIN(GMB, NAND, IDE, NAND, GMI, GMI_INT, GMI), + PIN(GMD, NAND, RSVD, NAND, GMI, SFLASH, GMI), + PIN(DDC, LCD, I2C2, RSVD, RSVD, RSVD, RSVD4), + + /* 64 */ + PINP(LD0, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LD17), + PINP(LD1, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LD17), + PINP(LD2, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LD17), + PINP(LD3, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LD17), + PINP(LD4, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LD17), + PINP(LD5, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LD17), + PINP(LD6, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LD17), + PINP(LD7, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LD17), + + PINP(LD8, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LD17), + PINP(LD9, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LD17), + PINP(LD10, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LD17), + PINP(LD11, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LD17), + PINP(LD12, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LD17), + PINP(LD13, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LD17), + PINP(LD14, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LD17), + PINP(LD15, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LD17), + + PINP(LD16, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LD17), + PINP(LD17, LCD, DISPA, DISPB, RSVD, RSVD, RSVD4, LD17), + PINP(LHP0, LCD, DISPA, DISPB, RSVD, RSVD, RSVD4, LD21_20), + PINP(LHP1, LCD, DISPA, DISPB, RSVD, RSVD, RSVD4, LD19_18), + PINP(LHP2, LCD, DISPA, DISPB, RSVD, RSVD, RSVD4, LD19_18), + PINP(LVP0, LCD, DISPA, DISPB, RSVD, RSVD, RSVD4, LC), + PINP(LVP1, LCD, DISPA, DISPB, RSVD, RSVD, RSVD4, LD21_20), + PINP(HDINT, LCD, HDMI, RSVD, RSVD, RSVD, HDMI , LC), + + PINP(LM0, LCD, DISPA, DISPB, SPI3, RSVD, RSVD4, LC), + PINP(LM1, LCD, DISPA, DISPB, RSVD, CRT, RSVD3, LC), + PINP(LVS, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LC), + PINP(LSC0, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LC), + PINP(LSC1, LCD, DISPA, DISPB, SPI3, HDMI, DISPA, LS), + PINP(LSCK, LCD, DISPA, DISPB, SPI3, HDMI, DISPA, LS), + PINP(LDC, LCD, DISPA, DISPB, RSVD, RSVD, RSVD4, LS), + PINP(LCSN, LCD, DISPA, DISPB, SPI3, RSVD, RSVD4, LS), + + /* 96 */ + PINP(LSPI, LCD, DISPA, DISPB, XIO, HDMI, DISPA, LC), + PINP(LSDA, LCD, DISPA, DISPB, SPI3, HDMI, DISPA, LS), + PINP(LSDI, LCD, DISPA, DISPB, SPI3, RSVD, DISPA, LS), + PINP(LPW0, LCD, DISPA, DISPB, SPI3, HDMI, DISPA, LS), + PINP(LPW1, LCD, DISPA, DISPB, RSVD, RSVD, RSVD4, LS), + PINP(LPW2, LCD, DISPA, DISPB, SPI3, HDMI, DISPA, LS), + PINP(LDI, LCD, DISPA, DISPB, RSVD, RSVD, RSVD4, LD23_22), + PINP(LHS, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LC), + + PINP(LPP, LCD, DISPA, DISPB, RSVD, RSVD, RSVD4, LD23_22), + PIN_RESERVED, + PIN(KBCD, SYS, KBC, NAND, SDIO2, MIO, KBC), + PIN(GPU7, SYS, RTCK, RSVD, RSVD, RSVD, RTCK), + PIN(DTF, VI, I2C3, RSVD, VI, RSVD, RSVD4), + PIN(UDA, BB, SPI1, RSVD, UARTD, ULPI, RSVD2), + PIN(CRTP, LCD, CRT, RSVD, RSVD, RSVD, RSVD), + PINP(SDB, SD, UARTA, PWM, SDIO3, SPI2, PWM, NONE), + + /* these pin groups only have pullup and pull down control */ + PINALL(CK32, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, MUXCTL_NONE, + PUCTL_NONE), + PINALL(DDRC, DDR, RSVD, RSVD, RSVD, RSVD, RSVD, MUXCTL_NONE, + PUCTL_NONE), + PINALL(PMCA, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, MUXCTL_NONE, + PUCTL_NONE), + PINALL(PMCB, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, MUXCTL_NONE, + PUCTL_NONE), + PINALL(PMCC, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, MUXCTL_NONE, + PUCTL_NONE), + PINALL(PMCD, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, MUXCTL_NONE, + PUCTL_NONE), + PINALL(PMCE, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, MUXCTL_NONE, + PUCTL_NONE), + PINALL(XM2C, DDR, RSVD, RSVD, RSVD, RSVD, RSVD, MUXCTL_NONE, + PUCTL_NONE), + PINALL(XM2D, DDR, RSVD, RSVD, RSVD, RSVD, RSVD, MUXCTL_NONE, + PUCTL_NONE), +}; + void pinmux_set_tristate(enum pmux_pingrp pin, int enable) { - struct pmux_tri_ctlr *pmt = (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; + struct pmux_tri_ctlr *pmt = + (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; u32 *tri = &pmt->pmt_tri[TRISTATE_REG(pin)]; u32 reg; @@ -50,3 +504,69 @@ void pinmux_tristate_disable(enum pmux_pingrp pin) { pinmux_set_tristate(pin, 0); } + +void pinmux_set_pullupdown(enum pmux_pingrp pin, enum pmux_pull pupd) +{ + struct pmux_tri_ctlr *pmt = + (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; + enum pmux_pullid pull_id = tegra_soc_pingroups[pin].pull_id; + u32 *pull = &pmt->pmt_pull[PULL_REG(pull_id)]; + u32 mask_bit; + u32 reg; + mask_bit = PULL_SHIFT(pull_id); + + reg = readl(pull); + reg &= ~(0x3 << mask_bit); + reg |= pupd << mask_bit; + writel(reg, pull); +} + +void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func) +{ + struct pmux_tri_ctlr *pmt = + (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; + enum pmux_ctlid mux_id = tegra_soc_pingroups[pin].ctl_id; + u32 *muxctl = &pmt->pmt_ctl[MUXCTL_REG(mux_id)]; + u32 mask_bit; + int i, mux = -1; + u32 reg; + + assert(pmux_func_isvalid(func)); + + /* Handle special values */ + if (func >= PMUX_FUNC_RSVD1) { + mux = (func - PMUX_FUNC_RSVD1) & 0x3; + } else { + /* Search for the appropriate function */ + for (i = 0; i < 4; i++) { + if (tegra_soc_pingroups[pin].funcs[i] == func) { + mux = i; + break; + } + } + } + assert(mux != -1); + + mask_bit = MUXCTL_SHIFT(mux_id); + reg = readl(muxctl); + reg &= ~(0x3 << mask_bit); + reg |= mux << mask_bit; + writel(reg, muxctl); +} + +void pinmux_config_pingroup(struct pingroup_config *config) +{ + enum pmux_pingrp pin = config->pingroup; + + pinmux_set_func(pin, config->func); + pinmux_set_pullupdown(pin, config->pull); + pinmux_set_tristate(pin, config->tristate); +} + +void pinmux_config_table(struct pingroup_config *config, int len) +{ + int i; + + for (i = 0; i < len; i++) + pinmux_config_pingroup(&config[i]); +} -- cgit From 47c5455a489c8e558ecb002a3a97a030ce490f9e Mon Sep 17 00:00:00 2001 From: Helmut Raiger Date: Thu, 29 Sep 2011 05:45:03 +0000 Subject: mx31: provide readable WEIM CS accessor setup_weimcs() and some macros are added to support the setup for i.MX31 WEIM chip selects. As a compromise between verbosity and readability an ASCII-art'ish bit comment is used instead of bitfields. All i.MX31 boards have been patched to use this approach using a helper program to verify the changes. Signed-off-by: Helmut Raiger Acked-by: Stefano Babic --- arch/arm/cpu/arm1136/mx31/generic.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/arm1136/mx31/generic.c b/arch/arm/cpu/arm1136/mx31/generic.c index 5524b23275..78df7b9261 100644 --- a/arch/arm/cpu/arm1136/mx31/generic.c +++ b/arch/arm/cpu/arm1136/mx31/generic.c @@ -25,6 +25,7 @@ #include #include #include +#include static u32 mx31_decode_pll(u32 reg, u32 infreq) { @@ -140,6 +141,16 @@ void mx31_set_pad(enum iomux_pins pin, u32 config) } +void mxc_setup_weimcs(int cs, const struct mxc_weimcs *weimcs) +{ + struct mx31_weim *weim = (struct mx31_weim *) WEIM_BASE; + struct mx31_weim_cscr *cscr = &weim->cscr[cs]; + + writel(weimcs->upper, &cscr->upper); + writel(weimcs->lower, &cscr->lower); + writel(weimcs->additional, &cscr->additional); +} + struct mx3_cpu_type mx31_cpu_type[] = { { .srev = 0x00, .v = 0x10 }, { .srev = 0x10, .v = 0x11 }, -- cgit From 77f11a99e14ce10ebc3b26a39a976a0827b88f86 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 13 Oct 2011 05:34:59 +0000 Subject: imx: fix coding style Fix checkpatch warning and errors in several i.MX related files. While at it also address a checkpatch warning at arch/arm/cpu/armv7/mx5/soc.c regarding the usage of extern in a C file. Signed-off-by: Fabio Estevam --- arch/arm/cpu/arm1136/mx31/timer.c | 23 ++++--- arch/arm/cpu/arm1136/mx35/generic.c | 2 +- arch/arm/cpu/arm926ejs/mx25/generic.c | 110 +++++++++++++++++----------------- arch/arm/cpu/arm926ejs/mx25/reset.c | 2 +- arch/arm/cpu/arm926ejs/mx25/timer.c | 16 ++--- arch/arm/cpu/arm926ejs/mx27/reset.c | 2 +- arch/arm/cpu/arm926ejs/mx27/timer.c | 14 ++--- arch/arm/cpu/armv7/mx5/soc.c | 10 +--- 8 files changed, 89 insertions(+), 90 deletions(-) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/arm1136/mx31/timer.c b/arch/arm/cpu/arm1136/mx31/timer.c index 717a2b72bd..f494440094 100644 --- a/arch/arm/cpu/arm1136/mx31/timer.c +++ b/arch/arm/cpu/arm1136/mx31/timer.c @@ -43,7 +43,11 @@ DECLARE_GLOBAL_DATA_PTR; -/* "time" is measured in 1 / CONFIG_SYS_HZ seconds, "tick" is internal timer period */ +/* + * "time" is measured in 1 / CONFIG_SYS_HZ seconds, + * "tick" is internal timer period + */ + #ifdef CONFIG_MX31_TIMER_HIGH_PRECISION /* ~0.4% error - measured with stop-watch on 100s boot-delay */ static inline unsigned long long tick_to_time(unsigned long long tick) @@ -68,7 +72,8 @@ static inline unsigned long long us_to_tick(unsigned long long us) } #else /* ~2% error */ -#define TICK_PER_TIME ((CONFIG_MX31_CLK32 + CONFIG_SYS_HZ / 2) / CONFIG_SYS_HZ) +#define TICK_PER_TIME ((CONFIG_MX31_CLK32 + CONFIG_SYS_HZ / 2) \ + / CONFIG_SYS_HZ) #define US_PER_TICK (1000000 / CONFIG_MX31_CLK32) static inline unsigned long long tick_to_time(unsigned long long tick) @@ -91,7 +96,7 @@ static inline unsigned long long us_to_tick(unsigned long long us) #endif /* The 32768Hz 32-bit timer overruns in 131072 seconds */ -int timer_init (void) +int timer_init(void) { int i; @@ -106,7 +111,7 @@ int timer_init (void) return 0; } -unsigned long long get_ticks (void) +unsigned long long get_ticks(void) { ulong now = GPTCNT; /* current tick value */ @@ -119,7 +124,7 @@ unsigned long long get_ticks (void) return gd->tbl; } -ulong get_timer_masked (void) +ulong get_timer_masked(void) { /* * get_ticks() returns a long long (64 bit), it wraps in @@ -130,13 +135,13 @@ ulong get_timer_masked (void) return tick_to_time(get_ticks()); } -ulong get_timer (ulong base) +ulong get_timer(ulong base) { - return get_timer_masked () - base; + return get_timer_masked() - base; } /* delay x useconds AND preserve advance timestamp value */ -void __udelay (unsigned long usec) +void __udelay(unsigned long usec) { unsigned long long tmp; ulong tmo; @@ -148,7 +153,7 @@ void __udelay (unsigned long usec) /*NOP*/; } -void reset_cpu (ulong addr) +void reset_cpu(ulong addr) { struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE; wdog->wcr = WDOG_ENABLE; diff --git a/arch/arm/cpu/arm1136/mx35/generic.c b/arch/arm/cpu/arm1136/mx35/generic.c index fcfaba5515..1b9809b2f8 100644 --- a/arch/arm/cpu/arm1136/mx35/generic.c +++ b/arch/arm/cpu/arm1136/mx35/generic.c @@ -240,7 +240,7 @@ unsigned int mxc_get_main_clock(enum mxc_main_clocks clk) } break; case IPG_CLK: - ret_val = get_ipg_clk();; + ret_val = get_ipg_clk(); break; case IPG_PER_CLK: ret_val = get_ipg_per_clk(); diff --git a/arch/arm/cpu/arm926ejs/mx25/generic.c b/arch/arm/cpu/arm926ejs/mx25/generic.c index 8e60a262eb..c045a0bc58 100644 --- a/arch/arm/cpu/arm926ejs/mx25/generic.c +++ b/arch/arm/cpu/arm926ejs/mx25/generic.c @@ -39,7 +39,7 @@ * f = 2 * f_ref * -------------------- * pd + 1 */ -static unsigned int imx_decode_pll (unsigned int pll, unsigned int f_ref) +static unsigned int imx_decode_pll(unsigned int pll, unsigned int f_ref) { unsigned int mfi = (pll >> CCM_PLL_MFI_SHIFT) & CCM_PLL_MFI_MASK; @@ -52,57 +52,57 @@ static unsigned int imx_decode_pll (unsigned int pll, unsigned int f_ref) mfi = mfi <= 5 ? 5 : mfi; - return lldiv (2 * (u64) f_ref * (mfi * (mfd + 1) + mfn), + return lldiv(2 * (u64) f_ref * (mfi * (mfd + 1) + mfn), (mfd + 1) * (pd + 1)); } -static ulong imx_get_mpllclk (void) +static ulong imx_get_mpllclk(void) { struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE; ulong fref = 24000000; - return imx_decode_pll (readl (&ccm->mpctl), fref); + return imx_decode_pll(readl(&ccm->mpctl), fref); } -ulong imx_get_armclk (void) +ulong imx_get_armclk(void) { struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE; - ulong cctl = readl (&ccm->cctl); - ulong fref = imx_get_mpllclk (); + ulong cctl = readl(&ccm->cctl); + ulong fref = imx_get_mpllclk(); ulong div; if (cctl & CCM_CCTL_ARM_SRC) - fref = lldiv ((fref * 3), 4); + fref = lldiv((fref * 3), 4); div = ((cctl >> CCM_CCTL_ARM_DIV_SHIFT) & CCM_CCTL_ARM_DIV_MASK) + 1; - return lldiv (fref, div); + return lldiv(fref, div); } -ulong imx_get_ahbclk (void) +ulong imx_get_ahbclk(void) { struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE; - ulong cctl = readl (&ccm->cctl); - ulong fref = imx_get_armclk (); + ulong cctl = readl(&ccm->cctl); + ulong fref = imx_get_armclk(); ulong div; div = ((cctl >> CCM_CCTL_AHB_DIV_SHIFT) & CCM_CCTL_AHB_DIV_MASK) + 1; - return lldiv (fref, div); + return lldiv(fref, div); } -ulong imx_get_perclk (int clk) +ulong imx_get_perclk(int clk) { struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE; - ulong fref = imx_get_ahbclk (); + ulong fref = imx_get_ahbclk(); ulong div; - div = readl (&ccm->pcdr[CCM_PERCLK_REG (clk)]); - div = ((div >> CCM_PERCLK_SHIFT (clk)) & CCM_PERCLK_MASK) + 1; + div = readl(&ccm->pcdr[CCM_PERCLK_REG(clk)]); + div = ((div >> CCM_PERCLK_SHIFT(clk)) & CCM_PERCLK_MASK) + 1; - return lldiv (fref, div); + return lldiv(fref, div); } u32 get_cpu_rev(void) @@ -153,7 +153,7 @@ static char *get_reset_cause(void) } -int print_cpuinfo (void) +int print_cpuinfo(void) { char buf[32]; u32 cpurev = get_cpu_rev(); @@ -161,22 +161,22 @@ int print_cpuinfo (void) printf("CPU: Freescale i.MX25 rev%d.%d%s at %s MHz\n", (cpurev & 0xF0) >> 4, (cpurev & 0x0F), ((cpurev & 0x8000) ? " unknown" : ""), - strmhz (buf, imx_get_armclk ())); + strmhz(buf, imx_get_armclk())); printf("Reset cause: %s\n\n", get_reset_cause()); return 0; } #endif -int cpu_eth_init (bd_t * bis) +int cpu_eth_init(bd_t *bis) { #if defined(CONFIG_FEC_MXC) struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE; ulong val; - val = readl (&ccm->cgr0); + val = readl(&ccm->cgr0); val |= (1 << 23); - writel (val, &ccm->cgr0); - return fecmxc_initialize (bis); + writel(val, &ccm->cgr0); + return fecmxc_initialize(bis); #else return 0; #endif @@ -186,10 +186,10 @@ int cpu_eth_init (bd_t * bis) * Initializes on-chip MMC controllers. * to override, implement board_mmc_init() */ -int cpu_mmc_init (bd_t * bis) +int cpu_mmc_init(bd_t *bis) { #ifdef CONFIG_MXC_MMC - return mxc_mmc_init (bis); + return mxc_mmc_init(bis); #else return 0; #endif @@ -206,7 +206,7 @@ void mx25_uart1_init_pins(void) muxctl = (struct iomuxc_mux_ctl *)IMX_IOPADMUX_BASE; padctl = (struct iomuxc_pad_ctl *)IMX_IOPADCTL_BASE; - muxmode0 = MX25_PIN_MUX_MODE (0); + muxmode0 = MX25_PIN_MUX_MODE(0); /* * set up input pins with hysteresis and 100K pull-ups */ @@ -227,25 +227,25 @@ void mx25_uart1_init_pins(void) /* UART1 */ /* rxd */ - writel (muxmode0, &muxctl->pad_uart1_rxd); - writel (inpadctl, &padctl->pad_uart1_rxd); + writel(muxmode0, &muxctl->pad_uart1_rxd); + writel(inpadctl, &padctl->pad_uart1_rxd); /* txd */ - writel (muxmode0, &muxctl->pad_uart1_txd); - writel (outpadctl, &padctl->pad_uart1_txd); + writel(muxmode0, &muxctl->pad_uart1_txd); + writel(outpadctl, &padctl->pad_uart1_txd); /* rts */ - writel (muxmode0, &muxctl->pad_uart1_rts); - writel (outpadctl, &padctl->pad_uart1_rts); + writel(muxmode0, &muxctl->pad_uart1_rts); + writel(outpadctl, &padctl->pad_uart1_rts); /* cts */ - writel (muxmode0, &muxctl->pad_uart1_cts); - writel (inpadctl, &padctl->pad_uart1_cts); + writel(muxmode0, &muxctl->pad_uart1_cts); + writel(inpadctl, &padctl->pad_uart1_cts); } #endif /* CONFIG_MXC_UART */ #ifdef CONFIG_FEC_MXC -void mx25_fec_init_pins (void) +void mx25_fec_init_pins(void) { struct iomuxc_mux_ctl *muxctl; struct iomuxc_pad_ctl *padctl; @@ -256,7 +256,7 @@ void mx25_fec_init_pins (void) muxctl = (struct iomuxc_mux_ctl *)IMX_IOPADMUX_BASE; padctl = (struct iomuxc_pad_ctl *)IMX_IOPADCTL_BASE; - muxmode0 = MX25_PIN_MUX_MODE (0); + muxmode0 = MX25_PIN_MUX_MODE(0); inpadctl_100kpd = MX25_PIN_PAD_CTL_HYS | MX25_PIN_PAD_CTL_PKE | MX25_PIN_PAD_CTL_PUE | MX25_PIN_PAD_CTL_100K_PD; @@ -275,40 +275,40 @@ void mx25_fec_init_pins (void) outpadctl = MX25_PIN_PAD_CTL_PUE | MX25_PIN_PAD_CTL_100K_PD; /* FEC_TX_CLK */ - writel (muxmode0, &muxctl->pad_fec_tx_clk); - writel (inpadctl_100kpd, &padctl->pad_fec_tx_clk); + writel(muxmode0, &muxctl->pad_fec_tx_clk); + writel(inpadctl_100kpd, &padctl->pad_fec_tx_clk); /* FEC_RX_DV */ - writel (muxmode0, &muxctl->pad_fec_rx_dv); - writel (inpadctl_100kpd, &padctl->pad_fec_rx_dv); + writel(muxmode0, &muxctl->pad_fec_rx_dv); + writel(inpadctl_100kpd, &padctl->pad_fec_rx_dv); /* FEC_RDATA0 */ - writel (muxmode0, &muxctl->pad_fec_rdata0); - writel (inpadctl_100kpd, &padctl->pad_fec_rdata0); + writel(muxmode0, &muxctl->pad_fec_rdata0); + writel(inpadctl_100kpd, &padctl->pad_fec_rdata0); /* FEC_TDATA0 */ - writel (muxmode0, &muxctl->pad_fec_tdata0); - writel (outpadctl, &padctl->pad_fec_tdata0); + writel(muxmode0, &muxctl->pad_fec_tdata0); + writel(outpadctl, &padctl->pad_fec_tdata0); /* FEC_TX_EN */ - writel (muxmode0, &muxctl->pad_fec_tx_en); - writel (outpadctl, &padctl->pad_fec_tx_en); + writel(muxmode0, &muxctl->pad_fec_tx_en); + writel(outpadctl, &padctl->pad_fec_tx_en); /* FEC_MDC */ - writel (muxmode0, &muxctl->pad_fec_mdc); - writel (outpadctl, &padctl->pad_fec_mdc); + writel(muxmode0, &muxctl->pad_fec_mdc); + writel(outpadctl, &padctl->pad_fec_mdc); /* FEC_MDIO */ - writel (muxmode0, &muxctl->pad_fec_mdio); - writel (inpadctl_22kpu, &padctl->pad_fec_mdio); + writel(muxmode0, &muxctl->pad_fec_mdio); + writel(inpadctl_22kpu, &padctl->pad_fec_mdio); /* FEC_RDATA1 */ - writel (muxmode0, &muxctl->pad_fec_rdata1); - writel (inpadctl_100kpd, &padctl->pad_fec_rdata1); + writel(muxmode0, &muxctl->pad_fec_rdata1); + writel(inpadctl_100kpd, &padctl->pad_fec_rdata1); /* FEC_TDATA1 */ - writel (muxmode0, &muxctl->pad_fec_tdata1); - writel (outpadctl, &padctl->pad_fec_tdata1); + writel(muxmode0, &muxctl->pad_fec_tdata1); + writel(outpadctl, &padctl->pad_fec_tdata1); } diff --git a/arch/arm/cpu/arm926ejs/mx25/reset.c b/arch/arm/cpu/arm926ejs/mx25/reset.c index 1a43683081..e6f1056670 100644 --- a/arch/arm/cpu/arm926ejs/mx25/reset.c +++ b/arch/arm/cpu/arm926ejs/mx25/reset.c @@ -39,7 +39,7 @@ /* * Reset the cpu by setting up the watchdog timer and let it time out */ -void reset_cpu (ulong ignored) +void reset_cpu(ulong ignored) { struct wdog_regs *regs = (struct wdog_regs *)IMX_WDT_BASE; /* Disable watchdog and set Time-Out field to 0 */ diff --git a/arch/arm/cpu/arm926ejs/mx25/timer.c b/arch/arm/cpu/arm926ejs/mx25/timer.c index 5eb2747122..1cfd02b230 100644 --- a/arch/arm/cpu/arm926ejs/mx25/timer.c +++ b/arch/arm/cpu/arm926ejs/mx25/timer.c @@ -15,7 +15,7 @@ * * (C) Copyright 2009 DENX Software Engineering * Author: John Rigby - * Add support for MX25 + * Add support for MX25 * * See file CREDITS for list of people who contributed to this * project. @@ -43,8 +43,8 @@ DECLARE_GLOBAL_DATA_PTR; -#define timestamp gd->tbl -#define lastinc gd->lastinc +#define timestamp (gd->tbl) +#define lastinc (gd->lastinc) /* * "time" is measured in 1 / CONFIG_SYS_HZ seconds, @@ -121,7 +121,7 @@ int timer_init(void) return 0; } -unsigned long long get_ticks (void) +unsigned long long get_ticks(void) { struct gpt_regs *gpt = (struct gpt_regs *)IMX_GPT1_BASE; ulong now = readl(&gpt->counter); /* current tick value */ @@ -140,7 +140,7 @@ unsigned long long get_ticks (void) return timestamp; } -ulong get_timer_masked (void) +ulong get_timer_masked(void) { /* * get_ticks() returns a long long (64 bit), it wraps in @@ -151,13 +151,13 @@ ulong get_timer_masked (void) return tick_to_time(get_ticks()); } -ulong get_timer (ulong base) +ulong get_timer(ulong base) { - return get_timer_masked () - base; + return get_timer_masked() - base; } /* delay x useconds AND preserve advance timstamp value */ -void __udelay (unsigned long usec) +void __udelay(unsigned long usec) { unsigned long long tmp; ulong tmo; diff --git a/arch/arm/cpu/arm926ejs/mx27/reset.c b/arch/arm/cpu/arm926ejs/mx27/reset.c index 6c54eafd37..cc0a33ed55 100644 --- a/arch/arm/cpu/arm926ejs/mx27/reset.c +++ b/arch/arm/cpu/arm926ejs/mx27/reset.c @@ -39,7 +39,7 @@ /* * Reset the cpu by setting up the watchdog timer and let it time out */ -void reset_cpu (ulong ignored) +void reset_cpu(ulong ignored) { struct wdog_regs *regs = (struct wdog_regs *)IMX_WDT_BASE; /* Disable watchdog and set Time-Out field to 0 */ diff --git a/arch/arm/cpu/arm926ejs/mx27/timer.c b/arch/arm/cpu/arm926ejs/mx27/timer.c index df76d16810..5af935976e 100644 --- a/arch/arm/cpu/arm926ejs/mx27/timer.c +++ b/arch/arm/cpu/arm926ejs/mx27/timer.c @@ -45,8 +45,8 @@ DECLARE_GLOBAL_DATA_PTR; -#define timestamp gd->tbl -#define lastinc gd->lastinc +#define timestamp (gd->tbl) +#define lastinc (gd->lastinc) /* * "time" is measured in 1 / CONFIG_SYS_HZ seconds, @@ -124,7 +124,7 @@ int timer_init(void) return 0; } -unsigned long long get_ticks (void) +unsigned long long get_ticks(void) { struct gpt_regs *regs = (struct gpt_regs *)IMX_TIM1_BASE; ulong now = readl(®s->gpt_tcn); /* current tick value */ @@ -143,7 +143,7 @@ unsigned long long get_ticks (void) return timestamp; } -ulong get_timer_masked (void) +ulong get_timer_masked(void) { /* * get_ticks() returns a long long (64 bit), it wraps in @@ -154,13 +154,13 @@ ulong get_timer_masked (void) return tick_to_time(get_ticks()); } -ulong get_timer (ulong base) +ulong get_timer(ulong base) { - return get_timer_masked () - base; + return get_timer_masked() - base; } /* delay x useconds AND preserve advance timstamp value */ -void __udelay (unsigned long usec) +void __udelay(unsigned long usec) { unsigned long long tmp; ulong tmo; diff --git a/arch/arm/cpu/armv7/mx5/soc.c b/arch/arm/cpu/armv7/mx5/soc.c index c6106d5210..cf12ba88f4 100644 --- a/arch/arm/cpu/armv7/mx5/soc.c +++ b/arch/arm/cpu/armv7/mx5/soc.c @@ -26,6 +26,8 @@ #include #include #include +#include + #include #include @@ -117,14 +119,6 @@ int print_cpuinfo(void) } #endif -/* - * Initializes on-chip ethernet controllers. - * to override, implement board_eth_init() - */ -#if defined(CONFIG_FEC_MXC) -extern int fecmxc_initialize(bd_t *bis); -#endif - int cpu_eth_init(bd_t *bis) { int rc = -ENODEV; -- cgit From 2e0c1c7d5cafb92f7bee9c8ac4b69f5bed075c67 Mon Sep 17 00:00:00 2001 From: Jason Cooper <[u-boot@lakedaemon.net]> Date: Mon, 3 Oct 2011 13:49:53 +0530 Subject: dreamplug: initial board support. Copied wholeheartedly from board/Marvell/guruplug and modified to add support for SPI NOR flash. CONFIG_MACH_DREAMPLUG defined in include/configs/dreamplug.h until Linus's kernel.org tree adds it to mach-types.h. Once it trickles down, the definition can be removed from include/configs/dreamplug.h. Signed-off-by: Jason Cooper --- arch/arm/cpu/arm926ejs/kirkwood/asm-offsets.s | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 arch/arm/cpu/arm926ejs/kirkwood/asm-offsets.s (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/arm926ejs/kirkwood/asm-offsets.s b/arch/arm/cpu/arm926ejs/kirkwood/asm-offsets.s new file mode 100644 index 0000000000..e69de29bb2 -- cgit From 0c0d9b708be45184f74b8b497d15b60c538caccf Mon Sep 17 00:00:00 2001 From: Lei Wen <[leiwen@marvell.com]> Date: Tue, 18 Oct 2011 19:21:33 +0530 Subject: ARM: pantheon: reduce dependence of including platform file For files like the drivers/serial/serial.c, it must include the platform file, as the CONFIG_SYS_NS16550_COM1 must reference to the definition in the platform definition files. Include the platform definition file in the config file, so that it would decouple the dependence for the driver files. Signed-off-by: Lei Wen --- arch/arm/cpu/arm926ejs/pantheon/cpu.c | 2 +- arch/arm/cpu/arm926ejs/pantheon/dram.c | 1 + arch/arm/cpu/arm926ejs/pantheon/timer.c | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/arm926ejs/pantheon/cpu.c b/arch/arm/cpu/arm926ejs/pantheon/cpu.c index 8b2eafa40b..efc9395b96 100644 --- a/arch/arm/cpu/arm926ejs/pantheon/cpu.c +++ b/arch/arm/cpu/arm926ejs/pantheon/cpu.c @@ -23,8 +23,8 @@ */ #include +#include #include -#include #define UARTCLK14745KHZ (APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(1)) #define SET_MRVL_ID (1<<8) diff --git a/arch/arm/cpu/arm926ejs/pantheon/dram.c b/arch/arm/cpu/arm926ejs/pantheon/dram.c index bbca7eef16..a3d719e5cf 100644 --- a/arch/arm/cpu/arm926ejs/pantheon/dram.c +++ b/arch/arm/cpu/arm926ejs/pantheon/dram.c @@ -23,6 +23,7 @@ */ #include +#include #include DECLARE_GLOBAL_DATA_PTR; diff --git a/arch/arm/cpu/arm926ejs/pantheon/timer.c b/arch/arm/cpu/arm926ejs/pantheon/timer.c index c71162a8be..17045b1c2f 100644 --- a/arch/arm/cpu/arm926ejs/pantheon/timer.c +++ b/arch/arm/cpu/arm926ejs/pantheon/timer.c @@ -23,6 +23,7 @@ */ #include +#include #include /* -- cgit From ab1b95521174e6705abec72c5f1756e8cdb22016 Mon Sep 17 00:00:00 2001 From: Lei Wen <[leiwen@marvell.com]> Date: Tue, 18 Oct 2011 19:50:48 +0530 Subject: ARM: armada100: reduce dependence of including platform file For files like the drivers/serial/serial.c, it must include the platform file, as the CONFIG_SYS_NS16550_COM1 must reference to the definition in the platform definition files. Include the platform definition file in the config file, so that it would decouple the dependence for the driver files. Updated cpu.h to remove build errors for gplugd board (by prafulla) Signed-off-by: Lei Wen Signed-off-by: Prafulla Wadaskar --- arch/arm/cpu/arm926ejs/armada100/cpu.c | 2 +- arch/arm/cpu/arm926ejs/armada100/dram.c | 1 + arch/arm/cpu/arm926ejs/armada100/timer.c | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/arm926ejs/armada100/cpu.c b/arch/arm/cpu/arm926ejs/armada100/cpu.c index c21938e31f..14121a08f8 100644 --- a/arch/arm/cpu/arm926ejs/armada100/cpu.c +++ b/arch/arm/cpu/arm926ejs/armada100/cpu.c @@ -24,8 +24,8 @@ */ #include +#include #include -#include #define UARTCLK14745KHZ (APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(1)) #define SET_MRVL_ID (1<<8) diff --git a/arch/arm/cpu/arm926ejs/armada100/dram.c b/arch/arm/cpu/arm926ejs/armada100/dram.c index eacec2386d..8609004565 100644 --- a/arch/arm/cpu/arm926ejs/armada100/dram.c +++ b/arch/arm/cpu/arm926ejs/armada100/dram.c @@ -24,6 +24,7 @@ */ #include +#include #include DECLARE_GLOBAL_DATA_PTR; diff --git a/arch/arm/cpu/arm926ejs/armada100/timer.c b/arch/arm/cpu/arm926ejs/armada100/timer.c index 82a6d7b72d..fbade4b459 100644 --- a/arch/arm/cpu/arm926ejs/armada100/timer.c +++ b/arch/arm/cpu/arm926ejs/armada100/timer.c @@ -24,6 +24,7 @@ */ #include +#include #include /* -- cgit From a7efd719f415833a833d6a8e46bcd470a0847ecc Mon Sep 17 00:00:00 2001 From: Lei Wen <[leiwen@marvell.com]> Date: Tue, 18 Oct 2011 20:11:42 +0530 Subject: ARM: kirkwood: reduce dependence of including platform file For files like the drivers/serial/serial.c, it must include the platform file, as the CONFIG_SYS_NS16550_COM1 must reference to the definition in the platform definition files. Include the platform definition file in the config file, so that it would decouple the dependence for the driver files. Signed-off-by: Lei Wen --- arch/arm/cpu/arm926ejs/kirkwood/cpu.c | 2 ++ arch/arm/cpu/arm926ejs/kirkwood/dram.c | 2 ++ arch/arm/cpu/arm926ejs/kirkwood/mpp.c | 2 ++ arch/arm/cpu/arm926ejs/kirkwood/timer.c | 1 + 4 files changed, 7 insertions(+) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/arm926ejs/kirkwood/cpu.c b/arch/arm/cpu/arm926ejs/kirkwood/cpu.c index b4a4c0428f..8f04ddbb86 100644 --- a/arch/arm/cpu/arm926ejs/kirkwood/cpu.c +++ b/arch/arm/cpu/arm926ejs/kirkwood/cpu.c @@ -26,6 +26,8 @@ #include #include #include +#include +#include #include #include diff --git a/arch/arm/cpu/arm926ejs/kirkwood/dram.c b/arch/arm/cpu/arm926ejs/kirkwood/dram.c index 2441554ae3..181b3e7bd3 100644 --- a/arch/arm/cpu/arm926ejs/kirkwood/dram.c +++ b/arch/arm/cpu/arm926ejs/kirkwood/dram.c @@ -24,6 +24,8 @@ #include #include +#include +#include #include DECLARE_GLOBAL_DATA_PTR; diff --git a/arch/arm/cpu/arm926ejs/kirkwood/mpp.c b/arch/arm/cpu/arm926ejs/kirkwood/mpp.c index b2f0ad55e3..3da6c98d11 100644 --- a/arch/arm/cpu/arm926ejs/kirkwood/mpp.c +++ b/arch/arm/cpu/arm926ejs/kirkwood/mpp.c @@ -10,6 +10,8 @@ */ #include +#include +#include #include #include diff --git a/arch/arm/cpu/arm926ejs/kirkwood/timer.c b/arch/arm/cpu/arm926ejs/kirkwood/timer.c index b4f6cf87e0..a98f54c05b 100644 --- a/arch/arm/cpu/arm926ejs/kirkwood/timer.c +++ b/arch/arm/cpu/arm926ejs/kirkwood/timer.c @@ -22,6 +22,7 @@ */ #include +#include #include #define UBOOT_CNTR 0 /* counter to use for uboot timer */ -- cgit From 5ff8b35412e895287d91172c9ac3b60520d41ddb Mon Sep 17 00:00:00 2001 From: Lei Wen Date: Mon, 24 Oct 2011 16:27:32 +0000 Subject: ARM: orion5x: reduce dependence of including platform file For files like the drivers/serial/serial.c, it must include the platform file, as the CONFIG_SYS_NS16550_COM1 must reference to the definition in the platform definition files. Include the platform definition file in the config file, so that it would decouple the dependence for the driver files. Signed-off-by: Lei Wen --- arch/arm/cpu/arm926ejs/orion5x/cpu.c | 3 ++- arch/arm/cpu/arm926ejs/orion5x/dram.c | 2 +- arch/arm/cpu/arm926ejs/orion5x/timer.c | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/arm926ejs/orion5x/cpu.c b/arch/arm/cpu/arm926ejs/orion5x/cpu.c index 05bd45c3f6..792b11dfc5 100644 --- a/arch/arm/cpu/arm926ejs/orion5x/cpu.c +++ b/arch/arm/cpu/arm926ejs/orion5x/cpu.c @@ -28,8 +28,9 @@ #include #include #include +#include #include -#include +#include #include #define BUFLEN 16 diff --git a/arch/arm/cpu/arm926ejs/orion5x/dram.c b/arch/arm/cpu/arm926ejs/orion5x/dram.c index 5cc31a99f1..c0f7ef157f 100644 --- a/arch/arm/cpu/arm926ejs/orion5x/dram.c +++ b/arch/arm/cpu/arm926ejs/orion5x/dram.c @@ -27,7 +27,7 @@ #include #include -#include +#include DECLARE_GLOBAL_DATA_PTR; diff --git a/arch/arm/cpu/arm926ejs/orion5x/timer.c b/arch/arm/cpu/arm926ejs/orion5x/timer.c index 17df68f86a..e39ecc245b 100644 --- a/arch/arm/cpu/arm926ejs/orion5x/timer.c +++ b/arch/arm/cpu/arm926ejs/orion5x/timer.c @@ -25,7 +25,7 @@ */ #include -#include +#include #define UBOOT_CNTR 0 /* counter to use for uboot timer */ -- cgit From 20033c9f87ef6aa9834aeab19bc363abc3d92a4d Mon Sep 17 00:00:00 2001 From: Ricardo Salveti de Araujo Date: Wed, 21 Sep 2011 10:17:29 +0000 Subject: omap4: replacing OMAP4_CONTROL with OMAP4430_CONTROL OMAP4460 has a different set of values for the ID code, so moving the old ones to be related just with 4430. Signed-off-by: Ricardo Salveti de Araujo Signed-off-by: Sandeep Paulraj --- arch/arm/cpu/armv7/omap4/board.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/armv7/omap4/board.c b/arch/arm/cpu/armv7/omap4/board.c index 8584fdd590..86ddef28d7 100644 --- a/arch/arm/cpu/armv7/omap4/board.c +++ b/arch/arm/cpu/armv7/omap4/board.c @@ -200,13 +200,13 @@ static void init_omap4_revision(void) break; case MIDR_CORTEX_A9_R1P2: switch (readl(CONTROL_ID_CODE)) { - case OMAP4_CONTROL_ID_CODE_ES2_0: + case OMAP4430_CONTROL_ID_CODE_ES2_0: *omap4_revision = OMAP4430_ES2_0; break; - case OMAP4_CONTROL_ID_CODE_ES2_1: + case OMAP4430_CONTROL_ID_CODE_ES2_1: *omap4_revision = OMAP4430_ES2_1; break; - case OMAP4_CONTROL_ID_CODE_ES2_2: + case OMAP4430_CONTROL_ID_CODE_ES2_2: *omap4_revision = OMAP4430_ES2_2; break; default: -- cgit From 8f6a027f627d6002bedc3ab12610535dbf9ef497 Mon Sep 17 00:00:00 2001 From: Ricardo Salveti de Araujo Date: Wed, 21 Sep 2011 10:17:30 +0000 Subject: omap4: adding revision detection for 4460 ES1.1 Signed-off-by: Ricardo Salveti de Araujo 2 files changed, 17 insertions(+), 1 deletions(-) Signed-off-by: Sandeep Paulraj --- arch/arm/cpu/armv7/omap4/board.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/armv7/omap4/board.c b/arch/arm/cpu/armv7/omap4/board.c index 86ddef28d7..6d8811f484 100644 --- a/arch/arm/cpu/armv7/omap4/board.c +++ b/arch/arm/cpu/armv7/omap4/board.c @@ -218,7 +218,17 @@ static void init_omap4_revision(void) *omap4_revision = OMAP4430_ES2_3; break; case MIDR_CORTEX_A9_R2P10: - *omap4_revision = OMAP4460_ES1_0; + switch (readl(CONTROL_ID_CODE)) { + case OMAP4460_CONTROL_ID_CODE_ES1_0: + *omap4_revision = OMAP4460_ES1_0; + break; + case OMAP4460_CONTROL_ID_CODE_ES1_1: + *omap4_revision = OMAP4460_ES1_1; + break; + default: + *omap4_revision = OMAP4460_ES1_0; + break; + } break; default: *omap4_revision = OMAP4430_SILICON_ID_INVALID; -- cgit From 53430a4f251eacc32ada54b56258cc18856d0d8e Mon Sep 17 00:00:00 2001 From: Ricardo Salveti de Araujo Date: Wed, 21 Sep 2011 10:17:31 +0000 Subject: omap4: splitting padconfs into common, 4430 and 4460 Not all padconfs are the same between 4430 and 4460, so instead of working around this with an if, we should have an specific padconf structure for both chips (like handling the differences between the LEDs GPIOs and TPS). Signed-off-by: Ricardo Salveti de Araujo Signed-off-by: Sandeep Paulraj --- arch/arm/cpu/armv7/omap4/board.c | 6 ++++-- arch/arm/cpu/armv7/omap4/omap4_mux_data.h | 7 +++++++ 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/armv7/omap4/board.c b/arch/arm/cpu/armv7/omap4/board.c index 6d8811f484..2497e3e729 100644 --- a/arch/arm/cpu/armv7/omap4/board.c +++ b/arch/arm/cpu/armv7/omap4/board.c @@ -152,9 +152,11 @@ static void set_muxconf_regs_essential(void) sizeof(wkup_padconf_array_essential) / sizeof(struct pad_conf_entry)); - /* gpio_wk7 is used for controlling TPS on 4460 */ if (omap_revision() >= OMAP4460_ES1_0) - writew(M3, CONTROL_WKUP_PAD1_FREF_CLK4_REQ); + do_set_mux(CONTROL_PADCONF_WKUP, + wkup_padconf_array_essential_4460, + sizeof(wkup_padconf_array_essential_4460) / + sizeof(struct pad_conf_entry)); } static void set_mux_conf_regs(void) diff --git a/arch/arm/cpu/armv7/omap4/omap4_mux_data.h b/arch/arm/cpu/armv7/omap4/omap4_mux_data.h index 00c52f835f..b9403910c9 100644 --- a/arch/arm/cpu/armv7/omap4/omap4_mux_data.h +++ b/arch/arm/cpu/armv7/omap4/omap4_mux_data.h @@ -73,4 +73,11 @@ const struct pad_conf_entry wkup_padconf_array_essential[] = { }; +const struct pad_conf_entry wkup_padconf_array_essential_4460[] = { + +{PAD1_FREF_CLK4_REQ, (M3)}, /* gpio_wk7, TPS */ + +}; + + #endif /* _OMAP4_MUX_DATA_H_ */ -- cgit From 9e2538e11fc87fb51cfde707fd5ffae086f1b467 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Fri, 23 Sep 2011 04:29:15 +0000 Subject: DaVinci: correct MDSTAT.STATE mask MDSTAT.STATE occupies bits 0..5 according to all available documentation, so fix the mask which previously was leaving out the intermediate state indicator bit. While at it, introduce two #define's for that mask -- unfortunately, we can't use a single #define as the assembly code can't include due to C-specfic constructs in it. Signed-off-by: Sergei Shtylyov Signed-off-by: Sandeep Paulraj --- arch/arm/cpu/arm926ejs/davinci/lowlevel_init.S | 8 +++++--- arch/arm/cpu/arm926ejs/davinci/psc.c | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/arm926ejs/davinci/lowlevel_init.S b/arch/arm/cpu/arm926ejs/davinci/lowlevel_init.S index 0a4b2cf674..7a169b1076 100644 --- a/arch/arm/cpu/arm926ejs/davinci/lowlevel_init.S +++ b/arch/arm/cpu/arm926ejs/davinci/lowlevel_init.S @@ -45,6 +45,8 @@ #include +#define MDSTAT_STATE 0x3f + .globl lowlevel_init lowlevel_init: @@ -268,7 +270,7 @@ checkStatClkStop: checkDDRStatClkStop: ldr r6, MDSTAT_DDR2 ldr r7, [r6] - and r7, r7, $0x1f + and r7, r7, $MDSTAT_STATE cmp r7, $0x03 bne checkDDRStatClkStop @@ -343,7 +345,7 @@ checkStatClkStop2: checkDDRStatClkStop2: ldr r6, MDSTAT_DDR2 ldr r7, [r6] - and r7, r7, $0x1f + and r7, r7, $MDSTAT_STATE cmp r7, $0x01 bne checkDDRStatClkStop2 @@ -374,7 +376,7 @@ checkStatClkEn2: checkDDRStatClkEn2: ldr r6, MDSTAT_DDR2 ldr r7, [r6] - and r7, r7, $0x1f + and r7, r7, $MDSTAT_STATE cmp r7, $0x03 bne checkDDRStatClkEn2 diff --git a/arch/arm/cpu/arm926ejs/davinci/psc.c b/arch/arm/cpu/arm926ejs/davinci/psc.c index 8273a7fae4..707fa47e31 100644 --- a/arch/arm/cpu/arm926ejs/davinci/psc.c +++ b/arch/arm/cpu/arm926ejs/davinci/psc.c @@ -83,7 +83,7 @@ void lpsc_on(unsigned int id) while (readl(ptstat) & 0x01) continue; - if ((readl(mdstat) & 0x1f) == 0x03) + if ((readl(mdstat) & PSC_MDSTAT_STATE) == 0x03) return; /* Already on and enabled */ writel(readl(mdctl) | 0x03, mdctl); @@ -114,7 +114,7 @@ void lpsc_on(unsigned int id) while (readl(ptstat) & 0x01) continue; - while ((readl(mdstat) & 0x1f) != 0x03) + while ((readl(mdstat) & PSC_MDSTAT_STATE) != 0x03) continue; } -- cgit From cc3f7058435c94acaaf9111340437a0a4c018de6 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Tue, 4 Oct 2011 04:59:23 +0000 Subject: OMAP3 SPL: Provide weak omap_rev_string We add an weak version of omap_rev_string in omap-common/spl.c and while at it drop the omap3 version. Move the prototype over to with the other SPL functions. Signed-off-by: Tom Rini Signed-off-by: Sandeep Paulraj --- arch/arm/cpu/armv7/omap-common/spl.c | 8 ++++++++ arch/arm/cpu/armv7/omap3/board.c | 6 ------ 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index 01fd58a354..d0866c03d0 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -160,3 +160,11 @@ void preloader_console_init(void) omap_rev_string(rev_string_buffer); printf("Texas Instruments %s\n", rev_string_buffer); } + +void __omap_rev_string(char *str) +{ + sprintf(str, "Revision detection unimplemented"); +} + +void omap_rev_string(char *str) + __attribute__((weak, alias("__omap_rev_string"))); diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c index 1b3ef69a99..a9fdb4f8ed 100644 --- a/arch/arm/cpu/armv7/omap3/board.c +++ b/arch/arm/cpu/armv7/omap3/board.c @@ -450,9 +450,3 @@ void enable_caches(void) dcache_enable(); } #endif - -void omap_rev_string(char *omap_rev_string) -{ - sprintf(omap_rev_string, "OMAP3, sorry revision detection" \ - " unimplemented"); -} -- cgit From 2d01dd953a269e5fc27e04cb8571e0d8d81c7c4a Mon Sep 17 00:00:00 2001 From: Aneesh V Date: Fri, 21 Oct 2011 12:29:34 -0400 Subject: omap: spl: fix build break due to changes in FAT FAT library now uses malloc() and free(). But SPL doesn't have heap until now. Setup a heap in SDRAM to fix this issue. However this increases SPL footprint beyond the available SRAM budget. So, compile out some fancy features in the SDARM init bring back footprint under control CC: Sandeep Paulraj CC: Wolfgang Denk Signed-off-by: Aneesh V Signed-off-by: Sandeep Paulraj --- arch/arm/cpu/armv7/omap-common/spl.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index d0866c03d0..d37ca0ff5a 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -34,6 +34,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -105,6 +106,9 @@ void board_init_r(gd_t *id, ulong dummy) u32 boot_device; debug(">>spl:board_init_r()\n"); + mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START, + CONFIG_SYS_SPL_MALLOC_SIZE); + timer_init(); i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); -- cgit From b5db0a068a25e71b178e4b89635af731cf2f7c24 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Wed, 12 Oct 2011 10:31:44 +0000 Subject: omap: Don't use gpio_free to change direction to input gpio_free() should not have the side effect of setting the line to input since this prevents the gpio command from being able to set a line as output. Signed-off-by: Joe Hershberger Cc: Joe Hershberger Cc: Sandeep Paulraj Signed-off-by: Sandeep Paulraj --- arch/arm/cpu/armv7/omap-common/gpio.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/armv7/omap-common/gpio.c b/arch/arm/cpu/armv7/omap-common/gpio.c index e62c6f4eb5..75a02da877 100644 --- a/arch/arm/cpu/armv7/omap-common/gpio.c +++ b/arch/arm/cpu/armv7/omap-common/gpio.c @@ -237,11 +237,4 @@ int gpio_request(int gpio, const char *label) */ void gpio_free(unsigned gpio) { - const struct gpio_bank *bank; - - if (check_gpio(gpio) < 0) - return; - bank = get_gpio_bank(gpio); - - _set_gpio_direction(bank, get_gpio_index(gpio), 1); } -- cgit From fb1d6332b5430b90a8fa8ebab709f33a60e9f816 Mon Sep 17 00:00:00 2001 From: Manjunath Hadli Date: Thu, 13 Oct 2011 03:40:55 +0000 Subject: davinci: remove obsolete macro CONFIG_EMAC_MDIO_PHY_NUM remove macro CONFIG_EMAC_MDIO_PHY_NUM and depending macro EMAC_MDIO_PHY_NUM as they are no longer needed with the support for more than 1 PHYs in davinci emac driver. Signed-off-by: Manjunath Hadli Signed-off-by: Sandeep Paulraj --- arch/arm/cpu/arm926ejs/davinci/et1011c.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/arm926ejs/davinci/et1011c.c b/arch/arm/cpu/arm926ejs/davinci/et1011c.c index da073457a3..df35e44d13 100644 --- a/arch/arm/cpu/arm926ejs/davinci/et1011c.c +++ b/arch/arm/cpu/arm926ejs/davinci/et1011c.c @@ -39,11 +39,9 @@ int et1011c_get_link_speed(int phy_addr) u_int16_t data; if (davinci_eth_phy_read(phy_addr, MII_STATUS_REG, &data) && (data & 0x04)) { - davinci_eth_phy_read(EMAC_MDIO_PHY_NUM, - MII_PHY_CONFIG_REG, &data); + davinci_eth_phy_read(phy_addr, MII_PHY_CONFIG_REG, &data); /* Enable 125MHz clock sourced from PHY */ - davinci_eth_phy_write(EMAC_MDIO_PHY_NUM, - MII_PHY_CONFIG_REG, + davinci_eth_phy_write(phy_addr, MII_PHY_CONFIG_REG, data | PHY_SYS_CLK_EN); return (1); } -- cgit From 5655108a8215123bac7154f64c29109fd63d86be Mon Sep 17 00:00:00 2001 From: Chandan Nath Date: Fri, 14 Oct 2011 02:58:22 +0000 Subject: ARM:AM33XX: Added support for AM33xx This patch adds basic support for AM33xx which is based on ARMV7 Cortex A8 CPU. Signed-off-by: Chandan Nath Signed-off-by: Sandeep Paulraj --- arch/arm/cpu/armv7/am33xx/Makefile | 44 ++++++++++ arch/arm/cpu/armv7/am33xx/lowlevel_init.S | 72 +++++++++++++++++ arch/arm/cpu/armv7/am33xx/sys_info.c | 130 ++++++++++++++++++++++++++++++ 3 files changed, 246 insertions(+) create mode 100644 arch/arm/cpu/armv7/am33xx/Makefile create mode 100644 arch/arm/cpu/armv7/am33xx/lowlevel_init.S create mode 100644 arch/arm/cpu/armv7/am33xx/sys_info.c (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/armv7/am33xx/Makefile b/arch/arm/cpu/armv7/am33xx/Makefile new file mode 100644 index 0000000000..498df785ab --- /dev/null +++ b/arch/arm/cpu/armv7/am33xx/Makefile @@ -0,0 +1,44 @@ +# +# Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/ +# +# 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 "as is" WITHOUT ANY WARRANTY of any +# kind, whether express or implied; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).o + +SOBJS := lowlevel_init.o + +COBJS += sys_info.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS) $(COBJS-y) $(SOBJS)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak .depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/armv7/am33xx/lowlevel_init.S b/arch/arm/cpu/armv7/am33xx/lowlevel_init.S new file mode 100644 index 0000000000..17c962ff71 --- /dev/null +++ b/arch/arm/cpu/armv7/am33xx/lowlevel_init.S @@ -0,0 +1,72 @@ +/* + * lowlevel_init.S + * + * AM33XX low level initialization. + * + * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/ + * + * Initial Code by: + * Mansoor Ahamed + * + * 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 "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include + +_mark1: + .word mark1 +_lowlevel_init1: + .word lowlevel_init +_s_init_start: + .word s_init_start + +_TEXT_BASE: + .word CONFIG_SYS_TEXT_BASE /* sdram load addr from config.mk */ + +/***************************************************************************** + * lowlevel_init: - Platform low level init. + ****************************************************************************/ +.globl lowlevel_init +lowlevel_init: + + /* The link register is saved in ip by start.S */ + mov r6, ip + /* check if we are already running from RAM */ + ldr r2, _lowlevel_init1 + ldr r3, _TEXT_BASE + sub r4, r2, r3 + sub r0, pc, r4 + ldr sp, SRAM_STACK +mark1: + ldr r5, _mark1 + sub r5, r5, r2 /* bytes between mark1 and lowlevel_init */ + sub r0, r0, r5 /* r0 <- _start w.r.t current place of execution */ + mov r10, #0x0 /* r10 has in_ddr used by s_init() */ + + ands r0, r0, #0xC0000000 + /* MSB 2 bits <> 0 then we are in ocmc or DDR */ + cmp r0, #0x80000000 + bne s_init_start + mov r10, #0x01 + b s_init_start + +s_init_start: + mov r0, r10 /* passing in_ddr in r0 */ + bl s_init + /* back to arch calling code */ + mov pc, r6 + /* the literal pools origin */ + .ltorg + +SRAM_STACK: + /* Place stack at the top */ + .word LOW_LEVEL_SRAM_STACK diff --git a/arch/arm/cpu/armv7/am33xx/sys_info.c b/arch/arm/cpu/armv7/am33xx/sys_info.c new file mode 100644 index 0000000000..507b6180e6 --- /dev/null +++ b/arch/arm/cpu/armv7/am33xx/sys_info.c @@ -0,0 +1,130 @@ +/* + * sys_info.c + * + * System information functions + * + * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/ + * + * Derived from Beagle Board and 3430 SDP code by + * Richard Woodruff + * Syed Mohammed Khasim + * + * 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. + */ + +#include +#include +#include +#include +#include + +struct ctrl_stat *cstat = (struct ctrl_stat *)CTRL_BASE; + +/** + * get_cpu_rev(void) - extract rev info + */ +u32 get_cpu_rev(void) +{ + u32 id; + u32 rev; + + id = readl(DEVICE_ID); + rev = (id >> 28) & 0xff; + + return rev; +} + +/** + * get_cpu_type(void) - extract cpu info + */ +u32 get_cpu_type(void) +{ + u32 id = 0; + u32 partnum; + + id = readl(DEVICE_ID); + partnum = (id >> 12) & 0xffff; + + return partnum; +} + +/** + * get_board_rev() - setup to pass kernel board revision information + * returns:(bit[0-3] sub version, higher bit[7-4] is higher version) + */ +u32 get_board_rev(void) +{ + return BOARD_REV_ID; +} + +/** + * get_device_type(): tell if GP/HS/EMU/TST + */ +u32 get_device_type(void) +{ + int mode; + mode = readl(&cstat->statusreg) & (DEVICE_MASK); + return mode >>= 8; +} + +/** + * get_sysboot_value(void) - return SYS_BOOT[4:0] + */ +u32 get_sysboot_value(void) +{ + int mode; + mode = readl(&cstat->statusreg) & (SYSBOOT_MASK); + return mode; +} + +#ifdef CONFIG_DISPLAY_CPUINFO +/** + * Print CPU information + */ +int print_cpuinfo(void) +{ + char *cpu_s, *sec_s; + int arm_freq, ddr_freq; + + switch (get_cpu_type()) { + case AM335X: + cpu_s = "AM335X"; + break; + default: + cpu_s = "Unknown cpu type"; + break; + } + + switch (get_device_type()) { + case TST_DEVICE: + sec_s = "TST"; + break; + case EMU_DEVICE: + sec_s = "EMU"; + break; + case HS_DEVICE: + sec_s = "HS"; + break; + case GP_DEVICE: + sec_s = "GP"; + break; + default: + sec_s = "?"; + } + + printf("AM%s-%s rev %d\n", + cpu_s, sec_s, get_cpu_rev()); + + /* TODO: Print ARM and DDR frequencies */ + + return 0; +} +#endif /* CONFIG_DISPLAY_CPUINFO */ -- cgit From f87fa62af9abd5f8196596d3ea4347999ec40e1e Mon Sep 17 00:00:00 2001 From: Chandan Nath Date: Fri, 14 Oct 2011 02:58:23 +0000 Subject: ARM:AM33XX: Add clock definitions This patch adds basic clock definition of am33xx SoC. Signed-off-by: Chandan Nath Signed-off-by: Sandeep Paulraj --- arch/arm/cpu/armv7/am33xx/Makefile | 1 + arch/arm/cpu/armv7/am33xx/clock.c | 273 +++++++++++++++++++++++++++++++++++++ 2 files changed, 274 insertions(+) create mode 100644 arch/arm/cpu/armv7/am33xx/clock.c (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/armv7/am33xx/Makefile b/arch/arm/cpu/armv7/am33xx/Makefile index 498df785ab..fc25587fa3 100644 --- a/arch/arm/cpu/armv7/am33xx/Makefile +++ b/arch/arm/cpu/armv7/am33xx/Makefile @@ -18,6 +18,7 @@ LIB = $(obj)lib$(SOC).o SOBJS := lowlevel_init.o +COBJS += clock.o COBJS += sys_info.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) diff --git a/arch/arm/cpu/armv7/am33xx/clock.c b/arch/arm/cpu/armv7/am33xx/clock.c new file mode 100644 index 0000000000..4ca6c45349 --- /dev/null +++ b/arch/arm/cpu/armv7/am33xx/clock.c @@ -0,0 +1,273 @@ +/* + * clock.c + * + * clocks for AM33XX based boards + * + * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/ + * + * 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. + */ + +#include +#include +#include +#include +#include + +#define PRCM_MOD_EN 0x2 +#define PRCM_FORCE_WAKEUP 0x2 + +#define PRCM_EMIF_CLK_ACTIVITY BIT(2) +#define PRCM_L3_GCLK_ACTIVITY BIT(4) + +#define PLL_BYPASS_MODE 0x4 +#define ST_MN_BYPASS 0x00000100 +#define ST_DPLL_CLK 0x00000001 +#define CLK_SEL_MASK 0x7ffff +#define CLK_DIV_MASK 0x1f +#define CLK_DIV2_MASK 0x7f +#define CLK_SEL_SHIFT 0x8 +#define CLK_MODE_SEL 0x7 +#define CLK_MODE_MASK 0xfffffff8 +#define CLK_DIV_SEL 0xFFFFFFE0 + + +const struct cm_perpll *cmper = (struct cm_perpll *)CM_PER; +const struct cm_wkuppll *cmwkup = (struct cm_wkuppll *)CM_WKUP; +const struct cm_dpll *cmdpll = (struct cm_dpll *)CM_DPLL; + +static void enable_interface_clocks(void) +{ + /* Enable all the Interconnect Modules */ + writel(PRCM_MOD_EN, &cmper->l3clkctrl); + while (readl(&cmper->l3clkctrl) != PRCM_MOD_EN) + ; + + writel(PRCM_MOD_EN, &cmper->l4lsclkctrl); + while (readl(&cmper->l4lsclkctrl) != PRCM_MOD_EN) + ; + + writel(PRCM_MOD_EN, &cmper->l4fwclkctrl); + while (readl(&cmper->l4fwclkctrl) != PRCM_MOD_EN) + ; + + writel(PRCM_MOD_EN, &cmwkup->wkl4wkclkctrl); + while (readl(&cmwkup->wkl4wkclkctrl) != PRCM_MOD_EN) + ; + + writel(PRCM_MOD_EN, &cmper->l3instrclkctrl); + while (readl(&cmper->l3instrclkctrl) != PRCM_MOD_EN) + ; + + writel(PRCM_MOD_EN, &cmper->l4hsclkctrl); + while (readl(&cmper->l4hsclkctrl) != PRCM_MOD_EN) + ; +} + +/* + * Force power domain wake up transition + * Ensure that the corresponding interface clock is active before + * using the peripheral + */ +static void power_domain_wkup_transition(void) +{ + writel(PRCM_FORCE_WAKEUP, &cmper->l3clkstctrl); + writel(PRCM_FORCE_WAKEUP, &cmper->l4lsclkstctrl); + writel(PRCM_FORCE_WAKEUP, &cmwkup->wkclkstctrl); + writel(PRCM_FORCE_WAKEUP, &cmper->l4fwclkstctrl); + writel(PRCM_FORCE_WAKEUP, &cmper->l3sclkstctrl); +} + +/* + * Enable the peripheral clock for required peripherals + */ +static void enable_per_clocks(void) +{ + /* Enable the control module though RBL would have done it*/ + writel(PRCM_MOD_EN, &cmwkup->wkctrlclkctrl); + while (readl(&cmwkup->wkctrlclkctrl) != PRCM_MOD_EN) + ; + + /* Enable the module clock */ + writel(PRCM_MOD_EN, &cmper->timer2clkctrl); + while (readl(&cmper->timer2clkctrl) != PRCM_MOD_EN) + ; + + /* UART0 */ + writel(PRCM_MOD_EN, &cmwkup->wkup_uart0ctrl); + while (readl(&cmwkup->wkup_uart0ctrl) != PRCM_MOD_EN) + ; +} + +static void mpu_pll_config(void) +{ + u32 clkmode, clksel, div_m2; + + clkmode = readl(&cmwkup->clkmoddpllmpu); + clksel = readl(&cmwkup->clkseldpllmpu); + div_m2 = readl(&cmwkup->divm2dpllmpu); + + /* Set the PLL to bypass Mode */ + writel(PLL_BYPASS_MODE, &cmwkup->clkmoddpllmpu); + while (readl(&cmwkup->idlestdpllmpu) != ST_MN_BYPASS) + ; + + clksel = clksel & (~CLK_SEL_MASK); + clksel = clksel | ((MPUPLL_M << CLK_SEL_SHIFT) | MPUPLL_N); + writel(clksel, &cmwkup->clkseldpllmpu); + + div_m2 = div_m2 & ~CLK_DIV_MASK; + div_m2 = div_m2 | MPUPLL_M2; + writel(div_m2, &cmwkup->divm2dpllmpu); + + clkmode = clkmode | CLK_MODE_SEL; + writel(clkmode, &cmwkup->clkmoddpllmpu); + + while (readl(&cmwkup->idlestdpllmpu) != ST_DPLL_CLK) + ; +} + +static void core_pll_config(void) +{ + u32 clkmode, clksel, div_m4, div_m5, div_m6; + + clkmode = readl(&cmwkup->clkmoddpllcore); + clksel = readl(&cmwkup->clkseldpllcore); + div_m4 = readl(&cmwkup->divm4dpllcore); + div_m5 = readl(&cmwkup->divm5dpllcore); + div_m6 = readl(&cmwkup->divm6dpllcore); + + /* Set the PLL to bypass Mode */ + writel(PLL_BYPASS_MODE, &cmwkup->clkmoddpllcore); + + while (readl(&cmwkup->idlestdpllcore) != ST_MN_BYPASS) + ; + + clksel = clksel & (~CLK_SEL_MASK); + clksel = clksel | ((COREPLL_M << CLK_SEL_SHIFT) | COREPLL_N); + writel(clksel, &cmwkup->clkseldpllcore); + + div_m4 = div_m4 & ~CLK_DIV_MASK; + div_m4 = div_m4 | COREPLL_M4; + writel(div_m4, &cmwkup->divm4dpllcore); + + div_m5 = div_m5 & ~CLK_DIV_MASK; + div_m5 = div_m5 | COREPLL_M5; + writel(div_m5, &cmwkup->divm5dpllcore); + + div_m6 = div_m6 & ~CLK_DIV_MASK; + div_m6 = div_m6 | COREPLL_M6; + writel(div_m6, &cmwkup->divm6dpllcore); + + clkmode = clkmode | CLK_MODE_SEL; + writel(clkmode, &cmwkup->clkmoddpllcore); + + while (readl(&cmwkup->idlestdpllcore) != ST_DPLL_CLK) + ; +} + +static void per_pll_config(void) +{ + u32 clkmode, clksel, div_m2; + + clkmode = readl(&cmwkup->clkmoddpllper); + clksel = readl(&cmwkup->clkseldpllper); + div_m2 = readl(&cmwkup->divm2dpllper); + + /* Set the PLL to bypass Mode */ + writel(PLL_BYPASS_MODE, &cmwkup->clkmoddpllper); + + while (readl(&cmwkup->idlestdpllper) != ST_MN_BYPASS) + ; + + clksel = clksel & (~CLK_SEL_MASK); + clksel = clksel | ((PERPLL_M << CLK_SEL_SHIFT) | PERPLL_N); + writel(clksel, &cmwkup->clkseldpllper); + + div_m2 = div_m2 & ~CLK_DIV2_MASK; + div_m2 = div_m2 | PERPLL_M2; + writel(div_m2, &cmwkup->divm2dpllper); + + clkmode = clkmode | CLK_MODE_SEL; + writel(clkmode, &cmwkup->clkmoddpllper); + + while (readl(&cmwkup->idlestdpllper) != ST_DPLL_CLK) + ; +} + +static void ddr_pll_config(void) +{ + u32 clkmode, clksel, div_m2; + + clkmode = readl(&cmwkup->clkmoddpllddr); + clksel = readl(&cmwkup->clkseldpllddr); + div_m2 = readl(&cmwkup->divm2dpllddr); + + /* Set the PLL to bypass Mode */ + clkmode = (clkmode & CLK_MODE_MASK) | PLL_BYPASS_MODE; + writel(clkmode, &cmwkup->clkmoddpllddr); + + /* Wait till bypass mode is enabled */ + while ((readl(&cmwkup->idlestdpllddr) & ST_MN_BYPASS) + != ST_MN_BYPASS) + ; + + clksel = clksel & (~CLK_SEL_MASK); + clksel = clksel | ((DDRPLL_M << CLK_SEL_SHIFT) | DDRPLL_N); + writel(clksel, &cmwkup->clkseldpllddr); + + div_m2 = div_m2 & CLK_DIV_SEL; + div_m2 = div_m2 | DDRPLL_M2; + writel(div_m2, &cmwkup->divm2dpllddr); + + clkmode = (clkmode & CLK_MODE_MASK) | CLK_MODE_SEL; + writel(clkmode, &cmwkup->clkmoddpllddr); + + /* Wait till dpll is locked */ + while ((readl(&cmwkup->idlestdpllddr) & ST_DPLL_CLK) != ST_DPLL_CLK) + ; +} + +void enable_emif_clocks(void) +{ + /* Enable the EMIF_FW Functional clock */ + writel(PRCM_MOD_EN, &cmper->emiffwclkctrl); + /* Enable EMIF0 Clock */ + writel(PRCM_MOD_EN, &cmper->emifclkctrl); + /* Poll for emif_gclk & L3_G clock are active */ + while ((readl(&cmper->l3clkstctrl) & (PRCM_EMIF_CLK_ACTIVITY | + PRCM_L3_GCLK_ACTIVITY)) != (PRCM_EMIF_CLK_ACTIVITY | + PRCM_L3_GCLK_ACTIVITY)) + ; + /* Poll if module is functional */ + while ((readl(&cmper->emifclkctrl)) != PRCM_MOD_EN) + ; +} + +/* + * Configure the PLL/PRCM for necessary peripherals + */ +void pll_init() +{ + mpu_pll_config(); + core_pll_config(); + per_pll_config(); + ddr_pll_config(); + + /* Enable the required interconnect clocks */ + enable_interface_clocks(); + + /* Power domain wake up transition */ + power_domain_wkup_transition(); + + /* Enable the required peripherals */ + enable_per_clocks(); +} -- cgit From 62d7fe7c91d9da43c8164c7baa9b2331a18d9ee0 Mon Sep 17 00:00:00 2001 From: Chandan Nath Date: Fri, 14 Oct 2011 02:58:24 +0000 Subject: ARM:AM33XX: Add emif/ddr support This patch adds AM33xx emif/ddr support along with board specific defines. Signed-off-by: Chandan Nath Signed-off-by: Sandeep Paulraj --- arch/arm/cpu/armv7/am33xx/Makefile | 3 + arch/arm/cpu/armv7/am33xx/ddr.c | 147 +++++++++++++++++++++++++++ arch/arm/cpu/armv7/am33xx/emif4.c | 201 +++++++++++++++++++++++++++++++++++++ 3 files changed, 351 insertions(+) create mode 100644 arch/arm/cpu/armv7/am33xx/ddr.c create mode 100644 arch/arm/cpu/armv7/am33xx/emif4.c (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/armv7/am33xx/Makefile b/arch/arm/cpu/armv7/am33xx/Makefile index fc25587fa3..7ed667877b 100644 --- a/arch/arm/cpu/armv7/am33xx/Makefile +++ b/arch/arm/cpu/armv7/am33xx/Makefile @@ -20,6 +20,9 @@ SOBJS := lowlevel_init.o COBJS += clock.o COBJS += sys_info.o +COBJS += ddr.o +COBJS += emif4.o + SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS) $(COBJS-y) $(SOBJS)) diff --git a/arch/arm/cpu/armv7/am33xx/ddr.c b/arch/arm/cpu/armv7/am33xx/ddr.c new file mode 100644 index 0000000000..ed982c11e8 --- /dev/null +++ b/arch/arm/cpu/armv7/am33xx/ddr.c @@ -0,0 +1,147 @@ +/* + * DDR Configuration for AM33xx devices. + * + * Copyright (C) 2011 Texas Instruments Incorporated - +http://www.ti.com/ + * + * 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 .as is. WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include + +/** + * Base address for EMIF instances + */ +static struct emif_regs *emif_reg = { + (struct emif_regs *)EMIF4_0_CFG_BASE}; + +/** + * Base address for DDR instance + */ +static struct ddr_regs *ddr_reg[2] = { + (struct ddr_regs *)DDR_PHY_BASE_ADDR, + (struct ddr_regs *)DDR_PHY_BASE_ADDR2}; + +/** + * Base address for ddr io control instances + */ +static struct ddr_cmdtctrl *ioctrl_reg = { + (struct ddr_cmdtctrl *)DDR_CONTROL_BASE_ADDR}; + +/** + * As a convention, all functions here return 0 on success + * -1 on failure. + */ + +/** + * Configure SDRAM + */ +int config_sdram(struct sdram_config *cfg) +{ + writel(cfg->sdrcr, &emif_reg->sdrcr); + writel(cfg->sdrcr2, &emif_reg->sdrcr2); + writel(cfg->refresh, &emif_reg->sdrrcr); + writel(cfg->refresh_sh, &emif_reg->sdrrcsr); + + return 0; +} + +/** + * Set SDRAM timings + */ +int set_sdram_timings(struct sdram_timing *t) +{ + writel(t->time1, &emif_reg->sdrtim1); + writel(t->time1_sh, &emif_reg->sdrtim1sr); + writel(t->time2, &emif_reg->sdrtim2); + writel(t->time2_sh, &emif_reg->sdrtim2sr); + writel(t->time3, &emif_reg->sdrtim3); + writel(t->time3_sh, &emif_reg->sdrtim3sr); + + return 0; +} + +/** + * Configure DDR PHY + */ +int config_ddr_phy(struct ddr_phy_control *p) +{ + writel(p->reg, &emif_reg->ddrphycr); + writel(p->reg_sh, &emif_reg->ddrphycsr); + + return 0; +} + +/** + * Configure DDR CMD control registers + */ +int config_cmd_ctrl(struct cmd_control *cmd) +{ + writel(cmd->cmd0csratio, &ddr_reg[0]->cm0csratio); + writel(cmd->cmd0csforce, &ddr_reg[0]->cm0csforce); + writel(cmd->cmd0csdelay, &ddr_reg[0]->cm0csdelay); + writel(cmd->cmd0dldiff, &ddr_reg[0]->cm0dldiff); + writel(cmd->cmd0iclkout, &ddr_reg[0]->cm0iclkout); + + writel(cmd->cmd1csratio, &ddr_reg[0]->cm1csratio); + writel(cmd->cmd1csforce, &ddr_reg[0]->cm1csforce); + writel(cmd->cmd1csdelay, &ddr_reg[0]->cm1csdelay); + writel(cmd->cmd1dldiff, &ddr_reg[0]->cm1dldiff); + writel(cmd->cmd1iclkout, &ddr_reg[0]->cm1iclkout); + + writel(cmd->cmd2csratio, &ddr_reg[0]->cm2csratio); + writel(cmd->cmd2csforce, &ddr_reg[0]->cm2csforce); + writel(cmd->cmd2csdelay, &ddr_reg[0]->cm2csdelay); + writel(cmd->cmd2dldiff, &ddr_reg[0]->cm2dldiff); + writel(cmd->cmd2iclkout, &ddr_reg[0]->cm2iclkout); + + return 0; +} + +/** + * Configure DDR DATA registers + */ +int config_ddr_data(int macrono, struct ddr_data *data) +{ + writel(data->datardsratio0, &ddr_reg[macrono]->dt0rdsratio0); + writel(data->datardsratio1, &ddr_reg[macrono]->dt0rdsratio1); + + writel(data->datawdsratio0, &ddr_reg[macrono]->dt0wdsratio0); + writel(data->datawdsratio1, &ddr_reg[macrono]->dt0wdsratio1); + + writel(data->datawiratio0, &ddr_reg[macrono]->dt0wiratio0); + writel(data->datawiratio1, &ddr_reg[macrono]->dt0wiratio1); + writel(data->datagiratio0, &ddr_reg[macrono]->dt0giratio0); + writel(data->datagiratio1, &ddr_reg[macrono]->dt0giratio1); + + writel(data->datafwsratio0, &ddr_reg[macrono]->dt0fwsratio0); + writel(data->datafwsratio1, &ddr_reg[macrono]->dt0fwsratio1); + + writel(data->datawrsratio0, &ddr_reg[macrono]->dt0wrsratio0); + writel(data->datawrsratio1, &ddr_reg[macrono]->dt0wrsratio1); + + writel(data->datadldiff0, &ddr_reg[macrono]->dt0dldiff0); + + return 0; +} + +int config_io_ctrl(struct ddr_ioctrl *ioctrl) +{ + writel(ioctrl->cmd1ctl, &ioctrl_reg->cm0ioctl); + writel(ioctrl->cmd2ctl, &ioctrl_reg->cm1ioctl); + writel(ioctrl->cmd3ctl, &ioctrl_reg->cm2ioctl); + writel(ioctrl->data1ctl, &ioctrl_reg->dt0ioctl); + writel(ioctrl->data2ctl, &ioctrl_reg->dt1ioctl); + + return 0; +} diff --git a/arch/arm/cpu/armv7/am33xx/emif4.c b/arch/arm/cpu/armv7/am33xx/emif4.c new file mode 100644 index 0000000000..1318365a4a --- /dev/null +++ b/arch/arm/cpu/armv7/am33xx/emif4.c @@ -0,0 +1,201 @@ +/* + * emif4.c + * + * AM33XX emif4 configuration file + * + * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/ + * + * 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. + */ + +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +struct ddr_regs *ddrregs = (struct ddr_regs *)DDR_PHY_BASE_ADDR; +struct vtp_reg *vtpreg = (struct vtp_reg *)VTP0_CTRL_ADDR; +struct ddr_ctrl *ddrctrl = (struct ddr_ctrl *)DDR_CTRL_ADDR; + + +int dram_init(void) +{ + /* dram_init must store complete ramsize in gd->ram_size */ + gd->ram_size = get_ram_size( + (void *)CONFIG_SYS_SDRAM_BASE, + CONFIG_MAX_RAM_BANK_SIZE); + return 0; +} + +void dram_init_banksize(void) +{ + gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; + gd->bd->bi_dram[0].size = gd->ram_size; +} + + +#ifdef CONFIG_AM335X_CONFIG_DDR +static void data_macro_config(int dataMacroNum) +{ + struct ddr_data data; + + data.datardsratio0 = ((DDR2_RD_DQS<<30)|(DDR2_RD_DQS<<20) + |(DDR2_RD_DQS<<10)|(DDR2_RD_DQS<<0)); + data.datardsratio1 = DDR2_RD_DQS>>2; + data.datawdsratio0 = ((DDR2_WR_DQS<<30)|(DDR2_WR_DQS<<20) + |(DDR2_WR_DQS<<10)|(DDR2_WR_DQS<<0)); + data.datawdsratio1 = DDR2_WR_DQS>>2; + data.datawiratio0 = ((DDR2_PHY_WRLVL<<30)|(DDR2_PHY_WRLVL<<20) + |(DDR2_PHY_WRLVL<<10)|(DDR2_PHY_WRLVL<<0)); + data.datawiratio1 = DDR2_PHY_WRLVL>>2; + data.datagiratio0 = ((DDR2_PHY_GATELVL<<30)|(DDR2_PHY_GATELVL<<20) + |(DDR2_PHY_GATELVL<<10)|(DDR2_PHY_GATELVL<<0)); + data.datagiratio1 = DDR2_PHY_GATELVL>>2; + data.datafwsratio0 = ((DDR2_PHY_FIFO_WE<<30)|(DDR2_PHY_FIFO_WE<<20) + |(DDR2_PHY_FIFO_WE<<10)|(DDR2_PHY_FIFO_WE<<0)); + data.datafwsratio1 = DDR2_PHY_FIFO_WE>>2; + data.datawrsratio0 = ((DDR2_PHY_WR_DATA<<30)|(DDR2_PHY_WR_DATA<<20) + |(DDR2_PHY_WR_DATA<<10)|(DDR2_PHY_WR_DATA<<0)); + data.datawrsratio1 = DDR2_PHY_WR_DATA>>2; + data.datadldiff0 = PHY_DLL_LOCK_DIFF; + + config_ddr_data(dataMacroNum, &data); +} + +static void cmd_macro_config(void) +{ + struct cmd_control cmd; + + cmd.cmd0csratio = DDR2_RATIO; + cmd.cmd0csforce = CMD_FORCE; + cmd.cmd0csdelay = CMD_DELAY; + cmd.cmd0dldiff = DDR2_DLL_LOCK_DIFF; + cmd.cmd0iclkout = DDR2_INVERT_CLKOUT; + + cmd.cmd1csratio = DDR2_RATIO; + cmd.cmd1csforce = CMD_FORCE; + cmd.cmd1csdelay = CMD_DELAY; + cmd.cmd1dldiff = DDR2_DLL_LOCK_DIFF; + cmd.cmd1iclkout = DDR2_INVERT_CLKOUT; + + cmd.cmd2csratio = DDR2_RATIO; + cmd.cmd2csforce = CMD_FORCE; + cmd.cmd2csdelay = CMD_DELAY; + cmd.cmd2dldiff = DDR2_DLL_LOCK_DIFF; + cmd.cmd2iclkout = DDR2_INVERT_CLKOUT; + + config_cmd_ctrl(&cmd); + +} + +static void config_vtp(void) +{ + writel(readl(&vtpreg->vtp0ctrlreg) | VTP_CTRL_ENABLE, + &vtpreg->vtp0ctrlreg); + writel(readl(&vtpreg->vtp0ctrlreg) & (~VTP_CTRL_START_EN), + &vtpreg->vtp0ctrlreg); + writel(readl(&vtpreg->vtp0ctrlreg) | VTP_CTRL_START_EN, + &vtpreg->vtp0ctrlreg); + + /* Poll for READY */ + while ((readl(&vtpreg->vtp0ctrlreg) & VTP_CTRL_READY) != + VTP_CTRL_READY) + ; +} + +static void config_emif_ddr2(void) +{ + int i; + int ret; + struct sdram_config cfg; + struct sdram_timing tmg; + struct ddr_phy_control phyc; + + /*Program EMIF0 CFG Registers*/ + phyc.reg = EMIF_READ_LATENCY; + phyc.reg_sh = EMIF_READ_LATENCY; + phyc.reg2 = EMIF_READ_LATENCY; + + tmg.time1 = EMIF_TIM1; + tmg.time1_sh = EMIF_TIM1; + tmg.time2 = EMIF_TIM2; + tmg.time2_sh = EMIF_TIM2; + tmg.time3 = EMIF_TIM3; + tmg.time3_sh = EMIF_TIM3; + + cfg.sdrcr = EMIF_SDCFG; + cfg.sdrcr2 = EMIF_SDCFG; + cfg.refresh = 0x00004650; + cfg.refresh_sh = 0x00004650; + + /* Program EMIF instance */ + ret = config_ddr_phy(&phyc); + if (ret < 0) + printf("Couldn't configure phyc\n"); + + ret = config_sdram(&cfg); + if (ret < 0) + printf("Couldn't configure SDRAM\n"); + + ret = set_sdram_timings(&tmg); + if (ret < 0) + printf("Couldn't configure timings\n"); + + /* Delay */ + for (i = 0; i < 5000; i++) + ; + + cfg.refresh = EMIF_SDREF; + cfg.refresh_sh = EMIF_SDREF; + cfg.sdrcr = EMIF_SDCFG; + cfg.sdrcr2 = EMIF_SDCFG; + + ret = config_sdram(&cfg); + if (ret < 0) + printf("Couldn't configure SDRAM\n"); +} + +void config_ddr(void) +{ + int data_macro_0 = 0; + int data_macro_1 = 1; + struct ddr_ioctrl ioctrl; + + enable_emif_clocks(); + + config_vtp(); + + cmd_macro_config(); + + data_macro_config(data_macro_0); + data_macro_config(data_macro_1); + + writel(PHY_RANK0_DELAY, &ddrregs->dt0rdelays0); + writel(PHY_RANK0_DELAY, &ddrregs->dt1rdelays0); + + ioctrl.cmd1ctl = DDR_IOCTRL_VALUE; + ioctrl.cmd2ctl = DDR_IOCTRL_VALUE; + ioctrl.cmd3ctl = DDR_IOCTRL_VALUE; + ioctrl.data1ctl = DDR_IOCTRL_VALUE; + ioctrl.data2ctl = DDR_IOCTRL_VALUE; + + config_io_ctrl(&ioctrl); + + writel(readl(&ddrctrl->ddrioctrl) & 0xefffffff, &ddrctrl->ddrioctrl); + writel(readl(&ddrctrl->ddrckectrl) | 0x00000001, &ddrctrl->ddrckectrl); + + config_emif_ddr2(); +} +#endif -- cgit From f0f4b5ff50b1ee8db5caceed6bbf464880e33274 Mon Sep 17 00:00:00 2001 From: Chandan Nath Date: Fri, 14 Oct 2011 02:58:25 +0000 Subject: ARM:AM33XX: Added timer support This patch adds timer support for AM33xx platform. Signed-off-by: Chandan Nath Signed-off-by: Sandeep Paulraj --- arch/arm/cpu/armv7/omap-common/Makefile | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/armv7/omap-common/Makefile b/arch/arm/cpu/armv7/omap-common/Makefile index 0b96b4789f..1dee81f22a 100644 --- a/arch/arm/cpu/armv7/omap-common/Makefile +++ b/arch/arm/cpu/armv7/omap-common/Makefile @@ -29,7 +29,9 @@ SOBJS := reset.o COBJS := timer.o COBJS += utils.o +ifdef CONFIG_OMAP COBJS += gpio.o +endif ifdef CONFIG_SPL_BUILD COBJS += spl.o -- cgit From 5289e83a8ca8c4a6613d2d019bad330816dbc2d4 Mon Sep 17 00:00:00 2001 From: Chandan Nath Date: Fri, 14 Oct 2011 02:58:26 +0000 Subject: ARM:AM33XX: Add support for TI AM335X EVM This patch adds basic support for booting the board. This patch adds support for the UART necessary to get to the u-boot prompt. Signed-off-by: Chandan Nath Signed-off-by: Sandeep Paulraj --- arch/arm/cpu/armv7/am33xx/Makefile | 2 +- arch/arm/cpu/armv7/am33xx/board.c | 66 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 arch/arm/cpu/armv7/am33xx/board.c (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/armv7/am33xx/Makefile b/arch/arm/cpu/armv7/am33xx/Makefile index 7ed667877b..6beafbbece 100644 --- a/arch/arm/cpu/armv7/am33xx/Makefile +++ b/arch/arm/cpu/armv7/am33xx/Makefile @@ -22,7 +22,7 @@ COBJS += clock.o COBJS += sys_info.o COBJS += ddr.o COBJS += emif4.o - +COBJS += board.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS) $(COBJS-y) $(SOBJS)) diff --git a/arch/arm/cpu/armv7/am33xx/board.c b/arch/arm/cpu/armv7/am33xx/board.c new file mode 100644 index 0000000000..2d6d359e5f --- /dev/null +++ b/arch/arm/cpu/armv7/am33xx/board.c @@ -0,0 +1,66 @@ +/* + * board.c + * + * Common board functions for AM33XX based boards + * + * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/ + * + * 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. + */ + +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE; +struct timer_reg *timerreg = (struct timer_reg *)DM_TIMER2_BASE; + +/* + * early system init of muxing and clocks. + */ +void s_init(u32 in_ddr) +{ + /* WDT1 is already running when the bootloader gets control + * Disable it to avoid "random" resets + */ + writel(0xAAAA, &wdtimer->wdtwspr); + while (readl(&wdtimer->wdtwwps) != 0x0) + ; + writel(0x5555, &wdtimer->wdtwspr); + while (readl(&wdtimer->wdtwwps) != 0x0) + ; + + /* Setup the PLLs and the clocks for the peripherals */ +#ifdef CONFIG_SETUP_PLL + pll_init(); +#endif + if (!in_ddr) + config_ddr(); +} + +/* Initialize timer */ +void init_timer(void) +{ + /* Reset the Timer */ + writel(0x2, (&timerreg->tsicrreg)); + + /* Wait until the reset is done */ + while (readl(&timerreg->tiocpcfgreg) & 1) + ; + + /* Start the Timer */ + writel(0x1, (&timerreg->tclrreg)); +} -- cgit From 23365af0992e939b12b85050212b44b7dfae3d39 Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Mon, 17 Oct 2011 08:46:53 +0000 Subject: davinci: remove config.mk file from the sources To compile TI Davinci SoC support the identical config.mk file from the cpu directory shall be used. Signed-off-by: Vladimir Zapolskiy Signed-off-by: Sandeep Paulraj --- arch/arm/cpu/arm926ejs/davinci/config.mk | 32 -------------------------------- 1 file changed, 32 deletions(-) delete mode 100644 arch/arm/cpu/arm926ejs/davinci/config.mk (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/arm926ejs/davinci/config.mk b/arch/arm/cpu/arm926ejs/davinci/config.mk deleted file mode 100644 index 565adda11d..0000000000 --- a/arch/arm/cpu/arm926ejs/davinci/config.mk +++ /dev/null @@ -1,32 +0,0 @@ -# -# (C) Copyright 2002 -# Gary Jennejohn, DENX Software Engineering, -# -# 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 -# - -PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float - -PLATFORM_CPPFLAGS += -march=armv5te -# ========================================================================= -# -# Supply options according to compiler version -# -# ========================================================================= -PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -- cgit From 3d90a2adcb1c240c9ef9e9088a4d49a40a3c9504 Mon Sep 17 00:00:00 2001 From: Lei Wen Date: Mon, 3 Oct 2011 20:33:41 +0000 Subject: ARM: pantheon: add mmc definition Signed-off-by: Lei Wen --- arch/arm/cpu/arm926ejs/pantheon/cpu.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/arm926ejs/pantheon/cpu.c b/arch/arm/cpu/arm926ejs/pantheon/cpu.c index efc9395b96..db9b348ad3 100644 --- a/arch/arm/cpu/arm926ejs/pantheon/cpu.c +++ b/arch/arm/cpu/arm926ejs/pantheon/cpu.c @@ -42,6 +42,9 @@ int arch_cpu_init(void) struct panthmpmu_registers *mpmu = (struct panthmpmu_registers*) PANTHEON_MPMU_BASE; + struct panthapmu_registers *apmu = + (struct panthapmu_registers *) PANTHEON_APMU_BASE; + /* set SEL_MRVL_ID bit in PANTHEON_CPU_CONF register */ val = readl(&cpuregs->cpu_conf); val = val | SET_MRVL_ID; @@ -65,6 +68,14 @@ int arch_cpu_init(void) writel(APBC_FNCLK | APBC_APBCLK, &apbclkres->twsi); #endif +#ifdef CONFIG_MV_SDHCI + /* Enable mmc clock */ + writel(APMU_PERI_CLK | APMU_AXI_CLK | APMU_PERI_RST | APMU_AXI_RST, + &apmu->sd1); + writel(APMU_PERI_CLK | APMU_AXI_CLK | APMU_PERI_RST | APMU_AXI_RST, + &apmu->sd3); +#endif + icache_enable(); return 0; -- cgit From 37fc0ed268dc5acacd3a83adafa26eb1a84e90af Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 24 Oct 2011 08:50:20 +0000 Subject: ARM: Add Calxeda Highbank platform Add basic support for Calxeda Highbank platform. Only minimal support with serial and SATA are included. Signed-off-by: Jason Hobbs Signed-off-by: Rob Herring Cc: Albert ARIBAUD --- arch/arm/cpu/armv7/highbank/Makefile | 46 +++++++++++++ arch/arm/cpu/armv7/highbank/timer.c | 123 +++++++++++++++++++++++++++++++++++ 2 files changed, 169 insertions(+) create mode 100644 arch/arm/cpu/armv7/highbank/Makefile create mode 100644 arch/arm/cpu/armv7/highbank/timer.c (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/armv7/highbank/Makefile b/arch/arm/cpu/armv7/highbank/Makefile new file mode 100644 index 0000000000..76faeb0fe1 --- /dev/null +++ b/arch/arm/cpu/armv7/highbank/Makefile @@ -0,0 +1,46 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# 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 +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).o + +COBJS := timer.o +SOBJS := + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/armv7/highbank/timer.c b/arch/arm/cpu/armv7/highbank/timer.c new file mode 100644 index 0000000000..d8a02888a2 --- /dev/null +++ b/arch/arm/cpu/armv7/highbank/timer.c @@ -0,0 +1,123 @@ +/* + * Copyright 2010-2011 Calxeda, Inc. + * + * Based on arm926ejs/mx27/timer.c + * + * 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 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, see . + */ + +#include +#include +#include /* for size_t */ +#include /* for NULL */ +#include +#include + +#undef SYSTIMER_BASE +#define SYSTIMER_BASE 0xFFF34000 /* Timer 0 and 1 base */ +#define SYSTIMER_RATE 150000000 + +static ulong timestamp; +static ulong lastinc; +static struct systimer *systimer_base = (struct systimer *)SYSTIMER_BASE; + +/* + * Start the timer + */ +int timer_init(void) +{ + /* + * Setup timer0 + */ + writel(SYSTIMER_RELOAD, &systimer_base->timer0load); + writel(SYSTIMER_RELOAD, &systimer_base->timer0value); + writel(SYSTIMER_EN | SYSTIMER_32BIT, &systimer_base->timer0control); + + reset_timer_masked(); + + return 0; + +} + +#define TICK_PER_TIME ((SYSTIMER_RATE + CONFIG_SYS_HZ / 2) / CONFIG_SYS_HZ) +#define NS_PER_TICK (1000000000 / SYSTIMER_RATE) + +static inline unsigned long long tick_to_time(unsigned long long tick) +{ + do_div(tick, TICK_PER_TIME); + return tick; +} + +static inline unsigned long long time_to_tick(unsigned long long time) +{ + return time * TICK_PER_TIME; +} + +static inline unsigned long long us_to_tick(unsigned long long us) +{ + unsigned long long tick = us << 16; + tick += NS_PER_TICK - 1; + do_div(tick, NS_PER_TICK); + return tick >> 16; +} + +unsigned long long get_ticks(void) +{ + ulong now = ~readl(&systimer_base->timer0value); + + if (now >= lastinc) /* normal mode (non roll) */ + /* move stamp forward with absolut diff ticks */ + timestamp += (now - lastinc); + else /* we have rollover of incrementer */ + timestamp += (0xFFFFFFFF - lastinc) + now; + lastinc = now; + return timestamp; +} + +/* + * Delay x useconds AND preserve advance timstamp value + * assumes timer is ticking at 1 msec + */ +void __udelay(ulong usec) +{ + unsigned long long tmp; + ulong tmo; + + tmo = us_to_tick(usec); + tmp = get_ticks() + tmo; /* get current timestamp */ + + while (get_ticks() < tmp) /* loop till event */ + /*NOP*/; +} + +ulong get_timer(ulong base) +{ + return get_timer_masked() - base; +} + +void reset_timer_masked(void) +{ + lastinc = ~readl(&systimer_base->timer0value); + timestamp = 0; +} + +void reset_timer(void) +{ + reset_timer_masked(); +} + +ulong get_timer_masked(void) +{ + return tick_to_time(get_ticks()); +} -- cgit