]>
Commit | Line | Data |
---|---|---|
aa44ef4d SK |
1 | /* |
2 | * Copyright (C) 2008-2009 ST-Ericsson | |
3 | * | |
4 | * Author: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com> | |
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 | */ | |
11 | #include <linux/types.h> | |
12 | #include <linux/init.h> | |
13 | #include <linux/device.h> | |
14 | #include <linux/amba/bus.h> | |
15 | #include <linux/irq.h> | |
94bdc0e2 | 16 | #include <linux/gpio.h> |
aa44ef4d | 17 | #include <linux/platform_device.h> |
cc2c1334 | 18 | #include <linux/io.h> |
aa44ef4d | 19 | |
aa44ef4d SK |
20 | #include <asm/mach/map.h> |
21 | #include <mach/hardware.h> | |
cc2c1334 | 22 | #include <mach/setup.h> |
5b1f7ddf | 23 | #include <mach/devices.h> |
94bdc0e2 | 24 | |
fbf1eadf RV |
25 | #include "devices-db8500.h" |
26 | ||
aa44ef4d | 27 | static struct platform_device *platform_devs[] __initdata = { |
94bdc0e2 RV |
28 | &u8500_gpio_devs[0], |
29 | &u8500_gpio_devs[1], | |
30 | &u8500_gpio_devs[2], | |
31 | &u8500_gpio_devs[3], | |
32 | &u8500_gpio_devs[4], | |
33 | &u8500_gpio_devs[5], | |
34 | &u8500_gpio_devs[6], | |
35 | &u8500_gpio_devs[7], | |
36 | &u8500_gpio_devs[8], | |
7b8ddb06 | 37 | &u8500_dma40_device, |
aa44ef4d SK |
38 | }; |
39 | ||
aa44ef4d SK |
40 | /* minimum static i/o mapping required to boot U8500 platforms */ |
41 | static struct map_desc u8500_io_desc[] __initdata = { | |
1df20afc | 42 | __IO_DEV_DESC(U8500_PRCMU_BASE, SZ_4K), |
f946738c | 43 | __IO_DEV_DESC(U8500_PRCMU_TCDM_BASE, SZ_4K), |
c9c09572 | 44 | __IO_DEV_DESC(U8500_GPIO0_BASE, SZ_4K), |
94bdc0e2 RV |
45 | __IO_DEV_DESC(U8500_GPIO1_BASE, SZ_4K), |
46 | __IO_DEV_DESC(U8500_GPIO2_BASE, SZ_4K), | |
47 | __IO_DEV_DESC(U8500_GPIO3_BASE, SZ_4K), | |
f946738c | 48 | __MEM_DEV_DESC(U8500_BOOT_ROM_BASE, SZ_1M), |
aa44ef4d SK |
49 | }; |
50 | ||
75a36ee0 RV |
51 | static struct map_desc u8500ed_io_desc[] __initdata = { |
52 | __IO_DEV_DESC(U8500_MTU0_BASE_ED, SZ_4K), | |
1df20afc | 53 | __IO_DEV_DESC(U8500_CLKRST7_BASE_ED, SZ_8K), |
75a36ee0 RV |
54 | }; |
55 | ||
56 | static struct map_desc u8500v1_io_desc[] __initdata = { | |
c9c09572 | 57 | __IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K), |
75a36ee0 RV |
58 | }; |
59 | ||
f946738c LW |
60 | /* |
61 | * Functions to differentiate between later ASICs | |
62 | * We look into the end of the ROM to locate the hardcoded ASIC ID. | |
63 | * This is only needed to differentiate between minor revisions and | |
64 | * process variants of an ASIC, the major revisions are encoded in | |
65 | * the cpuid. | |
66 | */ | |
67 | #define U8500_ASIC_ID_LOC_ED_V1 (U8500_BOOT_ROM_BASE + 0x1FFF4) | |
68 | #define U8500_ASIC_ID_LOC_V2 (U8500_BOOT_ROM_BASE + 0x1DBF4) | |
69 | #define U8500_ASIC_REV_ED 0x01 | |
70 | #define U8500_ASIC_REV_V10 0xA0 | |
71 | #define U8500_ASIC_REV_V11 0xA1 | |
72 | #define U8500_ASIC_REV_V20 0xB0 | |
73 | ||
74 | /** | |
75 | * struct db8500_asic_id - fields of the ASIC ID | |
76 | * @process: the manufacturing process, 0x40 is 40 nm | |
77 | * 0x00 is "standard" | |
78 | * @partnumber: hithereto 0x8500 for DB8500 | |
79 | * @revision: version code in the series | |
80 | * This field definion is not formally defined but makes | |
81 | * sense. | |
82 | */ | |
83 | struct db8500_asic_id { | |
84 | u8 process; | |
85 | u16 partnumber; | |
86 | u8 revision; | |
87 | }; | |
88 | ||
89 | /* This isn't going to change at runtime */ | |
90 | static struct db8500_asic_id db8500_id; | |
91 | ||
92 | static void __init get_db8500_asic_id(void) | |
93 | { | |
94 | u32 asicid; | |
95 | ||
96 | if (cpu_is_u8500v1() || cpu_is_u8500ed()) | |
97 | asicid = readl(__io_address(U8500_ASIC_ID_LOC_ED_V1)); | |
98 | else if (cpu_is_u8500v2()) | |
99 | asicid = readl(__io_address(U8500_ASIC_ID_LOC_V2)); | |
100 | else | |
101 | BUG(); | |
102 | ||
103 | db8500_id.process = (asicid >> 24); | |
104 | db8500_id.partnumber = (asicid >> 16) & 0xFFFFU; | |
105 | db8500_id.revision = asicid & 0xFFU; | |
106 | } | |
107 | ||
108 | bool cpu_is_u8500v10(void) | |
109 | { | |
110 | return (db8500_id.revision == U8500_ASIC_REV_V10); | |
111 | } | |
112 | ||
113 | bool cpu_is_u8500v11(void) | |
114 | { | |
115 | return (db8500_id.revision == U8500_ASIC_REV_V11); | |
116 | } | |
117 | ||
118 | bool cpu_is_u8500v20(void) | |
119 | { | |
120 | return (db8500_id.revision == U8500_ASIC_REV_V20); | |
121 | } | |
122 | ||
aa44ef4d SK |
123 | void __init u8500_map_io(void) |
124 | { | |
178980f9 RV |
125 | ux500_map_io(); |
126 | ||
aa44ef4d | 127 | iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc)); |
75a36ee0 RV |
128 | |
129 | if (cpu_is_u8500ed()) | |
130 | iotable_init(u8500ed_io_desc, ARRAY_SIZE(u8500ed_io_desc)); | |
131 | else | |
132 | iotable_init(u8500v1_io_desc, ARRAY_SIZE(u8500v1_io_desc)); | |
f946738c LW |
133 | |
134 | /* Read out the ASIC ID as early as we can */ | |
135 | get_db8500_asic_id(); | |
aa44ef4d SK |
136 | } |
137 | ||
aa44ef4d SK |
138 | /* |
139 | * This function is called from the board init | |
140 | */ | |
141 | void __init u8500_init_devices(void) | |
142 | { | |
f946738c LW |
143 | /* Display some ASIC boilerplate */ |
144 | pr_info("DB8500: process: %02x, revision ID: 0x%02x\n", | |
145 | db8500_id.process, db8500_id.revision); | |
146 | if (cpu_is_u8500ed()) | |
147 | pr_info("DB8500: Early Drop (ED)\n"); | |
148 | else if (cpu_is_u8500v10()) | |
149 | pr_info("DB8500: version 1.0\n"); | |
150 | else if (cpu_is_u8500v11()) | |
151 | pr_info("DB8500: version 1.1\n"); | |
152 | else if (cpu_is_u8500v20()) | |
153 | pr_info("DB8500: version 2.0\n"); | |
154 | else | |
155 | pr_warning("ASIC: UNKNOWN SILICON VERSION!\n"); | |
156 | ||
7b8ddb06 LW |
157 | if (cpu_is_u8500ed()) |
158 | dma40_u8500ed_fixup(); | |
159 | ||
fbf1eadf RV |
160 | db8500_add_rtc(); |
161 | ||
aa44ef4d SK |
162 | platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); |
163 | ||
164 | return ; | |
165 | } |