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