1f2105c61SSimon Glass /* 2f2105c61SSimon Glass * Copyright (C) 2000-2005, DENX Software Engineering 3f2105c61SSimon Glass * Wolfgang Denk <wd@denx.de> 4f2105c61SSimon Glass * Copyright (C) Procsys. All rights reserved. 5f2105c61SSimon Glass * Mushtaq Khan <mushtaq_k@procsys.com> 6f2105c61SSimon Glass * <mushtaqk_921@yahoo.co.in> 7f2105c61SSimon Glass * Copyright (C) 2008 Freescale Semiconductor, Inc. 8f2105c61SSimon Glass * Dave Liu <daveliu@freescale.com> 9f2105c61SSimon Glass * 10f2105c61SSimon Glass * SPDX-License-Identifier: GPL-2.0+ 11f2105c61SSimon Glass */ 12f2105c61SSimon Glass 13f2105c61SSimon Glass #include <common.h> 14*b8341f1cSSimon Glass #include <ahci.h> 15f2105c61SSimon Glass #include <dm.h> 16f2105c61SSimon Glass #include <sata.h> 17f2105c61SSimon Glass 18*b8341f1cSSimon Glass #ifndef CONFIG_AHCI 19f2105c61SSimon Glass struct blk_desc sata_dev_desc[CONFIG_SYS_SATA_MAX_DEVICE]; 20*b8341f1cSSimon Glass #endif 21f2105c61SSimon Glass 22*b8341f1cSSimon Glass int sata_reset(struct udevice *dev) 23*b8341f1cSSimon Glass { 24*b8341f1cSSimon Glass struct ahci_ops *ops = ahci_get_ops(dev); 25*b8341f1cSSimon Glass 26*b8341f1cSSimon Glass if (!ops->reset) 27*b8341f1cSSimon Glass return -ENOSYS; 28*b8341f1cSSimon Glass 29*b8341f1cSSimon Glass return ops->reset(dev); 30*b8341f1cSSimon Glass } 31*b8341f1cSSimon Glass 32*b8341f1cSSimon Glass int sata_dm_port_status(struct udevice *dev, int port) 33*b8341f1cSSimon Glass { 34*b8341f1cSSimon Glass struct ahci_ops *ops = ahci_get_ops(dev); 35*b8341f1cSSimon Glass 36*b8341f1cSSimon Glass if (!ops->port_status) 37*b8341f1cSSimon Glass return -ENOSYS; 38*b8341f1cSSimon Glass 39*b8341f1cSSimon Glass return ops->port_status(dev, port); 40*b8341f1cSSimon Glass } 41*b8341f1cSSimon Glass 42*b8341f1cSSimon Glass int sata_scan(struct udevice *dev) 43*b8341f1cSSimon Glass { 44*b8341f1cSSimon Glass struct ahci_ops *ops = ahci_get_ops(dev); 45*b8341f1cSSimon Glass 46*b8341f1cSSimon Glass if (!ops->scan) 47*b8341f1cSSimon Glass return -ENOSYS; 48*b8341f1cSSimon Glass 49*b8341f1cSSimon Glass return ops->scan(dev); 50*b8341f1cSSimon Glass } 51*b8341f1cSSimon Glass 52*b8341f1cSSimon Glass #ifndef CONFIG_AHCI 53f2105c61SSimon Glass #ifdef CONFIG_PARTITIONS 54f2105c61SSimon Glass struct blk_desc *sata_get_dev(int dev) 55f2105c61SSimon Glass { 56f2105c61SSimon Glass return (dev < CONFIG_SYS_SATA_MAX_DEVICE) ? &sata_dev_desc[dev] : NULL; 57f2105c61SSimon Glass } 58f2105c61SSimon Glass #endif 59*b8341f1cSSimon Glass #endif 60f2105c61SSimon Glass 61f2105c61SSimon Glass #ifdef CONFIG_BLK 62f2105c61SSimon Glass static unsigned long sata_bread(struct udevice *dev, lbaint_t start, 63f2105c61SSimon Glass lbaint_t blkcnt, void *dst) 64f2105c61SSimon Glass { 65f2105c61SSimon Glass return -ENOSYS; 66f2105c61SSimon Glass } 67f2105c61SSimon Glass 68f2105c61SSimon Glass static unsigned long sata_bwrite(struct udevice *dev, lbaint_t start, 69f2105c61SSimon Glass lbaint_t blkcnt, const void *buffer) 70f2105c61SSimon Glass { 71f2105c61SSimon Glass return -ENOSYS; 72f2105c61SSimon Glass } 73f2105c61SSimon Glass #else 74f2105c61SSimon Glass static unsigned long sata_bread(struct blk_desc *block_dev, lbaint_t start, 75f2105c61SSimon Glass lbaint_t blkcnt, void *dst) 76f2105c61SSimon Glass { 77f2105c61SSimon Glass return sata_read(block_dev->devnum, start, blkcnt, dst); 78f2105c61SSimon Glass } 79f2105c61SSimon Glass 80f2105c61SSimon Glass static unsigned long sata_bwrite(struct blk_desc *block_dev, lbaint_t start, 81f2105c61SSimon Glass lbaint_t blkcnt, const void *buffer) 82f2105c61SSimon Glass { 83f2105c61SSimon Glass return sata_write(block_dev->devnum, start, blkcnt, buffer); 84f2105c61SSimon Glass } 85f2105c61SSimon Glass #endif 86f2105c61SSimon Glass 87*b8341f1cSSimon Glass #ifndef CONFIG_AHCI 88f2105c61SSimon Glass int __sata_initialize(void) 89f2105c61SSimon Glass { 90f2105c61SSimon Glass int rc, ret = -1; 91f2105c61SSimon Glass int i; 92f2105c61SSimon Glass 93f2105c61SSimon Glass for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; i++) { 94f2105c61SSimon Glass memset(&sata_dev_desc[i], 0, sizeof(struct blk_desc)); 95f2105c61SSimon Glass sata_dev_desc[i].if_type = IF_TYPE_SATA; 96f2105c61SSimon Glass sata_dev_desc[i].devnum = i; 97f2105c61SSimon Glass sata_dev_desc[i].part_type = PART_TYPE_UNKNOWN; 98f2105c61SSimon Glass sata_dev_desc[i].type = DEV_TYPE_HARDDISK; 99f2105c61SSimon Glass sata_dev_desc[i].lba = 0; 100f2105c61SSimon Glass sata_dev_desc[i].blksz = 512; 101f2105c61SSimon Glass sata_dev_desc[i].log2blksz = LOG2(sata_dev_desc[i].blksz); 102f2105c61SSimon Glass #ifndef CONFIG_BLK 103f2105c61SSimon Glass sata_dev_desc[i].block_read = sata_bread; 104f2105c61SSimon Glass sata_dev_desc[i].block_write = sata_bwrite; 105f2105c61SSimon Glass #endif 106f2105c61SSimon Glass rc = init_sata(i); 107f2105c61SSimon Glass if (!rc) { 108f2105c61SSimon Glass rc = scan_sata(i); 109f2105c61SSimon Glass if (!rc && sata_dev_desc[i].lba > 0 && 110f2105c61SSimon Glass sata_dev_desc[i].blksz > 0) { 111f2105c61SSimon Glass part_init(&sata_dev_desc[i]); 112f2105c61SSimon Glass ret = i; 113f2105c61SSimon Glass } 114f2105c61SSimon Glass } 115f2105c61SSimon Glass } 116f2105c61SSimon Glass 117f2105c61SSimon Glass return ret; 118f2105c61SSimon Glass } 119f2105c61SSimon Glass int sata_initialize(void) __attribute__((weak, alias("__sata_initialize"))); 120f2105c61SSimon Glass 121f2105c61SSimon Glass __weak int __sata_stop(void) 122f2105c61SSimon Glass { 123f2105c61SSimon Glass int i, err = 0; 124f2105c61SSimon Glass 125f2105c61SSimon Glass for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; i++) 126f2105c61SSimon Glass err |= reset_sata(i); 127f2105c61SSimon Glass 128f2105c61SSimon Glass if (err) 129f2105c61SSimon Glass printf("Could not reset some SATA devices\n"); 130f2105c61SSimon Glass 131f2105c61SSimon Glass return err; 132f2105c61SSimon Glass } 133f2105c61SSimon Glass int sata_stop(void) __attribute__((weak, alias("__sata_stop"))); 134*b8341f1cSSimon Glass #endif 135f2105c61SSimon Glass 136f2105c61SSimon Glass #ifdef CONFIG_BLK 137f2105c61SSimon Glass static const struct blk_ops sata_blk_ops = { 138f2105c61SSimon Glass .read = sata_bread, 139f2105c61SSimon Glass .write = sata_bwrite, 140f2105c61SSimon Glass }; 141f2105c61SSimon Glass 142f2105c61SSimon Glass U_BOOT_DRIVER(sata_blk) = { 143f2105c61SSimon Glass .name = "sata_blk", 144f2105c61SSimon Glass .id = UCLASS_BLK, 145f2105c61SSimon Glass .ops = &sata_blk_ops, 146f2105c61SSimon Glass }; 147f2105c61SSimon Glass #else 148f2105c61SSimon Glass U_BOOT_LEGACY_BLK(sata) = { 149f2105c61SSimon Glass .if_typename = "sata", 150f2105c61SSimon Glass .if_type = IF_TYPE_SATA, 151f2105c61SSimon Glass .max_devs = CONFIG_SYS_SATA_MAX_DEVICE, 152f2105c61SSimon Glass .desc = sata_dev_desc, 153f2105c61SSimon Glass }; 154f2105c61SSimon Glass #endif 155