From patchwork Fri Jan 4 09:34:05 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amar X-Patchwork-Id: 209413 X-Patchwork-Delegate: promsoft@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id DAB482C0086 for ; Fri, 4 Jan 2013 20:13:33 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 372854A136; Fri, 4 Jan 2013 10:13:13 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id CRGkJWE4U1yy; Fri, 4 Jan 2013 10:13:12 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 33ED54A107; Fri, 4 Jan 2013 10:12:37 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 74B494A0C1 for ; Fri, 4 Jan 2013 10:12:29 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id NSSBhAChnhXh for ; Fri, 4 Jan 2013 10:12:27 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mailout3.samsung.com (mailout3.samsung.com [203.254.224.33]) by theia.denx.de (Postfix) with ESMTP id 7615C4A0BD for ; Fri, 4 Jan 2013 10:12:23 +0100 (CET) Received: from epcpsbgm2.samsung.com (epcpsbgm2 [203.254.230.27]) by mailout3.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MG300CEDG24BSR0@mailout3.samsung.com> for u-boot@lists.denx.de; Fri, 04 Jan 2013 18:12:11 +0900 (KST) Received: from epcpsbgm2.samsung.com ( [172.20.52.125]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id 7F.F3.12699.BEC96E05; Fri, 04 Jan 2013 18:12:11 +0900 (KST) X-AuditID: cbfee61b-b7f616d00000319b-4e-50e69ceb9339 Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id EE.F3.12699.AEC96E05; Fri, 04 Jan 2013 18:12:10 +0900 (KST) Received: from chrome-ubuntu.sisodomain.com ([107.108.73.106]) by mmp1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0MG30081AG7XXLA0@mmp1.samsung.com> for u-boot@lists.denx.de; Fri, 04 Jan 2013 18:12:10 +0900 (KST) From: Amar To: u-boot@lists.denx.de, jh80.chung@samsung.com Date: Fri, 04 Jan 2013 04:34:05 -0500 Message-id: <1357292050-12137-5-git-send-email-amarendra.xt@samsung.com> X-Mailer: git-send-email 1.8.0 In-reply-to: <1357292050-12137-1-git-send-email-amarendra.xt@samsung.com> References: <1357292050-12137-1-git-send-email-amarendra.xt@samsung.com> DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrOLMWRmVeSWpSXmKPExsWyRsSkVvf1nGcBBpt2cVq83dvJ7sDocfbO DsYAxigum5TUnMyy1CJ9uwSujM//bzAWHDCt6Oh8zNrAuFuri5GTQ0LAROLViX9MELaYxIV7 69m6GLk4hASWMkoc2zyTHabo1tvFrBCJRYwSO5fNYARJCAksY5LY2ZjRxcjBwSagKvFrsT1I WETAQGL6k+2sIGFmgQKJZ7vFQMLCAs4Si96vYQQJswBVt2zKBQnzCnhIdO54C3WCnMSHPY/Y QUo4BTwlNl0RATGFgEquHioBqWAREJD4NvkQC0hYQkBWYtMBZpCzJASus0n8vLQQaoqkxMEV N1gmMAovYGRYxSiaWpBcUJyUnmukV5yYW1yal66XnJ+7iREYeqf/PZPewbiqweIQowAHoxIP r+WdpwFCrIllxZW5hxglOJiVRHg/az8LEOJNSaysSi3Kjy8qzUktPsToA3TJRGYp0eR8YFzk lcQbGpuYmxqbWhoZmZma4hBWEudlPPUkQEggPbEkNTs1tSC1CGYcEwenVAOj8xSp7P+PHzIG P3wosFj+l/mEFV+0Jq1iPpb/evOCZxkcq03XPz6dsf9RzrrgHSmRl4K+Pl1dcuO3UOeZbfXM E9LDfzXquU29/PxDgFJs1tFjDBN/PDeYrrisJDOp23nxyf9P/dQNb0rbLF4Y9YcllaGD59dy Q9V6+QxVlXfBZ43/OURwKASrKbEUZyQaajEXFScCAModF9NqAgAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpjkeLIzCtJLcpLzFFi42I5/e+xgO6rOc8CDD68MrF4u7eT3YHR4+yd HYwBjFENjDYZqYkpqUUKqXnJ+SmZeem2St7B8c7xpmYGhrqGlhbmSgp5ibmptkouPgG6bpk5 QGOVFMoSc0qBQgGJxcVK+naYJoSGuOlawDRG6PqGBMH1GBmggYQ1jBmf/99gLDhgWtHR+Zi1 gXG3VhcjJ4eEgInErbeLWSFsMYkL99azdTFycQgJLGKU2LlsBiNIQkhgGZPEzsaMLkYODjYB VYlfi+1BwiICBhLTn2xnBQkzCxRIPNstBhIWFnCWWPR+DSNImAWoumVTLkiYV8BDonPHWyaI TXISH/Y8Ygcp4RTwlNh0RQTEFAIquXqoZAIj7wJGhlWMoqkFyQXFSem5RnrFibnFpXnpesn5 uZsYwYH9THoH46oGi0OMAhyMSjy8lneeBgixJpYVV+YeYpTgYFYS4f2s/SxAiDclsbIqtSg/ vqg0J7X4EKMP0EkTmaVEk/OBUZdXEm9obGJuamxqaWJhYmaJQ1hJnJfx1JMAIYH0xJLU7NTU gtQimHFMHJxSDYxxgV3Ljt69ZL72za4bp5N2eCatTVgdMnf/9Bc+tR1NsTzWSw3PGl3Of/NG 6aPTJn57genvJh1csu0hU79Bh5vOigvCW8yvPerlvzhLUoRd2ts1Ulp8286mrXHmwn/+Tv38 dsr9VDeWu65qEkFlL7f5S8Wq/dm9/n3+w+pYR2EZhfdlL1uEvmspsRRnJBpqMRcVJwIAto7V TpkCAAA= X-CFilter-Loop: Reflected Cc: afleming@gmail.com, patches@linaro.org Subject: [U-Boot] [PATCH V4 4/9] EXYNOS5: DWMMC: Added FDT support for DWMMC X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de This patch adds FDT support for DWMMC, by reading the DWMMC node data from the device tree and initialising DWMMC channels as per data obtained from the node. Changes from V1: 1)Updated code to have same signature for the function exynos_dwmci_init() for both FDT and non-FDT versions. 2)Updated code to pass device_id parameter to the function exynos5_mmc_set_clk_div() instead of index. 3)Updated code to decode the value of "samsung,width" from FDT. 4)Channel index is computed instead of getting from FDT. Changes from V2: 1)Updation of commit message and resubmition of proper patch set. Changes from V3: 1)Replaced the new function exynos5_mmc_set_clk_div() with the existing function set_mmc_clk(). set_mmc_clk() will do the purpose. 2)Computation of FSYS block clock divisor (pre-ratio) is added. Signed-off-by: Vivek Gautam Signed-off-by: Amar --- arch/arm/include/asm/arch-exynos/dwmmc.h | 4 + drivers/mmc/exynos_dw_mmc.c | 129 +++++++++++++++++++++++++++++-- include/dwmmc.h | 4 + 3 files changed, 130 insertions(+), 7 deletions(-) diff --git a/arch/arm/include/asm/arch-exynos/dwmmc.h b/arch/arm/include/asm/arch-exynos/dwmmc.h index 8acdf9b..40dcc7b 100644 --- a/arch/arm/include/asm/arch-exynos/dwmmc.h +++ b/arch/arm/include/asm/arch-exynos/dwmmc.h @@ -29,8 +29,12 @@ int exynos_dwmci_init(u32 regbase, int bus_width, int index); +#ifdef CONFIG_OF_CONTROL +unsigned int exynos_dwmmc_init(const void *blob); +#else static inline unsigned int exynos_dwmmc_init(int index, int bus_width) { unsigned int base = samsung_get_base_mmc() + (0x10000 * index); return exynos_dwmci_init(base, bus_width, index); } +#endif diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c index 72a31b7..d7ca7d0 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -19,39 +19,154 @@ */ #include -#include #include +#include +#include +#include #include #include +#include + +#define DWMMC_MAX_CH_NUM 4 +#define DWMMC_MAX_FREQ 52000000 +#define DWMMC_MIN_FREQ 400000 +#define DWMMC_MMC0_CLKSEL_VAL 0x03030001 +#define DWMMC_MMC2_CLKSEL_VAL 0x03020001 +#define ONE_MEGA_HZ 1000000 +#define SCALED_VAL_FOUR_HUNDRED 400 static char *EXYNOS_NAME = "EXYNOS DWMMC"; +u32 timing[3]; +/* + * Function used as callback function to initialise the + * CLKSEL register for every mmc channel. + */ static void exynos_dwmci_clksel(struct dwmci_host *host) { - u32 val; - val = DWMCI_SET_SAMPLE_CLK(DWMCI_SHIFT_0) | - DWMCI_SET_DRV_CLK(DWMCI_SHIFT_0) | DWMCI_SET_DIV_RATIO(0); + dwmci_writel(host, DWMCI_CLKSEL, host->clksel_val); +} - dwmci_writel(host, DWMCI_CLKSEL, val); +unsigned int exynos_dwmci_get_clk(int dev_index) +{ + return get_mmc_clk(dev_index); } int exynos_dwmci_init(u32 regbase, int bus_width, int index) { struct dwmci_host *host = NULL; + unsigned int clock, div; host = malloc(sizeof(struct dwmci_host)); if (!host) { printf("dwmci_host malloc fail!\n"); return 1; } + /* + * The max operating freq of FSYS block is 400MHz. + * Scale down the 400MHz to number 400. + * Scale down the MPLL clock by dividing MPLL_CLK with ONE_MEGA_HZ. + * Arrive at the divisor value taking 400 as the reference. + */ + + /* get mpll clock and divide it by ONE_MEGA_HZ */ + clock = get_pll_clk(MPLL) / ONE_MEGA_HZ; + + /* Arrive at the divisor value. */ + for (div = 0; div <= 0xf; div++) { + if ((clock / (div + 1)) <= SCALED_VAL_FOUR_HUNDRED) + break; + } + + /* set the clock divisor for mmc */ + set_mmc_clk(index, div); + host->name = EXYNOS_NAME; host->ioaddr = (void *)regbase; host->buswidth = bus_width; +#ifdef CONFIG_OF_CONTROL + host->clksel_val = (DWMCI_SET_SAMPLE_CLK(timing[0]) | + DWMCI_SET_DRV_CLK(timing[1]) | + DWMCI_SET_DIV_RATIO(timing[2])); +#else + if (0 == index) + host->clksel_val = DWMMC_MMC0_CLKSEL_VAL; + if (2 == index) + host->clksel_val = DWMMC_MMC2_CLKSEL_VAL; +#endif host->clksel = exynos_dwmci_clksel; host->dev_index = index; - - add_dwmci(host, 52000000, 400000); + host->mmc_clk = exynos_dwmci_get_clk; + /* Add the mmc chennel to be registered with mmc core */ + add_dwmci(host, DWMMC_MAX_FREQ, DWMMC_MIN_FREQ); return 0; } +#ifdef CONFIG_OF_CONTROL +unsigned int exynos_dwmmc_init(const void *blob) +{ + u32 base; + int index, bus_width; + int node_list[DWMMC_MAX_CH_NUM]; + int err = 0; + int dev_id, flag; + int count, i; + + count = fdtdec_find_aliases_for_id(blob, "dwmmc", + COMPAT_SAMSUNG_EXYNOS5_DWMMC, node_list, + DWMMC_MAX_CH_NUM); + + for (i = 0; i < count; i++) { + int node = node_list[i]; + + if (node <= 0) + continue; + + /* Extract device id for each mmc channel */ + dev_id = pinmux_decode_periph_id(blob, node); + + /* Get the bus width from the device node */ + bus_width = fdtdec_get_int(blob, node, "samsung,bus-width", 0); + if (bus_width < 0) { + debug("DWMMC: Can't get bus-width\n"); + return -1; + } + if (8 == bus_width) + flag = PINMUX_FLAG_8BIT_MODE; + else + flag = PINMUX_FLAG_NONE; + + /* config pinmux for each mmc channel */ + err = exynos_pinmux_config(dev_id, flag); + if (err) { + debug("DWMMC not configured\n"); + return err; + } + + index = dev_id - PERIPH_ID_SDMMC0; + + /* Get the base address from the device node */ + base = fdtdec_get_addr(blob, node, "reg"); + if (!base) { + debug("DWMMC: Can't get base address\n"); + return -1; + } + /* Extract the timing info from the node */ + err = fdtdec_get_int_array(blob, node, "samsung,timing", + timing, 3); + if (err) { + debug("Can't get sdr-timings for divider\n"); + return -1; + } + /* Initialise each mmc channel */ + err = exynos_dwmci_init(base, bus_width, index); + if (err) { + debug("Can't do dwmci init\n"); + return -1; + } + } + + return 0; +} +#endif diff --git a/include/dwmmc.h b/include/dwmmc.h index c8b1d40..4a42849 100644 --- a/include/dwmmc.h +++ b/include/dwmmc.h @@ -123,6 +123,9 @@ #define MSIZE(x) ((x) << 28) #define RX_WMARK(x) ((x) << 16) #define TX_WMARK(x) (x) +#define RX_WMARK_SHIFT 16 +#define RX_WMARK_MASK (0xfff << RX_WMARK_SHIFT) + #define DWMCI_IDMAC_OWN (1 << 31) #define DWMCI_IDMAC_CH (1 << 4) @@ -144,6 +147,7 @@ struct dwmci_host { unsigned int bus_hz; int dev_index; int buswidth; + u32 clksel_val; u32 fifoth_val; struct mmc *mmc;