firmware/br-ext-chip-allwinner/board/v83x/kernel/patches/00000-drivers_mmc_host_sunx...

367 lines
10 KiB
Diff

diff -drupN a/drivers/mmc/host/sunxi-smhc.h b/drivers/mmc/host/sunxi-smhc.h
--- a/drivers/mmc/host/sunxi-smhc.h 1970-01-01 03:00:00.000000000 +0300
+++ b/drivers/mmc/host/sunxi-smhc.h 2022-06-12 05:28:14.000000000 +0300
@@ -0,0 +1,362 @@
+/*
+* Sunxi SD/MMC host driver
+*
+* Copyright (C) 2015 AllWinnertech Ltd.
+* Author: lixiang <lixiang@allwinnertech>
+*
+* 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.
+*
+* This program is distributed "as is" WITHOUT ANY WARRANTY of any
+* kind, whether express or implied; without even the implied warranty
+* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*/
+
+
+#include <linux/clk.h>
+#include <linux/clk/sunxi.h>
+
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/scatterlist.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/reset.h>
+
+#include <linux/of_address.h>
+#include <linux/of_gpio.h>
+#include <linux/of_platform.h>
+
+#include <linux/mmc/host.h>
+#include <linux/mmc/sd.h>
+#include <linux/mmc/sdio.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/core.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/slot-gpio.h>
+
+#ifndef __SUNXI_MMC_H__
+#define __SUNXI_MMC_H__
+
+#define DRIVER_NAME "sunxi-smhc"
+#define DRIVER_RIVISION "v0.6 2016-4-29 16:53"
+#define DRIVER_VERSION "SD/MMC/SDIO Host Controller Driver(" DRIVER_RIVISION ")"
+
+#if defined CONFIG_FPGA_V4_PLATFORM || defined CONFIG_FPGA_V7_PLATFORM
+#define MMC_FPGA
+#endif
+
+
+#define SMHC_DEVICE_ID (2) /*number of id in multi device*/
+/*max blk count and size is limited by the SMHC_BLK_CFG register's max value*/
+#define MAX_BLK_COUNT (0xFFFF)
+#define MAX_BLK_SIZE (0x800)
+/*#define MAX_DES_SIZE PAGE_SIZE*/
+#define SUNXI_REQ_PAGE_SIZE (PAGE_SIZE*4)
+
+/*---------------------------------------------*/
+/* registers define */
+/*---------------------------------------------*/
+#define SMHC_CMD_ARG2 (0x00)
+#define SMHC_BLK_CFG (0x04)
+#define SMHC_CMD_ARG1 (0x08)
+#define SMHC_CMD (0x0C)
+#define SMHC_RESP0 (0x10)
+#define SMHC_RESP1 (0x14)
+#define SMHC_RESP2 (0x18)
+#define SMHC_RESP3 (0x1C)
+#define SMHC_BUFF (0x20)
+#define SMHC_STA (0x24)
+#define SMHC_CTRL1 (0x28)
+#define SMHC_RST_CLK_CTRL (0x2C)
+#define SMHC_INT_STA (0x30)
+#define SMHC_INT_STA_EN (0x34)
+#define SMHC_INT_SIG_EN (0x38)
+#define SMHC_ACMD_ERR_CTRL2 (0x3C)
+#define SMHC_SET_ERR (0x50)
+#define SMHC_ADMA_ERR (0x54)
+#define SMHC_ADMA_ADDR (0x58)
+
+#define SMHC_CTRL3 (0x200)
+#define SMHC_CMD_ATTR (0x204)
+#define SMHC_TO_CTRL2 (0x208)
+#define SMHC_ATC (0x210)
+#define SMHC_RTC (0x214)
+#define SMHC_DITC0 (0x218)
+#define SMHC_DITC1 (0x21C)
+#define SMHC_TP0 (0x220)
+#define SMHC_TP1 (0x224)
+
+#define SMHC_CRC_STA (0x240)
+#define SMHC_TBC0 (0x244)
+#define SMHC_TBC1 (0x248)
+#define SMHC_BL (0x24C)
+#define SMHC_CEDBN (0x250)
+/*----------------------------------------*/
+
+#define smhc_readl(host, reg) \
+ __raw_readl((host)->reg_base + reg)
+#define smhc_writel(host, reg, value) \
+ __raw_writel((value), (host)->reg_base + reg)
+#define smhc_readw(host, reg) \
+ __raw_readw((host)->reg_base + reg)
+#define smhc_writew(host, reg, value) \
+ __raw_writew((value), (host)->reg_base + reg)
+#define smhc_clr_bit(host, reg, bitmap) \
+ do { \
+ u32 tmp = smhc_readl(host, reg); \
+ tmp &= ~(bitmap); \
+ smhc_writel(host, reg, tmp); \
+ } while (0)
+
+#define smhc_set_bit(host, reg, bitmap) \
+ do { \
+ u32 tmp = smhc_readl(host, reg); \
+ tmp |= (bitmap); \
+ smhc_writel(host, reg, tmp); \
+ } while (0)
+
+ /* control register bit field */
+ /*0x2c */
+#define ResetAll (0x1U<<24)
+#define ResetCmd (0x1U<<25)
+#define ResetDat (0x1U<<26)
+#define SdclkEn (0x1U<<2)
+
+ /*0x200 */
+#define CPUAcessBuffEn (0x1U<<31)
+#define StopReadClkAtBlkGap (0x1U<<8)
+#define SWDebounceMode (0x1U<<5)
+#define DebounceEnb (0x1U<<4)
+#define CdDat3En (0x1U<<3)
+#define SdclkIdleCtrl (0x1U<<2)
+
+ /* Struct for SMC Commands */
+ /*0x18 */
+#define CMDType (0x3U<<22)
+#define DataExp (0x1U<<21)
+#define CheckRspIdx (0x1U<<20)
+#define CheckRspCRC (0x1U<<19)
+#define NoRsp (0x0U<<16)
+#define Rsp136 (0x1U<<16)
+#define Rsp48 (0x2U<<16)
+#define Rsp48b (0x3U<<16)
+#define SingleBlkTrans (0x0U<<5)
+#define MultiBlkTrans (0x1U<<5)
+#define Read (0x1U<<4)
+#define Write (0x0U<<4)
+#define AutoCmd12 (0x1U<<2)
+#define AutoCmd23 (0x2U<<2)
+#define BlkCntEn (0x1U<<1)
+#define DMAEn (0x1U<<0)
+
+ /*0x204 */
+#define SendInitSeq (0x1U<<4)
+#define DisableBoot (0x1U<<3)
+#define BootACKExp (0x1U<<2)
+#define AltBootMode (0x2U<<0)
+#define MandBootMode (0x1U<<0)
+
+ /*0x03C */
+#define Switch3v3To1v8 (0x1U<<19)
+#define DdrType (0x7<<16)
+#define DDR_SHIFT (16)
+
+ /*0x24 */
+#define CmdLineSta (0x1U<<24)
+#define Dat3LineSta (0x1U<<23)
+#define Dat2LineSta (0x1U<<22)
+#define Dat1LineSta (0x1U<<21)
+#define Dat0LineSta (0x1U<<20)
+#define WpPinSta (0x1U<<19)
+#define CdPinInvSta (0x1U<<18)
+#define CardStable (0x1U<<17)
+#define CardInsert (0x1U<<16)
+#define BuffRDEn (0x1U<<11)
+#define BuffWREn (0x1U<<10)
+#define RDTransActive (0x1U<<9)
+#define WRTransActive (0x1U<<8)
+#define DatLineActive (0x1U<<2)
+#define CmdInhibitDat (0x1U<<1)
+#define CmdInhibitCmd (0x1U<<0)
+
+#define BootDataStart (0x1U<<29)
+#define BootAckRcv (0x1U<<28)
+#define DSFOInt (0x1U<<30)
+#define DmaErrInt (0x1U<<25)
+#define AcmdErrInt (0x1U<<24)
+#define DatEndBitErrInt (0x1U<<22)
+#define DatCRCErrInt (0x1U<<21)
+#define DatTimeoutErrInt (0x1U<<20)
+#define CmdIdxErrInt (0x1U<<19)
+#define CmdEndBitErrInt (0x1U<<18)
+#define CmdCRCErrInt (0x1U<<17)
+#define CmdTimeoutErrInt (0x1U<<16)
+#define ErrInt (0x1U<<15)
+#define CardInt (0x1U<<8)
+#define CardRemoveInt (0x1U<<7)
+#define CardInsertInt (0x1U<<6)
+#define BuffRDRdyInt (0x1U<<5)
+#define BuffWRRdyInt (0x1U<<4)
+#define DmaInt (0x1U<<3)
+ /*#define BlkGapEvtInt (0x1U<<2)*/
+#define TransOverInt (0x1U<<1)
+#define CmdOverInt (0x1U<<0)
+#define TxDatIntBit (DmaInt | TransOverInt | DmaErrInt | ErrInt)
+#define RxDatIntBit (DmaInt | TransOverInt | DmaErrInt | ErrInt)
+#define DmaIntBit (DmaInt | DmaErrInt)
+#define ErrIntBit (0x437F0000) /*(0x1ff<<16)*/
+#define DoneIntBit (TransOverInt|CmdOverInt)
+
+ /*0x28 SMHC_CTRL1 bit field*/
+#define Dma32BitSel (0x3<<3)
+#define DmaSel (0x3<<3)
+#define BusWidth (0x1<<1)
+#define ExtBusWidth (0x1<<5)
+
+ /*0x3C Auto CMD Error Status */
+#define NoAcmd12 (0x1U<<7)
+#define AcmdIdxErr (0x1U<<4)
+#define AcmdEndBitErr (0x1U<<3)
+#define AcmdCRCErr (0x1U<<2)
+#define AcmdTimeoutErr (0x1U<<1)
+#define NotIssueAcmd (0x0<<0)
+
+enum {
+ ACT_NOP = 0,
+ ACT_RSV,
+ ACT_TRANS,
+ ACT_LINK,
+};
+
+enum {
+ MAN_BOOT_MD = 0,
+ ALT_BOOT_MD,
+};
+
+struct sdhc_idma_des {
+/*=1: indicates this line of descriptor is effective.
+ *=0: generate ADMA Error interrupt and stop ADMA to prevent runaway.
+ */
+ u32 valid:1,
+/*=1: indicates end of descriptor.
+ *The Transfer Complete Interrupt is generated
+ *when the operation of the descriptor line is completed.
+ */
+ end:1,
+/*
+ *=1: generates DMA Interrupt
+ *when the operation of the descriptor line is completed.
+ */
+ int_en:1,
+ : 1,
+/*00b: Nop, No Operation, Do not execute current line and go to next line.*/
+act:2,
+/*01b: rsv, reserved, (Same as Nop. Do not execute current line
+ *and go to next line.)
+ */
+/*10b: Tran, transfer data, Transfer data of one descriptor
+ *line Transfer data of one descriptor line
+ */
+/*11b: Link, Link Descriptor, Link to another descriptor*/
+ : 10,
+ length:16;
+ u32 addr;
+};
+
+struct sunxi_mmc_ctrl_regs {
+ u32 rst_clk_ctrl;
+ u32 int_sta_en;
+ u32 to;
+ u32 ctrl3;
+ u32 int_sig_en;
+ u32 ctrl1;
+ u32 acmd_err_ctrl2;
+ u32 atc;
+};
+
+struct sunxi_mmc_host {
+ struct mmc_host *mmc;
+ struct reset_control *reset;
+
+ /* IO mapping base */
+ void __iomem *reg_base;
+
+ /* clock management */
+ struct clk *clk_ahb;
+ struct clk *clk_mmc;
+ struct clk *clk_rst;
+
+ int (*sunxi_mmc_clk_set_rate)(struct sunxi_mmc_host *host,
+ struct mmc_ios *ios);
+
+ /* irq */
+ spinlock_t lock;
+ int irq;
+ u32 int_sum;
+ u32 sdio_imask;
+
+ /* dma */
+ u32 idma_des_size_bits;
+ dma_addr_t sg_dma;
+ void *sg_cpu;
+ bool wait_dma;
+ u32 dma_tl;
+ u64 dma_mask;
+
+ void (*sunxi_mmc_thld_ctl)(struct sunxi_mmc_host *host,
+ struct mmc_ios *ios,
+ struct mmc_data *data);
+
+ struct mmc_request *mrq;
+ struct mmc_request *mrq_busy;
+ struct mmc_request *manual_stop_mrq;
+ int ferror;
+
+ u32 power_on;
+
+ /* pinctrl handles */
+ struct pinctrl *pinctrl;
+ struct pinctrl_state *pins_default;
+ struct pinctrl_state *pins_sleep;
+
+ /*sys node */
+ struct device_attribute maual_insert;
+ struct device_attribute *dump_register;
+ struct device_attribute dump_clk_dly;
+ void (*sunxi_mmc_dump_dly_table)(struct sunxi_mmc_host *host);
+
+ /* backup register structrue */
+ struct sunxi_mmc_ctrl_regs bak_regs;
+ void (*sunxi_mmc_save_spec_reg)(struct sunxi_mmc_host *host);
+ void (*sunxi_mmc_restore_spec_reg)(struct sunxi_mmc_host *host);
+
+ void (*sunxi_mmc_set_acmda)(struct sunxi_mmc_host *host);
+
+ void (*sunxi_mmc_shutdown)(struct platform_device *pdev);
+
+ /*really controller id,no logic id */
+ int phy_index;
+
+ u32 dat3_imask;
+
+ /*no wait busy if wrtie end, only for customer need */
+#define NO_MANUAL_WAIT_BUSY_WRITE_END 0x1
+#define NO_REINIT_SHUTDOWN 0x2
+#define CARD_PWR_GPIO_HIGH_ACTIVE 0x4
+ /*control specal function control,for customer need */
+ u32 ctl_spec_cap;
+
+ int card_pwr_gpio;
+
+ void *version_priv_dat;
+};
+
+/*use to check ddr mode,not include hs400*/
+#define sunxi_mmc_ddr_timing(it) \
+ (((it) == MMC_TIMING_UHS_DDR50) || ((it) == MMC_TIMING_MMC_DDR52))
+
+#endif