diff options
Diffstat (limited to 'package/uboot-xburst/files/cpu/mips/jz4740.c')
-rw-r--r-- | package/uboot-xburst/files/cpu/mips/jz4740.c | 559 |
1 files changed, 0 insertions, 559 deletions
diff --git a/package/uboot-xburst/files/cpu/mips/jz4740.c b/package/uboot-xburst/files/cpu/mips/jz4740.c deleted file mode 100644 index 5ae57971d7..0000000000 --- a/package/uboot-xburst/files/cpu/mips/jz4740.c +++ /dev/null @@ -1,559 +0,0 @@ -/* - * Jz4740 common routines - * - * Copyright (c) 2006 - * Ingenic Semiconductor, <jlwei@ingenic.cn> - * - * 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 <config.h> - -#ifdef CONFIG_JZ4740 -#include <common.h> -#include <command.h> -#include <asm/jz4740.h> - -extern void board_early_init(void); - -/* PLL output clock = EXTAL * NF / (NR * NO) - * - * NF = FD + 2, NR = RD + 2 - * NO = 1 (if OD = 0), NO = 2 (if OD = 1 or 2), NO = 4 (if OD = 3) - */ -void pll_init(void) -{ - register unsigned int cfcr, plcr1; - int n2FR[33] = { - 0, 0, 1, 2, 3, 0, 4, 0, 5, 0, 0, 0, 6, 0, 0, 0, - 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, - 9 - }; - int div[5] = {1, 3, 3, 3, 3}; /* divisors of I:S:P:L:M */ - int nf, pllout2; - - cfcr = CPM_CPCCR_CLKOEN | - CPM_CPCCR_PCS | - (n2FR[div[0]] << CPM_CPCCR_CDIV_BIT) | - (n2FR[div[1]] << CPM_CPCCR_HDIV_BIT) | - (n2FR[div[2]] << CPM_CPCCR_PDIV_BIT) | - (n2FR[div[3]] << CPM_CPCCR_MDIV_BIT) | - (n2FR[div[4]] << CPM_CPCCR_LDIV_BIT); - - pllout2 = (cfcr & CPM_CPCCR_PCS) ? CONFIG_SYS_CPU_SPEED : (CONFIG_SYS_CPU_SPEED / 2); - - /* Init USB Host clock, pllout2 must be n*48MHz */ - REG_CPM_UHCCDR = pllout2 / 48000000 - 1; - - nf = CONFIG_SYS_CPU_SPEED * 2 / CONFIG_SYS_EXTAL; - plcr1 = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | /* FD */ - (0 << CPM_CPPCR_PLLN_BIT) | /* RD=0, NR=2 */ - (0 << CPM_CPPCR_PLLOD_BIT) | /* OD=0, NO=1 */ - (0x20 << CPM_CPPCR_PLLST_BIT) | /* PLL stable time */ - CPM_CPPCR_PLLEN; /* enable PLL */ - - /* init PLL */ - REG_CPM_CPCCR = cfcr; - REG_CPM_CPPCR = plcr1; -} - -void pll_add_test(int new_freq) -{ - register unsigned int cfcr, plcr1; - int n2FR[33] = { - 0, 0, 1, 2, 3, 0, 4, 0, 5, 0, 0, 0, 6, 0, 0, 0, - 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, - 9 - }; - int div[5] = {1, 4, 4, 4, 4}; /* divisors of I:S:P:M:L */ - int nf, pllout2; - - cfcr = CPM_CPCCR_CLKOEN | - (n2FR[div[0]] << CPM_CPCCR_CDIV_BIT) | - (n2FR[div[1]] << CPM_CPCCR_HDIV_BIT) | - (n2FR[div[2]] << CPM_CPCCR_PDIV_BIT) | - (n2FR[div[3]] << CPM_CPCCR_MDIV_BIT) | - (n2FR[div[4]] << CPM_CPCCR_LDIV_BIT); - - pllout2 = (cfcr & CPM_CPCCR_PCS) ? new_freq : (new_freq / 2); - - /* Init UHC clock */ - REG_CPM_UHCCDR = pllout2 / 48000000 - 1; - - /* nf = new_freq * 2 / CONFIG_SYS_EXTAL; */ - nf = new_freq / 1000000; /* step length is 1M */ - plcr1 = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | /* FD */ - (10 << CPM_CPPCR_PLLN_BIT) | /* RD=0, NR=2 */ - (0 << CPM_CPPCR_PLLOD_BIT) | /* OD=0, NO=1 */ - (0x20 << CPM_CPPCR_PLLST_BIT) | /* PLL stable time */ - CPM_CPPCR_PLLEN; /* enable PLL */ - - /* init PLL */ - REG_CPM_CPCCR = cfcr; - REG_CPM_CPPCR = plcr1; -} - -void calc_clocks_add_test(void) -{ - DECLARE_GLOBAL_DATA_PTR; - - unsigned int pllout; - unsigned int div[10] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; - - pllout = __cpm_get_pllout(); - - gd->cpu_clk = pllout / div[__cpm_get_cdiv()]; - gd->sys_clk = pllout / div[__cpm_get_hdiv()]; - gd->per_clk = pllout / div[__cpm_get_pdiv()]; - gd->mem_clk = pllout / div[__cpm_get_mdiv()]; - gd->dev_clk = CONFIG_SYS_EXTAL; -} - -void sdram_add_test(int new_freq) -{ - register unsigned int dmcr, sdmode, tmp, cpu_clk, mem_clk, ns; - - unsigned int cas_latency_sdmr[2] = { - EMC_SDMR_CAS_2, - EMC_SDMR_CAS_3, - }; - - unsigned int cas_latency_dmcr[2] = { - 1 << EMC_DMCR_TCL_BIT, /* CAS latency is 2 */ - 2 << EMC_DMCR_TCL_BIT /* CAS latency is 3 */ - }; - - int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; - - cpu_clk = new_freq; - mem_clk = cpu_clk * div[__cpm_get_cdiv()] / div[__cpm_get_mdiv()]; - - REG_EMC_RTCSR = EMC_RTCSR_CKS_DISABLE; - REG_EMC_RTCOR = 0; - REG_EMC_RTCNT = 0; - - /* Basic DMCR register value. */ - dmcr = ((SDRAM_ROW-11)<<EMC_DMCR_RA_BIT) | - ((SDRAM_COL-8)<<EMC_DMCR_CA_BIT) | - (SDRAM_BANK4<<EMC_DMCR_BA_BIT) | - (SDRAM_BW16<<EMC_DMCR_BW_BIT) | - EMC_DMCR_EPIN | - cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)]; - - /* SDRAM timimg parameters */ - ns = 1000000000 / mem_clk; - -#if 0 - tmp = SDRAM_TRAS/ns; - if (tmp < 4) tmp = 4; - if (tmp > 11) tmp = 11; - dmcr |= ((tmp-4) << EMC_DMCR_TRAS_BIT); - - tmp = SDRAM_RCD/ns; - if (tmp > 3) tmp = 3; - dmcr |= (tmp << EMC_DMCR_RCD_BIT); - - tmp = SDRAM_TPC/ns; - if (tmp > 7) tmp = 7; - dmcr |= (tmp << EMC_DMCR_TPC_BIT); - - tmp = SDRAM_TRWL/ns; - if (tmp > 3) tmp = 3; - dmcr |= (tmp << EMC_DMCR_TRWL_BIT); - - tmp = (SDRAM_TRAS + SDRAM_TPC)/ns; - if (tmp > 14) tmp = 14; - dmcr |= (((tmp + 1) >> 1) << EMC_DMCR_TRC_BIT); -#else - dmcr |= 0xfffc; -#endif - - /* First, precharge phase */ - REG_EMC_DMCR = dmcr; - - /* Set refresh registers */ - tmp = SDRAM_TREF/ns; - tmp = tmp/64 + 1; - if (tmp > 0xff) tmp = 0xff; - - REG_EMC_RTCOR = tmp; - REG_EMC_RTCSR = EMC_RTCSR_CKS_64; /* Divisor is 64, CKO/64 */ - - /* SDRAM mode values */ - sdmode = EMC_SDMR_BT_SEQ | - EMC_SDMR_OM_NORMAL | - EMC_SDMR_BL_4 | - cas_latency_sdmr[((SDRAM_CASL == 3) ? 1 : 0)]; - - /* precharge all chip-selects */ - REG8(EMC_SDMR0|sdmode) = 0; - - /* wait for precharge, > 200us */ - tmp = (cpu_clk / 1000000) * 200; - while (tmp--); - - /* enable refresh and set SDRAM mode */ - REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET; - - /* write sdram mode register for each chip-select */ - REG8(EMC_SDMR0|sdmode) = 0; - - /* everything is ok now */ -} - -void sdram_init(void) -{ - register unsigned int dmcr0, dmcr, sdmode, tmp, cpu_clk, mem_clk, ns; - - unsigned int cas_latency_sdmr[2] = { - EMC_SDMR_CAS_2, - EMC_SDMR_CAS_3, - }; - - unsigned int cas_latency_dmcr[2] = { - 1 << EMC_DMCR_TCL_BIT, /* CAS latency is 2 */ - 2 << EMC_DMCR_TCL_BIT /* CAS latency is 3 */ - }; - - int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; - - cpu_clk = CONFIG_SYS_CPU_SPEED; - mem_clk = cpu_clk * div[__cpm_get_cdiv()] / div[__cpm_get_mdiv()]; - - REG_EMC_BCR = 0; /* Disable bus release */ - REG_EMC_RTCSR = 0; /* Disable clock for counting */ - - /* Fault DMCR value for mode register setting*/ -#define SDRAM_ROW0 11 -#define SDRAM_COL0 8 -#define SDRAM_BANK40 0 - - dmcr0 = ((SDRAM_ROW0-11)<<EMC_DMCR_RA_BIT) | - ((SDRAM_COL0-8)<<EMC_DMCR_CA_BIT) | - (SDRAM_BANK40<<EMC_DMCR_BA_BIT) | - (SDRAM_BW16<<EMC_DMCR_BW_BIT) | - EMC_DMCR_EPIN | - cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)]; - - /* Basic DMCR value */ - dmcr = ((SDRAM_ROW-11)<<EMC_DMCR_RA_BIT) | - ((SDRAM_COL-8)<<EMC_DMCR_CA_BIT) | - (SDRAM_BANK4<<EMC_DMCR_BA_BIT) | - (SDRAM_BW16<<EMC_DMCR_BW_BIT) | - EMC_DMCR_EPIN | - cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)]; - - /* SDRAM timimg */ - ns = 1000000000 / mem_clk; - tmp = SDRAM_TRAS/ns; - if (tmp < 4) tmp = 4; - if (tmp > 11) tmp = 11; - dmcr |= ((tmp-4) << EMC_DMCR_TRAS_BIT); - tmp = SDRAM_RCD/ns; - if (tmp > 3) tmp = 3; - dmcr |= (tmp << EMC_DMCR_RCD_BIT); - tmp = SDRAM_TPC/ns; - if (tmp > 7) tmp = 7; - dmcr |= (tmp << EMC_DMCR_TPC_BIT); - tmp = SDRAM_TRWL/ns; - if (tmp > 3) tmp = 3; - dmcr |= (tmp << EMC_DMCR_TRWL_BIT); - tmp = (SDRAM_TRAS + SDRAM_TPC)/ns; - if (tmp > 14) tmp = 14; - dmcr |= (((tmp + 1) >> 1) << EMC_DMCR_TRC_BIT); - - /* SDRAM mode value */ - sdmode = EMC_SDMR_BT_SEQ | - EMC_SDMR_OM_NORMAL | - EMC_SDMR_BL_4 | - cas_latency_sdmr[((SDRAM_CASL == 3) ? 1 : 0)]; - - /* Stage 1. Precharge all banks by writing SDMR with DMCR.MRSET=0 */ - REG_EMC_DMCR = dmcr; - REG8(EMC_SDMR0|sdmode) = 0; - - /* Wait for precharge, > 200us */ - tmp = (cpu_clk / 1000000) * 1000; - while (tmp--); - - /* Stage 2. Enable auto-refresh */ - REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH; - - tmp = SDRAM_TREF/ns; - tmp = tmp/64 + 1; - if (tmp > 0xff) tmp = 0xff; - REG_EMC_RTCOR = tmp; - REG_EMC_RTCNT = 0; - REG_EMC_RTCSR = EMC_RTCSR_CKS_64; /* Divisor is 64, CKO/64 */ - - /* Wait for number of auto-refresh cycles */ - tmp = (cpu_clk / 1000000) * 1000; - while (tmp--); - - /* Stage 3. Mode Register Set */ - REG_EMC_DMCR = dmcr0 | EMC_DMCR_RFSH | EMC_DMCR_MRSET; - REG8(EMC_SDMR0|sdmode) = 0; - - /* Set back to basic DMCR value */ - REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET; - - /* everything is ok now */ -} - -#ifndef CONFIG_NAND_SPL - -static void calc_clocks(void) -{ - DECLARE_GLOBAL_DATA_PTR; - - unsigned int pllout; - unsigned int div[10] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; - - pllout = __cpm_get_pllout(); - - gd->cpu_clk = pllout / div[__cpm_get_cdiv()]; - gd->sys_clk = pllout / div[__cpm_get_hdiv()]; - gd->per_clk = pllout / div[__cpm_get_pdiv()]; - gd->mem_clk = pllout / div[__cpm_get_mdiv()]; - gd->dev_clk = CONFIG_SYS_EXTAL; -} - -static void rtc_init(void) -{ - unsigned long rtcsta; - - while ( !__rtc_write_ready()) ; - __rtc_enable_alarm(); /* enable alarm */ - - while ( !__rtc_write_ready()) - ; - REG_RTC_RGR = 0x00007fff; /* type value */ - - while ( !__rtc_write_ready()) - ; - REG_RTC_HWFCR = 0x0000ffe0; /* Power on delay 2s */ - - while ( !__rtc_write_ready()) - ; - REG_RTC_HRCR = 0x00000fe0; /* reset delay 125ms */ -#if 0 - while ( !__rtc_write_ready()) - ; - rtcsta = REG_RTC_HWRSR; - while ( !__rtc_write_ready()) - ; - if (rtcsta & 0x33) { - if (rtcsta & 0x10) { - while ( !__rtc_write_ready()) - ; - REG_RTC_RSR = 0x0; - } - while ( !__rtc_write_ready()) - ; - REG_RTC_HWRSR = 0x0; - } -#endif -} - -/* - * jz4740 board init routine - */ -int jz_board_init(void) -{ - board_early_init(); /* init gpio, pll etc. */ -#ifndef CONFIG_NAND_U_BOOT - pll_init(); /* init PLL */ - sdram_init(); /* init sdram memory */ -#endif - calc_clocks(); /* calc the clocks */ - rtc_init(); /* init rtc on any reset: */ - return 0; -} - -/* U-Boot common routines */ -phys_size_t initdram(int board_type) -{ - u32 dmcr; - u32 rows, cols, dw, banks; - ulong size; - - dmcr = REG_EMC_DMCR; - rows = 11 + ((dmcr & EMC_DMCR_RA_MASK) >> EMC_DMCR_RA_BIT); - cols = 8 + ((dmcr & EMC_DMCR_CA_MASK) >> EMC_DMCR_CA_BIT); - dw = (dmcr & EMC_DMCR_BW) ? 2 : 4; - banks = (dmcr & EMC_DMCR_BA) ? 4 : 2; - - size = (1 << (rows + cols)) * dw * banks; - - return size; -} - -/* - * Timer routines - */ - -#define TIMER_CHAN 0 -#define TIMER_FDATA 0xffff /* Timer full data value */ -#define TIMER_HZ CONFIG_SYS_HZ - -#define READ_TIMER REG_TCU_TCNT(TIMER_CHAN) /* macro to read the 16 bit timer */ - -static ulong timestamp; -static ulong lastdec; - -void reset_timer_masked (void); -ulong get_timer_masked (void); -void udelay_masked (unsigned long usec); - -/* - * timer without interrupts - */ - -int timer_init(void) -{ - REG_TCU_TCSR(TIMER_CHAN) = TCU_TCSR_PRESCALE256 | TCU_TCSR_EXT_EN; - REG_TCU_TCNT(TIMER_CHAN) = 0; - REG_TCU_TDHR(TIMER_CHAN) = 0; - REG_TCU_TDFR(TIMER_CHAN) = TIMER_FDATA; - - REG_TCU_TMSR = (1 << TIMER_CHAN) | (1 << (TIMER_CHAN + 16)); /* mask irqs */ - REG_TCU_TSCR = (1 << TIMER_CHAN); /* enable timer clock */ - REG_TCU_TESR = (1 << TIMER_CHAN); /* start counting up */ - - lastdec = 0; - timestamp = 0; - - return 0; -} - -void reset_timer(void) -{ - reset_timer_masked (); -} - -ulong get_timer(ulong base) -{ - return get_timer_masked () - base; -} - -void set_timer(ulong t) -{ - timestamp = t; -} - -void udelay (unsigned long usec) -{ - ulong tmo,tmp; - - /* normalize */ - if (usec >= 1000) { - tmo = usec / 1000; - tmo *= TIMER_HZ; - tmo /= 1000; - } - else { - if (usec >= 1) { - tmo = usec * TIMER_HZ; - tmo /= (1000*1000); - } - else - tmo = 1; - } - - /* check for rollover during this delay */ - tmp = get_timer (0); - if ((tmp + tmo) < tmp ) - reset_timer_masked(); /* timer would roll over */ - else - tmo += tmp; - - while (get_timer_masked () < tmo); -} - -void reset_timer_masked (void) -{ - /* reset time */ - lastdec = READ_TIMER; - timestamp = 0; -} - -ulong get_timer_masked (void) -{ - ulong now = READ_TIMER; - - if (lastdec <= now) { - /* normal mode */ - timestamp += (now - lastdec); - } else { - /* we have an overflow ... */ - timestamp += TIMER_FDATA + now - lastdec; - } - lastdec = now; - - return timestamp; -} - -void udelay_masked (unsigned long usec) -{ - ulong tmo; - ulong endtime; - signed long diff; - - /* normalize */ - if (usec >= 1000) { - tmo = usec / 1000; - tmo *= TIMER_HZ; - tmo /= 1000; - } else { - if (usec > 1) { - tmo = usec * TIMER_HZ; - tmo /= (1000*1000); - } else { - tmo = 1; - } - } - - endtime = get_timer_masked () + tmo; - - do { - ulong now = get_timer_masked (); - diff = endtime - now; - } while (diff >= 0); -} - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On MIPS it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return get_timer(0); -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On MIPS it returns the number of timer ticks per second. - */ -ulong get_tbclk (void) -{ - return TIMER_HZ; -} - -#endif /* CONFIG_NAND_SPL */ - -/* End of timer routine. */ - -#endif |