diff options
author | Tom Rini <trini@konsulko.com> | 2017-08-18 18:24:36 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2017-08-18 18:24:36 -0400 |
commit | 1fdafb2e3dfecdc4129a8062ad25b1adb32b0efb (patch) | |
tree | 6c6a74d4cb4e8a19bfd47510ade9fdcc3d08cb01 | |
parent | a6dd10c70be9be863488d9d7afede057a4d99823 (diff) | |
parent | a191ccaf12fb4fadedcd3c76df6327e2bb0f182b (diff) |
Merge branch 'master' of git://git.denx.de/u-boot-mmc
67 files changed, 1511 insertions, 1036 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index da9324b43ca..0e8dc0179bf 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -728,7 +728,6 @@ config ARCH_ZYNQ select DM_GPIO select SPL_DM if SPL select DM_MMC - select DM_MMC_OPS select DM_SPI select DM_SERIAL select DM_SPI_FLASH @@ -1076,7 +1075,6 @@ config ARCH_ROCKCHIP select DM_GPIO select DM_I2C select DM_MMC - select DM_MMC_OPS select DM_SERIAL select DM_SPI select DM_SPI_FLASH diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index f94c2471b4e..d07715fc4f1 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -359,6 +359,7 @@ dtb-$(CONFIG_MX6) += imx6ull-14x14-evk.dtb \ imx6sll-evk.dtb \ imx6dl-icore.dtb \ imx6dl-icore-rqs.dtb \ + imx6q-cm-fx6.dtb \ imx6q-icore.dtb \ imx6q-icore-rqs.dtb \ imx6q-logicpd.dtb \ diff --git a/arch/arm/dts/imx6q-cm-fx6.dts b/arch/arm/dts/imx6q-cm-fx6.dts new file mode 100644 index 00000000000..4f1fced40ea --- /dev/null +++ b/arch/arm/dts/imx6q-cm-fx6.dts @@ -0,0 +1,115 @@ +/* + * Copyright 2013 CompuLab Ltd. + * + * Author: Valentin Raevsky <valentin@compulab.co.il> + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/dts-v1/; +#include "imx6q.dtsi" + +/ { + model = "CompuLab CM-FX6"; + compatible = "compulab,cm-fx6", "fsl,imx6q"; + + memory { + reg = <0x10000000 0x80000000>; + }; + + leds { + compatible = "gpio-leds"; + + heartbeat-led { + label = "Heartbeat"; + gpios = <&gpio2 31 0>; + linux,default-trigger = "heartbeat"; + }; + }; +}; + +&fec { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enet>; + phy-mode = "rgmii"; + status = "okay"; +}; + +&gpmi { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpmi_nand>; + status = "okay"; +}; + +&iomuxc { + imx6q-cm-fx6 { + pinctrl_enet: enetgrp { + fsl,pins = < + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0 + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0 + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0 + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0 + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0 + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0 + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0 + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0 + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0 + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0 + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0 + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0 + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0 + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0 + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0 + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8 + >; + }; + + pinctrl_gpmi_nand: gpminandgrp { + fsl,pins = < + MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1 + MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1 + MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1 + MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000 + MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1 + MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1 + MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1 + MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1 + MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1 + MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1 + MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1 + MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1 + MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1 + MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1 + MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1 + MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1 + MX6QDL_PAD_SD4_DAT0__NAND_DQS 0x00b1 + >; + }; + + pinctrl_uart4: uart4grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1 + MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1 + >; + }; + }; +}; + +&uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart4>; + status = "okay"; +}; + +&sata { + status = "okay"; +}; + +&usdhc3 { + status = "okay"; +}; diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c index 9e83b4221e0..1017eb84f95 100644 --- a/arch/arm/mach-imx/cpu.c +++ b/arch/arm/mach-imx/cpu.c @@ -279,7 +279,7 @@ void arch_preboot_os(void) imx_pcie_remove(); #endif #if defined(CONFIG_SATA) - sata_stop(); + sata_remove(0); #if defined(CONFIG_MX6) disable_sata_clock(); #endif diff --git a/arch/arm/mach-rmobile/include/mach/sh_sdhi.h b/arch/arm/mach-rmobile/include/mach/sh_sdhi.h index 1fb0648b126..00a135faa14 100644 --- a/arch/arm/mach-rmobile/include/mach/sh_sdhi.h +++ b/arch/arm/mach-rmobile/include/mach/sh_sdhi.h @@ -49,11 +49,6 @@ /* SDHI CMD VALUE */ #define CMD_MASK 0x0000ffff -#define SDHI_APP 0x0040 -#define SDHI_MMC_SEND_OP_COND 0x0701 -#define SDHI_SD_APP_SEND_SCR 0x0073 -#define SDHI_SD_SWITCH 0x1C06 -#define SDHI_MMC_SEND_EXT_CSD 0x1C08 /* SDHI_PORTSEL */ #define USE_1PORT (1 << 8) /* 1 port */ diff --git a/board/compulab/cm_fx6/cm_fx6.c b/board/compulab/cm_fx6/cm_fx6.c index a1da2780aa4..638e9f393b9 100644 --- a/board/compulab/cm_fx6/cm_fx6.c +++ b/board/compulab/cm_fx6/cm_fx6.c @@ -9,7 +9,9 @@ */ #include <common.h> +#include <ahci.h> #include <dm.h> +#include <dwc_ahsata.h> #include <fsl_esdhc.h> #include <miiphy.h> #include <mtd_node.h> @@ -29,6 +31,7 @@ #include <asm/io.h> #include <asm/gpio.h> #include <dm/platform_data/serial_mxc.h> +#include <dm/device-internal.h> #include <jffs2/load_kernel.h> #include "common.h" #include "../common/eeprom.h" @@ -206,6 +209,8 @@ static int cm_fx6_setup_issd(void) } #define CM_FX6_SATA_INIT_RETRIES 10 + +# if !CONFIG_IS_ENABLED(AHCI) int sata_initialize(void) { int err, i; @@ -246,6 +251,7 @@ int sata_stop(void) return 0; } +# endif #else static int cm_fx6_setup_issd(void) { return 0; } #endif @@ -672,6 +678,17 @@ int board_init(void) cm_fx6_setup_display(); + /* This should be done in the MMC driver when MX6 has a clock driver */ +#ifdef CONFIG_FSL_ESDHC + if (IS_ENABLED(CONFIG_BLK)) { + int i; + + cm_fx6_set_usdhc_iomux(); + for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) + enable_usdhc_clk(1, i); + } +#endif + return 0; } @@ -757,3 +774,66 @@ U_BOOT_DEVICE(cm_fx6_serial) = { .name = "serial_mxc", .platdata = &cm_fx6_mxc_serial_plat, }; + +#if CONFIG_IS_ENABLED(AHCI) +static int sata_imx_probe(struct udevice *dev) +{ + int i, err; + + /* Make sure this gpio has logical 0 value */ + gpio_direction_output(CM_FX6_SATA_PWLOSS_INT, 0); + udelay(100); + cm_fx6_sata_power(1); + + for (i = 0; i < CM_FX6_SATA_INIT_RETRIES; i++) { + err = setup_sata(); + if (err) { + printf("SATA setup failed: %d\n", err); + return err; + } + + udelay(100); + + err = dwc_ahsata_probe(dev); + if (!err) + break; + + /* There is no device on the SATA port */ + if (sata_dm_port_status(0, 0) == 0) + break; + + /* There's a device, but link not established. Retry */ + device_remove(dev, DM_REMOVE_NORMAL); + } + + return 0; +} + +static int sata_imx_remove(struct udevice *dev) +{ + cm_fx6_sata_power(0); + mdelay(250); + + return 0; +} + +struct ahci_ops sata_imx_ops = { + .port_status = dwc_ahsata_port_status, + .reset = dwc_ahsata_bus_reset, + .scan = dwc_ahsata_scan, +}; + +static const struct udevice_id sata_imx_ids[] = { + { .compatible = "fsl,imx6q-ahci" }, + { } +}; + +U_BOOT_DRIVER(sata_imx) = { + .name = "dwc_ahci", + .id = UCLASS_AHCI, + .of_match = sata_imx_ids, + .ops = &sata_imx_ops, + .probe = sata_imx_probe, + .remove = sata_imx_remove, /* reset bus to stop it */ +}; +#endif /* AHCI */ diff --git a/cmd/Makefile b/cmd/Makefile index 13c86f8fccc..4a865bd7d75 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -15,6 +15,7 @@ obj-y += version.o # command obj-$(CONFIG_CMD_AES) += aes.o obj-$(CONFIG_CMD_ARMFLASH) += armflash.o +obj-y += blk_common.o obj-$(CONFIG_SOURCE) += source.o obj-$(CONFIG_CMD_SOURCE) += source.o obj-$(CONFIG_CMD_BDI) += bdinfo.o diff --git a/cmd/blk_common.c b/cmd/blk_common.c new file mode 100644 index 00000000000..86c75e78d88 --- /dev/null +++ b/cmd/blk_common.c @@ -0,0 +1,104 @@ +/* + * Handling of common block commands + * + * Copyright (c) 2017 Google, Inc + * + * (C) Copyright 2000-2011 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <blk.h> + +#ifdef HAVE_BLOCK_DEVICE +int blk_common_cmd(int argc, char * const argv[], enum if_type if_type, + int *cur_devnump) +{ + const char *if_name = blk_get_if_type_name(if_type); + + switch (argc) { + case 0: + case 1: + return CMD_RET_USAGE; + case 2: + if (strncmp(argv[1], "inf", 3) == 0) { + blk_list_devices(if_type); + return 0; + } else if (strncmp(argv[1], "dev", 3) == 0) { + if (blk_print_device_num(if_type, *cur_devnump)) { + printf("\nno %s devices available\n", if_name); + return CMD_RET_FAILURE; + } + return 0; + } else if (strncmp(argv[1], "part", 4) == 0) { + if (blk_list_part(if_type)) + printf("\nno %s devices available\n", if_name); + return 0; + } + return CMD_RET_USAGE; + case 3: + if (strncmp(argv[1], "dev", 3) == 0) { + int dev = (int)simple_strtoul(argv[2], NULL, 10); + + if (!blk_show_device(if_type, dev)) { + *cur_devnump = dev; + printf("... is now current device\n"); + } else { + return CMD_RET_FAILURE; + } + return 0; + } else if (strncmp(argv[1], "part", 4) == 0) { + int dev = (int)simple_strtoul(argv[2], NULL, 10); + + if (blk_print_part_devnum(if_type, dev)) { + printf("\n%s device %d not available\n", + if_name, dev); + return CMD_RET_FAILURE; + } + return 0; + } + return CMD_RET_USAGE; + + default: /* at least 4 args */ + if (strcmp(argv[1], "read") == 0) { + ulong addr = simple_strtoul(argv[2], NULL, 16); + lbaint_t blk = simple_strtoul(argv[3], NULL, 16); + ulong cnt = simple_strtoul(argv[4], NULL, 16); + ulong n; + + printf("\n%s read: device %d block # %lld, count %ld ... ", + if_name, *cur_devnump, (unsigned long long)blk, + cnt); + + n = blk_read_devnum(if_type, *cur_devnump, blk, cnt, + (ulong *)addr); + + printf("%ld blocks read: %s\n", n, + n == cnt ? "OK" : "ERROR"); + return n == cnt ? 0 : 1; + } else if (strcmp(argv[1], "write") == 0) { + ulong addr = simple_strtoul(argv[2], NULL, 16); + lbaint_t blk = simple_strtoul(argv[3], NULL, 16); + ulong cnt = simple_strtoul(argv[4], NULL, 16); + ulong n; + + printf("\n%s write: device %d block # %lld, count %ld ... ", + if_name, *cur_devnump, (unsigned long long)blk, + cnt); + + n = blk_write_devnum(if_type, *cur_devnump, blk, cnt, + (ulong *)addr); + + printf("%ld blocks written: %s\n", n, + n == cnt ? "OK" : "ERROR"); + return n == cnt ? 0 : 1; + } else { + return CMD_RET_USAGE; + } + + return 0; + } +} +#endif diff --git a/cmd/ide.c b/cmd/ide.c index 10fb2f95a7f..e3c32420cfe 100644 --- a/cmd/ide.c +++ b/cmd/ide.c @@ -34,116 +34,15 @@ static int curr_device = -1; int do_ide(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { - int rcode = 0; - - switch (argc) { - case 0: - case 1: - return CMD_RET_USAGE; - case 2: + if (argc == 2) { if (strncmp(argv[1], "res", 3) == 0) { puts("\nReset IDE: "); ide_init(); return 0; - } else if (strncmp(argv[1], "inf", 3) == 0) { - blk_list_devices(IF_TYPE_IDE); - return 0; - - } else if (strncmp(argv[1], "dev", 3) == 0) { - if (blk_print_device_num(IF_TYPE_IDE, curr_device)) { - printf("\nno IDE devices available\n"); - return CMD_RET_FAILURE; - } - - return 0; - } else if (strncmp(argv[1], "part", 4) == 0) { - if (blk_list_part(IF_TYPE_IDE)) - printf("\nno IDE devices available\n"); - return 1; } - return CMD_RET_USAGE; - case 3: - if (strncmp(argv[1], "dev", 3) == 0) { - int dev = (int)simple_strtoul(argv[2], NULL, 10); - - if (!blk_show_device(IF_TYPE_IDE, dev)) { - curr_device = dev; - printf("... is now current device\n"); - } else { - return CMD_RET_FAILURE; - } - return 0; - } else if (strncmp(argv[1], "part", 4) == 0) { - int dev = (int)simple_strtoul(argv[2], NULL, 10); - - if (blk_print_part_devnum(IF_TYPE_IDE, dev)) { - printf("\nIDE device %d not available\n", dev); - return CMD_RET_FAILURE; - } - return 1; - } - - return CMD_RET_USAGE; - default: - /* at least 4 args */ - - if (strcmp(argv[1], "read") == 0) { - ulong addr = simple_strtoul(argv[2], NULL, 16); - ulong cnt = simple_strtoul(argv[4], NULL, 16); - ulong n; - -#ifdef CONFIG_SYS_64BIT_LBA - lbaint_t blk = simple_strtoull(argv[3], NULL, 16); - - printf("\nIDE read: device %d block # %lld, count %ld...", - curr_device, blk, cnt); -#else - lbaint_t blk = simple_strtoul(argv[3], NULL, 16); - - printf("\nIDE read: device %d block # %ld, count %ld...", - curr_device, blk, cnt); -#endif - - n = blk_read_devnum(IF_TYPE_IDE, curr_device, blk, cnt, - (ulong *)addr); - - printf("%ld blocks read: %s\n", - n, (n == cnt) ? "OK" : "ERROR"); - if (n == cnt) - return 0; - else - return 1; - } else if (strcmp(argv[1], "write") == 0) { - ulong addr = simple_strtoul(argv[2], NULL, 16); - ulong cnt = simple_strtoul(argv[4], NULL, 16); - ulong n; - -#ifdef CONFIG_SYS_64BIT_LBA - lbaint_t blk = simple_strtoull(argv[3], NULL, 16); - - printf("\nIDE write: device %d block # %lld, count %ld...", - curr_device, blk, cnt); -#else - lbaint_t blk = simple_strtoul(argv[3], NULL, 16); - - printf("\nIDE write: device %d block # %ld, count %ld...", - curr_device, blk, cnt); -#endif - n = blk_write_devnum(IF_TYPE_IDE, curr_device, blk, cnt, - (ulong *)addr); - - printf("%ld blocks written: %s\n", n, - n == cnt ? "OK" : "ERROR"); - if (n == cnt) - return 0; - else - return 1; - } else { - return CMD_RET_USAGE; - } - - return rcode; } + + return blk_common_cmd(argc, argv, IF_TYPE_IDE, &curr_device); } int do_diskboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) diff --git a/cmd/mmc.c b/cmd/mmc.c index f7b75684ade..00697fc1f2b 100644 --- a/cmd/mmc.c +++ b/cmd/mmc.c @@ -643,6 +643,28 @@ static int do_mmc_boot_resize(cmd_tbl_t *cmdtp, int flag, printf("EMMC RPMB partition Size %d MB\n", rpmbsize); return CMD_RET_SUCCESS; } + +static int mmc_partconf_print(struct mmc *mmc) +{ + u8 ack, access, part; + + if (mmc->part_config == MMCPART_NOAVAILABLE) { + printf("No part_config info for ver. 0x%x\n", mmc->version); + return CMD_RET_FAILURE; + } + + access = EXT_CSD_EXTRACT_PARTITION_ACCESS(mmc->part_config); + ack = EXT_CSD_EXTRACT_BOOT_ACK(mmc->part_config); + part = EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config); + + printf("EXT_CSD[179], PARTITION_CONFIG:\n" + "BOOT_ACK: 0x%x\n" + "BOOT_PARTITION_ENABLE: 0x%x\n" + "PARTITION_ACCESS: 0x%x\n", ack, part, access); + + return CMD_RET_SUCCESS; +} + static int do_mmc_partconf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { @@ -650,13 +672,10 @@ static int do_mmc_partconf(cmd_tbl_t *cmdtp, int flag, struct mmc *mmc; u8 ack, part_num, access; - if (argc != 5) + if (argc != 2 && argc != 5) return CMD_RET_USAGE; dev = simple_strtoul(argv[1], NULL, 10); - ack = simple_strtoul(argv[2], NULL, 10); - part_num = simple_strtoul(argv[3], NULL, 10); - access = simple_strtoul(argv[4], NULL, 10); mmc = init_mmc_device(dev, false); if (!mmc) @@ -667,6 +686,13 @@ static int do_mmc_partconf(cmd_tbl_t *cmdtp, int flag, return CMD_RET_FAILURE; } + if (argc == 2) + return mmc_partconf_print(mmc); + + ack = simple_strtoul(argv[2], NULL, 10); + part_num = simple_strtoul(argv[3], NULL, 10); + access = simple_strtoul(argv[4], NULL, 10); + /* acknowledge to be sent during boot operation */ return mmc_set_part_conf(mmc, ack, part_num, access); } @@ -832,8 +858,8 @@ U_BOOT_CMD( " - Set the BOOT_BUS_WIDTH field of the specified device\n" "mmc bootpart-resize <dev> <boot part size MB> <RPMB part size MB>\n" " - Change sizes of boot and RPMB partitions of specified device\n" - "mmc partconf dev boot_ack boot_partition partition_access\n" - " - Change the bits of the PARTITION_CONFIG field of the specified device\n" + "mmc partconf dev [boot_ack boot_partition partition_access]\n" + " - Show or change the bits of the PARTITION_CONFIG field of the specified device\n" "mmc rst-function dev value\n" " - Change the RST_n_FUNCTION field of the specified device\n" " WARNING: This is a write-once field and 0 / 1 / 2 are the only valid values.\n" diff --git a/cmd/sata.c b/cmd/sata.c index 4c53022ff60..7817442532a 100644 --- a/cmd/sata.c +++ b/cmd/sata.c @@ -11,124 +11,116 @@ */ #include <common.h> +#include <ahci.h> +#include <dm.h> #include <command.h> #include <part.h> #include <sata.h> +#include <dm/device-internal.h> +#include <dm/uclass-internal.h> static int sata_curr_device = -1; +int sata_remove(int devnum) +{ +#ifdef CONFIG_AHCI + struct udevice *dev; + int rc; + + rc = uclass_find_device(UCLASS_AHCI, devnum, &dev); + if (!rc && !dev) + rc = uclass_find_first_device(UCLASS_AHCI, &dev); + if (rc || !dev) { + printf("Cannot find SATA device %d (err=%d)\n", devnum, rc); + return CMD_RET_FAILURE; + } + + rc = device_remove(dev, DM_REMOVE_NORMAL); + if (rc) { + printf("Cannot remove SATA device '%s' (err=%d)\n", dev->name, + rc); + return CMD_RET_FAILURE; + } + + return 0; +#else + return sata_stop(); +#endif +} + +int sata_probe(int devnum) +{ +#ifdef CONFIG_AHCI + struct udevice *dev; + struct udevice *blk; + int rc; + + rc = uclass_get_device(UCLASS_AHCI, devnum, &dev); + if (rc) + rc = uclass_find_first_device(UCLASS_AHCI, &dev); + if (rc) { + printf("Cannot probe SATA device %d (err=%d)\n", devnum, rc); + return CMD_RET_FAILURE; + } + rc = sata_scan(dev); + if (rc) { + printf("Cannot scan SATA device %d (err=%d)\n", devnum, rc); + return CMD_RET_FAILURE; + } + + rc = blk_get_from_parent(dev, &blk); + if (!rc) { + struct blk_desc *desc = dev_get_uclass_platdata(blk); + + if (desc->lba > 0 && desc->blksz > 0) + part_init(desc); + } + + return 0; +#else + return sata_initialize() < 0 ? CMD_RET_FAILURE : CMD_RET_SUCCESS; +#endif +} + static int do_sata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int rc = 0; - if (argc == 2 && strcmp(argv[1], "stop") == 0) - return sata_stop(); + if (argc >= 2) { + int devnum = 0; - if (argc == 2 && strcmp(argv[1], "init") == 0) { - if (sata_curr_device != -1) - sata_stop(); + if (argc == 3) + devnum = (int)simple_strtoul(argv[2], NULL, 10); + if (!strcmp(argv[1], "stop")) + return sata_remove(devnum); + + if (!strcmp(argv[1], "init")) { + if (sata_curr_device != -1) { + rc = sata_remove(devnum); + if (rc) + return rc; + } - return (sata_initialize() < 0) ? - CMD_RET_FAILURE : CMD_RET_SUCCESS; + return sata_probe(devnum); + } } /* If the user has not yet run `sata init`, do it now */ if (sata_curr_device == -1) { - rc = sata_initialize(); - if (rc == -1) + rc = sata_probe(0); + if (rc < 0) return CMD_RET_FAILURE; - sata_curr_device = rc; + sata_curr_device = 0; } - switch (argc) { - case 0: - case 1: - return CMD_RET_USAGE; - case 2: - if (strncmp(argv[1], "inf", 3) == 0) { - blk_list_devices(IF_TYPE_SATA); - return 0; - } else if (strncmp(argv[1], "dev", 3) == 0) { - if (blk_print_device_num(IF_TYPE_SATA, - sata_curr_device)) { - printf("\nno SATA devices available\n"); - return CMD_RET_FAILURE; - } - return 0; - } else if (strncmp(argv[1], "part", 4) == 0) { - if (blk_list_part(IF_TYPE_SATA)) - puts("\nno SATA devices available\n"); - return 0; - } - return CMD_RET_USAGE; - case 3: - if (strncmp(argv[1], "dev", 3) == 0) { - int dev = (int)simple_strtoul(argv[2], NULL, 10); - - if (!blk_show_device(IF_TYPE_SATA, dev)) { - sata_curr_device = dev; - printf("... is now current device\n"); - } else { - return CMD_RET_FAILURE; - } - return 0; - } else if (strncmp(argv[1], "part", 4) == 0) { - int dev = (int)simple_strtoul(argv[2], NULL, 10); - - if (blk_print_part_devnum(IF_TYPE_SATA, dev)) { - printf("\nSATA device %d not available\n", - dev); - return CMD_RET_FAILURE; - } - return rc; - } - return CMD_RET_USAGE; - - default: /* at least 4 args */ - if (strcmp(argv[1], "read") == 0) { - ulong addr = simple_strtoul(argv[2], NULL, 16); - ulong cnt = simple_strtoul(argv[4], NULL, 16); - ulong n; - lbaint_t blk = simple_strtoul(argv[3], NULL, 16); - - printf("\nSATA read: device %d block # %ld, count %ld ... ", - sata_curr_device, blk, cnt); - - n = blk_read_devnum(IF_TYPE_SATA, sata_curr_device, blk, - cnt, (ulong *)addr); - - printf("%ld blocks read: %s\n", - n, (n==cnt) ? "OK" : "ERROR"); - return (n == cnt) ? 0 : 1; - } else if (strcmp(argv[1], "write") == 0) { - ulong addr = simple_strtoul(argv[2], NULL, 16); - ulong cnt = simple_strtoul(argv[4], NULL, 16); - ulong n; - - lbaint_t blk = simple_strtoul(argv[3], NULL, 16); - - printf("\nSATA write: device %d block # %ld, count %ld ... ", - sata_curr_device, blk, cnt); - - n = blk_write_devnum(IF_TYPE_SATA, sata_curr_device, - blk, cnt, (ulong *)addr); - - printf("%ld blocks written: %s\n", - n, (n == cnt) ? "OK" : "ERROR"); - return (n == cnt) ? 0 : 1; - } else { - return CMD_RET_USAGE; - } - - return rc; - } + return blk_common_cmd(argc, argv, IF_TYPE_SATA, &sata_curr_device); } U_BOOT_CMD( sata, 5, 1, do_sata, "SATA sub system", "init - init SATA sub system\n" - "sata stop - disable SATA sub system\n" + "sata stop [dev] - disable SATA sub system or device\n" "sata info - show available SATA devices\n" "sata device [dev] - show or set current device\n" "sata part [dev] - print partition table\n" diff --git a/cmd/scsi.c b/cmd/scsi.c index 8e36de107e9..b9d086fb6b1 100644 --- a/cmd/scsi.c +++ b/cmd/scsi.c @@ -29,11 +29,7 @@ static int do_scsi(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { int ret; - switch (argc) { - case 0: - case 1: - return CMD_RET_USAGE; - case 2: + if (argc == 2) { if (strncmp(argv[1], "res", 3) == 0) { printf("\nReset SCSI\n"); #ifndef CONFIG_DM_SCSI @@ -44,84 +40,15 @@ static int do_scsi(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) return CMD_RET_FAILURE; return ret; } - if (strncmp(argv[1], "inf", 3) == 0) { - blk_list_devices(IF_TYPE_SCSI); - return 0; - } - if (strncmp(argv[1], "dev", 3) == 0) { - if (blk_print_device_num(IF_TYPE_SCSI, scsi_curr_dev)) { - printf("\nno SCSI devices available\n"); - return CMD_RET_FAILURE; - } - - return 0; - } if (strncmp(argv[1], "scan", 4) == 0) { ret = scsi_scan(true); if (ret) return CMD_RET_FAILURE; return ret; } - if (strncmp(argv[1], "part", 4) == 0) { - if (blk_list_part(IF_TYPE_SCSI)) - printf("\nno SCSI devices available\n"); - return 0; - } - return CMD_RET_USAGE; - case 3: - if (strncmp(argv[1], "dev", 3) == 0) { - int dev = (int)simple_strtoul(argv[2], NULL, 10); + } - if (!blk_show_device(IF_TYPE_SCSI, dev)) { - scsi_curr_dev = dev; - printf("... is now current device\n"); - } else { - return CMD_RET_FAILURE; - } - return 0; - } - if (strncmp(argv[1], "part", 4) == 0) { - int dev = (int)simple_strtoul(argv[2], NULL, 10); - - if (blk_print_part_devnum(IF_TYPE_SCSI, dev)) { - printf("\nSCSI device %d not available\n", - dev); - return CMD_RET_FAILURE; - } - return 0; - } - return CMD_RET_USAGE; - default: - /* at least 4 args */ - if (strcmp(argv[1], "read") == 0) { - ulong addr = simple_strtoul(argv[2], NULL, 16); - ulong blk = simple_strtoul(argv[3], NULL, 16); - ulong cnt = simple_strtoul(argv[4], NULL, 16); - ulong n; - - printf("\nSCSI read: device %d block # %ld, count %ld ... ", - scsi_curr_dev, blk, cnt); - n = blk_read_devnum(IF_TYPE_SCSI, scsi_curr_dev, blk, - cnt, (ulong *)addr); - printf("%ld blocks read: %s\n", n, - n == cnt ? "OK" : "ERROR"); - return 0; - } else if (strcmp(argv[1], "write") == 0) { - ulong addr = simple_strtoul(argv[2], NULL, 16); - ulong blk = simple_strtoul(argv[3], NULL, 16); - ulong cnt = simple_strtoul(argv[4], NULL, 16); - ulong n; - - printf("\nSCSI write: device %d block # %ld, count %ld ... ", - scsi_curr_dev, blk, cnt); - n = blk_write_devnum(IF_TYPE_SCSI, scsi_curr_dev, blk, - cnt, (ulong *)addr); - printf("%ld blocks written: %s\n", n, - n == cnt ? "OK" : "ERROR"); - return 0; - } - } /* switch */ - return CMD_RET_USAGE; + return blk_common_cmd(argc, argv, IF_TYPE_SCSI, &scsi_curr_dev); } U_BOOT_CMD( diff --git a/cmd/usb.c b/cmd/usb.c index 992d4140819..d95bcf5c8ee 100644 --- a/cmd/usb.c +++ b/cmd/usb.c @@ -621,9 +621,6 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) struct usb_device *udev = NULL; int i; extern char usb_started; -#ifdef CONFIG_USB_STORAGE - struct blk_desc *stor_dev; -#endif if (argc < 2) return CMD_RET_USAGE; @@ -712,112 +709,10 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if (strncmp(argv[1], "stor", 4) == 0) return usb_stor_info(); - if (strncmp(argv[1], "part", 4) == 0) { - int devno, ok = 0; - if (argc == 2) { - for (devno = 0; ; ++devno) { - stor_dev = blk_get_devnum_by_type(IF_TYPE_USB, - devno); - if (stor_dev == NULL) - break; - if (stor_dev->type != DEV_TYPE_UNKNOWN) { - ok++; - if (devno) - printf("\n"); - debug("print_part of %x\n", devno); - part_print(stor_dev); - } - } - } else { - devno = simple_strtoul(argv[2], NULL, 16); - stor_dev = blk_get_devnum_by_type(IF_TYPE_USB, devno); - if (stor_dev != NULL && - stor_dev->type != DEV_TYPE_UNKNOWN) { - ok++; - debug("print_part of %x\n", devno); - part_print(stor_dev); - } - } - if (!ok) { - printf("\nno USB devices available\n"); - return 1; - } - return 0; - } - if (strcmp(argv[1], "read") == 0) { - if (usb_stor_curr_dev < 0) { - printf("no current device selected\n"); - return 1; - } - if (argc == 5) { - unsigned long addr = simple_strtoul(argv[2], NULL, 16); - unsigned long blk = simple_strtoul(argv[3], NULL, 16); - unsigned long cnt = simple_strtoul(argv[4], NULL, 16); - unsigned long n; - printf("\nUSB read: device %d block # %ld, count %ld" - " ... ", usb_stor_curr_dev, blk, cnt); - stor_dev = blk_get_devnum_by_type(IF_TYPE_USB, - usb_stor_curr_dev); - n = blk_dread(stor_dev, blk, cnt, (ulong *)addr); - printf("%ld blocks read: %s\n", n, - (n == cnt) ? "OK" : "ERROR"); - if (n == cnt) - return 0; - return 1; - } - } - if (strcmp(argv[1], "write") == 0) { - if (usb_stor_curr_dev < 0) { - printf("no current device selected\n"); - return 1; - } - if (argc == 5) { - unsigned long addr = simple_strtoul(argv[2], NULL, 16); - unsigned long blk = simple_strtoul(argv[3], NULL, 16); - unsigned long cnt = simple_strtoul(argv[4], NULL, 16); - unsigned long n; - printf("\nUSB write: device %d block # %ld, count %ld" - " ... ", usb_stor_curr_dev, blk, cnt); - stor_dev = blk_get_devnum_by_type(IF_TYPE_USB, - usb_stor_curr_dev); - n = blk_dwrite(stor_dev, blk, cnt, (ulong *)addr); - printf("%ld blocks write: %s\n", n, - (n == cnt) ? "OK" : "ERROR"); - if (n == cnt) - return 0; - return 1; - } - } - if (strncmp(argv[1], "dev", 3) == 0) { - if (argc == 3) { - int dev = (int)simple_strtoul(argv[2], NULL, 10); - printf("\nUSB device %d: ", dev); - stor_dev = blk_get_devnum_by_type(IF_TYPE_USB, dev); - if ((stor_dev == NULL) || - (stor_dev->if_type == IF_TYPE_UNKNOWN)) { - printf("unknown device\n"); - return 1; - } - printf("\n Device %d: ", dev); - dev_print(stor_dev); - if (stor_dev->type == DEV_TYPE_UNKNOWN) - return 1; - usb_stor_curr_dev = dev; - printf("... is now current device\n"); - return 0; - } else { - printf("\nUSB device %d: ", usb_stor_curr_dev); - stor_dev = blk_get_devnum_by_type(IF_TYPE_USB, - usb_stor_curr_dev); - dev_print(stor_dev); - if (stor_dev->type == DEV_TYPE_UNKNOWN) - return 1; - return 0; - } - return 0; - } -#endif /* CONFIG_USB_STORAGE */ + return blk_common_cmd(argc, argv, IF_TYPE_USB, &usb_stor_curr_dev); +#else return CMD_RET_USAGE; +#endif /* CONFIG_USB_STORAGE */ } U_BOOT_CMD( diff --git a/common/splash_source.c b/common/splash_source.c index 8c0ac581f73..a21ad62f82d 100644 --- a/common/splash_source.c +++ b/common/splash_source.c @@ -166,7 +166,7 @@ static inline int splash_init_usb(void) #ifdef CONFIG_SATA static int splash_init_sata(void) { - return sata_initialize(); + return sata_probe(0); } #else static inline int splash_init_sata(void) diff --git a/configs/cm_fx6_defconfig b/configs/cm_fx6_defconfig index bbe82a678db..d3aab58cf61 100644 --- a/configs/cm_fx6_defconfig +++ b/configs/cm_fx6_defconfig @@ -11,6 +11,8 @@ CONFIG_SPL_SPI_SUPPORT=y CONFIG_SPL_WATCHDOG_SUPPORT=y CONFIG_VIDEO=y # CONFIG_CMD_BMODE is not set +CONFIG_DEFAULT_DEVICE_TREE="imx6q-cm-fx6" +CONFIG_AHCI=y CONFIG_OF_BOARD_SETUP=y CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg,MX6QDL" CONFIG_ENV_IS_IN_SPI_FLASH=y @@ -49,6 +51,8 @@ CONFIG_CMD_EXT4_WRITE=y CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y CONFIG_CMD_MTDPARTS=y +CONFIG_OF_CONTROL=y +CONFIG_DM_MMC=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_ATMEL=y CONFIG_SPI_FLASH_EON=y @@ -59,9 +63,11 @@ CONFIG_SPI_FLASH_STMICRO=y CONFIG_SPI_FLASH_SST=y CONFIG_SPI_FLASH_WINBOND=y CONFIG_PHYLIB=y +CONFIG_DM_PMIC=y +CONFIG_DM_REGULATOR=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_USB_KEYBOARD=y CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y -CONFIG_OF_LIBFDT=y CONFIG_FDT_FIXUP_PARTITIONS=y diff --git a/configs/imx6q_logic_defconfig b/configs/imx6q_logic_defconfig index 1070f892c49..bb13abedf7b 100644 --- a/configs/imx6q_logic_defconfig +++ b/configs/imx6q_logic_defconfig @@ -31,7 +31,6 @@ CONFIG_CMD_FS_GENERIC=y CONFIG_CMD_MTDPARTS=y # CONFIG_BLK is not set CONFIG_SYS_I2C_MXC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_NAND=y CONFIG_NAND_MXS=y CONFIG_PHYLIB=y diff --git a/configs/imx6qdl_icore_mmc_defconfig b/configs/imx6qdl_icore_mmc_defconfig index 090480aacbe..ec39d091348 100644 --- a/configs/imx6qdl_icore_mmc_defconfig +++ b/configs/imx6qdl_icore_mmc_defconfig @@ -38,7 +38,6 @@ CONFIG_CMD_FS_GENERIC=y CONFIG_OF_LIST="imx6q-icore imx6dl-icore" # CONFIG_BLK is not set CONFIG_SYS_I2C_MXC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_PHYLIB=y CONFIG_PHY_SMSC=y CONFIG_FEC_MXC=y diff --git a/configs/imx6qdl_icore_rqs_defconfig b/configs/imx6qdl_icore_rqs_defconfig index 78128a08726..ba3ac1bbf92 100644 --- a/configs/imx6qdl_icore_rqs_defconfig +++ b/configs/imx6qdl_icore_rqs_defconfig @@ -36,7 +36,6 @@ CONFIG_CMD_FS_GENERIC=y CONFIG_OF_LIST="imx6q-icore-rqs imx6dl-icore-rqs" # CONFIG_BLK is not set CONFIG_SYS_I2C_MXC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_PHYLIB=y CONFIG_PHY_MICREL=y CONFIG_FEC_MXC=y diff --git a/configs/imx6ul_geam_mmc_defconfig b/configs/imx6ul_geam_mmc_defconfig index dfeb083c8f3..d0abfd80294 100644 --- a/configs/imx6ul_geam_mmc_defconfig +++ b/configs/imx6ul_geam_mmc_defconfig @@ -35,7 +35,6 @@ CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y # CONFIG_BLK is not set CONFIG_SYS_I2C_MXC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_PHYLIB=y CONFIG_PHY_SMSC=y CONFIG_FEC_MXC=y diff --git a/configs/imx6ul_geam_nand_defconfig b/configs/imx6ul_geam_nand_defconfig index ed81f61759c..3c079011802 100644 --- a/configs/imx6ul_geam_nand_defconfig +++ b/configs/imx6ul_geam_nand_defconfig @@ -34,7 +34,6 @@ CONFIG_CMD_FS_GENERIC=y CONFIG_CMD_UBI=y # CONFIG_BLK is not set CONFIG_SYS_I2C_MXC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_NAND=y CONFIG_NAND_MXS=y CONFIG_PHYLIB=y diff --git a/configs/imx6ul_isiot_emmc_defconfig b/configs/imx6ul_isiot_emmc_defconfig index 318deb692d5..eeb0509e204 100644 --- a/configs/imx6ul_isiot_emmc_defconfig +++ b/configs/imx6ul_isiot_emmc_defconfig @@ -33,7 +33,6 @@ CONFIG_CMD_EXT4_WRITE=y CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y # CONFIG_BLK is not set -# CONFIG_DM_MMC_OPS is not set CONFIG_PHYLIB=y CONFIG_PHY_SMSC=y CONFIG_FEC_MXC=y diff --git a/configs/imx6ul_isiot_mmc_defconfig b/configs/imx6ul_isiot_mmc_defconfig index 8abfbabfcc1..afa64d80553 100644 --- a/configs/imx6ul_isiot_mmc_defconfig +++ b/configs/imx6ul_isiot_mmc_defconfig @@ -35,7 +35,6 @@ CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y # CONFIG_BLK is not set CONFIG_SYS_I2C_MXC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_PHYLIB=y CONFIG_PHY_SMSC=y CONFIG_FEC_MXC=y diff --git a/configs/imx6ul_isiot_nand_defconfig b/configs/imx6ul_isiot_nand_defconfig index ad11ac3a377..9acf6c535fd 100644 --- a/configs/imx6ul_isiot_nand_defconfig +++ b/configs/imx6ul_isiot_nand_defconfig @@ -34,7 +34,6 @@ CONFIG_CMD_FS_GENERIC=y CONFIG_CMD_UBI=y # CONFIG_BLK is not set CONFIG_SYS_I2C_MXC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_NAND=y CONFIG_NAND_MXS=y CONFIG_PHYLIB=y diff --git a/configs/ls1012aqds_qspi_defconfig b/configs/ls1012aqds_qspi_defconfig index ff58a74986e..426992e5771 100644 --- a/configs/ls1012aqds_qspi_defconfig +++ b/configs/ls1012aqds_qspi_defconfig @@ -36,7 +36,6 @@ CONFIG_NET_RANDOM_ETHADDR=y CONFIG_DM=y # CONFIG_BLK is not set CONFIG_DM_MMC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH=y CONFIG_NETDEVICES=y diff --git a/configs/ls1012ardb_qspi_defconfig b/configs/ls1012ardb_qspi_defconfig index 6a150221b25..4eaaecd9912 100644 --- a/configs/ls1012ardb_qspi_defconfig +++ b/configs/ls1012ardb_qspi_defconfig @@ -34,7 +34,6 @@ CONFIG_NET_RANDOM_ETHADDR=y CONFIG_DM=y # CONFIG_BLK is not set CONFIG_DM_MMC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH=y CONFIG_NETDEVICES=y diff --git a/configs/mx6slevk_defconfig b/configs/mx6slevk_defconfig index ee27daa68e0..f7f4b0edf1f 100644 --- a/configs/mx6slevk_defconfig +++ b/configs/mx6slevk_defconfig @@ -32,7 +32,6 @@ CONFIG_DM=y CONFIG_DM_GPIO=y CONFIG_DM_I2C=y CONFIG_DM_MMC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_STMICRO=y CONFIG_PHYLIB=y diff --git a/configs/mx6slevk_spinor_defconfig b/configs/mx6slevk_spinor_defconfig index 354eae3f572..a3d68512cf0 100644 --- a/configs/mx6slevk_spinor_defconfig +++ b/configs/mx6slevk_spinor_defconfig @@ -33,7 +33,6 @@ CONFIG_DM=y CONFIG_DM_GPIO=y CONFIG_DM_I2C=y CONFIG_DM_MMC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_STMICRO=y CONFIG_PHYLIB=y diff --git a/configs/mx6sllevk_defconfig b/configs/mx6sllevk_defconfig index 916fa091fa6..11d2500949a 100644 --- a/configs/mx6sllevk_defconfig +++ b/configs/mx6sllevk_defconfig @@ -29,7 +29,6 @@ CONFIG_OF_CONTROL=y CONFIG_DM_GPIO=y CONFIG_DM_I2C=y CONFIG_DM_MMC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_PINCTRL=y CONFIG_PINCTRL_IMX6=y CONFIG_DM_PMIC=y diff --git a/configs/mx6sllevk_plugin_defconfig b/configs/mx6sllevk_plugin_defconfig index 12f865713dd..064c949e356 100644 --- a/configs/mx6sllevk_plugin_defconfig +++ b/configs/mx6sllevk_plugin_defconfig @@ -30,7 +30,6 @@ CONFIG_OF_CONTROL=y CONFIG_DM_GPIO=y CONFIG_DM_I2C=y CONFIG_DM_MMC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_PINCTRL=y CONFIG_PINCTRL_IMX6=y CONFIG_DM_PMIC=y diff --git a/configs/mx6sxsabreauto_defconfig b/configs/mx6sxsabreauto_defconfig index a8144fe8021..ebf0a9aacba 100644 --- a/configs/mx6sxsabreauto_defconfig +++ b/configs/mx6sxsabreauto_defconfig @@ -34,7 +34,6 @@ CONFIG_DM_GPIO=y CONFIG_DM_PCA953X=y CONFIG_DM_I2C=y CONFIG_DM_MMC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_BAR=y CONFIG_SPI_FLASH_STMICRO=y diff --git a/configs/mx6ull_14x14_evk_defconfig b/configs/mx6ull_14x14_evk_defconfig index 2c03f8cba83..6ed18da3769 100644 --- a/configs/mx6ull_14x14_evk_defconfig +++ b/configs/mx6ull_14x14_evk_defconfig @@ -27,7 +27,6 @@ CONFIG_DM_GPIO=y CONFIG_DM_74X164=y CONFIG_DM_I2C=y CONFIG_DM_MMC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_PINCTRL=y CONFIG_PINCTRL_IMX6=y CONFIG_DM_REGULATOR=y diff --git a/configs/mx6ull_14x14_evk_plugin_defconfig b/configs/mx6ull_14x14_evk_plugin_defconfig index 1a5bbb6265f..2c5ae76f263 100644 --- a/configs/mx6ull_14x14_evk_plugin_defconfig +++ b/configs/mx6ull_14x14_evk_plugin_defconfig @@ -28,7 +28,6 @@ CONFIG_DM_GPIO=y CONFIG_DM_74X164=y CONFIG_DM_I2C=y CONFIG_DM_MMC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_PINCTRL=y CONFIG_PINCTRL_IMX6=y CONFIG_DM_REGULATOR=y diff --git a/configs/mx7dsabresd_defconfig b/configs/mx7dsabresd_defconfig index 7c99420e853..8f2e33adc86 100644 --- a/configs/mx7dsabresd_defconfig +++ b/configs/mx7dsabresd_defconfig @@ -45,7 +45,6 @@ CONFIG_DM_GPIO=y CONFIG_DM_74X164=y CONFIG_DM_I2C=y CONFIG_DM_MMC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_EON=y CONFIG_PHYLIB=y diff --git a/configs/mx7dsabresd_secure_defconfig b/configs/mx7dsabresd_secure_defconfig index ea087d2af42..bba933f250b 100644 --- a/configs/mx7dsabresd_secure_defconfig +++ b/configs/mx7dsabresd_secure_defconfig @@ -47,7 +47,6 @@ CONFIG_DM_GPIO=y CONFIG_DM_74X164=y CONFIG_DM_I2C=y CONFIG_DM_MMC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_EON=y CONFIG_PHYLIB=y diff --git a/configs/mx7ulp_evk_defconfig b/configs/mx7ulp_evk_defconfig index 5918f3c0c73..49b576954b5 100644 --- a/configs/mx7ulp_evk_defconfig +++ b/configs/mx7ulp_evk_defconfig @@ -16,7 +16,6 @@ CONFIG_DM_GPIO=y CONFIG_IMX_RGPIO2P=y CONFIG_DM_I2C=y CONFIG_DM_MMC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_PINCTRL=y CONFIG_PINCTRL_IMX7ULP=y CONFIG_DM_REGULATOR=y diff --git a/configs/mx7ulp_evk_plugin_defconfig b/configs/mx7ulp_evk_plugin_defconfig index 5918f3c0c73..49b576954b5 100644 --- a/configs/mx7ulp_evk_plugin_defconfig +++ b/configs/mx7ulp_evk_plugin_defconfig @@ -16,7 +16,6 @@ CONFIG_DM_GPIO=y CONFIG_IMX_RGPIO2P=y CONFIG_DM_I2C=y CONFIG_DM_MMC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_PINCTRL=y CONFIG_PINCTRL_IMX7ULP=y CONFIG_DM_REGULATOR=y diff --git a/configs/opos6uldev_defconfig b/configs/opos6uldev_defconfig index f4511af2930..88ba18eaeb2 100644 --- a/configs/opos6uldev_defconfig +++ b/configs/opos6uldev_defconfig @@ -62,7 +62,6 @@ CONFIG_SYSCON=y CONFIG_DM_I2C=y CONFIG_SYS_I2C_MXC=y CONFIG_PWRSEQ=y -# CONFIG_DM_MMC_OPS is not set CONFIG_PHYLIB=y CONFIG_PHY_MICREL=y CONFIG_NETDEVICES=y diff --git a/drivers/ata/dwc_ahsata.c b/drivers/ata/dwc_ahsata.c index 78572a5b73a..480ae115afd 100644 --- a/drivers/ata/dwc_ahsata.c +++ b/drivers/ata/dwc_ahsata.c @@ -5,20 +5,22 @@ * SPDX-License-Identifier: GPL-2.0+ */ -#include <libata.h> +#include <common.h> #include <ahci.h> +#include <dm.h> +#include <dwc_ahsata.h> #include <fis.h> -#include <sata.h> - -#include <common.h> +#include <libata.h> #include <malloc.h> -#include <linux/ctype.h> -#include <linux/errno.h> +#include <memalign.h> +#include <sata.h> #include <asm/io.h> -#include <linux/bitops.h> #include <asm/arch/clock.h> #include <asm/arch/sys_proto.h> -#include "dwc_ahsata.h" +#include <linux/bitops.h> +#include <linux/ctype.h> +#include <linux/errno.h> +#include "dwc_ahsata_priv.h" struct sata_port_regs { u32 clb; @@ -78,8 +80,6 @@ struct sata_host_regs { #define writel_with_flush(a, b) do { writel(a, b); readl(b); } while (0) -static int is_ready; - static inline void __iomem *ahci_port_base(void __iomem *base, u32 port) { return base + 0x100 + (port * 0x80); @@ -100,37 +100,33 @@ static int waiting_for_cmd_completed(u8 *offset, return (i < timeout_msec) ? 0 : -1; } -static int ahci_setup_oobr(struct ahci_uc_priv *probe_ent, - int clk) +static int ahci_setup_oobr(struct ahci_uc_priv *uc_priv, int clk) { - struct sata_host_regs *host_mmio = - (struct sata_host_regs *)probe_ent->mmio_base; + struct sata_host_regs *host_mmio = uc_priv->mmio_base; - writel(SATA_HOST_OOBR_WE, &(host_mmio->oobr)); - writel(0x02060b14, &(host_mmio->oobr)); + writel(SATA_HOST_OOBR_WE, &host_mmio->oobr); + writel(0x02060b14, &host_mmio->oobr); return 0; } -static int ahci_host_init(struct ahci_uc_priv *probe_ent) +static int ahci_host_init(struct ahci_uc_priv *uc_priv) { u32 tmp, cap_save, num_ports; int i, j, timeout = 1000; struct sata_port_regs *port_mmio = NULL; - struct sata_host_regs *host_mmio = - (struct sata_host_regs *)probe_ent->mmio_base; + struct sata_host_regs *host_mmio = uc_priv->mmio_base; int clk = mxc_get_clock(MXC_SATA_CLK); - cap_save = readl(&(host_mmio->cap)); + cap_save = readl(&host_mmio->cap); cap_save |= SATA_HOST_CAP_SSS; /* global controller reset */ - tmp = readl(&(host_mmio->ghc)); + tmp = readl(&host_mmio->ghc); if ((tmp & SATA_HOST_GHC_HR) == 0) - writel_with_flush(tmp | SATA_HOST_GHC_HR, &(host_mmio->ghc)); + writel_with_flush(tmp | SATA_HOST_GHC_HR, &host_mmio->ghc); - while ((readl(&(host_mmio->ghc)) & SATA_HOST_GHC_HR) - && --timeout) + while ((readl(&host_mmio->ghc) & SATA_HOST_GHC_HR) && --timeout) ; if (timeout <= 0) { @@ -139,15 +135,14 @@ static int ahci_host_init(struct ahci_uc_priv *probe_ent) } /* Set timer 1ms */ - writel(clk / 1000, &(host_mmio->timer1ms)); + writel(clk / 1000, &host_mmio->timer1ms); - ahci_setup_oobr(probe_ent, 0); + ahci_setup_oobr(uc_priv, 0); - writel_with_flush(SATA_HOST_GHC_AE, &(host_mmio->ghc)); - writel(cap_save, &(host_mmio->cap)); + writel_with_flush(SATA_HOST_GHC_AE, &host_mmio->ghc); + writel(cap_save, &host_mmio->cap); num_ports = (cap_save & SATA_HOST_CAP_NP_MASK) + 1; - writel_with_flush((1 << num_ports) - 1, - &(host_mmio->pi)); + writel_with_flush((1 << num_ports) - 1, &host_mmio->pi); /* * Determine which Ports are implemented by the DWC_ahsata, @@ -155,24 +150,21 @@ static int ahci_host_init(struct ahci_uc_priv *probe_ent) * software to determine how many Ports are available and * which Port registers need to be initialized. */ - probe_ent->cap = readl(&(host_mmio->cap)); - probe_ent->port_map = readl(&(host_mmio->pi)); + uc_priv->cap = readl(&host_mmio->cap); + uc_priv->port_map = readl(&host_mmio->pi); /* Determine how many command slots the HBA supports */ - probe_ent->n_ports = - (probe_ent->cap & SATA_HOST_CAP_NP_MASK) + 1; + uc_priv->n_ports = (uc_priv->cap & SATA_HOST_CAP_NP_MASK) + 1; debug("cap 0x%x port_map 0x%x n_ports %d\n", - probe_ent->cap, probe_ent->port_map, probe_ent->n_ports); + uc_priv->cap, uc_priv->port_map, uc_priv->n_ports); - for (i = 0; i < probe_ent->n_ports; i++) { - probe_ent->port[i].port_mmio = - ahci_port_base(host_mmio, i); - port_mmio = - (struct sata_port_regs *)probe_ent->port[i].port_mmio; + for (i = 0; i < uc_priv->n_ports; i++) { + uc_priv->port[i].port_mmio = ahci_port_base(host_mmio, i); + port_mmio = uc_priv->port[i].port_mmio; /* Ensure that the DWC_ahsata is in idle state */ - tmp = readl(&(port_mmio->cmd)); + tmp = readl(&port_mmio->cmd); /* * When P#CMD.ST, P#CMD.CR, P#CMD.FRE and P#CMD.FR @@ -187,7 +179,7 @@ static int ahci_host_init(struct ahci_uc_priv *probe_ent) * 0 when read. */ tmp &= ~SATA_PORT_CMD_ST; - writel_with_flush(tmp, &(port_mmio->cmd)); + writel_with_flush(tmp, &port_mmio->cmd); /* * spec says 500 msecs for each bit, so @@ -196,7 +188,7 @@ static int ahci_host_init(struct ahci_uc_priv *probe_ent) mdelay(500); timeout = 1000; - while ((readl(&(port_mmio->cmd)) & SATA_PORT_CMD_CR) + while ((readl(&port_mmio->cmd) & SATA_PORT_CMD_CR) && --timeout) ; @@ -207,12 +199,12 @@ static int ahci_host_init(struct ahci_uc_priv *probe_ent) } /* Spin-up device */ - tmp = readl(&(port_mmio->cmd)); - writel((tmp | SATA_PORT_CMD_SUD), &(port_mmio->cmd)); + tmp = readl(&port_mmio->cmd); + writel((tmp | SATA_PORT_CMD_SUD), &port_mmio->cmd); /* Wait for spin-up to finish */ timeout = 1000; - while (!(readl(&(port_mmio->cmd)) | SATA_PORT_CMD_SUD) + while (!(readl(&port_mmio->cmd) | SATA_PORT_CMD_SUD) && --timeout) ; if (timeout <= 0) { @@ -222,7 +214,7 @@ static int ahci_host_init(struct ahci_uc_priv *probe_ent) for (j = 0; j < 100; ++j) { mdelay(10); - tmp = readl(&(port_mmio->ssts)); + tmp = readl(&port_mmio->ssts); if (((tmp & SATA_PORT_SSTS_DET_MASK) == 0x3) || ((tmp & SATA_PORT_SSTS_DET_MASK) == 0x1)) break; @@ -230,7 +222,7 @@ static int ahci_host_init(struct ahci_uc_priv *probe_ent) /* Wait for COMINIT bit 26 (DIAG_X) in SERR */ timeout = 1000; - while (!(readl(&(port_mmio->serr)) | SATA_PORT_SERR_DIAG_X) + while (!(readl(&port_mmio->serr) | SATA_PORT_SERR_DIAG_X) && --timeout) ; if (timeout <= 0) { @@ -243,49 +235,48 @@ static int ahci_host_init(struct ahci_uc_priv *probe_ent) * register, by writing ones to each implemented\ * bit location. */ - tmp = readl(&(port_mmio->serr)); + tmp = readl(&port_mmio->serr); debug("P#SERR 0x%x\n", tmp); - writel(tmp, &(port_mmio->serr)); + writel(tmp, &port_mmio->serr); /* Ack any pending irq events for this port */ - tmp = readl(&(host_mmio->is)); + tmp = readl(&host_mmio->is); debug("IS 0x%x\n", tmp); if (tmp) - writel(tmp, &(host_mmio->is)); + writel(tmp, &host_mmio->is); - writel(1 << i, &(host_mmio->is)); + writel(1 << i, &host_mmio->is); /* set irq mask (enables interrupts) */ - writel(DEF_PORT_IRQ, &(port_mmio->ie)); + writel(DEF_PORT_IRQ, &port_mmio->ie); /* register linkup ports */ - tmp = readl(&(port_mmio->ssts)); + tmp = readl(&port_mmio->ssts); debug("Port %d status: 0x%x\n", i, tmp); if ((tmp & SATA_PORT_SSTS_DET_MASK) == 0x03) - probe_ent->link_port_map |= (0x01 << i); + uc_priv->link_port_map |= (0x01 << i); } - tmp = readl(&(host_mmio->ghc)); + tmp = readl(&host_mmio->ghc); debug("GHC 0x%x\n", tmp); - writel(tmp | SATA_HOST_GHC_IE, &(host_mmio->ghc)); - tmp = readl(&(host_mmio->ghc)); + writel(tmp | SATA_HOST_GHC_IE, &host_mmio->ghc); + tmp = readl(&host_mmio->ghc); debug("GHC 0x%x\n", tmp); return 0; } -static void ahci_print_info(struct ahci_uc_priv *probe_ent) +static void ahci_print_info(struct ahci_uc_priv *uc_priv) { - struct sata_host_regs *host_mmio = - (struct sata_host_regs *)probe_ent->mmio_base; + struct sata_host_regs *host_mmio = uc_priv->mmio_base; u32 vers, cap, impl, speed; const char *speed_s; const char *scc_s; - vers = readl(&(host_mmio->vs)); - cap = probe_ent->cap; - impl = probe_ent->port_map; + vers = readl(&host_mmio->vs); + cap = uc_priv->cap; + impl = uc_priv->port_map; speed = (cap & SATA_HOST_CAP_ISS_MASK) >> SATA_HOST_CAP_ISS_OFFSET; @@ -328,43 +319,10 @@ static void ahci_print_info(struct ahci_uc_priv *probe_ent) cap & (1 << 13) ? "part " : ""); } -static int ahci_init_one(int pdev) -{ - int rc; - struct ahci_uc_priv *probe_ent = NULL; - - probe_ent = malloc(sizeof(struct ahci_uc_priv)); - memset(probe_ent, 0, sizeof(struct ahci_uc_priv)); - probe_ent->dev = pdev; - - probe_ent->host_flags = ATA_FLAG_SATA - | ATA_FLAG_NO_LEGACY - | ATA_FLAG_MMIO - | ATA_FLAG_PIO_DMA - | ATA_FLAG_NO_ATAPI; - - probe_ent->mmio_base = (void __iomem *)CONFIG_DWC_AHSATA_BASE_ADDR; - - /* initialize adapter */ - rc = ahci_host_init(probe_ent); - if (rc) - goto err_out; - - ahci_print_info(probe_ent); - - /* Save the private struct to block device struct */ - sata_dev_desc[pdev].priv = (void *)probe_ent; - - return 0; - -err_out: - return rc; -} - -static int ahci_fill_sg(struct ahci_uc_priv *probe_ent, - u8 port, unsigned char *buf, int buf_len) +static int ahci_fill_sg(struct ahci_uc_priv *uc_priv, u8 port, + unsigned char *buf, int buf_len) { - struct ahci_ioports *pp = &(probe_ent->port[port]); + struct ahci_ioports *pp = &uc_priv->port[port]; struct ahci_sg *ahci_sg = pp->cmd_tbl_sg; u32 sg_count, max_bytes; int i; @@ -408,17 +366,16 @@ static void ahci_fill_cmd_slot(struct ahci_ioports *pp, u32 cmd_slot, u32 opts) #define AHCI_GET_CMD_SLOT(c) ((c) ? ffs(c) : 0) -static int ahci_exec_ata_cmd(struct ahci_uc_priv *probe_ent, - u8 port, struct sata_fis_h2d *cfis, - u8 *buf, u32 buf_len, s32 is_write) +static int ahci_exec_ata_cmd(struct ahci_uc_priv *uc_priv, u8 port, + struct sata_fis_h2d *cfis, u8 *buf, u32 buf_len, + s32 is_write) { - struct ahci_ioports *pp = &(probe_ent->port[port]); - struct sata_port_regs *port_mmio = - (struct sata_port_regs *)pp->port_mmio; + struct ahci_ioports *pp = &uc_priv->port[port]; + struct sata_port_regs *port_mmio = pp->port_mmio; u32 opts; int sg_count = 0, cmd_slot = 0; - cmd_slot = AHCI_GET_CMD_SLOT(readl(&(port_mmio->ci))); + cmd_slot = AHCI_GET_CMD_SLOT(readl(&port_mmio->ci)); if (32 == cmd_slot) { printf("Can't find empty command slot!\n"); return 0; @@ -433,7 +390,7 @@ static int ahci_exec_ata_cmd(struct ahci_uc_priv *probe_ent, memcpy((u8 *)(pp->cmd_tbl), cfis, sizeof(struct sata_fis_h2d)); if (buf && buf_len) - sg_count = ahci_fill_sg(probe_ent, port, buf, buf_len); + sg_count = ahci_fill_sg(uc_priv, port, buf, buf_len); opts = (sizeof(struct sata_fis_h2d) >> 2) | (sg_count << 16); if (is_write) { opts |= 0x40; @@ -442,10 +399,10 @@ static int ahci_exec_ata_cmd(struct ahci_uc_priv *probe_ent, ahci_fill_cmd_slot(pp, cmd_slot, opts); flush_cache((int)(pp->cmd_slot), AHCI_PORT_PRIV_DMA_SZ); - writel_with_flush(1 << cmd_slot, &(port_mmio->ci)); + writel_with_flush(1 << cmd_slot, &port_mmio->ci); - if (waiting_for_cmd_completed((u8 *)&(port_mmio->ci), - 10000, 0x1 << cmd_slot)) { + if (waiting_for_cmd_completed((u8 *)&port_mmio->ci, 10000, + 0x1 << cmd_slot)) { printf("timeout exit!\n"); return -1; } @@ -459,10 +416,8 @@ static int ahci_exec_ata_cmd(struct ahci_uc_priv *probe_ent, return buf_len; } -static void ahci_set_feature(u8 dev, u8 port) +static void ahci_set_feature(struct ahci_uc_priv *uc_priv, u8 port) { - struct ahci_uc_priv *probe_ent = - (struct ahci_uc_priv *)sata_dev_desc[dev].priv; struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN); struct sata_fis_h2d *cfis = &h2d; @@ -471,23 +426,21 @@ static void ahci_set_feature(u8 dev, u8 port) cfis->pm_port_c = 1 << 7; cfis->command = ATA_CMD_SET_FEATURES; cfis->features = SETFEATURES_XFER; - cfis->sector_count = ffs(probe_ent->udma_mask + 1) + 0x3e; + cfis->sector_count = ffs(uc_priv->udma_mask + 1) + 0x3e; - ahci_exec_ata_cmd(probe_ent, port, cfis, NULL, 0, READ_CMD); + ahci_exec_ata_cmd(uc_priv, port, cfis, NULL, 0, READ_CMD); } -static int ahci_port_start(struct ahci_uc_priv *probe_ent, - u8 port) +static int ahci_port_start(struct ahci_uc_priv *uc_priv, u8 port) { - struct ahci_ioports *pp = &(probe_ent->port[port]); - struct sata_port_regs *port_mmio = - (struct sata_port_regs *)pp->port_mmio; + struct ahci_ioports *pp = &uc_priv->port[port]; + struct sata_port_regs *port_mmio = pp->port_mmio; u32 port_status; u32 mem; int timeout = 10000000; debug("Enter start port: %d\n", port); - port_status = readl(&(port_mmio->ssts)); + port_status = readl(&port_mmio->ssts); debug("Port %d status: %x\n", port, port_status); if ((port_status & 0xf) != 0x03) { printf("No Link on this port!\n"); @@ -527,17 +480,17 @@ static int ahci_port_start(struct ahci_uc_priv *probe_ent, mem += AHCI_CMD_TBL_HDR; - writel_with_flush(0x00004444, &(port_mmio->dmacr)); + writel_with_flush(0x00004444, &port_mmio->dmacr); pp->cmd_tbl_sg = (struct ahci_sg *)mem; - writel_with_flush((u32)pp->cmd_slot, &(port_mmio->clb)); - writel_with_flush(pp->rx_fis, &(port_mmio->fb)); + writel_with_flush((u32)pp->cmd_slot, &port_mmio->clb); + writel_with_flush(pp->rx_fis, &port_mmio->fb); /* Enable FRE */ - writel_with_flush((SATA_PORT_CMD_FRE | readl(&(port_mmio->cmd))), - &(port_mmio->cmd)); + writel_with_flush((SATA_PORT_CMD_FRE | readl(&port_mmio->cmd)), + &port_mmio->cmd); /* Wait device ready */ - while ((readl(&(port_mmio->tfd)) & (SATA_PORT_TFD_STS_ERR | + while ((readl(&port_mmio->tfd) & (SATA_PORT_TFD_STS_ERR | SATA_PORT_TFD_STS_DRQ | SATA_PORT_TFD_STS_BSY)) && --timeout) ; @@ -549,79 +502,15 @@ static int ahci_port_start(struct ahci_uc_priv *probe_ent, writel_with_flush(PORT_CMD_ICC_ACTIVE | PORT_CMD_FIS_RX | PORT_CMD_POWER_ON | PORT_CMD_SPIN_UP | - PORT_CMD_START, &(port_mmio->cmd)); + PORT_CMD_START, &port_mmio->cmd); debug("Exit start port %d\n", port); return 0; } -int init_sata(int dev) -{ - int i; - u32 linkmap; - struct ahci_uc_priv *probe_ent = NULL; - -#if defined(CONFIG_MX6) - if (!is_mx6dq() && !is_mx6dqp()) - return 1; -#endif - if (dev < 0 || dev > (CONFIG_SYS_SATA_MAX_DEVICE - 1)) { - printf("The sata index %d is out of ranges\n\r", dev); - return -1; - } - - ahci_init_one(dev); - - probe_ent = (struct ahci_uc_priv *)sata_dev_desc[dev].priv; - linkmap = probe_ent->link_port_map; - - if (0 == linkmap) { - printf("No port device detected!\n"); - return 1; - } - - for (i = 0; i < probe_ent->n_ports; i++) { - if ((linkmap >> i) && ((linkmap >> i) & 0x01)) { - if (ahci_port_start(probe_ent, (u8)i)) { - printf("Can not start port %d\n", i); - return 1; - } - probe_ent->hard_port_no = i; - break; - } - } - - return 0; -} - -int reset_sata(int dev) -{ - struct ahci_uc_priv *probe_ent; - struct sata_host_regs *host_mmio; - - if (dev < 0 || dev > (CONFIG_SYS_SATA_MAX_DEVICE - 1)) { - printf("The sata index %d is out of ranges\n\r", dev); - return -1; - } - - probe_ent = (struct ahci_uc_priv *)sata_dev_desc[dev].priv; - if (NULL == probe_ent) - /* not initialized, so nothing to reset */ - return 0; - - host_mmio = (struct sata_host_regs *)probe_ent->mmio_base; - setbits_le32(&host_mmio->ghc, SATA_HOST_GHC_HR); - while (readl(&host_mmio->ghc) & SATA_HOST_GHC_HR) - udelay(100); - - return 0; -} - -static void dwc_ahsata_print_info(int dev) +static void dwc_ahsata_print_info(struct blk_desc *pdev) { - struct blk_desc *pdev = &(sata_dev_desc[dev]); - printf("SATA Device Info:\n\r"); #ifdef CONFIG_SYS_64BIT_LBA printf("S/N: %s\n\rProduct model number: %s\n\r" @@ -634,13 +523,11 @@ static void dwc_ahsata_print_info(int dev) #endif } -static void dwc_ahsata_identify(int dev, u16 *id) +static void dwc_ahsata_identify(struct ahci_uc_priv *uc_priv, u16 *id) { - struct ahci_uc_priv *probe_ent = - (struct ahci_uc_priv *)sata_dev_desc[dev].priv; struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN); struct sata_fis_h2d *cfis = &h2d; - u8 port = probe_ent->hard_port_no; + u8 port = uc_priv->hard_port_no; memset(cfis, 0, sizeof(struct sata_fis_h2d)); @@ -648,30 +535,24 @@ static void dwc_ahsata_identify(int dev, u16 *id) cfis->pm_port_c = 0x80; /* is command */ cfis->command = ATA_CMD_ID_ATA; - ahci_exec_ata_cmd(probe_ent, port, cfis, - (u8 *)id, ATA_ID_WORDS * 2, READ_CMD); + ahci_exec_ata_cmd(uc_priv, port, cfis, (u8 *)id, ATA_ID_WORDS * 2, + READ_CMD); ata_swap_buf_le16(id, ATA_ID_WORDS); } -static void dwc_ahsata_xfer_mode(int dev, u16 *id) +static void dwc_ahsata_xfer_mode(struct ahci_uc_priv *uc_priv, u16 *id) { - struct ahci_uc_priv *probe_ent = - (struct ahci_uc_priv *)sata_dev_desc[dev].priv; - - probe_ent->pio_mask = id[ATA_ID_PIO_MODES]; - probe_ent->udma_mask = id[ATA_ID_UDMA_MODES]; - debug("pio %04x, udma %04x\n\r", - probe_ent->pio_mask, probe_ent->udma_mask); + uc_priv->pio_mask = id[ATA_ID_PIO_MODES]; + uc_priv->udma_mask = id[ATA_ID_UDMA_MODES]; + debug("pio %04x, udma %04x\n\r", uc_priv->pio_mask, uc_priv->udma_mask); } -static u32 dwc_ahsata_rw_cmd(int dev, u32 start, u32 blkcnt, - u8 *buffer, int is_write) +static u32 dwc_ahsata_rw_cmd(struct ahci_uc_priv *uc_priv, u32 start, + u32 blkcnt, u8 *buffer, int is_write) { - struct ahci_uc_priv *probe_ent = - (struct ahci_uc_priv *)sata_dev_desc[dev].priv; struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN); struct sata_fis_h2d *cfis = &h2d; - u8 port = probe_ent->hard_port_no; + u8 port = uc_priv->hard_port_no; u32 block; block = start; @@ -689,20 +570,18 @@ static u32 dwc_ahsata_rw_cmd(int dev, u32 start, u32 blkcnt, cfis->lba_low = block & 0xff; cfis->sector_count = (u8)(blkcnt & 0xff); - if (ahci_exec_ata_cmd(probe_ent, port, cfis, - buffer, ATA_SECT_SIZE * blkcnt, is_write) > 0) + if (ahci_exec_ata_cmd(uc_priv, port, cfis, buffer, + ATA_SECT_SIZE * blkcnt, is_write) > 0) return blkcnt; else return 0; } -void dwc_ahsata_flush_cache(int dev) +static void dwc_ahsata_flush_cache(struct ahci_uc_priv *uc_priv) { - struct ahci_uc_priv *probe_ent = - (struct ahci_uc_priv *)sata_dev_desc[dev].priv; struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN); struct sata_fis_h2d *cfis = &h2d; - u8 port = probe_ent->hard_port_no; + u8 port = uc_priv->hard_port_no; memset(cfis, 0, sizeof(struct sata_fis_h2d)); @@ -710,17 +589,15 @@ void dwc_ahsata_flush_cache(int dev) cfis->pm_port_c = 0x80; /* is command */ cfis->command = ATA_CMD_FLUSH; - ahci_exec_ata_cmd(probe_ent, port, cfis, NULL, 0, 0); + ahci_exec_ata_cmd(uc_priv, port, cfis, NULL, 0, 0); } -static u32 dwc_ahsata_rw_cmd_ext(int dev, u32 start, lbaint_t blkcnt, - u8 *buffer, int is_write) +static u32 dwc_ahsata_rw_cmd_ext(struct ahci_uc_priv *uc_priv, u32 start, + lbaint_t blkcnt, u8 *buffer, int is_write) { - struct ahci_uc_priv *probe_ent = - (struct ahci_uc_priv *)sata_dev_desc[dev].priv; struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN); struct sata_fis_h2d *cfis = &h2d; - u8 port = probe_ent->hard_port_no; + u8 port = uc_priv->hard_port_no; u64 block; block = (u64)start; @@ -743,63 +620,18 @@ static u32 dwc_ahsata_rw_cmd_ext(int dev, u32 start, lbaint_t blkcnt, cfis->sector_count_exp = (blkcnt >> 8) & 0xff; cfis->sector_count = blkcnt & 0xff; - if (ahci_exec_ata_cmd(probe_ent, port, cfis, buffer, - ATA_SECT_SIZE * blkcnt, is_write) > 0) + if (ahci_exec_ata_cmd(uc_priv, port, cfis, buffer, + ATA_SECT_SIZE * blkcnt, is_write) > 0) return blkcnt; else return 0; } -u32 dwc_ahsata_rw_ncq_cmd(int dev, u32 start, lbaint_t blkcnt, - u8 *buffer, int is_write) -{ - struct ahci_uc_priv *probe_ent = - (struct ahci_uc_priv *)sata_dev_desc[dev].priv; - struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN); - struct sata_fis_h2d *cfis = &h2d; - u8 port = probe_ent->hard_port_no; - u64 block; - - if (sata_dev_desc[dev].lba48 != 1) { - printf("execute FPDMA command on non-LBA48 hard disk\n\r"); - return -1; - } - - block = (u64)start; - - memset(cfis, 0, sizeof(struct sata_fis_h2d)); - - cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D; - cfis->pm_port_c = 0x80; /* is command */ - - cfis->command = (is_write) ? ATA_CMD_FPDMA_WRITE - : ATA_CMD_FPDMA_READ; - - cfis->lba_high_exp = (block >> 40) & 0xff; - cfis->lba_mid_exp = (block >> 32) & 0xff; - cfis->lba_low_exp = (block >> 24) & 0xff; - cfis->lba_high = (block >> 16) & 0xff; - cfis->lba_mid = (block >> 8) & 0xff; - cfis->lba_low = block & 0xff; - - cfis->device = ATA_LBA; - cfis->features_exp = (blkcnt >> 8) & 0xff; - cfis->features = blkcnt & 0xff; - - /* Use the latest queue */ - ahci_exec_ata_cmd(probe_ent, port, cfis, - buffer, ATA_SECT_SIZE * blkcnt, is_write); - - return blkcnt; -} - -void dwc_ahsata_flush_cache_ext(int dev) +static void dwc_ahsata_flush_cache_ext(struct ahci_uc_priv *uc_priv) { - struct ahci_uc_priv *probe_ent = - (struct ahci_uc_priv *)sata_dev_desc[dev].priv; struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN); struct sata_fis_h2d *cfis = &h2d; - u8 port = probe_ent->hard_port_no; + u8 port = uc_priv->hard_port_no; memset(cfis, 0, sizeof(struct sata_fis_h2d)); @@ -807,24 +639,22 @@ void dwc_ahsata_flush_cache_ext(int dev) cfis->pm_port_c = 0x80; /* is command */ cfis->command = ATA_CMD_FLUSH_EXT; - ahci_exec_ata_cmd(probe_ent, port, cfis, NULL, 0, 0); + ahci_exec_ata_cmd(uc_priv, port, cfis, NULL, 0, 0); } -static void dwc_ahsata_init_wcache(int dev, u16 *id) +static void dwc_ahsata_init_wcache(struct ahci_uc_priv *uc_priv, u16 *id) { - struct ahci_uc_priv *probe_ent = - (struct ahci_uc_priv *)sata_dev_desc[dev].priv; - if (ata_id_has_wcache(id) && ata_id_wcache_enabled(id)) - probe_ent->flags |= SATA_FLAG_WCACHE; + uc_priv->flags |= SATA_FLAG_WCACHE; if (ata_id_has_flush(id)) - probe_ent->flags |= SATA_FLAG_FLUSH; + uc_priv->flags |= SATA_FLAG_FLUSH; if (ata_id_has_flush_ext(id)) - probe_ent->flags |= SATA_FLAG_FLUSH_EXT; + uc_priv->flags |= SATA_FLAG_FLUSH_EXT; } -u32 ata_low_level_rw_lba48(int dev, u32 blknr, lbaint_t blkcnt, - const void *buffer, int is_write) +static u32 ata_low_level_rw_lba48(struct ahci_uc_priv *uc_priv, u32 blknr, + lbaint_t blkcnt, const void *buffer, + int is_write) { u32 start, blks; u8 *addr; @@ -838,15 +668,16 @@ u32 ata_low_level_rw_lba48(int dev, u32 blknr, lbaint_t blkcnt, do { if (blks > max_blks) { - if (max_blks != dwc_ahsata_rw_cmd_ext(dev, start, - max_blks, addr, is_write)) + if (max_blks != dwc_ahsata_rw_cmd_ext(uc_priv, start, + max_blks, addr, + is_write)) return 0; start += max_blks; blks -= max_blks; addr += ATA_SECT_SIZE * max_blks; } else { - if (blks != dwc_ahsata_rw_cmd_ext(dev, start, - blks, addr, is_write)) + if (blks != dwc_ahsata_rw_cmd_ext(uc_priv, start, blks, + addr, is_write)) return 0; start += blks; blks = 0; @@ -857,8 +688,9 @@ u32 ata_low_level_rw_lba48(int dev, u32 blknr, lbaint_t blkcnt, return blkcnt; } -u32 ata_low_level_rw_lba28(int dev, u32 blknr, lbaint_t blkcnt, - const void *buffer, int is_write) +static u32 ata_low_level_rw_lba28(struct ahci_uc_priv *uc_priv, u32 blknr, + lbaint_t blkcnt, const void *buffer, + int is_write) { u32 start, blks; u8 *addr; @@ -871,15 +703,16 @@ u32 ata_low_level_rw_lba28(int dev, u32 blknr, lbaint_t blkcnt, max_blks = ATA_MAX_SECTORS; do { if (blks > max_blks) { - if (max_blks != dwc_ahsata_rw_cmd(dev, start, - max_blks, addr, is_write)) + if (max_blks != dwc_ahsata_rw_cmd(uc_priv, start, + max_blks, addr, + is_write)) return 0; start += max_blks; blks -= max_blks; addr += ATA_SECT_SIZE * max_blks; } else { - if (blks != dwc_ahsata_rw_cmd(dev, start, - blks, addr, is_write)) + if (blks != dwc_ahsata_rw_cmd(uc_priv, start, blks, + addr, is_write)) return 0; start += blks; blks = 0; @@ -890,84 +723,44 @@ u32 ata_low_level_rw_lba28(int dev, u32 blknr, lbaint_t blkcnt, return blkcnt; } -int sata_port_status(int dev, int port) +static int dwc_ahci_start_ports(struct ahci_uc_priv *uc_priv) { - struct sata_port_regs *port_mmio; - struct ahci_uc_priv *probe_ent = NULL; - - if (dev < 0 || dev > (CONFIG_SYS_SATA_MAX_DEVICE - 1)) - return -EINVAL; - - if (sata_dev_desc[dev].priv == NULL) - return -ENODEV; + u32 linkmap; + int i; - probe_ent = (struct ahci_uc_priv *)sata_dev_desc[dev].priv; - port_mmio = (struct sata_port_regs *)probe_ent->port[port].port_mmio; + linkmap = uc_priv->link_port_map; - return readl(&(port_mmio->ssts)) & SATA_PORT_SSTS_DET_MASK; -} + if (0 == linkmap) { + printf("No port device detected!\n"); + return -ENXIO; + } -/* - * SATA interface between low level driver and command layer - */ -ulong sata_read(int dev, ulong blknr, lbaint_t blkcnt, void *buffer) -{ - u32 rc; + for (i = 0; i < uc_priv->n_ports; i++) { + if ((linkmap >> i) && ((linkmap >> i) & 0x01)) { + if (ahci_port_start(uc_priv, (u8)i)) { + printf("Can not start port %d\n", i); + return 1; + } + uc_priv->hard_port_no = i; + break; + } + } - if (sata_dev_desc[dev].lba48) - rc = ata_low_level_rw_lba48(dev, blknr, blkcnt, - buffer, READ_CMD); - else - rc = ata_low_level_rw_lba28(dev, blknr, blkcnt, - buffer, READ_CMD); - return rc; + return 0; } -ulong sata_write(int dev, ulong blknr, lbaint_t blkcnt, const void *buffer) -{ - u32 rc; - struct ahci_uc_priv *probe_ent = - (struct ahci_uc_priv *)sata_dev_desc[dev].priv; - u32 flags = probe_ent->flags; - - if (sata_dev_desc[dev].lba48) { - rc = ata_low_level_rw_lba48(dev, blknr, blkcnt, - buffer, WRITE_CMD); - if ((flags & SATA_FLAG_WCACHE) && - (flags & SATA_FLAG_FLUSH_EXT)) - dwc_ahsata_flush_cache_ext(dev); - } else { - rc = ata_low_level_rw_lba28(dev, blknr, blkcnt, - buffer, WRITE_CMD); - if ((flags & SATA_FLAG_WCACHE) && - (flags & SATA_FLAG_FLUSH)) - dwc_ahsata_flush_cache(dev); - } - return rc; -} - -int scan_sata(int dev) +static int dwc_ahsata_scan_common(struct ahci_uc_priv *uc_priv, + struct blk_desc *pdev) { u8 serial[ATA_ID_SERNO_LEN + 1] = { 0 }; u8 firmware[ATA_ID_FW_REV_LEN + 1] = { 0 }; u8 product[ATA_ID_PROD_LEN + 1] = { 0 }; - u16 *id; u64 n_sectors; - struct ahci_uc_priv *probe_ent = - (struct ahci_uc_priv *)sata_dev_desc[dev].priv; - u8 port = probe_ent->hard_port_no; - struct blk_desc *pdev = &(sata_dev_desc[dev]); - - id = (u16 *)memalign(ARCH_DMA_MINALIGN, - roundup(ARCH_DMA_MINALIGN, - (ATA_ID_WORDS * 2))); - if (!id) { - printf("id malloc failed\n\r"); - return -1; - } + u8 port = uc_priv->hard_port_no; + ALLOC_CACHE_ALIGN_BUFFER(u16, id, ATA_ID_WORDS); /* Identify device to get information */ - dwc_ahsata_identify(dev, id); + dwc_ahsata_identify(uc_priv, id); /* Serial number */ ata_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial)); @@ -987,7 +780,7 @@ int scan_sata(int dev) pdev->type = DEV_TYPE_HARDDISK; pdev->blksz = ATA_SECT_SIZE; - pdev->lun = 0 ; + pdev->lun = 0; /* Check if support LBA48 */ if (ata_id_has_lba48(id)) { @@ -996,23 +789,291 @@ int scan_sata(int dev) } /* Get the NCQ queue depth from device */ - probe_ent->flags &= (~SATA_FLAG_Q_DEP_MASK); - probe_ent->flags |= ata_id_queue_depth(id); + uc_priv->flags &= (~SATA_FLAG_Q_DEP_MASK); + uc_priv->flags |= ata_id_queue_depth(id); /* Get the xfer mode from device */ - dwc_ahsata_xfer_mode(dev, id); + dwc_ahsata_xfer_mode(uc_priv, id); /* Get the write cache status from device */ - dwc_ahsata_init_wcache(dev, id); + dwc_ahsata_init_wcache(uc_priv, id); /* Set the xfer mode to highest speed */ - ahci_set_feature(dev, port); + ahci_set_feature(uc_priv, port); + + dwc_ahsata_print_info(pdev); + + return 0; +} + +/* + * SATA interface between low level driver and command layer + */ +static ulong sata_read_common(struct ahci_uc_priv *uc_priv, + struct blk_desc *desc, ulong blknr, + lbaint_t blkcnt, void *buffer) +{ + u32 rc; + + if (desc->lba48) + rc = ata_low_level_rw_lba48(uc_priv, blknr, blkcnt, buffer, + READ_CMD); + else + rc = ata_low_level_rw_lba28(uc_priv, blknr, blkcnt, buffer, + READ_CMD); + + return rc; +} + +static ulong sata_write_common(struct ahci_uc_priv *uc_priv, + struct blk_desc *desc, ulong blknr, + lbaint_t blkcnt, const void *buffer) +{ + u32 rc; + u32 flags = uc_priv->flags; + + if (desc->lba48) { + rc = ata_low_level_rw_lba48(uc_priv, blknr, blkcnt, buffer, + WRITE_CMD); + if ((flags & SATA_FLAG_WCACHE) && (flags & SATA_FLAG_FLUSH_EXT)) + dwc_ahsata_flush_cache_ext(uc_priv); + } else { + rc = ata_low_level_rw_lba28(uc_priv, blknr, blkcnt, buffer, + WRITE_CMD); + if ((flags & SATA_FLAG_WCACHE) && (flags & SATA_FLAG_FLUSH)) + dwc_ahsata_flush_cache(uc_priv); + } + + return rc; +} + +#if !CONFIG_IS_ENABLED(AHCI) +static int ahci_init_one(int pdev) +{ + int rc; + struct ahci_uc_priv *uc_priv = NULL; + + uc_priv = malloc(sizeof(struct ahci_uc_priv)); + memset(uc_priv, 0, sizeof(struct ahci_uc_priv)); + uc_priv->dev = pdev; + + uc_priv->host_flags = ATA_FLAG_SATA + | ATA_FLAG_NO_LEGACY + | ATA_FLAG_MMIO + | ATA_FLAG_PIO_DMA + | ATA_FLAG_NO_ATAPI; + + uc_priv->mmio_base = (void __iomem *)CONFIG_DWC_AHSATA_BASE_ADDR; + + /* initialize adapter */ + rc = ahci_host_init(uc_priv); + if (rc) + goto err_out; + + ahci_print_info(uc_priv); + + /* Save the uc_private struct to block device struct */ + sata_dev_desc[pdev].priv = uc_priv; + + return 0; + +err_out: + return rc; +} + +int init_sata(int dev) +{ + struct ahci_uc_priv *uc_priv = NULL; + +#if defined(CONFIG_MX6) + if (!is_mx6dq() && !is_mx6dqp()) + return 1; +#endif + if (dev < 0 || dev > (CONFIG_SYS_SATA_MAX_DEVICE - 1)) { + printf("The sata index %d is out of ranges\n\r", dev); + return -1; + } + + ahci_init_one(dev); + + uc_priv = sata_dev_desc[dev].priv; + + return dwc_ahci_start_ports(uc_priv) ? 1 : 0; +} + +int reset_sata(int dev) +{ + struct ahci_uc_priv *uc_priv; + struct sata_host_regs *host_mmio; - free((void *)id); + if (dev < 0 || dev > (CONFIG_SYS_SATA_MAX_DEVICE - 1)) { + printf("The sata index %d is out of ranges\n\r", dev); + return -1; + } - dwc_ahsata_print_info(dev); + uc_priv = sata_dev_desc[dev].priv; + if (NULL == uc_priv) + /* not initialized, so nothing to reset */ + return 0; - is_ready = 1; + host_mmio = uc_priv->mmio_base; + setbits_le32(&host_mmio->ghc, SATA_HOST_GHC_HR); + while (readl(&host_mmio->ghc) & SATA_HOST_GHC_HR) + udelay(100); return 0; } + +int sata_port_status(int dev, int port) +{ + struct sata_port_regs *port_mmio; + struct ahci_uc_priv *uc_priv = NULL; + + if (dev < 0 || dev > (CONFIG_SYS_SATA_MAX_DEVICE - 1)) + return -EINVAL; + + if (sata_dev_desc[dev].priv == NULL) + return -ENODEV; + + uc_priv = sata_dev_desc[dev].priv; + port_mmio = uc_priv->port[port].port_mmio; + + return readl(&port_mmio->ssts) & SATA_PORT_SSTS_DET_MASK; +} + +/* + * SATA interface between low level driver and command layer + */ +ulong sata_read(int dev, ulong blknr, lbaint_t blkcnt, void *buffer) +{ + struct ahci_uc_priv *uc_priv = sata_dev_desc[dev].priv; + + return sata_read_common(uc_priv, &sata_dev_desc[dev], blknr, blkcnt, + buffer); +} + +ulong sata_write(int dev, ulong blknr, lbaint_t blkcnt, const void *buffer) +{ + struct ahci_uc_priv *uc_priv = sata_dev_desc[dev].priv; + + return sata_write_common(uc_priv, &sata_dev_desc[dev], blknr, blkcnt, + buffer); +} + +int scan_sata(int dev) +{ + struct ahci_uc_priv *uc_priv = sata_dev_desc[dev].priv; + struct blk_desc *pdev = &sata_dev_desc[dev]; + + return dwc_ahsata_scan_common(uc_priv, pdev); +} +#endif /* CONFIG_IS_ENABLED(AHCI) */ + +#if CONFIG_IS_ENABLED(AHCI) + +int dwc_ahsata_port_status(struct udevice *dev, int port) +{ + struct ahci_uc_priv *uc_priv = dev_get_uclass_priv(dev); + struct sata_port_regs *port_mmio; + + port_mmio = uc_priv->port[port].port_mmio; + return readl(&port_mmio->ssts) & SATA_PORT_SSTS_DET_MASK ? 0 : -ENXIO; +} + +int dwc_ahsata_bus_reset(struct udevice *dev) +{ + struct ahci_uc_priv *uc_priv = dev_get_uclass_priv(dev); + struct sata_host_regs *host_mmio = uc_priv->mmio_base; + + setbits_le32(&host_mmio->ghc, SATA_HOST_GHC_HR); + while (readl(&host_mmio->ghc) & SATA_HOST_GHC_HR) + udelay(100); + + return 0; +} + +int dwc_ahsata_scan(struct udevice *dev) +{ + struct ahci_uc_priv *uc_priv = dev_get_uclass_priv(dev); + struct blk_desc *desc; + struct udevice *blk; + int ret; + + /* + * Create only one block device and do detection + * to make sure that there won't be a lot of + * block devices created + */ + device_find_first_child(dev, &blk); + if (!blk) { + ret = blk_create_devicef(dev, "dwc_ahsata_blk", "blk", + IF_TYPE_SATA, -1, 512, 0, &blk); + if (ret) { + debug("Can't create device\n"); + return ret; + } + } + + desc = dev_get_uclass_platdata(blk); + ret = dwc_ahsata_scan_common(uc_priv, desc); + if (ret) { + debug("%s: Failed to scan bus\n", __func__); + return ret; + } + + return 0; +} + +int dwc_ahsata_probe(struct udevice *dev) +{ + struct ahci_uc_priv *uc_priv = dev_get_uclass_priv(dev); + int ret; + + uc_priv->host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | + ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | ATA_FLAG_NO_ATAPI; + uc_priv->mmio_base = (void __iomem *)dev_read_addr(dev); + + /* initialize adapter */ + ret = ahci_host_init(uc_priv); + if (ret) + return ret; + + ahci_print_info(uc_priv); + + return dwc_ahci_start_ports(uc_priv); +} + +static ulong dwc_ahsata_read(struct udevice *blk, lbaint_t blknr, + lbaint_t blkcnt, void *buffer) +{ + struct blk_desc *desc = dev_get_uclass_platdata(blk); + struct udevice *dev = dev_get_parent(blk); + struct ahci_uc_priv *uc_priv; + + uc_priv = dev_get_uclass_priv(dev); + return sata_read_common(uc_priv, desc, blknr, blkcnt, buffer); +} + +static ulong dwc_ahsata_write(struct udevice *blk, lbaint_t blknr, + lbaint_t blkcnt, const void *buffer) +{ + struct blk_desc *desc = dev_get_uclass_platdata(blk); + struct udevice *dev = dev_get_parent(blk); + struct ahci_uc_priv *uc_priv; + + uc_priv = dev_get_uclass_priv(dev); + return sata_write_common(uc_priv, desc, blknr, blkcnt, buffer); +} + +static const struct blk_ops dwc_ahsata_blk_ops = { + .read = dwc_ahsata_read, + .write = dwc_ahsata_write, +}; + +U_BOOT_DRIVER(dwc_ahsata_blk) = { + .name = "dwc_ahsata_blk", + .id = UCLASS_BLK, + .ops = &dwc_ahsata_blk_ops, +}; + +#endif diff --git a/drivers/ata/dwc_ahsata.h b/drivers/ata/dwc_ahsata_priv.h index caa2e501f96..6089c0b268d 100644 --- a/drivers/ata/dwc_ahsata.h +++ b/drivers/ata/dwc_ahsata_priv.h @@ -5,8 +5,8 @@ * SPDX-License-Identifier: GPL-2.0+ */ -#ifndef __FSL_SATA_H__ -#define __FSL_SATA_H__ +#ifndef __DWC_AHSATA_PRIV_H__ +#define __DWC_AHSATA_PRIV_H__ #define DWC_AHSATA_MAX_CMD_SLOTS 32 @@ -317,4 +317,4 @@ #define READ_CMD 0 #define WRITE_CMD 1 -#endif /* __FSL_SATA_H__ */ +#endif /* __DWC_AHSATA_H__ */ diff --git a/drivers/ata/sata.c b/drivers/ata/sata.c index 42ff5c7755a..b3ebc05ead3 100644 --- a/drivers/ata/sata.c +++ b/drivers/ata/sata.c @@ -11,17 +11,52 @@ */ #include <common.h> +#include <ahci.h> #include <dm.h> #include <sata.h> +#ifndef CONFIG_AHCI struct blk_desc sata_dev_desc[CONFIG_SYS_SATA_MAX_DEVICE]; +#endif + +int sata_reset(struct udevice *dev) +{ + struct ahci_ops *ops = ahci_get_ops(dev); + + if (!ops->reset) + return -ENOSYS; + + return ops->reset(dev); +} + +int sata_dm_port_status(struct udevice *dev, int port) +{ + struct ahci_ops *ops = ahci_get_ops(dev); + + if (!ops->port_status) + return -ENOSYS; + return ops->port_status(dev, port); +} + +int sata_scan(struct udevice *dev) +{ + struct ahci_ops *ops = ahci_get_ops(dev); + + if (!ops->scan) + return -ENOSYS; + + return ops->scan(dev); +} + +#ifndef CONFIG_AHCI #ifdef CONFIG_PARTITIONS struct blk_desc *sata_get_dev(int dev) { return (dev < CONFIG_SYS_SATA_MAX_DEVICE) ? &sata_dev_desc[dev] : NULL; } #endif +#endif #ifdef CONFIG_BLK static unsigned long sata_bread(struct udevice *dev, lbaint_t start, @@ -49,6 +84,7 @@ static unsigned long sata_bwrite(struct blk_desc *block_dev, lbaint_t start, } #endif +#ifndef CONFIG_AHCI int __sata_initialize(void) { int rc, ret = -1; @@ -95,6 +131,7 @@ __weak int __sata_stop(void) return err; } int sata_stop(void) __attribute__((weak, alias("__sata_stop"))); +#endif #ifdef CONFIG_BLK static const struct blk_ops sata_blk_ops = { diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c index a3737badec6..3aec569d124 100644 --- a/drivers/block/blk-uclass.c +++ b/drivers/block/blk-uclass.c @@ -57,6 +57,11 @@ static enum uclass_id if_type_to_uclass_id(enum if_type if_type) return if_type_uclass_id[if_type]; } +const char *blk_get_if_type_name(enum if_type if_type) +{ + return if_typename_str[if_type]; +} + struct blk_desc *blk_get_devnum_by_type(enum if_type if_type, int devnum) { struct blk_desc *desc; @@ -591,7 +596,7 @@ int blk_create_devicef(struct udevice *parent, const char *drv_name, } device_set_name_alloced(*devp); - return ret; + return 0; } int blk_unbind_all(int if_type) diff --git a/drivers/block/blk_legacy.c b/drivers/block/blk_legacy.c index 7b90a8a6e18..981872ecb35 100644 --- a/drivers/block/blk_legacy.c +++ b/drivers/block/blk_legacy.c @@ -38,6 +38,13 @@ static struct blk_driver *blk_driver_lookup_typename(const char *if_typename) return NULL; } +const char *blk_get_if_type_name(enum if_type if_type) +{ + struct blk_driver *drv = blk_driver_lookup_type(if_type); + + return drv ? drv->if_typename : NULL; +} + /** * get_desc() - Get the block device descriptor for the given device number * diff --git a/drivers/core/syscon-uclass.c b/drivers/core/syscon-uclass.c index 2148469abc1..a69937e63c1 100644 --- a/drivers/core/syscon-uclass.c +++ b/drivers/core/syscon-uclass.c @@ -104,5 +104,8 @@ static const struct udevice_id generic_syscon_ids[] = { U_BOOT_DRIVER(generic_syscon) = { .name = "syscon", .id = UCLASS_SYSCON, +#if !CONFIG_IS_ENABLED(OF_PLATDATA) + .bind = dm_scan_fdt_dev, +#endif .of_match = generic_syscon_ids, }; diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 51a87cdd77d..56c352e72a0 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -20,16 +20,6 @@ config DM_MMC appear as block devices in U-Boot and can support filesystems such as EXT4 and FAT. -config DM_MMC_OPS - bool "Support MMC controller operations using Driver Model" - depends on DM_MMC - default y if DM_MMC - help - Driver model provides a means of supporting device operations. This - option moves MMC operations under the control of driver model. The - option will be removed as soon as all DM_MMC drivers use it, as it - will the only supported behaviour. - config SPL_DM_MMC bool "Enable MMC controllers using Driver Model in SPL" depends on SPL_DM && DM_MMC @@ -41,16 +31,6 @@ config SPL_DM_MMC appear as block devices in U-Boot and can support filesystems such as EXT4 and FAT. -config SPL_DM_MMC_OPS - bool "Support MMC controller operations using Driver Model in SPL" - depends on SPL_DM && DM_MMC_OPS - default y - help - Driver model provides a means of supporting device operations. This - option moves MMC operations under the control of driver model. The - option will be removed as soon as all DM_MMC drivers use it, as it - will the only supported behaviour. - if MMC config SPL_MMC_TINY @@ -124,7 +104,7 @@ config MMC_DW_SOCFPGA config MMC_MESON_GX bool "Meson GX EMMC controller support" - depends on DM_MMC && BLK && DM_MMC_OPS && ARCH_MESON + depends on DM_MMC && BLK && ARCH_MESON help Support for EMMC host controller on Meson GX ARM SoCs platform (S905) @@ -155,7 +135,7 @@ config MMC_PCI config MMC_OMAP_HS bool "TI OMAP High Speed Multimedia Card Interface support" - select DM_MMC_OPS if DM_MMC + select DM_REGULATOR_PBIAS if DM_MMC && DM_REGULATOR help This selects the TI OMAP High Speed Multimedia card Interface. If you have an omap2plus board with a Multimedia Card slot, @@ -184,7 +164,7 @@ config SH_SDHI config MMC_UNIPHIER bool "UniPhier SD/MMC Host Controller support" depends on ARCH_UNIPHIER - depends on BLK && DM_MMC_OPS + depends on BLK && DM_MMC depends on OF_CONTROL help This selects support for the SD/MMC Host Controller on UniPhier SoCs. @@ -192,7 +172,7 @@ config MMC_UNIPHIER config MMC_SANDBOX bool "Sandbox MMC support" depends on SANDBOX - depends on BLK && DM_MMC_OPS && OF_CONTROL + depends on BLK && DM_MMC && OF_CONTROL help This select a dummy sandbox MMC driver. At present this does nothing other than allow sandbox to be build with MMC support. This @@ -227,7 +207,7 @@ config MMC_SDHCI_SDMA config MMC_SDHCI_ATMEL bool "Atmel SDHCI controller support" depends on ARCH_AT91 - depends on DM_MMC && BLK && DM_MMC_OPS && ARCH_AT91 + depends on DM_MMC && BLK && ARCH_AT91 depends on MMC_SDHCI help This enables support for the Atmel SDHCI controller, which supports @@ -251,7 +231,7 @@ config MMC_SDHCI_BCM2835 config MMC_SDHCI_CADENCE bool "SDHCI support for the Cadence SD/SDIO/eMMC controller" - depends on BLK && DM_MMC_OPS + depends on BLK && DM_MMC depends on MMC_SDHCI depends on OF_CONTROL help @@ -273,7 +253,7 @@ config MMC_SDHCI_KONA config MMC_SDHCI_MSM bool "Qualcomm SDHCI controller" - depends on BLK && DM_MMC_OPS + depends on BLK && DM_MMC depends on MMC_SDHCI help Enables support for SDHCI 2.0 controller present on some Qualcomm @@ -303,7 +283,7 @@ config MMC_SDHCI_PIC32 config MMC_SDHCI_ROCKCHIP bool "Arasan SDHCI controller for Rockchip support" depends on ARCH_ROCKCHIP - depends on DM_MMC && BLK && DM_MMC_OPS + depends on DM_MMC && BLK depends on MMC_SDHCI help Support for Arasan SDHCI host controller on Rockchip ARM SoCs platform @@ -376,7 +356,7 @@ config MMC_SDHCI_TEGRA config MMC_SDHCI_ZYNQ bool "Arasan SDHCI controller support" depends on ARCH_ZYNQ || ARCH_ZYNQMP - depends on DM_MMC && OF_CONTROL && BLK && DM_MMC_OPS + depends on DM_MMC && OF_CONTROL && BLK depends on MMC_SDHCI help Support for Arasan SDHCI host controller on Zynq/ZynqMP ARM SoCs platform @@ -391,7 +371,7 @@ config MMC_SUNXI config GENERIC_ATMEL_MCI bool "Atmel Multimedia Card Interface support" - depends on DM_MMC && BLK && DM_MMC_OPS && ARCH_AT91 + depends on DM_MMC && BLK && ARCH_AT91 help This enables support for Atmel High Speed Multimedia Card Interface (HSMCI), which supports the MultiMedia Card (MMC) Specification V4.3, diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index 700f7644329..23f642980bf 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -184,7 +184,7 @@ static int dwmci_set_transfer_mode(struct dwmci_host *host, return mode; } -#ifdef CONFIG_DM_MMC_OPS +#ifdef CONFIG_DM_MMC static int dwmci_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, struct mmc_data *data) { @@ -383,7 +383,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq) return 0; } -#ifdef CONFIG_DM_MMC_OPS +#ifdef CONFIG_DM_MMC static int dwmci_set_ios(struct udevice *dev) { struct mmc *mmc = mmc_get_mmc_dev(dev); @@ -466,7 +466,7 @@ static int dwmci_init(struct mmc *mmc) return 0; } -#ifdef CONFIG_DM_MMC_OPS +#ifdef CONFIG_DM_MMC int dwmci_probe(struct udevice *dev) { struct mmc *mmc = mmc_get_mmc_dev(dev); @@ -491,7 +491,7 @@ void dwmci_setup_cfg(struct mmc_config *cfg, struct dwmci_host *host, u32 max_clk, u32 min_clk) { cfg->name = host->name; -#ifndef CONFIG_DM_MMC_OPS +#ifndef CONFIG_DM_MMC cfg->ops = &dwmci_ops; #endif cfg->f_min = min_clk; diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index b69c9b71e4c..cc188c42607 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -81,6 +81,11 @@ struct fsl_esdhc { uint scr; /* eSDHC control register */ }; +struct fsl_esdhc_plat { + struct mmc_config cfg; + struct mmc mmc; +}; + /** * struct fsl_esdhc_priv * @@ -101,8 +106,9 @@ struct fsl_esdhc_priv { struct fsl_esdhc *esdhc_regs; unsigned int sdhc_clk; unsigned int bus_width; - struct mmc_config cfg; +#if !CONFIG_IS_ENABLED(BLK) struct mmc *mmc; +#endif struct udevice *dev; int non_removable; int wp_enable; @@ -156,10 +162,9 @@ static uint esdhc_xfertyp(struct mmc_cmd *cmd, struct mmc_data *data) /* * PIO Read/Write Mode reduce the performace as DMA is not used in this mode. */ -static void -esdhc_pio_read_write(struct mmc *mmc, struct mmc_data *data) +static void esdhc_pio_read_write(struct fsl_esdhc_priv *priv, + struct mmc_data *data) { - struct fsl_esdhc_priv *priv = mmc->priv; struct fsl_esdhc *regs = priv->esdhc_regs; uint blocks; char *buffer; @@ -218,10 +223,10 @@ esdhc_pio_read_write(struct mmc *mmc, struct mmc_data *data) } #endif -static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data) +static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc, + struct mmc_data *data) { int timeout; - struct fsl_esdhc_priv *priv = mmc->priv; struct fsl_esdhc *regs = priv->esdhc_regs; #if defined(CONFIG_FSL_LAYERSCAPE) || defined(CONFIG_S32V234) dma_addr_t addr; @@ -349,13 +354,12 @@ static void check_and_invalidate_dcache_range * Sends a command out on the bus. Takes the mmc pointer, * a command pointer, and an optional data pointer. */ -static int -esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) +static int esdhc_send_cmd_common(struct fsl_esdhc_priv *priv, struct mmc *mmc, + struct mmc_cmd *cmd, struct mmc_data *data) { int err = 0; uint xfertyp; uint irqstat; - struct fsl_esdhc_priv *priv = mmc->priv; struct fsl_esdhc *regs = priv->esdhc_regs; #ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC111 @@ -384,7 +388,7 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) /* Set up for a data transfer if we have one */ if (data) { - err = esdhc_setup_data(mmc, data); + err = esdhc_setup_data(priv, mmc, data); if(err) return err; @@ -470,7 +474,7 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) /* Wait until all of the blocks are transferred */ if (data) { #ifdef CONFIG_SYS_FSL_ESDHC_USE_PIO - esdhc_pio_read_write(mmc, data); + esdhc_pio_read_write(priv, data); #else do { irqstat = esdhc_read32(®s->irqstat); @@ -522,7 +526,7 @@ out: return err; } -static void set_sysctl(struct mmc *mmc, uint clock) +static void set_sysctl(struct fsl_esdhc_priv *priv, struct mmc *mmc, uint clock) { int div = 1; #ifdef ARCH_MXC @@ -531,7 +535,6 @@ static void set_sysctl(struct mmc *mmc, uint clock) int pre_div = 2; #endif int ddr_pre_div = mmc->ddr_mode ? 2 : 1; - struct fsl_esdhc_priv *priv = mmc->priv; struct fsl_esdhc *regs = priv->esdhc_regs; int sdhc_clk = priv->sdhc_clk; uint clk; @@ -569,9 +572,8 @@ static void set_sysctl(struct mmc *mmc, uint clock) } #ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK -static void esdhc_clock_control(struct mmc *mmc, bool enable) +static void esdhc_clock_control(struct fsl_esdhc_priv *priv, bool enable) { - struct fsl_esdhc_priv *priv = mmc->priv; struct fsl_esdhc *regs = priv->esdhc_regs; u32 value; u32 time_out; @@ -598,19 +600,18 @@ static void esdhc_clock_control(struct mmc *mmc, bool enable) } #endif -static int esdhc_set_ios(struct mmc *mmc) +static int esdhc_set_ios_common(struct fsl_esdhc_priv *priv, struct mmc *mmc) { - struct fsl_esdhc_priv *priv = mmc->priv; struct fsl_esdhc *regs = priv->esdhc_regs; #ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK /* Select to use peripheral clock */ - esdhc_clock_control(mmc, false); + esdhc_clock_control(priv, false); esdhc_setbits32(®s->scr, ESDHCCTL_PCS); - esdhc_clock_control(mmc, true); + esdhc_clock_control(priv, true); #endif /* Set the clock speed */ - set_sysctl(mmc, mmc->clock); + set_sysctl(priv, mmc, mmc->clock); /* Set the bus width */ esdhc_clrbits32(®s->proctl, PROCTL_DTW_4 | PROCTL_DTW_8); @@ -623,18 +624,20 @@ static int esdhc_set_ios(struct mmc *mmc) return 0; } -static int esdhc_init(struct mmc *mmc) +static int esdhc_init_common(struct fsl_esdhc_priv *priv, struct mmc *mmc) { - struct fsl_esdhc_priv *priv = mmc->priv; struct fsl_esdhc *regs = priv->esdhc_regs; - int timeout = 1000; + ulong start; /* Reset the entire host controller */ esdhc_setbits32(®s->sysctl, SYSCTL_RSTA); /* Wait until the controller is available */ - while ((esdhc_read32(®s->sysctl) & SYSCTL_RSTA) && --timeout) - udelay(1000); + start = get_timer(0); + while ((esdhc_read32(®s->sysctl) & SYSCTL_RSTA)) { + if (get_timer(start) > 1000) + return -ETIMEDOUT; + } #if defined(CONFIG_FSL_USDHC) /* RSTA doesn't reset MMC_BOOT register, so manually reset it */ @@ -679,9 +682,8 @@ static int esdhc_init(struct mmc *mmc) return 0; } -static int esdhc_getcd(struct mmc *mmc) +static int esdhc_getcd_common(struct fsl_esdhc_priv *priv) { - struct fsl_esdhc_priv *priv = mmc->priv; struct fsl_esdhc *regs = priv->esdhc_regs; int timeout = 1000; @@ -690,7 +692,7 @@ static int esdhc_getcd(struct mmc *mmc) return 1; #endif -#ifdef CONFIG_DM_MMC +#if CONFIG_IS_ENABLED(DM_MMC) if (priv->non_removable) return 1; #ifdef CONFIG_DM_GPIO @@ -705,32 +707,70 @@ static int esdhc_getcd(struct mmc *mmc) return timeout > 0; } -static void esdhc_reset(struct fsl_esdhc *regs) +static int esdhc_reset(struct fsl_esdhc *regs) { - unsigned long timeout = 100; /* wait max 100 ms */ + ulong start; /* reset the controller */ esdhc_setbits32(®s->sysctl, SYSCTL_RSTA); /* hardware clears the bit when it is done */ - while ((esdhc_read32(®s->sysctl) & SYSCTL_RSTA) && --timeout) - udelay(1000); - if (!timeout) - printf("MMC/SD: Reset never completed.\n"); + start = get_timer(0); + while ((esdhc_read32(®s->sysctl) & SYSCTL_RSTA)) { + if (get_timer(start) > 100) { + printf("MMC/SD: Reset never completed.\n"); + return -ETIMEDOUT; + } + } + + return 0; +} + +#if !CONFIG_IS_ENABLED(DM_MMC) +static int esdhc_getcd(struct mmc *mmc) +{ + struct fsl_esdhc_priv *priv = mmc->priv; + + return esdhc_getcd_common(priv); +} + +static int esdhc_init(struct mmc *mmc) +{ + struct fsl_esdhc_priv *priv = mmc->priv; + + return esdhc_init_common(priv, mmc); +} + +static int esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, + struct mmc_data *data) +{ + struct fsl_esdhc_priv *priv = mmc->priv; + + return esdhc_send_cmd_common(priv, mmc, cmd, data); +} + +static int esdhc_set_ios(struct mmc *mmc) +{ + struct fsl_esdhc_priv *priv = mmc->priv; + + return esdhc_set_ios_common(priv, mmc); } static const struct mmc_ops esdhc_ops = { + .getcd = esdhc_getcd, + .init = esdhc_init, .send_cmd = esdhc_send_cmd, .set_ios = esdhc_set_ios, - .init = esdhc_init, - .getcd = esdhc_getcd, }; +#endif -static int fsl_esdhc_init(struct fsl_esdhc_priv *priv) +static int fsl_esdhc_init(struct fsl_esdhc_priv *priv, + struct fsl_esdhc_plat *plat) { + struct mmc_config *cfg; struct fsl_esdhc *regs; - struct mmc *mmc; u32 caps, voltage_caps; + int ret; if (!priv) return -EINVAL; @@ -738,7 +778,9 @@ static int fsl_esdhc_init(struct fsl_esdhc_priv *priv) regs = priv->esdhc_regs; /* First reset the eSDHC controller */ - esdhc_reset(regs); + ret = esdhc_reset(regs); + if (ret) + return ret; #ifndef CONFIG_FSL_USDHC esdhc_setbits32(®s->sysctl, SYSCTL_PEREN | SYSCTL_HCKEN @@ -752,7 +794,10 @@ static int fsl_esdhc_init(struct fsl_esdhc_priv *priv) esdhc_setbits32(®s->vendorspec, ESDHC_VENDORSPEC_VSELECT); writel(SDHCI_IRQ_EN_BITS, ®s->irqstaten); - memset(&priv->cfg, 0, sizeof(priv->cfg)); + cfg = &plat->cfg; +#ifndef CONFIG_DM_MMC + memset(cfg, '\0', sizeof(*cfg)); +#endif voltage_caps = 0; caps = esdhc_read32(®s->hostcapblt); @@ -774,58 +819,54 @@ static int fsl_esdhc_init(struct fsl_esdhc_priv *priv) if (caps & ESDHC_HOSTCAPBLT_VS33) voltage_caps |= MMC_VDD_32_33 | MMC_VDD_33_34; - priv->cfg.name = "FSL_SDHC"; - priv->cfg.ops = &esdhc_ops; + cfg->name = "FSL_SDHC"; +#if !CONFIG_IS_ENABLED(DM_MMC) + cfg->ops = &esdhc_ops; +#endif #ifdef CONFIG_SYS_SD_VOLTAGE - priv->cfg.voltages = CONFIG_SYS_SD_VOLTAGE; + cfg->voltages = CONFIG_SYS_SD_VOLTAGE; #else - priv->cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34; + cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; #endif - if ((priv->cfg.voltages & voltage_caps) == 0) { + if ((cfg->voltages & voltage_caps) == 0) { printf("voltage not supported by controller\n"); return -1; } if (priv->bus_width == 8) - priv->cfg.host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT; + cfg->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT; else if (priv->bus_width == 4) - priv->cfg.host_caps = MMC_MODE_4BIT; + cfg->host_caps = MMC_MODE_4BIT; - priv->cfg.host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT; + cfg->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT; #ifdef CONFIG_SYS_FSL_ESDHC_HAS_DDR_MODE - priv->cfg.host_caps |= MMC_MODE_DDR_52MHz; + cfg->host_caps |= MMC_MODE_DDR_52MHz; #endif if (priv->bus_width > 0) { if (priv->bus_width < 8) - priv->cfg.host_caps &= ~MMC_MODE_8BIT; + cfg->host_caps &= ~MMC_MODE_8BIT; if (priv->bus_width < 4) - priv->cfg.host_caps &= ~MMC_MODE_4BIT; + cfg->host_caps &= ~MMC_MODE_4BIT; } if (caps & ESDHC_HOSTCAPBLT_HSS) - priv->cfg.host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; + cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; #ifdef CONFIG_ESDHC_DETECT_8_BIT_QUIRK if (CONFIG_ESDHC_DETECT_8_BIT_QUIRK) - priv->cfg.host_caps &= ~MMC_MODE_8BIT; + cfg->host_caps &= ~MMC_MODE_8BIT; #endif - priv->cfg.f_min = 400000; - priv->cfg.f_max = min(priv->sdhc_clk, (u32)52000000); - - priv->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; - - mmc = mmc_create(&priv->cfg, priv); - if (mmc == NULL) - return -1; + cfg->f_min = 400000; + cfg->f_max = min(priv->sdhc_clk, (u32)52000000); - priv->mmc = mmc; + cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; return 0; } -#ifndef CONFIG_DM_MMC +#if !CONFIG_IS_ENABLED(DM_MMC) static int fsl_esdhc_cfg_to_priv(struct fsl_esdhc_cfg *cfg, struct fsl_esdhc_priv *priv) { @@ -843,7 +884,9 @@ static int fsl_esdhc_cfg_to_priv(struct fsl_esdhc_cfg *cfg, int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg) { + struct fsl_esdhc_plat *plat; struct fsl_esdhc_priv *priv; + struct mmc *mmc; int ret; if (!cfg) @@ -852,21 +895,34 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg) priv = calloc(sizeof(struct fsl_esdhc_priv), 1); if (!priv) return -ENOMEM; + plat = calloc(sizeof(struct fsl_esdhc_plat), 1); + if (!plat) { + free(priv); + return -ENOMEM; + } ret = fsl_esdhc_cfg_to_priv(cfg, priv); if (ret) { debug("%s xlate failure\n", __func__); + free(plat); free(priv); return ret; } - ret = fsl_esdhc_init(priv); + ret = fsl_esdhc_init(priv, plat); if (ret) { debug("%s init failure\n", __func__); + free(plat); free(priv); return ret; } + mmc = mmc_create(&plat->cfg, priv); + if (!mmc) + return -EIO; + + priv->mmc = mmc; + return 0; } @@ -954,7 +1010,7 @@ void fdt_fixup_esdhc(void *blob, bd_t *bd) } #endif -#ifdef CONFIG_DM_MMC +#if CONFIG_IS_ENABLED(DM_MMC) #include <asm/arch/clock.h> __weak void init_clk_usdhc(u32 index) { @@ -963,24 +1019,24 @@ __weak void init_clk_usdhc(u32 index) static int fsl_esdhc_probe(struct udevice *dev) { struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); + struct fsl_esdhc_plat *plat = dev_get_platdata(dev); struct fsl_esdhc_priv *priv = dev_get_priv(dev); - const void *fdt = gd->fdt_blob; - int node = dev_of_offset(dev); #ifdef CONFIG_DM_REGULATOR struct udevice *vqmmc_dev; #endif fdt_addr_t addr; unsigned int val; + struct mmc *mmc; int ret; - addr = devfdt_get_addr(dev); + addr = dev_read_addr(dev); if (addr == FDT_ADDR_T_NONE) return -EINVAL; priv->esdhc_regs = (struct fsl_esdhc *)addr; priv->dev = dev; - val = fdtdec_get_int(fdt, node, "bus-width", -1); + val = dev_read_u32_default(dev, "bus-width", -1); if (val == 8) priv->bus_width = 8; else if (val == 4) @@ -988,21 +1044,21 @@ static int fsl_esdhc_probe(struct udevice *dev) else priv->bus_width = 1; - if (fdt_get_property(fdt, node, "non-removable", NULL)) { + if (dev_read_bool(dev, "non-removable")) { priv->non_removable = 1; } else { priv->non_removable = 0; #ifdef CONFIG_DM_GPIO - gpio_request_by_name_nodev(offset_to_ofnode(node), "cd-gpios", - 0, &priv->cd_gpio, GPIOD_IS_IN); + gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio, + GPIOD_IS_IN); #endif } priv->wp_enable = 1; #ifdef CONFIG_DM_GPIO - ret = gpio_request_by_name_nodev(offset_to_ofnode(node), "wp-gpios", 0, - &priv->wp_gpio, GPIOD_IS_IN); + ret = gpio_request_by_name(dev, "wp-gpios", 0, &priv->wp_gpio, + GPIOD_IS_IN); if (ret) priv->wp_enable = 0; #endif @@ -1057,18 +1113,53 @@ static int fsl_esdhc_probe(struct udevice *dev) return -EINVAL; } - ret = fsl_esdhc_init(priv); + ret = fsl_esdhc_init(priv, plat); if (ret) { dev_err(dev, "fsl_esdhc_init failure\n"); return ret; } - upriv->mmc = priv->mmc; - priv->mmc->dev = dev; + mmc = &plat->mmc; + mmc->cfg = &plat->cfg; + mmc->dev = dev; + upriv->mmc = mmc; - return 0; + return esdhc_init_common(priv, mmc); } +#if CONFIG_IS_ENABLED(DM_MMC) +static int fsl_esdhc_get_cd(struct udevice *dev) +{ + struct fsl_esdhc_priv *priv = dev_get_priv(dev); + + return true; + return esdhc_getcd_common(priv); +} + +static int fsl_esdhc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, + struct mmc_data *data) +{ + struct fsl_esdhc_plat *plat = dev_get_platdata(dev); + struct fsl_esdhc_priv *priv = dev_get_priv(dev); + + return esdhc_send_cmd_common(priv, &plat->mmc, cmd, data); +} + +static int fsl_esdhc_set_ios(struct udevice *dev) +{ + struct fsl_esdhc_plat *plat = dev_get_platdata(dev); + struct fsl_esdhc_priv *priv = dev_get_priv(dev); + + return esdhc_set_ios_common(priv, &plat->mmc); +} + +static const struct dm_mmc_ops fsl_esdhc_ops = { + .get_cd = fsl_esdhc_get_cd, + .send_cmd = fsl_esdhc_send_cmd, + .set_ios = fsl_esdhc_set_ios, +}; +#endif + static const struct udevice_id fsl_esdhc_ids[] = { { .compatible = "fsl,imx6ul-usdhc", }, { .compatible = "fsl,imx6sx-usdhc", }, @@ -1080,11 +1171,25 @@ static const struct udevice_id fsl_esdhc_ids[] = { { /* sentinel */ } }; +#if CONFIG_IS_ENABLED(BLK) +static int fsl_esdhc_bind(struct udevice *dev) +{ + struct fsl_esdhc_plat *plat = dev_get_platdata(dev); + + return mmc_bind(dev, &plat->mmc, &plat->cfg); +} +#endif + U_BOOT_DRIVER(fsl_esdhc) = { .name = "fsl-esdhc-mmc", .id = UCLASS_MMC, .of_match = fsl_esdhc_ids, + .ops = &fsl_esdhc_ops, +#if CONFIG_IS_ENABLED(BLK) + .bind = fsl_esdhc_bind, +#endif .probe = fsl_esdhc_probe, + .platdata_auto_alloc_size = sizeof(struct fsl_esdhc_plat), .priv_auto_alloc_size = sizeof(struct fsl_esdhc_priv), }; #endif diff --git a/drivers/mmc/gen_atmel_mci.c b/drivers/mmc/gen_atmel_mci.c index e9f061e55dc..22154d13d79 100644 --- a/drivers/mmc/gen_atmel_mci.c +++ b/drivers/mmc/gen_atmel_mci.c @@ -36,13 +36,22 @@ DECLARE_GLOBAL_DATA_PTR; # define MCI_BUS 0 #endif +#ifdef CONFIG_DM_MMC +struct atmel_mci_plat { + struct mmc mmc; + struct mmc_config cfg; + struct atmel_mci *mci; +}; +#endif + struct atmel_mci_priv { +#ifndef CONFIG_DM_MMC struct mmc_config cfg; struct atmel_mci *mci; +#endif unsigned int initialized:1; unsigned int curr_clk; #ifdef CONFIG_DM_MMC - struct mmc mmc; ulong bus_clk_rate; #endif }; @@ -67,18 +76,21 @@ static void dump_cmd(u32 cmdr, u32 arg, u32 status, const char* msg) /* Setup for MCI Clock and Block Size */ #ifdef CONFIG_DM_MMC -static void mci_set_mode(struct atmel_mci_priv *priv, u32 hz, u32 blklen) +static void mci_set_mode(struct udevice *dev, u32 hz, u32 blklen) { - struct mmc *mmc = &priv->mmc; + struct atmel_mci_plat *plat = dev_get_platdata(dev); + struct atmel_mci_priv *priv = dev_get_priv(dev); + struct mmc *mmc = &plat->mmc; u32 bus_hz = priv->bus_clk_rate; + atmel_mci_t *mci = plat->mci; #else static void mci_set_mode(struct mmc *mmc, u32 hz, u32 blklen) { struct atmel_mci_priv *priv = mmc->priv; u32 bus_hz = get_mci_clk_rate(); + atmel_mci_t *mci = priv->mci; #endif - atmel_mci_t *mci = priv->mci; u32 clkdiv = 255; unsigned int version = atmel_mci_get_version(mci); u32 clkodd = 0; @@ -222,15 +234,17 @@ io_fail: static int atmel_mci_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, struct mmc_data *data) { + struct atmel_mci_plat *plat = dev_get_platdata(dev); struct atmel_mci_priv *priv = dev_get_priv(dev); struct mmc *mmc = mmc_get_mmc_dev(dev); + atmel_mci_t *mci = plat->mci; #else static int mci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) { struct atmel_mci_priv *priv = mmc->priv; -#endif atmel_mci_t *mci = priv->mci; +#endif u32 cmdr; u32 error_flags = 0; u32 status; @@ -362,22 +376,23 @@ mci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) #ifdef CONFIG_DM_MMC static int atmel_mci_set_ios(struct udevice *dev) { - struct atmel_mci_priv *priv = dev_get_priv(dev); + struct atmel_mci_plat *plat = dev_get_platdata(dev); struct mmc *mmc = mmc_get_mmc_dev(dev); + atmel_mci_t *mci = plat->mci; #else /* Entered into mmc structure during driver init */ static int mci_set_ios(struct mmc *mmc) { struct atmel_mci_priv *priv = mmc->priv; -#endif atmel_mci_t *mci = priv->mci; +#endif int bus_width = mmc->bus_width; unsigned int version = atmel_mci_get_version(mci); int busw; /* Set the clock speed */ #ifdef CONFIG_DM_MMC - mci_set_mode(priv, mmc->clock, MMC_DEFAULT_BLKLEN); + mci_set_mode(dev, mmc->clock, MMC_DEFAULT_BLKLEN); #else mci_set_mode(mmc, mmc->clock, MMC_DEFAULT_BLKLEN); #endif @@ -410,15 +425,17 @@ static int mci_set_ios(struct mmc *mmc) } #ifdef CONFIG_DM_MMC -static int atmel_mci_hw_init(struct atmel_mci_priv *priv) +static int atmel_mci_hw_init(struct udevice *dev) { + struct atmel_mci_plat *plat = dev_get_platdata(dev); + atmel_mci_t *mci = plat->mci; #else /* Entered into mmc structure during driver init */ static int mci_init(struct mmc *mmc) { struct atmel_mci_priv *priv = mmc->priv; -#endif atmel_mci_t *mci = priv->mci; +#endif /* Initialize controller */ writel(MMCI_BIT(SWRST), &mci->cr); /* soft reset */ @@ -433,7 +450,7 @@ static int mci_init(struct mmc *mmc) /* Set default clocks and blocklen */ #ifdef CONFIG_DM_MMC - mci_set_mode(priv, CONFIG_SYS_MMC_CLK_OD, MMC_DEFAULT_BLKLEN); + mci_set_mode(dev, CONFIG_SYS_MMC_CLK_OD, MMC_DEFAULT_BLKLEN); #else mci_set_mode(mmc, CONFIG_SYS_MMC_CLK_OD, MMC_DEFAULT_BLKLEN); #endif @@ -509,12 +526,14 @@ static const struct dm_mmc_ops atmel_mci_mmc_ops = { .set_ios = atmel_mci_set_ios, }; -static void atmel_mci_setup_cfg(struct atmel_mci_priv *priv) +static void atmel_mci_setup_cfg(struct udevice *dev) { + struct atmel_mci_plat *plat = dev_get_platdata(dev); + struct atmel_mci_priv *priv = dev_get_priv(dev); struct mmc_config *cfg; u32 version; - cfg = &priv->cfg; + cfg = &plat->cfg; cfg->name = "Atmel mci"; cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; @@ -522,7 +541,7 @@ static void atmel_mci_setup_cfg(struct atmel_mci_priv *priv) * If the version is above 3.0, the capabilities of the 8-bit * bus width and high speed are supported. */ - version = atmel_mci_get_version(priv->mci); + version = atmel_mci_get_version(plat->mci); if ((version & 0xf00) >= 0x300) { cfg->host_caps = MMC_MODE_8BIT | MMC_MODE_HS | MMC_MODE_HS_52MHz; @@ -568,7 +587,7 @@ failed: static int atmel_mci_probe(struct udevice *dev) { struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); - struct atmel_mci_priv *priv = dev_get_priv(dev); + struct atmel_mci_plat *plat = dev_get_platdata(dev); struct mmc *mmc; int ret; @@ -576,25 +595,25 @@ static int atmel_mci_probe(struct udevice *dev) if (ret) return ret; - priv->mci = (struct atmel_mci *)devfdt_get_addr_ptr(dev); + plat->mci = (struct atmel_mci *)devfdt_get_addr_ptr(dev); - atmel_mci_setup_cfg(priv); + atmel_mci_setup_cfg(dev); - mmc = &priv->mmc; - mmc->cfg = &priv->cfg; + mmc = &plat->mmc; + mmc->cfg = &plat->cfg; mmc->dev = dev; upriv->mmc = mmc; - atmel_mci_hw_init(priv); + atmel_mci_hw_init(dev); return 0; } static int atmel_mci_bind(struct udevice *dev) { - struct atmel_mci_priv *priv = dev_get_priv(dev); + struct atmel_mci_plat *plat = dev_get_platdata(dev); - return mmc_bind(dev, &priv->mmc, &priv->cfg); + return mmc_bind(dev, &plat->mmc, &plat->cfg); } static const struct udevice_id atmel_mci_ids[] = { @@ -608,6 +627,7 @@ U_BOOT_DRIVER(atmel_mci) = { .of_match = atmel_mci_ids, .bind = atmel_mci_bind, .probe = atmel_mci_probe, + .platdata_auto_alloc_size = sizeof(struct atmel_mci_plat), .priv_auto_alloc_size = sizeof(struct atmel_mci_priv), .ops = &atmel_mci_mmc_ops, }; diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c index 3e907253ea8..5dda20cda5e 100644 --- a/drivers/mmc/mmc-uclass.c +++ b/drivers/mmc/mmc-uclass.c @@ -15,7 +15,6 @@ DECLARE_GLOBAL_DATA_PTR; -#if CONFIG_IS_ENABLED(DM_MMC_OPS) int dm_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, struct mmc_data *data) { @@ -79,7 +78,6 @@ int mmc_getcd(struct mmc *mmc) { return dm_mmc_get_cd(mmc->dev); } -#endif struct mmc *mmc_get_mmc_dev(struct udevice *dev) { @@ -198,10 +196,8 @@ int mmc_bind(struct udevice *dev, struct mmc *mmc, const struct mmc_config *cfg) struct udevice *bdev; int ret, devnum = -1; -#if CONFIG_IS_ENABLED(DM_MMC_OPS) if (!mmc_get_ops(dev)) return -ENOSYS; -#endif #ifndef CONFIG_SPL_BUILD /* Use the fixed index with aliase node's index */ ret = dev_read_alias_seq(dev, &devnum); diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 38e1c800e10..38d2e07dd51 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -53,7 +53,7 @@ struct blk_desc *mmc_get_blk_desc(struct mmc *mmc) } #endif -#if !CONFIG_IS_ENABLED(DM_MMC_OPS) +#if !CONFIG_IS_ENABLED(DM_MMC) __weak int board_mmc_getwp(struct mmc *mmc) { return -1; @@ -149,7 +149,7 @@ void mmc_trace_state(struct mmc *mmc, struct mmc_cmd *cmd) } #endif -#if !CONFIG_IS_ENABLED(DM_MMC_OPS) +#if !CONFIG_IS_ENABLED(DM_MMC) int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) { int ret; @@ -839,7 +839,7 @@ int mmc_hwpart_config(struct mmc *mmc, return 0; } -#if !CONFIG_IS_ENABLED(DM_MMC_OPS) +#if !CONFIG_IS_ENABLED(DM_MMC) int mmc_getcd(struct mmc *mmc) { int cd; @@ -1075,7 +1075,7 @@ static const u8 multipliers[] = { 80, }; -#if !CONFIG_IS_ENABLED(DM_MMC_OPS) +#if !CONFIG_IS_ENABLED(DM_MMC) static void mmc_set_ios(struct mmc *mmc) { if (mmc->cfg->ops->set_ios) @@ -1652,7 +1652,7 @@ int mmc_start_init(struct mmc *mmc) /* we pretend there's no card when init is NULL */ no_card = mmc_getcd(mmc) == 0; -#if !CONFIG_IS_ENABLED(DM_MMC_OPS) +#if !CONFIG_IS_ENABLED(DM_MMC) no_card = no_card || (mmc->cfg->ops->init == NULL); #endif if (no_card) { @@ -1673,7 +1673,7 @@ int mmc_start_init(struct mmc *mmc) if (err) return err; -#if CONFIG_IS_ENABLED(DM_MMC_OPS) +#if CONFIG_IS_ENABLED(DM_MMC) /* The device has already been probed ready for use */ #else /* made sure it's not NULL earlier */ diff --git a/drivers/mmc/mmc_boot.c b/drivers/mmc/mmc_boot.c index ac6f56f157a..6d77ce95e7e 100644 --- a/drivers/mmc/mmc_boot.c +++ b/drivers/mmc/mmc_boot.c @@ -100,10 +100,19 @@ int mmc_set_boot_bus_width(struct mmc *mmc, u8 width, u8 reset, u8 mode) */ int mmc_set_part_conf(struct mmc *mmc, u8 ack, u8 part_num, u8 access) { - return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF, - EXT_CSD_BOOT_ACK(ack) | - EXT_CSD_BOOT_PART_NUM(part_num) | - EXT_CSD_PARTITION_ACCESS(access)); + int ret; + u8 part_conf; + + part_conf = EXT_CSD_BOOT_ACK(ack) | + EXT_CSD_BOOT_PART_NUM(part_num) | + EXT_CSD_PARTITION_ACCESS(access); + + ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF, + part_conf); + if (!ret) + mmc->part_config = part_conf; + + return ret; } /* diff --git a/drivers/mmc/mmc_legacy.c b/drivers/mmc/mmc_legacy.c index 59dc3df35f8..100b931e5b3 100644 --- a/drivers/mmc/mmc_legacy.c +++ b/drivers/mmc/mmc_legacy.c @@ -150,7 +150,7 @@ struct mmc *mmc_create(const struct mmc_config *cfg, void *priv) cfg->f_max == 0 || cfg->b_max == 0) return NULL; -#if !CONFIG_IS_ENABLED(DM_MMC_OPS) +#if !CONFIG_IS_ENABLED(DM_MMC) if (cfg->ops == NULL || cfg->ops->send_cmd == NULL) return NULL; #endif diff --git a/drivers/mmc/pci_mmc.c b/drivers/mmc/pci_mmc.c index 6db89779ba3..05c0044a7a0 100644 --- a/drivers/mmc/pci_mmc.c +++ b/drivers/mmc/pci_mmc.c @@ -64,12 +64,7 @@ U_BOOT_DRIVER(pci_mmc) = { }; static struct pci_device_id mmc_supported[] = { - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT_SDIO) }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT_SD) }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT_EMMC2) }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_QRK_SDIO) }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TCF_SDIO_0) }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TCF_SDIO_1) }, + { PCI_DEVICE_CLASS(PCI_CLASS_SYSTEM_SDHCI << 8, 0xffff00) }, {}, }; diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 161a6b1399c..11d1f0c24cd 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -134,7 +134,7 @@ static int sdhci_transfer_data(struct sdhci_host *host, struct mmc_data *data, #define SDHCI_CMD_DEFAULT_TIMEOUT 100 #define SDHCI_READ_STATUS_TIMEOUT 1000 -#ifdef CONFIG_DM_MMC_OPS +#ifdef CONFIG_DM_MMC static int sdhci_send_command(struct udevice *dev, struct mmc_cmd *cmd, struct mmc_data *data) { @@ -422,7 +422,7 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power) sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); } -#ifdef CONFIG_DM_MMC_OPS +#ifdef CONFIG_DM_MMC static int sdhci_set_ios(struct udevice *dev) { struct mmc *mmc = mmc_get_mmc_dev(dev); @@ -502,7 +502,7 @@ static int sdhci_init(struct mmc *mmc) return 0; } -#ifdef CONFIG_DM_MMC_OPS +#ifdef CONFIG_DM_MMC int sdhci_probe(struct udevice *dev) { struct mmc *mmc = mmc_get_mmc_dev(dev); @@ -543,7 +543,7 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host, host->version = sdhci_readw(host, SDHCI_HOST_VERSION); cfg->name = host->name; -#ifndef CONFIG_DM_MMC_OPS +#ifndef CONFIG_DM_MMC cfg->ops = &sdhci_ops; #endif diff --git a/drivers/mmc/sh_sdhi.c b/drivers/mmc/sh_sdhi.c index d181b639058..eef061abb2d 100644 --- a/drivers/mmc/sh_sdhi.c +++ b/drivers/mmc/sh_sdhi.c @@ -13,21 +13,26 @@ #include <common.h> #include <malloc.h> #include <mmc.h> +#include <dm.h> #include <linux/errno.h> -#include <asm/io.h> +#include <linux/compat.h> +#include <linux/io.h> +#include <linux/sizes.h> #include <asm/arch/rmobile.h> #include <asm/arch/sh_sdhi.h> +#include <clk.h> #define DRIVER_NAME "sh-sdhi" struct sh_sdhi_host { - unsigned long addr; + void __iomem *addr; int ch; int bus_shift; unsigned long quirks; unsigned char wait_int; unsigned char sd_error; unsigned char detect_waiting; + unsigned char app_cmd; }; static inline void sh_sdhi_writeq(struct sh_sdhi_host *host, int reg, u64 val) @@ -50,11 +55,6 @@ static inline u16 sh_sdhi_readw(struct sh_sdhi_host *host, int reg) return readw(host->addr + (reg << host->bus_shift)); } -static void *mmc_priv(struct mmc *mmc) -{ - return (void *)mmc->priv; -} - static void sh_sdhi_detect(struct sh_sdhi_host *host) { sh_sdhi_writew(host, SDHI_OPTION, @@ -477,65 +477,64 @@ static void sh_sdhi_get_response(struct sh_sdhi_host *host, struct mmc_cmd *cmd) static unsigned short sh_sdhi_set_cmd(struct sh_sdhi_host *host, struct mmc_data *data, unsigned short opc) { - switch (opc) { - case SD_CMD_APP_SEND_OP_COND: - case SD_CMD_APP_SEND_SCR: - opc |= SDHI_APP; - break; - case SD_CMD_APP_SET_BUS_WIDTH: - /* SD_APP_SET_BUS_WIDTH*/ + if (host->app_cmd) { if (!data) - opc |= SDHI_APP; - else /* SD_SWITCH */ - opc = SDHI_SD_SWITCH; - break; - case MMC_CMD_SEND_OP_COND: - opc = SDHI_MMC_SEND_OP_COND; - break; + host->app_cmd = 0; + return opc | BIT(6); + } + + switch (opc) { + case MMC_CMD_SWITCH: + return opc | (data ? 0x1c00 : 0x40); case MMC_CMD_SEND_EXT_CSD: - if (data) - opc = SDHI_MMC_SEND_EXT_CSD; - break; + return opc | (data ? 0x1c00 : 0); + case MMC_CMD_SEND_OP_COND: + return opc | 0x0700; + case MMC_CMD_APP_CMD: + host->app_cmd = 1; default: - break; + return opc; } - return opc; } static unsigned short sh_sdhi_data_trans(struct sh_sdhi_host *host, struct mmc_data *data, unsigned short opc) { - unsigned short ret; - - switch (opc) { - case MMC_CMD_READ_MULTIPLE_BLOCK: - ret = sh_sdhi_multi_read(host, data); - break; - case MMC_CMD_WRITE_MULTIPLE_BLOCK: - ret = sh_sdhi_multi_write(host, data); - break; - case MMC_CMD_WRITE_SINGLE_BLOCK: - ret = sh_sdhi_single_write(host, data); - break; - case MMC_CMD_READ_SINGLE_BLOCK: - case SDHI_SD_APP_SEND_SCR: - case SDHI_SD_SWITCH: /* SD_SWITCH */ - case SDHI_MMC_SEND_EXT_CSD: - ret = sh_sdhi_single_read(host, data); - break; - default: - printf(DRIVER_NAME": SD: NOT SUPPORT CMD = d'%04d\n", opc); - ret = -EINVAL; - break; + if (host->app_cmd) { + host->app_cmd = 0; + switch (opc) { + case SD_CMD_APP_SEND_SCR: + case SD_CMD_APP_SD_STATUS: + return sh_sdhi_single_read(host, data); + default: + printf(DRIVER_NAME": SD: NOT SUPPORT APP CMD = d'%04d\n", + opc); + return -EINVAL; + } + } else { + switch (opc) { + case MMC_CMD_WRITE_MULTIPLE_BLOCK: + return sh_sdhi_multi_write(host, data); + case MMC_CMD_READ_MULTIPLE_BLOCK: + return sh_sdhi_multi_read(host, data); + case MMC_CMD_WRITE_SINGLE_BLOCK: + return sh_sdhi_single_write(host, data); + case MMC_CMD_READ_SINGLE_BLOCK: + case MMC_CMD_SWITCH: + case MMC_CMD_SEND_EXT_CSD:; + return sh_sdhi_single_read(host, data); + default: + printf(DRIVER_NAME": SD: NOT SUPPORT CMD = d'%04d\n", opc); + return -EINVAL; + } } - return ret; } static int sh_sdhi_start_cmd(struct sh_sdhi_host *host, struct mmc_data *data, struct mmc_cmd *cmd) { long time; - unsigned short opc = cmd->cmdidx; + unsigned short shcmd, opc = cmd->cmdidx; int ret = 0; unsigned long timeout; @@ -563,7 +562,8 @@ static int sh_sdhi_start_cmd(struct sh_sdhi_host *host, } sh_sdhi_writew(host, SDHI_SIZE, data->blocksize); } - opc = sh_sdhi_set_cmd(host, data, opc); + + shcmd = sh_sdhi_set_cmd(host, data, opc); /* * U-Boot cannot use interrupt. @@ -594,11 +594,12 @@ static int sh_sdhi_start_cmd(struct sh_sdhi_host *host, INFO2M_RESP_TIMEOUT | INFO2M_ILA) & sh_sdhi_readw(host, SDHI_INFO2_MASK)); - sh_sdhi_writew(host, SDHI_CMD, (unsigned short)(opc & CMD_MASK)); - + sh_sdhi_writew(host, SDHI_CMD, (unsigned short)(shcmd & CMD_MASK)); time = sh_sdhi_wait_interrupt_flag(host); - if (!time) + if (!time) { + host->app_cmd = 0; return sh_sdhi_error_manage(host); + } if (host->sd_error) { switch (cmd->cmdidx) { @@ -616,15 +617,20 @@ static int sh_sdhi_start_cmd(struct sh_sdhi_host *host, } host->sd_error = 0; host->wait_int = 0; + host->app_cmd = 0; return ret; } - if (sh_sdhi_readw(host, SDHI_INFO1) & INFO1_RESP_END) + + if (sh_sdhi_readw(host, SDHI_INFO1) & INFO1_RESP_END) { + host->app_cmd = 0; return -EINVAL; + } if (host->wait_int) { sh_sdhi_get_response(host, cmd); host->wait_int = 0; } + if (data) ret = sh_sdhi_data_trans(host, data, opc); @@ -634,23 +640,17 @@ static int sh_sdhi_start_cmd(struct sh_sdhi_host *host, return ret; } -static int sh_sdhi_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, - struct mmc_data *data) +static int sh_sdhi_send_cmd_common(struct sh_sdhi_host *host, + struct mmc_cmd *cmd, struct mmc_data *data) { - struct sh_sdhi_host *host = mmc_priv(mmc); - int ret; - host->sd_error = 0; - ret = sh_sdhi_start_cmd(host, data, cmd); - - return ret; + return sh_sdhi_start_cmd(host, data, cmd); } -static int sh_sdhi_set_ios(struct mmc *mmc) +static int sh_sdhi_set_ios_common(struct sh_sdhi_host *host, struct mmc *mmc) { int ret; - struct sh_sdhi_host *host = mmc_priv(mmc); ret = sh_sdhi_clock_control(host, mmc->clock); if (ret) @@ -674,9 +674,8 @@ static int sh_sdhi_set_ios(struct mmc *mmc) return 0; } -static int sh_sdhi_initialize(struct mmc *mmc) +static int sh_sdhi_initialize_common(struct sh_sdhi_host *host) { - struct sh_sdhi_host *host = mmc_priv(mmc); int ret = sh_sdhi_sync_reset(host); sh_sdhi_writew(host, SDHI_PORTSEL, USE_1PORT); @@ -692,6 +691,34 @@ static int sh_sdhi_initialize(struct mmc *mmc) return ret; } +#ifndef CONFIG_DM_MMC +static void *mmc_priv(struct mmc *mmc) +{ + return (void *)mmc->priv; +} + +static int sh_sdhi_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, + struct mmc_data *data) +{ + struct sh_sdhi_host *host = mmc_priv(mmc); + + return sh_sdhi_send_cmd_common(host, cmd, data); +} + +static int sh_sdhi_set_ios(struct mmc *mmc) +{ + struct sh_sdhi_host *host = mmc_priv(mmc); + + return sh_sdhi_set_ios_common(host, mmc); +} + +static int sh_sdhi_initialize(struct mmc *mmc) +{ + struct sh_sdhi_host *host = mmc_priv(mmc); + + return sh_sdhi_initialize_common(host); +} + static const struct mmc_ops sh_sdhi_ops = { .send_cmd = sh_sdhi_send_cmd, .set_ios = sh_sdhi_set_ios, @@ -743,7 +770,7 @@ int sh_sdhi_init(unsigned long addr, int ch, unsigned long quirks) } host->ch = ch; - host->addr = addr; + host->addr = (void __iomem *)addr; host->quirks = quirks; if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF) @@ -757,3 +784,123 @@ error: free(host); return ret; } + +#else + +struct sh_sdhi_plat { + struct mmc_config cfg; + struct mmc mmc; +}; + +int sh_sdhi_dm_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, + struct mmc_data *data) +{ + struct sh_sdhi_host *host = dev_get_priv(dev); + + return sh_sdhi_send_cmd_common(host, cmd, data); +} + +int sh_sdhi_dm_set_ios(struct udevice *dev) +{ + struct sh_sdhi_host *host = dev_get_priv(dev); + struct mmc *mmc = mmc_get_mmc_dev(dev); + + return sh_sdhi_set_ios_common(host, mmc); +} + +static const struct dm_mmc_ops sh_sdhi_dm_ops = { + .send_cmd = sh_sdhi_dm_send_cmd, + .set_ios = sh_sdhi_dm_set_ios, +}; + +static int sh_sdhi_dm_bind(struct udevice *dev) +{ + struct sh_sdhi_plat *plat = dev_get_platdata(dev); + + return mmc_bind(dev, &plat->mmc, &plat->cfg); +} + +static int sh_sdhi_dm_probe(struct udevice *dev) +{ + struct sh_sdhi_plat *plat = dev_get_platdata(dev); + struct sh_sdhi_host *host = dev_get_priv(dev); + struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); + struct clk sh_sdhi_clk; + const u32 quirks = dev_get_driver_data(dev); + fdt_addr_t base; + int ret; + + base = devfdt_get_addr(dev); + if (base == FDT_ADDR_T_NONE) + return -EINVAL; + + host->addr = devm_ioremap(dev, base, SZ_2K); + if (!host->addr) + return -ENOMEM; + + ret = clk_get_by_index(dev, 0, &sh_sdhi_clk); + if (ret) { + debug("failed to get clock, ret=%d\n", ret); + return ret; + } + + ret = clk_enable(&sh_sdhi_clk); + if (ret) { + debug("failed to enable clock, ret=%d\n", ret); + return ret; + } + + host->quirks = quirks; + + if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF) + host->bus_shift = 2; + else if (host->quirks & SH_SDHI_QUIRK_16BIT_BUF) + host->bus_shift = 1; + + plat->cfg.name = dev->name; + plat->cfg.host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS; + + switch (fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "bus-width", + 1)) { + case 8: + plat->cfg.host_caps |= MMC_MODE_8BIT; + break; + case 4: + plat->cfg.host_caps |= MMC_MODE_4BIT; + break; + case 1: + break; + default: + dev_err(dev, "Invalid \"bus-width\" value\n"); + return -EINVAL; + } + + sh_sdhi_initialize_common(host); + + plat->cfg.voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34; + plat->cfg.f_min = CLKDEV_INIT; + plat->cfg.f_max = CLKDEV_HS_DATA; + plat->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; + + upriv->mmc = &plat->mmc; + + return 0; +} + +static const struct udevice_id sh_sdhi_sd_match[] = { + { .compatible = "renesas,sdhi-r8a7795", .data = SH_SDHI_QUIRK_64BIT_BUF }, + { .compatible = "renesas,sdhi-r8a7796", .data = SH_SDHI_QUIRK_64BIT_BUF }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(sh_sdhi_mmc) = { + .name = "sh-sdhi-mmc", + .id = UCLASS_MMC, + .of_match = sh_sdhi_sd_match, + .bind = sh_sdhi_dm_bind, + .probe = sh_sdhi_dm_probe, + .priv_auto_alloc_size = sizeof(struct sh_sdhi_host), + .platdata_auto_alloc_size = sizeof(struct sh_sdhi_plat), + .ops = &sh_sdhi_dm_ops, +}; +#endif diff --git a/drivers/mmc/uniphier-sd.c b/drivers/mmc/uniphier-sd.c index 3c462bd5835..e272b141532 100644 --- a/drivers/mmc/uniphier-sd.c +++ b/drivers/mmc/uniphier-sd.c @@ -470,13 +470,13 @@ static int uniphier_sd_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, u32 rsp_71_40 = readl(priv->regbase + UNIPHIER_SD_RSP32); u32 rsp_39_8 = readl(priv->regbase + UNIPHIER_SD_RSP10); - cmd->response[0] = (rsp_127_104 & 0xffffff) << 8 | - (rsp_103_72 & 0xff); - cmd->response[1] = (rsp_103_72 & 0xffffff) << 8 | - (rsp_71_40 & 0xff); - cmd->response[2] = (rsp_71_40 & 0xffffff) << 8 | - (rsp_39_8 & 0xff); - cmd->response[3] = (rsp_39_8 & 0xffffff) << 8; + cmd->response[0] = ((rsp_127_104 & 0x00ffffff) << 8) | + ((rsp_103_72 & 0xff000000) >> 24); + cmd->response[1] = ((rsp_103_72 & 0x00ffffff) << 8) | + ((rsp_71_40 & 0xff000000) >> 24); + cmd->response[2] = ((rsp_71_40 & 0x00ffffff) << 8) | + ((rsp_39_8 & 0xff000000) >> 24); + cmd->response[3] = (rsp_39_8 & 0xffffff) << 8; } else { /* bit 39-8 */ cmd->response[0] = readl(priv->regbase + UNIPHIER_SD_RSP10); diff --git a/include/ahci.h b/include/ahci.h index 29f4ba1d13d..33171b7ffd6 100644 --- a/include/ahci.h +++ b/include/ahci.h @@ -176,6 +176,60 @@ struct ahci_uc_priv { u32 link_port_map; /*linkup port map*/ }; +struct ahci_ops { + /** + * reset() - reset the controller + * + * @dev: Controller to reset + * @return 0 if OK, -ve on error + */ + int (*reset)(struct udevice *dev); + + /** + * port_status() - get the status of a SATA port + * + * @dev: Controller to reset + * @port: Port number to check (0 for first) + * @return 0 if detected, -ENXIO if nothing on port, other -ve on error + */ + int (*port_status)(struct udevice *dev, int port); + + /** + * scan() - scan SATA ports + * + * @dev: Controller to scan + * @return 0 if OK, -ve on error + */ + int (*scan)(struct udevice *dev); +}; + +#define ahci_get_ops(dev) ((struct ahci_ops *)(dev)->driver->ops) + +/** + * sata_reset() - reset the controller + * + * @dev: Controller to reset + * @return 0 if OK, -ve on error + */ +int sata_reset(struct udevice *dev); + +/** + * sata_port_status() - get the status of a SATA port + * + * @dev: Controller to reset + * @port: Port number to check (0 for first) + * @return 0 if detected, -ENXIO if nothin on port, other -ve on error + */ +int sata_dm_port_status(struct udevice *dev, int port); + +/** + * sata_scan() - scan SATA ports + * + * @dev: Controller to scan + * @return 0 if OK, -ve on error + */ +int sata_scan(struct udevice *dev); + int ahci_init(void __iomem *base); int ahci_reset(void __iomem *base); diff --git a/include/blk.h b/include/blk.h index 61b56281b31..a106f9ca0e5 100644 --- a/include/blk.h +++ b/include/blk.h @@ -624,4 +624,24 @@ ulong blk_write_devnum(enum if_type if_type, int devnum, lbaint_t start, */ int blk_select_hwpart_devnum(enum if_type if_type, int devnum, int hwpart); +/** + * blk_get_if_type_name() - Get the name of an interface type + * + * @if_type: Interface type to check + * @return name of interface, or NULL if none + */ +const char *blk_get_if_type_name(enum if_type if_type); + +/** + * blk_common_cmd() - handle common commands with block devices + * + * @args: Number of arguments to the command (argv[0] is the command itself) + * @argv: Command arguments + * @if_type: Interface type + * @cur_devnump: Current device number for this interface type + * @return 0 if OK, CMD_RET_ERROR on error + */ +int blk_common_cmd(int argc, char * const argv[], enum if_type if_type, + int *cur_devnump); + #endif diff --git a/include/configs/am335x_evm.h b/include/configs/am335x_evm.h index c9420b2d739..973f63f891b 100644 --- a/include/configs/am335x_evm.h +++ b/include/configs/am335x_evm.h @@ -282,7 +282,6 @@ */ #ifdef CONFIG_SPL_BUILD #undef CONFIG_DM_MMC -#undef CONFIG_DM_MMC_OPS #undef CONFIG_TIMER #undef CONFIG_DM_USB #endif diff --git a/include/configs/am335x_shc.h b/include/configs/am335x_shc.h index 62ab2d7227e..3fdbfdcdc67 100644 --- a/include/configs/am335x_shc.h +++ b/include/configs/am335x_shc.h @@ -256,7 +256,6 @@ */ #ifdef CONFIG_SPL_BUILD #undef CONFIG_DM_MMC -#undef CONFIG_DM_MMC_OPS #undef CONFIG_TIMER #endif diff --git a/include/configs/chiliboard.h b/include/configs/chiliboard.h index fb3e67466ee..20075915fd5 100644 --- a/include/configs/chiliboard.h +++ b/include/configs/chiliboard.h @@ -183,7 +183,6 @@ */ #ifdef CONFIG_SPL_BUILD #undef CONFIG_DM_MMC -#undef CONFIG_DM_MMC_OPS #undef CONFIG_TIMER #undef CONFIG_DM_USB #endif diff --git a/include/configs/omap3_logic.h b/include/configs/omap3_logic.h index 5490fc945a1..b4311ab13b6 100644 --- a/include/configs/omap3_logic.h +++ b/include/configs/omap3_logic.h @@ -23,7 +23,6 @@ * DM support in SPL */ #undef CONFIG_DM_MMC -#undef CONFIG_DM_MMC_OPS #undef OMAP_HSMMC_USE_GPIO /* select serial console configuration for SPL */ diff --git a/include/dm/device-internal.h b/include/dm/device-internal.h index 81ab893b600..eaeadd48d2a 100644 --- a/include/dm/device-internal.h +++ b/include/dm/device-internal.h @@ -98,7 +98,7 @@ int device_probe(struct udevice *dev); * children are deactivated first. * * @dev: Pointer to device to remove - * @flags: Flags for selective device removal + * @flags: Flags for selective device removal (DM_REMOVE_...) * @return 0 if OK, -ve on error (an error here is normally a very bad thing) */ #if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE) diff --git a/include/dwc_ahsata.h b/include/dwc_ahsata.h new file mode 100644 index 00000000000..cae275fe75a --- /dev/null +++ b/include/dwc_ahsata.h @@ -0,0 +1,16 @@ +/* + * Copyright 2017 Google, Inc + * Written by Simon Glass <sjg@chromium.org> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __DWC_AHSATA_H__ +#define __DWC_AHSATA_H__ + +int dwc_ahsata_bus_reset(struct udevice *dev); +int dwc_ahsata_probe(struct udevice *dev); +int dwc_ahsata_scan(struct udevice *dev); +int dwc_ahsata_port_status(struct udevice *dev, int port); + +#endif diff --git a/include/dwmmc.h b/include/dwmmc.h index 4dda0091cef..a9058824e0d 100644 --- a/include/dwmmc.h +++ b/include/dwmmc.h @@ -291,7 +291,7 @@ int dwmci_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg); int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk); #endif /* !CONFIG_BLK */ -#ifdef CONFIG_DM_MMC_OPS +#ifdef CONFIG_DM_MMC /* Export the operations to drivers */ int dwmci_probe(struct udevice *dev); extern const struct dm_mmc_ops dm_dwmci_ops; diff --git a/include/mmc.h b/include/mmc.h index cb8bf6a971c..010ebe048c4 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -221,6 +221,10 @@ #define EXT_CSD_BOOT_PART_NUM(x) (x << 3) #define EXT_CSD_PARTITION_ACCESS(x) (x << 0) +#define EXT_CSD_EXTRACT_BOOT_ACK(x) (((x) >> 6) & 0x1) +#define EXT_CSD_EXTRACT_BOOT_PART(x) (((x) >> 3) & 0x7) +#define EXT_CSD_EXTRACT_PARTITION_ACCESS(x) ((x) & 0x7) + #define EXT_CSD_BOOT_BUS_WIDTH_MODE(x) (x << 3) #define EXT_CSD_BOOT_BUS_WIDTH_RESET(x) (x << 2) #define EXT_CSD_BOOT_BUS_WIDTH_WIDTH(x) (x) @@ -321,7 +325,7 @@ struct mmc_data { /* forward decl. */ struct mmc; -#if CONFIG_IS_ENABLED(DM_MMC_OPS) +#if CONFIG_IS_ENABLED(DM_MMC) struct dm_mmc_ops { /** * send_cmd() - Send a command to the MMC device @@ -385,7 +389,7 @@ struct mmc_ops { struct mmc_config { const char *name; -#if !CONFIG_IS_ENABLED(DM_MMC_OPS) +#if !CONFIG_IS_ENABLED(DM_MMC) const struct mmc_ops *ops; #endif uint host_caps; @@ -519,7 +523,7 @@ int mmc_switch_part(struct mmc *mmc, unsigned int part_num); int mmc_hwpart_config(struct mmc *mmc, const struct mmc_hwpart_conf *conf, enum mmc_hwpart_conf_mode mode); -#if !CONFIG_IS_ENABLED(DM_MMC_OPS) +#if !CONFIG_IS_ENABLED(DM_MMC) int mmc_getcd(struct mmc *mmc); int board_mmc_getcd(struct mmc *mmc); int mmc_getwp(struct mmc *mmc); diff --git a/include/sata.h b/include/sata.h index d18cc9aa875..d89f7a8a298 100644 --- a/include/sata.h +++ b/include/sata.h @@ -2,7 +2,7 @@ #define __SATA_H__ #include <part.h> -#if !defined(CONFIG_DM_SCSI) +#if !defined(CONFIG_DM_SCSI) && !defined(CONFIG_AHCI) int init_sata(int dev); int reset_sata(int dev); int scan_sata(int dev); @@ -18,4 +18,7 @@ int sata_port_status(int dev, int port); extern struct blk_desc sata_dev_desc[]; #endif +int sata_probe(int devnum); +int sata_remove(int devnum); + #endif diff --git a/include/sdhci.h b/include/sdhci.h index 6a43271e963..7e84012f60e 100644 --- a/include/sdhci.h +++ b/include/sdhci.h @@ -410,7 +410,7 @@ int sdhci_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg); int add_sdhci(struct sdhci_host *host, u32 f_max, u32 f_min); #endif /* !CONFIG_BLK */ -#ifdef CONFIG_DM_MMC_OPS +#ifdef CONFIG_DM_MMC /* Export the operations to drivers */ int sdhci_probe(struct udevice *dev); extern const struct dm_mmc_ops sdhci_ops; |