diff options
Diffstat (limited to 'drivers')
88 files changed, 2096 insertions, 23957 deletions
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index a3afac4be73..cbe7a2fb779 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -299,11 +299,11 @@ config I2C_AT91 unless your system can cope with those limitations. config I2C_AU1550 - tristate "Au1550/Au1200 SMBus interface" + tristate "Au1550/Au1200/Au1300 SMBus interface" depends on MIPS_ALCHEMY help If you say yes to this option, support will be included for the - Au1550 and Au1200 SMBus interface. + Au1550/Au1200/Au1300 SMBus interface. This driver can also be built as a module. If so, the module will be called i2c-au1550. diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index 5d3b9ae6452..dbd0c8a4e98 100644 --- a/drivers/mmc/host/au1xmmc.c +++ b/drivers/mmc/host/au1xmmc.c @@ -153,6 +153,7 @@ static inline int has_dbdma(void) { switch (alchemy_get_cputype()) { case ALCHEMY_CPU_AU1200: + case ALCHEMY_CPU_AU1300: return 1; default: return 0; @@ -768,11 +769,15 @@ static void au1xmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) config2 = au_readl(HOST_CONFIG2(host)); switch (ios->bus_width) { + case MMC_BUS_WIDTH_8: + config2 |= SD_CONFIG2_BB; + break; case MMC_BUS_WIDTH_4: + config2 &= ~SD_CONFIG2_BB; config2 |= SD_CONFIG2_WB; break; case MMC_BUS_WIDTH_1: - config2 &= ~SD_CONFIG2_WB; + config2 &= ~(SD_CONFIG2_WB | SD_CONFIG2_BB); break; } au_writel(config2, HOST_CONFIG2(host)); @@ -943,7 +948,7 @@ static int __devinit au1xmmc_probe(struct platform_device *pdev) struct mmc_host *mmc; struct au1xmmc_host *host; struct resource *r; - int ret; + int ret, iflag; mmc = mmc_alloc_host(sizeof(struct au1xmmc_host), &pdev->dev); if (!mmc) { @@ -982,37 +987,43 @@ static int __devinit au1xmmc_probe(struct platform_device *pdev) dev_err(&pdev->dev, "no IRQ defined\n"); goto out3; } - host->irq = r->start; - /* IRQ is shared among both SD controllers */ - ret = request_irq(host->irq, au1xmmc_irq, IRQF_SHARED, - DRIVER_NAME, host); - if (ret) { - dev_err(&pdev->dev, "cannot grab IRQ\n"); - goto out3; - } mmc->ops = &au1xmmc_ops; mmc->f_min = 450000; mmc->f_max = 24000000; + mmc->max_blk_size = 2048; + mmc->max_blk_count = 512; + + mmc->ocr_avail = AU1XMMC_OCR; + mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ; + mmc->max_segs = AU1XMMC_DESCRIPTOR_COUNT; + + iflag = IRQF_SHARED; /* Au1100/Au1200: one int for both ctrls */ + switch (alchemy_get_cputype()) { case ALCHEMY_CPU_AU1100: mmc->max_seg_size = AU1100_MMC_DESCRIPTOR_SIZE; - mmc->max_segs = AU1XMMC_DESCRIPTOR_COUNT; break; case ALCHEMY_CPU_AU1200: mmc->max_seg_size = AU1200_MMC_DESCRIPTOR_SIZE; - mmc->max_segs = AU1XMMC_DESCRIPTOR_COUNT; + break; + case ALCHEMY_CPU_AU1300: + iflag = 0; /* nothing is shared */ + mmc->max_seg_size = AU1200_MMC_DESCRIPTOR_SIZE; + mmc->f_max = 52000000; + if (host->ioarea->start == AU1100_SD0_PHYS_ADDR) + mmc->caps |= MMC_CAP_8_BIT_DATA; break; } - mmc->max_blk_size = 2048; - mmc->max_blk_count = 512; - - mmc->ocr_avail = AU1XMMC_OCR; - mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ; + ret = request_irq(host->irq, au1xmmc_irq, iflag, DRIVER_NAME, host); + if (ret) { + dev_err(&pdev->dev, "cannot grab IRQ\n"); + goto out3; + } host->status = HOST_S_IDLE; diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c index 7dd3700f230..73abbc3e093 100644 --- a/drivers/mtd/nand/au1550nd.c +++ b/drivers/mtd/nand/au1550nd.c @@ -17,35 +17,19 @@ #include <linux/mtd/mtd.h> #include <linux/mtd/nand.h> #include <linux/mtd/partitions.h> +#include <linux/platform_device.h> #include <asm/io.h> +#include <asm/mach-au1x00/au1000.h> +#include <asm/mach-au1x00/au1550nd.h> -#ifdef CONFIG_MIPS_PB1550 -#include <asm/mach-pb1x00/pb1550.h> -#elif defined(CONFIG_MIPS_DB1550) -#include <asm/mach-db1x00/db1x00.h> -#endif -#include <asm/mach-db1x00/bcsr.h> -/* - * MTD structure for NAND controller - */ -static struct mtd_info *au1550_mtd = NULL; -static void __iomem *p_nand; -static int nand_width = 1; /* default x8 */ -static void (*au1550_write_byte)(struct mtd_info *, u_char); +struct au1550nd_ctx { + struct mtd_info info; + struct nand_chip chip; -/* - * Define partitions for flash device - */ -static const struct mtd_partition partition_info[] = { - { - .name = "NAND FS 0", - .offset = 0, - .size = 8 * 1024 * 1024}, - { - .name = "NAND FS 1", - .offset = MTDPART_OFS_APPEND, - .size = MTDPART_SIZ_FULL} + int cs; + void __iomem *base; + void (*write_byte)(struct mtd_info *, u_char); }; /** @@ -259,24 +243,25 @@ static int au_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len) static void au1550_hwcontrol(struct mtd_info *mtd, int cmd) { - register struct nand_chip *this = mtd->priv; + struct au1550nd_ctx *ctx = container_of(mtd, struct au1550nd_ctx, info); + struct nand_chip *this = mtd->priv; switch (cmd) { case NAND_CTL_SETCLE: - this->IO_ADDR_W = p_nand + MEM_STNAND_CMD; + this->IO_ADDR_W = ctx->base + MEM_STNAND_CMD; break; case NAND_CTL_CLRCLE: - this->IO_ADDR_W = p_nand + MEM_STNAND_DATA; + this->IO_ADDR_W = ctx->base + MEM_STNAND_DATA; break; case NAND_CTL_SETALE: - this->IO_ADDR_W = p_nand + MEM_STNAND_ADDR; + this->IO_ADDR_W = ctx->base + MEM_STNAND_ADDR; break; case NAND_CTL_CLRALE: - this->IO_ADDR_W = p_nand + MEM_STNAND_DATA; + this->IO_ADDR_W = ctx->base + MEM_STNAND_DATA; /* FIXME: Nobody knows why this is necessary, * but it works only that way */ udelay(1); @@ -284,7 +269,7 @@ static void au1550_hwcontrol(struct mtd_info *mtd, int cmd) case NAND_CTL_SETNCE: /* assert (force assert) chip enable */ - au_writel((1 << (4 + NAND_CS)), MEM_STNDCTL); + au_writel((1 << (4 + ctx->cs)), MEM_STNDCTL); break; case NAND_CTL_CLRNCE: @@ -331,9 +316,10 @@ static void au1550_select_chip(struct mtd_info *mtd, int chip) */ static void au1550_command(struct mtd_info *mtd, unsigned command, int column, int page_addr) { - register struct nand_chip *this = mtd->priv; + struct au1550nd_ctx *ctx = container_of(mtd, struct au1550nd_ctx, info); + struct nand_chip *this = mtd->priv; int ce_override = 0, i; - ulong flags; + unsigned long flags = 0; /* Begin command latch cycle */ au1550_hwcontrol(mtd, NAND_CTL_SETCLE); @@ -354,9 +340,9 @@ static void au1550_command(struct mtd_info *mtd, unsigned command, int column, i column -= 256; readcmd = NAND_CMD_READ1; } - au1550_write_byte(mtd, readcmd); + ctx->write_byte(mtd, readcmd); } - au1550_write_byte(mtd, command); + ctx->write_byte(mtd, command); /* Set ALE and clear CLE to start address cycle */ au1550_hwcontrol(mtd, NAND_CTL_CLRCLE); @@ -369,10 +355,10 @@ static void au1550_command(struct mtd_info *mtd, unsigned command, int column, i /* Adjust columns for 16 bit buswidth */ if (this->options & NAND_BUSWIDTH_16) column >>= 1; - au1550_write_byte(mtd, column); + ctx->write_byte(mtd, column); } if (page_addr != -1) { - au1550_write_byte(mtd, (u8)(page_addr & 0xff)); + ctx->write_byte(mtd, (u8)(page_addr & 0xff)); if (command == NAND_CMD_READ0 || command == NAND_CMD_READ1 || @@ -390,11 +376,12 @@ static void au1550_command(struct mtd_info *mtd, unsigned command, int column, i au1550_hwcontrol(mtd, NAND_CTL_SETNCE); } - au1550_write_byte(mtd, (u8)(page_addr >> 8)); + ctx->write_byte(mtd, (u8)(page_addr >> 8)); /* One more address cycle for devices > 32MiB */ if (this->chipsize > (32 << 20)) - au1550_write_byte(mtd, (u8)((page_addr >> 16) & 0x0f)); + ctx->write_byte(mtd, + ((page_addr >> 16) & 0x0f)); } /* Latch in address */ au1550_hwcontrol(mtd, NAND_CTL_CLRALE); @@ -440,121 +427,79 @@ static void au1550_command(struct mtd_info *mtd, unsigned command, int column, i while(!this->dev_ready(mtd)); } - -/* - * Main initialization routine - */ -static int __init au1xxx_nand_init(void) +static int __devinit find_nand_cs(unsigned long nand_base) { - struct nand_chip *this; - u16 boot_swapboot = 0; /* default value */ - int retval; - u32 mem_staddr; - u32 nand_phys; - - /* Allocate memory for MTD device structure and private data */ - au1550_mtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); - if (!au1550_mtd) { - printk("Unable to allocate NAND MTD dev structure.\n"); - return -ENOMEM; - } - - /* Get pointer to private data */ - this = (struct nand_chip *)(&au1550_mtd[1]); - - /* Link the private data with the MTD structure */ - au1550_mtd->priv = this; - au1550_mtd->owner = THIS_MODULE; - + void __iomem *base = + (void __iomem *)KSEG1ADDR(AU1000_STATIC_MEM_PHYS_ADDR); + unsigned long addr, staddr, start, mask, end; + int i; - /* MEM_STNDCTL: disable ints, disable nand boot */ - au_writel(0, MEM_STNDCTL); + for (i = 0; i < 4; i++) { + addr = 0x1000 + (i * 0x10); /* CSx */ + staddr = __raw_readl(base + addr + 0x08); /* STADDRx */ + /* figure out the decoded range of this CS */ + start = (staddr << 4) & 0xfffc0000; + mask = (staddr << 18) & 0xfffc0000; + end = (start | (start - 1)) & ~(start ^ mask); + if ((nand_base >= start) && (nand_base < end)) + return i; + } -#ifdef CONFIG_MIPS_PB1550 - /* set gpio206 high */ - gpio_direction_input(206); + return -ENODEV; +} - boot_swapboot = (au_readl(MEM_STSTAT) & (0x7 << 1)) | ((bcsr_read(BCSR_STATUS) >> 6) & 0x |