/* SPDX-License-Identifier: GPL-2.0-only */

#include <device/mmio.h>
#include <console/console.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <drivers/intel/gma/edid.h>
#include <drivers/intel/gma/opregion.h>
#include <drivers/intel/gma/libgfxinit.h>
#include <string.h>
#include <device/pci_ops.h>
#include <commonlib/helpers.h>
#include <types.h>

#include "drivers/intel/gma/i915_reg.h"
#include "chip.h"
#include "gm45.h"

static struct resource *gtt_res = NULL;

u32 gtt_read(u32 reg)
{
	return read32(res2mmio(gtt_res, reg, 0));
}

void gtt_write(u32 reg, u32 data)
{
	write32(res2mmio(gtt_res, reg, 0), data);
}

static u32 get_cdclk(struct device *const dev)
{
	const u16 cdclk_sel = pci_read_config16(dev, GCFGC_OFFSET) & GCFGC_CD_MASK;

	switch (mchbar_read8(HPLLVCO_MCHBAR) & 0x7) {
	case VCO_2666:
	case VCO_4000:
	case VCO_5333:
		return cdclk_sel ? 333333333 : 222222222;
	case VCO_3200:
		return cdclk_sel ? 320000000 : 228571429;
	default:
		printk(BIOS_WARNING,
		       "Unknown VCO frequency, using default cdclk.\n");
		return 222222222;
	}
}

static u32 freq_to_blc_pwm_ctl(struct device *const dev,
			u16 pwm_freq, u8 duty_perc)
{
	u32 blc_mod;

	blc_mod = get_cdclk(dev) / (128 * pwm_freq);

	if (duty_perc <= 100)
		return (blc_mod << 16) | (blc_mod * duty_perc / 100);
	else
		return (blc_mod << 16) | blc_mod;
}

u16 get_blc_pwm_freq_value(const char *edid_ascii_string)
{
	static u16 blc_pwm_freq;
	const struct blc_pwm_t *blc_pwm;
	int i;
	int blc_array_len;

	/* Prevent null-deref on strcmp() below */
	if (blc_pwm_freq > 0 || !edid_ascii_string)
		return blc_pwm_freq;

	blc_array_len = get_blc_values(&blc_pwm);
	/* Find EDID string and pwm freq in lookup table */
	for (i = 0; i < blc_array_len; i++) {
		if (!strcmp(blc_pwm[i].ascii_string, edid_ascii_string)) {
			blc_pwm_freq = blc_pwm[i].pwm_freq;
			printk(BIOS_DEBUG, "Found EDID string: %s in lookup table, pwm: %dHz\n",
			       blc_pwm[i].ascii_string, blc_pwm_freq);
			break;
		}
	}

	if (i == blc_array_len)
		printk(BIOS_NOTICE, "Your panels EDID `%s` wasn't found in the"
		       "lookup table.\n You may have issues with your panels"
		       "backlight.\n If you want to help improving coreboot"
		       "please report: this EDID string\n and the result"
		       "of `intel_read read BLC_PWM_CTL`"
		       "(from intel-gpu-tools)\n while running vendor BIOS\n",
		       edid_ascii_string);

	return blc_pwm_freq;
}

static void gma_pm_init_post_vbios(struct device *const dev,
				const char *edid_ascii_string)
{
	const struct northbridge_intel_gm45_config *const conf = dev->chip_info;

	u32 reg32;
	u8 reg8;
	u16 pwm_freq;

	/* Setup Panel Power On Delays */
	reg32 = gtt_read(PP_ON_DELAYS);
	if (!reg32) {
		reg32 = (conf->gpu_panel_power_up_delay & 0x1fff) << 16;
		reg32 |= (conf->gpu_panel_power_backlight_on_delay & 0x1fff);
		gtt_write(PP_ON_DELAYS, reg32);
	}

	/* Setup Panel Power Off Delays */
	reg32 = gtt_read(PP_OFF_DELAYS);
	if (!reg32) {
		reg32 = (conf->gpu_panel_power_down_delay & 0x1fff) << 16;
		reg32 |= (conf->gpu_panel_power_backlight_off_delay & 0x1fff);
		gtt_write(PP_OFF_DELAYS, reg32);
	}

	/* Setup Panel Power Cycle Delay */
	if (conf->gpu_panel_power_cycle_delay) {
		reg32 = (get_cdclk(dev) / 20000 - 1)
			<< PP_REFERENCE_DIVIDER_SHIFT;
		reg32 |= conf->gpu_panel_power_cycle_delay & 0x1f;
		gtt_write(PP_DIVISOR, reg32);
	}

	/* Enable Backlight  */
	gtt_write(BLC_PWM_CTL2, (1 << 31));
	reg8 = 100;
	if (conf->duty_cycle != 0)
		reg8 = conf->duty_cycle;
	pwm_freq = get_blc_pwm_freq_value(edid_ascii_string);
	if (pwm_freq == 0 && conf->default_pwm_freq != 0)
		pwm_freq = conf->default_pwm_freq;

	if (pwm_freq == 0)
		gtt_write(BLC_PWM_CTL, 0x06100610);
	else
		gtt_write(BLC_PWM_CTL, freq_to_blc_pwm_ctl(dev, pwm_freq,
								reg8));
}

const char *gm45_get_lvds_edid_str(void)
{
	u8 *mmio;
	u8 edid_data_lvds[128];
	struct edid edid_lvds;
	static char edid_str[EDID_ASCII_STRING_LENGTH + 1];

	if (edid_str[0])
		return edid_str;
	if (!gtt_res) {
		printk(BIOS_ERR, "Never call %s() outside dev.init() context.\n", __func__);
		return NULL;
	}
	mmio = res2mmio(gtt_res, 0, 0);

	printk(BIOS_DEBUG, "LVDS EDID\n");
	intel_gmbus_read_edid(mmio + GMBUS0, GMBUS_PORT_PANEL, 0x50,
			edid_data_lvds, sizeof(edid_data_lvds));
	intel_gmbus_stop(mmio + GMBUS0);

	if (decode_edid(edid_data_lvds, sizeof(edid_data_lvds), &edid_lvds)
	    != EDID_CONFORMANT)
		return NULL;
	memcpy(edid_str, edid_lvds.ascii_string, sizeof(edid_str));
	return edid_str;
}

static void gma_func0_init(struct device *dev)
{
	u8 *mmio;
	const struct northbridge_intel_gm45_config *const conf = dev->chip_info;
	const char *edid_str;

	/* Probe MMIO resource first. It's needed even for
	   intel_gma_init_igd_opregion() which may call back. */
	gtt_res = probe_resource(dev, PCI_BASE_ADDRESS_0);
	if (!gtt_res)
		return;

	intel_gma_init_igd_opregion();

	edid_str = gm45_get_lvds_edid_str();
	if (!edid_str)
		printk(BIOS_ERR, "Failed to obtain LVDS EDID string!\n");

	mmio = res2mmio(gtt_res, 0, 0);

	/*
	 * GTT base is at a 2M offset and is 2M big. If GTT is smaller than 2M
	 * cycles are simply not decoded which is fine.
	 */
	pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER);
	memset(mmio + 2 * MiB, 0, 2 * MiB);

	if (CONFIG(NO_GFX_INIT))
		pci_and_config16(dev, PCI_COMMAND, ~PCI_COMMAND_MASTER);

	if (!CONFIG(MAINBOARD_USE_LIBGFXINIT)) {
		/* PCI Init, will run VBIOS */
		printk(BIOS_DEBUG, "Initialising IGD using VBIOS\n");
		pci_dev_init(dev);
	}

	/* Post VBIOS init */
	gma_pm_init_post_vbios(dev, edid_str);

	if (CONFIG(MAINBOARD_USE_LIBGFXINIT) && !acpi_is_wakeup_s3()) {
		int vga_disable = (pci_read_config16(dev, D0F0_GGC) & 2) >> 1;
		if (vga_disable) {
			printk(BIOS_INFO,
			       "IGD is not decoding legacy VGA MEM and IO: skipping NATIVE graphic init\n");
		} else {
			int lightup_ok;
			gma_gfxinit(&lightup_ok);
			/* Linux relies on VBT for panel info. */
			generate_fake_intel_oprom(&conf->gfx, dev, "$VBT CANTIGA");
		}
	}
}

static void gma_generate_ssdt(const struct device *device)
{
	const struct northbridge_intel_gm45_config *chip = device->chip_info;

	drivers_intel_gma_displays_ssdt_generate(&chip->gfx);
}

static const char *gma_acpi_name(const struct device *dev)
{
	return "GFX0";
}

static struct device_operations gma_func0_ops = {
	.read_resources		= pci_dev_read_resources,
	.set_resources		= pci_dev_set_resources,
	.enable_resources	= pci_dev_enable_resources,
	.acpi_fill_ssdt		= gma_generate_ssdt,
	.init			= gma_func0_init,
	.ops_pci		= &pci_dev_ops_pci,
	.acpi_name		= gma_acpi_name,
};

static const unsigned short pci_device_ids[] =
{
	0x2a42, 0
};

static const struct pci_driver gma __pci_driver = {
	.ops = &gma_func0_ops,
	.vendor = PCI_VID_INTEL,
	.devices = pci_device_ids,
};
