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

« back to all changes in this revision

Viewing changes to roms/skiboot/hw/fsi-master.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
/* Copyright 2013-2014 IBM Corp.
 
2
 *
 
3
 * Licensed under the Apache License, Version 2.0 (the "License");
 
4
 * you may not use this file except in compliance with the License.
 
5
 * You may obtain a copy of the License at
 
6
 *
 
7
 *      http://www.apache.org/licenses/LICENSE-2.0
 
8
 *
 
9
 * Unless required by applicable law or agreed to in writing, software
 
10
 * distributed under the License is distributed on an "AS IS" BASIS,
 
11
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 
12
 * implied.
 
13
 * See the License for the specific language governing permissions and
 
14
 * limitations under the License.
 
15
 */
 
16
#include <skiboot.h>
 
17
#include <xscom.h>
 
18
#include <lock.h>
 
19
#include <timebase.h>
 
20
#include <chip.h>
 
21
#include <fsi-master.h>
 
22
 
 
23
/*
 
24
 * FSI Masters sit on OPB busses behind PIB2OPB bridges
 
25
 *
 
26
 * There are two cMFSI behind two different bridges at
 
27
 * different XSCOM addresses. For now we don't have them in
 
28
 * the device-tree so we hard code the address
 
29
 */
 
30
#define PIB2OPB_MFSI0_ADDR      0x20000
 
31
#define PIB2OPB_MFSI1_ADDR      0x30000
 
32
 
 
33
/*
 
34
 * Bridge registers on XSCOM that allow generatoin
 
35
 * of OPB cycles
 
36
 */
 
37
#define PIB2OPB_REG_CMD         0x0
 
38
#define   OPB_CMD_WRITE         0x80000000
 
39
#define   OPB_CMD_READ          0x00000000
 
40
#define   OPB_CMD_8BIT          0x00000000
 
41
#define   OPB_CMD_16BIT         0x20000000
 
42
#define   OPB_CMD_32BIT         0x60000000
 
43
#define PIB2OPB_REG_STAT        0x1
 
44
#define   OPB_STAT_ANY_ERR      0x80000000
 
45
#define   OPB_STAT_ERR_OPB      0x7FEC0000
 
46
#define   OPB_STAT_ERRACK       0x00100000
 
47
#define   OPB_STAT_BUSY         0x00010000
 
48
#define   OPB_STAT_READ_VALID   0x00020000
 
49
#define   OPB_STAT_ERR_CMFSI    0x0000FC00
 
50
#define   OPB_STAT_ERR_HMFSI    0x000000FC
 
51
#define   OPB_STAT_ERR_BASE     (OPB_STAT_ANY_ERR | \
 
52
                                 OPB_STAT_ERR_OPB | \
 
53
                                 OPB_STAT_ERRACK)
 
54
#define PIB2OPB_REG_LSTAT       0x2
 
55
#define PIB2OPB_REG_RESET       0x4
 
56
#define PIB2OPB_REG_cRSIC       0x5
 
57
#define PIB2OPB_REG_cRSIM       0x6
 
58
#define PIB2OPB_REG_cRSIS       0x7
 
59
#define PIB2OPB_REG_hRSIC       0x8
 
60
#define PIB2OPB_REG_hRSIM       0x9
 
61
#define PIB2OPB_REG_hRSIS       0xA
 
62
 
 
63
/* Low level errors from OPB contain the status in the bottom 32-bit
 
64
 * and one of these in the top 32-bit
 
65
 */
 
66
#define OPB_ERR_XSCOM_ERR       0x100000000ull
 
67
#define OPB_ERR_TIMEOUT_ERR     0x200000000ull
 
68
#define OPB_ERR_BAD_OPB_ADDR    0x400000000ull
 
69
 
 
70
/*
 
71
 * PIB2OPB 0 has 2 MFSIs, cMFSI and hMFSI, PIB2OPB 1 only
 
72
 * has cMFSI
 
73
 */
 
74
#define cMFSI_OPB_PORTS_BASE    0x40000
 
75
#define cMFSI_OPB_REG_BASE      0x03000
 
76
#define hMFSI_OPB_PORTS_BASE    0x80000
 
77
#define hMFSI_OPB_REG_BASE      0x03400
 
78
#define MFSI_OPB_PORT_STRIDE    0x08000
 
79
 
 
80
/* MFSI control registers */
 
81
#define MFSI_REG_MSTAP(__n)     (0x0D0 + (__n) * 4)
 
82
#define MFSI_REG_MATRB0         0x1D8
 
83
#define MFSI_REG_MDTRB0         0x1DC
 
84
#define MFSI_REG_MESRB0         0x1D0
 
85
#define MFSI_REG_MAESP0         0x050
 
86
#define MFSI_REG_MAEB           0x070
 
87
#define MFSI_REG_MSCSB0         0x1D4
 
88
 
 
89
/* FSI Slave registers */
 
90
#define FSI_SLAVE_REGS          0x000800        /**< FSI Slave Register */
 
91
#define FSI_SMODE               (FSI_SLAVE_REGS | 0x00)
 
92
#define FSI_SLBUS               (FSI_SLAVE_REGS | 0x30)
 
93
#define FSI_SLRES               (FSI_SLAVE_REGS | 0x34)
 
94
 
 
95
#define FSI2PIB_ENGINE          0x001000        /**< FSI2PIB Engine (SCOM) */
 
96
#define FSI2PIB_RESET           (FSI2PIB_ENGINE | 0x18)
 
97
#define FSI2PIB_STATUS          (FSI2PIB_ENGINE | 0x1C)
 
98
#define FSI2PIB_COMPMASK        (FSI2PIB_ENGINE | 0x30)
 
99
#define FSI2PIB_TRUEMASK        (FSI2PIB_ENGINE | 0x34)
 
100
 
 
101
struct mfsi {
 
102
        uint32_t chip_id;
 
103
        uint32_t unit;
 
104
        uint32_t xscom_base;
 
105
        uint32_t ports_base;
 
106
        uint32_t reg_base;
 
107
        uint32_t err_bits;
 
108
};
 
109
 
 
110
#define mfsi_log(__lev, __m, __fmt, ...) \
 
111
        prlog(__lev, "MFSI %x:%x: " __fmt, __m->chip_id, __m->unit, ##__VA_ARGS__)
 
112
/*
 
113
 * Use a global FSI lock for now. Beware of re-entrancy
 
114
 * if we ever add support for normal chip XSCOM via FSI, in
 
115
 * which case we'll probably have to consider either per chip
 
116
 * lock (which can have AB->BA deadlock issues) or a re-entrant
 
117
 * global lock or something else. ...
 
118
 */
 
119
static struct lock fsi_lock = LOCK_UNLOCKED;
 
120
 
 
121
/*
 
122
 * OPB accessors
 
123
 */
 
124
 
 
125
/* We try up to 1.2ms for an OPB access */
 
126
#define MFSI_OPB_MAX_TRIES      1200
 
127
 
 
128
static uint64_t mfsi_opb_poll(struct mfsi *mfsi, uint32_t *read_data)
 
129
{
 
130
        unsigned long retries = MFSI_OPB_MAX_TRIES;
 
131
        uint64_t sval;
 
132
        uint32_t stat;
 
133
        int64_t rc;
 
134
 
 
135
        /* We try again every 10us for a bit more than 1ms */
 
136
        for (;;) {
 
137
                /* Read OPB status register */
 
138
                rc = xscom_read(mfsi->chip_id, mfsi->xscom_base + PIB2OPB_REG_STAT, &sval);
 
139
                if (rc) {
 
140
                        /* Do something here ? */
 
141
                        mfsi_log(PR_ERR, mfsi, "XSCOM error %lld read OPB STAT\n", rc);
 
142
                        return OPB_ERR_XSCOM_ERR;
 
143
                }
 
144
                mfsi_log(PR_INSANE, mfsi, "  STAT=0x%16llx...\n", sval);
 
145
 
 
146
                stat = sval >> 32;
 
147
 
 
148
                /* Complete */
 
149
                if (!(stat & OPB_STAT_BUSY))
 
150
                        break;
 
151
                if (retries-- == 0) {
 
152
                        /* This isn't supposed to happen (HW timeout) */
 
153
                        mfsi_log(PR_ERR, mfsi, "OPB POLL timeout !\n");
 
154
                        return OPB_ERR_TIMEOUT_ERR | (stat & mfsi->err_bits);
 
155
                }
 
156
                time_wait_us(1);
 
157
        }
 
158
 
 
159
        /* Did we have an error ? */
 
160
        if (stat & mfsi->err_bits)
 
161
                return stat & mfsi->err_bits;
 
162
 
 
163
        if (read_data) {
 
164
                if (!(stat & OPB_STAT_READ_VALID)) {
 
165
                        mfsi_log(PR_ERR, mfsi, "Read successful but no data !\n");
 
166
 
 
167
                        /* What do do here ? can it actually happen ? */
 
168
                        sval = 0xffffffff;
 
169
                }
 
170
                *read_data = sval & 0xffffffff;
 
171
        }
 
172
 
 
173
        return 0;
 
174
}
 
175
 
 
176
static uint64_t mfsi_opb_read(struct mfsi *mfsi, uint32_t opb_addr, uint32_t *data)
 
177
{
 
178
        uint64_t opb_cmd = OPB_CMD_READ | OPB_CMD_32BIT;
 
179
        int64_t rc;
 
180
 
 
181
        if (opb_addr > 0x00ffffff)
 
182
                return OPB_ERR_BAD_OPB_ADDR;
 
183
 
 
184
        opb_cmd |= opb_addr;
 
185
        opb_cmd <<= 32;
 
186
 
 
187
        mfsi_log(PR_INSANE, mfsi, "MFSI_OPB_READ: Writing 0x%16llx to XSCOM %x\n",
 
188
                 opb_cmd, mfsi->xscom_base);
 
189
 
 
190
        rc = xscom_write(mfsi->chip_id, mfsi->xscom_base + PIB2OPB_REG_CMD, opb_cmd);
 
191
        if (rc) {
 
192
                mfsi_log(PR_ERR, mfsi, "XSCOM error %lld writing OPB CMD\n", rc);
 
193
                return OPB_ERR_XSCOM_ERR;
 
194
        }
 
195
        return mfsi_opb_poll(mfsi, data);
 
196
}
 
197
 
 
198
static uint64_t mfsi_opb_write(struct mfsi *mfsi, uint32_t opb_addr, uint32_t data)
 
199
{
 
200
        uint64_t opb_cmd = OPB_CMD_WRITE | OPB_CMD_32BIT;
 
201
        int64_t rc;
 
202
 
 
203
        if (opb_addr > 0x00ffffff)
 
204
                return OPB_ERR_BAD_OPB_ADDR;
 
205
 
 
206
        opb_cmd |= opb_addr;
 
207
        opb_cmd <<= 32;
 
208
        opb_cmd |= data;
 
209
 
 
210
        mfsi_log(PR_INSANE, mfsi, "MFSI_OPB_WRITE: Writing 0x%16llx to XSCOM %x\n",
 
211
                 opb_cmd, mfsi->xscom_base);
 
212
 
 
213
        rc = xscom_write(mfsi->chip_id, mfsi->xscom_base + PIB2OPB_REG_CMD, opb_cmd);
 
214
        if (rc) {
 
215
                mfsi_log(PR_ERR, mfsi, "XSCOM error %lld writing OPB CMD\n", rc);
 
216
                return OPB_ERR_XSCOM_ERR;
 
217
        }
 
218
        return mfsi_opb_poll(mfsi, NULL);
 
219
}
 
220
 
 
221
static struct mfsi *mfsi_get(uint32_t chip_id, uint32_t unit)
 
222
{
 
223
        struct proc_chip *chip = get_chip(chip_id);
 
224
        struct mfsi *mfsi;
 
225
 
 
226
        if (!chip || unit > MFSI_hMFSI0)
 
227
                return NULL;
 
228
        mfsi = &chip->fsi_masters[unit];
 
229
        if (mfsi->xscom_base == 0)
 
230
                return NULL;
 
231
        return mfsi;
 
232
}
 
233
 
 
234
static int64_t mfsi_reset_pib2opb(struct mfsi *mfsi)
 
235
{
 
236
        uint64_t stat;
 
237
        int64_t rc;
 
238
 
 
239
        rc = xscom_write(mfsi->chip_id,
 
240
                         mfsi->xscom_base + PIB2OPB_REG_RESET, (1ul << 63));
 
241
        if (rc) {
 
242
                mfsi_log(PR_ERR, mfsi, "XSCOM error %lld resetting PIB2OPB\n", rc);
 
243
                return rc;
 
244
        }
 
245
        rc = xscom_write(mfsi->chip_id,
 
246
                         mfsi->xscom_base + PIB2OPB_REG_STAT, (1ul << 63));
 
247
        if (rc) {
 
248
                mfsi_log(PR_ERR, mfsi, "XSCOM error %lld resetting status\n", rc);
 
249
                return rc;
 
250
        }
 
251
        rc = xscom_read(mfsi->chip_id,
 
252
                        mfsi->xscom_base + PIB2OPB_REG_STAT, &stat);
 
253
        if (rc) {
 
254
                mfsi_log(PR_ERR, mfsi, "XSCOM error %lld reading status\n", rc);
 
255
                return rc;
 
256
        }
 
257
        return 0;
 
258
}
 
259
 
 
260
 
 
261
static void mfsi_dump_pib2opb_state(struct mfsi *mfsi)
 
262
{
 
263
        uint64_t val;
 
264
 
 
265
        /* Dump a bunch of registers */
 
266
        if (xscom_read(mfsi->chip_id, mfsi->xscom_base + PIB2OPB_REG_CMD, &val))
 
267
                goto xscom_error;
 
268
        mfsi_log(PR_ERR, mfsi, " PIB2OPB CMD   = %016llx\n", val);
 
269
        if (xscom_read(mfsi->chip_id, mfsi->xscom_base + PIB2OPB_REG_STAT, &val))
 
270
                goto xscom_error;
 
271
        mfsi_log(PR_ERR, mfsi, " PIB2OPB STAT  = %016llx\n", val);
 
272
        if (xscom_read(mfsi->chip_id, mfsi->xscom_base + PIB2OPB_REG_LSTAT, &val))
 
273
                goto xscom_error;
 
274
        mfsi_log(PR_ERR, mfsi, " PIB2OPB LSTAT = %016llx\n", val);
 
275
 
 
276
        if (mfsi->unit == MFSI_cMFSI0 || mfsi->unit == MFSI_cMFSI1) {
 
277
                if (xscom_read(mfsi->chip_id, mfsi->xscom_base + PIB2OPB_REG_cRSIC, &val))
 
278
                        goto xscom_error;
 
279
                mfsi_log(PR_ERR, mfsi, " PIB2OPB cRSIC = %016llx\n", val);
 
280
                if (xscom_read(mfsi->chip_id, mfsi->xscom_base + PIB2OPB_REG_cRSIM, &val))
 
281
                        goto xscom_error;
 
282
                mfsi_log(PR_ERR, mfsi, " PIB2OPB cRSIM = %016llx\n", val);
 
283
                if (xscom_read(mfsi->chip_id, mfsi->xscom_base + PIB2OPB_REG_cRSIS, &val))
 
284
                        goto xscom_error;
 
285
                mfsi_log(PR_ERR, mfsi, " PIB2OPB cRSIS = %016llx\n", val);
 
286
        } else if (mfsi->unit == MFSI_hMFSI0) {
 
287
                if (xscom_read(mfsi->chip_id, mfsi->xscom_base + PIB2OPB_REG_hRSIC, &val))
 
288
                        goto xscom_error;
 
289
                mfsi_log(PR_ERR, mfsi, " PIB2OPB hRSIC = %016llx\n", val);
 
290
                if (xscom_read(mfsi->chip_id, mfsi->xscom_base + PIB2OPB_REG_hRSIM, &val))
 
291
                        goto xscom_error;
 
292
                mfsi_log(PR_ERR, mfsi, " PIB2OPB hRSIM = %016llx\n", val);
 
293
                if (xscom_read(mfsi->chip_id, mfsi->xscom_base + PIB2OPB_REG_hRSIS, &val))
 
294
                        goto xscom_error;
 
295
                mfsi_log(PR_ERR, mfsi, " PIB2OPB hRSIS = %016llx\n", val);
 
296
        }
 
297
        return;
 
298
 xscom_error:
 
299
        mfsi_log(PR_ERR, mfsi, "XSCOM error reading PIB2OPB registers\n");
 
300
}
 
301
 
 
302
static int64_t mfsi_dump_ctrl_regs(struct mfsi *mfsi)
 
303
{
 
304
        uint64_t opb_stat;
 
305
        uint32_t i;
 
306
 
 
307
        /* List of registers to dump (from HB) */
 
308
        static uint32_t dump_regs[] = {
 
309
                MFSI_REG_MATRB0,
 
310
                MFSI_REG_MDTRB0,
 
311
                MFSI_REG_MESRB0,
 
312
                MFSI_REG_MAESP0,
 
313
                MFSI_REG_MAEB,
 
314
                MFSI_REG_MSCSB0,
 
315
        };
 
316
        static const char * dump_regs_names[] = {
 
317
                "MFSI_REG_MATRB0",
 
318
                "MFSI_REG_MDTRB0",
 
319
                "MFSI_REG_MESRB0",
 
320
                "MFSI_REG_MAESP0",
 
321
                "MFSI_REG_MAEB  ",
 
322
                "MFSI_REG_MSCSB0",
 
323
        };
 
324
        for (i = 0; i < ARRAY_SIZE(dump_regs); i++) {
 
325
                uint32_t val;
 
326
        
 
327
                opb_stat = mfsi_opb_read(mfsi, mfsi->reg_base + dump_regs[i], &val);
 
328
                if (opb_stat) {
 
329
                        /* Error on dump, give up */
 
330
                        mfsi_log(PR_ERR, mfsi, " OPB stat 0x%016llx dumping reg %x\n",
 
331
                                 opb_stat, dump_regs[i]);
 
332
                        return OPAL_HARDWARE;
 
333
                }
 
334
                mfsi_log(PR_ERR, mfsi, " %s = %08x\n", dump_regs_names[i], val);
 
335
        }
 
336
        for (i = 0; i < 8; i++) {
 
337
                uint32_t val;
 
338
        
 
339
                opb_stat = mfsi_opb_read(mfsi, mfsi->reg_base + MFSI_REG_MSTAP(i), &val);
 
340
                if (opb_stat) {
 
341
                        /* Error on dump, give up */
 
342
                        mfsi_log(PR_ERR, mfsi, " OPB stat 0x%016llx dumping reg %x\n",
 
343
                                 opb_stat, MFSI_REG_MSTAP(i));
 
344
                        return OPAL_HARDWARE;
 
345
                }
 
346
                mfsi_log(PR_ERR, mfsi, " MFSI_REG_MSTAP%d = %08x\n", i, val);
 
347
        }
 
348
        return OPAL_SUCCESS;
 
349
}
 
350
 
 
351
static int64_t mfsi_master_cleanup(struct mfsi *mfsi, uint32_t port)
 
352
{
 
353
        uint64_t opb_stat;
 
354
        uint32_t port_base, compmask, truemask;
 
355
 
 
356
        /* Reset the bridge to clear up the residual errors */
 
357
 
 
358
        /* bit0 = Bridge: General reset */
 
359
        opb_stat = mfsi_opb_write(mfsi, mfsi->reg_base + MFSI_REG_MESRB0, 0x80000000u);
 
360
        if (opb_stat) {
 
361
                mfsi_log(PR_ERR, mfsi, " OPB stat 0x%016llx writing reset to MESRB0\n",
 
362
                         opb_stat);
 
363
                return OPAL_HARDWARE;
 
364
        }
 
365
 
 
366
        /* Calculate base address of port */
 
367
        port_base = mfsi->ports_base + port * MFSI_OPB_PORT_STRIDE;
 
368
 
 
369
        /* Perform error reset on Centaur fsi slave: */
 
370
        /*  write 0x4000000 to addr=834 */
 
371
        opb_stat = mfsi_opb_write(mfsi, port_base + FSI_SLRES, 0x04000000);
 
372
        if (opb_stat) {
 
373
                mfsi_log(PR_ERR, mfsi,
 
374
                         " OPB stat 0x%016llx writing reset to FSI slave\n",
 
375
                         opb_stat);
 
376
                return OPAL_HARDWARE;
 
377
        }
 
378
 
 
379
        /* Further step is to issue a PIB reset to the FSI2PIB engine
 
380
         * in busy state, i.e. write arbitrary data to 101c
 
381
         * (putcfam 1007) register of the previously failed FSI2PIB
 
382
         * engine on Centaur.
 
383
         *
 
384
         * XXX BenH: Should that be done by the upper FSI XSCOM layer ?
 
385
         */
 
386
        opb_stat = mfsi_opb_write(mfsi, port_base + FSI2PIB_STATUS, 0xFFFFFFFF);
 
387
        if (opb_stat) {
 
388
                mfsi_log(PR_ERR, mfsi,
 
389
                         " OPB stat 0x%016llx clearing FSI2PIB_STATUS\n",
 
390
                         opb_stat);
 
391
                return OPAL_HARDWARE;
 
392
        }
 
393
 
 
394
        /* Need to save/restore the true/comp masks or the FSP (PRD ?) will
 
395
         * get annoyed
 
396
         */
 
397
        opb_stat = mfsi_opb_read(mfsi, port_base + FSI2PIB_COMPMASK, &compmask);
 
398
        if (opb_stat) {
 
399
                mfsi_log(PR_ERR, mfsi,
 
400
                         " OPB stat 0x%016llx reading FSI2PIB_COMPMASK\n",
 
401
                         opb_stat);
 
402
                return OPAL_HARDWARE;
 
403
        }
 
404
        opb_stat = mfsi_opb_read(mfsi, port_base + FSI2PIB_TRUEMASK, &truemask);
 
405
        if (opb_stat) {
 
406
                mfsi_log(PR_ERR, mfsi,
 
407
                         " OPB stat 0x%016llx reading FSI2PIB_TRUEMASK\n",
 
408
                         opb_stat);
 
409
                return OPAL_HARDWARE;
 
410
        }
 
411
 
 
412
        /* Then, write arbitrary data to 1018  (putcfam 1006) to
 
413
         * reset any pending FSI2PIB errors.
 
414
         */
 
415
        opb_stat = mfsi_opb_write(mfsi, port_base + FSI2PIB_RESET, 0xFFFFFFFF);
 
416
        if (opb_stat) {
 
417
                mfsi_log(PR_ERR, mfsi,
 
418
                         " OPB stat 0x%016llx writing FSI2PIB_RESET\n",
 
419
                         opb_stat);
 
420
                return OPAL_HARDWARE;
 
421
        }
 
422
 
 
423
        /* Restore the true/comp masks */
 
424
        opb_stat = mfsi_opb_write(mfsi, port_base + FSI2PIB_COMPMASK, compmask);
 
425
        if (opb_stat) {
 
426
                mfsi_log(PR_ERR, mfsi,
 
427
                         " OPB stat 0x%016llx writing FSI2PIB_COMPMASK\n",
 
428
                         opb_stat);
 
429
                return OPAL_HARDWARE;
 
430
        }
 
431
        opb_stat = mfsi_opb_write(mfsi, port_base + FSI2PIB_TRUEMASK, truemask);
 
432
        if (opb_stat) {
 
433
                mfsi_log(PR_ERR, mfsi,
 
434
                         " OPB stat 0x%016llx writing FSI2PIB_TRUEMASK\n",
 
435
                         opb_stat);
 
436
                return OPAL_HARDWARE;
 
437
        }
 
438
        return OPAL_SUCCESS;
 
439
}
 
440
 
 
441
static int64_t mfsi_analyse_fsi_error(struct mfsi *mfsi)
 
442
{
 
443
        uint64_t opb_stat;
 
444
        uint32_t mesrb0;
 
445
 
 
446
        /* Most of the code below is adapted from HB. The main difference is
 
447
         * that we don't gard
 
448
         */
 
449
 
 
450
        /* Read MESRB0 */
 
451
        opb_stat = mfsi_opb_read(mfsi, mfsi->reg_base + MFSI_REG_MESRB0, &mesrb0);
 
452
        if (opb_stat) {
 
453
                mfsi_log(PR_ERR, mfsi, " OPB stat 0x%016llx reading MESRB0\n", opb_stat);
 
454
                return OPAL_HARDWARE;
 
455
        }
 
456
        mfsi_log(PR_ERR, mfsi, " MESRB0=%08x\n", mesrb0);
 
457
 
 
458
        /* bits 8:15 are internal parity errors in the master */
 
459
        if (mesrb0 & 0x00FF0000) {      
 
460
                mfsi_log(PR_ERR, mfsi, " Master parity error !\n");
 
461
        } else {
 
462
                /* bits 0:3 are a specific error code */
 
463
                switch ((mesrb0 & 0xF0000000) >> 28 ) {
 
464
                case 0x1: /* OPB error  */
 
465
                case 0x2: /* Invalid state of OPB state machine */
 
466
                        /* error is inside the OPB logic */
 
467
                        mfsi_log(PR_ERR, mfsi, " OPB logic error !\n");
 
468
                        break;
 
469
                case 0x3: /* Port access error */
 
470
                        /* probably some kind of code collision */
 
471
                        /* could also be something weird in the chip */
 
472
                        mfsi_log(PR_ERR, mfsi, " Port access error !\n");
 
473
                        break;
 
474
                case 0x4: /* ID mismatch */
 
475
                        mfsi_log(PR_ERR, mfsi, " Port ID mismatch !\n");
 
476
                        break;
 
477
                case 0x6: /* port timeout error */
 
478
                        mfsi_log(PR_ERR, mfsi, " Port timeout !\n");
 
479
                        break;
 
480
                case 0x7: /* master timeout error */
 
481
                        mfsi_log(PR_ERR, mfsi, " Master timeout !\n");
 
482
                        break;
 
483
                case 0x9: /* Any error response from Slave */
 
484
                        mfsi_log(PR_ERR, mfsi, " Slave error response !\n");
 
485
                        break;
 
486
                case 0xC: /* bridge parity error */
 
487
                        mfsi_log(PR_ERR, mfsi, " Bridge parity error !\n");
 
488
                        break;
 
489
                case 0xB: /* protocol error */
 
490
                        mfsi_log(PR_ERR, mfsi, " Protocol error !\n");
 
491
                        break;
 
492
                case 0x8: /* master CRC error */
 
493
                        mfsi_log(PR_ERR, mfsi, " Master CRC error !\n");
 
494
                        break;
 
495
                case 0xA: /* Slave CRC error */
 
496
                        mfsi_log(PR_ERR, mfsi, " Slave CRC error !\n");
 
497
                        break;
 
498
                default:
 
499
                        mfsi_log(PR_ERR, mfsi, " Unknown error !\n");
 
500
                        break;
 
501
                }
 
502
        }
 
503
        return OPAL_SUCCESS;
 
504
}
 
505
 
 
506
static int64_t mfsi_handle_error(struct mfsi *mfsi, uint32_t port,
 
507
                                 uint64_t opb_stat, uint32_t fsi_addr)
 
508
{
 
509
        int rc;
 
510
        bool found_root_cause = false;
 
511
 
 
512
        mfsi_log(PR_ERR, mfsi, "Access error on port %d, stat=%012llx\n",
 
513
                 port, opb_stat);
 
514
        
 
515
        /* First handle stat codes we synthetized */
 
516
        if (opb_stat & OPB_ERR_XSCOM_ERR)
 
517
                return OPAL_HARDWARE;
 
518
        if (opb_stat & OPB_ERR_BAD_OPB_ADDR)
 
519
                return OPAL_PARAMETER;
 
520
 
 
521
        /* Dump a bunch of regisers from PIB2OPB and reset it */
 
522
        mfsi_dump_pib2opb_state(mfsi);
 
523
 
 
524
        /* Reset PIB2OPB */
 
525
        mfsi_reset_pib2opb(mfsi);
 
526
 
 
527
        /* This one is not supposed to happen but ... */
 
528
        if (opb_stat & OPB_ERR_TIMEOUT_ERR)
 
529
                return OPAL_HARDWARE;
 
530
 
 
531
        /* Dump some FSI control registers */
 
532
        rc = mfsi_dump_ctrl_regs(mfsi);
 
533
 
 
534
        /* If that failed, reset PIB2OPB again and return */
 
535
        if (rc) {
 
536
                mfsi_dump_pib2opb_state(mfsi);
 
537
                mfsi_reset_pib2opb(mfsi);
 
538
                return OPAL_HARDWARE;
 
539
        }
 
540
 
 
541
        /* Now check for known root causes (from HB) */
 
542
 
 
543
        /* First check if it's a ctrl register access error and we got an OPB NACK,
 
544
         * which means an out of bounds control reg
 
545
         */
 
546
        if ((opb_stat & OPB_STAT_ERRACK) &&
 
547
            ((fsi_addr & ~0x2ffu) == mfsi->reg_base)) {         
 
548
                mfsi_log(PR_ERR, mfsi, " Error appears to be out of bounds reg %08x\n",
 
549
                         fsi_addr);
 
550
                found_root_cause = true;
 
551
        }
 
552
        /* Else check for other OPB errors */
 
553
        else if (opb_stat & OPB_STAT_ERR_OPB) {
 
554
                mfsi_log(PR_ERR, mfsi, " Error appears to be an OPB error\n");
 
555
                found_root_cause = true;
 
556
        }
 
557
 
 
558
        /* Root cause not found, dig into FSI logic */
 
559
        if (!found_root_cause) {
 
560
                rc = mfsi_analyse_fsi_error(mfsi);
 
561
                if (!rc) {
 
562
                        /* If that failed too, reset the PIB2OPB again */
 
563
                        mfsi_reset_pib2opb(mfsi);
 
564
                }
 
565
        }
 
566
 
 
567
        /* Cleanup MFSI master */
 
568
        mfsi_master_cleanup(mfsi, port);
 
569
 
 
570
        return OPAL_HARDWARE;
 
571
}
 
572
 
 
573
int64_t mfsi_read(uint32_t chip, uint32_t unit, uint32_t port,
 
574
                  uint32_t fsi_addr, uint32_t *data)
 
575
{
 
576
        struct mfsi *mfsi = mfsi_get(chip, unit);
 
577
        uint32_t port_addr;
 
578
        uint64_t opb_stat;
 
579
        int64_t rc = OPAL_SUCCESS;
 
580
 
 
581
        if (!mfsi || port > 7)
 
582
                return OPAL_PARAMETER;
 
583
 
 
584
        lock(&fsi_lock);
 
585
 
 
586
        /* Calculate port address */
 
587
        port_addr = mfsi->ports_base + port * MFSI_OPB_PORT_STRIDE;
 
588
        port_addr += fsi_addr;
 
589
 
 
590
        /* Perform OPB access */
 
591
        opb_stat = mfsi_opb_read(mfsi, port_addr, data);
 
592
        if (opb_stat)
 
593
                rc = mfsi_handle_error(mfsi, port, opb_stat, port_addr);
 
594
 
 
595
        unlock(&fsi_lock);
 
596
 
 
597
        return rc;
 
598
}
 
599
 
 
600
int64_t mfsi_write(uint32_t chip, uint32_t unit, uint32_t port,
 
601
                   uint32_t fsi_addr, uint32_t data)
 
602
{
 
603
        struct mfsi *mfsi = mfsi_get(chip, unit);
 
604
        uint32_t port_addr;
 
605
        uint64_t opb_stat;
 
606
        int64_t rc = OPAL_SUCCESS;
 
607
 
 
608
        if (!mfsi || port > 7)
 
609
                return OPAL_PARAMETER;
 
610
 
 
611
        lock(&fsi_lock);
 
612
 
 
613
        /* Calculate port address */
 
614
        port_addr = mfsi->ports_base + port * MFSI_OPB_PORT_STRIDE;
 
615
        port_addr += fsi_addr;
 
616
 
 
617
        /* Perform OPB access */
 
618
        opb_stat = mfsi_opb_write(mfsi, port_addr, data);
 
619
        if (opb_stat)
 
620
                rc = mfsi_handle_error(mfsi, port, opb_stat, port_addr);
 
621
 
 
622
        unlock(&fsi_lock);
 
623
 
 
624
        return rc;
 
625
}
 
626
 
 
627
static void mfsi_add(struct proc_chip *chip, struct mfsi *mfsi, uint32_t unit)
 
628
{
 
629
        mfsi->chip_id = chip->id;
 
630
        mfsi->unit = unit;
 
631
 
 
632
        /* We hard code everything for now */
 
633
        switch(unit) {
 
634
        case MFSI_cMFSI0:
 
635
                mfsi->xscom_base = PIB2OPB_MFSI0_ADDR;
 
636
                mfsi->ports_base = cMFSI_OPB_PORTS_BASE;
 
637
                mfsi->reg_base = cMFSI_OPB_REG_BASE;
 
638
                mfsi->err_bits = OPB_STAT_ERR_BASE | OPB_STAT_ERR_CMFSI;
 
639
                break;
 
640
        case MFSI_cMFSI1:
 
641
                mfsi->xscom_base = PIB2OPB_MFSI1_ADDR;
 
642
                mfsi->ports_base = cMFSI_OPB_PORTS_BASE;
 
643
                mfsi->reg_base = cMFSI_OPB_REG_BASE;
 
644
                mfsi->err_bits = OPB_STAT_ERR_BASE | OPB_STAT_ERR_CMFSI;
 
645
                break;
 
646
        case MFSI_hMFSI0:
 
647
                mfsi->xscom_base = PIB2OPB_MFSI0_ADDR;
 
648
                mfsi->ports_base = hMFSI_OPB_PORTS_BASE;
 
649
                mfsi->reg_base = hMFSI_OPB_REG_BASE;
 
650
                mfsi->err_bits = OPB_STAT_ERR_BASE | OPB_STAT_ERR_HMFSI;
 
651
                break;
 
652
        default:
 
653
                /* ??? */
 
654
                return;
 
655
        }
 
656
 
 
657
        /* Hardware Bug HW222712 on Murano DD1.0 causes the
 
658
         * any_error bit to be un-clearable so we just
 
659
         * have to ignore it. Additionally, HostBoot applies
 
660
         * this to Venice too, though the comment there claims
 
661
         * this is a Simics workaround.
 
662
         *
 
663
         * The doc says that bit can be safely ignored, so let's
 
664
         * just not bother and always take it out.
 
665
         */
 
666
 
 
667
        /* 16: cMFSI any-master-error */
 
668
        /* 24: hMFSI any-master-error */
 
669
        mfsi->err_bits &= 0xFFFF7F7F;
 
670
 
 
671
        mfsi_log(PR_INFO, mfsi, "Initialized\n");
 
672
}
 
673
 
 
674
void mfsi_init(void)
 
675
{
 
676
        struct proc_chip *chip;
 
677
 
 
678
        for_each_chip(chip) {
 
679
                chip->fsi_masters = zalloc(sizeof(struct mfsi) * 3);
 
680
                mfsi_add(chip, &chip->fsi_masters[MFSI_cMFSI0], MFSI_cMFSI0);
 
681
                mfsi_add(chip, &chip->fsi_masters[MFSI_hMFSI0], MFSI_hMFSI0);
 
682
                mfsi_add(chip, &chip->fsi_masters[MFSI_cMFSI1], MFSI_cMFSI1);
 
683
 
 
684
        }
 
685
}
 
686