[U-Boot] [PATCH 8/8] x86: quark: Optimize MRC execution time

Bin Meng bmeng.cn at gmail.com
Mon Aug 31 11:52:53 CEST 2015


Boot time performance degradation is observed with the conversion
to use dm pci. Intel Quark SoC has a low end x86 processor with
only 400MHz frequency and the most time consuming part is with MRC.
Each MRC register programming requires indirect access via pci bus.
With dm pci, accessing pci configuration space has some overhead.
Unfortunately this single access overhead gets accumulated in the
whole MRC process, and finally leads to twice boot time (25 seconds)
than before (12 seconds).

To speed up the boot, create an optimized version of pci config
read/write routines without bothering to go through driver model.
Now it only takes about 3 seconds to finish MRC, which is really
fast (8 times faster than dm pci, or 4 times faster than before).

Signed-off-by: Bin Meng <bmeng.cn at gmail.com>
---

 arch/x86/cpu/quark/msg_port.c | 59 +++++++++++++++++++++++++++----------------
 1 file changed, 37 insertions(+), 22 deletions(-)

diff --git a/arch/x86/cpu/quark/msg_port.c b/arch/x86/cpu/quark/msg_port.c
index 31713e3..a75ef23 100644
--- a/arch/x86/cpu/quark/msg_port.c
+++ b/arch/x86/cpu/quark/msg_port.c
@@ -5,34 +5,49 @@
  */
 
 #include <common.h>
-#include <pci.h>
 #include <asm/arch/device.h>
 #include <asm/arch/msg_port.h>
+#include <asm/io.h>
+#include <asm/pci.h>
+
+/* Optimized pci config write dword routine */
+static void qrk_pci_write_config_dword(pci_dev_t dev, int offset, u32 value)
+{
+	outl(dev | offset | PCI_CFG_EN, PCI_REG_ADDR);
+	outl(value, PCI_REG_DATA);
+}
+
+/* Optimized pci config read dword routine */
+static void qrk_pci_read_config_dword(pci_dev_t dev, int offset, u32 *valuep)
+{
+	outl(dev | offset | PCI_CFG_EN, PCI_REG_ADDR);
+	*valuep = inl(PCI_REG_DATA);
+}
 
 void msg_port_setup(int op, int port, int reg)
 {
-	pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_REG,
-			       (((op) << 24) | ((port) << 16) |
-			       (((reg) << 8) & 0xff00) | MSG_BYTE_ENABLE));
+	qrk_pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_REG,
+				   (((op) << 24) | ((port) << 16) |
+				   (((reg) << 8) & 0xff00) | MSG_BYTE_ENABLE));
 }
 
 u32 msg_port_read(u8 port, u32 reg)
 {
 	u32 value;
 
-	pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG,
-			       reg & 0xffffff00);
+	qrk_pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG,
+				   reg & 0xffffff00);
 	msg_port_setup(MSG_OP_READ, port, reg);
-	pci_read_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, &value);
+	qrk_pci_read_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, &value);
 
 	return value;
 }
 
 void msg_port_write(u8 port, u32 reg, u32 value)
 {
-	pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, value);
-	pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG,
-			       reg & 0xffffff00);
+	qrk_pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, value);
+	qrk_pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG,
+				   reg & 0xffffff00);
 	msg_port_setup(MSG_OP_WRITE, port, reg);
 }
 
@@ -40,19 +55,19 @@ u32 msg_port_alt_read(u8 port, u32 reg)
 {
 	u32 value;
 
-	pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG,
-			       reg & 0xffffff00);
+	qrk_pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG,
+				   reg & 0xffffff00);
 	msg_port_setup(MSG_OP_ALT_READ, port, reg);
-	pci_read_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, &value);
+	qrk_pci_read_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, &value);
 
 	return value;
 }
 
 void msg_port_alt_write(u8 port, u32 reg, u32 value)
 {
-	pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, value);
-	pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG,
-			       reg & 0xffffff00);
+	qrk_pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, value);
+	qrk_pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG,
+				   reg & 0xffffff00);
 	msg_port_setup(MSG_OP_ALT_WRITE, port, reg);
 }
 
@@ -60,18 +75,18 @@ u32 msg_port_io_read(u8 port, u32 reg)
 {
 	u32 value;
 
-	pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG,
-			       reg & 0xffffff00);
+	qrk_pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG,
+				   reg & 0xffffff00);
 	msg_port_setup(MSG_OP_IO_READ, port, reg);
-	pci_read_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, &value);
+	qrk_pci_read_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, &value);
 
 	return value;
 }
 
 void msg_port_io_write(u8 port, u32 reg, u32 value)
 {
-	pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, value);
-	pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG,
-			       reg & 0xffffff00);
+	qrk_pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, value);
+	qrk_pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG,
+				   reg & 0xffffff00);
 	msg_port_setup(MSG_OP_IO_WRITE, port, reg);
 }
-- 
1.8.2.1



More information about the U-Boot mailing list