Linux MIPS Architecture development
 help / color / mirror / Atom feed
From: Daniel Schwierzeck <daniel.schwierzeck@googlemail.com>
To: John Crispin <blogic@openwrt.org>
Cc: Ralf Baechle <ralf@linux-mips.org>,
	Ralph Hempel <ralph.hempel@lantiq.com>,
	David Woodhouse <dwmw2@infradead.org>,
	linux-mips@linux-mips.org, linux-mtd@lists.infradead.org
Subject: Re: [PATCH 06/10] MIPS: lantiq: add NOR flash support
Date: Tue, 11 Jan 2011 03:59:19 +0100	[thread overview]
Message-ID: <4D2BC787.20002@gmail.com> (raw)
In-Reply-To: <1294257379-417-7-git-send-email-blogic@openwrt.org>

Hi John,

the EBU doesn't allow unaligned read or write access thus Lantiq added 
this alignment hack directly in hardware. The addr^=2 is only needed 
during CFI probe because odd addresses are accessed. A simple solution 
is inside your patch.

The spin_lock_irqsave(&ebu_lock, flags); is actually not needed because 
the EBU does access arbitration and protection already in hardware.

Daniel

On 01/05/2011 08:56 PM, John Crispin wrote:
> NOR flash is attached to the same EBU (External Bus Unit) as PCI. As described
> in the PCI patch, the EBU is a little obscure, resulting in the upper and lower
> 16 bit of the data on a 32 bit read are swapped. (essentially we have a addr^=2)
> This only happens on the read of data. In order to not have to high an impact
> on the read performance from the EBU we store all data on the flash with
> addr^=2. This allows us to do generic reads without having to do any swapping.
> For the write to now work we need to swizzle the the 0x2 bit of the addr.
> However this write swizzle needs to only happen when doing a CMD and not a DATA
> write.
>
> As the MTD layer currently makes no difference between a CMD and DATA read when
> using complex maps, the map driver does not know when the swizzle and when not
> to swizzle. The next patch in the series adds a hack to the MTD to workaround
> this problem. I am sending these 2 patches to the mtd list aswell. There are
> several ways to solve this generically in the mtd layer in a much better way.
> This will have minor impact on the actual map code provided in this patch.
>
> Signed-off-by: John Crispin<blogic@openwrt.org>
> Signed-off-by: Ralph Hempel<ralph.hempel@lantiq.com>
> Cc: David Woodhouse<dwmw2@infradead.org>
> Cc: linux-mips@linux-mips.org
> Cc: linux-mtd@lists.infradead.org
> ---
>   drivers/mtd/maps/Kconfig  |    7 ++
>   drivers/mtd/maps/Makefile |    1 +
>   drivers/mtd/maps/lantiq.c |  169 +++++++++++++++++++++++++++++++++++++++++++++
>   3 files changed, 177 insertions(+), 0 deletions(-)
>   create mode 100644 drivers/mtd/maps/lantiq.c
>
> diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
> index a0dd7bb..ca69a7f 100644
> --- a/drivers/mtd/maps/Kconfig
> +++ b/drivers/mtd/maps/Kconfig
> @@ -260,6 +260,13 @@ config MTD_BCM963XX
>   	  Support for parsing CFE image tag and creating MTD partitions on
>   	  Broadcom BCM63xx boards.
>
> +config MTD_LANTIQ
> +	bool "Lantiq SoC NOR support"
> +	depends on LANTIQ&&  MTD_PARTITIONS
> +	help
> +	  Support for NOR flash chips on Lantiq SoC. The Chips are connected
> +	  to the SoCs EBU (External Bus Unit)
> +
>   config MTD_DILNETPC
>   	tristate "CFI Flash device mapped on DIL/Net PC"
>   	depends on X86&&  MTD_CONCAT&&  MTD_PARTITIONS&&  MTD_CFI_INTELEXT&&  BROKEN
> diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
> index c7869c7..bb2ce2f 100644
> --- a/drivers/mtd/maps/Makefile
> +++ b/drivers/mtd/maps/Makefile
> @@ -59,3 +59,4 @@ obj-$(CONFIG_MTD_RBTX4939)	+= rbtx4939-flash.o
>   obj-$(CONFIG_MTD_VMU)		+= vmu-flash.o
>   obj-$(CONFIG_MTD_GPIO_ADDR)	+= gpio-addr-flash.o
>   obj-$(CONFIG_MTD_BCM963XX)	+= bcm963xx-flash.o
> +obj-$(CONFIG_MTD_LANTIQ)	+= lantiq.o
> diff --git a/drivers/mtd/maps/lantiq.c b/drivers/mtd/maps/lantiq.c
> new file mode 100644
> index 0000000..e5a361e
> --- /dev/null
> +++ b/drivers/mtd/maps/lantiq.c
> @@ -0,0 +1,169 @@
> +/*
> + *  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.
> + *
> + *  Copyright (C) 2004 Liu Peng Infineon IFAP DC COM CPE
> + *  Copyright (C) 2010 John Crispin<blogic@openwrt.org>
> + */
> +
> +#include<linux/module.h>
> +#include<linux/types.h>
> +#include<linux/kernel.h>
> +#include<linux/io.h>
> +#include<linux/init.h>
> +#include<linux/mtd/mtd.h>
> +#include<linux/mtd/map.h>
> +#include<linux/mtd/partitions.h>
> +#include<linux/mtd/cfi.h>
> +#include<linux/magic.h>
> +#include<linux/platform_device.h>
> +#include<linux/mtd/physmap.h>
> +
> +#include<lantiq_soc.h>
> +#include<lantiq_platform.h>
> +
static int ltq_probing = 0;

> +static map_word
> +ltq_read16(struct map_info *map, unsigned long adr)
> +{
> +	unsigned long flags;
> +	map_word temp;
> +	spin_lock_irqsave(&ebu_lock, flags);
	if (ltq_probing)
		adr ^= 2;
> +	temp.x[0] = *((__u16 *)(map->virt + adr));
> +	spin_unlock_irqrestore(&ebu_lock, flags);
> +	return temp;
> +}
> +
> +static void
> +ltq_write16(struct map_info *map, map_word d, unsigned long adr)
> +{
> +	unsigned long flags;
> +	spin_lock_irqsave(&ebu_lock, flags);
	if (ltq_probing)
		adr ^= 2;
> +	*((__u16 *)(map->virt + adr)) = d.x[0];
> +	spin_unlock_irqrestore(&ebu_lock, flags);
> +}
> +
> +void
> +ltq_copy_from(struct map_info *map, void *to,
> +	unsigned long from, ssize_t len)
> +{
> +	unsigned char *p;
> +	unsigned char *to_8;
> +	unsigned long flags;
> +	spin_lock_irqsave(&ebu_lock, flags);
> +	from = (unsigned long)(from + map->virt);
> +	p = (unsigned char *) from;
> +	to_8 = (unsigned char *) to;
> +	while (len--)
> +		*to_8++ = *p++;
> +	spin_unlock_irqrestore(&ebu_lock, flags);
> +}
> +
> +void
> +ltq_copy_to(struct map_info *map, unsigned long to,
> +	const void *from, ssize_t len)
> +{
> +	unsigned char *p =  (unsigned char *)from;
> +	unsigned char *to_8;
> +	unsigned long flags;
> +	spin_lock_irqsave(&ebu_lock, flags);
> +	to += (unsigned long) map->virt;
> +	to_8 = (unsigned char *)to;
> +	while (len--)
> +		*p++ = *to_8++;
> +	spin_unlock_irqrestore(&ebu_lock, flags);
> +}
> +
> +static const char * const part_probe_types[] = {
> +	"cmdlinepart", NULL };
> +
> +static struct map_info ltq_map = {
> +	.name = "ltq_nor",
> +	.bankwidth = 2,
> +	.read = ltq_read16,
> +	.write = ltq_write16,
> +	.copy_from = ltq_copy_from,
> +	.copy_to = ltq_copy_to,
> +};
> +
> +static int
> +ltq_mtd_probe(struct platform_device *pdev)
> +{
> +	struct physmap_flash_data *ltq_mtd_data =
> +		(struct physmap_flash_data *) dev_get_platdata(&pdev->dev);
> +	struct mtd_info *ltq_mtd = NULL;
> +	struct mtd_partition *parts = NULL;
> +	struct resource *res = 0;
> +	int nr_parts = 0;
> +
> +#ifdef CONFIG_SOC_TYPE_XWAY
> +	ltq_w32(ltq_r32(LTQ_EBU_BUSCON0)&  ~EBU_WRDIS, LTQ_EBU_BUSCON0);
> +#endif
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!res) {
> +		dev_err(&pdev->dev, "failed to get memory resource");
> +		return -ENOENT;
> +	}
> +	res = request_mem_region(res->start, resource_size(res),
> +		dev_name(&pdev->dev));
> +	if (!res) {
> +		dev_err(&pdev->dev, "failed to request mem resource");
> +		return -EBUSY;
> +	}
> +
> +	ltq_map.phys = res->start;
> +	ltq_map.size = resource_size(res);
> +	ltq_map.virt = ioremap_nocache(ltq_map.phys, ltq_map.size);
> +
> +	if (!ltq_map.virt) {
> +		dev_err(&pdev->dev, "failed to ioremap!\n");
> +		return -EIO;
> +	}
> +
	ltq_probing = 1;
> +	ltq_mtd = (struct mtd_info *) do_map_probe("cfi_probe",&ltq_map);
	ltq_probing = 0;
> +	if (!ltq_mtd) {
> +		iounmap(ltq_map.virt);
> +		dev_err(&pdev->dev, "probing failed\n");
> +		return -ENXIO;
> +	}
> +
> +	ltq_mtd->owner = THIS_MODULE;
> +
> +	nr_parts = parse_mtd_partitions(ltq_mtd, part_probe_types,&parts, 0);
> +	if (nr_parts>  0) {
> +		dev_info(&pdev->dev,
> +			"using %d partitions from cmdline", nr_parts);
> +	} else {
> +		nr_parts = ltq_mtd_data->nr_parts;
> +		parts = ltq_mtd_data->parts;
> +	}
> +
> +	add_mtd_partitions(ltq_mtd, parts, nr_parts);
> +	return 0;
> +}
> +
> +static struct platform_driver ltq_mtd_driver = {
> +	.probe = ltq_mtd_probe,
> +	.driver = {
> +		.name = "ltq_nor",
> +		.owner = THIS_MODULE,
> +	},
> +};
> +
> +int __init
> +init_ltq_mtd(void)
> +{
> +	int ret = platform_driver_register(&ltq_mtd_driver);
> +	if (ret)
> +		printk(KERN_INFO "ltq_nor: error registering platfom driver");
> +	return ret;
> +}
> +
> +module_init(init_ltq_mtd);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("John Crispin<blogic@openwrt.org>");
> +MODULE_DESCRIPTION("Lantiq SoC NOR");

  reply	other threads:[~2011-01-11  2:59 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-01-05 19:56 [PATCH 00/10] MIPS: add support for Lantiq SoCs John Crispin
2011-01-05 19:56 ` [PATCH 01/10] MIPS: lantiq: add initial " John Crispin
2011-01-05 20:25   ` Geert Uytterhoeven
2011-01-13 11:05   ` Daniel Schwierzeck
2011-01-13 11:14     ` John Crispin
2011-01-13 12:47       ` Daniel Schwierzeck
2011-01-13 15:03         ` John Crispin
2011-01-05 19:56 ` [PATCH 02/10] MIPS: lantiq: add SoC specific code for XWAY family John Crispin
2011-01-05 19:56 ` [PATCH 03/10] MIPS: lantiq: add PCI controller support John Crispin
2011-01-05 19:56 ` [PATCH 04/10] MIPS: lantiq: add serial port support John Crispin
2011-01-05 19:56 ` [PATCH 05/10] MIPS: lantiq: add watchdog support John Crispin
2011-01-05 23:49   ` Jamie Iles
2011-01-06  9:51     ` John Crispin
2011-01-06 11:15       ` Jamie Iles
2011-01-06 11:38         ` John Crispin
2011-01-05 19:56 ` [PATCH 06/10] MIPS: lantiq: add NOR flash support John Crispin
2011-01-11  2:59   ` Daniel Schwierzeck [this message]
2011-01-11 10:29     ` John Crispin
2011-01-05 19:56 ` [PATCH 07/10] MIPS: lantiq: add NOR flash CFI address swizzle John Crispin
2011-01-06 10:06   ` John Crispin
2011-01-05 19:56 ` [PATCH 08/10] MIPS: lantiq: add platform device support John Crispin
2011-01-05 19:56 ` [PATCH 09/10] MIPS: lantiq: add mips_machine support John Crispin
2011-01-05 19:56 ` [PATCH 10/10] MIPS: lantiq: add machtypes for lantiq eval kits John Crispin
2011-01-11  2:44 ` [PATCH 00/10] MIPS: add support for Lantiq SoCs Daniel Schwierzeck
2011-01-11 12:07   ` John Crispin
2011-01-11 12:40     ` Daniel Schwierzeck
2011-01-11 12:49       ` John Crispin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4D2BC787.20002@gmail.com \
    --to=daniel.schwierzeck@googlemail.com \
    --cc=blogic@openwrt.org \
    --cc=dwmw2@infradead.org \
    --cc=linux-mips@linux-mips.org \
    --cc=linux-mtd@lists.infradead.org \
    --cc=ralf@linux-mips.org \
    --cc=ralph.hempel@lantiq.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox