linux/arch/metag/kernel/core_reg.c
<<
>>
Prefs
   1/*
   2 *  Support for reading and writing Meta core internal registers.
   3 *
   4 *  Copyright (C) 2011 Imagination Technologies Ltd.
   5 *
   6 */
   7
   8#include <linux/delay.h>
   9#include <linux/export.h>
  10
  11#include <asm/core_reg.h>
  12#include <asm/global_lock.h>
  13#include <asm/hwthread.h>
  14#include <asm/io.h>
  15#include <asm/metag_mem.h>
  16#include <asm/metag_regs.h>
  17
  18#define UNIT_BIT_MASK           TXUXXRXRQ_UXX_BITS
  19#define REG_BIT_MASK            TXUXXRXRQ_RX_BITS
  20#define THREAD_BIT_MASK         TXUXXRXRQ_TX_BITS
  21
  22#define UNIT_SHIFTS             TXUXXRXRQ_UXX_S
  23#define REG_SHIFTS              TXUXXRXRQ_RX_S
  24#define THREAD_SHIFTS           TXUXXRXRQ_TX_S
  25
  26#define UNIT_VAL(x)             (((x) << UNIT_SHIFTS) & UNIT_BIT_MASK)
  27#define REG_VAL(x)              (((x) << REG_SHIFTS) & REG_BIT_MASK)
  28#define THREAD_VAL(x)           (((x) << THREAD_SHIFTS) & THREAD_BIT_MASK)
  29
  30/*
  31 * core_reg_write() - modify the content of a register in a core unit.
  32 * @unit:       The unit to be modified.
  33 * @reg:        Register number within the unit.
  34 * @thread:     The thread we want to access.
  35 * @val:        The new value to write.
  36 *
  37 * Check asm/metag_regs.h for a list/defines of supported units (ie: TXUPC_ID,
  38 * TXUTR_ID, etc), and regnums within the units (ie: TXMASKI_REGNUM,
  39 * TXPOLLI_REGNUM, etc).
  40 */
  41void core_reg_write(int unit, int reg, int thread, unsigned int val)
  42{
  43        unsigned long flags;
  44
  45        /* TXUCT_ID has its own memory mapped registers */
  46        if (unit == TXUCT_ID) {
  47                void __iomem *cu_reg = __CU_addr(thread, reg);
  48                metag_out32(val, cu_reg);
  49                return;
  50        }
  51
  52        __global_lock2(flags);
  53
  54        /* wait for ready */
  55        while (!(metag_in32(TXUXXRXRQ) & TXUXXRXRQ_DREADY_BIT))
  56                udelay(10);
  57
  58        /* set the value to write */
  59        metag_out32(val, TXUXXRXDT);
  60
  61        /* set the register to write */
  62        val = UNIT_VAL(unit) | REG_VAL(reg) | THREAD_VAL(thread);
  63        metag_out32(val, TXUXXRXRQ);
  64
  65        /* wait for finish */
  66        while (!(metag_in32(TXUXXRXRQ) & TXUXXRXRQ_DREADY_BIT))
  67                udelay(10);
  68
  69        __global_unlock2(flags);
  70}
  71EXPORT_SYMBOL(core_reg_write);
  72
  73/*
  74 * core_reg_read() - read the content of a register in a core unit.
  75 * @unit:       The unit to be modified.
  76 * @reg:        Register number within the unit.
  77 * @thread:     The thread we want to access.
  78 *
  79 * Check asm/metag_regs.h for a list/defines of supported units (ie: TXUPC_ID,
  80 * TXUTR_ID, etc), and regnums within the units (ie: TXMASKI_REGNUM,
  81 * TXPOLLI_REGNUM, etc).
  82 */
  83unsigned int core_reg_read(int unit, int reg, int thread)
  84{
  85        unsigned long flags;
  86        unsigned int val;
  87
  88        /* TXUCT_ID has its own memory mapped registers */
  89        if (unit == TXUCT_ID) {
  90                void __iomem *cu_reg = __CU_addr(thread, reg);
  91                val = metag_in32(cu_reg);
  92                return val;
  93        }
  94
  95        __global_lock2(flags);
  96
  97        /* wait for ready */
  98        while (!(metag_in32(TXUXXRXRQ) & TXUXXRXRQ_DREADY_BIT))
  99                udelay(10);
 100
 101        /* set the register to read */
 102        val = (UNIT_VAL(unit) | REG_VAL(reg) | THREAD_VAL(thread) |
 103                                                        TXUXXRXRQ_RDnWR_BIT);
 104        metag_out32(val, TXUXXRXRQ);
 105
 106        /* wait for finish */
 107        while (!(metag_in32(TXUXXRXRQ) & TXUXXRXRQ_DREADY_BIT))
 108                udelay(10);
 109
 110        /* read the register value */
 111        val = metag_in32(TXUXXRXDT);
 112
 113        __global_unlock2(flags);
 114
 115        return val;
 116}
 117EXPORT_SYMBOL(core_reg_read);
 118