Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * sdhci-pci-arasan.c - Driver for Arasan PCI Controller with
0004  * integrated phy.
0005  *
0006  * Copyright (C) 2017 Arasan Chip Systems Inc.
0007  *
0008  * Author: Atul Garg <agarg@arasan.com>
0009  */
0010 
0011 #include <linux/pci.h>
0012 #include <linux/delay.h>
0013 
0014 #include "sdhci.h"
0015 #include "sdhci-pci.h"
0016 
0017 /* Extra registers for Arasan SD/SDIO/MMC Host Controller with PHY */
0018 #define PHY_ADDR_REG    0x300
0019 #define PHY_DAT_REG 0x304
0020 
0021 #define PHY_WRITE   BIT(8)
0022 #define PHY_BUSY    BIT(9)
0023 #define DATA_MASK   0xFF
0024 
0025 /* PHY Specific Registers */
0026 #define DLL_STATUS  0x00
0027 #define IPAD_CTRL1  0x01
0028 #define IPAD_CTRL2  0x02
0029 #define IPAD_STS    0x03
0030 #define IOREN_CTRL1 0x06
0031 #define IOREN_CTRL2 0x07
0032 #define IOPU_CTRL1  0x08
0033 #define IOPU_CTRL2  0x09
0034 #define ITAP_DELAY  0x0C
0035 #define OTAP_DELAY  0x0D
0036 #define STRB_SEL    0x0E
0037 #define CLKBUF_SEL  0x0F
0038 #define MODE_CTRL   0x11
0039 #define DLL_TRIM    0x12
0040 #define CMD_CTRL    0x20
0041 #define DATA_CTRL   0x21
0042 #define STRB_CTRL   0x22
0043 #define CLK_CTRL    0x23
0044 #define PHY_CTRL    0x24
0045 
0046 #define DLL_ENBL    BIT(3)
0047 #define RTRIM_EN    BIT(1)
0048 #define PDB_ENBL    BIT(1)
0049 #define RETB_ENBL   BIT(6)
0050 #define ODEN_CMD    BIT(1)
0051 #define ODEN_DAT    0xFF
0052 #define REN_STRB    BIT(0)
0053 #define REN_CMND    BIT(1)
0054 #define REN_DATA    0xFF
0055 #define PU_CMD      BIT(1)
0056 #define PU_DAT      0xFF
0057 #define ITAPDLY_EN  BIT(0)
0058 #define OTAPDLY_EN  BIT(0)
0059 #define OD_REL_CMD  BIT(1)
0060 #define OD_REL_DAT  0xFF
0061 #define DLLTRM_ICP  0x8
0062 #define PDB_CMND    BIT(0)
0063 #define PDB_DATA    0xFF
0064 #define PDB_STRB    BIT(0)
0065 #define PDB_CLOCK   BIT(0)
0066 #define CALDONE_MASK    0x10
0067 #define DLL_RDY_MASK    0x10
0068 #define MAX_CLK_BUF 0x7
0069 
0070 /* Mode Controls */
0071 #define ENHSTRB_MODE    BIT(0)
0072 #define HS400_MODE  BIT(1)
0073 #define LEGACY_MODE BIT(2)
0074 #define DDR50_MODE  BIT(3)
0075 
0076 /*
0077  * Controller has no specific bits for HS200/HS.
0078  * Used BIT(4), BIT(5) for software programming.
0079  */
0080 #define HS200_MODE  BIT(4)
0081 #define HISPD_MODE  BIT(5)
0082 
0083 #define OTAPDLY(x)  (((x) << 1) | OTAPDLY_EN)
0084 #define ITAPDLY(x)  (((x) << 1) | ITAPDLY_EN)
0085 #define FREQSEL(x)  (((x) << 5) | DLL_ENBL)
0086 #define IOPAD(x, y) ((x) | ((y) << 2))
0087 
0088 /* Arasan private data */
0089 struct arasan_host {
0090     u32 chg_clk;
0091 };
0092 
0093 static int arasan_phy_addr_poll(struct sdhci_host *host, u32 offset, u32 mask)
0094 {
0095     ktime_t timeout = ktime_add_us(ktime_get(), 100);
0096     bool failed;
0097     u8 val = 0;
0098 
0099     while (1) {
0100         failed = ktime_after(ktime_get(), timeout);
0101         val = sdhci_readw(host, PHY_ADDR_REG);
0102         if (!(val & mask))
0103             return 0;
0104         if (failed)
0105             return -EBUSY;
0106     }
0107 }
0108 
0109 static int arasan_phy_write(struct sdhci_host *host, u8 data, u8 offset)
0110 {
0111     sdhci_writew(host, data, PHY_DAT_REG);
0112     sdhci_writew(host, (PHY_WRITE | offset), PHY_ADDR_REG);
0113     return arasan_phy_addr_poll(host, PHY_ADDR_REG, PHY_BUSY);
0114 }
0115 
0116 static int arasan_phy_read(struct sdhci_host *host, u8 offset, u8 *data)
0117 {
0118     int ret;
0119 
0120     sdhci_writew(host, 0, PHY_DAT_REG);
0121     sdhci_writew(host, offset, PHY_ADDR_REG);
0122     ret = arasan_phy_addr_poll(host, PHY_ADDR_REG, PHY_BUSY);
0123 
0124     /* Masking valid data bits */
0125     *data = sdhci_readw(host, PHY_DAT_REG) & DATA_MASK;
0126     return ret;
0127 }
0128 
0129 static int arasan_phy_sts_poll(struct sdhci_host *host, u32 offset, u32 mask)
0130 {
0131     int ret;
0132     ktime_t timeout = ktime_add_us(ktime_get(), 100);
0133     bool failed;
0134     u8 val = 0;
0135 
0136     while (1) {
0137         failed = ktime_after(ktime_get(), timeout);
0138         ret = arasan_phy_read(host, offset, &val);
0139         if (ret)
0140             return -EBUSY;
0141         else if (val & mask)
0142             return 0;
0143         if (failed)
0144             return -EBUSY;
0145     }
0146 }
0147 
0148 /* Initialize the Arasan PHY */
0149 static int arasan_phy_init(struct sdhci_host *host)
0150 {
0151     int ret;
0152     u8 val;
0153 
0154     /* Program IOPADs and wait for calibration to be done */
0155     if (arasan_phy_read(host, IPAD_CTRL1, &val) ||
0156         arasan_phy_write(host, val | RETB_ENBL | PDB_ENBL, IPAD_CTRL1) ||
0157         arasan_phy_read(host, IPAD_CTRL2, &val) ||
0158         arasan_phy_write(host, val | RTRIM_EN, IPAD_CTRL2))
0159         return -EBUSY;
0160     ret = arasan_phy_sts_poll(host, IPAD_STS, CALDONE_MASK);
0161     if (ret)
0162         return -EBUSY;
0163 
0164     /* Program CMD/Data lines */
0165     if (arasan_phy_read(host, IOREN_CTRL1, &val) ||
0166         arasan_phy_write(host, val | REN_CMND | REN_STRB, IOREN_CTRL1) ||
0167         arasan_phy_read(host, IOPU_CTRL1, &val) ||
0168         arasan_phy_write(host, val | PU_CMD, IOPU_CTRL1) ||
0169         arasan_phy_read(host, CMD_CTRL, &val) ||
0170         arasan_phy_write(host, val | PDB_CMND, CMD_CTRL) ||
0171         arasan_phy_read(host, IOREN_CTRL2, &val) ||
0172         arasan_phy_write(host, val | REN_DATA, IOREN_CTRL2) ||
0173         arasan_phy_read(host, IOPU_CTRL2, &val) ||
0174         arasan_phy_write(host, val | PU_DAT, IOPU_CTRL2) ||
0175         arasan_phy_read(host, DATA_CTRL, &val) ||
0176         arasan_phy_write(host, val | PDB_DATA, DATA_CTRL) ||
0177         arasan_phy_read(host, STRB_CTRL, &val) ||
0178         arasan_phy_write(host, val | PDB_STRB, STRB_CTRL) ||
0179         arasan_phy_read(host, CLK_CTRL, &val) ||
0180         arasan_phy_write(host, val | PDB_CLOCK, CLK_CTRL) ||
0181         arasan_phy_read(host, CLKBUF_SEL, &val) ||
0182         arasan_phy_write(host, val | MAX_CLK_BUF, CLKBUF_SEL) ||
0183         arasan_phy_write(host, LEGACY_MODE, MODE_CTRL))
0184         return -EBUSY;
0185     return 0;
0186 }
0187 
0188 /* Set Arasan PHY for different modes */
0189 static int arasan_phy_set(struct sdhci_host *host, u8 mode, u8 otap,
0190               u8 drv_type, u8 itap, u8 trim, u8 clk)
0191 {
0192     u8 val;
0193     int ret;
0194 
0195     if (mode == HISPD_MODE || mode == HS200_MODE)
0196         ret = arasan_phy_write(host, 0x0, MODE_CTRL);
0197     else
0198         ret = arasan_phy_write(host, mode, MODE_CTRL);
0199     if (ret)
0200         return ret;
0201     if (mode == HS400_MODE || mode == HS200_MODE) {
0202         ret = arasan_phy_read(host, IPAD_CTRL1, &val);
0203         if (ret)
0204             return ret;
0205         ret = arasan_phy_write(host, IOPAD(val, drv_type), IPAD_CTRL1);
0206         if (ret)
0207             return ret;
0208     }
0209     if (mode == LEGACY_MODE) {
0210         ret = arasan_phy_write(host, 0x0, OTAP_DELAY);
0211         if (ret)
0212             return ret;
0213         ret = arasan_phy_write(host, 0x0, ITAP_DELAY);
0214     } else {
0215         ret = arasan_phy_write(host, OTAPDLY(otap), OTAP_DELAY);
0216         if (ret)
0217             return ret;
0218         if (mode != HS200_MODE)
0219             ret = arasan_phy_write(host, ITAPDLY(itap), ITAP_DELAY);
0220         else
0221             ret = arasan_phy_write(host, 0x0, ITAP_DELAY);
0222     }
0223     if (ret)
0224         return ret;
0225     if (mode != LEGACY_MODE) {
0226         ret = arasan_phy_write(host, trim, DLL_TRIM);
0227         if (ret)
0228             return ret;
0229     }
0230     ret = arasan_phy_write(host, 0, DLL_STATUS);
0231     if (ret)
0232         return ret;
0233     if (mode != LEGACY_MODE) {
0234         ret = arasan_phy_write(host, FREQSEL(clk), DLL_STATUS);
0235         if (ret)
0236             return ret;
0237         ret = arasan_phy_sts_poll(host, DLL_STATUS, DLL_RDY_MASK);
0238         if (ret)
0239             return -EBUSY;
0240     }
0241     return 0;
0242 }
0243 
0244 static int arasan_select_phy_clock(struct sdhci_host *host)
0245 {
0246     struct sdhci_pci_slot *slot = sdhci_priv(host);
0247     struct arasan_host *arasan_host = sdhci_pci_priv(slot);
0248     u8 clk;
0249 
0250     if (arasan_host->chg_clk == host->mmc->ios.clock)
0251         return 0;
0252 
0253     arasan_host->chg_clk = host->mmc->ios.clock;
0254     if (host->mmc->ios.clock == 200000000)
0255         clk = 0x0;
0256     else if (host->mmc->ios.clock == 100000000)
0257         clk = 0x2;
0258     else if (host->mmc->ios.clock == 50000000)
0259         clk = 0x1;
0260     else
0261         clk = 0x0;
0262 
0263     if (host->mmc_host_ops.hs400_enhanced_strobe) {
0264         arasan_phy_set(host, ENHSTRB_MODE, 1, 0x0, 0x0,
0265                    DLLTRM_ICP, clk);
0266     } else {
0267         switch (host->mmc->ios.timing) {
0268         case MMC_TIMING_LEGACY:
0269             arasan_phy_set(host, LEGACY_MODE, 0x0, 0x0, 0x0,
0270                        0x0, 0x0);
0271             break;
0272         case MMC_TIMING_MMC_HS:
0273         case MMC_TIMING_SD_HS:
0274             arasan_phy_set(host, HISPD_MODE, 0x3, 0x0, 0x2,
0275                        DLLTRM_ICP, clk);
0276             break;
0277         case MMC_TIMING_MMC_HS200:
0278         case MMC_TIMING_UHS_SDR104:
0279             arasan_phy_set(host, HS200_MODE, 0x2,
0280                        host->mmc->ios.drv_type, 0x0,
0281                        DLLTRM_ICP, clk);
0282             break;
0283         case MMC_TIMING_MMC_DDR52:
0284         case MMC_TIMING_UHS_DDR50:
0285             arasan_phy_set(host, DDR50_MODE, 0x1, 0x0,
0286                        0x0, DLLTRM_ICP, clk);
0287             break;
0288         case MMC_TIMING_MMC_HS400:
0289             arasan_phy_set(host, HS400_MODE, 0x1,
0290                        host->mmc->ios.drv_type, 0xa,
0291                        DLLTRM_ICP, clk);
0292             break;
0293         default:
0294             break;
0295         }
0296     }
0297     return 0;
0298 }
0299 
0300 static int arasan_pci_probe_slot(struct sdhci_pci_slot *slot)
0301 {
0302     int err;
0303 
0304     slot->host->mmc->caps |= MMC_CAP_NONREMOVABLE | MMC_CAP_8_BIT_DATA;
0305     err = arasan_phy_init(slot->host);
0306     if (err)
0307         return -ENODEV;
0308     return 0;
0309 }
0310 
0311 static void arasan_sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
0312 {
0313     sdhci_set_clock(host, clock);
0314 
0315     /* Change phy settings for the new clock */
0316     arasan_select_phy_clock(host);
0317 }
0318 
0319 static const struct sdhci_ops arasan_sdhci_pci_ops = {
0320     .set_clock  = arasan_sdhci_set_clock,
0321     .enable_dma = sdhci_pci_enable_dma,
0322     .set_bus_width  = sdhci_set_bus_width,
0323     .reset      = sdhci_reset,
0324     .set_uhs_signaling  = sdhci_set_uhs_signaling,
0325 };
0326 
0327 const struct sdhci_pci_fixes sdhci_arasan = {
0328     .probe_slot = arasan_pci_probe_slot,
0329     .ops        = &arasan_sdhci_pci_ops,
0330     .priv_size  = sizeof(struct arasan_host),
0331 };