linux/include/linux/mmc/sh_mmcif.h
<<
>>
Prefs
   1/*
   2 * include/linux/mmc/sh_mmcif.h
   3 *
   4 * platform data for eMMC driver
   5 *
   6 * Copyright (C) 2010 Renesas Solutions Corp.
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License as published by
  10 * the Free Software Foundation; either version 2 of the License.
  11 *
  12 */
  13
  14#ifndef __SH_MMCIF_H__
  15#define __SH_MMCIF_H__
  16
  17#include <linux/io.h>
  18#include <linux/platform_device.h>
  19#include <linux/sh_dma.h>
  20
  21/*
  22 * MMCIF : CE_CLK_CTRL [19:16]
  23 * 1000 : Peripheral clock / 512
  24 * 0111 : Peripheral clock / 256
  25 * 0110 : Peripheral clock / 128
  26 * 0101 : Peripheral clock / 64
  27 * 0100 : Peripheral clock / 32
  28 * 0011 : Peripheral clock / 16
  29 * 0010 : Peripheral clock / 8
  30 * 0001 : Peripheral clock / 4
  31 * 0000 : Peripheral clock / 2
  32 * 1111 : Peripheral clock (sup_pclk set '1')
  33 */
  34
  35struct sh_mmcif_dma {
  36        struct sh_dmae_slave chan_priv_tx;
  37        struct sh_dmae_slave chan_priv_rx;
  38};
  39
  40struct sh_mmcif_plat_data {
  41        void (*set_pwr)(struct platform_device *pdev, int state);
  42        void (*down_pwr)(struct platform_device *pdev);
  43        int (*get_cd)(struct platform_device *pdef);
  44        struct sh_mmcif_dma     *dma;
  45        u8                      sup_pclk;       /* 1 :SH7757, 0: SH7724/SH7372 */
  46        unsigned long           caps;
  47        u32                     ocr;
  48};
  49
  50#define MMCIF_CE_CMD_SET        0x00000000
  51#define MMCIF_CE_ARG            0x00000008
  52#define MMCIF_CE_ARG_CMD12      0x0000000C
  53#define MMCIF_CE_CMD_CTRL       0x00000010
  54#define MMCIF_CE_BLOCK_SET      0x00000014
  55#define MMCIF_CE_CLK_CTRL       0x00000018
  56#define MMCIF_CE_BUF_ACC        0x0000001C
  57#define MMCIF_CE_RESP3          0x00000020
  58#define MMCIF_CE_RESP2          0x00000024
  59#define MMCIF_CE_RESP1          0x00000028
  60#define MMCIF_CE_RESP0          0x0000002C
  61#define MMCIF_CE_RESP_CMD12     0x00000030
  62#define MMCIF_CE_DATA           0x00000034
  63#define MMCIF_CE_INT            0x00000040
  64#define MMCIF_CE_INT_MASK       0x00000044
  65#define MMCIF_CE_HOST_STS1      0x00000048
  66#define MMCIF_CE_HOST_STS2      0x0000004C
  67#define MMCIF_CE_VERSION        0x0000007C
  68
  69/* CE_BUF_ACC */
  70#define BUF_ACC_DMAWEN          (1 << 25)
  71#define BUF_ACC_DMAREN          (1 << 24)
  72#define BUF_ACC_BUSW_32         (0 << 17)
  73#define BUF_ACC_BUSW_16         (1 << 17)
  74#define BUF_ACC_ATYP            (1 << 16)
  75
  76/* CE_CLK_CTRL */
  77#define CLK_ENABLE              (1 << 24) /* 1: output mmc clock */
  78#define CLK_CLEAR               ((1 << 19) | (1 << 18) | (1 << 17) | (1 << 16))
  79#define CLK_SUP_PCLK            ((1 << 19) | (1 << 18) | (1 << 17) | (1 << 16))
  80#define CLKDIV_4                (1<<16) /* mmc clock frequency.
  81                                         * n: bus clock/(2^(n+1)) */
  82#define CLKDIV_256              (7<<16) /* mmc clock frequency. (see above) */
  83#define SRSPTO_256              ((1 << 13) | (0 << 12)) /* resp timeout */
  84#define SRBSYTO_29              ((1 << 11) | (1 << 10) |        \
  85                                 (1 << 9) | (1 << 8)) /* resp busy timeout */
  86#define SRWDTO_29               ((1 << 7) | (1 << 6) |          \
  87                                 (1 << 5) | (1 << 4)) /* read/write timeout */
  88#define SCCSTO_29               ((1 << 3) | (1 << 2) |          \
  89                                 (1 << 1) | (1 << 0)) /* ccs timeout */
  90
  91/* CE_VERSION */
  92#define SOFT_RST_ON             (1 << 31)
  93#define SOFT_RST_OFF            0
  94
  95static inline u32 sh_mmcif_readl(void __iomem *addr, int reg)
  96{
  97        return __raw_readl(addr + reg);
  98}
  99
 100static inline void sh_mmcif_writel(void __iomem *addr, int reg, u32 val)
 101{
 102        __raw_writel(val, addr + reg);
 103}
 104
 105#define SH_MMCIF_BBS 512 /* boot block size */
 106
 107static inline void sh_mmcif_boot_cmd_send(void __iomem *base,
 108                                          unsigned long cmd, unsigned long arg)
 109{
 110        sh_mmcif_writel(base, MMCIF_CE_INT, 0);
 111        sh_mmcif_writel(base, MMCIF_CE_ARG, arg);
 112        sh_mmcif_writel(base, MMCIF_CE_CMD_SET, cmd);
 113}
 114
 115static inline int sh_mmcif_boot_cmd_poll(void __iomem *base, unsigned long mask)
 116{
 117        unsigned long tmp;
 118        int cnt;
 119
 120        for (cnt = 0; cnt < 1000000; cnt++) {
 121                tmp = sh_mmcif_readl(base, MMCIF_CE_INT);
 122                if (tmp & mask) {
 123                        sh_mmcif_writel(base, MMCIF_CE_INT, tmp & ~mask);
 124                        return 0;
 125                }
 126        }
 127
 128        return -1;
 129}
 130
 131static inline int sh_mmcif_boot_cmd(void __iomem *base,
 132                                    unsigned long cmd, unsigned long arg)
 133{
 134        sh_mmcif_boot_cmd_send(base, cmd, arg);
 135        return sh_mmcif_boot_cmd_poll(base, 0x00010000);
 136}
 137
 138static inline int sh_mmcif_boot_do_read_single(void __iomem *base,
 139                                               unsigned int block_nr,
 140                                               unsigned long *buf)
 141{
 142        int k;
 143
 144        /* CMD13 - Status */
 145        sh_mmcif_boot_cmd(base, 0x0d400000, 0x00010000);
 146
 147        if (sh_mmcif_readl(base, MMCIF_CE_RESP0) != 0x0900)
 148                return -1;
 149
 150        /* CMD17 - Read */
 151        sh_mmcif_boot_cmd(base, 0x11480000, block_nr * SH_MMCIF_BBS);
 152        if (sh_mmcif_boot_cmd_poll(base, 0x00100000) < 0)
 153                return -1;
 154
 155        for (k = 0; k < (SH_MMCIF_BBS / 4); k++)
 156                buf[k] = sh_mmcif_readl(base, MMCIF_CE_DATA);
 157
 158        return 0;
 159}
 160
 161static inline int sh_mmcif_boot_do_read(void __iomem *base,
 162                                        unsigned long first_block,
 163                                        unsigned long nr_blocks,
 164                                        void *buf)
 165{
 166        unsigned long k;
 167        int ret = 0;
 168
 169        /* In data transfer mode: Set clock to Bus clock/4 (about 20Mhz) */
 170        sh_mmcif_writel(base, MMCIF_CE_CLK_CTRL,
 171                        CLK_ENABLE | CLKDIV_4 | SRSPTO_256 |
 172                        SRBSYTO_29 | SRWDTO_29 | SCCSTO_29);
 173
 174        /* CMD9 - Get CSD */
 175        sh_mmcif_boot_cmd(base, 0x09806000, 0x00010000);
 176
 177        /* CMD7 - Select the card */
 178        sh_mmcif_boot_cmd(base, 0x07400000, 0x00010000);
 179
 180        /* CMD16 - Set the block size */
 181        sh_mmcif_boot_cmd(base, 0x10400000, SH_MMCIF_BBS);
 182
 183        for (k = 0; !ret && k < nr_blocks; k++)
 184                ret = sh_mmcif_boot_do_read_single(base, first_block + k,
 185                                                   buf + (k * SH_MMCIF_BBS));
 186
 187        return ret;
 188}
 189
 190static inline void sh_mmcif_boot_init(void __iomem *base)
 191{
 192        /* reset */
 193        sh_mmcif_writel(base, MMCIF_CE_VERSION, SOFT_RST_ON);
 194        sh_mmcif_writel(base, MMCIF_CE_VERSION, SOFT_RST_OFF);
 195
 196        /* byte swap */
 197        sh_mmcif_writel(base, MMCIF_CE_BUF_ACC, BUF_ACC_ATYP);
 198
 199        /* Set block size in MMCIF hardware */
 200        sh_mmcif_writel(base, MMCIF_CE_BLOCK_SET, SH_MMCIF_BBS);
 201
 202        /* Enable the clock, set it to Bus clock/256 (about 325Khz). */
 203        sh_mmcif_writel(base, MMCIF_CE_CLK_CTRL,
 204                        CLK_ENABLE | CLKDIV_256 | SRSPTO_256 |
 205                        SRBSYTO_29 | SRWDTO_29 | SCCSTO_29);
 206
 207        /* CMD0 */
 208        sh_mmcif_boot_cmd(base, 0x00000040, 0);
 209
 210        /* CMD1 - Get OCR */
 211        do {
 212                sh_mmcif_boot_cmd(base, 0x01405040, 0x40300000); /* CMD1 */
 213        } while ((sh_mmcif_readl(base, MMCIF_CE_RESP0) & 0x80000000)
 214                 != 0x80000000);
 215
 216        /* CMD2 - Get CID */
 217        sh_mmcif_boot_cmd(base, 0x02806040, 0);
 218
 219        /* CMD3 - Set card relative address */
 220        sh_mmcif_boot_cmd(base, 0x03400040, 0x00010000);
 221}
 222
 223#endif /* __SH_MMCIF_H__ */
 224