linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH drm/hisilicon v2 0/2] support reading resolutions from EDID
@ 2020-09-22  7:03 Tian Tao
  2020-09-22  7:03 ` [PATCH drm/hisilicon v2 1/2] drm/hisilicon: Support i2c driver algorithms for bit-shift adapters Tian Tao
  2020-09-22  7:03 ` [PATCH drm/hisilicon v2 2/2] drm/hisilicon: Features to support reading resolutions from EDID Tian Tao
  0 siblings, 2 replies; 5+ messages in thread
From: Tian Tao @ 2020-09-22  7:03 UTC (permalink / raw)
  To: airlied, daniel, tzimmermann, kraxel, alexander.deucher, tglx,
	dri-devel, xinliang.liu, linux-kernel
  Cc: linuxarm

patch #1 add a new file to implements i2c adapters, #2 read the
resolution from the edid, if that fails, set the resolution to fixed.
and update the destroy callback function to release the i2c adapters

Changes since v1:
-merge patch #3 into patch #2.
-add new function to_hibmc_drm_private, modify three functions in
hibmc_drm_i2c.c with the newly added function.
-deleting the member variable dev from the structure hibmc_connector.
-modify print log incorrectly.
-Modify hibmc_connector_get_modes.

Tian Tao (2):
  drm/hisilicon: Support i2c driver algorithms for bit-shift adapters
  drm/hisilicon: Features to support reading resolutions from EDID

 drivers/gpu/drm/hisilicon/hibmc/Makefile         |   2 +-
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h  |  28 ++++++-
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c  | 100 +++++++++++++++++++++++
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c |  40 +++++++--
 4 files changed, 163 insertions(+), 7 deletions(-)
 create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c

-- 
2.7.4


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH drm/hisilicon v2 1/2] drm/hisilicon: Support i2c driver algorithms for bit-shift adapters
  2020-09-22  7:03 [PATCH drm/hisilicon v2 0/2] support reading resolutions from EDID Tian Tao
@ 2020-09-22  7:03 ` Tian Tao
  2020-09-22  7:19   ` Thomas Zimmermann
  2020-09-22  7:03 ` [PATCH drm/hisilicon v2 2/2] drm/hisilicon: Features to support reading resolutions from EDID Tian Tao
  1 sibling, 1 reply; 5+ messages in thread
From: Tian Tao @ 2020-09-22  7:03 UTC (permalink / raw)
  To: airlied, daniel, tzimmermann, kraxel, alexander.deucher, tglx,
	dri-devel, xinliang.liu, linux-kernel
  Cc: linuxarm

Adding driver implementation to support i2c driver algorithms for
bit-shift adapters, so hibmc will using the interface provided by
drm to read edid.

Signed-off-by: Tian Tao <tiantao6@hisilicon.com>
---
 drivers/gpu/drm/hisilicon/hibmc/Makefile        |  2 +-
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 25 ++++++-
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c | 99 +++++++++++++++++++++++++
 3 files changed, 124 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c

diff --git a/drivers/gpu/drm/hisilicon/hibmc/Makefile b/drivers/gpu/drm/hisilicon/hibmc/Makefile
index f991327..684ef79 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/Makefile
+++ b/drivers/gpu/drm/hisilicon/hibmc/Makefile
@@ -1,4 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
-hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o hibmc_ttm.o
+hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o hibmc_ttm.o hibmc_drm_i2c.o
 
 obj-$(CONFIG_DRM_HISI_HIBMC) += hibmc-drm.o
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
index 197485e..704f477 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
@@ -14,11 +14,23 @@
 #ifndef HIBMC_DRM_DRV_H
 #define HIBMC_DRM_DRV_H
 
+#include <linux/gpio/consumer.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/i2c.h>
+
+#include <drm/drm_edid.h>
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_framebuffer.h>
 
 struct drm_device;
 
+struct hibmc_connector {
+	struct drm_connector base;
+
+	struct i2c_adapter adapter;
+	struct i2c_algo_bit_data bit_data;
+};
+
 struct hibmc_drm_private {
 	/* hw */
 	void __iomem   *mmio;
@@ -31,10 +43,20 @@ struct hibmc_drm_private {
 	struct drm_plane primary_plane;
 	struct drm_crtc crtc;
 	struct drm_encoder encoder;
-	struct drm_connector connector;
+	struct hibmc_connector connector;
 	bool mode_config_initialized;
 };
 
+static inline struct hibmc_connector *to_hibmc_connector(struct drm_connector *connector)
+{
+	return container_of(connector, struct hibmc_connector, base);
+}
+
+static inline struct hibmc_drm_private *to_hibmc_drm_private(struct hibmc_connector *connector)
+{
+	return container_of(connector, struct hibmc_drm_private, connector);
+}
+
 void hibmc_set_power_mode(struct hibmc_drm_private *priv,
 			  unsigned int power_mode);
 void hibmc_set_current_gate(struct hibmc_drm_private *priv,
@@ -47,6 +69,7 @@ int hibmc_mm_init(struct hibmc_drm_private *hibmc);
 void hibmc_mm_fini(struct hibmc_drm_private *hibmc);
 int hibmc_dumb_create(struct drm_file *file, struct drm_device *dev,
 		      struct drm_mode_create_dumb *args);
+int hibmc_ddc_create(struct drm_device *drm_dev, struct hibmc_connector *connector);
 
 extern const struct drm_mode_config_funcs hibmc_mode_funcs;
 
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c
new file mode 100644
index 0000000..5e4674b
--- /dev/null
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* Hisilicon Hibmc SoC drm driver
+ *
+ * Based on the bochs drm driver.
+ *
+ * Copyright (c) 2016 Huawei Limited.
+ *
+ * Author:
+ *      Tian Tao <tiantao6@hisilicon.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/pci.h>
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_probe_helper.h>
+
+#include "hibmc_drm_drv.h"
+
+#define GPIO_DATA		0x0802A0
+#define GPIO_DATA_DIRECTION	0x0802A4
+
+#define GPIO_SCL_MASK 0x1
+#define GPIO_SDA_MASK  0x2
+
+static void hibmc_set_i2c_signal(void *data, u32 mask, int value)
+{
+	struct hibmc_connector *hibmc_connector = data;
+	struct hibmc_drm_private *priv = to_hibmc_drm_private(hibmc_connector);
+	u32 tmp_dir = readl(priv->mmio + GPIO_DATA_DIRECTION);
+
+	if (value) {
+		tmp_dir &= ~mask;
+		writel(tmp_dir, priv->mmio + GPIO_DATA_DIRECTION);
+	} else {
+		u32 tmp_data = readl(priv->mmio + GPIO_DATA);
+
+		tmp_data &= ~mask;
+		writel(tmp_data, priv->mmio + GPIO_DATA);
+
+		tmp_dir |= mask;
+		writel(tmp_dir, priv->mmio + GPIO_DATA_DIRECTION);
+	}
+}
+
+static int hibmc_get_i2c_signal(void *data, u32 mask)
+{
+	struct hibmc_connector *hibmc_connector = data;
+	struct hibmc_drm_private *priv = to_hibmc_drm_private(hibmc_connector);
+	u32 tmp_dir = readl(priv->mmio + GPIO_DATA_DIRECTION);
+
+	if ((tmp_dir & mask) != mask) {
+		tmp_dir &= ~mask;
+		writel(tmp_dir, priv->mmio + GPIO_DATA_DIRECTION);
+	}
+
+	return (readl(priv->mmio + GPIO_DATA) & mask) ? 1 : 0;
+}
+
+static void hibmc_ddc_setsda(void *data, int state)
+{
+	hibmc_set_i2c_signal(data, GPIO_SDA_MASK, state);
+}
+
+static void hibmc_ddc_setscl(void *data, int state)
+{
+	hibmc_set_i2c_signal(data, GPIO_SCL_MASK, state);
+}
+
+static int hibmc_ddc_getsda(void *data)
+{
+	return hibmc_get_i2c_signal(data, GPIO_SDA_MASK);
+}
+
+static int hibmc_ddc_getscl(void *data)
+{
+	return hibmc_get_i2c_signal(data, GPIO_SCL_MASK);
+}
+
+int hibmc_ddc_create(struct drm_device * drm_dev,
+		     struct hibmc_connector *connector)
+{
+	connector->adapter.owner = THIS_MODULE;
+	connector->adapter.class = I2C_CLASS_DDC;
+	snprintf(connector->adapter.name, I2C_NAME_SIZE, "HIS i2c bit bus");
+	connector->adapter.dev.parent = &drm_dev->pdev->dev;
+	i2c_set_adapdata(&connector->adapter, connector);
+	connector->adapter.algo_data = &connector->bit_data;
+
+	connector->bit_data.udelay = 20;
+	connector->bit_data.timeout = usecs_to_jiffies(2000);
+	connector->bit_data.data = connector;
+	connector->bit_data.setsda = hibmc_ddc_setsda;
+	connector->bit_data.setscl = hibmc_ddc_setscl;
+	connector->bit_data.getsda = hibmc_ddc_getsda;
+	connector->bit_data.getscl = hibmc_ddc_getscl;
+
+	return i2c_bit_add_bus(&connector->adapter);
+}
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH drm/hisilicon v2 2/2] drm/hisilicon: Features to support reading resolutions from EDID
  2020-09-22  7:03 [PATCH drm/hisilicon v2 0/2] support reading resolutions from EDID Tian Tao
  2020-09-22  7:03 ` [PATCH drm/hisilicon v2 1/2] drm/hisilicon: Support i2c driver algorithms for bit-shift adapters Tian Tao
@ 2020-09-22  7:03 ` Tian Tao
  2020-09-22  7:20   ` Thomas Zimmermann
  1 sibling, 1 reply; 5+ messages in thread
From: Tian Tao @ 2020-09-22  7:03 UTC (permalink / raw)
  To: airlied, daniel, tzimmermann, kraxel, alexander.deucher, tglx,
	dri-devel, xinliang.liu, linux-kernel
  Cc: linuxarm

Use drm_get_edid to get the resolution, if that fails, set it to
a fixed resolution. Rewrite the desrtoy callback function to release
resources.

Signed-off-by: Tian Tao <tiantao6@hisilicon.com>
---
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 38 +++++++++++++++++++++---
 1 file changed, 34 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
index 376a05d..c6999ed 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
@@ -21,12 +21,24 @@
 static int hibmc_connector_get_modes(struct drm_connector *connector)
 {
 	int count;
+	void *edid;
+	struct hibmc_connector *hibmc_connector = to_hibmc_connector(connector);
+
+	edid = drm_get_edid(connector, &hibmc_connector->adapter);
+	if (edid) {
+		drm_connector_update_edid_property(connector, edid);
+		count = drm_add_edid_modes(connector, edid);
+		if (count)
+			goto out;
+	}
 
 	count = drm_add_modes_noedid(connector,
 				     connector->dev->mode_config.max_width,
 				     connector->dev->mode_config.max_height);
 	drm_set_preferred_mode(connector, 1024, 768);
 
+out:
+	kfree(edid);
 	return count;
 }
 
@@ -36,6 +48,14 @@ static enum drm_mode_status hibmc_connector_mode_valid(struct drm_connector *con
 	return MODE_OK;
 }
 
+static void hibmc_connector_destroy(struct drm_connector *connector)
+{
+	struct hibmc_connector *hibmc_connector = to_hibmc_connector(connector);
+
+	i2c_del_adapter(&hibmc_connector->adapter);
+	drm_connector_cleanup(connector);
+}
+
 static const struct drm_connector_helper_funcs
 	hibmc_connector_helper_funcs = {
 	.get_modes = hibmc_connector_get_modes,
@@ -44,7 +64,7 @@ static const struct drm_connector_helper_funcs
 
 static const struct drm_connector_funcs hibmc_connector_funcs = {
 	.fill_modes = drm_helper_probe_single_connector_modes,
-	.destroy = drm_connector_cleanup,
+	.destroy = hibmc_connector_destroy,
 	.reset = drm_atomic_helper_connector_reset,
 	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
@@ -77,10 +97,17 @@ static const struct drm_encoder_funcs hibmc_encoder_funcs = {
 int hibmc_vdac_init(struct hibmc_drm_private *priv)
 {
 	struct drm_device *dev = priv->dev;
+	struct hibmc_connector *hibmc_connector = &priv->connector;
 	struct drm_encoder *encoder = &priv->encoder;
-	struct drm_connector *connector = &priv->connector;
+	struct drm_connector *connector = &hibmc_connector->base;
 	int ret;
 
+	ret = hibmc_ddc_create(dev, hibmc_connector);
+	if (ret) {
+		drm_err(dev, "failed to create ddc: %d\n", ret);
+		return ret;
+	}
+
 	encoder->possible_crtcs = 0x1;
 	ret = drm_encoder_init(dev, encoder, &hibmc_encoder_funcs,
 			       DRM_MODE_ENCODER_DAC, NULL);
@@ -91,12 +118,15 @@ int hibmc_vdac_init(struct hibmc_drm_private *priv)
 
 	drm_encoder_helper_add(encoder, &hibmc_encoder_helper_funcs);
 
-	ret = drm_connector_init(dev, connector, &hibmc_connector_funcs,
-				 DRM_MODE_CONNECTOR_VGA);
+	ret = drm_connector_init_with_ddc(dev, connector,
+					  &hibmc_connector_funcs,
+					  DRM_MODE_CONNECTOR_VGA,
+					  &hibmc_connector->adapter);
 	if (ret) {
 		drm_err(dev, "failed to init connector: %d\n", ret);
 		return ret;
 	}
+
 	drm_connector_helper_add(connector, &hibmc_connector_helper_funcs);
 
 	drm_connector_attach_encoder(connector, encoder);
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH drm/hisilicon v2 1/2] drm/hisilicon: Support i2c driver algorithms for bit-shift adapters
  2020-09-22  7:03 ` [PATCH drm/hisilicon v2 1/2] drm/hisilicon: Support i2c driver algorithms for bit-shift adapters Tian Tao
@ 2020-09-22  7:19   ` Thomas Zimmermann
  0 siblings, 0 replies; 5+ messages in thread
From: Thomas Zimmermann @ 2020-09-22  7:19 UTC (permalink / raw)
  To: Tian Tao, airlied, daniel, kraxel, alexander.deucher, tglx,
	dri-devel, xinliang.liu, linux-kernel
  Cc: linuxarm


[-- Attachment #1.1: Type: text/plain, Size: 7114 bytes --]

Hi,

again a few nits below.

Am 22.09.20 um 09:03 schrieb Tian Tao:
> Adding driver implementation to support i2c driver algorithms for
> bit-shift adapters, so hibmc will using the interface provided by
> drm to read edid.
> 
> Signed-off-by: Tian Tao <tiantao6@hisilicon.com>

I gave this an R-b, which you should have added. The code is still the
same, so it counts.

> ---
>  drivers/gpu/drm/hisilicon/hibmc/Makefile        |  2 +-
>  drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 25 ++++++-
>  drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c | 99 +++++++++++++++++++++++++
>  3 files changed, 124 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c
> 
> diff --git a/drivers/gpu/drm/hisilicon/hibmc/Makefile b/drivers/gpu/drm/hisilicon/hibmc/Makefile
> index f991327..684ef79 100644
> --- a/drivers/gpu/drm/hisilicon/hibmc/Makefile
> +++ b/drivers/gpu/drm/hisilicon/hibmc/Makefile
> @@ -1,4 +1,4 @@
>  # SPDX-License-Identifier: GPL-2.0-only
> -hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o hibmc_ttm.o
> +hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o hibmc_ttm.o hibmc_drm_i2c.o
>  
>  obj-$(CONFIG_DRM_HISI_HIBMC) += hibmc-drm.o
> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
> index 197485e..704f477 100644
> --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
> @@ -14,11 +14,23 @@
>  #ifndef HIBMC_DRM_DRV_H
>  #define HIBMC_DRM_DRV_H
>  
> +#include <linux/gpio/consumer.h>
> +#include <linux/i2c-algo-bit.h>
> +#include <linux/i2c.h>
> +
> +#include <drm/drm_edid.h>
>  #include <drm/drm_fb_helper.h>
>  #include <drm/drm_framebuffer.h>
>  
>  struct drm_device;
>  
> +struct hibmc_connector {
> +	struct drm_connector base;
> +
> +	struct i2c_adapter adapter;
> +	struct i2c_algo_bit_data bit_data;
> +};
> +
>  struct hibmc_drm_private {
>  	/* hw */
>  	void __iomem   *mmio;
> @@ -31,10 +43,20 @@ struct hibmc_drm_private {
>  	struct drm_plane primary_plane;
>  	struct drm_crtc crtc;
>  	struct drm_encoder encoder;
> -	struct drm_connector connector;
> +	struct hibmc_connector connector;
>  	bool mode_config_initialized;
>  };
>  
> +static inline struct hibmc_connector *to_hibmc_connector(struct drm_connector *connector)
> +{
> +	return container_of(connector, struct hibmc_connector, base);
> +}
> +
> +static inline struct hibmc_drm_private *to_hibmc_drm_private(struct hibmc_connector *connector)
> +{
> +	return container_of(connector, struct hibmc_drm_private, connector);
> +}

That's not how it was supposed to be. What I meant was, that the
function should take struct drm_device and return struct
hibmc_drm_private from dev->dev_private. Sorry about the confusion.

> +
>  void hibmc_set_power_mode(struct hibmc_drm_private *priv,
>  			  unsigned int power_mode);
>  void hibmc_set_current_gate(struct hibmc_drm_private *priv,
> @@ -47,6 +69,7 @@ int hibmc_mm_init(struct hibmc_drm_private *hibmc);
>  void hibmc_mm_fini(struct hibmc_drm_private *hibmc);
>  int hibmc_dumb_create(struct drm_file *file, struct drm_device *dev,
>  		      struct drm_mode_create_dumb *args);
> +int hibmc_ddc_create(struct drm_device *drm_dev, struct hibmc_connector *connector);
>  
>  extern const struct drm_mode_config_funcs hibmc_mode_funcs;
>  
> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c
> new file mode 100644
> index 0000000..5e4674b
> --- /dev/null
> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c
> @@ -0,0 +1,99 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/* Hisilicon Hibmc SoC drm driver
> + *
> + * Based on the bochs drm driver.
> + *
> + * Copyright (c) 2016 Huawei Limited.
> + *
> + * Author:
> + *      Tian Tao <tiantao6@hisilicon.com>
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/pci.h>
> +
> +#include <drm/drm_atomic_helper.h>
> +#include <drm/drm_probe_helper.h>
> +
> +#include "hibmc_drm_drv.h"
> +
> +#define GPIO_DATA		0x0802A0
> +#define GPIO_DATA_DIRECTION	0x0802A4
> +
> +#define GPIO_SCL_MASK 0x1
> +#define GPIO_SDA_MASK  0x2

The indention of these two lines is still weird. The constants are not
aligned. I'd also suggest to use the BIT() macro to set the constants.

Best regards
Thomas

> +
> +static void hibmc_set_i2c_signal(void *data, u32 mask, int value)
> +{
> +	struct hibmc_connector *hibmc_connector = data;
> +	struct hibmc_drm_private *priv = to_hibmc_drm_private(hibmc_connector);
> +	u32 tmp_dir = readl(priv->mmio + GPIO_DATA_DIRECTION);
> +
> +	if (value) {
> +		tmp_dir &= ~mask;
> +		writel(tmp_dir, priv->mmio + GPIO_DATA_DIRECTION);
> +	} else {
> +		u32 tmp_data = readl(priv->mmio + GPIO_DATA);
> +
> +		tmp_data &= ~mask;
> +		writel(tmp_data, priv->mmio + GPIO_DATA);
> +
> +		tmp_dir |= mask;
> +		writel(tmp_dir, priv->mmio + GPIO_DATA_DIRECTION);
> +	}
> +}
> +
> +static int hibmc_get_i2c_signal(void *data, u32 mask)
> +{
> +	struct hibmc_connector *hibmc_connector = data;
> +	struct hibmc_drm_private *priv = to_hibmc_drm_private(hibmc_connector);
> +	u32 tmp_dir = readl(priv->mmio + GPIO_DATA_DIRECTION);
> +
> +	if ((tmp_dir & mask) != mask) {
> +		tmp_dir &= ~mask;
> +		writel(tmp_dir, priv->mmio + GPIO_DATA_DIRECTION);
> +	}
> +
> +	return (readl(priv->mmio + GPIO_DATA) & mask) ? 1 : 0;
> +}
> +
> +static void hibmc_ddc_setsda(void *data, int state)
> +{
> +	hibmc_set_i2c_signal(data, GPIO_SDA_MASK, state);
> +}
> +
> +static void hibmc_ddc_setscl(void *data, int state)
> +{
> +	hibmc_set_i2c_signal(data, GPIO_SCL_MASK, state);
> +}
> +
> +static int hibmc_ddc_getsda(void *data)
> +{
> +	return hibmc_get_i2c_signal(data, GPIO_SDA_MASK);
> +}
> +
> +static int hibmc_ddc_getscl(void *data)
> +{
> +	return hibmc_get_i2c_signal(data, GPIO_SCL_MASK);
> +}
> +
> +int hibmc_ddc_create(struct drm_device * drm_dev,
> +		     struct hibmc_connector *connector)
> +{
> +	connector->adapter.owner = THIS_MODULE;
> +	connector->adapter.class = I2C_CLASS_DDC;
> +	snprintf(connector->adapter.name, I2C_NAME_SIZE, "HIS i2c bit bus");
> +	connector->adapter.dev.parent = &drm_dev->pdev->dev;
> +	i2c_set_adapdata(&connector->adapter, connector);
> +	connector->adapter.algo_data = &connector->bit_data;
> +
> +	connector->bit_data.udelay = 20;
> +	connector->bit_data.timeout = usecs_to_jiffies(2000);
> +	connector->bit_data.data = connector;
> +	connector->bit_data.setsda = hibmc_ddc_setsda;
> +	connector->bit_data.setscl = hibmc_ddc_setscl;
> +	connector->bit_data.getsda = hibmc_ddc_getsda;
> +	connector->bit_data.getscl = hibmc_ddc_getscl;
> +
> +	return i2c_bit_add_bus(&connector->adapter);
> +}
> 

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Felix Imendörffer


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 516 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH drm/hisilicon v2 2/2] drm/hisilicon: Features to support reading resolutions from EDID
  2020-09-22  7:03 ` [PATCH drm/hisilicon v2 2/2] drm/hisilicon: Features to support reading resolutions from EDID Tian Tao
@ 2020-09-22  7:20   ` Thomas Zimmermann
  0 siblings, 0 replies; 5+ messages in thread
From: Thomas Zimmermann @ 2020-09-22  7:20 UTC (permalink / raw)
  To: Tian Tao, airlied, daniel, kraxel, alexander.deucher, tglx,
	dri-devel, xinliang.liu, linux-kernel
  Cc: linuxarm


[-- Attachment #1.1: Type: text/plain, Size: 4055 bytes --]



Am 22.09.20 um 09:03 schrieb Tian Tao:
> Use drm_get_edid to get the resolution, if that fails, set it to
> a fixed resolution. Rewrite the desrtoy callback function to release
> resources.
> 
> Signed-off-by: Tian Tao <tiantao6@hisilicon.com>

Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>

> ---
>  drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 38 +++++++++++++++++++++---
>  1 file changed, 34 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
> index 376a05d..c6999ed 100644
> --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
> @@ -21,12 +21,24 @@
>  static int hibmc_connector_get_modes(struct drm_connector *connector)
>  {
>  	int count;
> +	void *edid;
> +	struct hibmc_connector *hibmc_connector = to_hibmc_connector(connector);
> +
> +	edid = drm_get_edid(connector, &hibmc_connector->adapter);
> +	if (edid) {
> +		drm_connector_update_edid_property(connector, edid);
> +		count = drm_add_edid_modes(connector, edid);
> +		if (count)
> +			goto out;
> +	}
>  
>  	count = drm_add_modes_noedid(connector,
>  				     connector->dev->mode_config.max_width,
>  				     connector->dev->mode_config.max_height);
>  	drm_set_preferred_mode(connector, 1024, 768);
>  
> +out:
> +	kfree(edid);
>  	return count;
>  }
>  
> @@ -36,6 +48,14 @@ static enum drm_mode_status hibmc_connector_mode_valid(struct drm_connector *con
>  	return MODE_OK;
>  }
>  
> +static void hibmc_connector_destroy(struct drm_connector *connector)
> +{
> +	struct hibmc_connector *hibmc_connector = to_hibmc_connector(connector);
> +
> +	i2c_del_adapter(&hibmc_connector->adapter);
> +	drm_connector_cleanup(connector);
> +}
> +
>  static const struct drm_connector_helper_funcs
>  	hibmc_connector_helper_funcs = {
>  	.get_modes = hibmc_connector_get_modes,
> @@ -44,7 +64,7 @@ static const struct drm_connector_helper_funcs
>  
>  static const struct drm_connector_funcs hibmc_connector_funcs = {
>  	.fill_modes = drm_helper_probe_single_connector_modes,
> -	.destroy = drm_connector_cleanup,
> +	.destroy = hibmc_connector_destroy,
>  	.reset = drm_atomic_helper_connector_reset,
>  	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
>  	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
> @@ -77,10 +97,17 @@ static const struct drm_encoder_funcs hibmc_encoder_funcs = {
>  int hibmc_vdac_init(struct hibmc_drm_private *priv)
>  {
>  	struct drm_device *dev = priv->dev;
> +	struct hibmc_connector *hibmc_connector = &priv->connector;
>  	struct drm_encoder *encoder = &priv->encoder;
> -	struct drm_connector *connector = &priv->connector;
> +	struct drm_connector *connector = &hibmc_connector->base;
>  	int ret;
>  
> +	ret = hibmc_ddc_create(dev, hibmc_connector);
> +	if (ret) {
> +		drm_err(dev, "failed to create ddc: %d\n", ret);
> +		return ret;
> +	}
> +
>  	encoder->possible_crtcs = 0x1;
>  	ret = drm_encoder_init(dev, encoder, &hibmc_encoder_funcs,
>  			       DRM_MODE_ENCODER_DAC, NULL);
> @@ -91,12 +118,15 @@ int hibmc_vdac_init(struct hibmc_drm_private *priv)
>  
>  	drm_encoder_helper_add(encoder, &hibmc_encoder_helper_funcs);
>  
> -	ret = drm_connector_init(dev, connector, &hibmc_connector_funcs,
> -				 DRM_MODE_CONNECTOR_VGA);
> +	ret = drm_connector_init_with_ddc(dev, connector,
> +					  &hibmc_connector_funcs,
> +					  DRM_MODE_CONNECTOR_VGA,
> +					  &hibmc_connector->adapter);
>  	if (ret) {
>  		drm_err(dev, "failed to init connector: %d\n", ret);
>  		return ret;
>  	}
> +
>  	drm_connector_helper_add(connector, &hibmc_connector_helper_funcs);
>  
>  	drm_connector_attach_encoder(connector, encoder);
> 

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Felix Imendörffer


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 516 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-09-22  7:20 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-22  7:03 [PATCH drm/hisilicon v2 0/2] support reading resolutions from EDID Tian Tao
2020-09-22  7:03 ` [PATCH drm/hisilicon v2 1/2] drm/hisilicon: Support i2c driver algorithms for bit-shift adapters Tian Tao
2020-09-22  7:19   ` Thomas Zimmermann
2020-09-22  7:03 ` [PATCH drm/hisilicon v2 2/2] drm/hisilicon: Features to support reading resolutions from EDID Tian Tao
2020-09-22  7:20   ` Thomas Zimmermann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).