diff options
Diffstat (limited to 'drivers/gpu/drm/gma500/oaktrail_lvds.c')
| -rw-r--r-- | drivers/gpu/drm/gma500/oaktrail_lvds.c | 113 |
1 files changed, 57 insertions, 56 deletions
diff --git a/drivers/gpu/drm/gma500/oaktrail_lvds.c b/drivers/gpu/drm/gma500/oaktrail_lvds.c index 83babb815a5d..0705ba3813e6 100644 --- a/drivers/gpu/drm/gma500/oaktrail_lvds.c +++ b/drivers/gpu/drm/gma500/oaktrail_lvds.c @@ -1,19 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright © 2006-2009 Intel Corporation * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * * Authors: * Eric Anholt <eric@anholt.net> * Dave Airlie <airlied@linux.ie> @@ -21,15 +9,18 @@ */ #include <linux/i2c.h> -#include <drm/drmP.h> -#include <asm/intel-mid.h> +#include <linux/pm_runtime.h> + +#include <drm/drm_edid.h> +#include <drm/drm_modeset_helper_vtables.h> +#include <drm/drm_print.h> +#include <drm/drm_simple_kms_helper.h> #include "intel_bios.h" +#include "power.h" #include "psb_drv.h" #include "psb_intel_drv.h" #include "psb_intel_reg.h" -#include "power.h" -#include <linux/pm_runtime.h> /* The max/min PWM frequency in BPCR[31:17] - */ /* The smallest number is 1 (not 0) that can fit in the @@ -39,7 +30,7 @@ #define MRST_BLC_MAX_PWM_REG_FREQ 0xFFFF #define BRIGHTNESS_MAX_LEVEL 100 -/** +/* * Sets the power state for the panel. */ static void oaktrail_lvds_set_power(struct drm_device *dev, @@ -47,7 +38,7 @@ static void oaktrail_lvds_set_power(struct drm_device *dev, bool on) { u32 pp_status; - struct drm_psb_private *dev_priv = dev->dev_private; + struct drm_psb_private *dev_priv = to_drm_psb_private(dev); if (!gma_power_begin(dev, true)) return; @@ -70,7 +61,6 @@ static void oaktrail_lvds_set_power(struct drm_device *dev, pp_status = REG_READ(PP_STATUS); } while (pp_status & PP_ON); dev_priv->is_lvds_on = false; - pm_request_idle(&dev->pdev->dev); } gma_power_end(dev); } @@ -93,9 +83,9 @@ static void oaktrail_lvds_mode_set(struct drm_encoder *encoder, struct drm_display_mode *adjusted_mode) { struct drm_device *dev = encoder->dev; - struct drm_psb_private *dev_priv = dev->dev_private; + struct drm_psb_private *dev_priv = to_drm_psb_private(dev); struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev; - struct drm_mode_config *mode_config = &dev->mode_config; + struct drm_connector_list_iter conn_iter; struct drm_connector *connector = NULL; struct drm_crtc *crtc = encoder->crtc; u32 lvds_port; @@ -122,20 +112,22 @@ static void oaktrail_lvds_mode_set(struct drm_encoder *encoder, REG_WRITE(LVDS, lvds_port); /* Find the connector we're trying to set up */ - list_for_each_entry(connector, &mode_config->connector_list, head) { - if (!connector->encoder || connector->encoder->crtc != crtc) - continue; + drm_connector_list_iter_begin(dev, &conn_iter); + drm_for_each_connector_iter(connector, &conn_iter) { + if (connector->encoder && connector->encoder->crtc == crtc) + break; } if (!connector) { + drm_connector_list_iter_end(&conn_iter); DRM_ERROR("Couldn't find connector when setting mode"); + gma_power_end(dev); return; } - drm_object_property_get_value( - &connector->base, - dev->mode_config.scaling_mode_property, - &v); + drm_object_property_get_value( &connector->base, + dev->mode_config.scaling_mode_property, &v); + drm_connector_list_iter_end(&conn_iter); if (v == DRM_MODE_SCALE_NO_SCALE) REG_WRITE(PFIT_CONTROL, 0); @@ -164,7 +156,7 @@ static void oaktrail_lvds_mode_set(struct drm_encoder *encoder, static void oaktrail_lvds_prepare(struct drm_encoder *encoder) { struct drm_device *dev = encoder->dev; - struct drm_psb_private *dev_priv = dev->dev_private; + struct drm_psb_private *dev_priv = to_drm_psb_private(dev); struct gma_encoder *gma_encoder = to_gma_encoder(encoder); struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev; @@ -180,7 +172,7 @@ static void oaktrail_lvds_prepare(struct drm_encoder *encoder) static u32 oaktrail_lvds_get_max_backlight(struct drm_device *dev) { - struct drm_psb_private *dev_priv = dev->dev_private; + struct drm_psb_private *dev_priv = to_drm_psb_private(dev); u32 ret; if (gma_power_begin(dev, false)) { @@ -200,7 +192,7 @@ static u32 oaktrail_lvds_get_max_backlight(struct drm_device *dev) static void oaktrail_lvds_commit(struct drm_encoder *encoder) { struct drm_device *dev = encoder->dev; - struct drm_psb_private *dev_priv = dev->dev_private; + struct drm_psb_private *dev_priv = to_drm_psb_private(dev); struct gma_encoder *gma_encoder = to_gma_encoder(encoder); struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev; @@ -224,7 +216,7 @@ static void oaktrail_lvds_get_configuration_mode(struct drm_device *dev, struct psb_intel_mode_device *mode_dev) { struct drm_display_mode *mode = NULL; - struct drm_psb_private *dev_priv = dev->dev_private; + struct drm_psb_private *dev_priv = to_drm_psb_private(dev); struct oaktrail_timing_info *ti = &dev_priv->gct_data.DTD; mode_dev->panel_fixed_mode = NULL; @@ -291,6 +283,7 @@ static void oaktrail_lvds_get_configuration_mode(struct drm_device *dev, /** * oaktrail_lvds_init - setup LVDS connectors on this device * @dev: drm device + * @mode_dev: PSB mode device * * Create the connector, register the LVDS DDC bus, and try to figure out what * modes we can display on the LVDS panel (if present). @@ -300,12 +293,14 @@ void oaktrail_lvds_init(struct drm_device *dev, { struct gma_encoder *gma_encoder; struct gma_connector *gma_connector; + struct gma_i2c_chan *ddc_bus; struct drm_connector *connector; struct drm_encoder *encoder; - struct drm_psb_private *dev_priv = dev->dev_private; + struct drm_psb_private *dev_priv = to_drm_psb_private(dev); struct edid *edid; struct i2c_adapter *i2c_adap; struct drm_display_mode *scan; /* *modes, *bios_mode; */ + int ret; gma_encoder = kzalloc(sizeof(struct gma_encoder), GFP_KERNEL); if (!gma_encoder) @@ -313,17 +308,20 @@ void oaktrail_lvds_init(struct drm_device *dev, gma_connector = kzalloc(sizeof(struct gma_connector), GFP_KERNEL); if (!gma_connector) - goto failed_connector; + goto err_free_encoder; connector = &gma_connector->base; encoder = &gma_encoder->base; dev_priv->is_lvds_on = true; - drm_connector_init(dev, connector, - &psb_intel_lvds_connector_funcs, - DRM_MODE_CONNECTOR_LVDS); + ret = drm_connector_init(dev, connector, + &psb_intel_lvds_connector_funcs, + DRM_MODE_CONNECTOR_LVDS); + if (ret) + goto err_free_connector; - drm_encoder_init(dev, encoder, &psb_intel_lvds_enc_funcs, - DRM_MODE_ENCODER_LVDS, NULL); + ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_LVDS); + if (ret) + goto err_connector_cleanup; gma_connector_attach_encoder(gma_connector, gma_encoder); gma_encoder->type = INTEL_OUTPUT_LVDS; @@ -361,16 +359,26 @@ void oaktrail_lvds_init(struct drm_device *dev, edid = NULL; mutex_lock(&dev->mode_config.mutex); + i2c_adap = i2c_get_adapter(dev_priv->ops->i2c_bus); if (i2c_adap) edid = drm_get_edid(connector, i2c_adap); + if (edid == NULL && dev_priv->lpc_gpio_base) { - oaktrail_lvds_i2c_init(encoder); - if (gma_encoder->ddc_bus != NULL) { - i2c_adap = &gma_encoder->ddc_bus->adapter; + ddc_bus = oaktrail_lvds_i2c_init(dev); + if (!IS_ERR(ddc_bus)) { + i2c_adap = &ddc_bus->base; edid = drm_get_edid(connector, i2c_adap); } } + + /* + * Due to the logic in probing for i2c buses above we do not know the + * i2c_adap until now. Hence we cannot use drm_connector_init_with_ddc() + * but must instead set connector->ddc manually here. + */ + connector->ddc = i2c_adap; + /* * Attempt to get the fixed panel mode from DDC. Assume that the * preferred mode is the right one. @@ -403,30 +411,23 @@ void oaktrail_lvds_init(struct drm_device *dev, /* If we still don't have a mode after all that, give up. */ if (!mode_dev->panel_fixed_mode) { dev_err(dev->dev, "Found no modes on the lvds, ignoring the LVDS\n"); - goto failed_find; + goto err_unlock; } out: mutex_unlock(&dev->mode_config.mutex); - drm_connector_register(connector); return; -failed_find: +err_unlock: mutex_unlock(&dev->mode_config.mutex); - - dev_dbg(dev->dev, "No LVDS modes found, disabling.\n"); - if (gma_encoder->ddc_bus) { - psb_intel_i2c_destroy(gma_encoder->ddc_bus); - gma_encoder->ddc_bus = NULL; - } - -/* failed_ddc: */ - + gma_i2c_destroy(to_gma_i2c_chan(connector->ddc)); drm_encoder_cleanup(encoder); +err_connector_cleanup: drm_connector_cleanup(connector); +err_free_connector: kfree(gma_connector); -failed_connector: +err_free_encoder: kfree(gma_encoder); } |
