• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "hdf_log.h"
17 #include "hifmc100.h"
18 #include "mtd_core.h"
19 #include "mtd_spi_nor.h"
20 
21 #define HDF_LOG_TAG w25qh_c
22 
23 #define MTD_SPI_CMD_FIRST_RESET_4ADDR 0x66
24 #define MTD_SPI_CMD_SECOND_RESET_4ADDR 0x99
HifmcCntlrSpinorEntry4AddrW25qh(struct SpiFlash * spi,int enable)25 int32_t HifmcCntlrSpinorEntry4AddrW25qh(struct SpiFlash *spi, int enable)
26 {
27     uint8_t status;
28     unsigned long reg;
29     struct HifmcCntlr *cntlr = NULL;
30 
31     if (spi == NULL || spi->mtd.cntlr == NULL) {
32         return HDF_ERR_INVALID_OBJECT;
33     }
34     cntlr = spi->mtd.cntlr;
35 
36     enable = !!enable; // make it 0 or 1
37     HDF_LOGD("%s: start spinor flash 4-byte mode %s", __func__, (enable == 1) ? "enable" : "disbale");
38 
39     if (spi->addrCycle != MTD_SPI_ADDR_4BYTE) {
40         HDF_LOGD("%s: 4byte addr noty support", __func__);
41         return HDF_SUCCESS;
42     }
43 
44     status = HifmcCntlrReadDevReg(cntlr, spi, MTD_SPI_CMD_RDSR3);
45     HDF_LOGD("%s: read status register 3[%#x]:%#x", __func__, MTD_SPI_CMD_RDSR3, status);
46     if ((status & 0x1) == enable) {
47         HDF_LOGD("%s: 4byte status:%#x, enable:%d", __func__, status, enable);
48         return HDF_SUCCESS;
49     }
50 
51     reg = (enable == 1) ? MTD_SPI_CMD_EN4B : MTD_SPI_CMD_FIRST_RESET_4ADDR;
52     reg = HIFMC_CMD_CMD1(reg);
53     HIFMC_REG_WRITE(cntlr, reg, HIFMC_CMD_REG_OFF);
54 
55     reg = HIFMC_OP_CFG_FM_CS(spi->cs);
56     HIFMC_REG_WRITE(cntlr, reg, HIFMC_OP_CFG_REG_OFF);
57 
58     reg = HIFMC_OP_CMD1_EN(1) | HIFMC_OP_REG_OP_START;
59     HIFMC_REG_WRITE(cntlr, reg, HIFMC_OP_REG_OFF);
60 
61     HIFMC_CMD_WAIT_CPU_FINISH(cntlr);
62 
63     if (enable == 1) {
64         status = HifmcCntlrReadDevReg(cntlr, spi, MTD_SPI_CMD_RDSR3);
65         HDF_LOGD("%s: read status register 3[%#x]:%#x", __func__, MTD_SPI_CMD_RDSR3, status);
66         if ((status & 0x1) == enable) {
67             HDF_LOGD("%s: enable 4byte success, status:%#x", __func__, status);
68             return HDF_SUCCESS;
69         } else {
70             HDF_LOGE("%s: enable 4byte failed, status:%#x", __func__, status);
71             return HDF_ERR_IO;
72         }
73     } else {
74         reg = HIFMC_CMD_CMD1(MTD_SPI_CMD_SECOND_RESET_4ADDR);
75         HIFMC_REG_WRITE(cntlr, reg, HIFMC_CMD_REG_OFF);
76 
77         reg = HIFMC_OP_CFG_FM_CS(spi->cs);
78         HIFMC_REG_WRITE(cntlr, reg, HIFMC_OP_CFG_REG_OFF);
79 
80         reg = HIFMC_OP_CMD1_EN(1) | HIFMC_OP_REG_OP_START;
81         HIFMC_REG_WRITE(cntlr, reg, HIFMC_OP_REG_OFF);
82 
83         HIFMC_CMD_WAIT_CPU_FINISH(cntlr);
84 
85         status = HifmcCntlrReadDevReg(cntlr, spi, MTD_SPI_CMD_RDSR3);
86         HDF_LOGE("%s: disable 4byte done, status:%#x", __func__, status);
87     }
88 
89     HifmcCntlrSet4AddrMode(cntlr, enable);
90     HDF_LOGD("%s: end spinor flash 4-byte mode %s", __func__, (enable == 1) ? "enable" : "disbale");
91     return HDF_SUCCESS;
92 }
93 
HifmcCntlrSpinorQeEnableW25qh(struct SpiFlash * spi)94 int32_t HifmcCntlrSpinorQeEnableW25qh(struct SpiFlash *spi)
95 {
96     uint8_t status;
97     unsigned long reg;
98     int enable;
99     struct HifmcCntlr *cntlr = NULL;
100 
101     if (spi == NULL || spi->mtd.cntlr == NULL) {
102         return HDF_ERR_INVALID_OBJECT;
103     }
104     cntlr = spi->mtd.cntlr;
105 
106     enable = ((spi->writeCfg.ifType >= MTD_SPI_IF_QUAD) ||
107              (spi->readCfg.ifType >= MTD_SPI_IF_QUAD)) ? 1 : 0;
108 
109     status = HifmcCntlrReadDevReg(cntlr, spi, MTD_SPI_CMD_RDSR2);
110     if ((!!(status & MTD_SPI_SR_QE_MASK)) == enable) {
111         HDF_LOGI("%s: qe status:%d, qe enable:%d", __func__, status, enable);
112         return HDF_SUCCESS;
113     }
114 
115     SpiFlashWriteEnable(spi);
116 
117     if (enable == 1) {
118         status |= MTD_SPI_CR_QE_MASK;
119     } else {
120         status &= ~(MTD_SPI_CR_QE_MASK);
121     }
122     OSAL_WRITEB(status, cntlr->memBase);
123 
124     reg = HIFMC_CMD_CMD1(MTD_SPI_CMD_WRSR2);
125     HIFMC_REG_WRITE(cntlr, reg, HIFMC_CMD_REG_OFF);
126 
127     reg = HIFMC_OP_CFG_FM_CS(spi->cs);
128     HIFMC_REG_WRITE(cntlr, reg, HIFMC_OP_CFG_REG_OFF);
129 
130     reg = HIFMC_DATA_NUM_CNT(1);
131     HIFMC_REG_WRITE(cntlr, reg, HIFMC_DATA_NUM_REG_OFF);
132 
133     reg = HIFMC_OP_CMD1_EN(1) |
134           HIFMC_OP_WRITE_DATA_EN(1) |
135           HIFMC_OP_REG_OP_START;
136     HIFMC_REG_WRITE(cntlr, reg, HIFMC_OP_REG_OFF);
137 
138     HIFMC_CMD_WAIT_CPU_FINISH(cntlr);
139 
140     status = HifmcCntlrReadDevReg(cntlr, spi, MTD_SPI_CMD_RDSR2);
141     if ((!!(status & MTD_SPI_SR_QE_MASK)) != enable) {
142         HDF_LOGI("%s: failed, qe status:%d, qe enable:%d", __func__, status, enable);
143         return HDF_ERR_IO;
144     }
145 
146     return HDF_SUCCESS;
147 }
148