| Jonas Larsson | a16fffd | 2009-03-27 10:18:14 +0100 | [diff] [blame] | 1 | /* | 
|  | 2 | * Merisc board-specific flash initialization | 
|  | 3 | * | 
|  | 4 | * Copyright (C) 2008 Martinsson Elektronik AB | 
|  | 5 | * | 
|  | 6 | * This program is free software; you can redistribute it and/or modify | 
|  | 7 | * it under the terms of the GNU General Public License version 2 as | 
|  | 8 | * published by the Free Software Foundation. | 
|  | 9 | */ | 
|  | 10 | #include <linux/init.h> | 
|  | 11 | #include <linux/platform_device.h> | 
|  | 12 | #include <linux/mtd/mtd.h> | 
|  | 13 | #include <linux/mtd/partitions.h> | 
|  | 14 | #include <linux/mtd/physmap.h> | 
|  | 15 | #include <mach/smc.h> | 
|  | 16 |  | 
|  | 17 | /* Will be translated to units of 14.3 ns, rounded up */ | 
|  | 18 | static struct smc_timing flash_timing __initdata = { | 
|  | 19 | .ncs_read_setup		= 1 * 14, | 
|  | 20 | .nrd_setup		= 5 * 14, | 
|  | 21 | .ncs_write_setup	= 1 * 14, | 
|  | 22 | .nwe_setup		= 2 * 14, | 
|  | 23 |  | 
|  | 24 | .ncs_read_pulse		= 12 * 14, | 
|  | 25 | .nrd_pulse		= 7 * 14, | 
|  | 26 | .ncs_write_pulse	= 8 * 14, | 
|  | 27 | .nwe_pulse		= 4 * 14, | 
|  | 28 |  | 
|  | 29 | .read_cycle		= 14 * 14, | 
|  | 30 | .write_cycle		= 10 * 14, | 
|  | 31 | }; | 
|  | 32 |  | 
|  | 33 | static struct smc_config flash_config __initdata = { | 
|  | 34 | .bus_width	= 2, | 
|  | 35 | .nrd_controlled	= 1, | 
|  | 36 | .nwe_controlled	= 1, | 
|  | 37 | .byte_write	= 1, | 
|  | 38 | .tdf_cycles	= 3, | 
|  | 39 | }; | 
|  | 40 |  | 
|  | 41 | static struct mtd_partition flash_0_parts[] = { | 
|  | 42 | { | 
|  | 43 | .name		= "boot", | 
|  | 44 | .offset		= 0x00000000, | 
|  | 45 | .size		= 0x00060000, | 
|  | 46 | .mask_flags	= 0, | 
|  | 47 | }, | 
|  | 48 | { | 
|  | 49 | .name		= "kernel", | 
|  | 50 | .offset		= 0x00060000, | 
|  | 51 | .size		= 0x00200000, | 
|  | 52 | .mask_flags	= 0, | 
|  | 53 | }, | 
|  | 54 | { | 
|  | 55 | .name		= "root", | 
|  | 56 | .offset		= 0x00260000, | 
|  | 57 | .size		= MTDPART_SIZ_FULL, | 
|  | 58 | .mask_flags	= 0, | 
|  | 59 | }, | 
|  | 60 | }; | 
|  | 61 |  | 
|  | 62 | static struct mtd_partition flash_1_parts[] = { | 
|  | 63 | { | 
|  | 64 | .name		= "2ndflash", | 
|  | 65 | .offset		= 0x00000000, | 
|  | 66 | .size		= MTDPART_SIZ_FULL, | 
|  | 67 | .mask_flags	= 0, | 
|  | 68 | }, | 
|  | 69 | }; | 
|  | 70 |  | 
|  | 71 | static struct physmap_flash_data flash_data[] = { | 
|  | 72 | { | 
|  | 73 | .width		= 2, | 
|  | 74 | .nr_parts	= ARRAY_SIZE(flash_0_parts), | 
|  | 75 | .parts		= flash_0_parts, | 
|  | 76 | }, | 
|  | 77 | { | 
|  | 78 | .width		= 2, | 
|  | 79 | .nr_parts	= ARRAY_SIZE(flash_1_parts), | 
|  | 80 | .parts		= flash_1_parts, | 
|  | 81 | } | 
|  | 82 | }; | 
|  | 83 |  | 
|  | 84 | static struct resource flash_resource[] = { | 
|  | 85 | { | 
|  | 86 | .start		= 0x00000000, | 
|  | 87 | .end		= 0x03ffffff, | 
|  | 88 | .flags		= IORESOURCE_MEM, | 
|  | 89 | }, | 
|  | 90 | { | 
|  | 91 | .start		= 0x04000000, | 
|  | 92 | .end		= 0x07ffffff, | 
|  | 93 | .flags		= IORESOURCE_MEM, | 
|  | 94 | }, | 
|  | 95 | }; | 
|  | 96 |  | 
|  | 97 | static struct platform_device flash_device[] = { | 
|  | 98 | { | 
|  | 99 | .name		= "physmap-flash", | 
|  | 100 | .id		= 0, | 
|  | 101 | .resource	= &flash_resource[0], | 
|  | 102 | .num_resources	= 1, | 
|  | 103 | .dev		= { | 
|  | 104 | .platform_data	= &flash_data[0], | 
|  | 105 | }, | 
|  | 106 | }, | 
|  | 107 | { | 
|  | 108 | .name		= "physmap-flash", | 
|  | 109 | .id		= 1, | 
|  | 110 | .resource	= &flash_resource[1], | 
|  | 111 | .num_resources	= 1, | 
|  | 112 | .dev		= { | 
|  | 113 | .platform_data	= &flash_data[1], | 
|  | 114 | }, | 
|  | 115 | }, | 
|  | 116 | }; | 
|  | 117 |  | 
|  | 118 | static int __init merisc_flash_init(void) | 
|  | 119 | { | 
|  | 120 | int ret; | 
|  | 121 | smc_set_timing(&flash_config, &flash_timing); | 
|  | 122 |  | 
|  | 123 | ret = smc_set_configuration(0, &flash_config); | 
|  | 124 | if (ret < 0) { | 
|  | 125 | printk(KERN_ERR "Merisc: failed to set NOR flash timing #0\n"); | 
|  | 126 | return ret; | 
|  | 127 | } | 
|  | 128 |  | 
|  | 129 | ret = smc_set_configuration(4, &flash_config); | 
|  | 130 | if (ret < 0) { | 
|  | 131 | printk(KERN_ERR "Merisc: failed to set NOR flash timing #1\n"); | 
|  | 132 | return ret; | 
|  | 133 | } | 
|  | 134 |  | 
|  | 135 | platform_device_register(&flash_device[0]); | 
|  | 136 | platform_device_register(&flash_device[1]); | 
|  | 137 | return 0; | 
|  | 138 | } | 
|  | 139 | device_initcall(merisc_flash_init); |