| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (C) 2012-2013 Avionic Design GmbH |
|---|
| 3 | 4 | * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved. |
|---|
| 4 | 5 | * |
|---|
| 5 | 6 | * Based on the KMS/FB CMA helpers |
|---|
| 6 | | - * Copyright (C) 2012 Analog Device Inc. |
|---|
| 7 | | - * |
|---|
| 8 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 9 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 10 | | - * published by the Free Software Foundation. |
|---|
| 7 | + * Copyright (C) 2012 Analog Devices Inc. |
|---|
| 11 | 8 | */ |
|---|
| 12 | 9 | |
|---|
| 13 | 10 | #include <linux/console.h> |
|---|
| 14 | 11 | |
|---|
| 12 | +#include <drm/drm_fourcc.h> |
|---|
| 13 | +#include <drm/drm_gem_framebuffer_helper.h> |
|---|
| 14 | +#include <drm/drm_modeset_helper.h> |
|---|
| 15 | + |
|---|
| 15 | 16 | #include "drm.h" |
|---|
| 16 | 17 | #include "gem.h" |
|---|
| 17 | | -#include <drm/drm_gem_framebuffer_helper.h> |
|---|
| 18 | 18 | |
|---|
| 19 | 19 | #ifdef CONFIG_DRM_FBDEV_EMULATION |
|---|
| 20 | 20 | static inline struct tegra_fbdev *to_tegra_fbdev(struct drm_fb_helper *helper) |
|---|
| .. | .. |
|---|
| 130 | 130 | struct drm_file *file, |
|---|
| 131 | 131 | const struct drm_mode_fb_cmd2 *cmd) |
|---|
| 132 | 132 | { |
|---|
| 133 | | - unsigned int hsub, vsub, i; |
|---|
| 133 | + const struct drm_format_info *info = drm_get_format_info(drm, cmd); |
|---|
| 134 | 134 | struct tegra_bo *planes[4]; |
|---|
| 135 | 135 | struct drm_gem_object *gem; |
|---|
| 136 | 136 | struct drm_framebuffer *fb; |
|---|
| 137 | + unsigned int i; |
|---|
| 137 | 138 | int err; |
|---|
| 138 | 139 | |
|---|
| 139 | | - hsub = drm_format_horz_chroma_subsampling(cmd->pixel_format); |
|---|
| 140 | | - vsub = drm_format_vert_chroma_subsampling(cmd->pixel_format); |
|---|
| 141 | | - |
|---|
| 142 | | - for (i = 0; i < drm_format_num_planes(cmd->pixel_format); i++) { |
|---|
| 143 | | - unsigned int width = cmd->width / (i ? hsub : 1); |
|---|
| 144 | | - unsigned int height = cmd->height / (i ? vsub : 1); |
|---|
| 140 | + for (i = 0; i < info->num_planes; i++) { |
|---|
| 141 | + unsigned int width = cmd->width / (i ? info->hsub : 1); |
|---|
| 142 | + unsigned int height = cmd->height / (i ? info->vsub : 1); |
|---|
| 145 | 143 | unsigned int size, bpp; |
|---|
| 146 | 144 | |
|---|
| 147 | 145 | gem = drm_gem_object_lookup(file, cmd->handles[i]); |
|---|
| .. | .. |
|---|
| 150 | 148 | goto unreference; |
|---|
| 151 | 149 | } |
|---|
| 152 | 150 | |
|---|
| 153 | | - bpp = drm_format_plane_cpp(cmd->pixel_format, i); |
|---|
| 151 | + bpp = info->cpp[i]; |
|---|
| 154 | 152 | |
|---|
| 155 | 153 | size = (height - 1) * cmd->pitches[i] + |
|---|
| 156 | 154 | width * bpp + cmd->offsets[i]; |
|---|
| .. | .. |
|---|
| 173 | 171 | |
|---|
| 174 | 172 | unreference: |
|---|
| 175 | 173 | while (i--) |
|---|
| 176 | | - drm_gem_object_put_unlocked(&planes[i]->gem); |
|---|
| 174 | + drm_gem_object_put(&planes[i]->gem); |
|---|
| 177 | 175 | |
|---|
| 178 | 176 | return ERR_PTR(err); |
|---|
| 179 | 177 | } |
|---|
| .. | .. |
|---|
| 194 | 192 | return __tegra_gem_mmap(&bo->gem, vma); |
|---|
| 195 | 193 | } |
|---|
| 196 | 194 | |
|---|
| 197 | | -static struct fb_ops tegra_fb_ops = { |
|---|
| 195 | +static const struct fb_ops tegra_fb_ops = { |
|---|
| 198 | 196 | .owner = THIS_MODULE, |
|---|
| 199 | 197 | DRM_FB_HELPER_DEFAULT_OPS, |
|---|
| 200 | 198 | .fb_fillrect = drm_fb_helper_sys_fillrect, |
|---|
| .. | .. |
|---|
| 237 | 235 | info = drm_fb_helper_alloc_fbi(helper); |
|---|
| 238 | 236 | if (IS_ERR(info)) { |
|---|
| 239 | 237 | dev_err(drm->dev, "failed to allocate framebuffer info\n"); |
|---|
| 240 | | - drm_gem_object_put_unlocked(&bo->gem); |
|---|
| 238 | + drm_gem_object_put(&bo->gem); |
|---|
| 241 | 239 | return PTR_ERR(info); |
|---|
| 242 | 240 | } |
|---|
| 243 | 241 | |
|---|
| .. | .. |
|---|
| 246 | 244 | err = PTR_ERR(fbdev->fb); |
|---|
| 247 | 245 | dev_err(drm->dev, "failed to allocate DRM framebuffer: %d\n", |
|---|
| 248 | 246 | err); |
|---|
| 249 | | - drm_gem_object_put_unlocked(&bo->gem); |
|---|
| 247 | + drm_gem_object_put(&bo->gem); |
|---|
| 250 | 248 | return PTR_ERR(fbdev->fb); |
|---|
| 251 | 249 | } |
|---|
| 252 | 250 | |
|---|
| .. | .. |
|---|
| 254 | 252 | helper->fb = fb; |
|---|
| 255 | 253 | helper->fbdev = info; |
|---|
| 256 | 254 | |
|---|
| 257 | | - info->par = helper; |
|---|
| 258 | | - info->flags = FBINFO_FLAG_DEFAULT; |
|---|
| 259 | 255 | info->fbops = &tegra_fb_ops; |
|---|
| 260 | 256 | |
|---|
| 261 | | - drm_fb_helper_fill_fix(info, fb->pitches[0], fb->format->depth); |
|---|
| 262 | | - drm_fb_helper_fill_var(info, helper, fb->width, fb->height); |
|---|
| 257 | + drm_fb_helper_fill_info(info, helper, sizes); |
|---|
| 263 | 258 | |
|---|
| 264 | 259 | offset = info->var.xoffset * bytes_per_pixel + |
|---|
| 265 | 260 | info->var.yoffset * fb->pitches[0]; |
|---|
| .. | .. |
|---|
| 274 | 269 | } |
|---|
| 275 | 270 | } |
|---|
| 276 | 271 | |
|---|
| 277 | | - drm->mode_config.fb_base = (resource_size_t)bo->paddr; |
|---|
| 272 | + drm->mode_config.fb_base = (resource_size_t)bo->iova; |
|---|
| 278 | 273 | info->screen_base = (void __iomem *)bo->vaddr + offset; |
|---|
| 279 | 274 | info->screen_size = size; |
|---|
| 280 | | - info->fix.smem_start = (unsigned long)(bo->paddr + offset); |
|---|
| 275 | + info->fix.smem_start = (unsigned long)(bo->iova + offset); |
|---|
| 281 | 276 | info->fix.smem_len = size; |
|---|
| 282 | 277 | |
|---|
| 283 | 278 | return 0; |
|---|
| .. | .. |
|---|
| 319 | 314 | struct drm_device *drm = fbdev->base.dev; |
|---|
| 320 | 315 | int err; |
|---|
| 321 | 316 | |
|---|
| 322 | | - err = drm_fb_helper_init(drm, &fbdev->base, max_connectors); |
|---|
| 317 | + err = drm_fb_helper_init(drm, &fbdev->base); |
|---|
| 323 | 318 | if (err < 0) { |
|---|
| 324 | 319 | dev_err(drm->dev, "failed to initialize DRM FB helper: %d\n", |
|---|
| 325 | 320 | err); |
|---|
| 326 | 321 | return err; |
|---|
| 327 | | - } |
|---|
| 328 | | - |
|---|
| 329 | | - err = drm_fb_helper_single_add_all_connectors(&fbdev->base); |
|---|
| 330 | | - if (err < 0) { |
|---|
| 331 | | - dev_err(drm->dev, "failed to add connectors: %d\n", err); |
|---|
| 332 | | - goto fini; |
|---|
| 333 | 322 | } |
|---|
| 334 | 323 | |
|---|
| 335 | 324 | err = drm_fb_helper_initial_config(&fbdev->base, preferred_bpp); |
|---|
| .. | .. |
|---|
| 356 | 345 | /* Undo the special mapping we made in fbdev probe. */ |
|---|
| 357 | 346 | if (bo && bo->pages) { |
|---|
| 358 | 347 | vunmap(bo->vaddr); |
|---|
| 359 | | - bo->vaddr = 0; |
|---|
| 348 | + bo->vaddr = NULL; |
|---|
| 360 | 349 | } |
|---|
| 361 | 350 | |
|---|
| 362 | 351 | drm_framebuffer_remove(fbdev->fb); |
|---|
| .. | .. |
|---|
| 410 | 399 | struct tegra_drm *tegra = drm->dev_private; |
|---|
| 411 | 400 | |
|---|
| 412 | 401 | tegra_fbdev_exit(tegra->fbdev); |
|---|
| 413 | | -#endif |
|---|
| 414 | | -} |
|---|
| 415 | | - |
|---|
| 416 | | -void tegra_drm_fb_suspend(struct drm_device *drm) |
|---|
| 417 | | -{ |
|---|
| 418 | | -#ifdef CONFIG_DRM_FBDEV_EMULATION |
|---|
| 419 | | - struct tegra_drm *tegra = drm->dev_private; |
|---|
| 420 | | - |
|---|
| 421 | | - console_lock(); |
|---|
| 422 | | - drm_fb_helper_set_suspend(&tegra->fbdev->base, 1); |
|---|
| 423 | | - console_unlock(); |
|---|
| 424 | | -#endif |
|---|
| 425 | | -} |
|---|
| 426 | | - |
|---|
| 427 | | -void tegra_drm_fb_resume(struct drm_device *drm) |
|---|
| 428 | | -{ |
|---|
| 429 | | -#ifdef CONFIG_DRM_FBDEV_EMULATION |
|---|
| 430 | | - struct tegra_drm *tegra = drm->dev_private; |
|---|
| 431 | | - |
|---|
| 432 | | - console_lock(); |
|---|
| 433 | | - drm_fb_helper_set_suspend(&tegra->fbdev->base, 0); |
|---|
| 434 | | - console_unlock(); |
|---|
| 435 | 402 | #endif |
|---|
| 436 | 403 | } |
|---|