1 // SPDX-License-Identifier: GPL-2.0-only 2 /************************************************************************** 3 * Copyright (c) 2007-2011, Intel Corporation. 4 * All Rights Reserved. 5 * 6 **************************************************************************/ 7 8 #include <linux/console.h> 9 #include <linux/delay.h> 10 #include <linux/errno.h> 11 #include <linux/init.h> 12 #include <linux/kernel.h> 13 #include <linux/mm.h> 14 #include <linux/module.h> 15 #include <linux/pfn_t.h> 16 #include <linux/slab.h> 17 #include <linux/string.h> 18 #include <linux/tty.h> 19 20 #include <drm/drm.h> 21 #include <drm/drm_crtc.h> 22 #include <drm/drm_fb_helper.h> 23 #include <drm/drm_fourcc.h> 24 #include <drm/drm_framebuffer.h> 25 #include <drm/drm_gem_framebuffer_helper.h> 26 27 #include "framebuffer.h" 28 #include "gem.h" 29 #include "psb_drv.h" 30 #include "psb_intel_drv.h" 31 #include "psb_intel_reg.h" 32 33 static const struct drm_framebuffer_funcs psb_fb_funcs = { 34 .destroy = drm_gem_fb_destroy, 35 .create_handle = drm_gem_fb_create_handle, 36 }; 37 38 #define CMAP_TOHW(_val, _width) ((((_val) << (_width)) + 0x7FFF - (_val)) >> 16) 39 40 static int psbfb_setcolreg(unsigned regno, unsigned red, unsigned green, 41 unsigned blue, unsigned transp, 42 struct fb_info *info) 43 { 44 struct drm_fb_helper *fb_helper = info->par; 45 struct drm_framebuffer *fb = fb_helper->fb; 46 uint32_t v; 47 48 if (!fb) 49 return -ENOMEM; 50 51 if (regno > 255) 52 return 1; 53 54 red = CMAP_TOHW(red, info->var.red.length); 55 blue = CMAP_TOHW(blue, info->var.blue.length); 56 green = CMAP_TOHW(green, info->var.green.length); 57 transp = CMAP_TOHW(transp, info->var.transp.length); 58 59 v = (red << info->var.red.offset) | 60 (green << info->var.green.offset) | 61 (blue << info->var.blue.offset) | 62 (transp << info->var.transp.offset); 63 64 if (regno < 16) { 65 switch (fb->format->cpp[0] * 8) { 66 case 16: 67 ((uint32_t *) info->pseudo_palette)[regno] = v; 68 break; 69 case 24: 70 case 32: 71 ((uint32_t *) info->pseudo_palette)[regno] = v; 72 break; 73 } 74 } 75 76 return 0; 77 } 78 79 static vm_fault_t psbfb_vm_fault(struct vm_fault *vmf) 80 { 81 struct vm_area_struct *vma = vmf->vma; 82 struct drm_framebuffer *fb = vma->vm_private_data; 83 struct drm_device *dev = fb->dev; 84 struct drm_psb_private *dev_priv = to_drm_psb_private(dev); 85 struct psb_gem_object *pobj = to_psb_gem_object(fb->obj[0]); 86 int page_num; 87 int i; 88 unsigned long address; 89 vm_fault_t ret = VM_FAULT_SIGBUS; 90 unsigned long pfn; 91 unsigned long phys_addr = (unsigned long)dev_priv->stolen_base + pobj->offset; 92 93 page_num = vma_pages(vma); 94 address = vmf->address - (vmf->pgoff << PAGE_SHIFT); 95 96 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 97 98 for (i = 0; i < page_num; i++) { 99 pfn = (phys_addr >> PAGE_SHIFT); 100 101 ret = vmf_insert_mixed(vma, address, 102 __pfn_to_pfn_t(pfn, PFN_DEV)); 103 if (unlikely(ret & VM_FAULT_ERROR)) 104 break; 105 address += PAGE_SIZE; 106 phys_addr += PAGE_SIZE; 107 } 108 return ret; 109 } 110 111 static void psbfb_vm_open(struct vm_area_struct *vma) 112 { 113 } 114 115 static void psbfb_vm_close(struct vm_area_struct *vma) 116 { 117 } 118 119 static const struct vm_operations_struct psbfb_vm_ops = { 120 .fault = psbfb_vm_fault, 121 .open = psbfb_vm_open, 122 .close = psbfb_vm_close 123 }; 124 125 static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma) 126 { 127 struct drm_fb_helper *fb_helper = info->par; 128 struct drm_framebuffer *fb = fb_helper->fb; 129 130 if (vma->vm_pgoff != 0) 131 return -EINVAL; 132 if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) 133 return -EINVAL; 134 135 /* 136 * If this is a GEM object then info->screen_base is the virtual 137 * kernel remapping of the object. FIXME: Review if this is 138 * suitable for our mmap work 139 */ 140 vma->vm_ops = &psbfb_vm_ops; 141 vma->vm_private_data = (void *)fb; 142 vma->vm_flags |= VM_IO | VM_MIXEDMAP | VM_DONTEXPAND | VM_DONTDUMP; 143 return 0; 144 } 145 146 static const struct fb_ops psbfb_unaccel_ops = { 147 .owner = THIS_MODULE, 148 DRM_FB_HELPER_DEFAULT_OPS, 149 .fb_setcolreg = psbfb_setcolreg, 150 .fb_read = drm_fb_helper_cfb_read, 151 .fb_write = drm_fb_helper_cfb_write, 152 .fb_fillrect = drm_fb_helper_cfb_fillrect, 153 .fb_copyarea = drm_fb_helper_cfb_copyarea, 154 .fb_imageblit = drm_fb_helper_cfb_imageblit, 155 .fb_mmap = psbfb_mmap, 156 }; 157 158 /** 159 * psb_framebuffer_init - initialize a framebuffer 160 * @dev: our DRM device 161 * @fb: framebuffer to set up 162 * @mode_cmd: mode description 163 * @obj: backing object 164 * 165 * Configure and fill in the boilerplate for our frame buffer. Return 166 * 0 on success or an error code if we fail. 167 */ 168 static int psb_framebuffer_init(struct drm_device *dev, 169 struct drm_framebuffer *fb, 170 const struct drm_mode_fb_cmd2 *mode_cmd, 171 struct drm_gem_object *obj) 172 { 173 const struct drm_format_info *info; 174 int ret; 175 176 /* 177 * Reject unknown formats, YUV formats, and formats with more than 178 * 4 bytes per pixel. 179 */ 180 info = drm_get_format_info(dev, mode_cmd); 181 if (!info || !info->depth || info->cpp[0] > 4) 182 return -EINVAL; 183 184 if (mode_cmd->pitches[0] & 63) 185 return -EINVAL; 186 187 drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd); 188 fb->obj[0] = obj; 189 ret = drm_framebuffer_init(dev, fb, &psb_fb_funcs); 190 if (ret) { 191 dev_err(dev->dev, "framebuffer init failed: %d\n", ret); 192 return ret; 193 } 194 return 0; 195 } 196 197 /** 198 * psb_framebuffer_create - create a framebuffer backed by gt 199 * @dev: our DRM device 200 * @mode_cmd: the description of the requested mode 201 * @obj: the backing object 202 * 203 * Create a framebuffer object backed by the gt, and fill in the 204 * boilerplate required 205 * 206 * TODO: review object references 207 */ 208 209 static struct drm_framebuffer *psb_framebuffer_create 210 (struct drm_device *dev, 211 const struct drm_mode_fb_cmd2 *mode_cmd, 212 struct drm_gem_object *obj) 213 { 214 struct drm_framebuffer *fb; 215 int ret; 216 217 fb = kzalloc(sizeof(*fb), GFP_KERNEL); 218 if (!fb) 219 return ERR_PTR(-ENOMEM); 220 221 ret = psb_framebuffer_init(dev, fb, mode_cmd, obj); 222 if (ret) { 223 kfree(fb); 224 return ERR_PTR(ret); 225 } 226 return fb; 227 } 228 229 /** 230 * psbfb_create - create a framebuffer 231 * @fb_helper: the framebuffer helper 232 * @sizes: specification of the layout 233 * 234 * Create a framebuffer to the specifications provided 235 */ 236 static int psbfb_create(struct drm_fb_helper *fb_helper, 237 struct drm_fb_helper_surface_size *sizes) 238 { 239 struct drm_device *dev = fb_helper->dev; 240 struct drm_psb_private *dev_priv = to_drm_psb_private(dev); 241 struct pci_dev *pdev = to_pci_dev(dev->dev); 242 struct fb_info *info; 243 struct drm_framebuffer *fb; 244 struct drm_mode_fb_cmd2 mode_cmd; 245 int size; 246 int ret; 247 struct psb_gem_object *backing; 248 struct drm_gem_object *obj; 249 u32 bpp, depth; 250 251 mode_cmd.width = sizes->surface_width; 252 mode_cmd.height = sizes->surface_height; 253 bpp = sizes->surface_bpp; 254 depth = sizes->surface_depth; 255 256 /* No 24bit packed */ 257 if (bpp == 24) 258 bpp = 32; 259 260 mode_cmd.pitches[0] = ALIGN(mode_cmd.width * DIV_ROUND_UP(bpp, 8), 64); 261 262 size = mode_cmd.pitches[0] * mode_cmd.height; 263 size = ALIGN(size, PAGE_SIZE); 264 265 /* Allocate the framebuffer in the GTT with stolen page backing */ 266 backing = psb_gem_create(dev, size, "fb", true, PAGE_SIZE); 267 if (IS_ERR(backing)) 268 return PTR_ERR(backing); 269 obj = &backing->base; 270 271 memset(dev_priv->vram_addr + backing->offset, 0, size); 272 273 info = drm_fb_helper_alloc_info(fb_helper); 274 if (IS_ERR(info)) { 275 ret = PTR_ERR(info); 276 goto err_drm_gem_object_put; 277 } 278 279 mode_cmd.pixel_format = drm_mode_legacy_fb_format(bpp, depth); 280 281 fb = psb_framebuffer_create(dev, &mode_cmd, obj); 282 if (IS_ERR(fb)) { 283 ret = PTR_ERR(fb); 284 goto err_drm_gem_object_put; 285 } 286 287 fb_helper->fb = fb; 288 289 info->fbops = &psbfb_unaccel_ops; 290 291 info->fix.smem_start = dev_priv->fb_base; 292 info->fix.smem_len = size; 293 info->fix.ywrapstep = 0; 294 info->fix.ypanstep = 0; 295 296 /* Accessed stolen memory directly */ 297 info->screen_base = dev_priv->vram_addr + backing->offset; 298 info->screen_size = size; 299 300 if (dev_priv->gtt.stolen_size) { 301 info->apertures->ranges[0].base = dev_priv->fb_base; 302 info->apertures->ranges[0].size = dev_priv->gtt.stolen_size; 303 } 304 305 drm_fb_helper_fill_info(info, fb_helper, sizes); 306 307 info->fix.mmio_start = pci_resource_start(pdev, 0); 308 info->fix.mmio_len = pci_resource_len(pdev, 0); 309 310 /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */ 311 312 dev_dbg(dev->dev, "allocated %dx%d fb\n", fb->width, fb->height); 313 314 return 0; 315 316 err_drm_gem_object_put: 317 drm_gem_object_put(obj); 318 return ret; 319 } 320 321 /** 322 * psb_user_framebuffer_create - create framebuffer 323 * @dev: our DRM device 324 * @filp: client file 325 * @cmd: mode request 326 * 327 * Create a new framebuffer backed by a userspace GEM object 328 */ 329 static struct drm_framebuffer *psb_user_framebuffer_create 330 (struct drm_device *dev, struct drm_file *filp, 331 const struct drm_mode_fb_cmd2 *cmd) 332 { 333 struct drm_gem_object *obj; 334 struct drm_framebuffer *fb; 335 336 /* 337 * Find the GEM object and thus the gtt range object that is 338 * to back this space 339 */ 340 obj = drm_gem_object_lookup(filp, cmd->handles[0]); 341 if (obj == NULL) 342 return ERR_PTR(-ENOENT); 343 344 /* Let the core code do all the work */ 345 fb = psb_framebuffer_create(dev, cmd, obj); 346 if (IS_ERR(fb)) 347 drm_gem_object_put(obj); 348 349 return fb; 350 } 351 352 static int psbfb_probe(struct drm_fb_helper *fb_helper, 353 struct drm_fb_helper_surface_size *sizes) 354 { 355 struct drm_device *dev = fb_helper->dev; 356 struct drm_psb_private *dev_priv = to_drm_psb_private(dev); 357 unsigned int fb_size; 358 int bytespp; 359 360 bytespp = sizes->surface_bpp / 8; 361 if (bytespp == 3) /* no 24bit packed */ 362 bytespp = 4; 363 364 /* If the mode will not fit in 32bit then switch to 16bit to get 365 a console on full resolution. The X mode setting server will 366 allocate its own 32bit GEM framebuffer */ 367 fb_size = ALIGN(sizes->surface_width * bytespp, 64) * 368 sizes->surface_height; 369 fb_size = ALIGN(fb_size, PAGE_SIZE); 370 371 if (fb_size > dev_priv->vram_stolen_size) { 372 sizes->surface_bpp = 16; 373 sizes->surface_depth = 16; 374 } 375 376 return psbfb_create(fb_helper, sizes); 377 } 378 379 static const struct drm_fb_helper_funcs psb_fb_helper_funcs = { 380 .fb_probe = psbfb_probe, 381 }; 382 383 static int psb_fbdev_destroy(struct drm_device *dev, 384 struct drm_fb_helper *fb_helper) 385 { 386 struct drm_framebuffer *fb = fb_helper->fb; 387 388 drm_fb_helper_unregister_info(fb_helper); 389 390 drm_fb_helper_fini(fb_helper); 391 drm_framebuffer_unregister_private(fb); 392 drm_framebuffer_cleanup(fb); 393 394 if (fb->obj[0]) 395 drm_gem_object_put(fb->obj[0]); 396 kfree(fb); 397 398 return 0; 399 } 400 401 int psb_fbdev_init(struct drm_device *dev) 402 { 403 struct drm_fb_helper *fb_helper; 404 struct drm_psb_private *dev_priv = to_drm_psb_private(dev); 405 int ret; 406 407 fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL); 408 if (!fb_helper) { 409 dev_err(dev->dev, "no memory\n"); 410 return -ENOMEM; 411 } 412 413 dev_priv->fb_helper = fb_helper; 414 415 drm_fb_helper_prepare(dev, fb_helper, &psb_fb_helper_funcs); 416 417 ret = drm_fb_helper_init(dev, fb_helper); 418 if (ret) 419 goto free; 420 421 /* disable all the possible outputs/crtcs before entering KMS mode */ 422 drm_helper_disable_unused_functions(dev); 423 424 ret = drm_fb_helper_initial_config(fb_helper, 32); 425 if (ret) 426 goto fini; 427 428 return 0; 429 430 fini: 431 drm_fb_helper_fini(fb_helper); 432 free: 433 kfree(fb_helper); 434 return ret; 435 } 436 437 static void psb_fbdev_fini(struct drm_device *dev) 438 { 439 struct drm_psb_private *dev_priv = to_drm_psb_private(dev); 440 441 if (!dev_priv->fb_helper) 442 return; 443 444 psb_fbdev_destroy(dev, dev_priv->fb_helper); 445 kfree(dev_priv->fb_helper); 446 dev_priv->fb_helper = NULL; 447 } 448 449 static const struct drm_mode_config_funcs psb_mode_funcs = { 450 .fb_create = psb_user_framebuffer_create, 451 .output_poll_changed = drm_fb_helper_output_poll_changed, 452 }; 453 454 static void psb_setup_outputs(struct drm_device *dev) 455 { 456 struct drm_psb_private *dev_priv = to_drm_psb_private(dev); 457 struct drm_connector_list_iter conn_iter; 458 struct drm_connector *connector; 459 460 drm_mode_create_scaling_mode_property(dev); 461 462 /* It is ok for this to fail - we just don't get backlight control */ 463 if (!dev_priv->backlight_property) 464 dev_priv->backlight_property = drm_property_create_range(dev, 0, 465 "backlight", 0, 100); 466 dev_priv->ops->output_init(dev); 467 468 drm_connector_list_iter_begin(dev, &conn_iter); 469 drm_for_each_connector_iter(connector, &conn_iter) { 470 struct gma_encoder *gma_encoder = gma_attached_encoder(connector); 471 struct drm_encoder *encoder = &gma_encoder->base; 472 int crtc_mask = 0, clone_mask = 0; 473 474 /* valid crtcs */ 475 switch (gma_encoder->type) { 476 case INTEL_OUTPUT_ANALOG: 477 crtc_mask = (1 << 0); 478 clone_mask = (1 << INTEL_OUTPUT_ANALOG); 479 break; 480 case INTEL_OUTPUT_SDVO: 481 crtc_mask = dev_priv->ops->sdvo_mask; 482 clone_mask = 0; 483 break; 484 case INTEL_OUTPUT_LVDS: 485 crtc_mask = dev_priv->ops->lvds_mask; 486 clone_mask = 0; 487 break; 488 case INTEL_OUTPUT_MIPI: 489 crtc_mask = (1 << 0); 490 clone_mask = 0; 491 break; 492 case INTEL_OUTPUT_MIPI2: 493 crtc_mask = (1 << 2); 494 clone_mask = 0; 495 break; 496 case INTEL_OUTPUT_HDMI: 497 crtc_mask = dev_priv->ops->hdmi_mask; 498 clone_mask = (1 << INTEL_OUTPUT_HDMI); 499 break; 500 case INTEL_OUTPUT_DISPLAYPORT: 501 crtc_mask = (1 << 0) | (1 << 1); 502 clone_mask = 0; 503 break; 504 case INTEL_OUTPUT_EDP: 505 crtc_mask = (1 << 1); 506 clone_mask = 0; 507 } 508 encoder->possible_crtcs = crtc_mask; 509 encoder->possible_clones = 510 gma_connector_clones(dev, clone_mask); 511 } 512 drm_connector_list_iter_end(&conn_iter); 513 } 514 515 void psb_modeset_init(struct drm_device *dev) 516 { 517 struct drm_psb_private *dev_priv = to_drm_psb_private(dev); 518 struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev; 519 struct pci_dev *pdev = to_pci_dev(dev->dev); 520 int i; 521 522 if (drmm_mode_config_init(dev)) 523 return; 524 525 dev->mode_config.min_width = 0; 526 dev->mode_config.min_height = 0; 527 528 dev->mode_config.funcs = &psb_mode_funcs; 529 530 /* set memory base */ 531 /* Oaktrail and Poulsbo should use BAR 2*/ 532 pci_read_config_dword(pdev, PSB_BSM, (u32 *)&(dev_priv->fb_base)); 533 534 /* num pipes is 2 for PSB but 1 for Mrst */ 535 for (i = 0; i < dev_priv->num_pipe; i++) 536 psb_intel_crtc_init(dev, i, mode_dev); 537 538 dev->mode_config.max_width = 4096; 539 dev->mode_config.max_height = 4096; 540 541 psb_setup_outputs(dev); 542 543 if (dev_priv->ops->errata) 544 dev_priv->ops->errata(dev); 545 546 dev_priv->modeset = true; 547 } 548 549 void psb_modeset_cleanup(struct drm_device *dev) 550 { 551 struct drm_psb_private *dev_priv = to_drm_psb_private(dev); 552 if (dev_priv->modeset) { 553 drm_kms_helper_poll_fini(dev); 554 psb_fbdev_fini(dev); 555 } 556 } 557