Pārlūkot izejas kodu

mmc: dw_mmc: set the supported max/min frequency

Both f_max and f_min will be informed for core layer to request
valid clock rate. But current setting from 'host->bus_hz' may
not represent the max/min frequency properly. Even if host can
actually support high speed than bus_hz, core layer will not
request clock rate over bus_hz. Basically, f_max/f_min can be set
with the values according to spec. And then host will make its best
effort to meet the rate.

Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com>
Tested-by: Alim Akhtar <alim.akhtar@samsung.com>
Signed-off-by: Chris Ball <cjb@laptop.org>
Seungwon Jeon 12 gadi atpakaļ
vecāks
revīzija
1f44a2a557

+ 4 - 0
Documentation/devicetree/bindings/mmc/synopsis-dw-mshc.txt

@@ -52,6 +52,9 @@ Optional properties:
   is specified and the ciu clock is specified then we'll try to set the ciu
   is specified and the ciu clock is specified then we'll try to set the ciu
   clock to this at probe time.
   clock to this at probe time.
 
 
+* clock-freq-min-max: Minimum and Maximum clock frequency for card output
+  clock(cclk_out). If it's not specified, max is 200MHZ and min is 400KHz by default.
+
 * num-slots: specifies the number of slots supported by the controller.
 * num-slots: specifies the number of slots supported by the controller.
   The number of physical slots actually used could be equal or less than the
   The number of physical slots actually used could be equal or less than the
   value specified by num-slots. If this property is not specified, the value
   value specified by num-slots. If this property is not specified, the value
@@ -97,6 +100,7 @@ board specific portions as listed below.
 
 
 	dwmmc0@12200000 {
 	dwmmc0@12200000 {
 		clock-frequency = <400000000>;
 		clock-frequency = <400000000>;
+		clock-freq-min-max = <400000 200000000>;
 		num-slots = <1>;
 		num-slots = <1>;
 		supports-highspeed;
 		supports-highspeed;
 		caps2-mmc-hs200-1_8v;
 		caps2-mmc-hs200-1_8v;

+ 12 - 2
drivers/mmc/host/dw_mmc.c

@@ -50,6 +50,9 @@
 #define DW_MCI_RECV_STATUS	2
 #define DW_MCI_RECV_STATUS	2
 #define DW_MCI_DMA_THRESHOLD	16
 #define DW_MCI_DMA_THRESHOLD	16
 
 
+#define DW_MCI_FREQ_MAX	200000000	/* unit: HZ */
+#define DW_MCI_FREQ_MIN	400000		/* unit: HZ */
+
 #ifdef CONFIG_MMC_DW_IDMAC
 #ifdef CONFIG_MMC_DW_IDMAC
 #define IDMAC_INT_CLR		(SDMMC_IDMAC_INT_AI | SDMMC_IDMAC_INT_NI | \
 #define IDMAC_INT_CLR		(SDMMC_IDMAC_INT_AI | SDMMC_IDMAC_INT_NI | \
 				 SDMMC_IDMAC_INT_CES | SDMMC_IDMAC_INT_DU | \
 				 SDMMC_IDMAC_INT_CES | SDMMC_IDMAC_INT_DU | \
@@ -1936,6 +1939,7 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
 	struct dw_mci_slot *slot;
 	struct dw_mci_slot *slot;
 	const struct dw_mci_drv_data *drv_data = host->drv_data;
 	const struct dw_mci_drv_data *drv_data = host->drv_data;
 	int ctrl_id, ret;
 	int ctrl_id, ret;
+	u32 freq[2];
 	u8 bus_width;
 	u8 bus_width;
 
 
 	mmc = mmc_alloc_host(sizeof(struct dw_mci_slot), host->dev);
 	mmc = mmc_alloc_host(sizeof(struct dw_mci_slot), host->dev);
@@ -1951,8 +1955,14 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
 	slot->quirks = dw_mci_of_get_slot_quirks(host->dev, slot->id);
 	slot->quirks = dw_mci_of_get_slot_quirks(host->dev, slot->id);
 
 
 	mmc->ops = &dw_mci_ops;
 	mmc->ops = &dw_mci_ops;
-	mmc->f_min = DIV_ROUND_UP(host->bus_hz, 510);
-	mmc->f_max = host->bus_hz;
+	if (of_property_read_u32_array(host->dev->of_node,
+				       "clock-freq-min-max", freq, 2)) {
+		mmc->f_min = DW_MCI_FREQ_MIN;
+		mmc->f_max = DW_MCI_FREQ_MAX;
+	} else {
+		mmc->f_min = freq[0];
+		mmc->f_max = freq[1];
+	}
 
 
 	if (host->pdata->get_ocr)
 	if (host->pdata->get_ocr)
 		mmc->ocr_avail = host->pdata->get_ocr(id);
 		mmc->ocr_avail = host->pdata->get_ocr(id);