From 4bc2ba3beec581ad940ba6f43d5aaf107bba2d54 Mon Sep 17 00:00:00 2001 From: Masayuki Ishikawa Date: Wed, 18 Jul 2018 11:45:20 +0000 Subject: [PATCH] Merged in masayuki2009/nuttx.nuttx/lc823450_spi_flash (pull request #687) lc823450 spi flash * arch/arm/src/lc823450: Add SPI flash driver for lc823450 NOTE: Only bus accelerator mode is supported. Signed-off-by: Masayuki Ishikawa * arch/arm/src/lc823450: Remove unnecessary settings in Kconfig Signed-off-by: Masayuki Ishikawa Approved-by: GregoryN --- arch/arm/src/lc823450/Kconfig | 33 +-- arch/arm/src/lc823450/Make.defs | 4 +- arch/arm/src/lc823450/lc823450_spifi2.c | 364 ++++++++++++++++++++++++ arch/arm/src/lc823450/lc823450_spifi2.h | 129 +++++++++ arch/arm/src/lc823450/lc823450_start.c | 4 +- 5 files changed, 498 insertions(+), 36 deletions(-) create mode 100644 arch/arm/src/lc823450/lc823450_spifi2.c create mode 100644 arch/arm/src/lc823450/lc823450_spifi2.h diff --git a/arch/arm/src/lc823450/Kconfig b/arch/arm/src/lc823450/Kconfig index f616cbdfca9..947a564e3f1 100644 --- a/arch/arm/src/lc823450/Kconfig +++ b/arch/arm/src/lc823450/Kconfig @@ -37,42 +37,11 @@ config LC823450_WDT config LC823450_SPIFI bool "SPI Flash Interface (SPIFI)" default n - depends on MTD if LC823450_SPIFI - -config LC823450_SPIFI_DEVNO - int "number in /dev/mtdblk?" - default 0 - -config LC823450_SPIFI_SIZE - int "SPI FLASH size (byte)" - default 4194304 - config LC823450_SPIFI_QUADIO bool "SPIFI 4bit access" - default n - -config LC823450_SPIFI_RAMFAT - bool "SPIFI with SRAM FAT" - default n - -config LC823450_SPIFI_RAMFAT_VOLUMELABEL - string "volume label for SRAM FAT" - depends on LC823450_SPIFI_RAMFAT - -config LC823450_SPIFI_BACKUP - bool "power dwon tolerance I/O" - default n - -config LC823450_SPIFI_BACKUP_HEAD_OFFSET - hex "backup header offset" - depends on LC823450_SPIFI_BACKUP - -config LC823450_SPIFI_BACKUP_VAL_OFFSET - hex "backup area offset" - depends on LC823450_SPIFI_BACKUP - + default y endif config LC823450_SDIF diff --git a/arch/arm/src/lc823450/Make.defs b/arch/arm/src/lc823450/Make.defs index c13cb52fcbe..9c2384bd7c9 100644 --- a/arch/arm/src/lc823450/Make.defs +++ b/arch/arm/src/lc823450/Make.defs @@ -1,7 +1,7 @@ ############################################################################ # arch/arm/src/lc823450/Make.defs # -# Copyright 2014, 2015, 2016, 2017 Sony Video & Sound Products Inc. +# Copyright 2014, 2015, 2016, 2017, 2018 Sony Video & Sound Products Inc. # Author: Masatoshi Tateishi # Author: Masayuki Ishikawa # Author: Yasuhiro Osaki @@ -92,7 +92,7 @@ CHIP_CSRCS += lc823450_wdt.c endif ifeq ($(CONFIG_LC823450_SPIFI), y) -CHIP_CSRCS += lc823450_spifi.c +CHIP_CSRCS += lc823450_spifi2.c endif ifeq ($(CONFIG_LC823450_SDIF), y) diff --git a/arch/arm/src/lc823450/lc823450_spifi2.c b/arch/arm/src/lc823450/lc823450_spifi2.c new file mode 100644 index 00000000000..7d1845141a4 --- /dev/null +++ b/arch/arm/src/lc823450/lc823450_spifi2.c @@ -0,0 +1,364 @@ +/**************************************************************************** + * arch/arm/src/lc823450/lc823450_spifi2.c + * + * Copyright 2014,2015,2016,2017,2018 Sony Video & Sound Products Inc. + * Author: Masatoshi Tateishi + * Author: Masayuki Ishikawa + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include +#include + +#include + +#include "chip.h" +#include "up_arch.h" + +#include "lc823450_syscontrol.h" +#include "lc823450_spifi2.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: wait_txfifo_empty + ****************************************************************************/ + +static int wait_txfifo_empty(void) +{ + int t; + t = 1000; + + while ((getreg32(SF_FIFO_NUM) & SF_FIFO_NUM_T_MASK) && t) + { + up_udelay(1); + t--; + } + + return t == 0 ? -ETIMEDOUT : 0; +} + +/**************************************************************************** + * Name: wait_rxfifo_notempty + ****************************************************************************/ + +static int wait_rxfifo_notempty(void) +{ + int t; + t = 1000; + + while (!(getreg32(SF_FIFO_NUM) & SF_FIFO_NUM_R_MASK) && t) + { + up_udelay(1); + t--; + } + + return t == 0 ? -ETIMEDOUT : 0; +} + +/**************************************************************************** + * Name: spiflash_cmd_only + ****************************************************************************/ + +static int spiflash_cmd_only(int cmd) +{ + /* COMMAND(1byte) = 1 */ + + putreg32(SF_SIZE_NOREAD | 1 << SF_SIZE_T_SHIFT, SF_SIZE); + putreg32(0, SF_DUMMY); + putreg8(cmd, SF_T_FIFO); + + /* Start Transfer */ + + putreg32(SF_CTL_ACT, SF_CTL); + return wait_txfifo_empty(); +} + +/**************************************************************************** + * Name: spiflash_read_jdid + ****************************************************************************/ + +static int spiflash_read_jdid(void) +{ + int ret = 0; + + /* COMMAND(1byte) + jid(3byte) */ + + putreg32(1 << SF_SIZE_UL_SHIFT | 4 << SF_SIZE_T_SHIFT, SF_SIZE); + putreg32(SF_DUMMY_DUMMY, SF_DUMMY); + + /* COMMAND */ + + putreg8(SF_CMD_READ_JID, SF_T_FIFO); + + /* Start Transfer */ + + putreg32(SF_CTL_ACT, SF_CTL); + + /* MID */ + + wait_rxfifo_notempty(); + ret |= getreg8(SF_R_FIFO); + + /* MType */ + + wait_rxfifo_notempty(); + ret <<= 8; + ret |= getreg8(SF_R_FIFO); + + /* CapID */ + + wait_rxfifo_notempty(); + + ret <<= 8; + ret |= getreg8(SF_R_FIFO); + + return ret; +} + +/**************************************************************************** + * Name: spiflash_quad_enable_winbond + ****************************************************************************/ + +static void spiflash_quad_enable_winbond(void) +{ + /* SR Write Enable */ + + if (spiflash_cmd_only(SF_CMD_WRITE_EN)) + { + return; + } + + /* Quad Enable */ + + putreg32(SF_SIZE_NOREAD | 3 << SF_SIZE_T_SHIFT, SF_SIZE); + putreg32(0, SF_DUMMY); + putreg8(SF_CMD_WRITE_STATUS, SF_T_FIFO); + putreg8(0, SF_T_FIFO); /* status1 */ + putreg8(SF_STATUS2_QE, SF_T_FIFO); /* status2 */ + + /* Start Transfer */ + + putreg32(SF_CTL_ACT, SF_CTL); + + wait_txfifo_empty(); + return; +} + +/**************************************************************************** + * Name: spiflash_read_quad_enable_winbond + ****************************************************************************/ + +static int spiflash_read_quad_enable_winbond(void) +{ + /* COMMAND(1byte) + status(1byte) */ + + putreg32(1 << SF_SIZE_UL_SHIFT | 2 << SF_SIZE_T_SHIFT, SF_SIZE); + putreg32(SF_DUMMY_DUMMY, SF_DUMMY); + + /* COMMAND */ + + putreg8(SF_CMD_READ_STATUS2, SF_T_FIFO); + + /* Start Transfer */ + + putreg32(SF_CTL_ACT, SF_CTL); + + wait_rxfifo_notempty(); + + return getreg8(SF_R_FIFO) & SF_STATUS2_QE; +} + +/**************************************************************************** + * Name: spiflash_quad_enable_macronix + ****************************************************************************/ + +static void spiflash_quad_enable_macronix(void) +{ + /* SR Write Enable */ + + if (spiflash_cmd_only(SF_CMD_WRITE_EN)) + { + return; + } + + /* Quad Enable */ + + putreg32(SF_SIZE_NOREAD | 2 << SF_SIZE_T_SHIFT, SF_SIZE); + putreg32(0, SF_DUMMY); + putreg8(SF_CMD_WRITE_STATUS, SF_T_FIFO); + putreg8(1 << 6, SF_T_FIFO); /* status1 */ + + /* Start Transfer */ + + putreg32(SF_CTL_ACT, SF_CTL); + + wait_txfifo_empty(); + return; +} + +/**************************************************************************** + * Name: spiflash_read_quad_enable_macronix + ****************************************************************************/ + +static int spiflash_read_quad_enable_macronix(void) +{ + /* COMMAND(1byte) + status(1byte) */ + + putreg32(1 << SF_SIZE_UL_SHIFT | 2 << SF_SIZE_T_SHIFT, SF_SIZE); + putreg32(SF_DUMMY_DUMMY, SF_DUMMY); + + /* COMMAND */ + + putreg8(SF_CMD_READ_STATUS1, SF_T_FIFO); + + /* Start Transfer */ + + putreg32(SF_CTL_ACT, SF_CTL); + + wait_rxfifo_notempty(); + + return getreg8(SF_R_FIFO) & (1 << 6); +} + +/**************************************************************************** + * Name: spiflash_quad_enable + ****************************************************************************/ + +static void spiflash_quad_enable(int jdid) +{ + if ((jdid & SF_JID_MID_MASK) == SF_JID_MID_MACRONIX) + { + spiflash_quad_enable_macronix(); + } + else + { + spiflash_quad_enable_winbond(); + } +} + +/**************************************************************************** + * Name: spiflash_read_quad_enable + ****************************************************************************/ + +static int spiflash_read_quad_enable(int jdid) +{ + if ((jdid & SF_JID_MID_MASK) == SF_JID_MID_MACRONIX) + { + return spiflash_read_quad_enable_macronix(); + } + + return spiflash_read_quad_enable_winbond(); +} + +/**************************************************************************** + * Name: spiflash_write_busy + ****************************************************************************/ + +static int spiflash_write_busy(void) +{ + /* COMMAND(1byte) + status(1byte) */ + + putreg32(1 << SF_SIZE_UL_SHIFT | 2 << SF_SIZE_T_SHIFT, SF_SIZE); + putreg32(SF_DUMMY_DUMMY, SF_DUMMY); + + /* COMMAND */ + + putreg8(SF_CMD_READ_STATUS1, SF_T_FIFO); + + /* Start Transfer */ + + putreg32(SF_CTL_ACT, SF_CTL); + + wait_rxfifo_notempty(); + + return getreg8(SF_R_FIFO) & SF_STATUS1_BUSY; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lc823450_spiflash_earlyinit + ****************************************************************************/ + +void lc823450_spiflash_earlyinit(void) +{ +#ifdef CONFIG_LC823450_SPIFI_QUADIO + int jdid; +#endif + + /* S-Flash controller: Enable clock & unreset */ + + modifyreg32(MCLKCNTBASIC, 0, MCLKCNTBASIC_SFIF_CLKEN); + modifyreg32(MRSTCNTBASIC, 0, MRSTCNTBASIC_SFIF_RSTB); + + /* S-Flash cache: Enable clock & unreset */ + + modifyreg32(MCLKCNTBASIC, 0, MCLKCNTBASIC_CACHE_CLKEN); + modifyreg32(MRSTCNTBASIC, 0, MRSTCNTBASIC_CACHE_RSTB); + + /* Set S-Flash I/O voltage to 3.3v */ + + putreg32(0x1, SFIFSEL); + +#ifdef CONFIG_LC823450_SPIFI_QUADIO + jdid = spiflash_read_jdid(); + + /* Check if QUAD mode supported */ + + if (!spiflash_read_quad_enable(jdid)) + { + spiflash_quad_enable(jdid); + while (spiflash_write_busy()) + { + up_udelay(10); + } + } + + /* bus accelerator enable : mode 3(use FAST_READ_QUAD_IO) */ + + putreg32(SF_BUS_BUSEN | 3 << SF_BUS_BUSMODE_SHIFT | SF_BUS_LOOKAHEAD, + SF_BUS); +#else + /* bus accelerator enable : mode 1(use FAST_READ) */ + + putreg32(SF_BUS_BUSEN | 1 << SF_BUS_BUSMODE_SHIFT | SF_BUS_LOOKAHEAD, + SF_BUS); +#endif /* CONFIG_LC823450_SPIFI_QUADIO */ + + /* S-Flash cache: Flash and Re-enable cache */ + + modifyreg32(CACHE_CTL, CACHE_CTL_USE, 0); + modifyreg32(CACHE_CTL, 0, CACHE_CTL_USE); +} diff --git a/arch/arm/src/lc823450/lc823450_spifi2.h b/arch/arm/src/lc823450/lc823450_spifi2.h new file mode 100644 index 00000000000..e3fc92d9ed8 --- /dev/null +++ b/arch/arm/src/lc823450/lc823450_spifi2.h @@ -0,0 +1,129 @@ +/**************************************************************************** + * arch/arm/src/lc823450/lc823450_spifi2.h + * + * Copyright 2014,2015,2016,2017,2018 Sony Video & Sound Products Inc. + * Author: Masatoshi Tateishi + * Author: Masayuki Ishikawa + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LC823450_LC823450_SPIFI2_H +#define __ARCH_ARM_SRC_LC823450_LC823450_SPIFI2_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define LC823450_SFLASH_REGBASE 0x40001000 + +#define SF_SIZE (LC823450_SFLASH_REGBASE + 0x00) +#define SF_SIZE_T_SHIFT 0 +#define SF_SIZE_UL_SHIFT 24 +#define SF_SIZE_NOREAD (1 << 28) +#define SF_CTL (LC823450_SFLASH_REGBASE + 0x04) +#define SF_CTL_ACT (1 << 0) +#define SF_MODE (LC823450_SFLASH_REGBASE + 0x08) +#define SF_MODE_MODE_SHIFT 0 +#define SF_DUMMY (LC823450_SFLASH_REGBASE + 0x0c) +#define SF_DUMMY_DUMMY (1 << 0) +#define SF_FIFO_CLR (LC823450_SFLASH_REGBASE + 0x10) +#define SF_STATUS (LC823450_SFLASH_REGBASE + 0x14) +#define SF_IRQEN (LC823450_SFLASH_REGBASE + 0x18) +#define SF_FIFO_NUM (LC823450_SFLASH_REGBASE + 0x1c) +#define SF_FIFO_NUM_T_SHIFT 0 +#define SF_FIFO_NUM_T_MASK (0xf << SF_FIFO_NUM_T_SHIFT) +#define SF_FIFO_NUM_R_SHIFT 8 +#define SF_FIFO_NUM_R_MASK (0xf << SF_FIFO_NUM_R_SHIFT) +#define SF_SRSTB (LC823450_SFLASH_REGBASE + 0x20) +#define SF_PHASE_SET (LC823450_SFLASH_REGBASE + 0x24) +#define SF_BUS (LC823450_SFLASH_REGBASE + 0x28) +#define SF_BUS_BUSEN (1 << 0) +#define SF_BUS_LOOKAHEAD (1 << 1) +#define SF_BUS_ACT (1 << 24) +#define SF_BUS_BUSMODE_SHIFT 8 +#define SF_TIMING (LC823450_SFLASH_REGBASE + 0x2c) +#define SF_TIMING_CS_MASK (0x7 << 0) +#define SF_TIMING_CS_SHIFT 0 +#define SF_T_FIFO (LC823450_SFLASH_REGBASE + 0x30) +#define SF_R_FIFO (LC823450_SFLASH_REGBASE + 0x34) + +#define SF_CMD_WRITE_STATUS 0x01 +#define SF_CMD_PAGE_PROG 0x02 +#define SF_CMD_READ_STATUS1 0x05 +#define SF_CMD_WRITE_EN 0x06 +#define SF_CMD_FAST_READ 0x0b +#define SF_CMD_SEC_ERASE 0x20 +#define SF_CMD_WRITE_STATUS2 0x31 +#define SF_CMD_READ_STATUS2 0x35 +#define SF_CMD_SR_WRITE_EN 0x50 +#define SF_CMD_CHIP_ERASE 0x60 +#define SF_CMD_FAST_READ_QUAD 0x6b +#define SF_CMD_READ_JID 0x9f + +#define SF_STATUS1_BUSY (1 << 0) +#define SF_STATUS2_QE (1 << 1) + +#define SF_JID_MID_MASK 0xff0000 +#define SF_JID_MID_WINBOND 0xef0000 +#define SF_JID_MID_MACRONIX 0xc20000 + + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void lc823450_spiflash_earlyinit(void); + +#if defined(__cplusplus) +} +#endif +#undef EXTERN + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_LC823450_LC823450_SPIFI2_H */ diff --git a/arch/arm/src/lc823450/lc823450_start.c b/arch/arm/src/lc823450/lc823450_start.c index a7ae3b88cef..c712bb1c52c 100644 --- a/arch/arm/src/lc823450/lc823450_start.c +++ b/arch/arm/src/lc823450/lc823450_start.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/arm/src/lc823450/lc823450_start.c * - * Copyright 2014, 2015, 2016, 2017 Sony Video & Sound Products Inc. + * Copyright 2014, 2015, 2016, 2017, 2018 Sony Video & Sound Products Inc. * Author: Masatoshi Tateishi * Author: Masayuki Ishikawa * Author: Yasuhiro Osaki @@ -61,7 +61,7 @@ #include #ifdef CONFIG_LC823450_SPIFI -# include "lc823450_spifi.h" +# include "lc823450_spifi2.h" #endif #include "lc823450_lowputc.h" #include "lc823450_clockconfig.h"