Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 75bb6b9a authored by Alexander Clouter's avatar Alexander Clouter Committed by Nicolas Pitre
Browse files

[ARM] orion5x: ts78xx add NAND support via plat_nand



ts78xx add NAND support via plat_nand

Signed-off-by: default avatarAlexander Clouter <alex@digriz.org.uk>
Signed-off-by: default avatarNicolas Pitre <nico@cam.org>
parent 673492a8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -481,7 +481,7 @@ CONFIG_MTD_NAND_IDS=y
# CONFIG_MTD_NAND_DISKONCHIP is not set
# CONFIG_MTD_NAND_CAFE is not set
# CONFIG_MTD_NAND_NANDSIM is not set
# CONFIG_MTD_NAND_PLATFORM is not set
CONFIG_MTD_NAND_PLATFORM=y
# CONFIG_MTD_ALAUDA is not set
CONFIG_MTD_NAND_ORION=y
# CONFIG_MTD_ONENAND is not set
+1 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ struct fpga_device {
struct fpga_devices {
	/* Technologic Systems */
	struct fpga_device 	ts_rtc;
	struct fpga_device 	ts_nand;
};

struct ts78xx_fpga_data {
+132 −0
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@
#include <linux/mv643xx_eth.h>
#include <linux/ata_platform.h>
#include <linux/m48t86.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@@ -150,12 +152,130 @@ static void ts78xx_ts_rtc_unload(void)
	platform_device_del(&ts78xx_ts_rtc_device);
}

/*****************************************************************************
 * NAND Flash
 ****************************************************************************/
#define TS_NAND_CTRL	(TS78XX_FPGA_REGS_VIRT_BASE | 0x800)	/* VIRT */
#define TS_NAND_DATA	(TS78XX_FPGA_REGS_PHYS_BASE | 0x804)	/* PHYS */

/*
 * hardware specific access to control-lines
 *
 * ctrl:
 * NAND_NCE: bit 0 -> bit 2
 * NAND_CLE: bit 1 -> bit 1
 * NAND_ALE: bit 2 -> bit 0
 */
static void ts78xx_ts_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
			unsigned int ctrl)
{
	struct nand_chip *this = mtd->priv;

	if (ctrl & NAND_CTRL_CHANGE) {
		unsigned char bits;

		bits = (ctrl & NAND_NCE) << 2;
		bits |= ctrl & NAND_CLE;
		bits |= (ctrl & NAND_ALE) >> 2;

		writeb((readb(TS_NAND_CTRL) & ~0x7) | bits, TS_NAND_CTRL);
	}

	if (cmd != NAND_CMD_NONE)
		writeb(cmd, this->IO_ADDR_W);
}

static int ts78xx_ts_nand_dev_ready(struct mtd_info *mtd)
{
	return readb(TS_NAND_CTRL) & 0x20;
}

const char *ts_nand_part_probes[] = { "cmdlinepart", NULL };

static struct mtd_partition ts78xx_ts_nand_parts[] = {
	{
		.name		= "mbr",
		.offset		= 0,
		.size		= SZ_128K,
		.mask_flags	= MTD_WRITEABLE,
	}, {
		.name		= "kernel",
		.offset		= MTDPART_OFS_APPEND,
		.size		= SZ_4M,
	}, {
		.name		= "initrd",
		.offset		= MTDPART_OFS_APPEND,
		.size		= SZ_4M,
	}, {
		.name		= "rootfs",
		.offset		= MTDPART_OFS_APPEND,
		.size		= MTDPART_SIZ_FULL,
	}
};

static struct platform_nand_data ts78xx_ts_nand_data = {
	.chip	= {
		.part_probe_types	= ts_nand_part_probes,
		.partitions		= ts78xx_ts_nand_parts,
		.nr_partitions		= ARRAY_SIZE(ts78xx_ts_nand_parts),
		.chip_delay		= 15,
		.options		= NAND_USE_FLASH_BBT,
	},
	.ctrl	= {
		/*
		 * The HW ECC offloading functions, used to give about a 9%
		 * performance increase for 'dd if=/dev/mtdblockX' and 5% for
		 * nanddump.  This all however was changed by git commit
		 * e6cf5df1838c28bb060ac45b5585e48e71bbc740 so now there is
		 * no performance advantage to be had so we no longer bother
		 */
		.cmd_ctrl		= ts78xx_ts_nand_cmd_ctrl,
		.dev_ready		= ts78xx_ts_nand_dev_ready,
	},
};

static struct resource ts78xx_ts_nand_resources = {
	.start		= TS_NAND_DATA,
	.end		= TS_NAND_DATA + 4,
	.flags		= IORESOURCE_IO,
};

static struct platform_device ts78xx_ts_nand_device = {
	.name		= "gen_nand",
	.id		= -1,
	.dev		= {
		.platform_data	= &ts78xx_ts_nand_data,
	},
	.resource	= &ts78xx_ts_nand_resources,
	.num_resources	= 1,
};

static int ts78xx_ts_nand_load(void)
{
	int rc;

	if (ts78xx_fpga.supports.ts_nand.init == 0) {
		rc = platform_device_register(&ts78xx_ts_nand_device);
		if (!rc)
			ts78xx_fpga.supports.ts_nand.init = 1;
	} else
		rc = platform_device_add(&ts78xx_ts_nand_device);

	return rc;
};

static void ts78xx_ts_nand_unload(void)
{
	platform_device_del(&ts78xx_ts_nand_device);
}

/*****************************************************************************
 * FPGA 'hotplug' support code
 ****************************************************************************/
static void ts78xx_fpga_devices_zero_init(void)
{
	ts78xx_fpga.supports.ts_rtc.init = 0;
	ts78xx_fpga.supports.ts_nand.init = 0;
}

static void ts78xx_fpga_supports(void)
@@ -164,9 +284,11 @@ static void ts78xx_fpga_supports(void)
	switch (ts78xx_fpga.id) {
	case TS7800_REV_B:
		ts78xx_fpga.supports.ts_rtc.present = 1;
		ts78xx_fpga.supports.ts_nand.present = 1;
		break;
	default:
		ts78xx_fpga.supports.ts_rtc.present = 0;
		ts78xx_fpga.supports.ts_nand.present = 0;
	}
}

@@ -182,6 +304,14 @@ static int ts78xx_fpga_load_devices(void)
		}
		ret |= tmp;
	}
	if (ts78xx_fpga.supports.ts_nand.present == 1) {
		tmp = ts78xx_ts_nand_load();
		if (tmp) {
			printk(KERN_INFO "TS-78xx: NAND not registered\n");
			ts78xx_fpga.supports.ts_nand.present = 0;
		}
		ret |= tmp;
	}

	return ret;
}
@@ -192,6 +322,8 @@ static int ts78xx_fpga_unload_devices(void)

	if (ts78xx_fpga.supports.ts_rtc.present == 1)
		ts78xx_ts_rtc_unload();
	if (ts78xx_fpga.supports.ts_nand.present == 1)
		ts78xx_ts_nand_unload();

	return ret;
}