1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <console/console.h>
4 #include <device/pci_ehci.h>
5 #include <device/mmio.h>
6 #include <device/pci_ops.h>
7 #include <device/pci.h>
10 #include "ehci_debug.h"
14 static struct device_operations
*ehci_drv_ops
;
15 static struct device_operations ehci_dbg_ops
;
18 int ehci_debug_hw_enable(unsigned int *base
, unsigned int *dbg_offset
)
20 pci_devfn_t dev
= pci_ehci_dbg_dev(CONFIG_USBDEBUG_HCD_INDEX
);
22 /* We only support controllers on bus 0. */
23 if (PCI_DEV2SEGBUS(dev
) != 0)
26 u32
class = pci_s_read_config32(dev
, PCI_CLASS_REVISION
) >> 8;
27 if (class != PCI_EHCI_CLASSCODE
)
30 u8 pm_cap
= pci_s_find_capability(dev
, PCI_CAP_ID_PM
);
32 u16 pm_ctrl
= pci_s_read_config16(dev
, pm_cap
+ PCI_PM_CTRL
);
33 /* Set to D0 and disable PM events. */
34 pm_ctrl
&= ~PCI_PM_CTRL_PME_ENABLE
;
35 pm_ctrl
&= ~PCI_PM_CTRL_STATE_MASK
;
36 pci_s_write_config16(dev
, pm_cap
+ PCI_PM_CTRL
, pm_ctrl
);
39 u8 pos
= pci_s_find_capability(dev
, PCI_CAP_ID_EHCI_DEBUG
);
43 u32 cap
= pci_s_read_config32(dev
, pos
);
45 /* FIXME: We should remove static EHCI_BAR_INDEX. */
46 u8 ehci_bar
= 0x10 + 4 * ((cap
>> 29) - 1);
47 if (ehci_bar
!= EHCI_BAR_INDEX
)
50 pci_s_write_config32(dev
, ehci_bar
, CONFIG_EHCI_BAR
);
52 pci_s_write_config8(dev
, PCI_COMMAND
, PCI_COMMAND_MEMORY
|
55 *base
= CONFIG_EHCI_BAR
;
56 *dbg_offset
= (cap
>>16) & 0x1ffc;
61 void ehci_debug_select_port(unsigned int port
)
63 pci_devfn_t dbg_dev
= pci_ehci_dbg_dev(CONFIG_USBDEBUG_HCD_INDEX
);
64 pci_ehci_dbg_set_port(dbg_dev
, port
);
68 static void pci_ehci_set_resources(struct device
*dev
)
72 printk(BIOS_DEBUG
, "%s EHCI Debug Port hook triggered\n", dev_path(dev
));
75 if (ehci_drv_ops
->set_resources
)
76 ehci_drv_ops
->set_resources(dev
);
77 res
= probe_resource(dev
, EHCI_BAR_INDEX
);
81 usbdebug_re_enable((u32
)res
->base
);
82 report_resource_stored(dev
, res
, "");
83 printk(BIOS_DEBUG
, "%s EHCI Debug Port relocated\n", dev_path(dev
));
86 void pci_ehci_read_resources(struct device
*dev
)
88 pci_devfn_t dbg_dev
= pci_ehci_dbg_dev(CONFIG_USBDEBUG_HCD_INDEX
);
90 if (!ehci_drv_ops
&& pci_match_simple_dev(dev
, dbg_dev
)) {
91 memcpy(&ehci_dbg_ops
, dev
->ops
, sizeof(ehci_dbg_ops
));
92 ehci_drv_ops
= dev
->ops
;
93 ehci_dbg_ops
.set_resources
= pci_ehci_set_resources
;
94 dev
->ops
= &ehci_dbg_ops
;
95 printk(BIOS_DEBUG
, "%s EHCI BAR hook registered\n", dev_path(dev
));
97 printk(BIOS_DEBUG
, "More than one caller of %s from %s\n", __func__
, dev_path(dev
));
100 pci_dev_read_resources(dev
);
104 u8
*pci_ehci_base_regs(pci_devfn_t sdev
)
106 u32 bar
= pci_s_read_config32(sdev
, EHCI_BAR_INDEX
) & ~0x0f;
107 u8
*base
= (u8
*)(uintptr_t)bar
;
108 return base
+ HC_LENGTH(read32(base
));