blob: ce807dd718db041727bb68a7a2ae9846a035ab86 [file] [log] [blame]
Stefan Reinauer2e73e192010-01-17 13:52:50 +00001/*
Uwe Hermannc70e9fc2010-02-15 23:10:19 +00002 * This file is part of the coreboot project.
Stefan Reinauer2e73e192010-01-17 13:52:50 +00003 *
Uwe Hermannc70e9fc2010-02-15 23:10:19 +00004 * Copyright (C) 2008-2009 coresystems GmbH
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
Stefan Reinauer2e73e192010-01-17 13:52:50 +000010 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
Stefan Reinauer2e73e192010-01-17 13:52:50 +000015 */
16
17#include <arch/io.h>
18#include <device/device.h>
19#include <device/pci.h>
20#include <device/pci_ops.h>
21#include <device/pci_ids.h>
22#include <console/console.h>
23#include <device/cardbus.h>
24#include "pci7420.h"
25#include "chip.h"
26
27#ifdef ODD_IRQ_FIXUP
28static int cardbus_count = 0;
29#endif
30
31static void pci7420_cardbus_init(device_t dev)
32{
33 u8 reg8;
34 u16 reg16;
35 u32 reg32;
36
37 struct southbridge_ti_pci7420_config *config = dev->chip_info;
38 int smartcard_enabled = 0;
39
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000040 printk(BIOS_DEBUG, "TI PCI7420/7620 init\n");
Stefan Reinauer2e73e192010-01-17 13:52:50 +000041
42 if (!config) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000043 printk(BIOS_DEBUG, "PCI7420: No configuration found.\n");
Stefan Reinauer2e73e192010-01-17 13:52:50 +000044 } else {
45 smartcard_enabled = config->smartcard_enabled;
46 }
47
48 reg32 = pci_read_config32(dev, SYSCTL);
49 reg32 |= RIMUX;
50 pci_write_config32(dev, SYSCTL, reg32);
51
52 /* Enable SPKROUT */
53 reg8 = pci_read_config8(dev, CARDCTL);
54 reg8 |= SPKROUTEN;
55 pci_write_config8(dev, CARDCTL, reg8);
56
57 /* Power switch select and FM disable */
58 reg16 = pci_read_config16(dev, GENCTL);
59 reg16 |= P12V_SW_SEL; // 12V capable power switch
60 if (smartcard_enabled == 0)
61 reg16 |= DISABLE_FM;
62 pci_write_config16(dev, GENCTL, reg16);
63
64 /* Multifunction routing status */
65 pci_write_config32(dev, MFUNC, 0x018a1b22);
66
67#ifdef ODD_IRQ_FIXUP
68 /* This is a workaround for buggy kernels. This should
69 * probably be read from the device tree, but as long
70 * as only one mainboard is using this bridge it does
71 * not matter.
72 *
73 * Basically what we do here is assign INTA to the first
74 * cardbus controller, and INTB to the second one. We know
75 * there are only two of them.
76 */
77 pci_write_config8(dev, PCI_INTERRUPT_PIN, cardbus_count);
78 cardbus_count++;
79#endif
80}
81
Stefan Reinauer53b0ea42010-03-22 11:50:52 +000082static void pci7420_cardbus_read_resources(device_t dev)
Stefan Reinauer2e73e192010-01-17 13:52:50 +000083{
84 cardbus_read_resources(dev);
85}
86
Stefan Reinauer53b0ea42010-03-22 11:50:52 +000087static void pci7420_cardbus_set_resources(device_t dev)
Stefan Reinauer2e73e192010-01-17 13:52:50 +000088{
Paul Menzeld0cdcae2014-08-08 15:24:31 +020089 printk(BIOS_DEBUG, "%s In set resources\n",dev_path(dev));
Stefan Reinauer2e73e192010-01-17 13:52:50 +000090
91 pci_dev_set_resources(dev);
92
Paul Menzeld0cdcae2014-08-08 15:24:31 +020093 printk(BIOS_DEBUG, "%s done set resources\n",dev_path(dev));
Stefan Reinauer2e73e192010-01-17 13:52:50 +000094}
95
96static struct device_operations ti_pci7420_ops = {
97 .read_resources = pci7420_cardbus_read_resources,
98 .set_resources = pci7420_cardbus_set_resources,
99 .enable_resources = cardbus_enable_resources,
100 .init = pci7420_cardbus_init,
Myles Watson84e8e452010-06-07 17:12:57 +0000101 .scan_bus = pci_scan_bridge,
Stefan Reinauer2e73e192010-01-17 13:52:50 +0000102};
103
104static const struct pci_driver ti_pci7420_driver __pci_driver = {
105 .ops = &ti_pci7420_ops,
106 .vendor = 0x104c,
107 .device = 0xac8e,
108};
109
110static const struct pci_driver ti_pci7620_driver __pci_driver = {
111 .ops = &ti_pci7420_ops,
112 .vendor = 0x104c,
113 .device = 0xac8d,
114};
115
116static void ti_pci7420_enable_dev(device_t dev)
117{
118 /* Nothing here yet */
119}
120
121struct chip_operations southbridge_ti_pci7420_ops = {
122 CHIP_NAME("Texas Instruments PCI7420/7620 Cardbus Controller")
123 .enable_dev = ti_pci7420_enable_dev,
124};