+
+#if defined(CONFIG_MPC83XX) || defined(CONFIG_MPC85xx)
+/*
+ * update crypto node properties to a specified revision of the SEC
+ * called with sec_rev == 0 if not on an mpc8xxxE processor
+ */
+void fdt_fixup_crypto_node(void *blob, int sec_rev)
+{
+ const struct sec_rev_prop {
+ u32 sec_rev;
+ u32 num_channels;
+ u32 channel_fifo_len;
+ u32 exec_units_mask;
+ u32 descriptor_types_mask;
+ } sec_rev_prop_list [] = {
+ { 0x0200, 4, 24, 0x07e, 0x01010ebf }, /* SEC 2.0 */
+ { 0x0201, 4, 24, 0x0fe, 0x012b0ebf }, /* SEC 2.1 */
+ { 0x0202, 1, 24, 0x04c, 0x0122003f }, /* SEC 2.2 */
+ { 0x0204, 4, 24, 0x07e, 0x012b0ebf }, /* SEC 2.4 */
+ { 0x0300, 4, 24, 0x9fe, 0x03ab0ebf }, /* SEC 3.0 */
+ { 0x0303, 4, 24, 0x97c, 0x03ab0abf }, /* SEC 3.3 */
+ };
+ char compat_strlist[ARRAY_SIZE(sec_rev_prop_list) *
+ sizeof("fsl,secX.Y")];
+ int crypto_node, sec_idx, err;
+ char *p;
+ u32 val;
+
+ /* locate crypto node based on lowest common compatible */
+ crypto_node = fdt_node_offset_by_compatible(blob, -1, "fsl,sec2.0");
+ if (crypto_node == -FDT_ERR_NOTFOUND)
+ return;
+
+ /* delete it if not on an E-processor */
+ if (crypto_node > 0 && !sec_rev) {
+ fdt_del_node(blob, crypto_node);
+ return;
+ }
+
+ /* else we got called for possible uprev */
+ for (sec_idx = 0; sec_idx < ARRAY_SIZE(sec_rev_prop_list); sec_idx++)
+ if (sec_rev_prop_list[sec_idx].sec_rev == sec_rev)
+ break;
+
+ if (sec_idx == ARRAY_SIZE(sec_rev_prop_list)) {
+ puts("warning: unknown SEC revision number\n");
+ return;
+ }
+
+ val = cpu_to_fdt32(sec_rev_prop_list[sec_idx].num_channels);
+ err = fdt_setprop(blob, crypto_node, "fsl,num-channels", &val, 4);
+ if (err < 0)
+ printf("WARNING: could not set crypto property: %s\n",
+ fdt_strerror(err));
+
+ val = cpu_to_fdt32(sec_rev_prop_list[sec_idx].descriptor_types_mask);
+ err = fdt_setprop(blob, crypto_node, "fsl,descriptor-types-mask", &val, 4);
+ if (err < 0)
+ printf("WARNING: could not set crypto property: %s\n",
+ fdt_strerror(err));
+
+ val = cpu_to_fdt32(sec_rev_prop_list[sec_idx].exec_units_mask);
+ err = fdt_setprop(blob, crypto_node, "fsl,exec-units-mask", &val, 4);
+ if (err < 0)
+ printf("WARNING: could not set crypto property: %s\n",
+ fdt_strerror(err));
+
+ val = cpu_to_fdt32(sec_rev_prop_list[sec_idx].channel_fifo_len);
+ err = fdt_setprop(blob, crypto_node, "fsl,channel-fifo-len", &val, 4);
+ if (err < 0)
+ printf("WARNING: could not set crypto property: %s\n",
+ fdt_strerror(err));
+
+ val = 0;
+ while (sec_idx >= 0) {
+ p = compat_strlist + val;
+ val += sprintf(p, "fsl,sec%d.%d",
+ (sec_rev_prop_list[sec_idx].sec_rev & 0xff00) >> 8,
+ sec_rev_prop_list[sec_idx].sec_rev & 0x00ff) + 1;
+ sec_idx--;
+ }
+ err = fdt_setprop(blob, crypto_node, "compatible", &compat_strlist, val);
+ if (err < 0)
+ printf("WARNING: could not set crypto property: %s\n",
+ fdt_strerror(err));
+}
+#endif /* defined(CONFIG_MPC83XX) || defined(CONFIG_MPC85xx) */
+
+/* Resize the fdt to its actual size + a bit of padding */
+int fdt_resize(void *blob)
+{
+ int i;
+ uint64_t addr, size;
+ int total, ret;
+ uint actualsize;
+
+ if (!blob)
+ return 0;
+
+ total = fdt_num_mem_rsv(blob);
+ for (i = 0; i < total; i++) {
+ fdt_get_mem_rsv(blob, i, &addr, &size);
+ if (addr == (uint64_t)(u32)blob) {
+ fdt_del_mem_rsv(blob, i);
+ break;
+ }
+ }
+
+ /*
+ * Calculate the actual size of the fdt
+ * plus the size needed for fdt_add_mem_rsv
+ */
+ actualsize = fdt_off_dt_strings(blob) +
+ fdt_size_dt_strings(blob) + sizeof(struct fdt_reserve_entry);
+
+ /* Make it so the fdt ends on a page boundary */
+ actualsize = ALIGN(actualsize + ((uint)blob & 0xfff), 0x1000);
+ actualsize = actualsize - ((uint)blob & 0xfff);
+
+ /* Change the fdt header to reflect the correct size */
+ fdt_set_totalsize(blob, actualsize);
+
+ /* Add the new reservation */
+ ret = fdt_add_mem_rsv(blob, (uint)blob, actualsize);
+ if (ret < 0)
+ return ret;
+
+ return actualsize;
+}
+
+#ifdef CONFIG_PCI
+#define CONFIG_SYS_PCI_NR_INBOUND_WIN 3
+
+#define FDT_PCI_PREFETCH (0x40000000)
+#define FDT_PCI_MEM32 (0x02000000)
+#define FDT_PCI_IO (0x01000000)
+#define FDT_PCI_MEM64 (0x03000000)
+
+int fdt_pci_dma_ranges(void *blob, int phb_off, struct pci_controller *hose) {
+
+ int addrcell, sizecell, len, r;
+ u32 *dma_range;
+ /* sized based on pci addr cells, size-cells, & address-cells */
+ u32 dma_ranges[(3 + 2 + 2) * CONFIG_SYS_PCI_NR_INBOUND_WIN];
+
+ addrcell = fdt_getprop_u32_default(blob, "/", "#address-cells", 1);
+ sizecell = fdt_getprop_u32_default(blob, "/", "#size-cells", 1);
+
+ dma_range = &dma_ranges[0];
+ for (r = 0; r < hose->region_count; r++) {
+ u64 bus_start, phys_start, size;
+
+ /* skip if !PCI_REGION_SYS_MEMORY */
+ if (!(hose->regions[r].flags & PCI_REGION_SYS_MEMORY))
+ continue;
+
+ bus_start = (u64)hose->regions[r].bus_start;
+ phys_start = (u64)hose->regions[r].phys_start;
+ size = (u64)hose->regions[r].size;
+
+ dma_range[0] = 0;
+ if (size > 0x100000000ull)
+ dma_range[0] |= FDT_PCI_MEM64;
+ else
+ dma_range[0] |= FDT_PCI_MEM32;
+ if (hose->regions[r].flags & PCI_REGION_PREFETCH)
+ dma_range[0] |= FDT_PCI_PREFETCH;
+#ifdef CONFIG_SYS_PCI_64BIT
+ dma_range[1] = bus_start >> 32;
+#else
+ dma_range[1] = 0;
+#endif
+ dma_range[2] = bus_start & 0xffffffff;
+
+ if (addrcell == 2) {
+ dma_range[3] = phys_start >> 32;
+ dma_range[4] = phys_start & 0xffffffff;
+ } else {
+ dma_range[3] = phys_start & 0xffffffff;
+ }
+
+ if (sizecell == 2) {
+ dma_range[3 + addrcell + 0] = size >> 32;
+ dma_range[3 + addrcell + 1] = size & 0xffffffff;
+ } else {
+ dma_range[3 + addrcell + 0] = size & 0xffffffff;
+ }
+
+ dma_range += (3 + addrcell + sizecell);
+ }
+
+ len = dma_range - &dma_ranges[0];
+ if (len)
+ fdt_setprop(blob, phb_off, "dma-ranges", &dma_ranges[0], len*4);
+
+ return 0;
+}
+#endif