~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/u-boot/drivers/pci/pci_gt64120.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2013 Gabor Juhos <juhosg@openwrt.org>
 
3
 *
 
4
 * Based on the Linux implementation.
 
5
 *   Copyright (C) 1999, 2000, 2004  MIPS Technologies, Inc.
 
6
 *   Authors: Carsten Langgaard <carstenl@mips.com>
 
7
 *            Maciej W. Rozycki <macro@mips.com>
 
8
 *
 
9
 * SPDX-License-Identifier:     GPL-2.0
 
10
 */
 
11
 
 
12
#include <common.h>
 
13
#include <gt64120.h>
 
14
#include <pci.h>
 
15
#include <pci_gt64120.h>
 
16
 
 
17
#include <asm/io.h>
 
18
 
 
19
#define PCI_ACCESS_READ  0
 
20
#define PCI_ACCESS_WRITE 1
 
21
 
 
22
struct gt64120_regs {
 
23
        u8      unused_000[0xc18];
 
24
        u32     intrcause;
 
25
        u8      unused_c1c[0x0dc];
 
26
        u32     pci0_cfgaddr;
 
27
        u32     pci0_cfgdata;
 
28
};
 
29
 
 
30
struct gt64120_pci_controller {
 
31
        struct pci_controller hose;
 
32
        struct gt64120_regs *regs;
 
33
};
 
34
 
 
35
static inline struct gt64120_pci_controller *
 
36
hose_to_gt64120(struct pci_controller *hose)
 
37
{
 
38
        return container_of(hose, struct gt64120_pci_controller, hose);
 
39
}
 
40
 
 
41
#define GT_INTRCAUSE_ABORT_BITS \
 
42
                (GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT)
 
43
 
 
44
static int gt_config_access(struct gt64120_pci_controller *gt,
 
45
                            unsigned char access_type, pci_dev_t bdf,
 
46
                            int where, u32 *data)
 
47
{
 
48
        unsigned int bus = PCI_BUS(bdf);
 
49
        unsigned int dev = PCI_DEV(bdf);
 
50
        unsigned int devfn = PCI_DEV(bdf) << 3 | PCI_FUNC(bdf);
 
51
        u32 intr;
 
52
        u32 addr;
 
53
        u32 val;
 
54
 
 
55
        if (bus == 0 && dev >= 31) {
 
56
                /* Because of a bug in the galileo (for slot 31). */
 
57
                return -1;
 
58
        }
 
59
 
 
60
        if (access_type == PCI_ACCESS_WRITE)
 
61
                debug("PCI WR %02x:%02x.%x reg:%02d data:%08x\n",
 
62
                      PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf), where, *data);
 
63
 
 
64
        /* Clear cause register bits */
 
65
        writel(~GT_INTRCAUSE_ABORT_BITS, &gt->regs->intrcause);
 
66
 
 
67
        addr = GT_PCI0_CFGADDR_CONFIGEN_BIT;
 
68
        addr |= bus << GT_PCI0_CFGADDR_BUSNUM_SHF;
 
69
        addr |= devfn << GT_PCI0_CFGADDR_FUNCTNUM_SHF;
 
70
        addr |= (where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF;
 
71
 
 
72
        /* Setup address */
 
73
        writel(addr, &gt->regs->pci0_cfgaddr);
 
74
 
 
75
        if (access_type == PCI_ACCESS_WRITE) {
 
76
                if (bus == 0 && dev == 0) {
 
77
                        /*
 
78
                         * The Galileo system controller is acting
 
79
                         * differently than other devices.
 
80
                         */
 
81
                        val = *data;
 
82
                } else {
 
83
                        val = cpu_to_le32(*data);
 
84
                }
 
85
 
 
86
                writel(val, &gt->regs->pci0_cfgdata);
 
87
        } else {
 
88
                val = readl(&gt->regs->pci0_cfgdata);
 
89
 
 
90
                if (bus == 0 && dev == 0) {
 
91
                        /*
 
92
                         * The Galileo system controller is acting
 
93
                         * differently than other devices.
 
94
                         */
 
95
                        *data = val;
 
96
                } else {
 
97
                        *data = le32_to_cpu(val);
 
98
                }
 
99
        }
 
100
 
 
101
        /* Check for master or target abort */
 
102
        intr = readl(&gt->regs->intrcause);
 
103
        if (intr & GT_INTRCAUSE_ABORT_BITS) {
 
104
                /* Error occurred, clear abort bits */
 
105
                writel(~GT_INTRCAUSE_ABORT_BITS, &gt->regs->intrcause);
 
106
                return -1;
 
107
        }
 
108
 
 
109
        if (access_type == PCI_ACCESS_READ)
 
110
                debug("PCI RD %02x:%02x.%x reg:%02d data:%08x\n",
 
111
                      PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf), where, *data);
 
112
 
 
113
        return 0;
 
114
}
 
115
 
 
116
static int gt_read_config_dword(struct pci_controller *hose, pci_dev_t dev,
 
117
                                int where, u32 *value)
 
118
{
 
119
        struct gt64120_pci_controller *gt = hose_to_gt64120(hose);
 
120
 
 
121
        *value = 0xffffffff;
 
122
        return gt_config_access(gt, PCI_ACCESS_READ, dev, where, value);
 
123
}
 
124
 
 
125
static int gt_write_config_dword(struct pci_controller *hose, pci_dev_t dev,
 
126
                                 int where, u32 value)
 
127
{
 
128
        struct gt64120_pci_controller *gt = hose_to_gt64120(hose);
 
129
        u32 data = value;
 
130
 
 
131
        return gt_config_access(gt, PCI_ACCESS_WRITE, dev, where, &data);
 
132
}
 
133
 
 
134
void gt64120_pci_init(void *regs, unsigned long sys_bus, unsigned long sys_phys,
 
135
                     unsigned long sys_size, unsigned long mem_bus,
 
136
                     unsigned long mem_phys, unsigned long mem_size,
 
137
                     unsigned long io_bus, unsigned long io_phys,
 
138
                     unsigned long io_size)
 
139
{
 
140
        static struct gt64120_pci_controller global_gt;
 
141
        struct gt64120_pci_controller *gt;
 
142
        struct pci_controller *hose;
 
143
 
 
144
        gt = &global_gt;
 
145
        gt->regs = regs;
 
146
 
 
147
        hose = &gt->hose;
 
148
 
 
149
        hose->first_busno = 0;
 
150
        hose->last_busno = 0;
 
151
 
 
152
        /* System memory space */
 
153
        pci_set_region(&hose->regions[0], sys_bus, sys_phys, sys_size,
 
154
                       PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
 
155
 
 
156
        /* PCI memory space */
 
157
        pci_set_region(&hose->regions[1], mem_bus, mem_phys, mem_size,
 
158
                       PCI_REGION_MEM);
 
159
 
 
160
        /* PCI I/O space */
 
161
        pci_set_region(&hose->regions[2], io_bus, io_phys, io_size,
 
162
                       PCI_REGION_IO);
 
163
 
 
164
        hose->region_count = 3;
 
165
 
 
166
        pci_set_ops(hose,
 
167
                    pci_hose_read_config_byte_via_dword,
 
168
                    pci_hose_read_config_word_via_dword,
 
169
                    gt_read_config_dword,
 
170
                    pci_hose_write_config_byte_via_dword,
 
171
                    pci_hose_write_config_word_via_dword,
 
172
                    gt_write_config_dword);
 
173
 
 
174
        pci_register_hose(hose);
 
175
        hose->last_busno = pci_hose_scan(hose);
 
176
}