[MMC subsystem] host (chapter II)--SDHCI

Source: Internet
Author: User
Tags bool mutex reset

MMC subsystem series (in continuous update):
[MMC subsystem] concepts and frameworks

[MMC Subsystem] MMC core (chapter I)--Overview
[MMC Subsystem] MMC core (chapter II)--Description of data structure and macro definitions
[MMC Subsystem] MMC core (chapter III)--bus module description
[MMC Subsystem] MMC core (fourth chapter)--host module description
[MMC Subsystem] MMC core (fifth chapter)--card related modules (MMC type card)
[MMC Subsystem] MMC core (sixth chapter)--MMC Core Master Module

[MMC subsystem] Host (chapter I)--Overview
[MMC subsystem] host (chapter II)--SDHCI
[MMC subsystem] Host (chapter III)--SDHCI-PLTFM description
[MMC subsystem] Host (fourth chapter)--host instance (sdhci-msm description)

It is recommended to refer to the [MMC subsystem] concept and framework for a holistic understanding.

========================================================================================================== A , SDHCI core Description 1, sdhci description

Refer to "host (Chapter One)-Overview"
Sdhc:secure Digital (SD) host controller, refers to a set of SD host controllers design standards, its register offset and meaning are certain specifications, and provide the corresponding driver, convenient vendor Host Controller development.
Vendor The host controller is designed according to this standard, the use of the host controller can be achieved directly using the SDHCI driver (both qcom and Samsung use this standard). and vendor only need to implement platform-related parts, such as clock, Pinctrl, power and so on.
Regarding this standard, we can refer to "sdhc_ver3.00_final_110225".
Note that this is a design standard for the MMC host controller, which essentially belongs to the MMC host. And, it is compatible with the MMC type card, not that it can only be used for the SD type card. 2. SDHCI Core

Because SDHCI driver is not a driver of a particular host, it provides some interface and action set methods for the corresponding host driver.
Therefore, we call the SDHCI.C code part SDHCI core to distinguish it from host driver.
Its main functions are as follows: the interface for host driver to provide allocation, release sdhci_host for host driver to provide registration, uninstall Sdhci_host interface implementation Sdhci_host and Mmc_host docking (that is, MMC core docking) Implements the host general purpose operation on the SDHCI Standard (Sdhci_ops) for universal Power management operations of host

Note that clock and Pinctrl are managed by host driver themselves and SDHCI core is not involved. 3. Code location

Drivers/mmc/host/sdhci.c
drivers/mmc/host/sdhci.h II. Data structure 1, struct sdhci_host

SDHCI Core abstracts the host into the struct sdhci_host for management and maintenance. The data structure is as follows:

struct Sdhci_host {/* Data set by hardware interface driver */const char *hw_name;    /* Hardware Bus name *//name unsigned int quirks;
    /* Deviations from spec. *//hobby, can be understood as hardware SDHCI controller and standard SDHCI specification does not conform to the place.   unsigned int quirks2;

    /* More deviations from spec.///hobby 2, which can be understood as hardware SDHCI controller and standard SDHCI specification does not conform to the place.        int IRQ;   /* Device IRQ *///SDHCI interrupt void __iomem *ioaddr;    /* Mapped Address *///SDHCI register base Address const struct SDHCI_OPS *ops;     /* Low Level HW interface */////operating interface of the underlying hardware struct regulator *VMMC;    /* Power Regulator (VMMC) *///SDHCI core Ldo struct regulator *VQMMC;   /* Signaling Regulator (VCCQ)/////////For SDHCI IO-powered ldo/* Internal data */struct mmc_host *mmc;       /* MMC structure *//struct mmc_host for registering to MMC subsystem u64 Dma_mask;    /* Custom DMA Mask */spinlock_t lock;      /* Mutex *//spin lock int flags; /* Host Attributes *///SDHCI someidentity unsigned int version;   /* SDHCI Spec. version *////Current SDHCI hardware version unsigned int max_clk;   /* Max possible freq (MHz) *////The SDHCI supports the maximum voltage unsigned int timeout_clk;   /* Timeout Freq (KHz) *//Timeout frequency unsigned int clk_mul; /* Clock Muliplier value *///Current multiplier value unsigned int Clock;         /* Current Clock (MHz) *///U8 PWR at present operating frequency; /* Current voltage *///present operating voltage bool runtime_suspended;    /* Host is runtime suspended *//is in runtime suspend state struct mmc_request *mrq;    /* Current request *///The requested struct Mmc_command *cmd currently being processed;  /* Current command *///present order request struct Mmc_data *data;  /* Current Data request *////unsigned int data_early:1    /* Data finished before CMD *//indicates that data has been processed to complete the struct Sg_mapping_iter sg_miter before the cmd processing is complete;    /* SG State for PIO */unsigned int blocks;       /* Remaining PIO blocks */int sg_count;      /* Mapped SG Entries */U8 *adma_desc; /* ADMA DESCRIptor table */U8 *align_buffer; /* Bounce buffer */unsigned int ADMA_DESC_SZ; /* ADMA Descriptor Table size */unsigned int ADMA_DESC_LINE_SZ; /* ADMA Descriptor Line Size */unsigned int ALIGN_BUF_SZ; /* Bounce buffer size */unsigned int align_bytes; /* Alignment bytes (4/8 for 32-bit/64-bit) */unsigned int adma_max_desc;   /* Max ADMA Descriptos (max SG segments) */dma_addr_t adma_addr; /* Mapped ADMA descr.  Table */dma_addr_t align_addr; /* Mapped Bounce buffer */struct tasklet_struct card_tasklet;      /* Tasklet Structures *//card Tasklet, used to process card insert or unplug event struct tasklet_struct finish_tasklet;    Finsh Tasklet, used to notify the upper layer of a request processing completed (including the case of error) struct timer_list timer;       /* Timer for Timeouts *///timeout timer list u32 caps;      /* Alternative CAPABILITY_0 *///Indicates the properties of the SDHCI controller u32 CAPS1; /* Alternative Capability_1 *///Indicates the properties of the SDHCI controller unsigned int ocr_avail_sdio; /* OCR bit masks */   An OCR value mask (representing the available voltage) of the Sdio card available on the SDHCI controller unsigned int ocr_avail_sd;   An OCR value mask (representing the available voltage) of the SD card available on the SDHCI controller unsigned int ocr_avail_mmc;  The OCR value mask for the MMC card that is available on the SDHCI controller (which represents its available voltage)/*/The following tuning related to MMC */wait_queue_head_t buf_ready_int;    /* Waitqueue for Buffer Read ready interrupt */unsigned int tuning_done;   /* Condition flag set when CMD19 succeeds */unsigned int tuning_count;    /* Timer count for re-tuning */unsigned int tuning_mode;   /* Re-tuning mode supported by host */#define SDHCI_TUNING_MODE_1 0 struct timer_list tuning_timer;
    /* Timer for tuning */* below and SDHCI QoS related */struct sdhci_host_qos host_qos[sdhci_qos_max_policy];
    Enum Sdhci_host_qos_policy Last_qos_policy;  
    BOOL Host_use_default_qos;         unsigned int pm_qos_timeout_us;
    /* Timeout for PM QoS request */struct Device_attribute pm_qos_tout; struct Delayed_work Pm_qos_woRk
    struct Sdhci_next next_data;
    ktime_t Data_start_time;
    struct Mutex Ios_mutex;

    Enum Sdhci_power_policy Power_policy; BOOL irq_enabled;
    /* Host IRQ Status flag *///Indicates whether the interrupt is enabled.  BOOL Async_int_supp; /* Async support to RXV int, when clks is off */bool disable_sdio_irq_deferred;
    /* Status of disabling Sdio IRQ */u32 auto_cmd_err_sts;
    struct Ratelimit_state dbg_dump_rs; int reset_wa_applied; /* Reset Workaround status */ktime_t reset_wa_t; /* time when the reset workaround is applied */int reset_wa_cnt;      /* Total number of times workaround is used */unsigned long private[0] ____cacheline_aligned; private Data pointer};
Quirks 1 (sdhci_host->quirks) Each bit has the following meanings:
/* Controller doesn ' t honor resets unless we touch the clock Register */#define Sdhci_quirk_clock_before_reset (1<<0)/* Controllers have bad caps bits, but really supports DMA */#define SDHCI_QUIRK_FORCE_DMA (1& LT;&LT;1)/* Controller doesn ' t like to being reset when there is no card inserted.  */#define SDHCI_QUIRK_NO_CARD_NO_RESET (1&LT;&LT;2)/* Controller doesn ' t like clearing the Power Reg before a Change */#define SDHCI_QUIRK_SINGLE_POWER_WRITE (1<<3)/* Controller has flaky internal state so reset It on all iOS change */#define SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS (1<<4)/* Controller have an unusable DMA E Ngine */#define SDHCI_QUIRK_BROKEN_DMA (1<<5)/* Controller have an unusable ADMA engine */#define S DHCI_QUIRK_BROKEN_ADMA (1<<6)/* Controller can only DMA from 32-bit aligned addresses */#define SDH CI_QUIRK_32BIT_DMA_ADDR (1<<7)/* Controller can Only DMA chunk sizes that is a multiple of bits */#define SDHCI_QUIRK_32BIT_DMA_SIZE (1<<8)/* Cont
Roller can only ADMA chunks that is a multiple of the bits */#define SDHCI_QUIRK_32BIT_ADMA_SIZE (1&LT;&LT;9) /* Controller needs to is reset after all request to stay stable */#define SDHCI_QUIRK_RESET_AFTER_REQUEST (1 &LT;&LT;10)/* Controller needs voltage and Power writes to happen separately */#define Sdhci_quirk_no_simult_vdd_and_pow ER (1<<11)/* Controller provides an incorrect timeout value for transfers */#define Sdhci_quirk_broken_time Out_val (1<<12)/* Controller has a issue with buffer bits for small transfers */#define SDHCI_QUIRK_BR Oken_small_pio (1<<13)//Controller does not provide transfer-complete interrupt when not busy */#defin E SDHCI_QUIRK_NO_BUSY_IRQ (1<<14)/* Controller has unreliable card detection */#define Sdhci_quirk_   Broken_card_detection     (1<<15)/* Controller reports Inverted write-protect state */#define Sdhci_quirk_inverted_write_protect (1<<16)/* Controller has nonstandard clock management */#define SDHCI_QUIRK_NONSTANDARD_CLOCK (1&LT;&L T;17)/* Controller does not like fast PIO transfers */#define SDHCI_QUIRK_PIO_NEEDS_DELAY (1<<18)/* Co Ntroller losing signal/interrupt Enable states after reset */#define SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET (1&LT;&L T;19)/* Controller have to is forced to use block size of 2048 bytes */#define SDHCI_QUIRK_FORCE_BLK_SZ_2048 ( 1&LT;&LT;20)/* Controller cannot do multi-block transfers */#define SDHCI_QUIRK_NO_MULTIBLOCK (1&LT;&LT;21)/ * Controller can only handle 1-bit data transfers */#define SDHCI_QUIRK_FORCE_1_BIT_DATA (1<<22)/* Cont 
Roller needs 10ms delay between applying power and clock */#define SDHCI_QUIRK_DELAY_AFTER_POWER (1<<23) /* Controller uses SDCLK instead of TMCLK for data timeouts */#define SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK (1<<24)/* Controller Rep Orts wrong base clock capability */#define SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN (1&LT;&LT;25)//Controller cannot su  Pport End Attribute in NOP ADMA descriptor */#define SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC (1&LT;&LT;26)//Controller is missing device caps. Use caps provided by host */#define SDHCI_QUIRK_MISSING_CAPS (1<<27)/* Controller uses Auto CMD12 comma nd to stop the transfer */#define SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12 (1&LT;&LT;28)//Controller doesn ' t has hisp D bit field in Hi-speed SD card */#define SDHCI_QUIRK_NO_HISPD_BIT (1<<29)//Controller treats ADMA des Criptors with length 0000h incorrectly */#define SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC (1&LT;&LT;30)/* The read-on Ly detection via sdhci_present_state Register is unstable */#define SDHCI_QUIRK_UNSTABLE_RO_DETECT (1<<31) 
Quirks 2 (SDHCI_HOST-&GT;QUIRKS2) Each bit has the following meanings:
#define SDHCI_QUIRK2_HOST_OFF_CARD_ON (1<<0) #define SDHCI_QUIRK2_HOST_NO_CMD23 (1<<1)/* T He system physically doesn ' t support 1.8v, even if the host does */#define SDHCI_QUIRK2_NO_1_8_V (1<< 2) #define SDHCI_QUIRK2_PRESET_VALUE_BROKEN (1&LT;&LT;3)/* * Read Transfer active/write Transfer Active May n OT * de-asserted after end of transaction.
 Issue reset for DAT line.  */#define SDHCI_QUIRK2_RDWR_TX_ACTIVE_EOT (1&LT;&LT;4)//* Slow interrupt clearance at 400KHZ may cause * Host
 Controller driver Interrupt Handler to * be called twice. */#define SDHCI_QUIRK2_SLOW_INT_CLR (1&LT;&LT;5)/* * If the base clock can be scalable and then there should be
 No further * clock dividing as the input clock itself would be a scaled down to * required frequency. */#define SDHCI_QUIRK2_ALWAYS_USE_BASE_CLOCK (1&LT;&LT;6)/* * Dont Use the max_discard_to in SDHCI driver so The maximum discard * unit gets PIcked by the MMC queue.
 Otherwise, it takes a long time for * secure discard kind of operations to complete. * * #define SDHCI_QUIRK2_USE_MAX_DISCARD_SIZE (1&LT;&LT;7)/* * Ignore Data timeout error for R1B commands as there Would is no * data associated and the busy timeout value for these commands * could be lager than the maximum timeout Val
 UE that controller * can handle. */#define SDHCI_QUIRK2_IGNORE_DATATOUT_FOR_R1BCMD (1&LT;&LT;8)/* * The preset value registers is not properly init
 ialized by * Some hardware and hence preset value must is enabled for * such controllers. */#define SDHCI_QUIRK2_BROKEN_PRESET_VALUE (1&LT;&LT;9)//* Some controllers define the usage of 0xF in data Tim
 Eout counter * Register (0X2E) which is actually a reserved bit as per * specification. */#define SDHCI_QUIRK2_USE_RESERVED_MAX_TIMEOUT (1&LT;&LT;10)/* * This was applicable for controllers that Adverti Ze Timeout clock * value in capabilities register (bit5-0) as just 50MHz whereas the * base clock frequency is 200MHz. So, the controller internally * Multiplies the value in the timeout control register by 4 with the * assumption that driver Always uses fixed timeout clock value from * capabilities register to calculate the timeout. But when the driver * uses Sdhci_quirk2_always_use_base_clock BASE CLOCK frequency was directly * Controller by driver an D It ' s rate varies upto max. 200MHz. This new quirk * would be used in such cases to avoid controller mulplication when timeout was * calculated based on the B
 ASE clock. */#define SDHCI_QUIRK2_DIVIDE_TOUT_BY_4 (1 <<)/* Some SDHC Controllers is unable to handle data-end bit err
 or in * 1-bit mode of SDIO. */#define SDHCI_QUIRK2_IGN_DATA_END_BIT_ERROR (1&LT;&LT;12)/* * Some SDHC controllers do not require DATA             Buffers Alignment, skip * The Bounce buffer logic when preparing data */#define Sdhci_quirk2_adma_skip_data_alignment (1<<13)/* Some controllers doesn ' t has any LED control */#define SDHCI_QUIRK2_BROKEN_LED_CONTROL (1 <<)/* Use Reset Workaround in case SDHCI reset timeouts */#define SDHCI_QUIRK2_USE_RESET_WORKAROUND (1 << 15)
Some of the SDHCI host's identities (Sdhci_host->flags) are as follows:
#define SDHCI_USE_SDMA (1<<0)/* Host is SDMA capable */#define SDHCI_USE_ADMA (1&LT;&LT;1)/* Host is ADMA capable */#define SDHCI_REQ_USE_DMA (1&LT;&LT;2)/* Use DMA for this REQ. */#define SDHCI_DEVICE_DEAD (1&LT;&L T;3)/* Device unresponsive */#define SDHCI_SDR50_NEEDS_TUNING (1<<4)/* SDR50 NEEDS TUNING */#define Sdhci_needs _retuning (1<<5)/* Host needs retuning */#define SDHCI_AUTO_CMD12 (1<<6)/* AUTO CMD12 support */#d  Efine sdhci_auto_cmd23 (1<<7)/* AUTO CMD23 Support */#define SDHCI_PV_ENABLED (1<<8)/* Preset value Enabled */#define SDHCI_SDIO_IRQ_ENABLED (1&LT;&LT;9)//SDIO IRQ ENABLED */#define SDHCI_HS200_NEEDS_TUNING (1&LT;&L T;10)/* HS200 needs tuning */#define SDHCI_USING_RETUNING_TIMER (1&LT;&LT;11)/* Host is USING a retuning TIMER for The card */#define SDHCI_HS400_NEEDS_TUNING (1&LT;&LT;12)//HS400 NEEDS TUNING */#define SDHCI_USE_ADMA_64BIT (1 &LT;&LT;13)/* Host is 64-bit ADMA Capable * * 
2. struct Sdhci_ops structural body

SDHCI Core simply provides some interfaces and an MMC core-compliant operation set method for use with the corresponding host driver. Because the hardware of each host is different, the driver part of actual and hardware interaction is implemented in host driver.
So SDHCI core requires host to provide standard methods of accessing the hardware. These methods are defined within the struct sdhci_ops structure.
The structure is as follows:

struct Sdhci_ops {#ifdef config_mmc_sdhci_io_accessors///indicates that host also provides a way to access the register, without a definition, the method of using a universal read-write register u32 (*read_l)
    (struct sdhci_host *host, int reg);
    U16 (*read_w) (struct sdhci_host *host, int reg);
    U8 (*read_b) (struct sdhci_host *host, int reg);
    void (*write_l) (struct Sdhci_host *host, u32 val, int reg);
    void (*write_w) (struct Sdhci_host *host, U16 val, int reg);
void (*write_b) (struct Sdhci_host *host, U8 val, int reg);    #endif void (*set_clock) (struct sdhci_host *host, unsigned int clock);    Set clock frequency int (*ENABLE_DMA) (struct sdhci_host *host);    Enable DMA unsigned int (*get_max_clock) (struct sdhci_host *host);    Gets the maximum supported clock frequency unsigned int (*get_min_clock) (struct sdhci_host *host);
    Gets the minimum supported clock frequency unsigned int (*get_timeout_clock) (struct sdhci_host *host);  
    Int (*platform_bus_width) (struct sdhci_host *host, int width); void (*platform_send_init_74_clocks) (struct sdhci_host *host, U8 Power_mode);    unsigned int (*get_ro) (struct sdhci_host *host);    get Void (*platform_reset_enter) (struct sdhci_host *host, U8 mask);    Method of entering platform reset Void (*platform_reset_exit) (struct sdhci_host *host, U8 mask);    method to exit the platform reset Int (*set_uhs_signaling) (struct sdhci_host *host, unsigned int uhs);    Set uhs mode void (*hw_reset) (struct sdhci_host *host);    Method of hardware reset void (*platform_suspend) (struct sdhci_host *host);    Platform host's Suspend method void (*platform_resume) (struct sdhci_host *host);
    Platform host's Resume method void (*adma_workaround) (struct sdhci_host *host, u32 intmask);    void (*platform_init) (struct sdhci_host *host);    Initialization method for platform host void (*check_power_status) (struct sdhci_host *host, u32 req_type); Detects the power state of the bus #define REQ_BUS_OFF (1 << 0) #define REQ_BUS_ON (1 << 1) #define REQ_IO_LOW (1 << 2) #define REQ_IO_HIGH (1 << 3) Int (*execute_tuning) (struct sdhci_host *host, u32 opcode);
    Method of performing the tuning Operation Void (*TOGGLE_CDR) (struct sdhci_host *host, bool enable);
    unsigned int (*get_max_segments) (void);    void (*platform_bus_voting) (struct sdhci_host *host, u32 enable);
    Method for platform bus voting void (*disable_data_xfer) (struct sdhci_host *host);
    void (*dump_vendor_regs) (struct sdhci_host *host); Int (*config_auto_tuning_cmd) (struct sdhci_host *host, bool Enable, U32 Typ
    e);
    Int (*enable_controller_clock) (struct sdhci_host *host);
void (*reset_workaround) (struct sdhci_host *host, u32 enable); };

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.