/* * Support for reading and writing Meta core internal registers. * * Copyright (C) 2011 Imagination Technologies Ltd. * */ #include #include #include #include #include #include #include #include #define UNIT_BIT_MASK TXUXXRXRQ_UXX_BITS #define REG_BIT_MASK TXUXXRXRQ_RX_BITS #define THREAD_BIT_MASK TXUXXRXRQ_TX_BITS #define UNIT_SHIFTS TXUXXRXRQ_UXX_S #define REG_SHIFTS TXUXXRXRQ_RX_S #define THREAD_SHIFTS TXUXXRXRQ_TX_S #define UNIT_VAL(x) (((x) << UNIT_SHIFTS) & UNIT_BIT_MASK) #define REG_VAL(x) (((x) << REG_SHIFTS) & REG_BIT_MASK) #define THREAD_VAL(x) (((x) << THREAD_SHIFTS) & THREAD_BIT_MASK) /* * core_reg_write() - modify the content of a register in a core unit. * @unit: The unit to be modified. * @reg: Register number within the unit. * @thread: The thread we want to access. * @val: The new value to write. * * Check asm/metag_regs.h for a list/defines of supported units (ie: TXUPC_ID, * TXUTR_ID, etc), and regnums within the units (ie: TXMASKI_REGNUM, * TXPOLLI_REGNUM, etc). */ void core_reg_write(int unit, int reg, int thread, unsigned int val) { unsigned long flags; /* TXUCT_ID has its own memory mapped registers */ if (unit == TXUCT_ID) { void __iomem *cu_reg = __CU_addr(thread, reg); metag_out32(val, cu_reg); return; } __global_lock2(flags); /* wait for ready */ while (!(metag_in32(TXUXXRXRQ) & TXUXXRXRQ_DREADY_BIT)) udelay(10); /* set the value to write */ metag_out32(val, TXUXXRXDT); /* set the register to write */ val = UNIT_VAL(unit) | REG_VAL(reg) | THREAD_VAL(thread); metag_out32(val, TXUXXRXRQ); /* wait for finish */ while (!(metag_in32(TXUXXRXRQ) & TXUXXRXRQ_DREADY_BIT)) udelay(10); __global_unlock2(flags); } EXPORT_SYMBOL(core_reg_write); /* * core_reg_read() - read the content of a register in a core unit. * @unit: The unit to be modified. * @reg: Register number within the unit. * @thread: The thread we want to access. * * Check asm/metag_regs.h for a list/defines of supported units (ie: TXUPC_ID, * TXUTR_ID, etc), and regnums within the units (ie: TXMASKI_REGNUM, * TXPOLLI_REGNUM, etc). */ unsigned int core_reg_read(int unit, int reg, int thread) { unsigned long flags; unsigned int val; /* TXUCT_ID has its own memory mapped registers */ if (unit == TXUCT_ID) { void __iomem *cu_reg = __CU_addr(thread, reg); val = metag_in32(cu_reg); return val; } __global_lock2(flags); /* wait for ready */ while (!(metag_in32(TXUXXRXRQ) & TXUXXRXRQ_DREADY_BIT)) udelay(10); /* set the register to read */ val = (UNIT_VAL(unit) | REG_VAL(reg) | THREAD_VAL(thread) | TXUXXRXRQ_RDnWR_BIT); metag_out32(val, TXUXXRXRQ); /* wait for finish */ while (!(metag_in32(TXUXXRXRQ) & TXUXXRXRQ_DREADY_BIT)) udelay(10); /* read the register value */ val = metag_in32(TXUXXRXDT); __global_unlock2(flags); return val; } EXPORT_SYMBOL(core_reg_read);