diff options
Diffstat (limited to 'arch/blackfin/mach-bf561')
-rw-r--r-- | arch/blackfin/mach-bf561/Kconfig | 222 | ||||
-rw-r--r-- | arch/blackfin/mach-bf561/Makefile | 9 | ||||
-rw-r--r-- | arch/blackfin/mach-bf561/boards/Makefile | 7 | ||||
-rw-r--r-- | arch/blackfin/mach-bf561/boards/cm_bf561.c | 289 | ||||
-rw-r--r-- | arch/blackfin/mach-bf561/boards/ezkit.c | 147 | ||||
-rw-r--r-- | arch/blackfin/mach-bf561/boards/generic_board.c | 82 | ||||
-rw-r--r-- | arch/blackfin/mach-bf561/coreb.c | 402 | ||||
-rw-r--r-- | arch/blackfin/mach-bf561/head.S | 512 | ||||
-rw-r--r-- | arch/blackfin/mach-bf561/ints-priority.c | 108 |
9 files changed, 1778 insertions, 0 deletions
diff --git a/arch/blackfin/mach-bf561/Kconfig b/arch/blackfin/mach-bf561/Kconfig new file mode 100644 index 00000000000..0a17c4cf005 --- /dev/null +++ b/arch/blackfin/mach-bf561/Kconfig @@ -0,0 +1,222 @@ +if BF561 + +menu "BF561 Specific Configuration" + +comment "Core B Support" + +menu "Core B Support" + +config BF561_COREB + bool "Enable Core B support" + default y + +config BF561_COREB_RESET + bool "Enable Core B reset support" + default n + help + This requires code in the application that is loaded + into Core B. In order to reset, the application needs + to install an interrupt handler for Supplemental + Interrupt 0, that sets RETI to 0xff600000 and writes + bit 11 of SICB_SYSCR when bit 5 of SICA_SYSCR is 0. + This causes Core B to stall when Supplemental Interrupt + 0 is set, and will reset PC to 0xff600000 when + COREB_SRAM_INIT is cleared. + +endmenu + +comment "Interrupt Priority Assignment" + +menu "Priority" + +config IRQ_PLL_WAKEUP + int "PLL Wakeup Interrupt" + default 7 +config IRQ_DMA1_ERROR + int "DMA1 Error (generic)" + default 7 +config IRQ_DMA2_ERROR + int "DMA2 Error (generic)" + default 7 +config IRQ_IMDMA_ERROR + int "IMDMA Error (generic)" + default 7 +config IRQ_PPI0_ERROR + int "PPI0 Error Interrupt" + default 7 +config IRQ_PPI1_ERROR + int "PPI1 Error Interrupt" + default 7 +config IRQ_SPORT0_ERROR + int "SPORT0 Error Interrupt" + default 7 +config IRQ_SPORT1_ERROR + int "SPORT1 Error Interrupt" + default 7 +config IRQ_SPI_ERROR + int "SPI Error Interrupt" + default 7 +config IRQ_UART_ERROR + int "UART Error Interrupt" + default 7 +config IRQ_RESERVED_ERROR + int "Reserved Interrupt" + default 7 +config IRQ_DMA1_0 + int "DMA1 0 Interrupt(PPI1)" + default 8 +config IRQ_DMA1_1 + int "DMA1 1 Interrupt(PPI2)" + default 8 +config IRQ_DMA1_2 + int "DMA1 2 Interrupt" + default 8 +config IRQ_DMA1_3 + int "DMA1 3 Interrupt" + default 8 +config IRQ_DMA1_4 + int "DMA1 4 Interrupt" + default 8 +config IRQ_DMA1_5 + int "DMA1 5 Interrupt" + default 8 +config IRQ_DMA1_6 + int "DMA1 6 Interrupt" + default 8 +config IRQ_DMA1_7 + int "DMA1 7 Interrupt" + default 8 +config IRQ_DMA1_8 + int "DMA1 8 Interrupt" + default 8 +config IRQ_DMA1_9 + int "DMA1 9 Interrupt" + default 8 +config IRQ_DMA1_10 + int "DMA1 10 Interrupt" + default 8 +config IRQ_DMA1_11 + int "DMA1 11 Interrupt" + default 8 +config IRQ_DMA2_0 + int "DMA2 0 (SPORT0 RX)" + default 9 +config IRQ_DMA2_1 + int "DMA2 1 (SPORT0 TX)" + default 9 +config IRQ_DMA2_2 + int "DMA2 2 (SPORT1 RX)" + default 9 +config IRQ_DMA2_3 + int "DMA2 3 (SPORT2 TX)" + default 9 +config IRQ_DMA2_4 + int "DMA2 4 (SPI)" + default 9 +config IRQ_DMA2_5 + int "DMA2 5 (UART RX)" + default 9 +config IRQ_DMA2_6 + int "DMA2 6 (UART TX)" + default 9 +config IRQ_DMA2_7 + int "DMA2 7 Interrupt" + default 9 +config IRQ_DMA2_8 + int "DMA2 8 Interrupt" + default 9 +config IRQ_DMA2_9 + int "DMA2 9 Interrupt" + default 9 +config IRQ_DMA2_10 + int "DMA2 10 Interrupt" + default 9 +config IRQ_DMA2_11 + int "DMA2 11 Interrupt" + default 9 +config IRQ_TIMER0 + int "TIMER 0 Interrupt" + default 10 +config IRQ_TIMER1 + int "TIMER 1 Interrupt" + default 10 +config IRQ_TIMER2 + int "TIMER 2 Interrupt" + default 10 +config IRQ_TIMER3 + int "TIMER 3 Interrupt" + default 10 +config IRQ_TIMER4 + int "TIMER 4 Interrupt" + default 10 +config IRQ_TIMER5 + int "TIMER 5 Interrupt" + default 10 +config IRQ_TIMER6 + int "TIMER 6 Interrupt" + default 10 +config IRQ_TIMER7 + int "TIMER 7 Interrupt" + default 10 +config IRQ_TIMER8 + int "TIMER 8 Interrupt" + default 10 +config IRQ_TIMER9 + int "TIMER 9 Interrupt" + default 10 +config IRQ_TIMER10 + int "TIMER 10 Interrupt" + default 10 +config IRQ_TIMER11 + int "TIMER 11 Interrupt" + default 10 +config IRQ_PROG0_INTA + int "Programmable Flags0 A (8)" + default 11 +config IRQ_PROG0_INTB + int "Programmable Flags0 B (8)" + default 11 +config IRQ_PROG1_INTA + int "Programmable Flags1 A (8)" + default 11 +config IRQ_PROG1_INTB + int "Programmable Flags1 B (8)" + default 11 +config IRQ_PROG2_INTA + int "Programmable Flags2 A (8)" + default 11 +config IRQ_PROG2_INTB + int "Programmable Flags2 B (8)" + default 11 +config IRQ_DMA1_WRRD0 + int "MDMA1 0 write/read INT" + default 8 +config IRQ_DMA1_WRRD1 + int "MDMA1 1 write/read INT" + default 8 +config IRQ_DMA2_WRRD0 + int "MDMA2 0 write/read INT" + default 9 +config IRQ_DMA2_WRRD1 + int "MDMA2 1 write/read INT" + default 9 +config IRQ_IMDMA_WRRD0 + int "IMDMA 0 write/read INT" + default 12 +config IRQ_IMDMA_WRRD1 + int "IMDMA 1 write/read INT" + default 12 +config IRQ_WDTIMER + int "Watch Dog Timer" + default 13 + + help + Enter the priority numbers between 7-13 ONLY. Others are Reserved. + This applies to all the above. It is not recommended to assign the + highest priority number 7 to UART or any other device. + +endmenu + +endmenu + +endif diff --git a/arch/blackfin/mach-bf561/Makefile b/arch/blackfin/mach-bf561/Makefile new file mode 100644 index 00000000000..57f475a5516 --- /dev/null +++ b/arch/blackfin/mach-bf561/Makefile @@ -0,0 +1,9 @@ +# +# arch/blackfin/mach-bf561/Makefile +# + +extra-y := head.o + +obj-y := ints-priority.o + +obj-$(CONFIG_BF561_COREB) += coreb.o diff --git a/arch/blackfin/mach-bf561/boards/Makefile b/arch/blackfin/mach-bf561/boards/Makefile new file mode 100644 index 00000000000..886edc739ab --- /dev/null +++ b/arch/blackfin/mach-bf561/boards/Makefile @@ -0,0 +1,7 @@ +# +# arch/blackfin/mach-bf561/boards/Makefile +# + +obj-$(CONFIG_GENERIC_BOARD) += generic_board.o +obj-$(CONFIG_BFIN561_EZKIT) += ezkit.o +obj-$(CONFIG_BFIN561_BLUETECHNIX_CM) += cm_bf561.o diff --git a/arch/blackfin/mach-bf561/boards/cm_bf561.c b/arch/blackfin/mach-bf561/boards/cm_bf561.c new file mode 100644 index 00000000000..6824e956d15 --- /dev/null +++ b/arch/blackfin/mach-bf561/boards/cm_bf561.c @@ -0,0 +1,289 @@ +/* + * File: arch/blackfin/mach-bf533/boards/cm_bf561.c + * Based on: arch/blackfin/mach-bf533/boards/ezkit.c + * Author: Aidan Williams <aidan@nicta.com.au> Copright 2005 + * + * Created: 2006 + * Description: Board description file + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * 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, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <linux/device.h> +#include <linux/platform_device.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/spi/spi.h> +#include <linux/spi/flash.h> +#include <linux/usb_isp1362.h> +#include <asm/irq.h> +#include <asm/bfin5xx_spi.h> + +/* + * Name the Board for the /proc/cpuinfo + */ +char *bfin_board_name = "Bluetechnix CM BF561"; + +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) +/* all SPI perpherals info goes here */ + +#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE) +static struct mtd_partition bfin_spi_flash_partitions[] = { + { + .name = "bootloader", + .size = 0x00020000, + .offset = 0, + .mask_flags = MTD_CAP_ROM + },{ + .name = "kernel", + .size = 0xe0000, + .offset = 0x20000 + },{ + .name = "file system", + .size = 0x700000, + .offset = 0x00100000, + } +}; + +static struct flash_platform_data bfin_spi_flash_data = { + .name = "m25p80", + .parts = bfin_spi_flash_partitions, + .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions), + .type = "m25p64", +}; + +/* SPI flash chip (m25p64) */ +static struct bfin5xx_spi_chip spi_flash_chip_info = { + .enable_dma = 0, /* use dma transfer with this chip*/ + .bits_per_word = 8, +}; +#endif + +#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE) +/* SPI ADC chip */ +static struct bfin5xx_spi_chip spi_adc_chip_info = { + .enable_dma = 1, /* use dma transfer with this chip*/ + .bits_per_word = 16, +}; +#endif + +#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +static struct bfin5xx_spi_chip ad1836_spi_chip_info = { + .enable_dma = 0, + .bits_per_word = 16, +}; +#endif + +#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) +static struct bfin5xx_spi_chip ad9960_spi_chip_info = { + .enable_dma = 0, + .bits_per_word = 16, +}; +#endif + +#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) +static struct bfin5xx_spi_chip spi_mmc_chip_info = { + .enable_dma = 1, + .bits_per_word = 8, +}; +#endif + +static struct spi_board_info bfin_spi_board_info[] __initdata = { +#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE) + { + /* the modalias must be the same as spi device driver name */ + .modalias = "m25p80", /* Name of spi_driver for this device */ + .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, /* Framework bus number */ + .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/ + .platform_data = &bfin_spi_flash_data, + .controller_data = &spi_flash_chip_info, + .mode = SPI_MODE_3, + }, +#endif + +#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE) + { + .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */ + .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, /* Framework bus number */ + .chip_select = 1, /* Framework chip select. */ + .platform_data = NULL, /* No spi_driver specific config */ + .controller_data = &spi_adc_chip_info, + }, +#endif + +#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) + { + .modalias = "ad1836-spi", + .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, + .controller_data = &ad1836_spi_chip_info, + }, +#endif +#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) + { + .modalias = "ad9960-spi", + .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = 1, + .controller_data = &ad9960_spi_chip_info, + }, +#endif +#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) + { + .modalias = "spi_mmc", + .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = CONFIG_SPI_MMC_CS_CHAN, + .platform_data = NULL, + .controller_data = &spi_mmc_chip_info, + .mode = SPI_MODE_3, + }, +#endif +}; + +/* SPI controller data */ +static struct bfin5xx_spi_master spi_bfin_master_info = { + .num_chipselect = 8, + .enable_dma = 1, /* master has the ability to do dma transfer */ +}; + +static struct platform_device spi_bfin_master_device = { + .name = "bfin-spi-master", + .id = 1, /* Bus number */ + .dev = { + .platform_data = &spi_bfin_master_info, /* Passed to driver */ + }, +}; +#endif /* spi master and devices */ + + +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) + +static struct resource smc91x_resources[] = { + { + .name = "smc91x-regs", + .start = 0x28000300, + .end = 0x28000300 + 16, + .flags = IORESOURCE_MEM, + },{ + .start = IRQ_PF0, + .end = IRQ_PF0, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; +#endif + +#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) +static struct resource isp1362_hcd_resources[] = { + { + .start = 0x24008000, + .end = 0x24008000, + .flags = IORESOURCE_MEM, + },{ + .start = 0x24008004, + .end = 0x24008004, + .flags = IORESOURCE_MEM, + },{ + .start = IRQ_PF47, + .end = IRQ_PF47, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; + +static struct isp1362_platform_data isp1362_priv = { + .sel15Kres = 1, + .clknotstop = 0, + .oc_enable = 0, + .int_act_high = 0, + .int_edge_triggered = 0, + .remote_wakeup_connected = 0, + .no_power_switching = 1, + .power_switching_mode = 0, +}; + +static struct platform_device isp1362_hcd_device = { + .name = "isp1362-hcd", + .id = 0, + .dev = { + .platform_data = &isp1362_priv, + }, + .num_resources = ARRAY_SIZE(isp1362_hcd_resources), + .resource = isp1362_hcd_resources, +}; +#endif + +#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) +static struct resource bfin_uart_resources[] = { + { + .start = 0xFFC00400, + .end = 0xFFC004FF, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device bfin_uart_device = { + .name = "bfin-uart", + .id = 1, + .num_resources = ARRAY_SIZE(bfin_uart_resources), + .resource = bfin_uart_resources, +}; +#endif + +static struct platform_device *cm_bf561_devices[] __initdata = { + +#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) + &bfin_uart_device, +#endif + +#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) + &isp1362_hcd_device, +#endif + +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) + &smc91x_device, +#endif + +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) + &spi_bfin_master_device, +#endif + +}; + +static int __init cm_bf561_init(void) +{ + printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__); + platform_add_devices(cm_bf561_devices, ARRAY_SIZE(cm_bf561_devices)); +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) + spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); +#endif + return 0; +} + +arch_initcall(cm_bf561_init); diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c new file mode 100644 index 00000000000..14eb4f9a68e --- /dev/null +++ b/arch/blackfin/mach-bf561/boards/ezkit.c @@ -0,0 +1,147 @@ +/* + * File: arch/blackfin/mach-bf561/ezkit.c + * Based on: + * Author: + * + * Created: + * Description: + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * 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, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <linux/device.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> +#include <asm/irq.h> +#include <asm/bfin5xx_spi.h> + +/* + * Name the Board for the /proc/cpuinfo + */ +char *bfin_board_name = "ADDS-BF561-EZKIT"; + +/* + * USB-LAN EzExtender board + * Driver needs to know address, irq and flag pin. + */ +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) +static struct resource smc91x_resources[] = { + { + .name = "smc91x-regs", + .start = 0x2C010300, + .end = 0x2C010300 + 16, + .flags = IORESOURCE_MEM, + },{ + + .start = IRQ_PF9, + .end = IRQ_PF9, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; +#endif + +#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) +static struct resource bfin_uart_resources[] = { + { + .start = 0xFFC00400, + .end = 0xFFC004FF, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device bfin_uart_device = { + .name = "bfin-uart", + .id = 1, + .num_resources = ARRAY_SIZE(bfin_uart_resources), + .resource = bfin_uart_resources, +}; +#endif + +#ifdef CONFIG_SPI_BFIN +#if defined(CONFIG_SND_BLACKFIN_AD1836) \ + || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +static struct bfin5xx_spi_chip ad1836_spi_chip_info = { + .enable_dma = 0, + .bits_per_word = 16, +}; +#endif +#endif + +/* SPI controller data */ +static struct bfin5xx_spi_master spi_bfin_master_info = { + .num_chipselect = 8, + .enable_dma = 1, /* master has the ability to do dma transfer */ +}; + +static struct platform_device spi_bfin_master_device = { + .name = "bfin-spi-master", + .id = 1, /* Bus number */ + .dev = { + .platform_data = &spi_bfin_master_info, /* Passed to driver */ + }, +}; + +static struct spi_board_info bfin_spi_board_info[] __initdata = { +#if defined(CONFIG_SND_BLACKFIN_AD1836) \ + || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) + { + .modalias = "ad1836-spi", + .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, + .controller_data = &ad1836_spi_chip_info, + }, +#endif +}; + +static struct platform_device *ezkit_devices[] __initdata = { +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) + &smc91x_device, +#endif +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) + &spi_bfin_master_device, +#endif +#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) + &bfin_uart_device, +#endif +}; + +static int __init ezkit_init(void) +{ + int ret; + + printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__); + ret = platform_add_devices(ezkit_devices, + ARRAY_SIZE(ezkit_devices)); + if (ret < 0) + return ret; + return spi_register_board_info(bfin_spi_board_info, + ARRAY_SIZE(bfin_spi_board_info)); +} + +arch_initcall(ezkit_init); diff --git a/arch/blackfin/mach-bf561/boards/generic_board.c b/arch/blackfin/mach-bf561/boards/generic_board.c new file mode 100644 index 00000000000..585ecdd2f6a --- /dev/null +++ b/arch/blackfin/mach-bf561/boards/generic_board.c @@ -0,0 +1,82 @@ +/* + * File: arch/blackfin/mach-bf561/generic_board.c + * Based on: arch/blackfin/mach-bf533/ezkit.c + * Author: Aidan Williams <aidan@nicta.com.au> + * + * Created: + * Description: + * + * Modified: + * Copyright 2005 National ICT Australia (NICTA) + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * 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, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <linux/device.h> +#include <linux/platform_device.h> +#include <asm/irq.h> + +char *bfin_board_name = "UNKNOWN BOARD"; + +/* + * Driver needs to know address, irq and flag pin. + */ +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) +static struct resource smc91x_resources[] = { + { + .start = 0x2C010300, + .end = 0x2C010300 + 16, + .flags = IORESOURCE_MEM, + },{ + .start = IRQ_PROG_INTB, + .end = IRQ_PROG_INTB, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + },{ + /* + * denotes the flag pin and is used directly if + * CONFIG_IRQCHIP_DEMUX_GPIO is defined. + */ + .start = IRQ_PF9, + .end = IRQ_PF9, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; +#endif + +static struct platform_device *generic_board_devices[] __initdata = { +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) + &smc91x_device, +#endif +}; + +static int __init generic_board_init(void) +{ + printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__); + return platform_add_devices(generic_board_devices, + ARRAY_SIZE(generic_board_devices)); +} + +arch_initcall(generic_board_init); diff --git a/arch/blackfin/mach-bf561/coreb.c b/arch/blackfin/mach-bf561/coreb.c new file mode 100644 index 00000000000..b28582fe083 --- /dev/null +++ b/arch/blackfin/mach-bf561/coreb.c @@ -0,0 +1,402 @@ +/* + * File: arch/blackfin/mach-bf561/coreb.c + * Based on: + * Author: + * + * Created: + * Description: Handle CoreB on a BF561 + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * 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, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <linux/mm.h> +#include <linux/miscdevice.h> +#include <linux/device.h> +#include <linux/ioport.h> +#include <linux/module.h> +#include <asm/dma.h> +#include <asm/uaccess.h> + +#define MODULE_VER "v0.1" + +static spinlock_t coreb_lock; +static wait_queue_head_t coreb_dma_wait; + +#define COREB_IS_OPEN 0x00000001 +#define COREB_IS_RUNNING 0x00000010 + +#define CMD_COREB_INDEX 1 +#define CMD_COREB_START 2 +#define CMD_COREB_STOP 3 +#define CMD_COREB_RESET 4 + +#define COREB_MINOR 229 + +static unsigned long coreb_status = 0; +static unsigned long coreb_base = 0xff600000; +static unsigned long coreb_size = 0x4000; +int coreb_dma_done; + +static loff_t coreb_lseek(struct file *file, loff_t offset, int origin); +static ssize_t coreb_read(struct file *file, char *buf, size_t count, + loff_t * ppos); +static ssize_t coreb_write(struct file *file, const char *buf, size_t count, + loff_t * ppos); +static int coreb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, + unsigned long arg); +static int coreb_open(struct inode *inode, struct file *file); +static int coreb_release(struct inode *inode, struct file *file); + +static irqreturn_t coreb_dma_interrupt(int irq, void *dev_id) +{ + clear_dma_irqstat(CH_MEM_STREAM2_DEST); + coreb_dma_done = 1; + wake_up_interruptible(&coreb_dma_wait); + return IRQ_HANDLED; +} + +static ssize_t coreb_write(struct file *file, const char *buf, size_t count, + loff_t * ppos) +{ + unsigned long p = *ppos; + ssize_t wrote = 0; + + if (p + count > coreb_size) + return -EFAULT; + + while (count > 0) { + int len = count; + + if (len > PAGE_SIZE) + len = PAGE_SIZE; + + coreb_dma_done = 0; + + /* Source Channel */ + set_dma_start_addr(CH_MEM_STREAM2_SRC, (unsigned long)buf); + set_dma_x_count(CH_MEM_STREAM2_SRC, len); + set_dma_x_modify(CH_MEM_STREAM2_SRC, sizeof(char)); + set_dma_config(CH_MEM_STREAM2_SRC, RESTART); + /* Destination Channel */ + set_dma_start_addr(CH_MEM_STREAM2_DEST, coreb_base + p); + set_dma_x_count(CH_MEM_STREAM2_DEST, len); + set_dma_x_modify(CH_MEM_STREAM2_DEST, sizeof(char)); + set_dma_config(CH_MEM_STREAM2_DEST, WNR | RESTART | DI_EN); + + enable_dma(CH_MEM_STREAM2_SRC); + enable_dma(CH_MEM_STREAM2_DEST); + + wait_event_interruptible(coreb_dma_wait, coreb_dma_done); + + disable_dma(CH_MEM_STREAM2_SRC); + disable_dma(CH_MEM_STREAM2_DEST); + + count -= len; + wrote += len; + buf += len; + p += len; + } + *ppos = p; + return wrote; +} + +static ssize_t coreb_read(struct file *file, char *buf, size_t count, + loff_t * ppos) +{ + unsigned long p = *ppos; + ssize_t read = 0; + + if ((p + count) > coreb_size) + return -EFAULT; + + while (count > 0) { + int len = count; + + if (len > PAGE_SIZE) + len = PAGE_SIZE; + + coreb_dma_done = 0; + + /* Source Channel */ + set_dma_start_addr(CH_MEM_STREAM2_SRC, coreb_base + p); + set_dma_x_count(CH_MEM_STREAM2_SRC, len); + set_dma_x_modify(CH_MEM_STREAM2_SRC, sizeof(char)); + set_dma_config(CH_MEM_STREAM2_SRC, RESTART); + /* Destination Channel */ + set_dma_start_addr(CH_MEM_STREAM2_DEST, (unsigned long)buf); + set_dma_x_count(CH_MEM_STREAM2_DEST, len); + set_dma_x_modify(CH_MEM_STREAM2_DEST, sizeof(char)); + set_dma_config(CH_MEM_STREAM2_DEST, WNR | RESTART | DI_EN); + + enable_dma(CH_MEM_STREAM2_SRC); + enable_dma(CH_MEM_STREAM2_DEST); + + wait_event_interruptible(coreb_dma_wait, coreb_dma_done); + + disable_dma(CH_MEM_STREAM2_SRC); + disable_dma(CH_MEM_STREAM2_DEST); + + count -= len; + read += len; + buf += len; + p += len; + } + + return read; +} + +static loff_t coreb_lseek(struct file *file, loff_t offset, int origin) +{ + loff_t ret; + + mutex_lock(&file->f_dentry->d_inode->i_mutex); + + switch (origin) { + case 0 /* SEEK_SET */ : + if (offset < coreb_size) { + file->f_pos = offset; + ret = file->f_pos; + } else + ret = -EINVAL; + break; + case 1 /* SEEK_CUR */ : + if ((offset + file->f_pos) < coreb_size) { + file->f_pos += offset; + ret = file->f_pos; + } else + ret = -EINVAL; + default: + ret = -EINVAL; + } + mutex_unlock(&file->f_dentry->d_inode->i_mutex); + return ret; +} + +static int coreb_open(struct inode *inode, struct file *file) +{ + spin_lock_irq(&coreb_lock); + + if (coreb_status & COREB_IS_OPEN) + goto out_busy; + + coreb_status |= COREB_IS_OPEN; + + spin_unlock_irq(&coreb_lock); + return 0; + + out_busy: + spin_unlock_irq(&coreb_lock); + return -EBUSY; +} + +static int coreb_release(struct inode *inode, struct file *file) +{ + spin_lock_irq(&coreb_lock); + coreb_status &= ~COREB_IS_OPEN; + spin_unlock_irq(&coreb_lock); + return 0; +} + +static int coreb_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + int retval = 0; + int coreb_index = 0; + + switch (cmd) { + case CMD_COREB_INDEX: + if (copy_from_user(&coreb_index, (int *)arg, sizeof(int))) { + retval = -EFAULT; + break; + } + + spin_lock_irq(&coreb_lock); + switch (coreb_index) { + case 0: + coreb_base = 0xff600000; + coreb_size = 0x4000; + break; + case 1: + coreb_base = 0xff610000; + coreb_size = 0x4000; + break; + case 2: + coreb_base = 0xff500000; + coreb_size = 0x8000; + break; + case 3: + coreb_base = 0xff400000; + coreb_size = 0x8000; + break; + default: + retval = -EINVAL; + break; + } + spin_unlock_irq(&coreb_lock); + + mutex_lock(&file->f_dentry->d_inode->i_mutex); + file->f_pos = 0; + mutex_unlock(&file->f_dentry->d_inode->i_mutex); + break; + case CMD_COREB_START: + spin_lock_irq(&coreb_lock); + if (coreb_status & COREB_IS_RUNNING) { + retval = -EBUSY; + break; + } + printk(KERN_INFO "Starting Core B\n"); + coreb_status |= COREB_IS_RUNNING; + bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() & ~0x0020); + SSYNC(); + spin_lock_irq(&coreb_lock); + break; +#if defined(CONFIG_BF561_COREB_RESET) + case CMD_COREB_STOP: + spin_lock_irq(&coreb_lock); + printk(KERN_INFO "Stopping Core B\n"); + bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() | 0x0020); + bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | 0x0080); + coreb_status &= ~COREB_IS_RUNNING; + spin_lock_irq(&coreb_lock); + break; + case CMD_COREB_RESET: + printk(KERN_INFO "Resetting Core B\n"); + bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | 0x0080); + break; +#endif + } + + return retval; +} + +static struct file_operations coreb_fops = { + .owner = THIS_MODULE, + .llseek = coreb_lseek, + .read = coreb_read, + .write = coreb_write, + .ioctl = coreb_ioctl, + .open = coreb_open, + .release = coreb_release +}; + +static struct miscdevice coreb_dev = { + COREB_MINOR, + "coreb", + &coreb_fops +}; + +static ssize_t coreb_show_status(struct device *dev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, + "Base Address:\t0x%08lx\n" + "Core B is %s\n" + "SICA_SYSCR:\t%04x\n" + "SICB_SYSCR:\t%04x\n" + "\n" + "IRQ Status:\tCore A\t\tCore B\n" + "ISR0:\t\t%08x\t\t%08x\n" + "ISR1:\t\t%08x\t\t%08x\n" + "IMASK0:\t\t%08x\t\t%08x\n" + "IMASK1:\t\t%08x\t\t%08x\n", + coreb_base, + coreb_status & COREB_IS_RUNNING ? "running" : "stalled", + bfin_read_SICA_SYSCR(), bfin_read_SICB_SYSCR(), + bfin_read_SICA_ISR0(), bfin_read_SICB_ISR0(), + bfin_read_SICA_ISR1(), bfin_read_SICB_ISR0(), + bfin_read_SICA_IMASK0(), bfin_read_SICB_IMASK0(), + bfin_read_SICA_IMASK1(), bfin_read_SICB_IMASK1()); +} + +static DEVICE_ATTR(coreb_status, S_IRUGO, coreb_show_status, NULL); + +int __init bf561_coreb_init(void) +{ + init_waitqueue_head(&coreb_dma_wait); + + spin_lock_init(&coreb_lock); + /* Request the core memory regions for Core B */ + if (request_mem_region(0xff600000, 0x4000, + "Core B - Instruction SRAM") == NULL) + goto exit; + + if (request_mem_region(0xFF610000, 0x4000, + "Core B - Instruction SRAM") == NULL) + goto release_instruction_a_sram; + + if (request_mem_region(0xFF500000, 0x8000, + "Core B - Data Bank B SRAM") == NULL) + goto release_instruction_b_sram; + + if (request_mem_region(0xff400000, 0x8000, + "Core B - Data Bank A SRAM") == NULL) + goto release_data_b_sram; + + if (request_dma(CH_MEM_STREAM2_DEST, "Core B - DMA Destination") < 0) + goto release_data_a_sram; + + if (request_dma(CH_MEM_STREAM2_SRC, "Core B - DMA Source") < 0) + goto release_dma_dest; + + set_dma_callback(CH_MEM_STREAM2_DEST, coreb_dma_interrupt, NULL); + + misc_register(&coreb_dev); + + if (device_create_file(coreb_dev.this_device, &dev_attr_coreb_status)) + goto release_dma_src; + + printk(KERN_INFO "BF561 Core B driver %s initialized.\n", MODULE_VER); + return 0; + + release_dma_src: + free_dma(CH_MEM_STREAM2_SRC); + release_dma_dest: + free_dma(CH_MEM_STREAM2_DEST); + release_data_a_sram: + release_mem_region(0xff400000, 0x8000); + release_data_b_sram: + release_mem_region(0xff500000, 0x8000); + release_instruction_b_sram: + release_mem_region(0xff610000, 0x4000); + release_instruction_a_sram: + release_mem_region(0xff600000, 0x4000); + exit: + return -ENOMEM; +} + +void __exit bf561_coreb_exit(void) +{ + device_remove_file(coreb_dev.this_device, &dev_attr_coreb_status); + misc_deregister(&coreb_dev); + + release_mem_region(0xff610000, 0x4000); + release_mem_region(0xff600000, 0x4000); + release_mem_region(0xff500000, 0x8000); + release_mem_region(0xff400000, 0x8000); + + free_dma(CH_MEM_STREAM2_DEST); + free_dma(CH_MEM_STREAM2_SRC); +} + +module_init(bf561_coreb_init); +module_exit(bf561_coreb_exit); + +MODULE_AUTHOR("Bas Vermeulen <bvermeul@blackstar.xs4all.nl>"); +MODULE_DESCRIPTION("BF561 Core B Support"); diff --git a/arch/blackfin/mach-bf561/head.S b/arch/blackfin/mach-bf561/head.S new file mode 100644 index 00000000000..7bca478526b --- /dev/null +++ b/arch/blackfin/mach-bf561/head.S @@ -0,0 +1,512 @@ +/* + * File: arch/blackfin/mach-bf561/head.S + * Based on: arch/blackfin/mach-bf533/head.S + * Author: + * + * Created: + * Description: BF561 startup file + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * 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, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <linux/linkage.h> +#include <asm/blackfin.h> +#if CONFIG_BFIN_KERNEL_CLOCK +#include <asm/mach/mem_init.h> +#endif + +.global __rambase +.global __ramstart +.global __ramend +.extern ___bss_stop +.extern ___bss_start +.extern _bf53x_relocate_l1_mem + +#define INITIAL_STACK 0xFFB01000 + +.text + +ENTRY(__start) +ENTRY(__stext) + /* R0: argument of command line string, passed from uboot, save it */ + R7 = R0; + /* Set the SYSCFG register */ + R0 = 0x36; + SYSCFG = R0; /*Enable Cycle Counter and Nesting Of Interrupts(3rd Bit)*/ + R0 = 0; + + /*Clear Out All the data and pointer Registers*/ + R1 = R0; + R2 = R0; + R3 = R0; + R4 = R0; + R5 = R0; + R6 = R0; + + P0 = R0; + P1 = R0; + P2 = R0; + P3 = R0; + P4 = R0; + P5 = R0; + + LC0 = r0; + LC1 = r0; + L0 = r0; + L1 = r0; + L2 = r0; + L3 = r0; + + /* Clear Out All the DAG Registers*/ + B0 = r0; + B1 = r0; + B2 = r0; + B3 = r0; + + I0 = r0; + I1 = r0; + I2 = r0; + I3 = r0; + + M0 = r0; + M1 = r0; + M2 = r0; + M3 = r0; + + /* Turn off the icache */ + p0.l = (IMEM_CONTROL & 0xFFFF); + p0.h = (IMEM_CONTROL >> 16); + R1 = [p0]; + R0 = ~ENICPLB; + R0 = R0 & R1; + + /* Anomaly 05000125 */ +#ifdef ANOMALY_05000125 + CLI R2; + SSYNC; +#endif + [p0] = R0; + SSYNC; +#ifdef ANOMALY_05000125 + STI R2; +#endif + + /* Turn off the dcache */ + p0.l = (DMEM_CONTROL & 0xFFFF); + p0.h = (DMEM_CONTROL >> 16); + R1 = [p0]; + R0 = ~ENDCPLB; + R0 = R0 & R1; + + /* Anomaly 05000125 */ +#ifdef ANOMALY_05000125 + CLI R2; + SSYNC; +#endif + [p0] = R0; + SSYNC; +#ifdef ANOMALY_05000125 + STI R2; +#endif + + /* Initialise UART*/ + p0.h = hi(UART_LCR); + p0.l = lo(UART_LCR); + r0 = 0x0(Z); + w[p0] = r0.L; /* To enable DLL writes */ + ssync; + + p0.h = hi(UART_DLL); + p0.l = lo(UART_DLL); + r0 = 0x0(Z); + w[p0] = r0.L; + ssync; + + p0.h = hi(UART_DLH); + p0.l = lo(UART_DLH); + r0 = 0x00(Z); + w[p0] = r0.L; + ssync; + + p0.h = hi(UART_GCTL); + p0.l = lo(UART_GCTL); + r0 = 0x0(Z); + w[p0] = r0.L; /* To enable UART clock */ + ssync; + + /* Initialize stack pointer */ + sp.l = lo(INITIAL_STACK); + sp.h = hi(INITIAL_STACK); + fp = sp; + usp = sp; + + /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */ + call _bf53x_relocate_l1_mem; +#if CONFIG_BFIN_KERNEL_CLOCK + call _start_dma_code; +#endif + + /* Code for initializing Async memory banks */ + + p2.h = hi(EBIU_AMBCTL1); + p2.l = lo(EBIU_AMBCTL1); + r0.h = hi(AMBCTL1VAL); + r0.l = lo(AMBCTL1VAL); + [p2] = r0; + ssync; + + p2.h = hi(EBIU_AMBCTL0); + p2.l = lo(EBIU_AMBCTL0); + r0.h = hi(AMBCTL0VAL); + r0.l = lo(AMBCTL0VAL); + [p2] = r0; + ssync; + + p2.h = hi(EBIU_AMGCTL); + p2.l = lo(EBIU_AMGCTL); + r0 = AMGCTLVAL; + w[p2] = r0; + ssync; + + /* This section keeps the processor in supervisor mode + * during kernel boot. Switches to user mode at end of boot. + * See page 3-9 of Hardware Reference manual for documentation. + */ + + /* EVT15 = _real_start */ + + p0.l = lo(EVT15); + p0.h = hi(EVT15); + p1.l = _real_start; + p1.h = _real_start; + [p0] = p1; + csync; + + p0.l = lo(IMASK); + p0.h = hi(IMASK); + p1.l = IMASK_IVG15; + p1.h = 0x0; + [p0] = p1; + csync; + + raise 15; + p0.l = .LWAIT_HERE; + p0.h = .LWAIT_HERE; + reti = p0; +#if defined(ANOMALY_05000281) + nop; nop; nop; +#endif + rti; + +.LWAIT_HERE: + jump .LWAIT_HERE; + +ENTRY(_real_start) + [ -- sp ] = reti; + p0.l = lo(WDOGA_CTL); + p0.h = hi(WDOGA_CTL); + r0 = 0xAD6(z); + w[p0] = r0; /* watchdog off for now */ + ssync; + + /* Code update for BSS size == 0 + * Zero out the bss region. + */ + + p1.l = ___bss_start; + p1.h = ___bss_start; + p2.l = ___bss_stop; + p2.h = ___bss_stop; + r0 = 0; + p2 -= p1; + lsetup (.L_clear_bss, .L_clear_bss ) lc0 = p2; +.L_clear_bss: + B[p1++] = r0; + + /* In case there is a NULL pointer reference + * Zero out region before stext + */ + + p1.l = 0x0; + p1.h = 0x0; + r0.l = __stext; + r0.h = __stext; + r0 = r0 >> 1; + p2 = r0; + r0 = 0; + lsetup (.L_clear_zero, .L_clear_zero ) lc0 = p2; +.L_clear_zero: + W[p1++] = r0; + +/* pass the uboot arguments to the global value command line */ + R0 = R7; + call _cmdline_init; + + p1.l = __rambase; + p1.h = __rambase; + r0.l = __sdata; + r0.h = __sdata; + [p1] = r0; + + p1.l = __ramstart; + p1.h = __ramstart; + p3.l = ___bss_stop; + p3.h = ___bss_stop; + + r1 = p3; + [p1] = r1; + + /* + * load the current thread pointer and stack + */ + r1.l = _init_thread_union; + r1.h = _init_thread_union; + + r2.l = 0x2000; + r2.h = 0x0000; + r1 = r1 + r2; + sp = r1; + usp = sp; + fp = sp; + call _start_kernel; +.L_exit: + jump.s .L_exit; + +.section .l1.text +#if CONFIG_BFIN_KERNEL_CLOCK +ENTRY(_start_dma_code) + p0.h = hi(SICA_IWR0); + p0.l = lo(SICA_IWR0); + r0.l = 0x1; + [p0] = r0; + SSYNC; + + /* + * Set PLL_CTL + * - [14:09] = MSEL[5:0] : CLKIN / VCO multiplication factors + * - [8] = BYPASS : BYPASS the PLL, run CLKIN into CCLK/SCLK + * - [7] = output delay (add 200ps of delay to mem signals) + * - [6] = input delay (add 200ps of input delay to mem signals) + * - [5] = PDWN : 1=All Clocks off + * - [3] = STOPCK : 1=Core Clock off + * - [1] = PLL_OFF : 1=Disable Power to PLL + * - [0] = DF : 1=Pass CLKIN/2 to PLL / 0=Pass CLKIN to PLL + * all other bits set to zero + */ + + p0.h = hi(PLL_LOCKCNT); + p0.l = lo(PLL_LOCKCNT); + r0 = 0x300(Z); + w[p0] = r0.l; + ssync; + + P2.H = hi(EBIU_SDGCTL); + P2.L = lo(EBIU_SDGCTL); + R0 = [P2]; + BITSET (R0, 24); + [P2] = R0; + SSYNC; + + r0 = CONFIG_VCO_MULT & 63; /* Load the VCO multiplier */ + r0 = r0 << 9; /* Shift it over, */ + r1 = CLKIN_HALF; /* Do we need to divide CLKIN by 2?*/ + r0 = r1 | r0; + r1 = PLL_BYPASS; /* Bypass the PLL? */ + r1 = r1 << 8; /* Shift it over */ + r0 = r1 | r0; /* add them all together */ + + p0.h = hi(PLL_CTL); + p0.l = lo(PLL_CTL); /* Load the address */ + cli r2; /* Disable interrupts */ + ssync; + w[p0] = r0.l; /* Set the value */ + idle; /* Wait for the PLL to stablize */ + sti r2; /* Enable interrupts */ + +.Lcheck_again: + p0.h = hi(PLL_STAT); + p0.l = lo(PLL_STAT); + R0 = W[P0](Z); + CC = BITTST(R0,5); + if ! CC jump .Lcheck_again; + + /* Configure SCLK & CCLK Dividers */ + r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV); + p0.h = hi(PLL_DIV); + p0.l = lo(PLL_DIV); + w[p0] = r0.l; + ssync; + + p0.l = lo(EBIU_SDRRC); + p0.h = hi(EBIU_SDRRC); + r0 = mem_SDRRC; + w[p0] = r0.l; + ssync; + + p0.l = (EBIU_SDBCTL & 0xFFFF); + p0.h = (EBIU_SDBCTL >> 16); /* SDRAM Memory Bank Control Register */ + r0 = mem_SDBCTL; + w[p0] = r0.l; + ssync; + + P2.H = hi(EBIU_SDGCTL); + P2.L = lo(EBIU_SDGCTL); + R0 = [P2]; + BITCLR (R0, 24); + p0.h = hi(EBIU_SDSTAT); + p0.l = lo(EBIU_SDSTAT); + r2.l = w[p0]; + cc = bittst(r2,3); + if !cc jump .Lskip; + NOP; + BITSET (R0, 23); +.Lskip: + [P2] = R0; + SSYNC; + + R0.L = lo(mem_SDGCTL); + R0.H = hi(mem_SDGCTL); + R1 = [p2]; + R1 = R1 | R0; + [P2] = R1; + SSYNC; + + RTS; +#endif /* CONFIG_BFIN_KERNEL_CLOCK */ + +ENTRY(_bfin_reset) + /* No more interrupts to be handled*/ + CLI R6; + SSYNC; + +#if defined(CONFIG_BFIN_SHARED_FLASH_ENET) + p0.h = hi(FIO_INEN); + p0.l = lo(FIO_INEN); + r0.l = ~(PF1 | PF0); + w[p0] = r0.l; + + p0.h = hi(FIO_DIR); + p0.l = lo(FIO_DIR); + r0.l = (PF1 | PF0); + w[p0] = r0.l; + + p0.h = hi(FIO_FLAG_C); + p0.l = lo(FIO_FLAG_C); + r0.l = (PF1 | PF0); + w[p0] = r0.l; +#endif + + /* Clear the bits 13-15 in SWRST if they werent cleared */ + p0.h = hi(SICA_SWRST); + p0.l = lo(SICA_SWRST); + csync; + r0.l = w[p0]; + + /* Clear the IMASK register */ + p0.h = hi(IMASK); + p0.l = lo(IMASK); + r0 = 0x0; + [p0] = r0; + + /* Clear the ILAT register */ + p0.h = hi(ILAT); + p0.l = lo(ILAT); + r0 = [p0]; + [p0] = r0; + SSYNC; + + /* Disable the WDOG TIMER */ + p0.h = hi(WDOGA_CTL); + p0.l = lo(WDOGA_CTL); + r0.l = 0xAD6; + w[p0] = r0.l; + SSYNC; + + /* Clear the sticky bit incase it is already set */ + p0.h = hi(WDOGA_CTL); + p0.l = lo(WDOGA_CTL); + r0.l = 0x8AD6; + w[p0] = r0.l; + SSYNC; + + /* Program the count value */ + R0.l = 0x100; + R0.h = 0x0; + P0.h = hi(WDOGA_CNT); + P0.l = lo(WDOGA_CNT); + [P0] = R0; + SSYNC; + + /* Program WDOG_STAT if necessary */ + P0.h = hi(WDOGA_CTL); + P0.l = lo(WDOGA_CTL); + R0 = W[P0](Z); + CC = BITTST(R0,1); + if !CC JUMP .LWRITESTAT; + CC = BITTST(R0,2); + if !CC JUMP .LWRITESTAT; + JUMP .LSKIP_WRITE; + +.LWRITESTAT: + /* When watch dog timer is enabled, + * a write to STAT will load the contents of CNT to STAT + */ + R0 = 0x0000(z); + P0.h = hi(WDOGA_STAT); + P0.l = lo(WDOGA_STAT) + [P0] = R0; + SSYNC; + +.LSKIP_WRITE: + /* Enable the reset event */ + P0.h = hi(WDOGA_CTL); + P0.l = lo(WDOGA_CTL); + R0 = W[P0](Z); + BITCLR(R0,1); + BITCLR(R0,2); + W[P0] = R0.L; + SSYNC; + NOP; + + /* Enable the wdog counter */ + R0 = W[P0](Z); + BITCLR(R0,4); + W[P0] = R0.L; + SSYNC; + + IDLE; + + RTS; + +.data + +/* + * Set up the usable of RAM stuff. Size of RAM is determined then + * an initial stack set up at the end. + */ + +.align 4 +__rambase: +.long 0 +__ramstart: +.long 0 +__ramend: +.long 0 diff --git a/arch/blackfin/mach-bf561/ints-priority.c b/arch/blackfin/mach-bf561/ints-priority.c new file mode 100644 index 00000000000..89c52ff95b2 --- /dev/null +++ b/arch/blackfin/mach-bf561/ints-priority.c @@ -0,0 +1,108 @@ +/* + * File: arch/blackfin/mach-bf561/ints-priority.c + * Based on: arch/blackfin/mach-bf537/ints-priority.c + * Author: Michael Hennerich + * + * Created: + * Description: Set up the interupt priorities + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * 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, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <linux/module.h> +#include <asm/blackfin.h> +#include <asm/irq.h> + +void program_IAR(void) +{ + /* Program the IAR0 Register with the configured priority */ + bfin_write_SICA_IAR0(((CONFIG_IRQ_PLL_WAKEUP - 7) << IRQ_PLL_WAKEUP_POS) | + ((CONFIG_IRQ_DMA1_ERROR - 7) << IRQ_DMA1_ERROR_POS) | + ((CONFIG_IRQ_DMA2_ERROR - 7) << IRQ_DMA2_ERROR_POS) | + ((CONFIG_IRQ_IMDMA_ERROR - 7) << IRQ_IMDMA_ERROR_POS) | + ((CONFIG_IRQ_PPI0_ERROR - 7) << IRQ_PPI0_ERROR_POS) | + ((CONFIG_IRQ_PPI1_ERROR - 7) << IRQ_PPI1_ERROR_POS) | + ((CONFIG_IRQ_SPORT0_ERROR - 7) << IRQ_SPORT0_ERROR_POS) | + ((CONFIG_IRQ_SPORT1_ERROR - 7) << IRQ_SPORT1_ERROR_POS)); + + bfin_write_SICA_IAR1(((CONFIG_IRQ_SPI_ERROR - 7) << IRQ_SPI_ERROR_POS) | + ((CONFIG_IRQ_UART_ERROR - 7) << IRQ_UART_ERROR_POS) | + ((CONFIG_IRQ_RESERVED_ERROR - 7) << IRQ_RESERVED_ERROR_POS) | + ((CONFIG_IRQ_DMA1_0 - 7) << IRQ_DMA1_0_POS) | + ((CONFIG_IRQ_DMA1_1 - 7) << IRQ_DMA1_1_POS) | + ((CONFIG_IRQ_DMA1_2 - 7) << IRQ_DMA1_2_POS) | + ((CONFIG_IRQ_DMA1_3 - 7) << IRQ_DMA1_3_POS) | + ((CONFIG_IRQ_DMA1_4 - 7) << IRQ_DMA1_4_POS)); + + bfin_write_SICA_IAR2(((CONFIG_IRQ_DMA1_5 - 7) << IRQ_DMA1_5_POS) | + ((CONFIG_IRQ_DMA1_6 - 7) << IRQ_DMA1_6_POS) | + ((CONFIG_IRQ_DMA1_7 - 7) << IRQ_DMA1_7_POS) | + ((CONFIG_IRQ_DMA1_8 - 7) << IRQ_DMA1_8_POS) | + ((CONFIG_IRQ_DMA1_9 - 7) << IRQ_DMA1_9_POS) | + ((CONFIG_IRQ_DMA1_10 - 7) << IRQ_DMA1_10_POS) | + ((CONFIG_IRQ_DMA1_11 - 7) << IRQ_DMA1_11_POS) | + ((CONFIG_IRQ_DMA2_0 - 7) << IRQ_DMA2_0_POS)); + + bfin_write_SICA_IAR3(((CONFIG_IRQ_DMA2_1 - 7) << IRQ_DMA2_1_POS) | + ((CONFIG_IRQ_DMA2_2 - 7) << IRQ_DMA2_2_POS) | + ((CONFIG_IRQ_DMA2_3 - 7) << IRQ_DMA2_3_POS) | + ((CONFIG_IRQ_DMA2_4 - 7) << IRQ_DMA2_4_POS) | + ((CONFIG_IRQ_DMA2_5 - 7) << IRQ_DMA2_5_POS) | + ((CONFIG_IRQ_DMA2_6 - 7) << IRQ_DMA2_6_POS) | + ((CONFIG_IRQ_DMA2_7 - 7) << IRQ_DMA2_7_POS) | + ((CONFIG_IRQ_DMA2_8 - 7) << IRQ_DMA2_8_POS)); + + bfin_write_SICA_IAR4(((CONFIG_IRQ_DMA2_9 - 7) << IRQ_DMA2_9_POS) | + ((CONFIG_IRQ_DMA2_10 - 7) << IRQ_DMA2_10_POS) | + ((CONFIG_IRQ_DMA2_11 - 7) << IRQ_DMA2_11_POS) | + ((CONFIG_IRQ_TIMER0 - 7) << IRQ_TIMER0_POS) | + ((CONFIG_IRQ_TIMER1 - 7) << IRQ_TIMER1_POS) | + ((CONFIG_IRQ_TIMER2 - 7) << IRQ_TIMER2_POS) | + ((CONFIG_IRQ_TIMER3 - 7) << IRQ_TIMER3_POS) | + ((CONFIG_IRQ_TIMER4 - 7) << IRQ_TIMER4_POS)); + + bfin_write_SICA_IAR5(((CONFIG_IRQ_TIMER5 - 7) << IRQ_TIMER5_POS) | + ((CONFIG_IRQ_TIMER6 - 7) << IRQ_TIMER6_POS) | + ((CONFIG_IRQ_TIMER7 - 7) << IRQ_TIMER7_POS) | + ((CONFIG_IRQ_TIMER8 - 7) << IRQ_TIMER8_POS) | + ((CONFIG_IRQ_TIMER9 - 7) << IRQ_TIMER9_POS) | + ((CONFIG_IRQ_TIMER10 - 7) << IRQ_TIMER10_POS) | + ((CONFIG_IRQ_TIMER11 - 7) << IRQ_TIMER11_POS) | + ((CONFIG_IRQ_PROG0_INTA - 7) << IRQ_PROG0_INTA_POS)); + + bfin_write_SICA_IAR6(((CONFIG_IRQ_PROG0_INTB - 7) << IRQ_PROG0_INTB_POS) | + ((CONFIG_IRQ_PROG1_INTA - 7) << IRQ_PROG1_INTA_POS) | + ((CONFIG_IRQ_PROG1_INTB - 7) << IRQ_PROG1_INTB_POS) | + ((CONFIG_IRQ_PROG2_INTA - 7) << IRQ_PROG2_INTA_POS) | + ((CONFIG_IRQ_PROG2_INTB - 7) << IRQ_PROG2_INTB_POS) | + ((CONFIG_IRQ_DMA1_WRRD0 - 7) << IRQ_DMA1_WRRD0_POS) | + ((CONFIG_IRQ_DMA1_WRRD1 - 7) << IRQ_DMA1_WRRD1_POS) | + ((CONFIG_IRQ_DMA2_WRRD0 - 7) << IRQ_DMA2_WRRD0_POS)); + + bfin_write_SICA_IAR7(((CONFIG_IRQ_DMA2_WRRD1 - 7) << IRQ_DMA2_WRRD1_POS) | + ((CONFIG_IRQ_IMDMA_WRRD0 - 7) << IRQ_IMDMA_WRRD0_POS) | + ((CONFIG_IRQ_IMDMA_WRRD1 - 7) << IRQ_IMDMA_WRRD1_POS) | + ((CONFIG_IRQ_WDTIMER - 7) << IRQ_WDTIMER_POS) | + (0 << IRQ_RESERVED_1_POS) | (0 << IRQ_RESERVED_2_POS) | + (0 << IRQ_SUPPLE_0_POS) | (0 << IRQ_SUPPLE_1_POS)); + + SSYNC(); +} |