From patchwork Sun May 29 09:40:50 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rongrong Zou X-Patchwork-Id: 9139723 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id D848D60221 for ; Sun, 29 May 2016 09:44:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CB8F11FF27 for ; Sun, 29 May 2016 09:44:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C01F6279E2; Sun, 29 May 2016 09:44:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,FREEMAIL_FROM,RCVD_IN_DNSWL_MED,T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 3780E1FF27 for ; Sun, 29 May 2016 09:44:58 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1b6xFy-0006BM-J6; Sun, 29 May 2016 09:43:38 +0000 Received: from mail-yw0-x244.google.com ([2607:f8b0:4002:c05::244]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1b6xFp-00060g-Uf for linux-arm-kernel@lists.infradead.org; Sun, 29 May 2016 09:43:32 +0000 Received: by mail-yw0-x244.google.com with SMTP id y6so11612363ywe.0 for ; Sun, 29 May 2016 02:43:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=VSEPWwdpoLabypVrP1qib4/xDZ1R7nmggSSIh9bq01A=; b=faj/u+jv2t8P0eFvGJ1jRWfnNcX2hW/QehD2O8B9LYVzOdBQEYEDC8PV1NRCWRiol7 y3GCZIGkciol34+yx9TQx/0kOh95r9KBHbWC8xW3onpWkeZw/Eduf7ULgxioQi+rZXEA M+O48He7IfrBmZVFEaDk8LZ2PLn+JOHe22uuA+2Vmc3KOJjp5C0P/qlfwi45CiZj3T8m 3z8w7CU70oOhITKKdaLM5kLynE+Gu0cS5N7/1kAJuEuejDAfbvDe69s1VNmFa47Tx8l5 JqCybvzqVeleqysi2xzYCLkTpbh8Lorrl+tkPqfJdp6p+KZe1eHYtQ1zk8K8zJrDBqSs Izfg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=VSEPWwdpoLabypVrP1qib4/xDZ1R7nmggSSIh9bq01A=; b=JjakzOOTBqlyzeYwyCkOcSuFeKgXX48rdU210+H5njPaRb7RleDOOuDx5j7FTTMe2m UhRWSXW+UScym8tgtIRfVPn1cwkAl1qCtXF6LxoMqplNQHQJphL75qfhFA8+6fC6vNr5 RIHpB9NAyG8K+HzUHdlxTsWVf+WXYOjkdmKmIVdV9eR/c3dU8VxnLlyQECYF58wrCmU/ Q6Ab+CWHRqyg1tM7Nbua+RRjGBWQ27CdoEKfX+R9N8/6XfEs59DdCiBnRCb1jAtWpqd2 8rpWNtcX3BdNevZrwC9YBBHUCXn2LkBL0/N9q53XpS91XkWG3FJdEZRhs1WLEo0kJhve Wv0Q== X-Gm-Message-State: ALyK8tJ61lIsvYusEAZGdbMe2FyFJ4zm4RSv8YFyV7NxUdGrYlZYN3cfzeSiAXPEJJf4rQ== X-Received: by 10.129.79.79 with SMTP id d76mr1528867ywb.194.1464514987837; Sun, 29 May 2016 02:43:07 -0700 (PDT) Received: from localhost.localdomain ([119.145.15.121]) by smtp.gmail.com with ESMTPSA id l200sm10414744ywe.40.2016.05.29.02.42.59 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 29 May 2016 02:43:06 -0700 (PDT) From: Rongrong Zou To: zourongrong@huawei.com, airlied@linux.ie, emil.l.velikov@gmail.com, lijianhua@huawei.com, xinliang.liu@linaro.org Subject: [path v2 2/7] drm/hisilicon/hibmc: Add plane for DE Date: Sun, 29 May 2016 17:40:50 +0800 Message-Id: <1464514855-108050-3-git-send-email-zourongrong@gmail.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1464514855-108050-1-git-send-email-zourongrong@gmail.com> References: <1464514855-108050-1-git-send-email-zourongrong@gmail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160529_024330_255736_35AD5CA6 X-CRM114-Status: GOOD ( 22.15 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-fbdev@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linuxarm@huawei.com, guohanjun@huawei.com, linux-arm-kernel@lists.infradead.org, majun258@huawei.com MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Add plane funcs and helper funcs for DE. Signed-off-by: Rongrong Zou Signed-off-by: Jianhua Li --- drivers/gpu/drm/hisilicon/hibmc/Makefile | 2 +- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c | 170 ++++++++++++++++++++++++ drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 41 +++++- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 3 + 4 files changed, 214 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c diff --git a/drivers/gpu/drm/hisilicon/hibmc/Makefile b/drivers/gpu/drm/hisilicon/hibmc/Makefile index 533f9ed..faa7e64 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/Makefile +++ b/drivers/gpu/drm/hisilicon/hibmc/Makefile @@ -1,4 +1,4 @@ -hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_power.o +hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_power.o obj-$(CONFIG_DRM_HISI_HIBMC) +=hibmc-drm.o #obj-y += hibmc-drm.o diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c new file mode 100644 index 0000000..e8e5853 --- /dev/null +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c @@ -0,0 +1,170 @@ +/* Hisilicon Hibmc SoC drm driver + * + * Based on the bochs drm driver. + * + * Copyright (c) 2016 Huawei Limited. + * + * Author: + * Rongrong Zou + * Rongrong Zou + * Jianhua Li + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "hibmc_drm_drv.h" +#include "hibmc_drm_regs.h" +#include "hibmc_drm_power.h" + +/* ---------------------------------------------------------------------- */ + +static int hibmc_plane_prepare_fb(struct drm_plane *plane, + const struct drm_plane_state *new_state) +{ + /* do nothing */ + return 0; +} + +static void hibmc_plane_cleanup_fb(struct drm_plane *plane, + const struct drm_plane_state *old_state) +{ + /* do nothing */ +} + +static int hibmc_plane_atomic_check(struct drm_plane *plane, + struct drm_plane_state *state) +{ + struct drm_framebuffer *fb = state->fb; + struct drm_crtc *crtc = state->crtc; + struct drm_crtc_state *crtc_state; + u32 src_x = state->src_x >> 16; + u32 src_y = state->src_y >> 16; + u32 src_w = state->src_w >> 16; + u32 src_h = state->src_h >> 16; + int crtc_x = state->crtc_x; + int crtc_y = state->crtc_y; + u32 crtc_w = state->crtc_w; + u32 crtc_h = state->crtc_h; + + if (!crtc || !fb) + return 0; + + crtc_state = drm_atomic_get_crtc_state(state->state, crtc); + if (IS_ERR(crtc_state)) + return PTR_ERR(crtc_state); + + if (src_w != crtc_w || src_h != crtc_h) { + DRM_ERROR("Scale not support!!!\n"); + return -EINVAL; + } + + if (src_x + src_w > fb->width || + src_y + src_h > fb->height) + return -EINVAL; + + if (crtc_x < 0 || crtc_y < 0) + return -EINVAL; + + if (crtc_x + crtc_w > crtc_state->adjusted_mode.hdisplay || + crtc_y + crtc_h > crtc_state->adjusted_mode.vdisplay) + return -EINVAL; + + return 0; +} + +static void hibmc_plane_atomic_update(struct drm_plane *plane, + struct drm_plane_state *old_state) +{ + struct drm_plane_state *state = plane->state; + u32 reg; + unsigned int line_l; + struct hibmc_drm_device *hidev = + (struct hibmc_drm_device *)plane->dev->dev_private; + + /* now just support one plane */ + writel(0, hidev->mmio + HIBMC_CRT_FB_ADDRESS); + reg = state->fb->width * (state->fb->bits_per_pixel >> 3); + /* now line_pad is 16 */ + reg = PADDING(16, reg); + + line_l = state->fb->width * state->fb->bits_per_pixel / 8; + line_l = PADDING(16, line_l); + writel((HIBMC_CRT_FB_WIDTH_WIDTH(reg) & HIBMC_CRT_FB_WIDTH_WIDTH_MASK) | + (HIBMC_CRT_FB_WIDTH_OFFS(line_l) & HIBMC_CRT_FB_WIDTH_OFFS_MASK), + hidev->mmio + HIBMC_CRT_FB_WIDTH); + + /* SET PIXEL FORMAT */ + reg = readl(hidev->mmio + HIBMC_CRT_DISP_CTL); + reg = reg & ~HIBMC_CRT_DISP_CTL_FORMAT_MASK; + reg = reg | (HIBMC_CRT_DISP_CTL_FORMAT(state->fb->bits_per_pixel >> 4) & + HIBMC_CRT_DISP_CTL_FORMAT_MASK); + writel(reg, hidev->mmio + HIBMC_CRT_DISP_CTL); +} + +static void hibmc_plane_atomic_disable(struct drm_plane *plane, + struct drm_plane_state *old_state) +{ +} + +static const u32 channel_formats1[] = { + DRM_FORMAT_RGB565, DRM_FORMAT_BGR565, DRM_FORMAT_RGB888, + DRM_FORMAT_BGR888, DRM_FORMAT_XRGB8888, DRM_FORMAT_XBGR8888, + DRM_FORMAT_RGBA8888, DRM_FORMAT_BGRA8888, DRM_FORMAT_ARGB8888, + DRM_FORMAT_ABGR8888 +}; + +static struct drm_plane_funcs hibmc_plane_funcs = { + .update_plane = drm_atomic_helper_update_plane, + .disable_plane = drm_atomic_helper_disable_plane, + .set_property = drm_atomic_helper_plane_set_property, + .destroy = drm_plane_cleanup, + .reset = drm_atomic_helper_plane_reset, + .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, +}; + +static const struct drm_plane_helper_funcs hibmc_plane_helper_funcs = { + .prepare_fb = hibmc_plane_prepare_fb, + .cleanup_fb = hibmc_plane_cleanup_fb, + .atomic_check = hibmc_plane_atomic_check, + .atomic_update = hibmc_plane_atomic_update, + .atomic_disable = hibmc_plane_atomic_disable, +}; + +int hibmc_plane_init(struct hibmc_drm_device *hidev) +{ + struct drm_device *dev = hidev->dev; + struct drm_plane *plane = &hidev->plane; + int ret = 0; + + /* + * plane init + * TODO: Now only support primary plane, overlay planes + * need to do. + */ + ret = drm_universal_plane_init(dev, plane, 1, &hibmc_plane_funcs, + channel_formats1, + ARRAY_SIZE(channel_formats1), + DRM_PLANE_TYPE_PRIMARY, + NULL); + if (ret) { + DRM_ERROR("fail to init plane!!!\n"); + return ret; + } + + drm_plane_helper_add(plane, &hibmc_plane_helper_funcs); + return 0; +} + diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c index 7eaacd8..794250a 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c @@ -51,7 +51,8 @@ static void hibmc_disable_vblank(struct drm_device *dev, unsigned int pipe) } static struct drm_driver hibmc_driver = { - .driver_features = DRIVER_GEM | DRIVER_MODESET, + .driver_features = DRIVER_GEM | DRIVER_MODESET | + DRIVER_ATOMIC, .fops = &hibmc_fops, .name = "hibmc", .desc = "hibmc drm driver", @@ -98,6 +99,40 @@ static const struct drm_mode_config_funcs mode_config_funcs = { .atomic_commit = drm_atomic_helper_commit, }; +static int hibmc_kms_init(struct hibmc_drm_device *hidev) +{ + int ret; + + drm_mode_config_init(hidev->dev); + hidev->mode_config_initialized = true; + + hidev->dev->mode_config.min_width = 0; + hidev->dev->mode_config.min_height = 0; + hidev->dev->mode_config.max_width = 1920; + hidev->dev->mode_config.max_height = 1440; + + hidev->dev->mode_config.fb_base = hidev->fb_base; + hidev->dev->mode_config.preferred_depth = 24; + hidev->dev->mode_config.prefer_shadow = 0; + + hidev->dev->mode_config.funcs = (void *)&mode_config_funcs; + + ret = hibmc_plane_init(hidev); + if (ret) { + DRM_ERROR("fail to init plane!!!\n"); + return ret; + } + + return 0; +} + +static void hibmc_kms_fini(struct hibmc_drm_device *hidev) +{ + if (hidev->mode_config_initialized) { + drm_mode_config_cleanup(hidev->dev); + hidev->mode_config_initialized = false; + } +} static int hibmc_hw_config(struct hibmc_drm_device *hidev) { @@ -190,6 +225,7 @@ static int hibmc_unload(struct drm_device *dev) { struct hibmc_drm_device *hidev = dev->dev_private; + hibmc_kms_fini(hidev); hibmc_hw_fini(hidev); dev->dev_private = NULL; return 0; @@ -210,6 +246,9 @@ static int hibmc_load(struct drm_device *dev, unsigned long flags) if (ret) goto err; + ret = hibmc_kms_init(hidev); + if (ret) + goto err; ret = drm_vblank_init(dev, dev->mode_config.num_crtc); if (ret) { diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h index a072ea9..6c7985d 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h @@ -32,8 +32,11 @@ struct hibmc_drm_device { /* drm */ struct drm_device *dev; + struct drm_plane plane; bool mode_config_initialized; }; +int hibmc_plane_init(struct hibmc_drm_device *hidev); + #endif