mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-04 22:11:41 +00:00
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:
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user