Date:2010-10-18 10:12:30 (13 years 5 months ago)
Author:Xiangfu Liu
Commit:d2f389bd2b56e0a8b4cee566560c97a01f0f3f83
Message:move mmc files to drivers/mmc/ move lcm files to drivers/video/

cleanup jz_mmc output, make it more readable.

Signed-off-by: Xiangfu Liu <xiangfu@sharism.cc>
Files: package/uboot-xburst/files/arch/mips/cpu/xburst/Makefile (1 diff)
package/uboot-xburst/files/arch/mips/cpu/xburst/jz_mmc.c (1 diff)
package/uboot-xburst/files/arch/mips/cpu/xburst/jz_mmc.h (1 diff)
package/uboot-xburst/files/arch/mips/cpu/xburst/nanonote_gpm940b0.c (1 diff)
package/uboot-xburst/files/arch/mips/cpu/xburst/nanonote_gpm940b0.h (1 diff)
package/uboot-xburst/files/drivers/mmc/jz_mmc.c (1 diff)
package/uboot-xburst/files/drivers/mmc/jz_mmc.h (1 diff)
package/uboot-xburst/files/drivers/video/nanonote_gpm940b0.c (1 diff)
package/uboot-xburst/files/drivers/video/nanonote_gpm940b0.h (1 diff)
package/uboot-xburst/files/include/configs/nanonote.h (1 diff)
package/uboot-xburst/patches/001-xburst.patch (2 diffs)

Change Details

package/uboot-xburst/files/arch/mips/cpu/xburst/Makefile
2929SOBJS-y =
3030COBJS-y = cpu.o interrupts.o jz4740.o jz_serial.o
3131
32COBJS-y += jz_mmc.o
33COBJS-$(CONFIG_NANONOTE) += nanonote_gpm940b0.o
34COBJS-$(CONFIG_SAKC) += nanonote_gpm940b0.o
35
3632SRCS := $(START:.o=.S) $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
3733OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
3834START := $(addprefix $(obj),$(START))
package/uboot-xburst/files/arch/mips/cpu/xburst/jz_mmc.c
1/*
2 * (C) Copyright 2003
3 * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 */
23
24#include <config.h>
25#include <common.h>
26#include <part.h>
27#include <mmc.h>
28
29#include <asm/jz4740.h>
30#include "jz_mmc.h"
31
32#define CFG_MMC_BASE 0x80600000
33static int sd2_0 = 0;
34
35/*
36 * GPIO definition
37 */
38#if defined(CONFIG_SAKC)
39
40#define __msc_init_io() \
41do { \
42    __gpio_as_input(GPIO_SD_CD_N); \
43} while (0)
44
45#else
46#define __msc_init_io() \
47do { \
48    __gpio_as_output(GPIO_SD_VCC_EN_N); \
49    __gpio_as_input(GPIO_SD_CD_N); \
50} while (0)
51
52#define __msc_enable_power() \
53do { \
54    __gpio_clear_pin(GPIO_SD_VCC_EN_N); \
55} while (0)
56
57#define __msc_disable_power() \
58do { \
59    __gpio_set_pin(GPIO_SD_VCC_EN_N); \
60} while (0)
61
62#endif /* CONFIG_SAKE */
63
64#define __msc_card_detected() \
65({ \
66    int detected = 1; \
67    __gpio_as_input(GPIO_SD_CD_N); \
68    __gpio_disable_pull(GPIO_SD_CD_N); \
69    if (!__gpio_get_pin(GPIO_SD_CD_N)) \
70        detected = 0; \
71    detected; \
72})
73
74/*
75 * Local functions
76 */
77
78#ifdef CONFIG_MMC
79extern int
80fat_register_device(block_dev_desc_t *dev_desc, int part_no);
81
82static block_dev_desc_t mmc_dev;
83
84block_dev_desc_t * mmc_get_dev(int dev)
85{
86    return ((block_dev_desc_t *)&mmc_dev);
87}
88
89/*
90 * FIXME needs to read cid and csd info to determine block size
91v * and other parameters
92 */
93static uchar mmc_buf[MMC_BLOCK_SIZE];
94static int mmc_ready = 0;
95static struct mmc_csd mmc_csd;
96static int use_4bit; /* Use 4-bit data bus */
97/*
98 * MMC Events
99 */
100#define MMC_EVENT_NONE 0x00 /* No events */
101#define MMC_EVENT_RX_DATA_DONE 0x01 /* Rx data done */
102#define MMC_EVENT_TX_DATA_DONE 0x02 /* Tx data done */
103#define MMC_EVENT_PROG_DONE 0x04 /* Programming is done */
104
105
106#define MMC_IRQ_MASK() \
107do { \
108          REG_MSC_IMASK = 0xffff; \
109          REG_MSC_IREG = 0xffff; \
110} while (0)
111
112/* Stop the MMC clock and wait while it happens */
113static inline int jz_mmc_stop_clock(void)
114{
115    int timeout = 1000;
116
117    REG_MSC_STRPCL = MSC_STRPCL_CLOCK_CONTROL_STOP;
118
119    while (timeout && (REG_MSC_STAT & MSC_STAT_CLK_EN)) {
120        timeout--;
121        if (timeout == 0)
122            return MMC_ERROR_TIMEOUT;
123        udelay(1);
124    }
125        return MMC_NO_ERROR;
126}
127
128/* Start the MMC clock and operation */
129static inline int jz_mmc_start_clock(void)
130{
131    REG_MSC_STRPCL = MSC_STRPCL_CLOCK_CONTROL_START | MSC_STRPCL_START_OP;
132    return MMC_NO_ERROR;
133}
134
135static inline u32 jz_mmc_calc_clkrt(int is_sd, u32 rate)
136{
137    u32 clkrt = 0;
138    u32 clk_src = is_sd ? 24000000 : 16000000;
139
140      while (rate < clk_src) {
141              clkrt ++;
142              clk_src >>= 1;
143        }
144
145    return clkrt;
146}
147
148/* Set the MMC clock frequency */
149void jz_mmc_set_clock(int sd, u32 rate)
150{
151    jz_mmc_stop_clock();
152
153    /* Select clock source of MSC */
154    __cpm_select_msc_clk(sd);
155
156    /* Set clock dividor of MSC */
157    REG_MSC_CLKRT = jz_mmc_calc_clkrt(sd, rate);
158}
159
160static int jz_mmc_check_status(struct mmc_request *request)
161{
162    u32 status = REG_MSC_STAT;
163
164    /* Checking for response or data timeout */
165    if (status & (MSC_STAT_TIME_OUT_RES | MSC_STAT_TIME_OUT_READ)) {
166        printf("MMC/SD timeout, MMC_STAT 0x%x CMD %d\n", status, request->cmd);
167        return MMC_ERROR_TIMEOUT;
168    }
169
170    /* Checking for CRC error */
171    if (status & (MSC_STAT_CRC_READ_ERROR | MSC_STAT_CRC_WRITE_ERROR | MSC_STAT_CRC_RES_ERR)) {
172        printf("MMC/CD CRC error, MMC_STAT 0x%x\n", status);
173        return MMC_ERROR_CRC;
174    }
175
176    return MMC_NO_ERROR;
177}
178
179/* Obtain response to the command and store it to response buffer */
180static void jz_mmc_get_response(struct mmc_request *request)
181{
182    int i;
183    u8 *buf;
184    u32 data;
185
186    debug("fetch response for request %d, cmd %d\n",
187          request->rtype, request->cmd);
188
189    buf = request->response;
190    request->result = MMC_NO_ERROR;
191
192    switch (request->rtype) {
193    case RESPONSE_R1: case RESPONSE_R1B: case RESPONSE_R6:
194    case RESPONSE_R3: case RESPONSE_R4: case RESPONSE_R5:
195    {
196        data = REG_MSC_RES;
197        buf[0] = (data >> 8) & 0xff;
198        buf[1] = data & 0xff;
199        data = REG_MSC_RES;
200        buf[2] = (data >> 8) & 0xff;
201        buf[3] = data & 0xff;
202        data = REG_MSC_RES;
203        buf[4] = data & 0xff;
204
205        debug("request %d, response [%02x %02x %02x %02x %02x]\n",
206              request->rtype, buf[0], buf[1], buf[2], buf[3], buf[4]);
207        break;
208    }
209    case RESPONSE_R2_CID: case RESPONSE_R2_CSD:
210    {
211        for (i = 0; i < 16; i += 2) {
212            data = REG_MSC_RES;
213            buf[i] = (data >> 8) & 0xff;
214            buf[i+1] = data & 0xff;
215        }
216        debug("request %d, response [", request->rtype);
217#if CONFIG_MMC_DEBUG_VERBOSE > 2
218        if (g_mmc_debug >= 3) {
219            int n;
220            for (n = 0; n < 17; n++)
221                printk("%02x ", buf[n]);
222            printk("]\n");
223        }
224#endif
225        break;
226    }
227    case RESPONSE_NONE:
228        debug("No response\n");
229        break;
230
231    default:
232        debug("unhandled response type for request %d\n", request->rtype);
233        break;
234    }
235}
236
237static int jz_mmc_receive_data(struct mmc_request *req)
238{
239    u32 stat, timeout, data, cnt;
240    u8 *buf = req->buffer;
241    u32 wblocklen = (u32)(req->block_len + 3) >> 2; /* length in word */
242
243    timeout = 0x3ffffff;
244
245    while (timeout) {
246        timeout--;
247        stat = REG_MSC_STAT;
248
249        if (stat & MSC_STAT_TIME_OUT_READ)
250            return MMC_ERROR_TIMEOUT;
251        else if (stat & MSC_STAT_CRC_READ_ERROR)
252            return MMC_ERROR_CRC;
253        else if (!(stat & MSC_STAT_DATA_FIFO_EMPTY)
254             || (stat & MSC_STAT_DATA_FIFO_AFULL)) {
255            /* Ready to read data */
256            break;
257        }
258        udelay(1);
259    }
260    if (!timeout)
261        return MMC_ERROR_TIMEOUT;
262
263    /* Read data from RXFIFO. It could be FULL or PARTIAL FULL */
264    cnt = wblocklen;
265    while (cnt) {
266        data = REG_MSC_RXFIFO;
267        {
268            *buf++ = (u8)(data >> 0);
269            *buf++ = (u8)(data >> 8);
270            *buf++ = (u8)(data >> 16);
271            *buf++ = (u8)(data >> 24);
272        }
273        cnt --;
274        while (cnt && (REG_MSC_STAT & MSC_STAT_DATA_FIFO_EMPTY))
275            ;
276    }
277    return MMC_NO_ERROR;
278}
279
280static int jz_mmc_transmit_data(struct mmc_request *req)
281{
282#if 0
283    u32 nob = req->nob;
284    u32 wblocklen = (u32)(req->block_len + 3) >> 2; /* length in word */
285    u8 *buf = req->buffer;
286    u32 *wbuf = (u32 *)buf;
287    u32 waligned = (((u32)buf & 0x3) == 0); /* word aligned ? */
288    u32 stat, timeout, data, cnt;
289
290    for (nob; nob >= 1; nob--) {
291        timeout = 0x3FFFFFF;
292
293        while (timeout) {
294            timeout--;
295            stat = REG_MSC_STAT;
296
297            if (stat & (MSC_STAT_CRC_WRITE_ERROR | MSC_STAT_CRC_WRITE_ERROR_NOSTS))
298                return MMC_ERROR_CRC;
299            else if (!(stat & MSC_STAT_DATA_FIFO_FULL)) {
300                /* Ready to write data */
301                break;
302            }
303
304            udelay(1);
305        }
306
307        if (!timeout)
308            return MMC_ERROR_TIMEOUT;
309
310        /* Write data to TXFIFO */
311        cnt = wblocklen;
312        while (cnt) {
313            while (REG_MSC_STAT & MSC_STAT_DATA_FIFO_FULL)
314                ;
315
316            if (waligned) {
317                REG_MSC_TXFIFO = *wbuf++;
318            }
319            else {
320                data = *buf++ | (*buf++ << 8) | (*buf++ << 16) | (*buf++ << 24);
321                REG_MSC_TXFIFO = data;
322            }
323
324            cnt--;
325        }
326    }
327#endif
328    return MMC_NO_ERROR;
329}
330
331
332/*
333 * Name: int jz_mmc_exec_cmd()
334 * Function: send command to the card, and get a response
335 * Input: struct mmc_request *req : MMC/SD request
336 * Output: 0: right >0: error code
337 */
338int jz_mmc_exec_cmd(struct mmc_request *request)
339{
340    u32 cmdat = 0, events = 0;
341    int retval, timeout = 0x3fffff;
342
343    /* Indicate we have no result yet */
344    request->result = MMC_NO_RESPONSE;
345    if (request->cmd == MMC_CIM_RESET) {
346        /* On reset, 1-bit bus width */
347        use_4bit = 0;
348
349        /* Reset MMC/SD controller */
350        __msc_reset();
351
352        /* On reset, drop MMC clock down */
353        jz_mmc_set_clock(0, MMC_CLOCK_SLOW);
354
355        /* On reset, stop MMC clock */
356        jz_mmc_stop_clock();
357    }
358    if (request->cmd == MMC_CMD_SEND_OP_COND) {
359        debug("Have an MMC card\n");
360        /* always use 1bit for MMC */
361        use_4bit = 0;
362    }
363    if (request->cmd == SET_BUS_WIDTH) {
364        if (request->arg == 0x2) {
365            printf("Use 4-bit bus width\n");
366            use_4bit = 1;
367        }
368        else {
369            printf("Use 1-bit bus width\n");
370            use_4bit = 0;
371        }
372    }
373
374    /* stop clock */
375    jz_mmc_stop_clock();
376
377    /* mask all interrupts */
378    REG_MSC_IMASK = 0xffff;
379
380    /* clear status */
381    REG_MSC_IREG = 0xffff;
382
383    /* use 4-bit bus width when possible */
384    if (use_4bit)
385        cmdat |= MSC_CMDAT_BUS_WIDTH_4BIT;
386
387        /* Set command type and events */
388    switch (request->cmd) {
389    /* MMC core extra command */
390    case MMC_CIM_RESET:
391        cmdat |= MSC_CMDAT_INIT; /* Initialization sequence sent prior to command */
392        break;
393
394    /* bc - broadcast - no response */
395    case MMC_CMD_GO_IDLE_STATE:
396    case MMC_CMD_SET_DSR:
397        break;
398
399    /* bcr - broadcast with response */
400    case MMC_CMD_SEND_OP_COND:
401    case MMC_CMD_ALL_SEND_CID:
402    case MMC_GO_IRQ_STATE:
403        break;
404
405    /* adtc - addressed with data transfer */
406    case MMC_READ_DAT_UNTIL_STOP:
407    case MMC_CMD_READ_SINGLE_BLOCK:
408    case MMC_CMD_READ_MULTIPLE_BLOCK:
409    case SD_CMD_APP_SEND_SCR:
410        cmdat |= MSC_CMDAT_DATA_EN | MSC_CMDAT_READ;
411        events = MMC_EVENT_RX_DATA_DONE;
412        break;
413
414    case MMC_WRITE_DAT_UNTIL_STOP:
415    case MMC_CMD_WRITE_SINGLE_BLOCK:
416    case MMC_CMD_WRITE_MULTIPLE_BLOCK:
417    case MMC_PROGRAM_CID:
418    case MMC_PROGRAM_CSD:
419    case MMC_SEND_WRITE_PROT:
420    case MMC_GEN_CMD:
421    case MMC_LOCK_UNLOCK:
422        cmdat |= MSC_CMDAT_DATA_EN | MSC_CMDAT_WRITE;
423        events = MMC_EVENT_TX_DATA_DONE | MMC_EVENT_PROG_DONE;
424
425        break;
426
427    case MMC_CMD_STOP_TRANSMISSION:
428        events = MMC_EVENT_PROG_DONE;
429        break;
430
431    /* ac - no data transfer */
432    default:
433        break;
434    }
435
436    /* Set response type */
437    switch (request->rtype) {
438    case RESPONSE_NONE:
439        break;
440
441    case RESPONSE_R1B:
442        cmdat |= MSC_CMDAT_BUSY;
443        /*FALLTHRU*/
444    case RESPONSE_R1:
445        cmdat |= MSC_CMDAT_RESPONSE_R1;
446        break;
447    case RESPONSE_R2_CID:
448    case RESPONSE_R2_CSD:
449        cmdat |= MSC_CMDAT_RESPONSE_R2;
450        break;
451    case RESPONSE_R3:
452        cmdat |= MSC_CMDAT_RESPONSE_R3;
453        break;
454    case RESPONSE_R4:
455        cmdat |= MSC_CMDAT_RESPONSE_R4;
456        break;
457    case RESPONSE_R5:
458        cmdat |= MSC_CMDAT_RESPONSE_R5;
459        break;
460    case RESPONSE_R6:
461        cmdat |= MSC_CMDAT_RESPONSE_R6;
462        break;
463    default:
464        break;
465    }
466
467    /* Set command index */
468    if (request->cmd == MMC_CIM_RESET) {
469        REG_MSC_CMD = MMC_CMD_GO_IDLE_STATE;
470    } else {
471        REG_MSC_CMD = request->cmd;
472    }
473
474        /* Set argument */
475    REG_MSC_ARG = request->arg;
476
477    /* Set block length and nob */
478    if (request->cmd == SD_CMD_APP_SEND_SCR) { /* get SCR from DataFIFO */
479        REG_MSC_BLKLEN = 8;
480        REG_MSC_NOB = 1;
481    } else {
482        REG_MSC_BLKLEN = request->block_len;
483        REG_MSC_NOB = request->nob;
484    }
485
486    /* Set command */
487    REG_MSC_CMDAT = cmdat;
488
489    debug("Send cmd %d cmdat: %x arg: %x resp %d\n", request->cmd,
490          cmdat, request->arg, request->rtype);
491
492        /* Start MMC/SD clock and send command to card */
493    jz_mmc_start_clock();
494
495    /* Wait for command completion */
496    while (timeout-- && !(REG_MSC_STAT & MSC_STAT_END_CMD_RES))
497        ;
498
499    if (timeout == 0)
500        return MMC_ERROR_TIMEOUT;
501
502    REG_MSC_IREG = MSC_IREG_END_CMD_RES; /* clear flag */
503
504    /* Check for status */
505    retval = jz_mmc_check_status(request);
506    if (retval) {
507        return retval;
508    }
509
510    /* Complete command with no response */
511    if (request->rtype == RESPONSE_NONE) {
512        return MMC_NO_ERROR;
513    }
514
515    /* Get response */
516    jz_mmc_get_response(request);
517
518    /* Start data operation */
519    if (events & (MMC_EVENT_RX_DATA_DONE | MMC_EVENT_TX_DATA_DONE)) {
520        if (events & MMC_EVENT_RX_DATA_DONE) {
521            if (request->cmd == SD_CMD_APP_SEND_SCR) {
522                /* SD card returns SCR register as data.
523                   MMC core expect it in the response buffer,
524                   after normal response. */
525                request->buffer = (u8 *)((u32)request->response + 5);
526            }
527            jz_mmc_receive_data(request);
528        }
529
530        if (events & MMC_EVENT_TX_DATA_DONE) {
531            jz_mmc_transmit_data(request);
532        }
533
534        /* Wait for Data Done */
535        while (!(REG_MSC_IREG & MSC_IREG_DATA_TRAN_DONE))
536            ;
537        REG_MSC_IREG = MSC_IREG_DATA_TRAN_DONE; /* clear status */
538    }
539
540    /* Wait for Prog Done event */
541    if (events & MMC_EVENT_PROG_DONE) {
542        while (!(REG_MSC_IREG & MSC_IREG_PRG_DONE))
543            ;
544        REG_MSC_IREG = MSC_IREG_PRG_DONE; /* clear status */
545    }
546
547    /* Command completed */
548
549    return MMC_NO_ERROR; /* return successfully */
550}
551
552int mmc_block_read(u8 *dst, ulong src, ulong len)
553{
554
555    struct mmc_request request;
556    struct mmc_response_r1 r1;
557    int retval;
558
559    if (len == 0) {
560        return 0;
561    }
562    mmc_simple_cmd(&request, MMC_CMD_SEND_STATUS, mmcinfo.rca, RESPONSE_R1);
563    retval = mmc_unpack_r1(&request, &r1, 0);
564    if (retval && (retval != MMC_ERROR_STATE_MISMATCH)) {
565        return retval;
566    }
567
568    mmc_simple_cmd(&request, MMC_CMD_SET_BLOCKLEN, len, RESPONSE_R1);
569    if ((retval = mmc_unpack_r1(&request, &r1, 0))) {
570        return retval;
571    }
572
573    if (sd2_0)
574        src /= len;
575
576    mmc_send_cmd(&request, MMC_CMD_READ_SINGLE_BLOCK, src, 1,len, RESPONSE_R1, dst);
577    if ((retval = mmc_unpack_r1(&request, &r1, 0))) {
578        return retval;
579    }
580    return retval;
581}
582
583int mmc_block_write(ulong dst, uchar *src, int len)
584{
585    return 0;
586}
587
588int xburst_mmc_read(u64 src, uchar *dst, int size)
589{
590    ulong end, part_start, part_end, part_len, aligned_start, aligned_end;
591    ulong mmc_block_size, mmc_block_address;
592
593    if (size == 0) {
594        return 0;
595    }
596
597    if (!mmc_ready) {
598        printf("MMC card is not ready\n");
599        return -1;
600    }
601
602    mmc_block_size = MMC_BLOCK_SIZE;
603    mmc_block_address = ~(mmc_block_size - 1);
604
605    //src -= CFG_MMC_BASE;
606    end = src + size;
607    part_start = ~mmc_block_address & src;
608    part_end = ~mmc_block_address & end;
609    aligned_start = mmc_block_address & src;
610    aligned_end = mmc_block_address & end;
611    /* all block aligned accesses */
612    debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
613    src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
614    if (part_start) {
615        part_len = mmc_block_size - part_start;
616        debug("ps src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
617        src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
618        if ((mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) < 0) {
619            return -1;
620        }
621        memcpy(dst, mmc_buf+part_start, part_len);
622        dst += part_len;
623        src += part_len;
624    }
625    debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
626    src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
627    for (; src < aligned_end; src += mmc_block_size, dst += mmc_block_size) {
628        debug("al src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
629        src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
630
631        if ((mmc_block_read((uchar *)(dst), src, mmc_block_size)) < 0) {
632            return -1;
633        }
634    }
635    debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
636    src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
637
638    if (part_end && src < end) {
639        if ((mmc_block_read(mmc_buf, aligned_end, mmc_block_size)) < 0) {
640            return -1;
641        }
642        memcpy(dst, mmc_buf, part_end);
643    }
644    return 0;
645
646}
647
648int mmc_write(uchar *src, ulong dst, int size)
649{
650    ulong end, part_start, part_end, part_len, aligned_start, aligned_end;
651    ulong mmc_block_size, mmc_block_address;
652
653    if (size == 0) {
654        return 0;
655    }
656
657    if (!mmc_ready) {
658        printf("MMC card is not ready\n");
659        return -1;
660    }
661
662    mmc_block_size = MMC_BLOCK_SIZE;
663    mmc_block_address = ~(mmc_block_size - 1);
664
665    dst -= CFG_MMC_BASE;
666    end = dst + size;
667    part_start = ~mmc_block_address & dst;
668    part_end = ~mmc_block_address & end;
669    aligned_start = mmc_block_address & dst;
670    aligned_end = mmc_block_address & end;
671
672    /* all block aligned accesses */
673    debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
674    src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
675    if (part_start) {
676        part_len = mmc_block_size - part_start;
677        debug("ps src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
678        (ulong)src, dst, end, part_start, part_end, aligned_start, aligned_end);
679        if ((mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) < 0) {
680            return -1;
681        }
682        memcpy(mmc_buf+part_start, src, part_len);
683        if ((mmc_block_write(aligned_start, mmc_buf, mmc_block_size)) < 0) {
684            return -1;
685        }
686        dst += part_len;
687        src += part_len;
688    }
689    debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
690    src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
691    for (; dst < aligned_end; src += mmc_block_size, dst += mmc_block_size) {
692        debug("al src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
693        src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
694        if ((mmc_block_write(dst, (uchar *)src, mmc_block_size)) < 0) {
695            return -1;
696        }
697    }
698    debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
699    src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
700    if (part_end && dst < end) {
701        debug("pe src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
702        src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
703        if ((mmc_block_read(mmc_buf, aligned_end, mmc_block_size)) < 0) {
704            return -1;
705        }
706        memcpy(mmc_buf, src, part_end);
707        if ((mmc_block_write(aligned_end, mmc_buf, mmc_block_size)) < 0) {
708            return -1;
709        }
710    }
711    return 0;
712}
713
714ulong mmc_bread(int dev_num, ulong blknr, ulong blkcnt, ulong *dst)
715{
716    ulong src;
717    int mmc_block_size = MMC_BLOCK_SIZE;
718
719    src = blknr * mmc_block_size ;//+ CFG_MMC_BASE;
720    xburst_mmc_read(src, (uchar *)dst, blkcnt*mmc_block_size);
721    return blkcnt;
722}
723
724int mmc_select_card(void)
725{
726    struct mmc_request request;
727    struct mmc_response_r1 r1;
728    int retval;
729
730    mmc_simple_cmd(&request, MMC_CMD_SELECT_CARD, mmcinfo.rca, RESPONSE_R1B);
731    retval = mmc_unpack_r1(&request, &r1, 0);
732    if (retval) {
733        return retval;
734    }
735
736    if (mmcinfo.sd) {
737        mmc_simple_cmd(&request, MMC_CMD_APP_CMD, mmcinfo.rca, RESPONSE_R1);
738        retval = mmc_unpack_r1(&request,&r1,0);
739        if (retval) {
740            return retval;
741        }
742#if defined(MMC_BUS_WIDTH_1BIT)
743        mmc_simple_cmd(&request, SET_BUS_WIDTH, 1, RESPONSE_R1);
744#else
745        mmc_simple_cmd(&request, SET_BUS_WIDTH, 2, RESPONSE_R1);
746#endif
747                retval = mmc_unpack_r1(&request,&r1,0);
748                if (retval) {
749            return retval;
750        }
751    }
752    return 0;
753}
754
755/*
756 * Configure card
757 */
758static void mmc_configure_card(void)
759{
760    u32 rate;
761
762    /* Get card info */
763    if (sd2_0)
764        mmcinfo.block_num = (mmcinfo.csd.c_size + 1) << 10;
765    else
766        mmcinfo.block_num = (mmcinfo.csd.c_size + 1) * (1 << (mmcinfo.csd.c_size_mult + 2));
767
768    mmcinfo.block_len = 1 << mmcinfo.csd.read_bl_len;
769
770    /* Fix the clock rate */
771    rate = mmc_tran_speed(mmcinfo.csd.tran_speed);
772    if (rate < MMC_CLOCK_SLOW)
773        rate = MMC_CLOCK_SLOW;
774    if ((mmcinfo.sd == 0) && (rate > MMC_CLOCK_FAST))
775        rate = MMC_CLOCK_FAST;
776        if ((mmcinfo.sd) && (rate > SD_CLOCK_FAST))
777        rate = SD_CLOCK_FAST;
778
779    debug("%s: block_len=%d block_num=%d rate=%d\n",
780          __func__, mmcinfo.block_len, mmcinfo.block_num, rate);
781
782    jz_mmc_set_clock(mmcinfo.sd, rate);
783}
784
785/*
786 * State machine routines to initialize card(s)
787 */
788
789/*
790  CIM_SINGLE_CARD_ACQ (frequency at 400 kHz)
791  --- Must enter from GO_IDLE_STATE ---
792  1. SD_SEND_OP_COND (SD Card) [CMD55] + [CMD41]
793  2. SEND_OP_COND (Full Range) [CMD1] {optional}
794  3. SEND_OP_COND (Set Range ) [CMD1]
795     If busy, delay and repeat step 2
796  4. ALL_SEND_CID [CMD2]
797     If timeout, set an error (no cards found)
798  5. SET_RELATIVE_ADDR [CMD3]
799  6. SEND_CSD [CMD9]
800  7. SET_DSR [CMD4] Only call this if (csd.dsr_imp).
801  8. Set clock frequency (check available in csd.tran_speed)
802 */
803
804#define MMC_INIT_DOING 0
805#define MMC_INIT_PASSED 1
806#define MMC_INIT_FAILED 2
807
808static int mmc_init_card_state(struct mmc_request *request)
809{
810    struct mmc_response_r1 r1;
811    struct mmc_response_r3 r3;
812    int retval;
813    int ocr = 0x40300000;
814    int limit_41 = 0;
815
816    switch (request->cmd) {
817    case MMC_CMD_GO_IDLE_STATE: /* No response to parse */
818        if (mmcinfo.sd)
819            mmc_simple_cmd(request, 8, 0x1aa, RESPONSE_R1);
820        else
821            mmc_simple_cmd(request, MMC_CMD_SEND_OP_COND, MMC_OCR_ARG, RESPONSE_R3);
822        break;
823
824    case 8:
825            retval = mmc_unpack_r1(request,&r1,mmcinfo.state);
826        mmc_simple_cmd(request, MMC_CMD_APP_CMD, 0, RESPONSE_R1);
827        break;
828
829        case MMC_CMD_APP_CMD:
830            retval = mmc_unpack_r1(request,&r1,mmcinfo.state);
831        if (retval & (limit_41 < 100)) {
832            debug("%s: unable to MMC_APP_CMD error=%d (%s)\n",
833                  __func__, retval, mmc_result_to_string(retval));
834            limit_41++;
835            mmc_simple_cmd(request, SD_CMD_APP_SEND_OP_COND, ocr, RESPONSE_R3);
836        } else if (limit_41 < 100) {
837            limit_41++;
838            mmc_simple_cmd(request, SD_CMD_APP_SEND_OP_COND, ocr, RESPONSE_R3);
839        } else{
840            /* reset the card to idle*/
841            mmc_simple_cmd(request, MMC_CMD_GO_IDLE_STATE, 0, RESPONSE_NONE);
842            mmcinfo.sd = 0;
843        }
844        break;
845
846        case SD_CMD_APP_SEND_OP_COND:
847                retval = mmc_unpack_r3(request, &r3);
848                if (retval) {
849                  /* Try MMC card */
850                    mmc_simple_cmd(request, SD_CMD_APP_SEND_OP_COND, MMC_OCR_ARG, RESPONSE_R3);
851                    break;
852        }
853
854                debug("%s: read ocr value = 0x%08x\n", __func__, r3.ocr);
855
856        if(!(r3.ocr & MMC_CARD_BUSY || ocr == 0)){
857            udelay(10000);
858            mmc_simple_cmd(request, MMC_CMD_APP_CMD, 0, RESPONSE_R1);
859        }
860        else {
861          /* Set the data bus width to 4 bits */
862                  mmcinfo.sd = 1; /* SD Card ready */
863                  mmcinfo.state = CARD_STATE_READY;
864          mmc_simple_cmd(request, MMC_CMD_ALL_SEND_CID, 0, RESPONSE_R2_CID);
865        }
866        break;
867
868    case MMC_CMD_SEND_OP_COND:
869        retval = mmc_unpack_r3(request, &r3);
870        if (retval) {
871            debug("%s: failed SEND_OP_COND error=%d (%s)\n",
872                  __func__, retval, mmc_result_to_string(retval));
873            return MMC_INIT_FAILED;
874        }
875
876        debug("%s: read ocr value = 0x%08x\n", __func__, r3.ocr);
877        if (!(r3.ocr & MMC_CARD_BUSY)) {
878                    mmc_simple_cmd(request, MMC_CMD_SEND_OP_COND, MMC_OCR_ARG, RESPONSE_R3);
879        } else {
880                mmcinfo.sd = 0; /* MMC Card ready */
881            mmcinfo.state = CARD_STATE_READY;
882            mmc_simple_cmd(request, MMC_CMD_ALL_SEND_CID, 0, RESPONSE_R2_CID);
883        }
884        break;
885
886    case MMC_CMD_ALL_SEND_CID:
887        retval = mmc_unpack_cid( request, &mmcinfo.cid );
888        /*FIXME:ignore CRC error for CMD2/CMD9/CMD10 */
889        if ( retval && (retval != MMC_ERROR_CRC)) {
890            debug("mmc_init_card_state: unable to ALL_SEND_CID error=%d (%s)\n",
891                  retval, mmc_result_to_string(retval));
892            return MMC_INIT_FAILED;
893        }
894        mmcinfo.state = CARD_STATE_IDENT;
895        if(mmcinfo.sd)
896            mmc_simple_cmd(request, MMC_CMD_SET_RELATIVE_ADDR, 0, RESPONSE_R6);
897                else
898            mmc_simple_cmd(request, MMC_CMD_SET_RELATIVE_ADDR, ID_TO_RCA(mmcinfo.id) << 16, RESPONSE_R1);
899        break;
900
901        case MMC_CMD_SET_RELATIVE_ADDR:
902            if (mmcinfo.sd) {
903            retval = mmc_unpack_r6(request, &r1, mmcinfo.state, &mmcinfo.rca);
904            mmcinfo.rca = mmcinfo.rca << 16;
905            debug("%s: Get RCA from SD: 0x%04x Status: %x\n",
906                  __func__, mmcinfo.rca, r1.status);
907                } else {
908            retval = mmc_unpack_r1(request,&r1,mmcinfo.state);
909            mmcinfo.rca = ID_TO_RCA(mmcinfo.id) << 16;
910            }
911        if (retval) {
912            debug("%s: unable to SET_RELATIVE_ADDR error=%d (%s)\n",
913                  __func__, retval, mmc_result_to_string(retval));
914            return MMC_INIT_FAILED;
915        }
916
917        mmcinfo.state = CARD_STATE_STBY;
918                mmc_simple_cmd(request, MMC_CMD_SEND_CSD, mmcinfo.rca, RESPONSE_R2_CSD);
919
920        break;
921
922    case MMC_CMD_SEND_CSD:
923        retval = mmc_unpack_csd(request, &mmcinfo.csd);
924            struct mmc_csd *csd = (struct mmc_csd *)retval;
925            memcpy(&mmc_csd, csd, sizeof(csd));
926            mmc_ready = 1;
927
928            printf("MMC card is ready\n");
929            /* FIXME add verbose printout for csd */
930
931        /*FIXME:ignore CRC error for CMD2/CMD9/CMD10 */
932            if (retval && (retval != MMC_ERROR_CRC)) {
933            debug("%s: unable to SEND_CSD error=%d (%s)\n",
934                  __func__, retval, mmc_result_to_string(retval));
935            return MMC_INIT_FAILED;
936        }
937        if (mmcinfo.csd.dsr_imp) {
938            debug("%s: driver doesn't support setting DSR\n", __func__);
939        }
940        mmc_configure_card();
941        return MMC_INIT_PASSED;
942
943    default:
944        debug("%s: error! Illegal last cmd %d\n", __func__, request->cmd);
945        return MMC_INIT_FAILED;
946    }
947
948    return MMC_INIT_DOING;
949}
950
951int mmc_init_card(void)
952{
953    struct mmc_request request;
954    int retval;
955
956    mmc_simple_cmd(&request, MMC_CIM_RESET, 0, RESPONSE_NONE); /* reset card */
957    mmc_simple_cmd(&request, MMC_CMD_GO_IDLE_STATE, 0, RESPONSE_NONE);
958    mmcinfo.sd = 1; /* assuming a SD card */
959
960    while ((retval = mmc_init_card_state(&request)) == MMC_INIT_DOING)
961        ;
962
963    if (retval == MMC_INIT_PASSED)
964        return MMC_NO_ERROR;
965    else
966        return MMC_NO_RESPONSE;
967}
968
969int mmc_legacy_init(int verbose)
970{
971    if (!__msc_card_detected())
972        return 1;
973
974    /* Step-1: init GPIO */
975    __gpio_as_msc();
976    __msc_init_io();
977
978    /* Step-2: turn on power of card */
979#if !defined(CONFIG_SAKC)
980    __msc_enable_power();
981#endif
982
983    /* Step-3: Reset MSC Controller. */
984    __msc_reset();
985
986    /* Step-3: mask all IRQs. */
987    MMC_IRQ_MASK();
988
989    /* Step-4: stop MMC/SD clock */
990    jz_mmc_stop_clock();
991    mmc_init_card();
992    mmc_select_card();
993
994    mmc_dev.block_read = mmc_bread;
995    fat_register_device(&mmc_dev,1); /* partitions start counting with 1 */
996
997    return 0;
998}
999
1000int mmc_ident(block_dev_desc_t *dev)
1001{
1002    return 0;
1003}
1004
1005int mmc2info(ulong addr)
1006{
1007    /* FIXME hard codes to 32 MB device */
1008    if (addr >= CFG_MMC_BASE && addr < CFG_MMC_BASE + 0x02000000) {
1009        return 1;
1010    }
1011    return 0;;
1012}
1013/*
1014 * Debugging functions
1015 */
1016
1017static char * mmc_result_strings[] = {
1018    "NO_RESPONSE",
1019    "NO_ERROR",
1020    "ERROR_OUT_OF_RANGE",
1021    "ERROR_ADDRESS",
1022    "ERROR_BLOCK_LEN",
1023    "ERROR_ERASE_SEQ",
1024    "ERROR_ERASE_PARAM",
1025    "ERROR_WP_VIOLATION",
1026    "ERROR_CARD_IS_LOCKED",
1027    "ERROR_LOCK_UNLOCK_FAILED",
1028    "ERROR_COM_CRC",
1029    "ERROR_ILLEGAL_COMMAND",
1030    "ERROR_CARD_ECC_FAILED",
1031    "ERROR_CC",
1032    "ERROR_GENERAL",
1033    "ERROR_UNDERRUN",
1034    "ERROR_OVERRUN",
1035    "ERROR_CID_CSD_OVERWRITE",
1036    "ERROR_STATE_MISMATCH",
1037    "ERROR_HEADER_MISMATCH",
1038    "ERROR_TIMEOUT",
1039    "ERROR_CRC",
1040    "ERROR_DRIVER_FAILURE",
1041};
1042
1043char * mmc_result_to_string(int i)
1044{
1045    return mmc_result_strings[i+1];
1046}
1047
1048static char * card_state_strings[] = {
1049    "empty",
1050    "idle",
1051    "ready",
1052    "ident",
1053    "stby",
1054    "tran",
1055    "data",
1056    "rcv",
1057    "prg",
1058    "dis",
1059};
1060
1061static inline char * card_state_to_string(int i)
1062{
1063    return card_state_strings[i+1];
1064}
1065
1066/*
1067 * Utility functions
1068 */
1069
1070#define PARSE_U32(_buf,_index) \
1071    (((u32)_buf[_index]) << 24) | (((u32)_buf[_index+1]) << 16) | \
1072        (((u32)_buf[_index+2]) << 8) | ((u32)_buf[_index+3]);
1073
1074#define PARSE_U16(_buf,_index) \
1075    (((u16)_buf[_index]) << 8) | ((u16)_buf[_index+1]);
1076
1077int mmc_unpack_csd(struct mmc_request *request, struct mmc_csd *csd)
1078{
1079    u8 *buf = request->response;
1080    int num = 0;
1081
1082    if (request->result)
1083        return request->result;
1084
1085    csd->csd_structure = (buf[1] & 0xc0) >> 6;
1086    if (csd->csd_structure)
1087        sd2_0 = 1;
1088    else
1089        sd2_0 = 0;
1090
1091    switch (csd->csd_structure) {
1092    case 0 :
1093        csd->taac = buf[2];
1094        csd->nsac = buf[3];
1095        csd->tran_speed = buf[4];
1096        csd->ccc = (((u16)buf[5]) << 4) | ((buf[6] & 0xf0) >> 4);
1097        csd->read_bl_len = buf[6] & 0x0f;
1098        /* for support 2GB card*/
1099        if (csd->read_bl_len >= 10)
1100        {
1101            num = csd->read_bl_len - 9;
1102            csd->read_bl_len = 9;
1103        }
1104
1105        csd->read_bl_partial = (buf[7] & 0x80) ? 1 : 0;
1106        csd->write_blk_misalign = (buf[7] & 0x40) ? 1 : 0;
1107        csd->read_blk_misalign = (buf[7] & 0x20) ? 1 : 0;
1108        csd->dsr_imp = (buf[7] & 0x10) ? 1 : 0;
1109        csd->c_size = ((((u16)buf[7]) & 0x03) << 10) | (((u16)buf[8]) << 2) | (((u16)buf[9]) & 0xc0) >> 6;
1110
1111        if (num)
1112            csd->c_size = csd->c_size << num;
1113
1114
1115        csd->vdd_r_curr_min = (buf[9] & 0x38) >> 3;
1116        csd->vdd_r_curr_max = buf[9] & 0x07;
1117        csd->vdd_w_curr_min = (buf[10] & 0xe0) >> 5;
1118        csd->vdd_w_curr_max = (buf[10] & 0x1c) >> 2;
1119        csd->c_size_mult = ((buf[10] & 0x03) << 1) | ((buf[11] & 0x80) >> 7);
1120        csd->sector_size = (buf[11] & 0x7c) >> 2;
1121        csd->erase_grp_size = ((buf[11] & 0x03) << 3) | ((buf[12] & 0xe0) >> 5);
1122        csd->wp_grp_size = buf[12] & 0x1f;
1123        csd->wp_grp_enable = (buf[13] & 0x80) ? 1 : 0;
1124        csd->default_ecc = (buf[13] & 0x60) >> 5;
1125        csd->r2w_factor = (buf[13] & 0x1c) >> 2;
1126        csd->write_bl_len = ((buf[13] & 0x03) << 2) | ((buf[14] & 0xc0) >> 6);
1127        if (csd->write_bl_len >= 10)
1128            csd->write_bl_len = 9;
1129
1130        csd->write_bl_partial = (buf[14] & 0x20) ? 1 : 0;
1131        csd->file_format_grp = (buf[15] & 0x80) ? 1 : 0;
1132        csd->copy = (buf[15] & 0x40) ? 1 : 0;
1133        csd->perm_write_protect = (buf[15] & 0x20) ? 1 : 0;
1134        csd->tmp_write_protect = (buf[15] & 0x10) ? 1 : 0;
1135        csd->file_format = (buf[15] & 0x0c) >> 2;
1136        csd->ecc = buf[15] & 0x03;
1137        break;
1138    case 1 :
1139        csd->taac = 0;
1140        csd->nsac = 0;
1141        csd->tran_speed = buf[4];
1142        csd->ccc = (((u16)buf[5]) << 4) | ((buf[6] & 0xf0) >> 4);
1143
1144        csd->read_bl_len = 9;
1145        csd->read_bl_partial = 0;
1146        csd->write_blk_misalign = 0;
1147        csd->read_blk_misalign = 0;
1148        csd->dsr_imp = (buf[7] & 0x10) ? 1 : 0;
1149        csd->c_size = ((((u16)buf[8]) & 0x3f) << 16) | (((u16)buf[9]) << 8) | ((u16)buf[10]) ;
1150        csd->sector_size = 0x7f;
1151        csd->erase_grp_size = 0;
1152        csd->wp_grp_size = 0;
1153        csd->wp_grp_enable = 0;
1154        csd->default_ecc = (buf[13] & 0x60) >> 5;
1155        csd->r2w_factor = 4;/* Unused */
1156        csd->write_bl_len = 9;
1157
1158        csd->write_bl_partial = 0;
1159        csd->file_format_grp = 0;
1160        csd->copy = (buf[15] & 0x40) ? 1 : 0;
1161        csd->perm_write_protect = (buf[15] & 0x20) ? 1 : 0;
1162        csd->tmp_write_protect = (buf[15] & 0x10) ? 1 : 0;
1163        csd->file_format = 0;
1164        csd->ecc = buf[15] & 0x03;
1165    }
1166
1167    mmc_dev.if_type = IF_TYPE_SD;
1168    mmc_dev.part_type = PART_TYPE_DOS;
1169    mmc_dev.dev = 0;
1170    mmc_dev.lun = 0;
1171    mmc_dev.type = 0;
1172    mmc_dev.blksz = 512;
1173    mmc_dev.lba = (1 + csd->c_size) << 10;
1174    mmc_dev.removable = 0;
1175
1176    printf("SD%s Detected: %lu blocks of %lu bytes (%luMB)\n",
1177           sd2_0 == 1 ? "HC" : " ",
1178           mmc_dev.lba,
1179           mmc_dev.blksz,
1180           mmc_dev.lba * mmc_dev.blksz / (1024 * 1024));
1181
1182    if (buf[0] != 0x3f) return MMC_ERROR_HEADER_MISMATCH;
1183
1184    return 0;
1185}
1186
1187int mmc_unpack_r1(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state)
1188{
1189    u8 *buf = request->response;
1190
1191    if (request->result)
1192        return request->result;
1193
1194    r1->cmd = buf[0];
1195    r1->status = PARSE_U32(buf,1);
1196
1197    debug("mmc_unpack_r1: cmd=%d status=%08x\n", r1->cmd, r1->status);
1198
1199    if (R1_STATUS(r1->status)) {
1200        if (r1->status & R1_OUT_OF_RANGE) return MMC_ERROR_OUT_OF_RANGE;
1201        if (r1->status & R1_ADDRESS_ERROR) return MMC_ERROR_ADDRESS;
1202        if (r1->status & R1_BLOCK_LEN_ERROR) return MMC_ERROR_BLOCK_LEN;
1203        if (r1->status & R1_ERASE_SEQ_ERROR) return MMC_ERROR_ERASE_SEQ;
1204        if (r1->status & R1_ERASE_PARAM) return MMC_ERROR_ERASE_PARAM;
1205        if (r1->status & R1_WP_VIOLATION) return MMC_ERROR_WP_VIOLATION;
1206        /*if (r1->status & R1_CARD_IS_LOCKED) return MMC_ERROR_CARD_IS_LOCKED; */
1207        if (r1->status & R1_LOCK_UNLOCK_FAILED) return MMC_ERROR_LOCK_UNLOCK_FAILED;
1208        if (r1->status & R1_COM_CRC_ERROR) return MMC_ERROR_COM_CRC;
1209        if (r1->status & R1_ILLEGAL_COMMAND) return MMC_ERROR_ILLEGAL_COMMAND;
1210        if (r1->status & R1_CARD_ECC_FAILED) return MMC_ERROR_CARD_ECC_FAILED;
1211        if (r1->status & R1_CC_ERROR) return MMC_ERROR_CC;
1212        if (r1->status & R1_ERROR) return MMC_ERROR_GENERAL;
1213        if (r1->status & R1_UNDERRUN) return MMC_ERROR_UNDERRUN;
1214        if (r1->status & R1_OVERRUN) return MMC_ERROR_OVERRUN;
1215        if (r1->status & R1_CID_CSD_OVERWRITE) return MMC_ERROR_CID_CSD_OVERWRITE;
1216    }
1217
1218    if (buf[0] != request->cmd)
1219        return MMC_ERROR_HEADER_MISMATCH;
1220
1221    /* This should be last - it's the least dangerous error */
1222
1223    return 0;
1224}
1225
1226int mmc_unpack_scr(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state, u32 *scr)
1227{
1228        u8 *buf = request->response;
1229    if (request->result)
1230        return request->result;
1231
1232        *scr = PARSE_U32(buf, 5); /* Save SCR returned by the SD Card */
1233        return mmc_unpack_r1(request, r1, state);
1234
1235}
1236
1237int mmc_unpack_r6(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state, int *rca)
1238{
1239    u8 *buf = request->response;
1240
1241    if (request->result)
1242        return request->result;
1243
1244        *rca = PARSE_U16(buf,1); /* Save RCA returned by the SD Card */
1245
1246        *(buf+1) = 0;
1247        *(buf+2) = 0;
1248
1249        return mmc_unpack_r1(request, r1, state);
1250}
1251
1252int mmc_unpack_cid(struct mmc_request *request, struct mmc_cid *cid)
1253{
1254    int i;
1255    u8 *buf = request->response;
1256
1257    if (request->result)
1258        return request->result;
1259
1260    cid->mid = buf[1];
1261    cid->oid = PARSE_U16(buf,2);
1262    for (i = 0 ; i < 6 ; i++)
1263        cid->pnm[i] = buf[4+i];
1264    cid->pnm[6] = 0;
1265    cid->prv = buf[10];
1266    cid->psn = PARSE_U32(buf,11);
1267    cid->mdt = buf[15];
1268
1269    printf("CID info:\n"
1270           " mid=%d\n"
1271           " oid=%d\n"
1272           " pnm=%s\n"
1273           " prv=%d.%d\n"
1274           " psn=%08x\n"
1275           " mdt=%d/%d\n",
1276           cid->mid,
1277           cid->oid,
1278           cid->pnm,
1279           cid->prv >> 4,
1280           cid->prv & 0xf,
1281           cid->psn,
1282           cid->mdt >> 4,
1283           (cid->mdt & 0xf) + 1997);
1284
1285    if (buf[0] != 0x3f) return MMC_ERROR_HEADER_MISMATCH;
1286          return 0;
1287}
1288
1289int mmc_unpack_r3(struct mmc_request *request, struct mmc_response_r3 *r3)
1290{
1291    u8 *buf = request->response;
1292
1293    if (request->result)
1294        return request->result;
1295
1296    r3->ocr = PARSE_U32(buf,1);
1297    debug("mmc_unpack_r3: ocr=%08x\n", r3->ocr);
1298
1299    if (buf[0] != 0x3f) return MMC_ERROR_HEADER_MISMATCH;
1300    return 0;
1301}
1302
1303#define KBPS 1
1304#define MBPS 1000
1305
1306static u32 ts_exp[] = { 100*KBPS, 1*MBPS, 10*MBPS, 100*MBPS, 0, 0, 0, 0 };
1307static u32 ts_mul[] = { 0, 1000, 1200, 1300, 1500, 2000, 2500, 3000,
1308            3500, 4000, 4500, 5000, 5500, 6000, 7000, 8000 };
1309
1310u32 mmc_tran_speed(u8 ts)
1311{
1312    u32 rate = ts_exp[(ts & 0x7)] * ts_mul[(ts & 0x78) >> 3];
1313
1314    if (rate <= 0) {
1315        debug("%s: error - unrecognized speed 0x%02x\n", __func__, ts);
1316        return 1;
1317    }
1318
1319    return rate;
1320}
1321
1322void mmc_send_cmd(struct mmc_request *request, int cmd, u32 arg,
1323           u16 nob, u16 block_len, enum mmc_rsp_t rtype, u8 *buffer)
1324{
1325    request->cmd = cmd;
1326    request->arg = arg;
1327    request->rtype = rtype;
1328    request->nob = nob;
1329    request->block_len = block_len;
1330    request->buffer = buffer;
1331    request->cnt = nob * block_len;
1332
1333    jz_mmc_exec_cmd(request);
1334}
1335
1336#endif /* CONFIG_MMC */
package/uboot-xburst/files/arch/mips/cpu/xburst/jz_mmc.h
1/*
2 * linux/drivers/mmc/jz_mmc.h
3 *
4 * Author: Vladimir Shebordaev, Igor Oblakov
5 * Copyright: MontaVista Software Inc.
6 *
7 * $Id: jz_mmc.h,v 1.3 2007-06-15 08:04:20 jlwei Exp $
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13#ifndef __MMC_JZMMC_H__
14#define __MMC_JZMMC_H__
15
16#define MMC_DEBUG_LEVEL 0 /* Enable Debug: 0 - no debug */
17#define MMC_BLOCK_SIZE 512 /* MMC/SD Block Size */
18#define ID_TO_RCA(x) ((x)+1)
19#define MMC_OCR_ARG 0x00ff8000 /* Argument of OCR */
20
21/* Standard MMC/SD clock speeds */
22#define MMC_CLOCK_SLOW 400000 /* 400 kHz for initial setup */
23#define MMC_CLOCK_FAST 20000000 /* 20 MHz for maximum for normal operation */
24#define SD_CLOCK_FAST 24000000 /* 24 MHz for SD Cards */
25
26/* Use negative numbers to disambiguate */
27#define MMC_CIM_RESET -1
28#define SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */
29
30#define R1_OUT_OF_RANGE (1 << 31) /* er, c */
31#define R1_ADDRESS_ERROR (1 << 30) /* erx, c */
32#define R1_BLOCK_LEN_ERROR (1 << 29) /* er, c */
33#define R1_ERASE_SEQ_ERROR (1 << 28) /* er, c */
34#define R1_ERASE_PARAM (1 << 27) /* ex, c */
35#define R1_WP_VIOLATION (1 << 26) /* erx, c */
36#define R1_CARD_IS_LOCKED (1 << 25) /* sx, a */
37#define R1_LOCK_UNLOCK_FAILED (1 << 24) /* erx, c */
38#define R1_COM_CRC_ERROR (1 << 23) /* er, b */
39#define R1_ILLEGAL_COMMAND (1 << 22) /* er, b */
40#define R1_CARD_ECC_FAILED (1 << 21) /* ex, c */
41#define R1_CC_ERROR (1 << 20) /* erx, c */
42#define R1_ERROR (1 << 19) /* erx, c */
43#define R1_UNDERRUN (1 << 18) /* ex, c */
44#define R1_OVERRUN (1 << 17) /* ex, c */
45#define R1_CID_CSD_OVERWRITE (1 << 16) /* erx, c, CID/CSD overwrite */
46#define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */
47#define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */
48#define R1_ERASE_RESET (1 << 13) /* sr, c */
49#define R1_STATUS(x) (x & 0xFFFFE000)
50
51#define MMC_CARD_BUSY 0x80000000 /* Card Power up status bit */
52
53#define MMC_PROGRAM_CID 26 /* adtc R1 */
54#define MMC_PROGRAM_CSD 27 /* adtc R1 */
55
56#define MMC_GO_IRQ_STATE 40 /* bcr R5 */
57#define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1b */
58#define MMC_LOCK_UNLOCK 42 /* adtc R1b */
59#define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */
60#define MMC_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */
61#define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */
62
63
64enum mmc_result_t {
65    MMC_NO_RESPONSE = -1,
66    MMC_NO_ERROR = 0,
67    MMC_ERROR_OUT_OF_RANGE,
68    MMC_ERROR_ADDRESS,
69    MMC_ERROR_BLOCK_LEN,
70    MMC_ERROR_ERASE_SEQ,
71    MMC_ERROR_ERASE_PARAM,
72    MMC_ERROR_WP_VIOLATION,
73    MMC_ERROR_CARD_IS_LOCKED,
74    MMC_ERROR_LOCK_UNLOCK_FAILED,
75    MMC_ERROR_COM_CRC,
76    MMC_ERROR_ILLEGAL_COMMAND,
77    MMC_ERROR_CARD_ECC_FAILED,
78    MMC_ERROR_CC,
79    MMC_ERROR_GENERAL,
80    MMC_ERROR_UNDERRUN,
81    MMC_ERROR_OVERRUN,
82    MMC_ERROR_CID_CSD_OVERWRITE,
83    MMC_ERROR_STATE_MISMATCH,
84    MMC_ERROR_HEADER_MISMATCH,
85    MMC_ERROR_TIMEOUT,
86    MMC_ERROR_CRC,
87    MMC_ERROR_DRIVER_FAILURE,
88};
89
90enum card_state {
91    CARD_STATE_EMPTY = -1,
92    CARD_STATE_IDLE = 0,
93    CARD_STATE_READY = 1,
94    CARD_STATE_IDENT = 2,
95    CARD_STATE_STBY = 3,
96    CARD_STATE_TRAN = 4,
97    CARD_STATE_DATA = 5,
98    CARD_STATE_RCV = 6,
99    CARD_STATE_PRG = 7,
100    CARD_STATE_DIS = 8,
101};
102
103enum mmc_rsp_t {
104    RESPONSE_NONE = 0,
105    RESPONSE_R1 = 1,
106    RESPONSE_R1B = 2,
107    RESPONSE_R2_CID = 3,
108    RESPONSE_R2_CSD = 4,
109    RESPONSE_R3 = 5,
110    RESPONSE_R4 = 6,
111    RESPONSE_R5 = 7,
112        RESPONSE_R6 = 8,
113};
114
115struct mmc_response_r1 {
116    u8 cmd;
117    u32 status;
118};
119
120struct mmc_response_r3 {
121    u32 ocr;
122};
123
124/* the information structure of MMC/SD Card */
125struct mmc_info {
126    int id; /* Card index */
127        int sd; /* MMC or SD card */
128        int rca; /* RCA */
129        u32 scr; /* SCR 63:32*/
130    int flags; /* Ejected, inserted */
131    enum card_state state; /* empty, ident, ready, whatever */
132
133    /* Card specific information */
134    struct mmc_cid cid;
135    struct mmc_csd csd;
136    u32 block_num;
137    u32 block_len;
138    u32 erase_unit;
139};
140
141struct mmc_info mmcinfo;
142
143struct mmc_request {
144    int index; /* Slot index - used for CS lines */
145    int cmd; /* Command to send */
146    u32 arg; /* Argument to send */
147    enum mmc_rsp_t rtype; /* Response type expected */
148
149    /* Data transfer (these may be modified at the low level) */
150    u16 nob; /* Number of blocks to transfer*/
151    u16 block_len; /* Block length */
152    u8 *buffer; /* Data buffer */
153    u32 cnt; /* Data length, for PIO */
154
155    /* Results */
156    u8 response[18]; /* Buffer to store response - CRC is optional */
157    enum mmc_result_t result;
158};
159
160char * mmc_result_to_string(int);
161int mmc_unpack_csd(struct mmc_request *request, struct mmc_csd *csd);
162int mmc_unpack_r1(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state);
163int mmc_unpack_r6(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state, int *rca);
164int mmc_unpack_scr(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state, u32 *scr);
165int mmc_unpack_cid(struct mmc_request *request, struct mmc_cid *cid);
166int mmc_unpack_r3(struct mmc_request *request, struct mmc_response_r3 *r3);
167
168void mmc_send_cmd(struct mmc_request *request, int cmd, u32 arg,
169             u16 nob, u16 block_len, enum mmc_rsp_t rtype, u8 *buffer);
170u32 mmc_tran_speed(u8 ts);
171void jz_mmc_set_clock(int sd, u32 rate);
172
173static inline void mmc_simple_cmd(struct mmc_request *request, int cmd, u32 arg, enum mmc_rsp_t rtype)
174{
175    mmc_send_cmd( request, cmd, arg, 0, 0, rtype, 0);
176}
177
178int mmc2info(ulong addr);
179
180#endif /* __MMC_JZMMC_H__ */
package/uboot-xburst/files/arch/mips/cpu/xburst/nanonote_gpm940b0.c
1/*
2 * JzRISC lcd controller
3 *
4 * xiangfu liu <xiangfu.z@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19 * MA 02111-1307 USA
20 */
21
22#include <config.h>
23#include <common.h>
24#include <lcd.h>
25
26#include <asm/io.h> /* virt_to_phys() */
27
28#include <asm/jz4740.h>
29#include "nanonote_gpm940b0.h"
30
31#define align2(n) (n)=((((n)+1)>>1)<<1)
32#define align4(n) (n)=((((n)+3)>>2)<<2)
33#define align8(n) (n)=((((n)+7)>>3)<<3)
34
35struct jzfb_info {
36    unsigned int cfg; /* panel mode and pin usage etc. */
37    unsigned int w;
38    unsigned int h;
39    unsigned int bpp; /* bit per pixel */
40    unsigned int fclk; /* frame clk */
41    unsigned int hsw; /* hsync width, in pclk */
42    unsigned int vsw; /* vsync width, in line count */
43    unsigned int elw; /* end of line, in pclk */
44    unsigned int blw; /* begin of line, in pclk */
45    unsigned int efw; /* end of frame, in line count */
46    unsigned int bfw; /* begin of frame, in line count */
47};
48
49static struct jzfb_info jzfb = {
50    MODE_8BIT_SERIAL_TFT | PCLK_N | HSYNC_N | VSYNC_N,
51    320, 240, 32, 70, 1, 1, 273, 140, 1, 20
52};
53
54vidinfo_t panel_info = {
55    320, 240, LCD_BPP,
56};
57
58int lcd_line_length;
59
60int lcd_color_fg;
61int lcd_color_bg;
62/*
63 * Frame buffer memory information
64 */
65void *lcd_base; /* Start of framebuffer memory */
66void *lcd_console_address; /* Start of console buffer */
67
68short console_col;
69short console_row;
70
71void lcd_ctrl_init (void *lcdbase);
72void lcd_enable (void);
73void lcd_disable (void);
74
75static int jz_lcd_init_mem(void *lcdbase, vidinfo_t *vid);
76static void jz_lcd_desc_init(vidinfo_t *vid);
77static int jz_lcd_hw_init( vidinfo_t *vid );
78extern int flush_cache_all(void);
79
80void lcd_ctrl_init (void *lcdbase)
81{
82    __lcd_display_pin_init();
83
84    jz_lcd_init_mem(lcdbase, &panel_info);
85    jz_lcd_desc_init(&panel_info);
86    jz_lcd_hw_init(&panel_info);
87
88    __lcd_display_on() ;
89}
90
91/*
92 * Before enabled lcd controller, lcd registers should be configured correctly.
93 */
94
95void lcd_enable (void)
96{
97    REG_LCD_CTRL &= ~(1<<4); /* LCDCTRL.DIS */
98    REG_LCD_CTRL |= 1<<3; /* LCDCTRL.ENA*/
99}
100
101void lcd_disable (void)
102{
103    REG_LCD_CTRL |= (1<<4); /* LCDCTRL.DIS, regular disable */
104    /* REG_LCD_CTRL |= (1<<3); */ /* LCDCTRL.DIS, quikly disable */
105}
106
107static int jz_lcd_init_mem(void *lcdbase, vidinfo_t *vid)
108{
109    u_long palette_mem_size;
110    struct jz_fb_info *fbi = &vid->jz_fb;
111    int fb_size = vid->vl_row * (vid->vl_col * NBITS (vid->vl_bpix)) / 8;
112
113    fbi->screen = (u_long)lcdbase;
114    fbi->palette_size = 256;
115    palette_mem_size = fbi->palette_size * sizeof(u16);
116
117    debug("jz_lcd.c palette_mem_size = 0x%08lx\n", (u_long) palette_mem_size);
118    /* locate palette and descs at end of page following fb */
119    fbi->palette = (u_long)lcdbase + fb_size + PAGE_SIZE - palette_mem_size;
120
121    return 0;
122}
123
124static void jz_lcd_desc_init(vidinfo_t *vid)
125{
126    struct jz_fb_info * fbi;
127    fbi = &vid->jz_fb;
128    fbi->dmadesc_fblow = (struct jz_fb_dma_descriptor *)((unsigned int)fbi->palette - 3*16);
129    fbi->dmadesc_fbhigh = (struct jz_fb_dma_descriptor *)((unsigned int)fbi->palette - 2*16);
130    fbi->dmadesc_palette = (struct jz_fb_dma_descriptor *)((unsigned int)fbi->palette - 1*16);
131
132    #define BYTES_PER_PANEL (vid->vl_col * vid->vl_row * NBITS(vid->vl_bpix) / 8)
133
134    /* populate descriptors */
135    fbi->dmadesc_fblow->fdadr = virt_to_phys(fbi->dmadesc_fblow);
136    fbi->dmadesc_fblow->fsadr = virt_to_phys((void *)(fbi->screen + BYTES_PER_PANEL));
137    fbi->dmadesc_fblow->fidr = 0;
138    fbi->dmadesc_fblow->ldcmd = BYTES_PER_PANEL / 4 ;
139
140    fbi->fdadr1 = virt_to_phys(fbi->dmadesc_fblow); /* only used in dual-panel mode */
141
142    fbi->dmadesc_fbhigh->fsadr = virt_to_phys((void *)fbi->screen);
143    fbi->dmadesc_fbhigh->fidr = 0;
144    fbi->dmadesc_fbhigh->ldcmd = BYTES_PER_PANEL / 4; /* length in word */
145
146    fbi->dmadesc_palette->fsadr = virt_to_phys((void *)fbi->palette);
147    fbi->dmadesc_palette->fidr = 0;
148    fbi->dmadesc_palette->ldcmd = (fbi->palette_size * 2)/4 | (1<<28);
149
150    if(NBITS(vid->vl_bpix) < 12)
151    {
152        /* assume any mode with <12 bpp is palette driven */
153        fbi->dmadesc_palette->fdadr = virt_to_phys(fbi->dmadesc_fbhigh);
154        fbi->dmadesc_fbhigh->fdadr = virt_to_phys(fbi->dmadesc_palette);
155        /* flips back and forth between pal and fbhigh */
156        fbi->fdadr0 = virt_to_phys(fbi->dmadesc_palette);
157    } else {
158        /* palette shouldn't be loaded in true-color mode */
159        fbi->dmadesc_fbhigh->fdadr = virt_to_phys((void *)fbi->dmadesc_fbhigh);
160        fbi->fdadr0 = virt_to_phys(fbi->dmadesc_fbhigh); /* no pal just fbhigh */
161    }
162
163    flush_cache_all();
164}
165
166static int jz_lcd_hw_init(vidinfo_t *vid)
167{
168    struct jz_fb_info *fbi = &vid->jz_fb;
169    unsigned int val = 0;
170    unsigned int pclk;
171    unsigned int stnH;
172    int pll_div;
173
174    /* Setting Control register */
175    switch (jzfb.bpp) {
176    case 1:
177        val |= LCD_CTRL_BPP_1;
178        break;
179    case 2:
180        val |= LCD_CTRL_BPP_2;
181        break;
182    case 4:
183        val |= LCD_CTRL_BPP_4;
184        break;
185    case 8:
186        val |= LCD_CTRL_BPP_8;
187        break;
188    case 15:
189        val |= LCD_CTRL_RGB555;
190    case 16:
191        val |= LCD_CTRL_BPP_16;
192        break;
193    case 17 ... 32:
194        val |= LCD_CTRL_BPP_18_24; /* target is 4bytes/pixel */
195        break;
196
197    default:
198        printf("jz_lcd.c The BPP %d is not supported\n", jzfb.bpp);
199        val |= LCD_CTRL_BPP_16;
200        break;
201    }
202
203    switch (jzfb.cfg & MODE_MASK) {
204    case MODE_STN_MONO_DUAL:
205    case MODE_STN_COLOR_DUAL:
206    case MODE_STN_MONO_SINGLE:
207    case MODE_STN_COLOR_SINGLE:
208        switch (jzfb.bpp) {
209        case 1:
210            /* val |= LCD_CTRL_PEDN; */
211        case 2:
212            val |= LCD_CTRL_FRC_2;
213            break;
214        case 4:
215            val |= LCD_CTRL_FRC_4;
216            break;
217        case 8:
218        default:
219            val |= LCD_CTRL_FRC_16;
220            break;
221        }
222        break;
223    }
224
225    val |= LCD_CTRL_BST_16; /* Burst Length is 16WORD=64Byte */
226    val |= LCD_CTRL_OFUP; /* OutFIFO underrun protect */
227
228    switch (jzfb.cfg & MODE_MASK) {
229    case MODE_STN_MONO_DUAL:
230    case MODE_STN_COLOR_DUAL:
231    case MODE_STN_MONO_SINGLE:
232    case MODE_STN_COLOR_SINGLE:
233        switch (jzfb.cfg & STN_DAT_PINMASK) {
234        case STN_DAT_PIN1:
235            /* Do not adjust the hori-param value. */
236            break;
237        case STN_DAT_PIN2:
238            align2(jzfb.hsw);
239            align2(jzfb.elw);
240            align2(jzfb.blw);
241            break;
242        case STN_DAT_PIN4:
243            align4(jzfb.hsw);
244            align4(jzfb.elw);
245            align4(jzfb.blw);
246            break;
247        case STN_DAT_PIN8:
248            align8(jzfb.hsw);
249            align8(jzfb.elw);
250            align8(jzfb.blw);
251            break;
252        }
253        break;
254    }
255
256    REG_LCD_CTRL = val;
257
258    switch (jzfb.cfg & MODE_MASK) {
259    case MODE_STN_MONO_DUAL:
260    case MODE_STN_COLOR_DUAL:
261    case MODE_STN_MONO_SINGLE:
262    case MODE_STN_COLOR_SINGLE:
263        if (((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL) ||
264            ((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL))
265            stnH = jzfb.h >> 1;
266        else
267            stnH = jzfb.h;
268
269        REG_LCD_VSYNC = (0 << 16) | jzfb.vsw;
270        REG_LCD_HSYNC = ((jzfb.blw+jzfb.w) << 16) | (jzfb.blw+jzfb.w+jzfb.hsw);
271
272        /* Screen setting */
273        REG_LCD_VAT = ((jzfb.blw + jzfb.w + jzfb.hsw + jzfb.elw) << 16) | (stnH + jzfb.vsw + jzfb.bfw + jzfb.efw);
274        REG_LCD_DAH = (jzfb.blw << 16) | (jzfb.blw + jzfb.w);
275        REG_LCD_DAV = (0 << 16) | (stnH);
276
277        /* AC BIAs signal */
278        REG_LCD_PS = (0 << 16) | (stnH+jzfb.vsw+jzfb.efw+jzfb.bfw);
279
280        break;
281
282    case MODE_TFT_GEN:
283    case MODE_TFT_SHARP:
284    case MODE_TFT_CASIO:
285    case MODE_TFT_SAMSUNG:
286    case MODE_8BIT_SERIAL_TFT:
287    case MODE_TFT_18BIT:
288        REG_LCD_VSYNC = (0 << 16) | jzfb.vsw;
289        REG_LCD_HSYNC = (0 << 16) | jzfb.hsw;
290        REG_LCD_DAV =((jzfb.vsw+jzfb.bfw) << 16) | (jzfb.vsw +jzfb.bfw+jzfb.h);
291        REG_LCD_DAH = ((jzfb.hsw + jzfb.blw) << 16) | (jzfb.hsw + jzfb.blw + jzfb.w );
292        REG_LCD_VAT = (((jzfb.blw + jzfb.w + jzfb.elw + jzfb.hsw)) << 16) \
293            | (jzfb.vsw + jzfb.bfw + jzfb.h + jzfb.efw);
294        break;
295    }
296
297    switch (jzfb.cfg & MODE_MASK) {
298    case MODE_TFT_SAMSUNG:
299    {
300        unsigned int total, tp_s, tp_e, ckv_s, ckv_e;
301        unsigned int rev_s, rev_e, inv_s, inv_e;
302
303        pclk = val * (jzfb.w + jzfb.hsw + jzfb.elw + jzfb.blw) *
304            (jzfb.h + jzfb.vsw + jzfb.efw + jzfb.bfw); /* Pixclk */
305
306        total = jzfb.blw + jzfb.w + jzfb.elw + jzfb.hsw;
307        tp_s = jzfb.blw + jzfb.w + 1;
308        tp_e = tp_s + 1;
309        /* ckv_s = tp_s - jz_clocks.pixclk/(1000000000/4100); */
310        ckv_s = tp_s - pclk/(1000000000/4100);
311        ckv_e = tp_s + total;
312        rev_s = tp_s - 11; /* -11.5 clk */
313        rev_e = rev_s + total;
314        inv_s = tp_s;
315        inv_e = inv_s + total;
316        REG_LCD_CLS = (tp_s << 16) | tp_e;
317        REG_LCD_PS = (ckv_s << 16) | ckv_e;
318        REG_LCD_SPL = (rev_s << 16) | rev_e;
319        REG_LCD_REV = (inv_s << 16) | inv_e;
320        jzfb.cfg |= STFT_REVHI | STFT_SPLHI;
321        break;
322    }
323    case MODE_TFT_SHARP:
324    {
325        unsigned int total, cls_s, cls_e, ps_s, ps_e;
326        unsigned int spl_s, spl_e, rev_s, rev_e;
327        total = jzfb.blw + jzfb.w + jzfb.elw + jzfb.hsw;
328        spl_s = 1;
329        spl_e = spl_s + 1;
330        cls_s = 0;
331        cls_e = total - 60; /* > 4us (pclk = 80ns) */
332        ps_s = cls_s;
333        ps_e = cls_e;
334        rev_s = total - 40; /* > 3us (pclk = 80ns) */
335        rev_e = rev_s + total;
336        jzfb.cfg |= STFT_PSHI;
337        REG_LCD_SPL = (spl_s << 16) | spl_e;
338        REG_LCD_CLS = (cls_s << 16) | cls_e;
339        REG_LCD_PS = (ps_s << 16) | ps_e;
340        REG_LCD_REV = (rev_s << 16) | rev_e;
341        break;
342    }
343    case MODE_TFT_CASIO:
344        break;
345    }
346
347    /* Configure the LCD panel */
348    REG_LCD_CFG = jzfb.cfg;
349
350    /* Timing setting */
351    __cpm_stop_lcd();
352
353    val = jzfb.fclk; /* frame clk */
354    if ( (jzfb.cfg & MODE_MASK) != MODE_8BIT_SERIAL_TFT) {
355        pclk = val * (jzfb.w + jzfb.hsw + jzfb.elw + jzfb.blw) *
356            (jzfb.h + jzfb.vsw + jzfb.efw + jzfb.bfw); /* Pixclk */
357    } else {
358        /* serial mode: Hsync period = 3*Width_Pixel */
359        pclk = val * (jzfb.w*3 + jzfb.hsw + jzfb.elw + jzfb.blw) *
360            (jzfb.h + jzfb.vsw + jzfb.efw + jzfb.bfw); /* Pixclk */
361    }
362
363    if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_SINGLE) ||
364        ((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL))
365        pclk = (pclk * 3);
366
367    if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_SINGLE) ||
368        ((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL) ||
369        ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_SINGLE) ||
370        ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL))
371        pclk = pclk >> ((jzfb.cfg & STN_DAT_PINMASK) >> 4);
372
373    if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL) ||
374        ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL))
375        pclk >>= 1;
376
377    pll_div = ( REG_CPM_CPCCR & CPM_CPCCR_PCS ); /* clock source,0:pllout/2 1: pllout */
378    pll_div = pll_div ? 1 : 2 ;
379    val = ( __cpm_get_pllout()/pll_div ) / pclk;
380    val--;
381    if ( val > 0x1ff ) {
382        printf("CPM_LPCDR too large, set it to 0x1ff\n");
383        val = 0x1ff;
384    }
385    __cpm_set_pixdiv(val);
386
387    val = pclk * 3 ; /* LCDClock > 2.5*Pixclock */
388    if ( val > 150000000 ) {
389        printf("Warning: LCDClock=%d\n, LCDClock must less or equal to 150MHz.\n", val);
390        printf("Change LCDClock to 150MHz\n");
391        val = 150000000;
392    }
393    val = ( __cpm_get_pllout()/pll_div ) / val;
394    val--;
395    if ( val > 0x1f ) {
396        printf("CPM_CPCCR.LDIV too large, set it to 0x1f\n");
397        val = 0x1f;
398    }
399    __cpm_set_ldiv( val );
400    REG_CPM_CPCCR |= CPM_CPCCR_CE ; /* update divide */
401
402    __cpm_start_lcd();
403    udelay(1000);
404
405    REG_LCD_DA0 = fbi->fdadr0; /* frame descripter*/
406
407    if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL) ||
408        ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL))
409        REG_LCD_DA1 = fbi->fdadr1; /* frame descripter*/
410
411    return 0;
412}
413
414void lcd_setcolreg (ushort regno, ushort red, ushort green, ushort blue)
415{
416}
417
418void lcd_initcolregs (void)
419{
420}
package/uboot-xburst/files/arch/mips/cpu/xburst/nanonote_gpm940b0.h
1/*
2 * JzRISC lcd controller
3 *
4 * xiangfu liu <xiangfu.z@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19 * MA 02111-1307 USA
20 */
21
22#ifndef __QI_LB60_GPM940B0_H__
23#define __QI_LB60_GPM940B0_H__
24
25#include <asm/io.h>
26
27struct lcd_desc{
28    unsigned int next_desc; /* LCDDAx */
29    unsigned int databuf; /* LCDSAx */
30    unsigned int frame_id; /* LCDFIDx */
31    unsigned int cmd; /* LCDCMDx */
32};
33
34#define MODE_MASK 0x0f
35#define MODE_TFT_GEN 0x00
36#define MODE_TFT_SHARP 0x01
37#define MODE_TFT_CASIO 0x02
38#define MODE_TFT_SAMSUNG 0x03
39#define MODE_CCIR656_NONINT 0x04
40#define MODE_CCIR656_INT 0x05
41#define MODE_STN_COLOR_SINGLE 0x08
42#define MODE_STN_MONO_SINGLE 0x09
43#define MODE_STN_COLOR_DUAL 0x0a
44#define MODE_STN_MONO_DUAL 0x0b
45#define MODE_8BIT_SERIAL_TFT 0x0c
46
47#define MODE_TFT_18BIT (1<<7)
48
49#define STN_DAT_PIN1 (0x00 << 4)
50#define STN_DAT_PIN2 (0x01 << 4)
51#define STN_DAT_PIN4 (0x02 << 4)
52#define STN_DAT_PIN8 (0x03 << 4)
53#define STN_DAT_PINMASK STN_DAT_PIN8
54
55#define STFT_PSHI (1 << 15)
56#define STFT_CLSHI (1 << 14)
57#define STFT_SPLHI (1 << 13)
58#define STFT_REVHI (1 << 12)
59
60#define SYNC_MASTER (0 << 16)
61#define SYNC_SLAVE (1 << 16)
62
63#define DE_P (0 << 9)
64#define DE_N (1 << 9)
65
66#define PCLK_P (0 << 10)
67#define PCLK_N (1 << 10)
68
69#define HSYNC_P (0 << 11)
70#define HSYNC_N (1 << 11)
71
72#define VSYNC_P (0 << 8)
73#define VSYNC_N (1 << 8)
74
75#define DATA_NORMAL (0 << 17)
76#define DATA_INVERSE (1 << 17)
77
78
79/* Jz LCDFB supported I/O controls. */
80#define FBIOSETBACKLIGHT 0x4688
81#define FBIODISPON 0x4689
82#define FBIODISPOFF 0x468a
83#define FBIORESET 0x468b
84#define FBIOPRINT_REG 0x468c
85
86/*
87 * LCD panel specific definition
88 */
89#define MODE 0xc9 /* 8bit serial RGB */
90#define SPEN (32*2+21) /*LCD_SPL */
91#define SPCK (32*2+23) /*LCD_CLS */
92#define SPDA (32*2+22) /*LCD_D12 */
93#define LCD_RET (32*3+27)
94
95#define __spi_write_reg1(reg, val) \
96do { \
97    unsigned char no;\
98    unsigned short value;\
99    unsigned char a=0;\
100    unsigned char b=0;\
101    a=reg;\
102    b=val;\
103    __gpio_set_pin(SPEN);\
104    __gpio_set_pin(SPCK);\
105    __gpio_clear_pin(SPDA);\
106    __gpio_clear_pin(SPEN);\
107    udelay(25);\
108    value=((a<<8)|(b&0xFF));\
109    for(no=0;no<16;no++)\
110    {\
111        __gpio_clear_pin(SPCK);\
112        if((value&0x8000)==0x8000)\
113        __gpio_set_pin(SPDA);\
114        else\
115        __gpio_clear_pin(SPDA);\
116        udelay(25);\
117        __gpio_set_pin(SPCK);\
118        value=(value<<1); \
119        udelay(25);\
120     }\
121    __gpio_set_pin(SPEN);\
122    udelay(100);\
123} while (0)
124
125#define __spi_write_reg(reg, val) \
126do {\
127    __spi_write_reg1((reg<<2|2), val);\
128    udelay(100); \
129}while(0)
130
131#define __lcd_special_pin_init() \
132do { \
133    __gpio_as_output(SPEN); /* use SPDA */\
134    __gpio_as_output(SPCK); /* use SPCK */\
135    __gpio_as_output(SPDA); /* use SPDA */\
136    __gpio_as_output(LCD_RET);\
137} while (0)
138
139#define __lcd_special_on() \
140do { \
141    __spi_write_reg1(0x05, 0x1e); \
142    udelay(50);\
143    __spi_write_reg1(0x05, 0x5d); \
144    __spi_write_reg1(0x0B, 0x81); \
145    __spi_write_reg1(0x01, 0x95); \
146    __spi_write_reg1(0x00, 0x07); \
147    __spi_write_reg1(0x06, 0x15); \
148    __spi_write_reg1(0x07, 0x8d); \
149    __spi_write_reg1(0x04, 0x0f); \
150    __spi_write_reg1(0x0d, 0x3d); \
151    __spi_write_reg1(0x10, 0x42); \
152    __spi_write_reg1(0x11, 0x3a); \
153    __spi_write_reg1(0x05, 0x5f); \
154} while (0)
155
156#define __lcd_special_off() \
157do { \
158    __spi_write_reg1(0x05, 0x5e); \
159} while (0)
160
161#define __lcd_set_backlight_level(n)\
162do { \
163    __gpio_as_output(LCD_RET); \
164    __gpio_set_pin(LCD_RET); \
165} while (0)
166
167#if defined(CONFIG_SAKC)
168#define __lcd_close_backlight() \
169do { \
170    __gpio_as_output(GPIO_PWM); \
171    __gpio_clear_pin(GPIO_PWM); \
172} while (0)
173#endif
174
175#if defined(CONFIG_SAKC)
176#define __lcd_display_pin_init() \
177do { \
178    __cpm_start_tcu(); \
179    __lcd_special_pin_init(); \
180} while (0)
181
182#define __lcd_display_on() \
183do { \
184    __lcd_special_on(); \
185} while (0)
186
187#define __lcd_display_off() \
188do { \
189    __lcd_special_off(); \
190} while (0)
191#else
192#define __lcd_display_pin_init() \
193do { \
194    __cpm_start_tcu(); \
195    __lcd_special_pin_init(); \
196} while (0)
197
198#define __lcd_display_on() \
199do { \
200    __gpio_set_pin(GPIO_DISP_OFF_N); \
201    __lcd_special_on(); \
202} while (0)
203
204#define __lcd_display_off() \
205do { \
206    __lcd_special_off(); \
207    __gpio_clear_pin(GPIO_DISP_OFF_N); \
208} while (0)
209#endif
210
211#endif /* __QI_LB60_GPM940B0_H__ */
package/uboot-xburst/files/drivers/mmc/jz_mmc.c
1/*
2 * (C) Copyright 2003
3 * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 */
23
24#include <config.h>
25#include <common.h>
26#include <part.h>
27#include <mmc.h>
28
29#include <asm/jz4740.h>
30#include "jz_mmc.h"
31
32#define debug(...) ;
33
34#define CFG_MMC_BASE 0x80600000
35static int sd2_0 = 0;
36
37/*
38 * GPIO definition
39 */
40#if defined(CONFIG_SAKC)
41
42#define __msc_init_io() \
43do { \
44    __gpio_as_input(GPIO_SD_CD_N); \
45} while (0)
46
47#else
48#define __msc_init_io() \
49do { \
50    __gpio_as_output(GPIO_SD_VCC_EN_N); \
51    __gpio_as_input(GPIO_SD_CD_N); \
52} while (0)
53
54#define __msc_enable_power() \
55do { \
56    __gpio_clear_pin(GPIO_SD_VCC_EN_N); \
57} while (0)
58
59#define __msc_disable_power() \
60do { \
61    __gpio_set_pin(GPIO_SD_VCC_EN_N); \
62} while (0)
63
64#endif /* CONFIG_SAKE */
65
66#define __msc_card_detected() \
67({ \
68    int detected = 1; \
69    __gpio_as_input(GPIO_SD_CD_N); \
70    __gpio_disable_pull(GPIO_SD_CD_N); \
71    if (!__gpio_get_pin(GPIO_SD_CD_N)) \
72        detected = 0; \
73    detected; \
74})
75
76/*
77 * Local functions
78 */
79
80#ifdef CONFIG_MMC
81extern int
82fat_register_device(block_dev_desc_t *dev_desc, int part_no);
83
84static block_dev_desc_t mmc_dev;
85
86block_dev_desc_t * mmc_get_dev(int dev)
87{
88    return ((block_dev_desc_t *)&mmc_dev);
89}
90
91/*
92 * FIXME needs to read cid and csd info to determine block size
93 * and other parameters
94 */
95static uchar mmc_buf[1024];
96static int mmc_ready = 0;
97static int use_4bit; /* Use 4-bit data bus */
98/*
99 * MMC Events
100 */
101#define MMC_EVENT_NONE 0x00 /* No events */
102#define MMC_EVENT_RX_DATA_DONE 0x01 /* Rx data done */
103#define MMC_EVENT_TX_DATA_DONE 0x02 /* Tx data done */
104#define MMC_EVENT_PROG_DONE 0x04 /* Programming is done */
105
106
107#define MMC_IRQ_MASK() \
108do { \
109          REG_MSC_IMASK = 0xffff; \
110          REG_MSC_IREG = 0xffff; \
111} while (0)
112
113/* Stop the MMC clock and wait while it happens */
114static inline int jz_mmc_stop_clock(void)
115{
116    int timeout = 1000;
117
118    REG_MSC_STRPCL = MSC_STRPCL_CLOCK_CONTROL_STOP;
119
120    while (timeout && (REG_MSC_STAT & MSC_STAT_CLK_EN)) {
121        timeout--;
122        if (timeout == 0)
123            return MMC_ERROR_TIMEOUT;
124        udelay(1);
125    }
126        return MMC_NO_ERROR;
127}
128
129/* Start the MMC clock and operation */
130static inline int jz_mmc_start_clock(void)
131{
132    REG_MSC_STRPCL = MSC_STRPCL_CLOCK_CONTROL_START | MSC_STRPCL_START_OP;
133    return MMC_NO_ERROR;
134}
135
136static inline u32 jz_mmc_calc_clkrt(int is_sd, u32 rate)
137{
138    u32 clkrt = 0;
139    u32 clk_src = is_sd ? 24000000 : 16000000;
140
141      while (rate < clk_src) {
142              clkrt ++;
143              clk_src >>= 1;
144        }
145
146    return clkrt;
147}
148
149/* Set the MMC clock frequency */
150void jz_mmc_set_clock(int sd, u32 rate)
151{
152    jz_mmc_stop_clock();
153
154    /* Select clock source of MSC */
155    __cpm_select_msc_clk(sd);
156
157    /* Set clock dividor of MSC */
158    REG_MSC_CLKRT = jz_mmc_calc_clkrt(sd, rate);
159}
160
161static int jz_mmc_check_status(struct mmc_request *request)
162{
163    u32 status = REG_MSC_STAT;
164
165    /* Checking for response or data timeout */
166    if (status & (MSC_STAT_TIME_OUT_RES | MSC_STAT_TIME_OUT_READ)) {
167        printf("MMC/SD timeout, MMC_STAT 0x%x CMD %d\n", status, request->cmd);
168        return MMC_ERROR_TIMEOUT;
169    }
170
171    /* Checking for CRC error */
172    if (status & (MSC_STAT_CRC_READ_ERROR | MSC_STAT_CRC_WRITE_ERROR | MSC_STAT_CRC_RES_ERR)) {
173        printf("MMC/CD CRC error, MMC_STAT 0x%x\n", status);
174        return MMC_ERROR_CRC;
175    }
176
177    return MMC_NO_ERROR;
178}
179
180/* Obtain response to the command and store it to response buffer */
181static void jz_mmc_get_response(struct mmc_request *request)
182{
183    int i;
184    u8 *buf;
185    u32 data;
186
187    debug("fetch response for request %d, cmd %d\n",
188          request->rtype, request->cmd);
189
190    buf = request->response;
191    request->result = MMC_NO_ERROR;
192
193    switch (request->rtype) {
194    case RESPONSE_R1: case RESPONSE_R1B: case RESPONSE_R6:
195    case RESPONSE_R3: case RESPONSE_R4: case RESPONSE_R5:
196    {
197        data = REG_MSC_RES;
198        buf[0] = (data >> 8) & 0xff;
199        buf[1] = data & 0xff;
200        data = REG_MSC_RES;
201        buf[2] = (data >> 8) & 0xff;
202        buf[3] = data & 0xff;
203        data = REG_MSC_RES;
204        buf[4] = data & 0xff;
205
206        debug("request %d, response [%02x %02x %02x %02x %02x]\n",
207              request->rtype, buf[0], buf[1], buf[2], buf[3], buf[4]);
208        break;
209    }
210    case RESPONSE_R2_CID: case RESPONSE_R2_CSD:
211    {
212        for (i = 0; i < 16; i += 2) {
213            data = REG_MSC_RES;
214            buf[i] = (data >> 8) & 0xff;
215            buf[i+1] = data & 0xff;
216        }
217        debug("request %d, response [", request->rtype);
218#if CONFIG_MMC_DEBUG_VERBOSE > 2
219        if (g_mmc_debug >= 3) {
220            int n;
221            for (n = 0; n < 17; n++)
222                printk("%02x ", buf[n]);
223            printk("]\n");
224        }
225#endif
226        break;
227    }
228    case RESPONSE_NONE:
229        debug("No response\n");
230        break;
231
232    default:
233        debug("unhandled response type for request %d\n", request->rtype);
234        break;
235    }
236}
237
238static int jz_mmc_receive_data(struct mmc_request *req)
239{
240    u32 stat, timeout, data, cnt;
241    u8 *buf = req->buffer;
242    u32 wblocklen = (u32)(req->block_len + 3) >> 2; /* length in word */
243
244    timeout = 0x3ffffff;
245
246    while (timeout) {
247        timeout--;
248        stat = REG_MSC_STAT;
249
250        if (stat & MSC_STAT_TIME_OUT_READ)
251            return MMC_ERROR_TIMEOUT;
252        else if (stat & MSC_STAT_CRC_READ_ERROR)
253            return MMC_ERROR_CRC;
254        else if (!(stat & MSC_STAT_DATA_FIFO_EMPTY)
255             || (stat & MSC_STAT_DATA_FIFO_AFULL)) {
256            /* Ready to read data */
257            break;
258        }
259        udelay(1);
260    }
261    if (!timeout)
262        return MMC_ERROR_TIMEOUT;
263
264    /* Read data from RXFIFO. It could be FULL or PARTIAL FULL */
265    cnt = wblocklen;
266    while (cnt) {
267        data = REG_MSC_RXFIFO;
268        {
269            *buf++ = (u8)(data >> 0);
270            *buf++ = (u8)(data >> 8);
271            *buf++ = (u8)(data >> 16);
272            *buf++ = (u8)(data >> 24);
273        }
274        cnt --;
275        while (cnt && (REG_MSC_STAT & MSC_STAT_DATA_FIFO_EMPTY))
276            ;
277    }
278    return MMC_NO_ERROR;
279}
280
281static int jz_mmc_transmit_data(struct mmc_request *req)
282{
283#if 0
284    u32 nob = req->nob;
285    u32 wblocklen = (u32)(req->block_len + 3) >> 2; /* length in word */
286    u8 *buf = req->buffer;
287    u32 *wbuf = (u32 *)buf;
288    u32 waligned = (((u32)buf & 0x3) == 0); /* word aligned ? */
289    u32 stat, timeout, data, cnt;
290
291    for (nob; nob >= 1; nob--) {
292        timeout = 0x3FFFFFF;
293
294        while (timeout) {
295            timeout--;
296            stat = REG_MSC_STAT;
297
298            if (stat & (MSC_STAT_CRC_WRITE_ERROR | MSC_STAT_CRC_WRITE_ERROR_NOSTS))
299                return MMC_ERROR_CRC;
300            else if (!(stat & MSC_STAT_DATA_FIFO_FULL)) {
301                /* Ready to write data */
302                break;
303            }
304
305            udelay(1);
306        }
307
308        if (!timeout)
309            return MMC_ERROR_TIMEOUT;
310
311        /* Write data to TXFIFO */
312        cnt = wblocklen;
313        while (cnt) {
314            while (REG_MSC_STAT & MSC_STAT_DATA_FIFO_FULL)
315                ;
316
317            if (waligned) {
318                REG_MSC_TXFIFO = *wbuf++;
319            }
320            else {
321                data = *buf++ | (*buf++ << 8) | (*buf++ << 16) | (*buf++ << 24);
322                REG_MSC_TXFIFO = data;
323            }
324
325            cnt--;
326        }
327    }
328#endif
329    return MMC_NO_ERROR;
330}
331
332
333/*
334 * Name: int jz_mmc_exec_cmd()
335 * Function: send command to the card, and get a response
336 * Input: struct mmc_request *req : MMC/SD request
337 * Output: 0: right >0: error code
338 */
339int jz_mmc_exec_cmd(struct mmc_request *request)
340{
341    u32 cmdat = 0, events = 0;
342    int retval, timeout = 0x3fffff;
343
344    /* Indicate we have no result yet */
345    request->result = MMC_NO_RESPONSE;
346    if (request->cmd == MMC_CIM_RESET) {
347        /* On reset, 1-bit bus width */
348        use_4bit = 0;
349
350        /* Reset MMC/SD controller */
351        __msc_reset();
352
353        /* On reset, drop MMC clock down */
354        jz_mmc_set_clock(0, MMC_CLOCK_SLOW);
355
356        /* On reset, stop MMC clock */
357        jz_mmc_stop_clock();
358    }
359    if (request->cmd == MMC_CMD_SEND_OP_COND) {
360        debug("Have an MMC card\n");
361        /* always use 1bit for MMC */
362        use_4bit = 0;
363    }
364    if (request->cmd == SET_BUS_WIDTH) {
365        if (request->arg == 0x2) {
366            printf("Use 4-bit bus width\n");
367            use_4bit = 1;
368        } else {
369            printf("Use 1-bit bus width\n");
370            use_4bit = 0;
371        }
372    }
373
374    /* stop clock */
375    jz_mmc_stop_clock();
376
377    /* mask all interrupts */
378    REG_MSC_IMASK = 0xffff;
379
380    /* clear status */
381    REG_MSC_IREG = 0xffff;
382
383    /* use 4-bit bus width when possible */
384    if (use_4bit)
385        cmdat |= MSC_CMDAT_BUS_WIDTH_4BIT;
386
387        /* Set command type and events */
388    switch (request->cmd) {
389    /* MMC core extra command */
390    case MMC_CIM_RESET:
391        cmdat |= MSC_CMDAT_INIT; /* Initialization sequence sent prior to command */
392        break;
393
394    /* bc - broadcast - no response */
395    case MMC_CMD_GO_IDLE_STATE:
396    case MMC_CMD_SET_DSR:
397        break;
398
399    /* bcr - broadcast with response */
400    case MMC_CMD_SEND_OP_COND:
401    case MMC_CMD_ALL_SEND_CID:
402    case MMC_GO_IRQ_STATE:
403        break;
404
405    /* adtc - addressed with data transfer */
406    case MMC_READ_DAT_UNTIL_STOP:
407    case MMC_CMD_READ_SINGLE_BLOCK:
408    case MMC_CMD_READ_MULTIPLE_BLOCK:
409    case SD_CMD_APP_SEND_SCR:
410        cmdat |= MSC_CMDAT_DATA_EN | MSC_CMDAT_READ;
411        events = MMC_EVENT_RX_DATA_DONE;
412        break;
413
414    case MMC_WRITE_DAT_UNTIL_STOP:
415    case MMC_CMD_WRITE_SINGLE_BLOCK:
416    case MMC_CMD_WRITE_MULTIPLE_BLOCK:
417    case MMC_PROGRAM_CID:
418    case MMC_PROGRAM_CSD:
419    case MMC_SEND_WRITE_PROT:
420    case MMC_GEN_CMD:
421    case MMC_LOCK_UNLOCK:
422        cmdat |= MSC_CMDAT_DATA_EN | MSC_CMDAT_WRITE;
423        events = MMC_EVENT_TX_DATA_DONE | MMC_EVENT_PROG_DONE;
424
425        break;
426
427    case MMC_CMD_STOP_TRANSMISSION:
428        events = MMC_EVENT_PROG_DONE;
429        break;
430
431    /* ac - no data transfer */
432    default:
433        break;
434    }
435
436    /* Set response type */
437    switch (request->rtype) {
438    case RESPONSE_NONE:
439        break;
440
441    case RESPONSE_R1B:
442        cmdat |= MSC_CMDAT_BUSY;
443        /*FALLTHRU*/
444    case RESPONSE_R1:
445        cmdat |= MSC_CMDAT_RESPONSE_R1;
446        break;
447    case RESPONSE_R2_CID:
448    case RESPONSE_R2_CSD:
449        cmdat |= MSC_CMDAT_RESPONSE_R2;
450        break;
451    case RESPONSE_R3:
452        cmdat |= MSC_CMDAT_RESPONSE_R3;
453        break;
454    case RESPONSE_R4:
455        cmdat |= MSC_CMDAT_RESPONSE_R4;
456        break;
457    case RESPONSE_R5:
458        cmdat |= MSC_CMDAT_RESPONSE_R5;
459        break;
460    case RESPONSE_R6:
461        cmdat |= MSC_CMDAT_RESPONSE_R6;
462        break;
463    default:
464        break;
465    }
466
467    /* Set command index */
468    if (request->cmd == MMC_CIM_RESET) {
469        REG_MSC_CMD = MMC_CMD_GO_IDLE_STATE;
470    } else {
471        REG_MSC_CMD = request->cmd;
472    }
473
474        /* Set argument */
475    REG_MSC_ARG = request->arg;
476
477    /* Set block length and nob */
478    if (request->cmd == SD_CMD_APP_SEND_SCR) { /* get SCR from DataFIFO */
479        REG_MSC_BLKLEN = 8;
480        REG_MSC_NOB = 1;
481    } else {
482        REG_MSC_BLKLEN = request->block_len;
483        REG_MSC_NOB = request->nob;
484    }
485
486    /* Set command */
487    REG_MSC_CMDAT = cmdat;
488
489    debug("Send cmd %d cmdat: %x arg: %x resp %d\n", request->cmd,
490          cmdat, request->arg, request->rtype);
491
492        /* Start MMC/SD clock and send command to card */
493    jz_mmc_start_clock();
494
495    /* Wait for command completion */
496    while (timeout-- && !(REG_MSC_STAT & MSC_STAT_END_CMD_RES))
497        ;
498
499    if (timeout == 0)
500        return MMC_ERROR_TIMEOUT;
501
502    REG_MSC_IREG = MSC_IREG_END_CMD_RES; /* clear flag */
503
504    /* Check for status */
505    retval = jz_mmc_check_status(request);
506    if (retval) {
507        return retval;
508    }
509
510    /* Complete command with no response */
511    if (request->rtype == RESPONSE_NONE) {
512        return MMC_NO_ERROR;
513    }
514
515    /* Get response */
516    jz_mmc_get_response(request);
517
518    /* Start data operation */
519    if (events & (MMC_EVENT_RX_DATA_DONE | MMC_EVENT_TX_DATA_DONE)) {
520        if (events & MMC_EVENT_RX_DATA_DONE) {
521            if (request->cmd == SD_CMD_APP_SEND_SCR) {
522                /* SD card returns SCR register as data.
523                   MMC core expect it in the response buffer,
524                   after normal response. */
525                request->buffer = (u8 *)((u32)request->response + 5);
526            }
527            jz_mmc_receive_data(request);
528        }
529
530        if (events & MMC_EVENT_TX_DATA_DONE) {
531            jz_mmc_transmit_data(request);
532        }
533
534        /* Wait for Data Done */
535        while (!(REG_MSC_IREG & MSC_IREG_DATA_TRAN_DONE))
536            ;
537        REG_MSC_IREG = MSC_IREG_DATA_TRAN_DONE; /* clear status */
538    }
539
540    /* Wait for Prog Done event */
541    if (events & MMC_EVENT_PROG_DONE) {
542        while (!(REG_MSC_IREG & MSC_IREG_PRG_DONE))
543            ;
544        REG_MSC_IREG = MSC_IREG_PRG_DONE; /* clear status */
545    }
546
547    /* Command completed */
548
549    return MMC_NO_ERROR; /* return successfully */
550}
551
552int mmc_block_read(u8 *dst, ulong src, ulong len)
553{
554
555    struct mmc_request request;
556    struct mmc_response_r1 r1;
557    int retval = 0;
558
559    if (len == 0)
560        goto exit;
561
562    mmc_simple_cmd(&request, MMC_CMD_SEND_STATUS, mmcinfo.rca, RESPONSE_R1);
563    retval = mmc_unpack_r1(&request, &r1, 0);
564    if (retval && (retval != MMC_ERROR_STATE_MISMATCH))
565        goto exit;
566
567    mmc_simple_cmd(&request, MMC_CMD_SET_BLOCKLEN, len, RESPONSE_R1);
568    if ((retval = mmc_unpack_r1(&request, &r1, 0)))
569        goto exit;
570
571    if (sd2_0)
572        src /= len;
573
574    mmc_send_cmd(&request, MMC_CMD_READ_SINGLE_BLOCK, src, 1,len, RESPONSE_R1, dst);
575    if ((retval = mmc_unpack_r1(&request, &r1, 0)))
576        goto exit;
577
578exit:
579    return retval;
580}
581
582int mmc_block_write(ulong dst, uchar *src, int len)
583{
584    return 0;
585}
586
587int xburst_mmc_read(u64 src, uchar *dst, int size)
588{
589    ulong end, part_start, part_end, part_len, aligned_start, aligned_end;
590    ulong mmc_block_size, mmc_block_address;
591
592    if (size == 0) {
593        return 0;
594    }
595
596    if (!mmc_ready) {
597        printf("Please initial the MMC first\n");
598        return -1;
599    }
600
601    debug("---- start %s ---- \n", __func__);
602
603    mmc_block_size = mmcinfo.block_len;
604    mmc_block_address = ~(mmc_block_size - 1);
605
606    end = src + size;
607    part_start = ~mmc_block_address & src;
608    part_end = ~mmc_block_address & end;
609    aligned_start = mmc_block_address & src;
610    aligned_end = mmc_block_address & end;
611    /* all block aligned accesses */
612    debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
613          src, (ulong)dst, end, part_start, part_end, aligned_start,
614          aligned_end);
615
616    if (part_start) {
617        part_len = mmc_block_size - part_start;
618        debug("ps src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
619             src, (ulong) dst, end, part_start, part_end, aligned_start,
620             aligned_end);
621
622        if ((mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) < 0) {
623
624            return -1;
625        }
626        memcpy(dst, mmc_buf + part_start, part_len);
627        dst += part_len;
628        src += part_len;
629    }
630
631    for (; src < aligned_end; src += mmc_block_size, dst += mmc_block_size) {
632        debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
633        src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
634
635        if ((mmc_block_read((uchar *)(dst), src, mmc_block_size)) < 0) {
636            return -1;
637        }
638    }
639
640    debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
641          src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
642
643    if (part_end && src < end) {
644        if ((mmc_block_read(mmc_buf, aligned_end, mmc_block_size)) < 0) {
645            return -1;
646        }
647        memcpy(dst, mmc_buf, part_end);
648    }
649
650    debug("---- end %s ---- \n", __func__);
651    return 0;
652}
653
654int mmc_write(uchar *src, ulong dst, int size)
655{
656    ulong end, part_start, part_end, part_len, aligned_start, aligned_end;
657    ulong mmc_block_size, mmc_block_address;
658
659    if (size == 0) {
660        return 0;
661    }
662
663    if (!mmc_ready) {
664        printf("MMC card is not ready\n");
665        return -1;
666    }
667
668    mmc_block_size = mmcinfo.block_len;
669    mmc_block_address = ~(mmc_block_size - 1);
670
671    dst -= CFG_MMC_BASE;
672    end = dst + size;
673    part_start = ~mmc_block_address & dst;
674    part_end = ~mmc_block_address & end;
675    aligned_start = mmc_block_address & dst;
676    aligned_end = mmc_block_address & end;
677
678    /* all block aligned accesses */
679    debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
680    src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
681    if (part_start) {
682        part_len = mmc_block_size - part_start;
683        debug("ps src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
684        (ulong)src, dst, end, part_start, part_end, aligned_start, aligned_end);
685        if ((mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) < 0) {
686            return -1;
687        }
688        memcpy(mmc_buf+part_start, src, part_len);
689        if ((mmc_block_write(aligned_start, mmc_buf, mmc_block_size)) < 0) {
690            return -1;
691        }
692        dst += part_len;
693        src += part_len;
694    }
695    debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
696    src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
697    for (; dst < aligned_end; src += mmc_block_size, dst += mmc_block_size) {
698        debug("al src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
699        src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
700        if ((mmc_block_write(dst, (uchar *)src, mmc_block_size)) < 0) {
701            return -1;
702        }
703    }
704    debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
705    src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
706    if (part_end && dst < end) {
707        debug("pe src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
708        src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
709        if ((mmc_block_read(mmc_buf, aligned_end, mmc_block_size)) < 0) {
710            return -1;
711        }
712        memcpy(mmc_buf, src, part_end);
713        if ((mmc_block_write(aligned_end, mmc_buf, mmc_block_size)) < 0) {
714            return -1;
715        }
716    }
717    return 0;
718}
719
720ulong mmc_bread(int dev_num, ulong blknr, ulong blkcnt, ulong *dst)
721{
722    int mmc_block_size = mmcinfo.block_len;
723    ulong src = blknr * mmc_block_size ;//+ CFG_MMC_BASE;
724
725    xburst_mmc_read(src, (uchar *)dst, blkcnt*mmc_block_size);
726    return blkcnt;
727}
728
729int mmc_select_card(void)
730{
731    struct mmc_request request;
732    struct mmc_response_r1 r1;
733    int retval;
734
735    mmc_simple_cmd(&request, MMC_CMD_SELECT_CARD, mmcinfo.rca, RESPONSE_R1B);
736    retval = mmc_unpack_r1(&request, &r1, 0);
737    if (retval) {
738        return retval;
739    }
740
741    if (mmcinfo.sd) {
742        mmc_simple_cmd(&request, MMC_CMD_APP_CMD, mmcinfo.rca, RESPONSE_R1);
743        retval = mmc_unpack_r1(&request,&r1,0);
744        if (retval) {
745            return retval;
746        }
747#if defined(MMC_BUS_WIDTH_1BIT)
748        mmc_simple_cmd(&request, SET_BUS_WIDTH, 1, RESPONSE_R1);
749#else
750        mmc_simple_cmd(&request, SET_BUS_WIDTH, 2, RESPONSE_R1);
751#endif
752                retval = mmc_unpack_r1(&request,&r1,0);
753                if (retval) {
754            return retval;
755        }
756    }
757    return 0;
758}
759
760/*
761 * Configure card
762 */
763static void mmc_configure_card(void)
764{
765    u32 rate;
766
767    /* Get card info */
768    if (sd2_0)
769        mmcinfo.block_num = (mmcinfo.csd.c_size + 1) << 10;
770    else
771        mmcinfo.block_num = (mmcinfo.csd.c_size + 1) * (1 << (mmcinfo.csd.c_size_mult + 2));
772
773    mmcinfo.block_len = 1 << mmcinfo.csd.read_bl_len;
774
775    mmc_dev.if_type = IF_TYPE_SD;
776    mmc_dev.part_type = PART_TYPE_DOS;
777    mmc_dev.dev = 0;
778    mmc_dev.lun = 0;
779    mmc_dev.type = 0;
780    mmc_dev.blksz = mmcinfo.block_len;
781    mmc_dev.lba = mmcinfo.block_num;
782    mmc_dev.removable = 0;
783
784    printf("%s Detected: %lu blocks of %lu bytes\n",
785           sd2_0 == 1 ? "SDHC" : "SD",
786           mmc_dev.lba,
787           mmc_dev.blksz);
788
789    /* Fix the clock rate */
790    rate = mmc_tran_speed(mmcinfo.csd.tran_speed);
791    if (rate < MMC_CLOCK_SLOW)
792        rate = MMC_CLOCK_SLOW;
793    if ((mmcinfo.sd == 0) && (rate > MMC_CLOCK_FAST))
794        rate = MMC_CLOCK_FAST;
795        if ((mmcinfo.sd) && (rate > SD_CLOCK_FAST))
796        rate = SD_CLOCK_FAST;
797
798    debug("%s: block_len=%d block_num=%d rate=%d\n",
799          __func__, mmcinfo.block_len, mmcinfo.block_num, rate);
800
801    jz_mmc_set_clock(mmcinfo.sd, rate);
802}
803
804/*
805 * State machine routines to initialize card(s)
806 */
807
808/*
809  CIM_SINGLE_CARD_ACQ (frequency at 400 kHz)
810  --- Must enter from GO_IDLE_STATE ---
811  1. SD_SEND_OP_COND (SD Card) [CMD55] + [CMD41]
812  2. SEND_OP_COND (Full Range) [CMD1] {optional}
813  3. SEND_OP_COND (Set Range ) [CMD1]
814     If busy, delay and repeat step 2
815  4. ALL_SEND_CID [CMD2]
816     If timeout, set an error (no cards found)
817  5. SET_RELATIVE_ADDR [CMD3]
818  6. SEND_CSD [CMD9]
819  7. SET_DSR [CMD4] Only call this if (csd.dsr_imp).
820  8. Set clock frequency (check available in csd.tran_speed)
821 */
822
823#define MMC_INIT_DOING 0
824#define MMC_INIT_PASSED 1
825#define MMC_INIT_FAILED 2
826
827static int mmc_init_card_state(struct mmc_request *request)
828{
829    struct mmc_response_r1 r1;
830    struct mmc_response_r3 r3;
831    int retval;
832    int ocr = 0x40300000;
833    int limit_41 = 0;
834
835    switch (request->cmd) {
836    case MMC_CMD_GO_IDLE_STATE: /* No response to parse */
837        if (mmcinfo.sd)
838            mmc_simple_cmd(request, 8, 0x1aa, RESPONSE_R1);
839        else
840            mmc_simple_cmd(request, MMC_CMD_SEND_OP_COND, MMC_OCR_ARG, RESPONSE_R3);
841        break;
842
843    case 8:
844            retval = mmc_unpack_r1(request,&r1,mmcinfo.state);
845        mmc_simple_cmd(request, MMC_CMD_APP_CMD, 0, RESPONSE_R1);
846        break;
847
848        case MMC_CMD_APP_CMD:
849            retval = mmc_unpack_r1(request,&r1,mmcinfo.state);
850        if (retval & (limit_41 < 100)) {
851            debug("%s: unable to MMC_APP_CMD error=%d (%s)\n",
852                  __func__, retval, mmc_result_to_string(retval));
853            limit_41++;
854            mmc_simple_cmd(request, SD_CMD_APP_SEND_OP_COND, ocr, RESPONSE_R3);
855        } else if (limit_41 < 100) {
856            limit_41++;
857            mmc_simple_cmd(request, SD_CMD_APP_SEND_OP_COND, ocr, RESPONSE_R3);
858        } else{
859            /* reset the card to idle*/
860            mmc_simple_cmd(request, MMC_CMD_GO_IDLE_STATE, 0, RESPONSE_NONE);
861            mmcinfo.sd = 0;
862        }
863        break;
864
865        case SD_CMD_APP_SEND_OP_COND:
866                retval = mmc_unpack_r3(request, &r3);
867                if (retval) {
868            debug("%s: try MMC card\n", __func__);
869            mmc_simple_cmd(request, SD_CMD_APP_SEND_OP_COND, MMC_OCR_ARG, RESPONSE_R3);
870            break;
871        }
872
873                debug("%s: read ocr value = 0x%08x\n", __func__, r3.ocr);
874
875        if(!(r3.ocr & MMC_CARD_BUSY || ocr == 0)){
876            udelay(50000);
877            mmc_simple_cmd(request, MMC_CMD_APP_CMD, 0, RESPONSE_R1);
878        } else {
879            mmcinfo.sd = 1; /* SD Card ready */
880            mmcinfo.state = CARD_STATE_READY;
881            mmc_simple_cmd(request, MMC_CMD_ALL_SEND_CID, 0, RESPONSE_R2_CID);
882        }
883        break;
884
885    case MMC_CMD_SEND_OP_COND:
886        retval = mmc_unpack_r3(request, &r3);
887        if (retval) {
888            debug("%s: failed SEND_OP_COND error=%d (%s)\n",
889                  __func__, retval, mmc_result_to_string(retval));
890            return MMC_INIT_FAILED;
891        }
892
893        debug("%s: read ocr value = 0x%08x\n", __func__, r3.ocr);
894        if (!(r3.ocr & MMC_CARD_BUSY)) {
895                    mmc_simple_cmd(request, MMC_CMD_SEND_OP_COND, MMC_OCR_ARG, RESPONSE_R3);
896        } else {
897                mmcinfo.sd = 0; /* MMC Card ready */
898            mmcinfo.state = CARD_STATE_READY;
899            mmc_simple_cmd(request, MMC_CMD_ALL_SEND_CID, 0, RESPONSE_R2_CID);
900        }
901        break;
902
903    case MMC_CMD_ALL_SEND_CID:
904        retval = mmc_unpack_cid( request, &mmcinfo.cid );
905        /*FIXME:ignore CRC error for CMD2/CMD9/CMD10 */
906        if ( retval && (retval != MMC_ERROR_CRC)) {
907            debug("mmc_init_card_state: unable to ALL_SEND_CID error=%d (%s)\n",
908                  retval, mmc_result_to_string(retval));
909            return MMC_INIT_FAILED;
910        }
911        mmcinfo.state = CARD_STATE_IDENT;
912        if(mmcinfo.sd)
913            mmc_simple_cmd(request, MMC_CMD_SET_RELATIVE_ADDR, 0, RESPONSE_R6);
914                else
915            mmc_simple_cmd(request, MMC_CMD_SET_RELATIVE_ADDR, ID_TO_RCA(mmcinfo.id) << 16, RESPONSE_R1);
916        break;
917
918        case MMC_CMD_SET_RELATIVE_ADDR:
919            if (mmcinfo.sd) {
920            retval = mmc_unpack_r6(request, &r1, mmcinfo.state, &mmcinfo.rca);
921            mmcinfo.rca = mmcinfo.rca << 16;
922            debug("%s: Get RCA from SD: 0x%04x Status: %x\n",
923                  __func__, mmcinfo.rca, r1.status);
924                } else {
925            retval = mmc_unpack_r1(request,&r1,mmcinfo.state);
926            mmcinfo.rca = ID_TO_RCA(mmcinfo.id) << 16;
927            }
928        if (retval) {
929            debug("%s: unable to SET_RELATIVE_ADDR error=%d (%s)\n",
930                  __func__, retval, mmc_result_to_string(retval));
931            return MMC_INIT_FAILED;
932        }
933
934        mmcinfo.state = CARD_STATE_STBY;
935                mmc_simple_cmd(request, MMC_CMD_SEND_CSD, mmcinfo.rca, RESPONSE_R2_CSD);
936
937        break;
938
939    case MMC_CMD_SEND_CSD:
940        retval = mmc_unpack_csd(request, &mmcinfo.csd);
941        mmc_ready = 1;
942        /*FIXME:ignore CRC error for CMD2/CMD9/CMD10 */
943            if (retval && (retval != MMC_ERROR_CRC)) {
944            debug("%s: unable to SEND_CSD error=%d (%s)\n",
945                  __func__, retval, mmc_result_to_string(retval));
946            return MMC_INIT_FAILED;
947        }
948        if (mmcinfo.csd.dsr_imp) {
949            debug("%s: driver doesn't support setting DSR\n", __func__);
950        }
951        mmc_configure_card();
952        return MMC_INIT_PASSED;
953
954    default:
955        debug("%s: error! Illegal last cmd %d\n", __func__, request->cmd);
956        return MMC_INIT_FAILED;
957    }
958
959    return MMC_INIT_DOING;
960}
961
962int mmc_init_card(void)
963{
964    struct mmc_request request;
965    int retval;
966
967    mmc_simple_cmd(&request, MMC_CIM_RESET, 0, RESPONSE_NONE); /* reset card */
968    mmc_simple_cmd(&request, MMC_CMD_GO_IDLE_STATE, 0, RESPONSE_NONE);
969    mmcinfo.sd = 1; /* assuming a SD card */
970
971    while ((retval = mmc_init_card_state(&request)) == MMC_INIT_DOING)
972        ;
973
974    if (retval == MMC_INIT_PASSED)
975        return MMC_NO_ERROR;
976    else
977        return MMC_NO_RESPONSE;
978}
979
980int mmc_legacy_init(int verbose)
981{
982    if (!__msc_card_detected())
983        return 1;
984
985    /* Step-1: init GPIO */
986    __gpio_as_msc();
987    __msc_init_io();
988
989    /* Step-2: turn on power of card */
990#if !defined(CONFIG_SAKC)
991    __msc_enable_power();
992#endif
993
994    /* Step-3: Reset MSC Controller. */
995    __msc_reset();
996
997    /* Step-3: mask all IRQs. */
998    MMC_IRQ_MASK();
999
1000    /* Step-4: stop MMC/SD clock */
1001    jz_mmc_stop_clock();
1002    mmc_init_card();
1003    mmc_select_card();
1004
1005    mmc_dev.block_read = mmc_bread;
1006    fat_register_device(&mmc_dev,1); /* partitions start counting with 1 */
1007
1008    return 0;
1009}
1010
1011int mmc_ident(block_dev_desc_t *dev)
1012{
1013    return 0;
1014}
1015
1016int mmc2info(ulong addr)
1017{
1018    /* FIXME hard codes to 32 MB device */
1019    if (addr >= CFG_MMC_BASE && addr < CFG_MMC_BASE + 0x02000000) {
1020        return 1;
1021    }
1022    return 0;;
1023}
1024/*
1025 * Debugging functions
1026 */
1027
1028static char * mmc_result_strings[] = {
1029    "NO_RESPONSE",
1030    "NO_ERROR",
1031    "ERROR_OUT_OF_RANGE",
1032    "ERROR_ADDRESS",
1033    "ERROR_BLOCK_LEN",
1034    "ERROR_ERASE_SEQ",
1035    "ERROR_ERASE_PARAM",
1036    "ERROR_WP_VIOLATION",
1037    "ERROR_CARD_IS_LOCKED",
1038    "ERROR_LOCK_UNLOCK_FAILED",
1039    "ERROR_COM_CRC",
1040    "ERROR_ILLEGAL_COMMAND",
1041    "ERROR_CARD_ECC_FAILED",
1042    "ERROR_CC",
1043    "ERROR_GENERAL",
1044    "ERROR_UNDERRUN",
1045    "ERROR_OVERRUN",
1046    "ERROR_CID_CSD_OVERWRITE",
1047    "ERROR_STATE_MISMATCH",
1048    "ERROR_HEADER_MISMATCH",
1049    "ERROR_TIMEOUT",
1050    "ERROR_CRC",
1051    "ERROR_DRIVER_FAILURE",
1052};
1053
1054char * mmc_result_to_string(int i)
1055{
1056    return mmc_result_strings[i+1];
1057}
1058
1059static char * card_state_strings[] = {
1060    "empty",
1061    "idle",
1062    "ready",
1063    "ident",
1064    "stby",
1065    "tran",
1066    "data",
1067    "rcv",
1068    "prg",
1069    "dis",
1070};
1071
1072static inline char * card_state_to_string(int i)
1073{
1074    return card_state_strings[i+1];
1075}
1076
1077/*
1078 * Utility functions
1079 */
1080
1081#define PARSE_U32(_buf,_index) \
1082    (((u32)_buf[_index]) << 24) | (((u32)_buf[_index+1]) << 16) | \
1083        (((u32)_buf[_index+2]) << 8) | ((u32)_buf[_index+3]);
1084
1085#define PARSE_U16(_buf,_index) \
1086    (((u16)_buf[_index]) << 8) | ((u16)_buf[_index+1]);
1087
1088int mmc_unpack_csd(struct mmc_request *request, struct mmc_csd *csd)
1089{
1090    u8 *buf = request->response;
1091    int num = 0;
1092
1093    if (request->result)
1094        return request->result;
1095
1096    if (buf[0] != 0x3f)
1097        return MMC_ERROR_HEADER_MISMATCH;
1098
1099    csd->csd_structure = (buf[1] & 0xc0) >> 6;
1100    if (csd->csd_structure)
1101        sd2_0 = 1;
1102    else
1103        sd2_0 = 0;
1104
1105    switch (csd->csd_structure) {
1106    case 0 :/* Version 1.01-1.10
1107         * Version 2.00/Standard Capacity */
1108        csd->taac = buf[2];
1109        csd->nsac = buf[3];
1110        csd->tran_speed = buf[4];
1111        csd->ccc = (((u16)buf[5]) << 4) | ((buf[6] & 0xf0) >> 4);
1112        csd->read_bl_len = buf[6] & 0x0f;
1113        /* for support 2GB card*/
1114        if (csd->read_bl_len >= 10)
1115        {
1116            num = csd->read_bl_len - 9;
1117            csd->read_bl_len = 9;
1118        }
1119
1120        csd->read_bl_partial = (buf[7] & 0x80) ? 1 : 0;
1121        csd->write_blk_misalign = (buf[7] & 0x40) ? 1 : 0;
1122        csd->read_blk_misalign = (buf[7] & 0x20) ? 1 : 0;
1123        csd->dsr_imp = (buf[7] & 0x10) ? 1 : 0;
1124        csd->c_size = ((((u16)buf[7]) & 0x03) << 10) | (((u16)buf[8]) << 2) | (((u16)buf[9]) & 0xc0) >> 6;
1125
1126        if (num)
1127            csd->c_size = csd->c_size << num;
1128
1129
1130        csd->vdd_r_curr_min = (buf[9] & 0x38) >> 3;
1131        csd->vdd_r_curr_max = buf[9] & 0x07;
1132        csd->vdd_w_curr_min = (buf[10] & 0xe0) >> 5;
1133        csd->vdd_w_curr_max = (buf[10] & 0x1c) >> 2;
1134        csd->c_size_mult = ((buf[10] & 0x03) << 1) | ((buf[11] & 0x80) >> 7);
1135        csd->sector_size = (buf[11] & 0x7c) >> 2;
1136        csd->erase_grp_size = ((buf[11] & 0x03) << 3) | ((buf[12] & 0xe0) >> 5);
1137        csd->wp_grp_size = buf[12] & 0x1f;
1138        csd->wp_grp_enable = (buf[13] & 0x80) ? 1 : 0;
1139        csd->default_ecc = (buf[13] & 0x60) >> 5;
1140        csd->r2w_factor = (buf[13] & 0x1c) >> 2;
1141        csd->write_bl_len = ((buf[13] & 0x03) << 2) | ((buf[14] & 0xc0) >> 6);
1142        if (csd->write_bl_len >= 10)
1143            csd->write_bl_len = 9;
1144
1145        csd->write_bl_partial = (buf[14] & 0x20) ? 1 : 0;
1146        csd->file_format_grp = (buf[15] & 0x80) ? 1 : 0;
1147        csd->copy = (buf[15] & 0x40) ? 1 : 0;
1148        csd->perm_write_protect = (buf[15] & 0x20) ? 1 : 0;
1149        csd->tmp_write_protect = (buf[15] & 0x10) ? 1 : 0;
1150        csd->file_format = (buf[15] & 0x0c) >> 2;
1151        csd->ecc = buf[15] & 0x03;
1152        break;
1153    case 1 : /* Version 2.00/High Capacity */
1154        csd->taac = 0;
1155        csd->nsac = 0;
1156        csd->tran_speed = buf[4];
1157        csd->ccc = (((u16)buf[5]) << 4) | ((buf[6] & 0xf0) >> 4);
1158
1159        csd->read_bl_len = 9;
1160        csd->read_bl_partial = 0;
1161        csd->write_blk_misalign = 0;
1162        csd->read_blk_misalign = 0;
1163        csd->dsr_imp = (buf[7] & 0x10) ? 1 : 0;
1164        csd->c_size = ((((u16)buf[8]) & 0x3f) << 16) | (((u16)buf[9]) << 8) | ((u16)buf[10]) ;
1165        csd->sector_size = 0x7f;
1166        csd->erase_grp_size = 0;
1167        csd->wp_grp_size = 0;
1168        csd->wp_grp_enable = 0;
1169        csd->default_ecc = (buf[13] & 0x60) >> 5;
1170        csd->r2w_factor = 4;/* Unused */
1171        csd->write_bl_len = 9;
1172
1173        csd->write_bl_partial = 0;
1174        csd->file_format_grp = 0;
1175        csd->copy = (buf[15] & 0x40) ? 1 : 0;
1176        csd->perm_write_protect = (buf[15] & 0x20) ? 1 : 0;
1177        csd->tmp_write_protect = (buf[15] & 0x10) ? 1 : 0;
1178        csd->file_format = 0;
1179        csd->ecc = buf[15] & 0x03;
1180    }
1181
1182    return 0;
1183}
1184
1185int mmc_unpack_r1(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state)
1186{
1187    u8 *buf = request->response;
1188
1189    if (request->result)
1190        return request->result;
1191
1192    r1->cmd = buf[0];
1193    r1->status = PARSE_U32(buf,1);
1194
1195    debug("mmc_unpack_r1: cmd=%d status=%08x\n", r1->cmd, r1->status);
1196
1197    if (R1_STATUS(r1->status)) {
1198        if (r1->status & R1_OUT_OF_RANGE) return MMC_ERROR_OUT_OF_RANGE;
1199        if (r1->status & R1_ADDRESS_ERROR) return MMC_ERROR_ADDRESS;
1200        if (r1->status & R1_BLOCK_LEN_ERROR) return MMC_ERROR_BLOCK_LEN;
1201        if (r1->status & R1_ERASE_SEQ_ERROR) return MMC_ERROR_ERASE_SEQ;
1202        if (r1->status & R1_ERASE_PARAM) return MMC_ERROR_ERASE_PARAM;
1203        if (r1->status & R1_WP_VIOLATION) return MMC_ERROR_WP_VIOLATION;
1204        /*if (r1->status & R1_CARD_IS_LOCKED) return MMC_ERROR_CARD_IS_LOCKED; */
1205        if (r1->status & R1_LOCK_UNLOCK_FAILED) return MMC_ERROR_LOCK_UNLOCK_FAILED;
1206        if (r1->status & R1_COM_CRC_ERROR) return MMC_ERROR_COM_CRC;
1207        if (r1->status & R1_ILLEGAL_COMMAND) return MMC_ERROR_ILLEGAL_COMMAND;
1208        if (r1->status & R1_CARD_ECC_FAILED) return MMC_ERROR_CARD_ECC_FAILED;
1209        if (r1->status & R1_CC_ERROR) return MMC_ERROR_CC;
1210        if (r1->status & R1_ERROR) return MMC_ERROR_GENERAL;
1211        if (r1->status & R1_UNDERRUN) return MMC_ERROR_UNDERRUN;
1212        if (r1->status & R1_OVERRUN) return MMC_ERROR_OVERRUN;
1213        if (r1->status & R1_CID_CSD_OVERWRITE) return MMC_ERROR_CID_CSD_OVERWRITE;
1214    }
1215
1216    if (buf[0] != request->cmd)
1217        return MMC_ERROR_HEADER_MISMATCH;
1218
1219    /* This should be last - it's the least dangerous error */
1220
1221    return 0;
1222}
1223
1224int mmc_unpack_scr(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state, u32 *scr)
1225{
1226        u8 *buf = request->response;
1227    if (request->result)
1228        return request->result;
1229
1230        *scr = PARSE_U32(buf, 5); /* Save SCR returned by the SD Card */
1231        return mmc_unpack_r1(request, r1, state);
1232
1233}
1234
1235int mmc_unpack_r6(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state, int *rca)
1236{
1237    u8 *buf = request->response;
1238
1239    if (request->result)
1240        return request->result;
1241
1242        *rca = PARSE_U16(buf,1); /* Save RCA returned by the SD Card */
1243
1244        *(buf+1) = 0;
1245        *(buf+2) = 0;
1246
1247        return mmc_unpack_r1(request, r1, state);
1248}
1249
1250int mmc_unpack_cid(struct mmc_request *request, struct mmc_cid *cid)
1251{
1252    int i;
1253    u8 *buf = request->response;
1254
1255    if (request->result)
1256        return request->result;
1257
1258    cid->mid = buf[1];
1259    cid->oid = PARSE_U16(buf,2);
1260    for (i = 0 ; i < 5 ; i++)
1261        cid->pnm[i] = buf[4+i];
1262    cid->pnm[6] = 0;
1263    cid->prv = buf[10];
1264    cid->psn = PARSE_U32(buf,10);
1265    cid->mdt = buf[15];
1266
1267    printf("Man %02x OEM 0x%04x \"%s\" %d.%d 0x%08x "
1268           "Date %02u/%04u\n",
1269           cid->mid,
1270           cid->oid,
1271           cid->pnm,
1272           cid->prv >> 4,
1273           cid->prv & 0xf,
1274           cid->psn,
1275           cid->mdt & 0xf,
1276           (cid->mdt >> 4) + 2000);
1277
1278    if (buf[0] != 0x3f)
1279        return MMC_ERROR_HEADER_MISMATCH;
1280          return 0;
1281}
1282
1283int mmc_unpack_r3(struct mmc_request *request, struct mmc_response_r3 *r3)
1284{
1285    u8 *buf = request->response;
1286
1287    if (request->result)
1288        return request->result;
1289
1290    r3->ocr = PARSE_U32(buf,1);
1291    debug("mmc_unpack_r3: ocr=%08x\n", r3->ocr);
1292
1293    if (buf[0] != 0x3f) return MMC_ERROR_HEADER_MISMATCH;
1294    return 0;
1295}
1296
1297#define KBPS 1
1298#define MBPS 1000
1299
1300static u32 ts_exp[] = { 100*KBPS, 1*MBPS, 10*MBPS, 100*MBPS, 0, 0, 0, 0 };
1301static u32 ts_mul[] = { 0, 1000, 1200, 1300, 1500, 2000, 2500, 3000,
1302            3500, 4000, 4500, 5000, 5500, 6000, 7000, 8000 };
1303
1304u32 mmc_tran_speed(u8 ts)
1305{
1306    u32 rate = ts_exp[(ts & 0x7)] * ts_mul[(ts & 0x78) >> 3];
1307
1308    if (rate <= 0) {
1309        debug("%s: error - unrecognized speed 0x%02x\n", __func__, ts);
1310        return 1;
1311    }
1312
1313    return rate;
1314}
1315
1316void mmc_send_cmd(struct mmc_request *request, int cmd, u32 arg,
1317           u16 nob, u16 block_len, enum mmc_rsp_t rtype, u8 *buffer)
1318{
1319    request->cmd = cmd;
1320    request->arg = arg;
1321    request->rtype = rtype;
1322    request->nob = nob;
1323    request->block_len = block_len;
1324    request->buffer = buffer;
1325    request->cnt = nob * block_len;
1326
1327    jz_mmc_exec_cmd(request);
1328}
1329
1330#endif /* CONFIG_MMC */
package/uboot-xburst/files/drivers/mmc/jz_mmc.h
1/*
2 * linux/drivers/mmc/jz_mmc.h
3 *
4 * Author: Vladimir Shebordaev, Igor Oblakov
5 * Copyright: MontaVista Software Inc.
6 *
7 * $Id: jz_mmc.h,v 1.3 2007-06-15 08:04:20 jlwei Exp $
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13#ifndef __MMC_JZMMC_H__
14#define __MMC_JZMMC_H__
15
16#define MMC_DEBUG_LEVEL 0 /* Enable Debug: 0 - no debug */
17#define ID_TO_RCA(x) ((x)+1)
18#define MMC_OCR_ARG 0x00ff8000 /* Argument of OCR */
19
20/* Standard MMC/SD clock speeds */
21#define MMC_CLOCK_SLOW 400000 /* 400 kHz for initial setup */
22#define MMC_CLOCK_FAST 20000000 /* 20 MHz for maximum for normal operation */
23#define SD_CLOCK_FAST 24000000 /* 24 MHz for SD Cards */
24
25/* Use negative numbers to disambiguate */
26#define MMC_CIM_RESET -1
27#define SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */
28
29#define R1_OUT_OF_RANGE (1 << 31) /* er, c */
30#define R1_ADDRESS_ERROR (1 << 30) /* erx, c */
31#define R1_BLOCK_LEN_ERROR (1 << 29) /* er, c */
32#define R1_ERASE_SEQ_ERROR (1 << 28) /* er, c */
33#define R1_ERASE_PARAM (1 << 27) /* ex, c */
34#define R1_WP_VIOLATION (1 << 26) /* erx, c */
35#define R1_CARD_IS_LOCKED (1 << 25) /* sx, a */
36#define R1_LOCK_UNLOCK_FAILED (1 << 24) /* erx, c */
37#define R1_COM_CRC_ERROR (1 << 23) /* er, b */
38#define R1_ILLEGAL_COMMAND (1 << 22) /* er, b */
39#define R1_CARD_ECC_FAILED (1 << 21) /* ex, c */
40#define R1_CC_ERROR (1 << 20) /* erx, c */
41#define R1_ERROR (1 << 19) /* erx, c */
42#define R1_UNDERRUN (1 << 18) /* ex, c */
43#define R1_OVERRUN (1 << 17) /* ex, c */
44#define R1_CID_CSD_OVERWRITE (1 << 16) /* erx, c, CID/CSD overwrite */
45#define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */
46#define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */
47#define R1_ERASE_RESET (1 << 13) /* sr, c */
48#define R1_STATUS(x) (x & 0xFFFFE000)
49
50#define MMC_CARD_BUSY 0x80000000 /* Card Power up status bit */
51
52#define MMC_PROGRAM_CID 26 /* adtc R1 */
53#define MMC_PROGRAM_CSD 27 /* adtc R1 */
54
55#define MMC_GO_IRQ_STATE 40 /* bcr R5 */
56#define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1b */
57#define MMC_LOCK_UNLOCK 42 /* adtc R1b */
58#define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */
59#define MMC_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */
60#define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */
61
62
63enum mmc_result_t {
64    MMC_NO_RESPONSE = -1,
65    MMC_NO_ERROR = 0,
66    MMC_ERROR_OUT_OF_RANGE,
67    MMC_ERROR_ADDRESS,
68    MMC_ERROR_BLOCK_LEN,
69    MMC_ERROR_ERASE_SEQ,
70    MMC_ERROR_ERASE_PARAM,
71    MMC_ERROR_WP_VIOLATION,
72    MMC_ERROR_CARD_IS_LOCKED,
73    MMC_ERROR_LOCK_UNLOCK_FAILED,
74    MMC_ERROR_COM_CRC,
75    MMC_ERROR_ILLEGAL_COMMAND,
76    MMC_ERROR_CARD_ECC_FAILED,
77    MMC_ERROR_CC,
78    MMC_ERROR_GENERAL,
79    MMC_ERROR_UNDERRUN,
80    MMC_ERROR_OVERRUN,
81    MMC_ERROR_CID_CSD_OVERWRITE,
82    MMC_ERROR_STATE_MISMATCH,
83    MMC_ERROR_HEADER_MISMATCH,
84    MMC_ERROR_TIMEOUT,
85    MMC_ERROR_CRC,
86    MMC_ERROR_DRIVER_FAILURE,
87};
88
89enum card_state {
90    CARD_STATE_EMPTY = -1,
91    CARD_STATE_IDLE = 0,
92    CARD_STATE_READY = 1,
93    CARD_STATE_IDENT = 2,
94    CARD_STATE_STBY = 3,
95    CARD_STATE_TRAN = 4,
96    CARD_STATE_DATA = 5,
97    CARD_STATE_RCV = 6,
98    CARD_STATE_PRG = 7,
99    CARD_STATE_DIS = 8,
100};
101
102enum mmc_rsp_t {
103    RESPONSE_NONE = 0,
104    RESPONSE_R1 = 1,
105    RESPONSE_R1B = 2,
106    RESPONSE_R2_CID = 3,
107    RESPONSE_R2_CSD = 4,
108    RESPONSE_R3 = 5,
109    RESPONSE_R4 = 6,
110    RESPONSE_R5 = 7,
111        RESPONSE_R6 = 8,
112};
113
114struct mmc_response_r1 {
115    u8 cmd;
116    u32 status;
117};
118
119struct mmc_response_r3 {
120    u32 ocr;
121};
122
123/* the information structure of MMC/SD Card */
124struct mmc_info {
125    int id; /* Card index */
126        int sd; /* MMC or SD card */
127        int rca; /* RCA */
128        u32 scr; /* SCR 63:32*/
129    int flags; /* Ejected, inserted */
130    enum card_state state; /* empty, ident, ready, whatever */
131
132    /* Card specific information */
133    struct mmc_cid cid;
134    struct mmc_csd csd;
135    u32 block_num;
136    u32 block_len;
137    u32 erase_unit;
138};
139
140struct mmc_info mmcinfo;
141
142struct mmc_request {
143    int index; /* Slot index - used for CS lines */
144    int cmd; /* Command to send */
145    u32 arg; /* Argument to send */
146    enum mmc_rsp_t rtype; /* Response type expected */
147
148    /* Data transfer (these may be modified at the low level) */
149    u16 nob; /* Number of blocks to transfer*/
150    u16 block_len; /* Block length */
151    u8 *buffer; /* Data buffer */
152    u32 cnt; /* Data length, for PIO */
153
154    /* Results */
155    u8 response[18]; /* Buffer to store response - CRC is optional */
156    enum mmc_result_t result;
157};
158
159char * mmc_result_to_string(int);
160int mmc_unpack_csd(struct mmc_request *request, struct mmc_csd *csd);
161int mmc_unpack_r1(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state);
162int mmc_unpack_r6(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state, int *rca);
163int mmc_unpack_scr(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state, u32 *scr);
164int mmc_unpack_cid(struct mmc_request *request, struct mmc_cid *cid);
165int mmc_unpack_r3(struct mmc_request *request, struct mmc_response_r3 *r3);
166
167void mmc_send_cmd(struct mmc_request *request, int cmd, u32 arg,
168             u16 nob, u16 block_len, enum mmc_rsp_t rtype, u8 *buffer);
169u32 mmc_tran_speed(u8 ts);
170void jz_mmc_set_clock(int sd, u32 rate);
171
172static inline void mmc_simple_cmd(struct mmc_request *request, int cmd, u32 arg, enum mmc_rsp_t rtype)
173{
174    mmc_send_cmd( request, cmd, arg, 0, 0, rtype, 0);
175}
176
177int mmc2info(ulong addr);
178
179#endif /* __MMC_JZMMC_H__ */
package/uboot-xburst/files/drivers/video/nanonote_gpm940b0.c
1/*
2 * JzRISC lcd controller
3 *
4 * xiangfu liu <xiangfu.z@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19 * MA 02111-1307 USA
20 */
21
22#include <config.h>
23#include <common.h>
24#include <lcd.h>
25
26#include <asm/io.h> /* virt_to_phys() */
27
28#include <asm/jz4740.h>
29#include "nanonote_gpm940b0.h"
30
31#define align2(n) (n)=((((n)+1)>>1)<<1)
32#define align4(n) (n)=((((n)+3)>>2)<<2)
33#define align8(n) (n)=((((n)+7)>>3)<<3)
34
35struct jzfb_info {
36    unsigned int cfg; /* panel mode and pin usage etc. */
37    unsigned int w;
38    unsigned int h;
39    unsigned int bpp; /* bit per pixel */
40    unsigned int fclk; /* frame clk */
41    unsigned int hsw; /* hsync width, in pclk */
42    unsigned int vsw; /* vsync width, in line count */
43    unsigned int elw; /* end of line, in pclk */
44    unsigned int blw; /* begin of line, in pclk */
45    unsigned int efw; /* end of frame, in line count */
46    unsigned int bfw; /* begin of frame, in line count */
47};
48
49static struct jzfb_info jzfb = {
50    MODE_8BIT_SERIAL_TFT | PCLK_N | HSYNC_N | VSYNC_N,
51    320, 240, 32, 70, 1, 1, 273, 140, 1, 20
52};
53
54vidinfo_t panel_info = {
55    320, 240, LCD_BPP,
56};
57
58int lcd_line_length;
59
60int lcd_color_fg;
61int lcd_color_bg;
62/*
63 * Frame buffer memory information
64 */
65void *lcd_base; /* Start of framebuffer memory */
66void *lcd_console_address; /* Start of console buffer */
67
68short console_col;
69short console_row;
70
71void lcd_ctrl_init (void *lcdbase);
72void lcd_enable (void);
73void lcd_disable (void);
74
75static int jz_lcd_init_mem(void *lcdbase, vidinfo_t *vid);
76static void jz_lcd_desc_init(vidinfo_t *vid);
77static int jz_lcd_hw_init( vidinfo_t *vid );
78extern int flush_cache_all(void);
79
80void lcd_ctrl_init (void *lcdbase)
81{
82    __lcd_display_pin_init();
83
84    jz_lcd_init_mem(lcdbase, &panel_info);
85    jz_lcd_desc_init(&panel_info);
86    jz_lcd_hw_init(&panel_info);
87
88    __lcd_display_on() ;
89}
90
91/*
92 * Before enabled lcd controller, lcd registers should be configured correctly.
93 */
94
95void lcd_enable (void)
96{
97    REG_LCD_CTRL &= ~(1<<4); /* LCDCTRL.DIS */
98    REG_LCD_CTRL |= 1<<3; /* LCDCTRL.ENA*/
99}
100
101void lcd_disable (void)
102{
103    REG_LCD_CTRL |= (1<<4); /* LCDCTRL.DIS, regular disable */
104    /* REG_LCD_CTRL |= (1<<3); */ /* LCDCTRL.DIS, quikly disable */
105}
106
107static int jz_lcd_init_mem(void *lcdbase, vidinfo_t *vid)
108{
109    u_long palette_mem_size;
110    struct jz_fb_info *fbi = &vid->jz_fb;
111    int fb_size = vid->vl_row * (vid->vl_col * NBITS (vid->vl_bpix)) / 8;
112
113    fbi->screen = (u_long)lcdbase;
114    fbi->palette_size = 256;
115    palette_mem_size = fbi->palette_size * sizeof(u16);
116
117    debug("jz_lcd.c palette_mem_size = 0x%08lx\n", (u_long) palette_mem_size);
118    /* locate palette and descs at end of page following fb */
119    fbi->palette = (u_long)lcdbase + fb_size + PAGE_SIZE - palette_mem_size;
120
121    return 0;
122}
123
124static void jz_lcd_desc_init(vidinfo_t *vid)
125{
126    struct jz_fb_info * fbi;
127    fbi = &vid->jz_fb;
128    fbi->dmadesc_fblow = (struct jz_fb_dma_descriptor *)((unsigned int)fbi->palette - 3*16);
129    fbi->dmadesc_fbhigh = (struct jz_fb_dma_descriptor *)((unsigned int)fbi->palette - 2*16);
130    fbi->dmadesc_palette = (struct jz_fb_dma_descriptor *)((unsigned int)fbi->palette - 1*16);
131
132    #define BYTES_PER_PANEL (vid->vl_col * vid->vl_row * NBITS(vid->vl_bpix) / 8)
133
134    /* populate descriptors */
135    fbi->dmadesc_fblow->fdadr = virt_to_phys(fbi->dmadesc_fblow);
136    fbi->dmadesc_fblow->fsadr = virt_to_phys((void *)(fbi->screen + BYTES_PER_PANEL));
137    fbi->dmadesc_fblow->fidr = 0;
138    fbi->dmadesc_fblow->ldcmd = BYTES_PER_PANEL / 4 ;
139
140    fbi->fdadr1 = virt_to_phys(fbi->dmadesc_fblow); /* only used in dual-panel mode */
141
142    fbi->dmadesc_fbhigh->fsadr = virt_to_phys((void *)fbi->screen);
143    fbi->dmadesc_fbhigh->fidr = 0;
144    fbi->dmadesc_fbhigh->ldcmd = BYTES_PER_PANEL / 4; /* length in word */
145
146    fbi->dmadesc_palette->fsadr = virt_to_phys((void *)fbi->palette);
147    fbi->dmadesc_palette->fidr = 0;
148    fbi->dmadesc_palette->ldcmd = (fbi->palette_size * 2)/4 | (1<<28);
149
150    if(NBITS(vid->vl_bpix) < 12)
151    {
152        /* assume any mode with <12 bpp is palette driven */
153        fbi->dmadesc_palette->fdadr = virt_to_phys(fbi->dmadesc_fbhigh);
154        fbi->dmadesc_fbhigh->fdadr = virt_to_phys(fbi->dmadesc_palette);
155        /* flips back and forth between pal and fbhigh */
156        fbi->fdadr0 = virt_to_phys(fbi->dmadesc_palette);
157    } else {
158        /* palette shouldn't be loaded in true-color mode */
159        fbi->dmadesc_fbhigh->fdadr = virt_to_phys((void *)fbi->dmadesc_fbhigh);
160        fbi->fdadr0 = virt_to_phys(fbi->dmadesc_fbhigh); /* no pal just fbhigh */
161    }
162
163    flush_cache_all();
164}
165
166static int jz_lcd_hw_init(vidinfo_t *vid)
167{
168    struct jz_fb_info *fbi = &vid->jz_fb;
169    unsigned int val = 0;
170    unsigned int pclk;
171    unsigned int stnH;
172    int pll_div;
173
174    /* Setting Control register */
175    switch (jzfb.bpp) {
176    case 1:
177        val |= LCD_CTRL_BPP_1;
178        break;
179    case 2:
180        val |= LCD_CTRL_BPP_2;
181        break;
182    case 4:
183        val |= LCD_CTRL_BPP_4;
184        break;
185    case 8:
186        val |= LCD_CTRL_BPP_8;
187        break;
188    case 15:
189        val |= LCD_CTRL_RGB555;
190    case 16:
191        val |= LCD_CTRL_BPP_16;
192        break;
193    case 17 ... 32:
194        val |= LCD_CTRL_BPP_18_24; /* target is 4bytes/pixel */
195        break;
196
197    default:
198        printf("jz_lcd.c The BPP %d is not supported\n", jzfb.bpp);
199        val |= LCD_CTRL_BPP_16;
200        break;
201    }
202
203    switch (jzfb.cfg & MODE_MASK) {
204    case MODE_STN_MONO_DUAL:
205    case MODE_STN_COLOR_DUAL:
206    case MODE_STN_MONO_SINGLE:
207    case MODE_STN_COLOR_SINGLE:
208        switch (jzfb.bpp) {
209        case 1:
210            /* val |= LCD_CTRL_PEDN; */
211        case 2:
212            val |= LCD_CTRL_FRC_2;
213            break;
214        case 4:
215            val |= LCD_CTRL_FRC_4;
216            break;
217        case 8:
218        default:
219            val |= LCD_CTRL_FRC_16;
220            break;
221        }
222        break;
223    }
224
225    val |= LCD_CTRL_BST_16; /* Burst Length is 16WORD=64Byte */
226    val |= LCD_CTRL_OFUP; /* OutFIFO underrun protect */
227
228    switch (jzfb.cfg & MODE_MASK) {
229    case MODE_STN_MONO_DUAL:
230    case MODE_STN_COLOR_DUAL:
231    case MODE_STN_MONO_SINGLE:
232    case MODE_STN_COLOR_SINGLE:
233        switch (jzfb.cfg & STN_DAT_PINMASK) {
234        case STN_DAT_PIN1:
235            /* Do not adjust the hori-param value. */
236            break;
237        case STN_DAT_PIN2:
238            align2(jzfb.hsw);
239            align2(jzfb.elw);
240            align2(jzfb.blw);
241            break;
242        case STN_DAT_PIN4:
243            align4(jzfb.hsw);
244            align4(jzfb.elw);
245            align4(jzfb.blw);
246            break;
247        case STN_DAT_PIN8:
248            align8(jzfb.hsw);
249            align8(jzfb.elw);
250            align8(jzfb.blw);
251            break;
252        }
253        break;
254    }
255
256    REG_LCD_CTRL = val;
257
258    switch (jzfb.cfg & MODE_MASK) {
259    case MODE_STN_MONO_DUAL:
260    case MODE_STN_COLOR_DUAL:
261    case MODE_STN_MONO_SINGLE:
262    case MODE_STN_COLOR_SINGLE:
263        if (((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL) ||
264            ((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL))
265            stnH = jzfb.h >> 1;
266        else
267            stnH = jzfb.h;
268
269        REG_LCD_VSYNC = (0 << 16) | jzfb.vsw;
270        REG_LCD_HSYNC = ((jzfb.blw+jzfb.w) << 16) | (jzfb.blw+jzfb.w+jzfb.hsw);
271
272        /* Screen setting */
273        REG_LCD_VAT = ((jzfb.blw + jzfb.w + jzfb.hsw + jzfb.elw) << 16) | (stnH + jzfb.vsw + jzfb.bfw + jzfb.efw);
274        REG_LCD_DAH = (jzfb.blw << 16) | (jzfb.blw + jzfb.w);
275        REG_LCD_DAV = (0 << 16) | (stnH);
276
277        /* AC BIAs signal */
278        REG_LCD_PS = (0 << 16) | (stnH+jzfb.vsw+jzfb.efw+jzfb.bfw);
279
280        break;
281
282    case MODE_TFT_GEN:
283    case MODE_TFT_SHARP:
284    case MODE_TFT_CASIO:
285    case MODE_TFT_SAMSUNG:
286    case MODE_8BIT_SERIAL_TFT:
287    case MODE_TFT_18BIT:
288        REG_LCD_VSYNC = (0 << 16) | jzfb.vsw;
289        REG_LCD_HSYNC = (0 << 16) | jzfb.hsw;
290        REG_LCD_DAV =((jzfb.vsw+jzfb.bfw) << 16) | (jzfb.vsw +jzfb.bfw+jzfb.h);
291        REG_LCD_DAH = ((jzfb.hsw + jzfb.blw) << 16) | (jzfb.hsw + jzfb.blw + jzfb.w );
292        REG_LCD_VAT = (((jzfb.blw + jzfb.w + jzfb.elw + jzfb.hsw)) << 16) \
293            | (jzfb.vsw + jzfb.bfw + jzfb.h + jzfb.efw);
294        break;
295    }
296
297    switch (jzfb.cfg & MODE_MASK) {
298    case MODE_TFT_SAMSUNG:
299    {
300        unsigned int total, tp_s, tp_e, ckv_s, ckv_e;
301        unsigned int rev_s, rev_e, inv_s, inv_e;
302
303        pclk = val * (jzfb.w + jzfb.hsw + jzfb.elw + jzfb.blw) *
304            (jzfb.h + jzfb.vsw + jzfb.efw + jzfb.bfw); /* Pixclk */
305
306        total = jzfb.blw + jzfb.w + jzfb.elw + jzfb.hsw;
307        tp_s = jzfb.blw + jzfb.w + 1;
308        tp_e = tp_s + 1;
309        /* ckv_s = tp_s - jz_clocks.pixclk/(1000000000/4100); */
310        ckv_s = tp_s - pclk/(1000000000/4100);
311        ckv_e = tp_s + total;
312        rev_s = tp_s - 11; /* -11.5 clk */
313        rev_e = rev_s + total;
314        inv_s = tp_s;
315        inv_e = inv_s + total;
316        REG_LCD_CLS = (tp_s << 16) | tp_e;
317        REG_LCD_PS = (ckv_s << 16) | ckv_e;
318        REG_LCD_SPL = (rev_s << 16) | rev_e;
319        REG_LCD_REV = (inv_s << 16) | inv_e;
320        jzfb.cfg |= STFT_REVHI | STFT_SPLHI;
321        break;
322    }
323    case MODE_TFT_SHARP:
324    {
325        unsigned int total, cls_s, cls_e, ps_s, ps_e;
326        unsigned int spl_s, spl_e, rev_s, rev_e;
327        total = jzfb.blw + jzfb.w + jzfb.elw + jzfb.hsw;
328        spl_s = 1;
329        spl_e = spl_s + 1;
330        cls_s = 0;
331        cls_e = total - 60; /* > 4us (pclk = 80ns) */
332        ps_s = cls_s;
333        ps_e = cls_e;
334        rev_s = total - 40; /* > 3us (pclk = 80ns) */
335        rev_e = rev_s + total;
336        jzfb.cfg |= STFT_PSHI;
337        REG_LCD_SPL = (spl_s << 16) | spl_e;
338        REG_LCD_CLS = (cls_s << 16) | cls_e;
339        REG_LCD_PS = (ps_s << 16) | ps_e;
340        REG_LCD_REV = (rev_s << 16) | rev_e;
341        break;
342    }
343    case MODE_TFT_CASIO:
344        break;
345    }
346
347    /* Configure the LCD panel */
348    REG_LCD_CFG = jzfb.cfg;
349
350    /* Timing setting */
351    __cpm_stop_lcd();
352
353    val = jzfb.fclk; /* frame clk */
354    if ( (jzfb.cfg & MODE_MASK) != MODE_8BIT_SERIAL_TFT) {
355        pclk = val * (jzfb.w + jzfb.hsw + jzfb.elw + jzfb.blw) *
356            (jzfb.h + jzfb.vsw + jzfb.efw + jzfb.bfw); /* Pixclk */
357    } else {
358        /* serial mode: Hsync period = 3*Width_Pixel */
359        pclk = val * (jzfb.w*3 + jzfb.hsw + jzfb.elw + jzfb.blw) *
360            (jzfb.h + jzfb.vsw + jzfb.efw + jzfb.bfw); /* Pixclk */
361    }
362
363    if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_SINGLE) ||
364        ((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL))
365        pclk = (pclk * 3);
366
367    if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_SINGLE) ||
368        ((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL) ||
369        ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_SINGLE) ||
370        ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL))
371        pclk = pclk >> ((jzfb.cfg & STN_DAT_PINMASK) >> 4);
372
373    if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL) ||
374        ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL))
375        pclk >>= 1;
376
377    pll_div = ( REG_CPM_CPCCR & CPM_CPCCR_PCS ); /* clock source,0:pllout/2 1: pllout */
378    pll_div = pll_div ? 1 : 2 ;
379    val = ( __cpm_get_pllout()/pll_div ) / pclk;
380    val--;
381    if ( val > 0x1ff ) {
382        printf("CPM_LPCDR too large, set it to 0x1ff\n");
383        val = 0x1ff;
384    }
385    __cpm_set_pixdiv(val);
386
387    val = pclk * 3 ; /* LCDClock > 2.5*Pixclock */
388    if ( val > 150000000 ) {
389        printf("Warning: LCDClock=%d\n, LCDClock must less or equal to 150MHz.\n", val);
390        printf("Change LCDClock to 150MHz\n");
391        val = 150000000;
392    }
393    val = ( __cpm_get_pllout()/pll_div ) / val;
394    val--;
395    if ( val > 0x1f ) {
396        printf("CPM_CPCCR.LDIV too large, set it to 0x1f\n");
397        val = 0x1f;
398    }
399    __cpm_set_ldiv( val );
400    REG_CPM_CPCCR |= CPM_CPCCR_CE ; /* update divide */
401
402    __cpm_start_lcd();
403    udelay(1000);
404
405    REG_LCD_DA0 = fbi->fdadr0; /* frame descripter*/
406
407    if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL) ||
408        ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL))
409        REG_LCD_DA1 = fbi->fdadr1; /* frame descripter*/
410
411    return 0;
412}
413
414void lcd_setcolreg (ushort regno, ushort red, ushort green, ushort blue)
415{
416}
417
418void lcd_initcolregs (void)
419{
420}
package/uboot-xburst/files/drivers/video/nanonote_gpm940b0.h
1/*
2 * JzRISC lcd controller
3 *
4 * xiangfu liu <xiangfu.z@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19 * MA 02111-1307 USA
20 */
21
22#ifndef __QI_LB60_GPM940B0_H__
23#define __QI_LB60_GPM940B0_H__
24
25#include <asm/io.h>
26
27struct lcd_desc{
28    unsigned int next_desc; /* LCDDAx */
29    unsigned int databuf; /* LCDSAx */
30    unsigned int frame_id; /* LCDFIDx */
31    unsigned int cmd; /* LCDCMDx */
32};
33
34#define MODE_MASK 0x0f
35#define MODE_TFT_GEN 0x00
36#define MODE_TFT_SHARP 0x01
37#define MODE_TFT_CASIO 0x02
38#define MODE_TFT_SAMSUNG 0x03
39#define MODE_CCIR656_NONINT 0x04
40#define MODE_CCIR656_INT 0x05
41#define MODE_STN_COLOR_SINGLE 0x08
42#define MODE_STN_MONO_SINGLE 0x09
43#define MODE_STN_COLOR_DUAL 0x0a
44#define MODE_STN_MONO_DUAL 0x0b
45#define MODE_8BIT_SERIAL_TFT 0x0c
46
47#define MODE_TFT_18BIT (1<<7)
48
49#define STN_DAT_PIN1 (0x00 << 4)
50#define STN_DAT_PIN2 (0x01 << 4)
51#define STN_DAT_PIN4 (0x02 << 4)
52#define STN_DAT_PIN8 (0x03 << 4)
53#define STN_DAT_PINMASK STN_DAT_PIN8
54
55#define STFT_PSHI (1 << 15)
56#define STFT_CLSHI (1 << 14)
57#define STFT_SPLHI (1 << 13)
58#define STFT_REVHI (1 << 12)
59
60#define SYNC_MASTER (0 << 16)
61#define SYNC_SLAVE (1 << 16)
62
63#define DE_P (0 << 9)
64#define DE_N (1 << 9)
65
66#define PCLK_P (0 << 10)
67#define PCLK_N (1 << 10)
68
69#define HSYNC_P (0 << 11)
70#define HSYNC_N (1 << 11)
71
72#define VSYNC_P (0 << 8)
73#define VSYNC_N (1 << 8)
74
75#define DATA_NORMAL (0 << 17)
76#define DATA_INVERSE (1 << 17)
77
78
79/* Jz LCDFB supported I/O controls. */
80#define FBIOSETBACKLIGHT 0x4688
81#define FBIODISPON 0x4689
82#define FBIODISPOFF 0x468a
83#define FBIORESET 0x468b
84#define FBIOPRINT_REG 0x468c
85
86/*
87 * LCD panel specific definition
88 */
89#define MODE 0xc9 /* 8bit serial RGB */
90#define SPEN (32*2+21) /*LCD_SPL */
91#define SPCK (32*2+23) /*LCD_CLS */
92#define SPDA (32*2+22) /*LCD_D12 */
93#define LCD_RET (32*3+27)
94
95#define __spi_write_reg1(reg, val) \
96do { \
97    unsigned char no;\
98    unsigned short value;\
99    unsigned char a=0;\
100    unsigned char b=0;\
101    a=reg;\
102    b=val;\
103    __gpio_set_pin(SPEN);\
104    __gpio_set_pin(SPCK);\
105    __gpio_clear_pin(SPDA);\
106    __gpio_clear_pin(SPEN);\
107    udelay(25);\
108    value=((a<<8)|(b&0xFF));\
109    for(no=0;no<16;no++)\
110    {\
111        __gpio_clear_pin(SPCK);\
112        if((value&0x8000)==0x8000)\
113        __gpio_set_pin(SPDA);\
114        else\
115        __gpio_clear_pin(SPDA);\
116        udelay(25);\
117        __gpio_set_pin(SPCK);\
118        value=(value<<1); \
119        udelay(25);\
120     }\
121    __gpio_set_pin(SPEN);\
122    udelay(100);\
123} while (0)
124
125#define __spi_write_reg(reg, val) \
126do {\
127    __spi_write_reg1((reg<<2|2), val);\
128    udelay(100); \
129}while(0)
130
131#define __lcd_special_pin_init() \
132do { \
133    __gpio_as_output(SPEN); /* use SPDA */\
134    __gpio_as_output(SPCK); /* use SPCK */\
135    __gpio_as_output(SPDA); /* use SPDA */\
136    __gpio_as_output(LCD_RET);\
137} while (0)
138
139#define __lcd_special_on() \
140do { \
141    __spi_write_reg1(0x05, 0x1e); \
142    udelay(50);\
143    __spi_write_reg1(0x05, 0x5d); \
144    __spi_write_reg1(0x0B, 0x81); \
145    __spi_write_reg1(0x01, 0x95); \
146    __spi_write_reg1(0x00, 0x07); \
147    __spi_write_reg1(0x06, 0x15); \
148    __spi_write_reg1(0x07, 0x8d); \
149    __spi_write_reg1(0x04, 0x0f); \
150    __spi_write_reg1(0x0d, 0x3d); \
151    __spi_write_reg1(0x10, 0x42); \
152    __spi_write_reg1(0x11, 0x3a); \
153    __spi_write_reg1(0x05, 0x5f); \
154} while (0)
155
156#define __lcd_special_off() \
157do { \
158    __spi_write_reg1(0x05, 0x5e); \
159} while (0)
160
161#define __lcd_set_backlight_level(n)\
162do { \
163    __gpio_as_output(LCD_RET); \
164    __gpio_set_pin(LCD_RET); \
165} while (0)
166
167#if defined(CONFIG_SAKC)
168#define __lcd_close_backlight() \
169do { \
170    __gpio_as_output(GPIO_PWM); \
171    __gpio_clear_pin(GPIO_PWM); \
172} while (0)
173#endif
174
175#if defined(CONFIG_SAKC)
176#define __lcd_display_pin_init() \
177do { \
178    __cpm_start_tcu(); \
179    __lcd_special_pin_init(); \
180} while (0)
181
182#define __lcd_display_on() \
183do { \
184    __lcd_special_on(); \
185} while (0)
186
187#define __lcd_display_off() \
188do { \
189    __lcd_special_off(); \
190} while (0)
191#else
192#define __lcd_display_pin_init() \
193do { \
194    __cpm_start_tcu(); \
195    __lcd_special_pin_init(); \
196} while (0)
197
198#define __lcd_display_on() \
199do { \
200    __gpio_set_pin(GPIO_DISP_OFF_N); \
201    __lcd_special_on(); \
202} while (0)
203
204#define __lcd_display_off() \
205do { \
206    __lcd_special_off(); \
207    __gpio_clear_pin(GPIO_DISP_OFF_N); \
208} while (0)
209#endif
210
211#endif /* __QI_LB60_GPM940B0_H__ */
package/uboot-xburst/files/include/configs/nanonote.h
1717#define CONFIG_JzRISC 1 /* JzRISC core */
1818#define CONFIG_JZSOC 1 /* Jz SoC */
1919#define CONFIG_JZ4740 1 /* Jz4740 SoC */
20#define CONFIG_NANONOTE 1
2120#define CONFIG_NAND_JZ4740
21#define CONFIG_JZ4740_MMC
22#define CONFIG_NANONOTE
2223
2324#define BOOT_FROM_SDCARD 1
2425#define BOOT_WITH_ENABLE_UART (1 << 1) /* Vaule for global_data.h gd->boot_option */
2526
2627#define CONFIG_LCD 1 /* LCD support */
2728#define LCD_BPP LCD_COLOR32 /*5:18,24,32 bits per pixel */
28#define CONFIG_SYS_WHITE_ON_BLACK 1
29#define CONFIG_SYS_WHITE_ON_BLACK
30#define CONFIG_VIDEO_GPM940B0
2931
3032#define CONFIG_SYS_CPU_SPEED 336000000 /* CPU clock: 336 MHz */
3133#define CONFIG_SYS_EXTAL 12000000 /* EXTAL freq: 12 MHz */
package/uboot-xburst/patches/001-xburst.patch
219219
220220     debug ("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>");
221221
222diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
223index 6fa04b8..b08a800 100644
224--- a/drivers/mmc/Makefile
225@@ -32,6 +32,7 @@ COBJS-$(CONFIG_OMAP3_MMC) += omap3_mmc.o
226 COBJS-$(CONFIG_FSL_ESDHC) += fsl_esdhc.o
227 COBJS-$(CONFIG_MXC_MMC) += mxcmmc.o
228 COBJS-$(CONFIG_PXA_MMC) += pxa_mmc.o
229+COBJS-$(CONFIG_JZ4740_MMC) += jz_mmc.o
230
231 COBJS := $(COBJS-y)
232 SRCS := $(COBJS:.o=.c)
222233diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
223234index 28f27da..427d963 100644
224235--- a/drivers/mtd/nand/Makefile
...... 
231243 endif
232244
233245 COBJS := $(COBJS-y)
246diff --git a/drivers/video/Makefile b/drivers/video/Makefile
247index 7d84fc7..39f981d 100644
248--- a/drivers/video/Makefile
249@@ -38,6 +38,7 @@ COBJS-$(CONFIG_SED156X) += sed156x.o
250 COBJS-$(CONFIG_VIDEO_SM501) += sm501.o
251 COBJS-$(CONFIG_VIDEO_SMI_LYNXEM) += smiLynxEM.o videomodes.o
252 COBJS-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o
253+COBJS-$(CONFIG_VIDEO_GPM940B0) += nanonote_gpm940b0.o
254
255 COBJS := $(COBJS-y)
256 SRCS := $(COBJS:.o=.c)
234257diff --git a/examples/standalone/mips.lds b/examples/standalone/mips.lds
235258index 717b201..d4a45f8 100644
236259--- a/examples/standalone/mips.lds

Archive Download the corresponding diff file



interactive