| .. | .. |
|---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-only */ |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright 2010 Matt Turner. |
|---|
| 3 | | - * Copyright 2012 Red Hat |
|---|
| 4 | | - * |
|---|
| 5 | | - * This file is subject to the terms and conditions of the GNU General |
|---|
| 6 | | - * Public License version 2. See the file COPYING in the main |
|---|
| 7 | | - * directory of this archive for more details. |
|---|
| 4 | + * Copyright 2012 Red Hat |
|---|
| 8 | 5 | * |
|---|
| 9 | 6 | * Authors: Matthew Garrett |
|---|
| 10 | 7 | * Matt Turner |
|---|
| .. | .. |
|---|
| 13 | 10 | #ifndef __MGAG200_DRV_H__ |
|---|
| 14 | 11 | #define __MGAG200_DRV_H__ |
|---|
| 15 | 12 | |
|---|
| 13 | +#include <linux/i2c-algo-bit.h> |
|---|
| 14 | +#include <linux/i2c.h> |
|---|
| 15 | + |
|---|
| 16 | 16 | #include <video/vga.h> |
|---|
| 17 | 17 | |
|---|
| 18 | 18 | #include <drm/drm_encoder.h> |
|---|
| 19 | 19 | #include <drm/drm_fb_helper.h> |
|---|
| 20 | | -#include <drm/ttm/ttm_bo_api.h> |
|---|
| 21 | | -#include <drm/ttm/ttm_bo_driver.h> |
|---|
| 22 | | -#include <drm/ttm/ttm_placement.h> |
|---|
| 23 | | -#include <drm/ttm/ttm_memory.h> |
|---|
| 24 | | -#include <drm/ttm/ttm_module.h> |
|---|
| 25 | | - |
|---|
| 26 | 20 | #include <drm/drm_gem.h> |
|---|
| 27 | | - |
|---|
| 28 | | -#include <linux/i2c.h> |
|---|
| 29 | | -#include <linux/i2c-algo-bit.h> |
|---|
| 21 | +#include <drm/drm_gem_shmem_helper.h> |
|---|
| 22 | +#include <drm/drm_simple_kms_helper.h> |
|---|
| 30 | 23 | |
|---|
| 31 | 24 | #include "mgag200_reg.h" |
|---|
| 32 | 25 | |
|---|
| .. | .. |
|---|
| 40 | 33 | #define DRIVER_MINOR 0 |
|---|
| 41 | 34 | #define DRIVER_PATCHLEVEL 0 |
|---|
| 42 | 35 | |
|---|
| 43 | | -#define MGAG200FB_CONN_LIMIT 1 |
|---|
| 44 | | - |
|---|
| 45 | 36 | #define RREG8(reg) ioread8(((void __iomem *)mdev->rmmio) + (reg)) |
|---|
| 46 | 37 | #define WREG8(reg, v) iowrite8(v, ((void __iomem *)mdev->rmmio) + (reg)) |
|---|
| 47 | 38 | #define RREG32(reg) ioread32(((void __iomem *)mdev->rmmio) + (reg)) |
|---|
| 48 | 39 | #define WREG32(reg, v) iowrite32(v, ((void __iomem *)mdev->rmmio) + (reg)) |
|---|
| 49 | 40 | |
|---|
| 41 | +#define MGA_BIOS_OFFSET 0x7ffc |
|---|
| 42 | + |
|---|
| 50 | 43 | #define ATTR_INDEX 0x1fc0 |
|---|
| 51 | 44 | #define ATTR_DATA 0x1fc1 |
|---|
| 45 | + |
|---|
| 46 | +#define WREG_MISC(v) \ |
|---|
| 47 | + WREG8(MGA_MISC_OUT, v) |
|---|
| 48 | + |
|---|
| 49 | +#define RREG_MISC(v) \ |
|---|
| 50 | + ((v) = RREG8(MGA_MISC_IN)) |
|---|
| 51 | + |
|---|
| 52 | +#define WREG_MISC_MASKED(v, mask) \ |
|---|
| 53 | + do { \ |
|---|
| 54 | + u8 misc_; \ |
|---|
| 55 | + u8 mask_ = (mask); \ |
|---|
| 56 | + RREG_MISC(misc_); \ |
|---|
| 57 | + misc_ &= ~mask_; \ |
|---|
| 58 | + misc_ |= ((v) & mask_); \ |
|---|
| 59 | + WREG_MISC(misc_); \ |
|---|
| 60 | + } while (0) |
|---|
| 52 | 61 | |
|---|
| 53 | 62 | #define WREG_ATTR(reg, v) \ |
|---|
| 54 | 63 | do { \ |
|---|
| .. | .. |
|---|
| 57 | 66 | WREG8(ATTR_DATA, v); \ |
|---|
| 58 | 67 | } while (0) \ |
|---|
| 59 | 68 | |
|---|
| 69 | +#define RREG_SEQ(reg, v) \ |
|---|
| 70 | + do { \ |
|---|
| 71 | + WREG8(MGAREG_SEQ_INDEX, reg); \ |
|---|
| 72 | + v = RREG8(MGAREG_SEQ_DATA); \ |
|---|
| 73 | + } while (0) \ |
|---|
| 74 | + |
|---|
| 60 | 75 | #define WREG_SEQ(reg, v) \ |
|---|
| 61 | 76 | do { \ |
|---|
| 62 | 77 | WREG8(MGAREG_SEQ_INDEX, reg); \ |
|---|
| 63 | 78 | WREG8(MGAREG_SEQ_DATA, v); \ |
|---|
| 79 | + } while (0) \ |
|---|
| 80 | + |
|---|
| 81 | +#define RREG_CRT(reg, v) \ |
|---|
| 82 | + do { \ |
|---|
| 83 | + WREG8(MGAREG_CRTC_INDEX, reg); \ |
|---|
| 84 | + v = RREG8(MGAREG_CRTC_DATA); \ |
|---|
| 64 | 85 | } while (0) \ |
|---|
| 65 | 86 | |
|---|
| 66 | 87 | #define WREG_CRT(reg, v) \ |
|---|
| .. | .. |
|---|
| 69 | 90 | WREG8(MGAREG_CRTC_DATA, v); \ |
|---|
| 70 | 91 | } while (0) \ |
|---|
| 71 | 92 | |
|---|
| 93 | +#define RREG_ECRT(reg, v) \ |
|---|
| 94 | + do { \ |
|---|
| 95 | + WREG8(MGAREG_CRTCEXT_INDEX, reg); \ |
|---|
| 96 | + v = RREG8(MGAREG_CRTCEXT_DATA); \ |
|---|
| 97 | + } while (0) \ |
|---|
| 72 | 98 | |
|---|
| 73 | 99 | #define WREG_ECRT(reg, v) \ |
|---|
| 74 | 100 | do { \ |
|---|
| .. | .. |
|---|
| 100 | 126 | #define MGAG200_MAX_FB_HEIGHT 4096 |
|---|
| 101 | 127 | #define MGAG200_MAX_FB_WIDTH 4096 |
|---|
| 102 | 128 | |
|---|
| 103 | | -#define MATROX_DPMS_CLEARED (-1) |
|---|
| 104 | | - |
|---|
| 105 | | -#define to_mga_crtc(x) container_of(x, struct mga_crtc, base) |
|---|
| 106 | | -#define to_mga_encoder(x) container_of(x, struct mga_encoder, base) |
|---|
| 107 | 129 | #define to_mga_connector(x) container_of(x, struct mga_connector, base) |
|---|
| 108 | | -#define to_mga_framebuffer(x) container_of(x, struct mga_framebuffer, base) |
|---|
| 109 | | - |
|---|
| 110 | | -struct mga_framebuffer { |
|---|
| 111 | | - struct drm_framebuffer base; |
|---|
| 112 | | - struct drm_gem_object *obj; |
|---|
| 113 | | -}; |
|---|
| 114 | | - |
|---|
| 115 | | -struct mga_fbdev { |
|---|
| 116 | | - struct drm_fb_helper helper; |
|---|
| 117 | | - struct mga_framebuffer mfb; |
|---|
| 118 | | - void *sysram; |
|---|
| 119 | | - int size; |
|---|
| 120 | | - struct ttm_bo_kmap_obj mapping; |
|---|
| 121 | | - int x1, y1, x2, y2; /* dirty rect */ |
|---|
| 122 | | - spinlock_t dirty_lock; |
|---|
| 123 | | -}; |
|---|
| 124 | | - |
|---|
| 125 | | -struct mga_crtc { |
|---|
| 126 | | - struct drm_crtc base; |
|---|
| 127 | | - u8 lut_r[256], lut_g[256], lut_b[256]; |
|---|
| 128 | | - int last_dpms; |
|---|
| 129 | | - bool enabled; |
|---|
| 130 | | -}; |
|---|
| 131 | | - |
|---|
| 132 | | -struct mga_mode_info { |
|---|
| 133 | | - bool mode_config_initialized; |
|---|
| 134 | | - struct mga_crtc *crtc; |
|---|
| 135 | | -}; |
|---|
| 136 | | - |
|---|
| 137 | | -struct mga_encoder { |
|---|
| 138 | | - struct drm_encoder base; |
|---|
| 139 | | - int last_dpms; |
|---|
| 140 | | -}; |
|---|
| 141 | | - |
|---|
| 142 | 130 | |
|---|
| 143 | 131 | struct mga_i2c_chan { |
|---|
| 144 | 132 | struct i2c_adapter adapter; |
|---|
| .. | .. |
|---|
| 152 | 140 | struct mga_i2c_chan *i2c; |
|---|
| 153 | 141 | }; |
|---|
| 154 | 142 | |
|---|
| 155 | | -struct mga_cursor { |
|---|
| 156 | | - /* |
|---|
| 157 | | - We have to have 2 buffers for the cursor to avoid occasional |
|---|
| 158 | | - corruption while switching cursor icons. |
|---|
| 159 | | - If either of these is NULL, then don't do hardware cursors, and |
|---|
| 160 | | - fall back to software. |
|---|
| 161 | | - */ |
|---|
| 162 | | - struct mgag200_bo *pixels_1; |
|---|
| 163 | | - struct mgag200_bo *pixels_2; |
|---|
| 164 | | - u64 pixels_1_gpu_addr, pixels_2_gpu_addr; |
|---|
| 165 | | - /* The currently displayed icon, this points to one of pixels_1, or pixels_2 */ |
|---|
| 166 | | - struct mgag200_bo *pixels_current; |
|---|
| 167 | | - /* The previously displayed icon */ |
|---|
| 168 | | - struct mgag200_bo *pixels_prev; |
|---|
| 169 | | -}; |
|---|
| 170 | | - |
|---|
| 171 | 143 | struct mga_mc { |
|---|
| 172 | 144 | resource_size_t vram_size; |
|---|
| 173 | 145 | resource_size_t vram_base; |
|---|
| .. | .. |
|---|
| 175 | 147 | }; |
|---|
| 176 | 148 | |
|---|
| 177 | 149 | enum mga_type { |
|---|
| 150 | + G200_PCI, |
|---|
| 151 | + G200_AGP, |
|---|
| 178 | 152 | G200_SE_A, |
|---|
| 179 | 153 | G200_SE_B, |
|---|
| 180 | 154 | G200_WB, |
|---|
| .. | .. |
|---|
| 185 | 159 | G200_EW3, |
|---|
| 186 | 160 | }; |
|---|
| 187 | 161 | |
|---|
| 162 | +/* HW does not handle 'startadd' field correct. */ |
|---|
| 163 | +#define MGAG200_FLAG_HW_BUG_NO_STARTADD (1ul << 8) |
|---|
| 164 | + |
|---|
| 165 | +#define MGAG200_TYPE_MASK (0x000000ff) |
|---|
| 166 | +#define MGAG200_FLAG_MASK (0x00ffff00) |
|---|
| 167 | + |
|---|
| 188 | 168 | #define IS_G200_SE(mdev) (mdev->type == G200_SE_A || mdev->type == G200_SE_B) |
|---|
| 189 | 169 | |
|---|
| 190 | 170 | struct mga_device { |
|---|
| 191 | | - struct drm_device *dev; |
|---|
| 171 | + struct drm_device base; |
|---|
| 192 | 172 | unsigned long flags; |
|---|
| 193 | 173 | |
|---|
| 194 | 174 | resource_size_t rmmio_base; |
|---|
| .. | .. |
|---|
| 196 | 176 | void __iomem *rmmio; |
|---|
| 197 | 177 | |
|---|
| 198 | 178 | struct mga_mc mc; |
|---|
| 199 | | - struct mga_mode_info mode_info; |
|---|
| 200 | 179 | |
|---|
| 201 | | - struct mga_fbdev *mfbdev; |
|---|
| 202 | | - struct mga_cursor cursor; |
|---|
| 180 | + void __iomem *vram; |
|---|
| 181 | + size_t vram_fb_available; |
|---|
| 203 | 182 | |
|---|
| 204 | | - bool suspended; |
|---|
| 205 | | - int num_crtc; |
|---|
| 206 | 183 | enum mga_type type; |
|---|
| 207 | | - int has_sdram; |
|---|
| 208 | | - struct drm_display_mode mode; |
|---|
| 209 | 184 | |
|---|
| 210 | 185 | int bpp_shifts[4]; |
|---|
| 211 | 186 | |
|---|
| 212 | 187 | int fb_mtrr; |
|---|
| 213 | 188 | |
|---|
| 214 | | - struct { |
|---|
| 215 | | - struct drm_global_reference mem_global_ref; |
|---|
| 216 | | - struct ttm_bo_global_ref bo_global_ref; |
|---|
| 217 | | - struct ttm_bo_device bdev; |
|---|
| 218 | | - } ttm; |
|---|
| 189 | + union { |
|---|
| 190 | + struct { |
|---|
| 191 | + long ref_clk; |
|---|
| 192 | + long pclk_min; |
|---|
| 193 | + long pclk_max; |
|---|
| 194 | + } g200; |
|---|
| 195 | + struct { |
|---|
| 196 | + /* SE model number stored in reg 0x1e24 */ |
|---|
| 197 | + u32 unique_rev_id; |
|---|
| 198 | + } g200se; |
|---|
| 199 | + } model; |
|---|
| 219 | 200 | |
|---|
| 220 | | - /* SE model number stored in reg 0x1e24 */ |
|---|
| 221 | | - u32 unique_rev_id; |
|---|
| 201 | + |
|---|
| 202 | + struct mga_connector connector; |
|---|
| 203 | + struct drm_simple_display_pipe display_pipe; |
|---|
| 222 | 204 | }; |
|---|
| 223 | 205 | |
|---|
| 224 | | - |
|---|
| 225 | | -struct mgag200_bo { |
|---|
| 226 | | - struct ttm_buffer_object bo; |
|---|
| 227 | | - struct ttm_placement placement; |
|---|
| 228 | | - struct ttm_bo_kmap_obj kmap; |
|---|
| 229 | | - struct drm_gem_object gem; |
|---|
| 230 | | - struct ttm_place placements[3]; |
|---|
| 231 | | - int pin_count; |
|---|
| 232 | | -}; |
|---|
| 233 | | -#define gem_to_mga_bo(gobj) container_of((gobj), struct mgag200_bo, gem) |
|---|
| 234 | | - |
|---|
| 235 | | -static inline struct mgag200_bo * |
|---|
| 236 | | -mgag200_bo(struct ttm_buffer_object *bo) |
|---|
| 206 | +static inline struct mga_device *to_mga_device(struct drm_device *dev) |
|---|
| 237 | 207 | { |
|---|
| 238 | | - return container_of(bo, struct mgag200_bo, bo); |
|---|
| 208 | + return container_of(dev, struct mga_device, base); |
|---|
| 209 | +} |
|---|
| 210 | + |
|---|
| 211 | +static inline enum mga_type |
|---|
| 212 | +mgag200_type_from_driver_data(kernel_ulong_t driver_data) |
|---|
| 213 | +{ |
|---|
| 214 | + return (enum mga_type)(driver_data & MGAG200_TYPE_MASK); |
|---|
| 215 | +} |
|---|
| 216 | + |
|---|
| 217 | +static inline unsigned long |
|---|
| 218 | +mgag200_flags_from_driver_data(kernel_ulong_t driver_data) |
|---|
| 219 | +{ |
|---|
| 220 | + return driver_data & MGAG200_FLAG_MASK; |
|---|
| 239 | 221 | } |
|---|
| 240 | 222 | |
|---|
| 241 | 223 | /* mgag200_mode.c */ |
|---|
| 242 | 224 | int mgag200_modeset_init(struct mga_device *mdev); |
|---|
| 243 | | -void mgag200_modeset_fini(struct mga_device *mdev); |
|---|
| 244 | 225 | |
|---|
| 245 | | - /* mgag200_fb.c */ |
|---|
| 246 | | -int mgag200_fbdev_init(struct mga_device *mdev); |
|---|
| 247 | | -void mgag200_fbdev_fini(struct mga_device *mdev); |
|---|
| 248 | | - |
|---|
| 249 | | - /* mgag200_main.c */ |
|---|
| 250 | | -int mgag200_framebuffer_init(struct drm_device *dev, |
|---|
| 251 | | - struct mga_framebuffer *mfb, |
|---|
| 252 | | - const struct drm_mode_fb_cmd2 *mode_cmd, |
|---|
| 253 | | - struct drm_gem_object *obj); |
|---|
| 254 | | - |
|---|
| 255 | | - |
|---|
| 256 | | -int mgag200_driver_load(struct drm_device *dev, unsigned long flags); |
|---|
| 257 | | -void mgag200_driver_unload(struct drm_device *dev); |
|---|
| 258 | | -int mgag200_gem_create(struct drm_device *dev, |
|---|
| 259 | | - u32 size, bool iskernel, |
|---|
| 260 | | - struct drm_gem_object **obj); |
|---|
| 261 | | -int mgag200_dumb_create(struct drm_file *file, |
|---|
| 262 | | - struct drm_device *dev, |
|---|
| 263 | | - struct drm_mode_create_dumb *args); |
|---|
| 264 | | -void mgag200_gem_free_object(struct drm_gem_object *obj); |
|---|
| 265 | | -int |
|---|
| 266 | | -mgag200_dumb_mmap_offset(struct drm_file *file, |
|---|
| 267 | | - struct drm_device *dev, |
|---|
| 268 | | - uint32_t handle, |
|---|
| 269 | | - uint64_t *offset); |
|---|
| 270 | 226 | /* mgag200_i2c.c */ |
|---|
| 271 | 227 | struct mga_i2c_chan *mgag200_i2c_create(struct drm_device *dev); |
|---|
| 272 | 228 | void mgag200_i2c_destroy(struct mga_i2c_chan *i2c); |
|---|
| 273 | 229 | |
|---|
| 274 | | -#define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT) |
|---|
| 275 | | -void mgag200_ttm_placement(struct mgag200_bo *bo, int domain); |
|---|
| 276 | | - |
|---|
| 277 | | -static inline int mgag200_bo_reserve(struct mgag200_bo *bo, bool no_wait) |
|---|
| 278 | | -{ |
|---|
| 279 | | - int ret; |
|---|
| 280 | | - |
|---|
| 281 | | - ret = ttm_bo_reserve(&bo->bo, true, no_wait, NULL); |
|---|
| 282 | | - if (ret) { |
|---|
| 283 | | - if (ret != -ERESTARTSYS && ret != -EBUSY) |
|---|
| 284 | | - DRM_ERROR("reserve failed %p\n", bo); |
|---|
| 285 | | - return ret; |
|---|
| 286 | | - } |
|---|
| 287 | | - return 0; |
|---|
| 288 | | -} |
|---|
| 289 | | - |
|---|
| 290 | | -static inline void mgag200_bo_unreserve(struct mgag200_bo *bo) |
|---|
| 291 | | -{ |
|---|
| 292 | | - ttm_bo_unreserve(&bo->bo); |
|---|
| 293 | | -} |
|---|
| 294 | | - |
|---|
| 295 | | -int mgag200_bo_create(struct drm_device *dev, int size, int align, |
|---|
| 296 | | - uint32_t flags, struct mgag200_bo **pastbo); |
|---|
| 230 | + /* mgag200_mm.c */ |
|---|
| 297 | 231 | int mgag200_mm_init(struct mga_device *mdev); |
|---|
| 298 | | -void mgag200_mm_fini(struct mga_device *mdev); |
|---|
| 299 | | -int mgag200_mmap(struct file *filp, struct vm_area_struct *vma); |
|---|
| 300 | | -int mgag200_bo_pin(struct mgag200_bo *bo, u32 pl_flag, u64 *gpu_addr); |
|---|
| 301 | | -int mgag200_bo_unpin(struct mgag200_bo *bo); |
|---|
| 302 | | -int mgag200_bo_push_sysram(struct mgag200_bo *bo); |
|---|
| 303 | | - /* mgag200_cursor.c */ |
|---|
| 304 | | -int mga_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, |
|---|
| 305 | | - uint32_t handle, uint32_t width, uint32_t height); |
|---|
| 306 | | -int mga_crtc_cursor_move(struct drm_crtc *crtc, int x, int y); |
|---|
| 307 | 232 | |
|---|
| 308 | 233 | #endif /* __MGAG200_DRV_H__ */ |
|---|