static int __init exynos5_smp_init(void) { struct dt_device_node *node; void __iomem *sysram; char *compatible; u64 sysram_addr; u64 size; u64 sysram_offset; int rc; node = dt_find_compatible_node(NULL, NULL, "samsung,secure-firmware"); if ( node ) { /* Have to use sysram_ns_base_addr + 0x1c for boot address */ compatible = "samsung,exynos4210-sysram-ns"; sysram_offset = 0x1c; secure_firmware = 1; printk("Running under secure firmware.\n"); } else { /* Have to use sysram_base_addr + offset 0 for boot address */ compatible = "samsung,exynos4210-sysram"; sysram_offset = 0; } node = dt_find_compatible_node(NULL, NULL, compatible); if ( !node ) { dprintk(XENLOG_ERR, "%s missing in DT\n", compatible); return -ENXIO; } rc = dt_device_get_address(node, 0, &sysram_addr, &size); if ( rc ) { dprintk(XENLOG_ERR, "Error in %s\n", compatible); return -ENXIO; } dprintk(XENLOG_INFO, "sysram_addr: %016llx size: %016llx offset: %016llx\n", sysram_addr, size, sysram_offset); sysram = ioremap_nocache(sysram_addr, size); if ( !sysram ) { dprintk(XENLOG_ERR, "Unable to map exynos5 MMIO\n"); return -EFAULT; } printk("Set SYSRAM to %"PRIpaddr" (%p)\n", __pa(init_secondary), init_secondary); writel(__pa(init_secondary), sysram + sysram_offset); iounmap(sysram); return 0; }
static __init int brcm_get_dt_node(char *compat_str, const struct dt_device_node **dn, u32 *reg_base) { const struct dt_device_node *node; u64 reg_base_64; int rc; node = dt_find_compatible_node(NULL, NULL, compat_str); if ( !node ) { dprintk(XENLOG_ERR, "%s: missing \"%s\" node\n", __func__, compat_str); return -ENOENT; } rc = dt_device_get_address(node, 0, ®_base_64, NULL); if ( rc ) { dprintk(XENLOG_ERR, "%s: missing \"reg\" prop\n", __func__); return rc; } if ( dn ) *dn = node; if ( reg_base ) *reg_base = reg_base_64; return 0; }
int __init psci_init_0_1(void) { int ret; const struct dt_device_node *psci; psci = dt_find_compatible_node(NULL, NULL, "arm,psci"); if ( !psci ) return -EOPNOTSUPP; ret = psci_is_smc_method(psci); if ( ret ) return -EINVAL; if ( !dt_property_read_u32(psci, "cpu_on", &psci_cpu_on_nr) ) { printk("/psci node is missing the \"cpu_on\" property\n"); return -ENOENT; } psci_ver = PSCI_VERSION(0, 1); printk(XENLOG_INFO "Using PSCI-0.1 for SMP bringup\n"); return 0; }
void p8_sbe_init_timer(void) { struct dt_node *np; int64_t rc; uint32_t tick_us; np = dt_find_compatible_node(dt_root, NULL, "ibm,power8-sbe-timer"); if (!np) return; sbe_timer_chip = dt_get_chip_id(np); tick_us = dt_prop_get_u32(np, "tick-time-us"); sbe_timer_inc = usecs_to_tb(tick_us); sbe_timer_target = ~0ull; rc = xscom_read(sbe_timer_chip, 0xE0006, &sbe_last_gen); if (rc) { prerror("SLW: Error %lld reading tmr gen count\n", rc); return; } sbe_last_gen_stamp = mftb(); prlog(PR_INFO, "SLW: Timer facility on chip %d, resolution %dus\n", sbe_timer_chip, tick_us); sbe_has_timer = true; }
/* * Xen does not currently support mapping MMIO regions and interrupt * for bus child devices (referenced via the "ranges" and * "interrupt-map" properties to domain 0). Instead for now map the * necessary resources manually. */ static int xgene_storm_specific_mapping(struct domain *d) { struct dt_device_node *node = NULL; int ret; while ( (node = dt_find_compatible_node(node, "pci", "apm,xgene-pcie")) ) { u64 addr; /* Identify the bus via it's control register address */ ret = dt_device_get_address(node, 0, &addr, NULL); if ( ret < 0 ) return ret; if ( !dt_device_is_available(node) ) continue; switch ( addr ) { case 0x1f2b0000: /* PCIe0 */ ret = xgene_storm_pcie_specific_mapping(d, node, 0x0e000000000UL, 0x10000000000UL, 0xc2); break; case 0x1f2c0000: /* PCIe1 */ ret = xgene_storm_pcie_specific_mapping(d, node, 0x0d000000000UL, 0x0e000000000UL, 0xc8); break; case 0x1f2d0000: /* PCIe2 */ ret = xgene_storm_pcie_specific_mapping(d, node, 0x09000000000UL, 0x0a000000000UL, 0xce); break; case 0x1f500000: /* PCIe3 */ ret = xgene_storm_pcie_specific_mapping(d, node, 0x0a000000000UL, 0x0c000000000UL, 0xd4); break; case 0x1f510000: /* PCIe4 */ ret = xgene_storm_pcie_specific_mapping(d, node, 0x0c000000000UL, 0x0d000000000UL, 0xda); break; default: printk("Ignoring unknown PCI bus %s\n", dt_node_full_name(node)); continue; } if ( ret < 0 ) return ret; } return 0; }
static int exynos5_init_time(void) { uint32_t reg; void __iomem *mct; int rc; struct dt_device_node *node; u64 mct_base_addr; u64 size; node = dt_find_compatible_node(NULL, NULL, "samsung,exynos4210-mct"); if ( !node ) { dprintk(XENLOG_ERR, "samsung,exynos4210-mct missing in DT\n"); return -ENXIO; } rc = dt_device_get_address(node, 0, &mct_base_addr, &size); if ( rc ) { dprintk(XENLOG_ERR, "Error in \"samsung,exynos4210-mct\"\n"); return -ENXIO; } dprintk(XENLOG_INFO, "mct_base_addr: %016llx size: %016llx\n", mct_base_addr, size); mct = ioremap_attr(mct_base_addr, size, PAGE_HYPERVISOR_NOCACHE); if ( !mct ) { dprintk(XENLOG_ERR, "Unable to map MCT\n"); return -ENOMEM; } /* Enable timer on Exynos 5250 should probably be done by u-boot */ reg = readl(mct + EXYNOS5_MCT_G_TCON); writel(reg | EXYNOS5_MCT_G_TCON_START, mct + EXYNOS5_MCT_G_TCON); iounmap(mct); return 0; }
static void firenze_dt_fixup_i2cm(void) { struct dt_node *master, *bus, *dev; struct proc_chip *c; const uint32_t *p; char name[32]; uint64_t lx; if (dt_find_compatible_node(dt_root, NULL, "ibm,power8-i2cm")) return; p = dt_prop_get_def(dt_root, "ibm,vpd-lx-info", NULL); if (!p) return; lx = ((uint64_t)p[1] << 32) | p[2]; switch (lx) { case LX_VPD_2S4U_BACKPLANE: case LX_VPD_2S2U_BACKPLANE: case LX_VPD_SHARK_BACKPLANE: /* XXX confirm ? */ /* i2c nodes on chip 0x10 */ c = get_chip(0x10); if (c) { /* Engine 1 */ master = dt_create_i2c_master(c->devnode, 1); assert(master); snprintf(name, sizeof(name), "p8_%08x_e%dp%d", c->id, 1, 0); bus = dt_create_i2c_bus(master, name, 0); assert(bus); dev = dt_create_i2c_device(bus, 0x39, "power-control", "maxim,5961", "pcie-hotplug"); assert(dev); dt_add_property_strings(dev, "target-list", "slot-C4", "slot-C5"); dev = dt_create_i2c_device(bus, 0x3a, "power-control", "maxim,5961", "pcie-hotplug"); assert(dev); dt_add_property_strings(dev, "target-list", "slot-C2", "slot-C3"); } else { prlog(PR_INFO, "PLAT: Chip not found for the id 0x10\n"); } /* Fall through */ case LX_VPD_1S4U_BACKPLANE: case LX_VPD_1S2U_BACKPLANE: /* i2c nodes on chip 0 */ c = get_chip(0); if (!c) { prlog(PR_INFO, "PLAT: Chip not found for the id 0x0\n"); break; } /* Engine 1*/ master = dt_create_i2c_master(c->devnode, 1); assert(master); snprintf(name, sizeof(name), "p8_%08x_e%dp%d", c->id, 1, 0); bus = dt_create_i2c_bus(master, name, 0); assert(bus); dev = dt_create_i2c_device(bus, 0x32, "power-control", "maxim,5961", "pcie-hotplug"); assert(dev); dt_add_property_strings(dev, "target-list", "slot-C10", "slot-C11"); dev = dt_create_i2c_device(bus, 0x35, "power-control", "maxim,5961", "pcie-hotplug"); assert(dev); dt_add_property_strings(dev, "target-list", "slot-C6", "slot-C7"); dev = dt_create_i2c_device(bus, 0x36, "power-control", "maxim,5961", "pcie-hotplug"); assert(dev); dt_add_property_strings(dev, "target-list", "slot-C8", "slot-C9"); dev = dt_create_i2c_device(bus, 0x39, "power-control", "maxim,5961", "pcie-hotplug"); assert(dev); dt_add_property_strings(dev, "target-list", "slot-C12"); break; default: break; } }
static void __init set_pixclock(uint32_t pixclock) { if ( dt_find_compatible_node(NULL, NULL, "arm,vexpress") ) vexpress_syscfg(1, V2M_SYS_CFG_OSC_FUNC, V2M_SYS_CFG_OSC5, &pixclock); }
void __init video_init(void) { struct lfb_prop lfbp; unsigned char *lfb; paddr_t hdlcd_start, hdlcd_size; paddr_t framebuffer_start, framebuffer_size; const char *mode_string; char _mode_string[16]; int bytes_per_pixel = 4; struct color_masks *c = NULL; struct modeline *videomode = NULL; int i; const struct dt_device_node *dev; const __be32 *cells; u32 lenp; int res; dev = dt_find_compatible_node(NULL, NULL, "arm,hdlcd"); if ( !dev ) { early_printk("HDLCD: Cannot find node compatible with \"arm,hdcld\"\n"); return; } res = dt_device_get_address(dev, 0, &hdlcd_start, &hdlcd_size); if ( !res ) { early_printk("HDLCD: Unable to retrieve MMIO base address\n"); return; } cells = dt_get_property(dev, "framebuffer", &lenp); if ( !cells ) { early_printk("HDLCD: Unable to retrieve framebuffer property\n"); return; } framebuffer_start = dt_next_cell(dt_n_addr_cells(dev), &cells); framebuffer_size = dt_next_cell(dt_n_size_cells(dev), &cells); if ( !hdlcd_start ) { early_printk(KERN_ERR "HDLCD: address missing from device tree, disabling driver\n"); return; } if ( !framebuffer_start ) { early_printk(KERN_ERR "HDLCD: framebuffer address missing from device tree, disabling driver\n"); return; } res = dt_property_read_string(dev, "mode", &mode_string); if ( res ) { get_color_masks("32", &c); memcpy(_mode_string, "1280x1024@60", strlen("1280x1024@60") + 1); bytes_per_pixel = 4; } else if ( strlen(mode_string) < strlen("800x600@60") || strlen(mode_string) > sizeof(_mode_string) - 1 ) { early_printk(KERN_ERR "HDLCD: invalid modeline=%s\n", mode_string); return; } else { char *s = strchr(mode_string, '-'); if ( !s ) { early_printk(KERN_INFO "HDLCD: bpp not found in modeline %s, assume 32 bpp\n", mode_string); get_color_masks("32", &c); memcpy(_mode_string, mode_string, strlen(mode_string) + 1); bytes_per_pixel = 4; } else { if ( strlen(s) < 6 ) { early_printk(KERN_ERR "HDLCD: invalid mode %s\n", mode_string); return; } s++; if ( get_color_masks(s, &c) < 0 ) { early_printk(KERN_WARNING "HDLCD: unsupported bpp %s\n", s); return; } bytes_per_pixel = simple_strtoll(s, NULL, 10) / 8; } i = s - mode_string - 1; memcpy(_mode_string, mode_string, i); memcpy(_mode_string + i, mode_string + i + 3, 4); } for ( i = 0; i < ARRAY_SIZE(videomodes); i++ ) { if ( !strcmp(_mode_string, videomodes[i].mode) ) { videomode = &videomodes[i]; break; } } if ( !videomode ) { early_printk(KERN_WARNING "HDLCD: unsupported videomode %s\n", _mode_string); return; } if ( framebuffer_size < bytes_per_pixel * videomode->xres * videomode->yres ) { early_printk(KERN_ERR "HDLCD: the framebuffer is too small, disabling the HDLCD driver\n"); return; } early_printk(KERN_INFO "Initializing HDLCD driver\n"); lfb = ioremap_wc(framebuffer_start, framebuffer_size); if ( !lfb ) { early_printk(KERN_ERR "Couldn't map the framebuffer\n"); return; } memset(lfb, 0x00, bytes_per_pixel * videomode->xres * videomode->yres); /* uses FIXMAP_MISC */ set_pixclock(videomode->pixclock); set_fixmap(FIXMAP_MISC, hdlcd_start >> PAGE_SHIFT, DEV_SHARED); HDLCD[HDLCD_COMMAND] = 0; HDLCD[HDLCD_LINELENGTH] = videomode->xres * bytes_per_pixel; HDLCD[HDLCD_LINECOUNT] = videomode->yres - 1; HDLCD[HDLCD_LINEPITCH] = videomode->xres * bytes_per_pixel; HDLCD[HDLCD_PF] = ((bytes_per_pixel - 1) << 3); HDLCD[HDLCD_INTMASK] = 0; HDLCD[HDLCD_FBBASE] = framebuffer_start; HDLCD[HDLCD_BUS] = 0xf00 | (1 << 4); HDLCD[HDLCD_VBACK] = videomode->vback - 1; HDLCD[HDLCD_VSYNC] = videomode->vsync - 1; HDLCD[HDLCD_VDATA] = videomode->yres - 1; HDLCD[HDLCD_VFRONT] = videomode->vfront - 1; HDLCD[HDLCD_HBACK] = videomode->hback - 1; HDLCD[HDLCD_HSYNC] = videomode->hsync - 1; HDLCD[HDLCD_HDATA] = videomode->xres - 1; HDLCD[HDLCD_HFRONT] = videomode->hfront - 1; HDLCD[HDLCD_POLARITIES] = (1 << 2) | (1 << 3); HDLCD[HDLCD_RED] = (c->red_size << 8) | c->red_shift; HDLCD[HDLCD_GREEN] = (c->green_size << 8) | c->green_shift; HDLCD[HDLCD_BLUE] = (c->blue_size << 8) | c->blue_shift; HDLCD[HDLCD_COMMAND] = 1; clear_fixmap(FIXMAP_MISC); lfbp.pixel_on = (((1 << c->red_size) - 1) << c->red_shift) | (((1 << c->green_size) - 1) << c->green_shift) | (((1 << c->blue_size) - 1) << c->blue_shift); lfbp.lfb = lfb; lfbp.font = &font_vga_8x16; lfbp.bits_per_pixel = bytes_per_pixel*8; lfbp.bytes_per_line = bytes_per_pixel*videomode->xres; lfbp.width = videomode->xres; lfbp.height = videomode->yres; lfbp.flush = hdlcd_flush; lfbp.text_columns = videomode->xres / 8; lfbp.text_rows = videomode->yres / 16; if ( lfb_init(&lfbp) < 0 ) return; video_puts = lfb_scroll_puts; }