linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [-mm patch 0/3] AVR32 MTD: Introduction (try 2)
@ 2006-09-15 14:31 Haavard Skinnemoen
  2006-09-15 14:35 ` [-mm patch 1/3] AVR32 MTD: Static Memory Controller driver " Haavard Skinnemoen
  0 siblings, 1 reply; 9+ messages in thread
From: Haavard Skinnemoen @ 2006-09-15 14:31 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-mtd, linux-kernel, David Woodhouse

Hi again,

This patchset adds the necessary drivers and infrastructure to access
the external flash on the ATSTK1000 board through the MTD subsystem.
With this stuff in place, it will be possible to use a jffs2 filesystem
stored in the external flash as a root filesystem. It might also be
possible to update the boot loader if you drop the write protection of
partition 0.

As suggested by David Woodhouse, I reworked the patches to use the
physmap driver instead of introducing a separate mapping driver for the
ATSTK1000. I've also cleaned up the hsmc header by removing useless
comments and converting spaces to tabs (my headerfile generator needs
some work.)

Unfortunately, I couldn't unlock the flash in fixup_use_atmel_lock
because the erase regions hadn't been set up yet, so I had to do it
from cfi_amdstd_setup instead.

This also needs two patches I've submitted earlier (included in
git-mtd.patch) in order to work, but it should still apply without
them. For the record, these are:

  MTD: Add lock/unlock operations for Atmel AT49BV6416
  MTD: Convert Atmel PRI information to AMD format

This patchset includes the following patches:

  AVR32 MTD: Static Memory Controller driver
  AVR32 MTD: Unlock flash if necessary
  AVR32 MTD: AT49BV6416 platform device for atstk1000

And the combined diffstat looks like this:

 arch/avr32/boards/atstk1000/Makefile |    2
 arch/avr32/boards/atstk1000/flash.c  |   95 ++++++++++++++++++++
 arch/avr32/mach-at32ap/Makefile      |    2
 arch/avr32/mach-at32ap/at32ap7000.c  |   10 ++
 arch/avr32/mach-at32ap/hsmc.c        |  164 +++++++++++++++++++++++++++++++++++
 arch/avr32/mach-at32ap/hsmc.h        |  127 +++++++++++++++++++++++++++
 drivers/mtd/chips/cfi_cmdset_0002.c  |    9 +
 include/asm-avr32/arch-at32ap/smc.h  |   60 ++++++++++++
 8 files changed, 467 insertions(+), 2 deletions(-)

Best regards,
Haavard

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [-mm patch 1/3] AVR32 MTD: Static Memory Controller driver (try 2)
  2006-09-15 14:31 [-mm patch 0/3] AVR32 MTD: Introduction (try 2) Haavard Skinnemoen
@ 2006-09-15 14:35 ` Haavard Skinnemoen
  2006-09-15 14:37   ` [-mm patch 2/3] AVR32 MTD: Unlock flash if necessary " Haavard Skinnemoen
  0 siblings, 1 reply; 9+ messages in thread
From: Haavard Skinnemoen @ 2006-09-15 14:35 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-mtd, linux-kernel, David Woodhouse

This adds a simple API for configuring the static memory controller
along with an implementation for the Atmel HSMC.

Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
---
 arch/avr32/mach-at32ap/Makefile     |    2 
 arch/avr32/mach-at32ap/at32ap7000.c |   10 ++
 arch/avr32/mach-at32ap/hsmc.c       |  164 ++++++++++++++++++++++++++++++++++++
 arch/avr32/mach-at32ap/hsmc.h       |  127 +++++++++++++++++++++++++++
 include/asm-avr32/arch-at32ap/smc.h |   60 +++++++++++++
 5 files changed, 362 insertions(+), 1 deletion(-)

Index: linux-2.6.18-rc6-mm2/arch/avr32/mach-at32ap/Makefile
===================================================================
--- linux-2.6.18-rc6-mm2.orig/arch/avr32/mach-at32ap/Makefile	2006-09-15 10:00:15.000000000 +0200
+++ linux-2.6.18-rc6-mm2/arch/avr32/mach-at32ap/Makefile	2006-09-15 10:00:39.000000000 +0200
@@ -1,2 +1,2 @@
-obj-y				+= at32ap.o clock.o pio.o intc.o extint.o
+obj-y				+= at32ap.o clock.o pio.o intc.o extint.o hsmc.o
 obj-$(CONFIG_CPU_AT32AP7000)	+= at32ap7000.o
Index: linux-2.6.18-rc6-mm2/arch/avr32/mach-at32ap/at32ap7000.c
===================================================================
--- linux-2.6.18-rc6-mm2.orig/arch/avr32/mach-at32ap/at32ap7000.c	2006-09-15 10:00:15.000000000 +0200
+++ linux-2.6.18-rc6-mm2/arch/avr32/mach-at32ap/at32ap7000.c	2006-09-15 10:00:39.000000000 +0200
@@ -450,6 +450,13 @@ static struct clk hramc_clk = {
 	.users		= 1,
 };
 
+static struct resource smc0_resource[] = {
+	PBMEM(0xfff03400),
+};
+DEFINE_DEV(smc, 0);
+DEV_CLK(pclk, smc0, pbb, 13);
+DEV_CLK(mck, smc0, hsb, 0);
+
 static struct platform_device pdc_device = {
 	.name		= "pdc",
 	.id		= 0,
@@ -503,6 +510,7 @@ void __init at32_add_system_devices(void
 
 	platform_device_register(&at32_sm_device);
 	platform_device_register(&at32_intc0_device);
+	platform_device_register(&smc0_device);
 	platform_device_register(&pdc_device);
 
 	platform_device_register(&pio0_device);
@@ -796,6 +804,8 @@ struct clk *at32_clock_list[] = {
 	&at32_intc0_pclk,
 	&ebi_clk,
 	&hramc_clk,
+	&smc0_pclk,
+	&smc0_mck,
 	&pdc_hclk,
 	&pdc_pclk,
 	&pico_clk,
Index: linux-2.6.18-rc6-mm2/arch/avr32/mach-at32ap/hsmc.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.18-rc6-mm2/arch/avr32/mach-at32ap/hsmc.c	2006-09-15 10:00:39.000000000 +0200
@@ -0,0 +1,164 @@
+/*
+ * Static Memory Controller for AT32 chips
+ *
+ * Copyright (C) 2006 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#define DEBUG
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <asm/io.h>
+#include <asm/arch/smc.h>
+
+#include "hsmc.h"
+
+#define NR_CHIP_SELECTS 6
+
+struct hsmc {
+	void __iomem *regs;
+	struct clk *pclk;
+	struct clk *mck;
+};
+
+static struct hsmc *hsmc;
+
+int smc_set_configuration(int cs, const struct smc_config *config)
+{
+	unsigned long mul;
+	unsigned long offset;
+	u32 setup, pulse, cycle, mode;
+
+	if (!hsmc)
+		return -ENODEV;
+	if (cs >= NR_CHIP_SELECTS)
+		return -EINVAL;
+
+	/*
+	 * cycles = x / T = x * f
+	 *   = ((x * 1000000000) * ((f * 65536) / 1000000000)) / 65536
+	 *   = ((x * 1000000000) * (((f / 10000) * 65536) / 100000)) / 65536
+	 */
+	mul = (clk_get_rate(hsmc->mck) / 10000) << 16;
+	mul /= 100000;
+
+#define ns2cyc(x) ((((x) * mul) + 65535) >> 16)
+
+	setup = (HSMC_BF(NWE_SETUP, ns2cyc(config->nwe_setup))
+		 | HSMC_BF(NCS_WR_SETUP, ns2cyc(config->ncs_write_setup))
+		 | HSMC_BF(NRD_SETUP, ns2cyc(config->nrd_setup))
+		 | HSMC_BF(NCS_RD_SETUP, ns2cyc(config->ncs_read_setup)));
+	pulse = (HSMC_BF(NWE_PULSE, ns2cyc(config->nwe_pulse))
+		 | HSMC_BF(NCS_WR_PULSE, ns2cyc(config->ncs_write_pulse))
+		 | HSMC_BF(NRD_PULSE, ns2cyc(config->nrd_pulse))
+		 | HSMC_BF(NCS_RD_PULSE, ns2cyc(config->ncs_read_pulse)));
+	cycle = (HSMC_BF(NWE_CYCLE, ns2cyc(config->write_cycle))
+		 | HSMC_BF(NRD_CYCLE, ns2cyc(config->read_cycle)));
+
+	switch (config->bus_width) {
+	case 1:
+		mode = HSMC_BF(DBW, HSMC_DBW_8_BITS);
+		break;
+	case 2:
+		mode = HSMC_BF(DBW, HSMC_DBW_16_BITS);
+		break;
+	case 4:
+		mode = HSMC_BF(DBW, HSMC_DBW_32_BITS);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (config->nrd_controlled)
+		mode |= HSMC_BIT(READ_MODE);
+	if (config->nwe_controlled)
+		mode |= HSMC_BIT(WRITE_MODE);
+	if (config->byte_write)
+		mode |= HSMC_BIT(BAT);
+
+	pr_debug("smc cs%d: setup/%08x pulse/%08x cycle/%08x mode/%08x\n",
+		 cs, setup, pulse, cycle, mode);
+
+	offset = cs * 0x10;
+	hsmc_writel(hsmc, SETUP0 + offset, setup);
+	hsmc_writel(hsmc, PULSE0 + offset, pulse);
+	hsmc_writel(hsmc, CYCLE0 + offset, cycle);
+	hsmc_writel(hsmc, MODE0 + offset, mode);
+	hsmc_readl(hsmc, MODE0); /* I/O barrier */
+
+	return 0;
+}
+EXPORT_SYMBOL(smc_set_configuration);
+
+static int hsmc_probe(struct platform_device *pdev)
+{
+	struct resource *regs;
+	struct clk *pclk, *mck;
+	int ret;
+
+	if (hsmc)
+		return -EBUSY;
+
+	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!regs)
+		return -ENXIO;
+	pclk = clk_get(&pdev->dev, "pclk");
+	if (IS_ERR(pclk))
+		return PTR_ERR(pclk);
+	mck = clk_get(&pdev->dev, "mck");
+	if (IS_ERR(mck)) {
+		ret = PTR_ERR(mck);
+		goto out_put_pclk;
+	}
+
+	ret = -ENOMEM;
+	hsmc = kzalloc(sizeof(struct hsmc), GFP_KERNEL);
+	if (!hsmc)
+		goto out_put_clocks;
+
+	clk_enable(pclk);
+	clk_enable(mck);
+
+	hsmc->pclk = pclk;
+	hsmc->mck = mck;
+	hsmc->regs = ioremap(regs->start, regs->end - regs->start + 1);
+	if (!hsmc->regs)
+		goto out_disable_clocks;
+
+	dev_info(&pdev->dev, "Atmel Static Memory Controller at 0x%08lx\n",
+		 (unsigned long)regs->start);
+
+	platform_set_drvdata(pdev, hsmc);
+
+	return 0;
+
+out_disable_clocks:
+	clk_disable(mck);
+	clk_disable(pclk);
+	kfree(hsmc);
+out_put_clocks:
+	clk_put(mck);
+out_put_pclk:
+	clk_put(pclk);
+	hsmc = NULL;
+	return ret;
+}
+
+static struct platform_driver hsmc_driver = {
+	.probe		= hsmc_probe,
+	.driver		= {
+		.name	= "smc",
+	},
+};
+
+static int __init hsmc_init(void)
+{
+	return platform_driver_register(&hsmc_driver);
+}
+arch_initcall(hsmc_init);
Index: linux-2.6.18-rc6-mm2/arch/avr32/mach-at32ap/hsmc.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.18-rc6-mm2/arch/avr32/mach-at32ap/hsmc.h	2006-09-15 10:03:32.000000000 +0200
@@ -0,0 +1,127 @@
+/*
+ * Register definitions for Atmel Static Memory Controller (SMC)
+ *
+ * Copyright (C) 2006 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_AVR32_HSMC_H__
+#define __ASM_AVR32_HSMC_H__
+
+/* HSMC register offsets */
+#define HSMC_SETUP0				0x0000
+#define HSMC_PULSE0				0x0004
+#define HSMC_CYCLE0				0x0008
+#define HSMC_MODE0				0x000c
+#define HSMC_SETUP1				0x0010
+#define HSMC_PULSE1				0x0014
+#define HSMC_CYCLE1				0x0018
+#define HSMC_MODE1				0x001c
+#define HSMC_SETUP2				0x0020
+#define HSMC_PULSE2				0x0024
+#define HSMC_CYCLE2				0x0028
+#define HSMC_MODE2				0x002c
+#define HSMC_SETUP3				0x0030
+#define HSMC_PULSE3				0x0034
+#define HSMC_CYCLE3				0x0038
+#define HSMC_MODE3				0x003c
+#define HSMC_SETUP4				0x0040
+#define HSMC_PULSE4				0x0044
+#define HSMC_CYCLE4				0x0048
+#define HSMC_MODE4				0x004c
+#define HSMC_SETUP5				0x0050
+#define HSMC_PULSE5				0x0054
+#define HSMC_CYCLE5				0x0058
+#define HSMC_MODE5				0x005c
+
+/* Bitfields in SETUP0 */
+#define HSMC_NWE_SETUP_OFFSET			0
+#define HSMC_NWE_SETUP_SIZE			6
+#define HSMC_NCS_WR_SETUP_OFFSET		8
+#define HSMC_NCS_WR_SETUP_SIZE			6
+#define HSMC_NRD_SETUP_OFFSET			16
+#define HSMC_NRD_SETUP_SIZE			6
+#define HSMC_NCS_RD_SETUP_OFFSET		24
+#define HSMC_NCS_RD_SETUP_SIZE			6
+
+/* Bitfields in PULSE0 */
+#define HSMC_NWE_PULSE_OFFSET			0
+#define HSMC_NWE_PULSE_SIZE			7
+#define HSMC_NCS_WR_PULSE_OFFSET		8
+#define HSMC_NCS_WR_PULSE_SIZE			7
+#define HSMC_NRD_PULSE_OFFSET			16
+#define HSMC_NRD_PULSE_SIZE			7
+#define HSMC_NCS_RD_PULSE_OFFSET		24
+#define HSMC_NCS_RD_PULSE_SIZE			7
+
+/* Bitfields in CYCLE0 */
+#define HSMC_NWE_CYCLE_OFFSET			0
+#define HSMC_NWE_CYCLE_SIZE			9
+#define HSMC_NRD_CYCLE_OFFSET			16
+#define HSMC_NRD_CYCLE_SIZE			9
+
+/* Bitfields in MODE0 */
+#define HSMC_READ_MODE_OFFSET			0
+#define HSMC_READ_MODE_SIZE			1
+#define HSMC_WRITE_MODE_OFFSET			1
+#define HSMC_WRITE_MODE_SIZE			1
+#define HSMC_EXNW_MODE_OFFSET			4
+#define HSMC_EXNW_MODE_SIZE			2
+#define HSMC_BAT_OFFSET				8
+#define HSMC_BAT_SIZE				1
+#define HSMC_DBW_OFFSET				12
+#define HSMC_DBW_SIZE				2
+#define HSMC_TDF_CYCLES_OFFSET			16
+#define HSMC_TDF_CYCLES_SIZE			4
+#define HSMC_TDF_MODE_OFFSET			20
+#define HSMC_TDF_MODE_SIZE			1
+#define HSMC_PMEN_OFFSET			24
+#define HSMC_PMEN_SIZE				1
+#define HSMC_PS_OFFSET				28
+#define HSMC_PS_SIZE				2
+
+/* Constants for READ_MODE */
+#define HSMC_READ_MODE_NCS_CONTROLLED		0
+#define HSMC_READ_MODE_NRD_CONTROLLED		1
+
+/* Constants for WRITE_MODE */
+#define HSMC_WRITE_MODE_NCS_CONTROLLED		0
+#define HSMC_WRITE_MODE_NWE_CONTROLLED		1
+
+/* Constants for EXNW_MODE */
+#define HSMC_EXNW_MODE_DISABLED			0
+#define HSMC_EXNW_MODE_RESERVED			1
+#define HSMC_EXNW_MODE_FROZEN			2
+#define HSMC_EXNW_MODE_READY			3
+
+/* Constants for BAT */
+#define HSMC_BAT_BYTE_SELECT			0
+#define HSMC_BAT_BYTE_WRITE			1
+
+/* Constants for DBW */
+#define HSMC_DBW_8_BITS				0
+#define HSMC_DBW_16_BITS			1
+#define HSMC_DBW_32_BITS			2
+
+/* Bit manipulation macros */
+#define HSMC_BIT(name)							\
+	(1 << HSMC_##name##_OFFSET)
+#define HSMC_BF(name,value)						\
+	(((value) & ((1 << HSMC_##name##_SIZE) - 1))			\
+	 << HSMC_##name##_OFFSET)
+#define HSMC_BFEXT(name,value)						\
+	(((value) >> HSMC_##name##_OFFSET)				\
+	 & ((1 << HSMC_##name##_SIZE) - 1))
+#define HSMC_BFINS(name,value,old)					\
+	(((old) & ~(((1 << HSMC_##name##_SIZE) - 1)			\
+		    << HSMC_##name##_OFFSET)) | HSMC_BF(name,value))
+
+/* Register access macros */
+#define hsmc_readl(port,reg)						\
+	readl((port)->regs + HSMC_##reg)
+#define hsmc_writel(port,reg,value)					\
+	writel((value), (port)->regs + HSMC_##reg)
+
+#endif /* __ASM_AVR32_HSMC_H__ */
Index: linux-2.6.18-rc6-mm2/include/asm-avr32/arch-at32ap/smc.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.18-rc6-mm2/include/asm-avr32/arch-at32ap/smc.h	2006-09-15 10:00:39.000000000 +0200
@@ -0,0 +1,60 @@
+/*
+ * Static Memory Controller for AT32 chips
+ *
+ * Copyright (C) 2006 Atmel Corporation
+ *
+ * Inspired by the OMAP2 General-Purpose Memory Controller interface
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ARCH_AT32AP_SMC_H
+#define __ARCH_AT32AP_SMC_H
+
+/*
+ * All timing parameters are in nanoseconds.
+ */
+struct smc_config {
+	/* Delay from address valid to assertion of given strobe */
+	u16		ncs_read_setup;
+	u16		nrd_setup;
+	u16		ncs_write_setup;
+	u16		nwe_setup;
+
+	/* Pulse length of given strobe */
+	u16		ncs_read_pulse;
+	u16		nrd_pulse;
+	u16		ncs_write_pulse;
+	u16		nwe_pulse;
+
+	/* Total cycle length of given operation */
+	u16		read_cycle;
+	u16		write_cycle;
+
+	/* Bus width in bytes */
+	u8		bus_width;
+
+	/*
+	 * 0: Data is sampled on rising edge of NCS
+	 * 1: Data is sampled on rising edge of NRD
+	 */
+	unsigned int	nrd_controlled:1;
+
+	/*
+	 * 0: Data is driven on falling edge of NCS
+	 * 1: Data is driven on falling edge of NWR
+	 */
+	unsigned int	nwe_controlled:1;
+
+	/*
+	 * 0: Byte select access type
+	 * 1: Byte write access type
+	 */
+	unsigned int	byte_write:1;
+};
+
+extern int smc_set_configuration(int cs, const struct smc_config *config);
+extern struct smc_config *smc_get_configuration(int cs);
+
+#endif /* __ARCH_AT32AP_SMC_H */

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [-mm patch 2/3] AVR32 MTD: Unlock flash if necessary (try 2)
  2006-09-15 14:35 ` [-mm patch 1/3] AVR32 MTD: Static Memory Controller driver " Haavard Skinnemoen
@ 2006-09-15 14:37   ` Haavard Skinnemoen
  2006-09-15 14:38     ` [-mm patch 3/3] AVR32 MTD: AT49BV6416 platform device for ATSTK1000 " Haavard Skinnemoen
  2006-09-15 15:32     ` [-mm patch 2/3] AVR32 MTD: Unlock flash if necessary " David Woodhouse
  0 siblings, 2 replies; 9+ messages in thread
From: Haavard Skinnemoen @ 2006-09-15 14:37 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-mtd, linux-kernel, David Woodhouse

If a cfi_cmdset_0002 fixup installs an unlock() operation, use it
to unlock the whole flash after the erase regions have been set up.

I wanted to do this in the fixup itself, but it wouldn't work because
the erase regions hadn't been initialized, and mtd->size was zero.

Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
---
 drivers/mtd/chips/cfi_cmdset_0002.c |    9 +++++++++
 1 file changed, 9 insertions(+)

Index: linux-2.6.18-rc6-mm2/drivers/mtd/chips/cfi_cmdset_0002.c
===================================================================
--- linux-2.6.18-rc6-mm2.orig/drivers/mtd/chips/cfi_cmdset_0002.c	2006-09-15 14:39:40.000000000 +0200
+++ linux-2.6.18-rc6-mm2/drivers/mtd/chips/cfi_cmdset_0002.c	2006-09-15 15:45:41.000000000 +0200
@@ -416,6 +416,15 @@ static struct mtd_info *cfi_amdstd_setup
 	}
 #endif
 
+	/*
+	 * If an unlock() operation was installed by a fixup, use it
+	 * now to unlock the whole flash.
+	 */
+	if (mtd->unlock && mtd->unlock(mtd, 0, mtd->size))
+		printk(KERN_WARNING "%s: unlock failed, writes may not work\n",
+		       map->name);
+
+
 	/* FIXME: erase-suspend-program is broken.  See
 	   http://lists.infradead.org/pipermail/linux-mtd/2003-December/009001.html */
 	printk(KERN_NOTICE "cfi_cmdset_0002: Disabling erase-suspend-program due to code brokenness.\n");

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [-mm patch 3/3] AVR32 MTD: AT49BV6416 platform device for ATSTK1000 (try 2)
  2006-09-15 14:37   ` [-mm patch 2/3] AVR32 MTD: Unlock flash if necessary " Haavard Skinnemoen
@ 2006-09-15 14:38     ` Haavard Skinnemoen
  2006-09-15 15:32     ` [-mm patch 2/3] AVR32 MTD: Unlock flash if necessary " David Woodhouse
  1 sibling, 0 replies; 9+ messages in thread
From: Haavard Skinnemoen @ 2006-09-15 14:38 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-mtd, linux-kernel, David Woodhouse

FRegister a platform device for the AT49BV6416 NOR flash chip on the
ATSTK1000 development board for use by the physmap MTD driver.

The SMC timings are set up before the platform device is registered
so that no board-specific mapping driver is necessary.

Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
---
 arch/avr32/boards/atstk1000/Makefile |    2 
 arch/avr32/boards/atstk1000/flash.c  |   95 +++++++++++++++++++++++++++++++++++
 2 files changed, 96 insertions(+), 1 deletion(-)

Index: linux-2.6.18-rc6-mm2/arch/avr32/boards/atstk1000/Makefile
===================================================================
--- linux-2.6.18-rc6-mm2.orig/arch/avr32/boards/atstk1000/Makefile	2006-09-15 13:41:12.000000000 +0200
+++ linux-2.6.18-rc6-mm2/arch/avr32/boards/atstk1000/Makefile	2006-09-15 13:44:30.000000000 +0200
@@ -1,2 +1,2 @@
-obj-y				+= setup.o spi.o
+obj-y				+= setup.o spi.o flash.o
 obj-$(CONFIG_BOARD_ATSTK1002)	+= atstk1002.o
Index: linux-2.6.18-rc6-mm2/arch/avr32/boards/atstk1000/flash.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.18-rc6-mm2/arch/avr32/boards/atstk1000/flash.c	2006-09-15 13:45:21.000000000 +0200
@@ -0,0 +1,95 @@
+/*
+ * ATSTK1000 board-specific flash initialization
+ *
+ * Copyright (C) 2005-2006 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/arch/smc.h>
+
+static struct smc_config flash_config __initdata = {
+	.ncs_read_setup		= 0,
+	.nrd_setup		= 40,
+	.ncs_write_setup	= 0,
+	.nwe_setup		= 10,
+
+	.ncs_read_pulse		= 80,
+	.nrd_pulse		= 40,
+	.ncs_write_pulse	= 65,
+	.nwe_pulse		= 55,
+
+	.read_cycle		= 120,
+	.write_cycle		= 120,
+
+	.bus_width		= 2,
+	.nrd_controlled		= 1,
+	.nwe_controlled		= 1,
+	.byte_write		= 1,
+};
+
+static struct mtd_partition flash_parts[] = {
+	{
+		.name           = "u-boot",
+		.offset         = 0x00000000,
+		.size           = 0x00020000,           /* 128 KiB */
+		.mask_flags     = MTD_WRITEABLE,
+	},
+	{
+		.name           = "root",
+		.offset         = 0x00020000,
+		.size           = 0x007d0000,
+	},
+	{
+		.name           = "env",
+		.offset         = 0x007f0000,
+		.size           = 0x00010000,
+		.mask_flags     = MTD_WRITEABLE,
+	},
+};
+
+static struct physmap_flash_data flash_data = {
+	.width		= 2,
+	.nr_parts	= ARRAY_SIZE(flash_parts),
+	.parts		= flash_parts,
+};
+
+static struct resource flash_resource = {
+	.start		= 0x00000000,
+	.end		= 0x007fffff,
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device flash_device = {
+	.name		= "physmap-flash",
+	.id		= 0,
+	.resource	= &flash_resource,
+	.num_resources	= 1,
+	.dev		= {
+		.platform_data = &flash_data,
+	},
+};
+
+/* This needs to be called after the SMC has been initialized */
+static int __init atstk1000_flash_init(void)
+{
+	int ret;
+
+	ret = smc_set_configuration(0, &flash_config);
+	if (ret < 0) {
+		printk(KERN_ERR "atstk1000: failed to set NOR flash timing\n");
+		return ret;
+	}
+
+	platform_device_register(&flash_device);
+
+	return 0;
+}
+device_initcall(atstk1000_flash_init);

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [-mm patch 2/3] AVR32 MTD: Unlock flash if necessary (try 2)
  2006-09-15 14:37   ` [-mm patch 2/3] AVR32 MTD: Unlock flash if necessary " Haavard Skinnemoen
  2006-09-15 14:38     ` [-mm patch 3/3] AVR32 MTD: AT49BV6416 platform device for ATSTK1000 " Haavard Skinnemoen
@ 2006-09-15 15:32     ` David Woodhouse
  2006-09-18  8:12       ` Haavard Skinnemoen
  1 sibling, 1 reply; 9+ messages in thread
From: David Woodhouse @ 2006-09-15 15:32 UTC (permalink / raw)
  To: Haavard Skinnemoen; +Cc: Andrew Morton, linux-mtd, linux-kernel

On Fri, 2006-09-15 at 16:37 +0200, Haavard Skinnemoen wrote:
> If a cfi_cmdset_0002 fixup installs an unlock() operation, use it
> to unlock the whole flash after the erase regions have been set up.

There are cmdset_0001 chips which have this affliction too. I was
thinking of having a flag MTD_STUPID_LOCK which you set when you
determine that it's one of these chips, then add_mtd_device() can do the
unlocking... or add_mtd_partitions() can do it but _only_ for writable
partitions.

-- 
dwmw2


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [-mm patch 2/3] AVR32 MTD: Unlock flash if necessary (try 2)
  2006-09-15 15:32     ` [-mm patch 2/3] AVR32 MTD: Unlock flash if necessary " David Woodhouse
@ 2006-09-18  8:12       ` Haavard Skinnemoen
  2006-09-18  8:14         ` David Woodhouse
  0 siblings, 1 reply; 9+ messages in thread
From: Haavard Skinnemoen @ 2006-09-18  8:12 UTC (permalink / raw)
  To: David Woodhouse; +Cc: Andrew Morton, linux-mtd, linux-kernel

On Fri, 15 Sep 2006 16:32:26 +0100
David Woodhouse <dwmw2@infradead.org> wrote:

> On Fri, 2006-09-15 at 16:37 +0200, Haavard Skinnemoen wrote:
> > If a cfi_cmdset_0002 fixup installs an unlock() operation, use it
> > to unlock the whole flash after the erase regions have been set up.
> 
> There are cmdset_0001 chips which have this affliction too. I was
> thinking of having a flag MTD_STUPID_LOCK which you set when you
> determine that it's one of these chips, then add_mtd_device() can do
> the unlocking... or add_mtd_partitions() can do it but _only_ for
> writable partitions.

Ok, so how about something like this? Which other chips should be marked?

---

From: Haavard Skinnemoen <hskinnemoen@atmel.com>
Subject: [-mm patch 2/3] AVR32 MTD: Unlock flash if necessary

Introduce the MTD_STUPID_LOCK flag which indicates that the flash chip
is always locked after power-up, so all sectors need to be unlocked
before it is usable.

If this flag is set, and the chip provides an unlock() operation,
mtd_add_device will unlock the whole MTD device if it's writeable. This
means that non-writeable partitions will stay locked.

Set MTD_STUPID_LOCK in fixup_use_atmel_lock() so that these chips will
work as expected.

Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
---
 drivers/mtd/chips/cfi_cmdset_0002.c |    1 +
 drivers/mtd/mtdcore.c               |   10 ++++++++++
 include/mtd/mtd-abi.h               |    1 +
 3 files changed, 12 insertions(+)

Index: linux-2.6.18-rc6-mm2/drivers/mtd/chips/cfi_cmdset_0002.c
===================================================================
--- linux-2.6.18-rc6-mm2.orig/drivers/mtd/chips/cfi_cmdset_0002.c	2006-09-18 09:43:02.000000000 +0200
+++ linux-2.6.18-rc6-mm2/drivers/mtd/chips/cfi_cmdset_0002.c	2006-09-18 10:02:31.000000000 +0200
@@ -212,6 +212,7 @@ static void fixup_use_atmel_lock(struct 
 {
 	mtd->lock = cfi_atmel_lock;
 	mtd->unlock = cfi_atmel_unlock;
+	mtd->flags |= MTD_STUPID_LOCK;
 }
 
 static struct cfi_fixup cfi_fixup_table[] = {
Index: linux-2.6.18-rc6-mm2/drivers/mtd/mtdcore.c
===================================================================
--- linux-2.6.18-rc6-mm2.orig/drivers/mtd/mtdcore.c	2006-09-18 09:36:56.000000000 +0200
+++ linux-2.6.18-rc6-mm2/drivers/mtd/mtdcore.c	2006-09-18 10:03:24.000000000 +0200
@@ -57,6 +57,16 @@ int add_mtd_device(struct mtd_info *mtd)
 			mtd->index = i;
 			mtd->usecount = 0;
 
+			/* Some chips always power up locked. Unlock them now */
+			if ((mtd->flags & MTD_WRITEABLE)
+			    && (mtd->flags & MTD_STUPID_LOCK) && mtd->unlock) {
+				if (mtd->unlock(mtd, 0, mtd->size))
+					printk(KERN_WARNING
+					       "%s: unlock failed, "
+					       "writes may not work\n",
+					       mtd->name);
+			}
+
 			DEBUG(0, "mtd: Giving out device %d to %s\n",i, mtd->name);
 			/* No need to get a refcount on the module containing
 			   the notifier, since we hold the mtd_table_mutex */
Index: linux-2.6.18-rc6-mm2/include/mtd/mtd-abi.h
===================================================================
--- linux-2.6.18-rc6-mm2.orig/include/mtd/mtd-abi.h	2006-09-18 09:34:14.000000000 +0200
+++ linux-2.6.18-rc6-mm2/include/mtd/mtd-abi.h	2006-09-18 09:35:27.000000000 +0200
@@ -34,6 +34,7 @@ struct mtd_oob_buf {
 #define MTD_WRITEABLE		0x400	/* Device is writeable */
 #define MTD_BIT_WRITEABLE	0x800	/* Single bits can be flipped */
 #define MTD_NO_ERASE		0x1000	/* No erase necessary */
+#define MTD_STUPID_LOCK		0x2000	/* Always locked after reset */
 
 // Some common devices / combinations of capabilities
 #define MTD_CAP_ROM		0

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [-mm patch 2/3] AVR32 MTD: Unlock flash if necessary (try 2)
  2006-09-18  8:12       ` Haavard Skinnemoen
@ 2006-09-18  8:14         ` David Woodhouse
  2006-09-18  8:21           ` Haavard Skinnemoen
  0 siblings, 1 reply; 9+ messages in thread
From: David Woodhouse @ 2006-09-18  8:14 UTC (permalink / raw)
  To: Haavard Skinnemoen; +Cc: Andrew Morton, linux-mtd, linux-kernel

On Mon, 2006-09-18 at 10:12 +0200, Haavard Skinnemoen wrote:
> On Fri, 15 Sep 2006 16:32:26 +0100
> David Woodhouse <dwmw2@infradead.org> wrote:
> 
> > On Fri, 2006-09-15 at 16:37 +0200, Haavard Skinnemoen wrote:
> > > If a cfi_cmdset_0002 fixup installs an unlock() operation, use it
> > > to unlock the whole flash after the erase regions have been set up.
> > 
> > There are cmdset_0001 chips which have this affliction too. I was
> > thinking of having a flag MTD_STUPID_LOCK which you set when you
> > determine that it's one of these chips, then add_mtd_device() can do
> > the unlocking... or add_mtd_partitions() can do it but _only_ for
> > writable partitions.
> 
> Ok, so how about something like this? Which other chips should be marked?

Looks good; thanks. There's some Intel chips which need to be so marked
but I'll let the Intel folks deal with that.

I'll apply it to my git tree, but only _after_ Linus has pulled from it
as requested a couple of days ago -- I think this should wait for 2.6.19
rather than being slipped in at the last moment.

-- 
dwmw2


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [-mm patch 2/3] AVR32 MTD: Unlock flash if necessary (try 2)
  2006-09-18  8:14         ` David Woodhouse
@ 2006-09-18  8:21           ` Haavard Skinnemoen
  2006-09-18  8:21             ` David Woodhouse
  0 siblings, 1 reply; 9+ messages in thread
From: Haavard Skinnemoen @ 2006-09-18  8:21 UTC (permalink / raw)
  To: David Woodhouse; +Cc: Andrew Morton, linux-mtd, linux-kernel

On Mon, 18 Sep 2006 09:14:20 +0100
David Woodhouse <dwmw2@infradead.org> wrote:

> I'll apply it to my git tree, but only _after_ Linus has pulled from
> it as requested a couple of days ago -- I think this should wait for
> 2.6.19 rather than being slipped in at the last moment.

Fine with me. The stuff that depends on this (and that I care about) is
definitely not 2.6.18 material. There could of course be other boards
where this matters, but they have to speak up for themselves.

Haavard

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [-mm patch 2/3] AVR32 MTD: Unlock flash if necessary (try 2)
  2006-09-18  8:21           ` Haavard Skinnemoen
@ 2006-09-18  8:21             ` David Woodhouse
  0 siblings, 0 replies; 9+ messages in thread
From: David Woodhouse @ 2006-09-18  8:21 UTC (permalink / raw)
  To: Haavard Skinnemoen; +Cc: Andrew Morton, linux-mtd, linux-kernel

On Mon, 2006-09-18 at 10:21 +0200, Haavard Skinnemoen wrote:
> Fine with me. The stuff that depends on this (and that I care about)
> is definitely not 2.6.18 material. There could of course be other
> boards where this matters, but they have to speak up for themselves. 

Largely, they have hacks in their own board drivers (or userspace) to
deal with the problem.

-- 
dwmw2


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2006-09-18  8:22 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-09-15 14:31 [-mm patch 0/3] AVR32 MTD: Introduction (try 2) Haavard Skinnemoen
2006-09-15 14:35 ` [-mm patch 1/3] AVR32 MTD: Static Memory Controller driver " Haavard Skinnemoen
2006-09-15 14:37   ` [-mm patch 2/3] AVR32 MTD: Unlock flash if necessary " Haavard Skinnemoen
2006-09-15 14:38     ` [-mm patch 3/3] AVR32 MTD: AT49BV6416 platform device for ATSTK1000 " Haavard Skinnemoen
2006-09-15 15:32     ` [-mm patch 2/3] AVR32 MTD: Unlock flash if necessary " David Woodhouse
2006-09-18  8:12       ` Haavard Skinnemoen
2006-09-18  8:14         ` David Woodhouse
2006-09-18  8:21           ` Haavard Skinnemoen
2006-09-18  8:21             ` David Woodhouse

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).