summaryrefslogtreecommitdiffstats
path: root/arch/x86/cpu
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2016-01-17 16:11:50 -0700
committerBin Meng <bmeng.cn@gmail.com>2016-01-24 12:09:41 +0800
commitc02a4242c88fa42d2a08e979551a85b45c946b8e (patch)
treecddfb88ad752bc1e7c5cd709f931ea4bdbfc0ceb /arch/x86/cpu
parentb32375d070e7f9717293bc55aebdba3130bee72a (diff)
downloadtalos-obmc-uboot-c02a4242c88fa42d2a08e979551a85b45c946b8e.tar.gz
talos-obmc-uboot-c02a4242c88fa42d2a08e979551a85b45c946b8e.zip
x86: ivybridge: Convert SDRAM init to use driver model
SDRAM init needs access to the Northbridge controller and the Intel Management Engine device. Add the latter to the device tree and convert all of this code to driver model. Signed-off-by: Simon Glass <sjg@chromium.org> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Diffstat (limited to 'arch/x86/cpu')
-rw-r--r--arch/x86/cpu/ivybridge/early_me.c68
-rw-r--r--arch/x86/cpu/ivybridge/sdram.c20
2 files changed, 55 insertions, 33 deletions
diff --git a/arch/x86/cpu/ivybridge/early_me.c b/arch/x86/cpu/ivybridge/early_me.c
index 711470f364..612c9103e3 100644
--- a/arch/x86/cpu/ivybridge/early_me.c
+++ b/arch/x86/cpu/ivybridge/early_me.c
@@ -7,6 +7,7 @@
*/
#include <common.h>
+#include <dm.h>
#include <errno.h>
#include <asm/pci.h>
#include <asm/processor.h>
@@ -25,33 +26,36 @@ static const char *const me_ack_values[] = {
[ME_HFS_ACK_CONTINUE] = "Continue to boot"
};
-static inline void pci_read_dword_ptr(void *ptr, int offset)
+static inline void pci_read_dword_ptr(struct udevice *me_dev, void *ptr,
+ int offset)
{
u32 dword;
- dword = x86_pci_read_config32(PCH_ME_DEV, offset);
+ dm_pci_read_config32(me_dev, offset, &dword);
memcpy(ptr, &dword, sizeof(dword));
}
-static inline void pci_write_dword_ptr(void *ptr, int offset)
+static inline void pci_write_dword_ptr(struct udevice *me_dev, void *ptr,
+ int offset)
{
u32 dword = 0;
+
memcpy(&dword, ptr, sizeof(dword));
- x86_pci_write_config32(PCH_ME_DEV, offset, dword);
+ dm_pci_write_config32(me_dev, offset, dword);
}
-void intel_early_me_status(void)
+void intel_early_me_status(struct udevice *me_dev)
{
struct me_hfs hfs;
struct me_gmes gmes;
- pci_read_dword_ptr(&hfs, PCI_ME_HFS);
- pci_read_dword_ptr(&gmes, PCI_ME_GMES);
+ pci_read_dword_ptr(me_dev, &hfs, PCI_ME_HFS);
+ pci_read_dword_ptr(me_dev, &gmes, PCI_ME_GMES);
intel_me_status(&hfs, &gmes);
}
-int intel_early_me_init(void)
+int intel_early_me_init(struct udevice *me_dev)
{
int count;
struct me_uma uma;
@@ -61,7 +65,7 @@ int intel_early_me_init(void)
/* Wait for ME UMA SIZE VALID bit to be set */
for (count = ME_RETRY; count > 0; --count) {
- pci_read_dword_ptr(&uma, PCI_ME_UMA);
+ pci_read_dword_ptr(me_dev, &uma, PCI_ME_UMA);
if (uma.valid)
break;
udelay(ME_DELAY);
@@ -72,7 +76,7 @@ int intel_early_me_init(void)
}
/* Check for valid firmware */
- pci_read_dword_ptr(&hfs, PCI_ME_HFS);
+ pci_read_dword_ptr(me_dev, &hfs, PCI_ME_HFS);
if (hfs.fpt_bad) {
printf("WARNING: ME has bad firmware\n");
return -EBADF;
@@ -83,11 +87,11 @@ int intel_early_me_init(void)
return 0;
}
-int intel_early_me_uma_size(void)
+int intel_early_me_uma_size(struct udevice *me_dev)
{
struct me_uma uma;
- pci_read_dword_ptr(&uma, PCI_ME_UMA);
+ pci_read_dword_ptr(me_dev, &uma, PCI_ME_UMA);
if (uma.valid) {
debug("ME: Requested %uMB UMA\n", uma.size);
return uma.size;
@@ -97,11 +101,11 @@ int intel_early_me_uma_size(void)
return -EINVAL;
}
-static inline void set_global_reset(int enable)
+static inline void set_global_reset(struct udevice *dev, int enable)
{
u32 etr3;
- etr3 = x86_pci_read_config32(PCH_LPC_DEV, ETR3);
+ dm_pci_read_config32(dev, ETR3, &etr3);
/* Clear CF9 Without Resume Well Reset Enable */
etr3 &= ~ETR3_CWORWRE;
@@ -112,10 +116,11 @@ static inline void set_global_reset(int enable)
else
etr3 &= ~ETR3_CF9GR;
- x86_pci_write_config32(PCH_LPC_DEV, ETR3, etr3);
+ dm_pci_write_config32(dev, ETR3, etr3);
}
-int intel_early_me_init_done(u8 status)
+int intel_early_me_init_done(struct udevice *dev, struct udevice *me_dev,
+ uint status)
{
int count;
u32 mebase_l, mebase_h;
@@ -126,8 +131,8 @@ int intel_early_me_init_done(u8 status)
};
/* MEBASE from MESEG_BASE[35:20] */
- mebase_l = x86_pci_read_config32(PCH_DEV, PCI_CPU_MEBASE_L);
- mebase_h = x86_pci_read_config32(PCH_DEV, PCI_CPU_MEBASE_H);
+ dm_pci_read_config32(PCH_DEV, PCI_CPU_MEBASE_L, &mebase_l);
+ dm_pci_read_config32(PCH_DEV, PCI_CPU_MEBASE_H, &mebase_h);
mebase_h &= 0xf;
did.uma_base = (mebase_l >> 20) | (mebase_h << 12);
@@ -135,25 +140,25 @@ int intel_early_me_init_done(u8 status)
debug("ME: Sending Init Done with status: %d, UMA base: 0x%04x\n",
status, did.uma_base);
- pci_write_dword_ptr(&did, PCI_ME_H_GS);
+ pci_write_dword_ptr(me_dev, &did, PCI_ME_H_GS);
/* Must wait for ME acknowledgement */
for (count = ME_RETRY; count > 0; --count) {
- pci_read_dword_ptr(&hfs, PCI_ME_HFS);
+ pci_read_dword_ptr(me_dev, &hfs, PCI_ME_HFS);
if (hfs.bios_msg_ack)
break;
udelay(ME_DELAY);
}
if (!count) {
printf("ERROR: ME failed to respond\n");
- return -1;
+ return -ETIMEDOUT;
}
/* Return the requested BIOS action */
debug("ME: Requested BIOS Action: %s\n", me_ack_values[hfs.ack_data]);
/* Check status after acknowledgement */
- intel_early_me_status();
+ intel_early_me_status(me_dev);
switch (hfs.ack_data) {
case ME_HFS_ACK_CONTINUE:
@@ -161,17 +166,17 @@ int intel_early_me_init_done(u8 status)
return 0;
case ME_HFS_ACK_RESET:
/* Non-power cycle reset */
- set_global_reset(0);
+ set_global_reset(dev, 0);
reset_cpu(0);
break;
case ME_HFS_ACK_PWR_CYCLE:
/* Power cycle reset */
- set_global_reset(0);
+ set_global_reset(dev, 0);
x86_full_reset();
break;
case ME_HFS_ACK_GBL_RESET:
/* Global reset */
- set_global_reset(1);
+ set_global_reset(dev, 1);
x86_full_reset();
break;
case ME_HFS_ACK_S3:
@@ -180,5 +185,16 @@ int intel_early_me_init_done(u8 status)
break;
}
- return -1;
+ return -EINVAL;
}
+
+static const struct udevice_id ivybridge_syscon_ids[] = {
+ { .compatible = "intel,me", },
+ { }
+};
+
+U_BOOT_DRIVER(syscon_intel_me) = {
+ .name = "intel_me_syscon",
+ .id = UCLASS_SYSCON,
+ .of_match = ivybridge_syscon_ids,
+};
diff --git a/arch/x86/cpu/ivybridge/sdram.c b/arch/x86/cpu/ivybridge/sdram.c
index 6105cc0259..696351b7bf 100644
--- a/arch/x86/cpu/ivybridge/sdram.c
+++ b/arch/x86/cpu/ivybridge/sdram.c
@@ -286,7 +286,8 @@ static int recovery_mode_enabled(void)
* @dev: Northbridge device
* @pei_data: configuration data for UEFI PEI reference code
*/
-int sdram_initialise(struct udevice *dev, struct pei_data *pei_data)
+int sdram_initialise(struct udevice *dev, struct udevice *me_dev,
+ struct pei_data *pei_data)
{
unsigned version;
const char *data;
@@ -296,10 +297,10 @@ int sdram_initialise(struct udevice *dev, struct pei_data *pei_data)
report_platform_info();
/* Wait for ME to be ready */
- ret = intel_early_me_init();
+ ret = intel_early_me_init(me_dev);
if (ret)
return ret;
- ret = intel_early_me_uma_size();
+ ret = intel_early_me_uma_size(me_dev);
if (ret < 0)
return ret;
@@ -378,9 +379,9 @@ int sdram_initialise(struct udevice *dev, struct pei_data *pei_data)
dm_pci_read_config16(dev, PCI_DEVICE_ID, &done);
done &= BASE_REV_MASK;
if (BASE_REV_SNB == done)
- intel_early_me_init_done(ME_INIT_STATUS_SUCCESS);
+ intel_early_me_init_done(dev, me_dev, ME_INIT_STATUS_SUCCESS);
else
- intel_early_me_status();
+ intel_early_me_status(me_dev);
post_system_agent_init(pei_data);
report_memory_config();
@@ -730,7 +731,7 @@ int dram_init(void)
{ 0, 4, 0x0000 }, /* P13= Empty */
},
};
- struct udevice *dev;
+ struct udevice *dev, *me_dev;
int ret;
ret = uclass_first_device(UCLASS_NORTHBRIDGE, &dev);
@@ -738,12 +739,17 @@ int dram_init(void)
return ret;
if (!dev)
return -ENODEV;
+ ret = uclass_first_device(UCLASS_SYSCON, &me_dev);
+ if (ret)
+ return ret;
+ if (!me_dev)
+ return -ENODEV;
debug("Boot mode %d\n", gd->arch.pei_boot_mode);
debug("mrc_input %p\n", pei_data.mrc_input);
pei_data.boot_mode = gd->arch.pei_boot_mode;
ret = copy_spd(&pei_data);
if (!ret)
- ret = sdram_initialise(dev, &pei_data);
+ ret = sdram_initialise(dev, me_dev, &pei_data);
if (ret)
return ret;
OpenPOWER on IntegriCloud