Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.16 294 lines 7.6 kB view raw
1/* 2 * This program is free software; you can redistribute it and/or modify 3 * it under the terms of the GNU General Public License as published by 4 * the Free Software Foundation; either version 2 of the License, or 5 * (at your option) any later version. 6 */ 7 8#include "bochs.h" 9 10static int defx = 1024; 11static int defy = 768; 12 13module_param(defx, int, 0444); 14module_param(defy, int, 0444); 15MODULE_PARM_DESC(defx, "default x resolution"); 16MODULE_PARM_DESC(defy, "default y resolution"); 17 18/* ---------------------------------------------------------------------- */ 19 20static void bochs_crtc_load_lut(struct drm_crtc *crtc) 21{ 22} 23 24static void bochs_crtc_dpms(struct drm_crtc *crtc, int mode) 25{ 26 switch (mode) { 27 case DRM_MODE_DPMS_ON: 28 case DRM_MODE_DPMS_STANDBY: 29 case DRM_MODE_DPMS_SUSPEND: 30 case DRM_MODE_DPMS_OFF: 31 default: 32 return; 33 } 34} 35 36static bool bochs_crtc_mode_fixup(struct drm_crtc *crtc, 37 const struct drm_display_mode *mode, 38 struct drm_display_mode *adjusted_mode) 39{ 40 return true; 41} 42 43static int bochs_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, 44 struct drm_framebuffer *old_fb) 45{ 46 struct bochs_device *bochs = 47 container_of(crtc, struct bochs_device, crtc); 48 struct bochs_framebuffer *bochs_fb; 49 struct bochs_bo *bo; 50 u64 gpu_addr = 0; 51 int ret; 52 53 if (old_fb) { 54 bochs_fb = to_bochs_framebuffer(old_fb); 55 bo = gem_to_bochs_bo(bochs_fb->obj); 56 ret = ttm_bo_reserve(&bo->bo, true, false, false, 0); 57 if (ret) { 58 DRM_ERROR("failed to reserve old_fb bo\n"); 59 } else { 60 bochs_bo_unpin(bo); 61 ttm_bo_unreserve(&bo->bo); 62 } 63 } 64 65 if (WARN_ON(crtc->primary->fb == NULL)) 66 return -EINVAL; 67 68 bochs_fb = to_bochs_framebuffer(crtc->primary->fb); 69 bo = gem_to_bochs_bo(bochs_fb->obj); 70 ret = ttm_bo_reserve(&bo->bo, true, false, false, 0); 71 if (ret) 72 return ret; 73 74 ret = bochs_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr); 75 if (ret) { 76 ttm_bo_unreserve(&bo->bo); 77 return ret; 78 } 79 80 ttm_bo_unreserve(&bo->bo); 81 bochs_hw_setbase(bochs, x, y, gpu_addr); 82 return 0; 83} 84 85static int bochs_crtc_mode_set(struct drm_crtc *crtc, 86 struct drm_display_mode *mode, 87 struct drm_display_mode *adjusted_mode, 88 int x, int y, struct drm_framebuffer *old_fb) 89{ 90 struct bochs_device *bochs = 91 container_of(crtc, struct bochs_device, crtc); 92 93 bochs_hw_setmode(bochs, mode); 94 bochs_crtc_mode_set_base(crtc, x, y, old_fb); 95 return 0; 96} 97 98static void bochs_crtc_prepare(struct drm_crtc *crtc) 99{ 100} 101 102static void bochs_crtc_commit(struct drm_crtc *crtc) 103{ 104} 105 106static void bochs_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, 107 u16 *blue, uint32_t start, uint32_t size) 108{ 109} 110 111/* These provide the minimum set of functions required to handle a CRTC */ 112static const struct drm_crtc_funcs bochs_crtc_funcs = { 113 .gamma_set = bochs_crtc_gamma_set, 114 .set_config = drm_crtc_helper_set_config, 115 .destroy = drm_crtc_cleanup, 116}; 117 118static const struct drm_crtc_helper_funcs bochs_helper_funcs = { 119 .dpms = bochs_crtc_dpms, 120 .mode_fixup = bochs_crtc_mode_fixup, 121 .mode_set = bochs_crtc_mode_set, 122 .mode_set_base = bochs_crtc_mode_set_base, 123 .prepare = bochs_crtc_prepare, 124 .commit = bochs_crtc_commit, 125 .load_lut = bochs_crtc_load_lut, 126}; 127 128static void bochs_crtc_init(struct drm_device *dev) 129{ 130 struct bochs_device *bochs = dev->dev_private; 131 struct drm_crtc *crtc = &bochs->crtc; 132 133 drm_crtc_init(dev, crtc, &bochs_crtc_funcs); 134 drm_mode_crtc_set_gamma_size(crtc, 256); 135 drm_crtc_helper_add(crtc, &bochs_helper_funcs); 136} 137 138static bool bochs_encoder_mode_fixup(struct drm_encoder *encoder, 139 const struct drm_display_mode *mode, 140 struct drm_display_mode *adjusted_mode) 141{ 142 return true; 143} 144 145static void bochs_encoder_mode_set(struct drm_encoder *encoder, 146 struct drm_display_mode *mode, 147 struct drm_display_mode *adjusted_mode) 148{ 149} 150 151static void bochs_encoder_dpms(struct drm_encoder *encoder, int state) 152{ 153} 154 155static void bochs_encoder_prepare(struct drm_encoder *encoder) 156{ 157} 158 159static void bochs_encoder_commit(struct drm_encoder *encoder) 160{ 161} 162 163static const struct drm_encoder_helper_funcs bochs_encoder_helper_funcs = { 164 .dpms = bochs_encoder_dpms, 165 .mode_fixup = bochs_encoder_mode_fixup, 166 .mode_set = bochs_encoder_mode_set, 167 .prepare = bochs_encoder_prepare, 168 .commit = bochs_encoder_commit, 169}; 170 171static const struct drm_encoder_funcs bochs_encoder_encoder_funcs = { 172 .destroy = drm_encoder_cleanup, 173}; 174 175static void bochs_encoder_init(struct drm_device *dev) 176{ 177 struct bochs_device *bochs = dev->dev_private; 178 struct drm_encoder *encoder = &bochs->encoder; 179 180 encoder->possible_crtcs = 0x1; 181 drm_encoder_init(dev, encoder, &bochs_encoder_encoder_funcs, 182 DRM_MODE_ENCODER_DAC); 183 drm_encoder_helper_add(encoder, &bochs_encoder_helper_funcs); 184} 185 186 187int bochs_connector_get_modes(struct drm_connector *connector) 188{ 189 int count; 190 191 count = drm_add_modes_noedid(connector, 8192, 8192); 192 drm_set_preferred_mode(connector, defx, defy); 193 return count; 194} 195 196static int bochs_connector_mode_valid(struct drm_connector *connector, 197 struct drm_display_mode *mode) 198{ 199 struct bochs_device *bochs = 200 container_of(connector, struct bochs_device, connector); 201 unsigned long size = mode->hdisplay * mode->vdisplay * 4; 202 203 /* 204 * Make sure we can fit two framebuffers into video memory. 205 * This allows up to 1600x1200 with 16 MB (default size). 206 * If you want more try this: 207 * 'qemu -vga std -global VGA.vgamem_mb=32 $otherargs' 208 */ 209 if (size * 2 > bochs->fb_size) 210 return MODE_BAD; 211 212 return MODE_OK; 213} 214 215static struct drm_encoder * 216bochs_connector_best_encoder(struct drm_connector *connector) 217{ 218 int enc_id = connector->encoder_ids[0]; 219 struct drm_mode_object *obj; 220 struct drm_encoder *encoder; 221 222 /* pick the encoder ids */ 223 if (enc_id) { 224 obj = drm_mode_object_find(connector->dev, enc_id, 225 DRM_MODE_OBJECT_ENCODER); 226 if (!obj) 227 return NULL; 228 encoder = obj_to_encoder(obj); 229 return encoder; 230 } 231 return NULL; 232} 233 234static enum drm_connector_status bochs_connector_detect(struct drm_connector 235 *connector, bool force) 236{ 237 return connector_status_connected; 238} 239 240struct drm_connector_helper_funcs bochs_connector_connector_helper_funcs = { 241 .get_modes = bochs_connector_get_modes, 242 .mode_valid = bochs_connector_mode_valid, 243 .best_encoder = bochs_connector_best_encoder, 244}; 245 246struct drm_connector_funcs bochs_connector_connector_funcs = { 247 .dpms = drm_helper_connector_dpms, 248 .detect = bochs_connector_detect, 249 .fill_modes = drm_helper_probe_single_connector_modes, 250 .destroy = drm_connector_cleanup, 251}; 252 253static void bochs_connector_init(struct drm_device *dev) 254{ 255 struct bochs_device *bochs = dev->dev_private; 256 struct drm_connector *connector = &bochs->connector; 257 258 drm_connector_init(dev, connector, &bochs_connector_connector_funcs, 259 DRM_MODE_CONNECTOR_VIRTUAL); 260 drm_connector_helper_add(connector, 261 &bochs_connector_connector_helper_funcs); 262} 263 264 265int bochs_kms_init(struct bochs_device *bochs) 266{ 267 drm_mode_config_init(bochs->dev); 268 bochs->mode_config_initialized = true; 269 270 bochs->dev->mode_config.max_width = 8192; 271 bochs->dev->mode_config.max_height = 8192; 272 273 bochs->dev->mode_config.fb_base = bochs->fb_base; 274 bochs->dev->mode_config.preferred_depth = 24; 275 bochs->dev->mode_config.prefer_shadow = 0; 276 277 bochs->dev->mode_config.funcs = (void *)&bochs_mode_funcs; 278 279 bochs_crtc_init(bochs->dev); 280 bochs_encoder_init(bochs->dev); 281 bochs_connector_init(bochs->dev); 282 drm_mode_connector_attach_encoder(&bochs->connector, 283 &bochs->encoder); 284 285 return 0; 286} 287 288void bochs_kms_fini(struct bochs_device *bochs) 289{ 290 if (bochs->mode_config_initialized) { 291 drm_mode_config_cleanup(bochs->dev); 292 bochs->mode_config_initialized = false; 293 } 294}