root/drivers/dma/fsl_raid.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. fsl_re_tx_submit
  2. fsl_re_issue_pending
  3. fsl_re_desc_done
  4. fsl_re_cleanup_descs
  5. fsl_re_dequeue
  6. fsl_re_isr
  7. fsl_re_tx_status
  8. fill_cfd_frame
  9. fsl_re_init_desc
  10. fsl_re_chan_alloc_desc
  11. fsl_re_prep_dma_genq
  12. fsl_re_prep_dma_xor
  13. fsl_re_prep_dma_pq
  14. fsl_re_prep_dma_memcpy
  15. fsl_re_alloc_chan_resources
  16. fsl_re_free_chan_resources
  17. fsl_re_chan_probe
  18. fsl_re_probe
  19. fsl_re_remove_chan
  20. fsl_re_remove

   1 /*
   2  * drivers/dma/fsl_raid.c
   3  *
   4  * Freescale RAID Engine device driver
   5  *
   6  * Author:
   7  *      Harninder Rai <harninder.rai@freescale.com>
   8  *      Naveen Burmi <naveenburmi@freescale.com>
   9  *
  10  * Rewrite:
  11  *      Xuelin Shi <xuelin.shi@freescale.com>
  12  *
  13  * Copyright (c) 2010-2014 Freescale Semiconductor, Inc.
  14  *
  15  * Redistribution and use in source and binary forms, with or without
  16  * modification, are permitted provided that the following conditions are met:
  17  *     * Redistributions of source code must retain the above copyright
  18  *       notice, this list of conditions and the following disclaimer.
  19  *     * Redistributions in binary form must reproduce the above copyright
  20  *       notice, this list of conditions and the following disclaimer in the
  21  *       documentation and/or other materials provided with the distribution.
  22  *     * Neither the name of Freescale Semiconductor nor the
  23  *       names of its contributors may be used to endorse or promote products
  24  *       derived from this software without specific prior written permission.
  25  *
  26  * ALTERNATIVELY, this software may be distributed under the terms of the
  27  * GNU General Public License ("GPL") as published by the Free Software
  28  * Foundation, either version 2 of that License or (at your option) any
  29  * later version.
  30  *
  31  * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
  32  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  33  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  34  * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
  35  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  36  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  37  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  38  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  39  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  40  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  41  *
  42  * Theory of operation:
  43  *
  44  * General capabilities:
  45  *      RAID Engine (RE) block is capable of offloading XOR, memcpy and P/Q
  46  *      calculations required in RAID5 and RAID6 operations. RE driver
  47  *      registers with Linux's ASYNC layer as dma driver. RE hardware
  48  *      maintains strict ordering of the requests through chained
  49  *      command queueing.
  50  *
  51  * Data flow:
  52  *      Software RAID layer of Linux (MD layer) maintains RAID partitions,
  53  *      strips, stripes etc. It sends requests to the underlying ASYNC layer
  54  *      which further passes it to RE driver. ASYNC layer decides which request
  55  *      goes to which job ring of RE hardware. For every request processed by
  56  *      RAID Engine, driver gets an interrupt unless coalescing is set. The
  57  *      per job ring interrupt handler checks the status register for errors,
  58  *      clears the interrupt and leave the post interrupt processing to the irq
  59  *      thread.
  60  */
  61 #include <linux/interrupt.h>
  62 #include <linux/module.h>
  63 #include <linux/of_irq.h>
  64 #include <linux/of_address.h>
  65 #include <linux/of_platform.h>
  66 #include <linux/dma-mapping.h>
  67 #include <linux/dmapool.h>
  68 #include <linux/dmaengine.h>
  69 #include <linux/io.h>
  70 #include <linux/spinlock.h>
  71 #include <linux/slab.h>
  72 
  73 #include "dmaengine.h"
  74 #include "fsl_raid.h"
  75 
  76 #define FSL_RE_MAX_XOR_SRCS     16
  77 #define FSL_RE_MAX_PQ_SRCS      16
  78 #define FSL_RE_MIN_DESCS        256
  79 #define FSL_RE_MAX_DESCS        (4 * FSL_RE_MIN_DESCS)
  80 #define FSL_RE_FRAME_FORMAT     0x1
  81 #define FSL_RE_MAX_DATA_LEN     (1024*1024)
  82 
  83 #define to_fsl_re_dma_desc(tx) container_of(tx, struct fsl_re_desc, async_tx)
  84 
  85 /* Add descriptors into per chan software queue - submit_q */
  86 static dma_cookie_t fsl_re_tx_submit(struct dma_async_tx_descriptor *tx)
  87 {
  88         struct fsl_re_desc *desc;
  89         struct fsl_re_chan *re_chan;
  90         dma_cookie_t cookie;
  91         unsigned long flags;
  92 
  93         desc = to_fsl_re_dma_desc(tx);
  94         re_chan = container_of(tx->chan, struct fsl_re_chan, chan);
  95 
  96         spin_lock_irqsave(&re_chan->desc_lock, flags);
  97         cookie = dma_cookie_assign(tx);
  98         list_add_tail(&desc->node, &re_chan->submit_q);
  99         spin_unlock_irqrestore(&re_chan->desc_lock, flags);
 100 
 101         return cookie;
 102 }
 103 
 104 /* Copy descriptor from per chan software queue into hardware job ring */
 105 static void fsl_re_issue_pending(struct dma_chan *chan)
 106 {
 107         struct fsl_re_chan *re_chan;
 108         int avail;
 109         struct fsl_re_desc *desc, *_desc;
 110         unsigned long flags;
 111 
 112         re_chan = container_of(chan, struct fsl_re_chan, chan);
 113 
 114         spin_lock_irqsave(&re_chan->desc_lock, flags);
 115         avail = FSL_RE_SLOT_AVAIL(
 116                 in_be32(&re_chan->jrregs->inbring_slot_avail));
 117 
 118         list_for_each_entry_safe(desc, _desc, &re_chan->submit_q, node) {
 119                 if (!avail)
 120                         break;
 121 
 122                 list_move_tail(&desc->node, &re_chan->active_q);
 123 
 124                 memcpy(&re_chan->inb_ring_virt_addr[re_chan->inb_count],
 125                        &desc->hwdesc, sizeof(struct fsl_re_hw_desc));
 126 
 127                 re_chan->inb_count = (re_chan->inb_count + 1) &
 128                                                 FSL_RE_RING_SIZE_MASK;
 129                 out_be32(&re_chan->jrregs->inbring_add_job, FSL_RE_ADD_JOB(1));
 130                 avail--;
 131         }
 132         spin_unlock_irqrestore(&re_chan->desc_lock, flags);
 133 }
 134 
 135 static void fsl_re_desc_done(struct fsl_re_desc *desc)
 136 {
 137         dma_cookie_complete(&desc->async_tx);
 138         dma_descriptor_unmap(&desc->async_tx);
 139         dmaengine_desc_get_callback_invoke(&desc->async_tx, NULL);
 140 }
 141 
 142 static void fsl_re_cleanup_descs(struct fsl_re_chan *re_chan)
 143 {
 144         struct fsl_re_desc *desc, *_desc;
 145         unsigned long flags;
 146 
 147         spin_lock_irqsave(&re_chan->desc_lock, flags);
 148         list_for_each_entry_safe(desc, _desc, &re_chan->ack_q, node) {
 149                 if (async_tx_test_ack(&desc->async_tx))
 150                         list_move_tail(&desc->node, &re_chan->free_q);
 151         }
 152         spin_unlock_irqrestore(&re_chan->desc_lock, flags);
 153 
 154         fsl_re_issue_pending(&re_chan->chan);
 155 }
 156 
 157 static void fsl_re_dequeue(unsigned long data)
 158 {
 159         struct fsl_re_chan *re_chan;
 160         struct fsl_re_desc *desc, *_desc;
 161         struct fsl_re_hw_desc *hwdesc;
 162         unsigned long flags;
 163         unsigned int count, oub_count;
 164         int found;
 165 
 166         re_chan = dev_get_drvdata((struct device *)data);
 167 
 168         fsl_re_cleanup_descs(re_chan);
 169 
 170         spin_lock_irqsave(&re_chan->desc_lock, flags);
 171         count = FSL_RE_SLOT_FULL(in_be32(&re_chan->jrregs->oubring_slot_full));
 172         while (count--) {
 173                 found = 0;
 174                 hwdesc = &re_chan->oub_ring_virt_addr[re_chan->oub_count];
 175                 list_for_each_entry_safe(desc, _desc, &re_chan->active_q,
 176                                          node) {
 177                         /* compare the hw dma addr to find the completed */
 178                         if (desc->hwdesc.lbea32 == hwdesc->lbea32 &&
 179                             desc->hwdesc.addr_low == hwdesc->addr_low) {
 180                                 found = 1;
 181                                 break;
 182                         }
 183                 }
 184 
 185                 if (found) {
 186                         fsl_re_desc_done(desc);
 187                         list_move_tail(&desc->node, &re_chan->ack_q);
 188                 } else {
 189                         dev_err(re_chan->dev,
 190                                 "found hwdesc not in sw queue, discard it\n");
 191                 }
 192 
 193                 oub_count = (re_chan->oub_count + 1) & FSL_RE_RING_SIZE_MASK;
 194                 re_chan->oub_count = oub_count;
 195 
 196                 out_be32(&re_chan->jrregs->oubring_job_rmvd,
 197                          FSL_RE_RMVD_JOB(1));
 198         }
 199         spin_unlock_irqrestore(&re_chan->desc_lock, flags);
 200 }
 201 
 202 /* Per Job Ring interrupt handler */
 203 static irqreturn_t fsl_re_isr(int irq, void *data)
 204 {
 205         struct fsl_re_chan *re_chan;
 206         u32 irqstate, status;
 207 
 208         re_chan = dev_get_drvdata((struct device *)data);
 209 
 210         irqstate = in_be32(&re_chan->jrregs->jr_interrupt_status);
 211         if (!irqstate)
 212                 return IRQ_NONE;
 213 
 214         /*
 215          * There's no way in upper layer (read MD layer) to recover from
 216          * error conditions except restart everything. In long term we
 217          * need to do something more than just crashing
 218          */
 219         if (irqstate & FSL_RE_ERROR) {
 220                 status = in_be32(&re_chan->jrregs->jr_status);
 221                 dev_err(re_chan->dev, "chan error irqstate: %x, status: %x\n",
 222                         irqstate, status);
 223         }
 224 
 225         /* Clear interrupt */
 226         out_be32(&re_chan->jrregs->jr_interrupt_status, FSL_RE_CLR_INTR);
 227 
 228         tasklet_schedule(&re_chan->irqtask);
 229 
 230         return IRQ_HANDLED;
 231 }
 232 
 233 static enum dma_status fsl_re_tx_status(struct dma_chan *chan,
 234                                         dma_cookie_t cookie,
 235                                         struct dma_tx_state *txstate)
 236 {
 237         return dma_cookie_status(chan, cookie, txstate);
 238 }
 239 
 240 static void fill_cfd_frame(struct fsl_re_cmpnd_frame *cf, u8 index,
 241                            size_t length, dma_addr_t addr, bool final)
 242 {
 243         u32 efrl = length & FSL_RE_CF_LENGTH_MASK;
 244 
 245         efrl |= final << FSL_RE_CF_FINAL_SHIFT;
 246         cf[index].efrl32 = efrl;
 247         cf[index].addr_high = upper_32_bits(addr);
 248         cf[index].addr_low = lower_32_bits(addr);
 249 }
 250 
 251 static struct fsl_re_desc *fsl_re_init_desc(struct fsl_re_chan *re_chan,
 252                                             struct fsl_re_desc *desc,
 253                                             void *cf, dma_addr_t paddr)
 254 {
 255         desc->re_chan = re_chan;
 256         desc->async_tx.tx_submit = fsl_re_tx_submit;
 257         dma_async_tx_descriptor_init(&desc->async_tx, &re_chan->chan);
 258         INIT_LIST_HEAD(&desc->node);
 259 
 260         desc->hwdesc.fmt32 = FSL_RE_FRAME_FORMAT << FSL_RE_HWDESC_FMT_SHIFT;
 261         desc->hwdesc.lbea32 = upper_32_bits(paddr);
 262         desc->hwdesc.addr_low = lower_32_bits(paddr);
 263         desc->cf_addr = cf;
 264         desc->cf_paddr = paddr;
 265 
 266         desc->cdb_addr = (void *)(cf + FSL_RE_CF_DESC_SIZE);
 267         desc->cdb_paddr = paddr + FSL_RE_CF_DESC_SIZE;
 268 
 269         return desc;
 270 }
 271 
 272 static struct fsl_re_desc *fsl_re_chan_alloc_desc(struct fsl_re_chan *re_chan,
 273                                                   unsigned long flags)
 274 {
 275         struct fsl_re_desc *desc = NULL;
 276         void *cf;
 277         dma_addr_t paddr;
 278         unsigned long lock_flag;
 279 
 280         fsl_re_cleanup_descs(re_chan);
 281 
 282         spin_lock_irqsave(&re_chan->desc_lock, lock_flag);
 283         if (!list_empty(&re_chan->free_q)) {
 284                 /* take one desc from free_q */
 285                 desc = list_first_entry(&re_chan->free_q,
 286                                         struct fsl_re_desc, node);
 287                 list_del(&desc->node);
 288 
 289                 desc->async_tx.flags = flags;
 290         }
 291         spin_unlock_irqrestore(&re_chan->desc_lock, lock_flag);
 292 
 293         if (!desc) {
 294                 desc = kzalloc(sizeof(*desc), GFP_NOWAIT);
 295                 if (!desc)
 296                         return NULL;
 297 
 298                 cf = dma_pool_alloc(re_chan->re_dev->cf_desc_pool, GFP_NOWAIT,
 299                                     &paddr);
 300                 if (!cf) {
 301                         kfree(desc);
 302                         return NULL;
 303                 }
 304 
 305                 desc = fsl_re_init_desc(re_chan, desc, cf, paddr);
 306                 desc->async_tx.flags = flags;
 307 
 308                 spin_lock_irqsave(&re_chan->desc_lock, lock_flag);
 309                 re_chan->alloc_count++;
 310                 spin_unlock_irqrestore(&re_chan->desc_lock, lock_flag);
 311         }
 312 
 313         return desc;
 314 }
 315 
 316 static struct dma_async_tx_descriptor *fsl_re_prep_dma_genq(
 317                 struct dma_chan *chan, dma_addr_t dest, dma_addr_t *src,
 318                 unsigned int src_cnt, const unsigned char *scf, size_t len,
 319                 unsigned long flags)
 320 {
 321         struct fsl_re_chan *re_chan;
 322         struct fsl_re_desc *desc;
 323         struct fsl_re_xor_cdb *xor;
 324         struct fsl_re_cmpnd_frame *cf;
 325         u32 cdb;
 326         unsigned int i, j;
 327         unsigned int save_src_cnt = src_cnt;
 328         int cont_q = 0;
 329 
 330         re_chan = container_of(chan, struct fsl_re_chan, chan);
 331         if (len > FSL_RE_MAX_DATA_LEN) {
 332                 dev_err(re_chan->dev, "genq tx length %zu, max length %d\n",
 333                         len, FSL_RE_MAX_DATA_LEN);
 334                 return NULL;
 335         }
 336 
 337         desc = fsl_re_chan_alloc_desc(re_chan, flags);
 338         if (desc <= 0)
 339                 return NULL;
 340 
 341         if (scf && (flags & DMA_PREP_CONTINUE)) {
 342                 cont_q = 1;
 343                 src_cnt += 1;
 344         }
 345 
 346         /* Filling xor CDB */
 347         cdb = FSL_RE_XOR_OPCODE << FSL_RE_CDB_OPCODE_SHIFT;
 348         cdb |= (src_cnt - 1) << FSL_RE_CDB_NRCS_SHIFT;
 349         cdb |= FSL_RE_BLOCK_SIZE << FSL_RE_CDB_BLKSIZE_SHIFT;
 350         cdb |= FSL_RE_INTR_ON_ERROR << FSL_RE_CDB_ERROR_SHIFT;
 351         cdb |= FSL_RE_DATA_DEP << FSL_RE_CDB_DEPEND_SHIFT;
 352         xor = desc->cdb_addr;
 353         xor->cdb32 = cdb;
 354 
 355         if (scf) {
 356                 /* compute q = src0*coef0^src1*coef1^..., * is GF(8) mult */
 357                 for (i = 0; i < save_src_cnt; i++)
 358                         xor->gfm[i] = scf[i];
 359                 if (cont_q)
 360                         xor->gfm[i++] = 1;
 361         } else {
 362                 /* compute P, that is XOR all srcs */
 363                 for (i = 0; i < src_cnt; i++)
 364                         xor->gfm[i] = 1;
 365         }
 366 
 367         /* Filling frame 0 of compound frame descriptor with CDB */
 368         cf = desc->cf_addr;
 369         fill_cfd_frame(cf, 0, sizeof(*xor), desc->cdb_paddr, 0);
 370 
 371         /* Fill CFD's 1st frame with dest buffer */
 372         fill_cfd_frame(cf, 1, len, dest, 0);
 373 
 374         /* Fill CFD's rest of the frames with source buffers */
 375         for (i = 2, j = 0; j < save_src_cnt; i++, j++)
 376                 fill_cfd_frame(cf, i, len, src[j], 0);
 377 
 378         if (cont_q)
 379                 fill_cfd_frame(cf, i++, len, dest, 0);
 380 
 381         /* Setting the final bit in the last source buffer frame in CFD */
 382         cf[i - 1].efrl32 |= 1 << FSL_RE_CF_FINAL_SHIFT;
 383 
 384         return &desc->async_tx;
 385 }
 386 
 387 /*
 388  * Prep function for P parity calculation.In RAID Engine terminology,
 389  * XOR calculation is called GenQ calculation done through GenQ command
 390  */
 391 static struct dma_async_tx_descriptor *fsl_re_prep_dma_xor(
 392                 struct dma_chan *chan, dma_addr_t dest, dma_addr_t *src,
 393                 unsigned int src_cnt, size_t len, unsigned long flags)
 394 {
 395         /* NULL let genq take all coef as 1 */
 396         return fsl_re_prep_dma_genq(chan, dest, src, src_cnt, NULL, len, flags);
 397 }
 398 
 399 /*
 400  * Prep function for P/Q parity calculation.In RAID Engine terminology,
 401  * P/Q calculation is called GenQQ done through GenQQ command
 402  */
 403 static struct dma_async_tx_descriptor *fsl_re_prep_dma_pq(
 404                 struct dma_chan *chan, dma_addr_t *dest, dma_addr_t *src,
 405                 unsigned int src_cnt, const unsigned char *scf, size_t len,
 406                 unsigned long flags)
 407 {
 408         struct fsl_re_chan *re_chan;
 409         struct fsl_re_desc *desc;
 410         struct fsl_re_pq_cdb *pq;
 411         struct fsl_re_cmpnd_frame *cf;
 412         u32 cdb;
 413         u8 *p;
 414         int gfmq_len, i, j;
 415         unsigned int save_src_cnt = src_cnt;
 416 
 417         re_chan = container_of(chan, struct fsl_re_chan, chan);
 418         if (len > FSL_RE_MAX_DATA_LEN) {
 419                 dev_err(re_chan->dev, "pq tx length is %zu, max length is %d\n",
 420                         len, FSL_RE_MAX_DATA_LEN);
 421                 return NULL;
 422         }
 423 
 424         /*
 425          * RE requires at least 2 sources, if given only one source, we pass the
 426          * second source same as the first one.
 427          * With only one source, generating P is meaningless, only generate Q.
 428          */
 429         if (src_cnt == 1) {
 430                 struct dma_async_tx_descriptor *tx;
 431                 dma_addr_t dma_src[2];
 432                 unsigned char coef[2];
 433 
 434                 dma_src[0] = *src;
 435                 coef[0] = *scf;
 436                 dma_src[1] = *src;
 437                 coef[1] = 0;
 438                 tx = fsl_re_prep_dma_genq(chan, dest[1], dma_src, 2, coef, len,
 439                                           flags);
 440                 if (tx)
 441                         desc = to_fsl_re_dma_desc(tx);
 442 
 443                 return tx;
 444         }
 445 
 446         /*
 447          * During RAID6 array creation, Linux's MD layer gets P and Q
 448          * calculated separately in two steps. But our RAID Engine has
 449          * the capability to calculate both P and Q with a single command
 450          * Hence to merge well with MD layer, we need to provide a hook
 451          * here and call re_jq_prep_dma_genq() function
 452          */
 453 
 454         if (flags & DMA_PREP_PQ_DISABLE_P)
 455                 return fsl_re_prep_dma_genq(chan, dest[1], src, src_cnt,
 456                                 scf, len, flags);
 457 
 458         if (flags & DMA_PREP_CONTINUE)
 459                 src_cnt += 3;
 460 
 461         desc = fsl_re_chan_alloc_desc(re_chan, flags);
 462         if (desc <= 0)
 463                 return NULL;
 464 
 465         /* Filling GenQQ CDB */
 466         cdb = FSL_RE_PQ_OPCODE << FSL_RE_CDB_OPCODE_SHIFT;
 467         cdb |= (src_cnt - 1) << FSL_RE_CDB_NRCS_SHIFT;
 468         cdb |= FSL_RE_BLOCK_SIZE << FSL_RE_CDB_BLKSIZE_SHIFT;
 469         cdb |= FSL_RE_BUFFER_OUTPUT << FSL_RE_CDB_BUFFER_SHIFT;
 470         cdb |= FSL_RE_DATA_DEP << FSL_RE_CDB_DEPEND_SHIFT;
 471 
 472         pq = desc->cdb_addr;
 473         pq->cdb32 = cdb;
 474 
 475         p = pq->gfm_q1;
 476         /* Init gfm_q1[] */
 477         for (i = 0; i < src_cnt; i++)
 478                 p[i] = 1;
 479 
 480         /* Align gfm[] to 32bit */
 481         gfmq_len = ALIGN(src_cnt, 4);
 482 
 483         /* Init gfm_q2[] */
 484         p += gfmq_len;
 485         for (i = 0; i < src_cnt; i++)
 486                 p[i] = scf[i];
 487 
 488         /* Filling frame 0 of compound frame descriptor with CDB */
 489         cf = desc->cf_addr;
 490         fill_cfd_frame(cf, 0, sizeof(struct fsl_re_pq_cdb), desc->cdb_paddr, 0);
 491 
 492         /* Fill CFD's 1st & 2nd frame with dest buffers */
 493         for (i = 1, j = 0; i < 3; i++, j++)
 494                 fill_cfd_frame(cf, i, len, dest[j], 0);
 495 
 496         /* Fill CFD's rest of the frames with source buffers */
 497         for (i = 3, j = 0; j < save_src_cnt; i++, j++)
 498                 fill_cfd_frame(cf, i, len, src[j], 0);
 499 
 500         /* PQ computation continuation */
 501         if (flags & DMA_PREP_CONTINUE) {
 502                 if (src_cnt - save_src_cnt == 3) {
 503                         p[save_src_cnt] = 0;
 504                         p[save_src_cnt + 1] = 0;
 505                         p[save_src_cnt + 2] = 1;
 506                         fill_cfd_frame(cf, i++, len, dest[0], 0);
 507                         fill_cfd_frame(cf, i++, len, dest[1], 0);
 508                         fill_cfd_frame(cf, i++, len, dest[1], 0);
 509                 } else {
 510                         dev_err(re_chan->dev, "PQ tx continuation error!\n");
 511                         return NULL;
 512                 }
 513         }
 514 
 515         /* Setting the final bit in the last source buffer frame in CFD */
 516         cf[i - 1].efrl32 |= 1 << FSL_RE_CF_FINAL_SHIFT;
 517 
 518         return &desc->async_tx;
 519 }
 520 
 521 /*
 522  * Prep function for memcpy. In RAID Engine, memcpy is done through MOVE
 523  * command. Logic of this function will need to be modified once multipage
 524  * support is added in Linux's MD/ASYNC Layer
 525  */
 526 static struct dma_async_tx_descriptor *fsl_re_prep_dma_memcpy(
 527                 struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
 528                 size_t len, unsigned long flags)
 529 {
 530         struct fsl_re_chan *re_chan;
 531         struct fsl_re_desc *desc;
 532         size_t length;
 533         struct fsl_re_cmpnd_frame *cf;
 534         struct fsl_re_move_cdb *move;
 535         u32 cdb;
 536 
 537         re_chan = container_of(chan, struct fsl_re_chan, chan);
 538 
 539         if (len > FSL_RE_MAX_DATA_LEN) {
 540                 dev_err(re_chan->dev, "cp tx length is %zu, max length is %d\n",
 541                         len, FSL_RE_MAX_DATA_LEN);
 542                 return NULL;
 543         }
 544 
 545         desc = fsl_re_chan_alloc_desc(re_chan, flags);
 546         if (desc <= 0)
 547                 return NULL;
 548 
 549         /* Filling move CDB */
 550         cdb = FSL_RE_MOVE_OPCODE << FSL_RE_CDB_OPCODE_SHIFT;
 551         cdb |= FSL_RE_BLOCK_SIZE << FSL_RE_CDB_BLKSIZE_SHIFT;
 552         cdb |= FSL_RE_INTR_ON_ERROR << FSL_RE_CDB_ERROR_SHIFT;
 553         cdb |= FSL_RE_DATA_DEP << FSL_RE_CDB_DEPEND_SHIFT;
 554 
 555         move = desc->cdb_addr;
 556         move->cdb32 = cdb;
 557 
 558         /* Filling frame 0 of CFD with move CDB */
 559         cf = desc->cf_addr;
 560         fill_cfd_frame(cf, 0, sizeof(*move), desc->cdb_paddr, 0);
 561 
 562         length = min_t(size_t, len, FSL_RE_MAX_DATA_LEN);
 563 
 564         /* Fill CFD's 1st frame with dest buffer */
 565         fill_cfd_frame(cf, 1, length, dest, 0);
 566 
 567         /* Fill CFD's 2nd frame with src buffer */
 568         fill_cfd_frame(cf, 2, length, src, 1);
 569 
 570         return &desc->async_tx;
 571 }
 572 
 573 static int fsl_re_alloc_chan_resources(struct dma_chan *chan)
 574 {
 575         struct fsl_re_chan *re_chan;
 576         struct fsl_re_desc *desc;
 577         void *cf;
 578         dma_addr_t paddr;
 579         int i;
 580 
 581         re_chan = container_of(chan, struct fsl_re_chan, chan);
 582         for (i = 0; i < FSL_RE_MIN_DESCS; i++) {
 583                 desc = kzalloc(sizeof(*desc), GFP_KERNEL);
 584                 if (!desc)
 585                         break;
 586 
 587                 cf = dma_pool_alloc(re_chan->re_dev->cf_desc_pool, GFP_KERNEL,
 588                                     &paddr);
 589                 if (!cf) {
 590                         kfree(desc);
 591                         break;
 592                 }
 593 
 594                 INIT_LIST_HEAD(&desc->node);
 595                 fsl_re_init_desc(re_chan, desc, cf, paddr);
 596 
 597                 list_add_tail(&desc->node, &re_chan->free_q);
 598                 re_chan->alloc_count++;
 599         }
 600         return re_chan->alloc_count;
 601 }
 602 
 603 static void fsl_re_free_chan_resources(struct dma_chan *chan)
 604 {
 605         struct fsl_re_chan *re_chan;
 606         struct fsl_re_desc *desc;
 607 
 608         re_chan = container_of(chan, struct fsl_re_chan, chan);
 609         while (re_chan->alloc_count--) {
 610                 desc = list_first_entry(&re_chan->free_q,
 611                                         struct fsl_re_desc,
 612                                         node);
 613 
 614                 list_del(&desc->node);
 615                 dma_pool_free(re_chan->re_dev->cf_desc_pool, desc->cf_addr,
 616                               desc->cf_paddr);
 617                 kfree(desc);
 618         }
 619 
 620         if (!list_empty(&re_chan->free_q))
 621                 dev_err(re_chan->dev, "chan resource cannot be cleaned!\n");
 622 }
 623 
 624 static int fsl_re_chan_probe(struct platform_device *ofdev,
 625                       struct device_node *np, u8 q, u32 off)
 626 {
 627         struct device *dev, *chandev;
 628         struct fsl_re_drv_private *re_priv;
 629         struct fsl_re_chan *chan;
 630         struct dma_device *dma_dev;
 631         u32 ptr;
 632         u32 status;
 633         int ret = 0, rc;
 634         struct platform_device *chan_ofdev;
 635 
 636         dev = &ofdev->dev;
 637         re_priv = dev_get_drvdata(dev);
 638         dma_dev = &re_priv->dma_dev;
 639 
 640         chan = devm_kzalloc(dev, sizeof(*chan), GFP_KERNEL);
 641         if (!chan)
 642                 return -ENOMEM;
 643 
 644         /* create platform device for chan node */
 645         chan_ofdev = of_platform_device_create(np, NULL, dev);
 646         if (!chan_ofdev) {
 647                 dev_err(dev, "Not able to create ofdev for jr %d\n", q);
 648                 ret = -EINVAL;
 649                 goto err_free;
 650         }
 651 
 652         /* read reg property from dts */
 653         rc = of_property_read_u32(np, "reg", &ptr);
 654         if (rc) {
 655                 dev_err(dev, "Reg property not found in jr %d\n", q);
 656                 ret = -ENODEV;
 657                 goto err_free;
 658         }
 659 
 660         chan->jrregs = (struct fsl_re_chan_cfg *)((u8 *)re_priv->re_regs +
 661                         off + ptr);
 662 
 663         /* read irq property from dts */
 664         chan->irq = irq_of_parse_and_map(np, 0);
 665         if (!chan->irq) {
 666                 dev_err(dev, "No IRQ defined for JR %d\n", q);
 667                 ret = -ENODEV;
 668                 goto err_free;
 669         }
 670 
 671         snprintf(chan->name, sizeof(chan->name), "re_jr%02d", q);
 672 
 673         chandev = &chan_ofdev->dev;
 674         tasklet_init(&chan->irqtask, fsl_re_dequeue, (unsigned long)chandev);
 675 
 676         ret = request_irq(chan->irq, fsl_re_isr, 0, chan->name, chandev);
 677         if (ret) {
 678                 dev_err(dev, "Unable to register interrupt for JR %d\n", q);
 679                 ret = -EINVAL;
 680                 goto err_free;
 681         }
 682 
 683         re_priv->re_jrs[q] = chan;
 684         chan->chan.device = dma_dev;
 685         chan->chan.private = chan;
 686         chan->dev = chandev;
 687         chan->re_dev = re_priv;
 688 
 689         spin_lock_init(&chan->desc_lock);
 690         INIT_LIST_HEAD(&chan->ack_q);
 691         INIT_LIST_HEAD(&chan->active_q);
 692         INIT_LIST_HEAD(&chan->submit_q);
 693         INIT_LIST_HEAD(&chan->free_q);
 694 
 695         chan->inb_ring_virt_addr = dma_pool_alloc(chan->re_dev->hw_desc_pool,
 696                 GFP_KERNEL, &chan->inb_phys_addr);
 697         if (!chan->inb_ring_virt_addr) {
 698                 dev_err(dev, "No dma memory for inb_ring_virt_addr\n");
 699                 ret = -ENOMEM;
 700                 goto err_free;
 701         }
 702 
 703         chan->oub_ring_virt_addr = dma_pool_alloc(chan->re_dev->hw_desc_pool,
 704                 GFP_KERNEL, &chan->oub_phys_addr);
 705         if (!chan->oub_ring_virt_addr) {
 706                 dev_err(dev, "No dma memory for oub_ring_virt_addr\n");
 707                 ret = -ENOMEM;
 708                 goto err_free_1;
 709         }
 710 
 711         /* Program the Inbound/Outbound ring base addresses and size */
 712         out_be32(&chan->jrregs->inbring_base_h,
 713                  chan->inb_phys_addr & FSL_RE_ADDR_BIT_MASK);
 714         out_be32(&chan->jrregs->oubring_base_h,
 715                  chan->oub_phys_addr & FSL_RE_ADDR_BIT_MASK);
 716         out_be32(&chan->jrregs->inbring_base_l,
 717                  chan->inb_phys_addr >> FSL_RE_ADDR_BIT_SHIFT);
 718         out_be32(&chan->jrregs->oubring_base_l,
 719                  chan->oub_phys_addr >> FSL_RE_ADDR_BIT_SHIFT);
 720         out_be32(&chan->jrregs->inbring_size,
 721                  FSL_RE_RING_SIZE << FSL_RE_RING_SIZE_SHIFT);
 722         out_be32(&chan->jrregs->oubring_size,
 723                  FSL_RE_RING_SIZE << FSL_RE_RING_SIZE_SHIFT);
 724 
 725         /* Read LIODN value from u-boot */
 726         status = in_be32(&chan->jrregs->jr_config_1) & FSL_RE_REG_LIODN_MASK;
 727 
 728         /* Program the CFG reg */
 729         out_be32(&chan->jrregs->jr_config_1,
 730                  FSL_RE_CFG1_CBSI | FSL_RE_CFG1_CBS0 | status);
 731 
 732         dev_set_drvdata(chandev, chan);
 733 
 734         /* Enable RE/CHAN */
 735         out_be32(&chan->jrregs->jr_command, FSL_RE_ENABLE);
 736 
 737         return 0;
 738 
 739 err_free_1:
 740         dma_pool_free(chan->re_dev->hw_desc_pool, chan->inb_ring_virt_addr,
 741                       chan->inb_phys_addr);
 742 err_free:
 743         return ret;
 744 }
 745 
 746 /* Probe function for RAID Engine */
 747 static int fsl_re_probe(struct platform_device *ofdev)
 748 {
 749         struct fsl_re_drv_private *re_priv;
 750         struct device_node *np;
 751         struct device_node *child;
 752         u32 off;
 753         u8 ridx = 0;
 754         struct dma_device *dma_dev;
 755         struct resource *res;
 756         int rc;
 757         struct device *dev = &ofdev->dev;
 758 
 759         re_priv = devm_kzalloc(dev, sizeof(*re_priv), GFP_KERNEL);
 760         if (!re_priv)
 761                 return -ENOMEM;
 762 
 763         res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
 764         if (!res)
 765                 return -ENODEV;
 766 
 767         /* IOMAP the entire RAID Engine region */
 768         re_priv->re_regs = devm_ioremap(dev, res->start, resource_size(res));
 769         if (!re_priv->re_regs)
 770                 return -EBUSY;
 771 
 772         /* Program the RE mode */
 773         out_be32(&re_priv->re_regs->global_config, FSL_RE_NON_DPAA_MODE);
 774 
 775         /* Program Galois Field polynomial */
 776         out_be32(&re_priv->re_regs->galois_field_config, FSL_RE_GFM_POLY);
 777 
 778         dev_info(dev, "version %x, mode %x, gfp %x\n",
 779                  in_be32(&re_priv->re_regs->re_version_id),
 780                  in_be32(&re_priv->re_regs->global_config),
 781                  in_be32(&re_priv->re_regs->galois_field_config));
 782 
 783         dma_dev = &re_priv->dma_dev;
 784         dma_dev->dev = dev;
 785         INIT_LIST_HEAD(&dma_dev->channels);
 786         dma_set_mask(dev, DMA_BIT_MASK(40));
 787 
 788         dma_dev->device_alloc_chan_resources = fsl_re_alloc_chan_resources;
 789         dma_dev->device_tx_status = fsl_re_tx_status;
 790         dma_dev->device_issue_pending = fsl_re_issue_pending;
 791 
 792         dma_dev->max_xor = FSL_RE_MAX_XOR_SRCS;
 793         dma_dev->device_prep_dma_xor = fsl_re_prep_dma_xor;
 794         dma_cap_set(DMA_XOR, dma_dev->cap_mask);
 795 
 796         dma_dev->max_pq = FSL_RE_MAX_PQ_SRCS;
 797         dma_dev->device_prep_dma_pq = fsl_re_prep_dma_pq;
 798         dma_cap_set(DMA_PQ, dma_dev->cap_mask);
 799 
 800         dma_dev->device_prep_dma_memcpy = fsl_re_prep_dma_memcpy;
 801         dma_cap_set(DMA_MEMCPY, dma_dev->cap_mask);
 802 
 803         dma_dev->device_free_chan_resources = fsl_re_free_chan_resources;
 804 
 805         re_priv->total_chans = 0;
 806 
 807         re_priv->cf_desc_pool = dmam_pool_create("fsl_re_cf_desc_pool", dev,
 808                                         FSL_RE_CF_CDB_SIZE,
 809                                         FSL_RE_CF_CDB_ALIGN, 0);
 810 
 811         if (!re_priv->cf_desc_pool) {
 812                 dev_err(dev, "No memory for fsl re_cf desc pool\n");
 813                 return -ENOMEM;
 814         }
 815 
 816         re_priv->hw_desc_pool = dmam_pool_create("fsl_re_hw_desc_pool", dev,
 817                         sizeof(struct fsl_re_hw_desc) * FSL_RE_RING_SIZE,
 818                         FSL_RE_FRAME_ALIGN, 0);
 819         if (!re_priv->hw_desc_pool) {
 820                 dev_err(dev, "No memory for fsl re_hw desc pool\n");
 821                 return -ENOMEM;
 822         }
 823 
 824         dev_set_drvdata(dev, re_priv);
 825 
 826         /* Parse Device tree to find out the total number of JQs present */
 827         for_each_compatible_node(np, NULL, "fsl,raideng-v1.0-job-queue") {
 828                 rc = of_property_read_u32(np, "reg", &off);
 829                 if (rc) {
 830                         dev_err(dev, "Reg property not found in JQ node\n");
 831                         of_node_put(np);
 832                         return -ENODEV;
 833                 }
 834                 /* Find out the Job Rings present under each JQ */
 835                 for_each_child_of_node(np, child) {
 836                         rc = of_device_is_compatible(child,
 837                                              "fsl,raideng-v1.0-job-ring");
 838                         if (rc) {
 839                                 fsl_re_chan_probe(ofdev, child, ridx++, off);
 840                                 re_priv->total_chans++;
 841                         }
 842                 }
 843         }
 844 
 845         dma_async_device_register(dma_dev);
 846 
 847         return 0;
 848 }
 849 
 850 static void fsl_re_remove_chan(struct fsl_re_chan *chan)
 851 {
 852         tasklet_kill(&chan->irqtask);
 853 
 854         dma_pool_free(chan->re_dev->hw_desc_pool, chan->inb_ring_virt_addr,
 855                       chan->inb_phys_addr);
 856 
 857         dma_pool_free(chan->re_dev->hw_desc_pool, chan->oub_ring_virt_addr,
 858                       chan->oub_phys_addr);
 859 }
 860 
 861 static int fsl_re_remove(struct platform_device *ofdev)
 862 {
 863         struct fsl_re_drv_private *re_priv;
 864         struct device *dev;
 865         int i;
 866 
 867         dev = &ofdev->dev;
 868         re_priv = dev_get_drvdata(dev);
 869 
 870         /* Cleanup chan related memory areas */
 871         for (i = 0; i < re_priv->total_chans; i++)
 872                 fsl_re_remove_chan(re_priv->re_jrs[i]);
 873 
 874         /* Unregister the driver */
 875         dma_async_device_unregister(&re_priv->dma_dev);
 876 
 877         return 0;
 878 }
 879 
 880 static const struct of_device_id fsl_re_ids[] = {
 881         { .compatible = "fsl,raideng-v1.0", },
 882         {}
 883 };
 884 MODULE_DEVICE_TABLE(of, fsl_re_ids);
 885 
 886 static struct platform_driver fsl_re_driver = {
 887         .driver = {
 888                 .name = "fsl-raideng",
 889                 .of_match_table = fsl_re_ids,
 890         },
 891         .probe = fsl_re_probe,
 892         .remove = fsl_re_remove,
 893 };
 894 
 895 module_platform_driver(fsl_re_driver);
 896 
 897 MODULE_AUTHOR("Harninder Rai <harninder.rai@freescale.com>");
 898 MODULE_LICENSE("GPL v2");
 899 MODULE_DESCRIPTION("Freescale RAID Engine Device Driver");

/* [<][>][^][v][top][bottom][index][help] */