From patchwork Tue Jan 22 09:24:25 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Qian Wang X-Patchwork-Id: 10775171 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8D2336C2 for ; Tue, 22 Jan 2019 09:40:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7A13F2A12D for ; Tue, 22 Jan 2019 09:40:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6D8F02A140; Tue, 22 Jan 2019 09:40:23 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 7CA002A12D for ; Tue, 22 Jan 2019 09:40:22 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8816D6EC41; Tue, 22 Jan 2019 09:40:21 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from EUR03-DB5-obe.outbound.protection.outlook.com (mail-eopbgr40089.outbound.protection.outlook.com [40.107.4.89]) by gabe.freedesktop.org (Postfix) with ESMTPS id 694176EC41 for ; Tue, 22 Jan 2019 09:40:20 +0000 (UTC) Received: from DB6PR0801MB1990.eurprd08.prod.outlook.com (10.168.81.21) by DB6PR0801MB1813.eurprd08.prod.outlook.com (10.169.227.135) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1558.16; Tue, 22 Jan 2019 09:24:26 +0000 Received: from DB6PR0801MB1990.eurprd08.prod.outlook.com ([fe80::b9be:3d28:78a2:6e33]) by DB6PR0801MB1990.eurprd08.prod.outlook.com ([fe80::b9be:3d28:78a2:6e33%2]) with mapi id 15.20.1537.031; Tue, 22 Jan 2019 09:24:26 +0000 From: "james qian wang (Arm Technology China)" To: Liviu Dudau , "airlied@linux.ie" , Brian Starkey Subject: [PATCH v2 6/7] drm/komeda: Add irq handling Thread-Topic: [PATCH v2 6/7] drm/komeda: Add irq handling Thread-Index: AQHUsjRETgedwkt14Em51hz5Ex8diA== Date: Tue, 22 Jan 2019 09:24:25 +0000 Message-ID: <20190122092243.21226-7-james.qian.wang@arm.com> References: <20190122092243.21226-1-james.qian.wang@arm.com> In-Reply-To: <20190122092243.21226-1-james.qian.wang@arm.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [113.29.88.7] x-clientproxiedby: SYCPR01CA0039.ausprd01.prod.outlook.com (2603:10c6:10:e::27) To DB6PR0801MB1990.eurprd08.prod.outlook.com (2603:10a6:4:6c::21) x-ms-exchange-messagesentrepresentingtype: 1 x-mailer: git-send-email 2.17.1 x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; DB6PR0801MB1813; 6:Sj/3niJqZtkhRLyElrJr2JkW4+H480Y6IjRb0e8jPQmxm8RG72KbGbTOJUr+Ra1jo8JobhAmAOBYrAQwZ9QZBN+4yN5bDX5mGybiLDND4Mq81yXgGZ7PTvOQgNRAd1lsdUdxCP2/Db6N3qjYdRTtnxtLOunSBgW5uVlm9YkQ7kemfxpbKdJsstdZv/mIG+ogzSZMD8qGQWXBz5qrxKXxZLxLc/8O8mtnPsxwFvYp2nzcxxGoFzY4clgriKfaFxQaBjvDqj2HnSCBufmaxNxtFM+w2K+xlmKJL3uX6hsldK8vlPasDqQEMJcl8gzgGIu/TvmyjMphbGF2AL3kreDY84Oz49IsRg5VRBcfulBWDSgnG5MuJ7QdxBjLuoGmPNBO9FAZsCr1Rclpq8nrNha8eZaXUbBGrKVkxnFLgaqhgkL3VR3VoAlB2Vtldl0AHySwDb0Hj3vkjVhXcwHnGb2xyw==; 5:sMokVRzp3838aTclmcwrqmykNZ+JDu7C18kA2Mp/WBsF5Vtkxhvn/wIGs4LNuyjGiaujvQP9LdEYZh3CBMiaBK65phxjvYhH/m2naXFhC/KuuPOtD/eqUd1zASLpeWa/RRxGwtaXQTB61RDlFQtgSoqW0k708gjjFudas9JqfUo970wcwnD6tdT0gGkX/qOoJgHml+NBfuypHfJRq+Tbkw==; 7:VzQJNT54CccuRw+a5DjdaA/Kg1PKucGM/r2+3shT7nKEB8DgZphiLA4ok6u/Pk1f5A0Zd05jkUL7A9UDsALFficXJTKpqLzzQ8nvcOJDN+vgLsh/lgnFgkW3SRrSHLye7xG4niRERtepkVEEoDm7tw== x-ms-office365-filtering-correlation-id: ea3ca720-8be8-4ece-1973-08d6804b66ce x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0; PCL:0; RULEID:(2390118)(7020095)(4652040)(8989299)(4534185)(7168020)(4627221)(201703031133081)(201702281549075)(8990200)(5600109)(711020)(4618075)(2017052603328)(7153060)(7193020); SRVR:DB6PR0801MB1813; x-ms-traffictypediagnostic: DB6PR0801MB1813: nodisclaimer: True x-microsoft-antispam-prvs: x-forefront-prvs: 0925081676 x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(396003)(346002)(376002)(136003)(39860400002)(366004)(189003)(199004)(54906003)(110136005)(305945005)(66066001)(103116003)(316002)(6486002)(25786009)(6636002)(478600001)(11346002)(446003)(256004)(5024004)(14444005)(486006)(81156014)(2616005)(476003)(53946003)(1076003)(4326008)(50226002)(68736007)(6512007)(386003)(6506007)(55236004)(71190400001)(71200400001)(53936002)(36756003)(105586002)(3846002)(2501003)(6116002)(8936002)(14454004)(99286004)(52116002)(97736004)(26005)(8676002)(81166006)(7736002)(86362001)(30864003)(186003)(6436002)(2906002)(102836004)(106356001)(76176011); DIR:OUT; SFP:1101; SCL:1; SRVR:DB6PR0801MB1813; H:DB6PR0801MB1990.eurprd08.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; received-spf: None (protection.outlook.com: arm.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: arq1uuirKvSV2S8toivhKjQOpqc1/07OWdPIHdepCCRjOR+mc40voMs++N15a/qcFM7T3d990f8yke2SnRcvREHylbhcSmZEf65dkK65WT0zXwlc0YmcjdrEfS3gaTPZK1iZofpPcjCgxSIks/McLj4+a1gQqOTq2KwTqZAFmVXAvnSqPbHYjLRle7Le6Hm8KMiH7NEw0lbrn9O++f5hIK1gE30Ysqy+Yt6pNQmGNu4BuiMs4ALotaLXKaqIkPfSrDVe4JI9Y7TyhiTNlkRyJvQDCcF6EA0TY1T49OdGbR5RBrMgBqeWNzOUoHpLBNRIWF1YiIU8UwanmpdQKgrZaYPcivJRL33p6RNuQ4xmNkSPBxbUBomFB5HHXNfRVBgcj8boznmSrFt3VGALbXKHA/xBUN9+YJ/skKffLZRtPuo= spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-Network-Message-Id: ea3ca720-8be8-4ece-1973-08d6804b66ce X-MS-Exchange-CrossTenant-originalarrivaltime: 22 Jan 2019 09:24:17.4251 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB6PR0801MB1813 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: nd , Ayan Halder , "Tiannan Zhu \(Arm Technology China\)" , "Jonathan Chai \(Arm Technology China\)" , "linux-kernel@vger.kernel.org" , "dri-devel@lists.freedesktop.org" , "Julien Yin \(Arm Technology China\)" , "james qian wang \(Arm Technology China\)" , "malidp@foss.arm.com" , "Yiqi Kang \(Arm Technology China\)" , "thomas Sun \(Arm Technology China\)" , "Jin Gao \(Arm Technology China\)" , "Lowry Li \(Arm Technology China\)" Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: "james qian wang (Arm Technology China)" 1. Added irq_handler/irq_enable/irq_disable to komeda_dev_func, then the Komeda-CORE can control the HW irq via these chip function. 2. Install irq and register irq_handler to system by DRM, so once the IRQ coming, the handling sequence is: komeda_kms_irq_handler(int irq, void *data) /* step 1. call into the CHIP to recognize event */ mdev->funcs->irq_handler(mdev, &evts); /* step 2. notify the crtc to handle the events */ for (i = 0; i < kms->n_crtcs; i++) komeda_crtc_handle_event(&kms->crtcs[i], &evts); v2: - Move get IRQ number into this change. - Enable irq before drm_dev_register. Signed-off-by: James Qian Wang (Arm Technology China) --- .../gpu/drm/arm/display/komeda/d71/d71_dev.c | 237 ++++++++++++++++++ .../gpu/drm/arm/display/komeda/komeda_crtc.c | 18 ++ .../gpu/drm/arm/display/komeda/komeda_dev.c | 6 + .../gpu/drm/arm/display/komeda/komeda_dev.h | 46 ++++ .../gpu/drm/arm/display/komeda/komeda_kms.c | 37 ++- .../gpu/drm/arm/display/komeda/komeda_kms.h | 3 + 6 files changed, 345 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c index b87ffae62dbe..afc13d3b3afc 100644 --- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c +++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c @@ -7,6 +7,240 @@ #include "d71_dev.h" #include "malidp_io.h" +static u64 get_lpu_event(struct d71_pipeline *d71_pipeline) +{ + u32 __iomem *reg = d71_pipeline->lpu_addr; + u32 status, raw_status; + u64 evts = 0ULL; + + raw_status = malidp_read32(reg, BLK_IRQ_RAW_STATUS); + if (raw_status & LPU_IRQ_IBSY) + evts |= KOMEDA_EVENT_IBSY; + if (raw_status & LPU_IRQ_EOW) + evts |= KOMEDA_EVENT_EOW; + + if (raw_status & (LPU_IRQ_ERR | LPU_IRQ_IBSY)) { + u32 restore = 0, tbu_status; + /* Check error of LPU status */ + status = malidp_read32(reg, BLK_STATUS); + if (status & LPU_STATUS_AXIE) { + restore |= LPU_STATUS_AXIE; + evts |= KOMEDA_ERR_AXIE; + } + if (status & LPU_STATUS_ACE0) { + restore |= LPU_STATUS_ACE0; + evts |= KOMEDA_ERR_ACE0; + } + if (status & LPU_STATUS_ACE1) { + restore |= LPU_STATUS_ACE1; + evts |= KOMEDA_ERR_ACE1; + } + if (status & LPU_STATUS_ACE2) { + restore |= LPU_STATUS_ACE2; + evts |= KOMEDA_ERR_ACE2; + } + if (status & LPU_STATUS_ACE3) { + restore |= LPU_STATUS_ACE3; + evts |= KOMEDA_ERR_ACE3; + } + if (restore != 0) + malidp_write32_mask(reg, BLK_STATUS, restore, 0); + + restore = 0; + /* Check errors of TBU status */ + tbu_status = malidp_read32(reg, LPU_TBU_STATUS); + if (tbu_status & LPU_TBU_STATUS_TCF) { + restore |= LPU_TBU_STATUS_TCF; + evts |= KOMEDA_ERR_TCF; + } + if (tbu_status & LPU_TBU_STATUS_TTNG) { + restore |= LPU_TBU_STATUS_TTNG; + evts |= KOMEDA_ERR_TTNG; + } + if (tbu_status & LPU_TBU_STATUS_TITR) { + restore |= LPU_TBU_STATUS_TITR; + evts |= KOMEDA_ERR_TITR; + } + if (tbu_status & LPU_TBU_STATUS_TEMR) { + restore |= LPU_TBU_STATUS_TEMR; + evts |= KOMEDA_ERR_TEMR; + } + if (tbu_status & LPU_TBU_STATUS_TTF) { + restore |= LPU_TBU_STATUS_TTF; + evts |= KOMEDA_ERR_TTF; + } + if (restore != 0) + malidp_write32_mask(reg, LPU_TBU_STATUS, restore, 0); + } + + malidp_write32(reg, BLK_IRQ_CLEAR, raw_status); + return evts; +} + +static u64 get_cu_event(struct d71_pipeline *d71_pipeline) +{ + u32 __iomem *reg = d71_pipeline->cu_addr; + u32 status, raw_status; + u64 evts = 0ULL; + + raw_status = malidp_read32(reg, BLK_IRQ_RAW_STATUS); + if (raw_status & CU_IRQ_OVR) + evts |= KOMEDA_EVENT_OVR; + + if (raw_status & (CU_IRQ_ERR | CU_IRQ_OVR)) { + status = malidp_read32(reg, BLK_STATUS) & 0x7FFFFFFF; + if (status & CU_STATUS_CPE) + evts |= KOMEDA_ERR_CPE; + if (status & CU_STATUS_ZME) + evts |= KOMEDA_ERR_ZME; + if (status & CU_STATUS_CFGE) + evts |= KOMEDA_ERR_CFGE; + if (status) + malidp_write32_mask(reg, BLK_STATUS, status, 0); + } + + malidp_write32(reg, BLK_IRQ_CLEAR, raw_status); + + return evts; +} + +static u64 get_dou_event(struct d71_pipeline *d71_pipeline) +{ + u32 __iomem *reg = d71_pipeline->dou_addr; + u32 status, raw_status; + u64 evts = 0ULL; + + raw_status = malidp_read32(reg, BLK_IRQ_RAW_STATUS); + if (raw_status & DOU_IRQ_PL0) + evts |= KOMEDA_EVENT_VSYNC; + if (raw_status & DOU_IRQ_UND) + evts |= KOMEDA_EVENT_URUN; + + if (raw_status & (DOU_IRQ_ERR | DOU_IRQ_UND)) { + u32 restore = 0; + + status = malidp_read32(reg, BLK_STATUS); + if (status & DOU_STATUS_DRIFTTO) { + restore |= DOU_STATUS_DRIFTTO; + evts |= KOMEDA_ERR_DRIFTTO; + } + if (status & DOU_STATUS_FRAMETO) { + restore |= DOU_STATUS_FRAMETO; + evts |= KOMEDA_ERR_FRAMETO; + } + if (status & DOU_STATUS_TETO) { + restore |= DOU_STATUS_TETO; + evts |= KOMEDA_ERR_TETO; + } + if (status & DOU_STATUS_CSCE) { + restore |= DOU_STATUS_CSCE; + evts |= KOMEDA_ERR_CSCE; + } + + if (restore != 0) + malidp_write32_mask(reg, BLK_STATUS, restore, 0); + } + + malidp_write32(reg, BLK_IRQ_CLEAR, raw_status); + return evts; +} + +static u64 get_pipeline_event(struct d71_pipeline *d71_pipeline, u32 gcu_status) +{ + u32 evts = 0ULL; + + if (gcu_status & (GLB_IRQ_STATUS_LPU0 | GLB_IRQ_STATUS_LPU1)) + evts |= get_lpu_event(d71_pipeline); + + if (gcu_status & (GLB_IRQ_STATUS_CU0 | GLB_IRQ_STATUS_CU1)) + evts |= get_cu_event(d71_pipeline); + + if (gcu_status & (GLB_IRQ_STATUS_DOU0 | GLB_IRQ_STATUS_DOU1)) + evts |= get_dou_event(d71_pipeline); + + return evts; +} + +static irqreturn_t +d71_irq_handler(struct komeda_dev *mdev, struct komeda_events *evts) +{ + struct d71_dev *d71 = mdev->chip_data; + u32 status, gcu_status, raw_status; + + gcu_status = malidp_read32(d71->gcu_addr, GLB_IRQ_STATUS); + + if (gcu_status & GLB_IRQ_STATUS_GCU) { + raw_status = malidp_read32(d71->gcu_addr, BLK_IRQ_RAW_STATUS); + if (raw_status & GCU_IRQ_CVAL0) + evts->pipes[0] |= KOMEDA_EVENT_FLIP; + if (raw_status & GCU_IRQ_CVAL1) + evts->pipes[1] |= KOMEDA_EVENT_FLIP; + if (raw_status & GCU_IRQ_ERR) { + status = malidp_read32(d71->gcu_addr, BLK_STATUS); + if (status & GCU_STATUS_MERR) { + evts->global |= KOMEDA_ERR_MERR; + malidp_write32_mask(d71->gcu_addr, BLK_STATUS, + GCU_STATUS_MERR, 0); + } + } + + malidp_write32(d71->gcu_addr, BLK_IRQ_CLEAR, raw_status); + } + + if (gcu_status & GLB_IRQ_STATUS_PIPE0) + evts->pipes[0] |= get_pipeline_event(d71->pipes[0], gcu_status); + + if (gcu_status & GLB_IRQ_STATUS_PIPE1) + evts->pipes[1] |= get_pipeline_event(d71->pipes[1], gcu_status); + + return gcu_status ? IRQ_HANDLED : IRQ_NONE; +} + +#define ENABLED_GCU_IRQS (GCU_IRQ_CVAL0 | GCU_IRQ_CVAL1 | \ + GCU_IRQ_MODE | GCU_IRQ_ERR) +#define ENABLED_LPU_IRQS (LPU_IRQ_IBSY | LPU_IRQ_ERR | LPU_IRQ_EOW) +#define ENABLED_CU_IRQS (CU_IRQ_OVR | CU_IRQ_ERR) +#define ENABLED_DOU_IRQS (DOU_IRQ_UND | DOU_IRQ_ERR) + +static int d71_enable_irq(struct komeda_dev *mdev) +{ + struct d71_dev *d71 = mdev->chip_data; + struct d71_pipeline *pipe; + u32 i; + + malidp_write32_mask(d71->gcu_addr, BLK_IRQ_MASK, + ENABLED_GCU_IRQS, ENABLED_GCU_IRQS); + for (i = 0; i < d71->num_pipelines; i++) { + pipe = d71->pipes[i]; + malidp_write32_mask(pipe->cu_addr, BLK_IRQ_MASK, + ENABLED_CU_IRQS, ENABLED_CU_IRQS); + malidp_write32_mask(pipe->lpu_addr, BLK_IRQ_MASK, + ENABLED_LPU_IRQS, ENABLED_LPU_IRQS); + malidp_write32_mask(pipe->dou_addr, BLK_IRQ_MASK, + ENABLED_DOU_IRQS, ENABLED_DOU_IRQS); + } + return 0; +} + +static int d71_disable_irq(struct komeda_dev *mdev) +{ + struct d71_dev *d71 = mdev->chip_data; + struct d71_pipeline *pipe; + u32 i; + + malidp_write32_mask(d71->gcu_addr, BLK_IRQ_MASK, ENABLED_GCU_IRQS, 0); + for (i = 0; i < d71->num_pipelines; i++) { + pipe = d71->pipes[i]; + malidp_write32_mask(pipe->cu_addr, BLK_IRQ_MASK, + ENABLED_CU_IRQS, 0); + malidp_write32_mask(pipe->lpu_addr, BLK_IRQ_MASK, + ENABLED_LPU_IRQS, 0); + malidp_write32_mask(pipe->dou_addr, BLK_IRQ_MASK, + ENABLED_DOU_IRQS, 0); + } + return 0; +} + static int d71_reset(struct d71_dev *d71) { u32 __iomem *gcu = d71->gcu_addr; @@ -220,6 +454,9 @@ static struct komeda_dev_funcs d71_chip_funcs = { .init_format_table = d71_init_fmt_tbl, .enum_resources = d71_enum_resources, .cleanup = d71_cleanup, + .irq_handler = d71_irq_handler, + .enable_irq = d71_enable_irq, + .disable_irq = d71_disable_irq, }; struct komeda_dev_funcs * diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c index 5bb5a55f6b31..7ca9bc8ef725 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c @@ -14,6 +14,24 @@ #include "komeda_dev.h" #include "komeda_kms.h" +void komeda_crtc_handle_event(struct komeda_crtc *kcrtc, + struct komeda_events *evts) +{ + struct drm_crtc *crtc = &kcrtc->base; + u32 events = evts->pipes[kcrtc->master->id]; + + if (events & KOMEDA_EVENT_VSYNC) + drm_crtc_handle_vblank(crtc); + + /* will handle it together with the write back support */ + if (events & KOMEDA_EVENT_EOW) + DRM_DEBUG("EOW.\n"); + + /* will handle it with crtc->flush */ + if (events & KOMEDA_EVENT_FLIP) + DRM_DEBUG("FLIP Done.\n"); +} + struct drm_crtc_helper_funcs komeda_crtc_helper_funcs = { }; diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c index a1160e2f07ec..01ae869b659b 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c @@ -49,6 +49,7 @@ static int komeda_parse_pipe_dt(struct komeda_dev *mdev, struct device_node *np) static int komeda_parse_dt(struct device *dev, struct komeda_dev *mdev) { + struct platform_device *pdev = to_platform_device(dev); struct device_node *child, *np = dev->of_node; struct clk *clk; int ret; @@ -58,6 +59,11 @@ static int komeda_parse_dt(struct device *dev, struct komeda_dev *mdev) return PTR_ERR(clk); mdev->mclk = clk; + mdev->irq = platform_get_irq(pdev, 0); + if (mdev->irq < 0) { + DRM_ERROR("could not get IRQ number.\n"); + return mdev->irq; + } for_each_available_child_of_node(np, child) { if (of_node_cmp(child->name, "pipeline") == 0) { diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h index 0f77dead6a23..681fe022bd22 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h +++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h @@ -13,6 +13,33 @@ #include "malidp_product.h" #include "komeda_format_caps.h" +#define KOMEDA_EVENT_VSYNC BIT_ULL(0) +#define KOMEDA_EVENT_FLIP BIT_ULL(1) +#define KOMEDA_EVENT_URUN BIT_ULL(2) +#define KOMEDA_EVENT_IBSY BIT_ULL(3) +#define KOMEDA_EVENT_OVR BIT_ULL(4) +#define KOMEDA_EVENT_EOW BIT_ULL(5) +#define KOMEDA_EVENT_MODE BIT_ULL(6) + +#define KOMEDA_ERR_TETO BIT_ULL(14) +#define KOMEDA_ERR_TEMR BIT_ULL(15) +#define KOMEDA_ERR_TITR BIT_ULL(16) +#define KOMEDA_ERR_CPE BIT_ULL(17) +#define KOMEDA_ERR_CFGE BIT_ULL(18) +#define KOMEDA_ERR_AXIE BIT_ULL(19) +#define KOMEDA_ERR_ACE0 BIT_ULL(20) +#define KOMEDA_ERR_ACE1 BIT_ULL(21) +#define KOMEDA_ERR_ACE2 BIT_ULL(22) +#define KOMEDA_ERR_ACE3 BIT_ULL(23) +#define KOMEDA_ERR_DRIFTTO BIT_ULL(24) +#define KOMEDA_ERR_FRAMETO BIT_ULL(25) +#define KOMEDA_ERR_CSCE BIT_ULL(26) +#define KOMEDA_ERR_ZME BIT_ULL(27) +#define KOMEDA_ERR_MERR BIT_ULL(28) +#define KOMEDA_ERR_TCF BIT_ULL(29) +#define KOMEDA_ERR_TTNG BIT_ULL(30) +#define KOMEDA_ERR_TTF BIT_ULL(31) + /* malidp device id */ enum { MALI_D71 = 0, @@ -39,6 +66,11 @@ struct komeda_product_data { struct komeda_dev; +struct komeda_events { + u64 global; + u64 pipes[KOMEDA_MAX_PIPELINES]; +}; + /** * struct komeda_dev_funcs * @@ -60,6 +92,17 @@ struct komeda_dev_funcs { int (*enum_resources)(struct komeda_dev *mdev); /** @cleanup: call to chip to cleanup komeda_dev->chip data */ void (*cleanup)(struct komeda_dev *mdev); + /** + * @irq_handler: + * + * for CORE to get the HW event from the CHIP when interrupt happened. + */ + irqreturn_t (*irq_handler)(struct komeda_dev *mdev, + struct komeda_events *events); + /** @enable_irq: enable irq */ + int (*enable_irq)(struct komeda_dev *mdev); + /** @disable_irq: disable irq */ + int (*disable_irq)(struct komeda_dev *mdev); }; /** @@ -81,6 +124,9 @@ struct komeda_dev { /** @mck: HW main engine clk */ struct clk *mclk; + /** @irq: irq number */ + int irq; + int n_pipelines; struct komeda_pipeline *pipelines[KOMEDA_MAX_PIPELINES]; diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c index 3fc096d3883e..4adc6a3104c9 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c @@ -29,10 +29,31 @@ static int komeda_gem_cma_dumb_create(struct drm_file *file, return drm_gem_cma_dumb_create_internal(file, dev, args); } +static irqreturn_t komeda_kms_irq_handler(int irq, void *data) +{ + struct drm_device *drm = data; + struct komeda_dev *mdev = drm->dev_private; + struct komeda_kms_dev *kms = to_kdev(drm); + struct komeda_events evts; + irqreturn_t status; + u32 i; + + /* Call into the CHIP to recognize events */ + memset(&evts, 0, sizeof(evts)); + status = mdev->funcs->irq_handler(mdev, &evts); + + /* Notify the crtc to handle the events */ + for (i = 0; i < kms->n_crtcs; i++) + komeda_crtc_handle_event(&kms->crtcs[i], &evts); + + return status; +} + static struct drm_driver komeda_kms_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC | - DRIVER_PRIME, + DRIVER_PRIME | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, .lastclose = drm_fb_helper_lastclose, + .irq_handler = komeda_kms_irq_handler, .gem_free_object_unlocked = drm_gem_cma_free_object, .gem_vm_ops = &drm_gem_cma_vm_ops, .dumb_create = komeda_gem_cma_dumb_create, @@ -140,12 +161,22 @@ struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev) drm_mode_config_reset(drm); - err = drm_dev_register(drm, 0); + err = drm_irq_install(drm, mdev->irq); if (err) goto cleanup_mode_config; + err = mdev->funcs->enable_irq(mdev); + if (err) + goto uninstall_irq; + + err = drm_dev_register(drm, 0); + if (err) + goto uninstall_irq; + return kms; +uninstall_irq: + drm_irq_uninstall(drm); cleanup_mode_config: drm_mode_config_cleanup(drm); free_kms: @@ -158,7 +189,9 @@ void komeda_kms_detach(struct komeda_kms_dev *kms) struct drm_device *drm = &kms->base; struct komeda_dev *mdev = drm->dev_private; + mdev->funcs->disable_irq(mdev); drm_dev_unregister(drm); + drm_irq_uninstall(drm); component_unbind_all(mdev->dev, drm); komeda_kms_cleanup_private_objs(mdev); drm_mode_config_cleanup(drm); diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h index f519a4c587e6..0faeeac2765a 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h +++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h @@ -109,6 +109,9 @@ int komeda_kms_add_private_objs(struct komeda_kms_dev *kms, struct komeda_dev *mdev); void komeda_kms_cleanup_private_objs(struct komeda_dev *mdev); +void komeda_crtc_handle_event(struct komeda_crtc *kcrtc, + struct komeda_events *evts); + struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev); void komeda_kms_detach(struct komeda_kms_dev *kms);