1 /*
2 * Copyright (c) 2020 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 <boot_rom.h>
17
18 /* QE for MX */
spi_flash_enable_quad_mode_mx(hi_void)19 hi_u32 spi_flash_enable_quad_mode_mx(hi_void)
20 {
21 hi_u32 ret;
22 hi_u8 data = 0;
23
24 ret = spi_flash_read_reg(SPI_CMD_RDSR, &data, 1);
25 if (ret != HI_ERR_SUCCESS) {
26 return ret;
27 }
28
29 /* QE bit is enable already, do nothing. */
30 if (data & SPI_QE_EN_MX) {
31 return HI_ERR_SUCCESS;
32 }
33
34 data |= SPI_QE_EN_MX;
35 ret = spi_flash_write_reg(SPI_CMD_WRSRCR, &data, 1);
36 if (ret != HI_ERR_SUCCESS) {
37 return ret;
38 }
39
40 ret = spi_flash_read_reg(SPI_CMD_RDSR, &data, 1);
41 if (ret != HI_ERR_SUCCESS) {
42 return ret;
43 }
44
45 /* QE bit is enable already, do nothing */
46 if (data & SPI_QE_EN_MX) {
47 return HI_ERR_SUCCESS;
48 }
49
50 return HI_ERR_FLASH_QUAD_MODE_COMPARE_REG;
51 }
52
53
54 /* QE for W25Q */
spi_flash_enable_quad_mode(hi_void)55 hi_u32 spi_flash_enable_quad_mode(hi_void)
56 {
57 hi_u32 ret;
58 hi_u8 data[2] = { 0 }; /* flash has 2 RDSR reg */
59
60 ret = spi_flash_read_reg(SPI_CMD_RDSR2, &data[1], 1);
61 if (ret != HI_ERR_SUCCESS) {
62 return ret;
63 }
64
65 /* QE bit is enable already, do nothing */
66 if (data[1] & SPI_QE_EN) {
67 return HI_ERR_SUCCESS;
68 }
69
70 ret = spi_flash_read_reg(SPI_CMD_RDSR, &data[0], 1);
71 if (ret != HI_ERR_SUCCESS) {
72 return ret;
73 }
74
75 /* SPI_CMD_WRSR1 is compatible with the old flash. */
76 data[1] |= SPI_QE_EN;
77 ret = spi_flash_write_reg(SPI_CMD_WRSR1, data, 2); /* flash has 2 RDSR reg */
78 if (ret != HI_ERR_SUCCESS) {
79 return ret;
80 }
81
82 ret = spi_flash_read_reg(SPI_CMD_RDSR2, &data[1], 1);
83 if (ret != HI_ERR_SUCCESS) {
84 return ret;
85 }
86
87 if (data[1] & SPI_QE_EN) {
88 return HI_ERR_SUCCESS;
89 }
90
91 return HI_ERR_FLASH_QUAD_MODE_COMPARE_REG;
92 }
93
spi_flash_configure_driver_strength(hi_flash_drv_strength drv_strength)94 hi_u32 spi_flash_configure_driver_strength(hi_flash_drv_strength drv_strength)
95 {
96 hi_u8 data = 0;
97 hi_u32 ret;
98
99 if (drv_strength >= SPI_SR3_DRV_MAX) {
100 return HI_ERR_FLASH_INVALID_PARAMETER;
101 }
102
103 ret = spi_flash_read_reg(SPI_CMD_RDSR3, &data, 1);
104 if (ret != HI_ERR_SUCCESS) {
105 return ret;
106 }
107
108 if (((hi_u32)drv_strength << 5) == (data & (SPI_SR3_DRV_MASK << 5))) { /* left shift 5bit */
109 return HI_ERR_SUCCESS;
110 }
111
112 data &= ~(SPI_SR3_DRV_MASK << 5); /* left shift 5bit */
113 data |= (hi_u32)drv_strength << 5; /* left shift 5bit */
114 ret = spi_flash_write_reg(SPI_CMD_WRSR3, &data, 1);
115
116 return ret;
117 }
118