diff options
author | Vignesh Raghavendra <vigneshr@ti.com> | 2019-10-23 13:30:01 +0530 |
---|---|---|
committer | Stefan Roese <sr@denx.de> | 2019-10-24 09:49:10 +0200 |
commit | c2dfd0a4d81faeb50aa0cfe36bf1835a40811304 (patch) | |
tree | 2e849b5be710e515b410b619d89cd645d0b73c08 /drivers | |
parent | d75eacf9b8a7562e8ea8c94138cd4ff4694f7c53 (diff) |
mtd: Add TI HyperBus Memory Controller driver
AM654/J721e has HyperBus Memory Controller that supports HyperFlash and
HyperRAM devices. It provides a memory mapped interface to interact with
these devices. Add a driver to support the same.
Driver calibrates the controller, setups up for MMIO access and probes
HyperFlash child node.
Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
Reviewed-by: Stefan Roese <sr@denx.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mtd/Kconfig | 7 | ||||
-rw-r--r-- | drivers/mtd/Makefile | 1 | ||||
-rw-r--r-- | drivers/mtd/hbmc-am654.c | 105 |
3 files changed, 113 insertions, 0 deletions
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index 0050fb2b9b..37f379d478 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -94,6 +94,13 @@ config RENESAS_RPC_HF This enables access to Hyperflash memory through the Renesas RCar Gen3 RPC controller. +config HBMC_AM654 + bool "HyperBus controller driver for AM65x SoC" + depends on SYSCON + help + This is the driver for HyperBus controller on TI's AM65x and + other SoCs + source "drivers/mtd/nand/Kconfig" source "drivers/mtd/spi/Kconfig" diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile index 22ceda93c0..293079d709 100644 --- a/drivers/mtd/Makefile +++ b/drivers/mtd/Makefile @@ -18,5 +18,6 @@ obj-$(CONFIG_FLASH_PIC32) += pic32_flash.o obj-$(CONFIG_ST_SMI) += st_smi.o obj-$(CONFIG_STM32_FLASH) += stm32_flash.o obj-$(CONFIG_RENESAS_RPC_HF) += renesas_rpc_hf.o +obj-$(CONFIG_HBMC_AM654) += hbmc-am654.o obj-y += nand/ diff --git a/drivers/mtd/hbmc-am654.c b/drivers/mtd/hbmc-am654.c new file mode 100644 index 0000000000..5a560f1253 --- /dev/null +++ b/drivers/mtd/hbmc-am654.c @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/ +// Author: Vignesh Raghavendra <vigneshr@ti.com> + +#include <common.h> +#include <asm/io.h> +#include <dm.h> +#include <regmap.h> +#include <syscon.h> + +#define FSS_SYSC_REG 0x4 + +#define HYPERBUS_CALIB_COUNT 25 + +struct am654_hbmc_priv { + void __iomem *mmiobase; + bool calibrated; +}; + +/* Calibrate by looking for "QRY" string within the CFI space */ +static int am654_hyperbus_calibrate(struct udevice *dev) +{ + struct am654_hbmc_priv *priv = dev_get_priv(dev); + int count = HYPERBUS_CALIB_COUNT; + int pass_count = 0; + u16 qry[3]; + + if (priv->calibrated) + return 0; + + writew(0xF0, priv->mmiobase); + writew(0x98, priv->mmiobase + 0xaa); + + while (count--) { + qry[0] = readw(priv->mmiobase + 0x20); + qry[1] = readw(priv->mmiobase + 0x22); + qry[2] = readw(priv->mmiobase + 0x24); + + if (qry[0] == 'Q' && qry[1] == 'R' && qry[2] == 'Y') + pass_count++; + else + pass_count = 0; + if (pass_count == 5) + break; + } + writew(0xF0, priv->mmiobase); + writew(0xFF, priv->mmiobase); + + return pass_count == 5; +} + +static int am654_select_hbmc(struct udevice *dev) +{ + struct regmap *regmap = syscon_get_regmap(dev_get_parent(dev)); + + return regmap_update_bits(regmap, FSS_SYSC_REG, 0x2, 0x2); +} + +static int am654_hbmc_bind(struct udevice *dev) +{ + return dm_scan_fdt_dev(dev); +} + +static int am654_hbmc_probe(struct udevice *dev) +{ + struct am654_hbmc_priv *priv = dev_get_priv(dev); + int ret; + + priv->mmiobase = devfdt_remap_addr_index(dev, 1); + if (dev_read_bool(dev, "mux-controls")) { + ret = am654_select_hbmc(dev); + if (ret) { + dev_err(dev, "Failed to select HBMC mux\n"); + return ret; + } + } + + if (!priv->calibrated) { + ret = am654_hyperbus_calibrate(dev); + if (!ret) { + dev_err(dev, "Calibration Failed\n"); + return -EIO; + } + } + priv->calibrated = true; + + return 0; +} + +static const struct udevice_id am654_hbmc_dt_ids[] = { + { + .compatible = "ti,am654-hbmc", + }, + { /* end of table */ } +}; + +U_BOOT_DRIVER(hbmc_am654) = { + .name = "hbmc-am654", + .id = UCLASS_MTD, + .of_match = am654_hbmc_dt_ids, + .probe = am654_hbmc_probe, + .bind = am654_hbmc_bind, + .priv_auto_alloc_size = sizeof(struct am654_hbmc_priv), +}; |