From patchwork Wed Apr 10 12:42:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: ayaka X-Patchwork-Id: 10893843 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 32BB31515 for ; Wed, 10 Apr 2019 12:43:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DB7C726B39 for ; Wed, 10 Apr 2019 12:43:33 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CD59A28908; Wed, 10 Apr 2019 12:43:33 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 1FCB3289B6 for ; Wed, 10 Apr 2019 12:43:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.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=Ugt30dav7pdbztLXYzKOLELxaEDlu/K8x667pCUMMlw=; b=M+O5HaSeGQ2W4+ CV6iARyrhwizpejqWbkiCdrauDS4EE2VTiqfM+/mFr8YfHeo/cA3tt4mRX9BsNUpIGnMsqhHFCmhl NzZOugbgNo11/XoRKxeCzav2WJofiObSKkZypHW8lOFZ4rsO8Trz+pS0Xqm1HoKHEv8QnAhUpjN0h JZ+w1R/CjC4sPzOAE0QphkMoYyv7ubhQSJc1rgaFbmmp1iYJ+BPjsOyv5WZ9Np92xz3ZI0IsyoaXD uV+r1JTyYbM+veVDnyTTEJiMN7uh45I4nBzohd2GOjd+cqnh7jz+0FpxXM5iTQxNeLts//qq4XgfD LavEZpL6t3XS0DEQqyWA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hECZO-0002vF-33; Wed, 10 Apr 2019 12:43:14 +0000 Received: from kozue.soulik.info ([2001:19f0:7000:8404:5054:ff:fe75:428f]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hECYy-0002cw-Ic for linux-rockchip@lists.infradead.org; Wed, 10 Apr 2019 12:43:12 +0000 Received: from misaki.sumomo.pri (unknown [IPv6:2001:470:b30d:2:c604:15ff:0:401]) by kozue.soulik.info (Postfix) with ESMTPA id 5C7711014E9; Wed, 10 Apr 2019 21:43:32 +0900 (JST) From: ayaka To: linux-media@vger.kernel.org Subject: [PATCH v3 1/9] staging: video: rockchip: add v4l2 decoder Date: Wed, 10 Apr 2019 20:42:18 +0800 Message-Id: <20190410124226.8612-2-ayaka@soulik.info> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190410124226.8612-1-ayaka@soulik.info> References: <20190410124226.8612-1-ayaka@soulik.info> MIME-Version: 1.0 X-BeenThere: linux-rockchip@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Upstream kernel work for Rockchip platforms List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: paul.kocialkowski@bootlin.com, maxime.ripard@bootlin.com, joro@8bytes.org, Randy Li , randy.li@rock-chips.com, jernej.skrabec@gmail.com, nicolas@ndufresne.ca, hverkuil@xs4all.nl, linux-rockchip@lists.infradead.org, thomas.petazzoni@bootlin.com, groeck@chromium.org, mchehab@kernel.org, ezequiel@collabora.com, posciak@chromium.org Sender: "Linux-rockchip" Errors-To: linux-rockchip-bounces+patchwork-linux-rockchip=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Randy Li TODO: task finish finish a task before it would be dequeued iommu attach won't reload buffers Signed-off-by: Randy Li Signed-off-by: Randy Li --- drivers/staging/Kconfig | 2 + drivers/staging/Makefile | 1 + drivers/staging/rockchip-mpp/Kconfig | 33 + drivers/staging/rockchip-mpp/Makefile | 10 + drivers/staging/rockchip-mpp/mpp_debug.h | 87 + drivers/staging/rockchip-mpp/mpp_dev_common.c | 1391 +++++++ drivers/staging/rockchip-mpp/mpp_dev_common.h | 212 + drivers/staging/rockchip-mpp/mpp_dev_rkvdec.c | 919 +++++ drivers/staging/rockchip-mpp/mpp_dev_vdpu2.c | 601 +++ drivers/staging/rockchip-mpp/mpp_service.c | 197 + drivers/staging/rockchip-mpp/mpp_service.h | 38 + drivers/staging/rockchip-mpp/rkvdec/avc.c | 202 + drivers/staging/rockchip-mpp/rkvdec/cabac.h | 3614 +++++++++++++++++ drivers/staging/rockchip-mpp/rkvdec/hal.h | 70 + drivers/staging/rockchip-mpp/rkvdec/hevc.c | 167 + drivers/staging/rockchip-mpp/rkvdec/regs.h | 377 ++ drivers/staging/rockchip-mpp/vdpu2/hal.h | 52 + drivers/staging/rockchip-mpp/vdpu2/mpeg2.c | 270 ++ drivers/staging/rockchip-mpp/vdpu2/regs.h | 670 +++ include/uapi/video/rk_vpu_service.h | 101 + 20 files changed, 9014 insertions(+) create mode 100644 drivers/staging/rockchip-mpp/Kconfig create mode 100644 drivers/staging/rockchip-mpp/Makefile create mode 100644 drivers/staging/rockchip-mpp/mpp_debug.h create mode 100644 drivers/staging/rockchip-mpp/mpp_dev_common.c create mode 100644 drivers/staging/rockchip-mpp/mpp_dev_common.h create mode 100644 drivers/staging/rockchip-mpp/mpp_dev_rkvdec.c create mode 100644 drivers/staging/rockchip-mpp/mpp_dev_vdpu2.c create mode 100644 drivers/staging/rockchip-mpp/mpp_service.c create mode 100644 drivers/staging/rockchip-mpp/mpp_service.h create mode 100644 drivers/staging/rockchip-mpp/rkvdec/avc.c create mode 100644 drivers/staging/rockchip-mpp/rkvdec/cabac.h create mode 100644 drivers/staging/rockchip-mpp/rkvdec/hal.h create mode 100644 drivers/staging/rockchip-mpp/rkvdec/hevc.c create mode 100644 drivers/staging/rockchip-mpp/rkvdec/regs.h create mode 100644 drivers/staging/rockchip-mpp/vdpu2/hal.h create mode 100644 drivers/staging/rockchip-mpp/vdpu2/mpeg2.c create mode 100644 drivers/staging/rockchip-mpp/vdpu2/regs.h create mode 100644 include/uapi/video/rk_vpu_service.h diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index c0901b96cfe4..5f84035e2a89 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -124,4 +124,6 @@ source "drivers/staging/axis-fifo/Kconfig" source "drivers/staging/erofs/Kconfig" +source "drivers/staging/rockchip-mpp/Kconfig" + endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 57c6bce13ff4..fc3ed97a0eab 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -52,3 +52,4 @@ obj-$(CONFIG_SOC_MT7621) += mt7621-dts/ obj-$(CONFIG_STAGING_GASKET_FRAMEWORK) += gasket/ obj-$(CONFIG_XIL_AXIS_FIFO) += axis-fifo/ obj-$(CONFIG_EROFS_FS) += erofs/ +obj-$(CONFIG_ROCKCHIP_MPP_SERVICE) += rockchip-mpp/ diff --git a/drivers/staging/rockchip-mpp/Kconfig b/drivers/staging/rockchip-mpp/Kconfig new file mode 100644 index 000000000000..17e079a77203 --- /dev/null +++ b/drivers/staging/rockchip-mpp/Kconfig @@ -0,0 +1,33 @@ +# SPDX-License-Identifier: GPL-2.0 +menu "ROCKCHIP_MPP" + depends on ARCH_ROCKCHIP + +config ROCKCHIP_MPP_SERVICE + tristate "mpp service scheduler" + default n + help + rockchip mpp service. + +config ROCKCHIP_MPP_DEVICE + tristate "mpp device framework" + depends on ROCKCHIP_MPP_SERVICE + select V4L2_MEM2MEM_DEV + select VIDEOBUF2_DMA_CONTIG + default n + help + rockchip mpp device framework. + +config ROCKCHIP_MPP_VDEC_DEVICE + tristate "video decoder device driver" + depends on ROCKCHIP_MPP_DEVICE + default n + help + rockchip mpp video decoder and hevc decoder. + +config ROCKCHIP_MPP_VDPU2_DEVICE + tristate "VPU decoder v2 device driver" + depends on ROCKCHIP_MPP_DEVICE + default n + help + rockchip mpp vpu decoder v2. +endmenu diff --git a/drivers/staging/rockchip-mpp/Makefile b/drivers/staging/rockchip-mpp/Makefile new file mode 100644 index 000000000000..9722b0059563 --- /dev/null +++ b/drivers/staging/rockchip-mpp/Makefile @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0 +rk-mpp-service-objs := mpp_service.o +rk-mpp-device-objs := mpp_dev_common.o +rk-mpp-vdec-objs := mpp_dev_rkvdec.o rkvdec/hevc.o rkvdec/avc.o +rk-mpp-vdpu2-objs := mpp_dev_vdpu2.o vdpu2/mpeg2.o + +obj-$(CONFIG_ROCKCHIP_MPP_SERVICE) += rk-mpp-service.o +obj-$(CONFIG_ROCKCHIP_MPP_DEVICE) += rk-mpp-device.o +obj-$(CONFIG_ROCKCHIP_MPP_VDEC_DEVICE) += rk-mpp-vdec.o +obj-$(CONFIG_ROCKCHIP_MPP_VDPU2_DEVICE) += rk-mpp-vdpu2.o diff --git a/drivers/staging/rockchip-mpp/mpp_debug.h b/drivers/staging/rockchip-mpp/mpp_debug.h new file mode 100644 index 000000000000..bd6c0e594da3 --- /dev/null +++ b/drivers/staging/rockchip-mpp/mpp_debug.h @@ -0,0 +1,87 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2016 - 2017 Fuzhou Rockchip Electronics Co., Ltd + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _ROCKCHIP_MPP_DEBUG_H_ +#define _ROCKCHIP_MPP_DEBUG_H_ + +#include + +/* + * debug flag usage: + * +------+-------------------+ + * | 8bit | 24bit | + * +------+-------------------+ + * 0~23 bit is for different information type + * 24~31 bit is for information print format + */ + +#define DEBUG_POWER 0x00000001 +#define DEBUG_CLOCK 0x00000002 +#define DEBUG_IRQ_STATUS 0x00000004 +#define DEBUG_IOMMU 0x00000008 +#define DEBUG_IOCTL 0x00000010 +#define DEBUG_FUNCTION 0x00000020 +#define DEBUG_REGISTER 0x00000040 +#define DEBUG_EXTRA_INFO 0x00000080 +#define DEBUG_TIMING 0x00000100 +#define DEBUG_TASK_INFO 0x00000200 +#define DEBUG_DUMP_ERR_REG 0x00000400 +#define DEBUG_LINK_TABLE 0x00000800 + +#define DEBUG_SET_REG 0x00001000 +#define DEBUG_GET_REG 0x00002000 +#define DEBUG_PPS_FILL 0x00004000 +#define DEBUG_IRQ_CHECK 0x00008000 +#define DEBUG_CACHE_32B 0x00010000 + +#define DEBUG_RESET 0x00020000 + +#define PRINT_FUNCTION 0x80000000 +#define PRINT_LINE 0x40000000 + +#define mpp_debug_func(type, fmt, args...) \ + do { \ + if (unlikely(debug & type)) { \ + pr_info("%s:%d: " fmt, \ + __func__, __LINE__, ##args); \ + } \ + } while (0) +#define mpp_debug(type, fmt, args...) \ + do { \ + if (unlikely(debug & type)) { \ + pr_info(fmt, ##args); \ + } \ + } while (0) + +#define mpp_debug_enter() \ + do { \ + if (unlikely(debug & DEBUG_FUNCTION)) { \ + pr_info("%s:%d: enter\n", \ + __func__, __LINE__); \ + } \ + } while (0) + +#define mpp_debug_leave() \ + do { \ + if (unlikely(debug & DEBUG_FUNCTION)) { \ + pr_info("%s:%d: leave\n", \ + __func__, __LINE__); \ + } \ + } while (0) + +#define mpp_err(fmt, args...) \ + pr_err("%s:%d: " fmt, __func__, __LINE__, ##args) + +#endif diff --git a/drivers/staging/rockchip-mpp/mpp_dev_common.c b/drivers/staging/rockchip-mpp/mpp_dev_common.c new file mode 100644 index 000000000000..21816ad8a43b --- /dev/null +++ b/drivers/staging/rockchip-mpp/mpp_dev_common.c @@ -0,0 +1,1391 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2016 - 2017 Fuzhou Rockchip Electronics Co., Ltd + * Randy Li, + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "mpp_debug.h" +#include "mpp_dev_common.h" +#include "mpp_service.h" + +#define MPP_TIMEOUT_DELAY (2000) +#include "mpp_dev_common.h" + +#define MPP_SESSION_MAX_DONE_TASK (20) + +static int debug; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "bit switch for mpp device debug information"); + +static struct class *mpp_device_class; +static const struct v4l2_file_operations mpp_v4l2_default_fops; + +static int rockchip_mpp_result(struct rockchip_mpp_dev *mpp_dev, + struct mpp_task *task); + +static const struct media_device_ops mpp_m2m_media_ops = { + .req_validate = vb2_request_validate, + .req_queue = v4l2_m2m_request_queue, +}; + +static void mpp_session_push_pending(struct mpp_session *session, + struct mpp_task *task) +{ + mutex_lock(&session->lock); + list_add_tail(&task->session_link, &session->pending); + mutex_unlock(&session->lock); +} + +static void mpp_session_push_done(struct mpp_task *task) +{ + struct mpp_session *session = NULL; + + session = task->session; + + mutex_lock(&session->lock); + list_del_init(&task->session_link); + mutex_unlock(&session->lock); + + //kfifo_in(&session->done_fifo, &task, 1); + rockchip_mpp_result(session->mpp_dev, task); +} + +static struct mpp_task *mpp_session_pull_done(struct mpp_session *session) +{ + struct mpp_task *task = NULL; + + if (kfifo_out(&session->done_fifo, &task, 1)) + return task; + return NULL; +} + +static void mpp_dev_sched_irq(struct work_struct *work) +{ + struct mpp_task *task = container_of(work, struct mpp_task, work); + struct rockchip_mpp_dev *mpp_dev = NULL; + + mpp_dev = task->session->mpp_dev; + + mpp_debug_time_diff(task); + + if (mpp_dev->ops->finish) + mpp_dev->ops->finish(mpp_dev, task); + + atomic_dec(&task->session->task_running); + pm_runtime_mark_last_busy(mpp_dev->dev); + pm_runtime_put_autosuspend(mpp_dev->dev); + /* + * TODO: unlock the reader locker of the device resource locker + * here + */ + mpp_srv_done(mpp_dev->srv, task); + /* Wake up the GET thread */ + mpp_session_push_done(task); +} + +static void *mpp_dev_alloc_task(struct rockchip_mpp_dev *mpp_dev, + struct mpp_session *session, void __user *src, + u32 size) +{ + if (mpp_dev->ops->alloc_task) + return mpp_dev->ops->alloc_task(session, src, size); + return NULL; +} + +static int mpp_dev_free_task(struct mpp_session *session, struct mpp_task *task) +{ + struct rockchip_mpp_dev *mpp_dev = session->mpp_dev; + + if (mpp_dev->ops->free_task) + mpp_dev->ops->free_task(session, task); + return 0; +} + +int mpp_dev_task_init(struct mpp_session *session, struct mpp_task *task) +{ + INIT_LIST_HEAD(&task->session_link); + INIT_LIST_HEAD(&task->service_link); + INIT_WORK(&task->work, mpp_dev_sched_irq); + + task->session = session; + + return 0; +} +EXPORT_SYMBOL(mpp_dev_task_init); + +void mpp_dev_task_finish(struct mpp_session *session, struct mpp_task *task) +{ + struct rockchip_mpp_dev *mpp_dev = NULL; + + mpp_dev = session->mpp_dev; + queue_work(mpp_dev->irq_workq, &task->work); +} +EXPORT_SYMBOL(mpp_dev_task_finish); + +void mpp_dev_task_finalize(struct mpp_session *session, struct mpp_task *task) +{ +#if 0 + struct vb2_v4l2_buffer *src, *dst; + + src = v4l2_m2m_src_buf_remove(session->fh.m2m_ctx); + dst = v4l2_m2m_dst_buf_remove(session->fh.m2m_ctx); + if (WARN_ON(!src)) + return -EINVAL; + + if (WARN_ON(!dst)) + return -EINVAL; + + src->sequence = session->sequence_out++; + dst->sequence = session->sequence_cap++; + + v4l2_m2m_buf_copy_data(src, dst, true); + + v4l2_m2m_buf_done(src, result); + v4l2_m2m_buf_done(dst, result); +#endif +} +EXPORT_SYMBOL(mpp_dev_task_finalize); + +static void mpp_dev_session_clear(struct rockchip_mpp_dev *mpp, + struct mpp_session *session) +{ + struct mpp_task *task, *n; + + list_for_each_entry_safe(task, n, &session->pending, session_link) { + list_del(&task->session_link); + mpp_dev_free_task(session, task); + } + while (kfifo_out(&session->done_fifo, &task, 1)) + mpp_dev_free_task(session, task); +} + +#if 0 +void *mpp_dev_alloc_session(struct rockchip_mpp_dev *mpp_dev) +{ + struct mpp_session *session = NULL; + int error = 0; + + session = kzalloc(sizeof(*session), GFP_KERNEL); + if (!session) + return ERR_PTR(-ENOMEM); + + session->pid = current->pid; + session->mpp_dev = mpp_dev; + mutex_init(&session->lock); + INIT_LIST_HEAD(&session->pending); + init_waitqueue_head(&session->wait); + error = kfifo_alloc(&session->done_fifo, MPP_SESSION_MAX_DONE_TASK, + GFP_KERNEL); + if (error < 0) { + kfree(session); + return ERR_PTR(error); + } + + atomic_set(&session->task_running, 0); + INIT_LIST_HEAD(&session->list_session); + + return session; +} +EXPORT_SYMBOL(mpp_dev_alloc_session); + +#endif + +static void mpp_dev_reset(struct rockchip_mpp_dev *mpp_dev) +{ + mpp_debug_enter(); + + /* FIXME lock resource lock of the other devices in combo */ + write_lock(&mpp_dev->resource_rwlock); + atomic_set(&mpp_dev->reset_request, 0); + + iommu_detach_device(mpp_dev->domain, mpp_dev->dev); + mpp_dev->ops->reset(mpp_dev); + iommu_attach_device(mpp_dev->domain, mpp_dev->dev); + + write_unlock(&mpp_dev->resource_rwlock); + mpp_debug_leave(); +} + +static void mpp_dev_abort(struct rockchip_mpp_dev *mpp_dev) +{ + int ret = 0; + + mpp_debug_enter(); + + /* destroy the current task after hardware reset */ + ret = mpp_srv_is_running(mpp_dev->srv); + + mpp_dev_reset(mpp_dev); + + if (ret) { + struct mpp_task *task = NULL; + + task = mpp_srv_get_cur_task(mpp_dev->srv); + cancel_work_sync(&task->work); + list_del(&task->session_link); + mpp_srv_abort(mpp_dev->srv, task); + mpp_dev_free_task(task->session, task); + atomic_dec(&task->session->task_running); + } else { + mpp_srv_abort(mpp_dev->srv, NULL); + } + + mpp_debug_leave(); +} + +void mpp_dev_power_on(struct rockchip_mpp_dev *mpp_dev) +{ + pm_runtime_get_sync(mpp_dev->dev); + pm_stay_awake(mpp_dev->dev); +} + +void mpp_dev_power_off(struct rockchip_mpp_dev *mpp_dev) +{ + pm_runtime_put_sync(mpp_dev->dev); + pm_relax(mpp_dev->dev); +} + +static void rockchip_mpp_run(struct rockchip_mpp_dev *mpp_dev, + struct mpp_task *task) +{ + mpp_debug_enter(); + /* + * As I got the global lock from the mpp service here, + * I am the very task to be run, the device is ready + * for me. Wait a gap in the other is operating with the IOMMU. + */ + if (atomic_read(&mpp_dev->reset_request)) + mpp_dev_reset(mpp_dev); + + mpp_debug_time_record(task); + + mpp_debug(DEBUG_TASK_INFO, "pid %d, start hw %s\n", + task->session->pid, dev_name(mpp_dev->dev)); + + if (unlikely(debug & DEBUG_REGISTER)) + mpp_debug_dump_reg(mpp_dev->reg_base, + mpp_dev->variant->reg_len); + + /* + * TODO: Lock the reader locker of the device resource lock here, + * release at the finish operation + */ + if (mpp_dev->ops->run) + mpp_dev->ops->run(mpp_dev, task); + + mpp_debug_leave(); +} + +static void rockchip_mpp_try_run(struct rockchip_mpp_dev *mpp_dev) +{ + int ret = 0; + struct mpp_task *task; + + mpp_debug_enter(); + + task = mpp_srv_get_pending_task(mpp_dev->srv); + + if (mpp_dev->ops->prepare) + ret = mpp_dev->ops->prepare(mpp_dev, task); + + mpp_srv_wait_to_run(mpp_dev->srv, task); + /* + * FIXME if the hardware supports task query, but we still need to lock + * the running list and lock the mpp service in the current state. + */ + /* Push a pending task to running queue */ + rockchip_mpp_run(mpp_dev, task); + + mpp_debug_leave(); +} + +static int rockchip_mpp_result(struct rockchip_mpp_dev *mpp_dev, + struct mpp_task *task) +{ + struct mpp_session *session = NULL; + struct vb2_v4l2_buffer *src, *dst; + enum vb2_buffer_state result = VB2_BUF_STATE_DONE; + + mpp_debug_enter(); + + if (!mpp_dev || !task) + return -EINVAL; + + session = task->session; + + if (mpp_dev->ops->result) + result = mpp_dev->ops->result(mpp_dev, task, NULL, 0); + + mpp_dev_free_task(session, task); + + src = v4l2_m2m_src_buf_remove(session->fh.m2m_ctx); + dst = v4l2_m2m_dst_buf_remove(session->fh.m2m_ctx); + if (WARN_ON(!src)) + return -EINVAL; + + if (WARN_ON(!dst)) + return -EINVAL; + + src->sequence = session->sequence_out++; + dst->sequence = session->sequence_cap++; + + v4l2_m2m_buf_copy_metadata(src, dst, true); + + v4l2_m2m_buf_done(src, result); + v4l2_m2m_buf_done(dst, result); + + v4l2_m2m_job_finish(mpp_dev->m2m_dev, session->fh.m2m_ctx); + + mpp_debug_leave(); + return 0; +} + +#if 0 +static int rockchip_mpp_wait_result(struct mpp_session *session, + struct rockchip_mpp_dev *mpp, + struct vpu_request req) +{ + struct mpp_task *task; + int ret; + + ret = wait_event_timeout(session->wait, + !kfifo_is_empty(&session->done_fifo), + msecs_to_jiffies(MPP_TIMEOUT_DELAY)); + if (ret == 0) { + mpp_err("error: pid %d wait %d task done timeout\n", + session->pid, atomic_read(&session->task_running)); + ret = -ETIMEDOUT; + + if (unlikely(debug & DEBUG_REGISTER)) + mpp_debug_dump_reg(mpp->reg_base, + mpp->variant->reg_len); + mpp_dev_abort(mpp); + + return ret; + } + + task = mpp_session_pull_done(session); + rockchip_mpp_result(mpp, task, req.req, req.size); + + return 0; +} + +long mpp_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + struct mpp_session *session = (struct mpp_session *)filp->private_data; + struct rockchip_mpp_dev *mpp = NULL; + + mpp_debug_enter(); + if (!session) + return -EINVAL; + + mpp = session->mpp_dev; + + switch (cmd) { + case VPU_IOC_SET_CLIENT_TYPE: + break; + case VPU_IOC_SET_REG: { + struct vpu_request req; + struct mpp_task *task; + + mpp_debug(DEBUG_IOCTL, "pid %d set reg\n", + session->pid); + if (copy_from_user(&req, (void __user *)arg, + sizeof(struct vpu_request))) { + mpp_err("error: set reg copy_from_user failed\n"); + return -EFAULT; + } + + task = mpp_dev_alloc_task(mpp, session, (void __user *)req.req, + req.size); + if (IS_ERR_OR_NULL(task)) + return -EFAULT; + mpp_srv_push_pending(mpp->srv, task); + mpp_session_push_pending(session, task); + atomic_inc(&session->task_running); + + /* TODO: processing the current task */ + rockchip_mpp_try_run(mpp); + } break; + case VPU_IOC_GET_REG: { + struct vpu_request req; + + mpp_debug(DEBUG_IOCTL, "pid %d get reg\n", + session->pid); + if (copy_from_user(&req, (void __user *)arg, + sizeof(struct vpu_request))) { + mpp_err("error: get reg copy_from_user failed\n"); + return -EFAULT; + } + + return rockchip_mpp_wait_result(session, mpp, req); + } break; + case VPU_IOC_PROBE_IOMMU_STATUS: { + int iommu_enable = 1; + + mpp_debug(DEBUG_IOCTL, "VPU_IOC_PROBE_IOMMU_STATUS\n"); + + if (put_user(iommu_enable, ((u32 __user *)arg))) { + mpp_err("error: iommu status copy_to_user failed\n"); + return -EFAULT; + } + break; + } + default: { + dev_err(mpp->dev, "unknown mpp ioctl cmd %x\n", cmd); + return -ENOIOCTLCMD; + } break; + } + + mpp_debug_leave(); + return 0; +} +EXPORT_SYMBOL(mpp_dev_ioctl); + +static unsigned int mpp_dev_poll(struct file *filp, poll_table *wait) +{ + struct mpp_session *session = (struct mpp_session *)filp->private_data; + unsigned int mask = 0; + + poll_wait(filp, &session->wait, wait); + if (kfifo_len(&session->done_fifo)) + mask |= POLLIN | POLLRDNORM; + + return mask; +} + +static int mpp_dev_open(struct file *filp) +{ + struct rockchip_mpp_dev *mpp_dev = video_drvdata(flip); + struct video_device *vdev = video_devdata(filp); + struct mpp_session *session = NULL; + int error = 0; + + mpp_debug_enter(); + + session = kzalloc(sizeof(*session), GFP_KERNEL); + if (!session) + return -ENOMEM; + + session->pid = current->pid; + session->mpp_dev = mpp_dev; + mutex_init(&session->lock); + INIT_LIST_HEAD(&session->pending); + init_waitqueue_head(&session->wait); + error = kfifo_alloc(&session->done_fifo, MPP_SESSION_MAX_DONE_TASK, + GFP_KERNEL); + if (error < 0) + goto fail; + + atomic_set(&session->task_running, 0); + INIT_LIST_HEAD(&session->list_session); +#if 0 + session->fh.m2m_ctx = v4l2_m2m_ctx_init(mpp_dev->m2m_dev, session, + default_queue_init); + if (IS_ERR(session->fh.m2m_ctx)) { + error = PTR_ERR(session->fb.m2m_ctx); + goto fail; + } + v4l2_fh_init(&session->fh, vdev); + filp->private_data = &session->fh; + v4l2_fh_add(&session->fh); + + /* TODO: setup default formats */ + + /* TODO: install v4l2 ctrl */ + if (error) { + dev_err(mpp_dev->dev, "Failed to set up controls\n"); + goto err_fh; + } + + session->fb.ctrl_handler = mpp_dev->ctrl_handler; +#endif + + mpp_dev_power_on(mpp); + mpp_debug_leave(); + + return 0; + +err_fh: + v4l2_fh_del(&session->fh); + v4l2_fh_exit(&session->fh); +fail: + kfree(session); + return error; +} + +static int mpp_dev_release(struct file *filp) +{ + struct mpp_session *session = container_of(filp->private_data, + struct mpp_session, fh); + struct rockchip_mpp_dev *mpp_dev = video_drvdata(flip); + int task_running; + + mpp_debug_enter(); + if (!session) + return -EINVAL; + + /* TODO: is it necessary for v4l2? */ + task_running = atomic_read(&session->task_running); + if (task_running) { + pr_err("session %d still has %d task running when closing\n", + session->pid, task_running); + msleep(50); + } + wake_up(&session->wait); + +#if 0 + v4l2_m2m_ctx_release(session->fh.m2m_ctx); + v4l2_fh_del(&seesion->>fh); + v4l2_fh_exit(&session->fh); + v4l2_ctrl_handler_free(&session->ctrl_handler); +#endif + mpp_dev_session_clear(mpp, session); + +#if 0 + read_lock(&mpp->resource_rwlock); + read_unlock(&mpp->resource_rwlock); +#endif + kfifo_free(&session->done_fifo); + filp->private_data = NULL; + + mpp_dev_power_off(mpp); + kfree(session); + + dev_dbg(mpp->dev, "closed\n"); + mpp_debug_leave(); + return 0; +} + +static const struct v4l2_file_operations mpp_v4l2_default_fops = { + .owner = THIS_MODULE, + .open = mpp_dev_open, + .release = mpp_dev_release, + .poll = v4l2_m2m_fop_poll, + .unlocked_ioctl = video_ioctl2, + .mmap = v4l2_m2m_fop_mmap, +}; +#endif + +static int rockchip_mpp_dev_open(struct file *filp) +{ + struct rockchip_mpp_dev *mpp_dev = video_drvdata(filp); + struct video_device *vdev = video_devdata(filp); + struct mpp_session *session = NULL; + + mpp_debug_enter(); + + session = rockchip_mpp_alloc_session(mpp_dev, vdev); + if (IS_ERR_OR_NULL(session)) + return PTR_ERR(session); + + filp->private_data = &session->fh; + pm_runtime_get_sync(mpp_dev->dev); + + mpp_debug_leave(); + return 0; +} + +static struct mpp_service_node *mpp_dev_load_srv(struct platform_device *p) +{ + struct mpp_service *srv = NULL; + struct device_node *np = NULL; + struct platform_device *pdev = NULL; + struct mpp_service_node *client = NULL; + + np = of_parse_phandle(p->dev.of_node, "rockchip,srv", 0); + if (!np || !of_device_is_available(np)) { + dev_err(&p->dev, + "failed to get the mpp service node\n"); + return NULL; + } + + pdev = of_find_device_by_node(np); + if (!pdev) { + of_node_put(np); + dev_err(&p->dev, + "failed to get mpp service from node\n"); + return ERR_PTR(-ENODEV); + } + + device_lock(&pdev->dev); + + srv = platform_get_drvdata(pdev); + if (srv) { + client = mpp_srv_attach(srv, NULL); + } else { + dev_info(&pdev->dev, "defer probe\n"); + client = ERR_PTR(-EPROBE_DEFER); + } + device_unlock(&pdev->dev); + + put_device(&pdev->dev); + of_node_put(np); + + return client; +} + +static void mpp_device_run(void *priv) +{ + struct mpp_session *session = (struct mpp_session *)priv; + struct rockchip_mpp_dev *mpp_dev = NULL; + struct mpp_task *task; + + mpp_debug_enter(); + if (!session) + return; + + mpp_dev = session->mpp_dev; + + mpp_debug(DEBUG_IOCTL, "pid %d set reg\n", session->pid); + /* power on here */ + if (pm_runtime_get_if_in_use(mpp_dev->dev) <= 0) { + /* TODO: destroy the session and report more error */ + dev_err(mpp_dev->dev, "can't power on device\n"); + return; + } + + task = mpp_dev_alloc_task(mpp_dev, session, NULL, 0); + if (IS_ERR_OR_NULL(task)) + return; + + mpp_srv_push_pending(mpp_dev->srv, task); + mpp_session_push_pending(session, task); + atomic_inc(&session->task_running); + + /* TODO: processing the current task */ + rockchip_mpp_try_run(mpp_dev); + + mpp_debug_leave(); +} + +#if 0 +void mpp_job_abort(void *priv) +{ + struct mpp_session *session = (struct mpp_session *)priv; + + /* TODO: invoke v4l2_m2m_job_finish */ + mpp_dev_abort(session->mpp_dev); +} +#endif + +static const struct v4l2_m2m_ops mpp_m2m_ops = { + .device_run = mpp_device_run, +#if 0 + .job_abort = mpp_job_abort, +#endif +}; + +/* The device will do more probing work after this */ +int mpp_dev_common_probe(struct rockchip_mpp_dev *mpp_dev, + struct platform_device *pdev, struct mpp_dev_ops *ops) +{ + struct device *dev = NULL; + struct resource *res = NULL; + int err; + + /* Get and register to MPP service */ + mpp_dev->srv = mpp_dev_load_srv(pdev); + if (IS_ERR_OR_NULL(mpp_dev->srv)) + return PTR_ERR(mpp_dev->srv); + + dev = &pdev->dev; + mpp_dev->dev = dev; + mpp_dev->ops = ops; + + rwlock_init(&mpp_dev->resource_rwlock); + + device_init_wakeup(mpp_dev->dev, true); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + pm_runtime_idle(dev); + + mpp_dev->irq_workq = alloc_ordered_workqueue("%s_irq_wq", + WQ_MEM_RECLAIM + | WQ_FREEZABLE, + dev_name(mpp_dev->dev)); + if (!mpp_dev->irq_workq) { + dev_err(dev, "failed to create irq workqueue\n"); + err = -EINVAL; + goto failed_irq_workq; + } + + mpp_dev->irq = platform_get_irq(pdev, 0); + if (mpp_dev->irq < 0) { + dev_err(dev, "No interrupt resource found\n"); + err = -ENODEV; + goto failed; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "no memory resource defined\n"); + err = -ENODEV; + goto failed; + } + mpp_dev->reg_base = devm_ioremap_resource(dev, res); + if (IS_ERR(mpp_dev->reg_base)) { + err = PTR_ERR(mpp_dev->reg_base); + goto failed; + } + + /* V4l2 part */ + mutex_init(&mpp_dev->dev_lock); + + err = v4l2_device_register(dev, &mpp_dev->v4l2_dev); + if (err) { + dev_err(dev, "Failed to register v4l2 device\n"); + goto failed; + } + + /* TODO */ + mpp_dev->m2m_dev = v4l2_m2m_init(&mpp_m2m_ops); + if (IS_ERR(mpp_dev->m2m_dev)) { + v4l2_err(&mpp_dev->v4l2_dev, "Failed to init mem2mem device\n"); + err = PTR_ERR(mpp_dev->m2m_dev); + goto err_v4l2_unreg; + } + + mpp_dev->mdev.dev = dev; + strlcpy(mpp_dev->mdev.model, MPP_MODULE_NAME, + sizeof(mpp_dev->mdev.model)); + media_device_init(&mpp_dev->mdev); + mpp_dev->mdev.ops = &mpp_m2m_media_ops; + mpp_dev->v4l2_dev.mdev = &mpp_dev->mdev; + + mpp_dev->domain = iommu_get_domain_for_dev(dev); + + return 0; + +err_v4l2_unreg: + v4l2_device_unregister(&mpp_dev->v4l2_dev); +failed_irq_workq: + destroy_workqueue(mpp_dev->irq_workq); +failed: + pm_runtime_disable(dev); + return err; +} +EXPORT_SYMBOL(mpp_dev_common_probe); + +/* Remember to set the platform data after this */ +int mpp_dev_register_node(struct rockchip_mpp_dev *mpp_dev, + const char *node_name, const void *v4l2_fops, + const void *v4l2_ioctl_ops) +{ + struct video_device *vfd; + int ret = 0; + + /* create a device node */ + vfd = video_device_alloc(); + if (!vfd) { + v4l2_err(&mpp_dev->v4l2_dev, + "Failed to allocate video device\n"); + return -ENOMEM; + } + + if (v4l2_fops) + vfd->fops = v4l2_fops; + else + vfd->fops = &mpp_v4l2_default_fops; + + vfd->release = video_device_release; + vfd->lock = &mpp_dev->dev_lock; + vfd->v4l2_dev = &mpp_dev->v4l2_dev; + vfd->vfl_dir = VFL_DIR_M2M; + vfd->device_caps = V4L2_CAP_STREAMING; + vfd->ioctl_ops = v4l2_ioctl_ops; + + strlcpy(vfd->name, node_name, sizeof(vfd->name)); + video_set_drvdata(vfd, mpp_dev); + + ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); + if (ret) { + v4l2_err(&mpp_dev->v4l2_dev, + "Failed to register video device\n"); + goto err_m2m_rel; + } + v4l2_info(&mpp_dev->v4l2_dev, "registered as /dev/video%d\n", vfd->num); + + ret = v4l2_m2m_register_media_controller(mpp_dev->m2m_dev, vfd, + mpp_dev->variant->vfd_func); + if (ret) { + v4l2_err(&mpp_dev->v4l2_dev, + "Failed to init mem2mem media controller\n"); + goto err_unreg_video; + } + + mpp_dev->vfd = vfd; + + ret = media_device_register(&mpp_dev->mdev); + if (ret) { + v4l2_err(&mpp_dev->v4l2_dev, + "Failed to register mem2mem media device\n"); + goto err_unreg_video_dev; + } + + return 0; + +err_unreg_video: + video_unregister_device(mpp_dev->vfd); +err_unreg_video_dev: + video_device_release(mpp_dev->vfd); +err_m2m_rel: + v4l2_m2m_release(mpp_dev->m2m_dev); + return ret; +} +EXPORT_SYMBOL(mpp_dev_register_node); + +int mpp_dev_common_remove(struct rockchip_mpp_dev *mpp_dev) +{ + destroy_workqueue(mpp_dev->irq_workq); + + media_device_unregister(&mpp_dev->mdev); + v4l2_m2m_unregister_media_controller(mpp_dev->m2m_dev); + media_device_cleanup(&mpp_dev->mdev); + + video_unregister_device(mpp_dev->vfd); + video_device_release(mpp_dev->vfd); + + mpp_srv_detach(mpp_dev->srv); + + mpp_dev_power_off(mpp_dev); + + device_init_wakeup(mpp_dev->dev, false); + pm_runtime_disable(mpp_dev->dev); + + return 0; +} +EXPORT_SYMBOL(mpp_dev_common_remove); + +void mpp_debug_dump_reg(void __iomem *regs, int count) +{ + int i; + + pr_info("dumping registers: %p\n", regs); + + for (i = 0; i < count; i++) + pr_info("reg[%02d]: %08x\n", i, readl_relaxed(regs + i * 4)); +} +EXPORT_SYMBOL(mpp_debug_dump_reg); + +void mpp_debug_dump_reg_mem(u32 *regs, int count) +{ + int i; + + pr_info("Dumping registers: %p\n", regs); + + for (i = 0; i < count; i++) + pr_info("reg[%03d]: %08x\n", i, regs[i]); +} +EXPORT_SYMBOL(mpp_debug_dump_reg_mem); + +void mpp_dev_write_seq(struct rockchip_mpp_dev *mpp_dev, unsigned long offset, + void *buffer, unsigned long count) +{ + int i; + + for (i = 0; i < count; i++) { + u32 *cur = (u32 *)buffer; + u32 pos = offset + i * 4; + u32 j = i + (u32)(offset / 4); + + cur += i; + mpp_debug(DEBUG_SET_REG, "write reg[%03d]: %08x\n", j, *cur); + iowrite32(*cur, mpp_dev->reg_base + pos); + } +} +EXPORT_SYMBOL(mpp_dev_write_seq); + +void mpp_dev_write(struct rockchip_mpp_dev *mpp, u32 reg, u32 val) +{ + mpp_debug(DEBUG_SET_REG, "write reg[%03d]: %08x\n", reg / 4, val); + iowrite32(val, mpp->reg_base + reg); +} +EXPORT_SYMBOL(mpp_dev_write); + +void mpp_dev_read_seq(struct rockchip_mpp_dev *mpp_dev, + unsigned long offset, void *buffer, + unsigned long count) +{ + int i = 0; + + for (i = 0; i < count; i++) { + u32 *cur = (u32 *)buffer; + u32 pos = offset / 4 + i; + + cur += i; + *cur = ioread32(mpp_dev->reg_base + pos * 4); + mpp_debug(DEBUG_GET_REG, "get reg[%03d]: %08x\n", pos, *cur); + } +} +EXPORT_SYMBOL(mpp_dev_read_seq); + +u32 mpp_dev_read(struct rockchip_mpp_dev *mpp, u32 reg) +{ + u32 val = ioread32(mpp->reg_base + reg); + + mpp_debug(DEBUG_GET_REG, "get reg[%03d] 0x%x: %08x\n", reg / 4, + reg, val); + return val; +} +EXPORT_SYMBOL(mpp_dev_read); + +void mpp_debug_time_record(struct mpp_task *task) +{ + if (unlikely(debug & DEBUG_TIMING) && task) + getboottime64(&task->start); +} +EXPORT_SYMBOL(mpp_debug_time_record); + +void mpp_debug_time_diff(struct mpp_task *task) +{ + struct timespec64 end; + + getboottime64(&end); + mpp_debug(DEBUG_TIMING, "time: %lld ms\n", + (end.tv_sec - task->start.tv_sec) * 1000 + + (end.tv_nsec - task->start.tv_nsec) / 1000000); +} +EXPORT_SYMBOL(mpp_debug_time_diff); + +static int mpp_m2m_querycap(struct file *filp, void *fh, + struct v4l2_capability *cap) +{ + struct rockchip_mpp_dev *mpp_dev = video_drvdata(filp); + + strscpy(cap->driver, MPP_MODULE_NAME, sizeof(cap->driver)); + strscpy(cap->card, MPP_MODULE_NAME, sizeof(cap->card)); + snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", + dev_name(mpp_dev->dev)); + + cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; + + return 0; +} + +static int mpp_g_fmt_mplane(struct file *filp, void *fh, struct v4l2_format *f) +{ + struct mpp_session *session = container_of(filp->private_data, + struct mpp_session, fh); + + struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; + struct v4l2_pix_format_mplane *fmt = NULL; + + if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + fmt = &session->fmt_cap; + else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) + fmt = &session->fmt_out; + + *pix_mp = *fmt; + + return 0; +} + +static int mpp_enum_fmt_mplane(struct file *filp, void *priv, + struct v4l2_fmtdesc *f) +{ + struct rockchip_mpp_dev *mpp_dev = video_drvdata(filp); + const struct v4l2_pix_format_mplane *formats; + unsigned int num_fmts; + + switch (f->type) { + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: + num_fmts = ARRAY_SIZE(mpp_dev->fmt_out); + formats = mpp_dev->fmt_out; + break; + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + num_fmts = ARRAY_SIZE(mpp_dev->fmt_cap); + formats = mpp_dev->fmt_cap; + break; + default: + return -EINVAL; + } + + if (f->index >= num_fmts) + return -EINVAL; + + if (formats[f->index].pixelformat == 0) + return -EINVAL; + + f->pixelformat = formats[f->index].pixelformat; + + return 0; +} + +static int mpp_try_fmt_mplane(struct file *filp, void *priv, + struct v4l2_format *f) +{ + struct rockchip_mpp_dev *mpp_dev = video_drvdata(filp); + const struct v4l2_pix_format_mplane *formats; + unsigned int num_fmts; + int i; + + switch (f->type) { + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: + num_fmts = ARRAY_SIZE(mpp_dev->fmt_out); + formats = mpp_dev->fmt_out; + break; + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + num_fmts = ARRAY_SIZE(mpp_dev->fmt_cap); + formats = mpp_dev->fmt_cap; + break; + default: + return -EINVAL; + } + + for (i = 0; i < num_fmts; i++) { + if (f->fmt.pix_mp.pixelformat == formats[i].pixelformat) + return 0; + } + + return -EINVAL; +} + +const struct v4l2_ioctl_ops mpp_ioctl_ops_templ = { + .vidioc_querycap = mpp_m2m_querycap, +#if 0 + .vidioc_try_fmt_vid_cap = mpp_try_fmt_cap, + .vidioc_try_fmt_vid_out = mpp_try_fmt_out, + .vidioc_s_fmt_vid_out = mpp_s_fmt_out, + .vidioc_s_fmt_vid_cap = mpp_s_fmt_cap, +#endif + .vidioc_try_fmt_vid_out_mplane = mpp_try_fmt_mplane, + .vidioc_try_fmt_vid_cap_mplane = mpp_try_fmt_mplane, + .vidioc_g_fmt_vid_out_mplane = mpp_g_fmt_mplane, + .vidioc_g_fmt_vid_cap_mplane = mpp_g_fmt_mplane, + .vidioc_enum_fmt_vid_out_mplane = mpp_enum_fmt_mplane, + .vidioc_enum_fmt_vid_cap_mplane = mpp_enum_fmt_mplane, + + .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, + .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, + .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, + .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, + .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, + .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, + .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, + + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, + + .vidioc_streamon = v4l2_m2m_ioctl_streamon, + .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, +}; +EXPORT_SYMBOL(mpp_ioctl_ops_templ); + +static int mpp_queue_setup(struct vb2_queue *vq, unsigned int *num_buffers, + unsigned int *num_planes, unsigned int sizes[], + struct device *alloc_devs[]) +{ + struct mpp_session *session = vb2_get_drv_priv(vq); + struct v4l2_pix_format_mplane *pixfmt; + int i; + + switch (vq->type) { + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: + pixfmt = &session->fmt_out; + break; + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + pixfmt = &session->fmt_cap; + break; + default: + return -EINVAL; + } + + if (*num_planes) { + if (*num_planes != pixfmt->num_planes) + return -EINVAL; + for (i = 0; i < pixfmt->num_planes; ++i) + if (sizes[i] < pixfmt->plane_fmt[i].sizeimage) + return -EINVAL; + + return 0; + } + + *num_planes = pixfmt->num_planes; + for (i = 0; i < pixfmt->num_planes; i++) + sizes[i] = pixfmt->plane_fmt[i].sizeimage; + + return 0; +} + +/* I am sure what is used for */ +static int mpp_buf_out_validata(struct vb2_buffer *vb) +{ + return 0; +} + +static int mpp_start_streaming(struct vb2_queue *vq, unsigned int count) +{ + struct mpp_session *session = vb2_get_drv_priv(vq); + + if (V4L2_TYPE_IS_OUTPUT(vq->type)) + session->sequence_out = 0; + else + session->sequence_cap = 0; + + return 0; +} + +static void mpp_stop_streaming(struct vb2_queue *vq) +{ + struct mpp_session *session = vb2_get_drv_priv(vq); + + for (;;) { + struct vb2_v4l2_buffer *vbuf; + + if (V4L2_TYPE_IS_OUTPUT(vq->type)) + vbuf = v4l2_m2m_src_buf_remove(session->fh.m2m_ctx); + else + vbuf = v4l2_m2m_dst_buf_remove(session->fh.m2m_ctx); + + if (!vbuf) + break; + + v4l2_ctrl_request_complete(vbuf->vb2_buf.req_obj.req, + &session->ctrl_handler); + v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR); + } +} + +static void mpp_buf_queue(struct vb2_buffer *vb) { + struct mpp_session *session = vb2_get_drv_priv(vb->vb2_queue); + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + + /* TODO: may alloc registers table here */ + v4l2_m2m_buf_queue(session->fh.m2m_ctx, vbuf); +} + +static void mpp_buf_request_complete(struct vb2_buffer *vb) { + struct mpp_session *session = vb2_get_drv_priv(vb->vb2_queue); + + v4l2_ctrl_request_complete(vb->req_obj.req, &session->ctrl_handler); +} + +static const struct vb2_ops mpp_queue_ops = { + .queue_setup = mpp_queue_setup, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, + /* + * TODO: may write back feedback to userspace .buf_finish for encoder, + * not the slice header which the job of the userspace + */ + /* TODO: fill the INPUT buffer with device configure at .buf_prepare */ + .buf_out_validate = mpp_buf_out_validata, + .start_streaming = mpp_start_streaming, + .stop_streaming = mpp_stop_streaming, + .buf_queue = mpp_buf_queue, + .buf_request_complete = mpp_buf_request_complete, +}; + +static int rockchip_mpp_queue_init(void *priv, struct vb2_queue *src_vq, + struct vb2_queue *dst_vq) +{ + struct mpp_session *session = priv; + int ret; + + src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + src_vq->io_modes = VB2_MMAP | VB2_DMABUF; + src_vq->drv_priv = session; + src_vq->mem_ops = &vb2_dma_contig_memops; + src_vq->dma_attrs = DMA_ATTR_ALLOC_SINGLE_PAGES | + DMA_ATTR_NO_KERNEL_MAPPING; + src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); + src_vq->min_buffers_needed = 1; + src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; + src_vq->lock = &session->mpp_dev->dev_lock; + src_vq->ops = &mpp_queue_ops; + src_vq->dev = session->mpp_dev->v4l2_dev.dev; + src_vq->supports_requests = true; + + ret = vb2_queue_init(src_vq); + if (ret) + return ret; + + dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; + dst_vq->min_buffers_needed = 1; + dst_vq->drv_priv = session; + dst_vq->mem_ops = &vb2_dma_contig_memops; + dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); + dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; + dst_vq->lock = &session->mpp_dev->dev_lock; + dst_vq->ops = &mpp_queue_ops; + dst_vq->dev = session->mpp_dev->v4l2_dev.dev; + + ret = vb2_queue_init(dst_vq); + + return ret; +} + +void *rockchip_mpp_alloc_session(struct rockchip_mpp_dev *mpp_dev, + struct video_device *vdev) +{ + struct mpp_session *session = NULL; + int error = 0; + + mpp_debug_enter(); + + session = kzalloc(sizeof(*session), GFP_KERNEL); + if (!session) + return ERR_PTR(-ENOMEM); + + session->pid = current->pid; + session->mpp_dev = mpp_dev; + mutex_init(&session->lock); + INIT_LIST_HEAD(&session->pending); + init_waitqueue_head(&session->wait); + error = kfifo_alloc(&session->done_fifo, MPP_SESSION_MAX_DONE_TASK, + GFP_KERNEL); + if (error < 0) + goto fail; + + atomic_set(&session->task_running, 0); + INIT_LIST_HEAD(&session->list_session); + + session->fh.m2m_ctx = v4l2_m2m_ctx_init(mpp_dev->m2m_dev, session, + rockchip_mpp_queue_init); + if (IS_ERR(session->fh.m2m_ctx)) { + error = PTR_ERR(session->fh.m2m_ctx); + goto fail; + } + v4l2_fh_init(&session->fh, vdev); + v4l2_fh_add(&session->fh); + + mpp_debug_leave(); + + return session; + +fail: + kfree(session); + return ERR_PTR(error); +} +EXPORT_SYMBOL(rockchip_mpp_alloc_session); + +int rockchip_mpp_dev_release(struct file *filp) +{ + struct mpp_session *session = container_of(filp->private_data, + struct mpp_session, fh); + struct rockchip_mpp_dev *mpp_dev = video_drvdata(filp); + + mpp_debug_enter(); + if (!session) + return -EINVAL; + + /* TODO: is it necessary for v4l2? */ +#if 0 + int task_running; + task_running = atomic_read(&session->task_running); + if (task_running) { + pr_err("session %d still has %d task running when closing\n", + session->pid, task_running); + msleep(50); + } + wake_up(&session->wait); +#endif + + v4l2_m2m_ctx_release(session->fh.m2m_ctx); + v4l2_fh_del(&session->fh); + v4l2_fh_exit(&session->fh); + v4l2_ctrl_handler_free(&session->ctrl_handler); + mpp_dev_session_clear(mpp_dev, session); + + kfifo_free(&session->done_fifo); + filp->private_data = NULL; + + mpp_dev_power_off(mpp_dev); + kfree(session); + + dev_dbg(mpp_dev->dev, "closed\n"); + mpp_debug_leave(); + return 0; +} +EXPORT_SYMBOL(rockchip_mpp_dev_release); + +void *rockchip_mpp_get_cur_ctrl(struct mpp_session *session, u32 id) +{ + struct v4l2_ctrl *ctrl; + + ctrl = v4l2_ctrl_find(&session->ctrl_handler, id); + return ctrl ? ctrl->p_cur.p : NULL; +} +EXPORT_SYMBOL(rockchip_mpp_get_cur_ctrl); + +int rockchip_mpp_get_ref_idx(struct vb2_queue *queue, + struct vb2_buffer *vb2_buf, u64 timestamp) +{ + /* FIXME: TODO: the timestamp is not copied yet before copy_data */ + if (vb2_buf->timestamp == timestamp) + return vb2_buf->index; + else + return vb2_find_timestamp(queue, timestamp, 0); +} +EXPORT_SYMBOL(rockchip_mpp_get_ref_idx); + +dma_addr_t rockchip_mpp_find_addr(struct vb2_queue *queue, + struct vb2_buffer *vb2_buf, u64 timestamp) +{ + int idx = -1; + + idx = rockchip_mpp_get_ref_idx(queue, vb2_buf, timestamp); + if (idx < 0) + return 0; + + return vb2_dma_contig_plane_dma_addr(queue->bufs[idx], 0); +} +EXPORT_SYMBOL(rockchip_mpp_find_addr); + +static const struct v4l2_file_operations mpp_v4l2_default_fops = { + .open = rockchip_mpp_dev_open, + .release = rockchip_mpp_dev_release, + .poll = v4l2_m2m_fop_poll, + .unlocked_ioctl = video_ioctl2, + .mmap = v4l2_m2m_fop_mmap, +}; + +static int __init mpp_device_init(void) +{ + mpp_device_class = class_create(THIS_MODULE, "mpp_device"); + if (PTR_ERR_OR_ZERO(mpp_device_class)) + return PTR_ERR(mpp_device_class); + + return 0; +} + +static void __exit mpp_device_exit(void) +{ + class_destroy(mpp_device_class); +} + +module_init(mpp_device_init); +module_exit(mpp_device_exit); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/rockchip-mpp/mpp_dev_common.h b/drivers/staging/rockchip-mpp/mpp_dev_common.h new file mode 100644 index 000000000000..36770af53a95 --- /dev/null +++ b/drivers/staging/rockchip-mpp/mpp_dev_common.h @@ -0,0 +1,212 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2016 - 2017 Fuzhou Rockchip Electronics Co., Ltd + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _ROCKCHIP_MPP_DEV_COMMON_H_ +#define _ROCKCHIP_MPP_DEV_COMMON_H_ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "mpp_service.h" + +#define MPP_MODULE_NAME "rk-mpp" + +extern const struct v4l2_ioctl_ops mpp_ioctl_ops_templ; + +struct mpp_dev_variant { + u32 reg_len; + const char *node_name; + u32 version_bit; + int vfd_func; +}; + +/* Definition in mpp service file */ +struct mpp_service; + +struct rockchip_mpp_dev { + struct device *dev; + + const struct mpp_dev_variant *variant; + struct mpp_dev_ops *ops; + struct v4l2_pix_format_mplane fmt_out[16]; + struct v4l2_pix_format_mplane fmt_cap[16]; + + void __iomem *reg_base; + int irq; + struct workqueue_struct *irq_workq; + struct iommu_domain *domain; + + rwlock_t resource_rwlock; + atomic_t reset_request; + + struct v4l2_device v4l2_dev; + struct v4l2_m2m_dev *m2m_dev; + struct media_device mdev; + struct video_device *vfd; + struct mutex dev_lock; + + /* MPP Service */ + struct mpp_service_node *srv; +}; + +struct mpp_task; + +struct mpp_session { + /* the session related device private data */ + struct rockchip_mpp_dev *mpp_dev; + /* a linked list of data so we can access them for debugging */ + struct list_head list_session; + + /* session tasks list lock */ + struct mutex lock; + struct list_head pending; + + DECLARE_KFIFO_PTR(done_fifo, struct mpp_task *); + + wait_queue_head_t wait; + pid_t pid; + atomic_t task_running; + + struct v4l2_fh fh; + u32 sequence_cap; + u32 sequence_out; + + struct v4l2_pix_format_mplane fmt_out; + struct v4l2_pix_format_mplane fmt_cap; + + struct v4l2_ctrl_handler ctrl_handler; + /* TODO: FIXME: slower than helper function ? */ + struct v4l2_ctrl **ctrls; +}; + +/* The context for the a task */ +struct mpp_task { + /* context belong to */ + struct mpp_session *session; + + /* link to service session */ + struct list_head session_link; + /* link to service list */ + struct list_head service_link; + struct work_struct work; + + /* record context running start time */ + struct timespec64 start; +}; + +/* + * struct mpp_dev_ops - context specific operations for a device + * The task part + * @alloc_task + * @prepare Check HW status for determining run next task or not. + * @run Start a single {en,de}coding run. Set registers to hardware. + * @finish Read back processing results and additional data from hardware. + * @result Read status to userspace. + * @free_task Release the resource allocate during init. + * The device part + * @reset + */ +struct mpp_dev_ops { + /* size: in bytes, data sent from userspace, length in bytes */ + void *(*alloc_task)(struct mpp_session *session, + void __user *src, u32 size); + int (*prepare)(struct rockchip_mpp_dev *mpp_dev, struct mpp_task *task); + int (*run)(struct rockchip_mpp_dev *mpp_dev, struct mpp_task *task); + int (*finish)(struct rockchip_mpp_dev *mpp_dev, struct mpp_task *task); + int (*result)(struct rockchip_mpp_dev *mpp_dev, struct mpp_task *task, + u32 __user *dst, u32 size); + int (*free_task)(struct mpp_session *session, + struct mpp_task *task); + /* Hardware only operations */ + int (*reset)(struct rockchip_mpp_dev *mpp_dev); +}; + +struct rockchip_mpp_control { + u32 codec; + u32 id; + u32 elem_size; +}; + +void *rockchip_mpp_alloc_session(struct rockchip_mpp_dev *mpp_dev, + struct video_device *vdev); +int rockchip_mpp_dev_release(struct file *filp); + +void *rockchip_mpp_get_cur_ctrl(struct mpp_session *session, u32 id); +int rockchip_mpp_get_ref_idx(struct vb2_queue *queue, + struct vb2_buffer *vb2_buf, u64 timestamp); +dma_addr_t rockchip_mpp_find_addr(struct vb2_queue *queue, + struct vb2_buffer *vb2_buf, u64 timestamp); + +int mpp_dev_task_init(struct mpp_session *session, struct mpp_task *task); +void mpp_dev_task_finish(struct mpp_session *session, struct mpp_task *task); +void mpp_dev_task_finalize(struct mpp_session *session, struct mpp_task *task); + +void mpp_dev_power_on(struct rockchip_mpp_dev *mpp); +void mpp_dev_power_off(struct rockchip_mpp_dev *mpp); +bool mpp_dev_is_power_on(struct rockchip_mpp_dev *mpp); + +void mpp_dump_reg(void __iomem *regs, int count); +void mpp_dump_reg_mem(u32 *regs, int count); + +int mpp_dev_common_probe(struct rockchip_mpp_dev *mpp_dev, + struct platform_device *pdev, + struct mpp_dev_ops *ops); +int mpp_dev_register_node(struct rockchip_mpp_dev *mpp_dev, + const char *node_name, const void *v4l2_fops, + const void *v4l2_ioctl_ops); +int mpp_dev_common_remove(struct rockchip_mpp_dev *mpp_dev); + +static inline void safe_reset(struct reset_control *rst) +{ + if (rst) + reset_control_assert(rst); +} + +static inline void safe_unreset(struct reset_control *rst) +{ + if (rst) + reset_control_deassert(rst); +} + +void mpp_dev_write_seq(struct rockchip_mpp_dev *mpp_dev, + unsigned long offset, void *buffer, + unsigned long count); + +void mpp_dev_write(struct rockchip_mpp_dev *mpp, u32 val, u32 reg); + +void mpp_dev_read_seq(struct rockchip_mpp_dev *mpp_dev, + unsigned long offset, void *buffer, + unsigned long count); + +u32 mpp_dev_read(struct rockchip_mpp_dev *mpp, u32 reg); + +void mpp_debug_time_record(struct mpp_task *task); +void mpp_debug_time_diff(struct mpp_task *task); + +void mpp_debug_dump_reg(void __iomem *regs, int count); +void mpp_debug_dump_reg_mem(u32 *regs, int count); + +#endif diff --git a/drivers/staging/rockchip-mpp/mpp_dev_rkvdec.c b/drivers/staging/rockchip-mpp/mpp_dev_rkvdec.c new file mode 100644 index 000000000000..756821dbf829 --- /dev/null +++ b/drivers/staging/rockchip-mpp/mpp_dev_rkvdec.c @@ -0,0 +1,919 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "mpp_debug.h" +#include "mpp_dev_common.h" +#include "rkvdec/cabac.h" +#include "rkvdec/hal.h" + +#define RKVDEC_DRIVER_NAME "mpp_rkvdec" + +#define RKVDEC_VER_RK3328_BIT BIT(1) +#define IOMMU_GET_BUS_ID(x) (((x) >> 6) & 0x1f) +#define IOMMU_PAGE_SIZE SZ_4K + +#define RKVDEC_NODE_NAME "rkvdec" +#define RK_HEVCDEC_NODE_NAME "hevc-service" + +#define to_rkvdec_task(ctx) \ + container_of(ctx, struct rkvdec_task, mpp_task) +#define to_rkvdec_dev(dev) \ + container_of(dev, struct rockchip_rkvdec_dev, mpp_dev) + +#define RKVDEC_ERROR_INFO_SIZE (144 * 4) +#define RKVDEC_ERROR_INFO_MAX_SIZE (RKVDEC_ERROR_INFO_SIZE * 256) + +static int debug; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "bit switch for rkvdec debug information"); + +enum RKVDEC_STATE { + RKVDEC_STATE_NORMAL, + RKVDEC_STATE_LT_START, + RKVDEC_STATE_LT_RUN, +}; + +struct rockchip_rkvdec_dev { + struct rockchip_mpp_dev mpp_dev; + + struct reset_control *rst_a; + struct reset_control *rst_h; + struct reset_control *rst_niu_a; + struct reset_control *rst_niu_h; + struct reset_control *rst_core; + struct reset_control *rst_cabac; + + enum RKVDEC_STATE state; + + unsigned long aux_iova; + struct page *aux_page; + + dma_addr_t cabac_avc_addr; + void *cabac_avc_vaddr; + + dma_addr_t cabac_hevc_addr; + void *cabac_hevc_vaddr; + + dma_addr_t errorinfo_addr; + void *errorinfo_vaddr; + + void *current_task; +}; + +struct rkvdec_task { + struct mpp_task mpp_task; + + u32 reg[ROCKCHIP_RKVDEC_REG_NUM]; + u32 idx; + + u32 irq_status; +}; + +static struct rockchip_mpp_control hevc_controls[] = { + { + .codec = V4L2_PIX_FMT_HEVC_SLICE, + .id = V4L2_CID_MPEG_VIDEO_HEVC_SPS, + .elem_size = sizeof(struct v4l2_ctrl_hevc_sps), + }, + { + .codec = V4L2_PIX_FMT_HEVC_SLICE, + .id = V4L2_CID_MPEG_VIDEO_HEVC_PPS, + .elem_size = sizeof(struct v4l2_ctrl_hevc_pps), + }, + { + .codec = V4L2_PIX_FMT_HEVC_SLICE, + .id = V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS, + .elem_size = sizeof(struct v4l2_ctrl_hevc_slice_params), + }, +}; + +static struct rockchip_mpp_control rkvdec_controls[] = { + { + .codec = V4L2_PIX_FMT_HEVC_SLICE, + .id = V4L2_CID_MPEG_VIDEO_HEVC_SPS, + .elem_size = sizeof(struct v4l2_ctrl_hevc_sps), + }, + { + .codec = V4L2_PIX_FMT_HEVC_SLICE, + .id = V4L2_CID_MPEG_VIDEO_HEVC_PPS, + .elem_size = sizeof(struct v4l2_ctrl_hevc_pps), + }, + { + .codec = V4L2_PIX_FMT_HEVC_SLICE, + .id = V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS, + .elem_size = sizeof(struct v4l2_ctrl_hevc_slice_params), + }, + { + .codec = V4L2_PIX_FMT_H264_SLICE, + .id = V4L2_CID_MPEG_VIDEO_H264_SPS, + .elem_size = sizeof(struct v4l2_ctrl_h264_sps), + }, + { + .codec = V4L2_PIX_FMT_H264_SLICE, + .id = V4L2_CID_MPEG_VIDEO_H264_PPS, + .elem_size = sizeof(struct v4l2_ctrl_h264_pps), + }, + { + .codec = V4L2_PIX_FMT_H264_SLICE, + .id = V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX, + .elem_size = sizeof(struct v4l2_ctrl_h264_scaling_matrix), + }, + { + .codec = V4L2_PIX_FMT_H264_SLICE, + .id = V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS, + .elem_size = sizeof(struct v4l2_ctrl_h264_slice_param), + }, + { + .codec = V4L2_PIX_FMT_H264_SLICE, + .id = V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS, + .elem_size = sizeof(struct v4l2_ctrl_h264_decode_param), + }, +}; + +static const struct v4l2_pix_format_mplane fmt_out_templ[] = { + { + .pixelformat = V4L2_PIX_FMT_H264_SLICE, + }, + { + .pixelformat = V4L2_PIX_FMT_HEVC_SLICE, + }, +}; + +static const struct v4l2_pix_format_mplane fmt_cap_templ[] = { + { + .pixelformat = V4L2_PIX_FMT_NV12M, + }, + { + .pixelformat = V4L2_PIX_FMT_NV16M, + }, +}; + +static const struct mpp_dev_variant rkvdec_v1_data = { + .reg_len = 76, + .node_name = RKVDEC_NODE_NAME, + .version_bit = BIT(0), + .vfd_func = MEDIA_ENT_F_PROC_VIDEO_DECODER, +}; + +static const struct mpp_dev_variant rkvdec_v1p_data = { + .reg_len = 76, + .node_name = RKVDEC_NODE_NAME, + .version_bit = RKVDEC_VER_RK3328_BIT, + .vfd_func = MEDIA_ENT_F_PROC_VIDEO_DECODER, +}; + +static const struct mpp_dev_variant rk_hevcdec_data = { + .reg_len = 48, + .node_name = RK_HEVCDEC_NODE_NAME, + .version_bit = BIT(0), + .vfd_func = MEDIA_ENT_F_PROC_VIDEO_DECODER, +}; + +static int rkvdec_open(struct file *filp); + +static const struct v4l2_file_operations rkvdec_fops = { + .open = rkvdec_open, + .release = rockchip_mpp_dev_release, + .poll = v4l2_m2m_fop_poll, + .unlocked_ioctl = video_ioctl2, + .mmap = v4l2_m2m_fop_mmap, +}; + +static struct v4l2_ioctl_ops rkvdec_ioctl_ops = { 0, }; + +static void *rockchip_rkvdec_get_drv_data(struct platform_device *pdev); + +static int rkvdec_s_fmt_vid_out_mplane(struct file *filp, void *priv, + struct v4l2_format *f) +{ + struct mpp_session *session = container_of(filp->private_data, + struct mpp_session, fh); + struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; + struct vb2_queue *vq; + int sizes = 0; + int i; + + /* TODO: We can change width and height at streaming on */ + vq = v4l2_m2m_get_vq(session->fh.m2m_ctx, f->type); + if (vb2_is_streaming(vq)) + return -EBUSY; + + if (!pix_mp->num_planes) + pix_mp->num_planes = 1; + + for (i = 0; i < pix_mp->num_planes; i++) { + sizes += pix_mp->plane_fmt[i].sizeimage; + } + /* strm_len is 24 bits */ + if (sizes >= SZ_16M - SZ_1K) + return -EINVAL; + + /* FIXME: For those slice header data, put it in a better place */ + pix_mp->plane_fmt[pix_mp->num_planes - 1].sizeimage += SZ_4M; + + session->fmt_out = *pix_mp; + + /* Copy the pixel format information from OUTPUT to CAPUTRE */ + session->fmt_cap.pixelformat = V4L2_PIX_FMT_NV12M; + session->fmt_cap.width = pix_mp->width; + session->fmt_cap.height = pix_mp->height; + session->fmt_cap.colorspace = pix_mp->colorspace; + session->fmt_cap.ycbcr_enc = pix_mp->ycbcr_enc; + session->fmt_cap.xfer_func = pix_mp->xfer_func; + session->fmt_cap.quantization = pix_mp->quantization; + + return 0; +} + +static int rkvdec_s_fmt_vid_cap_mplane(struct file *filp, void *priv, + struct v4l2_format *f) +{ + struct mpp_session *session = container_of(filp->private_data, + struct mpp_session, fh); + struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; + struct vb2_queue *vq; + + vq = v4l2_m2m_get_vq(session->fh.m2m_ctx, f->type); + if (vb2_is_streaming(vq)) + return -EBUSY; + + switch (pix_mp->pixelformat) { + case V4L2_PIX_FMT_NV12M: + /* TODO: adaptive based by cache settings */ + pix_mp->plane_fmt[0].bytesperline = + ALIGN(pix_mp->width, 256) | 256; + pix_mp->plane_fmt[1].bytesperline = + ALIGN(pix_mp->width, 256) | 256; +#if 0 + /* TODO: align with 16 for H.264 */ + pix_mp->plane_fmt[0].sizeimage = + pix_mp->plane_fmt[0].bytesperline * ALIGN(pix_mp->height, + 8); + /* Additional space for motion vector */ + pix_mp->plane_fmt[1].sizeimage = + pix_mp->plane_fmt[1].bytesperline * ALIGN(pix_mp->height, + 8); +#else + /* TODO: HEVC only request the height is aligned with 8 */ + pix_mp->plane_fmt[0].sizeimage = + pix_mp->plane_fmt[0].bytesperline * ALIGN(pix_mp->height, + 16); + /* Additional space for motion vector */ + pix_mp->plane_fmt[0].sizeimage *= 2; + pix_mp->plane_fmt[0].sizeimage += SZ_4M; + pix_mp->plane_fmt[1].sizeimage = SZ_2M; +#endif + pix_mp->num_planes = 2; + break; + case V4L2_PIX_FMT_NV16M: + pix_mp->plane_fmt[0].bytesperline = + ALIGN(pix_mp->width, 256) | 256; + pix_mp->plane_fmt[1].bytesperline = + ALIGN(pix_mp->width, 256) | 256; + pix_mp->plane_fmt[0].sizeimage = + pix_mp->plane_fmt[0].bytesperline * ALIGN(pix_mp->height, + 8); + /* Additional space for motion vector */ + pix_mp->plane_fmt[1].sizeimage = + pix_mp->plane_fmt[1].bytesperline * ALIGN(pix_mp->height, + 8) * 3 / 2; + pix_mp->num_planes = 2; + break; + default: + return -EINVAL; + } + + session->fmt_cap = *pix_mp; + + return 0; +} + +static int rkvdec_setup_ctrls(struct rockchip_mpp_dev *mpp_dev, + struct mpp_session *session) +{ + struct v4l2_ctrl_handler *hdl = &session->ctrl_handler; + struct v4l2_ctrl *ctrl; + unsigned int num_ctrls = ARRAY_SIZE(rkvdec_controls); + unsigned int i; + + v4l2_ctrl_handler_init(hdl, num_ctrls); + if (hdl->error) { + v4l2_err(&mpp_dev->v4l2_dev, + "Failed to initialize control handler\n"); + return hdl->error; + } + + for (i = 0; i < num_ctrls; i++) { + struct v4l2_ctrl_config cfg = { }; + + cfg.id = rkvdec_controls[i].id; + cfg.elem_size = rkvdec_controls[i].elem_size; + + ctrl = v4l2_ctrl_new_custom(hdl, &cfg, NULL); + if (hdl->error) { + v4l2_err(&mpp_dev->v4l2_dev, + "Failed to create new custom %d control\n", + cfg.id); + goto fail; + } + } + + session->fh.ctrl_handler = hdl; + v4l2_ctrl_handler_setup(hdl); + + return 0; +fail: + v4l2_ctrl_handler_free(hdl); + return hdl->error; +} + +static int rkvdec_open(struct file *filp) +{ + struct rockchip_mpp_dev *mpp_dev = video_drvdata(filp); + struct video_device *vdev = video_devdata(filp); + struct mpp_session *session = NULL; + /* TODO: install ctrl based on register report */ + int error = 0; + + mpp_debug_enter(); + + session = rockchip_mpp_alloc_session(mpp_dev, vdev); + if (IS_ERR_OR_NULL(session)) + return PTR_ERR(session); + + error = rkvdec_setup_ctrls(mpp_dev, session); + if (error) { + kfree(session); + return error; + } + + filp->private_data = &session->fh; + pm_runtime_get_sync(mpp_dev->dev); + + mpp_debug_leave(); + return 0; +} + +static void *rockchip_mpp_rkvdec_alloc_task(struct mpp_session *session, + void __user * src, u32 size) +{ + struct rockchip_rkvdec_dev *dec_dev = to_rkvdec_dev(session->mpp_dev); + struct rkvdec_task *task = NULL; + struct vb2_v4l2_buffer *src_buf; + u32 fmt = 0; + int err = -EFAULT; + + mpp_debug_enter(); + + task = kzalloc(sizeof(*task), GFP_KERNEL); + if (!task) + return NULL; + + mpp_dev_task_init(session, &task->mpp_task); + + src_buf = v4l2_m2m_next_src_buf(session->fh.m2m_ctx); + v4l2_ctrl_request_setup(src_buf->vb2_buf.req_obj.req, + &session->ctrl_handler); + + fmt = session->fmt_out.pixelformat; + switch (fmt) { + case V4L2_PIX_FMT_HEVC_SLICE: + err = rkvdec_hevc_gen_reg(session, task->reg, src_buf); + rkvdec_assign_cabac(task->reg, dec_dev->cabac_hevc_addr); + break; + case V4L2_PIX_FMT_H264_SLICE: + err = rkvdec_avc_gen_reg(session, task->reg, src_buf); + rkvdec_assign_cabac(task->reg, dec_dev->cabac_avc_addr); + rkvdec_avc_assign_errorinfo(task->reg, dec_dev->errorinfo_addr); + break; + default: + goto fail; + } + + if (err) + goto fail; + + v4l2_ctrl_request_complete(src_buf->vb2_buf.req_obj.req, + &session->ctrl_handler); + + mpp_debug_leave(); + + return &task->mpp_task; + +fail: + kfree(task); + return ERR_PTR(err); +} + +static int rockchip_mpp_rkvdec_prepare(struct rockchip_mpp_dev *mpp_dev, + struct mpp_task *task) +{ + struct rockchip_rkvdec_dev *dec_dev = to_rkvdec_dev(mpp_dev); + + if (dec_dev->state == RKVDEC_STATE_NORMAL) + return -EINVAL; + /* + * Don't do soft reset before running or you will meet 0x00408322 + * if you will decode a HEVC stream. Different error for the AVC. + */ + + return 0; +} + +static int rockchip_mpp_rkvdec_run(struct rockchip_mpp_dev *mpp_dev, + struct mpp_task *mpp_task) +{ + struct rockchip_rkvdec_dev *dec_dev = NULL; + struct rkvdec_task *task = NULL; + u32 reg = 0; + + mpp_debug_enter(); + + dec_dev = to_rkvdec_dev(mpp_dev); + task = to_rkvdec_task(mpp_task); + + switch (dec_dev->state) { + case RKVDEC_STATE_NORMAL: + /* FIXME: spin lock here */ + dec_dev->current_task = task; + + reg = RKVDEC_CACHE_PERMIT_CACHEABLE_ACCESS + | RKVDEC_CACHE_PERMIT_READ_ALLOCATE; + if (!(debug & DEBUG_CACHE_32B)) + reg |= RKVDEC_CACHE_LINE_SIZE_64_BYTES; + + mpp_dev_write(mpp_dev, RKVDEC_REG_CACHE_ENABLE(0), reg); + mpp_dev_write(mpp_dev, RKVDEC_REG_CACHE_ENABLE(1), reg); + + mpp_dev_write_seq(mpp_dev, RKVDEC_REG_SYS_CTRL, + &task->reg[RKVDEC_REG_SYS_CTRL_INDEX], + mpp_dev->variant->reg_len + - RKVDEC_REG_SYS_CTRL_INDEX); + + /* Flush the register before the start the device */ + wmb(); + mpp_dev_write(mpp_dev, RKVDEC_REG_DEC_INT_EN, + task->reg[RKVDEC_REG_DEC_INT_EN_INDEX] + | RKVDEC_DEC_START); + break; + default: + break; + } + + mpp_debug_leave(); + + return 0; +} + +static int rockchip_mpp_rkvdec_finish(struct rockchip_mpp_dev *mpp_dev, + struct mpp_task *mpp_task) +{ + struct rockchip_rkvdec_dev *dec_dev = to_rkvdec_dev(mpp_dev); + struct rkvdec_task *task = to_rkvdec_task(mpp_task); + + mpp_debug_enter(); + + switch (dec_dev->state) { + case RKVDEC_STATE_NORMAL:{ + mpp_dev_read_seq(mpp_dev, RKVDEC_REG_SYS_CTRL, + &task->reg[RKVDEC_REG_SYS_CTRL_INDEX], + mpp_dev->variant->reg_len + - RKVDEC_REG_SYS_CTRL_INDEX); + task->reg[RKVDEC_REG_DEC_INT_EN_INDEX] = + task->irq_status; + } + break; + default: + break; + } + + mpp_debug_leave(); + + return 0; +} + +static int rockchip_mpp_rkvdec_result(struct rockchip_mpp_dev *mpp_dev, + struct mpp_task *mpp_task, + u32 __user * dst, u32 size) +{ + struct rkvdec_task *task = to_rkvdec_task(mpp_task); + u32 err_mask; + + err_mask = RKVDEC_INT_BUF_EMPTY + | RKVDEC_INT_BUS_ERROR + | RKVDEC_INT_COLMV_REF_ERROR + | RKVDEC_INT_STRM_ERROR + | RKVDEC_INT_TIMEOUT; + + if (task->irq_status & err_mask) + return VB2_BUF_STATE_ERROR; + + return VB2_BUF_STATE_DONE; +} + +static int rockchip_mpp_rkvdec_free_task(struct mpp_session *session, + struct mpp_task *mpp_task) +{ + struct rkvdec_task *task = to_rkvdec_task(mpp_task); + + mpp_dev_task_finalize(session, mpp_task); + kfree(task); + + return 0; +} + +static irqreturn_t mpp_rkvdec_isr(int irq, void *dev_id) +{ + struct rockchip_rkvdec_dev *dec_dev = dev_id; + struct rockchip_mpp_dev *mpp_dev = &dec_dev->mpp_dev; + struct rkvdec_task *task = NULL; + struct mpp_task *mpp_task = NULL; + u32 irq_status; + u32 err_mask; + + irq_status = mpp_dev_read(mpp_dev, RKVDEC_REG_DEC_INT_EN); + if (!(irq_status & RKVDEC_DEC_INT_RAW)) + return IRQ_NONE; + + mpp_dev_write(mpp_dev, RKVDEC_REG_DEC_INT_EN, RKVDEC_CLOCK_GATE_EN); + /* FIXME use a spin lock here */ + task = (struct rkvdec_task *)dec_dev->current_task; + if (!task) { + dev_err(dec_dev->mpp_dev.dev, "no current task\n"); + return IRQ_HANDLED; + } + mpp_debug_time_diff(&task->mpp_task); + mpp_task = &task->mpp_task; + + task->irq_status = irq_status; + switch (dec_dev->state) { + case RKVDEC_STATE_NORMAL: + mpp_debug(DEBUG_IRQ_STATUS, "irq_status: %08x\n", + task->irq_status); + + err_mask = RKVDEC_INT_BUF_EMPTY + | RKVDEC_INT_BUS_ERROR + | RKVDEC_INT_COLMV_REF_ERROR + | RKVDEC_INT_STRM_ERROR + | RKVDEC_INT_TIMEOUT; + + if (err_mask & task->irq_status) + atomic_set(&mpp_dev->reset_request, 1); + + mpp_dev_task_finish(mpp_task->session, mpp_task); + mpp_debug_leave(); + return IRQ_HANDLED; + default: + goto fail; + } +fail: + return IRQ_HANDLED; +} + +static int rockchip_mpp_rkvdec_assign_reset(struct rockchip_rkvdec_dev *dec_dev) +{ + struct rockchip_mpp_dev *mpp_dev = &dec_dev->mpp_dev; + + dec_dev->rst_a = devm_reset_control_get_shared(mpp_dev->dev, "video_a"); + dec_dev->rst_h = devm_reset_control_get_shared(mpp_dev->dev, "video_h"); + /* The reset controller below are not shared with VPU */ + dec_dev->rst_niu_a = devm_reset_control_get(mpp_dev->dev, "niu_a"); + dec_dev->rst_niu_h = devm_reset_control_get(mpp_dev->dev, "niu_h"); + dec_dev->rst_core = devm_reset_control_get(mpp_dev->dev, "video_core"); + dec_dev->rst_cabac = devm_reset_control_get(mpp_dev->dev, + "video_cabac"); + + if (IS_ERR_OR_NULL(dec_dev->rst_a)) { + mpp_err("No aclk reset resource define\n"); + dec_dev->rst_a = NULL; + } + + if (IS_ERR_OR_NULL(dec_dev->rst_h)) { + mpp_err("No hclk reset resource define\n"); + dec_dev->rst_h = NULL; + } + + if (IS_ERR_OR_NULL(dec_dev->rst_niu_a)) { + mpp_err("No axi niu reset resource define\n"); + dec_dev->rst_niu_a = NULL; + } + + if (IS_ERR_OR_NULL(dec_dev->rst_niu_h)) { + mpp_err("No ahb niu reset resource define\n"); + dec_dev->rst_niu_h = NULL; + } + + if (IS_ERR_OR_NULL(dec_dev->rst_core)) { + mpp_err("No core reset resource define\n"); + dec_dev->rst_core = NULL; + } + + if (IS_ERR_OR_NULL(dec_dev->rst_cabac)) { + mpp_err("No cabac reset resource define\n"); + dec_dev->rst_cabac = NULL; + } + + safe_unreset(dec_dev->rst_a); + safe_unreset(dec_dev->rst_h); + + return 0; +} + +static int rockchip_mpp_rkvdec_reset(struct rockchip_mpp_dev *mpp_dev) +{ + struct rockchip_rkvdec_dev *dec = to_rkvdec_dev(mpp_dev); + + if (dec->rst_a && dec->rst_h) { + mpp_debug(DEBUG_RESET, "reset in\n"); + rockchip_pmu_idle_request(mpp_dev->dev, true); + + safe_reset(dec->rst_niu_a); + safe_reset(dec->rst_niu_h); + safe_reset(dec->rst_a); + safe_reset(dec->rst_h); + safe_reset(dec->rst_core); + safe_reset(dec->rst_cabac); + udelay(5); + safe_unreset(dec->rst_niu_h); + safe_unreset(dec->rst_niu_a); + safe_unreset(dec->rst_a); + safe_unreset(dec->rst_h); + safe_unreset(dec->rst_core); + safe_unreset(dec->rst_cabac); + + rockchip_pmu_idle_request(mpp_dev->dev, false); + + mpp_dev_write(mpp_dev, RKVDEC_REG_DEC_INT_EN, 0); + dec->current_task = NULL; + mpp_debug(DEBUG_RESET, "reset out\n"); + } + + return 0; +} + +static int rockchip_mpp_rkvdec_sip_reset(struct rockchip_mpp_dev *mpp_dev) +{ +/* The reset flow in arm trustzone firmware */ +#if CONFIG_ROCKCHIP_SIP + sip_smc_vpu_reset(0, 0, 0); +#else + return rockchip_mpp_rkvdec_reset(mpp_dev); +#endif + return 0; +} + +#if 0 +static int rkvdec_rk3328_iommu_hdl(struct iommu_domain *iommu, + struct device *iommu_dev, unsigned long iova, + int status, void *arg) +{ + struct device *dev = (struct device *)arg; + struct platform_device *pdev = NULL; + struct rockchip_rkvdec_dev *dec_dev = NULL; + struct rockchip_mpp_dev *mpp_dev = NULL; + + int ret = -EIO; + + pdev = container_of(dev, struct platform_device, dev); + if (!pdev) { + dev_err(dev, "invalid platform_device\n"); + ret = -ENXIO; + goto done; + } + + dec_dev = platform_get_drvdata(pdev); + if (!dec_dev) { + dev_err(dev, "invalid device instance\n"); + ret = -ENXIO; + goto done; + } + mpp_dev = &dec_dev->mpp_dev; + + if (IOMMU_GET_BUS_ID(status) == 2) { + unsigned long page_iova = 0; + + /* avoid another page fault occur after page fault */ + if (dec_dev->aux_iova != 0) + iommu_unmap(mpp_dev->iommu_info->domain, + dec_dev->aux_iova, IOMMU_PAGE_SIZE); + + page_iova = round_down(iova, IOMMU_PAGE_SIZE); + ret = iommu_map(mpp_dev->iommu_info->domain, page_iova, + page_to_phys(dec_dev->aux_page), + IOMMU_PAGE_SIZE, DMA_FROM_DEVICE); + if (!ret) + dec_dev->aux_iova = page_iova; + } + +done: + return ret; +} +#endif + +static struct mpp_dev_ops rkvdec_ops = { + .alloc_task = rockchip_mpp_rkvdec_alloc_task, + .prepare = rockchip_mpp_rkvdec_prepare, + .run = rockchip_mpp_rkvdec_run, + .finish = rockchip_mpp_rkvdec_finish, + .result = rockchip_mpp_rkvdec_result, + .free_task = rockchip_mpp_rkvdec_free_task, + .reset = rockchip_mpp_rkvdec_reset, +}; + +#if 0 +static struct mpp_dev_ops rkvdec_rk3328_ops = { + .alloc_task = rockchip_mpp_rkvdec_alloc_task, + .prepare = rockchip_mpp_rkvdec_prepare, + .run = rockchip_mpp_rkvdec_run, + .finish = rockchip_mpp_rkvdec_finish, + .result = rockchip_mpp_rkvdec_result, + .free_task = rockchip_mpp_rkvdec_free_task, + .reset = rockchip_mpp_rkvdec_sip_reset, +}; +#endif + +static int rockchip_mpp_rkvdec_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct rockchip_rkvdec_dev *dec_dev = NULL; + struct rockchip_mpp_dev *mpp_dev = NULL; + int ret = 0; + + dec_dev = devm_kzalloc(dev, sizeof(struct rockchip_rkvdec_dev), + GFP_KERNEL); + if (!dec_dev) + return -ENOMEM; + + mpp_dev = &dec_dev->mpp_dev; + mpp_dev->variant = rockchip_rkvdec_get_drv_data(pdev); + +#if 0 + if (mpp_dev->variant->version_bit & RKVDEC_VER_RK3328_BIT) { + ret = mpp_dev_common_probe(mpp_dev, pdev, &rkvdec_rk3328_ops); + + dec_dev->aux_page = alloc_page(GFP_KERNEL); + if (!dec_dev->aux_page) { + dev_err(dev, + "can't allocate a page for auxiliary usage\n"); + return ret; + } + dec_dev->aux_iova = 0; + + iommu_set_fault_handler(mpp_dev->iommu_info->domain, + rkvdec_rk3328_iommu_hdl, dev); + } else { + ret = mpp_dev_common_probe(mpp_dev, pdev, &rkvdec_ops); + } +#else + ret = mpp_dev_common_probe(mpp_dev, pdev, &rkvdec_ops); +#endif + if (ret) + return ret; + + ret = devm_request_threaded_irq(dev, mpp_dev->irq, NULL, mpp_rkvdec_isr, + IRQF_SHARED | IRQF_ONESHOT, + dev_name(dev), dec_dev); + if (ret) { + dev_err(dev, "register interrupter runtime failed\n"); + return ret; + } + + rockchip_mpp_rkvdec_assign_reset(dec_dev); + dec_dev->state = RKVDEC_STATE_NORMAL; + + rkvdec_ioctl_ops = mpp_ioctl_ops_templ; + rkvdec_ioctl_ops.vidioc_s_fmt_vid_out_mplane = + rkvdec_s_fmt_vid_out_mplane; + rkvdec_ioctl_ops.vidioc_s_fmt_vid_cap_mplane = + rkvdec_s_fmt_vid_cap_mplane; + + ret = mpp_dev_register_node(mpp_dev, mpp_dev->variant->node_name, + &rkvdec_fops, &rkvdec_ioctl_ops); + if (ret) + dev_err(dev, "register v4l2/media device failed: %d\n", ret); + + memcpy(mpp_dev->fmt_out, fmt_out_templ, sizeof(fmt_out_templ)); + memcpy(mpp_dev->fmt_cap, fmt_cap_templ, sizeof(fmt_cap_templ)); + + dec_dev->cabac_avc_vaddr = + dmam_alloc_coherent(dev, ARRAY_SIZE(h264_cabac_table), + &dec_dev->cabac_avc_addr, GFP_KERNEL); + if (IS_ERR_OR_NULL(dec_dev->cabac_avc_vaddr)) + dev_err(dev, "failed to allocate H.264 CABAC buffer\n"); + else + memcpy(dec_dev->cabac_avc_vaddr, h264_cabac_table, + ARRAY_SIZE(h264_cabac_table)); + + dec_dev->cabac_hevc_vaddr = + dmam_alloc_coherent(dev, ARRAY_SIZE(hevc_cabac_table), + &dec_dev->cabac_hevc_addr, GFP_KERNEL); + if (IS_ERR_OR_NULL(dec_dev->cabac_hevc_vaddr)) + dev_err(dev, "failed to allocate H.265 CABAC buffer\n"); + else + memcpy(dec_dev->cabac_hevc_vaddr, hevc_cabac_table, + ARRAY_SIZE(hevc_cabac_table)); + + dec_dev->errorinfo_vaddr = + dmam_alloc_coherent(dev, RKVDEC_ERROR_INFO_MAX_SIZE, + &dec_dev->errorinfo_addr, GFP_KERNEL); + if (IS_ERR_OR_NULL(dec_dev->errorinfo_vaddr)) + dev_err(dev, "failed to allocate H.264 error info buffer\n"); + + dev_info(dev, "probing finish\n"); + + platform_set_drvdata(pdev, dec_dev); + + return 0; +} + +static int rockchip_mpp_rkvdec_remove(struct platform_device *pdev) +{ + struct rockchip_rkvdec_dev *dec_dev = platform_get_drvdata(pdev); + + mpp_dev_common_remove(&dec_dev->mpp_dev); + + return 0; +} + +static const struct of_device_id mpp_rkvdec_dt_match[] = { + {.compatible = "rockchip,video-decoder-v1p",.data = &rkvdec_v1p_data}, + {.compatible = "rockchip,video-decoder-v1",.data = &rkvdec_v1_data}, + {.compatible = "rockchip,hevc-decoder-v1",.data = &rk_hevcdec_data}, + {}, +}; + +static void *rockchip_rkvdec_get_drv_data(struct platform_device *pdev) +{ + struct mpp_dev_variant *driver_data = NULL; + + if (pdev->dev.of_node) { + const struct of_device_id *match; + + match = of_match_node(mpp_rkvdec_dt_match, pdev->dev.of_node); + if (match) + driver_data = (struct mpp_dev_variant *)match->data; + } + return driver_data; +} + +static struct platform_driver rockchip_rkvdec_driver = { + .probe = rockchip_mpp_rkvdec_probe, + .remove = rockchip_mpp_rkvdec_remove, + .driver = { + .name = RKVDEC_DRIVER_NAME, + .of_match_table = of_match_ptr(mpp_rkvdec_dt_match), + }, +}; + +static int __init mpp_dev_rkvdec_init(void) +{ + int ret = platform_driver_register(&rockchip_rkvdec_driver); + + if (ret) { + mpp_err("Platform device register failed (%d).\n", ret); + return ret; + } + + return ret; +} + +static void __exit mpp_dev_rkvdec_exit(void) +{ + platform_driver_unregister(&rockchip_rkvdec_driver); +} + +module_init(mpp_dev_rkvdec_init); +module_exit(mpp_dev_rkvdec_exit); + +MODULE_DEVICE_TABLE(of, mpp_rkvdec_dt_match); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/rockchip-mpp/mpp_dev_vdpu2.c b/drivers/staging/rockchip-mpp/mpp_dev_vdpu2.c new file mode 100644 index 000000000000..dbd9f334562e --- /dev/null +++ b/drivers/staging/rockchip-mpp/mpp_dev_vdpu2.c @@ -0,0 +1,601 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd + * Randy Li, + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "mpp_debug.h" +#include "mpp_dev_common.h" +#include "vdpu2/hal.h" + +#define RKVDPU2_DRIVER_NAME "mpp_vdpu2" +#define RKVDPU2_NODE_NAME "vpu-service" + +#define to_rkvdpu_task(ctx) \ + container_of(ctx, struct rkvdpu_task, mpp_task) +#define to_rkvdpu_dev(dev) \ + container_of(dev, struct rockchip_rkvdpu_dev, mpp_dev) + +static int debug; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "bit switch for vdpu2 debug information"); + +struct rockchip_rkvdpu_dev { + struct rockchip_mpp_dev mpp_dev; + + struct reset_control *rst_a; + struct reset_control *rst_h; + + void *current_task; +}; + +struct rkvdpu_task { + struct mpp_task mpp_task; + + u32 reg[ROCKCHIP_VDPU2_REG_NUM]; + u32 idx; + + u32 strm_base; + u32 irq_status; +}; + +static struct rockchip_mpp_control vdpu_controls[] = { + { + .codec = V4L2_PIX_FMT_MPEG2_SLICE, + .id = V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS, + .elem_size = sizeof(struct v4l2_ctrl_mpeg2_slice_params), + }, + { + .codec = V4L2_PIX_FMT_MPEG2_SLICE, + .id = V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION, + .elem_size = sizeof(struct v4l2_ctrl_mpeg2_quantization), + }, +}; + +static struct v4l2_pix_format_mplane fmt_out_templ[] = { + { + .pixelformat = V4L2_PIX_FMT_MPEG2_SLICE, + }, + {.pixelformat = 0}, +}; + +static struct v4l2_pix_format_mplane fmt_cap_templ[] = { + { + .pixelformat = V4L2_PIX_FMT_NV12M, + }, + {.pixelformat = 0}, +}; + +static const struct mpp_dev_variant rkvdpu_v2_data = { + /* Exclude the register of the Performance counter */ + .reg_len = 159, + .node_name = RKVDPU2_NODE_NAME, + .vfd_func = MEDIA_ENT_F_PROC_VIDEO_DECODER, +}; + +static struct v4l2_ioctl_ops rkvdpu_ioctl_ops = { 0, }; + +static void *rockchip_rkvdpu2_get_drv_data(struct platform_device *pdev); + +static int vdpu_setup_ctrls(struct mpp_session *session, u32 pixelformat) +{ + struct rockchip_mpp_dev *mpp_dev = session->mpp_dev; + struct v4l2_ctrl_handler *hdl = &session->ctrl_handler; + struct v4l2_ctrl *ctrl; + unsigned int num_ctrls = ARRAY_SIZE(vdpu_controls); + unsigned int i; + + v4l2_ctrl_handler_init(hdl, num_ctrls); + if (hdl->error) { + v4l2_err(&mpp_dev->v4l2_dev, + "Failed to initialize control handler\n"); + return hdl->error; + } + + for (i = 0; i < num_ctrls; i++) { + struct v4l2_ctrl_config cfg = { }; + + if (vdpu_controls[i].codec != pixelformat) + continue; + + cfg.id = vdpu_controls[i].id; + cfg.elem_size = vdpu_controls[i].elem_size; + + ctrl = v4l2_ctrl_new_custom(hdl, &cfg, NULL); + if (hdl->error) { + v4l2_err(&mpp_dev->v4l2_dev, + "Failed to create new custom %d control\n", + cfg.id); + goto fail; + } + } + + session->fh.ctrl_handler = hdl; + v4l2_ctrl_handler_setup(hdl); + + return 0; +fail: + v4l2_ctrl_handler_free(hdl); + return hdl->error; +} + +static int rkvdpu_s_fmt_vid_out_mplane(struct file *filp, void *priv, + struct v4l2_format *f) +{ + struct mpp_session *session = container_of(filp->private_data, + struct mpp_session, fh); + struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; + struct vb2_queue *vq; + int sizes = 0; + int i; + + /* TODO: We can change width and height at streaming on */ + vq = v4l2_m2m_get_vq(session->fh.m2m_ctx, f->type); + if (vb2_is_streaming(vq)) + return -EBUSY; + +#if 0 + ret = rkvdpu_try_fmt_out(filp, priv, f); + if (ret) + return ret; +#endif + if (!pix_mp->num_planes) + pix_mp->num_planes = 1; + + for (i = 0; i < pix_mp->num_planes; i++) { + sizes += pix_mp->plane_fmt[i].sizeimage; + } + /* strm_len is 24 bits */ + if (sizes >= SZ_16M) + return -EINVAL; + + if (vdpu_setup_ctrls(session, pix_mp->pixelformat)) + return -EINVAL; + + session->fmt_out = *pix_mp; + + /* Copy the pixel format information from OUTPUT to CAPUTRE */ + session->fmt_cap.pixelformat = V4L2_PIX_FMT_NV12M; + session->fmt_cap.width = pix_mp->width; + session->fmt_cap.height = pix_mp->height; + session->fmt_cap.colorspace = pix_mp->colorspace; + session->fmt_cap.ycbcr_enc = pix_mp->ycbcr_enc; + session->fmt_cap.xfer_func = pix_mp->xfer_func; + session->fmt_cap.quantization = pix_mp->quantization; + + return 0; +} + +static int rkvdpu_s_fmt_vid_cap_mplane(struct file *filp, void *priv, + struct v4l2_format *f) +{ + struct mpp_session *session = container_of(filp->private_data, + struct mpp_session, fh); + struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; + struct vb2_queue *vq; + + vq = v4l2_m2m_get_vq(session->fh.m2m_ctx, f->type); + if (vb2_is_streaming(vq)) + return -EBUSY; + +#if 0 + ret = rkvdpu_try_fmt_cap(filp, priv, f); + if (ret) + return ret; +#endif + switch (pix_mp->pixelformat) { + case V4L2_PIX_FMT_NV12M: + pix_mp->plane_fmt[0].bytesperline = ALIGN(pix_mp->width, 16); + pix_mp->plane_fmt[1].bytesperline = ALIGN(pix_mp->width, 16); + pix_mp->plane_fmt[0].sizeimage = ALIGN(pix_mp->width, 16) * + /* + * FIXME: the plane 1 may map to a lower address than plane 0 + * before solve this allocator problem, it can pass the test + */ + ALIGN(pix_mp->height, 16) * 2; + /* Additional space for motion vector */ + pix_mp->plane_fmt[1].sizeimage = ALIGN(pix_mp->width, 16) * + ALIGN(pix_mp->height, 16); + pix_mp->num_planes = 2; + break; + default: + return -EINVAL; + } + + session->fmt_cap = *pix_mp; + + return 0; +} + +static int rkvdpu_open(struct file *filp) +{ + struct rockchip_mpp_dev *mpp_dev = video_drvdata(filp); + struct video_device *vdev = video_devdata(filp); + struct mpp_session *session = NULL; + + mpp_debug_enter(); + + session = rockchip_mpp_alloc_session(mpp_dev, vdev); + if (IS_ERR_OR_NULL(session)) + return PTR_ERR(session); + + filp->private_data = &session->fh; + pm_runtime_get_sync(mpp_dev->dev); + + mpp_debug_leave(); + return 0; +} + +static void *rockchip_mpp_rkvdpu_alloc_task(struct mpp_session *session, + void __user * src, u32 size) +{ + struct rkvdpu_task *task = NULL; + struct vb2_v4l2_buffer *src_buf; + u32 fmt = 0; + int err = -EFAULT; + + mpp_debug_enter(); + + task = kzalloc(sizeof(*task), GFP_KERNEL); + if (!task) + return NULL; + + mpp_dev_task_init(session, &task->mpp_task); + + src_buf = v4l2_m2m_next_src_buf(session->fh.m2m_ctx); + v4l2_ctrl_request_setup(src_buf->vb2_buf.req_obj.req, + &session->ctrl_handler); + + fmt = session->fmt_out.pixelformat; + switch (fmt) { + case V4L2_PIX_FMT_MPEG2_SLICE: + err = rkvdpu_mpeg2_gen_reg(session, task->reg, src_buf); + break; + default: + goto fail; + } + + if (err) + goto fail; + + v4l2_ctrl_request_complete(src_buf->vb2_buf.req_obj.req, + &session->ctrl_handler); + + mpp_debug_leave(); + + return &task->mpp_task; + +fail: + if (unlikely(debug & DEBUG_DUMP_ERR_REG)) + mpp_debug_dump_reg_mem(task->reg, ROCKCHIP_VDPU2_REG_NUM); + + kfree(task); + return ERR_PTR(err); +} + +static int rockchip_mpp_rkvdpu_prepare(struct rockchip_mpp_dev *mpp_dev, + struct mpp_task *mpp_task) +{ + struct rkvdpu_task *task = container_of(mpp_task, struct rkvdpu_task, + mpp_task); + + return rkvdpu_mpeg2_prepare_buf(mpp_task->session, task->reg); +} + +static int rockchip_mpp_rkvdpu_run(struct rockchip_mpp_dev *mpp_dev, + struct mpp_task *mpp_task) +{ + struct rkvdpu_task *task = NULL; + struct rockchip_rkvdpu_dev *dec_dev = NULL; + + mpp_debug_enter(); + + task = to_rkvdpu_task(mpp_task); + dec_dev = to_rkvdpu_dev(mpp_dev); + + /* FIXME: spin lock here */ + dec_dev->current_task = task; + /* NOTE: Only write the decoder part */ + mpp_dev_write_seq(mpp_dev, RKVDPU2_REG_DEC_CTRL, + &task->reg[RKVDPU2_REG_DEC_CTRL_INDEX], + RKVDPU2_REG_DEC_DEV_CTRL_INDEX + - RKVDPU2_REG_DEC_CTRL_INDEX); + + mpp_dev_write_seq(mpp_dev, RKVDPU2_REG59, + &task->reg[RKVDPU2_REG59_INDEX], + mpp_dev->variant->reg_len - RKVDPU2_REG59_INDEX); + /* Flush the registers */ + wmb(); + mpp_dev_write(mpp_dev, RKVDPU2_REG_DEC_DEV_CTRL, + task->reg[RKVDPU2_REG_DEC_DEV_CTRL_INDEX] + | RKVDPU2_DEC_START); + + mpp_debug_leave(); + + return 0; +} + +static int rockchip_mpp_rkvdpu_finish(struct rockchip_mpp_dev *mpp_dev, + struct mpp_task *mpp_task) +{ + struct rkvdpu_task *task = to_rkvdpu_task(mpp_task); + + mpp_debug_enter(); + + /* NOTE: Only read the decoder part */ + mpp_dev_read_seq(mpp_dev, RKVDPU2_REG_DEC_CTRL, + &task->reg[RKVDPU2_REG_DEC_CTRL_INDEX], + mpp_dev->variant->reg_len + - RKVDPU2_REG_DEC_CTRL_INDEX); + + task->reg[RKVDPU2_REG_DEC_INT_EN_INDEX] = task->irq_status; + + mpp_debug_leave(); + + return 0; +} + +static int rockchip_mpp_rkvdpu_result(struct rockchip_mpp_dev *mpp_dev, + struct mpp_task *mpp_task, + u32 __user * dst, u32 size) +{ + struct rkvdpu_task *task = to_rkvdpu_task(mpp_task); + u32 err_mask; + + err_mask = RKVDPU2_INT_TIMEOUT + | RKVDPU2_INT_STRM_ERROR + | RKVDPU2_INT_ASO_ERROR + | RKVDPU2_INT_BUF_EMPTY + | RKVDPU2_INT_BUS_ERROR; + + if (err_mask & task->irq_status) + return VB2_BUF_STATE_ERROR; + + return VB2_BUF_STATE_DONE; +} + +static int rockchip_mpp_rkvdpu_free_task(struct mpp_session *session, + struct mpp_task *mpp_task) +{ + struct rkvdpu_task *task = to_rkvdpu_task(mpp_task); + + mpp_dev_task_finalize(session, mpp_task); + kfree(task); + + return 0; +} + +static irqreturn_t mpp_rkvdpu_isr(int irq, void *dev_id) +{ + struct rockchip_rkvdpu_dev *dec_dev = dev_id; + struct rockchip_mpp_dev *mpp_dev = &dec_dev->mpp_dev; + struct rkvdpu_task *task = NULL; + struct mpp_task *mpp_task = NULL; + u32 irq_status; + u32 err_mask; + + irq_status = mpp_dev_read(mpp_dev, RKVDPU2_REG_DEC_INT_EN); + if (!(irq_status & RKVDPU2_DEC_INT_RAW)) + return IRQ_NONE; + + mpp_dev_write(mpp_dev, RKVDPU2_REG_DEC_INT_EN, 0); + mpp_dev_write(mpp_dev, RKVDPU2_REG_DEC_DEV_CTRL, + RKVDPU2_DEC_CLOCK_GATE_EN); + + /* FIXME use a spin lock here */ + task = (struct rkvdpu_task *)dec_dev->current_task; + if (!task) { + dev_err(dec_dev->mpp_dev.dev, "no current task\n"); + return IRQ_HANDLED; + } + + mpp_task = &task->mpp_task; + mpp_debug_time_diff(mpp_task); + task->irq_status = irq_status; + mpp_debug(DEBUG_IRQ_STATUS, "irq_status: %08x\n", task->irq_status); + + err_mask = RKVDPU2_INT_TIMEOUT + | RKVDPU2_INT_STRM_ERROR + | RKVDPU2_INT_ASO_ERROR + | RKVDPU2_INT_BUF_EMPTY + | RKVDPU2_INT_BUS_ERROR; + + if (err_mask & task->irq_status) + atomic_set(&mpp_dev->reset_request, 1); + + mpp_dev_task_finish(mpp_task->session, mpp_task); + + mpp_debug_leave(); + return IRQ_HANDLED; +} + +static int rockchip_mpp_rkvdpu_assign_reset(struct rockchip_rkvdpu_dev *dec_dev) +{ + struct rockchip_mpp_dev *mpp_dev = &dec_dev->mpp_dev; + + dec_dev->rst_a = devm_reset_control_get_shared(mpp_dev->dev, "video_a"); + dec_dev->rst_h = devm_reset_control_get_shared(mpp_dev->dev, "video_h"); + + if (IS_ERR_OR_NULL(dec_dev->rst_a)) { + mpp_err("No aclk reset resource define\n"); + dec_dev->rst_a = NULL; + } + + if (IS_ERR_OR_NULL(dec_dev->rst_h)) { + mpp_err("No hclk reset resource define\n"); + dec_dev->rst_h = NULL; + } + + safe_unreset(dec_dev->rst_h); + safe_unreset(dec_dev->rst_a); + + + return 0; +} + +static int rockchip_mpp_rkvdpu_reset(struct rockchip_mpp_dev *mpp_dev) +{ + struct rockchip_rkvdpu_dev *dec = to_rkvdpu_dev(mpp_dev); + + if (dec->rst_a && dec->rst_h) { + mpp_debug(DEBUG_RESET, "reset in\n"); + + safe_reset(dec->rst_a); + safe_reset(dec->rst_h); + udelay(5); + safe_unreset(dec->rst_h); + safe_unreset(dec->rst_a); + + mpp_dev_write(mpp_dev, RKVDPU2_REG_DEC_DEV_CTRL, 0); + mpp_dev_write(mpp_dev, RKVDPU2_REG_DEC_INT_EN, 0); + dec->current_task = NULL; + mpp_debug(DEBUG_RESET, "reset out\n"); + } + + return 0; +} + +static struct mpp_dev_ops rkvdpu_ops = { + .alloc_task = rockchip_mpp_rkvdpu_alloc_task, + .prepare = rockchip_mpp_rkvdpu_prepare, + .run = rockchip_mpp_rkvdpu_run, + .finish = rockchip_mpp_rkvdpu_finish, + .result = rockchip_mpp_rkvdpu_result, + .free_task = rockchip_mpp_rkvdpu_free_task, + .reset = rockchip_mpp_rkvdpu_reset, +}; + +static int rockchip_mpp_rkvdpu_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct rockchip_rkvdpu_dev *dec_dev = NULL; + struct rockchip_mpp_dev *mpp_dev = NULL; + int ret = 0; + + dec_dev = devm_kzalloc(dev, sizeof(struct rockchip_rkvdpu_dev), + GFP_KERNEL); + if (!dec_dev) + return -ENOMEM; + + mpp_dev = &dec_dev->mpp_dev; + mpp_dev->variant = rockchip_rkvdpu2_get_drv_data(pdev); + ret = mpp_dev_common_probe(mpp_dev, pdev, &rkvdpu_ops); + if (ret) + return ret; + + ret = devm_request_threaded_irq(dev, mpp_dev->irq, NULL, mpp_rkvdpu_isr, + IRQF_SHARED | IRQF_ONESHOT, + dev_name(dev), dec_dev); + if (ret) { + dev_err(dev, "register interrupter runtime failed\n"); + return ret; + } + + rockchip_mpp_rkvdpu_assign_reset(dec_dev); + + rkvdpu_ioctl_ops = mpp_ioctl_ops_templ; + rkvdpu_ioctl_ops.vidioc_s_fmt_vid_out_mplane = + rkvdpu_s_fmt_vid_out_mplane; + rkvdpu_ioctl_ops.vidioc_s_fmt_vid_cap_mplane = + rkvdpu_s_fmt_vid_cap_mplane; + + ret = mpp_dev_register_node(mpp_dev, mpp_dev->variant->node_name, + NULL, &rkvdpu_ioctl_ops); + if (ret) + dev_err(dev, "register char device failed: %d\n", ret); + + memcpy(mpp_dev->fmt_out, fmt_out_templ, sizeof(fmt_out_templ)); + memcpy(mpp_dev->fmt_cap, fmt_cap_templ, sizeof(fmt_cap_templ)); + dev_info(dev, "probing finish\n"); + + platform_set_drvdata(pdev, dec_dev); + + return 0; +} + +static int rockchip_mpp_rkvdpu_remove(struct platform_device *pdev) +{ + struct rockchip_rkvdpu_dev *dec_dev = platform_get_drvdata(pdev); + + mpp_dev_common_remove(&dec_dev->mpp_dev); + + return 0; +} + +static const struct of_device_id mpp_rkvdpu2_dt_match[] = { + {.compatible = "rockchip,vpu-decoder-v2",.data = &rkvdpu_v2_data}, + {}, +}; + +static void *rockchip_rkvdpu2_get_drv_data(struct platform_device *pdev) +{ + struct mpp_dev_variant *driver_data = NULL; + + if (pdev->dev.of_node) { + const struct of_device_id *match; + + match = of_match_node(mpp_rkvdpu2_dt_match, pdev->dev.of_node); + if (match) + driver_data = (struct mpp_dev_variant *)match->data; + } + return driver_data; +} + +static struct platform_driver rockchip_rkvdpu2_driver = { + .probe = rockchip_mpp_rkvdpu_probe, + .remove = rockchip_mpp_rkvdpu_remove, + .driver = { + .name = RKVDPU2_DRIVER_NAME, + .of_match_table = of_match_ptr(mpp_rkvdpu2_dt_match), + }, +}; + +static int __init mpp_dev_rkvdpu2_init(void) +{ + int ret = platform_driver_register(&rockchip_rkvdpu2_driver); + + if (ret) { + mpp_err("Platform device register failed (%d).\n", ret); + return ret; + } + + return ret; +} + +static void __exit mpp_dev_rkvdpu2_exit(void) +{ + platform_driver_unregister(&rockchip_rkvdpu2_driver); +} + +module_init(mpp_dev_rkvdpu2_init); +module_exit(mpp_dev_rkvdpu2_exit); + +MODULE_DEVICE_TABLE(of, mpp_rkvdpu2_dt_match); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/rockchip-mpp/mpp_service.c b/drivers/staging/rockchip-mpp/mpp_service.c new file mode 100644 index 000000000000..1e45ce141fc4 --- /dev/null +++ b/drivers/staging/rockchip-mpp/mpp_service.c @@ -0,0 +1,197 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2016 - 2017 Fuzhou Rockchip Electronics Co., Ltd + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include + +#include "mpp_dev_common.h" +#include "mpp_service.h" + +struct mpp_service { + /* service critical time lock */ + struct completion running; + struct mpp_task *cur_task; + + u32 dev_cnt; + struct list_head subdev_list; +}; + +struct mpp_service_node { + /* node structure global lock */ + struct mutex lock; + struct mpp_service *parent; + struct list_head pending; +}; + +/* service queue schedule */ +void mpp_srv_push_pending(struct mpp_service_node *node, struct mpp_task *task) +{ + mutex_lock(&node->lock); + list_add_tail(&task->service_link, &node->pending); + mutex_unlock(&node->lock); +} +EXPORT_SYMBOL(mpp_srv_push_pending); + +struct mpp_task *mpp_srv_get_pending_task(struct mpp_service_node *node) +{ + struct mpp_task *task = NULL; + + mutex_lock(&node->lock); + if (!list_empty(&node->pending)) { + task = list_first_entry(&node->pending, struct mpp_task, + service_link); + list_del_init(&task->service_link); + } + mutex_unlock(&node->lock); + + return task; +} +EXPORT_SYMBOL(mpp_srv_get_pending_task); + +int mpp_srv_is_running(struct mpp_service_node *node) +{ + struct mpp_service *pservice = node->parent; + + return !try_wait_for_completion(&pservice->running); +} +EXPORT_SYMBOL(mpp_srv_is_running); + +void mpp_srv_wait_to_run(struct mpp_service_node *node, struct mpp_task *task) +{ + struct mpp_service *pservice = node->parent; + + wait_for_completion(&pservice->running); + pservice->cur_task = task; +} +EXPORT_SYMBOL(mpp_srv_wait_to_run); + +struct mpp_task *mpp_srv_get_cur_task(struct mpp_service_node *node) +{ + struct mpp_service *pservice = node->parent; + + return pservice->cur_task; +} +EXPORT_SYMBOL(mpp_srv_get_cur_task); + +void mpp_srv_done(struct mpp_service_node *node, struct mpp_task *task) +{ + struct mpp_service *pservice = node->parent; + + pservice->cur_task = NULL; + complete(&pservice->running); +} +EXPORT_SYMBOL(mpp_srv_done); + +int mpp_srv_abort(struct mpp_service_node *node, struct mpp_task *task) +{ + struct mpp_service *pservice = node->parent; + + if (task) { + if (pservice->cur_task == task) + pservice->cur_task = NULL; + } + complete(&pservice->running); + + return 0; +} +EXPORT_SYMBOL(mpp_srv_abort); + +void *mpp_srv_attach(struct mpp_service *pservice, void *data) +{ + struct mpp_service_node *node = NULL; + + node = kzalloc(sizeof(*node), GFP_KERNEL); + if (!node) + return node; + + node->parent = pservice; + mutex_init(&node->lock); + INIT_LIST_HEAD(&node->pending); + + return node; +} +EXPORT_SYMBOL(mpp_srv_attach); + +void mpp_srv_detach(struct mpp_service_node *node) +{ + kfree(node); +} +EXPORT_SYMBOL(mpp_srv_detach); + +static void mpp_init_drvdata(struct mpp_service *pservice) +{ + init_completion(&pservice->running); + complete(&pservice->running); +} + +static int mpp_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct mpp_service *pservice = devm_kzalloc(dev, sizeof(*pservice), + GFP_KERNEL); + if (!pservice) + return -ENOMEM; + + mpp_init_drvdata(pservice); + + platform_set_drvdata(pdev, pservice); + dev_info(dev, "init success\n"); + + return 0; +} + +static int mpp_remove(struct platform_device *pdev) +{ + return 0; +} + +static const struct of_device_id mpp_service_dt_ids[] = { + { .compatible = "rockchip,mpp-service", }, + { }, +}; + +static struct platform_driver mpp_driver = { + .probe = mpp_probe, + .remove = mpp_remove, + .driver = { + .name = "mpp", + .of_match_table = of_match_ptr(mpp_service_dt_ids), + }, +}; + +static int __init mpp_service_init(void) +{ + int ret = platform_driver_register(&mpp_driver); + + if (ret) { + pr_err("Platform device register failed (%d).\n", ret); + return ret; + } + + return ret; +} + +static void __exit mpp_service_exit(void) +{ +} + +module_init(mpp_service_init); +module_exit(mpp_service_exit) +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/rockchip-mpp/mpp_service.h b/drivers/staging/rockchip-mpp/mpp_service.h new file mode 100644 index 000000000000..a77cff7b02df --- /dev/null +++ b/drivers/staging/rockchip-mpp/mpp_service.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2016 - 2017 Fuzhou Rockchip Electronics Co., Ltd + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _ROCKCHIP_MPP_SERVICE_H_ +#define _ROCKCHIP_MPP_SERVICE_H_ + +struct mpp_service_node; +struct mpp_service; + +struct mpp_task; + +void mpp_srv_push_pending(struct mpp_service_node *node, struct mpp_task *task); +struct mpp_task *mpp_srv_get_pending_task(struct mpp_service_node *node); + +void mpp_srv_run(struct mpp_service_node *node, struct mpp_task *task); +void mpp_srv_done(struct mpp_service_node *node, struct mpp_task *task); +int mpp_srv_abort(struct mpp_service_node *node, struct mpp_task *task); + +void mpp_srv_wait_to_run(struct mpp_service_node *node, struct mpp_task *task); +struct mpp_task *mpp_srv_get_cur_task(struct mpp_service_node *node); + +int mpp_srv_is_running(struct mpp_service_node *node); + +void *mpp_srv_attach(struct mpp_service *pservice, void *data); +void mpp_srv_detach(struct mpp_service_node *node); +#endif diff --git a/drivers/staging/rockchip-mpp/rkvdec/avc.c b/drivers/staging/rockchip-mpp/rkvdec/avc.c new file mode 100644 index 000000000000..3d91a119e533 --- /dev/null +++ b/drivers/staging/rockchip-mpp/rkvdec/avc.c @@ -0,0 +1,202 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2019 Randy Li, + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include + +#include +#include +#include +#include +#include + +#include "mpp_dev_common.h" +#include "hal.h" +#include "regs.h" + +static void init_hw_cfg(struct rkvdec_regs *p_regs) +{ + p_regs->sw_interrupt.dec_e = 1; + p_regs->sw_interrupt.dec_timeout_e = 1; + p_regs->sw_interrupt.timeout_mode = 1; + + /* AVC */ + p_regs->sw_sysctrl.dec_mode = RKVDEC_FMT_H264D; + p_regs->sw_sysctrl.rlc_mode = 0; + + p_regs->sw_picparameter.slice_num_lowbits = 0; + p_regs->sw_picparameter.slice_num_highbit = 0; +} + +/* FIXME: TODO: support field coding */ +static void stride_calc(struct rkvdec_regs *p_regs, + const struct v4l2_ctrl_h264_sps *sps) +{ + u32 stride_y, stride_uv, virstride_y, virstride_yuv; + u32 width, height; + + width = (sps->pic_width_in_mbs_minus1 + 1) << 4; + /* TODO: frame_mbs_only_flag (7-18) */ + height = (sps->pic_height_in_map_units_minus1 + 1) << 4; + + stride_y = (width * (sps->bit_depth_luma_minus8 + 8)) >> 3; + stride_uv = (width * (sps->bit_depth_chroma_minus8 + 8)) >> 3; + /* TODO: align with 16 bytes while the resolution is under HD */ + stride_y = ALIGN(stride_y, 16); + stride_uv = ALIGN(stride_uv, 16); + + virstride_y = stride_y * ALIGN(height, 16); + + switch (sps->chroma_format_idc) { + default: + case 0: + virstride_yuv = virstride_y; + break; + case 1: + virstride_yuv = virstride_y * 3 / 2; + break; + case 2: + virstride_yuv = virstride_y * 2; + break; + } + + p_regs->sw_picparameter.y_hor_virstride = stride_y >> 4; + p_regs->sw_picparameter.uv_hor_virstride = stride_uv >> 4; + p_regs->sw_y_virstride = virstride_y >> 4; + p_regs->sw_yuv_virstride = virstride_yuv >> 4; +} + +static int rkvdec_avc_gen_ref(struct rkvdec_regs *p_regs, + struct vb2_v4l2_buffer *dst_buf, + const struct v4l2_ctrl_h264_decode_param + *decode_param) +{ + struct vb2_queue *cap_q = dst_buf->vb2_buf.vb2_queue; + dma_addr_t cur_addr; + u16 i = 0; + + cur_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0); + p_regs->sw_decout_base = cur_addr; + + p_regs->sw_cur_poc = decode_param->top_field_order_cnt; + p_regs->sw_cur_poc_b = decode_param->bottom_field_order_cnt; + + /* 8.2.1 Decoding process for picture order count */ + for (i = 0; i < 7; i++) { + /* TopFieldOrderCnt */ + p_regs->sw_refer_poc[i * 2] = + decode_param->dpb[i].top_field_order_cnt; + p_regs->sw_refer_poc[i * 2 + 1] = + decode_param->dpb[i].bottom_field_order_cnt; + } + p_regs->sw_refer_poc[14] = decode_param->dpb[7].top_field_order_cnt; + p_regs->sw_refer15_29_poc[0] = + decode_param->dpb[7].bottom_field_order_cnt; + + for (i = 8; i < 15; i++) { + u16 j = i - 8; + + p_regs->sw_refer15_29_poc[j * 2 + 1] = + decode_param->dpb[i].top_field_order_cnt; + p_regs->sw_refer15_29_poc[(j + 1) * 2] = + decode_param->dpb[i].bottom_field_order_cnt; + } + + p_regs->sw72_h264_refer30_poc = + decode_param->dpb[15].top_field_order_cnt; + p_regs->sw73_h264_refer31_poc = + decode_param->dpb[15].bottom_field_order_cnt; + + for (i = 0; i < 16; i++) { + dma_addr_t ref_addr; + + ref_addr = rockchip_mpp_find_addr(cap_q, &dst_buf->vb2_buf, + decode_param->dpb[i]. + timestamp); + if (!ref_addr) + ref_addr = cur_addr; + + /* TODO: support filed codec */ + if (15 == i) { + p_regs->sw48_h264.ref_base = ref_addr >> 4; + p_regs->sw48_h264.ref_topfield_used = 1; + p_regs->sw48_h264.ref_botfield_used = 1; + p_regs->sw48_h264.ref_colmv_use_flag = 1; + break; + } + + p_regs->sw_refer_base[i].ref_base = ref_addr >> 4; + p_regs->sw_refer_base[i].ref_topfield_used = 1; + p_regs->sw_refer_base[i].ref_botfield_used = 1; + p_regs->sw_refer_base[i].ref_colmv_use_flag = 1; + + cur_addr = ref_addr; + } + + return 0; +} + +int rkvdec_avc_gen_reg(struct mpp_session *session, void *regs, + struct vb2_v4l2_buffer *src_buf) +{ + const struct v4l2_ctrl_h264_sps *sps; + const struct v4l2_ctrl_h264_pps *pps; + const struct v4l2_ctrl_h264_slice_param *slice_param; + const struct v4l2_ctrl_h264_decode_param *decode_param; + struct vb2_v4l2_buffer *dst_buf; + struct rkvdec_regs *p_regs = regs; + size_t stream_len = 0; + + sps = rockchip_mpp_get_cur_ctrl(session, V4L2_CID_MPEG_VIDEO_H264_SPS); + pps = rockchip_mpp_get_cur_ctrl(session, V4L2_CID_MPEG_VIDEO_H264_PPS); + slice_param = rockchip_mpp_get_cur_ctrl(session, + V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS); + decode_param = rockchip_mpp_get_cur_ctrl(session, + V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS); + + if (!sps || !pps || !slice_param || !decode_param) + return -EINVAL; + + init_hw_cfg(p_regs); + + stride_calc(p_regs, sps); + + p_regs->sw_strm_rlc_base = + vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0); + /* The bitstream must be 128bit align ? */ + p_regs->sw_sysctrl.strm_start_bit = slice_param->header_bit_size; + + /* hardware wants a zerod memory at the stream end */ + stream_len = slice_param->size + 64; + p_regs->sw_stream_len = stream_len; + + dst_buf = v4l2_m2m_next_dst_buf(session->fh.m2m_ctx); + rkvdec_avc_gen_ref(p_regs, dst_buf, decode_param); + + return 0; +} + +void rkvdec_avc_assign_errorinfo(void *regs, dma_addr_t addr) +{ + struct rkvdec_regs *p_regs = regs; + + p_regs->sw75_errorinfo_base = addr; +} + +void rkvdec_assign_cabac(void *regs, dma_addr_t addr) +{ + struct rkvdec_regs *p_regs = regs; + + p_regs->sw_cabactbl_base = addr; +} diff --git a/drivers/staging/rockchip-mpp/rkvdec/cabac.h b/drivers/staging/rockchip-mpp/rkvdec/cabac.h new file mode 100644 index 000000000000..d258e75150bd --- /dev/null +++ b/drivers/staging/rockchip-mpp/rkvdec/cabac.h @@ -0,0 +1,3614 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _CABAC_H +#define _CABAC_H + +/* Constant CABAC table. */ +static const u32 h264_cabac_table[] = { + 0x3602f114, 0xf1144a03, 0x4a033602, 0x68e97fe4, 0x36ff35fa, 0x21173307, + 0x00150217, 0x31000901, 0x390576db, 0x41f54ef3, 0x310c3e01, 0x321149fc, + 0x2b094012, 0x431a001d, 0x68095a10, 0x68ec7fd2, 0x4ef34301, 0x3e0141f5, + 0x5fef56fa, 0x2d093dfa, 0x51fa45fd, 0x370660f5, 0x56fb4307, 0x3a005802, + 0x5ef64cfd, 0x45043605, 0x580051fd, 0x4afb43f9, 0x50fb4afc, 0x3a0148f9, + 0x3f002900, 0x3f003f00, 0x560453f7, 0x48f96100, 0x3e03290d, 0x4efc2d00, + 0x7ee560fd, 0x65e762e4, 0x52e443e9, 0x53f05eec, 0x5beb6eea, 0x5df366ee, + 0x5cf97fe3, 0x60f959fb, 0x2efd6cf3, 0x39ff41ff, 0x4afd5df7, 0x57f85cf7, + 0x36057ee9, 0x3b063c06, 0x30ff4506, 0x45fc4400, 0x55fe58f8, 0x4bff4efa, + 0x36024df9, 0x44fd3205, 0x2a063201, 0x3f0151fc, 0x430046fc, 0x4cfe3902, + 0x4004230b, 0x230b3d01, 0x180c1912, 0x240d1d0d, 0x49f95df6, 0x2e0d49fe, + 0x64f93109, 0x35023509, 0x3dfe3505, 0x38003800, 0x3cfb3ff3, 0x39043eff, + 0x390445fa, 0x3304270e, 0x4003440d, 0x3f093d01, 0x27103207, 0x34042c05, + 0x3cfb300b, 0x3b003bff, 0x2c052116, 0x4eff2b0e, 0x45093c00, 0x28021c0b, + 0x31002c03, 0x2c022e00, 0x2f003302, 0x3e022704, 0x36002e06, 0x3a023603, + 0x33063f04, 0x35073906, 0x37063406, 0x240e2d0b, 0x52ff3508, 0x4efd3707, + 0x1f162e0f, 0x071954ff, 0x031cf91e, 0x0020041c, 0x061eff22, 0x0920061e, + 0x1b1a131f, 0x14251e1a, 0x4611221c, 0x3b054301, 0x1e104309, 0x23122012, + 0x1f181d16, 0x2b122617, 0x3f0b2914, 0x40093b09, 0x59fe5eff, 0x4cfa6cf7, + 0x2d002cfe, 0x40fd3400, 0x46fc3bfe, 0x52f84bfc, 0x4df766ef, 0x2a001803, + 0x37003000, 0x47f93bfa, 0x57f553f4, 0x3a0177e2, 0x24ff1dfd, 0x2b022601, + 0x3a0037fa, 0x4afd4000, 0x46005af6, 0x1f051dfc, 0x3b012a07, 0x48fd3afe, + 0x61f551fd, 0x05083a00, 0x120e0e0a, 0x28021b0d, 0x46fd3a00, 0x55f84ffa, + 0x6af30000, 0x57f66af0, 0x6eee72eb, 0x6eea62f2, 0x67ee6aeb, 0x6ce96beb, + 0x60f670e6, 0x5bfb5ff4, 0x5eea5df7, 0x430956fb, 0x55f650fc, 0x3c0746ff, + 0x3d053a09, 0x320f320c, 0x36113112, 0x2e07290a, 0x310733ff, 0x29093408, + 0x37022f06, 0x2c0a290d, 0x35053206, 0x3f04310d, 0x45fe4006, 0x46063bfe, + 0x1f092c0a, 0x35032b0c, 0x260a220e, 0x280d34fd, 0x2c072011, 0x320d2607, + 0x2b1a390a, 0x0e0b0b0e, 0x0b120b09, 0xfe170915, 0xf120f120, 0xe927eb22, + 0xe129df2a, 0xf426e42e, 0xe82d1d15, 0xe630d335, 0xed2bd541, 0x091ef627, + 0x1b141a12, 0x52f23900, 0x61ed4bfb, 0x001b7ddd, 0xfc1f001c, 0x0822061b, + 0x16180a1e, 0x20161321, 0x29151f1a, 0x2f172c1a, 0x470e4110, 0x3f063c08, + 0x18154111, 0x171a1417, 0x171c201b, 0x2817181c, 0x1d1c2018, 0x39132a17, + 0x3d163516, 0x280c560b, 0x3b0e330b, 0x47f94ffc, 0x46f745fb, 0x44f642f8, + 0x45f449ed, 0x43f146f0, 0x46ed3eec, 0x41ea42f0, 0xfe093fec, 0xf721f71a, + 0xfe29f927, 0x0931032d, 0x3b241b2d, 0x23f942fa, 0x2df82af9, 0x38f430fb, + 0x3efb3cfa, 0x4cf842f8, 0x51fa55fb, 0x51f94df6, 0x49ee50ef, 0x53f64afc, + 0x43f747f7, 0x42f83dff, 0x3b0042f2, 0xf3153b02, 0xf927f221, 0x0233fe2e, + 0x113d063c, 0x3e2a2237, 0x00000000, 0x00000000, 0x3602f114, 0xf1144a03, + 0x4a033602, 0x68e97fe4, 0x36ff35fa, 0x19163307, 0x00100022, 0x290409fe, + 0x410276e3, 0x4ff347fa, 0x32093405, 0x360a46fd, 0x1613221a, 0x02390028, + 0x451a2429, 0x65f17fd3, 0x47fa4cfc, 0x34054ff3, 0x5af34506, 0x2b083400, + 0x52fb45fe, 0x3b0260f6, 0x57fd4b02, 0x380164fd, 0x55fa4afd, 0x51fd3b00, + 0x5ffb56f9, 0x4dff42ff, 0x56fe4601, 0x3d0048fb, 0x3f002900, 0x3f003f00, + 0x560453f7, 0x48f96100, 0x3e03290d, 0x33070f0d, 0x7fd95002, 0x60ef5bee, + 0x62dd51e6, 0x61e966e8, 0x63e877e5, 0x66ee6eeb, 0x50007fdc, 0x5ef959fb, + 0x27005cfc, 0x54f14100, 0x49fe7fdd, 0x5bf768f4, 0x37037fe1, 0x37073807, + 0x35fd3d08, 0x4af94400, 0x67f358f7, 0x59f75bf3, 0x4cf85cf2, 0x6ee957f4, + 0x4ef669e8, 0x63ef70ec, 0x7fba7fb2, 0x7fd27fce, 0x4efb42fc, 0x48f847fc, + 0x37ff3b02, 0x4bfa46f9, 0x77de59f8, 0x14204bfd, 0x7fd4161e, 0x3dfb3600, + 0x3cff3a00, 0x43f83dfd, 0x4af254e7, 0x340541fb, 0x3d003902, 0x46f545f7, + 0x47fc3712, 0x3d073a00, 0x19122909, 0x2b052009, 0x2c002f09, 0x2e023300, + 0x42fc2613, 0x2a0c260f, 0x59002209, 0x1c0a2d04, 0xf5211f0a, 0x0f12d534, + 0xea23001c, 0x0022e726, 0xf420ee27, 0x0000a266, 0xfc21f138, 0xfb250a1d, + 0xf727e333, 0xc645de34, 0xfb2cc143, 0xe3370720, 0x00000120, 0xe721241b, + 0xe424e222, 0xe526e426, 0xf023ee22, 0xf820f222, 0x0023fa25, 0x121c0a1e, + 0x291d191a, 0x48024b00, 0x230e4d08, 0x23111f12, 0x2d111e15, 0x2d122a14, + 0x36101a1b, 0x38104207, 0x430a490b, 0x70e974f6, 0x3df947f1, 0x42fb3500, + 0x50f74df5, 0x57f654f7, 0x65eb7fde, 0x35fb27fd, 0x4bf53df9, 0x5bef4df1, + 0x6fe76be7, 0x4cf57ae4, 0x34f62cf6, 0x3af739f6, 0x45f948f0, 0x4afb45fc, + 0x420256f7, 0x200122f7, 0x34051f0b, 0x43fe37fe, 0x59f84900, 0x04073403, + 0x0811080a, 0x25031310, 0x49fb3dff, 0x4efc46ff, 0x7eeb0000, 0x6eec7ce9, + 0x7ce77ee6, 0x79e569ef, 0x66ef75e5, 0x74e575e6, 0x5ff67adf, 0x5ff864f2, + 0x72e46fef, 0x50fe59fa, 0x55f752fc, 0x48ff51f8, 0x43014005, 0x45003809, + 0x45074501, 0x43fa45f9, 0x40fe4df0, 0x43fa3d02, 0x390240fd, 0x42fd41fd, + 0x33093e00, 0x47fe42ff, 0x46ff4bfe, 0x3c0e48f7, 0x2f002510, 0x250b2312, + 0x290a290c, 0x290c3002, 0x3b00290d, 0x28133203, 0x32124203, 0xfa12fa13, + 0xf41a000e, 0xe721f01f, 0xe425ea21, 0xe22ae227, 0xdc2dd62f, 0xef29de31, + 0xb9450920, 0xc042c13f, 0xd936b64d, 0xf629dd34, 0xff280024, 0x1a1c0e1e, + 0x370c2517, 0xdf25410b, 0xdb28dc27, 0xdf2ee226, 0xe828e22a, 0xf426e331, + 0xfd26f628, 0x141ffb2e, 0x2c191e1d, 0x310b300c, 0x16162d1a, 0x151b1617, + 0x1c1a1421, 0x221b181e, 0x27192a12, 0x460c3212, 0x470e3615, 0x2019530b, + 0x36153115, 0x51fa55fb, 0x51f94df6, 0x49ee50ef, 0x53f64afc, 0x43f747f7, + 0x42f83dff, 0x3b0042f2, 0xf6113b02, 0xf72af320, 0x0035fb31, 0x0a440340, + 0x392f1b42, 0x180047fb, 0x2afe24ff, 0x39f734fe, 0x41fc3ffa, 0x52f943fc, + 0x4cfd51fd, 0x4efa48f9, 0x44f248f4, 0x4cfa46fd, 0x3efb42fb, 0x3dfc3900, + 0x36013cf7, 0xf6113a02, 0xf72af320, 0x0035fb31, 0x0a440340, 0x392f1b42, + 0x00000000, 0x00000000, 0x3602f114, 0xf1144a03, 0x4a033602, 0x68e97fe4, + 0x36ff35fa, 0x101d3307, 0x000e0019, 0x3efd33f6, 0x101a63e5, 0x66e855fc, + 0x39063905, 0x390e49ef, 0x0a142814, 0x0036001d, 0x610c2a25, 0x75ea7fe0, + 0x55fc4afe, 0x390566e8, 0x58f25dfa, 0x37042cfa, 0x67f159f5, 0x391374eb, + 0x54043a14, 0x3f016006, 0x6af355fb, 0x4b063f05, 0x65ff5afd, 0x4ffc3703, + 0x61f44bfe, 0x3c0132f9, 0x3f002900, 0x3f003f00, 0x560453f7, 0x48f96100, + 0x3e03290d, 0x58f72207, 0x7fdc7fec, 0x5ff25bef, 0x56e754e7, 0x5bef59f4, + 0x4cf27fe1, 0x5af367ee, 0x500b7fdb, 0x54024c05, 0x37fa4e05, 0x53f23d04, + 0x4ffb7fdb, 0x5bf568f5, 0x41007fe2, 0x48004ffe, 0x38fa5cfc, 0x47f84403, + 0x56fc62f3, 0x52fb58f4, 0x43fc48fd, 0x59f048f8, 0x3bff45f7, 0x39044205, + 0x47fe47fc, 0x4aff3a02, 0x45ff2cfc, 0x33f93e00, 0x2afa2ffc, 0x35fa29fd, + 0x4ef74c08, 0x340953f5, 0x5afb4300, 0x48f14301, 0x50f84bfb, 0x40eb53eb, + 0x40e71ff3, 0x4b095ee3, 0x4af83f11, 0x1bfe23fb, 0x41035b0d, 0x4d0845f9, + 0x3e0342f6, 0x51ec44fd, 0x07011e00, 0x4aeb17fd, 0x7ce94210, 0xee2c2511, + 0x7feade32, 0x2a002704, 0x1d0b2207, 0x25061f08, 0x28032a07, 0x2b0d2108, + 0x2f04240d, 0x3a023703, 0x2c083c06, 0x2a0e2c0b, 0x38043007, 0x250d3404, + 0x3a133109, 0x2d0c300a, 0x21144500, 0xee233f08, 0xfd1ce721, 0x001b0a18, + 0xd434f222, 0x1113e827, 0x1d24191f, 0x0f222118, 0x4916141e, 0x1f132214, + 0x10132c1b, 0x240f240f, 0x15191c15, 0x0c1f141e, 0x2a18101b, 0x380e5d00, + 0x261a390f, 0x73e87fe8, 0x3ef752ea, 0x3b003500, 0x59f355f2, 0x5cf55ef3, + 0x64eb7fe3, 0x43f439f2, 0x4df647f5, 0x58f055eb, 0x62f168e9, 0x52f67fdb, + 0x3df830f8, 0x46f942f8, 0x4ff64bf2, 0x5cf453f7, 0x4ffc6cee, 0x4bf045ea, + 0x3a013afe, 0x53f74ef3, 0x63f351fc, 0x26fa51f3, 0x3afa3ef3, 0x49f03bfe, + 0x56f34cf6, 0x57f653f7, 0x7fea0000, 0x78e77fe7, 0x72ed7fe5, 0x76e775e9, + 0x71e875e6, 0x78e176e4, 0x5ef67cdb, 0x63f666f1, 0x7fce6af3, 0x39115cfb, + 0x5ef356fb, 0x4dfe5bf4, 0x49ff4700, 0x51f94004, 0x390f4005, 0x44004301, + 0x440143f6, 0x40024d00, 0x4efb4400, 0x3b053707, 0x360e4102, 0x3c052c0f, + 0x4cfe4602, 0x460c56ee, 0x46f44005, 0x3805370b, 0x41024500, 0x36054afa, + 0x4cfa3607, 0x4dfe52f5, 0x2a194dfe, 0xf710f311, 0xeb1bf411, 0xd829e225, + 0xd130d72a, 0xd82ee027, 0xd72ecd34, 0xed2bd934, 0xc93d0b20, 0xce3ed238, + 0xec2dbd51, 0x0f1cfe23, 0x01270122, 0x2614111e, 0x360f2d12, 0xf0244f00, + 0xef25f225, 0x0f220120, 0x19180f1d, 0x101f1622, 0x1c1f1223, 0x1c242921, + 0x3e152f1b, 0x1a131f12, 0x17181824, 0x1e18101b, 0x29161d1f, 0x3c102a16, + 0x3c0e340f, 0x7bf04e03, 0x38163515, 0x21153d19, 0x3d113213, 0x4af84efd, + 0x48f648f7, 0x47f44bee, 0x46fb3ff5, 0x48f24bef, 0x35f843f0, 0x34f73bf2, + 0xfe0944f5, 0xfc1ff61e, 0x0721ff21, 0x17250c1f, 0x4014261f, 0x25f947f7, + 0x31f52cf8, 0x3bf438f6, 0x43f73ff8, 0x4ff644fa, 0x4af84efd, 0x48f648f7, + 0x47f44bee, 0x46fb3ff5, 0x48f24bef, 0x35f843f0, 0x34f73bf2, 0xfe0944f5, + 0xfc1ff61e, 0x0721ff21, 0x17250c1f, 0x4014261f, 0x00000000, 0x00000000, + 0x3602f114, 0xf1144a03, 0x4a033602, 0x68e97fe4, 0x36ff35fa, 0x00003307, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x3f002900, 0x3f003f00, 0x560453f7, 0x48f96100, 0x3e03290d, 0x37010b00, + 0x7fef4500, 0x520066f3, 0x6beb4af9, 0x7fe17fe5, 0x5fee7fe8, 0x72eb7fe5, + 0x7bef7fe2, 0x7af073f4, 0x3ff473f5, 0x54f144fe, 0x46fd68f3, 0x5af65df8, + 0x4aff7fe2, 0x5bf961fa, 0x38fc7fec, 0x4cf952fb, 0x5df97dea, 0x4dfd57f5, + 0x3ffc47fb, 0x54f444fc, 0x41f93ef9, 0x38053d08, 0x400142fe, 0x4efe3d00, + 0x34073201, 0x2c00230a, 0x2d01260b, 0x2c052e00, 0x3301111f, 0x131c3207, + 0x3e0e2110, 0x64f16cf3, 0x5bf365f3, 0x58f65ef4, 0x56f654f0, 0x57f353f9, + 0x46015eed, 0x4afb4800, 0x66f83b12, 0x5f0064f1, 0x48024bfc, 0x47fd4bf5, + 0x45f32e0f, 0x41003e00, 0x48f12515, 0x36103909, 0x480c3e00, 0x090f0018, + 0x120d1908, 0x130d090f, 0x120c250a, 0x21141d06, 0x2d041e0f, 0x3e003a01, + 0x260c3d07, 0x270f2d0b, 0x2c0d2a0b, 0x290c2d10, 0x221e310a, 0x370a2a12, + 0x2e113311, 0xed1a5900, 0xef1aef16, 0xec1ce71e, 0xe525e921, 0xe428e921, + 0xf521ef26, 0xfa29f128, 0x11290126, 0x031bfa1e, 0xf025161a, 0xf826fc23, + 0x0325fd26, 0x002a0526, 0x16271023, 0x251b300e, 0x440c3c15, 0x47fd6102, + 0x32fb2afa, 0x3efe36fd, 0x3f013a00, 0x4aff48fe, 0x43fb5bf7, 0x27fd1bfb, + 0x2e002cfe, 0x44f840f0, 0x4dfa4ef6, 0x5cf456f6, 0x3cf637f1, 0x41fc3efa, + 0x4cf849f4, 0x58f750f9, 0x61f56eef, 0x4ff554ec, 0x4afc49fa, 0x60f356f3, + 0x75ed61f5, 0x21fb4ef8, 0x35fe30fc, 0x47f33efd, 0x56f44ff6, 0x61f25af3, + 0x5dfa0000, 0x4ff854fa, 0x47ff4200, 0x3cfe3e00, 0x4bfb3bfe, 0x3afc3efd, + 0x4fff42f7, 0x44034700, 0x3ef92c0a, 0x280e240f, 0x1d0c1b10, 0x24142c01, + 0x2a052012, 0x3e0a3001, 0x40092e11, 0x61f568f4, 0x58f960f0, 0x55f955f8, + 0x58f355f7, 0x4dfd4204, 0x4cfa4cfd, 0x4cff3a0a, 0x63f953ff, 0x5f025ff2, + 0x4afb4c00, 0x4bf54600, 0x41004401, 0x3e0349f2, 0x44ff3e04, 0x370b4bf3, + 0x460c4005, 0x1306060f, 0x0e0c1007, 0x0b0d0d12, 0x100f0f0d, 0x170d170c, + 0x1a0e140f, 0x28112c0e, 0x11182f11, 0x16191515, 0x1d161b1f, 0x320e2313, + 0x3f07390a, 0x52fc4dfe, 0x45095efd, 0xdd246df4, 0xe620de24, 0xe02ce225, + 0xf122ee22, 0xf921f128, 0x0021fb23, 0x0d210226, 0x3a0d2317, 0x001afd1d, + 0xf91f1e16, 0xfd22f123, 0xff240322, 0x0b200522, 0x0c220523, 0x1d1e0b27, + 0x271d1a22, 0x151f4213, 0x32191f1f, 0x70ec78ef, 0x55f572ee, 0x59f25cf1, + 0x51f147e6, 0x440050f2, 0x38e846f2, 0x32e844e9, 0xf3174af5, 0xf128f31a, + 0x032cf231, 0x222c062d, 0x52133621, 0x17ff4bfd, 0x2b012201, 0x37fe3600, + 0x40013d00, 0x5cf74400, 0x61f36af2, 0x5af45af1, 0x49f658ee, 0x56f24ff7, + 0x46f649f6, 0x42fb45f6, 0x3afb40f7, 0xf6153b02, 0xf81cf518, 0x031dff1c, + 0x1423091d, 0x430e241d +}; + +static const u8 hevc_cabac_table[27456] = { + 0x07, 0x0f, 0x48, 0x58, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x0f, 0x40, + 0x40, 0x40, 0x0f, 0x68, + 0x48, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x40, 0x40, 0x68, + 0x58, 0x60, 0x40, 0x1f, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x48, 0x48, + 0x60, 0x60, 0x50, 0x58, + 0x50, 0x07, 0x58, 0x68, 0x50, 0x58, 0x68, 0x68, 0x68, 0x68, 0x68, 0x50, + 0x48, 0x68, 0x60, 0x60, + 0x50, 0x58, 0x50, 0x07, 0x58, 0x68, 0x50, 0x58, 0x68, 0x68, 0x68, 0x68, + 0x68, 0x50, 0x48, 0x68, + 0x48, 0x48, 0x1f, 0x58, 0x68, 0x68, 0x58, 0x60, 0x60, 0x60, 0x50, 0x50, + 0x50, 0x48, 0x58, 0x58, + 0x37, 0x07, 0x58, 0x48, 0x58, 0x58, 0x37, 0x07, 0x58, 0x48, 0x58, 0x58, + 0x37, 0x07, 0x58, 0x50, + 0x48, 0x1f, 0x1f, 0x0f, 0x0f, 0x0f, 0x0f, 0x07, 0x0f, 0x48, 0x68, 0x0f, + 0x48, 0x68, 0x40, 0x40, + 0x50, 0x50, 0x07, 0x40, 0x50, 0x0f, 0x40, 0x48, 0x07, 0x40, 0x27, 0x50, + 0x48, 0x48, 0x40, 0x0f, + 0x50, 0x37, 0x1f, 0x1f, 0x50, 0x37, 0x40, 0x27, 0x40, 0x07, 0x0f, 0x17, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x0f, 0x47, 0x57, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x0f, 0x40, + 0x40, 0x40, 0x0f, 0x66, + 0x47, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x00, 0x00, 0x67, + 0x57, 0x5e, 0x00, 0x1f, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x47, 0x47, + 0x5f, 0x5f, 0x4f, 0x57, + 0x4f, 0x07, 0x57, 0x67, 0x4f, 0x57, 0x67, 0x67, 0x67, 0x67, 0x66, 0x4f, + 0x47, 0x66, 0x5f, 0x5f, + 0x4f, 0x57, 0x4f, 0x07, 0x57, 0x67, 0x4f, 0x57, 0x67, 0x67, 0x67, 0x67, + 0x66, 0x4f, 0x47, 0x66, + 0x46, 0x48, 0x20, 0x57, 0x67, 0x67, 0x57, 0x5f, 0x5f, 0x5e, 0x4f, 0x4f, + 0x4f, 0x47, 0x57, 0x57, + 0x37, 0x07, 0x57, 0x47, 0x57, 0x57, 0x37, 0x07, 0x57, 0x47, 0x57, 0x57, + 0x37, 0x07, 0x57, 0x4f, + 0x47, 0x1f, 0x1f, 0x0f, 0x10, 0x0f, 0x10, 0x07, 0x10, 0x47, 0x67, 0x10, + 0x47, 0x67, 0x40, 0x40, + 0x4f, 0x4e, 0x08, 0x00, 0x4f, 0x0f, 0x00, 0x47, 0x07, 0x01, 0x27, 0x4e, + 0x47, 0x47, 0x00, 0x0f, + 0x4f, 0x37, 0x1f, 0x1f, 0x4f, 0x36, 0x00, 0x27, 0x00, 0x07, 0x10, 0x17, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x0e, 0x47, 0x57, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x0e, 0x40, + 0x40, 0x40, 0x0e, 0x64, + 0x47, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x00, 0x00, 0x66, + 0x57, 0x5d, 0x00, 0x1e, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x47, 0x47, + 0x5e, 0x5e, 0x4e, 0x56, + 0x4f, 0x07, 0x56, 0x66, 0x4f, 0x56, 0x66, 0x67, 0x66, 0x66, 0x64, 0x4e, + 0x46, 0x64, 0x5e, 0x5e, + 0x4e, 0x56, 0x4f, 0x07, 0x56, 0x66, 0x4f, 0x56, 0x66, 0x67, 0x66, 0x66, + 0x64, 0x4e, 0x46, 0x64, + 0x45, 0x48, 0x20, 0x57, 0x66, 0x66, 0x56, 0x5e, 0x5e, 0x5d, 0x4e, 0x4e, + 0x4e, 0x46, 0x56, 0x57, + 0x36, 0x07, 0x56, 0x46, 0x56, 0x57, 0x36, 0x07, 0x56, 0x46, 0x56, 0x57, + 0x36, 0x07, 0x56, 0x4f, + 0x47, 0x1e, 0x1e, 0x0f, 0x10, 0x0f, 0x10, 0x07, 0x10, 0x47, 0x66, 0x10, + 0x47, 0x66, 0x40, 0x40, + 0x4f, 0x4d, 0x08, 0x00, 0x4f, 0x0f, 0x00, 0x47, 0x07, 0x03, 0x27, 0x4d, + 0x47, 0x46, 0x01, 0x0f, + 0x4f, 0x36, 0x1f, 0x1e, 0x4f, 0x34, 0x01, 0x26, 0x00, 0x07, 0x10, 0x17, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x0d, 0x47, 0x57, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x0e, 0x40, + 0x40, 0x40, 0x0e, 0x62, + 0x47, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x00, 0x00, 0x65, + 0x57, 0x5c, 0x00, 0x1e, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x47, 0x47, + 0x5d, 0x5d, 0x4e, 0x56, + 0x4f, 0x07, 0x56, 0x66, 0x4f, 0x55, 0x65, 0x67, 0x66, 0x65, 0x63, 0x4d, + 0x46, 0x62, 0x5d, 0x5d, + 0x4e, 0x56, 0x4f, 0x07, 0x56, 0x66, 0x4f, 0x55, 0x65, 0x67, 0x66, 0x65, + 0x63, 0x4d, 0x46, 0x62, + 0x44, 0x48, 0x20, 0x57, 0x65, 0x65, 0x56, 0x5d, 0x5d, 0x5c, 0x4e, 0x4d, + 0x4e, 0x45, 0x56, 0x57, + 0x36, 0x07, 0x56, 0x45, 0x56, 0x57, 0x36, 0x07, 0x56, 0x45, 0x56, 0x57, + 0x36, 0x07, 0x56, 0x4f, + 0x47, 0x1e, 0x1e, 0x0f, 0x10, 0x0f, 0x10, 0x07, 0x10, 0x47, 0x65, 0x10, + 0x47, 0x65, 0x40, 0x40, + 0x4f, 0x4c, 0x08, 0x00, 0x4f, 0x0f, 0x00, 0x47, 0x07, 0x04, 0x27, 0x4c, + 0x47, 0x45, 0x01, 0x0f, + 0x4f, 0x36, 0x1f, 0x1e, 0x4f, 0x33, 0x01, 0x25, 0x00, 0x07, 0x10, 0x17, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x0c, 0x46, 0x56, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x0d, 0x40, + 0x40, 0x40, 0x0d, 0x60, + 0x46, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x01, 0x01, 0x64, + 0x56, 0x5b, 0x01, 0x1d, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x46, 0x46, + 0x5c, 0x5c, 0x4d, 0x55, + 0x4e, 0x07, 0x55, 0x65, 0x4e, 0x54, 0x64, 0x66, 0x65, 0x64, 0x61, 0x4c, + 0x45, 0x60, 0x5c, 0x5c, + 0x4d, 0x55, 0x4e, 0x07, 0x55, 0x65, 0x4e, 0x54, 0x64, 0x66, 0x65, 0x64, + 0x61, 0x4c, 0x45, 0x60, + 0x43, 0x49, 0x21, 0x56, 0x64, 0x64, 0x55, 0x5c, 0x5c, 0x5b, 0x4d, 0x4c, + 0x4d, 0x44, 0x55, 0x56, + 0x35, 0x07, 0x55, 0x44, 0x55, 0x56, 0x35, 0x07, 0x55, 0x44, 0x55, 0x56, + 0x35, 0x07, 0x55, 0x4e, + 0x46, 0x1d, 0x1d, 0x0f, 0x11, 0x0f, 0x11, 0x07, 0x11, 0x46, 0x64, 0x11, + 0x46, 0x64, 0x40, 0x40, + 0x4e, 0x4b, 0x09, 0x01, 0x4e, 0x0f, 0x01, 0x46, 0x07, 0x06, 0x27, 0x4b, + 0x46, 0x44, 0x02, 0x0f, + 0x4e, 0x35, 0x1e, 0x1d, 0x4e, 0x31, 0x02, 0x24, 0x01, 0x07, 0x11, 0x16, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x0b, 0x46, 0x56, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x0c, 0x40, + 0x40, 0x40, 0x0c, 0x5e, + 0x46, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x01, 0x01, 0x63, + 0x56, 0x59, 0x01, 0x1c, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x46, 0x46, + 0x5b, 0x5b, 0x4c, 0x54, + 0x4e, 0x07, 0x54, 0x64, 0x4e, 0x53, 0x63, 0x66, 0x64, 0x63, 0x60, 0x4b, + 0x44, 0x5e, 0x5b, 0x5b, + 0x4c, 0x54, 0x4e, 0x07, 0x54, 0x64, 0x4e, 0x53, 0x63, 0x66, 0x64, 0x63, + 0x60, 0x4b, 0x44, 0x5e, + 0x41, 0x49, 0x21, 0x56, 0x63, 0x63, 0x54, 0x5b, 0x5b, 0x59, 0x4c, 0x4b, + 0x4c, 0x43, 0x54, 0x56, + 0x34, 0x07, 0x54, 0x43, 0x54, 0x56, 0x34, 0x07, 0x54, 0x43, 0x54, 0x56, + 0x34, 0x07, 0x54, 0x4e, + 0x46, 0x1c, 0x1c, 0x0f, 0x11, 0x0f, 0x11, 0x07, 0x11, 0x46, 0x63, 0x11, + 0x46, 0x63, 0x40, 0x40, + 0x4e, 0x49, 0x09, 0x01, 0x4e, 0x0f, 0x01, 0x46, 0x07, 0x07, 0x27, 0x49, + 0x46, 0x43, 0x03, 0x0f, + 0x4e, 0x34, 0x1e, 0x1c, 0x4e, 0x30, 0x03, 0x23, 0x01, 0x07, 0x11, 0x16, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x0a, 0x46, 0x56, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x0c, 0x40, + 0x40, 0x40, 0x0c, 0x5c, + 0x46, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x01, 0x01, 0x62, + 0x56, 0x58, 0x01, 0x1c, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x46, 0x46, + 0x5a, 0x5a, 0x4c, 0x54, + 0x4e, 0x07, 0x54, 0x64, 0x4e, 0x52, 0x62, 0x66, 0x64, 0x62, 0x5e, 0x4a, + 0x44, 0x5c, 0x5a, 0x5a, + 0x4c, 0x54, 0x4e, 0x07, 0x54, 0x64, 0x4e, 0x52, 0x62, 0x66, 0x64, 0x62, + 0x5e, 0x4a, 0x44, 0x5c, + 0x40, 0x49, 0x21, 0x56, 0x62, 0x62, 0x54, 0x5a, 0x5a, 0x58, 0x4c, 0x4a, + 0x4c, 0x42, 0x54, 0x56, + 0x34, 0x07, 0x54, 0x42, 0x54, 0x56, 0x34, 0x07, 0x54, 0x42, 0x54, 0x56, + 0x34, 0x07, 0x54, 0x4e, + 0x46, 0x1c, 0x1c, 0x0f, 0x11, 0x0f, 0x11, 0x07, 0x11, 0x46, 0x62, 0x11, + 0x46, 0x62, 0x40, 0x40, + 0x4e, 0x48, 0x09, 0x01, 0x4e, 0x0f, 0x01, 0x46, 0x07, 0x09, 0x27, 0x48, + 0x46, 0x42, 0x03, 0x0f, + 0x4e, 0x34, 0x1e, 0x1c, 0x4e, 0x2e, 0x03, 0x22, 0x01, 0x07, 0x11, 0x16, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x09, 0x45, 0x55, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x0b, 0x40, + 0x40, 0x40, 0x0b, 0x5a, + 0x45, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x02, 0x02, 0x61, + 0x55, 0x57, 0x02, 0x1b, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x45, 0x45, + 0x59, 0x59, 0x4b, 0x53, + 0x4d, 0x07, 0x53, 0x63, 0x4d, 0x51, 0x61, 0x65, 0x63, 0x61, 0x5d, 0x49, + 0x43, 0x5a, 0x59, 0x59, + 0x4b, 0x53, 0x4d, 0x07, 0x53, 0x63, 0x4d, 0x51, 0x61, 0x65, 0x63, 0x61, + 0x5d, 0x49, 0x43, 0x5a, + 0x00, 0x4a, 0x22, 0x55, 0x61, 0x61, 0x53, 0x59, 0x59, 0x57, 0x4b, 0x49, + 0x4b, 0x41, 0x53, 0x55, + 0x33, 0x07, 0x53, 0x41, 0x53, 0x55, 0x33, 0x07, 0x53, 0x41, 0x53, 0x55, + 0x33, 0x07, 0x53, 0x4d, + 0x45, 0x1b, 0x1b, 0x0f, 0x12, 0x0f, 0x12, 0x07, 0x12, 0x45, 0x61, 0x12, + 0x45, 0x61, 0x40, 0x40, + 0x4d, 0x47, 0x0a, 0x02, 0x4d, 0x0f, 0x02, 0x45, 0x07, 0x0a, 0x27, 0x47, + 0x45, 0x41, 0x04, 0x0f, + 0x4d, 0x33, 0x1d, 0x1b, 0x4d, 0x2d, 0x04, 0x21, 0x02, 0x07, 0x12, 0x15, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x08, 0x45, 0x55, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x0a, 0x40, + 0x40, 0x40, 0x0a, 0x59, + 0x45, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x02, 0x02, 0x60, + 0x55, 0x56, 0x02, 0x1a, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x45, 0x45, + 0x58, 0x58, 0x4b, 0x53, + 0x4d, 0x07, 0x53, 0x63, 0x4d, 0x50, 0x60, 0x65, 0x63, 0x60, 0x5b, 0x48, + 0x43, 0x59, 0x58, 0x58, + 0x4b, 0x53, 0x4d, 0x07, 0x53, 0x63, 0x4d, 0x50, 0x60, 0x65, 0x63, 0x60, + 0x5b, 0x48, 0x43, 0x59, + 0x01, 0x4a, 0x22, 0x55, 0x60, 0x60, 0x53, 0x58, 0x58, 0x56, 0x4b, 0x48, + 0x4b, 0x40, 0x53, 0x55, + 0x32, 0x07, 0x53, 0x40, 0x53, 0x55, 0x32, 0x07, 0x53, 0x40, 0x53, 0x55, + 0x32, 0x07, 0x53, 0x4d, + 0x45, 0x1a, 0x1a, 0x0f, 0x12, 0x0f, 0x12, 0x07, 0x12, 0x45, 0x60, 0x12, + 0x45, 0x60, 0x40, 0x40, + 0x4d, 0x46, 0x0a, 0x02, 0x4d, 0x0f, 0x02, 0x45, 0x07, 0x0c, 0x27, 0x46, + 0x45, 0x40, 0x04, 0x0f, + 0x4d, 0x32, 0x1d, 0x1a, 0x4d, 0x2b, 0x04, 0x20, 0x02, 0x07, 0x12, 0x15, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x07, 0x45, 0x55, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x0a, 0x40, + 0x40, 0x40, 0x0a, 0x57, + 0x45, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x02, 0x02, 0x5f, + 0x55, 0x54, 0x02, 0x1a, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x45, 0x45, + 0x57, 0x57, 0x4a, 0x52, + 0x4d, 0x07, 0x52, 0x62, 0x4d, 0x4f, 0x5f, 0x65, 0x62, 0x5f, 0x59, 0x47, + 0x42, 0x57, 0x57, 0x57, + 0x4a, 0x52, 0x4d, 0x07, 0x52, 0x62, 0x4d, 0x4f, 0x5f, 0x65, 0x62, 0x5f, + 0x59, 0x47, 0x42, 0x57, + 0x03, 0x4a, 0x22, 0x55, 0x5f, 0x5f, 0x52, 0x57, 0x57, 0x54, 0x4a, 0x47, + 0x4a, 0x00, 0x52, 0x55, + 0x32, 0x07, 0x52, 0x00, 0x52, 0x55, 0x32, 0x07, 0x52, 0x00, 0x52, 0x55, + 0x32, 0x07, 0x52, 0x4d, + 0x45, 0x1a, 0x1a, 0x0f, 0x12, 0x0f, 0x12, 0x07, 0x12, 0x45, 0x5f, 0x12, + 0x45, 0x5f, 0x40, 0x40, + 0x4d, 0x44, 0x0a, 0x02, 0x4d, 0x0f, 0x02, 0x45, 0x07, 0x0e, 0x27, 0x44, + 0x45, 0x00, 0x05, 0x0f, + 0x4d, 0x32, 0x1d, 0x1a, 0x4d, 0x29, 0x05, 0x1f, 0x02, 0x07, 0x12, 0x15, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x06, 0x44, 0x54, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x09, 0x40, + 0x40, 0x40, 0x09, 0x55, + 0x44, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x03, 0x03, 0x5e, + 0x54, 0x53, 0x03, 0x19, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x44, 0x44, + 0x56, 0x56, 0x49, 0x51, + 0x4c, 0x07, 0x51, 0x61, 0x4c, 0x4e, 0x5e, 0x64, 0x61, 0x5e, 0x58, 0x46, + 0x41, 0x55, 0x56, 0x56, + 0x49, 0x51, 0x4c, 0x07, 0x51, 0x61, 0x4c, 0x4e, 0x5e, 0x64, 0x61, 0x5e, + 0x58, 0x46, 0x41, 0x55, + 0x04, 0x4b, 0x23, 0x54, 0x5e, 0x5e, 0x51, 0x56, 0x56, 0x53, 0x49, 0x46, + 0x49, 0x01, 0x51, 0x54, + 0x31, 0x07, 0x51, 0x01, 0x51, 0x54, 0x31, 0x07, 0x51, 0x01, 0x51, 0x54, + 0x31, 0x07, 0x51, 0x4c, + 0x44, 0x19, 0x19, 0x0f, 0x13, 0x0f, 0x13, 0x07, 0x13, 0x44, 0x5e, 0x13, + 0x44, 0x5e, 0x40, 0x40, + 0x4c, 0x43, 0x0b, 0x03, 0x4c, 0x0f, 0x03, 0x44, 0x07, 0x0f, 0x27, 0x43, + 0x44, 0x01, 0x06, 0x0f, + 0x4c, 0x31, 0x1c, 0x19, 0x4c, 0x28, 0x06, 0x1e, 0x03, 0x07, 0x13, 0x14, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x05, 0x44, 0x54, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x09, 0x40, + 0x40, 0x40, 0x09, 0x53, + 0x44, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x03, 0x03, 0x5d, + 0x54, 0x52, 0x03, 0x19, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x44, 0x44, + 0x55, 0x55, 0x49, 0x51, + 0x4c, 0x07, 0x51, 0x61, 0x4c, 0x4d, 0x5d, 0x64, 0x61, 0x5d, 0x56, 0x45, + 0x41, 0x53, 0x55, 0x55, + 0x49, 0x51, 0x4c, 0x07, 0x51, 0x61, 0x4c, 0x4d, 0x5d, 0x64, 0x61, 0x5d, + 0x56, 0x45, 0x41, 0x53, + 0x05, 0x4b, 0x23, 0x54, 0x5d, 0x5d, 0x51, 0x55, 0x55, 0x52, 0x49, 0x45, + 0x49, 0x02, 0x51, 0x54, + 0x31, 0x07, 0x51, 0x02, 0x51, 0x54, 0x31, 0x07, 0x51, 0x02, 0x51, 0x54, + 0x31, 0x07, 0x51, 0x4c, + 0x44, 0x19, 0x19, 0x0f, 0x13, 0x0f, 0x13, 0x07, 0x13, 0x44, 0x5d, 0x13, + 0x44, 0x5d, 0x40, 0x40, + 0x4c, 0x42, 0x0b, 0x03, 0x4c, 0x0f, 0x03, 0x44, 0x07, 0x11, 0x27, 0x42, + 0x44, 0x02, 0x06, 0x0f, + 0x4c, 0x31, 0x1c, 0x19, 0x4c, 0x26, 0x06, 0x1d, 0x03, 0x07, 0x13, 0x14, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x04, 0x44, 0x54, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x08, 0x40, + 0x40, 0x40, 0x08, 0x51, + 0x44, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x03, 0x03, 0x5c, + 0x54, 0x51, 0x03, 0x18, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x44, 0x44, + 0x54, 0x54, 0x48, 0x50, + 0x4c, 0x07, 0x50, 0x60, 0x4c, 0x4c, 0x5c, 0x64, 0x60, 0x5c, 0x55, 0x44, + 0x40, 0x51, 0x54, 0x54, + 0x48, 0x50, 0x4c, 0x07, 0x50, 0x60, 0x4c, 0x4c, 0x5c, 0x64, 0x60, 0x5c, + 0x55, 0x44, 0x40, 0x51, + 0x06, 0x4b, 0x23, 0x54, 0x5c, 0x5c, 0x50, 0x54, 0x54, 0x51, 0x48, 0x44, + 0x48, 0x03, 0x50, 0x54, + 0x30, 0x07, 0x50, 0x03, 0x50, 0x54, 0x30, 0x07, 0x50, 0x03, 0x50, 0x54, + 0x30, 0x07, 0x50, 0x4c, + 0x44, 0x18, 0x18, 0x0f, 0x13, 0x0f, 0x13, 0x07, 0x13, 0x44, 0x5c, 0x13, + 0x44, 0x5c, 0x40, 0x40, + 0x4c, 0x41, 0x0b, 0x03, 0x4c, 0x0f, 0x03, 0x44, 0x07, 0x12, 0x27, 0x41, + 0x44, 0x03, 0x07, 0x0f, + 0x4c, 0x30, 0x1c, 0x18, 0x4c, 0x25, 0x07, 0x1c, 0x03, 0x07, 0x13, 0x14, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x03, 0x43, 0x53, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x40, + 0x40, 0x40, 0x07, 0x4f, + 0x43, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x04, 0x04, 0x5b, + 0x53, 0x4f, 0x04, 0x17, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x43, 0x43, + 0x53, 0x53, 0x47, 0x4f, + 0x4b, 0x07, 0x4f, 0x5f, 0x4b, 0x4b, 0x5b, 0x63, 0x5f, 0x5b, 0x53, 0x43, + 0x00, 0x4f, 0x53, 0x53, + 0x47, 0x4f, 0x4b, 0x07, 0x4f, 0x5f, 0x4b, 0x4b, 0x5b, 0x63, 0x5f, 0x5b, + 0x53, 0x43, 0x00, 0x4f, + 0x08, 0x4c, 0x24, 0x53, 0x5b, 0x5b, 0x4f, 0x53, 0x53, 0x4f, 0x47, 0x43, + 0x47, 0x04, 0x4f, 0x53, + 0x2f, 0x07, 0x4f, 0x04, 0x4f, 0x53, 0x2f, 0x07, 0x4f, 0x04, 0x4f, 0x53, + 0x2f, 0x07, 0x4f, 0x4b, + 0x43, 0x17, 0x17, 0x0f, 0x14, 0x0f, 0x14, 0x07, 0x14, 0x43, 0x5b, 0x14, + 0x43, 0x5b, 0x40, 0x40, + 0x4b, 0x00, 0x0c, 0x04, 0x4b, 0x0f, 0x04, 0x43, 0x07, 0x14, 0x27, 0x00, + 0x43, 0x04, 0x08, 0x0f, + 0x4b, 0x2f, 0x1b, 0x17, 0x4b, 0x23, 0x08, 0x1b, 0x04, 0x07, 0x14, 0x13, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x02, 0x43, 0x53, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x40, + 0x40, 0x40, 0x07, 0x4d, + 0x43, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x04, 0x04, 0x5a, + 0x53, 0x4e, 0x04, 0x17, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x43, 0x43, + 0x52, 0x52, 0x47, 0x4f, + 0x4b, 0x07, 0x4f, 0x5f, 0x4b, 0x4a, 0x5a, 0x63, 0x5f, 0x5a, 0x52, 0x42, + 0x00, 0x4d, 0x52, 0x52, + 0x47, 0x4f, 0x4b, 0x07, 0x4f, 0x5f, 0x4b, 0x4a, 0x5a, 0x63, 0x5f, 0x5a, + 0x52, 0x42, 0x00, 0x4d, + 0x09, 0x4c, 0x24, 0x53, 0x5a, 0x5a, 0x4f, 0x52, 0x52, 0x4e, 0x47, 0x42, + 0x47, 0x05, 0x4f, 0x53, + 0x2f, 0x07, 0x4f, 0x05, 0x4f, 0x53, 0x2f, 0x07, 0x4f, 0x05, 0x4f, 0x53, + 0x2f, 0x07, 0x4f, 0x4b, + 0x43, 0x17, 0x17, 0x0f, 0x14, 0x0f, 0x14, 0x07, 0x14, 0x43, 0x5a, 0x14, + 0x43, 0x5a, 0x40, 0x40, + 0x4b, 0x01, 0x0c, 0x04, 0x4b, 0x0f, 0x04, 0x43, 0x07, 0x15, 0x27, 0x01, + 0x43, 0x05, 0x08, 0x0f, + 0x4b, 0x2f, 0x1b, 0x17, 0x4b, 0x22, 0x08, 0x1a, 0x04, 0x07, 0x14, 0x13, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x01, 0x43, 0x53, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x06, 0x40, + 0x40, 0x40, 0x06, 0x4b, + 0x43, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x04, 0x04, 0x59, + 0x53, 0x4d, 0x04, 0x16, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x43, 0x43, + 0x51, 0x51, 0x46, 0x4e, + 0x4b, 0x07, 0x4e, 0x5e, 0x4b, 0x49, 0x59, 0x63, 0x5e, 0x59, 0x50, 0x41, + 0x01, 0x4b, 0x51, 0x51, + 0x46, 0x4e, 0x4b, 0x07, 0x4e, 0x5e, 0x4b, 0x49, 0x59, 0x63, 0x5e, 0x59, + 0x50, 0x41, 0x01, 0x4b, + 0x0a, 0x4c, 0x24, 0x53, 0x59, 0x59, 0x4e, 0x51, 0x51, 0x4d, 0x46, 0x41, + 0x46, 0x06, 0x4e, 0x53, + 0x2e, 0x07, 0x4e, 0x06, 0x4e, 0x53, 0x2e, 0x07, 0x4e, 0x06, 0x4e, 0x53, + 0x2e, 0x07, 0x4e, 0x4b, + 0x43, 0x16, 0x16, 0x0f, 0x14, 0x0f, 0x14, 0x07, 0x14, 0x43, 0x59, 0x14, + 0x43, 0x59, 0x40, 0x40, + 0x4b, 0x02, 0x0c, 0x04, 0x4b, 0x0f, 0x04, 0x43, 0x07, 0x17, 0x27, 0x02, + 0x43, 0x06, 0x09, 0x0f, + 0x4b, 0x2e, 0x1b, 0x16, 0x4b, 0x20, 0x09, 0x19, 0x04, 0x07, 0x14, 0x13, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x43, 0x53, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x05, 0x40, + 0x40, 0x40, 0x05, 0x4a, + 0x43, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x04, 0x04, 0x59, + 0x53, 0x4c, 0x04, 0x15, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x43, 0x43, + 0x51, 0x51, 0x46, 0x4e, + 0x4b, 0x07, 0x4e, 0x5e, 0x4b, 0x49, 0x59, 0x63, 0x5e, 0x59, 0x4f, 0x41, + 0x01, 0x4a, 0x51, 0x51, + 0x46, 0x4e, 0x4b, 0x07, 0x4e, 0x5e, 0x4b, 0x49, 0x59, 0x63, 0x5e, 0x59, + 0x4f, 0x41, 0x01, 0x4a, + 0x0b, 0x4d, 0x24, 0x53, 0x59, 0x59, 0x4e, 0x51, 0x51, 0x4c, 0x46, 0x41, + 0x46, 0x06, 0x4e, 0x53, + 0x2d, 0x07, 0x4e, 0x06, 0x4e, 0x53, 0x2d, 0x07, 0x4e, 0x06, 0x4e, 0x53, + 0x2d, 0x07, 0x4e, 0x4b, + 0x43, 0x15, 0x15, 0x0f, 0x14, 0x0f, 0x14, 0x07, 0x14, 0x43, 0x59, 0x14, + 0x43, 0x59, 0x40, 0x40, + 0x4b, 0x03, 0x0c, 0x04, 0x4b, 0x0f, 0x04, 0x43, 0x07, 0x18, 0x27, 0x03, + 0x43, 0x06, 0x09, 0x0f, + 0x4b, 0x2d, 0x1a, 0x15, 0x4b, 0x1e, 0x09, 0x18, 0x04, 0x07, 0x14, 0x12, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x42, 0x52, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x05, 0x40, + 0x40, 0x40, 0x05, 0x48, + 0x42, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x05, 0x05, 0x58, + 0x52, 0x4a, 0x05, 0x15, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x42, 0x42, + 0x50, 0x50, 0x45, 0x4d, + 0x4a, 0x07, 0x4d, 0x5d, 0x4a, 0x48, 0x58, 0x62, 0x5d, 0x58, 0x4d, 0x40, + 0x02, 0x48, 0x50, 0x50, + 0x45, 0x4d, 0x4a, 0x07, 0x4d, 0x5d, 0x4a, 0x48, 0x58, 0x62, 0x5d, 0x58, + 0x4d, 0x40, 0x02, 0x48, + 0x0d, 0x4d, 0x25, 0x52, 0x58, 0x58, 0x4d, 0x50, 0x50, 0x4a, 0x45, 0x40, + 0x45, 0x07, 0x4d, 0x52, + 0x2d, 0x07, 0x4d, 0x07, 0x4d, 0x52, 0x2d, 0x07, 0x4d, 0x07, 0x4d, 0x52, + 0x2d, 0x07, 0x4d, 0x4a, + 0x42, 0x15, 0x15, 0x0f, 0x15, 0x0f, 0x15, 0x07, 0x15, 0x42, 0x58, 0x15, + 0x42, 0x58, 0x40, 0x40, + 0x4a, 0x05, 0x0d, 0x05, 0x4a, 0x0f, 0x05, 0x42, 0x07, 0x1a, 0x27, 0x05, + 0x42, 0x07, 0x0a, 0x0f, + 0x4a, 0x2d, 0x1a, 0x15, 0x4a, 0x1d, 0x0a, 0x18, 0x05, 0x07, 0x15, 0x12, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x40, 0x42, 0x52, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x04, 0x40, + 0x40, 0x40, 0x04, 0x46, + 0x42, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x05, 0x05, 0x57, + 0x52, 0x49, 0x05, 0x14, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x42, 0x42, + 0x4f, 0x4f, 0x44, 0x4c, + 0x4a, 0x07, 0x4c, 0x5c, 0x4a, 0x47, 0x57, 0x62, 0x5c, 0x57, 0x4b, 0x00, + 0x03, 0x46, 0x4f, 0x4f, + 0x44, 0x4c, 0x4a, 0x07, 0x4c, 0x5c, 0x4a, 0x47, 0x57, 0x62, 0x5c, 0x57, + 0x4b, 0x00, 0x03, 0x46, + 0x0e, 0x4d, 0x25, 0x52, 0x57, 0x57, 0x4c, 0x4f, 0x4f, 0x49, 0x44, 0x00, + 0x44, 0x08, 0x4c, 0x52, + 0x2c, 0x07, 0x4c, 0x08, 0x4c, 0x52, 0x2c, 0x07, 0x4c, 0x08, 0x4c, 0x52, + 0x2c, 0x07, 0x4c, 0x4a, + 0x42, 0x14, 0x14, 0x0f, 0x15, 0x0f, 0x15, 0x07, 0x15, 0x42, 0x57, 0x15, + 0x42, 0x57, 0x40, 0x40, + 0x4a, 0x06, 0x0d, 0x05, 0x4a, 0x0f, 0x05, 0x42, 0x07, 0x1c, 0x27, 0x06, + 0x42, 0x08, 0x0b, 0x0f, + 0x4a, 0x2c, 0x1a, 0x14, 0x4a, 0x1b, 0x0b, 0x17, 0x05, 0x07, 0x15, 0x12, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x41, 0x42, 0x52, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x04, 0x40, + 0x40, 0x40, 0x04, 0x44, + 0x42, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x05, 0x05, 0x56, + 0x52, 0x48, 0x05, 0x14, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x42, 0x42, + 0x4e, 0x4e, 0x44, 0x4c, + 0x4a, 0x07, 0x4c, 0x5c, 0x4a, 0x46, 0x56, 0x62, 0x5c, 0x56, 0x4a, 0x01, + 0x03, 0x44, 0x4e, 0x4e, + 0x44, 0x4c, 0x4a, 0x07, 0x4c, 0x5c, 0x4a, 0x46, 0x56, 0x62, 0x5c, 0x56, + 0x4a, 0x01, 0x03, 0x44, + 0x0f, 0x4d, 0x25, 0x52, 0x56, 0x56, 0x4c, 0x4e, 0x4e, 0x48, 0x44, 0x01, + 0x44, 0x09, 0x4c, 0x52, + 0x2c, 0x07, 0x4c, 0x09, 0x4c, 0x52, 0x2c, 0x07, 0x4c, 0x09, 0x4c, 0x52, + 0x2c, 0x07, 0x4c, 0x4a, + 0x42, 0x14, 0x14, 0x0f, 0x15, 0x0f, 0x15, 0x07, 0x15, 0x42, 0x56, 0x15, + 0x42, 0x56, 0x40, 0x40, + 0x4a, 0x07, 0x0d, 0x05, 0x4a, 0x0f, 0x05, 0x42, 0x07, 0x1d, 0x27, 0x07, + 0x42, 0x09, 0x0b, 0x0f, + 0x4a, 0x2c, 0x1a, 0x14, 0x4a, 0x1a, 0x0b, 0x16, 0x05, 0x07, 0x15, 0x12, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x42, 0x41, 0x51, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x03, 0x40, + 0x40, 0x40, 0x03, 0x42, + 0x41, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x06, 0x06, 0x55, + 0x51, 0x47, 0x06, 0x13, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x41, 0x41, + 0x4d, 0x4d, 0x43, 0x4b, + 0x49, 0x07, 0x4b, 0x5b, 0x49, 0x45, 0x55, 0x61, 0x5b, 0x55, 0x48, 0x02, + 0x04, 0x42, 0x4d, 0x4d, + 0x43, 0x4b, 0x49, 0x07, 0x4b, 0x5b, 0x49, 0x45, 0x55, 0x61, 0x5b, 0x55, + 0x48, 0x02, 0x04, 0x42, + 0x10, 0x4e, 0x26, 0x51, 0x55, 0x55, 0x4b, 0x4d, 0x4d, 0x47, 0x43, 0x02, + 0x43, 0x0a, 0x4b, 0x51, + 0x2b, 0x07, 0x4b, 0x0a, 0x4b, 0x51, 0x2b, 0x07, 0x4b, 0x0a, 0x4b, 0x51, + 0x2b, 0x07, 0x4b, 0x49, + 0x41, 0x13, 0x13, 0x0f, 0x16, 0x0f, 0x16, 0x07, 0x16, 0x41, 0x55, 0x16, + 0x41, 0x55, 0x40, 0x40, + 0x49, 0x08, 0x0e, 0x06, 0x49, 0x0f, 0x06, 0x41, 0x07, 0x1f, 0x27, 0x08, + 0x41, 0x0a, 0x0c, 0x0f, + 0x49, 0x2b, 0x19, 0x13, 0x49, 0x18, 0x0c, 0x15, 0x06, 0x07, 0x16, 0x11, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x43, 0x41, 0x51, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x02, 0x40, + 0x40, 0x40, 0x02, 0x40, + 0x41, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x06, 0x06, 0x54, + 0x51, 0x45, 0x06, 0x12, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x41, 0x41, + 0x4c, 0x4c, 0x42, 0x4a, + 0x49, 0x07, 0x4a, 0x5a, 0x49, 0x44, 0x54, 0x61, 0x5a, 0x54, 0x47, 0x03, + 0x05, 0x40, 0x4c, 0x4c, + 0x42, 0x4a, 0x49, 0x07, 0x4a, 0x5a, 0x49, 0x44, 0x54, 0x61, 0x5a, 0x54, + 0x47, 0x03, 0x05, 0x40, + 0x12, 0x4e, 0x26, 0x51, 0x54, 0x54, 0x4a, 0x4c, 0x4c, 0x45, 0x42, 0x03, + 0x42, 0x0b, 0x4a, 0x51, + 0x2a, 0x07, 0x4a, 0x0b, 0x4a, 0x51, 0x2a, 0x07, 0x4a, 0x0b, 0x4a, 0x51, + 0x2a, 0x07, 0x4a, 0x49, + 0x41, 0x12, 0x12, 0x0f, 0x16, 0x0f, 0x16, 0x07, 0x16, 0x41, 0x54, 0x16, + 0x41, 0x54, 0x40, 0x40, + 0x49, 0x0a, 0x0e, 0x06, 0x49, 0x0f, 0x06, 0x41, 0x07, 0x20, 0x27, 0x0a, + 0x41, 0x0b, 0x0d, 0x0f, + 0x49, 0x2a, 0x19, 0x12, 0x49, 0x17, 0x0d, 0x14, 0x06, 0x07, 0x16, 0x11, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x44, 0x41, 0x51, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x02, 0x40, + 0x40, 0x40, 0x02, 0x01, + 0x41, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x06, 0x06, 0x53, + 0x51, 0x44, 0x06, 0x12, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x41, 0x41, + 0x4b, 0x4b, 0x42, 0x4a, + 0x49, 0x07, 0x4a, 0x5a, 0x49, 0x43, 0x53, 0x61, 0x5a, 0x53, 0x45, 0x04, + 0x05, 0x01, 0x4b, 0x4b, + 0x42, 0x4a, 0x49, 0x07, 0x4a, 0x5a, 0x49, 0x43, 0x53, 0x61, 0x5a, 0x53, + 0x45, 0x04, 0x05, 0x01, + 0x13, 0x4e, 0x26, 0x51, 0x53, 0x53, 0x4a, 0x4b, 0x4b, 0x44, 0x42, 0x04, + 0x42, 0x0c, 0x4a, 0x51, + 0x2a, 0x07, 0x4a, 0x0c, 0x4a, 0x51, 0x2a, 0x07, 0x4a, 0x0c, 0x4a, 0x51, + 0x2a, 0x07, 0x4a, 0x49, + 0x41, 0x12, 0x12, 0x0f, 0x16, 0x0f, 0x16, 0x07, 0x16, 0x41, 0x53, 0x16, + 0x41, 0x53, 0x40, 0x40, + 0x49, 0x0b, 0x0e, 0x06, 0x49, 0x0f, 0x06, 0x41, 0x07, 0x22, 0x27, 0x0b, + 0x41, 0x0c, 0x0d, 0x0f, + 0x49, 0x2a, 0x19, 0x12, 0x49, 0x15, 0x0d, 0x13, 0x06, 0x07, 0x16, 0x11, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x45, 0x40, 0x50, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x01, 0x40, + 0x40, 0x40, 0x01, 0x03, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x07, 0x07, 0x52, + 0x50, 0x43, 0x07, 0x11, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x4a, 0x4a, 0x41, 0x49, + 0x48, 0x07, 0x49, 0x59, 0x48, 0x42, 0x52, 0x60, 0x59, 0x52, 0x44, 0x05, + 0x06, 0x03, 0x4a, 0x4a, + 0x41, 0x49, 0x48, 0x07, 0x49, 0x59, 0x48, 0x42, 0x52, 0x60, 0x59, 0x52, + 0x44, 0x05, 0x06, 0x03, + 0x14, 0x4f, 0x27, 0x50, 0x52, 0x52, 0x49, 0x4a, 0x4a, 0x43, 0x41, 0x05, + 0x41, 0x0d, 0x49, 0x50, + 0x29, 0x07, 0x49, 0x0d, 0x49, 0x50, 0x29, 0x07, 0x49, 0x0d, 0x49, 0x50, + 0x29, 0x07, 0x49, 0x48, + 0x40, 0x11, 0x11, 0x0f, 0x17, 0x0f, 0x17, 0x07, 0x17, 0x40, 0x52, 0x17, + 0x40, 0x52, 0x40, 0x40, + 0x48, 0x0c, 0x0f, 0x07, 0x48, 0x0f, 0x07, 0x40, 0x07, 0x23, 0x27, 0x0c, + 0x40, 0x0d, 0x0e, 0x0f, + 0x48, 0x29, 0x18, 0x11, 0x48, 0x14, 0x0e, 0x12, 0x07, 0x07, 0x17, 0x10, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x46, 0x40, 0x50, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x40, + 0x40, 0x40, 0x00, 0x04, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x07, 0x07, 0x51, + 0x50, 0x42, 0x07, 0x10, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x49, 0x49, 0x41, 0x49, + 0x48, 0x07, 0x49, 0x59, 0x48, 0x41, 0x51, 0x60, 0x59, 0x51, 0x42, 0x06, + 0x06, 0x04, 0x49, 0x49, + 0x41, 0x49, 0x48, 0x07, 0x49, 0x59, 0x48, 0x41, 0x51, 0x60, 0x59, 0x51, + 0x42, 0x06, 0x06, 0x04, + 0x15, 0x4f, 0x27, 0x50, 0x51, 0x51, 0x49, 0x49, 0x49, 0x42, 0x41, 0x06, + 0x41, 0x0e, 0x49, 0x50, + 0x28, 0x07, 0x49, 0x0e, 0x49, 0x50, 0x28, 0x07, 0x49, 0x0e, 0x49, 0x50, + 0x28, 0x07, 0x49, 0x48, + 0x40, 0x10, 0x10, 0x0f, 0x17, 0x0f, 0x17, 0x07, 0x17, 0x40, 0x51, 0x17, + 0x40, 0x51, 0x40, 0x40, + 0x48, 0x0d, 0x0f, 0x07, 0x48, 0x0f, 0x07, 0x40, 0x07, 0x25, 0x27, 0x0d, + 0x40, 0x0e, 0x0e, 0x0f, + 0x48, 0x28, 0x18, 0x10, 0x48, 0x12, 0x0e, 0x11, 0x07, 0x07, 0x17, 0x10, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x47, 0x40, 0x50, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x40, + 0x40, 0x40, 0x00, 0x06, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x07, 0x07, 0x50, + 0x50, 0x40, 0x07, 0x10, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x48, 0x48, 0x40, 0x48, + 0x48, 0x07, 0x48, 0x58, 0x48, 0x40, 0x50, 0x60, 0x58, 0x50, 0x40, 0x07, + 0x07, 0x06, 0x48, 0x48, + 0x40, 0x48, 0x48, 0x07, 0x48, 0x58, 0x48, 0x40, 0x50, 0x60, 0x58, 0x50, + 0x40, 0x07, 0x07, 0x06, + 0x17, 0x4f, 0x27, 0x50, 0x50, 0x50, 0x48, 0x48, 0x48, 0x40, 0x40, 0x07, + 0x40, 0x0f, 0x48, 0x50, + 0x28, 0x07, 0x48, 0x0f, 0x48, 0x50, 0x28, 0x07, 0x48, 0x0f, 0x48, 0x50, + 0x28, 0x07, 0x48, 0x48, + 0x40, 0x10, 0x10, 0x0f, 0x17, 0x0f, 0x17, 0x07, 0x17, 0x40, 0x50, 0x17, + 0x40, 0x50, 0x40, 0x40, + 0x48, 0x0f, 0x0f, 0x07, 0x48, 0x0f, 0x07, 0x40, 0x07, 0x27, 0x27, 0x0f, + 0x40, 0x0f, 0x0f, 0x0f, + 0x48, 0x28, 0x18, 0x10, 0x48, 0x10, 0x0f, 0x10, 0x07, 0x07, 0x17, 0x10, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x48, 0x00, 0x4f, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x08, + 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x08, 0x08, 0x4f, + 0x4f, 0x00, 0x08, 0x0f, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, + 0x47, 0x47, 0x00, 0x47, + 0x47, 0x07, 0x47, 0x57, 0x47, 0x00, 0x4f, 0x5f, 0x57, 0x4f, 0x00, 0x08, + 0x08, 0x08, 0x47, 0x47, + 0x00, 0x47, 0x47, 0x07, 0x47, 0x57, 0x47, 0x00, 0x4f, 0x5f, 0x57, 0x4f, + 0x00, 0x08, 0x08, 0x08, + 0x18, 0x50, 0x28, 0x4f, 0x4f, 0x4f, 0x47, 0x47, 0x47, 0x00, 0x00, 0x08, + 0x00, 0x10, 0x47, 0x4f, + 0x27, 0x07, 0x47, 0x10, 0x47, 0x4f, 0x27, 0x07, 0x47, 0x10, 0x47, 0x4f, + 0x27, 0x07, 0x47, 0x47, + 0x00, 0x0f, 0x0f, 0x0f, 0x18, 0x0f, 0x18, 0x07, 0x18, 0x00, 0x4f, 0x18, + 0x00, 0x4f, 0x40, 0x40, + 0x47, 0x10, 0x10, 0x08, 0x47, 0x0f, 0x08, 0x00, 0x07, 0x28, 0x27, 0x10, + 0x00, 0x10, 0x10, 0x0f, + 0x47, 0x27, 0x17, 0x0f, 0x47, 0x0f, 0x10, 0x0f, 0x08, 0x07, 0x18, 0x0f, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x49, 0x00, 0x4f, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x0a, + 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x08, 0x08, 0x4e, + 0x4f, 0x01, 0x08, 0x0f, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, + 0x46, 0x46, 0x00, 0x47, + 0x47, 0x07, 0x47, 0x57, 0x47, 0x01, 0x4e, 0x5f, 0x57, 0x4e, 0x02, 0x09, + 0x08, 0x0a, 0x46, 0x46, + 0x00, 0x47, 0x47, 0x07, 0x47, 0x57, 0x47, 0x01, 0x4e, 0x5f, 0x57, 0x4e, + 0x02, 0x09, 0x08, 0x0a, + 0x19, 0x50, 0x28, 0x4f, 0x4e, 0x4e, 0x47, 0x46, 0x46, 0x01, 0x00, 0x09, + 0x00, 0x11, 0x47, 0x4f, + 0x27, 0x07, 0x47, 0x11, 0x47, 0x4f, 0x27, 0x07, 0x47, 0x11, 0x47, 0x4f, + 0x27, 0x07, 0x47, 0x47, + 0x00, 0x0f, 0x0f, 0x0f, 0x18, 0x0f, 0x18, 0x07, 0x18, 0x00, 0x4e, 0x18, + 0x00, 0x4e, 0x40, 0x40, + 0x47, 0x11, 0x10, 0x08, 0x47, 0x0f, 0x08, 0x00, 0x07, 0x2a, 0x27, 0x11, + 0x00, 0x11, 0x10, 0x0f, + 0x47, 0x27, 0x17, 0x0f, 0x47, 0x0d, 0x10, 0x0e, 0x08, 0x07, 0x18, 0x0f, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x4a, 0x00, 0x4f, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x41, 0x40, + 0x40, 0x40, 0x41, 0x0c, + 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x08, 0x08, 0x4d, + 0x4f, 0x02, 0x08, 0x0e, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, + 0x45, 0x45, 0x01, 0x46, + 0x47, 0x07, 0x46, 0x56, 0x47, 0x02, 0x4d, 0x5f, 0x56, 0x4d, 0x03, 0x0a, + 0x09, 0x0c, 0x45, 0x45, + 0x01, 0x46, 0x47, 0x07, 0x46, 0x56, 0x47, 0x02, 0x4d, 0x5f, 0x56, 0x4d, + 0x03, 0x0a, 0x09, 0x0c, + 0x1a, 0x50, 0x28, 0x4f, 0x4d, 0x4d, 0x46, 0x45, 0x45, 0x02, 0x01, 0x0a, + 0x01, 0x12, 0x46, 0x4f, + 0x26, 0x07, 0x46, 0x12, 0x46, 0x4f, 0x26, 0x07, 0x46, 0x12, 0x46, 0x4f, + 0x26, 0x07, 0x46, 0x47, + 0x00, 0x0e, 0x0e, 0x0f, 0x18, 0x0f, 0x18, 0x07, 0x18, 0x00, 0x4d, 0x18, + 0x00, 0x4d, 0x40, 0x40, + 0x47, 0x12, 0x10, 0x08, 0x47, 0x0f, 0x08, 0x00, 0x07, 0x2b, 0x27, 0x12, + 0x00, 0x12, 0x11, 0x0f, + 0x47, 0x26, 0x17, 0x0e, 0x47, 0x0c, 0x11, 0x0d, 0x08, 0x07, 0x18, 0x0f, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x4b, 0x01, 0x4e, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x42, 0x40, + 0x40, 0x40, 0x42, 0x0e, + 0x01, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x09, 0x09, 0x4c, + 0x4e, 0x04, 0x09, 0x0d, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x01, 0x01, + 0x44, 0x44, 0x02, 0x45, + 0x46, 0x07, 0x45, 0x55, 0x46, 0x03, 0x4c, 0x5e, 0x55, 0x4c, 0x05, 0x0b, + 0x0a, 0x0e, 0x44, 0x44, + 0x02, 0x45, 0x46, 0x07, 0x45, 0x55, 0x46, 0x03, 0x4c, 0x5e, 0x55, 0x4c, + 0x05, 0x0b, 0x0a, 0x0e, + 0x1c, 0x51, 0x29, 0x4e, 0x4c, 0x4c, 0x45, 0x44, 0x44, 0x04, 0x02, 0x0b, + 0x02, 0x13, 0x45, 0x4e, + 0x25, 0x07, 0x45, 0x13, 0x45, 0x4e, 0x25, 0x07, 0x45, 0x13, 0x45, 0x4e, + 0x25, 0x07, 0x45, 0x46, + 0x01, 0x0d, 0x0d, 0x0f, 0x19, 0x0f, 0x19, 0x07, 0x19, 0x01, 0x4c, 0x19, + 0x01, 0x4c, 0x40, 0x40, + 0x46, 0x14, 0x11, 0x09, 0x46, 0x0f, 0x09, 0x01, 0x07, 0x2d, 0x27, 0x14, + 0x01, 0x13, 0x12, 0x0f, + 0x46, 0x25, 0x16, 0x0d, 0x46, 0x0a, 0x12, 0x0c, 0x09, 0x07, 0x19, 0x0e, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x4c, 0x01, 0x4e, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x42, 0x40, + 0x40, 0x40, 0x42, 0x10, + 0x01, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x09, 0x09, 0x4b, + 0x4e, 0x05, 0x09, 0x0d, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x01, 0x01, + 0x43, 0x43, 0x02, 0x45, + 0x46, 0x07, 0x45, 0x55, 0x46, 0x04, 0x4b, 0x5e, 0x55, 0x4b, 0x06, 0x0c, + 0x0a, 0x10, 0x43, 0x43, + 0x02, 0x45, 0x46, 0x07, 0x45, 0x55, 0x46, 0x04, 0x4b, 0x5e, 0x55, 0x4b, + 0x06, 0x0c, 0x0a, 0x10, + 0x1d, 0x51, 0x29, 0x4e, 0x4b, 0x4b, 0x45, 0x43, 0x43, 0x05, 0x02, 0x0c, + 0x02, 0x14, 0x45, 0x4e, + 0x25, 0x07, 0x45, 0x14, 0x45, 0x4e, 0x25, 0x07, 0x45, 0x14, 0x45, 0x4e, + 0x25, 0x07, 0x45, 0x46, + 0x01, 0x0d, 0x0d, 0x0f, 0x19, 0x0f, 0x19, 0x07, 0x19, 0x01, 0x4b, 0x19, + 0x01, 0x4b, 0x40, 0x40, + 0x46, 0x15, 0x11, 0x09, 0x46, 0x0f, 0x09, 0x01, 0x07, 0x2e, 0x27, 0x15, + 0x01, 0x14, 0x12, 0x0f, + 0x46, 0x25, 0x16, 0x0d, 0x46, 0x09, 0x12, 0x0b, 0x09, 0x07, 0x19, 0x0e, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x4d, 0x01, 0x4e, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x43, 0x40, + 0x40, 0x40, 0x43, 0x12, + 0x01, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x09, 0x09, 0x4a, + 0x4e, 0x06, 0x09, 0x0c, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x01, 0x01, + 0x42, 0x42, 0x03, 0x44, + 0x46, 0x07, 0x44, 0x54, 0x46, 0x05, 0x4a, 0x5e, 0x54, 0x4a, 0x08, 0x0d, + 0x0b, 0x12, 0x42, 0x42, + 0x03, 0x44, 0x46, 0x07, 0x44, 0x54, 0x46, 0x05, 0x4a, 0x5e, 0x54, 0x4a, + 0x08, 0x0d, 0x0b, 0x12, + 0x1e, 0x51, 0x29, 0x4e, 0x4a, 0x4a, 0x44, 0x42, 0x42, 0x06, 0x03, 0x0d, + 0x03, 0x15, 0x44, 0x4e, + 0x24, 0x07, 0x44, 0x15, 0x44, 0x4e, 0x24, 0x07, 0x44, 0x15, 0x44, 0x4e, + 0x24, 0x07, 0x44, 0x46, + 0x01, 0x0c, 0x0c, 0x0f, 0x19, 0x0f, 0x19, 0x07, 0x19, 0x01, 0x4a, 0x19, + 0x01, 0x4a, 0x40, 0x40, + 0x46, 0x16, 0x11, 0x09, 0x46, 0x0f, 0x09, 0x01, 0x07, 0x30, 0x27, 0x16, + 0x01, 0x15, 0x13, 0x0f, + 0x46, 0x24, 0x16, 0x0c, 0x46, 0x07, 0x13, 0x0a, 0x09, 0x07, 0x19, 0x0e, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x4e, 0x01, 0x4e, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x44, 0x40, + 0x40, 0x40, 0x44, 0x13, + 0x01, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x09, 0x09, 0x4a, + 0x4e, 0x07, 0x09, 0x0b, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x01, 0x01, + 0x42, 0x42, 0x03, 0x44, + 0x46, 0x07, 0x44, 0x54, 0x46, 0x05, 0x4a, 0x5e, 0x54, 0x4a, 0x09, 0x0d, + 0x0b, 0x13, 0x42, 0x42, + 0x03, 0x44, 0x46, 0x07, 0x44, 0x54, 0x46, 0x05, 0x4a, 0x5e, 0x54, 0x4a, + 0x09, 0x0d, 0x0b, 0x13, + 0x1f, 0x52, 0x29, 0x4e, 0x4a, 0x4a, 0x44, 0x42, 0x42, 0x07, 0x03, 0x0d, + 0x03, 0x15, 0x44, 0x4e, + 0x23, 0x07, 0x44, 0x15, 0x44, 0x4e, 0x23, 0x07, 0x44, 0x15, 0x44, 0x4e, + 0x23, 0x07, 0x44, 0x46, + 0x01, 0x0b, 0x0b, 0x0f, 0x19, 0x0f, 0x19, 0x07, 0x19, 0x01, 0x4a, 0x19, + 0x01, 0x4a, 0x40, 0x40, + 0x46, 0x17, 0x11, 0x09, 0x46, 0x0f, 0x09, 0x01, 0x07, 0x31, 0x27, 0x17, + 0x01, 0x15, 0x13, 0x0f, + 0x46, 0x23, 0x15, 0x0b, 0x46, 0x05, 0x13, 0x09, 0x09, 0x07, 0x19, 0x0d, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x4e, 0x02, 0x4d, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x44, 0x40, + 0x40, 0x40, 0x44, 0x15, + 0x02, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x0a, 0x0a, 0x49, + 0x4d, 0x09, 0x0a, 0x0b, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x02, 0x02, + 0x41, 0x41, 0x04, 0x43, + 0x45, 0x07, 0x43, 0x53, 0x45, 0x06, 0x49, 0x5d, 0x53, 0x49, 0x0b, 0x0e, + 0x0c, 0x15, 0x41, 0x41, + 0x04, 0x43, 0x45, 0x07, 0x43, 0x53, 0x45, 0x06, 0x49, 0x5d, 0x53, 0x49, + 0x0b, 0x0e, 0x0c, 0x15, + 0x21, 0x52, 0x2a, 0x4d, 0x49, 0x49, 0x43, 0x41, 0x41, 0x09, 0x04, 0x0e, + 0x04, 0x16, 0x43, 0x4d, + 0x23, 0x07, 0x43, 0x16, 0x43, 0x4d, 0x23, 0x07, 0x43, 0x16, 0x43, 0x4d, + 0x23, 0x07, 0x43, 0x45, + 0x02, 0x0b, 0x0b, 0x0f, 0x1a, 0x0f, 0x1a, 0x07, 0x1a, 0x02, 0x49, 0x1a, + 0x02, 0x49, 0x40, 0x40, + 0x45, 0x19, 0x12, 0x0a, 0x45, 0x0f, 0x0a, 0x02, 0x07, 0x33, 0x27, 0x19, + 0x02, 0x16, 0x14, 0x0f, + 0x45, 0x23, 0x15, 0x0b, 0x45, 0x04, 0x14, 0x09, 0x0a, 0x07, 0x1a, 0x0d, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x4f, 0x02, 0x4d, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x45, 0x40, + 0x40, 0x40, 0x45, 0x17, + 0x02, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x0a, 0x0a, 0x48, + 0x4d, 0x0a, 0x0a, 0x0a, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x02, 0x02, + 0x40, 0x40, 0x05, 0x42, + 0x45, 0x07, 0x42, 0x52, 0x45, 0x07, 0x48, 0x5d, 0x52, 0x48, 0x0d, 0x0f, + 0x0d, 0x17, 0x40, 0x40, + 0x05, 0x42, 0x45, 0x07, 0x42, 0x52, 0x45, 0x07, 0x48, 0x5d, 0x52, 0x48, + 0x0d, 0x0f, 0x0d, 0x17, + 0x22, 0x52, 0x2a, 0x4d, 0x48, 0x48, 0x42, 0x40, 0x40, 0x0a, 0x05, 0x0f, + 0x05, 0x17, 0x42, 0x4d, + 0x22, 0x07, 0x42, 0x17, 0x42, 0x4d, 0x22, 0x07, 0x42, 0x17, 0x42, 0x4d, + 0x22, 0x07, 0x42, 0x45, + 0x02, 0x0a, 0x0a, 0x0f, 0x1a, 0x0f, 0x1a, 0x07, 0x1a, 0x02, 0x48, 0x1a, + 0x02, 0x48, 0x40, 0x40, + 0x45, 0x1a, 0x12, 0x0a, 0x45, 0x0f, 0x0a, 0x02, 0x07, 0x35, 0x27, 0x1a, + 0x02, 0x17, 0x15, 0x0f, + 0x45, 0x22, 0x15, 0x0a, 0x45, 0x02, 0x15, 0x08, 0x0a, 0x07, 0x1a, 0x0d, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x50, 0x02, 0x4d, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x45, 0x40, + 0x40, 0x40, 0x45, 0x19, + 0x02, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x0a, 0x0a, 0x47, + 0x4d, 0x0b, 0x0a, 0x0a, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x02, 0x02, + 0x00, 0x00, 0x05, 0x42, + 0x45, 0x07, 0x42, 0x52, 0x45, 0x08, 0x47, 0x5d, 0x52, 0x47, 0x0e, 0x10, + 0x0d, 0x19, 0x00, 0x00, + 0x05, 0x42, 0x45, 0x07, 0x42, 0x52, 0x45, 0x08, 0x47, 0x5d, 0x52, 0x47, + 0x0e, 0x10, 0x0d, 0x19, + 0x23, 0x52, 0x2a, 0x4d, 0x47, 0x47, 0x42, 0x00, 0x00, 0x0b, 0x05, 0x10, + 0x05, 0x18, 0x42, 0x4d, + 0x22, 0x07, 0x42, 0x18, 0x42, 0x4d, 0x22, 0x07, 0x42, 0x18, 0x42, 0x4d, + 0x22, 0x07, 0x42, 0x45, + 0x02, 0x0a, 0x0a, 0x0f, 0x1a, 0x0f, 0x1a, 0x07, 0x1a, 0x02, 0x47, 0x1a, + 0x02, 0x47, 0x40, 0x40, + 0x45, 0x1b, 0x12, 0x0a, 0x45, 0x0f, 0x0a, 0x02, 0x07, 0x36, 0x27, 0x1b, + 0x02, 0x18, 0x15, 0x0f, + 0x45, 0x22, 0x15, 0x0a, 0x45, 0x01, 0x15, 0x07, 0x0a, 0x07, 0x1a, 0x0d, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x51, 0x03, 0x4c, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x46, 0x40, + 0x40, 0x40, 0x46, 0x1b, + 0x03, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x0b, 0x0b, 0x46, + 0x4c, 0x0c, 0x0b, 0x09, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x03, 0x03, + 0x01, 0x01, 0x06, 0x41, + 0x44, 0x07, 0x41, 0x51, 0x44, 0x09, 0x46, 0x5c, 0x51, 0x46, 0x10, 0x11, + 0x0e, 0x1b, 0x01, 0x01, + 0x06, 0x41, 0x44, 0x07, 0x41, 0x51, 0x44, 0x09, 0x46, 0x5c, 0x51, 0x46, + 0x10, 0x11, 0x0e, 0x1b, + 0x24, 0x53, 0x2b, 0x4c, 0x46, 0x46, 0x41, 0x01, 0x01, 0x0c, 0x06, 0x11, + 0x06, 0x19, 0x41, 0x4c, + 0x21, 0x07, 0x41, 0x19, 0x41, 0x4c, 0x21, 0x07, 0x41, 0x19, 0x41, 0x4c, + 0x21, 0x07, 0x41, 0x44, + 0x03, 0x09, 0x09, 0x0f, 0x1b, 0x0f, 0x1b, 0x07, 0x1b, 0x03, 0x46, 0x1b, + 0x03, 0x46, 0x40, 0x40, + 0x44, 0x1c, 0x13, 0x0b, 0x44, 0x0f, 0x0b, 0x03, 0x07, 0x38, 0x27, 0x1c, + 0x03, 0x19, 0x16, 0x0f, + 0x44, 0x21, 0x14, 0x09, 0x44, 0x40, 0x16, 0x06, 0x0b, 0x07, 0x1b, 0x0c, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x52, 0x03, 0x4c, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x47, 0x40, + 0x40, 0x40, 0x47, 0x1d, + 0x03, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x0b, 0x0b, 0x45, + 0x4c, 0x0e, 0x0b, 0x08, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x03, 0x03, + 0x02, 0x02, 0x07, 0x40, + 0x44, 0x07, 0x40, 0x50, 0x44, 0x0a, 0x45, 0x5c, 0x50, 0x45, 0x11, 0x12, + 0x0f, 0x1d, 0x02, 0x02, + 0x07, 0x40, 0x44, 0x07, 0x40, 0x50, 0x44, 0x0a, 0x45, 0x5c, 0x50, 0x45, + 0x11, 0x12, 0x0f, 0x1d, + 0x26, 0x53, 0x2b, 0x4c, 0x45, 0x45, 0x40, 0x02, 0x02, 0x0e, 0x07, 0x12, + 0x07, 0x1a, 0x40, 0x4c, + 0x20, 0x07, 0x40, 0x1a, 0x40, 0x4c, 0x20, 0x07, 0x40, 0x1a, 0x40, 0x4c, + 0x20, 0x07, 0x40, 0x44, + 0x03, 0x08, 0x08, 0x0f, 0x1b, 0x0f, 0x1b, 0x07, 0x1b, 0x03, 0x45, 0x1b, + 0x03, 0x45, 0x40, 0x40, + 0x44, 0x1e, 0x13, 0x0b, 0x44, 0x0f, 0x0b, 0x03, 0x07, 0x39, 0x27, 0x1e, + 0x03, 0x1a, 0x17, 0x0f, + 0x44, 0x20, 0x14, 0x08, 0x44, 0x41, 0x17, 0x05, 0x0b, 0x07, 0x1b, 0x0c, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x53, 0x03, 0x4c, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x47, 0x40, + 0x40, 0x40, 0x47, 0x1f, + 0x03, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x0b, 0x0b, 0x44, + 0x4c, 0x0f, 0x0b, 0x08, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x03, 0x03, + 0x03, 0x03, 0x07, 0x40, + 0x44, 0x07, 0x40, 0x50, 0x44, 0x0b, 0x44, 0x5c, 0x50, 0x44, 0x13, 0x13, + 0x0f, 0x1f, 0x03, 0x03, + 0x07, 0x40, 0x44, 0x07, 0x40, 0x50, 0x44, 0x0b, 0x44, 0x5c, 0x50, 0x44, + 0x13, 0x13, 0x0f, 0x1f, + 0x27, 0x53, 0x2b, 0x4c, 0x44, 0x44, 0x40, 0x03, 0x03, 0x0f, 0x07, 0x13, + 0x07, 0x1b, 0x40, 0x4c, + 0x20, 0x07, 0x40, 0x1b, 0x40, 0x4c, 0x20, 0x07, 0x40, 0x1b, 0x40, 0x4c, + 0x20, 0x07, 0x40, 0x44, + 0x03, 0x08, 0x08, 0x0f, 0x1b, 0x0f, 0x1b, 0x07, 0x1b, 0x03, 0x44, 0x1b, + 0x03, 0x44, 0x40, 0x40, + 0x44, 0x1f, 0x13, 0x0b, 0x44, 0x0f, 0x0b, 0x03, 0x07, 0x3b, 0x27, 0x1f, + 0x03, 0x1b, 0x17, 0x0f, + 0x44, 0x20, 0x14, 0x08, 0x44, 0x43, 0x17, 0x04, 0x0b, 0x07, 0x1b, 0x0c, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x54, 0x04, 0x4b, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x48, 0x40, + 0x40, 0x40, 0x48, 0x21, + 0x04, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x0c, 0x0c, 0x43, + 0x4b, 0x10, 0x0c, 0x07, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x04, 0x04, + 0x04, 0x04, 0x08, 0x00, + 0x43, 0x07, 0x00, 0x4f, 0x43, 0x0c, 0x43, 0x5b, 0x4f, 0x43, 0x14, 0x14, + 0x10, 0x21, 0x04, 0x04, + 0x08, 0x00, 0x43, 0x07, 0x00, 0x4f, 0x43, 0x0c, 0x43, 0x5b, 0x4f, 0x43, + 0x14, 0x14, 0x10, 0x21, + 0x28, 0x54, 0x2c, 0x4b, 0x43, 0x43, 0x00, 0x04, 0x04, 0x10, 0x08, 0x14, + 0x08, 0x1c, 0x00, 0x4b, + 0x1f, 0x07, 0x00, 0x1c, 0x00, 0x4b, 0x1f, 0x07, 0x00, 0x1c, 0x00, 0x4b, + 0x1f, 0x07, 0x00, 0x43, + 0x04, 0x07, 0x07, 0x0f, 0x1c, 0x0f, 0x1c, 0x07, 0x1c, 0x04, 0x43, 0x1c, + 0x04, 0x43, 0x40, 0x40, + 0x43, 0x20, 0x14, 0x0c, 0x43, 0x0f, 0x0c, 0x04, 0x07, 0x3c, 0x27, 0x20, + 0x04, 0x1c, 0x18, 0x0f, + 0x43, 0x1f, 0x13, 0x07, 0x43, 0x44, 0x18, 0x03, 0x0c, 0x07, 0x1c, 0x0b, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x55, 0x04, 0x4b, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x49, 0x40, + 0x40, 0x40, 0x49, 0x22, + 0x04, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x0c, 0x0c, 0x42, + 0x4b, 0x11, 0x0c, 0x06, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x04, 0x04, + 0x05, 0x05, 0x08, 0x00, + 0x43, 0x07, 0x00, 0x4f, 0x43, 0x0d, 0x42, 0x5b, 0x4f, 0x42, 0x16, 0x15, + 0x10, 0x22, 0x05, 0x05, + 0x08, 0x00, 0x43, 0x07, 0x00, 0x4f, 0x43, 0x0d, 0x42, 0x5b, 0x4f, 0x42, + 0x16, 0x15, 0x10, 0x22, + 0x29, 0x54, 0x2c, 0x4b, 0x42, 0x42, 0x00, 0x05, 0x05, 0x11, 0x08, 0x15, + 0x08, 0x1d, 0x00, 0x4b, + 0x1e, 0x07, 0x00, 0x1d, 0x00, 0x4b, 0x1e, 0x07, 0x00, 0x1d, 0x00, 0x4b, + 0x1e, 0x07, 0x00, 0x43, + 0x04, 0x06, 0x06, 0x0f, 0x1c, 0x0f, 0x1c, 0x07, 0x1c, 0x04, 0x42, 0x1c, + 0x04, 0x42, 0x40, 0x40, + 0x43, 0x21, 0x14, 0x0c, 0x43, 0x0f, 0x0c, 0x04, 0x07, 0x3e, 0x27, 0x21, + 0x04, 0x1d, 0x18, 0x0f, + 0x43, 0x1e, 0x13, 0x06, 0x43, 0x46, 0x18, 0x02, 0x0c, 0x07, 0x1c, 0x0b, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x56, 0x04, 0x4b, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x49, 0x40, + 0x40, 0x40, 0x49, 0x24, + 0x04, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x0c, 0x0c, 0x41, + 0x4b, 0x13, 0x0c, 0x06, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x04, 0x04, + 0x06, 0x06, 0x09, 0x01, + 0x43, 0x07, 0x01, 0x4e, 0x43, 0x0e, 0x41, 0x5b, 0x4e, 0x41, 0x18, 0x16, + 0x11, 0x24, 0x06, 0x06, + 0x09, 0x01, 0x43, 0x07, 0x01, 0x4e, 0x43, 0x0e, 0x41, 0x5b, 0x4e, 0x41, + 0x18, 0x16, 0x11, 0x24, + 0x2b, 0x54, 0x2c, 0x4b, 0x41, 0x41, 0x01, 0x06, 0x06, 0x13, 0x09, 0x16, + 0x09, 0x1e, 0x01, 0x4b, + 0x1e, 0x07, 0x01, 0x1e, 0x01, 0x4b, 0x1e, 0x07, 0x01, 0x1e, 0x01, 0x4b, + 0x1e, 0x07, 0x01, 0x43, + 0x04, 0x06, 0x06, 0x0f, 0x1c, 0x0f, 0x1c, 0x07, 0x1c, 0x04, 0x41, 0x1c, + 0x04, 0x41, 0x40, 0x40, + 0x43, 0x23, 0x14, 0x0c, 0x43, 0x0f, 0x0c, 0x04, 0x07, 0x3e, 0x27, 0x23, + 0x04, 0x1e, 0x19, 0x0f, + 0x43, 0x1e, 0x13, 0x06, 0x43, 0x48, 0x19, 0x01, 0x0c, 0x07, 0x1c, 0x0b, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x57, 0x05, 0x4a, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x4a, 0x40, + 0x40, 0x40, 0x4a, 0x26, + 0x05, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x0d, 0x0d, 0x40, + 0x4a, 0x14, 0x0d, 0x05, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x05, 0x05, + 0x07, 0x07, 0x0a, 0x02, + 0x42, 0x07, 0x02, 0x4d, 0x42, 0x0f, 0x40, 0x5a, 0x4d, 0x40, 0x19, 0x17, + 0x12, 0x26, 0x07, 0x07, + 0x0a, 0x02, 0x42, 0x07, 0x02, 0x4d, 0x42, 0x0f, 0x40, 0x5a, 0x4d, 0x40, + 0x19, 0x17, 0x12, 0x26, + 0x2c, 0x55, 0x2d, 0x4a, 0x40, 0x40, 0x02, 0x07, 0x07, 0x14, 0x0a, 0x17, + 0x0a, 0x1f, 0x02, 0x4a, + 0x1d, 0x07, 0x02, 0x1f, 0x02, 0x4a, 0x1d, 0x07, 0x02, 0x1f, 0x02, 0x4a, + 0x1d, 0x07, 0x02, 0x42, + 0x05, 0x05, 0x05, 0x0f, 0x1d, 0x0f, 0x1d, 0x07, 0x1d, 0x05, 0x40, 0x1d, + 0x05, 0x40, 0x40, 0x40, + 0x42, 0x24, 0x15, 0x0d, 0x42, 0x0f, 0x0d, 0x05, 0x07, 0x3e, 0x27, 0x24, + 0x05, 0x1f, 0x1a, 0x0f, + 0x42, 0x1d, 0x12, 0x05, 0x42, 0x49, 0x1a, 0x00, 0x0d, 0x07, 0x1d, 0x0a, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x58, 0x05, 0x4a, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x4a, 0x40, + 0x40, 0x40, 0x4a, 0x28, + 0x05, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x0d, 0x0d, 0x00, + 0x4a, 0x15, 0x0d, 0x05, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x05, 0x05, + 0x08, 0x08, 0x0a, 0x02, + 0x42, 0x07, 0x02, 0x4d, 0x42, 0x10, 0x00, 0x5a, 0x4d, 0x00, 0x1b, 0x18, + 0x12, 0x28, 0x08, 0x08, + 0x0a, 0x02, 0x42, 0x07, 0x02, 0x4d, 0x42, 0x10, 0x00, 0x5a, 0x4d, 0x00, + 0x1b, 0x18, 0x12, 0x28, + 0x2d, 0x55, 0x2d, 0x4a, 0x00, 0x00, 0x02, 0x08, 0x08, 0x15, 0x0a, 0x18, + 0x0a, 0x20, 0x02, 0x4a, + 0x1d, 0x07, 0x02, 0x20, 0x02, 0x4a, 0x1d, 0x07, 0x02, 0x20, 0x02, 0x4a, + 0x1d, 0x07, 0x02, 0x42, + 0x05, 0x05, 0x05, 0x0f, 0x1d, 0x0f, 0x1d, 0x07, 0x1d, 0x05, 0x00, 0x1d, + 0x05, 0x00, 0x40, 0x40, + 0x42, 0x25, 0x15, 0x0d, 0x42, 0x0f, 0x0d, 0x05, 0x07, 0x3e, 0x27, 0x25, + 0x05, 0x20, 0x1a, 0x0f, + 0x42, 0x1d, 0x12, 0x05, 0x42, 0x4b, 0x1a, 0x40, 0x0d, 0x07, 0x1d, 0x0a, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x59, 0x05, 0x4a, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x4b, 0x40, + 0x40, 0x40, 0x4b, 0x2a, + 0x05, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x0d, 0x0d, 0x01, + 0x4a, 0x16, 0x0d, 0x04, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x05, 0x05, + 0x09, 0x09, 0x0b, 0x03, + 0x42, 0x07, 0x03, 0x4c, 0x42, 0x11, 0x01, 0x5a, 0x4c, 0x01, 0x1c, 0x19, + 0x13, 0x2a, 0x09, 0x09, + 0x0b, 0x03, 0x42, 0x07, 0x03, 0x4c, 0x42, 0x11, 0x01, 0x5a, 0x4c, 0x01, + 0x1c, 0x19, 0x13, 0x2a, + 0x2e, 0x55, 0x2d, 0x4a, 0x01, 0x01, 0x03, 0x09, 0x09, 0x16, 0x0b, 0x19, + 0x0b, 0x21, 0x03, 0x4a, + 0x1c, 0x07, 0x03, 0x21, 0x03, 0x4a, 0x1c, 0x07, 0x03, 0x21, 0x03, 0x4a, + 0x1c, 0x07, 0x03, 0x42, + 0x05, 0x04, 0x04, 0x0f, 0x1d, 0x0f, 0x1d, 0x07, 0x1d, 0x05, 0x01, 0x1d, + 0x05, 0x01, 0x40, 0x40, + 0x42, 0x26, 0x15, 0x0d, 0x42, 0x0f, 0x0d, 0x05, 0x07, 0x3e, 0x27, 0x26, + 0x05, 0x21, 0x1b, 0x0f, + 0x42, 0x1c, 0x12, 0x04, 0x42, 0x4c, 0x1b, 0x41, 0x0d, 0x07, 0x1d, 0x0a, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x5a, 0x06, 0x49, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x4c, 0x40, + 0x40, 0x40, 0x4c, 0x2c, + 0x06, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x0e, 0x0e, 0x02, + 0x49, 0x18, 0x0e, 0x03, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x06, 0x06, + 0x0a, 0x0a, 0x0c, 0x04, + 0x41, 0x07, 0x04, 0x4b, 0x41, 0x12, 0x02, 0x59, 0x4b, 0x02, 0x1e, 0x1a, + 0x14, 0x2c, 0x0a, 0x0a, + 0x0c, 0x04, 0x41, 0x07, 0x04, 0x4b, 0x41, 0x12, 0x02, 0x59, 0x4b, 0x02, + 0x1e, 0x1a, 0x14, 0x2c, + 0x30, 0x56, 0x2e, 0x49, 0x02, 0x02, 0x04, 0x0a, 0x0a, 0x18, 0x0c, 0x1a, + 0x0c, 0x22, 0x04, 0x49, + 0x1b, 0x07, 0x04, 0x22, 0x04, 0x49, 0x1b, 0x07, 0x04, 0x22, 0x04, 0x49, + 0x1b, 0x07, 0x04, 0x41, + 0x06, 0x03, 0x03, 0x0f, 0x1e, 0x0f, 0x1e, 0x07, 0x1e, 0x06, 0x02, 0x1e, + 0x06, 0x02, 0x40, 0x40, + 0x41, 0x28, 0x16, 0x0e, 0x41, 0x0f, 0x0e, 0x06, 0x07, 0x3e, 0x27, 0x28, + 0x06, 0x22, 0x1c, 0x0f, + 0x41, 0x1b, 0x11, 0x03, 0x41, 0x4e, 0x1c, 0x42, 0x0e, 0x07, 0x1e, 0x09, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x5b, 0x06, 0x49, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x4c, 0x40, + 0x40, 0x40, 0x4c, 0x2e, + 0x06, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x0e, 0x0e, 0x03, + 0x49, 0x19, 0x0e, 0x03, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x06, 0x06, + 0x0b, 0x0b, 0x0c, 0x04, + 0x41, 0x07, 0x04, 0x4b, 0x41, 0x13, 0x03, 0x59, 0x4b, 0x03, 0x1f, 0x1b, + 0x14, 0x2e, 0x0b, 0x0b, + 0x0c, 0x04, 0x41, 0x07, 0x04, 0x4b, 0x41, 0x13, 0x03, 0x59, 0x4b, 0x03, + 0x1f, 0x1b, 0x14, 0x2e, + 0x31, 0x56, 0x2e, 0x49, 0x03, 0x03, 0x04, 0x0b, 0x0b, 0x19, 0x0c, 0x1b, + 0x0c, 0x23, 0x04, 0x49, + 0x1b, 0x07, 0x04, 0x23, 0x04, 0x49, 0x1b, 0x07, 0x04, 0x23, 0x04, 0x49, + 0x1b, 0x07, 0x04, 0x41, + 0x06, 0x03, 0x03, 0x0f, 0x1e, 0x0f, 0x1e, 0x07, 0x1e, 0x06, 0x03, 0x1e, + 0x06, 0x03, 0x40, 0x40, + 0x41, 0x29, 0x16, 0x0e, 0x41, 0x0f, 0x0e, 0x06, 0x07, 0x3e, 0x27, 0x29, + 0x06, 0x23, 0x1c, 0x0f, + 0x41, 0x1b, 0x11, 0x03, 0x41, 0x4f, 0x1c, 0x43, 0x0e, 0x07, 0x1e, 0x09, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x5c, 0x06, 0x49, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x4d, 0x40, + 0x40, 0x40, 0x4d, 0x30, + 0x06, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x0e, 0x0e, 0x04, + 0x49, 0x1a, 0x0e, 0x02, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x06, 0x06, + 0x0c, 0x0c, 0x0d, 0x05, + 0x41, 0x07, 0x05, 0x4a, 0x41, 0x14, 0x04, 0x59, 0x4a, 0x04, 0x21, 0x1c, + 0x15, 0x30, 0x0c, 0x0c, + 0x0d, 0x05, 0x41, 0x07, 0x05, 0x4a, 0x41, 0x14, 0x04, 0x59, 0x4a, 0x04, + 0x21, 0x1c, 0x15, 0x30, + 0x32, 0x56, 0x2e, 0x49, 0x04, 0x04, 0x05, 0x0c, 0x0c, 0x1a, 0x0d, 0x1c, + 0x0d, 0x24, 0x05, 0x49, + 0x1a, 0x07, 0x05, 0x24, 0x05, 0x49, 0x1a, 0x07, 0x05, 0x24, 0x05, 0x49, + 0x1a, 0x07, 0x05, 0x41, + 0x06, 0x02, 0x02, 0x0f, 0x1e, 0x0f, 0x1e, 0x07, 0x1e, 0x06, 0x04, 0x1e, + 0x06, 0x04, 0x40, 0x40, + 0x41, 0x2a, 0x16, 0x0e, 0x41, 0x0f, 0x0e, 0x06, 0x07, 0x3e, 0x27, 0x2a, + 0x06, 0x24, 0x1d, 0x0f, + 0x41, 0x1a, 0x11, 0x02, 0x41, 0x51, 0x1d, 0x44, 0x0e, 0x07, 0x1e, 0x09, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x5d, 0x06, 0x49, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x4e, 0x40, + 0x40, 0x40, 0x4e, 0x31, + 0x06, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x0e, 0x0e, 0x04, + 0x49, 0x1b, 0x0e, 0x01, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x06, 0x06, + 0x0c, 0x0c, 0x0d, 0x05, + 0x41, 0x07, 0x05, 0x4a, 0x41, 0x14, 0x04, 0x59, 0x4a, 0x04, 0x22, 0x1c, + 0x15, 0x31, 0x0c, 0x0c, + 0x0d, 0x05, 0x41, 0x07, 0x05, 0x4a, 0x41, 0x14, 0x04, 0x59, 0x4a, 0x04, + 0x22, 0x1c, 0x15, 0x31, + 0x33, 0x57, 0x2e, 0x49, 0x04, 0x04, 0x05, 0x0c, 0x0c, 0x1b, 0x0d, 0x1c, + 0x0d, 0x24, 0x05, 0x49, + 0x19, 0x07, 0x05, 0x24, 0x05, 0x49, 0x19, 0x07, 0x05, 0x24, 0x05, 0x49, + 0x19, 0x07, 0x05, 0x41, + 0x06, 0x01, 0x01, 0x0f, 0x1e, 0x0f, 0x1e, 0x07, 0x1e, 0x06, 0x04, 0x1e, + 0x06, 0x04, 0x40, 0x40, + 0x41, 0x2b, 0x16, 0x0e, 0x41, 0x0f, 0x0e, 0x06, 0x07, 0x3e, 0x27, 0x2b, + 0x06, 0x24, 0x1d, 0x0f, + 0x41, 0x19, 0x10, 0x01, 0x41, 0x53, 0x1d, 0x45, 0x0e, 0x07, 0x1e, 0x08, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x5d, 0x07, 0x48, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x4e, 0x40, + 0x40, 0x40, 0x4e, 0x33, + 0x07, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x0f, 0x0f, 0x05, + 0x48, 0x1d, 0x0f, 0x01, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x07, + 0x0d, 0x0d, 0x0e, 0x06, + 0x40, 0x07, 0x06, 0x49, 0x40, 0x15, 0x05, 0x58, 0x49, 0x05, 0x24, 0x1d, + 0x16, 0x33, 0x0d, 0x0d, + 0x0e, 0x06, 0x40, 0x07, 0x06, 0x49, 0x40, 0x15, 0x05, 0x58, 0x49, 0x05, + 0x24, 0x1d, 0x16, 0x33, + 0x35, 0x57, 0x2f, 0x48, 0x05, 0x05, 0x06, 0x0d, 0x0d, 0x1d, 0x0e, 0x1d, + 0x0e, 0x25, 0x06, 0x48, + 0x19, 0x07, 0x06, 0x25, 0x06, 0x48, 0x19, 0x07, 0x06, 0x25, 0x06, 0x48, + 0x19, 0x07, 0x06, 0x40, + 0x07, 0x01, 0x01, 0x0f, 0x1f, 0x0f, 0x1f, 0x07, 0x1f, 0x07, 0x05, 0x1f, + 0x07, 0x05, 0x40, 0x40, + 0x40, 0x2d, 0x17, 0x0f, 0x40, 0x0f, 0x0f, 0x07, 0x07, 0x3e, 0x27, 0x2d, + 0x07, 0x25, 0x1e, 0x0f, + 0x40, 0x19, 0x10, 0x01, 0x40, 0x54, 0x1e, 0x45, 0x0f, 0x07, 0x1f, 0x08, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x5e, 0x07, 0x48, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x4f, 0x40, + 0x40, 0x40, 0x4f, 0x35, + 0x07, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x0f, 0x0f, 0x06, + 0x48, 0x1e, 0x0f, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x07, + 0x0e, 0x0e, 0x0f, 0x07, + 0x40, 0x07, 0x07, 0x48, 0x40, 0x16, 0x06, 0x58, 0x48, 0x06, 0x26, 0x1e, + 0x17, 0x35, 0x0e, 0x0e, + 0x0f, 0x07, 0x40, 0x07, 0x07, 0x48, 0x40, 0x16, 0x06, 0x58, 0x48, 0x06, + 0x26, 0x1e, 0x17, 0x35, + 0x36, 0x57, 0x2f, 0x48, 0x06, 0x06, 0x07, 0x0e, 0x0e, 0x1e, 0x0f, 0x1e, + 0x0f, 0x26, 0x07, 0x48, + 0x18, 0x07, 0x07, 0x26, 0x07, 0x48, 0x18, 0x07, 0x07, 0x26, 0x07, 0x48, + 0x18, 0x07, 0x07, 0x40, + 0x07, 0x00, 0x00, 0x0f, 0x1f, 0x0f, 0x1f, 0x07, 0x1f, 0x07, 0x06, 0x1f, + 0x07, 0x06, 0x40, 0x40, + 0x40, 0x2e, 0x17, 0x0f, 0x40, 0x0f, 0x0f, 0x07, 0x07, 0x3e, 0x27, 0x2e, + 0x07, 0x26, 0x1f, 0x0f, + 0x40, 0x18, 0x10, 0x00, 0x40, 0x56, 0x1f, 0x46, 0x0f, 0x07, 0x1f, 0x08, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x5f, 0x07, 0x48, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x4f, 0x40, + 0x40, 0x40, 0x4f, 0x37, + 0x07, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x07, 0x0f, 0x0f, 0x07, + 0x48, 0x1f, 0x0f, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x07, + 0x0f, 0x0f, 0x0f, 0x07, + 0x40, 0x07, 0x07, 0x48, 0x40, 0x17, 0x07, 0x58, 0x48, 0x07, 0x27, 0x1f, + 0x17, 0x37, 0x0f, 0x0f, + 0x0f, 0x07, 0x40, 0x07, 0x07, 0x48, 0x40, 0x17, 0x07, 0x58, 0x48, 0x07, + 0x27, 0x1f, 0x17, 0x37, + 0x37, 0x57, 0x2f, 0x48, 0x07, 0x07, 0x07, 0x0f, 0x0f, 0x1f, 0x0f, 0x1f, + 0x0f, 0x27, 0x07, 0x48, + 0x18, 0x07, 0x07, 0x27, 0x07, 0x48, 0x18, 0x07, 0x07, 0x27, 0x07, 0x48, + 0x18, 0x07, 0x07, 0x40, + 0x07, 0x00, 0x00, 0x0f, 0x1f, 0x0f, 0x1f, 0x07, 0x1f, 0x07, 0x07, 0x1f, + 0x07, 0x07, 0x40, 0x40, + 0x40, 0x2f, 0x17, 0x0f, 0x40, 0x0f, 0x0f, 0x07, 0x07, 0x3e, 0x27, 0x2f, + 0x07, 0x27, 0x1f, 0x0f, + 0x40, 0x18, 0x10, 0x00, 0x40, 0x57, 0x1f, 0x47, 0x0f, 0x07, 0x1f, 0x08, + 0x0f, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x07, 0x48, 0x48, 0x60, 0x40, 0x27, 0x07, 0x07, 0x27, 0x40, 0x48, + 0x40, 0x40, 0x40, 0x0f, + 0x48, 0x68, 0x60, 0x40, 0x68, 0x68, 0x68, 0x68, 0x68, 0x07, 0x07, 0x0f, + 0x50, 0x40, 0x60, 0x07, + 0x68, 0x27, 0x48, 0x17, 0x40, 0x50, 0x1f, 0x40, 0x40, 0x40, 0x48, 0x48, + 0x58, 0x60, 0x60, 0x60, + 0x68, 0x68, 0x58, 0x68, 0x60, 0x60, 0x60, 0x68, 0x68, 0x68, 0x60, 0x50, + 0x48, 0x50, 0x58, 0x60, + 0x60, 0x60, 0x68, 0x68, 0x58, 0x68, 0x60, 0x60, 0x60, 0x68, 0x68, 0x68, + 0x60, 0x50, 0x48, 0x50, + 0x07, 0x50, 0x58, 0x40, 0x48, 0x40, 0x48, 0x07, 0x48, 0x48, 0x48, 0x68, + 0x07, 0x1f, 0x17, 0x50, + 0x0f, 0x07, 0x40, 0x1f, 0x17, 0x50, 0x0f, 0x07, 0x40, 0x1f, 0x17, 0x50, + 0x0f, 0x07, 0x40, 0x40, + 0x07, 0x48, 0x48, 0x48, 0x07, 0x48, 0x07, 0x17, 0x17, 0x17, 0x50, 0x17, + 0x17, 0x50, 0x40, 0x40, + 0x40, 0x2f, 0x2f, 0x17, 0x40, 0x0f, 0x17, 0x1f, 0x1f, 0x1f, 0x27, 0x0f, + 0x07, 0x07, 0x0f, 0x07, + 0x07, 0x3e, 0x1f, 0x17, 0x40, 0x17, 0x07, 0x1f, 0x48, 0x17, 0x48, 0x40, + 0x48, 0x17, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x07, 0x47, 0x47, 0x5f, 0x40, 0x27, 0x07, 0x07, 0x27, 0x40, 0x47, + 0x40, 0x40, 0x40, 0x0f, + 0x47, 0x66, 0x5f, 0x00, 0x66, 0x66, 0x66, 0x65, 0x65, 0x07, 0x07, 0x0f, + 0x4f, 0x00, 0x5e, 0x07, + 0x67, 0x27, 0x47, 0x17, 0x40, 0x4f, 0x1f, 0x40, 0x40, 0x40, 0x47, 0x47, + 0x57, 0x5f, 0x5e, 0x5f, + 0x66, 0x66, 0x57, 0x67, 0x5f, 0x5e, 0x5f, 0x67, 0x67, 0x66, 0x5e, 0x4f, + 0x47, 0x4f, 0x57, 0x5f, + 0x5e, 0x5f, 0x66, 0x66, 0x57, 0x67, 0x5f, 0x5e, 0x5f, 0x67, 0x67, 0x66, + 0x5e, 0x4f, 0x47, 0x4f, + 0x08, 0x4f, 0x56, 0x40, 0x48, 0x40, 0x47, 0x07, 0x47, 0x47, 0x47, 0x66, + 0x07, 0x1f, 0x17, 0x4f, + 0x10, 0x07, 0x40, 0x1f, 0x17, 0x4f, 0x10, 0x07, 0x40, 0x1f, 0x17, 0x4f, + 0x10, 0x07, 0x40, 0x40, + 0x07, 0x47, 0x47, 0x47, 0x08, 0x47, 0x08, 0x17, 0x17, 0x17, 0x4f, 0x17, + 0x17, 0x4f, 0x40, 0x40, + 0x40, 0x2f, 0x2f, 0x17, 0x40, 0x0f, 0x17, 0x1f, 0x1f, 0x20, 0x27, 0x10, + 0x07, 0x08, 0x10, 0x08, + 0x07, 0x3e, 0x1f, 0x17, 0x40, 0x17, 0x08, 0x1f, 0x47, 0x17, 0x46, 0x00, + 0x47, 0x17, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x06, 0x46, 0x47, 0x5e, 0x40, 0x26, 0x06, 0x06, 0x27, 0x40, 0x47, + 0x40, 0x40, 0x40, 0x0f, + 0x47, 0x64, 0x5e, 0x01, 0x65, 0x64, 0x64, 0x63, 0x63, 0x07, 0x07, 0x0f, + 0x4e, 0x00, 0x5d, 0x07, + 0x66, 0x27, 0x46, 0x17, 0x40, 0x4f, 0x1e, 0x40, 0x40, 0x40, 0x47, 0x47, + 0x56, 0x5e, 0x5d, 0x5e, + 0x65, 0x64, 0x56, 0x66, 0x5e, 0x5c, 0x5e, 0x66, 0x66, 0x65, 0x5d, 0x4e, + 0x46, 0x4e, 0x56, 0x5e, + 0x5d, 0x5e, 0x65, 0x64, 0x56, 0x66, 0x5e, 0x5c, 0x5e, 0x66, 0x66, 0x65, + 0x5d, 0x4e, 0x46, 0x4e, + 0x09, 0x4f, 0x54, 0x40, 0x48, 0x40, 0x47, 0x07, 0x47, 0x46, 0x46, 0x64, + 0x07, 0x1f, 0x16, 0x4f, + 0x10, 0x07, 0x40, 0x1f, 0x16, 0x4f, 0x10, 0x07, 0x40, 0x1f, 0x16, 0x4f, + 0x10, 0x07, 0x40, 0x40, + 0x07, 0x46, 0x46, 0x46, 0x09, 0x46, 0x09, 0x17, 0x17, 0x16, 0x4f, 0x17, + 0x16, 0x4f, 0x40, 0x40, + 0x40, 0x2e, 0x2e, 0x17, 0x40, 0x0f, 0x17, 0x1e, 0x1e, 0x20, 0x27, 0x10, + 0x07, 0x09, 0x10, 0x08, + 0x07, 0x3e, 0x1f, 0x17, 0x40, 0x17, 0x08, 0x1e, 0x46, 0x17, 0x45, 0x01, + 0x46, 0x17, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x06, 0x45, 0x47, 0x5e, 0x40, 0x25, 0x06, 0x05, 0x27, 0x40, 0x47, + 0x40, 0x40, 0x40, 0x0f, + 0x47, 0x63, 0x5d, 0x01, 0x64, 0x63, 0x62, 0x60, 0x60, 0x07, 0x07, 0x0f, + 0x4e, 0x00, 0x5c, 0x07, + 0x65, 0x27, 0x45, 0x17, 0x40, 0x4f, 0x1d, 0x40, 0x40, 0x40, 0x47, 0x47, + 0x56, 0x5d, 0x5c, 0x5d, + 0x64, 0x63, 0x56, 0x65, 0x5d, 0x5b, 0x5d, 0x65, 0x65, 0x64, 0x5c, 0x4d, + 0x46, 0x4d, 0x56, 0x5d, + 0x5c, 0x5d, 0x64, 0x63, 0x56, 0x65, 0x5d, 0x5b, 0x5d, 0x65, 0x65, 0x64, + 0x5c, 0x4d, 0x46, 0x4d, + 0x09, 0x4f, 0x52, 0x40, 0x48, 0x40, 0x47, 0x07, 0x47, 0x46, 0x46, 0x62, + 0x07, 0x1f, 0x16, 0x4f, + 0x10, 0x07, 0x40, 0x1f, 0x16, 0x4f, 0x10, 0x07, 0x40, 0x1f, 0x16, 0x4f, + 0x10, 0x07, 0x40, 0x40, + 0x07, 0x46, 0x46, 0x45, 0x09, 0x45, 0x09, 0x17, 0x17, 0x16, 0x4f, 0x17, + 0x16, 0x4f, 0x40, 0x40, + 0x40, 0x2d, 0x2d, 0x17, 0x40, 0x0f, 0x17, 0x1e, 0x1e, 0x20, 0x27, 0x10, + 0x07, 0x09, 0x10, 0x08, + 0x07, 0x3d, 0x1f, 0x17, 0x40, 0x17, 0x08, 0x1e, 0x45, 0x17, 0x44, 0x01, + 0x45, 0x17, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x05, 0x44, 0x46, 0x5d, 0x40, 0x24, 0x05, 0x04, 0x27, 0x40, 0x46, + 0x40, 0x40, 0x40, 0x0f, + 0x46, 0x61, 0x5c, 0x02, 0x63, 0x61, 0x60, 0x5e, 0x5e, 0x07, 0x07, 0x0e, + 0x4d, 0x01, 0x5b, 0x07, + 0x64, 0x27, 0x44, 0x16, 0x40, 0x4e, 0x1c, 0x40, 0x40, 0x40, 0x46, 0x46, + 0x55, 0x5c, 0x5b, 0x5c, + 0x63, 0x61, 0x55, 0x64, 0x5c, 0x59, 0x5c, 0x64, 0x64, 0x63, 0x5b, 0x4c, + 0x45, 0x4c, 0x55, 0x5c, + 0x5b, 0x5c, 0x63, 0x61, 0x55, 0x64, 0x5c, 0x59, 0x5c, 0x64, 0x64, 0x63, + 0x5b, 0x4c, 0x45, 0x4c, + 0x0a, 0x4e, 0x50, 0x40, 0x48, 0x40, 0x46, 0x07, 0x46, 0x45, 0x45, 0x60, + 0x07, 0x1e, 0x15, 0x4e, + 0x11, 0x07, 0x40, 0x1e, 0x15, 0x4e, 0x11, 0x07, 0x40, 0x1e, 0x15, 0x4e, + 0x11, 0x07, 0x40, 0x41, + 0x07, 0x45, 0x45, 0x44, 0x0a, 0x44, 0x0a, 0x16, 0x17, 0x15, 0x4e, 0x17, + 0x15, 0x4e, 0x40, 0x40, + 0x40, 0x2c, 0x2c, 0x16, 0x40, 0x0f, 0x16, 0x1d, 0x1d, 0x21, 0x27, 0x11, + 0x07, 0x0a, 0x11, 0x09, + 0x06, 0x3c, 0x1e, 0x16, 0x40, 0x16, 0x09, 0x1d, 0x44, 0x16, 0x43, 0x02, + 0x44, 0x16, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x04, 0x43, 0x46, 0x5c, 0x40, 0x23, 0x04, 0x03, 0x27, 0x40, 0x46, + 0x40, 0x40, 0x40, 0x0f, + 0x46, 0x60, 0x5b, 0x03, 0x61, 0x60, 0x5e, 0x5b, 0x5b, 0x07, 0x07, 0x0e, + 0x4c, 0x01, 0x59, 0x07, + 0x63, 0x27, 0x43, 0x16, 0x40, 0x4e, 0x1b, 0x40, 0x40, 0x40, 0x46, 0x46, + 0x54, 0x5b, 0x59, 0x5b, + 0x61, 0x60, 0x54, 0x63, 0x5b, 0x58, 0x5b, 0x63, 0x63, 0x61, 0x59, 0x4b, + 0x44, 0x4b, 0x54, 0x5b, + 0x59, 0x5b, 0x61, 0x60, 0x54, 0x63, 0x5b, 0x58, 0x5b, 0x63, 0x63, 0x61, + 0x59, 0x4b, 0x44, 0x4b, + 0x0b, 0x4e, 0x4e, 0x40, 0x48, 0x40, 0x46, 0x07, 0x46, 0x44, 0x44, 0x5e, + 0x07, 0x1e, 0x14, 0x4e, + 0x11, 0x07, 0x40, 0x1e, 0x14, 0x4e, 0x11, 0x07, 0x40, 0x1e, 0x14, 0x4e, + 0x11, 0x07, 0x40, 0x41, + 0x07, 0x44, 0x44, 0x43, 0x0b, 0x43, 0x0b, 0x16, 0x17, 0x14, 0x4e, 0x17, + 0x14, 0x4e, 0x40, 0x40, + 0x40, 0x2b, 0x2b, 0x16, 0x40, 0x0f, 0x16, 0x1c, 0x1c, 0x21, 0x27, 0x11, + 0x07, 0x0b, 0x11, 0x09, + 0x06, 0x3b, 0x1e, 0x16, 0x40, 0x16, 0x09, 0x1c, 0x43, 0x16, 0x41, 0x03, + 0x43, 0x16, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x04, 0x42, 0x46, 0x5c, 0x40, 0x22, 0x04, 0x02, 0x27, 0x40, 0x46, + 0x40, 0x40, 0x40, 0x0f, + 0x46, 0x5e, 0x5a, 0x03, 0x60, 0x5e, 0x5c, 0x59, 0x59, 0x07, 0x07, 0x0e, + 0x4c, 0x01, 0x58, 0x07, + 0x62, 0x27, 0x42, 0x16, 0x40, 0x4e, 0x1a, 0x40, 0x40, 0x40, 0x46, 0x46, + 0x54, 0x5a, 0x58, 0x5a, + 0x60, 0x5e, 0x54, 0x62, 0x5a, 0x56, 0x5a, 0x62, 0x62, 0x60, 0x58, 0x4a, + 0x44, 0x4a, 0x54, 0x5a, + 0x58, 0x5a, 0x60, 0x5e, 0x54, 0x62, 0x5a, 0x56, 0x5a, 0x62, 0x62, 0x60, + 0x58, 0x4a, 0x44, 0x4a, + 0x0b, 0x4e, 0x4c, 0x40, 0x48, 0x40, 0x46, 0x07, 0x46, 0x44, 0x44, 0x5c, + 0x07, 0x1e, 0x14, 0x4e, + 0x11, 0x07, 0x40, 0x1e, 0x14, 0x4e, 0x11, 0x07, 0x40, 0x1e, 0x14, 0x4e, + 0x11, 0x07, 0x40, 0x41, + 0x07, 0x44, 0x44, 0x42, 0x0b, 0x42, 0x0b, 0x16, 0x17, 0x14, 0x4e, 0x17, + 0x14, 0x4e, 0x40, 0x40, + 0x40, 0x2a, 0x2a, 0x16, 0x40, 0x0f, 0x16, 0x1c, 0x1c, 0x21, 0x27, 0x11, + 0x07, 0x0b, 0x11, 0x09, + 0x06, 0x3a, 0x1e, 0x16, 0x40, 0x16, 0x09, 0x1c, 0x42, 0x16, 0x40, 0x03, + 0x42, 0x16, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x03, 0x41, 0x45, 0x5b, 0x40, 0x21, 0x03, 0x01, 0x27, 0x40, 0x45, + 0x40, 0x40, 0x40, 0x0f, + 0x45, 0x5d, 0x59, 0x04, 0x5f, 0x5d, 0x5a, 0x56, 0x56, 0x07, 0x07, 0x0d, + 0x4b, 0x02, 0x57, 0x07, + 0x61, 0x27, 0x41, 0x15, 0x40, 0x4d, 0x19, 0x40, 0x40, 0x40, 0x45, 0x45, + 0x53, 0x59, 0x57, 0x59, + 0x5f, 0x5d, 0x53, 0x61, 0x59, 0x55, 0x59, 0x61, 0x61, 0x5f, 0x57, 0x49, + 0x43, 0x49, 0x53, 0x59, + 0x57, 0x59, 0x5f, 0x5d, 0x53, 0x61, 0x59, 0x55, 0x59, 0x61, 0x61, 0x5f, + 0x57, 0x49, 0x43, 0x49, + 0x0c, 0x4d, 0x4a, 0x40, 0x48, 0x40, 0x45, 0x07, 0x45, 0x43, 0x43, 0x5a, + 0x07, 0x1d, 0x13, 0x4d, + 0x12, 0x07, 0x40, 0x1d, 0x13, 0x4d, 0x12, 0x07, 0x40, 0x1d, 0x13, 0x4d, + 0x12, 0x07, 0x40, 0x42, + 0x07, 0x43, 0x43, 0x41, 0x0c, 0x41, 0x0c, 0x15, 0x17, 0x13, 0x4d, 0x17, + 0x13, 0x4d, 0x40, 0x40, + 0x40, 0x29, 0x29, 0x15, 0x40, 0x0f, 0x15, 0x1b, 0x1b, 0x22, 0x27, 0x12, + 0x07, 0x0c, 0x12, 0x0a, + 0x05, 0x39, 0x1d, 0x15, 0x40, 0x15, 0x0a, 0x1b, 0x41, 0x15, 0x00, 0x04, + 0x41, 0x15, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x02, 0x40, 0x45, 0x5b, 0x40, 0x20, 0x02, 0x00, 0x27, 0x40, 0x45, + 0x40, 0x40, 0x40, 0x0f, + 0x45, 0x5b, 0x58, 0x04, 0x5e, 0x5b, 0x59, 0x54, 0x54, 0x07, 0x07, 0x0d, + 0x4b, 0x02, 0x56, 0x07, + 0x60, 0x27, 0x40, 0x15, 0x40, 0x4d, 0x18, 0x40, 0x40, 0x40, 0x45, 0x45, + 0x53, 0x58, 0x56, 0x58, + 0x5e, 0x5b, 0x53, 0x60, 0x58, 0x53, 0x58, 0x60, 0x60, 0x5e, 0x56, 0x48, + 0x43, 0x48, 0x53, 0x58, + 0x56, 0x58, 0x5e, 0x5b, 0x53, 0x60, 0x58, 0x53, 0x58, 0x60, 0x60, 0x5e, + 0x56, 0x48, 0x43, 0x48, + 0x0c, 0x4d, 0x49, 0x40, 0x48, 0x40, 0x45, 0x07, 0x45, 0x43, 0x43, 0x59, + 0x07, 0x1d, 0x12, 0x4d, + 0x12, 0x07, 0x40, 0x1d, 0x12, 0x4d, 0x12, 0x07, 0x40, 0x1d, 0x12, 0x4d, + 0x12, 0x07, 0x40, 0x42, + 0x07, 0x43, 0x43, 0x40, 0x0c, 0x40, 0x0c, 0x15, 0x17, 0x12, 0x4d, 0x17, + 0x12, 0x4d, 0x40, 0x40, + 0x40, 0x28, 0x28, 0x15, 0x40, 0x0f, 0x15, 0x1a, 0x1a, 0x22, 0x27, 0x12, + 0x07, 0x0c, 0x12, 0x0a, + 0x05, 0x38, 0x1d, 0x15, 0x40, 0x15, 0x0a, 0x1a, 0x40, 0x15, 0x01, 0x04, + 0x40, 0x15, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x02, 0x00, 0x45, 0x5a, 0x40, 0x1f, 0x02, 0x40, 0x27, 0x40, 0x45, + 0x40, 0x40, 0x40, 0x0f, + 0x45, 0x59, 0x57, 0x05, 0x5c, 0x59, 0x57, 0x51, 0x51, 0x07, 0x07, 0x0d, + 0x4a, 0x02, 0x54, 0x07, + 0x5f, 0x27, 0x00, 0x15, 0x40, 0x4d, 0x17, 0x40, 0x40, 0x40, 0x45, 0x45, + 0x52, 0x57, 0x54, 0x57, + 0x5c, 0x59, 0x52, 0x5f, 0x57, 0x51, 0x57, 0x5f, 0x5f, 0x5c, 0x54, 0x47, + 0x42, 0x47, 0x52, 0x57, + 0x54, 0x57, 0x5c, 0x59, 0x52, 0x5f, 0x57, 0x51, 0x57, 0x5f, 0x5f, 0x5c, + 0x54, 0x47, 0x42, 0x47, + 0x0d, 0x4d, 0x47, 0x40, 0x48, 0x40, 0x45, 0x07, 0x45, 0x42, 0x42, 0x57, + 0x07, 0x1d, 0x12, 0x4d, + 0x12, 0x07, 0x40, 0x1d, 0x12, 0x4d, 0x12, 0x07, 0x40, 0x1d, 0x12, 0x4d, + 0x12, 0x07, 0x40, 0x42, + 0x07, 0x42, 0x42, 0x00, 0x0d, 0x00, 0x0d, 0x15, 0x17, 0x12, 0x4d, 0x17, + 0x12, 0x4d, 0x40, 0x40, + 0x40, 0x27, 0x27, 0x15, 0x40, 0x0f, 0x15, 0x1a, 0x1a, 0x22, 0x27, 0x12, + 0x07, 0x0d, 0x12, 0x0a, + 0x05, 0x37, 0x1d, 0x15, 0x40, 0x15, 0x0a, 0x1a, 0x00, 0x15, 0x03, 0x05, + 0x00, 0x15, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x01, 0x01, 0x44, 0x59, 0x40, 0x1e, 0x01, 0x41, 0x27, 0x40, 0x44, + 0x40, 0x40, 0x40, 0x0f, + 0x44, 0x58, 0x56, 0x06, 0x5b, 0x58, 0x55, 0x4f, 0x4f, 0x07, 0x07, 0x0c, + 0x49, 0x03, 0x53, 0x07, + 0x5e, 0x27, 0x01, 0x14, 0x40, 0x4c, 0x16, 0x40, 0x40, 0x40, 0x44, 0x44, + 0x51, 0x56, 0x53, 0x56, + 0x5b, 0x58, 0x51, 0x5e, 0x56, 0x50, 0x56, 0x5e, 0x5e, 0x5b, 0x53, 0x46, + 0x41, 0x46, 0x51, 0x56, + 0x53, 0x56, 0x5b, 0x58, 0x51, 0x5e, 0x56, 0x50, 0x56, 0x5e, 0x5e, 0x5b, + 0x53, 0x46, 0x41, 0x46, + 0x0e, 0x4c, 0x45, 0x40, 0x48, 0x40, 0x44, 0x07, 0x44, 0x41, 0x41, 0x55, + 0x07, 0x1c, 0x11, 0x4c, + 0x13, 0x07, 0x40, 0x1c, 0x11, 0x4c, 0x13, 0x07, 0x40, 0x1c, 0x11, 0x4c, + 0x13, 0x07, 0x40, 0x43, + 0x07, 0x41, 0x41, 0x01, 0x0e, 0x01, 0x0e, 0x14, 0x17, 0x11, 0x4c, 0x17, + 0x11, 0x4c, 0x40, 0x40, + 0x40, 0x26, 0x26, 0x14, 0x40, 0x0f, 0x14, 0x19, 0x19, 0x23, 0x27, 0x13, + 0x07, 0x0e, 0x13, 0x0b, + 0x04, 0x36, 0x1c, 0x14, 0x40, 0x14, 0x0b, 0x19, 0x01, 0x14, 0x04, 0x06, + 0x01, 0x14, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x01, 0x02, 0x44, 0x59, 0x40, 0x1d, 0x01, 0x42, 0x27, 0x40, 0x44, + 0x40, 0x40, 0x40, 0x0f, + 0x44, 0x56, 0x55, 0x06, 0x5a, 0x56, 0x53, 0x4c, 0x4c, 0x07, 0x07, 0x0c, + 0x49, 0x03, 0x52, 0x07, + 0x5d, 0x27, 0x02, 0x14, 0x40, 0x4c, 0x15, 0x40, 0x40, 0x40, 0x44, 0x44, + 0x51, 0x55, 0x52, 0x55, + 0x5a, 0x56, 0x51, 0x5d, 0x55, 0x4e, 0x55, 0x5d, 0x5d, 0x5a, 0x52, 0x45, + 0x41, 0x45, 0x51, 0x55, + 0x52, 0x55, 0x5a, 0x56, 0x51, 0x5d, 0x55, 0x4e, 0x55, 0x5d, 0x5d, 0x5a, + 0x52, 0x45, 0x41, 0x45, + 0x0e, 0x4c, 0x43, 0x40, 0x48, 0x40, 0x44, 0x07, 0x44, 0x41, 0x41, 0x53, + 0x07, 0x1c, 0x11, 0x4c, + 0x13, 0x07, 0x40, 0x1c, 0x11, 0x4c, 0x13, 0x07, 0x40, 0x1c, 0x11, 0x4c, + 0x13, 0x07, 0x40, 0x43, + 0x07, 0x41, 0x41, 0x02, 0x0e, 0x02, 0x0e, 0x14, 0x17, 0x11, 0x4c, 0x17, + 0x11, 0x4c, 0x40, 0x40, + 0x40, 0x25, 0x25, 0x14, 0x40, 0x0f, 0x14, 0x19, 0x19, 0x23, 0x27, 0x13, + 0x07, 0x0e, 0x13, 0x0b, + 0x04, 0x35, 0x1c, 0x14, 0x40, 0x14, 0x0b, 0x19, 0x02, 0x14, 0x05, 0x06, + 0x02, 0x14, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x03, 0x44, 0x58, 0x40, 0x1c, 0x00, 0x43, 0x27, 0x40, 0x44, + 0x40, 0x40, 0x40, 0x0f, + 0x44, 0x55, 0x54, 0x07, 0x59, 0x55, 0x51, 0x4a, 0x4a, 0x07, 0x07, 0x0c, + 0x48, 0x03, 0x51, 0x07, + 0x5c, 0x27, 0x03, 0x14, 0x40, 0x4c, 0x14, 0x40, 0x40, 0x40, 0x44, 0x44, + 0x50, 0x54, 0x51, 0x54, + 0x59, 0x55, 0x50, 0x5c, 0x54, 0x4d, 0x54, 0x5c, 0x5c, 0x59, 0x51, 0x44, + 0x40, 0x44, 0x50, 0x54, + 0x51, 0x54, 0x59, 0x55, 0x50, 0x5c, 0x54, 0x4d, 0x54, 0x5c, 0x5c, 0x59, + 0x51, 0x44, 0x40, 0x44, + 0x0f, 0x4c, 0x41, 0x40, 0x48, 0x40, 0x44, 0x07, 0x44, 0x40, 0x40, 0x51, + 0x07, 0x1c, 0x10, 0x4c, + 0x13, 0x07, 0x40, 0x1c, 0x10, 0x4c, 0x13, 0x07, 0x40, 0x1c, 0x10, 0x4c, + 0x13, 0x07, 0x40, 0x43, + 0x07, 0x40, 0x40, 0x03, 0x0f, 0x03, 0x0f, 0x14, 0x17, 0x10, 0x4c, 0x17, + 0x10, 0x4c, 0x40, 0x40, + 0x40, 0x24, 0x24, 0x14, 0x40, 0x0f, 0x14, 0x18, 0x18, 0x23, 0x27, 0x13, + 0x07, 0x0f, 0x13, 0x0b, + 0x04, 0x34, 0x1c, 0x14, 0x40, 0x14, 0x0b, 0x18, 0x03, 0x14, 0x06, 0x07, + 0x03, 0x14, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x40, 0x04, 0x43, 0x57, 0x40, 0x1b, 0x40, 0x44, 0x27, 0x40, 0x43, + 0x40, 0x40, 0x40, 0x0f, + 0x43, 0x53, 0x53, 0x08, 0x57, 0x53, 0x4f, 0x47, 0x47, 0x07, 0x07, 0x0b, + 0x47, 0x04, 0x4f, 0x07, + 0x5b, 0x27, 0x04, 0x13, 0x40, 0x4b, 0x13, 0x40, 0x40, 0x40, 0x43, 0x43, + 0x4f, 0x53, 0x4f, 0x53, + 0x57, 0x53, 0x4f, 0x5b, 0x53, 0x4b, 0x53, 0x5b, 0x5b, 0x57, 0x4f, 0x43, + 0x00, 0x43, 0x4f, 0x53, + 0x4f, 0x53, 0x57, 0x53, 0x4f, 0x5b, 0x53, 0x4b, 0x53, 0x5b, 0x5b, 0x57, + 0x4f, 0x43, 0x00, 0x43, + 0x10, 0x4b, 0x00, 0x40, 0x48, 0x40, 0x43, 0x07, 0x43, 0x00, 0x00, 0x4f, + 0x07, 0x1b, 0x0f, 0x4b, + 0x14, 0x07, 0x40, 0x1b, 0x0f, 0x4b, 0x14, 0x07, 0x40, 0x1b, 0x0f, 0x4b, + 0x14, 0x07, 0x40, 0x44, + 0x07, 0x00, 0x00, 0x04, 0x10, 0x04, 0x10, 0x13, 0x17, 0x0f, 0x4b, 0x17, + 0x0f, 0x4b, 0x40, 0x40, + 0x40, 0x23, 0x23, 0x13, 0x40, 0x0f, 0x13, 0x17, 0x17, 0x24, 0x27, 0x14, + 0x07, 0x10, 0x14, 0x0c, + 0x03, 0x33, 0x1b, 0x13, 0x40, 0x13, 0x0c, 0x17, 0x04, 0x13, 0x08, 0x08, + 0x04, 0x13, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x40, 0x05, 0x43, 0x57, 0x40, 0x1a, 0x40, 0x45, 0x27, 0x40, 0x43, + 0x40, 0x40, 0x40, 0x0f, + 0x43, 0x52, 0x52, 0x08, 0x56, 0x52, 0x4d, 0x45, 0x45, 0x07, 0x07, 0x0b, + 0x47, 0x04, 0x4e, 0x07, + 0x5a, 0x27, 0x05, 0x13, 0x40, 0x4b, 0x12, 0x40, 0x40, 0x40, 0x43, 0x43, + 0x4f, 0x52, 0x4e, 0x52, + 0x56, 0x52, 0x4f, 0x5a, 0x52, 0x4a, 0x52, 0x5a, 0x5a, 0x56, 0x4e, 0x42, + 0x00, 0x42, 0x4f, 0x52, + 0x4e, 0x52, 0x56, 0x52, 0x4f, 0x5a, 0x52, 0x4a, 0x52, 0x5a, 0x5a, 0x56, + 0x4e, 0x42, 0x00, 0x42, + 0x10, 0x4b, 0x02, 0x40, 0x48, 0x40, 0x43, 0x07, 0x43, 0x00, 0x00, 0x4d, + 0x07, 0x1b, 0x0f, 0x4b, + 0x14, 0x07, 0x40, 0x1b, 0x0f, 0x4b, 0x14, 0x07, 0x40, 0x1b, 0x0f, 0x4b, + 0x14, 0x07, 0x40, 0x44, + 0x07, 0x00, 0x00, 0x05, 0x10, 0x05, 0x10, 0x13, 0x17, 0x0f, 0x4b, 0x17, + 0x0f, 0x4b, 0x40, 0x40, + 0x40, 0x22, 0x22, 0x13, 0x40, 0x0f, 0x13, 0x17, 0x17, 0x24, 0x27, 0x14, + 0x07, 0x10, 0x14, 0x0c, + 0x03, 0x32, 0x1b, 0x13, 0x40, 0x13, 0x0c, 0x17, 0x05, 0x13, 0x09, 0x08, + 0x05, 0x13, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x41, 0x06, 0x43, 0x56, 0x40, 0x19, 0x41, 0x46, 0x27, 0x40, 0x43, + 0x40, 0x40, 0x40, 0x0f, + 0x43, 0x50, 0x51, 0x09, 0x55, 0x50, 0x4b, 0x42, 0x42, 0x07, 0x07, 0x0b, + 0x46, 0x04, 0x4d, 0x07, + 0x59, 0x27, 0x06, 0x13, 0x40, 0x4b, 0x11, 0x40, 0x40, 0x40, 0x43, 0x43, + 0x4e, 0x51, 0x4d, 0x51, + 0x55, 0x50, 0x4e, 0x59, 0x51, 0x48, 0x51, 0x59, 0x59, 0x55, 0x4d, 0x41, + 0x01, 0x41, 0x4e, 0x51, + 0x4d, 0x51, 0x55, 0x50, 0x4e, 0x59, 0x51, 0x48, 0x51, 0x59, 0x59, 0x55, + 0x4d, 0x41, 0x01, 0x41, + 0x11, 0x4b, 0x04, 0x40, 0x48, 0x40, 0x43, 0x07, 0x43, 0x01, 0x01, 0x4b, + 0x07, 0x1b, 0x0e, 0x4b, + 0x14, 0x07, 0x40, 0x1b, 0x0e, 0x4b, 0x14, 0x07, 0x40, 0x1b, 0x0e, 0x4b, + 0x14, 0x07, 0x40, 0x44, + 0x07, 0x01, 0x01, 0x06, 0x11, 0x06, 0x11, 0x13, 0x17, 0x0e, 0x4b, 0x17, + 0x0e, 0x4b, 0x40, 0x40, + 0x40, 0x21, 0x21, 0x13, 0x40, 0x0f, 0x13, 0x16, 0x16, 0x24, 0x27, 0x14, + 0x07, 0x11, 0x14, 0x0c, + 0x03, 0x31, 0x1b, 0x13, 0x40, 0x13, 0x0c, 0x16, 0x06, 0x13, 0x0a, 0x09, + 0x06, 0x13, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x42, 0x06, 0x43, 0x56, 0x40, 0x18, 0x42, 0x47, 0x27, 0x40, 0x43, + 0x40, 0x40, 0x40, 0x0f, + 0x43, 0x4f, 0x51, 0x09, 0x54, 0x4f, 0x4a, 0x40, 0x40, 0x07, 0x07, 0x0a, + 0x46, 0x04, 0x4c, 0x07, + 0x59, 0x27, 0x06, 0x12, 0x40, 0x4b, 0x10, 0x40, 0x40, 0x40, 0x43, 0x43, + 0x4e, 0x51, 0x4c, 0x51, + 0x54, 0x4f, 0x4e, 0x59, 0x51, 0x47, 0x51, 0x59, 0x59, 0x54, 0x4c, 0x41, + 0x01, 0x41, 0x4e, 0x51, + 0x4c, 0x51, 0x54, 0x4f, 0x4e, 0x59, 0x51, 0x47, 0x51, 0x59, 0x59, 0x54, + 0x4c, 0x41, 0x01, 0x41, + 0x11, 0x4b, 0x05, 0x40, 0x48, 0x40, 0x43, 0x07, 0x43, 0x01, 0x01, 0x4a, + 0x07, 0x1a, 0x0d, 0x4b, + 0x14, 0x07, 0x40, 0x1a, 0x0d, 0x4b, 0x14, 0x07, 0x40, 0x1a, 0x0d, 0x4b, + 0x14, 0x07, 0x40, 0x45, + 0x07, 0x01, 0x01, 0x06, 0x11, 0x06, 0x11, 0x12, 0x17, 0x0d, 0x4b, 0x17, + 0x0d, 0x4b, 0x40, 0x40, + 0x40, 0x20, 0x20, 0x12, 0x40, 0x0f, 0x12, 0x15, 0x15, 0x24, 0x27, 0x14, + 0x07, 0x11, 0x14, 0x0c, + 0x02, 0x30, 0x1a, 0x12, 0x40, 0x12, 0x0c, 0x15, 0x06, 0x12, 0x0b, 0x09, + 0x06, 0x12, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x42, 0x07, 0x42, 0x55, 0x40, 0x18, 0x42, 0x47, 0x27, 0x40, 0x42, + 0x40, 0x40, 0x40, 0x0f, + 0x42, 0x4d, 0x50, 0x0a, 0x52, 0x4d, 0x48, 0x02, 0x02, 0x07, 0x07, 0x0a, + 0x45, 0x05, 0x4a, 0x07, + 0x58, 0x27, 0x07, 0x12, 0x40, 0x4a, 0x10, 0x40, 0x40, 0x40, 0x42, 0x42, + 0x4d, 0x50, 0x4a, 0x50, + 0x52, 0x4d, 0x4d, 0x58, 0x50, 0x45, 0x50, 0x58, 0x58, 0x52, 0x4a, 0x40, + 0x02, 0x40, 0x4d, 0x50, + 0x4a, 0x50, 0x52, 0x4d, 0x4d, 0x58, 0x50, 0x45, 0x50, 0x58, 0x58, 0x52, + 0x4a, 0x40, 0x02, 0x40, + 0x12, 0x4a, 0x07, 0x40, 0x48, 0x40, 0x42, 0x07, 0x42, 0x02, 0x02, 0x48, + 0x07, 0x1a, 0x0d, 0x4a, + 0x15, 0x07, 0x40, 0x1a, 0x0d, 0x4a, 0x15, 0x07, 0x40, 0x1a, 0x0d, 0x4a, + 0x15, 0x07, 0x40, 0x45, + 0x07, 0x02, 0x02, 0x07, 0x12, 0x07, 0x12, 0x12, 0x17, 0x0d, 0x4a, 0x17, + 0x0d, 0x4a, 0x40, 0x40, + 0x40, 0x20, 0x20, 0x12, 0x40, 0x0f, 0x12, 0x15, 0x15, 0x25, 0x27, 0x15, + 0x07, 0x12, 0x15, 0x0d, + 0x02, 0x30, 0x1a, 0x12, 0x40, 0x12, 0x0d, 0x15, 0x07, 0x12, 0x0d, 0x0a, + 0x07, 0x12, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x43, 0x08, 0x42, 0x54, 0x40, 0x17, 0x43, 0x48, 0x27, 0x40, 0x42, + 0x40, 0x40, 0x40, 0x0f, + 0x42, 0x4b, 0x4f, 0x0b, 0x51, 0x4b, 0x46, 0x04, 0x04, 0x07, 0x07, 0x0a, + 0x44, 0x05, 0x49, 0x07, + 0x57, 0x27, 0x08, 0x12, 0x40, 0x4a, 0x0f, 0x40, 0x40, 0x40, 0x42, 0x42, + 0x4c, 0x4f, 0x49, 0x4f, + 0x51, 0x4b, 0x4c, 0x57, 0x4f, 0x43, 0x4f, 0x57, 0x57, 0x51, 0x49, 0x00, + 0x03, 0x00, 0x4c, 0x4f, + 0x49, 0x4f, 0x51, 0x4b, 0x4c, 0x57, 0x4f, 0x43, 0x4f, 0x57, 0x57, 0x51, + 0x49, 0x00, 0x03, 0x00, + 0x13, 0x4a, 0x09, 0x40, 0x48, 0x40, 0x42, 0x07, 0x42, 0x03, 0x03, 0x46, + 0x07, 0x1a, 0x0c, 0x4a, + 0x15, 0x07, 0x40, 0x1a, 0x0c, 0x4a, 0x15, 0x07, 0x40, 0x1a, 0x0c, 0x4a, + 0x15, 0x07, 0x40, 0x45, + 0x07, 0x03, 0x03, 0x08, 0x13, 0x08, 0x13, 0x12, 0x17, 0x0c, 0x4a, 0x17, + 0x0c, 0x4a, 0x40, 0x40, + 0x40, 0x1f, 0x1f, 0x12, 0x40, 0x0f, 0x12, 0x14, 0x14, 0x25, 0x27, 0x15, + 0x07, 0x13, 0x15, 0x0d, + 0x02, 0x2f, 0x1a, 0x12, 0x40, 0x12, 0x0d, 0x14, 0x08, 0x12, 0x0e, 0x0b, + 0x08, 0x12, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x43, 0x09, 0x42, 0x54, 0x40, 0x16, 0x43, 0x49, 0x27, 0x40, 0x42, + 0x40, 0x40, 0x40, 0x0f, + 0x42, 0x4a, 0x4e, 0x0b, 0x50, 0x4a, 0x44, 0x07, 0x07, 0x07, 0x07, 0x0a, + 0x44, 0x05, 0x48, 0x07, + 0x56, 0x27, 0x09, 0x12, 0x40, 0x4a, 0x0e, 0x40, 0x40, 0x40, 0x42, 0x42, + 0x4c, 0x4e, 0x48, 0x4e, + 0x50, 0x4a, 0x4c, 0x56, 0x4e, 0x42, 0x4e, 0x56, 0x56, 0x50, 0x48, 0x01, + 0x03, 0x01, 0x4c, 0x4e, + 0x48, 0x4e, 0x50, 0x4a, 0x4c, 0x56, 0x4e, 0x42, 0x4e, 0x56, 0x56, 0x50, + 0x48, 0x01, 0x03, 0x01, + 0x13, 0x4a, 0x0b, 0x40, 0x48, 0x40, 0x42, 0x07, 0x42, 0x03, 0x03, 0x44, + 0x07, 0x1a, 0x0c, 0x4a, + 0x15, 0x07, 0x40, 0x1a, 0x0c, 0x4a, 0x15, 0x07, 0x40, 0x1a, 0x0c, 0x4a, + 0x15, 0x07, 0x40, 0x45, + 0x07, 0x03, 0x03, 0x09, 0x13, 0x09, 0x13, 0x12, 0x17, 0x0c, 0x4a, 0x17, + 0x0c, 0x4a, 0x40, 0x40, + 0x40, 0x1e, 0x1e, 0x12, 0x40, 0x0f, 0x12, 0x14, 0x14, 0x25, 0x27, 0x15, + 0x07, 0x13, 0x15, 0x0d, + 0x02, 0x2e, 0x1a, 0x12, 0x40, 0x12, 0x0d, 0x14, 0x09, 0x12, 0x0f, 0x0b, + 0x09, 0x12, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x44, 0x0a, 0x41, 0x53, 0x40, 0x15, 0x44, 0x4a, 0x27, 0x40, 0x41, + 0x40, 0x40, 0x40, 0x0f, + 0x41, 0x48, 0x4d, 0x0c, 0x4f, 0x48, 0x42, 0x09, 0x09, 0x07, 0x07, 0x09, + 0x43, 0x06, 0x47, 0x07, + 0x55, 0x27, 0x0a, 0x11, 0x40, 0x49, 0x0d, 0x40, 0x40, 0x40, 0x41, 0x41, + 0x4b, 0x4d, 0x47, 0x4d, + 0x4f, 0x48, 0x4b, 0x55, 0x4d, 0x40, 0x4d, 0x55, 0x55, 0x4f, 0x47, 0x02, + 0x04, 0x02, 0x4b, 0x4d, + 0x47, 0x4d, 0x4f, 0x48, 0x4b, 0x55, 0x4d, 0x40, 0x4d, 0x55, 0x55, 0x4f, + 0x47, 0x02, 0x04, 0x02, + 0x14, 0x49, 0x0d, 0x40, 0x48, 0x40, 0x41, 0x07, 0x41, 0x04, 0x04, 0x42, + 0x07, 0x19, 0x0b, 0x49, + 0x16, 0x07, 0x40, 0x19, 0x0b, 0x49, 0x16, 0x07, 0x40, 0x19, 0x0b, 0x49, + 0x16, 0x07, 0x40, 0x46, + 0x07, 0x04, 0x04, 0x0a, 0x14, 0x0a, 0x14, 0x11, 0x17, 0x0b, 0x49, 0x17, + 0x0b, 0x49, 0x40, 0x40, + 0x40, 0x1d, 0x1d, 0x11, 0x40, 0x0f, 0x11, 0x13, 0x13, 0x26, 0x27, 0x16, + 0x07, 0x14, 0x16, 0x0e, + 0x01, 0x2d, 0x19, 0x11, 0x40, 0x11, 0x0e, 0x13, 0x0a, 0x11, 0x10, 0x0c, + 0x0a, 0x11, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x45, 0x0b, 0x41, 0x52, 0x40, 0x14, 0x45, 0x4b, 0x27, 0x40, 0x41, + 0x40, 0x40, 0x40, 0x0f, + 0x41, 0x47, 0x4c, 0x0d, 0x4d, 0x47, 0x40, 0x0c, 0x0c, 0x07, 0x07, 0x09, + 0x42, 0x06, 0x45, 0x07, + 0x54, 0x27, 0x0b, 0x11, 0x40, 0x49, 0x0c, 0x40, 0x40, 0x40, 0x41, 0x41, + 0x4a, 0x4c, 0x45, 0x4c, + 0x4d, 0x47, 0x4a, 0x54, 0x4c, 0x00, 0x4c, 0x54, 0x54, 0x4d, 0x45, 0x03, + 0x05, 0x03, 0x4a, 0x4c, + 0x45, 0x4c, 0x4d, 0x47, 0x4a, 0x54, 0x4c, 0x00, 0x4c, 0x54, 0x54, 0x4d, + 0x45, 0x03, 0x05, 0x03, + 0x15, 0x49, 0x0f, 0x40, 0x48, 0x40, 0x41, 0x07, 0x41, 0x05, 0x05, 0x40, + 0x07, 0x19, 0x0a, 0x49, + 0x16, 0x07, 0x40, 0x19, 0x0a, 0x49, 0x16, 0x07, 0x40, 0x19, 0x0a, 0x49, + 0x16, 0x07, 0x40, 0x46, + 0x07, 0x05, 0x05, 0x0b, 0x15, 0x0b, 0x15, 0x11, 0x17, 0x0a, 0x49, 0x17, + 0x0a, 0x49, 0x40, 0x40, + 0x40, 0x1c, 0x1c, 0x11, 0x40, 0x0f, 0x11, 0x12, 0x12, 0x26, 0x27, 0x16, + 0x07, 0x15, 0x16, 0x0e, + 0x01, 0x2c, 0x19, 0x11, 0x40, 0x11, 0x0e, 0x12, 0x0b, 0x11, 0x12, 0x0d, + 0x0b, 0x11, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x45, 0x0c, 0x41, 0x52, 0x40, 0x13, 0x45, 0x4c, 0x27, 0x40, 0x41, + 0x40, 0x40, 0x40, 0x0f, + 0x41, 0x45, 0x4b, 0x0d, 0x4c, 0x45, 0x01, 0x0e, 0x0e, 0x07, 0x07, 0x09, + 0x42, 0x06, 0x44, 0x07, + 0x53, 0x27, 0x0c, 0x11, 0x40, 0x49, 0x0b, 0x40, 0x40, 0x40, 0x41, 0x41, + 0x4a, 0x4b, 0x44, 0x4b, + 0x4c, 0x45, 0x4a, 0x53, 0x4b, 0x02, 0x4b, 0x53, 0x53, 0x4c, 0x44, 0x04, + 0x05, 0x04, 0x4a, 0x4b, + 0x44, 0x4b, 0x4c, 0x45, 0x4a, 0x53, 0x4b, 0x02, 0x4b, 0x53, 0x53, 0x4c, + 0x44, 0x04, 0x05, 0x04, + 0x15, 0x49, 0x11, 0x40, 0x48, 0x40, 0x41, 0x07, 0x41, 0x05, 0x05, 0x01, + 0x07, 0x19, 0x0a, 0x49, + 0x16, 0x07, 0x40, 0x19, 0x0a, 0x49, 0x16, 0x07, 0x40, 0x19, 0x0a, 0x49, + 0x16, 0x07, 0x40, 0x46, + 0x07, 0x05, 0x05, 0x0c, 0x15, 0x0c, 0x15, 0x11, 0x17, 0x0a, 0x49, 0x17, + 0x0a, 0x49, 0x40, 0x40, + 0x40, 0x1b, 0x1b, 0x11, 0x40, 0x0f, 0x11, 0x12, 0x12, 0x26, 0x27, 0x16, + 0x07, 0x15, 0x16, 0x0e, + 0x01, 0x2b, 0x19, 0x11, 0x40, 0x11, 0x0e, 0x12, 0x0c, 0x11, 0x13, 0x0d, + 0x0c, 0x11, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x46, 0x0d, 0x40, 0x51, 0x40, 0x12, 0x46, 0x4d, 0x27, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x0f, + 0x40, 0x44, 0x4a, 0x0e, 0x4b, 0x44, 0x03, 0x11, 0x11, 0x07, 0x07, 0x08, + 0x41, 0x07, 0x43, 0x07, + 0x52, 0x27, 0x0d, 0x10, 0x40, 0x48, 0x0a, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x49, 0x4a, 0x43, 0x4a, + 0x4b, 0x44, 0x49, 0x52, 0x4a, 0x03, 0x4a, 0x52, 0x52, 0x4b, 0x43, 0x05, + 0x06, 0x05, 0x49, 0x4a, + 0x43, 0x4a, 0x4b, 0x44, 0x49, 0x52, 0x4a, 0x03, 0x4a, 0x52, 0x52, 0x4b, + 0x43, 0x05, 0x06, 0x05, + 0x16, 0x48, 0x13, 0x40, 0x48, 0x40, 0x40, 0x07, 0x40, 0x06, 0x06, 0x03, + 0x07, 0x18, 0x09, 0x48, + 0x17, 0x07, 0x40, 0x18, 0x09, 0x48, 0x17, 0x07, 0x40, 0x18, 0x09, 0x48, + 0x17, 0x07, 0x40, 0x47, + 0x07, 0x06, 0x06, 0x0d, 0x16, 0x0d, 0x16, 0x10, 0x17, 0x09, 0x48, 0x17, + 0x09, 0x48, 0x40, 0x40, + 0x40, 0x1a, 0x1a, 0x10, 0x40, 0x0f, 0x10, 0x11, 0x11, 0x27, 0x27, 0x17, + 0x07, 0x16, 0x17, 0x0f, + 0x00, 0x2a, 0x18, 0x10, 0x40, 0x10, 0x0f, 0x11, 0x0d, 0x10, 0x14, 0x0e, + 0x0d, 0x10, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x47, 0x0e, 0x40, 0x51, 0x40, 0x11, 0x47, 0x4e, 0x27, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x0f, + 0x40, 0x42, 0x49, 0x0e, 0x4a, 0x42, 0x04, 0x13, 0x13, 0x07, 0x07, 0x08, + 0x41, 0x07, 0x42, 0x07, + 0x51, 0x27, 0x0e, 0x10, 0x40, 0x48, 0x09, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x49, 0x49, 0x42, 0x49, + 0x4a, 0x42, 0x49, 0x51, 0x49, 0x05, 0x49, 0x51, 0x51, 0x4a, 0x42, 0x06, + 0x06, 0x06, 0x49, 0x49, + 0x42, 0x49, 0x4a, 0x42, 0x49, 0x51, 0x49, 0x05, 0x49, 0x51, 0x51, 0x4a, + 0x42, 0x06, 0x06, 0x06, + 0x16, 0x48, 0x14, 0x40, 0x48, 0x40, 0x40, 0x07, 0x40, 0x06, 0x06, 0x04, + 0x07, 0x18, 0x08, 0x48, + 0x17, 0x07, 0x40, 0x18, 0x08, 0x48, 0x17, 0x07, 0x40, 0x18, 0x08, 0x48, + 0x17, 0x07, 0x40, 0x47, + 0x07, 0x06, 0x06, 0x0e, 0x16, 0x0e, 0x16, 0x10, 0x17, 0x08, 0x48, 0x17, + 0x08, 0x48, 0x40, 0x40, + 0x40, 0x19, 0x19, 0x10, 0x40, 0x0f, 0x10, 0x10, 0x10, 0x27, 0x27, 0x17, + 0x07, 0x16, 0x17, 0x0f, + 0x00, 0x29, 0x18, 0x10, 0x40, 0x10, 0x0f, 0x10, 0x0e, 0x10, 0x15, 0x0e, + 0x0e, 0x10, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x47, 0x0f, 0x40, 0x50, 0x40, 0x10, 0x47, 0x4f, 0x27, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x0f, + 0x40, 0x40, 0x48, 0x0f, 0x48, 0x40, 0x06, 0x16, 0x16, 0x07, 0x07, 0x08, + 0x40, 0x07, 0x40, 0x07, + 0x50, 0x27, 0x0f, 0x10, 0x40, 0x48, 0x08, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x48, 0x48, 0x40, 0x48, + 0x48, 0x40, 0x48, 0x50, 0x48, 0x07, 0x48, 0x50, 0x50, 0x48, 0x40, 0x07, + 0x07, 0x07, 0x48, 0x48, + 0x40, 0x48, 0x48, 0x40, 0x48, 0x50, 0x48, 0x07, 0x48, 0x50, 0x50, 0x48, + 0x40, 0x07, 0x07, 0x07, + 0x17, 0x48, 0x16, 0x40, 0x48, 0x40, 0x40, 0x07, 0x40, 0x07, 0x07, 0x06, + 0x07, 0x18, 0x08, 0x48, + 0x17, 0x07, 0x40, 0x18, 0x08, 0x48, 0x17, 0x07, 0x40, 0x18, 0x08, 0x48, + 0x17, 0x07, 0x40, 0x47, + 0x07, 0x07, 0x07, 0x0f, 0x17, 0x0f, 0x17, 0x10, 0x17, 0x08, 0x48, 0x17, + 0x08, 0x48, 0x40, 0x40, + 0x40, 0x18, 0x18, 0x10, 0x40, 0x0f, 0x10, 0x10, 0x10, 0x27, 0x27, 0x17, + 0x07, 0x17, 0x17, 0x0f, + 0x00, 0x28, 0x18, 0x10, 0x40, 0x10, 0x0f, 0x10, 0x0f, 0x10, 0x17, 0x0f, + 0x0f, 0x10, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x48, 0x10, 0x00, 0x4f, 0x40, 0x0f, 0x48, 0x50, 0x27, 0x40, 0x00, + 0x40, 0x40, 0x40, 0x0f, + 0x00, 0x00, 0x47, 0x10, 0x47, 0x00, 0x08, 0x18, 0x18, 0x07, 0x07, 0x07, + 0x00, 0x08, 0x00, 0x07, + 0x4f, 0x27, 0x10, 0x0f, 0x40, 0x47, 0x07, 0x40, 0x40, 0x40, 0x00, 0x00, + 0x47, 0x47, 0x00, 0x47, + 0x47, 0x00, 0x47, 0x4f, 0x47, 0x08, 0x47, 0x4f, 0x4f, 0x47, 0x00, 0x08, + 0x08, 0x08, 0x47, 0x47, + 0x00, 0x47, 0x47, 0x00, 0x47, 0x4f, 0x47, 0x08, 0x47, 0x4f, 0x4f, 0x47, + 0x00, 0x08, 0x08, 0x08, + 0x18, 0x47, 0x18, 0x40, 0x48, 0x40, 0x00, 0x07, 0x00, 0x08, 0x08, 0x08, + 0x07, 0x17, 0x07, 0x47, + 0x18, 0x07, 0x40, 0x17, 0x07, 0x47, 0x18, 0x07, 0x40, 0x17, 0x07, 0x47, + 0x18, 0x07, 0x40, 0x48, + 0x07, 0x08, 0x08, 0x10, 0x18, 0x10, 0x18, 0x0f, 0x17, 0x07, 0x47, 0x17, + 0x07, 0x47, 0x40, 0x40, + 0x40, 0x17, 0x17, 0x0f, 0x40, 0x0f, 0x0f, 0x0f, 0x0f, 0x28, 0x27, 0x18, + 0x07, 0x18, 0x18, 0x10, + 0x40, 0x27, 0x17, 0x0f, 0x40, 0x0f, 0x10, 0x0f, 0x10, 0x0f, 0x18, 0x10, + 0x10, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x48, 0x11, 0x00, 0x4f, 0x40, 0x0e, 0x48, 0x51, 0x27, 0x40, 0x00, + 0x40, 0x40, 0x40, 0x0f, + 0x00, 0x02, 0x46, 0x10, 0x46, 0x02, 0x0a, 0x1b, 0x1b, 0x07, 0x07, 0x07, + 0x00, 0x08, 0x01, 0x07, + 0x4e, 0x27, 0x11, 0x0f, 0x40, 0x47, 0x06, 0x40, 0x40, 0x40, 0x00, 0x00, + 0x47, 0x46, 0x01, 0x46, + 0x46, 0x02, 0x47, 0x4e, 0x46, 0x0a, 0x46, 0x4e, 0x4e, 0x46, 0x01, 0x09, + 0x08, 0x09, 0x47, 0x46, + 0x01, 0x46, 0x46, 0x02, 0x47, 0x4e, 0x46, 0x0a, 0x46, 0x4e, 0x4e, 0x46, + 0x01, 0x09, 0x08, 0x09, + 0x18, 0x47, 0x1a, 0x40, 0x48, 0x40, 0x00, 0x07, 0x00, 0x08, 0x08, 0x0a, + 0x07, 0x17, 0x07, 0x47, + 0x18, 0x07, 0x40, 0x17, 0x07, 0x47, 0x18, 0x07, 0x40, 0x17, 0x07, 0x47, + 0x18, 0x07, 0x40, 0x48, + 0x07, 0x08, 0x08, 0x11, 0x18, 0x11, 0x18, 0x0f, 0x17, 0x07, 0x47, 0x17, + 0x07, 0x47, 0x40, 0x40, + 0x40, 0x16, 0x16, 0x0f, 0x40, 0x0f, 0x0f, 0x0f, 0x0f, 0x28, 0x27, 0x18, + 0x07, 0x18, 0x18, 0x10, + 0x40, 0x26, 0x17, 0x0f, 0x40, 0x0f, 0x10, 0x0f, 0x11, 0x0f, 0x19, 0x10, + 0x11, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x49, 0x12, 0x00, 0x4e, 0x40, 0x0d, 0x49, 0x52, 0x27, 0x40, 0x00, + 0x40, 0x40, 0x40, 0x0f, + 0x00, 0x03, 0x45, 0x11, 0x45, 0x03, 0x0c, 0x1d, 0x1d, 0x07, 0x07, 0x07, + 0x01, 0x08, 0x02, 0x07, + 0x4d, 0x27, 0x12, 0x0f, 0x40, 0x47, 0x05, 0x40, 0x40, 0x40, 0x00, 0x00, + 0x46, 0x45, 0x02, 0x45, + 0x45, 0x03, 0x46, 0x4d, 0x45, 0x0b, 0x45, 0x4d, 0x4d, 0x45, 0x02, 0x0a, + 0x09, 0x0a, 0x46, 0x45, + 0x02, 0x45, 0x45, 0x03, 0x46, 0x4d, 0x45, 0x0b, 0x45, 0x4d, 0x4d, 0x45, + 0x02, 0x0a, 0x09, 0x0a, + 0x19, 0x47, 0x1c, 0x40, 0x48, 0x40, 0x00, 0x07, 0x00, 0x09, 0x09, 0x0c, + 0x07, 0x17, 0x06, 0x47, + 0x18, 0x07, 0x40, 0x17, 0x06, 0x47, 0x18, 0x07, 0x40, 0x17, 0x06, 0x47, + 0x18, 0x07, 0x40, 0x48, + 0x07, 0x09, 0x09, 0x12, 0x19, 0x12, 0x19, 0x0f, 0x17, 0x06, 0x47, 0x17, + 0x06, 0x47, 0x40, 0x40, + 0x40, 0x15, 0x15, 0x0f, 0x40, 0x0f, 0x0f, 0x0e, 0x0e, 0x28, 0x27, 0x18, + 0x07, 0x19, 0x18, 0x10, + 0x40, 0x25, 0x17, 0x0f, 0x40, 0x0f, 0x10, 0x0e, 0x12, 0x0f, 0x1a, 0x11, + 0x12, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x4a, 0x13, 0x01, 0x4d, 0x40, 0x0c, 0x4a, 0x53, 0x27, 0x40, 0x01, + 0x40, 0x40, 0x40, 0x0f, + 0x01, 0x05, 0x44, 0x12, 0x43, 0x05, 0x0e, 0x20, 0x20, 0x07, 0x07, 0x06, + 0x02, 0x09, 0x04, 0x07, + 0x4c, 0x27, 0x13, 0x0e, 0x40, 0x46, 0x04, 0x40, 0x40, 0x40, 0x01, 0x01, + 0x45, 0x44, 0x04, 0x44, + 0x43, 0x05, 0x45, 0x4c, 0x44, 0x0d, 0x44, 0x4c, 0x4c, 0x43, 0x04, 0x0b, + 0x0a, 0x0b, 0x45, 0x44, + 0x04, 0x44, 0x43, 0x05, 0x45, 0x4c, 0x44, 0x0d, 0x44, 0x4c, 0x4c, 0x43, + 0x04, 0x0b, 0x0a, 0x0b, + 0x1a, 0x46, 0x1e, 0x40, 0x48, 0x40, 0x01, 0x07, 0x01, 0x0a, 0x0a, 0x0e, + 0x07, 0x16, 0x05, 0x46, + 0x19, 0x07, 0x40, 0x16, 0x05, 0x46, 0x19, 0x07, 0x40, 0x16, 0x05, 0x46, + 0x19, 0x07, 0x40, 0x49, + 0x07, 0x0a, 0x0a, 0x13, 0x1a, 0x13, 0x1a, 0x0e, 0x17, 0x05, 0x46, 0x17, + 0x05, 0x46, 0x40, 0x40, + 0x40, 0x14, 0x14, 0x0e, 0x40, 0x0f, 0x0e, 0x0d, 0x0d, 0x29, 0x27, 0x19, + 0x07, 0x1a, 0x19, 0x11, + 0x41, 0x24, 0x16, 0x0e, 0x40, 0x0e, 0x11, 0x0d, 0x13, 0x0e, 0x1c, 0x12, + 0x13, 0x0e, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x4a, 0x14, 0x01, 0x4d, 0x40, 0x0b, 0x4a, 0x54, 0x27, 0x40, 0x01, + 0x40, 0x40, 0x40, 0x0f, + 0x01, 0x06, 0x43, 0x12, 0x42, 0x06, 0x10, 0x22, 0x22, 0x07, 0x07, 0x06, + 0x02, 0x09, 0x05, 0x07, + 0x4b, 0x27, 0x14, 0x0e, 0x40, 0x46, 0x03, 0x40, 0x40, 0x40, 0x01, 0x01, + 0x45, 0x43, 0x05, 0x43, + 0x42, 0x06, 0x45, 0x4b, 0x43, 0x0e, 0x43, 0x4b, 0x4b, 0x42, 0x05, 0x0c, + 0x0a, 0x0c, 0x45, 0x43, + 0x05, 0x43, 0x42, 0x06, 0x45, 0x4b, 0x43, 0x0e, 0x43, 0x4b, 0x4b, 0x42, + 0x05, 0x0c, 0x0a, 0x0c, + 0x1a, 0x46, 0x20, 0x40, 0x48, 0x40, 0x01, 0x07, 0x01, 0x0a, 0x0a, 0x10, + 0x07, 0x16, 0x05, 0x46, + 0x19, 0x07, 0x40, 0x16, 0x05, 0x46, 0x19, 0x07, 0x40, 0x16, 0x05, 0x46, + 0x19, 0x07, 0x40, 0x49, + 0x07, 0x0a, 0x0a, 0x14, 0x1a, 0x14, 0x1a, 0x0e, 0x17, 0x05, 0x46, 0x17, + 0x05, 0x46, 0x40, 0x40, + 0x40, 0x13, 0x13, 0x0e, 0x40, 0x0f, 0x0e, 0x0d, 0x0d, 0x29, 0x27, 0x19, + 0x07, 0x1a, 0x19, 0x11, + 0x41, 0x23, 0x16, 0x0e, 0x40, 0x0e, 0x11, 0x0d, 0x14, 0x0e, 0x1d, 0x12, + 0x14, 0x0e, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x4b, 0x15, 0x01, 0x4c, 0x40, 0x0a, 0x4b, 0x55, 0x27, 0x40, 0x01, + 0x40, 0x40, 0x40, 0x0f, + 0x01, 0x08, 0x42, 0x13, 0x41, 0x08, 0x12, 0x25, 0x25, 0x07, 0x07, 0x06, + 0x03, 0x09, 0x06, 0x07, + 0x4a, 0x27, 0x15, 0x0e, 0x40, 0x46, 0x02, 0x40, 0x40, 0x40, 0x01, 0x01, + 0x44, 0x42, 0x06, 0x42, + 0x41, 0x08, 0x44, 0x4a, 0x42, 0x10, 0x42, 0x4a, 0x4a, 0x41, 0x06, 0x0d, + 0x0b, 0x0d, 0x44, 0x42, + 0x06, 0x42, 0x41, 0x08, 0x44, 0x4a, 0x42, 0x10, 0x42, 0x4a, 0x4a, 0x41, + 0x06, 0x0d, 0x0b, 0x0d, + 0x1b, 0x46, 0x22, 0x40, 0x48, 0x40, 0x01, 0x07, 0x01, 0x0b, 0x0b, 0x12, + 0x07, 0x16, 0x04, 0x46, + 0x19, 0x07, 0x40, 0x16, 0x04, 0x46, 0x19, 0x07, 0x40, 0x16, 0x04, 0x46, + 0x19, 0x07, 0x40, 0x49, + 0x07, 0x0b, 0x0b, 0x15, 0x1b, 0x15, 0x1b, 0x0e, 0x17, 0x04, 0x46, 0x17, + 0x04, 0x46, 0x40, 0x40, + 0x40, 0x12, 0x12, 0x0e, 0x40, 0x0f, 0x0e, 0x0c, 0x0c, 0x29, 0x27, 0x19, + 0x07, 0x1b, 0x19, 0x11, + 0x41, 0x22, 0x16, 0x0e, 0x40, 0x0e, 0x11, 0x0c, 0x15, 0x0e, 0x1e, 0x13, + 0x15, 0x0e, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x4c, 0x15, 0x01, 0x4c, 0x40, 0x09, 0x4c, 0x56, 0x27, 0x40, 0x01, + 0x40, 0x40, 0x40, 0x0f, + 0x01, 0x09, 0x42, 0x13, 0x40, 0x09, 0x13, 0x27, 0x27, 0x07, 0x07, 0x05, + 0x03, 0x09, 0x07, 0x07, + 0x4a, 0x27, 0x15, 0x0d, 0x40, 0x46, 0x01, 0x40, 0x40, 0x40, 0x01, 0x01, + 0x44, 0x42, 0x07, 0x42, + 0x40, 0x09, 0x44, 0x4a, 0x42, 0x11, 0x42, 0x4a, 0x4a, 0x40, 0x07, 0x0d, + 0x0b, 0x0d, 0x44, 0x42, + 0x07, 0x42, 0x40, 0x09, 0x44, 0x4a, 0x42, 0x11, 0x42, 0x4a, 0x4a, 0x40, + 0x07, 0x0d, 0x0b, 0x0d, + 0x1b, 0x46, 0x23, 0x40, 0x48, 0x40, 0x01, 0x07, 0x01, 0x0b, 0x0b, 0x13, + 0x07, 0x15, 0x03, 0x46, + 0x19, 0x07, 0x40, 0x15, 0x03, 0x46, 0x19, 0x07, 0x40, 0x15, 0x03, 0x46, + 0x19, 0x07, 0x40, 0x4a, + 0x07, 0x0b, 0x0b, 0x15, 0x1b, 0x15, 0x1b, 0x0d, 0x17, 0x03, 0x46, 0x17, + 0x03, 0x46, 0x40, 0x40, + 0x40, 0x11, 0x11, 0x0d, 0x40, 0x0f, 0x0d, 0x0b, 0x0b, 0x29, 0x27, 0x19, + 0x07, 0x1b, 0x19, 0x11, + 0x42, 0x21, 0x15, 0x0d, 0x40, 0x0d, 0x11, 0x0b, 0x15, 0x0d, 0x1f, 0x13, + 0x15, 0x0d, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x4c, 0x16, 0x02, 0x4b, 0x40, 0x09, 0x4c, 0x56, 0x27, 0x40, 0x02, + 0x40, 0x40, 0x40, 0x0f, + 0x02, 0x0b, 0x41, 0x14, 0x01, 0x0b, 0x15, 0x2a, 0x2a, 0x07, 0x07, 0x05, + 0x04, 0x0a, 0x09, 0x07, + 0x49, 0x27, 0x16, 0x0d, 0x40, 0x45, 0x01, 0x40, 0x40, 0x40, 0x02, 0x02, + 0x43, 0x41, 0x09, 0x41, + 0x01, 0x0b, 0x43, 0x49, 0x41, 0x13, 0x41, 0x49, 0x49, 0x01, 0x09, 0x0e, + 0x0c, 0x0e, 0x43, 0x41, + 0x09, 0x41, 0x01, 0x0b, 0x43, 0x49, 0x41, 0x13, 0x41, 0x49, 0x49, 0x01, + 0x09, 0x0e, 0x0c, 0x0e, + 0x1c, 0x45, 0x25, 0x40, 0x48, 0x40, 0x02, 0x07, 0x02, 0x0c, 0x0c, 0x15, + 0x07, 0x15, 0x03, 0x45, + 0x1a, 0x07, 0x40, 0x15, 0x03, 0x45, 0x1a, 0x07, 0x40, 0x15, 0x03, 0x45, + 0x1a, 0x07, 0x40, 0x4a, + 0x07, 0x0c, 0x0c, 0x16, 0x1c, 0x16, 0x1c, 0x0d, 0x17, 0x03, 0x45, 0x17, + 0x03, 0x45, 0x40, 0x40, + 0x40, 0x11, 0x11, 0x0d, 0x40, 0x0f, 0x0d, 0x0b, 0x0b, 0x2a, 0x27, 0x1a, + 0x07, 0x1c, 0x1a, 0x12, + 0x42, 0x21, 0x15, 0x0d, 0x40, 0x0d, 0x12, 0x0b, 0x16, 0x0d, 0x21, 0x14, + 0x16, 0x0d, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x4d, 0x17, 0x02, 0x4a, 0x40, 0x08, 0x4d, 0x57, 0x27, 0x40, 0x02, + 0x40, 0x40, 0x40, 0x0f, + 0x02, 0x0d, 0x40, 0x15, 0x02, 0x0d, 0x17, 0x2c, 0x2c, 0x07, 0x07, 0x05, + 0x05, 0x0a, 0x0a, 0x07, + 0x48, 0x27, 0x17, 0x0d, 0x40, 0x45, 0x00, 0x40, 0x40, 0x40, 0x02, 0x02, + 0x42, 0x40, 0x0a, 0x40, + 0x02, 0x0d, 0x42, 0x48, 0x40, 0x15, 0x40, 0x48, 0x48, 0x02, 0x0a, 0x0f, + 0x0d, 0x0f, 0x42, 0x40, + 0x0a, 0x40, 0x02, 0x0d, 0x42, 0x48, 0x40, 0x15, 0x40, 0x48, 0x48, 0x02, + 0x0a, 0x0f, 0x0d, 0x0f, + 0x1d, 0x45, 0x27, 0x40, 0x48, 0x40, 0x02, 0x07, 0x02, 0x0d, 0x0d, 0x17, + 0x07, 0x15, 0x02, 0x45, + 0x1a, 0x07, 0x40, 0x15, 0x02, 0x45, 0x1a, 0x07, 0x40, 0x15, 0x02, 0x45, + 0x1a, 0x07, 0x40, 0x4a, + 0x07, 0x0d, 0x0d, 0x17, 0x1d, 0x17, 0x1d, 0x0d, 0x17, 0x02, 0x45, 0x17, + 0x02, 0x45, 0x40, 0x40, + 0x40, 0x10, 0x10, 0x0d, 0x40, 0x0f, 0x0d, 0x0a, 0x0a, 0x2a, 0x27, 0x1a, + 0x07, 0x1d, 0x1a, 0x12, + 0x42, 0x20, 0x15, 0x0d, 0x40, 0x0d, 0x12, 0x0a, 0x17, 0x0d, 0x22, 0x15, + 0x17, 0x0d, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x4d, 0x18, 0x02, 0x4a, 0x40, 0x07, 0x4d, 0x58, 0x27, 0x40, 0x02, + 0x40, 0x40, 0x40, 0x0f, + 0x02, 0x0e, 0x00, 0x15, 0x03, 0x0e, 0x19, 0x2f, 0x2f, 0x07, 0x07, 0x05, + 0x05, 0x0a, 0x0b, 0x07, + 0x47, 0x27, 0x18, 0x0d, 0x40, 0x45, 0x40, 0x40, 0x40, 0x40, 0x02, 0x02, + 0x42, 0x00, 0x0b, 0x00, + 0x03, 0x0e, 0x42, 0x47, 0x00, 0x16, 0x00, 0x47, 0x47, 0x03, 0x0b, 0x10, + 0x0d, 0x10, 0x42, 0x00, + 0x0b, 0x00, 0x03, 0x0e, 0x42, 0x47, 0x00, 0x16, 0x00, 0x47, 0x47, 0x03, + 0x0b, 0x10, 0x0d, 0x10, + 0x1d, 0x45, 0x29, 0x40, 0x48, 0x40, 0x02, 0x07, 0x02, 0x0d, 0x0d, 0x19, + 0x07, 0x15, 0x02, 0x45, + 0x1a, 0x07, 0x40, 0x15, 0x02, 0x45, 0x1a, 0x07, 0x40, 0x15, 0x02, 0x45, + 0x1a, 0x07, 0x40, 0x4a, + 0x07, 0x0d, 0x0d, 0x18, 0x1d, 0x18, 0x1d, 0x0d, 0x17, 0x02, 0x45, 0x17, + 0x02, 0x45, 0x40, 0x40, + 0x40, 0x0f, 0x0f, 0x0d, 0x40, 0x0f, 0x0d, 0x0a, 0x0a, 0x2a, 0x27, 0x1a, + 0x07, 0x1d, 0x1a, 0x12, + 0x42, 0x1f, 0x15, 0x0d, 0x40, 0x0d, 0x12, 0x0a, 0x18, 0x0d, 0x23, 0x15, + 0x18, 0x0d, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x4e, 0x19, 0x03, 0x49, 0x40, 0x06, 0x4e, 0x59, 0x27, 0x40, 0x03, + 0x40, 0x40, 0x40, 0x0f, + 0x03, 0x10, 0x01, 0x16, 0x04, 0x10, 0x1b, 0x31, 0x31, 0x07, 0x07, 0x04, + 0x06, 0x0b, 0x0c, 0x07, + 0x46, 0x27, 0x19, 0x0c, 0x40, 0x44, 0x41, 0x40, 0x40, 0x40, 0x03, 0x03, + 0x41, 0x01, 0x0c, 0x01, + 0x04, 0x10, 0x41, 0x46, 0x01, 0x18, 0x01, 0x46, 0x46, 0x04, 0x0c, 0x11, + 0x0e, 0x11, 0x41, 0x01, + 0x0c, 0x01, 0x04, 0x10, 0x41, 0x46, 0x01, 0x18, 0x01, 0x46, 0x46, 0x04, + 0x0c, 0x11, 0x0e, 0x11, + 0x1e, 0x44, 0x2b, 0x40, 0x48, 0x40, 0x03, 0x07, 0x03, 0x0e, 0x0e, 0x1b, + 0x07, 0x14, 0x01, 0x44, + 0x1b, 0x07, 0x40, 0x14, 0x01, 0x44, 0x1b, 0x07, 0x40, 0x14, 0x01, 0x44, + 0x1b, 0x07, 0x40, 0x4b, + 0x07, 0x0e, 0x0e, 0x19, 0x1e, 0x19, 0x1e, 0x0c, 0x17, 0x01, 0x44, 0x17, + 0x01, 0x44, 0x40, 0x40, + 0x40, 0x0e, 0x0e, 0x0c, 0x40, 0x0f, 0x0c, 0x09, 0x09, 0x2b, 0x27, 0x1b, + 0x07, 0x1e, 0x1b, 0x13, + 0x43, 0x1e, 0x14, 0x0c, 0x40, 0x0c, 0x13, 0x09, 0x19, 0x0c, 0x24, 0x16, + 0x19, 0x0c, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x4f, 0x1a, 0x03, 0x48, 0x40, 0x05, 0x4f, 0x5a, 0x27, 0x40, 0x03, + 0x40, 0x40, 0x40, 0x0f, + 0x03, 0x11, 0x02, 0x17, 0x06, 0x11, 0x1d, 0x34, 0x34, 0x07, 0x07, 0x04, + 0x07, 0x0b, 0x0e, 0x07, + 0x45, 0x27, 0x1a, 0x0c, 0x40, 0x44, 0x42, 0x40, 0x40, 0x40, 0x03, 0x03, + 0x40, 0x02, 0x0e, 0x02, + 0x06, 0x11, 0x40, 0x45, 0x02, 0x19, 0x02, 0x45, 0x45, 0x06, 0x0e, 0x12, + 0x0f, 0x12, 0x40, 0x02, + 0x0e, 0x02, 0x06, 0x11, 0x40, 0x45, 0x02, 0x19, 0x02, 0x45, 0x45, 0x06, + 0x0e, 0x12, 0x0f, 0x12, + 0x1f, 0x44, 0x2d, 0x40, 0x48, 0x40, 0x03, 0x07, 0x03, 0x0f, 0x0f, 0x1d, + 0x07, 0x14, 0x00, 0x44, + 0x1b, 0x07, 0x40, 0x14, 0x00, 0x44, 0x1b, 0x07, 0x40, 0x14, 0x00, 0x44, + 0x1b, 0x07, 0x40, 0x4b, + 0x07, 0x0f, 0x0f, 0x1a, 0x1f, 0x1a, 0x1f, 0x0c, 0x17, 0x00, 0x44, 0x17, + 0x00, 0x44, 0x40, 0x40, + 0x40, 0x0d, 0x0d, 0x0c, 0x40, 0x0f, 0x0c, 0x08, 0x08, 0x2b, 0x27, 0x1b, + 0x07, 0x1f, 0x1b, 0x13, + 0x43, 0x1d, 0x14, 0x0c, 0x40, 0x0c, 0x13, 0x08, 0x1a, 0x0c, 0x26, 0x17, + 0x1a, 0x0c, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x4f, 0x1b, 0x03, 0x48, 0x40, 0x04, 0x4f, 0x5b, 0x27, 0x40, 0x03, + 0x40, 0x40, 0x40, 0x0f, + 0x03, 0x13, 0x03, 0x17, 0x07, 0x13, 0x1f, 0x36, 0x36, 0x07, 0x07, 0x04, + 0x07, 0x0b, 0x0f, 0x07, + 0x44, 0x27, 0x1b, 0x0c, 0x40, 0x44, 0x43, 0x40, 0x40, 0x40, 0x03, 0x03, + 0x40, 0x03, 0x0f, 0x03, + 0x07, 0x13, 0x40, 0x44, 0x03, 0x1b, 0x03, 0x44, 0x44, 0x07, 0x0f, 0x13, + 0x0f, 0x13, 0x40, 0x03, + 0x0f, 0x03, 0x07, 0x13, 0x40, 0x44, 0x03, 0x1b, 0x03, 0x44, 0x44, 0x07, + 0x0f, 0x13, 0x0f, 0x13, + 0x1f, 0x44, 0x2f, 0x40, 0x48, 0x40, 0x03, 0x07, 0x03, 0x0f, 0x0f, 0x1f, + 0x07, 0x14, 0x00, 0x44, + 0x1b, 0x07, 0x40, 0x14, 0x00, 0x44, 0x1b, 0x07, 0x40, 0x14, 0x00, 0x44, + 0x1b, 0x07, 0x40, 0x4b, + 0x07, 0x0f, 0x0f, 0x1b, 0x1f, 0x1b, 0x1f, 0x0c, 0x17, 0x00, 0x44, 0x17, + 0x00, 0x44, 0x40, 0x40, + 0x40, 0x0c, 0x0c, 0x0c, 0x40, 0x0f, 0x0c, 0x08, 0x08, 0x2b, 0x27, 0x1b, + 0x07, 0x1f, 0x1b, 0x13, + 0x43, 0x1c, 0x14, 0x0c, 0x40, 0x0c, 0x13, 0x08, 0x1b, 0x0c, 0x27, 0x17, + 0x1b, 0x0c, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x50, 0x1c, 0x04, 0x47, 0x40, 0x03, 0x50, 0x5c, 0x27, 0x40, 0x04, + 0x40, 0x40, 0x40, 0x0f, + 0x04, 0x14, 0x04, 0x18, 0x08, 0x14, 0x21, 0x39, 0x39, 0x07, 0x07, 0x03, + 0x08, 0x0c, 0x10, 0x07, + 0x43, 0x27, 0x1c, 0x0b, 0x40, 0x43, 0x44, 0x40, 0x40, 0x40, 0x04, 0x04, + 0x00, 0x04, 0x10, 0x04, + 0x08, 0x14, 0x00, 0x43, 0x04, 0x1c, 0x04, 0x43, 0x43, 0x08, 0x10, 0x14, + 0x10, 0x14, 0x00, 0x04, + 0x10, 0x04, 0x08, 0x14, 0x00, 0x43, 0x04, 0x1c, 0x04, 0x43, 0x43, 0x08, + 0x10, 0x14, 0x10, 0x14, + 0x20, 0x43, 0x31, 0x40, 0x48, 0x40, 0x04, 0x07, 0x04, 0x10, 0x10, 0x21, + 0x07, 0x13, 0x40, 0x43, + 0x1c, 0x07, 0x40, 0x13, 0x40, 0x43, 0x1c, 0x07, 0x40, 0x13, 0x40, 0x43, + 0x1c, 0x07, 0x40, 0x4c, + 0x07, 0x10, 0x10, 0x1c, 0x20, 0x1c, 0x20, 0x0b, 0x17, 0x40, 0x43, 0x17, + 0x40, 0x43, 0x40, 0x40, + 0x40, 0x0b, 0x0b, 0x0b, 0x40, 0x0f, 0x0b, 0x07, 0x07, 0x2c, 0x27, 0x1c, + 0x07, 0x20, 0x1c, 0x14, + 0x44, 0x1b, 0x13, 0x0b, 0x40, 0x0b, 0x14, 0x07, 0x1c, 0x0b, 0x28, 0x18, + 0x1c, 0x0b, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x51, 0x1d, 0x04, 0x47, 0x40, 0x02, 0x51, 0x5d, 0x27, 0x40, 0x04, + 0x40, 0x40, 0x40, 0x0f, + 0x04, 0x16, 0x05, 0x18, 0x09, 0x16, 0x22, 0x3b, 0x3b, 0x07, 0x07, 0x03, + 0x08, 0x0c, 0x11, 0x07, + 0x42, 0x27, 0x1d, 0x0b, 0x40, 0x43, 0x45, 0x40, 0x40, 0x40, 0x04, 0x04, + 0x00, 0x05, 0x11, 0x05, + 0x09, 0x16, 0x00, 0x42, 0x05, 0x1e, 0x05, 0x42, 0x42, 0x09, 0x11, 0x15, + 0x10, 0x15, 0x00, 0x05, + 0x11, 0x05, 0x09, 0x16, 0x00, 0x42, 0x05, 0x1e, 0x05, 0x42, 0x42, 0x09, + 0x11, 0x15, 0x10, 0x15, + 0x20, 0x43, 0x32, 0x40, 0x48, 0x40, 0x04, 0x07, 0x04, 0x10, 0x10, 0x22, + 0x07, 0x13, 0x41, 0x43, + 0x1c, 0x07, 0x40, 0x13, 0x41, 0x43, 0x1c, 0x07, 0x40, 0x13, 0x41, 0x43, + 0x1c, 0x07, 0x40, 0x4c, + 0x07, 0x10, 0x10, 0x1d, 0x20, 0x1d, 0x20, 0x0b, 0x17, 0x41, 0x43, 0x17, + 0x41, 0x43, 0x40, 0x40, + 0x40, 0x0a, 0x0a, 0x0b, 0x40, 0x0f, 0x0b, 0x06, 0x06, 0x2c, 0x27, 0x1c, + 0x07, 0x20, 0x1c, 0x14, + 0x44, 0x1a, 0x13, 0x0b, 0x40, 0x0b, 0x14, 0x06, 0x1d, 0x0b, 0x29, 0x18, + 0x1d, 0x0b, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x51, 0x1e, 0x04, 0x46, 0x40, 0x01, 0x51, 0x5e, 0x27, 0x40, 0x04, + 0x40, 0x40, 0x40, 0x0f, + 0x04, 0x18, 0x06, 0x19, 0x0b, 0x18, 0x24, 0x3e, 0x3e, 0x07, 0x07, 0x03, + 0x09, 0x0c, 0x13, 0x07, + 0x41, 0x27, 0x1e, 0x0b, 0x40, 0x43, 0x46, 0x40, 0x40, 0x40, 0x04, 0x04, + 0x01, 0x06, 0x13, 0x06, + 0x0b, 0x18, 0x01, 0x41, 0x06, 0x20, 0x06, 0x41, 0x41, 0x0b, 0x13, 0x16, + 0x11, 0x16, 0x01, 0x06, + 0x13, 0x06, 0x0b, 0x18, 0x01, 0x41, 0x06, 0x20, 0x06, 0x41, 0x41, 0x0b, + 0x13, 0x16, 0x11, 0x16, + 0x21, 0x43, 0x34, 0x40, 0x48, 0x40, 0x04, 0x07, 0x04, 0x11, 0x11, 0x24, + 0x07, 0x13, 0x41, 0x43, + 0x1c, 0x07, 0x40, 0x13, 0x41, 0x43, 0x1c, 0x07, 0x40, 0x13, 0x41, 0x43, + 0x1c, 0x07, 0x40, 0x4c, + 0x07, 0x11, 0x11, 0x1e, 0x21, 0x1e, 0x21, 0x0b, 0x17, 0x41, 0x43, 0x17, + 0x41, 0x43, 0x40, 0x40, + 0x40, 0x09, 0x09, 0x0b, 0x40, 0x0f, 0x0b, 0x06, 0x06, 0x2c, 0x27, 0x1c, + 0x07, 0x21, 0x1c, 0x14, + 0x44, 0x19, 0x13, 0x0b, 0x40, 0x0b, 0x14, 0x06, 0x1e, 0x0b, 0x2b, 0x19, + 0x1e, 0x0b, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x52, 0x1f, 0x05, 0x45, 0x40, 0x00, 0x52, 0x5f, 0x27, 0x40, 0x05, + 0x40, 0x40, 0x40, 0x0f, + 0x05, 0x19, 0x07, 0x1a, 0x0c, 0x19, 0x26, 0x3e, 0x3e, 0x07, 0x07, 0x02, + 0x0a, 0x0d, 0x14, 0x07, + 0x40, 0x27, 0x1f, 0x0a, 0x40, 0x42, 0x47, 0x40, 0x40, 0x40, 0x05, 0x05, + 0x02, 0x07, 0x14, 0x07, + 0x0c, 0x19, 0x02, 0x40, 0x07, 0x21, 0x07, 0x40, 0x40, 0x0c, 0x14, 0x17, + 0x12, 0x17, 0x02, 0x07, + 0x14, 0x07, 0x0c, 0x19, 0x02, 0x40, 0x07, 0x21, 0x07, 0x40, 0x40, 0x0c, + 0x14, 0x17, 0x12, 0x17, + 0x22, 0x42, 0x36, 0x40, 0x48, 0x40, 0x05, 0x07, 0x05, 0x12, 0x12, 0x26, + 0x07, 0x12, 0x42, 0x42, + 0x1d, 0x07, 0x40, 0x12, 0x42, 0x42, 0x1d, 0x07, 0x40, 0x12, 0x42, 0x42, + 0x1d, 0x07, 0x40, 0x4d, + 0x07, 0x12, 0x12, 0x1f, 0x22, 0x1f, 0x22, 0x0a, 0x17, 0x42, 0x42, 0x17, + 0x42, 0x42, 0x40, 0x40, + 0x40, 0x08, 0x08, 0x0a, 0x40, 0x0f, 0x0a, 0x05, 0x05, 0x2d, 0x27, 0x1d, + 0x07, 0x22, 0x1d, 0x15, + 0x45, 0x18, 0x12, 0x0a, 0x40, 0x0a, 0x15, 0x05, 0x1f, 0x0a, 0x2c, 0x1a, + 0x1f, 0x0a, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x52, 0x20, 0x05, 0x45, 0x40, 0x40, 0x52, 0x60, 0x27, 0x40, 0x05, + 0x40, 0x40, 0x40, 0x0f, + 0x05, 0x1b, 0x08, 0x1a, 0x0d, 0x1b, 0x28, 0x3e, 0x3e, 0x07, 0x07, 0x02, + 0x0a, 0x0d, 0x15, 0x07, + 0x00, 0x27, 0x20, 0x0a, 0x40, 0x42, 0x48, 0x40, 0x40, 0x40, 0x05, 0x05, + 0x02, 0x08, 0x15, 0x08, + 0x0d, 0x1b, 0x02, 0x00, 0x08, 0x23, 0x08, 0x00, 0x00, 0x0d, 0x15, 0x18, + 0x12, 0x18, 0x02, 0x08, + 0x15, 0x08, 0x0d, 0x1b, 0x02, 0x00, 0x08, 0x23, 0x08, 0x00, 0x00, 0x0d, + 0x15, 0x18, 0x12, 0x18, + 0x22, 0x42, 0x38, 0x40, 0x48, 0x40, 0x05, 0x07, 0x05, 0x12, 0x12, 0x28, + 0x07, 0x12, 0x42, 0x42, + 0x1d, 0x07, 0x40, 0x12, 0x42, 0x42, 0x1d, 0x07, 0x40, 0x12, 0x42, 0x42, + 0x1d, 0x07, 0x40, 0x4d, + 0x07, 0x12, 0x12, 0x20, 0x22, 0x20, 0x22, 0x0a, 0x17, 0x42, 0x42, 0x17, + 0x42, 0x42, 0x40, 0x40, + 0x40, 0x07, 0x07, 0x0a, 0x40, 0x0f, 0x0a, 0x05, 0x05, 0x2d, 0x27, 0x1d, + 0x07, 0x22, 0x1d, 0x15, + 0x45, 0x17, 0x12, 0x0a, 0x40, 0x0a, 0x15, 0x05, 0x20, 0x0a, 0x2d, 0x1a, + 0x20, 0x0a, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x53, 0x21, 0x05, 0x44, 0x40, 0x41, 0x53, 0x61, 0x27, 0x40, 0x05, + 0x40, 0x40, 0x40, 0x0f, + 0x05, 0x1c, 0x09, 0x1b, 0x0e, 0x1c, 0x2a, 0x3e, 0x3e, 0x07, 0x07, 0x02, + 0x0b, 0x0d, 0x16, 0x07, + 0x01, 0x27, 0x21, 0x0a, 0x40, 0x42, 0x49, 0x40, 0x40, 0x40, 0x05, 0x05, + 0x03, 0x09, 0x16, 0x09, + 0x0e, 0x1c, 0x03, 0x01, 0x09, 0x24, 0x09, 0x01, 0x01, 0x0e, 0x16, 0x19, + 0x13, 0x19, 0x03, 0x09, + 0x16, 0x09, 0x0e, 0x1c, 0x03, 0x01, 0x09, 0x24, 0x09, 0x01, 0x01, 0x0e, + 0x16, 0x19, 0x13, 0x19, + 0x23, 0x42, 0x3a, 0x40, 0x48, 0x40, 0x05, 0x07, 0x05, 0x13, 0x13, 0x2a, + 0x07, 0x12, 0x43, 0x42, + 0x1d, 0x07, 0x40, 0x12, 0x43, 0x42, 0x1d, 0x07, 0x40, 0x12, 0x43, 0x42, + 0x1d, 0x07, 0x40, 0x4d, + 0x07, 0x13, 0x13, 0x21, 0x23, 0x21, 0x23, 0x0a, 0x17, 0x43, 0x42, 0x17, + 0x43, 0x42, 0x40, 0x40, + 0x40, 0x06, 0x06, 0x0a, 0x40, 0x0f, 0x0a, 0x04, 0x04, 0x2d, 0x27, 0x1d, + 0x07, 0x23, 0x1d, 0x15, + 0x45, 0x16, 0x12, 0x0a, 0x40, 0x0a, 0x15, 0x04, 0x21, 0x0a, 0x2e, 0x1b, + 0x21, 0x0a, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x54, 0x22, 0x06, 0x43, 0x40, 0x42, 0x54, 0x62, 0x27, 0x40, 0x06, + 0x40, 0x40, 0x40, 0x0f, + 0x06, 0x1e, 0x0a, 0x1c, 0x10, 0x1e, 0x2c, 0x3e, 0x3e, 0x07, 0x07, 0x01, + 0x0c, 0x0e, 0x18, 0x07, + 0x02, 0x27, 0x22, 0x09, 0x40, 0x41, 0x4a, 0x40, 0x40, 0x40, 0x06, 0x06, + 0x04, 0x0a, 0x18, 0x0a, + 0x10, 0x1e, 0x04, 0x02, 0x0a, 0x26, 0x0a, 0x02, 0x02, 0x10, 0x18, 0x1a, + 0x14, 0x1a, 0x04, 0x0a, + 0x18, 0x0a, 0x10, 0x1e, 0x04, 0x02, 0x0a, 0x26, 0x0a, 0x02, 0x02, 0x10, + 0x18, 0x1a, 0x14, 0x1a, + 0x24, 0x41, 0x3c, 0x40, 0x48, 0x40, 0x06, 0x07, 0x06, 0x14, 0x14, 0x2c, + 0x07, 0x11, 0x44, 0x41, + 0x1e, 0x07, 0x40, 0x11, 0x44, 0x41, 0x1e, 0x07, 0x40, 0x11, 0x44, 0x41, + 0x1e, 0x07, 0x40, 0x4e, + 0x07, 0x14, 0x14, 0x22, 0x24, 0x22, 0x24, 0x09, 0x17, 0x44, 0x41, 0x17, + 0x44, 0x41, 0x40, 0x40, + 0x40, 0x05, 0x05, 0x09, 0x40, 0x0f, 0x09, 0x03, 0x03, 0x2e, 0x27, 0x1e, + 0x07, 0x24, 0x1e, 0x16, + 0x46, 0x15, 0x11, 0x09, 0x40, 0x09, 0x16, 0x03, 0x22, 0x09, 0x30, 0x1c, + 0x22, 0x09, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x54, 0x23, 0x06, 0x43, 0x40, 0x43, 0x54, 0x63, 0x27, 0x40, 0x06, + 0x40, 0x40, 0x40, 0x0f, + 0x06, 0x1f, 0x0b, 0x1c, 0x11, 0x1f, 0x2e, 0x3e, 0x3e, 0x07, 0x07, 0x01, + 0x0c, 0x0e, 0x19, 0x07, + 0x03, 0x27, 0x23, 0x09, 0x40, 0x41, 0x4b, 0x40, 0x40, 0x40, 0x06, 0x06, + 0x04, 0x0b, 0x19, 0x0b, + 0x11, 0x1f, 0x04, 0x03, 0x0b, 0x27, 0x0b, 0x03, 0x03, 0x11, 0x19, 0x1b, + 0x14, 0x1b, 0x04, 0x0b, + 0x19, 0x0b, 0x11, 0x1f, 0x04, 0x03, 0x0b, 0x27, 0x0b, 0x03, 0x03, 0x11, + 0x19, 0x1b, 0x14, 0x1b, + 0x24, 0x41, 0x3e, 0x40, 0x48, 0x40, 0x06, 0x07, 0x06, 0x14, 0x14, 0x2e, + 0x07, 0x11, 0x44, 0x41, + 0x1e, 0x07, 0x40, 0x11, 0x44, 0x41, 0x1e, 0x07, 0x40, 0x11, 0x44, 0x41, + 0x1e, 0x07, 0x40, 0x4e, + 0x07, 0x14, 0x14, 0x23, 0x24, 0x23, 0x24, 0x09, 0x17, 0x44, 0x41, 0x17, + 0x44, 0x41, 0x40, 0x40, + 0x40, 0x04, 0x04, 0x09, 0x40, 0x0f, 0x09, 0x03, 0x03, 0x2e, 0x27, 0x1e, + 0x07, 0x24, 0x1e, 0x16, + 0x46, 0x14, 0x11, 0x09, 0x40, 0x09, 0x16, 0x03, 0x23, 0x09, 0x31, 0x1c, + 0x23, 0x09, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x55, 0x24, 0x06, 0x42, 0x40, 0x44, 0x55, 0x64, 0x27, 0x40, 0x06, + 0x40, 0x40, 0x40, 0x0f, + 0x06, 0x21, 0x0c, 0x1d, 0x12, 0x21, 0x30, 0x3e, 0x3e, 0x07, 0x07, 0x01, + 0x0d, 0x0e, 0x1a, 0x07, + 0x04, 0x27, 0x24, 0x09, 0x40, 0x41, 0x4c, 0x40, 0x40, 0x40, 0x06, 0x06, + 0x05, 0x0c, 0x1a, 0x0c, + 0x12, 0x21, 0x05, 0x04, 0x0c, 0x29, 0x0c, 0x04, 0x04, 0x12, 0x1a, 0x1c, + 0x15, 0x1c, 0x05, 0x0c, + 0x1a, 0x0c, 0x12, 0x21, 0x05, 0x04, 0x0c, 0x29, 0x0c, 0x04, 0x04, 0x12, + 0x1a, 0x1c, 0x15, 0x1c, + 0x25, 0x41, 0x3e, 0x40, 0x48, 0x40, 0x06, 0x07, 0x06, 0x15, 0x15, 0x30, + 0x07, 0x11, 0x45, 0x41, + 0x1e, 0x07, 0x40, 0x11, 0x45, 0x41, 0x1e, 0x07, 0x40, 0x11, 0x45, 0x41, + 0x1e, 0x07, 0x40, 0x4e, + 0x07, 0x15, 0x15, 0x24, 0x25, 0x24, 0x25, 0x09, 0x17, 0x45, 0x41, 0x17, + 0x45, 0x41, 0x40, 0x40, + 0x40, 0x03, 0x03, 0x09, 0x40, 0x0f, 0x09, 0x02, 0x02, 0x2e, 0x27, 0x1e, + 0x07, 0x25, 0x1e, 0x16, + 0x46, 0x13, 0x11, 0x09, 0x40, 0x09, 0x16, 0x02, 0x24, 0x09, 0x32, 0x1d, + 0x24, 0x09, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x56, 0x24, 0x06, 0x42, 0x40, 0x45, 0x56, 0x65, 0x27, 0x40, 0x06, + 0x40, 0x40, 0x40, 0x0f, + 0x06, 0x22, 0x0c, 0x1d, 0x13, 0x22, 0x31, 0x3e, 0x3e, 0x07, 0x07, 0x00, + 0x0d, 0x0e, 0x1b, 0x07, + 0x04, 0x27, 0x24, 0x08, 0x40, 0x41, 0x4d, 0x40, 0x40, 0x40, 0x06, 0x06, + 0x05, 0x0c, 0x1b, 0x0c, + 0x13, 0x22, 0x05, 0x04, 0x0c, 0x2a, 0x0c, 0x04, 0x04, 0x13, 0x1b, 0x1c, + 0x15, 0x1c, 0x05, 0x0c, + 0x1b, 0x0c, 0x13, 0x22, 0x05, 0x04, 0x0c, 0x2a, 0x0c, 0x04, 0x04, 0x13, + 0x1b, 0x1c, 0x15, 0x1c, + 0x25, 0x41, 0x3e, 0x40, 0x48, 0x40, 0x06, 0x07, 0x06, 0x15, 0x15, 0x31, + 0x07, 0x10, 0x46, 0x41, + 0x1e, 0x07, 0x40, 0x10, 0x46, 0x41, 0x1e, 0x07, 0x40, 0x10, 0x46, 0x41, + 0x1e, 0x07, 0x40, 0x4f, + 0x07, 0x15, 0x15, 0x24, 0x25, 0x24, 0x25, 0x08, 0x17, 0x46, 0x41, 0x17, + 0x46, 0x41, 0x40, 0x40, + 0x40, 0x02, 0x02, 0x08, 0x40, 0x0f, 0x08, 0x01, 0x01, 0x2e, 0x27, 0x1e, + 0x07, 0x25, 0x1e, 0x16, + 0x47, 0x12, 0x10, 0x08, 0x40, 0x08, 0x16, 0x01, 0x24, 0x08, 0x33, 0x1d, + 0x24, 0x08, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x56, 0x25, 0x07, 0x41, 0x40, 0x45, 0x56, 0x65, 0x27, 0x40, 0x07, + 0x40, 0x40, 0x40, 0x0f, + 0x07, 0x24, 0x0d, 0x1e, 0x15, 0x24, 0x33, 0x3e, 0x3e, 0x07, 0x07, 0x00, + 0x0e, 0x0f, 0x1d, 0x07, + 0x05, 0x27, 0x25, 0x08, 0x40, 0x40, 0x4d, 0x40, 0x40, 0x40, 0x07, 0x07, + 0x06, 0x0d, 0x1d, 0x0d, + 0x15, 0x24, 0x06, 0x05, 0x0d, 0x2c, 0x0d, 0x05, 0x05, 0x15, 0x1d, 0x1d, + 0x16, 0x1d, 0x06, 0x0d, + 0x1d, 0x0d, 0x15, 0x24, 0x06, 0x05, 0x0d, 0x2c, 0x0d, 0x05, 0x05, 0x15, + 0x1d, 0x1d, 0x16, 0x1d, + 0x26, 0x40, 0x3e, 0x40, 0x48, 0x40, 0x07, 0x07, 0x07, 0x16, 0x16, 0x33, + 0x07, 0x10, 0x46, 0x40, + 0x1f, 0x07, 0x40, 0x10, 0x46, 0x40, 0x1f, 0x07, 0x40, 0x10, 0x46, 0x40, + 0x1f, 0x07, 0x40, 0x4f, + 0x07, 0x16, 0x16, 0x25, 0x26, 0x25, 0x26, 0x08, 0x17, 0x46, 0x40, 0x17, + 0x46, 0x40, 0x40, 0x40, + 0x40, 0x02, 0x02, 0x08, 0x40, 0x0f, 0x08, 0x01, 0x01, 0x2f, 0x27, 0x1f, + 0x07, 0x26, 0x1f, 0x17, + 0x47, 0x12, 0x10, 0x08, 0x40, 0x08, 0x17, 0x01, 0x25, 0x08, 0x35, 0x1e, + 0x25, 0x08, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x57, 0x26, 0x07, 0x40, 0x40, 0x46, 0x57, 0x66, 0x27, 0x40, 0x07, + 0x40, 0x40, 0x40, 0x0f, + 0x07, 0x26, 0x0e, 0x1f, 0x16, 0x26, 0x35, 0x3e, 0x3e, 0x07, 0x07, 0x00, + 0x0f, 0x0f, 0x1e, 0x07, + 0x06, 0x27, 0x26, 0x08, 0x40, 0x40, 0x4e, 0x40, 0x40, 0x40, 0x07, 0x07, + 0x07, 0x0e, 0x1e, 0x0e, + 0x16, 0x26, 0x07, 0x06, 0x0e, 0x2e, 0x0e, 0x06, 0x06, 0x16, 0x1e, 0x1e, + 0x17, 0x1e, 0x07, 0x0e, + 0x1e, 0x0e, 0x16, 0x26, 0x07, 0x06, 0x0e, 0x2e, 0x0e, 0x06, 0x06, 0x16, + 0x1e, 0x1e, 0x17, 0x1e, + 0x27, 0x40, 0x3e, 0x40, 0x48, 0x40, 0x07, 0x07, 0x07, 0x17, 0x17, 0x35, + 0x07, 0x10, 0x47, 0x40, + 0x1f, 0x07, 0x40, 0x10, 0x47, 0x40, 0x1f, 0x07, 0x40, 0x10, 0x47, 0x40, + 0x1f, 0x07, 0x40, 0x4f, + 0x07, 0x17, 0x17, 0x26, 0x27, 0x26, 0x27, 0x08, 0x17, 0x47, 0x40, 0x17, + 0x47, 0x40, 0x40, 0x40, + 0x40, 0x01, 0x01, 0x08, 0x40, 0x0f, 0x08, 0x00, 0x00, 0x2f, 0x27, 0x1f, + 0x07, 0x27, 0x1f, 0x17, + 0x47, 0x11, 0x10, 0x08, 0x40, 0x08, 0x17, 0x00, 0x26, 0x08, 0x36, 0x1f, + 0x26, 0x08, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x57, 0x27, 0x07, 0x40, 0x40, 0x47, 0x57, 0x67, 0x27, 0x40, 0x07, + 0x40, 0x40, 0x40, 0x0f, + 0x07, 0x27, 0x0f, 0x1f, 0x17, 0x27, 0x37, 0x3e, 0x3e, 0x07, 0x07, 0x00, + 0x0f, 0x0f, 0x1f, 0x07, + 0x07, 0x27, 0x27, 0x08, 0x40, 0x40, 0x4f, 0x40, 0x40, 0x40, 0x07, 0x07, + 0x07, 0x0f, 0x1f, 0x0f, + 0x17, 0x27, 0x07, 0x07, 0x0f, 0x2f, 0x0f, 0x07, 0x07, 0x17, 0x1f, 0x1f, + 0x17, 0x1f, 0x07, 0x0f, + 0x1f, 0x0f, 0x17, 0x27, 0x07, 0x07, 0x0f, 0x2f, 0x0f, 0x07, 0x07, 0x17, + 0x1f, 0x1f, 0x17, 0x1f, + 0x27, 0x40, 0x3e, 0x40, 0x48, 0x40, 0x07, 0x07, 0x07, 0x17, 0x17, 0x37, + 0x07, 0x10, 0x47, 0x40, + 0x1f, 0x07, 0x40, 0x10, 0x47, 0x40, 0x1f, 0x07, 0x40, 0x10, 0x47, 0x40, + 0x1f, 0x07, 0x40, 0x4f, + 0x07, 0x17, 0x17, 0x27, 0x27, 0x27, 0x27, 0x08, 0x17, 0x47, 0x40, 0x17, + 0x47, 0x40, 0x40, 0x40, + 0x40, 0x00, 0x00, 0x08, 0x40, 0x0f, 0x08, 0x00, 0x00, 0x2f, 0x27, 0x1f, + 0x07, 0x27, 0x1f, 0x17, + 0x47, 0x10, 0x10, 0x08, 0x40, 0x08, 0x17, 0x00, 0x27, 0x08, 0x37, 0x1f, + 0x27, 0x08, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x48, 0x48, 0x60, 0x40, 0x27, 0x07, 0x07, 0x1f, 0x40, 0x48, + 0x40, 0x40, 0x17, 0x0f, + 0x48, 0x68, 0x40, 0x07, 0x68, 0x68, 0x68, 0x68, 0x68, 0x07, 0x07, 0x0f, + 0x3e, 0x17, 0x40, 0x07, + 0x68, 0x27, 0x50, 0x17, 0x40, 0x07, 0x1f, 0x40, 0x40, 0x40, 0x48, 0x48, + 0x58, 0x60, 0x50, 0x60, + 0x68, 0x60, 0x58, 0x68, 0x68, 0x68, 0x58, 0x60, 0x68, 0x68, 0x68, 0x50, + 0x48, 0x58, 0x58, 0x60, + 0x50, 0x60, 0x68, 0x60, 0x58, 0x68, 0x68, 0x68, 0x58, 0x60, 0x68, 0x68, + 0x68, 0x50, 0x48, 0x58, + 0x07, 0x50, 0x58, 0x40, 0x40, 0x40, 0x48, 0x07, 0x48, 0x48, 0x48, 0x68, + 0x50, 0x1f, 0x17, 0x50, + 0x0f, 0x07, 0x40, 0x1f, 0x17, 0x50, 0x0f, 0x07, 0x40, 0x1f, 0x17, 0x50, + 0x0f, 0x07, 0x40, 0x40, + 0x07, 0x40, 0x40, 0x40, 0x07, 0x40, 0x07, 0x17, 0x17, 0x17, 0x50, 0x17, + 0x17, 0x50, 0x40, 0x40, + 0x40, 0x2f, 0x17, 0x17, 0x40, 0x0f, 0x17, 0x1f, 0x1f, 0x1f, 0x27, 0x0f, + 0x07, 0x07, 0x0f, 0x40, + 0x07, 0x3e, 0x1f, 0x17, 0x40, 0x0f, 0x17, 0x1f, 0x48, 0x17, 0x48, 0x48, + 0x48, 0x17, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x47, 0x47, 0x5f, 0x40, 0x27, 0x07, 0x07, 0x20, 0x40, 0x47, + 0x40, 0x40, 0x17, 0x0f, + 0x47, 0x66, 0x40, 0x08, 0x66, 0x66, 0x66, 0x65, 0x65, 0x07, 0x07, 0x0f, + 0x3e, 0x17, 0x00, 0x07, + 0x67, 0x27, 0x4e, 0x17, 0x40, 0x07, 0x1f, 0x40, 0x40, 0x40, 0x47, 0x47, + 0x57, 0x5f, 0x4f, 0x5f, + 0x66, 0x5e, 0x57, 0x67, 0x67, 0x66, 0x57, 0x5f, 0x67, 0x67, 0x66, 0x4f, + 0x47, 0x56, 0x57, 0x5f, + 0x4f, 0x5f, 0x66, 0x5e, 0x57, 0x67, 0x67, 0x66, 0x57, 0x5f, 0x67, 0x67, + 0x66, 0x4f, 0x47, 0x56, + 0x08, 0x4f, 0x56, 0x40, 0x40, 0x40, 0x47, 0x07, 0x47, 0x47, 0x47, 0x66, + 0x4f, 0x1f, 0x17, 0x4f, + 0x10, 0x07, 0x40, 0x1f, 0x17, 0x4f, 0x10, 0x07, 0x40, 0x1f, 0x17, 0x4f, + 0x10, 0x07, 0x40, 0x40, + 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x17, 0x17, 0x17, 0x4f, 0x17, + 0x17, 0x4f, 0x40, 0x40, + 0x40, 0x2f, 0x17, 0x17, 0x40, 0x0f, 0x17, 0x1f, 0x1f, 0x20, 0x27, 0x10, + 0x07, 0x08, 0x10, 0x00, + 0x07, 0x3e, 0x1f, 0x17, 0x40, 0x0f, 0x17, 0x1f, 0x47, 0x17, 0x46, 0x47, + 0x47, 0x17, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x46, 0x47, 0x5e, 0x40, 0x26, 0x06, 0x06, 0x20, 0x40, 0x47, + 0x40, 0x40, 0x16, 0x0f, + 0x47, 0x64, 0x40, 0x08, 0x65, 0x64, 0x64, 0x63, 0x63, 0x07, 0x07, 0x0f, + 0x3e, 0x17, 0x01, 0x07, + 0x66, 0x27, 0x4d, 0x17, 0x40, 0x07, 0x1e, 0x40, 0x40, 0x40, 0x47, 0x47, + 0x56, 0x5e, 0x4e, 0x5e, + 0x65, 0x5d, 0x56, 0x66, 0x66, 0x64, 0x56, 0x5e, 0x66, 0x66, 0x64, 0x4e, + 0x46, 0x55, 0x56, 0x5e, + 0x4e, 0x5e, 0x65, 0x5d, 0x56, 0x66, 0x66, 0x64, 0x56, 0x5e, 0x66, 0x66, + 0x64, 0x4e, 0x46, 0x55, + 0x09, 0x4f, 0x54, 0x40, 0x40, 0x40, 0x47, 0x07, 0x47, 0x46, 0x46, 0x64, + 0x4e, 0x1f, 0x16, 0x4f, + 0x10, 0x07, 0x40, 0x1f, 0x16, 0x4f, 0x10, 0x07, 0x40, 0x1f, 0x16, 0x4f, + 0x10, 0x07, 0x40, 0x40, + 0x07, 0x00, 0x00, 0x01, 0x09, 0x01, 0x09, 0x17, 0x17, 0x16, 0x4f, 0x17, + 0x16, 0x4f, 0x40, 0x40, + 0x40, 0x2e, 0x17, 0x17, 0x40, 0x0f, 0x17, 0x1e, 0x1e, 0x20, 0x27, 0x10, + 0x07, 0x09, 0x10, 0x01, + 0x07, 0x3e, 0x1f, 0x17, 0x40, 0x0f, 0x17, 0x1e, 0x46, 0x17, 0x45, 0x46, + 0x46, 0x17, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x45, 0x47, 0x5e, 0x40, 0x25, 0x06, 0x05, 0x20, 0x40, 0x47, + 0x40, 0x40, 0x16, 0x0f, + 0x47, 0x63, 0x40, 0x08, 0x64, 0x63, 0x62, 0x60, 0x60, 0x07, 0x07, 0x0f, + 0x3e, 0x17, 0x01, 0x07, + 0x65, 0x27, 0x4c, 0x17, 0x40, 0x07, 0x1d, 0x40, 0x40, 0x40, 0x47, 0x47, + 0x56, 0x5d, 0x4e, 0x5d, + 0x64, 0x5c, 0x56, 0x65, 0x65, 0x63, 0x56, 0x5e, 0x65, 0x65, 0x63, 0x4d, + 0x46, 0x54, 0x56, 0x5d, + 0x4e, 0x5d, 0x64, 0x5c, 0x56, 0x65, 0x65, 0x63, 0x56, 0x5e, 0x65, 0x65, + 0x63, 0x4d, 0x46, 0x54, + 0x09, 0x4f, 0x52, 0x40, 0x40, 0x40, 0x47, 0x07, 0x47, 0x46, 0x46, 0x62, + 0x4e, 0x1f, 0x16, 0x4f, + 0x10, 0x07, 0x40, 0x1f, 0x16, 0x4f, 0x10, 0x07, 0x40, 0x1f, 0x16, 0x4f, + 0x10, 0x07, 0x40, 0x40, + 0x07, 0x00, 0x00, 0x01, 0x09, 0x01, 0x09, 0x17, 0x17, 0x16, 0x4f, 0x17, + 0x16, 0x4f, 0x40, 0x40, + 0x40, 0x2d, 0x17, 0x17, 0x40, 0x0f, 0x17, 0x1e, 0x1e, 0x20, 0x27, 0x10, + 0x07, 0x09, 0x10, 0x01, + 0x07, 0x3e, 0x1f, 0x17, 0x40, 0x0f, 0x17, 0x1e, 0x45, 0x17, 0x44, 0x45, + 0x45, 0x17, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x44, 0x46, 0x5d, 0x40, 0x24, 0x05, 0x04, 0x21, 0x40, 0x46, + 0x40, 0x40, 0x15, 0x0f, + 0x46, 0x61, 0x40, 0x09, 0x63, 0x61, 0x60, 0x5e, 0x5e, 0x07, 0x07, 0x0e, + 0x3e, 0x16, 0x02, 0x07, + 0x64, 0x27, 0x4b, 0x16, 0x40, 0x06, 0x1c, 0x40, 0x40, 0x40, 0x46, 0x46, + 0x55, 0x5c, 0x4d, 0x5c, + 0x63, 0x5b, 0x55, 0x64, 0x64, 0x61, 0x55, 0x5d, 0x64, 0x64, 0x61, 0x4c, + 0x45, 0x53, 0x55, 0x5c, + 0x4d, 0x5c, 0x63, 0x5b, 0x55, 0x64, 0x64, 0x61, 0x55, 0x5d, 0x64, 0x64, + 0x61, 0x4c, 0x45, 0x53, + 0x0a, 0x4e, 0x50, 0x40, 0x41, 0x40, 0x46, 0x07, 0x46, 0x45, 0x45, 0x60, + 0x4d, 0x1e, 0x15, 0x4e, + 0x11, 0x07, 0x40, 0x1e, 0x15, 0x4e, 0x11, 0x07, 0x40, 0x1e, 0x15, 0x4e, + 0x11, 0x07, 0x40, 0x41, + 0x07, 0x01, 0x01, 0x02, 0x0a, 0x02, 0x0a, 0x16, 0x17, 0x15, 0x4e, 0x17, + 0x15, 0x4e, 0x40, 0x40, + 0x40, 0x2c, 0x16, 0x16, 0x40, 0x0f, 0x16, 0x1d, 0x1d, 0x21, 0x27, 0x11, + 0x07, 0x0a, 0x11, 0x02, + 0x06, 0x3e, 0x1e, 0x16, 0x40, 0x0f, 0x16, 0x1d, 0x44, 0x16, 0x43, 0x44, + 0x44, 0x16, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x43, 0x46, 0x5c, 0x40, 0x23, 0x04, 0x03, 0x21, 0x40, 0x46, + 0x40, 0x40, 0x14, 0x0f, + 0x46, 0x60, 0x40, 0x09, 0x61, 0x60, 0x5e, 0x5b, 0x5b, 0x07, 0x07, 0x0e, + 0x3e, 0x16, 0x03, 0x07, + 0x63, 0x27, 0x49, 0x16, 0x40, 0x06, 0x1b, 0x40, 0x40, 0x40, 0x46, 0x46, + 0x54, 0x5b, 0x4c, 0x5b, + 0x61, 0x59, 0x54, 0x63, 0x63, 0x60, 0x54, 0x5c, 0x63, 0x63, 0x60, 0x4b, + 0x44, 0x51, 0x54, 0x5b, + 0x4c, 0x5b, 0x61, 0x59, 0x54, 0x63, 0x63, 0x60, 0x54, 0x5c, 0x63, 0x63, + 0x60, 0x4b, 0x44, 0x51, + 0x0b, 0x4e, 0x4e, 0x40, 0x41, 0x40, 0x46, 0x07, 0x46, 0x44, 0x44, 0x5e, + 0x4c, 0x1e, 0x14, 0x4e, + 0x11, 0x07, 0x40, 0x1e, 0x14, 0x4e, 0x11, 0x07, 0x40, 0x1e, 0x14, 0x4e, + 0x11, 0x07, 0x40, 0x41, + 0x07, 0x01, 0x01, 0x03, 0x0b, 0x03, 0x0b, 0x16, 0x17, 0x14, 0x4e, 0x17, + 0x14, 0x4e, 0x40, 0x40, + 0x40, 0x2b, 0x16, 0x16, 0x40, 0x0f, 0x16, 0x1c, 0x1c, 0x21, 0x27, 0x11, + 0x07, 0x0b, 0x11, 0x03, + 0x06, 0x3e, 0x1e, 0x16, 0x40, 0x0f, 0x16, 0x1c, 0x43, 0x16, 0x41, 0x43, + 0x43, 0x16, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x42, 0x46, 0x5c, 0x40, 0x22, 0x04, 0x02, 0x21, 0x40, 0x46, + 0x40, 0x40, 0x14, 0x0f, + 0x46, 0x5e, 0x40, 0x09, 0x60, 0x5e, 0x5c, 0x59, 0x59, 0x07, 0x07, 0x0e, + 0x3e, 0x16, 0x03, 0x07, + 0x62, 0x27, 0x48, 0x16, 0x40, 0x06, 0x1a, 0x40, 0x40, 0x40, 0x46, 0x46, + 0x54, 0x5a, 0x4c, 0x5a, + 0x60, 0x58, 0x54, 0x62, 0x62, 0x5e, 0x54, 0x5c, 0x62, 0x62, 0x5e, 0x4a, + 0x44, 0x50, 0x54, 0x5a, + 0x4c, 0x5a, 0x60, 0x58, 0x54, 0x62, 0x62, 0x5e, 0x54, 0x5c, 0x62, 0x62, + 0x5e, 0x4a, 0x44, 0x50, + 0x0b, 0x4e, 0x4c, 0x40, 0x41, 0x40, 0x46, 0x07, 0x46, 0x44, 0x44, 0x5c, + 0x4c, 0x1e, 0x14, 0x4e, + 0x11, 0x07, 0x40, 0x1e, 0x14, 0x4e, 0x11, 0x07, 0x40, 0x1e, 0x14, 0x4e, + 0x11, 0x07, 0x40, 0x41, + 0x07, 0x01, 0x01, 0x03, 0x0b, 0x03, 0x0b, 0x16, 0x17, 0x14, 0x4e, 0x17, + 0x14, 0x4e, 0x40, 0x40, + 0x40, 0x2a, 0x16, 0x16, 0x40, 0x0f, 0x16, 0x1c, 0x1c, 0x21, 0x27, 0x11, + 0x07, 0x0b, 0x11, 0x03, + 0x06, 0x3e, 0x1e, 0x16, 0x40, 0x0f, 0x16, 0x1c, 0x42, 0x16, 0x40, 0x42, + 0x42, 0x16, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x41, 0x45, 0x5b, 0x40, 0x21, 0x03, 0x01, 0x22, 0x40, 0x45, + 0x40, 0x40, 0x13, 0x0f, + 0x45, 0x5d, 0x40, 0x0a, 0x5f, 0x5d, 0x5a, 0x56, 0x56, 0x07, 0x07, 0x0d, + 0x3e, 0x15, 0x04, 0x07, + 0x61, 0x27, 0x47, 0x15, 0x40, 0x05, 0x19, 0x40, 0x40, 0x40, 0x45, 0x45, + 0x53, 0x59, 0x4b, 0x59, + 0x5f, 0x57, 0x53, 0x61, 0x61, 0x5d, 0x53, 0x5b, 0x61, 0x61, 0x5d, 0x49, + 0x43, 0x4f, 0x53, 0x59, + 0x4b, 0x59, 0x5f, 0x57, 0x53, 0x61, 0x61, 0x5d, 0x53, 0x5b, 0x61, 0x61, + 0x5d, 0x49, 0x43, 0x4f, + 0x0c, 0x4d, 0x4a, 0x40, 0x42, 0x40, 0x45, 0x07, 0x45, 0x43, 0x43, 0x5a, + 0x4b, 0x1d, 0x13, 0x4d, + 0x12, 0x07, 0x40, 0x1d, 0x13, 0x4d, 0x12, 0x07, 0x40, 0x1d, 0x13, 0x4d, + 0x12, 0x07, 0x40, 0x42, + 0x07, 0x02, 0x02, 0x04, 0x0c, 0x04, 0x0c, 0x15, 0x17, 0x13, 0x4d, 0x17, + 0x13, 0x4d, 0x40, 0x40, + 0x40, 0x29, 0x15, 0x15, 0x40, 0x0f, 0x15, 0x1b, 0x1b, 0x22, 0x27, 0x12, + 0x07, 0x0c, 0x12, 0x04, + 0x05, 0x3e, 0x1d, 0x15, 0x40, 0x0f, 0x15, 0x1b, 0x41, 0x15, 0x00, 0x41, + 0x41, 0x15, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x40, 0x45, 0x5b, 0x40, 0x20, 0x02, 0x00, 0x22, 0x40, 0x45, + 0x40, 0x40, 0x12, 0x0f, + 0x45, 0x5b, 0x40, 0x0a, 0x5e, 0x5b, 0x59, 0x54, 0x54, 0x07, 0x07, 0x0d, + 0x3e, 0x15, 0x04, 0x07, + 0x60, 0x27, 0x46, 0x15, 0x40, 0x05, 0x18, 0x40, 0x40, 0x40, 0x45, 0x45, + 0x53, 0x58, 0x4b, 0x58, + 0x5e, 0x56, 0x53, 0x60, 0x60, 0x5b, 0x53, 0x5b, 0x60, 0x60, 0x5b, 0x48, + 0x43, 0x4e, 0x53, 0x58, + 0x4b, 0x58, 0x5e, 0x56, 0x53, 0x60, 0x60, 0x5b, 0x53, 0x5b, 0x60, 0x60, + 0x5b, 0x48, 0x43, 0x4e, + 0x0c, 0x4d, 0x49, 0x40, 0x42, 0x40, 0x45, 0x07, 0x45, 0x43, 0x43, 0x59, + 0x4b, 0x1d, 0x12, 0x4d, + 0x12, 0x07, 0x40, 0x1d, 0x12, 0x4d, 0x12, 0x07, 0x40, 0x1d, 0x12, 0x4d, + 0x12, 0x07, 0x40, 0x42, + 0x07, 0x02, 0x02, 0x04, 0x0c, 0x04, 0x0c, 0x15, 0x17, 0x12, 0x4d, 0x17, + 0x12, 0x4d, 0x40, 0x40, + 0x40, 0x28, 0x15, 0x15, 0x40, 0x0f, 0x15, 0x1a, 0x1a, 0x22, 0x27, 0x12, + 0x07, 0x0c, 0x12, 0x04, + 0x05, 0x3e, 0x1d, 0x15, 0x40, 0x0f, 0x15, 0x1a, 0x40, 0x15, 0x01, 0x40, + 0x40, 0x15, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x00, 0x45, 0x5a, 0x40, 0x1f, 0x02, 0x40, 0x22, 0x40, 0x45, + 0x40, 0x40, 0x12, 0x0f, + 0x45, 0x59, 0x40, 0x0a, 0x5c, 0x59, 0x57, 0x51, 0x51, 0x07, 0x07, 0x0d, + 0x3e, 0x15, 0x05, 0x07, + 0x5f, 0x27, 0x44, 0x15, 0x40, 0x05, 0x17, 0x40, 0x40, 0x40, 0x45, 0x45, + 0x52, 0x57, 0x4a, 0x57, + 0x5c, 0x54, 0x52, 0x5f, 0x5f, 0x59, 0x52, 0x5a, 0x5f, 0x5f, 0x59, 0x47, + 0x42, 0x4c, 0x52, 0x57, + 0x4a, 0x57, 0x5c, 0x54, 0x52, 0x5f, 0x5f, 0x59, 0x52, 0x5a, 0x5f, 0x5f, + 0x59, 0x47, 0x42, 0x4c, + 0x0d, 0x4d, 0x47, 0x40, 0x42, 0x40, 0x45, 0x07, 0x45, 0x42, 0x42, 0x57, + 0x4a, 0x1d, 0x12, 0x4d, + 0x12, 0x07, 0x40, 0x1d, 0x12, 0x4d, 0x12, 0x07, 0x40, 0x1d, 0x12, 0x4d, + 0x12, 0x07, 0x40, 0x42, + 0x07, 0x02, 0x02, 0x05, 0x0d, 0x05, 0x0d, 0x15, 0x17, 0x12, 0x4d, 0x17, + 0x12, 0x4d, 0x40, 0x40, + 0x40, 0x27, 0x15, 0x15, 0x40, 0x0f, 0x15, 0x1a, 0x1a, 0x22, 0x27, 0x12, + 0x07, 0x0d, 0x12, 0x05, + 0x05, 0x3e, 0x1d, 0x15, 0x40, 0x0f, 0x15, 0x1a, 0x00, 0x15, 0x03, 0x00, + 0x00, 0x15, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x01, 0x44, 0x59, 0x40, 0x1e, 0x01, 0x41, 0x23, 0x40, 0x44, + 0x40, 0x40, 0x11, 0x0f, + 0x44, 0x58, 0x40, 0x0b, 0x5b, 0x58, 0x55, 0x4f, 0x4f, 0x07, 0x07, 0x0c, + 0x3e, 0x14, 0x06, 0x07, + 0x5e, 0x27, 0x43, 0x14, 0x40, 0x04, 0x16, 0x40, 0x40, 0x40, 0x44, 0x44, + 0x51, 0x56, 0x49, 0x56, + 0x5b, 0x53, 0x51, 0x5e, 0x5e, 0x58, 0x51, 0x59, 0x5e, 0x5e, 0x58, 0x46, + 0x41, 0x4b, 0x51, 0x56, + 0x49, 0x56, 0x5b, 0x53, 0x51, 0x5e, 0x5e, 0x58, 0x51, 0x59, 0x5e, 0x5e, + 0x58, 0x46, 0x41, 0x4b, + 0x0e, 0x4c, 0x45, 0x40, 0x43, 0x40, 0x44, 0x07, 0x44, 0x41, 0x41, 0x55, + 0x49, 0x1c, 0x11, 0x4c, + 0x13, 0x07, 0x40, 0x1c, 0x11, 0x4c, 0x13, 0x07, 0x40, 0x1c, 0x11, 0x4c, + 0x13, 0x07, 0x40, 0x43, + 0x07, 0x03, 0x03, 0x06, 0x0e, 0x06, 0x0e, 0x14, 0x17, 0x11, 0x4c, 0x17, + 0x11, 0x4c, 0x40, 0x40, + 0x40, 0x26, 0x14, 0x14, 0x40, 0x0f, 0x14, 0x19, 0x19, 0x23, 0x27, 0x13, + 0x07, 0x0e, 0x13, 0x06, + 0x04, 0x3e, 0x1c, 0x14, 0x40, 0x0f, 0x14, 0x19, 0x01, 0x14, 0x04, 0x01, + 0x01, 0x14, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x02, 0x44, 0x59, 0x40, 0x1d, 0x01, 0x42, 0x23, 0x40, 0x44, + 0x40, 0x40, 0x11, 0x0f, + 0x44, 0x56, 0x40, 0x0b, 0x5a, 0x56, 0x53, 0x4c, 0x4c, 0x07, 0x07, 0x0c, + 0x3e, 0x14, 0x06, 0x07, + 0x5d, 0x27, 0x42, 0x14, 0x40, 0x04, 0x15, 0x40, 0x40, 0x40, 0x44, 0x44, + 0x51, 0x55, 0x49, 0x55, + 0x5a, 0x52, 0x51, 0x5d, 0x5d, 0x56, 0x51, 0x59, 0x5d, 0x5d, 0x56, 0x45, + 0x41, 0x4a, 0x51, 0x55, + 0x49, 0x55, 0x5a, 0x52, 0x51, 0x5d, 0x5d, 0x56, 0x51, 0x59, 0x5d, 0x5d, + 0x56, 0x45, 0x41, 0x4a, + 0x0e, 0x4c, 0x43, 0x40, 0x43, 0x40, 0x44, 0x07, 0x44, 0x41, 0x41, 0x53, + 0x49, 0x1c, 0x11, 0x4c, + 0x13, 0x07, 0x40, 0x1c, 0x11, 0x4c, 0x13, 0x07, 0x40, 0x1c, 0x11, 0x4c, + 0x13, 0x07, 0x40, 0x43, + 0x07, 0x03, 0x03, 0x06, 0x0e, 0x06, 0x0e, 0x14, 0x17, 0x11, 0x4c, 0x17, + 0x11, 0x4c, 0x40, 0x40, + 0x40, 0x25, 0x14, 0x14, 0x40, 0x0f, 0x14, 0x19, 0x19, 0x23, 0x27, 0x13, + 0x07, 0x0e, 0x13, 0x06, + 0x04, 0x3e, 0x1c, 0x14, 0x40, 0x0f, 0x14, 0x19, 0x02, 0x14, 0x05, 0x02, + 0x02, 0x14, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x03, 0x44, 0x58, 0x40, 0x1c, 0x00, 0x43, 0x23, 0x40, 0x44, + 0x40, 0x40, 0x10, 0x0f, + 0x44, 0x55, 0x40, 0x0b, 0x59, 0x55, 0x51, 0x4a, 0x4a, 0x07, 0x07, 0x0c, + 0x3d, 0x14, 0x07, 0x07, + 0x5c, 0x27, 0x41, 0x14, 0x40, 0x04, 0x14, 0x40, 0x40, 0x40, 0x44, 0x44, + 0x50, 0x54, 0x48, 0x54, + 0x59, 0x51, 0x50, 0x5c, 0x5c, 0x55, 0x50, 0x58, 0x5c, 0x5c, 0x55, 0x44, + 0x40, 0x49, 0x50, 0x54, + 0x48, 0x54, 0x59, 0x51, 0x50, 0x5c, 0x5c, 0x55, 0x50, 0x58, 0x5c, 0x5c, + 0x55, 0x44, 0x40, 0x49, + 0x0f, 0x4c, 0x41, 0x40, 0x43, 0x40, 0x44, 0x07, 0x44, 0x40, 0x40, 0x51, + 0x48, 0x1c, 0x10, 0x4c, + 0x13, 0x07, 0x40, 0x1c, 0x10, 0x4c, 0x13, 0x07, 0x40, 0x1c, 0x10, 0x4c, + 0x13, 0x07, 0x40, 0x43, + 0x07, 0x03, 0x03, 0x07, 0x0f, 0x07, 0x0f, 0x14, 0x17, 0x10, 0x4c, 0x17, + 0x10, 0x4c, 0x40, 0x40, + 0x40, 0x24, 0x14, 0x14, 0x40, 0x0f, 0x14, 0x18, 0x18, 0x23, 0x27, 0x13, + 0x07, 0x0f, 0x13, 0x07, + 0x04, 0x3e, 0x1c, 0x14, 0x40, 0x0f, 0x14, 0x18, 0x03, 0x14, 0x06, 0x03, + 0x03, 0x14, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x04, 0x43, 0x57, 0x40, 0x1b, 0x40, 0x44, 0x24, 0x40, 0x43, + 0x40, 0x40, 0x0f, 0x0f, + 0x43, 0x53, 0x40, 0x0c, 0x57, 0x53, 0x4f, 0x47, 0x47, 0x07, 0x07, 0x0b, + 0x3b, 0x13, 0x08, 0x07, + 0x5b, 0x27, 0x00, 0x13, 0x40, 0x03, 0x13, 0x40, 0x40, 0x40, 0x43, 0x43, + 0x4f, 0x53, 0x47, 0x53, + 0x57, 0x4f, 0x4f, 0x5b, 0x5b, 0x53, 0x4f, 0x57, 0x5b, 0x5b, 0x53, 0x43, + 0x00, 0x47, 0x4f, 0x53, + 0x47, 0x53, 0x57, 0x4f, 0x4f, 0x5b, 0x5b, 0x53, 0x4f, 0x57, 0x5b, 0x5b, + 0x53, 0x43, 0x00, 0x47, + 0x10, 0x4b, 0x00, 0x40, 0x44, 0x40, 0x43, 0x07, 0x43, 0x00, 0x00, 0x4f, + 0x47, 0x1b, 0x0f, 0x4b, + 0x14, 0x07, 0x40, 0x1b, 0x0f, 0x4b, 0x14, 0x07, 0x40, 0x1b, 0x0f, 0x4b, + 0x14, 0x07, 0x40, 0x44, + 0x07, 0x04, 0x04, 0x08, 0x10, 0x08, 0x10, 0x13, 0x17, 0x0f, 0x4b, 0x17, + 0x0f, 0x4b, 0x40, 0x40, + 0x40, 0x23, 0x13, 0x13, 0x40, 0x0f, 0x13, 0x17, 0x17, 0x24, 0x27, 0x14, + 0x07, 0x10, 0x14, 0x08, + 0x03, 0x3e, 0x1b, 0x13, 0x40, 0x0f, 0x13, 0x17, 0x04, 0x13, 0x08, 0x04, + 0x04, 0x13, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x05, 0x43, 0x57, 0x40, 0x1a, 0x40, 0x45, 0x24, 0x40, 0x43, + 0x40, 0x40, 0x0f, 0x0f, + 0x43, 0x52, 0x40, 0x0c, 0x56, 0x52, 0x4d, 0x45, 0x45, 0x07, 0x07, 0x0b, + 0x3a, 0x13, 0x08, 0x07, + 0x5a, 0x27, 0x01, 0x13, 0x40, 0x03, 0x12, 0x40, 0x40, 0x40, 0x43, 0x43, + 0x4f, 0x52, 0x47, 0x52, + 0x56, 0x4e, 0x4f, 0x5a, 0x5a, 0x52, 0x4f, 0x57, 0x5a, 0x5a, 0x52, 0x42, + 0x00, 0x46, 0x4f, 0x52, + 0x47, 0x52, 0x56, 0x4e, 0x4f, 0x5a, 0x5a, 0x52, 0x4f, 0x57, 0x5a, 0x5a, + 0x52, 0x42, 0x00, 0x46, + 0x10, 0x4b, 0x02, 0x40, 0x44, 0x40, 0x43, 0x07, 0x43, 0x00, 0x00, 0x4d, + 0x47, 0x1b, 0x0f, 0x4b, + 0x14, 0x07, 0x40, 0x1b, 0x0f, 0x4b, 0x14, 0x07, 0x40, 0x1b, 0x0f, 0x4b, + 0x14, 0x07, 0x40, 0x44, + 0x07, 0x04, 0x04, 0x08, 0x10, 0x08, 0x10, 0x13, 0x17, 0x0f, 0x4b, 0x17, + 0x0f, 0x4b, 0x40, 0x40, + 0x40, 0x22, 0x13, 0x13, 0x40, 0x0f, 0x13, 0x17, 0x17, 0x24, 0x27, 0x14, + 0x07, 0x10, 0x14, 0x08, + 0x03, 0x3e, 0x1b, 0x13, 0x40, 0x0f, 0x13, 0x17, 0x05, 0x13, 0x09, 0x05, + 0x05, 0x13, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x06, 0x43, 0x56, 0x40, 0x19, 0x41, 0x46, 0x24, 0x40, 0x43, + 0x40, 0x40, 0x0e, 0x0f, + 0x43, 0x50, 0x40, 0x0c, 0x55, 0x50, 0x4b, 0x42, 0x42, 0x07, 0x07, 0x0b, + 0x38, 0x13, 0x09, 0x07, + 0x59, 0x27, 0x02, 0x13, 0x40, 0x03, 0x11, 0x40, 0x40, 0x40, 0x43, 0x43, + 0x4e, 0x51, 0x46, 0x51, + 0x55, 0x4d, 0x4e, 0x59, 0x59, 0x50, 0x4e, 0x56, 0x59, 0x59, 0x50, 0x41, + 0x01, 0x45, 0x4e, 0x51, + 0x46, 0x51, 0x55, 0x4d, 0x4e, 0x59, 0x59, 0x50, 0x4e, 0x56, 0x59, 0x59, + 0x50, 0x41, 0x01, 0x45, + 0x11, 0x4b, 0x04, 0x40, 0x44, 0x40, 0x43, 0x07, 0x43, 0x01, 0x01, 0x4b, + 0x46, 0x1b, 0x0e, 0x4b, + 0x14, 0x07, 0x40, 0x1b, 0x0e, 0x4b, 0x14, 0x07, 0x40, 0x1b, 0x0e, 0x4b, + 0x14, 0x07, 0x40, 0x44, + 0x07, 0x04, 0x04, 0x09, 0x11, 0x09, 0x11, 0x13, 0x17, 0x0e, 0x4b, 0x17, + 0x0e, 0x4b, 0x40, 0x40, + 0x40, 0x21, 0x13, 0x13, 0x40, 0x0f, 0x13, 0x16, 0x16, 0x24, 0x27, 0x14, + 0x07, 0x11, 0x14, 0x09, + 0x03, 0x3d, 0x1b, 0x13, 0x40, 0x0f, 0x13, 0x16, 0x06, 0x13, 0x0a, 0x06, + 0x06, 0x13, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x06, 0x43, 0x56, 0x40, 0x18, 0x42, 0x47, 0x24, 0x40, 0x43, + 0x40, 0x40, 0x0d, 0x0f, + 0x43, 0x4f, 0x40, 0x0c, 0x54, 0x4f, 0x4a, 0x40, 0x40, 0x07, 0x07, 0x0a, + 0x36, 0x12, 0x09, 0x07, + 0x59, 0x27, 0x03, 0x12, 0x40, 0x02, 0x10, 0x40, 0x40, 0x40, 0x43, 0x43, + 0x4e, 0x51, 0x46, 0x51, + 0x54, 0x4c, 0x4e, 0x59, 0x59, 0x4f, 0x4e, 0x56, 0x59, 0x59, 0x4f, 0x41, + 0x01, 0x44, 0x4e, 0x51, + 0x46, 0x51, 0x54, 0x4c, 0x4e, 0x59, 0x59, 0x4f, 0x4e, 0x56, 0x59, 0x59, + 0x4f, 0x41, 0x01, 0x44, + 0x11, 0x4b, 0x05, 0x40, 0x45, 0x40, 0x43, 0x07, 0x43, 0x01, 0x01, 0x4a, + 0x46, 0x1a, 0x0d, 0x4b, + 0x14, 0x07, 0x40, 0x1a, 0x0d, 0x4b, 0x14, 0x07, 0x40, 0x1a, 0x0d, 0x4b, + 0x14, 0x07, 0x40, 0x45, + 0x07, 0x04, 0x04, 0x09, 0x11, 0x09, 0x11, 0x12, 0x17, 0x0d, 0x4b, 0x17, + 0x0d, 0x4b, 0x40, 0x40, + 0x40, 0x20, 0x12, 0x12, 0x40, 0x0f, 0x12, 0x15, 0x15, 0x24, 0x27, 0x14, + 0x07, 0x11, 0x14, 0x09, + 0x02, 0x3b, 0x1a, 0x12, 0x40, 0x0f, 0x12, 0x15, 0x06, 0x12, 0x0b, 0x06, + 0x06, 0x12, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x07, 0x42, 0x55, 0x40, 0x18, 0x42, 0x47, 0x25, 0x40, 0x42, + 0x40, 0x40, 0x0d, 0x0f, + 0x42, 0x4d, 0x40, 0x0d, 0x52, 0x4d, 0x48, 0x02, 0x02, 0x07, 0x07, 0x0a, + 0x35, 0x12, 0x0a, 0x07, + 0x58, 0x27, 0x05, 0x12, 0x40, 0x02, 0x10, 0x40, 0x40, 0x40, 0x42, 0x42, + 0x4d, 0x50, 0x45, 0x50, + 0x52, 0x4a, 0x4d, 0x58, 0x58, 0x4d, 0x4d, 0x55, 0x58, 0x58, 0x4d, 0x40, + 0x02, 0x42, 0x4d, 0x50, + 0x45, 0x50, 0x52, 0x4a, 0x4d, 0x58, 0x58, 0x4d, 0x4d, 0x55, 0x58, 0x58, + 0x4d, 0x40, 0x02, 0x42, + 0x12, 0x4a, 0x07, 0x40, 0x45, 0x40, 0x42, 0x07, 0x42, 0x02, 0x02, 0x48, + 0x45, 0x1a, 0x0d, 0x4a, + 0x15, 0x07, 0x40, 0x1a, 0x0d, 0x4a, 0x15, 0x07, 0x40, 0x1a, 0x0d, 0x4a, + 0x15, 0x07, 0x40, 0x45, + 0x07, 0x05, 0x05, 0x0a, 0x12, 0x0a, 0x12, 0x12, 0x17, 0x0d, 0x4a, 0x17, + 0x0d, 0x4a, 0x40, 0x40, + 0x40, 0x20, 0x12, 0x12, 0x40, 0x0f, 0x12, 0x15, 0x15, 0x25, 0x27, 0x15, + 0x07, 0x12, 0x15, 0x0a, + 0x02, 0x3a, 0x1a, 0x12, 0x40, 0x0f, 0x12, 0x15, 0x07, 0x12, 0x0d, 0x07, + 0x07, 0x12, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x08, 0x42, 0x54, 0x40, 0x17, 0x43, 0x48, 0x25, 0x40, 0x42, + 0x40, 0x40, 0x0c, 0x0f, + 0x42, 0x4b, 0x40, 0x0d, 0x51, 0x4b, 0x46, 0x04, 0x04, 0x07, 0x07, 0x0a, + 0x33, 0x12, 0x0b, 0x07, + 0x57, 0x27, 0x06, 0x12, 0x40, 0x02, 0x0f, 0x40, 0x40, 0x40, 0x42, 0x42, + 0x4c, 0x4f, 0x44, 0x4f, + 0x51, 0x49, 0x4c, 0x57, 0x57, 0x4b, 0x4c, 0x54, 0x57, 0x57, 0x4b, 0x00, + 0x03, 0x41, 0x4c, 0x4f, + 0x44, 0x4f, 0x51, 0x49, 0x4c, 0x57, 0x57, 0x4b, 0x4c, 0x54, 0x57, 0x57, + 0x4b, 0x00, 0x03, 0x41, + 0x13, 0x4a, 0x09, 0x40, 0x45, 0x40, 0x42, 0x07, 0x42, 0x03, 0x03, 0x46, + 0x44, 0x1a, 0x0c, 0x4a, + 0x15, 0x07, 0x40, 0x1a, 0x0c, 0x4a, 0x15, 0x07, 0x40, 0x1a, 0x0c, 0x4a, + 0x15, 0x07, 0x40, 0x45, + 0x07, 0x05, 0x05, 0x0b, 0x13, 0x0b, 0x13, 0x12, 0x17, 0x0c, 0x4a, 0x17, + 0x0c, 0x4a, 0x40, 0x40, + 0x40, 0x1f, 0x12, 0x12, 0x40, 0x0f, 0x12, 0x14, 0x14, 0x25, 0x27, 0x15, + 0x07, 0x13, 0x15, 0x0b, + 0x02, 0x39, 0x1a, 0x12, 0x40, 0x0f, 0x12, 0x14, 0x08, 0x12, 0x0e, 0x08, + 0x08, 0x12, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x09, 0x42, 0x54, 0x40, 0x16, 0x43, 0x49, 0x25, 0x40, 0x42, + 0x40, 0x40, 0x0c, 0x0f, + 0x42, 0x4a, 0x40, 0x0d, 0x50, 0x4a, 0x44, 0x07, 0x07, 0x07, 0x07, 0x0a, + 0x32, 0x12, 0x0b, 0x07, + 0x56, 0x27, 0x07, 0x12, 0x40, 0x02, 0x0e, 0x40, 0x40, 0x40, 0x42, 0x42, + 0x4c, 0x4e, 0x44, 0x4e, + 0x50, 0x48, 0x4c, 0x56, 0x56, 0x4a, 0x4c, 0x54, 0x56, 0x56, 0x4a, 0x01, + 0x03, 0x40, 0x4c, 0x4e, + 0x44, 0x4e, 0x50, 0x48, 0x4c, 0x56, 0x56, 0x4a, 0x4c, 0x54, 0x56, 0x56, + 0x4a, 0x01, 0x03, 0x40, + 0x13, 0x4a, 0x0b, 0x40, 0x45, 0x40, 0x42, 0x07, 0x42, 0x03, 0x03, 0x44, + 0x44, 0x1a, 0x0c, 0x4a, + 0x15, 0x07, 0x40, 0x1a, 0x0c, 0x4a, 0x15, 0x07, 0x40, 0x1a, 0x0c, 0x4a, + 0x15, 0x07, 0x40, 0x45, + 0x07, 0x05, 0x05, 0x0b, 0x13, 0x0b, 0x13, 0x12, 0x17, 0x0c, 0x4a, 0x17, + 0x0c, 0x4a, 0x40, 0x40, + 0x40, 0x1e, 0x12, 0x12, 0x40, 0x0f, 0x12, 0x14, 0x14, 0x25, 0x27, 0x15, + 0x07, 0x13, 0x15, 0x0b, + 0x02, 0x38, 0x1a, 0x12, 0x40, 0x0f, 0x12, 0x14, 0x09, 0x12, 0x0f, 0x09, + 0x09, 0x12, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x0a, 0x41, 0x53, 0x40, 0x15, 0x44, 0x4a, 0x26, 0x40, 0x41, + 0x40, 0x40, 0x0b, 0x0f, + 0x41, 0x48, 0x40, 0x0e, 0x4f, 0x48, 0x42, 0x09, 0x09, 0x07, 0x07, 0x09, + 0x30, 0x11, 0x0c, 0x07, + 0x55, 0x27, 0x08, 0x11, 0x40, 0x01, 0x0d, 0x40, 0x40, 0x40, 0x41, 0x41, + 0x4b, 0x4d, 0x43, 0x4d, + 0x4f, 0x47, 0x4b, 0x55, 0x55, 0x48, 0x4b, 0x53, 0x55, 0x55, 0x48, 0x02, + 0x04, 0x00, 0x4b, 0x4d, + 0x43, 0x4d, 0x4f, 0x47, 0x4b, 0x55, 0x55, 0x48, 0x4b, 0x53, 0x55, 0x55, + 0x48, 0x02, 0x04, 0x00, + 0x14, 0x49, 0x0d, 0x40, 0x46, 0x40, 0x41, 0x07, 0x41, 0x04, 0x04, 0x42, + 0x43, 0x19, 0x0b, 0x49, + 0x16, 0x07, 0x40, 0x19, 0x0b, 0x49, 0x16, 0x07, 0x40, 0x19, 0x0b, 0x49, + 0x16, 0x07, 0x40, 0x46, + 0x07, 0x06, 0x06, 0x0c, 0x14, 0x0c, 0x14, 0x11, 0x17, 0x0b, 0x49, 0x17, + 0x0b, 0x49, 0x40, 0x40, + 0x40, 0x1d, 0x11, 0x11, 0x40, 0x0f, 0x11, 0x13, 0x13, 0x26, 0x27, 0x16, + 0x07, 0x14, 0x16, 0x0c, + 0x01, 0x36, 0x19, 0x11, 0x40, 0x0f, 0x11, 0x13, 0x0a, 0x11, 0x10, 0x0a, + 0x0a, 0x11, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x0b, 0x41, 0x52, 0x40, 0x14, 0x45, 0x4b, 0x26, 0x40, 0x41, + 0x40, 0x40, 0x0a, 0x0f, + 0x41, 0x47, 0x40, 0x0e, 0x4d, 0x47, 0x40, 0x0c, 0x0c, 0x07, 0x07, 0x09, + 0x2f, 0x11, 0x0d, 0x07, + 0x54, 0x27, 0x0a, 0x11, 0x40, 0x01, 0x0c, 0x40, 0x40, 0x40, 0x41, 0x41, + 0x4a, 0x4c, 0x42, 0x4c, + 0x4d, 0x45, 0x4a, 0x54, 0x54, 0x47, 0x4a, 0x52, 0x54, 0x54, 0x47, 0x03, + 0x05, 0x02, 0x4a, 0x4c, + 0x42, 0x4c, 0x4d, 0x45, 0x4a, 0x54, 0x54, 0x47, 0x4a, 0x52, 0x54, 0x54, + 0x47, 0x03, 0x05, 0x02, + 0x15, 0x49, 0x0f, 0x40, 0x46, 0x40, 0x41, 0x07, 0x41, 0x05, 0x05, 0x40, + 0x42, 0x19, 0x0a, 0x49, + 0x16, 0x07, 0x40, 0x19, 0x0a, 0x49, 0x16, 0x07, 0x40, 0x19, 0x0a, 0x49, + 0x16, 0x07, 0x40, 0x46, + 0x07, 0x06, 0x06, 0x0d, 0x15, 0x0d, 0x15, 0x11, 0x17, 0x0a, 0x49, 0x17, + 0x0a, 0x49, 0x40, 0x40, + 0x40, 0x1c, 0x11, 0x11, 0x40, 0x0f, 0x11, 0x12, 0x12, 0x26, 0x27, 0x16, + 0x07, 0x15, 0x16, 0x0d, + 0x01, 0x35, 0x19, 0x11, 0x40, 0x0f, 0x11, 0x12, 0x0b, 0x11, 0x12, 0x0b, + 0x0b, 0x11, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x0c, 0x41, 0x52, 0x40, 0x13, 0x45, 0x4c, 0x26, 0x40, 0x41, + 0x40, 0x40, 0x0a, 0x0f, + 0x41, 0x45, 0x40, 0x0e, 0x4c, 0x45, 0x01, 0x0e, 0x0e, 0x07, 0x07, 0x09, + 0x2d, 0x11, 0x0d, 0x07, + 0x53, 0x27, 0x0b, 0x11, 0x40, 0x01, 0x0b, 0x40, 0x40, 0x40, 0x41, 0x41, + 0x4a, 0x4b, 0x42, 0x4b, + 0x4c, 0x44, 0x4a, 0x53, 0x53, 0x45, 0x4a, 0x52, 0x53, 0x53, 0x45, 0x04, + 0x05, 0x03, 0x4a, 0x4b, + 0x42, 0x4b, 0x4c, 0x44, 0x4a, 0x53, 0x53, 0x45, 0x4a, 0x52, 0x53, 0x53, + 0x45, 0x04, 0x05, 0x03, + 0x15, 0x49, 0x11, 0x40, 0x46, 0x40, 0x41, 0x07, 0x41, 0x05, 0x05, 0x01, + 0x42, 0x19, 0x0a, 0x49, + 0x16, 0x07, 0x40, 0x19, 0x0a, 0x49, 0x16, 0x07, 0x40, 0x19, 0x0a, 0x49, + 0x16, 0x07, 0x40, 0x46, + 0x07, 0x06, 0x06, 0x0d, 0x15, 0x0d, 0x15, 0x11, 0x17, 0x0a, 0x49, 0x17, + 0x0a, 0x49, 0x40, 0x40, + 0x40, 0x1b, 0x11, 0x11, 0x40, 0x0f, 0x11, 0x12, 0x12, 0x26, 0x27, 0x16, + 0x07, 0x15, 0x16, 0x0d, + 0x01, 0x34, 0x19, 0x11, 0x40, 0x0f, 0x11, 0x12, 0x0c, 0x11, 0x13, 0x0c, + 0x0c, 0x11, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x0d, 0x40, 0x51, 0x40, 0x12, 0x46, 0x4d, 0x27, 0x40, 0x40, + 0x40, 0x40, 0x09, 0x0f, + 0x40, 0x44, 0x40, 0x0f, 0x4b, 0x44, 0x03, 0x11, 0x11, 0x07, 0x07, 0x08, + 0x2c, 0x10, 0x0e, 0x07, + 0x52, 0x27, 0x0c, 0x10, 0x40, 0x00, 0x0a, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x49, 0x4a, 0x41, 0x4a, + 0x4b, 0x43, 0x49, 0x52, 0x52, 0x44, 0x49, 0x51, 0x52, 0x52, 0x44, 0x05, + 0x06, 0x04, 0x49, 0x4a, + 0x41, 0x4a, 0x4b, 0x43, 0x49, 0x52, 0x52, 0x44, 0x49, 0x51, 0x52, 0x52, + 0x44, 0x05, 0x06, 0x04, + 0x16, 0x48, 0x13, 0x40, 0x47, 0x40, 0x40, 0x07, 0x40, 0x06, 0x06, 0x03, + 0x41, 0x18, 0x09, 0x48, + 0x17, 0x07, 0x40, 0x18, 0x09, 0x48, 0x17, 0x07, 0x40, 0x18, 0x09, 0x48, + 0x17, 0x07, 0x40, 0x47, + 0x07, 0x07, 0x07, 0x0e, 0x16, 0x0e, 0x16, 0x10, 0x17, 0x09, 0x48, 0x17, + 0x09, 0x48, 0x40, 0x40, + 0x40, 0x1a, 0x10, 0x10, 0x40, 0x0f, 0x10, 0x11, 0x11, 0x27, 0x27, 0x17, + 0x07, 0x16, 0x17, 0x0e, + 0x00, 0x33, 0x18, 0x10, 0x40, 0x0f, 0x10, 0x11, 0x0d, 0x10, 0x14, 0x0d, + 0x0d, 0x10, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x0e, 0x40, 0x51, 0x40, 0x11, 0x47, 0x4e, 0x27, 0x40, 0x40, + 0x40, 0x40, 0x08, 0x0f, + 0x40, 0x42, 0x40, 0x0f, 0x4a, 0x42, 0x04, 0x13, 0x13, 0x07, 0x07, 0x08, + 0x2a, 0x10, 0x0e, 0x07, + 0x51, 0x27, 0x0d, 0x10, 0x40, 0x00, 0x09, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x49, 0x49, 0x41, 0x49, + 0x4a, 0x42, 0x49, 0x51, 0x51, 0x42, 0x49, 0x51, 0x51, 0x51, 0x42, 0x06, + 0x06, 0x05, 0x49, 0x49, + 0x41, 0x49, 0x4a, 0x42, 0x49, 0x51, 0x51, 0x42, 0x49, 0x51, 0x51, 0x51, + 0x42, 0x06, 0x06, 0x05, + 0x16, 0x48, 0x14, 0x40, 0x47, 0x40, 0x40, 0x07, 0x40, 0x06, 0x06, 0x04, + 0x41, 0x18, 0x08, 0x48, + 0x17, 0x07, 0x40, 0x18, 0x08, 0x48, 0x17, 0x07, 0x40, 0x18, 0x08, 0x48, + 0x17, 0x07, 0x40, 0x47, + 0x07, 0x07, 0x07, 0x0e, 0x16, 0x0e, 0x16, 0x10, 0x17, 0x08, 0x48, 0x17, + 0x08, 0x48, 0x40, 0x40, + 0x40, 0x19, 0x10, 0x10, 0x40, 0x0f, 0x10, 0x10, 0x10, 0x27, 0x27, 0x17, + 0x07, 0x16, 0x17, 0x0e, + 0x00, 0x31, 0x18, 0x10, 0x40, 0x0f, 0x10, 0x10, 0x0e, 0x10, 0x15, 0x0e, + 0x0e, 0x10, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x0f, 0x40, 0x50, 0x40, 0x10, 0x47, 0x4f, 0x27, 0x40, 0x40, + 0x40, 0x40, 0x08, 0x0f, + 0x40, 0x40, 0x40, 0x0f, 0x48, 0x40, 0x06, 0x16, 0x16, 0x07, 0x07, 0x08, + 0x28, 0x10, 0x0f, 0x07, + 0x50, 0x27, 0x0f, 0x10, 0x40, 0x00, 0x08, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x48, 0x48, 0x40, 0x48, + 0x48, 0x40, 0x48, 0x50, 0x50, 0x40, 0x48, 0x50, 0x50, 0x50, 0x40, 0x07, + 0x07, 0x07, 0x48, 0x48, + 0x40, 0x48, 0x48, 0x40, 0x48, 0x50, 0x50, 0x40, 0x48, 0x50, 0x50, 0x50, + 0x40, 0x07, 0x07, 0x07, + 0x17, 0x48, 0x16, 0x40, 0x47, 0x40, 0x40, 0x07, 0x40, 0x07, 0x07, 0x06, + 0x40, 0x18, 0x08, 0x48, + 0x17, 0x07, 0x40, 0x18, 0x08, 0x48, 0x17, 0x07, 0x40, 0x18, 0x08, 0x48, + 0x17, 0x07, 0x40, 0x47, + 0x07, 0x07, 0x07, 0x0f, 0x17, 0x0f, 0x17, 0x10, 0x17, 0x08, 0x48, 0x17, + 0x08, 0x48, 0x40, 0x40, + 0x40, 0x18, 0x10, 0x10, 0x40, 0x0f, 0x10, 0x10, 0x10, 0x27, 0x27, 0x17, + 0x07, 0x17, 0x17, 0x0f, + 0x00, 0x30, 0x18, 0x10, 0x40, 0x0f, 0x10, 0x10, 0x0f, 0x10, 0x17, 0x0f, + 0x0f, 0x10, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x10, 0x00, 0x4f, 0x40, 0x0f, 0x48, 0x50, 0x28, 0x40, 0x00, + 0x40, 0x40, 0x07, 0x0f, + 0x00, 0x00, 0x40, 0x10, 0x47, 0x00, 0x08, 0x18, 0x18, 0x07, 0x07, 0x07, + 0x27, 0x0f, 0x10, 0x07, + 0x4f, 0x27, 0x10, 0x0f, 0x40, 0x40, 0x07, 0x40, 0x40, 0x40, 0x00, 0x00, + 0x47, 0x47, 0x00, 0x47, + 0x47, 0x00, 0x47, 0x4f, 0x4f, 0x00, 0x47, 0x4f, 0x4f, 0x4f, 0x00, 0x08, + 0x08, 0x08, 0x47, 0x47, + 0x00, 0x47, 0x47, 0x00, 0x47, 0x4f, 0x4f, 0x00, 0x47, 0x4f, 0x4f, 0x4f, + 0x00, 0x08, 0x08, 0x08, + 0x18, 0x47, 0x18, 0x40, 0x48, 0x40, 0x00, 0x07, 0x00, 0x08, 0x08, 0x08, + 0x00, 0x17, 0x07, 0x47, + 0x18, 0x07, 0x40, 0x17, 0x07, 0x47, 0x18, 0x07, 0x40, 0x17, 0x07, 0x47, + 0x18, 0x07, 0x40, 0x48, + 0x07, 0x08, 0x08, 0x10, 0x18, 0x10, 0x18, 0x0f, 0x17, 0x07, 0x47, 0x17, + 0x07, 0x47, 0x40, 0x40, + 0x40, 0x17, 0x0f, 0x0f, 0x40, 0x0f, 0x0f, 0x0f, 0x0f, 0x28, 0x27, 0x18, + 0x07, 0x18, 0x18, 0x10, + 0x40, 0x2f, 0x17, 0x0f, 0x40, 0x0f, 0x0f, 0x0f, 0x10, 0x0f, 0x18, 0x10, + 0x10, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x11, 0x00, 0x4f, 0x40, 0x0e, 0x48, 0x51, 0x28, 0x40, 0x00, + 0x40, 0x40, 0x07, 0x0f, + 0x00, 0x02, 0x40, 0x10, 0x46, 0x02, 0x0a, 0x1b, 0x1b, 0x07, 0x07, 0x07, + 0x25, 0x0f, 0x10, 0x07, + 0x4e, 0x27, 0x11, 0x0f, 0x40, 0x40, 0x06, 0x40, 0x40, 0x40, 0x00, 0x00, + 0x47, 0x46, 0x00, 0x46, + 0x46, 0x01, 0x47, 0x4e, 0x4e, 0x02, 0x47, 0x4f, 0x4e, 0x4e, 0x02, 0x09, + 0x08, 0x09, 0x47, 0x46, + 0x00, 0x46, 0x46, 0x01, 0x47, 0x4e, 0x4e, 0x02, 0x47, 0x4f, 0x4e, 0x4e, + 0x02, 0x09, 0x08, 0x09, + 0x18, 0x47, 0x1a, 0x40, 0x48, 0x40, 0x00, 0x07, 0x00, 0x08, 0x08, 0x0a, + 0x00, 0x17, 0x07, 0x47, + 0x18, 0x07, 0x40, 0x17, 0x07, 0x47, 0x18, 0x07, 0x40, 0x17, 0x07, 0x47, + 0x18, 0x07, 0x40, 0x48, + 0x07, 0x08, 0x08, 0x10, 0x18, 0x10, 0x18, 0x0f, 0x17, 0x07, 0x47, 0x17, + 0x07, 0x47, 0x40, 0x40, + 0x40, 0x16, 0x0f, 0x0f, 0x40, 0x0f, 0x0f, 0x0f, 0x0f, 0x28, 0x27, 0x18, + 0x07, 0x18, 0x18, 0x10, + 0x40, 0x2e, 0x17, 0x0f, 0x40, 0x0f, 0x0f, 0x0f, 0x11, 0x0f, 0x19, 0x11, + 0x11, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x12, 0x00, 0x4e, 0x40, 0x0d, 0x49, 0x52, 0x28, 0x40, 0x00, + 0x40, 0x40, 0x06, 0x0f, + 0x00, 0x03, 0x40, 0x10, 0x45, 0x03, 0x0c, 0x1d, 0x1d, 0x07, 0x07, 0x07, + 0x24, 0x0f, 0x11, 0x07, + 0x4d, 0x27, 0x12, 0x0f, 0x40, 0x40, 0x05, 0x40, 0x40, 0x40, 0x00, 0x00, + 0x46, 0x45, 0x01, 0x45, + 0x45, 0x02, 0x46, 0x4d, 0x4d, 0x03, 0x46, 0x4e, 0x4d, 0x4d, 0x03, 0x0a, + 0x09, 0x0a, 0x46, 0x45, + 0x01, 0x45, 0x45, 0x02, 0x46, 0x4d, 0x4d, 0x03, 0x46, 0x4e, 0x4d, 0x4d, + 0x03, 0x0a, 0x09, 0x0a, + 0x19, 0x47, 0x1c, 0x40, 0x48, 0x40, 0x00, 0x07, 0x00, 0x09, 0x09, 0x0c, + 0x01, 0x17, 0x06, 0x47, + 0x18, 0x07, 0x40, 0x17, 0x06, 0x47, 0x18, 0x07, 0x40, 0x17, 0x06, 0x47, + 0x18, 0x07, 0x40, 0x48, + 0x07, 0x08, 0x08, 0x11, 0x19, 0x11, 0x19, 0x0f, 0x17, 0x06, 0x47, 0x17, + 0x06, 0x47, 0x40, 0x40, + 0x40, 0x15, 0x0f, 0x0f, 0x40, 0x0f, 0x0f, 0x0e, 0x0e, 0x28, 0x27, 0x18, + 0x07, 0x19, 0x18, 0x11, + 0x40, 0x2c, 0x17, 0x0f, 0x40, 0x0f, 0x0f, 0x0e, 0x12, 0x0f, 0x1a, 0x12, + 0x12, 0x0f, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x13, 0x01, 0x4d, 0x40, 0x0c, 0x4a, 0x53, 0x29, 0x40, 0x01, + 0x40, 0x40, 0x05, 0x0f, + 0x01, 0x05, 0x40, 0x11, 0x43, 0x05, 0x0e, 0x20, 0x20, 0x07, 0x07, 0x06, + 0x22, 0x0e, 0x12, 0x07, + 0x4c, 0x27, 0x14, 0x0e, 0x40, 0x41, 0x04, 0x40, 0x40, 0x40, 0x01, 0x01, + 0x45, 0x44, 0x02, 0x44, + 0x43, 0x04, 0x45, 0x4c, 0x4c, 0x05, 0x45, 0x4d, 0x4c, 0x4c, 0x05, 0x0b, + 0x0a, 0x0c, 0x45, 0x44, + 0x02, 0x44, 0x43, 0x04, 0x45, 0x4c, 0x4c, 0x05, 0x45, 0x4d, 0x4c, 0x4c, + 0x05, 0x0b, 0x0a, 0x0c, + 0x1a, 0x46, 0x1e, 0x40, 0x49, 0x40, 0x01, 0x07, 0x01, 0x0a, 0x0a, 0x0e, + 0x02, 0x16, 0x05, 0x46, + 0x19, 0x07, 0x40, 0x16, 0x05, 0x46, 0x19, 0x07, 0x40, 0x16, 0x05, 0x46, + 0x19, 0x07, 0x40, 0x49, + 0x07, 0x09, 0x09, 0x12, 0x1a, 0x12, 0x1a, 0x0e, 0x17, 0x05, 0x46, 0x17, + 0x05, 0x46, 0x40, 0x40, + 0x40, 0x14, 0x0e, 0x0e, 0x40, 0x0f, 0x0e, 0x0d, 0x0d, 0x29, 0x27, 0x19, + 0x07, 0x1a, 0x19, 0x12, + 0x41, 0x2b, 0x16, 0x0e, 0x40, 0x0f, 0x0e, 0x0d, 0x13, 0x0e, 0x1c, 0x13, + 0x13, 0x0e, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x14, 0x01, 0x4d, 0x40, 0x0b, 0x4a, 0x54, 0x29, 0x40, 0x01, + 0x40, 0x40, 0x05, 0x0f, + 0x01, 0x06, 0x40, 0x11, 0x42, 0x06, 0x10, 0x22, 0x22, 0x07, 0x07, 0x06, + 0x21, 0x0e, 0x12, 0x07, + 0x4b, 0x27, 0x15, 0x0e, 0x40, 0x41, 0x03, 0x40, 0x40, 0x40, 0x01, 0x01, + 0x45, 0x43, 0x02, 0x43, + 0x42, 0x05, 0x45, 0x4b, 0x4b, 0x06, 0x45, 0x4d, 0x4b, 0x4b, 0x06, 0x0c, + 0x0a, 0x0d, 0x45, 0x43, + 0x02, 0x43, 0x42, 0x05, 0x45, 0x4b, 0x4b, 0x06, 0x45, 0x4d, 0x4b, 0x4b, + 0x06, 0x0c, 0x0a, 0x0d, + 0x1a, 0x46, 0x20, 0x40, 0x49, 0x40, 0x01, 0x07, 0x01, 0x0a, 0x0a, 0x10, + 0x02, 0x16, 0x05, 0x46, + 0x19, 0x07, 0x40, 0x16, 0x05, 0x46, 0x19, 0x07, 0x40, 0x16, 0x05, 0x46, + 0x19, 0x07, 0x40, 0x49, + 0x07, 0x09, 0x09, 0x12, 0x1a, 0x12, 0x1a, 0x0e, 0x17, 0x05, 0x46, 0x17, + 0x05, 0x46, 0x40, 0x40, + 0x40, 0x13, 0x0e, 0x0e, 0x40, 0x0f, 0x0e, 0x0d, 0x0d, 0x29, 0x27, 0x19, + 0x07, 0x1a, 0x19, 0x12, + 0x41, 0x2a, 0x16, 0x0e, 0x40, 0x0f, 0x0e, 0x0d, 0x14, 0x0e, 0x1d, 0x14, + 0x14, 0x0e, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x15, 0x01, 0x4c, 0x40, 0x0a, 0x4b, 0x55, 0x29, 0x40, 0x01, + 0x40, 0x40, 0x04, 0x0f, + 0x01, 0x08, 0x40, 0x11, 0x41, 0x08, 0x12, 0x25, 0x25, 0x07, 0x07, 0x06, + 0x1f, 0x0e, 0x13, 0x07, + 0x4a, 0x27, 0x16, 0x0e, 0x40, 0x41, 0x02, 0x40, 0x40, 0x40, 0x01, 0x01, + 0x44, 0x42, 0x03, 0x42, + 0x41, 0x06, 0x44, 0x4a, 0x4a, 0x08, 0x44, 0x4c, 0x4a, 0x4a, 0x08, 0x0d, + 0x0b, 0x0e, 0x44, 0x42, + 0x03, 0x42, 0x41, 0x06, 0x44, 0x4a, 0x4a, 0x08, 0x44, 0x4c, 0x4a, 0x4a, + 0x08, 0x0d, 0x0b, 0x0e, + 0x1b, 0x46, 0x22, 0x40, 0x49, 0x40, 0x01, 0x07, 0x01, 0x0b, 0x0b, 0x12, + 0x03, 0x16, 0x04, 0x46, + 0x19, 0x07, 0x40, 0x16, 0x04, 0x46, 0x19, 0x07, 0x40, 0x16, 0x04, 0x46, + 0x19, 0x07, 0x40, 0x49, + 0x07, 0x09, 0x09, 0x13, 0x1b, 0x13, 0x1b, 0x0e, 0x17, 0x04, 0x46, 0x17, + 0x04, 0x46, 0x40, 0x40, + 0x40, 0x12, 0x0e, 0x0e, 0x40, 0x0f, 0x0e, 0x0c, 0x0c, 0x29, 0x27, 0x19, + 0x07, 0x1b, 0x19, 0x13, + 0x41, 0x29, 0x16, 0x0e, 0x40, 0x0f, 0x0e, 0x0c, 0x15, 0x0e, 0x1e, 0x15, + 0x15, 0x0e, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x15, 0x01, 0x4c, 0x40, 0x09, 0x4c, 0x56, 0x29, 0x40, 0x01, + 0x40, 0x40, 0x03, 0x0f, + 0x01, 0x09, 0x40, 0x11, 0x40, 0x09, 0x13, 0x27, 0x27, 0x07, 0x07, 0x05, + 0x1d, 0x0d, 0x13, 0x07, + 0x4a, 0x27, 0x17, 0x0d, 0x40, 0x42, 0x01, 0x40, 0x40, 0x40, 0x01, 0x01, + 0x44, 0x42, 0x03, 0x42, + 0x40, 0x07, 0x44, 0x4a, 0x4a, 0x09, 0x44, 0x4c, 0x4a, 0x4a, 0x09, 0x0d, + 0x0b, 0x0f, 0x44, 0x42, + 0x03, 0x42, 0x40, 0x07, 0x44, 0x4a, 0x4a, 0x09, 0x44, 0x4c, 0x4a, 0x4a, + 0x09, 0x0d, 0x0b, 0x0f, + 0x1b, 0x46, 0x23, 0x40, 0x4a, 0x40, 0x01, 0x07, 0x01, 0x0b, 0x0b, 0x13, + 0x03, 0x15, 0x03, 0x46, + 0x19, 0x07, 0x40, 0x15, 0x03, 0x46, 0x19, 0x07, 0x40, 0x15, 0x03, 0x46, + 0x19, 0x07, 0x40, 0x4a, + 0x07, 0x09, 0x09, 0x13, 0x1b, 0x13, 0x1b, 0x0d, 0x17, 0x03, 0x46, 0x17, + 0x03, 0x46, 0x40, 0x40, + 0x40, 0x11, 0x0d, 0x0d, 0x40, 0x0f, 0x0d, 0x0b, 0x0b, 0x29, 0x27, 0x19, + 0x07, 0x1b, 0x19, 0x13, + 0x42, 0x27, 0x15, 0x0d, 0x40, 0x0f, 0x0d, 0x0b, 0x15, 0x0d, 0x1f, 0x15, + 0x15, 0x0d, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x16, 0x02, 0x4b, 0x40, 0x09, 0x4c, 0x56, 0x2a, 0x40, 0x02, + 0x40, 0x40, 0x03, 0x0f, + 0x02, 0x0b, 0x40, 0x12, 0x01, 0x0b, 0x15, 0x2a, 0x2a, 0x07, 0x07, 0x05, + 0x1c, 0x0d, 0x14, 0x07, + 0x49, 0x27, 0x19, 0x0d, 0x40, 0x42, 0x01, 0x40, 0x40, 0x40, 0x02, 0x02, + 0x43, 0x41, 0x04, 0x41, + 0x01, 0x09, 0x43, 0x49, 0x49, 0x0b, 0x43, 0x4b, 0x49, 0x49, 0x0b, 0x0e, + 0x0c, 0x11, 0x43, 0x41, + 0x04, 0x41, 0x01, 0x09, 0x43, 0x49, 0x49, 0x0b, 0x43, 0x4b, 0x49, 0x49, + 0x0b, 0x0e, 0x0c, 0x11, + 0x1c, 0x45, 0x25, 0x40, 0x4a, 0x40, 0x02, 0x07, 0x02, 0x0c, 0x0c, 0x15, + 0x04, 0x15, 0x03, 0x45, + 0x1a, 0x07, 0x40, 0x15, 0x03, 0x45, 0x1a, 0x07, 0x40, 0x15, 0x03, 0x45, + 0x1a, 0x07, 0x40, 0x4a, + 0x07, 0x0a, 0x0a, 0x14, 0x1c, 0x14, 0x1c, 0x0d, 0x17, 0x03, 0x45, 0x17, + 0x03, 0x45, 0x40, 0x40, + 0x40, 0x11, 0x0d, 0x0d, 0x40, 0x0f, 0x0d, 0x0b, 0x0b, 0x2a, 0x27, 0x1a, + 0x07, 0x1c, 0x1a, 0x14, + 0x42, 0x26, 0x15, 0x0d, 0x40, 0x0f, 0x0d, 0x0b, 0x16, 0x0d, 0x21, 0x16, + 0x16, 0x0d, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x17, 0x02, 0x4a, 0x40, 0x08, 0x4d, 0x57, 0x2a, 0x40, 0x02, + 0x40, 0x40, 0x02, 0x0f, + 0x02, 0x0d, 0x40, 0x12, 0x02, 0x0d, 0x17, 0x2c, 0x2c, 0x07, 0x07, 0x05, + 0x1a, 0x0d, 0x15, 0x07, + 0x48, 0x27, 0x1a, 0x0d, 0x40, 0x42, 0x00, 0x40, 0x40, 0x40, 0x02, 0x02, + 0x42, 0x40, 0x05, 0x40, + 0x02, 0x0a, 0x42, 0x48, 0x48, 0x0d, 0x42, 0x4a, 0x48, 0x48, 0x0d, 0x0f, + 0x0d, 0x12, 0x42, 0x40, + 0x05, 0x40, 0x02, 0x0a, 0x42, 0x48, 0x48, 0x0d, 0x42, 0x4a, 0x48, 0x48, + 0x0d, 0x0f, 0x0d, 0x12, + 0x1d, 0x45, 0x27, 0x40, 0x4a, 0x40, 0x02, 0x07, 0x02, 0x0d, 0x0d, 0x17, + 0x05, 0x15, 0x02, 0x45, + 0x1a, 0x07, 0x40, 0x15, 0x02, 0x45, 0x1a, 0x07, 0x40, 0x15, 0x02, 0x45, + 0x1a, 0x07, 0x40, 0x4a, + 0x07, 0x0a, 0x0a, 0x15, 0x1d, 0x15, 0x1d, 0x0d, 0x17, 0x02, 0x45, 0x17, + 0x02, 0x45, 0x40, 0x40, + 0x40, 0x10, 0x0d, 0x0d, 0x40, 0x0f, 0x0d, 0x0a, 0x0a, 0x2a, 0x27, 0x1a, + 0x07, 0x1d, 0x1a, 0x15, + 0x42, 0x25, 0x15, 0x0d, 0x40, 0x0f, 0x0d, 0x0a, 0x17, 0x0d, 0x22, 0x17, + 0x17, 0x0d, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x18, 0x02, 0x4a, 0x40, 0x07, 0x4d, 0x58, 0x2a, 0x40, 0x02, + 0x40, 0x40, 0x02, 0x0f, + 0x02, 0x0e, 0x40, 0x12, 0x03, 0x0e, 0x19, 0x2f, 0x2f, 0x07, 0x07, 0x05, + 0x19, 0x0d, 0x15, 0x07, + 0x47, 0x27, 0x1b, 0x0d, 0x40, 0x42, 0x40, 0x40, 0x40, 0x40, 0x02, 0x02, + 0x42, 0x00, 0x05, 0x00, + 0x03, 0x0b, 0x42, 0x47, 0x47, 0x0e, 0x42, 0x4a, 0x47, 0x47, 0x0e, 0x10, + 0x0d, 0x13, 0x42, 0x00, + 0x05, 0x00, 0x03, 0x0b, 0x42, 0x47, 0x47, 0x0e, 0x42, 0x4a, 0x47, 0x47, + 0x0e, 0x10, 0x0d, 0x13, + 0x1d, 0x45, 0x29, 0x40, 0x4a, 0x40, 0x02, 0x07, 0x02, 0x0d, 0x0d, 0x19, + 0x05, 0x15, 0x02, 0x45, + 0x1a, 0x07, 0x40, 0x15, 0x02, 0x45, 0x1a, 0x07, 0x40, 0x15, 0x02, 0x45, + 0x1a, 0x07, 0x40, 0x4a, + 0x07, 0x0a, 0x0a, 0x15, 0x1d, 0x15, 0x1d, 0x0d, 0x17, 0x02, 0x45, 0x17, + 0x02, 0x45, 0x40, 0x40, + 0x40, 0x0f, 0x0d, 0x0d, 0x40, 0x0f, 0x0d, 0x0a, 0x0a, 0x2a, 0x27, 0x1a, + 0x07, 0x1d, 0x1a, 0x15, + 0x42, 0x24, 0x15, 0x0d, 0x40, 0x0f, 0x0d, 0x0a, 0x18, 0x0d, 0x23, 0x18, + 0x18, 0x0d, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x19, 0x03, 0x49, 0x40, 0x06, 0x4e, 0x59, 0x2b, 0x40, 0x03, + 0x40, 0x40, 0x01, 0x0f, + 0x03, 0x10, 0x40, 0x13, 0x04, 0x10, 0x1b, 0x31, 0x31, 0x07, 0x07, 0x04, + 0x17, 0x0c, 0x16, 0x07, + 0x46, 0x27, 0x1c, 0x0c, 0x40, 0x43, 0x41, 0x40, 0x40, 0x40, 0x03, 0x03, + 0x41, 0x01, 0x06, 0x01, + 0x04, 0x0c, 0x41, 0x46, 0x46, 0x10, 0x41, 0x49, 0x46, 0x46, 0x10, 0x11, + 0x0e, 0x14, 0x41, 0x01, + 0x06, 0x01, 0x04, 0x0c, 0x41, 0x46, 0x46, 0x10, 0x41, 0x49, 0x46, 0x46, + 0x10, 0x11, 0x0e, 0x14, + 0x1e, 0x44, 0x2b, 0x40, 0x4b, 0x40, 0x03, 0x07, 0x03, 0x0e, 0x0e, 0x1b, + 0x06, 0x14, 0x01, 0x44, + 0x1b, 0x07, 0x40, 0x14, 0x01, 0x44, 0x1b, 0x07, 0x40, 0x14, 0x01, 0x44, + 0x1b, 0x07, 0x40, 0x4b, + 0x07, 0x0b, 0x0b, 0x16, 0x1e, 0x16, 0x1e, 0x0c, 0x17, 0x01, 0x44, 0x17, + 0x01, 0x44, 0x40, 0x40, + 0x40, 0x0e, 0x0c, 0x0c, 0x40, 0x0f, 0x0c, 0x09, 0x09, 0x2b, 0x27, 0x1b, + 0x07, 0x1e, 0x1b, 0x16, + 0x43, 0x22, 0x14, 0x0c, 0x40, 0x0f, 0x0c, 0x09, 0x19, 0x0c, 0x24, 0x19, + 0x19, 0x0c, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x1a, 0x03, 0x48, 0x40, 0x05, 0x4f, 0x5a, 0x2b, 0x40, 0x03, + 0x40, 0x40, 0x00, 0x0f, + 0x03, 0x11, 0x40, 0x13, 0x06, 0x11, 0x1d, 0x34, 0x34, 0x07, 0x07, 0x04, + 0x16, 0x0c, 0x17, 0x07, + 0x45, 0x27, 0x1e, 0x0c, 0x40, 0x43, 0x42, 0x40, 0x40, 0x40, 0x03, 0x03, + 0x40, 0x02, 0x07, 0x02, + 0x06, 0x0e, 0x40, 0x45, 0x45, 0x11, 0x40, 0x48, 0x45, 0x45, 0x11, 0x12, + 0x0f, 0x16, 0x40, 0x02, + 0x07, 0x02, 0x06, 0x0e, 0x40, 0x45, 0x45, 0x11, 0x40, 0x48, 0x45, 0x45, + 0x11, 0x12, 0x0f, 0x16, + 0x1f, 0x44, 0x2d, 0x40, 0x4b, 0x40, 0x03, 0x07, 0x03, 0x0f, 0x0f, 0x1d, + 0x07, 0x14, 0x00, 0x44, + 0x1b, 0x07, 0x40, 0x14, 0x00, 0x44, 0x1b, 0x07, 0x40, 0x14, 0x00, 0x44, + 0x1b, 0x07, 0x40, 0x4b, + 0x07, 0x0b, 0x0b, 0x17, 0x1f, 0x17, 0x1f, 0x0c, 0x17, 0x00, 0x44, 0x17, + 0x00, 0x44, 0x40, 0x40, + 0x40, 0x0d, 0x0c, 0x0c, 0x40, 0x0f, 0x0c, 0x08, 0x08, 0x2b, 0x27, 0x1b, + 0x07, 0x1f, 0x1b, 0x17, + 0x43, 0x21, 0x14, 0x0c, 0x40, 0x0f, 0x0c, 0x08, 0x1a, 0x0c, 0x26, 0x1a, + 0x1a, 0x0c, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x1b, 0x03, 0x48, 0x40, 0x04, 0x4f, 0x5b, 0x2b, 0x40, 0x03, + 0x40, 0x40, 0x00, 0x0f, + 0x03, 0x13, 0x40, 0x13, 0x07, 0x13, 0x1f, 0x36, 0x36, 0x07, 0x07, 0x04, + 0x14, 0x0c, 0x17, 0x07, + 0x44, 0x27, 0x1f, 0x0c, 0x40, 0x43, 0x43, 0x40, 0x40, 0x40, 0x03, 0x03, + 0x40, 0x03, 0x07, 0x03, + 0x07, 0x0f, 0x40, 0x44, 0x44, 0x13, 0x40, 0x48, 0x44, 0x44, 0x13, 0x13, + 0x0f, 0x17, 0x40, 0x03, + 0x07, 0x03, 0x07, 0x0f, 0x40, 0x44, 0x44, 0x13, 0x40, 0x48, 0x44, 0x44, + 0x13, 0x13, 0x0f, 0x17, + 0x1f, 0x44, 0x2f, 0x40, 0x4b, 0x40, 0x03, 0x07, 0x03, 0x0f, 0x0f, 0x1f, + 0x07, 0x14, 0x00, 0x44, + 0x1b, 0x07, 0x40, 0x14, 0x00, 0x44, 0x1b, 0x07, 0x40, 0x14, 0x00, 0x44, + 0x1b, 0x07, 0x40, 0x4b, + 0x07, 0x0b, 0x0b, 0x17, 0x1f, 0x17, 0x1f, 0x0c, 0x17, 0x00, 0x44, 0x17, + 0x00, 0x44, 0x40, 0x40, + 0x40, 0x0c, 0x0c, 0x0c, 0x40, 0x0f, 0x0c, 0x08, 0x08, 0x2b, 0x27, 0x1b, + 0x07, 0x1f, 0x1b, 0x17, + 0x43, 0x20, 0x14, 0x0c, 0x40, 0x0f, 0x0c, 0x08, 0x1b, 0x0c, 0x27, 0x1b, + 0x1b, 0x0c, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x1c, 0x04, 0x47, 0x40, 0x03, 0x50, 0x5c, 0x2c, 0x40, 0x04, + 0x40, 0x40, 0x40, 0x0f, + 0x04, 0x14, 0x40, 0x14, 0x08, 0x14, 0x21, 0x39, 0x39, 0x07, 0x07, 0x03, + 0x13, 0x0b, 0x18, 0x07, + 0x43, 0x27, 0x20, 0x0b, 0x40, 0x44, 0x44, 0x40, 0x40, 0x40, 0x04, 0x04, + 0x00, 0x04, 0x08, 0x04, + 0x08, 0x10, 0x00, 0x43, 0x43, 0x14, 0x00, 0x47, 0x43, 0x43, 0x14, 0x14, + 0x10, 0x18, 0x00, 0x04, + 0x08, 0x04, 0x08, 0x10, 0x00, 0x43, 0x43, 0x14, 0x00, 0x47, 0x43, 0x43, + 0x14, 0x14, 0x10, 0x18, + 0x20, 0x43, 0x31, 0x40, 0x4c, 0x40, 0x04, 0x07, 0x04, 0x10, 0x10, 0x21, + 0x08, 0x13, 0x40, 0x43, + 0x1c, 0x07, 0x40, 0x13, 0x40, 0x43, 0x1c, 0x07, 0x40, 0x13, 0x40, 0x43, + 0x1c, 0x07, 0x40, 0x4c, + 0x07, 0x0c, 0x0c, 0x18, 0x20, 0x18, 0x20, 0x0b, 0x17, 0x40, 0x43, 0x17, + 0x40, 0x43, 0x40, 0x40, + 0x40, 0x0b, 0x0b, 0x0b, 0x40, 0x0f, 0x0b, 0x07, 0x07, 0x2c, 0x27, 0x1c, + 0x07, 0x20, 0x1c, 0x18, + 0x44, 0x1f, 0x13, 0x0b, 0x40, 0x0f, 0x0b, 0x07, 0x1c, 0x0b, 0x28, 0x1c, + 0x1c, 0x0b, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x1d, 0x04, 0x47, 0x40, 0x02, 0x51, 0x5d, 0x2c, 0x40, 0x04, + 0x40, 0x40, 0x41, 0x0f, + 0x04, 0x16, 0x40, 0x14, 0x09, 0x16, 0x22, 0x3b, 0x3b, 0x07, 0x07, 0x03, + 0x11, 0x0b, 0x18, 0x07, + 0x42, 0x27, 0x21, 0x0b, 0x40, 0x44, 0x45, 0x40, 0x40, 0x40, 0x04, 0x04, + 0x00, 0x05, 0x08, 0x05, + 0x09, 0x11, 0x00, 0x42, 0x42, 0x16, 0x00, 0x47, 0x42, 0x42, 0x16, 0x15, + 0x10, 0x19, 0x00, 0x05, + 0x08, 0x05, 0x09, 0x11, 0x00, 0x42, 0x42, 0x16, 0x00, 0x47, 0x42, 0x42, + 0x16, 0x15, 0x10, 0x19, + 0x20, 0x43, 0x32, 0x40, 0x4c, 0x40, 0x04, 0x07, 0x04, 0x10, 0x10, 0x22, + 0x08, 0x13, 0x41, 0x43, + 0x1c, 0x07, 0x40, 0x13, 0x41, 0x43, 0x1c, 0x07, 0x40, 0x13, 0x41, 0x43, + 0x1c, 0x07, 0x40, 0x4c, + 0x07, 0x0c, 0x0c, 0x18, 0x20, 0x18, 0x20, 0x0b, 0x17, 0x41, 0x43, 0x17, + 0x41, 0x43, 0x40, 0x40, + 0x40, 0x0a, 0x0b, 0x0b, 0x40, 0x0f, 0x0b, 0x06, 0x06, 0x2c, 0x27, 0x1c, + 0x07, 0x20, 0x1c, 0x18, + 0x44, 0x1d, 0x13, 0x0b, 0x40, 0x0f, 0x0b, 0x06, 0x1d, 0x0b, 0x29, 0x1d, + 0x1d, 0x0b, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x1e, 0x04, 0x46, 0x40, 0x01, 0x51, 0x5e, 0x2c, 0x40, 0x04, + 0x40, 0x40, 0x41, 0x0f, + 0x04, 0x18, 0x40, 0x14, 0x0b, 0x18, 0x24, 0x3e, 0x3e, 0x07, 0x07, 0x03, + 0x0f, 0x0b, 0x19, 0x07, + 0x41, 0x27, 0x23, 0x0b, 0x40, 0x44, 0x46, 0x40, 0x40, 0x40, 0x04, 0x04, + 0x01, 0x06, 0x09, 0x06, + 0x0b, 0x13, 0x01, 0x41, 0x41, 0x18, 0x01, 0x46, 0x41, 0x41, 0x18, 0x16, + 0x11, 0x1b, 0x01, 0x06, + 0x09, 0x06, 0x0b, 0x13, 0x01, 0x41, 0x41, 0x18, 0x01, 0x46, 0x41, 0x41, + 0x18, 0x16, 0x11, 0x1b, + 0x21, 0x43, 0x34, 0x40, 0x4c, 0x40, 0x04, 0x07, 0x04, 0x11, 0x11, 0x24, + 0x09, 0x13, 0x41, 0x43, + 0x1c, 0x07, 0x40, 0x13, 0x41, 0x43, 0x1c, 0x07, 0x40, 0x13, 0x41, 0x43, + 0x1c, 0x07, 0x40, 0x4c, + 0x07, 0x0c, 0x0c, 0x19, 0x21, 0x19, 0x21, 0x0b, 0x17, 0x41, 0x43, 0x17, + 0x41, 0x43, 0x40, 0x40, + 0x40, 0x09, 0x0b, 0x0b, 0x40, 0x0f, 0x0b, 0x06, 0x06, 0x2c, 0x27, 0x1c, + 0x07, 0x21, 0x1c, 0x19, + 0x44, 0x1c, 0x13, 0x0b, 0x40, 0x0f, 0x0b, 0x06, 0x1e, 0x0b, 0x2b, 0x1e, + 0x1e, 0x0b, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x1f, 0x05, 0x45, 0x40, 0x00, 0x52, 0x5f, 0x2d, 0x40, 0x05, + 0x40, 0x40, 0x42, 0x0f, + 0x05, 0x19, 0x40, 0x15, 0x0c, 0x19, 0x26, 0x3e, 0x3e, 0x07, 0x07, 0x02, + 0x0e, 0x0a, 0x1a, 0x07, + 0x40, 0x27, 0x24, 0x0a, 0x40, 0x45, 0x47, 0x40, 0x40, 0x40, 0x05, 0x05, + 0x02, 0x07, 0x0a, 0x07, + 0x0c, 0x14, 0x02, 0x40, 0x40, 0x19, 0x02, 0x45, 0x40, 0x40, 0x19, 0x17, + 0x12, 0x1c, 0x02, 0x07, + 0x0a, 0x07, 0x0c, 0x14, 0x02, 0x40, 0x40, 0x19, 0x02, 0x45, 0x40, 0x40, + 0x19, 0x17, 0x12, 0x1c, + 0x22, 0x42, 0x36, 0x40, 0x4d, 0x40, 0x05, 0x07, 0x05, 0x12, 0x12, 0x26, + 0x0a, 0x12, 0x42, 0x42, + 0x1d, 0x07, 0x40, 0x12, 0x42, 0x42, 0x1d, 0x07, 0x40, 0x12, 0x42, 0x42, + 0x1d, 0x07, 0x40, 0x4d, + 0x07, 0x0d, 0x0d, 0x1a, 0x22, 0x1a, 0x22, 0x0a, 0x17, 0x42, 0x42, 0x17, + 0x42, 0x42, 0x40, 0x40, + 0x40, 0x08, 0x0a, 0x0a, 0x40, 0x0f, 0x0a, 0x05, 0x05, 0x2d, 0x27, 0x1d, + 0x07, 0x22, 0x1d, 0x1a, + 0x45, 0x1b, 0x12, 0x0a, 0x40, 0x0f, 0x0a, 0x05, 0x1f, 0x0a, 0x2c, 0x1f, + 0x1f, 0x0a, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x20, 0x05, 0x45, 0x40, 0x40, 0x52, 0x60, 0x2d, 0x40, 0x05, + 0x40, 0x40, 0x42, 0x0f, + 0x05, 0x1b, 0x40, 0x15, 0x0d, 0x1b, 0x28, 0x3e, 0x3e, 0x07, 0x07, 0x02, + 0x0c, 0x0a, 0x1a, 0x07, + 0x00, 0x27, 0x25, 0x0a, 0x40, 0x45, 0x48, 0x40, 0x40, 0x40, 0x05, 0x05, + 0x02, 0x08, 0x0a, 0x08, + 0x0d, 0x15, 0x02, 0x00, 0x00, 0x1b, 0x02, 0x45, 0x00, 0x00, 0x1b, 0x18, + 0x12, 0x1d, 0x02, 0x08, + 0x0a, 0x08, 0x0d, 0x15, 0x02, 0x00, 0x00, 0x1b, 0x02, 0x45, 0x00, 0x00, + 0x1b, 0x18, 0x12, 0x1d, + 0x22, 0x42, 0x38, 0x40, 0x4d, 0x40, 0x05, 0x07, 0x05, 0x12, 0x12, 0x28, + 0x0a, 0x12, 0x42, 0x42, + 0x1d, 0x07, 0x40, 0x12, 0x42, 0x42, 0x1d, 0x07, 0x40, 0x12, 0x42, 0x42, + 0x1d, 0x07, 0x40, 0x4d, + 0x07, 0x0d, 0x0d, 0x1a, 0x22, 0x1a, 0x22, 0x0a, 0x17, 0x42, 0x42, 0x17, + 0x42, 0x42, 0x40, 0x40, + 0x40, 0x07, 0x0a, 0x0a, 0x40, 0x0f, 0x0a, 0x05, 0x05, 0x2d, 0x27, 0x1d, + 0x07, 0x22, 0x1d, 0x1a, + 0x45, 0x1a, 0x12, 0x0a, 0x40, 0x0f, 0x0a, 0x05, 0x20, 0x0a, 0x2d, 0x20, + 0x20, 0x0a, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x21, 0x05, 0x44, 0x40, 0x41, 0x53, 0x61, 0x2d, 0x40, 0x05, + 0x40, 0x40, 0x43, 0x0f, + 0x05, 0x1c, 0x40, 0x15, 0x0e, 0x1c, 0x2a, 0x3e, 0x3e, 0x07, 0x07, 0x02, + 0x0b, 0x0a, 0x1b, 0x07, + 0x01, 0x27, 0x26, 0x0a, 0x40, 0x45, 0x49, 0x40, 0x40, 0x40, 0x05, 0x05, + 0x03, 0x09, 0x0b, 0x09, + 0x0e, 0x16, 0x03, 0x01, 0x01, 0x1c, 0x03, 0x44, 0x01, 0x01, 0x1c, 0x19, + 0x13, 0x1e, 0x03, 0x09, + 0x0b, 0x09, 0x0e, 0x16, 0x03, 0x01, 0x01, 0x1c, 0x03, 0x44, 0x01, 0x01, + 0x1c, 0x19, 0x13, 0x1e, + 0x23, 0x42, 0x3a, 0x40, 0x4d, 0x40, 0x05, 0x07, 0x05, 0x13, 0x13, 0x2a, + 0x0b, 0x12, 0x43, 0x42, + 0x1d, 0x07, 0x40, 0x12, 0x43, 0x42, 0x1d, 0x07, 0x40, 0x12, 0x43, 0x42, + 0x1d, 0x07, 0x40, 0x4d, + 0x07, 0x0d, 0x0d, 0x1b, 0x23, 0x1b, 0x23, 0x0a, 0x17, 0x43, 0x42, 0x17, + 0x43, 0x42, 0x40, 0x40, + 0x40, 0x06, 0x0a, 0x0a, 0x40, 0x0f, 0x0a, 0x04, 0x04, 0x2d, 0x27, 0x1d, + 0x07, 0x23, 0x1d, 0x1b, + 0x45, 0x18, 0x12, 0x0a, 0x40, 0x0f, 0x0a, 0x04, 0x21, 0x0a, 0x2e, 0x21, + 0x21, 0x0a, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x22, 0x06, 0x43, 0x40, 0x42, 0x54, 0x62, 0x2e, 0x40, 0x06, + 0x40, 0x40, 0x44, 0x0f, + 0x06, 0x1e, 0x40, 0x16, 0x10, 0x1e, 0x2c, 0x3e, 0x3e, 0x07, 0x07, 0x01, + 0x09, 0x09, 0x1c, 0x07, + 0x02, 0x27, 0x28, 0x09, 0x40, 0x46, 0x4a, 0x40, 0x40, 0x40, 0x06, 0x06, + 0x04, 0x0a, 0x0c, 0x0a, + 0x10, 0x18, 0x04, 0x02, 0x02, 0x1e, 0x04, 0x43, 0x02, 0x02, 0x1e, 0x1a, + 0x14, 0x20, 0x04, 0x0a, + 0x0c, 0x0a, 0x10, 0x18, 0x04, 0x02, 0x02, 0x1e, 0x04, 0x43, 0x02, 0x02, + 0x1e, 0x1a, 0x14, 0x20, + 0x24, 0x41, 0x3c, 0x40, 0x4e, 0x40, 0x06, 0x07, 0x06, 0x14, 0x14, 0x2c, + 0x0c, 0x11, 0x44, 0x41, + 0x1e, 0x07, 0x40, 0x11, 0x44, 0x41, 0x1e, 0x07, 0x40, 0x11, 0x44, 0x41, + 0x1e, 0x07, 0x40, 0x4e, + 0x07, 0x0e, 0x0e, 0x1c, 0x24, 0x1c, 0x24, 0x09, 0x17, 0x44, 0x41, 0x17, + 0x44, 0x41, 0x40, 0x40, + 0x40, 0x05, 0x09, 0x09, 0x40, 0x0f, 0x09, 0x03, 0x03, 0x2e, 0x27, 0x1e, + 0x07, 0x24, 0x1e, 0x1c, + 0x46, 0x17, 0x11, 0x09, 0x40, 0x0f, 0x09, 0x03, 0x22, 0x09, 0x30, 0x22, + 0x22, 0x09, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x23, 0x06, 0x43, 0x40, 0x43, 0x54, 0x63, 0x2e, 0x40, 0x06, + 0x40, 0x40, 0x44, 0x0f, + 0x06, 0x1f, 0x40, 0x16, 0x11, 0x1f, 0x2e, 0x3e, 0x3e, 0x07, 0x07, 0x01, + 0x08, 0x09, 0x1c, 0x07, + 0x03, 0x27, 0x29, 0x09, 0x40, 0x46, 0x4b, 0x40, 0x40, 0x40, 0x06, 0x06, + 0x04, 0x0b, 0x0c, 0x0b, + 0x11, 0x19, 0x04, 0x03, 0x03, 0x1f, 0x04, 0x43, 0x03, 0x03, 0x1f, 0x1b, + 0x14, 0x21, 0x04, 0x0b, + 0x0c, 0x0b, 0x11, 0x19, 0x04, 0x03, 0x03, 0x1f, 0x04, 0x43, 0x03, 0x03, + 0x1f, 0x1b, 0x14, 0x21, + 0x24, 0x41, 0x3e, 0x40, 0x4e, 0x40, 0x06, 0x07, 0x06, 0x14, 0x14, 0x2e, + 0x0c, 0x11, 0x44, 0x41, + 0x1e, 0x07, 0x40, 0x11, 0x44, 0x41, 0x1e, 0x07, 0x40, 0x11, 0x44, 0x41, + 0x1e, 0x07, 0x40, 0x4e, + 0x07, 0x0e, 0x0e, 0x1c, 0x24, 0x1c, 0x24, 0x09, 0x17, 0x44, 0x41, 0x17, + 0x44, 0x41, 0x40, 0x40, + 0x40, 0x04, 0x09, 0x09, 0x40, 0x0f, 0x09, 0x03, 0x03, 0x2e, 0x27, 0x1e, + 0x07, 0x24, 0x1e, 0x1c, + 0x46, 0x16, 0x11, 0x09, 0x40, 0x0f, 0x09, 0x03, 0x23, 0x09, 0x31, 0x23, + 0x23, 0x09, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x24, 0x06, 0x42, 0x40, 0x44, 0x55, 0x64, 0x2e, 0x40, 0x06, + 0x40, 0x40, 0x45, 0x0f, + 0x06, 0x21, 0x40, 0x16, 0x12, 0x21, 0x30, 0x3e, 0x3e, 0x07, 0x07, 0x01, + 0x06, 0x09, 0x1d, 0x07, + 0x04, 0x27, 0x2a, 0x09, 0x40, 0x46, 0x4c, 0x40, 0x40, 0x40, 0x06, 0x06, + 0x05, 0x0c, 0x0d, 0x0c, + 0x12, 0x1a, 0x05, 0x04, 0x04, 0x21, 0x05, 0x42, 0x04, 0x04, 0x21, 0x1c, + 0x15, 0x22, 0x05, 0x0c, + 0x0d, 0x0c, 0x12, 0x1a, 0x05, 0x04, 0x04, 0x21, 0x05, 0x42, 0x04, 0x04, + 0x21, 0x1c, 0x15, 0x22, + 0x25, 0x41, 0x3e, 0x40, 0x4e, 0x40, 0x06, 0x07, 0x06, 0x15, 0x15, 0x30, + 0x0d, 0x11, 0x45, 0x41, + 0x1e, 0x07, 0x40, 0x11, 0x45, 0x41, 0x1e, 0x07, 0x40, 0x11, 0x45, 0x41, + 0x1e, 0x07, 0x40, 0x4e, + 0x07, 0x0e, 0x0e, 0x1d, 0x25, 0x1d, 0x25, 0x09, 0x17, 0x45, 0x41, 0x17, + 0x45, 0x41, 0x40, 0x40, + 0x40, 0x03, 0x09, 0x09, 0x40, 0x0f, 0x09, 0x02, 0x02, 0x2e, 0x27, 0x1e, + 0x07, 0x25, 0x1e, 0x1d, + 0x46, 0x15, 0x11, 0x09, 0x40, 0x0f, 0x09, 0x02, 0x24, 0x09, 0x32, 0x24, + 0x24, 0x09, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x24, 0x06, 0x42, 0x40, 0x45, 0x56, 0x65, 0x2e, 0x40, 0x06, + 0x40, 0x40, 0x46, 0x0f, + 0x06, 0x22, 0x40, 0x16, 0x13, 0x22, 0x31, 0x3e, 0x3e, 0x07, 0x07, 0x00, + 0x04, 0x08, 0x1d, 0x07, + 0x04, 0x27, 0x2b, 0x08, 0x40, 0x47, 0x4d, 0x40, 0x40, 0x40, 0x06, 0x06, + 0x05, 0x0c, 0x0d, 0x0c, + 0x13, 0x1b, 0x05, 0x04, 0x04, 0x22, 0x05, 0x42, 0x04, 0x04, 0x22, 0x1c, + 0x15, 0x23, 0x05, 0x0c, + 0x0d, 0x0c, 0x13, 0x1b, 0x05, 0x04, 0x04, 0x22, 0x05, 0x42, 0x04, 0x04, + 0x22, 0x1c, 0x15, 0x23, + 0x25, 0x41, 0x3e, 0x40, 0x4f, 0x40, 0x06, 0x07, 0x06, 0x15, 0x15, 0x31, + 0x0d, 0x10, 0x46, 0x41, + 0x1e, 0x07, 0x40, 0x10, 0x46, 0x41, 0x1e, 0x07, 0x40, 0x10, 0x46, 0x41, + 0x1e, 0x07, 0x40, 0x4f, + 0x07, 0x0e, 0x0e, 0x1d, 0x25, 0x1d, 0x25, 0x08, 0x17, 0x46, 0x41, 0x17, + 0x46, 0x41, 0x40, 0x40, + 0x40, 0x02, 0x08, 0x08, 0x40, 0x0f, 0x08, 0x01, 0x01, 0x2e, 0x27, 0x1e, + 0x07, 0x25, 0x1e, 0x1d, + 0x47, 0x13, 0x10, 0x08, 0x40, 0x0f, 0x08, 0x01, 0x24, 0x08, 0x33, 0x24, + 0x24, 0x08, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x25, 0x07, 0x41, 0x40, 0x45, 0x56, 0x65, 0x2f, 0x40, 0x07, + 0x40, 0x40, 0x46, 0x0f, + 0x07, 0x24, 0x40, 0x17, 0x15, 0x24, 0x33, 0x3e, 0x3e, 0x07, 0x07, 0x00, + 0x03, 0x08, 0x1e, 0x07, + 0x05, 0x27, 0x2d, 0x08, 0x40, 0x47, 0x4d, 0x40, 0x40, 0x40, 0x07, 0x07, + 0x06, 0x0d, 0x0e, 0x0d, + 0x15, 0x1d, 0x06, 0x05, 0x05, 0x24, 0x06, 0x41, 0x05, 0x05, 0x24, 0x1d, + 0x16, 0x25, 0x06, 0x0d, + 0x0e, 0x0d, 0x15, 0x1d, 0x06, 0x05, 0x05, 0x24, 0x06, 0x41, 0x05, 0x05, + 0x24, 0x1d, 0x16, 0x25, + 0x26, 0x40, 0x3e, 0x40, 0x4f, 0x40, 0x07, 0x07, 0x07, 0x16, 0x16, 0x33, + 0x0e, 0x10, 0x46, 0x40, + 0x1f, 0x07, 0x40, 0x10, 0x46, 0x40, 0x1f, 0x07, 0x40, 0x10, 0x46, 0x40, + 0x1f, 0x07, 0x40, 0x4f, + 0x07, 0x0f, 0x0f, 0x1e, 0x26, 0x1e, 0x26, 0x08, 0x17, 0x46, 0x40, 0x17, + 0x46, 0x40, 0x40, 0x40, + 0x40, 0x02, 0x08, 0x08, 0x40, 0x0f, 0x08, 0x01, 0x01, 0x2f, 0x27, 0x1f, + 0x07, 0x26, 0x1f, 0x1e, + 0x47, 0x12, 0x10, 0x08, 0x40, 0x0f, 0x08, 0x01, 0x25, 0x08, 0x35, 0x25, + 0x25, 0x08, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x26, 0x07, 0x40, 0x40, 0x46, 0x57, 0x66, 0x2f, 0x40, 0x07, + 0x40, 0x40, 0x47, 0x0f, + 0x07, 0x26, 0x40, 0x17, 0x16, 0x26, 0x35, 0x3e, 0x3e, 0x07, 0x07, 0x00, + 0x01, 0x08, 0x1f, 0x07, + 0x06, 0x27, 0x2e, 0x08, 0x40, 0x47, 0x4e, 0x40, 0x40, 0x40, 0x07, 0x07, + 0x07, 0x0e, 0x0f, 0x0e, + 0x16, 0x1e, 0x07, 0x06, 0x06, 0x26, 0x07, 0x40, 0x06, 0x06, 0x26, 0x1e, + 0x17, 0x26, 0x07, 0x0e, + 0x0f, 0x0e, 0x16, 0x1e, 0x07, 0x06, 0x06, 0x26, 0x07, 0x40, 0x06, 0x06, + 0x26, 0x1e, 0x17, 0x26, + 0x27, 0x40, 0x3e, 0x40, 0x4f, 0x40, 0x07, 0x07, 0x07, 0x17, 0x17, 0x35, + 0x0f, 0x10, 0x47, 0x40, + 0x1f, 0x07, 0x40, 0x10, 0x47, 0x40, 0x1f, 0x07, 0x40, 0x10, 0x47, 0x40, + 0x1f, 0x07, 0x40, 0x4f, + 0x07, 0x0f, 0x0f, 0x1f, 0x27, 0x1f, 0x27, 0x08, 0x17, 0x47, 0x40, 0x17, + 0x47, 0x40, 0x40, 0x40, + 0x40, 0x01, 0x08, 0x08, 0x40, 0x0f, 0x08, 0x00, 0x00, 0x2f, 0x27, 0x1f, + 0x07, 0x27, 0x1f, 0x1f, + 0x47, 0x11, 0x10, 0x08, 0x40, 0x0f, 0x08, 0x00, 0x26, 0x08, 0x36, 0x26, + 0x26, 0x08, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x07, 0x3e, 0x27, 0x07, 0x40, 0x40, 0x47, 0x57, 0x67, 0x2f, 0x40, 0x07, + 0x40, 0x40, 0x47, 0x0f, + 0x07, 0x27, 0x40, 0x17, 0x17, 0x27, 0x37, 0x3e, 0x3e, 0x07, 0x07, 0x00, + 0x00, 0x08, 0x1f, 0x07, + 0x07, 0x27, 0x2f, 0x08, 0x40, 0x47, 0x4f, 0x40, 0x40, 0x40, 0x07, 0x07, + 0x07, 0x0f, 0x0f, 0x0f, + 0x17, 0x1f, 0x07, 0x07, 0x07, 0x27, 0x07, 0x40, 0x07, 0x07, 0x27, 0x1f, + 0x17, 0x27, 0x07, 0x0f, + 0x0f, 0x0f, 0x17, 0x1f, 0x07, 0x07, 0x07, 0x27, 0x07, 0x40, 0x07, 0x07, + 0x27, 0x1f, 0x17, 0x27, + 0x27, 0x40, 0x3e, 0x40, 0x4f, 0x40, 0x07, 0x07, 0x07, 0x17, 0x17, 0x37, + 0x0f, 0x10, 0x47, 0x40, + 0x1f, 0x07, 0x40, 0x10, 0x47, 0x40, 0x1f, 0x07, 0x40, 0x10, 0x47, 0x40, + 0x1f, 0x07, 0x40, 0x4f, + 0x07, 0x0f, 0x0f, 0x1f, 0x27, 0x1f, 0x27, 0x08, 0x17, 0x47, 0x40, 0x17, + 0x47, 0x40, 0x40, 0x40, + 0x40, 0x00, 0x08, 0x08, 0x40, 0x0f, 0x08, 0x00, 0x00, 0x2f, 0x27, 0x1f, + 0x07, 0x27, 0x1f, 0x1f, + 0x47, 0x10, 0x10, 0x08, 0x40, 0x0f, 0x08, 0x00, 0x27, 0x08, 0x37, 0x27, + 0x27, 0x08, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, +}; + +#endif diff --git a/drivers/staging/rockchip-mpp/rkvdec/hal.h b/drivers/staging/rockchip-mpp/rkvdec/hal.h new file mode 100644 index 000000000000..e70764be8354 --- /dev/null +++ b/drivers/staging/rockchip-mpp/rkvdec/hal.h @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _RKVDEC_HAL_H +#define _RKVDEC_HAL_H + +/* The maximum registers number of all the version */ +#define ROCKCHIP_RKVDEC_REG_NUM (109) + +#define RKVDEC_REG_DEC_INT_EN 0x004 +#define RKVDEC_REG_DEC_INT_EN_INDEX (1) +#define RKVDEC_WR_DDR_ALIGN_EN BIT(23) +#define RKVDEC_FORCE_SOFT_RESET_VALID BIT(21) +#define RKVDEC_SOFTWARE_RESET_EN BIT(20) +#define RKVDEC_INT_COLMV_REF_ERROR BIT(17) +#define RKVDEC_INT_BUF_EMPTY BIT(16) +#define RKVDEC_INT_TIMEOUT BIT(15) +#define RKVDEC_INT_STRM_ERROR BIT(14) +#define RKVDEC_INT_BUS_ERROR BIT(13) +#define RKVDEC_DEC_INT_RAW BIT(9) +#define RKVDEC_DEC_INT BIT(8) +#define RKVDEC_DEC_TIMEOUT_EN BIT(5) +#define RKVDEC_DEC_IRQ_DIS BIT(4) +#define RKVDEC_CLOCK_GATE_EN BIT(1) +#define RKVDEC_DEC_START BIT(0) + +#define RKVDEC_REG_SYS_CTRL 0x008 +#define RKVDEC_REG_SYS_CTRL_INDEX (2) +#define RKVDEC_GET_FORMAT(x) (((x) >> 20) & 0x3) +#define RKVDEC_FMT_H265D (0) +#define RKVDEC_FMT_H264D (1) +#define RKVDEC_FMT_VP9D (2) + +#define RKVDEC_REG_STREAM_RLC_BASE 0x010 +#define RKVDEC_REG_STREAM_RLC_BASE_INDEX (4) + +#define RKVDEC_REG_PPS_BASE 0x0a0 +#define RKVDEC_REG_PPS_BASE_INDEX (42) + +#define RKVDEC_REG_VP9_REFCOLMV_BASE 0x0d0 +#define RKVDEC_REG_VP9_REFCOLMV_BASE_INDEX (52) + +#define RKVDEC_REG_CACHE_ENABLE(i) (0x41c + ((i) * 0x40)) +#define RKVDEC_CACHE_PERMIT_CACHEABLE_ACCESS BIT(0) +#define RKVDEC_CACHE_PERMIT_READ_ALLOCATE BIT(1) +#define RKVDEC_CACHE_LINE_SIZE_64_BYTES BIT(4) + +int rkvdec_avc_gen_reg(struct mpp_session *session, void *regs, + struct vb2_v4l2_buffer *src_buf); + +int rkvdec_hevc_gen_reg(struct mpp_session *session, void *regs, + struct vb2_v4l2_buffer *src_buf); + +void rkvdec_avc_assign_errorinfo(void *regs, dma_addr_t addr); + +void rkvdec_assign_cabac(void *regs, dma_addr_t addr); + +#endif diff --git a/drivers/staging/rockchip-mpp/rkvdec/hevc.c b/drivers/staging/rockchip-mpp/rkvdec/hevc.c new file mode 100644 index 000000000000..78f150000128 --- /dev/null +++ b/drivers/staging/rockchip-mpp/rkvdec/hevc.c @@ -0,0 +1,167 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2019 Randy Li, + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include + +#include +#include +#include +#include +#include + +#include "mpp_dev_common.h" +#include "hal.h" +#include "regs.h" + +static void init_hw_cfg(struct rkvdec_regs *p_regs) +{ + p_regs->sw_interrupt.dec_e = 1; + p_regs->sw_interrupt.dec_timeout_e = 1; + /* TODO: support HEVC tiles */ + p_regs->sw_interrupt.wr_ddr_align_en = 1; + /* HEVC */ + p_regs->sw_sysctrl.dec_mode = RKVDEC_FMT_H265D; + + p_regs->sw_ref_valid = 0; + /* cabac_error_en */ + p_regs->sw_strmd_error_en = 0xfdfffffd; + /* p_regs->extern_error_en = 0x30000000; */ + p_regs->extern_error_en.error_en_highbits = 0x3000000; +} + +static void ctb_calc(struct rkvdec_regs *p_regs, + const struct v4l2_ctrl_hevc_sps *sps) +{ + u32 min_cb_log2_size_y, ctb_log2_size_y, min_cb_size_y, ctb_size_y; + u32 pic_width_in_min_cbs_y, pic_height_in_min_bbs_y; + u32 stride_y, stride_uv, virstride_y, virstride_yuv; + u32 width, height; + + min_cb_log2_size_y = sps->log2_min_luma_coding_block_size_minus3 + 3; + ctb_log2_size_y = min_cb_log2_size_y + + sps->log2_diff_max_min_luma_coding_block_size; + + min_cb_size_y = 1 << min_cb_log2_size_y; + /* uiMaxCUWidth */ + ctb_size_y = 1 << ctb_log2_size_y; + + /* PicWidthInCtbsY (7-15) */ + pic_width_in_min_cbs_y = sps->pic_width_in_luma_samples / min_cb_size_y; + pic_height_in_min_bbs_y = sps->pic_height_in_luma_samples / + min_cb_size_y; + + width = pic_width_in_min_cbs_y << min_cb_log2_size_y; + height = pic_height_in_min_bbs_y << min_cb_log2_size_y; + + stride_y = (roundup(width, ctb_size_y) * + ALIGN(sps->bit_depth_luma_minus8, 8)) >> 3; + stride_uv = (roundup(height, ctb_size_y) * + ALIGN(sps->bit_depth_chroma_minus8, 8)) >> 3; + stride_y = ALIGN(stride_y, 256) | 256; + stride_uv = ALIGN(stride_uv, 256) | 256; + + virstride_y = stride_y * ALIGN(height, 8); + /* TODO: only NV12 is supported by device now */ + virstride_yuv = virstride_y + ((stride_uv * ALIGN(height, 8)) >> 1); + + p_regs->sw_picparameter.y_hor_virstride = stride_y >> 4; + p_regs->sw_picparameter.uv_hor_virstride = stride_uv >> 4; + p_regs->sw_y_virstride = virstride_y >> 4; + p_regs->sw_yuv_virstride = virstride_yuv >> 4; +} + +static int rkvdec_hevc_gen_ref(struct rkvdec_regs *p_regs, + struct vb2_v4l2_buffer *dst_buf, + const struct v4l2_ctrl_hevc_slice_params *slice_params) +{ + struct vb2_queue *cap_q = dst_buf->vb2_buf.vb2_queue; + dma_addr_t cur_addr; + u16 i = 0; + + cur_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0); + p_regs->sw_decout_base = cur_addr; + + /* FIXME: use a const value */ + for (i = 0; i < 15; i++) + p_regs->sw_refer_base[i].ref_base = cur_addr >> 4; + + for (i = 0; i < slice_params->num_active_dpb_entries; i++) { + dma_addr_t ref_addr; + /* FIXME: why two pic_order_cnt */ + p_regs->sw_refer_poc[i] = slice_params->dpb[i].pic_order_cnt[0]; + + ref_addr = rockchip_mpp_find_addr(cap_q, &dst_buf->vb2_buf, + slice_params->dpb[i]. + timestamp); + if (!ref_addr) + ref_addr = cur_addr; + + p_regs->sw_refer_base[i].ref_base = ref_addr >> 4; + cur_addr = ref_addr; + + p_regs->sw_ref_valid |= (1 << i); + } + + /* Enable flag for reference picture */ + p_regs->sw_refer_base[0].ref_valid_flag = + (p_regs->sw_ref_valid >> 0) & 0xf; + p_regs->sw_refer_base[1].ref_valid_flag = + (p_regs->sw_ref_valid >> 4) & 0xf; + p_regs->sw_refer_base[2].ref_valid_flag = + (p_regs->sw_ref_valid >> 8) & 0xf; + p_regs->sw_refer_base[3].ref_valid_flag = + (p_regs->sw_ref_valid >> 12) & 0x7; + + return 0; +} + +int rkvdec_hevc_gen_reg(struct mpp_session *session, void *regs, + struct vb2_v4l2_buffer *src_buf) +{ + const struct v4l2_ctrl_hevc_sps *sps; + const struct v4l2_ctrl_hevc_pps *pps; + const struct v4l2_ctrl_hevc_slice_params *slice_params; + struct vb2_v4l2_buffer *dst_buf; + struct rkvdec_regs *p_regs = regs; + size_t stream_len = 0; + + sps = rockchip_mpp_get_cur_ctrl(session, V4L2_CID_MPEG_VIDEO_HEVC_SPS); + pps = rockchip_mpp_get_cur_ctrl(session, V4L2_CID_MPEG_VIDEO_HEVC_PPS); + slice_params = rockchip_mpp_get_cur_ctrl(session, + V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS); + if (!sps || !pps || !slice_params) + return -EINVAL; + + init_hw_cfg(p_regs); + + ctb_calc(p_regs, sps); + + /* FIXME: support more than 1 slice */ + p_regs->sw_picparameter.slice_num_lowbits = 0; + p_regs->sw_strm_rlc_base = + vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0); + /* The bitstream must be 128bit align ? */ + p_regs->sw_sysctrl.strm_start_bit = slice_params->data_bit_offset; + + /* hardware wants a zerod memory at the stream end */ + stream_len = DIV_ROUND_UP(slice_params->bit_size, 8); + stream_len = DIV_ROUND_UP(stream_len, 16) + 64; + p_regs->sw_stream_len = stream_len; + + dst_buf = v4l2_m2m_next_dst_buf(session->fh.m2m_ctx); + rkvdec_hevc_gen_ref(p_regs, dst_buf, slice_params); + + return 0; +} diff --git a/drivers/staging/rockchip-mpp/rkvdec/regs.h b/drivers/staging/rockchip-mpp/rkvdec/regs.h new file mode 100644 index 000000000000..bd200f6be9b3 --- /dev/null +++ b/drivers/staging/rockchip-mpp/rkvdec/regs.h @@ -0,0 +1,377 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2019 Randy Li + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _RKVDEC_REGS_H_ +#define _RKVDEC_REGS_H_ + +struct vp9_segid_grp { + /* this bit is only used by segid0 */ + u32 abs_delta:1; + u32 frame_qp_delta_en:1; + u32 frame_qp_delta:9; + u32 frame_loopfitler_value_en:1; + u32 frame_loopfilter_value:7; + u32 referinfo_en:1; + u32 referinfo:2; + u32 frame_skip_en:1; + u32 reserved0:9; +}; + +struct rkvdec_regs { + struct { + u32 minor_ver:8; + u32 level:1; + u32 dec_support:3; + u32 profile:1; + u32 reserved0:1; + u32 codec_flag:1; + u32 reserved1:1; + u32 prod_num:16; + } sw_id; + + struct { + u32 dec_e:1; + u32 dec_clkgate_e:1; + u32 reserved0:1; + u32 timeout_mode:1; + u32 dec_irq_dis:1; + u32 dec_timeout_e:1; + u32 buf_empty_en:1; + u32 stmerror_waitdecfifo_empty:1; + u32 dec_irq:1; + u32 dec_irq_raw:1; + u32 reserved1:2; + u32 dec_rdy_sta:1; + u32 dec_bus_sta:1; + u32 dec_error_sta:1; + u32 dec_empty_sta:1; + u32 colmv_ref_error_sta:1; + u32 cabu_end_sta:1; + u32 h264orvp9_error_mode:1; + u32 softrst_en_p:1; + u32 force_softreset_valid:1; + u32 softreset_rdy:1; + u32 wr_ddr_align_en:1; + u32 scl_down_en:1; + u32 allow_not_wr_unref_bframe:1; + u32 reserved2:6; + } sw_interrupt; + + struct { + u32 in_endian:1; + u32 in_swap32_e:1; + u32 in_swap64_e:1; + u32 str_endian:1; + u32 str_swap32_e:1; + u32 str_swap64_e:1; + u32 out_endian:1; + u32 out_swap32_e:1; + u32 out_cbcr_swap:1; + u32 reserved0:1; + u32 rlc_mode_direct_write:1; + u32 rlc_mode:1; + u32 strm_start_bit:7; + u32 reserved1:1; + u32 dec_mode:2; + u32 reserved2:2; + u32 rps_mode:1; + u32 stream_mode:1; + u32 stream_lastpacket:1; + u32 firstslice_flag:1; + u32 frame_orslice:1; + u32 buspr_slot_disable:1; + u32 colmv_mode:1; + u32 ycacherd_prior:1; + } sw_sysctrl; + + struct { + u32 y_hor_virstride:10; + u32 uv_hor_virstride_highbit:1; + u32 slice_num_highbit:1; + u32 uv_hor_virstride:9; + u32 slice_num_lowbits:11; + } sw_picparameter; + + u32 sw_strm_rlc_base; + u32 sw_stream_len; + u32 sw_cabactbl_base; + u32 sw_decout_base; + u32 sw_y_virstride; + u32 sw_yuv_virstride; + /* SWREG 10 */ + union { + struct { + union { + struct { + u32 ref_valid_flag:4; + u32 ref_base:28; + }; + struct { + u32 ref_field:1; + u32 ref_topfield_used:1; + u32 ref_botfield_used:1; + u32 ref_colmv_use_flag:1; + u32 padding:28; + }; + } sw_refer_base[15]; + u32 sw_refer_poc[15]; + }; + + struct { + struct { + u32 vp9_cprheader_offset:16; + u32 reserved0:16; + }; + struct { + u32 reserved1:4; + u32 vp9last_base:28; + }; + struct { + u32 reserved2:4; + u32 vp9golden_base:28; + }; + struct { + u32 reserved3:4; + u32 vp9alfter_base:28; + }; + struct { + u32 vp9count_update_en:1; + u32 reserved4:2; + u32 vp9count_base:29; + }; + struct { + u32 reserved5:4; + u32 vp9segidlast_base:28; + }; + struct { + u32 reserved6:4; + u32 vp9segidcur_base:28; + }; + struct { + u32 framewidth_last:16; + u32 frameheight_last:16; + }; + struct { + u32 framewidth_golden:16; + u32 frameheight_golden:16; + }; + struct { + u32 framewidth_alfter:16; + u32 frameheight_alfter:16; + }; + /* SWREG 20 (segid_grp0) to SWREG 27 (segid_grp7) */ + struct vp9_segid_grp grp[8]; + /* cprheader_config */ + struct { + u32 tx_mode:3; + u32 frame_reference_mode:2; + u32 reserved7:27; + }; + /* lref_scale */ + struct { + u32 lref_hor_scale:16; + u32 lref_ver_scale:16; + }; + /* gref_scale */ + struct { + u32 gref_hor_scale:16; + u32 gref_ver_scale:16; + }; + /* aref_scale */ + struct { + u32 aref_hor_scale:16; + u32 aref_ver_scale:16; + }; + /* ref_deltas_lastframe */ + struct { + u32 ref_deltas_lastframe:28; + u32 reserved8:4; + }; + /* info_lastframe */ + struct { + u32 mode_deltas_lastframe:14; + u32 reserved9:2; + u32 segmentation_enable_lastframe:1; + u32 last_show_frame:1; + u32 last_intra_only:1; + u32 last_widthheight_eqcur:1; + u32 color_space_lastkeyframe:3; + u32 reserved10:9; + }; + /* intercmd_base */ + struct { + u32 reserved11:4; + u32 intercmd_base:28; + }; + /* intercmd_num */ + struct { + u32 intercmd_num:24; + u32 reserved12:8; + }; + /* lasttile_size */ + struct { + u32 lasttile_size:24; + u32 reserved13:8; + }; + /* lastf_hor_virstride */ + struct { + u32 lastfy_hor_virstride:10; + u32 reserved14:6; + u32 lastfuv_hor_virstride:10; + u32 reserved15:6; + }; + /* goldenf_hor_virstride */ + struct { + u32 goldenfy_hor_virstride:10; + u32 reserved16:6; + u32 goldenuv_hor_virstride:10; + u32 reserved17:6; + }; + /* altreff_hor_virstride */ + struct { + u32 altrey_hor_virstride:10; + u32 reserved18:6; + u32 altreuv_hor_virstride:10; + u32 reserved19:6; + }; + } vp9; + }; + + /* SWREG 40 */ + u32 sw_cur_poc; + u32 sw_rlcwrite_base; + u32 sw_pps_base; + u32 sw_rps_base; + /* in HEVC, it is called cabac_error_en */ + u32 sw_strmd_error_en; + /* SWREG 45, cabac_error_status, vp9_error_info0 */ + struct { + u32 strmd_error_status:28; + u32 colmv_error_ref_picidx:4; + } sw_strmd_error_status; + + struct cabac_error_ctu { + u32 strmd_error_ctu_xoffset:8; + u32 strmd_error_ctu_yoffset:8; + u32 streamfifo_space2full:7; + u32 reserved0:1; + u32 vp9_error_ctu0_en:1; + u32 reversed1:7; + } cabac_error_ctu; + + /* SWREG 47 */ + struct sao_ctu_position { + u32 sw_saowr_xoffset:9; + u32 reversed0:7; + u32 sw_saowr_yoffset:10; + u32 reversed1:6; + } sao_ctu_position; + + /* SWREG 48 */ + union { + u32 sw_ref_valid; + struct { + u32 ref_base:10; + u32 ref_field:1; + u32 ref_topfield_used:1; + u32 ref_botfield_used:1; + u32 ref_colmv_use_flag:1; + u32 reverse0:18; + } sw48_h264; + + struct { + u32 lastfy_virstride:20; + u32 reserved0:12; + } sw48_vp9; + }; + + /* SWREG 49 - 63 */ + union { + u32 sw_refer15_29_poc[15]; + struct { + struct { + u32 goldeny_virstride:20; + u32 reserved0:12; + }; + struct { + u32 altrefy_virstride:20; + u32 reserved1:12; + }; + struct { + u32 lastref_yuv_virstride:20; + u32 reserved2:12; + }; + struct { + u32 reserved3:4; + u32 refcolmv_base:28; + }; + u32 padding[11]; + } vp9_vir; + + }; + + /* SWREG 64 */ + u32 performance_cycle; + u32 axi_ddr_rdata; + u32 axi_ddr_wdata; + /* SWREG 67 */ + u32 fpgadebug_reset; + + struct { + u32 perf_cnt0_sel:6; + u32 reserved2:2; + u32 perf_cnt1_sel:6; + u32 reserved1:2; + u32 perf_cnt2_sel:6; + u32 reserved0:10; + } sw68_perf_sel; + + u32 sw69_perf_cnt0; + u32 sw70_perf_cnt1; + u32 sw71_perf_cnt2; + u32 sw72_h264_refer30_poc; + u32 sw73_h264_refer31_poc; + /* SWREG 74 h264_cur_poc1 */ + u32 sw_cur_poc_b; + u32 sw75_errorinfo_base; + + union { + struct { + u32 slicedec_num:14; + u32 reserved1:1; + u32 strmd_detect_error_flag:1; + u32 sw_error_packet_num:14; + u32 reserved0:2; + } sw76_errorinfo_num; + + struct { + u32 error_ctu1_x:6; + u32 reserved0:2; + u32 vp9_error_ctu1_y:6; + u32 reserved1:1; + u32 vp9_error_ctu1_en:1; + u32 reserved2:16; + } swreg76_vp9_error_ctu1; + }; + + /* SWREG 77 */ + struct { + u32 error_en_highbits:28; + u32 strmd_error_en:2; + u32 reserved0:2; + } extern_error_en; +}; + +#endif diff --git a/drivers/staging/rockchip-mpp/vdpu2/hal.h b/drivers/staging/rockchip-mpp/vdpu2/hal.h new file mode 100644 index 000000000000..3da4b0e04c17 --- /dev/null +++ b/drivers/staging/rockchip-mpp/vdpu2/hal.h @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2019 Randy Li, + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _VDPU2_HAL_H_ +#define _VDPU2_HAL_H_ + +#include + +/* The maximum registers number of all the version */ +#define ROCKCHIP_VDPU2_REG_NUM 159 + +/* The first register of the decoder is Reg50(0x000c8) */ +#define RKVDPU2_REG_DEC_CTRL 0x0c8 +#define RKVDPU2_REG_DEC_CTRL_INDEX (50) + +#define RKVDPU2_REG_DEC_INT_EN 0x0dc +#define RKVDPU2_REG_DEC_INT_EN_INDEX (55) +#define RKVDPU2_INT_TIMEOUT BIT(13) +#define RKVDPU2_INT_STRM_ERROR BIT(12) +#define RKVDPU2_INT_SLICE BIT(9) +#define RKVDPU2_INT_ASO_ERROR BIT(8) +#define RKVDPU2_INT_BUF_EMPTY BIT(6) +#define RKVDPU2_INT_BUS_ERROR BIT(5) +#define RKVDPU2_DEC_INT BIT(4) +#define RKVDPU2_DEC_IRQ_DIS BIT(1) +#define RKVDPU2_DEC_INT_RAW BIT(0) + +#define RKVDPU2_REG_DEC_DEV_CTRL 0x0e4 +#define RKVDPU2_REG_DEC_DEV_CTRL_INDEX (57) +#define RKVDPU2_DEC_CLOCK_GATE_EN BIT(4) +#define RKVDPU2_DEC_START BIT(0) + +#define RKVDPU2_REG59 0x0ec +#define RKVDPU2_REG59_INDEX (59) + +int rkvdpu_mpeg2_gen_reg(struct mpp_session *session, void *regs, + struct vb2_v4l2_buffer *src_buf); +int rkvdpu_mpeg2_prepare_buf(struct mpp_session *session, void *regs); + +#endif diff --git a/drivers/staging/rockchip-mpp/vdpu2/mpeg2.c b/drivers/staging/rockchip-mpp/vdpu2/mpeg2.c new file mode 100644 index 000000000000..d32958c4cb20 --- /dev/null +++ b/drivers/staging/rockchip-mpp/vdpu2/mpeg2.c @@ -0,0 +1,270 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2019 Randy Li, + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include + +#include +#include +#include +#include +#include + +#include "mpp_dev_common.h" +#include "hal.h" +#include "regs.h" + +#define DEC_LITTLE_ENDIAN (1) + +static const u8 zigzag[64] = { + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63 +}; + +static const u8 intra_default_q_matrix[64] = { + 8, 16, 19, 22, 26, 27, 29, 34, + 16, 16, 22, 24, 27, 29, 34, 37, + 19, 22, 26, 27, 29, 34, 34, 38, + 22, 22, 26, 27, 29, 34, 37, 40, + 22, 26, 27, 29, 32, 35, 40, 48, + 26, 27, 29, 32, 35, 40, 48, 58, + 26, 27, 29, 34, 38, 46, 56, 69, + 27, 29, 35, 38, 46, 56, 69, 83 +}; + +static void mpeg2_dec_copy_qtable(u8 * qtable, const struct v4l2_ctrl_mpeg2_quantization + *ctrl) +{ + int i, n; + + if (!qtable || !ctrl) + return; + + if (ctrl->load_intra_quantiser_matrix) { + for (i = 0; i < 64; i++) + qtable[zigzag[i]] = ctrl->intra_quantiser_matrix[i]; + } else { + for (i = 0; i < 64; i++) + qtable[zigzag[i]] = intra_default_q_matrix[i]; + + } + + if (ctrl->load_non_intra_quantiser_matrix) { + for (i = 0; i < 64; i++) + qtable[zigzag[i] + 64] = + ctrl->non_intra_quantiser_matrix[i]; + } else { + for (i = 0; i < 64; i++) + qtable[zigzag[i] + 64] = 16; + } +} + +static void init_hw_cfg(struct vdpu2_regs *p_regs) +{ + p_regs->sw54.dec_strm_wordsp = 1; + p_regs->sw54.dec_strendian_e = DEC_LITTLE_ENDIAN; + p_regs->sw54.dec_in_wordsp = 1; + p_regs->sw54.dec_out_wordsp = 1; + p_regs->sw54.dec_in_endian = DEC_LITTLE_ENDIAN; //change + p_regs->sw54.dec_out_endian = DEC_LITTLE_ENDIAN; + p_regs->sw57.dec_timeout = 1; + p_regs->sw57.dec_timeout_e = 1; + + p_regs->sw57.dec_clk_gate_e = 1; + + p_regs->sw50.tiled_mode_msb = 0; + p_regs->sw56.dec_max_burst = 16; + p_regs->sw50.dec_scmd_dis = 0; + p_regs->sw50.dec_adv_pre_dis = 0; + p_regs->sw52.apf_threshold = 8; + + p_regs->sw50.dec_latency = 0; + p_regs->sw56.dec_data_disc_e = 0; + + p_regs->sw55.dec_irq = 0; + p_regs->sw56.dec_axi_rd_id = 0; + p_regs->sw56.dec_axi_wr_id = 0; + + /* default for MPEG-2 */ + p_regs->sw136.mv_accuracy_fwd = 1; + p_regs->sw136.mv_accuracy_bwd = 1; +} + +int rkvdpu_mpeg2_gen_reg(struct mpp_session *session, void *regs, + struct vb2_v4l2_buffer *src_buf) +{ + const struct v4l2_ctrl_mpeg2_slice_params *params; + const struct v4l2_ctrl_mpeg2_quantization *quantization; + const struct v4l2_mpeg2_sequence *sequence; + const struct v4l2_mpeg2_picture *picture; + struct vdpu2_regs *p_regs = regs; + + params = rockchip_mpp_get_cur_ctrl(session, + V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS); + quantization = rockchip_mpp_get_cur_ctrl(session, + V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION); + + if (!params) + return -EINVAL; + + sequence = ¶ms->sequence; + picture = ¶ms->picture; + + init_hw_cfg(p_regs); + + p_regs->sw120.pic_mb_width = DIV_ROUND_UP(sequence->horizontal_size, + 16); + p_regs->sw120.pic_mb_height_p = DIV_ROUND_UP(sequence->vertical_size, + 16); + + /* PICT_FRAME */ + if (picture->picture_structure == 3) { + p_regs->sw57.pic_fieldmode_e = 0; + } else { + p_regs->sw57.pic_fieldmode_e = 1; + /* PICT_TOP_FIEL */ + if (picture->picture_structure == 1) + p_regs->sw57.pic_topfield_e = 1; + } + + switch (picture->picture_coding_type) { + case V4L2_MPEG2_PICTURE_CODING_TYPE_B: + p_regs->sw57.pic_b_e = 1; + case V4L2_MPEG2_PICTURE_CODING_TYPE_P: + p_regs->sw57.pic_inter_e = 1; + break; + case V4L2_MPEG2_PICTURE_CODING_TYPE_I: + default: + p_regs->sw57.pic_inter_e = 0; + p_regs->sw57.pic_b_e = 0; + break; + } + + if (picture->top_field_first) + p_regs->sw120.mpeg.topfieldfirst_e = 1; + + p_regs->sw57.fwd_interlace_e = 0; + p_regs->sw57.write_mvs_e = 0; + + p_regs->sw120.mpeg.alt_scan_e = picture->alternate_scan; + p_regs->sw136.alt_scan_flag_e = picture->alternate_scan; + + p_regs->sw122.qscale_type = picture->q_scale_type; + p_regs->sw122.intra_dc_prec = picture->intra_dc_precision; + p_regs->sw122.con_mv_e = picture->concealment_motion_vectors; + p_regs->sw122.intra_vlc_tab = picture->intra_vlc_format; + p_regs->sw122.frame_pred_dct = picture->frame_pred_frame_dct; + p_regs->sw51.qp_init = 1; + + /* MPEG-2 decoding mode */ + p_regs->sw53.dec_mode = RKVDPU2_FMT_MPEG2D; + + p_regs->sw136.fcode_fwd_hor = picture->f_code[0][0]; + p_regs->sw136.fcode_fwd_ver = picture->f_code[0][1]; + p_regs->sw136.fcode_bwd_hor = picture->f_code[1][0]; + p_regs->sw136.fcode_bwd_ver = picture->f_code[1][1]; + + p_regs->sw57.pic_interlace_e = 1 - sequence->progressive_sequence; +#if 0 + /* MPEG-1 decoding mode */ + p_regs->sw53.sw_dec_mode = 6; + p_regs->sw136.fcode_fwd_hor = picture->f_code[0][1]; + p_regs->sw136.fcode_fwd_ver = picture->f_code[0][1]; + p_regs->sw136.fcode_bwd_hor = picture->f_code[1][1]; + p_regs->sw136.fcode_bwd_ver = picture->f_code[1][1]; + if (picture->f_code[0][0]) + p_regs->sw136.mv_accuracy_fwd = 0; + if (picture->f_code[1][0]) + p_regs->sw136.mv_accuracy_bwd = 0; +#endif + p_regs->sw52.startmb_x = 0; + p_regs->sw52.startmb_y = 0; + p_regs->sw57.dec_out_dis = 0; + p_regs->sw50.filtering_dis = 1; + + p_regs->sw64.rlc_vlc_base = + vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0); + p_regs->sw122.strm_start_bit = params->data_bit_offset; + p_regs->sw51.stream_len = vb2_get_plane_payload(&src_buf->vb2_buf, 0); + + return 0; +} + +int rkvdpu_mpeg2_prepare_buf(struct mpp_session *session, void *regs) +{ + const struct v4l2_ctrl_mpeg2_slice_params *params; + const struct v4l2_mpeg2_sequence *sequence; + const struct v4l2_mpeg2_picture *picture; + struct vb2_v4l2_buffer *dst_buf; + dma_addr_t cur_addr, fwd_addr, bwd_addr; + struct vb2_queue *cap_q = &session->fh.m2m_ctx->cap_q_ctx.q; + struct vdpu2_regs *p_regs = regs; + + params = + rockchip_mpp_get_cur_ctrl(session, + V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS); + picture = ¶ms->picture; + sequence = ¶ms->sequence; + + dst_buf = v4l2_m2m_next_dst_buf(session->fh.m2m_ctx); + cur_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0); + + fwd_addr = + rockchip_mpp_find_addr(cap_q, &dst_buf->vb2_buf, + params->forward_ref_ts); + bwd_addr = + rockchip_mpp_find_addr(cap_q, &dst_buf->vb2_buf, + params->backward_ref_ts); + if (!bwd_addr) + bwd_addr = cur_addr; + if (!fwd_addr) + fwd_addr = cur_addr; + + /* Starting from the second horizontal line */ + if (picture->picture_structure == 2) + cur_addr += ALIGN(sequence->horizontal_size, 16); + p_regs->sw63.dec_out_base = cur_addr; + + if (picture->picture_coding_type == V4L2_MPEG2_PICTURE_CODING_TYPE_B) { + p_regs->sw131.refer0_base = fwd_addr >> 2; + p_regs->sw148.refer1_base = fwd_addr >> 2; + p_regs->sw134.refer2_base = bwd_addr >> 2; + p_regs->sw135.refer3_base = bwd_addr >> 2; + } else { + if (picture->picture_structure == 3 || + (picture->picture_structure == 1 + && picture->top_field_first) + || (picture->picture_structure == 2 + && !picture->top_field_first)) { + p_regs->sw131.refer0_base = fwd_addr >> 2; + p_regs->sw148.refer1_base = fwd_addr >> 2; + } else if (picture->picture_structure == 1) { + p_regs->sw131.refer0_base = fwd_addr >> 2; + p_regs->sw148.refer1_base = cur_addr >> 2; + } else if (picture->picture_structure == 2) { + p_regs->sw131.refer0_base = cur_addr >> 2; + p_regs->sw148.refer1_base = fwd_addr >> 2; + } + p_regs->sw134.refer2_base = cur_addr >> 2; + p_regs->sw135.refer3_base = cur_addr >> 2; + } + + return 0; +} diff --git a/drivers/staging/rockchip-mpp/vdpu2/regs.h b/drivers/staging/rockchip-mpp/vdpu2/regs.h new file mode 100644 index 000000000000..65e114320bcf --- /dev/null +++ b/drivers/staging/rockchip-mpp/vdpu2/regs.h @@ -0,0 +1,670 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd + * Randy Li, + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _VDPU2_REGS_H_ +#define _VDPU2_REGS_H_ + +#define RKVDPU2_REG_SYS_CTRL 0x0d4 +#define RKVDPU2_REG_SYS_CTRL_INDEX (53) +#define RKVDPU2_GET_FORMAT(x) ((x) & 0xf) +#define RKVDPU2_FMT_H264D 0 +#define RKVDPU2_FMT_MPEG4D 1 +#define RKVDPU2_FMT_H263D 2 +#define RKVDPU2_FMT_JPEGD 3 +#define RKVDPU2_FMT_VC1D 4 +#define RKVDPU2_FMT_MPEG2D 5 +#define RKVDPU2_FMT_MPEG1D 6 +#define RKVDPU2_FMT_VP6D 7 +#define RKVDPU2_FMT_RESERVED 8 +#define RKVDPU2_FMT_VP7D 9 +#define RKVDPU2_FMT_VP8D 10 +#define RKVDPU2_FMT_AVSD 11 + +#define RKVDPU2_REG_DIR_MV_BASE 0x0f8 +#define RKVDPU2_REG_DIR_MV_BASE_INDEX (62) + +#define RKVDPU2_REG_STREAM_RLC_BASE 0x100 +#define RKVDPU2_REG_STREAM_RLC_BASE_INDEX (64) + +struct vdpu2_regs { + /* Post processor */ + u32 sw00_49[50]; + + struct { + u32 tiled_mode_msb:1; + u32 dec_latency:6; + u32 dec_fixed_quant:1; + u32 filtering_dis:1; + u32 skip_sel:1; + u32 dec_scmd_dis:1; + u32 dec_adv_pre_dis:1; + u32 tiled_mode_lsb:1; + u32 refbuf_thrd:12; + u32 refbuf_pid:5; + u32 reserved0:2; + } sw50; + + struct { + u32 stream_len:24; + u32 stream_len_ext:1; + u32 qp_init:6; + u32 reserved0:1; + } sw51; + + struct { + /* ydim_mbst */ + u32 startmb_y:8; + /* xdim_mbst */ + u32 startmb_x:9; + /* adv_pref_thrd */ + u32 apf_threshold:14; + u32 reserved0:1; + } sw52; + + struct { + u32 dec_mode:4; + u32 reserved0:28; + } sw53; + + struct { + u32 dec_in_endian:1; + u32 dec_out_endian:1; + u32 dec_in_wordsp:1; + u32 dec_out_wordsp:1; + u32 dec_strm_wordsp:1; + u32 dec_strendian_e:1; + u32 reserved0:26; + } sw54; + + struct { + u32 dec_irq:1; + u32 dec_irq_dis:1; + u32 reserved0:2; + u32 dec_rdy_sts:1; + u32 pp_bus_sts:1; + u32 buf_emt_sts:1; + u32 reserved1:1; + u32 aso_det_sts:1; + u32 slice_det_sts:1; + u32 bslice_det_sts:1; + u32 reserved2:1; + u32 error_det_sts:1; + u32 timeout_det_sts:1; + u32 reserved3:18; + } sw55; + + struct { + u32 dec_axi_rd_id:8; + u32 dec_axi_wr_id:8; + u32 dec_max_burst:5; + u32 bus_pos_sel:1; + u32 dec_data_disc_e:1; + u32 axi_sel:1; + u32 reserved0:8; + } sw56; + + struct { + u32 dec_e:1; + u32 refbuf2_buf_e:1; + u32 dec_out_dis:1; + u32 reserved2:1; + u32 dec_clk_gate_e:1; + u32 dec_timeout_e:1; + /* rd_cnt_tab_en */ + u32 picord_count_e:1; + u32 seq_mbaff_e:1; + u32 reftopfirst_e:1; + u32 ref_topfield_e:1; + u32 write_mvs_e:1; + u32 sorenson_e:1; + u32 fwd_interlace_e:1; + u32 pic_topfield_e:1; + /* sw_pic_type_sel0 */ + u32 pic_inter_e:1; + u32 pic_b_e:1; + u32 pic_fieldmode_e:1; + u32 pic_interlace_e:1; + u32 pjpeg_e:1; + u32 divx3_e:1; + u32 rlc_mode_e:1; + u32 ch_8pix_ileav_e:1; + u32 start_code_e:1; + u32 reserved1:2; + /* sw_init_dc_match0 ? */ + u32 inter_dblspeed:1; + u32 intra_dblspeed:1; + u32 intra_dbl3t:1; + u32 pref_sigchan:1; + u32 cache_en:1; + u32 reserved0:1; + /* dec_timeout_mode */ + u32 dec_timeout:1; + } sw57; + + struct { + u32 soft_rst:1; + u32 reserved0:31; + } sw58; + + struct { + u32 reserved0:2; + /* sw_pflt_set0_tap2 */ + u32 pred_bc_tap_0_2:10; + u32 pred_bc_tap_0_1:10; + /* pflt_set0_tap0 */ + u32 pred_bc_tap_0_0:10; + } sw59; + + struct { + u32 addit_ch_st_adr:32; + } sw60; + + struct { + u32 qtable_base:32; + } sw61; + + struct { + u32 dir_mv_base:32; + } sw62; + + struct { + /* dec_out_st_adr */ + u32 dec_out_base:32; + } sw63; + + struct { + u32 rlc_vlc_base:32; + } sw64; + + struct { + u32 refbuf_y_offset:9; + u32 reserve0:3; + u32 refbuf_fildpar_mode_e:1; + u32 refbuf_idcal_e:1; + u32 refbuf_picid:5; + u32 refbuf_thr_level:12; + u32 refbuf_e:1; + } sw65; + + u32 sw66; + u32 sw67; + + struct { + u32 refbuf_sum_bot:16; + u32 refbuf_sum_top:16; + } sw68; + + struct { + u32 luma_sum_intra:16; + u32 refbuf_sum_hit:16; + } sw69; + + struct { + u32 ycomp_mv_sum:22; + u32 reserve0:10; + } sw70; + + u32 sw71; + u32 sw72; + u32 sw73; + + struct { + u32 init_reflist_pf4:5; + u32 init_reflist_pf5:5; + u32 init_reflist_pf6:5; + u32 init_reflist_pf7:5; + u32 init_reflist_pf8:5; + u32 init_reflist_pf9:5; + u32 reserved0:2; + } sw74; + + struct { + u32 init_reflist_pf10:5; + u32 init_reflist_pf11:5; + u32 init_reflist_pf12:5; + u32 init_reflist_pf13:5; + u32 init_reflist_pf14:5; + u32 init_reflist_pf15:5; + u32 reserved0:2; + } sw75; + + struct { + u32 num_ref_idx0:16; + u32 num_ref_idx1:16; + } sw76; + + struct { + u32 num_ref_idx2:16; + u32 num_ref_idx3:16; + } sw77; + + struct { + u32 num_ref_idx4:16; + u32 num_ref_idx5:16; + } sw78; + + struct { + u32 num_ref_idx6:16; + u32 num_ref_idx7:16; + } sw79; + + struct { + u32 num_ref_idx8:16; + u32 num_ref_idx9:16; + } sw80; + + struct { + u32 num_ref_idx10:16; + u32 num_ref_idx11:16; + } sw81; + + struct { + u32 num_ref_idx12:16; + u32 num_ref_idx13:16; + } sw82; + + struct { + u32 num_ref_idx14:16; + u32 num_ref_idx15:16; + } sw83; + + /* Used by H.264 */ + union { + u32 ref0_st_addr; + struct { + u32 ref0_closer_sel:1; + u32 ref0_field_en:1; + u32 reserved0:30; + }; + } sw84; + + union { + u32 ref1_st_addr; + struct { + u32 ref1_closer_sel:1; + u32 ref1_field_en:1; + u32 reserved0:30; + }; + } sw85; + + union { + u32 ref2_st_addr; + struct { + u32 ref2_closer_sel:1; + u32 ref2_field_en:1; + u32 reserved0:30; + }; + } sw86; + + union { + u32 ref3_st_addr; + struct { + u32 ref3_closer_sel:1; + u32 ref3_field_en:1; + u32 reserved0:30; + }; + } sw87; + + union { + u32 ref4_st_addr; + struct { + u32 ref4_closer_sel:1; + u32 ref4_field_en:1; + u32 reserved0:30; + }; + } sw88; + + union { + u32 ref5_st_addr; + struct { + u32 ref5_closer_sel:1; + u32 ref5_field_en:1; + u32 reserved0:30; + }; + } sw89; + + union { + u32 ref6_st_addr; + struct { + u32 ref6_closer_sel:1; + u32 ref6_field_en:1; + u32 reserved0:30; + }; + } sw90; + + union { + u32 ref7_st_addr; + struct { + u32 ref7_closer_sel:1; + u32 ref7_field_en:1; + u32 reserved0:30; + }; + } sw91; + + union { + u32 ref8_st_addr; + struct { + u32 ref8_closer_sel:1; + u32 ref8_field_en:1; + u32 reserved0:30; + }; + } sw92; + + union { + u32 ref9_st_addr; + struct { + u32 ref9_closer_sel:1; + u32 ref9_field_en:1; + u32 reserved0:30; + }; + } sw93; + + union { + u32 ref10_st_addr; + struct { + u32 ref10_closer_sel:1; + u32 ref10_field_en:1; + u32 reserved0:30; + }; + } sw94; + + union { + u32 ref11_st_addr; + struct { + u32 ref11_closer_sel:1; + u32 ref11_field_en:1; + u32 reserved0:30; + }; + } sw95; + + union { + u32 ref12_st_addr; + struct { + u32 ref12_closer_sel:1; + u32 ref12_field_en:1; + u32 reserved0:30; + }; + } sw96; + + union { + u32 ref13_st_addr; + struct { + u32 ref13_closer_sel:1; + u32 ref13_field_en:1; + u32 reserved0:30; + }; + } sw97; + + union { + u32 ref14_st_addr; + struct { + u32 ref14_closer_sel:1; + u32 ref14_field_en:1; + u32 reserved0:30; + }; + } sw98; + + /* Used by H.264 */ + union { + u32 ref15_st_addr; + struct { + u32 ref15_closer_sel:1; + u32 ref15_field_en:1; + u32 reserved0:30; + }; + } sw99; + + struct { + u32 init_reflist_df0:5; + u32 init_reflist_df1:5; + u32 init_reflist_df2:5; + u32 init_reflist_df3:5; + u32 init_reflist_df4:5; + u32 init_reflist_df5:5; + u32 reserved0:2; + } sw100; + + struct { + u32 init_reflist_df6:5; + u32 init_reflist_df7:5; + u32 init_reflist_df8:5; + u32 init_reflist_df9:5; + u32 init_reflist_df10:5; + u32 init_reflist_df11:5; + u32 reserved0:2; + } sw101; + + struct { + u32 init_reflist_df12:5; + u32 init_reflist_df13:5; + u32 init_reflist_df14:5; + u32 init_reflist_df15:5; + u32 reserved0:12; + } sw102; + + struct { + u32 init_reflist_db0:5; + u32 init_reflist_db1:5; + u32 init_reflist_db2:5; + u32 init_reflist_db3:5; + u32 init_reflist_db4:5; + u32 init_reflist_db5:5; + u32 reserved0:2; + } sw103; + + struct { + u32 init_reflist_db6:5; + u32 init_reflist_db7:5; + u32 init_reflist_db8:5; + u32 init_reflist_db9:5; + u32 init_reflist_db10:5; + u32 init_reflist_db11:5; + u32 reserved0:2; + } sw104; + + struct { + u32 init_reflist_db12:5; + u32 init_reflist_db13:5; + u32 init_reflist_db14:5; + u32 init_reflist_db15:5; + u32 reserved0:12; + } sw105; + + struct { + u32 init_reflist_pf0:5; + u32 init_reflist_pf1:5; + u32 init_reflist_pf2:5; + u32 init_reflist_pf3:5; + u32 reserved0:12; + } sw106; + + struct { + u32 refpic_term_flag:32; + } sw107; + + struct { + u32 refpic_valid_flag:32; + } sw108; + + struct { + u32 strm_start_bit:6; + u32 reserved0:26; + } sw109; + + struct { + u32 pic_mb_w:9; + u32 pic_mb_h:8; + u32 flt_offset_cb_qp:5; + u32 flt_offset_cr_qp:5; + u32 reserved0:5; + } sw110; + + struct { + u32 max_refnum:5; + u32 reserved0:11; + u32 wp_bslice_sel:2; + u32 reserved1:14; + } sw111; + + struct { + u32 curfrm_num:16; + u32 cur_frm_len:5; + u32 reserved0:9; + u32 rpcp_flag:1; + u32 dblk_ctrl_flag:1; + } sw112; + + struct { + u32 idr_pic_id:16; + u32 refpic_mk_len:11; + u32 reserved0:5; + } sw113; + + struct { + u32 poc_field_len:8; + u32 reserved0:6; + u32 max_refidx0:5; + u32 max_refidx1:5; + u32 pps_id:5; + } sw114; + + struct { + u32 fieldpic_flag_exist:1; + u32 scl_matrix_en:1; + u32 tranf_8x8_flag_en:1; + u32 const_intra_en:1; + u32 weight_pred_en:1; + u32 cabac_en:1; + u32 monochr_en:1; + u32 dlmv_method_en:1; + u32 idr_pic_flag:1; + u32 reserved0:23; + } sw115; + + /* Not used */ + u32 sw116_119[4]; + + union { + struct { + u32 pic_refer_flag:1; + u32 reserved0:10; + } avs; + + struct { + u32 pic_mb_w_ext:3; + u32 pic_mb_h_ext:3; + u32 reserved0:1; + u32 mb_height_off:4; + } vc1; + + struct { + u32 ref_frames:5; + u32 reserved0:6; + } h264; + + struct { + u32 ref_frames:5; + u32 topfieldfirst_e:1; + u32 alt_scan_e:1; + u32 reserved0:4; + } mpeg; + + struct { + u32 pad:11; + u32 pic_mb_height_p:8; + /* this register is only used by VC-1 */ + u32 mb_width_off:4; + u32 pic_mb_width:9; + }; + } sw120 __attribute__ ((packed)); + + u32 sw121; + + struct { + u32 frame_pred_dct:1; + u32 intra_vlc_tab:1; + u32 intra_dc_prec:1; + u32 con_mv_e:1; + u32 reserved0:19; + u32 qscale_type:1; + u32 reserved1:1; + u32 strm_start_bit:6; + } sw122; + + u32 sw123; + u32 sw124; + u32 sw125; + u32 sw126; + u32 sw127; + u32 sw128; + u32 sw129; + u32 sw130; + + struct { + u32 refer0_topc_e:1; + u32 refer0_field_e:1; + u32 refer0_base:30; + } sw131; + + u32 sw132; + u32 sw133; + + struct { + u32 refer2_topc_e:1; + u32 refer2_field_e:1; + u32 refer2_base:30; + } sw134; + + struct { + u32 refer3_topc_e:1; + u32 refer3_field_e:1; + u32 refer3_base:30; + } sw135; + + struct { + u32 reserved0:1; + u32 mv_accuracy_bwd:1; + u32 mv_accuracy_fwd:1; + u32 fcode_bwd_ver:4; + u32 fcode_bwd_hor:4; + u32 fcode_fwd_ver:4; + u32 fcode_fwd_hor:4; + u32 alt_scan_flag_e:1; + u32 reserved1:12; + } sw136; + + u32 sw137; + u32 sw138; + u32 sw139; + u32 sw140; + u32 sw141; + u32 sw142; + u32 sw143; + u32 sw144; + u32 sw145; + u32 sw146; + u32 sw147; + + struct { + u32 refer1_topc_e:1; + u32 refer1_field_e:1; + u32 refer1_base:30; + } sw148; + + u32 sw149_sw158[10]; +} __attribute__((packed)); + +#endif diff --git a/include/uapi/video/rk_vpu_service.h b/include/uapi/video/rk_vpu_service.h new file mode 100644 index 000000000000..b75e03c391c7 --- /dev/null +++ b/include/uapi/video/rk_vpu_service.h @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2015 Fuzhou Rockchip Electronics Co., Ltd + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __UAPI_LINUX_RK_VPU_SERVICE_H__ +#define __UAPI_LINUX_RK_VPU_SERVICE_H__ + +#include +#include + +/* + * Ioctl definitions + */ + +/* Use 'l' as magic number */ +#define VPU_IOC_MAGIC 'l' + +#define VPU_IOC_SET_CLIENT_TYPE _IOW(VPU_IOC_MAGIC, 1, __u32) +#define VPU_IOC_GET_HW_FUSE_STATUS _IOW(VPU_IOC_MAGIC, 2, unsigned long) + +#define VPU_IOC_SET_REG _IOW(VPU_IOC_MAGIC, 3, unsigned long) +#define VPU_IOC_GET_REG _IOW(VPU_IOC_MAGIC, 4, unsigned long) + +#define VPU_IOC_PROBE_IOMMU_STATUS _IOR(VPU_IOC_MAGIC, 5, __u32) +#define VPU_IOC_SET_DRIVER_DATA _IOW(VPU_IOC_MAGIC, 64, u32) + +struct vpu_request { + __u32 *req; + __u32 size; +}; + +/* Hardware decoder configuration description */ +struct vpu_dec_config { + /* Maximum video decoding width supported */ + __u32 max_dec_pic_width; + /* Maximum output width of Post-Processor */ + __u32 max_pp_out_pic_width; + /* HW supports h.264 */ + __u32 h264_support; + /* HW supports JPEG */ + __u32 jpeg_support; + /* HW supports MPEG-4 */ + __u32 mpeg4_support; + /* HW supports custom MPEG-4 features */ + __u32 custom_mpeg4_support; + /* HW supports VC-1 Simple */ + __u32 vc1_support; + /* HW supports MPEG-2 */ + __u32 mpeg2_support; + /* HW supports post-processor */ + __u32 pp_support; + /* HW post-processor functions bitmask */ + __u32 pp_config; + /* HW supports Sorenson Spark */ + __u32 sorenson_support; + /* HW supports reference picture buffering */ + __u32 ref_buf_support; + /* HW supports VP6 */ + __u32 vp6_support; + /* HW supports VP7 */ + __u32 vp7_support; + /* HW supports VP8 */ + __u32 vp8_support; + /* HW supports AVS */ + __u32 avs_support; + /* HW supports JPEG extensions */ + __u32 jpeg_ext_support; + __u32 reserve; + /* HW supports H264 MVC extension */ + __u32 mvc_support; +}; + +/* Hardware encoder configuration description */ +struct vpu_enc_config { + /* Maximum supported width for video encoding (not JPEG) */ + __u32 max_encoded_width; + /* HW supports H.264 */ + __u32 h264_enabled; + /* HW supports JPEG */ + __u32 jpeg_enabled; + /* HW supports MPEG-4 */ + __u32 mpeg4_enabled; + /* HW supports video stabilization */ + __u32 vs_enabled; + /* HW supports RGB input */ + __u32 rgb_enabled; + __u32 reg_size; + __u32 reserv[2]; +}; + +#endif From patchwork Wed Apr 10 12:42:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: ayaka X-Patchwork-Id: 10893813 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2EE9217EF for ; Wed, 10 Apr 2019 12:42:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1026828908 for ; Wed, 10 Apr 2019 12:42:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0394F26B39; Wed, 10 Apr 2019 12:42:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 96E2028908 for ; Wed, 10 Apr 2019 12:42:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.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=SOpuGIuBSyVldA69le8UHyladBxf6fkwXzIjV10AeBE=; b=QKGoazkMsxxulv D9cA2RZfQdtASoBghxbHUCvt9SovUYSaDjMZzpvGV205kZDYZDTll4LBSqbAYjnurXyPWbNEKeExf Oq/I6EFyJfDpkgifwl6gRF95ob57X5gaFx5EMoBnWpwUmsmesfv0PtY1d0WWhB4HL25BNgDDY45Xw 4YYcy3nqEc4FFxx4i7bStl3PLQPK/abDk9agVU2+q/HYu3mGgsXrsntHfzovjgcPHbXoDiOnlCpqp 54xzqsuP2rJkAv1/N3mMJ0/wd65lM8qK/mkH4/9RXUGuFyWquX6fQ03jJdguhgccS4jqPdc1drlEw eZcqg7f1K+25V50EdGyw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hECZ5-0002eg-Bu; Wed, 10 Apr 2019 12:42:55 +0000 Received: from kozue.soulik.info ([2001:19f0:7000:8404:5054:ff:fe75:428f]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hECYz-0002d7-4B for linux-rockchip@lists.infradead.org; Wed, 10 Apr 2019 12:42:53 +0000 Received: from misaki.sumomo.pri (unknown [IPv6:2001:470:b30d:2:c604:15ff:0:401]) by kozue.soulik.info (Postfix) with ESMTPA id 4E2481014EA; Wed, 10 Apr 2019 21:43:36 +0900 (JST) From: ayaka To: linux-media@vger.kernel.org Subject: [PATCH v3 2/9] rockchip: mpp: rkvdec: rbsp Date: Wed, 10 Apr 2019 20:42:19 +0800 Message-Id: <20190410124226.8612-3-ayaka@soulik.info> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190410124226.8612-1-ayaka@soulik.info> References: <20190410124226.8612-1-ayaka@soulik.info> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190410_054249_842319_F012BEA3 X-CRM114-Status: GOOD ( 11.44 ) X-BeenThere: linux-rockchip@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Upstream kernel work for Rockchip platforms List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: paul.kocialkowski@bootlin.com, maxime.ripard@bootlin.com, joro@8bytes.org, Randy Li , jernej.skrabec@gmail.com, nicolas@ndufresne.ca, hverkuil@xs4all.nl, linux-rockchip@lists.infradead.org, thomas.petazzoni@bootlin.com, groeck@chromium.org, mchehab@kernel.org, ezequiel@collabora.com, posciak@chromium.org Sender: "Linux-rockchip" Errors-To: linux-rockchip-bounces+patchwork-linux-rockchip=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Randy Li It is a bit writer. Signed-off-by: Randy Li --- drivers/staging/rockchip-mpp/rkvdec/rbsp.c | 96 ++++++++++++++++++++++ drivers/staging/rockchip-mpp/rkvdec/rbsp.h | 30 +++++++ 2 files changed, 126 insertions(+) create mode 100644 drivers/staging/rockchip-mpp/rkvdec/rbsp.c create mode 100644 drivers/staging/rockchip-mpp/rkvdec/rbsp.h diff --git a/drivers/staging/rockchip-mpp/rkvdec/rbsp.c b/drivers/staging/rockchip-mpp/rkvdec/rbsp.c new file mode 100644 index 000000000000..3fbc50e9bca1 --- /dev/null +++ b/drivers/staging/rockchip-mpp/rkvdec/rbsp.c @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2012 Vista Silicon S.L. + * Copyright (C) 2019 Randy Li + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include + +#include "rbsp.h" + +int rbsp_init(struct rbsp *rbsp, void *buf, int size, int bit_pos) +{ + if (!buf) + return -EINVAL; + if (DIV_ROUND_UP(bit_pos, 32) >= size) + return -EINVAL; + + rbsp->buf = buf; + rbsp->size = size >> 2; + rbsp->pos = bit_pos; + + return 0; +} + +static inline int rbsp_read_bit(struct rbsp *rbsp) +{ + int shift = rbsp->pos % 32; + int ofs = rbsp->pos++ / 32; + + if (ofs >= rbsp->size) + return -EINVAL; + + return (rbsp->buf[ofs] >> shift) & 1; +} + +static inline int rbsp_write_bit(struct rbsp *rbsp, int bit) +{ + int shift = rbsp->pos % 32; + int ofs = rbsp->pos++ / 32; + + if (ofs >= rbsp->size) + return -EINVAL; + + rbsp->buf[ofs] &= ~(1 << shift); + rbsp->buf[ofs] |= bit << shift; + + return 0; +} + +int rbsp_write_bits(struct rbsp *rbsp, int num, int value) +{ + int shift = rbsp->pos % 32; + int ofs = rbsp->pos / 32; + + if (ofs >= rbsp->size) + return -EINVAL; + + if (num + shift >= 32) { + u32 lbits = 32 - shift; + u32 hbits = num + shift - 32; + + rbsp->buf[ofs] &= ~(((1 << lbits) - 1) << shift); + rbsp->buf[ofs] |= value << shift; + + value >>= (32 - shift); + rbsp->buf[ofs + 1] &= ~(((1 << hbits) - 1)); + rbsp->buf[ofs + 1] |= value; + } else { + rbsp->buf[ofs] &= ~(((1 << num) - 1) << shift); + rbsp->buf[ofs] |= value << shift; + } + + rbsp->pos += num; + + return 0; +} + +int rbsp_write_flag(struct rbsp *rbsp, int value) +{ + if (value) + return rbsp_write_bit(rbsp, BIT(0)); + else + return rbsp_write_bit(rbsp, 0); +} diff --git a/drivers/staging/rockchip-mpp/rkvdec/rbsp.h b/drivers/staging/rockchip-mpp/rkvdec/rbsp.h new file mode 100644 index 000000000000..d87c582bfd41 --- /dev/null +++ b/drivers/staging/rockchip-mpp/rkvdec/rbsp.h @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2012 Vista Silicon S.L. + * Copyright (C) 2019 Randy Li + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _RBSP_H_ +#define _RBSP_H_ + +struct rbsp { + u32 *buf; + int size; + int pos; +}; + +int rbsp_init(struct rbsp *rbsp, void *buf, int size, int bit_pos); +int rbsp_write_flag(struct rbsp *rbsp, int bit); +int rbsp_write_bits(struct rbsp *rbsp, int num, int value); + +#endif From patchwork Wed Apr 10 12:42:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: ayaka X-Patchwork-Id: 10893819 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C73871390 for ; Wed, 10 Apr 2019 12:43:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A7C14289B6 for ; Wed, 10 Apr 2019 12:43:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9C3BF289D7; Wed, 10 Apr 2019 12:43:04 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id E8E0526B39 for ; Wed, 10 Apr 2019 12:43:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.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=UeLa7zUTFLRzJgaWf0L8I8xObUniOGEBSo8QAzYn+DM=; b=Z4XZiHuyQZilrm RiUWHafBg5SzVsAWwL82hR5pSUpA6aXwgOP5mOzWR0KTcW2ShcHsnCbvJulw5LsOlQ1FNhVOkXwck +f16vXfIUThxd367xdWAmyZV4VUQM+5tZee8yDRi5r0U5BNyi6fiwCRxlaIy/Y9aR9DEmm3pqY9VA ed7Vw4N5wkl8k+UThU+9Bhse1m4NZapGCcmGpMtMDUQQBdfmYUSboDq4LoAoAQZro/Xe3D7bfQlx/ nZ94Mkd85kGuRkFNxds4Ra9X0uDvQMDk90xLR/0Y5LXjZDneOuOr9ITawCSHiRh1w48M1SkriesUz 06uaCYx4KdbFydSX6EGQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hECZB-0002j0-BR; Wed, 10 Apr 2019 12:43:01 +0000 Received: from kozue.soulik.info ([108.61.200.231]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hECZ7-0002fJ-Pn for linux-rockchip@lists.infradead.org; Wed, 10 Apr 2019 12:42:59 +0000 Received: from misaki.sumomo.pri (unknown [IPv6:2001:470:b30d:2:c604:15ff:0:401]) by kozue.soulik.info (Postfix) with ESMTPA id C4F861014EF; Wed, 10 Apr 2019 21:43:38 +0900 (JST) From: ayaka To: linux-media@vger.kernel.org Subject: [PATCH v3 3/9] [WIP]: rockchip: mpp: HEVC decoder ctrl data Date: Wed, 10 Apr 2019 20:42:20 +0800 Message-Id: <20190410124226.8612-4-ayaka@soulik.info> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190410124226.8612-1-ayaka@soulik.info> References: <20190410124226.8612-1-ayaka@soulik.info> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190410_054258_045281_4B63838D X-CRM114-Status: GOOD ( 14.75 ) X-BeenThere: linux-rockchip@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Upstream kernel work for Rockchip platforms List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: paul.kocialkowski@bootlin.com, maxime.ripard@bootlin.com, joro@8bytes.org, Randy Li , jernej.skrabec@gmail.com, nicolas@ndufresne.ca, hverkuil@xs4all.nl, linux-rockchip@lists.infradead.org, thomas.petazzoni@bootlin.com, groeck@chromium.org, mchehab@kernel.org, ezequiel@collabora.com, posciak@chromium.org Sender: "Linux-rockchip" Errors-To: linux-rockchip-bounces+patchwork-linux-rockchip=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Randy Li Not done yet, not enough data. Signed-off-by: Randy Li --- drivers/staging/rockchip-mpp/Makefile | 4 +- .../staging/rockchip-mpp/rkvdec/hevc-data.c | 208 ++++++++++++++++++ .../staging/rockchip-mpp/rkvdec/hevc-data.h | 27 +++ drivers/staging/rockchip-mpp/rkvdec/hevc.c | 2 + 4 files changed, 240 insertions(+), 1 deletion(-) create mode 100644 drivers/staging/rockchip-mpp/rkvdec/hevc-data.c create mode 100644 drivers/staging/rockchip-mpp/rkvdec/hevc-data.h diff --git a/drivers/staging/rockchip-mpp/Makefile b/drivers/staging/rockchip-mpp/Makefile index 9722b0059563..8da33fa5142d 100644 --- a/drivers/staging/rockchip-mpp/Makefile +++ b/drivers/staging/rockchip-mpp/Makefile @@ -1,7 +1,9 @@ # SPDX-License-Identifier: GPL-2.0 rk-mpp-service-objs := mpp_service.o rk-mpp-device-objs := mpp_dev_common.o -rk-mpp-vdec-objs := mpp_dev_rkvdec.o rkvdec/hevc.o rkvdec/avc.o +rk-mpp-vdec-objs := mpp_dev_rkvdec.o +rk-mpp-vdec-objs += rkvdec/avc.o +rk-mpp-vdec-objs += rkvdec/hevc.o rkvdec/hevc-data.o rkvdec/rbsp.o rk-mpp-vdpu2-objs := mpp_dev_vdpu2.o vdpu2/mpeg2.o obj-$(CONFIG_ROCKCHIP_MPP_SERVICE) += rk-mpp-service.o diff --git a/drivers/staging/rockchip-mpp/rkvdec/hevc-data.c b/drivers/staging/rockchip-mpp/rkvdec/hevc-data.c new file mode 100644 index 000000000000..26694a2f46c5 --- /dev/null +++ b/drivers/staging/rockchip-mpp/rkvdec/hevc-data.c @@ -0,0 +1,208 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2019 Randy Li, + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "hevc-data.h" + +/* 7.3.2.2.1 General sequence parameter set RBSP syntax */ +int rkvdec_hevc_write_sps(struct rbsp *rbsp, + const struct v4l2_ctrl_hevc_sps *sps) +{ + /* TODO: sps_video_parameter_set_id */ + rbsp_write_bits(rbsp, 4, 0); + /* TODO: sps_seq_parameter_set_id */ + rbsp_write_bits(rbsp, 4, 0); + /* chroma_format_idc */ + rbsp_write_bits(rbsp, 2, sps->chroma_format_idc); + rbsp_write_bits(rbsp, 13, sps->pic_width_in_luma_samples); + rbsp_write_bits(rbsp, 13, sps->pic_height_in_luma_samples); + /* bit_depth_luma */ + rbsp_write_bits(rbsp, 4, sps->bit_depth_luma_minus8 + 8); + rbsp_write_bits(rbsp, 4, sps->bit_depth_chroma_minus8 + 8); + /* log2_max_pic_order_cnt_lsb */ + rbsp_write_bits(rbsp, 5, sps->log2_max_pic_order_cnt_lsb_minus4 + 4); + /* FIXME it is 3 bits in document */ + rbsp_write_bits(rbsp, 2, sps->log2_diff_max_min_luma_coding_block_size); + /* log2_min_luma_coding_block_size */ + rbsp_write_bits(rbsp, 3, + sps->log2_min_luma_coding_block_size_minus3 + 3); + /* log2_min_transform_block_size */ + rbsp_write_bits(rbsp, 3, + sps->log2_min_luma_transform_block_size_minus2 + 2); + rbsp_write_bits(rbsp, 2, + sps->log2_diff_max_min_luma_transform_block_size); + rbsp_write_bits(rbsp, 3, sps->max_transform_hierarchy_depth_inter); + rbsp_write_bits(rbsp, 3, sps->max_transform_hierarchy_depth_intra); + + rbsp_write_flag(rbsp, sps->scaling_list_enabled_flag); + rbsp_write_flag(rbsp, sps->amp_enabled_flag); + rbsp_write_flag(rbsp, sps->sample_adaptive_offset_enabled_flag); + rbsp_write_flag(rbsp, sps->pcm_enabled_flag); + + /* pcm_sample_bit_depth_luma */ + rbsp_write_bits(rbsp, 4, sps->pcm_sample_bit_depth_luma_minus1 + 1); + /* pcm_sample_bit_depth_chroma */ + rbsp_write_bits(rbsp, 4, sps->pcm_sample_bit_depth_chroma_minus1 + 1); + rbsp_write_flag(rbsp, sps->pcm_loop_filter_disabled_flag); + + rbsp_write_bits(rbsp, 3, + sps->log2_diff_max_min_pcm_luma_coding_block_size); + /* log2_min_pcm_luma_coding_block_size */ + rbsp_write_bits(rbsp, 3, + sps->log2_min_pcm_luma_coding_block_size_minus3 + 3); + rbsp_write_bits(rbsp, 7, sps->num_short_term_ref_pic_sets); + rbsp_write_flag(rbsp, sps->long_term_ref_pics_present_flag); + rbsp_write_bits(rbsp, 6, sps->num_long_term_ref_pics_sps); + rbsp_write_flag(rbsp, sps->sps_temporal_mvp_enabled_flag); + rbsp_write_flag(rbsp, sps->strong_intra_smoothing_enabled_flag); + /* Above is 100 bits total */ +#if 0 + /* transform_skip_rotation_enabled_flag to intra_smoothing_disabled_flag */ + rbsp_write_bits(rbsp, 7, 0); + /* sps_max_dec_pic_buffering_minus1 */ + rbsp_write_bits(rbsp, 4, sps->sps_max_dec_pic_buffering_minus1); + rbsp_write_flag(rbsp, sps->separate_colour_plane_flag); + /* TODO: high_precision_offsets_enabled */ + rbsp_write_flag(rbsp, 0); + /* TODO: persistent_rice_adaptation_enabled_flag */ + rbsp_write_flag(rbsp, 0); + /* reserved */ + rbsp_write_bits(rbsp, 14, 0xffffffff); +#else + rbsp_write_bits(rbsp, 7, 0); + /* padding */ + rbsp_write_bits(rbsp, 21, 0xffffffff); +#endif + + return 0; +} + +int rkvdec_hevc_write_pps(struct rbsp *rbsp, + const struct v4l2_ctrl_hevc_sps *sps, + const struct v4l2_ctrl_hevc_pps *pps, + const struct v4l2_ctrl_hevc_slice_params *slice_params) +{ + + u32 min_cb_log2_size_y, ctb_log2_size_y, log2_min_cu_qp_delta_size; + u16 column_width[20] = { 0, }; + u16 row_height[22] = { 0, }; + u8 i; + + min_cb_log2_size_y = sps->log2_min_luma_coding_block_size_minus3 + 3; + ctb_log2_size_y = min_cb_log2_size_y + + sps->log2_diff_max_min_luma_coding_block_size; + + log2_min_cu_qp_delta_size = ctb_log2_size_y - pps->diff_cu_qp_delta_depth; + + /* pps_pic_parameter_set_id */ + rbsp_write_bits(rbsp, 6, 0); + /* pps_seq_parameter_set_id */ + rbsp_write_bits(rbsp, 4, 0); + /* dependent_slice_segments_enabled_flag */ + rbsp_write_flag(rbsp, pps->dependent_slice_segment_flag); + rbsp_write_flag(rbsp, pps->output_flag_present_flag); + /* FIXME it is 3 bits in document */ + rbsp_write_bits(rbsp, 13, pps->num_extra_slice_header_bits); + /* sign_data_hiding_flag */ + rbsp_write_flag(rbsp, pps->sign_data_hiding_enabled_flag); + rbsp_write_flag(rbsp, pps->cabac_init_present_flag); + /* FIXME: from slice params ? */ + rbsp_write_bits(rbsp, 4, slice_params->num_ref_idx_l0_active_minus1 + 1); + rbsp_write_bits(rbsp, 4, slice_params->num_ref_idx_l1_active_minus1 + 1); + /* FIXME it is 6 bits in document init_qp_minus26 */ + rbsp_write_bits(rbsp, 7, pps->init_qp_minus26); + rbsp_write_flag(rbsp, pps->constrained_intra_pred_flag); + rbsp_write_flag(rbsp, pps->transform_skip_enabled_flag); + rbsp_write_flag(rbsp, pps->cu_qp_delta_enabled_flag); + /* Log2MinCuQpDeltaSize */ + rbsp_write_bits(rbsp, 3, log2_min_cu_qp_delta_size); + rbsp_write_bits(rbsp, 5, pps->pps_cb_qp_offset); + rbsp_write_bits(rbsp, 5, pps->pps_cr_qp_offset); + rbsp_write_flag(rbsp, pps->pps_slice_chroma_qp_offsets_present_flag); + rbsp_write_flag(rbsp, pps->weighted_pred_flag); + rbsp_write_flag(rbsp, pps->weighted_bipred_flag); + rbsp_write_flag(rbsp, pps->transquant_bypass_enabled_flag); + rbsp_write_flag(rbsp, pps->tiles_enabled_flag); + rbsp_write_flag(rbsp, pps->entropy_coding_sync_enabled_flag); + rbsp_write_flag(rbsp, pps->pps_loop_filter_across_slices_enabled_flag); + rbsp_write_flag(rbsp, pps->loop_filter_across_tiles_enabled_flag); + rbsp_write_flag(rbsp, pps->deblocking_filter_override_enabled_flag); + /* pps_deblocking_filter_disabled_flag */ + rbsp_write_flag(rbsp, pps->pps_disable_deblocking_filter_flag); + rbsp_write_bits(rbsp, 4, pps->pps_beta_offset_div2); + rbsp_write_bits(rbsp, 4, pps->pps_tc_offset_div2); + rbsp_write_flag(rbsp, pps->lists_modification_present_flag); + rbsp_write_bits(rbsp, 3, pps->log2_parallel_merge_level_minus2 + 2); + rbsp_write_flag(rbsp, pps->slice_segment_header_extension_present_flag); + /* reserved, log2_transform_skip_max_size_minus2 */ + rbsp_write_bits(rbsp, 3, 0); + /* num_tile_columns */ + rbsp_write_bits(rbsp, 5, pps->num_tile_columns_minus1 + 1); + /* num_tile_rows */ + rbsp_write_bits(rbsp, 5, pps->num_tile_rows_minus1 + 1); + /* ? */ + rbsp_write_bits(rbsp, 3, 2); + /* align 30 ? */ + rbsp_write_bits(rbsp, 32, 0xffffffff); + + /* TODO: support tile video */ + column_width[0] = 0; + row_height[0] = 0; + + for (i = 0; i < 20; i++) { + if (column_width[i]) + column_width[i]--; + rbsp_write_bits(rbsp, column_width[i], 8); + } + for (i = 0; i < 22; i++) { + if (row_height[i]) + row_height[i]--; + rbsp_write_bits(rbsp, row_height[i], 8); + } + + /* TODO: scaleing_address */ + + return 0; +} + +int rkvdec_hevc_write_soft_rps(struct rbsp *rbsp, + const struct v4l2_ctrl_hevc_slice_params *slice_params) +{ + int i; + + for (i = 0; i < 15; i++) { + /* FIXME: is long term */ + rbsp_write_flag(rbsp, 0); + rbsp_write_bits(rbsp, 4, slice_params->ref_idx_l0[i]); + } + + for (i = 0; i < 15; i++) { + /* FIXME: is long term */ + rbsp_write_flag(rbsp, 0); + rbsp_write_bits(rbsp, 4, slice_params->ref_idx_l1[i]); + } + /* TODO: lowdelay_flag */ + rbsp_write_flag(rbsp, 1); + + /* TODO: Rps_bit_offset_include_lt */ + rbsp_write_bits(rbsp, 10, 0); + rbsp_write_bits(rbsp, 9, 0); +} + +/* 7.3.7 Short-term reference picture set syntax */ +int rkvdec_hevc_write_rps(struct rbsp *rbsp, + const struct v4l2_ctrl_hevc_pps *pps) +{ + +} diff --git a/drivers/staging/rockchip-mpp/rkvdec/hevc-data.h b/drivers/staging/rockchip-mpp/rkvdec/hevc-data.h new file mode 100644 index 000000000000..6b94cd41d377 --- /dev/null +++ b/drivers/staging/rockchip-mpp/rkvdec/hevc-data.h @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2019 Randy Li, + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include + +#include +#include + +#include "rbsp.h" + +int rkvdec_hevc_write_sps(struct rbsp *rbsp, + const struct v4l2_ctrl_hevc_sps *sps); + +int rkvdec_hevc_write_rps(struct rbsp *rbsp, + const struct v4l2_ctrl_hevc_pps *pps); diff --git a/drivers/staging/rockchip-mpp/rkvdec/hevc.c b/drivers/staging/rockchip-mpp/rkvdec/hevc.c index 78f150000128..6f74ce45533a 100644 --- a/drivers/staging/rockchip-mpp/rkvdec/hevc.c +++ b/drivers/staging/rockchip-mpp/rkvdec/hevc.c @@ -25,6 +25,8 @@ #include "hal.h" #include "regs.h" +#include "hevc-data.h" + static void init_hw_cfg(struct rkvdec_regs *p_regs) { p_regs->sw_interrupt.dec_e = 1; From patchwork Wed Apr 10 12:42:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: ayaka X-Patchwork-Id: 10893825 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 70A1717EF for ; Wed, 10 Apr 2019 12:43:07 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5342426B39 for ; Wed, 10 Apr 2019 12:43:07 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 46825289B6; Wed, 10 Apr 2019 12:43:07 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 2562126B39 for ; Wed, 10 Apr 2019 12:43:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.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=Jt+QMUgI3VEBnC66shmI5rll/BowDyj3AOJLB98veXA=; b=BbbWPD5XX2GMqf ejqeJu4CfrRGXFCTu1pA8BhxkpZGxYqlU86Sr3vu/2BaC6Ooml/VY48rQSDQazDE5f2AOgOuhc5U7 ll7CK4z8EThdMC5mrBzDA3752dpNyTRwjjBlkfnStDFPLs3J9p1y5BrT4QzKd9Gj/UKS/qudYcbJd K7EHWAb+nNbWWLvEnsPwA8+Vj8nD3rDAWyBHv9nRup0S9oIYrvZtVIRfvsMQ/ZCDsq2QM1tGqJTeL CdMSnbQucxd9BzBf6ROX8bHKNBbtctQs/f04TiL9TMJYvwOQVAmdwBMBPH9cooFgcCcWPHKrjdGwb 3MOzfdfjzWaKLu8rsPJA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hECZD-0002kv-Tl; Wed, 10 Apr 2019 12:43:03 +0000 Received: from kozue.soulik.info ([2001:19f0:7000:8404:5054:ff:fe75:428f]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hECZ8-0002hW-SB for linux-rockchip@lists.infradead.org; Wed, 10 Apr 2019 12:43:01 +0000 Received: from misaki.sumomo.pri (unknown [IPv6:2001:470:b30d:2:c604:15ff:0:401]) by kozue.soulik.info (Postfix) with ESMTPA id 4C5791014EC; Wed, 10 Apr 2019 21:43:46 +0900 (JST) From: ayaka To: linux-media@vger.kernel.org Subject: [PATCH v3 4/9] [WIP]: rockchip: mpp: H.264 decoder ctrl data Date: Wed, 10 Apr 2019 20:42:21 +0800 Message-Id: <20190410124226.8612-5-ayaka@soulik.info> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190410124226.8612-1-ayaka@soulik.info> References: <20190410124226.8612-1-ayaka@soulik.info> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190410_054259_117753_45BB8247 X-CRM114-Status: GOOD ( 18.96 ) X-BeenThere: linux-rockchip@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Upstream kernel work for Rockchip platforms List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: paul.kocialkowski@bootlin.com, maxime.ripard@bootlin.com, joro@8bytes.org, ayaka , randy.li@rock-chips.com, jernej.skrabec@gmail.com, nicolas@ndufresne.ca, hverkuil@xs4all.nl, linux-rockchip@lists.infradead.org, thomas.petazzoni@bootlin.com, groeck@chromium.org, mchehab@kernel.org, ezequiel@collabora.com, posciak@chromium.org Sender: "Linux-rockchip" Errors-To: linux-rockchip-bounces+patchwork-linux-rockchip=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP I really don't want to do this. Signed-off-by: Randy Li Signed-off-by: ayaka --- drivers/staging/rockchip-mpp/Makefile | 2 +- drivers/staging/rockchip-mpp/mpp_dev_rkvdec.c | 8 +- .../staging/rockchip-mpp/rkvdec/avc-data.c | 239 ++++++++++++++++++ .../staging/rockchip-mpp/rkvdec/avc-data.h | 40 +++ drivers/staging/rockchip-mpp/rkvdec/avc.c | 71 +++++- drivers/staging/rockchip-mpp/vdpu2/avc.c | 165 ++++++++++++ 6 files changed, 514 insertions(+), 11 deletions(-) create mode 100644 drivers/staging/rockchip-mpp/rkvdec/avc-data.c create mode 100644 drivers/staging/rockchip-mpp/rkvdec/avc-data.h create mode 100644 drivers/staging/rockchip-mpp/vdpu2/avc.c diff --git a/drivers/staging/rockchip-mpp/Makefile b/drivers/staging/rockchip-mpp/Makefile index 8da33fa5142d..e2c2bf297812 100644 --- a/drivers/staging/rockchip-mpp/Makefile +++ b/drivers/staging/rockchip-mpp/Makefile @@ -2,7 +2,7 @@ rk-mpp-service-objs := mpp_service.o rk-mpp-device-objs := mpp_dev_common.o rk-mpp-vdec-objs := mpp_dev_rkvdec.o -rk-mpp-vdec-objs += rkvdec/avc.o +rk-mpp-vdec-objs += rkvdec/avc.o rkvdec/avc-data.o rk-mpp-vdec-objs += rkvdec/hevc.o rkvdec/hevc-data.o rkvdec/rbsp.o rk-mpp-vdpu2-objs := mpp_dev_vdpu2.o vdpu2/mpeg2.o diff --git a/drivers/staging/rockchip-mpp/mpp_dev_rkvdec.c b/drivers/staging/rockchip-mpp/mpp_dev_rkvdec.c index 756821dbf829..97abfdfc344f 100644 --- a/drivers/staging/rockchip-mpp/mpp_dev_rkvdec.c +++ b/drivers/staging/rockchip-mpp/mpp_dev_rkvdec.c @@ -284,13 +284,15 @@ static int rkvdec_s_fmt_vid_cap_mplane(struct file *filp, void *priv, pix_mp->plane_fmt[1].bytesperline * ALIGN(pix_mp->height, 8); #else - /* TODO: HEVC only request the height is aligned with 8 */ + /* + * TODO: H.264 would use 16 alignment while the resolution is under HD, + * HEVC only request the height is aligned with 8 + */ pix_mp->plane_fmt[0].sizeimage = pix_mp->plane_fmt[0].bytesperline * ALIGN(pix_mp->height, - 16); + 8); /* Additional space for motion vector */ pix_mp->plane_fmt[0].sizeimage *= 2; - pix_mp->plane_fmt[0].sizeimage += SZ_4M; pix_mp->plane_fmt[1].sizeimage = SZ_2M; #endif pix_mp->num_planes = 2; diff --git a/drivers/staging/rockchip-mpp/rkvdec/avc-data.c b/drivers/staging/rockchip-mpp/rkvdec/avc-data.c new file mode 100644 index 000000000000..57172528f988 --- /dev/null +++ b/drivers/staging/rockchip-mpp/rkvdec/avc-data.c @@ -0,0 +1,239 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2019 Randy Li, + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "avc-data.h" + +static const u32 zig_zag_4x4[16] = { + 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15 +}; + +static const u32 zig_zag_8x8[64] = { + 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63 +}; + +static void fill_is_long_term(struct rbsp *rbsp, const struct v4l2_ctrl_h264_decode_param + *decode_param) +{ + u16 is_long_term = 0; + u8 i; + + for (i = 0; i < 16; i++) + if (decode_param->dpb[i]. + flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) + is_long_term |= (1 << i); + + rbsp_write_bits(rbsp, 16, is_long_term); +} + +/* in zig-zag order */ +void rkvdec_avc_update_scaling_list(u8 * buf, const struct + v4l2_ctrl_h264_scaling_matrix + *scaling) +{ + u8 i, j; + + for (i = 0; i < 6; i++) + for (j = 0; j < 16; j++) + buf[zig_zag_4x4[j] + (i << 4)] = + scaling->scaling_list_4x4[i][j]; + + for (i = 0; i < 2; i++) + for (j = 0; j < 64; j++) + buf[zig_zag_8x8[j] + (i << 6)] = + scaling->scaling_list_8x8[i][j]; +} + +int rkvdec_avc_write_sps(struct rbsp *rbsp, + const struct v4l2_ctrl_h264_sps *sps) +{ + /* TODO: seq_parameter_set_id */ + rbsp_write_bits(rbsp, 4, 0); + rbsp_write_bits(rbsp, 8, sps->profile_idc); + /* constraint_set3_flag */ + rbsp_write_flag(rbsp, sps->constraint_set_flags >> 3); + rbsp_write_bits(rbsp, 2, sps->chroma_format_idc); + /* bit_depth_luma Not used */ + rbsp_write_bits(rbsp, 3, sps->bit_depth_luma_minus8); + /* bit_depth_chroma Not used */ + rbsp_write_bits(rbsp, 3, sps->bit_depth_chroma_minus8); + /* TODO: qpprime_y_zero_transform_bypass_flag */ + rbsp_write_flag(rbsp, 0); + rbsp_write_bits(rbsp, 4, sps->log2_max_frame_num_minus4); + rbsp_write_bits(rbsp, 5, sps->max_num_ref_frames); + rbsp_write_bits(rbsp, 2, sps->pic_order_cnt_type); + rbsp_write_bits(rbsp, 4, sps->log2_max_pic_order_cnt_lsb_minus4); + /* delta_pic_order_always_zero_flag */ + rbsp_write_flag(rbsp, + sps->flags & + V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO); + rbsp_write_bits(rbsp, 9, sps->pic_width_in_mbs_minus1 + 1); + /* TODO: check whether it work for field coding */ + rbsp_write_bits(rbsp, 9, sps->pic_height_in_map_units_minus1 + 1); + rbsp_write_flag(rbsp, sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY); + rbsp_write_flag(rbsp, sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD); + rbsp_write_flag(rbsp, + sps->flags & V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE); + + /* TODO: mvc */ + rbsp_write_flag(rbsp, 0); + /* num_views_minus1 */ + rbsp_write_bits(rbsp, 2, 0); + /* view_id[0] */ + rbsp_write_bits(rbsp, 10, 0); + /* view_id[1] */ + rbsp_write_bits(rbsp, 10, 0); + /* num_anchor_refs_l0 */ + rbsp_write_flag(rbsp, 0); + /* anchor_ref_l0 */ + rbsp_write_bits(rbsp, 10, 0); + rbsp_write_flag(rbsp, 0); + rbsp_write_bits(rbsp, 10, 0); + /* num_non_anchor_refs_l0 */ + rbsp_write_flag(rbsp, 0); + rbsp_write_bits(rbsp, 10, 0); + rbsp_write_flag(rbsp, 0); + rbsp_write_bits(rbsp, 10, 0); + /* Align with 128 bit */ + rbsp_write_bits(rbsp, 2, 0); + + return 0; +} + +int rkvdec_avc_write_pps(struct rbsp *rbsp, + const struct v4l2_ctrl_h264_pps *pps) +{ + /* TODO: pps_pic_parameter_set_id */ + rbsp_write_bits(rbsp, 8, 0); + rbsp_write_bits(rbsp, 5, 0); + rbsp_write_flag(rbsp, + pps->flags & V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE); + rbsp_write_flag(rbsp, + pps->flags & + V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT); + rbsp_write_bits(rbsp, 5, pps->num_ref_idx_l0_default_active_minus1); + rbsp_write_bits(rbsp, 5, pps->num_ref_idx_l1_default_active_minus1); + rbsp_write_flag(rbsp, pps->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED); + rbsp_write_bits(rbsp, 2, pps->weighted_bipred_idc); + rbsp_write_bits(rbsp, 7, pps->pic_init_qp_minus26); + rbsp_write_bits(rbsp, 6, pps->pic_init_qs_minus26); + rbsp_write_bits(rbsp, 5, pps->chroma_qp_index_offset); + rbsp_write_flag(rbsp, + pps->flags & + V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT); + rbsp_write_flag(rbsp, + pps->flags & V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED); + rbsp_write_flag(rbsp, + pps->flags & + V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT); + rbsp_write_flag(rbsp, + pps->flags & V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE); + rbsp_write_bits(rbsp, 5, pps->second_chroma_qp_index_offset); + rbsp_write_flag(rbsp, + pps->flags & + V4L2_H264_PPS_FLAG_PIC_SCALING_MATRIX_PRESENT); + + return 0; +} + +int rkvdec_avc_write_pps_tail(struct rbsp *rbsp, dma_addr_t scaling_addr, const struct v4l2_ctrl_h264_decode_param + *decode_param) +{ + /* scaling list buffer */ + rbsp_write_bits(rbsp, 32, scaling_addr); + + /* DPB */ + fill_is_long_term(rbsp, decode_param); + + /* TODO: VOIdx, Layer id */ + rbsp_write_bits(rbsp, 16, 0); + + /* Align with 128 bit */ + rbsp_write_bits(rbsp, 8, 0); + + return 0; +} + +static inline void fill_rps_list(struct rbsp *rbsp, const struct v4l2_ctrl_h264_decode_param + *decode_param, const u8 * list) +{ + u8 i; + + for (i = 0; i < 32; i++) { + u8 idx, active_flag; + + idx = list[i]; + + active_flag = decode_param->dpb[idx].flags & + V4L2_H264_DPB_ENTRY_FLAG_ACTIVE; + if (!active_flag) { + rbsp_write_bits(rbsp, 7, 0); + } else { + rbsp_write_bits(rbsp, 5, idx | BIT(5)); + /* TODO: bottom flag */ + rbsp_write_flag(rbsp, 0); + /* TODO: view id */ + rbsp_write_flag(rbsp, 0); + } + } +} + +int rkvdec_avc_write_rps(struct rbsp *rbsp, + const struct v4l2_ctrl_h264_sps *sps, + const struct v4l2_ctrl_h264_slice_param *slice_param, + const struct v4l2_ctrl_h264_decode_param *decode_param) +{ + int max_frame_num = 1 << (sps->log2_max_frame_num_minus4 + 4); + u8 i; + + for (i = 0; i < 16; i++) { + u16 frame_num = decode_param->dpb[i].frame_num; + + rbsp_write_bits(rbsp, 16, frame_num > max_frame_num ? + frame_num - max_frame_num : frame_num); + } + + /* reserved */ + rbsp_write_bits(rbsp, 16, 0); + /* TODO: VoidX */ + rbsp_write_bits(rbsp, 16, 0); + + switch (slice_param->slice_type) { + case V4L2_H264_SLICE_TYPE_P: + fill_rps_list(rbsp, decode_param, slice_param->ref_pic_list0); + for (i = 0; i < 14; i++) + rbsp_write_bits(rbsp, 32, 0); + break; + case V4L2_H264_SLICE_TYPE_B: + for (i = 0; i < 7; i++) + rbsp_write_bits(rbsp, 32, 0); + fill_rps_list(rbsp, decode_param, slice_param->ref_pic_list0); + fill_rps_list(rbsp, decode_param, slice_param->ref_pic_list1); + break; + case V4L2_H264_SLICE_TYPE_I: + /* TODO: SVC */ + default: + for (i = 0; i < 21; i++) + rbsp_write_bits(rbsp, 32, 0); + break; + } + + rbsp_write_bits(rbsp, 32, 0); + rbsp_write_bits(rbsp, 32, 0); + + return 0; +} diff --git a/drivers/staging/rockchip-mpp/rkvdec/avc-data.h b/drivers/staging/rockchip-mpp/rkvdec/avc-data.h new file mode 100644 index 000000000000..38ad17273b8a --- /dev/null +++ b/drivers/staging/rockchip-mpp/rkvdec/avc-data.h @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2019 Randy Li, + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include + +#include +#include + +#include "rbsp.h" + +void rkvdec_avc_update_scaling_list(u8 * buf, const struct + v4l2_ctrl_h264_scaling_matrix + *scaling); + +int rkvdec_avc_write_sps(struct rbsp *rbsp, + const struct v4l2_ctrl_h264_sps *sps); + +int rkvdec_avc_write_pps(struct rbsp *rbsp, + const struct v4l2_ctrl_h264_pps *pps); + +int rkvdec_avc_write_pps_tail(struct rbsp *rbsp, dma_addr_t scaling_addr, + const struct v4l2_ctrl_h264_decode_param *decode_param); + +int rkvdec_avc_write_rps(struct rbsp *rbsp, + const struct v4l2_ctrl_h264_sps *sps, + const struct v4l2_ctrl_h264_slice_param *slice_param, + const struct v4l2_ctrl_h264_decode_param + *decode_param); diff --git a/drivers/staging/rockchip-mpp/rkvdec/avc.c b/drivers/staging/rockchip-mpp/rkvdec/avc.c index 3d91a119e533..1cb5b2208bfa 100644 --- a/drivers/staging/rockchip-mpp/rkvdec/avc.c +++ b/drivers/staging/rockchip-mpp/rkvdec/avc.c @@ -24,6 +24,56 @@ #include "mpp_dev_common.h" #include "hal.h" #include "regs.h" +#include "avc-data.h" + +static void generate_input_data(struct rkvdec_regs *p_regs, + struct vb2_v4l2_buffer *src_buf, + const struct v4l2_ctrl_h264_sps *sps, + const struct v4l2_ctrl_h264_pps *pps, + const struct v4l2_ctrl_h264_scaling_matrix + *scaling, const struct v4l2_ctrl_h264_slice_param + *slice_param, const struct v4l2_ctrl_h264_decode_param + *decode_param) +{ + struct rbsp rbsp = { 0, }; + size_t r_scaling_offs, r_sps_offs, r_rps_offs; + size_t stream_len = 0; + dma_addr_t scaling_addr = 0; + void *r_data = NULL; + int i; + + stream_len = slice_param->size + 64; + + r_data = vb2_plane_vaddr(&src_buf->vb2_buf, 0); + r_scaling_offs = ALIGN(stream_len, 16); + r_data += r_scaling_offs; + + if (pps->flags & V4L2_H264_PPS_FLAG_PIC_SCALING_MATRIX_PRESENT) { + rkvdec_avc_update_scaling_list(r_data, scaling); + r_sps_offs = r_scaling_offs + 6 * 16 + 2 * 64 + 128; + r_sps_offs = ALIGN(r_sps_offs, 16); + scaling_addr = p_regs->sw_strm_rlc_base + r_scaling_offs; + } else { + r_sps_offs = r_scaling_offs; + scaling_addr = 0; + } + + rbsp_init(&rbsp, r_data + r_sps_offs, SZ_2M - r_sps_offs, 0); + rkvdec_avc_write_sps(&rbsp, sps); + rkvdec_avc_write_pps(&rbsp, pps); + rkvdec_avc_write_pps_tail(&rbsp, scaling_addr, decode_param); + p_regs->sw_pps_base = p_regs->sw_strm_rlc_base + r_sps_offs; + + for (i = 1; i < 256; i++) + memset(r_data + r_sps_offs + i * 32, 0, 32); + + /* 256 bits */ + r_rps_offs = r_sps_offs + 32 * 256 + 128; + r_rps_offs = ALIGN(r_rps_offs, 16); + rbsp_init(&rbsp, r_data + r_rps_offs, SZ_2M - r_rps_offs, 0); + rkvdec_avc_write_rps(&rbsp, sps, slice_param, decode_param); + p_regs->sw_rps_base = p_regs->sw_strm_rlc_base + r_rps_offs; +} static void init_hw_cfg(struct rkvdec_regs *p_regs) { @@ -152,18 +202,23 @@ int rkvdec_avc_gen_reg(struct mpp_session *session, void *regs, { const struct v4l2_ctrl_h264_sps *sps; const struct v4l2_ctrl_h264_pps *pps; + const struct v4l2_ctrl_h264_scaling_matrix *scaling; const struct v4l2_ctrl_h264_slice_param *slice_param; const struct v4l2_ctrl_h264_decode_param *decode_param; struct vb2_v4l2_buffer *dst_buf; struct rkvdec_regs *p_regs = regs; - size_t stream_len = 0; sps = rockchip_mpp_get_cur_ctrl(session, V4L2_CID_MPEG_VIDEO_H264_SPS); pps = rockchip_mpp_get_cur_ctrl(session, V4L2_CID_MPEG_VIDEO_H264_PPS); - slice_param = rockchip_mpp_get_cur_ctrl(session, - V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS); - decode_param = rockchip_mpp_get_cur_ctrl(session, - V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS); + scaling = + rockchip_mpp_get_cur_ctrl(session, + V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS); + slice_param = + rockchip_mpp_get_cur_ctrl(session, + V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS); + decode_param = + rockchip_mpp_get_cur_ctrl(session, + V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS); if (!sps || !pps || !slice_param || !decode_param) return -EINVAL; @@ -178,12 +233,14 @@ int rkvdec_avc_gen_reg(struct mpp_session *session, void *regs, p_regs->sw_sysctrl.strm_start_bit = slice_param->header_bit_size; /* hardware wants a zerod memory at the stream end */ - stream_len = slice_param->size + 64; - p_regs->sw_stream_len = stream_len; + p_regs->sw_stream_len = slice_param->size + 64; dst_buf = v4l2_m2m_next_dst_buf(session->fh.m2m_ctx); rkvdec_avc_gen_ref(p_regs, dst_buf, decode_param); + generate_input_data(p_regs, src_buf, sps, pps, scaling, slice_param, + decode_param); + return 0; } diff --git a/drivers/staging/rockchip-mpp/vdpu2/avc.c b/drivers/staging/rockchip-mpp/vdpu2/avc.c new file mode 100644 index 000000000000..f77bb8ef810a --- /dev/null +++ b/drivers/staging/rockchip-mpp/vdpu2/avc.c @@ -0,0 +1,165 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2019 Randy Li, + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include + +#include +#include +#include +#include +#include + +#include "mpp_dev_common.h" +#include "hal.h" +#include "regs.h" + +#define DEC_LITTLE_ENDIAN (1) + +static const u8 zigzag[64] = { + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63 +}; + +static const u8 intra_default_q_matrix[64] = { + 8, 16, 19, 22, 26, 27, 29, 34, + 16, 16, 22, 24, 27, 29, 34, 37, + 19, 22, 26, 27, 29, 34, 34, 38, + 22, 22, 26, 27, 29, 34, 37, 40, + 22, 26, 27, 29, 32, 35, 40, 48, + 26, 27, 29, 32, 35, 40, 48, 58, + 26, 27, 29, 34, 38, 46, 56, 69, + 27, 29, 35, 38, 46, 56, 69, 83 +}; + +static void init_hw_cfg(struct vdpu2_regs *p_regs) +{ + p_regs->sw54.dec_strm_wordsp = 1; + p_regs->sw54.dec_strendian_e = DEC_LITTLE_ENDIAN; + p_regs->sw54.dec_in_wordsp = 1; + p_regs->sw54.dec_out_wordsp = 1; + p_regs->sw54.dec_in_endian = DEC_LITTLE_ENDIAN; //change + p_regs->sw54.dec_out_endian = DEC_LITTLE_ENDIAN; + p_regs->sw57.dec_timeout = 1; + p_regs->sw57.dec_timeout_e = 1; + + p_regs->sw57.dec_clk_gate_e = 1; + p_regs->sw57.pref_sigchan = 1; + p_regs->sw57.bus_pos_sel = 1; + p_regs->sw57.intra_dbl3t = 1; + p_regs->sw57.inter_dblspeed = 1; + p_regs->sw57.intra_dblspeed = 1; + + p_regs->sw50.tiled_mode_msb = 0; + p_regs->sw56.dec_max_burst = 16; + p_regs->sw50.dec_scmd_dis = 0; + p_regs->sw50.dec_adv_pre_dis = 0; + p_regs->sw52.apf_threshold = 8; + + p_regs->sw50.dec_latency = 0; + p_regs->sw56.dec_data_disc_e = 0; + + p_regs->sw55.dec_irq = 0; + p_regs->sw56.dec_axi_rd_id = 0; + p_regs->sw56.dec_axi_wr_id = 0; + + p_reg->sw59.pred_bc_tap_0_0 = 1; + /* -5 */ + p_reg->sw59.pred_bc_tap_0_1 = 0x3fb; + p_reg->sw59.pred_bc_tap_0_2 = 20; + + p_regs->sw53.dec_mode = RKVDPU2_FMT_H264D; +} + +int rkvdpu_mpeg2_gen_reg(struct mpp_session *session, void *regs, + struct vb2_v4l2_buffer *src_buf) +{ + const struct v4l2_ctrl_h264_sps *sps; + const struct v4l2_ctrl_h264_pps *pps; + const struct v4l2_ctrl_h264_scaling_matrix *scaling; + const struct v4l2_ctrl_h264_slice_param *slice_param; + const struct v4l2_ctrl_h264_decode_param *decode_param; + struct vb2_v4l2_buffer *dst_buf; + struct rkvdec_regs *p_regs = regs; + + sps = rockchip_mpp_get_cur_ctrl(session, V4L2_CID_MPEG_VIDEO_H264_SPS); + pps = rockchip_mpp_get_cur_ctrl(session, V4L2_CID_MPEG_VIDEO_H264_PPS); + scaling = + rockchip_mpp_get_cur_ctrl(session, + V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS); + slice_param = + rockchip_mpp_get_cur_ctrl(session, + V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS); + decode_param = + rockchip_mpp_get_cur_ctrl(session, + V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS); + + if (!sps || !pps || !slice_param || !decode_param) + return -EINVAL; + + init_hw_cfg(p_regs); + + p_regs->sw120.pic_mb_width = sps->pic_width_in_mbs_minus1 + 1; + p_regs->sw120.pic_mb_height_p = sps->pic_height_in_map_units_minus1 + 1; + +#if 0 + /* PICT_FRAME */ + if (picture->picture_structure == 3) { + p_regs->sw57.pic_fieldmode_e = 0; + } else { + p_regs->sw57.pic_fieldmode_e = 1; + /* PICT_TOP_FIEL */ + if (picture->picture_structure == 1) + p_regs->sw57.pic_topfield_e = 1; + } +#endif + p_regs->sw51.qp_init = pps->pic_init_qp_minus26 + 26; + p_regs->sw114.max_refidx0 = slice_params->num_ref_idx_l0_active_minus1 + 1; + p_regs->sw111.max_refnum = sps->num_ref_frames; + + p_regs->sw115.const_intra_en = pps->constrained_intra_pred_flag; + +#if 0 + p_regs->sw112.dblk_ctrl_flag = pp->deblocking_filter_control_present_flag; + p_regs->sw112.rpcp_flag = pp->redundant_pic_cnt_present_flag; + p_regs->sw113.refpic_mk_len = p_hal->slice_long[0].drpm_used_bitlen; + p_regs->sw115.idr_pic_flag = p_hal->slice_long[0].idr_flag; + p_regs->sw113.idr_pic_id = p_hal->slice_long[0].idr_pic_id; + p_regs->sw114.pps_id = p_hal->slice_long[0].active_pps_id; + p_regs->sw114.poc_field_len = p_hal->slice_long[0].poc_used_bitlen; +#endif + + p_regs->sw52.startmb_x = 0; + p_regs->sw52.startmb_y = 0; + p_regs->sw57.dec_out_dis = 0; + p_regs->sw50.filtering_dis = 1; + + p_regs->sw64.rlc_vlc_base = + vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0); + p_regs->sw122.strm_start_bit = params->data_bit_offset; + stream_len = vb2_get_plane_payload(&src_buf->vb2_buf, 0); + p_regs->sw51.stream_len = stream_len; + + qtable = vb2_plane_vaddr(&src_buf->vb2_buf, 0) + ALIGN(stream_len, 8); + p_regs->sw61.qtable_base = p_regs->sw64.rlc_vlc_base + + ALIGN(stream_len, 8); + + return 0; +} From patchwork Wed Apr 10 12:42:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: ayaka X-Patchwork-Id: 10893827 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 233F11390 for ; Wed, 10 Apr 2019 12:43:08 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0507726B39 for ; Wed, 10 Apr 2019 12:43:08 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id ED42B289B6; Wed, 10 Apr 2019 12:43:07 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 9603726B39 for ; Wed, 10 Apr 2019 12:43:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.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=EsIkxFDmbWsKvr+9jokqF/XCfIhNWuugrZqWYCNrl5Q=; b=rDse3A+/50iXel WKsF/iVuu03OGXdaBUx9joRoX3gLCUxNB2sdMTBkkpW37ennsQDdzdBvQUq7W7GMwd6Re6hiN8TI8 d4V15rhSUIpImjF1hq9qjfxy/Ndc/m31gfDgCM2PZaKh9qy9noAAJGYQc6GFyf2u8w987xOJwaaBa AsxFo21yvDYGPVycmpOuSOVN9KZI4hes+3bReRob8DnGPYfkayWfGBnI1urd/lz+xCtyJGDTQlY8F Lzqsks2gfOUv98UWa3VQOcSz9AbqKJXcPZA/nmyf6zDBdwfSEZNmeO9pQ/aa0w7qYj27w+PKYNO5L uz7a/fOtLrfhxrCDahOg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hECZF-0002mT-5B; Wed, 10 Apr 2019 12:43:05 +0000 Received: from kozue.soulik.info ([2001:19f0:7000:8404:5054:ff:fe75:428f]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hECZC-0002j5-21 for linux-rockchip@lists.infradead.org; Wed, 10 Apr 2019 12:43:03 +0000 Received: from misaki.sumomo.pri (unknown [IPv6:2001:470:b30d:2:c604:15ff:0:401]) by kozue.soulik.info (Postfix) with ESMTPA id A5EA21014ED; Wed, 10 Apr 2019 21:43:48 +0900 (JST) From: ayaka To: linux-media@vger.kernel.org Subject: [PATCH v3 5/9] [TEST]: rockchip: mpp: support qtable Date: Wed, 10 Apr 2019 20:42:22 +0800 Message-Id: <20190410124226.8612-6-ayaka@soulik.info> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190410124226.8612-1-ayaka@soulik.info> References: <20190410124226.8612-1-ayaka@soulik.info> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190410_054302_336319_D130E08E X-CRM114-Status: GOOD ( 10.86 ) X-BeenThere: linux-rockchip@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Upstream kernel work for Rockchip platforms List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: paul.kocialkowski@bootlin.com, maxime.ripard@bootlin.com, joro@8bytes.org, Randy Li , jernej.skrabec@gmail.com, nicolas@ndufresne.ca, hverkuil@xs4all.nl, linux-rockchip@lists.infradead.org, thomas.petazzoni@bootlin.com, groeck@chromium.org, mchehab@kernel.org, ezequiel@collabora.com, posciak@chromium.org Sender: "Linux-rockchip" Errors-To: linux-rockchip-bounces+patchwork-linux-rockchip=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Randy Li I don't care, I don't want to store buffers for a session. I just want to use it to verify the FFmpeg. --- drivers/staging/rockchip-mpp/mpp_dev_common.h | 3 +++ drivers/staging/rockchip-mpp/mpp_dev_vdpu2.c | 5 ++++- drivers/staging/rockchip-mpp/vdpu2/mpeg2.c | 13 ++++++++----- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/staging/rockchip-mpp/mpp_dev_common.h b/drivers/staging/rockchip-mpp/mpp_dev_common.h index 36770af53a95..33d7725be67b 100644 --- a/drivers/staging/rockchip-mpp/mpp_dev_common.h +++ b/drivers/staging/rockchip-mpp/mpp_dev_common.h @@ -100,6 +100,9 @@ struct mpp_session { struct v4l2_ctrl_handler ctrl_handler; /* TODO: FIXME: slower than helper function ? */ struct v4l2_ctrl **ctrls; + + dma_addr_t qtable_addr; + void *qtable_vaddr; }; /* The context for the a task */ diff --git a/drivers/staging/rockchip-mpp/mpp_dev_vdpu2.c b/drivers/staging/rockchip-mpp/mpp_dev_vdpu2.c index dbd9f334562e..1be73ab9c2be 100644 --- a/drivers/staging/rockchip-mpp/mpp_dev_vdpu2.c +++ b/drivers/staging/rockchip-mpp/mpp_dev_vdpu2.c @@ -246,6 +246,9 @@ static int rkvdpu_open(struct file *filp) if (IS_ERR_OR_NULL(session)) return PTR_ERR(session); + session->qtable_vaddr = dmam_alloc_coherent(mpp_dev->dev, 64 * 4, + &session->qtable_addr, + GFP_KERNEL); filp->private_data = &session->fh; pm_runtime_get_sync(mpp_dev->dev); @@ -529,7 +532,7 @@ static int rockchip_mpp_rkvdpu_probe(struct platform_device *pdev) ret = mpp_dev_register_node(mpp_dev, mpp_dev->variant->node_name, NULL, &rkvdpu_ioctl_ops); if (ret) - dev_err(dev, "register char device failed: %d\n", ret); + dev_err(dev, "register v4l2/media device failed: %d\n", ret); memcpy(mpp_dev->fmt_out, fmt_out_templ, sizeof(fmt_out_templ)); memcpy(mpp_dev->fmt_cap, fmt_cap_templ, sizeof(fmt_cap_templ)); diff --git a/drivers/staging/rockchip-mpp/vdpu2/mpeg2.c b/drivers/staging/rockchip-mpp/vdpu2/mpeg2.c index d32958c4cb20..837ee4a4a000 100644 --- a/drivers/staging/rockchip-mpp/vdpu2/mpeg2.c +++ b/drivers/staging/rockchip-mpp/vdpu2/mpeg2.c @@ -52,7 +52,7 @@ static const u8 intra_default_q_matrix[64] = { static void mpeg2_dec_copy_qtable(u8 * qtable, const struct v4l2_ctrl_mpeg2_quantization *ctrl) { - int i, n; + int i; if (!qtable || !ctrl) return; @@ -111,16 +111,12 @@ int rkvdpu_mpeg2_gen_reg(struct mpp_session *session, void *regs, struct vb2_v4l2_buffer *src_buf) { const struct v4l2_ctrl_mpeg2_slice_params *params; - const struct v4l2_ctrl_mpeg2_quantization *quantization; const struct v4l2_mpeg2_sequence *sequence; const struct v4l2_mpeg2_picture *picture; struct vdpu2_regs *p_regs = regs; params = rockchip_mpp_get_cur_ctrl(session, V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS); - quantization = rockchip_mpp_get_cur_ctrl(session, - V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION); - if (!params) return -EINVAL; @@ -211,6 +207,7 @@ int rkvdpu_mpeg2_prepare_buf(struct mpp_session *session, void *regs) { const struct v4l2_ctrl_mpeg2_slice_params *params; const struct v4l2_mpeg2_sequence *sequence; + const struct v4l2_ctrl_mpeg2_quantization *quantization; const struct v4l2_mpeg2_picture *picture; struct vb2_v4l2_buffer *dst_buf; dma_addr_t cur_addr, fwd_addr, bwd_addr; @@ -223,6 +220,9 @@ int rkvdpu_mpeg2_prepare_buf(struct mpp_session *session, void *regs) picture = ¶ms->picture; sequence = ¶ms->sequence; + quantization = rockchip_mpp_get_cur_ctrl(session, + V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION); + dst_buf = v4l2_m2m_next_dst_buf(session->fh.m2m_ctx); cur_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0); @@ -266,5 +266,8 @@ int rkvdpu_mpeg2_prepare_buf(struct mpp_session *session, void *regs) p_regs->sw135.refer3_base = cur_addr >> 2; } + mpeg2_dec_copy_qtable(session->qtable_vaddr, quantization); + p_regs->sw61.qtable_base = session->qtable_addr; + return 0; } From patchwork Wed Apr 10 12:42:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: ayaka X-Patchwork-Id: 10893831 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DF4FF1515 for ; Wed, 10 Apr 2019 12:43:11 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C0A3026B39 for ; Wed, 10 Apr 2019 12:43:11 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B4A1C289D7; Wed, 10 Apr 2019 12:43:11 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 526A926B39 for ; Wed, 10 Apr 2019 12:43:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.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=U0UP8HaS+oQILkwFDUEstqrNv7GiVZNwIHeCWWNx5/U=; b=H6bFlhfo5sczoq LiD9nMNpgOGJfs+lBakL56QtgcCBI7pmKyGP6O3iEXxgMGLk2TF1cYB2k5mAiezVihYhgKL09/HbS Hl1JDkB5cj2DQUAok/OSxu/jc78+wPmUHH8UPQJ7XajE5x2KdeTvbfbnQgVQHWrNnzEeP2uFjaAEz bUu5PkNsDgmLV3fOdNSaD9o9PFUd5DVrY5G7Fxm9F/C592l9cPg/qhIwRdB6M5cNwfy8Ru9D/JWXH t/mDlZucp3eZdxItVmGlSexi/jjgNROAcnC7GUBU4E5V5BGKT4c4CfW5DWg5Wrv8fyPfNNBSVjvlR 4YrmSlEsWJYIVBR5Bkww==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hECZI-0002qK-To; Wed, 10 Apr 2019 12:43:08 +0000 Received: from kozue.soulik.info ([108.61.200.231]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hECZE-0002kk-7H for linux-rockchip@lists.infradead.org; Wed, 10 Apr 2019 12:43:07 +0000 Received: from misaki.sumomo.pri (unknown [IPv6:2001:470:b30d:2:c604:15ff:0:401]) by kozue.soulik.info (Postfix) with ESMTPA id CB93F1014F0; Wed, 10 Apr 2019 21:43:51 +0900 (JST) From: ayaka To: linux-media@vger.kernel.org Subject: [PATCH v3 6/9] [TEST]: rockchip: mpp: vdpu2: move qtable to input buffer Date: Wed, 10 Apr 2019 20:42:23 +0800 Message-Id: <20190410124226.8612-7-ayaka@soulik.info> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190410124226.8612-1-ayaka@soulik.info> References: <20190410124226.8612-1-ayaka@soulik.info> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190410_054304_667699_63AB8DE8 X-CRM114-Status: GOOD ( 10.30 ) X-BeenThere: linux-rockchip@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Upstream kernel work for Rockchip platforms List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: paul.kocialkowski@bootlin.com, maxime.ripard@bootlin.com, joro@8bytes.org, Randy Li , jernej.skrabec@gmail.com, nicolas@ndufresne.ca, hverkuil@xs4all.nl, linux-rockchip@lists.infradead.org, thomas.petazzoni@bootlin.com, groeck@chromium.org, mchehab@kernel.org, ezequiel@collabora.com, posciak@chromium.org Sender: "Linux-rockchip" Errors-To: linux-rockchip-bounces+patchwork-linux-rockchip=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Randy Li I want the memory region !!! It can save more time if those data are prepared in userspace. Signed-off-by: Randy Li --- drivers/staging/rockchip-mpp/mpp_dev_common.c | 3 +-- drivers/staging/rockchip-mpp/mpp_dev_common.h | 3 --- drivers/staging/rockchip-mpp/mpp_dev_vdpu2.c | 3 +++ drivers/staging/rockchip-mpp/vdpu2/mpeg2.c | 20 +++++++++++-------- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/drivers/staging/rockchip-mpp/mpp_dev_common.c b/drivers/staging/rockchip-mpp/mpp_dev_common.c index 21816ad8a43b..97c4d897f168 100644 --- a/drivers/staging/rockchip-mpp/mpp_dev_common.c +++ b/drivers/staging/rockchip-mpp/mpp_dev_common.c @@ -1217,8 +1217,7 @@ static int rockchip_mpp_queue_init(void *priv, struct vb2_queue *src_vq, src_vq->io_modes = VB2_MMAP | VB2_DMABUF; src_vq->drv_priv = session; src_vq->mem_ops = &vb2_dma_contig_memops; - src_vq->dma_attrs = DMA_ATTR_ALLOC_SINGLE_PAGES | - DMA_ATTR_NO_KERNEL_MAPPING; + src_vq->dma_attrs = DMA_ATTR_ALLOC_SINGLE_PAGES; src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); src_vq->min_buffers_needed = 1; src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; diff --git a/drivers/staging/rockchip-mpp/mpp_dev_common.h b/drivers/staging/rockchip-mpp/mpp_dev_common.h index 33d7725be67b..36770af53a95 100644 --- a/drivers/staging/rockchip-mpp/mpp_dev_common.h +++ b/drivers/staging/rockchip-mpp/mpp_dev_common.h @@ -100,9 +100,6 @@ struct mpp_session { struct v4l2_ctrl_handler ctrl_handler; /* TODO: FIXME: slower than helper function ? */ struct v4l2_ctrl **ctrls; - - dma_addr_t qtable_addr; - void *qtable_vaddr; }; /* The context for the a task */ diff --git a/drivers/staging/rockchip-mpp/mpp_dev_vdpu2.c b/drivers/staging/rockchip-mpp/mpp_dev_vdpu2.c index 1be73ab9c2be..92d68b962fe1 100644 --- a/drivers/staging/rockchip-mpp/mpp_dev_vdpu2.c +++ b/drivers/staging/rockchip-mpp/mpp_dev_vdpu2.c @@ -176,6 +176,9 @@ static int rkvdpu_s_fmt_vid_out_mplane(struct file *filp, void *priv, if (sizes >= SZ_16M) return -EINVAL; + /* For those slice header data */ + pix_mp->plane_fmt[pix_mp->num_planes - 1].sizeimage += SZ_1M; + if (vdpu_setup_ctrls(session, pix_mp->pixelformat)) return -EINVAL; diff --git a/drivers/staging/rockchip-mpp/vdpu2/mpeg2.c b/drivers/staging/rockchip-mpp/vdpu2/mpeg2.c index 837ee4a4a000..c12d1a8ef2da 100644 --- a/drivers/staging/rockchip-mpp/vdpu2/mpeg2.c +++ b/drivers/staging/rockchip-mpp/vdpu2/mpeg2.c @@ -113,7 +113,10 @@ int rkvdpu_mpeg2_gen_reg(struct mpp_session *session, void *regs, const struct v4l2_ctrl_mpeg2_slice_params *params; const struct v4l2_mpeg2_sequence *sequence; const struct v4l2_mpeg2_picture *picture; + const struct v4l2_ctrl_mpeg2_quantization *quantization; struct vdpu2_regs *p_regs = regs; + void *qtable = NULL; + size_t stream_len = 0; params = rockchip_mpp_get_cur_ctrl(session, V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS); @@ -122,6 +125,8 @@ int rkvdpu_mpeg2_gen_reg(struct mpp_session *session, void *regs, sequence = ¶ms->sequence; picture = ¶ms->picture; + quantization = rockchip_mpp_get_cur_ctrl(session, + V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION); init_hw_cfg(p_regs); @@ -198,7 +203,13 @@ int rkvdpu_mpeg2_gen_reg(struct mpp_session *session, void *regs, p_regs->sw64.rlc_vlc_base = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0); p_regs->sw122.strm_start_bit = params->data_bit_offset; - p_regs->sw51.stream_len = vb2_get_plane_payload(&src_buf->vb2_buf, 0); + stream_len = vb2_get_plane_payload(&src_buf->vb2_buf, 0); + p_regs->sw51.stream_len = stream_len; + + qtable = vb2_plane_vaddr(&src_buf->vb2_buf, 0) + ALIGN(stream_len, 8); + mpeg2_dec_copy_qtable(qtable, quantization); + p_regs->sw61.qtable_base = p_regs->sw64.rlc_vlc_base + + ALIGN(stream_len, 8); return 0; } @@ -207,7 +218,6 @@ int rkvdpu_mpeg2_prepare_buf(struct mpp_session *session, void *regs) { const struct v4l2_ctrl_mpeg2_slice_params *params; const struct v4l2_mpeg2_sequence *sequence; - const struct v4l2_ctrl_mpeg2_quantization *quantization; const struct v4l2_mpeg2_picture *picture; struct vb2_v4l2_buffer *dst_buf; dma_addr_t cur_addr, fwd_addr, bwd_addr; @@ -220,9 +230,6 @@ int rkvdpu_mpeg2_prepare_buf(struct mpp_session *session, void *regs) picture = ¶ms->picture; sequence = ¶ms->sequence; - quantization = rockchip_mpp_get_cur_ctrl(session, - V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION); - dst_buf = v4l2_m2m_next_dst_buf(session->fh.m2m_ctx); cur_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0); @@ -266,8 +273,5 @@ int rkvdpu_mpeg2_prepare_buf(struct mpp_session *session, void *regs) p_regs->sw135.refer3_base = cur_addr >> 2; } - mpeg2_dec_copy_qtable(session->qtable_vaddr, quantization); - p_regs->sw61.qtable_base = session->qtable_addr; - return 0; } From patchwork Wed Apr 10 12:42:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: ayaka X-Patchwork-Id: 10893835 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D459517EF for ; Wed, 10 Apr 2019 12:43:12 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B71D1289B6 for ; Wed, 10 Apr 2019 12:43:12 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AB3F226B39; Wed, 10 Apr 2019 12:43:12 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 4A885289B6 for ; Wed, 10 Apr 2019 12:43:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.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=AkM6GsBNcsQd9TG3IAEs9O+KgNaIL5DGL6uMKjZN52E=; b=hii12LnmK7pCMB wy210Wlv8fb8EyNH+S5v6C0C1ZD4UGExtEPKJJi45KT/HH9H10nCfgfif4VqMvKXR8z2ZA8xMJFev VjYb+RyL0Nu/IOVktJ9qbNZ1jg/kJzA4xLQQu3OGp0qlLEgoPnY3/40F8IvczKWSfZBtJ+z1PEVJg ONxRHHexh4a0KpJ/hH9LuF8SWWVBGkyurLTgBQCN6tP3lfJ9dQ/f43qBIvhiR2ME49isZ0PUPdnIf riFzh+mjJ+CdXfeJf+jnmiyMwtAbvATgxMbJ0VgQ5WSr2tzmhQ/yDPuX/RBD05uBypWiYDvIns92f AjsfEunGXsZ1rWXLQkjw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hECZK-0002re-D8; Wed, 10 Apr 2019 12:43:10 +0000 Received: from kozue.soulik.info ([2001:19f0:7000:8404:5054:ff:fe75:428f]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hECZH-0002p8-W4 for linux-rockchip@lists.infradead.org; Wed, 10 Apr 2019 12:43:09 +0000 Received: from misaki.sumomo.pri (unknown [IPv6:2001:470:b30d:2:c604:15ff:0:401]) by kozue.soulik.info (Postfix) with ESMTPA id 086B81014F2; Wed, 10 Apr 2019 21:43:53 +0900 (JST) From: ayaka To: linux-media@vger.kernel.org Subject: [PATCH v3 7/9] [TEST]: rkvdec: spspps address alignment Date: Wed, 10 Apr 2019 20:42:24 +0800 Message-Id: <20190410124226.8612-8-ayaka@soulik.info> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190410124226.8612-1-ayaka@soulik.info> References: <20190410124226.8612-1-ayaka@soulik.info> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190410_054308_236754_8048041D X-CRM114-Status: UNSURE ( 9.68 ) X-CRM114-Notice: Please train this message. X-BeenThere: linux-rockchip@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Upstream kernel work for Rockchip platforms List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: paul.kocialkowski@bootlin.com, maxime.ripard@bootlin.com, joro@8bytes.org, ayaka , randy.li@rock-chips.com, jernej.skrabec@gmail.com, nicolas@ndufresne.ca, hverkuil@xs4all.nl, linux-rockchip@lists.infradead.org, thomas.petazzoni@bootlin.com, groeck@chromium.org, mchehab@kernel.org, ezequiel@collabora.com, posciak@chromium.org Sender: "Linux-rockchip" Errors-To: linux-rockchip-bounces+patchwork-linux-rockchip=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP I found the offset for cpu access is not equal to the DMA opeartion. Signed-off-by: ayaka --- drivers/staging/rockchip-mpp/mpp_dev_common.h | 3 +++ drivers/staging/rockchip-mpp/mpp_dev_rkvdec.c | 3 +++ drivers/staging/rockchip-mpp/rkvdec/avc.c | 14 +++++++------- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/staging/rockchip-mpp/mpp_dev_common.h b/drivers/staging/rockchip-mpp/mpp_dev_common.h index 36770af53a95..6718bcccde1f 100644 --- a/drivers/staging/rockchip-mpp/mpp_dev_common.h +++ b/drivers/staging/rockchip-mpp/mpp_dev_common.h @@ -100,6 +100,9 @@ struct mpp_session { struct v4l2_ctrl_handler ctrl_handler; /* TODO: FIXME: slower than helper function ? */ struct v4l2_ctrl **ctrls; + + void *aux_vaddr; + dma_addr_t aux_addr; }; /* The context for the a task */ diff --git a/drivers/staging/rockchip-mpp/mpp_dev_rkvdec.c b/drivers/staging/rockchip-mpp/mpp_dev_rkvdec.c index 97abfdfc344f..cc1fa9737bc1 100644 --- a/drivers/staging/rockchip-mpp/mpp_dev_rkvdec.c +++ b/drivers/staging/rockchip-mpp/mpp_dev_rkvdec.c @@ -382,6 +382,9 @@ static int rkvdec_open(struct file *filp) filp->private_data = &session->fh; pm_runtime_get_sync(mpp_dev->dev); + session->aux_vaddr = dmam_alloc_coherent(mpp_dev->dev, SZ_1M, + &session->aux_addr, GFP_KERNEL); + mpp_debug_leave(); return 0; } diff --git a/drivers/staging/rockchip-mpp/rkvdec/avc.c b/drivers/staging/rockchip-mpp/rkvdec/avc.c index 1cb5b2208bfa..8266a990dca6 100644 --- a/drivers/staging/rockchip-mpp/rkvdec/avc.c +++ b/drivers/staging/rockchip-mpp/rkvdec/avc.c @@ -26,8 +26,8 @@ #include "regs.h" #include "avc-data.h" -static void generate_input_data(struct rkvdec_regs *p_regs, - struct vb2_v4l2_buffer *src_buf, +static void generate_input_data(struct mpp_session *session, + struct rkvdec_regs *p_regs, const struct v4l2_ctrl_h264_sps *sps, const struct v4l2_ctrl_h264_pps *pps, const struct v4l2_ctrl_h264_scaling_matrix @@ -44,8 +44,8 @@ static void generate_input_data(struct rkvdec_regs *p_regs, stream_len = slice_param->size + 64; - r_data = vb2_plane_vaddr(&src_buf->vb2_buf, 0); - r_scaling_offs = ALIGN(stream_len, 16); + r_data = session->aux_vaddr; + r_scaling_offs = 0; r_data += r_scaling_offs; if (pps->flags & V4L2_H264_PPS_FLAG_PIC_SCALING_MATRIX_PRESENT) { @@ -62,7 +62,7 @@ static void generate_input_data(struct rkvdec_regs *p_regs, rkvdec_avc_write_sps(&rbsp, sps); rkvdec_avc_write_pps(&rbsp, pps); rkvdec_avc_write_pps_tail(&rbsp, scaling_addr, decode_param); - p_regs->sw_pps_base = p_regs->sw_strm_rlc_base + r_sps_offs; + p_regs->sw_pps_base = session->aux_addr + r_sps_offs; for (i = 1; i < 256; i++) memset(r_data + r_sps_offs + i * 32, 0, 32); @@ -72,7 +72,7 @@ static void generate_input_data(struct rkvdec_regs *p_regs, r_rps_offs = ALIGN(r_rps_offs, 16); rbsp_init(&rbsp, r_data + r_rps_offs, SZ_2M - r_rps_offs, 0); rkvdec_avc_write_rps(&rbsp, sps, slice_param, decode_param); - p_regs->sw_rps_base = p_regs->sw_strm_rlc_base + r_rps_offs; + p_regs->sw_rps_base = session->aux_addr + r_rps_offs; } static void init_hw_cfg(struct rkvdec_regs *p_regs) @@ -238,7 +238,7 @@ int rkvdec_avc_gen_reg(struct mpp_session *session, void *regs, dst_buf = v4l2_m2m_next_dst_buf(session->fh.m2m_ctx); rkvdec_avc_gen_ref(p_regs, dst_buf, decode_param); - generate_input_data(p_regs, src_buf, sps, pps, scaling, slice_param, + generate_input_data(session, p_regs, sps, pps, scaling, slice_param, decode_param); return 0; From patchwork Wed Apr 10 12:42:25 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: ayaka X-Patchwork-Id: 10893839 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 32CD81390 for ; Wed, 10 Apr 2019 12:43:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1623726B39 for ; Wed, 10 Apr 2019 12:43:18 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0A14E289D7; Wed, 10 Apr 2019 12:43:18 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id BC76526B39 for ; Wed, 10 Apr 2019 12:43:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.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=ZJHjFWWNSOl0+1FLS3oBX5FyalrrwY5IGQuKhFfLJus=; b=cHBS6tXSWaGCLu qnH9JrheZX5UWQXAes4IS7VPIFU3quvAUVCBJb4BpgthkN7ftONgu6mOdJ+NA2AMjM0XPVkrklGWw 4AcouE+42ZXzlzX9mHseuRMh3/wDzR+wZvh+PXOUqKCRbpUo14uEk+uY9M/26HQifMAtL+b8O4Ht/ Th8f1M9k+ionyxR+httq35XXNTqG1YIk4JKZs4ygi+iT/Z27x8r9UIjRhRQInIedsvrXaYAaevT06 v3C8SmhVxx0zGcUKC/MlUl1zFnB3H/tVWtN62OHgOH8rIsmTDPjcJhxfCb0weGWmR9evPQkaulSXx kEhYQg8QiyBnvK7ljVew==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hECZP-0002wC-5T; Wed, 10 Apr 2019 12:43:15 +0000 Received: from kozue.soulik.info ([108.61.200.231]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hECZL-0002s3-DU for linux-rockchip@lists.infradead.org; Wed, 10 Apr 2019 12:43:12 +0000 Received: from misaki.sumomo.pri (unknown [IPv6:2001:470:b30d:2:c604:15ff:0:401]) by kozue.soulik.info (Postfix) with ESMTPA id D233A1014F3; Wed, 10 Apr 2019 21:43:57 +0900 (JST) From: ayaka To: linux-media@vger.kernel.org Subject: [PATCH v3 8/9] arm64: dts: rockchip: boost clocks for rk3328 Date: Wed, 10 Apr 2019 20:42:25 +0800 Message-Id: <20190410124226.8612-9-ayaka@soulik.info> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190410124226.8612-1-ayaka@soulik.info> References: <20190410124226.8612-1-ayaka@soulik.info> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190410_054311_594046_78F870AF X-CRM114-Status: UNSURE ( 7.71 ) X-CRM114-Notice: Please train this message. X-BeenThere: linux-rockchip@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Upstream kernel work for Rockchip platforms List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: paul.kocialkowski@bootlin.com, maxime.ripard@bootlin.com, joro@8bytes.org, Randy Li , jernej.skrabec@gmail.com, nicolas@ndufresne.ca, hverkuil@xs4all.nl, linux-rockchip@lists.infradead.org, thomas.petazzoni@bootlin.com, groeck@chromium.org, mchehab@kernel.org, ezequiel@collabora.com, posciak@chromium.org Sender: "Linux-rockchip" Errors-To: linux-rockchip-bounces+patchwork-linux-rockchip=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Randy Li Or VOP won't work well. Signed-off-by: Randy Li --- arch/arm64/boot/dts/rockchip/rk3328.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi index 84f14b132e8f..55a72abed6e7 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi @@ -738,8 +738,8 @@ <0>, <24000000>, <24000000>, <24000000>, <15000000>, <15000000>, - <100000000>, <100000000>, - <100000000>, <100000000>, + <300000000>, <100000000>, + <400000000>, <100000000>, <50000000>, <100000000>, <100000000>, <100000000>, <50000000>, <50000000>, From patchwork Wed Apr 10 12:42:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: ayaka X-Patchwork-Id: 10893841 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9BBF81390 for ; Wed, 10 Apr 2019 12:43:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7D68126B39 for ; Wed, 10 Apr 2019 12:43:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 71A42289D7; Wed, 10 Apr 2019 12:43:20 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id F14D226B39 for ; Wed, 10 Apr 2019 12:43:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.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=Nm8+56ajbVp3dgYbhe4lvemauHLDHII9X0Bpeatnod8=; b=fgh+eIfx9VJPY9 kHsGkIQwljs8M02vQM3HJ8OeSawS4rXof2WbzkzyrojWrLuZRryUxOmlZvJcSKoX1efxTo3f6f+NA AGDf9DTW6KYWT8w/2ZAnsAYd5tOIFKJ1Xh6pQYGNJOga7tBpaCC6eSKCkF+OM7u8GfUFVydtdgyXD urY+1ZDiUhL8rgbbdBuMr9WrhFFoWGMuq1Y5gLYwPzBz73Pu6DJCmXhEqsgRV0tLOkgRPySl7N1Wn 3h2B7jSjHGkojuLbfnLykY2akImYb8xv88+LK01h9klxsg11Cr74LMXK6ZrCnkWQWdZHr4W4H/Zhq 1pnkYVbOslHspYxlHMkQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hECZR-0002z3-MQ; Wed, 10 Apr 2019 12:43:17 +0000 Received: from kozue.soulik.info ([2001:19f0:7000:8404:5054:ff:fe75:428f]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hECZN-0002um-QX for linux-rockchip@lists.infradead.org; Wed, 10 Apr 2019 12:43:16 +0000 Received: from misaki.sumomo.pri (unknown [IPv6:2001:470:b30d:2:c604:15ff:0:401]) by kozue.soulik.info (Postfix) with ESMTPA id 1500C1014F7; Wed, 10 Apr 2019 21:44:00 +0900 (JST) From: ayaka To: linux-media@vger.kernel.org Subject: [PATCH v3 9/9] arm64: dts: rockchip: add video codec for rk3328 Date: Wed, 10 Apr 2019 20:42:26 +0800 Message-Id: <20190410124226.8612-10-ayaka@soulik.info> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190410124226.8612-1-ayaka@soulik.info> References: <20190410124226.8612-1-ayaka@soulik.info> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190410_054314_124095_0BCF23D8 X-CRM114-Status: GOOD ( 10.50 ) X-BeenThere: linux-rockchip@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Upstream kernel work for Rockchip platforms List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: paul.kocialkowski@bootlin.com, maxime.ripard@bootlin.com, joro@8bytes.org, Randy Li , randy.li@rock-chips.com, jernej.skrabec@gmail.com, nicolas@ndufresne.ca, hverkuil@xs4all.nl, linux-rockchip@lists.infradead.org, thomas.petazzoni@bootlin.com, groeck@chromium.org, mchehab@kernel.org, ezequiel@collabora.com, posciak@chromium.org Sender: "Linux-rockchip" Errors-To: linux-rockchip-bounces+patchwork-linux-rockchip=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Randy Li Having problem with vepu2 The sclk_vdec_core for RKVDEC is in gpll at vendor kernel. Signed-off-by: Randy Li --- arch/arm64/boot/dts/rockchip/rk3328-evb.dts | 32 ++++++ .../arm64/boot/dts/rockchip/rk3328-rock64.dts | 32 ++++++ arch/arm64/boot/dts/rockchip/rk3328.dtsi | 108 +++++++++++++++++- 3 files changed, 170 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts index 8302d86d35c4..c89714f79f93 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts +++ b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts @@ -213,6 +213,18 @@ }; }; +&rkvdec { + status = "okay"; +}; + +&rkvdec_mmu { + status = "okay"; +}; + +&rkvdec_srv { + status = "okay"; +}; + &sdio { bus-width = <4>; cap-sd-highspeed; @@ -269,3 +281,23 @@ &usb_host0_ohci { status = "okay"; }; + +&vdpu { + status = "okay"; +}; + +&vop { + status = "okay"; +}; + +&vop_mmu { + status = "okay"; +}; + +&vpu_mmu { + status = "okay"; +}; + +&vpu_service{ + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts index 2157a528276b..520e444806cc 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts @@ -256,6 +256,14 @@ }; }; +&h265e { + status = "okay"; +}; + +&h265e_mmu { + status = "okay"; +}; + &i2s1 { status = "okay"; @@ -300,6 +308,18 @@ }; }; +&rkvdec { + status = "okay"; +}; + +&rkvdec_mmu { + status = "okay"; +}; + +&rkvdec_srv { + status = "okay"; +}; + &sdmmc { bus-width = <4>; cap-mmc-highspeed; @@ -370,6 +390,10 @@ status = "okay"; }; +&vdpu { + status = "okay"; +}; + &vop { status = "okay"; }; @@ -377,3 +401,11 @@ &vop_mmu { status = "okay"; }; + +&vpu_mmu { + status = "okay"; +}; + +&vpu_service{ + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi index 55a72abed6e7..9b3f8d22b60a 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi @@ -573,6 +573,27 @@ resets = <&cru SRST_GPU_A>; }; + venc_srv: venc-srv { + compatible = "rockchip,mpp-service"; + status = "disabled"; + }; + + h265e: h265e@ff330000 { + compatible = "rockchip,hevc-encoder-v1"; + reg = <0x0 0xff330000 0 0x200>; + interrupts = ; + clocks = <&cru ACLK_H265>, <&cru PCLK_H265>, + <&cru SCLK_VENC_CORE>, <&cru SCLK_VENC_DSP>, + <&cru ACLK_RKVENC>, <&cru ACLK_AXISRAM>; + clock-names = "aclk_h265", "pclk_h265", "clk_core", + "clk_dsp", "aclk_venc", "aclk_axi2sram"; + iommus = <&h265e_mmu>; + rockchip,srv = <&venc_srv>; + syscon = <&grf 0x040c 0x8000800 0x80000>; + power-domains = <&power RK3328_PD_HEVC>; + status = "disabled"; + }; + h265e_mmu: iommu@ff330200 { compatible = "rockchip,iommu"; reg = <0x0 0xff330200 0 0x100>; @@ -584,6 +605,25 @@ status = "disabled"; }; + vepu: vepu@ff340000 { + compatible = "rockchip,vpu-encoder-v2"; + reg = <0x0 0xff340000 0x0 0x400>; + interrupts = ; + clocks = <&cru ACLK_H264>, <&cru HCLK_H264>, + <&cru SCLK_VENC_CORE>; + clock-names = "aclk_vcodec", "hclk_vcodec", + "clk_core"; + resets = <&cru SRST_RKVENC_H264_A>, + <&cru SRST_RKVENC_H264_H>; + reset-names = "video_a", "video_h"; + iommus = <&vepu_mmu>; + rockchip,srv = <&venc_srv>; + syscon = <&grf 0x040c 0x8000800 0x80000>; + power-domains = <&power RK3328_PD_HEVC>; + status = "disabled"; + }; + + vepu_mmu: iommu@ff340800 { compatible = "rockchip,iommu"; reg = <0x0 0xff340800 0x0 0x40>; @@ -595,6 +635,42 @@ status = "disabled"; }; + + vpu_service: vdpu-srv { + compatible = "rockchip,mpp-service"; + status = "disabled"; + }; + + vdpu: vpu-decoder@ff350000 { + compatible = "rockchip,vpu-decoder-v2"; + reg = <0x0 0xff350400 0x0 0x400>; + interrupts = ; + interrupt-names = "irq_dec"; + resets = <&cru SRST_VCODEC_A>, <&cru SRST_VCODEC_H>; + reset-names = "video_a", "video_h"; + clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>; + clock-names = "aclk_vcodec", "hclk_vcodec"; + iommus = <&vpu_mmu>; + power-domains = <&power RK3328_PD_VPU>; + rockchip,srv = <&vpu_service>; + status = "disabled"; + }; + + avsd: avs-decoder@ff351000 { + compatible = "rockchip,avs-decoder-v1"; + reg = <0x0 0xff351000 0x0 0x200>; + interrupts = ; + interrupt-names = "irq_dec"; + clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>; + clock-names = "aclk_vcodec", "hclk_vcodec"; + resets = <&cru SRST_VCODEC_A>, <&cru SRST_VCODEC_H>; + reset-names = "video_a", "video_h"; + power-domains = <&power RK3328_PD_VPU>; + iommus = <&vpu_mmu>; + rockchip,srv = <&vpu_service>; + status = "disabled"; + }; + vpu_mmu: iommu@ff350800 { compatible = "rockchip,iommu"; reg = <0x0 0xff350800 0x0 0x40>; @@ -606,6 +682,34 @@ status = "disabled"; }; + rkvdec_srv: rkvdec-srv { + compatible = "rockchip,mpp-service"; + status = "disabled"; + }; + + rkvdec: rkvdec@ff36000 { + compatible = "rockchip,video-decoder-v1"; + reg = <0x0 0xff360000 0x0 0x400>; + interrupts = ; + interrupt-names = "irq_dec"; + clocks = <&cru ACLK_RKVDEC>, <&cru HCLK_RKVDEC>, + <&cru SCLK_VDEC_CABAC>, <&cru SCLK_VDEC_CORE>; + clock-names = "aclk_vcodec", "hclk_vcodec", "clk_cabac", + "clk_core"; + assigned-clocks = <&cru ACLK_RKVDEC_PRE>, <&cru SCLK_VDEC_CORE>; + assigned-clock-parents = <&cru PLL_GPLL>, <&cru PLL_GPLL>; + assigned-clock-rates = <500000000>, <245760000>; + resets = <&cru SRST_VDEC_A>, <&cru SRST_VDEC_H>, + <&cru SRST_VDEC_NIU_A>, <&cru SRST_VDEC_NIU_H>, + <&cru SRST_VDEC_CABAC>, <&cru SRST_VDEC_CORE>; + reset-names = "video_a", "video_h", "niu_a", "niu_h", + "video_cabac", "video_core"; + iommus = <&rkvdec_mmu>; + power-domains = <&power RK3328_PD_VIDEO>; + rockchip,srv = <&rkvdec_srv>; + status = "disabled"; + }; + rkvdec_mmu: iommu@ff360480 { compatible = "rockchip,iommu"; reg = <0x0 0xff360480 0x0 0x40>, <0x0 0xff3604c0 0x0 0x40>; @@ -740,8 +844,8 @@ <15000000>, <15000000>, <300000000>, <100000000>, <400000000>, <100000000>, - <50000000>, <100000000>, - <100000000>, <100000000>, + <50000000>, <300000000>, + <300000000>, <300000000>, <50000000>, <50000000>, <50000000>, <50000000>, <24000000>, <600000000>,