예제 #1
0
파일: spu.c 프로젝트: E-LLP/n900
static int __init setup_areas(struct spu *spu)
{
	struct table {char* name; unsigned long addr; unsigned long size;};
	static const unsigned long shadow_flags = _PAGE_NO_CACHE | 3;

	spu_pdata(spu)->shadow = __ioremap(spu_pdata(spu)->shadow_addr,
					   sizeof(struct spe_shadow),
					   shadow_flags);
	if (!spu_pdata(spu)->shadow) {
		pr_debug("%s:%d: ioremap shadow failed\n", __func__, __LINE__);
		goto fail_ioremap;
	}

	spu->local_store = (__force void *)ioremap_flags(spu->local_store_phys,
		LS_SIZE, _PAGE_NO_CACHE);

	if (!spu->local_store) {
		pr_debug("%s:%d: ioremap local_store failed\n",
			__func__, __LINE__);
		goto fail_ioremap;
	}

	spu->problem = ioremap(spu->problem_phys,
		sizeof(struct spu_problem));

	if (!spu->problem) {
		pr_debug("%s:%d: ioremap problem failed\n", __func__, __LINE__);
		goto fail_ioremap;
	}

	spu->priv2 = ioremap(spu_pdata(spu)->priv2_addr,
		sizeof(struct spu_priv2));

	if (!spu->priv2) {
		pr_debug("%s:%d: ioremap priv2 failed\n", __func__, __LINE__);
		goto fail_ioremap;
	}

	dump_areas(spu_pdata(spu)->spe_id, spu_pdata(spu)->priv2_addr,
		spu->problem_phys, spu->local_store_phys,
		spu_pdata(spu)->shadow_addr);
	dump_areas(spu_pdata(spu)->spe_id, (unsigned long)spu->priv2,
		(unsigned long)spu->problem, (unsigned long)spu->local_store,
		(unsigned long)spu_pdata(spu)->shadow);

	return 0;

fail_ioremap:
	spu_unmap(spu);

	return -ENOMEM;
}
예제 #2
0
static int __init ps3sbmmio_init(void)
{
	int res;

	res = lv1_undocumented_function_114(MMAP_START_ADDR, PAGE_SHIFT, MMAP_SIZE, &ps3sbmmio_lpar_addr);
	if (res) {
		pr_debug("%s:%u: lpar map failed %d\n", __func__, __LINE__, res);
		res = -EFAULT;
		goto fail;
	}

	ps3sbmmio = ioremap_flags(ps3sbmmio_lpar_addr, MMAP_SIZE, _PAGE_NO_CACHE);
	if (!ps3sbmmio) {
		pr_debug("%s:%d: ioremap_flags failed\n", __func__, __LINE__);
		res = -EFAULT;
		goto fail_lpar_unmap;
	}

	res = misc_register(&ps3sbmmio_misc);
	if (res) {
		pr_debug("%s:%u: misc_register failed %d\n",
			 __func__, __LINE__, res);
		goto fail_iounmap;
	}

	pr_debug("%s:%u: registered misc device %d\n",
		 __func__, __LINE__, ps3sbmmio_misc.minor);

	return 0;

fail_iounmap:

	iounmap(ps3sbmmio);

fail_lpar_unmap:

	lv1_undocumented_function_115(ps3sbmmio_lpar_addr);

fail:

	return res;
}
예제 #3
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;
}
int __init instantiate_cache_sram(struct of_device *dev,
		struct sram_parameters sram_params)
{
	int ret = 0;

	if (cache_sram) {
		dev_err(&dev->dev, "Already initialized cache-sram\n");
		return -EBUSY;
	}

	cache_sram = kzalloc(sizeof(struct mpc85xx_cache_sram), GFP_KERNEL);
	if (!cache_sram) {
		dev_err(&dev->dev, "Out of memory for cache_sram structure\n");
		return -ENOMEM;
	}

	cache_sram->base_phys = sram_params.sram_offset;
	cache_sram->size = sram_params.sram_size;

	if (!request_mem_region(cache_sram->base_phys, cache_sram->size,
						"fsl_85xx_cache_sram")) {
		dev_err(&dev->dev, "%s: request memory failed\n",
				dev->dev.of_node->full_name);
		ret = -ENXIO;
		goto out_free;
	}

	cache_sram->base_virt = ioremap_flags(cache_sram->base_phys,
				cache_sram->size, _PAGE_COHERENT | PAGE_KERNEL);
	if (!cache_sram->base_virt) {
		dev_err(&dev->dev, "%s: ioremap_flags failed\n",
				dev->dev.of_node->full_name);
		ret = -ENOMEM;
		goto out_release;
	}

	cache_sram->rh = rh_create(sizeof(unsigned int));
	if (IS_ERR(cache_sram->rh)) {
		dev_err(&dev->dev, "%s: Unable to create remote heap\n",
				dev->dev.of_node->full_name);
		ret = PTR_ERR(cache_sram->rh);
		goto out_unmap;
	}

	rh_attach_region(cache_sram->rh, 0, cache_sram->size);
	spin_lock_init(&cache_sram->lock);

	dev_info(&dev->dev, "[base:0x%llx, size:0x%x] configured and loaded\n",
		(unsigned long long)cache_sram->base_phys, cache_sram->size);

	return 0;

out_unmap:
	iounmap(cache_sram->base_virt);

out_release:
	release_mem_region(cache_sram->base_phys, cache_sram->size);

out_free:
	kfree(cache_sram);
	return ret;
}