--- /dev/null
+/*
+ * drivers/video/tegra/dc/hdmi.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ * Author: Erik Gilling <konkers@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/nvhost_bus.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+
+#include <mach/clk.h>
+#include <mach/dc.h>
+#include <mach/fb.h>
+
+#include "dc_reg.h"
+#include "dc_priv.h"
+#include "hdmi_reg.h"
+#include "edid.h"
+
+struct tegra_dc_hdmi_data {
+ struct tegra_dc *dc;
+ struct tegra_edid *edid;
+ struct delayed_work work;
+
+ struct resource *base_res;
+ void __iomem *base;
+ struct clk *clk;
+};
+
+const struct fb_videomode tegra_dc_hdmi_supported_modes[] = {
+ /* 1280x720p 60hz: EIA/CEA-861-B Format 4 */
+ {
+ .xres = 1280,
+ .yres = 720,
+ .pixclock = KHZ2PICOS(74250),
+ .hsync_len = 40, /* h_sync_width */
+ .vsync_len = 5, /* v_sync_width */
+ .left_margin = 220, /* h_back_porch */
+ .upper_margin = 20, /* v_back_porch */
+ .right_margin = 110, /* h_front_porch */
+ .lower_margin = 5, /* v_front_porch */
+ .vmode = FB_VMODE_NONINTERLACED,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ },
+
+ /* 720x480p 59.94hz: EIA/CEA-861-B Formats 2 & 3 */
+ {
+ .xres = 720,
+ .yres = 480,
+ .pixclock = KHZ2PICOS(27000),
+ .hsync_len = 62, /* h_sync_width */
+ .vsync_len = 6, /* v_sync_width */
+ .left_margin = 60, /* h_back_porch */
+ .upper_margin = 30, /* v_back_porch */
+ .right_margin = 16, /* h_front_porch */
+ .lower_margin = 9, /* v_front_porch */
+ .vmode = FB_VMODE_NONINTERLACED,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ },
+
+ /* 640x480p 60hz: EIA/CEA-861-B Format 1 */
+ {
+ .xres = 640,
+ .yres = 480,
+ .pixclock = KHZ2PICOS(25200),
+ .hsync_len = 96, /* h_sync_width */
+ .vsync_len = 2, /* v_sync_width */
+ .left_margin = 48, /* h_back_porch */
+ .upper_margin = 33, /* v_back_porch */
+ .right_margin = 16, /* h_front_porch */
+ .lower_margin = 10, /* v_front_porch */
+ .vmode = FB_VMODE_NONINTERLACED,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ },
+
+ /* 720x576p 50hz EIA/CEA-861-B Formats 17 & 18 */
+ {
+ .xres = 720,
+ .yres = 576,
+ .pixclock = KHZ2PICOS(27000),
+ .hsync_len = 64, /* h_sync_width */
+ .vsync_len = 5, /* v_sync_width */
+ .left_margin = 68, /* h_back_porch */
+ .upper_margin = 39, /* v_back_porch */
+ .right_margin = 12, /* h_front_porch */
+ .lower_margin = 5, /* v_front_porch */
+ .vmode = FB_VMODE_NONINTERLACED,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ },
+
+ /* 1920x1080p 59.94/60hz EIA/CEA-861-B Format 16 */
+ {
+ .xres = 1920,
+ .yres = 1080,
+ .pixclock = KHZ2PICOS(148500),
+ .hsync_len = 44, /* h_sync_width */
+ .vsync_len = 5, /* v_sync_width */
+ .left_margin = 148, /* h_back_porch */
+ .upper_margin = 36, /* v_back_porch */
+ .right_margin = 88, /* h_front_porch */
+ .lower_margin = 4, /* v_front_porch */
+ .vmode = FB_VMODE_NONINTERLACED,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ },
+};
+
+static inline unsigned long tegra_hdmi_readl(struct tegra_dc_hdmi_data *hdmi,
+ unsigned long reg)
+{
+ return readl(hdmi->base + reg * 4);
+}
+
+static inline void tegra_hdmi_writel(struct tegra_dc_hdmi_data *hdmi,
+ unsigned long val, unsigned long reg)
+{
+ writel(val, hdmi->base + reg * 4);
+}
+
+static inline void tegra_hdmi_clrsetbits(struct tegra_dc_hdmi_data *hdmi,
+ unsigned long reg, unsigned long clr,
+ unsigned long set)
+{
+ unsigned long val = tegra_hdmi_readl(hdmi, reg);
+ val &= ~clr;
+ val |= set;
+ tegra_hdmi_writel(hdmi, val, reg);
+}
+
+#define DUMP_REG(a) do { \
+ printk("HDMI %-32s\t%03x\t%08lx\n", \
+ #a, a, tegra_hdmi_readl(hdmi, a)); \
+ } while (0)
+
+#ifdef DEBUG
+static void hdmi_dumpregs(struct tegra_dc_hdmi_data *hdmi)
+{
+ DUMP_REG(HDMI_CTXSW);
+ DUMP_REG(HDMI_NV_PDISP_SOR_STATE0);
+ DUMP_REG(HDMI_NV_PDISP_SOR_STATE1);
+ DUMP_REG(HDMI_NV_PDISP_SOR_STATE2);
+ DUMP_REG(HDMI_NV_PDISP_RG_HDCP_AN_MSB);
+ DUMP_REG(HDMI_NV_PDISP_RG_HDCP_AN_LSB);
+ DUMP_REG(HDMI_NV_PDISP_RG_HDCP_CN_MSB);
+ DUMP_REG(HDMI_NV_PDISP_RG_HDCP_CN_LSB);
+ DUMP_REG(HDMI_NV_PDISP_RG_HDCP_AKSV_MSB);
+ DUMP_REG(HDMI_NV_PDISP_RG_HDCP_AKSV_LSB);
+ DUMP_REG(HDMI_NV_PDISP_RG_HDCP_BKSV_MSB);
+ DUMP_REG(HDMI_NV_PDISP_RG_HDCP_BKSV_LSB);
+ DUMP_REG(HDMI_NV_PDISP_RG_HDCP_CKSV_MSB);
+ DUMP_REG(HDMI_NV_PDISP_RG_HDCP_CKSV_LSB);
+ DUMP_REG(HDMI_NV_PDISP_RG_HDCP_DKSV_MSB);
+ DUMP_REG(HDMI_NV_PDISP_RG_HDCP_DKSV_LSB);
+ DUMP_REG(HDMI_NV_PDISP_RG_HDCP_CTRL);
+ DUMP_REG(HDMI_NV_PDISP_RG_HDCP_CMODE);
+ DUMP_REG(HDMI_NV_PDISP_RG_HDCP_MPRIME_MSB);
+ DUMP_REG(HDMI_NV_PDISP_RG_HDCP_MPRIME_LSB);
+ DUMP_REG(HDMI_NV_PDISP_RG_HDCP_SPRIME_MSB);
+ DUMP_REG(HDMI_NV_PDISP_RG_HDCP_SPRIME_LSB2);
+ DUMP_REG(HDMI_NV_PDISP_RG_HDCP_SPRIME_LSB1);
+ DUMP_REG(HDMI_NV_PDISP_RG_HDCP_RI);
+ DUMP_REG(HDMI_NV_PDISP_RG_HDCP_CS_MSB);
+ DUMP_REG(HDMI_NV_PDISP_RG_HDCP_CS_LSB);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_AUDIO_EMU0);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_AUDIO_EMU_RDATA0);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_AUDIO_EMU1);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_AUDIO_EMU2);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_STATUS);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_HEADER);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_SUBPACK0_LOW);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_SUBPACK0_HIGH);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_CTRL);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_STATUS);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_HEADER);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK0_LOW);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK0_HIGH);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK1_LOW);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK1_HIGH);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_GENERIC_CTRL);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_GENERIC_STATUS);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_GENERIC_HEADER);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK0_LOW);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK0_HIGH);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK1_LOW);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK1_HIGH);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK2_LOW);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK2_HIGH);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK3_LOW);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK3_HIGH);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_CTRL);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_0320_SUBPACK_LOW);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_0320_SUBPACK_HIGH);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_0441_SUBPACK_LOW);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_0441_SUBPACK_HIGH);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_0882_SUBPACK_LOW);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_0882_SUBPACK_HIGH);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_1764_SUBPACK_LOW);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_1764_SUBPACK_HIGH);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_0480_SUBPACK_LOW);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_0480_SUBPACK_HIGH);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_0960_SUBPACK_LOW);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_0960_SUBPACK_HIGH);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_1920_SUBPACK_LOW);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_1920_SUBPACK_HIGH);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_CTRL);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_VSYNC_KEEPOUT);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_VSYNC_WINDOW);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_GCP_CTRL);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_GCP_STATUS);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_GCP_SUBPACK);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_CHANNEL_STATUS1);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_CHANNEL_STATUS2);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_EMU0);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_EMU1);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_EMU1_RDATA);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_SPARE);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_SPDIF_CHN_STATUS1);
+ DUMP_REG(HDMI_NV_PDISP_HDMI_SPDIF_CHN_STATUS2);
+ DUMP_REG(HDMI_NV_PDISP_HDCPRIF_ROM_CTRL);
+ DUMP_REG(HDMI_NV_PDISP_SOR_CAP);
+ DUMP_REG(HDMI_NV_PDISP_SOR_PWR);
+ DUMP_REG(HDMI_NV_PDISP_SOR_TEST);
+ DUMP_REG(HDMI_NV_PDISP_SOR_PLL0);
+ DUMP_REG(HDMI_NV_PDISP_SOR_PLL1);
+ DUMP_REG(HDMI_NV_PDISP_SOR_PLL2);
+ DUMP_REG(HDMI_NV_PDISP_SOR_CSTM);
+ DUMP_REG(HDMI_NV_PDISP_SOR_LVDS);
+ DUMP_REG(HDMI_NV_PDISP_SOR_CRCA);
+ DUMP_REG(HDMI_NV_PDISP_SOR_CRCB);
+ DUMP_REG(HDMI_NV_PDISP_SOR_BLANK);
+ DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_CTL);
+ DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST0);
+ DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST1);
+ DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST2);
+ DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST3);
+ DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST4);
+ DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST5);
+ DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST6);
+ DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST7);
+ DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST8);
+ DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST9);
+ DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INSTA);
+ DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INSTB);
+ DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INSTC);
+ DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INSTD);
+ DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INSTE);
+ DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INSTF);
+ DUMP_REG(HDMI_NV_PDISP_SOR_VCRCA0);
+ DUMP_REG(HDMI_NV_PDISP_SOR_VCRCA1);
+ DUMP_REG(HDMI_NV_PDISP_SOR_CCRCA0);
+ DUMP_REG(HDMI_NV_PDISP_SOR_CCRCA1);
+ DUMP_REG(HDMI_NV_PDISP_SOR_EDATAA0);
+ DUMP_REG(HDMI_NV_PDISP_SOR_EDATAA1);
+ DUMP_REG(HDMI_NV_PDISP_SOR_COUNTA0);
+ DUMP_REG(HDMI_NV_PDISP_SOR_COUNTA1);
+ DUMP_REG(HDMI_NV_PDISP_SOR_DEBUGA0);
+ DUMP_REG(HDMI_NV_PDISP_SOR_DEBUGA1);
+ DUMP_REG(HDMI_NV_PDISP_SOR_TRIG);
+ DUMP_REG(HDMI_NV_PDISP_SOR_MSCHECK);
+ DUMP_REG(HDMI_NV_PDISP_SOR_LANE_DRIVE_CURRENT);
+ DUMP_REG(HDMI_NV_PDISP_AUDIO_DEBUG0);
+ DUMP_REG(HDMI_NV_PDISP_AUDIO_DEBUG1);
+ DUMP_REG(HDMI_NV_PDISP_AUDIO_DEBUG2);
+ DUMP_REG(HDMI_NV_PDISP_AUDIO_FS1);
+ DUMP_REG(HDMI_NV_PDISP_AUDIO_FS2);
+ DUMP_REG(HDMI_NV_PDISP_AUDIO_FS3);
+ DUMP_REG(HDMI_NV_PDISP_AUDIO_FS4);
+ DUMP_REG(HDMI_NV_PDISP_AUDIO_FS5);
+ DUMP_REG(HDMI_NV_PDISP_AUDIO_FS6);
+ DUMP_REG(HDMI_NV_PDISP_AUDIO_FS7);
+ DUMP_REG(HDMI_NV_PDISP_AUDIO_PULSE_WIDTH);
+ DUMP_REG(HDMI_NV_PDISP_AUDIO_THRESHOLD);
+ DUMP_REG(HDMI_NV_PDISP_AUDIO_CNTRL0);
+ DUMP_REG(HDMI_NV_PDISP_AUDIO_N);
+ DUMP_REG(HDMI_NV_PDISP_HDCPRIF_ROM_TIMING);
+ DUMP_REG(HDMI_NV_PDISP_SOR_REFCLK);
+ DUMP_REG(HDMI_NV_PDISP_CRC_CONTROL);
+ DUMP_REG(HDMI_NV_PDISP_INPUT_CONTROL);
+ DUMP_REG(HDMI_NV_PDISP_SCRATCH);
+ DUMP_REG(HDMI_NV_PDISP_PE_CURRENT);
+ DUMP_REG(HDMI_NV_PDISP_KEY_CTRL);
+ DUMP_REG(HDMI_NV_PDISP_KEY_DEBUG0);
+ DUMP_REG(HDMI_NV_PDISP_KEY_DEBUG1);
+ DUMP_REG(HDMI_NV_PDISP_KEY_DEBUG2);
+ DUMP_REG(HDMI_NV_PDISP_KEY_HDCP_KEY_0);
+ DUMP_REG(HDMI_NV_PDISP_KEY_HDCP_KEY_1);
+ DUMP_REG(HDMI_NV_PDISP_KEY_HDCP_KEY_2);
+ DUMP_REG(HDMI_NV_PDISP_KEY_HDCP_KEY_3);
+ DUMP_REG(HDMI_NV_PDISP_KEY_HDCP_KEY_TRIG);
+ DUMP_REG(HDMI_NV_PDISP_KEY_SKEY_INDEX);
+}
+#endif
+
+#define PIXCLOCK_TOLERANCE 200
+
+static bool tegra_dc_hdmi_mode_equal(const struct fb_videomode *mode1,
+ const struct fb_videomode *mode2)
+{
+ int diff = (s64)mode1->pixclock - (s64)mode2->pixclock;
+
+ return mode1->xres == mode2->xres &&
+ mode1->yres == mode2->yres &&
+ diff < PIXCLOCK_TOLERANCE &&
+ diff > -PIXCLOCK_TOLERANCE &&
+ mode1->vmode == mode2->vmode;
+}
+
+static bool tegra_dc_hdmi_mode_filter(struct fb_videomode *mode)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(tegra_dc_hdmi_supported_modes); i++) {
+ if (tegra_dc_hdmi_mode_equal(&tegra_dc_hdmi_supported_modes[i],
+ mode))
+ return true;
+ }
+
+ return false;
+}
+
+
+static bool tegra_dc_hdmi_hpd(struct tegra_dc *dc)
+{
+ int sense;
+ int level;
+
+ level = gpio_get_value(dc->out->hotplug_gpio);
+
+ sense = dc->out->flags & TEGRA_DC_OUT_HOTPLUG_MASK;
+
+ return (sense == TEGRA_DC_OUT_HOTPLUG_HIGH && level) ||
+ (sense == TEGRA_DC_OUT_HOTPLUG_LOW && !level);
+}
+
+static bool tegra_dc_hdmi_detect(struct tegra_dc *dc)
+{
+ struct tegra_dc_hdmi_data *hdmi = tegra_dc_get_outdata(dc);
+ struct fb_monspecs specs;
+ int err;
+
+ if (!tegra_dc_hdmi_hpd(dc))
+ return false;
+
+ err = tegra_edid_get_monspecs(hdmi->edid, &specs);
+ if (err < 0) {
+ dev_err(&dc->ndev->dev, "error reading edid\n");
+ return false;
+ }
+
+ tegra_fb_update_monspecs(dc->fb, &specs, tegra_dc_hdmi_mode_filter);
+ dev_info(&dc->ndev->dev, "display detected\n");
+ return true;
+}
+
+
+static void tegra_dc_hdmi_detect_worker(struct work_struct *work)
+{
+ struct tegra_dc_hdmi_data *hdmi =
+ container_of(to_delayed_work(work), struct tegra_dc_hdmi_data, work);
+ struct tegra_dc *dc = hdmi->dc;
+
+ if (tegra_dc_hdmi_hpd(dc))
+ tegra_dc_hdmi_detect(dc);
+}
+
+static irqreturn_t tegra_dc_hdmi_irq(int irq, void *ptr)
+{
+ struct tegra_dc *dc = ptr;
+ struct tegra_dc_hdmi_data *hdmi = tegra_dc_get_outdata(dc);
+
+ if (tegra_dc_hdmi_hpd(dc))
+ schedule_delayed_work(&hdmi->work, msecs_to_jiffies(2000));
+
+ return IRQ_HANDLED;
+}
+
+static int tegra_dc_hdmi_init(struct tegra_dc *dc)
+{
+ struct tegra_dc_hdmi_data *hdmi;
+ struct resource *res;
+ struct resource *base_res;
+ void __iomem *base;
+ struct clk *clk;
+ int err;
+
+ hdmi = kzalloc(sizeof(*hdmi), GFP_KERNEL);
+ if (!hdmi)
+ return -ENOMEM;
+
+ res = nvhost_get_resource_byname(dc->ndev, IORESOURCE_MEM, "hdmi_regs");
+ if (!res) {
+ dev_err(&dc->ndev->dev, "hdmi: no mem resource\n");
+ err = -ENOENT;
+ goto err_free_hdmi;
+ }
+
+ base_res = request_mem_region(res->start, resource_size(res), dc->ndev->name);
+ if (!base_res) {
+ dev_err(&dc->ndev->dev, "hdmi: request_mem_region failed\n");
+ err = -EBUSY;
+ goto err_free_hdmi;
+ }
+
+ base = ioremap(res->start, resource_size(res));
+ if (!base) {
+ dev_err(&dc->ndev->dev, "hdmi: registers can't be mapped\n");
+ err = -EBUSY;
+ goto err_release_resource_reg;
+ }
+
+ clk = clk_get(&dc->ndev->dev, "hdmi");
+ if (IS_ERR_OR_NULL(clk)) {
+ dev_err(&dc->ndev->dev, "hdmi: can't get clock\n");
+ err = -ENOENT;
+ goto err_iounmap_reg;
+ }
+
+ /* TODO: support non-hotplug */
+ if (request_irq(gpio_to_irq(dc->out->hotplug_gpio), tegra_dc_hdmi_irq,
+ IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ dev_name(&dc->ndev->dev), dc)) {
+ dev_err(&dc->ndev->dev, "hdmi: request_irq %d failed\n",
+ gpio_to_irq(dc->out->hotplug_gpio));
+ err = -EBUSY;
+ goto err_put_clock;
+ }
+
+ hdmi->edid = tegra_edid_create(dc->out->dcc_bus);
+ if (IS_ERR_OR_NULL(hdmi->edid)) {
+ dev_err(&dc->ndev->dev, "hdmi: can't create edid\n");
+ err = PTR_ERR(hdmi->edid);
+ goto err_free_irq;
+ }
+
+ INIT_DELAYED_WORK(&hdmi->work, tegra_dc_hdmi_detect_worker);
+
+ hdmi->dc = dc;
+ hdmi->base = base;
+ hdmi->base_res = base_res;
+ hdmi->clk = clk;
+
+ tegra_dc_set_outdata(dc, hdmi);
+
+ return 0;
+
+err_free_irq:
+ free_irq(gpio_to_irq(dc->out->hotplug_gpio), dc);
+err_put_clock:
+ clk_put(clk);
+err_iounmap_reg:
+ iounmap(base);
+err_release_resource_reg:
+ release_resource(base_res);
+err_free_hdmi:
+ kfree(hdmi);
+ return err;
+}
+
+static void tegra_dc_hdmi_destroy(struct tegra_dc *dc)
+{
+ struct tegra_dc_hdmi_data *hdmi = tegra_dc_get_outdata(dc);
+
+ free_irq(gpio_to_irq(dc->out->hotplug_gpio), dc);
+ cancel_delayed_work_sync(&hdmi->work);
+ iounmap(hdmi->base);
+ release_resource(hdmi->base_res);
+ clk_put(hdmi->clk);
+ tegra_edid_destroy(hdmi->edid);
+
+ kfree(hdmi);
+
+}
+
+static void tegra_dc_hdmi_enable(struct tegra_dc *dc)
+{
+ struct tegra_dc_hdmi_data *hdmi = tegra_dc_get_outdata(dc);
+ int pulse_start;
+ int dispclk_div_8_2;
+ int pll0;
+ int pll1;
+ int ds;
+ int retries;
+ unsigned long val;
+
+ /* enbale power, clocks, resets, etc. */
+ tegra_dc_setup_clk(dc, hdmi->clk);
+ clk_set_rate(hdmi->clk, dc->mode.pclk);
+
+ clk_enable(hdmi->clk);
+ tegra_periph_reset_assert(hdmi->clk);
+ mdelay(1);
+ tegra_periph_reset_deassert(hdmi->clk);
+
+ /* TODO: copy HDCP keys from KFUSE to HDMI */
+
+ /* Program display timing registers: handled by dc */
+
+ /* program HDMI registers and SOR sequencer */
+
+ tegra_dc_writel(dc, VSYNC_H_POSITION(1), DC_DISP_DISP_TIMING_OPTIONS);
+ tegra_dc_writel(dc, DITHER_CONTROL_DISABLE | BASE_COLOR_SIZE888,
+ DC_DISP_DISP_COLOR_CONTROL);
+
+ /* video_preamble uses h_pulse2 */
+ pulse_start = dc->mode.h_ref_to_sync + dc->mode.h_sync_width +
+ dc->mode.h_back_porch - 10;
+ tegra_dc_writel(dc, H_PULSE_2_ENABLE, DC_DISP_DISP_SIGNAL_OPTIONS0);
+ tegra_dc_writel(dc,
+ PULSE_MODE_NORMAL |
+ PULSE_POLARITY_HIGH |
+ PULSE_QUAL_VACTIVE |
+ PULSE_LAST_END_A,
+ DC_DISP_H_PULSE2_CONTROL);
+ tegra_dc_writel(dc, PULSE_START(pulse_start) | PULSE_END(pulse_start + 8),
+ DC_DISP_H_PULSE2_POSITION_A);
+
+ tegra_hdmi_writel(hdmi,
+ VSYNC_WINDOW_END(0x210) |
+ VSYNC_WINDOW_START(0x200) |
+ VSYNC_WINDOW_ENABLE,
+ HDMI_NV_PDISP_HDMI_VSYNC_WINDOW);
+
+ /* TODO: scale output to 16-235 */
+
+ tegra_hdmi_writel(hdmi,
+ (dc->ndev->id ? HDMI_SRC_DISPLAYB : HDMI_SRC_DISPLAYA) |
+ ARM_VIDEO_RANGE_LIMITED,
+ HDMI_NV_PDISP_INPUT_CONTROL);
+
+ dispclk_div_8_2 = clk_get_rate(hdmi->clk) / 1000000 * 4;
+ tegra_hdmi_writel(hdmi,
+ SOR_REFCLK_DIV_INT(dispclk_div_8_2 >> 2) |
+ SOR_REFCLK_DIV_FRAC(dispclk_div_8_2),
+ HDMI_NV_PDISP_SOR_REFCLK);
+
+ /* TODO: setup audio */
+
+ /* values from harmony board. Will be replaced when
+ * audio and avi are supported */
+ tegra_hdmi_writel(hdmi, 0x00000001, 0x1e);
+ tegra_hdmi_writel(hdmi, 0x00000000, 0x20);
+ tegra_hdmi_writel(hdmi, 0x000000aa, 0x21);
+ tegra_hdmi_writel(hdmi, 0x00000001, 0x23);
+ tegra_hdmi_writel(hdmi, 0x00000001, 0x24);
+ tegra_hdmi_writel(hdmi, 0x00000000, 0x25);
+ tegra_hdmi_writel(hdmi, 0x000445eb, 0x26);
+ tegra_hdmi_writel(hdmi, 0x00000004, 0x27);
+ tegra_hdmi_writel(hdmi, 0x00002710, 0x2a);
+ tegra_hdmi_writel(hdmi, 0x00000000, 0x35);
+ tegra_hdmi_writel(hdmi, 0x0015bc10, 0x38);
+ tegra_hdmi_writel(hdmi, 0x04c4bb58, 0x39);
+ tegra_hdmi_writel(hdmi, 0x0263b9b6, 0x44);
+ tegra_hdmi_writel(hdmi, 0x00002713, 0x4f);
+ tegra_hdmi_writel(hdmi, 0x01e85426, 0x57);
+ tegra_hdmi_writel(hdmi, 0x001136c2, 0x89);
+ tegra_hdmi_writel(hdmi, 0x00000730, 0x8a);
+ tegra_hdmi_writel(hdmi, 0x0001875b, 0x8c);
+ tegra_hdmi_writel(hdmi, 0x00000000, 0x9d);
+
+ tegra_hdmi_writel(hdmi, 0x40090038, HDMI_NV_PDISP_HDMI_CTRL);
+ tegra_hdmi_writel(hdmi, 0x0, HDMI_NV_PDISP_HDMI_GENERIC_CTRL);
+
+ /* TMDS CONFIG */
+ pll0 = 0x200033f;
+ pll1 = 0;
+
+ pll0 &= ~SOR_PLL_PWR & ~SOR_PLL_VCOPD & ~SOR_PLL_PDBG & ~SOR_PLL_PDPORT & ~SOR_PLL_PULLDOWN &
+ ~SOR_PLL_VCOCAP(~0) & ~SOR_PLL_ICHPMP(~0);
+ pll0 |= SOR_PLL_RESISTORSEL;
+
+ if (dc->mode.pclk <= 27000000)
+ pll0 |= SOR_PLL_VCOCAP(0);
+ else if (dc->mode.pclk <= 74250000)
+ pll0 |= SOR_PLL_VCOCAP(1);
+ else
+ pll0 |= SOR_PLL_VCOCAP(3);
+
+ if (dc->mode.h_active == 1080) {
+ pll0 |= SOR_PLL_ICHPMP(1) | SOR_PLL_TX_REG_LOAD(3) |
+ SOR_PLL_TX_REG_LOAD(3) | SOR_PLL_BG_V17_S(3);
+ pll1 |= SOR_PLL_TMDS_TERM_ENABLE | SOR_PLL_PE_EN;
+ } else {
+ pll0 |= SOR_PLL_ICHPMP(2);
+ }
+
+ tegra_hdmi_writel(hdmi, pll0, HDMI_NV_PDISP_SOR_PLL0);
+ tegra_hdmi_writel(hdmi, pll1, HDMI_NV_PDISP_SOR_PLL1);
+
+ if (pll1 & SOR_PLL_PE_EN) {
+ tegra_hdmi_writel(hdmi,
+ PE_CURRENT0(0xf) |
+ PE_CURRENT1(0xf) |
+ PE_CURRENT2(0xf) |
+ PE_CURRENT3(0xf),
+ HDMI_NV_PDISP_PE_CURRENT);
+ }
+
+ /* enable SOR */
+ if (dc->mode.h_active == 1080)
+ ds = DRIVE_CURRENT_13_500_mA;
+ else
+ ds = DRIVE_CURRENT_5_250_mA;
+
+ tegra_hdmi_writel(hdmi,
+ DRIVE_CURRENT_LANE0(ds) |
+ DRIVE_CURRENT_LANE1(ds) |
+ DRIVE_CURRENT_LANE2(ds) |
+ DRIVE_CURRENT_LANE3(ds) |
+ DRIVE_CURRENT_FUSE_OVERRIDE,
+ HDMI_NV_PDISP_SOR_LANE_DRIVE_CURRENT);
+
+ tegra_hdmi_writel(hdmi,
+ SOR_SEQ_CTL_PU_PC(0) |
+ SOR_SEQ_PU_PC_ALT(0) |
+ SOR_SEQ_PD_PC(8) |
+ SOR_SEQ_PD_PC_ALT(8),
+ HDMI_NV_PDISP_SOR_SEQ_CTL);
+
+ val = SOR_SEQ_INST_WAIT_TIME(1) |
+ SOR_SEQ_INST_WAIT_UNITS_VSYNC |
+ SOR_SEQ_INST_HALT |
+ SOR_SEQ_INST_PIN_A_LOW |
+ SOR_SEQ_INST_PIN_B_LOW |
+ SOR_SEQ_INST_DRIVE_PWM_OUT_LO;
+
+ tegra_hdmi_writel(hdmi, val, HDMI_NV_PDISP_SOR_SEQ_INST0);
+ tegra_hdmi_writel(hdmi, val, HDMI_NV_PDISP_SOR_SEQ_INST8);
+
+ val = 0x1c800;
+ val &= ~SOR_CSTM_ROTCLK(~0);
+ val |= SOR_CSTM_ROTCLK(2);
+ tegra_hdmi_writel(hdmi, val, HDMI_NV_PDISP_SOR_CSTM);
+
+
+ tegra_dc_writel(dc, DISP_CTRL_MODE_STOP, DC_CMD_DISPLAY_COMMAND);
+ tegra_dc_writel(dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL);
+ tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
+
+
+ /* start SOR */
+ tegra_hdmi_writel(hdmi,
+ SOR_PWR_NORMAL_STATE_PU |
+ SOR_PWR_NORMAL_START_NORMAL |
+ SOR_PWR_SAFE_STATE_PD |
+ SOR_PWR_SETTING_NEW_TRIGGER,
+ HDMI_NV_PDISP_SOR_PWR);
+ tegra_hdmi_writel(hdmi,
+ SOR_PWR_NORMAL_STATE_PU |
+ SOR_PWR_NORMAL_START_NORMAL |
+ SOR_PWR_SAFE_STATE_PD |
+ SOR_PWR_SETTING_NEW_DONE,
+ HDMI_NV_PDISP_SOR_PWR);
+
+ retries = 1000;
+ do {
+ BUG_ON(--retries < 0);
+ val = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_SOR_PWR);
+ } while (val & SOR_PWR_SETTING_NEW_PENDING);
+
+ tegra_hdmi_writel(hdmi,
+ SOR_STATE_ASY_CRCMODE_COMPLETE |
+ SOR_STATE_ASY_OWNER_HEAD0 |
+ SOR_STATE_ASY_SUBOWNER_BOTH |
+ SOR_STATE_ASY_PROTOCOL_SINGLE_TMDS_A |
+ /* TODO: to look at hsync polarity */
+ SOR_STATE_ASY_HSYNCPOL_POS |
+ SOR_STATE_ASY_VSYNCPOL_POS |
+ SOR_STATE_ASY_DEPOL_POS,
+ HDMI_NV_PDISP_SOR_STATE2);
+
+ val = SOR_STATE_ASY_HEAD_OPMODE_AWAKE | SOR_STATE_ASY_ORMODE_NORMAL;
+ tegra_hdmi_writel(hdmi, val, HDMI_NV_PDISP_SOR_STATE1);
+
+ tegra_hdmi_writel(hdmi, 0, HDMI_NV_PDISP_SOR_STATE0);
+ tegra_hdmi_writel(hdmi, SOR_STATE_UPDATE, HDMI_NV_PDISP_SOR_STATE0);
+ tegra_hdmi_writel(hdmi, val | SOR_STATE_ATTACHED,
+ HDMI_NV_PDISP_SOR_STATE1);
+ tegra_hdmi_writel(hdmi, 0, HDMI_NV_PDISP_SOR_STATE0);
+
+ tegra_dc_writel(dc, HDMI_ENABLE, DC_DISP_DISP_WIN_OPTIONS);
+
+ tegra_dc_writel(dc, PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
+ PW4_ENABLE | PM0_ENABLE | PM1_ENABLE,
+ DC_CMD_DISPLAY_POWER_CONTROL);
+
+ tegra_dc_writel(dc, DISP_CTRL_MODE_C_DISPLAY, DC_CMD_DISPLAY_COMMAND);
+ tegra_dc_writel(dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL);
+ tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
+}
+
+static void tegra_dc_hdmi_disable(struct tegra_dc *dc)
+{
+ struct tegra_dc_hdmi_data *hdmi = tegra_dc_get_outdata(dc);
+
+ tegra_periph_reset_assert(hdmi->clk);
+ clk_disable(hdmi->clk);
+}
+struct tegra_dc_out_ops tegra_dc_hdmi_ops = {
+ .init = tegra_dc_hdmi_init,
+ .destroy = tegra_dc_hdmi_destroy,
+ .enable = tegra_dc_hdmi_enable,
+ .disable = tegra_dc_hdmi_disable,
+ .detect = tegra_dc_hdmi_detect,
+};
+
--- /dev/null
+/*
+ * drivers/video/tegra/dc/hdmi_reg.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ * Author: Erik Gilling <konkers@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __DRIVERS_VIDEO_TEGRA_DC_HDMI_REG_H
+#define __DRIVERS_VIDEO_TEGRA_DC_HDMI_REG_H
+
+#define HDMI_CTXSW 0x00
+#define HDMI_NV_PDISP_SOR_STATE0 0x01
+#define SOR_STATE_UPDATE (1 << 0)
+
+#define HDMI_NV_PDISP_SOR_STATE1 0x02
+#define SOR_STATE_ASY_HEAD_OPMODE_SLEEP (0 << 0)
+#define SOR_STATE_ASY_HEAD_OPMODE_SNOOSE (1 << 0)
+#define SOR_STATE_ASY_HEAD_OPMODE_AWAKE (2 << 0)
+#define SOR_STATE_ASY_ORMODE_SAFE (0 << 2)
+#define SOR_STATE_ASY_ORMODE_NORMAL (1 << 2)
+#define SOR_STATE_ATTACHED (1 << 3)
+#define SOR_STATE_ARM_SHOW_VGA (1 << 4)
+
+#define HDMI_NV_PDISP_SOR_STATE2 0x03
+#define SOR_STATE_ASY_OWNER_NONE (0 << 0)
+#define SOR_STATE_ASY_OWNER_HEAD0 (1 << 0)
+#define SOR_STATE_ASY_SUBOWNER_NONE (0 << 4)
+#define SOR_STATE_ASY_SUBOWNER_SUBHEAD0 (1 << 4)
+#define SOR_STATE_ASY_SUBOWNER_SUBHEAD1 (2 << 4)
+#define SOR_STATE_ASY_SUBOWNER_BOTH (3 << 4)
+#define SOR_STATE_ASY_CRCMODE_ACTIVE (0 << 6)
+#define SOR_STATE_ASY_CRCMODE_COMPLETE (1 << 6)
+#define SOR_STATE_ASY_CRCMODE_NON_ACTIVE (2 << 6)
+#define SOR_STATE_ASY_PROTOCOL_SINGLE_TMDS_A (1 << 8)
+#define SOR_STATE_ASY_PROTOCOL_CUSTOM (15 << 8)
+#define SOR_STATE_ASY_HSYNCPOL_POS (0 << 12)
+#define SOR_STATE_ASY_HSYNCPOL_NEG (1 << 12)
+#define SOR_STATE_ASY_VSYNCPOL_POS (0 << 13)
+#define SOR_STATE_ASY_VSYNCPOL_NEG (1 << 13)
+#define SOR_STATE_ASY_DEPOL_POS (0 << 14)
+#define SOR_STATE_ASY_DEPOL_NEG (1 << 14)
+
+#define HDMI_NV_PDISP_RG_HDCP_AN_MSB 0x04
+#define HDMI_NV_PDISP_RG_HDCP_AN_LSB 0x05
+#define HDMI_NV_PDISP_RG_HDCP_CN_MSB 0x06
+#define HDMI_NV_PDISP_RG_HDCP_CN_LSB 0x07
+#define HDMI_NV_PDISP_RG_HDCP_AKSV_MSB 0x08
+#define HDMI_NV_PDISP_RG_HDCP_AKSV_LSB 0x09
+#define HDMI_NV_PDISP_RG_HDCP_BKSV_MSB 0x0a
+#define HDMI_NV_PDISP_RG_HDCP_BKSV_LSB 0x0b
+#define HDMI_NV_PDISP_RG_HDCP_CKSV_MSB 0x0c
+#define HDMI_NV_PDISP_RG_HDCP_CKSV_LSB 0x0d
+#define HDMI_NV_PDISP_RG_HDCP_DKSV_MSB 0x0e
+#define HDMI_NV_PDISP_RG_HDCP_DKSV_LSB 0x0f
+#define HDMI_NV_PDISP_RG_HDCP_CTRL 0x10
+#define HDMI_NV_PDISP_RG_HDCP_CMODE 0x11
+#define HDMI_NV_PDISP_RG_HDCP_MPRIME_MSB 0x12
+#define HDMI_NV_PDISP_RG_HDCP_MPRIME_LSB 0x13
+#define HDMI_NV_PDISP_RG_HDCP_SPRIME_MSB 0x14
+#define HDMI_NV_PDISP_RG_HDCP_SPRIME_LSB2 0x15
+#define HDMI_NV_PDISP_RG_HDCP_SPRIME_LSB1 0x16
+#define HDMI_NV_PDISP_RG_HDCP_RI 0x17
+#define HDMI_NV_PDISP_RG_HDCP_CS_MSB 0x18
+#define HDMI_NV_PDISP_RG_HDCP_CS_LSB 0x19
+#define HDMI_NV_PDISP_HDMI_AUDIO_EMU0 0x1a
+#define HDMI_NV_PDISP_HDMI_AUDIO_EMU_RDATA0 0x1b
+#define HDMI_NV_PDISP_HDMI_AUDIO_EMU1 0x1c
+#define HDMI_NV_PDISP_HDMI_AUDIO_EMU2 0x1d
+#define HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL 0x1e
+#define HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_STATUS 0x1f
+#define HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_HEADER 0x20
+#define HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_SUBPACK0_LOW 0x21
+#define HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_SUBPACK0_HIGH 0x22
+#define HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_CTRL 0x23
+#define HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_STATUS 0x24
+#define HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_HEADER 0x25
+#define HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK0_LOW 0x26
+#define HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK0_HIGH 0x27
+#define HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK1_LOW 0x28
+#define HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK1_HIGH 0x29
+#define HDMI_NV_PDISP_HDMI_GENERIC_CTRL 0x2a
+#define HDMI_NV_PDISP_HDMI_GENERIC_STATUS 0x2b
+#define HDMI_NV_PDISP_HDMI_GENERIC_HEADER 0x2c
+#define HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK0_LOW 0x2d
+#define HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK0_HIGH 0x2e
+#define HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK1_LOW 0x2f
+#define HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK1_HIGH 0x30
+#define HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK2_LOW 0x31
+#define HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK2_HIGH 0x32
+#define HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK3_LOW 0x33
+#define HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK3_HIGH 0x34
+#define HDMI_NV_PDISP_HDMI_ACR_CTRL 0x35
+#define HDMI_NV_PDISP_HDMI_ACR_0320_SUBPACK_LOW 0x36
+#define HDMI_NV_PDISP_HDMI_ACR_0320_SUBPACK_HIGH 0x37
+#define HDMI_NV_PDISP_HDMI_ACR_0441_SUBPACK_LOW 0x38
+#define HDMI_NV_PDISP_HDMI_ACR_0441_SUBPACK_HIGH 0x39
+#define HDMI_NV_PDISP_HDMI_ACR_0882_SUBPACK_LOW 0x3a
+#define HDMI_NV_PDISP_HDMI_ACR_0882_SUBPACK_HIGH 0x3b
+#define HDMI_NV_PDISP_HDMI_ACR_1764_SUBPACK_LOW 0x3c
+#define HDMI_NV_PDISP_HDMI_ACR_1764_SUBPACK_HIGH 0x3d
+#define HDMI_NV_PDISP_HDMI_ACR_0480_SUBPACK_LOW 0x3e
+#define HDMI_NV_PDISP_HDMI_ACR_0480_SUBPACK_HIGH 0x3f
+#define HDMI_NV_PDISP_HDMI_ACR_0960_SUBPACK_LOW 0x40
+#define HDMI_NV_PDISP_HDMI_ACR_0960_SUBPACK_HIGH 0x41
+#define HDMI_NV_PDISP_HDMI_ACR_1920_SUBPACK_LOW 0x42
+#define HDMI_NV_PDISP_HDMI_ACR_1920_SUBPACK_HIGH 0x43
+#define HDMI_NV_PDISP_HDMI_CTRL 0x44
+#define HDMI_CTRL_REKEY(x) (((x) & 0x7f) << 0)
+#define HDMI_CTRL_AUDIO_LAYOUT (1 << 8)
+#define HDMI_CTRL_SAMPLE_FLAT (1 << 12)
+#define HDMI_CTRL_MAX_AC_PACKET(x) (((x) & 0x1f) << 16)
+#define HDMI_CTRL_ENABLE (1 << 30)
+
+#define HDMI_NV_PDISP_HDMI_VSYNC_KEEPOUT 0x45
+#define HDMI_NV_PDISP_HDMI_VSYNC_WINDOW 0x46
+#define VSYNC_WINDOW_END(x) (((x) & 0x3ff) << 0)
+#define VSYNC_WINDOW_START(x) (((x) & 0x3ff) << 16)
+#define VSYNC_WINDOW_ENABLE (1 << 31)
+
+#define HDMI_NV_PDISP_HDMI_GCP_CTRL 0x47
+#define HDMI_NV_PDISP_HDMI_GCP_STATUS 0x48
+#define HDMI_NV_PDISP_HDMI_GCP_SUBPACK 0x49
+#define HDMI_NV_PDISP_HDMI_CHANNEL_STATUS1 0x4a
+#define HDMI_NV_PDISP_HDMI_CHANNEL_STATUS2 0x4b
+#define HDMI_NV_PDISP_HDMI_EMU0 0x4c
+#define HDMI_NV_PDISP_HDMI_EMU1 0x4d
+#define HDMI_NV_PDISP_HDMI_EMU1_RDATA 0x4e
+#define HDMI_NV_PDISP_HDMI_SPARE 0x4f
+#define HDMI_NV_PDISP_HDMI_SPDIF_CHN_STATUS1 0x50
+#define HDMI_NV_PDISP_HDMI_SPDIF_CHN_STATUS2 0x51
+#define HDMI_NV_PDISP_HDCPRIF_ROM_CTRL 0x53
+#define HDMI_NV_PDISP_SOR_CAP 0x54
+#define HDMI_NV_PDISP_SOR_PWR 0x55
+#define SOR_PWR_NORMAL_STATE_PD (0 << 0)
+#define SOR_PWR_NORMAL_STATE_PU (1 << 0)
+#define SOR_PWR_NORMAL_START_NORMAL (0 << 1)
+#define SOR_PWR_NORMAL_START_ALT (1 << 1)
+#define SOR_PWR_SAFE_STATE_PD (0 << 16)
+#define SOR_PWR_SAFE_STATE_PU (1 << 16)
+#define SOR_PWR_SAFE_START_NORMAL (0 << 17)
+#define SOR_PWR_SAFE_START_ALT (1 << 17)
+#define SOR_PWR_HALT_DELAY (1 << 24)
+#define SOR_PWR_MODE (1 << 28)
+#define SOR_PWR_SETTING_NEW_DONE (0 << 31)
+#define SOR_PWR_SETTING_NEW_PENDING (1 << 31)
+#define SOR_PWR_SETTING_NEW_TRIGGER (1 << 31)
+
+#define HDMI_NV_PDISP_SOR_TEST 0x56
+#define HDMI_NV_PDISP_SOR_PLL0 0x57
+#define SOR_PLL_PWR (1 << 0)
+#define SOR_PLL_PDBG (1 << 1)
+#define SOR_PLL_VCOPD (1 << 2)
+#define SOR_PLL_PDPORT (1 << 3)
+#define SOR_PLL_RESISTORSEL (1 << 4)
+#define SOR_PLL_PULLDOWN (1 << 5)
+#define SOR_PLL_VCOCAP(x) (((x) & 0xf) << 8)
+#define SOR_PLL_BG_V17_S(x) (((x) & 0xf) << 12)
+#define SOR_PLL_FILTER(x) (((x) & 0xf) << 16)
+#define SOR_PLL_ICHPMP(x) (((x) & 0xf) << 24)
+#define SOR_PLL_TX_REG_LOAD(x) (((x) & 0x3) << 28)
+
+#define HDMI_NV_PDISP_SOR_PLL1 0x58
+#define SOR_PLL_TMDS_TERM_ENABLE (1 << 8)
+#define SOR_PLL_TMDS_TERMADJ(x) (((x) & 0xf) << 9)
+#define SOR_PLL_LOADADJ(x) (((x) & 0xf) << 20)
+#define SOR_PLL_PE_EN (1 << 28)
+#define SOR_PLL_HALF_FULL_PE (1 << 29)
+#define SOR_PLL_S_D_PIN_PE (1 << 30)
+
+#define HDMI_NV_PDISP_SOR_PLL2 0x59
+#define HDMI_NV_PDISP_SOR_CSTM 0x5a
+#define SOR_CSTM_PD_TXDA_0 (1 << 0)
+#define SOR_CSTM_PD_TXDA_1 (1 << 1)
+#define SOR_CSTM_PD_TXDA_2 (1 << 2)
+#define SOR_CSTM_PD_TXDA_3 (1 << 3)
+#define SOR_CSTM_PD_TXDB_0 (1 << 4)
+#define SOR_CSTM_PD_TXDB_1 (1 << 5)
+#define SOR_CSTM_PD_TXDB_2 (1 << 6)
+#define SOR_CSTM_PD_TXDB_3 (1 << 7)
+#define SOR_CSTM_PD_TXCA (1 << 8)
+#define SOR_CSTM_PD_TXCB (1 << 9)
+#define SOR_CSTM_UPPER (1 << 11)
+#define SOR_CSTM_MODE(x) (((x) & 0x3) << 12)
+#define SOR_CSTM_LINKACTA (1 << 14)
+#define SOR_CSTM_LINKACTB (1 << 15)
+#define SOR_CSTM_LVDS_EN (1 << 16)
+#define SOR_CSTM_DUP_SYNC (1 << 17)
+#define SOR_CSTM_NEW_MODE (1 << 18)
+#define SOR_CSTM_BALANCED (1 << 19)
+#define SOR_CSTM_PLLDIV (1 << 21)
+#define SOR_CSTM_ROTCLK(x) (((x) & 0xf) << 24)
+#define SOR_CSTM_ROTDAT(x) (((x) & 0x7) << 28)
+
+#define HDMI_NV_PDISP_SOR_LVDS 0x5b
+#define HDMI_NV_PDISP_SOR_CRCA 0x5c
+#define HDMI_NV_PDISP_SOR_CRCB 0x5d
+#define HDMI_NV_PDISP_SOR_BLANK 0x5e
+#define HDMI_NV_PDISP_SOR_SEQ_CTL 0x5f
+#define SOR_SEQ_CTL_PU_PC(x) (((x) & 0xf) << 0)
+#define SOR_SEQ_PU_PC_ALT(x) (((x) & 0xf) << 4)
+#define SOR_SEQ_PD_PC(x) (((x) & 0xf) << 8)
+#define SOR_SEQ_PD_PC_ALT(x) (((x) & 0xf) << 12)
+#define SOR_SEQ_PC(x) (((x) & 0xf) << 16)
+#define SOR_SEQ_STATUS (1 << 28)
+#define SOR_SEQ_SWITCH (1 << 30)
+
+#define HDMI_NV_PDISP_SOR_SEQ_INST0 0x60
+#define HDMI_NV_PDISP_SOR_SEQ_INST1 0x61
+#define HDMI_NV_PDISP_SOR_SEQ_INST2 0x62
+#define HDMI_NV_PDISP_SOR_SEQ_INST3 0x63
+#define HDMI_NV_PDISP_SOR_SEQ_INST4 0x64
+#define HDMI_NV_PDISP_SOR_SEQ_INST5 0x65
+#define HDMI_NV_PDISP_SOR_SEQ_INST6 0x66
+#define HDMI_NV_PDISP_SOR_SEQ_INST7 0x67
+#define HDMI_NV_PDISP_SOR_SEQ_INST8 0x68
+#define HDMI_NV_PDISP_SOR_SEQ_INST9 0x69
+#define HDMI_NV_PDISP_SOR_SEQ_INSTA 0x6a
+#define HDMI_NV_PDISP_SOR_SEQ_INSTB 0x6b
+#define HDMI_NV_PDISP_SOR_SEQ_INSTC 0x6c
+#define HDMI_NV_PDISP_SOR_SEQ_INSTD 0x6d
+#define HDMI_NV_PDISP_SOR_SEQ_INSTE 0x6e
+#define HDMI_NV_PDISP_SOR_SEQ_INSTF 0x6f
+#define SOR_SEQ_INST_WAIT_TIME(x) (((x) & 0x3ff) << 0)
+#define SOR_SEQ_INST_WAIT_UNITS_US (0 << 12)
+#define SOR_SEQ_INST_WAIT_UNITS_MS (1 << 12)
+#define SOR_SEQ_INST_WAIT_UNITS_VSYNC (2 << 12)
+#define SOR_SEQ_INST_HALT (1 << 15)
+#define SOR_SEQ_INST_PIN_A_LOW (0 << 21)
+#define SOR_SEQ_INST_PIN_A_HIGH (1 << 21)
+#define SOR_SEQ_INST_PIN_B_LOW (0 << 22)
+#define SOR_SEQ_INST_PIN_B_HIGH (1 << 22)
+#define SOR_SEQ_INST_DRIVE_PWM_OUT_LO (1 << 23)
+#define SOR_SEQ_INST_TRISTATE_IOS (1 << 24)
+#define SOR_SEQ_INST_SOR_SEQ_INST_BLACK_DATA (1 << 25)
+#define SOR_SEQ_INST_BLANK_DE (1 << 26)
+#define SOR_SEQ_INST_BLANK_H (1 << 27)
+#define SOR_SEQ_INST_BLANK_V (1 << 28)
+#define SOR_SEQ_INST_ASSERT_PLL_RESETV (1 << 29)
+#define SOR_SEQ_INST_POWERDOWN_MACRO (1 << 30)
+#define SOR_SEQ_INST_PLL_PULLDOWN (1 << 31)
+
+#define HDMI_NV_PDISP_SOR_VCRCA0 0x72
+#define HDMI_NV_PDISP_SOR_VCRCA1 0x73
+#define HDMI_NV_PDISP_SOR_CCRCA0 0x74
+#define HDMI_NV_PDISP_SOR_CCRCA1 0x75
+#define HDMI_NV_PDISP_SOR_EDATAA0 0x76
+#define HDMI_NV_PDISP_SOR_EDATAA1 0x77
+#define HDMI_NV_PDISP_SOR_COUNTA0 0x78
+#define HDMI_NV_PDISP_SOR_COUNTA1 0x79
+#define HDMI_NV_PDISP_SOR_DEBUGA0 0x7a
+#define HDMI_NV_PDISP_SOR_DEBUGA1 0x7b
+#define HDMI_NV_PDISP_SOR_TRIG 0x7c
+#define HDMI_NV_PDISP_SOR_MSCHECK 0x7d
+#define HDMI_NV_PDISP_SOR_LANE_DRIVE_CURRENT 0x7e
+#define DRIVE_CURRENT_LANE0(x) (((x) & 0x3f) << 0)
+#define DRIVE_CURRENT_LANE1(x) (((x) & 0x3f) << 8)
+#define DRIVE_CURRENT_LANE2(x) (((x) & 0x3f) << 16)
+#define DRIVE_CURRENT_LANE3(x) (((x) & 0x3f) << 24)
+#define DRIVE_CURRENT_FUSE_OVERRIDE (1 << 31)
+#define DRIVE_CURRENT_1_500_mA 0x00
+#define DRIVE_CURRENT_1_875_mA 0x01
+#define DRIVE_CURRENT_2_250_mA 0x02
+#define DRIVE_CURRENT_2_625_mA 0x03
+#define DRIVE_CURRENT_3_000_mA 0x04
+#define DRIVE_CURRENT_3_375_mA 0x05
+#define DRIVE_CURRENT_3_750_mA 0x06
+#define DRIVE_CURRENT_4_125_mA 0x07
+#define DRIVE_CURRENT_4_500_mA 0x08
+#define DRIVE_CURRENT_4_875_mA 0x09
+#define DRIVE_CURRENT_5_250_mA 0x0a
+#define DRIVE_CURRENT_5_625_mA 0x0b
+#define DRIVE_CURRENT_6_000_mA 0x0c
+#define DRIVE_CURRENT_6_375_mA 0x0d
+#define DRIVE_CURRENT_6_750_mA 0x0e
+#define DRIVE_CURRENT_7_125_mA 0x0f
+#define DRIVE_CURRENT_7_500_mA 0x10
+#define DRIVE_CURRENT_7_875_mA 0x11
+#define DRIVE_CURRENT_8_250_mA 0x12
+#define DRIVE_CURRENT_8_625_mA 0x13
+#define DRIVE_CURRENT_9_000_mA 0x14
+#define DRIVE_CURRENT_9_375_mA 0x15
+#define DRIVE_CURRENT_9_750_mA 0x16
+#define DRIVE_CURRENT_10_125_mA 0x17
+#define DRIVE_CURRENT_10_500_mA 0x18
+#define DRIVE_CURRENT_10_875_mA 0x19
+#define DRIVE_CURRENT_11_250_mA 0x1a
+#define DRIVE_CURRENT_11_625_mA 0x1b
+#define DRIVE_CURRENT_12_000_mA 0x1c
+#define DRIVE_CURRENT_12_375_mA 0x1d
+#define DRIVE_CURRENT_12_750_mA 0x1e
+#define DRIVE_CURRENT_13_125_mA 0x1f
+#define DRIVE_CURRENT_13_500_mA 0x20
+#define DRIVE_CURRENT_13_875_mA 0x21
+#define DRIVE_CURRENT_14_250_mA 0x22
+#define DRIVE_CURRENT_14_625_mA 0x23
+#define DRIVE_CURRENT_15_000_mA 0x24
+#define DRIVE_CURRENT_15_375_mA 0x25
+#define DRIVE_CURRENT_15_750_mA 0x26
+#define DRIVE_CURRENT_16_125_mA 0x27
+#define DRIVE_CURRENT_16_500_mA 0x28
+#define DRIVE_CURRENT_16_875_mA 0x29
+#define DRIVE_CURRENT_17_250_mA 0x2a
+#define DRIVE_CURRENT_17_625_mA 0x2b
+#define DRIVE_CURRENT_18_000_mA 0x2c
+#define DRIVE_CURRENT_18_375_mA 0x2d
+#define DRIVE_CURRENT_18_750_mA 0x2e
+#define DRIVE_CURRENT_19_125_mA 0x2f
+#define DRIVE_CURRENT_19_500_mA 0x30
+#define DRIVE_CURRENT_19_875_mA 0x31
+#define DRIVE_CURRENT_20_250_mA 0x32
+#define DRIVE_CURRENT_20_625_mA 0x33
+#define DRIVE_CURRENT_21_000_mA 0x34
+#define DRIVE_CURRENT_21_375_mA 0x35
+#define DRIVE_CURRENT_21_750_mA 0x36
+#define DRIVE_CURRENT_22_125_mA 0x37
+#define DRIVE_CURRENT_22_500_mA 0x38
+#define DRIVE_CURRENT_22_875_mA 0x39
+#define DRIVE_CURRENT_23_250_mA 0x3a
+#define DRIVE_CURRENT_23_625_mA 0x3b
+#define DRIVE_CURRENT_24_000_mA 0x3c
+#define DRIVE_CURRENT_24_375_mA 0x3d
+#define DRIVE_CURRENT_24_750_mA 0x3e
+
+#define HDMI_NV_PDISP_AUDIO_DEBUG0 0x7f
+#define HDMI_NV_PDISP_AUDIO_DEBUG1 0x80
+#define HDMI_NV_PDISP_AUDIO_DEBUG2 0x81
+#define HDMI_NV_PDISP_AUDIO_FS1 0x82
+#define HDMI_NV_PDISP_AUDIO_FS2 0x83
+#define HDMI_NV_PDISP_AUDIO_FS3 0x84
+#define HDMI_NV_PDISP_AUDIO_FS4 0x85
+#define HDMI_NV_PDISP_AUDIO_FS5 0x86
+#define HDMI_NV_PDISP_AUDIO_FS6 0x87
+#define HDMI_NV_PDISP_AUDIO_FS7 0x88
+#define HDMI_NV_PDISP_AUDIO_PULSE_WIDTH 0x89
+#define HDMI_NV_PDISP_AUDIO_THRESHOLD 0x8a
+#define HDMI_NV_PDISP_AUDIO_CNTRL0 0x8b
+#define HDMI_NV_PDISP_AUDIO_N 0x8c
+#define HDMI_NV_PDISP_HDCPRIF_ROM_TIMING 0x94
+#define HDMI_NV_PDISP_SOR_REFCLK 0x95
+#define SOR_REFCLK_DIV_INT(x) (((x) & 0xff) << 8)
+#define SOR_REFCLK_DIV_FRAC(x) (((x) & 0x3) << 6)
+
+#define HDMI_NV_PDISP_CRC_CONTROL 0x96
+#define HDMI_NV_PDISP_INPUT_CONTROL 0x97
+#define HDMI_SRC_DISPLAYA (0 << 0)
+#define HDMI_SRC_DISPLAYB (1 << 0)
+#define ARM_VIDEO_RANGE_FULL (0 << 1)
+#define ARM_VIDEO_RANGE_LIMITED (1 << 1)
+
+#define HDMI_NV_PDISP_SCRATCH 0x98
+#define HDMI_NV_PDISP_PE_CURRENT 0x99
+#define PE_CURRENT0(x) (((x) & 0xf) << 0)
+#define PE_CURRENT1(x) (((x) & 0xf) << 8)
+#define PE_CURRENT2(x) (((x) & 0xf) << 16)
+#define PE_CURRENT3(x) (((x) & 0xf) << 24)
+
+#define HDMI_NV_PDISP_KEY_CTRL 0x9a
+#define HDMI_NV_PDISP_KEY_DEBUG0 0x9b
+#define HDMI_NV_PDISP_KEY_DEBUG1 0x9c
+#define HDMI_NV_PDISP_KEY_DEBUG2 0x9d
+#define HDMI_NV_PDISP_KEY_HDCP_KEY_0 0x9e
+#define HDMI_NV_PDISP_KEY_HDCP_KEY_1 0x9f
+#define HDMI_NV_PDISP_KEY_HDCP_KEY_2 0xa0
+#define HDMI_NV_PDISP_KEY_HDCP_KEY_3 0xa1
+#define HDMI_NV_PDISP_KEY_HDCP_KEY_TRIG 0xa2
+#define HDMI_NV_PDISP_KEY_SKEY_INDEX 0xa3
+
+#endif