Commit | Line | Data |
---|---|---|
b2441318 | 1 | // SPDX-License-Identifier: GPL-2.0 |
67088d49 MR |
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> | |
81dee67e | 15 | #include <linux/console.h> |
67088d49 MR |
16 | #include <linux/platform_device.h> |
17 | #include <linux/screen_info.h> | |
81dee67e SM |
18 | |
19 | #include "sm750.h" | |
81dee67e SM |
20 | #include "sm750_cursor.h" |
21 | ||
c075b6f2 | 22 | #define poke32(addr, data) \ |
c97b2c15 | 23 | writel((data), cursor->mmio + (addr)) |
81dee67e SM |
24 | |
25 | /* cursor control for voyager and 718/750*/ | |
26 | #define HWC_ADDRESS 0x0 | |
672f75b0 MR |
27 | #define HWC_ADDRESS_ENABLE BIT(31) |
28 | #define HWC_ADDRESS_EXT BIT(27) | |
29 | #define HWC_ADDRESS_CS BIT(26) | |
30 | #define HWC_ADDRESS_ADDRESS_MASK 0x3ffffff | |
81dee67e SM |
31 | |
32 | #define HWC_LOCATION 0x4 | |
fe3bd267 MR |
33 | #define HWC_LOCATION_TOP BIT(27) |
34 | #define HWC_LOCATION_Y_SHIFT 16 | |
35 | #define HWC_LOCATION_Y_MASK (0x7ff << 16) | |
36 | #define HWC_LOCATION_LEFT BIT(11) | |
37 | #define HWC_LOCATION_X_MASK 0x7ff | |
81dee67e SM |
38 | |
39 | #define HWC_COLOR_12 0x8 | |
6aa178ee MR |
40 | #define HWC_COLOR_12_2_RGB565_SHIFT 16 |
41 | #define HWC_COLOR_12_2_RGB565_MASK (0xffff << 16) | |
42 | #define HWC_COLOR_12_1_RGB565_MASK 0xffff | |
81dee67e SM |
43 | |
44 | #define HWC_COLOR_3 0xC | |
6aa178ee | 45 | #define HWC_COLOR_3_RGB565_MASK 0xffff |
81dee67e | 46 | |
81dee67e | 47 | /* hw_cursor_xxx works for voyager,718 and 750 */ |
52d0744d | 48 | void sm750_hw_cursor_enable(struct lynx_cursor *cursor) |
81dee67e SM |
49 | { |
50 | u32 reg; | |
40403c1b | 51 | |
672f75b0 | 52 | reg = (cursor->offset & HWC_ADDRESS_ADDRESS_MASK) | HWC_ADDRESS_ENABLE; |
c075b6f2 | 53 | poke32(HWC_ADDRESS, reg); |
81dee67e | 54 | } |
23b6fc73 | 55 | |
52d0744d | 56 | void sm750_hw_cursor_disable(struct lynx_cursor *cursor) |
81dee67e | 57 | { |
c075b6f2 | 58 | poke32(HWC_ADDRESS, 0); |
81dee67e SM |
59 | } |
60 | ||
c9750456 | 61 | void sm750_hw_cursor_setSize(struct lynx_cursor *cursor, int w, int h) |
81dee67e SM |
62 | { |
63 | cursor->w = w; | |
64 | cursor->h = h; | |
65 | } | |
23b6fc73 | 66 | |
c9750456 | 67 | void sm750_hw_cursor_setPos(struct lynx_cursor *cursor, int x, int y) |
81dee67e SM |
68 | { |
69 | u32 reg; | |
40403c1b | 70 | |
4e1c89de VR |
71 | reg = ((y << HWC_LOCATION_Y_SHIFT) & HWC_LOCATION_Y_MASK) | |
72 | (x & HWC_LOCATION_X_MASK); | |
c075b6f2 | 73 | poke32(HWC_LOCATION, reg); |
81dee67e | 74 | } |
23b6fc73 | 75 | |
c9750456 | 76 | void sm750_hw_cursor_setColor(struct lynx_cursor *cursor, u32 fg, u32 bg) |
81dee67e | 77 | { |
6aa178ee MR |
78 | u32 reg = (fg << HWC_COLOR_12_2_RGB565_SHIFT) & |
79 | HWC_COLOR_12_2_RGB565_MASK; | |
80 | ||
c075b6f2 MS |
81 | poke32(HWC_COLOR_12, reg | (bg & HWC_COLOR_12_1_RGB565_MASK)); |
82 | poke32(HWC_COLOR_3, 0xffe0); | |
81dee67e SM |
83 | } |
84 | ||
c9750456 MD |
85 | void sm750_hw_cursor_setData(struct lynx_cursor *cursor, u16 rop, |
86 | const u8 *pcol, const u8 *pmsk) | |
81dee67e | 87 | { |
c97b2c15 IA |
88 | int i, j, count, pitch, offset; |
89 | u8 color, mask, opr; | |
81dee67e | 90 | u16 data; |
35fb80b9 | 91 | void __iomem *pbuffer, *pstart; |
81dee67e SM |
92 | |
93 | /* in byte*/ | |
94 | pitch = cursor->w >> 3; | |
95 | ||
96 | /* in byte */ | |
97 | count = pitch * cursor->h; | |
98 | ||
35fb80b9 LS |
99 | /* in byte */ |
100 | offset = cursor->maxW * 2 / 8; | |
81dee67e SM |
101 | |
102 | data = 0; | |
35fb80b9 | 103 | pstart = cursor->vstart; |
81dee67e SM |
104 | pbuffer = pstart; |
105 | ||
259fef35 | 106 | for (i = 0; i < count; i++) { |
81dee67e SM |
107 | color = *pcol++; |
108 | mask = *pmsk++; | |
109 | data = 0; | |
110 | ||
adbb90e8 | 111 | for (j = 0; j < 8; j++) { |
3efc6616 | 112 | if (mask & (0x80 >> j)) { |
9ccc5f44 | 113 | if (rop == ROP_XOR) |
81dee67e SM |
114 | opr = mask ^ color; |
115 | else | |
116 | opr = mask & color; | |
117 | ||
118 | /* 2 stands for forecolor and 1 for backcolor */ | |
3efc6616 | 119 | data |= ((opr & (0x80 >> j)) ? 2 : 1) << (j * 2); |
81dee67e SM |
120 | } |
121 | } | |
35fb80b9 | 122 | iowrite16(data, pbuffer); |
81dee67e SM |
123 | |
124 | /* assume pitch is 1,2,4,8,...*/ | |
04c73f28 | 125 | if ((i + 1) % pitch == 0) { |
81dee67e SM |
126 | /* need a return */ |
127 | pstart += offset; | |
128 | pbuffer = pstart; | |
6338a781 | 129 | } else { |
35fb80b9 | 130 | pbuffer += sizeof(u16); |
81dee67e | 131 | } |
81dee67e | 132 | } |
81dee67e SM |
133 | } |
134 | ||
c9750456 MD |
135 | void sm750_hw_cursor_setData2(struct lynx_cursor *cursor, u16 rop, |
136 | const u8 *pcol, const u8 *pmsk) | |
81dee67e | 137 | { |
c97b2c15 | 138 | int i, j, count, pitch, offset; |
041d3a42 | 139 | u8 color, mask; |
81dee67e | 140 | u16 data; |
35fb80b9 | 141 | void __iomem *pbuffer, *pstart; |
81dee67e SM |
142 | |
143 | /* in byte*/ | |
144 | pitch = cursor->w >> 3; | |
145 | ||
146 | /* in byte */ | |
147 | count = pitch * cursor->h; | |
148 | ||
35fb80b9 LS |
149 | /* in byte */ |
150 | offset = cursor->maxW * 2 / 8; | |
81dee67e SM |
151 | |
152 | data = 0; | |
35fb80b9 | 153 | pstart = cursor->vstart; |
81dee67e SM |
154 | pbuffer = pstart; |
155 | ||
259fef35 | 156 | for (i = 0; i < count; i++) { |
81dee67e SM |
157 | color = *pcol++; |
158 | mask = *pmsk++; | |
159 | data = 0; | |
160 | ||
adbb90e8 | 161 | for (j = 0; j < 8; j++) { |
3efc6616 KD |
162 | if (mask & (1 << j)) |
163 | data |= ((color & (1 << j)) ? 1 : 2) << (j * 2); | |
81dee67e | 164 | } |
35fb80b9 | 165 | iowrite16(data, pbuffer); |
81dee67e SM |
166 | |
167 | /* assume pitch is 1,2,4,8,...*/ | |
3efc6616 | 168 | if (!(i & (pitch - 1))) { |
81dee67e SM |
169 | /* need a return */ |
170 | pstart += offset; | |
171 | pbuffer = pstart; | |
6338a781 | 172 | } else { |
35fb80b9 | 173 | pbuffer += sizeof(u16); |
81dee67e | 174 | } |
81dee67e | 175 | } |
81dee67e | 176 | } |