0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include "ops.h"
0012 #include "stdio.h"
0013 #include "cuboot.h"
0014 #include "io.h"
0015 #include "fsl-soc.h"
0016
0017 #define TARGET_CPM2
0018 #define TARGET_HAS_ETH1
0019 #include "ppcboot.h"
0020
0021 static bd_t bd;
0022
0023 struct cs_range {
0024 u32 csnum;
0025 u32 base;
0026 u32 addr;
0027 u32 size;
0028 };
0029
0030 struct pci_range {
0031 u32 flags;
0032 u32 pci_addr[2];
0033 u32 phys_addr;
0034 u32 size[2];
0035 };
0036
0037 struct cs_range cs_ranges_buf[MAX_PROP_LEN / sizeof(struct cs_range)];
0038 struct pci_range pci_ranges_buf[MAX_PROP_LEN / sizeof(struct pci_range)];
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048 static void update_cs_ranges(void)
0049 {
0050 void *bus_node, *parent_node;
0051 u32 *ctrl_addr;
0052 unsigned long ctrl_size;
0053 u32 naddr, nsize;
0054 int len;
0055 int i;
0056
0057 bus_node = finddevice("/localbus");
0058 if (!bus_node || !dt_is_compatible(bus_node, "fsl,pq2-localbus"))
0059 return;
0060
0061 dt_get_reg_format(bus_node, &naddr, &nsize);
0062 if (naddr != 2 || nsize != 1)
0063 goto err;
0064
0065 parent_node = get_parent(bus_node);
0066 if (!parent_node)
0067 goto err;
0068
0069 dt_get_reg_format(parent_node, &naddr, &nsize);
0070 if (naddr != 1 || nsize != 1)
0071 goto err;
0072
0073 if (!dt_xlate_reg(bus_node, 0, (unsigned long *)&ctrl_addr,
0074 &ctrl_size))
0075 goto err;
0076
0077 len = getprop(bus_node, "ranges", cs_ranges_buf, sizeof(cs_ranges_buf));
0078
0079 for (i = 0; i < len / sizeof(struct cs_range); i++) {
0080 u32 base, option;
0081 int cs = cs_ranges_buf[i].csnum;
0082 if (cs >= ctrl_size / 8)
0083 goto err;
0084
0085 if (cs_ranges_buf[i].base != 0)
0086 goto err;
0087
0088 base = in_be32(&ctrl_addr[cs * 2]);
0089
0090
0091
0092
0093 if (base & 1) {
0094 base &= 0x7fff;
0095 option = in_be32(&ctrl_addr[cs * 2 + 1]) & 0x7fff;
0096 } else {
0097 base = 0x1801;
0098 option = 0x10;
0099 }
0100
0101 out_be32(&ctrl_addr[cs * 2], 0);
0102 out_be32(&ctrl_addr[cs * 2 + 1],
0103 option | ~(cs_ranges_buf[i].size - 1));
0104 out_be32(&ctrl_addr[cs * 2], base | cs_ranges_buf[i].addr);
0105 }
0106
0107 return;
0108
0109 err:
0110 printf("Bad /localbus node\r\n");
0111 }
0112
0113
0114
0115
0116
0117
0118
0119
0120 static void fixup_pci(void)
0121 {
0122 struct pci_range *mem = NULL, *mmio = NULL,
0123 *io = NULL, *mem_base = NULL;
0124 u32 *pci_regs[3];
0125 u8 *soc_regs;
0126 int i, len;
0127 void *node, *parent_node;
0128 u32 naddr, nsize, mem_pow2, mem_mask;
0129
0130 node = finddevice("/pci");
0131 if (!node || !dt_is_compatible(node, "fsl,pq2-pci"))
0132 return;
0133
0134 for (i = 0; i < 3; i++)
0135 if (!dt_xlate_reg(node, i,
0136 (unsigned long *)&pci_regs[i], NULL))
0137 goto err;
0138
0139 soc_regs = (u8 *)fsl_get_immr();
0140 if (!soc_regs)
0141 goto unhandled;
0142
0143 dt_get_reg_format(node, &naddr, &nsize);
0144 if (naddr != 3 || nsize != 2)
0145 goto err;
0146
0147 parent_node = get_parent(node);
0148 if (!parent_node)
0149 goto err;
0150
0151 dt_get_reg_format(parent_node, &naddr, &nsize);
0152 if (naddr != 1 || nsize != 1)
0153 goto unhandled;
0154
0155 len = getprop(node, "ranges", pci_ranges_buf,
0156 sizeof(pci_ranges_buf));
0157
0158 for (i = 0; i < len / sizeof(struct pci_range); i++) {
0159 u32 flags = pci_ranges_buf[i].flags & 0x43000000;
0160
0161 if (flags == 0x42000000)
0162 mem = &pci_ranges_buf[i];
0163 else if (flags == 0x02000000)
0164 mmio = &pci_ranges_buf[i];
0165 else if (flags == 0x01000000)
0166 io = &pci_ranges_buf[i];
0167 }
0168
0169 if (!mem || !mmio || !io)
0170 goto unhandled;
0171 if (mem->size[1] != mmio->size[1])
0172 goto unhandled;
0173 if (mem->size[1] & (mem->size[1] - 1))
0174 goto unhandled;
0175 if (io->size[1] & (io->size[1] - 1))
0176 goto unhandled;
0177
0178 if (mem->phys_addr + mem->size[1] == mmio->phys_addr)
0179 mem_base = mem;
0180 else if (mmio->phys_addr + mmio->size[1] == mem->phys_addr)
0181 mem_base = mmio;
0182 else
0183 goto unhandled;
0184
0185 out_be32(&pci_regs[1][0], mem_base->phys_addr | 1);
0186 out_be32(&pci_regs[2][0], ~(mem->size[1] + mmio->size[1] - 1));
0187
0188 out_be32(&pci_regs[1][1], io->phys_addr | 1);
0189 out_be32(&pci_regs[2][1], ~(io->size[1] - 1));
0190
0191 out_le32(&pci_regs[0][0], mem->pci_addr[1] >> 12);
0192 out_le32(&pci_regs[0][2], mem->phys_addr >> 12);
0193 out_le32(&pci_regs[0][4], (~(mem->size[1] - 1) >> 12) | 0xa0000000);
0194
0195 out_le32(&pci_regs[0][6], mmio->pci_addr[1] >> 12);
0196 out_le32(&pci_regs[0][8], mmio->phys_addr >> 12);
0197 out_le32(&pci_regs[0][10], (~(mmio->size[1] - 1) >> 12) | 0x80000000);
0198
0199 out_le32(&pci_regs[0][12], io->pci_addr[1] >> 12);
0200 out_le32(&pci_regs[0][14], io->phys_addr >> 12);
0201 out_le32(&pci_regs[0][16], (~(io->size[1] - 1) >> 12) | 0xc0000000);
0202
0203
0204 out_le32(&pci_regs[0][58], 0);
0205 out_le32(&pci_regs[0][60], 0);
0206
0207 mem_pow2 = 1 << (__ilog2_u32(bd.bi_memsize - 1) + 1);
0208 mem_mask = ~(mem_pow2 - 1) >> 12;
0209 out_le32(&pci_regs[0][62], 0xa0000000 | mem_mask);
0210
0211
0212 if (!(in_le32(&pci_regs[0][32]) & 1)) {
0213
0214 udelay(100000);
0215
0216 out_le32(&pci_regs[0][32], 1);
0217
0218
0219 udelay(1020000);
0220 }
0221
0222
0223 out_le32(&pci_regs[0][64], 0x80000004);
0224 out_le32(&pci_regs[0][65], in_le32(&pci_regs[0][65]) | 6);
0225
0226
0227
0228
0229 out_8(&soc_regs[0x10028], 3);
0230 out_be32((u32 *)&soc_regs[0x1002c], 0x01236745);
0231
0232 return;
0233
0234 err:
0235 printf("Bad PCI node -- using existing firmware setup.\r\n");
0236 return;
0237
0238 unhandled:
0239 printf("Unsupported PCI node -- using existing firmware setup.\r\n");
0240 }
0241
0242 static void pq2_platform_fixups(void)
0243 {
0244 void *node;
0245
0246 dt_fixup_memory(bd.bi_memstart, bd.bi_memsize);
0247 dt_fixup_mac_addresses(bd.bi_enetaddr, bd.bi_enet1addr);
0248 dt_fixup_cpu_clocks(bd.bi_intfreq, bd.bi_busfreq / 4, bd.bi_busfreq);
0249
0250 node = finddevice("/soc/cpm");
0251 if (node)
0252 setprop(node, "clock-frequency", &bd.bi_cpmfreq, 4);
0253
0254 node = finddevice("/soc/cpm/brg");
0255 if (node)
0256 setprop(node, "clock-frequency", &bd.bi_brgfreq, 4);
0257
0258 update_cs_ranges();
0259 fixup_pci();
0260 }
0261
0262 void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
0263 unsigned long r6, unsigned long r7)
0264 {
0265 CUBOOT_INIT();
0266 fdt_init(_dtb_start);
0267 serial_console_init();
0268 platform_ops.fixups = pq2_platform_fixups;
0269 }