* [U-Boot] [PATCH V3] exynos: spl: Add a custom spi copy function
@ 2013-10-08 13:12 Rajeshwari S Shinde
2013-10-09 7:55 ` Rajeshwari Birje
0 siblings, 1 reply; 5+ messages in thread
From: Rajeshwari S Shinde @ 2013-10-08 13:12 UTC (permalink / raw)
To: u-boot
This patch implements a custom spi_copy funtion to copy u-boot from SF
to RAM. This is faster then iROM spi_copy funtion as this runs spi at
50Mhz and also in WORD mode of operation.
Changed a printf in pinmux.c to debug just to avoid the compilation
error in SPL.
Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
Signed-off-by: Tom Wai-Hong Tam <waihong@chromium.org>
Signed-off-by: Rajeshwari S Shinde <rajeshwari.s@samsung.com>
---
Based on following patch yet to be merged:
"[U-Boot] [PATCH 4/4] spi: exynos: Support word transfers"
Changes in V2:
- Corrected the commit message.
- Added a SPI timeout check.
- Corrected the comments.
Changes in V3:
- Rebased on the latest u-boot-spi tree.
arch/arm/cpu/armv7/exynos/pinmux.c | 2 +-
arch/arm/cpu/armv7/exynos/spl_boot.c | 122 ++++++++++++++++++++++++++++++++-
arch/arm/include/asm/arch-exynos/spi.h | 1 +
include/configs/exynos5250-dt.h | 2 +
4 files changed, 123 insertions(+), 4 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c
index 8002bce..74cc700 100644
--- a/arch/arm/cpu/armv7/exynos/pinmux.c
+++ b/arch/arm/cpu/armv7/exynos/pinmux.c
@@ -462,7 +462,7 @@ static int exynos4_pinmux_config(int peripheral, int flags)
case PERIPH_ID_SDMMC1:
case PERIPH_ID_SDMMC3:
case PERIPH_ID_SDMMC4:
- printf("SDMMC device %d not implemented\n", peripheral);
+ debug("SDMMC device %d not implemented\n", peripheral);
return -1;
default:
debug("%s: invalid peripheral %d", __func__, peripheral);
diff --git a/arch/arm/cpu/armv7/exynos/spl_boot.c b/arch/arm/cpu/armv7/exynos/spl_boot.c
index 3651c00..6faf13f 100644
--- a/arch/arm/cpu/armv7/exynos/spl_boot.c
+++ b/arch/arm/cpu/armv7/exynos/spl_boot.c
@@ -10,8 +10,11 @@
#include <asm/arch/clock.h>
#include <asm/arch/clk.h>
#include <asm/arch/dmc.h>
+#include <asm/arch/periph.h>
+#include <asm/arch/pinmux.h>
#include <asm/arch/power.h>
#include <asm/arch/spl.h>
+#include <asm/arch/spi.h>
#include "common_setup.h"
#include "clock_init.h"
@@ -59,6 +62,119 @@ static int config_branch_prediction(int set_cr_z)
}
#endif
+static void spi_rx_tx(struct exynos_spi *regs, int todo,
+ void *dinp, void const *doutp, int i)
+{
+ uint *rxp = (uint *)(dinp + (i * (32 * 1024)));
+ int rx_lvl, tx_lvl;
+ uint out_bytes, in_bytes;
+
+ out_bytes = todo;
+ in_bytes = todo;
+ setbits_le32(®s->ch_cfg, SPI_CH_RST);
+ clrbits_le32(®s->ch_cfg, SPI_CH_RST);
+ writel(((todo * 8) / 32) | SPI_PACKET_CNT_EN, ®s->pkt_cnt);
+
+ while (in_bytes) {
+ uint32_t spi_sts;
+ int temp;
+
+ spi_sts = readl(®s->spi_sts);
+ rx_lvl = ((spi_sts >> 15) & 0x7f);
+ tx_lvl = ((spi_sts >> 6) & 0x7f);
+ while (tx_lvl < 32 && out_bytes) {
+ temp = 0xffffffff;
+ writel(temp, ®s->tx_data);
+ out_bytes -= 4;
+ tx_lvl += 4;
+ }
+ while (rx_lvl >= 4 && in_bytes) {
+ temp = readl(®s->rx_data);
+ if (rxp)
+ *rxp++ = temp;
+ in_bytes -= 4;
+ rx_lvl -= 4;
+ }
+ }
+}
+
+/*
+ * Copy uboot from spi flash to RAM
+ *
+ * @parma uboot_size size of u-boot to copy
+ * @param uboot_addr address in u-boot to copy
+ */
+static void exynos_spi_copy(unsigned int uboot_size, unsigned int uboot_addr)
+{
+ int upto, todo;
+ int i, timeout = 100;
+ struct exynos_spi *regs = (struct exynos_spi *)CONFIG_ENV_SPI_BASE;
+
+ set_spi_clk(PERIPH_ID_SPI1, 50000000); /* set spi clock to 50Mhz */
+ /* set the spi1 GPIO */
+ exynos_pinmux_config(PERIPH_ID_SPI1, PINMUX_FLAG_NONE);
+
+ /* set pktcnt and enable it */
+ writel(4 | SPI_PACKET_CNT_EN, ®s->pkt_cnt);
+ /* set FB_CLK_SEL */
+ writel(SPI_FB_DELAY_180, ®s->fb_clk);
+ /* set CH_WIDTH and BUS_WIDTH as word */
+ setbits_le32(®s->mode_cfg, SPI_MODE_CH_WIDTH_WORD |
+ SPI_MODE_BUS_WIDTH_WORD);
+ clrbits_le32(®s->ch_cfg, SPI_CH_CPOL_L); /* CPOL: active high */
+
+ /* clear rx and tx channel if set priveously */
+ clrbits_le32(®s->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON);
+
+ setbits_le32(®s->swap_cfg, SPI_RX_SWAP_EN |
+ SPI_RX_BYTE_SWAP |
+ SPI_RX_HWORD_SWAP);
+
+ /* do a soft reset */
+ setbits_le32(®s->ch_cfg, SPI_CH_RST);
+ clrbits_le32(®s->ch_cfg, SPI_CH_RST);
+
+ /* now set rx and tx channel ON */
+ setbits_le32(®s->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON | SPI_CH_HS_EN);
+ clrbits_le32(®s->cs_reg, SPI_SLAVE_SIG_INACT); /* CS low */
+
+ /* Send read instruction (0x3h) followed by a 24 bit addr */
+ writel((SF_READ_DATA_CMD << 24) | SPI_FLASH_UBOOT_POS, ®s->tx_data);
+
+ /* waiting for TX done */
+ while (!(readl(®s->spi_sts) & SPI_ST_TX_DONE)) {
+ if (!timeout) {
+ debug("SPI TIMEOUT\n");
+ break;
+ }
+ timeout--;
+ }
+
+ for (upto = 0, i = 0; upto < uboot_size; upto += todo, i++) {
+ todo = min(uboot_size - upto, (1 << 15));
+ spi_rx_tx(regs, todo, (void *)(uboot_addr),
+ (void *)(SPI_FLASH_UBOOT_POS), i);
+ }
+
+ setbits_le32(®s->cs_reg, SPI_SLAVE_SIG_INACT);/* make the CS high */
+
+ /*
+ * Let put controller mode to BYTE as
+ * SPI driver does not support WORD mode yet
+ */
+ clrbits_le32(®s->mode_cfg, SPI_MODE_CH_WIDTH_WORD |
+ SPI_MODE_BUS_WIDTH_WORD);
+ writel(0, ®s->swap_cfg);
+
+ /*
+ * Flush spi tx, rx fifos and reset the SPI controller
+ * and clear rx/tx channel
+ */
+ clrsetbits_le32(®s->ch_cfg, SPI_CH_HS_EN, SPI_CH_RST);
+ clrbits_le32(®s->ch_cfg, SPI_CH_RST);
+ clrbits_le32(®s->ch_cfg, SPI_TX_CH_ON | SPI_RX_CH_ON);
+}
+
/*
* Copy U-boot from mmc to RAM:
* COPY_BL2_FNPTR_ADDR: Address in iRAM, which Contains
@@ -70,6 +186,7 @@ void copy_uboot_to_ram(void)
u32 (*copy_bl2)(u32 offset, u32 nblock, u32 dst) = NULL;
u32 offset = 0, size = 0;
+ struct spl_machine_param *param = spl_get_machine_params();
#ifdef CONFIG_SUPPORT_EMMC_BOOT
u32 (*copy_bl2_from_emmc)(u32 nblock, u32 dst);
void (*end_bootop_from_emmc)(void);
@@ -91,9 +208,8 @@ void copy_uboot_to_ram(void)
switch (bootmode) {
#ifdef CONFIG_SPI_BOOTING
case BOOT_MODE_SERIAL:
- offset = SPI_FLASH_UBOOT_POS;
- size = CONFIG_BL2_SIZE;
- copy_bl2 = get_irom_func(SPI_INDEX);
+ /* Customised function to copy u-boot from SF */
+ exynos_spi_copy(param->uboot_size, CONFIG_SYS_TEXT_BASE);
break;
#endif
case BOOT_MODE_MMC:
diff --git a/arch/arm/include/asm/arch-exynos/spi.h b/arch/arm/include/asm/arch-exynos/spi.h
index 147c1a7..0ba931b 100644
--- a/arch/arm/include/asm/arch-exynos/spi.h
+++ b/arch/arm/include/asm/arch-exynos/spi.h
@@ -30,6 +30,7 @@ struct exynos_spi {
#define EXYNOS_SPI_MAX_FREQ 50000000
#define SPI_TIMEOUT_MS 10
+#define SF_READ_DATA_CMD 0x3
/* SPI_CHCFG */
#define SPI_CH_HS_EN (1 << 6)
diff --git a/include/configs/exynos5250-dt.h b/include/configs/exynos5250-dt.h
index 8c21909..1d32396 100644
--- a/include/configs/exynos5250-dt.h
+++ b/include/configs/exynos5250-dt.h
@@ -154,6 +154,7 @@
#define COPY_BL2_FNPTR_ADDR 0x02020030
#define CONFIG_SPL_LIBCOMMON_SUPPORT
+#define CONFIG_SPL_GPIO_SUPPORT
/* specific .lds file */
#define CONFIG_SPL_LDSCRIPT "board/samsung/common/exynos-uboot-spl.lds"
@@ -292,6 +293,7 @@
/* SPI */
#define CONFIG_ENV_IS_IN_SPI_FLASH
#define CONFIG_SPI_FLASH
+#define CONFIG_ENV_SPI_BASE 0x12D30000
#ifdef CONFIG_SPI_FLASH
#define CONFIG_EXYNOS_SPI
--
1.7.12.4
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [U-Boot] [PATCH V3] exynos: spl: Add a custom spi copy function
2013-10-08 13:12 [U-Boot] [PATCH V3] exynos: spl: Add a custom spi copy function Rajeshwari S Shinde
@ 2013-10-09 7:55 ` Rajeshwari Birje
2013-12-02 8:48 ` Minkyu Kang
0 siblings, 1 reply; 5+ messages in thread
From: Rajeshwari Birje @ 2013-10-09 7:55 UTC (permalink / raw)
To: u-boot
Hi Minkyu Kang,
Since this patch is related to arch/arm spi booting, I had a doubt
where would it get merged in u-boot-samsung.git or u-boot-spi.git.
This patch is based on "[U-Boot] [PATCH 4/4] spi: exynos: Support word
transfers" which is already merged in u-boot-spi.git.
Regards,
Rajeshwari Shinde.
On Tue, Oct 8, 2013 at 6:42 PM, Rajeshwari S Shinde
<rajeshwari.s@samsung.com> wrote:
> This patch implements a custom spi_copy funtion to copy u-boot from SF
> to RAM. This is faster then iROM spi_copy funtion as this runs spi at
> 50Mhz and also in WORD mode of operation.
>
> Changed a printf in pinmux.c to debug just to avoid the compilation
> error in SPL.
>
> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
> Signed-off-by: Tom Wai-Hong Tam <waihong@chromium.org>
> Signed-off-by: Rajeshwari S Shinde <rajeshwari.s@samsung.com>
> ---
> Based on following patch yet to be merged:
> "[U-Boot] [PATCH 4/4] spi: exynos: Support word transfers"
> Changes in V2:
> - Corrected the commit message.
> - Added a SPI timeout check.
> - Corrected the comments.
> Changes in V3:
> - Rebased on the latest u-boot-spi tree.
> arch/arm/cpu/armv7/exynos/pinmux.c | 2 +-
> arch/arm/cpu/armv7/exynos/spl_boot.c | 122 ++++++++++++++++++++++++++++++++-
> arch/arm/include/asm/arch-exynos/spi.h | 1 +
> include/configs/exynos5250-dt.h | 2 +
> 4 files changed, 123 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c
> index 8002bce..74cc700 100644
> --- a/arch/arm/cpu/armv7/exynos/pinmux.c
> +++ b/arch/arm/cpu/armv7/exynos/pinmux.c
> @@ -462,7 +462,7 @@ static int exynos4_pinmux_config(int peripheral, int flags)
> case PERIPH_ID_SDMMC1:
> case PERIPH_ID_SDMMC3:
> case PERIPH_ID_SDMMC4:
> - printf("SDMMC device %d not implemented\n", peripheral);
> + debug("SDMMC device %d not implemented\n", peripheral);
> return -1;
> default:
> debug("%s: invalid peripheral %d", __func__, peripheral);
> diff --git a/arch/arm/cpu/armv7/exynos/spl_boot.c b/arch/arm/cpu/armv7/exynos/spl_boot.c
> index 3651c00..6faf13f 100644
> --- a/arch/arm/cpu/armv7/exynos/spl_boot.c
> +++ b/arch/arm/cpu/armv7/exynos/spl_boot.c
> @@ -10,8 +10,11 @@
> #include <asm/arch/clock.h>
> #include <asm/arch/clk.h>
> #include <asm/arch/dmc.h>
> +#include <asm/arch/periph.h>
> +#include <asm/arch/pinmux.h>
> #include <asm/arch/power.h>
> #include <asm/arch/spl.h>
> +#include <asm/arch/spi.h>
>
> #include "common_setup.h"
> #include "clock_init.h"
> @@ -59,6 +62,119 @@ static int config_branch_prediction(int set_cr_z)
> }
> #endif
>
> +static void spi_rx_tx(struct exynos_spi *regs, int todo,
> + void *dinp, void const *doutp, int i)
> +{
> + uint *rxp = (uint *)(dinp + (i * (32 * 1024)));
> + int rx_lvl, tx_lvl;
> + uint out_bytes, in_bytes;
> +
> + out_bytes = todo;
> + in_bytes = todo;
> + setbits_le32(®s->ch_cfg, SPI_CH_RST);
> + clrbits_le32(®s->ch_cfg, SPI_CH_RST);
> + writel(((todo * 8) / 32) | SPI_PACKET_CNT_EN, ®s->pkt_cnt);
> +
> + while (in_bytes) {
> + uint32_t spi_sts;
> + int temp;
> +
> + spi_sts = readl(®s->spi_sts);
> + rx_lvl = ((spi_sts >> 15) & 0x7f);
> + tx_lvl = ((spi_sts >> 6) & 0x7f);
> + while (tx_lvl < 32 && out_bytes) {
> + temp = 0xffffffff;
> + writel(temp, ®s->tx_data);
> + out_bytes -= 4;
> + tx_lvl += 4;
> + }
> + while (rx_lvl >= 4 && in_bytes) {
> + temp = readl(®s->rx_data);
> + if (rxp)
> + *rxp++ = temp;
> + in_bytes -= 4;
> + rx_lvl -= 4;
> + }
> + }
> +}
> +
> +/*
> + * Copy uboot from spi flash to RAM
> + *
> + * @parma uboot_size size of u-boot to copy
> + * @param uboot_addr address in u-boot to copy
> + */
> +static void exynos_spi_copy(unsigned int uboot_size, unsigned int uboot_addr)
> +{
> + int upto, todo;
> + int i, timeout = 100;
> + struct exynos_spi *regs = (struct exynos_spi *)CONFIG_ENV_SPI_BASE;
> +
> + set_spi_clk(PERIPH_ID_SPI1, 50000000); /* set spi clock to 50Mhz */
> + /* set the spi1 GPIO */
> + exynos_pinmux_config(PERIPH_ID_SPI1, PINMUX_FLAG_NONE);
> +
> + /* set pktcnt and enable it */
> + writel(4 | SPI_PACKET_CNT_EN, ®s->pkt_cnt);
> + /* set FB_CLK_SEL */
> + writel(SPI_FB_DELAY_180, ®s->fb_clk);
> + /* set CH_WIDTH and BUS_WIDTH as word */
> + setbits_le32(®s->mode_cfg, SPI_MODE_CH_WIDTH_WORD |
> + SPI_MODE_BUS_WIDTH_WORD);
> + clrbits_le32(®s->ch_cfg, SPI_CH_CPOL_L); /* CPOL: active high */
> +
> + /* clear rx and tx channel if set priveously */
> + clrbits_le32(®s->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON);
> +
> + setbits_le32(®s->swap_cfg, SPI_RX_SWAP_EN |
> + SPI_RX_BYTE_SWAP |
> + SPI_RX_HWORD_SWAP);
> +
> + /* do a soft reset */
> + setbits_le32(®s->ch_cfg, SPI_CH_RST);
> + clrbits_le32(®s->ch_cfg, SPI_CH_RST);
> +
> + /* now set rx and tx channel ON */
> + setbits_le32(®s->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON | SPI_CH_HS_EN);
> + clrbits_le32(®s->cs_reg, SPI_SLAVE_SIG_INACT); /* CS low */
> +
> + /* Send read instruction (0x3h) followed by a 24 bit addr */
> + writel((SF_READ_DATA_CMD << 24) | SPI_FLASH_UBOOT_POS, ®s->tx_data);
> +
> + /* waiting for TX done */
> + while (!(readl(®s->spi_sts) & SPI_ST_TX_DONE)) {
> + if (!timeout) {
> + debug("SPI TIMEOUT\n");
> + break;
> + }
> + timeout--;
> + }
> +
> + for (upto = 0, i = 0; upto < uboot_size; upto += todo, i++) {
> + todo = min(uboot_size - upto, (1 << 15));
> + spi_rx_tx(regs, todo, (void *)(uboot_addr),
> + (void *)(SPI_FLASH_UBOOT_POS), i);
> + }
> +
> + setbits_le32(®s->cs_reg, SPI_SLAVE_SIG_INACT);/* make the CS high */
> +
> + /*
> + * Let put controller mode to BYTE as
> + * SPI driver does not support WORD mode yet
> + */
> + clrbits_le32(®s->mode_cfg, SPI_MODE_CH_WIDTH_WORD |
> + SPI_MODE_BUS_WIDTH_WORD);
> + writel(0, ®s->swap_cfg);
> +
> + /*
> + * Flush spi tx, rx fifos and reset the SPI controller
> + * and clear rx/tx channel
> + */
> + clrsetbits_le32(®s->ch_cfg, SPI_CH_HS_EN, SPI_CH_RST);
> + clrbits_le32(®s->ch_cfg, SPI_CH_RST);
> + clrbits_le32(®s->ch_cfg, SPI_TX_CH_ON | SPI_RX_CH_ON);
> +}
> +
> /*
> * Copy U-boot from mmc to RAM:
> * COPY_BL2_FNPTR_ADDR: Address in iRAM, which Contains
> @@ -70,6 +186,7 @@ void copy_uboot_to_ram(void)
>
> u32 (*copy_bl2)(u32 offset, u32 nblock, u32 dst) = NULL;
> u32 offset = 0, size = 0;
> + struct spl_machine_param *param = spl_get_machine_params();
> #ifdef CONFIG_SUPPORT_EMMC_BOOT
> u32 (*copy_bl2_from_emmc)(u32 nblock, u32 dst);
> void (*end_bootop_from_emmc)(void);
> @@ -91,9 +208,8 @@ void copy_uboot_to_ram(void)
> switch (bootmode) {
> #ifdef CONFIG_SPI_BOOTING
> case BOOT_MODE_SERIAL:
> - offset = SPI_FLASH_UBOOT_POS;
> - size = CONFIG_BL2_SIZE;
> - copy_bl2 = get_irom_func(SPI_INDEX);
> + /* Customised function to copy u-boot from SF */
> + exynos_spi_copy(param->uboot_size, CONFIG_SYS_TEXT_BASE);
> break;
> #endif
> case BOOT_MODE_MMC:
> diff --git a/arch/arm/include/asm/arch-exynos/spi.h b/arch/arm/include/asm/arch-exynos/spi.h
> index 147c1a7..0ba931b 100644
> --- a/arch/arm/include/asm/arch-exynos/spi.h
> +++ b/arch/arm/include/asm/arch-exynos/spi.h
> @@ -30,6 +30,7 @@ struct exynos_spi {
> #define EXYNOS_SPI_MAX_FREQ 50000000
>
> #define SPI_TIMEOUT_MS 10
> +#define SF_READ_DATA_CMD 0x3
>
> /* SPI_CHCFG */
> #define SPI_CH_HS_EN (1 << 6)
> diff --git a/include/configs/exynos5250-dt.h b/include/configs/exynos5250-dt.h
> index 8c21909..1d32396 100644
> --- a/include/configs/exynos5250-dt.h
> +++ b/include/configs/exynos5250-dt.h
> @@ -154,6 +154,7 @@
> #define COPY_BL2_FNPTR_ADDR 0x02020030
>
> #define CONFIG_SPL_LIBCOMMON_SUPPORT
> +#define CONFIG_SPL_GPIO_SUPPORT
>
> /* specific .lds file */
> #define CONFIG_SPL_LDSCRIPT "board/samsung/common/exynos-uboot-spl.lds"
> @@ -292,6 +293,7 @@
> /* SPI */
> #define CONFIG_ENV_IS_IN_SPI_FLASH
> #define CONFIG_SPI_FLASH
> +#define CONFIG_ENV_SPI_BASE 0x12D30000
>
> #ifdef CONFIG_SPI_FLASH
> #define CONFIG_EXYNOS_SPI
> --
> 1.7.12.4
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
--
Regards,
Rajeshwari Shinde
^ permalink raw reply [flat|nested] 5+ messages in thread
* [U-Boot] [PATCH V3] exynos: spl: Add a custom spi copy function
2013-10-09 7:55 ` Rajeshwari Birje
@ 2013-12-02 8:48 ` Minkyu Kang
2013-12-02 13:17 ` Rajeshwari Birje
0 siblings, 1 reply; 5+ messages in thread
From: Minkyu Kang @ 2013-12-02 8:48 UTC (permalink / raw)
To: u-boot
On 09/10/13 16:55, Rajeshwari Birje wrote:
> Hi Minkyu Kang,
>
> Since this patch is related to arch/arm spi booting, I had a doubt
> where would it get merged in u-boot-samsung.git or u-boot-spi.git.
>
> This patch is based on "[U-Boot] [PATCH 4/4] spi: exynos: Support word
> transfers" which is already merged in u-boot-spi.git.
Now, that patch is merged to u-boot-samsung.
Anyway I'm OK to pick this patch to u-boot-spi.
>
> Regards,
> Rajeshwari Shinde.
>
> On Tue, Oct 8, 2013 at 6:42 PM, Rajeshwari S Shinde
> <rajeshwari.s@samsung.com> wrote:
>> This patch implements a custom spi_copy funtion to copy u-boot from SF
>> to RAM. This is faster then iROM spi_copy funtion as this runs spi at
>> 50Mhz and also in WORD mode of operation.
>>
>> Changed a printf in pinmux.c to debug just to avoid the compilation
>> error in SPL.
>>
>> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
>> Signed-off-by: Tom Wai-Hong Tam <waihong@chromium.org>
>> Signed-off-by: Rajeshwari S Shinde <rajeshwari.s@samsung.com>
>> ---
>> Based on following patch yet to be merged:
>> "[U-Boot] [PATCH 4/4] spi: exynos: Support word transfers"
>> Changes in V2:
>> - Corrected the commit message.
>> - Added a SPI timeout check.
>> - Corrected the comments.
>> Changes in V3:
>> - Rebased on the latest u-boot-spi tree.
>> arch/arm/cpu/armv7/exynos/pinmux.c | 2 +-
>> arch/arm/cpu/armv7/exynos/spl_boot.c | 122 ++++++++++++++++++++++++++++++++-
>> arch/arm/include/asm/arch-exynos/spi.h | 1 +
>> include/configs/exynos5250-dt.h | 2 +
>> 4 files changed, 123 insertions(+), 4 deletions(-)
>>
>> diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c
>> index 8002bce..74cc700 100644
>> --- a/arch/arm/cpu/armv7/exynos/pinmux.c
>> +++ b/arch/arm/cpu/armv7/exynos/pinmux.c
>> @@ -462,7 +462,7 @@ static int exynos4_pinmux_config(int peripheral, int flags)
>> case PERIPH_ID_SDMMC1:
>> case PERIPH_ID_SDMMC3:
>> case PERIPH_ID_SDMMC4:
>> - printf("SDMMC device %d not implemented\n", peripheral);
>> + debug("SDMMC device %d not implemented\n", peripheral);
unrelated change.
>> return -1;
>> default:
>> debug("%s: invalid peripheral %d", __func__, peripheral);
>> diff --git a/arch/arm/cpu/armv7/exynos/spl_boot.c b/arch/arm/cpu/armv7/exynos/spl_boot.c
>> index 3651c00..6faf13f 100644
>> --- a/arch/arm/cpu/armv7/exynos/spl_boot.c
>> +++ b/arch/arm/cpu/armv7/exynos/spl_boot.c
>> @@ -10,8 +10,11 @@
>> #include <asm/arch/clock.h>
>> #include <asm/arch/clk.h>
>> #include <asm/arch/dmc.h>
>> +#include <asm/arch/periph.h>
>> +#include <asm/arch/pinmux.h>
>> #include <asm/arch/power.h>
>> #include <asm/arch/spl.h>
>> +#include <asm/arch/spi.h>
>>
>> #include "common_setup.h"
>> #include "clock_init.h"
>> @@ -59,6 +62,119 @@ static int config_branch_prediction(int set_cr_z)
>> }
>> #endif
>>
>> +static void spi_rx_tx(struct exynos_spi *regs, int todo,
>> + void *dinp, void const *doutp, int i)
>> +{
>> + uint *rxp = (uint *)(dinp + (i * (32 * 1024)));
>> + int rx_lvl, tx_lvl;
>> + uint out_bytes, in_bytes;
>> +
>> + out_bytes = todo;
>> + in_bytes = todo;
>> + setbits_le32(®s->ch_cfg, SPI_CH_RST);
>> + clrbits_le32(®s->ch_cfg, SPI_CH_RST);
>> + writel(((todo * 8) / 32) | SPI_PACKET_CNT_EN, ®s->pkt_cnt);
>> +
>> + while (in_bytes) {
>> + uint32_t spi_sts;
>> + int temp;
>> +
>> + spi_sts = readl(®s->spi_sts);
>> + rx_lvl = ((spi_sts >> 15) & 0x7f);
>> + tx_lvl = ((spi_sts >> 6) & 0x7f);
>> + while (tx_lvl < 32 && out_bytes) {
>> + temp = 0xffffffff;
>> + writel(temp, ®s->tx_data);
>> + out_bytes -= 4;
>> + tx_lvl += 4;
>> + }
>> + while (rx_lvl >= 4 && in_bytes) {
>> + temp = readl(®s->rx_data);
>> + if (rxp)
>> + *rxp++ = temp;
>> + in_bytes -= 4;
>> + rx_lvl -= 4;
>> + }
>> + }
>> +}
>> +
>> +/*
>> + * Copy uboot from spi flash to RAM
>> + *
>> + * @parma uboot_size size of u-boot to copy
>> + * @param uboot_addr address in u-boot to copy
>> + */
>> +static void exynos_spi_copy(unsigned int uboot_size, unsigned int uboot_addr)
>> +{
>> + int upto, todo;
>> + int i, timeout = 100;
>> + struct exynos_spi *regs = (struct exynos_spi *)CONFIG_ENV_SPI_BASE;
>> +
>> + set_spi_clk(PERIPH_ID_SPI1, 50000000); /* set spi clock to 50Mhz */
>> + /* set the spi1 GPIO */
>> + exynos_pinmux_config(PERIPH_ID_SPI1, PINMUX_FLAG_NONE);
>> +
>> + /* set pktcnt and enable it */
>> + writel(4 | SPI_PACKET_CNT_EN, ®s->pkt_cnt);
>> + /* set FB_CLK_SEL */
>> + writel(SPI_FB_DELAY_180, ®s->fb_clk);
>> + /* set CH_WIDTH and BUS_WIDTH as word */
>> + setbits_le32(®s->mode_cfg, SPI_MODE_CH_WIDTH_WORD |
>> + SPI_MODE_BUS_WIDTH_WORD);
>> + clrbits_le32(®s->ch_cfg, SPI_CH_CPOL_L); /* CPOL: active high */
>> +
>> + /* clear rx and tx channel if set priveously */
>> + clrbits_le32(®s->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON);
>> +
>> + setbits_le32(®s->swap_cfg, SPI_RX_SWAP_EN |
>> + SPI_RX_BYTE_SWAP |
>> + SPI_RX_HWORD_SWAP);
>> +
>> + /* do a soft reset */
>> + setbits_le32(®s->ch_cfg, SPI_CH_RST);
>> + clrbits_le32(®s->ch_cfg, SPI_CH_RST);
>> +
>> + /* now set rx and tx channel ON */
>> + setbits_le32(®s->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON | SPI_CH_HS_EN);
>> + clrbits_le32(®s->cs_reg, SPI_SLAVE_SIG_INACT); /* CS low */
>> +
>> + /* Send read instruction (0x3h) followed by a 24 bit addr */
>> + writel((SF_READ_DATA_CMD << 24) | SPI_FLASH_UBOOT_POS, ®s->tx_data);
>> +
>> + /* waiting for TX done */
>> + while (!(readl(®s->spi_sts) & SPI_ST_TX_DONE)) {
>> + if (!timeout) {
>> + debug("SPI TIMEOUT\n");
>> + break;
>> + }
>> + timeout--;
>> + }
>> +
>> + for (upto = 0, i = 0; upto < uboot_size; upto += todo, i++) {
>> + todo = min(uboot_size - upto, (1 << 15));
>> + spi_rx_tx(regs, todo, (void *)(uboot_addr),
>> + (void *)(SPI_FLASH_UBOOT_POS), i);
>> + }
>> +
>> + setbits_le32(®s->cs_reg, SPI_SLAVE_SIG_INACT);/* make the CS high */
>> +
>> + /*
>> + * Let put controller mode to BYTE as
>> + * SPI driver does not support WORD mode yet
>> + */
>> + clrbits_le32(®s->mode_cfg, SPI_MODE_CH_WIDTH_WORD |
>> + SPI_MODE_BUS_WIDTH_WORD);
>> + writel(0, ®s->swap_cfg);
>> +
>> + /*
>> + * Flush spi tx, rx fifos and reset the SPI controller
>> + * and clear rx/tx channel
>> + */
>> + clrsetbits_le32(®s->ch_cfg, SPI_CH_HS_EN, SPI_CH_RST);
>> + clrbits_le32(®s->ch_cfg, SPI_CH_RST);
>> + clrbits_le32(®s->ch_cfg, SPI_TX_CH_ON | SPI_RX_CH_ON);
>> +}
>> +
>> /*
>> * Copy U-boot from mmc to RAM:
>> * COPY_BL2_FNPTR_ADDR: Address in iRAM, which Contains
>> @@ -70,6 +186,7 @@ void copy_uboot_to_ram(void)
>>
>> u32 (*copy_bl2)(u32 offset, u32 nblock, u32 dst) = NULL;
>> u32 offset = 0, size = 0;
>> + struct spl_machine_param *param = spl_get_machine_params();
>> #ifdef CONFIG_SUPPORT_EMMC_BOOT
>> u32 (*copy_bl2_from_emmc)(u32 nblock, u32 dst);
>> void (*end_bootop_from_emmc)(void);
>> @@ -91,9 +208,8 @@ void copy_uboot_to_ram(void)
>> switch (bootmode) {
>> #ifdef CONFIG_SPI_BOOTING
>> case BOOT_MODE_SERIAL:
>> - offset = SPI_FLASH_UBOOT_POS;
>> - size = CONFIG_BL2_SIZE;
>> - copy_bl2 = get_irom_func(SPI_INDEX);
>> + /* Customised function to copy u-boot from SF */
>> + exynos_spi_copy(param->uboot_size, CONFIG_SYS_TEXT_BASE);
>> break;
>> #endif
>> case BOOT_MODE_MMC:
>> diff --git a/arch/arm/include/asm/arch-exynos/spi.h b/arch/arm/include/asm/arch-exynos/spi.h
>> index 147c1a7..0ba931b 100644
>> --- a/arch/arm/include/asm/arch-exynos/spi.h
>> +++ b/arch/arm/include/asm/arch-exynos/spi.h
>> @@ -30,6 +30,7 @@ struct exynos_spi {
>> #define EXYNOS_SPI_MAX_FREQ 50000000
>>
>> #define SPI_TIMEOUT_MS 10
>> +#define SF_READ_DATA_CMD 0x3
>>
>> /* SPI_CHCFG */
>> #define SPI_CH_HS_EN (1 << 6)
>> diff --git a/include/configs/exynos5250-dt.h b/include/configs/exynos5250-dt.h
>> index 8c21909..1d32396 100644
>> --- a/include/configs/exynos5250-dt.h
>> +++ b/include/configs/exynos5250-dt.h
>> @@ -154,6 +154,7 @@
>> #define COPY_BL2_FNPTR_ADDR 0x02020030
>>
>> #define CONFIG_SPL_LIBCOMMON_SUPPORT
>> +#define CONFIG_SPL_GPIO_SUPPORT
>>
>> /* specific .lds file */
>> #define CONFIG_SPL_LDSCRIPT "board/samsung/common/exynos-uboot-spl.lds"
>> @@ -292,6 +293,7 @@
>> /* SPI */
>> #define CONFIG_ENV_IS_IN_SPI_FLASH
>> #define CONFIG_SPI_FLASH
>> +#define CONFIG_ENV_SPI_BASE 0x12D30000
>>
>> #ifdef CONFIG_SPI_FLASH
>> #define CONFIG_EXYNOS_SPI
>> --
>> 1.7.12.4
>>
>> _______________________________________________
>> U-Boot mailing list
>> U-Boot at lists.denx.de
>> http://lists.denx.de/mailman/listinfo/u-boot
>
>
>
Thanks,
Minkyu Kang.
^ permalink raw reply [flat|nested] 5+ messages in thread
* [U-Boot] [PATCH V3] exynos: spl: Add a custom spi copy function
2013-12-02 8:48 ` Minkyu Kang
@ 2013-12-02 13:17 ` Rajeshwari Birje
2013-12-03 6:30 ` Minkyu Kang
0 siblings, 1 reply; 5+ messages in thread
From: Rajeshwari Birje @ 2013-12-02 13:17 UTC (permalink / raw)
To: u-boot
Hi Minkyu Kang,
Thank you for comments.
On Mon, Dec 2, 2013 at 2:18 PM, Minkyu Kang <mk7.kang@samsung.com> wrote:
> On 09/10/13 16:55, Rajeshwari Birje wrote:
>> Hi Minkyu Kang,
>>
>> Since this patch is related to arch/arm spi booting, I had a doubt
>> where would it get merged in u-boot-samsung.git or u-boot-spi.git.
>>
>> This patch is based on "[U-Boot] [PATCH 4/4] spi: exynos: Support word
>> transfers" which is already merged in u-boot-spi.git.
>
> Now, that patch is merged to u-boot-samsung.
> Anyway I'm OK to pick this patch to u-boot-spi.
>
>>
>> Regards,
>> Rajeshwari Shinde.
>>
>> On Tue, Oct 8, 2013 at 6:42 PM, Rajeshwari S Shinde
>> <rajeshwari.s@samsung.com> wrote:
>>> This patch implements a custom spi_copy funtion to copy u-boot from SF
>>> to RAM. This is faster then iROM spi_copy funtion as this runs spi at
>>> 50Mhz and also in WORD mode of operation.
>>>
>>> Changed a printf in pinmux.c to debug just to avoid the compilation
>>> error in SPL.
>>>
>>> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
>>> Signed-off-by: Tom Wai-Hong Tam <waihong@chromium.org>
>>> Signed-off-by: Rajeshwari S Shinde <rajeshwari.s@samsung.com>
>>> ---
>>> Based on following patch yet to be merged:
>>> "[U-Boot] [PATCH 4/4] spi: exynos: Support word transfers"
>>> Changes in V2:
>>> - Corrected the commit message.
>>> - Added a SPI timeout check.
>>> - Corrected the comments.
>>> Changes in V3:
>>> - Rebased on the latest u-boot-spi tree.
>>> arch/arm/cpu/armv7/exynos/pinmux.c | 2 +-
>>> arch/arm/cpu/armv7/exynos/spl_boot.c | 122 ++++++++++++++++++++++++++++++++-
>>> arch/arm/include/asm/arch-exynos/spi.h | 1 +
>>> include/configs/exynos5250-dt.h | 2 +
>>> 4 files changed, 123 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c
>>> index 8002bce..74cc700 100644
>>> --- a/arch/arm/cpu/armv7/exynos/pinmux.c
>>> +++ b/arch/arm/cpu/armv7/exynos/pinmux.c
>>> @@ -462,7 +462,7 @@ static int exynos4_pinmux_config(int peripheral, int flags)
>>> case PERIPH_ID_SDMMC1:
>>> case PERIPH_ID_SDMMC3:
>>> case PERIPH_ID_SDMMC4:
>>> - printf("SDMMC device %d not implemented\n", peripheral);
>>> + debug("SDMMC device %d not implemented\n", peripheral);
>
> unrelated change.
>
As mentioned commit message
"Changed a printf in pinmux.c to debug just to avoid the compilation
error in SPL."
>>> return -1;
>>> default:
>>> debug("%s: invalid peripheral %d", __func__, peripheral);
>>> diff --git a/arch/arm/cpu/armv7/exynos/spl_boot.c b/arch/arm/cpu/armv7/exynos/spl_boot.c
>>> index 3651c00..6faf13f 100644
>>> --- a/arch/arm/cpu/armv7/exynos/spl_boot.c
>>> +++ b/arch/arm/cpu/armv7/exynos/spl_boot.c
>>> @@ -10,8 +10,11 @@
>>> #include <asm/arch/clock.h>
>>> #include <asm/arch/clk.h>
>>> #include <asm/arch/dmc.h>
>>> +#include <asm/arch/periph.h>
>>> +#include <asm/arch/pinmux.h>
>>> #include <asm/arch/power.h>
>>> #include <asm/arch/spl.h>
>>> +#include <asm/arch/spi.h>
>>>
>>> #include "common_setup.h"
>>> #include "clock_init.h"
>>> @@ -59,6 +62,119 @@ static int config_branch_prediction(int set_cr_z)
>>> }
>>> #endif
>>>
>>> +static void spi_rx_tx(struct exynos_spi *regs, int todo,
>>> + void *dinp, void const *doutp, int i)
>>> +{
>>> + uint *rxp = (uint *)(dinp + (i * (32 * 1024)));
>>> + int rx_lvl, tx_lvl;
>>> + uint out_bytes, in_bytes;
>>> +
>>> + out_bytes = todo;
>>> + in_bytes = todo;
>>> + setbits_le32(®s->ch_cfg, SPI_CH_RST);
>>> + clrbits_le32(®s->ch_cfg, SPI_CH_RST);
>>> + writel(((todo * 8) / 32) | SPI_PACKET_CNT_EN, ®s->pkt_cnt);
>>> +
>>> + while (in_bytes) {
>>> + uint32_t spi_sts;
>>> + int temp;
>>> +
>>> + spi_sts = readl(®s->spi_sts);
>>> + rx_lvl = ((spi_sts >> 15) & 0x7f);
>>> + tx_lvl = ((spi_sts >> 6) & 0x7f);
>>> + while (tx_lvl < 32 && out_bytes) {
>>> + temp = 0xffffffff;
>>> + writel(temp, ®s->tx_data);
>>> + out_bytes -= 4;
>>> + tx_lvl += 4;
>>> + }
>>> + while (rx_lvl >= 4 && in_bytes) {
>>> + temp = readl(®s->rx_data);
>>> + if (rxp)
>>> + *rxp++ = temp;
>>> + in_bytes -= 4;
>>> + rx_lvl -= 4;
>>> + }
>>> + }
>>> +}
>>> +
>>> +/*
>>> + * Copy uboot from spi flash to RAM
>>> + *
>>> + * @parma uboot_size size of u-boot to copy
>>> + * @param uboot_addr address in u-boot to copy
>>> + */
>>> +static void exynos_spi_copy(unsigned int uboot_size, unsigned int uboot_addr)
>>> +{
>>> + int upto, todo;
>>> + int i, timeout = 100;
>>> + struct exynos_spi *regs = (struct exynos_spi *)CONFIG_ENV_SPI_BASE;
>>> +
>>> + set_spi_clk(PERIPH_ID_SPI1, 50000000); /* set spi clock to 50Mhz */
>>> + /* set the spi1 GPIO */
>>> + exynos_pinmux_config(PERIPH_ID_SPI1, PINMUX_FLAG_NONE);
>>> +
>>> + /* set pktcnt and enable it */
>>> + writel(4 | SPI_PACKET_CNT_EN, ®s->pkt_cnt);
>>> + /* set FB_CLK_SEL */
>>> + writel(SPI_FB_DELAY_180, ®s->fb_clk);
>>> + /* set CH_WIDTH and BUS_WIDTH as word */
>>> + setbits_le32(®s->mode_cfg, SPI_MODE_CH_WIDTH_WORD |
>>> + SPI_MODE_BUS_WIDTH_WORD);
>>> + clrbits_le32(®s->ch_cfg, SPI_CH_CPOL_L); /* CPOL: active high */
>>> +
>>> + /* clear rx and tx channel if set priveously */
>>> + clrbits_le32(®s->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON);
>>> +
>>> + setbits_le32(®s->swap_cfg, SPI_RX_SWAP_EN |
>>> + SPI_RX_BYTE_SWAP |
>>> + SPI_RX_HWORD_SWAP);
>>> +
>>> + /* do a soft reset */
>>> + setbits_le32(®s->ch_cfg, SPI_CH_RST);
>>> + clrbits_le32(®s->ch_cfg, SPI_CH_RST);
>>> +
>>> + /* now set rx and tx channel ON */
>>> + setbits_le32(®s->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON | SPI_CH_HS_EN);
>>> + clrbits_le32(®s->cs_reg, SPI_SLAVE_SIG_INACT); /* CS low */
>>> +
>>> + /* Send read instruction (0x3h) followed by a 24 bit addr */
>>> + writel((SF_READ_DATA_CMD << 24) | SPI_FLASH_UBOOT_POS, ®s->tx_data);
>>> +
>>> + /* waiting for TX done */
>>> + while (!(readl(®s->spi_sts) & SPI_ST_TX_DONE)) {
>>> + if (!timeout) {
>>> + debug("SPI TIMEOUT\n");
>>> + break;
>>> + }
>>> + timeout--;
>>> + }
>>> +
>>> + for (upto = 0, i = 0; upto < uboot_size; upto += todo, i++) {
>>> + todo = min(uboot_size - upto, (1 << 15));
>>> + spi_rx_tx(regs, todo, (void *)(uboot_addr),
>>> + (void *)(SPI_FLASH_UBOOT_POS), i);
>>> + }
>>> +
>>> + setbits_le32(®s->cs_reg, SPI_SLAVE_SIG_INACT);/* make the CS high */
>>> +
>>> + /*
>>> + * Let put controller mode to BYTE as
>>> + * SPI driver does not support WORD mode yet
>>> + */
>>> + clrbits_le32(®s->mode_cfg, SPI_MODE_CH_WIDTH_WORD |
>>> + SPI_MODE_BUS_WIDTH_WORD);
>>> + writel(0, ®s->swap_cfg);
>>> +
>>> + /*
>>> + * Flush spi tx, rx fifos and reset the SPI controller
>>> + * and clear rx/tx channel
>>> + */
>>> + clrsetbits_le32(®s->ch_cfg, SPI_CH_HS_EN, SPI_CH_RST);
>>> + clrbits_le32(®s->ch_cfg, SPI_CH_RST);
>>> + clrbits_le32(®s->ch_cfg, SPI_TX_CH_ON | SPI_RX_CH_ON);
>>> +}
>>> +
>>> /*
>>> * Copy U-boot from mmc to RAM:
>>> * COPY_BL2_FNPTR_ADDR: Address in iRAM, which Contains
>>> @@ -70,6 +186,7 @@ void copy_uboot_to_ram(void)
>>>
>>> u32 (*copy_bl2)(u32 offset, u32 nblock, u32 dst) = NULL;
>>> u32 offset = 0, size = 0;
>>> + struct spl_machine_param *param = spl_get_machine_params();
>>> #ifdef CONFIG_SUPPORT_EMMC_BOOT
>>> u32 (*copy_bl2_from_emmc)(u32 nblock, u32 dst);
>>> void (*end_bootop_from_emmc)(void);
>>> @@ -91,9 +208,8 @@ void copy_uboot_to_ram(void)
>>> switch (bootmode) {
>>> #ifdef CONFIG_SPI_BOOTING
>>> case BOOT_MODE_SERIAL:
>>> - offset = SPI_FLASH_UBOOT_POS;
>>> - size = CONFIG_BL2_SIZE;
>>> - copy_bl2 = get_irom_func(SPI_INDEX);
>>> + /* Customised function to copy u-boot from SF */
>>> + exynos_spi_copy(param->uboot_size, CONFIG_SYS_TEXT_BASE);
>>> break;
>>> #endif
>>> case BOOT_MODE_MMC:
>>> diff --git a/arch/arm/include/asm/arch-exynos/spi.h b/arch/arm/include/asm/arch-exynos/spi.h
>>> index 147c1a7..0ba931b 100644
>>> --- a/arch/arm/include/asm/arch-exynos/spi.h
>>> +++ b/arch/arm/include/asm/arch-exynos/spi.h
>>> @@ -30,6 +30,7 @@ struct exynos_spi {
>>> #define EXYNOS_SPI_MAX_FREQ 50000000
>>>
>>> #define SPI_TIMEOUT_MS 10
>>> +#define SF_READ_DATA_CMD 0x3
>>>
>>> /* SPI_CHCFG */
>>> #define SPI_CH_HS_EN (1 << 6)
>>> diff --git a/include/configs/exynos5250-dt.h b/include/configs/exynos5250-dt.h
>>> index 8c21909..1d32396 100644
>>> --- a/include/configs/exynos5250-dt.h
>>> +++ b/include/configs/exynos5250-dt.h
>>> @@ -154,6 +154,7 @@
>>> #define COPY_BL2_FNPTR_ADDR 0x02020030
>>>
>>> #define CONFIG_SPL_LIBCOMMON_SUPPORT
>>> +#define CONFIG_SPL_GPIO_SUPPORT
>>>
>>> /* specific .lds file */
>>> #define CONFIG_SPL_LDSCRIPT "board/samsung/common/exynos-uboot-spl.lds"
>>> @@ -292,6 +293,7 @@
>>> /* SPI */
>>> #define CONFIG_ENV_IS_IN_SPI_FLASH
>>> #define CONFIG_SPI_FLASH
>>> +#define CONFIG_ENV_SPI_BASE 0x12D30000
>>>
>>> #ifdef CONFIG_SPI_FLASH
>>> #define CONFIG_EXYNOS_SPI
>>> --
>>> 1.7.12.4
>>>
>>> _______________________________________________
>>> U-Boot mailing list
>>> U-Boot at lists.denx.de
>>> http://lists.denx.de/mailman/listinfo/u-boot
>>
>>
>>
>
> Thanks,
> Minkyu Kang.
>
--
Regards,
Rajeshwari Shinde
^ permalink raw reply [flat|nested] 5+ messages in thread
* [U-Boot] [PATCH V3] exynos: spl: Add a custom spi copy function
2013-12-02 13:17 ` Rajeshwari Birje
@ 2013-12-03 6:30 ` Minkyu Kang
0 siblings, 0 replies; 5+ messages in thread
From: Minkyu Kang @ 2013-12-03 6:30 UTC (permalink / raw)
To: u-boot
On 02/12/13 22:17, Rajeshwari Birje wrote:
> Hi Minkyu Kang,
>
> Thank you for comments.
>
>
>
> On Mon, Dec 2, 2013 at 2:18 PM, Minkyu Kang <mk7.kang@samsung.com> wrote:
>> On 09/10/13 16:55, Rajeshwari Birje wrote:
>>> Hi Minkyu Kang,
>>>
>>> Since this patch is related to arch/arm spi booting, I had a doubt
>>> where would it get merged in u-boot-samsung.git or u-boot-spi.git.
>>>
>>> This patch is based on "[U-Boot] [PATCH 4/4] spi: exynos: Support word
>>> transfers" which is already merged in u-boot-spi.git.
>>
>> Now, that patch is merged to u-boot-samsung.
>> Anyway I'm OK to pick this patch to u-boot-spi.
>>
>>>
>>> Regards,
>>> Rajeshwari Shinde.
>>>
>>> On Tue, Oct 8, 2013 at 6:42 PM, Rajeshwari S Shinde
>>> <rajeshwari.s@samsung.com> wrote:
>>>> This patch implements a custom spi_copy funtion to copy u-boot from SF
>>>> to RAM. This is faster then iROM spi_copy funtion as this runs spi at
>>>> 50Mhz and also in WORD mode of operation.
>>>>
>>>> Changed a printf in pinmux.c to debug just to avoid the compilation
>>>> error in SPL.
>>>>
>>>> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
>>>> Signed-off-by: Tom Wai-Hong Tam <waihong@chromium.org>
>>>> Signed-off-by: Rajeshwari S Shinde <rajeshwari.s@samsung.com>
>>>> ---
>>>> Based on following patch yet to be merged:
>>>> "[U-Boot] [PATCH 4/4] spi: exynos: Support word transfers"
>>>> Changes in V2:
>>>> - Corrected the commit message.
>>>> - Added a SPI timeout check.
>>>> - Corrected the comments.
>>>> Changes in V3:
>>>> - Rebased on the latest u-boot-spi tree.
>>>> arch/arm/cpu/armv7/exynos/pinmux.c | 2 +-
>>>> arch/arm/cpu/armv7/exynos/spl_boot.c | 122 ++++++++++++++++++++++++++++++++-
>>>> arch/arm/include/asm/arch-exynos/spi.h | 1 +
>>>> include/configs/exynos5250-dt.h | 2 +
>>>> 4 files changed, 123 insertions(+), 4 deletions(-)
>>>>
>>>> diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c
>>>> index 8002bce..74cc700 100644
>>>> --- a/arch/arm/cpu/armv7/exynos/pinmux.c
>>>> +++ b/arch/arm/cpu/armv7/exynos/pinmux.c
>>>> @@ -462,7 +462,7 @@ static int exynos4_pinmux_config(int peripheral, int flags)
>>>> case PERIPH_ID_SDMMC1:
>>>> case PERIPH_ID_SDMMC3:
>>>> case PERIPH_ID_SDMMC4:
>>>> - printf("SDMMC device %d not implemented\n", peripheral);
>>>> + debug("SDMMC device %d not implemented\n", peripheral);
>>
>> unrelated change.
>>
> As mentioned commit message
> "Changed a printf in pinmux.c to debug just to avoid the compilation
> error in SPL."
>>>> return -1;
>>>> default:
>>>> debug("%s: invalid peripheral %d", __func__, peripheral);
>>>> diff --git a/arch/arm/cpu/armv7/exynos/spl_boot.c b/arch/arm/cpu/armv7/exynos/spl_boot.c
>>>> index 3651c00..6faf13f 100644
>>>> --- a/arch/arm/cpu/armv7/exynos/spl_boot.c
>>>> +++ b/arch/arm/cpu/armv7/exynos/spl_boot.c
>>>> @@ -10,8 +10,11 @@
>>>> #include <asm/arch/clock.h>
>>>> #include <asm/arch/clk.h>
>>>> #include <asm/arch/dmc.h>
>>>> +#include <asm/arch/periph.h>
>>>> +#include <asm/arch/pinmux.h>
>>>> #include <asm/arch/power.h>
>>>> #include <asm/arch/spl.h>
>>>> +#include <asm/arch/spi.h>
>>>>
>>>> #include "common_setup.h"
>>>> #include "clock_init.h"
>>>> @@ -59,6 +62,119 @@ static int config_branch_prediction(int set_cr_z)
>>>> }
>>>> #endif
>>>>
>>>> +static void spi_rx_tx(struct exynos_spi *regs, int todo,
>>>> + void *dinp, void const *doutp, int i)
>>>> +{
>>>> + uint *rxp = (uint *)(dinp + (i * (32 * 1024)));
>>>> + int rx_lvl, tx_lvl;
>>>> + uint out_bytes, in_bytes;
>>>> +
>>>> + out_bytes = todo;
>>>> + in_bytes = todo;
>>>> + setbits_le32(®s->ch_cfg, SPI_CH_RST);
>>>> + clrbits_le32(®s->ch_cfg, SPI_CH_RST);
>>>> + writel(((todo * 8) / 32) | SPI_PACKET_CNT_EN, ®s->pkt_cnt);
>>>> +
>>>> + while (in_bytes) {
>>>> + uint32_t spi_sts;
>>>> + int temp;
>>>> +
>>>> + spi_sts = readl(®s->spi_sts);
>>>> + rx_lvl = ((spi_sts >> 15) & 0x7f);
>>>> + tx_lvl = ((spi_sts >> 6) & 0x7f);
>>>> + while (tx_lvl < 32 && out_bytes) {
>>>> + temp = 0xffffffff;
>>>> + writel(temp, ®s->tx_data);
>>>> + out_bytes -= 4;
>>>> + tx_lvl += 4;
>>>> + }
>>>> + while (rx_lvl >= 4 && in_bytes) {
>>>> + temp = readl(®s->rx_data);
>>>> + if (rxp)
>>>> + *rxp++ = temp;
>>>> + in_bytes -= 4;
>>>> + rx_lvl -= 4;
>>>> + }
>>>> + }
>>>> +}
>>>> +
>>>> +/*
>>>> + * Copy uboot from spi flash to RAM
>>>> + *
>>>> + * @parma uboot_size size of u-boot to copy
>>>> + * @param uboot_addr address in u-boot to copy
>>>> + */
>>>> +static void exynos_spi_copy(unsigned int uboot_size, unsigned int uboot_addr)
>>>> +{
>>>> + int upto, todo;
>>>> + int i, timeout = 100;
>>>> + struct exynos_spi *regs = (struct exynos_spi *)CONFIG_ENV_SPI_BASE;
>>>> +
>>>> + set_spi_clk(PERIPH_ID_SPI1, 50000000); /* set spi clock to 50Mhz */
>>>> + /* set the spi1 GPIO */
>>>> + exynos_pinmux_config(PERIPH_ID_SPI1, PINMUX_FLAG_NONE);
>>>> +
>>>> + /* set pktcnt and enable it */
>>>> + writel(4 | SPI_PACKET_CNT_EN, ®s->pkt_cnt);
>>>> + /* set FB_CLK_SEL */
>>>> + writel(SPI_FB_DELAY_180, ®s->fb_clk);
>>>> + /* set CH_WIDTH and BUS_WIDTH as word */
>>>> + setbits_le32(®s->mode_cfg, SPI_MODE_CH_WIDTH_WORD |
>>>> + SPI_MODE_BUS_WIDTH_WORD);
>>>> + clrbits_le32(®s->ch_cfg, SPI_CH_CPOL_L); /* CPOL: active high */
>>>> +
>>>> + /* clear rx and tx channel if set priveously */
>>>> + clrbits_le32(®s->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON);
>>>> +
>>>> + setbits_le32(®s->swap_cfg, SPI_RX_SWAP_EN |
>>>> + SPI_RX_BYTE_SWAP |
>>>> + SPI_RX_HWORD_SWAP);
>>>> +
>>>> + /* do a soft reset */
>>>> + setbits_le32(®s->ch_cfg, SPI_CH_RST);
>>>> + clrbits_le32(®s->ch_cfg, SPI_CH_RST);
>>>> +
>>>> + /* now set rx and tx channel ON */
>>>> + setbits_le32(®s->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON | SPI_CH_HS_EN);
>>>> + clrbits_le32(®s->cs_reg, SPI_SLAVE_SIG_INACT); /* CS low */
>>>> +
>>>> + /* Send read instruction (0x3h) followed by a 24 bit addr */
>>>> + writel((SF_READ_DATA_CMD << 24) | SPI_FLASH_UBOOT_POS, ®s->tx_data);
>>>> +
>>>> + /* waiting for TX done */
>>>> + while (!(readl(®s->spi_sts) & SPI_ST_TX_DONE)) {
>>>> + if (!timeout) {
>>>> + debug("SPI TIMEOUT\n");
>>>> + break;
>>>> + }
>>>> + timeout--;
>>>> + }
>>>> +
>>>> + for (upto = 0, i = 0; upto < uboot_size; upto += todo, i++) {
>>>> + todo = min(uboot_size - upto, (1 << 15));
>>>> + spi_rx_tx(regs, todo, (void *)(uboot_addr),
>>>> + (void *)(SPI_FLASH_UBOOT_POS), i);
>>>> + }
>>>> +
>>>> + setbits_le32(®s->cs_reg, SPI_SLAVE_SIG_INACT);/* make the CS high */
>>>> +
>>>> + /*
>>>> + * Let put controller mode to BYTE as
>>>> + * SPI driver does not support WORD mode yet
>>>> + */
>>>> + clrbits_le32(®s->mode_cfg, SPI_MODE_CH_WIDTH_WORD |
>>>> + SPI_MODE_BUS_WIDTH_WORD);
>>>> + writel(0, ®s->swap_cfg);
>>>> +
>>>> + /*
>>>> + * Flush spi tx, rx fifos and reset the SPI controller
>>>> + * and clear rx/tx channel
>>>> + */
>>>> + clrsetbits_le32(®s->ch_cfg, SPI_CH_HS_EN, SPI_CH_RST);
>>>> + clrbits_le32(®s->ch_cfg, SPI_CH_RST);
>>>> + clrbits_le32(®s->ch_cfg, SPI_TX_CH_ON | SPI_RX_CH_ON);
>>>> +}
>>>> +
>>>> /*
>>>> * Copy U-boot from mmc to RAM:
>>>> * COPY_BL2_FNPTR_ADDR: Address in iRAM, which Contains
>>>> @@ -70,6 +186,7 @@ void copy_uboot_to_ram(void)
>>>>
>>>> u32 (*copy_bl2)(u32 offset, u32 nblock, u32 dst) = NULL;
>>>> u32 offset = 0, size = 0;
>>>> + struct spl_machine_param *param = spl_get_machine_params();
>>>> #ifdef CONFIG_SUPPORT_EMMC_BOOT
>>>> u32 (*copy_bl2_from_emmc)(u32 nblock, u32 dst);
>>>> void (*end_bootop_from_emmc)(void);
>>>> @@ -91,9 +208,8 @@ void copy_uboot_to_ram(void)
>>>> switch (bootmode) {
>>>> #ifdef CONFIG_SPI_BOOTING
>>>> case BOOT_MODE_SERIAL:
>>>> - offset = SPI_FLASH_UBOOT_POS;
>>>> - size = CONFIG_BL2_SIZE;
>>>> - copy_bl2 = get_irom_func(SPI_INDEX);
>>>> + /* Customised function to copy u-boot from SF */
>>>> + exynos_spi_copy(param->uboot_size, CONFIG_SYS_TEXT_BASE);
>>>> break;
>>>> #endif
>>>> case BOOT_MODE_MMC:
>>>> diff --git a/arch/arm/include/asm/arch-exynos/spi.h b/arch/arm/include/asm/arch-exynos/spi.h
>>>> index 147c1a7..0ba931b 100644
>>>> --- a/arch/arm/include/asm/arch-exynos/spi.h
>>>> +++ b/arch/arm/include/asm/arch-exynos/spi.h
>>>> @@ -30,6 +30,7 @@ struct exynos_spi {
>>>> #define EXYNOS_SPI_MAX_FREQ 50000000
>>>>
>>>> #define SPI_TIMEOUT_MS 10
>>>> +#define SF_READ_DATA_CMD 0x3
>>>>
>>>> /* SPI_CHCFG */
>>>> #define SPI_CH_HS_EN (1 << 6)
>>>> diff --git a/include/configs/exynos5250-dt.h b/include/configs/exynos5250-dt.h
>>>> index 8c21909..1d32396 100644
>>>> --- a/include/configs/exynos5250-dt.h
>>>> +++ b/include/configs/exynos5250-dt.h
>>>> @@ -154,6 +154,7 @@
>>>> #define COPY_BL2_FNPTR_ADDR 0x02020030
>>>>
>>>> #define CONFIG_SPL_LIBCOMMON_SUPPORT
>>>> +#define CONFIG_SPL_GPIO_SUPPORT
>>>>
>>>> /* specific .lds file */
>>>> #define CONFIG_SPL_LDSCRIPT "board/samsung/common/exynos-uboot-spl.lds"
>>>> @@ -292,6 +293,7 @@
>>>> /* SPI */
>>>> #define CONFIG_ENV_IS_IN_SPI_FLASH
>>>> #define CONFIG_SPI_FLASH
>>>> +#define CONFIG_ENV_SPI_BASE 0x12D30000
>>>>
>>>> #ifdef CONFIG_SPI_FLASH
>>>> #define CONFIG_EXYNOS_SPI
>>>> --
>>>> 1.7.12.4
>>>>
>>>> _______________________________________________
>>>> U-Boot mailing list
>>>> U-Boot at lists.denx.de
>>>> http://lists.denx.de/mailman/listinfo/u-boot
>>>
>>>
>>>
>>
>> Thanks,
>> Minkyu Kang.
>>
applied to u-boot-samsung.
Thanks,
Minkyu Kang.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2013-12-03 6:30 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-10-08 13:12 [U-Boot] [PATCH V3] exynos: spl: Add a custom spi copy function Rajeshwari S Shinde
2013-10-09 7:55 ` Rajeshwari Birje
2013-12-02 8:48 ` Minkyu Kang
2013-12-02 13:17 ` Rajeshwari Birje
2013-12-03 6:30 ` Minkyu Kang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).