x86: quark: Initialize thermal sensor properly
authorBin Meng <bmeng.cn@gmail.com>
Thu, 10 Sep 2015 06:20:27 +0000 (23:20 -0700)
committerSimon Glass <sjg@chromium.org>
Thu, 17 Sep 2015 01:53:53 +0000 (19:53 -0600)
Thermal sensor on Quark SoC needs to be properly initialized per
Quark firmware writer guide, otherwise when booting Linux kernel,
it triggers system shutdown because of wrong temperature in the
thermal sensor is detected by the kernel driver (see below):

[    5.119819] thermal_sys: Critical temperature reached(206 C),shutting down
[    5.128997] Failed to start orderly shutdown: forcing the issue
[    5.135495] Emergency Sync complete

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Acked-by: Simon Glass <sjg@chromium.org>
arch/x86/cpu/quark/quark.c
arch/x86/include/asm/arch-quark/quark.h

index 3ddf079..8b78a86 100644 (file)
@@ -134,6 +134,43 @@ static void quark_usb_early_init(void)
        msg_port_alt_setbits(MSG_PORT_USB_AFE, USB2_PLL2, 1 << 24);
 }
 
+static void quark_thermal_early_init(void)
+{
+       /* The sequence below comes from Quark firmware writer guide */
+
+       /* thermal sensor mode config */
+       msg_port_alt_clrsetbits(MSG_PORT_SOC_UNIT, TS_CFG1,
+                               (1 << 3) | (1 << 4) | (1 << 5), 1 << 5);
+       msg_port_alt_clrsetbits(MSG_PORT_SOC_UNIT, TS_CFG1,
+                               (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) |
+                               (1 << 12), 1 << 9);
+       msg_port_alt_setbits(MSG_PORT_SOC_UNIT, TS_CFG1, 1 << 14);
+       msg_port_alt_clrbits(MSG_PORT_SOC_UNIT, TS_CFG1, 1 << 17);
+       msg_port_alt_clrbits(MSG_PORT_SOC_UNIT, TS_CFG1, 1 << 18);
+       msg_port_alt_clrsetbits(MSG_PORT_SOC_UNIT, TS_CFG2, 0xffff, 0x011f);
+       msg_port_alt_clrsetbits(MSG_PORT_SOC_UNIT, TS_CFG3, 0xff, 0x17);
+       msg_port_alt_clrsetbits(MSG_PORT_SOC_UNIT, TS_CFG3,
+                               (1 << 8) | (1 << 9), 1 << 8);
+       msg_port_alt_clrbits(MSG_PORT_SOC_UNIT, TS_CFG3, 0xff000000);
+       msg_port_alt_clrsetbits(MSG_PORT_SOC_UNIT, TS_CFG4,
+                               0x7ff800, 0xc8 << 11);
+
+       /* thermal monitor catastrophic trip set point (105 celsius) */
+       msg_port_clrsetbits(MSG_PORT_RMU, TS_TRIP, 0xff, 155);
+
+       /* thermal monitor catastrophic trip clear point (0 celsius) */
+       msg_port_clrsetbits(MSG_PORT_RMU, TS_TRIP, 0xff0000, 50 << 16);
+
+       /* take thermal sensor out of reset */
+       msg_port_alt_clrbits(MSG_PORT_SOC_UNIT, TS_CFG4, 1 << 0);
+
+       /* enable thermal monitor */
+       msg_port_setbits(MSG_PORT_RMU, TS_MODE, 1 << 15);
+
+       /* lock all thermal configuration */
+       msg_port_setbits(MSG_PORT_RMU, RMU_CTRL, (1 << 5) | (1 << 6));
+}
+
 static void quark_enable_legacy_seg(void)
 {
        msg_port_setbits(MSG_PORT_HOST_BRIDGE, HMISC2,
@@ -173,6 +210,9 @@ int arch_cpu_init(void)
        /* Initialize USB2 PHY */
        quark_usb_early_init();
 
+       /* Initialize thermal sensor */
+       quark_thermal_early_init();
+
        /* Turn on legacy segments (A/B/E/F) decode to system RAM */
        quark_enable_legacy_seg();
 
index 338c896..f6009f6 100644 (file)
 /* ACPI PBLK Base Address Register */
 #define PBLK_BA                        0x70
 
+/* Control Register */
+#define RMU_CTRL               0x71
+
 /* SPI DMA Base Address Register */
 #define SPI_DMA_BA             0x7a
 
+/* Thermal Sensor Register */
+#define TS_MODE                        0xb0
+#define TS_TEMP                        0xb1
+#define TS_TRIP                        0xb2
+
 /* Port 0x05: Memory Manager Message Port Registers */
 
 /* eSRAM Block Page Control */
 
 /* Port 0x31: SoC Unit Port Registers */
 
+/* Thermal Sensor Config */
+#define TS_CFG1                        0x31
+#define TS_CFG2                        0x32
+#define TS_CFG3                        0x33
+#define TS_CFG4                        0x34
+
 /* PCIe Controller Config */
 #define PCIE_CFG               0x36
 #define PCIE_CTLR_PRI_RST      0x00010000