linux/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_layer.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2014 Free Electrons
   3 * Copyright (C) 2014 Atmel
   4 *
   5 * Author: Boris BREZILLON <boris.brezillon@free-electrons.com>
   6 *
   7 * This program is free software; you can redistribute it and/or modify it
   8 * under the terms of the GNU General Public License version 2 as published by
   9 * the Free Software Foundation.
  10 *
  11 * This program is distributed in the hope that it will be useful, but WITHOUT
  12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  14 * more details.
  15 *
  16 * You should have received a copy of the GNU General Public License along with
  17 * this program.  If not, see <http://www.gnu.org/licenses/>.
  18 */
  19
  20#include <linux/dma-mapping.h>
  21#include <linux/interrupt.h>
  22
  23#include "atmel_hlcdc_dc.h"
  24
  25static void
  26atmel_hlcdc_layer_fb_flip_release(struct drm_flip_work *work, void *val)
  27{
  28        struct atmel_hlcdc_layer_fb_flip *flip = val;
  29
  30        if (flip->fb)
  31                drm_framebuffer_unreference(flip->fb);
  32        kfree(flip);
  33}
  34
  35static void
  36atmel_hlcdc_layer_fb_flip_destroy(struct atmel_hlcdc_layer_fb_flip *flip)
  37{
  38        if (flip->fb)
  39                drm_framebuffer_unreference(flip->fb);
  40        kfree(flip->task);
  41        kfree(flip);
  42}
  43
  44static void
  45atmel_hlcdc_layer_fb_flip_release_queue(struct atmel_hlcdc_layer *layer,
  46                                        struct atmel_hlcdc_layer_fb_flip *flip)
  47{
  48        int i;
  49
  50        if (!flip)
  51                return;
  52
  53        for (i = 0; i < layer->max_planes; i++) {
  54                if (!flip->dscrs[i])
  55                        break;
  56
  57                flip->dscrs[i]->status = 0;
  58                flip->dscrs[i] = NULL;
  59        }
  60
  61        drm_flip_work_queue_task(&layer->gc, flip->task);
  62        drm_flip_work_commit(&layer->gc, layer->wq);
  63}
  64
  65static void atmel_hlcdc_layer_update_reset(struct atmel_hlcdc_layer *layer,
  66                                           int id)
  67{
  68        struct atmel_hlcdc_layer_update *upd = &layer->update;
  69        struct atmel_hlcdc_layer_update_slot *slot;
  70
  71        if (id < 0 || id > 1)
  72                return;
  73
  74        slot = &upd->slots[id];
  75        bitmap_clear(slot->updated_configs, 0, layer->desc->nconfigs);
  76        memset(slot->configs, 0,
  77               sizeof(*slot->configs) * layer->desc->nconfigs);
  78
  79        if (slot->fb_flip) {
  80                atmel_hlcdc_layer_fb_flip_release_queue(layer, slot->fb_flip);
  81                slot->fb_flip = NULL;
  82        }
  83}
  84
  85static void atmel_hlcdc_layer_update_apply(struct atmel_hlcdc_layer *layer)
  86{
  87        struct atmel_hlcdc_layer_dma_channel *dma = &layer->dma;
  88        const struct atmel_hlcdc_layer_desc *desc = layer->desc;
  89        struct atmel_hlcdc_layer_update *upd = &layer->update;
  90        struct regmap *regmap = layer->hlcdc->regmap;
  91        struct atmel_hlcdc_layer_update_slot *slot;
  92        struct atmel_hlcdc_layer_fb_flip *fb_flip;
  93        struct atmel_hlcdc_dma_channel_dscr *dscr;
  94        unsigned int cfg;
  95        u32 action = 0;
  96        int i = 0;
  97
  98        if (upd->pending < 0 || upd->pending > 1)
  99                return;
 100
 101        slot = &upd->slots[upd->pending];
 102
 103        for_each_set_bit(cfg, slot->updated_configs, layer->desc->nconfigs) {
 104                regmap_write(regmap,
 105                             desc->regs_offset +
 106                             ATMEL_HLCDC_LAYER_CFG(layer, cfg),
 107                             slot->configs[cfg]);
 108                action |= ATMEL_HLCDC_LAYER_UPDATE;
 109        }
 110
 111        fb_flip = slot->fb_flip;
 112
 113        if (!fb_flip->fb)
 114                goto apply;
 115
 116        if (dma->status == ATMEL_HLCDC_LAYER_DISABLED) {
 117                for (i = 0; i < fb_flip->ngems; i++) {
 118                        dscr = fb_flip->dscrs[i];
 119                        dscr->ctrl = ATMEL_HLCDC_LAYER_DFETCH |
 120                                     ATMEL_HLCDC_LAYER_DMA_IRQ |
 121                                     ATMEL_HLCDC_LAYER_ADD_IRQ |
 122                                     ATMEL_HLCDC_LAYER_DONE_IRQ;
 123
 124                        regmap_write(regmap,
 125                                     desc->regs_offset +
 126                                     ATMEL_HLCDC_LAYER_PLANE_ADDR(i),
 127                                     dscr->addr);
 128                        regmap_write(regmap,
 129                                     desc->regs_offset +
 130                                     ATMEL_HLCDC_LAYER_PLANE_CTRL(i),
 131                                     dscr->ctrl);
 132                        regmap_write(regmap,
 133                                     desc->regs_offset +
 134                                     ATMEL_HLCDC_LAYER_PLANE_NEXT(i),
 135                                     dscr->next);
 136                }
 137
 138                action |= ATMEL_HLCDC_LAYER_DMA_CHAN;
 139                dma->status = ATMEL_HLCDC_LAYER_ENABLED;
 140        } else {
 141                for (i = 0; i < fb_flip->ngems; i++) {
 142                        dscr =  fb_flip->dscrs[i];
 143                        dscr->ctrl = ATMEL_HLCDC_LAYER_DFETCH |
 144                                     ATMEL_HLCDC_LAYER_DMA_IRQ |
 145                                     ATMEL_HLCDC_LAYER_DSCR_IRQ |
 146                                     ATMEL_HLCDC_LAYER_DONE_IRQ;
 147
 148                        regmap_write(regmap,
 149                                     desc->regs_offset +
 150                                     ATMEL_HLCDC_LAYER_PLANE_HEAD(i),
 151                                     dscr->next);
 152                }
 153
 154                action |= ATMEL_HLCDC_LAYER_A2Q;
 155        }
 156
 157        /* Release unneeded descriptors */
 158        for (i = fb_flip->ngems; i < layer->max_planes; i++) {
 159                fb_flip->dscrs[i]->status = 0;
 160                fb_flip->dscrs[i] = NULL;
 161        }
 162
 163        dma->queue = fb_flip;
 164        slot->fb_flip = NULL;
 165
 166apply:
 167        if (action)
 168                regmap_write(regmap,
 169                             desc->regs_offset + ATMEL_HLCDC_LAYER_CHER,
 170                             action);
 171
 172        atmel_hlcdc_layer_update_reset(layer, upd->pending);
 173
 174        upd->pending = -1;
 175}
 176
 177void atmel_hlcdc_layer_irq(struct atmel_hlcdc_layer *layer)
 178{
 179        struct atmel_hlcdc_layer_dma_channel *dma = &layer->dma;
 180        const struct atmel_hlcdc_layer_desc *desc = layer->desc;
 181        struct regmap *regmap = layer->hlcdc->regmap;
 182        struct atmel_hlcdc_layer_fb_flip *flip;
 183        unsigned long flags;
 184        unsigned int isr, imr;
 185        unsigned int status;
 186        unsigned int plane_status;
 187        u32 flip_status;
 188
 189        int i;
 190
 191        regmap_read(regmap, desc->regs_offset + ATMEL_HLCDC_LAYER_IMR, &imr);
 192        regmap_read(regmap, desc->regs_offset + ATMEL_HLCDC_LAYER_ISR, &isr);
 193        status = imr & isr;
 194        if (!status)
 195                return;
 196
 197        spin_lock_irqsave(&layer->lock, flags);
 198
 199        flip = dma->queue ? dma->queue : dma->cur;
 200
 201        if (!flip) {
 202                spin_unlock_irqrestore(&layer->lock, flags);
 203                return;
 204        }
 205
 206        /*
 207         * Set LOADED and DONE flags: they'll be cleared if at least one
 208         * memory plane is not LOADED or DONE.
 209         */
 210        flip_status = ATMEL_HLCDC_DMA_CHANNEL_DSCR_LOADED |
 211                      ATMEL_HLCDC_DMA_CHANNEL_DSCR_DONE;
 212        for (i = 0; i < flip->ngems; i++) {
 213                plane_status = (status >> (8 * i));
 214
 215                if (plane_status &
 216                    (ATMEL_HLCDC_LAYER_ADD_IRQ |
 217                     ATMEL_HLCDC_LAYER_DSCR_IRQ) &
 218                    ~flip->dscrs[i]->ctrl) {
 219                        flip->dscrs[i]->status |=
 220                                        ATMEL_HLCDC_DMA_CHANNEL_DSCR_LOADED;
 221                        flip->dscrs[i]->ctrl |=
 222                                        ATMEL_HLCDC_LAYER_ADD_IRQ |
 223                                        ATMEL_HLCDC_LAYER_DSCR_IRQ;
 224                }
 225
 226                if (plane_status &
 227                    ATMEL_HLCDC_LAYER_DONE_IRQ &
 228                    ~flip->dscrs[i]->ctrl) {
 229                        flip->dscrs[i]->status |=
 230                                        ATMEL_HLCDC_DMA_CHANNEL_DSCR_DONE;
 231                        flip->dscrs[i]->ctrl |=
 232                                        ATMEL_HLCDC_LAYER_DONE_IRQ;
 233                }
 234
 235                if (plane_status & ATMEL_HLCDC_LAYER_OVR_IRQ)
 236                        flip->dscrs[i]->status |=
 237                                        ATMEL_HLCDC_DMA_CHANNEL_DSCR_OVERRUN;
 238
 239                /*
 240                 * Clear LOADED and DONE flags if the memory plane is either
 241                 * not LOADED or not DONE.
 242                 */
 243                if (!(flip->dscrs[i]->status &
 244                      ATMEL_HLCDC_DMA_CHANNEL_DSCR_LOADED))
 245                        flip_status &= ~ATMEL_HLCDC_DMA_CHANNEL_DSCR_LOADED;
 246
 247                if (!(flip->dscrs[i]->status &
 248                      ATMEL_HLCDC_DMA_CHANNEL_DSCR_DONE))
 249                        flip_status &= ~ATMEL_HLCDC_DMA_CHANNEL_DSCR_DONE;
 250
 251                /*
 252                 * An overrun on one memory plane impact the whole framebuffer
 253                 * transfer, hence we set the OVERRUN flag as soon as there's
 254                 * one memory plane reporting such an overrun.
 255                 */
 256                flip_status |= flip->dscrs[i]->status &
 257                               ATMEL_HLCDC_DMA_CHANNEL_DSCR_OVERRUN;
 258        }
 259
 260        /* Get changed bits */
 261        flip_status ^= flip->status;
 262        flip->status |= flip_status;
 263
 264        if (flip_status & ATMEL_HLCDC_DMA_CHANNEL_DSCR_LOADED) {
 265                atmel_hlcdc_layer_fb_flip_release_queue(layer, dma->cur);
 266                dma->cur = dma->queue;
 267                dma->queue = NULL;
 268        }
 269
 270        if (flip_status & ATMEL_HLCDC_DMA_CHANNEL_DSCR_DONE) {
 271                atmel_hlcdc_layer_fb_flip_release_queue(layer, dma->cur);
 272                dma->cur = NULL;
 273        }
 274
 275        if (flip_status & ATMEL_HLCDC_DMA_CHANNEL_DSCR_OVERRUN) {
 276                regmap_write(regmap,
 277                             desc->regs_offset + ATMEL_HLCDC_LAYER_CHDR,
 278                             ATMEL_HLCDC_LAYER_RST);
 279                if (dma->queue)
 280                        atmel_hlcdc_layer_fb_flip_release_queue(layer,
 281                                                                dma->queue);
 282
 283                if (dma->cur)
 284                        atmel_hlcdc_layer_fb_flip_release_queue(layer,
 285                                                                dma->cur);
 286
 287                dma->cur = NULL;
 288                dma->queue = NULL;
 289        }
 290
 291        if (!dma->queue) {
 292                atmel_hlcdc_layer_update_apply(layer);
 293
 294                if (!dma->cur)
 295                        dma->status = ATMEL_HLCDC_LAYER_DISABLED;
 296        }
 297
 298        spin_unlock_irqrestore(&layer->lock, flags);
 299}
 300
 301void atmel_hlcdc_layer_disable(struct atmel_hlcdc_layer *layer)
 302{
 303        struct atmel_hlcdc_layer_dma_channel *dma = &layer->dma;
 304        struct atmel_hlcdc_layer_update *upd = &layer->update;
 305        struct regmap *regmap = layer->hlcdc->regmap;
 306        const struct atmel_hlcdc_layer_desc *desc = layer->desc;
 307        unsigned long flags;
 308        unsigned int isr;
 309
 310        spin_lock_irqsave(&layer->lock, flags);
 311
 312        /* Disable the layer */
 313        regmap_write(regmap, desc->regs_offset + ATMEL_HLCDC_LAYER_CHDR,
 314                     ATMEL_HLCDC_LAYER_RST | ATMEL_HLCDC_LAYER_A2Q |
 315                     ATMEL_HLCDC_LAYER_UPDATE);
 316
 317        /* Clear all pending interrupts */
 318        regmap_read(regmap, desc->regs_offset + ATMEL_HLCDC_LAYER_ISR, &isr);
 319
 320        /* Discard current and queued framebuffer transfers. */
 321        if (dma->cur) {
 322                atmel_hlcdc_layer_fb_flip_release_queue(layer, dma->cur);
 323                dma->cur = NULL;
 324        }
 325
 326        if (dma->queue) {
 327                atmel_hlcdc_layer_fb_flip_release_queue(layer, dma->queue);
 328                dma->queue = NULL;
 329        }
 330
 331        /*
 332         * Then discard the pending update request (if any) to prevent
 333         * DMA irq handler from restarting the DMA channel after it has
 334         * been disabled.
 335         */
 336        if (upd->pending >= 0) {
 337                atmel_hlcdc_layer_update_reset(layer, upd->pending);
 338                upd->pending = -1;
 339        }
 340
 341        dma->status = ATMEL_HLCDC_LAYER_DISABLED;
 342
 343        spin_unlock_irqrestore(&layer->lock, flags);
 344}
 345
 346int atmel_hlcdc_layer_update_start(struct atmel_hlcdc_layer *layer)
 347{
 348        struct atmel_hlcdc_layer_dma_channel *dma = &layer->dma;
 349        struct atmel_hlcdc_layer_update *upd = &layer->update;
 350        struct regmap *regmap = layer->hlcdc->regmap;
 351        struct atmel_hlcdc_layer_fb_flip *fb_flip;
 352        struct atmel_hlcdc_layer_update_slot *slot;
 353        unsigned long flags;
 354        int i, j = 0;
 355
 356        fb_flip = kzalloc(sizeof(*fb_flip), GFP_KERNEL);
 357        if (!fb_flip)
 358                return -ENOMEM;
 359
 360        fb_flip->task = drm_flip_work_allocate_task(fb_flip, GFP_KERNEL);
 361        if (!fb_flip->task) {
 362                kfree(fb_flip);
 363                return -ENOMEM;
 364        }
 365
 366        spin_lock_irqsave(&layer->lock, flags);
 367
 368        upd->next = upd->pending ? 0 : 1;
 369
 370        slot = &upd->slots[upd->next];
 371
 372        for (i = 0; i < layer->max_planes * 4; i++) {
 373                if (!dma->dscrs[i].status) {
 374                        fb_flip->dscrs[j++] = &dma->dscrs[i];
 375                        dma->dscrs[i].status =
 376                                ATMEL_HLCDC_DMA_CHANNEL_DSCR_RESERVED;
 377                        if (j == layer->max_planes)
 378                                break;
 379                }
 380        }
 381
 382        if (j < layer->max_planes) {
 383                for (i = 0; i < j; i++)
 384                        fb_flip->dscrs[i]->status = 0;
 385        }
 386
 387        if (j < layer->max_planes) {
 388                spin_unlock_irqrestore(&layer->lock, flags);
 389                atmel_hlcdc_layer_fb_flip_destroy(fb_flip);
 390                return -EBUSY;
 391        }
 392
 393        slot->fb_flip = fb_flip;
 394
 395        if (upd->pending >= 0) {
 396                memcpy(slot->configs,
 397                       upd->slots[upd->pending].configs,
 398                       layer->desc->nconfigs * sizeof(u32));
 399                memcpy(slot->updated_configs,
 400                       upd->slots[upd->pending].updated_configs,
 401                       DIV_ROUND_UP(layer->desc->nconfigs,
 402                                    BITS_PER_BYTE * sizeof(unsigned long)) *
 403                       sizeof(unsigned long));
 404                slot->fb_flip->fb = upd->slots[upd->pending].fb_flip->fb;
 405                if (upd->slots[upd->pending].fb_flip->fb) {
 406                        slot->fb_flip->fb =
 407                                upd->slots[upd->pending].fb_flip->fb;
 408                        slot->fb_flip->ngems =
 409                                upd->slots[upd->pending].fb_flip->ngems;
 410                        drm_framebuffer_reference(slot->fb_flip->fb);
 411                }
 412        } else {
 413                regmap_bulk_read(regmap,
 414                                 layer->desc->regs_offset +
 415                                 ATMEL_HLCDC_LAYER_CFG(layer, 0),
 416                                 upd->slots[upd->next].configs,
 417                                 layer->desc->nconfigs);
 418        }
 419
 420        spin_unlock_irqrestore(&layer->lock, flags);
 421
 422        return 0;
 423}
 424
 425void atmel_hlcdc_layer_update_rollback(struct atmel_hlcdc_layer *layer)
 426{
 427        struct atmel_hlcdc_layer_update *upd = &layer->update;
 428
 429        atmel_hlcdc_layer_update_reset(layer, upd->next);
 430        upd->next = -1;
 431}
 432
 433void atmel_hlcdc_layer_update_set_fb(struct atmel_hlcdc_layer *layer,
 434                                     struct drm_framebuffer *fb,
 435                                     unsigned int *offsets)
 436{
 437        struct atmel_hlcdc_layer_update *upd = &layer->update;
 438        struct atmel_hlcdc_layer_fb_flip *fb_flip;
 439        struct atmel_hlcdc_layer_update_slot *slot;
 440        struct atmel_hlcdc_dma_channel_dscr *dscr;
 441        struct drm_framebuffer *old_fb;
 442        int nplanes = 0;
 443        int i;
 444
 445        if (upd->next < 0 || upd->next > 1)
 446                return;
 447
 448        if (fb)
 449                nplanes = drm_format_num_planes(fb->pixel_format);
 450
 451        if (nplanes > layer->max_planes)
 452                return;
 453
 454        slot = &upd->slots[upd->next];
 455
 456        fb_flip = slot->fb_flip;
 457        old_fb = slot->fb_flip->fb;
 458
 459        for (i = 0; i < nplanes; i++) {
 460                struct drm_gem_cma_object *gem;
 461
 462                dscr = slot->fb_flip->dscrs[i];
 463                gem = drm_fb_cma_get_gem_obj(fb, i);
 464                dscr->addr = gem->paddr + offsets[i];
 465        }
 466
 467        fb_flip->ngems = nplanes;
 468        fb_flip->fb = fb;
 469
 470        if (fb)
 471                drm_framebuffer_reference(fb);
 472
 473        if (old_fb)
 474                drm_framebuffer_unreference(old_fb);
 475}
 476
 477void atmel_hlcdc_layer_update_cfg(struct atmel_hlcdc_layer *layer, int cfg,
 478                                  u32 mask, u32 val)
 479{
 480        struct atmel_hlcdc_layer_update *upd = &layer->update;
 481        struct atmel_hlcdc_layer_update_slot *slot;
 482
 483        if (upd->next < 0 || upd->next > 1)
 484                return;
 485
 486        if (cfg >= layer->desc->nconfigs)
 487                return;
 488
 489        slot = &upd->slots[upd->next];
 490        slot->configs[cfg] &= ~mask;
 491        slot->configs[cfg] |= (val & mask);
 492        set_bit(cfg, slot->updated_configs);
 493}
 494
 495void atmel_hlcdc_layer_update_commit(struct atmel_hlcdc_layer *layer)
 496{
 497        struct atmel_hlcdc_layer_dma_channel *dma = &layer->dma;
 498        struct atmel_hlcdc_layer_update *upd = &layer->update;
 499        struct atmel_hlcdc_layer_update_slot *slot;
 500        unsigned long flags;
 501
 502        if (upd->next < 0  || upd->next > 1)
 503                return;
 504
 505        slot = &upd->slots[upd->next];
 506
 507        spin_lock_irqsave(&layer->lock, flags);
 508
 509        /*
 510         * Release pending update request and replace it by the new one.
 511         */
 512        if (upd->pending >= 0)
 513                atmel_hlcdc_layer_update_reset(layer, upd->pending);
 514
 515        upd->pending = upd->next;
 516        upd->next = -1;
 517
 518        if (!dma->queue)
 519                atmel_hlcdc_layer_update_apply(layer);
 520
 521        spin_unlock_irqrestore(&layer->lock, flags);
 522
 523
 524        upd->next = -1;
 525}
 526
 527static int atmel_hlcdc_layer_dma_init(struct drm_device *dev,
 528                                      struct atmel_hlcdc_layer *layer)
 529{
 530        struct atmel_hlcdc_layer_dma_channel *dma = &layer->dma;
 531        dma_addr_t dma_addr;
 532        int i;
 533
 534        dma->dscrs = dma_alloc_coherent(dev->dev,
 535                                        layer->max_planes * 4 *
 536                                        sizeof(*dma->dscrs),
 537                                        &dma_addr, GFP_KERNEL);
 538        if (!dma->dscrs)
 539                return -ENOMEM;
 540
 541        for (i = 0; i < layer->max_planes * 4; i++) {
 542                struct atmel_hlcdc_dma_channel_dscr *dscr = &dma->dscrs[i];
 543
 544                dscr->next = dma_addr + (i * sizeof(*dscr));
 545        }
 546
 547        return 0;
 548}
 549
 550static void atmel_hlcdc_layer_dma_cleanup(struct drm_device *dev,
 551                                          struct atmel_hlcdc_layer *layer)
 552{
 553        struct atmel_hlcdc_layer_dma_channel *dma = &layer->dma;
 554        int i;
 555
 556        for (i = 0; i < layer->max_planes * 4; i++) {
 557                struct atmel_hlcdc_dma_channel_dscr *dscr = &dma->dscrs[i];
 558
 559                dscr->status = 0;
 560        }
 561
 562        dma_free_coherent(dev->dev, layer->max_planes * 4 *
 563                          sizeof(*dma->dscrs), dma->dscrs,
 564                          dma->dscrs[0].next);
 565}
 566
 567static int atmel_hlcdc_layer_update_init(struct drm_device *dev,
 568                                struct atmel_hlcdc_layer *layer,
 569                                const struct atmel_hlcdc_layer_desc *desc)
 570{
 571        struct atmel_hlcdc_layer_update *upd = &layer->update;
 572        int updated_size;
 573        void *buffer;
 574        int i;
 575
 576        updated_size = DIV_ROUND_UP(desc->nconfigs,
 577                                    BITS_PER_BYTE *
 578                                    sizeof(unsigned long));
 579
 580        buffer = devm_kzalloc(dev->dev,
 581                              ((desc->nconfigs * sizeof(u32)) +
 582                                (updated_size * sizeof(unsigned long))) * 2,
 583                              GFP_KERNEL);
 584        if (!buffer)
 585                return -ENOMEM;
 586
 587        for (i = 0; i < 2; i++) {
 588                upd->slots[i].updated_configs = buffer;
 589                buffer += updated_size * sizeof(unsigned long);
 590                upd->slots[i].configs = buffer;
 591                buffer += desc->nconfigs * sizeof(u32);
 592        }
 593
 594        upd->pending = -1;
 595        upd->next = -1;
 596
 597        return 0;
 598}
 599
 600int atmel_hlcdc_layer_init(struct drm_device *dev,
 601                           struct atmel_hlcdc_layer *layer,
 602                           const struct atmel_hlcdc_layer_desc *desc)
 603{
 604        struct atmel_hlcdc_dc *dc = dev->dev_private;
 605        struct regmap *regmap = dc->hlcdc->regmap;
 606        unsigned int tmp;
 607        int ret;
 608        int i;
 609
 610        layer->hlcdc = dc->hlcdc;
 611        layer->wq = dc->wq;
 612        layer->desc = desc;
 613
 614        regmap_write(regmap, desc->regs_offset + ATMEL_HLCDC_LAYER_CHDR,
 615                     ATMEL_HLCDC_LAYER_RST);
 616        for (i = 0; i < desc->formats->nformats; i++) {
 617                int nplanes = drm_format_num_planes(desc->formats->formats[i]);
 618
 619                if (nplanes > layer->max_planes)
 620                        layer->max_planes = nplanes;
 621        }
 622
 623        spin_lock_init(&layer->lock);
 624        drm_flip_work_init(&layer->gc, desc->name,
 625                           atmel_hlcdc_layer_fb_flip_release);
 626        ret = atmel_hlcdc_layer_dma_init(dev, layer);
 627        if (ret)
 628                return ret;
 629
 630        ret = atmel_hlcdc_layer_update_init(dev, layer, desc);
 631        if (ret)
 632                return ret;
 633
 634        /* Flush Status Register */
 635        regmap_write(regmap, desc->regs_offset + ATMEL_HLCDC_LAYER_IDR,
 636                     0xffffffff);
 637        regmap_read(regmap, desc->regs_offset + ATMEL_HLCDC_LAYER_ISR,
 638                    &tmp);
 639
 640        tmp = 0;
 641        for (i = 0; i < layer->max_planes; i++)
 642                tmp |= (ATMEL_HLCDC_LAYER_DMA_IRQ |
 643                        ATMEL_HLCDC_LAYER_DSCR_IRQ |
 644                        ATMEL_HLCDC_LAYER_ADD_IRQ |
 645                        ATMEL_HLCDC_LAYER_DONE_IRQ |
 646                        ATMEL_HLCDC_LAYER_OVR_IRQ) << (8 * i);
 647
 648        regmap_write(regmap, desc->regs_offset + ATMEL_HLCDC_LAYER_IER, tmp);
 649
 650        return 0;
 651}
 652
 653void atmel_hlcdc_layer_cleanup(struct drm_device *dev,
 654                               struct atmel_hlcdc_layer *layer)
 655{
 656        const struct atmel_hlcdc_layer_desc *desc = layer->desc;
 657        struct regmap *regmap = layer->hlcdc->regmap;
 658
 659        regmap_write(regmap, desc->regs_offset + ATMEL_HLCDC_LAYER_IDR,
 660                     0xffffffff);
 661        regmap_write(regmap, desc->regs_offset + ATMEL_HLCDC_LAYER_CHDR,
 662                     ATMEL_HLCDC_LAYER_RST);
 663
 664        atmel_hlcdc_layer_dma_cleanup(dev, layer);
 665        drm_flip_work_cleanup(&layer->gc);
 666}
 667