161f1c4a8Sjames qian wang (Arm Technology China) // SPDX-License-Identifier: GPL-2.0
261f1c4a8Sjames qian wang (Arm Technology China) /*
361f1c4a8Sjames qian wang (Arm Technology China) * (C) COPYRIGHT 2018 ARM Limited. All rights reserved.
461f1c4a8Sjames qian wang (Arm Technology China) * Author: James.Qian.Wang <james.qian.wang@arm.com>
561f1c4a8Sjames qian wang (Arm Technology China) *
661f1c4a8Sjames qian wang (Arm Technology China) */
76649a95dSSam Ravnborg #include <linux/interrupt.h>
86649a95dSSam Ravnborg
961f1c4a8Sjames qian wang (Arm Technology China) #include <drm/drm_atomic.h>
1061f1c4a8Sjames qian wang (Arm Technology China) #include <drm/drm_atomic_helper.h>
116649a95dSSam Ravnborg #include <drm/drm_drv.h>
124a83c26aSDanilo Krummrich #include <drm/drm_gem_dma_helper.h>
136649a95dSSam Ravnborg #include <drm/drm_gem_framebuffer_helper.h>
14780e41edSDaniel Vetter #include <drm/drm_managed.h>
151109635bSLowry Li (Arm Technology China) #include <drm/drm_probe_helper.h>
166649a95dSSam Ravnborg #include <drm/drm_vblank.h>
176649a95dSSam Ravnborg
1861f1c4a8Sjames qian wang (Arm Technology China) #include "komeda_dev.h"
1961f1c4a8Sjames qian wang (Arm Technology China) #include "komeda_framebuffer.h"
206649a95dSSam Ravnborg #include "komeda_kms.h"
2161f1c4a8Sjames qian wang (Arm Technology China)
224a83c26aSDanilo Krummrich DEFINE_DRM_GEM_DMA_FOPS(komeda_cma_fops);
2361f1c4a8Sjames qian wang (Arm Technology China)
komeda_gem_dma_dumb_create(struct drm_file * file,struct drm_device * dev,struct drm_mode_create_dumb * args)244a83c26aSDanilo Krummrich static int komeda_gem_dma_dumb_create(struct drm_file *file,
2561f1c4a8Sjames qian wang (Arm Technology China) struct drm_device *dev,
2661f1c4a8Sjames qian wang (Arm Technology China) struct drm_mode_create_dumb *args)
2761f1c4a8Sjames qian wang (Arm Technology China) {
288c134d13Sjames qian wang (Arm Technology China) struct komeda_dev *mdev = dev->dev_private;
298c134d13Sjames qian wang (Arm Technology China) u32 pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
3061f1c4a8Sjames qian wang (Arm Technology China)
318c134d13Sjames qian wang (Arm Technology China) args->pitch = ALIGN(pitch, mdev->chip.bus_width);
3261f1c4a8Sjames qian wang (Arm Technology China)
334a83c26aSDanilo Krummrich return drm_gem_dma_dumb_create_internal(file, dev, args);
3461f1c4a8Sjames qian wang (Arm Technology China) }
3561f1c4a8Sjames qian wang (Arm Technology China)
komeda_kms_irq_handler(int irq,void * data)360dac37bfSjames qian wang (Arm Technology China) static irqreturn_t komeda_kms_irq_handler(int irq, void *data)
370dac37bfSjames qian wang (Arm Technology China) {
380dac37bfSjames qian wang (Arm Technology China) struct drm_device *drm = data;
390dac37bfSjames qian wang (Arm Technology China) struct komeda_dev *mdev = drm->dev_private;
400dac37bfSjames qian wang (Arm Technology China) struct komeda_kms_dev *kms = to_kdev(drm);
410dac37bfSjames qian wang (Arm Technology China) struct komeda_events evts;
420dac37bfSjames qian wang (Arm Technology China) irqreturn_t status;
430dac37bfSjames qian wang (Arm Technology China) u32 i;
440dac37bfSjames qian wang (Arm Technology China)
450dac37bfSjames qian wang (Arm Technology China) /* Call into the CHIP to recognize events */
460dac37bfSjames qian wang (Arm Technology China) memset(&evts, 0, sizeof(evts));
470dac37bfSjames qian wang (Arm Technology China) status = mdev->funcs->irq_handler(mdev, &evts);
480dac37bfSjames qian wang (Arm Technology China)
498894cd58SMihail Atanassov komeda_print_events(&evts, drm);
504d74b25eSLowry Li (Arm Technology China)
510dac37bfSjames qian wang (Arm Technology China) /* Notify the crtc to handle the events */
520dac37bfSjames qian wang (Arm Technology China) for (i = 0; i < kms->n_crtcs; i++)
530dac37bfSjames qian wang (Arm Technology China) komeda_crtc_handle_event(&kms->crtcs[i], &evts);
540dac37bfSjames qian wang (Arm Technology China)
550dac37bfSjames qian wang (Arm Technology China) return status;
560dac37bfSjames qian wang (Arm Technology China) }
570dac37bfSjames qian wang (Arm Technology China)
5870a59dd8SDaniel Vetter static const struct drm_driver komeda_kms_driver = {
59055a12ffSDaniel Vetter .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
604a83c26aSDanilo Krummrich DRM_GEM_DMA_DRIVER_OPS_WITH_DUMB_CREATE(komeda_gem_dma_dumb_create),
6161f1c4a8Sjames qian wang (Arm Technology China) .fops = &komeda_cma_fops,
6261f1c4a8Sjames qian wang (Arm Technology China) .name = "komeda",
6361f1c4a8Sjames qian wang (Arm Technology China) .desc = "Arm Komeda Display Processor driver",
6461f1c4a8Sjames qian wang (Arm Technology China) .date = "20181101",
6561f1c4a8Sjames qian wang (Arm Technology China) .major = 0,
6661f1c4a8Sjames qian wang (Arm Technology China) .minor = 1,
6761f1c4a8Sjames qian wang (Arm Technology China) };
6861f1c4a8Sjames qian wang (Arm Technology China)
komeda_kms_atomic_commit_hw_done(struct drm_atomic_state * state)69eaa225b6SLiviu Dudau static void komeda_kms_atomic_commit_hw_done(struct drm_atomic_state *state)
70eaa225b6SLiviu Dudau {
71eaa225b6SLiviu Dudau struct drm_device *dev = state->dev;
72eaa225b6SLiviu Dudau struct komeda_kms_dev *kms = to_kdev(dev);
73eaa225b6SLiviu Dudau int i;
74eaa225b6SLiviu Dudau
75eaa225b6SLiviu Dudau for (i = 0; i < kms->n_crtcs; i++) {
76eaa225b6SLiviu Dudau struct komeda_crtc *kcrtc = &kms->crtcs[i];
77eaa225b6SLiviu Dudau
78eaa225b6SLiviu Dudau if (kcrtc->base.state->active) {
79eaa225b6SLiviu Dudau struct completion *flip_done = NULL;
80eaa225b6SLiviu Dudau if (kcrtc->base.state->event)
81eaa225b6SLiviu Dudau flip_done = kcrtc->base.state->event->base.completion;
82eaa225b6SLiviu Dudau komeda_crtc_flush_and_wait_for_flip_done(kcrtc, flip_done);
83eaa225b6SLiviu Dudau }
84eaa225b6SLiviu Dudau }
85eaa225b6SLiviu Dudau drm_atomic_helper_commit_hw_done(state);
86eaa225b6SLiviu Dudau }
87eaa225b6SLiviu Dudau
komeda_kms_commit_tail(struct drm_atomic_state * old_state)8861f1c4a8Sjames qian wang (Arm Technology China) static void komeda_kms_commit_tail(struct drm_atomic_state *old_state)
8961f1c4a8Sjames qian wang (Arm Technology China) {
9061f1c4a8Sjames qian wang (Arm Technology China) struct drm_device *dev = old_state->dev;
9153fc08c2SDaniel Vetter bool fence_cookie = dma_fence_begin_signalling();
9261f1c4a8Sjames qian wang (Arm Technology China)
9361f1c4a8Sjames qian wang (Arm Technology China) drm_atomic_helper_commit_modeset_disables(dev, old_state);
9461f1c4a8Sjames qian wang (Arm Technology China)
95b88639b8SMihail Atanassov drm_atomic_helper_commit_planes(dev, old_state,
96b88639b8SMihail Atanassov DRM_PLANE_COMMIT_ACTIVE_ONLY);
9761f1c4a8Sjames qian wang (Arm Technology China)
9861f1c4a8Sjames qian wang (Arm Technology China) drm_atomic_helper_commit_modeset_enables(dev, old_state);
9961f1c4a8Sjames qian wang (Arm Technology China)
100eaa225b6SLiviu Dudau komeda_kms_atomic_commit_hw_done(old_state);
10161f1c4a8Sjames qian wang (Arm Technology China)
1024b501262SJames Qian Wang drm_atomic_helper_wait_for_flip_done(dev, old_state);
1034b501262SJames Qian Wang
10453fc08c2SDaniel Vetter dma_fence_end_signalling(fence_cookie);
10553fc08c2SDaniel Vetter
10661f1c4a8Sjames qian wang (Arm Technology China) drm_atomic_helper_cleanup_planes(dev, old_state);
10761f1c4a8Sjames qian wang (Arm Technology China) }
10861f1c4a8Sjames qian wang (Arm Technology China)
10961f1c4a8Sjames qian wang (Arm Technology China) static const struct drm_mode_config_helper_funcs komeda_mode_config_helpers = {
11061f1c4a8Sjames qian wang (Arm Technology China) .atomic_commit_tail = komeda_kms_commit_tail,
11161f1c4a8Sjames qian wang (Arm Technology China) };
11261f1c4a8Sjames qian wang (Arm Technology China)
komeda_plane_state_list_add(struct drm_plane_state * plane_st,struct list_head * zorder_list)113109bd7d5SLowry Li (Arm Technology China) static int komeda_plane_state_list_add(struct drm_plane_state *plane_st,
114109bd7d5SLowry Li (Arm Technology China) struct list_head *zorder_list)
115109bd7d5SLowry Li (Arm Technology China) {
116109bd7d5SLowry Li (Arm Technology China) struct komeda_plane_state *new = to_kplane_st(plane_st);
117109bd7d5SLowry Li (Arm Technology China) struct komeda_plane_state *node, *last;
118109bd7d5SLowry Li (Arm Technology China)
119109bd7d5SLowry Li (Arm Technology China) last = list_empty(zorder_list) ?
120109bd7d5SLowry Li (Arm Technology China) NULL : list_last_entry(zorder_list, typeof(*last), zlist_node);
121109bd7d5SLowry Li (Arm Technology China)
122109bd7d5SLowry Li (Arm Technology China) /* Considering the list sequence is zpos increasing, so if list is empty
123109bd7d5SLowry Li (Arm Technology China) * or the zpos of new node bigger than the last node in list, no need
124109bd7d5SLowry Li (Arm Technology China) * loop and just insert the new one to the tail of the list.
125109bd7d5SLowry Li (Arm Technology China) */
126109bd7d5SLowry Li (Arm Technology China) if (!last || (new->base.zpos > last->base.zpos)) {
127109bd7d5SLowry Li (Arm Technology China) list_add_tail(&new->zlist_node, zorder_list);
128109bd7d5SLowry Li (Arm Technology China) return 0;
129109bd7d5SLowry Li (Arm Technology China) }
130109bd7d5SLowry Li (Arm Technology China)
131109bd7d5SLowry Li (Arm Technology China) /* Build the list by zpos increasing */
132109bd7d5SLowry Li (Arm Technology China) list_for_each_entry(node, zorder_list, zlist_node) {
133109bd7d5SLowry Li (Arm Technology China) if (new->base.zpos < node->base.zpos) {
134109bd7d5SLowry Li (Arm Technology China) list_add_tail(&new->zlist_node, &node->zlist_node);
135109bd7d5SLowry Li (Arm Technology China) break;
136109bd7d5SLowry Li (Arm Technology China) } else if (node->base.zpos == new->base.zpos) {
137109bd7d5SLowry Li (Arm Technology China) struct drm_plane *a = node->base.plane;
138109bd7d5SLowry Li (Arm Technology China) struct drm_plane *b = new->base.plane;
139109bd7d5SLowry Li (Arm Technology China)
140109bd7d5SLowry Li (Arm Technology China) /* Komeda doesn't support setting a same zpos for
141109bd7d5SLowry Li (Arm Technology China) * different planes.
142109bd7d5SLowry Li (Arm Technology China) */
143109bd7d5SLowry Li (Arm Technology China) DRM_DEBUG_ATOMIC("PLANE: %s and PLANE: %s are configured same zpos: %d.\n",
144109bd7d5SLowry Li (Arm Technology China) a->name, b->name, node->base.zpos);
145109bd7d5SLowry Li (Arm Technology China) return -EINVAL;
146109bd7d5SLowry Li (Arm Technology China) }
147109bd7d5SLowry Li (Arm Technology China) }
148109bd7d5SLowry Li (Arm Technology China)
149109bd7d5SLowry Li (Arm Technology China) return 0;
150109bd7d5SLowry Li (Arm Technology China) }
151109bd7d5SLowry Li (Arm Technology China)
komeda_crtc_normalize_zpos(struct drm_crtc * crtc,struct drm_crtc_state * crtc_st)152109bd7d5SLowry Li (Arm Technology China) static int komeda_crtc_normalize_zpos(struct drm_crtc *crtc,
153109bd7d5SLowry Li (Arm Technology China) struct drm_crtc_state *crtc_st)
154109bd7d5SLowry Li (Arm Technology China) {
155109bd7d5SLowry Li (Arm Technology China) struct drm_atomic_state *state = crtc_st->state;
1563b9dfa4eSLowry Li (Arm Technology China) struct komeda_crtc *kcrtc = to_kcrtc(crtc);
1573b9dfa4eSLowry Li (Arm Technology China) struct komeda_crtc_state *kcrtc_st = to_kcrtc_st(crtc_st);
158109bd7d5SLowry Li (Arm Technology China) struct komeda_plane_state *kplane_st;
159109bd7d5SLowry Li (Arm Technology China) struct drm_plane_state *plane_st;
160109bd7d5SLowry Li (Arm Technology China) struct drm_plane *plane;
161109bd7d5SLowry Li (Arm Technology China) struct list_head zorder_list;
162109bd7d5SLowry Li (Arm Technology China) int order = 0, err;
163*745fe9f1Shongchi.peng u32 slave_zpos = 0;
164109bd7d5SLowry Li (Arm Technology China)
165109bd7d5SLowry Li (Arm Technology China) DRM_DEBUG_ATOMIC("[CRTC:%d:%s] calculating normalized zpos values\n",
166109bd7d5SLowry Li (Arm Technology China) crtc->base.id, crtc->name);
167109bd7d5SLowry Li (Arm Technology China)
168109bd7d5SLowry Li (Arm Technology China) INIT_LIST_HEAD(&zorder_list);
169109bd7d5SLowry Li (Arm Technology China)
170109bd7d5SLowry Li (Arm Technology China) /* This loop also added all effected planes into the new state */
171109bd7d5SLowry Li (Arm Technology China) drm_for_each_plane_mask(plane, crtc->dev, crtc_st->plane_mask) {
172109bd7d5SLowry Li (Arm Technology China) plane_st = drm_atomic_get_plane_state(state, plane);
173109bd7d5SLowry Li (Arm Technology China) if (IS_ERR(plane_st))
174109bd7d5SLowry Li (Arm Technology China) return PTR_ERR(plane_st);
175109bd7d5SLowry Li (Arm Technology China)
176109bd7d5SLowry Li (Arm Technology China) /* Build a list by zpos increasing */
177109bd7d5SLowry Li (Arm Technology China) err = komeda_plane_state_list_add(plane_st, &zorder_list);
178109bd7d5SLowry Li (Arm Technology China) if (err)
179109bd7d5SLowry Li (Arm Technology China) return err;
180109bd7d5SLowry Li (Arm Technology China) }
181109bd7d5SLowry Li (Arm Technology China)
1823b9dfa4eSLowry Li (Arm Technology China) kcrtc_st->max_slave_zorder = 0;
1833b9dfa4eSLowry Li (Arm Technology China)
184109bd7d5SLowry Li (Arm Technology China) list_for_each_entry(kplane_st, &zorder_list, zlist_node) {
185109bd7d5SLowry Li (Arm Technology China) plane_st = &kplane_st->base;
186109bd7d5SLowry Li (Arm Technology China) plane = plane_st->plane;
187109bd7d5SLowry Li (Arm Technology China)
188109bd7d5SLowry Li (Arm Technology China) plane_st->normalized_zpos = order++;
189a407a650Sjames qian wang (Arm Technology China) /* When layer_split has been enabled, one plane will be handled
190a407a650Sjames qian wang (Arm Technology China) * by two separated komeda layers (left/right), which may needs
191a407a650Sjames qian wang (Arm Technology China) * two zorders.
192a407a650Sjames qian wang (Arm Technology China) * - zorder: for left_layer for left display part.
193a407a650Sjames qian wang (Arm Technology China) * - zorder + 1: will be reserved for right layer.
194a407a650Sjames qian wang (Arm Technology China) */
195a407a650Sjames qian wang (Arm Technology China) if (to_kplane_st(plane_st)->layer_split)
196a407a650Sjames qian wang (Arm Technology China) order++;
197109bd7d5SLowry Li (Arm Technology China)
198109bd7d5SLowry Li (Arm Technology China) DRM_DEBUG_ATOMIC("[PLANE:%d:%s] zpos:%d, normalized zpos: %d\n",
199109bd7d5SLowry Li (Arm Technology China) plane->base.id, plane->name,
200109bd7d5SLowry Li (Arm Technology China) plane_st->zpos, plane_st->normalized_zpos);
2013b9dfa4eSLowry Li (Arm Technology China)
2023b9dfa4eSLowry Li (Arm Technology China) /* calculate max slave zorder */
203*745fe9f1Shongchi.peng if (has_bit(drm_plane_index(plane), kcrtc->slave_planes)) {
204*745fe9f1Shongchi.peng slave_zpos = plane_st->normalized_zpos;
205*745fe9f1Shongchi.peng if (to_kplane_st(plane_st)->layer_split)
206*745fe9f1Shongchi.peng slave_zpos++;
2073b9dfa4eSLowry Li (Arm Technology China) kcrtc_st->max_slave_zorder =
208*745fe9f1Shongchi.peng max(slave_zpos, kcrtc_st->max_slave_zorder);
209*745fe9f1Shongchi.peng }
210109bd7d5SLowry Li (Arm Technology China) }
211109bd7d5SLowry Li (Arm Technology China)
212109bd7d5SLowry Li (Arm Technology China) crtc_st->zpos_changed = true;
213109bd7d5SLowry Li (Arm Technology China)
214109bd7d5SLowry Li (Arm Technology China) return 0;
215109bd7d5SLowry Li (Arm Technology China) }
216109bd7d5SLowry Li (Arm Technology China)
komeda_kms_check(struct drm_device * dev,struct drm_atomic_state * state)21742c72941Sjames qian wang (Arm Technology China) static int komeda_kms_check(struct drm_device *dev,
21842c72941Sjames qian wang (Arm Technology China) struct drm_atomic_state *state)
21942c72941Sjames qian wang (Arm Technology China) {
22042c72941Sjames qian wang (Arm Technology China) struct drm_crtc *crtc;
22161d05b18Sjames qian wang (Arm Technology China) struct drm_crtc_state *new_crtc_st;
22242c72941Sjames qian wang (Arm Technology China) int i, err;
22342c72941Sjames qian wang (Arm Technology China)
22442c72941Sjames qian wang (Arm Technology China) err = drm_atomic_helper_check_modeset(dev, state);
22542c72941Sjames qian wang (Arm Technology China) if (err)
22642c72941Sjames qian wang (Arm Technology China) return err;
22742c72941Sjames qian wang (Arm Technology China)
228109bd7d5SLowry Li (Arm Technology China) /* Komeda need to re-calculate resource assumption in every commit
22942c72941Sjames qian wang (Arm Technology China) * so need to add all affected_planes (even unchanged) to
23042c72941Sjames qian wang (Arm Technology China) * drm_atomic_state.
23142c72941Sjames qian wang (Arm Technology China) */
23261d05b18Sjames qian wang (Arm Technology China) for_each_new_crtc_in_state(state, crtc, new_crtc_st, i) {
23342c72941Sjames qian wang (Arm Technology China) err = drm_atomic_add_affected_planes(state, crtc);
23442c72941Sjames qian wang (Arm Technology China) if (err)
23542c72941Sjames qian wang (Arm Technology China) return err;
236109bd7d5SLowry Li (Arm Technology China)
237109bd7d5SLowry Li (Arm Technology China) err = komeda_crtc_normalize_zpos(crtc, new_crtc_st);
238109bd7d5SLowry Li (Arm Technology China) if (err)
239109bd7d5SLowry Li (Arm Technology China) return err;
24042c72941Sjames qian wang (Arm Technology China) }
24142c72941Sjames qian wang (Arm Technology China)
24242c72941Sjames qian wang (Arm Technology China) err = drm_atomic_helper_check_planes(dev, state);
24342c72941Sjames qian wang (Arm Technology China) if (err)
24442c72941Sjames qian wang (Arm Technology China) return err;
24542c72941Sjames qian wang (Arm Technology China)
24642c72941Sjames qian wang (Arm Technology China) return 0;
24742c72941Sjames qian wang (Arm Technology China) }
24842c72941Sjames qian wang (Arm Technology China)
24961f1c4a8Sjames qian wang (Arm Technology China) static const struct drm_mode_config_funcs komeda_mode_config_funcs = {
25061f1c4a8Sjames qian wang (Arm Technology China) .fb_create = komeda_fb_create,
25142c72941Sjames qian wang (Arm Technology China) .atomic_check = komeda_kms_check,
25261f1c4a8Sjames qian wang (Arm Technology China) .atomic_commit = drm_atomic_helper_commit,
25361f1c4a8Sjames qian wang (Arm Technology China) };
25461f1c4a8Sjames qian wang (Arm Technology China)
komeda_kms_mode_config_init(struct komeda_kms_dev * kms,struct komeda_dev * mdev)25561f1c4a8Sjames qian wang (Arm Technology China) static void komeda_kms_mode_config_init(struct komeda_kms_dev *kms,
25661f1c4a8Sjames qian wang (Arm Technology China) struct komeda_dev *mdev)
25761f1c4a8Sjames qian wang (Arm Technology China) {
25861f1c4a8Sjames qian wang (Arm Technology China) struct drm_mode_config *config = &kms->base.mode_config;
25961f1c4a8Sjames qian wang (Arm Technology China)
26061f1c4a8Sjames qian wang (Arm Technology China) drm_mode_config_init(&kms->base);
26161f1c4a8Sjames qian wang (Arm Technology China)
26261f1c4a8Sjames qian wang (Arm Technology China) komeda_kms_setup_crtcs(kms, mdev);
26361f1c4a8Sjames qian wang (Arm Technology China)
26461f1c4a8Sjames qian wang (Arm Technology China) /* Get value from dev */
26561f1c4a8Sjames qian wang (Arm Technology China) config->min_width = 0;
26661f1c4a8Sjames qian wang (Arm Technology China) config->min_height = 0;
26761f1c4a8Sjames qian wang (Arm Technology China) config->max_width = 4096;
26861f1c4a8Sjames qian wang (Arm Technology China) config->max_height = 4096;
26961f1c4a8Sjames qian wang (Arm Technology China)
27061f1c4a8Sjames qian wang (Arm Technology China) config->funcs = &komeda_mode_config_funcs;
27161f1c4a8Sjames qian wang (Arm Technology China) config->helper_private = &komeda_mode_config_helpers;
27261f1c4a8Sjames qian wang (Arm Technology China) }
27361f1c4a8Sjames qian wang (Arm Technology China)
komeda_kms_attach(struct komeda_dev * mdev)27461f1c4a8Sjames qian wang (Arm Technology China) struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev)
27561f1c4a8Sjames qian wang (Arm Technology China) {
276843ef624SDaniel Vetter struct komeda_kms_dev *kms;
27761f1c4a8Sjames qian wang (Arm Technology China) struct drm_device *drm;
27861f1c4a8Sjames qian wang (Arm Technology China) int err;
27961f1c4a8Sjames qian wang (Arm Technology China)
280843ef624SDaniel Vetter kms = devm_drm_dev_alloc(mdev->dev, &komeda_kms_driver,
281843ef624SDaniel Vetter struct komeda_kms_dev, base);
282843ef624SDaniel Vetter if (IS_ERR(kms))
283843ef624SDaniel Vetter return kms;
28461f1c4a8Sjames qian wang (Arm Technology China)
28561f1c4a8Sjames qian wang (Arm Technology China) drm = &kms->base;
28661f1c4a8Sjames qian wang (Arm Technology China)
28761f1c4a8Sjames qian wang (Arm Technology China) drm->dev_private = mdev;
28861f1c4a8Sjames qian wang (Arm Technology China)
28961f1c4a8Sjames qian wang (Arm Technology China) komeda_kms_mode_config_init(kms, mdev);
29061f1c4a8Sjames qian wang (Arm Technology China)
29161f1c4a8Sjames qian wang (Arm Technology China) err = komeda_kms_add_private_objs(kms, mdev);
29261f1c4a8Sjames qian wang (Arm Technology China) if (err)
29361f1c4a8Sjames qian wang (Arm Technology China) goto cleanup_mode_config;
29461f1c4a8Sjames qian wang (Arm Technology China)
29561f1c4a8Sjames qian wang (Arm Technology China) err = komeda_kms_add_planes(kms, mdev);
29661f1c4a8Sjames qian wang (Arm Technology China) if (err)
29761f1c4a8Sjames qian wang (Arm Technology China) goto cleanup_mode_config;
29861f1c4a8Sjames qian wang (Arm Technology China)
29961f1c4a8Sjames qian wang (Arm Technology China) err = drm_vblank_init(drm, kms->n_crtcs);
30061f1c4a8Sjames qian wang (Arm Technology China) if (err)
30161f1c4a8Sjames qian wang (Arm Technology China) goto cleanup_mode_config;
30261f1c4a8Sjames qian wang (Arm Technology China)
30361f1c4a8Sjames qian wang (Arm Technology China) err = komeda_kms_add_crtcs(kms, mdev);
30461f1c4a8Sjames qian wang (Arm Technology China) if (err)
30561f1c4a8Sjames qian wang (Arm Technology China) goto cleanup_mode_config;
30661f1c4a8Sjames qian wang (Arm Technology China)
3075d51f6c0Sjames qian wang (Arm Technology China) err = komeda_kms_add_wb_connectors(kms, mdev);
3085d51f6c0Sjames qian wang (Arm Technology China) if (err)
3095d51f6c0Sjames qian wang (Arm Technology China) goto cleanup_mode_config;
3105d51f6c0Sjames qian wang (Arm Technology China)
31161f1c4a8Sjames qian wang (Arm Technology China) drm_mode_config_reset(drm);
31261f1c4a8Sjames qian wang (Arm Technology China)
3132cfb1981SAyan Halder err = devm_request_irq(drm->dev, mdev->irq,
3142cfb1981SAyan Halder komeda_kms_irq_handler, IRQF_SHARED,
3152cfb1981SAyan Halder drm->driver->name, drm);
31661f1c4a8Sjames qian wang (Arm Technology China) if (err)
3174cfe5cc0SFaiz Abbas goto cleanup_mode_config;
31861f1c4a8Sjames qian wang (Arm Technology China)
3191109635bSLowry Li (Arm Technology China) drm_kms_helper_poll_init(drm);
3201109635bSLowry Li (Arm Technology China)
3210dac37bfSjames qian wang (Arm Technology China) err = drm_dev_register(drm, 0);
3220dac37bfSjames qian wang (Arm Technology China) if (err)
3236978bce0SAyan Kumar Halder goto free_interrupts;
3240dac37bfSjames qian wang (Arm Technology China)
32561f1c4a8Sjames qian wang (Arm Technology China) return kms;
32661f1c4a8Sjames qian wang (Arm Technology China)
3276978bce0SAyan Kumar Halder free_interrupts:
3281109635bSLowry Li (Arm Technology China) drm_kms_helper_poll_fini(drm);
3296978bce0SAyan Kumar Halder cleanup_mode_config:
33061f1c4a8Sjames qian wang (Arm Technology China) drm_mode_config_cleanup(drm);
331ee6b73d6Sjames qian wang (Arm Technology China) komeda_kms_cleanup_private_objs(kms);
3326978bce0SAyan Kumar Halder drm->dev_private = NULL;
33361f1c4a8Sjames qian wang (Arm Technology China) return ERR_PTR(err);
33461f1c4a8Sjames qian wang (Arm Technology China) }
33561f1c4a8Sjames qian wang (Arm Technology China)
komeda_kms_detach(struct komeda_kms_dev * kms)33661f1c4a8Sjames qian wang (Arm Technology China) void komeda_kms_detach(struct komeda_kms_dev *kms)
33761f1c4a8Sjames qian wang (Arm Technology China) {
33861f1c4a8Sjames qian wang (Arm Technology China) struct drm_device *drm = &kms->base;
33961f1c4a8Sjames qian wang (Arm Technology China)
34061f1c4a8Sjames qian wang (Arm Technology China) drm_dev_unregister(drm);
3411109635bSLowry Li (Arm Technology China) drm_kms_helper_poll_fini(drm);
3426978bce0SAyan Kumar Halder drm_atomic_helper_shutdown(drm);
34361f1c4a8Sjames qian wang (Arm Technology China) drm_mode_config_cleanup(drm);
3446978bce0SAyan Kumar Halder komeda_kms_cleanup_private_objs(kms);
34561f1c4a8Sjames qian wang (Arm Technology China) drm->dev_private = NULL;
34661f1c4a8Sjames qian wang (Arm Technology China) }
347