int qxl_driver_load(struct drm_device *dev, unsigned long flags) { struct qxl_device *qdev; int r; /* require kms */ if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -ENODEV; qdev = kzalloc(sizeof(struct qxl_device), GFP_KERNEL); if (qdev == NULL) return -ENOMEM; dev->dev_private = qdev; r = qxl_device_init(qdev, dev, dev->pdev, flags); if (r) goto out; r = qxl_modeset_init(qdev); if (r) { qxl_driver_unload(dev); goto out; } drm_kms_helper_poll_init(qdev->ddev); return 0; out: kfree(qdev); return r; }
int fsl_dcu_drm_modeset_init(struct fsl_dcu_drm_device *fsl_dev) { int ret; drm_mode_config_init(fsl_dev->drm); fsl_dev->drm->mode_config.min_width = 0; fsl_dev->drm->mode_config.min_height = 0; fsl_dev->drm->mode_config.max_width = 2031; fsl_dev->drm->mode_config.max_height = 2047; fsl_dev->drm->mode_config.funcs = &fsl_dcu_drm_mode_config_funcs; ret = fsl_dcu_drm_crtc_create(fsl_dev); if (ret) goto err; ret = fsl_dcu_drm_encoder_create(fsl_dev, &fsl_dev->crtc); if (ret) goto err; ret = fsl_dcu_create_outputs(fsl_dev); if (ret) goto err; drm_mode_config_reset(fsl_dev->drm); drm_kms_helper_poll_init(fsl_dev->drm); return 0; err: drm_mode_config_cleanup(fsl_dev->drm); return ret; }
static int kirin_drm_kms_init(struct drm_device *dev) { struct kirin_drm_private *priv; int ret; priv = devm_kzalloc(dev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; dev->dev_private = priv; dev_set_drvdata(dev->dev, dev); /* dev->mode_config initialization */ drm_mode_config_init(dev); kirin_drm_mode_config_init(dev); /* display controller init */ ret = dc_ops->init(to_platform_device(dev->dev)); if (ret) goto err_mode_config_cleanup; /* bind and init sub drivers */ ret = component_bind_all(dev->dev, dev); if (ret) { DRM_ERROR("failed to bind all component.\n"); goto err_dc_cleanup; } /* vblank init */ ret = drm_vblank_init(dev, dev->mode_config.num_crtc); if (ret) { DRM_ERROR("failed to initialize vblank.\n"); goto err_unbind_all; } /* with irq_enabled = true, we can use the vblank feature. */ dev->irq_enabled = true; /* reset all the states of crtc/plane/encoder/connector */ drm_mode_config_reset(dev); /* init kms poll for handling hpd */ drm_kms_helper_poll_init(dev); /* force detection after connectors init */ (void)drm_helper_hpd_irq_event(dev); return 0; err_unbind_all: component_unbind_all(dev->dev, dev); err_dc_cleanup: dc_ops->cleanup(to_platform_device(dev->dev)); err_mode_config_cleanup: drm_mode_config_cleanup(dev); devm_kfree(dev->dev, priv); dev->dev_private = NULL; return ret; }
static int pl111_modeset_init(struct drm_device *dev) { struct drm_mode_config *mode_config; struct pl111_drm_dev_private *priv = dev->dev_private; int ret = 0; drm_mode_config_init(dev); mode_config = &dev->mode_config; mode_config->funcs = &mode_config_funcs; mode_config->min_width = 1; mode_config->max_width = 1024; mode_config->min_height = 1; mode_config->max_height = 768; ret = pl111_connector_init(dev); if (ret) { dev_err(dev->dev, "Failed to create pl111_drm_connector\n"); goto out_config; } /* Don't actually attach if we didn't find a drm_panel * attached to us. This will allow a kernel to include both * the fbdev pl111 driver and this one, and choose between * them based on which subsystem has support for the panel. */ if (!priv->connector.panel) { dev_info(dev->dev, "Disabling due to lack of DRM panel device.\n"); ret = -ENODEV; goto out_config; } ret = pl111_display_init(dev); if (ret != 0) { dev_err(dev->dev, "Failed to init display\n"); goto out_config; } ret = drm_vblank_init(dev, 1); if (ret != 0) { dev_err(dev->dev, "Failed to init vblank\n"); goto out_config; } drm_mode_config_reset(dev); priv->fbdev = drm_fbdev_cma_init(dev, 32, dev->mode_config.num_connector); drm_kms_helper_poll_init(dev); goto finish; out_config: drm_mode_config_cleanup(dev); finish: return ret; }
int evdi_driver_load(struct drm_device *dev, __always_unused unsigned long flags) { struct platform_device *platdev = NULL; struct evdi_device *evdi; int ret; EVDI_CHECKPT(); evdi = kzalloc(sizeof(struct evdi_device), GFP_KERNEL); if (!evdi) return -ENOMEM; evdi->ddev = dev; dev->dev_private = evdi; ret = evdi_cursor_alloc(&evdi->cursor); if (ret) goto err; EVDI_CHECKPT(); ret = evdi_modeset_init(dev); if (ret) goto err; ret = evdi_fbdev_init(dev); if (ret) goto err; ret = drm_vblank_init(dev, 1); if (ret) goto err_fb; ret = evdi_painter_init(evdi); if (ret) goto err_fb; evdi_stats_init(evdi); drm_kms_helper_poll_init(dev); platdev = to_platform_device(dev->dev); platform_set_drvdata(platdev, dev); return 0; err_fb: evdi_fbdev_cleanup(dev); err: kfree(evdi); EVDI_ERROR("%d\n", ret); if (evdi->cursor) evdi_cursor_free(evdi->cursor); return ret; }
/** * load - setup chip and create an initial config * @dev: DRM device * @flags: startup flags * * The driver load routine has to do several things: * - initialize the memory manager * - allocate initial config memory * - setup the DRM framebuffer with the allocated memory */ static int dev_load(struct drm_device *dev, unsigned long flags) { struct omap_drm_platform_data *pdata = dev->dev->platform_data; struct omap_drm_private *priv; int ret; DBG("load: dev=%p", dev); priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; priv->omaprev = pdata->omaprev; dev->dev_private = priv; priv->wq = alloc_ordered_workqueue("omapdrm", 0); spin_lock_init(&priv->list_lock); INIT_LIST_HEAD(&priv->obj_list); omap_gem_init(dev); ret = omap_modeset_init(dev); if (ret) { dev_err(dev->dev, "omap_modeset_init failed: ret=%d\n", ret); dev->dev_private = NULL; kfree(priv); return ret; } ret = drm_vblank_init(dev, priv->num_crtcs); if (ret) dev_warn(dev->dev, "could not init vblank\n"); priv->fbdev = omap_fbdev_init(dev); if (!priv->fbdev) { dev_warn(dev->dev, "omap_fbdev_init failed\n"); /* well, limp along without an fbdev.. maybe X11 will work? */ } /* store off drm_device for use in pm ops */ dev_set_drvdata(dev->dev, dev); drm_kms_helper_poll_init(dev); return 0; }
/** * load - setup chip and create an initial config * @dev: DRM device * @flags: startup flags * * The driver load routine has to do several things: * - initialize the memory manager * - allocate initial config memory * - setup the DRM framebuffer with the allocated memory */ static int dev_load(struct drm_device *dev, unsigned long flags) { struct omap_drm_private *priv; int ret; DBG("load: dev=%p", dev); drm_device = dev; priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) { dev_err(dev->dev, "could not allocate priv\n"); return -ENOMEM; } dev->dev_private = priv; priv->wq = alloc_workqueue("omapdrm", WQ_UNBOUND | WQ_NON_REENTRANT, 1); INIT_LIST_HEAD(&priv->obj_list); omap_gem_init(dev); ret = omap_modeset_init(dev); if (ret) { dev_err(dev->dev, "omap_modeset_init failed: ret=%d\n", ret); dev->dev_private = NULL; kfree(priv); return ret; } priv->fbdev = omap_fbdev_init(dev); if (!priv->fbdev) { dev_warn(dev->dev, "omap_fbdev_init failed\n"); /* well, limp along without an fbdev.. maybe X11 will work? */ } drm_kms_helper_poll_init(dev); ret = drm_vblank_init(dev, priv->num_crtcs); if (ret) { dev_warn(dev->dev, "could not init vblank\n"); } return 0; }
int fsl_dcu_drm_modeset_init(struct fsl_dcu_drm_device *fsl_dev) { drm_mode_config_init(fsl_dev->drm); fsl_dev->drm->mode_config.min_width = 0; fsl_dev->drm->mode_config.min_height = 0; fsl_dev->drm->mode_config.max_width = 2031; fsl_dev->drm->mode_config.max_height = 2047; fsl_dev->drm->mode_config.funcs = &fsl_dcu_drm_mode_config_funcs; drm_kms_helper_poll_init(fsl_dev->drm); fsl_dcu_drm_crtc_create(fsl_dev); fsl_dcu_drm_encoder_create(fsl_dev, &fsl_dev->crtc); fsl_dcu_drm_connector_create(fsl_dev, &fsl_dev->encoder); drm_mode_config_reset(fsl_dev->drm); return 0; }
static int dce_virtual_sw_init(void *handle) { int r, i; struct amdgpu_device *adev = (struct amdgpu_device *)handle; r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 229, &adev->crtc_irq); if (r) return r; adev->ddev->max_vblank_count = 0; adev->ddev->mode_config.funcs = &amdgpu_mode_funcs; adev->ddev->mode_config.max_width = 16384; adev->ddev->mode_config.max_height = 16384; adev->ddev->mode_config.preferred_depth = 24; adev->ddev->mode_config.prefer_shadow = 1; adev->ddev->mode_config.fb_base = adev->mc.aper_base; r = amdgpu_modeset_create_props(adev); if (r) return r; adev->ddev->mode_config.max_width = 16384; adev->ddev->mode_config.max_height = 16384; /* allocate crtcs, encoders, connectors */ for (i = 0; i < adev->mode_info.num_crtc; i++) { r = dce_virtual_crtc_init(adev, i); if (r) return r; r = dce_virtual_connector_encoder_init(adev, i); if (r) return r; } drm_kms_helper_poll_init(adev->ddev); adev->mode_info.mode_config_initialized = true; return 0; }
int shmob_drm_modeset_init(struct shmob_drm_device *sdev) { drm_mode_config_init(sdev->ddev); shmob_drm_crtc_create(sdev); shmob_drm_encoder_create(sdev); shmob_drm_connector_create(sdev, &sdev->encoder.encoder); drm_kms_helper_poll_init(sdev->ddev); sdev->ddev->mode_config.min_width = 0; sdev->ddev->mode_config.min_height = 0; sdev->ddev->mode_config.max_width = 4095; sdev->ddev->mode_config.max_height = 4095; sdev->ddev->mode_config.funcs = &shmob_drm_mode_config_funcs; drm_helper_disable_unused_functions(sdev->ddev); return 0; }
static int drv_load(struct drm_device *ddev) { struct platform_device *pdev = to_platform_device(ddev->dev); struct ltdc_device *ldev; int ret; DRM_DEBUG("%s\n", __func__); ldev = devm_kzalloc(ddev->dev, sizeof(*ldev), GFP_KERNEL); if (!ldev) return -ENOMEM; ddev->dev_private = (void *)ldev; drm_mode_config_init(ddev); /* * set max width and height as default value. * this value would be used to check framebuffer size limitation * at drm_mode_addfb(). */ ddev->mode_config.min_width = 0; ddev->mode_config.min_height = 0; ddev->mode_config.max_width = STM_MAX_FB_WIDTH; ddev->mode_config.max_height = STM_MAX_FB_HEIGHT; ddev->mode_config.funcs = &drv_mode_config_funcs; ret = ltdc_load(ddev); if (ret) goto err; drm_mode_config_reset(ddev); drm_kms_helper_poll_init(ddev); platform_set_drvdata(pdev, ddev); return 0; err: drm_mode_config_cleanup(ddev); return ret; }
static int pl111_modeset_init(struct drm_device *dev) { struct drm_mode_config *mode_config; struct pl111_drm_dev_private *priv = dev->dev_private; struct drm_panel *panel; struct drm_bridge *bridge; int ret = 0; drm_mode_config_init(dev); mode_config = &dev->mode_config; mode_config->funcs = &mode_config_funcs; mode_config->min_width = 1; mode_config->max_width = 1024; mode_config->min_height = 1; mode_config->max_height = 768; ret = drm_of_find_panel_or_bridge(dev->dev->of_node, 0, 0, &panel, &bridge); if (ret && ret != -ENODEV) return ret; if (panel) { bridge = drm_panel_bridge_add(panel, DRM_MODE_CONNECTOR_Unknown); if (IS_ERR(bridge)) { ret = PTR_ERR(bridge); goto out_config; } /* * TODO: when we are using a different bridge than a panel * (such as a dumb VGA connector) we need to devise a different * method to get the connector out of the bridge. */ } ret = pl111_display_init(dev); if (ret != 0) { dev_err(dev->dev, "Failed to init display\n"); goto out_bridge; } ret = drm_simple_display_pipe_attach_bridge(&priv->pipe, bridge); if (ret) return ret; priv->bridge = bridge; priv->panel = panel; priv->connector = panel->connector; ret = drm_vblank_init(dev, 1); if (ret != 0) { dev_err(dev->dev, "Failed to init vblank\n"); goto out_bridge; } drm_mode_config_reset(dev); drm_fb_cma_fbdev_init(dev, 32, 0); drm_kms_helper_poll_init(dev); goto finish; out_bridge: if (panel) drm_panel_bridge_remove(bridge); out_config: drm_mode_config_cleanup(dev); finish: return ret; }
static int pdev_probe(struct platform_device *pdev) { const struct soc_device_attribute *soc; struct omap_drm_private *priv; struct drm_device *ddev; unsigned int i; int ret; DBG("%s", pdev->name); if (omapdss_is_initialized() == false) return -EPROBE_DEFER; ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); if (ret) { dev_err(&pdev->dev, "Failed to set the DMA mask\n"); return ret; } omap_crtc_pre_init(); ret = omap_connect_dssdevs(); if (ret) goto err_crtc_uninit; /* Allocate and initialize the driver private structure. */ priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) { ret = -ENOMEM; goto err_disconnect_dssdevs; } priv->dispc_ops = dispc_get_ops(); soc = soc_device_match(omapdrm_soc_devices); priv->omaprev = soc ? (unsigned int)soc->data : 0; priv->wq = alloc_ordered_workqueue("omapdrm", 0); spin_lock_init(&priv->list_lock); INIT_LIST_HEAD(&priv->obj_list); /* Allocate and initialize the DRM device. */ ddev = drm_dev_alloc(&omap_drm_driver, &pdev->dev); if (IS_ERR(ddev)) { ret = PTR_ERR(ddev); goto err_free_priv; } ddev->dev_private = priv; platform_set_drvdata(pdev, ddev); /* Get memory bandwidth limits */ if (priv->dispc_ops->get_memory_bandwidth_limit) priv->max_bandwidth = priv->dispc_ops->get_memory_bandwidth_limit(); omap_gem_init(ddev); ret = omap_modeset_init(ddev); if (ret) { dev_err(&pdev->dev, "omap_modeset_init failed: ret=%d\n", ret); goto err_free_drm_dev; } /* Initialize vblank handling, start with all CRTCs disabled. */ ret = drm_vblank_init(ddev, priv->num_crtcs); if (ret) { dev_err(&pdev->dev, "could not init vblank\n"); goto err_cleanup_modeset; } for (i = 0; i < priv->num_crtcs; i++) drm_crtc_vblank_off(priv->crtcs[i]); priv->fbdev = omap_fbdev_init(ddev); drm_kms_helper_poll_init(ddev); omap_modeset_enable_external_hpd(); /* * Register the DRM device with the core and the connectors with * sysfs. */ ret = drm_dev_register(ddev, 0); if (ret) goto err_cleanup_helpers; return 0; err_cleanup_helpers: omap_modeset_disable_external_hpd(); drm_kms_helper_poll_fini(ddev); if (priv->fbdev) omap_fbdev_free(ddev); err_cleanup_modeset: drm_mode_config_cleanup(ddev); omap_drm_irq_uninstall(ddev); err_free_drm_dev: omap_gem_deinit(ddev); drm_dev_unref(ddev); err_free_priv: destroy_workqueue(priv->wq); kfree(priv); err_disconnect_dssdevs: omap_disconnect_dssdevs(); err_crtc_uninit: omap_crtc_pre_uninit(); return ret; }
static int mxsfb_load(struct drm_device *drm, unsigned long flags) { struct platform_device *pdev = to_platform_device(drm->dev); struct mxsfb_drm_private *mxsfb; struct resource *res; int ret; mxsfb = devm_kzalloc(&pdev->dev, sizeof(*mxsfb), GFP_KERNEL); if (!mxsfb) return -ENOMEM; drm->dev_private = mxsfb; mxsfb->devdata = &mxsfb_devdata[pdev->id_entry->driver_data]; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); mxsfb->base = devm_ioremap_resource(drm->dev, res); if (IS_ERR(mxsfb->base)) return PTR_ERR(mxsfb->base); mxsfb->clk = devm_clk_get(drm->dev, NULL); if (IS_ERR(mxsfb->clk)) return PTR_ERR(mxsfb->clk); mxsfb->clk_axi = devm_clk_get(drm->dev, "axi"); if (IS_ERR(mxsfb->clk_axi)) mxsfb->clk_axi = NULL; mxsfb->clk_disp_axi = devm_clk_get(drm->dev, "disp_axi"); if (IS_ERR(mxsfb->clk_disp_axi)) mxsfb->clk_disp_axi = NULL; ret = dma_set_mask_and_coherent(drm->dev, DMA_BIT_MASK(32)); if (ret) return ret; pm_runtime_enable(drm->dev); ret = drm_vblank_init(drm, drm->mode_config.num_crtc); if (ret < 0) { dev_err(drm->dev, "Failed to initialise vblank\n"); goto err_vblank; } /* Modeset init */ drm_mode_config_init(drm); ret = mxsfb_create_output(drm); if (ret < 0) { dev_err(drm->dev, "Failed to create outputs\n"); goto err_vblank; } ret = drm_simple_display_pipe_init(drm, &mxsfb->pipe, &mxsfb_funcs, mxsfb_formats, ARRAY_SIZE(mxsfb_formats), &mxsfb->connector); if (ret < 0) { dev_err(drm->dev, "Cannot setup simple display pipe\n"); goto err_vblank; } ret = drm_panel_attach(mxsfb->panel, &mxsfb->connector); if (ret) { dev_err(drm->dev, "Cannot connect panel\n"); goto err_vblank; } drm->mode_config.min_width = MXSFB_MIN_XRES; drm->mode_config.min_height = MXSFB_MIN_YRES; drm->mode_config.max_width = MXSFB_MAX_XRES; drm->mode_config.max_height = MXSFB_MAX_YRES; drm->mode_config.funcs = &mxsfb_mode_config_funcs; drm_mode_config_reset(drm); pm_runtime_get_sync(drm->dev); ret = drm_irq_install(drm, platform_get_irq(pdev, 0)); pm_runtime_put_sync(drm->dev); if (ret < 0) { dev_err(drm->dev, "Failed to install IRQ handler\n"); goto err_irq; } drm_kms_helper_poll_init(drm); mxsfb->fbdev = drm_fbdev_cma_init(drm, 32, drm->mode_config.num_crtc, drm->mode_config.num_connector); if (IS_ERR(mxsfb->fbdev)) { mxsfb->fbdev = NULL; dev_err(drm->dev, "Failed to init FB CMA area\n"); goto err_cma; } platform_set_drvdata(pdev, drm); drm_helper_hpd_irq_event(drm); return 0; err_cma: drm_irq_uninstall(drm); err_irq: drm_panel_detach(mxsfb->panel); err_vblank: pm_runtime_disable(drm->dev); return ret; }
int i915_load_modeset_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; int ret; ret = intel_parse_bios(dev); if (ret) DRM_INFO("failed to find VBIOS tables\n"); #if 0 intel_register_dsm_handler(); #endif /* IIR "flip pending" bit means done if this bit is set */ if (IS_GEN3(dev) && (I915_READ(ECOSKPD) & ECO_FLIP_DONE)) dev_priv->flip_pending_is_done = true; #ifdef notyet ret = vga_switcheroo_register_client(dev->pdev, &i915_switcheroo_ops); if (ret) goto cleanup_vga_client; /* Initialise stolen first so that we may reserve preallocated * objects for the BIOS to KMS transition. */ ret = i915_gem_init_stolen(dev); if (ret) goto cleanup_vga_switcheroo; #endif intel_modeset_init(dev); ret = i915_gem_init(dev); if (ret) goto cleanup_gem_stolen; intel_modeset_gem_init(dev); ret = drm_irq_install(dev); if (ret) goto cleanup_gem; /* Always safe in the mode setting case. */ /* FIXME: do pre/post-mode set stuff in core KMS code */ dev->vblank_disable_allowed = 1; ret = intel_fbdev_init(dev); if (ret) goto cleanup_irq; drm_kms_helper_poll_init(dev); /* We're off and running w/KMS */ dev_priv->mm.suspended = 0; return (0); cleanup_irq: drm_irq_uninstall(dev); cleanup_gem: DRM_LOCK(); i915_gem_cleanup_ringbuffer(dev); DRM_UNLOCK(); i915_gem_cleanup_aliasing_ppgtt(dev); cleanup_gem_stolen: #ifdef notyet i915_gem_cleanup_stolen(dev); #endif return (ret); }
int nouveau_card_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_engine *engine; int ret; NV_DEBUG(dev, "prev state = %d\n", dev_priv->init_state); if (dev_priv->init_state == NOUVEAU_CARD_INIT_DONE) return 0; vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode); vga_switcheroo_register_client(dev->pdev, nouveau_switcheroo_set_state, nouveau_switcheroo_can_switch); /* Initialise internal driver API hooks */ ret = nouveau_init_engine_ptrs(dev); if (ret) goto out; engine = &dev_priv->engine; dev_priv->init_state = NOUVEAU_CARD_INIT_FAILED; spin_lock_init(&dev_priv->context_switch_lock); /* Parse BIOS tables / Run init tables if card not POSTed */ if (drm_core_check_feature(dev, DRIVER_MODESET)) { ret = nouveau_bios_init(dev); if (ret) goto out; } ret = nouveau_mem_detect(dev); if (ret) goto out_bios; ret = nouveau_gpuobj_early_init(dev); if (ret) goto out_bios; /* Initialise instance memory, must happen before mem_init so we * know exactly how much VRAM we're able to use for "normal" * purposes. */ ret = engine->instmem.init(dev); if (ret) goto out_gpuobj_early; /* Setup the memory manager */ ret = nouveau_mem_init(dev); if (ret) goto out_instmem; ret = nouveau_gpuobj_init(dev); if (ret) goto out_mem; /* PMC */ ret = engine->mc.init(dev); if (ret) goto out_gpuobj; /* PTIMER */ ret = engine->timer.init(dev); if (ret) goto out_mc; /* PFB */ ret = engine->fb.init(dev); if (ret) goto out_timer; if (nouveau_noaccel) engine->graph.accel_blocked = true; else { /* PGRAPH */ ret = engine->graph.init(dev); if (ret) goto out_fb; /* PFIFO */ ret = engine->fifo.init(dev); if (ret) goto out_graph; } /* this call irq_preinstall, register irq handler and * call irq_postinstall */ ret = drm_irq_install(dev); if (ret) goto out_fifo; ret = drm_vblank_init(dev, 0); if (ret) goto out_irq; /* what about PVIDEO/PCRTC/PRAMDAC etc? */ if (!engine->graph.accel_blocked) { ret = nouveau_card_init_channel(dev); if (ret) goto out_irq; } if (drm_core_check_feature(dev, DRIVER_MODESET)) { if (dev_priv->card_type >= NV_50) ret = nv50_display_create(dev); else ret = nv04_display_create(dev); if (ret) goto out_channel; } ret = nouveau_backlight_init(dev); if (ret) NV_ERROR(dev, "Error %d registering backlight\n", ret); dev_priv->init_state = NOUVEAU_CARD_INIT_DONE; if (drm_core_check_feature(dev, DRIVER_MODESET)) { nouveau_fbcon_init(dev); drm_kms_helper_poll_init(dev); } return 0; out_channel: if (dev_priv->channel) { nouveau_channel_free(dev_priv->channel); dev_priv->channel = NULL; } out_irq: drm_irq_uninstall(dev); out_fifo: if (!nouveau_noaccel) engine->fifo.takedown(dev); out_graph: if (!nouveau_noaccel) engine->graph.takedown(dev); out_fb: engine->fb.takedown(dev); out_timer: engine->timer.takedown(dev); out_mc: engine->mc.takedown(dev); out_gpuobj: nouveau_gpuobj_takedown(dev); out_mem: nouveau_sgdma_takedown(dev); nouveau_mem_close(dev); out_instmem: engine->instmem.takedown(dev); out_gpuobj_early: nouveau_gpuobj_late_takedown(dev); out_bios: nouveau_bios_takedown(dev); out: vga_client_register(dev->pdev, NULL, NULL, NULL); return ret; }
int nouveau_card_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_engine *engine; int ret; vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode); vga_switcheroo_register_client(dev->pdev, nouveau_switcheroo_set_state, nouveau_switcheroo_reprobe, nouveau_switcheroo_can_switch); /* Initialise internal driver API hooks */ ret = nouveau_init_engine_ptrs(dev); if (ret) goto out; engine = &dev_priv->engine; spin_lock_init(&dev_priv->channels.lock); spin_lock_init(&dev_priv->tile.lock); spin_lock_init(&dev_priv->context_switch_lock); spin_lock_init(&dev_priv->vm_lock); /* Make the CRTCs and I2C buses accessible */ ret = engine->display.early_init(dev); if (ret) goto out; /* Parse BIOS tables / Run init tables if card not POSTed */ ret = nouveau_bios_init(dev); if (ret) goto out_display_early; nouveau_pm_init(dev); ret = nouveau_mem_vram_init(dev); if (ret) goto out_bios; ret = nouveau_gpuobj_init(dev); if (ret) goto out_vram; ret = engine->instmem.init(dev); if (ret) goto out_gpuobj; ret = nouveau_mem_gart_init(dev); if (ret) goto out_instmem; /* PMC */ ret = engine->mc.init(dev); if (ret) goto out_gart; /* PGPIO */ ret = engine->gpio.init(dev); if (ret) goto out_mc; /* PTIMER */ ret = engine->timer.init(dev); if (ret) goto out_gpio; /* PFB */ ret = engine->fb.init(dev); if (ret) goto out_timer; if (nouveau_noaccel) engine->graph.accel_blocked = true; else { /* PGRAPH */ ret = engine->graph.init(dev); if (ret) goto out_fb; /* PCRYPT */ ret = engine->crypt.init(dev); if (ret) goto out_graph; /* PFIFO */ ret = engine->fifo.init(dev); if (ret) goto out_crypt; } ret = engine->display.create(dev); if (ret) goto out_fifo; ret = drm_vblank_init(dev, nv_two_heads(dev) ? 2 : 1); if (ret) goto out_vblank; ret = nouveau_irq_init(dev); if (ret) goto out_vblank; /* what about PVIDEO/PCRTC/PRAMDAC etc? */ if (!engine->graph.accel_blocked) { ret = nouveau_fence_init(dev); if (ret) goto out_irq; ret = nouveau_card_init_channel(dev); if (ret) goto out_fence; } nouveau_fbcon_init(dev); drm_kms_helper_poll_init(dev); return 0; out_fence: nouveau_fence_fini(dev); out_irq: nouveau_irq_fini(dev); out_vblank: drm_vblank_cleanup(dev); engine->display.destroy(dev); out_fifo: if (!nouveau_noaccel) engine->fifo.takedown(dev); out_crypt: if (!nouveau_noaccel) engine->crypt.takedown(dev); out_graph: if (!nouveau_noaccel) engine->graph.takedown(dev); out_fb: engine->fb.takedown(dev); out_timer: engine->timer.takedown(dev); out_gpio: engine->gpio.takedown(dev); out_mc: engine->mc.takedown(dev); out_gart: nouveau_mem_gart_fini(dev); out_instmem: engine->instmem.takedown(dev); out_gpuobj: nouveau_gpuobj_takedown(dev); out_vram: nouveau_mem_vram_fini(dev); out_bios: nouveau_pm_fini(dev); nouveau_bios_takedown(dev); out_display_early: engine->display.late_takedown(dev); out: vga_client_register(dev->pdev, NULL, NULL, NULL); return ret; }
static int arcpgu_load(struct drm_device *drm) { struct platform_device *pdev = to_platform_device(drm->dev); struct arcpgu_drm_private *arcpgu; struct device_node *encoder_node; struct resource *res; int ret; arcpgu = devm_kzalloc(&pdev->dev, sizeof(*arcpgu), GFP_KERNEL); if (arcpgu == NULL) return -ENOMEM; drm->dev_private = arcpgu; arcpgu->clk = devm_clk_get(drm->dev, "pxlclk"); if (IS_ERR(arcpgu->clk)) return PTR_ERR(arcpgu->clk); arcpgu_setup_mode_config(drm); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); arcpgu->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(arcpgu->regs)) return PTR_ERR(arcpgu->regs); dev_info(drm->dev, "arc_pgu ID: 0x%x\n", arc_pgu_read(arcpgu, ARCPGU_REG_ID)); /* Get the optional framebuffer memory resource */ ret = of_reserved_mem_device_init(drm->dev); if (ret && ret != -ENODEV) return ret; if (dma_set_mask_and_coherent(drm->dev, DMA_BIT_MASK(32))) return -ENODEV; if (arc_pgu_setup_crtc(drm) < 0) return -ENODEV; /* find the encoder node and initialize it */ encoder_node = of_parse_phandle(drm->dev->of_node, "encoder-slave", 0); if (encoder_node) { ret = arcpgu_drm_hdmi_init(drm, encoder_node); of_node_put(encoder_node); if (ret < 0) return ret; } else { ret = arcpgu_drm_sim_init(drm, NULL); if (ret < 0) return ret; } drm_mode_config_reset(drm); drm_kms_helper_poll_init(drm); arcpgu->fbdev = drm_fbdev_cma_init(drm, 16, drm->mode_config.num_crtc, drm->mode_config.num_connector); if (IS_ERR(arcpgu->fbdev)) { ret = PTR_ERR(arcpgu->fbdev); arcpgu->fbdev = NULL; return -ENODEV; } platform_set_drvdata(pdev, arcpgu); return 0; }
static int sun4i_drv_bind(struct device *dev) { struct drm_device *drm; struct sun4i_drv *drv; int ret; drm = drm_dev_alloc(&sun4i_drv_driver, dev); if (IS_ERR(drm)) return PTR_ERR(drm); drv = devm_kzalloc(dev, sizeof(*drv), GFP_KERNEL); if (!drv) { ret = -ENOMEM; goto free_drm; } dev_set_drvdata(dev, drm); drm->dev_private = drv; INIT_LIST_HEAD(&drv->frontend_list); INIT_LIST_HEAD(&drv->engine_list); INIT_LIST_HEAD(&drv->tcon_list); ret = of_reserved_mem_device_init(dev); if (ret && ret != -ENODEV) { dev_err(drm->dev, "Couldn't claim our memory region\n"); goto free_drm; } drm_mode_config_init(drm); drm->mode_config.allow_fb_modifiers = true; ret = component_bind_all(drm->dev, drm); if (ret) { dev_err(drm->dev, "Couldn't bind all pipelines components\n"); goto cleanup_mode_config; } /* drm_vblank_init calls kcalloc, which can fail */ ret = drm_vblank_init(drm, drm->mode_config.num_crtc); if (ret) goto cleanup_mode_config; drm->irq_enabled = true; /* Remove early framebuffers (ie. simplefb) */ drm_fb_helper_remove_conflicting_framebuffers(NULL, "sun4i-drm-fb", false); sun4i_framebuffer_init(drm); /* Enable connectors polling */ drm_kms_helper_poll_init(drm); ret = drm_dev_register(drm, 0); if (ret) goto finish_poll; drm_fbdev_generic_setup(drm, 32); return 0; finish_poll: drm_kms_helper_poll_fini(drm); cleanup_mode_config: drm_mode_config_cleanup(drm); of_reserved_mem_device_release(dev); free_drm: drm_dev_put(drm); return ret; }
static int hdlcd_drm_bind(struct device *dev) { struct drm_device *drm; struct hdlcd_drm_private *hdlcd; int ret; hdlcd = devm_kzalloc(dev, sizeof(*hdlcd), GFP_KERNEL); if (!hdlcd) return -ENOMEM; drm = drm_dev_alloc(&hdlcd_driver, dev); if (IS_ERR(drm)) return PTR_ERR(drm); drm->dev_private = hdlcd; dev_set_drvdata(dev, drm); hdlcd_setup_mode_config(drm); ret = hdlcd_load(drm, 0); if (ret) goto err_free; ret = drm_dev_register(drm, 0); if (ret) goto err_unload; ret = component_bind_all(dev, drm); if (ret) { DRM_ERROR("Failed to bind all components\n"); goto err_unregister; } ret = pm_runtime_set_active(dev); if (ret) goto err_pm_active; pm_runtime_enable(dev); ret = drm_vblank_init(drm, drm->mode_config.num_crtc); if (ret < 0) { DRM_ERROR("failed to initialise vblank\n"); goto err_vblank; } drm_mode_config_reset(drm); drm_kms_helper_poll_init(drm); hdlcd->fbdev = drm_fbdev_cma_init(drm, 32, drm->mode_config.num_crtc, drm->mode_config.num_connector); if (IS_ERR(hdlcd->fbdev)) { ret = PTR_ERR(hdlcd->fbdev); hdlcd->fbdev = NULL; goto err_fbdev; } return 0; err_fbdev: drm_kms_helper_poll_fini(drm); drm_mode_config_cleanup(drm); drm_vblank_cleanup(drm); err_vblank: pm_runtime_disable(drm->dev); err_pm_active: component_unbind_all(dev, drm); err_unregister: drm_dev_unregister(drm); err_unload: drm_irq_uninstall(drm); of_reserved_mem_device_release(drm->dev); err_free: dev_set_drvdata(dev, NULL); drm_dev_unref(drm); return ret; }
static int armada_drm_load(struct drm_device *dev, unsigned long flags) { struct armada_private *priv; struct resource *mem = NULL; int ret, n; for (n = 0; ; n++) { struct resource *r = platform_get_resource(dev->platformdev, IORESOURCE_MEM, n); if (!r) break; /* Resources above 64K are graphics memory */ if (resource_size(r) > SZ_64K) mem = r; else return -EINVAL; } if (!mem) return -ENXIO; if (!devm_request_mem_region(dev->dev, mem->start, resource_size(mem), "armada-drm")) return -EBUSY; priv = devm_kzalloc(dev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) { DRM_ERROR("failed to allocate private\n"); return -ENOMEM; } platform_set_drvdata(dev->platformdev, dev); dev->dev_private = priv; INIT_WORK(&priv->fb_unref_work, armada_drm_unref_work); INIT_KFIFO(priv->fb_unref); /* Mode setting support */ drm_mode_config_init(dev); dev->mode_config.min_width = 320; dev->mode_config.min_height = 200; /* * With vscale enabled, the maximum width is 1920 due to the * 1920 by 3 lines RAM */ dev->mode_config.max_width = 1920; dev->mode_config.max_height = 2048; dev->mode_config.preferred_depth = 24; dev->mode_config.funcs = &armada_drm_mode_config_funcs; drm_mm_init(&priv->linear, mem->start, resource_size(mem)); mutex_init(&priv->linear_lock); ret = component_bind_all(dev->dev, dev); if (ret) goto err_kms; ret = drm_vblank_init(dev, dev->mode_config.num_crtc); if (ret) goto err_comp; dev->irq_enabled = true; dev->vblank_disable_allowed = 1; ret = armada_fbdev_init(dev); if (ret) goto err_comp; drm_kms_helper_poll_init(dev); return 0; err_comp: component_unbind_all(dev->dev, dev); err_kms: drm_mode_config_cleanup(dev); drm_mm_takedown(&priv->linear); flush_work(&priv->fb_unref_work); return ret; }
static int sun4i_drv_bind(struct device *dev) { struct drm_device *drm; struct sun4i_drv *drv; int ret; drm = drm_dev_alloc(&sun4i_drv_driver, dev); if (IS_ERR(drm)) return PTR_ERR(drm); drv = devm_kzalloc(dev, sizeof(*drv), GFP_KERNEL); if (!drv) { ret = -ENOMEM; goto free_drm; } drm->dev_private = drv; ret = of_reserved_mem_device_init(dev); if (ret && ret != -ENODEV) { dev_err(drm->dev, "Couldn't claim our memory region\n"); goto free_drm; } /* drm_vblank_init calls kcalloc, which can fail */ ret = drm_vblank_init(drm, 1); if (ret) goto free_mem_region; drm_mode_config_init(drm); ret = component_bind_all(drm->dev, drm); if (ret) { dev_err(drm->dev, "Couldn't bind all pipelines components\n"); goto cleanup_mode_config; } drm->irq_enabled = true; /* Remove early framebuffers (ie. simplefb) */ sun4i_remove_framebuffers(); /* Create our framebuffer */ drv->fbdev = sun4i_framebuffer_init(drm); if (IS_ERR(drv->fbdev)) { dev_err(drm->dev, "Couldn't create our framebuffer\n"); ret = PTR_ERR(drv->fbdev); goto cleanup_mode_config; } /* Enable connectors polling */ drm_kms_helper_poll_init(drm); ret = drm_dev_register(drm, 0); if (ret) goto finish_poll; return 0; finish_poll: drm_kms_helper_poll_fini(drm); sun4i_framebuffer_free(drm); cleanup_mode_config: drm_mode_config_cleanup(drm); drm_vblank_cleanup(drm); free_mem_region: of_reserved_mem_device_release(dev); free_drm: drm_dev_unref(drm); return ret; }
static int sun4i_drv_bind(struct device *dev) { struct drm_device *drm; struct sun4i_drv *drv; int ret; drm = drm_dev_alloc(&sun4i_drv_driver, dev); if (!drm) return -ENOMEM; drv = devm_kzalloc(dev, sizeof(*drv), GFP_KERNEL); if (!drv) { ret = -ENOMEM; goto free_drm; } drm->dev_private = drv; drm_vblank_init(drm, 1); drm_mode_config_init(drm); ret = component_bind_all(drm->dev, drm); if (ret) { dev_err(drm->dev, "Couldn't bind all pipelines components\n"); goto free_drm; } /* Create our layers */ drv->layers = sun4i_layers_init(drm); if (!drv->layers) { dev_err(drm->dev, "Couldn't create the planes\n"); ret = -EINVAL; goto free_drm; } /* Create our CRTC */ drv->crtc = sun4i_crtc_init(drm); if (!drv->crtc) { dev_err(drm->dev, "Couldn't create the CRTC\n"); ret = -EINVAL; goto free_drm; } drm->irq_enabled = true; /* Remove early framebuffers (ie. simplefb) */ sun4i_remove_framebuffers(); /* Create our framebuffer */ drv->fbdev = sun4i_framebuffer_init(drm); if (IS_ERR(drv->fbdev)) { dev_err(drm->dev, "Couldn't create our framebuffer\n"); ret = PTR_ERR(drv->fbdev); goto free_drm; } /* Enable connectors polling */ drm_kms_helper_poll_init(drm); ret = drm_dev_register(drm, 0); if (ret) goto free_drm; return 0; free_drm: drm_dev_unref(drm); return ret; }
static int armada_drm_load(struct drm_device *dev, unsigned long flags) { const struct platform_device_id *id; const struct armada_variant *variant; struct armada_private *priv; struct resource *res[ARRAY_SIZE(priv->dcrtc)]; struct resource *mem = NULL; int ret, n, i; memset(res, 0, sizeof(res)); for (n = i = 0; ; n++) { struct resource *r = platform_get_resource(dev->platformdev, IORESOURCE_MEM, n); if (!r) break; /* Resources above 64K are graphics memory */ if (resource_size(r) > SZ_64K) mem = r; else if (i < ARRAY_SIZE(priv->dcrtc)) res[i++] = r; else return -EINVAL; } if (!mem) return -ENXIO; if (!devm_request_mem_region(dev->dev, mem->start, resource_size(mem), "armada-drm")) return -EBUSY; priv = devm_kzalloc(dev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) { DRM_ERROR("failed to allocate private\n"); return -ENOMEM; } platform_set_drvdata(dev->platformdev, dev); dev->dev_private = priv; /* Get the implementation specific driver data. */ id = platform_get_device_id(dev->platformdev); if (!id) return -ENXIO; variant = (const struct armada_variant *)id->driver_data; INIT_WORK(&priv->fb_unref_work, armada_drm_unref_work); INIT_KFIFO(priv->fb_unref); /* Mode setting support */ drm_mode_config_init(dev); dev->mode_config.min_width = 320; dev->mode_config.min_height = 200; /* * With vscale enabled, the maximum width is 1920 due to the * 1920 by 3 lines RAM */ dev->mode_config.max_width = 1920; dev->mode_config.max_height = 2048; dev->mode_config.preferred_depth = 24; dev->mode_config.funcs = &armada_drm_mode_config_funcs; drm_mm_init(&priv->linear, mem->start, resource_size(mem)); /* Create all LCD controllers */ for (n = 0; n < ARRAY_SIZE(priv->dcrtc); n++) { int irq; if (!res[n]) break; irq = platform_get_irq(dev->platformdev, n); if (irq < 0) goto err_kms; ret = armada_drm_crtc_create(dev, dev->dev, res[n], irq, variant, NULL); if (ret) goto err_kms; } if (is_componentized(dev->dev)) { ret = component_bind_all(dev->dev, dev); if (ret) goto err_kms; } else { #ifdef CONFIG_DRM_ARMADA_TDA1998X ret = armada_drm_connector_slave_create(dev, &tda19988_config); if (ret) goto err_kms; #endif } ret = drm_vblank_init(dev, dev->mode_config.num_crtc); if (ret) goto err_comp; dev->irq_enabled = true; dev->vblank_disable_allowed = 1; ret = armada_fbdev_init(dev); if (ret) goto err_comp; drm_kms_helper_poll_init(dev); return 0; err_comp: if (is_componentized(dev->dev)) component_unbind_all(dev->dev, dev); err_kms: drm_mode_config_cleanup(dev); drm_mm_takedown(&priv->linear); flush_work(&priv->fb_unref_work); return ret; }
static int malidp_bind(struct device *dev) { struct resource *res; struct drm_device *drm; struct device_node *ep; struct malidp_drm *malidp; struct malidp_hw_device *hwdev; struct platform_device *pdev = to_platform_device(dev); /* number of lines for the R, G and B output */ u8 output_width[MAX_OUTPUT_CHANNELS]; int ret = 0, i; u32 version, out_depth = 0; malidp = devm_kzalloc(dev, sizeof(*malidp), GFP_KERNEL); if (!malidp) return -ENOMEM; hwdev = devm_kzalloc(dev, sizeof(*hwdev), GFP_KERNEL); if (!hwdev) return -ENOMEM; /* * copy the associated data from malidp_drm_of_match to avoid * having to keep a reference to the OF node after binding */ memcpy(hwdev, of_device_get_match_data(dev), sizeof(*hwdev)); malidp->dev = hwdev; INIT_LIST_HEAD(&malidp->event_list); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); hwdev->regs = devm_ioremap_resource(dev, res); if (IS_ERR(hwdev->regs)) return PTR_ERR(hwdev->regs); hwdev->pclk = devm_clk_get(dev, "pclk"); if (IS_ERR(hwdev->pclk)) return PTR_ERR(hwdev->pclk); hwdev->aclk = devm_clk_get(dev, "aclk"); if (IS_ERR(hwdev->aclk)) return PTR_ERR(hwdev->aclk); hwdev->mclk = devm_clk_get(dev, "mclk"); if (IS_ERR(hwdev->mclk)) return PTR_ERR(hwdev->mclk); hwdev->pxlclk = devm_clk_get(dev, "pxlclk"); if (IS_ERR(hwdev->pxlclk)) return PTR_ERR(hwdev->pxlclk); /* Get the optional framebuffer memory resource */ ret = of_reserved_mem_device_init(dev); if (ret && ret != -ENODEV) return ret; drm = drm_dev_alloc(&malidp_driver, dev); if (IS_ERR(drm)) { ret = PTR_ERR(drm); goto alloc_fail; } /* Enable APB clock in order to get access to the registers */ clk_prepare_enable(hwdev->pclk); /* * Enable AXI clock and main clock so that prefetch can start once * the registers are set */ clk_prepare_enable(hwdev->aclk); clk_prepare_enable(hwdev->mclk); ret = hwdev->query_hw(hwdev); if (ret) { DRM_ERROR("Invalid HW configuration\n"); goto query_hw_fail; } version = malidp_hw_read(hwdev, hwdev->map.dc_base + MALIDP_DE_CORE_ID); DRM_INFO("found ARM Mali-DP%3x version r%dp%d\n", version >> 16, (version >> 12) & 0xf, (version >> 8) & 0xf); /* set the number of lines used for output of RGB data */ ret = of_property_read_u8_array(dev->of_node, "arm,malidp-output-port-lines", output_width, MAX_OUTPUT_CHANNELS); if (ret) goto query_hw_fail; for (i = 0; i < MAX_OUTPUT_CHANNELS; i++) out_depth = (out_depth << 8) | (output_width[i] & 0xf); malidp_hw_write(hwdev, out_depth, hwdev->map.out_depth_base); drm->dev_private = malidp; dev_set_drvdata(dev, drm); atomic_set(&malidp->config_valid, 0); init_waitqueue_head(&malidp->wq); ret = malidp_init(drm); if (ret < 0) goto init_fail; ret = drm_dev_register(drm, 0); if (ret) goto register_fail; /* Set the CRTC's port so that the encoder component can find it */ ep = of_graph_get_next_endpoint(dev->of_node, NULL); if (!ep) { ret = -EINVAL; goto port_fail; } malidp->crtc.port = of_get_next_parent(ep); ret = component_bind_all(dev, drm); if (ret) { DRM_ERROR("Failed to bind all components\n"); goto bind_fail; } ret = malidp_irq_init(pdev); if (ret < 0) goto irq_init_fail; ret = drm_vblank_init(drm, drm->mode_config.num_crtc); if (ret < 0) { DRM_ERROR("failed to initialise vblank\n"); goto vblank_fail; } drm_mode_config_reset(drm); malidp->fbdev = drm_fbdev_cma_init(drm, 32, drm->mode_config.num_crtc, drm->mode_config.num_connector); if (IS_ERR(malidp->fbdev)) { ret = PTR_ERR(malidp->fbdev); malidp->fbdev = NULL; goto fbdev_fail; } drm_kms_helper_poll_init(drm); return 0; fbdev_fail: drm_vblank_cleanup(drm); vblank_fail: malidp_se_irq_fini(drm); malidp_de_irq_fini(drm); irq_init_fail: component_unbind_all(dev, drm); bind_fail: of_node_put(malidp->crtc.port); malidp->crtc.port = NULL; port_fail: drm_dev_unregister(drm); register_fail: malidp_de_planes_destroy(drm); drm_mode_config_cleanup(drm); init_fail: drm->dev_private = NULL; dev_set_drvdata(dev, NULL); query_hw_fail: clk_disable_unprepare(hwdev->mclk); clk_disable_unprepare(hwdev->aclk); clk_disable_unprepare(hwdev->pclk); drm_dev_unref(drm); alloc_fail: of_reserved_mem_device_release(dev); return ret; }
static int atmel_hlcdc_dc_load(struct drm_device *dev) { struct platform_device *pdev = to_platform_device(dev->dev); const struct of_device_id *match; struct atmel_hlcdc_dc *dc; int ret; match = of_match_node(atmel_hlcdc_of_match, dev->dev->parent->of_node); if (!match) { dev_err(&pdev->dev, "invalid compatible string\n"); return -ENODEV; } if (!match->data) { dev_err(&pdev->dev, "invalid hlcdc description\n"); return -EINVAL; } dc = devm_kzalloc(dev->dev, sizeof(*dc), GFP_KERNEL); if (!dc) return -ENOMEM; dc->wq = alloc_ordered_workqueue("atmel-hlcdc-dc", 0); if (!dc->wq) return -ENOMEM; init_waitqueue_head(&dc->commit.wait); dc->desc = match->data; dc->hlcdc = dev_get_drvdata(dev->dev->parent); dev->dev_private = dc; ret = clk_prepare_enable(dc->hlcdc->periph_clk); if (ret) { dev_err(dev->dev, "failed to enable periph_clk\n"); goto err_destroy_wq; } pm_runtime_enable(dev->dev); ret = drm_vblank_init(dev, 1); if (ret < 0) { dev_err(dev->dev, "failed to initialize vblank\n"); goto err_periph_clk_disable; } ret = atmel_hlcdc_dc_modeset_init(dev); if (ret < 0) { dev_err(dev->dev, "failed to initialize mode setting\n"); goto err_periph_clk_disable; } drm_mode_config_reset(dev); pm_runtime_get_sync(dev->dev); ret = drm_irq_install(dev, dc->hlcdc->irq); pm_runtime_put_sync(dev->dev); if (ret < 0) { dev_err(dev->dev, "failed to install IRQ handler\n"); goto err_periph_clk_disable; } platform_set_drvdata(pdev, dev); drm_kms_helper_poll_init(dev); /* force connectors detection */ drm_helper_hpd_irq_event(dev); return 0; err_periph_clk_disable: pm_runtime_disable(dev->dev); clk_disable_unprepare(dc->hlcdc->periph_clk); err_destroy_wq: destroy_workqueue(dc->wq); return ret; }
static int i915_load_modeset_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; int ret; ret = intel_parse_bios(dev); if (ret) DRM_INFO("failed to find VBIOS tables\n"); /* If we have > 1 VGA cards, then we need to arbitrate access * to the common VGA resources. * * If we are a secondary display controller (!PCI_DISPLAY_CLASS_VGA), * then we do not take part in VGA arbitration and the * vga_client_register() fails with -ENODEV. */ ret = vga_client_register(dev->pdev, dev, NULL, i915_vga_set_decode); if (ret && ret != -ENODEV) goto out; intel_register_dsm_handler(); ret = vga_switcheroo_register_client(dev->pdev, &i915_switcheroo_ops, false); if (ret) goto cleanup_vga_client; /* Initialise stolen first so that we may reserve preallocated * objects for the BIOS to KMS transition. */ ret = i915_gem_init_stolen(dev); if (ret) goto cleanup_vga_switcheroo; intel_power_domains_init_hw(dev_priv); ret = intel_irq_install(dev_priv); if (ret) goto cleanup_gem_stolen; /* Important: The output setup functions called by modeset_init need * working irqs for e.g. gmbus and dp aux transfers. */ intel_modeset_init(dev); ret = i915_gem_init(dev); if (ret) goto cleanup_irq; intel_modeset_gem_init(dev); /* Always safe in the mode setting case. */ /* FIXME: do pre/post-mode set stuff in core KMS code */ dev->vblank_disable_allowed = true; if (INTEL_INFO(dev)->num_pipes == 0) return 0; ret = intel_fbdev_init(dev); if (ret) goto cleanup_gem; /* Only enable hotplug handling once the fbdev is fully set up. */ intel_hpd_init(dev_priv); /* * Some ports require correctly set-up hpd registers for detection to * work properly (leading to ghost connected connector status), e.g. VGA * on gm45. Hence we can only set up the initial fbdev config after hpd * irqs are fully enabled. Now we should scan for the initial config * only once hotplug handling is enabled, but due to screwed-up locking * around kms/fbdev init we can't protect the fdbev initial config * scanning against hotplug events. Hence do this first and ignore the * tiny window where we will loose hotplug notifactions. */ async_schedule(intel_fbdev_initial_config, dev_priv); drm_kms_helper_poll_init(dev); return 0; cleanup_gem: mutex_lock(&dev->struct_mutex); i915_gem_cleanup_ringbuffer(dev); i915_gem_context_fini(dev); mutex_unlock(&dev->struct_mutex); cleanup_irq: drm_irq_uninstall(dev); cleanup_gem_stolen: i915_gem_cleanup_stolen(dev); cleanup_vga_switcheroo: vga_switcheroo_unregister_client(dev->pdev); cleanup_vga_client: vga_client_register(dev->pdev, NULL, NULL, NULL); out: return ret; }
static int xylon_drm_load(struct drm_device *dev, unsigned long flags) { struct platform_device *pdev = dev->platformdev; struct xylon_drm_device *xdev; unsigned int bpp; int ret; xdev = devm_kzalloc(dev->dev, sizeof(*xdev), GFP_KERNEL); if (!xdev) return -ENOMEM; xdev->dev = dev; dev->dev_private = xdev; drm_mode_config_init(dev); drm_kms_helper_poll_init(dev); xdev->crtc = xylon_drm_crtc_create(dev); if (IS_ERR(xdev->crtc)) { DRM_ERROR("failed create xylon crtc\n"); ret = PTR_ERR(xdev->crtc); goto err_out; } xylon_drm_mode_config_init(dev); xdev->encoder = xylon_drm_encoder_create(dev); if (IS_ERR(xdev->encoder)) { DRM_ERROR("failed create xylon encoder\n"); ret = PTR_ERR(xdev->encoder); goto err_out; } xdev->connector = xylon_drm_connector_create(dev, xdev->encoder); if (IS_ERR(xdev->connector)) { DRM_ERROR("failed create xylon connector\n"); ret = PTR_ERR(xdev->connector); goto err_out; } ret = drm_vblank_init(dev, 1); if (ret) { DRM_ERROR("failed initialize vblank\n"); goto err_out; } dev->vblank_disable_allowed = 1; ret = xylon_drm_irq_install(dev); if (ret < 0) { DRM_ERROR("failed install irq\n"); goto err_irq; } ret = xylon_drm_crtc_get_param(xdev->crtc, &bpp, XYLON_DRM_CRTC_BUFF_BPP); if (ret) { DRM_ERROR("failed get bpp\n"); goto err_fbdev; } xdev->fbdev = xylon_drm_fbdev_init(dev, bpp, 1, 1); if (IS_ERR(xdev->fbdev)) { DRM_ERROR("failed initialize fbdev\n"); ret = PTR_ERR(xdev->fbdev); goto err_fbdev; } drm_helper_disable_unused_functions(dev); platform_set_drvdata(pdev, xdev); return 0; err_fbdev: xylon_drm_irq_uninstall(dev); err_irq: drm_vblank_cleanup(dev); err_out: drm_mode_config_cleanup(dev); if (ret == -EPROBE_DEFER) DRM_INFO("driver load deferred, will be called again\n"); return ret; }
static int imx_drm_bind(struct device *dev) { struct drm_device *drm; int ret; drm = drm_dev_alloc(&imx_drm_driver, dev); if (IS_ERR(drm)) return PTR_ERR(drm); /* * enable drm irq mode. * - with irq_enabled = true, we can use the vblank feature. * * P.S. note that we wouldn't use drm irq handler but * just specific driver own one instead because * drm framework supports only one irq handler and * drivers can well take care of their interrupts */ drm->irq_enabled = true; /* * set max width and height as default value(4096x4096). * this value would be used to check framebuffer size limitation * at drm_mode_addfb(). */ drm->mode_config.min_width = 1; drm->mode_config.min_height = 1; drm->mode_config.max_width = 4096; drm->mode_config.max_height = 4096; drm->mode_config.funcs = &imx_drm_mode_config_funcs; drm->mode_config.helper_private = &imx_drm_mode_config_helpers; drm->mode_config.allow_fb_modifiers = true; drm_mode_config_init(drm); ret = drm_vblank_init(drm, MAX_CRTC); if (ret) goto err_kms; dev_set_drvdata(dev, drm); /* Now try and bind all our sub-components */ ret = component_bind_all(dev, drm); if (ret) goto err_kms; drm_mode_config_reset(drm); /* * All components are now initialised, so setup the fb helper. * The fb helper takes copies of key hardware information, so the * crtcs/connectors/encoders must not change after this point. */ if (legacyfb_depth != 16 && legacyfb_depth != 32) { dev_warn(dev, "Invalid legacyfb_depth. Defaulting to 16bpp\n"); legacyfb_depth = 16; } drm_kms_helper_poll_init(drm); ret = drm_dev_register(drm, 0); if (ret) goto err_poll_fini; drm_fbdev_generic_setup(drm, legacyfb_depth); return 0; err_poll_fini: drm_kms_helper_poll_fini(drm); component_unbind_all(drm->dev, drm); err_kms: drm_mode_config_cleanup(drm); drm_dev_put(drm); return ret; }