s5j/sflash: clean up code and add function descriptions
authorIvan <ivan.galkin@samsung.com>
Fri, 17 Mar 2017 11:46:31 +0000 (20:46 +0900)
committerHeesub Shin <heesub.shin@samsung.com>
Mon, 17 Apr 2017 10:52:03 +0000 (19:52 +0900)
Change-Id: Ib32feaae43b8bb906e6451006367bcd26cb01362
Signed-off-by: Ivan <ivan.galkin@samsung.com>
os/arch/arm/src/s5j/s5j_sflash.c

index c2d7461..27eff55 100644 (file)
@@ -49,7 +49,6 @@
  * POSSIBILITY OF SUCH DAMAGE.
  *
  *****************************************************************************/
-
 /******************************************************************************
  * Included Files
  *****************************************************************************/
@@ -62,6 +61,7 @@
 #include <tinyara/kmalloc.h>
 #include <tinyara/spi/spi.h>
 #include <arpa/inet.h>
+#include <tinyara/fs/mtd.h>
 
 #include "up_arch.h"
 #include "cache.h"
  * Pre-processor Definitions
  *****************************************************************************/
 #define S5J_SFLASH_MAPPED_ADDR   (CONFIG_S5J_FLASH_BASE)
-#undef  S5J_SFLASH_USE_DIRECT_RW
+#define S5J_SFLASH_USE_DIRECT_RW
 
-#define SFLASH_SECTOR_SIZE       (CONFIG_S5J_FLASH_SECTOR_SIZE)
+#define SFLASH_SECTOR_SIZE       (4096)
 #define SECTOR_ALIGN_SIZE(x)     (((x)/SFLASH_SECTOR_SIZE)*SFLASH_SECTOR_SIZE)
 
-#define MIN(a, b) (a > b) ? b : a
-
-#if defined(CONFIG_BOARD_COREDUMP_FLASH) || defined(CONFIG_BOARD_RAMDUMP_FLASH)
-volatile bool g_sflash_nonsleep_mode = false;
-
-#define usleep(x) \
-       do { \
-               if (g_sflash_nonsleep_mode) { \
-                       up_udelay(x); \
-               } else { \
-                       usleep(x); \
-               } \
-       } while (0)
-#endif
+#define MIN(a, b) ( a > b ) ? b : a
 
 /******************************************************************************
  * Private Types
  *****************************************************************************/
 /* Command definitions */
-
 enum s5j_sflash_command_e {
-       SFLASH_WRITE_STATUS_REGISTER = 0x01,/* WRSR                   */
+       SFLASH_WRITE_STATUS_REGISTER = 0x01,    /* WRSR                   */
        SFLASH_WRITE = 0x02,
        SFLASH_READ = 0x03,
        SFLASH_WRITE_DISABLE = 0x04,            /* WRDI                   */
        SFLASH_READ_STATUS_REGISTER = 0x05,     /* RDSR                   */
-       SFLASH_WRITE_ENABLE = 0x06,                     /* WREN                   */
-       SFLASH_SECTOR_ERASE = 0x20,                     /* SE                     */
-       SFLASH_READ_STATUS_REGISTER2 = 0x35,/* RDSR-2 - Winbond only  */
+       SFLASH_WRITE_ENABLE = 0x06,             /* WREN                   */
+       SFLASH_SECTOR_ERASE = 0x20,             /* SE                     */
+       SFLASH_READ_STATUS_REGISTER2 = 0x35,    /* RDSR-2 - Winbond only  */
        SFLASH_BLOCK_ERASE_MID = 0x52,          /* SE                     */
        SFLASH_BLOCK_ERASE_LARGE = 0xD8,        /* SE                     */
-       SFLASH_READ_ID1 = 0x90,                         /* data size varies       */
-       SFLASH_READ_ID2 = 0xAB,                         /* data size varies       */
+       SFLASH_READ_ID1 = 0x90,                 /* data size varies       */
+       SFLASH_READ_ID2 = 0xAB,                 /* data size varies       */
        SFLASH_READ_JEDEC_ID = 0x9F,            /* RDID                   */
-       SFLASH_CHIP_ERASE1 = 0x60,                      /* CE                     */
-       SFLASH_CHIP_ERASE2 = 0xC7,                      /* CE                     */
-       SFLASH_DUMMY = 0xA5,                            /* Dummy */
+       SFLASH_CHIP_ERASE1 = 0x60,              /* CE                     */
+       SFLASH_CHIP_ERASE2 = 0xC7,              /* CE                     */
+       SFLASH_DUMMY = 0xA5,                    /* Dummy */
 };
 
 struct s5j_sflash_priv_s {
        uint32_t addr;
        sem_t sem_excl;                         /* mutex */
+       void *priv;
 };
 
 struct s5j_sflash_dev_s {
@@ -128,7 +115,7 @@ struct s5j_sflash_dev_s {
 
 /* this ptr can be used in nsh_cmd */
 
-FAR struct s5j_sflash_dev_s *sflashdev;
+FAR struct s5j_sflash_dev_s *sflashdev = NULL;
 
 /******************************************************************************
  * Private Function Prototypes
@@ -182,45 +169,17 @@ static FAR const struct spi_ops_s s5j_spi_ops = {
  * Private Functions
  *****************************************************************************/
 
-static void QSPI_Set_GPIOPort(void)
-{
-       s32 gpio_sf_clk;
-       s32 gpio_sf_cs;
-       s32 gpio_sf_si;
-       s32 gpio_sf_so;
-       s32 gpio_sf_wp;
-       s32 gpio_sf_hld;
-
-       gpio_sf_clk = s5j_gpio(GPP1, 0);
-       gpio_sf_cs = s5j_gpio(GPP1, 1);
-       gpio_sf_si = s5j_gpio(GPP1, 2);
-       gpio_sf_so = s5j_gpio(GPP1, 3);
-       gpio_sf_wp = s5j_gpio(GPP1, 4);
-       gpio_sf_hld = s5j_gpio(GPP1, 5);
-
-       gpio_cfg_pin(gpio_sf_clk, GPIO_FUNC(2));
-       gpio_cfg_pin(gpio_sf_cs, GPIO_FUNC(2));
-       gpio_cfg_pin(gpio_sf_si, GPIO_FUNC(2));
-       gpio_cfg_pin(gpio_sf_so, GPIO_FUNC(2));
-       gpio_cfg_pin(gpio_sf_wp, GPIO_FUNC(2));
-       gpio_cfg_pin(gpio_sf_hld, GPIO_FUNC(2));
-
-       gpio_set_pull(gpio_sf_clk, GPIO_PULL_UP);
-       gpio_set_pull(gpio_sf_cs, GPIO_PULL_UP);
-       gpio_set_pull(gpio_sf_si, GPIO_PULL_UP);
-       gpio_set_pull(gpio_sf_so, GPIO_PULL_UP);
-       gpio_set_pull(gpio_sf_wp, GPIO_PULL_UP);
-       gpio_set_pull(gpio_sf_hld, GPIO_PULL_UP);
-
-       return;
-}
-
 /******************************************************************************
  * Name: s5j_sflash_sem_post
  *
  * Description:
  *   Release the mutual exclusion semaphore
  *
+ * Input Parameters:
+ *   dev - pointer to spi dev structure
+ *
+ * Returned Value:
+ *   OK
  *****************************************************************************/
 
 static inline void s5j_sflash_sem_post(struct s5j_sflash_dev_s *dev)
@@ -234,6 +193,11 @@ static inline void s5j_sflash_sem_post(struct s5j_sflash_dev_s *dev)
  * Description:
  *   Initialize semaphores
  *
+ * Input Parameters:
+ *   dev - pointer to spi dev structure
+ *
+ * Returned Value:
+ *   OK
  *****************************************************************************/
 
 static inline void s5j_sflash_sem_init(struct s5j_sflash_dev_s *dev)
@@ -247,6 +211,11 @@ static inline void s5j_sflash_sem_init(struct s5j_sflash_dev_s *dev)
  * Description:
  *   Take the exclusive access, waiting as necessary
  *
+ * Input Parameters:
+ *   dev - pointer to spi dev structure
+ *
+ * Returned Value:
+ *   OK
  *****************************************************************************/
 
 static inline void s5j_sflash_sem_wait(struct s5j_sflash_dev_s *dev)
@@ -260,13 +229,23 @@ static inline void s5j_sflash_sem_wait(struct s5j_sflash_dev_s *dev)
  * Name: s5j_sflash_erase
  *
  * Description:
- *   erase flash
+ *   Flash Erase
+ *
+ * Input Parameters:
+ *   dev - pointer to spi dev structure
+ *   cmd - erase command
+ *   addr - erase start address
  *
+ * Returned Value:
+ *   OK
  *****************************************************************************/
 
-int s5j_sflash_erase(struct s5j_sflash_dev_s *dev, uint8_t cmd, uint32_t addr)
+static int s5j_sflash_erase(struct s5j_sflash_dev_s *dev, uint8_t cmd, uint32_t addr)
 {
        int ret;
+#ifdef CONFIG_S5J_FLASH_ONLY_ALLOW_SUBSECTOR
+       uint32_t i;
+#endif
        uint32_t val;
        int size = 0;
 
@@ -278,6 +257,8 @@ int s5j_sflash_erase(struct s5j_sflash_dev_s *dev, uint8_t cmd, uint32_t addr)
        }
 #endif
 
+       s5j_qspi_disable_wp();
+
        do {
                ret = s5j_sflash_write_enable(dev);
                if (OK != ret) {
@@ -299,16 +280,25 @@ int s5j_sflash_erase(struct s5j_sflash_dev_s *dev, uint8_t cmd, uint32_t addr)
        case SFLASH_SECTOR_ERASE:
                Outp32(rERASE_ADDRESS, addr);
                Outp8(rSE, QSPI_DUMMY_DATA);
-               size = 4096; /* Sub-sector size */
+               size = 4096;                    /* Sub-sector size */
                break;
        case SFLASH_BLOCK_ERASE_LARGE:
-               size = 65536; /* block size */
+               size = 65536;                   /* block size */
+#ifdef CONFIG_S5J_FLASH_ONLY_ALLOW_SUBSECTOR
+               for (i = 0; i < 16; i++) {
+                       Outp32(rERASE_ADDRESS, addr + i * 4096);
+                       Outp8(rSE, QSPI_DUMMY_DATA);
+
+                       while (getreg8(rRDSR) & 0x1) ;
+                       pthread_yield();
+               }
+#else
                SetBits(rCOMMAND2, 16, 0xFF, COMMAND_ERASE_64KB);
                /* SetBits(rCOMMAND2, 16, 0xFF, COMMAND_ERASE_32KB); */
 
                Outp32(rERASE_ADDRESS, addr);
                Outp8(rBE, QSPI_DUMMY_DATA);
-
+#endif
                break;
        default:
                break;
@@ -316,6 +306,8 @@ int s5j_sflash_erase(struct s5j_sflash_dev_s *dev, uint8_t cmd, uint32_t addr)
 
        while (getreg8(rRDSR) & 0x1) ;
 
+       s5j_qspi_enable_wp();
+
        if (cmd != SFLASH_CHIP_ERASE1) {
                arch_invalidate_dcache(addr + S5J_SFLASH_MAPPED_ADDR, (addr + S5J_SFLASH_MAPPED_ADDR + size));
        }
@@ -323,7 +315,19 @@ int s5j_sflash_erase(struct s5j_sflash_dev_s *dev, uint8_t cmd, uint32_t addr)
        return OK;
 }
 
-int s5j_sflash_write_enable(struct s5j_sflash_dev_s *dev)
+/******************************************************************************
+ * Name: s5j_sflash_write_enable
+ *
+ * Description:
+ *   Enable flash write operation
+ *
+ * Input Parameters:
+ *   dev - pointer to spi dev structure
+ *
+ * Returned Value:
+ *   OK
+ *****************************************************************************/
+static int s5j_sflash_write_enable(struct s5j_sflash_dev_s *dev)
 {
        SetBits(rCOMMAND4, 8, 0xFF, 0x06);
 
@@ -331,14 +335,41 @@ int s5j_sflash_write_enable(struct s5j_sflash_dev_s *dev)
 }
 
 /******************************************************************************
+ * Name: s5j_sflash_write_disable
+ *
+ * Description:
+ *   Disable flash write operation
+ *
+ * Input Parameters:
+ *   dev - pointer to spi dev structure
+ *
+ * Returned Value:
+ *   OK
+ *****************************************************************************/
+static int s5j_sflash_write_disable(struct s5j_sflash_dev_s *dev)
+{
+       SetBits(rCOMMAND4, 8, 0xFF, 0x04);
+
+       return OK;
+}
+
+/******************************************************************************
  * Name: s5j_sflash_read
  *
  * Description:
  *   Read data from flash.
  *
+ * Input Parameters:
+ *   dev - pointer to spi dev structure
+ *   addr - Start address
+ *   buf - pointer to buffer for data to read
+ *   size - number of bytes to read
+ *
+ * Returned Value:
+ *   OK
  *****************************************************************************/
 
-int s5j_sflash_read(struct s5j_sflash_dev_s *dev, uint32_t addr, uint8_t *buf, uint32_t size)
+static int s5j_sflash_read(struct s5j_sflash_dev_s *dev, uint32_t addr, uint8_t *buf, uint32_t size)
 {
        int32_t i;
        int32_t readsize;
@@ -354,6 +385,9 @@ int s5j_sflash_read(struct s5j_sflash_dev_s *dev, uint32_t addr, uint8_t *buf, u
        }
 #endif
 
+       /* it avoid to conflict smartfs read and SSS f/w write */
+       s5j_qspi_take_sem();
+
        fvdbg("addr 0x%x, size %d\n", addr, size);
        while (size != 0) {
                /* first align */
@@ -368,6 +402,8 @@ int s5j_sflash_read(struct s5j_sflash_dev_s *dev, uint32_t addr, uint8_t *buf, u
                size -= readsize;
        }
 
+       s5j_qspi_release_sem();
+
        fvdbg("buf[%d]\n", *buf);
        return OK;
 }
@@ -378,9 +414,17 @@ int s5j_sflash_read(struct s5j_sflash_dev_s *dev, uint32_t addr, uint8_t *buf, u
  * Description:
  *  Write data.
  *
+ * Input Parameters:
+ *   dev - pointer to spi dev structure
+ *   addr - Start address
+ *   buf - pointer to buffer for data to write
+ *   size - number of bytes to write
+ *
+ * Returned Value:
+ *   OK
  *****************************************************************************/
 
-int s5j_sflash_write(struct s5j_sflash_dev_s *dev, uint32_t addr, uint8_t *buf, uint32_t size)
+static int s5j_sflash_write(struct s5j_sflash_dev_s *dev, uint32_t addr, uint8_t *buf, uint32_t size)
 {
        int32_t i;
        int32_t readsize;
@@ -403,15 +447,17 @@ int s5j_sflash_write(struct s5j_sflash_dev_s *dev, uint32_t addr, uint8_t *buf,
 
                offset = addr % SFLASH_SECTOR_SIZE;
                readsize = MIN(SFLASH_SECTOR_SIZE - offset, size);
-
+               s5j_qspi_disable_wp();
                memcpy((void *)(addr + S5J_SFLASH_MAPPED_ADDR), (void *)(buf + i), readsize);
                arch_flush_dcache(addr + S5J_SFLASH_MAPPED_ADDR, (addr + S5J_SFLASH_MAPPED_ADDR + readsize));
+               s5j_qspi_enable_wp();
                addr += readsize;
                i += readsize;
                size -= readsize;
 
                /* check write in progress */
                while (getreg8(rRDSR) & 0x1) ;
+               pthread_yield();
        }
 
        return OK;
@@ -423,22 +469,18 @@ int s5j_sflash_write(struct s5j_sflash_dev_s *dev, uint32_t addr, uint8_t *buf,
  * Description:
  *  initialize sflash controller.
  *
+ * Input Parameters:
+ *   spidev - pointer to spi dev structure
+ *
+ * Returned Value:
+ *   OK
  *****************************************************************************/
 
 static int s5j_sflash_init(struct s5j_sflash_dev_s *dev)
 {
        /* initialize mutex */
-
        s5j_sflash_sem_init(dev);
 
-       QSPI_Set_GPIOPort();
-       HW_REG32(0x80310000, 0x04) = 0x8010001A;        /* disable WP */
-       HW_REG32(0x80310000, 0x78) = 0x8;                       //FLASH_IO_MODE
-       HW_REG32(0x80310000, 0x74) = 0x4;                       //QUAD_FAST_READ
-
-       /* COMMNAD1 will be asserted by default value */
-       cal_clk_setrate(d1_serialflash, 80000000);
-
        return OK;
 }
 
@@ -448,6 +490,12 @@ static int s5j_sflash_init(struct s5j_sflash_dev_s *dev)
  * Description:
  *  Support Lock/Unlock. This function s a part of spi_ops.
  *
+ * Input Parameters:
+ *   spidev - pointer to spi dev structure
+ *   lock - true, locks access; false, release access
+ *
+ * Returned Value:
+ *   OK
  *****************************************************************************/
 
 static int s5j_sflash_lock(FAR struct spi_dev_s *spidev, bool lock)
@@ -469,7 +517,7 @@ static int s5j_sflash_lock(FAR struct spi_dev_s *spidev, bool lock)
  *
  * Description:
  *  Support SPI CS. But, the S5J only 1 sflash. We don't necessary.
- *  This function is a part of spi_ops.
+ *  This function is a part of spi_ops. Dummy Function
  *
  *****************************************************************************/
 
@@ -482,7 +530,7 @@ static void s5j_sflash_select(FAR struct spi_dev_s *spidev, enum spi_dev_e devid
  * Name: s5j_sflash_setfrequency
  *
  * Description:
- *  Support changing frequency.
+ *  Support changing frequency. Dummy function.
  *
  *****************************************************************************/
 
@@ -495,7 +543,7 @@ static uint32_t s5j_sflash_setfrequency(FAR struct spi_dev_s *spidev, uint32_t f
  * Name: s5j_sflash_setmode
  *
  * Description:
- *  Support changing mode(CPHA/CPOL).
+ *  Support changing mode(CPHA/CPOL). Dummy function.
  *
  *****************************************************************************/
 
@@ -508,9 +556,7 @@ static int s5j_sflash_setmode(FAR struct spi_dev_s *spidev, enum spi_mode_e mode
  * Name: s5j_sflash_setbits
  *
  * Description:
- *  Support changing 1/4Bit. But we can't change bit.
- *  If you need to change bit, please ask the broadcom.
- *  This function is a part of spi_ops.
+ *  Support changing 1/4Bit. Dummy function.
  *
  *****************************************************************************/
 
@@ -525,7 +571,7 @@ static int s5j_sflash_setbits(FAR struct spi_dev_s *spidev, int nbits)
  * Name: s5j_sflash_setbits
  *
  * Description:
- *  This function is a part of spi_ops
+ *  This function is a part of spi_ops. Dummy function.
  *
  *****************************************************************************/
 
@@ -542,6 +588,12 @@ static int s5j_sflash_hwfeatures(FAR struct spi_dev_s *spidev, spi_hwfeatures_t
  *  Send a slave address from upper-level driver to device.
  *  This function is a part of spi_ops.
  *
+ * Input Parameters:
+ *   spidev - pointer to spi dev structure
+ *   wd - write data. Data is a command or erase addr.
+ *
+ * Returned Value:
+ *   OK, or 0.
  *****************************************************************************/
 
 static uint16_t s5j_sflash_send(FAR struct spi_dev_s *spidev, uint16_t wd)
@@ -634,6 +686,14 @@ static uint16_t s5j_sflash_send(FAR struct spi_dev_s *spidev, uint16_t wd)
  *  Send data from upper-level driver to device.
  *  This function is a part of spi_ops.
  *
+ * Input Parameters:
+ *   spidev - pointer to spi dev structure
+ *   txbuffer - pointer to buffer with data to send
+ *   rxbuffer - pointer to buffer for read data
+ *   nwords - number of words (actually bytes)
+ *
+ * Returned Value:
+ *   None
  *****************************************************************************/
 
 static void s5j_sflash_exchange(FAR struct spi_dev_s *spidev, FAR const void *txbuffer, FAR void *rxbuffer, size_t nwords)
@@ -654,6 +714,14 @@ static void s5j_sflash_exchange(FAR struct spi_dev_s *spidev, FAR const void *tx
  *  Send data from upper-level driver to device.
  *  This function is a part of spi_ops.
  *
+ * Input Parameters:
+ *   spidev - pointer to spi dev structure
+ *   buffer - pointer to buffer with data to send
+ *   nwords - number of words (actually bytes)
+ *
+ * Returned Value:
+ *   None
+ *
  *****************************************************************************/
 
 static void s5j_sflash_sndblock(FAR struct spi_dev_s *spidev, FAR const void *buffer, size_t nwords)
@@ -664,7 +732,7 @@ static void s5j_sflash_sndblock(FAR struct spi_dev_s *spidev, FAR const void *bu
 
        /* it's not word, it's byte */
 
-       s5j_sflash_write(dev, dev->priv.addr, (uint8_t *)buffer, nwords);
+       s5j_sflash_write(dev, dev->priv.addr, (uint8_t *) buffer, nwords);
 
        return;
 }
@@ -676,6 +744,14 @@ static void s5j_sflash_sndblock(FAR struct spi_dev_s *spidev, FAR const void *bu
  *  Recv data from device to upper-level driver
  *  This function is a part of spi_ops.
  *
+ * Input Parameters:
+ *   spidev - pointer to spi dev structure
+ *   buffer - pointer to buffer for read data
+ *   nwords - number of words (actually bytes)
+ *
+ * Returned Value:
+ *   None
+ *
  *****************************************************************************/
 
 static void s5j_sflash_recvblock(FAR struct spi_dev_s *spidev, FAR void *buffer, size_t nwords)
@@ -697,7 +773,10 @@ static void s5j_sflash_recvblock(FAR struct spi_dev_s *spidev, FAR void *buffer,
  * Name: up_spiflashinitialize
  *
  * Description:
- *   Initialize the selected SPI port
+ *   Initialize SPI port
+ *
+ * Input Parameters:
+ *   None
  *
  * Returned Value:
  *   Valid SPI device structure reference on success; a NULL on failure
@@ -706,15 +785,81 @@ static void s5j_sflash_recvblock(FAR struct spi_dev_s *spidev, FAR void *buffer,
 
 FAR struct spi_dev_s *up_spiflashinitialize(void)
 {
-       static bool sflashdev_initialized = 0;
-       /* Lets have single instance */
-       if (sflashdev_initialized == 0) {
+       if (sflashdev == NULL) {
                if (!(sflashdev = kmm_malloc(sizeof(struct s5j_sflash_dev_s)))) {
                        return NULL;
                }
+
                sflashdev->ops = (FAR const struct spi_ops_s *)&s5j_spi_ops;
+
                s5j_sflash_init(sflashdev);
-               sflashdev_initialized = 1;
+               sflashdev->priv.priv = NULL;
        }
+
        return (FAR struct spi_dev_s *)sflashdev;
 }
+
+
+/****************************************************************************
+ * Name: up_spiflashinitialized
+ *
+ * Description:
+ *   Check is spi slash device is initialized.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   == 1, Initialized
+ *   == 0, not initialized
+ *
+ ****************************************************************************/
+
+int up_spiflashinitialized(void)
+{
+       if (sflashdev->priv.priv) {
+               return 1;
+       }
+
+       return 0;
+}
+
+
+/****************************************************************************
+ * Name: update_spiflashmtd
+ *
+ * Description:
+ *   Updates spiflash private field with mtd pointer value
+ *
+ * Input Parameters:
+ *   mtd - pointer to mtd dev structure
+ *
+ * Returned Value:
+ *   none
+ *
+ ****************************************************************************/
+
+void update_spiflashmtd(struct mtd_dev_s *mtd)
+{
+       sflashdev->priv.priv = mtd;
+       return;
+}
+
+/****************************************************************************
+ * Name: getspiflashmtd
+ *
+ * Description:
+ *   Returns spi flash mtd structure pointer
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   mtd dev structure pointer
+ *
+ ****************************************************************************/
+
+struct mtd_dev_s *getspiflashmtd(void)
+{
+       return (struct mtd_dev_s *)sflashdev->priv.priv;
+}
\ No newline at end of file