X-Git-Url: https://git.kernelconcepts.de/?p=karo-tx-uboot.git;a=blobdiff_plain;f=common%2Fcmd_ide.c;h=ecd3e9d64f086318578af7579e125dabdf0c381b;hp=bbede1ce818caed3f96b31d72674295906557dd0;hb=ffcdbd85b18e0e34ce296a4bfa90ec441e9db6c8;hpb=34c202c7eb24d04c577722c14b90fbedf517fd22 diff --git a/common/cmd_ide.c b/common/cmd_ide.c index bbede1ce81..ecd3e9d64f 100644 --- a/common/cmd_ide.c +++ b/common/cmd_ide.c @@ -2,24 +2,7 @@ * (C) Copyright 2000-2011 * 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 - * + * SPDX-License-Identifier: GPL-2.0+ */ /* @@ -38,14 +21,6 @@ # include #endif -#ifdef CONFIG_8xx -# include -#endif - -#ifdef CONFIG_MPC5xxx -#include -#endif - #include #include @@ -53,10 +28,6 @@ # include #endif -#ifdef CONFIG_IDE_8xx_DIRECT -DECLARE_GLOBAL_DATA_PTR; -#endif - #ifdef __PPC__ # define EIEIO __asm__ volatile ("eieio") # define SYNC __asm__ volatile ("sync") @@ -65,45 +36,6 @@ DECLARE_GLOBAL_DATA_PTR; # define SYNC /* nothing */ #endif -#ifdef CONFIG_IDE_8xx_DIRECT -/* 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 CONFIG_SYS_PIO_MODE -#define CONFIG_SYS_PIO_MODE 0 /* use a relaxed default */ -#endif -static int pio_mode = CONFIG_SYS_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 */ @@ -124,19 +56,6 @@ static int ide_bus_ok[CONFIG_SYS_IDE_MAXBUS]; block_dev_desc_t ide_dev_desc[CONFIG_SYS_IDE_MAXDEVICE]; /* ------------------------------------------------------------------------- */ -#ifdef CONFIG_IDE_LED -# if !defined(CONFIG_BMS2003) && \ - !defined(CONFIG_CPC45) && \ - !defined(CONFIG_KUP4K) && \ - !defined(CONFIG_KUP4X) -static void ide_led (uchar led, uchar status); -#else -extern void ide_led (uchar led, uchar status); -#endif -#else -#define ide_led(a,b) /* dummy */ -#endif - #ifdef CONFIG_IDE_RESET static void ide_reset (void); #else @@ -152,8 +71,6 @@ static uchar ide_wait (int dev, ulong t); #define IDE_SPIN_UP_TIME_OUT 5000 /* 5 sec spin-up timeout */ -static void input_data(int dev, ulong *sect_buf, int words); -static void output_data(int dev, const ulong *sect_buf, int words); static void ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len); #ifndef CONFIG_SYS_ATA_PORT_ADDR @@ -162,14 +79,11 @@ 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, lbaint_t blknr, ulong blkcnt, void *buffer); +static ulong atapi_read(int device, lbaint_t blknr, lbaint_t blkcnt, + void *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 *const argv[]) @@ -179,7 +93,7 @@ int do_ide(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) switch (argc) { case 0: case 1: - return cmd_usage(cmdtp); + return CMD_RET_USAGE; case 2: if (strncmp(argv[1], "res", 3) == 0) { puts("\nReset IDE" @@ -232,7 +146,7 @@ int do_ide(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) } return rcode; } - return cmd_usage(cmdtp); + return CMD_RET_USAGE; case 3: if (strncmp(argv[1], "dev", 3) == 0) { int dev = (int) simple_strtoul(argv[2], NULL, 10); @@ -266,7 +180,7 @@ int do_ide(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) return rcode; } - return cmd_usage(cmdtp); + return CMD_RET_USAGE; default: /* at least 4 args */ @@ -325,7 +239,7 @@ int do_ide(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) else return 1; } else { - return cmd_usage(cmdtp); + return CMD_RET_USAGE; } return rcode; @@ -334,159 +248,36 @@ int do_ide(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) int do_diskboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { - char *boot_device = NULL; - char *ep; - int dev, part = 0; - ulong addr, cnt; - disk_partition_t info; - image_header_t *hdr; - -#if defined(CONFIG_FIT) - const void *fit_hdr = NULL; -#endif - - show_boot_progress(41); - switch (argc) { - case 1: - addr = CONFIG_SYS_LOAD_ADDR; - boot_device = getenv("bootdevice"); - break; - case 2: - addr = simple_strtoul(argv[1], NULL, 16); - boot_device = getenv("bootdevice"); - break; - case 3: - addr = simple_strtoul(argv[1], NULL, 16); - boot_device = argv[2]; - break; - default: - show_boot_progress(-42); - return cmd_usage(cmdtp); - } - show_boot_progress(42); - - if (!boot_device) { - puts("\n** No boot device **\n"); - show_boot_progress(-43); - return 1; - } - show_boot_progress(43); - - dev = simple_strtoul(boot_device, &ep, 16); - - if (ide_dev_desc[dev].type == DEV_TYPE_UNKNOWN) { - printf("\n** Device %d not available\n", dev); - show_boot_progress(-44); - return 1; - } - show_boot_progress(44); - - if (*ep) { - if (*ep != ':') { - puts("\n** Invalid boot device, use `dev[:part]' **\n"); - show_boot_progress(-45); - return 1; - } - part = simple_strtoul(++ep, NULL, 16); - } - show_boot_progress(45); - if (get_partition_info(&ide_dev_desc[dev], part, &info)) { - show_boot_progress(-46); - return 1; - } - show_boot_progress(46); - if ((strncmp((char *)info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) - && - (strncmp((char *)info.type, BOOT_PART_COMP, sizeof(info.type)) != 0) - ) { - printf("\n** Invalid partition type \"%.32s\"" " (expect \"" - BOOT_PART_TYPE "\")\n", - info.type); - show_boot_progress(-47); - return 1; - } - show_boot_progress(47); - - printf("\nLoading from IDE device %d, partition %d: " - "Name: %.32s Type: %.32s\n", dev, part, info.name, info.type); - - debug("First Block: %ld, # of blocks: %ld, Block Size: %ld\n", - info.start, info.size, info.blksz); - - if (ide_dev_desc[dev]. - block_read(dev, info.start, 1, (ulong *) addr) != 1) { - printf("** Read error on %d:%d\n", dev, part); - show_boot_progress(-48); - return 1; - } - show_boot_progress(48); - - switch (genimg_get_format((void *) addr)) { - case IMAGE_FORMAT_LEGACY: - hdr = (image_header_t *) addr; + return common_diskboot(cmdtp, "ide", argc, argv); +} - show_boot_progress(49); +/* ------------------------------------------------------------------------- */ - if (!image_check_hcrc(hdr)) { - puts("\n** Bad Header Checksum **\n"); - show_boot_progress(-50); - return 1; - } - show_boot_progress(50); +__weak void ide_led(uchar led, uchar status) +{ +#if defined(CONFIG_IDE_LED) && defined(PER8_BASE) /* required by LED_PORT */ + static uchar led_buffer; /* Buffer for current LED status */ - image_print_contents(hdr); + uchar *led_port = LED_PORT; - cnt = image_get_image_size(hdr); - break; -#if defined(CONFIG_FIT) - case IMAGE_FORMAT_FIT: - fit_hdr = (const void *) addr; - puts("Fit image detected...\n"); + if (status) /* switch LED on */ + led_buffer |= led; + else /* switch LED off */ + led_buffer &= ~led; - cnt = fit_get_size(fit_hdr); - break; + *led_port = led_buffer; #endif - default: - show_boot_progress(-49); - puts("** Unknown image type\n"); - return 1; - } - - cnt += info.blksz - 1; - cnt /= info.blksz; - cnt -= 1; +} - if (ide_dev_desc[dev].block_read(dev, info.start + 1, cnt, - (ulong *)(addr + info.blksz)) != cnt) { - printf("** Read error on %d:%d\n", dev, part); - show_boot_progress(-51); - return 1; - } - show_boot_progress(51); - -#if defined(CONFIG_FIT) - /* This cannot be done earlier, we need complete FIT image in RAM first */ - if (genimg_get_format((void *) addr) == IMAGE_FORMAT_FIT) { - if (!fit_check_format(fit_hdr)) { - show_boot_progress(-140); - puts("** Bad FIT image format\n"); - return 1; - } - show_boot_progress(141); - fit_print_contents(fit_hdr); - } +#ifndef CONFIG_IDE_LED /* define LED macros, they are not used anyways */ +# define DEVICE_LED(x) 0 +# define LED_IDE1 1 +# define LED_IDE2 2 #endif - /* Loading ok, update default load address */ - - load_addr = addr; - - return bootm_maybe_autostart(cmdtp, argv[0]); -} - /* ------------------------------------------------------------------------- */ -inline void __ide_outb(int dev, int port, unsigned char val) +__weak void ide_outb(int dev, int port, unsigned char val) { debug("ide_outb (dev= %d, port= 0x%x, val= 0x%02x) : @ 0x%08lx\n", dev, port, val, @@ -505,10 +296,7 @@ inline void __ide_outb(int dev, int port, unsigned char val) #endif } -void ide_outb(int dev, int port, unsigned char val) - __attribute__ ((weak, alias("__ide_outb"))); - -inline unsigned char __ide_inb(int dev, int port) +__weak unsigned char ide_inb(int dev, int port) { uchar val; @@ -524,40 +312,16 @@ inline unsigned char __ide_inb(int dev, int port) return val; } -unsigned char ide_inb(int dev, int port) - __attribute__ ((weak, alias("__ide_inb"))); - -#ifdef CONFIG_TUNE_PIO -inline int __ide_set_piomode(int pio_mode) -{ - return 0; -} - -inline int ide_set_piomode(int pio_mode) - __attribute__ ((weak, alias("__ide_set_piomode"))); -#endif - void ide_init(void) { - -#ifdef CONFIG_IDE_8xx_DIRECT - volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; - volatile pcmconf8xx_t *pcmp = &(immr->im_pcmcia); -#endif unsigned char c; int i, bus; -#if defined(CONFIG_SC3) - unsigned int ata_reset_time = ATA_RESET_TIME; -#endif #ifdef CONFIG_IDE_8xx_PCCARD - extern int pcmcia_on(void); extern int ide_devices_found; /* Initialized in check_ide_device() */ #endif /* CONFIG_IDE_8xx_PCCARD */ #ifdef CONFIG_IDE_PREINIT - extern int ide_preinit(void); - WATCHDOG_RESET(); if (ide_preinit()) { @@ -566,40 +330,8 @@ void ide_init(void) } #endif /* CONFIG_IDE_PREINIT */ -#ifdef CONFIG_IDE_8xx_PCCARD - extern int pcmcia_on(void); - extern int ide_devices_found; /* Initialized in check_ide_device() */ - WATCHDOG_RESET(); - ide_devices_found = 0; - /* initialize the PCMCIA IDE adapter card */ - pcmcia_on(); - if (!ide_devices_found) - return; - udelay(1000000); /* 1 s */ -#endif /* CONFIG_IDE_8xx_PCCARD */ - - WATCHDOG_RESET(); - -#ifdef CONFIG_IDE_8xx_DIRECT - /* Initialize PIO timing tables */ - for (i = 0; i <= IDE_MAX_PIO_MODE; ++i) { - pio_config_clk[i].t_setup = - PCMCIA_MK_CLKS(pio_config_ns[i].t_setup, gd->bus_clk); - pio_config_clk[i].t_length = - PCMCIA_MK_CLKS(pio_config_ns[i].t_length, - gd->bus_clk); - pio_config_clk[i].t_hold = - PCMCIA_MK_CLKS(pio_config_ns[i].t_hold, gd->bus_clk); - debug("PIO Mode %d: setup=%2d ns/%d clk" " len=%3d ns/%d clk" - " hold=%2d ns/%d clk\n", i, pio_config_ns[i].t_setup, - pio_config_clk[i].t_setup, pio_config_ns[i].t_length, - pio_config_clk[i].t_length, pio_config_ns[i].t_hold, - pio_config_clk[i].t_hold); - } -#endif /* CONFIG_IDE_8xx_DIRECT */ - /* * Reset the IDE just to be sure. * Light LED's to show @@ -609,14 +341,14 @@ void ide_init(void) /* ATAPI Drives seems to need a proper IDE Reset */ ide_reset(); -#ifdef CONFIG_IDE_8xx_DIRECT - /* PCMCIA / IDE initialization for common mem space */ - pcmp->pcmc_pgcrb = 0; +#ifdef CONFIG_IDE_INIT_POSTRESET + WATCHDOG_RESET(); - /* start in PIO mode 0 - most relaxed timings */ - pio_mode = 0; - set_pcmcia_timing(pio_mode); -#endif /* CONFIG_IDE_8xx_DIRECT */ + if (ide_init_postreset()) { + puts("ide_preinit_postreset failed\n"); + return; + } +#endif /* CONFIG_IDE_INIT_POSTRESET */ /* * Wait for IDE to get ready. @@ -649,11 +381,7 @@ void ide_init(void) c = ide_inb(dev, ATA_STATUS); i++; -#if defined(CONFIG_SC3) - if (i > (ata_reset_time * 100)) { -#else if (i > (ATA_RESET_TIME * 100)) { -#endif puts("** Timeout **\n"); /* LED's off */ ide_led((LED_IDE1 | LED_IDE2), 0); @@ -685,14 +413,14 @@ void ide_init(void) curr_device = -1; for (i = 0; i < CONFIG_SYS_IDE_MAXDEVICE; ++i) { -#ifdef CONFIG_IDE_LED int led = (IDE_BUS(i) == 0) ? LED_IDE1 : LED_IDE2; -#endif ide_dev_desc[i].type = DEV_TYPE_UNKNOWN; ide_dev_desc[i].if_type = IF_TYPE_IDE; ide_dev_desc[i].dev = i; ide_dev_desc[i].part_type = PART_TYPE_UNKNOWN; ide_dev_desc[i].blksz = 0; + ide_dev_desc[i].log2blksz = + LOG2_INVALID(typeof(ide_dev_desc[i].log2blksz)); ide_dev_desc[i].lba = 0; ide_dev_desc[i].block_read = ide_read; ide_dev_desc[i].block_write = ide_write; @@ -722,121 +450,17 @@ block_dev_desc_t *ide_get_dev(int dev) } #endif - -#ifdef CONFIG_IDE_8xx_DIRECT - -static void set_pcmcia_timing(int pmode) -{ - volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; - volatile pcmconf8xx_t *pcmp = &(immr->im_pcmcia); - ulong timings; - - debug("Set timing for PIO Mode %d\n", pmode); - - timings = PCMCIA_SHT(pio_config_clk[pmode].t_hold) - | PCMCIA_SST(pio_config_clk[pmode].t_setup) - | PCMCIA_SL(pio_config_clk[pmode].t_length); - - /* - * IDE 0 - */ - pcmp->pcmc_pbr0 = CONFIG_SYS_PCMCIA_PBR0; - pcmp->pcmc_por0 = CONFIG_SYS_PCMCIA_POR0 -#if (CONFIG_SYS_PCMCIA_POR0 != 0) - | timings -#endif - ; - debug("PBR0: %08x POR0: %08x\n", pcmp->pcmc_pbr0, pcmp->pcmc_por0); - - pcmp->pcmc_pbr1 = CONFIG_SYS_PCMCIA_PBR1; - pcmp->pcmc_por1 = CONFIG_SYS_PCMCIA_POR1 -#if (CONFIG_SYS_PCMCIA_POR1 != 0) - | timings -#endif - ; - debug("PBR1: %08x POR1: %08x\n", pcmp->pcmc_pbr1, pcmp->pcmc_por1); - - pcmp->pcmc_pbr2 = CONFIG_SYS_PCMCIA_PBR2; - pcmp->pcmc_por2 = CONFIG_SYS_PCMCIA_POR2 -#if (CONFIG_SYS_PCMCIA_POR2 != 0) - | timings -#endif - ; - debug("PBR2: %08x POR2: %08x\n", pcmp->pcmc_pbr2, pcmp->pcmc_por2); - - pcmp->pcmc_pbr3 = CONFIG_SYS_PCMCIA_PBR3; - pcmp->pcmc_por3 = CONFIG_SYS_PCMCIA_POR3 -#if (CONFIG_SYS_PCMCIA_POR3 != 0) - | timings -#endif - ; - debug("PBR3: %08x POR3: %08x\n", pcmp->pcmc_pbr3, pcmp->pcmc_por3); - - /* - * IDE 1 - */ - pcmp->pcmc_pbr4 = CONFIG_SYS_PCMCIA_PBR4; - pcmp->pcmc_por4 = CONFIG_SYS_PCMCIA_POR4 -#if (CONFIG_SYS_PCMCIA_POR4 != 0) - | timings -#endif - ; - debug("PBR4: %08x POR4: %08x\n", pcmp->pcmc_pbr4, pcmp->pcmc_por4); - - pcmp->pcmc_pbr5 = CONFIG_SYS_PCMCIA_PBR5; - pcmp->pcmc_por5 = CONFIG_SYS_PCMCIA_POR5 -#if (CONFIG_SYS_PCMCIA_POR5 != 0) - | timings -#endif - ; - debug("PBR5: %08x POR5: %08x\n", pcmp->pcmc_pbr5, pcmp->pcmc_por5); - - pcmp->pcmc_pbr6 = CONFIG_SYS_PCMCIA_PBR6; - pcmp->pcmc_por6 = CONFIG_SYS_PCMCIA_POR6 -#if (CONFIG_SYS_PCMCIA_POR6 != 0) - | timings -#endif - ; - debug("PBR6: %08x POR6: %08x\n", pcmp->pcmc_pbr6, pcmp->pcmc_por6); - - pcmp->pcmc_pbr7 = CONFIG_SYS_PCMCIA_PBR7; - pcmp->pcmc_por7 = CONFIG_SYS_PCMCIA_POR7 -#if (CONFIG_SYS_PCMCIA_POR7 != 0) - | timings -#endif - ; - debug("PBR7: %08x POR7: %08x\n", pcmp->pcmc_pbr7, pcmp->pcmc_por7); - -} - -#endif /* CONFIG_IDE_8xx_DIRECT */ - /* ------------------------------------------------------------------------- */ /* We only need to swap data if we are running on a big endian cpu. */ -/* But Au1x00 cpu:s already swaps data in big endian mode! */ -#if defined(__LITTLE_ENDIAN) || \ - (defined(CONFIG_SOC_AU1X00) && !defined(CONFIG_GTH2)) -#define input_swap_data(x,y,z) input_data(x,y,z) -#else -static void input_swap_data(int dev, ulong *sect_buf, int words) +#if defined(__LITTLE_ENDIAN) +__weak void ide_input_swap_data(int dev, ulong *sect_buf, int words) { -#if defined(CONFIG_CPC45) - uchar i; - volatile uchar *pbuf_even = - (uchar *) (ATA_CURR_BASE(dev) + ATA_DATA_EVEN); - volatile uchar *pbuf_odd = - (uchar *) (ATA_CURR_BASE(dev) + ATA_DATA_ODD); - ushort *dbuf = (ushort *) sect_buf; - - while (words--) { - for (i = 0; i < 2; i++) { - *(((uchar *) (dbuf)) + 1) = *pbuf_even; - *(uchar *) dbuf = *pbuf_odd; - dbuf += 1; - } - } + ide_input_data(dev, sect_buf, words); +} #else +__weak void ide_input_swap_data(int dev, ulong *sect_buf, int words) +{ volatile ushort *pbuf = (ushort *) (ATA_CURR_BASE(dev) + ATA_DATA_REG); ushort *dbuf = (ushort *) sect_buf; @@ -848,64 +472,32 @@ static void input_swap_data(int dev, ulong *sect_buf, int words) #ifdef __MIPS__ *dbuf++ = swab16p((u16 *) pbuf); *dbuf++ = swab16p((u16 *) pbuf); -#elif defined(CONFIG_PCS440EP) - *dbuf++ = *pbuf; - *dbuf++ = *pbuf; #else *dbuf++ = ld_le16(pbuf); *dbuf++ = ld_le16(pbuf); #endif /* !MIPS */ } -#endif } -#endif /* __LITTLE_ENDIAN || CONFIG_AU1X00 */ +#endif /* __LITTLE_ENDIAN */ #if defined(CONFIG_IDE_SWAP_IO) -static void output_data(int dev, const ulong *sect_buf, int words) +__weak void ide_output_data(int dev, const ulong *sect_buf, int words) { -#if defined(CONFIG_CPC45) - uchar *dbuf; - volatile uchar *pbuf_even; - volatile uchar *pbuf_odd; - - pbuf_even = (uchar *) (ATA_CURR_BASE(dev) + ATA_DATA_EVEN); - pbuf_odd = (uchar *) (ATA_CURR_BASE(dev) + ATA_DATA_ODD); - dbuf = (uchar *) sect_buf; - while (words--) { - EIEIO; - *pbuf_even = *dbuf++; - EIEIO; - *pbuf_odd = *dbuf++; - EIEIO; - *pbuf_even = *dbuf++; - EIEIO; - *pbuf_odd = *dbuf++; - } -#else ushort *dbuf; volatile ushort *pbuf; pbuf = (ushort *) (ATA_CURR_BASE(dev) + ATA_DATA_REG); dbuf = (ushort *) sect_buf; while (words--) { -#if defined(CONFIG_PCS440EP) - /* not tested, because CF was write protected */ - EIEIO; - *pbuf = ld_le16(dbuf++); - EIEIO; - *pbuf = ld_le16(dbuf++); -#else EIEIO; *pbuf = *dbuf++; EIEIO; *pbuf = *dbuf++; -#endif } -#endif } #else /* ! CONFIG_IDE_SWAP_IO */ -static void output_data(int dev, const ulong *sect_buf, int words) +__weak void ide_output_data(int dev, const ulong *sect_buf, int words) { #if defined(CONFIG_IDE_AHB) ide_write_data(dev, sect_buf, words); @@ -916,31 +508,8 @@ static void output_data(int dev, const ulong *sect_buf, int words) #endif /* CONFIG_IDE_SWAP_IO */ #if defined(CONFIG_IDE_SWAP_IO) -static void input_data(int dev, ulong *sect_buf, int words) +__weak void ide_input_data(int dev, ulong *sect_buf, int words) { -#if defined(CONFIG_CPC45) - uchar *dbuf; - volatile uchar *pbuf_even; - volatile uchar *pbuf_odd; - - pbuf_even = (uchar *) (ATA_CURR_BASE(dev) + ATA_DATA_EVEN); - pbuf_odd = (uchar *) (ATA_CURR_BASE(dev) + ATA_DATA_ODD); - dbuf = (uchar *) sect_buf; - while (words--) { - *dbuf++ = *pbuf_even; - EIEIO; - SYNC; - *dbuf++ = *pbuf_odd; - EIEIO; - SYNC; - *dbuf++ = *pbuf_even; - EIEIO; - SYNC; - *dbuf++ = *pbuf_odd; - EIEIO; - SYNC; - } -#else ushort *dbuf; volatile ushort *pbuf; @@ -950,22 +519,14 @@ static void input_data(int dev, ulong *sect_buf, int words) debug("in input data base for read is %lx\n", (unsigned long) pbuf); while (words--) { -#if defined(CONFIG_PCS440EP) - EIEIO; - *dbuf++ = ld_le16(pbuf); - EIEIO; - *dbuf++ = ld_le16(pbuf); -#else EIEIO; *dbuf++ = *pbuf; EIEIO; *dbuf++ = *pbuf; -#endif } -#endif } #else /* ! CONFIG_IDE_SWAP_IO */ -static void input_data(int dev, ulong *sect_buf, int words) +__weak void ide_input_data(int dev, ulong *sect_buf, int words) { #if defined(CONFIG_IDE_AHB) ide_read_data(dev, sect_buf, words); @@ -985,15 +546,6 @@ static void ide_ident(block_dev_desc_t *dev_desc) #ifdef CONFIG_ATAPI int retries = 0; - int do_retry = 0; -#endif - -#ifdef CONFIG_TUNE_PIO - int pio_mode; -#endif - -#if 0 - int mode, cycle_time; #endif int device; @@ -1007,7 +559,6 @@ static void ide_ident(block_dev_desc_t *dev_desc) dev_desc->if_type = IF_TYPE_IDE; #ifdef CONFIG_ATAPI - do_retry = 0; retries = 0; /* Warning: This will be tricky to read */ @@ -1077,7 +628,7 @@ static void ide_ident(block_dev_desc_t *dev_desc) return; #endif - input_swap_data(device, (ulong *)&iop, ATA_SECTORWORDS); + ide_input_swap_data(device, (ulong *)&iop, ATA_SECTORWORDS); ident_cpy((unsigned char *) dev_desc->revision, iop.fw_rev, sizeof(dev_desc->revision)); @@ -1104,72 +655,6 @@ static void ide_ident(block_dev_desc_t *dev_desc) else dev_desc->removable = 0; -#ifdef CONFIG_TUNE_PIO - /* Mode 0 - 2 only, are directly determined by word 51. */ - pio_mode = iop.tPIO; - if (pio_mode > 2) { - printf("WARNING: Invalid PIO (word 51 = %d).\n", pio_mode); - /* Force it to dead slow, and hope for the best... */ - pio_mode = 0; - } - - /* Any CompactFlash Storage Card that supports PIO mode 3 or above - * shall set bit 1 of word 53 to one and support the fields contained - * in words 64 through 70. - */ - if (iop.field_valid & 0x02) { - /* - * Mode 3 and above are possible. Check in order from slow - * to fast, so we wind up with the highest mode allowed. - */ - if (iop.eide_pio_modes & 0x01) - pio_mode = 3; - if (iop.eide_pio_modes & 0x02) - pio_mode = 4; - if (ata_id_is_cfa((u16 *)&iop)) { - if ((iop.cf_advanced_caps & 0x07) == 0x01) - pio_mode = 5; - if ((iop.cf_advanced_caps & 0x07) == 0x02) - pio_mode = 6; - } - } - - /* System-specific, depends on bus speeds, etc. */ - ide_set_piomode(pio_mode); -#endif /* CONFIG_TUNE_PIO */ - -#if 0 - /* - * Drive PIO mode autoselection - */ - mode = iop.tPIO; - - printf("tPIO = 0x%02x = %d\n", mode, mode); - if (mode > 2) { /* 2 is maximum allowed tPIO value */ - mode = 2; - debug("Override tPIO -> 2\n"); - } - if (iop.field_valid & 2) { /* drive implements ATA2? */ - debug("Drive implements ATA2\n"); - if (iop.capability & 8) { /* drive supports use_iordy? */ - cycle_time = iop.eide_pio_iordy; - } else { - cycle_time = iop.eide_pio; - } - debug("cycle time = %d\n", cycle_time); - mode = 4; - if (cycle_time > 120) - mode = 3; /* 120 ns for PIO mode 4 */ - if (cycle_time > 180) - mode = 2; /* 180 ns for PIO mode 3 */ - if (cycle_time > 240) - mode = 1; /* 240 ns for PIO mode 4 */ - if (cycle_time > 383) - mode = 0; /* 383 ns for PIO mode 4 */ - } - printf("PIO mode to use: PIO %d\n", mode); -#endif /* 0 */ - #ifdef CONFIG_ATAPI if (dev_desc->if_type == IF_TYPE_ATAPI) { atapi_inquiry(dev_desc); @@ -1204,6 +689,7 @@ static void ide_ident(block_dev_desc_t *dev_desc) /* assuming HD */ dev_desc->type = DEV_TYPE_HARDDISK; dev_desc->blksz = ATA_BLOCKSIZE; + dev_desc->log2blksz = LOG2(dev_desc->blksz); dev_desc->lun = 0; /* just to fill something in... */ #if 0 /* only used to test the powersaving mode, @@ -1225,7 +711,7 @@ static void ide_ident(block_dev_desc_t *dev_desc) /* ------------------------------------------------------------------------- */ -ulong ide_read(int device, lbaint_t blknr, ulong blkcnt, void *buffer) +ulong ide_read(int device, lbaint_t blknr, lbaint_t blkcnt, void *buffer) { ulong n = 0; unsigned char c; @@ -1239,7 +725,7 @@ ulong ide_read(int device, lbaint_t blknr, ulong blkcnt, void *buffer) lba48 = 1; } #endif - debug("ide_read dev %d start %lX, blocks %lX buffer at %lX\n", + debug("ide_read dev %d start " LBAF ", blocks " LBAF " buffer at %lX\n", device, blknr, blkcnt, (ulong) buffer); ide_led(DEVICE_LED(device), 1); /* LED on */ @@ -1329,17 +815,12 @@ ulong ide_read(int device, lbaint_t blknr, ulong blkcnt, void *buffer) if ((c & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR)) != ATA_STAT_DRQ) { -#if defined(CONFIG_SYS_64BIT_LBA) - printf("Error (no IRQ) dev %d blk %lld: status 0x%02x\n", - device, blknr, c); -#else - printf("Error (no IRQ) dev %d blk %ld: status 0x%02x\n", - device, (ulong) blknr, c); -#endif + printf("Error (no IRQ) dev %d blk " LBAF ": status " + "%#02x\n", device, blknr, c); break; } - input_data(device, buffer, ATA_SECTORWORDS); + ide_input_data(device, buffer, ATA_SECTORWORDS); (void) ide_inb(device, ATA_STATUS); /* clear IRQ */ ++n; @@ -1354,7 +835,7 @@ IDE_READ_E: /* ------------------------------------------------------------------------- */ -ulong ide_write(int device, lbaint_t blknr, ulong blkcnt, const void *buffer) +ulong ide_write(int device, lbaint_t blknr, lbaint_t blkcnt, const void *buffer) { ulong n = 0; unsigned char c; @@ -1422,17 +903,12 @@ ulong ide_write(int device, lbaint_t blknr, ulong blkcnt, const void *buffer) if ((c & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR)) != ATA_STAT_DRQ) { -#if defined(CONFIG_SYS_64BIT_LBA) - printf("Error (no IRQ) dev %d blk %lld: status 0x%02x\n", - device, blknr, c); -#else - printf("Error (no IRQ) dev %d blk %ld: status 0x%02x\n", - device, (ulong) blknr, c); -#endif + printf("Error (no IRQ) dev %d blk " LBAF ": status " + "%#02x\n", device, blknr, c); goto WR_OUT; } - output_data(device, buffer, ATA_SECTORWORDS); + ide_output_data(device, buffer, ATA_SECTORWORDS); c = ide_inb(device, ATA_STATUS); /* clear IRQ */ ++n; ++blknr; @@ -1502,9 +978,6 @@ extern void ide_set_reset(int idereset); static void ide_reset(void) { -#if defined(CONFIG_SYS_PB_12V_ENABLE) || defined(CONFIG_SYS_PB_IDE_MOTOR) - volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; -#endif int i; curr_device = -1; @@ -1520,51 +993,6 @@ static void ide_reset(void) WATCHDOG_RESET(); -#ifdef CONFIG_SYS_PB_12V_ENABLE - /* 12V Enable output OFF */ - immr->im_cpm.cp_pbdat &= ~(CONFIG_SYS_PB_12V_ENABLE); - - immr->im_cpm.cp_pbpar &= ~(CONFIG_SYS_PB_12V_ENABLE); - immr->im_cpm.cp_pbodr &= ~(CONFIG_SYS_PB_12V_ENABLE); - immr->im_cpm.cp_pbdir |= CONFIG_SYS_PB_12V_ENABLE; - - /* wait 500 ms for the voltage to stabilize */ - for (i = 0; i < 500; ++i) - udelay(1000); - - /* 12V Enable output ON */ - immr->im_cpm.cp_pbdat |= CONFIG_SYS_PB_12V_ENABLE; -#endif /* CONFIG_SYS_PB_12V_ENABLE */ - -#ifdef CONFIG_SYS_PB_IDE_MOTOR - /* configure IDE Motor voltage monitor pin as input */ - immr->im_cpm.cp_pbpar &= ~(CONFIG_SYS_PB_IDE_MOTOR); - immr->im_cpm.cp_pbodr &= ~(CONFIG_SYS_PB_IDE_MOTOR); - immr->im_cpm.cp_pbdir &= ~(CONFIG_SYS_PB_IDE_MOTOR); - - /* wait up to 1 s for the motor voltage to stabilize */ - for (i = 0; i < 1000; ++i) { - if ((immr->im_cpm.cp_pbdat & CONFIG_SYS_PB_IDE_MOTOR) != 0) { - break; - } - udelay(1000); - } - - if (i == 1000) { /* Timeout */ - printf("\nWarning: 5V for IDE Motor missing\n"); -#ifdef CONFIG_STATUS_LED -#ifdef STATUS_LED_YELLOW - status_led_set(STATUS_LED_YELLOW, STATUS_LED_ON); -#endif -#ifdef STATUS_LED_GREEN - status_led_set(STATUS_LED_GREEN, STATUS_LED_OFF); -#endif -#endif /* CONFIG_STATUS_LED */ - } -#endif /* CONFIG_SYS_PB_IDE_MOTOR */ - - WATCHDOG_RESET(); - /* de-assert RESET signal */ ide_set_reset(0); @@ -1577,27 +1005,6 @@ static void ide_reset(void) /* ------------------------------------------------------------------------- */ -#if defined(CONFIG_IDE_LED) && \ - !defined(CONFIG_CPC45) && \ - !defined(CONFIG_KUP4K) && \ - !defined(CONFIG_KUP4X) - -static uchar led_buffer; /* Buffer for current LED status */ - -static void ide_led(uchar led, uchar status) -{ - uchar *led_port = LED_PORT; - - if (status) /* switch LED on */ - led_buffer |= led; - else /* switch LED off */ - led_buffer &= ~led; - - *led_port = led_buffer; -} - -#endif /* CONFIG_IDE_LED */ - #if defined(CONFIG_OF_IDE_FIXUP) int ide_device_present(int dev) { @@ -1616,22 +1023,8 @@ int ide_device_present(int dev) #if defined(CONFIG_IDE_SWAP_IO) /* since ATAPI may use commands with not 4 bytes alligned length * we have our own transfer functions, 2 bytes alligned */ -static void output_data_shorts(int dev, ushort *sect_buf, int shorts) +__weak void ide_output_data_shorts(int dev, ushort *sect_buf, int shorts) { -#if defined(CONFIG_CPC45) - uchar *dbuf; - volatile uchar *pbuf_even; - volatile uchar *pbuf_odd; - - pbuf_even = (uchar *) (ATA_CURR_BASE(dev) + ATA_DATA_EVEN); - pbuf_odd = (uchar *) (ATA_CURR_BASE(dev) + ATA_DATA_ODD); - while (shorts--) { - EIEIO; - *pbuf_even = *dbuf++; - EIEIO; - *pbuf_odd = *dbuf++; - } -#else ushort *dbuf; volatile ushort *pbuf; @@ -1645,25 +1038,10 @@ static void output_data_shorts(int dev, ushort *sect_buf, int shorts) EIEIO; *pbuf = *dbuf++; } -#endif } -static void input_data_shorts(int dev, ushort *sect_buf, int shorts) +__weak void ide_input_data_shorts(int dev, ushort *sect_buf, int shorts) { -#if defined(CONFIG_CPC45) - uchar *dbuf; - volatile uchar *pbuf_even; - volatile uchar *pbuf_odd; - - pbuf_even = (uchar *) (ATA_CURR_BASE(dev) + ATA_DATA_EVEN); - pbuf_odd = (uchar *) (ATA_CURR_BASE(dev) + ATA_DATA_ODD); - while (shorts--) { - EIEIO; - *dbuf++ = *pbuf_even; - EIEIO; - *dbuf++ = *pbuf_odd; - } -#else ushort *dbuf; volatile ushort *pbuf; @@ -1677,16 +1055,15 @@ static void input_data_shorts(int dev, ushort *sect_buf, int shorts) EIEIO; *dbuf++ = *pbuf; } -#endif } #else /* ! CONFIG_IDE_SWAP_IO */ -static void output_data_shorts(int dev, ushort *sect_buf, int shorts) +__weak void ide_output_data_shorts(int dev, ushort *sect_buf, int shorts) { outsw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, shorts); } -static void input_data_shorts(int dev, ushort *sect_buf, int shorts) +__weak void ide_input_data_shorts(int dev, ushort *sect_buf, int shorts) { insw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, shorts); } @@ -1765,7 +1142,7 @@ unsigned char atapi_issue(int device, unsigned char *ccb, int ccblen, } /* write command block */ - output_data_shorts(device, (unsigned short *) ccb, ccblen / 2); + ide_output_data_shorts(device, (unsigned short *) ccb, ccblen / 2); /* ATAPI Command written wait for completition */ udelay(5000); /* device must set bsy */ @@ -1816,12 +1193,12 @@ unsigned char atapi_issue(int device, unsigned char *ccb, int ccblen, /* ok now decide if it is an in or output */ if ((ide_inb(device, ATA_SECT_CNT) & 0x02) == 0) { debug("Write to device\n"); - output_data_shorts(device, (unsigned short *) buffer, - n); + ide_output_data_shorts(device, + (unsigned short *) buffer, n); } else { debug("Read from device @ %p shorts %d\n", buffer, n); - input_data_shorts(device, (unsigned short *) buffer, - n); + ide_input_data_shorts(device, + (unsigned short *) buffer, n); } } udelay(5000); /* seems that some CD ROMs need this... */ @@ -1948,6 +1325,7 @@ static void atapi_inquiry(block_dev_desc_t *dev_desc) dev_desc->lun = 0; dev_desc->lba = 0; dev_desc->blksz = 0; + dev_desc->log2blksz = LOG2_INVALID(typeof(dev_desc->log2blksz)); dev_desc->type = iobuf[0] & 0x1f; if ((iobuf[1] & 0x80) == 0x80) @@ -1992,6 +1370,7 @@ static void atapi_inquiry(block_dev_desc_t *dev_desc) dev_desc->blksz = ((unsigned long) iobuf[4] << 24) + ((unsigned long) iobuf[5] << 16) + ((unsigned long) iobuf[6] << 8) + ((unsigned long) iobuf[7]); + dev_desc->log2blksz = LOG2(dev_desc->blksz); #ifdef CONFIG_LBA48 /* ATAPI devices cannot use 48bit addressing (ATA/ATAPI v7) */ dev_desc->lba48 = 0; @@ -2009,13 +1388,13 @@ static void atapi_inquiry(block_dev_desc_t *dev_desc) #define ATAPI_READ_BLOCK_SIZE 2048 /* assuming CD part */ #define ATAPI_READ_MAX_BLOCK (ATAPI_READ_MAX_BYTES/ATAPI_READ_BLOCK_SIZE) -ulong atapi_read(int device, lbaint_t blknr, ulong blkcnt, void *buffer) +ulong atapi_read(int device, lbaint_t blknr, lbaint_t blkcnt, void *buffer) { ulong n = 0; unsigned char ccb[12]; /* Command descriptor block */ ulong cnt; - debug("atapi_read dev %d start %lX, blocks %lX buffer at %lX\n", + debug("atapi_read dev %d start " LBAF " blocks " LBAF " buffer at %lX\n", device, blknr, blkcnt, (ulong) buffer); do {