colibri_imx6: fix video stdout in default environment
[oweals/u-boot.git] / drivers / block / ide.c
index cea0397eb23e4ebbfacb86f4866733fae2912f99..a766b5cf03660807857943075ce273928063c664 100644 (file)
@@ -1,16 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * (C) Copyright 2000-2011
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
 #include <ata.h>
+#include <blk.h>
 #include <dm.h>
 #include <ide.h>
+#include <log.h>
+#include <part.h>
 #include <watchdog.h>
 #include <asm/io.h>
+#include <linux/delay.h>
 
 #ifdef __PPC__
 # define EIEIO         __asm__ volatile ("eieio")
@@ -44,12 +47,6 @@ struct blk_desc ide_dev_desc[CONFIG_SYS_IDE_MAXDEVICE];
 #define CONFIG_SYS_ATA_PORT_ADDR(port) (port)
 #endif
 
-#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
-
 #ifdef CONFIG_IDE_RESET
 extern void ide_set_reset(int idereset);
 
@@ -217,8 +214,6 @@ unsigned char atapi_issue(int device, unsigned char *ccb, int ccblen,
        unsigned char c, err, mask, res;
        int n;
 
-       ide_led(DEVICE_LED(device), 1); /* LED on       */
-
        /* Select device
         */
        mask = ATA_STAT_BUSY | ATA_STAT_DRQ;
@@ -240,7 +235,7 @@ unsigned char atapi_issue(int device, unsigned char *ccb, int ccblen,
                 (unsigned char) ((buflen >> 8) & 0xFF));
        ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
 
-       ide_outb(device, ATA_COMMAND, ATAPI_CMD_PACKET);
+       ide_outb(device, ATA_COMMAND, ATA_CMD_PACKET);
        udelay(50);
 
        mask = ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR;
@@ -326,7 +321,6 @@ unsigned char atapi_issue(int device, unsigned char *ccb, int ccblen,
                err = 0;
        }
 AI_OUT:
-       ide_led(DEVICE_LED(device), 0); /* LED off      */
        return err;
 }
 
@@ -560,7 +554,6 @@ static void ide_ident(struct blk_desc *dev_desc)
        device = dev_desc->devnum;
        printf("  Device %d: ", device);
 
-       ide_led(DEVICE_LED(device), 1); /* LED on       */
        /* Select device
         */
        ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
@@ -581,7 +574,7 @@ static void ide_ident(struct blk_desc *dev_desc)
                        /*
                         * Start Ident Command
                         */
-                       ide_outb(device, ATA_COMMAND, ATAPI_CMD_IDENT);
+                       ide_outb(device, ATA_COMMAND, ATA_CMD_ID_ATAPI);
                        /*
                         * Wait for completion - ATAPI devices need more time
                         * to become ready
@@ -593,14 +586,13 @@ static void ide_ident(struct blk_desc *dev_desc)
                        /*
                         * Start Ident Command
                         */
-                       ide_outb(device, ATA_COMMAND, ATA_CMD_IDENT);
+                       ide_outb(device, ATA_COMMAND, ATA_CMD_ID_ATA);
 
                        /*
                         * Wait for completion
                         */
                        c = ide_wait(device, IDE_TIME_OUT);
                }
-               ide_led(DEVICE_LED(device), 0); /* LED off      */
 
                if (((c & ATA_STAT_DRQ) == 0) ||
                    ((c & (ATA_STAT_FAULT | ATA_STAT_ERR)) != 0)) {
@@ -716,22 +708,6 @@ static void ide_ident(struct blk_desc *dev_desc)
 #endif
 }
 
-__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 */
-
-       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
-}
-
 __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",
@@ -783,12 +759,6 @@ void ide_init(void)
 
        WATCHDOG_RESET();
 
-       /*
-        * Reset the IDE just to be sure.
-        * Light LED's to show
-        */
-       ide_led((LED_IDE1 | LED_IDE2), 1);      /* LED's on     */
-
        /* ATAPI Drives seems to need a proper IDE Reset */
        ide_reset();
 
@@ -818,8 +788,6 @@ void ide_init(void)
                        i++;
                        if (i > (ATA_RESET_TIME * 100)) {
                                puts("** Timeout **\n");
-                               /* LED's off */
-                               ide_led((LED_IDE1 | LED_IDE2), 0);
                                return;
                        }
                        if ((i >= 100) && ((i % 100) == 0))
@@ -844,10 +812,7 @@ void ide_init(void)
 
        putc('\n');
 
-       ide_led((LED_IDE1 | LED_IDE2), 0);      /* LED's off    */
-
        for (i = 0; i < CONFIG_SYS_IDE_MAXDEVICE; ++i) {
-               int led = (IDE_BUS(i) == 0) ? LED_IDE1 : LED_IDE2;
                ide_dev_desc[i].type = DEV_TYPE_UNKNOWN;
                ide_dev_desc[i].if_type = IF_TYPE_IDE;
                ide_dev_desc[i].devnum = i;
@@ -862,17 +827,23 @@ void ide_init(void)
 #endif
                if (!ide_bus_ok[IDE_BUS(i)])
                        continue;
-               ide_led(led, 1);        /* LED on       */
                ide_ident(&ide_dev_desc[i]);
-               ide_led(led, 0);        /* LED off      */
                dev_print(&ide_dev_desc[i]);
 
+#ifndef CONFIG_BLK
                if ((ide_dev_desc[i].lba > 0) && (ide_dev_desc[i].blksz > 0)) {
                        /* initialize partition type */
                        part_init(&ide_dev_desc[i]);
                }
+#endif
        }
        WATCHDOG_RESET();
+
+#ifdef CONFIG_BLK
+       struct udevice *dev;
+
+       uclass_first_device(UCLASS_IDE, &dev);
+#endif
 }
 
 /* We only need to swap data if we are running on a big endian cpu. */
@@ -987,8 +958,6 @@ ulong ide_read(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt,
        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       */
-
        /* Select device
         */
        ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
@@ -1001,7 +970,7 @@ ulong ide_read(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt,
 
        /* first check if the drive is in Powersaving mode, if yes,
         * increase the timeout value */
-       ide_outb(device, ATA_COMMAND, ATA_CMD_CHK_PWR);
+       ide_outb(device, ATA_COMMAND, ATA_CMD_CHK_POWER);
        udelay(50);
 
        c = ide_wait(device, IDE_TIME_OUT);     /* can't take over 500 ms */
@@ -1086,7 +1055,6 @@ ulong ide_read(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt,
                buffer += ATA_BLOCKSIZE;
        }
 IDE_READ_E:
-       ide_led(DEVICE_LED(device), 0); /* LED off      */
        return n;
 }
 
@@ -1114,8 +1082,6 @@ ulong ide_write(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt,
        }
 #endif
 
-       ide_led(DEVICE_LED(device), 1); /* LED on       */
-
        /* Select device
         */
        ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
@@ -1179,7 +1145,6 @@ ulong ide_write(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt,
                buffer += ATA_BLOCKSIZE;
        }
 WR_OUT:
-       ide_led(DEVICE_LED(device), 0); /* LED off      */
        return n;
 }
 
@@ -1193,6 +1158,24 @@ int ide_device_present(int dev)
 #endif
 
 #ifdef CONFIG_BLK
+static int ide_blk_probe(struct udevice *udev)
+{
+       struct blk_desc *desc = dev_get_uclass_platdata(udev);
+
+       /* fill in device vendor/product/rev strings */
+       strncpy(desc->vendor, ide_dev_desc[desc->devnum].vendor,
+               BLK_VEN_SIZE);
+       desc->vendor[BLK_VEN_SIZE] = '\0';
+       strncpy(desc->product, ide_dev_desc[desc->devnum].product,
+               BLK_PRD_SIZE);
+       desc->product[BLK_PRD_SIZE] = '\0';
+       strncpy(desc->revision, ide_dev_desc[desc->devnum].revision,
+               BLK_REV_SIZE);
+       desc->revision[BLK_REV_SIZE] = '\0';
+
+       return 0;
+}
+
 static const struct blk_ops ide_blk_ops = {
        .read   = ide_read,
        .write  = ide_write,
@@ -1202,6 +1185,58 @@ U_BOOT_DRIVER(ide_blk) = {
        .name           = "ide_blk",
        .id             = UCLASS_BLK,
        .ops            = &ide_blk_ops,
+       .probe          = ide_blk_probe,
+};
+
+static int ide_probe(struct udevice *udev)
+{
+       struct udevice *blk_dev;
+       char name[20];
+       int blksz;
+       lbaint_t size;
+       int i;
+       int ret;
+
+       for (i = 0; i < CONFIG_SYS_IDE_MAXDEVICE; i++) {
+               if (ide_dev_desc[i].type != DEV_TYPE_UNKNOWN) {
+                       sprintf(name, "blk#%d", i);
+
+                       blksz = ide_dev_desc[i].blksz;
+                       size = blksz * ide_dev_desc[i].lba;
+
+                       /*
+                        * With CDROM, if there is no CD inserted, blksz will
+                        * be zero, don't bother to create IDE block device.
+                        */
+                       if (!blksz)
+                               continue;
+                       ret = blk_create_devicef(udev, "ide_blk", name,
+                                                IF_TYPE_IDE, i,
+                                                blksz, size, &blk_dev);
+                       if (ret)
+                               return ret;
+               }
+       }
+
+       return 0;
+}
+
+U_BOOT_DRIVER(ide) = {
+       .name           = "ide",
+       .id             = UCLASS_IDE,
+       .probe          = ide_probe,
+};
+
+struct pci_device_id ide_supported[] = {
+       { PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_IDE << 8, 0xffff00) },
+       { }
+};
+
+U_BOOT_PCI_DEVICE(ide, ide_supported);
+
+UCLASS_DRIVER(ide) = {
+       .name           = "ide",
+       .id             = UCLASS_IDE,
 };
 #else
 U_BOOT_LEGACY_BLK(ide) = {