it8380dev: fix lpc module

1. add lpc_keyboard_clear_buffer() function.
2. Enable P80L function, that LPC I/O port 80h data can be mapped
   to BRAM bank1 (offset 0x80 ~ 0xBF).

Signed-off-by: Dino Li <dino.li@ite.com.tw>

BRANCH=none
BUG=none
TEST=1. The lpc_keyboard_clear_buffer() function can clear OBF.
     2. 80h port, console command port80.
     3. 62h/66h port.
       3-a. out 66h 80h, out 62h 00h, in 62h 02h
       3-b. out 66h 81h, out 62h 01h, out 62h 55h
       3-c. out 66h 80h, out 62h 01h, in 62h 55h
       3-d. out 66h 80h, out 62h 02h, in 62h aah
     4. Host command "version".

Change-Id: Id2b5a5813cbe8edfc4ecc7b153874b819d460f43
Reviewed-on: https://chromium-review.googlesource.com/298421
Commit-Ready: Dino Li <dino.li@ite.com.tw>
Tested-by: Dino Li <dino.li@ite.com.tw>
Reviewed-by: Randall Spangler <rspangler@chromium.org>
This commit is contained in:
Dino Li
2015-09-11 10:53:23 +08:00
committed by chrome-bot
parent 72a7796dcb
commit f33ff43d93
5 changed files with 100 additions and 7 deletions

View File

@@ -146,6 +146,14 @@ const struct ec2i_t pnpcfg_settings[] = {
{HOST_INDEX_IRQNUMX, 0x00},
/* Enable logical device */
{HOST_INDEX_LDA, 0x01},
/* Select logical device 10h(RTCT) */
{HOST_INDEX_LDN, LDN_RTCT},
/* P80L Begin Index */
{HOST_INDEX_DSLDC4, P80L_P80LB},
/* P80L End Index */
{HOST_INDEX_DSLDC5, P80L_P80LE},
/* P80L Current Index */
{HOST_INDEX_DSLDC6, P80L_P80LC},
};
BUILD_ASSERT(ARRAY_SIZE(pnpcfg_settings) == EC2I_SETTING_COUNT);

View File

@@ -90,6 +90,10 @@ enum ec2i_setting {
EC2I_SET_PMC3_BASE1_LSB,
EC2I_SET_PMC3_IRQ,
EC2I_SET_PMC3_ENABLE,
EC2I_SET_RTCT_LDN,
EC2I_SET_RTCT_P80LB,
EC2I_SET_RTCT_P80LE,
EC2I_SET_RTCT_P80LC,
/* Number of EC2I settings */
EC2I_SETTING_COUNT
};

View File

@@ -8,6 +8,11 @@
#ifndef __CROS_EC_EC2I_CHIP_H
#define __CROS_EC_EC2I_CHIP_H
#define P80L_P80LB 0
#define P80L_P80LE 0x3F
#define P80L_P80LC 0
#define P80L_BRAM_BANK1_MAX_SIZE 0x3F
/* Index list of the host interface registers of PNPCFG */
enum host_pnpcfg_index {
/* Logical Device Number */

View File

@@ -9,9 +9,11 @@
#include "clock.h"
#include "common.h"
#include "console.h"
#include "ec2i_chip.h"
#include "gpio.h"
#include "hooks.h"
#include "host_command.h"
#include "irq_chip.h"
#include "keyboard_protocol.h"
#include "lpc.h"
#include "port80.h"
@@ -22,7 +24,6 @@
#include "timer.h"
#include "uart.h"
#include "util.h"
#include "irq_chip.h"
/* Console output macros */
#define CPUTS(outstr) cputs(CC_LPC, outstr)
@@ -62,6 +63,7 @@ static uint8_t host_cmd_flags; /* Flags from host command */
/* Params must be 32-bit aligned */
static uint8_t params_copy[EC_LPC_HOST_PACKET_SIZE] __aligned(4);
static int init_done;
static int p80l_index;
static uint8_t * const cmd_params = (uint8_t *)host_cmd_memmap +
EC_LPC_ADDR_HOST_PARAM - EC_LPC_ADDR_HOST_ARGS;
@@ -99,6 +101,12 @@ static void pm_put_data_out(enum lpc_pm_ch ch, uint8_t out)
IT83XX_PMC_PMDO(ch) = out;
}
static void pm_clear_ibf(enum lpc_pm_ch ch)
{
/* bit7, write-1 clear IBF */
IT83XX_PMC_PMIE(ch) |= (1 << 7);
}
/**
* Generate SMI pulse to the host chipset via GPIO.
*
@@ -269,7 +277,7 @@ void lpc_keyboard_put_char(uint8_t chr, int send_irq)
* bit0 = 0, The IRQ1 is controlled by the IRQ1B bit in KBIRQR.
* bit1 = 0, The IRQ12 is controlled by the IRQ12B bit in KBIRQR.
*/
IT83XX_KBC_KBHICR &= 0xFC;
IT83XX_KBC_KBHICR &= 0x3C;
/*
* Enable the interrupt to keyboard driver in the host processor
@@ -288,7 +296,12 @@ void lpc_keyboard_put_char(uint8_t chr, int send_irq)
void lpc_keyboard_clear_buffer(void)
{
/* --- (not implemented yet) --- */
uint32_t int_mask = get_int_mask();
interrupt_disable();
/* bit6, write-1 clear OBF */
IT83XX_KBC_KBHICR |= (1 << 6);
IT83XX_KBC_KBHICR &= ~(1 << 6);
set_int_mask(int_mask);
}
void lpc_keyboard_resume_irq(void)
@@ -378,6 +391,9 @@ void lpc_kbc_ibf_interrupt(void)
if (lpc_keyboard_input_pending()) {
keyboard_host_write(IT83XX_KBC_KBHIDIR,
(IT83XX_KBC_KBHISR & 0x08) ? 1 : 0);
/* bit7, write-1 clear IBF */
IT83XX_KBC_KBHICR |= (1 << 7);
IT83XX_KBC_KBHICR &= ~(1 << 7);
}
task_clear_pending_irq(IT83XX_IRQ_KBC_IN);
@@ -423,6 +439,8 @@ void pm1_ibf_interrupt(void)
if (acpi_ap_to_ec(is_cmd, value, &result))
pm_put_data_out(LPC_ACPI_CMD, result);
pm_clear_ibf(LPC_ACPI_CMD);
/* Clear the busy bit */
pm_set_status(LPC_ACPI_CMD, EC_LPC_STATUS_PROCESSING, 0);
@@ -452,6 +470,7 @@ void pm2_ibf_interrupt(void)
if (!(status & EC_LPC_STATUS_LAST_CMD)) {
/* R/C IBF*/
value = pm_get_data_in(LPC_HOST_CMD);
pm_clear_ibf(LPC_HOST_CMD);
task_clear_pending_irq(IT83XX_IRQ_PMC2_IN);
return;
}
@@ -487,6 +506,7 @@ void pm2_ibf_interrupt(void)
lpc_packet.driver_result = EC_RES_SUCCESS;
host_packet_receive(&lpc_packet);
pm_clear_ibf(LPC_HOST_CMD);
task_clear_pending_irq(IT83XX_IRQ_PMC2_IN);
return;
} else {
@@ -497,29 +517,55 @@ void pm2_ibf_interrupt(void)
/* Hand off to host command handler */
host_command_received(&host_cmd_args);
pm_clear_ibf(LPC_HOST_CMD);
task_clear_pending_irq(IT83XX_IRQ_PMC2_IN);
}
void pm3_ibf_interrupt(void)
{
if (pm_get_status(LPC_HOST_PORT_80H) & EC_LPC_STATUS_FROM_HOST)
port_80_write(pm_get_data_in(LPC_HOST_PORT_80H));
int new_p80_idx, i;
enum ec2i_message ec2i_r;
/* set LDN */
if (ec2i_write(HOST_INDEX_LDN, LDN_RTCT) == EC2I_WRITE_SUCCESS) {
/* get P80L current index */
ec2i_r = ec2i_read(HOST_INDEX_DSLDC6);
/* clear IBF */
pm_clear_ibf(LPC_HOST_PORT_80H);
/* read OK */
if ((ec2i_r & 0xff00) == EC2I_READ_SUCCESS) {
new_p80_idx = ec2i_r & P80L_BRAM_BANK1_MAX_SIZE;
for (i = 0; i < P80L_BRAM_BANK1_MAX_SIZE; i++) {
if (++p80l_index > P80L_P80LE)
p80l_index = P80L_P80LB;
port_80_write(IT83XX_BRAM_BANK1(p80l_index));
if (p80l_index == new_p80_idx)
break;
}
}
} else {
pm_clear_ibf(LPC_HOST_PORT_80H);
}
task_clear_pending_irq(IT83XX_IRQ_PMC3_IN);
}
void pm4_ibf_interrupt(void)
{
pm_clear_ibf(LPC_PM4);
task_clear_pending_irq(IT83XX_IRQ_PMC4_IN);
}
void pm5_ibf_interrupt(void)
{
pm_clear_ibf(LPC_PM5);
task_clear_pending_irq(IT83XX_IRQ_PMC5_IN);
}
static void lpc_init(void)
{
enum ec2i_message ec2i_r;
/*
* DLM 52k~56k size select enable.
* For mapping LPC I/O cycle 800h ~ 9FFh to DLM 8D800 ~ 8D9FF.
@@ -537,8 +583,15 @@ static void lpc_init(void)
/*
* bit2, Output Buffer Empty CPU Interrupt Enable.
* bit3, Input Buffer Full CPU Interrupt Enable.
* bit5, IBF/OBF EC clear mode.
* 0b: IBF cleared if EC read data register, EC reset, or host reset.
* OBF cleared if host read data register, or EC reset.
* 1b: IBF cleared if EC write-1 to bit7 at related registers,
* EC reset, or host reset.
* OBF cleared if host read data register, EC write-1 to bit6 at
* related registers, or EC reset.
*/
IT83XX_KBC_KBHICR |= 0x0C;
IT83XX_KBC_KBHICR |= 0x2C;
/* PM1 Input Buffer Full Interrupt Enable for 62h/66 port */
pm_set_ctrl(LPC_ACPI_CMD, PM_CTRL_IBFIE, 1);
@@ -609,6 +662,22 @@ static void lpc_init(void)
/* PM3 Input Buffer Full Interrupt Enable for 80h port */
pm_set_ctrl(LPC_HOST_PORT_80H, PM_CTRL_IBFIE, 1);
p80l_index = P80L_P80LC;
if (ec2i_write(HOST_INDEX_LDN, LDN_RTCT) == EC2I_WRITE_SUCCESS) {
/* get P80L current index */
ec2i_r = ec2i_read(HOST_INDEX_DSLDC6);
/* read OK */
if ((ec2i_r & 0xff00) == EC2I_READ_SUCCESS)
p80l_index = ec2i_r & P80L_BRAM_BANK1_MAX_SIZE;
}
/*
* bit[7], enable P80L function.
* bit[6], accept port 80h cycle.
* bit[1-0], 10b: I2EC is read-only.
*/
IT83XX_GCTRL_SPCTRL1 |= 0xC2;
gpio_enable_interrupt(GPIO_PCH_PLTRST_L);
task_clear_pending_irq(IT83XX_IRQ_KBC_OUT);

View File

@@ -642,6 +642,7 @@ enum clock_gate_offsets {
#define IT83XX_GCTRL_WNCKR REG8(IT83XX_GCTRL_BASE+0x0B)
#define IT83XX_GCTRL_RSTS REG8(IT83XX_GCTRL_BASE+0x06)
#define IT83XX_GCTRL_BADRSEL REG8(IT83XX_GCTRL_BASE+0x0A)
#define IT83XX_GCTRL_SPCTRL1 REG8(IT83XX_GCTRL_BASE+0x0D)
#define IT83XX_GCTRL_RSTC4 REG8(IT83XX_GCTRL_BASE+0x11)
#define IT83XX_GCTRL_SPCTRL4 REG8(IT83XX_GCTRL_BASE+0x1C)
#define IT83XX_GCTRL_MCCR REG8(IT83XX_GCTRL_BASE+0x30)
@@ -817,6 +818,8 @@ enum clock_gate_offsets {
REG8(IT83XX_PMC_BASE + (ch > LPC_PM2 ? 2 : 4) + (ch << 4))
#define IT83XX_PMC_PMCTL(ch) \
REG8(IT83XX_PMC_BASE + (ch > LPC_PM2 ? 3 : 6) + (ch << 4))
#define IT83XX_PMC_PMIE(ch) \
REG8(IT83XX_PMC_BASE + (ch > LPC_PM2 ? 5 : 8) + (ch << 4))
/* Keyboard Matrix Scan control (KBS) */
#define IT83XX_KBS_BASE 0x00F01D00
@@ -936,13 +939,17 @@ REG8(IT83XX_PMC_BASE + (ch > LPC_PM2 ? 3 : 6) + (ch << 4))
#define IT83XX_SMB_SMBPCTL(ch) REG8(IT83XX_SMB_BASE+0x4A+(ch << 6))
#define IT83XX_SMB_HOCTL2(ch) REG8(IT83XX_SMB_BASE+0x50+(ch << 6))
/* BRAM */
#define IT83XX_BRAM_BASE 0x00F02200
#define IT83XX_BRAM_BANK1(i) REG8(IT83XX_BRAM_BASE + 0x80 + i)
/* --- MISC (not implemented yet) --- */
#define IT83XX_PS2_BASE 0x00F01700
#define IT83XX_DAC_BASE 0x00F01A00
#define IT83XX_WUC_BASE 0x00F01B00
#define IT83XX_EGPIO_BASE 0x00F02100
#define IT83XX_BRAM_BASE 0x00F02200
#define IT83XX_CIR_BASE 0x00F02300
#define IT83XX_DBGR_BASE 0x00F02500
#define IT83XX_OW_BASE 0x00F02A00