summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2018-05-11 15:22:36 -0400
committerTom Rini <trini@konsulko.com>2018-05-11 15:22:36 -0400
commit9a66328a37e3b31dbe646ef3668b60466e8abd9a (patch)
tree0ece22b0187232017e0930aa88fa4664772edba9 /drivers
parent57a72d0560eb7693a35a891f43587bcd6786dc04 (diff)
parent71cb3d7c7897cd02ca731f4c510fff49705b84b7 (diff)
Merge git://git.denx.de/u-boot-tegra
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/nand/tegra_nand.c98
-rw-r--r--drivers/pci/pci_tegra.c17
-rw-r--r--drivers/power/regulator/as3722_regulator.c18
3 files changed, 85 insertions, 48 deletions
diff --git a/drivers/mtd/nand/tegra_nand.c b/drivers/mtd/nand/tegra_nand.c
index d585b7a652..74acdfb308 100644
--- a/drivers/mtd/nand/tegra_nand.c
+++ b/drivers/mtd/nand/tegra_nand.c
@@ -17,6 +17,7 @@
#include <asm/gpio.h>
#include <fdtdec.h>
#include <bouncebuf.h>
+#include <dm.h>
#include "tegra_nand.h"
DECLARE_GLOBAL_DATA_PTR;
@@ -28,6 +29,13 @@ DECLARE_GLOBAL_DATA_PTR;
/* ECC bytes to be generated for tag data */
#define TAG_ECC_BYTES 4
+static const struct udevice_id tegra_nand_dt_ids[] = {
+ {
+ .compatible = "nvidia,tegra20-nand",
+ },
+ { /* sentinel */ }
+};
+
/* 64 byte oob block info for large page (== 2KB) device
*
* OOB flash layout for Tegra with Reed-Solomon 4 symbol correct ECC:
@@ -90,9 +98,11 @@ struct nand_drv {
struct fdt_nand config;
};
-static struct nand_drv nand_ctrl;
-static struct mtd_info *our_mtd;
-static struct nand_chip nand_chip[CONFIG_SYS_MAX_NAND_DEVICE];
+struct tegra_nand_info {
+ struct udevice *dev;
+ struct nand_drv nand_ctrl;
+ struct nand_chip nand_chip;
+};
/**
* Wait for command completion
@@ -452,8 +462,8 @@ static void stop_command(struct nand_ctlr *reg)
* @param *reg_val address of reg_val
* @return 0 if ok, -1 on error
*/
-static int set_bus_width_page_size(struct fdt_nand *config,
- u32 *reg_val)
+static int set_bus_width_page_size(struct mtd_info *our_mtd,
+ struct fdt_nand *config, u32 *reg_val)
{
if (config->width == 8)
*reg_val = CFG_BUS_WIDTH_8BIT;
@@ -513,7 +523,7 @@ static int nand_rw_page(struct mtd_info *mtd, struct nand_chip *chip,
info = (struct nand_drv *)nand_get_controller_data(chip);
config = &info->config;
- if (set_bus_width_page_size(config, &reg_val))
+ if (set_bus_width_page_size(mtd, config, &reg_val))
return -EINVAL;
/* Need to be 4-byte aligned */
@@ -721,7 +731,7 @@ static int nand_rw_oob(struct mtd_info *mtd, struct nand_chip *chip,
if (((int)chip->oob_poi) & 0x03)
return -EINVAL;
info = (struct nand_drv *)nand_get_controller_data(chip);
- if (set_bus_width_page_size(&info->config, &reg_val))
+ if (set_bus_width_page_size(mtd, &info->config, &reg_val))
return -EINVAL;
stop_command(info->reg);
@@ -882,51 +892,39 @@ static void setup_timing(unsigned timing[FDT_NAND_TIMING_COUNT],
/**
* Decode NAND parameters from the device tree
*
- * @param blob Device tree blob
- * @param node Node containing "nand-flash" compatible node
+ * @param dev Driver model device
+ * @param config Device tree NAND configuration
* @return 0 if ok, -ve on error (FDT_ERR_...)
*/
-static int fdt_decode_nand(const void *blob, int node, struct fdt_nand *config)
+static int fdt_decode_nand(struct udevice *dev, struct fdt_nand *config)
{
int err;
- config->reg = (struct nand_ctlr *)fdtdec_get_addr(blob, node, "reg");
- config->enabled = fdtdec_get_is_enabled(blob, node);
- config->width = fdtdec_get_int(blob, node, "nvidia,nand-width", 8);
- err = gpio_request_by_name_nodev(offset_to_ofnode(node),
- "nvidia,wp-gpios", 0, &config->wp_gpio, GPIOD_IS_OUT);
+ config->reg = (struct nand_ctlr *)dev_read_addr(dev);
+ config->enabled = dev_read_enabled(dev);
+ config->width = dev_read_u32_default(dev, "nvidia,nand-width", 8);
+ err = gpio_request_by_name(dev, "nvidia,wp-gpios", 0, &config->wp_gpio,
+ GPIOD_IS_OUT);
if (err)
return err;
- err = fdtdec_get_int_array(blob, node, "nvidia,timing",
- config->timing, FDT_NAND_TIMING_COUNT);
+ err = dev_read_u32_array(dev, "nvidia,timing", config->timing,
+ FDT_NAND_TIMING_COUNT);
if (err < 0)
return err;
- /* Now look up the controller and decode that */
- node = fdt_next_node(blob, node, NULL);
- if (node < 0)
- return node;
-
return 0;
}
-/**
- * Board-specific NAND initialization
- *
- * @param nand nand chip info structure
- * @return 0, after initialized, -1 on error
- */
-int tegra_nand_init(struct nand_chip *nand, int devnum)
+static int tegra_probe(struct udevice *dev)
{
- struct nand_drv *info = &nand_ctrl;
+ struct tegra_nand_info *tegra = dev_get_priv(dev);
+ struct nand_chip *nand = &tegra->nand_chip;
+ struct nand_drv *info = &tegra->nand_ctrl;
struct fdt_nand *config = &info->config;
- int node, ret;
+ struct mtd_info *our_mtd;
+ int ret;
- node = fdtdec_next_compatible(gd->fdt_blob, 0,
- COMPAT_NVIDIA_TEGRA20_NAND);
- if (node < 0)
- return -1;
- if (fdt_decode_nand(gd->fdt_blob, node, config)) {
+ if (fdt_decode_nand(dev, config)) {
printf("Could not decode nand-flash in device tree\n");
return -1;
}
@@ -949,7 +947,7 @@ int tegra_nand_init(struct nand_chip *nand, int devnum)
nand->ecc.strength = 1;
nand->select_chip = nand_select_chip;
nand->dev_ready = nand_dev_ready;
- nand_set_controller_data(nand, &nand_ctrl);
+ nand_set_controller_data(nand, &tegra->nand_ctrl);
/* Disable subpage writes as we do not provide ecc->hwctl */
nand->options |= NAND_NO_SUBPAGE_WRITE;
@@ -974,17 +972,31 @@ int tegra_nand_init(struct nand_chip *nand, int devnum)
if (ret)
return ret;
- ret = nand_register(devnum, our_mtd);
- if (ret)
+ ret = nand_register(0, our_mtd);
+ if (ret) {
+ dev_err(dev, "Failed to register MTD: %d\n", ret);
return ret;
+ }
return 0;
}
+U_BOOT_DRIVER(tegra_nand) = {
+ .name = "tegra-nand",
+ .id = UCLASS_MTD,
+ .of_match = tegra_nand_dt_ids,
+ .probe = tegra_probe,
+ .priv_auto_alloc_size = sizeof(struct tegra_nand_info),
+};
+
void board_nand_init(void)
{
- struct nand_chip *nand = &nand_chip[0];
-
- if (tegra_nand_init(nand, 0))
- puts("Tegra NAND init failed\n");
+ struct udevice *dev;
+ int ret;
+
+ ret = uclass_get_device_by_driver(UCLASS_MTD,
+ DM_GET_DRIVER(tegra_nand), &dev);
+ if (ret && ret != -ENODEV)
+ pr_err("Failed to initialize %s. (error %d)\n", dev->name,
+ ret);
}
diff --git a/drivers/pci/pci_tegra.c b/drivers/pci/pci_tegra.c
index b325914b15..56c08585e6 100644
--- a/drivers/pci/pci_tegra.c
+++ b/drivers/pci/pci_tegra.c
@@ -17,6 +17,7 @@
#include <errno.h>
#include <malloc.h>
#include <pci.h>
+#include <pci_tegra.h>
#include <power-domain.h>
#include <reset.h>
@@ -888,7 +889,7 @@ static unsigned long tegra_pcie_port_get_pex_ctrl(struct tegra_pcie_port *port)
return ret;
}
-static void tegra_pcie_port_reset(struct tegra_pcie_port *port)
+void tegra_pcie_port_reset(struct tegra_pcie_port *port)
{
unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port);
unsigned long value;
@@ -905,6 +906,16 @@ static void tegra_pcie_port_reset(struct tegra_pcie_port *port)
afi_writel(port->pcie, value, ctrl);
}
+int tegra_pcie_port_index_of_port(struct tegra_pcie_port *port)
+{
+ return port->index;
+}
+
+void __weak tegra_pcie_board_port_reset(struct tegra_pcie_port *port)
+{
+ tegra_pcie_port_reset(port);
+}
+
static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
{
struct tegra_pcie *pcie = port->pcie;
@@ -923,7 +934,7 @@ static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
afi_writel(pcie, value, ctrl);
- tegra_pcie_port_reset(port);
+ tegra_pcie_board_port_reset(port);
if (soc->force_pca_enable) {
value = rp_readl(port, RP_VEND_CTL2);
@@ -974,7 +985,7 @@ static bool tegra_pcie_port_check_link(struct tegra_pcie_port *port)
} while (--timeout);
retry:
- tegra_pcie_port_reset(port);
+ tegra_pcie_board_port_reset(port);
} while (--retries);
return false;
diff --git a/drivers/power/regulator/as3722_regulator.c b/drivers/power/regulator/as3722_regulator.c
index 63f4615398..a0703c9e05 100644
--- a/drivers/power/regulator/as3722_regulator.c
+++ b/drivers/power/regulator/as3722_regulator.c
@@ -13,6 +13,8 @@
#include <power/pmic.h>
#include <power/regulator.h>
+#define AS3722_LDO_CONTROL0_MAX_INDEX 7
+
static int stepdown_get_value(struct udevice *dev)
{
return -ENOSYS;
@@ -68,10 +70,16 @@ static int ldo_set_value(struct udevice *dev, int uvolt)
static int ldo_set_enable(struct udevice *dev, bool enable)
{
struct udevice *pmic = dev_get_parent(dev);
+ u8 ctrl_reg = AS3722_LDO_CONTROL0;
int ldo = dev->driver_data;
int ret;
- ret = pmic_clrsetbits(pmic, AS3722_LDO_CONTROL, 0, 1 << ldo);
+ if (ldo > AS3722_LDO_CONTROL0_MAX_INDEX) {
+ ctrl_reg = AS3722_LDO_CONTROL1;
+ ldo -= 8;
+ }
+
+ ret = pmic_clrsetbits(pmic, ctrl_reg, !enable << ldo, enable << ldo);
if (ret < 0) {
debug("%s: failed to write LDO control register: %d", __func__,
ret);
@@ -84,10 +92,16 @@ static int ldo_set_enable(struct udevice *dev, bool enable)
static int ldo_get_enable(struct udevice *dev)
{
struct udevice *pmic = dev_get_parent(dev);
+ u8 ctrl_reg = AS3722_LDO_CONTROL0;
int ldo = dev->driver_data;
int ret;
- ret = pmic_reg_read(pmic, AS3722_LDO_CONTROL);
+ if (ldo > AS3722_LDO_CONTROL0_MAX_INDEX) {
+ ctrl_reg = AS3722_LDO_CONTROL1;
+ ldo -= 8;
+ }
+
+ ret = pmic_reg_read(pmic, ctrl_reg);
if (ret < 0) {
debug("%s: failed to read SD control register: %d", __func__,
ret);