mirror of
https://gitee.com/open-loongarch/linux-5.10.git
synced 2026-10-25 12:47:11 +08:00
286 lines
7.3 KiB
C
286 lines
7.3 KiB
C
/*
|
|
* linux/drivers/mmc/ls2k_mci.h - Loongson ls2k MCI driver
|
|
*
|
|
* Copyright (C) loongson, All Rights Reserved.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*/
|
|
|
|
#ifndef FCR_SDIO_H_
|
|
#define FCR_SDIO_H_
|
|
|
|
#include <linux/interrupt.h>
|
|
|
|
#define _REG(x) ((volatile u32 *)(x))
|
|
#define _REG2(b, o) ((volatile u32 *)((b)+(o)))
|
|
|
|
/*
|
|
* sdio_controler
|
|
*/
|
|
#ifndef CONFIG_LOONGARCH
|
|
#define LS2K1000_SDIO_REG_BASE 0x1fe0c000
|
|
#define LS2K1000_GPIO_INTEN_BASE TO_UNCAC(0x1fe10530)
|
|
#else
|
|
#define LS2K1000_SDIO_REG_BASE 0x1fe2c000
|
|
#define LS2K1000_GPIO_INTEN_BASE TO_UNCAC(0x1fe00530)
|
|
#endif
|
|
|
|
#define LS2K0500_SDIO0_REG_BASE 0x1ff64000
|
|
#define LS2K0500_SDIO0_GPIO_INTEN_BASE TO_UNCAC(0x1fe104e4) /* GPIO32~63 */
|
|
#define LS2K0500_SDIO1_REG_BASE 0x1ff66000
|
|
#define LS2K0500_SDIO1_GPIO_INTEN_BASE TO_UNCAC(0x1fe104e8) /* GPIO64~95 */
|
|
|
|
#define SDIO_DEV_ADDR (host->base+0x40)
|
|
#define WDMA_OFFSET 0x400
|
|
#define RDMA_OFFSET 0x800
|
|
|
|
#define SDICON 0x00
|
|
#define SDIPRE 0x04
|
|
#define SDICMDARG 0x08
|
|
#define SDICMDCON 0x0c
|
|
#define SDICMDSTA 0x10
|
|
#define SDIRSP0 0x14
|
|
#define SDIRSP1 0x18
|
|
#define SDIRSP2 0x1C
|
|
#define SDIRSP3 0x20
|
|
#define SDIDTIMER 0x24
|
|
#define SDIBSIZE 0x28
|
|
#define SDIDATCON 0x2C
|
|
#define SDIDATCNT 0x30
|
|
#define SDIDSTA 0x34
|
|
#define SDIFSTA 0x38
|
|
#define SDIINTMSK 0x3C
|
|
#define SDIWRDAT 0x40
|
|
#define SDISTAADD0 0x44
|
|
#define SDISTAADD1 0x48
|
|
#define SDISTAADD2 0x4c
|
|
#define SDISTAADD3 0x50
|
|
#define SDISTAADD4 0x54
|
|
#define SDISTAADD5 0x58
|
|
#define SDISTAADD6 0x5c
|
|
#define SDISTAADD7 0x60
|
|
#define SDIINTEN 0x64
|
|
|
|
#define DAT_4_WIRE 1
|
|
#define ERASE_START_ADDR 0x5000
|
|
#define ERASE_End_ADDR 0x5000
|
|
|
|
#define SDICMDSTAT (0x10)
|
|
#define SDITIMER (0x24)
|
|
#define SDIDCON (0x2C)
|
|
#define SDIDCNT (0x30)
|
|
|
|
#define SDIDATA (0x3C)
|
|
#define SDIIMSK (0x40)
|
|
|
|
#define SDICON_RESET (1<<8)
|
|
#define SDICON_MMCCLOCK (1<<5)
|
|
#define SDICON_BYTEORDER (1<<4)
|
|
#define SDICON_SDIOIRQ (1<<3)
|
|
#define SDICON_RWAITEN (1<<2)
|
|
#define SDICON_FIFORESET (1<<1)
|
|
#define SDICON_CLOCKTYPE (1<<0)
|
|
|
|
#define SDIPRE_REVCLOCK (1<<31)
|
|
|
|
#define SDICMDCON_CMD6DATA (1<<18)
|
|
#define SDICMDCON_ABORT (1<<12)
|
|
#define SDICMDCON_WITHDATA (1<<11)
|
|
#define SDICMDCON_LONGRSP (1<<10)
|
|
#define SDICMDCON_WAITRSP (1<<9)
|
|
#define SDICMDCON_CMDSTART (1<<8)
|
|
#define SDICMDCON_SENDERHOST (1<<6)
|
|
#define SDICMDCON_INDEX (0x3f)
|
|
|
|
#define SDICMDSTAT_CRCFAIL (1<<12)
|
|
#define SDICMDSTAT_CMDSENT (1<<11)
|
|
#define SDICMDSTAT_CMDTIMEOUT (1<<10)
|
|
#define SDICMDSTAT_RSPFIN (1<<9)
|
|
#define SDICMDSTAT_XFERING (1<<8)
|
|
#define SDICMDSTAT_INDEX (0xff)
|
|
|
|
#define SDIDCON_8BIT_BUS (1<<26)
|
|
#define SDIDCON_IRQPERIOD (1<<21)
|
|
#define SDIDCON_TXAFTERRESP (1<<20)
|
|
#define SDIDCON_RXAFTERCMD (1<<19)
|
|
#define SDIDCON_BUSYAFTERCMD (1<<18)
|
|
#define SDIDCON_BLOCKMODE (1<<17)
|
|
#define SDIDCON_4BIT_BUS (1<<16)
|
|
#define MISC_CTRL_SDIO_DMAEN (1<<15)
|
|
#define SDIDCON_STOP (1<<14)
|
|
#define SDIDCON_DATMODE (3<<12)
|
|
#define SDIDCON_BLKNUM (0x7ff)
|
|
|
|
/* constants for SDIDCON_DATMODE */
|
|
#define SDIDCON_XFER_READY (0<<12)
|
|
#define SDIDCON_XFER_CHKSTART (1<<12)
|
|
#define SDIDCON_XFER_RXSTART (2<<12)
|
|
#define SDIDCON_XFER_TXSTART (3<<12)
|
|
|
|
#define SDIDCON_BLKNUM_MASK (0xFFF)
|
|
#define SDIDCNT_BLKNUM_SHIFT (12)
|
|
|
|
#define SDIDSTA_RDYWAITREQ (1<<10)
|
|
#define SDIDSTA_FIFOFAIL (1<<9)
|
|
#define SDIDSTA_SDIOIRQDETECT (1<<8)
|
|
#define SDIDSTA_CRCFAIL (1<<7)
|
|
#define SDIDSTA_RXCRCFAIL (1<<6)
|
|
#define SDIDSTA_DATATIMEOUT (1<<5)
|
|
#define SDIDSTA_XFERFINISH (1<<4)
|
|
#define SDIDSTA_BUSYFINISH (1<<3)
|
|
#define SDIDSTA_SBITERR (1<<2)
|
|
#define SDIDSTA_TXDATAON (1<<1)
|
|
#define SDIDSTA_RXDATAON (1<<0)
|
|
|
|
#define SDIFSTA_TFDET (1<<13)
|
|
#define SDIFSTA_RFDET (1<<12)
|
|
#define SDIFSTA_TFFULL (1<<11)
|
|
#define SDIFSTA_TFEMPTY (1<<10)
|
|
#define SDIFSTA_RFLAST (1<<9)
|
|
#define SDIFSTA_RFFULL (1<<8)
|
|
#define SDIFSTA_RFEMPTY (1<<7)
|
|
#define SDIFSTA_COUNTMASK (0x7f)
|
|
|
|
#define SDIIMSK_RESPONSECRC (1<<8)
|
|
#define SDIIMSK_CMDTIMEOUT (1<<7)
|
|
#define SDIIMSK_CMDSENT (1<<6)
|
|
#define SDIIMSK_SDIOIRQ (1<<5)
|
|
#define SDIIMSK_PROGERR (1<<4)
|
|
#define SDIIMSK_TXCRCFAIL (1<<3)
|
|
#define SDIIMSK_RXCRCFAIL (1<<2)
|
|
#define SDIIMSK_DATATIMEOUT (1<<1)
|
|
#define SDIIMSK_DATAFINISH (1<<0)
|
|
|
|
#define SDIIMSK_BUSYFINISH (1<<6)
|
|
#define SDIIMSK_SBITERR (1<<5)
|
|
#define SDIIMSK_TXFIFOHALF (1<<4)
|
|
#define SDIIMSK_TXFIFOEMPTY (1<<3)
|
|
#define SDIIMSK_RXFIFOLAST (1<<2)
|
|
#define SDIIMSK_RXFIFOFULL (1<<1)
|
|
#define SDIIMSK_RXFIFOHALF (1<<0)
|
|
|
|
#define SDIINT_CLEARALL 0x1ff
|
|
#define SDIINT_ENALL 0x1ff
|
|
|
|
#define nr_strtol strtoul
|
|
|
|
enum ls2k_mci_waitfor {
|
|
COMPLETION_NONE,
|
|
COMPLETION_FINALIZE,
|
|
COMPLETION_CMDSENT,
|
|
COMPLETION_RSPFIN,
|
|
COMPLETION_XFERFINISH,
|
|
COMPLETION_XFERFINISH_RSPFIN,
|
|
};
|
|
|
|
typedef struct ls2k_dma_desc{
|
|
volatile u32 order_addr;
|
|
volatile u32 saddr;
|
|
volatile u32 daddr;
|
|
volatile u32 length;
|
|
volatile u32 step_length;
|
|
volatile u32 step_times;
|
|
volatile u32 cmd;
|
|
volatile u32 dummy;
|
|
volatile u32 order_addr_hi;
|
|
volatile u32 saddr_hi;
|
|
} ls2k_dma_desc;
|
|
|
|
struct ls2k_mci_host {
|
|
struct platform_device *pdev;
|
|
struct ls2k_mci_pdata *pdata;
|
|
struct mmc_host *mmc;
|
|
struct resource *mem;
|
|
struct clk *clk;
|
|
void __iomem *base;
|
|
dma_addr_t phys_base;
|
|
void __iomem *wdma_order_reg;
|
|
void __iomem *rdma_order_reg;
|
|
int irq;
|
|
int irq_cd;
|
|
int dma;
|
|
unsigned long dma_send_vir_mem;
|
|
unsigned long dma_send_phy_mem;
|
|
unsigned long dma_rec_vir_mem;
|
|
unsigned long dma_rec_phy_mem;
|
|
struct ls2k_dma_desc *sg_cpu;
|
|
dma_addr_t sg_dma;
|
|
|
|
unsigned long clk_rate;
|
|
unsigned long clk_div;
|
|
unsigned long real_rate;
|
|
u8 prescaler;
|
|
|
|
int is2440;
|
|
unsigned sdiimsk;
|
|
unsigned sdidata;
|
|
int dodma;
|
|
int dmatogo;
|
|
|
|
bool irq_disabled;
|
|
bool irq_enabled;
|
|
bool irq_state;
|
|
int sdio_irqen;
|
|
|
|
struct mmc_request *mrq;
|
|
int cmd_is_stop;
|
|
|
|
spinlock_t complete_lock;
|
|
enum ls2k_mci_waitfor complete_what;
|
|
|
|
int dma_complete;
|
|
|
|
u32 pio_sgptr;
|
|
u32 pio_bytes;
|
|
u32 pio_count;
|
|
u32 *pio_ptr;
|
|
#define XFER_NONE 0
|
|
#define XFER_READ 1
|
|
#define XFER_WRITE 2
|
|
u32 pio_active;
|
|
|
|
int bus_width;
|
|
|
|
char dbgmsg_cmd[301];
|
|
char dbgmsg_dat[301];
|
|
char *status;
|
|
|
|
unsigned int ccnt, dcnt;
|
|
struct tasklet_struct pio_tasklet;
|
|
|
|
#ifdef CONFIG_DEBUG_FS
|
|
struct dentry *debug_root;
|
|
struct dentry *debug_state;
|
|
struct dentry *debug_regs;
|
|
#endif
|
|
|
|
#ifdef CONFIG_CPU_FREQ
|
|
struct notifier_block freq_transition;
|
|
#endif
|
|
struct dma_chan *chan;
|
|
unsigned int app_cmd;
|
|
};
|
|
|
|
struct ls2k_mci_pdata {
|
|
unsigned int no_wprotect : 1;
|
|
unsigned int no_detect : 1;
|
|
unsigned int wprotect_invert : 1;
|
|
unsigned int detect_invert : 1; /* set => detect active high. */
|
|
unsigned int use_dma : 1;
|
|
|
|
unsigned int gpio_detect;
|
|
unsigned int gpio_wprotect;
|
|
#define LOONGSON_SDIO_EMMC_VER_1_0 0x100
|
|
#define LOONGSON_SDIO_EMMC_VER_1_1 0x110
|
|
#define LOONGSON_SDIO_EMMC_VER_1_2 0x120
|
|
unsigned int version;
|
|
unsigned long ocr_avail;
|
|
void (*set_power)(unsigned char power_mode,
|
|
unsigned short vdd);
|
|
void (*irq_fixup)(struct ls2k_mci_host *host,
|
|
struct mmc_command *cmd);
|
|
};
|
|
#endif
|