aboutsummaryrefslogtreecommitdiffstats
path: root/roms/skiboot/external/xscom-utils/sram.c
diff options
context:
space:
mode:
Diffstat (limited to 'roms/skiboot/external/xscom-utils/sram.c')
-rw-r--r--roms/skiboot/external/xscom-utils/sram.c139
1 files changed, 139 insertions, 0 deletions
diff --git a/roms/skiboot/external/xscom-utils/sram.c b/roms/skiboot/external/xscom-utils/sram.c
new file mode 100644
index 000000000..efe08d8e7
--- /dev/null
+++ b/roms/skiboot/external/xscom-utils/sram.c
@@ -0,0 +1,139 @@
+// 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 */
+#define PVR_TYPE_P10 0x0080
+
+#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:
+ case PVR_TYPE_P10: /* P10 OCB_PIB OCC Control Register is same for P9 and P10 */
+ 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;
+}