summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/export/pl180.h65
-rw-r--r--firmware/target/arm/as3525/ata_sd_as3525.c40
-rw-r--r--firmware/target/arm/as3525/mmci.h123
3 files changed, 85 insertions, 143 deletions
diff --git a/firmware/export/pl180.h b/firmware/export/pl180.h
new file mode 100644
index 0000000000..98993cc244
--- /dev/null
+++ b/firmware/export/pl180.h
@@ -0,0 +1,65 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright © 2008 Rafaël Carré
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22/* ARM PrimeCell PL180 SD/MMC controller */
23
24/* MCIStatus bits */
25#define MCI_CMD_CRC_FAIL (1<<0)
26#define MCI_DATA_CRC_FAIL (1<<1)
27#define MCI_CMD_TIMEOUT (1<<2)
28#define MCI_DATA_TIMEOUT (1<<3)
29#define MCI_TX_UNDERRUN (1<<4)
30#define MCI_RX_OVERRUN (1<<5)
31#define MCI_CMD_RESP_END (1<<6)
32#define MCI_CMD_SENT (1<<7)
33#define MCI_DATA_END (1<<8)
34#define MCI_START_BIT_ERR (1<<9)
35#define MCI_DATA_BLOCK_END (1<<10)
36#define MCI_CMD_ACTIVE (1<<11)
37
38
39/* MCIPower bits */
40#define MCI_POWER_OFF 0x0
41/* 0x1 is reserved */
42#define MCI_POWER_UP 0x2
43#define MCI_POWER_ON 0x3
44
45/* bits 5:2 are the voltage */
46
47#define MCI_POWER_OPEN_DRAIN (1<<6)
48#define MCI_POWER_ROD (1<<7)
49
50
51/* MCIClock bits */
52/* bits 7:0 are the clock divider */
53#define MCI_CLOCK_ENABLE (1<<8)
54#define MCI_CLOCK_POWERSAVE (1<<9)
55#define MCI_CLOCK_BYPASS (1<<10)
56#define MCI_CLOCK_WIDEBUS (1<<11)
57
58
59/* MCICommand bits */
60/* bits 5:0 are the command index */
61#define MCI_COMMAND_RESPONSE (1<<6)
62#define MCI_COMMAND_LONG_RESPONSE (1<<7)
63#define MCI_COMMAND_INTERRUPT (1<<8)
64#define MCI_COMMAND_PENDING (1<<9)
65#define MCI_COMMAND_ENABLE (1<<10)
diff --git a/firmware/target/arm/as3525/ata_sd_as3525.c b/firmware/target/arm/as3525/ata_sd_as3525.c
index 2b8578ff59..3dea237a5d 100644
--- a/firmware/target/arm/as3525/ata_sd_as3525.c
+++ b/firmware/target/arm/as3525/ata_sd_as3525.c
@@ -24,7 +24,7 @@
24#include "config.h" /* for HAVE_MULTIVOLUME */ 24#include "config.h" /* for HAVE_MULTIVOLUME */
25 25
26#include "as3525.h" 26#include "as3525.h"
27#include "mmci.h" 27#include "pl180.h"
28#include "panic.h" 28#include "panic.h"
29#include "stdbool.h" 29#include "stdbool.h"
30#include "ata.h" 30#include "ata.h"
@@ -87,7 +87,7 @@ static void mci_set_clock_divider(const int drive, int divider)
87 if(divider > 1) 87 if(divider > 1)
88 { 88 {
89 /* use divide logic */ 89 /* use divide logic */
90 clock &= ~MCI_CLK_BYPASS; 90 clock &= ~MCI_CLOCK_BYPASS;
91 91
92 /* convert divider to MMC_CLOCK logic */ 92 /* convert divider to MMC_CLOCK logic */
93 divider = (divider/2) - 1; 93 divider = (divider/2) - 1;
@@ -97,7 +97,7 @@ static void mci_set_clock_divider(const int drive, int divider)
97 else 97 else
98 { 98 {
99 /* bypass dividing logic */ 99 /* bypass dividing logic */
100 clock |= MCI_CLK_BYPASS; 100 clock |= MCI_CLOCK_BYPASS;
101 divider = 0; 101 divider = 0;
102 } 102 }
103 103
@@ -110,20 +110,20 @@ static int send_cmd(const int drive, struct mmc_command *cmd)
110{ 110{
111 int val, status; 111 int val, status;
112 112
113 while(MMC_STATUS(drive) & MCI_CMDACTIVE); /* useless */ 113 while(MMC_STATUS(drive) & MCI_CMD_ACTIVE); /* useless */
114 114
115 if(MMC_COMMAND(drive) & MCI_CPSM_ENABLE) /* clears existing command */ 115 if(MMC_COMMAND(drive) & MCI_COMMAND_ENABLE) /* clears existing command */
116 { 116 {
117 MMC_COMMAND(drive) = 0; 117 MMC_COMMAND(drive) = 0;
118 mci_delay(); 118 mci_delay();
119 } 119 }
120 120
121 val = cmd->cmd | MCI_CPSM_ENABLE; 121 val = cmd->cmd | MCI_COMMAND_ENABLE;
122 if(cmd->flags & MMC_RESP) 122 if(cmd->flags & MMC_RESP)
123 { 123 {
124 val |= MCI_CPSM_RESPONSE; 124 val |= MCI_COMMAND_RESPONSE;
125 if(cmd->flags & MMC_LONG_RESP) 125 if(cmd->flags & MMC_LONG_RESP)
126 val |= MCI_CPSM_LONGRSP; 126 val |= MCI_COMMAND_LONG_RESPONSE;
127 } 127 }
128 128
129 MMC_CLEAR(drive) = 0x7ff; 129 MMC_CLEAR(drive) = 0x7ff;
@@ -131,7 +131,7 @@ static int send_cmd(const int drive, struct mmc_command *cmd)
131 MMC_ARGUMENT(drive) = (cmd->flags & MMC_ARG) ? cmd->arg : 0; 131 MMC_ARGUMENT(drive) = (cmd->flags & MMC_ARG) ? cmd->arg : 0;
132 MMC_COMMAND(drive) = val; 132 MMC_COMMAND(drive) = val;
133 133
134 while(MMC_STATUS(drive) & MCI_CMDACTIVE); 134 while(MMC_STATUS(drive) & MCI_CMD_ACTIVE);
135 135
136 MMC_COMMAND(drive) = 0; 136 MMC_COMMAND(drive) = 0;
137 MMC_ARGUMENT(drive) = ~0; 137 MMC_ARGUMENT(drive) = ~0;
@@ -141,13 +141,13 @@ static int send_cmd(const int drive, struct mmc_command *cmd)
141 status = MMC_STATUS(drive); 141 status = MMC_STATUS(drive);
142 if(cmd->flags & MMC_RESP) 142 if(cmd->flags & MMC_RESP)
143 { 143 {
144 if(status & MCI_CMDTIMEOUT) 144 if(status & MCI_CMD_TIMEOUT)
145 { 145 {
146 if(cmd->cmd == SEND_IF_COND) 146 if(cmd->cmd == SEND_IF_COND)
147 break; /* SDHC test can fail */ 147 break; /* SDHC test can fail */
148 panicf("Response timeout"); 148 panicf("Response timeout");
149 } 149 }
150 else if(status & (MCI_CMDCRCFAIL|MCI_CMDRESPEND)) 150 else if(status & (MCI_CMD_CRC_FAIL|MCI_CMD_RESP_END))
151 { /* resp received */ 151 { /* resp received */
152 cmd->resp[0] = MMC_RESP0(drive); 152 cmd->resp[0] = MMC_RESP0(drive);
153 if(cmd->flags & MMC_LONG_RESP) 153 if(cmd->flags & MMC_LONG_RESP)
@@ -160,7 +160,7 @@ static int send_cmd(const int drive, struct mmc_command *cmd)
160 } 160 }
161 } 161 }
162 else 162 else
163 if(status & MCI_CMDSENT) 163 if(status & MCI_CMD_SENT)
164 break; 164 break;
165 165
166 } while(1); 166 } while(1);
@@ -183,7 +183,7 @@ static void sd_init_card(const int drive)
183 cmd_idle.cmd = GO_IDLE_STATE; 183 cmd_idle.cmd = GO_IDLE_STATE;
184 cmd_idle.arg = 0; 184 cmd_idle.arg = 0;
185 cmd_idle.flags = MMC_NO_FLAGS; 185 cmd_idle.flags = MMC_NO_FLAGS;
186 if(send_cmd(drive, &cmd_idle) != MCI_CMDSENT) 186 if(send_cmd(drive, &cmd_idle) != MCI_CMD_SENT)
187 panicf("goto idle failed!"); 187 panicf("goto idle failed!");
188#ifdef DEBUG 188#ifdef DEBUG
189 else 189 else
@@ -209,7 +209,7 @@ static void sd_init_card(const int drive)
209 209
210 sdhc = false; 210 sdhc = false;
211 status = send_cmd(drive, &cmd_if_cond); 211 status = send_cmd(drive, &cmd_if_cond);
212 if(status & (MCI_CMDCRCFAIL|MCI_CMDRESPEND)) 212 if(status & (MCI_CMD_CRC_FAIL|MCI_CMD_RESP_END))
213 { 213 {
214 if((cmd_if_cond.resp[0] & 0xFFF) == cmd_if_cond.arg) 214 if((cmd_if_cond.resp[0] & 0xFFF) == cmd_if_cond.arg)
215 sdhc = true; 215 sdhc = true;
@@ -240,7 +240,7 @@ static void sd_init_card(const int drive)
240#endif 240#endif
241 /* app_cmd */ 241 /* app_cmd */
242 status = send_cmd(drive, &cmd_app); 242 status = send_cmd(drive, &cmd_app);
243 if( !(status & (MCI_CMDCRCFAIL|MCI_CMDRESPEND)) || 243 if( !(status & (MCI_CMD_CRC_FAIL|MCI_CMD_RESP_END)) ||
244 !(cmd_app.resp[0] & (1<<5)) ) 244 !(cmd_app.resp[0] & (1<<5)) )
245 { 245 {
246 panicf("app_cmd failed"); 246 panicf("app_cmd failed");
@@ -248,7 +248,7 @@ static void sd_init_card(const int drive)
248 248
249 cmd_op_cond.arg = sdhc ? 0x40FF8000 : (8<<0x14); /* ocr */ 249 cmd_op_cond.arg = sdhc ? 0x40FF8000 : (8<<0x14); /* ocr */
250 status = send_cmd(drive, &cmd_op_cond); 250 status = send_cmd(drive, &cmd_op_cond);
251 if(!(status & (MCI_CMDCRCFAIL|MCI_CMDRESPEND))) 251 if(!(status & (MCI_CMD_CRC_FAIL|MCI_CMD_RESP_END)))
252 panicf("cmd_op_cond failed"); 252 panicf("cmd_op_cond failed");
253 253
254#ifdef DEBUG 254#ifdef DEBUG
@@ -268,16 +268,16 @@ static void init_pl180_controller(const int drive)
268 268
269 MMC_MASK0(drive) = MMC_MASK1(drive) = 0; /* disable all interrupts */ 269 MMC_MASK0(drive) = MMC_MASK1(drive) = 0; /* disable all interrupts */
270 270
271 MMC_POWER(drive) = MCI_PWR_UP | (10 /*voltage*/ << 2); /* use OF voltage */ 271 MMC_POWER(drive) = MCI_POWER_UP|(10 /*voltage*/ << 2); /* use OF voltage */
272 mci_delay(); 272 mci_delay();
273 273
274 MMC_POWER(drive) |= MCI_PWR_ON; 274 MMC_POWER(drive) |= MCI_POWER_ON;
275 mci_delay(); 275 mci_delay();
276 276
277 MMC_SELECT(drive) = 0; 277 MMC_SELECT(drive) = 0;
278 278
279 MMC_CLOCK(drive) = MCI_CLK_ENABLE; 279 MMC_CLOCK(drive) = MCI_CLOCK_ENABLE;
280 MMC_CLOCK(drive) &= ~MCI_CLK_PWRSAVE; 280 MMC_CLOCK(drive) &= ~MCI_CLOCK_POWERSAVE;
281 281
282 /* set MCLK divider */ 282 /* set MCLK divider */
283 mci_set_clock_divider(drive, 200); 283 mci_set_clock_divider(drive, 200);
diff --git a/firmware/target/arm/as3525/mmci.h b/firmware/target/arm/as3525/mmci.h
deleted file mode 100644
index 284eee0c75..0000000000
--- a/firmware/target/arm/as3525/mmci.h
+++ /dev/null
@@ -1,123 +0,0 @@
1/*
2 * linux/drivers/mmc/host/mmci.h - ARM PrimeCell MMCI PL180/1 driver
3 *
4 * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10//#define MMCIPOWER 0x000
11#define MCI_PWR_OFF 0x00
12#define MCI_PWR_UP 0x02
13#define MCI_PWR_ON 0x03
14#define MCI_OD (1 << 6)
15#define MCI_ROD (1 << 7)
16
17//#define MMCICLOCK 0x004
18#define MCI_CLK_ENABLE (1 << 8)
19#define MCI_CLK_PWRSAVE (1 << 9)
20#define MCI_CLK_BYPASS (1 << 10)
21#define MCI_WIDEBUS (1 << 11)
22
23//#define MMCIARGUMENT 0x008
24//#define MMCICOMMAND 0x00c
25#define MCI_CPSM_RESPONSE (1 << 6)
26#define MCI_CPSM_LONGRSP (1 << 7)
27#define MCI_CPSM_INTERRUPT (1 << 8)
28#define MCI_CPSM_PENDING (1 << 9)
29#define MCI_CPSM_ENABLE (1 << 10)
30
31#if 0
32#define MMCIRESPCMD 0x010
33#define MMCIRESPONSE0 0x014
34#define MMCIRESPONSE1 0x018
35#define MMCIRESPONSE2 0x01c
36#define MMCIRESPONSE3 0x020
37#define MMCIDATATIMER 0x024
38#define MMCIDATALENGTH 0x028
39#define MMCIDATACTRL 0x02c
40#endif
41#define MCI_DPSM_ENABLE (1 << 0)
42#define MCI_DPSM_DIRECTION (1 << 1)
43#define MCI_DPSM_MODE (1 << 2)
44#define MCI_DPSM_DMAENABLE (1 << 3)
45
46//#define MMCIDATACNT 0x030
47//#define MMCISTATUS 0x034
48#define MCI_CMDCRCFAIL (1 << 0)
49#define MCI_DATACRCFAIL (1 << 1)
50#define MCI_CMDTIMEOUT (1 << 2)
51#define MCI_DATATIMEOUT (1 << 3)
52#define MCI_TXUNDERRUN (1 << 4)
53#define MCI_RXOVERRUN (1 << 5)
54#define MCI_CMDRESPEND (1 << 6)
55#define MCI_CMDSENT (1 << 7)
56#define MCI_DATAEND (1 << 8)
57#define MCI_DATABLOCKEND (1 << 10)
58#define MCI_CMDACTIVE (1 << 11)
59#define MCI_TXACTIVE (1 << 12)
60#define MCI_RXACTIVE (1 << 13)
61#define MCI_TXFIFOHALFEMPTY (1 << 14)
62#define MCI_RXFIFOHALFFULL (1 << 15)
63#define MCI_TXFIFOFULL (1 << 16)
64#define MCI_RXFIFOFULL (1 << 17)
65#define MCI_TXFIFOEMPTY (1 << 18)
66#define MCI_RXFIFOEMPTY (1 << 19)
67#define MCI_TXDATAAVLBL (1 << 20)
68#define MCI_RXDATAAVLBL (1 << 21)
69
70//#define MMCICLEAR 0x038
71#define MCI_CMDCRCFAILCLR (1 << 0)
72#define MCI_DATACRCFAILCLR (1 << 1)
73#define MCI_CMDTIMEOUTCLR (1 << 2)
74#define MCI_DATATIMEOUTCLR (1 << 3)
75#define MCI_TXUNDERRUNCLR (1 << 4)
76#define MCI_RXOVERRUNCLR (1 << 5)
77#define MCI_CMDRESPENDCLR (1 << 6)
78#define MCI_CMDSENTCLR (1 << 7)
79#define MCI_DATAENDCLR (1 << 8)
80#define MCI_DATABLOCKENDCLR (1 << 10)
81
82//#define MMCIMASK0 0x03c
83#define MCI_CMDCRCFAILMASK (1 << 0)
84#define MCI_DATACRCFAILMASK (1 << 1)
85#define MCI_CMDTIMEOUTMASK (1 << 2)
86#define MCI_DATATIMEOUTMASK (1 << 3)
87#define MCI_TXUNDERRUNMASK (1 << 4)
88#define MCI_RXOVERRUNMASK (1 << 5)
89#define MCI_CMDRESPENDMASK (1 << 6)
90#define MCI_CMDSENTMASK (1 << 7)
91#define MCI_DATAENDMASK (1 << 8)
92#define MCI_DATABLOCKENDMASK (1 << 10)
93#define MCI_CMDACTIVEMASK (1 << 11)
94#define MCI_TXACTIVEMASK (1 << 12)
95#define MCI_RXACTIVEMASK (1 << 13)
96#define MCI_TXFIFOHALFEMPTYMASK (1 << 14)
97#define MCI_RXFIFOHALFFULLMASK (1 << 15)
98#define MCI_TXFIFOFULLMASK (1 << 16)
99#define MCI_RXFIFOFULLMASK (1 << 17)
100#define MCI_TXFIFOEMPTYMASK (1 << 18)
101#define MCI_RXFIFOEMPTYMASK (1 << 19)
102#define MCI_TXDATAAVLBLMASK (1 << 20)
103#define MCI_RXDATAAVLBLMASK (1 << 21)
104
105#if 0
106#define MMCIMASK1 0x040
107#define MMCIFIFOCNT 0x048
108#define MMCIFIFO 0x080 /* to 0x0bc */
109#endif
110
111#define MCI_IRQENABLE \
112 (MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK| \
113 MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \
114 MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATABLOCKENDMASK)
115
116/*
117 * The size of the FIFO in bytes.
118 */
119#define MCI_FIFOSIZE (16*4)
120
121#define MCI_FIFOHALFSIZE (MCI_FIFOSIZE / 2)
122
123#define NR_SG 16