Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/mips/pci/fixup-sb1250.c
26424 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
* Copyright (C) 2004, 2006 MIPS Technologies, Inc. All rights reserved.
4
* Author: Maciej W. Rozycki <[email protected]>
5
* Copyright (C) 2018 Maciej W. Rozycki
6
*/
7
8
#include <linux/dma-mapping.h>
9
#include <linux/pci.h>
10
11
/*
12
* Set the BCM1250, etc. PCI host bridge's TRDY timeout
13
* to the finite max.
14
*/
15
static void quirk_sb1250_pci(struct pci_dev *dev)
16
{
17
pci_write_config_byte(dev, 0x40, 0xff);
18
}
19
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIBYTE, PCI_DEVICE_ID_BCM1250_PCI,
20
quirk_sb1250_pci);
21
22
/*
23
* The BCM1250, etc. PCI host bridge does not support DAC on its 32-bit
24
* bus, so we set the bus's DMA limit accordingly. However the HT link
25
* down the artificial PCI-HT bridge supports 40-bit addressing and the
26
* SP1011 HT-PCI bridge downstream supports both DAC and a 64-bit bus
27
* width, so we record the PCI-HT bridge's secondary and subordinate bus
28
* numbers and do not set the limit for devices present in the inclusive
29
* range of those.
30
*/
31
struct sb1250_bus_dma_limit_exclude {
32
bool set;
33
unsigned char start;
34
unsigned char end;
35
};
36
37
static int sb1250_bus_dma_limit(struct pci_dev *dev, void *data)
38
{
39
struct sb1250_bus_dma_limit_exclude *exclude = data;
40
bool exclude_this;
41
bool ht_bridge;
42
43
exclude_this = exclude->set && (dev->bus->number >= exclude->start &&
44
dev->bus->number <= exclude->end);
45
ht_bridge = !exclude->set && (dev->vendor == PCI_VENDOR_ID_SIBYTE &&
46
dev->device == PCI_DEVICE_ID_BCM1250_HT);
47
48
if (exclude_this) {
49
dev_dbg(&dev->dev, "not disabling DAC for device");
50
} else if (ht_bridge) {
51
exclude->start = dev->subordinate->number;
52
exclude->end = pci_bus_max_busnr(dev->subordinate);
53
exclude->set = true;
54
dev_dbg(&dev->dev, "not disabling DAC for [bus %02x-%02x]",
55
exclude->start, exclude->end);
56
} else {
57
dev_dbg(&dev->dev, "disabling DAC for device");
58
dev->dev.bus_dma_limit = DMA_BIT_MASK(32);
59
}
60
61
return 0;
62
}
63
64
static void quirk_sb1250_pci_dac(struct pci_dev *dev)
65
{
66
struct sb1250_bus_dma_limit_exclude exclude = { .set = false };
67
68
pci_walk_bus(dev->bus, sb1250_bus_dma_limit, &exclude);
69
}
70
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SIBYTE, PCI_DEVICE_ID_BCM1250_PCI,
71
quirk_sb1250_pci_dac);
72
73
/*
74
* The BCM1250, etc. PCI/HT bridge reports as a host bridge.
75
*/
76
static void quirk_sb1250_ht(struct pci_dev *dev)
77
{
78
dev->class = PCI_CLASS_BRIDGE_PCI_NORMAL;
79
}
80
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIBYTE, PCI_DEVICE_ID_BCM1250_HT,
81
quirk_sb1250_ht);
82
83
/*
84
* Set the SP1011 HT/PCI bridge's TRDY timeout to the finite max.
85
*/
86
static void quirk_sp1011(struct pci_dev *dev)
87
{
88
pci_write_config_byte(dev, 0x64, 0xff);
89
}
90
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIPACKETS, PCI_DEVICE_ID_SP1011,
91
quirk_sp1011);
92
93