14cdc2ec1Saddy ke /* 24cdc2ec1Saddy ke * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd 34cdc2ec1Saddy ke * 44cdc2ec1Saddy ke * This program is free software; you can redistribute it and/or modify 54cdc2ec1Saddy ke * it under the terms of the GNU General Public License as published by 64cdc2ec1Saddy ke * the Free Software Foundation; either version 2 of the License, or 74cdc2ec1Saddy ke * (at your option) any later version. 84cdc2ec1Saddy ke */ 94cdc2ec1Saddy ke 104cdc2ec1Saddy ke #include <linux/module.h> 114cdc2ec1Saddy ke #include <linux/platform_device.h> 124cdc2ec1Saddy ke #include <linux/clk.h> 134cdc2ec1Saddy ke #include <linux/mmc/host.h> 144cdc2ec1Saddy ke #include <linux/mmc/dw_mmc.h> 154cdc2ec1Saddy ke #include <linux/of_address.h> 164cdc2ec1Saddy ke 174cdc2ec1Saddy ke #include "dw_mmc.h" 184cdc2ec1Saddy ke #include "dw_mmc-pltfm.h" 194cdc2ec1Saddy ke 204cdc2ec1Saddy ke #define RK3288_CLKGEN_DIV 2 214cdc2ec1Saddy ke 224cdc2ec1Saddy ke static void dw_mci_rockchip_prepare_command(struct dw_mci *host, u32 *cmdr) 234cdc2ec1Saddy ke { 244cdc2ec1Saddy ke *cmdr |= SDMMC_CMD_USE_HOLD_REG; 254cdc2ec1Saddy ke } 264cdc2ec1Saddy ke 274cdc2ec1Saddy ke static int dw_mci_rk3288_setup_clock(struct dw_mci *host) 284cdc2ec1Saddy ke { 294cdc2ec1Saddy ke host->bus_hz /= RK3288_CLKGEN_DIV; 304cdc2ec1Saddy ke 314cdc2ec1Saddy ke return 0; 324cdc2ec1Saddy ke } 334cdc2ec1Saddy ke 344cdc2ec1Saddy ke static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios) 354cdc2ec1Saddy ke { 364cdc2ec1Saddy ke int ret; 374cdc2ec1Saddy ke unsigned int cclkin; 384cdc2ec1Saddy ke u32 bus_hz; 394cdc2ec1Saddy ke 40e7791079SDoug Anderson if (ios->clock == 0) 41e7791079SDoug Anderson return; 42e7791079SDoug Anderson 434cdc2ec1Saddy ke /* 444cdc2ec1Saddy ke * cclkin: source clock of mmc controller 454cdc2ec1Saddy ke * bus_hz: card interface clock generated by CLKGEN 464cdc2ec1Saddy ke * bus_hz = cclkin / RK3288_CLKGEN_DIV 474cdc2ec1Saddy ke * ios->clock = (div == 0) ? bus_hz : (bus_hz / (2 * div)) 484cdc2ec1Saddy ke * 494cdc2ec1Saddy ke * Note: div can only be 0 or 1 504cdc2ec1Saddy ke * if DDR50 8bit mode(only emmc work in 8bit mode), 514cdc2ec1Saddy ke * div must be set 1 524cdc2ec1Saddy ke */ 534cdc2ec1Saddy ke if (ios->bus_width == MMC_BUS_WIDTH_8 && 544cdc2ec1Saddy ke ios->timing == MMC_TIMING_MMC_DDR52) 554cdc2ec1Saddy ke cclkin = 2 * ios->clock * RK3288_CLKGEN_DIV; 564cdc2ec1Saddy ke else 574cdc2ec1Saddy ke cclkin = ios->clock * RK3288_CLKGEN_DIV; 584cdc2ec1Saddy ke 594cdc2ec1Saddy ke ret = clk_set_rate(host->ciu_clk, cclkin); 604cdc2ec1Saddy ke if (ret) 614cdc2ec1Saddy ke dev_warn(host->dev, "failed to set rate %uHz\n", ios->clock); 624cdc2ec1Saddy ke 634cdc2ec1Saddy ke bus_hz = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV; 644cdc2ec1Saddy ke if (bus_hz != host->bus_hz) { 654cdc2ec1Saddy ke host->bus_hz = bus_hz; 664cdc2ec1Saddy ke /* force dw_mci_setup_bus() */ 674cdc2ec1Saddy ke host->current_speed = 0; 684cdc2ec1Saddy ke } 694cdc2ec1Saddy ke } 704cdc2ec1Saddy ke 714cdc2ec1Saddy ke static const struct dw_mci_drv_data rk2928_drv_data = { 724cdc2ec1Saddy ke .prepare_command = dw_mci_rockchip_prepare_command, 734cdc2ec1Saddy ke }; 744cdc2ec1Saddy ke 754cdc2ec1Saddy ke static const struct dw_mci_drv_data rk3288_drv_data = { 764cdc2ec1Saddy ke .prepare_command = dw_mci_rockchip_prepare_command, 774cdc2ec1Saddy ke .set_ios = dw_mci_rk3288_set_ios, 784cdc2ec1Saddy ke .setup_clock = dw_mci_rk3288_setup_clock, 794cdc2ec1Saddy ke }; 804cdc2ec1Saddy ke 814cdc2ec1Saddy ke static const struct of_device_id dw_mci_rockchip_match[] = { 824cdc2ec1Saddy ke { .compatible = "rockchip,rk2928-dw-mshc", 834cdc2ec1Saddy ke .data = &rk2928_drv_data }, 844cdc2ec1Saddy ke { .compatible = "rockchip,rk3288-dw-mshc", 854cdc2ec1Saddy ke .data = &rk3288_drv_data }, 864cdc2ec1Saddy ke {}, 874cdc2ec1Saddy ke }; 884cdc2ec1Saddy ke MODULE_DEVICE_TABLE(of, dw_mci_rockchip_match); 894cdc2ec1Saddy ke 904cdc2ec1Saddy ke static int dw_mci_rockchip_probe(struct platform_device *pdev) 914cdc2ec1Saddy ke { 924cdc2ec1Saddy ke const struct dw_mci_drv_data *drv_data; 934cdc2ec1Saddy ke const struct of_device_id *match; 944cdc2ec1Saddy ke 954cdc2ec1Saddy ke if (!pdev->dev.of_node) 964cdc2ec1Saddy ke return -ENODEV; 974cdc2ec1Saddy ke 984cdc2ec1Saddy ke match = of_match_node(dw_mci_rockchip_match, pdev->dev.of_node); 994cdc2ec1Saddy ke drv_data = match->data; 1004cdc2ec1Saddy ke 1014cdc2ec1Saddy ke return dw_mci_pltfm_register(pdev, drv_data); 1024cdc2ec1Saddy ke } 1034cdc2ec1Saddy ke 1044cdc2ec1Saddy ke #ifdef CONFIG_PM_SLEEP 1054cdc2ec1Saddy ke static int dw_mci_rockchip_suspend(struct device *dev) 1064cdc2ec1Saddy ke { 1074cdc2ec1Saddy ke struct dw_mci *host = dev_get_drvdata(dev); 1084cdc2ec1Saddy ke 1094cdc2ec1Saddy ke return dw_mci_suspend(host); 1104cdc2ec1Saddy ke } 1114cdc2ec1Saddy ke 1124cdc2ec1Saddy ke static int dw_mci_rockchip_resume(struct device *dev) 1134cdc2ec1Saddy ke { 1144cdc2ec1Saddy ke struct dw_mci *host = dev_get_drvdata(dev); 1154cdc2ec1Saddy ke 1164cdc2ec1Saddy ke return dw_mci_resume(host); 1174cdc2ec1Saddy ke } 1184cdc2ec1Saddy ke #endif /* CONFIG_PM_SLEEP */ 1194cdc2ec1Saddy ke 1204cdc2ec1Saddy ke static SIMPLE_DEV_PM_OPS(dw_mci_rockchip_pmops, 1214cdc2ec1Saddy ke dw_mci_rockchip_suspend, 1224cdc2ec1Saddy ke dw_mci_rockchip_resume); 1234cdc2ec1Saddy ke 1244cdc2ec1Saddy ke static struct platform_driver dw_mci_rockchip_pltfm_driver = { 1254cdc2ec1Saddy ke .probe = dw_mci_rockchip_probe, 1264cdc2ec1Saddy ke .remove = __exit_p(dw_mci_pltfm_remove), 1274cdc2ec1Saddy ke .driver = { 1284cdc2ec1Saddy ke .name = "dwmmc_rockchip", 1294cdc2ec1Saddy ke .of_match_table = dw_mci_rockchip_match, 1304cdc2ec1Saddy ke .pm = &dw_mci_rockchip_pmops, 1314cdc2ec1Saddy ke }, 1324cdc2ec1Saddy ke }; 1334cdc2ec1Saddy ke 1344cdc2ec1Saddy ke module_platform_driver(dw_mci_rockchip_pltfm_driver); 1354cdc2ec1Saddy ke 1364cdc2ec1Saddy ke MODULE_AUTHOR("Addy Ke <addy.ke@rock-chips.com>"); 1374cdc2ec1Saddy ke MODULE_DESCRIPTION("Rockchip Specific DW-MSHC Driver Extension"); 1384cdc2ec1Saddy ke MODULE_ALIAS("platform:dwmmc-rockchip"); 1394cdc2ec1Saddy ke MODULE_LICENSE("GPL v2"); 140