Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * DMM IOMMU driver support functions for TI OMAP processors.
0004  *
0005  * Copyright (C) 2011 Texas Instruments Incorporated - https://www.ti.com/
0006  * Author: Rob Clark <rob@ti.com>
0007  *         Andy Gross <andy.gross@ti.com>
0008  */
0009 
0010 #include <linux/completion.h>
0011 #include <linux/delay.h>
0012 #include <linux/dma-mapping.h>
0013 #include <linux/dmaengine.h>
0014 #include <linux/errno.h>
0015 #include <linux/init.h>
0016 #include <linux/interrupt.h>
0017 #include <linux/list.h>
0018 #include <linux/mm.h>
0019 #include <linux/module.h>
0020 #include <linux/of.h>
0021 #include <linux/platform_device.h> /* platform_device() */
0022 #include <linux/sched.h>
0023 #include <linux/seq_file.h>
0024 #include <linux/slab.h>
0025 #include <linux/time.h>
0026 #include <linux/vmalloc.h>
0027 #include <linux/wait.h>
0028 
0029 #include "omap_dmm_tiler.h"
0030 #include "omap_dmm_priv.h"
0031 
0032 #define DMM_DRIVER_NAME "dmm"
0033 
0034 /* mappings for associating views to luts */
0035 static struct tcm *containers[TILFMT_NFORMATS];
0036 static struct dmm *omap_dmm;
0037 
0038 #if defined(CONFIG_OF)
0039 static const struct of_device_id dmm_of_match[];
0040 #endif
0041 
0042 /* global spinlock for protecting lists */
0043 static DEFINE_SPINLOCK(list_lock);
0044 
0045 /* Geometry table */
0046 #define GEOM(xshift, yshift, bytes_per_pixel) { \
0047         .x_shft = (xshift), \
0048         .y_shft = (yshift), \
0049         .cpp    = (bytes_per_pixel), \
0050         .slot_w = 1 << (SLOT_WIDTH_BITS - (xshift)), \
0051         .slot_h = 1 << (SLOT_HEIGHT_BITS - (yshift)), \
0052     }
0053 
0054 static const struct {
0055     u32 x_shft; /* unused X-bits (as part of bpp) */
0056     u32 y_shft; /* unused Y-bits (as part of bpp) */
0057     u32 cpp;        /* bytes/chars per pixel */
0058     u32 slot_w; /* width of each slot (in pixels) */
0059     u32 slot_h; /* height of each slot (in pixels) */
0060 } geom[TILFMT_NFORMATS] = {
0061     [TILFMT_8BIT]  = GEOM(0, 0, 1),
0062     [TILFMT_16BIT] = GEOM(0, 1, 2),
0063     [TILFMT_32BIT] = GEOM(1, 1, 4),
0064     [TILFMT_PAGE]  = GEOM(SLOT_WIDTH_BITS, SLOT_HEIGHT_BITS, 1),
0065 };
0066 
0067 
0068 /* lookup table for registers w/ per-engine instances */
0069 static const u32 reg[][4] = {
0070     [PAT_STATUS] = {DMM_PAT_STATUS__0, DMM_PAT_STATUS__1,
0071             DMM_PAT_STATUS__2, DMM_PAT_STATUS__3},
0072     [PAT_DESCR]  = {DMM_PAT_DESCR__0, DMM_PAT_DESCR__1,
0073             DMM_PAT_DESCR__2, DMM_PAT_DESCR__3},
0074 };
0075 
0076 static int dmm_dma_copy(struct dmm *dmm, dma_addr_t src, dma_addr_t dst)
0077 {
0078     struct dma_async_tx_descriptor *tx;
0079     enum dma_status status;
0080     dma_cookie_t cookie;
0081 
0082     tx = dmaengine_prep_dma_memcpy(dmm->wa_dma_chan, dst, src, 4, 0);
0083     if (!tx) {
0084         dev_err(dmm->dev, "Failed to prepare DMA memcpy\n");
0085         return -EIO;
0086     }
0087 
0088     cookie = tx->tx_submit(tx);
0089     if (dma_submit_error(cookie)) {
0090         dev_err(dmm->dev, "Failed to do DMA tx_submit\n");
0091         return -EIO;
0092     }
0093 
0094     status = dma_sync_wait(dmm->wa_dma_chan, cookie);
0095     if (status != DMA_COMPLETE)
0096         dev_err(dmm->dev, "i878 wa DMA copy failure\n");
0097 
0098     dmaengine_terminate_all(dmm->wa_dma_chan);
0099     return 0;
0100 }
0101 
0102 static u32 dmm_read_wa(struct dmm *dmm, u32 reg)
0103 {
0104     dma_addr_t src, dst;
0105     int r;
0106 
0107     src = dmm->phys_base + reg;
0108     dst = dmm->wa_dma_handle;
0109 
0110     r = dmm_dma_copy(dmm, src, dst);
0111     if (r) {
0112         dev_err(dmm->dev, "sDMA read transfer timeout\n");
0113         return readl(dmm->base + reg);
0114     }
0115 
0116     /*
0117      * As per i878 workaround, the DMA is used to access the DMM registers.
0118      * Make sure that the readl is not moved by the compiler or the CPU
0119      * earlier than the DMA finished writing the value to memory.
0120      */
0121     rmb();
0122     return readl(dmm->wa_dma_data);
0123 }
0124 
0125 static void dmm_write_wa(struct dmm *dmm, u32 val, u32 reg)
0126 {
0127     dma_addr_t src, dst;
0128     int r;
0129 
0130     writel(val, dmm->wa_dma_data);
0131     /*
0132      * As per i878 workaround, the DMA is used to access the DMM registers.
0133      * Make sure that the writel is not moved by the compiler or the CPU, so
0134      * the data will be in place before we start the DMA to do the actual
0135      * register write.
0136      */
0137     wmb();
0138 
0139     src = dmm->wa_dma_handle;
0140     dst = dmm->phys_base + reg;
0141 
0142     r = dmm_dma_copy(dmm, src, dst);
0143     if (r) {
0144         dev_err(dmm->dev, "sDMA write transfer timeout\n");
0145         writel(val, dmm->base + reg);
0146     }
0147 }
0148 
0149 static u32 dmm_read(struct dmm *dmm, u32 reg)
0150 {
0151     if (dmm->dmm_workaround) {
0152         u32 v;
0153         unsigned long flags;
0154 
0155         spin_lock_irqsave(&dmm->wa_lock, flags);
0156         v = dmm_read_wa(dmm, reg);
0157         spin_unlock_irqrestore(&dmm->wa_lock, flags);
0158 
0159         return v;
0160     } else {
0161         return readl(dmm->base + reg);
0162     }
0163 }
0164 
0165 static void dmm_write(struct dmm *dmm, u32 val, u32 reg)
0166 {
0167     if (dmm->dmm_workaround) {
0168         unsigned long flags;
0169 
0170         spin_lock_irqsave(&dmm->wa_lock, flags);
0171         dmm_write_wa(dmm, val, reg);
0172         spin_unlock_irqrestore(&dmm->wa_lock, flags);
0173     } else {
0174         writel(val, dmm->base + reg);
0175     }
0176 }
0177 
0178 static int dmm_workaround_init(struct dmm *dmm)
0179 {
0180     dma_cap_mask_t mask;
0181 
0182     spin_lock_init(&dmm->wa_lock);
0183 
0184     dmm->wa_dma_data = dma_alloc_coherent(dmm->dev,  sizeof(u32),
0185                           &dmm->wa_dma_handle, GFP_KERNEL);
0186     if (!dmm->wa_dma_data)
0187         return -ENOMEM;
0188 
0189     dma_cap_zero(mask);
0190     dma_cap_set(DMA_MEMCPY, mask);
0191 
0192     dmm->wa_dma_chan = dma_request_channel(mask, NULL, NULL);
0193     if (!dmm->wa_dma_chan) {
0194         dma_free_coherent(dmm->dev, 4, dmm->wa_dma_data, dmm->wa_dma_handle);
0195         return -ENODEV;
0196     }
0197 
0198     return 0;
0199 }
0200 
0201 static void dmm_workaround_uninit(struct dmm *dmm)
0202 {
0203     dma_release_channel(dmm->wa_dma_chan);
0204 
0205     dma_free_coherent(dmm->dev, 4, dmm->wa_dma_data, dmm->wa_dma_handle);
0206 }
0207 
0208 /* simple allocator to grab next 16 byte aligned memory from txn */
0209 static void *alloc_dma(struct dmm_txn *txn, size_t sz, dma_addr_t *pa)
0210 {
0211     void *ptr;
0212     struct refill_engine *engine = txn->engine_handle;
0213 
0214     /* dmm programming requires 16 byte aligned addresses */
0215     txn->current_pa = round_up(txn->current_pa, 16);
0216     txn->current_va = (void *)round_up((long)txn->current_va, 16);
0217 
0218     ptr = txn->current_va;
0219     *pa = txn->current_pa;
0220 
0221     txn->current_pa += sz;
0222     txn->current_va += sz;
0223 
0224     BUG_ON((txn->current_va - engine->refill_va) > REFILL_BUFFER_SIZE);
0225 
0226     return ptr;
0227 }
0228 
0229 /* check status and spin until wait_mask comes true */
0230 static int wait_status(struct refill_engine *engine, u32 wait_mask)
0231 {
0232     struct dmm *dmm = engine->dmm;
0233     u32 r = 0, err, i;
0234 
0235     i = DMM_FIXED_RETRY_COUNT;
0236     while (true) {
0237         r = dmm_read(dmm, reg[PAT_STATUS][engine->id]);
0238         err = r & DMM_PATSTATUS_ERR;
0239         if (err) {
0240             dev_err(dmm->dev,
0241                 "%s: error (engine%d). PAT_STATUS: 0x%08x\n",
0242                 __func__, engine->id, r);
0243             return -EFAULT;
0244         }
0245 
0246         if ((r & wait_mask) == wait_mask)
0247             break;
0248 
0249         if (--i == 0) {
0250             dev_err(dmm->dev,
0251                 "%s: timeout (engine%d). PAT_STATUS: 0x%08x\n",
0252                 __func__, engine->id, r);
0253             return -ETIMEDOUT;
0254         }
0255 
0256         udelay(1);
0257     }
0258 
0259     return 0;
0260 }
0261 
0262 static void release_engine(struct refill_engine *engine)
0263 {
0264     unsigned long flags;
0265 
0266     spin_lock_irqsave(&list_lock, flags);
0267     list_add(&engine->idle_node, &omap_dmm->idle_head);
0268     spin_unlock_irqrestore(&list_lock, flags);
0269 
0270     atomic_inc(&omap_dmm->engine_counter);
0271     wake_up_interruptible(&omap_dmm->engine_queue);
0272 }
0273 
0274 static irqreturn_t omap_dmm_irq_handler(int irq, void *arg)
0275 {
0276     struct dmm *dmm = arg;
0277     u32 status = dmm_read(dmm, DMM_PAT_IRQSTATUS);
0278     int i;
0279 
0280     /* ack IRQ */
0281     dmm_write(dmm, status, DMM_PAT_IRQSTATUS);
0282 
0283     for (i = 0; i < dmm->num_engines; i++) {
0284         if (status & DMM_IRQSTAT_ERR_MASK)
0285             dev_err(dmm->dev,
0286                 "irq error(engine%d): IRQSTAT 0x%02x\n",
0287                 i, status & 0xff);
0288 
0289         if (status & DMM_IRQSTAT_LST) {
0290             if (dmm->engines[i].async)
0291                 release_engine(&dmm->engines[i]);
0292 
0293             complete(&dmm->engines[i].compl);
0294         }
0295 
0296         status >>= 8;
0297     }
0298 
0299     return IRQ_HANDLED;
0300 }
0301 
0302 /*
0303  * Get a handle for a DMM transaction
0304  */
0305 static struct dmm_txn *dmm_txn_init(struct dmm *dmm, struct tcm *tcm)
0306 {
0307     struct dmm_txn *txn = NULL;
0308     struct refill_engine *engine = NULL;
0309     int ret;
0310     unsigned long flags;
0311 
0312 
0313     /* wait until an engine is available */
0314     ret = wait_event_interruptible(omap_dmm->engine_queue,
0315         atomic_add_unless(&omap_dmm->engine_counter, -1, 0));
0316     if (ret)
0317         return ERR_PTR(ret);
0318 
0319     /* grab an idle engine */
0320     spin_lock_irqsave(&list_lock, flags);
0321     if (!list_empty(&dmm->idle_head)) {
0322         engine = list_entry(dmm->idle_head.next, struct refill_engine,
0323                     idle_node);
0324         list_del(&engine->idle_node);
0325     }
0326     spin_unlock_irqrestore(&list_lock, flags);
0327 
0328     BUG_ON(!engine);
0329 
0330     txn = &engine->txn;
0331     engine->tcm = tcm;
0332     txn->engine_handle = engine;
0333     txn->last_pat = NULL;
0334     txn->current_va = engine->refill_va;
0335     txn->current_pa = engine->refill_pa;
0336 
0337     return txn;
0338 }
0339 
0340 /*
0341  * Add region to DMM transaction.  If pages or pages[i] is NULL, then the
0342  * corresponding slot is cleared (ie. dummy_pa is programmed)
0343  */
0344 static void dmm_txn_append(struct dmm_txn *txn, struct pat_area *area,
0345         struct page **pages, u32 npages, u32 roll)
0346 {
0347     dma_addr_t pat_pa = 0, data_pa = 0;
0348     u32 *data;
0349     struct pat *pat;
0350     struct refill_engine *engine = txn->engine_handle;
0351     int columns = (1 + area->x1 - area->x0);
0352     int rows = (1 + area->y1 - area->y0);
0353     int i = columns*rows;
0354 
0355     pat = alloc_dma(txn, sizeof(*pat), &pat_pa);
0356 
0357     if (txn->last_pat)
0358         txn->last_pat->next_pa = (u32)pat_pa;
0359 
0360     pat->area = *area;
0361 
0362     /* adjust Y coordinates based off of container parameters */
0363     pat->area.y0 += engine->tcm->y_offset;
0364     pat->area.y1 += engine->tcm->y_offset;
0365 
0366     pat->ctrl = (struct pat_ctrl){
0367             .start = 1,
0368             .lut_id = engine->tcm->lut_id,
0369         };
0370 
0371     data = alloc_dma(txn, 4*i, &data_pa);
0372     /* FIXME: what if data_pa is more than 32-bit ? */
0373     pat->data_pa = data_pa;
0374 
0375     while (i--) {
0376         int n = i + roll;
0377         if (n >= npages)
0378             n -= npages;
0379         data[i] = (pages && pages[n]) ?
0380             page_to_phys(pages[n]) : engine->dmm->dummy_pa;
0381     }
0382 
0383     txn->last_pat = pat;
0384 
0385     return;
0386 }
0387 
0388 /*
0389  * Commit the DMM transaction.
0390  */
0391 static int dmm_txn_commit(struct dmm_txn *txn, bool wait)
0392 {
0393     int ret = 0;
0394     struct refill_engine *engine = txn->engine_handle;
0395     struct dmm *dmm = engine->dmm;
0396 
0397     if (!txn->last_pat) {
0398         dev_err(engine->dmm->dev, "need at least one txn\n");
0399         ret = -EINVAL;
0400         goto cleanup;
0401     }
0402 
0403     txn->last_pat->next_pa = 0;
0404     /* ensure that the written descriptors are visible to DMM */
0405     wmb();
0406 
0407     /*
0408      * NOTE: the wmb() above should be enough, but there seems to be a bug
0409      * in OMAP's memory barrier implementation, which in some rare cases may
0410      * cause the writes not to be observable after wmb().
0411      */
0412 
0413     /* read back to ensure the data is in RAM */
0414     readl(&txn->last_pat->next_pa);
0415 
0416     /* write to PAT_DESCR to clear out any pending transaction */
0417     dmm_write(dmm, 0x0, reg[PAT_DESCR][engine->id]);
0418 
0419     /* wait for engine ready: */
0420     ret = wait_status(engine, DMM_PATSTATUS_READY);
0421     if (ret) {
0422         ret = -EFAULT;
0423         goto cleanup;
0424     }
0425 
0426     /* mark whether it is async to denote list management in IRQ handler */
0427     engine->async = wait ? false : true;
0428     reinit_completion(&engine->compl);
0429     /* verify that the irq handler sees the 'async' and completion value */
0430     smp_mb();
0431 
0432     /* kick reload */
0433     dmm_write(dmm, engine->refill_pa, reg[PAT_DESCR][engine->id]);
0434 
0435     if (wait) {
0436         if (!wait_for_completion_timeout(&engine->compl,
0437                 msecs_to_jiffies(100))) {
0438             dev_err(dmm->dev, "timed out waiting for done\n");
0439             ret = -ETIMEDOUT;
0440             goto cleanup;
0441         }
0442 
0443         /* Check the engine status before continue */
0444         ret = wait_status(engine, DMM_PATSTATUS_READY |
0445                   DMM_PATSTATUS_VALID | DMM_PATSTATUS_DONE);
0446     }
0447 
0448 cleanup:
0449     /* only place engine back on list if we are done with it */
0450     if (ret || wait)
0451         release_engine(engine);
0452 
0453     return ret;
0454 }
0455 
0456 /*
0457  * DMM programming
0458  */
0459 static int fill(struct tcm_area *area, struct page **pages,
0460         u32 npages, u32 roll, bool wait)
0461 {
0462     int ret = 0;
0463     struct tcm_area slice, area_s;
0464     struct dmm_txn *txn;
0465 
0466     /*
0467      * FIXME
0468      *
0469      * Asynchronous fill does not work reliably, as the driver does not
0470      * handle errors in the async code paths. The fill operation may
0471      * silently fail, leading to leaking DMM engines, which may eventually
0472      * lead to deadlock if we run out of DMM engines.
0473      *
0474      * For now, always set 'wait' so that we only use sync fills. Async
0475      * fills should be fixed, or alternatively we could decide to only
0476      * support sync fills and so the whole async code path could be removed.
0477      */
0478 
0479     wait = true;
0480 
0481     txn = dmm_txn_init(omap_dmm, area->tcm);
0482     if (IS_ERR_OR_NULL(txn))
0483         return -ENOMEM;
0484 
0485     tcm_for_each_slice(slice, *area, area_s) {
0486         struct pat_area p_area = {
0487                 .x0 = slice.p0.x,  .y0 = slice.p0.y,
0488                 .x1 = slice.p1.x,  .y1 = slice.p1.y,
0489         };
0490 
0491         dmm_txn_append(txn, &p_area, pages, npages, roll);
0492 
0493         roll += tcm_sizeof(slice);
0494     }
0495 
0496     ret = dmm_txn_commit(txn, wait);
0497 
0498     return ret;
0499 }
0500 
0501 /*
0502  * Pin/unpin
0503  */
0504 
0505 /* note: slots for which pages[i] == NULL are filled w/ dummy page
0506  */
0507 int tiler_pin(struct tiler_block *block, struct page **pages,
0508         u32 npages, u32 roll, bool wait)
0509 {
0510     int ret;
0511 
0512     ret = fill(&block->area, pages, npages, roll, wait);
0513 
0514     if (ret)
0515         tiler_unpin(block);
0516 
0517     return ret;
0518 }
0519 
0520 int tiler_unpin(struct tiler_block *block)
0521 {
0522     return fill(&block->area, NULL, 0, 0, false);
0523 }
0524 
0525 /*
0526  * Reserve/release
0527  */
0528 struct tiler_block *tiler_reserve_2d(enum tiler_fmt fmt, u16 w,
0529         u16 h, u16 align)
0530 {
0531     struct tiler_block *block;
0532     u32 min_align = 128;
0533     int ret;
0534     unsigned long flags;
0535     u32 slot_bytes;
0536 
0537     block = kzalloc(sizeof(*block), GFP_KERNEL);
0538     if (!block)
0539         return ERR_PTR(-ENOMEM);
0540 
0541     BUG_ON(!validfmt(fmt));
0542 
0543     /* convert width/height to slots */
0544     w = DIV_ROUND_UP(w, geom[fmt].slot_w);
0545     h = DIV_ROUND_UP(h, geom[fmt].slot_h);
0546 
0547     /* convert alignment to slots */
0548     slot_bytes = geom[fmt].slot_w * geom[fmt].cpp;
0549     min_align = max(min_align, slot_bytes);
0550     align = (align > min_align) ? ALIGN(align, min_align) : min_align;
0551     align /= slot_bytes;
0552 
0553     block->fmt = fmt;
0554 
0555     ret = tcm_reserve_2d(containers[fmt], w, h, align, -1, slot_bytes,
0556             &block->area);
0557     if (ret) {
0558         kfree(block);
0559         return ERR_PTR(-ENOMEM);
0560     }
0561 
0562     /* add to allocation list */
0563     spin_lock_irqsave(&list_lock, flags);
0564     list_add(&block->alloc_node, &omap_dmm->alloc_head);
0565     spin_unlock_irqrestore(&list_lock, flags);
0566 
0567     return block;
0568 }
0569 
0570 struct tiler_block *tiler_reserve_1d(size_t size)
0571 {
0572     struct tiler_block *block = kzalloc(sizeof(*block), GFP_KERNEL);
0573     int num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
0574     unsigned long flags;
0575 
0576     if (!block)
0577         return ERR_PTR(-ENOMEM);
0578 
0579     block->fmt = TILFMT_PAGE;
0580 
0581     if (tcm_reserve_1d(containers[TILFMT_PAGE], num_pages,
0582                 &block->area)) {
0583         kfree(block);
0584         return ERR_PTR(-ENOMEM);
0585     }
0586 
0587     spin_lock_irqsave(&list_lock, flags);
0588     list_add(&block->alloc_node, &omap_dmm->alloc_head);
0589     spin_unlock_irqrestore(&list_lock, flags);
0590 
0591     return block;
0592 }
0593 
0594 /* note: if you have pin'd pages, you should have already unpin'd first! */
0595 int tiler_release(struct tiler_block *block)
0596 {
0597     int ret = tcm_free(&block->area);
0598     unsigned long flags;
0599 
0600     if (block->area.tcm)
0601         dev_err(omap_dmm->dev, "failed to release block\n");
0602 
0603     spin_lock_irqsave(&list_lock, flags);
0604     list_del(&block->alloc_node);
0605     spin_unlock_irqrestore(&list_lock, flags);
0606 
0607     kfree(block);
0608     return ret;
0609 }
0610 
0611 /*
0612  * Utils
0613  */
0614 
0615 /* calculate the tiler space address of a pixel in a view orientation...
0616  * below description copied from the display subsystem section of TRM:
0617  *
0618  * When the TILER is addressed, the bits:
0619  *   [28:27] = 0x0 for 8-bit tiled
0620  *             0x1 for 16-bit tiled
0621  *             0x2 for 32-bit tiled
0622  *             0x3 for page mode
0623  *   [31:29] = 0x0 for 0-degree view
0624  *             0x1 for 180-degree view + mirroring
0625  *             0x2 for 0-degree view + mirroring
0626  *             0x3 for 180-degree view
0627  *             0x4 for 270-degree view + mirroring
0628  *             0x5 for 270-degree view
0629  *             0x6 for 90-degree view
0630  *             0x7 for 90-degree view + mirroring
0631  * Otherwise the bits indicated the corresponding bit address to access
0632  * the SDRAM.
0633  */
0634 static u32 tiler_get_address(enum tiler_fmt fmt, u32 orient, u32 x, u32 y)
0635 {
0636     u32 x_bits, y_bits, tmp, x_mask, y_mask, alignment;
0637 
0638     x_bits = CONT_WIDTH_BITS - geom[fmt].x_shft;
0639     y_bits = CONT_HEIGHT_BITS - geom[fmt].y_shft;
0640     alignment = geom[fmt].x_shft + geom[fmt].y_shft;
0641 
0642     /* validate coordinate */
0643     x_mask = MASK(x_bits);
0644     y_mask = MASK(y_bits);
0645 
0646     if (x < 0 || x > x_mask || y < 0 || y > y_mask) {
0647         DBG("invalid coords: %u < 0 || %u > %u || %u < 0 || %u > %u",
0648                 x, x, x_mask, y, y, y_mask);
0649         return 0;
0650     }
0651 
0652     /* account for mirroring */
0653     if (orient & MASK_X_INVERT)
0654         x ^= x_mask;
0655     if (orient & MASK_Y_INVERT)
0656         y ^= y_mask;
0657 
0658     /* get coordinate address */
0659     if (orient & MASK_XY_FLIP)
0660         tmp = ((x << y_bits) + y);
0661     else
0662         tmp = ((y << x_bits) + x);
0663 
0664     return TIL_ADDR((tmp << alignment), orient, fmt);
0665 }
0666 
0667 dma_addr_t tiler_ssptr(struct tiler_block *block)
0668 {
0669     BUG_ON(!validfmt(block->fmt));
0670 
0671     return TILVIEW_8BIT + tiler_get_address(block->fmt, 0,
0672             block->area.p0.x * geom[block->fmt].slot_w,
0673             block->area.p0.y * geom[block->fmt].slot_h);
0674 }
0675 
0676 dma_addr_t tiler_tsptr(struct tiler_block *block, u32 orient,
0677         u32 x, u32 y)
0678 {
0679     struct tcm_pt *p = &block->area.p0;
0680     BUG_ON(!validfmt(block->fmt));
0681 
0682     return tiler_get_address(block->fmt, orient,
0683             (p->x * geom[block->fmt].slot_w) + x,
0684             (p->y * geom[block->fmt].slot_h) + y);
0685 }
0686 
0687 void tiler_align(enum tiler_fmt fmt, u16 *w, u16 *h)
0688 {
0689     BUG_ON(!validfmt(fmt));
0690     *w = round_up(*w, geom[fmt].slot_w);
0691     *h = round_up(*h, geom[fmt].slot_h);
0692 }
0693 
0694 u32 tiler_stride(enum tiler_fmt fmt, u32 orient)
0695 {
0696     BUG_ON(!validfmt(fmt));
0697 
0698     if (orient & MASK_XY_FLIP)
0699         return 1 << (CONT_HEIGHT_BITS + geom[fmt].x_shft);
0700     else
0701         return 1 << (CONT_WIDTH_BITS + geom[fmt].y_shft);
0702 }
0703 
0704 size_t tiler_size(enum tiler_fmt fmt, u16 w, u16 h)
0705 {
0706     tiler_align(fmt, &w, &h);
0707     return geom[fmt].cpp * w * h;
0708 }
0709 
0710 size_t tiler_vsize(enum tiler_fmt fmt, u16 w, u16 h)
0711 {
0712     BUG_ON(!validfmt(fmt));
0713     return round_up(geom[fmt].cpp * w, PAGE_SIZE) * h;
0714 }
0715 
0716 u32 tiler_get_cpu_cache_flags(void)
0717 {
0718     return omap_dmm->plat_data->cpu_cache_flags;
0719 }
0720 
0721 bool dmm_is_available(void)
0722 {
0723     return omap_dmm ? true : false;
0724 }
0725 
0726 static int omap_dmm_remove(struct platform_device *dev)
0727 {
0728     struct tiler_block *block, *_block;
0729     int i;
0730     unsigned long flags;
0731 
0732     if (omap_dmm) {
0733         /* Disable all enabled interrupts */
0734         dmm_write(omap_dmm, 0x7e7e7e7e, DMM_PAT_IRQENABLE_CLR);
0735         free_irq(omap_dmm->irq, omap_dmm);
0736 
0737         /* free all area regions */
0738         spin_lock_irqsave(&list_lock, flags);
0739         list_for_each_entry_safe(block, _block, &omap_dmm->alloc_head,
0740                     alloc_node) {
0741             list_del(&block->alloc_node);
0742             kfree(block);
0743         }
0744         spin_unlock_irqrestore(&list_lock, flags);
0745 
0746         for (i = 0; i < omap_dmm->num_lut; i++)
0747             if (omap_dmm->tcm && omap_dmm->tcm[i])
0748                 omap_dmm->tcm[i]->deinit(omap_dmm->tcm[i]);
0749         kfree(omap_dmm->tcm);
0750 
0751         kfree(omap_dmm->engines);
0752         if (omap_dmm->refill_va)
0753             dma_free_wc(omap_dmm->dev,
0754                     REFILL_BUFFER_SIZE * omap_dmm->num_engines,
0755                     omap_dmm->refill_va, omap_dmm->refill_pa);
0756         if (omap_dmm->dummy_page)
0757             __free_page(omap_dmm->dummy_page);
0758 
0759         if (omap_dmm->dmm_workaround)
0760             dmm_workaround_uninit(omap_dmm);
0761 
0762         iounmap(omap_dmm->base);
0763         kfree(omap_dmm);
0764         omap_dmm = NULL;
0765     }
0766 
0767     return 0;
0768 }
0769 
0770 static int omap_dmm_probe(struct platform_device *dev)
0771 {
0772     int ret = -EFAULT, i;
0773     struct tcm_area area = {0};
0774     u32 hwinfo, pat_geom;
0775     struct resource *mem;
0776 
0777     omap_dmm = kzalloc(sizeof(*omap_dmm), GFP_KERNEL);
0778     if (!omap_dmm)
0779         goto fail;
0780 
0781     /* initialize lists */
0782     INIT_LIST_HEAD(&omap_dmm->alloc_head);
0783     INIT_LIST_HEAD(&omap_dmm->idle_head);
0784 
0785     init_waitqueue_head(&omap_dmm->engine_queue);
0786 
0787     if (dev->dev.of_node) {
0788         const struct of_device_id *match;
0789 
0790         match = of_match_node(dmm_of_match, dev->dev.of_node);
0791         if (!match) {
0792             dev_err(&dev->dev, "failed to find matching device node\n");
0793             ret = -ENODEV;
0794             goto fail;
0795         }
0796 
0797         omap_dmm->plat_data = match->data;
0798     }
0799 
0800     /* lookup hwmod data - base address and irq */
0801     mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
0802     if (!mem) {
0803         dev_err(&dev->dev, "failed to get base address resource\n");
0804         goto fail;
0805     }
0806 
0807     omap_dmm->phys_base = mem->start;
0808     omap_dmm->base = ioremap(mem->start, SZ_2K);
0809 
0810     if (!omap_dmm->base) {
0811         dev_err(&dev->dev, "failed to get dmm base address\n");
0812         goto fail;
0813     }
0814 
0815     omap_dmm->irq = platform_get_irq(dev, 0);
0816     if (omap_dmm->irq < 0) {
0817         dev_err(&dev->dev, "failed to get IRQ resource\n");
0818         goto fail;
0819     }
0820 
0821     omap_dmm->dev = &dev->dev;
0822 
0823     if (of_machine_is_compatible("ti,dra7")) {
0824         /*
0825          * DRA7 Errata i878 says that MPU should not be used to access
0826          * RAM and DMM at the same time. As it's not possible to prevent
0827          * MPU accessing RAM, we need to access DMM via a proxy.
0828          */
0829         if (!dmm_workaround_init(omap_dmm)) {
0830             omap_dmm->dmm_workaround = true;
0831             dev_info(&dev->dev,
0832                 "workaround for errata i878 in use\n");
0833         } else {
0834             dev_warn(&dev->dev,
0835                  "failed to initialize work-around for i878\n");
0836         }
0837     }
0838 
0839     hwinfo = dmm_read(omap_dmm, DMM_PAT_HWINFO);
0840     omap_dmm->num_engines = (hwinfo >> 24) & 0x1F;
0841     omap_dmm->num_lut = (hwinfo >> 16) & 0x1F;
0842     omap_dmm->container_width = 256;
0843     omap_dmm->container_height = 128;
0844 
0845     atomic_set(&omap_dmm->engine_counter, omap_dmm->num_engines);
0846 
0847     /* read out actual LUT width and height */
0848     pat_geom = dmm_read(omap_dmm, DMM_PAT_GEOMETRY);
0849     omap_dmm->lut_width = ((pat_geom >> 16) & 0xF) << 5;
0850     omap_dmm->lut_height = ((pat_geom >> 24) & 0xF) << 5;
0851 
0852     /* increment LUT by one if on OMAP5 */
0853     /* LUT has twice the height, and is split into a separate container */
0854     if (omap_dmm->lut_height != omap_dmm->container_height)
0855         omap_dmm->num_lut++;
0856 
0857     /* initialize DMM registers */
0858     dmm_write(omap_dmm, 0x88888888, DMM_PAT_VIEW__0);
0859     dmm_write(omap_dmm, 0x88888888, DMM_PAT_VIEW__1);
0860     dmm_write(omap_dmm, 0x80808080, DMM_PAT_VIEW_MAP__0);
0861     dmm_write(omap_dmm, 0x80000000, DMM_PAT_VIEW_MAP_BASE);
0862     dmm_write(omap_dmm, 0x88888888, DMM_TILER_OR__0);
0863     dmm_write(omap_dmm, 0x88888888, DMM_TILER_OR__1);
0864 
0865     omap_dmm->dummy_page = alloc_page(GFP_KERNEL | __GFP_DMA32);
0866     if (!omap_dmm->dummy_page) {
0867         dev_err(&dev->dev, "could not allocate dummy page\n");
0868         ret = -ENOMEM;
0869         goto fail;
0870     }
0871 
0872     /* set dma mask for device */
0873     ret = dma_set_coherent_mask(&dev->dev, DMA_BIT_MASK(32));
0874     if (ret)
0875         goto fail;
0876 
0877     omap_dmm->dummy_pa = page_to_phys(omap_dmm->dummy_page);
0878 
0879     /* alloc refill memory */
0880     omap_dmm->refill_va = dma_alloc_wc(&dev->dev,
0881                        REFILL_BUFFER_SIZE * omap_dmm->num_engines,
0882                        &omap_dmm->refill_pa, GFP_KERNEL);
0883     if (!omap_dmm->refill_va) {
0884         dev_err(&dev->dev, "could not allocate refill memory\n");
0885         ret = -ENOMEM;
0886         goto fail;
0887     }
0888 
0889     /* alloc engines */
0890     omap_dmm->engines = kcalloc(omap_dmm->num_engines,
0891                     sizeof(*omap_dmm->engines), GFP_KERNEL);
0892     if (!omap_dmm->engines) {
0893         ret = -ENOMEM;
0894         goto fail;
0895     }
0896 
0897     for (i = 0; i < omap_dmm->num_engines; i++) {
0898         omap_dmm->engines[i].id = i;
0899         omap_dmm->engines[i].dmm = omap_dmm;
0900         omap_dmm->engines[i].refill_va = omap_dmm->refill_va +
0901                         (REFILL_BUFFER_SIZE * i);
0902         omap_dmm->engines[i].refill_pa = omap_dmm->refill_pa +
0903                         (REFILL_BUFFER_SIZE * i);
0904         init_completion(&omap_dmm->engines[i].compl);
0905 
0906         list_add(&omap_dmm->engines[i].idle_node, &omap_dmm->idle_head);
0907     }
0908 
0909     omap_dmm->tcm = kcalloc(omap_dmm->num_lut, sizeof(*omap_dmm->tcm),
0910                 GFP_KERNEL);
0911     if (!omap_dmm->tcm) {
0912         ret = -ENOMEM;
0913         goto fail;
0914     }
0915 
0916     /* init containers */
0917     /* Each LUT is associated with a TCM (container manager).  We use the
0918        lut_id to denote the lut_id used to identify the correct LUT for
0919        programming during reill operations */
0920     for (i = 0; i < omap_dmm->num_lut; i++) {
0921         omap_dmm->tcm[i] = sita_init(omap_dmm->container_width,
0922                         omap_dmm->container_height);
0923 
0924         if (!omap_dmm->tcm[i]) {
0925             dev_err(&dev->dev, "failed to allocate container\n");
0926             ret = -ENOMEM;
0927             goto fail;
0928         }
0929 
0930         omap_dmm->tcm[i]->lut_id = i;
0931     }
0932 
0933     /* assign access mode containers to applicable tcm container */
0934     /* OMAP 4 has 1 container for all 4 views */
0935     /* OMAP 5 has 2 containers, 1 for 2D and 1 for 1D */
0936     containers[TILFMT_8BIT] = omap_dmm->tcm[0];
0937     containers[TILFMT_16BIT] = omap_dmm->tcm[0];
0938     containers[TILFMT_32BIT] = omap_dmm->tcm[0];
0939 
0940     if (omap_dmm->container_height != omap_dmm->lut_height) {
0941         /* second LUT is used for PAGE mode.  Programming must use
0942            y offset that is added to all y coordinates.  LUT id is still
0943            0, because it is the same LUT, just the upper 128 lines */
0944         containers[TILFMT_PAGE] = omap_dmm->tcm[1];
0945         omap_dmm->tcm[1]->y_offset = OMAP5_LUT_OFFSET;
0946         omap_dmm->tcm[1]->lut_id = 0;
0947     } else {
0948         containers[TILFMT_PAGE] = omap_dmm->tcm[0];
0949     }
0950 
0951     area = (struct tcm_area) {
0952         .tcm = NULL,
0953         .p1.x = omap_dmm->container_width - 1,
0954         .p1.y = omap_dmm->container_height - 1,
0955     };
0956 
0957     ret = request_irq(omap_dmm->irq, omap_dmm_irq_handler, IRQF_SHARED,
0958                 "omap_dmm_irq_handler", omap_dmm);
0959 
0960     if (ret) {
0961         dev_err(&dev->dev, "couldn't register IRQ %d, error %d\n",
0962             omap_dmm->irq, ret);
0963         omap_dmm->irq = -1;
0964         goto fail;
0965     }
0966 
0967     /* Enable all interrupts for each refill engine except
0968      * ERR_LUT_MISS<n> (which is just advisory, and we don't care
0969      * about because we want to be able to refill live scanout
0970      * buffers for accelerated pan/scroll) and FILL_DSC<n> which
0971      * we just generally don't care about.
0972      */
0973     dmm_write(omap_dmm, 0x7e7e7e7e, DMM_PAT_IRQENABLE_SET);
0974 
0975     /* initialize all LUTs to dummy page entries */
0976     for (i = 0; i < omap_dmm->num_lut; i++) {
0977         area.tcm = omap_dmm->tcm[i];
0978         if (fill(&area, NULL, 0, 0, true))
0979             dev_err(omap_dmm->dev, "refill failed");
0980     }
0981 
0982     dev_info(omap_dmm->dev, "initialized all PAT entries\n");
0983 
0984     return 0;
0985 
0986 fail:
0987     if (omap_dmm_remove(dev))
0988         dev_err(&dev->dev, "cleanup failed\n");
0989     return ret;
0990 }
0991 
0992 /*
0993  * debugfs support
0994  */
0995 
0996 #ifdef CONFIG_DEBUG_FS
0997 
0998 static const char *alphabet = "abcdefghijklmnopqrstuvwxyz"
0999                 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
1000 static const char *special = ".,:;'\"`~!^-+";
1001 
1002 static void fill_map(char **map, int xdiv, int ydiv, struct tcm_area *a,
1003                             char c, bool ovw)
1004 {
1005     int x, y;
1006     for (y = a->p0.y / ydiv; y <= a->p1.y / ydiv; y++)
1007         for (x = a->p0.x / xdiv; x <= a->p1.x / xdiv; x++)
1008             if (map[y][x] == ' ' || ovw)
1009                 map[y][x] = c;
1010 }
1011 
1012 static void fill_map_pt(char **map, int xdiv, int ydiv, struct tcm_pt *p,
1013                                     char c)
1014 {
1015     map[p->y / ydiv][p->x / xdiv] = c;
1016 }
1017 
1018 static char read_map_pt(char **map, int xdiv, int ydiv, struct tcm_pt *p)
1019 {
1020     return map[p->y / ydiv][p->x / xdiv];
1021 }
1022 
1023 static int map_width(int xdiv, int x0, int x1)
1024 {
1025     return (x1 / xdiv) - (x0 / xdiv) + 1;
1026 }
1027 
1028 static void text_map(char **map, int xdiv, char *nice, int yd, int x0, int x1)
1029 {
1030     char *p = map[yd] + (x0 / xdiv);
1031     int w = (map_width(xdiv, x0, x1) - strlen(nice)) / 2;
1032     if (w >= 0) {
1033         p += w;
1034         while (*nice)
1035             *p++ = *nice++;
1036     }
1037 }
1038 
1039 static void map_1d_info(char **map, int xdiv, int ydiv, char *nice,
1040                             struct tcm_area *a)
1041 {
1042     sprintf(nice, "%dK", tcm_sizeof(*a) * 4);
1043     if (a->p0.y + 1 < a->p1.y) {
1044         text_map(map, xdiv, nice, (a->p0.y + a->p1.y) / 2 / ydiv, 0,
1045                             256 - 1);
1046     } else if (a->p0.y < a->p1.y) {
1047         if (strlen(nice) < map_width(xdiv, a->p0.x, 256 - 1))
1048             text_map(map, xdiv, nice, a->p0.y / ydiv,
1049                     a->p0.x + xdiv, 256 - 1);
1050         else if (strlen(nice) < map_width(xdiv, 0, a->p1.x))
1051             text_map(map, xdiv, nice, a->p1.y / ydiv,
1052                     0, a->p1.y - xdiv);
1053     } else if (strlen(nice) + 1 < map_width(xdiv, a->p0.x, a->p1.x)) {
1054         text_map(map, xdiv, nice, a->p0.y / ydiv, a->p0.x, a->p1.x);
1055     }
1056 }
1057 
1058 static void map_2d_info(char **map, int xdiv, int ydiv, char *nice,
1059                             struct tcm_area *a)
1060 {
1061     sprintf(nice, "(%d*%d)", tcm_awidth(*a), tcm_aheight(*a));
1062     if (strlen(nice) + 1 < map_width(xdiv, a->p0.x, a->p1.x))
1063         text_map(map, xdiv, nice, (a->p0.y + a->p1.y) / 2 / ydiv,
1064                             a->p0.x, a->p1.x);
1065 }
1066 
1067 int tiler_map_show(struct seq_file *s, void *arg)
1068 {
1069     int xdiv = 2, ydiv = 1;
1070     char **map = NULL, *global_map;
1071     struct tiler_block *block;
1072     struct tcm_area a, p;
1073     int i;
1074     const char *m2d = alphabet;
1075     const char *a2d = special;
1076     const char *m2dp = m2d, *a2dp = a2d;
1077     char nice[128];
1078     int h_adj;
1079     int w_adj;
1080     unsigned long flags;
1081     int lut_idx;
1082 
1083 
1084     if (!omap_dmm) {
1085         /* early return if dmm/tiler device is not initialized */
1086         return 0;
1087     }
1088 
1089     h_adj = omap_dmm->container_height / ydiv;
1090     w_adj = omap_dmm->container_width / xdiv;
1091 
1092     map = kmalloc_array(h_adj, sizeof(*map), GFP_KERNEL);
1093     global_map = kmalloc_array(w_adj + 1, h_adj, GFP_KERNEL);
1094 
1095     if (!map || !global_map)
1096         goto error;
1097 
1098     for (lut_idx = 0; lut_idx < omap_dmm->num_lut; lut_idx++) {
1099         memset(map, 0, h_adj * sizeof(*map));
1100         memset(global_map, ' ', (w_adj + 1) * h_adj);
1101 
1102         for (i = 0; i < omap_dmm->container_height; i++) {
1103             map[i] = global_map + i * (w_adj + 1);
1104             map[i][w_adj] = 0;
1105         }
1106 
1107         spin_lock_irqsave(&list_lock, flags);
1108 
1109         list_for_each_entry(block, &omap_dmm->alloc_head, alloc_node) {
1110             if (block->area.tcm == omap_dmm->tcm[lut_idx]) {
1111                 if (block->fmt != TILFMT_PAGE) {
1112                     fill_map(map, xdiv, ydiv, &block->area,
1113                         *m2dp, true);
1114                     if (!*++a2dp)
1115                         a2dp = a2d;
1116                     if (!*++m2dp)
1117                         m2dp = m2d;
1118                     map_2d_info(map, xdiv, ydiv, nice,
1119                             &block->area);
1120                 } else {
1121                     bool start = read_map_pt(map, xdiv,
1122                         ydiv, &block->area.p0) == ' ';
1123                     bool end = read_map_pt(map, xdiv, ydiv,
1124                             &block->area.p1) == ' ';
1125 
1126                     tcm_for_each_slice(a, block->area, p)
1127                         fill_map(map, xdiv, ydiv, &a,
1128                             '=', true);
1129                     fill_map_pt(map, xdiv, ydiv,
1130                             &block->area.p0,
1131                             start ? '<' : 'X');
1132                     fill_map_pt(map, xdiv, ydiv,
1133                             &block->area.p1,
1134                             end ? '>' : 'X');
1135                     map_1d_info(map, xdiv, ydiv, nice,
1136                             &block->area);
1137                 }
1138             }
1139         }
1140 
1141         spin_unlock_irqrestore(&list_lock, flags);
1142 
1143         if (s) {
1144             seq_printf(s, "CONTAINER %d DUMP BEGIN\n", lut_idx);
1145             for (i = 0; i < 128; i++)
1146                 seq_printf(s, "%03d:%s\n", i, map[i]);
1147             seq_printf(s, "CONTAINER %d DUMP END\n", lut_idx);
1148         } else {
1149             dev_dbg(omap_dmm->dev, "CONTAINER %d DUMP BEGIN\n",
1150                 lut_idx);
1151             for (i = 0; i < 128; i++)
1152                 dev_dbg(omap_dmm->dev, "%03d:%s\n", i, map[i]);
1153             dev_dbg(omap_dmm->dev, "CONTAINER %d DUMP END\n",
1154                 lut_idx);
1155         }
1156     }
1157 
1158 error:
1159     kfree(map);
1160     kfree(global_map);
1161 
1162     return 0;
1163 }
1164 #endif
1165 
1166 #ifdef CONFIG_PM_SLEEP
1167 static int omap_dmm_resume(struct device *dev)
1168 {
1169     struct tcm_area area;
1170     int i;
1171 
1172     if (!omap_dmm)
1173         return -ENODEV;
1174 
1175     area = (struct tcm_area) {
1176         .tcm = NULL,
1177         .p1.x = omap_dmm->container_width - 1,
1178         .p1.y = omap_dmm->container_height - 1,
1179     };
1180 
1181     /* initialize all LUTs to dummy page entries */
1182     for (i = 0; i < omap_dmm->num_lut; i++) {
1183         area.tcm = omap_dmm->tcm[i];
1184         if (fill(&area, NULL, 0, 0, true))
1185             dev_err(dev, "refill failed");
1186     }
1187 
1188     return 0;
1189 }
1190 #endif
1191 
1192 static SIMPLE_DEV_PM_OPS(omap_dmm_pm_ops, NULL, omap_dmm_resume);
1193 
1194 #if defined(CONFIG_OF)
1195 static const struct dmm_platform_data dmm_omap4_platform_data = {
1196     .cpu_cache_flags = OMAP_BO_WC,
1197 };
1198 
1199 static const struct dmm_platform_data dmm_omap5_platform_data = {
1200     .cpu_cache_flags = OMAP_BO_UNCACHED,
1201 };
1202 
1203 static const struct of_device_id dmm_of_match[] = {
1204     {
1205         .compatible = "ti,omap4-dmm",
1206         .data = &dmm_omap4_platform_data,
1207     },
1208     {
1209         .compatible = "ti,omap5-dmm",
1210         .data = &dmm_omap5_platform_data,
1211     },
1212     {},
1213 };
1214 #endif
1215 
1216 struct platform_driver omap_dmm_driver = {
1217     .probe = omap_dmm_probe,
1218     .remove = omap_dmm_remove,
1219     .driver = {
1220         .owner = THIS_MODULE,
1221         .name = DMM_DRIVER_NAME,
1222         .of_match_table = of_match_ptr(dmm_of_match),
1223         .pm = &omap_dmm_pm_ops,
1224     },
1225 };
1226 
1227 MODULE_LICENSE("GPL v2");
1228 MODULE_AUTHOR("Andy Gross <andy.gross@ti.com>");
1229 MODULE_DESCRIPTION("OMAP DMM/Tiler Driver");