From patchwork Mon Dec 31 10:58:15 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amar X-Patchwork-Id: 208824 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 ABC382C00A7 for ; Mon, 31 Dec 2012 21:38:48 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 9E3AA4A03A; Mon, 31 Dec 2012 11:38: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 rk3-mjd6Y2jK; Mon, 31 Dec 2012 11:38:29 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id D42664A0B0; Mon, 31 Dec 2012 11:37:56 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 2762B4A025 for ; Mon, 31 Dec 2012 11:36:39 +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 ZJQ2rNpmO8Nf for ; Mon, 31 Dec 2012 11:36:37 +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 mailout4.samsung.com (mailout4.samsung.com [203.254.224.34]) by theia.denx.de (Postfix) with ESMTP id 171AF4A032 for ; Mon, 31 Dec 2012 11:36:22 +0100 (CET) Received: from epcpsbgm1.samsung.com (epcpsbgm1 [203.254.230.26]) by mailout4.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MFW009QX5G7FY70@mailout4.samsung.com> for u-boot@lists.denx.de; Mon, 31 Dec 2012 19:36:15 +0900 (KST) Received: from epcpsbgm1.samsung.com ( [172.20.52.122]) by epcpsbgm1.samsung.com (EPCPMTA) with SMTP id EB.B2.01231.F9A61E05; Mon, 31 Dec 2012 19:36:15 +0900 (KST) X-AuditID: cbfee61a-b7fa66d0000004cf-77-50e16a9f1574 Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm1.samsung.com (EPCPMTA) with SMTP id 5B.B2.01231.F9A61E05; Mon, 31 Dec 2012 19:36:15 +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 <0MFW00JL05G0TP80@mmp1.samsung.com> for u-boot@lists.denx.de; Mon, 31 Dec 2012 19:36:15 +0900 (KST) From: Amar To: u-boot@lists.denx.de, jh80.chung@samsung.com Date: Mon, 31 Dec 2012 05:58:15 -0500 Message-id: <1356951500-22490-5-git-send-email-amarendra.xt@samsung.com> X-Mailer: git-send-email 1.8.0 In-reply-to: <1356951500-22490-1-git-send-email-amarendra.xt@samsung.com> References: <1356951500-22490-1-git-send-email-amarendra.xt@samsung.com> DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrFLMWRmVeSWpSXmKPExsWyRsSkSnd+1sMAg03frCze7u1kd2D0OHtn B2MAYxSXTUpqTmZZapG+XQJXxsOdu9kKVhpUHHnzn6WB8bZaFyMnh4SAicTqDZfZIWwxiQv3 1rN1MXJxCAksZZSYNXMpM0xR591rUIlFjBInvuxjgnCWMUl8+viCsYuRg4NNQFXi12J7kAYR AQOJ6U+2s4KEmQUKJJ7tFgMJCws4SzR92wg2kwWoetPRf8wgJbwCHhLtx2MgVslJfNjzCOwe TgFPidNbdoCVCwGV3OxeyA7RKiDxbfIhFpBWCQFZiU0HmEGOkRC4zCYx/es8qJMlJQ6uuMEy gVF4ASPDKkbR1ILkguKk9FxDveLE3OLSvHS95PzcTYzAADz975nUDsaVDRaHGAU4GJV4eLmY HgYIsSaWFVfmHmKU4GBWEuF9qwUU4k1JrKxKLcqPLyrNSS0+xOgDdMlEZinR5HxgdOSVxBsa m5ibGptaGhmZmZriEFYS5232SAkQEkhPLEnNTk0tSC2CGcfEwSnVwDiNo+Rc90X53cr1Sb7r GCtSI2O52BSC2tg/J//wfP7hqKooT+z9yjlSrL+WTJh7Ys1ivu1+/beX37mb4B3j1v73Rsnl lQfeinRequLYN5H/zWo7X4vbDYlh6gv3Xtw990lzs4cy/4LYnymFpot/7pZ4PPHF4ZXlkU4a qzXd/R/NOXdyZcWdw8uUWIozEg21mIuKEwERIQR1bQIAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupkkeLIzCtJLcpLzFFi42I5/e+xgO78rIcBBsfXaFi83dvJ7sDocfbO DsYAxqgGRpuM1MSU1CKF1Lzk/JTMvHRbJe/geOd4UzMDQ11DSwtzJYW8xNxUWyUXnwBdt8wc oLFKCmWJOaVAoYDE4mIlfTtME0JD3HQtYBojdH1DguB6jAzQQMIaxoyHO3ezFaw0qDjy5j9L A+NttS5GTg4JAROJzrvX2CBsMYkL99YD2VwcQgKLGCVOfNnHBOEsY5L49PEFYxcjBwebgKrE r8X2IA0iAgYS059sZwUJMwsUSDzbLQYSFhZwlmj6tpEZxGYBqt509B8zSAmvgIdE+/EYiFVy Eh/2PGIHsTkFPCVOb9kBVi4EVHKzeyH7BEbeBYwMqxhFUwuSC4qT0nMN9YoTc4tL89L1kvNz NzGCw/uZ1A7GlQ0WhxgFOBiVeHi5mB4GCLEmlhVX5h5ilOBgVhLhfasFFOJNSaysSi3Kjy8q zUktPsToA3TURGYp0eR8YOzllcQbGpuYmxqbWppYmJhZ4hBWEudt9kgJEBJITyxJzU5NLUgt ghnHxMEp1cB4kKPnz7lQ5X0LPhvNWPLcpfXlO1vTvCvaGjt9mNZOuf5/gyLf+eRl7mWCWx+3 L170N3lPfa912ITdzpuXTl86b33CXRFhdRcFjc1/Y7sappkGHtcJujvLdZaSrJphI+sX9/qT Ws3WSkHTUuLr263CZHRvKrwoWxbRcfP9RffPR7e8EH/56riEEktxRqKhFnNRcSIA99KJopwC AAA= X-CFilter-Loop: Reflected Cc: afleming@gmail.com, patches@linaro.org Subject: [U-Boot] [PATCH V3 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. Signed-off-by: Vivek Gautam Signed-off-by: Amar --- arch/arm/include/asm/arch-exynos/dwmmc.h | 4 ++ drivers/mmc/exynos_dw_mmc.c | 116 +++++++++++++++++++++++++++++-- include/dwmmc.h | 4 ++ 3 files changed, 117 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..541889f 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -19,39 +19,141 @@ */ #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 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; + int dev_id = 0; host = malloc(sizeof(struct dwmci_host)); if (!host) { printf("dwmci_host malloc fail!\n"); return 1; } + /* Convert index into corresponding peripheral ID */ + dev_id = index + PERIPH_ID_SDMMC0; + + /* set the clock divisor - clk_div_fsys for mmc */ + if (exynos5_mmc_set_clk_div(dev_id)) { + debug("mmc clock div set failed\n"); + return -1; + } 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;