Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * ps3vram - Use extra PS3 video ram as block device.
0004  *
0005  * Copyright 2009 Sony Corporation
0006  *
0007  * Based on the MTD ps3vram driver, which is
0008  * Copyright (c) 2007-2008 Jim Paris <jim@jtan.com>
0009  * Added support RSX DMA Vivien Chappelier <vivien.chappelier@free.fr>
0010  */
0011 
0012 #include <linux/blkdev.h>
0013 #include <linux/delay.h>
0014 #include <linux/module.h>
0015 #include <linux/proc_fs.h>
0016 #include <linux/seq_file.h>
0017 #include <linux/slab.h>
0018 
0019 #include <asm/cell-regs.h>
0020 #include <asm/firmware.h>
0021 #include <asm/lv1call.h>
0022 #include <asm/ps3.h>
0023 #include <asm/ps3gpu.h>
0024 
0025 
0026 #define DEVICE_NAME     "ps3vram"
0027 
0028 
0029 #define XDR_BUF_SIZE (2 * 1024 * 1024) /* XDR buffer (must be 1MiB aligned) */
0030 #define XDR_IOIF 0x0c000000
0031 
0032 #define FIFO_BASE XDR_IOIF
0033 #define FIFO_SIZE (64 * 1024)
0034 
0035 #define DMA_PAGE_SIZE (4 * 1024)
0036 
0037 #define CACHE_PAGE_SIZE (256 * 1024)
0038 #define CACHE_PAGE_COUNT ((XDR_BUF_SIZE - FIFO_SIZE) / CACHE_PAGE_SIZE)
0039 
0040 #define CACHE_OFFSET CACHE_PAGE_SIZE
0041 #define FIFO_OFFSET 0
0042 
0043 #define CTRL_PUT 0x10
0044 #define CTRL_GET 0x11
0045 #define CTRL_TOP 0x15
0046 
0047 #define UPLOAD_SUBCH    1
0048 #define DOWNLOAD_SUBCH  2
0049 
0050 #define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN    0x0000030c
0051 #define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY   0x00000104
0052 
0053 #define CACHE_PAGE_PRESENT 1
0054 #define CACHE_PAGE_DIRTY   2
0055 
0056 struct ps3vram_tag {
0057     unsigned int address;
0058     unsigned int flags;
0059 };
0060 
0061 struct ps3vram_cache {
0062     unsigned int page_count;
0063     unsigned int page_size;
0064     struct ps3vram_tag *tags;
0065     unsigned int hit;
0066     unsigned int miss;
0067 };
0068 
0069 struct ps3vram_priv {
0070     struct gendisk *gendisk;
0071 
0072     u64 size;
0073 
0074     u64 memory_handle;
0075     u64 context_handle;
0076     u32 __iomem *ctrl;
0077     void __iomem *reports;
0078     u8 *xdr_buf;
0079 
0080     u32 *fifo_base;
0081     u32 *fifo_ptr;
0082 
0083     struct ps3vram_cache cache;
0084 
0085     spinlock_t lock;    /* protecting list of bios */
0086     struct bio_list list;
0087 };
0088 
0089 
0090 static int ps3vram_major;
0091 
0092 #define DMA_NOTIFIER_HANDLE_BASE 0x66604200 /* first DMA notifier handle */
0093 #define DMA_NOTIFIER_OFFSET_BASE 0x1000     /* first DMA notifier offset */
0094 #define DMA_NOTIFIER_SIZE        0x40
0095 #define NOTIFIER 7  /* notifier used for completion report */
0096 
0097 static char *size = "256M";
0098 module_param(size, charp, 0);
0099 MODULE_PARM_DESC(size, "memory size");
0100 
0101 static u32 __iomem *ps3vram_get_notifier(void __iomem *reports, int notifier)
0102 {
0103     return reports + DMA_NOTIFIER_OFFSET_BASE +
0104            DMA_NOTIFIER_SIZE * notifier;
0105 }
0106 
0107 static void ps3vram_notifier_reset(struct ps3_system_bus_device *dev)
0108 {
0109     struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
0110     u32 __iomem *notify = ps3vram_get_notifier(priv->reports, NOTIFIER);
0111     int i;
0112 
0113     for (i = 0; i < 4; i++)
0114         iowrite32be(0xffffffff, notify + i);
0115 }
0116 
0117 static int ps3vram_notifier_wait(struct ps3_system_bus_device *dev,
0118                  unsigned int timeout_ms)
0119 {
0120     struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
0121     u32 __iomem *notify = ps3vram_get_notifier(priv->reports, NOTIFIER);
0122     unsigned long timeout;
0123 
0124     for (timeout = 20; timeout; timeout--) {
0125         if (!ioread32be(notify + 3))
0126             return 0;
0127         udelay(10);
0128     }
0129 
0130     timeout = jiffies + msecs_to_jiffies(timeout_ms);
0131 
0132     do {
0133         if (!ioread32be(notify + 3))
0134             return 0;
0135         msleep(1);
0136     } while (time_before(jiffies, timeout));
0137 
0138     return -ETIMEDOUT;
0139 }
0140 
0141 static void ps3vram_init_ring(struct ps3_system_bus_device *dev)
0142 {
0143     struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
0144 
0145     iowrite32be(FIFO_BASE + FIFO_OFFSET, priv->ctrl + CTRL_PUT);
0146     iowrite32be(FIFO_BASE + FIFO_OFFSET, priv->ctrl + CTRL_GET);
0147 }
0148 
0149 static int ps3vram_wait_ring(struct ps3_system_bus_device *dev,
0150                  unsigned int timeout_ms)
0151 {
0152     struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
0153     unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms);
0154 
0155     do {
0156         if (ioread32be(priv->ctrl + CTRL_PUT) == ioread32be(priv->ctrl + CTRL_GET))
0157             return 0;
0158         msleep(1);
0159     } while (time_before(jiffies, timeout));
0160 
0161     dev_warn(&dev->core, "FIFO timeout (%08x/%08x/%08x)\n",
0162          ioread32be(priv->ctrl + CTRL_PUT), ioread32be(priv->ctrl + CTRL_GET),
0163          ioread32be(priv->ctrl + CTRL_TOP));
0164 
0165     return -ETIMEDOUT;
0166 }
0167 
0168 static void ps3vram_out_ring(struct ps3vram_priv *priv, u32 data)
0169 {
0170     *(priv->fifo_ptr)++ = data;
0171 }
0172 
0173 static void ps3vram_begin_ring(struct ps3vram_priv *priv, u32 chan, u32 tag,
0174                    u32 size)
0175 {
0176     ps3vram_out_ring(priv, (size << 18) | (chan << 13) | tag);
0177 }
0178 
0179 static void ps3vram_rewind_ring(struct ps3_system_bus_device *dev)
0180 {
0181     struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
0182     int status;
0183 
0184     ps3vram_out_ring(priv, 0x20000000 | (FIFO_BASE + FIFO_OFFSET));
0185 
0186     iowrite32be(FIFO_BASE + FIFO_OFFSET, priv->ctrl + CTRL_PUT);
0187 
0188     /* asking the HV for a blit will kick the FIFO */
0189     status = lv1_gpu_fb_blit(priv->context_handle, 0, 0, 0, 0);
0190     if (status)
0191         dev_err(&dev->core, "%s: lv1_gpu_fb_blit failed %d\n",
0192             __func__, status);
0193 
0194     priv->fifo_ptr = priv->fifo_base;
0195 }
0196 
0197 static void ps3vram_fire_ring(struct ps3_system_bus_device *dev)
0198 {
0199     struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
0200     int status;
0201 
0202     mutex_lock(&ps3_gpu_mutex);
0203 
0204     iowrite32be(FIFO_BASE + FIFO_OFFSET + (priv->fifo_ptr - priv->fifo_base)
0205         * sizeof(u32), priv->ctrl + CTRL_PUT);
0206 
0207     /* asking the HV for a blit will kick the FIFO */
0208     status = lv1_gpu_fb_blit(priv->context_handle, 0, 0, 0, 0);
0209     if (status)
0210         dev_err(&dev->core, "%s: lv1_gpu_fb_blit failed %d\n",
0211             __func__, status);
0212 
0213     if ((priv->fifo_ptr - priv->fifo_base) * sizeof(u32) >
0214         FIFO_SIZE - 1024) {
0215         dev_dbg(&dev->core, "FIFO full, rewinding\n");
0216         ps3vram_wait_ring(dev, 200);
0217         ps3vram_rewind_ring(dev);
0218     }
0219 
0220     mutex_unlock(&ps3_gpu_mutex);
0221 }
0222 
0223 static void ps3vram_bind(struct ps3_system_bus_device *dev)
0224 {
0225     struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
0226 
0227     ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0, 1);
0228     ps3vram_out_ring(priv, 0x31337303);
0229     ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0x180, 3);
0230     ps3vram_out_ring(priv, DMA_NOTIFIER_HANDLE_BASE + NOTIFIER);
0231     ps3vram_out_ring(priv, 0xfeed0001); /* DMA system RAM instance */
0232     ps3vram_out_ring(priv, 0xfeed0000);     /* DMA video RAM instance */
0233 
0234     ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0, 1);
0235     ps3vram_out_ring(priv, 0x3137c0de);
0236     ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0x180, 3);
0237     ps3vram_out_ring(priv, DMA_NOTIFIER_HANDLE_BASE + NOTIFIER);
0238     ps3vram_out_ring(priv, 0xfeed0000); /* DMA video RAM instance */
0239     ps3vram_out_ring(priv, 0xfeed0001); /* DMA system RAM instance */
0240 
0241     ps3vram_fire_ring(dev);
0242 }
0243 
0244 static int ps3vram_upload(struct ps3_system_bus_device *dev,
0245               unsigned int src_offset, unsigned int dst_offset,
0246               int len, int count)
0247 {
0248     struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
0249 
0250     ps3vram_begin_ring(priv, UPLOAD_SUBCH,
0251                NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
0252     ps3vram_out_ring(priv, XDR_IOIF + src_offset);
0253     ps3vram_out_ring(priv, dst_offset);
0254     ps3vram_out_ring(priv, len);
0255     ps3vram_out_ring(priv, len);
0256     ps3vram_out_ring(priv, len);
0257     ps3vram_out_ring(priv, count);
0258     ps3vram_out_ring(priv, (1 << 8) | 1);
0259     ps3vram_out_ring(priv, 0);
0260 
0261     ps3vram_notifier_reset(dev);
0262     ps3vram_begin_ring(priv, UPLOAD_SUBCH,
0263                NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1);
0264     ps3vram_out_ring(priv, 0);
0265     ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0x100, 1);
0266     ps3vram_out_ring(priv, 0);
0267     ps3vram_fire_ring(dev);
0268     if (ps3vram_notifier_wait(dev, 200) < 0) {
0269         dev_warn(&dev->core, "%s: Notifier timeout\n", __func__);
0270         return -1;
0271     }
0272 
0273     return 0;
0274 }
0275 
0276 static int ps3vram_download(struct ps3_system_bus_device *dev,
0277                 unsigned int src_offset, unsigned int dst_offset,
0278                 int len, int count)
0279 {
0280     struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
0281 
0282     ps3vram_begin_ring(priv, DOWNLOAD_SUBCH,
0283                NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
0284     ps3vram_out_ring(priv, src_offset);
0285     ps3vram_out_ring(priv, XDR_IOIF + dst_offset);
0286     ps3vram_out_ring(priv, len);
0287     ps3vram_out_ring(priv, len);
0288     ps3vram_out_ring(priv, len);
0289     ps3vram_out_ring(priv, count);
0290     ps3vram_out_ring(priv, (1 << 8) | 1);
0291     ps3vram_out_ring(priv, 0);
0292 
0293     ps3vram_notifier_reset(dev);
0294     ps3vram_begin_ring(priv, DOWNLOAD_SUBCH,
0295                NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1);
0296     ps3vram_out_ring(priv, 0);
0297     ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0x100, 1);
0298     ps3vram_out_ring(priv, 0);
0299     ps3vram_fire_ring(dev);
0300     if (ps3vram_notifier_wait(dev, 200) < 0) {
0301         dev_warn(&dev->core, "%s: Notifier timeout\n", __func__);
0302         return -1;
0303     }
0304 
0305     return 0;
0306 }
0307 
0308 static void ps3vram_cache_evict(struct ps3_system_bus_device *dev, int entry)
0309 {
0310     struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
0311     struct ps3vram_cache *cache = &priv->cache;
0312 
0313     if (!(cache->tags[entry].flags & CACHE_PAGE_DIRTY))
0314         return;
0315 
0316     dev_dbg(&dev->core, "Flushing %d: 0x%08x\n", entry,
0317         cache->tags[entry].address);
0318     if (ps3vram_upload(dev, CACHE_OFFSET + entry * cache->page_size,
0319                cache->tags[entry].address, DMA_PAGE_SIZE,
0320                cache->page_size / DMA_PAGE_SIZE) < 0) {
0321         dev_err(&dev->core,
0322             "Failed to upload from 0x%x to " "0x%x size 0x%x\n",
0323             entry * cache->page_size, cache->tags[entry].address,
0324             cache->page_size);
0325     }
0326     cache->tags[entry].flags &= ~CACHE_PAGE_DIRTY;
0327 }
0328 
0329 static void ps3vram_cache_load(struct ps3_system_bus_device *dev, int entry,
0330                    unsigned int address)
0331 {
0332     struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
0333     struct ps3vram_cache *cache = &priv->cache;
0334 
0335     dev_dbg(&dev->core, "Fetching %d: 0x%08x\n", entry, address);
0336     if (ps3vram_download(dev, address,
0337                  CACHE_OFFSET + entry * cache->page_size,
0338                  DMA_PAGE_SIZE,
0339                  cache->page_size / DMA_PAGE_SIZE) < 0) {
0340         dev_err(&dev->core,
0341             "Failed to download from 0x%x to 0x%x size 0x%x\n",
0342             address, entry * cache->page_size, cache->page_size);
0343     }
0344 
0345     cache->tags[entry].address = address;
0346     cache->tags[entry].flags |= CACHE_PAGE_PRESENT;
0347 }
0348 
0349 
0350 static void ps3vram_cache_flush(struct ps3_system_bus_device *dev)
0351 {
0352     struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
0353     struct ps3vram_cache *cache = &priv->cache;
0354     int i;
0355 
0356     dev_dbg(&dev->core, "FLUSH\n");
0357     for (i = 0; i < cache->page_count; i++) {
0358         ps3vram_cache_evict(dev, i);
0359         cache->tags[i].flags = 0;
0360     }
0361 }
0362 
0363 static unsigned int ps3vram_cache_match(struct ps3_system_bus_device *dev,
0364                     loff_t address)
0365 {
0366     struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
0367     struct ps3vram_cache *cache = &priv->cache;
0368     unsigned int base;
0369     unsigned int offset;
0370     int i;
0371     static int counter;
0372 
0373     offset = (unsigned int) (address & (cache->page_size - 1));
0374     base = (unsigned int) (address - offset);
0375 
0376     /* fully associative check */
0377     for (i = 0; i < cache->page_count; i++) {
0378         if ((cache->tags[i].flags & CACHE_PAGE_PRESENT) &&
0379             cache->tags[i].address == base) {
0380             cache->hit++;
0381             dev_dbg(&dev->core, "Found entry %d: 0x%08x\n", i,
0382                 cache->tags[i].address);
0383             return i;
0384         }
0385     }
0386 
0387     /* choose a random entry */
0388     i = (jiffies + (counter++)) % cache->page_count;
0389     dev_dbg(&dev->core, "Using entry %d\n", i);
0390 
0391     ps3vram_cache_evict(dev, i);
0392     ps3vram_cache_load(dev, i, base);
0393 
0394     cache->miss++;
0395     return i;
0396 }
0397 
0398 static int ps3vram_cache_init(struct ps3_system_bus_device *dev)
0399 {
0400     struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
0401 
0402     priv->cache.page_count = CACHE_PAGE_COUNT;
0403     priv->cache.page_size = CACHE_PAGE_SIZE;
0404     priv->cache.tags = kcalloc(CACHE_PAGE_COUNT,
0405                    sizeof(struct ps3vram_tag),
0406                    GFP_KERNEL);
0407     if (!priv->cache.tags)
0408         return -ENOMEM;
0409 
0410     dev_info(&dev->core, "Created ram cache: %d entries, %d KiB each\n",
0411         CACHE_PAGE_COUNT, CACHE_PAGE_SIZE / 1024);
0412 
0413     return 0;
0414 }
0415 
0416 static void ps3vram_cache_cleanup(struct ps3_system_bus_device *dev)
0417 {
0418     struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
0419 
0420     ps3vram_cache_flush(dev);
0421     kfree(priv->cache.tags);
0422 }
0423 
0424 static blk_status_t ps3vram_read(struct ps3_system_bus_device *dev, loff_t from,
0425             size_t len, size_t *retlen, u_char *buf)
0426 {
0427     struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
0428     unsigned int cached, count;
0429 
0430     dev_dbg(&dev->core, "%s: from=0x%08x len=0x%zx\n", __func__,
0431         (unsigned int)from, len);
0432 
0433     if (from >= priv->size)
0434         return BLK_STS_IOERR;
0435 
0436     if (len > priv->size - from)
0437         len = priv->size - from;
0438 
0439     /* Copy from vram to buf */
0440     count = len;
0441     while (count) {
0442         unsigned int offset, avail;
0443         unsigned int entry;
0444 
0445         offset = (unsigned int) (from & (priv->cache.page_size - 1));
0446         avail  = priv->cache.page_size - offset;
0447 
0448         entry = ps3vram_cache_match(dev, from);
0449         cached = CACHE_OFFSET + entry * priv->cache.page_size + offset;
0450 
0451         dev_dbg(&dev->core, "%s: from=%08x cached=%08x offset=%08x "
0452             "avail=%08x count=%08x\n", __func__,
0453             (unsigned int)from, cached, offset, avail, count);
0454 
0455         if (avail > count)
0456             avail = count;
0457         memcpy(buf, priv->xdr_buf + cached, avail);
0458 
0459         buf += avail;
0460         count -= avail;
0461         from += avail;
0462     }
0463 
0464     *retlen = len;
0465     return 0;
0466 }
0467 
0468 static blk_status_t ps3vram_write(struct ps3_system_bus_device *dev, loff_t to,
0469              size_t len, size_t *retlen, const u_char *buf)
0470 {
0471     struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
0472     unsigned int cached, count;
0473 
0474     if (to >= priv->size)
0475         return BLK_STS_IOERR;
0476 
0477     if (len > priv->size - to)
0478         len = priv->size - to;
0479 
0480     /* Copy from buf to vram */
0481     count = len;
0482     while (count) {
0483         unsigned int offset, avail;
0484         unsigned int entry;
0485 
0486         offset = (unsigned int) (to & (priv->cache.page_size - 1));
0487         avail  = priv->cache.page_size - offset;
0488 
0489         entry = ps3vram_cache_match(dev, to);
0490         cached = CACHE_OFFSET + entry * priv->cache.page_size + offset;
0491 
0492         dev_dbg(&dev->core, "%s: to=%08x cached=%08x offset=%08x "
0493             "avail=%08x count=%08x\n", __func__, (unsigned int)to,
0494             cached, offset, avail, count);
0495 
0496         if (avail > count)
0497             avail = count;
0498         memcpy(priv->xdr_buf + cached, buf, avail);
0499 
0500         priv->cache.tags[entry].flags |= CACHE_PAGE_DIRTY;
0501 
0502         buf += avail;
0503         count -= avail;
0504         to += avail;
0505     }
0506 
0507     *retlen = len;
0508     return 0;
0509 }
0510 
0511 static int ps3vram_proc_show(struct seq_file *m, void *v)
0512 {
0513     struct ps3vram_priv *priv = m->private;
0514 
0515     seq_printf(m, "hit:%u\nmiss:%u\n", priv->cache.hit, priv->cache.miss);
0516     return 0;
0517 }
0518 
0519 static void ps3vram_proc_init(struct ps3_system_bus_device *dev)
0520 {
0521     struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
0522     struct proc_dir_entry *pde;
0523 
0524     pde = proc_create_single_data(DEVICE_NAME, 0444, NULL,
0525             ps3vram_proc_show, priv);
0526     if (!pde)
0527         dev_warn(&dev->core, "failed to create /proc entry\n");
0528 }
0529 
0530 static struct bio *ps3vram_do_bio(struct ps3_system_bus_device *dev,
0531                   struct bio *bio)
0532 {
0533     struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
0534     int write = bio_data_dir(bio) == WRITE;
0535     const char *op = write ? "write" : "read";
0536     loff_t offset = bio->bi_iter.bi_sector << 9;
0537     blk_status_t error = 0;
0538     struct bio_vec bvec;
0539     struct bvec_iter iter;
0540     struct bio *next;
0541 
0542     bio_for_each_segment(bvec, bio, iter) {
0543         /* PS3 is ppc64, so we don't handle highmem */
0544         char *ptr = bvec_virt(&bvec);
0545         size_t len = bvec.bv_len, retlen;
0546 
0547         dev_dbg(&dev->core, "    %s %zu bytes at offset %llu\n", op,
0548             len, offset);
0549         if (write)
0550             error = ps3vram_write(dev, offset, len, &retlen, ptr);
0551         else
0552             error = ps3vram_read(dev, offset, len, &retlen, ptr);
0553 
0554         if (error) {
0555             dev_err(&dev->core, "%s failed\n", op);
0556             goto out;
0557         }
0558 
0559         if (retlen != len) {
0560             dev_err(&dev->core, "Short %s\n", op);
0561             error = BLK_STS_IOERR;
0562             goto out;
0563         }
0564 
0565         offset += len;
0566     }
0567 
0568     dev_dbg(&dev->core, "%s completed\n", op);
0569 
0570 out:
0571     spin_lock_irq(&priv->lock);
0572     bio_list_pop(&priv->list);
0573     next = bio_list_peek(&priv->list);
0574     spin_unlock_irq(&priv->lock);
0575 
0576     bio->bi_status = error;
0577     bio_endio(bio);
0578     return next;
0579 }
0580 
0581 static void ps3vram_submit_bio(struct bio *bio)
0582 {
0583     struct ps3_system_bus_device *dev = bio->bi_bdev->bd_disk->private_data;
0584     struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
0585     int busy;
0586 
0587     dev_dbg(&dev->core, "%s\n", __func__);
0588 
0589     bio = bio_split_to_limits(bio);
0590 
0591     spin_lock_irq(&priv->lock);
0592     busy = !bio_list_empty(&priv->list);
0593     bio_list_add(&priv->list, bio);
0594     spin_unlock_irq(&priv->lock);
0595 
0596     if (busy)
0597         return;
0598 
0599     do {
0600         bio = ps3vram_do_bio(dev, bio);
0601     } while (bio);
0602 }
0603 
0604 static const struct block_device_operations ps3vram_fops = {
0605     .owner      = THIS_MODULE,
0606     .submit_bio = ps3vram_submit_bio,
0607 };
0608 
0609 static int ps3vram_probe(struct ps3_system_bus_device *dev)
0610 {
0611     struct ps3vram_priv *priv;
0612     int error, status;
0613     struct gendisk *gendisk;
0614     u64 ddr_size, ddr_lpar, ctrl_lpar, info_lpar, reports_lpar,
0615         reports_size, xdr_lpar;
0616     char *rest;
0617 
0618     priv = kzalloc(sizeof(*priv), GFP_KERNEL);
0619     if (!priv) {
0620         error = -ENOMEM;
0621         goto fail;
0622     }
0623 
0624     spin_lock_init(&priv->lock);
0625     bio_list_init(&priv->list);
0626     ps3_system_bus_set_drvdata(dev, priv);
0627 
0628     /* Allocate XDR buffer (1MiB aligned) */
0629     priv->xdr_buf = (void *)__get_free_pages(GFP_KERNEL,
0630         get_order(XDR_BUF_SIZE));
0631     if (priv->xdr_buf == NULL) {
0632         dev_err(&dev->core, "Could not allocate XDR buffer\n");
0633         error = -ENOMEM;
0634         goto fail_free_priv;
0635     }
0636 
0637     /* Put FIFO at begginning of XDR buffer */
0638     priv->fifo_base = (u32 *) (priv->xdr_buf + FIFO_OFFSET);
0639     priv->fifo_ptr = priv->fifo_base;
0640 
0641     /* XXX: Need to open GPU, in case ps3fb or snd_ps3 aren't loaded */
0642     if (ps3_open_hv_device(dev)) {
0643         dev_err(&dev->core, "ps3_open_hv_device failed\n");
0644         error = -EAGAIN;
0645         goto out_free_xdr_buf;
0646     }
0647 
0648     /* Request memory */
0649     status = -1;
0650     ddr_size = ALIGN(memparse(size, &rest), 1024*1024);
0651     if (!ddr_size) {
0652         dev_err(&dev->core, "Specified size is too small\n");
0653         error = -EINVAL;
0654         goto out_close_gpu;
0655     }
0656 
0657     while (ddr_size > 0) {
0658         status = lv1_gpu_memory_allocate(ddr_size, 0, 0, 0, 0,
0659                          &priv->memory_handle,
0660                          &ddr_lpar);
0661         if (!status)
0662             break;
0663         ddr_size -= 1024*1024;
0664     }
0665     if (status) {
0666         dev_err(&dev->core, "lv1_gpu_memory_allocate failed %d\n",
0667             status);
0668         error = -ENOMEM;
0669         goto out_close_gpu;
0670     }
0671 
0672     /* Request context */
0673     status = lv1_gpu_context_allocate(priv->memory_handle, 0,
0674                       &priv->context_handle, &ctrl_lpar,
0675                       &info_lpar, &reports_lpar,
0676                       &reports_size);
0677     if (status) {
0678         dev_err(&dev->core, "lv1_gpu_context_allocate failed %d\n",
0679             status);
0680         error = -ENOMEM;
0681         goto out_free_memory;
0682     }
0683 
0684     /* Map XDR buffer to RSX */
0685     xdr_lpar = ps3_mm_phys_to_lpar(__pa(priv->xdr_buf));
0686     status = lv1_gpu_context_iomap(priv->context_handle, XDR_IOIF,
0687                        xdr_lpar, XDR_BUF_SIZE,
0688                        CBE_IOPTE_PP_W | CBE_IOPTE_PP_R |
0689                        CBE_IOPTE_M);
0690     if (status) {
0691         dev_err(&dev->core, "lv1_gpu_context_iomap failed %d\n",
0692             status);
0693         error = -ENOMEM;
0694         goto out_free_context;
0695     }
0696 
0697     priv->ctrl = ioremap(ctrl_lpar, 64 * 1024);
0698     if (!priv->ctrl) {
0699         dev_err(&dev->core, "ioremap CTRL failed\n");
0700         error = -ENOMEM;
0701         goto out_unmap_context;
0702     }
0703 
0704     priv->reports = ioremap(reports_lpar, reports_size);
0705     if (!priv->reports) {
0706         dev_err(&dev->core, "ioremap REPORTS failed\n");
0707         error = -ENOMEM;
0708         goto out_unmap_ctrl;
0709     }
0710 
0711     mutex_lock(&ps3_gpu_mutex);
0712     ps3vram_init_ring(dev);
0713     mutex_unlock(&ps3_gpu_mutex);
0714 
0715     priv->size = ddr_size;
0716 
0717     ps3vram_bind(dev);
0718 
0719     mutex_lock(&ps3_gpu_mutex);
0720     error = ps3vram_wait_ring(dev, 100);
0721     mutex_unlock(&ps3_gpu_mutex);
0722     if (error < 0) {
0723         dev_err(&dev->core, "Failed to initialize channels\n");
0724         error = -ETIMEDOUT;
0725         goto out_unmap_reports;
0726     }
0727 
0728     error = ps3vram_cache_init(dev);
0729     if (error < 0) {
0730         goto out_unmap_reports;
0731     }
0732 
0733     ps3vram_proc_init(dev);
0734 
0735     gendisk = blk_alloc_disk(NUMA_NO_NODE);
0736     if (!gendisk) {
0737         dev_err(&dev->core, "blk_alloc_disk failed\n");
0738         error = -ENOMEM;
0739         goto out_cache_cleanup;
0740     }
0741 
0742     priv->gendisk = gendisk;
0743     gendisk->major = ps3vram_major;
0744     gendisk->minors = 1;
0745     gendisk->flags |= GENHD_FL_NO_PART;
0746     gendisk->fops = &ps3vram_fops;
0747     gendisk->private_data = dev;
0748     strlcpy(gendisk->disk_name, DEVICE_NAME, sizeof(gendisk->disk_name));
0749     set_capacity(gendisk, priv->size >> 9);
0750     blk_queue_max_segments(gendisk->queue, BLK_MAX_SEGMENTS);
0751     blk_queue_max_segment_size(gendisk->queue, BLK_MAX_SEGMENT_SIZE);
0752     blk_queue_max_hw_sectors(gendisk->queue, BLK_SAFE_MAX_SECTORS);
0753 
0754     dev_info(&dev->core, "%s: Using %llu MiB of GPU memory\n",
0755          gendisk->disk_name, get_capacity(gendisk) >> 11);
0756 
0757     error = device_add_disk(&dev->core, gendisk, NULL);
0758     if (error)
0759         goto out_cleanup_disk;
0760 
0761     return 0;
0762 
0763 out_cleanup_disk:
0764     put_disk(gendisk);
0765 out_cache_cleanup:
0766     remove_proc_entry(DEVICE_NAME, NULL);
0767     ps3vram_cache_cleanup(dev);
0768 out_unmap_reports:
0769     iounmap(priv->reports);
0770 out_unmap_ctrl:
0771     iounmap(priv->ctrl);
0772 out_unmap_context:
0773     lv1_gpu_context_iomap(priv->context_handle, XDR_IOIF, xdr_lpar,
0774                   XDR_BUF_SIZE, CBE_IOPTE_M);
0775 out_free_context:
0776     lv1_gpu_context_free(priv->context_handle);
0777 out_free_memory:
0778     lv1_gpu_memory_free(priv->memory_handle);
0779 out_close_gpu:
0780     ps3_close_hv_device(dev);
0781 out_free_xdr_buf:
0782     free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE));
0783 fail_free_priv:
0784     kfree(priv);
0785     ps3_system_bus_set_drvdata(dev, NULL);
0786 fail:
0787     return error;
0788 }
0789 
0790 static void ps3vram_remove(struct ps3_system_bus_device *dev)
0791 {
0792     struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
0793 
0794     del_gendisk(priv->gendisk);
0795     put_disk(priv->gendisk);
0796     remove_proc_entry(DEVICE_NAME, NULL);
0797     ps3vram_cache_cleanup(dev);
0798     iounmap(priv->reports);
0799     iounmap(priv->ctrl);
0800     lv1_gpu_context_iomap(priv->context_handle, XDR_IOIF,
0801                   ps3_mm_phys_to_lpar(__pa(priv->xdr_buf)),
0802                   XDR_BUF_SIZE, CBE_IOPTE_M);
0803     lv1_gpu_context_free(priv->context_handle);
0804     lv1_gpu_memory_free(priv->memory_handle);
0805     ps3_close_hv_device(dev);
0806     free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE));
0807     kfree(priv);
0808     ps3_system_bus_set_drvdata(dev, NULL);
0809 }
0810 
0811 static struct ps3_system_bus_driver ps3vram = {
0812     .match_id   = PS3_MATCH_ID_GPU,
0813     .match_sub_id   = PS3_MATCH_SUB_ID_GPU_RAMDISK,
0814     .core.name  = DEVICE_NAME,
0815     .core.owner = THIS_MODULE,
0816     .probe      = ps3vram_probe,
0817     .remove     = ps3vram_remove,
0818     .shutdown   = ps3vram_remove,
0819 };
0820 
0821 
0822 static int __init ps3vram_init(void)
0823 {
0824     int error;
0825 
0826     if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
0827         return -ENODEV;
0828 
0829     error = register_blkdev(0, DEVICE_NAME);
0830     if (error <= 0) {
0831         pr_err("%s: register_blkdev failed %d\n", DEVICE_NAME, error);
0832         return error;
0833     }
0834     ps3vram_major = error;
0835 
0836     pr_info("%s: registered block device major %d\n", DEVICE_NAME,
0837         ps3vram_major);
0838 
0839     error = ps3_system_bus_driver_register(&ps3vram);
0840     if (error)
0841         unregister_blkdev(ps3vram_major, DEVICE_NAME);
0842 
0843     return error;
0844 }
0845 
0846 static void __exit ps3vram_exit(void)
0847 {
0848     ps3_system_bus_driver_unregister(&ps3vram);
0849     unregister_blkdev(ps3vram_major, DEVICE_NAME);
0850 }
0851 
0852 module_init(ps3vram_init);
0853 module_exit(ps3vram_exit);
0854 
0855 MODULE_LICENSE("GPL");
0856 MODULE_DESCRIPTION("PS3 Video RAM Storage Driver");
0857 MODULE_AUTHOR("Sony Corporation");
0858 MODULE_ALIAS(PS3_MODULE_ALIAS_GPU_RAMDISK);