int mgag200_driver_load(struct drm_device *dev, unsigned long flags) { struct mga_device *mdev; int r; mdev = devm_kzalloc(dev->dev, sizeof(struct mga_device), GFP_KERNEL); if (mdev == NULL) return -ENOMEM; dev->dev_private = (void *)mdev; mdev->dev = dev; r = mgag200_device_init(dev, flags); if (r) { dev_err(&dev->pdev->dev, "Fatal error during GPU init: %d\n", r); goto out; } r = mgag200_mm_init(mdev); if (r) goto out; drm_mode_config_init(dev); dev->mode_config.funcs = (void *)&mga_mode_funcs; dev->mode_config.preferred_depth = 24; dev->mode_config.prefer_shadow = 1; r = mgag200_modeset_init(mdev); if (r) dev_err(&dev->pdev->dev, "Fatal error during modeset init: %d\n", r); out: if (r) mgag200_driver_unload(dev); return r; }
static int tinydrm_init(struct device *parent, struct tinydrm_device *tdev, const struct drm_framebuffer_funcs *fb_funcs, struct drm_driver *driver) { struct drm_device *drm; mutex_init(&tdev->dirty_lock); tdev->fb_funcs = fb_funcs; /* * We don't embed drm_device, because that prevent us from using * devm_kzalloc() to allocate tinydrm_device in the driver since * drm_dev_unref() frees the structure. The devm_ functions provide * for easy error handling. */ drm = drm_dev_alloc(driver, parent); if (IS_ERR(drm)) return PTR_ERR(drm); tdev->drm = drm; drm->dev_private = tdev; drm_mode_config_init(drm); drm->mode_config.funcs = &tinydrm_mode_config_funcs; return 0; }
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; }
int qxl_modeset_init(struct qxl_device *qdev) { int i; int ret; drm_mode_config_init(qdev->ddev); ret = qxl_create_monitors_object(qdev); if (ret) return ret; qdev->ddev->mode_config.funcs = (void *)&qxl_mode_funcs; /* modes will be validated against the framebuffer size */ qdev->ddev->mode_config.min_width = 320; qdev->ddev->mode_config.min_height = 200; qdev->ddev->mode_config.max_width = 8192; qdev->ddev->mode_config.max_height = 8192; qdev->ddev->mode_config.fb_base = qdev->vram_base; for (i = 0 ; i < qxl_num_crtc; ++i) { qdev_crtc_init(qdev->ddev, i); qdev_output_init(qdev->ddev, i); } qdev->mode_info.mode_config_initialized = true; /* primary surface must be created by this point, to allow * issuing command queue commands and having them read by * spice server. */ qxl_fbdev_init(qdev); return 0; }
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; }
int mgag200_driver_load(struct drm_device *dev, unsigned long flags) { struct mga_device *mdev; int r; mdev = devm_kzalloc(dev->dev, sizeof(struct mga_device), GFP_KERNEL); if (mdev == NULL) return -ENOMEM; dev->dev_private = (void *)mdev; mdev->dev = dev; r = mgag200_device_init(dev, flags); if (r) { dev_err(&dev->pdev->dev, "Fatal error during GPU init: %d\n", r); return r; } r = mgag200_mm_init(mdev); if (r) goto err_mm; drm_mode_config_init(dev); dev->mode_config.funcs = (void *)&mga_mode_funcs; if (IS_G200_SE(mdev) && mdev->mc.vram_size < (2048*1024)) dev->mode_config.preferred_depth = 16; else dev->mode_config.preferred_depth = 24; dev->mode_config.prefer_shadow = 1; r = mgag200_modeset_init(mdev); if (r) { dev_err(&dev->pdev->dev, "Fatal error during modeset init: %d\n", r); goto err_modeset; } /* Make small buffers to store a hardware cursor (double buffered icon updates) */ mgag200_bo_create(dev, roundup(48*64, PAGE_SIZE), 0, 0, &mdev->cursor.pixels_1); mgag200_bo_create(dev, roundup(48*64, PAGE_SIZE), 0, 0, &mdev->cursor.pixels_2); if (!mdev->cursor.pixels_2 || !mdev->cursor.pixels_1) { mdev->cursor.pixels_1 = NULL; mdev->cursor.pixels_2 = NULL; dev_warn(&dev->pdev->dev, "Could not allocate space for cursors. Not doing hardware cursors.\n"); } else { mdev->cursor.pixels_current = mdev->cursor.pixels_1; mdev->cursor.pixels_prev = mdev->cursor.pixels_2; } return 0; err_modeset: drm_mode_config_cleanup(dev); mgag200_mm_fini(mdev); err_mm: dev->dev_private = NULL; return r; }
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; }
static void arcpgu_setup_mode_config(struct drm_device *drm) { drm_mode_config_init(drm); drm->mode_config.min_width = 0; drm->mode_config.min_height = 0; drm->mode_config.max_width = 1920; drm->mode_config.max_height = 1080; drm->mode_config.funcs = &arcpgu_drm_modecfg_funcs; }
static void hdlcd_setup_mode_config(struct drm_device *drm) { drm_mode_config_init(drm); drm->mode_config.min_width = 0; drm->mode_config.min_height = 0; drm->mode_config.max_width = HDLCD_MAX_XRES; drm->mode_config.max_height = HDLCD_MAX_YRES; drm->mode_config.funcs = &hdlcd_mode_config_funcs; }
static int hx8357d_probe(struct spi_device *spi) { struct device *dev = &spi->dev; struct drm_device *drm; struct mipi_dbi *mipi; struct gpio_desc *dc; u32 rotation = 0; int ret; mipi = kzalloc(sizeof(*mipi), GFP_KERNEL); if (!mipi) return -ENOMEM; drm = &mipi->drm; ret = devm_drm_dev_init(dev, drm, &hx8357d_driver); if (ret) { kfree(mipi); return ret; } drm_mode_config_init(drm); dc = devm_gpiod_get(dev, "dc", GPIOD_OUT_LOW); if (IS_ERR(dc)) { DRM_DEV_ERROR(dev, "Failed to get gpio 'dc'\n"); return PTR_ERR(dc); } mipi->backlight = devm_of_find_backlight(dev); if (IS_ERR(mipi->backlight)) return PTR_ERR(mipi->backlight); device_property_read_u32(dev, "rotation", &rotation); ret = mipi_dbi_spi_init(spi, mipi, dc); if (ret) return ret; ret = mipi_dbi_init(mipi, &hx8357d_pipe_funcs, &yx350hv15_mode, rotation); if (ret) return ret; drm_mode_config_reset(drm); ret = drm_dev_register(drm, 0); if (ret) return ret; spi_set_drvdata(spi, drm); drm_fbdev_generic_setup(drm, 0); return 0; }
static int vc4_drm_bind(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct drm_device *drm; struct vc4_dev *vc4; int ret = 0; dev->coherent_dma_mask = DMA_BIT_MASK(32); vc4 = devm_kzalloc(dev, sizeof(*vc4), GFP_KERNEL); if (!vc4) return -ENOMEM; drm = drm_dev_alloc(&vc4_drm_driver, dev); if (IS_ERR(drm)) return PTR_ERR(drm); platform_set_drvdata(pdev, drm); vc4->dev = drm; drm->dev_private = vc4; ret = vc4_bo_cache_init(drm); if (ret) goto dev_unref; drm_mode_config_init(drm); vc4_gem_init(drm); ret = component_bind_all(dev, drm); if (ret) goto gem_destroy; vc4_kick_out_firmware_fb(); ret = drm_dev_register(drm, 0); if (ret < 0) goto unbind_all; vc4_kms_load(drm); return 0; unbind_all: component_unbind_all(dev, drm); gem_destroy: vc4_gem_destroy(drm); vc4_bo_cache_destroy(drm); dev_unref: drm_dev_unref(drm); return ret; }
static int atmel_hlcdc_dc_modeset_init(struct drm_device *dev) { struct atmel_hlcdc_dc *dc = dev->dev_private; struct atmel_hlcdc_planes *planes; int ret; int i; drm_mode_config_init(dev); ret = atmel_hlcdc_create_outputs(dev); if (ret) { dev_err(dev->dev, "failed to create HLCDC outputs: %d\n", ret); return ret; } planes = atmel_hlcdc_create_planes(dev); if (IS_ERR(planes)) { dev_err(dev->dev, "failed to create planes\n"); return PTR_ERR(planes); } dc->planes = planes; dc->layers[planes->primary->layer.desc->id] = &planes->primary->layer; if (planes->cursor) dc->layers[planes->cursor->layer.desc->id] = &planes->cursor->layer; for (i = 0; i < planes->noverlays; i++) dc->layers[planes->overlays[i]->layer.desc->id] = &planes->overlays[i]->layer; ret = atmel_hlcdc_crtc_create(dev); if (ret) { dev_err(dev->dev, "failed to create crtc\n"); return ret; } dev->mode_config.min_width = dc->desc->min_width; dev->mode_config.min_height = dc->desc->min_height; dev->mode_config.max_width = dc->desc->max_width; dev->mode_config.max_height = dc->desc->max_height; dev->mode_config.funcs = &mode_config_funcs; 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; }
int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev) { int i; drm_mode_config_init(vgdev->ddev); vgdev->ddev->mode_config.funcs = (void *)&virtio_gpu_mode_funcs; /* modes will be validated against the framebuffer size */ vgdev->ddev->mode_config.min_width = XRES_MIN; vgdev->ddev->mode_config.min_height = YRES_MIN; vgdev->ddev->mode_config.max_width = XRES_MAX; vgdev->ddev->mode_config.max_height = YRES_MAX; for (i = 0 ; i < vgdev->num_scanouts; ++i) vgdev_output_init(vgdev, i); drm_mode_config_reset(vgdev->ddev); return 0; }
static void komeda_kms_mode_config_init(struct komeda_kms_dev *kms, struct komeda_dev *mdev) { struct drm_mode_config *config = &kms->base.mode_config; drm_mode_config_init(&kms->base); komeda_kms_setup_crtcs(kms, mdev); /* Get value from dev */ config->min_width = 0; config->min_height = 0; config->max_width = 4096; config->max_height = 4096; config->allow_fb_modifiers = false; config->funcs = &komeda_mode_config_funcs; config->helper_private = &komeda_mode_config_helpers; }
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; }
void virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev) { int i; drm_mode_config_init(vgdev->ddev); vgdev->ddev->mode_config.quirk_addfb_prefer_host_byte_order = true; vgdev->ddev->mode_config.funcs = &virtio_gpu_mode_funcs; vgdev->ddev->mode_config.helper_private = &virtio_mode_config_helpers; /* modes will be validated against the framebuffer size */ vgdev->ddev->mode_config.min_width = XRES_MIN; vgdev->ddev->mode_config.min_height = YRES_MIN; vgdev->ddev->mode_config.max_width = XRES_MAX; vgdev->ddev->mode_config.max_height = YRES_MAX; for (i = 0 ; i < vgdev->num_scanouts; ++i) vgdev_output_init(vgdev, i); drm_mode_config_reset(vgdev->ddev); }
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; }
int cirrus_modeset_init(struct cirrus_device *cdev) { struct drm_encoder *encoder; struct drm_connector *connector; int ret; drm_mode_config_init(cdev->dev); cdev->mode_info.mode_config_initialized = true; cdev->dev->mode_config.max_width = CIRRUS_MAX_FB_WIDTH; cdev->dev->mode_config.max_height = CIRRUS_MAX_FB_HEIGHT; cdev->dev->mode_config.fb_base = cdev->mc.vram_base; cdev->dev->mode_config.preferred_depth = 24; /* don't prefer a shadow on virt GPU */ cdev->dev->mode_config.prefer_shadow = 0; cirrus_crtc_init(cdev->dev); encoder = cirrus_encoder_init(cdev->dev); if (!encoder) { DRM_ERROR("cirrus_encoder_init failed\n"); return -1; } connector = cirrus_vga_init(cdev->dev); if (!connector) { DRM_ERROR("cirrus_vga_init failed\n"); return -1; } drm_mode_connector_attach_encoder(connector, encoder); ret = cirrus_fbdev_init(cdev); if (ret) { DRM_ERROR("cirrus_fbdev_init failed\n"); return ret; } return 0; }
int bochs_kms_init(struct bochs_device *bochs) { drm_mode_config_init(bochs->dev); bochs->mode_config_initialized = true; bochs->dev->mode_config.max_width = 8192; bochs->dev->mode_config.max_height = 8192; bochs->dev->mode_config.fb_base = bochs->fb_base; bochs->dev->mode_config.preferred_depth = 24; bochs->dev->mode_config.prefer_shadow = 0; bochs->dev->mode_config.funcs = (void *)&bochs_mode_funcs; bochs_crtc_init(bochs->dev); bochs_encoder_init(bochs->dev); bochs_connector_init(bochs->dev); drm_mode_connector_attach_encoder(&bochs->connector, &bochs->encoder); return 0; }
static int malidp_init(struct drm_device *drm) { int ret; struct malidp_drm *malidp = drm->dev_private; struct malidp_hw_device *hwdev = malidp->dev; drm_mode_config_init(drm); drm->mode_config.min_width = hwdev->min_line_size; drm->mode_config.min_height = hwdev->min_line_size; drm->mode_config.max_width = hwdev->max_line_size; drm->mode_config.max_height = hwdev->max_line_size; drm->mode_config.funcs = &malidp_mode_config_funcs; drm->mode_config.helper_private = &malidp_mode_config_helpers; ret = malidp_crtc_init(drm); if (ret) { drm_mode_config_cleanup(drm); return ret; } return 0; }
int ast_driver_load(struct drm_device *dev, unsigned long flags) { struct ast_private *ast; bool need_post; int ret = 0; ast = kzalloc(sizeof(struct ast_private), GFP_KERNEL); if (!ast) return -ENOMEM; dev->dev_private = ast; ast->dev = dev; ast->regs = pci_iomap(dev->pdev, 1, 0); if (!ast->regs) { ret = -EIO; goto out_free; } /* * If we don't have IO space at all, use MMIO now and * assume the chip has MMIO enabled by default (rev 0x20 * and higher). */ if (!(pci_resource_flags(dev->pdev, 2) & IORESOURCE_IO)) { DRM_INFO("platform has no IO space, trying MMIO\n"); ast->ioregs = ast->regs + AST_IO_MM_OFFSET; } /* "map" IO regs if the above hasn't done so already */ if (!ast->ioregs) { ast->ioregs = pci_iomap(dev->pdev, 2, 0); if (!ast->ioregs) { ret = -EIO; goto out_free; } } ast_detect_chip(dev, &need_post); if (ast->chip != AST1180) { ast_get_dram_info(dev); ast->vram_size = ast_get_vram_info(dev); DRM_INFO("dram %d %d %d %08x\n", ast->mclk, ast->dram_type, ast->dram_bus_width, ast->vram_size); } if (need_post) ast_post_gpu(dev); ret = ast_mm_init(ast); if (ret) goto out_free; drm_mode_config_init(dev); dev->mode_config.funcs = (void *)&ast_mode_funcs; dev->mode_config.min_width = 0; dev->mode_config.min_height = 0; dev->mode_config.preferred_depth = 24; dev->mode_config.prefer_shadow = 1; if (ast->chip == AST2100 || ast->chip == AST2200 || ast->chip == AST2300 || ast->chip == AST2400 || ast->chip == AST1180) { dev->mode_config.max_width = 1920; dev->mode_config.max_height = 2048; } else { dev->mode_config.max_width = 1600; dev->mode_config.max_height = 1200; } ret = ast_mode_init(dev); if (ret) goto out_free; ret = ast_fbdev_init(dev); if (ret) goto out_free; return 0; out_free: kfree(ast); dev->dev_private = NULL; 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 omap_modeset_init(struct drm_device *dev) { const struct omap_drm_platform_data *pdata = dev->dev->platform_data; struct omap_kms_platform_data *kms_pdata = NULL; struct omap_drm_private *priv = dev->dev_private; struct omap_dss_device *dssdev = NULL; int i, j; unsigned int connected_connectors = 0; drm_mode_config_init(dev); if (pdata && pdata->kms_pdata) { kms_pdata = pdata->kms_pdata; /* if platform data is provided by the board file, use it to * control which overlays, managers, and devices we own. */ for (i = 0; i < kms_pdata->mgr_cnt; i++) { struct omap_overlay_manager *mgr = omap_dss_get_overlay_manager( kms_pdata->mgr_ids[i]); create_encoder(dev, mgr); } for (i = 0; i < kms_pdata->dev_cnt; i++) { struct omap_dss_device *dssdev = omap_dss_find_device( (void *)kms_pdata->dev_names[i], match_dev_name); if (!dssdev) { dev_warn(dev->dev, "no such dssdev: %s\n", kms_pdata->dev_names[i]); continue; } create_connector(dev, dssdev); } connected_connectors = detect_connectors(dev); j = 0; for (i = 0; i < kms_pdata->ovl_cnt; i++) { struct omap_overlay *ovl = omap_dss_get_overlay(kms_pdata->ovl_ids[i]); create_crtc(dev, ovl, &j, connected_connectors); } for (i = 0; i < kms_pdata->pln_cnt; i++) { struct omap_overlay *ovl = omap_dss_get_overlay(kms_pdata->pln_ids[i]); create_plane(dev, ovl, (1 << priv->num_crtcs) - 1); } } else { /* otherwise just grab up to CONFIG_DRM_OMAP_NUM_CRTCS and try * to make educated guesses about everything else */ int max_overlays = min(omap_dss_get_num_overlays(), num_crtc); for (i = 0; i < omap_dss_get_num_overlay_managers(); i++) { create_encoder(dev, omap_dss_get_overlay_manager(i)); } for_each_dss_dev(dssdev) { create_connector(dev, dssdev); } connected_connectors = detect_connectors(dev); j = 0; for (i = 0; i < max_overlays; i++) { create_crtc(dev, omap_dss_get_overlay(i), &j, connected_connectors); } /* use any remaining overlays as drm planes */ for (; i < omap_dss_get_num_overlays(); i++) { struct omap_overlay *ovl = omap_dss_get_overlay(i); create_plane(dev, ovl, (1 << priv->num_crtcs) - 1); } } /* for now keep the mapping of CRTCs and encoders static.. */ for (i = 0; i < priv->num_encoders; i++) { struct drm_encoder *encoder = priv->encoders[i]; struct omap_overlay_manager *mgr = omap_encoder_get_manager(encoder); encoder->possible_crtcs = (1 << priv->num_crtcs) - 1; DBG("%s: possible_crtcs=%08x", mgr->name, encoder->possible_crtcs); } dump_video_chains(); dev->mode_config.min_width = 32; dev->mode_config.min_height = 32; /* note: eventually will need some cpu_is_omapXYZ() type stuff here * to fill in these limits properly on different OMAP generations.. */ dev->mode_config.max_width = 2048; dev->mode_config.max_height = 2048; dev->mode_config.funcs = &omap_mode_config_funcs; return 0; }
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 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 omap_modeset_init(struct drm_device *dev) { struct omap_drm_private *priv = dev->dev_private; struct omap_dss_device *dssdev = NULL; int num_ovls = dss_feat_get_num_ovls(); int num_mgrs = dss_feat_get_num_mgrs(); int num_crtcs; int i, id = 0; drm_mode_config_init(dev); omap_drm_irq_install(dev); /* * We usually don't want to create a CRTC for each manager, at least * not until we have a way to expose private planes to userspace. * Otherwise there would not be enough video pipes left for drm planes. * We use the num_crtc argument to limit the number of crtcs we create. */ num_crtcs = min3(num_crtc, num_mgrs, num_ovls); dssdev = NULL; for_each_dss_dev(dssdev) { struct drm_connector *connector; struct drm_encoder *encoder; enum omap_channel channel; struct omap_overlay_manager *mgr; if (!omapdss_device_is_connected(dssdev)) continue; encoder = omap_encoder_init(dev, dssdev); if (!encoder) { dev_err(dev->dev, "could not create encoder: %s\n", dssdev->name); return -ENOMEM; } connector = omap_connector_init(dev, get_connector_type(dssdev), dssdev, encoder); if (!connector) { dev_err(dev->dev, "could not create connector: %s\n", dssdev->name); return -ENOMEM; } BUG_ON(priv->num_encoders >= ARRAY_SIZE(priv->encoders)); BUG_ON(priv->num_connectors >= ARRAY_SIZE(priv->connectors)); priv->encoders[priv->num_encoders++] = encoder; priv->connectors[priv->num_connectors++] = connector; drm_mode_connector_attach_encoder(connector, encoder); /* * if we have reached the limit of the crtcs we are allowed to * create, let's not try to look for a crtc for this * panel/encoder and onwards, we will, of course, populate the * the possible_crtcs field for all the encoders with the final * set of crtcs we create */ if (id == num_crtcs) continue; /* * get the recommended DISPC channel for this encoder. For now, * we only try to get create a crtc out of the recommended, the * other possible channels to which the encoder can connect are * not considered. */ mgr = omapdss_find_mgr_from_display(dssdev); channel = mgr->id; /* * if this channel hasn't already been taken by a previously * allocated crtc, we create a new crtc for it */ if (!channel_used(dev, channel)) { struct drm_plane *plane; struct drm_crtc *crtc; plane = omap_plane_init(dev, id, true); crtc = omap_crtc_init(dev, plane, channel, id); BUG_ON(priv->num_crtcs >= ARRAY_SIZE(priv->crtcs)); priv->crtcs[id] = crtc; priv->num_crtcs++; priv->planes[id] = plane; priv->num_planes++; id++; } } /* * we have allocated crtcs according to the need of the panels/encoders, * adding more crtcs here if needed */ for (; id < num_crtcs; id++) { /* find a free manager for this crtc */ for (i = 0; i < num_mgrs; i++) { if (!channel_used(dev, i)) { struct drm_plane *plane; struct drm_crtc *crtc; plane = omap_plane_init(dev, id, true); crtc = omap_crtc_init(dev, plane, i, id); BUG_ON(priv->num_crtcs >= ARRAY_SIZE(priv->crtcs)); priv->crtcs[id] = crtc; priv->num_crtcs++; priv->planes[id] = plane; priv->num_planes++; break; } else { continue; } } if (i == num_mgrs) { /* this shouldn't really happen */ dev_err(dev->dev, "no managers left for crtc\n"); return -ENOMEM; } } /* * Create normal planes for the remaining overlays: */ for (; id < num_ovls; id++) { struct drm_plane *plane = omap_plane_init(dev, id, false); BUG_ON(priv->num_planes >= ARRAY_SIZE(priv->planes)); priv->planes[priv->num_planes++] = plane; } for (i = 0; i < priv->num_encoders; i++) { struct drm_encoder *encoder = priv->encoders[i]; struct omap_dss_device *dssdev = omap_encoder_get_dssdev(encoder); struct omap_dss_device *output; output = omapdss_find_output_from_display(dssdev); /* figure out which crtc's we can connect the encoder to: */ encoder->possible_crtcs = 0; for (id = 0; id < priv->num_crtcs; id++) { struct drm_crtc *crtc = priv->crtcs[id]; enum omap_channel crtc_channel; crtc_channel = omap_crtc_channel(crtc); if (output->dispc_channel == crtc_channel) { encoder->possible_crtcs |= (1 << id); break; } } omap_dss_put_device(output); } DBG("registered %d planes, %d crtcs, %d encoders and %d connectors\n", priv->num_planes, priv->num_crtcs, priv->num_encoders, priv->num_connectors); dev->mode_config.min_width = 32; dev->mode_config.min_height = 32; /* note: eventually will need some cpu_is_omapXYZ() type stuff here * to fill in these limits properly on different OMAP generations.. */ dev->mode_config.max_width = 2048; dev->mode_config.max_height = 2048; dev->mode_config.funcs = &omap_mode_config_funcs; return 0; }
static int omap_modeset_init(struct drm_device *dev) { struct omap_drm_private *priv = dev->dev_private; struct omap_dss_device *dssdev = NULL; int num_ovls = priv->dispc_ops->get_num_ovls(); int num_mgrs = priv->dispc_ops->get_num_mgrs(); int num_crtcs, crtc_idx, plane_idx; int ret; u32 plane_crtc_mask; drm_mode_config_init(dev); ret = omap_modeset_init_properties(dev); if (ret < 0) return ret; /* * This function creates exactly one connector, encoder, crtc, * and primary plane per each connected dss-device. Each * connector->encoder->crtc chain is expected to be separate * and each crtc is connect to a single dss-channel. If the * configuration does not match the expectations or exceeds * the available resources, the configuration is rejected. */ num_crtcs = 0; for_each_dss_dev(dssdev) if (omapdss_device_is_connected(dssdev)) num_crtcs++; if (num_crtcs > num_mgrs || num_crtcs > num_ovls || num_crtcs > ARRAY_SIZE(priv->crtcs) || num_crtcs > ARRAY_SIZE(priv->planes) || num_crtcs > ARRAY_SIZE(priv->encoders) || num_crtcs > ARRAY_SIZE(priv->connectors)) { dev_err(dev->dev, "%s(): Too many connected displays\n", __func__); return -EINVAL; } /* All planes can be put to any CRTC */ plane_crtc_mask = (1 << num_crtcs) - 1; dssdev = NULL; crtc_idx = 0; plane_idx = 0; for_each_dss_dev(dssdev) { struct drm_connector *connector; struct drm_encoder *encoder; struct drm_plane *plane; struct drm_crtc *crtc; if (!omapdss_device_is_connected(dssdev)) continue; encoder = omap_encoder_init(dev, dssdev); if (!encoder) return -ENOMEM; connector = omap_connector_init(dev, get_connector_type(dssdev), dssdev, encoder); if (!connector) return -ENOMEM; plane = omap_plane_init(dev, plane_idx, DRM_PLANE_TYPE_PRIMARY, plane_crtc_mask); if (IS_ERR(plane)) return PTR_ERR(plane); crtc = omap_crtc_init(dev, plane, dssdev); if (IS_ERR(crtc)) return PTR_ERR(crtc); drm_mode_connector_attach_encoder(connector, encoder); encoder->possible_crtcs = (1 << crtc_idx); priv->crtcs[priv->num_crtcs++] = crtc; priv->planes[priv->num_planes++] = plane; priv->encoders[priv->num_encoders++] = encoder; priv->connectors[priv->num_connectors++] = connector; plane_idx++; crtc_idx++; } /* * Create normal planes for the remaining overlays: */ for (; plane_idx < num_ovls; plane_idx++) { struct drm_plane *plane; if (WARN_ON(priv->num_planes >= ARRAY_SIZE(priv->planes))) return -EINVAL; plane = omap_plane_init(dev, plane_idx, DRM_PLANE_TYPE_OVERLAY, plane_crtc_mask); if (IS_ERR(plane)) return PTR_ERR(plane); priv->planes[priv->num_planes++] = plane; } DBG("registered %d planes, %d crtcs, %d encoders and %d connectors\n", priv->num_planes, priv->num_crtcs, priv->num_encoders, priv->num_connectors); dev->mode_config.min_width = 8; dev->mode_config.min_height = 2; /* note: eventually will need some cpu_is_omapXYZ() type stuff here * to fill in these limits properly on different OMAP generations.. */ dev->mode_config.max_width = 2048; dev->mode_config.max_height = 2048; dev->mode_config.funcs = &omap_mode_config_funcs; dev->mode_config.helper_private = &omap_mode_config_helper_funcs; drm_mode_config_reset(dev); omap_drm_irq_install(dev); return 0; }
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; }
int ast_driver_load(struct drm_device *dev, unsigned long flags) { struct ast_private *ast; int ret = 0; ast = kzalloc(sizeof(struct ast_private), GFP_KERNEL); if (!ast) return -ENOMEM; dev->dev_private = ast; ast->dev = dev; ast->regs = pci_iomap(dev->pdev, 1, 0); if (!ast->regs) { ret = -EIO; goto out_free; } ast->ioregs = pci_iomap(dev->pdev, 2, 0); if (!ast->ioregs) { ret = -EIO; goto out_free; } ast_detect_chip(dev); if (ast->chip != AST1180) { ast_get_dram_info(dev); ast->vram_size = ast_get_vram_info(dev); DRM_INFO("dram %d %d %d %08x\n", ast->mclk, ast->dram_type, ast->dram_bus_width, ast->vram_size); } ret = ast_mm_init(ast); if (ret) goto out_free; drm_mode_config_init(dev); dev->mode_config.funcs = (void *)&ast_mode_funcs; dev->mode_config.min_width = 0; dev->mode_config.min_height = 0; dev->mode_config.preferred_depth = 24; dev->mode_config.prefer_shadow = 1; if (ast->chip == AST2100 || ast->chip == AST2200 || ast->chip == AST2300 || ast->chip == AST1180) { dev->mode_config.max_width = 1920; dev->mode_config.max_height = 2048; } else { dev->mode_config.max_width = 1600; dev->mode_config.max_height = 1200; } ret = ast_mode_init(dev); if (ret) goto out_free; ret = ast_fbdev_init(dev); if (ret) goto out_free; return 0; out_free: kfree(ast); dev->dev_private = NULL; return ret; }