|
@@ -18,6 +18,8 @@
|
|
|
**************************************************************************/
|
|
|
|
|
|
#include <linux/backlight.h>
|
|
|
+#include <linux/module.h>
|
|
|
+#include <linux/dmi.h>
|
|
|
#include <drm/drmP.h>
|
|
|
#include <drm/drm.h>
|
|
|
#include "psb_drm.h"
|
|
@@ -28,7 +30,33 @@
|
|
|
#include <asm/intel_scu_ipc.h>
|
|
|
#include "mid_bios.h"
|
|
|
|
|
|
-static const struct psb_ops oaktrail_chip_ops;
|
|
|
+static int devtype;
|
|
|
+
|
|
|
+module_param_named(type, devtype, int, 0600);
|
|
|
+MODULE_PARM_DESC(type, "Moorestown/Oaktrail device type");
|
|
|
+
|
|
|
+#define DEVICE_MOORESTOWN 1
|
|
|
+#define DEVICE_OAKTRAIL 2
|
|
|
+#define DEVICE_MOORESTOWN_MM 3
|
|
|
+
|
|
|
+static int mrst_device_ident(struct drm_device *dev)
|
|
|
+{
|
|
|
+ /* User forced */
|
|
|
+ if (devtype)
|
|
|
+ return devtype;
|
|
|
+ if (dmi_match(DMI_PRODUCT_NAME, "OakTrail") ||
|
|
|
+ dmi_match(DMI_PRODUCT_NAME, "OakTrail platform"))
|
|
|
+ return DEVICE_OAKTRAIL;
|
|
|
+#if defined(CONFIG_X86_MRST)
|
|
|
+ if (dmi_match(DMI_PRODUCT_NAME, "MM") ||
|
|
|
+ dmi_match(DMI_PRODUCT_NAME, "MM 10"))
|
|
|
+ return DEVICE_MOORESTOWN_MM;
|
|
|
+ if (mrst_identify_cpu())
|
|
|
+ return DEVICE_MOORESTOWN;
|
|
|
+#endif
|
|
|
+ return DEVICE_OAKTRAIL;
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
/* IPC message and command defines used to enable/disable mipi panel voltages */
|
|
|
#define IPC_MSG_PANEL_ON_OFF 0xE9
|
|
@@ -266,8 +294,10 @@ static int mrst_save_display_registers(struct drm_device *dev)
|
|
|
dev_priv->saveOV_OGAMC5 = PSB_RVDC32(OV_OGAMC5);
|
|
|
|
|
|
/* DPST registers */
|
|
|
- dev_priv->saveHISTOGRAM_INT_CONTROL_REG = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
|
|
|
- dev_priv->saveHISTOGRAM_LOGIC_CONTROL_REG = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
|
|
|
+ dev_priv->saveHISTOGRAM_INT_CONTROL_REG =
|
|
|
+ PSB_RVDC32(HISTOGRAM_INT_CONTROL);
|
|
|
+ dev_priv->saveHISTOGRAM_LOGIC_CONTROL_REG =
|
|
|
+ PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
|
|
|
dev_priv->savePWM_CONTROL_LOGIC = PSB_RVDC32(PWM_CONTROL_LOGIC);
|
|
|
|
|
|
if (dev_priv->iLVDS_enable) {
|
|
@@ -282,7 +312,7 @@ static int mrst_save_display_registers(struct drm_device *dev)
|
|
|
PSB_WVDC32(0x58000000, DSPACNTR);
|
|
|
/* Trigger the plane disable */
|
|
|
PSB_WVDC32(0, DSPASURF);
|
|
|
-
|
|
|
+
|
|
|
/* Wait ~4 ticks */
|
|
|
msleep(4);
|
|
|
|
|
@@ -401,8 +431,10 @@ static int mrst_restore_display_registers(struct drm_device *dev)
|
|
|
PSB_WVDC32(dev_priv->saveOV_OGAMC5, OV_OGAMC5);
|
|
|
|
|
|
/* DPST registers */
|
|
|
- PSB_WVDC32(dev_priv->saveHISTOGRAM_INT_CONTROL_REG, HISTOGRAM_INT_CONTROL);
|
|
|
- PSB_WVDC32(dev_priv->saveHISTOGRAM_LOGIC_CONTROL_REG, HISTOGRAM_LOGIC_CONTROL);
|
|
|
+ PSB_WVDC32(dev_priv->saveHISTOGRAM_INT_CONTROL_REG,
|
|
|
+ HISTOGRAM_INT_CONTROL);
|
|
|
+ PSB_WVDC32(dev_priv->saveHISTOGRAM_LOGIC_CONTROL_REG,
|
|
|
+ HISTOGRAM_LOGIC_CONTROL);
|
|
|
PSB_WVDC32(dev_priv->savePWM_CONTROL_LOGIC, PWM_CONTROL_LOGIC);
|
|
|
|
|
|
return 0;
|
|
@@ -458,38 +490,44 @@ static int mrst_power_up(struct drm_device *dev)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int mrst_chip_setup(struct drm_device *dev)
|
|
|
+#if defined(CONFIG_X86_MRST)
|
|
|
+static void mrst_lvds_cache_bl(struct drm_device *dev)
|
|
|
{
|
|
|
struct drm_psb_private *dev_priv = dev->dev_private;
|
|
|
|
|
|
-#if defined(CONFIG_X86_MRST)
|
|
|
- if (mrst_identify_cpu())
|
|
|
- return mid_chip_setup(dev);
|
|
|
-#endif
|
|
|
- dev_priv->ops = &oaktrail_chip_ops;
|
|
|
- mrst_hdmi_setup(dev);
|
|
|
- /* Check - may be better to go via BIOS paths ? */
|
|
|
- return mid_chip_setup(dev);
|
|
|
+ intel_scu_ipc_ioread8(0x28, &(dev_priv->saveBKLTCNT));
|
|
|
+ intel_scu_ipc_ioread8(0x29, &(dev_priv->saveBKLTREQ));
|
|
|
+ intel_scu_ipc_ioread8(0x2A, &(dev_priv->saveBKLTBRTL));
|
|
|
}
|
|
|
|
|
|
-static void oaktrail_teardown(struct drm_device *dev)
|
|
|
+static void mrst_mm_bl_power(struct drm_device *dev, bool on)
|
|
|
{
|
|
|
- mrst_hdmi_teardown(dev);
|
|
|
+ struct drm_psb_private *dev_priv = dev->dev_private;
|
|
|
+
|
|
|
+ if (on) {
|
|
|
+ intel_scu_ipc_iowrite8(0x2A, dev_priv->saveBKLTBRTL);
|
|
|
+ intel_scu_ipc_iowrite8(0x28, dev_priv->saveBKLTCNT);
|
|
|
+ intel_scu_ipc_iowrite8(0x29, dev_priv->saveBKLTREQ);
|
|
|
+ } else {
|
|
|
+ intel_scu_ipc_iowrite8(0x2A, 0);
|
|
|
+ intel_scu_ipc_iowrite8(0x28, 0);
|
|
|
+ intel_scu_ipc_iowrite8(0x29, 0);
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
-const struct psb_ops mrst_chip_ops = {
|
|
|
- .name = "Moorestown",
|
|
|
+
|
|
|
+static const struct psb_ops mrst_mm_chip_ops = {
|
|
|
+ .name = "Moorestown MM ",
|
|
|
.accel_2d = 1,
|
|
|
.pipes = 1,
|
|
|
.crtcs = 1,
|
|
|
.sgx_offset = MRST_SGX_OFFSET,
|
|
|
|
|
|
- .chip_setup = mrst_chip_setup,
|
|
|
.crtc_helper = &mrst_helper_funcs,
|
|
|
.crtc_funcs = &psb_intel_crtc_funcs,
|
|
|
|
|
|
.output_init = mrst_output_init,
|
|
|
|
|
|
+ .lvds_bl_power = mrst_mm_bl_power,
|
|
|
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
|
|
|
.backlight_init = mrst_backlight_init,
|
|
|
#endif
|
|
@@ -499,8 +537,17 @@ const struct psb_ops mrst_chip_ops = {
|
|
|
.restore_regs = mrst_restore_display_registers,
|
|
|
.power_down = mrst_power_down,
|
|
|
.power_up = mrst_power_up,
|
|
|
+
|
|
|
+ .i2c_bus = 0,
|
|
|
};
|
|
|
|
|
|
+#endif
|
|
|
+
|
|
|
+static void oaktrail_teardown(struct drm_device *dev)
|
|
|
+{
|
|
|
+ mrst_hdmi_teardown(dev);
|
|
|
+}
|
|
|
+
|
|
|
static const struct psb_ops oaktrail_chip_ops = {
|
|
|
.name = "Oaktrail",
|
|
|
.accel_2d = 1,
|
|
@@ -524,5 +571,66 @@ static const struct psb_ops oaktrail_chip_ops = {
|
|
|
.restore_regs = mrst_restore_display_registers,
|
|
|
.power_down = mrst_power_down,
|
|
|
.power_up = mrst_power_up,
|
|
|
+
|
|
|
+ .i2c_bus = 1,
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ * mrst_chip_setup - perform the initial chip init
|
|
|
+ * @dev: Our drm_device
|
|
|
+ *
|
|
|
+ * Figure out which incarnation we are and then scan the firmware for
|
|
|
+ * tables and information.
|
|
|
+ */
|
|
|
+static int mrst_chip_setup(struct drm_device *dev)
|
|
|
+{
|
|
|
+ struct drm_psb_private *dev_priv = dev->dev_private;
|
|
|
+
|
|
|
+ switch (mrst_device_ident(dev)) {
|
|
|
+ case DEVICE_OAKTRAIL:
|
|
|
+ /* Dual CRTC, PC compatible, HDMI, I2C #2 */
|
|
|
+ dev_priv->ops = &oaktrail_chip_ops;
|
|
|
+ mrst_hdmi_setup(dev);
|
|
|
+ return mid_chip_setup(dev);
|
|
|
+#if defined(CONFIG_X86_MRST)
|
|
|
+ case DEVICE_MOORESTOWN_MM:
|
|
|
+ /* Single CRTC, No HDMI, I2C #0, BL control */
|
|
|
+ mrst_lvds_cache_bl(dev);
|
|
|
+ dev_priv->ops = &mrst_mm_chip_ops;
|
|
|
+ return mid_chip_setup(dev);
|
|
|
+ case DEVICE_MOORESTOWN:
|
|
|
+ /* Dual CRTC, No HDMI(?), I2C #1 */
|
|
|
+ return mid_chip_setup(dev);
|
|
|
+#endif
|
|
|
+ default:
|
|
|
+ dev_err(dev->dev, "unsupported device type.\n");
|
|
|
+ return -ENODEV;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const struct psb_ops mrst_chip_ops = {
|
|
|
+ .name = "Moorestown",
|
|
|
+ .accel_2d = 1,
|
|
|
+ .pipes = 2,
|
|
|
+ .crtcs = 2,
|
|
|
+ .sgx_offset = MRST_SGX_OFFSET,
|
|
|
+
|
|
|
+ .chip_setup = mrst_chip_setup,
|
|
|
+ .crtc_helper = &mrst_helper_funcs,
|
|
|
+ .crtc_funcs = &psb_intel_crtc_funcs,
|
|
|
+
|
|
|
+ .output_init = mrst_output_init,
|
|
|
+
|
|
|
+#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
|
|
|
+ .backlight_init = mrst_backlight_init,
|
|
|
+#endif
|
|
|
+
|
|
|
+ .init_pm = mrst_init_pm,
|
|
|
+ .save_regs = mrst_save_display_registers,
|
|
|
+ .restore_regs = mrst_restore_display_registers,
|
|
|
+ .power_down = mrst_power_down,
|
|
|
+ .power_up = mrst_power_up,
|
|
|
+
|
|
|
+ .i2c_bus = 2,
|
|
|
};
|
|
|
|