dc0391fabb490069589211ce603d8cd7394c4b20
[profile/mobile/platform/kernel/u-boot-tm1.git] / drivers / mmc / mv_sdhci.c
1 #include <common.h>
2 #include <malloc.h>
3 #include <sdhci.h>
4 #include <asm/io.h>
5 #include <asm/arch/regs_global.h>
6
7 #define MAX_DUMP_NUM 14
8 #define DRIVER_NAME "sdhci"
9 #define KERN_DEBUG " "
10
11 void sdhci_dumpregs(struct sdhci_host *host)
12 {
13         int i = 0;
14         printf(KERN_DEBUG DRIVER_NAME ": ============== REGISTER DUMP ==============\n");
15         printf(KERN_DEBUG DRIVER_NAME ":AHB CTRL 0x%08x\n", *((unsigned int*)0x20900200));
16 #if 1
17         for(i = 0; i < MAX_DUMP_NUM; i++){
18                 printf(KERN_DEBUG DRIVER_NAME ": address 0x%08x | value 0x%08x\n", host->ioaddr + i*4, sdhci_readl(host, i*4));
19         }
20 #endif
21
22         printf(KERN_DEBUG DRIVER_NAME ": Sys addr: 0x%08x | Version:  0x%08x\n",
23                         sdhci_readl(host, SDHCI_DMA_ADDRESS),
24                         sdhci_readw(host, SDHCI_HOST_VERSION));
25         printf(KERN_DEBUG DRIVER_NAME ": Blk size: 0x%08x | Blk cnt:  0x%08x\n",
26                         sdhci_readw(host, SDHCI_BLOCK_SIZE),
27                         sdhci_readw(host, SDHCI_BLOCK_COUNT));
28         printf(KERN_DEBUG DRIVER_NAME ": Argument: 0x%08x | Trn mode: 0x%08x\n",
29                         sdhci_readl(host, SDHCI_ARGUMENT),
30                         sdhci_readw(host, SDHCI_TRANSFER_MODE));
31         printf(KERN_DEBUG DRIVER_NAME ": Present:  0x%08x | Host ctl: 0x%08x\n",
32                         sdhci_readl(host, SDHCI_PRESENT_STATE),
33                         sdhci_readb(host, SDHCI_HOST_CONTROL));
34         printf(KERN_DEBUG DRIVER_NAME ": Power:    0x%08x | Blk gap:  0x%08x\n",
35                         sdhci_readb(host, SDHCI_POWER_CONTROL),
36                         sdhci_readb(host, SDHCI_BLOCK_GAP_CONTROL));
37         printf(KERN_DEBUG DRIVER_NAME ": Wake-up:  0x%08x | Clock:    0x%08x\n",
38                         sdhci_readb(host, SDHCI_WAKE_UP_CONTROL),
39                         sdhci_readw(host, SDHCI_CLOCK_CONTROL));
40         printf(KERN_DEBUG DRIVER_NAME ": Timeout:  0x%08x | Int stat: 0x%08x\n",
41                         sdhci_readb(host, SDHCI_TIMEOUT_CONTROL),
42                         sdhci_readl(host, SDHCI_INT_STATUS));
43         printf(KERN_DEBUG DRIVER_NAME ": Int enab: 0x%08x | Sig enab: 0x%08x\n",
44                         sdhci_readl(host, SDHCI_INT_ENABLE),
45                         sdhci_readl(host, SDHCI_SIGNAL_ENABLE));
46         printf(KERN_DEBUG DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n",
47                         sdhci_readw(host, SDHCI_ACMD12_ERR),
48                         sdhci_readw(host, SDHCI_SLOT_INT_STATUS));
49         printf(KERN_DEBUG DRIVER_NAME ": Caps:     0x%08x | Max curr: 0x%08x\n",
50                         sdhci_readl(host, SDHCI_CAPABILITIES),
51                         sdhci_readl(host, SDHCI_MAX_CURRENT));
52
53                 printf(KERN_DEBUG DRIVER_NAME ": ADMA Err: 0x%08x | ADMA Ptr: 0x%08x\n",
54                                 readl(host->ioaddr + SDHCI_ADMA_ERROR),
55                                 readl(host->ioaddr + SDHCI_ADMA_ADDRESS));
56         printf(KERN_DEBUG DRIVER_NAME ": ===========================================\n");
57 }
58
59 #define SDIO_MAX_CLK  SDIO_BASE_CLK_96M  //40Mhz
60
61 #define __raw_bits_and(v, a) writel((readl(a)&v), a)
62 #define __raw_bits_or(v, a) writel((readl(a)|v), a)
63 static void sdhci_sprd_set_base_clock(unsigned int clock)
64 {
65         unsigned long flags;
66
67         /* don't bother if the clock is going off. */
68         if (clock == 0)
69                 return;
70
71         if (clock > SDIO_MAX_CLK)
72                 clock = SDIO_MAX_CLK;
73
74         //Select the clk source of SDIO
75         __raw_bits_and(~(BIT_17|BIT_18), GR_CLK_GEN5);
76
77         if (clock >= SDIO_BASE_CLK_96M) {
78                 //default is 96M
79                 ;
80         } else if (clock >= SDIO_BASE_CLK_64M) {
81                 __raw_bits_or((1<<17), GR_CLK_GEN5);
82         } else if (clock >= SDIO_BASE_CLK_48M) {
83                 __raw_bits_or((2<<17), GR_CLK_GEN5);
84         } else {
85                 __raw_bits_or((3<<17), GR_CLK_GEN5);
86         }
87
88         printf("after set sd clk, CLK_GEN5:%x\r\n",
89                         __raw_readl(GR_CLK_GEN5));
90         return;
91 }
92                                                                                                                                                                                                                                                             
93
94 #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
95 static struct sdhci_ops mv_ops;
96
97 #if defined(CONFIG_SHEEVA_88SV331xV5)
98 #define SD_CE_ATA_2     0xEA
99 #define  MMC_CARD       0x1000
100 #define  MMC_WIDTH      0x0100
101 static inline void mv_sdhci_writeb(struct sdhci_host *host, u8 val, int reg)
102 {
103         struct mmc *mmc = host->mmc;
104         u32 ata = (u32)host->ioaddr + SD_CE_ATA_2;
105
106         if (!IS_SD(mmc) && reg == SDHCI_HOST_CONTROL) {
107                 if (mmc->bus_width == 8)
108                         writew(readw(ata) | (MMC_CARD | MMC_WIDTH), ata);
109                 else
110                         writew(readw(ata) & ~(MMC_CARD | MMC_WIDTH), ata);
111         }
112
113         writeb(val, host->ioaddr + reg);
114 }
115
116 #else
117 #define mv_sdhci_writeb NULL
118 #endif /* CONFIG_SHEEVA_88SV331xV5 */
119 #endif /* CONFIG_MMC_SDHCI_IO_ACCESSORS */
120
121 static char *MVSDH_NAME = "mv_sdh";
122 int mv_sdh_init(u32 regbase, u32 max_clk, u32 min_clk, u32 quirks)
123 {
124         struct sdhci_host *host = NULL;
125         host = (struct sdhci_host *)malloc(sizeof(struct sdhci_host));
126         if (!host) {
127                 printf("sdh_host malloc fail!\n");
128                 return 1;
129         }
130
131         host->name = MVSDH_NAME;
132         host->ioaddr = (void *)regbase;
133         host->quirks = quirks;
134 #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
135         memset(&mv_ops, 0, sizeof(struct sdhci_ops));
136         mv_ops.write_b = mv_sdhci_writeb;
137         host->ops = &mv_ops;
138 #endif
139         if (quirks & SDHCI_QUIRK_REG32_RW)
140                 host->version = sdhci_readl(host, SDHCI_HOST_VERSION - 2) >> 16;
141         else
142                 host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
143 #if !defined(CONFIG_SC8830) && !defined(CONFIG_SC9630)
144         sdhci_sprd_set_base_clock(375000);
145 #endif
146         add_sdhci(host, max_clk, min_clk);
147         return 0;
148 }