[PATCH v3 03/32] drm/via: Add via_crtc_hw.h
Kevin Brace
kevinbrace at gmx.com
Mon Jul 25 23:50:58 UTC 2022
From: Kevin Brace <kevinbrace at bracecomputerlab.com>
Signed-off-by: Kevin Brace <kevinbrace at bracecomputerlab.com>
---
drivers/gpu/drm/via/via_crtc_hw.h | 1190 +++++++++++++++++++++++++++++
1 file changed, 1190 insertions(+)
create mode 100644 drivers/gpu/drm/via/via_crtc_hw.h
diff --git a/drivers/gpu/drm/via/via_crtc_hw.h b/drivers/gpu/drm/via/via_crtc_hw.h
new file mode 100644
index 000000000000..4a6b785324bd
--- /dev/null
+++ b/drivers/gpu/drm/via/via_crtc_hw.h
@@ -0,0 +1,1190 @@
+/*
+ * Copyright 2012 James Simmons. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author(s):
+ * James Simmons <jsimmons at infradead.org>
+ */
+
+#ifndef __CRTC_HW_H__
+#define __CRTC_HW_H__
+
+#include <video/vga.h>
+
+#include <drm/drm_print.h>
+
+
+/* To be used with via_dac_set_dpms_control inline function. */
+#define VIA_DAC_DPMS_ON 0x00
+#define VIA_DAC_DPMS_STANDBY 0x01
+#define VIA_DAC_DPMS_SUSPEND 0x02
+#define VIA_DAC_DPMS_OFF 0x03
+
+
+struct vga_regset {
+ u16 ioport;
+ u8 io_addr;
+ u8 start_bit;
+ u8 end_bit;
+};
+
+struct vga_registers {
+ unsigned int count;
+ struct vga_regset *regs;
+};
+
+/************************************************
+ ***** Display Timing *****
+ ************************************************/
+
+struct crtc_timings {
+ struct vga_registers htotal;
+ struct vga_registers hdisplay;
+ struct vga_registers hblank_start;
+ struct vga_registers hblank_end;
+ struct vga_registers hsync_start;
+ struct vga_registers hsync_end;
+ struct vga_registers vtotal;
+ struct vga_registers vdisplay;
+ struct vga_registers vblank_start;
+ struct vga_registers vblank_end;
+ struct vga_registers vsync_start;
+ struct vga_registers vsync_end;
+};
+
+/* Write a value to misc register with a mask */
+static inline void svga_wmisc_mask(void __iomem *regbase, u8 data, u8 mask)
+{
+ vga_w(regbase, VGA_MIS_W, (data & mask) | (vga_r(regbase, VGA_MIS_R) & ~mask));
+}
+
+/* Write a value to a sequence register with a mask */
+static inline void svga_wseq_mask(void __iomem *regbase, u8 index, u8 data, u8 mask)
+{
+ vga_wseq(regbase, index, (data & mask) | (vga_rseq(regbase, index) & ~mask));
+}
+
+/* Write a value to a CRT register with a mask */
+static inline void svga_wcrt_mask(void __iomem *regbase, u8 index, u8 data, u8 mask)
+{
+ vga_wcrt(regbase, index, (data & mask) | (vga_rcrt(regbase, index) & ~mask));
+}
+
+
+/***********************************************************************
+
+ VIA Technologies Chrome IGP Register Access Helper Functions
+
+***********************************************************************/
+
+static inline void
+via_iga1_set_palette_lut_resolution(void __iomem *regs,
+ bool palette_lut)
+{
+ /* Set the palette LUT resolution for IGA1. */
+ /* 3C5.15[7] - IGA1 6 / 8 Bit LUT
+ * 0: 6-bit
+ * 1: 8-bit */
+ svga_wseq_mask(regs, 0x15, palette_lut ? BIT(7) : 0x00, BIT(7));
+ DRM_DEBUG_KMS("IGA1 Palette LUT Resolution: %s bit\n",
+ palette_lut ? "8" : "6");
+}
+
+static inline void
+via_iga2_set_palette_lut_resolution(void __iomem *regs,
+ bool palette_lut)
+{
+ /* Set the palette LUT resolution for IGA2. */
+ /* 3X5.6A[5] - IGA2 6 / 8 Bit LUT
+ * 0: 6-bit
+ * 1: 8-bit */
+ svga_wcrt_mask(regs, 0x6a, palette_lut ? BIT(5) : 0x00, BIT(5));
+ DRM_DEBUG_KMS("IGA2 Palette LUT Resolution: %s bit\n",
+ palette_lut ? "8" : "6");
+}
+
+static inline void
+via_iga1_set_interlace_mode(void __iomem *regs, bool interlace_mode)
+{
+ svga_wcrt_mask(regs, 0x33,
+ interlace_mode ? BIT(6) : 0x00, BIT(6));
+ DRM_DEBUG_KMS("IGA1 Interlace Mode: %s\n",
+ interlace_mode ? "On" : "Off");
+}
+
+static inline void
+via_iga2_set_interlace_mode(void __iomem *regs, bool interlace_mode)
+{
+ svga_wcrt_mask(regs, 0x67,
+ interlace_mode ? BIT(5) : 0x00, BIT(5));
+ DRM_DEBUG_KMS("IGA2 Interlace Mode: %s\n",
+ interlace_mode ? "On" : "Off");
+}
+
+/*
+ * Sets IGA1's HSYNC Shift value.
+ */
+static inline void
+via_iga1_set_hsync_shift(void __iomem *regs, u8 shift_value)
+{
+ /* 3X5.33[2:0] - IGA1 HSYNC Shift */
+ svga_wcrt_mask(regs, 0x33, shift_value, BIT(2) | BIT(1) | BIT(0));
+ DRM_DEBUG_KMS("IGA1 HSYNC Shift: %u\n",
+ (shift_value & 0x07));
+}
+
+/*
+ * Sets DIP0 (Digital Interface Port 0) I/O pad state.
+ * CLE266 chipset only.
+ */
+static inline void
+via_dip0_set_io_pad_state(void __iomem *regs, u8 io_pad_state)
+{
+ /* 3C5.1E[7:6] - DIP0 Power Control
+ * 0x: Pad always off
+ * 10: Depend on the other control signal
+ * 11: Pad on/off according to the
+ * Power Management Status (PMS) */
+ svga_wseq_mask(regs, 0x1E, io_pad_state << 6, BIT(7) | BIT(6));
+ DRM_DEBUG_KMS("DIP0 I/O Pad State: %s\n",
+ ((io_pad_state & (BIT(1) | BIT(0))) == 0x03) ? "On" :
+ ((io_pad_state & (BIT(1) | BIT(0))) == 0x02) ? "Conditional" :
+ ((io_pad_state & (BIT(1) | BIT(0))) == 0x01) ? "Off" :
+ "Off");
+}
+
+/*
+ * Output enable of DIP0 (Digital Interface Port 0) interface.
+ * CLE266 chipset only.
+ */
+static inline void
+via_dip0_set_output_enable(void __iomem *regs, bool output_enable)
+{
+ /*
+ * 3X5.6C[0] - DIP0 Output Enable
+ * 0: Output Disable
+ * 1: Output Enable
+ */
+ svga_wcrt_mask(regs, 0x6c, output_enable ? BIT(0) : 0x00, BIT(0));
+ DRM_DEBUG_KMS("DIP0 Output: %s\n",
+ output_enable ? "Enable" : "Disable");
+}
+
+/*
+ * Sets the clock source of DIP0 (Digital Interface Port 0)
+ * interface. CLE266 chipset only.
+ */
+static inline void
+via_dip0_set_clock_source(void __iomem *regs, bool clock_source)
+{
+ /*
+ * 3X5.6C[5] - DIP0 Clock Source
+ * 0: External
+ * 1: Internal
+ */
+ svga_wcrt_mask(regs, 0x6c, clock_source ? BIT(5) : 0x00, BIT(5));
+ DRM_DEBUG_KMS("DIP0 Clock Source: %s\n",
+ clock_source ? "Internal" : "External");
+}
+
+/*
+ * Sets the display source of DIP0 (Digital Interface Port 0) interface.
+ * CLE266 chipset only.
+ */
+static inline void
+via_dip0_set_display_source(void __iomem *regs, u8 display_source)
+{
+ /*
+ * 3X5.6C[7] - DIP0 Data Source Selection
+ * 0: Primary Display
+ * 1: Secondary Display
+ */
+ svga_wcrt_mask(regs, 0x6c, display_source << 7, BIT(7));
+ DRM_DEBUG_KMS("DIP0 Display Source: IGA%d\n",
+ (display_source & 0x01) + 1);
+}
+
+/*
+ * Sets DIP1 (Digital Interface Port 1) I/O pad state.
+ * CLE266 chipset only.
+ */
+static inline void
+via_dip1_set_io_pad_state(void __iomem *regs, u8 io_pad_state)
+{
+ /*
+ * 3C5.1E[5:4] - DIP1 I/O Pad Control
+ * 00: I/O pad off
+ * 11: I/O pad on
+ */
+ svga_wseq_mask(regs, 0x1e, io_pad_state << 4, BIT(5) | BIT(4));
+ DRM_DEBUG_KMS("DIP1 I/O Pad State: %s\n",
+ ((io_pad_state & (BIT(1) | BIT(0))) == 0x03) ? "On" :
+ ((io_pad_state & (BIT(1) | BIT(0))) == 0x02) ? "Conditional" :
+ ((io_pad_state & (BIT(1) | BIT(0))) == 0x01) ? "Off" :
+ "Off");
+}
+
+/*
+ * Output enable of DIP1 (Digital Interface Port 1) interface.
+ * CLE266 chipset only.
+ */
+static inline void
+via_dip1_set_output_enable(void __iomem *regs, bool output_enable)
+{
+ /*
+ * 3X5.93[0] - DIP1 Output Enable
+ * 0: Output Disable
+ * 1: Output Enable
+ */
+ svga_wcrt_mask(regs, 0x93, output_enable ? BIT(0) : 0x00, BIT(0));
+ DRM_DEBUG_KMS("DIP1 Output: %s\n",
+ output_enable ? "Enable" : "Disable");
+}
+
+/*
+ * Sets the clock source of DIP1 (Digital Interface Port 1)
+ * interface. CLE266 chipset only.
+ */
+static inline void
+via_dip1_set_clock_source(void __iomem *regs, bool clock_source)
+{
+ /*
+ * 3X5.93[5] - DIP1 Clock Source
+ * 0: External
+ * 1: Internal
+ */
+ svga_wcrt_mask(regs, 0x93, clock_source ? BIT(5) : 0x00, BIT(5));
+ DRM_DEBUG_KMS("DIP1 Clock Source: %s\n",
+ clock_source ? "Internal" : "External");
+}
+
+/*
+ * Sets the display source of DIP1 (Digital Interface Port 1)
+ * interface. CLE266 chipset only.
+ */
+static inline void
+via_dip1_set_display_source(void __iomem *regs, u8 display_source)
+{
+ /*
+ * 3X5.93[7] - DIP1 Data Source Selection
+ * 0: IGA1
+ * 1: IGA2
+ */
+ svga_wcrt_mask(regs, 0x93, display_source << 7, BIT(7));
+ DRM_DEBUG_KMS("DIP1 Display Source: IGA%d\n",
+ (display_source & 0x01) + 1);
+}
+
+/*
+ * Sets DVP0 (Digital Video Port 0) I/O pad state.
+ */
+static inline void
+via_dvp0_set_io_pad_state(void __iomem *regs, u8 io_pad_state)
+{
+ /* 3C5.1E[7:6] - DVP0 Power Control
+ * 0x: Pad always off
+ * 10: Depend on the other control signal
+ * 11: Pad on/off according to the
+ * Power Management Status (PMS) */
+ svga_wseq_mask(regs, 0x1E, io_pad_state << 6, BIT(7) | BIT(6));
+ DRM_DEBUG_KMS("DVP0 I/O Pad State: %s\n",
+ ((io_pad_state & (BIT(1) | BIT(0))) == 0x03) ? "On" :
+ ((io_pad_state & (BIT(1) | BIT(0))) == 0x02) ? "Conditional" :
+ ((io_pad_state & (BIT(1) | BIT(0))) == 0x01) ? "Off" :
+ "Off");
+}
+
+/*
+ * Sets DVP0 (Digital Video Port 0) clock I/O pad drive strength.
+ */
+static inline void
+via_dvp0_set_clock_drive_strength(void __iomem *regs,
+ u8 clock_drive_strength)
+{
+ /* 3C5.1E[2] - DVP0 Clock Drive Strength Bit [0] */
+ svga_wseq_mask(regs, 0x1E,
+ clock_drive_strength << 2, BIT(2));
+
+ /* 3C5.2A[4] - DVP0 Clock Drive Strength Bit [1] */
+ svga_wseq_mask(regs, 0x2A,
+ clock_drive_strength << 3, BIT(4));
+
+ DRM_DEBUG_KMS("DVP0 Clock I/O Pad Drive Strength: %lu\n",
+ clock_drive_strength & (BIT(1) | BIT(0)));
+}
+
+/*
+ * Sets DVP0 (Digital Video Port 0) data I/O pads drive strength.
+ */
+static inline void
+via_dvp0_set_data_drive_strength(void __iomem *regs,
+ u8 data_drive_strength)
+{
+ /* 3C5.1B[1] - DVP0 Data Drive Strength Bit [0] */
+ svga_wseq_mask(regs, 0x1B,
+ data_drive_strength << 1, BIT(1));
+
+ /* 3C5.2A[5] - DVP0 Data Drive Strength Bit [1] */
+ svga_wseq_mask(regs, 0x2A,
+ data_drive_strength << 4, BIT(5));
+
+ DRM_DEBUG_KMS("DVP0 Data I/O Pads Drive Strength: %lu\n",
+ data_drive_strength & (BIT(1) | BIT(0)));
+}
+
+/*
+ * Sets the display source of DVP0 (Digital Video Port 0) interface.
+ */
+static inline void
+via_dvp0_set_display_source(void __iomem *regs, u8 display_source)
+{
+ /* 3X5.96[4] - DVP0 Data Source Selection
+ * 0: Primary Display
+ * 1: Secondary Display */
+ svga_wcrt_mask(regs, 0x96, display_source << 4, BIT(4));
+ DRM_DEBUG_KMS("DVP0 Display Source: IGA%d\n",
+ (display_source & 0x01) + 1);
+}
+
+/*
+ * Sets DVP1 (Digital Video Port 1) I/O pad state.
+ */
+static inline void
+via_dvp1_set_io_pad_state(void __iomem *regs, u8 io_pad_state)
+{
+ /* 3C5.1E[5:4] - DVP1 Power Control
+ * 0x: Pad always off
+ * 10: Depend on the other control signal
+ * 11: Pad on/off according to the
+ * Power Management Status (PMS) */
+ svga_wseq_mask(regs, 0x1E, io_pad_state << 4, BIT(5) | BIT(4));
+ DRM_DEBUG_KMS("DVP1 I/O Pad State: %s\n",
+ ((io_pad_state & (BIT(1) | BIT(0))) == 0x03) ? "On" :
+ ((io_pad_state & (BIT(1) | BIT(0))) == 0x02) ? "Conditional" :
+ ((io_pad_state & (BIT(1) | BIT(0))) == 0x01) ? "Off" :
+ "Off");
+}
+
+/*
+ * Sets DVP1 (Digital Video Port 1) clock I/O pad drive strength.
+ */
+static inline void
+via_dvp1_set_clock_drive_strength(void __iomem *regs,
+ u8 clock_drive_strength)
+{
+ /* 3C5.65[3:2] - DVP1 Clock Pads Driving Select [1:0]
+ * 00: lowest
+ * 01: low
+ * 10: high
+ * 11: highest */
+ svga_wseq_mask(regs, 0x65,
+ clock_drive_strength << 2, BIT(3) | BIT(2));
+ DRM_DEBUG_KMS("DVP1 Clock I/O Pad Drive Strength: %lu\n",
+ clock_drive_strength & (BIT(1) | BIT(0)));
+}
+
+/*
+ * Sets DVP1 (Digital Video Port 1) data I/O pads drive strength.
+ */
+static inline void
+via_dvp1_set_data_drive_strength(void __iomem *regs,
+ u8 data_drive_strength)
+{
+ /* 3C5.65[1:0] - DVP1 Data Pads Driving Select [1:0}
+ * 00: lowest
+ * 01: low
+ * 10: high
+ * 11: highest */
+ svga_wseq_mask(regs, 0x65,
+ data_drive_strength, BIT(1) | BIT(0));
+ DRM_DEBUG_KMS("DVP1 Data I/O Pads Drive Strength: %lu\n",
+ data_drive_strength & (BIT(1) | BIT(0)));
+}
+
+/*
+ * Sets the display source of DVP1 (Digital Video Port 1) interface.
+ */
+static inline void
+via_dvp1_set_display_source(void __iomem *regs, u8 display_source)
+{
+ /* 3X5.9B[4] - DVP1 Data Source Selection
+ * 0: Primary Display
+ * 1: Secondary Display */
+ svga_wcrt_mask(regs, 0x9B, display_source << 4, BIT(4));
+ DRM_DEBUG_KMS("DVP1 Display Source: IGA%d\n",
+ (display_source & 0x01) + 1);
+}
+
+/*
+ * Sets analog (VGA) DAC power.
+ */
+static inline void via_dac_set_power(void __iomem *regs, bool output_state)
+{
+ /* 3X5.47[2] - DACOFF Backdoor Register
+ * 0: DAC on
+ * 1: DAC off */
+ svga_wcrt_mask(regs, 0x47,
+ output_state ? 0x00 : BIT(2), BIT(2));
+ DRM_DEBUG_KMS("Analog (VGA) Power: %s\n",
+ output_state ? "On" : "Off");
+}
+
+/*
+ * Sets analog (VGA) DPMS state.
+ */
+static inline void via_dac_set_dpms_control(void __iomem *regs,
+ u8 dpms_control)
+{
+ /* 3X5.36[5:4] - DPMS Control
+ * 00: On
+ * 01: Stand-by
+ * 10: Suspend
+ * 11: Off */
+ svga_wcrt_mask(regs, 0x36,
+ dpms_control << 4, BIT(5) | BIT(4));
+ DRM_DEBUG_KMS("Analog (VGA) DPMS: %s\n",
+ ((dpms_control & (BIT(1) | BIT(0))) == 0x03) ?
+ "Off" :
+ ((dpms_control & (BIT(1) | BIT(0))) == 0x02) ?
+ "Suspend" :
+ ((dpms_control & (BIT(1) | BIT(0))) == 0x01) ?
+ "Standby" :
+ "On");
+}
+
+/*
+ * Sets analog (VGA) sync polarity.
+ */
+static inline void via_dac_set_sync_polarity(void __iomem *regs,
+ u8 sync_polarity)
+{
+ /* 3C2[7] - Analog Vertical Sync Polarity
+ * 0: Positive
+ * 1: Negative
+ * 3C2[6] - Analog Horizontal Sync Polarity
+ * 0: Positive
+ * 1: Negative */
+ svga_wmisc_mask(regs,
+ sync_polarity << 6, (BIT(1) | BIT(0)) << 6);
+ DRM_DEBUG_KMS("Analog (VGA) Horizontal Sync Polarity: %s\n",
+ (sync_polarity & BIT(0)) ? "-" : "+");
+ DRM_DEBUG_KMS("Analog (VGA) Vertical Sync Polarity: %s\n",
+ (sync_polarity & BIT(1)) ? "-" : "+");
+}
+
+/*
+ * Sets analog (VGA) display source.
+ */
+static inline void via_dac_set_display_source(void __iomem *regs,
+ u8 display_source)
+{
+ /* 3C5.16[6] - CRT Display Source
+ * 0: Primary Display Stream (IGA1)
+ * 1: Secondary Display Stream (IGA2) */
+ svga_wseq_mask(regs, 0x16,
+ display_source << 6, BIT(6));
+ DRM_DEBUG_KMS("Analog (VGA) Display Source: IGA%d\n",
+ (display_source & 0x01) + 1);
+}
+
+/*
+ * Sets KM400 or later chipset's FP primary power sequence control
+ * type.
+ */
+static inline void via_lvds_set_primary_power_seq_type(void __iomem *regs,
+ bool ctrl_type)
+{
+ /* 3X5.91[0] - FP Primary Power Sequence Control Type
+ * 0: Hardware Control
+ * 1: Software Control */
+ svga_wcrt_mask(regs, 0x91,
+ ctrl_type ? 0x00 : BIT(0), BIT(0));
+ DRM_DEBUG_KMS("FP Primary Power Sequence Control Type: "
+ "%s Control\n",
+ ctrl_type ? "Hardware" : "Software");
+}
+
+/*
+ * Sets KM400 or later chipset's FP primary software controlled
+ * back light.
+ */
+static inline void via_lvds_set_primary_soft_back_light(void __iomem *regs,
+ bool soft_on)
+{
+ /* 3X5.91[1] - FP Primary Software Back Light On
+ * 0: Off
+ * 1: On */
+ svga_wcrt_mask(regs, 0x91,
+ soft_on ? BIT(1) : 0x00, BIT(1));
+ DRM_DEBUG_KMS("FP Primary Software Controlled Back Light: "
+ "%s\n", soft_on ? "On" : "Off");
+}
+
+/*
+ * Sets KM400 or later chipset's FP primary software controlled
+ * VEE.
+ */
+static inline void via_lvds_set_primary_soft_vee(void __iomem *regs,
+ bool soft_on)
+{
+ /* 3X5.91[2] - FP Primary Software VEE On
+ * 0: Off
+ * 1: On */
+ svga_wcrt_mask(regs, 0x91,
+ soft_on ? BIT(2) : 0x00, BIT(2));
+ DRM_DEBUG_KMS("FP Primary Software Controlled VEE: %s\n",
+ soft_on ? "On" : "Off");
+}
+
+/*
+ * Sets KM400 or later chipset's FP primary software controlled
+ * data.
+ */
+static inline void via_lvds_set_primary_soft_data(void __iomem *regs,
+ bool soft_on)
+{
+ /* 3X5.91[3] - FP Primary Software Data On
+ * 0: Off
+ * 1: On */
+ svga_wcrt_mask(regs, 0x91,
+ soft_on ? BIT(3) : 0x00, BIT(3));
+ DRM_DEBUG_KMS("FP Primary Software Controlled Data: %s\n",
+ soft_on ? "On" : "Off");
+}
+
+/*
+ * Sets KM400 or later chipset's FP primary software controlled
+ * VDD.
+ */
+static inline void via_lvds_set_primary_soft_vdd(void __iomem *regs,
+ bool soft_on)
+{
+ /* 3X5.91[4] - FP Primary Software VDD On
+ * 0: Off
+ * 1: On */
+ svga_wcrt_mask(regs, 0x91,
+ soft_on ? BIT(4) : 0x00, BIT(4));
+ DRM_DEBUG_KMS("FP Primary Software Controlled VDD: %s\n",
+ soft_on ? "On" : "Off");
+}
+
+/*
+ * Sets KM400 or later chipset's FP primary direct back
+ * light control.
+ */
+static inline void via_lvds_set_primary_direct_back_light_ctrl(
+ void __iomem *regs, bool direct_on)
+{
+ /* 3X5.91[6] - FP Primary Direct Back Light Control
+ * 0: On
+ * 1: Off */
+ svga_wcrt_mask(regs, 0x91,
+ direct_on ? 0x00 : BIT(6), BIT(6));
+ DRM_DEBUG_KMS("FP Primary Direct Back Light Control: %s\n",
+ direct_on ? "On" : "Off");
+}
+
+/*
+ * Sets KM400 or later chipset's FP primary direct display
+ * period control.
+ */
+static inline void via_lvds_set_primary_direct_display_period(
+ void __iomem *regs, bool direct_on)
+{
+ /* 3X5.91[7] - FP Primary Direct Display Period Control
+ * 0: On
+ * 1: Off */
+ svga_wcrt_mask(regs, 0x91,
+ direct_on ? 0x00 : BIT(7), BIT(7));
+ DRM_DEBUG_KMS("FP Primary Direct Display Period Control: %s\n",
+ direct_on ? "On" : "Off");
+}
+
+/*
+ * Sets KM400 or later chipset's FP primary hardware controlled
+ * power sequence.
+ */
+static inline void via_lvds_set_primary_hard_power(void __iomem *regs,
+ bool power_state)
+{
+ /* 3X5.6A[3] - FP Primary Hardware Controlled Power Sequence
+ * 0: Hardware Controlled Power Off
+ * 1: Hardware Controlled Power On */
+ svga_wcrt_mask(regs, 0x6A,
+ power_state ? BIT(3) : 0x00, BIT(3));
+ DRM_DEBUG_KMS("FP Primary Hardware Controlled Power "
+ "Sequence: %s\n", power_state ? "On" : "Off");
+}
+
+/*
+ * Sets CX700 / VX700 or later chipset's FP secondary
+ * power sequence control type.
+ */
+static inline void via_lvds_set_secondary_power_seq_type(void __iomem *regs,
+ bool ctrl_type)
+{
+ /* 3X5.D3[0] - FP Secondary Power Sequence Control Type
+ * 0: Hardware Control
+ * 1: Software Control */
+ svga_wcrt_mask(regs, 0xD3,
+ ctrl_type ? 0x00 : BIT(0), BIT(0));
+ DRM_DEBUG_KMS("FP Secondary Power Sequence Control Type: "
+ "%s Control\n",
+ ctrl_type ? "Hardware" : "Software");
+}
+
+/*
+ * Sets CX700 / VX700 or later chipset's FP secondary
+ * software controlled back light.
+ */
+static inline void via_lvds_set_secondary_soft_back_light(void __iomem *regs,
+ bool soft_on)
+{
+ /* 3X5.D3[1] - FP Secondary Software Back Light On
+ * 0: Off
+ * 1: On */
+ svga_wcrt_mask(regs, 0xD3,
+ soft_on ? BIT(1) : 0x00, BIT(1));
+ DRM_DEBUG_KMS("FP Secondary Software Controlled Back Light: "
+ "%s\n", soft_on ? "On" : "Off");
+}
+
+/*
+ * Sets CX700 / VX700 or later chipset's FP secondary software
+ * controlled VEE.
+ */
+static inline void via_lvds_set_secondary_soft_vee(void __iomem *regs,
+ bool soft_on)
+{
+ /* 3X5.D3[2] - FP Secondary Software VEE On
+ * 0: Off
+ * 1: On */
+ svga_wcrt_mask(regs, 0xD3,
+ soft_on ? BIT(2) : 0x00, BIT(2));
+ DRM_DEBUG_KMS("FP Secondary Software Controlled VEE: %s\n",
+ soft_on ? "On" : "Off");
+}
+
+/*
+ * Sets CX700 / VX700 or later chipset's FP secondary software
+ * controlled data.
+ */
+static inline void via_lvds_set_secondary_soft_data(void __iomem *regs,
+ bool soft_on)
+{
+ /* 3X5.D3[3] - FP Secondary Software Data On
+ * 0: Off
+ * 1: On */
+ svga_wcrt_mask(regs, 0xD3,
+ soft_on ? BIT(3) : 0x00, BIT(3));
+ DRM_DEBUG_KMS("FP Secondary Software Controlled Data: %s\n",
+ soft_on ? "On" : "Off");
+}
+
+/*
+ * Sets CX700 / VX700 or later chipset's FP secondary software
+ * controlled VDD.
+ */
+static inline void via_lvds_set_secondary_soft_vdd(void __iomem *regs,
+ bool soft_on)
+{
+ /* 3X5.D3[4] - FP Secondary Software VDD On
+ * 0: Off
+ * 1: On */
+ svga_wcrt_mask(regs, 0xD3,
+ soft_on ? BIT(4) : 0x00, BIT(4));
+ DRM_DEBUG_KMS("FP Secondary Software Controlled VDD: %s\n",
+ soft_on ? "On" : "Off");
+}
+
+/*
+ * Sets CX700 / VX700 or later chipset's FP secondary direct back
+ * light control.
+ */
+static inline void via_lvds_set_secondary_direct_back_light_ctrl(
+ void __iomem *regs, bool direct_on)
+{
+ /* 3X5.D3[6] - FP Secondary Direct Back Light Control
+ * 0: On
+ * 1: Off */
+ svga_wcrt_mask(regs, 0xD3,
+ direct_on ? 0x00 : BIT(6), BIT(6));
+ DRM_DEBUG_KMS("FP Secondary Direct Back Light "
+ "Control: %s\n", direct_on ? "On" : "Off");
+}
+
+/*
+ * Sets CX700 / VX700 or later chipset's FP secondary direct
+ * display period control.
+ */
+static inline void via_lvds_set_secondary_direct_display_period(
+ void __iomem *regs, bool direct_on)
+{
+ /* 3X5.D3[7] - FP Secondary Direct Display Period Control
+ * 0: On
+ * 1: Off */
+ svga_wcrt_mask(regs, 0xD3,
+ direct_on ? 0x00 : BIT(7), BIT(7));
+ DRM_DEBUG_KMS("FP Secondary Direct Display Period "
+ "Control: %s\n", direct_on ? "On" : "Off");
+}
+
+/*
+ * Sets FP secondary hardware controlled power sequence enable.
+ */
+static inline void via_lvds_set_secondary_hard_power(void __iomem *regs,
+ bool power_state)
+{
+ /* 3X5.D4[1] - Secondary Power Hardware Power Sequence Enable
+ * 0: Off
+ * 1: On */
+ svga_wcrt_mask(regs, 0xD4,
+ power_state ? BIT(1) : 0x00, BIT(1));
+ DRM_DEBUG_KMS("FP Secondary Hardware Controlled Power "
+ "Sequence: %s\n", power_state ? "On" : "Off");
+}
+
+/*
+ * Sets FPDP (Flat Panel Display Port) Low I/O pad state.
+ */
+static inline void
+via_fpdp_low_set_io_pad_state(void __iomem *regs, u8 io_pad_state)
+{
+ /* 3C5.2A[1:0] - FPDP Low I/O Pad Control
+ * 0x: Pad always off
+ * 10: Depend on the other control signal
+ * 11: Pad on/off according to the
+ * Power Management Status (PMS) */
+ svga_wseq_mask(regs, 0x2A,
+ io_pad_state, BIT(1) | BIT(0));
+ DRM_DEBUG_KMS("FPDP Low I/O Pad State: %s\n",
+ ((io_pad_state & (BIT(1) | BIT(0))) == 0x03) ?
+ "On" :
+ ((io_pad_state & (BIT(1) | BIT(0))) == 0x02) ?
+ "Conditional" :
+ ((io_pad_state & (BIT(1) | BIT(0))) == 0x01) ?
+ "Off" :
+ "Off");
+}
+
+/*
+ * Sets FPDP (Flat Panel Display Port) Low adjustment register.
+ */
+static inline void
+via_fpdp_low_set_adjustment(void __iomem *regs, u8 adjustment)
+{
+ /* 3X5.99[3:0] - FPDP Low Adjustment */
+ svga_wcrt_mask(regs, 0x99,
+ adjustment, BIT(3) | BIT(2) | BIT(1) | BIT(0));
+ DRM_DEBUG_KMS("FPDP Low Adjustment: %lu\n",
+ (adjustment & (BIT(3) | BIT(2) |
+ BIT(1) | BIT(0))));
+}
+
+/*
+ * Sets FPDP (Flat Panel Display Port) Low interface display source.
+ */
+static inline void
+via_fpdp_low_set_display_source(void __iomem *regs, u8 display_source)
+{
+ /* 3X5.99[4] - FPDP Low Data Source Selection
+ * 0: Primary Display
+ * 1: Secondary Display */
+ svga_wcrt_mask(regs, 0x99,
+ display_source << 4, BIT(4));
+ DRM_DEBUG_KMS("FPDP Low Display Source: IGA%d\n",
+ (display_source & 0x01) + 1);
+}
+
+/*
+ * Sets FPDP (Flat Panel Display Port) High I/O pad state.
+ */
+static inline void
+via_fpdp_high_set_io_pad_state(void __iomem *regs, u8 io_pad_state)
+{
+ /* 3C5.2A[3:2] - FPDP High I/O Pad Control
+ * 0x: Pad always off
+ * 10: Depend on the other control signal
+ * 11: Pad on/off according to the
+ * Power Management Status (PMS) */
+ svga_wseq_mask(regs, 0x2A,
+ io_pad_state << 2, BIT(3) | BIT(2));
+ DRM_DEBUG_KMS("FPDP High I/O Pad State: %s\n",
+ ((io_pad_state & (BIT(1) | BIT(0))) == 0x03) ?
+ "On" :
+ ((io_pad_state & (BIT(1) | BIT(0))) == 0x02) ?
+ "Conditional" :
+ ((io_pad_state & (BIT(1) | BIT(0))) == 0x01) ?
+ "Off" :
+ "Off");
+}
+
+/*
+ * Sets FPDP (Flat Panel Display Port) High adjustment register.
+ */
+static inline void
+via_fpdp_high_set_adjustment(void __iomem *regs, u8 adjustment)
+{
+ /* 3X5.97[3:0] - FPDP High Adjustment */
+ svga_wcrt_mask(regs, 0x97,
+ adjustment, BIT(3) | BIT(2) | BIT(1) | BIT(0));
+ DRM_DEBUG_KMS("FPDP High Adjustment: %lu\n",
+ (adjustment & (BIT(3) | BIT(2) |
+ BIT(1) | BIT(0))));
+}
+
+/*
+ * Sets FPDP (Flat Panel Display Port) High interface display source.
+ */
+static inline void
+via_fpdp_high_set_display_source(void __iomem *regs, u8 display_source)
+{
+ /* 3X5.97[4] - FPDP High Data Source Selection
+ * 0: Primary Display
+ * 1: Secondary Display */
+ svga_wcrt_mask(regs, 0x97,
+ display_source << 4, BIT(4));
+ DRM_DEBUG_KMS("FPDP High Display Source: IGA%d\n",
+ (display_source & 0x01) + 1);
+}
+
+/*
+ * Sets CX700 / VX700 or later chipset's LVDS1 power state.
+ */
+static inline void
+via_lvds1_set_power(void __iomem *regs, bool power_state)
+{
+ /* 3X5.D2[7] - Power Down (Active High) for Channel 1 LVDS
+ * 0: Power on
+ * 1: Power off */
+ svga_wcrt_mask(regs, 0xD2,
+ power_state ? 0x00 : BIT(7), BIT(7));
+ DRM_DEBUG_KMS("LVDS1 Power State: %s\n",
+ power_state ? "On" : "Off");
+}
+
+/*
+ * Sets CX700 or later single chipset's LVDS1 power sequence type.
+ */
+static inline void
+via_lvds1_set_power_seq(void __iomem *regs, bool softCtrl)
+{
+ /* Set LVDS1 power sequence type. */
+ /* 3X5.91[0] - LVDS1 Hardware or Software Control Power Sequence
+ * 0: Hardware Control
+ * 1: Software Control */
+ svga_wcrt_mask(regs, 0x91, softCtrl ? BIT(0) : 0, BIT(0));
+ DRM_DEBUG_KMS("LVDS1 Power Sequence: %s Control\n",
+ softCtrl ? "Software" : "Hardware");
+}
+
+/*
+ * Sets CX700 or later single chipset's LVDS1 software controlled
+ * data path state.
+ */
+static inline void
+via_lvds1_set_soft_data(void __iomem *regs, bool softOn)
+{
+ /* Set LVDS1 software controlled data path state. */
+ /* 3X5.91[3] - Software Data On
+ * 0: Off
+ * 1: On */
+ svga_wcrt_mask(regs, 0x91, softOn ? BIT(3) : 0, BIT(3));
+ DRM_DEBUG_KMS("LVDS1 Software Controlled Data Path: %s\n",
+ softOn ? "On" : "Off");
+}
+
+/*
+ * Sets CX700 or later single chipset's LVDS1 software controlled Vdd.
+ */
+static inline void
+via_lvds1_set_soft_vdd(void __iomem *regs, bool softOn)
+{
+ /* Set LVDS1 software controlled Vdd. */
+ /* 3X5.91[4] - Software VDD On
+ * 0: Off
+ * 1: On */
+ svga_wcrt_mask(regs, 0x91, softOn ? BIT(4) : 0, BIT(4));
+ DRM_DEBUG_KMS("LVDS1 Software Controlled Vdd: %s\n",
+ softOn ? "On" : "Off");
+}
+
+/*
+ * Sets CX700 or later single chipset's LVDS1 software controlled
+ * display period.
+ */
+static inline void
+via_lvds1_set_soft_display_period(void __iomem *regs, bool softOn)
+{
+ /* Set LVDS1 software controlled display period state. */
+ /* 3X5.91[7] - Software Direct On / Off Display Period
+ * in the Panel Path
+ * 0: On
+ * 1: Off */
+ svga_wcrt_mask(regs, 0x91, softOn ? 0 : BIT(7), BIT(7));
+ DRM_DEBUG_KMS("LVDS1 Software Controlled Display Period: %s\n",
+ softOn ? "On" : "Off");
+}
+
+/*
+ * Sets LVDS1 I/O pad state.
+ */
+static inline void
+via_lvds1_set_io_pad_setting(void __iomem *regs, u8 io_pad_state)
+{
+ /* 3C5.2A[1:0] - LVDS1 I/O Pad Control
+ * 0x: Pad always off
+ * 10: Depend on the other control signal
+ * 11: Pad on/off according to the
+ * Power Management Status (PMS) */
+ svga_wseq_mask(regs, 0x2A,
+ io_pad_state, BIT(1) | BIT(0));
+ DRM_DEBUG_KMS("LVDS1 I/O Pad State: %s\n",
+ ((io_pad_state & (BIT(1) | BIT(0))) == 0x03) ?
+ "On" :
+ ((io_pad_state & (BIT(1) | BIT(0))) == 0x02) ?
+ "Conditional" :
+ ((io_pad_state & (BIT(1) | BIT(0))) == 0x01) ?
+ "Off" :
+ "Off");
+}
+
+/*
+ * Sets LVDS1 format.
+ */
+static inline void
+via_lvds1_set_format(void __iomem *regs, u8 format)
+{
+ /* 3X5.D2[1] - LVDS Channel 1 Format Selection
+ * 0: SPWG Mode
+ * 1: OPENLDI Mode */
+ svga_wcrt_mask(regs, 0xd2,
+ format << 1, BIT(1));
+ DRM_DEBUG_KMS("LVDS1 Format: %s\n",
+ (format & BIT(0)) ? "OPENLDI" : "SPWG");
+}
+
+/*
+ * Sets LVDS1 output format (rotation or sequential mode).
+ */
+static inline void
+via_lvds1_set_output_format(void __iomem *regs, u8 output_format)
+{
+ /* 3X5.88[6] - LVDS Channel 1 Output Format
+ * 0: Rotation
+ * 1: Sequential */
+ svga_wcrt_mask(regs, 0x88,
+ output_format << 6, BIT(6));
+ DRM_DEBUG_KMS("LVDS1 Output Format: %s\n",
+ (output_format & BIT(0)) ?
+ "Sequential" : "Rotation");
+}
+
+/*
+ * Sets LVDS1 output color dithering (18-bit color display vs.
+ * 24-bit color display).
+ */
+static inline void
+via_lvds1_set_dithering(void __iomem *regs, bool dithering)
+{
+ /* 3X5.88[0] - LVDS Channel 1 Output Bits
+ * 0: 24 bits (dithering off)
+ * 1: 18 bits (dithering on) */
+ svga_wcrt_mask(regs, 0x88,
+ dithering ? BIT(0) : 0x00, BIT(0));
+ DRM_DEBUG_KMS("LVDS1 Color Dithering: %s\n",
+ dithering ?
+ "On (18 bit color)" : "Off (24 bit color)");
+}
+
+/*
+ * Sets LVDS1 display source.
+ */
+static inline void
+via_lvds1_set_display_source(void __iomem *regs, u8 display_source)
+{
+ /* 3X5.99[4] - LVDS Channel 1 Data Source Selection
+ * 0: Primary Display
+ * 1: Secondary Display */
+ svga_wcrt_mask(regs, 0x99,
+ display_source << 4, BIT(4));
+ DRM_DEBUG_KMS("LVDS1 Display Source: IGA%d\n",
+ (display_source & 0x01) + 1);
+}
+
+/*
+ * Sets CX700 / VX700 and VX800 chipset's LVDS2 power state.
+ */
+static inline void
+via_lvds2_set_power(void __iomem *regs, bool power_state)
+{
+ /* 3X5.D2[6] - Power Down (Active High) for Channel 2 LVDS
+ * 0: Power on
+ * 1: Power off */
+ svga_wcrt_mask(regs, 0xD2,
+ power_state ? 0x00 : BIT(6), BIT(6));
+ DRM_DEBUG_KMS("LVDS2 Power State: %s\n",
+ power_state ? "On" : "Off");
+}
+
+/*
+ * Sets LVDS2 I/O pad state.
+ */
+static inline void
+via_lvds2_set_io_pad_setting(void __iomem *regs, u8 io_pad_state)
+{
+ /* 3C5.2A[3:2] - LVDS2 I/O Pad Control
+ * 0x: Pad always off
+ * 10: Depend on the other control signal
+ * 11: Pad on/off according to the
+ * Power Management Status (PMS) */
+ svga_wseq_mask(regs, 0x2A,
+ io_pad_state << 2, BIT(3) | BIT(2));
+ DRM_DEBUG_KMS("LVDS2 I/O Pad State: %s\n",
+ ((io_pad_state & (BIT(1) | BIT(0))) == 0x03) ?
+ "On" :
+ ((io_pad_state & (BIT(1) | BIT(0))) == 0x02) ?
+ "Conditional" :
+ ((io_pad_state & (BIT(1) | BIT(0))) == 0x01) ?
+ "Off" :
+ "Off");
+}
+
+/*
+ * Sets LVDS2 format.
+ */
+static inline void
+via_lvds2_set_format(void __iomem *regs, u8 format)
+{
+ /* 3X5.D2[0] - LVDS Channel 2 Format Selection
+ * 0: SPWG Mode
+ * 1: OPENLDI Mode */
+ svga_wcrt_mask(regs, 0xd2, format, BIT(0));
+ DRM_DEBUG_KMS("LVDS2 Format: %s\n",
+ (format & BIT(0)) ? "OPENLDI" : "SPWG");
+}
+
+/*
+ * Sets LVDS2 output format (rotation or sequential mode).
+ */
+static inline void
+via_lvds2_set_output_format(void __iomem *regs, u8 output_format)
+{
+ /* 3X5.D4[7] - LVDS Channel 2 Output Format
+ * 0: Rotation
+ * 1: Sequential */
+ svga_wcrt_mask(regs, 0xd4, output_format << 7, BIT(7));
+ DRM_DEBUG_KMS("LVDS2 Output Format: %s\n",
+ (output_format & BIT(0)) ?
+ "Sequential" : "Rotation");
+}
+
+/*
+ * Sets LVDS2 output color dithering (18-bit color display vs.
+ * 24-bit color display).
+ */
+static inline void
+via_lvds2_set_dithering(void __iomem *regs, bool dithering)
+{
+ /* 3X5.D4[6] - LVDS Channel 2 Output Bits
+ * 0: 24 bits (dithering off)
+ * 1: 18 bits (dithering on) */
+ svga_wcrt_mask(regs, 0xd4,
+ dithering ? BIT(6) : 0x00, BIT(6));
+ DRM_DEBUG_KMS("LVDS2 Color Dithering: %s\n",
+ dithering ?
+ "On (18 bit color)" : "Off (24 bit color)");
+}
+
+/*
+ * Sets LVDS2 display source.
+ */
+static inline void
+via_lvds2_set_display_source(void __iomem *regs, u8 display_source)
+{
+ /* 3X5.97[4] - LVDS Channel 2 Data Source Selection
+ * 0: Primary Display
+ * 1: Secondary Display */
+ svga_wcrt_mask(regs, 0x97,
+ display_source << 4, BIT(4));
+ DRM_DEBUG_KMS("LVDS2 Display Source: IGA%d\n",
+ (display_source & 0x01) + 1);
+}
+
+/*
+ * Sets CX700 / VX700 and VX800 chipsets' TMDS (DVI) power state.
+ */
+static inline void
+via_tmds_set_power(void __iomem *regs, bool powerState)
+{
+ /* 3X5.D2[3] - Power Down (Active High) for DVI
+ * 0: TMDS power on
+ * 1: TMDS power down */
+ svga_wcrt_mask(regs, 0xD2,
+ powerState ? 0x00 : BIT(3), BIT(3));
+ DRM_DEBUG_KMS("TMDS (DVI) Power State: %s\n",
+ powerState ? "On" : "Off");
+}
+
+/*
+ * Sets CX700 / VX700 and VX800 chipsets' TMDS (DVI) sync polarity.
+ */
+static inline void
+via_tmds_set_sync_polarity(void __iomem *regs, u8 syncPolarity)
+{
+ /* Set TMDS (DVI) sync polarity. */
+ /* 3X5.97[6] - DVI (TMDS) VSYNC Polarity
+ * 0: Positive
+ * 1: Negative
+ * 3X5.97[5] - DVI (TMDS) HSYNC Polarity
+ * 0: Positive
+ * 1: Negative */
+ svga_wcrt_mask(regs, 0x97,
+ syncPolarity << 5, BIT(6) | BIT(5));
+ DRM_DEBUG_KMS("TMDS (DVI) Horizontal Sync Polarity: %s\n",
+ (syncPolarity & BIT(0)) ? "-" : "+");
+ DRM_DEBUG_KMS("TMDS (DVI) Vertical Sync Polarity: %s\n",
+ (syncPolarity & BIT(1)) ? "-" : "+");
+}
+
+/*
+ * Sets TMDS (DVI) display source.
+ */
+static inline void
+via_tmds_set_display_source(void __iomem *regs, u8 displaySource)
+{
+ /* The integrated TMDS transmitter appears to utilize LVDS1's
+ * data source selection bit (3X5.99[4]). */
+ /* 3X5.99[4] - LVDS Channel1 Data Source Selection
+ * 0: Primary Display
+ * 1: Secondary Display */
+ svga_wcrt_mask(regs, 0x99,
+ displaySource << 4, BIT(4));
+ DRM_DEBUG_KMS("TMDS (DVI) Display Source: IGA%d\n",
+ (displaySource & 0x01) + 1);
+}
+
+
+void load_register_tables(void __iomem *regbase, struct vga_registers *regs);
+void load_value_to_registers(void __iomem *regbase, struct vga_registers *regs,
+ unsigned int value);
+
+#endif /* __CRTC_HW_H__ */
--
2.35.1
More information about the dri-devel
mailing list