linux/drivers/mmc/host/sdhci-pci-o2micro.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2013 BayHub Technology Ltd.
   3 *
   4 * Authors: Peter Guo <peter.guo@bayhubtech.com>
   5 *          Adam Lee <adam.lee@canonical.com>
   6 *
   7 * This software is licensed under the terms of the GNU General Public
   8 * License version 2, as published by the Free Software Foundation, and
   9 * may be copied, distributed, and modified under those terms.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 *
  16 */
  17
  18#include <linux/pci.h>
  19
  20#include "sdhci.h"
  21#include "sdhci-pci.h"
  22#include "sdhci-pci-o2micro.h"
  23
  24static void o2_pci_set_baseclk(struct sdhci_pci_chip *chip, u32 value)
  25{
  26        u32 scratch_32;
  27        pci_read_config_dword(chip->pdev,
  28                              O2_SD_PLL_SETTING, &scratch_32);
  29
  30        scratch_32 &= 0x0000FFFF;
  31        scratch_32 |= value;
  32
  33        pci_write_config_dword(chip->pdev,
  34                               O2_SD_PLL_SETTING, scratch_32);
  35}
  36
  37static void o2_pci_led_enable(struct sdhci_pci_chip *chip)
  38{
  39        int ret;
  40        u32 scratch_32;
  41
  42        /* Set led of SD host function enable */
  43        ret = pci_read_config_dword(chip->pdev,
  44                                    O2_SD_FUNC_REG0, &scratch_32);
  45        if (ret)
  46                return;
  47
  48        scratch_32 &= ~O2_SD_FREG0_LEDOFF;
  49        pci_write_config_dword(chip->pdev,
  50                               O2_SD_FUNC_REG0, scratch_32);
  51
  52        ret = pci_read_config_dword(chip->pdev,
  53                                    O2_SD_TEST_REG, &scratch_32);
  54        if (ret)
  55                return;
  56
  57        scratch_32 |= O2_SD_LED_ENABLE;
  58        pci_write_config_dword(chip->pdev,
  59                               O2_SD_TEST_REG, scratch_32);
  60
  61}
  62
  63static void sdhci_pci_o2_fujin2_pci_init(struct sdhci_pci_chip *chip)
  64{
  65        u32 scratch_32;
  66        int ret;
  67        /* Improve write performance for SD3.0 */
  68        ret = pci_read_config_dword(chip->pdev, O2_SD_DEV_CTRL, &scratch_32);
  69        if (ret)
  70                return;
  71        scratch_32 &= ~((1 << 12) | (1 << 13) | (1 << 14));
  72        pci_write_config_dword(chip->pdev, O2_SD_DEV_CTRL, scratch_32);
  73
  74        /* Enable Link abnormal reset generating Reset */
  75        ret = pci_read_config_dword(chip->pdev, O2_SD_MISC_REG5, &scratch_32);
  76        if (ret)
  77                return;
  78        scratch_32 &= ~((1 << 19) | (1 << 11));
  79        scratch_32 |= (1 << 10);
  80        pci_write_config_dword(chip->pdev, O2_SD_MISC_REG5, scratch_32);
  81
  82        /* set card power over current protection */
  83        ret = pci_read_config_dword(chip->pdev, O2_SD_TEST_REG, &scratch_32);
  84        if (ret)
  85                return;
  86        scratch_32 |= (1 << 4);
  87        pci_write_config_dword(chip->pdev, O2_SD_TEST_REG, scratch_32);
  88
  89        /* adjust the output delay for SD mode */
  90        pci_write_config_dword(chip->pdev, O2_SD_DELAY_CTRL, 0x00002492);
  91
  92        /* Set the output voltage setting of Aux 1.2v LDO */
  93        ret = pci_read_config_dword(chip->pdev, O2_SD_LD0_CTRL, &scratch_32);
  94        if (ret)
  95                return;
  96        scratch_32 &= ~(3 << 12);
  97        pci_write_config_dword(chip->pdev, O2_SD_LD0_CTRL, scratch_32);
  98
  99        /* Set Max power supply capability of SD host */
 100        ret = pci_read_config_dword(chip->pdev, O2_SD_CAP_REG0, &scratch_32);
 101        if (ret)
 102                return;
 103        scratch_32 &= ~(0x01FE);
 104        scratch_32 |= 0x00CC;
 105        pci_write_config_dword(chip->pdev, O2_SD_CAP_REG0, scratch_32);
 106        /* Set DLL Tuning Window */
 107        ret = pci_read_config_dword(chip->pdev,
 108                                    O2_SD_TUNING_CTRL, &scratch_32);
 109        if (ret)
 110                return;
 111        scratch_32 &= ~(0x000000FF);
 112        scratch_32 |= 0x00000066;
 113        pci_write_config_dword(chip->pdev, O2_SD_TUNING_CTRL, scratch_32);
 114
 115        /* Set UHS2 T_EIDLE */
 116        ret = pci_read_config_dword(chip->pdev,
 117                                    O2_SD_UHS2_L1_CTRL, &scratch_32);
 118        if (ret)
 119                return;
 120        scratch_32 &= ~(0x000000FC);
 121        scratch_32 |= 0x00000084;
 122        pci_write_config_dword(chip->pdev, O2_SD_UHS2_L1_CTRL, scratch_32);
 123
 124        /* Set UHS2 Termination */
 125        ret = pci_read_config_dword(chip->pdev, O2_SD_FUNC_REG3, &scratch_32);
 126        if (ret)
 127                return;
 128        scratch_32 &= ~((1 << 21) | (1 << 30));
 129
 130        pci_write_config_dword(chip->pdev, O2_SD_FUNC_REG3, scratch_32);
 131
 132        /* Set L1 Entrance Timer */
 133        ret = pci_read_config_dword(chip->pdev, O2_SD_CAPS, &scratch_32);
 134        if (ret)
 135                return;
 136        scratch_32 &= ~(0xf0000000);
 137        scratch_32 |= 0x30000000;
 138        pci_write_config_dword(chip->pdev, O2_SD_CAPS, scratch_32);
 139
 140        ret = pci_read_config_dword(chip->pdev,
 141                                    O2_SD_MISC_CTRL4, &scratch_32);
 142        if (ret)
 143                return;
 144        scratch_32 &= ~(0x000f0000);
 145        scratch_32 |= 0x00080000;
 146        pci_write_config_dword(chip->pdev, O2_SD_MISC_CTRL4, scratch_32);
 147}
 148
 149int sdhci_pci_o2_probe_slot(struct sdhci_pci_slot *slot)
 150{
 151        struct sdhci_pci_chip *chip;
 152        struct sdhci_host *host;
 153        u32 reg;
 154
 155        chip = slot->chip;
 156        host = slot->host;
 157        switch (chip->pdev->device) {
 158        case PCI_DEVICE_ID_O2_SDS0:
 159        case PCI_DEVICE_ID_O2_SEABIRD0:
 160        case PCI_DEVICE_ID_O2_SEABIRD1:
 161        case PCI_DEVICE_ID_O2_SDS1:
 162        case PCI_DEVICE_ID_O2_FUJIN2:
 163                reg = sdhci_readl(host, O2_SD_VENDOR_SETTING);
 164                if (reg & 0x1)
 165                        host->quirks |= SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12;
 166
 167                if (chip->pdev->device != PCI_DEVICE_ID_O2_FUJIN2)
 168                        break;
 169                /* set dll watch dog timer */
 170                reg = sdhci_readl(host, O2_SD_VENDOR_SETTING2);
 171                reg |= (1 << 12);
 172                sdhci_writel(host, reg, O2_SD_VENDOR_SETTING2);
 173
 174                break;
 175        default:
 176                break;
 177        }
 178
 179        return 0;
 180}
 181
 182int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip)
 183{
 184        int ret;
 185        u8 scratch;
 186        u32 scratch_32;
 187
 188        switch (chip->pdev->device) {
 189        case PCI_DEVICE_ID_O2_8220:
 190        case PCI_DEVICE_ID_O2_8221:
 191        case PCI_DEVICE_ID_O2_8320:
 192        case PCI_DEVICE_ID_O2_8321:
 193                /* This extra setup is required due to broken ADMA. */
 194                ret = pci_read_config_byte(chip->pdev,
 195                                O2_SD_LOCK_WP, &scratch);
 196                if (ret)
 197                        return ret;
 198                scratch &= 0x7f;
 199                pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
 200
 201                /* Set Multi 3 to VCC3V# */
 202                pci_write_config_byte(chip->pdev, O2_SD_MULTI_VCC3V, 0x08);
 203
 204                /* Disable CLK_REQ# support after media DET */
 205                ret = pci_read_config_byte(chip->pdev,
 206                                O2_SD_CLKREQ, &scratch);
 207                if (ret)
 208                        return ret;
 209                scratch |= 0x20;
 210                pci_write_config_byte(chip->pdev, O2_SD_CLKREQ, scratch);
 211
 212                /* Choose capabilities, enable SDMA.  We have to write 0x01
 213                 * to the capabilities register first to unlock it.
 214                 */
 215                ret = pci_read_config_byte(chip->pdev, O2_SD_CAPS, &scratch);
 216                if (ret)
 217                        return ret;
 218                scratch |= 0x01;
 219                pci_write_config_byte(chip->pdev, O2_SD_CAPS, scratch);
 220                pci_write_config_byte(chip->pdev, O2_SD_CAPS, 0x73);
 221
 222                /* Disable ADMA1/2 */
 223                pci_write_config_byte(chip->pdev, O2_SD_ADMA1, 0x39);
 224                pci_write_config_byte(chip->pdev, O2_SD_ADMA2, 0x08);
 225
 226                /* Disable the infinite transfer mode */
 227                ret = pci_read_config_byte(chip->pdev,
 228                                O2_SD_INF_MOD, &scratch);
 229                if (ret)
 230                        return ret;
 231                scratch |= 0x08;
 232                pci_write_config_byte(chip->pdev, O2_SD_INF_MOD, scratch);
 233
 234                /* Lock WP */
 235                ret = pci_read_config_byte(chip->pdev,
 236                                O2_SD_LOCK_WP, &scratch);
 237                if (ret)
 238                        return ret;
 239                scratch |= 0x80;
 240                pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
 241                break;
 242        case PCI_DEVICE_ID_O2_SDS0:
 243        case PCI_DEVICE_ID_O2_SDS1:
 244        case PCI_DEVICE_ID_O2_FUJIN2:
 245                /* UnLock WP */
 246                ret = pci_read_config_byte(chip->pdev,
 247                                O2_SD_LOCK_WP, &scratch);
 248                if (ret)
 249                        return ret;
 250
 251                scratch &= 0x7f;
 252                pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
 253
 254                /* DevId=8520 subId= 0x11 or 0x12  Type Chip support */
 255                if (chip->pdev->device == PCI_DEVICE_ID_O2_FUJIN2) {
 256                        ret = pci_read_config_dword(chip->pdev,
 257                                                    O2_SD_FUNC_REG0,
 258                                                    &scratch_32);
 259                        scratch_32 = ((scratch_32 & 0xFF000000) >> 24);
 260
 261                        /* Check Whether subId is 0x11 or 0x12 */
 262                        if ((scratch_32 == 0x11) || (scratch_32 == 0x12)) {
 263                                scratch_32 = 0x2c280000;
 264
 265                                /* Set Base Clock to 208MZ */
 266                                o2_pci_set_baseclk(chip, scratch_32);
 267                                ret = pci_read_config_dword(chip->pdev,
 268                                                            O2_SD_FUNC_REG4,
 269                                                            &scratch_32);
 270
 271                                /* Enable Base Clk setting change */
 272                                scratch_32 |= O2_SD_FREG4_ENABLE_CLK_SET;
 273                                pci_write_config_dword(chip->pdev,
 274                                                       O2_SD_FUNC_REG4,
 275                                                       scratch_32);
 276
 277                                /* Set Tuning Window to 4 */
 278                                pci_write_config_byte(chip->pdev,
 279                                                      O2_SD_TUNING_CTRL, 0x44);
 280
 281                                break;
 282                        }
 283                }
 284
 285                /* Enable 8520 led function */
 286                o2_pci_led_enable(chip);
 287
 288                /* Set timeout CLK */
 289                ret = pci_read_config_dword(chip->pdev,
 290                                            O2_SD_CLK_SETTING, &scratch_32);
 291                if (ret)
 292                        return ret;
 293
 294                scratch_32 &= ~(0xFF00);
 295                scratch_32 |= 0x07E0C800;
 296                pci_write_config_dword(chip->pdev,
 297                                       O2_SD_CLK_SETTING, scratch_32);
 298
 299                ret = pci_read_config_dword(chip->pdev,
 300                                            O2_SD_CLKREQ, &scratch_32);
 301                if (ret)
 302                        return ret;
 303                scratch_32 |= 0x3;
 304                pci_write_config_dword(chip->pdev, O2_SD_CLKREQ, scratch_32);
 305
 306                ret = pci_read_config_dword(chip->pdev,
 307                                            O2_SD_PLL_SETTING, &scratch_32);
 308                if (ret)
 309                        return ret;
 310
 311                scratch_32 &= ~(0x1F3F070E);
 312                scratch_32 |= 0x18270106;
 313                pci_write_config_dword(chip->pdev,
 314                                       O2_SD_PLL_SETTING, scratch_32);
 315
 316                /* Disable UHS1 funciton */
 317                ret = pci_read_config_dword(chip->pdev,
 318                                            O2_SD_CAP_REG2, &scratch_32);
 319                if (ret)
 320                        return ret;
 321                scratch_32 &= ~(0xE0);
 322                pci_write_config_dword(chip->pdev,
 323                                       O2_SD_CAP_REG2, scratch_32);
 324
 325                if (chip->pdev->device == PCI_DEVICE_ID_O2_FUJIN2)
 326                        sdhci_pci_o2_fujin2_pci_init(chip);
 327
 328                /* Lock WP */
 329                ret = pci_read_config_byte(chip->pdev,
 330                                           O2_SD_LOCK_WP, &scratch);
 331                if (ret)
 332                        return ret;
 333                scratch |= 0x80;
 334                pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
 335                break;
 336        case PCI_DEVICE_ID_O2_SEABIRD0:
 337        case PCI_DEVICE_ID_O2_SEABIRD1:
 338                /* UnLock WP */
 339                ret = pci_read_config_byte(chip->pdev,
 340                                O2_SD_LOCK_WP, &scratch);
 341                if (ret)
 342                        return ret;
 343
 344                scratch &= 0x7f;
 345                pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
 346
 347                ret = pci_read_config_dword(chip->pdev,
 348                                            O2_SD_PLL_SETTING, &scratch_32);
 349
 350                if ((scratch_32 & 0xff000000) == 0x01000000) {
 351                        scratch_32 &= 0x0000FFFF;
 352                        scratch_32 |= 0x1F340000;
 353
 354                        pci_write_config_dword(chip->pdev,
 355                                               O2_SD_PLL_SETTING, scratch_32);
 356                } else {
 357                        scratch_32 &= 0x0000FFFF;
 358                        scratch_32 |= 0x2c280000;
 359
 360                        pci_write_config_dword(chip->pdev,
 361                                               O2_SD_PLL_SETTING, scratch_32);
 362
 363                        ret = pci_read_config_dword(chip->pdev,
 364                                                    O2_SD_FUNC_REG4,
 365                                                    &scratch_32);
 366                        scratch_32 |= (1 << 22);
 367                        pci_write_config_dword(chip->pdev,
 368                                               O2_SD_FUNC_REG4, scratch_32);
 369                }
 370
 371                /* Set Tuning Windows to 5 */
 372                pci_write_config_byte(chip->pdev,
 373                                O2_SD_TUNING_CTRL, 0x55);
 374                /* Lock WP */
 375                ret = pci_read_config_byte(chip->pdev,
 376                                           O2_SD_LOCK_WP, &scratch);
 377                if (ret)
 378                        return ret;
 379                scratch |= 0x80;
 380                pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
 381                break;
 382        }
 383
 384        return 0;
 385}
 386
 387int sdhci_pci_o2_resume(struct sdhci_pci_chip *chip)
 388{
 389        sdhci_pci_o2_probe(chip);
 390        return 0;
 391}
 392