^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Support for MicroBlaze PVR (processor version register)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2007-2009 PetaLogix
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2007 John Williams <john.williams@petalogix.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * License. See the file "COPYING" in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/compiler.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <asm/exceptions.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <asm/pvr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/irqflags.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * Until we get an assembler that knows about the pvr registers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * this horrible cruft will have to do.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * That hardcoded opcode is mfs r3, rpvrNN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define get_single_pvr(pvrid, val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) register unsigned tmp __asm__("r3"); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) tmp = 0x0; /* Prevent warning about unused */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) __asm__ __volatile__ ( \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) "mfs %0, rpvr" #pvrid ";" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) : "=r" (tmp) : : "memory"); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) val = tmp; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * Does the CPU support the PVR register?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * return value:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * 0: no PVR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * 1: simple PVR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * 2: full PVR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * This must work on all CPU versions, including those before the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * PVR was even an option.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) int cpu_has_pvr(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) unsigned pvr0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) local_save_flags(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) /* PVR bit in MSR tells us if there is any support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) if (!(flags & PVR_MSR_BIT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) get_single_pvr(0, pvr0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) pr_debug("%s: pvr0 is 0x%08x\n", __func__, pvr0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) if (pvr0 & PVR0_PVR_FULL_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /* for partial PVR use static cpuinfo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) return 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) void get_pvr(struct pvr_s *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) get_single_pvr(0, p->pvr[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) get_single_pvr(1, p->pvr[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) get_single_pvr(2, p->pvr[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) get_single_pvr(3, p->pvr[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) get_single_pvr(4, p->pvr[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) get_single_pvr(5, p->pvr[5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) get_single_pvr(6, p->pvr[6]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) get_single_pvr(7, p->pvr[7]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) get_single_pvr(8, p->pvr[8]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) get_single_pvr(9, p->pvr[9]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) get_single_pvr(10, p->pvr[10]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) get_single_pvr(11, p->pvr[11]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }