[Intel-gfx] [PATCH 1/2] drm/i915: Get the i2c bus number from the ACPI

Deepak, M m.deepak at intel.com
Tue Apr 19 10:38:17 UTC 2016


Waiting for review comments.

> -----Original Message-----
> From: Deepak, M
> Sent: Friday, March 11, 2016 3:55 PM
> To: intel-gfx at lists.freedesktop.org
> Cc: Deepak, M <m.deepak at intel.com>; Nikula, Jani <jani.nikula at intel.com>;
> Ville Syrjälä <ville.syrjala at linux.intel.com>
> Subject: [PATCH 1/2] drm/i915: Get the i2c bus number from the ACPI
> 
> Currently for executing the i2c MIPI sequence, we are relaying on the i2c bus
> number which is specified in the VBT. But there are cases where different
> Fab versions of the board will drive the same chip with different i2c port, in
> which case the i2c bus number from the VBT cant be relied on. To overcome
> this the i2c bus number is read from the BIOS acpi table; BIOS can detect the
> Fab version in runtime and will store the correct i2c bus number in the ACPI
> table.
> 
> v2 by Deepak:
>  - Reading the i2c from the ACPI and storing them in list
> 
> Cc: Jani Nikula <jani.nikula at intel.com>
> Cc: Ville Syrjälä <ville.syrjala at linux.intel.com>
> Signed-off-by: Deepak M <m.deepak at intel.com>
> ---
>  drivers/gpu/drm/i915/i915_dma.c   |  2 ++
>  drivers/gpu/drm/i915/i915_drv.h   | 11 ++++++++
>  drivers/gpu/drm/i915/intel_acpi.c | 59
> +++++++++++++++++++++++++++++++++++++++
>  3 files changed, 72 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_dma.c
> b/drivers/gpu/drm/i915/i915_dma.c index 4aa3db6..57be99b 100644
> --- a/drivers/gpu/drm/i915/i915_dma.c
> +++ b/drivers/gpu/drm/i915/i915_dma.c
> @@ -387,6 +387,8 @@ static int i915_load_modeset_init(struct drm_device
> *dev)
> 
>  	intel_register_dsm_handler();
> 
> +	intel_acpi_find_i2c(dev_priv);
> +
>  	ret = vga_switcheroo_register_client(dev->pdev,
> &i915_switcheroo_ops, false);
>  	if (ret)
>  		goto cleanup_vga_client;
> diff --git a/drivers/gpu/drm/i915/i915_drv.h
> b/drivers/gpu/drm/i915/i915_drv.h index f37ac12..5c6279d 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -41,6 +41,7 @@
>  #include "intel_lrc.h"
>  #include "i915_gem_gtt.h"
>  #include "i915_gem_render_state.h"
> +#include <linux/acpi.h>
>  #include <linux/io-mapping.h>
>  #include <linux/i2c.h>
>  #include <linux/i2c-algo-bit.h>
> @@ -1739,6 +1740,12 @@ struct intel_wm_config {
>  	bool sprites_scaled;
>  };
> 
> +struct acpi_i2c_data_node {
> +	struct list_head head;
> +	int i2c_bus_number;
> +	int i2c_slave_address;
> +};
> +
>  struct drm_i915_private {
>  	struct drm_device *dev;
>  	struct kmem_cache *objects;
> @@ -1823,6 +1830,8 @@ struct drm_i915_private {
>  	/* backlight registers and fields in struct intel_panel */
>  	struct mutex backlight_lock;
> 
> +	struct list_head acpi_i2c_list;
> +
>  	/* LVDS info */
>  	bool no_aux_handshake;
> 
> @@ -1892,6 +1901,7 @@ struct drm_i915_private {
> 
>  	struct i915_workarounds workarounds;
> 
> +
>  	/* Reclocking support */
>  	bool render_reclock_avail;
> 
> @@ -3439,6 +3449,7 @@ intel_opregion_notify_adapter(struct drm_device
> *dev, pci_power_t state)  #ifdef CONFIG_ACPI  extern void
> intel_register_dsm_handler(void);  extern void
> intel_unregister_dsm_handler(void);
> +extern acpi_status intel_acpi_find_i2c(struct drm_i915_private
> +*dev_priv);
>  #else
>  static inline void intel_register_dsm_handler(void) { return; }  static inline
> void intel_unregister_dsm_handler(void) { return; } diff --git
> a/drivers/gpu/drm/i915/intel_acpi.c b/drivers/gpu/drm/i915/intel_acpi.c
> index eb638a1..afe42ab 100644
> --- a/drivers/gpu/drm/i915/intel_acpi.c
> +++ b/drivers/gpu/drm/i915/intel_acpi.c
> @@ -110,6 +110,65 @@ static void intel_dsm_platform_mux_info(void)
>  	ACPI_FREE(pkg);
>  }
> 
> +static int i2c_acpi_get_name(struct acpi_resource *ares, void *data) {
> +	struct drm_i915_private *dev_priv = data;
> +	struct acpi_resource_i2c_serialbus *sb;
> +	unsigned int val;
> +	char *resource;
> +	int error;
> +
> +
> +	if (ares->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) {
> +		sb = &ares->data.i2c_serial_bus;
> +
> +		if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_I2C) {
> +			struct acpi_i2c_data_node *i2c_entry = NULL;
> +
> +			resource = sb->resource_source.string_ptr;
> +			resource = strstr(resource, "I2C");
> +			error = kstrtouint(resource+3, 0, &val);
> +			if (error)
> +				return error;
> +
> +			i2c_entry = kzalloc(sizeof(struct
> acpi_i2c_data_node),
> +					GFP_NOWAIT);
> +			i2c_entry->i2c_bus_number = val;
> +			i2c_entry->i2c_slave_address = sb->slave_address;
> +
> +			list_add_tail(&i2c_entry->head,
> +					&dev_priv->acpi_i2c_list);
> +		}
> +	}
> +
> +	return 1;
> +}
> +
> +acpi_status intel_acpi_find_i2c(struct drm_i915_private *dev_priv) {
> +	struct pci_dev *pdev = dev_priv->dev->pdev;
> +	struct list_head resource_list;
> +	struct acpi_device *adev;
> +	acpi_handle dhandle;
> +
> +	dhandle = ACPI_HANDLE(&pdev->dev);
> +	if (!dhandle)
> +		return false;
> +
> +	if (acpi_bus_get_device(dhandle, &adev))
> +		return AE_OK;
> +	if (acpi_bus_get_status(adev) || !adev->status.present)
> +		return AE_OK;
> +
> +	INIT_LIST_HEAD(&resource_list);
> +	INIT_LIST_HEAD(&dev_priv->acpi_i2c_list);
> +	acpi_dev_get_resources(adev, &resource_list,
> +			i2c_acpi_get_name, dev_priv);
> +	acpi_dev_free_resource_list(&resource_list);
> +
> +	return AE_OK;
> +}
> +
>  static bool intel_dsm_pci_probe(struct pci_dev *pdev)  {
>  	acpi_handle dhandle;
> --
> 1.9.1



More information about the Intel-gfx mailing list