📄 board.c
字号:
#include <target/herrno.h>#include <target/htypes.h>#include <target/io.h>#include <target/mem.h>#include <target/str.h>#include <target/memzero.h>#include <target/flash.h>#if defined(ENABLE_ETH)#include <target/net/mac.h>#endif#include <mx3/ioregs.h>#include "memregions.h"#include "board.h"#include <target/param.h>char target_name[256];char *target_profile = target_name;struct board_info board_info;/**************************************************************************** * i.MX31 common function ****************************************************************************/void mxc_set_mux(u32 mux, u32 config){ u32 offset = (mux & ~0x03); u32 field = (mux & 0x03); u32 val; if (mux < 0x00c || 0x153 < mux) return; /* Invalid mux */ val = IO_IOMUXC(WORD, offset); val = (val & ~(0xff << (field * 8))); val |= ((config & 0xff) << (field * 8)); IO_IOMUXC(WORD, offset) = val; }u32mxc_get_mux(u32 mux){ u32 offset = (mux & ~0x03); u32 field = (mux & 0x03); u32 val; if (mux < 0x00c || 0x153 < mux) return -1; /* Invalid mux */ val = IO_IOMUXC(WORD, offset); return ((val >> (field * 8)) & 0xff);}void mxc_set_pad(u32 pad, u32 config){ u32 offset = (pad & ~0x03); u32 field = (pad & 0x03); u32 val; if (pad < 0x154 || 0x30a < pad) return; /* Invalid pad */ if (field >= 0x3) return; /* Invalid field */ val = IO_IOMUXC(WORD, offset); val = (val & ~(0x3ff << (field * 10))); val |= ((config & 0x3ff) << (field * 10)); IO_IOMUXC(WORD, offset) = val;}intmxc_get_gpio(u32 gpio){ u32 offset = (gpio / 32); u32 field = (gpio % 32); u32 psr; u32 base_addr[3] = { GPIO1_BASE_ADDR, GPIO2_BASE_ADDR, GPIO3_BASE_ADDR }; if (offset > 2) return -1; /* Invalid */ psr = IO_WORD(base_addr[offset] + PSR); return ((psr & (1 << field)) != 0);}voidmxc_set_gpio(u32 gpio, u32 direction, u32 data){ u32 offset = (gpio / 32); u32 field = (gpio % 32); u32 dr, gdir; u32 base_addr[3] = { GPIO1_BASE_ADDR, GPIO2_BASE_ADDR, GPIO3_BASE_ADDR }; if (offset > 2) return; /* Invalid */ gdir = IO_WORD(base_addr[offset] + GDIR); gdir &= (~(1 << field)); gdir |= ((direction ? 1 : 0) << field); IO_WORD(base_addr[offset] + GDIR) = gdir; if (direction) { dr = IO_WORD(base_addr[offset] + DR); dr &= (~(1 << field)); dr |= ((data ? 1 : 0) << field); IO_WORD(base_addr[offset] + DR) = dr; }}/**************************************************************************** * armadillo5x0 init function ****************************************************************************/static void init_mux(void){ /* Jumper */ mxc_set_mux(MUX_PIN(xJP1), MUX_O_GPIO | MUX_I_GPIO); mxc_set_mux(MUX_PIN(xJP2), MUX_O_GPIO | MUX_I_GPIO); /* CPU ID */ mxc_set_mux(MUX_PIN(xCPU1), MUX_O_GPIO | MUX_I_GPIO); mxc_set_mux(MUX_PIN(xCPU2), MUX_O_GPIO | MUX_I_GPIO); mxc_set_mux(MUX_PIN(xCPU3), MUX_O_GPIO | MUX_I_GPIO); /* LED & BASE ID */ mxc_set_mux(MUX_PIN(xLED1), MUX_O_GPIO | MUX_I_GPIO); mxc_set_mux(MUX_PIN(xLED2), MUX_O_GPIO | MUX_I_GPIO); mxc_set_mux(MUX_PIN(xLED3), MUX_O_GPIO | MUX_I_GPIO); mxc_set_mux(MUX_PIN(xLED4), MUX_O_GPIO | MUX_I_GPIO); mxc_set_mux(MUX_PIN(xLED5), MUX_O_GPIO | MUX_I_GPIO); /* UART1 */ mxc_set_mux(MUX_PIN(RXD1), MUX_O_FUNC | MUX_I_FUNC); mxc_set_mux(MUX_PIN(TXD1), MUX_O_FUNC | MUX_I_FUNC); mxc_set_mux(MUX_PIN(CTS1), MUX_O_FUNC | MUX_I_FUNC); mxc_set_mux(MUX_PIN(RTS1), MUX_O_FUNC | MUX_I_FUNC); /* UART2 */ mxc_set_mux(MUX_PIN(RXD2), MUX_O_FUNC | MUX_I_FUNC); mxc_set_mux(MUX_PIN(TXD2), MUX_O_FUNC | MUX_I_FUNC); mxc_set_mux(MUX_PIN(CTS2), MUX_O_FUNC | MUX_I_FUNC); mxc_set_mux(MUX_PIN(RTS2), MUX_O_FUNC | MUX_I_FUNC); /* CF */ mxc_set_mux(MUX_PIN(xCF_PWREN), MUX_O_GPIO | MUX_I_GPIO); mxc_set_gpio(GPIO_PIN(xCF_PWREN), GPIO_OUTPUT, GPIO_HIGH);/* OFF */}static void init_weim(void){ /* GPR Setting */ IO_IOMUXC(WORD, GPR) = 0x00002000; /* CS3: smc911x */ IO_WEIM(WORD, CSCR3U) = 0x00004803; IO_WEIM(WORD, CSCR3L) = 0x24002531; IO_WEIM(WORD, CSCR3A) = 0x00240000; }#define B9600 9600#define B115200 115200static voidinit_uart(void){ u32 uart_base[2] = {UART1_BASE_ADDR, UART2_BASE_ADDR}; int baud = B115200; int i; /* periferal clock(ipg_per_clk) use USB clock source(60MHz) */ IO_CCM(WORD, CCMR) &= ~(CCMR_PERCS); for (i=0; i<2; i++) { IO_WORD(uart_base[i] + UCR3) = 0x0704; IO_WORD(uart_base[i] + UFCR) = 0x0a01; IO_WORD(uart_base[i] + ONEMS) = 0x81ea; switch(baud){ case B115200: default: IO_WORD(uart_base[i] + UBIR) = 0x0fa2; IO_WORD(uart_base[i] + UBMR) = 0xfe80; break; } IO_WORD(uart_base[i] + UCR1) = (UCR1_UARTEN); IO_WORD(uart_base[i] + UCR2) = (UCR2_RXEN | UCR2_TXEN | 0x4021); IO_WORD(uart_base[i] + USR2) = 0xffff; IO_WORD(uart_base[i] + USR1) = 0xffff; }}static voidinit_i2c(void){ int i; u32 old_mux; old_mux = mxc_get_mux(MUX_PIN(CSPI2_MOSI)); mxc_set_mux(MUX_PIN(CSPI2_MOSI), MUX_O_FUNC | MUX_I_FUNC); IO_CSPI2(WORD, CONREG) = 0x00071f0b; for (i=0; i<8; i++) { /* wait TxFIFO empty */ while (!(IO_CSPI2(WORD, STATREG) & 0x0001)); IO_CSPI2(WORD, TXDATA) = 0x55555555; } /* wait busy */ while (!(IO_CSPI2(WORD, STATREG) & 0x0100)); IO_CSPI2(WORD, STATREG) = 0x0100; IO_CSPI2(WORD, CONREG) = 0x0; mxc_set_mux(MUX_PIN(CSPI2_MOSI), old_mux); }/**************************************************************************** * ****************************************************************************/intchange_clk(u32 clk, u32 clkss){ u32 ccmr; u32 prcs; u32 mpctl; u32 pdr0; ccmr = IO_CCM(WORD, CCMR); prcs = (ccmr & CCMR_PRCS); switch(clk){ case CLK_399MHZ: pdr0 = PDR0_399MHZ; mpctl = ((prcs == PRCS_FPM) ? MPCTL_FPM_399 : MPCTL_CKIH_399); break; case CLK_532MHZ: pdr0 = PDR0_532MHZ; mpctl = ((prcs == PRCS_FPM) ? MPCTL_FPM_532 : MPCTL_CKIH_532); break; default: return -1; } IO_CCM(WORD, CCMR) = ((ccmr & ~(CCMR_MPE | CCMR_SPE | CCMR_UPE)) | CCMR_MDS); IO_CCM(WORD, PDR0) = pdr0; IO_CCM(WORD, MPCTL) = mpctl; IO_CCM(WORD, CCMR) = ccmr; return 0;}/**************************************************************************** * LED function ****************************************************************************/void led_on(void){ mxc_set_gpio(GPIO_PIN(xLED5), 1, 1);}void led_off(void){ mxc_set_gpio(GPIO_PIN(xLED5), 1, 0);}/**************************************************************************** * DELAY function **************************************************************************** * Note. * __udelay() : just a temperary implementation. ****************************************************************************/#define UDELAY_TIC_399MHz (5)#define UDELAY_TIC (UDELAY_TIC_399MHz)#define __udelay() \({ \ __asm__ volatile ( \ " mov r0, %0;" \ "udelay_loop:" \ " subs r0, r0, #0x01;" \ " bne udelay_loop;" \ : \ : "r" (UDELAY_TIC) \ : "r0", "memory" \ ); \})voidudelay(unsigned long usec){ while (usec--) __udelay();}voidmdelay(unsigned long msec){ while (msec--) udelay(1000);}/**************************************************************************** * ****************************************************************************/int is_autoboot_mode(void){ return (!board_info.jumper1);}/**************************************************************************** * get_board_info ****************************************************************************/static int get_board_info(void){ memzero(&board_info, sizeof(struct board_info)); /* Jumper */ mxc_set_gpio(GPIO_PIN(xJP1), GPIO_INPUT, 0); mxc_set_gpio(GPIO_PIN(xJP2), GPIO_INPUT, 0); board_info.jumper1 = mxc_get_gpio(GPIO_PIN(xJP1)) ? 0 : 1; board_info.jumper2 = mxc_get_gpio(GPIO_PIN(xJP2)) ? 0 : 1; /* CPU Board ID */ mxc_set_gpio(GPIO_PIN(xCPU1), GPIO_INPUT, 0); mxc_set_gpio(GPIO_PIN(xCPU2), GPIO_INPUT, 0); mxc_set_gpio(GPIO_PIN(xCPU3), GPIO_INPUT, 0); board_info.cpu_board_id = mxc_get_gpio(GPIO_PIN(xCPU1)) ? (1 << 0):0; board_info.cpu_board_id |= mxc_get_gpio(GPIO_PIN(xCPU1)) ? (1 << 1):0; board_info.cpu_board_id |= mxc_get_gpio(GPIO_PIN(xCPU1)) ? (1 << 2):0; /* BASE Board ID */ mxc_set_gpio(GPIO_PIN(xID1), GPIO_INPUT, 0); mxc_set_gpio(GPIO_PIN(xID2), GPIO_INPUT, 0); mxc_set_gpio(GPIO_PIN(xID3), GPIO_INPUT, 0); mxc_set_gpio(GPIO_PIN(xID4), GPIO_INPUT, 0); board_info.base_board_id = mxc_get_gpio(GPIO_PIN(xID1)) ? (1 << 0):0; board_info.base_board_id |= mxc_get_gpio(GPIO_PIN(xID2)) ? (1 << 1):0; board_info.base_board_id |= mxc_get_gpio(GPIO_PIN(xID3)) ? (1 << 2):0; board_info.base_board_id |= mxc_get_gpio(GPIO_PIN(xID4)) ? (1 << 3):0; mxc_set_gpio(GPIO_PIN(xID1), GPIO_OUTPUT, 0); mxc_set_gpio(GPIO_PIN(xID2), GPIO_OUTPUT, 0); mxc_set_gpio(GPIO_PIN(xID3), GPIO_OUTPUT, 0); mxc_set_gpio(GPIO_PIN(xID4), GPIO_OUTPUT, 0); return 0;}/**************************************************************************** * ****************************************************************************/static char *get_board_name(u32 id){ return "Armadillo-500";}static voidupdate_target_profile(void){ int len; memset(target_name, 0, TARGET_NAME_LEN); len = strlen(get_board_name(0)); strcpy(&target_name[0], get_board_name(0)); if (strlen(PROFILE_STRING)) { target_name[len] = '/'; strcpy(&target_name[len + 1], PROFILE_STRING); target_name[len + 1 + strlen(PROFILE_STRING)] = 0; /* NULL */ }}/**************************************************************************** * board_init ****************************************************************************/void board_init(void){ int ch; init_mux(); init_weim(); init_uart(); init_i2c(); /* get board info */ get_board_info(); /* update target_profile string */ update_target_profile();#if defined(RELOCATE) /* serial function initialize */ if (check_param("console=ttymxc0")) ch = 1; else if (check_param("console=ttymxc1")) ch = 2; else if (check_param("console=")) ch = 0; else ch = 1; if (!is_autoboot_mode()) if (ch == 0)#endif ch = 1; change_serial_channel(ch); /* flash function initialize */ flash_initialize(FLASH_TYPE_INTEL, FLASH_START);}/**************************************************************************** * get_board_info ****************************************************************************/static int setbootdevice_cmdfunc(int argc, char **argv){ /* initialize parameter: bootdevice, using default flash */ if (!check_param("@bootdevice")) { char *c_argv[2] = {argv[0], "flash"}; sethermit_param(2, c_argv, "@bootdevice"); } if (argc > 1) if (strcmp(argv[1], "flash") != 0 && strcmp(argv[1], "hda1") != 0 && strcmp(argv[1], "hda2") != 0 && strcmp(argv[1], "hda3") != 0 && strcmp(argv[1], "hda4") != 0 && strcmp(argv[1], "hda") != 0) return -H_EINVAL; return sethermit_param(argc, argv, "@bootdevice");}/**************************************************************************** * get_board_info ****************************************************************************/static int setclock_cmdfunc(int argc, char *argv[]){ /* initialize parameter: clock, using default 400 */ if (!check_param("@clock")) { char *c_argv[2] = {argv[0], "400"}; sethermit_param(2, c_argv, "@clock"); } if (argc > 1) if (strcmp(argv[1], "532") != 0 && strcmp(argv[1], "400") != 0) return -H_EINVAL; return sethermit_param(argc, argv, "@clock");}/**************************************************************************** * info_cmdfunc ****************************************************************************/static intinfo_cmdfunc(int argc, char *argv[]){ hprintf("CPU Silicon Rev: %p\n", IO_IIM(WORD, SREV) & 0xff); hprintf("CPU Board ID : %p\n", board_info.cpu_board_id); hprintf("BASE Board ID : %p\n", board_info.base_board_id); hprintf("HAB-TYPE : %p\n", IO_IIM(WORD, HAB1) & 0x07);#if defined(ENABLE_ETH) hprintf("MAC Address : "); mac_command.func(0, 0);#endif return 0;}const command_t setbootdevice_command = { "setbootdevice", "<flash/hda[1:4]>", "linux kernel location", &setbootdevice_cmdfunc };const command_t setclock_command = {"setclock", "<400/532>", "set mcu_clk", &setclock_cmdfunc};const command_t info_command = { "info", "", "display board info", &info_cmdfunc };COMMAND_ABBR(setbootdevice_command, 'l');COMMAND(setclock_command);COMMAND(info_command);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -