Add support for PMIC MIPI sequences using the new intel_soc_pmic_exec_mipi_pmic_seq_element function. This fixes the DSI LCD panel not lighting up when not initialized by the GOP (because an external monitor was connected) on GPD win and GPD pocket devices. Specifically the LCD panel seems to need GPIO pin 9 on the PMIC to be driven high, which is done through a PMIC MIPI sequence. Before this commit if the sequence was not executed by the GOP the pin would stay low causing the LCD panel to not work. Having the MIPI sequences properly control this GPIO should also help save some power when the panel is off. Changes in v2, v3: -Only changes to other patches in this patch-set Changes in v4: -Move decoding of the raw 15 bytes PMIC MIPI sequence element into i2c-address, register-address, value and mask into the mipi_exec_pmic() function instead of passing the raw data to intel_soc_pmic_exec_mipi_pmic_seq_element() Signed-off-by: Hans de Goede <hdegoede@xxxxxxxxxx> --- drivers/gpu/drm/i915/intel_dsi_vbt.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dsi_vbt.c b/drivers/gpu/drm/i915/intel_dsi_vbt.c index f27af47c6e49..ebe7e25614ce 100644 --- a/drivers/gpu/drm/i915/intel_dsi_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_vbt.c @@ -29,9 +29,11 @@ #include <drm/drm_edid.h> #include <drm/i915_drm.h> #include <linux/gpio/consumer.h> +#include <linux/mfd/intel_soc_pmic.h> #include <linux/slab.h> #include <video/mipi_display.h> #include <asm/intel-mid.h> +#include <asm/unaligned.h> #include <video/mipi_display.h> #include "i915_drv.h" #include "intel_drv.h" @@ -371,7 +373,25 @@ static const u8 *mipi_exec_spi(struct intel_dsi *intel_dsi, const u8 *data) static const u8 *mipi_exec_pmic(struct intel_dsi *intel_dsi, const u8 *data) { - DRM_DEBUG_KMS("Skipping PMIC element execution\n"); +#ifdef CONFIG_PMIC_OPREGION + u32 value, mask, reg_address; + u16 i2c_address; + int ret; + + /* byte 0 aka PMIC Flag is reserved */ + i2c_address = get_unaligned_le16(data + 1); + reg_address = get_unaligned_le32(data + 3); + value = get_unaligned_le32(data + 7); + mask = get_unaligned_le32(data + 11); + + ret = intel_soc_pmic_exec_mipi_pmic_seq_element(i2c_address, + reg_address, + value, mask); + if (ret) + DRM_ERROR("%s failed, error: %d\n", __func__, ret); +#else + DRM_ERROR("Your hardware requires CONFIG_PMIC_OPREGION and it is not set\n"); +#endif return data + 15; } -- 2.19.2