diff options
Diffstat (limited to 'drivers/mmc/host/sdhci-esdhc-imx.c')
| -rw-r--r-- | drivers/mmc/host/sdhci-esdhc-imx.c | 210 |
1 files changed, 104 insertions, 106 deletions
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index faf0cb910c96..c6b9f6492e1a 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c | |||
| @@ -581,13 +581,8 @@ static void esdhc_writeb_le(struct sdhci_host *host, u8 val, int reg) | |||
| 581 | static unsigned int esdhc_pltfm_get_max_clock(struct sdhci_host *host) | 581 | static unsigned int esdhc_pltfm_get_max_clock(struct sdhci_host *host) |
| 582 | { | 582 | { |
| 583 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | 583 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
| 584 | struct pltfm_imx_data *imx_data = pltfm_host->priv; | ||
| 585 | struct esdhc_platform_data *boarddata = &imx_data->boarddata; | ||
| 586 | 584 | ||
| 587 | if (boarddata->f_max && (boarddata->f_max < pltfm_host->clock)) | 585 | return pltfm_host->clock; |
| 588 | return boarddata->f_max; | ||
| 589 | else | ||
| 590 | return pltfm_host->clock; | ||
| 591 | } | 586 | } |
| 592 | 587 | ||
| 593 | static unsigned int esdhc_pltfm_get_min_clock(struct sdhci_host *host) | 588 | static unsigned int esdhc_pltfm_get_min_clock(struct sdhci_host *host) |
| @@ -878,34 +873,19 @@ static const struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = { | |||
| 878 | static int | 873 | static int |
| 879 | sdhci_esdhc_imx_probe_dt(struct platform_device *pdev, | 874 | sdhci_esdhc_imx_probe_dt(struct platform_device *pdev, |
| 880 | struct sdhci_host *host, | 875 | struct sdhci_host *host, |
| 881 | struct esdhc_platform_data *boarddata) | 876 | struct pltfm_imx_data *imx_data) |
| 882 | { | 877 | { |
| 883 | struct device_node *np = pdev->dev.of_node; | 878 | struct device_node *np = pdev->dev.of_node; |
| 884 | 879 | struct esdhc_platform_data *boarddata = &imx_data->boarddata; | |
| 885 | if (!np) | 880 | int ret; |
| 886 | return -ENODEV; | ||
| 887 | |||
| 888 | if (of_get_property(np, "non-removable", NULL)) | ||
| 889 | boarddata->cd_type = ESDHC_CD_PERMANENT; | ||
| 890 | |||
| 891 | if (of_get_property(np, "fsl,cd-controller", NULL)) | ||
| 892 | boarddata->cd_type = ESDHC_CD_CONTROLLER; | ||
| 893 | 881 | ||
| 894 | if (of_get_property(np, "fsl,wp-controller", NULL)) | 882 | if (of_get_property(np, "fsl,wp-controller", NULL)) |
| 895 | boarddata->wp_type = ESDHC_WP_CONTROLLER; | 883 | boarddata->wp_type = ESDHC_WP_CONTROLLER; |
| 896 | 884 | ||
| 897 | boarddata->cd_gpio = of_get_named_gpio(np, "cd-gpios", 0); | ||
| 898 | if (gpio_is_valid(boarddata->cd_gpio)) | ||
| 899 | boarddata->cd_type = ESDHC_CD_GPIO; | ||
| 900 | |||
| 901 | boarddata->wp_gpio = of_get_named_gpio(np, "wp-gpios", 0); | 885 | boarddata->wp_gpio = of_get_named_gpio(np, "wp-gpios", 0); |
| 902 | if (gpio_is_valid(boarddata->wp_gpio)) | 886 | if (gpio_is_valid(boarddata->wp_gpio)) |
| 903 | boarddata->wp_type = ESDHC_WP_GPIO; | 887 | boarddata->wp_type = ESDHC_WP_GPIO; |
| 904 | 888 | ||
| 905 | of_property_read_u32(np, "bus-width", &boarddata->max_bus_width); | ||
| 906 | |||
| 907 | of_property_read_u32(np, "max-frequency", &boarddata->f_max); | ||
| 908 | |||
| 909 | if (of_find_property(np, "no-1-8-v", NULL)) | 889 | if (of_find_property(np, "no-1-8-v", NULL)) |
| 910 | boarddata->support_vsel = false; | 890 | boarddata->support_vsel = false; |
| 911 | else | 891 | else |
| @@ -916,29 +896,119 @@ sdhci_esdhc_imx_probe_dt(struct platform_device *pdev, | |||
| 916 | 896 | ||
| 917 | mmc_of_parse_voltage(np, &host->ocr_mask); | 897 | mmc_of_parse_voltage(np, &host->ocr_mask); |
| 918 | 898 | ||
| 899 | /* sdr50 and sdr104 needs work on 1.8v signal voltage */ | ||
| 900 | if ((boarddata->support_vsel) && esdhc_is_usdhc(imx_data) && | ||
| 901 | !IS_ERR(imx_data->pins_default)) { | ||
| 902 | imx_data->pins_100mhz = pinctrl_lookup_state(imx_data->pinctrl, | ||
| 903 | ESDHC_PINCTRL_STATE_100MHZ); | ||
| 904 | imx_data->pins_200mhz = pinctrl_lookup_state(imx_data->pinctrl, | ||
| 905 | ESDHC_PINCTRL_STATE_200MHZ); | ||
| 906 | if (IS_ERR(imx_data->pins_100mhz) || | ||
| 907 | IS_ERR(imx_data->pins_200mhz)) { | ||
| 908 | dev_warn(mmc_dev(host->mmc), | ||
| 909 | "could not get ultra high speed state, work on normal mode\n"); | ||
| 910 | /* | ||
| 911 | * fall back to not support uhs by specify no 1.8v quirk | ||
| 912 | */ | ||
| 913 | host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V; | ||
| 914 | } | ||
| 915 | } else { | ||
| 916 | host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V; | ||
| 917 | } | ||
| 918 | |||
| 919 | /* call to generic mmc_of_parse to support additional capabilities */ | 919 | /* call to generic mmc_of_parse to support additional capabilities */ |
| 920 | return mmc_of_parse(host->mmc); | 920 | ret = mmc_of_parse(host->mmc); |
| 921 | if (ret) | ||
| 922 | return ret; | ||
| 923 | |||
| 924 | if (!IS_ERR_VALUE(mmc_gpio_get_cd(host->mmc))) | ||
| 925 | host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; | ||
| 926 | |||
| 927 | return 0; | ||
| 921 | } | 928 | } |
| 922 | #else | 929 | #else |
| 923 | static inline int | 930 | static inline int |
| 924 | sdhci_esdhc_imx_probe_dt(struct platform_device *pdev, | 931 | sdhci_esdhc_imx_probe_dt(struct platform_device *pdev, |
| 925 | struct sdhci_host *host, | 932 | struct sdhci_host *host, |
| 926 | struct esdhc_platform_data *boarddata) | 933 | struct pltfm_imx_data *imx_data) |
| 927 | { | 934 | { |
| 928 | return -ENODEV; | 935 | return -ENODEV; |
| 929 | } | 936 | } |
| 930 | #endif | 937 | #endif |
| 931 | 938 | ||
| 939 | static int sdhci_esdhc_imx_probe_nondt(struct platform_device *pdev, | ||
| 940 | struct sdhci_host *host, | ||
| 941 | struct pltfm_imx_data *imx_data) | ||
| 942 | { | ||
| 943 | struct esdhc_platform_data *boarddata = &imx_data->boarddata; | ||
| 944 | int err; | ||
| 945 | |||
| 946 | if (!host->mmc->parent->platform_data) { | ||
| 947 | dev_err(mmc_dev(host->mmc), "no board data!\n"); | ||
| 948 | return -EINVAL; | ||
| 949 | } | ||
| 950 | |||
| 951 | imx_data->boarddata = *((struct esdhc_platform_data *) | ||
| 952 | host->mmc->parent->platform_data); | ||
| 953 | /* write_protect */ | ||
| 954 | if (boarddata->wp_type == ESDHC_WP_GPIO) { | ||
| 955 | err = mmc_gpio_request_ro(host->mmc, boarddata->wp_gpio); | ||
| 956 | if (err) { | ||
| 957 | dev_err(mmc_dev(host->mmc), | ||
| 958 | "failed to request write-protect gpio!\n"); | ||
| 959 | return err; | ||
| 960 | } | ||
| 961 | host->mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH; | ||
| 962 | } | ||
| 963 | |||
| 964 | /* card_detect */ | ||
| 965 | switch (boarddata->cd_type) { | ||
| 966 | case ESDHC_CD_GPIO: | ||
| 967 | err = mmc_gpio_request_cd(host->mmc, boarddata->cd_gpio, 0); | ||
| 968 | if (err) { | ||
| 969 | dev_err(mmc_dev(host->mmc), | ||
| 970 | "failed to request card-detect gpio!\n"); | ||
| 971 | return err; | ||
| 972 | } | ||
| 973 | /* fall through */ | ||
| 974 | |||
| 975 | case ESDHC_CD_CONTROLLER: | ||
| 976 | /* we have a working card_detect back */ | ||
| 977 | host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; | ||
| 978 | break; | ||
| 979 | |||
| 980 | case ESDHC_CD_PERMANENT: | ||
| 981 | host->mmc->caps |= MMC_CAP_NONREMOVABLE; | ||
| 982 | break; | ||
| 983 | |||
| 984 | case ESDHC_CD_NONE: | ||
| 985 | break; | ||
| 986 | } | ||
| 987 | |||
| 988 | switch (boarddata->max_bus_width) { | ||
| 989 | case 8: | ||
| 990 | host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA; | ||
| 991 | break; | ||
| 992 | case 4: | ||
| 993 | host->mmc->caps |= MMC_CAP_4_BIT_DATA; | ||
| 994 | break; | ||
| 995 | case 1: | ||
| 996 | default: | ||
| 997 | host->quirks |= SDHCI_QUIRK_FORCE_1_BIT_DATA; | ||
| 998 | break; | ||
| 999 | } | ||
| 1000 | |||
| 1001 | return 0; | ||
| 1002 | } | ||
| 1003 | |||
| 932 | static int sdhci_esdhc_imx_probe(struct platform_device *pdev) | 1004 | static int sdhci_esdhc_imx_probe(struct platform_device *pdev) |
| 933 | { | 1005 | { |
| 934 | const struct of_device_id *of_id = | 1006 | const struct of_device_id *of_id = |
| 935 | of_match_device(imx_esdhc_dt_ids, &pdev->dev); | 1007 | of_match_device(imx_esdhc_dt_ids, &pdev->dev); |
| 936 | struct sdhci_pltfm_host *pltfm_host; | 1008 | struct sdhci_pltfm_host *pltfm_host; |
| 937 | struct sdhci_host *host; | 1009 | struct sdhci_host *host; |
| 938 | struct esdhc_platform_data *boarddata; | ||
| 939 | int err; | 1010 | int err; |
| 940 | struct pltfm_imx_data *imx_data; | 1011 | struct pltfm_imx_data *imx_data; |
| 941 | bool dt = true; | ||
| 942 | 1012 | ||
| 943 | host = sdhci_pltfm_init(pdev, &sdhci_esdhc_imx_pdata, 0); | 1013 | host = sdhci_pltfm_init(pdev, &sdhci_esdhc_imx_pdata, 0); |
| 944 | if (IS_ERR(host)) | 1014 | if (IS_ERR(host)) |
| @@ -1030,84 +1100,12 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev) | |||
| 1030 | if (imx_data->socdata->flags & ESDHC_FLAG_ERR004536) | 1100 | if (imx_data->socdata->flags & ESDHC_FLAG_ERR004536) |
| 1031 | host->quirks |= SDHCI_QUIRK_BROKEN_ADMA; | 1101 | host->quirks |= SDHCI_QUIRK_BROKEN_ADMA; |
| 1032 | 1102 | ||
| 1033 | boarddata = &imx_data->boarddata; | 1103 | if (of_id) |
| 1034 | if (sdhci_esdhc_imx_probe_dt(pdev, host, boarddata) < 0) { | 1104 | err = sdhci_esdhc_imx_probe_dt(pdev, host, imx_data); |
| 1035 | if (!host->mmc->parent->platform_data) { | 1105 | else |
| 1036 | dev_err(mmc_dev(host->mmc), "no board data!\n"); | 1106 | err = sdhci_esdhc_imx_probe_nondt(pdev, host, imx_data); |
| 1037 | err = -EINVAL; | 1107 | if (err) |
| 1038 | goto disable_clk; | 1108 | goto disable_clk; |
| 1039 | } | ||
| 1040 | imx_data->boarddata = *((struct esdhc_platform_data *) | ||
| 1041 | host->mmc->parent->platform_data); | ||
| 1042 | dt = false; | ||
| 1043 | } | ||
| 1044 | /* write_protect */ | ||
| 1045 | if (boarddata->wp_type == ESDHC_WP_GPIO && !dt) { | ||
| 1046 | err = mmc_gpio_request_ro(host->mmc, boarddata->wp_gpio); | ||
| 1047 | if (err) { | ||
| 1048 | dev_err(mmc_dev(host->mmc), | ||
| 1049 | "failed to request write-protect gpio!\n"); | ||
| 1050 | goto disable_clk; | ||
| 1051 | } | ||
| 1052 | host->mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH; | ||
| 1053 | } | ||
| 1054 | |||
| 1055 | /* card_detect */ | ||
| 1056 | switch (boarddata->cd_type) { | ||
| 1057 | case ESDHC_CD_GPIO: | ||
| 1058 | if (dt) | ||
| 1059 | break; | ||
| 1060 | err = mmc_gpio_request_cd(host->mmc, boarddata->cd_gpio, 0); | ||
| 1061 | if (err) { | ||
| 1062 | dev_err(mmc_dev(host->mmc), | ||
| 1063 | "failed to request card-detect gpio!\n"); | ||
| 1064 | goto disable_clk; | ||
| 1065 | } | ||
| 1066 | /* fall through */ | ||
| 1067 | |||
| 1068 | case ESDHC_CD_CONTROLLER: | ||
| 1069 | /* we have a working card_detect back */ | ||
| 1070 | host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; | ||
| 1071 | break; | ||
| 1072 | |||
| 1073 | case ESDHC_CD_PERMANENT: | ||
| 1074 | host->mmc->caps |= MMC_CAP_NONREMOVABLE; | ||
| 1075 | break; | ||
| 1076 | |||
| 1077 | case ESDHC_CD_NONE: | ||
| 1078 | break; | ||
| 1079 | } | ||
| 1080 | |||
| 1081 | switch (boarddata->max_bus_width) { | ||
| 1082 | case 8: | ||
| 1083 | host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA; | ||
| 1084 | break; | ||
| 1085 | case 4: | ||
| 1086 | host->mmc->caps |= MMC_CAP_4_BIT_DATA; | ||
| 1087 | break; | ||
| 1088 | case 1: | ||
| 1089 | default: | ||
| 1090 | host->quirks |= SDHCI_QUIRK_FORCE_1_BIT_DATA; | ||
| 1091 | break; | ||
| 1092 | } | ||
| 1093 | |||
| 1094 | /* sdr50 and sdr104 needs work on 1.8v signal voltage */ | ||
| 1095 | if ((boarddata->support_vsel) && esdhc_is_usdhc(imx_data) && | ||
| 1096 | !IS_ERR(imx_data->pins_default)) { | ||
| 1097 | imx_data->pins_100mhz = pinctrl_lookup_state(imx_data->pinctrl, | ||
| 1098 | ESDHC_PINCTRL_STATE_100MHZ); | ||
| 1099 | imx_data->pins_200mhz = pinctrl_lookup_state(imx_data->pinctrl, | ||
| 1100 | ESDHC_PINCTRL_STATE_200MHZ); | ||
| 1101 | if (IS_ERR(imx_data->pins_100mhz) || | ||
| 1102 | IS_ERR(imx_data->pins_200mhz)) { | ||
| 1103 | dev_warn(mmc_dev(host->mmc), | ||
| 1104 | "could not get ultra high speed state, work on normal mode\n"); | ||
| 1105 | /* fall back to not support uhs by specify no 1.8v quirk */ | ||
| 1106 | host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V; | ||
| 1107 | } | ||
| 1108 | } else { | ||
| 1109 | host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V; | ||
| 1110 | } | ||
| 1111 | 1109 | ||
| 1112 | err = sdhci_add_host(host); | 1110 | err = sdhci_add_host(host); |
| 1113 | if (err) | 1111 | if (err) |
