blob: 6a769effa6261b5993b3be6192434ed376fcd906 [file] [log] [blame]
Patrick Georgi02363b52020-05-05 20:48:50 +02001/* This file is part of the coreboot project. */
Patrick Georgiac959032020-05-05 22:49:26 +02002/* SPDX-License-Identifier: GPL-2.0-or-later */
Stefan Reinauer2e73e192010-01-17 13:52:50 +00003
Stefan Reinauer2e73e192010-01-17 13:52:50 +00004#include <device/device.h>
5#include <device/pci.h>
6#include <device/pci_ops.h>
Stefan Reinauer2e73e192010-01-17 13:52:50 +00007#include <console/console.h>
8#include <device/cardbus.h>
9#include "pci7420.h"
10#include "chip.h"
11
12#ifdef ODD_IRQ_FIXUP
13static int cardbus_count = 0;
14#endif
15
Elyes HAOUASa3970892018-05-19 10:39:20 +020016static void pci7420_cardbus_init(struct device *dev)
Stefan Reinauer2e73e192010-01-17 13:52:50 +000017{
18 u8 reg8;
19 u16 reg16;
20 u32 reg32;
21
22 struct southbridge_ti_pci7420_config *config = dev->chip_info;
23 int smartcard_enabled = 0;
24
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000025 printk(BIOS_DEBUG, "TI PCI7420/7620 init\n");
Stefan Reinauer2e73e192010-01-17 13:52:50 +000026
27 if (!config) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000028 printk(BIOS_DEBUG, "PCI7420: No configuration found.\n");
Stefan Reinauer2e73e192010-01-17 13:52:50 +000029 } else {
30 smartcard_enabled = config->smartcard_enabled;
31 }
32
33 reg32 = pci_read_config32(dev, SYSCTL);
34 reg32 |= RIMUX;
35 pci_write_config32(dev, SYSCTL, reg32);
36
37 /* Enable SPKROUT */
38 reg8 = pci_read_config8(dev, CARDCTL);
39 reg8 |= SPKROUTEN;
40 pci_write_config8(dev, CARDCTL, reg8);
41
42 /* Power switch select and FM disable */
43 reg16 = pci_read_config16(dev, GENCTL);
44 reg16 |= P12V_SW_SEL; // 12V capable power switch
45 if (smartcard_enabled == 0)
46 reg16 |= DISABLE_FM;
47 pci_write_config16(dev, GENCTL, reg16);
48
49 /* Multifunction routing status */
50 pci_write_config32(dev, MFUNC, 0x018a1b22);
51
52#ifdef ODD_IRQ_FIXUP
53 /* This is a workaround for buggy kernels. This should
54 * probably be read from the device tree, but as long
55 * as only one mainboard is using this bridge it does
56 * not matter.
57 *
58 * Basically what we do here is assign INTA to the first
59 * cardbus controller, and INTB to the second one. We know
60 * there are only two of them.
61 */
62 pci_write_config8(dev, PCI_INTERRUPT_PIN, cardbus_count);
63 cardbus_count++;
64#endif
65}
66
Elyes HAOUASa3970892018-05-19 10:39:20 +020067static void pci7420_cardbus_read_resources(struct device *dev)
Stefan Reinauer2e73e192010-01-17 13:52:50 +000068{
69 cardbus_read_resources(dev);
70}
71
Elyes HAOUASa3970892018-05-19 10:39:20 +020072static void pci7420_cardbus_set_resources(struct device *dev)
Stefan Reinauer2e73e192010-01-17 13:52:50 +000073{
Paul Menzeld0cdcae2014-08-08 15:24:31 +020074 printk(BIOS_DEBUG, "%s In set resources\n",dev_path(dev));
Stefan Reinauer2e73e192010-01-17 13:52:50 +000075
76 pci_dev_set_resources(dev);
77
Paul Menzeld0cdcae2014-08-08 15:24:31 +020078 printk(BIOS_DEBUG, "%s done set resources\n",dev_path(dev));
Stefan Reinauer2e73e192010-01-17 13:52:50 +000079}
80
81static struct device_operations ti_pci7420_ops = {
82 .read_resources = pci7420_cardbus_read_resources,
83 .set_resources = pci7420_cardbus_set_resources,
84 .enable_resources = cardbus_enable_resources,
85 .init = pci7420_cardbus_init,
Myles Watson84e8e452010-06-07 17:12:57 +000086 .scan_bus = pci_scan_bridge,
Stefan Reinauer2e73e192010-01-17 13:52:50 +000087};
88
89static const struct pci_driver ti_pci7420_driver __pci_driver = {
90 .ops = &ti_pci7420_ops,
91 .vendor = 0x104c,
92 .device = 0xac8e,
93};
94
95static const struct pci_driver ti_pci7620_driver __pci_driver = {
96 .ops = &ti_pci7420_ops,
97 .vendor = 0x104c,
98 .device = 0xac8d,
99};
100
Stefan Reinauer2e73e192010-01-17 13:52:50 +0000101struct chip_operations southbridge_ti_pci7420_ops = {
102 CHIP_NAME("Texas Instruments PCI7420/7620 Cardbus Controller")
Stefan Reinauer2e73e192010-01-17 13:52:50 +0000103};