OpenWrt – Blame information for rev 4
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
4 | office | 1 | /* |
2 | * (C) Copyright 2005 |
||
3 | * Oxford Semiconductor Ltd |
||
4 | * |
||
5 | * See file CREDITS for list of people who contributed to this |
||
6 | * project. |
||
7 | * |
||
8 | * This program is free software; you can redistribute it and/or |
||
9 | * modify it under the terms of the GNU General Public License as |
||
10 | * published by the Free Software Foundation; either version 2 of |
||
11 | * the License, or (at your option) any later version. |
||
12 | * |
||
13 | * This program is distributed in the hope that it will be useful, |
||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
16 | * GNU General Public License for more details. |
||
17 | * |
||
18 | * You should have received a copy of the GNU General Public License |
||
19 | * along with this program; if not, write to the Free Software |
||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston,` |
||
21 | * MA 02111-1307 USA |
||
22 | */ |
||
23 | #include <common.h> |
||
24 | #include <asm/arch/clock.h> |
||
25 | |||
26 | /** |
||
27 | * SATA related definitions |
||
28 | */ |
||
29 | #define ATA_PORT_CTL 0 |
||
30 | #define ATA_PORT_FEATURE 1 |
||
31 | #define ATA_PORT_NSECT 2 |
||
32 | #define ATA_PORT_LBAL 3 |
||
33 | #define ATA_PORT_LBAM 4 |
||
34 | #define ATA_PORT_LBAH 5 |
||
35 | #define ATA_PORT_DEVICE 6 |
||
36 | #define ATA_PORT_COMMAND 7 |
||
37 | |||
38 | /* The offsets to the SATA registers */ |
||
39 | #define SATA_ORB1_OFF 0 |
||
40 | #define SATA_ORB2_OFF 1 |
||
41 | #define SATA_ORB3_OFF 2 |
||
42 | #define SATA_ORB4_OFF 3 |
||
43 | #define SATA_ORB5_OFF 4 |
||
44 | |||
45 | #define SATA_FIS_ACCESS 11 |
||
46 | #define SATA_INT_STATUS_OFF 12 /* Read only */ |
||
47 | #define SATA_INT_CLR_OFF 12 /* Write only */ |
||
48 | #define SATA_INT_ENABLE_OFF 13 /* Read only */ |
||
49 | #define SATA_INT_ENABLE_SET_OFF 13 /* Write only */ |
||
50 | #define SATA_INT_ENABLE_CLR_OFF 14 /* Write only */ |
||
51 | #define SATA_VERSION_OFF 15 |
||
52 | #define SATA_CONTROL_OFF 23 |
||
53 | #define SATA_COMMAND_OFF 24 |
||
54 | #define SATA_PORT_CONTROL_OFF 25 |
||
55 | #define SATA_DRIVE_CONTROL_OFF 26 |
||
56 | |||
57 | /* The offsets to the link registers that are access in an asynchronous manner */ |
||
58 | #define SATA_LINK_DATA 28 |
||
59 | #define SATA_LINK_RD_ADDR 29 |
||
60 | #define SATA_LINK_WR_ADDR 30 |
||
61 | #define SATA_LINK_CONTROL 31 |
||
62 | |||
63 | /* SATA interrupt status register fields */ |
||
64 | #define SATA_INT_STATUS_EOC_RAW_BIT ( 0 + 16) |
||
65 | #define SATA_INT_STATUS_ERROR_BIT ( 2 + 16) |
||
66 | #define SATA_INT_STATUS_EOADT_RAW_BIT ( 1 + 16) |
||
67 | |||
68 | /* SATA core command register commands */ |
||
69 | #define SATA_CMD_WRITE_TO_ORB_REGS 2 |
||
70 | #define SATA_CMD_WRITE_TO_ORB_REGS_NO_COMMAND 4 |
||
71 | |||
72 | #define SATA_CMD_BUSY_BIT 7 |
||
73 | |||
74 | #define SATA_SCTL_CLR_ERR 0x00000316UL |
||
75 | |||
76 | #define SATA_LBAL_BIT 0 |
||
77 | #define SATA_LBAM_BIT 8 |
||
78 | #define SATA_LBAH_BIT 16 |
||
79 | #define SATA_HOB_LBAH_BIT 24 |
||
80 | #define SATA_DEVICE_BIT 24 |
||
81 | #define SATA_NSECT_BIT 0 |
||
82 | #define SATA_HOB_NSECT_BIT 8 |
||
83 | #define SATA_LBA32_BIT 0 |
||
84 | #define SATA_LBA40_BIT 8 |
||
85 | #define SATA_FEATURE_BIT 16 |
||
86 | #define SATA_COMMAND_BIT 24 |
||
87 | #define SATA_CTL_BIT 24 |
||
88 | |||
89 | /* ATA status (7) register field definitions */ |
||
90 | #define ATA_STATUS_BSY_BIT 7 |
||
91 | #define ATA_STATUS_DRDY_BIT 6 |
||
92 | #define ATA_STATUS_DF_BIT 5 |
||
93 | #define ATA_STATUS_DRQ_BIT 3 |
||
94 | #define ATA_STATUS_ERR_BIT 0 |
||
95 | |||
96 | /* ATA device (6) register field definitions */ |
||
97 | #define ATA_DEVICE_FIXED_MASK 0xA0 |
||
98 | #define ATA_DEVICE_DRV_BIT 4 |
||
99 | #define ATA_DEVICE_DRV_NUM_BITS 1 |
||
100 | #define ATA_DEVICE_LBA_BIT 6 |
||
101 | |||
102 | /* ATA Command register initiated commands */ |
||
103 | #define ATA_CMD_INIT 0x91 |
||
104 | #define ATA_CMD_IDENT 0xEC |
||
105 | |||
106 | #define SATA_STD_ASYNC_REGS_OFF 0x20 |
||
107 | #define SATA_SCR_STATUS 0 |
||
108 | #define SATA_SCR_ERROR 1 |
||
109 | #define SATA_SCR_CONTROL 2 |
||
110 | #define SATA_SCR_ACTIVE 3 |
||
111 | #define SATA_SCR_NOTIFICAION 4 |
||
112 | |||
113 | #define SATA_BURST_BUF_FORCE_EOT_BIT 0 |
||
114 | #define SATA_BURST_BUF_DATA_INJ_ENABLE_BIT 1 |
||
115 | #define SATA_BURST_BUF_DIR_BIT 2 |
||
116 | #define SATA_BURST_BUF_DATA_INJ_END_BIT 3 |
||
117 | #define SATA_BURST_BUF_FIFO_DIS_BIT 4 |
||
118 | #define SATA_BURST_BUF_DIS_DREQ_BIT 5 |
||
119 | #define SATA_BURST_BUF_DREQ_BIT 6 |
||
120 | |||
121 | #define SATA_OPCODE_MASK 0x3 |
||
122 | |||
123 | #define SATA_DMA_CHANNEL 0 |
||
124 | |||
125 | #define DMA_CTRL_STATUS (0x0) |
||
126 | #define DMA_BASE_SRC_ADR (0x4) |
||
127 | #define DMA_BASE_DST_ADR (0x8) |
||
128 | #define DMA_BYTE_CNT (0xC) |
||
129 | #define DMA_CURRENT_SRC_ADR (0x10) |
||
130 | #define DMA_CURRENT_DST_ADR (0x14) |
||
131 | #define DMA_CURRENT_BYTE_CNT (0x18) |
||
132 | #define DMA_INTR_ID (0x1C) |
||
133 | #define DMA_INTR_CLEAR_REG (DMA_CURRENT_SRC_ADR) |
||
134 | |||
135 | #define DMA_CALC_REG_ADR(channel, register) ((volatile u32*)(DMA_BASE + ((channel) << 5) + (register))) |
||
136 | |||
137 | #define DMA_CTRL_STATUS_FAIR_SHARE_ARB (1 << 0) |
||
138 | #define DMA_CTRL_STATUS_IN_PROGRESS (1 << 1) |
||
139 | #define DMA_CTRL_STATUS_SRC_DREQ_MASK (0x0000003C) |
||
140 | #define DMA_CTRL_STATUS_SRC_DREQ_SHIFT (2) |
||
141 | #define DMA_CTRL_STATUS_DEST_DREQ_MASK (0x000003C0) |
||
142 | #define DMA_CTRL_STATUS_DEST_DREQ_SHIFT (6) |
||
143 | #define DMA_CTRL_STATUS_INTR (1 << 10) |
||
144 | #define DMA_CTRL_STATUS_NXT_FREE (1 << 11) |
||
145 | #define DMA_CTRL_STATUS_RESET (1 << 12) |
||
146 | #define DMA_CTRL_STATUS_DIR_MASK (0x00006000) |
||
147 | #define DMA_CTRL_STATUS_DIR_SHIFT (13) |
||
148 | #define DMA_CTRL_STATUS_SRC_ADR_MODE (1 << 15) |
||
149 | #define DMA_CTRL_STATUS_DEST_ADR_MODE (1 << 16) |
||
150 | #define DMA_CTRL_STATUS_TRANSFER_MODE_A (1 << 17) |
||
151 | #define DMA_CTRL_STATUS_TRANSFER_MODE_B (1 << 18) |
||
152 | #define DMA_CTRL_STATUS_SRC_WIDTH_MASK (0x00380000) |
||
153 | #define DMA_CTRL_STATUS_SRC_WIDTH_SHIFT (19) |
||
154 | #define DMA_CTRL_STATUS_DEST_WIDTH_MASK (0x01C00000) |
||
155 | #define DMA_CTRL_STATUS_DEST_WIDTH_SHIFT (22) |
||
156 | #define DMA_CTRL_STATUS_PAUSE (1 << 25) |
||
157 | #define DMA_CTRL_STATUS_INTERRUPT_ENABLE (1 << 26) |
||
158 | #define DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED (1 << 27) |
||
159 | #define DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED (1 << 28) |
||
160 | #define DMA_CTRL_STATUS_STARVE_LOW_PRIORITY (1 << 29) |
||
161 | #define DMA_CTRL_STATUS_INTR_CLEAR_ENABLE (1 << 30) |
||
162 | |||
163 | #define DMA_BYTE_CNT_MASK ((1 << 21) - 1) |
||
164 | #define DMA_BYTE_CNT_WR_EOT_MASK (1 << 30) |
||
165 | #define DMA_BYTE_CNT_RD_EOT_MASK (1 << 31) |
||
166 | #define DMA_BYTE_CNT_BURST_MASK (1 << 28) |
||
167 | |||
168 | #define MAKE_FIELD(value, num_bits, bit_num) (((value) & ((1 << (num_bits)) - 1)) << (bit_num)) |
||
169 | |||
170 | typedef enum oxnas_dma_mode { |
||
171 | OXNAS_DMA_MODE_FIXED, OXNAS_DMA_MODE_INC |
||
172 | } oxnas_dma_mode_t; |
||
173 | |||
174 | typedef enum oxnas_dma_direction { |
||
175 | OXNAS_DMA_TO_DEVICE, OXNAS_DMA_FROM_DEVICE |
||
176 | } oxnas_dma_direction_t; |
||
177 | |||
178 | /* The available buses to which the DMA controller is attached */ |
||
179 | typedef enum oxnas_dma_transfer_bus { |
||
180 | OXNAS_DMA_SIDE_A, OXNAS_DMA_SIDE_B |
||
181 | } oxnas_dma_transfer_bus_t; |
||
182 | |||
183 | /* Direction of data flow between the DMA controller's pair of interfaces */ |
||
184 | typedef enum oxnas_dma_transfer_direction { |
||
185 | OXNAS_DMA_A_TO_A, OXNAS_DMA_B_TO_A, OXNAS_DMA_A_TO_B, OXNAS_DMA_B_TO_B |
||
186 | } oxnas_dma_transfer_direction_t; |
||
187 | |||
188 | /* The available data widths */ |
||
189 | typedef enum oxnas_dma_transfer_width { |
||
190 | OXNAS_DMA_TRANSFER_WIDTH_8BITS, |
||
191 | OXNAS_DMA_TRANSFER_WIDTH_16BITS, |
||
192 | OXNAS_DMA_TRANSFER_WIDTH_32BITS |
||
193 | } oxnas_dma_transfer_width_t; |
||
194 | |||
195 | /* The mode of the DMA transfer */ |
||
196 | typedef enum oxnas_dma_transfer_mode { |
||
197 | OXNAS_DMA_TRANSFER_MODE_SINGLE, OXNAS_DMA_TRANSFER_MODE_BURST |
||
198 | } oxnas_dma_transfer_mode_t; |
||
199 | |||
200 | /* The available transfer targets */ |
||
201 | typedef enum oxnas_dma_dreq { |
||
202 | OXNAS_DMA_DREQ_SATA = 0, OXNAS_DMA_DREQ_MEMORY = 15 |
||
203 | } oxnas_dma_dreq_t; |
||
204 | |||
205 | typedef struct oxnas_dma_device_settings { |
||
206 | unsigned long address_; |
||
207 | unsigned fifo_size_; // Chained transfers must take account of FIFO offset at end of previous transfer |
||
208 | unsigned char dreq_; |
||
209 | unsigned read_eot_ :1; |
||
210 | unsigned read_final_eot_ :1; |
||
211 | unsigned write_eot_ :1; |
||
212 | unsigned write_final_eot_ :1; |
||
213 | unsigned bus_ :1; |
||
214 | unsigned width_ :2; |
||
215 | unsigned transfer_mode_ :1; |
||
216 | unsigned address_mode_ :1; |
||
217 | unsigned address_really_fixed_ :1; |
||
218 | } oxnas_dma_device_settings_t; |
||
219 | |||
220 | static const int MAX_NO_ERROR_LOOPS = 100000; /* 1 second in units of 10uS */ |
||
221 | static const int MAX_DMA_XFER_LOOPS = 300000; /* 30 seconds in units of 100uS */ |
||
222 | static const int MAX_DMA_ABORT_LOOPS = 10000; /* 0.1 second in units of 10uS */ |
||
223 | static const int MAX_SRC_READ_LOOPS = 10000; /* 0.1 second in units of 10uS */ |
||
224 | static const int MAX_SRC_WRITE_LOOPS = 10000; /* 0.1 second in units of 10uS */ |
||
225 | static const int MAX_NOT_BUSY_LOOPS = 10000; /* 1 second in units of 100uS */ |
||
226 | |||
227 | /* The internal SATA drive on which we should attempt to find partitions */ |
||
228 | static volatile u32* sata_regs_base[2] = { (volatile u32*) SATA_0_REGS_BASE, |
||
229 | (volatile u32*) SATA_1_REGS_BASE, |
||
230 | |||
231 | }; |
||
232 | static u32 wr_sata_orb1[2] = { 0, 0 }; |
||
233 | static u32 wr_sata_orb2[2] = { 0, 0 }; |
||
234 | static u32 wr_sata_orb3[2] = { 0, 0 }; |
||
235 | static u32 wr_sata_orb4[2] = { 0, 0 }; |
||
236 | |||
237 | #ifdef CONFIG_LBA48 |
||
238 | /* need keeping a record of NSECT LBAL LBAM LBAH ide_outb values for lba48 support */ |
||
239 | #define OUT_HISTORY_BASE ATA_PORT_NSECT |
||
240 | #define OUT_HISTORY_MAX ATA_PORT_LBAH |
||
241 | static unsigned char out_history[2][OUT_HISTORY_MAX - OUT_HISTORY_BASE + 1] = {}; |
||
242 | #endif |
||
243 | |||
244 | static oxnas_dma_device_settings_t oxnas_sata_dma_settings = { .address_ = |
||
245 | SATA_DATA_BASE, .fifo_size_ = 16, .dreq_ = OXNAS_DMA_DREQ_SATA, |
||
246 | .read_eot_ = 0, .read_final_eot_ = 1, .write_eot_ = 0, |
||
247 | .write_final_eot_ = 1, .bus_ = OXNAS_DMA_SIDE_B, .width_ = |
||
248 | OXNAS_DMA_TRANSFER_WIDTH_32BITS, .transfer_mode_ = |
||
249 | OXNAS_DMA_TRANSFER_MODE_BURST, .address_mode_ = |
||
250 | OXNAS_DMA_MODE_FIXED, .address_really_fixed_ = 0 }; |
||
251 | |||
252 | oxnas_dma_device_settings_t oxnas_ram_dma_settings = { .address_ = 0, |
||
253 | .fifo_size_ = 0, .dreq_ = OXNAS_DMA_DREQ_MEMORY, .read_eot_ = 1, |
||
254 | .read_final_eot_ = 1, .write_eot_ = 1, .write_final_eot_ = 1, |
||
255 | .bus_ = OXNAS_DMA_SIDE_A, .width_ = |
||
256 | OXNAS_DMA_TRANSFER_WIDTH_32BITS, .transfer_mode_ = |
||
257 | OXNAS_DMA_TRANSFER_MODE_BURST, .address_mode_ = |
||
258 | OXNAS_DMA_MODE_FIXED, .address_really_fixed_ = 1 }; |
||
259 | |||
260 | static void xfer_wr_shadow_to_orbs(int device) |
||
261 | { |
||
262 | *(sata_regs_base[device] + SATA_ORB1_OFF) = wr_sata_orb1[device]; |
||
263 | *(sata_regs_base[device] + SATA_ORB2_OFF) = wr_sata_orb2[device]; |
||
264 | *(sata_regs_base[device] + SATA_ORB3_OFF) = wr_sata_orb3[device]; |
||
265 | *(sata_regs_base[device] + SATA_ORB4_OFF) = wr_sata_orb4[device]; |
||
266 | } |
||
267 | |||
268 | static inline void device_select(int device) |
||
269 | { |
||
270 | /* master/slave has no meaning to SATA core */ |
||
271 | } |
||
272 | |||
273 | static int disk_present[CONFIG_SYS_IDE_MAXDEVICE]; |
||
274 | |||
275 | #include <ata.h> |
||
276 | |||
277 | unsigned char ide_inb(int device, int port) |
||
278 | { |
||
279 | unsigned char val = 0; |
||
280 | |||
281 | /* Only permit accesses to disks found to be present during ide_preinit() */ |
||
282 | if (!disk_present[device]) { |
||
283 | return ATA_STAT_FAULT; |
||
284 | } |
||
285 | |||
286 | device_select(device); |
||
287 | |||
288 | switch (port) { |
||
289 | case ATA_PORT_CTL: |
||
290 | val = (*(sata_regs_base[device] + SATA_ORB4_OFF) |
||
291 | & (0xFFUL << SATA_CTL_BIT)) >> SATA_CTL_BIT; |
||
292 | break; |
||
293 | case ATA_PORT_FEATURE: |
||
294 | val = (*(sata_regs_base[device] + SATA_ORB2_OFF) |
||
295 | & (0xFFUL << SATA_FEATURE_BIT)) >> SATA_FEATURE_BIT; |
||
296 | break; |
||
297 | case ATA_PORT_NSECT: |
||
298 | val = (*(sata_regs_base[device] + SATA_ORB2_OFF) |
||
299 | & (0xFFUL << SATA_NSECT_BIT)) >> SATA_NSECT_BIT; |
||
300 | break; |
||
301 | case ATA_PORT_LBAL: |
||
302 | val = (*(sata_regs_base[device] + SATA_ORB3_OFF) |
||
303 | & (0xFFUL << SATA_LBAL_BIT)) >> SATA_LBAL_BIT; |
||
304 | break; |
||
305 | case ATA_PORT_LBAM: |
||
306 | val = (*(sata_regs_base[device] + SATA_ORB3_OFF) |
||
307 | & (0xFFUL << SATA_LBAM_BIT)) >> SATA_LBAM_BIT; |
||
308 | break; |
||
309 | case ATA_PORT_LBAH: |
||
310 | val = (*(sata_regs_base[device] + SATA_ORB3_OFF) |
||
311 | & (0xFFUL << SATA_LBAH_BIT)) >> SATA_LBAH_BIT; |
||
312 | break; |
||
313 | case ATA_PORT_DEVICE: |
||
314 | val = (*(sata_regs_base[device] + SATA_ORB3_OFF) |
||
315 | & (0xFFUL << SATA_HOB_LBAH_BIT)) >> SATA_HOB_LBAH_BIT; |
||
316 | val |= (*(sata_regs_base[device] + SATA_ORB1_OFF) |
||
317 | & (0xFFUL << SATA_DEVICE_BIT)) >> SATA_DEVICE_BIT; |
||
318 | break; |
||
319 | case ATA_PORT_COMMAND: |
||
320 | val = (*(sata_regs_base[device] + SATA_ORB2_OFF) |
||
321 | & (0xFFUL << SATA_COMMAND_BIT)) >> SATA_COMMAND_BIT; |
||
322 | val |= ATA_STAT_DRQ; |
||
323 | break; |
||
324 | default: |
||
325 | printf("ide_inb() Unknown port = %d\n", port); |
||
326 | break; |
||
327 | } |
||
328 | |||
329 | // printf("inb: %d:%01x => %02x\n", device, port, val); |
||
330 | |||
331 | return val; |
||
332 | } |
||
333 | |||
334 | /** |
||
335 | * Possible that ATA status will not become no-error, so must have timeout |
||
336 | * @returns An int which is zero on error |
||
337 | */ |
||
338 | static inline int wait_no_error(int device) |
||
339 | { |
||
340 | int status = 0; |
||
341 | |||
342 | /* Check for ATA core error */ |
||
343 | if (*(sata_regs_base[device] + SATA_INT_STATUS_OFF) |
||
344 | & (1 << SATA_INT_STATUS_ERROR_BIT)) { |
||
345 | printf("wait_no_error() SATA core flagged error\n"); |
||
346 | } else { |
||
347 | int loops = MAX_NO_ERROR_LOOPS; |
||
348 | do { |
||
349 | /* Check for ATA device error */ |
||
350 | if (!(ide_inb(device, ATA_PORT_COMMAND) |
||
351 | & (1 << ATA_STATUS_ERR_BIT))) { |
||
352 | status = 1; |
||
353 | break; |
||
354 | } |
||
355 | udelay(10); |
||
356 | } while (--loops); |
||
357 | |||
358 | if (!loops) { |
||
359 | printf("wait_no_error() Timed out of wait for SATA no-error condition\n"); |
||
360 | } |
||
361 | } |
||
362 | |||
363 | return status; |
||
364 | } |
||
365 | |||
366 | /** |
||
367 | * Expect SATA command to always finish, perhaps with error |
||
368 | * @returns An int which is zero on error |
||
369 | */ |
||
370 | static inline int wait_sata_command_not_busy(int device) |
||
371 | { |
||
372 | /* Wait for data to be available */ |
||
373 | int status = 0; |
||
374 | int loops = MAX_NOT_BUSY_LOOPS; |
||
375 | do { |
||
376 | if (!(*(sata_regs_base[device] + SATA_COMMAND_OFF) |
||
377 | & (1 << SATA_CMD_BUSY_BIT))) { |
||
378 | status = 1; |
||
379 | break; |
||
380 | } |
||
381 | udelay(100); |
||
382 | } while (--loops); |
||
383 | |||
384 | if (!loops) { |
||
385 | printf("wait_sata_command_not_busy() Timed out of wait for SATA command to finish\n"); |
||
386 | } |
||
387 | |||
388 | return status; |
||
389 | } |
||
390 | |||
391 | void ide_outb(int device, int port, unsigned char val) |
||
392 | { |
||
393 | typedef enum send_method { |
||
394 | SEND_NONE, SEND_SIMPLE, SEND_CMD, SEND_CTL, |
||
395 | } send_method_t; |
||
396 | |||
397 | /* Only permit accesses to disks found to be present during ide_preinit() */ |
||
398 | if (!disk_present[device]) { |
||
399 | return; |
||
400 | } |
||
401 | |||
402 | // printf("outb: %d:%01x <= %02x\n", device, port, val); |
||
403 | |||
404 | device_select(device); |
||
405 | |||
406 | #ifdef CONFIG_LBA48 |
||
407 | if (port >= OUT_HISTORY_BASE && port <= OUT_HISTORY_MAX) { |
||
408 | out_history[0][port - OUT_HISTORY_BASE] = |
||
409 | out_history[1][port - OUT_HISTORY_BASE]; |
||
410 | out_history[1][port - OUT_HISTORY_BASE] = val; |
||
411 | } |
||
412 | #endif |
||
413 | send_method_t send_regs = SEND_NONE; |
||
414 | switch (port) { |
||
415 | case ATA_PORT_CTL: |
||
416 | wr_sata_orb4[device] &= ~(0xFFUL << SATA_CTL_BIT); |
||
417 | wr_sata_orb4[device] |= (val << SATA_CTL_BIT); |
||
418 | send_regs = SEND_CTL; |
||
419 | break; |
||
420 | case ATA_PORT_FEATURE: |
||
421 | wr_sata_orb2[device] &= ~(0xFFUL << SATA_FEATURE_BIT); |
||
422 | wr_sata_orb2[device] |= (val << SATA_FEATURE_BIT); |
||
423 | send_regs = SEND_SIMPLE; |
||
424 | break; |
||
425 | case ATA_PORT_NSECT: |
||
426 | wr_sata_orb2[device] &= ~(0xFFUL << SATA_NSECT_BIT); |
||
427 | wr_sata_orb2[device] |= (val << SATA_NSECT_BIT); |
||
428 | send_regs = SEND_SIMPLE; |
||
429 | break; |
||
430 | case ATA_PORT_LBAL: |
||
431 | wr_sata_orb3[device] &= ~(0xFFUL << SATA_LBAL_BIT); |
||
432 | wr_sata_orb3[device] |= (val << SATA_LBAL_BIT); |
||
433 | send_regs = SEND_SIMPLE; |
||
434 | break; |
||
435 | case ATA_PORT_LBAM: |
||
436 | wr_sata_orb3[device] &= ~(0xFFUL << SATA_LBAM_BIT); |
||
437 | wr_sata_orb3[device] |= (val << SATA_LBAM_BIT); |
||
438 | send_regs = SEND_SIMPLE; |
||
439 | break; |
||
440 | case ATA_PORT_LBAH: |
||
441 | wr_sata_orb3[device] &= ~(0xFFUL << SATA_LBAH_BIT); |
||
442 | wr_sata_orb3[device] |= (val << SATA_LBAH_BIT); |
||
443 | send_regs = SEND_SIMPLE; |
||
444 | break; |
||
445 | case ATA_PORT_DEVICE: |
||
446 | wr_sata_orb1[device] &= ~(0xFFUL << SATA_DEVICE_BIT); |
||
447 | wr_sata_orb1[device] |= (val << SATA_DEVICE_BIT); |
||
448 | send_regs = SEND_SIMPLE; |
||
449 | break; |
||
450 | case ATA_PORT_COMMAND: |
||
451 | wr_sata_orb2[device] &= ~(0xFFUL << SATA_COMMAND_BIT); |
||
452 | wr_sata_orb2[device] |= (val << SATA_COMMAND_BIT); |
||
453 | send_regs = SEND_CMD; |
||
454 | #ifdef CONFIG_LBA48 |
||
455 | if (val == ATA_CMD_READ_EXT || val == ATA_CMD_WRITE_EXT) |
||
456 | { |
||
457 | /* fill high bytes of LBA48 && NSECT */ |
||
458 | wr_sata_orb2[device] &= ~(0xFFUL << SATA_HOB_NSECT_BIT); |
||
459 | wr_sata_orb2[device] |= |
||
460 | (out_history[0][ATA_PORT_NSECT - OUT_HISTORY_BASE] << SATA_HOB_NSECT_BIT); |
||
461 | |||
462 | wr_sata_orb3[device] &= ~(0xFFUL << SATA_HOB_LBAH_BIT); |
||
463 | wr_sata_orb3[device] |= |
||
464 | (out_history[0][ATA_PORT_LBAL - OUT_HISTORY_BASE] << SATA_HOB_LBAH_BIT); |
||
465 | |||
466 | wr_sata_orb4[device] &= ~(0xFFUL << SATA_LBA32_BIT); |
||
467 | wr_sata_orb4[device] |= |
||
468 | (out_history[0][ATA_PORT_LBAM - OUT_HISTORY_BASE] << SATA_LBA32_BIT); |
||
469 | |||
470 | wr_sata_orb4[device] &= ~(0xFFUL << SATA_LBA40_BIT); |
||
471 | wr_sata_orb4[device] |= |
||
472 | (out_history[0][ATA_PORT_LBAH - OUT_HISTORY_BASE] << SATA_LBA40_BIT); |
||
473 | } |
||
474 | #endif |
||
475 | break; |
||
476 | default: |
||
477 | printf("ide_outb() Unknown port = %d\n", port); |
||
478 | } |
||
479 | |||
480 | u32 command; |
||
481 | switch (send_regs) { |
||
482 | case SEND_CMD: |
||
483 | wait_sata_command_not_busy(device); |
||
484 | command = *(sata_regs_base[device] + SATA_COMMAND_OFF); |
||
485 | command &= ~SATA_OPCODE_MASK; |
||
486 | command |= SATA_CMD_WRITE_TO_ORB_REGS; |
||
487 | xfer_wr_shadow_to_orbs(device); |
||
488 | wait_sata_command_not_busy(device); |
||
489 | *(sata_regs_base[device] + SATA_COMMAND_OFF) = command; |
||
490 | if (!wait_no_error(device)) { |
||
491 | printf("ide_outb() Wait for ATA no-error timed-out\n"); |
||
492 | } |
||
493 | break; |
||
494 | case SEND_CTL: |
||
495 | wait_sata_command_not_busy(device); |
||
496 | command = *(sata_regs_base[device] + SATA_COMMAND_OFF); |
||
497 | command &= ~SATA_OPCODE_MASK; |
||
498 | command |= SATA_CMD_WRITE_TO_ORB_REGS_NO_COMMAND; |
||
499 | xfer_wr_shadow_to_orbs(device); |
||
500 | wait_sata_command_not_busy(device); |
||
501 | *(sata_regs_base[device] + SATA_COMMAND_OFF) = command; |
||
502 | if (!wait_no_error(device)) { |
||
503 | printf("ide_outb() Wait for ATA no-error timed-out\n"); |
||
504 | } |
||
505 | break; |
||
506 | default: |
||
507 | break; |
||
508 | } |
||
509 | } |
||
510 | |||
511 | static u32 encode_start(u32 ctrl_status) |
||
512 | { |
||
513 | return ctrl_status & ~DMA_CTRL_STATUS_PAUSE; |
||
514 | } |
||
515 | |||
516 | /* start a paused DMA transfer in channel 0 of the SATA DMA core */ |
||
517 | static void dma_start(void) |
||
518 | { |
||
519 | unsigned int reg; |
||
520 | reg = readl(SATA_DMA_REGS_BASE + DMA_CTRL_STATUS); |
||
521 | reg = encode_start(reg); |
||
522 | writel(reg, SATA_DMA_REGS_BASE + DMA_CTRL_STATUS); |
||
523 | } |
||
524 | |||
525 | static unsigned long encode_control_status( |
||
526 | oxnas_dma_device_settings_t* src_settings, |
||
527 | oxnas_dma_device_settings_t* dst_settings) |
||
528 | { |
||
529 | unsigned long ctrl_status; |
||
530 | oxnas_dma_transfer_direction_t direction; |
||
531 | |||
532 | ctrl_status = DMA_CTRL_STATUS_PAUSE; // Paused |
||
533 | ctrl_status |= DMA_CTRL_STATUS_FAIR_SHARE_ARB; // High priority |
||
534 | ctrl_status |= (src_settings->dreq_ << DMA_CTRL_STATUS_SRC_DREQ_SHIFT); // Dreq |
||
535 | ctrl_status |= (dst_settings->dreq_ << DMA_CTRL_STATUS_DEST_DREQ_SHIFT); // Dreq |
||
536 | ctrl_status &= ~DMA_CTRL_STATUS_RESET; // !RESET |
||
537 | |||
538 | // Use new interrupt clearing register |
||
539 | ctrl_status |= DMA_CTRL_STATUS_INTR_CLEAR_ENABLE; |
||
540 | |||
541 | // Setup the transfer direction and burst/single mode for the two DMA busses |
||
542 | if (src_settings->bus_ == OXNAS_DMA_SIDE_A) { |
||
543 | // Set the burst/single mode for bus A based on src device's settings |
||
544 | if (src_settings->transfer_mode_ |
||
545 | == OXNAS_DMA_TRANSFER_MODE_BURST) { |
||
546 | ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_A; |
||
547 | } else { |
||
548 | ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_A; |
||
549 | } |
||
550 | |||
551 | if (dst_settings->bus_ == OXNAS_DMA_SIDE_A) { |
||
552 | direction = OXNAS_DMA_A_TO_A; |
||
553 | } else { |
||
554 | direction = OXNAS_DMA_A_TO_B; |
||
555 | |||
556 | // Set the burst/single mode for bus B based on dst device's settings |
||
557 | if (dst_settings->transfer_mode_ |
||
558 | == OXNAS_DMA_TRANSFER_MODE_BURST) { |
||
559 | ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_B; |
||
560 | } else { |
||
561 | ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_B; |
||
562 | } |
||
563 | } |
||
564 | } else { |
||
565 | // Set the burst/single mode for bus B based on src device's settings |
||
566 | if (src_settings->transfer_mode_ |
||
567 | == OXNAS_DMA_TRANSFER_MODE_BURST) { |
||
568 | ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_B; |
||
569 | } else { |
||
570 | ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_B; |
||
571 | } |
||
572 | |||
573 | if (dst_settings->bus_ == OXNAS_DMA_SIDE_A) { |
||
574 | direction = OXNAS_DMA_B_TO_A; |
||
575 | |||
576 | // Set the burst/single mode for bus A based on dst device's settings |
||
577 | if (dst_settings->transfer_mode_ |
||
578 | == OXNAS_DMA_TRANSFER_MODE_BURST) { |
||
579 | ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_A; |
||
580 | } else { |
||
581 | ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_A; |
||
582 | } |
||
583 | } else { |
||
584 | direction = OXNAS_DMA_B_TO_B; |
||
585 | } |
||
586 | } |
||
587 | ctrl_status |= (direction << DMA_CTRL_STATUS_DIR_SHIFT); |
||
588 | |||
589 | // Setup source address mode fixed or increment |
||
590 | if (src_settings->address_mode_ == OXNAS_DMA_MODE_FIXED) { |
||
591 | // Fixed address |
||
592 | ctrl_status &= ~(DMA_CTRL_STATUS_SRC_ADR_MODE); |
||
593 | |||
594 | // Set up whether fixed address is _really_ fixed |
||
595 | if (src_settings->address_really_fixed_) { |
||
596 | ctrl_status |= DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED; |
||
597 | } else { |
||
598 | ctrl_status &= ~DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED; |
||
599 | } |
||
600 | } else { |
||
601 | // Incrementing address |
||
602 | ctrl_status |= DMA_CTRL_STATUS_SRC_ADR_MODE; |
||
603 | ctrl_status &= ~DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED; |
||
604 | } |
||
605 | |||
606 | // Setup destination address mode fixed or increment |
||
607 | if (dst_settings->address_mode_ == OXNAS_DMA_MODE_FIXED) { |
||
608 | // Fixed address |
||
609 | ctrl_status &= ~(DMA_CTRL_STATUS_DEST_ADR_MODE); |
||
610 | |||
611 | // Set up whether fixed address is _really_ fixed |
||
612 | if (dst_settings->address_really_fixed_) { |
||
613 | ctrl_status |= |
||
614 | DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED; |
||
615 | } else { |
||
616 | ctrl_status &= |
||
617 | ~DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED; |
||
618 | } |
||
619 | } else { |
||
620 | // Incrementing address |
||
621 | ctrl_status |= DMA_CTRL_STATUS_DEST_ADR_MODE; |
||
622 | ctrl_status &= ~DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED; |
||
623 | } |
||
624 | |||
625 | // Set up the width of the transfers on the DMA buses |
||
626 | ctrl_status |= |
||
627 | (src_settings->width_ << DMA_CTRL_STATUS_SRC_WIDTH_SHIFT); |
||
628 | ctrl_status |= |
||
629 | (dst_settings->width_ << DMA_CTRL_STATUS_DEST_WIDTH_SHIFT); |
||
630 | |||
631 | // Setup the priority arbitration scheme |
||
632 | ctrl_status &= ~DMA_CTRL_STATUS_STARVE_LOW_PRIORITY; // !Starve low priority |
||
633 | |||
634 | return ctrl_status; |
||
635 | } |
||
636 | |||
637 | static u32 encode_final_eot(oxnas_dma_device_settings_t* src_settings, |
||
638 | oxnas_dma_device_settings_t* dst_settings, |
||
639 | unsigned long length) |
||
640 | { |
||
641 | // Write the length, with EOT configuration for a final transfer |
||
642 | unsigned long encoded = length; |
||
643 | if (dst_settings->write_final_eot_) { |
||
644 | encoded |= DMA_BYTE_CNT_WR_EOT_MASK; |
||
645 | } else { |
||
646 | encoded &= ~DMA_BYTE_CNT_WR_EOT_MASK; |
||
647 | } |
||
648 | if (src_settings->read_final_eot_) { |
||
649 | encoded |= DMA_BYTE_CNT_RD_EOT_MASK; |
||
650 | } else { |
||
651 | encoded &= ~DMA_BYTE_CNT_RD_EOT_MASK; |
||
652 | } |
||
653 | /* if((src_settings->transfer_mode_) || |
||
654 | (src_settings->transfer_mode_)) { |
||
655 | encoded |= DMA_BYTE_CNT_BURST_MASK; |
||
656 | } else { |
||
657 | encoded &= ~DMA_BYTE_CNT_BURST_MASK; |
||
658 | }*/ |
||
659 | return encoded; |
||
660 | } |
||
661 | |||
662 | static void dma_start_write(const ulong* buffer, int num_bytes) |
||
663 | { |
||
664 | // Assemble complete memory settings |
||
665 | oxnas_dma_device_settings_t mem_settings = oxnas_ram_dma_settings; |
||
666 | mem_settings.address_ = (unsigned long) buffer; |
||
667 | mem_settings.address_mode_ = OXNAS_DMA_MODE_INC; |
||
668 | |||
669 | writel(encode_control_status(&mem_settings, &oxnas_sata_dma_settings), |
||
670 | SATA_DMA_REGS_BASE + DMA_CTRL_STATUS); |
||
671 | writel(mem_settings.address_, SATA_DMA_REGS_BASE + DMA_BASE_SRC_ADR); |
||
672 | writel(oxnas_sata_dma_settings.address_, |
||
673 | SATA_DMA_REGS_BASE + DMA_BASE_DST_ADR); |
||
674 | writel(encode_final_eot(&mem_settings, &oxnas_sata_dma_settings, |
||
675 | num_bytes), |
||
676 | SATA_DMA_REGS_BASE + DMA_BYTE_CNT); |
||
677 | |||
678 | dma_start(); |
||
679 | } |
||
680 | |||
681 | static void dma_start_read(ulong* buffer, int num_bytes) |
||
682 | { |
||
683 | // Assemble complete memory settings |
||
684 | oxnas_dma_device_settings_t mem_settings = oxnas_ram_dma_settings; |
||
685 | mem_settings.address_ = (unsigned long) buffer; |
||
686 | mem_settings.address_mode_ = OXNAS_DMA_MODE_INC; |
||
687 | |||
688 | writel(encode_control_status(&oxnas_sata_dma_settings, &mem_settings), |
||
689 | SATA_DMA_REGS_BASE + DMA_CTRL_STATUS); |
||
690 | writel(oxnas_sata_dma_settings.address_, |
||
691 | SATA_DMA_REGS_BASE + DMA_BASE_SRC_ADR); |
||
692 | writel(mem_settings.address_, SATA_DMA_REGS_BASE + DMA_BASE_DST_ADR); |
||
693 | writel(encode_final_eot(&oxnas_sata_dma_settings, &mem_settings, |
||
694 | num_bytes), |
||
695 | SATA_DMA_REGS_BASE + DMA_BYTE_CNT); |
||
696 | |||
697 | dma_start(); |
||
698 | } |
||
699 | |||
700 | static inline int dma_busy(void) |
||
701 | { |
||
702 | return readl(SATA_DMA_REGS_BASE + DMA_CTRL_STATUS) |
||
703 | & DMA_CTRL_STATUS_IN_PROGRESS; |
||
704 | } |
||
705 | |||
706 | static int wait_dma_not_busy(int device) |
||
707 | { |
||
708 | unsigned int cleanup_required = 0; |
||
709 | |||
710 | /* Poll for DMA completion */ |
||
711 | int loops = MAX_DMA_XFER_LOOPS; |
||
712 | do { |
||
713 | if (!dma_busy()) { |
||
714 | break; |
||
715 | } |
||
716 | udelay(100); |
||
717 | } while (--loops); |
||
718 | |||
719 | if (!loops) { |
||
720 | printf("wait_dma_not_busy() Timed out of wait for DMA not busy\n"); |
||
721 | cleanup_required = 1; |
||
722 | } |
||
723 | |||
724 | if (cleanup_required) { |
||
725 | /* Abort DMA to make sure it has finished. */ |
||
726 | unsigned int ctrl_status = readl( |
||
727 | SATA_DMA_CHANNEL + DMA_CTRL_STATUS); |
||
728 | ctrl_status |= DMA_CTRL_STATUS_RESET; |
||
729 | writel(ctrl_status, SATA_DMA_CHANNEL + DMA_CTRL_STATUS); |
||
730 | |||
731 | // Wait for the channel to become idle - should be quick as should |
||
732 | // finish after the next AHB single or burst transfer |
||
733 | loops = MAX_DMA_ABORT_LOOPS; |
||
734 | do { |
||
735 | if (!dma_busy()) { |
||
736 | break; |
||
737 | } |
||
738 | udelay(10); |
||
739 | } while (--loops); |
||
740 | |||
741 | if (!loops) { |
||
742 | printf("wait_dma_not_busy() Timed out of wait for DMA channel abort\n"); |
||
743 | } else { |
||
744 | /* Successfully cleanup the DMA channel */ |
||
745 | cleanup_required = 0; |
||
746 | } |
||
747 | |||
748 | // Deassert reset for the channel |
||
749 | ctrl_status = readl(SATA_DMA_CHANNEL + DMA_CTRL_STATUS); |
||
750 | ctrl_status &= ~DMA_CTRL_STATUS_RESET; |
||
751 | writel(ctrl_status, SATA_DMA_CHANNEL + DMA_CTRL_STATUS); |
||
752 | } |
||
753 | |||
754 | return !cleanup_required; |
||
755 | } |
||
756 | |||
757 | /** |
||
758 | * Possible that ATA status will not become not-busy, so must have timeout |
||
759 | */ |
||
760 | static unsigned int wait_not_busy(int device, unsigned long timeout_secs) |
||
761 | { |
||
762 | int busy = 1; |
||
763 | unsigned long loops = (timeout_secs * 1000) / 50; |
||
764 | do { |
||
765 | // Test the ATA status register BUSY flag |
||
766 | if (!((*(sata_regs_base[device] + SATA_ORB2_OFF) |
||
767 | >> SATA_COMMAND_BIT) & (1UL << ATA_STATUS_BSY_BIT))) { |
||
768 | /* Not busy, so stop polling */ |
||
769 | busy = 0; |
||
770 | break; |
||
771 | } |
||
772 | |||
773 | // Wait for 50mS before sampling ATA status register again |
||
774 | udelay(50000); |
||
775 | } while (--loops); |
||
776 | |||
777 | return busy; |
||
778 | } |
||
779 | |||
780 | void ide_output_data(int device, const ulong *sect_buf, int words) |
||
781 | { |
||
782 | /* Only permit accesses to disks found to be present during ide_preinit() */ |
||
783 | if (!disk_present[device]) { |
||
784 | return; |
||
785 | } |
||
786 | |||
787 | /* Select the required internal SATA drive */ |
||
788 | device_select(device); |
||
789 | |||
790 | /* Start the DMA channel sending data from the passed buffer to the SATA core */ |
||
791 | dma_start_write(sect_buf, words << 2); |
||
792 | |||
793 | /* Don't know why we need this delay, but without it the wait for DMA not |
||
794 | busy times soemtimes out, e.g. when saving environment to second disk */ |
||
795 | udelay(1000); |
||
796 | |||
797 | /* Wait for DMA to finish */ |
||
798 | if (!wait_dma_not_busy(device)) { |
||
799 | printf("Timed out of wait for DMA channel for SATA device %d to have in-progress clear\n", |
||
800 | device); |
||
801 | } |
||
802 | |||
803 | /* Sata core should finish after DMA */ |
||
804 | if (wait_not_busy(device, 30)) { |
||
805 | printf("Timed out of wait for SATA device %d to have BUSY clear\n", |
||
806 | device); |
||
807 | } |
||
808 | if (!wait_no_error(device)) { |
||
809 | printf("oxnas_sata_output_data() Wait for ATA no-error timed-out\n"); |
||
810 | } |
||
811 | } |
||
812 | |||
813 | |||
814 | #define SATA_DM_DBG1 (SATA_HOST_REGS_BASE + 0) |
||
815 | #define SATA_DATACOUNT_PORT0 (SATA_HOST_REGS_BASE + 0x10) |
||
816 | #define SATA_DATACOUNT_PORT1 (SATA_HOST_REGS_BASE + 0x14) |
||
817 | #define SATA_DATA_MUX_RAM0 (SATA_HOST_REGS_BASE + 0x8000) |
||
818 | #define SATA_DATA_MUX_RAM1 (SATA_HOST_REGS_BASE + 0xA000) |
||
819 | /* Sata core debug1 register bits */ |
||
820 | #define SATA_CORE_PORT0_DATA_DIR_BIT 20 |
||
821 | #define SATA_CORE_PORT1_DATA_DIR_BIT 21 |
||
822 | #define SATA_CORE_PORT0_DATA_DIR (1 << SATA_CORE_PORT0_DATA_DIR_BIT) |
||
823 | #define SATA_CORE_PORT1_DATA_DIR (1 << SATA_CORE_PORT1_DATA_DIR_BIT) |
||
824 | |||
825 | /** |
||
826 | * Ref bug-6320 |
||
827 | * |
||
828 | * This code is a work around for a DMA hardware bug that will repeat the |
||
829 | * penultimate 8-bytes on some reads. This code will check that the amount |
||
830 | * of data transferred is a multiple of 512 bytes, if not the in it will |
||
831 | * fetch the correct data from a buffer in the SATA core and copy it into |
||
832 | * memory. |
||
833 | * |
||
834 | */ |
||
835 | static void sata_bug_6320_workaround(int port, ulong *candidate) |
||
836 | { |
||
837 | int is_read; |
||
838 | int quads_transferred; |
||
839 | int remainder; |
||
840 | int sector_quads_remaining; |
||
841 | |||
842 | /* Only want to apply fix to reads */ |
||
843 | is_read = !(*((unsigned long*) SATA_DM_DBG1) |
||
844 | & (port ? SATA_CORE_PORT1_DATA_DIR : SATA_CORE_PORT0_DATA_DIR)); |
||
845 | |||
846 | /* Check for an incomplete transfer, i.e. not a multiple of 512 bytes |
||
847 | transferred (datacount_port register counts quads transferred) */ |
||
848 | quads_transferred = *((unsigned long*) ( |
||
849 | port ? SATA_DATACOUNT_PORT1 : SATA_DATACOUNT_PORT0)); |
||
850 | |||
851 | remainder = quads_transferred & 0x7f; |
||
852 | sector_quads_remaining = remainder ? (0x80 - remainder) : 0; |
||
853 | |||
854 | if (is_read && (sector_quads_remaining == 2)) { |
||
855 | debug("SATA read fixup, only transfered %d quads, " |
||
856 | "sector_quads_remaining %d, port %d\n", |
||
857 | quads_transferred, sector_quads_remaining, port); |
||
858 | |||
859 | int total_len = ATA_SECT_SIZE; |
||
860 | ulong *sata_data_ptr = (void*) ( |
||
861 | port ? SATA_DATA_MUX_RAM1 : SATA_DATA_MUX_RAM0) |
||
862 | + ((total_len - 8) % 2048); |
||
863 | |||
864 | *candidate = *sata_data_ptr; |
||
865 | *(candidate + 1) = *(sata_data_ptr + 1); |
||
866 | } |
||
867 | } |
||
868 | |||
869 | |||
870 | void ide_input_data(int device, ulong *sect_buf, int words) |
||
871 | { |
||
872 | /* Only permit accesses to disks found to be present during ide_preinit() */ |
||
873 | if (!disk_present[device]) { |
||
874 | return; |
||
875 | } |
||
876 | |||
877 | /* Select the required internal SATA drive */ |
||
878 | device_select(device); |
||
879 | |||
880 | /* Start the DMA channel receiving data from the SATA core into the passed buffer */ |
||
881 | dma_start_read(sect_buf, words << 2); |
||
882 | |||
883 | /* Sata core should finish before DMA */ |
||
884 | if (wait_not_busy(device, 30)) { |
||
885 | printf("Timed out of wait for SATA device %d to have BUSY clear\n", |
||
886 | device); |
||
887 | } |
||
888 | if (!wait_no_error(device)) { |
||
889 | printf("oxnas_sata_output_data() Wait for ATA no-error timed-out\n"); |
||
890 | } |
||
891 | |||
892 | /* Wait for DMA to finish */ |
||
893 | if (!wait_dma_not_busy(device)) { |
||
894 | printf("Timed out of wait for DMA channel for SATA device %d to have in-progress clear\n", |
||
895 | device); |
||
896 | } |
||
897 | |||
898 | if (words == ATA_SECTORWORDS) |
||
899 | sata_bug_6320_workaround(device, sect_buf + words - 2); |
||
900 | } |
||
901 | |||
902 | static u32 scr_read(int device, unsigned int sc_reg) |
||
903 | { |
||
904 | /* Setup adr of required register. std regs start eight into async region */ |
||
905 | *(sata_regs_base[device] + SATA_LINK_RD_ADDR) = sc_reg |
||
906 | * 4+ SATA_STD_ASYNC_REGS_OFF; |
||
907 | |||
908 | /* Wait for data to be available */ |
||
909 | int loops = MAX_SRC_READ_LOOPS; |
||
910 | do { |
||
911 | if (*(sata_regs_base[device] + SATA_LINK_CONTROL) & 1UL) { |
||
912 | break; |
||
913 | } |
||
914 | udelay(10); |
||
915 | } while (--loops); |
||
916 | |||
917 | if (!loops) { |
||
918 | printf("scr_read() Timed out of wait for read completion\n"); |
||
919 | } |
||
920 | |||
921 | /* Read the data from the async register */ |
||
922 | return *(sata_regs_base[device] + SATA_LINK_DATA); |
||
923 | } |
||
924 | |||
925 | static void scr_write(int device, unsigned int sc_reg, u32 val) |
||
926 | { |
||
927 | /* Setup the data for the write */ |
||
928 | *(sata_regs_base[device] + SATA_LINK_DATA) = val; |
||
929 | |||
930 | /* Setup adr of required register. std regs start eight into async region */ |
||
931 | *(sata_regs_base[device] + SATA_LINK_WR_ADDR) = sc_reg |
||
932 | * 4+ SATA_STD_ASYNC_REGS_OFF; |
||
933 | |||
934 | /* Wait for data to be written */ |
||
935 | int loops = MAX_SRC_WRITE_LOOPS; |
||
936 | do { |
||
937 | if (*(sata_regs_base[device] + SATA_LINK_CONTROL) & 1UL) { |
||
938 | break; |
||
939 | } |
||
940 | udelay(10); |
||
941 | } while (--loops); |
||
942 | |||
943 | if (!loops) { |
||
944 | printf("scr_write() Timed out of wait for write completion\n"); |
||
945 | } |
||
946 | } |
||
947 | extern void workaround5458(void); |
||
948 | |||
949 | #define PHY_LOOP_COUNT 25 /* Wait for upto 5 seconds for PHY to be found */ |
||
950 | #define LOS_AND_TX_LVL 0x2988 |
||
951 | #define TX_ATTEN 0x55629 |
||
952 | |||
953 | static int phy_reset(int device) |
||
954 | { |
||
955 | int phy_status = 0; |
||
956 | int loops = 0; |
||
957 | |||
958 | scr_write(device, (0x60 - SATA_STD_ASYNC_REGS_OFF) / 4, LOS_AND_TX_LVL); |
||
959 | scr_write(device, (0x70 - SATA_STD_ASYNC_REGS_OFF) / 4, TX_ATTEN); |
||
960 | |||
961 | /* limit it to Gen-1 SATA (1.5G) */ |
||
962 | scr_write(device, SATA_SCR_CONTROL, 0x311); /* Issue phy wake & core reset */ |
||
963 | scr_read(device, SATA_SCR_STATUS); /* Dummy read; flush */ |
||
964 | udelay(1000); |
||
965 | scr_write(device, SATA_SCR_CONTROL, 0x310); /* Issue phy wake & clear core reset */ |
||
966 | |||
967 | /* Wait for upto 5 seconds for PHY to become ready */ |
||
968 | do { |
||
969 | udelay(200000); |
||
970 | if ((scr_read(device, SATA_SCR_STATUS) & 0xf) == 3) { |
||
971 | scr_write(device, SATA_SCR_ERROR, ~0); |
||
972 | phy_status = 1; |
||
973 | break; |
||
974 | } |
||
975 | //printf("No SATA PHY found status:0x%x\n", scr_read(device, SATA_SCR_STATUS)); |
||
976 | } while (++loops < PHY_LOOP_COUNT); |
||
977 | |||
978 | if (phy_status) { |
||
979 | udelay(500000); /* wait half a second */ |
||
980 | } |
||
981 | |||
982 | return phy_status; |
||
983 | } |
||
984 | |||
985 | #define FIS_LOOP_COUNT 25 /* Wait for upto 5 seconds for FIS to be received */ |
||
986 | static int wait_FIS(int device) |
||
987 | { |
||
988 | int status = 0; |
||
989 | int loops = 0; |
||
990 | |||
991 | do { |
||
992 | udelay(200000); |
||
993 | if (ide_inb(device, ATA_PORT_NSECT) > 0) { |
||
994 | status = 1; |
||
995 | break; |
||
996 | } |
||
997 | } while (++loops < FIS_LOOP_COUNT); |
||
998 | |||
999 | return status; |
||
1000 | } |
||
1001 | |||
1002 | |||
1003 | #define SATA_PHY_ASIC_STAT (0x44900000) |
||
1004 | #define SATA_PHY_ASIC_DATA (0x44900004) |
||
1005 | |||
1006 | /** |
||
1007 | * initialise functions and macros for ASIC implementation |
||
1008 | */ |
||
1009 | #define PH_GAIN 2 |
||
1010 | #define FR_GAIN 3 |
||
1011 | #define PH_GAIN_OFFSET 6 |
||
1012 | #define FR_GAIN_OFFSET 8 |
||
1013 | #define PH_GAIN_MASK (0x3 << PH_GAIN_OFFSET) |
||
1014 | #define FR_GAIN_MASK (0x3 << FR_GAIN_OFFSET) |
||
1015 | #define USE_INT_SETTING (1<<5) |
||
1016 | |||
1017 | #define CR_READ_ENABLE (1<<16) |
||
1018 | #define CR_WRITE_ENABLE (1<<17) |
||
1019 | #define CR_CAP_DATA (1<<18) |
||
1020 | |||
1021 | static void wait_cr_ack(void) |
||
1022 | { |
||
1023 | while ((readl(SATA_PHY_ASIC_STAT) >> 16) & 0x1f) |
||
1024 | /* wait for an ack bit to be set */; |
||
1025 | } |
||
1026 | |||
1027 | static unsigned short read_cr(unsigned short address) |
||
1028 | { |
||
1029 | writel(address, SATA_PHY_ASIC_STAT); |
||
1030 | wait_cr_ack(); |
||
1031 | writel(CR_READ_ENABLE, SATA_PHY_ASIC_DATA); |
||
1032 | wait_cr_ack(); |
||
1033 | return readl(SATA_PHY_ASIC_STAT); |
||
1034 | } |
||
1035 | |||
1036 | static void write_cr(unsigned short data, unsigned short address) |
||
1037 | { |
||
1038 | writel(address, SATA_PHY_ASIC_STAT); |
||
1039 | wait_cr_ack(); |
||
1040 | writel((data | CR_CAP_DATA), SATA_PHY_ASIC_DATA); |
||
1041 | wait_cr_ack(); |
||
1042 | writel(CR_WRITE_ENABLE, SATA_PHY_ASIC_DATA); |
||
1043 | wait_cr_ack(); |
||
1044 | return; |
||
1045 | } |
||
1046 | |||
1047 | void workaround5458(void) |
||
1048 | { |
||
1049 | unsigned i; |
||
1050 | |||
1051 | for (i = 0; i < 2; i++) { |
||
1052 | unsigned short rx_control = read_cr(0x201d + (i << 8)); |
||
1053 | rx_control &= ~(PH_GAIN_MASK | FR_GAIN_MASK); |
||
1054 | rx_control |= PH_GAIN << PH_GAIN_OFFSET; |
||
1055 | rx_control |= FR_GAIN << FR_GAIN_OFFSET; |
||
1056 | rx_control |= USE_INT_SETTING; |
||
1057 | write_cr(rx_control, 0x201d + (i << 8)); |
||
1058 | } |
||
1059 | } |
||
1060 | |||
1061 | int ide_preinit(void) |
||
1062 | { |
||
1063 | int num_disks_found = 0; |
||
1064 | |||
1065 | /* Initialise records of which disks are present to all present */ |
||
1066 | int i; |
||
1067 | for (i = 0; i < CONFIG_SYS_IDE_MAXDEVICE; i++) { |
||
1068 | disk_present[i] = 1; |
||
1069 | } |
||
1070 | |||
1071 | /* Block reset SATA and DMA cores */ |
||
1072 | reset_block(SYS_CTRL_RST_SATA, 1); |
||
1073 | reset_block(SYS_CTRL_RST_SATA_LINK, 1); |
||
1074 | reset_block(SYS_CTRL_RST_SATA_PHY, 1); |
||
1075 | reset_block(SYS_CTRL_RST_SGDMA, 1); |
||
1076 | |||
1077 | /* Enable clocks to SATA and DMA cores */ |
||
1078 | enable_clock(SYS_CTRL_CLK_SATA); |
||
1079 | enable_clock(SYS_CTRL_CLK_DMA); |
||
1080 | |||
1081 | udelay(5000); |
||
1082 | reset_block(SYS_CTRL_RST_SATA_PHY, 0); |
||
1083 | udelay(50); |
||
1084 | reset_block(SYS_CTRL_RST_SATA, 0); |
||
1085 | reset_block(SYS_CTRL_RST_SATA_LINK, 0); |
||
1086 | udelay(50); |
||
1087 | reset_block(SYS_CTRL_RST_SGDMA, 0); |
||
1088 | udelay(100); |
||
1089 | /* Apply the Synopsis SATA PHY workarounds */ |
||
1090 | workaround5458(); |
||
1091 | udelay(10000); |
||
1092 | |||
1093 | /* disable and clear core interrupts */ |
||
1094 | *((unsigned long*) SATA_HOST_REGS_BASE + SATA_INT_ENABLE_CLR_OFF) = |
||
1095 | ~0UL; |
||
1096 | *((unsigned long*) SATA_HOST_REGS_BASE + SATA_INT_CLR_OFF) = ~0UL; |
||
1097 | |||
1098 | int device; |
||
1099 | for (device = 0; device < CONFIG_SYS_IDE_MAXDEVICE; device++) { |
||
1100 | int found = 0; |
||
1101 | int retries = 1; |
||
1102 | |||
1103 | /* Disable SATA interrupts */ |
||
1104 | *(sata_regs_base[device] + SATA_INT_ENABLE_CLR_OFF) = ~0UL; |
||
1105 | |||
1106 | /* Clear any pending SATA interrupts */ |
||
1107 | *(sata_regs_base[device] + SATA_INT_CLR_OFF) = ~0UL; |
||
1108 | |||
1109 | do { |
||
1110 | /* clear sector count register for FIS detection */ |
||
1111 | ide_outb(device, ATA_PORT_NSECT, 0); |
||
1112 | |||
1113 | /* Get the PHY working */ |
||
1114 | if (!phy_reset(device)) { |
||
1115 | printf("SATA PHY not ready for device %d\n", |
||
1116 | device); |
||
1117 | break; |
||
1118 | } |
||
1119 | |||
1120 | if (!wait_FIS(device)) { |
||
1121 | printf("No FIS received from device %d\n", |
||
1122 | device); |
||
1123 | } else { |
||
1124 | if ((scr_read(device, SATA_SCR_STATUS) & 0xf) |
||
1125 | == 0x3) { |
||
1126 | if (wait_not_busy(device, 30)) { |
||
1127 | printf("Timed out of wait for SATA device %d to have BUSY clear\n", |
||
1128 | device); |
||
1129 | } else { |
||
1130 | ++num_disks_found; |
||
1131 | found = 1; |
||
1132 | } |
||
1133 | } else { |
||
1134 | printf("No SATA device %d found, PHY status = 0x%08x\n", |
||
1135 | device, |
||
1136 | scr_read( |
||
1137 | device, |
||
1138 | SATA_SCR_STATUS)); |
||
1139 | } |
||
1140 | break; |
||
1141 | } |
||
1142 | } while (retries--); |
||
1143 | |||
1144 | /* Record whether disk is present, so won't attempt to access it later */ |
||
1145 | disk_present[device] = found; |
||
1146 | } |
||
1147 | |||
1148 | /* post disk detection clean-up */ |
||
1149 | for (device = 0; device < CONFIG_SYS_IDE_MAXDEVICE; device++) { |
||
1150 | if (disk_present[device]) { |
||
1151 | /* set as ata-5 (28-bit) */ |
||
1152 | *(sata_regs_base[device] + SATA_DRIVE_CONTROL_OFF) = |
||
1153 | 0UL; |
||
1154 | |||
1155 | /* clear phy/link errors */ |
||
1156 | scr_write(device, SATA_SCR_ERROR, ~0); |
||
1157 | |||
1158 | /* clear host errors */ |
||
1159 | *(sata_regs_base[device] + SATA_CONTROL_OFF) |= |
||
1160 | SATA_SCTL_CLR_ERR; |
||
1161 | |||
1162 | /* clear interrupt register as this clears the error bit in the IDE |
||
1163 | status register */ |
||
1164 | *(sata_regs_base[device] + SATA_INT_CLR_OFF) = ~0UL; |
||
1165 | } |
||
1166 | } |
||
1167 | |||
1168 | return !num_disks_found; |
||
1169 | } |
||
1170 |