1 /*
2 * Copyright (c) 2021 Bestechnic (Shanghai) Co., Ltd. All rights reserved.
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 #ifdef CHIP_HAS_SPIPHY
16
17 #include "plat_types.h"
18 #include "cmsis.h"
19 #include "hal_phyif.h"
20 #include "hal_spi.h"
21 #include "hal_location.h"
22
23 #ifdef CHIP_BEST2003
24 #define PHY_SPI_TX_BITS 27
25 #define PHY_SPI_RX_BITS 27
26 #define PHY_READ_CMD(r) ((1 << 26) | (((r) & 0x3FF) << 16))
27 #define PHY_WRITE_CMD(r, v) ((((r) & 0x3FF) << 16) | ((v) & 0xFFFF))
28 #define PHY_READ_VAL(v) ((v) & 0xFFFF)
29
30 #define SPIPHY_REG_CS(r) ((r) >> 12)
31 #define SPIPHY_REG_OFFSET(r) ((r) & 0x3FF)
32 #else
33 #define PHY_SPI_TX_BITS 25
34 #define PHY_SPI_RX_BITS 25
35 #define PHY_READ_CMD(r) ((1 << 24) | (((r) & 0xFF) << 16))
36 #define PHY_WRITE_CMD(r, v) ((((r) & 0xFF) << 16) | ((v) & 0xFFFF))
37 #define PHY_READ_VAL(v) ((v) & 0xFFFF)
38
39 #define SPIPHY_REG_CS(r) ((r) >> 12)
40 #define SPIPHY_REG_PAGE(r) (((r) >> 8) & 0xF)
41 #define SPIPHY_REG_OFFSET(r) ((r) & 0xFF)
42 #endif
43
44 static const struct HAL_SPI_CFG_T spi_cfg = {
45 .clk_delay_half = false,
46 .clk_polarity = false,
47 .slave = false,
48 .dma_rx = false,
49 .dma_tx = false,
50 .rx_sep_line = true,
51 .cs = 0,
52 .rate = 6500000,
53 .tx_bits = PHY_SPI_TX_BITS,
54 .rx_bits = PHY_SPI_RX_BITS,
55 .rx_frame_bits = 0,
56 };
57
58 static uint8_t BOOT_BSS_LOC phyif_open_map;
59
60 static uint8_t BOOT_BSS_LOC phy_cs;
61
hal_phyif_rawread(unsigned short reg,unsigned short * val)62 static int hal_phyif_rawread(unsigned short reg, unsigned short *val)
63 {
64 int ret;
65 unsigned int data;
66 unsigned int cmd;
67
68 data = 0;
69 cmd = PHY_READ_CMD(reg);
70 ret = hal_spiphy_recv(&cmd, &data, 4);
71 if (ret) {
72 return ret;
73 }
74 *val = PHY_READ_VAL(data);
75 return 0;
76 }
77
hal_phyif_rawwrite(unsigned short reg,unsigned short val)78 static int hal_phyif_rawwrite(unsigned short reg, unsigned short val)
79 {
80 int ret;
81 unsigned int cmd;
82
83 cmd = PHY_WRITE_CMD(reg, val);
84 ret = hal_spiphy_send(&cmd, 4);
85 if (ret) {
86 return ret;
87 }
88 return 0;
89 }
90
hal_phyif_reg_read(unsigned short reg,unsigned short * val)91 int hal_phyif_reg_read(unsigned short reg, unsigned short *val)
92 {
93 uint32_t lock;
94 int ret;
95 uint8_t cs;
96 //uint8_t page;
97
98 cs = SPIPHY_REG_CS(reg);
99 //page = SPIPHY_REG_PAGE(reg);
100 reg = SPIPHY_REG_OFFSET(reg);
101
102 lock = int_lock();
103 if (cs != phy_cs) {
104 hal_spiphy_activate_cs(cs);
105 phy_cs = cs;
106 }
107 ret = hal_phyif_rawread(reg, val);
108 int_unlock(lock);
109
110 return ret;
111 }
112
hal_phyif_reg_write(unsigned short reg,unsigned short val)113 int hal_phyif_reg_write(unsigned short reg, unsigned short val)
114 {
115 uint32_t lock;
116 int ret;
117 uint8_t cs;
118 //uint8_t page;
119
120 cs = SPIPHY_REG_CS(reg);
121 //page = SPIPHY_REG_PAGE(reg);
122 reg = SPIPHY_REG_OFFSET(reg);
123
124 lock = int_lock();
125 if (cs != phy_cs) {
126 hal_spiphy_activate_cs(cs);
127 phy_cs = cs;
128 }
129 ret = hal_phyif_rawwrite(reg, val);
130 int_unlock(lock);
131
132 return ret;
133 }
134
hal_phyif_open(uint32_t cs)135 int hal_phyif_open(uint32_t cs)
136 {
137 int ret;
138 uint32_t lock;
139
140 ret = 0;
141
142 lock = int_lock();
143 if (phyif_open_map == 0) {
144 ret = hal_spiphy_open(&spi_cfg);
145 }
146 if (ret == 0) {
147 phyif_open_map |= (1 << cs);
148 }
149 int_unlock(lock);
150
151 return ret;
152 }
153
hal_phyif_close(uint32_t cs)154 int hal_phyif_close(uint32_t cs)
155 {
156 int ret;
157 uint32_t lock;
158
159 ret = 0;
160
161 lock = int_lock();
162 phyif_open_map &= ~(1 << cs);
163 if (phyif_open_map == 0) {
164 ret = hal_spiphy_close(spi_cfg.cs);
165 }
166 int_unlock(lock);
167
168 return ret;
169 }
170
171 #endif
172