/* 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 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 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(void)
{
	static u16 blc_pwm_freq;
	const struct blc_pwm_t *blc_pwm;
	int i;
	int blc_array_len;

	if (blc_pwm_freq > 0)
		return blc_pwm_freq;

	const char *const edid_ascii_string = gm45_get_lvds_edid_str();
	if (!edid_ascii_string) {
		printk(BIOS_ERR, "Need LVDS EDID string to derive backlight PWM frequency!\n");
		return 0;
	}

	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 panel's EDID `%s` wasn't found in the lookup table.\n"
		       "You may have issues with your panel's backlight.\n"
		       "If you want to help improving coreboot please report: this EDID string\n"
		       "and the result of `intel_reg 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 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();
	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));
}

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

	/* 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();

	/*
	 * 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(res2mmio(gtt_res, 2*MiB, 0), 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);

	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,
};
