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 kirin_fbdev_output_poll_changed(struct drm_device *dev) { struct kirin_drm_private *priv = dev->dev_private; if (priv->fbdev) { drm_fbdev_cma_hotplug_event(priv->fbdev); } else { priv->fbdev = drm_fbdev_cma_init(dev, 32, dev->mode_config.num_connector); if (IS_ERR(priv->fbdev)) priv->fbdev = NULL; } }
struct drm_fbdev_cma *sun4i_framebuffer_init(struct drm_device *drm) { drm_mode_config_reset(drm); drm->mode_config.max_width = 8192; drm->mode_config.max_height = 8192; drm->mode_config.funcs = &sun4i_de_mode_config_funcs; return drm_fbdev_cma_init(drm, 32, drm->mode_config.num_crtc, drm->mode_config.num_connector); }
static void atmel_hlcdc_fb_output_poll_changed(struct drm_device *dev) { struct atmel_hlcdc_dc *dc = dev->dev_private; if (dc->fbdev) { drm_fbdev_cma_hotplug_event(dc->fbdev); } else { dc->fbdev = drm_fbdev_cma_init(dev, 24, dev->mode_config.num_crtc, dev->mode_config.num_connector); if (IS_ERR(dc->fbdev)) dc->fbdev = NULL; } }
static int fsl_dcu_load(struct drm_device *dev, unsigned long flags) { struct fsl_dcu_drm_device *fsl_dev = dev->dev_private; int ret; ret = fsl_dcu_drm_modeset_init(fsl_dev); if (ret < 0) { dev_err(dev->dev, "failed to initialize mode setting\n"); return ret; } ret = drm_vblank_init(dev, dev->mode_config.num_crtc); if (ret < 0) { dev_err(dev->dev, "failed to initialize vblank\n"); goto done; } ret = fsl_dcu_drm_irq_init(dev); if (ret < 0) goto done; dev->irq_enabled = true; if (legacyfb_depth != 16 && legacyfb_depth != 24 && legacyfb_depth != 32) { dev_warn(dev->dev, "Invalid legacyfb_depth. Defaulting to 24bpp\n"); legacyfb_depth = 24; } fsl_dev->fbdev = drm_fbdev_cma_init(dev, legacyfb_depth, 1); if (IS_ERR(fsl_dev->fbdev)) { ret = PTR_ERR(fsl_dev->fbdev); fsl_dev->fbdev = NULL; goto done; } return 0; done: drm_kms_helper_poll_fini(dev); if (fsl_dev->fbdev) drm_fbdev_cma_fini(fsl_dev->fbdev); drm_mode_config_cleanup(dev); drm_vblank_cleanup(dev); drm_irq_uninstall(dev); dev->dev_private = NULL; return ret; }
static int __init imx_fb_helper_init(void) { struct drm_device *drm = imx_drm_device_get(); if (!drm) return -EINVAL; if (legacyfb_depth != 16 && legacyfb_depth != 32) { pr_warn("i.MX legacyfb: invalid legacyfb_depth setting. defaulting to 16bpp\n"); legacyfb_depth = 16; } fbdev_cma = drm_fbdev_cma_init(drm, legacyfb_depth, drm->mode_config.num_crtc, MAX_CONNECTOR); if (IS_ERR(fbdev_cma)) { imx_drm_device_put(); return PTR_ERR(fbdev_cma); } imx_drm_fb_helper_set(fbdev_cma); return 0; }
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 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; }
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 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; }