From ae691e5719c48f1d2826cb72722497d1d162765b Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Wed, 21 Jan 2009 17:24:49 +0100 Subject: MIPS: Add VCT board series support (Part 2/3) Signed-off-by: Stefan Roese --- board/micronas/vct/ehci.c | 110 +++++++ board/micronas/vct/gpio.c | 88 ++++++ board/micronas/vct/scc.c | 669 ++++++++++++++++++++++++++++++++++++++++ board/micronas/vct/scc.h | 205 ++++++++++++ board/micronas/vct/smc_eeprom.c | 394 +++++++++++++++++++++++ board/micronas/vct/top.c | 289 +++++++++++++++++ board/micronas/vct/u-boot.lds | 71 +++++ board/micronas/vct/vct.c | 117 +++++++ board/micronas/vct/vct.h | 104 +++++++ 9 files changed, 2047 insertions(+) create mode 100644 board/micronas/vct/ehci.c create mode 100644 board/micronas/vct/gpio.c create mode 100644 board/micronas/vct/scc.c create mode 100644 board/micronas/vct/scc.h create mode 100644 board/micronas/vct/smc_eeprom.c create mode 100644 board/micronas/vct/top.c create mode 100644 board/micronas/vct/u-boot.lds create mode 100644 board/micronas/vct/vct.c create mode 100644 board/micronas/vct/vct.h (limited to 'board/micronas') diff --git a/board/micronas/vct/ehci.c b/board/micronas/vct/ehci.c new file mode 100644 index 000000000..d04bdceac --- /dev/null +++ b/board/micronas/vct/ehci.c @@ -0,0 +1,110 @@ +/* + * (C) Copyright 2009 Stefan Roese , DENX Software Engineering + * + * Original Author Guenter Gebhardt + * Copyright (C) 2006 Micronas GmbH + * + * 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 + +#include "vct.h" + +int vct_ehci_hcd_init(u32 *hccr, u32 *hcor) +{ + int retval; + u32 val; + u32 addr; + + dcgu_set_reset_switch(DCGU_HW_MODULE_USB_24, DCGU_SWITCH_ON); + dcgu_set_reset_switch(DCGU_HW_MODULE_USB_60, DCGU_SWITCH_ON); + dcgu_set_clk_switch(DCGU_HW_MODULE_USB_24, DCGU_SWITCH_ON); + dcgu_set_clk_switch(DCGU_HW_MODULE_USB_PLL, DCGU_SWITCH_ON); + dcgu_set_reset_switch(DCGU_HW_MODULE_USB_24, DCGU_SWITCH_OFF); + + /* Wait until (DCGU_USBPHY_STAT == 7) */ + addr = DCGU_USBPHY_STAT(DCGU_BASE); + val = reg_read(addr); + while (val != 7) + val = reg_read(addr); + + dcgu_set_clk_switch(DCGU_HW_MODULE_USB_60, DCGU_SWITCH_ON); + dcgu_set_reset_switch(DCGU_HW_MODULE_USB_60, DCGU_SWITCH_OFF); + + retval = scc_reset(SCC_USB_RW, 0); + if (retval) { + printf("scc_reset(SCC_USB_RW, 0) returned: 0x%x\n", retval); + return retval; + } else { + retval = scc_reset(SCC_CPU1_SPDMA_RW, 0); + if (retval) { + printf("scc_reset(SCC_CPU1_SPDMA_RW, 0) returned: 0x%x\n", + retval); + return retval; + } + } + + if (!retval) { + /* + * For the AGU bypass, where the SCC client provides full + * physical address + */ + scc_set_usb_address_generation_mode(1); + scc_setup_dma(SCC_USB_RW, BCU_USB_BUFFER_1, DMA_LINEAR, + USE_NO_FH, DMA_READ, 0); + scc_setup_dma(SCC_CPU1_SPDMA_RW, BCU_USB_BUFFER_1, DMA_LINEAR, + USE_NO_FH, DMA_WRITE, 0); + scc_setup_dma(SCC_USB_RW, BCU_USB_BUFFER_0, DMA_LINEAR, + USE_NO_FH, DMA_WRITE, 0); + scc_setup_dma(SCC_CPU1_SPDMA_RW, BCU_USB_BUFFER_0, DMA_LINEAR, + USE_NO_FH, DMA_READ, 0); + + /* Enable memory interface */ + scc_enable(SCC_USB_RW, 1); + + /* Start (start_cmd=0) DMAs */ + scc_dma_cmd(SCC_USB_RW, DMA_START, 0, DMA_READ); + scc_dma_cmd(SCC_USB_RW, DMA_START, 0, DMA_WRITE); + } else { + printf("Cannot configure USB memory channel.\n"); + printf("USB can not access RAM. SCC configuration failed.\n"); + return retval; + } + + /* Wait a short while */ + udelay(300000); + + reg_write(USBH_BURSTSIZE(USBH_BASE), 0x00001c1c); + + /* Set EHCI structures and DATA in RAM */ + reg_write(USBH_USBHMISC(USBH_BASE), 0x00840003); + /* Set USBMODE to bigendian and set host mode */ + reg_write(USBH_USBMODE(USBH_BASE), 0x00000007); + + /* + * USBH_BURSTSIZE MUST EQUAL 0x00001c1c in order for + * 512 byte USB transfers on the bulk pipe to work properly. + * Set USBH_BURSTSIZE to 0x00001c1c + */ + reg_write(USBH_BURSTSIZE(USBH_BASE), 0x00001c1c); + + /* Insert access register addresses */ + *hccr = REG_GLOBAL_START_ADDR + USBH_CAPLENGTH(USBH_BASE); + *hcor = REG_GLOBAL_START_ADDR + USBH_USBCMD(USBH_BASE); + + return 0; +} diff --git a/board/micronas/vct/gpio.c b/board/micronas/vct/gpio.c new file mode 100644 index 000000000..2c113be26 --- /dev/null +++ b/board/micronas/vct/gpio.c @@ -0,0 +1,88 @@ +/* + * (C) Copyright 2008 Stefan Roese , DENX Software Engineering + * + * 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 +#include +#include "vct.h" + +/* + * Find out to which of the 2 gpio modules the pin specified in the + * argument belongs: + * GPIO_MODULE yields 0 for pins 0 to 31, + * 1 for pins 32 to 63 + */ +#define GPIO_MODULE(pin) ((pin) >> 5) + +/* + * Bit position within a 32-bit peripheral register (where every + * bit is one bitslice) + */ +#define MASK(pin) (1 << ((pin) & 0x1F)) +#define BASE_ADDR(mod) module_base[mod] + +/* + * Lookup table for transforming gpio module number 0 to 2 to + * address offsets + */ +static u32 module_base[] = { + GPIO1_BASE, + GPIO2_BASE +}; + +static void clrsetbits(u32 addr, u32 and_mask, u32 or_mask) +{ + reg_write(addr, (reg_read(addr) & ~and_mask) | or_mask); +} + +int vct_gpio_dir(int pin, int dir) +{ + u32 gpio_base; + + gpio_base = BASE_ADDR(GPIO_MODULE(pin)); + + if (dir == 0) + clrsetbits(GPIO_SWPORTA_DDR(gpio_base), MASK(pin), 0); + else + clrsetbits(GPIO_SWPORTA_DDR(gpio_base), 0, MASK(pin)); + + return 0; +} + +void vct_gpio_set(int pin, int val) +{ + u32 gpio_base; + + gpio_base = BASE_ADDR(GPIO_MODULE(pin)); + + if (val == 0) + clrsetbits(GPIO_SWPORTA_DR(gpio_base), MASK(pin), 0); + else + clrsetbits(GPIO_SWPORTA_DR(gpio_base), 0, MASK(pin)); +} + +int vct_gpio_get(int pin) +{ + u32 gpio_base; + u32 value; + + gpio_base = BASE_ADDR(GPIO_MODULE(pin)); + value = reg_read(GPIO_EXT_PORTA(gpio_base)); + + return ((value & MASK(pin)) ? 1 : 0); +} diff --git a/board/micronas/vct/scc.c b/board/micronas/vct/scc.c new file mode 100644 index 000000000..0368183e0 --- /dev/null +++ b/board/micronas/vct/scc.c @@ -0,0 +1,669 @@ +/* + * (C) Copyright 2009 Stefan Roese , DENX Software Engineering + * + * Copyright (C) 2006 Micronas GmbH + * + * 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 +#include + +#include "vct.h" + +/* + * List of statically defined buffers per SCC. + * The first entry in the table is the number of fixed buffers + * followed by the list of buffer IDs + */ +static u32 buffer_list_0[] = { 6, 120, 121, 122, 123, 139, 140 }; +static u32 buffer_list_1[] = { 6, 120, 121, 122, 123, 139, 140 }; +static u32 buffer_list_2[] = { 5, 124, 125, 126, 139, 140 }; +static u32 buffer_list_3[] = { 5, 124, 125, 126, 139, 140 }; +static u32 buffer_list_4[] = { 5, 124, 125, 126, 139, 140 }; +static u32 buffer_list_5[] = { 3, 127, 139, 140 }; +static u32 buffer_list_6[] = { 3, 127, 139, 140 }; +static u32 buffer_list_7[] = { 6, 128, 129, 130, 131, 139, 140 }; +static u32 buffer_list_8[] = { 6, 128, 129, 130, 131, 139, 140 }; +static u32 buffer_list_9[] = { 5, 124, 125, 126, 139, 140 }; +static u32 buffer_list_10[] = { 5, 124, 125, 126, 139, 140 }; +static u32 buffer_list_11[] = { 5, 124, 125, 126, 139, 140 }; +static u32 buffer_list_12[] = { 6, 132, 133, 134, 135, 139, 140 }; +static u32 buffer_list_13[] = { 6, 132, 133, 134, 135, 139, 140 }; +static u32 buffer_list_14[] = { 4, 137, 138, 139, 140 }; +static u32 buffer_list_15[] = { 6, 136, 136, 137, 138, 139, 140 }; + +/** Issue#7674 (new) - DP/DVP buffer assignment */ +static u32 buffer_list_16[] = { 6, 106, 108, 109, 107, 139, 140 }; +static u32 buffer_list_17[] = { 6, 106, 110, 107, 111, 139, 140 }; +static u32 buffer_list_18[] = { 6, 106, 113, 107, 114, 139, 140 }; +static u32 buffer_list_19[] = { 3, 112, 139, 140 }; +static u32 buffer_list_20[] = { 35, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 79, 80, 81, 82, 83, 84, 85, 86, 139, 140 }; +static u32 buffer_list_21[] = { 27, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 139, 140 }; +static u32 buffer_list_22[] = { 81, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 139, 140 }; +static u32 buffer_list_23[] = { 29, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 88, 89, 139, 140 }; +static u32 buffer_list_24[] = { 6, 90, 91, 92, 93, 139, 140 }; +static u32 buffer_list_25[] = { 18, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 139, 140 }; +static u32 buffer_list_26[] = { 5, 94, 95, 96, 139, 140 }; +static u32 buffer_list_27[] = { 5, 97, 98, 99, 139, 140 }; +static u32 buffer_list_28[] = { 5, 100, 101, 102, 139, 140 }; +static u32 buffer_list_29[] = { 5, 103, 104, 105, 139, 140 }; +static u32 buffer_list_30[] = { 10, 108, 109, 110, 111, 113, 114, 116, 117, + 139, 140 }; +static u32 buffer_list_31[] = { 13, 106, 107, 108, 109, 110, 111, 113, 114, + 115, 116, 117, 139, 140 }; +static u32 buffer_list_32[] = { 13, 106, 107, 108, 109, 110, 111, 113, 114, + 115, 116, 117, 139, 140 }; +static u32 buffer_list_33[] = { 27, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 139, 140 }; +static u32 buffer_list_34[] = { 27, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 139, 140 }; +static u32 buffer_list_35[] = { 28, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 87, 139, 140 }; +static u32 buffer_list_36[] = { 28, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 87, 139, 140 }; +static u32 buffer_list_37[] = { 27, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 139, 140 }; +static u32 buffer_list_38[] = { 29, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 118, 119, 139, 140 }; +static u32 buffer_list_39[] = { 91, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 118, 119, 139, 140 }; +static u32 buffer_list_40[] = { 0 }; + +/* + * List of statically defined vcid.csize values. + * The first entry in the table is the number of possible csize values + * followed by the list of data path values in bits. + */ +static u32 csize_list_0[] = { 2, 0, 1 }; +static u32 csize_list_1[] = { 2, 0, 1 }; +static u32 csize_list_2[] = { 1, 1 }; +static u32 csize_list_3[] = { 1, 1 }; +static u32 csize_list_4[] = { 1, 1 }; +static u32 csize_list_5[] = { 1, 0 }; +static u32 csize_list_6[] = { 1, 0 }; +static u32 csize_list_7[] = { 1, 1 }; +static u32 csize_list_8[] = { 1, 1 }; +static u32 csize_list_9[] = { 1, 1 }; +static u32 csize_list_10[] = { 1, 1 }; +static u32 csize_list_11[] = { 1, 1 }; +static u32 csize_list_12[] = { 1, 1 }; +static u32 csize_list_13[] = { 1, 1 }; +static u32 csize_list_14[] = { 1, 2 }; +static u32 csize_list_15[] = { 1, 4 }; +static u32 csize_list_16[] = { 3, 0, 1, 2 }; +static u32 csize_list_17[] = { 3, 0, 1, 2 }; +static u32 csize_list_18[] = { 3, 0, 1, 2 }; +static u32 csize_list_19[] = { 1, 2 }; +static u32 csize_list_20[] = { 1, 0 }; +static u32 csize_list_21[] = { 1, 0 }; +static u32 csize_list_22[] = { 1, 2 }; +static u32 csize_list_23[] = { 1, 3 }; +static u32 csize_list_24[] = { 1, 3 }; +static u32 csize_list_25[] = { 1, 3 }; +static u32 csize_list_26[] = { 1, 0 }; +static u32 csize_list_27[] = { 1, 0 }; +static u32 csize_list_28[] = { 1, 0 }; +static u32 csize_list_29[] = { 1, 0 }; +static u32 csize_list_30[] = { 1, 2 }; +static u32 csize_list_31[] = { 1, 2 }; +static u32 csize_list_32[] = { 1, 2 }; +static u32 csize_list_33[] = { 1, 2 }; +static u32 csize_list_34[] = { 1, 2 }; +static u32 csize_list_35[] = { 1, 2 }; +static u32 csize_list_36[] = { 1, 2 }; +static u32 csize_list_37[] = { 2, 0, 1 }; +static u32 csize_list_38[] = { 1, 2 }; +static u32 csize_list_39[] = { 1, 3 }; +static u32 csize_list_40[] = { 1, 3 }; + +/* + * SCC_Configuration table + */ +static const struct scc_descriptor scc_descriptor_table[] = { +/* scn scc_name profile SCC scc_id mci_id rd wr m p fh si cfg sta */ + {"fe_", "fe_3dcomb_wr", STRM_P, SCC0_BASE, 0, 0, 0, 4, 1, 1, 0, 0, 0, 1, + buffer_list_0, csize_list_0}, + {"fe_", "fe_3dcomb_rd", STRM_P, SCC1_BASE, 1, 18, 4, 0, 1, 1, 0, 1, 0, + 1, buffer_list_1, csize_list_1}, + {"di_", "di_tnr_wr", STRM_P, SCC2_BASE, 2, 1, 0, 3, 1, 1, 0, 2, 0, 1, + buffer_list_2, csize_list_2}, + {"di_", "di_tnr_field_rd", STRM_P, SCC3_BASE, 3, 19, 3, 0, 1, 1, 0, 3, + 0, 1, buffer_list_3, csize_list_3}, + {"di_", "di_tnr_frame_rd", STRM_P, SCC4_BASE, 4, 20, 3, 0, 1, 1, 0, 4, + 0, 1, buffer_list_4, csize_list_4}, + {"di_", "di_mval_wr", STRM_P, SCC5_BASE, 5, 2, 0, 1, 1, 1, 0, 5, 0, 1, + buffer_list_5, csize_list_5}, + {"di_", "di_mval_rd", STRM_P, SCC6_BASE, 6, 21, 1, 0, 1, 1, 0, 6, 0, 1, + buffer_list_6, csize_list_6}, + {"rc_", "rc_frame_wr", STRM_P, SCC7_BASE, 7, 3, 0, 4, 1, 1, 0, 7, 0, 1, + buffer_list_7, csize_list_7}, + {"rc_", "rc_frame0_rd", STRM_P, SCC8_BASE, 8, 22, 4, 0, 1, 1, 0, 8, 0, + 1, buffer_list_8, csize_list_8}, + {"opt", "opt_field0_rd", STRM_P, SCC9_BASE, 9, 23, 3, 0, 1, 1, 0, 9, 0, + 1, buffer_list_9, csize_list_9}, + {"opt", "opt_field1_rd", STRM_P, SCC10_BASE, 10, 24, 3, 0, 1, 1, 0, 10, + 0, 1, buffer_list_10, csize_list_10}, + {"opt", "opt_field2_rd", STRM_P, SCC11_BASE, 11, 25, 3, 0, 1, 1, 0, 11, + 0, 1, buffer_list_11, csize_list_11}, + {"pip", "pip_frame_wr", STRM_P, SCC12_BASE, 12, 4, 0, 4, 1, 1, 0, 12, 0, + 1, buffer_list_12, csize_list_12}, + {"pip", "pip_frame_rd", STRM_P, SCC13_BASE, 13, 26, 4, 0, 1, 1, 0, 13, + 0, 1, buffer_list_13, csize_list_13}, + {"dp_", "dp_agpu_rd", STRM_P, SCC14_BASE, 14, 27, 2, 0, 2, 1, 0, 14, 0, + 1, buffer_list_14, csize_list_14}, + {"ewa", "ewarp_rw", SRMD, SCC15_BASE, 15, 11, 1, 1, 0, 0, 0, -1, 0, 0, + buffer_list_15, csize_list_15}, + {"dp_", "dp_osd_rd", STRM_P, SCC16_BASE, 16, 28, 3, 0, 2, 1, 0, 15, 0, + 1, buffer_list_16, csize_list_16}, + {"dp_", "dp_graphic_rd", STRM_P, SCC17_BASE, 17, 29, 3, 0, 2, 1, 0, 16, + 0, 1, buffer_list_17, csize_list_17}, + {"dvp", "dvp_osd_rd", STRM_P, SCC18_BASE, 18, 30, 2, 0, 2, 1, 0, 17, 0, + 1, buffer_list_18, csize_list_18}, + {"dvp", "dvp_vbi_rd", STRM_D, SCC19_BASE, 19, 31, 1, 0, 0, 1, 0, -1, 0, + 0, buffer_list_19, csize_list_19}, + {"tsi", "tsio_wr", STRM_P, SCC20_BASE, 20, 5, 0, 8, 2, 1, 1, -1, 0, 0, + buffer_list_20, csize_list_20}, + {"tsi", "tsio_rd", STRM_P, SCC21_BASE, 21, 32, 4, 0, 2, 1, 1, -1, 0, 0, + buffer_list_21, csize_list_21}, + {"tsd", "tsd_wr", SRMD, SCC22_BASE, 22, 6, 0, 64, 0, 0, 1, -1, 0, 0, + buffer_list_22, csize_list_22}, + {"vd_", "vd_ud_st_rw", SRMD, SCC23_BASE, 23, 12, 2, 2, 0, 0, 1, -1, 0, + 0, buffer_list_23, csize_list_23}, + {"vd_", "vd_frr_rd", SRMD, SCC24_BASE, 24, 33, 4, 0, 0, 0, 0, -1, 0, 0, + buffer_list_24, csize_list_24}, + {"vd_", "vd_frw_disp_wr", SRMD, SCC25_BASE, 25, 7, 0, 16, 0, 0, 0, -1, + 0, 0, buffer_list_25, csize_list_25}, + {"mr_", "mr_vd_m_y_rd", STRM_P, SCC26_BASE, 26, 34, 3, 0, 2, 1, 0, 18, + 0, 1, buffer_list_26, csize_list_26}, + {"mr_", "mr_vd_m_c_rd", STRM_P, SCC27_BASE, 27, 35, 3, 0, 2, 1, 0, 19, + 0, 1, buffer_list_27, csize_list_27}, + {"mr_", "mr_vd_s_y_rd", STRM_P, SCC28_BASE, 28, 36, 3, 0, 2, 1, 0, 20, + 0, 1, buffer_list_28, csize_list_28}, + {"mr_", "mr_vd_s_c_rd", STRM_P, SCC29_BASE, 29, 37, 3, 0, 2, 1, 0, 21, + 0, 1, buffer_list_29, csize_list_29}, + {"ga_", "ga_wr", STRM_P, SCC30_BASE, 30, 8, 0, 1, 1, 1, 0, -1, 1, 1, + buffer_list_30, csize_list_30}, + {"ga_", "ga_src1_rd", STRM_P, SCC31_BASE, 31, 38, 1, 0, 1, 1, 0, -1, 1, + 1, buffer_list_31, csize_list_31}, + {"ga_", "ga_src2_rd", STRM_P, SCC32_BASE, 32, 39, 1, 0, 1, 1, 0, -1, 1, + 1, buffer_list_32, csize_list_32}, + {"ad_", "ad_rd", STRM_D, SCC33_BASE, 33, 40, 2, 0, 0, 1, 1, -1, 0, 0, + buffer_list_33, csize_list_33}, + {"ad_", "ad_wr", STRM_D, SCC34_BASE, 34, 9, 0, 3, 0, 1, 1, -1, 0, 0, + buffer_list_34, csize_list_34}, + {"abp", "abp_rd", STRM_D, SCC35_BASE, 35, 41, 5, 0, 0, 1, 1, -1, 0, 0, + buffer_list_35, csize_list_35}, + {"abp", "abp_wr", STRM_D, SCC36_BASE, 36, 10, 0, 3, 0, 1, 1, -1, 0, 0, + buffer_list_36, csize_list_36}, + {"ebi", "ebi_rw", STRM_P, SCC37_BASE, 37, 13, 4, 4, 2, 1, 1, -1, 0, 0, + buffer_list_37, csize_list_37}, + {"usb", "usb_rw", SRMD, SCC38_BASE, 38, 14, 1, 1, 0, 0, 1, -1, 0, 0, + buffer_list_38, csize_list_38}, + {"cpu", "cpu1_spdma_rw", SRMD, SCC39_BASE, 39, 15, 1, 1, 0, 0, 1, -1, 0, + 0, buffer_list_39, csize_list_39}, + {"cpu", "cpu1_bridge_rw", SRMD, SCC40_BASE, 40, 16, 0, 0, 0, 0, 0, -1, + 0, 0, buffer_list_40, csize_list_40}, +}; + +/* DMA state structures for read and write channels for each SCC */ + +static struct scc_dma_state scc_state_rd_0[] = { {-1} }; +static struct scc_dma_state scc_state_wr_0[] = { {0}, {0}, {0}, {0} }; +static struct scc_dma_state scc_state_rd_1[] = { {0}, {0}, {0}, {0} }; +static struct scc_dma_state scc_state_wr_1[] = { {-1} }; +static struct scc_dma_state scc_state_rd_2[] = { {-1} }; +static struct scc_dma_state scc_state_wr_2[] = { {0}, {0}, {0} }; +static struct scc_dma_state scc_state_rd_3[] = { {0}, {0}, {0} }; +static struct scc_dma_state scc_state_wr_3[] = { {-1} }; +static struct scc_dma_state scc_state_rd_4[] = { {0}, {0}, {0} }; +static struct scc_dma_state scc_state_wr_4[] = { {-1} }; +static struct scc_dma_state scc_state_rd_5[] = { {-1} }; +static struct scc_dma_state scc_state_wr_5[] = { {0} }; +static struct scc_dma_state scc_state_rd_6[] = { {0} }; +static struct scc_dma_state scc_state_wr_6[] = { {-1} }; +static struct scc_dma_state scc_state_rd_7[] = { {-1} }; +static struct scc_dma_state scc_state_wr_7[] = { {0}, {0}, {0}, {0} }; +static struct scc_dma_state scc_state_rd_8[] = { {0}, {0}, {0}, {0} }; +static struct scc_dma_state scc_state_wr_8[] = { {-1} }; +static struct scc_dma_state scc_state_rd_9[] = { {0}, {0}, {0}, }; +static struct scc_dma_state scc_state_wr_9[] = { {-1} }; +static struct scc_dma_state scc_state_rd_10[] = { {0}, {0}, {0} }; +static struct scc_dma_state scc_state_wr_10[] = { {-1} }; +static struct scc_dma_state scc_state_rd_11[] = { {0}, {0}, {0} }; +static struct scc_dma_state scc_state_wr_11[] = { {-1} }; +static struct scc_dma_state scc_state_rd_12[] = { {-1} }; +static struct scc_dma_state scc_state_wr_12[] = { {0}, {0}, {0}, {0} }; +static struct scc_dma_state scc_state_rd_13[] = { {0}, {0}, {0}, {0} }; +static struct scc_dma_state scc_state_wr_13[] = { {-1} }; +static struct scc_dma_state scc_state_rd_14[] = { {0}, {0} }; +static struct scc_dma_state scc_state_wr_14[] = { {-1} }; +static struct scc_dma_state scc_state_rd_15[] = { {0} }; +static struct scc_dma_state scc_state_wr_15[] = { {0} }; +static struct scc_dma_state scc_state_rd_16[] = { {0}, {0}, {0} }; +static struct scc_dma_state scc_state_wr_16[] = { {-1} }; +static struct scc_dma_state scc_state_rd_17[] = { {0}, {0}, {0} }; +static struct scc_dma_state scc_state_wr_17[] = { {-1} }; +static struct scc_dma_state scc_state_rd_18[] = { {0}, {0} }; +static struct scc_dma_state scc_state_wr_18[] = { {-1} }; +static struct scc_dma_state scc_state_rd_19[] = { {0} }; +static struct scc_dma_state scc_state_wr_19[] = { {-1} }; +static struct scc_dma_state scc_state_rd_20[] = { {-1} }; +static struct scc_dma_state scc_state_wr_20[] = { + {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0} }; +static struct scc_dma_state scc_state_rd_21[] = { {0}, {0}, {0}, {0} }; +static struct scc_dma_state scc_state_wr_21[] = { {-1} }; +static struct scc_dma_state scc_state_rd_22[] = { {-1} }; +static struct scc_dma_state scc_state_wr_22[] = { + {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, + {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, + {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, + {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, + {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0} }; +static struct scc_dma_state scc_state_rd_23[] = { {0}, {0} }; +static struct scc_dma_state scc_state_wr_23[] = { {0}, {0} }; +static struct scc_dma_state scc_state_rd_24[] = { {0}, {0}, {0}, {0} }; +static struct scc_dma_state scc_state_wr_24[] = { {-1} }; +static struct scc_dma_state scc_state_rd_25[] = { {-1} }; +static struct scc_dma_state scc_state_wr_25[] = { + {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, + {0}, {0} }; +static struct scc_dma_state scc_state_rd_26[] = { {0}, {0}, {0} }; +static struct scc_dma_state scc_state_wr_26[] = { {-1} }; +static struct scc_dma_state scc_state_rd_27[] = { {0}, {0}, {0} }; +static struct scc_dma_state scc_state_wr_27[] = { {-1} }; +static struct scc_dma_state scc_state_rd_28[] = { {0}, {0}, {0} }; +static struct scc_dma_state scc_state_wr_28[] = { {-1} }; +static struct scc_dma_state scc_state_rd_29[] = { {0}, {0}, {0} }; +static struct scc_dma_state scc_state_wr_29[] = { {-1} }; +static struct scc_dma_state scc_state_rd_30[] = { {-1} }; +static struct scc_dma_state scc_state_wr_30[] = { {0} }; +static struct scc_dma_state scc_state_rd_31[] = { {0} }; +static struct scc_dma_state scc_state_wr_31[] = { {-1} }; +static struct scc_dma_state scc_state_rd_32[] = { {0} }; +static struct scc_dma_state scc_state_wr_32[] = { {-1} }; +static struct scc_dma_state scc_state_rd_33[] = { {0}, {0} }; +static struct scc_dma_state scc_state_wr_33[] = { {-1} }; +static struct scc_dma_state scc_state_rd_34[] = { {-1} }; +static struct scc_dma_state scc_state_wr_34[] = { {0}, {0}, {0} }; +static struct scc_dma_state scc_state_rd_35[] = { {0}, {0}, {0}, {0}, {0} }; +static struct scc_dma_state scc_state_wr_35[] = { {-1} }; +static struct scc_dma_state scc_state_rd_36[] = { {-1} }; +static struct scc_dma_state scc_state_wr_36[] = { {0}, {0}, {0} }; +static struct scc_dma_state scc_state_rd_37[] = { {0}, {0}, {0}, {0} }; +static struct scc_dma_state scc_state_wr_37[] = { {0}, {0}, {0}, {0} }; +static struct scc_dma_state scc_state_rd_38[] = { {0} }; +static struct scc_dma_state scc_state_wr_38[] = { {0} }; +static struct scc_dma_state scc_state_rd_39[] = { {0} }; +static struct scc_dma_state scc_state_wr_39[] = { {0} }; +static struct scc_dma_state scc_state_rd_40[] = { {-1} }; +static struct scc_dma_state scc_state_wr_40[] = { {-1} }; + +/* DMA state references to access from the driver */ +static struct scc_dma_state *scc_state_rd[] = { + scc_state_rd_0, + scc_state_rd_1, + scc_state_rd_2, + scc_state_rd_3, + scc_state_rd_4, + scc_state_rd_5, + scc_state_rd_6, + scc_state_rd_7, + scc_state_rd_8, + scc_state_rd_9, + scc_state_rd_10, + scc_state_rd_11, + scc_state_rd_12, + scc_state_rd_13, + scc_state_rd_14, + scc_state_rd_15, + scc_state_rd_16, + scc_state_rd_17, + scc_state_rd_18, + scc_state_rd_19, + scc_state_rd_20, + scc_state_rd_21, + scc_state_rd_22, + scc_state_rd_23, + scc_state_rd_24, + scc_state_rd_25, + scc_state_rd_26, + scc_state_rd_27, + scc_state_rd_28, + scc_state_rd_29, + scc_state_rd_30, + scc_state_rd_31, + scc_state_rd_32, + scc_state_rd_33, + scc_state_rd_34, + scc_state_rd_35, + scc_state_rd_36, + scc_state_rd_37, + scc_state_rd_38, + scc_state_rd_39, + scc_state_rd_40, +}; + +static struct scc_dma_state *scc_state_wr[] = { + scc_state_wr_0, + scc_state_wr_1, + scc_state_wr_2, + scc_state_wr_3, + scc_state_wr_4, + scc_state_wr_5, + scc_state_wr_6, + scc_state_wr_7, + scc_state_wr_8, + scc_state_wr_9, + scc_state_wr_10, + scc_state_wr_11, + scc_state_wr_12, + scc_state_wr_13, + scc_state_wr_14, + scc_state_wr_15, + scc_state_wr_16, + scc_state_wr_17, + scc_state_wr_18, + scc_state_wr_19, + scc_state_wr_20, + scc_state_wr_21, + scc_state_wr_22, + scc_state_wr_23, + scc_state_wr_24, + scc_state_wr_25, + scc_state_wr_26, + scc_state_wr_27, + scc_state_wr_28, + scc_state_wr_29, + scc_state_wr_30, + scc_state_wr_31, + scc_state_wr_32, + scc_state_wr_33, + scc_state_wr_34, + scc_state_wr_35, + scc_state_wr_36, + scc_state_wr_37, + scc_state_wr_38, + scc_state_wr_39, + scc_state_wr_40, +}; + +static u32 scc_takeover_mode = SCC_TO_IMMEDIATE; + +/* Change mode of the SPDMA for given direction */ +static u32 scc_agu_mode_sp = AGU_BYPASS; + +/* Change mode of the USB for given direction */ +static u32 scc_agu_mode_usb = AGU_BYPASS; + +static union scc_softwareconfiguration scc_software_configuration[SCC_MAX]; + +static u32 dma_fsm[4][4] = { + /* DMA_CMD_RESET DMA_CMD_SETUP DMA_CMD_START DMA_CMD_STOP */ + /* DMA_STATE_RESET */ + {DMA_STATE_RESET, DMA_STATE_SETUP, DMA_STATE_ERROR, DMA_STATE_ERROR}, + /* DMA_STATE_SETUP */ + {DMA_STATE_RESET, DMA_STATE_SETUP, DMA_STATE_START, DMA_STATE_SETUP}, + /* DMA_STATE_START */ + {DMA_STATE_RESET, DMA_STATE_ERROR, DMA_STATE_START, DMA_STATE_SETUP}, + /* DMA_STATE_ERROR */ + {DMA_STATE_RESET, DMA_STATE_ERROR, DMA_STATE_ERROR, DMA_STATE_ERROR}, +}; + +static void dma_state_process(struct scc_dma_state *dma_state, u32 cmd) +{ + dma_state->dma_status = dma_fsm[dma_state->dma_status][cmd]; + dma_state->dma_cmd = cmd; +} + +static void dma_state_process_dma_command(struct scc_dma_state *dma_state, + u32 dma_cmd) +{ + dma_state->dma_cmd = dma_cmd; + switch (dma_cmd) { + case DMA_START: + case DMA_START_FH_RESET: + dma_state_process(dma_state, DMA_CMD_START); + break; + case DMA_STOP: + dma_state_process(dma_state, DMA_CMD_STOP); + break; + default: + break; + } +} + +static void scc_takeover_dma(enum scc_id id, u32 dma_id, u32 drs) +{ + union scc_cmd dma_cmd; + + dma_cmd.reg = 0; + + /* Prepare the takeover for the DMA channel */ + dma_cmd.bits.action = DMA_TAKEOVER; + dma_cmd.bits.id = dma_id; + dma_cmd.bits.rid = TO_DMA_CFG; /* this is DMA_CFG register takeover */ + if (drs == DMA_WRITE) + dma_cmd.bits.drs = DMA_WRITE; + + reg_write(SCC_CMD(scc_descriptor_table[id].base_address), dma_cmd.reg); +} + +int scc_dma_cmd(enum scc_id id, u32 cmd, u32 dma_id, u32 drs) +{ + union scc_cmd dma_cmd; + struct scc_dma_state *dma_state; + + if ((id >= SCC_MAX) || (id < 0)) + return -EINVAL; + + dma_cmd.reg = 0; + + /* Prepare the takeover for the DMA channel */ + dma_cmd.bits.action = cmd; + dma_cmd.bits.id = dma_id; + if (drs == DMA_WRITE) { + dma_cmd.bits.drs = DMA_WRITE; + dma_state = &scc_state_wr[id][dma_id]; + } else { + dma_state = &scc_state_rd[id][dma_id]; + } + + dma_state->scc_id = id; + dma_state->dma_id = dma_id; + dma_state_process_dma_command(dma_state, cmd); + + reg_write(SCC_CMD(scc_descriptor_table[id].base_address), dma_cmd.reg); + + return 0; +} + +int scc_set_usb_address_generation_mode(u32 agu_mode) +{ + if (AGU_ACTIVE == agu_mode) { + /* Ensure both DMAs are stopped */ + scc_dma_cmd(SCC_USB_RW, DMA_STOP, 0, DMA_WRITE); + scc_dma_cmd(SCC_USB_RW, DMA_STOP, 0, DMA_READ); + } else { + agu_mode = AGU_BYPASS; + } + + scc_agu_mode_usb = agu_mode; + + return 0; +} + +int scc_setup_dma(enum scc_id id, u32 buffer_tag, + u32 type, u32 fh_mode, u32 drs, u32 dma_id) +{ + struct scc_dma_state *dma_state; + int return_value = 0; + union scc_dma_cfg dma_cfg; + u32 *buffer_tag_list = scc_descriptor_table[id].buffer_tag_list; + u32 tag_count, t, t_valid; + + if ((id >= SCC_MAX) || (id < 0)) + return -EINVAL; + + /* if the register is only configured by hw, cannot write! */ + if (1 == scc_descriptor_table[id].hw_dma_cfg) + return -EACCES; + + if (DMA_WRITE == drs) { + if (dma_id >= scc_descriptor_table[id].p_dma_channels_wr) + return -EINVAL; + dma_state = &scc_state_wr[id][dma_id]; + } else { + if (dma_id >= scc_descriptor_table[id].p_dma_channels_rd) + return -EINVAL; + dma_state = &scc_state_rd[id][dma_id]; + } + + /* Compose the DMA configuration register */ + tag_count = buffer_tag_list[0]; + t_valid = 0; + for (t = 1; t <= tag_count; t++) { + if (buffer_tag == buffer_tag_list[t]) { + /* Tag found - validate */ + t_valid = 1; + break; + } + } + + if (!t_valid) + return -EACCES; + + /* + * Read the register first -- two functions write into the register + * it does not make sense to read the DMA config back, because there + * are two register configuration sets (drs) + */ + dma_cfg.reg = 0; + dma_cfg.bits.buffer_id = buffer_tag; + dma_state_process(dma_state, DMA_CMD_SETUP); + + /* + * This is Packet CFG set select - usable for TSIO, EBI and those SCCs + * which habe 2 packet configs + */ + dma_cfg.bits.packet_cfg_id = + scc_software_configuration[id].bits.packet_select; + + if (type == DMA_CYCLIC) + dma_cfg.bits.buffer_type = 1; + else + dma_cfg.bits.buffer_type = 0; + + if (fh_mode == USE_FH) + dma_cfg.bits.fh_mode = 1; + else + dma_cfg.bits.fh_mode = 0; + + if (id == SCC_CPU1_SPDMA_RW) + dma_cfg.bits.agu_mode = scc_agu_mode_sp; + + if (id == SCC_USB_RW) + dma_cfg.bits.agu_mode = scc_agu_mode_usb; + + reg_write(SCC_DMA_CFG(scc_descriptor_table[id].base_address), + dma_cfg.reg); + + /* The DMA_CFG needs a takeover! */ + if (SCC_TO_IMMEDIATE == scc_takeover_mode) + scc_takeover_dma(id, dma_id, drs); + + /* if (buffer_tag is not used) */ + dma_state->buffer_tag = buffer_tag; + + dma_state->scc_id = id; + dma_state->dma_id = dma_id; + + return return_value; +} + +int scc_enable(enum scc_id id, u32 value) +{ + if ((id >= SCC_MAX) || (id < 0)) + return -EINVAL; + + if (value == 0) { + scc_software_configuration[id].bits.enable_status = 0; + } else { + value = 1; + scc_software_configuration[id].bits.enable_status = 1; + } + reg_write(SCC_ENABLE(scc_descriptor_table[id].base_address), value); + + return 0; +} + +static inline void ehb(void) +{ + __asm__ __volatile__( + " .set mips32r2 \n" + " ehb \n" + " .set mips0 \n"); +} + +int scc_reset(enum scc_id id, u32 value) +{ + if ((id >= SCC_MAX) || (id < 0)) + return -EINVAL; + + /* Invert value to the strait logic from the negative hardware logic */ + if (value == 0) + value = 1; + else + value = 0; + + /* Write the value to the register */ + reg_write(SCC_RESET(scc_descriptor_table[id].base_address), value); + + /* sync flush */ + asm("sync"); /* request bus write queue flush */ + ehb(); /* wait until previous bus commit instr has finished */ + asm("nop"); /* wait for flush to occur */ + asm("nop"); /* wait for flush to occur */ + + udelay(100); + + return 0; +} diff --git a/board/micronas/vct/scc.h b/board/micronas/vct/scc.h new file mode 100644 index 000000000..8415167c9 --- /dev/null +++ b/board/micronas/vct/scc.h @@ -0,0 +1,205 @@ +/* + * (C) Copyright 2009 Stefan Roese , DENX Software Engineering + * + * Copyright (C) 2006 Micronas GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _SCC_H +#define _SCC_H + +#define DMA_READ 0 /* SCC read DMA */ +#define DMA_WRITE 1 /* SCC write DMA */ + +#define DMA_LINEAR 0 /* DMA linear buffer access method */ +#define DMA_CYCLIC 1 /* DMA cyclic buffer access method */ + +#define DMA_START 0 /* DMA command - start DMA */ +#define DMA_STOP 1 /* DMA command - stop DMA */ +#define DMA_START_FH_RESET 2 /* DMA command - start DMA reset FH */ +#define DMA_TAKEOVER 15 /* DMA command - commit the DMA conf */ + +#define AGU_ACTIVE 0 /* enable AGU address calculation */ +#define AGU_BYPASS 1 /* set AGU to bypass mode */ + +#define USE_NO_FH 0 /* order the DMA to not use FH */ +#define USE_FH 1 /* order the DMA to work with FH*/ + +#define SCC_DBG_IDLE 0 /* DEBUG status (idle interfaces) */ +#define SCC_DBG_SYNC_RES 0x0001 /* synchronuous reset */ + +#define SCC_TO_IMMEDIATE 1 /* takeover command issued immediately*/ +#define TO_DMA_CFG 2 /* takeover command for the DMA config*/ + +#define DMA_CMD_RESET 0 +#define DMA_CMD_SETUP 1 +#define DMA_CMD_START 2 +#define DMA_CMD_STOP 3 + +#define DMA_STATE_RESET 0 +#define DMA_STATE_SETUP 1 +#define DMA_STATE_START 2 +#define DMA_STATE_ERROR 3 + +#define SRMD 0 +#define STRM_D 1 +#define STRM_P 2 + +/* + * Slowest Monterey domain is DVP 27 MHz (324/27 = 12; 12*16 = 192 CPU clocks) + */ +#define RESET_TIME 2 /* cycle calc see in SCC_Reset */ + +struct scc_descriptor { + char *pu_name; /* PU identifier */ + char *scc_instance; /* SCC Name */ + u32 profile; /* SCC VCI_D profile */ + + u32 base_address; /* base address of the SCC unit reg shell*/ + + /* SCS Interconnect configuration */ + u32 p_scc_id; /* instance number of SCC unit */ + u32 p_mci_id; /* memory channel ID */ + + /* DMA Registers configuration */ + u32 p_dma_channels_rd; /* Number of Read DMA channels */ + u32 p_dma_channels_wr; /* Number of Write DMA channels */ + + u32 p_dma_packet_desc; /* Number of packet descriptors */ + u32 p_dma_mci_desc; /* Number of MCI_CFG Descriptors */ + + int use_fh; /* the flag tells if SCC uses an FH */ + + int p_si2ocp_id; /* instance number of SI2OCP unit */ + int hw_dma_cfg; /* HW or SW DMA config flag */ + int hw_dma_start; /* HW or SW DMA start/stop flag */ + + u32 *buffer_tag_list; /* list of the buffer tags available */ + u32 *csize_list; /* list of the valid CSIZE values */ +}; + +struct scc_dma_state { + u32 scc_id:8; /* SCC id */ + u32 dma_id:8; /* DMA id, used for match with array idx*/ + u32 buffer_tag:8; /* mem buf tag, assigned to this DMA */ + u32 dma_status:2; /* state of DMA, of the DMA_STATE_ const*/ + u32 dma_drs:2; /* DMA dir, either DMA_READ or DMA_WRITE*/ + u32 dma_cmd:4; /* last executed command on this DMA */ +}; + +union scc_cmd { + u32 reg; + struct { + u32 res1:19; /* reserved */ + u32 drs:1; /* DMA Register Set */ + u32 rid:2; /* Register Identifier */ + u32 id:6; /* DMA Identifier */ + u32 action:4; /* DMA Command encoding */ + } bits; +}; + +union scc_dma_cfg { + u32 reg; + struct { + u32 res1:17; /* reserved */ + u32 agu_mode:1; /* AGU Mode */ + u32 res2:1; /* reserved */ + u32 fh_mode:1; /* Fifo Handler */ + u32 buffer_type:1; /* Defines type of mem buffers */ + u32 mci_cfg_id:1; /* MCI_CFG register selector */ + u32 packet_cfg_id:1; /* PACKET_CFG register selector */ + u32 buffer_id:8; /* DMA Buffer Identifier */ + } bits; +}; + +union scc_debug { + u32 reg; + struct { + u32 res1:20; /* reserved */ + u32 arg:8; /* SCC Debug Command Argument (#) */ + u32 cmd:4; /* SCC Debug Command Register */ + } bits; +}; + +union scc_softwareconfiguration { + u32 reg; + struct { + u32 res1:28; /* reserved */ + u32 clock_status:1; /* clock on/off */ + u32 packet_select:1; /* active SCC packet id */ + u32 enable_status:1; /* enabled [1/0] */ + u32 active_status:1; /* 1=active 0=reset */ + } bits; +}; + +/* + * System on Chip Channel ID + */ +enum scc_id { + SCC_NULL = -1, /* illegal SCC identifier */ + SCC_FE_3DCOMB_WR, /* SCC_FE_3DCOMB Write channel */ + SCC_FE_3DCOMB_RD, /* SCC_FE_3DCOMB Read channel */ + SCC_DI_TNR_WR, /* SCC_DI_TNR Write channel */ + SCC_DI_TNR_FIELD_RD, /* SCC_DI_TNR_FIELD Read channel */ + SCC_DI_TNR_FRAME_RD, /* SCC_DI_TNR_FRAME Read channel */ + SCC_DI_MVAL_WR, /* SCC_DI_MVAL Write channel */ + SCC_DI_MVAL_RD, /* SCC_DI_MVAL Read channel */ + SCC_RC_FRAME_WR, /* SCC_RC_FRAME Write channel */ + SCC_RC_FRAME0_RD, /* SCC_RC_FRAME0 Read channel */ + SCC_OPT_FIELD0_RD, /* SCC_OPT_FIELD0 Read channel */ + SCC_OPT_FIELD1_RD, /* SCC_OPT_FIELD1 Read channel */ + SCC_OPT_FIELD2_RD, /* SCC_OPT_FIELD2 Read channel */ + SCC_PIP_FRAME_WR, /* SCC_PIP_FRAME Write channel */ + SCC_PIP_FRAME_RD, /* SCC_PIP_FRAME Read channel */ + SCC_DP_AGPU_RD, /* SCC_DP_AGPU Read channel */ + SCC_EWARP_RW, /* SCC_EWARP Read/Write channel */ + SCC_DP_OSD_RD, /* SCC_DP_OSD Read channel */ + SCC_DP_GRAPHIC_RD, /* SCC_DP_GRAPHIC Read channel */ + SCC_DVP_OSD_RD, /* SCC_DVP_OSD Read channel */ + SCC_DVP_VBI_RD, /* SCC_DVP_VBI Read channel */ + SCC_TSIO_WR, /* SCC_TSIO Write channel */ + SCC_TSIO_RD, /* SCC_TSIO Read channel */ + SCC_TSD_WR, /* SCC_TSD Write channel */ + SCC_VD_UD_ST_RW, /* SCC_VD_UD_ST Read/Write channel */ + SCC_VD_FRR_RD, /* SCC_VD_FRR Read channel */ + SCC_VD_FRW_DISP_WR, /* SCC_VD_FRW_DISP Write channel */ + SCC_MR_VD_M_Y_RD, /* SCC_MR_VD_M_Y Read channel */ + SCC_MR_VD_M_C_RD, /* SCC_MR_VD_M_C Read channel */ + SCC_MR_VD_S_Y_RD, /* SCC_MR_VD_S_Y Read channel */ + SCC_MR_VD_S_C_RD, /* SCC_MR_VD_S_C Read channel */ + SCC_GA_WR, /* SCC_GA Write channel */ + SCC_GA_SRC1_RD, /* SCC_GA_SRC1 Read channel */ + SCC_GA_SRC2_RD, /* SCC_GA_SRC2 Read channel */ + SCC_AD_RD, /* SCC_AD Read channel */ + SCC_AD_WR, /* SCC_AD Write channel */ + SCC_ABP_RD, /* SCC_ABP Read channel */ + SCC_ABP_WR, /* SCC_ABP Write channel */ + SCC_EBI_RW, /* SCC_EBI Read/Write channel */ + SCC_USB_RW, /* SCC_USB Read/Write channel */ + SCC_CPU1_SPDMA_RW, /* SCC_CPU1_SPDMA Read/Write channel */ + SCC_CPU1_BRIDGE_RW, /* SCC_CPU1_BRIDGE Read/Write channel */ + SCC_MAX /* maximum limit on the SCC id */ +}; + +int scc_set_usb_address_generation_mode(u32 agu_mode); +int scc_dma_cmd(enum scc_id id, u32 cmd, u32 dma_id, u32 drs); +int scc_setup_dma(enum scc_id id, u32 buffer_tag, + u32 type, u32 fh_mode, u32 drs, u32 dma_id); +int scc_enable(enum scc_id id, u32 value); +int scc_reset(enum scc_id id, u32 value); + +#endif /* _SCC_H */ diff --git a/board/micronas/vct/smc_eeprom.c b/board/micronas/vct/smc_eeprom.c new file mode 100644 index 000000000..2bc7ad4c4 --- /dev/null +++ b/board/micronas/vct/smc_eeprom.c @@ -0,0 +1,394 @@ +/* + * (C) Copyright 2008 Stefan Roese , DENX Software Engineering + * + * Copyright 2005, Seagate Technology LLC + * + * 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 version 2 as + * published by the Free Software Foundation. + * + * 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 + * + */ + +#undef DEBUG + +#include +#include +#include +#include + +#include "vct.h" + +#define SMSC9118_BASE CONFIG_DRIVER_SMC911X_BASE +#define BYTE_TEST (SMSC9118_BASE + 0x64) +#define GPIO_CFG (SMSC9118_BASE + 0x88) +#define MAC_CSR_CMD (SMSC9118_BASE + 0xA4) +#define MAC_CSR_CMD_CSR_BUSY (0x80000000) +#define MAC_CSR_CMD_RNW (0x40000000) +#define MAC_RD_CMD(reg) ((reg & 0x000000FF) | \ + (MAC_CSR_CMD_CSR_BUSY | MAC_CSR_CMD_RNW)) +#define MAC_WR_CMD(reg) ((reg & 0x000000FF) | \ + (MAC_CSR_CMD_CSR_BUSY)) +#define MAC_CSR_DATA (SMSC9118_BASE + 0xA8) +#define E2P_CMD (SMSC9118_BASE + 0xB0) +#define E2P_CMD_EPC_BUSY_ (0x80000000UL) /* Self Clearing */ +#define E2P_CMD_EPC_CMD_ (0x70000000UL) /* R/W */ +#define E2P_CMD_EPC_CMD_READ_ (0x00000000UL) /* R/W */ +#define E2P_CMD_EPC_CMD_EWDS_ (0x10000000UL) /* R/W */ +#define E2P_CMD_EPC_CMD_EWEN_ (0x20000000UL) /* R/W */ +#define E2P_CMD_EPC_CMD_WRITE_ (0x30000000UL) /* R/W */ +#define E2P_CMD_EPC_CMD_WRAL_ (0x40000000UL) /* R/W */ +#define E2P_CMD_EPC_CMD_ERASE_ (0x50000000UL) /* R/W */ +#define E2P_CMD_EPC_CMD_ERAL_ (0x60000000UL) /* R/W */ +#define E2P_CMD_EPC_CMD_RELOAD_ (0x70000000UL) /* R/W */ +#define E2P_CMD_EPC_TIMEOUT_ (0x00000200UL) /* R */ +#define E2P_CMD_MAC_ADDR_LOADED_ (0x00000100UL) /* RO */ +#define E2P_CMD_EPC_ADDR_ (0x000000FFUL) /* R/W */ +#define E2P_DATA (SMSC9118_BASE + 0xB4) + +#define MAC_ADDRH (0x2) +#define MAC_ADDRL (0x3) + +#define MAC_TIMEOUT 200 + +#define HIBYTE(word) ((u8)(((u16)(word)) >> 8)) +#define LOBYTE(word) ((u8)(((u16)(word)) & 0x00FFU)) +#define HIWORD(dword) ((u16)(((u32)(dword)) >> 16)) +#define LOWORD(dword) ((u16)(((u32)(dword)) & 0x0000FFFFUL)) + +static int mac_busy(int req_to) +{ + int timeout = req_to; + + while (timeout--) { + if (!(smc911x_reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)) + goto done; + } + return 1; /* Timeout */ + +done: + return 0; /* No timeout */ +} + +static ulong get_mac_reg(int reg) +{ + ulong reg_val = 0xffffffff; + + if (smc911x_reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) { + printf("get_mac_reg: previous command not complete\n"); + goto done; + } + + smc911x_reg_write(MAC_CSR_CMD, MAC_RD_CMD(reg)); + udelay(10000); + + if (mac_busy(MAC_TIMEOUT) == 1) { + printf("get_mac_reg: timeout waiting for response from MAC\n"); + goto done; + } + + reg_val = smc911x_reg_read(MAC_CSR_DATA); + +done: + return (reg_val); +} + +static ulong eeprom_enable_access(void) +{ + ulong gpio; + + gpio = smc911x_reg_read(GPIO_CFG); + debug("%s: gpio= 0x%08lx ---> 0x%08lx\n", __func__, gpio, + (gpio & 0xFF0FFFFFUL)); + + smc911x_reg_write(GPIO_CFG, (gpio & 0xFF0FFFFFUL)); + return gpio; +} + +static void eeprom_disable_access(ulong gpio) +{ + debug("%s: gpio= 0x%08lx\n", __func__, gpio); + smc911x_reg_write(GPIO_CFG, gpio); +} + +static int eeprom_is_mac_address_loaded(void) +{ + int ret; + + ret = smc911x_reg_read(MAC_CSR_CMD) & E2P_CMD_MAC_ADDR_LOADED_; + debug("%s: ret = %x\n", __func__, ret); + + return ret; +} + +static int eeprom_read_location(unchar address, u8 *data) +{ + ulong timeout = 100000; + ulong temp = 0; + + if ((temp = smc911x_reg_read(E2P_CMD)) & E2P_CMD_EPC_BUSY_) { + printf("%s: Busy at start, E2P_CMD=0x%08lX\n", __func__, temp); + return 0; + } + + smc911x_reg_write(E2P_CMD, + (E2P_CMD_EPC_BUSY_ | E2P_CMD_EPC_CMD_READ_ | + ((ulong) address))); + + while ((timeout > 0) && (smc911x_reg_read(E2P_CMD) & E2P_CMD_EPC_BUSY_)) { + udelay(10); + timeout--; + } + + if (timeout == 0) { + printf("Timeout\n"); + return 0; + } + (*data) = (unchar) (smc911x_reg_read(E2P_DATA)); + debug("%s: ret = %x\n", __func__, (*data)); + + return 1; +} + +static int eeprom_enable_erase_and_write(void) +{ + ulong timeout = 100000; + + if (smc911x_reg_read(E2P_CMD) & E2P_CMD_EPC_BUSY_) { + printf("%s: Busy at start\n", __func__); + return 0; + } + smc911x_reg_write(E2P_CMD, (E2P_CMD_EPC_BUSY_ | E2P_CMD_EPC_CMD_EWEN_)); + + while ((timeout > 0) && (smc911x_reg_read(E2P_CMD) & E2P_CMD_EPC_BUSY_)) { + udelay(10); + timeout--; + } + + if (timeout == 0) { + printf("Timeout[1]\n"); + return 0; + } + + return 1; +} + +static int eeprom_disable_erase_and_write(void) +{ + ulong timeout = 100000; + + if (smc911x_reg_read(E2P_CMD) & E2P_CMD_EPC_BUSY_) { + printf("%s: Busy at start\n", __func__); + return 0; + } + smc911x_reg_write(E2P_CMD, (E2P_CMD_EPC_BUSY_ | E2P_CMD_EPC_CMD_EWDS_)); + + while ((timeout > 0) && (smc911x_reg_read(E2P_CMD) & E2P_CMD_EPC_BUSY_)) { + udelay(10); + timeout--; + } + + if (timeout == 0) { + printf("Timeout[2]\n"); + return 0; + } + + return 1; +} + +static int eeprom_write_location(unchar address, unchar data) +{ + ulong timeout = 100000; + + debug("%s: address: %x data = %x\n", __func__, address, data); + + if (smc911x_reg_read(E2P_CMD) & E2P_CMD_EPC_BUSY_) { + printf("%s: Busy at start\n", __func__); + return 0; + } + + smc911x_reg_write(E2P_DATA, ((ulong) data)); + smc911x_reg_write(E2P_CMD, + (E2P_CMD_EPC_BUSY_ | E2P_CMD_EPC_CMD_WRITE_ | + ((ulong) address))); + + while ((timeout > 0) && (smc911x_reg_read(E2P_CMD) & E2P_CMD_EPC_BUSY_)) { + udelay(10); + timeout--; + } + + if (timeout == 0) { + printf("Timeout[3]\n"); + return 0; + } + + return 1; +} + +static int eeprom_erase_all(void) +{ + ulong timeout = 100000; + + if (smc911x_reg_read(E2P_CMD) & E2P_CMD_EPC_BUSY_) { + printf("%s: Busy at start\n", __func__); + return 0; + } + + smc911x_reg_write(E2P_CMD, (E2P_CMD_EPC_BUSY_ | E2P_CMD_EPC_CMD_ERAL_)); + + while ((timeout > 0) && (smc911x_reg_read(E2P_CMD) & E2P_CMD_EPC_BUSY_)) { + udelay(10); + timeout--; + } + + if (timeout == 0) { + printf("Timeout[4]\n"); + return 0; + } + + return 1; +} + +static int eeprom_reload(void) +{ + ulong timeout = 100000; + + if (smc911x_reg_read(E2P_CMD) & E2P_CMD_EPC_BUSY_) { + printf("%s: Busy at start\n", __func__); + return -1; + } + smc911x_reg_write(E2P_CMD, + (E2P_CMD_EPC_BUSY_ | E2P_CMD_EPC_CMD_RELOAD_)); + + while ((timeout > 0) && (smc911x_reg_read(E2P_CMD) & E2P_CMD_EPC_BUSY_)) { + udelay(10); + timeout--; + } + + if (timeout == 0) + return 0; + + return 1; +} + +static int eeprom_save_mac_address(ulong dwHi16, ulong dwLo32) +{ + int result = 0; + + debug("%s: dwHI: 0x%08lx dwLO: %08lx, \n", __func__, dwHi16, dwLo32); + + if (!eeprom_enable_erase_and_write()) + goto DONE; + if (!eeprom_erase_all()) + goto DONE; + if (!eeprom_write_location(0, 0xA5)) + goto DONE; + if (!eeprom_write_location(1, LOBYTE(LOWORD(dwLo32)))) + goto DONE; + if (!eeprom_write_location(2, HIBYTE(LOWORD(dwLo32)))) + goto DONE; + if (!eeprom_write_location(3, LOBYTE(HIWORD(dwLo32)))) + goto DONE; + if (!eeprom_write_location(4, HIBYTE(HIWORD(dwLo32)))) + goto DONE; + if (!eeprom_write_location(5, LOBYTE(LOWORD(dwHi16)))) + goto DONE; + if (!eeprom_write_location(6, HIBYTE(LOWORD(dwHi16)))) + goto DONE; + if (!eeprom_disable_erase_and_write()) + goto DONE; + + result = 1; + +DONE: + return result; +} + +static int do_eeprom_dump(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + unchar data = 0, index = 0; + ulong gpio_old_val; + + gpio_old_val = eeprom_enable_access(); + + printf("EEPROM content: \n"); + for (index = 0; index < 8; index++) { + if (eeprom_read_location(index, &data)) + printf("%02x ", data); + else + printf("FAILED"); + } + + eeprom_disable_access(gpio_old_val); + printf("\n"); + + return 0; +} + +static int do_eeprom_erase_all(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + eeprom_erase_all(); + + return 0; +} + +static int do_eeprom_save_mac(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + ulong hi16, lo32; + unchar ethaddr[6], i; + ulong gpio; + char *tmp, *end; + + tmp = argv[1]; + for (i = 0; i < 6; i++) { + ethaddr[i] = tmp ? simple_strtoul(tmp, &end, 16) : 0; + if (tmp) + tmp = (*end) ? end + 1 : end; + } + + hi16 = (ethaddr[5] << 8) | (ethaddr[4]); + lo32 = (ethaddr[3] << 24) | (ethaddr[2] << 16) | + (ethaddr[1] << 8) | (ethaddr[0]); + + gpio = eeprom_enable_access(); + + eeprom_save_mac_address(hi16, lo32); + + eeprom_reload(); + + /* Check new values */ + if (eeprom_is_mac_address_loaded()) { + ulong mac_hi16, mac_lo32; + + mac_hi16 = get_mac_reg(MAC_ADDRH); + mac_lo32 = get_mac_reg(MAC_ADDRL); + printf("New MAC address: %lx, %lx\n", mac_hi16, mac_lo32); + } else { + printf("Address is not reloaded \n"); + } + eeprom_disable_access(gpio); + + return 0; +} + +U_BOOT_CMD(smcee, 1, 0, do_eeprom_erase_all, + "smcee - Erase content of SMC EEPROM\n",); + +U_BOOT_CMD(smced, 1, 0, do_eeprom_dump, + "smced - Dump content of SMC EEPROM\n",); + +U_BOOT_CMD(smcew, 2, 0, do_eeprom_save_mac, + "smcew - Write MAC address to SMC EEPROM\n", + "aa:bb:cc:dd:ee:ff new mac address\n"); diff --git a/board/micronas/vct/top.c b/board/micronas/vct/top.c new file mode 100644 index 000000000..092395484 --- /dev/null +++ b/board/micronas/vct/top.c @@ -0,0 +1,289 @@ +/* + * (C) Copyright 2008 Stefan Roese , DENX Software Engineering + * + * Copyright (C) 2006 Micronas GmbH + * + * 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 +#include "vct.h" + +typedef union _TOP_PINMUX_t +{ + u32 reg; + struct { + u32 res : 24; /* reserved */ + u32 drive : 2; /* Driver strength */ + u32 slew : 1; /* Slew rate */ + u32 strig : 1; /* Schmitt trigger input*/ + u32 pu_pd : 2; /* Pull up/ pull down */ + u32 funsel : 2; /* Pin function */ + } Bits; +} TOP_PINMUX_t; + +#if defined(CONFIG_VCT_PREMIUM) || defined(CONFIG_VCT_PLATINUM) + +static TOP_PINMUX_t top_read_pin(int pin) +{ + TOP_PINMUX_t reg; + + switch (pin) { + case 2: + case 3: + case 6: + case 9: + reg.reg = 0xdeadbeef; + break; + case 4: + reg.reg = reg_read(FWSRAM_TOP_SCL_CFG(FWSRAM_BASE)); + break; + case 5: + reg.reg = reg_read(FWSRAM_TOP_SDA_CFG(FWSRAM_BASE)); + break; + case 7: + reg.reg = reg_read(FWSRAM_TOP_TDO_CFG(FWSRAM_BASE)); + break; + case 8: + reg.reg = reg_read(FWSRAM_TOP_GPIO2_0_CFG(FWSRAM_BASE)); + break; + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + reg.reg = reg_read(FWSRAM_BASE + FWSRAM_TOP_GPIO2_1_CFG_OFFS + + ((pin - 10) * 4)); + break; + default: + reg.reg = reg_read(TOP_BASE + (pin * 4)); + break; + } + + return reg; +} + +static void top_write_pin(int pin, TOP_PINMUX_t reg) +{ + + switch (pin) { + case 4: + reg_write(FWSRAM_TOP_SCL_CFG(FWSRAM_BASE), reg.reg); + break; + case 5: + reg_write(FWSRAM_TOP_SDA_CFG(FWSRAM_BASE), reg.reg); + break; + case 7: + reg_write(FWSRAM_TOP_TDO_CFG(FWSRAM_BASE), reg.reg); + break; + case 8: + reg_write(FWSRAM_TOP_GPIO2_0_CFG(FWSRAM_BASE), reg.reg); + break; + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + reg_write(FWSRAM_BASE + FWSRAM_TOP_GPIO2_1_CFG_OFFS + + ((pin - 10) * 4), reg.reg); + break; + default: + reg_write(TOP_BASE + (pin * 4), reg.reg); + break; + } +} + +int top_set_pin(int pin, int func) +{ + TOP_PINMUX_t reg; + + /* check global range */ + if ((pin < 0) || (pin > 170) || (func < 0) || (func > 3)) + return -1; /* pin number or function out of valid range */ + + /* check undefined values; */ + if ((pin == 2) || (pin == 3) || (pin == 6) || (pin == 9)) + return -1; /* pin number out of valid range */ + + reg = top_read_pin(pin); + reg.Bits.funsel = func; + top_write_pin(pin, reg); + + return 0; +} + +#endif + +#if defined(CONFIG_VCT_PLATINUMAVC) + +int top_set_pin(int pin, int func) +{ + TOP_PINMUX_t reg; + + /* check global range */ + if ((pin < 0) || (pin > 158)) + return -1; /* pin number or function out of valid range */ + + reg.reg = reg_read(TOP_BASE + (pin * 4)); + reg.Bits.funsel = func; + reg_write(TOP_BASE + (pin * 4), reg.reg); + + return 0; +} + +#endif + +void vct_pin_mux_initialize(void) +{ +#if defined(CONFIG_VCT_PREMIUM) || defined(CONFIG_VCT_PLATINUM) + top_set_pin(34, 01); /* EBI_CS0 */ + top_set_pin(33, 01); /* EBI_CS1 */ + top_set_pin(32, 01); /* EBI_CS2 */ + top_set_pin(100, 02); /* EBI_CS3 */ + top_set_pin(101, 02); /* EBI_CS4 */ + top_set_pin(102, 02); /* EBI_CS5 */ + top_set_pin(103, 02); /* EBI_CS6 */ + top_set_pin(104, 02); /* EBI_CS7 top_set_pin(104,03); EBI_GENIO3 */ + top_set_pin(35, 01); /* EBI_ALE */ + top_set_pin(36, 01); /* EBI_ADDR15 */ + top_set_pin(37, 01); /* EBI_ADDR14 top_set_pin(78,03); EBI_ADDR14 */ + top_set_pin(38, 01); /* EBI_ADDR13 */ + top_set_pin(39, 01); /* EBI_ADDR12 */ + top_set_pin(40, 01); /* EBI_ADDR11 */ + top_set_pin(41, 01); /* EBI_ADDR10 */ + top_set_pin(42, 01); /* EBI_ADDR9 */ + top_set_pin(43, 01); /* EBI_ADDR8 */ + top_set_pin(44, 01); /* EBI_ADDR7 */ + top_set_pin(45, 01); /* EBI_ADDR6 */ + top_set_pin(46, 01); /* EBI_ADDR5 */ + top_set_pin(47, 01); /* EBI_ADDR4 */ + top_set_pin(48, 01); /* EBI_ADDR3 */ + top_set_pin(49, 01); /* EBI_ADDR2 */ + top_set_pin(50, 01); /* EBI_ADDR1 */ + top_set_pin(51, 01); /* EBI_ADDR0 */ + top_set_pin(52, 01); /* EBI_DIR */ + top_set_pin(53, 01); /* EBI_DAT15 top_set_pin(81,01); EBI_DAT15 */ + top_set_pin(54, 01); /* EBI_DAT14 top_set_pin(82,01); EBI_DAT14 */ + top_set_pin(55, 01); /* EBI_DAT13 top_set_pin(83,01); EBI_DAT13 */ + top_set_pin(56, 01); /* EBI_DAT12 top_set_pin(84,01); EBI_DAT12 */ + top_set_pin(57, 01); /* EBI_DAT11 top_set_pin(85,01); EBI_DAT11 */ + top_set_pin(58, 01); /* EBI_DAT10 top_set_pin(86,01); EBI_DAT10 */ + top_set_pin(59, 01); /* EBI_DAT9 top_set_pin(87,01); EBI_DAT9 */ + top_set_pin(60, 01); /* EBI_DAT8 top_set_pin(88,01); EBI_DAT8 */ + top_set_pin(61, 01); /* EBI_DAT7 */ + top_set_pin(62, 01); /* EBI_DAT6 */ + top_set_pin(63, 01); /* EBI_DAT5 */ + top_set_pin(64, 01); /* EBI_DAT4 */ + top_set_pin(65, 01); /* EBI_DAT3 */ + top_set_pin(66, 01); /* EBI_DAT2 */ + top_set_pin(67, 01); /* EBI_DAT1 */ + top_set_pin(68, 01); /* EBI_DAT0 */ + top_set_pin(69, 01); /* EBI_IORD */ + top_set_pin(70, 01); /* EBI_IOWR */ + top_set_pin(71, 01); /* EBI_WE */ + top_set_pin(72, 01); /* EBI_OE */ + top_set_pin(73, 01); /* EBI_IORDY */ + top_set_pin(95, 02); /* EBI_EBI_DMACK*/ + top_set_pin(112, 02); /* EBI_IRQ0 */ + top_set_pin(111, 02); /* EBI_IRQ1 top_set_pin(111,03); EBI_DMARQ */ + top_set_pin(107, 02); /* EBI_IRQ2 */ + top_set_pin(108, 02); /* EBI_IRQ3 */ + top_set_pin(30, 01); /* EBI_GENIO1 top_set_pin(99,03); EBI_GENIO1 */ + top_set_pin(31, 01); /* EBI_GENIO2 top_set_pin(98,03); EBI_GENIO2 */ + top_set_pin(105, 02); /* EBI_GENIO3 top_set_pin(104,03); EBI_GENIO3 */ + top_set_pin(106, 02); /* EBI_GENIO4 top_set_pin(144,02); EBI_GENIO4 */ + top_set_pin(109, 02); /* EBI_GENIO5 top_set_pin(142,02); EBI_GENIO5 */ + top_set_pin(110, 02); /* EBI_BURST_CLK */ +#endif + +#if defined(CONFIG_VCT_PLATINUMAVC) + top_set_pin(19, 01); /* EBI_CS0 */ + top_set_pin(18, 01); /* EBI_CS1 */ + top_set_pin(17, 01); /* EBI_CS2 */ + top_set_pin(92, 02); /* EBI_CS3 */ + top_set_pin(93, 02); /* EBI_CS4 */ + top_set_pin(95, 02); /* EBI_CS6 */ + top_set_pin(96, 02); /* EBI_CS7 top_set_pin(104,03); EBI_GENIO3 */ + top_set_pin(20, 01); /* EBI_ALE */ + top_set_pin(21, 01); /* EBI_ADDR15 */ + top_set_pin(22, 01); /* EBI_ADDR14 top_set_pin(78,03); EBI_ADDR14 */ + top_set_pin(23, 01); /* EBI_ADDR13 */ + top_set_pin(24, 01); /* EBI_ADDR12 */ + top_set_pin(25, 01); /* EBI_ADDR11 */ + top_set_pin(26, 01); /* EBI_ADDR10 */ + top_set_pin(27, 01); /* EBI_ADDR9 */ + top_set_pin(28, 01); /* EBI_ADDR8 */ + top_set_pin(29, 01); /* EBI_ADDR7 */ + top_set_pin(30, 01); /* EBI_ADDR6 */ + top_set_pin(31, 01); /* EBI_ADDR5 */ + top_set_pin(32, 01); /* EBI_ADDR4 */ + top_set_pin(33, 01); /* EBI_ADDR3 */ + top_set_pin(34, 01); /* EBI_ADDR2 */ + top_set_pin(35, 01); /* EBI_ADDR1 */ + top_set_pin(36, 01); /* EBI_ADDR0 */ + top_set_pin(37, 01); /* EBI_DIR */ + top_set_pin(38, 01); /* EBI_DAT15 top_set_pin(81,01); EBI_DAT15 */ + top_set_pin(39, 01); /* EBI_DAT14 top_set_pin(82,01); EBI_DAT14 */ + top_set_pin(40, 01); /* EBI_DAT13 top_set_pin(83,01); EBI_DAT13 */ + top_set_pin(41, 01); /* EBI_DAT12 top_set_pin(84,01); EBI_DAT12 */ + top_set_pin(42, 01); /* EBI_DAT11 top_set_pin(85,01); EBI_DAT11 */ + top_set_pin(43, 01); /* EBI_DAT10 top_set_pin(86,01); EBI_DAT10 */ + top_set_pin(44, 01); /* EBI_DAT9 top_set_pin(87,01); EBI_DAT9 */ + top_set_pin(45, 01); /* EBI_DAT8 top_set_pin(88,01); EBI_DAT8 */ + top_set_pin(46, 01); /* EBI_DAT7 */ + top_set_pin(47, 01); /* EBI_DAT6 */ + top_set_pin(48, 01); /* EBI_DAT5 */ + top_set_pin(49, 01); /* EBI_DAT4 */ + top_set_pin(50, 01); /* EBI_DAT3 */ + top_set_pin(51, 01); /* EBI_DAT2 */ + top_set_pin(52, 01); /* EBI_DAT1 */ + top_set_pin(53, 01); /* EBI_DAT0 */ + top_set_pin(54, 01); /* EBI_IORD */ + top_set_pin(55, 01); /* EBI_IOWR */ + top_set_pin(56, 01); /* EBI_WE */ + top_set_pin(57, 01); /* EBI_OE */ + top_set_pin(58, 01); /* EBI_IORDY */ + top_set_pin(87, 02); /* EBI_EBI_DMACK*/ + top_set_pin(106, 02); /* EBI_IRQ0 */ + top_set_pin(105, 02); /* EBI_IRQ1 top_set_pin(111,03); EBI_DMARQ */ + top_set_pin(101, 02); /* EBI_IRQ2 */ + top_set_pin(102, 02); /* EBI_IRQ3 */ + top_set_pin(15, 01); /* EBI_GENIO1 top_set_pin(99,03); EBI_GENIO1 */ + top_set_pin(16, 01); /* EBI_GENIO2 top_set_pin(98,03); EBI_GENIO2 */ + top_set_pin(99, 02); /* EBI_GENIO3 top_set_pin(104,03); EBI_GENIO3 */ + top_set_pin(100, 02); /* EBI_GENIO4 top_set_pin(144,02); EBI_GENIO4 */ + top_set_pin(103, 02); /* EBI_GENIO5 top_set_pin(142,02); EBI_GENIO5 */ + top_set_pin(104, 02); /* EBI_BURST_CLK */ +#endif + + /* I2C: Configure I2C-2 as GPIO to enable soft-i2c */ + top_set_pin(0, 2); /* SCL2 on GPIO 11 */ + top_set_pin(1, 2); /* SDA2 on GPIO 10 */ + + /* UART pins */ +#if defined(CONFIG_VCT_PREMIUM) || defined(CONFIG_VCT_PLATINUM) + top_set_pin(141, 1); + top_set_pin(143, 1); +#endif +#if defined(CONFIG_VCT_PLATINUMAVC) + top_set_pin(107, 1); + top_set_pin(109, 1); +#endif +} diff --git a/board/micronas/vct/u-boot.lds b/board/micronas/vct/u-boot.lds new file mode 100644 index 000000000..da9e60533 --- /dev/null +++ b/board/micronas/vct/u-boot.lds @@ -0,0 +1,71 @@ +/* + * (C) Copyright 2003 + * Wolfgang Denk 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 + */ + +OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradlittlemips") +OUTPUT_ARCH(mips) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + *(.text) + } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = .; + _gp = ALIGN(16) + 0x7ff0; + + .got : { + __got_start = .; + *(.got) + __got_end = .; + } + + . = ALIGN(4); + .sdata : { *(.sdata) } + + . = ALIGN(4); + .u_boot_cmd : { + __u_boot_cmd_start = .; + *(.u_boot_cmd) + __u_boot_cmd_end = .; + } + + . = ALIGN(4); + uboot_end_data = .; + num_got_entries = (__got_end - __got_start) >> 2; + + . = ALIGN(4); + .sbss (NOLOAD) : { *(.sbss) } + . = ALIGN(4); + .bss (NOLOAD) : { *(.bss) } + uboot_end = .; +} diff --git a/board/micronas/vct/vct.c b/board/micronas/vct/vct.c new file mode 100644 index 000000000..d320e0b5f --- /dev/null +++ b/board/micronas/vct/vct.c @@ -0,0 +1,117 @@ +/* + * (C) Copyright 2008 Stefan Roese , DENX Software Engineering + * + * Copyright (C) 2006 Micronas GmbH + * + * 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 +#include +#include +#include "vct.h" + +#if defined(CONFIG_VCT_PREMIUM) +#define BOARD_NAME "PremiumD" +#elif defined(CONFIG_VCT_PLATINUM) +#define BOARD_NAME "PlatinumD" +#elif defined(CONFIG_VCT_PLATINUMAVC) +#define BOARD_NAME "PlatinumAVC" +#else +#error "vct: No board variant defined!" +#endif + +#if defined(CONFIG_VCT_ONENAND) +#define BOARD_NAME_ADD " OneNAND" +#else +#define BOARD_NAME_ADD " NOR" +#endif + +int board_early_init_f(void) +{ + /* + * First initialize the PIN mulitplexing + */ + vct_pin_mux_initialize(); + + /* + * Init the EBI very early so that FLASH can be accessed + */ + ebi_initialize(); + + return 0; +} + +void _machine_restart(void) +{ + reg_write(DCGU_EN_WDT_RESET(DCGU_BASE), DCGU_MAGIC_WDT); + reg_write(WDT_TORR(WDT_BASE), 0x00); + reg_write(WDT_CR(WDT_BASE), 0x1D); + + /* + * Now wait for the watchdog to trigger the reset + */ + udelay(1000000); +} + +/* + * SDRAM is already configured by the bootstrap code, only return the + * auto-detected size here + */ +phys_size_t initdram(int board_type) +{ + return get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, + CONFIG_SYS_MBYTES_SDRAM << 20); +} + +int checkboard(void) +{ + u32 config0 = read_c0_prid(); + char *s = getenv("serial#"); + + if ((config0 & 0xff0000) == PRID_COMP_LEGACY + && (config0 & 0xff00) == PRID_IMP_LX4280) { + puts("Board: MDED \n"); + printf("CPU: LX4280 id: 0x%02x, rev: 0x%02x\n", + (config0 >> 8) & 0xFF, config0 & 0xFF); + } else if ((config0 & 0xff0000) == PRID_COMP_MIPS + && (config0 & 0xff00) == PRID_IMP_VGC) { + u32 jedec_id = *((u32 *) 0xBEBC71A0); + if ((((jedec_id) >> 12) & 0xFF) == 0x40) { + puts("Board: VGCA \n"); + } else if ((((jedec_id) >> 12) & 0xFF) == 0x48 + || (((jedec_id) >> 12) & 0xFF) == 0x49) { + puts("Board: VGCB \n"); + } + printf("CPU: MIPS 4K id: 0x%02x, rev: 0x%02x\n", + (config0 >> 8) & 0xFF, config0 & 0xFF); + } else if (config0 == 0x19378) { + printf("CPU: MIPS 24K id: 0x%02x, rev: 0x%02x\n", + (config0 >> 8) & 0xFF, config0 & 0xFF); + } else { + printf("Unsupported cpu %d, proc_id=0x%x\n", config0 >> 24, + config0); + } + + printf("Board: Micronas VCT " BOARD_NAME BOARD_NAME_ADD); + if (s != NULL) { + puts(", serial# "); + puts(s); + } + putc('\n'); + + return 0; +} diff --git a/board/micronas/vct/vct.h b/board/micronas/vct/vct.h new file mode 100644 index 000000000..f1a485113 --- /dev/null +++ b/board/micronas/vct/vct.h @@ -0,0 +1,104 @@ +/* + * (C) Copyright 2008 Stefan Roese , DENX Software Engineering + * + * Copyright (C) 2006 Micronas GmbH + * + * 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 + +#include "bcu.h" +#include "dcgu.h" +#include "ebi.h" +#include "scc.h" + +#ifdef CONFIG_VCT_PREMIUM +/* Global start address of all memory mapped registers */ +#define REG_GLOBAL_START_ADDR 0xbf800000 +#define TOP_BASE 0x000c8000 + +#include "vcth/reg_ebi.h" +#include "vcth/reg_dcgu.h" +#include "vcth/reg_wdt.h" +#include "vcth/reg_gpio.h" +#include "vcth/reg_fwsram.h" +#include "vcth/reg_scc.h" +#include "vcth/reg_usbh.h" +#endif + +#ifdef CONFIG_VCT_PLATINUM +/* Global start address of all memory mapped registers */ +#define REG_GLOBAL_START_ADDR 0xbf800000 +#define TOP_BASE 0x000c8000 + +#include "vcth2/reg_ebi.h" +#include "vcth/reg_dcgu.h" +#include "vcth/reg_wdt.h" +#include "vcth/reg_gpio.h" +#include "vcth/reg_fwsram.h" +#include "vcth/reg_scc.h" +#include "vcth/reg_usbh.h" +#endif + +#ifdef CONFIG_VCT_PLATINUMAVC +/* Global start address of all memory mapped registers */ +#define REG_GLOBAL_START_ADDR 0xbdc00000 +#define TOP_BASE 0x00050000 + +#include "vctv/reg_ebi.h" +#include "vctv/reg_dcgu.h" +#include "vctv/reg_wdt.h" +#include "vctv/reg_gpio.h" +#endif + +#ifndef _VCT_H +#define _VCT_H + +/* + * Defines + */ +#define PRID_COMP_LEGACY 0x000000 +#define PRID_COMP_MIPS 0x010000 +#define PRID_IMP_LX4280 0xc200 +#define PRID_IMP_VGC 0x9000 + +/* + * Prototypes + */ +int ebi_initialize(void); +int ebi_init_nor_flash(void); +int ebi_init_onenand(void); +int ebi_init_smc911x(void); +u32 smc911x_reg_read(u32 addr); +void smc911x_reg_write(u32 addr, u32 data); +int top_set_pin(int pin, int func); +void vct_pin_mux_initialize(void); + +/* + * static inlines + */ +static inline void reg_write(u32 addr, u32 data) +{ + __raw_writel(data, addr + REG_GLOBAL_START_ADDR); +} + +static inline u32 reg_read(u32 addr) +{ + return __raw_readl(addr + REG_GLOBAL_START_ADDR); +} + +#endif /* _VCT_H */ -- cgit v1.2.3