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: 13752 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 3287423E03 for ; Mon, 31 Dec 2012 10:36:19 +0000 (UTC) Received: from mail-vb0-f44.google.com (mail-vb0-f44.google.com [209.85.212.44]) by fiordland.canonical.com (Postfix) with ESMTP id D1DC3A18257 for ; Mon, 31 Dec 2012 10:36:18 +0000 (UTC) Received: by mail-vb0-f44.google.com with SMTP id fc26so12938159vbb.3 for ; Mon, 31 Dec 2012 02:36:18 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:x-forwarded-to:x-forwarded-for:delivered-to:x-received :received-spf:x-auditid:from:to:cc:subject:date:message-id:x-mailer :in-reply-to:references:dlp-filter:x-mtr:x-brightmail-tracker :x-brightmail-tracker:x-cfilter-loop:x-gm-message-state; bh=ClFlIbyctGOYl/Rb2LSO97f7IQChjRnagOfTgC/N6xw=; b=EN9v0pEQU9BJwbpUjcmHZ+UFntDjdhhi748jB3qFAPoEaB0W5VSna4Z/R1/9mOspTQ fwHdJyN/rKfeXC4CWTYCvr9wPLdISkQBUZFEWnAyW4ZDHx+hthOr213U+/M6niIC3vH3 Do2v6f+3G6Plg4zyCJX3pQJbDZTD2BNKi9stnPkUMg4erSr/ZbgpmmvUS9VBXv/nYbPE Jf/jnUe+8CDKEOOm00HA4yGPSGZSiIhGkJ93PMeXN5lBip0wOcnFsJkgQtOsjsAXwJ0Q G36GITk+W8BgWknVyV3qWRqk3ElLlkfx18hUa/iaLy1iwfJl4ivanJZATRsAxFv7bA2R X9PA== X-Received: by 10.58.247.132 with SMTP id ye4mr65418761vec.9.1356950178363; Mon, 31 Dec 2012 02:36:18 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.58.214.195 with SMTP id oc3csp153809vec; Mon, 31 Dec 2012 02:36:17 -0800 (PST) X-Received: by 10.68.197.197 with SMTP id iw5mr125141608pbc.22.1356950177204; Mon, 31 Dec 2012 02:36:17 -0800 (PST) Received: from mailout2.samsung.com (mailout2.samsung.com. [203.254.224.25]) by mx.google.com with ESMTP id a6si39376205paw.226.2012.12.31.02.36.16; Mon, 31 Dec 2012 02:36:17 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of amarendra.xt@samsung.com designates 203.254.224.25 as permitted sender) client-ip=203.254.224.25; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of amarendra.xt@samsung.com designates 203.254.224.25 as permitted sender) smtp.mail=amarendra.xt@samsung.com Received: from epcpsbgm2.samsung.com (epcpsbgm2 [203.254.230.27]) by mailout2.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MFW00AHA5G5QUD0@mailout2.samsung.com>; Mon, 31 Dec 2012 19:36:15 +0900 (KST) Received: from epcpsbgm2.samsung.com ( [172.20.52.125]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id 5E.CE.12699.F9A61E05; Mon, 31 Dec 2012 19:36:15 +0900 (KST) X-AuditID: cbfee61b-b7f616d00000319b-fd-50e16a9f8ad4 Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id FD.CE.12699.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>; Mon, 31 Dec 2012 19:36:15 +0900 (KST) From: Amar To: u-boot@lists.denx.de, jh80.chung@samsung.com Cc: patches@linaro.org, sjg@chromium.org, mk7.kang@samsung.com, chander.kashyap@linaro.org, afleming@gmail.com Subject: [PATCH V3 4/9] EXYNOS5: DWMMC: Added FDT support for DWMMC 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+NgFrrHLMWRmVeSWpSXmKPExsWyRsSkVnd+1sMAg72fTSwerr/JYjHl8BcW ByaPO9f2sAUwRnHZpKTmZJalFunbJXBlPNy5m61gpUHFkTf/WRoYb6t1MXJySAiYSCyY0skO YYtJXLi3nq2LkYtDSGApo0TjojVsMEWbm98yQSQWMUrcujqRFcLpZZKYumcZkMPBwSagKvFr sT1Ig4iAgcT0J9vBwswCBRLPdouBhIUFnCWavm1kBrFZgKo3Hf3HDFLCK+Ah0X48BmKVnMSH PY/A7uEU8JQ4vWUHWLkQUMnN7oXsEK0CEt8mH2IBaZUQkJXYdIAZovU6m8StM3kQtqTEwRU3 WCYwCi9gZFjFKJpakFxQnJSea6RXnJhbXJqXrpecn7uJERiIp/89k97BuKrB4hCjAAejEg8v J9PDACHWxLLiytxDjBIczEoivG+1gEK8KYmVValF+fFFpTmpxYcYfYAOmcgsJZqcD4ySvJJ4 Q2MTc1NjU0sjIzNTUxzCSuK8zR4pAUIC6YklqdmpqQWpRTDjmDg4pRoYNy8uXMme0ftQpOhv 3BfxrSxrbb2V9tivsOqfETHd9mDSHJGz2jaOTK26/usK9KZcmXwg/Pipqedtz/a3S1fnyU3q 1CtkLtj8/vDT8I2dky7ZNF3seGm1h/FY4fWdvNE3434syXtdvCWj82GKdsGZEzrFz2oeO0/d wFjt25ITcez+ifAbu6K7lViKMxINtZiLihMBfmQuGXECAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupjkeLIzCtJLcpLzFFi42I5/e+xgO78rIcBBnsOq1k8XH+TxWLK4S8s Dkwed67tYQtgjGpgtMlITUxJLVJIzUvOT8nMS7dV8g6Od443NTMw1DW0tDBXUshLzE21VXLx CdB1y8wBmq2kUJaYUwoUCkgsLlbSt8M0ITTETdcCpjFC1zckCK7HyAANJKxhzHi4czdbwUqD iiNv/rM0MN5W62Lk5JAQMJHY3PyWCcIWk7hwbz1bFyMXh5DAIkaJW1cnskI4vUwSU/csA3I4 ONgEVCV+LbYHaRARMJCY/mQ7WJhZoEDi2W4xkLCwgLNE07eNzCA2C1D1pqP/mEFKeAU8JNqP x0CskpP4sOcRO4jNKeApcXrLDrByIaCSm90L2Scw8i5gZFjFKJpakFxQnJSea6RXnJhbXJqX rpecn7uJERzoz6R3MK5qsDjEKMDBqMTDy8n0MECINbGsuDL3EKMEB7OSCO9bLaAQb0piZVVq UX58UWlOavEhRh+goyYyS4km5wOjMK8k3tDYxNzU2NTSxMLEzBKHsJI4b7NHSoCQQHpiSWp2 ampBahHMOCYOTqkGxvD1q5TiF6kY+PO+fywem/dQKqGQ/XW4YMLSvXXbWsxSrQ+pnM7eHPx2 9YP2o5GbPzzVqrLaatu19WzmIcHzMvuFG7t+1E/YtWdqCfeBimkfUx6+CmrdXnvDVyl20kWx fZKJSRazsurEvuaab3HunnNubv+lDSlxL4pY13cr2q7Le9zkVx/bpMRSnJFoqMVcVJwIAIP4 qMehAgAA X-CFilter-Loop: Reflected X-Gm-Message-State: ALoCoQkaSoQGDCvlWVxl90MwuUxbi4EQhtaAZj5G1X0R3w6avB3Hyz2AAQIkqbBdToUqj8DkAplt 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;