linux/drivers/dma/fsl_raid.c
<<
>>
Prefs
   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 */
  86static 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 */
 105static 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
 135static 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
 142static 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
 157static 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 */
 203static 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
 233static 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
 240static 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
 251static 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
 272static 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
 316static 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 */
 391static 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 */
 403static 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 */
 526static 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
 573static 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
 603static 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
 624static 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
 739err_free_1:
 740        dma_pool_free(chan->re_dev->hw_desc_pool, chan->inb_ring_virt_addr,
 741                      chan->inb_phys_addr);
 742err_free:
 743        return ret;
 744}
 745
 746/* Probe function for RAID Engine */
 747static 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
 850static 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
 861static 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
 880static const struct of_device_id fsl_re_ids[] = {
 881        { .compatible = "fsl,raideng-v1.0", },
 882        {}
 883};
 884MODULE_DEVICE_TABLE(of, fsl_re_ids);
 885
 886static 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
 895module_platform_driver(fsl_re_driver);
 896
 897MODULE_AUTHOR("Harninder Rai <harninder.rai@freescale.com>");
 898MODULE_LICENSE("GPL v2");
 899MODULE_DESCRIPTION("Freescale RAID Engine Device Driver");
 900