Commit d962f0af authored by Radhakrishna Sripada's avatar Radhakrishna Sripada Committed by Jani Nikula
Browse files

drm/i915: Move vbt read from firmware to intel_bios.c



VBT read from firmware is currently nested within opregion vbt read.
Extract it and place it together with other vbt read mechanisms and
dis-associate vbt-firmware from opregion structure.

v2: Return NULL in failure cases and use a null check in
    intel_bios_init(Jani)

Cc: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: default avatarRadhakrishna Sripada <radhakrishna.sripada@intel.com>
Reviewed-by: default avatarJani Nikula <jani.nikula@intel.com>
Signed-off-by: default avatarJani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240228213235.2495611-4-radhakrishna.sripada@intel.com
parent 8612f91e
Loading
Loading
Loading
Loading
+44 −1
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@
 *
 */

#include <linux/firmware.h>

#include <drm/display/drm_dp_helper.h>
#include <drm/display/drm_dsc_helper.h>
#include <drm/drm_edid.h>
@@ -3000,6 +3002,43 @@ bool intel_bios_is_valid_vbt(struct drm_i915_private *i915,
	return vbt;
}

static struct vbt_header *firmware_get_vbt(struct drm_i915_private *i915,
					   size_t *size)
{
	struct vbt_header *vbt = NULL;
	const struct firmware *fw = NULL;
	const char *name = i915->display.params.vbt_firmware;
	int ret;

	if (!name || !*name)
		return NULL;

	ret = request_firmware(&fw, name, i915->drm.dev);
	if (ret) {
		drm_err(&i915->drm,
			"Requesting VBT firmware \"%s\" failed (%d)\n",
			name, ret);
		return NULL;
	}

	if (intel_bios_is_valid_vbt(i915, fw->data, fw->size)) {
		vbt = kmemdup(fw->data, fw->size, GFP_KERNEL);
		if (vbt) {
			drm_dbg_kms(&i915->drm,
				    "Found valid VBT firmware \"%s\"\n", name);
			if (size)
				*size = fw->size;
		}
	} else {
		drm_dbg_kms(&i915->drm, "Invalid VBT firmware \"%s\"\n",
			    name);
	}

	release_firmware(fw);

	return vbt;
}

static u32 intel_spi_read(struct intel_uncore *uncore, u32 offset)
{
	intel_uncore_write(uncore, PRIMARY_SPI_ADDRESS, offset);
@@ -3152,6 +3191,10 @@ void intel_bios_init(struct drm_i915_private *i915)

	init_vbt_defaults(i915);

	oprom_vbt = firmware_get_vbt(i915, NULL);
	vbt = oprom_vbt;

	if (!vbt)
		vbt = intel_opregion_get_vbt(i915, NULL);

	/*
+0 −46
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@

#include <linux/acpi.h>
#include <linux/dmi.h>
#include <linux/firmware.h>
#include <acpi/video.h>

#include <drm/drm_edid.h>
@@ -263,7 +262,6 @@ struct intel_opregion {
	struct opregion_asle *asle;
	struct opregion_asle_ext *asle_ext;
	void *rvda;
	void *vbt_firmware;
	const void *vbt;
	u32 vbt_size;
	struct work_struct asle_work;
@@ -869,46 +867,6 @@ static const struct dmi_system_id intel_no_opregion_vbt[] = {
	{ }
};

static int intel_load_vbt_firmware(struct drm_i915_private *dev_priv)
{
	struct intel_opregion *opregion = dev_priv->display.opregion;
	const struct firmware *fw = NULL;
	const char *name = dev_priv->display.params.vbt_firmware;
	int ret;

	if (!name || !*name)
		return -ENOENT;

	ret = request_firmware(&fw, name, dev_priv->drm.dev);
	if (ret) {
		drm_err(&dev_priv->drm,
			"Requesting VBT firmware \"%s\" failed (%d)\n",
			name, ret);
		return ret;
	}

	if (intel_bios_is_valid_vbt(dev_priv, fw->data, fw->size)) {
		opregion->vbt_firmware = kmemdup(fw->data, fw->size, GFP_KERNEL);
		if (opregion->vbt_firmware) {
			drm_dbg_kms(&dev_priv->drm,
				    "Found valid VBT firmware \"%s\"\n", name);
			opregion->vbt = opregion->vbt_firmware;
			opregion->vbt_size = fw->size;
			ret = 0;
		} else {
			ret = -ENOMEM;
		}
	} else {
		drm_dbg_kms(&dev_priv->drm, "Invalid VBT firmware \"%s\"\n",
			    name);
		ret = -EINVAL;
	}

	release_firmware(fw);

	return ret;
}

int intel_opregion_setup(struct drm_i915_private *dev_priv)
{
	struct intel_opregion *opregion;
@@ -1006,9 +964,6 @@ int intel_opregion_setup(struct drm_i915_private *dev_priv)
		drm_dbg(&dev_priv->drm, "Mailbox #2 for backlight present\n");
	}

	if (intel_load_vbt_firmware(dev_priv) == 0)
		goto out;

	if (dmi_check_system(intel_no_opregion_vbt))
		goto out;

@@ -1312,7 +1267,6 @@ void intel_opregion_cleanup(struct drm_i915_private *i915)
	memunmap(opregion->header);
	if (opregion->rvda)
		memunmap(opregion->rvda);
	kfree(opregion->vbt_firmware);
	kfree(opregion);
	i915->display.opregion = NULL;
}