lh | 9ed821d | 2023-04-07 01:36:19 -0700 | [diff] [blame] | 1 | /*
|
| 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
|
| 42 | typedef 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
|
| 51 | typedef 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 |
|
| 60 | typedef 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 |
|
| 72 | static 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 |
|
| 93 | static void usdelay(u32 us)
|
| 94 | {
|
| 95 | u32 count;
|
| 96 |
|
| 97 | for(count = 0 ; count < us* 1000; count++);
|
| 98 | }
|
| 99 |
|
| 100 | static 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 |
|
| 146 | static 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 |
|
| 159 | static 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 |
|
| 175 | static 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 |
|
| 207 | static void ssp_init(T_SspDev* sspDev)
|
| 208 | {
|
| 209 | sspGpio_config(sspDev);
|
| 210 | sspClk_enable(sspDev);
|
| 211 | sspConfig_init(sspDev);
|
| 212 | }
|
| 213 |
|
| 214 | static void ssp_uninit(T_SspDev* sspDev)
|
| 215 | {
|
| 216 | sspClk_disable(sspDev);
|
| 217 | }
|
| 218 |
|
| 219 | void* 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 |
|
| 229 | void ssp_close(void* handler)
|
| 230 | {
|
| 231 | T_SspDev* sspDev = (T_SspDev*)handler;
|
| 232 | ssp_uninit(sspDev);
|
| 233 | }
|
| 234 |
|
| 235 |
|
| 236 | int 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 |
|
| 275 | return count;
|
| 276 |
|
| 277 | }
|
| 278 |
|
| 279 |
|