diff options
Diffstat (limited to 'firmware/target/arm/imx31/gigabeat-s/ata-imx31.c')
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/ata-imx31.c | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/ata-imx31.c b/firmware/target/arm/imx31/gigabeat-s/ata-imx31.c new file mode 100644 index 0000000000..58659c7d53 --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/ata-imx31.c | |||
@@ -0,0 +1,137 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 by Will Robertson | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include "config.h" | ||
20 | #include "cpu.h" | ||
21 | #include "kernel.h" | ||
22 | #include "thread.h" | ||
23 | #include "system.h" | ||
24 | #include "power.h" | ||
25 | #include "panic.h" | ||
26 | #include "pcf50606.h" | ||
27 | #include "ata-target.h" | ||
28 | #include "mmu-imx31.h" | ||
29 | #include "backlight-target.h" | ||
30 | |||
31 | #define ATA_RST (1 << 6) | ||
32 | |||
33 | void ata_reset(void) | ||
34 | { | ||
35 | ATA_CONTROL &= ~ATA_RST; | ||
36 | sleep(1); | ||
37 | ATA_CONTROL |= ATA_RST; | ||
38 | sleep(1); | ||
39 | } | ||
40 | |||
41 | /* This function is called before enabling the USB bus */ | ||
42 | void ata_enable(bool on) | ||
43 | { | ||
44 | (void)on; | ||
45 | } | ||
46 | |||
47 | bool ata_is_coldstart(void) | ||
48 | { | ||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | unsigned long get_pll(bool serial) { | ||
53 | unsigned long mfi, mfn, mfd, pdf, ref_clk; | ||
54 | unsigned long reg = 0, ccmr; | ||
55 | unsigned long long temp; | ||
56 | unsigned int prcs; | ||
57 | |||
58 | ccmr = CLKCTL_CCMR; | ||
59 | prcs = (ccmr & 0x6) >> 1; | ||
60 | if(prcs == 0x1) { | ||
61 | ref_clk = 32768 * 1024; | ||
62 | } else { | ||
63 | ref_clk = 27000000; | ||
64 | } | ||
65 | |||
66 | if(serial) { | ||
67 | reg = CLKCTL_SPCTL; | ||
68 | } else { | ||
69 | if((ccmr & 0x8) == 0) | ||
70 | return ref_clk; | ||
71 | if((ccmr & 0x80) != 0) | ||
72 | return ref_clk; | ||
73 | reg = CLKCTL_MPCTL; | ||
74 | } | ||
75 | pdf = (reg & (0x7 << 26)) >> 26; | ||
76 | mfd = (reg & (0x3FF << 16)) >> 16; | ||
77 | mfi = (reg & (0xF << 10)) >> 10; | ||
78 | mfi = (mfi <= 5) ? 5 : mfi; | ||
79 | mfn = (reg & 0x3FF); | ||
80 | |||
81 | if(mfn < 0x200) { | ||
82 | temp = (unsigned long long)2 *ref_clk * mfn; | ||
83 | temp /= (mfd + 1); | ||
84 | temp = (unsigned long long)2 *ref_clk * mfi + temp; | ||
85 | temp /= (pdf + 1); | ||
86 | } else { | ||
87 | temp = (unsigned long long)2 *ref_clk * (0x400 - mfn); | ||
88 | temp /= (mfd + 1); | ||
89 | temp = (unsigned long long)2 *ref_clk * mfi - temp; | ||
90 | temp /= (pdf + 1); | ||
91 | |||
92 | } | ||
93 | return (unsigned long)temp; | ||
94 | } | ||
95 | |||
96 | unsigned long get_ata_clock(void) { | ||
97 | unsigned long pll, ret_val, hclk, max_pdf, ipg_pdf, mcu_pdf; | ||
98 | |||
99 | max_pdf = (CLKCTL_PDR0 & (0x7 << 3)) >> 3; | ||
100 | ipg_pdf = (CLKCTL_PDR0 & (0x3 << 6)) >> 6; | ||
101 | mcu_pdf = (CLKCTL_PDR0 & 0x7); | ||
102 | if((CLKCTL_PMCR0 & 0xC0000000 ) == 0) { | ||
103 | pll = get_pll(true); | ||
104 | } else { | ||
105 | pll = get_pll(false); | ||
106 | } | ||
107 | hclk = pll/(max_pdf + 1); | ||
108 | ret_val = hclk / (ipg_pdf + 1); | ||
109 | |||
110 | return ret_val; | ||
111 | } | ||
112 | |||
113 | void ata_device_init(void) | ||
114 | { | ||
115 | ATA_CONTROL |= ATA_RST; /* Make sure we're not in reset mode */ | ||
116 | |||
117 | /* Setup the timing for PIO mode */ | ||
118 | int T = 1000 * 1000 * 1000 / get_ata_clock(); | ||
119 | TIME_OFF = 3; | ||
120 | TIME_ON = 3; | ||
121 | |||
122 | TIME_1 = (T + 70)/T; | ||
123 | TIME_2W = (T + 290)/T; | ||
124 | TIME_2R = (T + 290)/T; | ||
125 | TIME_AX = (T + 50)/T; | ||
126 | TIME_PIO_RDX = 1; | ||
127 | TIME_4 = (T + 30)/T; | ||
128 | TIME_9 = (T + 20)/T; | ||
129 | } | ||
130 | |||
131 | #if !defined(BOOTLOADER) | ||
132 | void copy_read_sectors(unsigned char* buf, int wordcount) | ||
133 | { | ||
134 | (void)buf; | ||
135 | (void)wordcount; | ||
136 | } | ||
137 | #endif | ||