static int ps3cons_init(int arg) { uint64_t fbhandle, fbcontext; int i; lv1_gpu_open(0); lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_MODE_SET, 0,0,0,0); lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_MODE_SET, 0,0,1,0); lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC, 0,L1GPU_DISPLAY_SYNC_VSYNC,0,0); lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC, 1,L1GPU_DISPLAY_SYNC_VSYNC,0,0); lv1_gpu_memory_allocate(FB_SIZE, 0, 0, 0, 0, &fbhandle, &fb_paddr); lv1_gpu_context_allocate(fbhandle, 0, &fbcontext); lv1_gpu_context_attribute(fbcontext, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 0, 0, 0, 0); lv1_gpu_context_attribute(fbcontext, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 1, 0, 0, 0); fb_vaddr = ps3mmu_mapdev(fb_paddr, FB_SIZE); x = y = 0; /* Blank console */ for (i = 0; i < fb_width*fb_height; i++) fb_vaddr[i] = BG_COLOR; return (0); }
static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev) { struct ps3vram_priv *priv; int status; u64 ddr_lpar; u64 ctrl_lpar; u64 info_lpar; u64 reports_lpar; u64 ddr_size; u64 reports_size; int ret = -ENOMEM; char *rest; ret = -EIO; ps3vram_mtd.priv = kzalloc(sizeof(struct ps3vram_priv), GFP_KERNEL); if (!ps3vram_mtd.priv) goto out; priv = ps3vram_mtd.priv; mutex_init(&priv->lock); priv->dev = &dev->core; /* Allocate XDR buffer (1MiB aligned) */ priv->xdr_buf = (void *)__get_free_pages(GFP_KERNEL, get_order(XDR_BUF_SIZE)); if (priv->xdr_buf == NULL) { dev_dbg(&dev->core, "%s:%d: could not allocate XDR buffer\n", __func__, __LINE__); ret = -ENOMEM; goto out_free_priv; } /* Put FIFO at begginning of XDR buffer */ priv->fifo_base = (u32 *) (priv->xdr_buf + FIFO_OFFSET); priv->fifo_ptr = priv->fifo_base; /* XXX: Need to open GPU, in case ps3fb or snd_ps3 aren't loaded */ if (ps3_open_hv_device(dev)) { dev_err(&dev->core, "%s:%d: ps3_open_hv_device failed\n", __func__, __LINE__); ret = -EAGAIN; goto out_close_gpu; } /* Request memory */ status = -1; ddr_size = memparse(size, &rest); if (*rest == '-') ddr_size -= ps3fb_videomemory.size; ddr_size = ALIGN(ddr_size, 1024*1024); if (ddr_size <= 0) { dev_err(&dev->core, "%s:%d: specified size is too small\n", __func__, __LINE__); ret = -EINVAL; goto out_close_gpu; } while (ddr_size > 0) { status = lv1_gpu_memory_allocate(ddr_size, 0, 0, 0, 0, &priv->memory_handle, &ddr_lpar); if (!status) break; ddr_size -= 1024*1024; } if (status || ddr_size <= 0) { dev_err(&dev->core, "%s:%d: lv1_gpu_memory_allocate failed\n", __func__, __LINE__); ret = -ENOMEM; goto out_free_xdr_buf; } /* Request context */ status = lv1_gpu_context_allocate(priv->memory_handle, 0, &priv->context_handle, &ctrl_lpar, &info_lpar, &reports_lpar, &reports_size); if (status) { dev_err(&dev->core, "%s:%d: lv1_gpu_context_allocate failed\n", __func__, __LINE__); ret = -ENOMEM; goto out_free_memory; } /* Map XDR buffer to RSX */ status = lv1_gpu_context_iomap(priv->context_handle, XDR_IOIF, ps3_mm_phys_to_lpar(__pa(priv->xdr_buf)), XDR_BUF_SIZE, 0); if (status) { dev_err(&dev->core, "%s:%d: lv1_gpu_context_iomap failed\n", __func__, __LINE__); ret = -ENOMEM; goto out_free_context; } priv->ddr_base = ioremap_flags(ddr_lpar, ddr_size, _PAGE_NO_CACHE); if (!priv->ddr_base) { dev_err(&dev->core, "%s:%d: ioremap failed\n", __func__, __LINE__); ret = -ENOMEM; goto out_free_context; } priv->ctrl = ioremap(ctrl_lpar, 64 * 1024); if (!priv->ctrl) { dev_err(&dev->core, "%s:%d: ioremap failed\n", __func__, __LINE__); ret = -ENOMEM; goto out_unmap_vram; } priv->reports = ioremap(reports_lpar, reports_size); if (!priv->reports) { dev_err(&dev->core, "%s:%d: ioremap failed\n", __func__, __LINE__); ret = -ENOMEM; goto out_unmap_ctrl; } mutex_lock(&ps3_gpu_mutex); ps3vram_init_ring(&ps3vram_mtd); mutex_unlock(&ps3_gpu_mutex); ps3vram_mtd.name = "ps3vram"; ps3vram_mtd.size = ddr_size; ps3vram_mtd.flags = MTD_CAP_RAM; ps3vram_mtd.erase = ps3vram_erase; ps3vram_mtd.point = NULL; ps3vram_mtd.unpoint = NULL; ps3vram_mtd.read = ps3vram_read; ps3vram_mtd.write = ps3vram_write; ps3vram_mtd.owner = THIS_MODULE; ps3vram_mtd.type = MTD_RAM; ps3vram_mtd.erasesize = CACHE_PAGE_SIZE; ps3vram_mtd.writesize = 1; ps3vram_bind(&ps3vram_mtd); mutex_lock(&ps3_gpu_mutex); ret = ps3vram_wait_ring(&ps3vram_mtd, 100); mutex_unlock(&ps3_gpu_mutex); if (ret < 0) { dev_err(&dev->core, "%s:%d: failed to initialize channels\n", __func__, __LINE__); ret = -ETIMEDOUT; goto out_unmap_reports; } ps3vram_cache_init(&ps3vram_mtd); if (add_mtd_device(&ps3vram_mtd)) { dev_err(&dev->core, "%s:%d: add_mtd_device failed\n", __func__, __LINE__); ret = -EAGAIN; goto out_cache_cleanup; } dev_info(&dev->core, "reserved %u MiB of gpu memory\n", (unsigned int)(ddr_size / 1024 / 1024)); return 0; out_cache_cleanup: ps3vram_cache_cleanup(&ps3vram_mtd); out_unmap_reports: iounmap(priv->reports); out_unmap_ctrl: iounmap(priv->ctrl); out_unmap_vram: iounmap(priv->ddr_base); out_free_context: lv1_gpu_context_free(priv->context_handle); out_free_memory: lv1_gpu_memory_free(priv->memory_handle); out_close_gpu: ps3_close_hv_device(dev); out_free_xdr_buf: free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE)); out_free_priv: kfree(ps3vram_mtd.priv); ps3vram_mtd.priv = NULL; out: return ret; }
static int register_device(void) { struct ps3vram_priv *priv; uint64_t status, ddr_lpar, ddr_size; int ret = -ENOMEM; ret = -EIO; ps3vram_mtd.priv = kzalloc(sizeof(struct ps3vram_priv), GFP_KERNEL); if (!ps3vram_mtd.priv) goto out0; priv = ps3vram_mtd.priv; /* Request memory */ ddr_size = 0x0fc00000; /* XXX 252 MB */ status = lv1_gpu_memory_allocate(ddr_size, 0, 0, 0, 0, &priv->memory_handle, &ddr_lpar); if (status != 0) { printk(KERN_ERR "ps3vram: lv1_gpu_memory_allocate failed\n"); goto out1; } priv->base = priv->real_base = ioremap(ddr_lpar, ddr_size); if (!priv->real_base) { printk(KERN_ERR "ps3vram: ioremap failed\n"); goto out2; } /* XXX: Skip beginning GDDR ram that might belong to the framebuffer. */ #define SKIP_SIZE ((1920*1080*4)*2) priv->base += SKIP_SIZE; ddr_size -= SKIP_SIZE; ps3vram_mtd.name = "ps3vram"; ps3vram_mtd.size = ddr_size; ps3vram_mtd.flags = MTD_CAP_RAM | MTD_ERASEABLE | MTD_VOLATILE; ps3vram_mtd.erase = ps3vram_erase; ps3vram_mtd.point = NULL; ps3vram_mtd.unpoint = NULL; ps3vram_mtd.read = ps3vram_read; ps3vram_mtd.write = ps3vram_write; ps3vram_mtd.owner = THIS_MODULE; ps3vram_mtd.type = MTD_RAM; ps3vram_mtd.erasesize = PAGE_SIZE; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) ps3vram_mtd.writesize = 1; #endif ret = -EAGAIN; if (add_mtd_device(&ps3vram_mtd)) { printk(KERN_ERR "ps3vram: failed to register device\n"); goto out3; } printk(KERN_INFO "ps3vram mtd device registered, %ld bytes\n", ddr_size); return 0; out3: iounmap(priv->real_base); out2: lv1_gpu_memory_free(priv->memory_handle); out1: kfree(ps3vram_mtd.priv); out0: return ret; }