diff --git a/src/board/system76/galp3-c/main.c b/src/board/system76/galp3-c/main.c index 1a38d37..b2f12e5 100644 --- a/src/board/system76/galp3-c/main.c +++ b/src/board/system76/galp3-c/main.c @@ -49,7 +49,85 @@ void init(void) { //TODO: INTC, PECI - // PECI information can be found here: https://www.intel.com/content/dam/www/public/us/en/documents/design-guides/core-i7-lga-2011-guide.pdf + // Allow PECI pin to be used + GCR2 |= (1 << 4); +} + +// PECI information can be found here: https://www.intel.com/content/dam/www/public/us/en/documents/design-guides/core-i7-lga-2011-guide.pdf +void peci_event(void) { + static volatile uint8_t __xdata __at(0x3000) HOSTAR; + static volatile uint8_t __xdata __at(0x3001) HOCTLR; + static volatile uint8_t __xdata __at(0x3002) HOCMDR; + static volatile uint8_t __xdata __at(0x3003) HOTRADDR; + static volatile uint8_t __xdata __at(0x3004) HOWRLR; + static volatile uint8_t __xdata __at(0x3005) HORDLR; + static volatile uint8_t __xdata __at(0x3006) HOWRDR; + static volatile uint8_t __xdata __at(0x3007) HORDDR; + static volatile uint8_t __xdata __at(0x3008) HOCTL2R; + static volatile uint8_t __xdata __at(0x3009) RWFCSV; + + // Wait for completion + while (HOSTAR & 1) {} + // Clear status + HOSTAR = HOSTAR; + + // Enable PECI, clearing data fifo's + HOCTLR = (1 << 5) | (1 << 3); + // Set address to default + HOTRADDR = 0x30; + // Set write length + HOWRLR = 1; + // Set read length + HORDLR = 2; + // Set command + HOCMDR = 1; + // Start transaction + HOCTLR |= 1; + + // Wait for completion + while (HOSTAR & 1) {} + + if (HOSTAR & (1 << 1)) { + // Use result if finished successfully + uint8_t low = HORDDR; + uint8_t high = HORDDR; + int16_t offset = ((int16_t)high << 8) | (int16_t)low; + + // Tjunction = 100C for i7-8565U (and probably the same for all WHL-U) + #define T_JUNCTION 10000 + int16_t temp = T_JUNCTION + offset; + + // Set fan based on temp, adapted from + // https://github.com/pop-os/system76-power/blob/master/src/fan.rs#L218 + uint8_t duty = 0; + if (temp >= 9000) { + // 90C = 100% + duty = 255; + } else if (temp >= 8000) { + // 80C = 50% + duty = 128; + } else if (temp >= 7500) { + // 75C = 45% + duty = 115; + } else if (temp >= 6500) { + // 65C = 40% + duty = 102; + } else if (temp >= 5500) { + // 55C = 35% + duty = 90; + } else if (temp >= 4500) { + // 45C = 30% + duty = 77; + } + + if (duty != DCR2) { + DCR2 = duty; + printf("PECI offset=%d, temp=%d = %d\n", offset, temp, duty); + } + } else { + // Default to 50% if there is an error + DCR2 = 128; + } } void ac_adapter() { @@ -368,6 +446,7 @@ void main(void) { printf("Hello from System76 EC for %s!\n", xstr(__BOARD__)); for(;;) { + peci_event(); ac_adapter(); power_button(); kbscan_event(); diff --git a/src/board/system76/galp3-c/pwm.c b/src/board/system76/galp3-c/pwm.c index b6ec7a0..6cd7dda 100644 --- a/src/board/system76/galp3-c/pwm.c +++ b/src/board/system76/galp3-c/pwm.c @@ -16,8 +16,8 @@ void pwm_init(void) { // Set cycle time to 255 + 1 CTR0 = 255; - // Turn on the CPU fan at half blast (temperature control TODO) - DCR2 = 128; + // Turn off CPU fan (temperature control in peci_event) + DCR2 = 0; // Enable PWM ZTIER = (1 << 1); diff --git a/src/ec/it8587e/include/ec/gpio.h b/src/ec/it8587e/include/ec/gpio.h index 4e104eb..e9a1605 100644 --- a/src/ec/it8587e/include/ec/gpio.h +++ b/src/ec/it8587e/include/ec/gpio.h @@ -22,6 +22,24 @@ bool gpio_get(struct Gpio * gpio); void gpio_set(struct Gpio * gpio, bool value); volatile uint8_t __xdata __at(0x1600) GCR; +volatile uint8_t __xdata __at(0x16F0) GCR1; +volatile uint8_t __xdata __at(0x16F1) GCR2; +volatile uint8_t __xdata __at(0x16F2) GCR3; +volatile uint8_t __xdata __at(0x16F3) GCR4; +volatile uint8_t __xdata __at(0x16F4) GCR5; +volatile uint8_t __xdata __at(0x16F5) GCR6; +volatile uint8_t __xdata __at(0x16F6) GCR7; +volatile uint8_t __xdata __at(0x16F7) GCR8; +volatile uint8_t __xdata __at(0x16F8) GCR9; +volatile uint8_t __xdata __at(0x16F9) GCR10; +volatile uint8_t __xdata __at(0x16FA) GCR11; +volatile uint8_t __xdata __at(0x16FB) GCR12; +volatile uint8_t __xdata __at(0x16FC) GCR13; +volatile uint8_t __xdata __at(0x16FD) GCR14; +volatile uint8_t __xdata __at(0x16FE) GCR15; +volatile uint8_t __xdata __at(0x16E0) GCR16; +volatile uint8_t __xdata __at(0x16E1) GCR17; +volatile uint8_t __xdata __at(0x16E2) GCR18; volatile uint8_t __xdata __at(0x1601) GPDRA; volatile uint8_t __xdata __at(0x1602) GPDRB;