Beispiel #1
0
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);
}
Beispiel #2
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;
}
Beispiel #3
0
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;
}