2 * Copyright (C) 2012 Spreadtrum Communications Inc.
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 #include <linux/kernel.h>
14 #include <linux/init.h>
15 #include <linux/platform_device.h>
16 #include <linux/delay.h>
17 #include <linux/export.h>
18 #include <linux/irqchip/arm-gic.h>
19 #include <linux/input.h>
22 #include <asm/setup.h>
23 #include <asm/mach/time.h>
24 #include <asm/mach/arch.h>
25 #include <asm/mach/map.h>
26 #include <asm/mach-types.h>
27 #include <linux/irqchip/arm-gic.h>
28 #include <asm/hardware/cache-l2x0.h>
29 #include <asm/localtimer.h>
30 #include <linux/of_platform.h>
32 #include <linux/of_address.h>
33 #include <linux/clocksource.h>
34 #include <linux/clk-provider.h>
35 #include <soc/sprd/hardware.h>
36 #include <linux/i2c.h>
37 #if(defined(CONFIG_INPUT_LIS3DH_I2C)||defined(CONFIG_INPUT_LIS3DH_I2C_MODULE))
38 #include <linux/i2c/lis3dh.h>
40 #if(defined(CONFIG_INPUT_LTR558_I2C)||defined(CONFIG_INPUT_LTR558_I2C_MODULE))
41 #include <linux/i2c/ltr_558als.h>
43 #include <linux/spi/spi.h>
44 #include <linux/gpio.h>
45 #include <soc/sprd/board.h>
46 #include <soc/sprd/serial_sprd.h>
47 #include <soc/sprd/adi.h>
48 #include <soc/sprd/adc.h>
49 #include <soc/sprd/pinmap.h>
50 #include <linux/irq.h>
51 #include <linux/input/matrix_keypad.h>
53 #include <soc/sprd/sci.h>
54 #include <soc/sprd/hardware.h>
55 #include <soc/sprd/kpd.h>
56 #include <soc/sprd/sci_glb_regs.h>
58 #if(defined(CONFIG_INV_MPU_IIO)||defined(CONFIG_INV_MPU_IIO_MODULE))
59 #include <linux/mpu.h>
61 #if(defined(CONFIG_SENSORS_AK8975)||defined(CONFIG_SENSORS_AK8975_MODULE))
62 #include <linux/akm8975.h>
65 //#include "devices.h"
67 #include <linux/regulator/consumer.h>
68 #include <soc/sprd/regulator.h>
69 #if(defined(CONFIG_TOUCHSCREEN_FOCALTECH)||defined(CONFIG_TOUCHSCREEN_FOCALTECH_MODULE))
70 #include <linux/i2c/focaltech.h>
72 #include <soc/sprd/i2s.h>
73 #include <linux/sprd_2351.h>
75 #if(defined(CONFIG_KEYBOARD_SC)||defined(CONFIG_KEYBOARD_SC_MODULE))
76 #include <linux/input/matrix_keypad.h>
77 #include <soc/sprd/kpd.h>
79 #if(defined(CONFIG_KEYBOARD_GPIO)||defined(CONFIG_KEYBOARD_GPIO_MODULE))
80 #include <linux/gpio_keys.h>
82 #if(defined(CONFIG_KEYBOARD_SPRD_EIC)||defined(CONFIG_KEYBOARD_SPRD_EIC_MODULE))
83 #include <linux/sprd_eic_keys.h>
85 #if(defined(CONFIG_BACKLIGHT_SPRD_PWM)||defined(CONFIG_BACKLIGHT_SPRD_PWM_MODULE))
86 #include <linux/sprd_pwm_bl.h>
88 #if(defined(CONFIG_INPUT_HEADSET_SPRD_SC2723)||defined(CONFIG_INPUT_HEADSET_SPRD_SC2723_MODULE))
89 #include <linux/headset_sprd_sc2723.h>
92 extern void __init sci_reserve(void);
93 extern void __init sci_map_io(void);
94 extern void __init sci_init_irq(void);
95 extern void __init sci_timer_init(void);
96 extern int __init sci_clock_init(void);
97 extern int __init sci_regulator_init(void);
99 int __init __clock_init_early(void)
101 pr_info("ahb ctl0 %08x, ctl2 %08x glb aon apb0 %08x aon apb1 %08x clk_en %08x\n",
102 sci_glb_raw_read(REG_AP_AHB_AHB_EB),
103 sci_glb_raw_read(REG_AP_AHB_AHB_RST),
104 sci_glb_raw_read(REG_AON_APB_APB_EB0),
105 sci_glb_raw_read(REG_AON_APB_APB_EB1),
106 sci_glb_raw_read(REG_AON_CLK_PUB_AHB_CFG));
108 sci_glb_clr(REG_AP_AHB_AHB_EB,
127 sci_glb_clr(REG_AP_APB_APB_EB,
141 sci_glb_clr(REG_AON_APB_APB_RTC_EB,
147 sci_glb_clr(REG_AON_APB_APB_EB0,
153 sci_glb_clr(REG_AON_APB_APB_EB1,
158 printk("sc clock module early init ok\n");
162 static inline int __sci_get_chip_id(void)
164 return __raw_readl(CHIP_ID_LOW_REG);
166 const struct of_device_id of_sprd_default_bus_match_table[] = {
167 { .compatible = "simple-bus", },
168 { .compatible = "sprd,adi-bus", },
172 static struct of_dev_auxdata of_sprd_default_bus_lookup[] = {
173 { .compatible = "sprd,sdhci-shark", .name = "sdio_sd",},
174 { .compatible = "sprd,sdhci-shark", .name = "sdio_wifi",},
175 { .compatible = "sprd,sdhci-shark", .name = "sprd-sdhci.2",},
176 { .compatible = "sprd,sdhci-shark", .name = "sdio_emmc",},
177 { .compatible = "sprd,sprd_backlight", .name = "sprd_backlight" },
181 struct iotable_sprd io_addr_sprd;
182 EXPORT_SYMBOL(io_addr_sprd);
186 struct device_node *np;
189 #define ADD_SPRD_DEVICE(compat, id) \
191 np = of_find_compatible_node(NULL, NULL, compat);\
192 if (of_can_translate_address(np)) { \
193 of_address_to_resource(np, 0, &res); \
194 io_addr_sprd.id.paddr = res.start; \
195 io_addr_sprd.id.length = \
196 resource_size(&res); \
197 io_addr_sprd.id.vaddr = \
198 ioremap_nocache(res.start, io_addr_sprd.id.length);\
199 pr_debug("sprd io map: phys=%08x virt=%08x size=%08x\n", \
200 io_addr_sprd.id.paddr, io_addr_sprd.id.vaddr, io_addr_sprd.id.length);\
203 #define ADD_SPRD_DEVICE_BY_NAME(name, id) \
205 np = of_find_node_by_name(NULL, name); \
206 if (of_can_translate_address(np)) { \
207 of_address_to_resource(np, 0, &res); \
208 io_addr_sprd.id.paddr = res.start; \
209 io_addr_sprd.id.length = \
210 resource_size(&res); \
211 io_addr_sprd.id.vaddr = \
212 ioremap_nocache(res.start, io_addr_sprd.id.length);\
213 pr_debug("sprd io map: phys=%16lx virt=%16lx size=%16lx\n", \
214 io_addr_sprd.id.paddr, io_addr_sprd.id.vaddr, io_addr_sprd.id.length);\
217 ADD_SPRD_DEVICE("sprd,ahb", AHB);
218 ADD_SPRD_DEVICE("sprd,aonapb", AONAPB);
219 ADD_SPRD_DEVICE("sprd,aonckg", AONCKG);
220 ADD_SPRD_DEVICE("sprd,apbreg", APBREG);
221 ADD_SPRD_DEVICE("sprd,core", CORE);
222 ADD_SPRD_DEVICE("sprd,mmahb", MMAHB);
223 ADD_SPRD_DEVICE("sprd,pmu", PMU);
224 ADD_SPRD_DEVICE("sprd,mmckg", MMCKG);
225 ADD_SPRD_DEVICE("sprd,gpuapb", GPUAPB);
226 ADD_SPRD_DEVICE("sprd,apbckg", APBCKG);
227 ADD_SPRD_DEVICE("sprd,gpuckg", GPUCKG);
228 ADD_SPRD_DEVICE("sprd,int", INT);
229 ADD_SPRD_DEVICE("sprd,intc0", INTC0);
230 ADD_SPRD_DEVICE("sprd,intc1", INTC1);
231 ADD_SPRD_DEVICE("sprd,intc2", INTC2);
232 ADD_SPRD_DEVICE("sprd,intc3", INTC3);
233 ADD_SPRD_DEVICE("sprd,uidefuse", UIDEFUSE);
234 ADD_SPRD_DEVICE("sprd,isp", ISP);
235 ADD_SPRD_DEVICE("sprd,csi2", CSI2);
236 ADD_SPRD_DEVICE("sprd,d-eic-gpio", EIC);
237 ADD_SPRD_DEVICE("sprd,ipi", IPI);
238 ADD_SPRD_DEVICE("sprd,dcam", DCAM);
239 ADD_SPRD_DEVICE("sprd,syscnt", SYSCNT);
240 ADD_SPRD_DEVICE("sprd,dma0", DMA0);
241 ADD_SPRD_DEVICE("sprd,pub", PUB);
242 ADD_SPRD_DEVICE("sprd,pin", PIN);
243 ADD_SPRD_DEVICE("sprd,d-gpio-gpio", GPIO);
244 ADD_SPRD_DEVICE_BY_NAME("hwspinlock0", HWSPINLOCK0);
245 ADD_SPRD_DEVICE_BY_NAME("hwspinlock1", HWSPINLOCK1);
250 static void __init sc8830_init_machine(void)
252 printk("sci get chip id = 0x%x\n",__sci_get_chip_id());
254 //sci_adc_init((void __iomem *)ADC_BASE);
256 sci_regulator_init();
257 of_sprd_default_bus_lookup[0].phys_addr = 0x20300000;
258 of_sprd_default_bus_lookup[1].phys_addr = 0x20400000;
259 of_sprd_default_bus_lookup[2].phys_addr = 0x20500000;
260 of_sprd_default_bus_lookup[3].phys_addr = 0x20600000;
261 of_platform_populate(NULL, of_sprd_default_bus_match_table, of_sprd_default_bus_lookup, NULL);
262 sprd_sr2351_vddwpa_ctrl_power_register();
265 const struct of_device_id of_sprd_late_bus_match_table[] = {
266 { .compatible = "sprd,sound", },
270 static void __init sc8830_init_late(void)
272 of_platform_populate(of_find_node_by_path("/sprd-audio-devices"),
273 of_sprd_late_bus_match_table, NULL, NULL);
276 extern void __init sci_enable_timer_early(void);
277 extern void __init sc_init_chip_id(void);
279 void __init sprd_init_before_irq(void)
283 /* earlier init request than irq and timer */
284 __clock_init_early();
285 /*ipi reg init for sipc*/
286 sci_glb_set(REG_AON_APB_APB_EB0, BIT_IPI_EB);
288 static void __init sc8830_pmu_init(void)
290 __raw_writel(__raw_readl(REG_PMU_APB_PD_MM_TOP_CFG)
291 & ~(BIT_PD_MM_TOP_FORCE_SHUTDOWN),
292 REG_PMU_APB_PD_MM_TOP_CFG);
294 __raw_writel(__raw_readl(REG_PMU_APB_PD_GPU_TOP_CFG)
295 & ~(BIT_PD_GPU_TOP_FORCE_SHUTDOWN),
296 REG_PMU_APB_PD_GPU_TOP_CFG);
298 __raw_writel(__raw_readl(REG_AON_APB_APB_EB0) | BIT_MM_EB |
299 BIT_GPU_EB, REG_AON_APB_APB_EB0);
301 __raw_writel(__raw_readl(REG_MM_AHB_AHB_EB) | BIT_MM_CKG_EB,
303 __raw_writel(__raw_readl(REG_MM_AHB_GEN_CKG_CFG)
304 | BIT_MM_MTX_AXI_CKG_EN | BIT_MM_AXI_CKG_EN,
305 REG_MM_AHB_GEN_CKG_CFG);
306 __raw_writel(__raw_readl(REG_MM_CLK_MM_AHB_CFG) | 0x3,
307 REG_MM_CLK_MM_AHB_CFG);
310 static void sprd_init_time(void)
312 if(of_have_populated_dt()){
315 clocksource_of_init();
318 sci_enable_timer_early();
322 static const char *sprd_boards_compat[] __initdata = {
326 extern struct smp_operations sprd_smp_ops;
328 MACHINE_START(SCPHONE, "sc8830")
329 .smp = smp_ops(sprd_smp_ops),
330 .reserve = sci_reserve,
331 .map_io = sci_map_io,
332 .init_irq = sci_init_irq,
333 .init_time = sprd_init_time,
334 .init_machine = sc8830_init_machine,
335 .init_late = sc8830_init_late,
336 .dt_compat = sprd_boards_compat,