aboutsummaryrefslogtreecommitdiff
path: root/include/linux/mmc
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/mmc')
-rw-r--r--include/linux/mmc/card.h6
-rw-r--r--include/linux/mmc/host.h42
-rw-r--r--include/linux/mmc/mmc.h5
-rw-r--r--include/linux/mmc/sd.h13
-rw-r--r--include/linux/mmc/sdhci.h73
-rw-r--r--include/linux/mmc/sdio.h22
-rw-r--r--[-rwxr-xr-x]include/linux/mmc/sdio_func.h0
-rw-r--r--include/linux/mmc/uhs2.h25
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
+
+