diff options
20 files changed, 1249 insertions, 541 deletions
diff --git a/apps/keymaps/keymap-ondavx747.c b/apps/keymaps/keymap-ondavx747.c new file mode 100644 index 0000000000..2e4bb86559 --- /dev/null +++ b/apps/keymaps/keymap-ondavx747.c | |||
@@ -0,0 +1,61 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2009 by Maurus Cuelenaere | ||
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 | /* Button Code Definitions for the Onda VX747 target */ | ||
23 | /* NB: Up/Down/Left/Right are not physical buttons - touchscreen emulation */ | ||
24 | |||
25 | #include <stdio.h> | ||
26 | #include <string.h> | ||
27 | #include <stdlib.h> | ||
28 | |||
29 | #include "config.h" | ||
30 | #include "action.h" | ||
31 | #include "button.h" | ||
32 | #include "settings.h" | ||
33 | |||
34 | /* | ||
35 | * The format of the list is as follows | ||
36 | * { Action Code, Button code, Prereq button code } | ||
37 | * if there's no need to check the previous button's value, use BUTTON_NONE | ||
38 | * Insert LAST_ITEM_IN_LIST at the end of each mapping | ||
39 | */ | ||
40 | |||
41 | /*TODO*/ | ||
42 | static const struct button_mapping button_context_standard[] = { | ||
43 | { ACTION_STD_PREV, BUTTON_VOL_DOWN, BUTTON_NONE }, | ||
44 | { ACTION_STD_PREVREPEAT, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE }, | ||
45 | { ACTION_STD_NEXT, BUTTON_VOL_UP, BUTTON_NONE }, | ||
46 | { ACTION_STD_NEXTREPEAT, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE }, | ||
47 | |||
48 | { ACTION_STD_OK, BUTTON_MENU|BUTTON_REL, BUTTON_MENU }, | ||
49 | { ACTION_STD_CANCEL, BUTTON_POWER, BUTTON_NONE }, | ||
50 | |||
51 | { ACTION_STD_QUICKSCREEN, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE }, | ||
52 | { ACTION_STD_CONTEXT, BUTTON_MENU|BUTTON_REPEAT, BUTTON_NONE }, | ||
53 | |||
54 | LAST_ITEM_IN_LIST | ||
55 | }; /* button_context_standard */ | ||
56 | |||
57 | const struct button_mapping* target_get_context_mapping(int context) | ||
58 | { | ||
59 | (void)context; | ||
60 | return button_context_standard; | ||
61 | } | ||
diff --git a/bootloader/ondavx747.c b/bootloader/ondavx747.c index 354cae42ec..12ab397078 100755 --- a/bootloader/ondavx747.c +++ b/bootloader/ondavx747.c | |||
@@ -101,7 +101,7 @@ static void boot_of(void) | |||
101 | 101 | ||
102 | int main(void) | 102 | int main(void) |
103 | { | 103 | { |
104 | int rc; | 104 | int rc, dummy; |
105 | void (*kernel_entry)(void); | 105 | void (*kernel_entry)(void); |
106 | 106 | ||
107 | kernel_init(); | 107 | kernel_init(); |
@@ -114,7 +114,7 @@ int main(void) | |||
114 | reset_screen(); | 114 | reset_screen(); |
115 | 115 | ||
116 | #ifdef HAVE_TOUCHSCREEN | 116 | #ifdef HAVE_TOUCHSCREEN |
117 | rc = button_read_device(NULL); | 117 | rc = button_read_device(&dummy); |
118 | #else | 118 | #else |
119 | rc = button_read_device(); | 119 | rc = button_read_device(); |
120 | #endif | 120 | #endif |
diff --git a/firmware/common/timefuncs.c b/firmware/common/timefuncs.c index d46b961a8c..53ca5f3c16 100644 --- a/firmware/common/timefuncs.c +++ b/firmware/common/timefuncs.c | |||
@@ -104,10 +104,13 @@ int set_time(const struct tm *tm) | |||
104 | { | 104 | { |
105 | #if CONFIG_RTC | 105 | #if CONFIG_RTC |
106 | int rc; | 106 | int rc; |
107 | #if CONFIG_RTC != RTC_JZ47XX | ||
107 | char rtcbuf[7]; | 108 | char rtcbuf[7]; |
109 | #endif | ||
108 | 110 | ||
109 | if (valid_time(tm)) | 111 | if (valid_time(tm)) |
110 | { | 112 | { |
113 | #if CONFIG_RTC != RTC_JZ47XX | ||
111 | rtcbuf[0]=((tm->tm_sec/10) << 4) | (tm->tm_sec%10); | 114 | rtcbuf[0]=((tm->tm_sec/10) << 4) | (tm->tm_sec%10); |
112 | rtcbuf[1]=((tm->tm_min/10) << 4) | (tm->tm_min%10); | 115 | rtcbuf[1]=((tm->tm_min/10) << 4) | (tm->tm_min%10); |
113 | rtcbuf[2]=((tm->tm_hour/10) << 4) | (tm->tm_hour%10); | 116 | rtcbuf[2]=((tm->tm_hour/10) << 4) | (tm->tm_hour%10); |
@@ -122,6 +125,9 @@ int set_time(const struct tm *tm) | |||
122 | #endif | 125 | #endif |
123 | 126 | ||
124 | rc = rtc_write_datetime(rtcbuf); | 127 | rc = rtc_write_datetime(rtcbuf); |
128 | #else | ||
129 | rc = rtc_write_datetime((unsigned char*)tm); | ||
130 | #endif | ||
125 | 131 | ||
126 | if (rc < 0) | 132 | if (rc < 0) |
127 | return -1; | 133 | return -1; |
diff --git a/firmware/drivers/rtc/rtc_jz4740.c b/firmware/drivers/rtc/rtc_jz4740.c index 77e0860cd2..da39b3faf7 100644 --- a/firmware/drivers/rtc/rtc_jz4740.c +++ b/firmware/drivers/rtc/rtc_jz4740.c | |||
@@ -28,11 +28,7 @@ | |||
28 | #include "jz4740.h" | 28 | #include "jz4740.h" |
29 | #include "rtc.h" | 29 | #include "rtc.h" |
30 | #include "timefuncs.h" | 30 | #include "timefuncs.h" |
31 | 31 | #include "logf.h" | |
32 | static unsigned int epoch = 1900; | ||
33 | static const unsigned char days_in_mo[] = { | ||
34 | 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 | ||
35 | }; | ||
36 | 32 | ||
37 | static const unsigned int yearday[5] = {0, 366, 366+365, 366+365*2, 366+365*3}; | 33 | static const unsigned int yearday[5] = {0, 366, 366+365, 366+365*2, 366+365*3}; |
38 | static const unsigned int sweekday = 6; | 34 | static const unsigned int sweekday = 6; |
@@ -52,8 +48,8 @@ static const unsigned int sum_monthday[13] = { | |||
52 | 365 | 48 | 365 |
53 | }; | 49 | }; |
54 | 50 | ||
55 | #if 0 | 51 | static unsigned int jz_mktime(int year, int mon, int day, int hour, int min, |
56 | static unsigned int jz_mktime(int year, int mon, int day, int hour, int min, int sec) | 52 | int sec) |
57 | { | 53 | { |
58 | unsigned int seccounter; | 54 | unsigned int seccounter; |
59 | 55 | ||
@@ -79,10 +75,9 @@ static unsigned int jz_mktime(int year, int mon, int day, int hour, int min, int | |||
79 | 75 | ||
80 | return seccounter; | 76 | return seccounter; |
81 | } | 77 | } |
82 | #endif | ||
83 | 78 | ||
84 | static void jz_gettime(unsigned int rtc, int *year, int *mon, int *day, int *hour, | 79 | static void jz_gettime(unsigned int rtc, int *year, int *mon, int *day, |
85 | int *min, int *sec, int *weekday) | 80 | int *hour, int *min, int *sec, int *weekday) |
86 | { | 81 | { |
87 | unsigned int tday, tsec, i, tmp; | 82 | unsigned int tday, tsec, i, tmp; |
88 | 83 | ||
@@ -143,9 +138,9 @@ int rtc_read_datetime(unsigned char* buf) | |||
143 | rtc_tm.tm_wday = wday; | 138 | rtc_tm.tm_wday = wday; |
144 | /* Don't use centry, but start from year 1970 */ | 139 | /* Don't use centry, but start from year 1970 */ |
145 | rtc_tm.tm_mon = mon; | 140 | rtc_tm.tm_mon = mon; |
146 | if ((year += (epoch - 1900)) <= 69) | 141 | if (year <= 69) |
147 | year += 100; | 142 | year += 100; |
148 | rtc_tm.tm_year = year + 1900; | 143 | rtc_tm.tm_year = year; |
149 | 144 | ||
150 | rtc_tm.tm_yday = 0; /* Not implemented for now */ | 145 | rtc_tm.tm_yday = 0; /* Not implemented for now */ |
151 | rtc_tm.tm_isdst = -1; /* Not implemented for now */ | 146 | rtc_tm.tm_isdst = -1; /* Not implemented for now */ |
@@ -156,7 +151,20 @@ int rtc_read_datetime(unsigned char* buf) | |||
156 | 151 | ||
157 | int rtc_write_datetime(unsigned char* buf) | 152 | int rtc_write_datetime(unsigned char* buf) |
158 | { | 153 | { |
159 | (void)buf; | 154 | struct tm *rtc_tm = (struct tm*)buf; |
155 | unsigned int year, lval; | ||
156 | |||
157 | year = rtc_tm->tm_year; | ||
158 | /* Don't use centry, but start from year 1970 */ | ||
159 | if (year > 69) | ||
160 | year -= 100; | ||
161 | year += 2000; | ||
162 | |||
163 | lval = jz_mktime(year, rtc_tm->tm_mon, rtc_tm->tm_mday, rtc_tm->tm_hour, | ||
164 | rtc_tm->tm_min, rtc_tm->tm_sec); | ||
165 | REG_RTC_RSR = lval; | ||
166 | |||
167 | return 0; | ||
160 | } | 168 | } |
161 | 169 | ||
162 | #if 0 | 170 | #if 0 |
diff --git a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c index 0b31e8e74d..5d670a8291 100644 --- a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c | |||
@@ -30,16 +30,19 @@ | |||
30 | #include "panic.h" | 30 | #include "panic.h" |
31 | #include "debug.h" | 31 | #include "debug.h" |
32 | #include "storage.h" | 32 | #include "storage.h" |
33 | #include "string.h" | ||
33 | 34 | ||
34 | static struct wakeup sd_wakeup; | 35 | static struct wakeup sd_wakeup; |
36 | static long last_disk_activity = -1; | ||
35 | 37 | ||
36 | //#define MMC_DMA_ENABLE | 38 | //#define MMC_DMA_ENABLE |
37 | #define MMC_DMA_INTERRUPT 0 | 39 | #define MMC_DMA_INTERRUPT 0 |
38 | 40 | ||
39 | #define DEBUG(x...) logf(x); | 41 | #define DEBUG(x...) logf(x) |
40 | 42 | ||
41 | #define MMC_INSERT_STATUS() __gpio_get_pin(MMC_CD_PIN) | 43 | #define BLOCK_SIZE 512 |
42 | 44 | ||
45 | #define MMC_INSERT_STATUS() __gpio_get_pin(MMC_CD_PIN) | ||
43 | #define MMC_RESET() __msc_reset() | 46 | #define MMC_RESET() __msc_reset() |
44 | 47 | ||
45 | #define MMC_IRQ_MASK() \ | 48 | #define MMC_IRQ_MASK() \ |
@@ -81,49 +84,49 @@ enum mmc_result_t | |||
81 | #define MMC_CLOCK_FAST 20000000 /* 20 MHz for maximum for normal operation */ | 84 | #define MMC_CLOCK_FAST 20000000 /* 20 MHz for maximum for normal operation */ |
82 | #define SD_CLOCK_FAST 24000000 /* 24 MHz for SD Cards */ | 85 | #define SD_CLOCK_FAST 24000000 /* 24 MHz for SD Cards */ |
83 | #define SD_CLOCK_HIGH 48000000 /* 48 MHz for SD Cards */ | 86 | #define SD_CLOCK_HIGH 48000000 /* 48 MHz for SD Cards */ |
84 | 87 | ||
85 | /* Extra MMC commands for state control */ | 88 | /* Extra MMC commands for state control */ |
86 | /* Use negative numbers to disambiguate */ | 89 | /* Use negative numbers to disambiguate */ |
87 | #define MMC_CIM_RESET -1 | 90 | #define MMC_CIM_RESET -1 |
88 | 91 | ||
89 | /* Standard MMC commands (3.1) type argument response */ | 92 | /* Standard MMC commands (3.1) type argument response */ |
90 | /* class 1 */ | 93 | /* class 1 */ |
91 | #define MMC_GO_IDLE_STATE 0 /* bc */ | 94 | #define MMC_GO_IDLE_STATE 0 /* bc */ |
92 | #define MMC_SEND_OP_COND 1 /* bcr [31:0] OCR R3 */ | 95 | #define MMC_SEND_OP_COND 1 /* bcr [31:0] OCR R3 */ |
93 | #define MMC_ALL_SEND_CID 2 /* bcr R2 */ | 96 | #define MMC_ALL_SEND_CID 2 /* bcr R2 */ |
94 | #define MMC_SET_RELATIVE_ADDR 3 /* ac [31:16] RCA R1 */ | 97 | #define MMC_SET_RELATIVE_ADDR 3 /* ac [31:16] RCA R1 */ |
95 | #define MMC_SET_DSR 4 /* bc [31:16] RCA */ | 98 | #define MMC_SET_DSR 4 /* bc [31:16] RCA */ |
96 | #define MMC_SELECT_CARD 7 /* ac [31:16] RCA R1 */ | 99 | #define MMC_SELECT_CARD 7 /* ac [31:16] RCA R1 */ |
97 | #define MMC_SEND_CSD 9 /* ac [31:16] RCA R2 */ | 100 | #define MMC_SEND_CSD 9 /* ac [31:16] RCA R2 */ |
98 | #define MMC_SEND_CID 10 /* ac [31:16] RCA R2 */ | 101 | #define MMC_SEND_CID 10 /* ac [31:16] RCA R2 */ |
99 | #define MMC_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */ | 102 | #define MMC_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */ |
100 | #define MMC_STOP_TRANSMISSION 12 /* ac R1b */ | 103 | #define MMC_STOP_TRANSMISSION 12 /* ac R1b */ |
101 | #define MMC_SEND_STATUS 13 /* ac [31:16] RCA R1 */ | 104 | #define MMC_SEND_STATUS 13 /* ac [31:16] RCA R1 */ |
102 | #define MMC_GO_INACTIVE_STATE 15 /* ac [31:16] RCA */ | 105 | #define MMC_GO_INACTIVE_STATE 15 /* ac [31:16] RCA */ |
103 | 106 | ||
104 | /* class 2 */ | 107 | /* class 2 */ |
105 | #define MMC_SET_BLOCKLEN 16 /* ac [31:0] block len R1 */ | 108 | #define MMC_SET_BLOCKLEN 16 /* ac [31:0] block len R1 */ |
106 | #define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */ | 109 | #define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */ |
107 | #define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */ | 110 | #define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */ |
108 | 111 | ||
109 | /* class 3 */ | 112 | /* class 3 */ |
110 | #define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */ | 113 | #define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */ |
111 | 114 | ||
112 | /* class 4 */ | 115 | /* class 4 */ |
113 | #define MMC_SET_BLOCK_COUNT 23 /* adtc [31:0] data addr R1 */ | 116 | #define MMC_SET_BLOCK_COUNT 23 /* adtc [31:0] data addr R1 */ |
114 | #define MMC_WRITE_BLOCK 24 /* adtc [31:0] data addr R1 */ | 117 | #define MMC_WRITE_BLOCK 24 /* adtc [31:0] data addr R1 */ |
115 | #define MMC_WRITE_MULTIPLE_BLOCK 25 /* adtc R1 */ | 118 | #define MMC_WRITE_MULTIPLE_BLOCK 25 /* adtc R1 */ |
116 | #define MMC_PROGRAM_CID 26 /* adtc R1 */ | 119 | #define MMC_PROGRAM_CID 26 /* adtc R1 */ |
117 | #define MMC_PROGRAM_CSD 27 /* adtc R1 */ | 120 | #define MMC_PROGRAM_CSD 27 /* adtc R1 */ |
118 | 121 | ||
119 | /* class 6 */ | 122 | /* class 6 */ |
120 | #define MMC_SET_WRITE_PROT 28 /* ac [31:0] data addr R1b */ | 123 | #define MMC_SET_WRITE_PROT 28 /* ac [31:0] data addr R1b */ |
121 | #define MMC_CLR_WRITE_PROT 29 /* ac [31:0] data addr R1b */ | 124 | #define MMC_CLR_WRITE_PROT 29 /* ac [31:0] data addr R1b */ |
122 | #define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */ | 125 | #define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */ |
123 | 126 | ||
124 | /* class 5 */ | 127 | /* class 5 */ |
125 | #define MMC_ERASE_GROUP_START 35 /* ac [31:0] data addr R1 */ | 128 | #define MMC_ERASE_GROUP_START 35 /* ac [31:0] data addr R1 */ |
126 | #define MMC_ERASE_GROUP_END 36 /* ac [31:0] data addr R1 */ | 129 | #define MMC_ERASE_GROUP_END 36 /* ac [31:0] data addr R1 */ |
127 | #define MMC_ERASE 37 /* ac R1b */ | 130 | #define MMC_ERASE 37 /* ac R1b */ |
128 | 131 | ||
129 | /* class 9 */ | 132 | /* class 9 */ |
@@ -135,12 +138,12 @@ enum mmc_result_t | |||
135 | 138 | ||
136 | /* class 8 */ | 139 | /* class 8 */ |
137 | #define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */ | 140 | #define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */ |
138 | #define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1b */ | 141 | #define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1b */ |
139 | 142 | ||
140 | /* SD class */ | 143 | /* SD class */ |
141 | #define SD_SEND_OP_COND 41 /* bcr [31:0] OCR R3 */ | 144 | #define SD_SEND_OP_COND 41 /* bcr [31:0] OCR R3 */ |
142 | #define SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */ | 145 | #define SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */ |
143 | #define SEND_SCR 51 /* adtc [31:0] staff R1 */ | 146 | #define SEND_SCR 51 /* adtc [31:0] staff R1 */ |
144 | 147 | ||
145 | /* Don't change the order of these; they are used in dispatch tables */ | 148 | /* Don't change the order of these; they are used in dispatch tables */ |
146 | enum mmc_rsp_t | 149 | enum mmc_rsp_t |
@@ -154,6 +157,7 @@ enum mmc_rsp_t | |||
154 | RESPONSE_R4 = 6, | 157 | RESPONSE_R4 = 6, |
155 | RESPONSE_R5 = 7, | 158 | RESPONSE_R5 = 7, |
156 | RESPONSE_R6 = 8, | 159 | RESPONSE_R6 = 8, |
160 | RESPONSE_R7 = 9, | ||
157 | }; | 161 | }; |
158 | 162 | ||
159 | 163 | ||
@@ -196,20 +200,6 @@ enum mmc_rsp_t | |||
196 | #define R1_READY_FOR_DATA (1 << 8) /* sx, a */ | 200 | #define R1_READY_FOR_DATA (1 << 8) /* sx, a */ |
197 | #define R1_APP_CMD (1 << 7) /* sr, c */ | 201 | #define R1_APP_CMD (1 << 7) /* sr, c */ |
198 | 202 | ||
199 | enum card_state | ||
200 | { | ||
201 | CARD_STATE_EMPTY = -1, | ||
202 | CARD_STATE_IDLE = 0, | ||
203 | CARD_STATE_READY = 1, | ||
204 | CARD_STATE_IDENT = 2, | ||
205 | CARD_STATE_STBY = 3, | ||
206 | CARD_STATE_TRAN = 4, | ||
207 | CARD_STATE_DATA = 5, | ||
208 | CARD_STATE_RCV = 6, | ||
209 | CARD_STATE_PRG = 7, | ||
210 | CARD_STATE_DIS = 8, | ||
211 | }; | ||
212 | |||
213 | /* These are unpacked versions of the actual responses */ | 203 | /* These are unpacked versions of the actual responses */ |
214 | struct mmc_response_r1 | 204 | struct mmc_response_r1 |
215 | { | 205 | { |
@@ -276,7 +266,7 @@ struct mmc_csd | |||
276 | struct mmc_response_r3 | 266 | struct mmc_response_r3 |
277 | { | 267 | { |
278 | unsigned int ocr; | 268 | unsigned int ocr; |
279 | }; | 269 | }; |
280 | 270 | ||
281 | #define MMC_VDD_145_150 0x00000001 /* VDD voltage 1.45 - 1.50 */ | 271 | #define MMC_VDD_145_150 0x00000001 /* VDD voltage 1.45 - 1.50 */ |
282 | #define MMC_VDD_150_155 0x00000002 /* VDD voltage 1.50 - 1.55 */ | 272 | #define MMC_VDD_150_155 0x00000002 /* VDD voltage 1.50 - 1.55 */ |
@@ -323,7 +313,6 @@ typedef struct MMC_INFO | |||
323 | int rca; /* RCA */ | 313 | int rca; /* RCA */ |
324 | unsigned int scr; /* SCR 63:32*/ | 314 | unsigned int scr; /* SCR 63:32*/ |
325 | int flags; /* Ejected, inserted */ | 315 | int flags; /* Ejected, inserted */ |
326 | enum card_state state; /* empty, ident, ready, whatever */ | ||
327 | 316 | ||
328 | /* Card specific information */ | 317 | /* Card specific information */ |
329 | struct mmc_cid cid; | 318 | struct mmc_cid cid; |
@@ -333,8 +322,6 @@ typedef struct MMC_INFO | |||
333 | unsigned int erase_unit; | 322 | unsigned int erase_unit; |
334 | } mmc_info; | 323 | } mmc_info; |
335 | 324 | ||
336 | static mmc_info mmcinfo; | ||
337 | |||
338 | struct mmc_request | 325 | struct mmc_request |
339 | { | 326 | { |
340 | int index; /* Slot index - used for CS lines */ | 327 | int index; /* Slot index - used for CS lines */ |
@@ -354,6 +341,7 @@ struct mmc_request | |||
354 | }; | 341 | }; |
355 | 342 | ||
356 | #define MMC_OCR_ARG 0x00ff8000 /* Argument of OCR */ | 343 | #define MMC_OCR_ARG 0x00ff8000 /* Argument of OCR */ |
344 | //#define MMC_OCR_ARG 0x40300000 | ||
357 | 345 | ||
358 | /*********************************************************************** | 346 | /*********************************************************************** |
359 | * MMC Events | 347 | * MMC Events |
@@ -363,16 +351,320 @@ struct mmc_request | |||
363 | #define MMC_EVENT_TX_DATA_DONE 0x02 /* Tx data done */ | 351 | #define MMC_EVENT_TX_DATA_DONE 0x02 /* Tx data done */ |
364 | #define MMC_EVENT_PROG_DONE 0x04 /* Programming is done */ | 352 | #define MMC_EVENT_PROG_DONE 0x04 /* Programming is done */ |
365 | 353 | ||
366 | static int use_4bit; /* Use 4-bit data bus */ | 354 | static int use_4bit = 1; /* Use 4-bit data bus */ |
367 | static int num_6; | 355 | static int num_6 = 0; |
368 | static int sd2_0 = 1; | 356 | static int sd2_0 = 0; |
357 | static mmc_info mmcinfo; | ||
358 | |||
359 | /************************************************************************** | ||
360 | * Utility functions | ||
361 | **************************************************************************/ | ||
362 | |||
363 | #define PARSE_U32(_buf,_index) \ | ||
364 | (((unsigned int)_buf[_index]) << 24) | (((unsigned int)_buf[_index+1]) << 16) | \ | ||
365 | (((unsigned int)_buf[_index+2]) << 8) | ((unsigned int)_buf[_index+3]); | ||
366 | |||
367 | #define PARSE_U16(_buf,_index) \ | ||
368 | (((unsigned short)_buf[_index]) << 8) | ((unsigned short)_buf[_index+1]); | ||
369 | |||
370 | int mmc_unpack_csd(struct mmc_request *request, struct mmc_csd *csd) | ||
371 | { | ||
372 | unsigned char *buf = request->response; | ||
373 | int num = 0; | ||
374 | |||
375 | if (request->result) | ||
376 | return request->result; | ||
377 | |||
378 | csd->csd_structure = (buf[1] & 0xc0) >> 6; | ||
379 | if (csd->csd_structure) | ||
380 | sd2_0 = 1; | ||
381 | else | ||
382 | sd2_0 = 0; | ||
383 | |||
384 | switch (csd->csd_structure) { | ||
385 | case 0 : | ||
386 | csd->taac = buf[2]; | ||
387 | csd->nsac = buf[3]; | ||
388 | csd->tran_speed = buf[4]; | ||
389 | csd->ccc = (((unsigned short)buf[5]) << 4) | ((buf[6] & 0xf0) >> 4); | ||
390 | csd->read_bl_len = buf[6] & 0x0f; | ||
391 | /* for support 2GB card*/ | ||
392 | if (csd->read_bl_len >= 10) | ||
393 | { | ||
394 | num = csd->read_bl_len - 9; | ||
395 | csd->read_bl_len = 9; | ||
396 | } | ||
397 | |||
398 | csd->read_bl_partial = (buf[7] & 0x80) ? 1 : 0; | ||
399 | csd->write_blk_misalign = (buf[7] & 0x40) ? 1 : 0; | ||
400 | csd->read_blk_misalign = (buf[7] & 0x20) ? 1 : 0; | ||
401 | csd->dsr_imp = (buf[7] & 0x10) ? 1 : 0; | ||
402 | csd->c_size = ((((unsigned short)buf[7]) & 0x03) << 10) | (((unsigned short)buf[8]) << 2) | (((unsigned short)buf[9]) & 0xc0) >> 6; | ||
403 | |||
404 | if (num) | ||
405 | csd->c_size = csd->c_size << num; | ||
406 | |||
407 | |||
408 | csd->vdd_r_curr_min = (buf[9] & 0x38) >> 3; | ||
409 | csd->vdd_r_curr_max = buf[9] & 0x07; | ||
410 | csd->vdd_w_curr_min = (buf[10] & 0xe0) >> 5; | ||
411 | csd->vdd_w_curr_max = (buf[10] & 0x1c) >> 2; | ||
412 | csd->c_size_mult = ((buf[10] & 0x03) << 1) | ((buf[11] & 0x80) >> 7); | ||
413 | switch (csd->csd_structure) { | ||
414 | case CSD_STRUCT_VER_1_0: | ||
415 | case CSD_STRUCT_VER_1_1: | ||
416 | csd->erase.v22.sector_size = (buf[11] & 0x7c) >> 2; | ||
417 | csd->erase.v22.erase_grp_size = ((buf[11] & 0x03) << 3) | ((buf[12] & 0xe0) >> 5); | ||
418 | |||
419 | break; | ||
420 | case CSD_STRUCT_VER_1_2: | ||
421 | default: | ||
422 | csd->erase.v31.erase_grp_size = (buf[11] & 0x7c) >> 2; | ||
423 | csd->erase.v31.erase_grp_mult = ((buf[11] & 0x03) << 3) | ((buf[12] & 0xe0) >> 5); | ||
424 | break; | ||
425 | } | ||
426 | csd->wp_grp_size = buf[12] & 0x1f; | ||
427 | csd->wp_grp_enable = (buf[13] & 0x80) ? 1 : 0; | ||
428 | csd->default_ecc = (buf[13] & 0x60) >> 5; | ||
429 | csd->r2w_factor = (buf[13] & 0x1c) >> 2; | ||
430 | csd->write_bl_len = ((buf[13] & 0x03) << 2) | ((buf[14] & 0xc0) >> 6); | ||
431 | if (csd->write_bl_len >= 10) | ||
432 | csd->write_bl_len = 9; | ||
433 | |||
434 | csd->write_bl_partial = (buf[14] & 0x20) ? 1 : 0; | ||
435 | csd->file_format_grp = (buf[15] & 0x80) ? 1 : 0; | ||
436 | csd->copy = (buf[15] & 0x40) ? 1 : 0; | ||
437 | csd->perm_write_protect = (buf[15] & 0x20) ? 1 : 0; | ||
438 | csd->tmp_write_protect = (buf[15] & 0x10) ? 1 : 0; | ||
439 | csd->file_format = (buf[15] & 0x0c) >> 2; | ||
440 | csd->ecc = buf[15] & 0x03; | ||
441 | |||
442 | DEBUG("csd_structure=%d spec_vers=%d taac=%02x nsac=%02x tran_speed=%02x", | ||
443 | csd->csd_structure, csd->spec_vers, | ||
444 | csd->taac, csd->nsac, csd->tran_speed); | ||
445 | DEBUG("ccc=%04x read_bl_len=%d read_bl_partial=%d write_blk_misalign=%d", | ||
446 | csd->ccc, csd->read_bl_len, | ||
447 | csd->read_bl_partial, csd->write_blk_misalign); | ||
448 | DEBUG("read_blk_misalign=%d dsr_imp=%d c_size=%d vdd_r_curr_min=%d", | ||
449 | csd->read_blk_misalign, csd->dsr_imp, | ||
450 | csd->c_size, csd->vdd_r_curr_min); | ||
451 | DEBUG("vdd_r_curr_max=%d vdd_w_curr_min=%d vdd_w_curr_max=%d c_size_mult=%d", | ||
452 | csd->vdd_r_curr_max, csd->vdd_w_curr_min, | ||
453 | csd->vdd_w_curr_max, csd->c_size_mult); | ||
454 | DEBUG("wp_grp_size=%d wp_grp_enable=%d default_ecc=%d r2w_factor=%d", | ||
455 | csd->wp_grp_size, csd->wp_grp_enable, | ||
456 | csd->default_ecc, csd->r2w_factor); | ||
457 | DEBUG("write_bl_len=%d write_bl_partial=%d file_format_grp=%d copy=%d", | ||
458 | csd->write_bl_len, csd->write_bl_partial, | ||
459 | csd->file_format_grp, csd->copy); | ||
460 | DEBUG("perm_write_protect=%d tmp_write_protect=%d file_format=%d ecc=%d", | ||
461 | csd->perm_write_protect, csd->tmp_write_protect, | ||
462 | csd->file_format, csd->ecc); | ||
463 | switch (csd->csd_structure) { | ||
464 | case CSD_STRUCT_VER_1_0: | ||
465 | case CSD_STRUCT_VER_1_1: | ||
466 | DEBUG("V22 sector_size=%d erase_grp_size=%d", | ||
467 | csd->erase.v22.sector_size, | ||
468 | csd->erase.v22.erase_grp_size); | ||
469 | break; | ||
470 | case CSD_STRUCT_VER_1_2: | ||
471 | default: | ||
472 | DEBUG("V31 erase_grp_size=%d erase_grp_mult=%d", | ||
473 | csd->erase.v31.erase_grp_size, | ||
474 | csd->erase.v31.erase_grp_mult); | ||
475 | break; | ||
476 | |||
477 | } | ||
478 | break; | ||
479 | |||
480 | case 1 : | ||
481 | csd->taac = 0; | ||
482 | csd->nsac = 0; | ||
483 | csd->tran_speed = buf[4]; | ||
484 | csd->ccc = (((unsigned short)buf[5]) << 4) | ((buf[6] & 0xf0) >> 4); | ||
485 | |||
486 | csd->read_bl_len = 9; | ||
487 | csd->read_bl_partial = 0; | ||
488 | csd->write_blk_misalign = 0; | ||
489 | csd->read_blk_misalign = 0; | ||
490 | csd->dsr_imp = (buf[7] & 0x10) ? 1 : 0; | ||
491 | csd->c_size = ((((unsigned short)buf[8]) & 0x3f) << 16) | (((unsigned short)buf[9]) << 8) | ((unsigned short)buf[10]) ; | ||
492 | switch (csd->csd_structure) { | ||
493 | case CSD_STRUCT_VER_1_0: | ||
494 | case CSD_STRUCT_VER_1_1: | ||
495 | csd->erase.v22.sector_size = 0x7f; | ||
496 | csd->erase.v22.erase_grp_size = 0; | ||
497 | break; | ||
498 | case CSD_STRUCT_VER_1_2: | ||
499 | default: | ||
500 | csd->erase.v31.erase_grp_size = 0x7f; | ||
501 | csd->erase.v31.erase_grp_mult = 0; | ||
502 | break; | ||
503 | } | ||
504 | csd->wp_grp_size = 0; | ||
505 | csd->wp_grp_enable = 0; | ||
506 | csd->default_ecc = (buf[13] & 0x60) >> 5; | ||
507 | csd->r2w_factor = 4;/* Unused */ | ||
508 | csd->write_bl_len = 9; | ||
509 | |||
510 | csd->write_bl_partial = 0; | ||
511 | csd->file_format_grp = 0; | ||
512 | csd->copy = (buf[15] & 0x40) ? 1 : 0; | ||
513 | csd->perm_write_protect = (buf[15] & 0x20) ? 1 : 0; | ||
514 | csd->tmp_write_protect = (buf[15] & 0x10) ? 1 : 0; | ||
515 | csd->file_format = 0; | ||
516 | csd->ecc = buf[15] & 0x03; | ||
517 | |||
518 | DEBUG("csd_structure=%d spec_vers=%d taac=%02x nsac=%02x tran_speed=%02x", | ||
519 | csd->csd_structure, csd->spec_vers, | ||
520 | csd->taac, csd->nsac, csd->tran_speed); | ||
521 | DEBUG("ccc=%04x read_bl_len=%d read_bl_partial=%d write_blk_misalign=%d", | ||
522 | csd->ccc, csd->read_bl_len, | ||
523 | csd->read_bl_partial, csd->write_blk_misalign); | ||
524 | DEBUG("read_blk_misalign=%d dsr_imp=%d c_size=%d vdd_r_curr_min=%d", | ||
525 | csd->read_blk_misalign, csd->dsr_imp, | ||
526 | csd->c_size, csd->vdd_r_curr_min); | ||
527 | DEBUG("vdd_r_curr_max=%d vdd_w_curr_min=%d vdd_w_curr_max=%d c_size_mult=%d", | ||
528 | csd->vdd_r_curr_max, csd->vdd_w_curr_min, | ||
529 | csd->vdd_w_curr_max, csd->c_size_mult); | ||
530 | DEBUG("wp_grp_size=%d wp_grp_enable=%d default_ecc=%d r2w_factor=%d", | ||
531 | csd->wp_grp_size, csd->wp_grp_enable, | ||
532 | csd->default_ecc, csd->r2w_factor); | ||
533 | DEBUG("write_bl_len=%d write_bl_partial=%d file_format_grp=%d copy=%d", | ||
534 | csd->write_bl_len, csd->write_bl_partial, | ||
535 | csd->file_format_grp, csd->copy); | ||
536 | DEBUG("perm_write_protect=%d tmp_write_protect=%d file_format=%d ecc=%d", | ||
537 | csd->perm_write_protect, csd->tmp_write_protect, | ||
538 | csd->file_format, csd->ecc); | ||
539 | switch (csd->csd_structure) { | ||
540 | case CSD_STRUCT_VER_1_0: | ||
541 | case CSD_STRUCT_VER_1_1: | ||
542 | DEBUG("V22 sector_size=%d erase_grp_size=%d", | ||
543 | csd->erase.v22.sector_size, | ||
544 | csd->erase.v22.erase_grp_size); | ||
545 | break; | ||
546 | case CSD_STRUCT_VER_1_2: | ||
547 | default: | ||
548 | DEBUG("V31 erase_grp_size=%d erase_grp_mult=%d", | ||
549 | csd->erase.v31.erase_grp_size, | ||
550 | csd->erase.v31.erase_grp_mult); | ||
551 | break; | ||
552 | } | ||
553 | } | ||
554 | |||
555 | if (buf[0] != 0x3f) | ||
556 | return MMC_ERROR_HEADER_MISMATCH; | ||
557 | |||
558 | return 0; | ||
559 | } | ||
560 | |||
561 | int mmc_unpack_r1(struct mmc_request *request, struct mmc_response_r1 *r1) | ||
562 | { | ||
563 | unsigned char *buf = request->response; | ||
564 | |||
565 | if (request->result) | ||
566 | return request->result; | ||
567 | |||
568 | r1->cmd = buf[0]; | ||
569 | r1->status = PARSE_U32(buf,1); | ||
570 | |||
571 | DEBUG("mmc_unpack_r1: cmd=%d status=%08x", r1->cmd, r1->status); | ||
572 | |||
573 | if (R1_STATUS(r1->status)) { | ||
574 | if (r1->status & R1_OUT_OF_RANGE) return MMC_ERROR_OUT_OF_RANGE; | ||
575 | if (r1->status & R1_ADDRESS_ERROR) return MMC_ERROR_ADDRESS; | ||
576 | if (r1->status & R1_BLOCK_LEN_ERROR) return MMC_ERROR_BLOCK_LEN; | ||
577 | if (r1->status & R1_ERASE_SEQ_ERROR) return MMC_ERROR_ERASE_SEQ; | ||
578 | if (r1->status & R1_ERASE_PARAM) return MMC_ERROR_ERASE_PARAM; | ||
579 | if (r1->status & R1_WP_VIOLATION) return MMC_ERROR_WP_VIOLATION; | ||
580 | //if (r1->status & R1_CARD_IS_LOCKED) return MMC_ERROR_CARD_IS_LOCKED; | ||
581 | if (r1->status & R1_LOCK_UNLOCK_FAILED) return MMC_ERROR_LOCK_UNLOCK_FAILED; | ||
582 | if (r1->status & R1_COM_CRC_ERROR) return MMC_ERROR_COM_CRC; | ||
583 | if (r1->status & R1_ILLEGAL_COMMAND) return MMC_ERROR_ILLEGAL_COMMAND; | ||
584 | if (r1->status & R1_CARD_ECC_FAILED) return MMC_ERROR_CARD_ECC_FAILED; | ||
585 | if (r1->status & R1_CC_ERROR) return MMC_ERROR_CC; | ||
586 | if (r1->status & R1_ERROR) return MMC_ERROR_GENERAL; | ||
587 | if (r1->status & R1_UNDERRUN) return MMC_ERROR_UNDERRUN; | ||
588 | if (r1->status & R1_OVERRUN) return MMC_ERROR_OVERRUN; | ||
589 | if (r1->status & R1_CID_CSD_OVERWRITE) return MMC_ERROR_CID_CSD_OVERWRITE; | ||
590 | } | ||
591 | |||
592 | if (buf[0] != request->cmd) | ||
593 | return MMC_ERROR_HEADER_MISMATCH; | ||
594 | |||
595 | /* This should be last - it's the least dangerous error */ | ||
596 | |||
597 | return 0; | ||
598 | } | ||
599 | |||
600 | int mmc_unpack_scr(struct mmc_request *request, struct mmc_response_r1 *r1, unsigned int *scr) | ||
601 | { | ||
602 | unsigned char *buf = request->response; | ||
603 | if (request->result) | ||
604 | return request->result; | ||
605 | |||
606 | *scr = PARSE_U32(buf, 5); /* Save SCR returned by the SD Card */ | ||
607 | return mmc_unpack_r1(request, r1); | ||
608 | } | ||
609 | |||
610 | int mmc_unpack_r6(struct mmc_request *request, struct mmc_response_r1 *r1, int *rca) | ||
611 | { | ||
612 | unsigned char *buf = request->response; | ||
613 | |||
614 | if (request->result) return request->result; | ||
615 | |||
616 | *rca = PARSE_U16(buf,1); /* Save RCA returned by the SD Card */ | ||
617 | |||
618 | *(buf+1) = 0; | ||
619 | *(buf+2) = 0; | ||
620 | |||
621 | return mmc_unpack_r1(request, r1); | ||
622 | } | ||
623 | |||
624 | int mmc_unpack_cid(struct mmc_request *request, struct mmc_cid *cid) | ||
625 | { | ||
626 | unsigned char *buf = request->response; | ||
627 | int i; | ||
628 | |||
629 | if (request->result) return request->result; | ||
630 | |||
631 | cid->mid = buf[1]; | ||
632 | cid->oid = PARSE_U16(buf,2); | ||
633 | for (i = 0 ; i < 6 ; i++) | ||
634 | cid->pnm[i] = buf[4+i]; | ||
635 | cid->pnm[6] = 0; | ||
636 | cid->prv = buf[10]; | ||
637 | cid->psn = PARSE_U32(buf,11); | ||
638 | cid->mdt = buf[15]; | ||
639 | |||
640 | DEBUG("mmc_unpack_cid: mid=%d oid=%d pnm=%s prv=%d.%d psn=%08x mdt=%d/%d", | ||
641 | cid->mid, cid->oid, cid->pnm, | ||
642 | (cid->prv>>4), (cid->prv&0xf), | ||
643 | cid->psn, (cid->mdt>>4), (cid->mdt&0xf)+1997); | ||
644 | |||
645 | if (buf[0] != 0x3f) return MMC_ERROR_HEADER_MISMATCH; | ||
646 | return 0; | ||
647 | } | ||
648 | |||
649 | int mmc_unpack_r3(struct mmc_request *request, struct mmc_response_r3 *r3) | ||
650 | { | ||
651 | unsigned char *buf = request->response; | ||
652 | |||
653 | if (request->result) return request->result; | ||
654 | |||
655 | r3->ocr = PARSE_U32(buf,1); | ||
656 | DEBUG("mmc_unpack_r3: ocr=%08x", r3->ocr); | ||
657 | |||
658 | if (buf[0] != 0x3f) return MMC_ERROR_HEADER_MISMATCH; | ||
659 | return 0; | ||
660 | } | ||
369 | 661 | ||
370 | /* Stop the MMC clock and wait while it happens */ | 662 | /* Stop the MMC clock and wait while it happens */ |
371 | static inline int jz_mmc_stop_clock(void) | 663 | static inline int jz_mmc_stop_clock(void) |
372 | { | 664 | { |
373 | int timeout = 1000; | 665 | register int timeout = 1000; |
374 | 666 | ||
375 | DEBUG("stop MMC clock"); | 667 | //DEBUG("stop MMC clock"); |
376 | REG_MSC_STRPCL = MSC_STRPCL_CLOCK_CONTROL_STOP; | 668 | REG_MSC_STRPCL = MSC_STRPCL_CLOCK_CONTROL_STOP; |
377 | 669 | ||
378 | while (timeout && (REG_MSC_STAT & MSC_STAT_CLK_EN)) | 670 | while (timeout && (REG_MSC_STAT & MSC_STAT_CLK_EN)) |
@@ -385,40 +677,26 @@ static inline int jz_mmc_stop_clock(void) | |||
385 | } | 677 | } |
386 | udelay(1); | 678 | udelay(1); |
387 | } | 679 | } |
388 | DEBUG("clock off time is %d microsec", timeout); | 680 | //DEBUG("clock off time is %d microsec", timeout); |
389 | return MMC_NO_ERROR; | 681 | return MMC_NO_ERROR; |
390 | } | 682 | } |
391 | 683 | ||
392 | /* Start the MMC clock and operation */ | 684 | /* Start the MMC clock and operation */ |
393 | static inline int jz_mmc_start_clock(void) | 685 | static inline int jz_mmc_start_clock(void) |
394 | { | 686 | { |
395 | REG_MSC_STRPCL = | 687 | REG_MSC_STRPCL = MSC_STRPCL_CLOCK_CONTROL_START | MSC_STRPCL_START_OP; |
396 | MSC_STRPCL_CLOCK_CONTROL_START | MSC_STRPCL_START_OP; | ||
397 | return MMC_NO_ERROR; | 688 | return MMC_NO_ERROR; |
398 | } | 689 | } |
399 | 690 | ||
400 | static inline unsigned int jz_mmc_calc_clkrt(int is_sd, unsigned int rate) | ||
401 | { | ||
402 | unsigned int clkrt; | ||
403 | unsigned int clk_src = is_sd ? 24000000 : 20000000; | ||
404 | |||
405 | clkrt = 0; | ||
406 | while (rate < clk_src) | ||
407 | { | ||
408 | clkrt++; | ||
409 | clk_src >>= 1; | ||
410 | } | ||
411 | return clkrt; | ||
412 | } | ||
413 | |||
414 | static int jz_mmc_check_status(struct mmc_request *request) | 691 | static int jz_mmc_check_status(struct mmc_request *request) |
415 | { | 692 | { |
693 | (void)request; | ||
416 | unsigned int status = REG_MSC_STAT; | 694 | unsigned int status = REG_MSC_STAT; |
417 | 695 | ||
418 | /* Checking for response or data timeout */ | 696 | /* Checking for response or data timeout */ |
419 | if (status & (MSC_STAT_TIME_OUT_RES | MSC_STAT_TIME_OUT_READ)) | 697 | if (status & (MSC_STAT_TIME_OUT_RES | MSC_STAT_TIME_OUT_READ)) |
420 | { | 698 | { |
421 | DEBUG("MMC/SD timeout, MMC_STAT 0x%x CMD %d", status, | 699 | DEBUG("MMC/SD timeout, MSC_STAT 0x%x CMD %d", status, |
422 | request->cmd); | 700 | request->cmd); |
423 | return MMC_ERROR_TIMEOUT; | 701 | return MMC_ERROR_TIMEOUT; |
424 | } | 702 | } |
@@ -428,9 +706,18 @@ static int jz_mmc_check_status(struct mmc_request *request) | |||
428 | (MSC_STAT_CRC_READ_ERROR | MSC_STAT_CRC_WRITE_ERROR | | 706 | (MSC_STAT_CRC_READ_ERROR | MSC_STAT_CRC_WRITE_ERROR | |
429 | MSC_STAT_CRC_RES_ERR)) | 707 | MSC_STAT_CRC_RES_ERR)) |
430 | { | 708 | { |
431 | DEBUG("MMC/CD CRC error, MMC_STAT 0x%x", status); | 709 | DEBUG("MMC/SD CRC error, MSC_STAT 0x%x", status); |
432 | return MMC_ERROR_CRC; | 710 | return MMC_ERROR_CRC; |
711 | |||
433 | } | 712 | } |
713 | |||
714 | |||
715 | /* Checking for FIFO empty */ | ||
716 | /*if(status & MSC_STAT_DATA_FIFO_EMPTY && request->rtype != RESPONSE_NONE) | ||
717 | { | ||
718 | DEBUG("MMC/SD FIFO empty, MSC_STAT 0x%x", status); | ||
719 | return MMC_ERROR_UNDERRUN; | ||
720 | }*/ | ||
434 | 721 | ||
435 | return MMC_NO_ERROR; | 722 | return MMC_NO_ERROR; |
436 | } | 723 | } |
@@ -451,6 +738,7 @@ static void jz_mmc_get_response(struct mmc_request *request) | |||
451 | { | 738 | { |
452 | case RESPONSE_R1: | 739 | case RESPONSE_R1: |
453 | case RESPONSE_R1B: | 740 | case RESPONSE_R1B: |
741 | case RESPONSE_R7: | ||
454 | case RESPONSE_R6: | 742 | case RESPONSE_R6: |
455 | case RESPONSE_R3: | 743 | case RESPONSE_R3: |
456 | case RESPONSE_R4: | 744 | case RESPONSE_R4: |
@@ -686,6 +974,20 @@ static int jz_mmc_transmit_data(struct mmc_request *req) | |||
686 | return MMC_NO_ERROR; | 974 | return MMC_NO_ERROR; |
687 | } | 975 | } |
688 | 976 | ||
977 | static inline unsigned int jz_mmc_calc_clkrt(int is_sd, unsigned int rate) | ||
978 | { | ||
979 | unsigned int clkrt; | ||
980 | unsigned int clk_src = is_sd ? 24000000 : 20000000; | ||
981 | |||
982 | clkrt = 0; | ||
983 | while (rate < clk_src) | ||
984 | { | ||
985 | clkrt++; | ||
986 | clk_src >>= 1; | ||
987 | } | ||
988 | return clkrt; | ||
989 | } | ||
990 | |||
689 | /* Set the MMC clock frequency */ | 991 | /* Set the MMC clock frequency */ |
690 | static void jz_mmc_set_clock(int sd, unsigned int rate) | 992 | static void jz_mmc_set_clock(int sd, unsigned int rate) |
691 | { | 993 | { |
@@ -695,19 +997,20 @@ static void jz_mmc_set_clock(int sd, unsigned int rate) | |||
695 | 997 | ||
696 | jz_mmc_stop_clock(); | 998 | jz_mmc_stop_clock(); |
697 | 999 | ||
698 | if(sd2_0) | 1000 | if (sd2_0) |
699 | { | 1001 | { |
700 | __cpm_select_msc_hs_clk(sd); /* select clock source from CPM */ | 1002 | __cpm_select_msc_hs_clk(sd); /* select clock source from CPM */ |
701 | REG_CPM_CPCCR |= CPM_CPCCR_CE; | 1003 | REG_CPM_CPCCR |= CPM_CPCCR_CE; |
702 | REG_MSC_CLKRT = 0; | 1004 | REG_MSC_CLKRT = 0; |
703 | } | 1005 | } |
704 | else | 1006 | else |
705 | { | 1007 | { |
706 | __cpm_select_msc_clk(sd); /* select clock source from CPM */ | 1008 | __cpm_select_msc_clk(sd); /* select clock source from CPM */ |
707 | REG_CPM_CPCCR |= CPM_CPCCR_CE; | 1009 | REG_CPM_CPCCR |= CPM_CPCCR_CE; |
708 | clkrt = jz_mmc_calc_clkrt(sd, rate); | 1010 | clkrt = jz_mmc_calc_clkrt(sd, rate); |
709 | REG_MSC_CLKRT = clkrt; | 1011 | REG_MSC_CLKRT = clkrt; |
710 | } | 1012 | } |
1013 | |||
711 | DEBUG("set clock to %u Hz is_sd=%d clkrt=%d", rate, sd, clkrt); | 1014 | DEBUG("set clock to %u Hz is_sd=%d clkrt=%d", rate, sd, clkrt); |
712 | } | 1015 | } |
713 | 1016 | ||
@@ -724,8 +1027,8 @@ static int jz_mmc_exec_cmd(struct mmc_request *request) | |||
724 | 1027 | ||
725 | /* Indicate we have no result yet */ | 1028 | /* Indicate we have no result yet */ |
726 | request->result = MMC_NO_RESPONSE; | 1029 | request->result = MMC_NO_RESPONSE; |
727 | if (request->cmd == MMC_CIM_RESET) | 1030 | |
728 | { | 1031 | if (request->cmd == MMC_CIM_RESET) { |
729 | /* On reset, 1-bit bus width */ | 1032 | /* On reset, 1-bit bus width */ |
730 | use_4bit = 0; | 1033 | use_4bit = 0; |
731 | 1034 | ||
@@ -733,19 +1036,11 @@ static int jz_mmc_exec_cmd(struct mmc_request *request) | |||
733 | __msc_reset(); | 1036 | __msc_reset(); |
734 | 1037 | ||
735 | /* On reset, drop MMC clock down */ | 1038 | /* On reset, drop MMC clock down */ |
736 | jz_mmc_set_clock(0, MMC_CLOCK_SLOW); | 1039 | jz_mmc_set_clock(1, MMC_CLOCK_SLOW); |
737 | 1040 | ||
738 | /* On reset, stop MMC clock */ | 1041 | /* On reset, stop MMC clock */ |
739 | jz_mmc_stop_clock(); | 1042 | jz_mmc_stop_clock(); |
740 | } | 1043 | } |
741 | #if 0 | ||
742 | if (request->cmd == MMC_SEND_OP_COND) | ||
743 | { | ||
744 | DEBUG("Have a MMC card"); | ||
745 | /* always use 1bit for MMC */ | ||
746 | use_4bit = 0; | ||
747 | } | ||
748 | #endif | ||
749 | if (request->cmd == SET_BUS_WIDTH) | 1044 | if (request->cmd == SET_BUS_WIDTH) |
750 | { | 1045 | { |
751 | if (request->arg == 0x2) | 1046 | if (request->arg == 0x2) |
@@ -764,7 +1059,7 @@ static int jz_mmc_exec_cmd(struct mmc_request *request) | |||
764 | jz_mmc_stop_clock(); | 1059 | jz_mmc_stop_clock(); |
765 | 1060 | ||
766 | /* mask all interrupts */ | 1061 | /* mask all interrupts */ |
767 | REG_MSC_IMASK = 0xffff; | 1062 | //REG_MSC_IMASK = 0xffff; |
768 | /* clear status */ | 1063 | /* clear status */ |
769 | REG_MSC_IREG = 0xffff; | 1064 | REG_MSC_IREG = 0xffff; |
770 | /*open interrupt */ | 1065 | /*open interrupt */ |
@@ -778,9 +1073,8 @@ static int jz_mmc_exec_cmd(struct mmc_request *request) | |||
778 | { | 1073 | { |
779 | /* MMC core extra command */ | 1074 | /* MMC core extra command */ |
780 | case MMC_CIM_RESET: | 1075 | case MMC_CIM_RESET: |
781 | cmdat |= MSC_CMDAT_INIT; /* Initialization sequence sent prior to command */ | 1076 | cmdat |= MSC_CMDAT_INIT; /* Initialization sequence sent prior to command */ |
782 | break; | 1077 | break; |
783 | |||
784 | /* bc - broadcast - no response */ | 1078 | /* bc - broadcast - no response */ |
785 | case MMC_GO_IDLE_STATE: | 1079 | case MMC_GO_IDLE_STATE: |
786 | case MMC_SET_DSR: | 1080 | case MMC_SET_DSR: |
@@ -854,8 +1148,9 @@ static int jz_mmc_exec_cmd(struct mmc_request *request) | |||
854 | break; | 1148 | break; |
855 | case RESPONSE_R1B: | 1149 | case RESPONSE_R1B: |
856 | cmdat |= MSC_CMDAT_BUSY; | 1150 | cmdat |= MSC_CMDAT_BUSY; |
857 | /*FALLTHRU*/ | 1151 | /* FALLTHRU */ |
858 | case RESPONSE_R1: | 1152 | case RESPONSE_R1: |
1153 | case RESPONSE_R7: | ||
859 | cmdat |= MSC_CMDAT_RESPONSE_R1; | 1154 | cmdat |= MSC_CMDAT_RESPONSE_R1; |
860 | break; | 1155 | break; |
861 | case RESPONSE_R2_CID: | 1156 | case RESPONSE_R2_CID: |
@@ -964,7 +1259,6 @@ static int jz_mmc_exec_cmd(struct mmc_request *request) | |||
964 | /* Wait for Data Done */ | 1259 | /* Wait for Data Done */ |
965 | while (!(REG_MSC_IREG & MSC_IREG_DATA_TRAN_DONE)); | 1260 | while (!(REG_MSC_IREG & MSC_IREG_DATA_TRAN_DONE)); |
966 | REG_MSC_IREG = MSC_IREG_DATA_TRAN_DONE; /* clear status */ | 1261 | REG_MSC_IREG = MSC_IREG_DATA_TRAN_DONE; /* clear status */ |
967 | |||
968 | } | 1262 | } |
969 | 1263 | ||
970 | /* Wait for Prog Done event */ | 1264 | /* Wait for Prog Done event */ |
@@ -1027,6 +1321,7 @@ static void jz_mmc_rx_handler(unsigned int arg) | |||
1027 | void MSC(void) | 1321 | void MSC(void) |
1028 | { | 1322 | { |
1029 | //wakeup_signal(&sd_wakeup); | 1323 | //wakeup_signal(&sd_wakeup); |
1324 | logf("MSC interrupt"); | ||
1030 | } | 1325 | } |
1031 | 1326 | ||
1032 | /******************************************************************************************************************* | 1327 | /******************************************************************************************************************* |
@@ -1037,8 +1332,8 @@ void MSC(void) | |||
1037 | ********************************************************************************************************************/ | 1332 | ********************************************************************************************************************/ |
1038 | static void jz_mmc_hardware_init(void) | 1333 | static void jz_mmc_hardware_init(void) |
1039 | { | 1334 | { |
1040 | mmc_init_gpio(); /* init GPIO */ | ||
1041 | __cpm_start_msc(); /* enable mmc clock */ | 1335 | __cpm_start_msc(); /* enable mmc clock */ |
1336 | mmc_init_gpio(); /* init GPIO */ | ||
1042 | #ifdef MMC_POWER_ON | 1337 | #ifdef MMC_POWER_ON |
1043 | MMC_POWER_ON(); /* turn on power of card */ | 1338 | MMC_POWER_ON(); /* turn on power of card */ |
1044 | #endif | 1339 | #endif |
@@ -1060,7 +1355,7 @@ static void jz_mmc_hardware_init(void) | |||
1060 | #endif | 1355 | #endif |
1061 | } | 1356 | } |
1062 | 1357 | ||
1063 | static void mmc_send_cmd(struct mmc_request *request, int cmd, unsigned int arg, | 1358 | static int mmc_send_cmd(struct mmc_request *request, int cmd, unsigned int arg, |
1064 | unsigned short nob, unsigned short block_len, | 1359 | unsigned short nob, unsigned short block_len, |
1065 | enum mmc_rsp_t rtype, unsigned char* buffer) | 1360 | enum mmc_rsp_t rtype, unsigned char* buffer) |
1066 | { | 1361 | { |
@@ -1071,26 +1366,284 @@ static void mmc_send_cmd(struct mmc_request *request, int cmd, unsigned int arg, | |||
1071 | request->block_len = block_len; | 1366 | request->block_len = block_len; |
1072 | request->buffer = buffer; | 1367 | request->buffer = buffer; |
1073 | request->cnt = nob * block_len; | 1368 | request->cnt = nob * block_len; |
1074 | logf("mmc_send_cmd: command = %d",cmd); | 1369 | |
1075 | jz_mmc_exec_cmd(request); | 1370 | return jz_mmc_exec_cmd(request); |
1076 | } | 1371 | } |
1077 | 1372 | ||
1078 | static bool inited = false; | 1373 | static void mmc_simple_cmd(struct mmc_request *request, int cmd, unsigned int arg, |
1079 | int _sd_init(void) | 1374 | enum mmc_rsp_t rtype) |
1080 | { | 1375 | { |
1376 | mmc_send_cmd(request, cmd, arg, 0, 0, rtype, NULL); | ||
1377 | } | ||
1378 | |||
1379 | #define KBPS 1 | ||
1380 | #define MBPS 1000 | ||
1381 | static unsigned int ts_exp[] = { 100*KBPS, 1*MBPS, 10*MBPS, 100*MBPS, 0, 0, 0, 0 }; | ||
1382 | static unsigned int ts_mul[] = { 0, 1000, 1200, 1300, 1500, 2000, 2500, 3000, | ||
1383 | 3500, 4000, 4500, 5000, 5500, 6000, 7000, 8000 }; | ||
1384 | |||
1385 | unsigned int mmc_tran_speed(unsigned char ts) | ||
1386 | { | ||
1387 | unsigned int rate = ts_exp[(ts & 0x7)] * ts_mul[(ts & 0x78) >> 3]; | ||
1388 | |||
1389 | if (rate <= 0) | ||
1390 | { | ||
1391 | DEBUG("mmc_tran_speed: error - unrecognized speed 0x%02x", ts); | ||
1392 | return 1; | ||
1393 | } | ||
1394 | |||
1395 | return rate; | ||
1396 | } | ||
1397 | |||
1398 | static void mmc_configure_card(void) | ||
1399 | { | ||
1400 | unsigned int rate; | ||
1401 | |||
1402 | /* Get card info */ | ||
1403 | if (sd2_0) | ||
1404 | mmcinfo.block_num = (mmcinfo.csd.c_size + 1) << 10; | ||
1405 | else | ||
1406 | mmcinfo.block_num = (mmcinfo.csd.c_size + 1) * (1 << (mmcinfo.csd.c_size_mult + 2)); | ||
1407 | |||
1408 | mmcinfo.block_len = 1 << mmcinfo.csd.read_bl_len; | ||
1409 | |||
1410 | /* Fix the clock rate */ | ||
1411 | rate = mmc_tran_speed(mmcinfo.csd.tran_speed); | ||
1412 | if (rate < MMC_CLOCK_SLOW) | ||
1413 | rate = MMC_CLOCK_SLOW; | ||
1414 | if (rate > SD_CLOCK_FAST) | ||
1415 | rate = SD_CLOCK_FAST; | ||
1416 | |||
1417 | DEBUG("mmc_configure_card: block_len=%d block_num=%d rate=%d", mmcinfo.block_len, mmcinfo.block_num, rate); | ||
1418 | |||
1419 | jz_mmc_set_clock(1, rate); | ||
1420 | } | ||
1421 | |||
1422 | #define MMC_INIT_DOING 0 | ||
1423 | #define MMC_INIT_PASSED 1 | ||
1424 | #define MMC_INIT_FAILED 2 | ||
1425 | |||
1426 | static int mmc_init_card_state(struct mmc_request *request) | ||
1427 | { | ||
1428 | struct mmc_response_r1 r1; | ||
1429 | struct mmc_response_r3 r3; | ||
1430 | int retval; | ||
1431 | int ocr = 0x40300000; | ||
1432 | int limit_41 = 0; | ||
1433 | |||
1434 | switch (request->cmd) | ||
1435 | { | ||
1436 | case MMC_GO_IDLE_STATE: /* No response to parse */ | ||
1437 | mmc_simple_cmd(request, SD_SEND_IF_COND, 0x1AA, RESPONSE_R1); | ||
1438 | break; | ||
1439 | |||
1440 | case SD_SEND_IF_COND: | ||
1441 | mmc_simple_cmd(request, MMC_APP_CMD, 0, RESPONSE_R1); | ||
1442 | break; | ||
1443 | |||
1444 | case MMC_APP_CMD: | ||
1445 | retval = mmc_unpack_r1(request, &r1); | ||
1446 | if (retval & (limit_41 < 100)) | ||
1447 | { | ||
1448 | DEBUG("mmc_init_card_state: unable to MMC_APP_CMD error=%d", | ||
1449 | retval); | ||
1450 | limit_41++; | ||
1451 | mmc_simple_cmd(request, SD_SEND_OP_COND, ocr, RESPONSE_R3); | ||
1452 | } else if (limit_41 < 100) { | ||
1453 | limit_41++; | ||
1454 | mmc_simple_cmd(request, SD_SEND_OP_COND, ocr, RESPONSE_R3); | ||
1455 | } else{ | ||
1456 | /* reset the card to idle*/ | ||
1457 | mmc_simple_cmd(request, MMC_GO_IDLE_STATE, 0, RESPONSE_NONE); | ||
1458 | } | ||
1459 | break; | ||
1460 | |||
1461 | case SD_SEND_OP_COND: | ||
1462 | retval = mmc_unpack_r3(request, &r3); | ||
1463 | if (retval) | ||
1464 | { | ||
1465 | /* Try MMC card */ | ||
1466 | mmc_simple_cmd(request, MMC_SEND_OP_COND, MMC_OCR_ARG, RESPONSE_R3); | ||
1467 | break; | ||
1468 | } | ||
1469 | |||
1470 | DEBUG("mmc_init_card_state: read ocr value = 0x%08x", r3.ocr); | ||
1471 | |||
1472 | if(!(r3.ocr & MMC_CARD_BUSY || ocr == 0)){ | ||
1473 | udelay(10000); | ||
1474 | mmc_simple_cmd(request, MMC_APP_CMD, 0, RESPONSE_R1); | ||
1475 | } | ||
1476 | else | ||
1477 | { | ||
1478 | /* Set the data bus width to 4 bits */ | ||
1479 | use_4bit = 1; | ||
1480 | mmc_simple_cmd(request, MMC_ALL_SEND_CID, 0, RESPONSE_R2_CID); | ||
1481 | } | ||
1482 | break; | ||
1483 | |||
1484 | case MMC_SEND_OP_COND: | ||
1485 | retval = mmc_unpack_r3(request, &r3); | ||
1486 | if (retval) | ||
1487 | { | ||
1488 | DEBUG("mmc_init_card_state: failed SEND_OP_COND error=%d", | ||
1489 | retval); | ||
1490 | return MMC_INIT_FAILED; | ||
1491 | } | ||
1492 | |||
1493 | DEBUG("mmc_init_card_state: read ocr value = 0x%08x", r3.ocr); | ||
1494 | if (!(r3.ocr & MMC_CARD_BUSY)) | ||
1495 | mmc_simple_cmd(request, MMC_SEND_OP_COND, MMC_OCR_ARG, RESPONSE_R3); | ||
1496 | else | ||
1497 | mmc_simple_cmd(request, MMC_ALL_SEND_CID, 0, RESPONSE_R2_CID); | ||
1498 | break; | ||
1499 | |||
1500 | case MMC_ALL_SEND_CID: | ||
1501 | retval = mmc_unpack_cid( request, &mmcinfo.cid ); | ||
1502 | |||
1503 | if ( retval && (retval != MMC_ERROR_CRC)) { | ||
1504 | DEBUG("mmc_init_card_state: unable to ALL_SEND_CID error=%d", | ||
1505 | retval); | ||
1506 | return MMC_INIT_FAILED; | ||
1507 | } | ||
1508 | mmc_simple_cmd(request, MMC_SET_RELATIVE_ADDR, 0, RESPONSE_R6); | ||
1509 | break; | ||
1510 | |||
1511 | case MMC_SET_RELATIVE_ADDR: | ||
1512 | retval = mmc_unpack_r6(request, &r1, &mmcinfo.rca); | ||
1513 | mmcinfo.rca = mmcinfo.rca << 16; | ||
1514 | DEBUG("mmc_init_card_state: Get RCA from SD: 0x%04x Status: %x", mmcinfo.rca, r1.status); | ||
1515 | if (retval) | ||
1516 | { | ||
1517 | DEBUG("mmc_init_card_state: unable to SET_RELATIVE_ADDR error=%d", | ||
1518 | retval); | ||
1519 | return MMC_INIT_FAILED; | ||
1520 | } | ||
1521 | |||
1522 | mmc_simple_cmd(request, MMC_SEND_CSD, mmcinfo.rca, RESPONSE_R2_CSD); | ||
1523 | break; | ||
1524 | |||
1525 | case MMC_SEND_CSD: | ||
1526 | retval = mmc_unpack_csd(request, &mmcinfo.csd); | ||
1527 | |||
1528 | DEBUG("SD card is ready"); | ||
1529 | |||
1530 | /*FIXME:ignore CRC error for CMD2/CMD9/CMD10 */ | ||
1531 | if (retval && (retval != MMC_ERROR_CRC)) | ||
1532 | { | ||
1533 | DEBUG("mmc_init_card_state: unable to SEND_CSD error=%d", | ||
1534 | retval); | ||
1535 | return MMC_INIT_FAILED; | ||
1536 | } | ||
1537 | mmc_configure_card(); | ||
1538 | return MMC_INIT_PASSED; | ||
1539 | |||
1540 | default: | ||
1541 | DEBUG("mmc_init_card_state: error! Illegal last cmd %d", request->cmd); | ||
1542 | return MMC_INIT_FAILED; | ||
1543 | } | ||
1544 | |||
1545 | return MMC_INIT_DOING; | ||
1546 | } | ||
1547 | |||
1548 | static int mmc_sd_switch(struct mmc_request *request, int mode, int group, | ||
1549 | unsigned char value, unsigned char * resp) | ||
1550 | { | ||
1551 | unsigned int arg; | ||
1552 | |||
1553 | mode = !!mode; | ||
1554 | value &= 0xF; | ||
1555 | arg = (mode << 31 | 0x00FFFFFF); | ||
1556 | arg &= ~(0xF << (group * 4)); | ||
1557 | arg |= value << (group * 4); | ||
1558 | mmc_send_cmd(request, 6, arg, 1, 64, RESPONSE_R1, resp); | ||
1559 | |||
1560 | return 0; | ||
1561 | } | ||
1562 | |||
1563 | /* | ||
1564 | * Fetches and decodes switch information | ||
1565 | */ | ||
1566 | static int mmc_read_switch(struct mmc_request *request) | ||
1567 | { | ||
1568 | unsigned int status[64 / 4]; | ||
1569 | |||
1570 | memset((unsigned char *)status, 0, 64); | ||
1571 | mmc_sd_switch(request, 0, 0, 1, (unsigned char*) status); | ||
1572 | |||
1573 | if (((unsigned char *)status)[13] & 0x02) | ||
1574 | return 0; | ||
1575 | else | ||
1576 | return 1; | ||
1577 | } | ||
1578 | |||
1579 | /* | ||
1580 | * Test if the card supports high-speed mode and, if so, switch to it. | ||
1581 | */ | ||
1582 | static int mmc_switch_hs(struct mmc_request *request) | ||
1583 | { | ||
1584 | unsigned int status[64 / 4]; | ||
1585 | |||
1586 | mmc_sd_switch(request, 1, 0, 1, (unsigned char*) status); | ||
1587 | return 0; | ||
1588 | } | ||
1589 | |||
1590 | int mmc_select_card(void) | ||
1591 | { | ||
1592 | struct mmc_request request; | ||
1593 | struct mmc_response_r1 r1; | ||
1594 | int retval; | ||
1595 | |||
1596 | mmc_simple_cmd(&request, MMC_SELECT_CARD, mmcinfo.rca, | ||
1597 | RESPONSE_R1B); | ||
1598 | retval = mmc_unpack_r1(&request, &r1); | ||
1599 | if (retval) | ||
1600 | return retval; | ||
1601 | |||
1602 | if (sd2_0) | ||
1603 | { | ||
1604 | retval = mmc_read_switch(&request); | ||
1605 | if (!retval) | ||
1606 | { | ||
1607 | mmc_switch_hs(&request); | ||
1608 | jz_mmc_set_clock(1, SD_CLOCK_HIGH); | ||
1609 | } | ||
1610 | } | ||
1611 | num_6 = 3; | ||
1612 | mmc_simple_cmd(&request, MMC_APP_CMD, mmcinfo.rca, | ||
1613 | RESPONSE_R1); | ||
1614 | retval = mmc_unpack_r1(&request, &r1); | ||
1615 | if (retval) | ||
1616 | return retval; | ||
1617 | mmc_simple_cmd(&request, SET_BUS_WIDTH, 2, RESPONSE_R1); | ||
1618 | retval = mmc_unpack_r1(&request, &r1); | ||
1619 | if (retval) | ||
1620 | return retval; | ||
1621 | |||
1622 | return retval; | ||
1623 | } | ||
1624 | |||
1625 | int sd_init(void) | ||
1626 | { | ||
1627 | int retval; | ||
1628 | static bool inited = false; | ||
1629 | struct mmc_request init_req; | ||
1081 | if(!inited) | 1630 | if(!inited) |
1082 | { | 1631 | { |
1083 | jz_mmc_hardware_init(); | 1632 | jz_mmc_hardware_init(); |
1084 | wakeup_init(&sd_wakeup); | 1633 | wakeup_init(&sd_wakeup); |
1634 | num_6 = 0; | ||
1085 | inited = true; | 1635 | inited = true; |
1086 | } | 1636 | } |
1087 | 1637 | ||
1088 | struct mmc_request test; | 1638 | mmc_send_cmd(&init_req, MMC_CIM_RESET, 0, 0, 0, RESPONSE_NONE, NULL); |
1089 | //mmc_send_cmd(&test, MMC_CIM_RESET, 0, 0, 0, RESPONSE_NONE, NULL); | 1639 | mmc_send_cmd(&init_req, SD_GO_IDLE_STATE, 0, 0, 0, RESPONSE_NONE, NULL); |
1090 | mmc_send_cmd(&test, MMC_GO_IDLE_STATE, 0, 0, 0, RESPONSE_NONE, NULL); | ||
1091 | mmc_send_cmd(&test, SD_SEND_OP_COND, MMC_OCR_ARG, 0, 0, RESPONSE_R3, NULL); | ||
1092 | 1640 | ||
1093 | return 0; | 1641 | while ((retval = mmc_init_card_state(&init_req)) == MMC_INIT_DOING); |
1642 | |||
1643 | if (retval == MMC_INIT_PASSED) | ||
1644 | return mmc_select_card(); | ||
1645 | else | ||
1646 | return -1; | ||
1094 | } | 1647 | } |
1095 | 1648 | ||
1096 | bool card_detect_target(void) | 1649 | bool card_detect_target(void) |
@@ -1115,27 +1668,150 @@ void card_enable_monitoring_target(bool on) | |||
1115 | /* TODO */ | 1668 | /* TODO */ |
1116 | tCardInfo* card_get_info_target(int card_no) | 1669 | tCardInfo* card_get_info_target(int card_no) |
1117 | { | 1670 | { |
1671 | (void)card_no; | ||
1672 | int i, temp; | ||
1118 | static tCardInfo card; | 1673 | static tCardInfo card; |
1674 | static const char mantissa[] = { /* *10 */ | ||
1675 | 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 }; | ||
1676 | static const int exponent[] = { /* use varies */ | ||
1677 | 1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000 }; | ||
1678 | |||
1679 | card.initialized = true; | ||
1680 | card.ocr = 0; | ||
1681 | for(i=0; i<4; i++) | ||
1682 | card.csd[i] = (*((unsigned long*)&mmcinfo.csd+4*i)); | ||
1683 | for(i=0; i<4; i++) | ||
1684 | card.cid[i] = (*((unsigned long*)&mmcinfo.cid+4*i)); | ||
1685 | temp = card_extract_bits(card.csd, 29, 3); | ||
1686 | card.speed = mantissa[card_extract_bits(card.csd, 25, 4)] | ||
1687 | * exponent[temp > 2 ? 7 : temp + 4]; | ||
1688 | card.nsac = 100 * card_extract_bits(card.csd, 16, 8); | ||
1689 | temp = card_extract_bits(card.csd, 13, 3); | ||
1690 | card.tsac = mantissa[card_extract_bits(card.csd, 9, 4)] | ||
1691 | * exponent[temp] / 10; | ||
1692 | card.numblocks = mmcinfo.block_num; | ||
1693 | card.blocksize = mmcinfo.block_len; | ||
1119 | 1694 | ||
1120 | return &card; | 1695 | return &card; |
1121 | } | 1696 | } |
1122 | 1697 | ||
1123 | /* TODO */ | 1698 | int sd_read_sectors(IF_MV2(int drive,) unsigned long start, int count, void* buf) |
1124 | int _sd_read_sectors(unsigned long start, int count, void* buf) | ||
1125 | { | 1699 | { |
1126 | (void)start; | 1700 | (void)drive; |
1127 | (void)count; | 1701 | struct mmc_request request; |
1128 | (void)buf; | 1702 | struct mmc_response_r1 r1; |
1129 | return -1; | 1703 | int retval; |
1704 | |||
1705 | if (!card_detect_target() || count == 0 || start > mmcinfo.block_num) | ||
1706 | return -1; | ||
1707 | |||
1708 | mmc_simple_cmd(&request, MMC_SEND_STATUS, mmcinfo.rca, RESPONSE_R1); | ||
1709 | retval = mmc_unpack_r1(&request, &r1); | ||
1710 | if (retval && (retval != MMC_ERROR_STATE_MISMATCH)) | ||
1711 | return retval; | ||
1712 | |||
1713 | mmc_simple_cmd(&request, MMC_SET_BLOCKLEN, BLOCK_SIZE, RESPONSE_R1); | ||
1714 | if ((retval = mmc_unpack_r1(&request, &r1))) | ||
1715 | return retval; | ||
1716 | |||
1717 | if (sd2_0) | ||
1718 | { | ||
1719 | mmc_send_cmd(&request, MMC_READ_MULTIPLE_BLOCK, start, | ||
1720 | count, BLOCK_SIZE, RESPONSE_R1, buf); | ||
1721 | if ((retval = mmc_unpack_r1(&request, &r1))) | ||
1722 | return retval; | ||
1723 | } | ||
1724 | else | ||
1725 | { | ||
1726 | mmc_send_cmd(&request, MMC_READ_MULTIPLE_BLOCK, | ||
1727 | start * BLOCK_SIZE, count, | ||
1728 | BLOCK_SIZE, RESPONSE_R1, buf); | ||
1729 | if ((retval = mmc_unpack_r1(&request, &r1))) | ||
1730 | return retval; | ||
1731 | } | ||
1732 | |||
1733 | last_disk_activity = current_tick; | ||
1734 | |||
1735 | mmc_simple_cmd(&request, MMC_STOP_TRANSMISSION, 0, RESPONSE_R1B); | ||
1736 | if ((retval = mmc_unpack_r1(&request, &r1))) | ||
1737 | return retval; | ||
1738 | |||
1739 | return retval; | ||
1130 | } | 1740 | } |
1131 | 1741 | ||
1132 | /* TODO */ | 1742 | int sd_write_sectors(IF_MV2(int drive,) unsigned long start, int count, const void* buf) |
1133 | int _sd_write_sectors(unsigned long start, int count, const void* buf) | ||
1134 | { | 1743 | { |
1135 | (void)start; | 1744 | (void)drive; |
1136 | (void)count; | 1745 | struct mmc_request request; |
1137 | (void)buf; | 1746 | struct mmc_response_r1 r1; |
1138 | return -1; | 1747 | int retval; |
1748 | |||
1749 | if (!card_detect_target() || count == 0 || start > mmcinfo.block_num) | ||
1750 | return -1; | ||
1751 | |||
1752 | mmc_simple_cmd(&request, MMC_SEND_STATUS, mmcinfo.rca, RESPONSE_R1); | ||
1753 | retval = mmc_unpack_r1(&request, &r1); | ||
1754 | if (retval && (retval != MMC_ERROR_STATE_MISMATCH)) | ||
1755 | return retval; | ||
1756 | |||
1757 | mmc_simple_cmd(&request, MMC_SET_BLOCKLEN, BLOCK_SIZE, RESPONSE_R1); | ||
1758 | if ((retval = mmc_unpack_r1(&request, &r1))) | ||
1759 | return retval; | ||
1760 | |||
1761 | if (sd2_0) | ||
1762 | { | ||
1763 | mmc_send_cmd(&request, MMC_WRITE_MULTIPLE_BLOCK, start, | ||
1764 | count, BLOCK_SIZE, RESPONSE_R1, | ||
1765 | (void*)buf); | ||
1766 | if ((retval = mmc_unpack_r1(&request, &r1))) | ||
1767 | return retval; | ||
1768 | } | ||
1769 | else | ||
1770 | { | ||
1771 | mmc_send_cmd(&request, MMC_WRITE_MULTIPLE_BLOCK, | ||
1772 | start * BLOCK_SIZE, count, | ||
1773 | BLOCK_SIZE, RESPONSE_R1, (void*)buf); | ||
1774 | if ((retval = mmc_unpack_r1(&request, &r1))) | ||
1775 | return retval; | ||
1776 | } | ||
1777 | mmc_simple_cmd(&request, MMC_STOP_TRANSMISSION, 0, RESPONSE_R1B); | ||
1778 | if ((retval = mmc_unpack_r1(&request, &r1))) | ||
1779 | return retval; | ||
1780 | |||
1781 | return retval; | ||
1782 | } | ||
1783 | |||
1784 | void sd_sleep(void) | ||
1785 | { | ||
1786 | } | ||
1787 | |||
1788 | void sd_spin(void) | ||
1789 | { | ||
1790 | } | ||
1791 | |||
1792 | long sd_last_disk_activity(void) | ||
1793 | { | ||
1794 | return last_disk_activity; | ||
1795 | } | ||
1796 | |||
1797 | void sd_spindown(int seconds) | ||
1798 | { | ||
1799 | (void)seconds; | ||
1800 | } | ||
1801 | |||
1802 | #ifdef HAVE_HOTSWAP | ||
1803 | bool sd_removable(IF_MV_NONVOID(int drive)) | ||
1804 | { | ||
1805 | (void)drive; | ||
1806 | //return true; | ||
1807 | return false; | ||
1808 | } | ||
1809 | #endif | ||
1810 | |||
1811 | bool sd_present(IF_MV_NONVOID(int drive)) | ||
1812 | { | ||
1813 | (void)drive; | ||
1814 | return (mmcinfo.block_num > 0 && card_detect_target()); | ||
1139 | } | 1815 | } |
1140 | 1816 | ||
1141 | #ifdef STORAGE_GET_INFO | 1817 | #ifdef STORAGE_GET_INFO |
@@ -1149,8 +1825,7 @@ void sd_get_info(IF_MV2(int drive,) struct storage_info *info) | |||
1149 | info->product="SD Storage"; | 1825 | info->product="SD Storage"; |
1150 | 1826 | ||
1151 | /* blocks count */ | 1827 | /* blocks count */ |
1152 | /* TODO: proper amount of sectors! */ | 1828 | info->num_sectors = mmcinfo.block_num; |
1153 | info->num_sectors = 0; | 1829 | info->sector_size = mmcinfo.block_len; |
1154 | info->sector_size = 512; | ||
1155 | } | 1830 | } |
1156 | #endif | 1831 | #endif |
diff --git a/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c b/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c index ef8c343035..c76c63dd78 100644 --- a/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c | |||
@@ -22,6 +22,23 @@ | |||
22 | #include "config.h" | 22 | #include "config.h" |
23 | #include "jz4740.h" | 23 | #include "jz4740.h" |
24 | #include "system.h" | 24 | #include "system.h" |
25 | #include "audiohw.h" | ||
26 | |||
27 | /* TODO */ | ||
28 | const struct sound_settings_info audiohw_settings[] = { | ||
29 | [SOUND_VOLUME] = {"dB", 0, 1, -73, 6, -20}, | ||
30 | /* HAVE_SW_TONE_CONTROLS */ | ||
31 | [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0}, | ||
32 | [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0}, | ||
33 | [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, | ||
34 | [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, | ||
35 | [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, | ||
36 | #ifdef HAVE_RECORDING | ||
37 | [SOUND_LEFT_GAIN] = {"dB", 1, 1, 0, 31, 23}, | ||
38 | [SOUND_RIGHT_GAIN] = {"dB", 1, 1, 0, 31, 23}, | ||
39 | [SOUND_MIC_GAIN] = {"dB", 1, 1, 0, 1, 1}, | ||
40 | #endif | ||
41 | }; | ||
25 | 42 | ||
26 | static unsigned short codec_volume; | 43 | static unsigned short codec_volume; |
27 | static unsigned short codec_base_gain; | 44 | static unsigned short codec_base_gain; |
diff --git a/firmware/target/mips/ingenic_jz47xx/crt0.S b/firmware/target/mips/ingenic_jz47xx/crt0.S index e619022fc8..6ac40c2f52 100644 --- a/firmware/target/mips/ingenic_jz47xx/crt0.S +++ b/firmware/target/mips/ingenic_jz47xx/crt0.S | |||
@@ -43,14 +43,16 @@ | |||
43 | .set mips32 | 43 | .set mips32 |
44 | 44 | ||
45 | .extern system_main | 45 | .extern system_main |
46 | .extern main | ||
47 | .global _start | ||
46 | 48 | ||
47 | .global _start | ||
48 | .section .init.text | 49 | .section .init.text |
49 | .set noreorder | 50 | .set noreorder |
50 | .set noat | 51 | .set noat |
51 | 52 | ||
52 | #ifdef BOOTLOADER | 53 | #ifdef BOOTLOADER |
53 | .word 0 /* Unknown */ | 54 | /* These will get filled in scramble */ |
55 | .word 0 /* Unknown */ | ||
54 | .word 0 /* Filesize */ | 56 | .word 0 /* Filesize */ |
55 | 57 | ||
56 | /* Relocate bootloader */ | 58 | /* Relocate bootloader */ |
@@ -64,12 +66,12 @@ _relocate_loop: | |||
64 | bne t1, t2, _relocate_loop | 66 | bne t1, t2, _relocate_loop |
65 | addiu t0, 4 | 67 | addiu t0, 4 |
66 | #endif | 68 | #endif |
67 | 69 | ||
68 | _start: | 70 | _start: |
69 | la ra, _start | 71 | la ra, _start |
70 | /* | 72 | /* |
71 | ---------------------------------------------------- | 73 | ---------------------------------------------------- |
72 | init cp0 registers. | 74 | Init CP0 registers. |
73 | ---------------------------------------------------- | 75 | ---------------------------------------------------- |
74 | */ | 76 | */ |
75 | mtc0 zero, C0_WATCHLO | 77 | mtc0 zero, C0_WATCHLO |
@@ -90,21 +92,21 @@ _start: | |||
90 | 92 | ||
91 | /* | 93 | /* |
92 | ---------------------------------------------------- | 94 | ---------------------------------------------------- |
93 | init caches, assumes a 4way*128set*32byte i/d cache | 95 | Init caches, assumes a 4way*128set*32byte I/D cache |
94 | ---------------------------------------------------- | 96 | ---------------------------------------------------- |
95 | */ | 97 | */ |
96 | li t0, 3 // enable cache for kseg0 accesses | 98 | li t0, 3 # enable cache for kseg0 accesses |
97 | mtc0 t0, C0_CONFIG // CONFIG reg | 99 | mtc0 t0, C0_CONFIG # CONFIG reg |
98 | la t0, 0x80000000 // an idx op should use an unmappable address | 100 | la t0, 0x80000000 # an idx op should use an unmappable address |
99 | ori t1, t0, 0x4000 // 16kB cache | 101 | ori t1, t0, 0x4000 # 16kB cache |
100 | mtc0 zero, C0_TAGLO // TAGLO reg | 102 | mtc0 zero, C0_TAGLO # TAGLO reg |
101 | mtc0 zero, C0_TAGHI // TAGHI reg | 103 | mtc0 zero, C0_TAGHI # TAGHI reg |
102 | 104 | ||
103 | _init_cache_loop: | 105 | _init_cache_loop: |
104 | cache 0x8, 0(t0) // index store icache tag | 106 | cache 0x8, 0(t0) # index store icache tag |
105 | cache 0x9, 0(t0) // index store dcache tag | 107 | cache 0x9, 0(t0) # index store dcache tag |
106 | bne t0, t1, _init_cache_loop | 108 | bne t0, t1, _init_cache_loop |
107 | addiu t0, t0, 0x20 // 32 bytes per cache line | 109 | addiu t0, t0, 0x20 # 32 bytes per cache line |
108 | nop | 110 | nop |
109 | 111 | ||
110 | /* | 112 | /* |
@@ -120,7 +122,7 @@ _init_cache_loop: | |||
120 | 122 | ||
121 | /* | 123 | /* |
122 | ---------------------------------------------------- | 124 | ---------------------------------------------------- |
123 | clear BSS section | 125 | Clear BSS section |
124 | ---------------------------------------------------- | 126 | ---------------------------------------------------- |
125 | */ | 127 | */ |
126 | la t0, _edata | 128 | la t0, _edata |
@@ -132,7 +134,7 @@ _init_bss_loop: | |||
132 | 134 | ||
133 | /* | 135 | /* |
134 | ---------------------------------------------------- | 136 | ---------------------------------------------------- |
135 | clear IBSS section | 137 | Clear IBSS section |
136 | ---------------------------------------------------- | 138 | ---------------------------------------------------- |
137 | */ | 139 | */ |
138 | la t0, _iedata | 140 | la t0, _iedata |
@@ -144,7 +146,7 @@ _init_ibss_loop: | |||
144 | 146 | ||
145 | /* | 147 | /* |
146 | ---------------------------------------------------- | 148 | ---------------------------------------------------- |
147 | copy IRAM section | 149 | Copy IRAM section |
148 | ---------------------------------------------------- | 150 | ---------------------------------------------------- |
149 | */ | 151 | */ |
150 | la t0, _iramcopy | 152 | la t0, _iramcopy |
@@ -159,7 +161,7 @@ _init_iram_loop: | |||
159 | 161 | ||
160 | /* | 162 | /* |
161 | ---------------------------------------------------- | 163 | ---------------------------------------------------- |
162 | setup stack, jump to C code | 164 | Setup stack |
163 | ---------------------------------------------------- | 165 | ---------------------------------------------------- |
164 | */ | 166 | */ |
165 | la sp, stackend | 167 | la sp, stackend |
@@ -171,7 +173,15 @@ _init_stack_loop: | |||
171 | bne t0, sp, _init_stack_loop | 173 | bne t0, sp, _init_stack_loop |
172 | addiu t0, t0, 4 | 174 | addiu t0, t0, 4 |
173 | 175 | ||
174 | la t0, system_main | 176 | /* |
177 | ---------------------------------------------------- | ||
178 | Jump to C code | ||
179 | ---------------------------------------------------- | ||
180 | */ | ||
181 | la t0, system_main /* Init clocks etc first */ | ||
182 | jalr t0 | ||
183 | nop | ||
184 | la t0, main | ||
175 | jr t0 | 185 | jr t0 |
176 | nop | 186 | nop |
177 | 187 | ||
@@ -182,11 +192,10 @@ _init_stack_loop: | |||
182 | * 0x180 - Exception/Interrupt handler | 192 | * 0x180 - Exception/Interrupt handler |
183 | * 0x200 - Special Exception Interrupt handler (when IV is set in CP0_CAUSE) | 193 | * 0x200 - Special Exception Interrupt handler (when IV is set in CP0_CAUSE) |
184 | */ | 194 | */ |
185 | |||
186 | 195 | ||
187 | .section .vectors.1, "ax", %progbits | 196 | .section .vectors.1, "ax", %progbits |
188 | la k0, tlb_refill_handler | 197 | la k0, tlb_refill_handler |
189 | jr k0 | 198 | jr k0 |
190 | nop | 199 | nop |
191 | 200 | ||
192 | .section .vectors.2, "ax", %progbits | 201 | .section .vectors.2, "ax", %progbits |
@@ -235,10 +244,10 @@ real_exception_handler: | |||
235 | sw v1, 0x64(sp) | 244 | sw v1, 0x64(sp) |
236 | sw v0, 0x68(sp) | 245 | sw v0, 0x68(sp) |
237 | sw $1, 0x6C(sp) | 246 | sw $1, 0x6C(sp) |
238 | mflo k0 # Move From LO | 247 | mflo k0 |
239 | nop | 248 | nop |
240 | sw k0, 0x70(sp) | 249 | sw k0, 0x70(sp) |
241 | mfhi k0 # Move From HI | 250 | mfhi k0 |
242 | nop | 251 | nop |
243 | sw k0, 0x74(sp) | 252 | sw k0, 0x74(sp) |
244 | mfc0 k0, C0_STATUS # Status register | 253 | mfc0 k0, C0_STATUS # Status register |
@@ -294,10 +303,10 @@ _int: | |||
294 | lw v0, 0x68(sp) | 303 | lw v0, 0x68(sp) |
295 | lw $1, 0x6C(sp) | 304 | lw $1, 0x6C(sp) |
296 | lw k0, 0x70(sp) | 305 | lw k0, 0x70(sp) |
297 | mtlo k0 # Move To LO | 306 | mtlo k0 |
298 | nop | 307 | nop |
299 | lw k0, 0x74(sp) | 308 | lw k0, 0x74(sp) |
300 | mthi k0 # Move To HI | 309 | mthi k0 |
301 | nop | 310 | nop |
302 | lw k0, 0x78(sp) | 311 | lw k0, 0x78(sp) |
303 | nop | 312 | nop |
@@ -360,10 +369,10 @@ _exception: | |||
360 | lw v0, 0x68(sp) | 369 | lw v0, 0x68(sp) |
361 | lw $1, 0x6C(sp) | 370 | lw $1, 0x6C(sp) |
362 | lw k0, 0x70(sp) | 371 | lw k0, 0x70(sp) |
363 | mtlo k0 # Move To LO | 372 | mtlo k0 |
364 | nop | 373 | nop |
365 | lw k0, 0x74(sp) | 374 | lw k0, 0x74(sp) |
366 | mthi k0 # Move To HI | 375 | mthi k0 |
367 | nop | 376 | nop |
368 | lw k0, 0x78(sp) | 377 | lw k0, 0x78(sp) |
369 | nop | 378 | nop |
diff --git a/firmware/target/mips/ingenic_jz47xx/debug-jz4740.c b/firmware/target/mips/ingenic_jz47xx/debug-jz4740.c index 648d410cd6..2164f1d323 100644 --- a/firmware/target/mips/ingenic_jz47xx/debug-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/debug-jz4740.c | |||
@@ -21,6 +21,29 @@ | |||
21 | 21 | ||
22 | #include "config.h" | 22 | #include "config.h" |
23 | #include "jz4740.h" | 23 | #include "jz4740.h" |
24 | #include "debug-target.h" | ||
25 | #include <stdarg.h> | ||
26 | #include <stdio.h> | ||
27 | #include "lcd.h" | ||
28 | #include "kernel.h" | ||
29 | #include "font.h" | ||
30 | #include "button.h" | ||
31 | |||
32 | static int line = 0; | ||
33 | static void printf(const char *format, ...) | ||
34 | { | ||
35 | int len; | ||
36 | unsigned char *ptr; | ||
37 | char printfbuf[256]; | ||
38 | va_list ap; | ||
39 | va_start(ap, format); | ||
40 | |||
41 | ptr = printfbuf; | ||
42 | len = vsnprintf(ptr, sizeof(printfbuf), format, ap); | ||
43 | va_end(ap); | ||
44 | |||
45 | lcd_puts(0, line++, ptr); | ||
46 | } | ||
24 | 47 | ||
25 | /* | 48 | /* |
26 | * Clock Generation Module | 49 | * Clock Generation Module |
@@ -126,6 +149,20 @@ bool __dbg_ports(void) | |||
126 | 149 | ||
127 | bool __dbg_hw_info(void) | 150 | bool __dbg_hw_info(void) |
128 | { | 151 | { |
129 | return false; | 152 | int btn = 0, touch; |
153 | |||
154 | lcd_setfont(FONT_SYSFIXED); | ||
155 | while(btn ^ BUTTON_POWER) | ||
156 | { | ||
157 | lcd_clear_display(); | ||
158 | line = 0; | ||
159 | display_clocks(); | ||
160 | display_enabled_clocks(); | ||
161 | btn = button_read_device(&touch); | ||
162 | printf("X: %d Y: %d BTN: 0x%X", touch>>16, touch&0xFFFF, btn); | ||
163 | lcd_update(); | ||
164 | sleep(HZ/16); | ||
165 | } | ||
166 | return true; | ||
130 | } | 167 | } |
131 | 168 | ||
diff --git a/firmware/target/mips/ingenic_jz47xx/debug-target.h b/firmware/target/mips/ingenic_jz47xx/debug-target.h new file mode 100644 index 0000000000..f753e6ee6c --- /dev/null +++ b/firmware/target/mips/ingenic_jz47xx/debug-target.h | |||
@@ -0,0 +1,28 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2009 by Maurus Cuelenaere | ||
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 | #ifndef __DEBUG_TARGET_H_ | ||
23 | #define __DEBUG_TARGET_H_ | ||
24 | |||
25 | bool __dbg_hw_info(void); | ||
26 | bool __dbg_ports(void); | ||
27 | |||
28 | #endif /* __DEBUG_TARGET_H_ */ | ||
diff --git a/firmware/target/mips/ingenic_jz47xx/onda_vx747/ata-sd-target.h b/firmware/target/mips/ingenic_jz47xx/onda_vx747/ata-sd-target.h index aed2b9cfea..d05690000f 100644 --- a/firmware/target/mips/ingenic_jz47xx/onda_vx747/ata-sd-target.h +++ b/firmware/target/mips/ingenic_jz47xx/onda_vx747/ata-sd-target.h | |||
@@ -38,16 +38,20 @@ int _sd_read_sectors(unsigned long start, int count, void* buf); | |||
38 | int _sd_write_sectors(unsigned long start, int count, const void* buf); | 38 | int _sd_write_sectors(unsigned long start, int count, const void* buf); |
39 | int _sd_init(void); | 39 | int _sd_init(void); |
40 | 40 | ||
41 | #define MMC_CD_PIN (29 + 1 * 32) /* Pin to check card insertion */ | 41 | #define MMC_CD_PIN (32*1 + 29) /* Pin to check card insertion */ |
42 | #define MSC_D0 (32*3 + 10) | ||
43 | #define MSC_D1 (32*3 + 11) | ||
44 | #define MSC_D2 (32*3 + 12) | ||
45 | #define MSC_CLK (32*3 + 9 ) | ||
42 | 46 | ||
43 | static inline void mmc_init_gpio(void) | 47 | static inline void mmc_init_gpio(void) |
44 | { | 48 | { |
45 | __gpio_as_msc(); | 49 | __gpio_as_msc(); |
46 | __gpio_as_input(MMC_CD_PIN); | 50 | __gpio_as_input(MMC_CD_PIN); |
47 | //__gpio_enable_pull(32*3+29); | 51 | __gpio_enable_pull(MSC_CLK); |
48 | __gpio_enable_pull(32*3+10); | 52 | __gpio_enable_pull(MSC_D0); |
49 | __gpio_enable_pull(32*3+11); | 53 | __gpio_enable_pull(MSC_D1); |
50 | __gpio_enable_pull(32*3+12); | 54 | __gpio_enable_pull(MSC_D2); |
51 | } | 55 | } |
52 | 56 | ||
53 | #endif | 57 | #endif |
diff --git a/firmware/target/mips/ingenic_jz47xx/onda_vx747/backlight-onda_vx747.c b/firmware/target/mips/ingenic_jz47xx/onda_vx747/backlight-onda_vx747.c index 208236ef95..eec48768b2 100644 --- a/firmware/target/mips/ingenic_jz47xx/onda_vx747/backlight-onda_vx747.c +++ b/firmware/target/mips/ingenic_jz47xx/onda_vx747/backlight-onda_vx747.c | |||
@@ -35,7 +35,7 @@ static bool backlight_on; | |||
35 | 35 | ||
36 | static void set_backlight(int val) | 36 | static void set_backlight(int val) |
37 | { | 37 | { |
38 | (void)val; | 38 | (void)val; |
39 | } | 39 | } |
40 | 40 | ||
41 | bool _backlight_init(void) | 41 | bool _backlight_init(void) |
@@ -153,3 +153,11 @@ void _backlight_set_brightness(int brightness) | |||
153 | set_backlight(brightness); | 153 | set_backlight(brightness); |
154 | } | 154 | } |
155 | #endif | 155 | #endif |
156 | |||
157 | #ifdef HAVE_LCD_SLEEP | ||
158 | /* Turn off LED supply */ | ||
159 | void _backlight_lcd_sleep(void) | ||
160 | { | ||
161 | set_backlight_off(); | ||
162 | } | ||
163 | #endif | ||
diff --git a/firmware/target/mips/ingenic_jz47xx/onda_vx747/backlight-target.h b/firmware/target/mips/ingenic_jz47xx/onda_vx747/backlight-target.h index f3f17f024e..c6647fa9da 100644 --- a/firmware/target/mips/ingenic_jz47xx/onda_vx747/backlight-target.h +++ b/firmware/target/mips/ingenic_jz47xx/onda_vx747/backlight-target.h | |||
@@ -29,10 +29,12 @@ | |||
29 | 29 | ||
30 | #include <stdbool.h> | 30 | #include <stdbool.h> |
31 | 31 | ||
32 | /* | ||
32 | bool _backlight_init(void); | 33 | bool _backlight_init(void); |
33 | void _backlight_on(void); | 34 | void _backlight_on(void); |
34 | void _backlight_off(void); | 35 | void _backlight_off(void); |
35 | void _backlight_set_brightness(int brightness); | 36 | void _backlight_set_brightness(int brightness); |
36 | bool backlight_enabled(void); | 37 | bool backlight_enabled(void); |
38 | */ | ||
37 | 39 | ||
38 | #endif /* BACKLIGHT_TARGET_H */ | 40 | #endif /* BACKLIGHT_TARGET_H */ |
diff --git a/firmware/target/mips/ingenic_jz47xx/onda_vx747/lcd-onda_vx747.c b/firmware/target/mips/ingenic_jz47xx/onda_vx747/lcd-onda_vx747.c index c07a191bbe..cc27a17944 100644 --- a/firmware/target/mips/ingenic_jz47xx/onda_vx747/lcd-onda_vx747.c +++ b/firmware/target/mips/ingenic_jz47xx/onda_vx747/lcd-onda_vx747.c | |||
@@ -26,6 +26,7 @@ | |||
26 | 26 | ||
27 | #define PIN_CS_N (32*1+17) /* Chip select */ | 27 | #define PIN_CS_N (32*1+17) /* Chip select */ |
28 | #define PIN_RESET_N (32*1+18) /* Reset */ | 28 | #define PIN_RESET_N (32*1+18) /* Reset */ |
29 | #define LCD_PCLK (20000000) /* LCD PCLK */ | ||
29 | 30 | ||
30 | #define my__gpio_as_lcd_16bit() \ | 31 | #define my__gpio_as_lcd_16bit() \ |
31 | do { \ | 32 | do { \ |
@@ -199,16 +200,15 @@ static void _set_lcd_bus(void) | |||
199 | static void _set_lcd_clock(void) | 200 | static void _set_lcd_clock(void) |
200 | { | 201 | { |
201 | unsigned int val; | 202 | unsigned int val; |
202 | int pll_div; | ||
203 | 203 | ||
204 | __cpm_stop_lcd(); | 204 | __cpm_stop_lcd(); |
205 | pll_div = ( REG_CPM_CPCCR & CPM_CPCCR_PCS ); /* clock source, 0:pllout/2 1: pllout */ | 205 | |
206 | pll_div = pll_div ? 1 : 2; | 206 | val = __cpm_get_pllout2() / LCD_PCLK; |
207 | val = ( __cpm_get_pllout()/pll_div ) / __cpm_get_pclk(); | ||
208 | val--; | 207 | val--; |
209 | if ( val > 0x1ff ) | 208 | if ( val > 0x1ff ) |
210 | val = 0x1ff; /* CPM_LPCDR is too large, set it to 0x1ff */ | 209 | val = 0x1ff; /* CPM_LPCDR is too large, set it to 0x1ff */ |
211 | __cpm_set_pixdiv(val); | 210 | __cpm_set_pixdiv(val); |
211 | |||
212 | __cpm_start_lcd(); | 212 | __cpm_start_lcd(); |
213 | } | 213 | } |
214 | 214 | ||
@@ -277,3 +277,8 @@ void lcd_off(void) | |||
277 | { | 277 | { |
278 | _display_off(); | 278 | _display_off(); |
279 | } | 279 | } |
280 | |||
281 | void lcd_set_contrast(int val) | ||
282 | { | ||
283 | (void)val; | ||
284 | } | ||
diff --git a/firmware/target/mips/ingenic_jz47xx/onda_vx747/power-onda_vx747.c b/firmware/target/mips/ingenic_jz47xx/onda_vx747/power-onda_vx747.c index 2c77da4ba7..fc77d063f9 100644 --- a/firmware/target/mips/ingenic_jz47xx/onda_vx747/power-onda_vx747.c +++ b/firmware/target/mips/ingenic_jz47xx/onda_vx747/power-onda_vx747.c | |||
@@ -42,3 +42,8 @@ void power_init(void) | |||
42 | { | 42 | { |
43 | __gpio_as_input(USB_CHARGER_GPIO); | 43 | __gpio_as_input(USB_CHARGER_GPIO); |
44 | } | 44 | } |
45 | |||
46 | bool charging_state(void) | ||
47 | { | ||
48 | return false; | ||
49 | } | ||
diff --git a/firmware/target/mips/ingenic_jz47xx/onda_vx747/sadc-onda_vx747.c b/firmware/target/mips/ingenic_jz47xx/onda_vx747/sadc-onda_vx747.c index cd1da694b0..f750efdf57 100644 --- a/firmware/target/mips/ingenic_jz47xx/onda_vx747/sadc-onda_vx747.c +++ b/firmware/target/mips/ingenic_jz47xx/onda_vx747/sadc-onda_vx747.c | |||
@@ -26,6 +26,8 @@ | |||
26 | #include "button-target.h" | 26 | #include "button-target.h" |
27 | #include "powermgmt.h" | 27 | #include "powermgmt.h" |
28 | #include "kernel.h" | 28 | #include "kernel.h" |
29 | #include "backlight.h" | ||
30 | #include "logf.h" | ||
29 | 31 | ||
30 | #ifdef ONDA_VX747 | 32 | #ifdef ONDA_VX747 |
31 | #define BTN_OFF (1 << 29) | 33 | #define BTN_OFF (1 << 29) |
@@ -54,15 +56,16 @@ | |||
54 | (2 << SADC_CFG_CLKOUT_NUM_BIT) | \ | 56 | (2 << SADC_CFG_CLKOUT_NUM_BIT) | \ |
55 | SADC_CFG_XYZ1Z2 | \ | 57 | SADC_CFG_XYZ1Z2 | \ |
56 | SADC_CFG_SNUM | \ | 58 | SADC_CFG_SNUM | \ |
57 | (2 << SADC_CFG_CLKDIV_BIT) | \ | 59 | (1 << SADC_CFG_CLKDIV_BIT) | \ |
58 | SADC_CFG_PBAT_HIGH | \ | 60 | SADC_CFG_PBAT_HIGH | \ |
59 | SADC_CFG_CMD_INT_PEN \ | 61 | SADC_CFG_CMD_INT_PEN \ |
60 | ) | 62 | ) |
61 | 63 | ||
62 | static signed int x_pos, y_pos; | 64 | static signed int x_pos, y_pos; |
63 | static int datacount = 0, cur_touch = 0; | 65 | static int datacount = 0; |
64 | static bool pen_down = false; | 66 | static volatile int cur_touch = 0; |
65 | static volatile unsigned short bat_val = 0; | 67 | static volatile bool pen_down = false; |
68 | static volatile unsigned short bat_val; | ||
66 | static struct mutex battery_mtx; | 69 | static struct mutex battery_mtx; |
67 | 70 | ||
68 | static enum touchscreen_mode current_mode = TOUCHSCREEN_POINT; | 71 | static enum touchscreen_mode current_mode = TOUCHSCREEN_POINT; |
@@ -76,20 +79,20 @@ static const int touchscreen_buttons[3][3] = | |||
76 | const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = | 79 | const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = |
77 | { | 80 | { |
78 | /* TODO */ | 81 | /* TODO */ |
79 | 3400 | 82 | 1400 |
80 | }; | 83 | }; |
81 | 84 | ||
82 | const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] = | 85 | const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] = |
83 | { | 86 | { |
84 | /* TODO */ | 87 | /* TODO */ |
85 | 3300 | 88 | 1300 |
86 | }; | 89 | }; |
87 | 90 | ||
88 | /* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */ | 91 | /* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */ |
89 | const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] = | 92 | const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] = |
90 | { | 93 | { |
91 | /* TODO */ | 94 | /* TODO */ |
92 | { 3300, 3680, 3740, 3760, 3780, 3810, 3870, 3930, 3970, 4070, 4160 }, | 95 | { 1300, 3680, 3740, 3760, 3780, 3810, 3870, 3930, 3970, 4070, 4160 }, |
93 | }; | 96 | }; |
94 | 97 | ||
95 | /* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */ | 98 | /* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */ |
@@ -105,23 +108,34 @@ const unsigned short percent_to_volt_charge[11] = | |||
105 | /* Returns battery voltage from ADC [millivolts] */ | 108 | /* Returns battery voltage from ADC [millivolts] */ |
106 | unsigned int battery_adc_voltage(void) | 109 | unsigned int battery_adc_voltage(void) |
107 | { | 110 | { |
108 | register unsigned short dummy; | 111 | unsigned int val, i; |
109 | 112 | ||
110 | mutex_lock(&battery_mtx); | 113 | mutex_lock(&battery_mtx); |
111 | 114 | ||
112 | dummy = REG_SADC_BATDAT; | 115 | val = REG_SADC_BATDAT; |
113 | dummy = REG_SADC_BATDAT; | 116 | val = REG_SADC_BATDAT; |
114 | 117 | ||
115 | bat_val = 0; | ||
116 | REG_SADC_ENA |= SADC_ENA_PBATEN; | 118 | REG_SADC_ENA |= SADC_ENA_PBATEN; |
119 | for(i=0; i<4; i++) | ||
120 | { | ||
121 | bat_val = 0; | ||
122 | |||
123 | /* primitive wakeup event */ | ||
124 | while(bat_val == 0) | ||
125 | sleep(0); | ||
126 | |||
127 | val += bat_val; | ||
128 | } | ||
129 | REG_SADC_ENA &= ~SADC_ENA_PBATEN; | ||
130 | |||
131 | val /= 4; | ||
117 | 132 | ||
118 | /* primitive wakeup event */ | 133 | logf("%d %d %d", val, (val*BATTERY_SCALE_FACTOR)>>12, |
119 | while(bat_val == 0) | 134 | (val*0xAAAAAAAB >> 32) >> 1); |
120 | yield(); | ||
121 | 135 | ||
122 | mutex_unlock(&battery_mtx); | 136 | mutex_unlock(&battery_mtx); |
123 | 137 | ||
124 | return (bat_val*BATTERY_SCALE_FACTOR)>>12; | 138 | return (val*BATTERY_SCALE_FACTOR)>>12; |
125 | } | 139 | } |
126 | 140 | ||
127 | void button_init_device(void) | 141 | void button_init_device(void) |
@@ -135,11 +149,11 @@ void button_init_device(void) | |||
135 | 149 | ||
136 | system_enable_irq(IRQ_SADC); | 150 | system_enable_irq(IRQ_SADC); |
137 | 151 | ||
138 | REG_SADC_SAMETIME = 350; | 152 | REG_SADC_SAMETIME = 10; |
139 | REG_SADC_WAITTIME = 100; | 153 | REG_SADC_WAITTIME = 100; |
140 | REG_SADC_STATE &= (~REG_SADC_STATE); | 154 | REG_SADC_STATE &= (~REG_SADC_STATE); |
141 | REG_SADC_CTRL = (~(SADC_CTRL_PENDM | SADC_CTRL_PENUM | SADC_CTRL_TSRDYM | SADC_CTRL_PBATRDYM)); | 155 | REG_SADC_CTRL = (~(SADC_CTRL_PENDM | SADC_CTRL_PENUM | SADC_CTRL_TSRDYM | SADC_CTRL_PBATRDYM)); |
142 | REG_SADC_ENA = (SADC_ENA_TSEN | SADC_ENA_PBATEN); | 156 | REG_SADC_ENA = SADC_ENA_TSEN; |
143 | 157 | ||
144 | #ifdef ONDA_VX747 | 158 | #ifdef ONDA_VX747 |
145 | __gpio_as_input(32*3 + 29); | 159 | __gpio_as_input(32*3 + 29); |
@@ -213,19 +227,24 @@ int button_read_device(int *data) | |||
213 | if(tmp & BTN_OFF) | 227 | if(tmp & BTN_OFF) |
214 | ret |= BUTTON_POWER; | 228 | ret |= BUTTON_POWER; |
215 | 229 | ||
216 | if(current_mode == TOUCHSCREEN_BUTTON && cur_touch != 0) | 230 | if(cur_touch != 0) |
217 | { | ||
218 | int px_x = cur_touch >> 16; | ||
219 | int px_y = cur_touch & 0xFFFF; | ||
220 | ret |= touchscreen_buttons[px_y/(LCD_HEIGHT/3)] | ||
221 | [px_x/(LCD_WIDTH/3)]; | ||
222 | } | ||
223 | else if(pen_down) | ||
224 | { | 231 | { |
225 | ret |= BUTTON_TOUCH; | 232 | if(current_mode == TOUCHSCREEN_BUTTON) |
226 | if(data != NULL && cur_touch != 0) | 233 | { |
234 | int px_x = cur_touch >> 16; | ||
235 | int px_y = cur_touch & 0xFFFF; | ||
236 | ret |= touchscreen_buttons[px_y/(LCD_HEIGHT/3)] | ||
237 | [px_x/(LCD_WIDTH/3)]; | ||
238 | } | ||
239 | else if(pen_down) | ||
240 | { | ||
241 | ret |= BUTTON_TOUCHSCREEN; | ||
227 | *data = cur_touch; | 242 | *data = cur_touch; |
243 | } | ||
228 | } | 244 | } |
245 | |||
246 | if(ret & BUTTON_TOUCHSCREEN && !is_backlight_on(true)) | ||
247 | *data = 0; | ||
229 | 248 | ||
230 | return ret; | 249 | return ret; |
231 | } | 250 | } |
@@ -299,15 +318,17 @@ void SADC(void) | |||
299 | x_pos += xData; | 318 | x_pos += xData; |
300 | y_pos += yData; | 319 | y_pos += yData; |
301 | } | 320 | } |
321 | |||
322 | datacount++; | ||
323 | |||
324 | if(datacount >= TS_AD_COUNT) | ||
325 | { | ||
326 | cur_touch = touch_to_pixels(x_pos/datacount, y_pos/datacount); | ||
327 | datacount = 0; | ||
328 | } | ||
302 | } | 329 | } |
303 | 330 | else | |
304 | datacount++; | ||
305 | |||
306 | if(datacount >= TS_AD_COUNT) | ||
307 | { | ||
308 | cur_touch = touch_to_pixels(x_pos/datacount, y_pos/datacount); | ||
309 | datacount = 0; | 331 | datacount = 0; |
310 | } | ||
311 | } | 332 | } |
312 | 333 | ||
313 | if(state & SADC_CTRL_PBATRDYM) | 334 | if(state & SADC_CTRL_PBATRDYM) |
@@ -316,3 +337,7 @@ void SADC(void) | |||
316 | /* Battery AD IRQ */ | 337 | /* Battery AD IRQ */ |
317 | } | 338 | } |
318 | } | 339 | } |
340 | |||
341 | void adc_init(void) | ||
342 | { | ||
343 | } | ||
diff --git a/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c b/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c index 1ed36cd312..b649311d13 100644 --- a/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c | |||
@@ -113,7 +113,8 @@ size_t pcm_get_bytes_waiting(void) | |||
113 | const void * pcm_play_dma_get_peak_buffer(int *count) | 113 | const void * pcm_play_dma_get_peak_buffer(int *count) |
114 | { | 114 | { |
115 | /* TODO */ | 115 | /* TODO */ |
116 | *count = REG_DMAC_DTCR(DMA_AIC_TX_CHANNEL)>>2; | 116 | //*count = REG_DMAC_DTCR(DMA_AIC_TX_CHANNEL)>>2; |
117 | *count = 0; | ||
117 | return NULL; | 118 | return NULL; |
118 | } | 119 | } |
119 | 120 | ||
diff --git a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c index c0f39a4933..e37f17c73f 100644 --- a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c | |||
@@ -22,11 +22,9 @@ | |||
22 | #include "config.h" | 22 | #include "config.h" |
23 | #include "jz4740.h" | 23 | #include "jz4740.h" |
24 | #include "mips.h" | 24 | #include "mips.h" |
25 | #include "mipsregs.h" | ||
26 | #include "mmu-mips.h" | 25 | #include "mmu-mips.h" |
27 | #include "panic.h" | 26 | #include "panic.h" |
28 | #include "system.h" | 27 | #include "system.h" |
29 | #include "string.h" | ||
30 | #include "kernel.h" | 28 | #include "kernel.h" |
31 | 29 | ||
32 | #define NUM_DMA 6 | 30 | #define NUM_DMA 6 |
@@ -36,165 +34,40 @@ | |||
36 | static int irq; | 34 | static int irq; |
37 | static void UIRQ(void) | 35 | static void UIRQ(void) |
38 | { | 36 | { |
39 | panicf("Unhandled interrupt occurred: %d\n", irq); | 37 | panicf("Unhandled interrupt occurred: %d", irq); |
40 | } | 38 | } |
41 | 39 | ||
42 | #define default_interrupt(name) \ | 40 | #define intr(name) extern __attribute__((weak,alias("UIRQ"))) void name (void) |
43 | extern __attribute__((weak,alias("UIRQ"))) void name (void) | 41 | |
44 | 42 | intr(I2C);intr(EMC);intr(UHC);intr(UART0);intr(SADC);intr(MSC);intr(RTC); | |
45 | default_interrupt(I2C); | 43 | intr(SSI);intr(CIM);intr(AIC);intr(ETH);intr(TCU2);intr(TCU1);intr(TCU0); |
46 | default_interrupt(EMC); | 44 | intr(UDC);intr(IPU);intr(LCD); |
47 | default_interrupt(UHC); | 45 | |
48 | default_interrupt(UART0); | 46 | intr(DMA0);intr(DMA1);intr(DMA2);intr(DMA3);intr(DMA4);intr(DMA5); |
49 | default_interrupt(SADC); | 47 | |
50 | default_interrupt(MSC); | 48 | intr(GPIO0);intr(GPIO1);intr(GPIO2);intr(GPIO3);intr(GPIO4);intr(GPIO5); |
51 | default_interrupt(RTC); | 49 | intr(GPIO6);intr(GPIO7);intr(GPIO8);intr(GPIO9);intr(GPIO10);intr(GPIO11); |
52 | default_interrupt(SSI); | 50 | intr(GPIO12);intr(GPIO13);intr(GPIO14);intr(GPIO15);intr(GPIO16);intr(GPIO17); |
53 | default_interrupt(CIM); | 51 | intr(GPIO18);intr(GPIO19);intr(GPIO20);intr(GPIO21);intr(GPIO22);intr(GPIO23); |
54 | default_interrupt(AIC); | 52 | intr(GPIO24);intr(GPIO25);intr(GPIO26);intr(GPIO27);intr(GPIO28);intr(GPIO29); |
55 | default_interrupt(ETH); | 53 | intr(GPIO30);intr(GPIO31);intr(GPIO32);intr(GPIO33);intr(GPIO34);intr(GPIO35); |
56 | default_interrupt(TCU2); | 54 | intr(GPIO36);intr(GPIO37);intr(GPIO38);intr(GPIO39);intr(GPIO40);intr(GPIO41); |
57 | default_interrupt(TCU1); | 55 | intr(GPIO42);intr(GPIO43);intr(GPIO44);intr(GPIO45);intr(GPIO46);intr(GPIO47); |
58 | default_interrupt(TCU0); | 56 | intr(GPIO48);intr(GPIO49);intr(GPIO50);intr(GPIO51);intr(GPIO52);intr(GPIO53); |
59 | default_interrupt(UDC); | 57 | intr(GPIO54);intr(GPIO55);intr(GPIO56);intr(GPIO57);intr(GPIO58);intr(GPIO59); |
60 | default_interrupt(IPU); | 58 | intr(GPIO60);intr(GPIO61);intr(GPIO62);intr(GPIO63);intr(GPIO64);intr(GPIO65); |
61 | default_interrupt(LCD); | 59 | intr(GPIO66);intr(GPIO67);intr(GPIO68);intr(GPIO69);intr(GPIO70);intr(GPIO71); |
62 | 60 | intr(GPIO72);intr(GPIO73);intr(GPIO74);intr(GPIO75);intr(GPIO76);intr(GPIO77); | |
63 | default_interrupt(DMA0); | 61 | intr(GPIO78);intr(GPIO79);intr(GPIO80);intr(GPIO81);intr(GPIO82);intr(GPIO83); |
64 | default_interrupt(DMA1); | 62 | intr(GPIO84);intr(GPIO85);intr(GPIO86);intr(GPIO87);intr(GPIO88);intr(GPIO89); |
65 | default_interrupt(DMA2); | 63 | intr(GPIO90);intr(GPIO91);intr(GPIO92);intr(GPIO93);intr(GPIO94);intr(GPIO95); |
66 | default_interrupt(DMA3); | 64 | intr(GPIO96);intr(GPIO97);intr(GPIO98);intr(GPIO99);intr(GPIO100);intr(GPIO101); |
67 | default_interrupt(DMA4); | 65 | intr(GPIO102);intr(GPIO103);intr(GPIO104);intr(GPIO105);intr(GPIO106); |
68 | default_interrupt(DMA5); | 66 | intr(GPIO107);intr(GPIO108);intr(GPIO109);intr(GPIO110);intr(GPIO111); |
69 | 67 | intr(GPIO112);intr(GPIO113);intr(GPIO114);intr(GPIO115);intr(GPIO116); | |
70 | default_interrupt(GPIO0); | 68 | intr(GPIO117);intr(GPIO118);intr(GPIO119);intr(GPIO120);intr(GPIO121); |
71 | default_interrupt(GPIO1); | 69 | intr(GPIO122);intr(GPIO123);intr(GPIO124);intr(GPIO125);intr(GPIO126); |
72 | default_interrupt(GPIO2); | 70 | intr(GPIO127); |
73 | default_interrupt(GPIO3); | ||
74 | default_interrupt(GPIO4); | ||
75 | default_interrupt(GPIO5); | ||
76 | default_interrupt(GPIO6); | ||
77 | default_interrupt(GPIO7); | ||
78 | default_interrupt(GPIO8); | ||
79 | default_interrupt(GPIO9); | ||
80 | default_interrupt(GPIO10); | ||
81 | default_interrupt(GPIO11); | ||
82 | default_interrupt(GPIO12); | ||
83 | default_interrupt(GPIO13); | ||
84 | default_interrupt(GPIO14); | ||
85 | default_interrupt(GPIO15); | ||
86 | default_interrupt(GPIO16); | ||
87 | default_interrupt(GPIO17); | ||
88 | default_interrupt(GPIO18); | ||
89 | default_interrupt(GPIO19); | ||
90 | default_interrupt(GPIO20); | ||
91 | default_interrupt(GPIO21); | ||
92 | default_interrupt(GPIO22); | ||
93 | default_interrupt(GPIO23); | ||
94 | default_interrupt(GPIO24); | ||
95 | default_interrupt(GPIO25); | ||
96 | default_interrupt(GPIO26); | ||
97 | default_interrupt(GPIO27); | ||
98 | default_interrupt(GPIO28); | ||
99 | default_interrupt(GPIO29); | ||
100 | default_interrupt(GPIO30); | ||
101 | default_interrupt(GPIO31); | ||
102 | default_interrupt(GPIO32); | ||
103 | default_interrupt(GPIO33); | ||
104 | default_interrupt(GPIO34); | ||
105 | default_interrupt(GPIO35); | ||
106 | default_interrupt(GPIO36); | ||
107 | default_interrupt(GPIO37); | ||
108 | default_interrupt(GPIO38); | ||
109 | default_interrupt(GPIO39); | ||
110 | default_interrupt(GPIO40); | ||
111 | default_interrupt(GPIO41); | ||
112 | default_interrupt(GPIO42); | ||
113 | default_interrupt(GPIO43); | ||
114 | default_interrupt(GPIO44); | ||
115 | default_interrupt(GPIO45); | ||
116 | default_interrupt(GPIO46); | ||
117 | default_interrupt(GPIO47); | ||
118 | default_interrupt(GPIO48); | ||
119 | default_interrupt(GPIO49); | ||
120 | default_interrupt(GPIO50); | ||
121 | default_interrupt(GPIO51); | ||
122 | default_interrupt(GPIO52); | ||
123 | default_interrupt(GPIO53); | ||
124 | default_interrupt(GPIO54); | ||
125 | default_interrupt(GPIO55); | ||
126 | default_interrupt(GPIO56); | ||
127 | default_interrupt(GPIO57); | ||
128 | default_interrupt(GPIO58); | ||
129 | default_interrupt(GPIO59); | ||
130 | default_interrupt(GPIO60); | ||
131 | default_interrupt(GPIO61); | ||
132 | default_interrupt(GPIO62); | ||
133 | default_interrupt(GPIO63); | ||
134 | default_interrupt(GPIO64); | ||
135 | default_interrupt(GPIO65); | ||
136 | default_interrupt(GPIO66); | ||
137 | default_interrupt(GPIO67); | ||
138 | default_interrupt(GPIO68); | ||
139 | default_interrupt(GPIO69); | ||
140 | default_interrupt(GPIO70); | ||
141 | default_interrupt(GPIO71); | ||
142 | default_interrupt(GPIO72); | ||
143 | default_interrupt(GPIO73); | ||
144 | default_interrupt(GPIO74); | ||
145 | default_interrupt(GPIO75); | ||
146 | default_interrupt(GPIO76); | ||
147 | default_interrupt(GPIO77); | ||
148 | default_interrupt(GPIO78); | ||
149 | default_interrupt(GPIO79); | ||
150 | default_interrupt(GPIO80); | ||
151 | default_interrupt(GPIO81); | ||
152 | default_interrupt(GPIO82); | ||
153 | default_interrupt(GPIO83); | ||
154 | default_interrupt(GPIO84); | ||
155 | default_interrupt(GPIO85); | ||
156 | default_interrupt(GPIO86); | ||
157 | default_interrupt(GPIO87); | ||
158 | default_interrupt(GPIO88); | ||
159 | default_interrupt(GPIO89); | ||
160 | default_interrupt(GPIO90); | ||
161 | default_interrupt(GPIO91); | ||
162 | default_interrupt(GPIO92); | ||
163 | default_interrupt(GPIO93); | ||
164 | default_interrupt(GPIO94); | ||
165 | default_interrupt(GPIO95); | ||
166 | default_interrupt(GPIO96); | ||
167 | default_interrupt(GPIO97); | ||
168 | default_interrupt(GPIO98); | ||
169 | default_interrupt(GPIO99); | ||
170 | default_interrupt(GPIO100); | ||
171 | default_interrupt(GPIO101); | ||
172 | default_interrupt(GPIO102); | ||
173 | default_interrupt(GPIO103); | ||
174 | default_interrupt(GPIO104); | ||
175 | default_interrupt(GPIO105); | ||
176 | default_interrupt(GPIO106); | ||
177 | default_interrupt(GPIO107); | ||
178 | default_interrupt(GPIO108); | ||
179 | default_interrupt(GPIO109); | ||
180 | default_interrupt(GPIO110); | ||
181 | default_interrupt(GPIO111); | ||
182 | default_interrupt(GPIO112); | ||
183 | default_interrupt(GPIO113); | ||
184 | default_interrupt(GPIO114); | ||
185 | default_interrupt(GPIO115); | ||
186 | default_interrupt(GPIO116); | ||
187 | default_interrupt(GPIO117); | ||
188 | default_interrupt(GPIO118); | ||
189 | default_interrupt(GPIO119); | ||
190 | default_interrupt(GPIO120); | ||
191 | default_interrupt(GPIO121); | ||
192 | default_interrupt(GPIO122); | ||
193 | default_interrupt(GPIO123); | ||
194 | default_interrupt(GPIO124); | ||
195 | default_interrupt(GPIO125); | ||
196 | default_interrupt(GPIO126); | ||
197 | default_interrupt(GPIO127); | ||
198 | 71 | ||
199 | static void (* const irqvector[])(void) = | 72 | static void (* const irqvector[])(void) = |
200 | { | 73 | { |
@@ -281,17 +154,16 @@ static void ack_irq(unsigned int irq) | |||
281 | __intc_ack_irq(irq); | 154 | __intc_ack_irq(irq); |
282 | } | 155 | } |
283 | 156 | ||
284 | static unsigned long ipl; | ||
285 | static int get_irq_number(void) | 157 | static int get_irq_number(void) |
286 | { | 158 | { |
287 | register int irq = 0; | 159 | static unsigned long ipl; |
160 | register int irq; | ||
288 | 161 | ||
289 | ipl |= REG_INTC_IPR; | 162 | ipl |= REG_INTC_IPR; |
290 | 163 | ||
291 | if (ipl == 0) | 164 | if (ipl == 0) |
292 | return -1; | 165 | return -1; |
293 | 166 | ||
294 | /* find out the real irq defined in irq_xxx.c */ | ||
295 | for (irq = 31; irq >= 0; irq--) | 167 | for (irq = 31; irq >= 0; irq--) |
296 | if (ipl & (1 << irq)) | 168 | if (ipl & (1 << irq)) |
297 | break; | 169 | break; |
@@ -369,15 +241,14 @@ void exception_handler(void* stack_ptr, unsigned int cause, unsigned int epc) | |||
369 | panicf("Exception occurred: %s [0x%08x] at 0x%08x (stack at 0x%08x)", parse_exception(cause), cause, epc, (unsigned int)stack_ptr); | 241 | panicf("Exception occurred: %s [0x%08x] at 0x%08x (stack at 0x%08x)", parse_exception(cause), cause, epc, (unsigned int)stack_ptr); |
370 | } | 242 | } |
371 | 243 | ||
372 | static unsigned int iclk; | 244 | void tlb_refill_handler(void) |
373 | static void detect_clock(void) | ||
374 | { | 245 | { |
375 | iclk = __cpm_get_cclk(); | 246 | panicf("TLB refill handler at 0x%08lx! [0x%x]", read_c0_epc(), read_c0_badvaddr()); |
376 | } | 247 | } |
377 | 248 | ||
378 | void udelay(unsigned int usec) | 249 | void udelay(unsigned int usec) |
379 | { | 250 | { |
380 | unsigned int i = usec * (iclk / 2000000); | 251 | unsigned int i = usec * (__cpm_get_cclk() / 2000000); |
381 | __asm__ __volatile__ ( | 252 | __asm__ __volatile__ ( |
382 | ".set noreorder \n" | 253 | ".set noreorder \n" |
383 | "1: \n" | 254 | "1: \n" |
@@ -396,135 +267,6 @@ void mdelay(unsigned int msec) | |||
396 | udelay(1000); | 267 | udelay(1000); |
397 | } | 268 | } |
398 | 269 | ||
399 | /* Core-level interrupt masking */ | ||
400 | void clear_interrupts(void) | ||
401 | { | ||
402 | register unsigned int t; | ||
403 | t = read_c0_status(); | ||
404 | t &= ~1; | ||
405 | write_c0_status(t); | ||
406 | } | ||
407 | |||
408 | unsigned int mips_get_sr(void) | ||
409 | { | ||
410 | return read_c0_status(); | ||
411 | } | ||
412 | |||
413 | void store_interrupts(void) | ||
414 | { | ||
415 | register unsigned int t; | ||
416 | t = read_c0_status(); | ||
417 | t |= 1; | ||
418 | t &= ~2; | ||
419 | write_c0_status(t); | ||
420 | } | ||
421 | |||
422 | #define Index_Invalidate_I 0x00 | ||
423 | #define Index_Writeback_Inv_D 0x01 | ||
424 | #define Index_Load_Tag_I 0x04 | ||
425 | #define Index_Load_Tag_D 0x05 | ||
426 | #define Index_Store_Tag_I 0x08 | ||
427 | #define Index_Store_Tag_D 0x09 | ||
428 | #define Hit_Invalidate_I 0x10 | ||
429 | #define Hit_Invalidate_D 0x11 | ||
430 | #define Hit_Writeback_Inv_D 0x15 | ||
431 | #define Hit_Writeback_I 0x18 | ||
432 | #define Hit_Writeback_D 0x19 | ||
433 | |||
434 | #define CACHE_SIZE 16*1024 | ||
435 | #define CACHE_LINE_SIZE 32 | ||
436 | #define KSEG0 0x80000000 | ||
437 | |||
438 | #define SYNC_WB() __asm__ __volatile__ ("sync") | ||
439 | |||
440 | #define __CACHE_OP(op, addr) \ | ||
441 | __asm__ __volatile__( \ | ||
442 | " .set noreorder \n" \ | ||
443 | " .set mips32\n\t \n" \ | ||
444 | " cache %0, %1 \n" \ | ||
445 | " .set mips0 \n" \ | ||
446 | " .set reorder \n" \ | ||
447 | : \ | ||
448 | : "i" (op), "m" (*(unsigned char *)(addr))) | ||
449 | |||
450 | void __flush_dcache_line(unsigned long addr) | ||
451 | { | ||
452 | __CACHE_OP(Hit_Writeback_Inv_D, addr); | ||
453 | SYNC_WB(); | ||
454 | } | ||
455 | |||
456 | void __icache_invalidate_all(void) | ||
457 | { | ||
458 | unsigned int i; | ||
459 | |||
460 | asm volatile (".set noreorder \n" | ||
461 | ".set mips32 \n" | ||
462 | "mtc0 $0, $28 \n" /* TagLo */ | ||
463 | "mtc0 $0, $29 \n" /* TagHi */ | ||
464 | ".set mips0 \n" | ||
465 | ".set reorder \n" | ||
466 | ); | ||
467 | for(i=KSEG0; i<KSEG0+CACHE_SIZE; i+=CACHE_LINE_SIZE) | ||
468 | __CACHE_OP(Index_Store_Tag_I, i); | ||
469 | |||
470 | /* invalidate btb */ | ||
471 | asm volatile ( | ||
472 | ".set mips32 \n" | ||
473 | "mfc0 %0, $16, 7 \n" | ||
474 | "nop \n" | ||
475 | "ori %0, 2 \n" | ||
476 | "mtc0 %0, $16, 7 \n" | ||
477 | ".set mips0 \n" | ||
478 | : | ||
479 | : "r" (i)); | ||
480 | } | ||
481 | |||
482 | void __dcache_invalidate_all(void) | ||
483 | { | ||
484 | unsigned int i; | ||
485 | |||
486 | asm volatile (".set noreorder \n" | ||
487 | ".set mips32 \n" | ||
488 | "mtc0 $0, $28 \n" | ||
489 | "mtc0 $0, $29 \n" | ||
490 | ".set mips0 \n" | ||
491 | ".set reorder \n" | ||
492 | ); | ||
493 | for (i=KSEG0; i<KSEG0+CACHE_SIZE; i+=CACHE_LINE_SIZE) | ||
494 | __CACHE_OP(Index_Store_Tag_D, i); | ||
495 | } | ||
496 | |||
497 | void __dcache_writeback_all(void) | ||
498 | { | ||
499 | unsigned int i; | ||
500 | for(i=KSEG0; i<KSEG0+CACHE_SIZE; i+=CACHE_LINE_SIZE) | ||
501 | __CACHE_OP(Index_Writeback_Inv_D, i); | ||
502 | |||
503 | SYNC_WB(); | ||
504 | } | ||
505 | |||
506 | void dma_cache_wback_inv(unsigned long addr, unsigned long size) | ||
507 | { | ||
508 | unsigned long end, a; | ||
509 | |||
510 | if (size >= CACHE_SIZE) | ||
511 | __dcache_writeback_all(); | ||
512 | else | ||
513 | { | ||
514 | unsigned long dc_lsize = CACHE_LINE_SIZE; | ||
515 | |||
516 | a = addr & ~(dc_lsize - 1); | ||
517 | end = (addr + size - 1) & ~(dc_lsize - 1); | ||
518 | for(; a < end; a += dc_lsize) | ||
519 | __flush_dcache_line(a); /* Hit_Writeback_Inv_D */ | ||
520 | } | ||
521 | } | ||
522 | |||
523 | void tlb_refill_handler(void) | ||
524 | { | ||
525 | panicf("TLB refill handler at 0x%08lx! [0x%x]", read_c0_epc(), read_c0_badvaddr()); | ||
526 | } | ||
527 | |||
528 | static int dma_count = 0; | 270 | static int dma_count = 0; |
529 | void dma_enable(void) | 271 | void dma_enable(void) |
530 | { | 272 | { |
@@ -718,9 +460,8 @@ static void sdram_init(void) | |||
718 | /* everything is ok now */ | 460 | /* everything is ok now */ |
719 | } | 461 | } |
720 | 462 | ||
721 | extern int main(void); | 463 | /* Gets called *before* main */ |
722 | void system_main(void) ICODE_ATTR; | 464 | void ICODE_ATTR system_main(void) |
723 | void system_main(void) | ||
724 | { | 465 | { |
725 | int i; | 466 | int i; |
726 | 467 | ||
@@ -733,24 +474,16 @@ void system_main(void) | |||
733 | for(i=0; i<IRQ_MAX; i++) | 474 | for(i=0; i<IRQ_MAX; i++) |
734 | dis_irq(i); | 475 | dis_irq(i); |
735 | 476 | ||
736 | tlb_init(); | 477 | mmu_init(); |
737 | 478 | pll_init(); | |
738 | //pll_init(); | 479 | sdram_init(); |
739 | //sdram_init(); | ||
740 | |||
741 | detect_clock(); | ||
742 | 480 | ||
743 | /* Disable unneeded clocks, clocks are enabled when needed */ | 481 | /* Disable unneeded clocks, clocks are enabled when needed */ |
744 | __cpm_stop_all(); | 482 | __cpm_stop_all(); |
745 | __cpm_suspend_usbhost(); | 483 | __cpm_suspend_usbhost(); |
746 | 484 | ||
747 | /* Enable interrupts at core level */ | 485 | /* Enable interrupts at core level */ |
748 | store_interrupts(); | 486 | enable_interrupt(); |
749 | |||
750 | main(); /* Shouldn't return */ | ||
751 | |||
752 | while(1) | ||
753 | core_idle(); | ||
754 | } | 487 | } |
755 | 488 | ||
756 | void system_reboot(void) | 489 | void system_reboot(void) |
@@ -781,8 +514,8 @@ void power_off(void) | |||
781 | __rtc_clear_hib_stat_all(); | 514 | __rtc_clear_hib_stat_all(); |
782 | /* __rtc_set_scratch_pattern(0x12345678); */ | 515 | /* __rtc_set_scratch_pattern(0x12345678); */ |
783 | __rtc_enable_alarm_wakeup(); | 516 | __rtc_enable_alarm_wakeup(); |
784 | __rtc_set_hrcr_val(0xfe0); | 517 | __rtc_set_hrcr_val(0xFE0); |
785 | __rtc_set_hwfcr_val((0xFFFF << 4)); | 518 | __rtc_set_hwfcr_val(0xFFFF << 4); |
786 | __rtc_power_down(); | 519 | __rtc_power_down(); |
787 | 520 | ||
788 | while(1); | 521 | while(1); |
diff --git a/firmware/target/mips/ingenic_jz47xx/system-target.h b/firmware/target/mips/ingenic_jz47xx/system-target.h index 6b505d6178..df9b103309 100644 --- a/firmware/target/mips/ingenic_jz47xx/system-target.h +++ b/firmware/target/mips/ingenic_jz47xx/system-target.h | |||
@@ -26,12 +26,11 @@ | |||
26 | #include "jz4740.h" | 26 | #include "jz4740.h" |
27 | #include "mipsregs.h" | 27 | #include "mipsregs.h" |
28 | 28 | ||
29 | /* This one returns the old status */ | 29 | #define CACHE_SIZE 16*1024 |
30 | #define HIGHEST_IRQ_LEVEL 0 | 30 | #define CACHE_LINE_SIZE 32 |
31 | 31 | #include "mmu-mips.h" | |
32 | #define set_irq_level(status) \ | ||
33 | set_interrupt_status((status), ST0_IE) | ||
34 | 32 | ||
33 | /* This one returns the old status */ | ||
35 | static inline int set_interrupt_status(int status, int mask) | 34 | static inline int set_interrupt_status(int status, int mask) |
36 | { | 35 | { |
37 | unsigned int res, oldstatus; | 36 | unsigned int res, oldstatus; |
@@ -56,48 +55,32 @@ static inline void disable_interrupt(void) | |||
56 | clear_c0_status(ST0_IE); | 55 | clear_c0_status(ST0_IE); |
57 | } | 56 | } |
58 | 57 | ||
59 | #define disable_irq() \ | ||
60 | disable_interrupt() | ||
61 | |||
62 | #define enable_irq() \ | ||
63 | enable_interrupt() | ||
64 | |||
65 | static inline int disable_interrupt_save(int mask) | 58 | static inline int disable_interrupt_save(int mask) |
66 | { | 59 | { |
67 | unsigned int oldstatus; | 60 | return set_interrupt_status(0, mask); |
68 | |||
69 | oldstatus = read_c0_status(); | ||
70 | write_c0_status(oldstatus & ~mask); | ||
71 | |||
72 | return oldstatus; | ||
73 | } | 61 | } |
74 | 62 | ||
75 | #define disable_irq_save() \ | ||
76 | disable_interrupt_save(ST0_IE) | ||
77 | |||
78 | static inline void restore_interrupt(int status) | 63 | static inline void restore_interrupt(int status) |
79 | { | 64 | { |
80 | write_c0_status(status); | 65 | write_c0_status(status); |
81 | } | 66 | } |
82 | 67 | ||
83 | #define restore_irq(c0_status) \ | 68 | #define disable_irq() disable_interrupt() |
84 | restore_interrupt(c0_status) | 69 | #define enable_irq() enable_interrupt() |
70 | #define HIGHEST_IRQ_LEVEL 0 | ||
71 | #define set_irq_level(status) set_interrupt_status((status), ST0_IE) | ||
72 | #define disable_irq_save() disable_interrupt_save(ST0_IE) | ||
73 | #define restore_irq(c0_status) restore_interrupt(c0_status) | ||
85 | 74 | ||
86 | #define swap16(x) (((x) & 0xff) << 8 | ((x) >> 8) & 0xff) | 75 | #define swap16(x) (((x) & 0xff) << 8 | ((x) >> 8) & 0xff) |
87 | #define swap32(x) (((x) & 0xff) << 24 | ((x) & 0xff00) << 8 | ((x) & 0xff0000) >> 8 | ((x) >> 24) & 0xff) | 76 | #define swap32(x) (((x) & 0xff) << 24 | ((x) & 0xff00) << 8 | \ |
77 | ((x) & 0xff0000) >> 8 | ((x) >> 24) & 0xff) | ||
88 | 78 | ||
89 | #define UNCACHED_ADDRESS(addr) ((unsigned int)(addr) | 0xA0000000) | 79 | #define UNCACHED_ADDRESS(addr) ((unsigned int)(addr) | 0xA0000000) |
90 | #define UNCACHED_ADDR(x) UNCACHED_ADDRESS((x)) | 80 | #define UNCACHED_ADDR(x) UNCACHED_ADDRESS((x)) |
91 | #define PHYSADDR(x) ((x) & 0x1fffffff) | 81 | #define PHYSADDR(x) ((x) & 0x1fffffff) |
92 | 82 | ||
93 | void __dcache_writeback_all(void); | ||
94 | void __dcache_invalidate_all(void); | ||
95 | void __icache_invalidate_all(void); | ||
96 | void __flush_dcache_line(unsigned long addr); | ||
97 | void dma_cache_wback_inv(unsigned long addr, unsigned long size); | ||
98 | void system_enable_irq(unsigned int irq); | 83 | void system_enable_irq(unsigned int irq); |
99 | void store_interrupts(void); | ||
100 | void clear_interrupts(void); | ||
101 | void udelay(unsigned int usec); | 84 | void udelay(unsigned int usec); |
102 | void mdelay(unsigned int msec); | 85 | void mdelay(unsigned int msec); |
103 | void power_off(void); | 86 | void power_off(void); |
diff --git a/firmware/target/mips/mmu-mips.c b/firmware/target/mips/mmu-mips.c index 570b209e3a..2f7f19d3b3 100644 --- a/firmware/target/mips/mmu-mips.c +++ b/firmware/target/mips/mmu-mips.c | |||
@@ -112,7 +112,7 @@ void map_address(unsigned long virtual, unsigned long physical, | |||
112 | add_wired_entry(entry0, entry1, entryhi, DEFAULT_PAGE_MASK); | 112 | add_wired_entry(entry0, entry1, entryhi, DEFAULT_PAGE_MASK); |
113 | } | 113 | } |
114 | 114 | ||
115 | void tlb_init(void) | 115 | void mmu_init(void) |
116 | { | 116 | { |
117 | write_c0_pagemask(DEFAULT_PAGE_MASK); | 117 | write_c0_pagemask(DEFAULT_PAGE_MASK); |
118 | write_c0_wired(0); | 118 | write_c0_wired(0); |
@@ -124,3 +124,93 @@ void tlb_init(void) | |||
124 | map_address(0x80004000, 0x80004000, MEM * 0x100000, K_CacheAttrC); | 124 | map_address(0x80004000, 0x80004000, MEM * 0x100000, K_CacheAttrC); |
125 | */ | 125 | */ |
126 | } | 126 | } |
127 | |||
128 | #define SYNC_WB() __asm__ __volatile__ ("sync") | ||
129 | |||
130 | #define __CACHE_OP(op, addr) \ | ||
131 | __asm__ __volatile__( \ | ||
132 | " .set noreorder \n" \ | ||
133 | " .set mips32\n\t \n" \ | ||
134 | " cache %0, %1 \n" \ | ||
135 | " .set mips0 \n" \ | ||
136 | " .set reorder \n" \ | ||
137 | : \ | ||
138 | : "i" (op), "m" (*(unsigned char *)(addr))) | ||
139 | |||
140 | void __flush_dcache_line(unsigned long addr) | ||
141 | { | ||
142 | __CACHE_OP(DCHitWBInv, addr); | ||
143 | SYNC_WB(); | ||
144 | } | ||
145 | |||
146 | void __icache_invalidate_all(void) | ||
147 | { | ||
148 | unsigned int i; | ||
149 | |||
150 | asm volatile (".set noreorder \n" | ||
151 | ".set mips32 \n" | ||
152 | "mtc0 $0, $28 \n" /* TagLo */ | ||
153 | "mtc0 $0, $29 \n" /* TagHi */ | ||
154 | ".set mips0 \n" | ||
155 | ".set reorder \n" | ||
156 | ); | ||
157 | for(i=A_K0BASE; i<A_K0BASE+CACHE_SIZE; i+=CACHE_LINE_SIZE) | ||
158 | __CACHE_OP(ICIndexStTag, i); | ||
159 | |||
160 | /* invalidate btb */ | ||
161 | asm volatile ( | ||
162 | ".set mips32 \n" | ||
163 | "mfc0 %0, $16, 7 \n" | ||
164 | "nop \n" | ||
165 | "ori %0, 2 \n" | ||
166 | "mtc0 %0, $16, 7 \n" | ||
167 | ".set mips0 \n" | ||
168 | : | ||
169 | : "r" (i)); | ||
170 | } | ||
171 | |||
172 | void cpucache_invalidate(void) | ||
173 | { | ||
174 | __icache_invalidate_all(); | ||
175 | } | ||
176 | |||
177 | void __dcache_invalidate_all(void) | ||
178 | { | ||
179 | unsigned int i; | ||
180 | |||
181 | asm volatile (".set noreorder \n" | ||
182 | ".set mips32 \n" | ||
183 | "mtc0 $0, $28 \n" | ||
184 | "mtc0 $0, $29 \n" | ||
185 | ".set mips0 \n" | ||
186 | ".set reorder \n" | ||
187 | ); | ||
188 | for (i=A_K0BASE; i<A_K0BASE+CACHE_SIZE; i+=CACHE_LINE_SIZE) | ||
189 | __CACHE_OP(DCIndexStTag, i); | ||
190 | } | ||
191 | |||
192 | void __dcache_writeback_all(void) | ||
193 | { | ||
194 | unsigned int i; | ||
195 | for(i=A_K0BASE; i<A_K0BASE+CACHE_SIZE; i+=CACHE_LINE_SIZE) | ||
196 | __CACHE_OP(DCIndexWBInv, i); | ||
197 | |||
198 | SYNC_WB(); | ||
199 | } | ||
200 | |||
201 | void dma_cache_wback_inv(unsigned long addr, unsigned long size) | ||
202 | { | ||
203 | unsigned long end, a; | ||
204 | |||
205 | if (size >= CACHE_SIZE) | ||
206 | __dcache_writeback_all(); | ||
207 | else | ||
208 | { | ||
209 | unsigned long dc_lsize = CACHE_LINE_SIZE; | ||
210 | |||
211 | a = addr & ~(dc_lsize - 1); | ||
212 | end = (addr + size - 1) & ~(dc_lsize - 1); | ||
213 | for(; a < end; a += dc_lsize) | ||
214 | __flush_dcache_line(a); | ||
215 | } | ||
216 | } | ||
diff --git a/firmware/target/mips/mmu-mips.h b/firmware/target/mips/mmu-mips.h index def4196be1..f3d35f606d 100644 --- a/firmware/target/mips/mmu-mips.h +++ b/firmware/target/mips/mmu-mips.h | |||
@@ -22,8 +22,19 @@ | |||
22 | #ifndef __MMU_MIPS_INCLUDE_H | 22 | #ifndef __MMU_MIPS_INCLUDE_H |
23 | #define __MMU_MIPS_INCLUDE_H | 23 | #define __MMU_MIPS_INCLUDE_H |
24 | 24 | ||
25 | #include "system-target.h" | ||
26 | |||
25 | void map_address(unsigned long virtual, unsigned long physical, | 27 | void map_address(unsigned long virtual, unsigned long physical, |
26 | unsigned long length, unsigned int cache_flags); | 28 | unsigned long length, unsigned int cache_flags); |
27 | void tlb_init(void); | 29 | void mmu_init(void); |
30 | |||
31 | #define HAVE_CPUCACHE_INVALIDATE | ||
32 | //#define HAVE_CPUCACHE_FLUSH | ||
33 | |||
34 | void __dcache_writeback_all(void); | ||
35 | void __dcache_invalidate_all(void); | ||
36 | void __icache_invalidate_all(void); | ||
37 | void __flush_dcache_line(unsigned long addr); | ||
38 | void dma_cache_wback_inv(unsigned long addr, unsigned long size); | ||
28 | 39 | ||
29 | #endif /* __MMU_MIPS_INCLUDE_H */ | 40 | #endif /* __MMU_MIPS_INCLUDE_H */ |