diff options
Diffstat (limited to 'drivers')
35 files changed, 670 insertions, 235 deletions
diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c index e8273ee..d1065f4 100644 --- a/drivers/gpio/pca953x.c +++ b/drivers/gpio/pca953x.c @@ -150,7 +150,7 @@ cmd_tbl_t cmd_pca953x[] = { #endif }; -int do_pca953x(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_pca953x(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { static uint8_t chip = CONFIG_SYS_I2C_PCA953X_ADDR; int val; diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 96aa331..4f15db9 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -28,6 +28,7 @@ LIB := $(obj)libmisc.a COBJS-$(CONFIG_ALI152X) += ali512x.o COBJS-$(CONFIG_DS4510) += ds4510.o COBJS-$(CONFIG_FSL_LAW) += fsl_law.o +COBJS-$(CONFIG_GPIO_LED) += gpio_led.o COBJS-$(CONFIG_NS87308) += ns87308.o COBJS-$(CONFIG_STATUS_LED) += status_led.o COBJS-$(CONFIG_TWL4030_LED) += twl4030_led.o diff --git a/drivers/misc/ds4510.c b/drivers/misc/ds4510.c index f2510a3..5b33c1f 100644 --- a/drivers/misc/ds4510.c +++ b/drivers/misc/ds4510.c @@ -273,7 +273,7 @@ cmd_tbl_t cmd_ds4510[] = { #endif }; -int do_ds4510(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_ds4510(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { static uint8_t chip = CONFIG_SYS_I2C_DS4510_ADDR; cmd_tbl_t *c; diff --git a/drivers/misc/fsl_pmic.c b/drivers/misc/fsl_pmic.c index 87f0aed..274327f 100644 --- a/drivers/misc/fsl_pmic.c +++ b/drivers/misc/fsl_pmic.c @@ -156,7 +156,7 @@ static void pmic_dump(int numregs) puts("\n"); } -int do_pmic(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_pmic(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *cmd; int nregs; diff --git a/drivers/misc/gpio_led.c b/drivers/misc/gpio_led.c new file mode 100644 index 0000000..acd6a90 --- /dev/null +++ b/drivers/misc/gpio_led.c @@ -0,0 +1,30 @@ +/* + * Status LED driver based on GPIO access conventions of Linux + * + * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw> + * + * 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. + */ + +#include <common.h> +#include <status_led.h> +#include <asm/gpio.h> + +/* assume led is active low */ + +void __led_init(led_id_t mask, int state) +{ + gpio_direction_output(mask, (state == STATUS_LED_ON) ? 0 : 1); +} + +void __led_set(led_id_t mask, int state) +{ + gpio_set_value(mask, (state == STATUS_LED_ON) ? 0 : 1); +} + +void __led_toggle(led_id_t mask) +{ + gpio_set_value(mask, !gpio_get_value(mask)); +} diff --git a/drivers/mmc/pxa_mmc.c b/drivers/mmc/pxa_mmc.c index 8225235..8776903 100644 --- a/drivers/mmc/pxa_mmc.c +++ b/drivers/mmc/pxa_mmc.c @@ -126,7 +126,7 @@ mmc_block_read(uchar * dst, ulong src, ulong len) MMC_I_MASK = ~MMC_I_MASK_RXFIFO_RD_REQ; while (len) { if (MMC_I_REG & MMC_I_REG_RXFIFO_RD_REQ) { -#ifdef CONFIG_PXA27X +#if defined(CONFIG_PXA27X) || defined(CONFIG_CPU_MONAHANS) int i; for (i = min(len, 32); i; i--) { *dst++ = *((volatile uchar *)&MMC_RXFIFO); @@ -558,8 +558,11 @@ mmc_legacy_init(int verbose) set_GPIO_mode(GPIO6_MMCCLK_MD); set_GPIO_mode(GPIO8_MMCCS0_MD); #endif +#ifdef CONFIG_CPU_MONAHANS /* pxa3xx */ + CKENA |= CKENA_12_MMC0 | CKENA_13_MMC1; +#else /* pxa2xx */ CKEN |= CKEN12_MMC; /* enable MMC unit clock */ - +#endif MMC_CLKRT = MMC_CLKRT_0_3125MHZ; MMC_RESTO = MMC_RES_TO_MAX; MMC_SPI = MMC_SPI_DISABLE; @@ -584,11 +587,7 @@ mmc_legacy_init(int verbose) debug("Detected SD card\n"); break; } -#ifdef CONFIG_PXA27X - udelay(10000); -#else udelay(200000); -#endif } if (retries <= 0 || !(IF_TYPE_SD == mmc_dev.if_type)) { @@ -598,11 +597,7 @@ mmc_legacy_init(int verbose) retries = 10; while (retries-- && resp && !(resp[0] & 0x80000000)) { -#ifdef CONFIG_PXA27X - udelay(10000); -#else udelay(200000); -#endif resp = mmc_cmd(MMC_CMD_SEND_OP_COND, 0x00ff, 0x8000, MMC_CMDAT_R3); @@ -632,7 +627,7 @@ mmc_legacy_init(int verbose) MMC_CLKRT = 0; /* 20 MHz */ resp = mmc_cmd(MMC_CMD_SELECT_CARD, rca, 0, MMC_CMDAT_R1); -#ifdef CONFIG_PXA27X +#if defined(CONFIG_PXA27X) || defined(CONFIG_CPU_MONAHANS) if (IF_TYPE_SD == mmc_dev.if_type) { resp = mmc_cmd(MMC_CMD_APP_CMD, rca, 0, MMC_CMDAT_R1); resp = mmc_cmd(SD_CMD_APP_SET_BUS_WIDTH, 0, 2, MMC_CMDAT_R1); diff --git a/drivers/mtd/nand/bfin_nand.c b/drivers/mtd/nand/bfin_nand.c index f134ef1..6d3d450 100644 --- a/drivers/mtd/nand/bfin_nand.c +++ b/drivers/mtd/nand/bfin_nand.c @@ -75,7 +75,7 @@ static void bfin_nfc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) int bfin_nfc_devready(struct mtd_info *mtd) { pr_stamp(); - return (bfin_read_NFC_STAT() & NBUSY ? 1 : 0); + return (bfin_read_NFC_STAT() & NBUSY) ? 1 : 0; } /* @@ -132,6 +132,11 @@ static void bfin_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len bfin_write_NFC_DATA_WR(buf[i]); } + + /* Wait for the buffer to drain before we return */ + while (!(bfin_read_NFC_STAT() & WB_EMPTY)) + if (ctrlc()) + return; } /* diff --git a/drivers/mtd/spi/atmel.c b/drivers/mtd/spi/atmel.c index 8306c00..8d02169 100644 --- a/drivers/mtd/spi/atmel.c +++ b/drivers/mtd/spi/atmel.c @@ -467,7 +467,7 @@ out: struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode) { const struct atmel_spi_flash_params *params; - unsigned long page_size; + unsigned page_size; unsigned int family; struct atmel_spi_flash *asf; unsigned int i; @@ -540,8 +540,9 @@ struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode) * params->blocks_per_sector * params->nr_sectors; - debug("SF: Detected %s with page size %lu, total %u bytes\n", - params->name, page_size, asf->flash.size); + printf("SF: Detected %s with page size %u, total ", + params->name, page_size); + print_size(asf->flash.size, "\n"); return &asf->flash; diff --git a/drivers/mtd/spi/macronix.c b/drivers/mtd/spi/macronix.c index fe1310b..76d5284 100644 --- a/drivers/mtd/spi/macronix.c +++ b/drivers/mtd/spi/macronix.c @@ -330,8 +330,9 @@ struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode) mcx->flash.size = params->page_size * params->pages_per_sector * params->sectors_per_block * params->nr_blocks; - printf("SF: Detected %s with page size %u, total %u bytes\n", - params->name, params->page_size, mcx->flash.size); + printf("SF: Detected %s with page size %u, total ", + params->name, params->page_size); + print_size(mcx->flash.size, "\n"); return &mcx->flash; } diff --git a/drivers/mtd/spi/spansion.c b/drivers/mtd/spi/spansion.c index fdb7917..d6c1a5f 100644 --- a/drivers/mtd/spi/spansion.c +++ b/drivers/mtd/spi/spansion.c @@ -343,8 +343,9 @@ struct spi_flash *spi_flash_probe_spansion(struct spi_slave *spi, u8 *idcode) spsn->flash.size = params->page_size * params->pages_per_sector * params->nr_sectors; - debug("SF: Detected %s with page size %u, total %u bytes\n", - params->name, params->page_size, spsn->flash.size); + printf("SF: Detected %s with page size %u, total ", + params->name, params->page_size); + print_size(spsn->flash.size, "\n"); return &spsn->flash; } diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c index 612f819..ea875dc 100644 --- a/drivers/mtd/spi/spi_flash.c +++ b/drivers/mtd/spi/spi_flash.c @@ -106,7 +106,7 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, spi = spi_setup_slave(bus, cs, max_hz, spi_mode); if (!spi) { - debug("SF: Failed to set up slave\n"); + printf("SF: Failed to set up slave\n"); return NULL; } @@ -147,6 +147,7 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, #endif #ifdef CONFIG_SPI_FLASH_STMICRO case 0x20: + case 0xff: /* Let the stmicro func handle non-JEDEC ids */ flash = spi_flash_probe_stmicro(spi, idcode); break; #endif @@ -156,7 +157,7 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, break; #endif default: - debug("SF: Unsupported manufacturer %02X\n", idcode[0]); + printf("SF: Unsupported manufacturer %02X\n", idcode[0]); flash = NULL; break; } diff --git a/drivers/mtd/spi/sst.c b/drivers/mtd/spi/sst.c index 50e9299..2557891 100644 --- a/drivers/mtd/spi/sst.c +++ b/drivers/mtd/spi/sst.c @@ -364,8 +364,9 @@ spi_flash_probe_sst(struct spi_slave *spi, u8 *idcode) stm->flash.read = sst_read_fast; stm->flash.size = SST_SECTOR_SIZE * params->nr_sectors; - debug("SF: Detected %s with page size %u, total %u bytes\n", - params->name, SST_SECTOR_SIZE, stm->flash.size); + printf("SF: Detected %s with page size %u, total ", + params->name, SST_SECTOR_SIZE); + print_size(stm->flash.size, "\n"); /* Flash powers up read-only, so clear BP# bits */ sst_unlock(&stm->flash); diff --git a/drivers/mtd/spi/stmicro.c b/drivers/mtd/spi/stmicro.c index ae0d047..3134027 100644 --- a/drivers/mtd/spi/stmicro.c +++ b/drivers/mtd/spi/stmicro.c @@ -46,6 +46,7 @@ #define CMD_M25PXX_DP 0xb9 /* Deep Power-down */ #define CMD_M25PXX_RES 0xab /* Release from DP, and Read Signature */ +#define STM_ID_M25P10 0x11 #define STM_ID_M25P16 0x15 #define STM_ID_M25P20 0x12 #define STM_ID_M25P32 0x16 @@ -78,6 +79,13 @@ static inline struct stmicro_spi_flash *to_stmicro_spi_flash(struct spi_flash static const struct stmicro_spi_flash_params stmicro_spi_flash_table[] = { { + .idcode1 = STM_ID_M25P10, + .page_size = 256, + .pages_per_sector = 128, + .nr_sectors = 4, + .name = "M25P10", + }, + { .idcode1 = STM_ID_M25P16, .page_size = 256, .pages_per_sector = 256, @@ -316,6 +324,19 @@ struct spi_flash *spi_flash_probe_stmicro(struct spi_slave *spi, u8 * idcode) struct stmicro_spi_flash *stm; unsigned int i; + if (idcode[0] == 0xff) { + i = spi_flash_cmd(spi, CMD_M25PXX_RES, + idcode, 4); + if (i) + return NULL; + if ((idcode[3] & 0xf0) == 0x10) { + idcode[0] = 0x20; + idcode[1] = 0x20; + idcode[2] = idcode[3] + 1; + } else + return NULL; + } + for (i = 0; i < ARRAY_SIZE(stmicro_spi_flash_table); i++) { params = &stmicro_spi_flash_table[i]; if (params->idcode1 == idcode[2]) { @@ -344,8 +365,9 @@ struct spi_flash *spi_flash_probe_stmicro(struct spi_slave *spi, u8 * idcode) stm->flash.size = params->page_size * params->pages_per_sector * params->nr_sectors; - debug("SF: Detected %s with page size %u, total %u bytes\n", - params->name, params->page_size, stm->flash.size); + printf("SF: Detected %s with page size %u, total ", + params->name, params->page_size); + print_size(stm->flash.size, "\n"); return &stm->flash; } diff --git a/drivers/mtd/spi/winbond.c b/drivers/mtd/spi/winbond.c index b8da923..ff1df25 100644 --- a/drivers/mtd/spi/winbond.c +++ b/drivers/mtd/spi/winbond.c @@ -289,7 +289,7 @@ out: struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode) { const struct winbond_spi_flash_params *params; - unsigned long page_size; + unsigned page_size; struct winbond_spi_flash *stm; unsigned int i; @@ -325,8 +325,9 @@ struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode) * params->sectors_per_block * params->nr_blocks; - debug("SF: Detected %s with page size %u, total %u bytes\n", - params->name, page_size, stm->flash.size); + printf("SF: Detected %s with page size %u, total ", + params->name, page_size); + print_size(stm->flash.size, "\n"); return &stm->flash; } diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index 9264ac6..f679f06 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -520,6 +520,7 @@ static int init_volumes(struct ubi_device *ubi, const struct ubi_scan_info *si, vol->reserved_pebs = be32_to_cpu(vtbl[i].reserved_pebs); vol->alignment = be32_to_cpu(vtbl[i].alignment); vol->data_pad = be32_to_cpu(vtbl[i].data_pad); + vol->upd_marker = vtbl[i].upd_marker; vol->vol_type = vtbl[i].vol_type == UBI_VID_DYNAMIC ? UBI_DYNAMIC_VOLUME : UBI_STATIC_VOLUME; vol->name_len = be16_to_cpu(vtbl[i].name_len); diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c index 3e4c3bd..5fa6f61 100644 --- a/drivers/net/tsec.c +++ b/drivers/net/tsec.c @@ -281,12 +281,16 @@ static uint tsec_local_mdio_read(volatile tsec_mdio_t *phyregs, | TBIANA_FULL_DUPLEX \ ) -/* Force the TBI PHY into 1000Mbps full duplex when in SGMII mode */ +/* By default force the TBI PHY into 1000Mbps full duplex when in SGMII mode */ +#ifndef CONFIG_TSEC_TBICR_SETTINGS #define TBICR_SETTINGS ( \ TBICR_PHY_RESET \ | TBICR_FULL_DUPLEX \ | TBICR_SPEED1_SET \ ) +#else +#define TBICR_SETTINGS CONFIG_TSEC_TBICR_SETTINGS +#endif /* CONFIG_TSEC_TBICR_SETTINGS */ /* Configure the TBI for SGMII operation */ static void tsec_configure_serdes(struct tsec_private *priv) diff --git a/drivers/qe/qe.c b/drivers/qe/qe.c index 8882c4f..63cc68e 100644 --- a/drivers/qe/qe.c +++ b/drivers/qe/qe.c @@ -436,7 +436,7 @@ struct qe_firmware_info *qe_get_firmware_info(void) return qe_firmware_uploaded ? &qe_firmware_info : NULL; } -static int qe_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +static int qe_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { ulong addr; diff --git a/drivers/rtc/mc146818.c b/drivers/rtc/mc146818.c index d68b438..ac4eb6a 100644 --- a/drivers/rtc/mc146818.c +++ b/drivers/rtc/mc146818.c @@ -67,9 +67,6 @@ int rtc_get (struct rtc_time *tmp) wday = rtc_read (RTC_DAY_OF_WEEK); mon = rtc_read (RTC_MONTH); year = rtc_read (RTC_YEAR); -#ifdef CONFIG_AMIGAONEG3SE - wday -= 1; /* VIA 686 stores Sunday = 1, Monday = 2, ... */ -#endif #ifdef RTC_DEBUG printf ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x " "hr: %02x min: %02x sec: %02x\n", @@ -114,11 +111,7 @@ int rtc_set (struct rtc_time *tmp) rtc_write (RTC_YEAR, bin2bcd(tmp->tm_year % 100)); rtc_write (RTC_MONTH, bin2bcd(tmp->tm_mon)); -#ifdef CONFIG_AMIGAONEG3SE - rtc_write (RTC_DAY_OF_WEEK, bin2bcd(tmp->tm_wday)+1); -#else rtc_write (RTC_DAY_OF_WEEK, bin2bcd(tmp->tm_wday)); -#endif rtc_write (RTC_DATE_OF_MONTH, bin2bcd(tmp->tm_mday)); rtc_write (RTC_HOURS, bin2bcd(tmp->tm_hour)); rtc_write (RTC_MINUTES, bin2bcd(tmp->tm_min )); diff --git a/drivers/rtc/mk48t59.c b/drivers/rtc/mk48t59.c index b176882..e285823 100644 --- a/drivers/rtc/mk48t59.c +++ b/drivers/rtc/mk48t59.c @@ -63,24 +63,6 @@ static void rtc_write (short reg, uchar val) out8(RTC(reg),val); } -#elif defined(CONFIG_AMIGAONEG3SE) - -#include "../board/MAI/AmigaOneG3SE/via686.h" -#include "../board/MAI/AmigaOneG3SE/memio.h" - - -static uchar rtc_read (short reg) -{ - out_byte(CMOS_ADDR, (uint8)reg); - return in_byte(CMOS_DATA); -} - -static void rtc_write (short reg, uchar val) -{ - out_byte(CMOS_ADDR, (uint8)reg); - out_byte(CMOS_DATA, (uint8)val); -} - #elif defined(CONFIG_EVAL5200) static uchar rtc_read (short reg) diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c index 8eda95c..1073ac0 100644 --- a/drivers/serial/serial.c +++ b/drivers/serial/serial.c @@ -30,6 +30,9 @@ #ifdef CONFIG_KIRKWOOD #include <asm/arch/kirkwood.h> #endif +#ifdef CONFIG_ORION5X +#include <asm/arch/orion5x.h> +#endif #if defined (CONFIG_SERIAL_MULTI) #include <serial.h> diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index f112ed0..dfcbb8b 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -25,6 +25,7 @@ include $(TOPDIR)/config.mk LIB := $(obj)libspi.a +COBJS-$(CONFIG_ALTERA_SPI) += altera_spi.o COBJS-$(CONFIG_ATMEL_DATAFLASH_SPI) += atmel_dataflash_spi.o COBJS-$(CONFIG_ATMEL_SPI) += atmel_spi.o COBJS-$(CONFIG_BFIN_SPI) += bfin_spi.o diff --git a/drivers/spi/altera_spi.c b/drivers/spi/altera_spi.c new file mode 100644 index 0000000..918b223 --- /dev/null +++ b/drivers/spi/altera_spi.c @@ -0,0 +1,165 @@ +/* + * Altera SPI driver + * + * based on bfin_spi.c + * Copyright (c) 2005-2008 Analog Devices Inc. + * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw> + * + * Licensed under the GPL-2 or later. + */ +#include <common.h> +#include <asm/io.h> +#include <malloc.h> +#include <spi.h> + +#define ALTERA_SPI_RXDATA 0 +#define ALTERA_SPI_TXDATA 4 +#define ALTERA_SPI_STATUS 8 +#define ALTERA_SPI_CONTROL 12 +#define ALTERA_SPI_SLAVE_SEL 20 + +#define ALTERA_SPI_STATUS_ROE_MSK (0x8) +#define ALTERA_SPI_STATUS_TOE_MSK (0x10) +#define ALTERA_SPI_STATUS_TMT_MSK (0x20) +#define ALTERA_SPI_STATUS_TRDY_MSK (0x40) +#define ALTERA_SPI_STATUS_RRDY_MSK (0x80) +#define ALTERA_SPI_STATUS_E_MSK (0x100) + +#define ALTERA_SPI_CONTROL_IROE_MSK (0x8) +#define ALTERA_SPI_CONTROL_ITOE_MSK (0x10) +#define ALTERA_SPI_CONTROL_ITRDY_MSK (0x40) +#define ALTERA_SPI_CONTROL_IRRDY_MSK (0x80) +#define ALTERA_SPI_CONTROL_IE_MSK (0x100) +#define ALTERA_SPI_CONTROL_SSO_MSK (0x400) + +#ifndef CONFIG_SYS_ALTERA_SPI_LIST +#define CONFIG_SYS_ALTERA_SPI_LIST { CONFIG_SYS_SPI_BASE } +#endif + +static ulong altera_spi_base_list[] = CONFIG_SYS_ALTERA_SPI_LIST; + +struct altera_spi_slave { + struct spi_slave slave; + ulong base; +}; +#define to_altera_spi_slave(s) container_of(s, struct altera_spi_slave, slave) + +__attribute__((weak)) +int spi_cs_is_valid(unsigned int bus, unsigned int cs) +{ + return bus < ARRAY_SIZE(altera_spi_base_list) && cs < 32; +} + +__attribute__((weak)) +void spi_cs_activate(struct spi_slave *slave) +{ + struct altera_spi_slave *altspi = to_altera_spi_slave(slave); + writel(1 << slave->cs, altspi->base + ALTERA_SPI_SLAVE_SEL); + writel(ALTERA_SPI_CONTROL_SSO_MSK, altspi->base + ALTERA_SPI_CONTROL); +} + +__attribute__((weak)) +void spi_cs_deactivate(struct spi_slave *slave) +{ + struct altera_spi_slave *altspi = to_altera_spi_slave(slave); + writel(0, altspi->base + ALTERA_SPI_CONTROL); + writel(0, altspi->base + ALTERA_SPI_SLAVE_SEL); +} + +void spi_init(void) +{ +} + +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int mode) +{ + struct altera_spi_slave *altspi; + + if (!spi_cs_is_valid(bus, cs)) + return NULL; + + altspi = malloc(sizeof(*altspi)); + if (!altspi) + return NULL; + + altspi->slave.bus = bus; + altspi->slave.cs = cs; + altspi->base = altera_spi_base_list[bus]; + debug("%s: bus:%i cs:%i base:%lx\n", __func__, + bus, cs, altspi->base); + + return &altspi->slave; +} + +void spi_free_slave(struct spi_slave *slave) +{ + struct altera_spi_slave *altspi = to_altera_spi_slave(slave); + free(altspi); +} + +int spi_claim_bus(struct spi_slave *slave) +{ + struct altera_spi_slave *altspi = to_altera_spi_slave(slave); + + debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs); + writel(0, altspi->base + ALTERA_SPI_CONTROL); + writel(0, altspi->base + ALTERA_SPI_SLAVE_SEL); + return 0; +} + +void spi_release_bus(struct spi_slave *slave) +{ + struct altera_spi_slave *altspi = to_altera_spi_slave(slave); + + debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs); + writel(0, altspi->base + ALTERA_SPI_SLAVE_SEL); +} + +#ifndef CONFIG_ALTERA_SPI_IDLE_VAL +# define CONFIG_ALTERA_SPI_IDLE_VAL 0xff +#endif + +int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, + void *din, unsigned long flags) +{ + struct altera_spi_slave *altspi = to_altera_spi_slave(slave); + /* assume spi core configured to do 8 bit transfers */ + uint bytes = bitlen / 8; + const uchar *txp = dout; + uchar *rxp = din; + + debug("%s: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n", __func__, + slave->bus, slave->cs, bitlen, bytes, flags); + if (bitlen == 0) + goto done; + + if (bitlen % 8) { + flags |= SPI_XFER_END; + goto done; + } + + /* empty read buffer */ + if (readl(altspi->base + ALTERA_SPI_STATUS) & + ALTERA_SPI_STATUS_RRDY_MSK) + readl(altspi->base + ALTERA_SPI_RXDATA); + if (flags & SPI_XFER_BEGIN) + spi_cs_activate(slave); + + while (bytes--) { + uchar d = txp ? *txp++ : CONFIG_ALTERA_SPI_IDLE_VAL; + debug("%s: tx:%x ", __func__, d); + writel(d, altspi->base + ALTERA_SPI_TXDATA); + while (!(readl(altspi->base + ALTERA_SPI_STATUS) & + ALTERA_SPI_STATUS_RRDY_MSK)) + ; + d = readl(altspi->base + ALTERA_SPI_RXDATA); + if (rxp) + *rxp++ = d; + debug("rx:%x\n", d); + } + done: + if (flags & SPI_XFER_END) + spi_cs_deactivate(slave); + + return 0; +} diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c index 08f837b..4518ecb 100644 --- a/drivers/spi/davinci_spi.c +++ b/drivers/spi/davinci_spi.c @@ -66,7 +66,7 @@ void spi_free_slave(struct spi_slave *slave) int spi_claim_bus(struct spi_slave *slave) { struct davinci_spi_slave *ds = to_davinci_spi(slave); - unsigned int scalar, data1_reg_val = 0; + unsigned int scalar; /* Enable the SPI hardware */ writel(SPIGCR0_SPIRST_MASK, &ds->regs->gcr0); @@ -93,11 +93,6 @@ int spi_claim_bus(struct spi_slave *slave) writel(8 | (scalar << SPIFMT_PRESCALE_SHIFT) | (1 << SPIFMT_PHASE_SHIFT), &ds->regs->fmt0); - /* hold cs active at end of transfer until explicitly de-asserted */ - data1_reg_val = (1 << SPIDAT1_CSHOLD_SHIFT) | - (slave->cs << SPIDAT1_CSNR_SHIFT); - writel(data1_reg_val, &ds->regs->dat1); - /* * Including a minor delay. No science here. Should be good even with * no delay @@ -113,8 +108,7 @@ int spi_claim_bus(struct spi_slave *slave) writel(0, &ds->regs->lvl); /* enable SPI */ - writel((readl(&ds->regs->gcr1) | - SPIGCR1_SPIENA_MASK), &ds->regs->gcr1); + writel((readl(&ds->regs->gcr1) | SPIGCR1_SPIENA_MASK), &ds->regs->gcr1); return 0; } @@ -127,14 +121,125 @@ void spi_release_bus(struct spi_slave *slave) writel(SPIGCR0_SPIRST_MASK, &ds->regs->gcr0); } +/* + * This functions needs to act like a macro to avoid pipeline reloads in the + * loops below. Use always_inline. This gains us about 160KiB/s and the bloat + * appears to be zero bytes (da830). + */ +__attribute__((always_inline)) +static inline u32 davinci_spi_xfer_data(struct davinci_spi_slave *ds, u32 data) +{ + u32 buf_reg_val; + + /* send out data */ + writel(data, &ds->regs->dat1); + + /* wait for the data to clock in/out */ + while ((buf_reg_val = readl(&ds->regs->buf)) & SPIBUF_RXEMPTY_MASK) + ; + + return buf_reg_val; +} + +static int davinci_spi_read(struct spi_slave *slave, unsigned int len, + u8 *rxp, unsigned long flags) +{ + struct davinci_spi_slave *ds = to_davinci_spi(slave); + unsigned int data1_reg_val; + + /* enable CS hold, CS[n] and clear the data bits */ + data1_reg_val = ((1 << SPIDAT1_CSHOLD_SHIFT) | + (slave->cs << SPIDAT1_CSNR_SHIFT)); + + /* wait till TXFULL is deasserted */ + while (readl(&ds->regs->buf) & SPIBUF_TXFULL_MASK) + ; + + /* preload the TX buffer to avoid clock starvation */ + writel(data1_reg_val, &ds->regs->dat1); + + /* keep reading 1 byte until only 1 byte left */ + while ((len--) > 1) + *rxp++ = davinci_spi_xfer_data(ds, data1_reg_val); + + /* clear CS hold when we reach the end */ + if (flags & SPI_XFER_END) + data1_reg_val &= ~(1 << SPIDAT1_CSHOLD_SHIFT); + + /* read the last byte */ + *rxp = davinci_spi_xfer_data(ds, data1_reg_val); + + return 0; +} + +static int davinci_spi_write(struct spi_slave *slave, unsigned int len, + const u8 *txp, unsigned long flags) +{ + struct davinci_spi_slave *ds = to_davinci_spi(slave); + unsigned int data1_reg_val; + + /* enable CS hold and clear the data bits */ + data1_reg_val = ((1 << SPIDAT1_CSHOLD_SHIFT) | + (slave->cs << SPIDAT1_CSNR_SHIFT)); + + /* wait till TXFULL is deasserted */ + while (readl(&ds->regs->buf) & SPIBUF_TXFULL_MASK) + ; + + /* preload the TX buffer to avoid clock starvation */ + if (len > 2) { + writel(data1_reg_val | *txp++, &ds->regs->dat1); + len--; + } + + /* keep writing 1 byte until only 1 byte left */ + while ((len--) > 1) + davinci_spi_xfer_data(ds, data1_reg_val | *txp++); + + /* clear CS hold when we reach the end */ + if (flags & SPI_XFER_END) + data1_reg_val &= ~(1 << SPIDAT1_CSHOLD_SHIFT); + + /* write the last byte */ + davinci_spi_xfer_data(ds, data1_reg_val | *txp); + + return 0; +} + +#ifndef CONFIG_SPI_HALF_DUPLEX +static int davinci_spi_read_write(struct spi_slave *slave, unsigned int len, + u8 *rxp, const u8 *txp, unsigned long flags) +{ + struct davinci_spi_slave *ds = to_davinci_spi(slave); + unsigned int data1_reg_val; + + /* enable CS hold and clear the data bits */ + data1_reg_val = ((1 << SPIDAT1_CSHOLD_SHIFT) | + (slave->cs << SPIDAT1_CSNR_SHIFT)); + + /* wait till TXFULL is deasserted */ + while (readl(&ds->regs->buf) & SPIBUF_TXFULL_MASK) + ; + + /* keep reading and writing 1 byte until only 1 byte left */ + while ((len--) > 1) + *rxp++ = davinci_spi_xfer_data(ds, data1_reg_val | *txp++); + + /* clear CS hold when we reach the end */ + if (flags & SPI_XFER_END) + data1_reg_val &= ~(1 << SPIDAT1_CSHOLD_SHIFT); + + /* read and write the last byte */ + *rxp = davinci_spi_xfer_data(ds, data1_reg_val | *txp); + + return 0; +} +#endif + int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, void *din, unsigned long flags) { - struct davinci_spi_slave *ds = to_davinci_spi(slave); - unsigned int len, data1_reg_val = readl(&ds->regs->dat1); - unsigned int i_cnt = 0, o_cnt = 0, buf_reg_val; - const u8 *txp = dout; /* dout can be NULL for read operation */ - u8 *rxp = din; /* din can be NULL for write operation */ + unsigned int len; if (bitlen == 0) /* Finish any previously submitted transfers */ @@ -154,63 +259,19 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, len = bitlen / 8; - /* do an empty read to clear the current contents */ - readl(&ds->regs->buf); - - /* keep writing and reading 1 byte until done */ - while ((i_cnt < len) || (o_cnt < len)) { - /* read RX buffer and flags */ - buf_reg_val = readl(&ds->regs->buf); - - /* if data is available */ - if ((i_cnt < len) && - (buf_reg_val & SPIBUF_RXEMPTY_MASK) == 0) { - /* - * If there is no read buffer simply - * ignore the read character - */ - if (rxp) - *rxp++ = buf_reg_val & 0xFF; - /* increment read words count */ - i_cnt++; - } - - /* - * if the tx buffer is empty and there - * is still data to transmit - */ - if ((o_cnt < len) && - ((buf_reg_val & SPIBUF_TXFULL_MASK) == 0)) { - /* write the data */ - data1_reg_val &= ~0xFFFF; - if (txp) - data1_reg_val |= *txp++; - /* - * Write to DAT1 is required to keep - * the serial transfer going. - * We just terminate when we reach the end. - */ - if ((o_cnt == (len - 1)) && (flags & SPI_XFER_END)) { - /* clear CS hold */ - writel(data1_reg_val & - ~(1 << SPIDAT1_CSHOLD_SHIFT), - &ds->regs->dat1); - } else { - /* enable CS hold and write TX register */ - data1_reg_val |= ((1 << SPIDAT1_CSHOLD_SHIFT) | - (slave->cs << SPIDAT1_CSNR_SHIFT)); - writel(data1_reg_val, &ds->regs->dat1); - } - /* increment written words count */ - o_cnt++; - } - } - return 0; + if (!dout) + return davinci_spi_read(slave, len, din, flags); + else if (!din) + return davinci_spi_write(slave, len, dout, flags); +#ifndef CONFIG_SPI_HALF_DUPLEX + else + return davinci_spi_read_write(slave, len, din, dout, flags); +#endif out: if (flags & SPI_XFER_END) { - writel(data1_reg_val & - ~(1 << SPIDAT1_CSHOLD_SHIFT), &ds->regs->dat1); + u8 dummy = 0; + davinci_spi_write(slave, 1, &dummy, flags); } return 0; } diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 7784d92..37d056e 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -275,7 +275,7 @@ static void *ehci_alloc(size_t sz, size_t align) return NULL; } - memset(p, sz, 0); + memset(p, 0, sz); return p; } @@ -350,7 +350,6 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, (dev->parent->devnum << 16) | (0 << 8) | (0 << 0); qh->qh_endpt2 = cpu_to_hc32(endpt); qh->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE); - qh->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE); td = NULL; tdp = &qh->qh_overlay.qt_next; diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index b2e03bc..64fde68 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -41,6 +41,15 @@ int usb_cpu_init(void) writel(get_pllb_init(), &pmc->pllbr); while ((readl(&pmc->sr) & AT91_PMC_LOCKB) != AT91_PMC_LOCKB) ; +#elif defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) + /* Enable UPLL */ + writel(readl(&pmc->uckr) | AT91_PMC_UPLLEN | AT91_PMC_BIASEN, + &pmc->uckr); + while ((readl(&pmc->sr) & AT91_PMC_LOCKU) != AT91_PMC_LOCKU) + ; + + /* Select PLLA as input clock of OHCI */ + writel(AT91_PMC_USBS_USB_UPLL | AT91_PMC_USBDIV_10, &pmc->usb); #endif /* Enable USB host clock. */ @@ -72,6 +81,11 @@ int usb_cpu_stop(void) writel(0, &pmc->pllbr); while ((readl(&pmc->sr) & AT91_PMC_LOCKB) != 0) ; +#elif defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) + /* Disable UPLL */ + writel(readl(&pmc->uckr) & (~AT91_PMC_UPLLEN), &pmc->uckr); + while ((readl(&pmc->sr) & AT91_PMC_LOCKU) == AT91_PMC_LOCKU) + ; #endif return 0; diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index b03a600..3f76c4e 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -83,17 +83,6 @@ #define OHCI_CONTROL_INIT \ (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE -/* - * e.g. PCI controllers need this - */ -#ifdef CONFIG_SYS_OHCI_SWAP_REG_ACCESS -# define readl(a) __swap_32(*((volatile u32 *)(a))) -# define writel(a, b) (*((volatile u32 *)(b)) = __swap_32((volatile u32)a)) -#else -# define readl(a) (*((volatile u32 *)(a))) -# define writel(a, b) (*((volatile u32 *)(b)) = ((volatile u32)a)) -#endif /* CONFIG_SYS_OHCI_SWAP_REG_ACCESS */ - #define min_t(type, x, y) \ ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) @@ -147,13 +136,13 @@ struct ohci_device ohci_dev; struct usb_device *devgone; static inline u32 roothub_a(struct ohci *hc) - { return readl(&hc->regs->roothub.a); } + { return ohci_readl(&hc->regs->roothub.a); } static inline u32 roothub_b(struct ohci *hc) - { return readl(&hc->regs->roothub.b); } + { return ohci_readl(&hc->regs->roothub.b); } static inline u32 roothub_status(struct ohci *hc) - { return readl(&hc->regs->roothub.status); } + { return ohci_readl(&hc->regs->roothub.status); } static inline u32 roothub_portstatus(struct ohci *hc, int i) - { return readl(&hc->regs->roothub.portstatus[i]); } + { return ohci_readl(&hc->regs->roothub.portstatus[i]); } /* forward declaration */ static int hc_interrupt(void); @@ -302,11 +291,11 @@ static void ohci_dump_status(ohci_t *controller) struct ohci_regs *regs = controller->regs; __u32 temp; - temp = readl(®s->revision) & 0xff; + temp = ohci_readl(®s->revision) & 0xff; if (temp != 0x10) dbg("spec %d.%d", (temp >> 4), (temp & 0x0f)); - temp = readl(®s->control); + temp = ohci_readl(®s->control); dbg("control: 0x%08x%s%s%s HCFS=%s%s%s%s%s CBSR=%d", temp, (temp & OHCI_CTRL_RWE) ? " RWE" : "", (temp & OHCI_CTRL_RWC) ? " RWC" : "", @@ -319,7 +308,7 @@ static void ohci_dump_status(ohci_t *controller) temp & OHCI_CTRL_CBSR ); - temp = readl(®s->cmdstatus); + temp = ohci_readl(®s->cmdstatus); dbg("cmdstatus: 0x%08x SOC=%d%s%s%s%s", temp, (temp & OHCI_SOC) >> 16, (temp & OHCI_OCR) ? " OCR" : "", @@ -328,18 +317,20 @@ static void ohci_dump_status(ohci_t *controller) (temp & OHCI_HCR) ? " HCR" : "" ); - ohci_dump_intr_mask("intrstatus", readl(®s->intrstatus)); - ohci_dump_intr_mask("intrenable", readl(®s->intrenable)); + ohci_dump_intr_mask("intrstatus", ohci_readl(®s->intrstatus)); + ohci_dump_intr_mask("intrenable", ohci_readl(®s->intrenable)); - maybe_print_eds("ed_periodcurrent", readl(®s->ed_periodcurrent)); + maybe_print_eds("ed_periodcurrent", + ohci_readl(®s->ed_periodcurrent)); - maybe_print_eds("ed_controlhead", readl(®s->ed_controlhead)); - maybe_print_eds("ed_controlcurrent", readl(®s->ed_controlcurrent)); + maybe_print_eds("ed_controlhead", ohci_readl(®s->ed_controlhead)); + maybe_print_eds("ed_controlcurrent", + ohci_readl(®s->ed_controlcurrent)); - maybe_print_eds("ed_bulkhead", readl(®s->ed_bulkhead)); - maybe_print_eds("ed_bulkcurrent", readl(®s->ed_bulkcurrent)); + maybe_print_eds("ed_bulkhead", ohci_readl(®s->ed_bulkhead)); + maybe_print_eds("ed_bulkcurrent", ohci_readl(®s->ed_bulkcurrent)); - maybe_print_eds("donehead", readl(®s->donehead)); + maybe_print_eds("donehead", ohci_readl(®s->donehead)); } static void ohci_dump_roothub(ohci_t *controller, int verbose) @@ -518,11 +509,11 @@ static inline int sohci_return_job(struct ohci *hc, urb_priv_t *urb) /* implicitly requeued */ if (urb->dev->irq_handle && (urb->dev->irq_act_len = urb->actual_length)) { - writel(OHCI_INTR_WDH, ®s->intrenable); - readl(®s->intrenable); /* PCI posting flush */ + ohci_writel(OHCI_INTR_WDH, ®s->intrenable); + ohci_readl(®s->intrenable); /* PCI posting flush */ urb->dev->irq_handle(urb->dev); - writel(OHCI_INTR_WDH, ®s->intrdisable); - readl(®s->intrdisable); /* PCI posting flush */ + ohci_writel(OHCI_INTR_WDH, ®s->intrdisable); + ohci_readl(®s->intrdisable); /* PCI posting flush */ } urb->actual_length = 0; td_submit_job( @@ -631,7 +622,7 @@ static int ep_link(ohci_t *ohci, ed_t *edi) case PIPE_CONTROL: ed->hwNextED = 0; if (ohci->ed_controltail == NULL) - writel(ed, &ohci->regs->ed_controlhead); + ohci_writel(ed, &ohci->regs->ed_controlhead); else ohci->ed_controltail->hwNextED = m32_swap((unsigned long)ed); @@ -640,7 +631,7 @@ static int ep_link(ohci_t *ohci, ed_t *edi) if (!ohci->ed_controltail && !ohci->ed_rm_list[0] && !ohci->ed_rm_list[1] && !ohci->sleeping) { ohci->hc_control |= OHCI_CTRL_CLE; - writel(ohci->hc_control, &ohci->regs->control); + ohci_writel(ohci->hc_control, &ohci->regs->control); } ohci->ed_controltail = edi; break; @@ -648,7 +639,7 @@ static int ep_link(ohci_t *ohci, ed_t *edi) case PIPE_BULK: ed->hwNextED = 0; if (ohci->ed_bulktail == NULL) - writel(ed, &ohci->regs->ed_bulkhead); + ohci_writel(ed, &ohci->regs->ed_bulkhead); else ohci->ed_bulktail->hwNextED = m32_swap((unsigned long)ed); @@ -657,7 +648,7 @@ static int ep_link(ohci_t *ohci, ed_t *edi) if (!ohci->ed_bulktail && !ohci->ed_rm_list[0] && !ohci->ed_rm_list[1] && !ohci->sleeping) { ohci->hc_control |= OHCI_CTRL_BLE; - writel(ohci->hc_control, &ohci->regs->control); + ohci_writel(ohci->hc_control, &ohci->regs->control); } ohci->ed_bulktail = edi; break; @@ -725,9 +716,10 @@ static int ep_unlink(ohci_t *ohci, ed_t *edi) if (ed->ed_prev == NULL) { if (!ed->hwNextED) { ohci->hc_control &= ~OHCI_CTRL_CLE; - writel(ohci->hc_control, &ohci->regs->control); + ohci_writel(ohci->hc_control, + &ohci->regs->control); } - writel(m32_swap(*((__u32 *)&ed->hwNextED)), + ohci_writel(m32_swap(*((__u32 *)&ed->hwNextED)), &ohci->regs->ed_controlhead); } else { ed->ed_prev->hwNextED = ed->hwNextED; @@ -744,9 +736,10 @@ static int ep_unlink(ohci_t *ohci, ed_t *edi) if (ed->ed_prev == NULL) { if (!ed->hwNextED) { ohci->hc_control &= ~OHCI_CTRL_BLE; - writel(ohci->hc_control, &ohci->regs->control); + ohci_writel(ohci->hc_control, + &ohci->regs->control); } - writel(m32_swap(*((__u32 *)&ed->hwNextED)), + ohci_writel(m32_swap(*((__u32 *)&ed->hwNextED)), &ohci->regs->ed_bulkhead); } else { ed->ed_prev->hwNextED = ed->hwNextED; @@ -923,7 +916,7 @@ static void td_submit_job(struct usb_device *dev, unsigned long pipe, if (!ohci->sleeping) { /* start bulk list */ - writel(OHCI_BLF, &ohci->regs->cmdstatus); + ohci_writel(OHCI_BLF, &ohci->regs->cmdstatus); } break; @@ -949,7 +942,7 @@ static void td_submit_job(struct usb_device *dev, unsigned long pipe, if (!ohci->sleeping) { /* start Control list */ - writel(OHCI_CLF, &ohci->regs->cmdstatus); + ohci_writel(OHCI_CLF, &ohci->regs->cmdstatus); } break; @@ -1224,13 +1217,13 @@ static unsigned char root_hub_str_index1[] = #define OK(x) len = (x); break #ifdef DEBUG -#define WR_RH_STAT(x) {info("WR:status %#8x", (x)); writel((x), \ +#define WR_RH_STAT(x) {info("WR:status %#8x", (x)); ohci_writel((x), \ &gohci.regs->roothub.status); } #define WR_RH_PORTSTAT(x) {info("WR:portstatus[%d] %#8x", wIndex-1, \ - (x)); writel((x), &gohci.regs->roothub.portstatus[wIndex-1]); } + (x)); ohci_writel((x), &gohci.regs->roothub.portstatus[wIndex-1]); } #else -#define WR_RH_STAT(x) writel((x), &gohci.regs->roothub.status) -#define WR_RH_PORTSTAT(x) writel((x), \ +#define WR_RH_STAT(x) ohci_writel((x), &gohci.regs->roothub.status) +#define WR_RH_PORTSTAT(x) ohci_writel((x), \ &gohci.regs->roothub.portstatus[wIndex-1]) #endif #define RD_RH_STAT roothub_status(&gohci) @@ -1661,10 +1654,10 @@ static int hc_reset(ohci_t *ohci) int timeout = 1000; pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &base); - writel(readl(base + EHCI_USBCMD_OFF) | EHCI_USBCMD_HCRESET, - base + EHCI_USBCMD_OFF); + base += EHCI_USBCMD_OFF; + ohci_writel(ohci_readl(base) | EHCI_USBCMD_HCRESET, base); - while (readl(base + EHCI_USBCMD_OFF) & EHCI_USBCMD_HCRESET) { + while (ohci_readl(base) & EHCI_USBCMD_HCRESET) { if (timeout-- <= 0) { printf("USB RootHub reset timed out!"); break; @@ -1674,11 +1667,11 @@ static int hc_reset(ohci_t *ohci) } else printf("No EHCI func at %d index!\n", CONFIG_PCI_EHCI_DEVNO); #endif - if (readl(&ohci->regs->control) & OHCI_CTRL_IR) { - /* SMM owns the HC */ - writel(OHCI_OCR, &ohci->regs->cmdstatus);/* request ownership */ + if (ohci_readl(&ohci->regs->control) & OHCI_CTRL_IR) { + /* SMM owns the HC, request ownership */ + ohci_writel(OHCI_OCR, &ohci->regs->cmdstatus); info("USB HC TakeOver from SMM"); - while (readl(&ohci->regs->control) & OHCI_CTRL_IR) { + while (ohci_readl(&ohci->regs->control) & OHCI_CTRL_IR) { wait_ms(10); if (--smm_timeout == 0) { err("USB HC TakeOver failed!"); @@ -1688,19 +1681,19 @@ static int hc_reset(ohci_t *ohci) } /* Disable HC interrupts */ - writel(OHCI_INTR_MIE, &ohci->regs->intrdisable); + ohci_writel(OHCI_INTR_MIE, &ohci->regs->intrdisable); dbg("USB HC reset_hc usb-%s: ctrl = 0x%X ;\n", ohci->slot_name, - readl(&ohci->regs->control)); + ohci_readl(&ohci->regs->control)); /* Reset USB (needed by some controllers) */ ohci->hc_control = 0; - writel(ohci->hc_control, &ohci->regs->control); + ohci_writel(ohci->hc_control, &ohci->regs->control); /* HC Reset requires max 10 us delay */ - writel(OHCI_HCR, &ohci->regs->cmdstatus); - while ((readl(&ohci->regs->cmdstatus) & OHCI_HCR) != 0) { + ohci_writel(OHCI_HCR, &ohci->regs->cmdstatus); + while ((ohci_readl(&ohci->regs->cmdstatus) & OHCI_HCR) != 0) { if (--timeout == 0) { err("USB HC reset timed out!"); return -1; @@ -1726,39 +1719,40 @@ static int hc_start(ohci_t *ohci) /* Tell the controller where the control and bulk lists are * The lists are empty now. */ - writel(0, &ohci->regs->ed_controlhead); - writel(0, &ohci->regs->ed_bulkhead); + ohci_writel(0, &ohci->regs->ed_controlhead); + ohci_writel(0, &ohci->regs->ed_bulkhead); - writel((__u32)ohci->hcca, &ohci->regs->hcca); /* a reset clears this */ + ohci_writel((__u32)ohci->hcca, + &ohci->regs->hcca); /* reset clears this */ fminterval = 0x2edf; - writel((fminterval * 9) / 10, &ohci->regs->periodicstart); + ohci_writel((fminterval * 9) / 10, &ohci->regs->periodicstart); fminterval |= ((((fminterval - 210) * 6) / 7) << 16); - writel(fminterval, &ohci->regs->fminterval); - writel(0x628, &ohci->regs->lsthresh); + ohci_writel(fminterval, &ohci->regs->fminterval); + ohci_writel(0x628, &ohci->regs->lsthresh); /* start controller operations */ ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER; ohci->disabled = 0; - writel(ohci->hc_control, &ohci->regs->control); + ohci_writel(ohci->hc_control, &ohci->regs->control); /* disable all interrupts */ mask = (OHCI_INTR_SO | OHCI_INTR_WDH | OHCI_INTR_SF | OHCI_INTR_RD | OHCI_INTR_UE | OHCI_INTR_FNO | OHCI_INTR_RHSC | OHCI_INTR_OC | OHCI_INTR_MIE); - writel(mask, &ohci->regs->intrdisable); + ohci_writel(mask, &ohci->regs->intrdisable); /* clear all interrupts */ mask &= ~OHCI_INTR_MIE; - writel(mask, &ohci->regs->intrstatus); + ohci_writel(mask, &ohci->regs->intrstatus); /* Choose the interrupts we care about now - but w/o MIE */ mask = OHCI_INTR_RHSC | OHCI_INTR_UE | OHCI_INTR_WDH | OHCI_INTR_SO; - writel(mask, &ohci->regs->intrenable); + ohci_writel(mask, &ohci->regs->intrenable); #ifdef OHCI_USE_NPS /* required for AMD-756 and some Mac platforms */ - writel((roothub_a(ohci) | RH_A_NPS) & ~RH_A_PSM, + ohci_writel((roothub_a(ohci) | RH_A_NPS) & ~RH_A_PSM, &ohci->regs->roothub.a); - writel(RH_HS_LPSC, &ohci->regs->roothub.status); + ohci_writel(RH_HS_LPSC, &ohci->regs->roothub.status); #endif /* OHCI_USE_NPS */ #define mdelay(n) ({unsigned long msec = (n); while (msec--) udelay(1000); }) @@ -1792,13 +1786,13 @@ static int hc_interrupt(void) !(m32_swap(ohci->hcca->done_head) & 0x01)) { ints = OHCI_INTR_WDH; } else { - ints = readl(®s->intrstatus); + ints = ohci_readl(®s->intrstatus); if (ints == ~(u32)0) { ohci->disabled++; err("%s device removed!", ohci->slot_name); return -1; } else { - ints &= readl(®s->intrenable); + ints &= ohci_readl(®s->intrenable); if (ints == 0) { dbg("hc_interrupt: returning..\n"); return 0xff; @@ -1833,16 +1827,16 @@ static int hc_interrupt(void) if (ints & OHCI_INTR_WDH) { wait_ms(1); - writel(OHCI_INTR_WDH, ®s->intrdisable); - (void)readl(®s->intrdisable); /* flush */ + ohci_writel(OHCI_INTR_WDH, ®s->intrdisable); + (void)ohci_readl(®s->intrdisable); /* flush */ stat = dl_done_list(&gohci); - writel(OHCI_INTR_WDH, ®s->intrenable); - (void)readl(®s->intrdisable); /* flush */ + ohci_writel(OHCI_INTR_WDH, ®s->intrenable); + (void)ohci_readl(®s->intrdisable); /* flush */ } if (ints & OHCI_INTR_SO) { dbg("USB Schedule overrun\n"); - writel(OHCI_INTR_SO, ®s->intrenable); + ohci_writel(OHCI_INTR_SO, ®s->intrenable); stat = -1; } @@ -1850,13 +1844,13 @@ static int hc_interrupt(void) if (ints & OHCI_INTR_SF) { unsigned int frame = m16_swap(ohci->hcca->frame_no) & 1; wait_ms(1); - writel(OHCI_INTR_SF, ®s->intrdisable); + ohci_writel(OHCI_INTR_SF, ®s->intrdisable); if (ohci->ed_rm_list[frame] != NULL) - writel(OHCI_INTR_SF, ®s->intrenable); + ohci_writel(OHCI_INTR_SF, ®s->intrenable); stat = 0xff; } - writel(ints, ®s->intrstatus); + ohci_writel(ints, ®s->intrstatus); return stat; } diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 79aa79d..d977e8f 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h @@ -7,6 +7,17 @@ * usb-ohci.h */ +/* + * e.g. PCI controllers need this + */ +#ifdef CONFIG_SYS_OHCI_SWAP_REG_ACCESS +# define ohci_readl(a) __swap_32(*((volatile u32 *)(a))) +# define ohci_writel(a, b) (*((volatile u32 *)(b)) = __swap_32((volatile u32)a)) +#else +# define ohci_readl(a) (*((volatile u32 *)(a))) +# define ohci_writel(a, b) (*((volatile u32 *)(b)) = ((volatile u32)a)) +#endif /* CONFIG_SYS_OHCI_SWAP_REG_ACCESS */ + /* functions for doing board or CPU specific setup/cleanup */ extern int usb_board_init(void); extern int usb_board_stop(void); @@ -196,8 +207,8 @@ struct ohci_hcca { /* * This is the structure of the OHCI controller's memory mapped I/O - * region. This is Memory Mapped I/O. You must use the readl() and - * writel() macros defined in asm/io.h to access these!! + * region. This is Memory Mapped I/O. You must use the ohci_readl() and + * ohci_writel() macros defined in this file to access these!! */ struct ohci_regs { /* control and status registers */ diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index 40bfe44..617d88e 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c @@ -27,9 +27,9 @@ /* MUSB platform configuration */ struct musb_config musb_cfg = { - (struct musb_regs *)DA8XX_USB_OTG_CORE_BASE, - DA8XX_USB_OTG_TIMEOUT, - 0 + .regs = (struct musb_regs *)DA8XX_USB_OTG_CORE_BASE, + .timeout = DA8XX_USB_OTG_TIMEOUT, + .musb_speed = 0, }; /* diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 8fbadc9..f56f2df 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -28,9 +28,9 @@ /* MUSB platform configuration */ struct musb_config musb_cfg = { - (struct musb_regs *)MENTOR_USB0_BASE, - DAVINCI_USB_TIMEOUT, - 0 + .regs = (struct musb_regs *)MENTOR_USB0_BASE, + .timeout = DAVINCI_USB_TIMEOUT, + .musb_speed = 0, }; /* MUSB module register overlay */ diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 7766069..dc740cf 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -34,6 +34,7 @@ void musb_start(void) { #if defined(CONFIG_MUSB_HCD) u8 devctl; + u8 busctl; #endif /* disable all interrupts */ @@ -45,6 +46,12 @@ void musb_start(void) /* put into basic highspeed mode and start session */ writeb(MUSB_POWER_HSENAB, &musbr->power); #if defined(CONFIG_MUSB_HCD) + /* Program PHY to use EXT VBUS if required */ + if (musb_cfg.extvbus == 1) { + busctl = musb_read_ulpi_buscontrol(musbr); + musb_write_ulpi_buscontrol(musbr, busctl | ULPI_USE_EXTVBUS); + } + devctl = readb(&musbr->devctl); writeb(devctl | MUSB_DEVCTL_SESSION, &musbr->devctl); #endif diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 9a1fb4f..4771876 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -112,7 +112,10 @@ struct musb_regs { u16 rxfifoadd; u32 vcontrol; u16 hwvers; - u16 reserved2[5]; + u16 reserved2a[1]; + u8 ulpi_busctl; + u8 reserved2b[1]; + u16 reserved2[3]; u8 epinfo; u8 raminfo; u8 linkinfo; @@ -181,6 +184,10 @@ struct musb_regs { #define MUSB_DEVCTL_HR 0x02 #define MUSB_DEVCTL_SESSION 0x01 +/* ULPI VBUSCONTROL */ +#define ULPI_USE_EXTVBUS 0x01 +#define ULPI_USE_EXTVBUSIND 0x02 + /* TESTMODE */ #define MUSB_TEST_FORCE_HOST 0x80 #define MUSB_TEST_FIFO_ACCESS 0x40 @@ -341,6 +348,7 @@ struct musb_config { struct musb_regs *regs; u32 timeout; u8 musb_speed; + u8 extvbus; }; /* externally defined data */ @@ -361,6 +369,26 @@ extern void read_fifo(u8 ep, u32 length, void *fifo_data); # define readb(addr) (u8)bfin_read16(addr) # undef writeb # define writeb(b, addr) bfin_write16(addr, b) +/* + * The USB PHY on current Blackfin processors is a UTMI+ level 2 PHY. + * However, it has no ULPI support - so there are no registers at all. + * That means accesses to ULPI_BUSCONTROL have to be abstracted away. + */ +static inline u8 musb_read_ulpi_buscontrol(struct musb_regs *musbr) +{ + return 0; +} +static inline void musb_write_ulpi_buscontrol(struct musb_regs *musbr, u8 val) +{} +#else +static inline u8 musb_read_ulpi_buscontrol(struct musb_regs *musbr) +{ + return readb(&musbr->ulpi_busctl); +} +static inline void musb_write_ulpi_buscontrol(struct musb_regs *musbr, u8 val) +{ + writeb(val, &musbr->ulpi_busctl); +} #endif #endif /* __MUSB_HDRC_DEFS_H__ */ diff --git a/drivers/usb/musb/omap3.c b/drivers/usb/musb/omap3.c index 3bfd0a0..a983552 100644 --- a/drivers/usb/musb/omap3.c +++ b/drivers/usb/musb/omap3.c @@ -36,9 +36,9 @@ static int platform_needs_initialization = 1; struct musb_config musb_cfg = { - (struct musb_regs *)MENTOR_USB0_BASE, - OMAP3_USB_TIMEOUT, - 0 + .regs = (struct musb_regs *)MENTOR_USB0_BASE, + .timeout = OMAP3_USB_TIMEOUT, + .musb_speed = 0, }; /* @@ -119,6 +119,9 @@ int musb_platform_init(void) stdby &= ~OMAP3_OTG_FORCESTDBY_STANDBY; writel(stdby, &otg->forcestdby); +#ifdef CONFIG_OMAP3_EVM + musb_cfg.extvbus = omap3_evm_need_extvbus(); +#endif platform_needs_initialization = 0; } diff --git a/drivers/usb/musb/omap3.h b/drivers/usb/musb/omap3.h index b591862..c934e0c 100644 --- a/drivers/usb/musb/omap3.h +++ b/drivers/usb/musb/omap3.h @@ -44,4 +44,8 @@ int musb_platform_init(void); +#ifdef CONFIG_OMAP3_EVM +extern u8 omap3_evm_use_extvbus(void); +#endif + #endif /* _MUSB_OMAP3_H */ diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c index d1f47c9..96d52fb 100644 --- a/drivers/video/cfb_console.c +++ b/drivers/video/cfb_console.c @@ -749,6 +749,18 @@ void video_puts (const char *s) /*****************************************************************************/ +/* + * Do not enforce drivers (or board code) to provide empty + * video_set_lut() if they do not support 8 bpp format. + * Implement weak default function instead. + */ +void __video_set_lut (unsigned int index, unsigned char r, + unsigned char g, unsigned char b) +{ +} +void video_set_lut (unsigned int, unsigned char, unsigned char, unsigned char) + __attribute__((weak, alias("__video_set_lut"))); + #if defined(CONFIG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN) #define FILL_8BIT_332RGB(r,g,b) { \ diff --git a/drivers/video/sm501.c b/drivers/video/sm501.c index 283d2d9..6a1e010 100644 --- a/drivers/video/sm501.c +++ b/drivers/video/sm501.c @@ -31,6 +31,7 @@ #include <common.h> +#include <asm/io.h> #include <video_fb.h> #include <sm501.h> @@ -54,6 +55,18 @@ GraphicDevice sm501; +void write_be32(int off, unsigned int val) +{ + out_be32((unsigned __iomem *)(sm501.isaBase + off), val); +} + +void write_le32(int off, unsigned int val) +{ + out_le32((unsigned __iomem *)(sm501.isaBase + off), val); +} + +void (*write_reg32)(int off, unsigned int val) = write_be32; + /*----------------------------------------------------------------------------- * SmiSetRegs -- *----------------------------------------------------------------------------- @@ -66,7 +79,7 @@ static void SmiSetRegs (void) */ const SMI_REGS *preg = board_get_regs (); while (preg->Index) { - write32 (preg->Index, preg->Value); + write_reg32 (preg->Index, preg->Value); /* * Insert a delay between */ @@ -75,26 +88,120 @@ static void SmiSetRegs (void) } } +#ifdef CONFIG_VIDEO_SM501_PCI +static struct pci_device_id sm501_pci_tbl[] = { + { PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_501 }, + {} +}; +#endif + +/* + * We do not enforce board code to provide empty/unused + * functions for this driver and define weak default + * functions here. + */ +unsigned int __board_video_init (void) +{ + return 0; +} + +unsigned int board_video_init (void) + __attribute__((weak, alias("__board_video_init"))); + +unsigned int __board_video_get_fb (void) +{ + return 0; +} + +unsigned int board_video_get_fb (void) + __attribute__((weak, alias("__board_video_get_fb"))); + +void __board_validate_screen (unsigned int base) +{ +} + +void board_validate_screen (unsigned int base) + __attribute__((weak, alias("__board_validate_screen"))); + /*----------------------------------------------------------------------------- * video_hw_init -- *----------------------------------------------------------------------------- */ void *video_hw_init (void) { +#ifdef CONFIG_VIDEO_SM501_PCI + unsigned int pci_mem_base, pci_mmio_base; + unsigned int id; + unsigned short device_id; + pci_dev_t devbusfn; + int mem; +#endif unsigned int *vm, i; memset (&sm501, 0, sizeof (GraphicDevice)); +#ifdef CONFIG_VIDEO_SM501_PCI + printf("Video: "); + + /* Look for SM501/SM502 chips */ + devbusfn = pci_find_devices(sm501_pci_tbl, 0); + if (devbusfn < 0) { + printf ("PCI Controller not found.\n"); + goto not_pci; + } + + /* Setup */ + pci_write_config_dword (devbusfn, PCI_COMMAND, + (PCI_COMMAND_MEMORY | PCI_COMMAND_IO)); + pci_read_config_word (devbusfn, PCI_DEVICE_ID, &device_id); + pci_read_config_dword (devbusfn, PCI_REVISION_ID, &id); + pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_0, &pci_mem_base); + pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_1, &pci_mmio_base); + sm501.frameAdrs = pci_mem_to_phys (devbusfn, pci_mem_base); + sm501.isaBase = pci_mem_to_phys (devbusfn, pci_mmio_base); + + if (sm501.isaBase) + write_reg32 = write_le32; + + mem = in_le32 ((unsigned __iomem *)(sm501.isaBase + 0x10)); + mem = (mem & 0x0000e000) >> 13; + switch (mem) { + case 1: + mem = 8; + break; + case 2: + mem = 16; + break; + case 3: + mem = 32; + break; + case 4: + mem = 64; + break; + case 5: + mem = 2; + break; + case 0: + default: + mem = 4; + } + printf ("PCI SM50%d %d MB\n", ((id & 0xff) == 0xC0) ? 2 : 1, mem); +not_pci: +#endif /* * Initialization of the access to the graphic chipset Retreive base * address of the chipset (see board/RPXClassic/eccx.c) */ - if ((sm501.isaBase = board_video_init ()) == 0) { - return (NULL); + if (!sm501.isaBase) { + sm501.isaBase = board_video_init (); + if (!sm501.isaBase) + return NULL; } - if ((sm501.frameAdrs = board_video_get_fb ()) == 0) { - return (NULL); + if (!sm501.frameAdrs) { + sm501.frameAdrs = board_video_get_fb (); + if (!sm501.frameAdrs) + return NULL; } sm501.winSizeX = board_get_width (); @@ -131,16 +238,3 @@ void *video_hw_init (void) return (&sm501); } - -/*----------------------------------------------------------------------------- - * video_set_lut -- - *----------------------------------------------------------------------------- - */ -void video_set_lut ( - unsigned int index, /* color number */ - unsigned char r, /* red */ - unsigned char g, /* green */ - unsigned char b /* blue */ - ) -{ -} |