From patchwork Tue May 18 14:43:04 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Magnus Damm X-Patchwork-Id: 100500 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o4IEgIu6009808 for ; Tue, 18 May 2010 14:42:18 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757563Ab0EROlx (ORCPT ); Tue, 18 May 2010 10:41:53 -0400 Received: from ey-out-2122.google.com ([74.125.78.25]:27898 "EHLO ey-out-2122.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755387Ab0EROlv (ORCPT ); Tue, 18 May 2010 10:41:51 -0400 Received: by ey-out-2122.google.com with SMTP id 9so281474eyd.5 for ; Tue, 18 May 2010 07:41:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:cc:date:message-id :in-reply-to:references:subject; bh=HVaKUBb24LCBwy583IYb9dmme2RubbAUJAoY5rHnEo8=; b=MmoiT9o4ALzuD/pU/AnHz7VG6MNoIb9+STGSz+pPMqI1LjnIRqmbsozm1f9eS9C559 34lELhJMkB6DC7rgBukcvR+oP6mW0m/qtnYrorXM3zCG2nPrDHq8sR6mnihaVlSOEgc8 SH7hn9WxbICDd6ZotzX6mxOuawH8JZLJMqG7M= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:date:message-id:in-reply-to:references:subject; b=vIYLpSHrqCsTVyheOwflzA6wnqpQzLmSLV66SfaAB8ri7ZOEInorx/M0I+xe6VY3Ks +/K7FCzXTys1OkrwcD4I+LkpzpuxwmgwTn38M3NYbLsd8U1Nz+DpVY7cCirwEjnGd74L b/vTngqdUefpD76LXibhrKfxNE37bntrwKT74= Received: by 10.213.38.11 with SMTP id z11mr3393683ebd.41.1274193709534; Tue, 18 May 2010 07:41:49 -0700 (PDT) Received: from [127.0.0.1] (49.14.32.202.bf.2iij.net [202.32.14.49]) by mx.google.com with ESMTPS id 16sm3097611ewy.3.2010.05.18.07.41.46 (version=TLSv1/SSLv3 cipher=RC4-MD5); Tue, 18 May 2010 07:41:48 -0700 (PDT) From: Magnus Damm To: linux-sh@vger.kernel.org Cc: Magnus Damm , lethal@linux-sh.org, akpm@linux-foundation.org Date: Tue, 18 May 2010 23:43:04 +0900 Message-Id: <20100518144304.29239.85313.sendpatchset@t400s> In-Reply-To: <20100518144229.29239.19891.sendpatchset@t400s> References: <20100518144229.29239.19891.sendpatchset@t400s> Subject: [PATCH 03/04] sh: add boot code to MMCIF driver header Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Tue, 18 May 2010 14:42:18 +0000 (UTC) --- 0004/include/linux/mmc/sh_mmcif.h +++ work/include/linux/mmc/sh_mmcif.h 2010-05-18 21:20:44.000000000 +0900 @@ -68,4 +68,133 @@ extern inline void sh_mmcif_writel(void writel(val, addr + reg); } +#define SH_MMCIF_BBS 512 /* boot block size */ + +extern inline void sh_mmcif_boot_cmd_send(void __iomem *base, + unsigned long cmd, unsigned long arg) +{ + sh_mmcif_writel(base, MMCIF_CE_INT, 0); + sh_mmcif_writel(base, MMCIF_CE_ARG, arg); + sh_mmcif_writel(base, MMCIF_CE_CMD_SET, cmd); +} + +extern inline int sh_mmcif_boot_cmd_poll(void __iomem *base, unsigned long mask) +{ + unsigned long tmp; + int cnt; + + for (cnt = 0; cnt < 1000000; cnt++) { + tmp = sh_mmcif_readl(base, MMCIF_CE_INT); + if (tmp & mask) { + sh_mmcif_writel(base, MMCIF_CE_INT, tmp & ~mask); + return 0; + } + } + + return -1; +} + +extern inline int sh_mmcif_boot_cmd(void __iomem *base, + unsigned long cmd, unsigned long arg) +{ + sh_mmcif_boot_cmd_send(base, cmd, arg); + return sh_mmcif_boot_cmd_poll(base, 0x00010000); +} + +extern inline int sh_mmcif_boot_do_read_single(void __iomem *base, + unsigned int block_nr, + unsigned long *buf) +{ + int k; + + /* CMD13 - Status */ + sh_mmcif_boot_cmd(base, 0x0d400000, 0x00010000); + + if (sh_mmcif_readl(base, MMCIF_CE_RESP0) != 0x0900) + return -1; + + /* CMD17 - Read */ + sh_mmcif_boot_cmd(base, 0x11480000, block_nr * SH_MMCIF_BBS); + if (sh_mmcif_boot_cmd_poll(base, 0x00100000) < 0) + return -1; + + for (k = 0; k < (SH_MMCIF_BBS / 4); k++) + buf[k] = sh_mmcif_readl(base, MMCIF_CE_DATA); + + return 0; +} + +extern inline int sh_mmcif_boot_do_read(void __iomem *base, + unsigned long first_block, + unsigned long nr_blocks, + void *buf) +{ + unsigned long k; + int ret = 0; + + /* CMD16 - Set the block size */ + sh_mmcif_boot_cmd(base, 0x10400000, SH_MMCIF_BBS); + + for (k = 0; !ret && k < nr_blocks; k++) + ret = sh_mmcif_boot_do_read_single(base, first_block + k, + buf + (k * SH_MMCIF_BBS)); + + return ret; +} + +extern inline void sh_mmcif_boot_init(void __iomem *base) +{ + unsigned long tmp; + + /* reset */ + tmp = sh_mmcif_readl(base, MMCIF_CE_VERSION); + sh_mmcif_writel(base, MMCIF_CE_VERSION, tmp | 0x80000000); + sh_mmcif_writel(base, MMCIF_CE_VERSION, tmp & ~0x80000000); + + /* byte swap */ + sh_mmcif_writel(base, MMCIF_CE_BUF_ACC, 0x00010000); + + /* Set block size in MMCIF hardware */ + sh_mmcif_writel(base, MMCIF_CE_BLOCK_SET, SH_MMCIF_BBS); + + /* Enable the clock, set it to Bus clock/256 (about 325Khz)*/ + sh_mmcif_writel(base, MMCIF_CE_CLK_CTRL, 0x01072fff); + + /* CMD0 */ + sh_mmcif_boot_cmd(base, 0x00000040, 0); + + /* CMD1 - Get OCR */ + do { + sh_mmcif_boot_cmd(base, 0x01405040, 0x40300000); /* CMD1 */ + } while ((sh_mmcif_readl(base, MMCIF_CE_RESP0) & 0x80000000) + != 0x80000000); + + /* CMD2 - Get CID */ + sh_mmcif_boot_cmd(base, 0x02806040, 0); + + /* CMD3 - Set card relative address */ + sh_mmcif_boot_cmd(base, 0x03400040, 0x00010000); +} + +extern inline void sh_mmcif_boot_slurp(void __iomem *base, + unsigned char *buf, + unsigned long no_bytes) +{ + unsigned long tmp; + + /* In data transfer mode: Set clock to Bus clock/4 (about 20Mhz) */ + sh_mmcif_writel(base, MMCIF_CE_CLK_CTRL, 0x01012fff); + + /* CMD9 - Get CSD */ + sh_mmcif_boot_cmd(base, 0x09806000, 0x00010000); + + /* CMD7 - Select the card */ + sh_mmcif_boot_cmd(base, 0x07400000, 0x00010000); + + tmp = no_bytes / SH_MMCIF_BBS; + tmp += (no_bytes % SH_MMCIF_BBS) ? 1 : 0; + + sh_mmcif_boot_do_read(base, 512, tmp, buf); +} + #endif /* __SH_MMCIF_H__ */