|
@@ -31,6 +31,7 @@
|
|
#include <drm/drm_panel.h>
|
|
#include <drm/drm_panel.h>
|
|
#include <drm/drm_mipi_dsi.h>
|
|
#include <drm/drm_mipi_dsi.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/slab.h>
|
|
|
|
+#include <linux/gpio/consumer.h>
|
|
#include "i915_drv.h"
|
|
#include "i915_drv.h"
|
|
#include "intel_drv.h"
|
|
#include "intel_drv.h"
|
|
#include "intel_dsi.h"
|
|
#include "intel_dsi.h"
|
|
@@ -415,6 +416,12 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder)
|
|
|
|
|
|
DRM_DEBUG_KMS("\n");
|
|
DRM_DEBUG_KMS("\n");
|
|
|
|
|
|
|
|
+ /* Panel Enable over CRC PMIC */
|
|
|
|
+ if (intel_dsi->gpio_panel)
|
|
|
|
+ gpiod_set_value_cansleep(intel_dsi->gpio_panel, 1);
|
|
|
|
+
|
|
|
|
+ msleep(intel_dsi->panel_on_delay);
|
|
|
|
+
|
|
/* Disable DPOunit clock gating, can stall pipe
|
|
/* Disable DPOunit clock gating, can stall pipe
|
|
* and we need DPLL REFA always enabled */
|
|
* and we need DPLL REFA always enabled */
|
|
tmp = I915_READ(DPLL(pipe));
|
|
tmp = I915_READ(DPLL(pipe));
|
|
@@ -432,8 +439,6 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder)
|
|
/* put device in ready state */
|
|
/* put device in ready state */
|
|
intel_dsi_device_ready(encoder);
|
|
intel_dsi_device_ready(encoder);
|
|
|
|
|
|
- msleep(intel_dsi->panel_on_delay);
|
|
|
|
-
|
|
|
|
drm_panel_prepare(intel_dsi->panel);
|
|
drm_panel_prepare(intel_dsi->panel);
|
|
|
|
|
|
for_each_dsi_port(port, intel_dsi->ports)
|
|
for_each_dsi_port(port, intel_dsi->ports)
|
|
@@ -576,6 +581,10 @@ static void intel_dsi_post_disable(struct intel_encoder *encoder)
|
|
|
|
|
|
msleep(intel_dsi->panel_off_delay);
|
|
msleep(intel_dsi->panel_off_delay);
|
|
msleep(intel_dsi->panel_pwr_cycle_delay);
|
|
msleep(intel_dsi->panel_pwr_cycle_delay);
|
|
|
|
+
|
|
|
|
+ /* Panel Disable over CRC PMIC */
|
|
|
|
+ if (intel_dsi->gpio_panel)
|
|
|
|
+ gpiod_set_value_cansleep(intel_dsi->gpio_panel, 0);
|
|
}
|
|
}
|
|
|
|
|
|
static bool intel_dsi_get_hw_state(struct intel_encoder *encoder,
|
|
static bool intel_dsi_get_hw_state(struct intel_encoder *encoder,
|
|
@@ -955,6 +964,11 @@ static void intel_dsi_encoder_destroy(struct drm_encoder *encoder)
|
|
/* XXX: Logically this call belongs in the panel driver. */
|
|
/* XXX: Logically this call belongs in the panel driver. */
|
|
drm_panel_remove(intel_dsi->panel);
|
|
drm_panel_remove(intel_dsi->panel);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ /* dispose of the gpios */
|
|
|
|
+ if (intel_dsi->gpio_panel)
|
|
|
|
+ gpiod_put(intel_dsi->gpio_panel);
|
|
|
|
+
|
|
intel_encoder_destroy(encoder);
|
|
intel_encoder_destroy(encoder);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1071,6 +1085,20 @@ void intel_dsi_init(struct drm_device *dev)
|
|
goto err;
|
|
goto err;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * In case of BYT with CRC PMIC, we need to use GPIO for
|
|
|
|
+ * Panel control.
|
|
|
|
+ */
|
|
|
|
+ if (dev_priv->vbt.dsi.config->pwm_blc == PPS_BLC_PMIC) {
|
|
|
|
+ intel_dsi->gpio_panel =
|
|
|
|
+ gpiod_get(dev->dev, "panel", GPIOD_OUT_HIGH);
|
|
|
|
+
|
|
|
|
+ if (IS_ERR(intel_dsi->gpio_panel)) {
|
|
|
|
+ DRM_ERROR("Failed to own gpio for panel control\n");
|
|
|
|
+ intel_dsi->gpio_panel = NULL;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
intel_encoder->type = INTEL_OUTPUT_DSI;
|
|
intel_encoder->type = INTEL_OUTPUT_DSI;
|
|
intel_encoder->cloneable = 0;
|
|
intel_encoder->cloneable = 0;
|
|
drm_connector_init(dev, connector, &intel_dsi_connector_funcs,
|
|
drm_connector_init(dev, connector, &intel_dsi_connector_funcs,
|