root/drivers/video/fbdev/bt431.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. bt431_set_value
  2. bt431_get_value
  3. bt431_select_reg
  4. bt431_read_reg_inc
  5. bt431_write_reg_inc
  6. bt431_read_reg
  7. bt431_write_reg
  8. bt431_read_cmap_inc
  9. bt431_write_cmap_inc
  10. bt431_read_cmap
  11. bt431_write_cmap
  12. bt431_enable_cursor
  13. bt431_erase_cursor
  14. bt431_position_cursor
  15. bt431_set_cursor
  16. bt431_init_cursor

   1 /*
   2  *      linux/drivers/video/bt431.h
   3  *
   4  *      Copyright 2003  Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
   5  *      Copyright 2016  Maciej W. Rozycki <macro@linux-mips.org>
   6  *
   7  *      This file is subject to the terms and conditions of the GNU General
   8  *      Public License. See the file COPYING in the main directory of this
   9  *      archive for more details.
  10  */
  11 #include <linux/types.h>
  12 
  13 #define BT431_CURSOR_SIZE       64
  14 
  15 /*
  16  * Bt431 cursor generator registers, 32-bit aligned.
  17  * Two twin Bt431 are used on the DECstation's PMAG-AA.
  18  */
  19 struct bt431_regs {
  20         volatile u16 addr_lo;
  21         u16 pad0;
  22         volatile u16 addr_hi;
  23         u16 pad1;
  24         volatile u16 addr_cmap;
  25         u16 pad2;
  26         volatile u16 addr_reg;
  27         u16 pad3;
  28 };
  29 
  30 static inline u16 bt431_set_value(u8 val)
  31 {
  32         return ((val << 8) | (val & 0xff)) & 0xffff;
  33 }
  34 
  35 static inline u8 bt431_get_value(u16 val)
  36 {
  37         return val & 0xff;
  38 }
  39 
  40 /*
  41  * Additional registers addressed indirectly.
  42  */
  43 #define BT431_REG_CMD           0x0000
  44 #define BT431_REG_CXLO          0x0001
  45 #define BT431_REG_CXHI          0x0002
  46 #define BT431_REG_CYLO          0x0003
  47 #define BT431_REG_CYHI          0x0004
  48 #define BT431_REG_WXLO          0x0005
  49 #define BT431_REG_WXHI          0x0006
  50 #define BT431_REG_WYLO          0x0007
  51 #define BT431_REG_WYHI          0x0008
  52 #define BT431_REG_WWLO          0x0009
  53 #define BT431_REG_WWHI          0x000a
  54 #define BT431_REG_WHLO          0x000b
  55 #define BT431_REG_WHHI          0x000c
  56 
  57 #define BT431_REG_CRAM_BASE     0x0000
  58 #define BT431_REG_CRAM_END      0x01ff
  59 
  60 /*
  61  * Command register.
  62  */
  63 #define BT431_CMD_CURS_ENABLE   0x40
  64 #define BT431_CMD_XHAIR_ENABLE  0x20
  65 #define BT431_CMD_OR_CURSORS    0x10
  66 #define BT431_CMD_XOR_CURSORS   0x00
  67 #define BT431_CMD_1_1_MUX       0x00
  68 #define BT431_CMD_4_1_MUX       0x04
  69 #define BT431_CMD_5_1_MUX       0x08
  70 #define BT431_CMD_xxx_MUX       0x0c
  71 #define BT431_CMD_THICK_1       0x00
  72 #define BT431_CMD_THICK_3       0x01
  73 #define BT431_CMD_THICK_5       0x02
  74 #define BT431_CMD_THICK_7       0x03
  75 
  76 static inline void bt431_select_reg(struct bt431_regs *regs, int ir)
  77 {
  78         /*
  79          * The compiler splits the write in two bytes without these
  80          * helper variables.
  81          */
  82         volatile u16 *lo = &(regs->addr_lo);
  83         volatile u16 *hi = &(regs->addr_hi);
  84 
  85         mb();
  86         *lo = bt431_set_value(ir & 0xff);
  87         wmb();
  88         *hi = bt431_set_value((ir >> 8) & 0xff);
  89 }
  90 
  91 /* Autoincrement read/write. */
  92 static inline u8 bt431_read_reg_inc(struct bt431_regs *regs)
  93 {
  94         /*
  95          * The compiler splits the write in two bytes without the
  96          * helper variable.
  97          */
  98         volatile u16 *r = &(regs->addr_reg);
  99 
 100         mb();
 101         return bt431_get_value(*r);
 102 }
 103 
 104 static inline void bt431_write_reg_inc(struct bt431_regs *regs, u8 value)
 105 {
 106         /*
 107          * The compiler splits the write in two bytes without the
 108          * helper variable.
 109          */
 110         volatile u16 *r = &(regs->addr_reg);
 111 
 112         mb();
 113         *r = bt431_set_value(value);
 114 }
 115 
 116 static inline u8 bt431_read_reg(struct bt431_regs *regs, int ir)
 117 {
 118         bt431_select_reg(regs, ir);
 119         return bt431_read_reg_inc(regs);
 120 }
 121 
 122 static inline void bt431_write_reg(struct bt431_regs *regs, int ir, u8 value)
 123 {
 124         bt431_select_reg(regs, ir);
 125         bt431_write_reg_inc(regs, value);
 126 }
 127 
 128 /* Autoincremented read/write for the cursor map. */
 129 static inline u16 bt431_read_cmap_inc(struct bt431_regs *regs)
 130 {
 131         /*
 132          * The compiler splits the write in two bytes without the
 133          * helper variable.
 134          */
 135         volatile u16 *r = &(regs->addr_cmap);
 136 
 137         mb();
 138         return *r;
 139 }
 140 
 141 static inline void bt431_write_cmap_inc(struct bt431_regs *regs, u16 value)
 142 {
 143         /*
 144          * The compiler splits the write in two bytes without the
 145          * helper variable.
 146          */
 147         volatile u16 *r = &(regs->addr_cmap);
 148 
 149         mb();
 150         *r = value;
 151 }
 152 
 153 static inline u16 bt431_read_cmap(struct bt431_regs *regs, int cr)
 154 {
 155         bt431_select_reg(regs, cr);
 156         return bt431_read_cmap_inc(regs);
 157 }
 158 
 159 static inline void bt431_write_cmap(struct bt431_regs *regs, int cr, u16 value)
 160 {
 161         bt431_select_reg(regs, cr);
 162         bt431_write_cmap_inc(regs, value);
 163 }
 164 
 165 static inline void bt431_enable_cursor(struct bt431_regs *regs)
 166 {
 167         bt431_write_reg(regs, BT431_REG_CMD,
 168                         BT431_CMD_CURS_ENABLE | BT431_CMD_OR_CURSORS
 169                         | BT431_CMD_4_1_MUX | BT431_CMD_THICK_1);
 170 }
 171 
 172 static inline void bt431_erase_cursor(struct bt431_regs *regs)
 173 {
 174         bt431_write_reg(regs, BT431_REG_CMD, BT431_CMD_4_1_MUX);
 175 }
 176 
 177 static inline void bt431_position_cursor(struct bt431_regs *regs, u16 x, u16 y)
 178 {
 179         /*
 180          * Magic from the MACH sources.
 181          *
 182          * Cx = x + D + H - P
 183          *  P = 37 if 1:1, 52 if 4:1, 57 if 5:1
 184          *  D = pixel skew between outdata and external data
 185          *  H = pixels between HSYNCH falling and active video
 186          *
 187          * Cy = y + V - 32
 188          *  V = scanlines between HSYNCH falling, two or more
 189          *      clocks after VSYNCH falling, and active video
 190          */
 191         x += 412 - 52;
 192         y += 68 - 32;
 193 
 194         /* Use autoincrement. */
 195         bt431_select_reg(regs, BT431_REG_CXLO);
 196         bt431_write_reg_inc(regs, x & 0xff); /* BT431_REG_CXLO */
 197         bt431_write_reg_inc(regs, (x >> 8) & 0x0f); /* BT431_REG_CXHI */
 198         bt431_write_reg_inc(regs, y & 0xff); /* BT431_REG_CYLO */
 199         bt431_write_reg_inc(regs, (y >> 8) & 0x0f); /* BT431_REG_CYHI */
 200 }
 201 
 202 static inline void bt431_set_cursor(struct bt431_regs *regs,
 203                                     const char *data, const char *mask,
 204                                     u16 rop, u16 width, u16 height)
 205 {
 206         u16 x, y;
 207         int i;
 208 
 209         i = 0;
 210         width = DIV_ROUND_UP(width, 8);
 211         bt431_select_reg(regs, BT431_REG_CRAM_BASE);
 212         for (y = 0; y < BT431_CURSOR_SIZE; y++)
 213                 for (x = 0; x < BT431_CURSOR_SIZE / 8; x++) {
 214                         u16 val = 0;
 215 
 216                         if (y < height && x < width) {
 217                                 val = mask[i];
 218                                 if (rop == ROP_XOR)
 219                                         val = (val << 8) | (val ^ data[i]);
 220                                 else
 221                                         val = (val << 8) | (val & data[i]);
 222                                 i++;
 223                         }
 224                         bt431_write_cmap_inc(regs, val);
 225                 }
 226 }
 227 
 228 static inline void bt431_init_cursor(struct bt431_regs *regs)
 229 {
 230         /* no crosshair window */
 231         bt431_select_reg(regs, BT431_REG_WXLO);
 232         bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WXLO */
 233         bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WXHI */
 234         bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WYLO */
 235         bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WYHI */
 236         bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WWLO */
 237         bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WWHI */
 238         bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WHLO */
 239         bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WHHI */
 240 }

/* [<][>][^][v][top][bottom][index][help] */