[Intel-gfx] [PATCH 2/2] drm/i915: GPIO for CHT generic MIPI
Deepak M
m.deepak at intel.com
Wed Feb 24 13:43:46 UTC 2016
From: Yogesh Mohan Marimuthu <yogesh.mohan.marimuthu at intel.com>
The GPIO configuration and register offsets are different from
baytrail for cherrytrail. Port the gpio programming accordingly
for cherrytrail in this patch.
v2: Removing the duplication of parsing
v3: Moved the macro def to panel_vbt.c file
Cc: Ville Syrjälä <ville.syrjala at linux.intel.com>
Cc: Jani Nikula <jani.nikula at intel.com>
Signed-off-by: Yogesh Mohan Marimuthu <yogesh.mohan.marimuthu at intel.com>
Signed-off-by: Deepak M <m.deepak at intel.com>
---
drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 123 +++++++++++++++++++++++------
1 file changed, 98 insertions(+), 25 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
index 794bd1f..6b9a1f7 100644
--- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
+++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
@@ -58,6 +58,28 @@ static inline struct vbt_panel *to_vbt_panel(struct drm_panel *panel)
#define NS_KHZ_RATIO 1000000
+#define CHV_IOSF_PORT_GPIO_N 0x13
+#define CHV_IOSF_PORT_GPIO_SE 0x48
+#define CHV_IOSF_PORT_GPIO_SW 0xB2
+#define CHV_IOSF_PORT_GPIO_E 0xA8
+#define CHV_MAX_GPIO_NUM_N 72
+#define CHV_MAX_GPIO_NUM_SE 99
+#define CHV_MAX_GPIO_NUM_SW 197
+#define CHV_MIN_GPIO_NUM_SE 73
+#define CHV_MIN_GPIO_NUM_SW 100
+#define CHV_MIN_GPIO_NUM_E 198
+
+#define CHV_PAD_FMLY_BASE 0x4400
+#define CHV_PAD_FMLY_SIZE 0x400
+#define CHV_PAD_CFG_0_1_REG_SIZE 0x8
+#define CHV_PAD_CFG_REG_SIZE 0x4
+#define CHV_VBT_MAX_PINS_PER_FMLY 15
+
+#define CHV_GPIO_CFG_UNLOCK 0x00000000
+#define CHV_GPIO_CFG_HIZ 0x00008100
+#define CHV_GPIO_CFG_TX_STATE_SHIFT 1
+
+
#define VLV_HV_DDI0_HPD_GPIONC_0_PCONF0 0x4130
#define VLV_HV_DDI0_HPD_GPIONC_0_PAD 0x4138
#define VLV_HV_DDI0_DDC_SDA_GPIONC_1_PCONF0 0x4120
@@ -685,34 +707,13 @@ static const u8 *mipi_exec_delay(struct intel_dsi *intel_dsi, const u8 *data)
return data;
}
-static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data)
+void vlv_program_gpio(struct intel_dsi *intel_dsi, u8 gpio, u8 action)
{
- u8 gpio, action;
+ struct drm_device *dev = intel_dsi->base.base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
u16 function, pad;
u32 val;
u8 port;
- struct drm_device *dev = intel_dsi->base.base.dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- DRM_DEBUG_DRIVER("MIPI: executing gpio element\n");
-
- if (dev_priv->vbt.dsi.seq_version >= 3)
- data++;
-
- gpio = *data++;
-
- /* pull up/down */
- action = *data++ & 1;
-
- if (gpio >= ARRAY_SIZE(gtable)) {
- DRM_DEBUG_KMS("unknown gpio %u\n", gpio);
- goto out;
- }
-
- if (!IS_VALLEYVIEW(dev_priv)) {
- DRM_DEBUG_KMS("GPIO element not supported on this platform\n");
- goto out;
- }
if (dev_priv->vbt.dsi.seq_version >= 3) {
if (gpio <= IOSF_MAX_GPIO_NUM_NC) {
@@ -728,7 +729,7 @@ static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data)
port = IOSF_PORT_GPIO_SUS;
} else {
DRM_ERROR("GPIO number is not present in the table\n");
- goto out;
+ return;
}
} else {
port = IOSF_PORT_GPIO_NC;
@@ -750,6 +751,78 @@ static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data)
/* pull up/down */
vlv_iosf_sb_write(dev_priv, port, pad, val);
mutex_unlock(&dev_priv->sb_lock);
+}
+
+void chv_program_gpio(struct intel_dsi *intel_dsi, u8 gpio, u8 action)
+{
+ struct drm_device *dev = intel_dsi->base.base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u16 function, pad;
+ u16 family_num;
+ u8 block;
+
+ if (dev_priv->vbt.dsi.seq_version >= 3) {
+ if (gpio <= CHV_MAX_GPIO_NUM_N) {
+ block = CHV_IOSF_PORT_GPIO_N;
+ DRM_DEBUG_DRIVER("GPIO is in the north Block\n");
+ } else if (gpio <= CHV_MAX_GPIO_NUM_SE) {
+ block = CHV_IOSF_PORT_GPIO_SE;
+ gpio = gpio - CHV_MIN_GPIO_NUM_SE;
+ DRM_DEBUG_DRIVER("GPIO is in the south east Block\n");
+ } else if (gpio <= CHV_MAX_GPIO_NUM_SW) {
+ block = CHV_IOSF_PORT_GPIO_SW;
+ gpio = gpio - CHV_MIN_GPIO_NUM_SW;
+ DRM_DEBUG_DRIVER("GPIO is in the south west Block\n");
+ } else {
+ block = CHV_IOSF_PORT_GPIO_E;
+ gpio = gpio - CHV_MIN_GPIO_NUM_E;
+ DRM_DEBUG_DRIVER("GPIO is in the east Block\n");
+ }
+ } else
+ block = IOSF_PORT_GPIO_NC;
+
+ family_num = gpio / CHV_VBT_MAX_PINS_PER_FMLY;
+ gpio = gpio - (family_num * CHV_VBT_MAX_PINS_PER_FMLY);
+ pad = CHV_PAD_FMLY_BASE + (family_num * CHV_PAD_FMLY_SIZE) +
+ (((u16)gpio) * CHV_PAD_CFG_0_1_REG_SIZE);
+ function = pad + CHV_PAD_CFG_REG_SIZE;
+
+ mutex_lock(&dev_priv->sb_lock);
+ vlv_iosf_sb_write(dev_priv, block, function,
+ CHV_GPIO_CFG_UNLOCK);
+ vlv_iosf_sb_write(dev_priv, block, pad, CHV_GPIO_CFG_HIZ |
+ (action << CHV_GPIO_CFG_TX_STATE_SHIFT));
+ mutex_unlock(&dev_priv->sb_lock);
+
+}
+
+static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data)
+{
+ u8 gpio, action;
+ struct drm_device *dev = intel_dsi->base.base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ DRM_DEBUG_DRIVER("MIPI: executing gpio element\n");
+
+ if (dev_priv->vbt.dsi.seq_version >= 3)
+ data++;
+
+ gpio = *data++;
+
+ /* pull up/down */
+ action = *data++ & 1;
+
+ if (gpio >= ARRAY_SIZE(gtable)) {
+ DRM_DEBUG_KMS("unknown gpio %u\n", gpio);
+ goto out;
+ }
+
+ if (IS_VALLEYVIEW(dev))
+ vlv_program_gpio(intel_dsi, gpio, action);
+ else if (IS_CHERRYVIEW(dev))
+ chv_program_gpio(intel_dsi, gpio, action);
+ else
+ DRM_ERROR("GPIO programming missing for this platform.\n");
out:
return data;
--
1.9.1
More information about the Intel-gfx
mailing list