From patchwork Wed Feb 13 03:23:11 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Allen Martin X-Patchwork-Id: 220049 X-Patchwork-Delegate: twarren@nvidia.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id B71FA2C00DC for ; Wed, 13 Feb 2013 16:53:08 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 5A1964A16D; Wed, 13 Feb 2013 06:52:59 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 5KdDcw83k6Mj; Wed, 13 Feb 2013 06:52:59 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 10C4C4A16F; Wed, 13 Feb 2013 06:52:09 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 3056C4A14D for ; Wed, 13 Feb 2013 06:51:59 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id JuDARFmJABaj for ; Wed, 13 Feb 2013 06:51:56 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from hqemgate04.nvidia.com (hqemgate04.nvidia.com [216.228.121.35]) by theia.denx.de (Postfix) with ESMTPS id DDF954A133 for ; Wed, 13 Feb 2013 06:51:50 +0100 (CET) Received: from hqnvupgp05.nvidia.com (Not Verified[216.228.121.13]) by hqemgate04.nvidia.com id ; Tue, 12 Feb 2013 21:51:38 -0800 Received: from hqemhub01.nvidia.com ([172.20.150.30]) by hqnvupgp05.nvidia.com (PGP Universal service); Tue, 12 Feb 2013 21:51:47 -0800 X-PGP-Universal: processed; by hqnvupgp05.nvidia.com on Tue, 12 Feb 2013 21:51:47 -0800 Received: from badger.nvidia.com (172.20.144.16) by hqemhub01.nvidia.com (172.20.150.30) with Microsoft SMTP Server id 8.3.297.1; Tue, 12 Feb 2013 19:23:49 -0800 From: Allen Martin To: , , Date: Tue, 12 Feb 2013 19:23:11 -0800 Message-ID: <1360725802-5518-5-git-send-email-amartin@nvidia.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1360725802-5518-1-git-send-email-amartin@nvidia.com> References: <1360725802-5518-1-git-send-email-amartin@nvidia.com> X-NVConfidentiality: public MIME-Version: 1.0 Cc: u-boot@lists.denx.de Subject: [U-Boot] [PATCH 04/14] tegra20: spi: move fdt probe to spi_init X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de Make the tegra20 SPI driver similar to the tegra30 (and soon to be tegra114) SPI drivers in preparation of common fdt SPI driver front end. Signed-off-by: Allen Martin --- drivers/spi/tegra20_spi.c | 110 +++++++++++++++++++++++++++------------------ 1 file changed, 67 insertions(+), 43 deletions(-) diff --git a/drivers/spi/tegra20_spi.c b/drivers/spi/tegra20_spi.c index d6567f8..f3985f2 100644 --- a/drivers/spi/tegra20_spi.c +++ b/drivers/spi/tegra20_spi.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2012 NVIDIA Corporation + * Copyright (c) 2010-2013 NVIDIA Corporation * With help from the mpc8xxx SPI driver * With more help from omap3_spi SPI driver * @@ -55,14 +55,22 @@ struct spi_regs { u32 rx_fifo; /* SPI_RX_FIFO_0 register */ }; -struct tegra_spi_slave { - struct spi_slave slave; +struct tegra_spi_ctrl { struct spi_regs *regs; unsigned int freq; unsigned int mode; int periph_id; + int valid; +}; + +struct tegra_spi_slave { + struct spi_slave slave; + struct tegra_spi_ctrl *ctrl; }; +/* tegra20 only supports one SFLASH controller */ +static struct tegra_spi_ctrl spi_ctrls[1]; + static inline struct tegra_spi_slave *to_tegra_spi(struct spi_slave *slave) { return container_of(slave, struct tegra_spi_slave, slave); @@ -81,7 +89,6 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, unsigned int max_hz, unsigned int mode) { struct tegra_spi_slave *spi; - int node; if (!spi_cs_is_valid(bus, cs)) { printf("SPI error: unsupported bus %d / chip select %d\n", @@ -102,41 +109,19 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, } spi->slave.bus = bus; spi->slave.cs = cs; - - node = fdtdec_next_compatible(gd->fdt_blob, 0, - COMPAT_NVIDIA_TEGRA20_SFLASH); - if (node < 0) { - debug("%s: cannot locate sflash node\n", __func__); - return NULL; - } - if (!fdtdec_get_is_enabled(gd->fdt_blob, node)) { - debug("%s: sflash is disabled\n", __func__); - return NULL; - } - spi->regs = (struct spi_regs *)fdtdec_get_addr(gd->fdt_blob, - node, "reg"); - if ((fdt_addr_t)spi->regs == FDT_ADDR_T_NONE) { - debug("%s: no sflash register found\n", __func__); + spi->ctrl = &spi_ctrls[bus]; + if (!spi->ctrl) { + printf("SPI error: could not find controller for bus %d\n", + bus); return NULL; } - spi->freq = fdtdec_get_int(gd->fdt_blob, node, "spi-max-frequency", 0); - if (!spi->freq) { - debug("%s: no sflash max frequency found\n", __func__); - return NULL; - } - spi->periph_id = clock_decode_periph_id(gd->fdt_blob, node); - if (spi->periph_id == PERIPH_ID_NONE) { - debug("%s: could not decode periph id\n", __func__); - return NULL; - } - if (max_hz < spi->freq) { + + if (max_hz < spi->ctrl->freq) { debug("%s: limiting frequency from %u to %u\n", __func__, - spi->freq, max_hz); - spi->freq = max_hz; + spi->ctrl->freq, max_hz); + spi->ctrl->freq = max_hz; } - debug("%s: controller initialized at %p, freq = %u, periph_id = %d\n", - __func__, spi->regs, spi->freq, spi->periph_id); - spi->mode = mode; + spi->ctrl->mode = mode; return &spi->slave; } @@ -150,17 +135,54 @@ void spi_free_slave(struct spi_slave *slave) void spi_init(void) { - /* do nothing */ + struct tegra_spi_ctrl *ctrl; + int i; + int node = 0; + int count; + int node_list[1]; + + count = fdtdec_find_aliases_for_id(gd->fdt_blob, "spi", + COMPAT_NVIDIA_TEGRA20_SFLASH, + node_list, + 1); + for (i = 0; i < count; i++) { + ctrl = &spi_ctrls[i]; + node = node_list[i]; + + ctrl->regs = (struct spi_regs *)fdtdec_get_addr(gd->fdt_blob, + node, "reg"); + if ((fdt_addr_t)ctrl->regs == FDT_ADDR_T_NONE) { + debug("%s: no slink register found\n", __func__); + continue; + } + ctrl->freq = fdtdec_get_int(gd->fdt_blob, node, + "spi-max-frequency", 0); + if (!ctrl->freq) { + debug("%s: no slink max frequency found\n", __func__); + continue; + } + + ctrl->periph_id = clock_decode_periph_id(gd->fdt_blob, node); + if (ctrl->periph_id == PERIPH_ID_NONE) { + debug("%s: could not decode periph id\n", __func__); + continue; + } + ctrl->valid = 1; + + debug("%s: found controller at %p, freq = %u, periph_id = %d\n", + __func__, ctrl->regs, ctrl->freq, ctrl->periph_id); + } } int spi_claim_bus(struct spi_slave *slave) { struct tegra_spi_slave *spi = to_tegra_spi(slave); - struct spi_regs *regs = spi->regs; + struct spi_regs *regs = spi->ctrl->regs; u32 reg; /* Change SPI clock to correct frequency, PLLP_OUT0 source */ - clock_start_periph_pll(spi->periph_id, CLOCK_ID_PERIPH, spi->freq); + clock_start_periph_pll(spi->ctrl->periph_id, CLOCK_ID_PERIPH, + spi->ctrl->freq); /* Clear stale status here */ reg = SPI_STAT_RDY | SPI_STAT_RXF_FLUSH | SPI_STAT_TXF_FLUSH | \ @@ -171,8 +193,8 @@ int spi_claim_bus(struct spi_slave *slave) /* * Use sw-controlled CS, so we can clock in data after ReadID, etc. */ - reg = (spi->mode & 1) << SPI_CMD_ACTIVE_SDA_SHIFT; - if (spi->mode & 2) + reg = (spi->ctrl->mode & 1) << SPI_CMD_ACTIVE_SDA_SHIFT; + if (spi->ctrl->mode & 2) reg |= 1 << SPI_CMD_ACTIVE_SCLK_SHIFT; clrsetbits_le32(®s->command, SPI_CMD_ACTIVE_SCLK_MASK | SPI_CMD_ACTIVE_SDA_MASK, SPI_CMD_CS_SOFT | reg); @@ -210,11 +232,12 @@ void spi_release_bus(struct spi_slave *slave) void spi_cs_activate(struct spi_slave *slave) { struct tegra_spi_slave *spi = to_tegra_spi(slave); + struct spi_regs *regs = spi->ctrl->regs; pinmux_select_spi(); /* CS is negated on Tegra, so drive a 1 to get a 0 */ - setbits_le32(&spi->regs->command, SPI_CMD_CS_VAL); + setbits_le32(®s->command, SPI_CMD_CS_VAL); corrupt_delay(); /* Let UART settle */ } @@ -222,11 +245,12 @@ void spi_cs_activate(struct spi_slave *slave) void spi_cs_deactivate(struct spi_slave *slave) { struct tegra_spi_slave *spi = to_tegra_spi(slave); + struct spi_regs *regs = spi->ctrl->regs; pinmux_select_uart(); /* CS is negated on Tegra, so drive a 0 to get a 1 */ - clrbits_le32(&spi->regs->command, SPI_CMD_CS_VAL); + clrbits_le32(®s->command, SPI_CMD_CS_VAL); corrupt_delay(); /* Let SPI settle */ } @@ -235,7 +259,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *data_out, void *data_in, unsigned long flags) { struct tegra_spi_slave *spi = to_tegra_spi(slave); - struct spi_regs *regs = spi->regs; + struct spi_regs *regs = spi->ctrl->regs; u32 reg, tmpdout, tmpdin = 0; const u8 *dout = data_out; u8 *din = data_in;