1 /* Copyright 2014-2016 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 * imitations under the License.
15 */
16
17 #include <stdint.h>
18 #include <stdio.h>
19 #include <stdbool.h>
20 #include <stdlib.h>
21 #include <time.h>
22
23 #include "xscom.h"
24
25 #define DBG(fmt...) do { if (verbose) printf(fmt); } while(0)
26 #define ERR(fmt...) do { fprintf(stderr, fmt); } while(0)
27
28 #define OCB_PIB_BASE_P8 0x0006B000
29 #define OCB_PIB_BASE_P9 0x0006D000
30
31 #define OCBCSR0 0x11
32 #define OCBCSR0_AND 0x12
33 #define OCBCSR0_OR 0x13
34 #define OCB_STREAM_MODE PPC_BIT(4)
35 #define OCB_STREAM_TYPE PPC_BIT(5)
36 #define OCBAR0 0x10
37 #define OCBDR0 0x15
38
39 #define PVR_TYPE_P8E 0x004b /* Murano */
40 #define PVR_TYPE_P8 0x004d /* Venice */
41 #define PVR_TYPE_P8NVL 0x004c /* Naples */
42 #define PVR_TYPE_P9 0x004e
43 #define PVR_TYPE_P9P 0x004f /* Axone */
44
45 #ifdef __powerpc__
get_xscom_base(void)46 static uint64_t get_xscom_base(void)
47 {
48 unsigned int pvr;
49
50 asm volatile("mfpvr %0" : "=r" (pvr));
51
52 switch (pvr >> 16) {
53 case PVR_TYPE_P9:
54 case PVR_TYPE_P9P:
55 return OCB_PIB_BASE_P9;
56
57 case PVR_TYPE_P8E:
58 case PVR_TYPE_P8:
59 case PVR_TYPE_P8NVL:
60 return OCB_PIB_BASE_P8;
61 }
62
63 ERR("Unknown processor, exiting\n");
64 exit(1);
65 return 0;
66 }
67 #else
68 /* Just so it compiles on x86 */
get_xscom_base(void)69 static uint64_t get_xscom_base(void) { return 0; }
70 #endif
71
sram_read(uint32_t chip_id,int chan,uint32_t addr,uint64_t * val)72 int sram_read(uint32_t chip_id, int chan, uint32_t addr, uint64_t *val)
73 {
74 uint64_t sdat, base = get_xscom_base();
75 uint32_t coff = chan * 0x20;
76 int rc;
77
78 /* Read for debug purposes */
79 rc = xscom_read(chip_id, base + OCBCSR0 + coff, &sdat);
80 if (rc) {
81 ERR("xscom OCBCSR0 read error %d\n", rc);
82 return -1;
83 }
84
85 /* Create an AND mask to clear bit 4 and 5 and poke the AND register */
86 sdat = ~(OCB_STREAM_MODE | OCB_STREAM_TYPE);
87 rc = xscom_write(chip_id, base + OCBCSR0_AND + coff, sdat);
88 if (rc) {
89 ERR("xscom OCBCSR0_AND write error %d\n", rc);
90 return -1;
91 }
92
93 sdat = ((uint64_t)addr) << 32;
94 rc = xscom_write(chip_id, base + OCBAR0 + coff, sdat);
95 if (rc) {
96 ERR("xscom OCBAR0 write error %d\n", rc);
97 return -1;
98 }
99
100 rc = xscom_read(chip_id, base + OCBDR0 + coff, val);
101 if (rc) {
102 ERR("xscom OCBDR0 read error %d\n", rc);
103 return -1;
104 }
105 return 0;
106 }
107
sram_write(uint32_t chip_id,int chan,uint32_t addr,uint64_t val)108 int sram_write(uint32_t chip_id, int chan, uint32_t addr, uint64_t val)
109 {
110 uint64_t sdat, base = get_xscom_base();
111 uint32_t coff = chan * 0x20;
112 int rc;
113
114 #if 0
115 if (dummy) {
116 printf("[dummy] write chip %d OCC sram 0x%08x = %016lx\n",
117 chip_id, addr, val);
118 return 0;
119 }
120 #endif
121
122 /* Read for debug purposes */
123 rc = xscom_read(chip_id, base + OCBCSR0 + coff, &sdat);
124 if (rc) {
125 ERR("xscom OCBCSR0 read error %d\n", rc);
126 return -1;
127 }
128
129 /* Create an AND mask to clear bit 4 and 5 and poke the AND register */
130 sdat = ~(OCB_STREAM_MODE | OCB_STREAM_TYPE);
131 rc = xscom_write(chip_id, base + OCBCSR0_AND + coff, sdat);
132 if (rc) {
133 ERR("xscom OCBCSR0_AND write error %d\n", rc);
134 return -1;
135 }
136
137 sdat = ((uint64_t)addr) << 32;
138 rc = xscom_write(chip_id, base + OCBAR0 + coff, sdat);
139 if (rc) {
140 ERR("xscom OCBAR0 write error %d\n", rc);
141 return -1;
142 }
143
144 rc = xscom_write(chip_id, base + OCBDR0 + coff, val);
145 if (rc) {
146 ERR("xscom OCBDR0 write error %d\n", rc);
147 return -1;
148 }
149 return 0;
150 }
151