acpi: Add IORT helper functions
[coreboot2.git] / src / drivers / generic / bayhub / bh720.c
blobfb782caf4cbbcf5e1896a910b182d1ae364b916b
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 /* Driver for BayHub Technology BH720 PCI to eMMC 5.0 HS200 bridge */
5 #include <console/console.h>
6 #include <device/device.h>
7 #include <device/mmio.h>
8 #include <device/pci.h>
9 #include <device/pci_ops.h>
10 #include <device/pci_ids.h>
11 #include <acpi/acpigen.h>
12 #include <acpi/acpigen_pci.h>
13 #include "chip.h"
14 #include "bh720.h"
16 #define BH720_ACPI_NAME "BHUB"
18 static u32 bh720_read_pcr(u32 sdbar, u32 addr)
20 write32p(sdbar + BH720_MEM_RW_ADR, BH720_MEM_RW_READ | addr);
21 return read32p(sdbar + BH720_MEM_RW_DATA);
24 static void bh720_write_pcr(u32 sdbar, u32 addr, u32 data)
26 write32p(sdbar + BH720_MEM_RW_DATA, data);
27 write32p(sdbar + BH720_MEM_RW_ADR, BH720_MEM_RW_WRITE | addr);
30 static void bh720_rmw_pcr(u32 sdbar, u32 addr, u32 clear, u32 set)
32 u32 data = bh720_read_pcr(sdbar, addr);
33 data &= ~clear;
34 data |= set;
35 bh720_write_pcr(sdbar, addr, data);
38 static void bh720_program_hs200_mode(struct device *dev)
40 u32 sdbar = pci_read_config32(dev, PCI_BASE_ADDRESS_1);
42 /* Enable Memory Access Function */
43 write32p(sdbar + BH720_MEM_ACCESS_EN, 0x40000000);
44 bh720_write_pcr(sdbar, 0xd0, 0x80000000);
46 /* Set EMMC VCCQ 1.8V PCR 0x308[4] */
47 bh720_rmw_pcr(sdbar, BH720_PCR_EMMC_SETTING, 0, BH720_PCR_EMMC_SETTING_1_8V);
49 /* Set Base clock to 200MHz(PCR 0x304[31:16] = 0x2510) */
50 bh720_rmw_pcr(sdbar, BH720_PCR_DrvStrength_PLL, 0xffff << 16, 0x2510 << 16);
52 /* Use PLL Base clock PCR 0x3E4[22] = 1 */
53 bh720_rmw_pcr(sdbar, BH720_PCR_CSR, 0, BH720_PCR_CSR_EMMC_MODE_SEL);
55 /* Disable Memory Access */
56 bh720_write_pcr(sdbar, 0xd0, 0x80000001);
57 write32p(sdbar + BH720_MEM_ACCESS_EN, 0x80000000);
60 static void bh720_init(struct device *dev)
62 struct drivers_generic_bayhub_config *config = dev->chip_info;
64 pci_dev_init(dev);
66 if (config && config->power_saving) {
68 * This procedure for enabling power-saving mode is from the
69 * BayHub BIOS Implementation Guideline document.
71 pci_write_config32(dev, BH720_PROTECT,
72 BH720_PROTECT_OFF | BH720_PROTECT_LOCK_OFF);
73 pci_or_config32(dev, BH720_RTD3_L1, BH720_RTD3_L1_DISABLE_L1);
74 pci_or_config32(dev, BH720_LINK_CTRL,
75 BH720_LINK_CTRL_L0_ENABLE |
76 BH720_LINK_CTRL_L1_ENABLE);
77 pci_or_config32(dev, BH720_LINK_CTRL, BH720_LINK_CTRL_CLKREQ);
78 pci_update_config32(dev, BH720_MISC2, ~BH720_MISC2_ASPM_DISABLE,
79 BH720_MISC2_APSM_CLKREQ_L1 |
80 BH720_MISC2_APSM_PHY_L1);
81 pci_write_config32(dev, BH720_PROTECT,
82 BH720_PROTECT_ON | BH720_PROTECT_LOCK_ON);
84 printk(BIOS_INFO, "BayHub BH720: Power-saving enabled (link_ctrl=%#x)\n",
85 pci_read_config32(dev, BH720_LINK_CTRL));
88 if (config && !config->disable_hs200_mode)
89 bh720_program_hs200_mode(dev);
91 if (config && config->vih_tuning_value) {
92 /* Tune VIH */
93 u32 bh720_pcr_data;
94 pci_write_config32(dev, BH720_PROTECT,
95 BH720_PROTECT_OFF | BH720_PROTECT_LOCK_OFF);
96 bh720_pcr_data = pci_read_config32(dev, BH720_PCR_DrvStrength_PLL);
97 bh720_pcr_data &= 0xFFFFFF00;
98 bh720_pcr_data |= config->vih_tuning_value;
99 pci_write_config32(dev, BH720_PCR_DrvStrength_PLL, bh720_pcr_data);
100 pci_write_config32(dev, BH720_PROTECT,
101 BH720_PROTECT_ON | BH720_PROTECT_LOCK_ON);
105 static void bh720_fill_ssdt(const struct device *dev)
107 if (dev->path.type != DEVICE_PATH_PCI) {
108 return;
111 const char *scope = acpi_device_scope(dev);
112 const char *name = acpi_device_name(dev);
113 if (!scope || !name)
114 return;
116 /* Device */
117 acpigen_write_scope(scope);
118 acpigen_write_device(name);
120 acpigen_write_ADR_pci_device(dev);
121 acpigen_write_STA(acpi_device_status(dev));
123 /* Card */
124 acpigen_write_device("CARD");
125 acpigen_write_ADR(0x08); //eMMC is always on address 0x8
128 * Method (_RMV, 0, NotSerialized) { Return (0) }
130 acpigen_write_method("_RMV", 0); /* Method */
131 acpigen_emit_byte(RETURN_OP);
132 acpigen_write_byte(0);
133 acpigen_pop_len(); /* Method */
135 acpigen_pop_len(); /* Card */
137 acpigen_pop_len(); /* Device */
138 acpigen_pop_len(); /* Scope */
141 static const char *bh720_acpi_name(const struct device *dev)
143 return BH720_ACPI_NAME;
146 static struct device_operations bh720_ops = {
147 .read_resources = pci_dev_read_resources,
148 .set_resources = pci_dev_set_resources,
149 .enable_resources = pci_dev_enable_resources,
150 .ops_pci = &pci_dev_ops_pci,
151 .init = bh720_init,
152 .acpi_name = bh720_acpi_name,
153 .acpi_fill_ssdt = bh720_fill_ssdt
156 static const unsigned short pci_device_ids[] = {
157 PCI_DID_O2_BH720,
161 static const struct pci_driver bayhub_bh720 __pci_driver = {
162 .ops = &bh720_ops,
163 .vendor = PCI_VID_O2,
164 .devices = pci_device_ids,
167 struct chip_operations drivers_generic_bayhub_ops = {
168 .name = "BayHub Technology BH720 PCI to eMMC 5.0 HS200 bridge",