Some of the LPC code is common to several Intel LPC devices. Move it into a common location. Signed-off-by: Simon Glass <sjg@chromium.org> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>master
parent
bb096b9fad
commit
8c30b57130
@ -0,0 +1,100 @@ |
||||
/*
|
||||
* Copyright (c) 2016 Google, Inc |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0 |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <dm.h> |
||||
#include <errno.h> |
||||
#include <fdtdec.h> |
||||
#include <pch.h> |
||||
#include <pci.h> |
||||
#include <asm/intel_regs.h> |
||||
#include <asm/io.h> |
||||
#include <asm/lpc_common.h> |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
/* Enable Prefetching and Caching */ |
||||
static void enable_spi_prefetch(struct udevice *pch) |
||||
{ |
||||
u8 reg8; |
||||
|
||||
dm_pci_read_config8(pch, 0xdc, ®8); |
||||
reg8 &= ~(3 << 2); |
||||
reg8 |= (2 << 2); /* Prefetching and Caching Enabled */ |
||||
dm_pci_write_config8(pch, 0xdc, reg8); |
||||
} |
||||
|
||||
static void enable_port80_on_lpc(struct udevice *pch) |
||||
{ |
||||
/* Enable port 80 POST on LPC */ |
||||
dm_pci_write_config32(pch, PCH_RCBA_BASE, RCB_BASE_ADDRESS | 1); |
||||
clrbits_le32(RCB_REG(GCS), 4); |
||||
} |
||||
|
||||
/**
|
||||
* lpc_early_init() - set up LPC serial ports and other early things |
||||
* |
||||
* @dev: LPC device |
||||
* @return 0 if OK, -ve on error |
||||
*/ |
||||
int lpc_common_early_init(struct udevice *dev) |
||||
{ |
||||
struct udevice *pch = dev->parent; |
||||
struct reg_info { |
||||
u32 base; |
||||
u32 size; |
||||
} values[4], *ptr; |
||||
int count; |
||||
int i; |
||||
|
||||
count = fdtdec_get_int_array_count(gd->fdt_blob, dev->of_offset, |
||||
"intel,gen-dec", (u32 *)values, |
||||
sizeof(values) / sizeof(u32)); |
||||
if (count < 0) |
||||
return -EINVAL; |
||||
|
||||
/* Set COM1/COM2 decode range */ |
||||
dm_pci_write_config16(pch, LPC_IO_DEC, 0x0010); |
||||
|
||||
/* Enable PS/2 Keyboard/Mouse, EC areas and COM1 */ |
||||
dm_pci_write_config16(pch, LPC_EN, KBC_LPC_EN | MC_LPC_EN | |
||||
GAMEL_LPC_EN | COMA_LPC_EN); |
||||
|
||||
/* Write all registers but use 0 if we run out of data */ |
||||
count = count * sizeof(u32) / sizeof(values[0]); |
||||
for (i = 0, ptr = values; i < ARRAY_SIZE(values); i++, ptr++) { |
||||
u32 reg = 0; |
||||
|
||||
if (i < count) |
||||
reg = ptr->base | PCI_COMMAND_IO | (ptr->size << 16); |
||||
dm_pci_write_config32(pch, LPC_GENX_DEC(i), reg); |
||||
} |
||||
|
||||
enable_spi_prefetch(pch); |
||||
|
||||
/* This is already done in start.S, but let's do it in C */ |
||||
enable_port80_on_lpc(pch); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int lpc_set_spi_protect(struct udevice *dev, int bios_ctrl, bool protect) |
||||
{ |
||||
uint8_t bios_cntl; |
||||
|
||||
/* Adjust the BIOS write protect and SMM BIOS Write Protect Disable */ |
||||
dm_pci_read_config8(dev, bios_ctrl, &bios_cntl); |
||||
if (protect) { |
||||
bios_cntl &= ~BIOS_CTRL_BIOSWE; |
||||
bios_cntl |= BIT(5); |
||||
} else { |
||||
bios_cntl |= BIOS_CTRL_BIOSWE; |
||||
bios_cntl &= ~BIT(5); |
||||
} |
||||
dm_pci_write_config8(dev, bios_ctrl, bios_cntl); |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,59 @@ |
||||
/*
|
||||
* Copyright (c) 2016 Google, Inc |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0 |
||||
*/ |
||||
|
||||
#ifndef __ASM_LPC_COMMON_H |
||||
#define __ASM_LPC_COMMON_H |
||||
|
||||
#define PCH_RCBA_BASE 0xf0 |
||||
|
||||
#define RC 0x3400 /* 32bit */ |
||||
#define GCS 0x3410 /* 32bit */ |
||||
|
||||
#define PMBASE 0x40 |
||||
#define ACPI_CNTL 0x44 |
||||
|
||||
#define LPC_IO_DEC 0x80 /* IO Decode Ranges Register */ |
||||
#define COMB_DEC_RANGE (1 << 4) /* 0x2f8-0x2ff (COM2) */ |
||||
#define COMA_DEC_RANGE (0 << 0) /* 0x3f8-0x3ff (COM1) */ |
||||
#define LPC_EN 0x82 /* LPC IF Enables Register */ |
||||
#define CNF2_LPC_EN (1 << 13) /* 0x4e/0x4f */ |
||||
#define CNF1_LPC_EN (1 << 12) /* 0x2e/0x2f */ |
||||
#define MC_LPC_EN (1 << 11) /* 0x62/0x66 */ |
||||
#define KBC_LPC_EN (1 << 10) /* 0x60/0x64 */ |
||||
#define GAMEH_LPC_EN (1 << 9) /* 0x208/0x20f */ |
||||
#define GAMEL_LPC_EN (1 << 8) /* 0x200/0x207 */ |
||||
#define FDD_LPC_EN (1 << 3) /* LPC_IO_DEC[12] */ |
||||
#define LPT_LPC_EN (1 << 2) /* LPC_IO_DEC[9:8] */ |
||||
#define COMB_LPC_EN (1 << 1) /* LPC_IO_DEC[6:4] */ |
||||
#define COMA_LPC_EN (1 << 0) /* LPC_IO_DEC[3:2] */ |
||||
#define LPC_GEN1_DEC 0x84 /* LPC IF Generic Decode Range 1 */ |
||||
#define LPC_GEN2_DEC 0x88 /* LPC IF Generic Decode Range 2 */ |
||||
#define LPC_GEN3_DEC 0x8c /* LPC IF Generic Decode Range 3 */ |
||||
#define LPC_GEN4_DEC 0x90 /* LPC IF Generic Decode Range 4 */ |
||||
#define LPC_GENX_DEC(x) (0x84 + 4 * (x)) |
||||
#define GEN_DEC_RANGE_256B 0xfc0000 /* 256 Bytes */ |
||||
#define GEN_DEC_RANGE_128B 0x7c0000 /* 128 Bytes */ |
||||
#define GEN_DEC_RANGE_64B 0x3c0000 /* 64 Bytes */ |
||||
#define GEN_DEC_RANGE_32B 0x1c0000 /* 32 Bytes */ |
||||
#define GEN_DEC_RANGE_16B 0x0c0000 /* 16 Bytes */ |
||||
#define GEN_DEC_RANGE_8B 0x040000 /* 8 Bytes */ |
||||
#define GEN_DEC_RANGE_4B 0x000000 /* 4 Bytes */ |
||||
#define GEN_DEC_RANGE_EN (1 << 0) /* Range Enable */ |
||||
|
||||
/**
|
||||
* lpc_common_early_init() - Set up common LPC init |
||||
* |
||||
* This sets up the legacy decode areas, GEN_DEC, SPI prefetch and Port80. It |
||||
* also puts the RCB in the correct place so that RCB_REG() works. |
||||
* |
||||
* @dev: LPC device (a child of the PCH) |
||||
* @return 0 on success, -ve on error |
||||
*/ |
||||
int lpc_common_early_init(struct udevice *dev); |
||||
|
||||
int lpc_set_spi_protect(struct udevice *dev, int bios_ctrl, bool protect); |
||||
|
||||
#endif |
Loading…
Reference in new issue