From patchwork Fri Jul 26 09:32:15 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Katsuya MATSUBARA X-Patchwork-Id: 19411 X-Patchwork-Delegate: laurent.pinchart@ideasonboard.com Received: from mail.tu-berlin.de ([130.149.7.33]) by www.linuxtv.org with esmtp (Exim 4.72) (envelope-from ) id 1V2eOl-0003Dz-5I; Fri, 26 Jul 2013 11:33:19 +0200 X-tubIT-Incoming-IP: 209.132.180.67 Received: from vger.kernel.org ([209.132.180.67]) by mail.tu-berlin.de (exim-4.72/mailfrontend-5) with esmtp id 1V2eOi-0005j4-95; Fri, 26 Jul 2013 11:33:19 +0200 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753400Ab3GZJdM (ORCPT + 1 other); Fri, 26 Jul 2013 05:33:12 -0400 Received: from mail-pd0-f176.google.com ([209.85.192.176]:34980 "EHLO mail-pd0-f176.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756307Ab3GZJdH (ORCPT ); Fri, 26 Jul 2013 05:33:07 -0400 Received: by mail-pd0-f176.google.com with SMTP id 14so1417765pdc.7 for ; Fri, 26 Jul 2013 02:33:07 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :x-gm-message-state; bh=I2shRBKsGGWMfomlC6JbtlNNGsI8hoS3yo0cqgcdU1g=; b=nUbUF87yKbVsmgHxkzCy2+wAXkohlWiSnUGjHjz7PSIv/J03PvkTinHDv1KjLak/pb IdArKnXD8Ls88348j2dQuSSIl1pKArxY5w3kT3BtrJwWQyl0fUKDx55iOKQqOpfL1eRH vQoaLZ/zy+HtSzcs3HKZ73RouvhbYHhEQhPoLpEw6ct9E1MOLtbq+5g0EQJOkMZGzNL6 FvyrB+JttlmZu/Fe2yg3LnYOT1krm9q6GQ3HrOJLO2RX5/LsDZUFbJYAaFFw2qHWTNQa kGyounX4Jku+HptkJ/6y7hEXjQekBYKIxFE995HsGOVxsHi6Q42lqcFHxLrwolO29Qtx T13A== X-Received: by 10.68.130.163 with SMTP id of3mr12744263pbb.181.1374831186967; Fri, 26 Jul 2013 02:33:06 -0700 (PDT) Received: from kiefer.hq.igel.co.jp ([219.106.231.132]) by mx.google.com with ESMTPSA id ot4sm2578248pac.17.2013.07.26.02.33.04 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 26 Jul 2013 02:33:06 -0700 (PDT) From: Katsuya Matsubara To: Laurent Pinchart Cc: linux-media@vger.kernel.org, linux-sh@vger.kernel.org, Hans Verkuil , Sakari Ailus , Sylwester Nawrocki , Katsuya Matsubara Subject: [PATCH 5/7] [media] vsp1: Introduce bit operations for the DPR route registers Date: Fri, 26 Jul 2013 18:32:15 +0900 Message-Id: <1374831137-9219-6-git-send-email-matsu@igel.co.jp> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1374831137-9219-1-git-send-email-matsu@igel.co.jp> References: <1374831137-9219-1-git-send-email-matsu@igel.co.jp> X-Gm-Message-State: ALoCoQmv4R6VhMgKSrHEazhqbhrWESw0HaEl8irqUJQfiMPMymtTNl8hPuk+30/ujhPD2s1vk4Ju Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-PMX-Version: 6.0.0.2142326, Antispam-Engine: 2.7.2.2107409, Antispam-Data: 2013.7.26.92426 X-PMX-Spam: Gauge=IIIIIIIII, Probability=9%, Report=' MULTIPLE_RCPTS 0.1, HTML_00_01 0.05, HTML_00_10 0.05, LINES_OF_YELLING_3 0.05, URI_ENDS_IN_HTML 0, __ANY_URI 0, __CP_MEDIA_BODY 0, __CP_URI_IN_BODY 0, __HAS_FROM 0, __HAS_MSGID 0, __HAS_X_MAILER 0, __HAS_X_MAILING_LIST 0, __IN_REP_TO 0, __LINES_OF_YELLING 0, __MIME_TEXT_ONLY 0, __MULTIPLE_RCPTS_CC_X2 0, __SANE_MSGID 0, __SUBJ_ALPHA_END 0, __TO_MALFORMED_2 0, __URI_NO_WWW 0, __URI_NS , __YOUTUBE_RCVD 0' This change allows support for H/W IPs in which multiple DPR route registers are combined into one. Signed-off-by: Katsuya Matsubara --- drivers/media/platform/vsp1/vsp1.h | 1 + drivers/media/platform/vsp1/vsp1_drv.c | 94 +++++++++++++++++++----------- drivers/media/platform/vsp1/vsp1_video.c | 23 +++++--- 3 files changed, 77 insertions(+), 41 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h index 4d9b6c8..31c24a3 100644 --- a/drivers/media/platform/vsp1/vsp1.h +++ b/drivers/media/platform/vsp1/vsp1.h @@ -39,6 +39,7 @@ struct vsp1_uds; struct vsp1_dpr_route { unsigned int id; int reg; + int shift; }; struct vsp1_device { diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c index 920edb1..ca05431 100644 --- a/drivers/media/platform/vsp1/vsp1_drv.c +++ b/drivers/media/platform/vsp1/vsp1_drv.c @@ -240,6 +240,7 @@ static void vsp1_device_init(struct vsp1_device *vsp1) unsigned int i; u32 status; u32 route_unused = vsp1->routes[VI6_DPR_NODE_UNUSED].id; + u32 val; /* Reset any channel that might be running. */ status = vsp1_read(vsp1, VI6_STATUS); @@ -266,18 +267,43 @@ static void vsp1_device_init(struct vsp1_device *vsp1) vsp1_write(vsp1, VI6_CLK_DCSWT, (8 << VI6_CLK_DCSWT_CSTPW_SHIFT) | (8 << VI6_CLK_DCSWT_CSTRW_SHIFT)); - for (i = 0; i < vsp1->pdata->rpf_count; ++i) - vsp1_write(vsp1, VI6_DPR_RPF_ROUTE0 + i, route_unused); + for (i = 0; i < vsp1->pdata->rpf_count; ++i) { + val = vsp1_read(vsp1, VI6_DPR_RPF_ROUTE0 + i); + val |= route_unused + << vsp1->routes[VI6_DPR_NODE_RPF0 + i].shift; + vsp1_write(vsp1, VI6_DPR_RPF_ROUTE0 + i, val); + } + + for (i = 0; i < vsp1->pdata->uds_count; ++i) { + val = vsp1_read(vsp1, VI6_DPR_UDS_ROUTE0 + i); + val |= route_unused + << vsp1->routes[VI6_DPR_NODE_UDS0 + i].shift; + vsp1_write(vsp1, VI6_DPR_UDS_ROUTE0 + i, val); + } + + val = vsp1_read(vsp1, VI6_DPR_SRU_ROUTE); + val |= route_unused << vsp1->routes[VI6_DPR_NODE_SRU].shift; + vsp1_write(vsp1, VI6_DPR_SRU_ROUTE, val); + + val = vsp1_read(vsp1, VI6_DPR_LUT_ROUTE); + val |= route_unused << vsp1->routes[VI6_DPR_NODE_LUT].shift; + vsp1_write(vsp1, VI6_DPR_LUT_ROUTE, val); + + val = vsp1_read(vsp1, VI6_DPR_CLU_ROUTE); + val |= route_unused << vsp1->routes[VI6_DPR_NODE_CLU].shift; + vsp1_write(vsp1, VI6_DPR_CLU_ROUTE, val); + + val = vsp1_read(vsp1, VI6_DPR_HST_ROUTE); + val |= route_unused << vsp1->routes[VI6_DPR_NODE_HST].shift; + vsp1_write(vsp1, VI6_DPR_HST_ROUTE, val); - for (i = 0; i < vsp1->pdata->uds_count; ++i) - vsp1_write(vsp1, VI6_DPR_UDS_ROUTE0 + i, route_unused); + val = vsp1_read(vsp1, VI6_DPR_HSI_ROUTE); + val |= route_unused << vsp1->routes[VI6_DPR_NODE_HSI].shift; + vsp1_write(vsp1, VI6_DPR_HSI_ROUTE, val); - vsp1_write(vsp1, VI6_DPR_SRU_ROUTE, route_unused); - vsp1_write(vsp1, VI6_DPR_LUT_ROUTE, route_unused); - vsp1_write(vsp1, VI6_DPR_CLU_ROUTE, route_unused); - vsp1_write(vsp1, VI6_DPR_HST_ROUTE, route_unused); - vsp1_write(vsp1, VI6_DPR_HSI_ROUTE, route_unused); - vsp1_write(vsp1, VI6_DPR_BRU_ROUTE, route_unused); + val = vsp1_read(vsp1, VI6_DPR_BRU_ROUTE); + val |= route_unused << vsp1->routes[VI6_DPR_NODE_BRU_OUT].shift; + vsp1_write(vsp1, VI6_DPR_BRU_ROUTE, val); vsp1_write(vsp1, VI6_DPR_HGO_SMPPT, (7 << VI6_DPR_SMPPT_TGW_SHIFT) | (route_unused << VI6_DPR_SMPPT_PT_SHIFT)); @@ -590,30 +616,30 @@ static const unsigned int vsp1_reg_offs[] = { }; static const struct vsp1_dpr_route vsp1_routes[] = { - [VI6_DPR_NODE_RPF0] = { 0, VI6_DPR_RPF_ROUTE0 }, - [VI6_DPR_NODE_RPF1] = { 1, VI6_DPR_RPF_ROUTE0 + 1 }, - [VI6_DPR_NODE_RPF2] = { 2, VI6_DPR_RPF_ROUTE0 + 2 }, - [VI6_DPR_NODE_RPF3] = { 3, VI6_DPR_RPF_ROUTE0 + 3 }, - [VI6_DPR_NODE_RPF4] = { 4, VI6_DPR_RPF_ROUTE0 + 4 }, - [VI6_DPR_NODE_SRU] = { 16, VI6_DPR_SRU_ROUTE }, - [VI6_DPR_NODE_UDS0] = { 17, VI6_DPR_UDS_ROUTE0 }, - [VI6_DPR_NODE_UDS1] = { 18, VI6_DPR_UDS_ROUTE0 + 1 }, - [VI6_DPR_NODE_UDS2] = { 19, VI6_DPR_UDS_ROUTE0 + 2 }, - [VI6_DPR_NODE_LUT] = { 22, VI6_DPR_LUT_ROUTE }, - [VI6_DPR_NODE_BRU_IN0] = { 23, 0 }, - [VI6_DPR_NODE_BRU_IN1] = { 24, 0 }, - [VI6_DPR_NODE_BRU_IN2] = { 25, 0 }, - [VI6_DPR_NODE_BRU_IN3] = { 26, 0 }, - [VI6_DPR_NODE_BRU_OUT] = { 27, VI6_DPR_BRU_ROUTE }, - [VI6_DPR_NODE_CLU] = { 29, VI6_DPR_CLU_ROUTE }, - [VI6_DPR_NODE_HST] = { 30, VI6_DPR_HST_ROUTE }, - [VI6_DPR_NODE_HSI] = { 31, VI6_DPR_HSI_ROUTE }, - [VI6_DPR_NODE_LIF] = { 55, 0 }, - [VI6_DPR_NODE_WPF0] = { 56, 0 }, - [VI6_DPR_NODE_WPF1] = { 57, 0 }, - [VI6_DPR_NODE_WPF2] = { 58, 0 }, - [VI6_DPR_NODE_WPF3] = { 59, 0 }, - [VI6_DPR_NODE_UNUSED] = { 63, 0 }, + [VI6_DPR_NODE_RPF0] = { 0, VI6_DPR_RPF_ROUTE0, 0 }, + [VI6_DPR_NODE_RPF1] = { 1, VI6_DPR_RPF_ROUTE0 + 1, 0 }, + [VI6_DPR_NODE_RPF2] = { 2, VI6_DPR_RPF_ROUTE0 + 2, 0 }, + [VI6_DPR_NODE_RPF3] = { 3, VI6_DPR_RPF_ROUTE0 + 3, 0 }, + [VI6_DPR_NODE_RPF4] = { 4, VI6_DPR_RPF_ROUTE0 + 4, 0 }, + [VI6_DPR_NODE_SRU] = { 16, VI6_DPR_SRU_ROUTE, 0 }, + [VI6_DPR_NODE_UDS0] = { 17, VI6_DPR_UDS_ROUTE0, 0 }, + [VI6_DPR_NODE_UDS1] = { 18, VI6_DPR_UDS_ROUTE0 + 1, 0 }, + [VI6_DPR_NODE_UDS2] = { 19, VI6_DPR_UDS_ROUTE0 + 2, 0 }, + [VI6_DPR_NODE_LUT] = { 22, VI6_DPR_LUT_ROUTE, 0 }, + [VI6_DPR_NODE_BRU_IN0] = { 23, 0, 0 }, + [VI6_DPR_NODE_BRU_IN1] = { 24, 0, 0 }, + [VI6_DPR_NODE_BRU_IN2] = { 25, 0, 0 }, + [VI6_DPR_NODE_BRU_IN3] = { 26, 0, 0 }, + [VI6_DPR_NODE_BRU_OUT] = { 27, VI6_DPR_BRU_ROUTE, 0 }, + [VI6_DPR_NODE_CLU] = { 29, VI6_DPR_CLU_ROUTE, 0 }, + [VI6_DPR_NODE_HST] = { 30, VI6_DPR_HST_ROUTE, 0 }, + [VI6_DPR_NODE_HSI] = { 31, VI6_DPR_HSI_ROUTE, 0 }, + [VI6_DPR_NODE_LIF] = { 55, 0, 0 }, + [VI6_DPR_NODE_WPF0] = { 56, 0, 0 }, + [VI6_DPR_NODE_WPF1] = { 57, 0, 0 }, + [VI6_DPR_NODE_WPF2] = { 58, 0, 0 }, + [VI6_DPR_NODE_WPF3] = { 59, 0, 0 }, + [VI6_DPR_NODE_UNUSED] = { 63, 0, 0 }, }; static int vsp1_probe(struct platform_device *pdev) diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index aa71ba8..304a809 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -370,11 +370,16 @@ static int vsp1_pipeline_stop(struct vsp1_pipeline *pipe) list_for_each_entry(entity, &pipe->entities, list_pipe) { const struct vsp1_dpr_route *routes = entity->vsp1->routes; + int route_index = entity->route_index; - if (routes[entity->route_index].reg) - vsp1_write(entity->vsp1, - routes[entity->route_index].reg, - routes[VI6_DPR_NODE_UNUSED].id); + if (routes[route_index].reg) { + u32 val; + + val = vsp1_read(entity->vsp1, routes[route_index].reg); + val |= routes[VI6_DPR_NODE_UNUSED].id + << routes[route_index].shift; + vsp1_write(entity->vsp1, routes[route_index].reg, val); + } v4l2_subdev_call(&entity->subdev, video, s_stream, 0); } @@ -573,13 +578,17 @@ static void vsp1_entity_route_setup(struct vsp1_entity *source) { struct vsp1_entity *sink; const struct vsp1_dpr_route *routes = source->vsp1->routes; + int route_index = source->route_index; + u32 val; - if (routes[source->route_index].reg == 0) + if (routes[route_index].reg == 0) return; sink = container_of(source->sink, struct vsp1_entity, subdev.entity); - vsp1_write(source->vsp1, routes[source->route_index].reg, - routes[sink->route_index].id); + val = vsp1_read(source->vsp1, routes[route_index].reg); + val &= ~(routes[VI6_DPR_NODE_UNUSED].id << routes[route_index].shift); + val |= routes[sink->route_index].id << routes[route_index].shift; + vsp1_write(source->vsp1, routes[route_index].reg, val); } static int vsp1_video_start_streaming(struct vb2_queue *vq, unsigned int count)