blob: 8358b6a8e9ee45af220b7db076afa4effe6f9303 [file] [log] [blame]
Angel Pons8a3453f2020-04-02 23:48:19 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Simon Glass38d875f2018-04-30 14:08:31 -06002
Martin Rothcddd6002019-09-23 17:38:27 -06003/* Driver for BayHub Technology BH720 PCI to eMMC 5.0 HS200 bridge */
4
Simon Glass38d875f2018-04-30 14:08:31 -06005#include <console/console.h>
6#include <device/device.h>
Angel Pons73c96762021-01-22 15:24:48 +01007#include <device/mmio.h>
Simon Glass38d875f2018-04-30 14:08:31 -06008#include <device/path.h>
9#include <device/pci.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +020010#include <device/pci_ops.h>
Simon Glass38d875f2018-04-30 14:08:31 -060011#include <device/pci_ids.h>
12#include "chip.h"
Kevin Chiu089b6852018-08-03 18:52:18 +080013#include "bh720.h"
Simon Glass38d875f2018-04-30 14:08:31 -060014
Angel Pons42e44332021-01-26 11:11:13 +010015static u32 bh720_read_pcr(u32 sdbar, u32 addr)
16{
17 write32((void *)(sdbar + BH720_MEM_RW_ADR), BH720_MEM_RW_READ | addr);
18 return read32((void *)(sdbar + BH720_MEM_RW_DATA));
19}
20
21static void bh720_write_pcr(u32 sdbar, u32 addr, u32 data)
22{
23 write32((void *)(sdbar + BH720_MEM_RW_DATA), data);
24 write32((void *)(sdbar + BH720_MEM_RW_ADR), BH720_MEM_RW_WRITE | addr);
25}
26
27static void bh720_rmw_pcr(u32 sdbar, u32 addr, u32 clear, u32 set)
28{
29 u32 data = bh720_read_pcr(sdbar, addr);
30 data &= ~clear;
31 data |= set;
32 bh720_write_pcr(sdbar, addr, data);
33}
34
Angel Pons73c96762021-01-22 15:24:48 +010035static void bh720_program_hs200_mode(struct device *dev)
Kevin Chiu089b6852018-08-03 18:52:18 +080036{
Angel Pons42e44332021-01-26 11:11:13 +010037 u32 sdbar = pci_read_config32(dev, PCI_BASE_ADDRESS_1);
Angel Pons73c96762021-01-22 15:24:48 +010038
39 /* Enable Memory Access Function */
40 write32((void *)(sdbar + BH720_MEM_ACCESS_EN), 0x40000000);
Angel Pons42e44332021-01-26 11:11:13 +010041 bh720_write_pcr(sdbar, 0xd0, 0x80000000);
Angel Pons73c96762021-01-22 15:24:48 +010042
43 /* Set EMMC VCCQ 1.8V PCR 0x308[4] */
Angel Pons42e44332021-01-26 11:11:13 +010044 bh720_rmw_pcr(sdbar, BH720_PCR_EMMC_SETTING, 0, BH720_PCR_EMMC_SETTING_1_8V);
Angel Pons73c96762021-01-22 15:24:48 +010045
46 /* Set Base clock to 200MHz(PCR 0x304[31:16] = 0x2510) */
Angel Pons42e44332021-01-26 11:11:13 +010047 bh720_rmw_pcr(sdbar, BH720_PCR_DrvStrength_PLL, 0xffff << 16, 0x2510 << 16);
Angel Pons73c96762021-01-22 15:24:48 +010048
49 /* Use PLL Base clock PCR 0x3E4[22] = 1 */
Angel Pons42e44332021-01-26 11:11:13 +010050 bh720_rmw_pcr(sdbar, BH720_PCR_CSR, 0, BH720_PCR_CSR_EMMC_MODE_SEL);
Angel Pons73c96762021-01-22 15:24:48 +010051
52 /* Disable Memory Access */
Angel Pons42e44332021-01-26 11:11:13 +010053 bh720_write_pcr(sdbar, 0xd0, 0x80000001);
Angel Pons73c96762021-01-22 15:24:48 +010054 write32((void *)(sdbar + BH720_MEM_ACCESS_EN), 0x80000000);
Kevin Chiu089b6852018-08-03 18:52:18 +080055}
Simon Glass38d875f2018-04-30 14:08:31 -060056
57static void bh720_init(struct device *dev)
58{
59 struct drivers_generic_bayhub_config *config = dev->chip_info;
60
61 pci_dev_init(dev);
62
63 if (config && config->power_saving) {
64 /*
65 * This procedure for enabling power-saving mode is from the
66 * BayHub BIOS Implementation Guideline document.
67 */
Simon Glass4f160492018-05-23 15:34:04 -060068 pci_write_config32(dev, BH720_PROTECT,
69 BH720_PROTECT_OFF | BH720_PROTECT_LOCK_OFF);
Simon Glass38d875f2018-04-30 14:08:31 -060070 pci_or_config32(dev, BH720_RTD3_L1, BH720_RTD3_L1_DISABLE_L1);
71 pci_or_config32(dev, BH720_LINK_CTRL,
72 BH720_LINK_CTRL_L0_ENABLE |
73 BH720_LINK_CTRL_L1_ENABLE);
74 pci_or_config32(dev, BH720_LINK_CTRL, BH720_LINK_CTRL_CLKREQ);
Simon Glass4f160492018-05-23 15:34:04 -060075 pci_update_config32(dev, BH720_MISC2, ~BH720_MISC2_ASPM_DISABLE,
76 BH720_MISC2_APSM_CLKREQ_L1 |
77 BH720_MISC2_APSM_PHY_L1);
78 pci_write_config32(dev, BH720_PROTECT,
79 BH720_PROTECT_ON | BH720_PROTECT_LOCK_ON);
80
Simon Glass38d875f2018-04-30 14:08:31 -060081 printk(BIOS_INFO, "BayHub BH720: Power-saving enabled (link_ctrl=%#x)\n",
82 pci_read_config32(dev, BH720_LINK_CTRL));
83 }
Kevin Chiu089b6852018-08-03 18:52:18 +080084
Angel Pons73c96762021-01-22 15:24:48 +010085 if (config && !config->disable_hs200_mode)
86 bh720_program_hs200_mode(dev);
Angel Ponse4abe7f2021-01-22 15:12:14 +010087
88 if (config && config->vih_tuning_value) {
89 /* Tune VIH */
90 u32 bh720_pcr_data;
91 pci_write_config32(dev, BH720_PROTECT,
92 BH720_PROTECT_OFF | BH720_PROTECT_LOCK_OFF);
93 bh720_pcr_data = pci_read_config32(dev, BH720_PCR_DrvStrength_PLL);
94 bh720_pcr_data &= 0xFFFFFF00;
95 bh720_pcr_data |= config->vih_tuning_value;
96 pci_write_config32(dev, BH720_PCR_DrvStrength_PLL, bh720_pcr_data);
97 pci_write_config32(dev, BH720_PROTECT,
98 BH720_PROTECT_ON | BH720_PROTECT_LOCK_ON);
99 }
Simon Glass38d875f2018-04-30 14:08:31 -0600100}
101
Simon Glass38d875f2018-04-30 14:08:31 -0600102static struct device_operations bh720_ops = {
103 .read_resources = pci_dev_read_resources,
104 .set_resources = pci_dev_set_resources,
105 .enable_resources = pci_dev_enable_resources,
Angel Pons1fc0edd2020-05-31 00:03:28 +0200106 .ops_pci = &pci_dev_ops_pci,
Simon Glass38d875f2018-04-30 14:08:31 -0600107 .init = bh720_init,
108};
109
110static const unsigned short pci_device_ids[] = {
Felix Singer43b7f412022-03-07 04:34:52 +0100111 PCI_DID_O2_BH720,
Simon Glass38d875f2018-04-30 14:08:31 -0600112 0
113};
114
115static const struct pci_driver bayhub_bh720 __pci_driver = {
116 .ops = &bh720_ops,
Felix Singer43b7f412022-03-07 04:34:52 +0100117 .vendor = PCI_VID_O2,
Simon Glass38d875f2018-04-30 14:08:31 -0600118 .devices = pci_device_ids,
119};
120
Kyösti Mälkki08c76e12019-08-25 13:05:46 +0300121struct chip_operations drivers_generic_bayhub_ops = {
Simon Glass38d875f2018-04-30 14:08:31 -0600122 CHIP_NAME("BayHub Technology BH720 PCI to eMMC 5.0 HS200 bridge")
Simon Glass38d875f2018-04-30 14:08:31 -0600123};