From patchwork Thu Mar 12 17:01:38 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: jilai wang X-Patchwork-Id: 5997281 Return-Path: X-Original-To: patchwork-linux-arm-msm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id D4F569F2A9 for ; Thu, 12 Mar 2015 17:01:53 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 6ACF520381 for ; Thu, 12 Mar 2015 17:01:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id F1C2C20379 for ; Thu, 12 Mar 2015 17:01:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754517AbbCLRBs (ORCPT ); Thu, 12 Mar 2015 13:01:48 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:44847 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754536AbbCLRBr (ORCPT ); Thu, 12 Mar 2015 13:01:47 -0400 Received: from smtp.codeaurora.org (localhost [127.0.0.1]) by smtp.codeaurora.org (Postfix) with ESMTP id CD55B1406DD; Thu, 12 Mar 2015 17:01:46 +0000 (UTC) Received: by smtp.codeaurora.org (Postfix, from userid 486) id BE3211409A9; Thu, 12 Mar 2015 17:01:46 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from yyzubuntu29.qualcomm.com (rrcs-67-52-130-30.west.biz.rr.com [67.52.130.30]) (using TLSv1.1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) (Authenticated sender: jilaiw@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id D6001140996; Thu, 12 Mar 2015 17:01:44 +0000 (UTC) From: Jilai Wang To: dri-devel@lists.freedesktop.org Cc: linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, robdclark@gmail.com, Jilai Wang Subject: [PATCH] drm/msm: Refactor msm drm driver to be able to support module Date: Thu, 12 Mar 2015 13:01:38 -0400 Message-Id: <1426179698-12266-1-git-send-email-jilaiw@codeaurora.org> X-Mailer: git-send-email 1.8.2.1 X-Virus-Scanned: ClamAV using ClamSMTP Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Each HW component's driver such as HDMI/eDP/DSI should be able to compiled as a module which allows user to prevent this part of code to be compiled if not needed. Signed-off-by: Jilai Wang --- drivers/gpu/drm/msm/adreno/adreno_device.c | 13 +++++-- drivers/gpu/drm/msm/edp/edp.c | 31 +++++++++++++---- drivers/gpu/drm/msm/edp/edp.h | 1 + drivers/gpu/drm/msm/hdmi/hdmi.c | 35 +++++++++++++++---- drivers/gpu/drm/msm/hdmi/hdmi.h | 1 + drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c | 3 +- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 56 +++++++++++++++--------------- drivers/gpu/drm/msm/msm_drv.c | 6 ---- drivers/gpu/drm/msm/msm_drv.h | 29 ++++++++-------- drivers/gpu/drm/msm/msm_gpu.h | 2 -- 10 files changed, 110 insertions(+), 67 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index be83dee..ff7d743 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -287,12 +287,19 @@ static struct platform_driver adreno_driver = { }, }; -void __init adreno_register(void) +static int __init adreno_register(void) { - platform_driver_register(&adreno_driver); + return platform_driver_register(&adreno_driver); } -void __exit adreno_unregister(void) +static void __exit adreno_unregister(void) { platform_driver_unregister(&adreno_driver); } + +module_init(adreno_register); +module_exit(adreno_unregister); + +MODULE_AUTHOR("Rob Clark #include "edp.h" +static int msm_edp_modeset_init(struct msm_drm_sub_dev *base, + struct drm_device *dev); + static irqreturn_t edp_irq(int irq, void *dev_id) { struct msm_edp *edp = dev_id; @@ -63,6 +66,8 @@ static struct msm_edp *edp_init(struct platform_device *pdev) if (ret) goto fail; + edp->base.modeset_init = msm_edp_modeset_init; + return edp; fail: @@ -82,7 +87,8 @@ static int edp_bind(struct device *dev, struct device *master, void *data) edp = edp_init(to_platform_device(dev)); if (IS_ERR(edp)) return PTR_ERR(edp); - priv->edp = edp; + + priv->edp = &edp->base; return 0; } @@ -131,26 +137,32 @@ static struct platform_driver edp_driver = { }, }; -void __init msm_edp_register(void) +static int __init msm_edp_register(void) { DBG(""); - platform_driver_register(&edp_driver); + return platform_driver_register(&edp_driver); } -void __exit msm_edp_unregister(void) +static void __exit msm_edp_unregister(void) { DBG(""); platform_driver_unregister(&edp_driver); } /* Second part of initialization, the drm/kms level modeset_init */ -int msm_edp_modeset_init(struct msm_edp *edp, struct drm_device *dev, - struct drm_encoder *encoder) +static int msm_edp_modeset_init(struct msm_drm_sub_dev *base, + struct drm_device *dev) { + struct msm_edp *edp = container_of(base, struct msm_edp, base); struct platform_device *pdev = edp->pdev; struct msm_drm_private *priv = dev->dev_private; + struct drm_encoder *encoder; int ret; + if (WARN_ON(base->num_encoders != 1)) + return -EINVAL; + + encoder = base->encoders[0]; edp->encoder = encoder; edp->dev = dev; @@ -206,3 +218,10 @@ fail: return ret; } + +module_init(msm_edp_register); +module_exit(msm_edp_unregister); + +MODULE_AUTHOR("Hai Li #include "hdmi.h" +static int hdmi_modeset_init(struct msm_drm_sub_dev *base, + struct drm_device *dev); + void hdmi_set_mode(struct hdmi *hdmi, bool power_on) { uint32_t ctrl = 0; @@ -197,6 +200,8 @@ static struct hdmi *hdmi_init(struct platform_device *pdev) goto fail; } + hdmi->base.modeset_init = hdmi_modeset_init; + return hdmi; fail: @@ -214,13 +219,19 @@ fail: * should be handled in hdmi_init() so that failure happens from * hdmi sub-device's probe. */ -int hdmi_modeset_init(struct hdmi *hdmi, - struct drm_device *dev, struct drm_encoder *encoder) +static int hdmi_modeset_init(struct msm_drm_sub_dev *base, + struct drm_device *dev) { + struct hdmi *hdmi = container_of(base, struct hdmi, base); struct msm_drm_private *priv = dev->dev_private; struct platform_device *pdev = hdmi->pdev; + struct drm_encoder *encoder; int ret; + if (WARN_ON(base->num_encoders != 1)) + return -EINVAL; + + encoder = base->encoders[0]; hdmi->dev = dev; hdmi->encoder = encoder; @@ -439,7 +450,8 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data) hdmi = hdmi_init(to_platform_device(dev)); if (IS_ERR(hdmi)) return PTR_ERR(hdmi); - priv->hdmi = hdmi; + + priv->hdmi = &hdmi->base; return 0; } @@ -449,8 +461,10 @@ static void hdmi_unbind(struct device *dev, struct device *master, { struct drm_device *drm = dev_get_drvdata(master); struct msm_drm_private *priv = drm->dev_private; + if (priv->hdmi) { - hdmi_destroy(priv->hdmi); + struct hdmi *hdmi = container_of(priv->hdmi, struct hdmi, base); + hdmi_destroy(hdmi); priv->hdmi = NULL; } } @@ -480,12 +494,19 @@ static struct platform_driver hdmi_driver = { }, }; -void __init hdmi_register(void) +static int __init hdmi_register(void) { - platform_driver_register(&hdmi_driver); + return platform_driver_register(&hdmi_driver); } -void __exit hdmi_unregister(void) +static void __exit hdmi_unregister(void) { platform_driver_unregister(&hdmi_driver); } + +module_init(hdmi_register); +module_exit(hdmi_unregister); + +MODULE_AUTHOR("Rob Clark hdmi) { /* Construct bridge/connector for HDMI: */ - ret = hdmi_modeset_init(priv->hdmi, dev, encoder); + priv->hdmi->encoders[priv->hdmi->num_encoders++] = encoder; + ret = priv->hdmi->modeset_init(priv->hdmi, dev); if (ret) { dev_err(dev->dev, "failed to initialize HDMI: %d\n", ret); goto fail; diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 84168bf..ae336ec 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark * @@ -166,8 +166,9 @@ int mdp5_enable(struct mdp5_kms *mdp5_kms) return 0; } -static int construct_encoder(struct mdp5_kms *mdp5_kms, - enum mdp5_intf_type intf_type, int intf_num) +static struct drm_encoder *construct_encoder(struct mdp5_kms *mdp5_kms, + enum mdp5_intf_type intf_type, int intf_num, + enum mdp5_intf_mode intf_mode) { struct drm_device *dev = mdp5_kms->dev; struct msm_drm_private *priv = dev->dev_private; @@ -175,33 +176,19 @@ static int construct_encoder(struct mdp5_kms *mdp5_kms, struct mdp5_interface intf = { .num = intf_num, .type = intf_type, - .mode = MDP5_INTF_MODE_NONE, + .mode = intf_mode, }; - int ret = 0; encoder = mdp5_encoder_init(dev, &intf); if (IS_ERR(encoder)) { - ret = PTR_ERR(encoder); - dev_err(dev->dev, "failed to construct encoder: %d\n", ret); - return ret; + dev_err(dev->dev, "failed to construct encoder\n"); + return encoder; } encoder->possible_crtcs = (1 << priv->num_crtcs) - 1; priv->encoders[priv->num_encoders++] = encoder; - if (intf_type == INTF_HDMI) { - ret = hdmi_modeset_init(priv->hdmi, dev, encoder); - if (ret) - dev_err(dev->dev, "failed to init HDMI: %d\n", ret); - - } else if (intf_type == INTF_eDP) { - /* Construct bridge/connector for eDP: */ - ret = msm_edp_modeset_init(priv->edp, dev, encoder); - if (ret) - dev_err(dev->dev, "failed to init eDP: %d\n", ret); - } - - return ret; + return encoder; } static int modeset_init(struct mdp5_kms *mdp5_kms) @@ -267,26 +254,39 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) /* Construct external display interfaces' encoders: */ for (i = 0; i < ARRAY_SIZE(hw_cfg->intfs); i++) { enum mdp5_intf_type intf_type = hw_cfg->intfs[i]; + enum mdp5_intf_mode intf_mode = MDP5_INTF_MODE_NONE; + struct msm_drm_sub_dev *sub_dev; + struct drm_encoder *encoder; switch (intf_type) { case INTF_DISABLED: + sub_dev = NULL; break; case INTF_eDP: - if (priv->edp) - ret = construct_encoder(mdp5_kms, INTF_eDP, i); + sub_dev = priv->edp; break; case INTF_HDMI: - if (priv->hdmi) - ret = construct_encoder(mdp5_kms, INTF_HDMI, i); + sub_dev = priv->hdmi; break; default: dev_err(dev->dev, "unknown intf: %d\n", intf_type); ret = -EINVAL; - break; + goto fail; } - if (ret) - goto fail; + if (sub_dev) { + encoder = construct_encoder(mdp5_kms, intf_type, + i, intf_mode); + if (IS_ERR(encoder)) { + ret = PTR_ERR(encoder); + goto fail; + } + + sub_dev->encoders[sub_dev->num_encoders++] = encoder; + ret = sub_dev->modeset_init(sub_dev, dev); + if (ret) + goto fail; + } } return 0; diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index a72ed0a..7b21bed 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -1032,9 +1032,6 @@ static struct platform_driver msm_platform_driver = { static int __init msm_drm_register(void) { DBG("init"); - msm_edp_register(); - hdmi_register(); - adreno_register(); return platform_driver_register(&msm_platform_driver); } @@ -1042,9 +1039,6 @@ static void __exit msm_drm_unregister(void) { DBG("fini"); platform_driver_unregister(&msm_platform_driver); - hdmi_unregister(); - adreno_unregister(); - msm_edp_unregister(); } module_init(msm_drm_register); diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 9e8d441..690d891 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -64,6 +64,19 @@ struct msm_file_private { int dummy; }; +/* A base data structure for all MDP sub devices */ +struct msm_drm_sub_dev { + /* + * the encoders can be used by sub dev, + * must be set before modeset_init + */ + unsigned int num_encoders; + struct drm_encoder *encoders[8]; + + int (*modeset_init)(struct msm_drm_sub_dev *base, + struct drm_device *dev); +}; + struct msm_drm_private { struct msm_kms *kms; @@ -74,13 +87,13 @@ struct msm_drm_private { /* possibly this should be in the kms component, but it is * shared by both mdp4 and mdp5.. */ - struct hdmi *hdmi; + struct msm_drm_sub_dev *hdmi; /* eDP is for mdp5 only, but kms has not been created * when edp_bind() and edp_init() are called. Here is the only * place to keep the edp instance. */ - struct msm_edp *edp; + struct msm_drm_sub_dev *edp; /* when we have more than one 'msm_gpu' these need to be an array: */ struct msm_gpu *gpu; @@ -224,18 +237,6 @@ struct drm_framebuffer *msm_framebuffer_create(struct drm_device *dev, struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev); -struct hdmi; -int hdmi_modeset_init(struct hdmi *hdmi, struct drm_device *dev, - struct drm_encoder *encoder); -void __init hdmi_register(void); -void __exit hdmi_unregister(void); - -struct msm_edp; -void __init msm_edp_register(void); -void __exit msm_edp_unregister(void); -int msm_edp_modeset_init(struct msm_edp *edp, struct drm_device *dev, - struct drm_encoder *encoder); - #ifdef CONFIG_DEBUG_FS void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m); void msm_gem_describe_objects(struct list_head *list, struct seq_file *m); diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index fd1e4b4..ab853bf 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -167,7 +167,5 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, void msm_gpu_cleanup(struct msm_gpu *gpu); struct msm_gpu *adreno_load_gpu(struct drm_device *dev); -void __init adreno_register(void); -void __exit adreno_unregister(void); #endif /* __MSM_GPU_H__ */