Re: [U-Boot] [PATCH v2 8/9] tegra: add SPI SLINK driver
Hi Allen, On Mon, Jan 14, 2013 at 8:27 PM, Allen Martin amar...@nvidia.com wrote: On Sat, Jan 12, 2013 at 08:56:23AM -0800, Simon Glass wrote: Hi, On Sat, Jan 12, 2013 at 1:07 AM, Allen Martin amar...@nvidia.com wrote: Add driver for tegra SPI SLINK style driver. This controller is similar to the tegra20 SPI SFLASH controller. The difference is that the SLINK controller is a genernal purpose SPI controller and the SFLASH controller is special purpose and can only talk to FLASH devices. In addition there are potentially many instances of an SLINK controller on tegra and only a single instance of SFLASH. Tegra20 is currently ths only version of tegra that instantiates an SFLASH controller. This driver supports basic PIO mode of operation and is configurable (CONFIG_OF_CONTROL) to be driven off devicetree bindings. Up to 4 devices per controller may be attached, although typically only a single chip select line is exposed from tegra per controller so in reality this is usually limited to 1. To enable this driver, use CONFIG_TEGRA_SLINK A few comments - note I am on holiday next week so please don't wait for my response on the next version. ... +#include spi.h +#ifdef CONFIG_OF_CONTROL You probably don't need this ifdef ok + + spi = malloc(sizeof(struct tegra_spi_slave)); Please also look at my SPI series where I added an allocate function for this. http://patchwork.ozlabs.org/patch/208226/ http://patchwork.ozlabs.org/patch/208229/ Nice, thanks. I propose I should wait for that to land in u-boot/master and trick back down to u-boot-arm and u-boot-tegra, and then add it in a separate patch. That way I don't have to add a cross repo dependency. Yes, sounds good. +{ + int node = 0, i; + struct tegra_spi_ctrl *ctrl; blank line here ok + for (i = 0; i CONFIG_TEGRA_SLINK_CTRLS; i++) { + ctrl = spi_ctrls[i]; +#ifdef CONFIG_OF_CONTROL + node = fdtdec_next_compatible(gd-fdt_blob, node, + COMPAT_NVIDIA_TEGRA20_SLINK); + if (!node) + break; I think you should be using fdtdec_find_aliases_for_id() so that aliases work. I'll reply in Stephen's follow-up on this. + (slave-cs SLINK_CMD2_SS_EN_SHIFT); + writel(reg, regs-command2); Could use clrsetbits_le32() if you like Ok + bytes = (num_bytes 4) ? 4 : num_bytes; + + if (dout != NULL) { + for (i = 0; i bytes; ++i) + tmpdout = (tmpdout 8) | dout[i]; dout += bytes here... + } + + num_bytes -= bytes; + if (dout) + dout += bytes; instead of here? ok + + clrsetbits_le32(regs-command, SLINK_CMD_BIT_LENGTH_MASK, + bytes * 8 - 1); + writel(tmpdout, regs-tx_fifo); + setbits_le32(regs-command, SLINK_CMD_GO); + + /* +* Wait for SPI transmit FIFO to empty, or to time out. +* The RX FIFO status will be read and cleared last +*/ + for (tm = 0, is_read = 0; tm SPI_TIMEOUT; ++tm) { + u32 status; + This says timeout but doesn't seem to actually check get_timer(). Also is it possible to separate the code that waits for completion from the code below? You're right about get_timer(), I'll fix that. I pulled this loop directly from the tegra20 tegra_spi driver, so I'm not the original author, but I believe the reason it's written this way is so there's a single timeout loop around the wait for STAT_BSY to drop, RXF_EMPTY to drop, and TXF_EMPTY to go high. It *should* be ok to move the TXF_EMPTY wait to a separate wait loop, but I'm a little hesitant to touch the code since it's beeen well tested in the tegra20 driver, and this part of the driver is identical. OK, well it's up to you - just a suggestion and what you have works. + status = readl(regs-status); + + /* We can exit when we've had both RX and TX activity */ + if (is_read (status SLINK_STAT_TXF_EMPTY)) + break; + + if ((status (SLINK_STAT_BSY | SLINK_STAT_RDY)) != + SLINK_STAT_RDY) + tm++; + + else if (!(status SLINK_STAT_RXF_EMPTY)) { + tmpdin = readl(regs-rx_fifo); + is_read = 1; + + /* swap bytes read in */ + if (din != NULL) { + for (i = bytes - 1; i = 0; --i) { +
Re: [U-Boot] [PATCH v2 8/9] tegra: add SPI SLINK driver
Hi Stephen, On Mon, Jan 14, 2013 at 10:49 AM, Stephen Warren swar...@wwwdotorg.org wrote: On 01/12/2013 09:56 AM, Simon Glass wrote: Hi, On Sat, Jan 12, 2013 at 1:07 AM, Allen Martin amar...@nvidia.com wrote: Add driver for tegra SPI SLINK style driver. This controller is similar to the tegra20 SPI SFLASH controller. The difference is that the SLINK controller is a genernal purpose SPI controller and the SFLASH controller is special purpose and can only talk to FLASH devices. In addition there are potentially many instances of an SLINK controller on tegra and only a single instance of SFLASH. Tegra20 is currently ths only version of tegra that instantiates an SFLASH controller. This driver supports basic PIO mode of operation and is configurable (CONFIG_OF_CONTROL) to be driven off devicetree bindings. Up to 4 devices per controller may be attached, although typically only a single chip select line is exposed from tegra per controller so in reality this is usually limited to 1. To enable this driver, use CONFIG_TEGRA_SLINK diff --git a/drivers/spi/tegra_slink.c b/drivers/spi/tegra_slink.c +#ifdef CONFIG_OF_CONTROL You probably don't need this ifdef If we did assume CONFIG_OF_CONTROL was on, then we could get rid of the previous patch; all the device addresses would come from device tree, so there would be no need to add them to any header file:-) As Allen said I just mean we shouldn't need to put #ifdefs around #include fdtdec.h +void spi_init(void) +{ + int node = 0, i; + struct tegra_spi_ctrl *ctrl; blank line here + for (i = 0; i CONFIG_TEGRA_SLINK_CTRLS; i++) { + ctrl = spi_ctrls[i]; +#ifdef CONFIG_OF_CONTROL + node = fdtdec_next_compatible(gd-fdt_blob, node, + COMPAT_NVIDIA_TEGRA20_SLINK); + if (!node) + break; I think you should be using fdtdec_find_aliases_for_id() so that aliases work. I strongly believe we shouldn't be using aliases for enumeration, which is what fdtdec_find_aliases_for_id() does, IIRC. Instead, we should enumerate all the devices in the correct fashion, and then apply aliases as a separate step if they exists. Hence, I believe it's not correct to use fdtdec_find_aliases_for_id() anywhere. We might be saying the same thing, but I can't tell. We had quite a long discussion about this when the function was written and I thought it was then considered correct. The function does not ignore nodes without an alias. It simply returns a list of nodes that your driver should init, in the order in which U-Boot expects to find them. So I think it is safe to call, and in fact should be called in any driver that has more than one device and wants to provide the ability to select device ordering. Please can you take another look at the function and see what you think? We should not enumerate devices that are not supposed to be used, so checking fdtdec_get_is_enabled() might be good too. Regards, Simon ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH v2 8/9] tegra: add SPI SLINK driver
On 01/14/2013 09:33 PM, Allen Martin wrote: On Mon, Jan 14, 2013 at 10:49:53AM -0800, Stephen Warren wrote: On 01/12/2013 09:56 AM, Simon Glass wrote: Hi, On Sat, Jan 12, 2013 at 1:07 AM, Allen Martin amar...@nvidia.com wrote: Add driver for tegra SPI SLINK style driver. This controller is similar to the tegra20 SPI SFLASH controller. The difference is that the SLINK controller is a genernal purpose SPI controller and the SFLASH controller is special purpose and can only talk to FLASH devices. In addition there are potentially many instances of an SLINK controller on tegra and only a single instance of SFLASH. Tegra20 is currently ths only version of tegra that instantiates an SFLASH controller. This driver supports basic PIO mode of operation and is configurable (CONFIG_OF_CONTROL) to be driven off devicetree bindings. Up to 4 devices per controller may be attached, although typically only a single chip select line is exposed from tegra per controller so in reality this is usually limited to 1. To enable this driver, use CONFIG_TEGRA_SLINK +void spi_init(void) +{ + int node = 0, i; + struct tegra_spi_ctrl *ctrl; blank line here + for (i = 0; i CONFIG_TEGRA_SLINK_CTRLS; i++) { + ctrl = spi_ctrls[i]; +#ifdef CONFIG_OF_CONTROL + node = fdtdec_next_compatible(gd-fdt_blob, node, + COMPAT_NVIDIA_TEGRA20_SLINK); + if (!node) + break; I think you should be using fdtdec_find_aliases_for_id() so that aliases work. I strongly believe we shouldn't be using aliases for enumeration, which is what fdtdec_find_aliases_for_id() does, IIRC. Instead, we should enumerate all the devices in the correct fashion, and then apply aliases as a separate step if they exists. Hence, I believe it's not correct to use fdtdec_find_aliases_for_id() anywhere. I'm a bit confused about the usage of fdt aliases in u-boot. My understanding of aliases is that they are intended to give drivers hints about device naming. Since u-boot doesn't really name devices, what are aliases supposed to do? Most U-Boot command use IDs to identify devices/interfaces, e.g. in ext2load mmc 0:1, the 0 means MMC instance #0. The instance number is parsed out from the end of the alias name. ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH v2 8/9] tegra: add SPI SLINK driver
On 01/12/2013 09:56 AM, Simon Glass wrote: Hi, On Sat, Jan 12, 2013 at 1:07 AM, Allen Martin amar...@nvidia.com wrote: Add driver for tegra SPI SLINK style driver. This controller is similar to the tegra20 SPI SFLASH controller. The difference is that the SLINK controller is a genernal purpose SPI controller and the SFLASH controller is special purpose and can only talk to FLASH devices. In addition there are potentially many instances of an SLINK controller on tegra and only a single instance of SFLASH. Tegra20 is currently ths only version of tegra that instantiates an SFLASH controller. This driver supports basic PIO mode of operation and is configurable (CONFIG_OF_CONTROL) to be driven off devicetree bindings. Up to 4 devices per controller may be attached, although typically only a single chip select line is exposed from tegra per controller so in reality this is usually limited to 1. To enable this driver, use CONFIG_TEGRA_SLINK diff --git a/drivers/spi/tegra_slink.c b/drivers/spi/tegra_slink.c +#ifdef CONFIG_OF_CONTROL You probably don't need this ifdef If we did assume CONFIG_OF_CONTROL was on, then we could get rid of the previous patch; all the device addresses would come from device tree, so there would be no need to add them to any header file:-) +void spi_init(void) +{ + int node = 0, i; + struct tegra_spi_ctrl *ctrl; blank line here + for (i = 0; i CONFIG_TEGRA_SLINK_CTRLS; i++) { + ctrl = spi_ctrls[i]; +#ifdef CONFIG_OF_CONTROL + node = fdtdec_next_compatible(gd-fdt_blob, node, + COMPAT_NVIDIA_TEGRA20_SLINK); + if (!node) + break; I think you should be using fdtdec_find_aliases_for_id() so that aliases work. I strongly believe we shouldn't be using aliases for enumeration, which is what fdtdec_find_aliases_for_id() does, IIRC. Instead, we should enumerate all the devices in the correct fashion, and then apply aliases as a separate step if they exists. Hence, I believe it's not correct to use fdtdec_find_aliases_for_id() anywhere. ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH v2 8/9] tegra: add SPI SLINK driver
On Sat, Jan 12, 2013 at 08:56:23AM -0800, Simon Glass wrote: Hi, On Sat, Jan 12, 2013 at 1:07 AM, Allen Martin amar...@nvidia.com wrote: Add driver for tegra SPI SLINK style driver. This controller is similar to the tegra20 SPI SFLASH controller. The difference is that the SLINK controller is a genernal purpose SPI controller and the SFLASH controller is special purpose and can only talk to FLASH devices. In addition there are potentially many instances of an SLINK controller on tegra and only a single instance of SFLASH. Tegra20 is currently ths only version of tegra that instantiates an SFLASH controller. This driver supports basic PIO mode of operation and is configurable (CONFIG_OF_CONTROL) to be driven off devicetree bindings. Up to 4 devices per controller may be attached, although typically only a single chip select line is exposed from tegra per controller so in reality this is usually limited to 1. To enable this driver, use CONFIG_TEGRA_SLINK A few comments - note I am on holiday next week so please don't wait for my response on the next version. ... +#include spi.h +#ifdef CONFIG_OF_CONTROL You probably don't need this ifdef ok + + spi = malloc(sizeof(struct tegra_spi_slave)); Please also look at my SPI series where I added an allocate function for this. http://patchwork.ozlabs.org/patch/208226/ http://patchwork.ozlabs.org/patch/208229/ Nice, thanks. I propose I should wait for that to land in u-boot/master and trick back down to u-boot-arm and u-boot-tegra, and then add it in a separate patch. That way I don't have to add a cross repo dependency. +{ + int node = 0, i; + struct tegra_spi_ctrl *ctrl; blank line here ok + for (i = 0; i CONFIG_TEGRA_SLINK_CTRLS; i++) { + ctrl = spi_ctrls[i]; +#ifdef CONFIG_OF_CONTROL + node = fdtdec_next_compatible(gd-fdt_blob, node, + COMPAT_NVIDIA_TEGRA20_SLINK); + if (!node) + break; I think you should be using fdtdec_find_aliases_for_id() so that aliases work. I'll reply in Stephen's follow-up on this. + (slave-cs SLINK_CMD2_SS_EN_SHIFT); + writel(reg, regs-command2); Could use clrsetbits_le32() if you like Ok + bytes = (num_bytes 4) ? 4 : num_bytes; + + if (dout != NULL) { + for (i = 0; i bytes; ++i) + tmpdout = (tmpdout 8) | dout[i]; dout += bytes here... + } + + num_bytes -= bytes; + if (dout) + dout += bytes; instead of here? ok + + clrsetbits_le32(regs-command, SLINK_CMD_BIT_LENGTH_MASK, + bytes * 8 - 1); + writel(tmpdout, regs-tx_fifo); + setbits_le32(regs-command, SLINK_CMD_GO); + + /* +* Wait for SPI transmit FIFO to empty, or to time out. +* The RX FIFO status will be read and cleared last +*/ + for (tm = 0, is_read = 0; tm SPI_TIMEOUT; ++tm) { + u32 status; + This says timeout but doesn't seem to actually check get_timer(). Also is it possible to separate the code that waits for completion from the code below? You're right about get_timer(), I'll fix that. I pulled this loop directly from the tegra20 tegra_spi driver, so I'm not the original author, but I believe the reason it's written this way is so there's a single timeout loop around the wait for STAT_BSY to drop, RXF_EMPTY to drop, and TXF_EMPTY to go high. It *should* be ok to move the TXF_EMPTY wait to a separate wait loop, but I'm a little hesitant to touch the code since it's beeen well tested in the tegra20 driver, and this part of the driver is identical. + status = readl(regs-status); + + /* We can exit when we've had both RX and TX activity */ + if (is_read (status SLINK_STAT_TXF_EMPTY)) + break; + + if ((status (SLINK_STAT_BSY | SLINK_STAT_RDY)) != + SLINK_STAT_RDY) + tm++; + + else if (!(status SLINK_STAT_RXF_EMPTY)) { + tmpdin = readl(regs-rx_fifo); + is_read = 1; + + /* swap bytes read in */ + if (din != NULL) { + for (i = bytes - 1; i = 0; --i) { + din[i] = tmpdin 0xff; + tmpdin = 8; + } +
Re: [U-Boot] [PATCH v2 8/9] tegra: add SPI SLINK driver
On Mon, Jan 14, 2013 at 10:49:53AM -0800, Stephen Warren wrote: On 01/12/2013 09:56 AM, Simon Glass wrote: Hi, On Sat, Jan 12, 2013 at 1:07 AM, Allen Martin amar...@nvidia.com wrote: Add driver for tegra SPI SLINK style driver. This controller is similar to the tegra20 SPI SFLASH controller. The difference is that the SLINK controller is a genernal purpose SPI controller and the SFLASH controller is special purpose and can only talk to FLASH devices. In addition there are potentially many instances of an SLINK controller on tegra and only a single instance of SFLASH. Tegra20 is currently ths only version of tegra that instantiates an SFLASH controller. This driver supports basic PIO mode of operation and is configurable (CONFIG_OF_CONTROL) to be driven off devicetree bindings. Up to 4 devices per controller may be attached, although typically only a single chip select line is exposed from tegra per controller so in reality this is usually limited to 1. To enable this driver, use CONFIG_TEGRA_SLINK diff --git a/drivers/spi/tegra_slink.c b/drivers/spi/tegra_slink.c +#ifdef CONFIG_OF_CONTROL You probably don't need this ifdef If we did assume CONFIG_OF_CONTROL was on, then we could get rid of the previous patch; all the device addresses would come from device tree, so there would be no need to add them to any header file:-) I took Simon's comment to mean it's safe to include fdtdec.h even if the fdt code is ifdef'ed out. +void spi_init(void) +{ + int node = 0, i; + struct tegra_spi_ctrl *ctrl; blank line here + for (i = 0; i CONFIG_TEGRA_SLINK_CTRLS; i++) { + ctrl = spi_ctrls[i]; +#ifdef CONFIG_OF_CONTROL + node = fdtdec_next_compatible(gd-fdt_blob, node, + COMPAT_NVIDIA_TEGRA20_SLINK); + if (!node) + break; I think you should be using fdtdec_find_aliases_for_id() so that aliases work. I strongly believe we shouldn't be using aliases for enumeration, which is what fdtdec_find_aliases_for_id() does, IIRC. Instead, we should enumerate all the devices in the correct fashion, and then apply aliases as a separate step if they exists. Hence, I believe it's not correct to use fdtdec_find_aliases_for_id() anywhere. I'm a bit confused about the usage of fdt aliases in u-boot. My understanding of aliases is that they are intended to give drivers hints about device naming. Since u-boot doesn't really name devices, what are aliases supposed to do? -Allen -- nvpublic ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH v2 8/9] tegra: add SPI SLINK driver
Add driver for tegra SPI SLINK style driver. This controller is similar to the tegra20 SPI SFLASH controller. The difference is that the SLINK controller is a genernal purpose SPI controller and the SFLASH controller is special purpose and can only talk to FLASH devices. In addition there are potentially many instances of an SLINK controller on tegra and only a single instance of SFLASH. Tegra20 is currently ths only version of tegra that instantiates an SFLASH controller. This driver supports basic PIO mode of operation and is configurable (CONFIG_OF_CONTROL) to be driven off devicetree bindings. Up to 4 devices per controller may be attached, although typically only a single chip select line is exposed from tegra per controller so in reality this is usually limited to 1. To enable this driver, use CONFIG_TEGRA_SLINK Signed-off-by: Allen Martin amar...@nvidia.com --- arch/arm/include/asm/arch-tegra/tegra_slink.h | 84 +++ board/nvidia/common/board.c |3 +- drivers/spi/Makefile |1 + drivers/spi/tegra_slink.c | 335 + include/fdtdec.h |1 + lib/fdtdec.c |1 + 6 files changed, 424 insertions(+), 1 deletion(-) create mode 100644 arch/arm/include/asm/arch-tegra/tegra_slink.h create mode 100644 drivers/spi/tegra_slink.c diff --git a/arch/arm/include/asm/arch-tegra/tegra_slink.h b/arch/arm/include/asm/arch-tegra/tegra_slink.h new file mode 100644 index 000..74804b5 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra/tegra_slink.h @@ -0,0 +1,84 @@ +/* + * NVIDIA Tegra SPI-SLINK controller + * + * Copyright 2010-2013 NVIDIA Corporation + * + * This software may be used and distributed according to the + * terms of the GNU Public License, Version 2, incorporated + * herein by reference. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * Version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _TEGRA_SLINK_H_ +#define _TEGRA_SLINK_H_ + +#include asm/types.h + +struct slink_tegra { + u32 command;/* SLINK_COMMAND_0 register */ + u32 command2; /* SLINK_COMMAND2_0 reg */ + u32 status; /* SLINK_STATUS_0 register */ + u32 reserved; /* Reserved offset 0C */ + u32 mas_data; /* SLINK_MAS_DATA_0 reg */ + u32 slav_data; /* SLINK_SLAVE_DATA_0 reg */ + u32 dma_ctl;/* SLINK_DMA_CTL_0 register */ + u32 status2;/* SLINK_STATUS2_0 reg */ + u32 rsvd[56]; /* 0x20 to 0xFF reserved */ + u32 tx_fifo;/* SLINK_TX_FIFO_0 reg off 100h */ + u32 rsvd2[31]; /* 0x104 to 0x17F reserved */ + u32 rx_fifo;/* SLINK_RX_FIFO_0 reg off 180h */ +}; + +/* COMMAND */ +#define SLINK_CMD_ENB (1 31) +#define SLINK_CMD_GO (1 30) +#define SLINK_CMD_M_S (1 28) +#define SLINK_CMD_CK_SDA (1 21) +#define SLINK_CMD_CS_POL (1 13) +#define SLINK_CMD_CS_VAL (1 12) +#define SLINK_CMD_CS_SOFT (1 11) +#define SLINK_CMD_BIT_LENGTH (1 4) +#define SLINK_CMD_BIT_LENGTH_MASK 0x001F +/* COMMAND2 */ +#define SLINK_CMD2_TXEN(1 30) +#define SLINK_CMD2_RXEN(1 31) +#define SLINK_CMD2_SS_EN (1 18) +#define SLINK_CMD2_SS_EN_SHIFT 18 +#define SLINK_CMD2_SS_EN_MASK 0x000C +#define SLINK_CMD2_CS_ACTIVE_BETWEEN (1 17) +/* STATUS */ +#define SLINK_STAT_BSY (1 31) +#define SLINK_STAT_RDY (1 30) +#define SLINK_STAT_ERR (1 29) +#define SLINK_STAT_RXF_FLUSH (1 27) +#define SLINK_STAT_TXF_FLUSH (1 26) +#define SLINK_STAT_RXF_OVF (1 25) +#define SLINK_STAT_TXF_UNR (1 24) +#define SLINK_STAT_RXF_EMPTY (1 23) +#define SLINK_STAT_RXF_FULL(1 22) +#define SLINK_STAT_TXF_EMPTY (1 21) +#define SLINK_STAT_TXF_FULL(1 20) +#define SLINK_STAT_TXF_OVF (1 19) +#define SLINK_STAT_RXF_UNR (1 18) +#define SLINK_STAT_CUR_BLKCNT (1 15) +/* STATUS2 */ +#define SLINK_STAT2_RXF_FULL_CNT (1 16) +#define SLINK_STAT2_TXF_FULL_CNT (1 0) + +#define SPI_TIMEOUT1000 +#define TEGRA_SPI_MAX_FREQ 5200 + +#endif /* _TEGRA_SLINK_H_ */ diff
Re: [U-Boot] [PATCH v2 8/9] tegra: add SPI SLINK driver
Hi, On Sat, Jan 12, 2013 at 1:07 AM, Allen Martin amar...@nvidia.com wrote: Add driver for tegra SPI SLINK style driver. This controller is similar to the tegra20 SPI SFLASH controller. The difference is that the SLINK controller is a genernal purpose SPI controller and the SFLASH controller is special purpose and can only talk to FLASH devices. In addition there are potentially many instances of an SLINK controller on tegra and only a single instance of SFLASH. Tegra20 is currently ths only version of tegra that instantiates an SFLASH controller. This driver supports basic PIO mode of operation and is configurable (CONFIG_OF_CONTROL) to be driven off devicetree bindings. Up to 4 devices per controller may be attached, although typically only a single chip select line is exposed from tegra per controller so in reality this is usually limited to 1. To enable this driver, use CONFIG_TEGRA_SLINK A few comments - note I am on holiday next week so please don't wait for my response on the next version. Signed-off-by: Allen Martin amar...@nvidia.com --- arch/arm/include/asm/arch-tegra/tegra_slink.h | 84 +++ board/nvidia/common/board.c |3 +- drivers/spi/Makefile |1 + drivers/spi/tegra_slink.c | 335 + include/fdtdec.h |1 + lib/fdtdec.c |1 + 6 files changed, 424 insertions(+), 1 deletion(-) create mode 100644 arch/arm/include/asm/arch-tegra/tegra_slink.h create mode 100644 drivers/spi/tegra_slink.c diff --git a/arch/arm/include/asm/arch-tegra/tegra_slink.h b/arch/arm/include/asm/arch-tegra/tegra_slink.h new file mode 100644 index 000..74804b5 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra/tegra_slink.h @@ -0,0 +1,84 @@ +/* + * NVIDIA Tegra SPI-SLINK controller + * + * Copyright 2010-2013 NVIDIA Corporation + * + * This software may be used and distributed according to the + * terms of the GNU Public License, Version 2, incorporated + * herein by reference. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * Version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _TEGRA_SLINK_H_ +#define _TEGRA_SLINK_H_ + +#include asm/types.h + +struct slink_tegra { + u32 command;/* SLINK_COMMAND_0 register */ + u32 command2; /* SLINK_COMMAND2_0 reg */ + u32 status; /* SLINK_STATUS_0 register */ + u32 reserved; /* Reserved offset 0C */ + u32 mas_data; /* SLINK_MAS_DATA_0 reg */ + u32 slav_data; /* SLINK_SLAVE_DATA_0 reg */ + u32 dma_ctl;/* SLINK_DMA_CTL_0 register */ + u32 status2;/* SLINK_STATUS2_0 reg */ + u32 rsvd[56]; /* 0x20 to 0xFF reserved */ + u32 tx_fifo;/* SLINK_TX_FIFO_0 reg off 100h */ + u32 rsvd2[31]; /* 0x104 to 0x17F reserved */ + u32 rx_fifo;/* SLINK_RX_FIFO_0 reg off 180h */ +}; + +/* COMMAND */ +#define SLINK_CMD_ENB (1 31) +#define SLINK_CMD_GO (1 30) +#define SLINK_CMD_M_S (1 28) +#define SLINK_CMD_CK_SDA (1 21) +#define SLINK_CMD_CS_POL (1 13) +#define SLINK_CMD_CS_VAL (1 12) +#define SLINK_CMD_CS_SOFT (1 11) +#define SLINK_CMD_BIT_LENGTH (1 4) +#define SLINK_CMD_BIT_LENGTH_MASK 0x001F +/* COMMAND2 */ +#define SLINK_CMD2_TXEN(1 30) +#define SLINK_CMD2_RXEN(1 31) +#define SLINK_CMD2_SS_EN (1 18) +#define SLINK_CMD2_SS_EN_SHIFT 18 +#define SLINK_CMD2_SS_EN_MASK 0x000C +#define SLINK_CMD2_CS_ACTIVE_BETWEEN (1 17) +/* STATUS */ +#define SLINK_STAT_BSY (1 31) +#define SLINK_STAT_RDY (1 30) +#define SLINK_STAT_ERR (1 29) +#define SLINK_STAT_RXF_FLUSH (1 27) +#define SLINK_STAT_TXF_FLUSH (1 26) +#define SLINK_STAT_RXF_OVF (1 25) +#define SLINK_STAT_TXF_UNR (1 24) +#define SLINK_STAT_RXF_EMPTY (1 23) +#define SLINK_STAT_RXF_FULL(1 22) +#define SLINK_STAT_TXF_EMPTY (1 21) +#define SLINK_STAT_TXF_FULL(1 20) +#define SLINK_STAT_TXF_OVF (1 19) +#define SLINK_STAT_RXF_UNR