0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/init.h>
0009 #include <linux/of_fdt.h>
0010 #include <linux/libfdt.h>
0011 #include <linux/smp.h>
0012 #include <asm/arcregs.h>
0013 #include <asm/io.h>
0014 #include <asm/mach_desc.h>
0015
0016 int arc_hsdk_axi_dmac_coherent __section(".data") = 0;
0017
0018 #define ARC_CCM_UNUSED_ADDR 0x60000000
0019
0020
0021 #define ARC_PERIPHERAL_BASE 0xf0000000
0022 #define CREG_BASE (ARC_PERIPHERAL_BASE + 0x1000)
0023
0024 #define SDIO_BASE (ARC_PERIPHERAL_BASE + 0xA000)
0025 #define SDIO_UHS_REG_EXT (SDIO_BASE + 0x108)
0026 #define SDIO_UHS_REG_EXT_DIV_2 (2 << 30)
0027
0028 #define HSDK_GPIO_INTC (ARC_PERIPHERAL_BASE + 0x3000)
0029
0030 static void __init hsdk_enable_gpio_intc_wire(void)
0031 {
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075 #define GPIO_INTEN (HSDK_GPIO_INTC + 0x30)
0076 #define GPIO_INTMASK (HSDK_GPIO_INTC + 0x34)
0077 #define GPIO_INTTYPE_LEVEL (HSDK_GPIO_INTC + 0x38)
0078 #define GPIO_INT_POLARITY (HSDK_GPIO_INTC + 0x3c)
0079 #define GPIO_INT_CONNECTED_MASK 0x0d
0080
0081 iowrite32(0xffffffff, (void __iomem *) GPIO_INTMASK);
0082 iowrite32(~GPIO_INT_CONNECTED_MASK, (void __iomem *) GPIO_INTMASK);
0083 iowrite32(0x00000000, (void __iomem *) GPIO_INTTYPE_LEVEL);
0084 iowrite32(0xffffffff, (void __iomem *) GPIO_INT_POLARITY);
0085 iowrite32(GPIO_INT_CONNECTED_MASK, (void __iomem *) GPIO_INTEN);
0086 }
0087
0088 static int __init hsdk_tweak_node_coherency(const char *path, bool coherent)
0089 {
0090 void *fdt = initial_boot_params;
0091 const void *prop;
0092 int node, ret;
0093 bool dt_coh_set;
0094
0095 node = fdt_path_offset(fdt, path);
0096 if (node < 0)
0097 goto tweak_fail;
0098
0099 prop = fdt_getprop(fdt, node, "dma-coherent", &ret);
0100 if (!prop && ret != -FDT_ERR_NOTFOUND)
0101 goto tweak_fail;
0102
0103 dt_coh_set = ret != -FDT_ERR_NOTFOUND;
0104 ret = 0;
0105
0106
0107 if (dt_coh_set && !coherent)
0108 ret = fdt_delprop(fdt, node, "dma-coherent");
0109
0110
0111 if (!dt_coh_set && coherent)
0112 ret = fdt_setprop(fdt, node, "dma-coherent", NULL, 0);
0113
0114 if (ret < 0)
0115 goto tweak_fail;
0116
0117 return 0;
0118
0119 tweak_fail:
0120 pr_err("failed to tweak %s to %scoherent\n", path, coherent ? "" : "non");
0121 return -EFAULT;
0122 }
0123
0124 enum hsdk_axi_masters {
0125 M_HS_CORE = 0,
0126 M_HS_RTT,
0127 M_AXI_TUN,
0128 M_HDMI_VIDEO,
0129 M_HDMI_AUDIO,
0130 M_USB_HOST,
0131 M_ETHERNET,
0132 M_SDIO,
0133 M_GPU,
0134 M_DMAC_0,
0135 M_DMAC_1,
0136 M_DVFS
0137 };
0138
0139 #define UPDATE_VAL 1
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178 #define CREG_AXI_M_SLV0(m) ((void __iomem *)(CREG_BASE + 0x20 * (m)))
0179 #define CREG_AXI_M_SLV1(m) ((void __iomem *)(CREG_BASE + 0x20 * (m) + 0x04))
0180 #define CREG_AXI_M_OFT0(m) ((void __iomem *)(CREG_BASE + 0x20 * (m) + 0x08))
0181 #define CREG_AXI_M_OFT1(m) ((void __iomem *)(CREG_BASE + 0x20 * (m) + 0x0C))
0182 #define CREG_AXI_M_UPDT(m) ((void __iomem *)(CREG_BASE + 0x20 * (m) + 0x14))
0183
0184 #define CREG_AXI_M_HS_CORE_BOOT ((void __iomem *)(CREG_BASE + 0x010))
0185
0186 #define CREG_PAE ((void __iomem *)(CREG_BASE + 0x180))
0187 #define CREG_PAE_UPDT ((void __iomem *)(CREG_BASE + 0x194))
0188
0189 static void __init hsdk_init_memory_bridge_axi_dmac(void)
0190 {
0191 bool coherent = !!arc_hsdk_axi_dmac_coherent;
0192 u32 axi_m_slv1, axi_m_oft1;
0193
0194
0195
0196
0197
0198 if (hsdk_tweak_node_coherency("/soc/dmac@80000", coherent))
0199 return;
0200
0201 if (coherent) {
0202 axi_m_slv1 = 0x77999999;
0203 axi_m_oft1 = 0x76DCBA98;
0204 } else {
0205 axi_m_slv1 = 0x77777777;
0206 axi_m_oft1 = 0x76543210;
0207 }
0208
0209 writel(0x77777777, CREG_AXI_M_SLV0(M_DMAC_0));
0210 writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_DMAC_0));
0211 writel(axi_m_slv1, CREG_AXI_M_SLV1(M_DMAC_0));
0212 writel(axi_m_oft1, CREG_AXI_M_OFT1(M_DMAC_0));
0213 writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_DMAC_0));
0214
0215 writel(0x77777777, CREG_AXI_M_SLV0(M_DMAC_1));
0216 writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_DMAC_1));
0217 writel(axi_m_slv1, CREG_AXI_M_SLV1(M_DMAC_1));
0218 writel(axi_m_oft1, CREG_AXI_M_OFT1(M_DMAC_1));
0219 writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_DMAC_1));
0220 }
0221
0222 static void __init hsdk_init_memory_bridge(void)
0223 {
0224 u32 reg;
0225
0226
0227
0228
0229
0230
0231 reg = readl(CREG_AXI_M_HS_CORE_BOOT) & (~0x3);
0232 writel(reg, CREG_AXI_M_HS_CORE_BOOT);
0233 writel(0x11111111, CREG_AXI_M_SLV0(M_HS_CORE));
0234 writel(0x63111111, CREG_AXI_M_SLV1(M_HS_CORE));
0235 writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_HS_CORE));
0236 writel(0x0E543210, CREG_AXI_M_OFT1(M_HS_CORE));
0237 writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_HS_CORE));
0238
0239 writel(0x77777777, CREG_AXI_M_SLV0(M_HS_RTT));
0240 writel(0x77777777, CREG_AXI_M_SLV1(M_HS_RTT));
0241 writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_HS_RTT));
0242 writel(0x76543210, CREG_AXI_M_OFT1(M_HS_RTT));
0243 writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_HS_RTT));
0244
0245 writel(0x88888888, CREG_AXI_M_SLV0(M_AXI_TUN));
0246 writel(0x88888888, CREG_AXI_M_SLV1(M_AXI_TUN));
0247 writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_AXI_TUN));
0248 writel(0x76543210, CREG_AXI_M_OFT1(M_AXI_TUN));
0249 writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_AXI_TUN));
0250
0251 writel(0x77777777, CREG_AXI_M_SLV0(M_HDMI_VIDEO));
0252 writel(0x77777777, CREG_AXI_M_SLV1(M_HDMI_VIDEO));
0253 writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_HDMI_VIDEO));
0254 writel(0x76543210, CREG_AXI_M_OFT1(M_HDMI_VIDEO));
0255 writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_HDMI_VIDEO));
0256
0257 writel(0x77777777, CREG_AXI_M_SLV0(M_HDMI_AUDIO));
0258 writel(0x77777777, CREG_AXI_M_SLV1(M_HDMI_AUDIO));
0259 writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_HDMI_AUDIO));
0260 writel(0x76543210, CREG_AXI_M_OFT1(M_HDMI_AUDIO));
0261 writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_HDMI_AUDIO));
0262
0263 writel(0x77777777, CREG_AXI_M_SLV0(M_USB_HOST));
0264 writel(0x77999999, CREG_AXI_M_SLV1(M_USB_HOST));
0265 writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_USB_HOST));
0266 writel(0x76DCBA98, CREG_AXI_M_OFT1(M_USB_HOST));
0267 writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_USB_HOST));
0268
0269 writel(0x77777777, CREG_AXI_M_SLV0(M_ETHERNET));
0270 writel(0x77999999, CREG_AXI_M_SLV1(M_ETHERNET));
0271 writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_ETHERNET));
0272 writel(0x76DCBA98, CREG_AXI_M_OFT1(M_ETHERNET));
0273 writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_ETHERNET));
0274
0275 writel(0x77777777, CREG_AXI_M_SLV0(M_SDIO));
0276 writel(0x77999999, CREG_AXI_M_SLV1(M_SDIO));
0277 writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_SDIO));
0278 writel(0x76DCBA98, CREG_AXI_M_OFT1(M_SDIO));
0279 writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_SDIO));
0280
0281 writel(0x77777777, CREG_AXI_M_SLV0(M_GPU));
0282 writel(0x77777777, CREG_AXI_M_SLV1(M_GPU));
0283 writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_GPU));
0284 writel(0x76543210, CREG_AXI_M_OFT1(M_GPU));
0285 writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_GPU));
0286
0287 writel(0x00000000, CREG_AXI_M_SLV0(M_DVFS));
0288 writel(0x60000000, CREG_AXI_M_SLV1(M_DVFS));
0289 writel(0x00000000, CREG_AXI_M_OFT0(M_DVFS));
0290 writel(0x00000000, CREG_AXI_M_OFT1(M_DVFS));
0291 writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_DVFS));
0292
0293 hsdk_init_memory_bridge_axi_dmac();
0294
0295
0296
0297
0298
0299
0300
0301 writel(0x00000000, CREG_PAE);
0302 writel(UPDATE_VAL, CREG_PAE_UPDT);
0303 }
0304
0305 static void __init hsdk_init_early(void)
0306 {
0307 hsdk_init_memory_bridge();
0308
0309
0310
0311
0312
0313 iowrite32(SDIO_UHS_REG_EXT_DIV_2, (void __iomem *) SDIO_UHS_REG_EXT);
0314
0315 hsdk_enable_gpio_intc_wire();
0316 }
0317
0318 static const char *hsdk_compat[] __initconst = {
0319 "snps,hsdk",
0320 NULL,
0321 };
0322
0323 MACHINE_START(SIMULATION, "hsdk")
0324 .dt_compat = hsdk_compat,
0325 .init_early = hsdk_init_early,
0326 MACHINE_END