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