From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Lx3Mh-0000Wn-GR for qemu-devel@nongnu.org; Thu, 23 Apr 2009 14:09:39 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Lx3Mg-0000WE-Iv for qemu-devel@nongnu.org; Thu, 23 Apr 2009 14:09:39 -0400 Received: from [199.232.76.173] (port=45826 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Lx3Mg-0000W6-Ez for qemu-devel@nongnu.org; Thu, 23 Apr 2009 14:09:38 -0400 Received: from flounder.pepperfish.net ([87.237.62.181]:55284) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1Lx3Mf-0005SG-Pc for qemu-devel@nongnu.org; Thu, 23 Apr 2009 14:09:38 -0400 Received: from [10.112.102.2] (helo=jennifer.kylikki.org) by flounder.pepperfish.net with esmtps (Exim 4.69 #1 (Debian)) id 1Lx3Md-000584-KM for ; Thu, 23 Apr 2009 19:09:35 +0100 Received: from derik.kyllikki.org ([192.168.7.20] helo=derik) by jennifer.kylikki.org with esmtp (Exim 4.63) (envelope-from ) id 1Lx3Me-0006LG-2u for qemu-devel@nongnu.org; Thu, 23 Apr 2009 19:09:36 +0100 Received: from vince by derik with local (Exim 4.69) (envelope-from ) id 1Lx3Me-00048z-13 for qemu-devel@nongnu.org; Thu, 23 Apr 2009 19:09:36 +0100 Date: Thu, 23 Apr 2009 19:09:36 +0100 From: Vincent Sanders Subject: [Qemu-devel] [PATCH 12/16] S3C NAND controller Message-ID: <20090423180935.GO4629@derik> References: <20090423171503.GC4629@derik> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20090423171503.GC4629@derik> List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org S3C NAND Driver Signed-off-by: Vincent Sanders --- s3c24xx_nand.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) diff -urN qemusvnclean/hw/s3c24xx_nand.c qemusvnpatches/hw/s3c24xx_nand.c --- qemusvnclean/hw/s3c24xx_nand.c 1970-01-01 01:00:00.000000000 +0100 +++ qemusvnpatches/hw/s3c24xx_nand.c 2009-04-23 17:13:06.000000000 +0100 @@ -0,0 +1,136 @@ +/* hw/s3c24xx_nand.c + * + * Samsung S3C24XX NAND emulation + * + * Copyright 2006, 2008 Ben Dooks, Daniel Silverstone and Vincent Sanders + * + * This file is under the terms of the GNU General Public + * License Version 2 + */ + +#include "hw.h" +#include "flash.h" + +#include "s3c24xx.h" + +#define NFCONF 0 +#define NFCMD 1 +#define NFADDR 2 +#define NFDATA 3 +#define NFSTAT 4 +#define NFECC 5 + +#define NFCE ((soc->nand_reg[NFCONF] & 1<<11) != 0) + +static void +s3c24xx_nand_write_f(void *opaque, target_phys_addr_t addr, + uint32_t value) +{ + S3CState *soc = (S3CState *)opaque; + int reg = (addr & 0x1f) >> 2; + + if ((reg != NFCONF) && ((soc->nand_reg[NFCONF] & 1<<15) == 0)) { + return; /* Ignore the write, the nand is not enabled */ + } + + switch (reg) { + case NFCONF: + soc->nand_reg[reg] = value; + if (soc->nand_chip != NULL) + nand_setpins(soc->nand_chip, 0, 0, NFCE, 1, 0); + break; + + case NFCMD: + soc->nand_reg[reg] = value; + if (soc->nand_chip != NULL) { + nand_setpins(soc->nand_chip, 1, 0, NFCE, 1, 0); + nand_setio(soc->nand_chip, value); + } + break; + + case NFADDR: + soc->nand_reg[reg] = value; + if (soc->nand_chip != NULL) { + nand_setpins(soc->nand_chip, 0, 1, NFCE, 1, 0); + nand_setio(soc->nand_chip, value); + } + break; + + case NFDATA: + soc->nand_reg[reg] = value; + if (soc->nand_chip != NULL) { + nand_setpins(soc->nand_chip, 0, 0, NFCE, 1, 0); + nand_setio(soc->nand_chip, value); + } + break; + + default: + /* Do nothing because the other registers are read only */ + break; + } +} + +static uint32_t +s3c24xx_nand_read_f(void *opaque, target_phys_addr_t addr) +{ + S3CState *soc = (S3CState *)opaque; + int reg = (addr & 0x1f) >> 2; + uint32_t ret = soc->nand_reg[reg]; + + switch (reg) { + case NFDATA: + if (soc->nand_chip != NULL) { + nand_setpins(soc->nand_chip, 0, 0, NFCE, 1, 0); + ret = soc->nand_reg[reg] = nand_getio(soc->nand_chip); + } else { + ret = soc->nand_reg[ret] = 0; + } + break; + + case NFSTAT: + if (soc->nand_chip != NULL) { + nand_getpins(soc->nand_chip, (int *)&ret); + soc->nand_reg[reg] = ret; + } else { + ret = soc->nand_reg[ret] = 0; + } + + default: + /* The rest read-back what was written to them */ + break; + } + + return ret; +} + +static CPUReadMemoryFunc *s3c24xx_nand_read[] = { + &s3c24xx_nand_read_f, + &s3c24xx_nand_read_f, + &s3c24xx_nand_read_f, +}; + +static CPUWriteMemoryFunc *s3c24xx_nand_write[] = { + &s3c24xx_nand_write_f, + &s3c24xx_nand_write_f, + &s3c24xx_nand_write_f, +}; + +void +s3c24xx_nand_init(S3CState *soc, target_phys_addr_t base_addr) +{ + int tag = cpu_register_io_memory(0, s3c24xx_nand_read, s3c24xx_nand_write, soc); + cpu_register_physical_memory(base_addr, 0x40, tag); + + memset(soc->nand_reg, 0, sizeof(uint32_t) * 5); +} + +void +s3c24xx_nand_attach(S3CState *soc, struct nand_flash_s *nand_chip) +{ + if (soc->nand_chip != NULL) { + /* Detach current nand device */ + /* no cmd, no addr, not enabled, write protected, no 'gnd' */ + nand_setpins(soc->nand_chip, 0, 0, 1, 0, 0); + } + soc->nand_chip = nand_chip; +} -- Regards Vincent http://www.kyllikki.org/