FILE
sm750_cursor.c
File preview with syntax highlighting.
linux-6.19.14/drivers/staging/sm750fb/sm750_cursor.c
1// SPDX-License-Identifier: GPL-2.0 2#include <linux/module.h> 3#include <linux/kernel.h> 4#include <linux/errno.h> 5#include <linux/string.h> 6#include <linux/mm.h> 7#include <linux/slab.h> 8#include <linux/delay.h> 9#include <linux/fb.h> 10#include <linux/ioport.h> 11#include <linux/init.h> 12#include <linux/pci.h> 13#include <linux/vmalloc.h> 14#include <linux/pagemap.h> 15#include <linux/console.h> 16#include <linux/platform_device.h> 17 18#include "sm750.h" 19#include "sm750_cursor.h" 20 21#define poke32(addr, data) \ 22writel((data), cursor->mmio + (addr)) 23 24/* cursor control for voyager and 718/750*/ 25#define HWC_ADDRESS 0x0 26#define HWC_ADDRESS_ENABLE BIT(31) 27#define HWC_ADDRESS_EXT BIT(27) 28#define HWC_ADDRESS_CS BIT(26) 29#define HWC_ADDRESS_ADDRESS_MASK 0x3ffffff 30 31#define HWC_LOCATION 0x4 32#define HWC_LOCATION_TOP BIT(27) 33#define HWC_LOCATION_Y_SHIFT 16 34#define HWC_LOCATION_Y_MASK (0x7ff << 16) 35#define HWC_LOCATION_LEFT BIT(11) 36#define HWC_LOCATION_X_MASK 0x7ff 37 38#define HWC_COLOR_12 0x8 39#define HWC_COLOR_12_2_RGB565_SHIFT 16 40#define HWC_COLOR_12_2_RGB565_MASK (0xffff << 16) 41#define HWC_COLOR_12_1_RGB565_MASK 0xffff 42 43#define HWC_COLOR_3 0xC 44#define HWC_COLOR_3_RGB565_MASK 0xffff 45 46/* hw_cursor_xxx works for voyager,718 and 750 */ 47void sm750_hw_cursor_enable(struct lynx_cursor *cursor) 48{ 49 u32 reg; 50 51 reg = (cursor->offset & HWC_ADDRESS_ADDRESS_MASK) | HWC_ADDRESS_ENABLE; 52 poke32(HWC_ADDRESS, reg); 53} 54 55void sm750_hw_cursor_disable(struct lynx_cursor *cursor) 56{ 57 poke32(HWC_ADDRESS, 0); 58} 59 60void sm750_hw_cursor_set_size(struct lynx_cursor *cursor, int w, int h) 61{ 62 cursor->w = w; 63 cursor->h = h; 64} 65 66void sm750_hw_cursor_set_pos(struct lynx_cursor *cursor, int x, int y) 67{ 68 u32 reg; 69 70 reg = ((y << HWC_LOCATION_Y_SHIFT) & HWC_LOCATION_Y_MASK) | 71 (x & HWC_LOCATION_X_MASK); 72 poke32(HWC_LOCATION, reg); 73} 74 75void sm750_hw_cursor_set_color(struct lynx_cursor *cursor, u32 fg, u32 bg) 76{ 77 u32 reg = (fg << HWC_COLOR_12_2_RGB565_SHIFT) & 78 HWC_COLOR_12_2_RGB565_MASK; 79 80 poke32(HWC_COLOR_12, reg | (bg & HWC_COLOR_12_1_RGB565_MASK)); 81 poke32(HWC_COLOR_3, 0xffe0); 82} 83 84void sm750_hw_cursor_set_data(struct lynx_cursor *cursor, u16 rop, 85 const u8 *pcol, const u8 *pmsk) 86{ 87 int i, j, count, pitch, offset; 88 u8 color, mask, opr; 89 u16 data; 90 void __iomem *pbuffer, *pstart; 91 92 /* in byte*/ 93 pitch = cursor->w >> 3; 94 95 /* in byte */ 96 count = pitch * cursor->h; 97 98 /* in byte */ 99 offset = cursor->max_w * 2 / 8; 100 101 data = 0; 102 pstart = cursor->vstart; 103 pbuffer = pstart; 104 105 for (i = 0; i < count; i++) { 106 color = *pcol++; 107 mask = *pmsk++; 108 data = 0; 109 110 for (j = 0; j < 8; j++) { 111 if (mask & (0x80 >> j)) { 112 if (rop == ROP_XOR) 113 opr = mask ^ color; 114 else 115 opr = mask & color; 116 117 /* 2 stands for forecolor and 1 for backcolor */ 118 data |= ((opr & (0x80 >> j)) ? 2 : 1) << (j * 2); 119 } 120 } 121 iowrite16(data, pbuffer); 122 123 /* assume pitch is 1,2,4,8,...*/ 124 if ((i + 1) % pitch == 0) { 125 /* need a return */ 126 pstart += offset; 127 pbuffer = pstart; 128 } else { 129 pbuffer += sizeof(u16); 130 } 131 } 132} 133 134void sm750_hw_cursor_set_data2(struct lynx_cursor *cursor, u16 rop, 135 const u8 *pcol, const u8 *pmsk) 136{ 137 int i, j, count, pitch, offset; 138 u8 color, mask; 139 u16 data; 140 void __iomem *pbuffer, *pstart; 141 142 /* in byte*/ 143 pitch = cursor->w >> 3; 144 145 /* in byte */ 146 count = pitch * cursor->h; 147 148 /* in byte */ 149 offset = cursor->max_w * 2 / 8; 150 151 data = 0; 152 pstart = cursor->vstart; 153 pbuffer = pstart; 154 155 for (i = 0; i < count; i++) { 156 color = *pcol++; 157 mask = *pmsk++; 158 data = 0; 159 160 for (j = 0; j < 8; j++) { 161 if (mask & (1 << j)) 162 data |= ((color & (1 << j)) ? 1 : 2) << (j * 2); 163 } 164 iowrite16(data, pbuffer); 165 166 /* assume pitch is 1,2,4,8,...*/ 167 if (!(i & (pitch - 1))) { 168 /* need a return */ 169 pstart += offset; 170 pbuffer = pstart; 171 } else { 172 pbuffer += sizeof(u16); 173 } 174 } 175}
~/
Read-only file preview.