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>
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
);
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
;
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
) {
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
) {
111 const char *scope
= acpi_device_scope(dev
);
112 const char *name
= acpi_device_name(dev
);
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
));
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
,
152 .acpi_name
= bh720_acpi_name
,
153 .acpi_fill_ssdt
= bh720_fill_ssdt
156 static const unsigned short pci_device_ids
[] = {
161 static const struct pci_driver bayhub_bh720 __pci_driver
= {
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",