From 66ef768fce7c41fd784b622b92c07f201982a678 Mon Sep 17 00:00:00 2001
From: Eric Schikschneit <eric.schikschneit@novatechautomation.com>
Date: Thu, 21 Sep 2023 16:11:23 -0500
Subject: [PATCH] WIP: Add Intel GMBUS support

This will allow uboot to communicate over the GMBUS to an attached
monitor to gather EDID information in order to properly setup video
during the boot process.

This is being tested as it is being developed on an Intel Bayrail SOC.

Signed-off-by: Eric Schikschneit <eric.schikschneit@novatechautomation.com>
---
 drivers/video/Kconfig         |  5 +++
 drivers/video/Makefile        |  1 +
 drivers/video/intel_gmbus.c   | 77 +++++++++++++++++++++++++++++++++++
 drivers/video/psb_intel_reg.h | 55 +++++++++++++++++++++++++
 4 files changed, 138 insertions(+)
 create mode 100644 drivers/video/intel_gmbus.c
 create mode 100644 drivers/video/psb_intel_reg.h

diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index ed0b21f2a7..7bc433d9af 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -683,4 +683,9 @@ config VIDEO_DT_SIMPLEFB
 	  The video output is initialized by U-Boot, and kept by the
 	  kernel.
 
+config VIDEO_INTEL_BAYTRAIL
+	bool "Enable GMBUS support for Intel Baytrail SOCs"
+	help
+	  Enables support for interfacing with monitors to gather EDID
+	  information to aid video bringup.
 endmenu
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 0f41a23193..4ff710e41a 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -56,6 +56,7 @@ obj-$(CONFIG_VIDEO_SIMPLE) += simplefb.o
 obj-$(CONFIG_VIDEO_TEGRA20) += tegra.o
 obj-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o
 obj-$(CONFIG_VIDEO_VESA) += vesa.o
+obj-$(CONFIG_VIDEO_INTEL_BAYTRAIL) += intel_gmbus.o
 
 obj-y += bridge/
 obj-y += sunxi/
diff --git a/drivers/video/intel_gmbus.c b/drivers/video/intel_gmbus.c
new file mode 100644
index 0000000000..e23e8030f2
--- /dev/null
+++ b/drivers/video/intel_gmbus.c
@@ -0,0 +1,77 @@
+/* This file is loosly based off of the file found in the linux kernel,
+ * modified for use with u-boot.
+ * File in kernel: drivers/gpu/drm/gma500/intel_gmbus.c
+ * 
+ * Authors:
+ * Eric Schikschneit <eric.schikschneit@novatechautomation.com
+ */
+
+#include <common.h>
+
+#include "psb_intel_reg.h"
+
+// struct intel_gpio {
+// 	struct i2c_adapter adapter;
+// 	struct i2c_algo_bit_data algo;
+// 	struct drm_psb_private *dev_priv;
+// 	u32 reg;
+// };
+
+#define GMBUS_REG_READ(reg) ioread32(dev_priv->gmbus_reg + (reg))
+#define GMBUS_REG_WRITE(reg, val) iowrite32((val), dev_priv->gmbus_reg + (reg))
+
+void intel_gmbus_i2c_reset() {
+}
+
+static void intel_gmbus_i2c_quirk_set() {
+}
+
+static u32 intel_gmbus_get_reserved() {
+    return 0;
+}
+
+static void intel_gmbus_set_clock (void *data, int state_high) {
+}
+
+static int intel_gmbus_get_clock(void *data) {
+    return 0;
+}
+
+static void intel_gmbus_set_data(void *data, int state_high) {
+}
+
+static int intel_gmbus_get_data(void *data) {
+    return 0;
+}
+
+static struct i2c_adapter * intel_gmbus_gpio_create() { // Use u-boot compatible struct
+    return;
+}
+
+static int intel_gmbus_i2c_quirk_xfer() {
+    return 0;
+}
+
+static int intel_gmbus_xfer() {
+    return 0;
+}
+
+static u32 intel_gmbus_func() {
+    return 0;
+}
+
+void intel_gmbus_setup() {
+}
+
+void intel_gmbus_set_speed(struct pci_dev_t *dev) {
+}
+
+void intel_gmbus_get_speed(struct pci_dev_t *dev) {
+}
+
+void intel_gmbus_force_bit() {
+}
+
+void intel_gmbus_teardown() {
+}
+
diff --git a/drivers/video/psb_intel_reg.h b/drivers/video/psb_intel_reg.h
new file mode 100644
index 0000000000..51ba722177
--- /dev/null
+++ b/drivers/video/psb_intel_reg.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2009, Intel Corporation.
+ * Modified for uboot by Eric Schikschneit (eric.schikschneit@novatechautomation.com)
+ */
+#ifndef __PSB_INTEL_REG_H__
+#define __PSB_INTEL_REG_H__
+
+#define GMBUS0			0x5100 /* clock/port select */
+#define   GMBUS_RATE_100KHZ	(0<<8)
+#define   GMBUS_RATE_50KHZ	(1<<8)
+#define   GMBUS_RATE_400KHZ	(2<<8) /* reserved on Pineview */
+#define   GMBUS_RATE_1MHZ	(3<<8) /* reserved on Pineview */
+#define   GMBUS_HOLD_EXT	(1<<7) /* 300ns hold time, rsvd on Pineview */
+#define   GMBUS_PORT_DISABLED	0
+#define   GMBUS_PORT_SSC	1
+#define   GMBUS_PORT_VGADDC	2
+#define   GMBUS_PORT_PANEL	3
+#define   GMBUS_PORT_DPC	4 /* HDMIC */
+#define   GMBUS_PORT_DPB	5 /* SDVO, HDMIB */
+				  /* 6 reserved */
+#define   GMBUS_PORT_DPD	7 /* HDMID */
+#define   GMBUS_NUM_PORTS       8
+#define GMBUS1			0x5104 /* command/status */
+#define   GMBUS_SW_CLR_INT	(1<<31)
+#define   GMBUS_SW_RDY		(1<<30)
+#define   GMBUS_ENT		(1<<29) /* enable timeout */
+#define   GMBUS_CYCLE_NONE	(0<<25)
+#define   GMBUS_CYCLE_WAIT	(1<<25)
+#define   GMBUS_CYCLE_INDEX	(2<<25)
+#define   GMBUS_CYCLE_STOP	(4<<25)
+#define   GMBUS_BYTE_COUNT_SHIFT 16
+#define   GMBUS_SLAVE_INDEX_SHIFT 8
+#define   GMBUS_SLAVE_ADDR_SHIFT 1
+#define   GMBUS_SLAVE_READ	(1<<0)
+#define   GMBUS_SLAVE_WRITE	(0<<0)
+#define GMBUS2			0x5108 /* status */
+#define   GMBUS_INUSE		(1<<15)
+#define   GMBUS_HW_WAIT_PHASE	(1<<14)
+#define   GMBUS_STALL_TIMEOUT	(1<<13)
+#define   GMBUS_INT		(1<<12)
+#define   GMBUS_HW_RDY		(1<<11)
+#define   GMBUS_SATOER		(1<<10)
+#define   GMBUS_ACTIVE		(1<<9)
+#define GMBUS3			0x510c /* data buffer bytes 3-0 */
+#define GMBUS4			0x5110 /* interrupt mask (Pineview+) */
+#define   GMBUS_SLAVE_TIMEOUT_EN (1<<4)
+#define   GMBUS_NAK_EN		(1<<3)
+#define   GMBUS_IDLE_EN		(1<<2)
+#define   GMBUS_HW_WAIT_EN	(1<<1)
+#define   GMBUS_HW_RDY_EN	(1<<0)
+#define GMBUS5			0x5120 /* byte index */
+#define   GMBUS_2BYTE_INDEX_EN	(1<<31)
+
+#endif
\ No newline at end of file
-- 
2.34.1

