1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <console/console.h>
4 #include <device/device.h>
5 #include <device/pci.h>
6 #include <device/pci_ops.h>
7 #include <device/cardbus.h>
11 * I don't think this code is quite correct but it is close.
12 * Anyone with a cardbus bridge and a little time should be able
13 * to make it usable quickly. -- Eric Biederman 24 March 2005
17 * IO should be max 256 bytes. However, since we may have a P2P bridge below
18 * a cardbus bridge, we need 4K.
20 #define CARDBUS_IO_SIZE 4096
21 #define CARDBUS_MEM_SIZE (32 * 1024 * 1024)
23 static void cardbus_record_bridge_resource(struct device
*dev
, resource_t moving
,
24 resource_t min_size
, unsigned int index
, unsigned long type
)
26 struct resource
*resource
;
30 /* Initialize the constraints on the current bus. */
35 resource
= new_resource(dev
, index
);
39 while ((moving
& step
) == 0) {
43 resource
->gran
= gran
;
44 resource
->align
= gran
;
45 resource
->limit
= moving
| (step
- 1);
46 resource
->flags
= type
;
48 /* Don't let the minimum size exceed what we can put in the resource. */
49 if ((min_size
- 1) > resource
->limit
)
50 min_size
= resource
->limit
+ 1;
52 resource
->size
= min_size
;
55 void cardbus_read_resources(struct device
*dev
)
57 resource_t moving_base
, moving_limit
, moving
;
61 /* See if needs a card control registers base address. */
63 pci_get_resource(dev
, PCI_BASE_ADDRESS_0
);
65 compact_resources(dev
);
67 /* See which bridge I/O resources are implemented. */
68 moving_base
= pci_moving_config32(dev
, PCI_CB_IO_BASE_0
);
69 moving_limit
= pci_moving_config32(dev
, PCI_CB_IO_LIMIT_0
);
70 moving
= moving_base
& moving_limit
;
72 /* Initialize the I/O space constraints on the current bus. */
73 cardbus_record_bridge_resource(dev
, moving
, CARDBUS_IO_SIZE
,
74 PCI_CB_IO_BASE_0
, IORESOURCE_IO
);
76 /* See which bridge I/O resources are implemented. */
77 moving_base
= pci_moving_config32(dev
, PCI_CB_IO_BASE_1
);
78 moving_limit
= pci_moving_config32(dev
, PCI_CB_IO_LIMIT_1
);
79 moving
= moving_base
& moving_limit
;
81 /* Initialize the I/O space constraints on the current bus. */
82 cardbus_record_bridge_resource(dev
, moving
, CARDBUS_IO_SIZE
,
83 PCI_CB_IO_BASE_1
, IORESOURCE_IO
);
85 /* If I can, enable prefetch for mem0. */
86 ctl
= pci_read_config16(dev
, PCI_CB_BRIDGE_CONTROL
);
87 ctl
&= ~PCI_CB_BRIDGE_CTL_PREFETCH_MEM0
;
88 ctl
&= ~PCI_CB_BRIDGE_CTL_PREFETCH_MEM1
;
89 ctl
|= PCI_CB_BRIDGE_CTL_PREFETCH_MEM0
;
90 pci_write_config16(dev
, PCI_CB_BRIDGE_CONTROL
, ctl
);
91 ctl
= pci_read_config16(dev
, PCI_CB_BRIDGE_CONTROL
);
93 /* See which bridge memory resources are implemented. */
94 moving_base
= pci_moving_config32(dev
, PCI_CB_MEMORY_BASE_0
);
95 moving_limit
= pci_moving_config32(dev
, PCI_CB_MEMORY_LIMIT_0
);
96 moving
= moving_base
& moving_limit
;
98 /* Initialize the memory space constraints on the current bus. */
99 type
= IORESOURCE_MEM
;
100 if (ctl
& PCI_CB_BRIDGE_CTL_PREFETCH_MEM0
)
101 type
|= IORESOURCE_PREFETCH
;
102 cardbus_record_bridge_resource(dev
, moving
, CARDBUS_MEM_SIZE
,
103 PCI_CB_MEMORY_BASE_0
, type
);
105 /* See which bridge memory resources are implemented. */
106 moving_base
= pci_moving_config32(dev
, PCI_CB_MEMORY_BASE_1
);
107 moving_limit
= pci_moving_config32(dev
, PCI_CB_MEMORY_LIMIT_1
);
108 moving
= moving_base
& moving_limit
;
110 /* Initialize the memory space constraints on the current bus. */
111 cardbus_record_bridge_resource(dev
, moving
, CARDBUS_MEM_SIZE
,
112 PCI_CB_MEMORY_BASE_1
, IORESOURCE_MEM
);
114 compact_resources(dev
);
117 void cardbus_enable_resources(struct device
*dev
)
121 ctrl
= pci_read_config16(dev
, PCI_CB_BRIDGE_CONTROL
);
122 ctrl
|= (dev
->link_list
->bridge_ctrl
& (
124 PCI_BRIDGE_CTL_MASTER_ABORT
|
125 PCI_BRIDGE_CTL_BUS_RESET
));
127 ctrl
|= (PCI_CB_BRIDGE_CTL_PARITY
| PCI_CB_BRIDGE_CTL_SERR
);
128 printk(BIOS_DEBUG
, "%s bridge ctrl <- %04x\n", dev_path(dev
), ctrl
);
129 pci_write_config16(dev
, PCI_CB_BRIDGE_CONTROL
, ctrl
);
131 pci_dev_enable_resources(dev
);
134 struct device_operations default_cardbus_ops_bus
= {
135 .read_resources
= cardbus_read_resources
,
136 .set_resources
= pci_dev_set_resources
,
137 .enable_resources
= cardbus_enable_resources
,
138 .scan_bus
= pci_scan_bridge
,
139 .reset_bus
= pci_bus_reset
,