From patchwork Tue Dec 8 03:39:06 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 553754 X-Patchwork-Delegate: bmeng.cn@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id D98281402BD for ; Tue, 8 Dec 2015 14:59:48 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b=dW+Tp/HH; dkim-atps=neutral Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 7A1814B7B1; Tue, 8 Dec 2015 04:59:40 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 5UiqoikE7zUw; Tue, 8 Dec 2015 04:59:40 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 220ED4B7B2; Tue, 8 Dec 2015 04:59:28 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id AFD0D4B73A for ; Tue, 8 Dec 2015 04:59:19 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id zZWiKZCmvkoS for ; Tue, 8 Dec 2015 04:59:19 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-oi0-f48.google.com (mail-oi0-f48.google.com [209.85.218.48]) by theia.denx.de (Postfix) with ESMTPS id 34C6A4B736 for ; Tue, 8 Dec 2015 04:59:15 +0100 (CET) Received: by oies6 with SMTP id s6so4118493oie.1 for ; Mon, 07 Dec 2015 19:59:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=eD033uSBfRPYxFoGbV83wz8C6fFPFtAqeEXN0mNaDsE=; b=dW+Tp/HHLf6r1UQ8kqO36P04sxa3+pgwF+0Ge/93dZn1iZFPicPmBgco2EjUSDT4Jm 2ZIOCTZoGvd2gvuOFjlctw16aUbYqE/npNHD4mNu9+UyH/ftTcKG8DaFs6v/0XExUhNO GAKrMMZOnfWKEjd0vdnyYVs8lYBZT1lHOQ7Pqd7tmxnAUG4NRaY8kLCBx6BlI3w68Q+T b4wldknz0/PjpVoICHvRQ5yEePRDOSbU3kBH+c8nQT7ZhHy3/nS7jGGe2EGWI7eMCEvY nNJqItv3SLk2Ghxv9fGgCyLVFY9S7kR3vYazmbiMN3j9jJazWGBONI2lUePT4IdL80OU rchQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=eD033uSBfRPYxFoGbV83wz8C6fFPFtAqeEXN0mNaDsE=; b=cN4yBX5Z5bfenvoNkhDgl1mFpHGFBMIF6jy8t3PIcC9k1tUomcjxwOIJyhCDq8f+hv 62VCeGu1p0HTqSpnUEFfjuN/26e2YpXLfsr8Kr2Wl0bmc1r8wVdPQR+vxq4zEjKAanQu v7tBMnLbRy1pTM0WmSnPiExz+OboQ5wc60znUnvb45X3nNfszk0dC67iVNXSJLg8tkjr Hf8f7eJHd7Z3TBJz9nmunKySahMGDg7q8DYlXH5B2jnXWXKLl0bI7I64ijCF/47u9c2J CUfJm7ql+rJxxCPFb1vf0U9Ky1iVbAvvm9XWU77b/TO+/33YrG9T3lDsQ2Q3h820pQEP Ndnw== X-Gm-Message-State: ALoCoQmN+KINmvVuOS34MspIhOMyUq+dMik+WkgAY4WlobnhUGyMcuL4H5zpnBAOD34QanGB5ilt8T5RHzwD8jVrO6txkWbfqA== X-Received: by 10.202.86.198 with SMTP id k189mr649636oib.109.1449547154557; Mon, 07 Dec 2015 19:59:14 -0800 (PST) Received: from kaki.bld.corp.google.com ([172.29.216.32]) by smtp.gmail.com with ESMTPSA id vv10sm303103oeb.4.2015.12.07.19.59.12 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 07 Dec 2015 19:59:13 -0800 (PST) Received: by kaki.bld.corp.google.com (Postfix, from userid 121222) id 34A0822212E; Mon, 7 Dec 2015 20:39:24 -0700 (MST) From: Simon Glass To: U-Boot Mailing List Date: Mon, 7 Dec 2015 20:39:06 -0700 Message-Id: <1449545956-2772-48-git-send-email-sjg@chromium.org> X-Mailer: git-send-email 2.6.0.rc2.230.g3dd15c0 In-Reply-To: <1449545956-2772-1-git-send-email-sjg@chromium.org> References: <1449545956-2772-1-git-send-email-sjg@chromium.org> Cc: Graeme Russ Subject: [U-Boot] [PATCH 47/57] x86: ivybridge: Convert SDRAM init to use driver model X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.15 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" 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 Reviewed-by: Bin Meng --- arch/x86/cpu/ivybridge/early_me.c | 68 ++++++++++++++++++++------------ arch/x86/cpu/ivybridge/sdram.c | 20 ++++++---- arch/x86/dts/chromebook_link.dts | 6 +++ arch/x86/include/asm/arch-ivybridge/me.h | 45 ++++++++++++++++++--- 4 files changed, 101 insertions(+), 38 deletions(-) diff --git a/arch/x86/cpu/ivybridge/early_me.c b/arch/x86/cpu/ivybridge/early_me.c index 711470f..612c910 100644 --- a/arch/x86/cpu/ivybridge/early_me.c +++ b/arch/x86/cpu/ivybridge/early_me.c @@ -7,6 +7,7 @@ */ #include +#include #include #include #include @@ -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 6105cc0..696351b 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; diff --git a/arch/x86/dts/chromebook_link.dts b/arch/x86/dts/chromebook_link.dts index a94d9de..b54a545 100644 --- a/arch/x86/dts/chromebook_link.dts +++ b/arch/x86/dts/chromebook_link.dts @@ -220,6 +220,12 @@ intel,pch-backlight = <0x04000000>; }; + me@16,0 { + reg = <0x0000b000 0 0 0 0>; + compatible = "intel,me"; + u-boot,dm-pre-reloc; + }; + pch@1f,0 { reg = <0x0000f800 0 0 0 0>; compatible = "intel,bd82x6x", "intel,pch"; diff --git a/arch/x86/include/asm/arch-ivybridge/me.h b/arch/x86/include/asm/arch-ivybridge/me.h index 3a0809d..eb1b73f 100644 --- a/arch/x86/include/asm/arch-ivybridge/me.h +++ b/arch/x86/include/asm/arch-ivybridge/me.h @@ -345,12 +345,47 @@ struct __packed me_fwcaps { u8 reserved[3]; }; -/* Defined in me_status.c for both romstage and ramstage */ +/** + * intel_me_status() - Check Intel Management Engine status + * + * struct hfs: Firmware status + * struct gmes: Management engine status + */ void intel_me_status(struct me_hfs *hfs, struct me_gmes *gmes); -void intel_early_me_status(void); -int intel_early_me_init(void); -int intel_early_me_uma_size(void); -int intel_early_me_init_done(u8 status); +/** + * intel_early_me_status() - Check early Management Engine Status + * + * @me_dev: Management engine PCI device + */ +void intel_early_me_status(struct udevice *me_dev); + +/** + * intel_early_me_init() - Early Intel Management Engine init + * + * @me_dev: Management engine PCI device + * @return 0 if OK, -ve on error + */ +int intel_early_me_init(struct udevice *me_dev); + +/** + * intel_early_me_uma_size() - Get UMA size from the Intel Management Engine + * + * @me_dev: Management engine PCI device + * @return UMA size if OK, -EINVAL on error + */ +int intel_early_me_uma_size(struct udevice *me_dev); + +/** + * intel_early_me_init_done() - Complete Intel Management Engine init + * + * @dev: Northbridge device + * @me_dev: Management engine PCI device + * @status: Status result (ME_INIT_...) + * @return 0 to continue to boot, -EINVAL on unknown result data, -ETIMEDOUT + * if ME did not respond + */ +int intel_early_me_init_done(struct udevice *dev, struct udevice *me_dev, + uint status); #endif