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