Esempio n. 1
0
static void __init xgene_check_pirq_eoi(void)
{
    const struct dt_device_node *node;
    int res;
    paddr_t dbase;
    const struct dt_device_match xgene_dt_int_ctrl_match[] =
    {
        DT_MATCH_COMPATIBLE("arm,cortex-a15-gic"),
        { /*sentinel*/ },
    };

    node = dt_find_interrupt_controller(xgene_dt_int_ctrl_match);
    if ( !node )
        panic("%s: Can not find interrupt controller node", __func__);

    res = dt_device_get_address(node, 0, &dbase, NULL);
    if ( !dbase )
        panic("%s: Cannot find a valid address for the distributor", __func__);

    /*
     * In old X-Gene Storm firmware and DT, secure mode addresses have
     * been mentioned in GICv2 node. We have to use maintenance interrupt
     * instead of EOI HW in this case. We check the GIC Distributor Base
     * Address to maintain compatibility with older firmware.
     */
    if ( dbase == XGENE_SEC_GICV2_DIST_ADDR )
    {
        xgene_quirks |= PLATFORM_QUIRK_GUEST_PIRQ_NEED_EOI;
        printk("Xen: WARNING: OLD X-Gene Firmware, disabling PIRQ EOI mode\n");
    }
}
Esempio n. 2
0
static void __init xgene_check_pirq_eoi(void)
{
    const struct dt_device_node *node;
    int res;
    paddr_t dbase;
    const struct dt_device_match xgene_dt_int_ctrl_match[] =
    {
        DT_MATCH_COMPATIBLE("arm,cortex-a15-gic"),
        { /*sentinel*/ },
    };

    node = dt_find_interrupt_controller(xgene_dt_int_ctrl_match);
    if ( !node )
        panic("%s: Can not find interrupt controller node", __func__);

    res = dt_device_get_address(node, 0, &dbase, NULL);
    if ( !dbase )
        panic("%s: Cannot find a valid address for the distributor", __func__);

    /*
     * In old X-Gene Storm firmware and DT, secure mode addresses have
     * been mentioned in GICv2 node. EOI HW won't work in this case.
     * We check the GIC Distributor Base Address to deny Xen booting
     * with older firmware.
     */
    if ( dbase == XGENE_SEC_GICV2_DIST_ADDR )
        panic("OLD X-Gene Firmware is not supported by Xen.\n"
              "Please upgrade your firmware to the latest version");
}
Esempio n. 3
0
File: exynos5.c Progetto: CPFL/xen
static int exynos5_get_pmu_baseandsize(u64 *power_base_addr, u64 *size)
{
    struct dt_device_node *node;
    int rc;
    static const struct dt_device_match exynos_dt_pmu_matches[] =
    {
        DT_MATCH_COMPATIBLE("samsung,exynos5250-pmu"),
        DT_MATCH_COMPATIBLE("samsung,exynos5410-pmu"),
        DT_MATCH_COMPATIBLE("samsung,exynos5420-pmu"),
        { /*sentinel*/ },
    };

    node = dt_find_matching_node(NULL, exynos_dt_pmu_matches);
    if ( !node )
    {
        dprintk(XENLOG_ERR, "samsung,exynos5XXX-pmu missing in DT\n");
        return -ENXIO;
    }

    rc = dt_device_get_address(node, 0, power_base_addr, size);
    if ( rc )
    {
        dprintk(XENLOG_ERR, "Error in \"samsung,exynos5XXX-pmu\"\n");
        return -ENXIO;
    }

    dprintk(XENLOG_DEBUG, "power_base_addr: %016llx size: %016llx\n",
            *power_base_addr, *size);

    return 0;
}
Esempio n. 4
0
File: brcm.c Progetto: CPFL/xen
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, &reg_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;
}
Esempio n. 5
0
File: exynos5.c Progetto: CPFL/xen
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;
}
Esempio n. 6
0
/*
 * 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;
}
Esempio n. 7
0
/* TODO: Parse UART config from the command line */
static int __init exynos4210_uart_init(struct dt_device_node *dev,
                                       const void *data)
{
    const char *config = data;
    struct exynos4210_uart *uart;
    int res;
    u64 addr, size;

    if ( strcmp(config, "") )
        printk("WARNING: UART configuration is not supported\n");

    uart = &exynos4210_com;

    /* uart->clock_hz  = 0x16e3600; */
    uart->baud      = BAUD_AUTO;
    uart->data_bits = 8;
    uart->parity    = PARITY_NONE;
    uart->stop_bits = 1;

    res = dt_device_get_address(dev, 0, &addr, &size);
    if ( res )
    {
        printk("exynos4210: Unable to retrieve the base"
               " address of the UART\n");
        return res;
    }

    res = platform_get_irq(dev, 0);
    if ( res < 0 )
    {
        printk("exynos4210: Unable to retrieve the IRQ\n");
        return -EINVAL;
    }
    uart->irq = res;

    uart->regs = ioremap_nocache(addr, size);
    if ( !uart->regs )
    {
        printk("exynos4210: Unable to map the UART memory\n");
        return -ENOMEM;
    }

    uart->vuart.base_addr = addr;
    uart->vuart.size = size;
    uart->vuart.data_off = UTXH;
    uart->vuart.status_off = UTRSTAT;
    uart->vuart.status = UTRSTAT_TXE | UTRSTAT_TXFE;

    /* Register with generic serial driver. */
    serial_register_uart(SERHND_DTUART, &exynos4210_uart_driver, uart);

    dt_device_set_used_by(dev, DOMID_XEN);

    return 0;
}
Esempio n. 8
0
File: exynos5.c Progetto: CPFL/xen
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;
}
Esempio n. 9
0
static int __init omap_uart_init(struct dt_device_node *dev,
                                 const void *data)
{
    const char *config = data;
    struct omap_uart *uart;
    u32 clkspec;
    int res;
    u64 addr, size;

    if ( strcmp(config, "") )
        printk("WARNING: UART configuration is not supported\n");

    uart = &omap_com;

    res = dt_property_read_u32(dev, "clock-frequency", &clkspec);
    if ( !res )
    {
        printk("omap-uart: Unable to retrieve the clock frequency\n");
        return -EINVAL;
    }

    uart->clock_hz = clkspec;
    uart->baud = 115200;
    uart->data_bits = 8;
    uart->parity = UART_PARITY_NONE;
    uart->stop_bits = 1;

    res = dt_device_get_address(dev, 0, &addr, &size);
    if ( res )
    {
        printk("omap-uart: Unable to retrieve the base"
               " address of the UART\n");
        return res;
    }

    res = platform_get_irq(dev, 0);
    if ( res < 0 )
    {
        printk("omap-uart: Unable to retrieve the IRQ\n");
        return -EINVAL;
    }
    uart->irq = res;

    uart->regs = ioremap_nocache(addr, size);
    if ( !uart->regs )
    {
        printk("omap-uart: Unable to map the UART memory\n");
        return -ENOMEM;
    }


    uart->vuart.base_addr = addr;
    uart->vuart.size = size;
    uart->vuart.data_off = UART_THR;
    uart->vuart.status_off = UART_LSR << REG_SHIFT;
    uart->vuart.status = UART_LSR_THRE;

    /* Register with generic serial driver */
    serial_register_uart(SERHND_DTUART, &omap_uart_driver, uart);

    dt_device_set_used_by(dev, DOMID_XEN);

    return 0;
}
Esempio n. 10
0
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;
}