@@ -92,10 +92,12 @@ int main(int argc, char *argv[])
fprintf(stderr,"Error %d writing XSCOM\n", rc);
exit(1);
}
- rc = xscom_read(chip_id, addr, &val);
- if (rc) {
- fprintf(stderr,"Error %d reading XSCOM\n", rc);
- exit(1);
+ if (xscom_readable(addr)) {
+ rc = xscom_read(chip_id, addr, &val);
+ if (rc) {
+ fprintf(stderr,"Error %d reading XSCOM\n", rc);
+ exit(1);
+ }
}
printf("%016" PRIx64 "\n", val);
return 0;
@@ -131,8 +131,17 @@ static struct xscom_chip *xscom_find_chip(uint32_t chip_id)
static uint64_t xscom_mangle_addr(uint64_t addr)
{
- if (addr & (1ull << 63))
- addr |= (1ull << 59);
+ uint64_t tmp;
+
+ /*
+ * Shift the top 4 bits (indirect mode) down by 4 bits so we
+ * don't lose going through the debugfs interfaces.
+ */
+ tmp = (addr & 0xf000000000000000) >> 4;
+ addr &= 0x00ffffffffffffff;
+ addr |= tmp;
+
+ /* Shift up by 3 for debugfs */
return addr << 3;
}
@@ -192,6 +201,14 @@ int xscom_write_ex(uint32_t ex_target_id, uint64_t addr, uint64_t val)
return xscom_write(chip_id, addr, val);
}
+bool xscom_readable(uint64_t addr)
+{
+ /* Top nibble 9 indicates form 1 indirect, which is write only */
+ if (((addr >> 60) & 0xf) == 9)
+ return false;
+ return true;
+}
+
uint32_t xscom_init(void)
{
return xscom_scan_chips(XSCOM_BASE_PATH);
@@ -27,6 +27,8 @@ extern int xscom_write_ex(uint32_t ex_target_id, uint64_t addr, uint64_t val);
extern void xscom_for_each_chip(void (*cb)(uint32_t chip_id));
+extern bool xscom_readable(uint64_t addr);
+
extern uint32_t xscom_init(void);
#endif /* __XSCOM_H */
Update get/putscom utils to support type 1 indirect access. Currently we do some (ugly) bit mangling so that we can fit a 64 bit scom address into the debugfs interface. The current code only shifts down the top bit (indirect bit). This patch changes it to shift down the whole top nibble so that the form of the indirection is also shifted. Also currently putscom always reads back the value. This causes a problem for form 1 which can only be written. This patch marks the form 1 as not readable and hence doesn't attempt the read back. The kernel debugfs scom driver doesn't do the bit mangling correctly. So for form1 to work correctly, the kernel debugfs scom driver needs updating. Existing scoms are forwards and backwards compatible with the kernel. (FWIW the kernel PRD scom interface doesn't need to be updated as it passes the whole 64 bit scom address without any bit mangling) Signed-off-by: Michael Neuling <mikey@neuling.org> --- external/xscom-utils/putscom.c | 10 ++++++---- external/xscom-utils/xscom.c | 21 +++++++++++++++++++-- external/xscom-utils/xscom.h | 2 ++ 3 files changed, 27 insertions(+), 6 deletions(-)