1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2016 Google, Inc
4  *
5  * From coreboot broadwell support
6  */
7 
8 #include <common.h>
9 #include <dm.h>
10 #include <log.h>
11 #include <pch.h>
12 #include <asm/global_data.h>
13 #include <asm/intel_regs.h>
14 #include <asm/io.h>
15 #include <asm/lpc_common.h>
16 #include <asm/arch/pch.h>
17 #include <asm/arch/spi.h>
18 
set_spi_speed(void)19 static void set_spi_speed(void)
20 {
21 	u32 fdod;
22 	u8 ssfc;
23 
24 	/* Observe SPI Descriptor Component Section 0 */
25 	writel(0x1000, SPI_REG(SPIBAR_FDOC));
26 
27 	/* Extract the Write/Erase SPI Frequency from descriptor */
28 	fdod = readl(SPI_REG(SPIBAR_FDOD));
29 	fdod >>= 24;
30 	fdod &= 7;
31 
32 	/* Set Software Sequence frequency to match */
33 	ssfc = readb(SPI_REG(SPIBAR_SSFC + 2));
34 	ssfc &= ~7;
35 	ssfc |= fdod;
36 	writeb(ssfc, SPI_REG(SPIBAR_SSFC + 2));
37 }
38 
broadwell_lpc_early_init(struct udevice * dev)39 static int broadwell_lpc_early_init(struct udevice *dev)
40 {
41 	set_spi_speed();
42 
43 	return 0;
44 }
45 
lpc_init_extra(struct udevice * dev)46 static int lpc_init_extra(struct udevice *dev)
47 {
48 	return 0;
49 }
50 
broadwell_lpc_probe(struct udevice * dev)51 static int broadwell_lpc_probe(struct udevice *dev)
52 {
53 	int ret;
54 
55 	if (!(gd->flags & GD_FLG_RELOC)) {
56 		ret = lpc_common_early_init(dev);
57 		if (ret) {
58 			debug("%s: lpc_early_init() failed\n", __func__);
59 			return ret;
60 		}
61 
62 		return broadwell_lpc_early_init(dev);
63 	}
64 
65 	return lpc_init_extra(dev);
66 }
67 
68 static const struct udevice_id broadwell_lpc_ids[] = {
69 	{ .compatible = "intel,broadwell-lpc" },
70 	{ }
71 };
72 
73 U_BOOT_DRIVER(broadwell_lpc_drv) = {
74 	.name		= "lpc",
75 	.id		= UCLASS_LPC,
76 	.of_match	= broadwell_lpc_ids,
77 	.probe		= broadwell_lpc_probe,
78 };
79