diff options
author | Tom Rini <trini@ti.com> | 2015-01-15 14:05:31 -0500 |
---|---|---|
committer | Tom Rini <trini@ti.com> | 2015-01-16 10:25:01 -0500 |
commit | ab77f24119e80257de4ab017b877f92f96980562 (patch) | |
tree | b541a8bda045a603f90ab55dae02812e1edb2e51 /drivers | |
parent | d928664f4101e24128c879956d1aa7c76509ea6a (diff) | |
parent | fa58b102cd8f5345cbc28657600c3a28acfbd80e (diff) | |
download | u-boot-ab77f24119e80257de4ab017b877f92f96980562.zip u-boot-ab77f24119e80257de4ab017b877f92f96980562.tar.gz u-boot-ab77f24119e80257de4ab017b877f92f96980562.tar.bz2 |
Merge branch 'master' of git://git.denx.de/u-boot-ti
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mtd/nand/omap_gpmc.c | 114 | ||||
-rw-r--r-- | drivers/power/pmic/Makefile | 1 | ||||
-rw-r--r-- | drivers/power/pmic/pmic_tps62362.c | 47 |
3 files changed, 160 insertions, 2 deletions
diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c index 459904d..fc64f48 100644 --- a/drivers/mtd/nand/omap_gpmc.c +++ b/drivers/mtd/nand/omap_gpmc.c @@ -441,6 +441,115 @@ static int omap_correct_data_bch(struct mtd_info *mtd, uint8_t *dat, return (err) ? err : error_count; } +#ifdef CONFIG_NAND_OMAP_GPMC_PREFETCH + +#define PREFETCH_CONFIG1_CS_SHIFT 24 +#define PREFETCH_FIFOTHRESHOLD_MAX 0x40 +#define PREFETCH_FIFOTHRESHOLD(val) ((val) << 8) +#define PREFETCH_STATUS_COUNT(val) (val & 0x00003fff) +#define PREFETCH_STATUS_FIFO_CNT(val) ((val >> 24) & 0x7F) +#define ENABLE_PREFETCH (1 << 7) + +/** + * omap_prefetch_enable - configures and starts prefetch transfer + * @fifo_th: fifo threshold to be used for read/ write + * @count: number of bytes to be transferred + * @is_write: prefetch read(0) or write post(1) mode + * @cs: chip select to use + */ +static int omap_prefetch_enable(int fifo_th, unsigned int count, int is_write, int cs) +{ + uint32_t val; + + if (fifo_th > PREFETCH_FIFOTHRESHOLD_MAX) + return -EINVAL; + + if (readl(&gpmc_cfg->prefetch_control)) + return -EBUSY; + + /* Set the amount of bytes to be prefetched */ + writel(count, &gpmc_cfg->prefetch_config2); + + val = (cs << PREFETCH_CONFIG1_CS_SHIFT) | (is_write & 1) | + PREFETCH_FIFOTHRESHOLD(fifo_th) | ENABLE_PREFETCH; + writel(val, &gpmc_cfg->prefetch_config1); + + /* Start the prefetch engine */ + writel(1, &gpmc_cfg->prefetch_control); + + return 0; +} + +/** + * omap_prefetch_reset - disables and stops the prefetch engine + */ +static void omap_prefetch_reset(void) +{ + writel(0, &gpmc_cfg->prefetch_control); + writel(0, &gpmc_cfg->prefetch_config1); +} + +static int __read_prefetch_aligned(struct nand_chip *chip, uint32_t *buf, int len) +{ + int ret; + uint32_t cnt; + struct omap_nand_info *info = chip->priv; + + ret = omap_prefetch_enable(PREFETCH_FIFOTHRESHOLD_MAX, len, 0, info->cs); + if (ret < 0) + return ret; + + do { + int i; + + cnt = readl(&gpmc_cfg->prefetch_status); + cnt = PREFETCH_STATUS_FIFO_CNT(cnt); + + for (i = 0; i < cnt / 4; i++) { + *buf++ = readl(CONFIG_SYS_NAND_BASE); + len -= 4; + } + } while (len); + + omap_prefetch_reset(); + + return 0; +} + +static void omap_nand_read_prefetch8(struct mtd_info *mtd, uint8_t *buf, int len) +{ + int ret; + uint32_t head, tail; + struct nand_chip *chip = mtd->priv; + + /* + * If the destination buffer is unaligned, start with reading + * the overlap byte-wise. + */ + head = ((uint32_t) buf) % 4; + if (head) { + nand_read_buf(mtd, buf, head); + buf += head; + len -= head; + } + + /* + * Only transfer multiples of 4 bytes in a pre-fetched fashion. + * If there's a residue, care for it byte-wise afterwards. + */ + tail = len % 4; + + ret = __read_prefetch_aligned(chip, (uint32_t *) buf, len - tail); + if (ret < 0) { + /* fallback in case the prefetch engine is busy */ + nand_read_buf(mtd, buf, len); + } else if (tail) { + buf += len - tail; + nand_read_buf(mtd, buf, tail); + } +} +#endif /* CONFIG_NAND_OMAP_GPMC_PREFETCH */ + /** * omap_read_page_bch - hardware ecc based page read function * @mtd: mtd info structure @@ -880,11 +989,12 @@ int board_nand_init(struct nand_chip *nand) if (err) return err; -#ifdef CONFIG_SPL_BUILD +#ifdef CONFIG_NAND_OMAP_GPMC_PREFETCH + /* TODO: Implement for 16-bit bus width */ if (nand->options & NAND_BUSWIDTH_16) nand->read_buf = nand_read_buf16; else - nand->read_buf = nand_read_buf; + nand->read_buf = omap_nand_read_prefetch8; #endif nand->dev_ready = omap_dev_ready; diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile index e7b07eb..985cfdb 100644 --- a/drivers/power/pmic/Makefile +++ b/drivers/power/pmic/Makefile @@ -14,5 +14,6 @@ obj-$(CONFIG_POWER_PFUZE100) += pmic_pfuze100.o obj-$(CONFIG_POWER_TPS65090_I2C) += pmic_tps65090.o obj-$(CONFIG_POWER_TPS65090_EC) += pmic_tps65090_ec.o obj-$(CONFIG_POWER_TPS65217) += pmic_tps65217.o +obj-$(CONFIG_POWER_TPS65218) += pmic_tps62362.o obj-$(CONFIG_POWER_TPS65218) += pmic_tps65218.o obj-$(CONFIG_POWER_TPS65910) += pmic_tps65910.o diff --git a/drivers/power/pmic/pmic_tps62362.c b/drivers/power/pmic/pmic_tps62362.c new file mode 100644 index 0000000..2123685 --- /dev/null +++ b/drivers/power/pmic/pmic_tps62362.c @@ -0,0 +1,47 @@ +/* + * (C) Copyright 2014 Texas Instruments Incorporated - http://www.ti.com + * Author: Felipe Balbi <balbi@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <i2c.h> +#include <asm/errno.h> +#include <power/pmic.h> +#include <power/tps62362.h> + +/** + * tps62362_voltage_update() - Function to change a voltage level, as this + * is a multi-step process. + * @reg: Register address to write to + * @volt_sel: Voltage register value to write + * @return: 0 on success, 1 on failure + */ +int tps62362_voltage_update(unsigned char reg, unsigned char volt_sel) +{ + if (reg > TPS62362_NUM_REGS) + return 1; + + return i2c_write(TPS62362_I2C_ADDR, reg, 1, &volt_sel, 1); +} + +int power_tps62362_init(unsigned char bus) +{ + static const char name[] = "TPS62362"; + struct pmic *p = pmic_alloc(); + + if (!p) { + printf("%s: POWER allocation error!\n", __func__); + return -ENOMEM; + } + + p->name = name; + p->interface = PMIC_I2C; + p->number_of_regs = TPS62362_NUM_REGS; + p->hw.i2c.addr = TPS62362_I2C_ADDR; + p->hw.i2c.tx_num = 1; + p->bus = bus; + + return 0; +} |