Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/*
* (C) Copyright 2000-2002
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*/
/*
* IDE support
*/
#include <common.h>
#include <config.h>
#include <watchdog.h>
#include <command.h>
#include <image.h>
#include <asm/byteorder.h>
#if defined(CONFIG_IDE_8xx_DIRECT) || defined(CONFIG_IDE_PCMCIA)
# include <pcmcia.h>
#endif
#ifdef CONFIG_8xx
# include <mpc8xx.h>
#endif
#include <ide.h>
#include <ata.h>
#ifdef CONFIG_STATUS_LED
# include <status_led.h>
#endif
#ifdef __MIPS__
/* Macros depend on this variable */
static unsigned long mips_io_port_base = 0;
#endif
#ifdef CONFIG_SHOW_BOOT_PROGRESS
# include <status_led.h>
# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg)
#else
# define SHOW_BOOT_PROGRESS(arg)
#endif
#undef IDE_DEBUG
#ifdef IDE_DEBUG
#define PRINTF(fmt,args...) printf (fmt ,##args)
#else
#define PRINTF(fmt,args...)
#endif
#if (CONFIG_COMMANDS & CFG_CMD_IDE)
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/* Timings for IDE Interface
*
* SETUP / LENGTH / HOLD - cycles valid for 50 MHz clk
* 70 165 30 PIO-Mode 0, [ns]
* 4 9 2 [Cycles]
* 50 125 20 PIO-Mode 1, [ns]
* 3 7 2 [Cycles]
* 30 100 15 PIO-Mode 2, [ns]
* 2 6 1 [Cycles]
* 30 80 10 PIO-Mode 3, [ns]
* 2 5 1 [Cycles]
* 25 70 10 PIO-Mode 4, [ns]
* 2 4 1 [Cycles]
*/
const static pio_config_t pio_config_ns [IDE_MAX_PIO_MODE+1] =
{
/* Setup Length Hold */
{ 70, 165, 30 }, /* PIO-Mode 0, [ns] */
{ 50, 125, 20 }, /* PIO-Mode 1, [ns] */
{ 30, 101, 15 }, /* PIO-Mode 2, [ns] */
{ 30, 80, 10 }, /* PIO-Mode 3, [ns] */
{ 25, 70, 10 }, /* PIO-Mode 4, [ns] */
};
static pio_config_t pio_config_clk [IDE_MAX_PIO_MODE+1];
#ifndef CFG_PIO_MODE
#define CFG_PIO_MODE 0 /* use a relaxed default */
#endif
static int pio_mode = CFG_PIO_MODE;
/* Make clock cycles and always round up */
#define PCMCIA_MK_CLKS( t, T ) (( (t) * (T) + 999U ) / 1000U )
#endif /* CONFIG_IDE_8xx_DIRECT */
/* ------------------------------------------------------------------------- */
/* Current I/O Device */
static int curr_device = -1;
/* Current offset for IDE0 / IDE1 bus access */
ulong ide_bus_offset[CFG_IDE_MAXBUS] = {
#if defined(CFG_ATA_IDE0_OFFSET)
CFG_ATA_IDE0_OFFSET,
#endif
#if defined(CFG_ATA_IDE1_OFFSET) && (CFG_IDE_MAXBUS > 1)
CFG_ATA_IDE1_OFFSET,
#endif
};
#define ATA_CURR_BASE(dev) (CFG_ATA_BASE_ADDR+ide_bus_offset[IDE_BUS(dev)])
#else
static int ide_bus_ok[CFG_IDE_MAXBUS] = {0,};
#endif
static block_dev_desc_t ide_dev_desc[CFG_IDE_MAXDEVICE];
/* ------------------------------------------------------------------------- */
#ifdef CONFIG_IDE_LED
static void ide_led (uchar led, uchar status);
#else
extern void ide_led (uchar led, uchar status);
#endif
#else
#else
extern void ide_led(uchar led, uchar status);
#define LED_IDE1 1
#define LED_IDE2 2
#define CONFIG_IDE_LED 1
#define DEVICE_LED(x) 1
#endif
#endif
#ifdef CONFIG_IDE_RESET
static void ide_reset (void);
#else
#define ide_reset() /* dummy */
#endif
static void ide_ident (block_dev_desc_t *dev_desc);
static uchar ide_wait (int dev, ulong t);
#define IDE_TIME_OUT 2000 /* 2 sec timeout */
#define ATAPI_TIME_OUT 7000 /* 7 sec timeout (5 sec seems to work...) */
#define IDE_SPIN_UP_TIME_OUT 5000 /* 5 sec spin-up timeout */
static void __inline__ ide_outb(int dev, int port, unsigned char val);
static unsigned char __inline__ ide_inb(int dev, int port);
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
static void input_data(int dev, ulong *sect_buf, int words);
static void output_data(int dev, ulong *sect_buf, int words);
static void ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len);
#ifdef CONFIG_ATAPI
static void atapi_inquiry(block_dev_desc_t *dev_desc);
ulong atapi_read (int device, ulong blknr, ulong blkcnt, ulong *buffer);
#endif
#ifdef CONFIG_IDE_8xx_DIRECT
static void set_pcmcia_timing (int pmode);
#endif
/* ------------------------------------------------------------------------- */
int do_ide (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
int rcode = 0;
switch (argc) {
case 0:
case 1:
printf ("Usage:\n%s\n", cmdtp->usage);
return 1;
case 2:
if (strncmp(argv[1],"res",3) == 0) {
Loading
Loading full blame...