From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5EEC0C433E1 for ; Fri, 14 Aug 2020 07:26:47 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 1412120639 for ; Fri, 14 Aug 2020 07:26:47 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="cL/VMxLb"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="ZL67253B" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1412120639 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-ID:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=fyBrsvJ1TohOzPH8l0Nh9ARkViS6f1AN9RGWlA7y/ho=; b=cL/VMxLbo5IX08gqTCC4c0zqM o1FdJRHpD7Xg+QF9QqgTiLuipcjnAieL2lhzQAZqCEC3c7dmhPbGIIhG0NUxkb642H7fUa7++BTOc 7HcEkzFQ7BwXaryD0xhfn8NKdL+gkPO2aup0nQzWkuDhVHdtSNqOrVi/ihG8C9Nkk1G5CsfsPjGyL iqwMh3TN+kCP25fPRa/E3pbWVKCknpBU2A/AOECt3IBY5PQyPQPG8VkbXsIoUDwyUEECL/+Wb5Yg/ hEFr5EnQv0TEt/2/SDOrb6KKC2/TPiRyZVj7R6sguMXYYLNwQox1o20utSx22fHJo2rNDVbIcy8+z haCpX+Vlg==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1k6U6i-0005HJ-Lf; Fri, 14 Aug 2020 07:26:32 +0000 Received: from mailgw02.mediatek.com ([216.200.240.185]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1k6U3i-0003N2-Qm; Fri, 14 Aug 2020 07:23:38 +0000 X-UUID: 5ae5ff5620e54cad887e6f7ed530c82d-20200813 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=rKRkfrldeTMdwzNxOIDH+OtOLPDraRIgEh2l5wXR8XI=; b=ZL67253BG4FitSXufxtwqCoZz8zxcDJkBGf1GBIrFNd6DwoD3WV3OIZTFD3hfcEo0Y3ZrcJBowo3VfCBarvnzhfqXO19VWxQv448ROeWAX87/xz7By5ce3qq4iTQuKEkkytTO+CpAhqN+VecIvMlqskLJOOGI7MFgYEJZ917Bck=; X-UUID: 5ae5ff5620e54cad887e6f7ed530c82d-20200813 Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by mailgw02.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLS) with ESMTP id 996701782; Thu, 13 Aug 2020 23:23:11 -0800 Received: from MTKMBS07N2.mediatek.inc (172.21.101.141) by MTKMBS62N2.mediatek.inc (172.29.193.42) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 14 Aug 2020 00:13:43 -0700 Received: from mtkcas08.mediatek.inc (172.21.101.126) by mtkmbs07n2.mediatek.inc (172.21.101.141) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 14 Aug 2020 15:13:38 +0800 Received: from localhost.localdomain (10.17.3.153) by mtkcas08.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Fri, 14 Aug 2020 15:13:37 +0800 From: Xia Jiang To: Hans Verkuil , Mauro Carvalho Chehab , Rob Herring , "Matthias Brugger" , Rick Chang Subject: [PATCH v12 29/29] media: platform: Add jpeg enc feature Date: Fri, 14 Aug 2020 15:12:02 +0800 Message-ID: <20200814071202.25067-31-xia.jiang@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20200814071202.25067-1-xia.jiang@mediatek.com> References: <20200814071202.25067-1-xia.jiang@mediatek.com> MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200814_032328_174018_C6C4F4E0 X-CRM114-Status: GOOD ( 22.73 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: maoguang.meng@mediatek.com, devicetree@vger.kernel.org, mojahsu@chromium.org, srv_heupstream@mediatek.com, linux-kernel@vger.kernel.org, Tomasz Figa , senozhatsky@chromium.org, drinkcat@chromium.org, linux-mediatek@lists.infradead.org, Xia Jiang , linux-media@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Marek Szyprowski Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org Add mtk jpeg encode v4l2 driver based on jpeg decode, because that jpeg decode and encode have great similarities with function operation. Reviewed-by: Tomasz Figa Signed-off-by: Xia Jiang --- v12: fix the compile warnings --- drivers/media/platform/mtk-jpeg/Makefile | 5 +- .../media/platform/mtk-jpeg/mtk_jpeg_core.c | 350 +++++++++++++++++- .../media/platform/mtk-jpeg/mtk_jpeg_core.h | 15 + .../media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c | 154 ++++++++ .../media/platform/mtk-jpeg/mtk_jpeg_enc_hw.h | 91 +++++ 5 files changed, 611 insertions(+), 4 deletions(-) create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.h diff --git a/drivers/media/platform/mtk-jpeg/Makefile b/drivers/media/platform/mtk-jpeg/Makefile index 48516dcf96e6..76c33aad0f3f 100644 --- a/drivers/media/platform/mtk-jpeg/Makefile +++ b/drivers/media/platform/mtk-jpeg/Makefile @@ -1,3 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only -mtk_jpeg-objs := mtk_jpeg_core.o mtk_jpeg_dec_hw.o mtk_jpeg_dec_parse.o +mtk_jpeg-objs := mtk_jpeg_core.o \ + mtk_jpeg_dec_hw.o \ + mtk_jpeg_dec_parse.o \ + mtk_jpeg_enc_hw.o obj-$(CONFIG_VIDEO_MEDIATEK_JPEG) += mtk_jpeg.o diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c index 3d95c7f0a22d..8d6d324ab113 100644 --- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c @@ -3,6 +3,7 @@ * Copyright (c) 2016 MediaTek Inc. * Author: Ming Hsiu Tsai * Rick Chang + * Xia Jiang */ #include @@ -23,10 +24,59 @@ #include #include +#include "mtk_jpeg_enc_hw.h" #include "mtk_jpeg_dec_hw.h" #include "mtk_jpeg_core.h" #include "mtk_jpeg_dec_parse.h" +static struct mtk_jpeg_fmt mtk_jpeg_enc_formats[] = { + { + .fourcc = V4L2_PIX_FMT_JPEG, + .colplanes = 1, + .flags = MTK_JPEG_FMT_FLAG_CAPTURE, + }, + { + .fourcc = V4L2_PIX_FMT_NV12M, + .hw_format = JPEG_ENC_YUV_FORMAT_NV12, + .h_sample = {4, 4}, + .v_sample = {4, 2}, + .colplanes = 2, + .h_align = 4, + .v_align = 4, + .flags = MTK_JPEG_FMT_FLAG_OUTPUT, + }, + { + .fourcc = V4L2_PIX_FMT_NV21M, + .hw_format = JEPG_ENC_YUV_FORMAT_NV21, + .h_sample = {4, 4}, + .v_sample = {4, 2}, + .colplanes = 2, + .h_align = 4, + .v_align = 4, + .flags = MTK_JPEG_FMT_FLAG_OUTPUT, + }, + { + .fourcc = V4L2_PIX_FMT_YUYV, + .hw_format = JPEG_ENC_YUV_FORMAT_YUYV, + .h_sample = {8}, + .v_sample = {4}, + .colplanes = 1, + .h_align = 5, + .v_align = 3, + .flags = MTK_JPEG_FMT_FLAG_OUTPUT, + }, + { + .fourcc = V4L2_PIX_FMT_YVYU, + .hw_format = JPEG_ENC_YUV_FORMAT_YVYU, + .h_sample = {8}, + .v_sample = {4}, + .colplanes = 1, + .h_align = 5, + .v_align = 3, + .flags = MTK_JPEG_FMT_FLAG_OUTPUT, + }, +}; + static struct mtk_jpeg_fmt mtk_jpeg_dec_formats[] = { { .fourcc = V4L2_PIX_FMT_JPEG, @@ -53,6 +103,7 @@ static struct mtk_jpeg_fmt mtk_jpeg_dec_formats[] = { }, }; +#define MTK_JPEG_ENC_NUM_FORMATS ARRAY_SIZE(mtk_jpeg_enc_formats) #define MTK_JPEG_DEC_NUM_FORMATS ARRAY_SIZE(mtk_jpeg_dec_formats) struct mtk_jpeg_src_buf { @@ -64,6 +115,11 @@ struct mtk_jpeg_src_buf { static int debug; module_param(debug, int, 0644); +static inline struct mtk_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *ctrl) +{ + return container_of(ctrl->handler, struct mtk_jpeg_ctx, ctrl_hdl); +} + static inline struct mtk_jpeg_ctx *mtk_jpeg_fh_to_ctx(struct v4l2_fh *fh) { return container_of(fh, struct mtk_jpeg_ctx, fh); @@ -88,6 +144,53 @@ static int mtk_jpeg_querycap(struct file *file, void *priv, return 0; } +static int vidioc_jpeg_enc_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct mtk_jpeg_ctx *ctx = ctrl_to_ctx(ctrl); + + switch (ctrl->id) { + case V4L2_CID_JPEG_RESTART_INTERVAL: + ctx->restart_interval = ctrl->val; + break; + case V4L2_CID_JPEG_COMPRESSION_QUALITY: + ctx->enc_quality = ctrl->val; + break; + case V4L2_CID_JPEG_ACTIVE_MARKER: + ctx->enable_exif = ctrl->val & V4L2_JPEG_ACTIVE_MARKER_APP1; + break; + } + + return 0; +} + +static const struct v4l2_ctrl_ops mtk_jpeg_enc_ctrl_ops = { + .s_ctrl = vidioc_jpeg_enc_s_ctrl, +}; + +static int mtk_jpeg_enc_ctrls_setup(struct mtk_jpeg_ctx *ctx) +{ + const struct v4l2_ctrl_ops *ops = &mtk_jpeg_enc_ctrl_ops; + struct v4l2_ctrl_handler *handler = &ctx->ctrl_hdl; + + v4l2_ctrl_handler_init(handler, 3); + + v4l2_ctrl_new_std(handler, ops, V4L2_CID_JPEG_RESTART_INTERVAL, 0, 100, + 1, 0); + v4l2_ctrl_new_std(handler, ops, V4L2_CID_JPEG_COMPRESSION_QUALITY, 48, + 100, 1, 90); + v4l2_ctrl_new_std(handler, ops, V4L2_CID_JPEG_ACTIVE_MARKER, 0, + V4L2_JPEG_ACTIVE_MARKER_APP1, 0, 0); + + if (handler->error) { + v4l2_ctrl_handler_free(&ctx->ctrl_hdl); + return handler->error; + } + + v4l2_ctrl_handler_setup(&ctx->ctrl_hdl); + + return 0; +} + static int mtk_jpeg_enum_fmt(struct mtk_jpeg_fmt *mtk_jpeg_formats, int n, struct v4l2_fmtdesc *f, u32 type) { @@ -331,6 +434,8 @@ static int mtk_jpeg_s_fmt_mplane(struct mtk_jpeg_ctx *ctx, pix_mp->pixelformat, fmt_type); q_data->pix_mp.width = pix_mp->width; q_data->pix_mp.height = pix_mp->height; + q_data->enc_crop_rect.width = pix_mp->width; + q_data->enc_crop_rect.height = pix_mp->height; q_data->pix_mp.colorspace = V4L2_COLORSPACE_SRGB; q_data->pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_601; q_data->pix_mp.xfer_func = V4L2_XFER_FUNC_SRGB; @@ -407,6 +512,31 @@ static int mtk_jpeg_subscribe_event(struct v4l2_fh *fh, return v4l2_ctrl_subscribe_event(fh, sub); } +static int mtk_jpeg_enc_g_selection(struct file *file, void *priv, + struct v4l2_selection *s) +{ + struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv); + + if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) + return -EINVAL; + + switch (s->target) { + case V4L2_SEL_TGT_CROP: + s->r = ctx->out_q.enc_crop_rect; + break; + case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SEL_TGT_CROP_DEFAULT: + s->r.width = ctx->out_q.pix_mp.width; + s->r.height = ctx->out_q.pix_mp.height; + s->r.left = 0; + s->r.top = 0; + break; + default: + return -EINVAL; + } + return 0; +} + static int mtk_jpeg_dec_g_selection(struct file *file, void *priv, struct v4l2_selection *s) { @@ -436,6 +566,56 @@ static int mtk_jpeg_dec_g_selection(struct file *file, void *priv, return 0; } +static int mtk_jpeg_enc_s_selection(struct file *file, void *priv, + struct v4l2_selection *s) +{ + struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv); + + if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) + return -EINVAL; + + switch (s->target) { + case V4L2_SEL_TGT_CROP: + s->r.left = 0; + s->r.top = 0; + s->r.width = min(s->r.width, ctx->out_q.pix_mp.width); + s->r.height = min(s->r.height, ctx->out_q.pix_mp.height); + ctx->out_q.enc_crop_rect = s->r; + break; + default: + return -EINVAL; + } + + return 0; +} + +static const struct v4l2_ioctl_ops mtk_jpeg_enc_ioctl_ops = { + .vidioc_querycap = mtk_jpeg_querycap, + .vidioc_enum_fmt_vid_cap = mtk_jpeg_enum_fmt_vid_cap, + .vidioc_enum_fmt_vid_out = mtk_jpeg_enum_fmt_vid_out, + .vidioc_try_fmt_vid_cap_mplane = mtk_jpeg_try_fmt_vid_cap_mplane, + .vidioc_try_fmt_vid_out_mplane = mtk_jpeg_try_fmt_vid_out_mplane, + .vidioc_g_fmt_vid_cap_mplane = mtk_jpeg_g_fmt_vid_mplane, + .vidioc_g_fmt_vid_out_mplane = mtk_jpeg_g_fmt_vid_mplane, + .vidioc_s_fmt_vid_cap_mplane = mtk_jpeg_s_fmt_vid_cap_mplane, + .vidioc_s_fmt_vid_out_mplane = mtk_jpeg_s_fmt_vid_out_mplane, + .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, + .vidioc_subscribe_event = mtk_jpeg_subscribe_event, + .vidioc_g_selection = mtk_jpeg_enc_g_selection, + .vidioc_s_selection = mtk_jpeg_enc_s_selection, + + .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, + .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, + .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, + .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, + .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, + .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, + .vidioc_streamon = v4l2_m2m_ioctl_streamon, + .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, + + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, +}; + static const struct v4l2_ioctl_ops mtk_jpeg_dec_ioctl_ops = { .vidioc_querycap = mtk_jpeg_querycap, .vidioc_enum_fmt_vid_cap = mtk_jpeg_enum_fmt_vid_cap, @@ -501,15 +681,22 @@ static int mtk_jpeg_buf_prepare(struct vb2_buffer *vb) { struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); struct mtk_jpeg_q_data *q_data = NULL; + struct v4l2_plane_pix_format plane_fmt = {}; int i; q_data = mtk_jpeg_get_q_data(ctx, vb->vb2_queue->type); if (!q_data) return -EINVAL; - for (i = 0; i < q_data->fmt->colplanes; i++) - vb2_set_plane_payload(vb, i, - q_data->pix_mp.plane_fmt[i].sizeimage); + for (i = 0; i < q_data->fmt->colplanes; i++) { + plane_fmt = q_data->pix_mp.plane_fmt[i]; + if (ctx->enable_exif && + q_data->fmt->fourcc == V4L2_PIX_FMT_JPEG) + vb2_set_plane_payload(vb, i, plane_fmt.sizeimage + + MTK_JPEG_MAX_EXIF_SIZE); + else + vb2_set_plane_payload(vb, i, plane_fmt.sizeimage); + } return 0; } @@ -572,6 +759,17 @@ static void mtk_jpeg_set_queue_data(struct mtk_jpeg_ctx *ctx, param->dec_w, param->dec_h); } +static void mtk_jpeg_enc_buf_queue(struct vb2_buffer *vb) +{ + struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + struct mtk_jpeg_dev *jpeg = ctx->jpeg; + + v4l2_dbg(2, debug, &jpeg->v4l2_dev, "(%d) buf_q id=%d, vb=%p\n", + vb->vb2_queue->type, vb->index, vb); + + v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, to_vb2_v4l2_buffer(vb)); +} + static void mtk_jpeg_dec_buf_queue(struct vb2_buffer *vb) { struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); @@ -620,6 +818,15 @@ static struct vb2_v4l2_buffer *mtk_jpeg_buf_remove(struct mtk_jpeg_ctx *ctx, return v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); } +static void mtk_jpeg_enc_stop_streaming(struct vb2_queue *q) +{ + struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q); + struct vb2_v4l2_buffer *vb; + + while ((vb = mtk_jpeg_buf_remove(ctx, q->type))) + v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR); +} + static void mtk_jpeg_dec_stop_streaming(struct vb2_queue *q) { struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q); @@ -655,6 +862,15 @@ static const struct vb2_ops mtk_jpeg_dec_qops = { .stop_streaming = mtk_jpeg_dec_stop_streaming, }; +static const struct vb2_ops mtk_jpeg_enc_qops = { + .queue_setup = mtk_jpeg_queue_setup, + .buf_prepare = mtk_jpeg_buf_prepare, + .buf_queue = mtk_jpeg_enc_buf_queue, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, + .stop_streaming = mtk_jpeg_enc_stop_streaming, +}; + static void mtk_jpeg_set_dec_src(struct mtk_jpeg_ctx *ctx, struct vb2_buffer *src_buf, struct mtk_jpeg_bs *bs) @@ -692,6 +908,48 @@ static int mtk_jpeg_set_dec_dst(struct mtk_jpeg_ctx *ctx, return 0; } +static void mtk_jpeg_enc_device_run(void *priv) +{ + struct mtk_jpeg_ctx *ctx = priv; + struct mtk_jpeg_dev *jpeg = ctx->jpeg; + struct vb2_v4l2_buffer *src_buf, *dst_buf; + enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR; + unsigned long flags; + int ret; + + src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); + dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); + + ret = pm_runtime_get_sync(jpeg->dev); + if (ret < 0) + goto enc_end; + + schedule_delayed_work(&jpeg->job_timeout_work, + msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC)); + + spin_lock_irqsave(&jpeg->hw_lock, flags); + + /* + * Resetting the hardware every frame is to ensure that all the + * registers are cleared. This is a hardware requirement. + */ + mtk_jpeg_enc_reset(jpeg->reg_base); + + mtk_jpeg_set_enc_src(ctx, jpeg->reg_base, &src_buf->vb2_buf); + mtk_jpeg_set_enc_dst(ctx, jpeg->reg_base, &dst_buf->vb2_buf); + mtk_jpeg_set_enc_params(ctx, jpeg->reg_base); + mtk_jpeg_enc_start(jpeg->reg_base); + spin_unlock_irqrestore(&jpeg->hw_lock, flags); + return; + +enc_end: + v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); + v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); + v4l2_m2m_buf_done(src_buf, buf_state); + v4l2_m2m_buf_done(dst_buf, buf_state); + v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); +} + static void mtk_jpeg_dec_device_run(void *priv) { struct mtk_jpeg_ctx *ctx = priv; @@ -750,6 +1008,10 @@ static int mtk_jpeg_dec_job_ready(void *priv) return (ctx->state == MTK_JPEG_RUNNING) ? 1 : 0; } +static const struct v4l2_m2m_ops mtk_jpeg_enc_m2m_ops = { + .device_run = mtk_jpeg_enc_device_run, +}; + static const struct v4l2_m2m_ops mtk_jpeg_dec_m2m_ops = { .device_run = mtk_jpeg_dec_device_run, .job_ready = mtk_jpeg_dec_job_ready, @@ -810,6 +1072,54 @@ static void mtk_jpeg_clk_off(struct mtk_jpeg_dev *jpeg) mtk_smi_larb_put(jpeg->larb); } +static irqreturn_t mtk_jpeg_enc_done(struct mtk_jpeg_dev *jpeg) +{ + struct mtk_jpeg_ctx *ctx; + struct vb2_v4l2_buffer *src_buf, *dst_buf; + enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR; + u32 result_size; + + ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev); + if (!ctx) { + v4l2_err(&jpeg->v4l2_dev, "Context is NULL\n"); + return IRQ_HANDLED; + } + + src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); + dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); + + result_size = mtk_jpeg_enc_get_file_size(jpeg->reg_base); + vb2_set_plane_payload(&dst_buf->vb2_buf, 0, result_size); + + buf_state = VB2_BUF_STATE_DONE; + + v4l2_m2m_buf_done(src_buf, buf_state); + v4l2_m2m_buf_done(dst_buf, buf_state); + v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); + pm_runtime_put(ctx->jpeg->dev); + return IRQ_HANDLED; +} + +static irqreturn_t mtk_jpeg_enc_irq(int irq, void *priv) +{ + struct mtk_jpeg_dev *jpeg = priv; + u32 irq_status; + irqreturn_t ret = IRQ_NONE; + + cancel_delayed_work(&jpeg->job_timeout_work); + + irq_status = readl(jpeg->reg_base + JPEG_ENC_INT_STS) & + JPEG_ENC_INT_STATUS_MASK_ALLIRQ; + if (irq_status) + writel(0, jpeg->reg_base + JPEG_ENC_INT_STS); + + if (!(irq_status & JPEG_ENC_INT_STATUS_DONE)) + return ret; + + ret = mtk_jpeg_enc_done(jpeg); + return ret; +} + static irqreturn_t mtk_jpeg_dec_irq(int irq, void *priv) { struct mtk_jpeg_dev *jpeg = priv; @@ -862,6 +1172,7 @@ static void mtk_jpeg_set_default_params(struct mtk_jpeg_ctx *ctx) struct mtk_jpeg_q_data *q = &ctx->out_q; struct mtk_jpeg_dev *jpeg = ctx->jpeg; + ctx->fh.ctrl_handler = &ctx->ctrl_hdl; q->pix_mp.colorspace = V4L2_COLORSPACE_SRGB; q->pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_601; q->pix_mp.quantization = V4L2_QUANTIZATION_FULL_RANGE; @@ -918,6 +1229,15 @@ static int mtk_jpeg_open(struct file *file) goto error; } + if (jpeg->variant->cap_q_default_fourcc == V4L2_PIX_FMT_JPEG) { + ret = mtk_jpeg_enc_ctrls_setup(ctx); + if (ret) { + v4l2_err(&jpeg->v4l2_dev, "Failed to setup jpeg enc controls\n"); + goto error; + } + } else { + v4l2_ctrl_handler_init(&ctx->ctrl_hdl, 0); + } mtk_jpeg_set_default_params(ctx); mutex_unlock(&jpeg->lock); return 0; @@ -938,6 +1258,7 @@ static int mtk_jpeg_release(struct file *file) mutex_lock(&jpeg->lock); v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); + v4l2_ctrl_handler_free(&ctx->ctrl_hdl); v4l2_fh_del(&ctx->fh); v4l2_fh_exit(&ctx->fh); kfree(ctx); @@ -959,6 +1280,10 @@ static struct clk_bulk_data mt8173_jpeg_dec_clocks[] = { { .id = "jpgdec" }, }; +static struct clk_bulk_data mtk_jpeg_clocks[] = { + { .id = "jpgenc" }, +}; + static int mtk_jpeg_clk_init(struct mtk_jpeg_dev *jpeg) { struct device_node *node; @@ -1190,6 +1515,21 @@ static const struct mtk_jpeg_variant mt8173_jpeg_drvdata = { .cap_q_default_fourcc = V4L2_PIX_FMT_YUV420M, }; +static const struct mtk_jpeg_variant mtk_jpeg_drvdata = { + .clks = mtk_jpeg_clocks, + .num_clks = ARRAY_SIZE(mtk_jpeg_clocks), + .formats = mtk_jpeg_enc_formats, + .num_formats = MTK_JPEG_ENC_NUM_FORMATS, + .qops = &mtk_jpeg_enc_qops, + .irq_handler = mtk_jpeg_enc_irq, + .hw_reset = mtk_jpeg_enc_reset, + .m2m_ops = &mtk_jpeg_enc_m2m_ops, + .dev_name = "mtk-jpeg-enc", + .ioctl_ops = &mtk_jpeg_enc_ioctl_ops, + .out_q_default_fourcc = V4L2_PIX_FMT_YUYV, + .cap_q_default_fourcc = V4L2_PIX_FMT_JPEG, +}; + static const struct of_device_id mtk_jpeg_match[] = { { .compatible = "mediatek,mt8173-jpgdec", @@ -1199,6 +1539,10 @@ static const struct of_device_id mtk_jpeg_match[] = { .compatible = "mediatek,mt2701-jpgdec", .data = &mt8173_jpeg_drvdata, }, + { + .compatible = "mediatek,mtk-jpgenc", + .data = &mtk_jpeg_drvdata, + }, {}, }; diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h index d11d366a247e..68e634f02e00 100644 --- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h @@ -3,6 +3,7 @@ * Copyright (c) 2016 MediaTek Inc. * Author: Ming Hsiu Tsai * Rick Chang + * Xia Jiang */ #ifndef _MTK_JPEG_CORE_H @@ -29,6 +30,8 @@ #define MTK_JPEG_HW_TIMEOUT_MSEC 1000 +#define MTK_JPEG_MAX_EXIF_SIZE (64 * 1024) + /** * enum mtk_jpeg_ctx_state - states of the context state machine * @MTK_JPEG_INIT: current state is initialized @@ -104,6 +107,7 @@ struct mtk_jpeg_dev { /** * struct jpeg_fmt - driver's internal color format data * @fourcc: the fourcc code, 0 if not applicable + * @hw_format: hardware format value * @h_sample: horizontal sample count of plane in 4 * 4 pixel image * @v_sample: vertical sample count of plane in 4 * 4 pixel image * @colplanes: number of color planes (1 for packed formats) @@ -113,6 +117,7 @@ struct mtk_jpeg_dev { */ struct mtk_jpeg_fmt { u32 fourcc; + u32 hw_format; int h_sample[VIDEO_MAX_PLANES]; int v_sample[VIDEO_MAX_PLANES]; int colplanes; @@ -125,10 +130,12 @@ struct mtk_jpeg_fmt { * mtk_jpeg_q_data - parameters of one queue * @fmt: driver-specific format of this queue * @pix_mp: multiplanar format + * @enc_crop_rect: jpeg encoder crop information */ struct mtk_jpeg_q_data { struct mtk_jpeg_fmt *fmt; struct v4l2_pix_format_mplane pix_mp; + struct v4l2_rect enc_crop_rect; }; /** @@ -138,6 +145,10 @@ struct mtk_jpeg_q_data { * @cap_q: destination (capture) queue queue information * @fh: V4L2 file handle * @state: state of the context + * @enable_exif: enable exif mode of jpeg encoder + * @enc_quality: jpeg encoder quality + * @restart_interval: jpeg encoder restart interval + * @ctrl_hdl: controls handler */ struct mtk_jpeg_ctx { struct mtk_jpeg_dev *jpeg; @@ -145,6 +156,10 @@ struct mtk_jpeg_ctx { struct mtk_jpeg_q_data cap_q; struct v4l2_fh fh; enum mtk_jpeg_ctx_state state; + bool enable_exif; + u8 enc_quality; + u8 restart_interval; + struct v4l2_ctrl_handler ctrl_hdl; }; #endif /* _MTK_JPEG_CORE_H */ diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c b/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c new file mode 100644 index 000000000000..1cf037bf72dd --- /dev/null +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2019 MediaTek Inc. + * Author: Xia Jiang + * + */ + +#include +#include +#include +#include + +#include "mtk_jpeg_enc_hw.h" + +static const struct mtk_jpeg_enc_qlt mtk_jpeg_enc_quality[] = { + {.quality_param = 34, .hardware_value = JPEG_ENC_QUALITY_Q34}, + {.quality_param = 39, .hardware_value = JPEG_ENC_QUALITY_Q39}, + {.quality_param = 48, .hardware_value = JPEG_ENC_QUALITY_Q48}, + {.quality_param = 60, .hardware_value = JPEG_ENC_QUALITY_Q60}, + {.quality_param = 64, .hardware_value = JPEG_ENC_QUALITY_Q64}, + {.quality_param = 68, .hardware_value = JPEG_ENC_QUALITY_Q68}, + {.quality_param = 74, .hardware_value = JPEG_ENC_QUALITY_Q74}, + {.quality_param = 80, .hardware_value = JPEG_ENC_QUALITY_Q80}, + {.quality_param = 82, .hardware_value = JPEG_ENC_QUALITY_Q82}, + {.quality_param = 84, .hardware_value = JPEG_ENC_QUALITY_Q84}, + {.quality_param = 87, .hardware_value = JPEG_ENC_QUALITY_Q87}, + {.quality_param = 90, .hardware_value = JPEG_ENC_QUALITY_Q90}, + {.quality_param = 92, .hardware_value = JPEG_ENC_QUALITY_Q92}, + {.quality_param = 95, .hardware_value = JPEG_ENC_QUALITY_Q95}, + {.quality_param = 97, .hardware_value = JPEG_ENC_QUALITY_Q97}, +}; + +void mtk_jpeg_enc_reset(void __iomem *base) +{ + writel(0, base + JPEG_ENC_RSTB); + writel(JPEG_ENC_RESET_BIT, base + JPEG_ENC_RSTB); + writel(0, base + JPEG_ENC_CODEC_SEL); +} + +u32 mtk_jpeg_enc_get_file_size(void __iomem *base) +{ + return readl(base + JPEG_ENC_DMA_ADDR0) - + readl(base + JPEG_ENC_DST_ADDR0); +} + +void mtk_jpeg_enc_start(void __iomem *base) +{ + u32 value; + + value = readl(base + JPEG_ENC_CTRL); + value |= JPEG_ENC_CTRL_INT_EN_BIT | JPEG_ENC_CTRL_ENABLE_BIT; + writel(value, base + JPEG_ENC_CTRL); +} + +void mtk_jpeg_set_enc_src(struct mtk_jpeg_ctx *ctx, void __iomem *base, + struct vb2_buffer *src_buf) +{ + int i; + dma_addr_t dma_addr; + + for (i = 0; i < src_buf->num_planes; i++) { + dma_addr = vb2_dma_contig_plane_dma_addr(src_buf, i) + + src_buf->planes[i].data_offset; + if (!i) + writel(dma_addr, base + JPEG_ENC_SRC_LUMA_ADDR); + else + writel(dma_addr, base + JPEG_ENC_SRC_CHROMA_ADDR); + } +} + +void mtk_jpeg_set_enc_dst(struct mtk_jpeg_ctx *ctx, void __iomem *base, + struct vb2_buffer *dst_buf) +{ + dma_addr_t dma_addr; + size_t size; + u32 dma_addr_offset; + u32 dma_addr_offsetmask; + + dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0); + dma_addr_offset = ctx->enable_exif ? MTK_JPEG_MAX_EXIF_SIZE : 0; + dma_addr_offsetmask = dma_addr & JPEG_ENC_DST_ADDR_OFFSET_MASK; + size = vb2_plane_size(dst_buf, 0); + + writel(dma_addr_offset & ~0xf, base + JPEG_ENC_OFFSET_ADDR); + writel(dma_addr_offsetmask & 0xf, base + JPEG_ENC_BYTE_OFFSET_MASK); + writel(dma_addr & ~0xf, base + JPEG_ENC_DST_ADDR0); + writel((dma_addr + size) & ~0xf, base + JPEG_ENC_STALL_ADDR0); +} + +void mtk_jpeg_set_enc_params(struct mtk_jpeg_ctx *ctx, void __iomem *base) +{ + u32 value; + u32 width = ctx->out_q.enc_crop_rect.width; + u32 height = ctx->out_q.enc_crop_rect.height; + u32 enc_format = ctx->out_q.fmt->fourcc; + u32 bytesperline = ctx->out_q.pix_mp.plane_fmt[0].bytesperline; + u32 blk_num; + u32 img_stride; + u32 mem_stride; + u32 i, enc_quality; + + value = width << 16 | height; + writel(value, base + JPEG_ENC_IMG_SIZE); + + if (enc_format == V4L2_PIX_FMT_NV12M || + enc_format == V4L2_PIX_FMT_NV21M) + /* + * Total 8 x 8 block number of luma and chroma. + * The number of blocks is counted from 0. + */ + blk_num = DIV_ROUND_UP(width, 16) * + DIV_ROUND_UP(height, 16) * 6 - 1; + else + blk_num = DIV_ROUND_UP(width, 16) * + DIV_ROUND_UP(height, 8) * 4 - 1; + writel(blk_num, base + JPEG_ENC_BLK_NUM); + + if (enc_format == V4L2_PIX_FMT_NV12M || + enc_format == V4L2_PIX_FMT_NV21M) { + /* 4:2:0 */ + img_stride = round_up(width, 16); + mem_stride = bytesperline; + } else { + /* 4:2:2 */ + img_stride = round_up(width * 2, 32); + mem_stride = img_stride; + } + writel(img_stride, base + JPEG_ENC_IMG_STRIDE); + writel(mem_stride, base + JPEG_ENC_STRIDE); + + enc_quality = mtk_jpeg_enc_quality[0].hardware_value; + for (i = 0; i < ARRAY_SIZE(mtk_jpeg_enc_quality); i++) { + if (ctx->enc_quality <= mtk_jpeg_enc_quality[i].quality_param) { + enc_quality = mtk_jpeg_enc_quality[i].hardware_value; + break; + } + } + writel(enc_quality, base + JPEG_ENC_QUALITY); + + value = readl(base + JPEG_ENC_CTRL); + value &= ~JPEG_ENC_CTRL_YUV_FORMAT_MASK; + value |= (ctx->out_q.fmt->hw_format & 3) << 3; + if (ctx->enable_exif) + value |= JPEG_ENC_CTRL_FILE_FORMAT_BIT; + else + value &= ~JPEG_ENC_CTRL_FILE_FORMAT_BIT; + if (ctx->restart_interval) + value |= JPEG_ENC_CTRL_RESTART_EN_BIT; + else + value &= ~JPEG_ENC_CTRL_RESTART_EN_BIT; + writel(value, base + JPEG_ENC_CTRL); + + writel(ctx->restart_interval, base + JPEG_ENC_RST_MCU_NUM); +} diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.h b/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.h new file mode 100644 index 000000000000..61c60e4e58ea --- /dev/null +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.h @@ -0,0 +1,91 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2019 MediaTek Inc. + * Author: Xia Jiang + * + */ + +#ifndef _MTK_JPEG_ENC_HW_H +#define _MTK_JPEG_ENC_HW_H + +#include + +#include "mtk_jpeg_core.h" + +#define JPEG_ENC_INT_STATUS_DONE BIT(0) +#define JPEG_ENC_INT_STATUS_MASK_ALLIRQ 0x13 + +#define JPEG_ENC_DST_ADDR_OFFSET_MASK GENMASK(3, 0) + +#define JPEG_ENC_CTRL_YUV_FORMAT_MASK 0x18 +#define JPEG_ENC_CTRL_RESTART_EN_BIT BIT(10) +#define JPEG_ENC_CTRL_FILE_FORMAT_BIT BIT(5) +#define JPEG_ENC_CTRL_INT_EN_BIT BIT(2) +#define JPEG_ENC_CTRL_ENABLE_BIT BIT(0) +#define JPEG_ENC_RESET_BIT BIT(0) + +#define JPEG_ENC_YUV_FORMAT_YUYV 0 +#define JPEG_ENC_YUV_FORMAT_YVYU 1 +#define JPEG_ENC_YUV_FORMAT_NV12 2 +#define JEPG_ENC_YUV_FORMAT_NV21 3 + +#define JPEG_ENC_QUALITY_Q60 0x0 +#define JPEG_ENC_QUALITY_Q80 0x1 +#define JPEG_ENC_QUALITY_Q90 0x2 +#define JPEG_ENC_QUALITY_Q95 0x3 +#define JPEG_ENC_QUALITY_Q39 0x4 +#define JPEG_ENC_QUALITY_Q68 0x5 +#define JPEG_ENC_QUALITY_Q84 0x6 +#define JPEG_ENC_QUALITY_Q92 0x7 +#define JPEG_ENC_QUALITY_Q48 0x8 +#define JPEG_ENC_QUALITY_Q74 0xa +#define JPEG_ENC_QUALITY_Q87 0xb +#define JPEG_ENC_QUALITY_Q34 0xc +#define JPEG_ENC_QUALITY_Q64 0xe +#define JPEG_ENC_QUALITY_Q82 0xf +#define JPEG_ENC_QUALITY_Q97 0x10 + +#define JPEG_ENC_RSTB 0x100 +#define JPEG_ENC_CTRL 0x104 +#define JPEG_ENC_QUALITY 0x108 +#define JPEG_ENC_BLK_NUM 0x10C +#define JPEG_ENC_BLK_CNT 0x110 +#define JPEG_ENC_INT_STS 0x11c +#define JPEG_ENC_DST_ADDR0 0x120 +#define JPEG_ENC_DMA_ADDR0 0x124 +#define JPEG_ENC_STALL_ADDR0 0x128 +#define JPEG_ENC_OFFSET_ADDR 0x138 +#define JPEG_ENC_RST_MCU_NUM 0x150 +#define JPEG_ENC_IMG_SIZE 0x154 +#define JPEG_ENC_DEBUG_INFO0 0x160 +#define JPEG_ENC_DEBUG_INFO1 0x164 +#define JPEG_ENC_TOTAL_CYCLE 0x168 +#define JPEG_ENC_BYTE_OFFSET_MASK 0x16c +#define JPEG_ENC_SRC_LUMA_ADDR 0x170 +#define JPEG_ENC_SRC_CHROMA_ADDR 0x174 +#define JPEG_ENC_STRIDE 0x178 +#define JPEG_ENC_IMG_STRIDE 0x17c +#define JPEG_ENC_DCM_CTRL 0x300 +#define JPEG_ENC_CODEC_SEL 0x314 +#define JPEG_ENC_ULTRA_THRES 0x318 + +/** + * struct mtk_jpeg_enc_qlt - JPEG encoder quality data + * @quality_param: quality value + * @hardware_value: hardware value of quality + */ +struct mtk_jpeg_enc_qlt { + u8 quality_param; + u8 hardware_value; +}; + +void mtk_jpeg_enc_reset(void __iomem *base); +u32 mtk_jpeg_enc_get_file_size(void __iomem *base); +void mtk_jpeg_enc_start(void __iomem *enc_reg_base); +void mtk_jpeg_set_enc_src(struct mtk_jpeg_ctx *ctx, void __iomem *base, + struct vb2_buffer *src_buf); +void mtk_jpeg_set_enc_dst(struct mtk_jpeg_ctx *ctx, void __iomem *base, + struct vb2_buffer *dst_buf); +void mtk_jpeg_set_enc_params(struct mtk_jpeg_ctx *ctx, void __iomem *base); + +#endif /* _MTK_JPEG_ENC_HW_H */ -- 2.18.0 _______________________________________________ Linux-mediatek mailing list Linux-mediatek@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-mediatek From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0747BC433E1 for ; Fri, 14 Aug 2020 07:29:57 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2F17620639 for ; Fri, 14 Aug 2020 07:29:56 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="uirvOhs3"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="ZL67253B" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2F17620639 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-ID:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=wTaDqeQhuYF7SFxWXr6+18z7IKX+hPh6CMH9ml2gqvk=; b=uirvOhs30eJGb3w+kHsRgmZmV xbRPB0ixMgF7q3kgMoeoo/tuvcL5akOr62UxERJ3A1WBpn9U5/tyYv/pO4iuFq+dLEB3kYfQNZEN4 A/RCDEt0rjkH74jrsockNaCwcN8HlWdCBCj25LUF8mCf86a2Fhm40eV/m1VD+pHzgWU5smiGEYMYf 7BLo0vJbJ3b4pY4KvukCI61UZr3s5G/y9+ydNEFNats5fRCJnbVblqfnwPH6wm2QO3JMkOAOs8uCy 0f5hrovnEPX0XWN54DkBbZ10y275DduMLMwSnj+YKJcl++TQI6YbcGZCaJwer4VaYmVe52bcQBCmQ jmyYAc2YA==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1k6U80-00065x-T0; Fri, 14 Aug 2020 07:27:52 +0000 Received: from mailgw02.mediatek.com ([216.200.240.185]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1k6U3i-0003N2-Qm; Fri, 14 Aug 2020 07:23:38 +0000 X-UUID: 5ae5ff5620e54cad887e6f7ed530c82d-20200813 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=rKRkfrldeTMdwzNxOIDH+OtOLPDraRIgEh2l5wXR8XI=; b=ZL67253BG4FitSXufxtwqCoZz8zxcDJkBGf1GBIrFNd6DwoD3WV3OIZTFD3hfcEo0Y3ZrcJBowo3VfCBarvnzhfqXO19VWxQv448ROeWAX87/xz7By5ce3qq4iTQuKEkkytTO+CpAhqN+VecIvMlqskLJOOGI7MFgYEJZ917Bck=; X-UUID: 5ae5ff5620e54cad887e6f7ed530c82d-20200813 Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by mailgw02.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLS) with ESMTP id 996701782; Thu, 13 Aug 2020 23:23:11 -0800 Received: from MTKMBS07N2.mediatek.inc (172.21.101.141) by MTKMBS62N2.mediatek.inc (172.29.193.42) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 14 Aug 2020 00:13:43 -0700 Received: from mtkcas08.mediatek.inc (172.21.101.126) by mtkmbs07n2.mediatek.inc (172.21.101.141) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 14 Aug 2020 15:13:38 +0800 Received: from localhost.localdomain (10.17.3.153) by mtkcas08.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Fri, 14 Aug 2020 15:13:37 +0800 From: Xia Jiang To: Hans Verkuil , Mauro Carvalho Chehab , Rob Herring , "Matthias Brugger" , Rick Chang Subject: [PATCH v12 29/29] media: platform: Add jpeg enc feature Date: Fri, 14 Aug 2020 15:12:02 +0800 Message-ID: <20200814071202.25067-31-xia.jiang@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20200814071202.25067-1-xia.jiang@mediatek.com> References: <20200814071202.25067-1-xia.jiang@mediatek.com> MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200814_032328_174018_C6C4F4E0 X-CRM114-Status: GOOD ( 22.73 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: maoguang.meng@mediatek.com, devicetree@vger.kernel.org, mojahsu@chromium.org, srv_heupstream@mediatek.com, linux-kernel@vger.kernel.org, Tomasz Figa , senozhatsky@chromium.org, drinkcat@chromium.org, linux-mediatek@lists.infradead.org, Xia Jiang , linux-media@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Marek Szyprowski Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add mtk jpeg encode v4l2 driver based on jpeg decode, because that jpeg decode and encode have great similarities with function operation. Reviewed-by: Tomasz Figa Signed-off-by: Xia Jiang --- v12: fix the compile warnings --- drivers/media/platform/mtk-jpeg/Makefile | 5 +- .../media/platform/mtk-jpeg/mtk_jpeg_core.c | 350 +++++++++++++++++- .../media/platform/mtk-jpeg/mtk_jpeg_core.h | 15 + .../media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c | 154 ++++++++ .../media/platform/mtk-jpeg/mtk_jpeg_enc_hw.h | 91 +++++ 5 files changed, 611 insertions(+), 4 deletions(-) create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.h diff --git a/drivers/media/platform/mtk-jpeg/Makefile b/drivers/media/platform/mtk-jpeg/Makefile index 48516dcf96e6..76c33aad0f3f 100644 --- a/drivers/media/platform/mtk-jpeg/Makefile +++ b/drivers/media/platform/mtk-jpeg/Makefile @@ -1,3 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only -mtk_jpeg-objs := mtk_jpeg_core.o mtk_jpeg_dec_hw.o mtk_jpeg_dec_parse.o +mtk_jpeg-objs := mtk_jpeg_core.o \ + mtk_jpeg_dec_hw.o \ + mtk_jpeg_dec_parse.o \ + mtk_jpeg_enc_hw.o obj-$(CONFIG_VIDEO_MEDIATEK_JPEG) += mtk_jpeg.o diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c index 3d95c7f0a22d..8d6d324ab113 100644 --- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c @@ -3,6 +3,7 @@ * Copyright (c) 2016 MediaTek Inc. * Author: Ming Hsiu Tsai * Rick Chang + * Xia Jiang */ #include @@ -23,10 +24,59 @@ #include #include +#include "mtk_jpeg_enc_hw.h" #include "mtk_jpeg_dec_hw.h" #include "mtk_jpeg_core.h" #include "mtk_jpeg_dec_parse.h" +static struct mtk_jpeg_fmt mtk_jpeg_enc_formats[] = { + { + .fourcc = V4L2_PIX_FMT_JPEG, + .colplanes = 1, + .flags = MTK_JPEG_FMT_FLAG_CAPTURE, + }, + { + .fourcc = V4L2_PIX_FMT_NV12M, + .hw_format = JPEG_ENC_YUV_FORMAT_NV12, + .h_sample = {4, 4}, + .v_sample = {4, 2}, + .colplanes = 2, + .h_align = 4, + .v_align = 4, + .flags = MTK_JPEG_FMT_FLAG_OUTPUT, + }, + { + .fourcc = V4L2_PIX_FMT_NV21M, + .hw_format = JEPG_ENC_YUV_FORMAT_NV21, + .h_sample = {4, 4}, + .v_sample = {4, 2}, + .colplanes = 2, + .h_align = 4, + .v_align = 4, + .flags = MTK_JPEG_FMT_FLAG_OUTPUT, + }, + { + .fourcc = V4L2_PIX_FMT_YUYV, + .hw_format = JPEG_ENC_YUV_FORMAT_YUYV, + .h_sample = {8}, + .v_sample = {4}, + .colplanes = 1, + .h_align = 5, + .v_align = 3, + .flags = MTK_JPEG_FMT_FLAG_OUTPUT, + }, + { + .fourcc = V4L2_PIX_FMT_YVYU, + .hw_format = JPEG_ENC_YUV_FORMAT_YVYU, + .h_sample = {8}, + .v_sample = {4}, + .colplanes = 1, + .h_align = 5, + .v_align = 3, + .flags = MTK_JPEG_FMT_FLAG_OUTPUT, + }, +}; + static struct mtk_jpeg_fmt mtk_jpeg_dec_formats[] = { { .fourcc = V4L2_PIX_FMT_JPEG, @@ -53,6 +103,7 @@ static struct mtk_jpeg_fmt mtk_jpeg_dec_formats[] = { }, }; +#define MTK_JPEG_ENC_NUM_FORMATS ARRAY_SIZE(mtk_jpeg_enc_formats) #define MTK_JPEG_DEC_NUM_FORMATS ARRAY_SIZE(mtk_jpeg_dec_formats) struct mtk_jpeg_src_buf { @@ -64,6 +115,11 @@ struct mtk_jpeg_src_buf { static int debug; module_param(debug, int, 0644); +static inline struct mtk_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *ctrl) +{ + return container_of(ctrl->handler, struct mtk_jpeg_ctx, ctrl_hdl); +} + static inline struct mtk_jpeg_ctx *mtk_jpeg_fh_to_ctx(struct v4l2_fh *fh) { return container_of(fh, struct mtk_jpeg_ctx, fh); @@ -88,6 +144,53 @@ static int mtk_jpeg_querycap(struct file *file, void *priv, return 0; } +static int vidioc_jpeg_enc_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct mtk_jpeg_ctx *ctx = ctrl_to_ctx(ctrl); + + switch (ctrl->id) { + case V4L2_CID_JPEG_RESTART_INTERVAL: + ctx->restart_interval = ctrl->val; + break; + case V4L2_CID_JPEG_COMPRESSION_QUALITY: + ctx->enc_quality = ctrl->val; + break; + case V4L2_CID_JPEG_ACTIVE_MARKER: + ctx->enable_exif = ctrl->val & V4L2_JPEG_ACTIVE_MARKER_APP1; + break; + } + + return 0; +} + +static const struct v4l2_ctrl_ops mtk_jpeg_enc_ctrl_ops = { + .s_ctrl = vidioc_jpeg_enc_s_ctrl, +}; + +static int mtk_jpeg_enc_ctrls_setup(struct mtk_jpeg_ctx *ctx) +{ + const struct v4l2_ctrl_ops *ops = &mtk_jpeg_enc_ctrl_ops; + struct v4l2_ctrl_handler *handler = &ctx->ctrl_hdl; + + v4l2_ctrl_handler_init(handler, 3); + + v4l2_ctrl_new_std(handler, ops, V4L2_CID_JPEG_RESTART_INTERVAL, 0, 100, + 1, 0); + v4l2_ctrl_new_std(handler, ops, V4L2_CID_JPEG_COMPRESSION_QUALITY, 48, + 100, 1, 90); + v4l2_ctrl_new_std(handler, ops, V4L2_CID_JPEG_ACTIVE_MARKER, 0, + V4L2_JPEG_ACTIVE_MARKER_APP1, 0, 0); + + if (handler->error) { + v4l2_ctrl_handler_free(&ctx->ctrl_hdl); + return handler->error; + } + + v4l2_ctrl_handler_setup(&ctx->ctrl_hdl); + + return 0; +} + static int mtk_jpeg_enum_fmt(struct mtk_jpeg_fmt *mtk_jpeg_formats, int n, struct v4l2_fmtdesc *f, u32 type) { @@ -331,6 +434,8 @@ static int mtk_jpeg_s_fmt_mplane(struct mtk_jpeg_ctx *ctx, pix_mp->pixelformat, fmt_type); q_data->pix_mp.width = pix_mp->width; q_data->pix_mp.height = pix_mp->height; + q_data->enc_crop_rect.width = pix_mp->width; + q_data->enc_crop_rect.height = pix_mp->height; q_data->pix_mp.colorspace = V4L2_COLORSPACE_SRGB; q_data->pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_601; q_data->pix_mp.xfer_func = V4L2_XFER_FUNC_SRGB; @@ -407,6 +512,31 @@ static int mtk_jpeg_subscribe_event(struct v4l2_fh *fh, return v4l2_ctrl_subscribe_event(fh, sub); } +static int mtk_jpeg_enc_g_selection(struct file *file, void *priv, + struct v4l2_selection *s) +{ + struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv); + + if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) + return -EINVAL; + + switch (s->target) { + case V4L2_SEL_TGT_CROP: + s->r = ctx->out_q.enc_crop_rect; + break; + case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SEL_TGT_CROP_DEFAULT: + s->r.width = ctx->out_q.pix_mp.width; + s->r.height = ctx->out_q.pix_mp.height; + s->r.left = 0; + s->r.top = 0; + break; + default: + return -EINVAL; + } + return 0; +} + static int mtk_jpeg_dec_g_selection(struct file *file, void *priv, struct v4l2_selection *s) { @@ -436,6 +566,56 @@ static int mtk_jpeg_dec_g_selection(struct file *file, void *priv, return 0; } +static int mtk_jpeg_enc_s_selection(struct file *file, void *priv, + struct v4l2_selection *s) +{ + struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv); + + if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) + return -EINVAL; + + switch (s->target) { + case V4L2_SEL_TGT_CROP: + s->r.left = 0; + s->r.top = 0; + s->r.width = min(s->r.width, ctx->out_q.pix_mp.width); + s->r.height = min(s->r.height, ctx->out_q.pix_mp.height); + ctx->out_q.enc_crop_rect = s->r; + break; + default: + return -EINVAL; + } + + return 0; +} + +static const struct v4l2_ioctl_ops mtk_jpeg_enc_ioctl_ops = { + .vidioc_querycap = mtk_jpeg_querycap, + .vidioc_enum_fmt_vid_cap = mtk_jpeg_enum_fmt_vid_cap, + .vidioc_enum_fmt_vid_out = mtk_jpeg_enum_fmt_vid_out, + .vidioc_try_fmt_vid_cap_mplane = mtk_jpeg_try_fmt_vid_cap_mplane, + .vidioc_try_fmt_vid_out_mplane = mtk_jpeg_try_fmt_vid_out_mplane, + .vidioc_g_fmt_vid_cap_mplane = mtk_jpeg_g_fmt_vid_mplane, + .vidioc_g_fmt_vid_out_mplane = mtk_jpeg_g_fmt_vid_mplane, + .vidioc_s_fmt_vid_cap_mplane = mtk_jpeg_s_fmt_vid_cap_mplane, + .vidioc_s_fmt_vid_out_mplane = mtk_jpeg_s_fmt_vid_out_mplane, + .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, + .vidioc_subscribe_event = mtk_jpeg_subscribe_event, + .vidioc_g_selection = mtk_jpeg_enc_g_selection, + .vidioc_s_selection = mtk_jpeg_enc_s_selection, + + .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, + .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, + .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, + .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, + .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, + .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, + .vidioc_streamon = v4l2_m2m_ioctl_streamon, + .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, + + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, +}; + static const struct v4l2_ioctl_ops mtk_jpeg_dec_ioctl_ops = { .vidioc_querycap = mtk_jpeg_querycap, .vidioc_enum_fmt_vid_cap = mtk_jpeg_enum_fmt_vid_cap, @@ -501,15 +681,22 @@ static int mtk_jpeg_buf_prepare(struct vb2_buffer *vb) { struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); struct mtk_jpeg_q_data *q_data = NULL; + struct v4l2_plane_pix_format plane_fmt = {}; int i; q_data = mtk_jpeg_get_q_data(ctx, vb->vb2_queue->type); if (!q_data) return -EINVAL; - for (i = 0; i < q_data->fmt->colplanes; i++) - vb2_set_plane_payload(vb, i, - q_data->pix_mp.plane_fmt[i].sizeimage); + for (i = 0; i < q_data->fmt->colplanes; i++) { + plane_fmt = q_data->pix_mp.plane_fmt[i]; + if (ctx->enable_exif && + q_data->fmt->fourcc == V4L2_PIX_FMT_JPEG) + vb2_set_plane_payload(vb, i, plane_fmt.sizeimage + + MTK_JPEG_MAX_EXIF_SIZE); + else + vb2_set_plane_payload(vb, i, plane_fmt.sizeimage); + } return 0; } @@ -572,6 +759,17 @@ static void mtk_jpeg_set_queue_data(struct mtk_jpeg_ctx *ctx, param->dec_w, param->dec_h); } +static void mtk_jpeg_enc_buf_queue(struct vb2_buffer *vb) +{ + struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + struct mtk_jpeg_dev *jpeg = ctx->jpeg; + + v4l2_dbg(2, debug, &jpeg->v4l2_dev, "(%d) buf_q id=%d, vb=%p\n", + vb->vb2_queue->type, vb->index, vb); + + v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, to_vb2_v4l2_buffer(vb)); +} + static void mtk_jpeg_dec_buf_queue(struct vb2_buffer *vb) { struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); @@ -620,6 +818,15 @@ static struct vb2_v4l2_buffer *mtk_jpeg_buf_remove(struct mtk_jpeg_ctx *ctx, return v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); } +static void mtk_jpeg_enc_stop_streaming(struct vb2_queue *q) +{ + struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q); + struct vb2_v4l2_buffer *vb; + + while ((vb = mtk_jpeg_buf_remove(ctx, q->type))) + v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR); +} + static void mtk_jpeg_dec_stop_streaming(struct vb2_queue *q) { struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q); @@ -655,6 +862,15 @@ static const struct vb2_ops mtk_jpeg_dec_qops = { .stop_streaming = mtk_jpeg_dec_stop_streaming, }; +static const struct vb2_ops mtk_jpeg_enc_qops = { + .queue_setup = mtk_jpeg_queue_setup, + .buf_prepare = mtk_jpeg_buf_prepare, + .buf_queue = mtk_jpeg_enc_buf_queue, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, + .stop_streaming = mtk_jpeg_enc_stop_streaming, +}; + static void mtk_jpeg_set_dec_src(struct mtk_jpeg_ctx *ctx, struct vb2_buffer *src_buf, struct mtk_jpeg_bs *bs) @@ -692,6 +908,48 @@ static int mtk_jpeg_set_dec_dst(struct mtk_jpeg_ctx *ctx, return 0; } +static void mtk_jpeg_enc_device_run(void *priv) +{ + struct mtk_jpeg_ctx *ctx = priv; + struct mtk_jpeg_dev *jpeg = ctx->jpeg; + struct vb2_v4l2_buffer *src_buf, *dst_buf; + enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR; + unsigned long flags; + int ret; + + src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); + dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); + + ret = pm_runtime_get_sync(jpeg->dev); + if (ret < 0) + goto enc_end; + + schedule_delayed_work(&jpeg->job_timeout_work, + msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC)); + + spin_lock_irqsave(&jpeg->hw_lock, flags); + + /* + * Resetting the hardware every frame is to ensure that all the + * registers are cleared. This is a hardware requirement. + */ + mtk_jpeg_enc_reset(jpeg->reg_base); + + mtk_jpeg_set_enc_src(ctx, jpeg->reg_base, &src_buf->vb2_buf); + mtk_jpeg_set_enc_dst(ctx, jpeg->reg_base, &dst_buf->vb2_buf); + mtk_jpeg_set_enc_params(ctx, jpeg->reg_base); + mtk_jpeg_enc_start(jpeg->reg_base); + spin_unlock_irqrestore(&jpeg->hw_lock, flags); + return; + +enc_end: + v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); + v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); + v4l2_m2m_buf_done(src_buf, buf_state); + v4l2_m2m_buf_done(dst_buf, buf_state); + v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); +} + static void mtk_jpeg_dec_device_run(void *priv) { struct mtk_jpeg_ctx *ctx = priv; @@ -750,6 +1008,10 @@ static int mtk_jpeg_dec_job_ready(void *priv) return (ctx->state == MTK_JPEG_RUNNING) ? 1 : 0; } +static const struct v4l2_m2m_ops mtk_jpeg_enc_m2m_ops = { + .device_run = mtk_jpeg_enc_device_run, +}; + static const struct v4l2_m2m_ops mtk_jpeg_dec_m2m_ops = { .device_run = mtk_jpeg_dec_device_run, .job_ready = mtk_jpeg_dec_job_ready, @@ -810,6 +1072,54 @@ static void mtk_jpeg_clk_off(struct mtk_jpeg_dev *jpeg) mtk_smi_larb_put(jpeg->larb); } +static irqreturn_t mtk_jpeg_enc_done(struct mtk_jpeg_dev *jpeg) +{ + struct mtk_jpeg_ctx *ctx; + struct vb2_v4l2_buffer *src_buf, *dst_buf; + enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR; + u32 result_size; + + ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev); + if (!ctx) { + v4l2_err(&jpeg->v4l2_dev, "Context is NULL\n"); + return IRQ_HANDLED; + } + + src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); + dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); + + result_size = mtk_jpeg_enc_get_file_size(jpeg->reg_base); + vb2_set_plane_payload(&dst_buf->vb2_buf, 0, result_size); + + buf_state = VB2_BUF_STATE_DONE; + + v4l2_m2m_buf_done(src_buf, buf_state); + v4l2_m2m_buf_done(dst_buf, buf_state); + v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); + pm_runtime_put(ctx->jpeg->dev); + return IRQ_HANDLED; +} + +static irqreturn_t mtk_jpeg_enc_irq(int irq, void *priv) +{ + struct mtk_jpeg_dev *jpeg = priv; + u32 irq_status; + irqreturn_t ret = IRQ_NONE; + + cancel_delayed_work(&jpeg->job_timeout_work); + + irq_status = readl(jpeg->reg_base + JPEG_ENC_INT_STS) & + JPEG_ENC_INT_STATUS_MASK_ALLIRQ; + if (irq_status) + writel(0, jpeg->reg_base + JPEG_ENC_INT_STS); + + if (!(irq_status & JPEG_ENC_INT_STATUS_DONE)) + return ret; + + ret = mtk_jpeg_enc_done(jpeg); + return ret; +} + static irqreturn_t mtk_jpeg_dec_irq(int irq, void *priv) { struct mtk_jpeg_dev *jpeg = priv; @@ -862,6 +1172,7 @@ static void mtk_jpeg_set_default_params(struct mtk_jpeg_ctx *ctx) struct mtk_jpeg_q_data *q = &ctx->out_q; struct mtk_jpeg_dev *jpeg = ctx->jpeg; + ctx->fh.ctrl_handler = &ctx->ctrl_hdl; q->pix_mp.colorspace = V4L2_COLORSPACE_SRGB; q->pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_601; q->pix_mp.quantization = V4L2_QUANTIZATION_FULL_RANGE; @@ -918,6 +1229,15 @@ static int mtk_jpeg_open(struct file *file) goto error; } + if (jpeg->variant->cap_q_default_fourcc == V4L2_PIX_FMT_JPEG) { + ret = mtk_jpeg_enc_ctrls_setup(ctx); + if (ret) { + v4l2_err(&jpeg->v4l2_dev, "Failed to setup jpeg enc controls\n"); + goto error; + } + } else { + v4l2_ctrl_handler_init(&ctx->ctrl_hdl, 0); + } mtk_jpeg_set_default_params(ctx); mutex_unlock(&jpeg->lock); return 0; @@ -938,6 +1258,7 @@ static int mtk_jpeg_release(struct file *file) mutex_lock(&jpeg->lock); v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); + v4l2_ctrl_handler_free(&ctx->ctrl_hdl); v4l2_fh_del(&ctx->fh); v4l2_fh_exit(&ctx->fh); kfree(ctx); @@ -959,6 +1280,10 @@ static struct clk_bulk_data mt8173_jpeg_dec_clocks[] = { { .id = "jpgdec" }, }; +static struct clk_bulk_data mtk_jpeg_clocks[] = { + { .id = "jpgenc" }, +}; + static int mtk_jpeg_clk_init(struct mtk_jpeg_dev *jpeg) { struct device_node *node; @@ -1190,6 +1515,21 @@ static const struct mtk_jpeg_variant mt8173_jpeg_drvdata = { .cap_q_default_fourcc = V4L2_PIX_FMT_YUV420M, }; +static const struct mtk_jpeg_variant mtk_jpeg_drvdata = { + .clks = mtk_jpeg_clocks, + .num_clks = ARRAY_SIZE(mtk_jpeg_clocks), + .formats = mtk_jpeg_enc_formats, + .num_formats = MTK_JPEG_ENC_NUM_FORMATS, + .qops = &mtk_jpeg_enc_qops, + .irq_handler = mtk_jpeg_enc_irq, + .hw_reset = mtk_jpeg_enc_reset, + .m2m_ops = &mtk_jpeg_enc_m2m_ops, + .dev_name = "mtk-jpeg-enc", + .ioctl_ops = &mtk_jpeg_enc_ioctl_ops, + .out_q_default_fourcc = V4L2_PIX_FMT_YUYV, + .cap_q_default_fourcc = V4L2_PIX_FMT_JPEG, +}; + static const struct of_device_id mtk_jpeg_match[] = { { .compatible = "mediatek,mt8173-jpgdec", @@ -1199,6 +1539,10 @@ static const struct of_device_id mtk_jpeg_match[] = { .compatible = "mediatek,mt2701-jpgdec", .data = &mt8173_jpeg_drvdata, }, + { + .compatible = "mediatek,mtk-jpgenc", + .data = &mtk_jpeg_drvdata, + }, {}, }; diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h index d11d366a247e..68e634f02e00 100644 --- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h @@ -3,6 +3,7 @@ * Copyright (c) 2016 MediaTek Inc. * Author: Ming Hsiu Tsai * Rick Chang + * Xia Jiang */ #ifndef _MTK_JPEG_CORE_H @@ -29,6 +30,8 @@ #define MTK_JPEG_HW_TIMEOUT_MSEC 1000 +#define MTK_JPEG_MAX_EXIF_SIZE (64 * 1024) + /** * enum mtk_jpeg_ctx_state - states of the context state machine * @MTK_JPEG_INIT: current state is initialized @@ -104,6 +107,7 @@ struct mtk_jpeg_dev { /** * struct jpeg_fmt - driver's internal color format data * @fourcc: the fourcc code, 0 if not applicable + * @hw_format: hardware format value * @h_sample: horizontal sample count of plane in 4 * 4 pixel image * @v_sample: vertical sample count of plane in 4 * 4 pixel image * @colplanes: number of color planes (1 for packed formats) @@ -113,6 +117,7 @@ struct mtk_jpeg_dev { */ struct mtk_jpeg_fmt { u32 fourcc; + u32 hw_format; int h_sample[VIDEO_MAX_PLANES]; int v_sample[VIDEO_MAX_PLANES]; int colplanes; @@ -125,10 +130,12 @@ struct mtk_jpeg_fmt { * mtk_jpeg_q_data - parameters of one queue * @fmt: driver-specific format of this queue * @pix_mp: multiplanar format + * @enc_crop_rect: jpeg encoder crop information */ struct mtk_jpeg_q_data { struct mtk_jpeg_fmt *fmt; struct v4l2_pix_format_mplane pix_mp; + struct v4l2_rect enc_crop_rect; }; /** @@ -138,6 +145,10 @@ struct mtk_jpeg_q_data { * @cap_q: destination (capture) queue queue information * @fh: V4L2 file handle * @state: state of the context + * @enable_exif: enable exif mode of jpeg encoder + * @enc_quality: jpeg encoder quality + * @restart_interval: jpeg encoder restart interval + * @ctrl_hdl: controls handler */ struct mtk_jpeg_ctx { struct mtk_jpeg_dev *jpeg; @@ -145,6 +156,10 @@ struct mtk_jpeg_ctx { struct mtk_jpeg_q_data cap_q; struct v4l2_fh fh; enum mtk_jpeg_ctx_state state; + bool enable_exif; + u8 enc_quality; + u8 restart_interval; + struct v4l2_ctrl_handler ctrl_hdl; }; #endif /* _MTK_JPEG_CORE_H */ diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c b/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c new file mode 100644 index 000000000000..1cf037bf72dd --- /dev/null +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2019 MediaTek Inc. + * Author: Xia Jiang + * + */ + +#include +#include +#include +#include + +#include "mtk_jpeg_enc_hw.h" + +static const struct mtk_jpeg_enc_qlt mtk_jpeg_enc_quality[] = { + {.quality_param = 34, .hardware_value = JPEG_ENC_QUALITY_Q34}, + {.quality_param = 39, .hardware_value = JPEG_ENC_QUALITY_Q39}, + {.quality_param = 48, .hardware_value = JPEG_ENC_QUALITY_Q48}, + {.quality_param = 60, .hardware_value = JPEG_ENC_QUALITY_Q60}, + {.quality_param = 64, .hardware_value = JPEG_ENC_QUALITY_Q64}, + {.quality_param = 68, .hardware_value = JPEG_ENC_QUALITY_Q68}, + {.quality_param = 74, .hardware_value = JPEG_ENC_QUALITY_Q74}, + {.quality_param = 80, .hardware_value = JPEG_ENC_QUALITY_Q80}, + {.quality_param = 82, .hardware_value = JPEG_ENC_QUALITY_Q82}, + {.quality_param = 84, .hardware_value = JPEG_ENC_QUALITY_Q84}, + {.quality_param = 87, .hardware_value = JPEG_ENC_QUALITY_Q87}, + {.quality_param = 90, .hardware_value = JPEG_ENC_QUALITY_Q90}, + {.quality_param = 92, .hardware_value = JPEG_ENC_QUALITY_Q92}, + {.quality_param = 95, .hardware_value = JPEG_ENC_QUALITY_Q95}, + {.quality_param = 97, .hardware_value = JPEG_ENC_QUALITY_Q97}, +}; + +void mtk_jpeg_enc_reset(void __iomem *base) +{ + writel(0, base + JPEG_ENC_RSTB); + writel(JPEG_ENC_RESET_BIT, base + JPEG_ENC_RSTB); + writel(0, base + JPEG_ENC_CODEC_SEL); +} + +u32 mtk_jpeg_enc_get_file_size(void __iomem *base) +{ + return readl(base + JPEG_ENC_DMA_ADDR0) - + readl(base + JPEG_ENC_DST_ADDR0); +} + +void mtk_jpeg_enc_start(void __iomem *base) +{ + u32 value; + + value = readl(base + JPEG_ENC_CTRL); + value |= JPEG_ENC_CTRL_INT_EN_BIT | JPEG_ENC_CTRL_ENABLE_BIT; + writel(value, base + JPEG_ENC_CTRL); +} + +void mtk_jpeg_set_enc_src(struct mtk_jpeg_ctx *ctx, void __iomem *base, + struct vb2_buffer *src_buf) +{ + int i; + dma_addr_t dma_addr; + + for (i = 0; i < src_buf->num_planes; i++) { + dma_addr = vb2_dma_contig_plane_dma_addr(src_buf, i) + + src_buf->planes[i].data_offset; + if (!i) + writel(dma_addr, base + JPEG_ENC_SRC_LUMA_ADDR); + else + writel(dma_addr, base + JPEG_ENC_SRC_CHROMA_ADDR); + } +} + +void mtk_jpeg_set_enc_dst(struct mtk_jpeg_ctx *ctx, void __iomem *base, + struct vb2_buffer *dst_buf) +{ + dma_addr_t dma_addr; + size_t size; + u32 dma_addr_offset; + u32 dma_addr_offsetmask; + + dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0); + dma_addr_offset = ctx->enable_exif ? MTK_JPEG_MAX_EXIF_SIZE : 0; + dma_addr_offsetmask = dma_addr & JPEG_ENC_DST_ADDR_OFFSET_MASK; + size = vb2_plane_size(dst_buf, 0); + + writel(dma_addr_offset & ~0xf, base + JPEG_ENC_OFFSET_ADDR); + writel(dma_addr_offsetmask & 0xf, base + JPEG_ENC_BYTE_OFFSET_MASK); + writel(dma_addr & ~0xf, base + JPEG_ENC_DST_ADDR0); + writel((dma_addr + size) & ~0xf, base + JPEG_ENC_STALL_ADDR0); +} + +void mtk_jpeg_set_enc_params(struct mtk_jpeg_ctx *ctx, void __iomem *base) +{ + u32 value; + u32 width = ctx->out_q.enc_crop_rect.width; + u32 height = ctx->out_q.enc_crop_rect.height; + u32 enc_format = ctx->out_q.fmt->fourcc; + u32 bytesperline = ctx->out_q.pix_mp.plane_fmt[0].bytesperline; + u32 blk_num; + u32 img_stride; + u32 mem_stride; + u32 i, enc_quality; + + value = width << 16 | height; + writel(value, base + JPEG_ENC_IMG_SIZE); + + if (enc_format == V4L2_PIX_FMT_NV12M || + enc_format == V4L2_PIX_FMT_NV21M) + /* + * Total 8 x 8 block number of luma and chroma. + * The number of blocks is counted from 0. + */ + blk_num = DIV_ROUND_UP(width, 16) * + DIV_ROUND_UP(height, 16) * 6 - 1; + else + blk_num = DIV_ROUND_UP(width, 16) * + DIV_ROUND_UP(height, 8) * 4 - 1; + writel(blk_num, base + JPEG_ENC_BLK_NUM); + + if (enc_format == V4L2_PIX_FMT_NV12M || + enc_format == V4L2_PIX_FMT_NV21M) { + /* 4:2:0 */ + img_stride = round_up(width, 16); + mem_stride = bytesperline; + } else { + /* 4:2:2 */ + img_stride = round_up(width * 2, 32); + mem_stride = img_stride; + } + writel(img_stride, base + JPEG_ENC_IMG_STRIDE); + writel(mem_stride, base + JPEG_ENC_STRIDE); + + enc_quality = mtk_jpeg_enc_quality[0].hardware_value; + for (i = 0; i < ARRAY_SIZE(mtk_jpeg_enc_quality); i++) { + if (ctx->enc_quality <= mtk_jpeg_enc_quality[i].quality_param) { + enc_quality = mtk_jpeg_enc_quality[i].hardware_value; + break; + } + } + writel(enc_quality, base + JPEG_ENC_QUALITY); + + value = readl(base + JPEG_ENC_CTRL); + value &= ~JPEG_ENC_CTRL_YUV_FORMAT_MASK; + value |= (ctx->out_q.fmt->hw_format & 3) << 3; + if (ctx->enable_exif) + value |= JPEG_ENC_CTRL_FILE_FORMAT_BIT; + else + value &= ~JPEG_ENC_CTRL_FILE_FORMAT_BIT; + if (ctx->restart_interval) + value |= JPEG_ENC_CTRL_RESTART_EN_BIT; + else + value &= ~JPEG_ENC_CTRL_RESTART_EN_BIT; + writel(value, base + JPEG_ENC_CTRL); + + writel(ctx->restart_interval, base + JPEG_ENC_RST_MCU_NUM); +} diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.h b/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.h new file mode 100644 index 000000000000..61c60e4e58ea --- /dev/null +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.h @@ -0,0 +1,91 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2019 MediaTek Inc. + * Author: Xia Jiang + * + */ + +#ifndef _MTK_JPEG_ENC_HW_H +#define _MTK_JPEG_ENC_HW_H + +#include + +#include "mtk_jpeg_core.h" + +#define JPEG_ENC_INT_STATUS_DONE BIT(0) +#define JPEG_ENC_INT_STATUS_MASK_ALLIRQ 0x13 + +#define JPEG_ENC_DST_ADDR_OFFSET_MASK GENMASK(3, 0) + +#define JPEG_ENC_CTRL_YUV_FORMAT_MASK 0x18 +#define JPEG_ENC_CTRL_RESTART_EN_BIT BIT(10) +#define JPEG_ENC_CTRL_FILE_FORMAT_BIT BIT(5) +#define JPEG_ENC_CTRL_INT_EN_BIT BIT(2) +#define JPEG_ENC_CTRL_ENABLE_BIT BIT(0) +#define JPEG_ENC_RESET_BIT BIT(0) + +#define JPEG_ENC_YUV_FORMAT_YUYV 0 +#define JPEG_ENC_YUV_FORMAT_YVYU 1 +#define JPEG_ENC_YUV_FORMAT_NV12 2 +#define JEPG_ENC_YUV_FORMAT_NV21 3 + +#define JPEG_ENC_QUALITY_Q60 0x0 +#define JPEG_ENC_QUALITY_Q80 0x1 +#define JPEG_ENC_QUALITY_Q90 0x2 +#define JPEG_ENC_QUALITY_Q95 0x3 +#define JPEG_ENC_QUALITY_Q39 0x4 +#define JPEG_ENC_QUALITY_Q68 0x5 +#define JPEG_ENC_QUALITY_Q84 0x6 +#define JPEG_ENC_QUALITY_Q92 0x7 +#define JPEG_ENC_QUALITY_Q48 0x8 +#define JPEG_ENC_QUALITY_Q74 0xa +#define JPEG_ENC_QUALITY_Q87 0xb +#define JPEG_ENC_QUALITY_Q34 0xc +#define JPEG_ENC_QUALITY_Q64 0xe +#define JPEG_ENC_QUALITY_Q82 0xf +#define JPEG_ENC_QUALITY_Q97 0x10 + +#define JPEG_ENC_RSTB 0x100 +#define JPEG_ENC_CTRL 0x104 +#define JPEG_ENC_QUALITY 0x108 +#define JPEG_ENC_BLK_NUM 0x10C +#define JPEG_ENC_BLK_CNT 0x110 +#define JPEG_ENC_INT_STS 0x11c +#define JPEG_ENC_DST_ADDR0 0x120 +#define JPEG_ENC_DMA_ADDR0 0x124 +#define JPEG_ENC_STALL_ADDR0 0x128 +#define JPEG_ENC_OFFSET_ADDR 0x138 +#define JPEG_ENC_RST_MCU_NUM 0x150 +#define JPEG_ENC_IMG_SIZE 0x154 +#define JPEG_ENC_DEBUG_INFO0 0x160 +#define JPEG_ENC_DEBUG_INFO1 0x164 +#define JPEG_ENC_TOTAL_CYCLE 0x168 +#define JPEG_ENC_BYTE_OFFSET_MASK 0x16c +#define JPEG_ENC_SRC_LUMA_ADDR 0x170 +#define JPEG_ENC_SRC_CHROMA_ADDR 0x174 +#define JPEG_ENC_STRIDE 0x178 +#define JPEG_ENC_IMG_STRIDE 0x17c +#define JPEG_ENC_DCM_CTRL 0x300 +#define JPEG_ENC_CODEC_SEL 0x314 +#define JPEG_ENC_ULTRA_THRES 0x318 + +/** + * struct mtk_jpeg_enc_qlt - JPEG encoder quality data + * @quality_param: quality value + * @hardware_value: hardware value of quality + */ +struct mtk_jpeg_enc_qlt { + u8 quality_param; + u8 hardware_value; +}; + +void mtk_jpeg_enc_reset(void __iomem *base); +u32 mtk_jpeg_enc_get_file_size(void __iomem *base); +void mtk_jpeg_enc_start(void __iomem *enc_reg_base); +void mtk_jpeg_set_enc_src(struct mtk_jpeg_ctx *ctx, void __iomem *base, + struct vb2_buffer *src_buf); +void mtk_jpeg_set_enc_dst(struct mtk_jpeg_ctx *ctx, void __iomem *base, + struct vb2_buffer *dst_buf); +void mtk_jpeg_set_enc_params(struct mtk_jpeg_ctx *ctx, void __iomem *base); + +#endif /* _MTK_JPEG_ENC_HW_H */ -- 2.18.0 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.4 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,MIME_BASE64_TEXT,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS, UNPARSEABLE_RELAY,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2AA72C433E4 for ; Fri, 14 Aug 2020 07:14:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 02D8A221E2 for ; Fri, 14 Aug 2020 07:14:01 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="usmyEwpG" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727018AbgHNHNz (ORCPT ); Fri, 14 Aug 2020 03:13:55 -0400 Received: from mailgw02.mediatek.com ([210.61.82.184]:59726 "EHLO mailgw02.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1726948AbgHNHNy (ORCPT ); Fri, 14 Aug 2020 03:13:54 -0400 X-UUID: 75354ea3529d4befae598a7dc95f8385-20200814 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=rKRkfrldeTMdwzNxOIDH+OtOLPDraRIgEh2l5wXR8XI=; b=usmyEwpGekLTSUlgy4wqiWjn0ClhZhGllF4q9eh1daeypUfj9z0ifDdv9RtbwlwiQun1vb6V5s8sWv8qeD3xSI5wAcfeoDDmxFx2yDd7ikAgWhmIcACbJPmdbP8VCkn9NToy+rSM4wcf7cjF8LKWuV9qVnwpZB4G68vnliaMmck=; X-UUID: 75354ea3529d4befae598a7dc95f8385-20200814 Received: from mtkcas10.mediatek.inc [(172.21.101.39)] by mailgw02.mediatek.com (envelope-from ) (Cellopoint E-mail Firewall v4.1.10 Build 0809 with TLS) with ESMTP id 210501686; Fri, 14 Aug 2020 15:13:41 +0800 Received: from mtkcas08.mediatek.inc (172.21.101.126) by mtkmbs07n2.mediatek.inc (172.21.101.141) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 14 Aug 2020 15:13:38 +0800 Received: from localhost.localdomain (10.17.3.153) by mtkcas08.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Fri, 14 Aug 2020 15:13:37 +0800 From: Xia Jiang To: Hans Verkuil , Mauro Carvalho Chehab , Rob Herring , Matthias Brugger , Rick Chang CC: , , , , , Marek Szyprowski , Tomasz Figa , , , , , , Xia Jiang Subject: [PATCH v12 29/29] media: platform: Add jpeg enc feature Date: Fri, 14 Aug 2020 15:12:02 +0800 Message-ID: <20200814071202.25067-31-xia.jiang@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20200814071202.25067-1-xia.jiang@mediatek.com> References: <20200814071202.25067-1-xia.jiang@mediatek.com> MIME-Version: 1.0 Content-Type: text/plain X-MTK: N Content-Transfer-Encoding: base64 Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org QWRkIG10ayBqcGVnIGVuY29kZSB2NGwyIGRyaXZlciBiYXNlZCBvbiBqcGVnIGRlY29kZSwgYmVj YXVzZSB0aGF0IGpwZWcNCmRlY29kZSBhbmQgZW5jb2RlIGhhdmUgZ3JlYXQgc2ltaWxhcml0aWVz IHdpdGggZnVuY3Rpb24gb3BlcmF0aW9uLg0KDQpSZXZpZXdlZC1ieTogVG9tYXN6IEZpZ2EgPHRm aWdhQGNocm9taXVtLm9yZz4NClNpZ25lZC1vZmYtYnk6IFhpYSBKaWFuZyA8eGlhLmppYW5nQG1l ZGlhdGVrLmNvbT4NCi0tLQ0KdjEyOiBmaXggdGhlIGNvbXBpbGUgd2FybmluZ3MNCi0tLQ0KIGRy aXZlcnMvbWVkaWEvcGxhdGZvcm0vbXRrLWpwZWcvTWFrZWZpbGUgICAgICB8ICAgNSArLQ0KIC4u Li9tZWRpYS9wbGF0Zm9ybS9tdGstanBlZy9tdGtfanBlZ19jb3JlLmMgICB8IDM1MCArKysrKysr KysrKysrKysrKy0NCiAuLi4vbWVkaWEvcGxhdGZvcm0vbXRrLWpwZWcvbXRrX2pwZWdfY29yZS5o ICAgfCAgMTUgKw0KIC4uLi9tZWRpYS9wbGF0Zm9ybS9tdGstanBlZy9tdGtfanBlZ19lbmNfaHcu YyB8IDE1NCArKysrKysrKw0KIC4uLi9tZWRpYS9wbGF0Zm9ybS9tdGstanBlZy9tdGtfanBlZ19l bmNfaHcuaCB8ICA5MSArKysrKw0KIDUgZmlsZXMgY2hhbmdlZCwgNjExIGluc2VydGlvbnMoKyks IDQgZGVsZXRpb25zKC0pDQogY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvbWVkaWEvcGxhdGZv cm0vbXRrLWpwZWcvbXRrX2pwZWdfZW5jX2h3LmMNCiBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVy cy9tZWRpYS9wbGF0Zm9ybS9tdGstanBlZy9tdGtfanBlZ19lbmNfaHcuaA0KDQpkaWZmIC0tZ2l0 IGEvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9tdGstanBlZy9NYWtlZmlsZSBiL2RyaXZlcnMvbWVk aWEvcGxhdGZvcm0vbXRrLWpwZWcvTWFrZWZpbGUNCmluZGV4IDQ4NTE2ZGNmOTZlNi4uNzZjMzNh YWQwZjNmIDEwMDY0NA0KLS0tIGEvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9tdGstanBlZy9NYWtl ZmlsZQ0KKysrIGIvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9tdGstanBlZy9NYWtlZmlsZQ0KQEAg LTEsMyArMSw2IEBADQogIyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMC1vbmx5DQot bXRrX2pwZWctb2JqcyA6PSBtdGtfanBlZ19jb3JlLm8gbXRrX2pwZWdfZGVjX2h3Lm8gbXRrX2pw ZWdfZGVjX3BhcnNlLm8NCittdGtfanBlZy1vYmpzIDo9IG10a19qcGVnX2NvcmUubyBcDQorCQkg bXRrX2pwZWdfZGVjX2h3Lm8gXA0KKwkJIG10a19qcGVnX2RlY19wYXJzZS5vIFwNCisJCSBtdGtf anBlZ19lbmNfaHcubw0KIG9iai0kKENPTkZJR19WSURFT19NRURJQVRFS19KUEVHKSArPSBtdGtf anBlZy5vDQpkaWZmIC0tZ2l0IGEvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9tdGstanBlZy9tdGtf anBlZ19jb3JlLmMgYi9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL210ay1qcGVnL210a19qcGVnX2Nv cmUuYw0KaW5kZXggM2Q5NWM3ZjBhMjJkLi44ZDZkMzI0YWIxMTMgMTAwNjQ0DQotLS0gYS9kcml2 ZXJzL21lZGlhL3BsYXRmb3JtL210ay1qcGVnL210a19qcGVnX2NvcmUuYw0KKysrIGIvZHJpdmVy cy9tZWRpYS9wbGF0Zm9ybS9tdGstanBlZy9tdGtfanBlZ19jb3JlLmMNCkBAIC0zLDYgKzMsNyBA QA0KICAqIENvcHlyaWdodCAoYykgMjAxNiBNZWRpYVRlayBJbmMuDQogICogQXV0aG9yOiBNaW5n IEhzaXUgVHNhaSA8bWluZ2hzaXUudHNhaUBtZWRpYXRlay5jb20+DQogICogICAgICAgICBSaWNr IENoYW5nIDxyaWNrLmNoYW5nQG1lZGlhdGVrLmNvbT4NCisgKiAgICAgICAgIFhpYSBKaWFuZyA8 eGlhLmppYW5nQG1lZGlhdGVrLmNvbT4NCiAgKi8NCiANCiAjaW5jbHVkZSA8bGludXgvY2xrLmg+ DQpAQCAtMjMsMTAgKzI0LDU5IEBADQogI2luY2x1ZGUgPG1lZGlhL3ZpZGVvYnVmMi1kbWEtY29u dGlnLmg+DQogI2luY2x1ZGUgPHNvYy9tZWRpYXRlay9zbWkuaD4NCiANCisjaW5jbHVkZSAibXRr X2pwZWdfZW5jX2h3LmgiDQogI2luY2x1ZGUgIm10a19qcGVnX2RlY19ody5oIg0KICNpbmNsdWRl ICJtdGtfanBlZ19jb3JlLmgiDQogI2luY2x1ZGUgIm10a19qcGVnX2RlY19wYXJzZS5oIg0KIA0K K3N0YXRpYyBzdHJ1Y3QgbXRrX2pwZWdfZm10IG10a19qcGVnX2VuY19mb3JtYXRzW10gPSB7DQor CXsNCisJCS5mb3VyY2MJCT0gVjRMMl9QSVhfRk1UX0pQRUcsDQorCQkuY29scGxhbmVzCT0gMSwN CisJCS5mbGFncwkJPSBNVEtfSlBFR19GTVRfRkxBR19DQVBUVVJFLA0KKwl9LA0KKwl7DQorCQku Zm91cmNjCQk9IFY0TDJfUElYX0ZNVF9OVjEyTSwNCisJCS5od19mb3JtYXQJPSBKUEVHX0VOQ19Z VVZfRk9STUFUX05WMTIsDQorCQkuaF9zYW1wbGUJPSB7NCwgNH0sDQorCQkudl9zYW1wbGUJPSB7 NCwgMn0sDQorCQkuY29scGxhbmVzCT0gMiwNCisJCS5oX2FsaWduCT0gNCwNCisJCS52X2FsaWdu CT0gNCwNCisJCS5mbGFncwkJPSBNVEtfSlBFR19GTVRfRkxBR19PVVRQVVQsDQorCX0sDQorCXsN CisJCS5mb3VyY2MJCT0gVjRMMl9QSVhfRk1UX05WMjFNLA0KKwkJLmh3X2Zvcm1hdAk9IEpFUEdf RU5DX1lVVl9GT1JNQVRfTlYyMSwNCisJCS5oX3NhbXBsZQk9IHs0LCA0fSwNCisJCS52X3NhbXBs ZQk9IHs0LCAyfSwNCisJCS5jb2xwbGFuZXMJPSAyLA0KKwkJLmhfYWxpZ24JPSA0LA0KKwkJLnZf YWxpZ24JPSA0LA0KKwkJLmZsYWdzCQk9IE1US19KUEVHX0ZNVF9GTEFHX09VVFBVVCwNCisJfSwN CisJew0KKwkJLmZvdXJjYwkJPSBWNEwyX1BJWF9GTVRfWVVZViwNCisJCS5od19mb3JtYXQJPSBK UEVHX0VOQ19ZVVZfRk9STUFUX1lVWVYsDQorCQkuaF9zYW1wbGUJPSB7OH0sDQorCQkudl9zYW1w bGUJPSB7NH0sDQorCQkuY29scGxhbmVzCT0gMSwNCisJCS5oX2FsaWduCT0gNSwNCisJCS52X2Fs aWduCT0gMywNCisJCS5mbGFncwkJPSBNVEtfSlBFR19GTVRfRkxBR19PVVRQVVQsDQorCX0sDQor CXsNCisJCS5mb3VyY2MJCT0gVjRMMl9QSVhfRk1UX1lWWVUsDQorCQkuaHdfZm9ybWF0CT0gSlBF R19FTkNfWVVWX0ZPUk1BVF9ZVllVLA0KKwkJLmhfc2FtcGxlCT0gezh9LA0KKwkJLnZfc2FtcGxl CT0gezR9LA0KKwkJLmNvbHBsYW5lcwk9IDEsDQorCQkuaF9hbGlnbgk9IDUsDQorCQkudl9hbGln bgk9IDMsDQorCQkuZmxhZ3MJCT0gTVRLX0pQRUdfRk1UX0ZMQUdfT1VUUFVULA0KKwl9LA0KK307 DQorDQogc3RhdGljIHN0cnVjdCBtdGtfanBlZ19mbXQgbXRrX2pwZWdfZGVjX2Zvcm1hdHNbXSA9 IHsNCiAJew0KIAkJLmZvdXJjYwkJPSBWNEwyX1BJWF9GTVRfSlBFRywNCkBAIC01Myw2ICsxMDMs NyBAQCBzdGF0aWMgc3RydWN0IG10a19qcGVnX2ZtdCBtdGtfanBlZ19kZWNfZm9ybWF0c1tdID0g ew0KIAl9LA0KIH07DQogDQorI2RlZmluZSBNVEtfSlBFR19FTkNfTlVNX0ZPUk1BVFMgQVJSQVlf U0laRShtdGtfanBlZ19lbmNfZm9ybWF0cykNCiAjZGVmaW5lIE1US19KUEVHX0RFQ19OVU1fRk9S TUFUUyBBUlJBWV9TSVpFKG10a19qcGVnX2RlY19mb3JtYXRzKQ0KIA0KIHN0cnVjdCBtdGtfanBl Z19zcmNfYnVmIHsNCkBAIC02NCw2ICsxMTUsMTEgQEAgc3RydWN0IG10a19qcGVnX3NyY19idWYg ew0KIHN0YXRpYyBpbnQgZGVidWc7DQogbW9kdWxlX3BhcmFtKGRlYnVnLCBpbnQsIDA2NDQpOw0K IA0KK3N0YXRpYyBpbmxpbmUgc3RydWN0IG10a19qcGVnX2N0eCAqY3RybF90b19jdHgoc3RydWN0 IHY0bDJfY3RybCAqY3RybCkNCit7DQorCXJldHVybiBjb250YWluZXJfb2YoY3RybC0+aGFuZGxl ciwgc3RydWN0IG10a19qcGVnX2N0eCwgY3RybF9oZGwpOw0KK30NCisNCiBzdGF0aWMgaW5saW5l IHN0cnVjdCBtdGtfanBlZ19jdHggKm10a19qcGVnX2ZoX3RvX2N0eChzdHJ1Y3QgdjRsMl9maCAq ZmgpDQogew0KIAlyZXR1cm4gY29udGFpbmVyX29mKGZoLCBzdHJ1Y3QgbXRrX2pwZWdfY3R4LCBm aCk7DQpAQCAtODgsNiArMTQ0LDUzIEBAIHN0YXRpYyBpbnQgbXRrX2pwZWdfcXVlcnljYXAoc3Ry dWN0IGZpbGUgKmZpbGUsIHZvaWQgKnByaXYsDQogCXJldHVybiAwOw0KIH0NCiANCitzdGF0aWMg aW50IHZpZGlvY19qcGVnX2VuY19zX2N0cmwoc3RydWN0IHY0bDJfY3RybCAqY3RybCkNCit7DQor CXN0cnVjdCBtdGtfanBlZ19jdHggKmN0eCA9IGN0cmxfdG9fY3R4KGN0cmwpOw0KKw0KKwlzd2l0 Y2ggKGN0cmwtPmlkKSB7DQorCWNhc2UgVjRMMl9DSURfSlBFR19SRVNUQVJUX0lOVEVSVkFMOg0K KwkJY3R4LT5yZXN0YXJ0X2ludGVydmFsID0gY3RybC0+dmFsOw0KKwkJYnJlYWs7DQorCWNhc2Ug VjRMMl9DSURfSlBFR19DT01QUkVTU0lPTl9RVUFMSVRZOg0KKwkJY3R4LT5lbmNfcXVhbGl0eSA9 IGN0cmwtPnZhbDsNCisJCWJyZWFrOw0KKwljYXNlIFY0TDJfQ0lEX0pQRUdfQUNUSVZFX01BUktF UjoNCisJCWN0eC0+ZW5hYmxlX2V4aWYgPSBjdHJsLT52YWwgJiBWNEwyX0pQRUdfQUNUSVZFX01B UktFUl9BUFAxOw0KKwkJYnJlYWs7DQorCX0NCisNCisJcmV0dXJuIDA7DQorfQ0KKw0KK3N0YXRp YyBjb25zdCBzdHJ1Y3QgdjRsMl9jdHJsX29wcyBtdGtfanBlZ19lbmNfY3RybF9vcHMgPSB7DQor CS5zX2N0cmwgPSB2aWRpb2NfanBlZ19lbmNfc19jdHJsLA0KK307DQorDQorc3RhdGljIGludCBt dGtfanBlZ19lbmNfY3RybHNfc2V0dXAoc3RydWN0IG10a19qcGVnX2N0eCAqY3R4KQ0KK3sNCisJ Y29uc3Qgc3RydWN0IHY0bDJfY3RybF9vcHMgKm9wcyA9ICZtdGtfanBlZ19lbmNfY3RybF9vcHM7 DQorCXN0cnVjdCB2NGwyX2N0cmxfaGFuZGxlciAqaGFuZGxlciA9ICZjdHgtPmN0cmxfaGRsOw0K Kw0KKwl2NGwyX2N0cmxfaGFuZGxlcl9pbml0KGhhbmRsZXIsIDMpOw0KKw0KKwl2NGwyX2N0cmxf bmV3X3N0ZChoYW5kbGVyLCBvcHMsIFY0TDJfQ0lEX0pQRUdfUkVTVEFSVF9JTlRFUlZBTCwgMCwg MTAwLA0KKwkJCSAgMSwgMCk7DQorCXY0bDJfY3RybF9uZXdfc3RkKGhhbmRsZXIsIG9wcywgVjRM Ml9DSURfSlBFR19DT01QUkVTU0lPTl9RVUFMSVRZLCA0OCwNCisJCQkgIDEwMCwgMSwgOTApOw0K Kwl2NGwyX2N0cmxfbmV3X3N0ZChoYW5kbGVyLCBvcHMsIFY0TDJfQ0lEX0pQRUdfQUNUSVZFX01B UktFUiwgMCwNCisJCQkgIFY0TDJfSlBFR19BQ1RJVkVfTUFSS0VSX0FQUDEsIDAsIDApOw0KKw0K KwlpZiAoaGFuZGxlci0+ZXJyb3IpIHsNCisJCXY0bDJfY3RybF9oYW5kbGVyX2ZyZWUoJmN0eC0+ Y3RybF9oZGwpOw0KKwkJcmV0dXJuIGhhbmRsZXItPmVycm9yOw0KKwl9DQorDQorCXY0bDJfY3Ry bF9oYW5kbGVyX3NldHVwKCZjdHgtPmN0cmxfaGRsKTsNCisNCisJcmV0dXJuIDA7DQorfQ0KKw0K IHN0YXRpYyBpbnQgbXRrX2pwZWdfZW51bV9mbXQoc3RydWN0IG10a19qcGVnX2ZtdCAqbXRrX2pw ZWdfZm9ybWF0cywgaW50IG4sDQogCQkJICAgICBzdHJ1Y3QgdjRsMl9mbXRkZXNjICpmLCB1MzIg dHlwZSkNCiB7DQpAQCAtMzMxLDYgKzQzNCw4IEBAIHN0YXRpYyBpbnQgbXRrX2pwZWdfc19mbXRf bXBsYW5lKHN0cnVjdCBtdGtfanBlZ19jdHggKmN0eCwNCiAJCQkJCSAgIHBpeF9tcC0+cGl4ZWxm b3JtYXQsIGZtdF90eXBlKTsNCiAJcV9kYXRhLT5waXhfbXAud2lkdGggPSBwaXhfbXAtPndpZHRo Ow0KIAlxX2RhdGEtPnBpeF9tcC5oZWlnaHQgPSBwaXhfbXAtPmhlaWdodDsNCisJcV9kYXRhLT5l bmNfY3JvcF9yZWN0LndpZHRoID0gcGl4X21wLT53aWR0aDsNCisJcV9kYXRhLT5lbmNfY3JvcF9y ZWN0LmhlaWdodCA9IHBpeF9tcC0+aGVpZ2h0Ow0KIAlxX2RhdGEtPnBpeF9tcC5jb2xvcnNwYWNl ID0gVjRMMl9DT0xPUlNQQUNFX1NSR0I7DQogCXFfZGF0YS0+cGl4X21wLnljYmNyX2VuYyA9IFY0 TDJfWUNCQ1JfRU5DXzYwMTsNCiAJcV9kYXRhLT5waXhfbXAueGZlcl9mdW5jID0gVjRMMl9YRkVS X0ZVTkNfU1JHQjsNCkBAIC00MDcsNiArNTEyLDMxIEBAIHN0YXRpYyBpbnQgbXRrX2pwZWdfc3Vi c2NyaWJlX2V2ZW50KHN0cnVjdCB2NGwyX2ZoICpmaCwNCiAJcmV0dXJuIHY0bDJfY3RybF9zdWJz Y3JpYmVfZXZlbnQoZmgsIHN1Yik7DQogfQ0KIA0KK3N0YXRpYyBpbnQgbXRrX2pwZWdfZW5jX2df c2VsZWN0aW9uKHN0cnVjdCBmaWxlICpmaWxlLCB2b2lkICpwcml2LA0KKwkJCQkgICAgc3RydWN0 IHY0bDJfc2VsZWN0aW9uICpzKQ0KK3sNCisJc3RydWN0IG10a19qcGVnX2N0eCAqY3R4ID0gbXRr X2pwZWdfZmhfdG9fY3R4KHByaXYpOw0KKw0KKwlpZiAocy0+dHlwZSAhPSBWNEwyX0JVRl9UWVBF X1ZJREVPX09VVFBVVCkNCisJCXJldHVybiAtRUlOVkFMOw0KKw0KKwlzd2l0Y2ggKHMtPnRhcmdl dCkgew0KKwljYXNlIFY0TDJfU0VMX1RHVF9DUk9QOg0KKwkJcy0+ciA9IGN0eC0+b3V0X3EuZW5j X2Nyb3BfcmVjdDsNCisJCWJyZWFrOw0KKwljYXNlIFY0TDJfU0VMX1RHVF9DUk9QX0JPVU5EUzoN CisJY2FzZSBWNEwyX1NFTF9UR1RfQ1JPUF9ERUZBVUxUOg0KKwkJcy0+ci53aWR0aCA9IGN0eC0+ b3V0X3EucGl4X21wLndpZHRoOw0KKwkJcy0+ci5oZWlnaHQgPSBjdHgtPm91dF9xLnBpeF9tcC5o ZWlnaHQ7DQorCQlzLT5yLmxlZnQgPSAwOw0KKwkJcy0+ci50b3AgPSAwOw0KKwkJYnJlYWs7DQor CWRlZmF1bHQ6DQorCQlyZXR1cm4gLUVJTlZBTDsNCisJfQ0KKwlyZXR1cm4gMDsNCit9DQorDQog c3RhdGljIGludCBtdGtfanBlZ19kZWNfZ19zZWxlY3Rpb24oc3RydWN0IGZpbGUgKmZpbGUsIHZv aWQgKnByaXYsDQogCQkJCSAgICBzdHJ1Y3QgdjRsMl9zZWxlY3Rpb24gKnMpDQogew0KQEAgLTQz Niw2ICs1NjYsNTYgQEAgc3RhdGljIGludCBtdGtfanBlZ19kZWNfZ19zZWxlY3Rpb24oc3RydWN0 IGZpbGUgKmZpbGUsIHZvaWQgKnByaXYsDQogCXJldHVybiAwOw0KIH0NCiANCitzdGF0aWMgaW50 IG10a19qcGVnX2VuY19zX3NlbGVjdGlvbihzdHJ1Y3QgZmlsZSAqZmlsZSwgdm9pZCAqcHJpdiwN CisJCQkJICAgIHN0cnVjdCB2NGwyX3NlbGVjdGlvbiAqcykNCit7DQorCXN0cnVjdCBtdGtfanBl Z19jdHggKmN0eCA9IG10a19qcGVnX2ZoX3RvX2N0eChwcml2KTsNCisNCisJaWYgKHMtPnR5cGUg IT0gVjRMMl9CVUZfVFlQRV9WSURFT19PVVRQVVQpDQorCQlyZXR1cm4gLUVJTlZBTDsNCisNCisJ c3dpdGNoIChzLT50YXJnZXQpIHsNCisJY2FzZSBWNEwyX1NFTF9UR1RfQ1JPUDoNCisJCXMtPnIu bGVmdCA9IDA7DQorCQlzLT5yLnRvcCA9IDA7DQorCQlzLT5yLndpZHRoID0gbWluKHMtPnIud2lk dGgsIGN0eC0+b3V0X3EucGl4X21wLndpZHRoKTsNCisJCXMtPnIuaGVpZ2h0ID0gbWluKHMtPnIu aGVpZ2h0LCBjdHgtPm91dF9xLnBpeF9tcC5oZWlnaHQpOw0KKwkJY3R4LT5vdXRfcS5lbmNfY3Jv cF9yZWN0ID0gcy0+cjsNCisJCWJyZWFrOw0KKwlkZWZhdWx0Og0KKwkJcmV0dXJuIC1FSU5WQUw7 DQorCX0NCisNCisJcmV0dXJuIDA7DQorfQ0KKw0KK3N0YXRpYyBjb25zdCBzdHJ1Y3QgdjRsMl9p b2N0bF9vcHMgbXRrX2pwZWdfZW5jX2lvY3RsX29wcyA9IHsNCisJLnZpZGlvY19xdWVyeWNhcCAg ICAgICAgICAgICAgICA9IG10a19qcGVnX3F1ZXJ5Y2FwLA0KKwkudmlkaW9jX2VudW1fZm10X3Zp ZF9jYXAJPSBtdGtfanBlZ19lbnVtX2ZtdF92aWRfY2FwLA0KKwkudmlkaW9jX2VudW1fZm10X3Zp ZF9vdXQJPSBtdGtfanBlZ19lbnVtX2ZtdF92aWRfb3V0LA0KKwkudmlkaW9jX3RyeV9mbXRfdmlk X2NhcF9tcGxhbmUJPSBtdGtfanBlZ190cnlfZm10X3ZpZF9jYXBfbXBsYW5lLA0KKwkudmlkaW9j X3RyeV9mbXRfdmlkX291dF9tcGxhbmUJPSBtdGtfanBlZ190cnlfZm10X3ZpZF9vdXRfbXBsYW5l LA0KKwkudmlkaW9jX2dfZm10X3ZpZF9jYXBfbXBsYW5lICAgID0gbXRrX2pwZWdfZ19mbXRfdmlk X21wbGFuZSwNCisJLnZpZGlvY19nX2ZtdF92aWRfb3V0X21wbGFuZSAgICA9IG10a19qcGVnX2df Zm10X3ZpZF9tcGxhbmUsDQorCS52aWRpb2Nfc19mbXRfdmlkX2NhcF9tcGxhbmUgICAgPSBtdGtf anBlZ19zX2ZtdF92aWRfY2FwX21wbGFuZSwNCisJLnZpZGlvY19zX2ZtdF92aWRfb3V0X21wbGFu ZSAgICA9IG10a19qcGVnX3NfZm10X3ZpZF9vdXRfbXBsYW5lLA0KKwkudmlkaW9jX3FidWYgICAg ICAgICAgICAgICAgICAgID0gdjRsMl9tMm1faW9jdGxfcWJ1ZiwNCisJLnZpZGlvY19zdWJzY3Jp YmVfZXZlbnQgICAgICAgICA9IG10a19qcGVnX3N1YnNjcmliZV9ldmVudCwNCisJLnZpZGlvY19n X3NlbGVjdGlvbgkJPSBtdGtfanBlZ19lbmNfZ19zZWxlY3Rpb24sDQorCS52aWRpb2Nfc19zZWxl Y3Rpb24JCT0gbXRrX2pwZWdfZW5jX3Nfc2VsZWN0aW9uLA0KKw0KKwkudmlkaW9jX2NyZWF0ZV9i dWZzCQk9IHY0bDJfbTJtX2lvY3RsX2NyZWF0ZV9idWZzLA0KKwkudmlkaW9jX3ByZXBhcmVfYnVm CQk9IHY0bDJfbTJtX2lvY3RsX3ByZXBhcmVfYnVmLA0KKwkudmlkaW9jX3JlcWJ1ZnMgICAgICAg ICAgICAgICAgID0gdjRsMl9tMm1faW9jdGxfcmVxYnVmcywNCisJLnZpZGlvY19xdWVyeWJ1ZiAg ICAgICAgICAgICAgICA9IHY0bDJfbTJtX2lvY3RsX3F1ZXJ5YnVmLA0KKwkudmlkaW9jX2RxYnVm ICAgICAgICAgICAgICAgICAgID0gdjRsMl9tMm1faW9jdGxfZHFidWYsDQorCS52aWRpb2NfZXhw YnVmICAgICAgICAgICAgICAgICAgPSB2NGwyX20ybV9pb2N0bF9leHBidWYsDQorCS52aWRpb2Nf c3RyZWFtb24gICAgICAgICAgICAgICAgPSB2NGwyX20ybV9pb2N0bF9zdHJlYW1vbiwNCisJLnZp ZGlvY19zdHJlYW1vZmYgICAgICAgICAgICAgICA9IHY0bDJfbTJtX2lvY3RsX3N0cmVhbW9mZiwN CisNCisJLnZpZGlvY191bnN1YnNjcmliZV9ldmVudAk9IHY0bDJfZXZlbnRfdW5zdWJzY3JpYmUs DQorfTsNCisNCiBzdGF0aWMgY29uc3Qgc3RydWN0IHY0bDJfaW9jdGxfb3BzIG10a19qcGVnX2Rl Y19pb2N0bF9vcHMgPSB7DQogCS52aWRpb2NfcXVlcnljYXAgICAgICAgICAgICAgICAgPSBtdGtf anBlZ19xdWVyeWNhcCwNCiAJLnZpZGlvY19lbnVtX2ZtdF92aWRfY2FwCT0gbXRrX2pwZWdfZW51 bV9mbXRfdmlkX2NhcCwNCkBAIC01MDEsMTUgKzY4MSwyMiBAQCBzdGF0aWMgaW50IG10a19qcGVn X2J1Zl9wcmVwYXJlKHN0cnVjdCB2YjJfYnVmZmVyICp2YikNCiB7DQogCXN0cnVjdCBtdGtfanBl Z19jdHggKmN0eCA9IHZiMl9nZXRfZHJ2X3ByaXYodmItPnZiMl9xdWV1ZSk7DQogCXN0cnVjdCBt dGtfanBlZ19xX2RhdGEgKnFfZGF0YSA9IE5VTEw7DQorCXN0cnVjdCB2NGwyX3BsYW5lX3BpeF9m b3JtYXQgcGxhbmVfZm10ID0ge307DQogCWludCBpOw0KIA0KIAlxX2RhdGEgPSBtdGtfanBlZ19n ZXRfcV9kYXRhKGN0eCwgdmItPnZiMl9xdWV1ZS0+dHlwZSk7DQogCWlmICghcV9kYXRhKQ0KIAkJ cmV0dXJuIC1FSU5WQUw7DQogDQotCWZvciAoaSA9IDA7IGkgPCBxX2RhdGEtPmZtdC0+Y29scGxh bmVzOyBpKyspDQotCQl2YjJfc2V0X3BsYW5lX3BheWxvYWQodmIsIGksDQotCQkJCSAgICAgIHFf ZGF0YS0+cGl4X21wLnBsYW5lX2ZtdFtpXS5zaXplaW1hZ2UpOw0KKwlmb3IgKGkgPSAwOyBpIDwg cV9kYXRhLT5mbXQtPmNvbHBsYW5lczsgaSsrKSB7DQorCQlwbGFuZV9mbXQgPSBxX2RhdGEtPnBp eF9tcC5wbGFuZV9mbXRbaV07DQorCQlpZiAoY3R4LT5lbmFibGVfZXhpZiAmJg0KKwkJICAgIHFf ZGF0YS0+Zm10LT5mb3VyY2MgPT0gVjRMMl9QSVhfRk1UX0pQRUcpDQorCQkJdmIyX3NldF9wbGFu ZV9wYXlsb2FkKHZiLCBpLCBwbGFuZV9mbXQuc2l6ZWltYWdlICsNCisJCQkJCSAgICAgIE1US19K UEVHX01BWF9FWElGX1NJWkUpOw0KKwkJZWxzZQ0KKwkJCXZiMl9zZXRfcGxhbmVfcGF5bG9hZCh2 YiwgaSwgIHBsYW5lX2ZtdC5zaXplaW1hZ2UpOw0KKwl9DQogDQogCXJldHVybiAwOw0KIH0NCkBA IC01NzIsNiArNzU5LDE3IEBAIHN0YXRpYyB2b2lkIG10a19qcGVnX3NldF9xdWV1ZV9kYXRhKHN0 cnVjdCBtdGtfanBlZ19jdHggKmN0eCwNCiAJCSBwYXJhbS0+ZGVjX3csIHBhcmFtLT5kZWNfaCk7 DQogfQ0KIA0KK3N0YXRpYyB2b2lkIG10a19qcGVnX2VuY19idWZfcXVldWUoc3RydWN0IHZiMl9i dWZmZXIgKnZiKQ0KK3sNCisJc3RydWN0IG10a19qcGVnX2N0eCAqY3R4ID0gdmIyX2dldF9kcnZf cHJpdih2Yi0+dmIyX3F1ZXVlKTsNCisJc3RydWN0IG10a19qcGVnX2RldiAqanBlZyA9IGN0eC0+ anBlZzsNCisNCisJdjRsMl9kYmcoMiwgZGVidWcsICZqcGVnLT52NGwyX2RldiwgIiglZCkgYnVm X3EgaWQ9JWQsIHZiPSVwXG4iLA0KKwkJIHZiLT52YjJfcXVldWUtPnR5cGUsIHZiLT5pbmRleCwg dmIpOw0KKw0KKwl2NGwyX20ybV9idWZfcXVldWUoY3R4LT5maC5tMm1fY3R4LCB0b192YjJfdjRs Ml9idWZmZXIodmIpKTsNCit9DQorDQogc3RhdGljIHZvaWQgbXRrX2pwZWdfZGVjX2J1Zl9xdWV1 ZShzdHJ1Y3QgdmIyX2J1ZmZlciAqdmIpDQogew0KIAlzdHJ1Y3QgbXRrX2pwZWdfY3R4ICpjdHgg PSB2YjJfZ2V0X2Rydl9wcml2KHZiLT52YjJfcXVldWUpOw0KQEAgLTYyMCw2ICs4MTgsMTUgQEAg c3RhdGljIHN0cnVjdCB2YjJfdjRsMl9idWZmZXIgKm10a19qcGVnX2J1Zl9yZW1vdmUoc3RydWN0 IG10a19qcGVnX2N0eCAqY3R4LA0KIAkJcmV0dXJuIHY0bDJfbTJtX2RzdF9idWZfcmVtb3ZlKGN0 eC0+ZmgubTJtX2N0eCk7DQogfQ0KIA0KK3N0YXRpYyB2b2lkIG10a19qcGVnX2VuY19zdG9wX3N0 cmVhbWluZyhzdHJ1Y3QgdmIyX3F1ZXVlICpxKQ0KK3sNCisJc3RydWN0IG10a19qcGVnX2N0eCAq Y3R4ID0gdmIyX2dldF9kcnZfcHJpdihxKTsNCisJc3RydWN0IHZiMl92NGwyX2J1ZmZlciAqdmI7 DQorDQorCXdoaWxlICgodmIgPSBtdGtfanBlZ19idWZfcmVtb3ZlKGN0eCwgcS0+dHlwZSkpKQ0K KwkJdjRsMl9tMm1fYnVmX2RvbmUodmIsIFZCMl9CVUZfU1RBVEVfRVJST1IpOw0KK30NCisNCiBz dGF0aWMgdm9pZCBtdGtfanBlZ19kZWNfc3RvcF9zdHJlYW1pbmcoc3RydWN0IHZiMl9xdWV1ZSAq cSkNCiB7DQogCXN0cnVjdCBtdGtfanBlZ19jdHggKmN0eCA9IHZiMl9nZXRfZHJ2X3ByaXYocSk7 DQpAQCAtNjU1LDYgKzg2MiwxNSBAQCBzdGF0aWMgY29uc3Qgc3RydWN0IHZiMl9vcHMgbXRrX2pw ZWdfZGVjX3FvcHMgPSB7DQogCS5zdG9wX3N0cmVhbWluZyAgICAgPSBtdGtfanBlZ19kZWNfc3Rv cF9zdHJlYW1pbmcsDQogfTsNCiANCitzdGF0aWMgY29uc3Qgc3RydWN0IHZiMl9vcHMgbXRrX2pw ZWdfZW5jX3FvcHMgPSB7DQorCS5xdWV1ZV9zZXR1cCAgICAgICAgPSBtdGtfanBlZ19xdWV1ZV9z ZXR1cCwNCisJLmJ1Zl9wcmVwYXJlICAgICAgICA9IG10a19qcGVnX2J1Zl9wcmVwYXJlLA0KKwku YnVmX3F1ZXVlICAgICAgICAgID0gbXRrX2pwZWdfZW5jX2J1Zl9xdWV1ZSwNCisJLndhaXRfcHJl cGFyZSAgICAgICA9IHZiMl9vcHNfd2FpdF9wcmVwYXJlLA0KKwkud2FpdF9maW5pc2ggICAgICAg ID0gdmIyX29wc193YWl0X2ZpbmlzaCwNCisJLnN0b3Bfc3RyZWFtaW5nICAgICA9IG10a19qcGVn X2VuY19zdG9wX3N0cmVhbWluZywNCit9Ow0KKw0KIHN0YXRpYyB2b2lkIG10a19qcGVnX3NldF9k ZWNfc3JjKHN0cnVjdCBtdGtfanBlZ19jdHggKmN0eCwNCiAJCQkJIHN0cnVjdCB2YjJfYnVmZmVy ICpzcmNfYnVmLA0KIAkJCQkgc3RydWN0IG10a19qcGVnX2JzICpicykNCkBAIC02OTIsNiArOTA4 LDQ4IEBAIHN0YXRpYyBpbnQgbXRrX2pwZWdfc2V0X2RlY19kc3Qoc3RydWN0IG10a19qcGVnX2N0 eCAqY3R4LA0KIAlyZXR1cm4gMDsNCiB9DQogDQorc3RhdGljIHZvaWQgbXRrX2pwZWdfZW5jX2Rl dmljZV9ydW4odm9pZCAqcHJpdikNCit7DQorCXN0cnVjdCBtdGtfanBlZ19jdHggKmN0eCA9IHBy aXY7DQorCXN0cnVjdCBtdGtfanBlZ19kZXYgKmpwZWcgPSBjdHgtPmpwZWc7DQorCXN0cnVjdCB2 YjJfdjRsMl9idWZmZXIgKnNyY19idWYsICpkc3RfYnVmOw0KKwllbnVtIHZiMl9idWZmZXJfc3Rh dGUgYnVmX3N0YXRlID0gVkIyX0JVRl9TVEFURV9FUlJPUjsNCisJdW5zaWduZWQgbG9uZyBmbGFn czsNCisJaW50IHJldDsNCisNCisJc3JjX2J1ZiA9IHY0bDJfbTJtX25leHRfc3JjX2J1ZihjdHgt PmZoLm0ybV9jdHgpOw0KKwlkc3RfYnVmID0gdjRsMl9tMm1fbmV4dF9kc3RfYnVmKGN0eC0+Zmgu bTJtX2N0eCk7DQorDQorCXJldCA9IHBtX3J1bnRpbWVfZ2V0X3N5bmMoanBlZy0+ZGV2KTsNCisJ aWYgKHJldCA8IDApDQorCQlnb3RvIGVuY19lbmQ7DQorDQorCXNjaGVkdWxlX2RlbGF5ZWRfd29y aygmanBlZy0+am9iX3RpbWVvdXRfd29yaywNCisJCQkgICAgICBtc2Vjc190b19qaWZmaWVzKE1U S19KUEVHX0hXX1RJTUVPVVRfTVNFQykpOw0KKw0KKwlzcGluX2xvY2tfaXJxc2F2ZSgmanBlZy0+ aHdfbG9jaywgZmxhZ3MpOw0KKw0KKwkvKg0KKwkgKiBSZXNldHRpbmcgdGhlIGhhcmR3YXJlIGV2 ZXJ5IGZyYW1lIGlzIHRvIGVuc3VyZSB0aGF0IGFsbCB0aGUNCisJICogcmVnaXN0ZXJzIGFyZSBj bGVhcmVkLiBUaGlzIGlzIGEgaGFyZHdhcmUgcmVxdWlyZW1lbnQuDQorCSAqLw0KKwltdGtfanBl Z19lbmNfcmVzZXQoanBlZy0+cmVnX2Jhc2UpOw0KKw0KKwltdGtfanBlZ19zZXRfZW5jX3NyYyhj dHgsIGpwZWctPnJlZ19iYXNlLCAmc3JjX2J1Zi0+dmIyX2J1Zik7DQorCW10a19qcGVnX3NldF9l bmNfZHN0KGN0eCwganBlZy0+cmVnX2Jhc2UsICZkc3RfYnVmLT52YjJfYnVmKTsNCisJbXRrX2pw ZWdfc2V0X2VuY19wYXJhbXMoY3R4LCBqcGVnLT5yZWdfYmFzZSk7DQorCW10a19qcGVnX2VuY19z dGFydChqcGVnLT5yZWdfYmFzZSk7DQorCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmpwZWctPmh3 X2xvY2ssIGZsYWdzKTsNCisJcmV0dXJuOw0KKw0KK2VuY19lbmQ6DQorCXY0bDJfbTJtX3NyY19i dWZfcmVtb3ZlKGN0eC0+ZmgubTJtX2N0eCk7DQorCXY0bDJfbTJtX2RzdF9idWZfcmVtb3ZlKGN0 eC0+ZmgubTJtX2N0eCk7DQorCXY0bDJfbTJtX2J1Zl9kb25lKHNyY19idWYsIGJ1Zl9zdGF0ZSk7 DQorCXY0bDJfbTJtX2J1Zl9kb25lKGRzdF9idWYsIGJ1Zl9zdGF0ZSk7DQorCXY0bDJfbTJtX2pv Yl9maW5pc2goanBlZy0+bTJtX2RldiwgY3R4LT5maC5tMm1fY3R4KTsNCit9DQorDQogc3RhdGlj IHZvaWQgbXRrX2pwZWdfZGVjX2RldmljZV9ydW4odm9pZCAqcHJpdikNCiB7DQogCXN0cnVjdCBt dGtfanBlZ19jdHggKmN0eCA9IHByaXY7DQpAQCAtNzUwLDYgKzEwMDgsMTAgQEAgc3RhdGljIGlu dCBtdGtfanBlZ19kZWNfam9iX3JlYWR5KHZvaWQgKnByaXYpDQogCXJldHVybiAoY3R4LT5zdGF0 ZSA9PSBNVEtfSlBFR19SVU5OSU5HKSA/IDEgOiAwOw0KIH0NCiANCitzdGF0aWMgY29uc3Qgc3Ry dWN0IHY0bDJfbTJtX29wcyBtdGtfanBlZ19lbmNfbTJtX29wcyA9IHsNCisJLmRldmljZV9ydW4g PSBtdGtfanBlZ19lbmNfZGV2aWNlX3J1biwNCit9Ow0KKw0KIHN0YXRpYyBjb25zdCBzdHJ1Y3Qg djRsMl9tMm1fb3BzIG10a19qcGVnX2RlY19tMm1fb3BzID0gew0KIAkuZGV2aWNlX3J1biA9IG10 a19qcGVnX2RlY19kZXZpY2VfcnVuLA0KIAkuam9iX3JlYWR5ICA9IG10a19qcGVnX2RlY19qb2Jf cmVhZHksDQpAQCAtODEwLDYgKzEwNzIsNTQgQEAgc3RhdGljIHZvaWQgbXRrX2pwZWdfY2xrX29m ZihzdHJ1Y3QgbXRrX2pwZWdfZGV2ICpqcGVnKQ0KIAltdGtfc21pX2xhcmJfcHV0KGpwZWctPmxh cmIpOw0KIH0NCiANCitzdGF0aWMgaXJxcmV0dXJuX3QgbXRrX2pwZWdfZW5jX2RvbmUoc3RydWN0 IG10a19qcGVnX2RldiAqanBlZykNCit7DQorCXN0cnVjdCBtdGtfanBlZ19jdHggKmN0eDsNCisJ c3RydWN0IHZiMl92NGwyX2J1ZmZlciAqc3JjX2J1ZiwgKmRzdF9idWY7DQorCWVudW0gdmIyX2J1 ZmZlcl9zdGF0ZSBidWZfc3RhdGUgPSBWQjJfQlVGX1NUQVRFX0VSUk9SOw0KKwl1MzIgcmVzdWx0 X3NpemU7DQorDQorCWN0eCA9IHY0bDJfbTJtX2dldF9jdXJyX3ByaXYoanBlZy0+bTJtX2Rldik7 DQorCWlmICghY3R4KSB7DQorCQl2NGwyX2VycigmanBlZy0+djRsMl9kZXYsICJDb250ZXh0IGlz IE5VTExcbiIpOw0KKwkJcmV0dXJuIElSUV9IQU5ETEVEOw0KKwl9DQorDQorCXNyY19idWYgPSB2 NGwyX20ybV9zcmNfYnVmX3JlbW92ZShjdHgtPmZoLm0ybV9jdHgpOw0KKwlkc3RfYnVmID0gdjRs Ml9tMm1fZHN0X2J1Zl9yZW1vdmUoY3R4LT5maC5tMm1fY3R4KTsNCisNCisJcmVzdWx0X3NpemUg PSBtdGtfanBlZ19lbmNfZ2V0X2ZpbGVfc2l6ZShqcGVnLT5yZWdfYmFzZSk7DQorCXZiMl9zZXRf cGxhbmVfcGF5bG9hZCgmZHN0X2J1Zi0+dmIyX2J1ZiwgMCwgcmVzdWx0X3NpemUpOw0KKw0KKwli dWZfc3RhdGUgPSBWQjJfQlVGX1NUQVRFX0RPTkU7DQorDQorCXY0bDJfbTJtX2J1Zl9kb25lKHNy Y19idWYsIGJ1Zl9zdGF0ZSk7DQorCXY0bDJfbTJtX2J1Zl9kb25lKGRzdF9idWYsIGJ1Zl9zdGF0 ZSk7DQorCXY0bDJfbTJtX2pvYl9maW5pc2goanBlZy0+bTJtX2RldiwgY3R4LT5maC5tMm1fY3R4 KTsNCisJcG1fcnVudGltZV9wdXQoY3R4LT5qcGVnLT5kZXYpOw0KKwlyZXR1cm4gSVJRX0hBTkRM RUQ7DQorfQ0KKw0KK3N0YXRpYyBpcnFyZXR1cm5fdCBtdGtfanBlZ19lbmNfaXJxKGludCBpcnEs IHZvaWQgKnByaXYpDQorew0KKwlzdHJ1Y3QgbXRrX2pwZWdfZGV2ICpqcGVnID0gcHJpdjsNCisJ dTMyIGlycV9zdGF0dXM7DQorCWlycXJldHVybl90IHJldCA9IElSUV9OT05FOw0KKw0KKwljYW5j ZWxfZGVsYXllZF93b3JrKCZqcGVnLT5qb2JfdGltZW91dF93b3JrKTsNCisNCisJaXJxX3N0YXR1 cyA9IHJlYWRsKGpwZWctPnJlZ19iYXNlICsgSlBFR19FTkNfSU5UX1NUUykgJg0KKwkJICAgICBK UEVHX0VOQ19JTlRfU1RBVFVTX01BU0tfQUxMSVJROw0KKwlpZiAoaXJxX3N0YXR1cykNCisJCXdy aXRlbCgwLCBqcGVnLT5yZWdfYmFzZSArIEpQRUdfRU5DX0lOVF9TVFMpOw0KKw0KKwlpZiAoIShp cnFfc3RhdHVzICYgSlBFR19FTkNfSU5UX1NUQVRVU19ET05FKSkNCisJCXJldHVybiByZXQ7DQor DQorCXJldCA9IG10a19qcGVnX2VuY19kb25lKGpwZWcpOw0KKwlyZXR1cm4gcmV0Ow0KK30NCisN CiBzdGF0aWMgaXJxcmV0dXJuX3QgbXRrX2pwZWdfZGVjX2lycShpbnQgaXJxLCB2b2lkICpwcml2 KQ0KIHsNCiAJc3RydWN0IG10a19qcGVnX2RldiAqanBlZyA9IHByaXY7DQpAQCAtODYyLDYgKzEx NzIsNyBAQCBzdGF0aWMgdm9pZCBtdGtfanBlZ19zZXRfZGVmYXVsdF9wYXJhbXMoc3RydWN0IG10 a19qcGVnX2N0eCAqY3R4KQ0KIAlzdHJ1Y3QgbXRrX2pwZWdfcV9kYXRhICpxID0gJmN0eC0+b3V0 X3E7DQogCXN0cnVjdCBtdGtfanBlZ19kZXYgKmpwZWcgPSBjdHgtPmpwZWc7DQogDQorCWN0eC0+ ZmguY3RybF9oYW5kbGVyID0gJmN0eC0+Y3RybF9oZGw7DQogCXEtPnBpeF9tcC5jb2xvcnNwYWNl ID0gVjRMMl9DT0xPUlNQQUNFX1NSR0I7DQogCXEtPnBpeF9tcC55Y2Jjcl9lbmMgPSBWNEwyX1lD QkNSX0VOQ182MDE7DQogCXEtPnBpeF9tcC5xdWFudGl6YXRpb24gPSBWNEwyX1FVQU5USVpBVElP Tl9GVUxMX1JBTkdFOw0KQEAgLTkxOCw2ICsxMjI5LDE1IEBAIHN0YXRpYyBpbnQgbXRrX2pwZWdf b3BlbihzdHJ1Y3QgZmlsZSAqZmlsZSkNCiAJCWdvdG8gZXJyb3I7DQogCX0NCiANCisJaWYgKGpw ZWctPnZhcmlhbnQtPmNhcF9xX2RlZmF1bHRfZm91cmNjID09IFY0TDJfUElYX0ZNVF9KUEVHKSB7 DQorCQlyZXQgPSBtdGtfanBlZ19lbmNfY3RybHNfc2V0dXAoY3R4KTsNCisJCWlmIChyZXQpIHsN CisJCQl2NGwyX2VycigmanBlZy0+djRsMl9kZXYsICJGYWlsZWQgdG8gc2V0dXAganBlZyBlbmMg Y29udHJvbHNcbiIpOw0KKwkJCWdvdG8gZXJyb3I7DQorCQl9DQorCX0gZWxzZSB7DQorCQl2NGwy X2N0cmxfaGFuZGxlcl9pbml0KCZjdHgtPmN0cmxfaGRsLCAwKTsNCisJfQ0KIAltdGtfanBlZ19z ZXRfZGVmYXVsdF9wYXJhbXMoY3R4KTsNCiAJbXV0ZXhfdW5sb2NrKCZqcGVnLT5sb2NrKTsNCiAJ cmV0dXJuIDA7DQpAQCAtOTM4LDYgKzEyNTgsNyBAQCBzdGF0aWMgaW50IG10a19qcGVnX3JlbGVh c2Uoc3RydWN0IGZpbGUgKmZpbGUpDQogDQogCW11dGV4X2xvY2soJmpwZWctPmxvY2spOw0KIAl2 NGwyX20ybV9jdHhfcmVsZWFzZShjdHgtPmZoLm0ybV9jdHgpOw0KKwl2NGwyX2N0cmxfaGFuZGxl cl9mcmVlKCZjdHgtPmN0cmxfaGRsKTsNCiAJdjRsMl9maF9kZWwoJmN0eC0+ZmgpOw0KIAl2NGwy X2ZoX2V4aXQoJmN0eC0+ZmgpOw0KIAlrZnJlZShjdHgpOw0KQEAgLTk1OSw2ICsxMjgwLDEwIEBA IHN0YXRpYyBzdHJ1Y3QgY2xrX2J1bGtfZGF0YSBtdDgxNzNfanBlZ19kZWNfY2xvY2tzW10gPSB7 DQogCXsgLmlkID0gImpwZ2RlYyIgfSwNCiB9Ow0KIA0KK3N0YXRpYyBzdHJ1Y3QgY2xrX2J1bGtf ZGF0YSBtdGtfanBlZ19jbG9ja3NbXSA9IHsNCisJeyAuaWQgPSAianBnZW5jIiB9LA0KK307DQor DQogc3RhdGljIGludCBtdGtfanBlZ19jbGtfaW5pdChzdHJ1Y3QgbXRrX2pwZWdfZGV2ICpqcGVn KQ0KIHsNCiAJc3RydWN0IGRldmljZV9ub2RlICpub2RlOw0KQEAgLTExOTAsNiArMTUxNSwyMSBA QCBzdGF0aWMgY29uc3Qgc3RydWN0IG10a19qcGVnX3ZhcmlhbnQgbXQ4MTczX2pwZWdfZHJ2ZGF0 YSA9IHsNCiAJLmNhcF9xX2RlZmF1bHRfZm91cmNjID0gVjRMMl9QSVhfRk1UX1lVVjQyME0sDQog fTsNCiANCitzdGF0aWMgY29uc3Qgc3RydWN0IG10a19qcGVnX3ZhcmlhbnQgbXRrX2pwZWdfZHJ2 ZGF0YSA9IHsNCisJLmNsa3MgPSBtdGtfanBlZ19jbG9ja3MsDQorCS5udW1fY2xrcyA9IEFSUkFZ X1NJWkUobXRrX2pwZWdfY2xvY2tzKSwNCisJLmZvcm1hdHMgPSBtdGtfanBlZ19lbmNfZm9ybWF0 cywNCisJLm51bV9mb3JtYXRzID0gTVRLX0pQRUdfRU5DX05VTV9GT1JNQVRTLA0KKwkucW9wcyA9 ICZtdGtfanBlZ19lbmNfcW9wcywNCisJLmlycV9oYW5kbGVyID0gbXRrX2pwZWdfZW5jX2lycSwN CisJLmh3X3Jlc2V0ID0gbXRrX2pwZWdfZW5jX3Jlc2V0LA0KKwkubTJtX29wcyA9ICZtdGtfanBl Z19lbmNfbTJtX29wcywNCisJLmRldl9uYW1lID0gIm10ay1qcGVnLWVuYyIsDQorCS5pb2N0bF9v cHMgPSAmbXRrX2pwZWdfZW5jX2lvY3RsX29wcywNCisJLm91dF9xX2RlZmF1bHRfZm91cmNjID0g VjRMMl9QSVhfRk1UX1lVWVYsDQorCS5jYXBfcV9kZWZhdWx0X2ZvdXJjYyA9IFY0TDJfUElYX0ZN VF9KUEVHLA0KK307DQorDQogc3RhdGljIGNvbnN0IHN0cnVjdCBvZl9kZXZpY2VfaWQgbXRrX2pw ZWdfbWF0Y2hbXSA9IHsNCiAJew0KIAkJLmNvbXBhdGlibGUgPSAibWVkaWF0ZWssbXQ4MTczLWpw Z2RlYyIsDQpAQCAtMTE5OSw2ICsxNTM5LDEwIEBAIHN0YXRpYyBjb25zdCBzdHJ1Y3Qgb2ZfZGV2 aWNlX2lkIG10a19qcGVnX21hdGNoW10gPSB7DQogCQkuY29tcGF0aWJsZSA9ICJtZWRpYXRlayxt dDI3MDEtanBnZGVjIiwNCiAJCS5kYXRhID0gJm10ODE3M19qcGVnX2RydmRhdGEsDQogCX0sDQor CXsNCisJCS5jb21wYXRpYmxlID0gIm1lZGlhdGVrLG10ay1qcGdlbmMiLA0KKwkJLmRhdGEgPSAm bXRrX2pwZWdfZHJ2ZGF0YSwNCisJfSwNCiAJe30sDQogfTsNCiANCmRpZmYgLS1naXQgYS9kcml2 ZXJzL21lZGlhL3BsYXRmb3JtL210ay1qcGVnL210a19qcGVnX2NvcmUuaCBiL2RyaXZlcnMvbWVk aWEvcGxhdGZvcm0vbXRrLWpwZWcvbXRrX2pwZWdfY29yZS5oDQppbmRleCBkMTFkMzY2YTI0N2Uu LjY4ZTYzNGYwMmUwMCAxMDA2NDQNCi0tLSBhL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vbXRrLWpw ZWcvbXRrX2pwZWdfY29yZS5oDQorKysgYi9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL210ay1qcGVn L210a19qcGVnX2NvcmUuaA0KQEAgLTMsNiArMyw3IEBADQogICogQ29weXJpZ2h0IChjKSAyMDE2 IE1lZGlhVGVrIEluYy4NCiAgKiBBdXRob3I6IE1pbmcgSHNpdSBUc2FpIDxtaW5naHNpdS50c2Fp QG1lZGlhdGVrLmNvbT4NCiAgKiAgICAgICAgIFJpY2sgQ2hhbmcgPHJpY2suY2hhbmdAbWVkaWF0 ZWsuY29tPg0KKyAqICAgICAgICAgWGlhIEppYW5nIDx4aWEuamlhbmdAbWVkaWF0ZWsuY29tPg0K ICAqLw0KIA0KICNpZm5kZWYgX01US19KUEVHX0NPUkVfSA0KQEAgLTI5LDYgKzMwLDggQEANCiAN CiAjZGVmaW5lIE1US19KUEVHX0hXX1RJTUVPVVRfTVNFQyAxMDAwDQogDQorI2RlZmluZSBNVEtf SlBFR19NQVhfRVhJRl9TSVpFCSg2NCAqIDEwMjQpDQorDQogLyoqDQogICogZW51bSBtdGtfanBl Z19jdHhfc3RhdGUgLSBzdGF0ZXMgb2YgdGhlIGNvbnRleHQgc3RhdGUgbWFjaGluZQ0KICAqIEBN VEtfSlBFR19JTklUOgkJY3VycmVudCBzdGF0ZSBpcyBpbml0aWFsaXplZA0KQEAgLTEwNCw2ICsx MDcsNyBAQCBzdHJ1Y3QgbXRrX2pwZWdfZGV2IHsNCiAvKioNCiAgKiBzdHJ1Y3QganBlZ19mbXQg LSBkcml2ZXIncyBpbnRlcm5hbCBjb2xvciBmb3JtYXQgZGF0YQ0KICAqIEBmb3VyY2M6CXRoZSBm b3VyY2MgY29kZSwgMCBpZiBub3QgYXBwbGljYWJsZQ0KKyAqIEBod19mb3JtYXQ6CWhhcmR3YXJl IGZvcm1hdCB2YWx1ZQ0KICAqIEBoX3NhbXBsZToJaG9yaXpvbnRhbCBzYW1wbGUgY291bnQgb2Yg cGxhbmUgaW4gNCAqIDQgcGl4ZWwgaW1hZ2UNCiAgKiBAdl9zYW1wbGU6CXZlcnRpY2FsIHNhbXBs ZSBjb3VudCBvZiBwbGFuZSBpbiA0ICogNCBwaXhlbCBpbWFnZQ0KICAqIEBjb2xwbGFuZXM6CW51 bWJlciBvZiBjb2xvciBwbGFuZXMgKDEgZm9yIHBhY2tlZCBmb3JtYXRzKQ0KQEAgLTExMyw2ICsx MTcsNyBAQCBzdHJ1Y3QgbXRrX2pwZWdfZGV2IHsNCiAgKi8NCiBzdHJ1Y3QgbXRrX2pwZWdfZm10 IHsNCiAJdTMyCWZvdXJjYzsNCisJdTMyCWh3X2Zvcm1hdDsNCiAJaW50CWhfc2FtcGxlW1ZJREVP X01BWF9QTEFORVNdOw0KIAlpbnQJdl9zYW1wbGVbVklERU9fTUFYX1BMQU5FU107DQogCWludAlj b2xwbGFuZXM7DQpAQCAtMTI1LDEwICsxMzAsMTIgQEAgc3RydWN0IG10a19qcGVnX2ZtdCB7DQog ICogbXRrX2pwZWdfcV9kYXRhIC0gcGFyYW1ldGVycyBvZiBvbmUgcXVldWUNCiAgKiBAZm10Ogkg IGRyaXZlci1zcGVjaWZpYyBmb3JtYXQgb2YgdGhpcyBxdWV1ZQ0KICAqIEBwaXhfbXA6CSAgbXVs dGlwbGFuYXIgZm9ybWF0DQorICogQGVuY19jcm9wX3JlY3Q6CWpwZWcgZW5jb2RlciBjcm9wIGlu Zm9ybWF0aW9uDQogICovDQogc3RydWN0IG10a19qcGVnX3FfZGF0YSB7DQogCXN0cnVjdCBtdGtf anBlZ19mbXQJKmZtdDsNCiAJc3RydWN0IHY0bDJfcGl4X2Zvcm1hdF9tcGxhbmUgcGl4X21wOw0K KwlzdHJ1Y3QgdjRsMl9yZWN0IGVuY19jcm9wX3JlY3Q7DQogfTsNCiANCiAvKioNCkBAIC0xMzgs NiArMTQ1LDEwIEBAIHN0cnVjdCBtdGtfanBlZ19xX2RhdGEgew0KICAqIEBjYXBfcToJCWRlc3Rp bmF0aW9uIChjYXB0dXJlKSBxdWV1ZSBxdWV1ZSBpbmZvcm1hdGlvbg0KICAqIEBmaDoJCQlWNEwy IGZpbGUgaGFuZGxlDQogICogQHN0YXRlOgkJc3RhdGUgb2YgdGhlIGNvbnRleHQNCisgKiBAZW5h YmxlX2V4aWY6CWVuYWJsZSBleGlmIG1vZGUgb2YganBlZyBlbmNvZGVyDQorICogQGVuY19xdWFs aXR5OglqcGVnIGVuY29kZXIgcXVhbGl0eQ0KKyAqIEByZXN0YXJ0X2ludGVydmFsOglqcGVnIGVu Y29kZXIgcmVzdGFydCBpbnRlcnZhbA0KKyAqIEBjdHJsX2hkbDoJCWNvbnRyb2xzIGhhbmRsZXIN CiAgKi8NCiBzdHJ1Y3QgbXRrX2pwZWdfY3R4IHsNCiAJc3RydWN0IG10a19qcGVnX2RldgkJKmpw ZWc7DQpAQCAtMTQ1LDYgKzE1NiwxMCBAQCBzdHJ1Y3QgbXRrX2pwZWdfY3R4IHsNCiAJc3RydWN0 IG10a19qcGVnX3FfZGF0YQkJY2FwX3E7DQogCXN0cnVjdCB2NGwyX2ZoCQkJZmg7DQogCWVudW0g bXRrX2pwZWdfY3R4X3N0YXRlCQlzdGF0ZTsNCisJYm9vbCBlbmFibGVfZXhpZjsNCisJdTggZW5j X3F1YWxpdHk7DQorCXU4IHJlc3RhcnRfaW50ZXJ2YWw7DQorCXN0cnVjdCB2NGwyX2N0cmxfaGFu ZGxlciBjdHJsX2hkbDsNCiB9Ow0KIA0KICNlbmRpZiAvKiBfTVRLX0pQRUdfQ09SRV9IICovDQpk aWZmIC0tZ2l0IGEvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9tdGstanBlZy9tdGtfanBlZ19lbmNf aHcuYyBiL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vbXRrLWpwZWcvbXRrX2pwZWdfZW5jX2h3LmMN Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0DQppbmRleCAwMDAwMDAwMDAwMDAuLjFjZjAzN2JmNzJkZA0K LS0tIC9kZXYvbnVsbA0KKysrIGIvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9tdGstanBlZy9tdGtf anBlZ19lbmNfaHcuYw0KQEAgLTAsMCArMSwxNTQgQEANCisvLyBTUERYLUxpY2Vuc2UtSWRlbnRp ZmllcjogR1BMLTIuMC1vbmx5DQorLyoNCisgKiBDb3B5cmlnaHQgKGMpIDIwMTkgTWVkaWFUZWsg SW5jLg0KKyAqIEF1dGhvcjogWGlhIEppYW5nIDx4aWEuamlhbmdAbWVkaWF0ZWsuY29tPg0KKyAq DQorICovDQorDQorI2luY2x1ZGUgPGxpbnV4L2lvLmg+DQorI2luY2x1ZGUgPGxpbnV4L2tlcm5l bC5oPg0KKyNpbmNsdWRlIDxtZWRpYS92aWRlb2J1ZjItY29yZS5oPg0KKyNpbmNsdWRlIDxtZWRp YS92aWRlb2J1ZjItZG1hLWNvbnRpZy5oPg0KKw0KKyNpbmNsdWRlICJtdGtfanBlZ19lbmNfaHcu aCINCisNCitzdGF0aWMgY29uc3Qgc3RydWN0IG10a19qcGVnX2VuY19xbHQgbXRrX2pwZWdfZW5j X3F1YWxpdHlbXSA9IHsNCisJey5xdWFsaXR5X3BhcmFtID0gMzQsIC5oYXJkd2FyZV92YWx1ZSA9 IEpQRUdfRU5DX1FVQUxJVFlfUTM0fSwNCisJey5xdWFsaXR5X3BhcmFtID0gMzksIC5oYXJkd2Fy ZV92YWx1ZSA9IEpQRUdfRU5DX1FVQUxJVFlfUTM5fSwNCisJey5xdWFsaXR5X3BhcmFtID0gNDgs IC5oYXJkd2FyZV92YWx1ZSA9IEpQRUdfRU5DX1FVQUxJVFlfUTQ4fSwNCisJey5xdWFsaXR5X3Bh cmFtID0gNjAsIC5oYXJkd2FyZV92YWx1ZSA9IEpQRUdfRU5DX1FVQUxJVFlfUTYwfSwNCisJey5x dWFsaXR5X3BhcmFtID0gNjQsIC5oYXJkd2FyZV92YWx1ZSA9IEpQRUdfRU5DX1FVQUxJVFlfUTY0 fSwNCisJey5xdWFsaXR5X3BhcmFtID0gNjgsIC5oYXJkd2FyZV92YWx1ZSA9IEpQRUdfRU5DX1FV QUxJVFlfUTY4fSwNCisJey5xdWFsaXR5X3BhcmFtID0gNzQsIC5oYXJkd2FyZV92YWx1ZSA9IEpQ RUdfRU5DX1FVQUxJVFlfUTc0fSwNCisJey5xdWFsaXR5X3BhcmFtID0gODAsIC5oYXJkd2FyZV92 YWx1ZSA9IEpQRUdfRU5DX1FVQUxJVFlfUTgwfSwNCisJey5xdWFsaXR5X3BhcmFtID0gODIsIC5o YXJkd2FyZV92YWx1ZSA9IEpQRUdfRU5DX1FVQUxJVFlfUTgyfSwNCisJey5xdWFsaXR5X3BhcmFt ID0gODQsIC5oYXJkd2FyZV92YWx1ZSA9IEpQRUdfRU5DX1FVQUxJVFlfUTg0fSwNCisJey5xdWFs aXR5X3BhcmFtID0gODcsIC5oYXJkd2FyZV92YWx1ZSA9IEpQRUdfRU5DX1FVQUxJVFlfUTg3fSwN CisJey5xdWFsaXR5X3BhcmFtID0gOTAsIC5oYXJkd2FyZV92YWx1ZSA9IEpQRUdfRU5DX1FVQUxJ VFlfUTkwfSwNCisJey5xdWFsaXR5X3BhcmFtID0gOTIsIC5oYXJkd2FyZV92YWx1ZSA9IEpQRUdf RU5DX1FVQUxJVFlfUTkyfSwNCisJey5xdWFsaXR5X3BhcmFtID0gOTUsIC5oYXJkd2FyZV92YWx1 ZSA9IEpQRUdfRU5DX1FVQUxJVFlfUTk1fSwNCisJey5xdWFsaXR5X3BhcmFtID0gOTcsIC5oYXJk d2FyZV92YWx1ZSA9IEpQRUdfRU5DX1FVQUxJVFlfUTk3fSwNCit9Ow0KKw0KK3ZvaWQgbXRrX2pw ZWdfZW5jX3Jlc2V0KHZvaWQgX19pb21lbSAqYmFzZSkNCit7DQorCXdyaXRlbCgwLCBiYXNlICsg SlBFR19FTkNfUlNUQik7DQorCXdyaXRlbChKUEVHX0VOQ19SRVNFVF9CSVQsIGJhc2UgKyBKUEVH X0VOQ19SU1RCKTsNCisJd3JpdGVsKDAsIGJhc2UgKyBKUEVHX0VOQ19DT0RFQ19TRUwpOw0KK30N CisNCit1MzIgbXRrX2pwZWdfZW5jX2dldF9maWxlX3NpemUodm9pZCBfX2lvbWVtICpiYXNlKQ0K K3sNCisJcmV0dXJuIHJlYWRsKGJhc2UgKyBKUEVHX0VOQ19ETUFfQUREUjApIC0NCisJICAgICAg IHJlYWRsKGJhc2UgKyBKUEVHX0VOQ19EU1RfQUREUjApOw0KK30NCisNCit2b2lkIG10a19qcGVn X2VuY19zdGFydCh2b2lkIF9faW9tZW0gKmJhc2UpDQorew0KKwl1MzIgdmFsdWU7DQorDQorCXZh bHVlID0gcmVhZGwoYmFzZSArIEpQRUdfRU5DX0NUUkwpOw0KKwl2YWx1ZSB8PSBKUEVHX0VOQ19D VFJMX0lOVF9FTl9CSVQgfCBKUEVHX0VOQ19DVFJMX0VOQUJMRV9CSVQ7DQorCXdyaXRlbCh2YWx1 ZSwgYmFzZSArIEpQRUdfRU5DX0NUUkwpOw0KK30NCisNCit2b2lkIG10a19qcGVnX3NldF9lbmNf c3JjKHN0cnVjdCBtdGtfanBlZ19jdHggKmN0eCwgIHZvaWQgX19pb21lbSAqYmFzZSwNCisJCQkg IHN0cnVjdCB2YjJfYnVmZmVyICpzcmNfYnVmKQ0KK3sNCisJaW50IGk7DQorCWRtYV9hZGRyX3Qg ZG1hX2FkZHI7DQorDQorCWZvciAoaSA9IDA7IGkgPCBzcmNfYnVmLT5udW1fcGxhbmVzOyBpKysp IHsNCisJCWRtYV9hZGRyID0gdmIyX2RtYV9jb250aWdfcGxhbmVfZG1hX2FkZHIoc3JjX2J1Ziwg aSkgKw0KKwkJCSAgIHNyY19idWYtPnBsYW5lc1tpXS5kYXRhX29mZnNldDsNCisJCWlmICghaSkN CisJCQl3cml0ZWwoZG1hX2FkZHIsIGJhc2UgKyBKUEVHX0VOQ19TUkNfTFVNQV9BRERSKTsNCisJ CWVsc2UNCisJCQl3cml0ZWwoZG1hX2FkZHIsIGJhc2UgKyBKUEVHX0VOQ19TUkNfQ0hST01BX0FE RFIpOw0KKwl9DQorfQ0KKw0KK3ZvaWQgbXRrX2pwZWdfc2V0X2VuY19kc3Qoc3RydWN0IG10a19q cGVnX2N0eCAqY3R4LCB2b2lkIF9faW9tZW0gKmJhc2UsDQorCQkJICBzdHJ1Y3QgdmIyX2J1ZmZl ciAqZHN0X2J1ZikNCit7DQorCWRtYV9hZGRyX3QgZG1hX2FkZHI7DQorCXNpemVfdCBzaXplOw0K Kwl1MzIgZG1hX2FkZHJfb2Zmc2V0Ow0KKwl1MzIgZG1hX2FkZHJfb2Zmc2V0bWFzazsNCisNCisJ ZG1hX2FkZHIgPSB2YjJfZG1hX2NvbnRpZ19wbGFuZV9kbWFfYWRkcihkc3RfYnVmLCAwKTsNCisJ ZG1hX2FkZHJfb2Zmc2V0ID0gY3R4LT5lbmFibGVfZXhpZiA/IE1US19KUEVHX01BWF9FWElGX1NJ WkUgOiAwOw0KKwlkbWFfYWRkcl9vZmZzZXRtYXNrID0gZG1hX2FkZHIgJiBKUEVHX0VOQ19EU1Rf QUREUl9PRkZTRVRfTUFTSzsNCisJc2l6ZSA9IHZiMl9wbGFuZV9zaXplKGRzdF9idWYsIDApOw0K Kw0KKwl3cml0ZWwoZG1hX2FkZHJfb2Zmc2V0ICYgfjB4ZiwgYmFzZSArIEpQRUdfRU5DX09GRlNF VF9BRERSKTsNCisJd3JpdGVsKGRtYV9hZGRyX29mZnNldG1hc2sgJiAweGYsIGJhc2UgKyBKUEVH X0VOQ19CWVRFX09GRlNFVF9NQVNLKTsNCisJd3JpdGVsKGRtYV9hZGRyICYgfjB4ZiwgYmFzZSAr IEpQRUdfRU5DX0RTVF9BRERSMCk7DQorCXdyaXRlbCgoZG1hX2FkZHIgKyBzaXplKSAmIH4weGYs IGJhc2UgKyBKUEVHX0VOQ19TVEFMTF9BRERSMCk7DQorfQ0KKw0KK3ZvaWQgbXRrX2pwZWdfc2V0 X2VuY19wYXJhbXMoc3RydWN0IG10a19qcGVnX2N0eCAqY3R4LCAgdm9pZCBfX2lvbWVtICpiYXNl KQ0KK3sNCisJdTMyIHZhbHVlOw0KKwl1MzIgd2lkdGggPSBjdHgtPm91dF9xLmVuY19jcm9wX3Jl Y3Qud2lkdGg7DQorCXUzMiBoZWlnaHQgPSBjdHgtPm91dF9xLmVuY19jcm9wX3JlY3QuaGVpZ2h0 Ow0KKwl1MzIgZW5jX2Zvcm1hdCA9IGN0eC0+b3V0X3EuZm10LT5mb3VyY2M7DQorCXUzMiBieXRl c3BlcmxpbmUgPSBjdHgtPm91dF9xLnBpeF9tcC5wbGFuZV9mbXRbMF0uYnl0ZXNwZXJsaW5lOw0K Kwl1MzIgYmxrX251bTsNCisJdTMyIGltZ19zdHJpZGU7DQorCXUzMiBtZW1fc3RyaWRlOw0KKwl1 MzIgaSwgZW5jX3F1YWxpdHk7DQorDQorCXZhbHVlID0gd2lkdGggPDwgMTYgfCBoZWlnaHQ7DQor CXdyaXRlbCh2YWx1ZSwgYmFzZSArIEpQRUdfRU5DX0lNR19TSVpFKTsNCisNCisJaWYgKGVuY19m b3JtYXQgPT0gVjRMMl9QSVhfRk1UX05WMTJNIHx8DQorCSAgICBlbmNfZm9ybWF0ID09IFY0TDJf UElYX0ZNVF9OVjIxTSkNCisJICAgIC8qDQorCSAgICAgKiBUb3RhbCA4IHggOCBibG9jayBudW1i ZXIgb2YgbHVtYSBhbmQgY2hyb21hLg0KKwkgICAgICogVGhlIG51bWJlciBvZiBibG9ja3MgaXMg Y291bnRlZCBmcm9tIDAuDQorCSAgICAgKi8NCisJCWJsa19udW0gPSBESVZfUk9VTkRfVVAod2lk dGgsIDE2KSAqDQorCQkJICBESVZfUk9VTkRfVVAoaGVpZ2h0LCAxNikgKiA2IC0gMTsNCisJZWxz ZQ0KKwkJYmxrX251bSA9IERJVl9ST1VORF9VUCh3aWR0aCwgMTYpICoNCisJCQkgIERJVl9ST1VO RF9VUChoZWlnaHQsIDgpICogNCAtIDE7DQorCXdyaXRlbChibGtfbnVtLCBiYXNlICsgSlBFR19F TkNfQkxLX05VTSk7DQorDQorCWlmIChlbmNfZm9ybWF0ID09IFY0TDJfUElYX0ZNVF9OVjEyTSB8 fA0KKwkgICAgZW5jX2Zvcm1hdCA9PSBWNEwyX1BJWF9GTVRfTlYyMU0pIHsNCisJCS8qIDQ6Mjow ICovDQorCQlpbWdfc3RyaWRlID0gcm91bmRfdXAod2lkdGgsIDE2KTsNCisJCW1lbV9zdHJpZGUg PSBieXRlc3BlcmxpbmU7DQorCX0gZWxzZSB7DQorCQkvKiA0OjI6MiAqLw0KKwkJaW1nX3N0cmlk ZSA9IHJvdW5kX3VwKHdpZHRoICogMiwgMzIpOw0KKwkJbWVtX3N0cmlkZSA9IGltZ19zdHJpZGU7 DQorCX0NCisJd3JpdGVsKGltZ19zdHJpZGUsIGJhc2UgKyBKUEVHX0VOQ19JTUdfU1RSSURFKTsN CisJd3JpdGVsKG1lbV9zdHJpZGUsIGJhc2UgKyBKUEVHX0VOQ19TVFJJREUpOw0KKw0KKwllbmNf cXVhbGl0eSA9IG10a19qcGVnX2VuY19xdWFsaXR5WzBdLmhhcmR3YXJlX3ZhbHVlOw0KKwlmb3Ig KGkgPSAwOyBpIDwgQVJSQVlfU0laRShtdGtfanBlZ19lbmNfcXVhbGl0eSk7IGkrKykgew0KKwkJ aWYgKGN0eC0+ZW5jX3F1YWxpdHkgPD0gbXRrX2pwZWdfZW5jX3F1YWxpdHlbaV0ucXVhbGl0eV9w YXJhbSkgew0KKwkJCWVuY19xdWFsaXR5ID0gbXRrX2pwZWdfZW5jX3F1YWxpdHlbaV0uaGFyZHdh cmVfdmFsdWU7DQorCQkJYnJlYWs7DQorCQl9DQorCX0NCisJd3JpdGVsKGVuY19xdWFsaXR5LCBi YXNlICsgSlBFR19FTkNfUVVBTElUWSk7DQorDQorCXZhbHVlID0gcmVhZGwoYmFzZSArIEpQRUdf RU5DX0NUUkwpOw0KKwl2YWx1ZSAmPSB+SlBFR19FTkNfQ1RSTF9ZVVZfRk9STUFUX01BU0s7DQor CXZhbHVlIHw9IChjdHgtPm91dF9xLmZtdC0+aHdfZm9ybWF0ICYgMykgPDwgMzsNCisJaWYgKGN0 eC0+ZW5hYmxlX2V4aWYpDQorCQl2YWx1ZSB8PSBKUEVHX0VOQ19DVFJMX0ZJTEVfRk9STUFUX0JJ VDsNCisJZWxzZQ0KKwkJdmFsdWUgJj0gfkpQRUdfRU5DX0NUUkxfRklMRV9GT1JNQVRfQklUOw0K KwlpZiAoY3R4LT5yZXN0YXJ0X2ludGVydmFsKQ0KKwkJdmFsdWUgfD0gSlBFR19FTkNfQ1RSTF9S RVNUQVJUX0VOX0JJVDsNCisJZWxzZQ0KKwkJdmFsdWUgJj0gfkpQRUdfRU5DX0NUUkxfUkVTVEFS VF9FTl9CSVQ7DQorCXdyaXRlbCh2YWx1ZSwgYmFzZSArIEpQRUdfRU5DX0NUUkwpOw0KKw0KKwl3 cml0ZWwoY3R4LT5yZXN0YXJ0X2ludGVydmFsLCBiYXNlICsgSlBFR19FTkNfUlNUX01DVV9OVU0p Ow0KK30NCmRpZmYgLS1naXQgYS9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL210ay1qcGVnL210a19q cGVnX2VuY19ody5oIGIvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9tdGstanBlZy9tdGtfanBlZ19l bmNfaHcuaA0KbmV3IGZpbGUgbW9kZSAxMDA2NDQNCmluZGV4IDAwMDAwMDAwMDAwMC4uNjFjNjBl NGU1OGVhDQotLS0gL2Rldi9udWxsDQorKysgYi9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL210ay1q cGVnL210a19qcGVnX2VuY19ody5oDQpAQCAtMCwwICsxLDkxIEBADQorLyogU1BEWC1MaWNlbnNl LUlkZW50aWZpZXI6IEdQTC0yLjAtb25seSAqLw0KKy8qDQorICogQ29weXJpZ2h0IChjKSAyMDE5 IE1lZGlhVGVrIEluYy4NCisgKiBBdXRob3I6IFhpYSBKaWFuZyA8eGlhLmppYW5nQG1lZGlhdGVr LmNvbT4NCisgKg0KKyAqLw0KKw0KKyNpZm5kZWYgX01US19KUEVHX0VOQ19IV19IDQorI2RlZmlu ZSBfTVRLX0pQRUdfRU5DX0hXX0gNCisNCisjaW5jbHVkZSA8bWVkaWEvdmlkZW9idWYyLWNvcmUu aD4NCisNCisjaW5jbHVkZSAibXRrX2pwZWdfY29yZS5oIg0KKw0KKyNkZWZpbmUgSlBFR19FTkNf SU5UX1NUQVRVU19ET05FCUJJVCgwKQ0KKyNkZWZpbmUgSlBFR19FTkNfSU5UX1NUQVRVU19NQVNL X0FMTElSUQkweDEzDQorDQorI2RlZmluZSBKUEVHX0VOQ19EU1RfQUREUl9PRkZTRVRfTUFTSwlH RU5NQVNLKDMsIDApDQorDQorI2RlZmluZSBKUEVHX0VOQ19DVFJMX1lVVl9GT1JNQVRfTUFTSwkw eDE4DQorI2RlZmluZSBKUEVHX0VOQ19DVFJMX1JFU1RBUlRfRU5fQklUCUJJVCgxMCkNCisjZGVm aW5lIEpQRUdfRU5DX0NUUkxfRklMRV9GT1JNQVRfQklUCUJJVCg1KQ0KKyNkZWZpbmUgSlBFR19F TkNfQ1RSTF9JTlRfRU5fQklUCUJJVCgyKQ0KKyNkZWZpbmUgSlBFR19FTkNfQ1RSTF9FTkFCTEVf QklUCUJJVCgwKQ0KKyNkZWZpbmUgSlBFR19FTkNfUkVTRVRfQklUCQlCSVQoMCkNCisNCisjZGVm aW5lIEpQRUdfRU5DX1lVVl9GT1JNQVRfWVVZVgkwDQorI2RlZmluZSBKUEVHX0VOQ19ZVVZfRk9S TUFUX1lWWVUJMQ0KKyNkZWZpbmUgSlBFR19FTkNfWVVWX0ZPUk1BVF9OVjEyCTINCisjZGVmaW5l IEpFUEdfRU5DX1lVVl9GT1JNQVRfTlYyMQkzDQorDQorI2RlZmluZSBKUEVHX0VOQ19RVUFMSVRZ X1E2MAkJMHgwDQorI2RlZmluZSBKUEVHX0VOQ19RVUFMSVRZX1E4MAkJMHgxDQorI2RlZmluZSBK UEVHX0VOQ19RVUFMSVRZX1E5MAkJMHgyDQorI2RlZmluZSBKUEVHX0VOQ19RVUFMSVRZX1E5NQkJ MHgzDQorI2RlZmluZSBKUEVHX0VOQ19RVUFMSVRZX1EzOQkJMHg0DQorI2RlZmluZSBKUEVHX0VO Q19RVUFMSVRZX1E2OAkJMHg1DQorI2RlZmluZSBKUEVHX0VOQ19RVUFMSVRZX1E4NAkJMHg2DQor I2RlZmluZSBKUEVHX0VOQ19RVUFMSVRZX1E5MgkJMHg3DQorI2RlZmluZSBKUEVHX0VOQ19RVUFM SVRZX1E0OAkJMHg4DQorI2RlZmluZSBKUEVHX0VOQ19RVUFMSVRZX1E3NAkJMHhhDQorI2RlZmlu ZSBKUEVHX0VOQ19RVUFMSVRZX1E4NwkJMHhiDQorI2RlZmluZSBKUEVHX0VOQ19RVUFMSVRZX1Ez NAkJMHhjDQorI2RlZmluZSBKUEVHX0VOQ19RVUFMSVRZX1E2NAkJMHhlDQorI2RlZmluZSBKUEVH X0VOQ19RVUFMSVRZX1E4MgkJMHhmDQorI2RlZmluZSBKUEVHX0VOQ19RVUFMSVRZX1E5NwkJMHgx MA0KKw0KKyNkZWZpbmUgSlBFR19FTkNfUlNUQgkJCTB4MTAwDQorI2RlZmluZSBKUEVHX0VOQ19D VFJMCQkJMHgxMDQNCisjZGVmaW5lIEpQRUdfRU5DX1FVQUxJVFkJCTB4MTA4DQorI2RlZmluZSBK UEVHX0VOQ19CTEtfTlVNCQkweDEwQw0KKyNkZWZpbmUgSlBFR19FTkNfQkxLX0NOVAkJMHgxMTAN CisjZGVmaW5lIEpQRUdfRU5DX0lOVF9TVFMJCTB4MTFjDQorI2RlZmluZSBKUEVHX0VOQ19EU1Rf QUREUjAJCTB4MTIwDQorI2RlZmluZSBKUEVHX0VOQ19ETUFfQUREUjAJCTB4MTI0DQorI2RlZmlu ZSBKUEVHX0VOQ19TVEFMTF9BRERSMAkJMHgxMjgNCisjZGVmaW5lIEpQRUdfRU5DX09GRlNFVF9B RERSCQkweDEzOA0KKyNkZWZpbmUgSlBFR19FTkNfUlNUX01DVV9OVU0JCTB4MTUwDQorI2RlZmlu ZSBKUEVHX0VOQ19JTUdfU0laRQkJMHgxNTQNCisjZGVmaW5lIEpQRUdfRU5DX0RFQlVHX0lORk8w CQkweDE2MA0KKyNkZWZpbmUgSlBFR19FTkNfREVCVUdfSU5GTzEJCTB4MTY0DQorI2RlZmluZSBK UEVHX0VOQ19UT1RBTF9DWUNMRQkJMHgxNjgNCisjZGVmaW5lIEpQRUdfRU5DX0JZVEVfT0ZGU0VU X01BU0sJMHgxNmMNCisjZGVmaW5lIEpQRUdfRU5DX1NSQ19MVU1BX0FERFIJCTB4MTcwDQorI2Rl ZmluZSBKUEVHX0VOQ19TUkNfQ0hST01BX0FERFIJMHgxNzQNCisjZGVmaW5lIEpQRUdfRU5DX1NU UklERQkJCTB4MTc4DQorI2RlZmluZSBKUEVHX0VOQ19JTUdfU1RSSURFCQkweDE3Yw0KKyNkZWZp bmUgSlBFR19FTkNfRENNX0NUUkwJCTB4MzAwDQorI2RlZmluZSBKUEVHX0VOQ19DT0RFQ19TRUwJ CTB4MzE0DQorI2RlZmluZSBKUEVHX0VOQ19VTFRSQV9USFJFUwkJMHgzMTgNCisNCisvKioNCisg KiBzdHJ1Y3QgbXRrX2pwZWdfZW5jX3FsdCAtIEpQRUcgZW5jb2RlciBxdWFsaXR5IGRhdGENCisg KiBAcXVhbGl0eV9wYXJhbToJcXVhbGl0eSB2YWx1ZQ0KKyAqIEBoYXJkd2FyZV92YWx1ZToJaGFy ZHdhcmUgdmFsdWUgb2YgcXVhbGl0eQ0KKyAqLw0KK3N0cnVjdCBtdGtfanBlZ19lbmNfcWx0IHsN CisJdTgJcXVhbGl0eV9wYXJhbTsNCisJdTgJaGFyZHdhcmVfdmFsdWU7DQorfTsNCisNCit2b2lk IG10a19qcGVnX2VuY19yZXNldCh2b2lkIF9faW9tZW0gKmJhc2UpOw0KK3UzMiBtdGtfanBlZ19l bmNfZ2V0X2ZpbGVfc2l6ZSh2b2lkIF9faW9tZW0gKmJhc2UpOw0KK3ZvaWQgbXRrX2pwZWdfZW5j X3N0YXJ0KHZvaWQgX19pb21lbSAqZW5jX3JlZ19iYXNlKTsNCit2b2lkIG10a19qcGVnX3NldF9l bmNfc3JjKHN0cnVjdCBtdGtfanBlZ19jdHggKmN0eCwgIHZvaWQgX19pb21lbSAqYmFzZSwNCisJ CQkgIHN0cnVjdCB2YjJfYnVmZmVyICpzcmNfYnVmKTsNCit2b2lkIG10a19qcGVnX3NldF9lbmNf ZHN0KHN0cnVjdCBtdGtfanBlZ19jdHggKmN0eCwgdm9pZCBfX2lvbWVtICpiYXNlLA0KKwkJCSAg c3RydWN0IHZiMl9idWZmZXIgKmRzdF9idWYpOw0KK3ZvaWQgbXRrX2pwZWdfc2V0X2VuY19wYXJh bXMoc3RydWN0IG10a19qcGVnX2N0eCAqY3R4LCAgdm9pZCBfX2lvbWVtICpiYXNlKTsNCisNCisj ZW5kaWYgLyogX01US19KUEVHX0VOQ19IV19IICovDQotLSANCjIuMTguMA0K