Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  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}