blob: ad0d4f9cf173630dcc12c1fc9a4c9c48680b8c2d [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/*
2|| ADD SPI DRVER FOR LCD DISPLAY
3*/
4
5#include <common.h>
6#include <drvs_gpio.h>
7
8#include <ssp.h>
9#include <config.h>
10
11#define REG32(x) (*(volatile u32*)(x))
12
13#define ZX29_SSP0_BASE 0x0140a000
14#define LSP_CRPM_SPI0_CLKREG (0x01400000 + 0x30)
15#define ZX29_SSP1_BASE 0x01410000
16#define LSP_CRPM_SPI1_CLKREG (0x01400000 + 0x48)
17
18#define SSP_COM_CTRL 0x04
19#define SSP_COM_CTRL_SSPEN (1 << 1)
20#define SSP_COM_CTRL_SSPEN_POS 1
21#define SSP_COM_CTRL_MASTER (1 << 2)
22#define SSP_COM_CTRL_MASTER_POS 2
23
24#define SSP_FMT_CTRL 0x08
25#define SSP_FMT_CTRL_POL (0x3 << 2)
26#define SSP_FMT_CTRL_POL_POS 2
27#define SSP_FMT_CTRL_DSS (0x1f << 4)
28#define SSP_FMT_CTRL_DSS_POS 4
29
30#define SSP_DATA_DR 0x0c
31#define SSP_FIFO_CTRL 0x10
32#define SSP_FIFO_CTRL_TXTHRES (0xf << 8)
33#define SSP_FIFO_CTRL_TXTHRES_POS 8
34
35#define SSP_FIFO_SR 0x14
36#define SSP_INT_EN 0x18
37#define SSP_INT_SC 0x1c
38#define SSP_TRANS_TIMEING 0x20
39
40
41//define ssp mode
42typedef enum _E_SspXferWidth
43{
44 SSP_WIDTH_BIT_8 = 7,
45 SSP_WIDTH_BIT_16 = 15,
46 SSP_WIDTH_BIT_32 = 31
47}E_SspXferWidth;
48
49
50//define ssp mode
51typedef enum _E_SspPolarity
52{
53 SPH_SPO_00 = 0x0,
54 SPH_SPO_01 = 0x1,
55 SPH_SPO_10 = 0x2,
56 SPH_SPO_11 = 0x3
57}E_SspPolarity;
58
59
60typedef struct
61{
62 u8 devNum; //indicate the ssp device num
63 u32 regBase;
64
65 E_SspPolarity polarity;
66 E_SspXferWidth xferWidth;
67 unsigned char master;
68 unsigned int fifoTxThres;
69}T_SspDev;
70
71
72static T_SspDev g_SspDev[SSP_DEV_NUM]=
73{
74 [0]={
75 .devNum = SSP_DEV_0,
76 .regBase = ZX29_SSP0_BASE,
77 .polarity =SPH_SPO_00,
78 .xferWidth = SSP_WIDTH_BIT_8,
79 .master = 0,
80 .fifoTxThres = 3,
81 },
82 [1]={
83 .devNum =SSP_DEV_1,
84 .regBase =ZX29_SSP1_BASE,
85 .polarity =SPH_SPO_00,
86 .xferWidth =SSP_WIDTH_BIT_8,
87 .master = 0, // 0:master; 1: slave
88 .fifoTxThres = 3, //thres 8
89 },
90};
91
92
93static void usdelay(u32 us)
94{
95 u32 count;
96
97 for(count = 0 ; count < us* 1000; count++);
98}
99
100static void sspClk_enable(T_SspDev* sspDev)
101{
102
103 if(sspDev->devNum == SSP_DEV_0)
104 {
105 REG32(LSP_CRPM_SPI0_CLKREG) &= ~(0x3 << 8);
106 usdelay(20);
107 REG32(LSP_CRPM_SPI0_CLKREG) = (0x3 << 8);
108 usdelay(20);
109
110 // CLK SEL 26M
111 REG32(LSP_CRPM_SPI0_CLKREG) |= (0x0 << 4); //(0x2 << 4);
112#if defined(CONFIG_ZX297520V3E_FWP)
113 REG32(LSP_CRPM_SPI0_CLKREG) |= (0x3 << 12); // max 0xf
114#else
115 REG32(LSP_CRPM_SPI0_CLKREG) |= (0x0 << 12); // max 0xf
116#endif
117 // enable ssp1 pclk wclk
118 REG32(LSP_CRPM_SPI0_CLKREG) |= (0x3);
119
120 usdelay(20);
121 // auto ssp1 wclk
122 REG32(LSP_CRPM_SPI0_CLKREG) |= (0x3 << 10); //(0x1 << 10);
123 return;
124 }
125 else if(sspDev->devNum == SSP_DEV_1)
126 {
127 REG32(LSP_CRPM_SPI1_CLKREG) &= ~(0x3 << 8);
128 usdelay(20);
129 REG32(LSP_CRPM_SPI1_CLKREG) = (0x3 << 8);
130 usdelay(20);
131
132 // enable ssp1 pclk wclk
133 REG32(LSP_CRPM_SPI1_CLKREG) |= (0x3);
134
135 // CLK SEL 26M
136 REG32(LSP_CRPM_SPI1_CLKREG) |= (0x0 << 4);
137 REG32(LSP_CRPM_SPI1_CLKREG) |= (0x0 << 12); // max 0xf
138
139 usdelay(20);
140 // auto ssp1 wclk
141 REG32(LSP_CRPM_SPI1_CLKREG) |= (0x3 << 10);
142 return;
143 }
144}
145
146static void sspClk_disable(T_SspDev* sspDev)
147{
148 if(sspDev->devNum == SSP_DEV_0)
149 {
150 REG32(LSP_CRPM_SPI0_CLKREG) &= ~(0x3);
151 }
152 else if(sspDev->devNum == SSP_DEV_1)
153 {
154 REG32(LSP_CRPM_SPI1_CLKREG) &= ~(0x3);
155 }
156}
157
158
159static void sspGpio_config(T_SspDev* sspDev)
160{
161 if(sspDev->devNum == SSP_DEV_0)
162 {
163 zDrvGpio_SetFunc(GPIO25, GPIO25_SSP0_CS);
164 zDrvGpio_SetFunc(GPIO26, GPIO26_SSP0_CLK);
165 zDrvGpio_SetFunc(GPIO28, GPIO28_SSP0_TXD);
166 }
167 else if(sspDev->devNum == SSP_DEV_1)
168 {
169 //zDrvGpio_SetFunc(GPIO87, GPIO87_CAM_SPI_CS);
170 //zDrvGpio_SetFunc(GPIO88, GPIO88_CAM_SPI_CLK);
171 //(GPIO90, GPIO90_CAM_SPI_TXD);
172 }
173}
174
175static void sspConfig_init(T_SspDev* sspDev)
176{
177 //config M/S
178 REG32(sspDev->regBase + SSP_COM_CTRL) &= ~SSP_COM_CTRL_MASTER;
179 REG32(sspDev->regBase + SSP_COM_CTRL) |= (sspDev->master << SSP_COM_CTRL_MASTER_POS);
180 //config ssp mode :default
181
182 REG32(sspDev->regBase + SSP_FMT_CTRL) &= ~(SSP_FMT_CTRL_POL | SSP_FMT_CTRL_DSS);
183 //config POL
184 REG32(sspDev->regBase + SSP_FMT_CTRL) |= (sspDev->polarity << SSP_FMT_CTRL_POL_POS);
185 //config bus width
186 REG32(sspDev->regBase + SSP_FMT_CTRL) |= (sspDev->xferWidth << SSP_FMT_CTRL_DSS_POS);
187
188 //config fifo
189 REG32(sspDev->regBase + SSP_FIFO_CTRL) &= ~SSP_FIFO_CTRL_TXTHRES;
190 REG32(sspDev->regBase + SSP_FIFO_CTRL) |= (sspDev->fifoTxThres << SSP_FIFO_CTRL_TXTHRES_POS);
191
192 //config fifo
193 REG32(sspDev->regBase + SSP_TRANS_TIMEING) = (0xe);
194
195 // close all int
196 REG32(sspDev->regBase + SSP_INT_EN) = 0x0;
197 //enable SSP
198 usdelay(80);
199
200 while(REG32(sspDev->regBase + SSP_COM_CTRL) & (0x1 << 4));
201 REG32(sspDev->regBase + SSP_COM_CTRL) |= (0x1 << 1 );
202 usdelay(80);
203 while ((REG32(sspDev->regBase + SSP_COM_CTRL) & (0x1 << 4)) == 0);
204
205}
206
207static void ssp_init(T_SspDev* sspDev)
208{
209 sspGpio_config(sspDev);
210 sspClk_enable(sspDev);
211 sspConfig_init(sspDev);
212}
213
214static void ssp_uninit(T_SspDev* sspDev)
215{
216 sspClk_disable(sspDev);
217}
218
219void* ssp_open(u8 num)
220{
221 if(num >= SSP_DEV_NUM)
222 return NULL;
223
224 ssp_init(&g_SspDev[num]);
225
226 return (void*)&g_SspDev[num];
227}
228
229void ssp_close(void* handler)
230{
231 T_SspDev* sspDev = (T_SspDev*)handler;
232 ssp_uninit(sspDev);
233}
234
235
236int ssp_transfer(void* handler, u8* buf, u32 length)
237{
238 T_SspDev* sspDev = (T_SspDev*)handler;
239
240 u32 count = 0;
241 u32 data;
242
243 if(!sspDev || !buf)
244 return 0;
245 //add chip select
246
247 if(sspDev->xferWidth == SSP_WIDTH_BIT_8){
248 u8* pbuf = (u8*)buf;
249 do{
250 REG32(sspDev->regBase + SSP_DATA_DR) = pbuf[count];
251 while(REG32(sspDev->regBase + SSP_FIFO_SR)& (1 << 4));
252 count++;
253
254 }while(count < length);
255
256 }else if(sspDev->xferWidth == SSP_WIDTH_BIT_16){
257 u16* pbuf = (u16*)buf;
258 do{
259 REG32(sspDev->regBase + SSP_DATA_DR) = pbuf[count];
260 while(REG32(sspDev->regBase + SSP_FIFO_SR)& (1 << 4));
261 count += 2;
262
263 }while(count < length);
264
265 }else if(sspDev->xferWidth == SSP_WIDTH_BIT_32){
266 do{
267 u32* pbuf = (u32*)buf;
268 REG32(sspDev->regBase + SSP_DATA_DR) = pbuf[count];
269 while(REG32(sspDev->regBase + SSP_FIFO_SR)& (1 << 4));
270 count += 4;
271
272 }while(count < length);
273 }
274
275return count;
276
277}
278
279