From patchwork Fri Aug 4 16:27:09 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Wajdeczko X-Patchwork-Id: 9881673 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 6FCDA602B8 for ; Fri, 4 Aug 2017 16:28:08 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5DD82284B5 for ; Fri, 4 Aug 2017 16:28:08 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 52C412891B; Fri, 4 Aug 2017 16:28:08 +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.2 required=2.0 tests=BAYES_00, 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 EC00D284B5 for ; Fri, 4 Aug 2017 16:28:07 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 593636E514; Fri, 4 Aug 2017 16:27:44 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by gabe.freedesktop.org (Postfix) with ESMTPS id BAB936E4ED for ; Fri, 4 Aug 2017 16:27:41 +0000 (UTC) Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 04 Aug 2017 09:27:40 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.41,321,1498546800"; d="scan'208";a="135587369" Received: from irvmail001.ir.intel.com ([163.33.26.43]) by fmsmga005.fm.intel.com with ESMTP; 04 Aug 2017 09:27:38 -0700 Received: from mwajdecz-MOBL1.ger.corp.intel.com (mwajdecz-mobl1.ger.corp.intel.com [172.28.174.25]) by irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id v74GRMdV010586; Fri, 4 Aug 2017 17:27:38 +0100 From: Michal Wajdeczko To: intel-gfx@lists.freedesktop.org Date: Fri, 4 Aug 2017 16:27:09 +0000 Message-Id: <20170804162712.20468-13-michal.wajdeczko@intel.com> X-Mailer: git-send-email 2.10.1.windows.1 In-Reply-To: <20170804162712.20468-1-michal.wajdeczko@intel.com> References: <20170804162712.20468-1-michal.wajdeczko@intel.com> Subject: [Intel-gfx] [PATCH 12/15] drm/i915/guc: Prepare to process incoming requests from CT X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP Requests are read from CT in the irq handler, but actual processing will be done in the work thread. Processing of specific actions will be added in the upcoming patches. Signed-off-by: Michal Wajdeczko Cc: Oscar Mateo Cc: Michel Thierry Cc: Daniele Ceraolo Spurio --- drivers/gpu/drm/i915/intel_guc_ct.c | 72 +++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_guc_ct.h | 4 +++ 2 files changed, 76 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_guc_ct.c b/drivers/gpu/drm/i915/intel_guc_ct.c index 4dfa0b9..75cd7af 100644 --- a/drivers/gpu/drm/i915/intel_guc_ct.c +++ b/drivers/gpu/drm/i915/intel_guc_ct.c @@ -32,10 +32,17 @@ struct ct_request { u32 *response_buf; }; +struct ct_incoming_request { + struct list_head link; + u32 data[GUC_CT_MSG_LEN_MASK+1]; +}; + enum { CTB_SEND = 0, CTB_RECV = 1 }; enum { CTB_OWNER_HOST = 0 }; +static void ct_worker_func(struct work_struct *w); + void intel_guc_ct_init_early(struct intel_guc_ct *ct) { /* we're using static channel owners */ @@ -43,6 +50,8 @@ void intel_guc_ct_init_early(struct intel_guc_ct *ct) spin_lock_init(&ct->lock); INIT_LIST_HEAD(&ct->pending_requests); + INIT_LIST_HEAD(&ct->incoming_requests); + INIT_WORK(&ct->worker, ct_worker_func); } static inline const char *guc_ct_buffer_type_to_str(u32 type) @@ -600,13 +609,76 @@ static int guc_handle_response(struct intel_guc *guc, const u32 *data) static int guc_handle_request(struct intel_guc *guc, const u32 *data) { u32 header = data[0]; + u32 len = ct_header_get_len(header) + 1; /* total len with header */ + struct ct_incoming_request *request; + unsigned long flags; GEM_BUG_ON(ct_header_is_response(header)); /* data layout beyond header is request specific */ + request = kmalloc(sizeof(*request), GFP_ATOMIC); + if (unlikely(!request)) { + DRM_ERROR("CT: dropping request %*phn\n", 4*len, data); + return 0; /* XXX: -ENOMEM ? */ + } + + GEM_BUG_ON(len > GUC_CT_MSG_LEN_MASK + 1); + memcpy(request->data, data, 4*len); + + spin_lock_irqsave(&guc->ct.lock, flags); + list_add_tail(&request->link, &guc->ct.incoming_requests); + spin_unlock_irqrestore(&guc->ct.lock, flags); + + queue_work(system_unbound_wq, &guc->ct.worker); return 0; } +static bool guc_process_incoming_requests(struct intel_guc *guc) +{ + unsigned long flags; + struct ct_incoming_request *request; + bool done; + u32 header; + u32 action; + u32 len; + + spin_lock_irqsave(&guc->ct.lock, flags); + request = list_first_entry_or_null(&guc->ct.incoming_requests, + struct ct_incoming_request, link); + if (request) + list_del(&request->link); + done = !!list_empty(&guc->ct.incoming_requests); + spin_unlock_irqrestore(&guc->ct.lock, flags); + + if (!request) + return true; + + header = request->data[0]; + action = ct_header_get_action(header); + len = ct_header_get_len(header) + 1; /* also count header dw */ + + switch (action) { + default: + DRM_ERROR("CT: unexpected request %*phn\n", + 4*len, request->data); + break; + } + + kfree(request); + return done; +} + +static void ct_worker_func(struct work_struct *w) +{ + struct intel_guc_ct *ct = container_of(w, struct intel_guc_ct, worker); + struct intel_guc *guc = container_of(ct, struct intel_guc, ct); + bool done; + + done = guc_process_incoming_requests(guc); + if (!done) + queue_work(system_unbound_wq, &ct->worker); +} + static void intel_guc_receive_ct(struct intel_guc *guc) { struct intel_guc_ct_channel *ctch = &guc->ct.host_channel; diff --git a/drivers/gpu/drm/i915/intel_guc_ct.h b/drivers/gpu/drm/i915/intel_guc_ct.h index 557c1e8..125e004 100644 --- a/drivers/gpu/drm/i915/intel_guc_ct.h +++ b/drivers/gpu/drm/i915/intel_guc_ct.h @@ -73,6 +73,8 @@ struct intel_guc_ct_channel { * @host_channel: main channel used by the host * @lock: spin lock for pending requests list * @pending_requests: list of pending requests + * @incoming_requests: list of incoming requests + * @tasklet: tasklet for handling incoming requests */ struct intel_guc_ct { struct intel_guc_ct_channel host_channel; @@ -80,6 +82,8 @@ struct intel_guc_ct { spinlock_t lock; struct list_head pending_requests; + struct list_head incoming_requests; + struct work_struct worker; }; void intel_guc_ct_init_early(struct intel_guc_ct *ct);