static void nv50_dac_destroy(struct drm_encoder *encoder) { struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); if (!encoder) return; NV_DEBUG_KMS(encoder->dev, "\n"); drm_encoder_cleanup(encoder); kfree(nv_encoder); }
/* destroy encoder */ void xilinx_drm_encoder_destroy(struct drm_encoder *base_encoder) { struct xilinx_drm_encoder *encoder; struct drm_encoder_slave *encoder_slave; encoder_slave = to_encoder_slave(base_encoder); encoder = to_xilinx_encoder(encoder_slave); /* make sure encoder is off */ xilinx_drm_encoder_dpms(base_encoder, DRM_MODE_DPMS_OFF); drm_encoder_cleanup(base_encoder); put_device(encoder->dev); }
int nv04_tv_create(struct drm_connector *connector, struct dcb_output *entry) { struct nouveau_encoder *nv_encoder; struct drm_encoder *encoder; struct drm_device *dev = connector->dev; struct nouveau_drm *drm = nouveau_drm(dev); struct nvkm_i2c *i2c = nvxx_i2c(&drm->device); struct nvkm_i2c_port *port = i2c->find(i2c, entry->i2c_index); int type, ret; /* Ensure that we can talk to this encoder */ type = nv04_tv_identify(dev, entry->i2c_index); if (type < 0) return type; /* Allocate the necessary memory */ nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); if (!nv_encoder) return -ENOMEM; /* Initialize the common members */ encoder = to_drm_encoder(nv_encoder); drm_encoder_init(dev, encoder, &nv04_tv_funcs, DRM_MODE_ENCODER_TVDAC); drm_encoder_helper_add(encoder, &nv04_tv_helper_funcs); encoder->possible_crtcs = entry->heads; encoder->possible_clones = 0; nv_encoder->dcb = entry; nv_encoder->or = ffs(entry->or) - 1; /* Run the slave-specific initialization */ ret = drm_i2c_encoder_init(dev, to_encoder_slave(encoder), &port->adapter, &nv04_tv_encoder_info[type].dev); if (ret < 0) goto fail_cleanup; /* Attach it to the specified connector. */ get_slave_funcs(encoder)->create_resources(encoder, connector); drm_mode_connector_attach_encoder(connector, encoder); return 0; fail_cleanup: drm_encoder_cleanup(encoder); kfree(nv_encoder); return ret; }
int rcar_du_hdmienc_init(struct rcar_du_device *rcdu, struct rcar_du_encoder *renc, struct device_node *np) { struct drm_encoder *encoder = rcar_encoder_to_drm_encoder(renc); struct drm_bridge *bridge; struct rcar_du_hdmienc *hdmienc; int ret; hdmienc = devm_kzalloc(rcdu->dev, sizeof(*hdmienc), GFP_KERNEL); if (hdmienc == NULL) return -ENOMEM; /* Locate the DRM bridge from the HDMI encoder DT node. */ bridge = of_drm_find_bridge(np); if (!bridge) return -EPROBE_DEFER; ret = drm_encoder_init(rcdu->ddev, encoder, &encoder_funcs, DRM_MODE_ENCODER_TMDS, NULL); if (ret < 0) return ret; drm_encoder_helper_add(encoder, &encoder_helper_funcs); renc->hdmi = hdmienc; hdmienc->renc = renc; /* Link the bridge to the encoder. */ bridge->encoder = encoder; encoder->bridge = bridge; ret = drm_bridge_attach(rcdu->ddev, bridge); if (ret) { drm_encoder_cleanup(encoder); return ret; } return 0; }
int tilcdc_attach_external_device(struct drm_device *ddev) { struct tilcdc_drm_private *priv = ddev->dev_private; struct device_node *remote_node; struct drm_bridge *bridge; int ret; remote_node = tilcdc_get_remote_node(ddev->dev->of_node); if (!remote_node) return 0; bridge = of_drm_find_bridge(remote_node); of_node_put(remote_node); if (!bridge) return -EPROBE_DEFER; priv->external_encoder = devm_kzalloc(ddev->dev, sizeof(*priv->external_encoder), GFP_KERNEL); if (!priv->external_encoder) return -ENOMEM; ret = drm_encoder_init(ddev, priv->external_encoder, &tilcdc_external_encoder_funcs, DRM_MODE_ENCODER_NONE, NULL); if (ret) { dev_err(ddev->dev, "drm_encoder_init() failed %d\n", ret); return ret; } ret = tilcdc_attach_bridge(ddev, bridge); if (ret) drm_encoder_cleanup(priv->external_encoder); return ret; }
int vkms_output_init(struct vkms_device *vkmsdev) { struct vkms_output *output = &vkmsdev->output; struct drm_device *dev = &vkmsdev->drm; struct drm_connector *connector = &output->connector; struct drm_encoder *encoder = &output->encoder; struct drm_crtc *crtc = &output->crtc; struct drm_plane *primary, *cursor = NULL; int ret; primary = vkms_plane_init(vkmsdev, DRM_PLANE_TYPE_PRIMARY); if (IS_ERR(primary)) return PTR_ERR(primary); if (enable_cursor) { cursor = vkms_plane_init(vkmsdev, DRM_PLANE_TYPE_CURSOR); if (IS_ERR(cursor)) { ret = PTR_ERR(cursor); goto err_cursor; } } ret = vkms_crtc_init(dev, crtc, primary, cursor); if (ret) goto err_crtc; ret = drm_connector_init(dev, connector, &vkms_connector_funcs, DRM_MODE_CONNECTOR_VIRTUAL); if (ret) { DRM_ERROR("Failed to init connector\n"); goto err_connector; } drm_connector_helper_add(connector, &vkms_conn_helper_funcs); ret = drm_connector_register(connector); if (ret) { DRM_ERROR("Failed to register connector\n"); goto err_connector_register; } ret = drm_encoder_init(dev, encoder, &vkms_encoder_funcs, DRM_MODE_ENCODER_VIRTUAL, NULL); if (ret) { DRM_ERROR("Failed to init encoder\n"); goto err_encoder; } encoder->possible_crtcs = 1; ret = drm_connector_attach_encoder(connector, encoder); if (ret) { DRM_ERROR("Failed to attach connector to encoder\n"); goto err_attach; } drm_mode_config_reset(dev); return 0; err_attach: drm_encoder_cleanup(encoder); err_encoder: drm_connector_unregister(connector); err_connector_register: drm_connector_cleanup(connector); err_connector: drm_crtc_cleanup(crtc); err_crtc: if (enable_cursor) drm_plane_cleanup(cursor); err_cursor: drm_plane_cleanup(primary); return ret; }
static int exynos_dp_bind(struct device *dev, struct device *master, void *data) { struct exynos_dp_device *dp = dev_get_drvdata(dev); struct platform_device *pdev = to_platform_device(dev); struct drm_device *drm_dev = data; struct drm_encoder *encoder = &dp->encoder; struct resource *res; unsigned int irq_flags; int pipe, ret = 0; dp->dev = &pdev->dev; dp->dpms_mode = DRM_MODE_DPMS_OFF; dp->video_info = exynos_dp_dt_parse_pdata(&pdev->dev); if (IS_ERR(dp->video_info)) return PTR_ERR(dp->video_info); dp->phy = devm_phy_get(dp->dev, "dp"); if (IS_ERR(dp->phy)) { dev_err(dp->dev, "no DP phy configured\n"); ret = PTR_ERR(dp->phy); if (ret) { /* * phy itself is not enabled, so we can move forward * assigning NULL to phy pointer. */ if (ret == -ENOSYS || ret == -ENODEV) dp->phy = NULL; else return ret; } } if (!dp->panel && !dp->ptn_bridge) { ret = exynos_dp_dt_parse_panel(dp); if (ret) return ret; } dp->clock = devm_clk_get(&pdev->dev, "dp"); if (IS_ERR(dp->clock)) { dev_err(&pdev->dev, "failed to get clock\n"); return PTR_ERR(dp->clock); } clk_prepare_enable(dp->clock); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); dp->reg_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(dp->reg_base)) return PTR_ERR(dp->reg_base); dp->hpd_gpio = of_get_named_gpio(dev->of_node, "samsung,hpd-gpio", 0); if (gpio_is_valid(dp->hpd_gpio)) { /* * Set up the hotplug GPIO from the device tree as an interrupt. * Simply specifying a different interrupt in the device tree * doesn't work since we handle hotplug rather differently when * using a GPIO. We also need the actual GPIO specifier so * that we can get the current state of the GPIO. */ ret = devm_gpio_request_one(&pdev->dev, dp->hpd_gpio, GPIOF_IN, "hpd_gpio"); if (ret) { dev_err(&pdev->dev, "failed to get hpd gpio\n"); return ret; } dp->irq = gpio_to_irq(dp->hpd_gpio); irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; } else { dp->hpd_gpio = -ENODEV; dp->irq = platform_get_irq(pdev, 0); irq_flags = 0; } if (dp->irq == -ENXIO) { dev_err(&pdev->dev, "failed to get irq\n"); return -ENODEV; } INIT_WORK(&dp->hotplug_work, exynos_dp_hotplug); ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler, irq_flags, "exynos-dp", dp); if (ret) { dev_err(&pdev->dev, "failed to request irq\n"); return ret; } disable_irq(dp->irq); dp->drm_dev = drm_dev; pipe = exynos_drm_crtc_get_pipe_from_type(drm_dev, EXYNOS_DISPLAY_TYPE_LCD); if (pipe < 0) return pipe; encoder->possible_crtcs = 1 << pipe; DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs); drm_encoder_init(drm_dev, encoder, &exynos_dp_encoder_funcs, DRM_MODE_ENCODER_TMDS, NULL); drm_encoder_helper_add(encoder, &exynos_dp_encoder_helper_funcs); ret = exynos_dp_create_connector(encoder); if (ret) { DRM_ERROR("failed to create connector ret = %d\n", ret); drm_encoder_cleanup(encoder); return ret; } return 0; }
/* dummy encoder */ static void evdi_enc_destroy(struct drm_encoder *encoder) { drm_encoder_cleanup(encoder); kfree(encoder); }
static void meson_venc_hdmi_encoder_destroy(struct drm_encoder *encoder) { drm_encoder_cleanup(encoder); }
static void panel_encoder_destroy(struct drm_encoder *encoder) { struct panel_encoder *panel_encoder = to_panel_encoder(encoder); drm_encoder_cleanup(encoder); kfree(panel_encoder); }
static void shmob_drm_encoder_destroy(struct drm_encoder *encoder) { drm_encoder_cleanup(encoder); }
static void qxl_enc_destroy(struct drm_encoder *encoder) { drm_encoder_cleanup(encoder); }
static void intel_hdmi_enc_destroy(struct drm_encoder *encoder) { drm_encoder_cleanup(encoder); }
void cdv_hdmi_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev, int reg) { struct gma_encoder *gma_encoder; struct gma_connector *gma_connector; struct drm_connector *connector; struct drm_encoder *encoder; struct mid_intel_hdmi_priv *hdmi_priv; int ddc_bus; gma_encoder = kzalloc(sizeof(struct gma_encoder), GFP_KERNEL); if (!gma_encoder) return; gma_connector = kzalloc(sizeof(struct gma_connector), GFP_KERNEL); if (!gma_connector) goto err_connector; hdmi_priv = kzalloc(sizeof(struct mid_intel_hdmi_priv), GFP_KERNEL); if (!hdmi_priv) goto err_priv; connector = &gma_connector->base; connector->polled = DRM_CONNECTOR_POLL_HPD; gma_connector->save = cdv_hdmi_save; gma_connector->restore = cdv_hdmi_restore; encoder = &gma_encoder->base; drm_connector_init(dev, connector, &cdv_hdmi_connector_funcs, DRM_MODE_CONNECTOR_DVID); drm_encoder_init(dev, encoder, &psb_intel_lvds_enc_funcs, DRM_MODE_ENCODER_TMDS, NULL); gma_connector_attach_encoder(gma_connector, gma_encoder); gma_encoder->type = INTEL_OUTPUT_HDMI; hdmi_priv->hdmi_reg = reg; hdmi_priv->has_hdmi_sink = false; gma_encoder->dev_priv = hdmi_priv; drm_encoder_helper_add(encoder, &cdv_hdmi_helper_funcs); drm_connector_helper_add(connector, &cdv_hdmi_connector_helper_funcs); connector->display_info.subpixel_order = SubPixelHorizontalRGB; connector->interlace_allowed = false; connector->doublescan_allowed = false; drm_object_attach_property(&connector->base, dev->mode_config.scaling_mode_property, DRM_MODE_SCALE_FULLSCREEN); switch (reg) { case SDVOB: ddc_bus = GPIOE; gma_encoder->ddi_select = DDI0_SELECT; break; case SDVOC: ddc_bus = GPIOD; gma_encoder->ddi_select = DDI1_SELECT; break; default: DRM_ERROR("unknown reg 0x%x for HDMI\n", reg); goto failed_ddc; break; } gma_encoder->i2c_bus = psb_intel_i2c_create(dev, ddc_bus, (reg == SDVOB) ? "HDMIB" : "HDMIC"); if (!gma_encoder->i2c_bus) { dev_err(dev->dev, "No ddc adapter available!\n"); goto failed_ddc; } hdmi_priv->hdmi_i2c_adapter = &(gma_encoder->i2c_bus->adapter); hdmi_priv->dev = dev; drm_connector_register(connector); return; failed_ddc: drm_encoder_cleanup(encoder); drm_connector_cleanup(connector); err_priv: kfree(gma_connector); err_connector: kfree(gma_encoder); }
bool intel_dsi_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_dsi *intel_dsi; struct intel_encoder *intel_encoder; struct drm_encoder *encoder; struct intel_connector *intel_connector; struct drm_connector *connector; struct drm_display_mode *fixed_mode = NULL; struct drm_display_mode *downclock_mode = NULL; const struct intel_dsi_device *dsi; unsigned int i; DRM_DEBUG_KMS("\n"); intel_dsi = kzalloc(sizeof(*intel_dsi), GFP_KERNEL); if (!intel_dsi) return false; intel_connector = kzalloc(sizeof(*intel_connector), GFP_KERNEL); if (!intel_connector) { kfree(intel_dsi); return false; } intel_encoder = &intel_dsi->base; encoder = &intel_encoder->base; intel_dsi->attached_connector = intel_connector; connector = &intel_connector->base; drm_encoder_init(dev, encoder, &intel_dsi_funcs, DRM_MODE_ENCODER_DSI); /* XXX: very likely not all of these are needed */ intel_encoder->hot_plug = intel_dsi_hot_plug; intel_encoder->compute_config = intel_dsi_compute_config; intel_encoder->pre_pll_enable = intel_dsi_pre_pll_enable; intel_encoder->pre_enable = intel_dsi_pre_enable; intel_encoder->enable = intel_dsi_enable; intel_encoder->mode_set = intel_dsi_mode_set; intel_encoder->disable = intel_dsi_disable; intel_encoder->post_disable = intel_dsi_post_disable; intel_encoder->get_hw_state = intel_dsi_get_hw_state; intel_encoder->get_config = intel_dsi_get_config; intel_encoder->set_drrs_state = intel_dsi_set_drrs_state; intel_connector->get_hw_state = intel_connector_get_hw_state; /* Initialize panel id based on kernel param. * If no kernel param use panel id from VBT * If no param and no VBT initialize with * default ASUS panel ID for now */ if (i915_mipi_panel_id <= 0) { /* check if panel id available from VBT */ if (!dev_priv->vbt.dsi.panel_id) { /* default Panasonic panel */ dev_priv->mipi_panel_id = MIPI_DSI_PANASONIC_VXX09F006A00_PANEL_ID; } else dev_priv->mipi_panel_id = dev_priv->vbt.dsi.panel_id; } else dev_priv->mipi_panel_id = i915_mipi_panel_id; for (i = 0; i < ARRAY_SIZE(intel_dsi_devices); i++) { dsi = &intel_dsi_devices[i]; if (dsi->panel_id == dev_priv->mipi_panel_id) { intel_dsi->dev = *dsi; if (dsi->dev_ops->init(&intel_dsi->dev)) break; } } if (i == ARRAY_SIZE(intel_dsi_devices)) { DRM_DEBUG_KMS("no device found\n"); goto err; } intel_encoder->type = INTEL_OUTPUT_DSI; intel_encoder->crtc_mask = (1 << 0); /* XXX */ intel_encoder->cloneable = false; drm_connector_init(dev, connector, &intel_dsi_connector_funcs, DRM_MODE_CONNECTOR_DSI); drm_encoder_helper_add(encoder, &intel_dsi_helper_funcs); drm_connector_helper_add(connector, &intel_dsi_connector_helper_funcs); connector->display_info.subpixel_order = SubPixelHorizontalRGB; /*XXX*/ connector->interlace_allowed = false; connector->doublescan_allowed = false; intel_dsi_add_properties(intel_dsi, connector); intel_connector_attach_encoder(intel_connector, intel_encoder); drm_sysfs_connector_add(connector); fixed_mode = dsi->dev_ops->get_modes(&intel_dsi->dev); if (!fixed_mode) { DRM_DEBUG_KMS("no fixed mode\n"); goto err; } dev_priv->is_mipi = true; fixed_mode->type |= DRM_MODE_TYPE_PREFERRED; if (INTEL_INFO(dev)->gen > 6) { downclock_mode = intel_dsi_calc_panel_downclock(dev, fixed_mode, connector); if (downclock_mode) intel_dsi_drrs_init(intel_connector, downclock_mode); else DRM_DEBUG_KMS("Downclock_mode is not found\n"); } intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode); intel_panel_setup_backlight(connector); intel_connector->panel.fitting_mode = 0; return true; err: drm_encoder_cleanup(&intel_encoder->base); kfree(intel_dsi); kfree(intel_connector); return false; }
static void tegra_encoder_destroy(struct drm_encoder *encoder) { drm_encoder_cleanup(encoder); drm_encoder_clear(encoder); }
static void dce_virtual_encoder_destroy(struct drm_encoder *encoder) { drm_encoder_cleanup(encoder); kfree(encoder); }
static void vbox_encoder_destroy(struct drm_encoder *encoder) { LogFunc(("vboxvideo: %d: encoder=%p\n", __LINE__, encoder)); drm_encoder_cleanup(encoder); kfree(encoder); }
bool intel_dsi_init(struct drm_device *dev) { struct intel_dsi *intel_dsi; struct intel_encoder *intel_encoder; struct drm_encoder *encoder; struct intel_connector *intel_connector; struct drm_connector *connector; struct drm_display_mode *fixed_mode = NULL; const struct intel_dsi_device *dsi; unsigned int i; DRM_DEBUG_KMS("\n"); intel_dsi = kzalloc(sizeof(*intel_dsi), GFP_KERNEL); if (!intel_dsi) return false; intel_connector = kzalloc(sizeof(*intel_connector), GFP_KERNEL); if (!intel_connector) { kfree(intel_dsi); return false; } intel_encoder = &intel_dsi->base; encoder = &intel_encoder->base; intel_dsi->attached_connector = intel_connector; connector = &intel_connector->base; drm_encoder_init(dev, encoder, &intel_dsi_funcs, DRM_MODE_ENCODER_DSI); /* XXX: very likely not all of these are needed */ intel_encoder->hot_plug = intel_dsi_hot_plug; intel_encoder->compute_config = intel_dsi_compute_config; intel_encoder->pre_pll_enable = intel_dsi_pre_pll_enable; intel_encoder->pre_enable = intel_dsi_pre_enable; intel_encoder->enable = intel_dsi_enable; intel_encoder->mode_set = intel_dsi_mode_set; intel_encoder->disable = intel_dsi_disable; intel_encoder->post_disable = intel_dsi_post_disable; intel_encoder->get_hw_state = intel_dsi_get_hw_state; intel_encoder->get_config = intel_dsi_get_config; intel_connector->get_hw_state = intel_connector_get_hw_state; for (i = 0; i < ARRAY_SIZE(intel_dsi_devices); i++) { dsi = &intel_dsi_devices[i]; intel_dsi->dev = *dsi; if (dsi->dev_ops->init(&intel_dsi->dev)) break; } if (i == ARRAY_SIZE(intel_dsi_devices)) { DRM_DEBUG_KMS("no device found\n"); goto err; } intel_encoder->type = INTEL_OUTPUT_DSI; intel_encoder->crtc_mask = (1 << 0); /* XXX */ intel_encoder->cloneable = false; drm_connector_init(dev, connector, &intel_dsi_connector_funcs, DRM_MODE_CONNECTOR_DSI); drm_connector_helper_add(connector, &intel_dsi_connector_helper_funcs); connector->display_info.subpixel_order = SubPixelHorizontalRGB; /*XXX*/ connector->interlace_allowed = false; connector->doublescan_allowed = false; intel_connector_attach_encoder(intel_connector, intel_encoder); drm_sysfs_connector_add(connector); fixed_mode = dsi->dev_ops->get_modes(&intel_dsi->dev); if (!fixed_mode) { DRM_DEBUG_KMS("no fixed mode\n"); goto err; } fixed_mode->type |= DRM_MODE_TYPE_PREFERRED; intel_panel_init(&intel_connector->panel, fixed_mode); return true; err: drm_encoder_cleanup(&intel_encoder->base); kfree(intel_dsi); kfree(intel_connector); return false; }
bool intel_dsi_init(struct drm_device *dev, int pipe) #endif { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_dsi *intel_dsi; struct intel_encoder *intel_encoder; struct drm_encoder *encoder; struct intel_connector *intel_connector; struct drm_connector *connector; struct drm_display_mode *fixed_mode = NULL; const struct intel_dsi_device *dsi; unsigned int i; unsigned int panel_id; extern int intel_adc_read_panelid(unsigned int*); DRM_DEBUG_KMS("\n"); intel_dsi = kzalloc(sizeof(*intel_dsi), GFP_KERNEL); if (!intel_dsi) return false; intel_connector = kzalloc(sizeof(*intel_connector), GFP_KERNEL); if (!intel_connector) { kfree(intel_dsi); return false; } intel_encoder = &intel_dsi->base; encoder = &intel_encoder->base; intel_dsi->attached_connector = intel_connector; connector = &intel_connector->base; drm_encoder_init(dev, encoder, &intel_dsi_funcs, DRM_MODE_ENCODER_DSI); /* XXX: very likely not all of these are needed */ intel_encoder->hot_plug = intel_dsi_hot_plug; intel_encoder->compute_config = intel_dsi_compute_config; intel_encoder->pre_pll_enable = intel_dsi_pre_pll_enable; intel_encoder->pre_enable = intel_dsi_pre_enable; intel_encoder->enable = intel_dsi_enable; intel_encoder->mode_set = intel_dsi_mode_set; intel_encoder->disable = intel_dsi_disable; intel_encoder->post_disable = intel_dsi_post_disable; intel_encoder->get_hw_state = intel_dsi_get_hw_state; intel_encoder->get_config = intel_dsi_get_config; intel_connector->get_hw_state = intel_connector_get_hw_state; /* Initialize panel id based on kernel param. * If no kernel param use panel id from VBT * If no param and no VBT initialize with * default ASUS panel ID for now */ #ifndef BYT_DUAL_MIPI_DSI intel_adc_read_panelid(&panel_id); i915_mipi_panel_id = panel_id; #else dual_display_status.pipea_status = PIPE_INIT; dual_display_status.pipeb_status = PIPE_OFF; dual_display_status.call_back = NULL; mutex_init(&(dual_display_status.dual_display_mutex)); if(pipe == 1) { i915_mipi_panel_id = MIPI_DSI_TI_DPP3430_PANEL_ID; #if 0 dual_display_status.mipia_ori = PIPE_INIT; dual_display_status.mipib_ori = PIPE_INIT; dual_display_status.pipea_status = PIPE_INIT; dual_display_status.pipeb_status = PIPE_INIT; dual_display_status.call_back = NULL; mutex_init(&(dual_display_status.dual_display_mutex)); #endif } else if (i915_enable_dummy_dsi) { i915_mipi_panel_id = MIPI_DSI_DUMMY_PANEL_ID; } else { intel_adc_read_panelid(&panel_id); i915_mipi_panel_id = panel_id; } #endif printk("[drm] intel debug panel_id is:%d\n",i915_mipi_panel_id); if (i915_mipi_panel_id <= 0) { /* check if panel id available from VBT */ if (!dev_priv->vbt.dsi.panel_id) { /* default Panasonic panel */ dev_priv->mipi_panel_id = MIPI_DSI_PANASONIC_VXX09F006A00_PANEL_ID; } else dev_priv->mipi_panel_id = dev_priv->vbt.dsi.panel_id; } else dev_priv->mipi_panel_id = i915_mipi_panel_id; /*enable for blade2 panel*/ //dev_priv->mipi_panel_id = MIPI_DSI_AUO_B101UAN01E_PANEL_ID; //dev_priv->mipi_panel_id = MIPI_DSI_CMI_NT51021_PANEL_ID; //dev_priv->mipi_panel_id = MIPI_DSI_TI_DPP3430_PANEL_ID; for (i = 0; i < ARRAY_SIZE(intel_dsi_devices); i++) { dsi = &intel_dsi_devices[i]; if (dsi->panel_id == dev_priv->mipi_panel_id) { intel_dsi->dev = *dsi; intel_dsi_dev = &intel_dsi->dev; if (dsi->dev_ops->init(&intel_dsi->dev)) break; } } if (i == ARRAY_SIZE(intel_dsi_devices)) { DRM_DEBUG_KMS("no device found\n"); goto err; } //specify pipe to the dsi #ifndef BYT_DUAL_MIPI_DSI intel_encoder->type = INTEL_OUTPUT_DSI; intel_encoder->crtc_mask = (1 << 0); #else if(pipe ==0){ intel_encoder->type = INTEL_OUTPUT_DSI; intel_encoder->crtc_mask = (1 << 0); } else{ intel_encoder->type = INTEL_OUTPUT_DSI; intel_encoder->crtc_mask = (1 << 1); } #endif intel_encoder->cloneable = false; drm_connector_init(dev, connector, &intel_dsi_connector_funcs, DRM_MODE_CONNECTOR_DSI); drm_encoder_helper_add(encoder, &intel_dsi_helper_funcs); drm_connector_helper_add(connector, &intel_dsi_connector_helper_funcs); connector->display_info.subpixel_order = SubPixelHorizontalRGB; /*XXX*/ connector->interlace_allowed = false; connector->doublescan_allowed = false; intel_dsi_add_properties(intel_dsi, connector); intel_connector_attach_encoder(intel_connector, intel_encoder); drm_sysfs_connector_add(connector); fixed_mode = dsi->dev_ops->get_modes(&intel_dsi->dev); if (!fixed_mode) { DRM_DEBUG_KMS("no fixed mode\n"); goto err; } //in dual display , mipi 's backlight is useless. it use a bulb to control #ifndef BYT_DUAL_MIPI_DSI dev_priv->is_mipi = true; #else dev_priv->is_mipi = false; #endif fixed_mode->type |= DRM_MODE_TYPE_PREFERRED; intel_panel_init(&intel_connector->panel, fixed_mode, NULL); intel_panel_setup_backlight(connector); intel_connector->panel.fitting_mode = 0; /* Panel native resolution and desired mode can be different in these two cases: 1. Generic driver specifies scaling reqd flag. 2. Static driver for Panasonic panel with BYT_CR Fixme: Remove static driver's panel ID check as we are planning to enable generic driver by default */ if ((dev_priv->scaling_reqd) || (BYT_CR_CONFIG && (i915_mipi_panel_id == MIPI_DSI_PANASONIC_VXX09F006A00_PANEL_ID))) { intel_connector->panel.fitting_mode = AUTOSCALE; DRM_DEBUG_DRIVER("Enabling panel fitter as scaling required flag set\n"); } return true; err: drm_encoder_cleanup(&intel_encoder->base); kfree(intel_dsi); kfree(intel_connector); return false; }
static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, void *data) { struct platform_device *pdev = to_platform_device(dev); struct dw_hdmi_plat_data *plat_data; const struct of_device_id *match; struct drm_device *drm = data; struct drm_encoder *encoder; struct rockchip_hdmi *hdmi; int ret; if (!pdev->dev.of_node) return -ENODEV; hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL); if (!hdmi) return -ENOMEM; match = of_match_node(dw_hdmi_rockchip_dt_ids, pdev->dev.of_node); plat_data = devm_kmemdup(&pdev->dev, match->data, sizeof(*plat_data), GFP_KERNEL); if (!plat_data) return -ENOMEM; hdmi->dev = &pdev->dev; hdmi->chip_data = plat_data->phy_data; plat_data->phy_data = hdmi; encoder = &hdmi->encoder; encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); /* * If we failed to find the CRTC(s) which this encoder is * supposed to be connected to, it's because the CRTC has * not been registered yet. Defer probing, and hope that * the required CRTC is added later. */ if (encoder->possible_crtcs == 0) return -EPROBE_DEFER; ret = rockchip_hdmi_parse_dt(hdmi); if (ret) { DRM_DEV_ERROR(hdmi->dev, "Unable to parse OF data\n"); return ret; } ret = clk_prepare_enable(hdmi->vpll_clk); if (ret) { DRM_DEV_ERROR(hdmi->dev, "Failed to enable HDMI vpll: %d\n", ret); return ret; } hdmi->phy = devm_phy_optional_get(dev, "hdmi"); if (IS_ERR(hdmi->phy)) { ret = PTR_ERR(hdmi->phy); if (ret != -EPROBE_DEFER) DRM_DEV_ERROR(hdmi->dev, "failed to get phy\n"); return ret; } drm_encoder_helper_add(encoder, &dw_hdmi_rockchip_encoder_helper_funcs); drm_encoder_init(drm, encoder, &dw_hdmi_rockchip_encoder_funcs, DRM_MODE_ENCODER_TMDS, NULL); platform_set_drvdata(pdev, hdmi); hdmi->hdmi = dw_hdmi_bind(pdev, encoder, plat_data); /* * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(), * which would have called the encoder cleanup. Do it manually. */ if (IS_ERR(hdmi->hdmi)) { ret = PTR_ERR(hdmi->hdmi); drm_encoder_cleanup(encoder); clk_disable_unprepare(hdmi->vpll_clk); } return ret; }
void rockchip_rgb_fini(struct rockchip_rgb *rgb) { drm_panel_bridge_remove(rgb->bridge); drm_encoder_cleanup(&rgb->encoder); }
static void cirrus_encoder_destroy(struct drm_encoder *encoder) { struct cirrus_encoder *cirrus_encoder = to_cirrus_encoder(encoder); drm_encoder_cleanup(encoder); kfree(cirrus_encoder); }
struct rockchip_rgb *rockchip_rgb_init(struct device *dev, struct drm_crtc *crtc, struct drm_device *drm_dev) { struct rockchip_rgb *rgb; struct drm_encoder *encoder; struct device_node *port, *endpoint; u32 endpoint_id; int ret = 0, child_count = 0; struct drm_panel *panel; struct drm_bridge *bridge; rgb = devm_kzalloc(dev, sizeof(*rgb), GFP_KERNEL); if (!rgb) return ERR_PTR(-ENOMEM); rgb->dev = dev; rgb->drm_dev = drm_dev; port = of_graph_get_port_by_id(dev->of_node, 0); if (!port) return ERR_PTR(-EINVAL); for_each_child_of_node(port, endpoint) { if (of_property_read_u32(endpoint, "reg", &endpoint_id)) endpoint_id = 0; if (rockchip_drm_endpoint_is_subdriver(endpoint) > 0) continue; child_count++; ret = drm_of_find_panel_or_bridge(dev->of_node, 0, endpoint_id, &panel, &bridge); if (!ret) { of_node_put(endpoint); break; } } of_node_put(port); /* if the rgb output is not connected to anything, just return */ if (!child_count) return NULL; if (ret < 0) { if (ret != -EPROBE_DEFER) DRM_DEV_ERROR(dev, "failed to find panel or bridge %d\n", ret); return ERR_PTR(ret); } encoder = &rgb->encoder; encoder->possible_crtcs = drm_crtc_mask(crtc); ret = drm_encoder_init(drm_dev, encoder, &rockchip_rgb_encoder_funcs, DRM_MODE_ENCODER_NONE, NULL); if (ret < 0) { DRM_DEV_ERROR(drm_dev->dev, "failed to initialize encoder: %d\n", ret); return ERR_PTR(ret); } drm_encoder_helper_add(encoder, &rockchip_rgb_encoder_helper_funcs); if (panel) { bridge = drm_panel_bridge_add(panel, DRM_MODE_CONNECTOR_LVDS); if (IS_ERR(bridge)) return ERR_CAST(bridge); } rgb->bridge = bridge; ret = drm_bridge_attach(encoder, rgb->bridge, NULL); if (ret) { DRM_DEV_ERROR(drm_dev->dev, "failed to attach bridge: %d\n", ret); goto err_free_encoder; } return rgb; err_free_encoder: drm_encoder_cleanup(encoder); return ERR_PTR(ret); }
/* dummy encoder */ void udl_enc_destroy(struct drm_encoder *encoder) { drm_encoder_cleanup(encoder); kfree(encoder); }
int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev, struct analogix_dp_plat_data *plat_data) { struct platform_device *pdev = to_platform_device(dev); struct analogix_dp_device *dp; struct resource *res; unsigned int irq_flags; int ret; if (!plat_data) { dev_err(dev, "Invalided input plat_data\n"); return -EINVAL; } dp = devm_kzalloc(dev, sizeof(struct analogix_dp_device), GFP_KERNEL); if (!dp) return -ENOMEM; dev_set_drvdata(dev, dp); dp->dev = &pdev->dev; dp->dpms_mode = DRM_MODE_DPMS_OFF; mutex_init(&dp->panel_lock); dp->panel_is_modeset = false; /* * platform dp driver need containor_of the plat_data to get * the driver private data, so we need to store the point of * plat_data, not the context of plat_data. */ dp->plat_data = plat_data; ret = analogix_dp_dt_parse_pdata(dp); if (ret) return ret; dp->phy = devm_phy_get(dp->dev, "dp"); if (IS_ERR(dp->phy)) { dev_err(dp->dev, "no DP phy configured\n"); ret = PTR_ERR(dp->phy); if (ret) { /* * phy itself is not enabled, so we can move forward * assigning NULL to phy pointer. */ if (ret == -ENOSYS || ret == -ENODEV) dp->phy = NULL; else return ret; } } dp->clock = devm_clk_get(&pdev->dev, "dp"); if (IS_ERR(dp->clock)) { dev_err(&pdev->dev, "failed to get clock\n"); return PTR_ERR(dp->clock); } clk_prepare_enable(dp->clock); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); dp->reg_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(dp->reg_base)) return PTR_ERR(dp->reg_base); dp->force_hpd = of_property_read_bool(dev->of_node, "force-hpd"); dp->hpd_gpio = of_get_named_gpio(dev->of_node, "hpd-gpios", 0); if (!gpio_is_valid(dp->hpd_gpio)) dp->hpd_gpio = of_get_named_gpio(dev->of_node, "samsung,hpd-gpio", 0); if (gpio_is_valid(dp->hpd_gpio)) { /* * Set up the hotplug GPIO from the device tree as an interrupt. * Simply specifying a different interrupt in the device tree * doesn't work since we handle hotplug rather differently when * using a GPIO. We also need the actual GPIO specifier so * that we can get the current state of the GPIO. */ ret = devm_gpio_request_one(&pdev->dev, dp->hpd_gpio, GPIOF_IN, "hpd_gpio"); if (ret) { dev_err(&pdev->dev, "failed to get hpd gpio\n"); return ret; } dp->irq = gpio_to_irq(dp->hpd_gpio); irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; } else { dp->hpd_gpio = -ENODEV; dp->irq = platform_get_irq(pdev, 0); irq_flags = 0; } if (dp->irq == -ENXIO) { dev_err(&pdev->dev, "failed to get irq\n"); return -ENODEV; } pm_runtime_enable(dev); pm_runtime_get_sync(dev); phy_power_on(dp->phy); analogix_dp_init_dp(dp); ret = devm_request_threaded_irq(&pdev->dev, dp->irq, analogix_dp_hardirq, analogix_dp_irq_thread, irq_flags, "analogix-dp", dp); if (ret) { dev_err(&pdev->dev, "failed to request irq\n"); goto err_disable_pm_runtime; } disable_irq(dp->irq); dp->drm_dev = drm_dev; dp->encoder = dp->plat_data->encoder; dp->aux.name = "DP-AUX"; dp->aux.transfer = analogix_dpaux_transfer; dp->aux.dev = &pdev->dev; ret = drm_dp_aux_register(&dp->aux); if (ret) goto err_disable_pm_runtime; ret = analogix_dp_create_bridge(drm_dev, dp); if (ret) { DRM_ERROR("failed to create bridge (%d)\n", ret); drm_encoder_cleanup(dp->encoder); goto err_disable_pm_runtime; } phy_power_off(dp->phy); pm_runtime_put(dev); return 0; err_disable_pm_runtime: phy_power_off(dp->phy); pm_runtime_put(dev); pm_runtime_disable(dev); return ret; }
static void cdv_intel_crt_enc_destroy(struct drm_encoder *encoder) { drm_encoder_cleanup(encoder); }
static void rockchip_dp_drm_encoder_destroy(struct drm_encoder *encoder) { drm_encoder_cleanup(encoder); }
static int sun4i_hdmi_bind(struct device *dev, struct device *master, void *data) { struct platform_device *pdev = to_platform_device(dev); struct drm_device *drm = data; struct sun4i_drv *drv = drm->dev_private; struct sun4i_hdmi *hdmi; struct resource *res; u32 reg; int ret; hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL); if (!hdmi) return -ENOMEM; dev_set_drvdata(dev, hdmi); hdmi->dev = dev; hdmi->drv = drv; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); hdmi->base = devm_ioremap_resource(dev, res); if (IS_ERR(hdmi->base)) { dev_err(dev, "Couldn't map the HDMI encoder registers\n"); return PTR_ERR(hdmi->base); } hdmi->bus_clk = devm_clk_get(dev, "ahb"); if (IS_ERR(hdmi->bus_clk)) { dev_err(dev, "Couldn't get the HDMI bus clock\n"); return PTR_ERR(hdmi->bus_clk); } clk_prepare_enable(hdmi->bus_clk); hdmi->mod_clk = devm_clk_get(dev, "mod"); if (IS_ERR(hdmi->mod_clk)) { dev_err(dev, "Couldn't get the HDMI mod clock\n"); ret = PTR_ERR(hdmi->mod_clk); goto err_disable_bus_clk; } clk_prepare_enable(hdmi->mod_clk); hdmi->pll0_clk = devm_clk_get(dev, "pll-0"); if (IS_ERR(hdmi->pll0_clk)) { dev_err(dev, "Couldn't get the HDMI PLL 0 clock\n"); ret = PTR_ERR(hdmi->pll0_clk); goto err_disable_mod_clk; } hdmi->pll1_clk = devm_clk_get(dev, "pll-1"); if (IS_ERR(hdmi->pll1_clk)) { dev_err(dev, "Couldn't get the HDMI PLL 1 clock\n"); ret = PTR_ERR(hdmi->pll1_clk); goto err_disable_mod_clk; } ret = sun4i_tmds_create(hdmi); if (ret) { dev_err(dev, "Couldn't create the TMDS clock\n"); goto err_disable_mod_clk; } writel(SUN4I_HDMI_CTRL_ENABLE, hdmi->base + SUN4I_HDMI_CTRL_REG); writel(SUN4I_HDMI_PAD_CTRL0_TXEN | SUN4I_HDMI_PAD_CTRL0_CKEN | SUN4I_HDMI_PAD_CTRL0_PWENG | SUN4I_HDMI_PAD_CTRL0_PWEND | SUN4I_HDMI_PAD_CTRL0_PWENC | SUN4I_HDMI_PAD_CTRL0_LDODEN | SUN4I_HDMI_PAD_CTRL0_LDOCEN | SUN4I_HDMI_PAD_CTRL0_BIASEN, hdmi->base + SUN4I_HDMI_PAD_CTRL0_REG); /* * We can't just initialize the register there, we need to * protect the clock bits that have already been read out and * cached by the clock framework. */ reg = readl(hdmi->base + SUN4I_HDMI_PAD_CTRL1_REG); reg &= SUN4I_HDMI_PAD_CTRL1_HALVE_CLK; reg |= SUN4I_HDMI_PAD_CTRL1_REG_AMP(6) | SUN4I_HDMI_PAD_CTRL1_REG_EMP(2) | SUN4I_HDMI_PAD_CTRL1_REG_DENCK | SUN4I_HDMI_PAD_CTRL1_REG_DEN | SUN4I_HDMI_PAD_CTRL1_EMPCK_OPT | SUN4I_HDMI_PAD_CTRL1_EMP_OPT | SUN4I_HDMI_PAD_CTRL1_AMPCK_OPT | SUN4I_HDMI_PAD_CTRL1_AMP_OPT; writel(reg, hdmi->base + SUN4I_HDMI_PAD_CTRL1_REG); reg = readl(hdmi->base + SUN4I_HDMI_PLL_CTRL_REG); reg &= SUN4I_HDMI_PLL_CTRL_DIV_MASK; reg |= SUN4I_HDMI_PLL_CTRL_VCO_S(8) | SUN4I_HDMI_PLL_CTRL_CS(7) | SUN4I_HDMI_PLL_CTRL_CP_S(15) | SUN4I_HDMI_PLL_CTRL_S(7) | SUN4I_HDMI_PLL_CTRL_VCO_GAIN(4) | SUN4I_HDMI_PLL_CTRL_SDIV2 | SUN4I_HDMI_PLL_CTRL_LDO2_EN | SUN4I_HDMI_PLL_CTRL_LDO1_EN | SUN4I_HDMI_PLL_CTRL_HV_IS_33 | SUN4I_HDMI_PLL_CTRL_BWS | SUN4I_HDMI_PLL_CTRL_PLL_EN; writel(reg, hdmi->base + SUN4I_HDMI_PLL_CTRL_REG); ret = sun4i_hdmi_i2c_create(dev, hdmi); if (ret) { dev_err(dev, "Couldn't create the HDMI I2C adapter\n"); goto err_disable_mod_clk; } drm_encoder_helper_add(&hdmi->encoder, &sun4i_hdmi_helper_funcs); ret = drm_encoder_init(drm, &hdmi->encoder, &sun4i_hdmi_funcs, DRM_MODE_ENCODER_TMDS, NULL); if (ret) { dev_err(dev, "Couldn't initialise the HDMI encoder\n"); goto err_del_i2c_adapter; } hdmi->encoder.possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); if (!hdmi->encoder.possible_crtcs) { ret = -EPROBE_DEFER; goto err_del_i2c_adapter; } #ifdef CONFIG_DRM_SUN4I_HDMI_CEC hdmi->cec_adap = cec_pin_allocate_adapter(&sun4i_hdmi_cec_pin_ops, hdmi, "sun4i", CEC_CAP_TRANSMIT | CEC_CAP_LOG_ADDRS | CEC_CAP_PASSTHROUGH | CEC_CAP_RC); ret = PTR_ERR_OR_ZERO(hdmi->cec_adap); if (ret < 0) goto err_cleanup_connector; writel(readl(hdmi->base + SUN4I_HDMI_CEC) & ~SUN4I_HDMI_CEC_TX, hdmi->base + SUN4I_HDMI_CEC); #endif drm_connector_helper_add(&hdmi->connector, &sun4i_hdmi_connector_helper_funcs); ret = drm_connector_init(drm, &hdmi->connector, &sun4i_hdmi_connector_funcs, DRM_MODE_CONNECTOR_HDMIA); if (ret) { dev_err(dev, "Couldn't initialise the HDMI connector\n"); goto err_cleanup_connector; } /* There is no HPD interrupt, so we need to poll the controller */ hdmi->connector.polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; ret = cec_register_adapter(hdmi->cec_adap, dev); if (ret < 0) goto err_cleanup_connector; drm_mode_connector_attach_encoder(&hdmi->connector, &hdmi->encoder); return 0; err_cleanup_connector: cec_delete_adapter(hdmi->cec_adap); drm_encoder_cleanup(&hdmi->encoder); err_del_i2c_adapter: i2c_del_adapter(hdmi->i2c); err_disable_mod_clk: clk_disable_unprepare(hdmi->mod_clk); err_disable_bus_clk: clk_disable_unprepare(hdmi->bus_clk); return ret; }
void cdv_intel_crt_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev) { struct gma_connector *gma_connector; struct gma_encoder *gma_encoder; struct drm_connector *connector; struct drm_encoder *encoder; u32 i2c_reg; gma_encoder = kzalloc(sizeof(struct gma_encoder), GFP_KERNEL); if (!gma_encoder) return; gma_connector = kzalloc(sizeof(struct gma_connector), GFP_KERNEL); if (!gma_connector) goto failed_connector; connector = &gma_connector->base; connector->polled = DRM_CONNECTOR_POLL_HPD; drm_connector_init(dev, connector, &cdv_intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); encoder = &gma_encoder->base; drm_encoder_init(dev, encoder, &cdv_intel_crt_enc_funcs, DRM_MODE_ENCODER_DAC, NULL); gma_connector_attach_encoder(gma_connector, gma_encoder); /* Set up the DDC bus. */ i2c_reg = GPIOA; /* Remove the following code for CDV */ /* if (dev_priv->crt_ddc_bus != 0) i2c_reg = dev_priv->crt_ddc_bus; }*/ gma_encoder->ddc_bus = psb_intel_i2c_create(dev, i2c_reg, "CRTDDC_A"); if (!gma_encoder->ddc_bus) { dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " "failed.\n"); goto failed_ddc; } gma_encoder->type = INTEL_OUTPUT_ANALOG; /* psb_intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT); psb_intel_output->crtc_mask = (1 << 0) | (1 << 1); */ connector->interlace_allowed = 0; connector->doublescan_allowed = 0; drm_encoder_helper_add(encoder, &cdv_intel_crt_helper_funcs); drm_connector_helper_add(connector, &cdv_intel_crt_connector_helper_funcs); drm_connector_register(connector); return; failed_ddc: drm_encoder_cleanup(&gma_encoder->base); drm_connector_cleanup(&gma_connector->base); kfree(gma_connector); failed_connector: kfree(gma_encoder); return; }