]>
Commit | Line | Data |
---|---|---|
5b3b1688 DD |
1 | /* |
2 | * Octeon Bootbus flash setup | |
3 | * | |
4 | * This file is subject to the terms and conditions of the GNU General Public | |
5 | * License. See the file "COPYING" in the main directory of this archive | |
6 | * for more details. | |
7 | * | |
8 | * Copyright (C) 2007, 2008 Cavium Networks | |
9 | */ | |
10 | #include <linux/kernel.h> | |
cae39d13 | 11 | #include <linux/export.h> |
8c1e6b14 | 12 | #include <linux/semaphore.h> |
5b3b1688 DD |
13 | #include <linux/mtd/mtd.h> |
14 | #include <linux/mtd/map.h> | |
15 | #include <linux/mtd/partitions.h> | |
16 | ||
17 | #include <asm/octeon/octeon.h> | |
18 | ||
19 | static struct map_info flash_map; | |
20 | static struct mtd_info *mymtd; | |
5b3b1688 DD |
21 | static const char *part_probe_types[] = { |
22 | "cmdlinepart", | |
23 | #ifdef CONFIG_MTD_REDBOOT_PARTS | |
24 | "RedBoot", | |
25 | #endif | |
26 | NULL | |
27 | }; | |
5b3b1688 | 28 | |
8c1e6b14 DD |
29 | static map_word octeon_flash_map_read(struct map_info *map, unsigned long ofs) |
30 | { | |
31 | map_word r; | |
32 | ||
33 | down(&octeon_bootbus_sem); | |
34 | r = inline_map_read(map, ofs); | |
35 | up(&octeon_bootbus_sem); | |
36 | ||
37 | return r; | |
38 | } | |
39 | ||
40 | static void octeon_flash_map_write(struct map_info *map, const map_word datum, | |
41 | unsigned long ofs) | |
42 | { | |
43 | down(&octeon_bootbus_sem); | |
44 | inline_map_write(map, datum, ofs); | |
45 | up(&octeon_bootbus_sem); | |
46 | } | |
47 | ||
48 | static void octeon_flash_map_copy_from(struct map_info *map, void *to, | |
49 | unsigned long from, ssize_t len) | |
50 | { | |
51 | down(&octeon_bootbus_sem); | |
52 | inline_map_copy_from(map, to, from, len); | |
53 | up(&octeon_bootbus_sem); | |
54 | } | |
55 | ||
56 | static void octeon_flash_map_copy_to(struct map_info *map, unsigned long to, | |
57 | const void *from, ssize_t len) | |
58 | { | |
59 | down(&octeon_bootbus_sem); | |
60 | inline_map_copy_to(map, to, from, len); | |
61 | up(&octeon_bootbus_sem); | |
62 | } | |
63 | ||
5b3b1688 DD |
64 | /** |
65 | * Module/ driver initialization. | |
66 | * | |
67 | * Returns Zero on success | |
68 | */ | |
69 | static int __init flash_init(void) | |
70 | { | |
71 | /* | |
72 | * Read the bootbus region 0 setup to determine the base | |
73 | * address of the flash. | |
74 | */ | |
75 | union cvmx_mio_boot_reg_cfgx region_cfg; | |
76 | region_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(0)); | |
77 | if (region_cfg.s.en) { | |
78 | /* | |
79 | * The bootloader always takes the flash and sets its | |
80 | * address so the entire flash fits below | |
81 | * 0x1fc00000. This way the flash aliases to | |
82 | * 0x1fc00000 for booting. Software can access the | |
83 | * full flash at the true address, while core boot can | |
84 | * access 4MB. | |
85 | */ | |
86 | /* Use this name so old part lines work */ | |
87 | flash_map.name = "phys_mapped_flash"; | |
88 | flash_map.phys = region_cfg.s.base << 16; | |
89 | flash_map.size = 0x1fc00000 - flash_map.phys; | |
0f731711 CH |
90 | /* 8-bit bus (0 + 1) or 16-bit bus (1 + 1) */ |
91 | flash_map.bankwidth = region_cfg.s.width + 1; | |
5b3b1688 DD |
92 | flash_map.virt = ioremap(flash_map.phys, flash_map.size); |
93 | pr_notice("Bootbus flash: Setting flash for %luMB flash at " | |
12e22e8e | 94 | "0x%08llx\n", flash_map.size >> 20, flash_map.phys); |
8c1e6b14 DD |
95 | WARN_ON(!map_bankwidth_supported(flash_map.bankwidth)); |
96 | flash_map.read = octeon_flash_map_read; | |
97 | flash_map.write = octeon_flash_map_write; | |
98 | flash_map.copy_from = octeon_flash_map_copy_from; | |
99 | flash_map.copy_to = octeon_flash_map_copy_to; | |
5b3b1688 DD |
100 | mymtd = do_map_probe("cfi_probe", &flash_map); |
101 | if (mymtd) { | |
102 | mymtd->owner = THIS_MODULE; | |
b2f90941 | 103 | mtd_device_parse_register(mymtd, part_probe_types, |
42d7fbe2 | 104 | NULL, NULL, 0); |
5b3b1688 DD |
105 | } else { |
106 | pr_err("Failed to register MTD device for flash\n"); | |
107 | } | |
108 | } | |
109 | return 0; | |
110 | } | |
111 | ||
112 | late_initcall(flash_init); |