1 /*
2 * xen/arch/arm/platforms/xgene-storm.c
3 *
4 * Applied Micro's X-Gene specific settings
5 *
6 * Pranavkumar Sawargaonkar <psawargaonkar@apm.com>
7 * Anup Patel <apatel@apm.com>
8 * Copyright (c) 2013 Applied Micro.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 */
20
21 #include <asm/platform.h>
22 #include <xen/vmap.h>
23 #include <xen/device_tree.h>
24 #include <asm/io.h>
25 #include <asm/gic.h>
26
27 /* XGENE RESET Specific defines */
28 #define XGENE_RESET_ADDR 0x17000014UL
29 #define XGENE_RESET_SIZE 0x100
30 #define XGENE_RESET_MASK 0x1
31
32 /* Variables to save reset address of soc during platform initialization. */
33 static u64 reset_addr, reset_size;
34 static u32 reset_mask;
35 static bool reset_vals_valid = false;
36
37 #define XGENE_SEC_GICV2_DIST_ADDR 0x78010000
38
xgene_check_pirq_eoi(void)39 static void __init xgene_check_pirq_eoi(void)
40 {
41 const struct dt_device_node *node;
42 int res;
43 paddr_t dbase;
44 const struct dt_device_match xgene_dt_int_ctrl_match[] =
45 {
46 DT_MATCH_COMPATIBLE("arm,cortex-a15-gic"),
47 { /*sentinel*/ },
48 };
49
50 node = dt_find_interrupt_controller(xgene_dt_int_ctrl_match);
51 if ( !node )
52 panic("%s: Can not find interrupt controller node", __func__);
53
54 res = dt_device_get_address(node, 0, &dbase, NULL);
55 if ( !dbase )
56 panic("%s: Cannot find a valid address for the distributor", __func__);
57
58 /*
59 * In old X-Gene Storm firmware and DT, secure mode addresses have
60 * been mentioned in GICv2 node. EOI HW won't work in this case.
61 * We check the GIC Distributor Base Address to deny Xen booting
62 * with older firmware.
63 */
64 if ( dbase == XGENE_SEC_GICV2_DIST_ADDR )
65 panic("OLD X-Gene Firmware is not supported by Xen.\n"
66 "Please upgrade your firmware to the latest version");
67 }
68
xgene_storm_quirks(void)69 static uint32_t xgene_storm_quirks(void)
70 {
71 return PLATFORM_QUIRK_GIC_64K_STRIDE;
72 }
73
xgene_storm_reset(void)74 static void xgene_storm_reset(void)
75 {
76 void __iomem *addr;
77
78 if ( !reset_vals_valid )
79 {
80 printk("XGENE: Invalid reset values, can not reset XGENE...\n");
81 return;
82 }
83
84 addr = ioremap_nocache(reset_addr, reset_size);
85
86 if ( !addr )
87 {
88 printk("XGENE: Unable to map xgene reset address, can not reset XGENE...\n");
89 return;
90 }
91
92 /* Write reset mask to base address */
93 writel(reset_mask, addr);
94
95 iounmap(addr);
96 }
97
xgene_storm_init(void)98 static int xgene_storm_init(void)
99 {
100 /* TBD: Once Linux side device tree bindings are finalized retrieve
101 * these values from dts.
102 */
103 reset_addr = XGENE_RESET_ADDR;
104 reset_size = XGENE_RESET_SIZE;
105 reset_mask = XGENE_RESET_MASK;
106
107 reset_vals_valid = true;
108 xgene_check_pirq_eoi();
109
110 return 0;
111 }
112
113 static const char * const xgene_storm_dt_compat[] __initconst =
114 {
115 "apm,xgene-storm",
116 NULL
117 };
118
119 PLATFORM_START(xgene_storm, "APM X-GENE STORM")
120 .compatible = xgene_storm_dt_compat,
121 .init = xgene_storm_init,
122 .reset = xgene_storm_reset,
123 .quirks = xgene_storm_quirks,
124 PLATFORM_END
125
126 /*
127 * Local variables:
128 * mode: C
129 * c-file-style: "BSD"
130 * c-basic-offset: 4
131 * indent-tabs-mode: nil
132 * End:
133 */
134