diff options
Diffstat (limited to 'include/linux/mmc')
| -rw-r--r-- | include/linux/mmc/card.h | 6 | ||||
| -rw-r--r-- | include/linux/mmc/host.h | 42 | ||||
| -rw-r--r-- | include/linux/mmc/mmc.h | 5 | ||||
| -rw-r--r-- | include/linux/mmc/sd.h | 13 | ||||
| -rw-r--r-- | include/linux/mmc/sdhci.h | 73 | ||||
| -rw-r--r-- | include/linux/mmc/sdio.h | 22 | ||||
| -rw-r--r--[-rwxr-xr-x] | include/linux/mmc/sdio_func.h | 0 | ||||
| -rw-r--r-- | include/linux/mmc/uhs2.h | 25 |
8 files changed, 171 insertions, 15 deletions
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 6a5c754daa4..8969bc33c34 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -249,6 +249,7 @@ struct mmc_card { #define MMC_CARD_REMOVED (1<<7) /* card has been removed */ #define MMC_STATE_HIGHSPEED_200 (1<<8) /* card is in HS200 mode */ #define MMC_STATE_DOING_BKOPS (1<<10) /* card is doing BKOPS */ +#define MMC_STATE_NEED_BKOPS (1<<11) /* Card needs to do bkops */ unsigned int quirks; /* card quirks */ #define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */ #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */ @@ -411,11 +412,11 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data) #define mmc_card_hs200(c) ((c)->state & MMC_STATE_HIGHSPEED_200) #define mmc_card_blockaddr(c) ((c)->state & MMC_STATE_BLOCKADDR) #define mmc_card_ddr_mode(c) ((c)->state & MMC_STATE_HIGHSPEED_DDR) -#define mmc_card_uhs(c) ((c)->state & MMC_STATE_ULTRAHIGHSPEED) #define mmc_sd_card_uhs(c) ((c)->state & MMC_STATE_ULTRAHIGHSPEED) #define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC) #define mmc_card_removed(c) ((c) && ((c)->state & MMC_CARD_REMOVED)) #define mmc_card_doing_bkops(c) ((c)->state & MMC_STATE_DOING_BKOPS) +#define mmc_card_need_bkops(c) ((c)->state & MMC_STATE_NEED_BKOPS) #define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT) #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY) @@ -423,12 +424,13 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data) #define mmc_card_set_hs200(c) ((c)->state |= MMC_STATE_HIGHSPEED_200) #define mmc_card_set_blockaddr(c) ((c)->state |= MMC_STATE_BLOCKADDR) #define mmc_card_set_ddr_mode(c) ((c)->state |= MMC_STATE_HIGHSPEED_DDR) -#define mmc_card_set_uhs(c) ((c)->state |= MMC_STATE_ULTRAHIGHSPEED) #define mmc_sd_card_set_uhs(c) ((c)->state |= MMC_STATE_ULTRAHIGHSPEED) #define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC) #define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED) #define mmc_card_set_doing_bkops(c) ((c)->state |= MMC_STATE_DOING_BKOPS) #define mmc_card_clr_doing_bkops(c) ((c)->state &= ~MMC_STATE_DOING_BKOPS) +#define mmc_card_set_need_bkops(c) ((c)->state |= MMC_STATE_NEED_BKOPS) +#define mmc_card_clk_need_bkops(c) ((c)->state &= ~MMC_STATE_NEED_BKOPS) /* * Quirk add/remove for MMC products. diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 1e163cd7b7d..17d11ea7d24 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -1,6 +1,8 @@ /* * linux/include/linux/mmc/host.h * + * Copyright (c) 2013, NVIDIA CORPORATION. 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. @@ -16,6 +18,7 @@ #include <linux/device.h> #include <linux/fault-inject.h> #include <linux/wakelock.h> +#include <linux/devfreq.h> #include <linux/mmc/core.h> #include <linux/mmc/pm.h> @@ -137,9 +140,20 @@ struct mmc_host_ops { /* The tuning command opcode value is different for SD and eMMC cards */ int (*execute_tuning)(struct mmc_host *host, u32 opcode); - int (*select_drive_strength)(unsigned int max_dtr, int host_drv, int card_drv); + int (*select_drive_strength)(struct mmc_host *host, + unsigned int max_dtr, + int host_drv, int card_drv); void (*hw_reset)(struct mmc_host *host); void (*card_event)(struct mmc_host *host); + + /* + * Device frequency scaling optional callbacks to allow for custom + * algorithms to determine the target frequency. + */ + int (*dfs_governor_init)(struct mmc_host *host); + void (*dfs_governor_exit)(struct mmc_host *host); + int (*dfs_governor_get_target)(struct mmc_host *host, + unsigned long *freq); }; struct mmc_card; @@ -196,6 +210,19 @@ struct mmc_supply { struct regulator *vqmmc; /* Optional Vccq supply */ }; +struct mmc_dev_stats { + /* Device busy and total times in the current interval */ + unsigned long busy_time; + unsigned long total_time; + + /* Active and polling timestamps used for time calculation */ + ktime_t t_busy; + ktime_t t_interval; + + unsigned int polling_interval; + bool update_dev_freq; +}; + /* * X-axis for IO latency histogram support. */ @@ -311,6 +338,8 @@ struct mmc_host { #define MMC_CAP2_PACKED_CMD (MMC_CAP2_PACKED_RD | \ MMC_CAP2_PACKED_WR) #define MMC_CAP2_NO_PRESCAN_POWERUP (1 << 14) /* Don't power up before scan */ +#define MMC_CAP2_FREQ_SCALING (1 << 15) /* Allow frequency scaling */ +#define MMC_CAP2_CLOCK_GATING (1 << 16) /* Enable Clock Gating */ mmc_pm_flag_t pm_caps; /* supported pm features */ @@ -325,6 +354,7 @@ struct mmc_host { struct device_attribute clkgate_delay_attr; unsigned long clkgate_delay; #endif + bool skip_host_clkgate; /* host specific block data */ unsigned int max_seg_size; /* see blk_queue_max_segment_size */ @@ -378,6 +408,13 @@ struct mmc_host { mmc_pm_flag_t pm_flags; /* requested pm features */ + /* MMC DFS and devfreq information */ + struct devfreq *df; + struct devfreq_dev_profile *df_profile; + struct devfreq_dev_status *devfreq_stats; + struct mmc_dev_stats *dev_stats; + struct delayed_work dfs_work; + struct led_trigger *led; /* activity led */ #ifdef CONFIG_REGULATOR @@ -502,6 +539,9 @@ int mmc_card_sleep(struct mmc_host *host); int mmc_card_can_sleep(struct mmc_host *host); int mmc_pm_notify(struct notifier_block *notify_block, unsigned long, void *); +int mmc_speed_class_control(struct mmc_host *host, + unsigned int speed_class_ctrl_arg); + /* Module parameter */ extern bool mmc_assume_removable; diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index 50bcde3677c..223be1b5448 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -331,6 +331,11 @@ struct _mmc_csd { #define EXT_CSD_MAX_PACKED_READS 501 /* RO */ #define EXT_CSD_BKOPS_SUPPORT 502 /* RO */ #define EXT_CSD_HPI_FEATURES 503 /* RO */ +#define EXT_CSD_PWR_CL_200_195 236 /* RO */ +#define EXT_CSD_PWR_CL_200_360 237 /* RO */ +#define EXT_CSD_PWR_CL_DDR_52_195 238 /* RO */ +#define EXT_CSD_PWR_CL_DDR_52_360 239 /* RO */ +#define EXT_CSD_POWER_OFF_LONG_TIME 247 /* RO */ /* * EXT_CSD field definitions diff --git a/include/linux/mmc/sd.h b/include/linux/mmc/sd.h index 1ebcf9ba125..e65bf7c9dab 100644 --- a/include/linux/mmc/sd.h +++ b/include/linux/mmc/sd.h @@ -19,6 +19,10 @@ #define SD_SEND_IF_COND 8 /* bcr [11:0] See below R7 */ #define SD_SWITCH_VOLTAGE 11 /* ac R1 */ + /* class 2 */ +#define SD_SEND_TUNING_PATTERN 19 /* adtc R1 */ +#define SD_SPEED_CLASS_CONTROL 20 /* ac R1b */ + /* class 10 */ #define SD_SWITCH 6 /* adtc [31:0] See below R1 */ @@ -91,4 +95,13 @@ #define SD_SWITCH_ACCESS_DEF 0 #define SD_SWITCH_ACCESS_HS 1 +/* + * SD_SPEED_CLASS_CONTROL definitions + */ +#define SD_SPEED_CLASS_CONTROL_START_REC 0x0 +#define SD_SPEED_CLASS_CONTROL_CREATE_DIR 0x1 +#define SD_SPEED_CLASS_CONTROL_UPDATE_CI 0x4 + + #endif /* LINUX_MMC_SD_H */ + diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h index b838ffc49e4..43c49d76a72 100644 --- a/include/linux/mmc/sdhci.h +++ b/include/linux/mmc/sdhci.h @@ -2,6 +2,7 @@ * linux/include/linux/mmc/sdhci.h - Secure Digital Host Controller Interface * * Copyright (C) 2005-2008 Pierre Ossman, All Rights Reserved. + * Copyright (c) 2013-2014, NVIDIA CORPORATION. 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 as published by @@ -16,12 +17,50 @@ #include <linux/types.h> #include <linux/io.h> #include <linux/mmc/host.h> +#include <linux/sysedp.h> + +#ifdef CONFIG_DEBUG_FS +struct data_stat_entry { + u32 max_kbps; + u32 min_kbps; + ktime_t start_ktime; + u32 duration_usecs; + u32 total_usecs; + u32 current_transferred_bytes; + u64 total_bytes; + u32 stat_blk_size; + u32 stat_blks_per_transfer; + struct data_stat_entry *next; +}; + +/* + * 1. Each block size has a element of type struct data_stat_entry + * 2. For a particular block size we maintain a table of + * performance values observed. This table is used to + * find the most frequent performance value + */ +struct data_stat { + /* + * use insertion sort to keep the list sorted with + * increasing block size + */ + struct data_stat_entry *head; + /* actual number of stat entries */ + u8 stat_size; +}; +#endif struct sdhci_host { /* Data set by hardware interface driver */ const char *hw_name; /* Hardware bus name */ +#ifdef CONFIG_DEBUG_FS + struct dentry *debugfs_root; + /* collect data transfer rate statistics */ + struct data_stat sdhci_data_stat; + unsigned int no_data_transfer_count; +#endif - unsigned int quirks; /* Deviations from spec. */ + u32 quirks; /* Deviations from spec. */ /* Controller doesn't honor resets unless we touch the clock register */ #define SDHCI_QUIRK_CLOCK_BEFORE_RESET (1<<0) @@ -91,10 +130,27 @@ struct sdhci_host { unsigned int quirks2; /* More deviations from spec. */ #define SDHCI_QUIRK2_HOST_OFF_CARD_ON (1<<0) +/* Controller cannot support CMD23 */ #define SDHCI_QUIRK2_HOST_NO_CMD23 (1<<1) /* The 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<<3) +/* Controller clock should be ON for register access */ +#define SDHCI_QUIRK2_REG_ACCESS_REQ_HOST_CLK (1<<4) +/* Controller cannot report the line status in present state register */ +#define SDHCI_QUIRK2_NON_STD_VOLTAGE_SWITCHING (1<<5) +/* Controller doesn't follow the standard frequency tuning procedure */ +#define SDHCI_QUIRK2_NON_STANDARD_TUNING (1<<6) +/* Controller doesn't calculate max_discard_to */ +#define SDHCI_QUIRK2_NO_CALC_MAX_DISCARD_TO (1<<7) +/* Controller needs a dummy write after INT_CLK_EN for clock to be stable */ +#define SDHCI_QUIRK2_INT_CLK_STABLE_REQ_DUMMY_REG_WRITE (1<<8) +/* Controller supports 64 BIT DMA mode */ +#define SDHCI_QUIRK2_SUPPORT_64BIT_DMA (1<<9) +/* Use 64 BIT addressing */ +#define SDHCI_QUIRK2_USE_64BIT_ADDR (1<<10) +/* delayed clock gate */ +#define SDHCI_QUIRK2_DELAYED_CLK_GATE (1<<11) int irq; /* Device IRQ */ void __iomem *ioaddr; /* Mapped address */ @@ -155,11 +211,13 @@ struct sdhci_host { dma_addr_t adma_addr; /* Mapped ADMA descr. table */ dma_addr_t align_addr; /* Mapped bounce buffer */ + bool use_dma_alloc; struct tasklet_struct card_tasklet; /* Tasklet structures */ struct tasklet_struct finish_tasklet; struct timer_list timer; /* Timer for timeouts */ + unsigned int card_int_set; /* card int status */ u32 caps; /* Alternative CAPABILITY_0 */ u32 caps1; /* Alternative CAPABILITY_1 */ @@ -176,6 +234,19 @@ struct sdhci_host { #define SDHCI_TUNING_MODE_1 0 struct timer_list tuning_timer; /* Timer for tuning */ + struct sysedp_consumer *sysedpc; + + struct delayed_work delayed_clk_gate_wrk; + bool is_clk_on; +#ifdef CONFIG_DEBUG_FS + bool enable_sdhci_perf_stats; +#endif + int clk_gate_tmout_ticks; + unsigned long private[0] ____cacheline_aligned; }; + +/* callback is registered during init */ +void delayed_clk_gate_cb(struct work_struct *work); + #endif /* LINUX_MMC_SDHCI_H */ diff --git a/include/linux/mmc/sdio.h b/include/linux/mmc/sdio.h index 17446d3c360..4bc451b93d0 100644 --- a/include/linux/mmc/sdio.h +++ b/include/linux/mmc/sdio.h @@ -38,8 +38,8 @@ * [8:0] Byte/block count */ -#define R4_18V_PRESENT (1<<24) -#define R4_MEMORY_PRESENT (1 << 27) +#define R4_18V_PRESENT BIT(24) +#define R4_MEMORY_PRESENT BIT(27) /* SDIO status in R5 @@ -139,12 +139,12 @@ #define SDIO_SPEED_SHS 0x01 /* Supports High-Speed mode */ #define SDIO_SPEED_BSS_SHIFT 1 -#define SDIO_SPEED_BSS_MASK (7<<SDIO_SPEED_BSS_SHIFT) -#define SDIO_SPEED_SDR12 (0<<SDIO_SPEED_BSS_SHIFT) -#define SDIO_SPEED_SDR25 (1<<SDIO_SPEED_BSS_SHIFT) -#define SDIO_SPEED_SDR50 (2<<SDIO_SPEED_BSS_SHIFT) -#define SDIO_SPEED_SDR104 (3<<SDIO_SPEED_BSS_SHIFT) -#define SDIO_SPEED_DDR50 (4<<SDIO_SPEED_BSS_SHIFT) +#define SDIO_SPEED_BSS_MASK (7 << SDIO_SPEED_BSS_SHIFT) +#define SDIO_SPEED_SDR12 (0 << SDIO_SPEED_BSS_SHIFT) +#define SDIO_SPEED_SDR25 (1 << SDIO_SPEED_BSS_SHIFT) +#define SDIO_SPEED_SDR50 (2 << SDIO_SPEED_BSS_SHIFT) +#define SDIO_SPEED_SDR104 (3 << SDIO_SPEED_BSS_SHIFT) +#define SDIO_SPEED_DDR50 (4 << SDIO_SPEED_BSS_SHIFT) #define SDIO_SPEED_EHS SDIO_SPEED_SDR25 /* Enable High-Speed */ #define SDIO_CCCR_UHS 0x14 @@ -154,9 +154,9 @@ #define SDIO_CCCR_DRIVE_STRENGTH 0x15 #define SDIO_SDTx_MASK 0x07 -#define SDIO_DRIVE_SDTA (1<<0) -#define SDIO_DRIVE_SDTC (1<<1) -#define SDIO_DRIVE_SDTD (1<<2) +#define SDIO_DRIVE_SDTA (1 << 0) +#define SDIO_DRIVE_SDTC (1 << 1) +#define SDIO_DRIVE_SDTD (1 << 2) #define SDIO_DRIVE_DTSx_MASK 0x03 #define SDIO_DRIVE_DTSx_SHIFT 4 #define SDIO_DTSx_SET_TYPE_B (0 << SDIO_DRIVE_DTSx_SHIFT) diff --git a/include/linux/mmc/sdio_func.h b/include/linux/mmc/sdio_func.h index dc680c4b50d..dc680c4b50d 100755..100644 --- a/include/linux/mmc/sdio_func.h +++ b/include/linux/mmc/sdio_func.h diff --git a/include/linux/mmc/uhs2.h b/include/linux/mmc/uhs2.h new file mode 100644 index 00000000000..bea9edb466a --- /dev/null +++ b/include/linux/mmc/uhs2.h @@ -0,0 +1,25 @@ +/* + * include/linux/mmc/uhs2.h + * + * Copyright (C) 2011-2012 NVIDIA Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + */ + +#ifndef MMC_UHS2_H +#define MMC_UHS2_H + +/* UHS2 commands */ + +#define UHS2_FULL_RESET 0x00 +#define UHS2_GO_DORMANT_STATE 0x01 +#define UHS2_DEVICE_INIT 0x02 +#define UHS2_ENUMERATE 0x03 +#define UHS2_TRANS_ABORT 0x04 + +#endif + + |
