WIP: burst mode

This commit is contained in:
Jeremy Soller 2020-01-28 15:24:05 -07:00
parent 06e226e9c8
commit ae4379199c
No known key found for this signature in database
GPG Key ID: E988B49EE78A7FB1

View File

@ -37,71 +37,78 @@ void pmc_event(struct Pmc * pmc) {
static enum PmcState state = PMC_STATE_DEFAULT; static enum PmcState state = PMC_STATE_DEFAULT;
static uint8_t state_data[2] = {0, 0}; static uint8_t state_data[2] = {0, 0};
uint8_t sts = pmc_status(pmc); uint16_t burst_timeout;
if (sts & PMC_STS_IBF) { for (burst_timeout = 1; burst_timeout > 0; burst_timeout--) {
uint8_t data = pmc_read(pmc); uint8_t sts = pmc_status(pmc);
if (sts & PMC_STS_CMD) { if (sts & PMC_STS_IBF) {
DEBUG("pmc cmd: %02X\n", data); uint8_t data = pmc_read(pmc);
if (sts & PMC_STS_CMD) {
DEBUG("pmc cmd: %02X\n", data);
state = PMC_STATE_DEFAULT; state = PMC_STATE_DEFAULT;
switch (data) { switch (data) {
case 0x80: case 0x80:
state = PMC_STATE_ACPI_READ; state = PMC_STATE_ACPI_READ;
break; break;
case 0x81: case 0x81:
state = PMC_STATE_ACPI_WRITE; state = PMC_STATE_ACPI_WRITE;
break; break;
case 0x82: case 0x82:
DEBUG(" burst enable\n"); DEBUG(" burst enable\n");
// Set burst bit // Run pmc_event in a tight loop for PMC_TIMEOUT iterations
pmc_set_status(pmc, sts | (1 << 4)); burst_timeout = PMC_TIMEOUT;
// Send acknowledgement byte // Set burst bit
pmc_write(pmc, 0x90, PMC_TIMEOUT); pmc_set_status(pmc, sts | (1 << 4));
break; // Send acknowledgement byte
case 0x83: pmc_write(pmc, 0x90, PMC_TIMEOUT);
DEBUG(" burst disable\n"); break;
// Clear burst bit case 0x83:
pmc_set_status(pmc, sts & ~(1 << 4)); DEBUG(" burst disable\n");
break; // Exit pmc_event tight loop
case 0x84: burst_timeout = 0;
DEBUG(" SCI queue\n"); // Clear burst bit
// Clear SCI pending bit pmc_set_status(pmc, sts & ~(1 << 4));
pmc_set_status(pmc, sts & ~(1 << 5)); break;
// Send SCI queue case 0x84:
pmc_write(pmc, pmc_sci_queue, PMC_TIMEOUT); DEBUG(" SCI queue\n");
// Stop SCI interrupt // Clear SCI pending bit
*(SCI_N.control) = 0x80; pmc_set_status(pmc, sts & ~(1 << 5));
gpio_set(&SCI_N, true); // Send SCI queue
// Clear SCI queue pmc_write(pmc, pmc_sci_queue, PMC_TIMEOUT);
pmc_sci_queue = 0; // Stop SCI interrupt
break; *(SCI_N.control) = 0x80;
gpio_set(&SCI_N, true);
// Clear SCI queue
pmc_sci_queue = 0;
break;
case 0xEC: case 0xEC:
DEBUG(" scratch rom\n"); DEBUG(" scratch rom\n");
pmc_write(pmc, 0x76, PMC_TIMEOUT); pmc_write(pmc, 0x76, PMC_TIMEOUT);
scratch_trampoline(); scratch_trampoline();
break; break;
} }
} else { } else {
DEBUG("pmc data: %02X\n", data); DEBUG("pmc data: %02X\n", data);
switch (state) { switch (state) {
case PMC_STATE_ACPI_READ: case PMC_STATE_ACPI_READ:
state = PMC_STATE_DEFAULT; state = PMC_STATE_DEFAULT;
uint8_t value = acpi_read(data); uint8_t value = acpi_read(data);
pmc_write(pmc, value, PMC_TIMEOUT); pmc_write(pmc, value, PMC_TIMEOUT);
break; break;
case PMC_STATE_ACPI_WRITE: case PMC_STATE_ACPI_WRITE:
state = PMC_STATE_ACPI_WRITE_ADDR; state = PMC_STATE_ACPI_WRITE_ADDR;
state_data[0] = data; state_data[0] = data;
break; break;
case PMC_STATE_ACPI_WRITE_ADDR: case PMC_STATE_ACPI_WRITE_ADDR:
state = PMC_STATE_DEFAULT; state = PMC_STATE_DEFAULT;
acpi_write(state_data[0], data); acpi_write(state_data[0], data);
break; break;
default: default:
state = PMC_STATE_DEFAULT; state = PMC_STATE_DEFAULT;
break; break;
}
} }
} }
} }