feat(mmc): manage SD Switch Function for high speed mode

On SD-cards, Switch Function Command (CMD6) is used to switch
functions, like setting High Speed mode. It is useful for high capacity
cards to double frequency (from 25MHz by default to 50MHz).
If the SD-card is High Capacity, a CMD6 is issued after filling the
device information. If High Speed mode is supported and the switch is
OK, then the max_bus_freq can be set to 50MHz. The driver set_ios()
function should then be called to update peripheral configuration,
especially clock prescaler.

Change-Id: I2d6807aa7f9440d2b2f907a747cd3b47a2ba1545
Signed-off-by: Yann Gautier <yann.gautier@st.com>
diff --git a/include/drivers/mmc.h b/include/drivers/mmc.h
index c154ea5..e973248 100644
--- a/include/drivers/mmc.h
+++ b/include/drivers/mmc.h
@@ -111,6 +111,7 @@
 #define MMC_STATE_SLP			10
 
 #define MMC_FLAG_CMD23			(U(1) << 0)
+#define MMC_FLAG_SD_CMD6		(U(1) << 1)
 
 #define CMD8_CHECK_PATTERN		U(0xAA)
 #define VHS_2_7_3_6_V			BIT(8)
@@ -118,6 +119,10 @@
 #define SD_SCR_BUS_WIDTH_1		BIT(8)
 #define SD_SCR_BUS_WIDTH_4		BIT(10)
 
+#define SD_SWITCH_FUNC_CHECK		0U
+#define SD_SWITCH_FUNC_SWITCH		BIT(31)
+#define SD_SWITCH_ALL_GROUPS_MASK	GENMASK(23, 0)
+
 struct mmc_cmd {
 	unsigned int	cmd_idx;
 	unsigned int	cmd_arg;
@@ -217,6 +222,27 @@
 	unsigned int		csd_structure:		2;
 };
 
+struct sd_switch_status {
+	unsigned short		max_current;
+	unsigned short		support_g6;
+	unsigned short		support_g5;
+	unsigned short		support_g4;
+	unsigned short		support_g3;
+	unsigned short		support_g2;
+	unsigned short		support_g1;
+	unsigned char		sel_g6_g5;
+	unsigned char		sel_g4_g3;
+	unsigned char		sel_g2_g1;
+	unsigned char		data_struct_ver;
+	unsigned short		busy_g6;
+	unsigned short		busy_g5;
+	unsigned short		busy_g4;
+	unsigned short		busy_g3;
+	unsigned short		busy_g2;
+	unsigned short		busy_g1;
+	unsigned short		reserved[17];
+};
+
 enum mmc_device_type {
 	MMC_IS_EMMC,
 	MMC_IS_SD,