-
Notifications
You must be signed in to change notification settings - Fork 51
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
drm/mediatek: Add MTK Framebuffer-Device (mt7623)
This patch adds Framebuffer-Driver for Mediatek currently tested on mt7623, maybe works on other platforms MTK-FBDev written by CK Hu and ported from 4.4 based on patchset drm/hdmi for 7623 v5 (except last part included in 4.20) https://patchwork.kernel.org/project/linux-mediatek/list/?series=25989 depends on dts-patch (resend of 5/5, parts 1-4 already in 4.20): "arm: dts: mt7623: add display subsystem related device nodes" https://patchwork.kernel.org/patch/10588951/ 2 bugfix-patches from bibby hsieh fix-boot-up-for-720-and-480-but-1080 using-different-round-rate-for-mt7623 1 Patch from Ryder Lee http://forum.banana-pi.org/t/kernel-4-19-rc1-for-testers/6618/52 full working tree here for reference: https://github.com/frank-w/BPI-R2-4.14/commits/4.20-hdmiv5 v2: [fbdev] fix problems mentioned by CK Hu Signed-off-by: CK Hu <[email protected]> Signed-off-by: Alexander Ryabchenko <[email protected]> Signed-off-by: Frank Wunderlich <[email protected]> Tested-by: Frank Wunderlich <[email protected]>
- Loading branch information
1 parent
88aa4bf
commit 4bda848
Showing
7 changed files
with
216 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* | ||
* Copyright (c) 2018 MediaTek Inc. | ||
* Author: CK Hu <[email protected]> | ||
*/ | ||
|
||
#include <drm/drmP.h> | ||
#include <drm/drm_crtc_helper.h> | ||
#include <drm/drm_fb_helper.h> | ||
#include <drm/drm_gem.h> | ||
|
||
#include "mtk_drm_drv.h" | ||
#include "mtk_drm_fb.h" | ||
#include "mtk_drm_fbdev.h" | ||
#include "mtk_drm_gem.h" | ||
|
||
#define to_drm_private(x) \ | ||
container_of(x, struct mtk_drm_private, fb_helper) | ||
|
||
static int mtk_drm_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma) | ||
{ | ||
struct drm_fb_helper *helper = info->par; | ||
struct mtk_drm_private *private = to_drm_private(helper); | ||
|
||
return mtk_drm_gem_mmap_buf(private->fbdev_bo, vma); | ||
} | ||
|
||
static struct fb_ops mtk_fbdev_ops = { | ||
.owner = THIS_MODULE, | ||
DRM_FB_HELPER_DEFAULT_OPS, | ||
.fb_fillrect = drm_fb_helper_cfb_fillrect, | ||
.fb_copyarea = drm_fb_helper_cfb_copyarea, | ||
.fb_imageblit = drm_fb_helper_cfb_imageblit, | ||
.fb_pan_display = drm_fb_helper_pan_display, | ||
.fb_mmap = mtk_drm_fbdev_mmap, | ||
}; | ||
|
||
static int mtk_fbdev_probe(struct drm_fb_helper *helper, | ||
struct drm_fb_helper_surface_size *sizes) | ||
{ | ||
struct drm_device *dev = helper->dev; | ||
struct mtk_drm_private *private = to_drm_private(helper); | ||
struct drm_mode_fb_cmd2 mode = { 0 }; | ||
struct mtk_drm_gem_obj *mtk_gem; | ||
struct fb_info *info; | ||
struct drm_framebuffer *fb; | ||
unsigned int bytes_per_pixel; | ||
unsigned long offset; | ||
size_t size; | ||
int err; | ||
|
||
bytes_per_pixel = DIV_ROUND_UP(sizes->surface_bpp, 8); | ||
|
||
mode.width = sizes->surface_width; | ||
mode.height = sizes->surface_height; | ||
mode.pitches[0] = sizes->surface_width * bytes_per_pixel; | ||
mode.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, | ||
sizes->surface_depth); | ||
|
||
size = mode.pitches[0] * mode.height; | ||
|
||
mtk_gem = mtk_drm_gem_create(dev, size, true); | ||
if (IS_ERR(mtk_gem)) | ||
return PTR_ERR(mtk_gem); | ||
|
||
private->fbdev_bo = &mtk_gem->base; | ||
|
||
info = drm_fb_helper_alloc_fbi(helper); | ||
if (IS_ERR(info)) { | ||
err = PTR_ERR(info); | ||
DRM_DEV_ERROR(dev->dev, | ||
"failed to allocate framebuffer info, %d\n", | ||
err); | ||
goto err_gem_free_object; | ||
} | ||
|
||
fb = mtk_drm_framebuffer_init(dev, &mode, private->fbdev_bo); | ||
if (IS_ERR(fb)) { | ||
err = PTR_ERR(fb); | ||
DRM_DEV_ERROR(dev->dev, | ||
"failed to allocate DRM framebuffer, %d\n", | ||
err); | ||
goto err_gem_release_info; | ||
} | ||
helper->fb = fb; | ||
|
||
info->par = helper; | ||
info->flags = FBINFO_FLAG_DEFAULT; | ||
info->fbops = &mtk_fbdev_ops; | ||
|
||
drm_fb_helper_fill_fix(info, fb->pitches[0], fb->format->depth); | ||
drm_fb_helper_fill_var(info, helper, sizes->fb_width, sizes->fb_height); | ||
|
||
offset = info->var.xoffset * bytes_per_pixel; | ||
offset += info->var.yoffset * fb->pitches[0]; | ||
|
||
dev->mode_config.fb_base = 0; | ||
info->screen_base = mtk_gem->kvaddr + offset; | ||
info->screen_size = size; | ||
info->fix.smem_len = size; | ||
|
||
DRM_DEBUG_KMS("FB [%ux%u]-%u offset=%lu size=%zd\n", | ||
fb->width, fb->height, fb->format->depth, offset, size); | ||
|
||
info->skip_vt_switch = true; | ||
|
||
return 0; | ||
|
||
err_gem_release_info: | ||
|
||
drm_fb_helper_unregister_fbi(helper); | ||
|
||
err_gem_free_object: | ||
|
||
mtk_drm_gem_free_object(&mtk_gem->base); | ||
return err; | ||
} | ||
|
||
static const struct drm_fb_helper_funcs mtk_drm_fb_helper_funcs = { | ||
.fb_probe = mtk_fbdev_probe, | ||
}; | ||
|
||
int mtk_fbdev_init(struct drm_device *dev) | ||
{ | ||
struct mtk_drm_private *priv = dev->dev_private; | ||
struct drm_fb_helper *helper = &priv->fb_helper; | ||
int ret; | ||
|
||
if (!dev->mode_config.num_crtc || !dev->mode_config.num_connector) | ||
return -EINVAL; | ||
|
||
drm_fb_helper_prepare(dev, helper, &mtk_drm_fb_helper_funcs); | ||
|
||
ret = drm_fb_helper_init(dev, helper, dev->mode_config.num_connector); | ||
if (ret < 0) { | ||
DRM_DEV_ERROR(dev->dev, | ||
"failed to initialize DRM FB helper, %d\n", | ||
ret); | ||
return ret; | ||
} | ||
|
||
ret = drm_fb_helper_single_add_all_connectors(helper); | ||
if (ret < 0) { | ||
DRM_DEV_ERROR(dev->dev, "failed to add connectors, %d\n", ret); | ||
goto err_fini; | ||
} | ||
|
||
ret = drm_fb_helper_initial_config(helper, 32); | ||
if (ret < 0) { | ||
DRM_DEV_ERROR(dev->dev, | ||
"failed to set initial configuration, %d\n", | ||
ret); | ||
goto err_fini; | ||
} | ||
|
||
return 0; | ||
|
||
err_fini: | ||
drm_fb_helper_fini(helper); | ||
return ret; | ||
} | ||
|
||
void mtk_fbdev_fini(struct drm_device *dev) | ||
{ | ||
struct mtk_drm_private *priv = dev->dev_private; | ||
struct drm_fb_helper *helper = &priv->fb_helper; | ||
|
||
drm_fb_helper_unregister_fbi(helper); | ||
|
||
if (helper->fb) { | ||
drm_framebuffer_unregister_private(helper->fb); | ||
drm_framebuffer_remove(helper->fb); | ||
} | ||
|
||
drm_fb_helper_fini(helper); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
/* | ||
* Copyright (c) 2018 MediaTek Inc. | ||
* Author: CK Hu <[email protected]> | ||
*/ | ||
|
||
#ifndef MTK_DRM_FBDEV_H | ||
#define MTK_DRM_FBDEV_H | ||
|
||
#ifdef CONFIG_DRM_FBDEV_EMULATION | ||
int mtk_fbdev_init(struct drm_device *dev); | ||
void mtk_fbdev_fini(struct drm_device *dev); | ||
#else | ||
int mtk_fbdev_init(struct drm_device *dev) | ||
{ | ||
return 0; | ||
} | ||
|
||
void mtk_fbdev_fini(struct drm_device *dev) | ||
{ | ||
|
||
} | ||
#endif /* CONFIG_DRM_FBDEV_EMULATION */ | ||
|
||
#endif /* MTK_DRM_FBDEV_H */ |