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: 13793 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 D3E8C23EDC for ; Fri, 4 Jan 2013 09:12:15 +0000 (UTC) Received: from mail-vc0-f169.google.com (mail-vc0-f169.google.com [209.85.220.169]) by fiordland.canonical.com (Postfix) with ESMTP id 2BB77A18576 for ; Fri, 4 Jan 2013 09:12:15 +0000 (UTC) Received: by mail-vc0-f169.google.com with SMTP id gb23so16167653vcb.14 for ; Fri, 04 Jan 2013 01:12:14 -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=K2eRtJX8Kp5cjdWtfuq0WJis4k59IsK7wF7VWPcpzyA=; b=YRB0pv8VQ+0ogq022wSOhyags7HIW88Qv8pcatuvKKoGTnHkK9i5cjJFPqIiPaHzOj demDbvgoeG5bA8694obRlxwLbGoqvfruDTb98HzYpwvh7IjYaKE4nh5n0u8+LuE19yHV Ws4EnTrHQzWatdYOX2nobEo6Vp39UWLzJHZR+p9mpJymS61D1/gcJgfkZZ1+XBdc+Hu5 yr4Gq0I50ZSNYbzj6aOZNw7CXuMBViteDvltKSR9Dp9JHPqFHLfsiEQggYu5qeyqIwxB 4fJQEorOkdMZoVwozs82vxzb/K4Y230hbjzX6zJWB8u9pNBk7lrb7AZuxdNw+cVFiqvw h/Bw== X-Received: by 10.52.88.168 with SMTP id bh8mr65136220vdb.51.1357290734619; Fri, 04 Jan 2013 01:12:14 -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.145.101 with SMTP id st5csp128041veb; Fri, 4 Jan 2013 01:12:13 -0800 (PST) X-Received: by 10.66.88.133 with SMTP id bg5mr152899481pab.21.1357290732786; Fri, 04 Jan 2013 01:12:12 -0800 (PST) Received: from mailout1.samsung.com (mailout1.samsung.com. [203.254.224.24]) by mx.google.com with ESMTP id ks7si48449254pbc.334.2013.01.04.01.12.12; Fri, 04 Jan 2013 01:12:12 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of amarendra.xt@samsung.com designates 203.254.224.24 as permitted sender) client-ip=203.254.224.24; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of amarendra.xt@samsung.com designates 203.254.224.24 as permitted sender) smtp.mail=amarendra.xt@samsung.com Received: from epcpsbgm1.samsung.com (epcpsbgm1 [203.254.230.26]) by mailout1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MG300AEHG7XGLC0@mailout1.samsung.com>; Fri, 04 Jan 2013 18:12:11 +0900 (KST) Received: from epcpsbgm1.samsung.com ( [172.20.52.123]) by epcpsbgm1.samsung.com (EPCPMTA) with SMTP id 8C.50.01231.AEC96E05; Fri, 04 Jan 2013 18:12:11 +0900 (KST) X-AuditID: cbfee61a-b7fa66d0000004cf-d8-50e69ceac5f4 Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm1.samsung.com (EPCPMTA) with SMTP id 2C.50.01231.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>; Fri, 04 Jan 2013 18:12:10 +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 V4 4/9] EXYNOS5: DWMMC: Added FDT support for DWMMC 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+NgFrrLLMWRmVeSWpSXmKPExsWyRsSkWvf1nGcBBq1tbBYP199ksZhy+AuL A5PHnWt72AIYo7hsUlJzMstSi/TtErgyPv+/wVhwwLSio/MxawPjbq0uRk4OCQETibt33jNC 2GISF+6tZ+ti5OIQEljKKLG17RATTNH8DQ8YIRKLGCWuXZnBAuH0MknsmbCJtYuRg4NNQFXi 12J7kAYRAQOJ6U+2g4WZBQoknu0WAwkLCzhLLHq/hhEkzAJU3bIpFyTMK+Ah0bnjLdQqOYkP ex6xg5RwCnhKbLoiAmIKAZVcPVQCUsEiICDxbfIhFpCwhICsxKYDzCCnSAjcZpP4/mYHG8QU SYmDK26wTGAUXsDIsIpRNLUguaA4KT3XUK84Mbe4NC9dLzk/dxMjMAxP/3smtYNxZYPFIUYB DkYlHl7LO08DhFgTy4orcw8xSnAwK4nwftZ+FiDEm5JYWZValB9fVJqTWnyI0QfokonMUqLJ +cAYySuJNzQ2MTc1NrU0MjIzNcUhrCTOy3jqSYCQQHpiSWp2ampBahHMOCYOTqkGRrOiH9Of Xd8qo2v/ylfk6b7DdSkxCyIZOZacO6/39Im60LKwN3+CreYoaSYJtupeX7z+k1TnlZj21e/M Dq77sH77NL2+5b0Xq5SMvmfMfsPoEVWzuIb7aEik7J7vV/QjPNcm7eLl0arWlneqSihzuKRY 9NKI5UD+12li1+dpMAX9LBE2PWO5TomlOCPRUIu5qDgRAMC8VPdwAgAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFuphkeLIzCtJLcpLzFFi42I5/e+xgO6rOc8CDLafN7Z4uP4mi8WUw19Y HJg87lzbwxbAGNXAaJORmpiSWqSQmpecn5KZl26r5B0c7xxvamZgqGtoaWGupJCXmJtqq+Ti E6DrlpkDNFtJoSwxpxQoFJBYXKykb4dpQmiIm64FTGOErm9IEFyPkQEaSFjDmPH5/w3GggOm FR2dj1kbGHdrdTFyckgImEjM3/CAEcIWk7hwbz1bFyMXh5DAIkaJa1dmsEA4vUwSeyZsYu1i 5OBgE1CV+LXYHqRBRMBAYvqT7WBhZoECiWe7xUDCwgLOEover2EECbMAVbdsygUJ8wp4SHTu eMsEsUpO4sOeR+wgJZwCnhKbroiAmEJAJVcPlUxg5F3AyLCKUTS1ILmgOCk911CvODG3uDQv XS85P3cTIzjIn0ntYFzZYHGIUYCDUYmH1/LO0wAh1sSy4srcQ4wSHMxKIryftZ8FCPGmJFZW pRblxxeV5qQWH2L0ATppIrOUaHI+MALzSuINjU3MTY1NLU0sTMwscQgrifMynnoSICSQnliS mp2aWpBaBDOOiYNTqoFxY98Zvu9xx6LV9jziOLY87My6stB9Rf1t4ndFbMXWqhxK3brByr3k Ae/vRQ2Pj6v8OR7KeeXGphkt+fPKNFh5I4w09+05XXTmwJOr4ZMe6cwXDynNiNU7KJN4UuKO mszCu/xR3K7H97CXTPVxZrw2uS1l+rtp8ncm7zjW5VFb22IxxzHcMqJciaU4I9FQi7moOBEA lVQWEJ8CAAA= X-CFilter-Loop: Reflected X-Gm-Message-State: ALoCoQkJ56u9gXk4NJinYKfJrjVbwJpL2M67nQ9igWdgqncrnPTFl06p1kRbXGV1wmIkteJrA2/F 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;