1985b1aa0SMike Rapoport /* 2985b1aa0SMike Rapoport * sdhci-dove.c Support for SDHCI on Marvell's Dove SoC 3985b1aa0SMike Rapoport * 4985b1aa0SMike Rapoport * Author: Saeed Bishara <saeed@marvell.com> 5985b1aa0SMike Rapoport * Mike Rapoport <mike@compulab.co.il> 6985b1aa0SMike Rapoport * Based on sdhci-cns3xxx.c 7985b1aa0SMike Rapoport * 8985b1aa0SMike Rapoport * This program is free software; you can redistribute it and/or modify 9985b1aa0SMike Rapoport * it under the terms of the GNU General Public License version 2 as 10985b1aa0SMike Rapoport * published by the Free Software Foundation. 11985b1aa0SMike Rapoport * 12985b1aa0SMike Rapoport * This program is distributed in the hope that it will be useful, 13985b1aa0SMike Rapoport * but WITHOUT ANY WARRANTY; without even the implied warranty of 14985b1aa0SMike Rapoport * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15985b1aa0SMike Rapoport * GNU General Public License for more details. 16985b1aa0SMike Rapoport * 17985b1aa0SMike Rapoport * You should have received a copy of the GNU General Public License 18985b1aa0SMike Rapoport * along with this program; if not, write to the Free Software 19985b1aa0SMike Rapoport * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20985b1aa0SMike Rapoport */ 21985b1aa0SMike Rapoport 2230b87c60SSebastian Hesselbarth #include <linux/clk.h> 2330b87c60SSebastian Hesselbarth #include <linux/err.h> 24f8ec589bSRussell King #include <linux/io.h> 25985b1aa0SMike Rapoport #include <linux/mmc/host.h> 26f8ec589bSRussell King #include <linux/module.h> 274ee7ed0dSSebastian Hesselbarth #include <linux/of.h> 28985b1aa0SMike Rapoport 29985b1aa0SMike Rapoport #include "sdhci-pltfm.h" 30985b1aa0SMike Rapoport 31985b1aa0SMike Rapoport static u16 sdhci_dove_readw(struct sdhci_host *host, int reg) 32985b1aa0SMike Rapoport { 33985b1aa0SMike Rapoport u16 ret; 34985b1aa0SMike Rapoport 35985b1aa0SMike Rapoport switch (reg) { 36985b1aa0SMike Rapoport case SDHCI_HOST_VERSION: 37985b1aa0SMike Rapoport case SDHCI_SLOT_INT_STATUS: 38985b1aa0SMike Rapoport /* those registers don't exist */ 39985b1aa0SMike Rapoport return 0; 40985b1aa0SMike Rapoport default: 41985b1aa0SMike Rapoport ret = readw(host->ioaddr + reg); 42985b1aa0SMike Rapoport } 43985b1aa0SMike Rapoport return ret; 44985b1aa0SMike Rapoport } 45985b1aa0SMike Rapoport 46985b1aa0SMike Rapoport static u32 sdhci_dove_readl(struct sdhci_host *host, int reg) 47985b1aa0SMike Rapoport { 48985b1aa0SMike Rapoport u32 ret; 49985b1aa0SMike Rapoport 50f8ec589bSRussell King ret = readl(host->ioaddr + reg); 51f8ec589bSRussell King 52985b1aa0SMike Rapoport switch (reg) { 53985b1aa0SMike Rapoport case SDHCI_CAPABILITIES: 54985b1aa0SMike Rapoport /* Mask the support for 3.0V */ 55985b1aa0SMike Rapoport ret &= ~SDHCI_CAN_VDD_300; 56985b1aa0SMike Rapoport break; 57985b1aa0SMike Rapoport } 58985b1aa0SMike Rapoport return ret; 59985b1aa0SMike Rapoport } 60985b1aa0SMike Rapoport 61c915568dSLars-Peter Clausen static const struct sdhci_ops sdhci_dove_ops = { 62985b1aa0SMike Rapoport .read_w = sdhci_dove_readw, 63985b1aa0SMike Rapoport .read_l = sdhci_dove_readl, 641771059cSRussell King .set_clock = sdhci_set_clock, 652317f56cSRussell King .set_bus_width = sdhci_set_bus_width, 6603231f9bSRussell King .reset = sdhci_reset, 6796d7b78cSRussell King .set_uhs_signaling = sdhci_set_uhs_signaling, 68985b1aa0SMike Rapoport }; 69985b1aa0SMike Rapoport 701db5eebfSLars-Peter Clausen static const struct sdhci_pltfm_data sdhci_dove_pdata = { 71985b1aa0SMike Rapoport .ops = &sdhci_dove_ops, 72985b1aa0SMike Rapoport .quirks = SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER | 73985b1aa0SMike Rapoport SDHCI_QUIRK_NO_BUSY_IRQ | 74985b1aa0SMike Rapoport SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | 75a9ca1d54SSebastian Hesselbarth SDHCI_QUIRK_FORCE_DMA | 76a9ca1d54SSebastian Hesselbarth SDHCI_QUIRK_NO_HISPD_BIT, 77985b1aa0SMike Rapoport }; 7885d6509dSShawn Guo 79c3be1efdSBill Pemberton static int sdhci_dove_probe(struct platform_device *pdev) 8085d6509dSShawn Guo { 8130b87c60SSebastian Hesselbarth struct sdhci_host *host; 8230b87c60SSebastian Hesselbarth struct sdhci_pltfm_host *pltfm_host; 8330b87c60SSebastian Hesselbarth int ret; 8430b87c60SSebastian Hesselbarth 850e748234SChristian Daudt host = sdhci_pltfm_init(pdev, &sdhci_dove_pdata, 0); 86c5ee2490SSebastian Hesselbarth if (IS_ERR(host)) 87c5ee2490SSebastian Hesselbarth return PTR_ERR(host); 88ee3298a2SRussell King - ARM Linux 8930b87c60SSebastian Hesselbarth pltfm_host = sdhci_priv(host); 9035daeedeSKevin Hao pltfm_host->clk = devm_clk_get(&pdev->dev, NULL); 9130b87c60SSebastian Hesselbarth 9235daeedeSKevin Hao if (!IS_ERR(pltfm_host->clk)) 9335daeedeSKevin Hao clk_prepare_enable(pltfm_host->clk); 94c430689fSRussell King 95c5ee2490SSebastian Hesselbarth ret = mmc_of_parse(host->mmc); 96c5ee2490SSebastian Hesselbarth if (ret) 97c5ee2490SSebastian Hesselbarth goto err_sdhci_add; 98c430689fSRussell King 99c430689fSRussell King ret = sdhci_add_host(host); 100c430689fSRussell King if (ret) 101c430689fSRussell King goto err_sdhci_add; 102c430689fSRussell King 10330b87c60SSebastian Hesselbarth return 0; 10430b87c60SSebastian Hesselbarth 105c430689fSRussell King err_sdhci_add: 10635daeedeSKevin Hao clk_disable_unprepare(pltfm_host->clk); 107c430689fSRussell King sdhci_pltfm_free(pdev); 10830b87c60SSebastian Hesselbarth return ret; 10985d6509dSShawn Guo } 11085d6509dSShawn Guo 111498d83e7SBill Pemberton static const struct of_device_id sdhci_dove_of_match_table[] = { 1124ee7ed0dSSebastian Hesselbarth { .compatible = "marvell,dove-sdhci", }, 1134ee7ed0dSSebastian Hesselbarth {} 1144ee7ed0dSSebastian Hesselbarth }; 1154ee7ed0dSSebastian Hesselbarth MODULE_DEVICE_TABLE(of, sdhci_dove_of_match_table); 1164ee7ed0dSSebastian Hesselbarth 11785d6509dSShawn Guo static struct platform_driver sdhci_dove_driver = { 11885d6509dSShawn Guo .driver = { 11985d6509dSShawn Guo .name = "sdhci-dove", 120fa243f64SUlf Hansson .pm = &sdhci_pltfm_pmops, 1215941fd07SSachin Kamat .of_match_table = sdhci_dove_of_match_table, 12285d6509dSShawn Guo }, 12385d6509dSShawn Guo .probe = sdhci_dove_probe, 124caebcae9SKevin Hao .remove = sdhci_pltfm_unregister, 12585d6509dSShawn Guo }; 12685d6509dSShawn Guo 127d1f81a64SAxel Lin module_platform_driver(sdhci_dove_driver); 12885d6509dSShawn Guo 12985d6509dSShawn Guo MODULE_DESCRIPTION("SDHCI driver for Dove"); 13085d6509dSShawn Guo MODULE_AUTHOR("Saeed Bishara <saeed@marvell.com>, " 13185d6509dSShawn Guo "Mike Rapoport <mike@compulab.co.il>"); 13285d6509dSShawn Guo MODULE_LICENSE("GPL v2"); 133