1 //==========================================================================
5 // Flash programming to support ATA flash on Freescale MXC platforms
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41 //#####DESCRIPTIONBEGIN####
43 // Author(s): Mahesh Mahadevan <mahesh.mahadevan@freescale.com>
44 // Contributors: Mahesh Mahadevan <mahesh.mahadevan@freescale.com>
45 // Date: 2008-11-18 Initial version
47 //==========================================================================
50 #include <cyg/hal/hal_cache.h>
52 #include <cyg/io/mxc_ata.h>
55 static struct fsl_ata_time_regs {
56 unsigned char time_off, time_on, time_1, time_2w;
57 unsigned char time_2r, time_ax, time_pio_rdx, time_4;
58 unsigned char time_9, time_m, time_jn, time_d;
59 unsigned char time_k, time_ack, time_env, time_rpx;
60 unsigned char time_zah, time_mlix, time_dvh, time_dzfs;
61 unsigned char time_dvs, time_cvh, time_ss, time_cyc;
63 extern void mxc_ata_iomux_setup(void);
66 * This structure contains the timing parameters for
67 * ATA bus timing in the 5 PIO modes. The timings
68 * are in nanoseconds, and are converted to clock
69 * cycles before being stored in the ATA controller
73 short t0, t1, t2_8, t2_16, t2i, t4, t9, tA;
76 .t0 = 600, .t1 = 70, .t2_8 = 290, .t2_16 = 165, .t2i = 40, .t4 =
77 30, .t9 = 20, .tA = 50,},
79 .t0 = 383, .t1 = 50, .t2_8 = 290, .t2_16 = 125, .t2i = 0, .t4 =
80 20, .t9 = 15, .tA = 50,},
82 .t0 = 240, .t1 = 30, .t2_8 = 290, .t2_16 = 100, .t2i = 0, .t4 =
83 15, .t9 = 10, .tA = 50,},
85 .t0 = 180, .t1 = 30, .t2_8 = 80, .t2_16 = 80, .t2i = 0, .t4 =
86 10, .t9 = 10, .tA = 50,},
88 .t0 = 120, .t1 = 25, .t2_8 = 70, .t2_16 = 70, .t2i = 0, .t4 =
89 10, .t9 = 10, .tA = 50,},
92 #define NR_PIO_SPECS (sizeof pio_specs / sizeof pio_specs[0])
94 static void update_timing_config(struct fsl_ata_time_regs *tp)
96 unsigned int *lp = (unsigned int *) tp;
97 unsigned int *ctlp = (unsigned int *) ATA_BASE_ADDR;
100 for (i = 0; i < 5; i++) {
107 static void set_ata_bus_timing(unsigned char xfer_mode)
109 int speed = xfer_mode;
110 struct fsl_ata_time_regs tr = { 0 };
111 int T = 1 * 1000 * 1000 * 1000 / get_main_clock(IPG_CLK);
113 if (speed >= NR_PIO_SPECS)
118 tr.time_1 = (pio_specs[speed].t1 + T) / T;
119 tr.time_2w = (pio_specs[speed].t2_8 + T) / T;
121 tr.time_2r = (pio_specs[speed].t2_8 + T) / T;
122 tr.time_ax = (pio_specs[speed].tA + T) / T + 2;
124 tr.time_4 = (pio_specs[speed].t4 + T) / T;
126 tr.time_9 = (pio_specs[speed].t9 + T) / T;
128 update_timing_config(&tr);
131 static unsigned char ata_sff_busy_wait(unsigned int bits, unsigned int max, unsigned int delay)
133 unsigned char status;
134 unsigned int iterations = 1;
141 status = readb(ATA_BASE_ADDR + FSL_ATA_DCDR);
144 } while (status != 0xff && (status & bits) && (iterations > 0));
146 if (iterations == 0) {
147 diag_printf("ata_sff_busy_wait timeout status = %x\n", status);
154 static void ata_sff_exec_command(unsigned short cmd)
156 writeb(cmd, ATA_BASE_ADDR + FSL_ATA_DCDR);
157 readb(ATA_BASE_ADDR + FSL_ATA_DRIVE_CONTROL);
161 static int ata_dev_set_feature(unsigned int feature)
163 unsigned char status;
165 writeb(feature, ATA_BASE_ADDR + FSL_ATA_DFTR);
166 //Issue Set feature command
167 ata_sff_exec_command(ATA_CMD_SET_FEATURES);
168 status = ata_sff_busy_wait(ATA_BUSY, 5000, 500);
172 if (status & ATA_ERR) {
178 void ata_id_string(int *id, unsigned char *s,
179 unsigned int ofs, unsigned int len)
198 * ata_id_c_string - Convert IDENTIFY DEVICE page into C string
199 * @id: IDENTIFY DEVICE results we will examine
200 * @s: string into which data is output
201 * @ofs: offset into identify device page
202 * @len: length of string to return. must be an odd number.
204 * This function is identical to ata_id_string except that it
205 * trims trailing spaces and terminates the resulting string with
206 * null. @len must be actual maximum length (even number) + 1.
211 void ata_id_c_string(int *id)
213 unsigned char model_num[ATA_ID_PROD_LEN + 1];
215 ata_id_string(id, model_num, ATA_ID_PROD, ATA_ID_PROD_LEN);
217 model_num[ATA_ID_PROD_LEN] = '\0';
219 diag_printf("ATA Model number = %s\n", model_num);
222 static int read_dev_id(void)
224 int i, tried_spinup = 0;
225 int CIS[256], err_mask = 0;
229 //identify device command
230 ata_sff_exec_command(ATA_CMD_ID_ATA);
231 if (ata_sff_busy_wait(ATA_BUSY, 5000, 500) == 0xff)
233 memset((void *)CIS, 0, sizeof(int) * 256);
235 for (i=0 ; i < 256; i++ ) {
236 CIS[i] = readw(ATA_BASE_ADDR + FSL_ATA_DRIVE_DATA);
239 if ((CIS[0] & (1 << 15)) == 0) {
240 if (!tried_spinup && (CIS[2] == 0x37c8 || CIS[2] == 0x738c)) {
242 err_mask = ata_dev_set_feature(0x7);
243 if (err_mask && CIS[2] != 0x738c) {
244 diag_printf("ATA SPINUP Failed \n");
247 if (CIS[2] == 0x37c8)
250 ata_id_c_string(CIS);
253 diag_printf("ATA IDENTIFY DEVICE command Failed \n");
259 static void write_sector_pio(unsigned int *addr, int num_of_sectors)
263 for (i = 0; i < num_of_sectors; i++) {
264 for (j= 0; j < ATA_SECTOR_SIZE; j = j + 4) {
265 /* Write 4 bytes in each iteration */
266 writew((*addr & 0xFFFF), ATA_BASE_ADDR + FSL_ATA_DRIVE_DATA) ;
267 writew(((*addr >> 16 ) & 0xFFFF), ATA_BASE_ADDR + FSL_ATA_DRIVE_DATA) ;
270 ata_sff_busy_wait(ATA_BUSY, 5000, 50);
272 readb(ATA_BASE_ADDR + FSL_ATA_DRIVE_CONTROL);
275 static void read_sector_pio(unsigned int *addr, int num_of_sectors)
278 unsigned int data[2];
280 for (i = 0; i < num_of_sectors; i++) {
281 for (j = 0; j < ATA_SECTOR_SIZE; j = j + 4) {
282 /* Read 4 bytes in each iteration */
283 data[0] = readw(ATA_BASE_ADDR + FSL_ATA_DRIVE_DATA);
284 data[1] = readw(ATA_BASE_ADDR + FSL_ATA_DRIVE_DATA);
285 *addr = ((data[1] << 16) & 0xFFFF0000) | (data[0] & 0xFFFF);
288 ata_sff_busy_wait(ATA_BUSY, 5000, 10);
290 readb(ATA_BASE_ADDR + FSL_ATA_DRIVE_CONTROL);
293 void ata_hwr_init(void)
295 mxc_ata_iomux_setup();
297 /* Deassert the reset bit to enable the interface */
298 writel(FSL_ATA_CTRL_ATA_RST_B, ATA_BASE_ADDR + FSL_ATA_CONTROL);
299 writel(FSL_ATA_CTRL_ATA_RST_B | FSL_ATA_CTRL_FIFO_RST_B, ATA_BASE_ADDR + FSL_ATA_CONTROL);
300 /* Set initial timing and mode */
301 set_ata_bus_timing(PIO_XFER_MODE_4);
302 writeb(20, ATA_BASE_ADDR+ FSL_ATA_FIFO_ALARM) ; /* set fifo alarm to 20 halfwords, midway */
305 writeb(ATA_IEN, ATA_BASE_ADDR + FSL_ATA_DRIVE_CONTROL);
307 writeb(ATA_IEN | ATA_SRST, ATA_BASE_ADDR + FSL_ATA_DRIVE_CONTROL);
309 writeb(ATA_IEN, ATA_BASE_ADDR + FSL_ATA_DRIVE_CONTROL);
311 writeb(0, ATA_BASE_ADDR + FSL_ATA_DDHR);
312 if (ata_sff_busy_wait(ATA_BUSY | ATA_DRQ, 6000, 1000) == 0xff) {
313 diag_printf("Failed to initialize the ATA drive\n");
317 /* Read the device ID */
319 diag_printf("Failed to initialize the ATA drive\n");
322 static void ata_read_buf(int argc, char *argv[]);
323 RedBoot_cmd("ata_read",
325 "-f <flash_addr> -b <mem_base> -l <image_length>",
329 static void ata_program_buf(int argc, char *argv[]);
330 RedBoot_cmd("ata_write",
332 "-f <flash_addr> -b <mem_base> -l <image_length>",
336 static void ata_read_buf(int argc, char *argv[])
338 unsigned int total_sectors, num_of_sectors;
339 unsigned char lba_addr[4];
340 CYG_ADDRESS addr, data;
341 unsigned long sect_addr;
343 unsigned char status;
344 bool mem_addr_set = false;
345 bool flash_addr_set = false;
346 bool length_set = false;
347 struct option_info opts[3];
349 init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM,
350 (void *)&data, (bool *)&mem_addr_set, "memory base address");
351 init_opts(&opts[1], 'f', true, OPTION_ARG_TYPE_NUM,
352 (void *)&addr, (bool *)&flash_addr_set, "FLASH memory base address");
353 init_opts(&opts[2], 'l', true, OPTION_ARG_TYPE_NUM,
354 (void *)&len, (bool *)&length_set, "image length [in FLASH]");
356 if (!scan_opts(argc, argv, 1, opts, 3, 0, 0, 0)) {
357 diag_printf("invalid arguments");
361 if (!mem_addr_set || !flash_addr_set || !length_set) {
362 diag_printf("required parameter missing\n");
366 if ((addr % ATA_SECTOR_SIZE) != 0) {
367 diag_printf("Need a sector-aligned (512 byte) address in ATA\n\n");
371 total_sectors = (len / ATA_SECTOR_SIZE);
372 sect_addr = addr / ATA_SECTOR_SIZE;
375 lba_addr[0] = sect_addr & 0xFF;
376 lba_addr[1] = (sect_addr >> 8) & 0xFF;
377 lba_addr[2] = (sect_addr >> 16) & 0xFF;
378 /* Enable the LBA bit */
379 lba_addr[3] = (1 << 6) | ((sect_addr >> 24) & 0xF);
381 if (total_sectors >= MAX_NUMBER_OF_SECTORS)
384 num_of_sectors = total_sectors;
386 ata_sff_busy_wait(ATA_BUSY | ATA_DRQ, 5000, 50);
387 writeb(num_of_sectors, ATA_BASE_ADDR + FSL_ATA_DSCR);
388 writeb(lba_addr[0], ATA_BASE_ADDR + FSL_ATA_DSNR);
389 writeb(lba_addr[1], ATA_BASE_ADDR + FSL_ATA_DCLR);
390 writeb(lba_addr[2], ATA_BASE_ADDR + FSL_ATA_DCHR);
391 writeb(lba_addr[3], ATA_BASE_ADDR + FSL_ATA_DDHR);
394 ata_sff_exec_command(ATA_CMD_READ);
395 status = ata_sff_busy_wait(ATA_BUSY, 5000, 50);
396 if (status & ATA_ERR) {
397 diag_printf("Error while issuing ATA Read command\n");
400 if (num_of_sectors == 0) {
401 read_sector_pio((unsigned int *)data, MAX_NUMBER_OF_SECTORS);
402 total_sectors -= MAX_NUMBER_OF_SECTORS;
403 sect_addr += MAX_NUMBER_OF_SECTORS;
404 data += (MAX_NUMBER_OF_SECTORS * ATA_SECTOR_SIZE);
406 read_sector_pio((unsigned int *)data, num_of_sectors);
407 total_sectors -= num_of_sectors;
408 sect_addr += num_of_sectors;
409 data += (num_of_sectors * ATA_SECTOR_SIZE);
411 } while (total_sectors > 0);
414 static void ata_program_buf(int argc, char *argv[])
416 int total_sectors, num_of_sectors, lba_addr[4];
417 CYG_ADDRESS addr, data;
419 unsigned long sect_addr;
420 unsigned char status;
421 bool mem_addr_set = false;
422 bool flash_addr_set = false;
423 bool length_set = false;
424 struct option_info opts[3];
426 init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM,
427 (void *)&data, (bool *)&mem_addr_set, "memory base address");
428 init_opts(&opts[1], 'f', true, OPTION_ARG_TYPE_NUM,
429 (void *)&addr, (bool *)&flash_addr_set, "FLASH memory base address");
430 init_opts(&opts[2], 'l', true, OPTION_ARG_TYPE_NUM,
431 (void *)&len, (bool *)&length_set, "image length [in FLASH]");
433 if (!scan_opts(argc, argv, 1, opts, 3, 0, 0, 0)) {
434 diag_printf("invalid arguments");
438 if (!mem_addr_set || !flash_addr_set || !length_set) {
439 diag_printf("required parameter missing\n");
443 if ((addr % ATA_SECTOR_SIZE) != 0) {
444 diag_printf("Need a sector-aligned (512 byte) address in ATA\n\n");
448 total_sectors = (len / ATA_SECTOR_SIZE);
449 sect_addr = addr / ATA_SECTOR_SIZE;
452 lba_addr[0] = sect_addr & 0xFF;
453 lba_addr[1] = (sect_addr >> 8) & 0xFF;
454 lba_addr[2] = (sect_addr >> 16) & 0xFF;
455 /* Enable the LBA bit */
456 lba_addr[3] = (1 << 6) | ((sect_addr >> 24) & 0xF);
458 if (total_sectors >= MAX_NUMBER_OF_SECTORS)
461 num_of_sectors = total_sectors;
463 ata_sff_busy_wait(ATA_BUSY | ATA_DRQ, 5000, 50);
464 writeb(num_of_sectors, ATA_BASE_ADDR + FSL_ATA_DSCR);
465 writeb(lba_addr[0], ATA_BASE_ADDR + FSL_ATA_DSNR);
466 writeb(lba_addr[1], ATA_BASE_ADDR + FSL_ATA_DCLR);
467 writeb(lba_addr[2], ATA_BASE_ADDR + FSL_ATA_DCHR);
468 writeb(lba_addr[3], ATA_BASE_ADDR + FSL_ATA_DDHR);
470 //Issue Write command
471 ata_sff_exec_command(ATA_CMD_WRITE);
472 ata_sff_busy_wait(ATA_BUSY, 5000, 50);
473 if (status & ATA_ERR) {
474 diag_printf("Error while issuing ATA Write command\n");
477 if (num_of_sectors == 0) {
478 write_sector_pio((unsigned int *)data, MAX_NUMBER_OF_SECTORS);
479 total_sectors -= MAX_NUMBER_OF_SECTORS;
480 sect_addr += MAX_NUMBER_OF_SECTORS;
481 data += (MAX_NUMBER_OF_SECTORS * ATA_SECTOR_SIZE);
483 write_sector_pio((unsigned int *)data, num_of_sectors);
484 total_sectors -= num_of_sectors;
485 sect_addr += num_of_sectors;
486 data += (num_of_sectors * ATA_SECTOR_SIZE);
488 } while (total_sectors > 0);