From fc2e8dbc42369ca958b2f48f3f589a6abb62f60d Mon Sep 17 00:00:00 2001 From: Dmitry Ilyin <6576495+widgetii@users.noreply.github.com> Date: Tue, 23 Jun 2026 22:50:52 +0300 Subject: [PATCH] kernel/hi3519dv500: add mipi_tx, gfbg, and the crypto subsystem from source MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The DV500 SDK ships these as full source (cv6xx's SDK didn't, so they were deferred there). Add the six source-only modules, taking dv500 to 59 open_*.ko: - mipi_tx — display output (mirrors mipi_rx; vendor init wrapper). - gfbg — graphics/OSD framebuffer (depends on TDE headers; chip-conditional gfbg feature flags from the vendor Makefile's hi3519dv500 branch — notably CONFIG_TDE_GFBG_COMPRESS_V2, and NOT CONFIG_GFBG_NOT_SUPPORT_FUNC which is the non-dv500 path). - cipher — symmetric crypto + the shared security_subsys_common framework (drv/kapi/dispatch/hal: trng/spacc/pke). - km / otp / hardware_cryptodev — key management / OTP fuses / /dev/crypto; disjoint source subsets that import cipher's framework at load. spi_dma_transfer (a cv6xx peripheral) has no dv500 SDK source, so it stays out. All pure source, no blobs. Verified: all 59 open_*.ko build to aarch64 with no undefined symbols against linux 5.10.0. --- README.md | 2 +- kernel/gfbg/hi3519dv500/Makefile | 64 + kernel/gfbg/hi3519dv500/drv/adp/Makefile | 8 + kernel/gfbg/hi3519dv500/drv/adp/gfbg_blit.c | 583 + kernel/gfbg/hi3519dv500/drv/adp/gfbg_blit.h | 40 + kernel/gfbg/hi3519dv500/drv/adp/gfbg_coef.h | 77 + kernel/gfbg/hi3519dv500/drv/adp/gfbg_comm.c | 146 + kernel/gfbg/hi3519dv500/drv/adp/gfbg_comm.h | 66 + kernel/gfbg/hi3519dv500/drv/adp/gfbg_def.h | 293 + kernel/gfbg/hi3519dv500/drv/adp/gfbg_drv.c | 1153 + .../hi3519dv500/drv/adp/gfbg_graphic_hal.c | 2807 +++ .../hi3519dv500/drv/adp/gfbg_graphic_hal.h | 173 + .../gfbg/hi3519dv500/drv/adp/gfbg_graphics.c | 538 + .../gfbg/hi3519dv500/drv/adp/gfbg_graphics.h | 137 + .../hi3519dv500/drv/adp/gfbg_graphics_drv.c | 1824 ++ .../hi3519dv500/drv/adp/gfbg_graphics_drv.h | 350 + kernel/gfbg/hi3519dv500/drv/adp/gfbg_reg.h | 18504 ++++++++++++++++ kernel/gfbg/hi3519dv500/drv/adp/gfbg_rotate.c | 38 + kernel/gfbg/hi3519dv500/drv/adp/gfbg_rotate.h | 40 + .../hi3519dv500/drv/adp/gfbg_rotate_tde.c | 178 + kernel/gfbg/hi3519dv500/drv/adp/mddrc_reg.h | 65 + .../gfbg/hi3519dv500/drv/include/gfbg_drv.h | 338 + kernel/gfbg/hi3519dv500/ext_inc/gfbg_ext.h | 41 + kernel/gfbg/hi3519dv500/include/gfbg.h | 349 + kernel/gfbg/hi3519dv500/src/Makefile | 10 + kernel/gfbg/hi3519dv500/src/gfbg_main.c | 8040 +++++++ kernel/gfbg/hi3519dv500/src/gfbg_main.h | 225 + kernel/gfbg/hi3519dv500/src/gfbg_proc.c | 78 + kernel/gfbg/hi3519dv500/src/gfbg_proc.h | 32 + kernel/gfbg/hi3519dv500/src/init/gfbg_init.h | 31 + .../hi3519dv500/src/init/linux/gfbg_init.c | 96 + kernel/hi3519dv500.kbuild | 115 + .../source_drv_init/mipi_tx_init.c | 77 + .../source_drv_init/ot_mipi_tx_mod_init.h | 28 + kernel/mipi_tx/hi3519dv500/mipi_tx.c | 1004 + kernel/mipi_tx/hi3519dv500/mipi_tx.h | 70 + kernel/mipi_tx/hi3519dv500/mipi_tx_def.h | 77 + kernel/mipi_tx/hi3519dv500/mipi_tx_hal.c | 1837 ++ kernel/mipi_tx/hi3519dv500/mipi_tx_hal.h | 214 + kernel/mipi_tx/hi3519dv500/mipi_tx_phy_reg.h | 2196 ++ kernel/mipi_tx/hi3519dv500/mipi_tx_reg.h | 1483 ++ kernel/mipi_tx/hi3519dv500/ot_mipi_tx.h | 127 + kernel/mipi_tx/hi3519dv500/type.h | 32 + kernel/security_subsys/hi3519dv500/Makefile | 59 + .../hi3519dv500/cipher/mkp/Makefile | 104 + .../hi3519dv500/cipher/mkp/crypto_drv_init.c | 400 + .../hi3519dv500/cipher/mkp/crypto_drv_init.h | 31 + .../hi3519dv500/cipher/mkp/crypto_drv_irq.c | 204 + .../hi3519dv500/cipher/mkp/crypto_drv_irq.h | 20 + .../hi3519dv500/cipher/mkp/hal_ca_misc_reg.h | 19 + .../hi3519dv500/cipher/mpi/Makefile | 31 + .../crypto_osal_lib/crypto_osal_lib.c | 323 + .../crypto_osal_lib/crypto_osal_lib.h | 80 + .../crypto_osal_lib/crypto_osal_user_lib.h | 37 + .../hi3519dv500/crypto_platform.h | 45 + .../hi3519dv500/hardware_cryptodev/Makefile | 37 + .../hi3519dv500/hardware_cryptodev/ot_reg.c | 428 + .../hi3519dv500/hardware_cryptodev/ot_reg.h | 130 + .../hi3519dv500/hardware_cryptodev/reg_aes.c | 454 + .../hi3519dv500/hardware_cryptodev/reg_hash.c | 305 + .../hi3519dv500/km/mkp/Makefile | 63 + .../hi3519dv500/km/mkp/crypto_km_drv_init.c | 201 + .../hi3519dv500/km/mkp/init_km.c | 83 + .../hi3519dv500/km/mkp/init_km.h | 22 + .../hi3519dv500/km/mpi/Makefile | 30 + .../hi3519dv500/mbedtls_harden_adapt/Makefile | 28 + .../mbedtls_harden_adapt.c | 463 + .../mbedtls_harden_adapt.h | 10 + .../hi3519dv500/otp/mkp/Makefile | 54 + .../hi3519dv500/otp/mkp/crypto_otp_drv_init.c | 134 + .../hi3519dv500/otp/mkp/init_otp.c | 81 + .../hi3519dv500/otp/mkp/init_otp.h | 16 + .../hi3519dv500/otp/mpi/Makefile | 30 + .../dispatch_code/crypto_dispatch.c | 2125 ++ .../dispatch_code/crypto_dispatch.h | 16 + .../dispatch_code/dispatch_km.c | 281 + .../dispatch_code/dispatch_km.h | 16 + .../dispatch_code/dispatch_otp.c | 83 + .../dispatch_code/dispatch_otp.h | 15 + .../drv_code/ca_misc_register.h | 26 + .../drv_code/crypto_drv_common.c | 486 + .../drv_code/crypto_drv_common.h | 121 + .../drv_code/crypto_osal_adapt.h | 126 + .../drv_code/drv_hash.c | 784 + .../drv_code/drv_inner.h | 129 + .../drv_code/drv_keyslot.c | 72 + .../drv_code/drv_klad.c | 302 + .../security_subsys_common/drv_code/drv_otp.c | 244 + .../drv_code/drv_pbkdf2_hard.c | 535 + .../security_subsys_common/drv_code/drv_pke.c | 792 + .../drv_code/drv_pke_ecc.c | 2235 ++ .../drv_code/drv_pke_ecc_curve.c | 592 + .../drv_code/drv_pke_rsa.c | 1208 + .../drv_code/drv_symc.c | 1392 ++ .../drv_code/drv_symc_mac_hard.c | 291 + .../drv_code/drv_trng.c | 82 + .../drv_code/otpc_register.h | 137 + .../hal_code/km_v4/README.md | 6 + .../hal_code/km_v4/hal_keyslot.c | 208 + .../hal_code/km_v4/hal_keyslot_reg.h | 153 + .../hal_code/km_v4/hal_klad.c | 648 + .../hal_code/km_v4/hal_klad_reg.h | 636 + .../hal_code/km_v4/hal_rkp.c | 551 + .../hal_code/km_v4/hal_rkp_reg.h | 147 + .../hal_code/pke_v4/hal_pke.c | 557 + .../hal_code/pke_v4/hal_pke_reg.h | 254 + .../hal_code/spacc_v4/hal_hash.c | 654 + .../hal_code/spacc_v4/hal_spacc_reg.h | 665 + .../hal_code/spacc_v4/hal_symc.c | 1859 ++ .../hal_code/trng_v4/hal_trng.c | 73 + .../hal_code/trng_v4/hal_trng_reg.h | 31 + .../common_include/crypto_common_def.h | 127 + .../common_include/crypto_common_macro.h | 148 + .../common_include/crypto_common_struct.h | 50 + .../include/common_include/crypto_ecc_curve.h | 12 + .../include/common_include/crypto_errno.h | 145 + .../common_include/crypto_hash_struct.h | 170 + .../common_include/crypto_kdf_struct.h | 20 + .../include/common_include/crypto_km_struct.h | 469 + .../common_include/crypto_pke_struct.h | 132 + .../common_include/crypto_symc_struct.h | 184 + .../include/common_include/crypto_type.h | 26 + .../include/drv_include/drv_common.h | 69 + .../include/drv_include/drv_hash.h | 32 + .../include/drv_include/drv_keyslot.h | 19 + .../include/drv_include/drv_klad.h | 29 + .../include/drv_include/drv_otp.h | 72 + .../include/drv_include/drv_pke.h | 178 + .../include/drv_include/drv_symc.h | 49 + .../include/drv_include/drv_trng.h | 18 + .../include/hal_include/hal_common.h | 67 + .../include/hal_include/hal_hash.h | 45 + .../include/hal_include/hal_keyslot.h | 15 + .../include/hal_include/hal_klad.h | 36 + .../include/hal_include/hal_pke.h | 131 + .../include/hal_include/hal_rkp.h | 37 + .../include/hal_include/hal_symc.h | 71 + .../include/hal_include/hal_trng.h | 16 + .../include/ioctl_include/crypto_ioctl.h | 21 + .../include/ioctl_include/crypto_ioctl_cmd.h | 503 + .../include/ioctl_include/ioctl_km.h | 101 + .../include/ioctl_include/ioctl_otp.h | 39 + .../include/kapi_include/kapi_hash.h | 54 + .../include/kapi_include/kapi_km.h | 36 + .../include/kapi_include/kapi_otp.h | 20 + .../include/kapi_include/kapi_pke.h | 62 + .../include/kapi_include/kapi_symc.h | 50 + .../include/kapi_include/kapi_trng.h | 14 + .../include/uapi_include/uapi_hash.h | 27 + .../include/uapi_include/uapi_kdf.h | 13 + .../include/uapi_include/uapi_km.h | 46 + .../include/uapi_include/uapi_otp.h | 32 + .../include/uapi_include/uapi_pke.h | 68 + .../include/uapi_include/uapi_symc.h | 45 + .../include/uapi_include/uapi_trng.h | 14 + .../kapi_code/kapi_hash.c | 595 + .../kapi_code/kapi_init.c | 44 + .../kapi_code/kapi_inner.h | 30 + .../kapi_code/kapi_km.c | 684 + .../kapi_code/kapi_otp.c | 85 + .../kapi_code/kapi_pke.c | 281 + .../kapi_code/kapi_symc.c | 1216 + .../kapi_code/kapi_trng.c | 66 + .../ot_mpi/ot_mpi_hash.c | 53 + .../ot_mpi/ot_mpi_kdf.c | 12 + .../security_subsys_common/ot_mpi/ot_mpi_km.c | 78 + .../ot_mpi/ot_mpi_otp.c | 31 + .../ot_mpi/ot_mpi_pke.c | 106 + .../ot_mpi/ot_mpi_symc.c | 81 + .../ot_mpi/ot_mpi_trng.c | 17 + .../ot_mpi_api/ot_mpi_cipher.h | 134 + .../ot_mpi_api/ot_mpi_km.h | 46 + .../ot_mpi_api/ot_mpi_otp.h | 32 + .../uapi_code/uapi_common.c | 73 + .../uapi_code/uapi_common.h | 18 + .../uapi_code/uapi_hash.c | 215 + .../uapi_code/uapi_kdf.c | 43 + .../uapi_code/uapi_km.c | 307 + .../uapi_code/uapi_otp.c | 136 + .../uapi_code/uapi_pke.c | 608 + .../uapi_code/uapi_symc.c | 498 + .../uapi_code/uapi_trng.c | 68 + 182 files changed, 75108 insertions(+), 1 deletion(-) create mode 100755 kernel/gfbg/hi3519dv500/Makefile create mode 100644 kernel/gfbg/hi3519dv500/drv/adp/Makefile create mode 100755 kernel/gfbg/hi3519dv500/drv/adp/gfbg_blit.c create mode 100755 kernel/gfbg/hi3519dv500/drv/adp/gfbg_blit.h create mode 100644 kernel/gfbg/hi3519dv500/drv/adp/gfbg_coef.h create mode 100755 kernel/gfbg/hi3519dv500/drv/adp/gfbg_comm.c create mode 100644 kernel/gfbg/hi3519dv500/drv/adp/gfbg_comm.h create mode 100755 kernel/gfbg/hi3519dv500/drv/adp/gfbg_def.h create mode 100755 kernel/gfbg/hi3519dv500/drv/adp/gfbg_drv.c create mode 100755 kernel/gfbg/hi3519dv500/drv/adp/gfbg_graphic_hal.c create mode 100755 kernel/gfbg/hi3519dv500/drv/adp/gfbg_graphic_hal.h create mode 100755 kernel/gfbg/hi3519dv500/drv/adp/gfbg_graphics.c create mode 100755 kernel/gfbg/hi3519dv500/drv/adp/gfbg_graphics.h create mode 100755 kernel/gfbg/hi3519dv500/drv/adp/gfbg_graphics_drv.c create mode 100755 kernel/gfbg/hi3519dv500/drv/adp/gfbg_graphics_drv.h create mode 100644 kernel/gfbg/hi3519dv500/drv/adp/gfbg_reg.h create mode 100755 kernel/gfbg/hi3519dv500/drv/adp/gfbg_rotate.c create mode 100755 kernel/gfbg/hi3519dv500/drv/adp/gfbg_rotate.h create mode 100755 kernel/gfbg/hi3519dv500/drv/adp/gfbg_rotate_tde.c create mode 100644 kernel/gfbg/hi3519dv500/drv/adp/mddrc_reg.h create mode 100755 kernel/gfbg/hi3519dv500/drv/include/gfbg_drv.h create mode 100755 kernel/gfbg/hi3519dv500/ext_inc/gfbg_ext.h create mode 100755 kernel/gfbg/hi3519dv500/include/gfbg.h create mode 100644 kernel/gfbg/hi3519dv500/src/Makefile create mode 100755 kernel/gfbg/hi3519dv500/src/gfbg_main.c create mode 100755 kernel/gfbg/hi3519dv500/src/gfbg_main.h create mode 100755 kernel/gfbg/hi3519dv500/src/gfbg_proc.c create mode 100755 kernel/gfbg/hi3519dv500/src/gfbg_proc.h create mode 100644 kernel/gfbg/hi3519dv500/src/init/gfbg_init.h create mode 100755 kernel/gfbg/hi3519dv500/src/init/linux/gfbg_init.c create mode 100644 kernel/init/hi3519dv500/source_drv_init/mipi_tx_init.c create mode 100644 kernel/init/hi3519dv500/source_drv_init/ot_mipi_tx_mod_init.h create mode 100644 kernel/mipi_tx/hi3519dv500/mipi_tx.c create mode 100644 kernel/mipi_tx/hi3519dv500/mipi_tx.h create mode 100644 kernel/mipi_tx/hi3519dv500/mipi_tx_def.h create mode 100644 kernel/mipi_tx/hi3519dv500/mipi_tx_hal.c create mode 100644 kernel/mipi_tx/hi3519dv500/mipi_tx_hal.h create mode 100644 kernel/mipi_tx/hi3519dv500/mipi_tx_phy_reg.h create mode 100644 kernel/mipi_tx/hi3519dv500/mipi_tx_reg.h create mode 100644 kernel/mipi_tx/hi3519dv500/ot_mipi_tx.h create mode 100644 kernel/mipi_tx/hi3519dv500/type.h create mode 100644 kernel/security_subsys/hi3519dv500/Makefile create mode 100644 kernel/security_subsys/hi3519dv500/cipher/mkp/Makefile create mode 100644 kernel/security_subsys/hi3519dv500/cipher/mkp/crypto_drv_init.c create mode 100644 kernel/security_subsys/hi3519dv500/cipher/mkp/crypto_drv_init.h create mode 100644 kernel/security_subsys/hi3519dv500/cipher/mkp/crypto_drv_irq.c create mode 100644 kernel/security_subsys/hi3519dv500/cipher/mkp/crypto_drv_irq.h create mode 100644 kernel/security_subsys/hi3519dv500/cipher/mkp/hal_ca_misc_reg.h create mode 100644 kernel/security_subsys/hi3519dv500/cipher/mpi/Makefile create mode 100644 kernel/security_subsys/hi3519dv500/crypto_osal_lib/crypto_osal_lib.c create mode 100644 kernel/security_subsys/hi3519dv500/crypto_osal_lib/crypto_osal_lib.h create mode 100644 kernel/security_subsys/hi3519dv500/crypto_osal_lib/crypto_osal_user_lib.h create mode 100644 kernel/security_subsys/hi3519dv500/crypto_platform.h create mode 100644 kernel/security_subsys/hi3519dv500/hardware_cryptodev/Makefile create mode 100644 kernel/security_subsys/hi3519dv500/hardware_cryptodev/ot_reg.c create mode 100644 kernel/security_subsys/hi3519dv500/hardware_cryptodev/ot_reg.h create mode 100644 kernel/security_subsys/hi3519dv500/hardware_cryptodev/reg_aes.c create mode 100644 kernel/security_subsys/hi3519dv500/hardware_cryptodev/reg_hash.c create mode 100644 kernel/security_subsys/hi3519dv500/km/mkp/Makefile create mode 100644 kernel/security_subsys/hi3519dv500/km/mkp/crypto_km_drv_init.c create mode 100644 kernel/security_subsys/hi3519dv500/km/mkp/init_km.c create mode 100644 kernel/security_subsys/hi3519dv500/km/mkp/init_km.h create mode 100644 kernel/security_subsys/hi3519dv500/km/mpi/Makefile create mode 100644 kernel/security_subsys/hi3519dv500/mbedtls_harden_adapt/Makefile create mode 100644 kernel/security_subsys/hi3519dv500/mbedtls_harden_adapt/mbedtls_harden_adapt.c create mode 100644 kernel/security_subsys/hi3519dv500/mbedtls_harden_adapt/mbedtls_harden_adapt.h create mode 100644 kernel/security_subsys/hi3519dv500/otp/mkp/Makefile create mode 100644 kernel/security_subsys/hi3519dv500/otp/mkp/crypto_otp_drv_init.c create mode 100644 kernel/security_subsys/hi3519dv500/otp/mkp/init_otp.c create mode 100644 kernel/security_subsys/hi3519dv500/otp/mkp/init_otp.h create mode 100644 kernel/security_subsys/hi3519dv500/otp/mpi/Makefile create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/dispatch_code/crypto_dispatch.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/dispatch_code/crypto_dispatch.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/dispatch_code/dispatch_km.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/dispatch_code/dispatch_km.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/dispatch_code/dispatch_otp.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/dispatch_code/dispatch_otp.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/ca_misc_register.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/crypto_drv_common.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/crypto_drv_common.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/crypto_osal_adapt.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_hash.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_inner.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_keyslot.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_klad.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_otp.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_pbkdf2_hard.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_pke.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_pke_ecc.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_pke_ecc_curve.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_pke_rsa.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_symc.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_symc_mac_hard.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_trng.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/otpc_register.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/km_v4/README.md create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/km_v4/hal_keyslot.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/km_v4/hal_keyslot_reg.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/km_v4/hal_klad.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/km_v4/hal_klad_reg.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/km_v4/hal_rkp.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/km_v4/hal_rkp_reg.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/pke_v4/hal_pke.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/pke_v4/hal_pke_reg.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/spacc_v4/hal_hash.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/spacc_v4/hal_spacc_reg.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/spacc_v4/hal_symc.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/trng_v4/hal_trng.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/trng_v4/hal_trng_reg.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_common_def.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_common_macro.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_common_struct.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_ecc_curve.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_errno.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_hash_struct.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_kdf_struct.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_km_struct.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_pke_struct.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_symc_struct.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_type.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/drv_include/drv_common.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/drv_include/drv_hash.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/drv_include/drv_keyslot.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/drv_include/drv_klad.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/drv_include/drv_otp.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/drv_include/drv_pke.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/drv_include/drv_symc.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/drv_include/drv_trng.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/hal_include/hal_common.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/hal_include/hal_hash.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/hal_include/hal_keyslot.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/hal_include/hal_klad.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/hal_include/hal_pke.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/hal_include/hal_rkp.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/hal_include/hal_symc.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/hal_include/hal_trng.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/ioctl_include/crypto_ioctl.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/ioctl_include/crypto_ioctl_cmd.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/ioctl_include/ioctl_km.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/ioctl_include/ioctl_otp.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/kapi_include/kapi_hash.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/kapi_include/kapi_km.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/kapi_include/kapi_otp.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/kapi_include/kapi_pke.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/kapi_include/kapi_symc.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/kapi_include/kapi_trng.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/uapi_include/uapi_hash.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/uapi_include/uapi_kdf.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/uapi_include/uapi_km.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/uapi_include/uapi_otp.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/uapi_include/uapi_pke.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/uapi_include/uapi_symc.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/include/uapi_include/uapi_trng.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/kapi_code/kapi_hash.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/kapi_code/kapi_init.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/kapi_code/kapi_inner.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/kapi_code/kapi_km.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/kapi_code/kapi_otp.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/kapi_code/kapi_pke.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/kapi_code/kapi_symc.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/kapi_code/kapi_trng.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi/ot_mpi_hash.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi/ot_mpi_kdf.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi/ot_mpi_km.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi/ot_mpi_otp.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi/ot_mpi_pke.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi/ot_mpi_symc.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi/ot_mpi_trng.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi_api/ot_mpi_cipher.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi_api/ot_mpi_km.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi_api/ot_mpi_otp.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_common.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_common.h create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_hash.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_kdf.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_km.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_otp.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_pke.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_symc.c create mode 100644 kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_trng.c diff --git a/README.md b/README.md index ed062293..2b68a837 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ The generation **number** tracks the peripheral address map and SDK architecture | V3.5 | CV500 | Cortex-A7 | OSAL | Raw `.o` + init wrappers | Incremental V3, snake_case SDK symbols | | V4 | EV200 | Cortex-A7 | OSAL | Source-based Kbuild | Redesigned modular SDK, Goke compat, mainline kernel | | V5 | CV610 | Cortex-A7 | OSAL + MMZ split | Raw `.o` + vendor init wrappers | Hi3516CV610/CV608, MMZ separated from OSAL again, vendor ships init wrappers as source | -| V5 | DV500 | Cortex-A55 (aarch64) | OSAL + MMZ split | Raw `.o` + vendor init wrappers | Hi3519DV500/Hi3516DV500, 64-bit ABI (`-DUSER_BIT_64/-DKERNEL_BIT_64`), 53 modules (42 blob + OSAL/MMZ/sys_config + peripherals + mipi_rx) | +| V5 | DV500 | Cortex-A55 (aarch64) | OSAL + MMZ split | Raw `.o` + vendor init wrappers | Hi3519DV500/Hi3516DV500, 64-bit ABI (`-DUSER_BIT_64/-DKERNEL_BIT_64`), 59 modules (42 blob + OSAL/MMZ/sys_config + peripherals + mipi_rx/tx + gfbg + crypto cipher/km/otp/hardware_cryptodev) | ### Dealing with vendor .ko blobs diff --git a/kernel/gfbg/hi3519dv500/Makefile b/kernel/gfbg/hi3519dv500/Makefile new file mode 100755 index 00000000..e483bd3c --- /dev/null +++ b/kernel/gfbg/hi3519dv500/Makefile @@ -0,0 +1,64 @@ +# $(PWD)/gfbg/Makefile + +ifeq ($(PARAM_FILE), ) + PARAM_FILE:=../../../Makefile.param + include $(PARAM_FILE) +endif + +ifeq ($(CBB_PARAM_FILE), ) + CBB_PARAM_FILE:=../Makefile.param + include $(CBB_PARAM_FILE) +endif + +ifeq ($(CONFIG_OT_GFBG_SUPPORT), y) +# Head file path variable's +CFG_INC := -I$(PWD)/include +CFG_INC += -I$(PWD)/ext_inc +CFG_INC += -I$(PWD)/src +CFG_INC += -I$(PWD)/src/init +CFG_INC += -I$(PWD)/drv/adp +CFG_INC += -I$(PWD)/drv/include +CFG_INC += -I$(TDE_ROOT)/drv/include + +ifeq ($(CONFIG_SYNC_FILE),y) +CFG_INC += -I$(KERNEL_ROOT)/drivers/ot_fence +EXTRA_CFLAGS += -DCONFIG_GFBG_FENCE_SUPPORT +endif + +ifneq ($(findstring $(OT_ARCH), hi3519dv500),) +EXTRA_CFLAGS += -DCONFIG_GFBG_G0_FHD_SUPPORT +EXTRA_CFLAGS += -DCONFIG_GFBG_LOW_DELAY_SUPPORT +EXTRA_CFLAGS += -DCONFIG_GFBG_RESOLUTION_SUPPORT_SQUARE +EXTRA_CFLAGS += -DCONFIG_TDE_CLUT_RECT_SUPPORT_G0 +EXTRA_CFLAGS += -DCONFIG_TDE_GFBG_COMPRESS_V2 +EXTRA_CFLAGS += -DCONFIG_TDE_CLUT_RECT_V2 +endif + +ifeq ($(findstring $(OT_ARCH), hi3519dv500),) +EXTRA_CFLAGS += -DCONFIG_GFBG_NOT_SUPPORT_FUNC +endif + +EXTRA_CFLAGS += -DCONFIG_COMPRESS_ECONOMIZE_MEMERY + +EXTRA_CFLAGS += $(CFG_INC) + +SRCS := +include $(PWD)/src/Makefile +include $(PWD)/drv/adp/Makefile + +TARGET:=gfbg + +#************************************************************************* +# release header +INC_FILE := $(wildcard $(GFBG_ROOT)/include/*.h) + +# compile linux or liteos +include $(MAKE_DRV_FILE) + +#CONFIG_OT_GFBG_SUPPORT endif +else +all: + @echo "gfbg module not compile" +clean: + @echo "gfbg module don't need clean" +endif diff --git a/kernel/gfbg/hi3519dv500/drv/adp/Makefile b/kernel/gfbg/hi3519dv500/drv/adp/Makefile new file mode 100644 index 00000000..cef915f0 --- /dev/null +++ b/kernel/gfbg/hi3519dv500/drv/adp/Makefile @@ -0,0 +1,8 @@ +SRCS+=drv/adp/gfbg_drv.c +SRCS+=drv/adp/gfbg_blit.c +SRCS+=drv/adp/gfbg_graphics.c +SRCS+=drv/adp/gfbg_graphics_drv.c +SRCS+=drv/adp/gfbg_graphic_hal.c +SRCS+=drv/adp/gfbg_comm.c +SRCS+=drv/adp/gfbg_rotate.c +SRCS+=drv/adp/gfbg_rotate_tde.c diff --git a/kernel/gfbg/hi3519dv500/drv/adp/gfbg_blit.c b/kernel/gfbg/hi3519dv500/drv/adp/gfbg_blit.c new file mode 100755 index 00000000..0a616002 --- /dev/null +++ b/kernel/gfbg/hi3519dv500/drv/adp/gfbg_blit.c @@ -0,0 +1,583 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "gfbg_blit.h" +#include "mod_ext.h" +#include "gfbg_comm.h" +#include "gfbg_rotate.h" + +#ifdef __LITEOS__ +#define in_atomic() (TD_FALSE) +#endif + +static drv_tde_func_callback g_tde_call_back; + +static td_s32 drv_blit_submit_job(const ot_tde_export_func *, const gfbg_blit_opt *, const td_s32 *); + +/* tde support which color format */ +static td_bool g_tde_col_fmt[OT_FB_FORMAT_BUTT] = { + TD_FALSE, /* OT_FB_FORMAT_RGB565 */ + TD_FALSE, /* OT_FB_FORMAT_RGB888 */ + TD_FALSE, /* OT_FB_FORMAT_KRGB444 */ + TD_FALSE, /* OT_FB_FORMAT_KRGB555 */ + TD_FALSE, /* OT_FB_FORMAT_KRGB888 */ + TD_TRUE, /* OT_FB_FORMAT_ARGB4444 */ + TD_TRUE, /* OT_FB_FORMAT_ARGB1555 */ + TD_TRUE, /* OT_FB_FORMAT_ARGB8888 */ + TD_FALSE, /* OT_FB_FORMAT_ARGB8565 */ + TD_FALSE, /* OT_FB_FORMAT_RGBA4444 */ + TD_FALSE, /* OT_FB_FORMAT_RGBA5551 */ + TD_FALSE, /* OT_FB_FORMAT_RGBA5658 */ + TD_FALSE, /* OT_FB_FORMAT_RGBA8888 */ + + TD_FALSE, /* BGR565 */ + TD_FALSE, /* BGR888 */ + TD_FALSE, /* ABGR4444 */ + TD_FALSE, /* ABGR1555 */ + TD_FALSE, /* ABGR8888 */ + TD_FALSE, /* ABGR8565 */ + TD_FALSE, /* BGR444 16bpp */ + TD_FALSE, /* BGR555 16bpp */ + TD_FALSE, /* BGR888 32bpp */ + + TD_FALSE, /* OT_FB_FORMAT_1BPP */ + TD_TRUE, /* OT_FB_FORMAT_2BPP */ /* just for quickcopy(dma) */ + TD_TRUE, /* OT_FB_FORMAT_4BPP */ /* just for quickcopy(dma) */ + TD_FALSE, /* OT_FB_FORMAT_8BPP */ + TD_FALSE, /* OT_FB_FORMAT_ACLUT44 */ + TD_FALSE, /* OT_FB_FORMAT_ACLUT88 */ + TD_FALSE, /* OT_FB_FORMAT_PUYVY */ + TD_FALSE, /* OT_FB_FORMAT_PYUYV */ + TD_FALSE, /* OT_FB_FORMAT_PYVYU */ + TD_FALSE, /* OT_FB_FORMAT_YUV888 */ + TD_FALSE, /* OT_FB_FORMAT_AYUV8888 */ + TD_FALSE, /* OT_FB_FORMAT_YUVA8888 */ +}; + +static drv_tde_color_fmt g_gfbg_fmt[OT_FB_FORMAT_BUTT] = { + DRV_TDE_COLOR_FMT_RGB565, + DRV_TDE_COLOR_FMT_RGB888, + DRV_TDE_COLOR_FMT_RGB444, + DRV_TDE_COLOR_FMT_RGB555, + DRV_TDE_COLOR_FMT_ARGB8888, + DRV_TDE_COLOR_FMT_ARGB4444, + DRV_TDE_COLOR_FMT_ARGB1555, + DRV_TDE_COLOR_FMT_ARGB8888, + DRV_TDE_COLOR_FMT_ARGB8565, + DRV_TDE_COLOR_FMT_MAX, + DRV_TDE_COLOR_FMT_MAX, + DRV_TDE_COLOR_FMT_MAX, + DRV_TDE_COLOR_FMT_MAX, + DRV_TDE_COLOR_FMT_BGR565, + DRV_TDE_COLOR_FMT_BGR888, + DRV_TDE_COLOR_FMT_ABGR4444, + DRV_TDE_COLOR_FMT_ABGR1555, + DRV_TDE_COLOR_FMT_ABGR8888, + DRV_TDE_COLOR_FMT_ABGR8565, + DRV_TDE_COLOR_FMT_BGR444, + DRV_TDE_COLOR_FMT_BGR555, + DRV_TDE_COLOR_FMT_ABGR8888, + DRV_TDE_COLOR_FMT_CLUT1, + DRV_TDE_COLOR_FMT_CLUT2, + DRV_TDE_COLOR_FMT_CLUT4, + DRV_TDE_COLOR_FMT_CLUT8, + DRV_TDE_COLOR_FMT_ACLUT44, + DRV_TDE_COLOR_FMT_ACLUT88, + DRV_TDE_COLOR_FMT_MAX, + DRV_TDE_COLOR_FMT_MAX, + DRV_TDE_COLOR_FMT_MAX, + DRV_TDE_COLOR_FMT_MAX, + DRV_TDE_COLOR_FMT_MAX, + DRV_TDE_COLOR_FMT_MAX, +}; + +td_bool gfbg_tde_is_support_fmt(ot_fb_color_format format) +{ + if (format >= OT_FB_FORMAT_BUTT) { + return TD_FALSE; + } + return g_tde_col_fmt[format]; +} + +drv_tde_color_fmt gfbg_drv_conv_fmt(ot_fb_color_format format) +{ + if (format >= OT_FB_FORMAT_BUTT) { + return DRV_TDE_COLOR_FMT_MAX; + } + return g_gfbg_fmt[format]; +} + +td_s32 gfbg_drv_fill(const ot_fb_buf *dst_img, td_u32 fill_data) +{ + td_s32 ret; + drv_tde_surface dst_surface = {0}; + drv_tde_rect dst_rect = {0}; + td_s32 handle = -1; + drv_tde_end_job_cmd end_job; + ot_tde_export_func *tde_export_func = func_entry(ot_tde_export_func, OT_ID_TDE); + if ((tde_export_func == TD_NULL) || (tde_export_func->drv_tde_module_begin_job == TD_NULL) || + (tde_export_func->drv_tde_module_end_job == TD_NULL) || + (tde_export_func->drv_tde_module_cancel_job == TD_NULL) || + (tde_export_func->drv_tde_module_quick_fill == TD_NULL)) { + gfbg_error("TDE tde_export_func is NULL!\n"); + return TD_FAILURE; + } + + /* config dst */ + dst_surface.phys_addr = dst_img->canvas.phys_addr; + dst_surface.width = dst_img->canvas.width; + dst_surface.height = dst_img->canvas.height; + dst_surface.stride = dst_img->canvas.pitch; + dst_surface.alpha_max_is_255 = TD_TRUE; + dst_surface.is_ycbcr_clut = TD_FALSE; + dst_surface.color_format = gfbg_drv_conv_fmt(dst_img->canvas.format); + + dst_rect.pos_x = 0; + dst_rect.pos_y = 0; + dst_rect.height = dst_surface.height; + dst_rect.width = dst_surface.width; + + ret = tde_export_func->drv_tde_module_begin_job(&handle); + if (ret != TD_SUCCESS) { + osal_printk("GFBG Warning: TDE begin job failed\n"); + return ret; + } + + ret = tde_export_func->drv_tde_module_quick_fill(handle, &dst_surface, &dst_rect, fill_data); + if (ret != TD_SUCCESS) { + osal_printk("GFBG Warning: TDE blit failed. ret = 0x%x handle %d \n", ret, handle); + tde_export_func->drv_tde_module_cancel_job(handle); + return ret; + } + + /* 1000 is timeout */ + fb_drv_tde_end_job_val(end_job, handle, TD_TRUE, 1000, TD_FALSE); + ret = tde_export_func->drv_tde_module_end_job(&end_job, TD_NULL, TD_NULL); + if (ret != TD_SUCCESS) { + osal_printk("GFBG Warning: FILL job submitted to TDE failed!!! Ret = 0x%x\n", ret); + return ret; + } + + return TD_SUCCESS; +} + +#ifndef CONFIG_COMPRESS_ECONOMIZE_MEMERY +static td_u32 gfbg_drv_get_dcmp_stride(const ot_fb_surface *canvas) +{ + td_u32 comp_ratio_int = 1000; /* 1000 for default compress ratio */ + td_u32 extend_width, bytes_per_pix; + td_u32 exp_num_temp = 0; + td_u32 stride = 0; + if (canvas == TD_NULL) { + return stride; + } + stride = canvas->pitch; + + if (canvas->format == OT_FB_FORMAT_ARGB8888) { + if (canvas->width <= 320) { /* 320 max width */ + exp_num_temp = 2; /* 2 alg data */ + comp_ratio_int = 1000; /* 1000 alg data */ + } else if (canvas->width <= 720) { /* 720 max width */ + exp_num_temp = 10; /* 10 alg data */ + comp_ratio_int = 2000; /* 2000 alg data */ + } else if (canvas->width <= 3840) { /* 3840 max width */ + exp_num_temp = 10; /* 10 alg data */ + comp_ratio_int = 2000; /* 2000 alg data */ + } + /* 4 is PerPix byte */ + bytes_per_pix = 4; + /* 8 1000 127 128 16 alg data */ + stride = ((canvas->width * bytes_per_pix * 8 * 1000 / comp_ratio_int + 127) / 128 + exp_num_temp) * 16; + } else if (OT_FB_FORMAT_ARGB1555 == canvas->format || OT_FB_FORMAT_ARGB4444 == canvas->format) { + if (canvas->width <= 720) { /* 720 max width */ + exp_num_temp = 2; /* 2 alg data */ + comp_ratio_int = 1000; /* 1000 alg data */ + } else if (canvas->width <= 3840) { /* 3840 alg data */ + exp_num_temp = 0; + comp_ratio_int = 1000; /* 1000 alg data */ + } + bytes_per_pix = 2; /* 2 is PerPix byte */ + + extend_width = ((canvas->width + 31) / 32) * 32; /* 31 32 alg data */ + /* 8 1000 127 128 16 alg data */ + stride = ((extend_width * bytes_per_pix * 8 * 1000 / comp_ratio_int + 127) / 128 + exp_num_temp) * 16; + } + + stride = (stride + 0xf) & 0xfffffff0; /* 0xf 0xfffffff0 for 16 bytes align */ + + return stride; +} +#endif + +static td_void drv_blit_init(drv_tde_surface *surface, drv_tde_rect *rect, const ot_fb_buf *img, + const gfbg_blit_opt *opt) +{ + surface->phys_addr = img->canvas.phys_addr; + surface->width = img->canvas.width; + surface->height = img->canvas.height; + surface->stride = img->canvas.pitch; + surface->alpha_max_is_255 = TD_TRUE; + surface->is_ycbcr_clut = TD_FALSE; + surface->color_format = gfbg_drv_conv_fmt(img->canvas.format); + surface->alpha0 = opt->alpha.alpha0; + surface->alpha1 = opt->alpha.alpha1; + + rect->pos_x = img->update_rect.x; + rect->pos_y = img->update_rect.y; + rect->width = img->update_rect.width; + rect->height = img->update_rect.height; + return; +} + +static td_void drv_blit_compress(drv_tde_surface *dst_surface, const ot_fb_buf *dst_img, const gfbg_blit_opt *opt) +{ +#ifndef CONFIG_COMPRESS_ECONOMIZE_MEMERY + if (opt->compress == TD_TRUE) { + dst_surface->cbcr_phys_addr = dst_img->canvas.phys_addr; + dst_surface->cbcr_stride = dst_img->canvas.pitch; + dst_surface->stride = gfbg_drv_get_dcmp_stride(&dst_img->canvas); + } +#else + td_u32 cmp_stride = 0; + td_u32 uncmp_stride = 0; + gfbg_stride_attr attr = {0}; + + dst_surface->cbcr_phys_addr = dst_img->canvas.phys_addr; + dst_surface->cbcr_stride = dst_img->canvas.pitch; + + attr.is_lossless = TD_FALSE; + attr.is_losslessa = TD_FALSE; + attr.width = dst_img->canvas.width; + attr.format = dst_img->canvas.format; + gfbg_recalculate_stride(&cmp_stride, &uncmp_stride, &attr); + if (opt->compress != TD_TRUE && uncmp_stride != 0) { + dst_surface->stride = uncmp_stride; + } else if (cmp_stride != 0) { + dst_surface->stride = cmp_stride; + } +#endif + return; +} + +static td_void drv_blit_refresh_screen(const drv_tde_surface *src_surface, const drv_tde_rect *src_rect, + const drv_tde_surface *dst_surface, drv_tde_rect *dst_rect, + td_bool is_refresh_screen) +{ + if (is_refresh_screen == TD_TRUE) { + if ((src_surface->width == 0) || (src_surface->height == 0)) { + return; + } + dst_rect->pos_x = src_rect->pos_x * dst_surface->width / src_surface->width; + dst_rect->pos_y = src_rect->pos_y * dst_surface->height / src_surface->height; + dst_rect->width = src_rect->width * dst_surface->width / src_surface->width; + dst_rect->height = src_rect->height * dst_surface->height / src_surface->height; + } + return; +} + +static td_void blit_opt_get_filter_mode(drv_tde_opt *option, const gfbg_blit_opt *opt) +{ + switch (opt->antiflicker_level) { + case OT_FB_LAYER_ANTIFLICKER_NONE: + option->filter_mode = DRV_TDE_FILTER_MODE_COLOR; + break; + case OT_FB_LAYER_ANTIFLICKER_LOW: + option->filter_mode = DRV_TDE_FILTER_MODE_COLOR; + break; + case OT_FB_LAYER_ANTIFLICKER_MID: + option->filter_mode = DRV_TDE_FILTER_MODE_COLOR; + break; + case OT_FB_LAYER_ANTIFLICKER_HIGH: + option->filter_mode = DRV_TDE_FILTER_MODE_COLOR; + break; + case OT_FB_LAYER_ANTIFLICKER_AUTO: + option->filter_mode = DRV_TDE_FILTER_MODE_COLOR; + break; + default: + break; + } + return; +} + +static td_void blit_opt_get_mirror_mode(drv_tde_opt *option, const gfbg_blit_opt *opt) +{ + switch (opt->mirror_mode) { + case OT_FB_MIRROR_NONE: + option->mirror = DRV_TDE_MIRROR_NONE; + break; + case OT_FB_MIRROR_HOR: + option->mirror = DRV_TDE_MIRROR_HORIZONTAL; + break; + case OT_FB_MIRROR_VER: + option->mirror = DRV_TDE_MIRROR_VERTICAL; + break; + case OT_FB_MIRROR_BOTH: + option->mirror = DRV_TDE_MIRROR_BOTH; + break; + default: + option->mirror = DRV_TDE_MIRROR_NONE; + break; + } + return; +} + +static td_void blit_opt_get_alpha(drv_tde_opt *option, const gfbg_blit_opt *opt) +{ + if (opt->alpha.pixel_alpha) { + option->alpha_blending_cmd = DRV_TDE_ALPHA_BLENDING_BLEND; + option->global_alpha = opt->alpha.global_alpha; + option->out_alpha_from = DRV_TDE_OUT_ALPHA_FROM_NORM; + } else { + option->out_alpha_from = DRV_TDE_OUT_ALPHA_FROM_FOREGROUND; + } + return; +} + +static td_void drv_blit_option_init(drv_tde_surface *src_surface, drv_tde_surface *dst_surface, drv_tde_opt *option, + const gfbg_blit_opt *opt) +{ + option->resize = opt->scale; + if ((src_surface->color_format >= gfbg_drv_conv_fmt(OT_FB_FORMAT_1BPP)) && + (src_surface->color_format <= gfbg_drv_conv_fmt(OT_FB_FORMAT_ACLUT88))) { + option->clut_reload = TD_TRUE; + src_surface->clut_phys_addr = opt->cmap_addr; + dst_surface->clut_phys_addr = opt->cmap_addr; + } + + /* if opt is antiflicker level */ + blit_opt_get_filter_mode(option, opt); + +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC + if (opt->ckey.key_enable) { + if ((src_surface->color_format >= gfbg_drv_conv_fmt(OT_FB_FORMAT_1BPP)) && + (src_surface->color_format <= gfbg_drv_conv_fmt(OT_FB_FORMAT_ACLUT88))) { + option->colorkey_mode = DRV_TDE_COLOR_KEY_MODE_FOREGROUND; + option->colorkey_value.clut_colorkey.alpha.is_component_ignore = TD_TRUE; + option->colorkey_value.clut_colorkey.clut.is_component_out = opt->ckey.key_mode; + option->colorkey_value.clut_colorkey.clut.component_max = opt->ckey.blue_max; + option->colorkey_value.clut_colorkey.clut.component_min = opt->ckey.blue_min; + } else { + option->colorkey_mode = DRV_TDE_COLOR_KEY_MODE_FOREGROUND; + option->colorkey_value.argb_colorkey.alpha.is_component_ignore = TD_TRUE; + option->colorkey_value.argb_colorkey.red.component_max = opt->ckey.red_max; + option->colorkey_value.argb_colorkey.red.component_min = opt->ckey.red_min; + option->colorkey_value.argb_colorkey.red.is_component_out = opt->ckey.key_mode; + option->colorkey_value.argb_colorkey.red.component_mask = 0xff; + option->colorkey_value.argb_colorkey.green.component_max = opt->ckey.green_max; + option->colorkey_value.argb_colorkey.green.component_min = opt->ckey.green_min; + option->colorkey_value.argb_colorkey.green.is_component_out = opt->ckey.key_mode; + option->colorkey_value.argb_colorkey.green.component_mask = 0xff; + option->colorkey_value.argb_colorkey.blue.component_max = opt->ckey.blue_max; + option->colorkey_value.argb_colorkey.blue.component_min = opt->ckey.blue_min; + option->colorkey_value.argb_colorkey.blue.is_component_out = opt->ckey.key_mode; + option->colorkey_value.argb_colorkey.blue.component_mask = 0xff; + } + } +#endif + /* if opt is alpha enable */ + blit_opt_get_alpha(option, opt); + + /* if opt is mirror mode */ + blit_opt_get_mirror_mode(option, opt); + + return; +} + + +static td_s32 gfbg_check_is_intelligence_rect(const drv_tde_surface *src_surface, const drv_tde_surface *dst_surface, + const drv_tde_opt *option) +{ + if (src_surface->color_format != dst_surface->color_format) { + gfbg_error("clut only support src and dst the same color format!\n"); + return TD_FAILURE; + } + /* not support scale */ + if (option->resize == TD_TRUE) { + gfbg_error("clut not support resize!\n"); + return TD_FAILURE; + } + /* not support compress */ + if ((option->is_compress == TD_TRUE) || (option->is_decompress == TD_TRUE)) { + gfbg_error("clut not support compress!\n"); + return TD_FAILURE; + } + /* not support alpha blending */ + if (option->alpha_blending_cmd != DRV_TDE_ALPHA_BLENDING_NONE) { + gfbg_error("clut not support alpha blending!\n"); + return TD_FAILURE; + } + /* not support colorkey */ + if (option->colorkey_mode != DRV_TDE_COLOR_KEY_MODE_NONE) { + gfbg_error("clut not support colorkey!\n"); + return TD_FAILURE; + } + return TD_SUCCESS; +} + +static td_s32 drv_blit_start(td_s32 *handle, const drv_tde_single_src *single_src, drv_tde_opt *option, + const gfbg_blit_opt *opt, const ot_tde_export_func *tde_export_func) +{ + td_s32 ret; + drv_tde_double_src double_src; + + ret = tde_export_func->drv_tde_module_begin_job(handle); + if (ret != TD_SUCCESS) { + return ret; + } + option->is_compress = opt->compress; + /* + * for 1 and 2 buff refresh intelligence rect + * when both src surface's dst surface's color format are clut2 or clut4 + * only quick copy without any operation + */ + if ((single_src->dst_surface->color_format == DRV_TDE_COLOR_FMT_CLUT2) || + (single_src->dst_surface->color_format == DRV_TDE_COLOR_FMT_CLUT4)) { + ret = gfbg_check_is_intelligence_rect(single_src->src_surface, single_src->dst_surface, option); + if (ret != TD_SUCCESS) { + tde_export_func->drv_tde_module_cancel_job(*handle); + return ret; + } + ret = tde_export_func->drv_tde_module_quick_copy(*handle, single_src); + } else { + double_src.bg_surface = single_src->dst_surface; + double_src.bg_rect = single_src->dst_rect; + double_src.fg_surface = single_src->src_surface; + double_src.fg_rect = single_src->src_rect; + double_src.dst_surface = single_src->dst_surface; + double_src.dst_rect = single_src->dst_rect; + ret = tde_export_func->drv_tde_module_blit(*handle, &double_src, option); + } + + if (ret != TD_SUCCESS) { + tde_export_func->drv_tde_module_cancel_job(*handle); + return ret; + } + + /* submit tde the job */ + ret = drv_blit_submit_job(tde_export_func, opt, handle); + if (ret != TD_SUCCESS) { + return ret; + } + + return ret; +} + +static td_s32 drv_blit_submit_job(const ot_tde_export_func *tde_export_func, const gfbg_blit_opt *opt, + const td_s32 *handle) +{ + gfbg_tde_callback_param *param = TD_NULL; + const td_u32 time_out = 1000; + td_s32 ret; + drv_tde_end_job_cmd end_job; + + if (opt->call_back) { + if (in_atomic()) { + param = osal_kmalloc(sizeof(gfbg_tde_callback_param), GFP_ATOMIC); + } else { + param = osal_kmalloc(sizeof(gfbg_tde_callback_param), GFP_KERNEL); + } + if (param == TD_NULL) { + tde_export_func->drv_tde_module_cancel_job(*handle); + return TD_FAILURE; + } + + param->layer_id = *(td_u32 *)opt->param; + param->soft_cursor_update = opt->soft_cursor_update; + param->compress = opt->compress; + fb_drv_tde_end_job_val(end_job, *handle, opt->block, time_out, opt->is_sync); + ret = tde_export_func->drv_tde_module_end_job(&end_job, g_tde_call_back, param); + } else { + fb_drv_tde_end_job_val(end_job, *handle, opt->block, time_out, opt->is_sync); + ret = tde_export_func->drv_tde_module_end_job(&end_job, TD_NULL, TD_NULL); + } + + if (ret != TD_SUCCESS) { + ret = tde_export_func->drv_tde_module_cancel_job(*handle); + if (ret != TD_SUCCESS) { + /* + * job has been submitted to the logic for processing + * memory will be released in the callback function + */ + gfbg_error("cancel job failed!ret = %x\n", ret); + } else { + /* + * job is not submitted to the logic for processing + * callback function is not invoked + * memory needs to be released here + */ + if (param != TD_NULL) { + osal_kfree(param); + param = TD_NULL; + } + } + return TD_FAILURE; + } + /* + * memory has been released in the callback function + * or after cancel_job executed successfully + */ + return TD_SUCCESS; +} + +static td_s32 gfbg_blit_check(ot_tde_export_func **tde_export_func, const ot_fb_buf *src_img, const ot_fb_buf *dst_img, + const gfbg_blit_opt *opt) +{ + if ((src_img == TD_NULL) || (dst_img == TD_NULL) || (opt == TD_NULL)) { + return TD_FAILURE; + } + *tde_export_func = func_entry(ot_tde_export_func, OT_ID_TDE); + if ((*tde_export_func == TD_NULL) || ((*tde_export_func)->drv_tde_module_begin_job == TD_NULL) || + ((*tde_export_func)->drv_tde_module_end_job == TD_NULL) || + ((*tde_export_func)->drv_tde_module_cancel_job == TD_NULL) || + ((*tde_export_func)->drv_tde_module_blit == TD_NULL)) { + gfbg_error("TDE tde_export_func is NULL!\n"); + return TD_FAILURE; + } + return TD_SUCCESS; +} + +td_s32 gfbg_drv_blit(const ot_fb_buf *src_img, const ot_fb_buf *dst_img, const gfbg_blit_opt *opt, + td_bool is_refresh_screen) +{ + td_s32 ret, handle; + drv_tde_surface src_surface = {0}; + drv_tde_surface dst_surface = {0}; + drv_tde_rect src_rect, dst_rect; + drv_tde_opt option = {0}; + ot_tde_export_func *tde_export_func = TD_NULL; + drv_tde_single_src single_src = {0}; + if (gfbg_blit_check((ot_tde_export_func **)&tde_export_func, src_img, dst_img, opt) != TD_SUCCESS) { + return TD_FAILURE; + } + /* src init */ + drv_blit_init(&src_surface, &src_rect, src_img, opt); + /* dst_init */ + drv_blit_init(&dst_surface, &dst_rect, dst_img, opt); + /* if compress */ + drv_blit_compress(&dst_surface, dst_img, opt); + /* if is_refresh_screen */ + drv_blit_refresh_screen(&src_surface, &src_rect, &dst_surface, &dst_rect, is_refresh_screen); + /* get option */ + drv_blit_option_init(&src_surface, &dst_surface, &option, opt); + + /* blit start */ + single_src.src_surface = &src_surface; + single_src.src_rect = &src_rect; + single_src.dst_surface = &dst_surface; + single_src.dst_rect = &dst_rect; + ret = drv_blit_start(&handle, &single_src, &option, opt, tde_export_func); + if (ret != TD_SUCCESS) { + gfbg_error("drv_blit_start failed!\n"); + return ret; + } + + return handle; +} + +td_s32 gfbg_drv_set_tde_callback(drv_tde_func_callback tde_callback) +{ + g_tde_call_back = tde_callback; + return TD_SUCCESS; +} + diff --git a/kernel/gfbg/hi3519dv500/drv/adp/gfbg_blit.h b/kernel/gfbg/hi3519dv500/drv/adp/gfbg_blit.h new file mode 100755 index 00000000..c393c6ea --- /dev/null +++ b/kernel/gfbg/hi3519dv500/drv/adp/gfbg_blit.h @@ -0,0 +1,40 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef GFBG_BLIT_H +#define GFBG_BLIT_H + +#include "ot_type.h" +#include "gfbg_main.h" +#include "drv_tde.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* End of #ifdef __cplusplus */ + +#define fb_drv_tde_end_job_val(end_job, thandle, tis_block, ttime_out, tis_sync) \ + do { \ + (end_job).handle = thandle; \ + (end_job).is_block = tis_block; \ + (end_job).is_sync = tis_sync; \ + (end_job).time_out = ttime_out; \ + } while (0) + +td_bool gfbg_tde_is_support_fmt(ot_fb_color_format format); +td_s32 gfbg_drv_fill(const ot_fb_buf *dst_img, td_u32 fill_data); +td_s32 gfbg_drv_blit(const ot_fb_buf *src_img, const ot_fb_buf *dst_img, const gfbg_blit_opt *opt, + td_bool is_refresh_screen); +td_s32 gfbg_drv_set_tde_callback(drv_tde_func_callback tde_callback); +drv_tde_color_fmt gfbg_drv_conv_fmt(ot_fb_color_format format); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* GFBG_BLIT_H */ + diff --git a/kernel/gfbg/hi3519dv500/drv/adp/gfbg_coef.h b/kernel/gfbg/hi3519dv500/drv/adp/gfbg_coef.h new file mode 100644 index 00000000..6dd36a91 --- /dev/null +++ b/kernel/gfbg/hi3519dv500/drv/adp/gfbg_coef.h @@ -0,0 +1,77 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef GFBG_COEF_H +#define GFBG_COEF_H + +#include "ot_type.h" +#include "ot_debug.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +/* COLOR SPACE CONVERT DEFINITION */ +typedef struct { + td_s32 csc_coef00; + td_s32 csc_coef01; + td_s32 csc_coef02; + + td_s32 csc_coef10; + td_s32 csc_coef11; + td_s32 csc_coef12; + + td_s32 csc_coef20; + td_s32 csc_coef21; + td_s32 csc_coef22; +} vdp_csc_coef; + +typedef struct { + td_s32 csc_in_dc0; + td_s32 csc_in_dc1; + td_s32 csc_in_dc2; + + td_s32 csc_out_dc0; + td_s32 csc_out_dc1; + td_s32 csc_out_dc2; +} vdp_csc_dc_coef; + +typedef struct { + // for old version csc + td_s32 csc_coef00; + td_s32 csc_coef01; + td_s32 csc_coef02; + + td_s32 csc_coef10; + td_s32 csc_coef11; + td_s32 csc_coef12; + + td_s32 csc_coef20; + td_s32 csc_coef21; + td_s32 csc_coef22; + + td_s32 csc_in_dc0; + td_s32 csc_in_dc1; + td_s32 csc_in_dc2; + + td_s32 csc_out_dc0; + td_s32 csc_out_dc1; + td_s32 csc_out_dc2; +} csc_coef; + +typedef struct { + td_s32 csc_scale2p; + td_s32 csc_clip_min; + td_s32 csc_clip_max; +} csc_coef_param; + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* GFBG_COEF_H */ \ No newline at end of file diff --git a/kernel/gfbg/hi3519dv500/drv/adp/gfbg_comm.c b/kernel/gfbg/hi3519dv500/drv/adp/gfbg_comm.c new file mode 100755 index 00000000..924fd42c --- /dev/null +++ b/kernel/gfbg/hi3519dv500/drv/adp/gfbg_comm.c @@ -0,0 +1,146 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "gfbg_comm.h" +#ifdef CONFIG_TDE_GFBG_COMPRESS_V2 +static td_u32 gfbg_node_max(td_u32 a, td_u32 b) +{ + return (a > b) ? a : b; +} + +static td_u32 gfbg_node_min(td_u32 a, td_u32 b) +{ + return (a > b) ? b : a; +} + +td_void gfbg_recalculate_stride(td_u32 *cmp_stride, td_u32 *uncmp_stride, const gfbg_stride_attr *attr) +{ + td_u32 bit_dep_a, bit_dep_rgb, osd_mode; + td_u32 comp_ratio; + td_bool is_continue; + td_u32 mb_num_x, buffer_init_bits, delta, mb_ori_bits, budget_mb_bits, last_mb_width, budget_mb_bits_last; + td_u32 last_mb_extra_bits; + + is_continue = ((attr->format != OT_FB_FORMAT_RGB888) && (attr->format != OT_FB_FORMAT_ARGB8888) && + (attr->format != OT_FB_FORMAT_ARGB1555) && (attr->format != OT_FB_FORMAT_ARGB4444)); + + if (is_continue == TD_TRUE) { + return; + } + + if (attr->format == OT_FB_FORMAT_ARGB8888) { + osd_mode = 1; + comp_ratio = 2000; /* 2000 for zme */ + } else if (attr->format == OT_FB_FORMAT_RGB888) { + osd_mode = 0; + comp_ratio = 1000; /* 1000 for zme */ + } else if (attr->format == OT_FB_FORMAT_ARGB1555) { + osd_mode = 2; /* 2 for zme */ + comp_ratio = 1000; /* 1000 for zme */ + } else { + osd_mode = 3; /* 3 for zme */ + comp_ratio = 1000; /* 1000 for zme */ + } + + bit_dep_a = (osd_mode <= 1) ? 8 : ((osd_mode == 2) ? 1 : 4); /* 8 2 4 alg data */ + bit_dep_rgb = (osd_mode <= 1) ? 8 : ((osd_mode == 2) ? 5 : 4); /* 8 2 5 4 alg data */ + + /* for calculate budget_mb_bits */ + last_mb_width = (attr->width % 32) ? (attr->width % 32) : 32; /* 32 alg data */ + mb_num_x = (attr->width + 32 - 1) / 32; /* 32 alg data */ + /* 2 9 7946 7000 18 8082 7000 alg data */ + buffer_init_bits = (osd_mode < 2) ? ((mb_num_x < 9) ? 7946 : 7000) : ((mb_num_x < 18) ? 8082 : 7000); + /* 9216 alg data */ + delta = gfbg_node_max(1, (9216 - buffer_init_bits + mb_num_x - 1) / (mb_num_x)); + mb_ori_bits = 32 * (bit_dep_rgb * 3 + bit_dep_a); /* 32 3 alg data */ + budget_mb_bits = mb_ori_bits * 1000 / comp_ratio - delta; /* 1000 alg data */ + budget_mb_bits = gfbg_node_min(gfbg_node_max(budget_mb_bits, 64), mb_ori_bits); /* 64 alg data */ + budget_mb_bits_last = (budget_mb_bits * last_mb_width) / 32; /* 32 alg data */ + last_mb_extra_bits = budget_mb_bits - budget_mb_bits_last; + + if (cmp_stride != NULL) { + /* 3 1000 126 alg data */ + *cmp_stride = (attr->width * (bit_dep_a + bit_dep_rgb * 3) * 1000 / comp_ratio + last_mb_extra_bits + 126) / + 127 + 1; /* 127 alg data */ + *cmp_stride = *cmp_stride * 16; /* 16 alg data */ + } + + if (uncmp_stride != NULL) { + /* 3 8 16 alg data */ + *uncmp_stride = ((attr->width * (bit_dep_a + bit_dep_rgb * 3) / 8) + 16 - 1) & (~(16 - 1)); + } + return; +} +#endif + +#ifdef CONFIG_TDE_GFBG_COMPRESS_V1 +static td_s32 gfbg_get_mode_and_ratio(ot_fb_color_format format, td_u32 *osd_mode, td_u32 *comp_ratio) +{ + td_bool is_continue; + is_continue = ((format != OT_FB_FORMAT_ARGB8888) && (format != OT_FB_FORMAT_RGBA8888) && + (format != OT_FB_FORMAT_ABGR8888) && (format != OT_FB_FORMAT_RGB888) && + (format != OT_FB_FORMAT_BGR888) && (format != OT_FB_FORMAT_ARGB1555) && + (format != OT_FB_FORMAT_ABGR1555) && (format != OT_FB_FORMAT_ARGB4444)); + + if (is_continue == TD_TRUE) { + return TD_FAILURE; + } + + if (format == OT_FB_FORMAT_ARGB8888) { + *osd_mode = 0; + *comp_ratio = 2000; /* 2000 for zme */ + } else if (format == OT_FB_FORMAT_RGB888) { + *osd_mode = 1; + *comp_ratio = 1000; /* 1000 for zme */ + } else if (format == OT_FB_FORMAT_ARGB1555) { + *osd_mode = 2; /* 2 for zme */ + *comp_ratio = 1000; /* 1000 for zme */ + } else { + *osd_mode = 3; /* 3 for zme */ + *comp_ratio = 1000; /* 1000 for zme */ + } + + return TD_SUCCESS; +} +td_void gfbg_recalculate_stride(td_u32 *cmp_stride, td_u32 *uncmp_stride, const gfbg_stride_attr *attr) +{ + td_u32 exp_num, extend_width; + td_u32 bit_dep_a, bit_dep_rgb, osd_mode; + td_u32 comp_ratio; + td_s32 ret; + + ret = gfbg_get_mode_and_ratio(attr->format, &osd_mode, &comp_ratio); + if (ret != TD_SUCCESS) { + return; + } + + extend_width = (attr->width + 31) / 32 * 32; /* 31 32 for align */ + bit_dep_a = (osd_mode == 0) ? 8 : ((osd_mode == 1) ? 6 : ((osd_mode == 2) ? 1 : 4)); /* 8 6 2 4 alg data */ + bit_dep_rgb = (osd_mode == 0) ? 8 : ((osd_mode == 1) ? 8 : ((osd_mode == 2) ? 5 : 4)); /* 8 2 5 4 alg data */ + + if ((osd_mode == 0) || (osd_mode == 1)) { + exp_num = (attr->width <= 320) ? 2 : ((attr->width <= 720) ? 2 : 14); /* 320 720 width, 2 14 alg data */ + } else { + exp_num = (attr->width <= 720) ? 2 : 0; /* 720 width, 2 alg data */ + } + + if (cmp_stride != NULL) { + /* 3 1000 127 128 alg data */ + *cmp_stride = (extend_width * (bit_dep_a + bit_dep_rgb * 3) * 1000 / comp_ratio + 127) / 128 + exp_num; + + if ((attr->is_lossless != TD_FALSE) || (attr->is_losslessa != TD_FALSE)) { + /* 3 13 9 10 128 alg data */ + *cmp_stride = (((attr->width * (bit_dep_a + bit_dep_rgb * 3)) * 13 + 9) / 10) / 128; + } + /* 16 alg data */ + *cmp_stride = *cmp_stride * 16; + } + + if (uncmp_stride != NULL) { + /* 3 8 16 alg data */ + *uncmp_stride = ((attr->width * (bit_dep_a + bit_dep_rgb * 3) / 8) + 16 - 1) & (~(16 - 1)); + } + return; +} +#endif diff --git a/kernel/gfbg/hi3519dv500/drv/adp/gfbg_comm.h b/kernel/gfbg/hi3519dv500/drv/adp/gfbg_comm.h new file mode 100644 index 00000000..ef25937d --- /dev/null +++ b/kernel/gfbg/hi3519dv500/drv/adp/gfbg_comm.h @@ -0,0 +1,66 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef GFBG_COMM_H +#define GFBG_COMM_H + +#include "ot_type.h" +#include "gfbg.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#define gfbg_unequal_eok_return(ret) \ + do { \ + if ((ret) != EOK) { \ + gfbg_error("secure function failure\n"); \ + return TD_FAILURE; \ + } \ + } while (0) + +#define gfbg_unequal_eok_return_void(ret) \ + do { \ + if ((ret) != EOK) { \ + gfbg_error("secure function failure\n"); \ + return; \ + } \ + } while (0) + +#define gfbg_unlock_unequal_eok_return(ret, lock, lock_flag) \ + do { \ + if ((ret) != EOK) { \ + gfbg_error("secure function failure\n"); \ + osal_spin_unlock_irqrestore(lock, lock_flag); \ + return TD_FAILURE; \ + } \ + } while (0) + +#define gfbg_unlock_unequal_eok_return_void(ret, lock, lock_flag) \ + do { \ + if ((ret) != EOK) { \ + gfbg_error("secure function failure\n"); \ + osal_spin_unlock_irqrestore(lock, lock_flag); \ + return; \ + } \ + } while (0) + +typedef struct { + td_bool is_losslessa; + td_bool is_lossless; + td_u32 width; + ot_fb_color_format format; +} gfbg_stride_attr; + +td_void gfbg_recalculate_stride(td_u32 *cmp_stride, td_u32 *uncmp_stride, const gfbg_stride_attr *attr); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* GFBG_COMM_H */ diff --git a/kernel/gfbg/hi3519dv500/drv/adp/gfbg_def.h b/kernel/gfbg/hi3519dv500/drv/adp/gfbg_def.h new file mode 100755 index 00000000..17b3cd84 --- /dev/null +++ b/kernel/gfbg/hi3519dv500/drv/adp/gfbg_def.h @@ -0,0 +1,293 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef GFBG_DEF_H +#define GFBG_DEF_H + +#include "ot_type.h" +#include "gfbg_coef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#define VHD_REGS_LEN 0x1000 /* len of V0's regs */ +#define VSD_REGS_LEN 0x1000 +#define GFX_REGS_LEN 0x800 +#define DHD_REGS_LEN 0x1000 +#define GRF_REGS_LEN 0x200 /* len of GFX regs */ + +/* Offset define */ +#define FDR_GFX_OFFSET 0x200 + +/* architecture define */ +#define GFBG_MAX_LAYER_NUM 5 +#define WBC_MAX 1 + +/* Value define */ +#define ZME_HPREC (1 << 20) +#define ZME_VPREC (1 << 12) + +/* Defined for ZME */ +#define MAX_OFFSET 3 +#define MIN_OFFSET (-1) + +/* vou device enumeration */ +typedef td_u32 vo_intf_type; + +typedef enum { + VO_DEV_DHD0 = 0, /* ultra high definition device */ + VO_DEV_DHD1 = 1, /* high definition device */ + VO_DEV_DSD0 = 2, + VO_DEV_BUTT +} hal_vo_dev; + +typedef enum { + HAL_DISP_CHANNEL_DHD0 = 0, + HAL_DISP_CHANNEL_DHD1 = 1, + HAL_DISP_CHANNEL_DSD0 = 2, + HAL_DISP_CHANNEL_WBC = 3, + HAL_DISP_CHANNEL_NONE = 4, + HAL_DISP_CHANNEL_BUTT +} hal_disp_outputchannel; + +typedef enum { + HAL_DISP_LAYER_VHD0 = 0, + HAL_DISP_LAYER_VHD1 = 1, + HAL_DISP_LAYER_VHD2 = 2, + HAL_DISP_LAYER_VSD0 = 3, + + HAL_DISP_LAYER_GFX0 = 4, + HAL_DISP_LAYER_GFX1 = 5, + HAL_DISP_LAYER_GFX2 = 6, + HAL_DISP_LAYER_GFX3 = 7, + HAL_DISP_LAYER_GFX4 = 8, + + HAL_DISP_LAYER_WBC = 9, + HAL_DISP_LAYER_BUTT, +} hal_disp_layer; + +#define LAYER_GFX_START HAL_DISP_LAYER_GFX0 /* GFX0 */ +#define LAYER_GFX_END HAL_DISP_LAYER_GFX4 /* GFX4 */ + +typedef enum { + HAL_INPUTFMT_YCBCR_SEMIPLANAR_400 = 0x1, + HAL_INPUTFMT_YCBCR_SEMIPLANAR_420 = 0x2, + HAL_INPUTFMT_YCBCR_SEMIPLANAR_422 = 0x3, + HAL_INPUTFMT_YCBCR_SEMIPLANAR_444 = 0x4, + HAL_INPUTFMT_YCBCR_SEMIPLANAR_411_4X1 = 0x6, + HAL_INPUTFMT_YCBCR_SEMIPLANAR_422_2X1 = 0x7, + + HAL_INPUTFMT_CBYCRY_PACKAGE_422 = 0x9, + HAL_INPUTFMT_YCBYCR_PACKAGE_422 = 0xa, + HAL_INPUTFMT_YCRYCB_PACKAGE_422 = 0xb, + HAL_INPUTFMT_YCBCR_PACKAGE_444 = 0x1000, + + HAL_INPUTFMT_CLUT_1BPP = 0x00, + HAL_INPUTFMT_CLUT_2BPP = 0x10, + HAL_INPUTFMT_CLUT_4BPP = 0x20, + HAL_INPUTFMT_CLUT_8BPP = 0x30, + HAL_INPUTFMT_ACLUT_44 = 0x38, + + HAL_INPUTFMT_RGB_444 = 0x40, + HAL_INPUTFMT_RGB_555 = 0x41, + HAL_INPUTFMT_RGB_565 = 0x42, + HAL_INPUTFMT_CBYCRY_PACKAGE_422_GRC = 0x43, + HAL_INPUTFMT_YCBYCR_PACKAGE_422_GRC = 0x44, + HAL_INPUTFMT_YCRYCB_PACKAGE_422_GRC = 0x45, + HAL_INPUTFMT_ACLUT_88 = 0x46, + HAL_INPUTFMT_ARGB_4444 = 0x48, + HAL_INPUTFMT_ARGB_1555 = 0x49, + + HAL_INPUTFMT_RGB_888 = 0x50, + HAL_INPUTFMT_YCBCR_888 = 0x51, + HAL_INPUTFMT_ARGB_8565 = 0x5a, + HAL_INPUTFMT_ARGB_6666 = 0x5b, + + HAL_INPUTFMT_KRGB_888 = 0x60, + HAL_INPUTFMT_ARGB_8888 = 0x68, + HAL_INPUTFMT_AYCBCR_8888 = 0x69, + + HAL_INPUTFMT_RGBA_4444 = 0xc8, + HAL_INPUTFMT_RGBA_5551 = 0xc9, + + HAL_INPUTFMT_RGBA_6666 = 0xd8, + HAL_INPUTFMT_RGBA_5658 = 0xda, + + HAL_INPUTFMT_RGBA_8888 = 0xe8, + HAL_INPUTFMT_YCBCRA_8888 = 0xe9, + + HAL_DISP_PIXELFORMAT_BUTT +} hal_disp_pixel_format; + +typedef enum { + HAL_CSC_MODE_BT601LIMIT_TO_BT601LIMIT, /* BT601LIMIT to BT601LIMIT */ + HAL_CSC_MODE_BT601FULL_TO_BT601LIMIT, /* BT601FULL to BT601LIMIT */ + HAL_CSC_MODE_BT709LIMIT_TO_BT601LIMIT, /* BT709LIMIT to BT601LIMIT */ + HAL_CSC_MODE_BT709FULL_TO_BT601LIMIT, /* BT709FULL to BT601LIMIT */ + + HAL_CSC_MODE_BT601LIMIT_TO_BT709LIMIT, /* BT601LIMIT to BT709LIMIT */ + HAL_CSC_MODE_BT601FULL_TO_BT709LIMIT, /* BT601FULL to BT709LIMIT */ + HAL_CSC_MODE_BT709LIMIT_TO_BT709LIMIT, /* BT709LIMIT to BT709LIMIT */ + HAL_CSC_MODE_BT709FULL_TO_BT709LIMIT, /* BT709FULL to BT709LIMIT */ + + HAL_CSC_MODE_BT601LIMIT_TO_BT601FULL, /* BT601LIMIT to BT601FULL */ + HAL_CSC_MODE_BT601FULL_TO_BT601FULL, /* BT601FULL to BT601FULL */ + HAL_CSC_MODE_BT709LIMIT_TO_BT601FULL, /* BT709LIMIT to BT601FULL */ + HAL_CSC_MODE_BT709FULL_TO_BT601FULL, /* BT709FULL to BT601FULL */ + + HAL_CSC_MODE_BT601LIMIT_TO_BT709FULL, /* BT601LIMIT to BT709FULL */ + HAL_CSC_MODE_BT709LIMIT_TO_BT709FULL, /* BT709LIMIT to BT709FULL */ + HAL_CSC_MODE_BT601FULL_TO_BT709FULL, /* BT601FULL to BT709FULL */ + HAL_CSC_MODE_BT709FULL_TO_BT709FULL, /* BT709FULL to BT709FULL */ + + HAL_CSC_MODE_BT601LIMIT_TO_RGBFULL, /* BT601LIMIT to RGBFULL */ + HAL_CSC_MODE_BT601FULL_TO_RGBFULL, /* BT601FULL to RGBFULL */ + HAL_CSC_MODE_BT709LIMIT_TO_RGBFULL, /* BT709LIMIT to RGBFULL */ + HAL_CSC_MODE_BT709FULL_TO_RGBFULL, /* BT709FULL to RGBFULL */ + + HAL_CSC_MODE_BT601LIMIT_TO_RGBLIMIT, /* BT601LIMIT to RGBLIMIT */ + HAL_CSC_MODE_BT601FULL_TO_RGBLIMIT, /* BT601FULL to RGBLIMIT */ + HAL_CSC_MODE_BT709LIMIT_TO_RGBLIMIT, /* BT709LIMIT to RGBLIMIT */ + HAL_CSC_MODE_BT709FULL_TO_RGBLIMIT, /* BT709FULL to RGBLIMIT */ + + HAL_CSC_MODE_RGBFULL_TO_BT601LIMIT, /* RGBFULL to BT601LIMIT */ + HAL_CSC_MODE_RGBFULL_TO_BT601FULL, /* RGBFULL to BT601FULL */ + HAL_CSC_MODE_RGBFULL_TO_BT709LIMIT, /* RGBFULL to BT709LIMIT */ + HAL_CSC_MODE_RGBFULL_TO_BT709FULL, /* RGBFULL to BT709FULL */ + HAL_CSC_MODE_RGBFULL_TO_RGBFULL, /* RGBFULL to RGBFULL */ + HAL_CSC_MODE_RGBFULL_TO_RGBLIMIT, /* RGBFULLto RGBLIMIT */ + + HAL_CSC_MODE_BUTT +} hal_csc_mode; + +typedef struct { + td_s32 luma; + td_s32 contrast; + td_s32 hue; + td_s32 satu; +} hal_csc_value; + +typedef struct { + ot_fb_layer_csc_matrix csc_matrix; + hal_csc_mode csc_mode; +} hal_csc_matrix_mode; + +typedef struct { + hal_csc_mode csc_mode; + const csc_coef *coef; +} hal_csc_mode_coef; + +/* graphic layer data extend mode */ +typedef enum { + HAL_GFX_BITEXTEND_1ST = 0, + HAL_GFX_BITEXTEND_2ND = 0x2, + HAL_GFX_BITEXTEND_3RD = 0x3, + + HAL_GFX_BITEXTEND_BUTT +} hal_gfx_bitextend; + +typedef struct { + td_u32 synm; + td_u32 iop; + td_u8 intfb; + + td_u16 vact; + td_u16 vbb; + td_u16 vfb; + + td_u16 hact; + td_u16 hbb; + td_u16 hfb; + td_u16 hmid; + + td_u16 bvact; + td_u16 bvbb; + td_u16 bvfb; + + td_u16 hpw; + td_u16 vpw; + + td_u32 idv; + td_u32 ihs; + td_u32 ivs; +} hal_disp_syncinfo; + +typedef enum { + HAL_DISP_INTF_CVBS = (0x01L << 0), + HAL_DISP_INTF_VGA = (0x01L << 1), + HAL_DISP_INTF_BT656 = (0x01L << 2), /* 2 alg data */ + HAL_DISP_INTF_BT1120 = (0x01L << 3), /* 3 alg data */ + HAL_DISP_INTF_HDMI = (0x01L << 4), /* 4 alg data */ + HAL_DISP_INTF_RGB_6BIT = (0x01L << 5), /* 5 alg data */ + HAL_DISP_INTF_RGB_8BIT = (0x01L << 6), /* 6 alg data */ + HAL_DISP_INTF_RGB_16BIT = (0x01L << 7), /* 7 alg data */ + HAL_DISP_INTF_RGB_18BIT = (0x01L << 8), /* 8 alg data */ + HAL_DISP_INTF_RGB_24BIT = (0x01L << 9), /* 9 alg data */ + HAL_DISP_INTF_MIPI = (0x01L << 10), /* 10 alg data */ + HAL_DISP_INTF_MIPI_SLAVE = (0x01L << 11), /* 11 alg data */ + HAL_DISP_INTF_BUTT = (0x01L << 12), /* 12 alg data */ +} hal_disp_intf; + +typedef struct { + td_u16 bkg_a; + td_u16 bkg_y; + td_u16 bkg_cb; + td_u16 bkg_cr; +} hal_disp_bkcolor; + +/* graphic layer mask */ +typedef struct { + td_u8 mask_r; + td_u8 mask_g; + td_u8 mask_b; +} hal_gfx_mask; + +typedef struct { + td_u8 key_max_r; + td_u8 key_max_g; + td_u8 key_max_b; +} hal_gfx_key_max; + +typedef struct { + td_u8 key_min_r; + td_u8 key_min_g; + td_u8 key_min_b; +} hal_gfx_key_min; + +typedef enum { + VDP_RMODE_INTERFACE = 0, + VDP_RMODE_INTERLACE = 0, + VDP_RMODE_PROGRESSIVE = 1, + VDP_RMODE_TOP = 2, + VDP_RMODE_BOTTOM = 3, + VDP_RMODE_PRO_TOP = 4, + VDP_RMODE_PRO_BOTTOM = 5, + VDP_RMODE_BUTT +} vdp_data_rmode; + +typedef enum { + VDP_CSC_YUV2YUV = 1, + VDP_CSC_YUV2RGB_601, + VDP_CSC_YUV2RGB_709, + VDP_CSC_YUV2YUV_709_601, + VDP_CSC_YUV2YUV_601_709, + VDP_CSC_RGB2YUV_601, + VDP_CSC_RGB2YUV_709, + VDP_CSC_YUV2YUV_MAX, + VDP_CSC_YUV2YUV_MIN, + VDP_CSC_YUV2YUV_RAND, + VDP_CSC_BUTT +} vdp_csc_mode; + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* GFBG_DEF_H */ + diff --git a/kernel/gfbg/hi3519dv500/drv/adp/gfbg_drv.c b/kernel/gfbg/hi3519dv500/drv/adp/gfbg_drv.c new file mode 100755 index 00000000..a249f71c --- /dev/null +++ b/kernel/gfbg/hi3519dv500/drv/adp/gfbg_drv.c @@ -0,0 +1,1153 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ +#include "gfbg_drv.h" +#include "mod_ext.h" +#include "securec.h" +#include "drv_tde.h" +#include "gfbg_graphics.h" +#include "gfbg_comm.h" + +#ifdef CONFIG_GFBG_G0_FHD_SUPPORT +#define GFBG_MAX_LAYER_WIDTH_G0 1920 +#ifdef CONFIG_GFBG_RESOLUTION_SUPPORT_SQUARE +#define GFBG_MAX_LAYER_HEIGHT_G0 1920 +#else +#define GFBG_MAX_LAYER_HEIGHT_G0 1080 +#endif +#else +#define GFBG_MAX_LAYER_WIDTH_G0 3840 +#define GFBG_MAX_LAYER_HEIGHT_G0 2160 +#endif +#define GFBG_MIN_LAYER_WIDTH_G0 32 +#define GFBG_MIN_LAYER_HEIGH_G0 32 + +#ifdef CONFIG_GFBG_G1_4K_SUPPORT +#define GFBG_MAX_LAYER_WIDTH_G1 3840 +#define GFBG_MAX_LAYER_HEIGTH_G1 2160 +#else +#define GFBG_MAX_LAYER_WIDTH_G1 1920 +#define GFBG_MAX_LAYER_HEIGTH_G1 1080 +#endif +#define GFBG_MIN_LAYER_WIDTH_G1 32 +#define GFBG_MIN_LAYER_HEIGTH_G1 32 + +#define GFBG_MAX_LAYER_WIDTH_G2 256 +#define GFBG_MAX_LAYER_HEIGTH_G2 256 +#define GFBG_MIN_LAYER_WIDTH_G2 2 +#define GFBG_MIN_LAYER_HEIGTH_G2 2 + +#ifdef CONFIG_GFBG_G3_960_SUPPORT +#define GFBG_MAX_LAYER_WIDTH_G3 960 +#define GFBG_MAX_LAYER_HEIGTH_G3 576 +#else +#define GFBG_MAX_LAYER_WIDTH_G3 720 +#define GFBG_MAX_LAYER_HEIGTH_G3 576 +#endif +#define GFBG_MIN_LAYER_WIDTH_G3 2 +#define GFBG_MIN_LAYER_HEIGTH_G3 2 + +#define GRAPHICS_LAYER_G0 0 +#define GRAPHICS_LAYER_G1 1 +#define GRAPHICS_LAYER_G2 2 +#define GRAPHICS_LAYER_G3 3 +#define GRAPHICS_LAYER_G4 4 + +ot_fb_capability g_gfbg_gfx_cap[GFBG_MAX_LAYER_NUM] = { + /* G0 */ + { + .is_key_rgb = 1, + .is_key_alpha = 0, + .is_global_alpha = 1, + .is_cmap = 0, + .is_color_format = { + 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, // 25 + .max_width = GFBG_MAX_LAYER_WIDTH_G0, + .max_height = GFBG_MAX_LAYER_HEIGHT_G0, + .min_width = GFBG_MIN_LAYER_WIDTH_G0, + .min_height = GFBG_MIN_LAYER_HEIGH_G0, + .ver_deflicker_level = 0, + .hor_deflicker_level = 0, + .is_layer_support = TD_TRUE, + .is_vo_scale = TD_TRUE, + .has_cmap_reg = 0, + .is_decompress = 1, + .is_premul = 1, + .is_ghdr = 0, + .is_osb = 0, + }, + /* G1 */ + { + .is_key_rgb = 1, + .is_key_alpha = 0, + .is_global_alpha = 1, + .is_cmap = 0, + .is_color_format = { + 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, // 25 + .max_width = GFBG_MAX_LAYER_WIDTH_G1, + .max_height = GFBG_MAX_LAYER_HEIGTH_G1, + .min_width = GFBG_MIN_LAYER_WIDTH_G1, + .min_height = GFBG_MIN_LAYER_HEIGTH_G1, + .ver_deflicker_level = 0, + .hor_deflicker_level = 0, + .is_layer_support = TD_TRUE, + .is_vo_scale = TD_FALSE, + .has_cmap_reg = 0, + .is_decompress = 1, + .is_premul = 1, + .is_ghdr = 0, + .is_osb = 0, + }, + { + .is_key_rgb = 1, + .is_key_alpha = 0, + .is_global_alpha = 1, + .is_cmap = 0, + .is_color_format = { + 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, // 25 + .max_width = GFBG_MAX_LAYER_WIDTH_G2, + .max_height = GFBG_MAX_LAYER_HEIGTH_G2, + .min_width = GFBG_MIN_LAYER_WIDTH_G2, + .min_height = GFBG_MIN_LAYER_HEIGTH_G2, + .ver_deflicker_level = 0, + .hor_deflicker_level = 0, + .is_layer_support = TD_TRUE, + .is_vo_scale = TD_FALSE, + .has_cmap_reg = 0, + .is_decompress = 0, + .is_premul = 1, + .is_ghdr = 0, + .is_osb = 0, + }, + /* G3 */ + { + .is_key_rgb = 1, + .is_key_alpha = 0, + .is_global_alpha = 1, + .is_cmap = 1, + .is_color_format = { + 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, // 25 + .max_width = GFBG_MAX_LAYER_WIDTH_G3, + .max_height = GFBG_MAX_LAYER_HEIGTH_G3, + .min_width = GFBG_MIN_LAYER_WIDTH_G3, + .min_height = GFBG_MIN_LAYER_HEIGTH_G3, + .ver_deflicker_level = 0, + .hor_deflicker_level = 0, + .is_layer_support = TD_TRUE, + .is_vo_scale = TD_FALSE, + .has_cmap_reg = 0, + .is_decompress = 0, + .is_premul = 1, + .is_ghdr = 0, + .is_osb = 1, + }, + /* G4 */ + { + .is_key_rgb = 1, + .is_key_alpha = 0, + .is_global_alpha = 1, + .is_cmap = 1, + .is_color_format = { + 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, // 25 + .max_width = GFBG_MAX_LAYER_WIDTH_G3, + .max_height = GFBG_MAX_LAYER_HEIGTH_G3, + .min_width = GFBG_MIN_LAYER_WIDTH_G3, + .min_height = GFBG_MIN_LAYER_HEIGTH_G3, + .ver_deflicker_level = 0, + .hor_deflicker_level = 0, + .is_layer_support = TD_TRUE, + .is_vo_scale = TD_FALSE, + .has_cmap_reg = 0, + .is_decompress = 0, + .is_premul = 1, + .is_ghdr = 0, + .is_osb = 1, + }, +}; + +td_s32 *g_vo_gfbg_layer_index = TD_NULL; +td_s32 g_vo_gfbg_layer_index_array[2][5] = { /* 2 5 alg data */ + { + 4, /* OT_VO_LAYER_G0 */ + 5, /* OT_VO_LAYER_G1 */ + 6, /* OT_VO_LAYER_G2 */ + 7, /* OT_VO_LAYER_G3 */ + 8, /* OT_VO_LAYER_G4 */ + }, + { + 3, /* OT_VO_LAYER_G0 */ + 4, /* OT_VO_LAYER_G1 */ + -1, /* OT_VO_LAYER_G2 */ + 5, /* OT_VO_LAYER_G3 */ + -1, /* OT_VO_LAYER_G4 */ + }, +}; + +td_s32 gfbg_vou_get_dev_id(td_u32 layer_id) +{ + if (layer_id >= GFBG_MAX_LAYER_NUM || g_vo_gfbg_layer_index == TD_NULL) { + return -1; + } + return g_vo_gfbg_layer_index[layer_id] - g_vo_gfbg_layer_index[0]; +} + +/* + * the index number of fb and the actual graphics layer + * 0 - HAL_DISP_LAYER_GFX0 + * 1 - HAL_DISP_LAYER_GFX1 + * 2 - HAL_DISP_LAYER_GFX3 + */ +hal_disp_layer g_gfbglayer_to_hwlayer[GFBG_MAX_LAYER_NUM] = { + HAL_DISP_LAYER_GFX0, + HAL_DISP_LAYER_GFX1, + HAL_DISP_LAYER_GFX2, + HAL_DISP_LAYER_GFX3, + HAL_DISP_LAYER_GFX4, +}; + +hal_disp_layer gfbg_drv_gfbglayer_to_hwlayer(td_u32 layer_id) +{ + return g_gfbglayer_to_hwlayer[layer_id]; +} + +td_bool is_4k_layer(td_u32 layer_id) +{ +#ifndef CONFIG_GFBG_G0_FHD_SUPPORT + if (layer_id == GRAPHICS_LAYER_G0 || layer_id == GRAPHICS_LAYER_G1) { + return TD_TRUE; + } else { + return TD_FALSE; + } +#else + ot_unused(layer_id); + return TD_FALSE; +#endif +} + +td_bool is_hd_layer(td_u32 layer_id) +{ +#ifdef CONFIG_GFBG_G0_FHD_SUPPORT + if (layer_id == GRAPHICS_LAYER_G0) { + return TD_TRUE; + } else { + return TD_FALSE; + } +#else + ot_unused(layer_id); + return TD_FALSE; +#endif +} + +td_bool is_sd_layer(td_u32 layer_id) +{ + if ((layer_id == GRAPHICS_LAYER_G3) || (layer_id == GRAPHICS_LAYER_G4)) { + return TD_TRUE; + } else { + return TD_FALSE; + } +} + +td_bool is_ad_layer(td_u32 layer_id) +{ + ot_unused(layer_id); + return TD_FALSE; +} + +td_bool is_cursor_layer(td_u32 layer_id) +{ + return (layer_id == GRAPHICS_LAYER_G2); +} + +td_bool is_layer_support_low_delay(td_u32 layer_id) +{ + return (layer_id == GRAPHICS_LAYER_G0); +} + +/* Frame decompression needs to be offset by 16 bytes; +line decompression does not need */ +td_phys_addr_t gfbg_drv_get_dcmp_offset_addr(td_phys_addr_t dcmp_addr) +{ + return dcmp_addr; +} + +td_s32 gfbg_drv_set_layer_enable(td_u32 layer_id, td_bool enable) +{ + return fb_graphics_set_layer_enable(g_gfbglayer_to_hwlayer[layer_id], enable); +} + +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC +td_s32 gfbg_drv_get_layer_enable(td_u32 layer_id, td_bool *enable) +{ + return fb_graphics_get_layer_enable(g_gfbglayer_to_hwlayer[layer_id], enable); +} +#endif + +/* +* Name : gfbg_drv_layer_default_setting +* Desc : The default settings for the layer, including the following: + 1.Color value mode + 2.Bit extension mode + 3.alpha, global alpha,CSC,CSC enable, get interface type +*/ +td_s32 gfbg_drv_layer_default_setting(td_u32 layer_id) +{ + hal_disp_layer disp_layer = g_gfbglayer_to_hwlayer[layer_id]; + + if (g_gfbg_gfx_cap[layer_id].is_key_rgb || g_gfbg_gfx_cap[layer_id].is_key_alpha) { + fb_graphics_set_gfx_key_mode(disp_layer, FB_COLORKEY_IN); + } + + fb_graphics_set_gfx_ext(disp_layer, FB_GFX_BITEXTEND_3RD); + + fb_graphics_set_gfx_palpha(disp_layer, TD_TRUE, TD_TRUE, GRAPHIC_ALPHA_OPACITY, GRAPHIC_ALPHA_OPACITY); + + fb_graphics_set_layer_galpha(disp_layer, GRAPHIC_ALPHA_OPACITY); + + fb_graphics_set_csc_coef(disp_layer); + + fb_graphics_set_csc_en(disp_layer, TD_TRUE); + + return TD_SUCCESS; +} + +td_s32 gfbg_drv_set_layer_addr(td_u32 layer_id, td_phys_addr_t addr) +{ + if (fb_graphics_set_gfx_addr(g_gfbglayer_to_hwlayer[layer_id], addr) != TD_SUCCESS) { + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +td_s32 gfbg_drv_get_layer_addr(td_u32 layer_id, td_phys_addr_t *phys_addr) +{ + if (fb_graphics_get_gfx_addr(g_gfbglayer_to_hwlayer[layer_id], phys_addr) != TD_SUCCESS) { + return TD_FAILURE; + } + + return TD_SUCCESS; +} + + +td_s32 gfbg_drv_set_layer_stride(td_u32 layer_id, td_u32 stride) +{ + if (fb_graphics_set_gfx_stride(g_gfbglayer_to_hwlayer[layer_id], stride) != TD_SUCCESS) { + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +td_s32 gfbg_drv_set_layer_alpha(td_u32 layer_id, ot_fb_alpha alpha) +{ + td_u32 pre_mult_mode = 0; + hal_disp_layer disp_layer; + + if (layer_id >= GFBG_MAX_LAYER_NUM) { + return TD_FAILURE; + } + + disp_layer = g_gfbglayer_to_hwlayer[layer_id]; + /* When the premultiply is enabled, the global alpha cannot be 1 */ + if (alpha.global_alpha == 1) { + if (fb_graphics_get_gfx_pre_mult(disp_layer, &pre_mult_mode) != TD_SUCCESS) { + return TD_FAILURE; + } + if (pre_mult_mode == 1) { + gfbg_error("the global alpha can not set to 1 when the pre-mult mode is enable\n"); + return TD_FAILURE; + } + } + if (alpha.global_alpha_en) { + fb_graphics_set_layer_galpha(g_gfbglayer_to_hwlayer[layer_id], alpha.global_alpha); + } else { + fb_graphics_set_layer_galpha(g_gfbglayer_to_hwlayer[layer_id], GRAPHIC_ALPHA_OPACITY); + } + + fb_graphics_set_gfx_palpha(g_gfbglayer_to_hwlayer[layer_id], alpha.pixel_alpha, TD_TRUE, + alpha.alpha0, alpha.alpha1); + + return TD_SUCCESS; +} +td_s32 gfbg_drv_set_layer_fmt_clut_check(hal_disp_layer disp_layer) +{ +#ifndef CONFIG_CHIP_GFBG_SUPPORT_G3 + if (disp_layer != HAL_DISP_LAYER_GFX0) { + gfbg_error("GFBG does not support clut2/clut4 except gfx0\n"); + return TD_FAILURE; + } +#else + if (disp_layer != HAL_DISP_LAYER_GFX3 && disp_layer != HAL_DISP_LAYER_GFX4) { + gfbg_error("GFBG does not support clut2/clut4 except gfx3 or gfx4\n"); + return TD_FAILURE; + } +#endif + + return TD_SUCCESS; +} + +td_s32 gfbg_drv_set_layer_data_fmt(td_u32 layer_id, ot_fb_color_format data_format) +{ + gfbg_disp_pixel_format pixel_format_for_hal; + hal_disp_layer disp_layer = g_gfbglayer_to_hwlayer[layer_id]; + + switch (data_format) { + case OT_FB_FORMAT_ARGB1555: { + pixel_format_for_hal = GFBG_INPUTFMT_ARGB_1555; + /* Pre-multiply enable is not supported when the data format is ARGB1555 */ + fb_graphics_set_gfx_pre_mult(disp_layer, TD_FALSE); + break; + } + + case OT_FB_FORMAT_ARGB8888: { + pixel_format_for_hal = GFBG_INPUTFMT_ARGB_8888; + break; + } + + case OT_FB_FORMAT_ARGB4444: { + pixel_format_for_hal = GFBG_INPUTFMT_ARGB_4444; + break; + } + + case OT_FB_FORMAT_4BPP: { + if (gfbg_drv_set_layer_fmt_clut_check(disp_layer) != TD_SUCCESS) { + return TD_FAILURE; + } + pixel_format_for_hal = GFBG_INPUTFMT_CLUT_4BPP; + break; + } + + case OT_FB_FORMAT_2BPP: { + if (gfbg_drv_set_layer_fmt_clut_check(disp_layer) != TD_SUCCESS) { + return TD_FAILURE; + } + pixel_format_for_hal = GFBG_INPUTFMT_CLUT_2BPP; + break; + } + default: { + gfbg_error("GFBG does not support this color format\n"); + return TD_FAILURE; + } + } + + if (fb_graphics_set_layer_data_fmt(disp_layer, pixel_format_for_hal) != TD_SUCCESS) { + return TD_FAILURE; + } + return TD_SUCCESS; +} + +td_s32 gfbg_drv_set_layer_src_image_reso(td_u32 disp_layer, const ot_fb_rect *rect) +{ + ot_fb_rect gfbg_rect = {0}; + + if (rect == TD_NULL) { + return TD_FAILURE; + } + gfbg_rect.x = rect->x; + gfbg_rect.y = rect->y; + gfbg_rect.width = rect->width; + gfbg_rect.height = rect->height; + if (fb_graphics_set_layer_src_image_reso(g_gfbglayer_to_hwlayer[disp_layer], &gfbg_rect) != TD_SUCCESS) { + return TD_FAILURE; + } + return TD_SUCCESS; +} + +td_s32 gfbg_drv_set_layer_rect(td_u32 layer_id, const ot_fb_rect *input_rect, const ot_fb_rect *output_rect) +{ + ot_fb_rect rect; + fb_scan_mode scan_mode = 0; + td_bool is_field_update; + ot_unused(input_rect); + + if (output_rect == TD_NULL) { + return TD_FAILURE; + } + + rect.x = output_rect->x; + rect.y = output_rect->y; + rect.width = output_rect->width; + rect.height = output_rect->height; + if (layer_id >= GFBG_MAX_LAYER_NUM) { + gfbg_error("layer_id(%u) is invalid\n", layer_id); + return TD_FAILURE; + } + if (fb_graphics_get_dev_mode(g_gfbglayer_to_hwlayer[layer_id], &scan_mode, &is_field_update) != TD_SUCCESS) { + return TD_FAILURE; + } + + if (scan_mode == FB_SCAN_MODE_INTERLACE) { + /* When interlaced display, the ordinate and height are required to be even */ + if ((((td_u32)rect.y & 0x1) == 1) || (((td_u32)rect.height & 0x1) == 1)) { + gfbg_error("the height must be even for interlaced device\n"); + return TD_FAILURE; + } + } + + fb_graphics_set_layer_out_rect(g_gfbglayer_to_hwlayer[layer_id], &rect); + + fb_graphics_set_layer_in_rect(g_gfbglayer_to_hwlayer[layer_id], &rect); + + return TD_SUCCESS; +} + +static td_s32 gfbg_drv_set_lay_key_mask(td_u32 layer_id, const gfbg_colorkeyex *colorkey) +{ + fb_gfx_key_max max_rgb; + fb_gfx_key_min min_rgb; + fb_gfx_mask mask_rgb; + hal_disp_layer disp_layer = g_gfbglayer_to_hwlayer[layer_id]; + + if (colorkey->key_enable) { + if (fb_graphics_set_gfx_key_mode(disp_layer, colorkey->key_mode) != TD_SUCCESS) { + return TD_FAILURE; + } + + max_rgb.key_max_r = colorkey->red_max; + max_rgb.key_max_g = colorkey->green_max; + max_rgb.key_max_b = colorkey->blue_max; + + min_rgb.key_min_r = colorkey->red_min; + min_rgb.key_min_g = colorkey->green_min; + min_rgb.key_min_b = colorkey->blue_min; + + fb_graphics_set_color_key_value(disp_layer, max_rgb, min_rgb); + if (colorkey->mask_enable) { + mask_rgb.mask_r = colorkey->red_mask; + mask_rgb.mask_g = colorkey->green_mask; + mask_rgb.mask_b = colorkey->blue_mask; + } else { + mask_rgb.mask_r = 0; + mask_rgb.mask_g = 0; + mask_rgb.mask_b = 0; + } + fb_graphics_set_color_key_mask(disp_layer, mask_rgb); + } + + if (fb_graphics_set_gfx_key_en(disp_layer, colorkey->key_enable) != TD_SUCCESS) { + return TD_FAILURE; + } + + return TD_FAILURE; +} + +td_s32 gfbg_drv_color_convert(const struct fb_var_screeninfo *var, gfbg_colorkeyex *ck_ex) +{ + td_u8 r, g, b; + td_u32 value; + td_u8 red_mask, green_mask, blue_mask; + + if (var == TD_NULL || ck_ex == TD_NULL) { + return TD_FAILURE; + } + value = ck_ex->key; + + r = (value >> var->red.offset) << (8 - var->red.length); /* 8 bit width */ + g = (value >> var->green.offset) << (8 - var->green.length); /* 8 bit width */ + b = (value >> var->blue.offset) << (8 - var->blue.length); /* 8 bit width */ + + red_mask = (0xff >> var->red.length); + green_mask = (0xff >> var->green.length); + blue_mask = (0xff >> var->blue.length); + + ck_ex->blue_min = b; + ck_ex->green_min = g; + ck_ex->red_min = r; + + ck_ex->blue_max = b | blue_mask; + ck_ex->green_max = g | blue_mask; + ck_ex->red_max = r | blue_mask; + + /* low bits not using when do compare, after extend bits */ + ck_ex->red_mask = ~red_mask; + ck_ex->green_mask = ~green_mask; + ck_ex->blue_mask = ~blue_mask; + + ck_ex->key_mode = 0; + + ck_ex->mask_enable = TD_TRUE; + + return TD_SUCCESS; +} + +td_s32 gfbg_drv_updata_layer_reg(td_u32 layer_id) +{ + if (fb_graphics_set_reg_up(g_gfbglayer_to_hwlayer[layer_id]) != TD_SUCCESS) { + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +td_s32 gfbg_drv_set_color_reg(td_u32 layer_id, td_u32 offset, td_u32 color, td_s32 up_flag) +{ + td_u32 *clut_table = TD_NULL; + gfbg_mmz_buffer *clut_table_addr = TD_NULL; + +#ifdef CONFIG_TDE_CLUT_RECT_SUPPORT_G0 + /* G0 support clut */ + if (layer_id != GRAPHICS_LAYER_G0) { + return TD_FAILURE; + } +#else + /* only G3 or G4 support clut */ + if ((layer_id != GRAPHICS_LAYER_G3) && (layer_id != GRAPHICS_LAYER_G4)) { + return TD_FAILURE; + } +#endif +#ifdef CONFIG_TDE_CLUT_RECT_SUPPORT_G0 + if (layer_id == GRAPHICS_LAYER_G0) { + clut_table_addr = graphic_drv_get_clut_table_g0(); + if (clut_table_addr == TD_NULL) { + return TD_FAILURE; + } + } +#else + if (layer_id == GRAPHICS_LAYER_G3) { + clut_table_addr = graphic_drv_get_clut_table_g3(); + if (clut_table_addr == TD_NULL) { + return TD_FAILURE; + } + } +#endif +#ifdef CONFIG_TDE_CLUT_RECT_SUPPORT_G4 + if (layer_id == GRAPHICS_LAYER_G4) { + clut_table_addr = graphic_drv_get_clut_table_g4(); + if (clut_table_addr == TD_NULL) { + return TD_FAILURE; + } + } +#endif + if (clut_table_addr == TD_NULL || clut_table_addr->start_vir_addr == TD_NULL) { + return TD_FAILURE; + } + clut_table = (td_u32 *)(clut_table_addr->start_vir_addr); + if (clut_table == TD_NULL) { + return TD_FAILURE; + } + + if (offset < 256) { /* 256 for clut table max */ + clut_table[offset] = color; + } + + if (up_flag != 0) { + fb_graphics_set_color_reg(layer_id, clut_table_addr->start_phy_addr); + } + + return TD_SUCCESS; +} + +td_void gfbg_drv_set_color_reg_up(td_u32 layer_id) +{ + fb_graphics_set_color_reg_up(layer_id); +} + +td_s32 gfbg_drv_init(td_void) +{ + td_s32 ret; + ot_tde_export_func *tde_export_func = TD_NULL; + + tde_export_func = func_entry(ot_tde_export_func, OT_ID_TDE); + if ((tde_export_func == TD_NULL) || (tde_export_func->drv_tde_module_open == TD_NULL) || + (tde_export_func->drv_tde_module_close == TD_NULL)) { + gfbg_error("TDE tde_export_func is NULL!\n"); + return TD_FAILURE; + } else { + ret = tde_export_func->drv_tde_module_open(); + if (ret != TD_SUCCESS) { + gfbg_error("TDE open failed\n"); + return ret; + } + } + + ret = fb_graphics_resource_init(); + if (ret != TD_SUCCESS) { + tde_export_func->drv_tde_module_close(); + gfbg_error("resource init failed\n"); + return ret; + } + + return TD_SUCCESS; +} + +td_s32 gfbg_drv_deinit(td_void) +{ + ot_tde_export_func *tde_export_func = TD_NULL; + fb_graphics_resource_deinit(); + + tde_export_func = func_entry(ot_tde_export_func, OT_ID_TDE); + if ((tde_export_func == TD_NULL) || (tde_export_func->drv_tde_module_close == TD_NULL)) { + gfbg_error("TDE tde_export_func is NULL!\n"); + return TD_FAILURE; + } + tde_export_func->drv_tde_module_close(); + + return TD_SUCCESS; +} + +/* set premul data */ +td_s32 gfbg_drv_set_pre_mul(td_u32 layer_id, td_bool is_premul) +{ + hal_disp_pixel_format format = HAL_INPUTFMT_ARGB_1555; + hal_disp_layer layer = g_gfbglayer_to_hwlayer[layer_id]; + td_u8 global_alpha; + + if (is_premul == TD_TRUE) { + /* When the global alpha configuration is 1, pre-multiplication cannot be enabled. */ + if (fb_graphics_get_layer_galpha(layer, &global_alpha) != TD_SUCCESS) { + return TD_FAILURE; + } + if (global_alpha == 1) { + gfbg_error("not allow to set pre-mult mode when the GlobalAlpha is 1\n"); + return TD_FAILURE; + } + + /* Pre-multiply enable is not supported when the data format is ARGB1555 */ + if (fb_graphics_get_layer_data_fmt(layer, &format) != TD_SUCCESS) { + return TD_FAILURE; + } + if ((format == HAL_INPUTFMT_ARGB_1555) || (format == HAL_INPUTFMT_ARGB_4444)) { + gfbg_error("not allow to set pre-mult mode when the color format is ARGB1555 or ARGB4444\n"); + return TD_FAILURE; + } + } + + if (fb_graphics_set_gfx_pre_mult(layer, is_premul) != TD_SUCCESS) { + return TD_FAILURE; + } + return TD_SUCCESS; +} + +td_s32 gfbg_drv_set_int_callback(gfbg_int_type int_type, int_vo_callback callback, td_u32 layer_id, td_void *arg) +{ + if (layer_id >= GFBG_MAX_LAYER_NUM) { + return TD_FAILURE; + } + + return fb_graphics_set_callback(g_gfbglayer_to_hwlayer[layer_id], int_type, (vo_fb_intcallback)callback, arg); +} + +/* The premise is that the VO device is enabled and an error is returned when the VO device is not enabled. +For X5HD, the current configuration content of the graphics layer is obtained for the boot screen; +since the boot screen is not required, only the device resolution and scan information +can be obtained. */ +td_s32 gfbg_drv_get_osd_data(td_u32 layer_id, gfbg_osd_data *layer_data) +{ + td_u32 width = 0; + td_u32 height = 0; + td_s32 ret; + hal_disp_layer disp_layer = g_gfbglayer_to_hwlayer[layer_id]; + fb_scan_mode scan_mode = 0; + + if (layer_data == TD_NULL) { + return TD_FAILURE; + } + + ret = fb_graphics_get_intf_size(disp_layer, &width, &height); + if (ret != TD_SUCCESS) { + gfbg_error("Failed to get screen width and height!\n"); + return TD_FAILURE; + } + + ret = fb_graphics_get_gfx_addr(disp_layer, &layer_data->buffer_phy_addr); + if (ret != TD_SUCCESS) { + return TD_FAILURE; + } + + ret = fb_graphics_get_gfx_stride(disp_layer, &layer_data->stride); + if (ret != TD_SUCCESS) { + return TD_FAILURE; + } + + ret = fb_graphics_get_dev_mode(disp_layer, &scan_mode, &layer_data->feild_update); + if (ret != TD_SUCCESS) { + return TD_FAILURE; + } + if (scan_mode == FB_SCAN_MODE_INTERLACE) { + layer_data->scan_mode = GFBG_SCANMODE_I; + } else { + layer_data->scan_mode = GFBG_SCANMODE_P; + } + + layer_data->screen_height = height; + layer_data->screen_width = width; + + return TD_SUCCESS; +} + +td_s32 gfbg_open_layer(td_u32 layer_id) +{ + return fb_graphics_open_layer(g_gfbglayer_to_hwlayer[layer_id]); +} + +td_s32 gfbg_close_layer(td_u32 layer_id) +{ + return fb_graphics_close_layer(g_gfbglayer_to_hwlayer[layer_id]); +} + +td_s32 gfbg_drv_enable_dcmp(td_u32 layer_id, td_bool enable) +{ + return fb_graphics_enable_dcmp(g_gfbglayer_to_hwlayer[layer_id], enable); +} + +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC +td_s32 gfbg_drv_get_dcmp_enable_state(td_u32 layer_id, td_bool *enable) +{ + return fb_graphics_get_dcmp_enable_state(g_gfbglayer_to_hwlayer[layer_id], enable); +} +#endif + +#ifndef CONFIG_COMPRESS_ECONOMIZE_MEMERY +static td_u32 gfbg_drv_get_hdcmp_stride(const gfbg_graphic_dcmp_info *dcmp_info) +{ + td_u32 comp_ratio_int = 1000; /* 1000 for calculate cmp */ + td_u32 byte_per_pix; + td_u32 extend_width; + td_u32 exp_num_temp = 0; + td_u32 stride = dcmp_info->stride; + + if (dcmp_info->pixel_fmt == GFBG_INPUTFMT_ARGB_8888) { + if (dcmp_info->width <= 320) { /* 320 width */ + exp_num_temp = 2; /* 2 for calculate cmp */ + comp_ratio_int = 1000; /* 1000 for calculate cmp */ + } else if (dcmp_info->width <= 720) { /* 720 width */ + exp_num_temp = 10; /* 10 for calculate cmp */ + comp_ratio_int = 2000; /* 2000 for calculate cmp */ + } else if (dcmp_info->width <= 3840) { /* 3840 width */ + exp_num_temp = 10; /* 10 for calculate cmp */ + comp_ratio_int = 2000; /* 2000 for calculate cmp */ + } + + byte_per_pix = 4; /* 4 for calculate cmp */ + /* 8 bits, 1000 for calculate 127,128,16 for align */ + stride = ((dcmp_info->width * byte_per_pix * 8 * 1000 / comp_ratio_int + 127) / 128 + exp_num_temp) * 16; + } else if ((dcmp_info->pixel_fmt == GFBG_INPUTFMT_ARGB_1555) || + (dcmp_info->pixel_fmt == GFBG_INPUTFMT_ARGB_4444)) { + if (dcmp_info->width <= 720) { /* 720 width */ + exp_num_temp = 2; /* 2 for calculate cmp */ + comp_ratio_int = 1000; /* 1000 for calculate cmp */ + } else if (dcmp_info->width <= 3840) { /* 3840 width */ + exp_num_temp = 0; + comp_ratio_int = 1000; /* 1000 for calculate cmp */ + } + byte_per_pix = 2; /* 2 for calculate cmp */ + + extend_width = ((dcmp_info->width + 31) / 32) * 32; /* 31 32 for calculate cmp */ + /* 8 bits, 1000 for calculate 127,128,16 for align */ + stride = ((extend_width * byte_per_pix * 8 * 1000 / comp_ratio_int + 127) / 128 + exp_num_temp) * 16; + } + + stride = (stride + 0xf) & 0xfffffff0; /* 0xf 0xfffffff0 for calculate cmp */ + + return stride; +} +#endif + +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC +static td_s32 gfbg_drv_set_dcmp_info(td_u32 layer_id, gfbg_graphic_dcmp_info *dcmp_info) +{ + /* line compress need to re calculate the stride */ +#ifndef CONFIG_COMPRESS_ECONOMIZE_MEMERY + dcmp_info->stride = gfbg_drv_get_hdcmp_stride(dcmp_info); +#else + gfbg_stride_attr attr = {0}; + attr.is_lossless = TD_FALSE; + attr.is_losslessa = TD_FALSE; + attr.width = dcmp_info->width; + + if (dcmp_info->pixel_fmt == GFBG_INPUTFMT_ARGB_8888) { + attr.format = OT_FB_FORMAT_ARGB8888; + } else if (dcmp_info->pixel_fmt == GFBG_INPUTFMT_ARGB_1555) { + attr.format = OT_FB_FORMAT_ARGB1555; + } else if (dcmp_info->pixel_fmt == GFBG_INPUTFMT_ARGB_4444) { + attr.format = OT_FB_FORMAT_ARGB4444; + } else { + attr.format = OT_FB_FORMAT_ARGB1555; + } + gfbg_recalculate_stride(&dcmp_info->stride, NULL, &attr); +#endif + return fb_graphics_set_dcmp_info(g_gfbglayer_to_hwlayer[layer_id], dcmp_info); +} + +td_bool gfbg_drv_is_layer_support_zoom_out(td_u32 layer_id) +{ + ot_unused(layer_id); + return TD_FALSE; +} +#endif + +td_s32 gfbg_drv_enable_zme(td_u32 layer_id, const ot_fb_rect *in_rect, const ot_fb_rect *out_rect, td_bool enable) +{ + ot_fb_rect inner_rect; + ot_fb_rect outer_rect; + + if (in_rect == TD_NULL || out_rect == TD_NULL) { + return TD_FAILURE; + } + inner_rect.width = in_rect->width; + inner_rect.height = in_rect->height; + outer_rect.width = out_rect->width; + outer_rect.height = out_rect->height; + + if (g_gfbglayer_to_hwlayer[layer_id] == HAL_DISP_LAYER_GFX0) { + return fb_graphics_enable_zme(g_gfbglayer_to_hwlayer[layer_id], &inner_rect, &outer_rect, enable); + } else { +#ifdef CONFIG_GFBG_G1_SUPPORT_ZME + if (g_gfbglayer_to_hwlayer[layer_id] == HAL_DISP_LAYER_GFX1) { + /* fb_graphics_enable_zme */ + return fb_graphics_enable_zme(g_gfbglayer_to_hwlayer[layer_id], &inner_rect, &outer_rect, enable); + } +#endif + if (enable) { + gfbg_error("G%u does not support zme.\n", layer_id); + } + return TD_SUCCESS; + } +} + +td_s32 gfbg_drv_graphics_get_int(td_u32 *int_status) +{ + return fb_graphics_get_int(int_status); +} + +static td_s32 gfbg_drv_graphics_get_interrupt_dev(td_u32 int_status, ot_vo_dev *vo_dev) +{ + return fb_graphics_get_interrupt_dev(int_status, vo_dev); +} + +td_void gfbg_drv_set_tde_sync(td_u32 layer_id, const gfbg_sync_attr *sync_info) +{ +#ifdef CONFIG_GFBG_LOW_DELAY_SUPPORT + gfbg_bind_tde_cfg bind_tde_cfg = {0}; + + if (sync_info == TD_NULL) { + return; + } + + if (g_gfbglayer_to_hwlayer[layer_id] != HAL_DISP_LAYER_GFX0) { + return; + } + + bind_tde_cfg.is_hw_mute_clr_en = 0; + bind_tde_cfg.is_mute_en = 0; + bind_tde_cfg.safe_dist = sync_info->safe_dist; + bind_tde_cfg.is_sync = sync_info->is_sync; + fb_graphics_set_tde_sync(&bind_tde_cfg); + return; +#else + ot_unused(layer_id); + ot_unused(sync_info); + return; +#endif +} + +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC +static td_s32 drv_gfbg_check_frame_param(const ot_fb_smart_rect_param *param, td_u32 i, td_u32 max_width, + td_u32 max_height) +{ + if ((param->rect_start[i].rect.width <= 0) || (param->rect_start[i].rect.height <= 0) || + (param->rect_start[i].rect.x < 0) || (param->rect_start[i].rect.y < 0)) { + gfbg_error("invalid i:%d, x:%d, y:%d, w:%d, h:%d\n", i, param->rect_start[i].rect.x, + param->rect_start[i].rect.y, param->rect_start[i].rect.width, param->rect_start[i].rect.height); + return TD_FAILURE; + } + if ((param->rect_start[i].rect.x > (td_s32)(max_width - 1)) || + (param->rect_start[i].rect.y > (td_s32)(max_height - 1)) || + ((param->rect_start[i].rect.x + param->rect_start[i].rect.width - 1) > (td_s32)(max_width - 1)) || + ((param->rect_start[i].rect.y + param->rect_start[i].rect.height - 1) > (td_s32)(max_height - 1))) { + gfbg_error("invalid i:%d, x:%d, y:%d, w:%d, h:%d, max_w:%u, max_height:%u\n", i, param->rect_start[i].rect.x, + param->rect_start[i].rect.y, param->rect_start[i].rect.width, param->rect_start[i].rect.height, + max_width, max_height); + return TD_FAILURE; + } + if (param->rect_start[i].mode == OT_FB_SMART_RECT_SOLID) { + if ((param->rect_start[i].rect.width < (td_s32)(param->rect_start[i].thick * 2)) || /* 2 double */ + (param->rect_start[i].rect.height < (td_s32)(param->rect_start[i].thick * 2)) || /* 2 double */ + (param->rect_start[i].thick > 32)) { /* 32 max */ + gfbg_error("invalid i:%d, w:%d, h:%d, thick:%u, thick_max:32\n", i, param->rect_start[i].rect.width, + param->rect_start[i].rect.height, param->rect_start[i].thick); + return TD_FAILURE; + } + } + if (param->rect_start[i].mode == OT_FB_SMART_RECT_CORNER) { + if ((param->rect_start[i].rect.width < (td_s32)(param->rect_start[i].thick * 2)) || /* 2 double */ + (param->rect_start[i].rect.height < (td_s32)(param->rect_start[i].thick * 2)) || /* 2 double */ + (param->rect_start[i].rect.width < (td_s32)(param->rect_start[i].corner_length * 2)) || /* 2 double */ + (param->rect_start[i].rect.height < (td_s32)(param->rect_start[i].corner_length * 2)) || + (param->rect_start[i].thick > 32) || (param->rect_start[i].corner_length > 255)) { /* 32 255 max */ + gfbg_error("invalid i:%d, w:%d, h:%d; thick:%u, corner_length:%u, thick_max:32, corner_length_max:255\n", i, + param->rect_start[i].rect.width, param->rect_start[i].rect.height, param->rect_start[i].thick, + param->rect_start[i].corner_length); + return TD_FAILURE; + } + } + return TD_SUCCESS; +} + +td_s32 gfbg_drv_set_smart_rect(td_u32 layer_id, td_u32 max_width, td_u32 max_height, + const ot_fb_smart_rect_param *param, const gfbg_mmz_buffer *osb_chn) +{ + td_u32 i, j; + td_u32 *vir = TD_NULL; + td_u32 alpha, red, green, blue, length, thick, mode; + td_u32 hor_start, hor_end, ver_start, ver_end; + /* only G3 or G4 support clut */ + if ((layer_id != GRAPHICS_LAYER_G3) && (layer_id != GRAPHICS_LAYER_G4)) { + gfbg_error("only G3 or G4 support smart rect\n"); + return TD_FAILURE; + } + if (osb_chn == TD_NULL || param == TD_NULL || param->rect_start == TD_NULL) { + return TD_FAILURE; + } + vir = (td_u32 *)(osb_chn->start_vir_addr); + if (vir == TD_NULL) { + return TD_FAILURE; + } + (td_void)memset_s(vir, osb_chn->size, 0, osb_chn->size); + for (i = 0; i < param->num; i++) { + if (drv_gfbg_check_frame_param(param, i, max_width, max_height)) { + return TD_FAILURE; + } + j = 4 * i; /* 4 part */ + alpha = (param->rect_start[i].color_value & 0xf0000000) >> 28; /* 28 29~32bits */ + red = (param->rect_start[i].color_value & 0x00f00000) >> 20; /* 20 21~24bits */ + green = (param->rect_start[i].color_value & 0x0000f000) >> 12; /* 12 13~16bits */ + blue = (param->rect_start[i].color_value & 0x000000f0) >> 4; /* 4 5~8bits */ + length = (param->rect_start[i].corner_length & 0x000000ff); /* 0x000000ff low 8bits */ + thick = (param->rect_start[i].thick & 0x3f); /* 0x20 max 32 */ + mode = (param->rect_start[i].mode); + /* 28,24,20,16,8 for alg data */ + vir[j] = (alpha << 28) | (red << 24) | (green << 20) | (blue << 16) | (length << 8) | (thick << 2) | + (mode); /* 2 for alg data */ + + hor_start = (td_u32)(param->rect_start[i].rect.x) & 0xfff; + hor_end = (td_u32)(param->rect_start[i].rect.x + param->rect_start[i].rect.width - 1) & 0xfff; + ver_start = (td_u32)(param->rect_start[i].rect.y) & 0xfff; + ver_end = (td_u32)(param->rect_start[i].rect.y + param->rect_start[i].rect.height - 1) & 0xfff; + + vir[j + 1] = (hor_end << 16) | (hor_start); /* 16 for alg data */ + vir[j + 2] = (ver_end << 16) | (ver_start); /* 2 16 for alg data */ + } + fb_graphics_set_frame_reg(layer_id, osb_chn->start_phy_addr); + + return TD_SUCCESS; +} + +td_void gfbg_drv_smart_rect_up_param(td_u32 layer_id) +{ + fb_graphics_up_frame_param(layer_id); +} +#endif + +td_void gfbg_close_smart_rect(td_u32 layer_id) +{ + if ((layer_id != GRAPHICS_LAYER_G3) && (layer_id != GRAPHICS_LAYER_G4)) { + return; + } +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC + fb_graphics_up_frame_param(layer_id); + fb_graphics_close_smart_rect(layer_id); + return; +#endif +} + +static td_void get_implement_ops(gfbg_drv_ops *ops) +{ + ops->gfbg_drv_init = gfbg_drv_init; + ops->gfbg_drv_deinit = gfbg_drv_deinit; + ops->gfbg_drv_set_layer_enable = gfbg_drv_set_layer_enable; +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC + ops->gfbg_drv_get_layer_enable = gfbg_drv_get_layer_enable; +#endif + ops->gfbg_drv_layer_default_setting = gfbg_drv_layer_default_setting; + ops->gfbg_drv_set_layer_addr = gfbg_drv_set_layer_addr; + ops->gfbg_drv_get_layer_addr = gfbg_drv_get_layer_addr; + ops->gfbg_drv_set_layer_stride = gfbg_drv_set_layer_stride; + ops->gfbg_drv_set_layer_alpha = gfbg_drv_set_layer_alpha; + ops->gfbg_drv_set_layer_data_fmt = gfbg_drv_set_layer_data_fmt; + ops->gfbg_drv_set_layer_rect = gfbg_drv_set_layer_rect; + ops->gfbg_drv_set_layer_src_image_reso = gfbg_drv_set_layer_src_image_reso; + ops->gfbg_drv_set_layer_key_mask = gfbg_drv_set_lay_key_mask; + ops->gfbg_drv_color_convert = gfbg_drv_color_convert; + ops->gfbg_drv_updata_layer_reg = gfbg_drv_updata_layer_reg; + ops->gfbg_drv_set_int_callback = gfbg_drv_set_int_callback; + ops->gfbg_drv_set_color_reg = gfbg_drv_set_color_reg; + ops->gfbg_drv_set_color_reg_up = gfbg_drv_set_color_reg_up; + ops->gfbg_drv_set_pre_mul = gfbg_drv_set_pre_mul; + ops->gfbg_drv_set_clut_addr = TD_NULL; + ops->gfbg_drv_get_osd_data = gfbg_drv_get_osd_data; + ops->gfbg_drv_open_display = TD_NULL; + ops->gfbg_drv_close_display = TD_NULL; + ops->gfbg_open_layer = gfbg_open_layer; + ops->gfbg_close_layer = gfbg_close_layer; + ops->gfbg_drv_enable_dcmp = gfbg_drv_enable_dcmp; + ops->gfbg_close_smart_rect = gfbg_close_smart_rect; +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC + ops->gfbg_drv_set_dcmp_info = gfbg_drv_set_dcmp_info; + ops->gfbg_drv_get_dcmp_enable_state = gfbg_drv_get_dcmp_enable_state; +#endif + return; +} + +static td_void gfbg_init_gfx_cap(td_void) +{ + /* reset capability */ + +#if defined (CONFIG_CHIP_GFBG_SUPPORT_G3) + g_gfbg_gfx_cap[1].is_decompress = TD_FALSE; /* 1 G1 */ + g_gfbg_gfx_cap[2].is_layer_support = TD_FALSE; /* 2 G2 */ + g_gfbg_gfx_cap[4].is_layer_support = TD_FALSE; /* 4 G4 */ + g_vo_gfbg_layer_index = g_vo_gfbg_layer_index_array[1]; +#else + g_gfbg_gfx_cap[0].is_vo_scale = TD_FALSE; /* 0 G0 zme */ + g_gfbg_gfx_cap[0].is_decompress = TD_FALSE; /* 0 G0 decompress */ + g_gfbg_gfx_cap[0].is_cmap = TD_TRUE; /* 0 G0 color map */ + g_gfbg_gfx_cap[0].is_color_format[OT_FB_FORMAT_2BPP] = TD_TRUE; /* 0 G0 clut2 */ + g_gfbg_gfx_cap[0].is_color_format[OT_FB_FORMAT_4BPP] = TD_TRUE; /* 0 G0 clut4 */ + g_gfbg_gfx_cap[1].is_layer_support = TD_FALSE; /* 1 G1 */ + g_gfbg_gfx_cap[2].is_layer_support = TD_FALSE; /* 2 G2 */ + g_gfbg_gfx_cap[3].is_layer_support = TD_FALSE; /* 3 G3 */ + g_gfbg_gfx_cap[4].is_layer_support = TD_FALSE; /* 4 G4 */ + g_vo_gfbg_layer_index = g_vo_gfbg_layer_index_array[0]; +#endif + return; +} + +td_void gfbg_drv_get_ops(gfbg_drv_ops *ops) +{ + ops->layer_count = GFBG_MAX_LAYER_NUM; + /* check if support G1 */ + gfbg_init_gfx_cap(); + ops->capability = (ot_fb_capability *)g_gfbg_gfx_cap; + + /* implement */ + get_implement_ops(ops); + /* For ZME */ + ops->gfbg_drv_enable_zme = gfbg_drv_enable_zme; +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC + ops->gfbg_drv_is_layer_support_zoom_out = gfbg_drv_is_layer_support_zoom_out; +#endif + /* for Int */ + ops->gfbg_drv_graphics_enable_int = TD_NULL; + ops->gfbg_drv_graphics_clear_int = TD_NULL; + ops->gfbg_drv_graphics_get_int = gfbg_drv_graphics_get_int; + ops->gfbg_drv_graphics_clear_int_status = TD_NULL; + ops->gfbg_drv_graphics_get_int_dev = gfbg_drv_graphics_get_interrupt_dev; + /* for low delay */ + ops->gfbg_drv_set_tde_sync = gfbg_drv_set_tde_sync; +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC + /* for smart rect */ + ops->gfbg_drv_set_smart_rect = gfbg_drv_set_smart_rect; + ops->gfbg_drv_smart_rect_up_param = gfbg_drv_smart_rect_up_param; +#endif +} diff --git a/kernel/gfbg/hi3519dv500/drv/adp/gfbg_graphic_hal.c b/kernel/gfbg/hi3519dv500/drv/adp/gfbg_graphic_hal.c new file mode 100755 index 00000000..3d7c5e4a --- /dev/null +++ b/kernel/gfbg/hi3519dv500/drv/adp/gfbg_graphic_hal.c @@ -0,0 +1,2807 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "gfbg_graphic_hal.h" +#include "ot_osal.h" +#include "ot_debug.h" +#include "gfbg_graphics_drv.h" + +/* MACRO DEFINITION */ +#define HAL_PRINT OT_PRINT + +#define GFBG_REGS_ADDR 0x17A00000 +#define GFBG_REGS_SIZE 0x40000 + +#define GFBG_FMT_CLUT_LAYER_G0 0 +#define GFBG_FMT_CLUT_LAYER_G3 3 +#define GFBG_FMT_CLUT_LAYER_G4 4 + +#define SMART_RECT_LAYER_G3 3 +#define SMART_RECT_LAYER_G4 4 + +volatile vdp_regs_type *g_gfbg_reg = TD_NULL; + +__inline static td_u32 get_low_addr(td_phys_addr_t phys_addr) +{ + return (td_u32)phys_addr; +} + +__inline static td_u32 get_high_addr(td_phys_addr_t phys_addr) +{ + td_u32 low_width = 32; /* 32bit low addr */ + return (sizeof(phys_addr) > (low_width / 8)) ? (td_u32)(phys_addr >> low_width) : 0; /* 8 bits per byte */ +} + + +td_s32 fb_hal_gfbg_init(td_void) +{ + if (g_gfbg_reg == TD_NULL) { + g_gfbg_reg = (volatile vdp_regs_type *)osal_ioremap(GFBG_REGS_ADDR, (td_u32)GFBG_REGS_SIZE); + } + + if (g_gfbg_reg == TD_NULL) { + osal_printk("ioremap_nocache failed\n"); + return TD_FAILURE; + } + return TD_SUCCESS; +} + +td_void fb_hal_gfbg_deinit(td_void) +{ + if (g_gfbg_reg != TD_NULL) { + osal_iounmap((void *)g_gfbg_reg, GFBG_REGS_SIZE); + g_gfbg_reg = TD_NULL; + } +} + +static td_void fb_hal_write_reg(td_u32 *address, td_u32 value) +{ + if (address == TD_NULL) { + return; + } + *(volatile td_u32 *)address = value; + return; +} + +static td_u32 fb_hal_read_reg(const td_u32 *address) +{ + if (address == TD_NULL) { + return 0; + } + return *(volatile td_u32 *)(address); +} + +/***************************************************************************** + Prototype : fb_hal_get_abs_addr + Description : Get the absolute address of the layer (video layer and graphics layer) +*****************************************************************************/ +static td_ulong fb_hal_get_abs_addr(hal_disp_layer layer, td_ulong reg) +{ + td_ulong reg_abs_addr; + + switch (layer) { + case HAL_DISP_LAYER_VHD0: + case HAL_DISP_LAYER_VHD1: + case HAL_DISP_LAYER_VHD2: + reg_abs_addr = (reg) + (layer - HAL_DISP_LAYER_VHD0) * VHD_REGS_LEN; + break; + case HAL_DISP_LAYER_GFX0: + case HAL_DISP_LAYER_GFX1: + case HAL_DISP_LAYER_GFX2: + case HAL_DISP_LAYER_GFX3: + case HAL_DISP_LAYER_GFX4: + reg_abs_addr = (reg) + (layer - HAL_DISP_LAYER_GFX0) * GFX_REGS_LEN; + break; + /* one wbc dev */ + case HAL_DISP_LAYER_WBC: + reg_abs_addr = (reg); + break; + default: + HAL_PRINT("Error channel id found in %s: L%d\n", __FUNCTION__, __LINE__); + return 0; + } + return reg_abs_addr; +} + +/* + * Prototype : fb_hal_get_chn_abs_addr + * Description : Get the absolute address of the video channel + */ +static td_ulong fb_hal_get_chn_abs_addr(hal_disp_outputchannel chan, td_ulong reg) +{ + volatile td_ulong reg_abs_addr; + + switch (chan) { + case HAL_DISP_CHANNEL_DHD0: + case HAL_DISP_CHANNEL_DHD1: + case HAL_DISP_CHANNEL_DSD0: + reg_abs_addr = reg + (chan - HAL_DISP_CHANNEL_DHD0) * DHD_REGS_LEN; + break; + default: + HAL_PRINT("Error channel id found in %s: L%d\n", __FUNCTION__, __LINE__); + return 0; + } + + return reg_abs_addr; +} + +static td_u32 hal_get_addr_chnabs(hal_disp_outputchannel chan, const volatile td_u32 *value) +{ + volatile td_ulong addr_reg; + addr_reg = fb_hal_get_chn_abs_addr(chan, (td_ulong)(uintptr_t)value); + return fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); +} + +static td_u32 hal_get_addr_abs(volatile td_ulong *addr_reg, hal_disp_layer layer, const volatile td_u32 *value) +{ + *addr_reg = fb_hal_get_abs_addr(layer, (td_ulong)(uintptr_t)value); + return fb_hal_read_reg((td_u32 *)(uintptr_t)(*addr_reg)); +} + +static td_ulong fb_hal_get_gfx_abs_addr(hal_disp_layer layer, td_ulong reg) +{ + volatile td_ulong reg_abs_addr; + + switch (layer) { + case HAL_DISP_LAYER_GFX0: + case HAL_DISP_LAYER_GFX1: + case HAL_DISP_LAYER_GFX2: + case HAL_DISP_LAYER_GFX3: + case HAL_DISP_LAYER_GFX4: + reg_abs_addr = reg + (layer - HAL_DISP_LAYER_GFX0) * GRF_REGS_LEN; + break; + + default: + HAL_PRINT("Error layer id found in FUNC:%s,LINE:%d\n", __FUNCTION__, __LINE__); + return 0; + } + + return reg_abs_addr; +} + +td_void fb_hal_disp_get_int_state_vcnt(hal_disp_outputchannel chan, td_u32 *vcnt) +{ + volatile u_dhd0_state dhd0_state; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + switch (chan) { + case HAL_DISP_CHANNEL_DHD0: + case HAL_DISP_CHANNEL_DHD1: + case HAL_DISP_CHANNEL_DSD0:{ + dhd0_state.u32 = hal_get_addr_chnabs(chan, &(g_gfbg_reg->dhd0_state.u32)); + *vcnt = dhd0_state.bits.vcnt; + break; + } + default: { + HAL_PRINT("Error channel id found in %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + } + + return; +} + +td_s32 fb_hal_disp_set_int_mask1(td_u32 mask_en) +{ + volatile u_vointmsk1 vo_intmsk1; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + /* display interrupt mask enable */ + vo_intmsk1.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)&(g_gfbg_reg->vointmsk1.u32)); + vo_intmsk1.u32 = vo_intmsk1.u32 | mask_en; + fb_hal_write_reg((td_u32 *)(uintptr_t)&(g_gfbg_reg->vointmsk1.u32), vo_intmsk1.u32); + return TD_SUCCESS; +} + +td_s32 fb_hal_disp_clr_int_mask1(td_u32 mask_en) +{ + volatile u_vointmsk1 vo_intmsk1; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + /* display interrupt mask enable */ + vo_intmsk1.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)&(g_gfbg_reg->vointmsk1.u32)); + vo_intmsk1.u32 = vo_intmsk1.u32 & (~mask_en); + fb_hal_write_reg((td_u32 *)(uintptr_t)&(g_gfbg_reg->vointmsk1.u32), vo_intmsk1.u32); + return TD_SUCCESS; +} + +/* + * Name : fb_hal_disp_get_intf_enable + * Desc : Get the status (enable,disable status) of display interface. + */ +td_s32 fb_hal_disp_get_intf_enable(hal_disp_outputchannel chan, td_bool *intf_en) +{ + volatile u_dhd0_ctrl dhd0_ctrl; + volatile td_ulong addr_reg; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + switch (chan) { + case HAL_DISP_CHANNEL_DHD0: + case HAL_DISP_CHANNEL_DHD1: + case HAL_DISP_CHANNEL_DSD0: + addr_reg = fb_hal_get_chn_abs_addr(chan, (td_ulong)(uintptr_t)&(g_gfbg_reg->dhd0_ctrl.u32)); + dhd0_ctrl.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + *intf_en = dhd0_ctrl.bits.intf_en; + break; + default: + HAL_PRINT("Error channel id found in %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +td_s32 fb_hal_disp_get_intf_sync(hal_disp_outputchannel chan, hal_disp_syncinfo *sync_info) +{ + volatile u_dhd0_ctrl dhd0_ctrl; + volatile u_dhd0_vsync1 dhd0_vsync1; + volatile u_dhd0_vsync2 dhd0_vsync2; + volatile u_dhd0_hsync1 dhd0_hsync1; + volatile u_dhd0_hsync2 dhd0_hsync2; + volatile u_dhd0_vplus1 dhd0_vplus1; + volatile u_dhd0_vplus2 dhd0_vplus2; + volatile u_dhd0_pwr dhd0_pwr; + if ((g_gfbg_reg == TD_NULL) || (sync_info == TD_NULL)) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + switch (chan) { + case HAL_DISP_CHANNEL_DHD0: + case HAL_DISP_CHANNEL_DHD1: + case HAL_DISP_CHANNEL_DSD0:{ + dhd0_ctrl.u32 = hal_get_addr_chnabs(chan, &(g_gfbg_reg->dhd0_ctrl.u32)); + sync_info->iop = dhd0_ctrl.bits.iop; + + dhd0_hsync1.u32 = hal_get_addr_chnabs(chan, &(g_gfbg_reg->dhd0_hsync1.u32)); + sync_info->hact = dhd0_hsync1.bits.hact + 1; + sync_info->hbb = dhd0_hsync1.bits.hbb + 1; + + dhd0_hsync2.u32 = hal_get_addr_chnabs(chan, &(g_gfbg_reg->dhd0_hsync2.u32)); + sync_info->hmid = (dhd0_hsync2.bits.hmid == 0) ? 0 : (dhd0_hsync2.bits.hmid + 1); + sync_info->hfb = dhd0_hsync2.bits.hfb + 1; + + /* Config VHD interface vertical timing */ + dhd0_vsync1.u32 = hal_get_addr_chnabs(chan, &(g_gfbg_reg->dhd0_vsync1.u32)); + sync_info->vact = dhd0_vsync1.bits.vact + 1; + sync_info->vbb = dhd0_vsync1.bits.vbb + 1; + + dhd0_vsync2.u32 = hal_get_addr_chnabs(chan, &(g_gfbg_reg->dhd0_vsync2.u32)); + sync_info->vfb = dhd0_vsync2.bits.vfb + 1; + + /* Config VHD interface vertical bottom timing,no use in progressive mode */ + dhd0_vplus1.u32 = hal_get_addr_chnabs(chan, &(g_gfbg_reg->dhd0_vplus1.u32)); + sync_info->bvact = dhd0_vplus1.bits.bvact + 1; + sync_info->bvbb = dhd0_vplus1.bits.bvbb + 1; + + dhd0_vplus2.u32 = hal_get_addr_chnabs(chan, &(g_gfbg_reg->dhd0_vplus2.u32)); + sync_info->bvfb = dhd0_vplus2.bits.bvfb + 1; + + /* Config VHD interface vertical bottom timing, */ + dhd0_pwr.u32 = hal_get_addr_chnabs(chan, &(g_gfbg_reg->dhd0_pwr.u32)); + sync_info->hpw = dhd0_pwr.bits.hpw + 1; + sync_info->vpw = dhd0_pwr.bits.vpw + 1; + break; + } + default: { + HAL_PRINT("Error channel id found in %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + } + return TD_SUCCESS; +} + +td_s32 fb_hal_disp_get_intf_mux_sel(hal_disp_outputchannel chan, vo_intf_type *intf_type) +{ + volatile u_vo_mux vo_mux; + if (chan > HAL_DISP_CHANNEL_DSD0) { + HAL_PRINT("Error channel id found in %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + if ((g_gfbg_reg == TD_NULL) || (intf_type == TD_NULL)) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + vo_mux.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->vo_mux.u32)); + + switch (vo_mux.bits.digital_sel) { + case 0: { /* 0 alg data */ + *intf_type = HAL_DISP_INTF_BT1120; + break; + } + case 1: { /* 1 alg data */ + *intf_type = HAL_DISP_INTF_BT656; + break; + } + + default: { + return TD_FAILURE; + } + } + + return TD_SUCCESS; +} + +/***************************************************************************** + Prototype : fb_hal_disp_get_disp_iop + Description : Interlace or Progressive +*****************************************************************************/ +td_s32 fb_hal_disp_get_disp_iop(hal_disp_outputchannel chan, td_bool *iop) +{ + u_dhd0_ctrl dhd0_ctrl; + volatile td_ulong addr_reg; + + if ((g_gfbg_reg == TD_NULL) || (iop == TD_NULL)) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + switch (chan) { + case HAL_DISP_CHANNEL_DHD0: + case HAL_DISP_CHANNEL_DHD1: + case HAL_DISP_CHANNEL_DSD0:{ + addr_reg = fb_hal_get_chn_abs_addr(chan, (td_ulong)(uintptr_t)&(g_gfbg_reg->dhd0_ctrl.u32)); + dhd0_ctrl.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + *iop = dhd0_ctrl.bits.iop; + break; + } + + default: + gfbg_graphics_error("Error channel id found in %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +td_s32 fb_hal_disp_get_vt_thd_mode(hal_disp_outputchannel chan, td_bool *field_mode) +{ + volatile u_dhd0_vtthd dhd0_vtthd; + volatile td_ulong addr_reg; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + switch (chan) { + case HAL_DISP_CHANNEL_DHD0: + case HAL_DISP_CHANNEL_DHD1: + case HAL_DISP_CHANNEL_DSD0: + addr_reg = fb_hal_get_chn_abs_addr(chan, (td_ulong)(uintptr_t)&(g_gfbg_reg->dhd0_vtthd.u32)); + dhd0_vtthd.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + *field_mode = dhd0_vtthd.bits.thd1_mode; + break; + default: + HAL_PRINT("Error channel id found in %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +/* Get interrupt status */ +td_u32 fb_hal_disp_get_int_status(td_u32 int_msk) +{ + volatile u_vomskintsta1 vomskintsta1; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return 0; + } + + /* read interrupt status */ + vomskintsta1.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->vomskintsta1.u32)); + + return (vomskintsta1.u32 & int_msk); +} + +/* + * Name : fb_hal_disp_clear_int_status + * Desc : Clear interrupt status. + */ +td_s32 fb_hal_disp_clear_int_status(td_u32 int_msk) +{ + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + /* read interrupt status */ + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->vomskintsta1.u32), int_msk); + + return TD_SUCCESS; +} + +td_s32 fb_hal_video_set_layer_disp_rect(hal_disp_layer layer, const ot_fb_rect *rect) +{ + volatile u_g0_dfpos g0_dfpos; + volatile u_g0_dlpos g0_dlpos; + volatile td_ulong addr_reg; + + if ((g_gfbg_reg == TD_NULL) || (rect == TD_NULL)) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + switch (layer) { + case HAL_DISP_LAYER_GFX0: + case HAL_DISP_LAYER_GFX1: + case HAL_DISP_LAYER_GFX2: + case HAL_DISP_LAYER_GFX3: + case HAL_DISP_LAYER_GFX4: + addr_reg = fb_hal_get_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->g0_dfpos.u32)); + g0_dfpos.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + g0_dfpos.bits.disp_xfpos = rect->x; + g0_dfpos.bits.disp_yfpos = rect->y; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, g0_dfpos.u32); + + addr_reg = fb_hal_get_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->g0_dlpos.u32)); + g0_dlpos.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + g0_dlpos.bits.disp_xlpos = rect->x + rect->width - 1; + g0_dlpos.bits.disp_ylpos = rect->y + rect->height - 1; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, g0_dlpos.u32); + break; + default: + HAL_PRINT("Error layer id found in %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +/* Set the video image display area window */ +td_s32 fb_hal_video_set_layer_video_rect(hal_disp_layer layer, const ot_fb_rect *rect) +{ + volatile u_g0_vfpos g0_vfpos; + volatile u_g0_vlpos g0_vlpos; + volatile td_ulong addr_reg; + + if ((g_gfbg_reg == TD_NULL) || (rect == TD_NULL)) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + switch (layer) { + case HAL_DISP_LAYER_GFX0: + case HAL_DISP_LAYER_GFX1: + case HAL_DISP_LAYER_GFX2: + case HAL_DISP_LAYER_GFX3: + case HAL_DISP_LAYER_GFX4: + addr_reg = fb_hal_get_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->g0_vfpos.u32)); + g0_vfpos.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + g0_vfpos.bits.video_xfpos = rect->x; + g0_vfpos.bits.video_yfpos = rect->y; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, g0_vfpos.u32); + + addr_reg = fb_hal_get_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->g0_vlpos.u32)); + g0_vlpos.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + g0_vlpos.bits.video_xlpos = rect->x + rect->width - 1; + g0_vlpos.bits.video_ylpos = rect->y + rect->height - 1; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, g0_vlpos.u32); + break; + default: + HAL_PRINT("Error layer id %d# found in %s: L%d\n", layer, __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +td_void fb_hal_link_get_hc_link(hal_disp_layer layer, td_u32 *data) +{ + volatile u_link_ctrl link_ctrl; + + if ((g_gfbg_reg == TD_NULL) || (data == TD_NULL)) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + link_ctrl.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)&(g_gfbg_reg->link_ctrl.u32)); + switch (layer) { + case HAL_DISP_LAYER_GFX4: + *data = link_ctrl.bits.g4_link; + break; + case HAL_DISP_LAYER_GFX3: + *data = link_ctrl.bits.g3_link; + break; + case HAL_DISP_LAYER_GFX2: + *data = link_ctrl.bits.g2_link; + break; + default: + break; + } + + return; +} + +/* + * Name : fb_hal_set_layer_enable + * Desc : Set layer enable + */ +td_s32 fb_hal_set_layer_enable(hal_disp_layer layer, td_u32 enable) +{ + volatile u_v0_ctrl v0_ctrl; + volatile u_g0_ctrl g0_ctrl; + volatile td_ulong addr_reg; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + switch (layer) { + case HAL_DISP_LAYER_VHD0: + case HAL_DISP_LAYER_VHD1: + case HAL_DISP_LAYER_VHD2: { + addr_reg = fb_hal_get_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->v0_ctrl.u32)); + v0_ctrl.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + v0_ctrl.bits.surface_en = enable; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, v0_ctrl.u32); + break; + } + + case HAL_DISP_LAYER_GFX0: + case HAL_DISP_LAYER_GFX1: + case HAL_DISP_LAYER_GFX2: + case HAL_DISP_LAYER_GFX3: + case HAL_DISP_LAYER_GFX4: + addr_reg = fb_hal_get_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->g0_ctrl.u32)); + g0_ctrl.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + g0_ctrl.bits.surface_en = enable; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, g0_ctrl.u32); + break; + default: + HAL_PRINT("Error layer id found in %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +td_void fb_hal_set_layer_ck_gt_en(hal_disp_layer layer, td_u32 ck_gt_en) +{ + volatile u_voctrl voctrl; + volatile td_ulong addr_reg; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + addr_reg = (td_ulong)(uintptr_t)&(g_gfbg_reg->voctrl.u32); + voctrl.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + + switch (layer) { + case HAL_DISP_LAYER_GFX0: + voctrl.bits.g0_ck_gt_en = ck_gt_en; + break; +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC + case HAL_DISP_LAYER_GFX1: + voctrl.bits.g1_ck_gt_en = ck_gt_en; + break; + case HAL_DISP_LAYER_GFX3: + voctrl.bits.g3_ck_gt_en = ck_gt_en; + break; +#endif + default: + /* Logic aren't configured for G2. Don't write the configuration to avoid affecting other layers. */ + return; + } + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, voctrl.u32); +} + +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC +td_s32 fb_hal_get_layer_enable(hal_disp_layer layer, td_u32 *enable) +{ + volatile u_v0_ctrl v0_ctrl; + volatile u_g0_ctrl g0_ctrl; + volatile td_ulong addr_reg; + + if ((g_gfbg_reg == TD_NULL) || (enable == TD_NULL)) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + switch (layer) { + case HAL_DISP_LAYER_VHD0: + case HAL_DISP_LAYER_VHD1: + case HAL_DISP_LAYER_VHD2: { + addr_reg = fb_hal_get_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->v0_ctrl.u32)); + v0_ctrl.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + *enable = v0_ctrl.bits.surface_en; + break; + } + + case HAL_DISP_LAYER_GFX0: + case HAL_DISP_LAYER_GFX1: + case HAL_DISP_LAYER_GFX2: + case HAL_DISP_LAYER_GFX3: + case HAL_DISP_LAYER_GFX4: + addr_reg = fb_hal_get_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->g0_ctrl.u32)); + g0_ctrl.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + *enable = g0_ctrl.bits.surface_en; + break; + default: + HAL_PRINT("Error layer id found in %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + return TD_SUCCESS; +} +#endif + +/* Desc : Set layer data type */ +td_s32 fb_hal_layer_set_layer_data_fmt(hal_disp_layer layer, hal_disp_pixel_format data_fmt) +{ + volatile u_gfx_src_info gfx_src_info; + volatile td_ulong addr_reg; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + if (layer == HAL_DISP_LAYER_GFX0 || + layer == HAL_DISP_LAYER_GFX1 || + layer == HAL_DISP_LAYER_GFX2 || + layer == HAL_DISP_LAYER_GFX3 || + layer == HAL_DISP_LAYER_GFX4) { + addr_reg = fb_hal_get_gfx_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->gfx_src_info.u32)); + gfx_src_info.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + gfx_src_info.bits.ifmt = data_fmt; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, gfx_src_info.u32); + } else { + HAL_PRINT("Error layer id%d found in %s: L%d\n", layer, __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +td_s32 fb_hal_layer_get_layer_data_fmt(hal_disp_layer layer, td_u32 *fmt) +{ + volatile u_gfx_src_info gfx_src_info; + volatile td_ulong addr_reg; + + if ((g_gfbg_reg == TD_NULL) || (fmt == TD_NULL)) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + if (layer == HAL_DISP_LAYER_GFX0 || + layer == HAL_DISP_LAYER_GFX1 || + layer == HAL_DISP_LAYER_GFX2 || + layer == HAL_DISP_LAYER_GFX3 || + layer == HAL_DISP_LAYER_GFX4) { + addr_reg = fb_hal_get_gfx_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->gfx_src_info.u32)); + gfx_src_info.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + *fmt = gfx_src_info.bits.ifmt; + } else { + HAL_PRINT("Error layer id found in %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + return TD_SUCCESS; +} + +static td_void fb_hal_layer_csc_set_enable(hal_disp_layer layer, td_bool csc_en) +{ + volatile u_g0_ot_pp_csc_ctrl g0_ot_pp_csc_ctrl; + volatile td_ulong addr_reg; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + if ((layer >= LAYER_GFX_START) && (layer <= LAYER_GFX_END)) { + addr_reg = fb_hal_get_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->g0_ot_pp_csc_ctrl.u32)); + g0_ot_pp_csc_ctrl.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + g0_ot_pp_csc_ctrl.bits.ot_pp_csc_en = csc_en; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, g0_ot_pp_csc_ctrl.u32); + } +} + +static td_void fb_hal_layer_csc_set_ck_gt_en(hal_disp_layer layer, td_bool ck_gt_en) +{ + volatile u_g0_ot_pp_csc_ctrl g0_ot_pp_csc_ctrl; + volatile td_ulong addr_reg; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + if ((layer >= LAYER_GFX_START) && (layer <= LAYER_GFX_END)) { + addr_reg = fb_hal_get_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->g0_ot_pp_csc_ctrl.u32)); + g0_ot_pp_csc_ctrl.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + g0_ot_pp_csc_ctrl.bits.ot_pp_csc_ck_gt_en = ck_gt_en; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, g0_ot_pp_csc_ctrl.u32); + } +} + +static td_void fb_hal_layer_csc_set_coef(hal_disp_layer layer, const vdp_csc_coef *coef) +{ + volatile u_g0_ot_pp_csc_coef00 g0_ot_pp_csc_coef00; + volatile u_g0_ot_pp_csc_coef01 g0_ot_pp_csc_coef01; + volatile u_g0_ot_pp_csc_coef02 g0_ot_pp_csc_coef02; + volatile u_g0_ot_pp_csc_coef10 g0_ot_pp_csc_coef10; + volatile u_g0_ot_pp_csc_coef11 g0_ot_pp_csc_coef11; + volatile u_g0_ot_pp_csc_coef12 g0_ot_pp_csc_coef12; + volatile u_g0_ot_pp_csc_coef20 g0_ot_pp_csc_coef20; + volatile u_g0_ot_pp_csc_coef21 g0_ot_pp_csc_coef21; + volatile u_g0_ot_pp_csc_coef22 g0_ot_pp_csc_coef22; + volatile td_ulong addr_reg; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + if ((layer >= HAL_DISP_LAYER_GFX0) && (layer <= HAL_DISP_LAYER_GFX4)) { + g0_ot_pp_csc_coef00.u32 = hal_get_addr_abs(&addr_reg, layer, &(g_gfbg_reg->g0_ot_pp_csc_coef00.u32)); + g0_ot_pp_csc_coef00.bits.ot_pp_csc_coef00 = coef->csc_coef00; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, g0_ot_pp_csc_coef00.u32); + + g0_ot_pp_csc_coef01.u32 = hal_get_addr_abs(&addr_reg, layer, &(g_gfbg_reg->g0_ot_pp_csc_coef01.u32)); + g0_ot_pp_csc_coef01.bits.ot_pp_csc_coef01 = coef->csc_coef01; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, g0_ot_pp_csc_coef01.u32); + + g0_ot_pp_csc_coef02.u32 = hal_get_addr_abs(&addr_reg, layer, &(g_gfbg_reg->g0_ot_pp_csc_coef02.u32)); + g0_ot_pp_csc_coef02.bits.ot_pp_csc_coef02 = coef->csc_coef02; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, g0_ot_pp_csc_coef02.u32); + + g0_ot_pp_csc_coef10.u32 = hal_get_addr_abs(&addr_reg, layer, &(g_gfbg_reg->g0_ot_pp_csc_coef10.u32)); + g0_ot_pp_csc_coef10.bits.ot_pp_csc_coef10 = coef->csc_coef10; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, g0_ot_pp_csc_coef10.u32); + + g0_ot_pp_csc_coef11.u32 = hal_get_addr_abs(&addr_reg, layer, &(g_gfbg_reg->g0_ot_pp_csc_coef11.u32)); + g0_ot_pp_csc_coef11.bits.ot_pp_csc_coef11 = coef->csc_coef11; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, g0_ot_pp_csc_coef11.u32); + + g0_ot_pp_csc_coef12.u32 = hal_get_addr_abs(&addr_reg, layer, &(g_gfbg_reg->g0_ot_pp_csc_coef12.u32)); + g0_ot_pp_csc_coef12.bits.ot_pp_csc_coef12 = coef->csc_coef12; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, g0_ot_pp_csc_coef12.u32); + + g0_ot_pp_csc_coef20.u32 = hal_get_addr_abs(&addr_reg, layer, &(g_gfbg_reg->g0_ot_pp_csc_coef20.u32)); + g0_ot_pp_csc_coef20.bits.ot_pp_csc_coef20 = coef->csc_coef20; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, g0_ot_pp_csc_coef20.u32); + + g0_ot_pp_csc_coef21.u32 = hal_get_addr_abs(&addr_reg, layer, &(g_gfbg_reg->g0_ot_pp_csc_coef21.u32)); + g0_ot_pp_csc_coef21.bits.ot_pp_csc_coef21 = coef->csc_coef21; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, g0_ot_pp_csc_coef21.u32); + + g0_ot_pp_csc_coef22.u32 = hal_get_addr_abs(&addr_reg, layer, &(g_gfbg_reg->g0_ot_pp_csc_coef22.u32)); + g0_ot_pp_csc_coef22.bits.ot_pp_csc_coef22 = coef->csc_coef22; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, g0_ot_pp_csc_coef22.u32); + } else { + HAL_PRINT("Error layer id found in %s, %d\n", __FUNCTION__, __LINE__); + } + return; +} + +static td_void fb_hal_layer_csc_set_dc_coef(hal_disp_layer layer, const vdp_csc_dc_coef *csc_dc_coef) +{ + volatile u_g0_ot_pp_csc_idc0 g0_ot_pp_csc_idc0; + volatile u_g0_ot_pp_csc_idc1 g0_ot_pp_csc_idc1; + volatile u_g0_ot_pp_csc_idc2 g0_ot_pp_csc_idc2; + volatile u_g0_ot_pp_csc_odc0 g0_ot_pp_csc_odc0; + volatile u_g0_ot_pp_csc_odc1 g0_ot_pp_csc_odc1; + volatile u_g0_ot_pp_csc_odc2 g0_ot_pp_csc_odc2; + volatile td_ulong addr_reg; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + if ((layer >= HAL_DISP_LAYER_GFX0) && (layer <= HAL_DISP_LAYER_GFX4)) { + addr_reg = fb_hal_get_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->g0_ot_pp_csc_idc0.u32)); + g0_ot_pp_csc_idc0.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + g0_ot_pp_csc_idc0.bits.ot_pp_csc_idc0 = csc_dc_coef->csc_in_dc0; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, g0_ot_pp_csc_idc0.u32); + + addr_reg = fb_hal_get_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->g0_ot_pp_csc_idc1.u32)); + g0_ot_pp_csc_idc1.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + g0_ot_pp_csc_idc1.bits.ot_pp_csc_idc1 = csc_dc_coef->csc_in_dc1; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, g0_ot_pp_csc_idc1.u32); + + addr_reg = fb_hal_get_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->g0_ot_pp_csc_idc2.u32)); + g0_ot_pp_csc_idc2.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + g0_ot_pp_csc_idc2.bits.ot_pp_csc_idc2 = csc_dc_coef->csc_in_dc2; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, g0_ot_pp_csc_idc2.u32); + + addr_reg = fb_hal_get_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->g0_ot_pp_csc_odc0.u32)); + g0_ot_pp_csc_odc0.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + g0_ot_pp_csc_odc0.bits.ot_pp_csc_odc0 = csc_dc_coef->csc_out_dc0; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, g0_ot_pp_csc_odc0.u32); + + addr_reg = fb_hal_get_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->g0_ot_pp_csc_odc1.u32)); + g0_ot_pp_csc_odc1.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + g0_ot_pp_csc_odc1.bits.ot_pp_csc_odc1 = csc_dc_coef->csc_out_dc1; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, g0_ot_pp_csc_odc1.u32); + + addr_reg = fb_hal_get_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->g0_ot_pp_csc_odc2.u32)); + g0_ot_pp_csc_odc2.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + g0_ot_pp_csc_odc2.bits.ot_pp_csc_odc2 = csc_dc_coef->csc_out_dc2; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, g0_ot_pp_csc_odc2.u32); + } else { + HAL_PRINT("Error layer id found in %s, %d\n", __FUNCTION__, __LINE__); + } +} + +static td_void fb_hal_layer_csc_set_param(hal_disp_layer layer, const csc_coef_param *coef_param) +{ + volatile u_g0_ot_pp_csc_scale g0_ot_pp_csc_scale; + volatile u_g0_ot_pp_csc_min_y g0_ot_pp_csc_min_y; + volatile u_g0_ot_pp_csc_min_c g0_ot_pp_csc_min_c; + volatile u_g0_ot_pp_csc_max_y g0_ot_pp_csc_max_y; + volatile u_g0_ot_pp_csc_max_c g0_ot_pp_csc_max_c; + volatile td_ulong addr_reg; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + if ((layer >= LAYER_GFX_START) && (layer <= LAYER_GFX_END)) { + addr_reg = fb_hal_get_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->g0_ot_pp_csc_scale.u32)); + g0_ot_pp_csc_scale.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + g0_ot_pp_csc_scale.bits.ot_pp_csc_scale = coef_param->csc_scale2p; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, g0_ot_pp_csc_scale.u32); + + addr_reg = fb_hal_get_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->g0_ot_pp_csc_min_y.u32)); + g0_ot_pp_csc_min_y.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + g0_ot_pp_csc_min_y.bits.ot_pp_csc_min_y = coef_param->csc_clip_min; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, g0_ot_pp_csc_min_y.u32); + + addr_reg = fb_hal_get_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->g0_ot_pp_csc_min_c.u32)); + g0_ot_pp_csc_min_c.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + g0_ot_pp_csc_min_c.bits.ot_pp_csc_min_c = coef_param->csc_clip_min; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, g0_ot_pp_csc_min_c.u32); + + addr_reg = fb_hal_get_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->g0_ot_pp_csc_max_y.u32)); + g0_ot_pp_csc_max_y.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + g0_ot_pp_csc_max_y.bits.ot_pp_csc_max_y = coef_param->csc_clip_max; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, g0_ot_pp_csc_max_y.u32); + + addr_reg = fb_hal_get_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->g0_ot_pp_csc_max_c.u32)); + g0_ot_pp_csc_max_c.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + g0_ot_pp_csc_max_c.bits.ot_pp_csc_max_c = coef_param->csc_clip_max; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, g0_ot_pp_csc_max_c.u32); + } +} + +td_s32 fb_hal_layer_set_csc_coef(hal_disp_layer layer, const csc_coef *coef, + const csc_coef_param *coef_param) +{ + if ((layer < HAL_DISP_LAYER_VHD0) || (layer > HAL_DISP_LAYER_GFX4)) { + HAL_PRINT("Error, Wrong layer ID!%d\n", __LINE__); + return TD_FAILURE; + } + + fb_hal_layer_csc_set_dc_coef(layer, (vdp_csc_dc_coef *)(&coef->csc_in_dc0)); + fb_hal_layer_csc_set_coef(layer, (vdp_csc_coef *)(&coef->csc_coef00)); + fb_hal_layer_csc_set_param(layer, coef_param); + + return TD_SUCCESS; +} + +td_s32 fb_hal_layer_set_csc_en(hal_disp_layer layer, td_bool csc_en) +{ + if ((layer < HAL_DISP_LAYER_VHD0) || (layer > HAL_DISP_LAYER_GFX4)) { + HAL_PRINT("Error, Wrong layer ID!%d\n", __LINE__); + return TD_FAILURE; + } + + fb_hal_layer_csc_set_ck_gt_en(layer, TD_TRUE); /* Turn on low power consumption */ + fb_hal_layer_csc_set_enable(layer, csc_en); + + return TD_SUCCESS; +} + +td_s32 fb_hal_layer_set_src_resolution(hal_disp_layer layer, const ot_fb_rect *rect) +{ + volatile u_gfx_src_reso gfx_src_reso; + volatile td_ulong addr_reg; + + if ((g_gfbg_reg == TD_NULL) || (rect == TD_NULL)) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + if (layer == HAL_DISP_LAYER_GFX0 || + layer == HAL_DISP_LAYER_GFX1 || + layer == HAL_DISP_LAYER_GFX2 || + layer == HAL_DISP_LAYER_GFX3 || + layer == HAL_DISP_LAYER_GFX4) { + addr_reg = fb_hal_get_gfx_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->gfx_src_reso.u32)); + gfx_src_reso.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + gfx_src_reso.bits.src_w = rect->width - 1; + gfx_src_reso.bits.src_h = rect->height - 1; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, gfx_src_reso.u32); + } else { + HAL_PRINT("Error:layer id not found in %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +td_s32 fb_hal_layer_set_layer_in_rect(hal_disp_layer layer, const ot_fb_rect *rect) +{ + volatile u_gfx_ireso gfx_ireso; + volatile td_ulong addr_reg; + + if ((g_gfbg_reg == TD_NULL) || (rect == TD_NULL)) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + if (layer == HAL_DISP_LAYER_GFX0 || + layer == HAL_DISP_LAYER_GFX1 || + layer == HAL_DISP_LAYER_GFX2 || + layer == HAL_DISP_LAYER_GFX3 || + layer == HAL_DISP_LAYER_GFX4) { + addr_reg = fb_hal_get_gfx_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->gfx_ireso.u32)); + gfx_ireso.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + gfx_ireso.bits.ireso_w = rect->width - 1; + gfx_ireso.bits.ireso_h = rect->height - 1; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, gfx_ireso.u32); + } else { + HAL_PRINT("Error layer id found in %s, %d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +td_s32 fb_hal_layer_set_layer_out_rect(hal_disp_layer layer, const ot_fb_rect *rect) +{ + ot_unused(rect); + if ((layer >= LAYER_GFX_START) && (layer <= LAYER_GFX_END)) { + return TD_SUCCESS; + } else { + HAL_PRINT("Error:layer id not found in %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } +} + +/* + * Name : hal_layer_set_layer_galpha + * Desc : Set video/graphic layer's global alpha + */ +td_s32 fb_hal_layer_set_layer_galpha(hal_disp_layer layer, td_u8 alpha0) +{ + volatile u_v0_ctrl v0_ctrl; + volatile u_g0_ctrl g0_ctrl; + volatile td_ulong addr_reg; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + switch (layer) { + case HAL_DISP_LAYER_VHD0: + case HAL_DISP_LAYER_VHD1: + case HAL_DISP_LAYER_VHD2: + addr_reg = fb_hal_get_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->v0_ctrl.u32)); + v0_ctrl.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + v0_ctrl.bits.galpha = alpha0; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, v0_ctrl.u32); + break; + case HAL_DISP_LAYER_GFX0: + case HAL_DISP_LAYER_GFX1: + case HAL_DISP_LAYER_GFX2: + case HAL_DISP_LAYER_GFX3: + case HAL_DISP_LAYER_GFX4: + addr_reg = fb_hal_get_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->g0_ctrl.u32)); + g0_ctrl.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + g0_ctrl.bits.galpha = alpha0; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, g0_ctrl.u32); + break; + default: + HAL_PRINT("Error layer id %d found in %s: L%d\n", layer, __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +td_s32 fb_hal_layer_get_layer_galpha(hal_disp_layer layer, td_u8 *alpha0) +{ + volatile u_v0_ctrl v0_ctrl; + volatile u_g0_ctrl g0_ctrl; + volatile td_ulong addr_reg; + + if ((g_gfbg_reg == TD_NULL) || (alpha0 == TD_NULL)) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + switch (layer) { + case HAL_DISP_LAYER_VHD0: + case HAL_DISP_LAYER_VHD1: + case HAL_DISP_LAYER_VHD2: + addr_reg = fb_hal_get_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->v0_ctrl.u32)); + v0_ctrl.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + *alpha0 = v0_ctrl.bits.galpha; + break; + case HAL_DISP_LAYER_GFX0: + case HAL_DISP_LAYER_GFX1: + case HAL_DISP_LAYER_GFX2: + case HAL_DISP_LAYER_GFX3: + case HAL_DISP_LAYER_GFX4: + addr_reg = fb_hal_get_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->g0_ctrl.u32)); + g0_ctrl.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + *alpha0 = g0_ctrl.bits.galpha; + break; + default: + HAL_PRINT("Error layer id found in %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +/* + * Name : fb_hal_layer_set_reg_up + * Desc : Set layer(video or graphic) register update. + */ +td_s32 fb_hal_layer_set_reg_up(hal_disp_layer layer) +{ + volatile u_v0_upd v0_upd; + volatile u_g0_upd g0_upd; + volatile td_ulong addr_reg; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + switch (layer) { + case HAL_DISP_LAYER_VHD0: + case HAL_DISP_LAYER_VHD1: + case HAL_DISP_LAYER_VHD2: { + addr_reg = fb_hal_get_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->v0_upd.u32)); + v0_upd.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + /* video layer register update */ + v0_upd.bits.regup = 0x1; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, v0_upd.u32); + break; + } + + case HAL_DISP_LAYER_GFX0: + case HAL_DISP_LAYER_GFX1: + case HAL_DISP_LAYER_GFX2: + case HAL_DISP_LAYER_GFX3: + case HAL_DISP_LAYER_GFX4: { + addr_reg = fb_hal_get_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->g0_upd.u32)); + g0_upd.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + /* graphic layer register update */ + g0_upd.bits.regup = 0x1; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, g0_upd.u32); + break; + } + default: { + HAL_PRINT("Error layer id found in %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + } + + return TD_SUCCESS; +} + +/* set layer addr */ +td_s32 fb_hal_graphic_set_gfx_addr(hal_disp_layer layer, td_phys_addr_t laddr) +{ + volatile td_ulong gfx_addr_h; + volatile td_ulong gfx_addr_l; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + if (layer == HAL_DISP_LAYER_GFX0 || + layer == HAL_DISP_LAYER_GFX1 || + layer == HAL_DISP_LAYER_GFX2 || + layer == HAL_DISP_LAYER_GFX3 || + layer == HAL_DISP_LAYER_GFX4) { + /* Write low address to register. */ + gfx_addr_l = fb_hal_get_gfx_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->gfx_addr_l)); + fb_hal_write_reg((td_u32 *)(uintptr_t)gfx_addr_l, get_low_addr(laddr)); + + /* Write high address to register. */ + gfx_addr_h = fb_hal_get_gfx_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->gfx_addr_h)); + fb_hal_write_reg((td_u32 *)(uintptr_t)gfx_addr_h, get_high_addr(laddr)); + } else { + HAL_PRINT("Error layer id found in %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + return TD_SUCCESS; +} + +/* + * Name : hal_graphic_get_gfx_addr + * Desc : get layer addr. + */ +td_s32 fb_hal_graphic_get_gfx_addr(hal_disp_layer layer, td_phys_addr_t *gfx_addr) +{ + volatile td_ulong addr_reg; + volatile td_phys_addr_t addr_h = 0x0; + volatile td_phys_addr_t addr_l = 0x0; + + if ((g_gfbg_reg == TD_NULL) || (gfx_addr == TD_NULL)) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + if (layer == HAL_DISP_LAYER_GFX0 || + layer == HAL_DISP_LAYER_GFX1 || + layer == HAL_DISP_LAYER_GFX2 || + layer == HAL_DISP_LAYER_GFX3 || + layer == HAL_DISP_LAYER_GFX4) { + addr_reg = fb_hal_get_gfx_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->gfx_addr_l)); + addr_l = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + addr_reg = fb_hal_get_gfx_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->gfx_addr_h)); + addr_h = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + } else { + HAL_PRINT("Error layer id found in %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + *gfx_addr = addr_l + ((td_u64)addr_h << 32); /* 32 max address */ + return TD_SUCCESS; +} + +/* layer stride */ +td_s32 fb_hal_graphic_set_gfx_stride(hal_disp_layer layer, td_u16 pitch) +{ + volatile u_gfx_stride gfx_stride; + volatile td_ulong addr_reg; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + if (layer == HAL_DISP_LAYER_GFX0 || + layer == HAL_DISP_LAYER_GFX1 || + layer == HAL_DISP_LAYER_GFX2 || + layer == HAL_DISP_LAYER_GFX3 || + layer == HAL_DISP_LAYER_GFX4) { + addr_reg = fb_hal_get_gfx_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->gfx_stride.u32)); + gfx_stride.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + gfx_stride.bits.surface_stride = pitch; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, gfx_stride.u32); + } else { + HAL_PRINT("Error layer id found in %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +/* get layer stride */ +td_s32 fb_hal_graphic_get_gfx_stride(hal_disp_layer layer, td_u32 *gfx_stride) +{ + volatile td_ulong addr_reg; + + if ((g_gfbg_reg == TD_NULL) || (gfx_stride == TD_NULL)) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + if (layer == HAL_DISP_LAYER_GFX0 || + layer == HAL_DISP_LAYER_GFX1 || + layer == HAL_DISP_LAYER_GFX2 || + layer == HAL_DISP_LAYER_GFX3 || + layer == HAL_DISP_LAYER_GFX4) { + addr_reg = fb_hal_get_gfx_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->gfx_stride.u32)); + } else { + HAL_PRINT("Error layer id found in %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + *gfx_stride = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + + return TD_SUCCESS; +} + +/* layer bit ext. */ +td_s32 fb_hal_graphic_set_gfx_ext(hal_disp_layer layer, hal_gfx_bitextend mode) +{ + volatile u_gfx_out_ctrl gfx_out_ctrl; + volatile td_ulong addr_reg; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + if (layer == HAL_DISP_LAYER_GFX0 || + layer == HAL_DISP_LAYER_GFX1 || + layer == HAL_DISP_LAYER_GFX2 || + layer == HAL_DISP_LAYER_GFX3 || + layer == HAL_DISP_LAYER_GFX4) { + addr_reg = fb_hal_get_gfx_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->gfx_out_ctrl.u32)); + gfx_out_ctrl.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + gfx_out_ctrl.bits.bitext = mode; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, gfx_out_ctrl.u32); + } else { + HAL_PRINT("Error layer id found in %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + return TD_SUCCESS; +} + +td_s32 fb_hal_graphic_set_gfx_pre_mult(hal_disp_layer layer, td_u32 enable) +{ + volatile u_gfx_out_ctrl gfx_out_ctrl; + volatile td_ulong addr_reg; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + if (layer == HAL_DISP_LAYER_GFX0 || + layer == HAL_DISP_LAYER_GFX1 || + layer == HAL_DISP_LAYER_GFX2 || + layer == HAL_DISP_LAYER_GFX3 || + layer == HAL_DISP_LAYER_GFX4) { + addr_reg = fb_hal_get_gfx_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->gfx_out_ctrl.u32)); + gfx_out_ctrl.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + gfx_out_ctrl.bits.premulti_en = enable; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, gfx_out_ctrl.u32); + } else { + HAL_PRINT("Error layer id found in %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + return TD_SUCCESS; +} + +td_s32 fb_hal_graphic_get_gfx_premult(hal_disp_layer layer, td_u32 *enable) +{ + volatile u_gfx_out_ctrl gfx_out_ctrl; + volatile td_ulong addr_reg; + + if ((g_gfbg_reg == TD_NULL) || (enable == TD_NULL)) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + if (layer == HAL_DISP_LAYER_GFX0 || + layer == HAL_DISP_LAYER_GFX1 || + layer == HAL_DISP_LAYER_GFX2 || + layer == HAL_DISP_LAYER_GFX3 || + layer == HAL_DISP_LAYER_GFX4) { + addr_reg = fb_hal_get_gfx_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->gfx_out_ctrl.u32)); + gfx_out_ctrl.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + *enable = gfx_out_ctrl.bits.premulti_en; + } else { + HAL_PRINT("Error layer id found in %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +td_s32 fb_hal_graphic_set_gfx_palpha(hal_disp_layer layer, td_u32 alpha_en, td_u32 arange, + td_u8 alpha0, td_u8 alpha1) +{ + volatile u_gfx_out_ctrl gfx_out_ctrl; + volatile u_gfx_1555_alpha gfx_1555_alpha; + volatile td_ulong addr_reg; + ot_unused(arange); + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + if (layer == HAL_DISP_LAYER_GFX0 || + layer == HAL_DISP_LAYER_GFX1 || + layer == HAL_DISP_LAYER_GFX2 || + layer == HAL_DISP_LAYER_GFX3 || + layer == HAL_DISP_LAYER_GFX4) { + addr_reg = fb_hal_get_gfx_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->gfx_out_ctrl.u32)); + gfx_out_ctrl.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + gfx_out_ctrl.bits.palpha_en = alpha_en; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, gfx_out_ctrl.u32); + + if (alpha_en == TD_TRUE) { + addr_reg = fb_hal_get_gfx_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->gfx_1555_alpha.u32)); + gfx_1555_alpha.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + gfx_1555_alpha.bits.alpha_1 = alpha1; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, gfx_1555_alpha.u32); + + addr_reg = fb_hal_get_gfx_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->gfx_1555_alpha.u32)); + gfx_1555_alpha.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + gfx_1555_alpha.bits.alpha_0 = alpha0; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, gfx_1555_alpha.u32); + } else { + addr_reg = fb_hal_get_gfx_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->gfx_1555_alpha.u32)); + gfx_1555_alpha.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + gfx_1555_alpha.bits.alpha_1 = 0xff; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, gfx_1555_alpha.u32); + + addr_reg = fb_hal_get_gfx_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->gfx_1555_alpha.u32)); + gfx_1555_alpha.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + gfx_1555_alpha.bits.alpha_0 = 0xff; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, gfx_1555_alpha.u32); + } + } else { + HAL_PRINT("Error layer id found in %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + return TD_SUCCESS; +} + +td_s32 fb_hal_graphic_set_gfx_key_en(hal_disp_layer layer, td_u32 key_enable) +{ + volatile u_gfx_out_ctrl gfx_out_ctrl; + volatile td_ulong addr_reg; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + if (layer == HAL_DISP_LAYER_GFX0 || + layer == HAL_DISP_LAYER_GFX1 || + layer == HAL_DISP_LAYER_GFX2 || + layer == HAL_DISP_LAYER_GFX3 || + layer == HAL_DISP_LAYER_GFX4) { + addr_reg = fb_hal_get_gfx_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->gfx_out_ctrl.u32)); + gfx_out_ctrl.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + gfx_out_ctrl.bits.enable = key_enable; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, gfx_out_ctrl.u32); + } else { + HAL_PRINT("Error layer id %d not support colorkey in %s: L%d\n", + (td_s32)layer, __FUNCTION__, __LINE__); + return TD_FAILURE; + } + return TD_SUCCESS; +} + +td_s32 fb_hal_graphic_set_gfx_key_mode(hal_disp_layer layer, td_u32 key_out) +{ + volatile u_gfx_out_ctrl gfx_out_ctrl; + volatile td_ulong addr_reg; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + if (layer == HAL_DISP_LAYER_GFX0 || + layer == HAL_DISP_LAYER_GFX1 || + layer == HAL_DISP_LAYER_GFX2 || + layer == HAL_DISP_LAYER_GFX3 || + layer == HAL_DISP_LAYER_GFX4) { + addr_reg = fb_hal_get_gfx_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->gfx_out_ctrl.u32)); + gfx_out_ctrl.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + gfx_out_ctrl.bits.key_mode = key_out; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, gfx_out_ctrl.u32); + } else { + HAL_PRINT("Error layer id %d not support colorkey mode in %s: L%d\n", + (td_s32)layer, __FUNCTION__, __LINE__); + return TD_FAILURE; + } + return TD_SUCCESS; +} + +td_s32 fb_hal_graphic_set_color_key_value(hal_disp_layer layer, hal_gfx_key_max key_max, + hal_gfx_key_min key_min) +{ + volatile u_gfx_ckey_max gfx_ckey_max; + volatile u_gfx_ckey_min gfx_ckey_min; + volatile td_ulong addr_reg; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + if (layer == HAL_DISP_LAYER_GFX0 || + layer == HAL_DISP_LAYER_GFX1 || + layer == HAL_DISP_LAYER_GFX2 || + layer == HAL_DISP_LAYER_GFX3 || + layer == HAL_DISP_LAYER_GFX4) { + addr_reg = fb_hal_get_gfx_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->gfx_ckey_max.u32)); + gfx_ckey_max.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + gfx_ckey_max.bits.key_r_max = key_max.key_max_r; + gfx_ckey_max.bits.key_g_max = key_max.key_max_g; + gfx_ckey_max.bits.key_b_max = key_max.key_max_b; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, gfx_ckey_max.u32); + + addr_reg = fb_hal_get_gfx_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->gfx_ckey_min.u32)); + gfx_ckey_min.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + gfx_ckey_min.bits.key_r_min = key_min.key_min_r; + gfx_ckey_min.bits.key_g_min = key_min.key_min_g; + gfx_ckey_min.bits.key_b_min = key_min.key_min_b; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, gfx_ckey_min.u32); + } else { + HAL_PRINT("Error layer id %d not support colorkey in %s: L%d\n", + (td_s32)layer, __FUNCTION__, __LINE__); + return TD_FAILURE; + } + return TD_SUCCESS; +} + +td_s32 fb_hal_graphic_set_color_key_mask(hal_disp_layer layer, hal_gfx_mask msk) +{ + volatile u_gfx_ckey_mask gfx_ckey_mask; + volatile td_ulong addr_reg; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + if (layer == HAL_DISP_LAYER_GFX0 || + layer == HAL_DISP_LAYER_GFX1 || + layer == HAL_DISP_LAYER_GFX2 || + layer == HAL_DISP_LAYER_GFX3 || + layer == HAL_DISP_LAYER_GFX4) { + addr_reg = fb_hal_get_gfx_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->gfx_ckey_mask.u32)); + gfx_ckey_mask.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + gfx_ckey_mask.bits.key_r_msk = msk.mask_r; + gfx_ckey_mask.bits.key_g_msk = msk.mask_g; + gfx_ckey_mask.bits.key_b_msk = msk.mask_b; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, gfx_ckey_mask.u32); + } else { + HAL_PRINT("Error layer id %d not support colorkey mask in %s: L%d\n", (td_s32)layer, __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +/* for gfx decmpress */ +td_s32 fb_hal_graphic_set_gfx_dcmp_enable(hal_disp_layer layer, td_u32 enable) +{ + volatile u_gfx_src_info gfx_src_info; + volatile td_ulong addr_reg; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + if (layer == HAL_DISP_LAYER_GFX0 || + layer == HAL_DISP_LAYER_GFX1 || + layer == HAL_DISP_LAYER_GFX2 || + layer == HAL_DISP_LAYER_GFX3 || + layer == HAL_DISP_LAYER_GFX4) { + addr_reg = fb_hal_get_gfx_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->gfx_src_info.u32)); + + gfx_src_info.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + gfx_src_info.bits.dcmp_en = enable; + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, gfx_src_info.u32); + } else { + HAL_PRINT("Error layer id %d not support dcmp in %s: L%d\n", (td_s32)layer, __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC +td_s32 fb_hal_graphic_get_gfx_dcmp_enable_state(hal_disp_layer layer, td_bool *enable) +{ + volatile u_gfx_src_info gfx_src_info; + volatile td_ulong addr_reg; + + if ((g_gfbg_reg == TD_NULL) || (enable == TD_NULL)) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + if ((layer == HAL_DISP_LAYER_GFX0) || (layer == HAL_DISP_LAYER_GFX1)) { + addr_reg = fb_hal_get_gfx_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->gfx_src_info.u32)); + gfx_src_info.u32 = fb_hal_read_reg((td_u32 *)(uintptr_t)addr_reg); + *enable = gfx_src_info.bits.dcmp_en; + } else { + HAL_PRINT("Error layer id %d not support dcmp in %s: L%d\n", (td_s32)layer, __FUNCTION__, __LINE__); + return TD_FAILURE; + } + return TD_SUCCESS; +} + +td_s32 fb_hal_graphic_set_gfx_dcmp_addr(hal_disp_layer layer, td_phys_addr_t addr_ar) +{ + volatile td_u32 gfx_addr_h; + volatile td_u32 gfx_addr_l; + volatile td_ulong addr_reg; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + if ((layer == HAL_DISP_LAYER_GFX0) || (layer == HAL_DISP_LAYER_GFX1)) { + /* DCMP low addr for AR */ + addr_reg = fb_hal_get_gfx_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->gfx_addr_l)); + gfx_addr_l = get_low_addr(addr_ar); + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, gfx_addr_l); + + /* DCMP high addr for AR */ + addr_reg = fb_hal_get_gfx_abs_addr(layer, (td_ulong)(uintptr_t)&(g_gfbg_reg->gfx_addr_h)); + gfx_addr_h = get_high_addr(addr_ar); + fb_hal_write_reg((td_u32 *)(uintptr_t)addr_reg, gfx_addr_h); + } else { + HAL_PRINT("Error layer id found in %s: L%d\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +td_void fb_hal_para_set_para_addr_vhd_chn06(td_phys_addr_t addr) +{ + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->para_haddr_vhd_chn06), get_high_addr(addr)); + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->para_addr_vhd_chn06), get_low_addr(addr)); + + return; +} + +td_void fb_hal_para_set_para_up_vhd_chn(td_u32 chn_num) +{ + volatile u_para_up_vhd para_up_vhd; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + para_up_vhd.u32 = (1 << chn_num); + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->para_up_vhd.u32), para_up_vhd.u32); + + return; +} + +#ifdef CONFIG_TDE_GFBG_COMPRESS_V1 +td_void fb_hal_fdr_gfx_set_source_mode(td_u32 layer, td_u32 source_mode) +{ + volatile u_gfx_dcmp_ctrl gfx_dcmp_ctrl; + + if (layer >= GFBG_MAX_LAYER_NUM) { + OT_TRACE(OT_DBG_ERR, OT_ID_FB, "Error, %s(),%d Select Wrong Layer ID\n", __FUNCTION__, __LINE__); + } + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + gfx_dcmp_ctrl.u32 = fb_hal_read_reg((td_u32 *)((uintptr_t)(&(g_gfbg_reg->gfx_dcmp_ctrl.u32)) + layer * + FDR_GFX_OFFSET)); + gfx_dcmp_ctrl.bits.osd_mode = source_mode; + fb_hal_write_reg((td_u32 *)((uintptr_t)(&(g_gfbg_reg->gfx_dcmp_ctrl.u32)) + layer * FDR_GFX_OFFSET), + gfx_dcmp_ctrl.u32); + return; +} + +td_void fb_hal_fdr_gfx_set_cmp_mode(td_u32 layer, td_u32 cmp_mode) +{ + volatile u_gfx_dcmp_ctrl gfx_dcmp_ctrl; + + if (layer >= GFBG_MAX_LAYER_NUM) { + OT_TRACE(OT_DBG_ERR, OT_ID_FB, "Error, %s(),%d Select Wrong Layer ID\n", __FUNCTION__, __LINE__); + } + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + gfx_dcmp_ctrl.u32 = fb_hal_read_reg((td_u32 *)((uintptr_t)(&(g_gfbg_reg->gfx_dcmp_ctrl.u32)) + layer * + FDR_GFX_OFFSET)); + gfx_dcmp_ctrl.bits.cmp_mode = cmp_mode; + fb_hal_write_reg((td_u32 *)((uintptr_t)(&(g_gfbg_reg->gfx_dcmp_ctrl.u32)) + layer * FDR_GFX_OFFSET), + gfx_dcmp_ctrl.u32); + + return; +} + +td_void fb_hal_fdr_gfx_set_is_loss_lessa(td_u32 layer, td_u32 is_lossless_a) +{ + volatile u_gfx_dcmp_ctrl gfx_dcmp_ctrl; + + if (layer >= GFBG_MAX_LAYER_NUM) { + OT_TRACE(OT_DBG_ERR, OT_ID_FB, "Error, %s(),%d Select Wrong Layer ID\n", __FUNCTION__, __LINE__); + } + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + gfx_dcmp_ctrl.u32 = fb_hal_read_reg((td_u32 *)((uintptr_t)(&(g_gfbg_reg->gfx_dcmp_ctrl.u32)) + layer * + FDR_GFX_OFFSET)); + gfx_dcmp_ctrl.bits.is_lossless_a = is_lossless_a; + fb_hal_write_reg((td_u32 *)((uintptr_t)(&(g_gfbg_reg->gfx_dcmp_ctrl.u32)) + layer * FDR_GFX_OFFSET), + gfx_dcmp_ctrl.u32); + + return; +} + +td_void fb_hal_fdr_gfx_set_is_loss_less(td_u32 layer, td_u32 is_lossless) +{ + volatile u_gfx_dcmp_ctrl gfx_dcmp_ctrl; + + if (layer >= GFBG_MAX_LAYER_NUM) { + OT_TRACE(OT_DBG_ERR, OT_ID_FB, "Error, %s(),%d Select Wrong Layer ID\n", __FUNCTION__, __LINE__); + } + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + gfx_dcmp_ctrl.u32 = fb_hal_read_reg((td_u32 *)((uintptr_t)(&(g_gfbg_reg->gfx_dcmp_ctrl.u32)) + layer * + FDR_GFX_OFFSET)); + gfx_dcmp_ctrl.bits.is_lossless = is_lossless; + fb_hal_write_reg((td_u32 *)((uintptr_t)(&(g_gfbg_reg->gfx_dcmp_ctrl.u32)) + layer * FDR_GFX_OFFSET), + gfx_dcmp_ctrl.u32); + + return; +} +#endif + +#ifdef CONFIG_TDE_GFBG_COMPRESS_V2 +td_void fb_hal_v3r2_gfx_set_source_mode(td_u32 layer, td_u32 source_mode) +{ + volatile u_vdp_v3r2_line_osd_dcmp_glb_info gfx_dcmp_ctrl; + + if (layer >= GFBG_MAX_LAYER_NUM) { + OT_TRACE(OT_DBG_ERR, OT_ID_FB, "Error, %s(),%d Select Wrong Layer ID\n", __FUNCTION__, __LINE__); + } + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + gfx_dcmp_ctrl.u32 = fb_hal_read_reg((td_u32 *)((uintptr_t)(&(g_gfbg_reg->vdp_v3r2_line_osd_dcmp_glb_info.u32)) + + layer * FDR_GFX_OFFSET)); + gfx_dcmp_ctrl.bits.osd_mode = source_mode; + fb_hal_write_reg((td_u32 *)((uintptr_t)(&(g_gfbg_reg->vdp_v3r2_line_osd_dcmp_glb_info.u32)) + + layer * FDR_GFX_OFFSET), gfx_dcmp_ctrl.u32); + + return; +} + +td_void fb_hal_v3r2_gfx_set_is_loss_less(td_u32 layer, td_u32 is_lossless) +{ + volatile u_vdp_v3r2_line_osd_dcmp_glb_info gfx_dcmp_ctrl; + + if (layer >= GFBG_MAX_LAYER_NUM) { + OT_TRACE(OT_DBG_ERR, OT_ID_FB, "Error, %s(),%d Select Wrong Layer ID\n", __FUNCTION__, __LINE__); + } + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + gfx_dcmp_ctrl.u32 = fb_hal_read_reg((td_u32 *)((uintptr_t)(&(g_gfbg_reg->vdp_v3r2_line_osd_dcmp_glb_info.u32)) + + layer * FDR_GFX_OFFSET)); + gfx_dcmp_ctrl.bits.is_lossless = is_lossless; + fb_hal_write_reg((td_u32 *)((uintptr_t)(&(g_gfbg_reg->vdp_v3r2_line_osd_dcmp_glb_info.u32)) + + layer * FDR_GFX_OFFSET), gfx_dcmp_ctrl.u32); + + return; +} + +td_void fb_hal_v3r2_gfx_set_is_conv_en(td_u32 layer, td_u32 conv_en) +{ + volatile u_vdp_v3r2_line_osd_dcmp_glb_info gfx_dcmp_ctrl; + + if (layer >= GFBG_MAX_LAYER_NUM) { + OT_TRACE(OT_DBG_ERR, OT_ID_FB, "Error, %s(),%d Select Wrong Layer ID\n", __FUNCTION__, __LINE__); + } + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + gfx_dcmp_ctrl.u32 = fb_hal_read_reg((td_u32 *)((uintptr_t)(&(g_gfbg_reg->vdp_v3r2_line_osd_dcmp_glb_info.u32)) + + layer * FDR_GFX_OFFSET)); + gfx_dcmp_ctrl.bits.conv_en = conv_en; + fb_hal_write_reg((td_u32 *)((uintptr_t)(&(g_gfbg_reg->vdp_v3r2_line_osd_dcmp_glb_info.u32)) + + layer * FDR_GFX_OFFSET), gfx_dcmp_ctrl.u32); + + return; +} + +td_void fb_hal_v3r2_gfx_set_cmp_mode(td_u32 layer, td_u32 cmp_mode) +{ + volatile u_vdp_v3r2_line_osd_dcmp_glb_info gfx_dcmp_ctrl; + + if (layer >= GFBG_MAX_LAYER_NUM) { + OT_TRACE(OT_DBG_ERR, OT_ID_FB, "Error, %s(),%d Select Wrong Layer ID\n", __FUNCTION__, __LINE__); + } + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + gfx_dcmp_ctrl.u32 = fb_hal_read_reg((td_u32 *)((uintptr_t)(&(g_gfbg_reg->vdp_v3r2_line_osd_dcmp_glb_info.u32)) + + layer * FDR_GFX_OFFSET)); + gfx_dcmp_ctrl.bits.cmp_mode = cmp_mode; + fb_hal_write_reg((td_u32 *)((uintptr_t)(&(g_gfbg_reg->vdp_v3r2_line_osd_dcmp_glb_info.u32)) + + layer * FDR_GFX_OFFSET), gfx_dcmp_ctrl.u32); + + return; +} + +td_void fb_hal_v3r2_gfx_set_is_ice_en(td_u32 layer, td_u32 ice_en) +{ + volatile u_vdp_v3r2_line_osd_dcmp_glb_info gfx_dcmp_ctrl; + + if (layer >= GFBG_MAX_LAYER_NUM) { + OT_TRACE(OT_DBG_ERR, OT_ID_FB, "Error, %s(),%d Select Wrong Layer ID\n", __FUNCTION__, __LINE__); + } + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + gfx_dcmp_ctrl.u32 = fb_hal_read_reg((td_u32 *)((uintptr_t)(&(g_gfbg_reg->vdp_v3r2_line_osd_dcmp_glb_info.u32)) + + layer * FDR_GFX_OFFSET)); + gfx_dcmp_ctrl.bits.ice_en = ice_en; + fb_hal_write_reg((td_u32 *)((uintptr_t)(&(g_gfbg_reg->vdp_v3r2_line_osd_dcmp_glb_info.u32)) + + layer * FDR_GFX_OFFSET), gfx_dcmp_ctrl.u32); + + return; +} + +td_void fb_hal_v3r2_gfx_set_frame_size(td_u32 layer, td_u32 width, td_u32 height) +{ + volatile u_vdp_v3r2_line_osd_dcmp_frame_size frame_size; + + if (layer >= GFBG_MAX_LAYER_NUM) { + OT_TRACE(OT_DBG_ERR, OT_ID_FB, "Error, %s(),%d Select Wrong Layer ID\n", __FUNCTION__, __LINE__); + } + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + frame_size.u32 = fb_hal_read_reg((td_u32 *)((uintptr_t)(&(g_gfbg_reg->vdp_v3r2_line_osd_dcmp_frame_size.u32)) + + layer * FDR_GFX_OFFSET)); + frame_size.bits.frame_width = width - 1; + frame_size.bits.frame_height = height - 1; + fb_hal_write_reg((td_u32 *)((uintptr_t)(&(g_gfbg_reg->vdp_v3r2_line_osd_dcmp_frame_size.u32)) + + layer * FDR_GFX_OFFSET), frame_size.u32); +} +#endif +#endif + +/********************************************************************************** +* Begin : Graphic layer ZME relative hal functions. +**********************************************************************************/ +td_void hal_g0_zme_set_ck_gt_en(td_u32 ck_gt_en) +{ + volatile u_g0_zme_hinfo g0_zme_hinfo; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g0_zme_hinfo.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g0_zme_hinfo.u32)); + g0_zme_hinfo.bits.ck_gt_en = ck_gt_en; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g0_zme_hinfo.u32), g0_zme_hinfo.u32); + + return; +} + +td_void hal_g0_zme_set_out_width(td_u32 out_width) +{ + volatile u_g0_zme_hinfo g0_zme_hinfo; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g0_zme_hinfo.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g0_zme_hinfo.u32)); + g0_zme_hinfo.bits.out_width = out_width - 1; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g0_zme_hinfo.u32), g0_zme_hinfo.u32); + + return; +} + +td_void hal_g0_zme_set_hfir_en(td_u32 hfir_en) +{ + volatile u_g0_zme_hsp g0_zme_hsp; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g0_zme_hsp.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g0_zme_hsp.u32)); + g0_zme_hsp.bits.hfir_en = hfir_en; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g0_zme_hsp.u32), g0_zme_hsp.u32); + + return; +} + +td_void hal_g0_zme_set_ahfir_mid_en(td_u32 ahfir_mid_en) +{ + volatile u_g0_zme_hsp g0_zme_hsp; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g0_zme_hsp.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g0_zme_hsp.u32)); + g0_zme_hsp.bits.ahfir_mid_en = ahfir_mid_en; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g0_zme_hsp.u32), g0_zme_hsp.u32); + + return; +} + +td_void hal_g0_zme_set_lhfir_mid_en(td_u32 lhfir_mid_en) +{ + volatile u_g0_zme_hsp g0_zme_hsp; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g0_zme_hsp.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g0_zme_hsp.u32)); + g0_zme_hsp.bits.lhfir_mid_en = lhfir_mid_en; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g0_zme_hsp.u32), g0_zme_hsp.u32); + + return; +} + +td_void hal_g0_zme_set_chfir_mid_en(td_u32 chfir_mid_en) +{ + volatile u_g0_zme_hsp g0_zme_hsp; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g0_zme_hsp.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g0_zme_hsp.u32)); + g0_zme_hsp.bits.chfir_mid_en = chfir_mid_en; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g0_zme_hsp.u32), g0_zme_hsp.u32); + + return; +} + +td_void hal_g0_zme_set_lhfir_mode(td_u32 lhfir_mode) +{ + volatile u_g0_zme_hsp g0_zme_hsp; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g0_zme_hsp.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g0_zme_hsp.u32)); + g0_zme_hsp.bits.lhfir_mode = lhfir_mode; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g0_zme_hsp.u32), g0_zme_hsp.u32); + + return; +} + +td_void hal_g0_zme_set_ahfir_mode(td_u32 ahfir_mode) +{ + volatile u_g0_zme_hsp g0_zme_hsp; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g0_zme_hsp.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g0_zme_hsp.u32)); + g0_zme_hsp.bits.ahfir_mode = ahfir_mode; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g0_zme_hsp.u32), g0_zme_hsp.u32); + + return; +} + +td_void hal_g0_zme_set_hfir_order(td_u32 hfir_order) +{ + volatile u_g0_zme_hsp g0_zme_hsp; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g0_zme_hsp.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g0_zme_hsp.u32)); + g0_zme_hsp.bits.hfir_order = hfir_order; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g0_zme_hsp.u32), g0_zme_hsp.u32); + + return; +} + +td_void hal_g0_zme_set_hratio(td_u32 hratio) +{ + volatile u_g0_zme_hsp g0_zme_hsp; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g0_zme_hsp.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g0_zme_hsp.u32)); + g0_zme_hsp.bits.hratio = hratio; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g0_zme_hsp.u32), g0_zme_hsp.u32); + + return; +} + +td_void hal_g0_zme_set_lhfir_offset(td_u32 lhfir_offset) +{ + volatile u_g0_zme_hloffset g0_zme_hloffset; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g0_zme_hloffset.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g0_zme_hloffset.u32)); + g0_zme_hloffset.bits.lhfir_offset = lhfir_offset; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g0_zme_hloffset.u32), g0_zme_hloffset.u32); + + return; +} + +td_void hal_g0_zme_set_chfir_offset(td_u32 chfir_offset) +{ + volatile u_g0_zme_hcoffset g0_zme_hcoffset; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g0_zme_hcoffset.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g0_zme_hcoffset.u32)); + g0_zme_hcoffset.bits.chfir_offset = chfir_offset; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g0_zme_hcoffset.u32), g0_zme_hcoffset.u32); + + return; +} + +td_void hal_g0_zme_set_out_pro(td_u32 out_pro) +{ + volatile u_g0_zme_vinfo g0_zme_vinfo; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g0_zme_vinfo.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g0_zme_vinfo.u32)); + g0_zme_vinfo.bits.out_pro = out_pro; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g0_zme_vinfo.u32), g0_zme_vinfo.u32); + + return; +} + +td_void hal_g0_zme_set_out_height(td_u32 out_height) +{ + volatile u_g0_zme_vinfo g0_zme_vinfo; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g0_zme_vinfo.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g0_zme_vinfo.u32)); + g0_zme_vinfo.bits.out_height = out_height - 1; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g0_zme_vinfo.u32), g0_zme_vinfo.u32); + + return; +} + +td_void hal_g0_zme_set_vfir_en(td_u32 vfir_en) +{ + volatile u_g0_zme_vsp g0_zme_vsp; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g0_zme_vsp.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g0_zme_vsp.u32)); + g0_zme_vsp.bits.vfir_en = vfir_en; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g0_zme_vsp.u32), g0_zme_vsp.u32); + + return; +} + +td_void hal_g0_zme_set_avfir_mid_en(td_u32 avfir_mid_en) +{ + volatile u_g0_zme_vsp g0_zme_vsp; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g0_zme_vsp.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g0_zme_vsp.u32)); + g0_zme_vsp.bits.avfir_mid_en = avfir_mid_en; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g0_zme_vsp.u32), g0_zme_vsp.u32); + + return; +} + +td_void hal_g0_zme_set_lvfir_mid_en(td_u32 lvfir_mid_en) +{ + volatile u_g0_zme_vsp g0_zme_vsp; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g0_zme_vsp.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g0_zme_vsp.u32)); + g0_zme_vsp.bits.lvfir_mid_en = lvfir_mid_en; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g0_zme_vsp.u32), g0_zme_vsp.u32); + + return; +} + +td_void hal_g0_zme_set_cvfir_mid_en(td_u32 cvfir_mid_en) +{ + volatile u_g0_zme_vsp g0_zme_vsp; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g0_zme_vsp.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g0_zme_vsp.u32)); + g0_zme_vsp.bits.cvfir_mid_en = cvfir_mid_en; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g0_zme_vsp.u32), g0_zme_vsp.u32); + + return; +} + +td_void hal_g0_zme_set_lvfir_mode(td_u32 lvfir_mode) +{ + volatile u_g0_zme_vsp g0_zme_vsp; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g0_zme_vsp.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g0_zme_vsp.u32)); + g0_zme_vsp.bits.lvfir_mode = lvfir_mode; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g0_zme_vsp.u32), g0_zme_vsp.u32); + + return; +} + +td_void hal_g0_zme_set_vafir_mode(td_u32 vafir_mode) +{ + volatile u_g0_zme_vsp g0_zme_vsp; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g0_zme_vsp.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g0_zme_vsp.u32)); + g0_zme_vsp.bits.vafir_mode = vafir_mode; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g0_zme_vsp.u32), g0_zme_vsp.u32); + + return; +} + +td_void hal_g0_zme_set_vratio(td_u32 vratio) +{ + volatile u_g0_zme_vsp g0_zme_vsp; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g0_zme_vsp.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g0_zme_vsp.u32)); + g0_zme_vsp.bits.vratio = vratio; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g0_zme_vsp.u32), g0_zme_vsp.u32); + + return; +} + +td_void hal_g0_zme_set_vtp_offset(td_u32 vtp_offset) +{ + volatile u_g0_zme_voffset g0_zme_voffset; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g0_zme_voffset.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g0_zme_voffset.u32)); + g0_zme_voffset.bits.vtp_offset = vtp_offset; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g0_zme_voffset.u32), g0_zme_voffset.u32); + + return; +} + +td_void hal_g0_zme_set_vbtm_offset(td_u32 vbtm_offset) +{ + volatile u_g0_zme_voffset g0_zme_voffset; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g0_zme_voffset.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g0_zme_voffset.u32)); + g0_zme_voffset.bits.vbtm_offset = vbtm_offset; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g0_zme_voffset.u32), g0_zme_voffset.u32); + + return; +} + +/********************************************************************************** +* Begin : Graphic layer ZME relative hal functions. +**********************************************************************************/ +#ifdef CONFIG_GFBG_G1_SUPPORT_ZME +td_void hal_g1_zme_set_ck_gt_en(td_u32 ck_gt_en) +{ + volatile u_g1_zme_hinfo g1_zme_hinfo; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g1_zme_hinfo.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g1_zme_hinfo.u32)); + g1_zme_hinfo.bits.ck_gt_en = ck_gt_en; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g1_zme_hinfo.u32), g1_zme_hinfo.u32); + + return; +} + +td_void hal_g1_zme_set_out_width(td_u32 out_width) +{ + volatile u_g1_zme_hinfo g1_zme_hinfo; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g1_zme_hinfo.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g1_zme_hinfo.u32)); + g1_zme_hinfo.bits.out_width = out_width - 1; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g1_zme_hinfo.u32), g1_zme_hinfo.u32); + + return; +} + +td_void hal_g1_zme_set_hfir_en(td_u32 hfir_en) +{ + volatile u_g1_zme_hsp g1_zme_hsp; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g1_zme_hsp.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g1_zme_hsp.u32)); + g1_zme_hsp.bits.hfir_en = hfir_en; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g1_zme_hsp.u32), g1_zme_hsp.u32); + + return; +} + +td_void hal_g1_zme_set_ahfir_mid_en(td_u32 ahfir_mid_en) +{ + volatile u_g1_zme_hsp g1_zme_hsp; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g1_zme_hsp.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g1_zme_hsp.u32)); + g1_zme_hsp.bits.ahfir_mid_en = ahfir_mid_en; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g1_zme_hsp.u32), g1_zme_hsp.u32); + + return; +} + +td_void hal_g1_zme_set_lhfir_mid_en(td_u32 lhfir_mid_en) +{ + volatile u_g1_zme_hsp g1_zme_hsp; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g1_zme_hsp.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g1_zme_hsp.u32)); + g1_zme_hsp.bits.lhfir_mid_en = lhfir_mid_en; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g1_zme_hsp.u32), g1_zme_hsp.u32); + + return; +} + +td_void hal_g1_zme_set_chfir_mid_en(td_u32 chfir_mid_en) +{ + volatile u_g1_zme_hsp g1_zme_hsp; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g1_zme_hsp.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g1_zme_hsp.u32)); + g1_zme_hsp.bits.chfir_mid_en = chfir_mid_en; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g1_zme_hsp.u32), g1_zme_hsp.u32); + + return; +} + +td_void hal_g1_zme_set_lhfir_mode(td_u32 lhfir_mode) +{ + volatile u_g1_zme_hsp g1_zme_hsp; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g1_zme_hsp.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g1_zme_hsp.u32)); + g1_zme_hsp.bits.lhfir_mode = lhfir_mode; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g1_zme_hsp.u32), g1_zme_hsp.u32); + + return; +} + +td_void hal_g1_zme_set_ahfir_mode(td_u32 ahfir_mode) +{ + volatile u_g1_zme_hsp g1_zme_hsp; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g1_zme_hsp.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g1_zme_hsp.u32)); + g1_zme_hsp.bits.ahfir_mode = ahfir_mode; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g1_zme_hsp.u32), g1_zme_hsp.u32); + + return; +} + +td_void hal_g1_zme_set_hfir_order(td_u32 hfir_order) +{ + volatile u_g1_zme_hsp g1_zme_hsp; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g1_zme_hsp.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g1_zme_hsp.u32)); + g1_zme_hsp.bits.hfir_order = hfir_order; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g1_zme_hsp.u32), g1_zme_hsp.u32); + + return; +} + +td_void hal_g1_zme_set_hratio(td_u32 hratio) +{ + volatile u_g1_zme_hsp g1_zme_hsp; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g1_zme_hsp.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g1_zme_hsp.u32)); + g1_zme_hsp.bits.hratio = hratio; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g1_zme_hsp.u32), g1_zme_hsp.u32); + + return; +} + +td_void hal_g1_zme_set_lhfir_offset(td_u32 lhfir_offset) +{ + volatile u_g1_zme_hloffset g1_zme_hloffset; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g1_zme_hloffset.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g1_zme_hloffset.u32)); + g1_zme_hloffset.bits.lhfir_offset = lhfir_offset; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g1_zme_hloffset.u32), g1_zme_hloffset.u32); + + return; +} + +td_void hal_g1_zme_set_chfir_offset(td_u32 chfir_offset) +{ + volatile u_g1_zme_hcoffset g1_zme_hcoffset; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g1_zme_hcoffset.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g1_zme_hcoffset.u32)); + g1_zme_hcoffset.bits.chfir_offset = chfir_offset; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g1_zme_hcoffset.u32), g1_zme_hcoffset.u32); + + return; +} + +td_void hal_g1_zme_set_out_pro(td_u32 out_pro) +{ + volatile u_g1_zme_vinfo g1_zme_vinfo; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g1_zme_vinfo.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g1_zme_vinfo.u32)); + g1_zme_vinfo.bits.out_pro = out_pro; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g1_zme_vinfo.u32), g1_zme_vinfo.u32); + + return; +} + +td_void hal_g1_zme_set_out_height(td_u32 out_height) +{ + volatile u_g1_zme_vinfo g1_zme_vinfo; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g1_zme_vinfo.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g1_zme_vinfo.u32)); + g1_zme_vinfo.bits.out_height = out_height - 1; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g1_zme_vinfo.u32), g1_zme_vinfo.u32); + + return; +} + +td_void hal_g1_zme_set_vfir_en(td_u32 vfir_en) +{ + volatile u_g1_zme_vsp g1_zme_vsp; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g1_zme_vsp.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g1_zme_vsp.u32)); + g1_zme_vsp.bits.vfir_en = vfir_en; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g1_zme_vsp.u32), g1_zme_vsp.u32); + + return; +} + +td_void hal_g1_zme_set_avfir_mid_en(td_u32 avfir_mid_en) +{ + volatile u_g1_zme_vsp g1_zme_vsp; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g1_zme_vsp.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g1_zme_vsp.u32)); + g1_zme_vsp.bits.avfir_mid_en = avfir_mid_en; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g1_zme_vsp.u32), g1_zme_vsp.u32); + + return; +} + +td_void hal_g1_zme_set_lvfir_mid_en(td_u32 lvfir_mid_en) +{ + volatile u_g1_zme_vsp g1_zme_vsp; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g1_zme_vsp.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g1_zme_vsp.u32)); + g1_zme_vsp.bits.lvfir_mid_en = lvfir_mid_en; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g1_zme_vsp.u32), g1_zme_vsp.u32); + + return; +} + +td_void hal_g1_zme_set_cvfir_mid_en(td_u32 cvfir_mid_en) +{ + volatile u_g1_zme_vsp g1_zme_vsp; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g1_zme_vsp.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g1_zme_vsp.u32)); + g1_zme_vsp.bits.cvfir_mid_en = cvfir_mid_en; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g1_zme_vsp.u32), g1_zme_vsp.u32); + + return; +} + +td_void hal_g1_zme_set_lvfir_mode(td_u32 lvfir_mode) +{ + volatile u_g1_zme_vsp g1_zme_vsp; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g1_zme_vsp.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g1_zme_vsp.u32)); + g1_zme_vsp.bits.lvfir_mode = lvfir_mode; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g1_zme_vsp.u32), g1_zme_vsp.u32); + + return; +} + +td_void hal_g1_zme_set_vafir_mode(td_u32 vafir_mode) +{ + volatile u_g1_zme_vsp g1_zme_vsp; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g1_zme_vsp.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g1_zme_vsp.u32)); + g1_zme_vsp.bits.vafir_mode = vafir_mode; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g1_zme_vsp.u32), g1_zme_vsp.u32); + + return; +} + +td_void hal_g1_zme_set_vratio(td_u32 vratio) +{ + volatile u_g1_zme_vsp g1_zme_vsp; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g1_zme_vsp.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g1_zme_vsp.u32)); + g1_zme_vsp.bits.vratio = vratio; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g1_zme_vsp.u32), g1_zme_vsp.u32); + + return; +} + +td_void hal_g1_zme_set_vtp_offset(td_u32 vtp_offset) +{ + volatile u_g1_zme_voffset g1_zme_voffset; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g1_zme_voffset.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g1_zme_voffset.u32)); + g1_zme_voffset.bits.vtp_offset = vtp_offset; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g1_zme_voffset.u32), g1_zme_voffset.u32); + + return; +} + +td_void hal_g1_zme_set_vbtm_offset(td_u32 vbtm_offset) +{ + volatile u_g1_zme_voffset g1_zme_voffset; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + g1_zme_voffset.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->g1_zme_voffset.u32)); + g1_zme_voffset.bits.vbtm_offset = vbtm_offset; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->g1_zme_voffset.u32), g1_zme_voffset.u32); + + return; +} +#endif + +#ifndef CONFIG_TDE_CLUT_RECT_V2 +td_void hal_clut_set_up_param(td_u32 layer_id, td_phys_addr_t clut_phy_addr) +{ + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + if (layer_id != GFBG_FMT_CLUT_LAYER_G3) { + HAL_PRINT("layer%u doesn't support clut\n", layer_id); + return; + } + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->para_haddr_vhd_chn11), get_high_addr(clut_phy_addr)); + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->para_addr_vhd_chn11), get_low_addr(clut_phy_addr)); +} + +td_void hal_clut_set_up(td_u32 layer_id) +{ + volatile u_para_up_vhd para_up_vhd; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("g_gfbg_reg is NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + if (layer_id != GFBG_FMT_CLUT_LAYER_G3) { + HAL_PRINT("layer%u doesn't support clut\n", layer_id); + return; + } + para_up_vhd.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->para_up_vhd.u32)); + /* up */ + para_up_vhd.bits.para_up_vhd_chn11 = 0x1; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->para_up_vhd.u32), para_up_vhd.u32); +} +#else +td_void hal_clut_set_up_param(td_u32 layer_id, td_phys_addr_t clut_phy_addr) +{ + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + if (layer_id == GFBG_FMT_CLUT_LAYER_G3 || layer_id == GFBG_FMT_CLUT_LAYER_G0) { + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->para_haddr_vhd_chn07), get_high_addr(clut_phy_addr)); + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->para_addr_vhd_chn07), get_low_addr(clut_phy_addr)); +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC + } else if (layer_id == GFBG_FMT_CLUT_LAYER_G4) { + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->para_haddr_vhd_chn06), get_high_addr(clut_phy_addr)); + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->para_addr_vhd_chn06), get_low_addr(clut_phy_addr)); +#endif + } else { + HAL_PRINT("layer%u doesn't support clut\n", layer_id); + } +} + +td_void hal_clut_set_up(td_u32 layer_id) +{ + volatile u_para_up_vhd para_up_vhd; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + para_up_vhd.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->para_up_vhd.u32)); + if (layer_id == GFBG_FMT_CLUT_LAYER_G3 || layer_id == GFBG_FMT_CLUT_LAYER_G0) { + /* up */ + para_up_vhd.bits.para_up_vhd_chn07 = 0x1; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->para_up_vhd.u32), para_up_vhd.u32); +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC + } else if (layer_id == GFBG_FMT_CLUT_LAYER_G4) { + /* up */ + para_up_vhd.bits.para_up_vhd_chn06 = 0x1; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->para_up_vhd.u32), para_up_vhd.u32); +#endif + } else { + HAL_PRINT("layer%u doesn't support clut\n", layer_id); + } +} + +#endif + +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC +#ifndef CONFIG_GFBG_SMART_RECT_V2 +td_void hal_smart_rect_set_up(td_u32 layer_id, td_phys_addr_t phys_addr) +{ + volatile u_osb_mute_bk osb_mute_bk; + + if (layer_id != SMART_RECT_LAYER_G3) { + return; + } + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->para_haddr_vhd_chn05), get_high_addr(phys_addr)); + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->para_addr_vhd_chn05), get_low_addr(phys_addr)); + + /* enable OSB_MUTE_BK */ + osb_mute_bk.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->osb_mute_bk.u32)); + osb_mute_bk.bits.osb_mute_en = 0x1; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->osb_mute_bk.u32), osb_mute_bk.u32); +} +#else +td_void hal_smart_rect_set_up(td_u32 layer_id, td_phys_addr_t phys_addr) +{ + volatile u_g0_mute_bk g0_mute_bk; + volatile u_g0_lbox_ctrl g0_lbox_ctrl; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + if (layer_id == SMART_RECT_LAYER_G3) { + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->para_haddr_vhd_chn03), get_high_addr(phys_addr)); + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->para_addr_vhd_chn03), get_low_addr(phys_addr)); + } else if (layer_id == SMART_RECT_LAYER_G4) { + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->para_haddr_vhd_chn02), get_high_addr(phys_addr)); + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->para_addr_vhd_chn02), get_low_addr(phys_addr)); + } + + g0_mute_bk.u32 = 0x0; + fb_hal_write_reg((td_u32 *)((uintptr_t)(&(g_gfbg_reg->g0_mute_bk.u32)) + layer_id * FDR_GFX_OFFSET), + g0_mute_bk.u32); + + g0_lbox_ctrl.u32 = fb_hal_read_reg((td_u32 *)((uintptr_t)(&(g_gfbg_reg->g0_lbox_ctrl.u32)) + + layer_id * FDR_GFX_OFFSET)); + g0_lbox_ctrl.bits.mute_en = 0x1; + fb_hal_write_reg((td_u32 *)((uintptr_t)(&(g_gfbg_reg->g0_lbox_ctrl.u32)) + layer_id * FDR_GFX_OFFSET), + g0_lbox_ctrl.u32); + return; +} +#endif + +td_void hal_smart_rect_up_param(td_u32 layer_id) +{ + volatile u_para_up_vhd para_up_vhd; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + para_up_vhd.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->para_up_vhd.u32)); +#ifndef CONFIG_GFBG_SMART_RECT_V2 + /* up */ + if (layer_id == SMART_RECT_LAYER_G3) { + para_up_vhd.bits.para_up_vhd_chn05 = 0x1; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->para_up_vhd.u32), para_up_vhd.u32); + } +#else + if (layer_id == SMART_RECT_LAYER_G3) { + para_up_vhd.bits.para_up_vhd_chn03 = 0x1; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->para_up_vhd.u32), para_up_vhd.u32); + } else if (layer_id == SMART_RECT_LAYER_G4) { + para_up_vhd.bits.para_up_vhd_chn02 = 0x1; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->para_up_vhd.u32), para_up_vhd.u32); + } +#endif + return; +} + +#ifndef CONFIG_GFBG_SMART_RECT_V2 +td_void hal_smart_rect_disable(td_u32 layer_id) +{ + volatile u_osb_mute_bk osb_mute_bk; + ot_unused(layer_id); + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + /* disable OSB_MUTE_BK */ + osb_mute_bk.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->osb_mute_bk.u32)); + osb_mute_bk.bits.osb_mute_en = 0x0; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->osb_mute_bk.u32), osb_mute_bk.u32); +} +#else +td_void hal_smart_rect_disable(td_u32 layer_id) +{ + volatile u_g0_lbox_ctrl g0_lbox_ctrl; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + g0_lbox_ctrl.u32 = fb_hal_read_reg((td_u32 *)((uintptr_t)(&(g_gfbg_reg->g0_lbox_ctrl.u32)) + + layer_id * FDR_GFX_OFFSET)); + g0_lbox_ctrl.bits.mute_en = 0x0; + fb_hal_write_reg((td_u32 *)((uintptr_t)(&(g_gfbg_reg->g0_lbox_ctrl.u32)) + layer_id * FDR_GFX_OFFSET), + g0_lbox_ctrl.u32); + return; +} +#endif +#endif + +td_void hal_gfx_set_bind_mode(td_bool is_sync) +{ + volatile u_gfx_mac_ctrl gfx_mac_ctrl; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + gfx_mac_ctrl.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->gfx_mac_ctrl)); + if (is_sync == TD_TRUE) { + gfx_mac_ctrl.bits.req_ld_mode = 1; /* bind G0 */ + } else { + gfx_mac_ctrl.bits.req_ld_mode = 0; /* not bind */ + } + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->gfx_mac_ctrl.u32), gfx_mac_ctrl.u32); + return; +} + +td_void hal_gfx_set_hardware_mute_clr(td_u32 hw_mute_clr) +{ + volatile u_gfx_ld_ctrl gfx_ld_ctrl; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + gfx_ld_ctrl.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->gfx_ld_ctrl)); + gfx_ld_ctrl.bits.hw_mute_clr = hw_mute_clr; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->gfx_ld_ctrl.u32), gfx_ld_ctrl.u32); + return; +} + +td_void hal_gfx_set_tde_safe_dis(td_u32 start_safe_dis) +{ + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->gfx_tde_safe_dis), start_safe_dis); + return; +} + +td_void hal_gfx_set_ld_mute_en(td_u32 ld_mute_en) +{ + volatile u_gfx_ld_ctrl gfx_ld_ctrl; + + if (g_gfbg_reg == TD_NULL) { + HAL_PRINT("NULL pointer %s: L%d\n", __FUNCTION__, __LINE__); + return; + } + + gfx_ld_ctrl.u32 = fb_hal_read_reg((td_u32 *)&(g_gfbg_reg->gfx_ld_ctrl)); + gfx_ld_ctrl.bits.ld_mute_en = ld_mute_en; + fb_hal_write_reg((td_u32 *)&(g_gfbg_reg->gfx_ld_ctrl.u32), gfx_ld_ctrl.u32); + return; +} + diff --git a/kernel/gfbg/hi3519dv500/drv/adp/gfbg_graphic_hal.h b/kernel/gfbg/hi3519dv500/drv/adp/gfbg_graphic_hal.h new file mode 100755 index 00000000..c1437ffa --- /dev/null +++ b/kernel/gfbg/hi3519dv500/drv/adp/gfbg_graphic_hal.h @@ -0,0 +1,173 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef GFBG_GRAPHIC_HAL_H +#define GFBG_GRAPHIC_HAL_H + +#include "gfbg.h" +#include "gfbg_reg.h" +#include "gfbg_def.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +td_s32 fb_hal_gfbg_init(td_void); +td_void fb_hal_gfbg_deinit(td_void); + +/* Prototype : device Relative */ +td_s32 fb_hal_disp_get_intf_enable(hal_disp_outputchannel chan, td_bool *intf_en); + +td_s32 fb_hal_disp_get_intf_sync(hal_disp_outputchannel chan, hal_disp_syncinfo *sync_info); +td_s32 fb_hal_disp_get_disp_iop(hal_disp_outputchannel chan, td_bool *iop); +td_s32 fb_hal_disp_get_intf_mux_sel(hal_disp_outputchannel chan, vo_intf_type *intf_type); +td_s32 fb_hal_disp_get_vt_thd_mode(hal_disp_outputchannel chan, td_bool *field_mode); + +td_u32 fb_hal_disp_get_int_status(td_u32 int_msk); +td_s32 fb_hal_disp_clear_int_status(td_u32 int_msk); + +td_s32 fb_hal_video_set_layer_disp_rect(hal_disp_layer layer, const ot_fb_rect *rect); +td_s32 fb_hal_video_set_layer_video_rect(hal_disp_layer layer, const ot_fb_rect *rect); +td_s32 fb_hal_disp_set_int_mask1(td_u32 mask_en); +td_s32 fb_hal_disp_clr_int_mask1(td_u32 mask_en); + +/* Video layer CSC relative hal functions. */ +td_void fb_hal_link_get_hc_link(hal_disp_layer gfx_layer, td_u32 *data); + +td_s32 fb_hal_set_layer_enable(hal_disp_layer layer, td_u32 enable); +td_void fb_hal_set_layer_ck_gt_en(hal_disp_layer layer, td_u32 ck_gt_en); +td_s32 fb_hal_get_layer_enable(hal_disp_layer layer, td_u32 *enable); +td_s32 fb_hal_layer_set_layer_data_fmt(hal_disp_layer layer, hal_disp_pixel_format data_fmt); +td_s32 fb_hal_layer_get_layer_data_fmt(hal_disp_layer layer, td_u32 *format); + +td_s32 fb_hal_layer_set_csc_coef(hal_disp_layer layer, const csc_coef *coef, const csc_coef_param *coef_param); +td_s32 fb_hal_layer_set_csc_en(hal_disp_layer layer, td_bool cscen); + +td_s32 fb_hal_layer_set_src_resolution(hal_disp_layer layer, const ot_fb_rect *rect); +td_s32 fb_hal_layer_set_layer_in_rect(hal_disp_layer layer, const ot_fb_rect *rect); +td_s32 fb_hal_layer_set_layer_out_rect(hal_disp_layer layer, const ot_fb_rect *rect); +td_s32 fb_hal_layer_set_layer_galpha(hal_disp_layer layer, td_u8 alpha0); +td_s32 fb_hal_layer_get_layer_galpha(hal_disp_layer layer, td_u8 *alpha0); + +td_s32 fb_hal_layer_set_reg_up(hal_disp_layer layer); + +/* Prototype : graphic layer Relative */ +td_s32 fb_hal_graphic_set_gfx_addr(hal_disp_layer layer, td_phys_addr_t laddr); +td_s32 fb_hal_graphic_get_gfx_addr(hal_disp_layer layer, td_phys_addr_t *gfx_addr); +td_s32 fb_hal_graphic_set_gfx_stride(hal_disp_layer layer, td_u16 pitch); +td_s32 fb_hal_graphic_get_gfx_stride(hal_disp_layer layer, td_u32 *gfx_stride); +td_s32 fb_hal_graphic_set_gfx_ext(hal_disp_layer layer, hal_gfx_bitextend mode); +td_s32 fb_hal_graphic_set_gfx_pre_mult(hal_disp_layer layer, td_u32 enable); +td_s32 fb_hal_graphic_set_gfx_palpha(hal_disp_layer layer, td_u32 alpha_en, td_u32 arange, td_u8 alpha0, td_u8 alpha1); +td_s32 fb_hal_graphic_get_gfx_palpha(hal_disp_layer layer, td_u32 *alpha_en, td_u8 *alpha0, td_u8 *alpha1); + +td_s32 fb_hal_graphic_set_gfx_key_en(hal_disp_layer layer, td_u32 key_enable); +td_s32 fb_hal_graphic_set_gfx_key_mode(hal_disp_layer layer, td_u32 key_out); +td_s32 fb_hal_graphic_set_color_key_value(hal_disp_layer layer, hal_gfx_key_max key_max, hal_gfx_key_min key_min); +td_s32 fb_hal_graphic_set_color_key_mask(hal_disp_layer layer, hal_gfx_mask msk); + +td_s32 fb_hal_graphic_get_gfx_premult(hal_disp_layer layer, td_u32 *enable); + +/* for compress */ +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC +td_s32 fb_hal_graphic_set_gfx_dcmp_addr(hal_disp_layer layer, td_phys_addr_t addr_ar); +td_s32 fb_hal_graphic_get_gfx_dcmp_enable_state(hal_disp_layer layer, td_bool *enable); +#endif +td_s32 fb_hal_graphic_set_gfx_dcmp_enable(hal_disp_layer layer, td_u32 enable); + +td_void fb_hal_mddrc_get_status(td_u32 *status); +td_void fb_hal_mddrc_clear_status(td_u32 status); +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC +td_void fb_hal_para_set_para_addr_vhd_chn06(td_phys_addr_t para_addr_vhd_chn06); +td_void fb_hal_para_set_para_up_vhd_chn(td_u32 chn_num); +#ifdef CONFIG_TDE_GFBG_COMPRESS_V1 +td_void fb_hal_fdr_gfx_set_source_mode(td_u32 data, td_u32 source_mode); +td_void fb_hal_fdr_gfx_set_cmp_mode(td_u32 data, td_u32 cmp_mode); +td_void fb_hal_fdr_gfx_set_is_loss_lessa(td_u32 data, td_u32 is_lossless_a); +td_void fb_hal_fdr_gfx_set_is_loss_less(td_u32 data, td_u32 is_lossless); +#endif +#ifdef CONFIG_TDE_GFBG_COMPRESS_V2 +td_void fb_hal_v3r2_gfx_set_source_mode(td_u32 data, td_u32 source_mode); +td_void fb_hal_v3r2_gfx_set_cmp_mode(td_u32 data, td_u32 cmp_mode); +td_void fb_hal_v3r2_gfx_set_is_loss_less(td_u32 data, td_u32 is_lossless); +td_void fb_hal_v3r2_gfx_set_is_conv_en(td_u32 layer, td_u32 conv_en); +td_void fb_hal_v3r2_gfx_set_is_ice_en(td_u32 layer, td_u32 ice_en); +td_void fb_hal_v3r2_gfx_set_frame_size(td_u32 layer_index, td_u32 width, td_u32 height); +#endif +#endif + +td_void hal_g0_zme_set_ck_gt_en(td_u32 ck_gt_en); +td_void hal_g0_zme_set_out_width(td_u32 out_width); +td_void hal_g0_zme_set_hfir_en(td_u32 hfir_en); +td_void hal_g0_zme_set_ahfir_mid_en(td_u32 ahfir_mid_en); +td_void hal_g0_zme_set_lhfir_mid_en(td_u32 lhfir_mid_en); +td_void hal_g0_zme_set_chfir_mid_en(td_u32 chfir_mid_en); +td_void hal_g0_zme_set_lhfir_mode(td_u32 lhfir_mode); +td_void hal_g0_zme_set_ahfir_mode(td_u32 ahfir_mode); +td_void hal_g0_zme_set_hfir_order(td_u32 hfir_order); +td_void hal_g0_zme_set_hratio(td_u32 hratio); +td_void hal_g0_zme_set_lhfir_offset(td_u32 lhfir_offset); +td_void hal_g0_zme_set_chfir_offset(td_u32 chfir_offset); +td_void hal_g0_zme_set_out_pro(td_u32 out_pro); +td_void hal_g0_zme_set_out_height(td_u32 out_height); +td_void hal_g0_zme_set_vfir_en(td_u32 vfir_en); +td_void hal_g0_zme_set_avfir_mid_en(td_u32 avfir_mid_en); +td_void hal_g0_zme_set_lvfir_mid_en(td_u32 lvfir_mid_en); +td_void hal_g0_zme_set_cvfir_mid_en(td_u32 cvfir_mid_en); +td_void hal_g0_zme_set_lvfir_mode(td_u32 lvfir_mode); +td_void hal_g0_zme_set_vafir_mode(td_u32 vafir_mode); +td_void hal_g0_zme_set_vratio(td_u32 vratio); +td_void hal_g0_zme_set_vtp_offset(td_u32 vtp_offset); +td_void hal_g0_zme_set_vbtm_offset(td_u32 vbtm_offset); + +#ifdef CONFIG_GFBG_G1_SUPPORT_ZME +td_void hal_g1_zme_set_ck_gt_en(td_u32 ck_gt_en); +td_void hal_g1_zme_set_out_width(td_u32 out_width); +td_void hal_g1_zme_set_hfir_en(td_u32 hfir_en); +td_void hal_g1_zme_set_ahfir_mid_en(td_u32 ahfir_mid_en); +td_void hal_g1_zme_set_lhfir_mid_en(td_u32 lhfir_mid_en); +td_void hal_g1_zme_set_chfir_mid_en(td_u32 chfir_mid_en); +td_void hal_g1_zme_set_lhfir_mode(td_u32 lhfir_mode); +td_void hal_g1_zme_set_ahfir_mode(td_u32 ahfir_mode); +td_void hal_g1_zme_set_hfir_order(td_u32 hfir_order); +td_void hal_g1_zme_set_hratio(td_u32 hratio); +td_void hal_g1_zme_set_lhfir_offset(td_u32 lhfir_offset); +td_void hal_g1_zme_set_chfir_offset(td_u32 chfir_offset); +td_void hal_g1_zme_set_out_pro(td_u32 out_pro); +td_void hal_g1_zme_set_out_height(td_u32 out_height); +td_void hal_g1_zme_set_vfir_en(td_u32 vfir_en); +td_void hal_g1_zme_set_avfir_mid_en(td_u32 avfir_mid_en); +td_void hal_g1_zme_set_lvfir_mid_en(td_u32 lvfir_mid_en); +td_void hal_g1_zme_set_cvfir_mid_en(td_u32 cvfir_mid_en); +td_void hal_g1_zme_set_lvfir_mode(td_u32 lvfir_mode); +td_void hal_g1_zme_set_vafir_mode(td_u32 vafir_mode); +td_void hal_g1_zme_set_vratio(td_u32 vratio); +td_void hal_g1_zme_set_vtp_offset(td_u32 vtp_offset); +td_void hal_g1_zme_set_vbtm_offset(td_u32 vbtm_offset); +#endif + +td_void hal_clut_set_up_param(td_u32 layer_id, td_phys_addr_t clut_phy_addr); +td_void hal_clut_set_up(td_u32 layer_id); +/* for draw smart rect */ +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC +td_void hal_smart_rect_set_up(td_u32 layer_id, td_phys_addr_t phys_addr); +td_void hal_smart_rect_up_param(td_u32 layer_id); +td_void hal_smart_rect_disable(td_u32 layer_id); +#endif +td_void fb_hal_disp_get_int_state_vcnt(hal_disp_outputchannel chan, td_u32 *vcnt); + +/* for low delay */ +td_void hal_gfx_set_bind_mode(td_bool is_sync); +td_void hal_gfx_set_hardware_mute_clr(td_bool is_hw_mute_clr_en); +td_void hal_gfx_set_tde_safe_dis(td_u32 safe_dist); +td_void hal_gfx_set_ld_mute_en(td_bool is_mute_en); +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* GFBG_GRAPHIC_HAL_H */ \ No newline at end of file diff --git a/kernel/gfbg/hi3519dv500/drv/adp/gfbg_graphics.c b/kernel/gfbg/hi3519dv500/drv/adp/gfbg_graphics.c new file mode 100755 index 00000000..a6e3a4d8 --- /dev/null +++ b/kernel/gfbg/hi3519dv500/drv/adp/gfbg_graphics.c @@ -0,0 +1,538 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "gfbg_graphics.h" +#include "ot_osal.h" +#include "proc_ext.h" +#include "ot_debug.h" + +typedef struct { + td_bool vo_enable; /* Device enable flag */ + vo_intf_type intf_type; /* Device interface type */ + td_u32 max_width; /* Device resolution maximum width */ + td_u32 max_height; /* Device resolution maximum height */ +} fb_dev_info; + +unsigned int g_fifb_irq = GFBG_IRQ_NR; + +fb_dev_info g_ast_vo_dev[OT_VO_MAX_PHYS_DEV_NUM]; + +graphic_layer_context g_gfbg_gfx_layer_ctx[GFBG_MAX_LAYER_NUM]; +td_u32 g_fb_dectect_zone = 0; /* Record the DDR detection area used */ + +unsigned int *fb_get_gfbg_irq(td_void) +{ + return &g_fifb_irq; +} + +graphic_layer_context* fb_graphics_get_gfx_layer_ctx(td_void) +{ + return g_gfbg_gfx_layer_ctx; +} + +static td_void fb_graphics_get_gfx_dcmp_pixel(gfbg_disp_pixel_format pixel_fmt, hal_disp_pixel_format *pen_pixel_fmt) +{ + switch (pixel_fmt) { + case GFBG_INPUTFMT_ARGB_4444: + *pen_pixel_fmt = HAL_INPUTFMT_ARGB_4444; + break; + case GFBG_INPUTFMT_ARGB_1555: + *pen_pixel_fmt = HAL_INPUTFMT_ARGB_1555; + break; + case GFBG_INPUTFMT_ARGB_8888: + *pen_pixel_fmt = HAL_INPUTFMT_ARGB_8888; + break; + case GFBG_INPUTFMT_CLUT_4BPP: + *pen_pixel_fmt = HAL_INPUTFMT_CLUT_4BPP; + break; + case GFBG_INPUTFMT_CLUT_2BPP: + *pen_pixel_fmt = HAL_INPUTFMT_CLUT_2BPP; + break; + default: + graphics_drv_error("pixel format(%d) is invalid!\n", pixel_fmt); + break; + } +} + +td_s32 fb_graphics_set_gfx_key_mode(ot_gfx_layer disp_layer, td_u32 key_out) +{ + return graphic_drv_set_gfx_key_mode(disp_layer, key_out); +} + +td_s32 fb_graphics_set_gfx_ext(ot_gfx_layer disp_layer, fb_gfx_bitextend mode) +{ + return graphic_drv_set_gfx_ext(disp_layer, (hal_gfx_bitextend)mode); +} + +td_s32 fb_graphics_set_gfx_palpha(ot_gfx_layer disp_layer, td_u32 alpha_en, td_u32 arange, td_u8 alpha0, td_u8 alpha1) +{ + return graphic_drv_set_gfx_palpha(disp_layer, alpha_en, arange, alpha0, alpha1); +} + +td_s32 fb_graphics_set_layer_galpha(ot_gfx_layer disp_layer, td_u8 alpha0) +{ + return graphic_drv_layer_set_layer_galpha(disp_layer, alpha0); +} + +td_s32 fb_graphics_set_csc_en(ot_gfx_layer disp_layer, td_bool csc_en) +{ + return graphic_drv_layer_set_csc_en(disp_layer, csc_en); +} + +td_s32 fb_graphics_set_gfx_addr(ot_gfx_layer disp_layer, td_phys_addr_t l_addr) +{ + return graphic_drv_set_layer_addr(disp_layer, l_addr); +} + +td_s32 fb_graphics_set_gfx_stride(ot_gfx_layer disp_layer, td_u16 pitch) +{ + return graphic_drv_set_gfx_stride(disp_layer, pitch); +} + +td_s32 fb_graphics_get_gfx_pre_mult(ot_gfx_layer disp_layer, td_u32 *enable) +{ + return graphic_drv_get_gfx_pre_mult(disp_layer, enable); +} + +td_s32 fb_graphics_set_gfx_pre_mult(ot_gfx_layer disp_layer, td_u32 enable) +{ + return graphic_drv_set_gfx_pre_mult(disp_layer, enable); +} + +td_s32 fb_graphics_set_layer_data_fmt(ot_gfx_layer disp_layer, gfbg_disp_pixel_format data_fmt) +{ + hal_disp_pixel_format pix_fmt = HAL_INPUTFMT_ARGB_1555; + fb_graphics_get_gfx_dcmp_pixel(data_fmt, &pix_fmt); + return graphic_drv_set_layer_data_fmt(disp_layer, pix_fmt); +} + +td_s32 fb_graphics_set_layer_in_rect(ot_gfx_layer disp_layer, const ot_fb_rect *rect) +{ + return graphic_drv_set_layer_in_rect(disp_layer, rect); +} + +td_s32 fb_graphics_set_layer_src_image_reso(ot_gfx_layer disp_layer, const ot_fb_rect *rect) +{ + return graphic_drv_set_src_image_resolution(disp_layer, rect); +} + +td_s32 fb_graphics_set_layer_out_rect(ot_gfx_layer disp_layer, const ot_fb_rect *rect) +{ + return graphic_drv_set_layer_out_rect(disp_layer, rect); +} + +td_s32 fb_graphics_set_color_key_value(ot_gfx_layer disp_layer, fb_gfx_key_max vo_key_max, + fb_gfx_key_min vo_key_min) +{ + hal_gfx_key_max key_max; + hal_gfx_key_min key_min; + key_max.key_max_r = vo_key_max.key_max_r; + key_max.key_max_g = vo_key_max.key_max_g; + key_max.key_max_b = vo_key_max.key_max_b; + key_min.key_min_r = vo_key_min.key_min_r; + key_min.key_min_g = vo_key_min.key_min_g; + key_min.key_min_b = vo_key_min.key_min_b; + return graphic_drv_set_color_key_value(disp_layer, key_max, key_min); +} + +td_s32 fb_graphics_set_color_key_mask(ot_gfx_layer disp_layer, fb_gfx_mask vo_msk) +{ + hal_gfx_mask msk; + msk.mask_r = vo_msk.mask_r; + msk.mask_g = vo_msk.mask_g; + msk.mask_b = vo_msk.mask_b; + return graphic_drv_set_color_key_mask(disp_layer, msk); +} + +td_s32 fb_graphics_set_gfx_key_en(ot_gfx_layer disp_layer, td_u32 key_enable) +{ + return graphic_drv_set_gfx_key_en(disp_layer, key_enable); +} + +td_s32 fb_graphics_set_reg_up(ot_gfx_layer disp_layer) +{ + return graphic_drv_set_reg_up(disp_layer); +} + +td_void fb_graphics_set_color_reg(td_u32 layer_id, td_phys_addr_t clut_phy_addr) +{ + graphic_drv_set_clut_reg(layer_id, clut_phy_addr); + return; +} + +td_void fb_graphics_set_color_reg_up(td_u32 layer_id) +{ + graphic_drv_set_clut_reg_up(layer_id); + return; +} + +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC +td_s32 fb_graphics_set_frame_reg(td_u32 layer_id, td_phys_addr_t frame_phy_addr) +{ + return graphic_drv_set_smart_rect_reg(layer_id, frame_phy_addr); +} + +td_void fb_graphics_up_frame_param(td_u32 layer_id) +{ + return graphic_drv_smart_rect_up_param(layer_id); +} + +td_void fb_graphics_close_smart_rect(td_s32 layer_id) +{ + return graphic_drv_smart_rect_disable(layer_id); +} +#endif + +td_s32 fb_graphics_init(td_void) +{ + td_s32 ret; + ot_vo_dev vo_dev; + hal_disp_syncinfo sync_info = {0}; + td_bool logic_ret; + td_bool vo_enable = TD_FALSE; + vo_intf_type intf_type = HAL_DISP_INTF_BT1120; + td_s32 i; + + ret = fb_graphic_drv_init(); + + for (i = 0; i < OT_VO_MAX_PHYS_DEV_NUM; i++) { + vo_dev = i; + logic_ret = graphic_drv_get_dev_enable(vo_dev, &vo_enable); + if (logic_ret != TD_SUCCESS) { + continue; + } else { + g_ast_vo_dev[vo_dev].vo_enable = vo_enable; + } + + logic_ret = graphic_drv_get_intf_sync(vo_dev, &sync_info); + if (logic_ret != TD_SUCCESS) { + continue; + } else { + g_ast_vo_dev[vo_dev].max_width = sync_info.hact; + /* 2 alg data */ + g_ast_vo_dev[vo_dev].max_height = (sync_info.iop) ? sync_info.vact : (sync_info.vact * 2); + } + + logic_ret = graphic_drv_get_intf_mux_sel(vo_dev, &intf_type); + if (logic_ret != TD_SUCCESS) { + continue; + } else { + g_ast_vo_dev[vo_dev].intf_type = intf_type; + } + } + + return ret; +} + +td_s32 fb_graphics_deinit(td_void) +{ + return fb_graphic_drv_exit(); +} + +td_s32 fb_graphics_get_layer_galpha(ot_gfx_layer disp_layer, td_u8 *alpha0) +{ + return graphic_drv_get_layer_galpha(disp_layer, alpha0); +} + +td_s32 fb_graphics_get_layer_data_fmt(ot_gfx_layer disp_layer, td_u32 *fmt) +{ + return graphic_drv_get_layer_data_fmt(disp_layer, fmt); +} + +td_s32 fb_graphics_get_gfx_addr(ot_gfx_layer disp_layer, td_phys_addr_t *gfx_addr) +{ + return graphic_drv_get_gfx_addr(disp_layer, gfx_addr); +} + +td_s32 fb_graphics_get_gfx_stride(ot_gfx_layer disp_layer, td_u32 *gfx_stride) +{ + return graphic_drv_get_gfx_stride(disp_layer, gfx_stride); +} + +td_s32 fb_graphics_get_dev_mode(hal_disp_layer layer, fb_scan_mode *scan_mode, td_bool *feild_update) +{ + ot_vo_dev vo_dev; + td_u32 layer_index; + unsigned long lock_flag; + graphic_layer_context *gfx_layer_ctx = TD_NULL; + if (fb_graphic_drv_get_layer_index(layer, &layer_index) != TD_SUCCESS) { + graphics_drv_error("gfx_layer(%u) is invalid!\n", (td_u32)layer); + return TD_FAILURE; + } + gfx_layer_ctx = &g_gfbg_gfx_layer_ctx[layer_index]; + gfx_spin_lock_irqsave(&gfx_layer_ctx->spin_lock, &lock_flag); + if (!gfx_layer_ctx->binded) { + gfx_spin_unlock_irqrestore(&gfx_layer_ctx->spin_lock, &lock_flag); + gfbg_graphics_error("graphics layer %d has not been binded!\n", layer_index); + return TD_FAILURE; + } + vo_dev = gfx_layer_ctx->binded_dev; + if (!g_ast_vo_dev[vo_dev].vo_enable) { + gfx_spin_unlock_irqrestore(&gfx_layer_ctx->spin_lock, &lock_flag); + gfbg_graphics_error("vodev %d for graphics layer %d has been disable!\n", vo_dev, layer_index); + return TD_FAILURE; + } + if (fb_graphic_drv_get_scan_mode(vo_dev, (td_bool *)scan_mode) != TD_SUCCESS) { + gfx_spin_unlock_irqrestore(&gfx_layer_ctx->spin_lock, &lock_flag); + gfbg_graphics_error("get vodev:%d scan mode failed!\n", vo_dev); + return TD_FAILURE; + } + if (graphic_drv_get_vt_thd_mode(vo_dev, feild_update) != TD_SUCCESS) { + gfx_spin_unlock_irqrestore(&gfx_layer_ctx->spin_lock, &lock_flag); + gfbg_graphics_error("get vodev:%d scan mode failed!\n", vo_dev); + return TD_FAILURE; + } + gfx_spin_unlock_irqrestore(&gfx_layer_ctx->spin_lock, &lock_flag); + return TD_SUCCESS; +} + +td_s32 fb_graphics_resource_init(td_void) +{ + td_s32 ret; + + ret = graphic_drv_resource_init(); + if (ret != TD_SUCCESS) { + gfbg_graphics_error("graphic drv resource init failed.\n"); + return ret; + } + + return ret; +} + +td_s32 fb_graphics_resource_deinit(td_void) +{ + td_s32 ret; + ret = graphic_drv_resource_exit(); + return ret; +} + +td_s32 fb_graphics_set_layer_enable(ot_gfx_layer gfx_layer, td_bool enable) +{ + if ((gfx_layer < LAYER_GFX_START) || (gfx_layer > LAYER_GFX_END)) { + graphics_drv_error("gfx_layer(%u) is invalid!\n", (td_u32)gfx_layer); + return TD_FAILURE; + } + return graphic_drv_set_layer_enable(gfx_layer, enable); +} + +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC +td_s32 fb_graphics_get_layer_enable(ot_gfx_layer gfx_layer, td_bool *enable) +{ + if ((gfx_layer < LAYER_GFX_START) || (gfx_layer > LAYER_GFX_END)) { + graphics_drv_error("gfx_layer(%u) is invalid!\n", (td_u32)gfx_layer); + return TD_FAILURE; + } + return graphic_drv_get_layer_enable(gfx_layer, enable); +} +#endif + +td_s32 fb_graphics_set_callback(ot_gfx_layer gfx_layer, gfbg_int_type type, vo_fb_intcallback call_back, td_void *arg) +{ + unsigned long lock_flag; + td_u32 layer_index; + td_s32 ret = TD_SUCCESS; + graphic_layer_context *gfx_layer_ctx = TD_NULL; + + if (fb_graphic_drv_get_layer_index(gfx_layer, &layer_index) != TD_SUCCESS) { + graphics_drv_error("gfx_layer(%u) is invalid!\n", (td_u32)gfx_layer); + return TD_FAILURE; + } + + gfx_layer_ctx = &g_gfbg_gfx_layer_ctx[layer_index]; + + gfx_spin_lock_irqsave(&gfx_layer_ctx->spin_lock, &lock_flag); + switch (type) { + case GFBG_INTTYPE_VO: + gfx_layer_ctx->vo_callback = (fb_intcallback)call_back; + gfx_layer_ctx->vo_callback_arg = arg; + break; + default: + ret = TD_FAILURE; + break; + } + gfx_spin_unlock_irqrestore(&gfx_layer_ctx->spin_lock, &lock_flag); + + return ret; +} + +td_s32 fb_graphics_enable_dcmp(ot_gfx_layer gfx_layer, td_bool enable) +{ + return graphic_drv_enable_dcmp(gfx_layer, enable); +} + +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC +td_s32 fb_graphics_get_dcmp_enable_state(ot_gfx_layer gfx_layer, td_bool *enable) +{ + return graphic_drv_get_dcmp_enable_state(gfx_layer, enable); +} + +td_s32 fb_graphics_set_dcmp_info(ot_gfx_layer disp_layer, const gfbg_graphic_dcmp_info *dcmp_info) +{ + graphic_dcmp_info dcmp_information = {0}; + + if (dcmp_info == TD_NULL) { + graphics_drv_error("null pointer!\n"); + return TD_FAILURE; + } + fb_graphics_get_gfx_dcmp_pixel(dcmp_info->pixel_fmt, &dcmp_information.pixel_fmt); + dcmp_information.is_lossless = dcmp_info->is_lossless; + dcmp_information.is_lossless_a = dcmp_info->is_lossless_a; + dcmp_information.ar_phy_addr = dcmp_info->ar_phy_addr; + dcmp_information.frame_size0 = dcmp_info->frame_size0; + dcmp_information.frame_size1 = dcmp_info->frame_size1; + dcmp_information.gb_phy_addr = dcmp_info->gb_phy_addr; + dcmp_information.height = dcmp_info->height; + dcmp_information.offset = dcmp_info->offset; + dcmp_information.stride = dcmp_info->stride; + dcmp_information.width = dcmp_info->width; + return graphic_drv_set_dcmp_info(disp_layer, &dcmp_information); +} +#endif + +td_s32 fb_graphics_enable_zme(ot_gfx_layer disp_layer, const ot_fb_rect *in_rect, const ot_fb_rect *out_rect, + td_bool enable) +{ + gf_zme_cfg zme_cfg; + + if (in_rect == TD_NULL || out_rect == TD_NULL) { + return TD_FAILURE; + } + zme_cfg.in_width = in_rect->width; + zme_cfg.in_height = in_rect->height; + zme_cfg.out_width = out_rect->width; + zme_cfg.out_height = out_rect->height; + + return graphic_drv_enable_zme(disp_layer, &zme_cfg, enable); +} + +td_s32 fb_graphics_get_intf_size(ot_gfx_layer gfx_layer, td_u32 *width, td_u32 *height) +{ + ot_vo_dev vo_dev; + td_u32 layer_index; + graphic_layer_context *gfx_layer_ctx = TD_NULL; + fb_dev_info *dev_info = TD_NULL; + td_bool ret; + hal_disp_syncinfo sync_info = { 0 }; + + if (width == TD_NULL || height == TD_NULL) { + return TD_FAILURE; + } + + if (fb_graphic_drv_get_layer_index(gfx_layer, &layer_index) != TD_SUCCESS) { + graphics_drv_error("gfx_layer(%u) is invalid!\n", (td_u32)gfx_layer); + return TD_FAILURE; + } + + gfx_layer_ctx = &g_gfbg_gfx_layer_ctx[layer_index]; + + if (!gfx_layer_ctx->binded) { + gfbg_graphics_error("Graphics layer %d# has not been binded!\n", layer_index); + return TD_FAILURE; + } + + vo_dev = gfx_layer_ctx->binded_dev; + dev_info = &g_ast_vo_dev[vo_dev]; + + if (!dev_info->vo_enable) { + gfbg_graphics_error("The vo device (%d) for graphics layer %d has been disable!\n", vo_dev, + layer_index); + return TD_FAILURE; + } + + /* Be sure to read from the register, otherwise the width and height of + the gfbg context will not be updated when the vo timing changes. */ + ret = graphic_drv_get_intf_sync(vo_dev, &sync_info); + if (ret != TD_SUCCESS) { + /* keep the old value. */ + } else { + g_ast_vo_dev[vo_dev].max_width = sync_info.hact; + /* 2 alg data */ + g_ast_vo_dev[vo_dev].max_height = (sync_info.iop) ? sync_info.vact : (sync_info.vact * 2); + } + + *width = dev_info->max_width; + *height = dev_info->max_height; + + return TD_SUCCESS; +} + +td_s32 fb_graphics_set_csc_coef(ot_gfx_layer gfx_layer) +{ + td_u32 layer_index; + + if (fb_graphic_drv_get_layer_index(gfx_layer, &layer_index) != TD_SUCCESS) { + graphics_drv_error("gfx_layer(%u) is invalid!\n", (td_u32)gfx_layer); + return TD_FAILURE; + } + return fb_graphic_drv_set_csc_coef(gfx_layer, &g_gfbg_gfx_layer_ctx[layer_index].gfx_csc, + &g_gfbg_gfx_layer_ctx[layer_index].coef_param); +} + +/* check the bind is exist or not when the first open */ +td_s32 fb_graphics_open_layer(ot_gfx_layer gfx_layer) +{ + ot_vo_dev vo_dev; + unsigned long lock_flag = 0; + td_u32 layer_index; + + if (fb_graphic_drv_get_layer_index(gfx_layer, &layer_index) != TD_SUCCESS) { + graphics_drv_error("gfx_layer(%u) is invalid!\n", (td_u32)gfx_layer); + return TD_FAILURE; + } + + gfx_spin_lock_irqsave(&g_gfbg_gfx_layer_ctx[layer_index].spin_lock, &lock_flag); + if (!g_gfbg_gfx_layer_ctx[layer_index].binded) { + gfx_spin_unlock_irqrestore(&g_gfbg_gfx_layer_ctx[layer_index].spin_lock, &lock_flag); + gfbg_graphics_error("graphics layer %d has not been binded!\n", layer_index); + return TD_FAILURE; + } + + vo_dev = g_gfbg_gfx_layer_ctx[layer_index].binded_dev; + + if (!g_ast_vo_dev[vo_dev].vo_enable) { + gfx_spin_unlock_irqrestore(&g_gfbg_gfx_layer_ctx[layer_index].spin_lock, &lock_flag); + gfbg_graphics_error("vodev %d for graphics layer %d has not been enable!\n", vo_dev, layer_index); + return TD_FAILURE; + } + g_gfbg_gfx_layer_ctx[layer_index].opened = TD_TRUE; + gfx_spin_unlock_irqrestore(&g_gfbg_gfx_layer_ctx[layer_index].spin_lock, &lock_flag); + return TD_SUCCESS; +} + +td_s32 fb_graphics_close_layer(ot_gfx_layer gfx_layer) +{ + unsigned long lock_flag = 0; + td_u32 layer_index; + + if (fb_graphic_drv_get_layer_index(gfx_layer, &layer_index) != TD_SUCCESS) { + graphics_drv_error("gfx_layer(%u) is invalid!\n", (td_u32)gfx_layer); + return TD_FAILURE; + } + + gfx_spin_lock_irqsave(&g_gfbg_gfx_layer_ctx[layer_index].spin_lock, &lock_flag); + g_gfbg_gfx_layer_ctx[layer_index].opened = TD_FALSE; + gfx_spin_unlock_irqrestore(&g_gfbg_gfx_layer_ctx[layer_index].spin_lock, &lock_flag); + + return TD_SUCCESS; +} + +td_s32 fb_graphics_get_int(td_u32 *int_staus) +{ + if (int_staus == TD_NULL) { + return TD_FAILURE; + } + *int_staus = graphic_drv_int_get_status(); + return TD_SUCCESS; +} + +td_s32 fb_graphics_get_interrupt_dev(td_u32 int_status, ot_vo_dev *vo_dev) +{ + return graphic_drv_get_interrupt_dev(int_status, vo_dev); +} + +td_void fb_graphics_set_tde_sync(const gfbg_bind_tde_cfg *bind_tde_cfg) +{ + return graphics_drv_set_tde_sync(bind_tde_cfg->is_sync, bind_tde_cfg->is_hw_mute_clr_en, bind_tde_cfg->is_mute_en, + bind_tde_cfg->safe_dist); +} diff --git a/kernel/gfbg/hi3519dv500/drv/adp/gfbg_graphics.h b/kernel/gfbg/hi3519dv500/drv/adp/gfbg_graphics.h new file mode 100755 index 00000000..47c30df7 --- /dev/null +++ b/kernel/gfbg/hi3519dv500/drv/adp/gfbg_graphics.h @@ -0,0 +1,137 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef GFBG_GRAPHICS_H +#define GFBG_GRAPHICS_H + +#include "ot_type.h" +#include "gfbg.h" +#include "gfbg_drv.h" +#include "gfbg_graphics_drv.h" + +#define MDDRC_ZONE_MAX_NUM 32 +#define GFBG_LINE_BUF 1920 +#define GFBG_IRQ_NR 193 + +#define FB_CSC_LUMA_MAX 100 +#define FB_CSC_CONT_MAX 100 +#define FB_CSC_HUE_MAX 100 +#define FB_CSC_SAT_MAX 100 + +typedef enum { + FB_BITEXT_LOW_ZERO = 0x0, + FB_BITEXT_LOW_HIGHBIT = 0x2, + FB_BITEXT_LOW_HIGHBITS = 0x3, + FB_BITEXT_BUTT +} fb_bitext_mode; + +typedef enum { + FB_COLORKEY_IN = 0x0, + FB_COLORKEY_OUT = 0x1, + FB_COLORKEY_BUTT +} fb_colorkey_mode; + +typedef struct { + td_u8 key_max_r; + td_u8 key_max_g; + td_u8 key_max_b; +} fb_gfx_key_max; + +typedef struct { + td_u8 key_min_r; + td_u8 key_min_g; + td_u8 key_min_b; +} fb_gfx_key_min; + +typedef struct { + td_u8 mask_r; + td_u8 mask_g; + td_u8 mask_b; +} fb_gfx_mask; + +typedef enum { + FB_SCAN_MODE_INTERLACE = 0x0, + FB_SCAN_MODE_PROGRESSIVE = 0x1, + FB_SCAN_MODE_BUTT +} fb_scan_mode; + +typedef enum { + FB_GFX_BITEXTEND_1ST = 0, + FB_GFX_BITEXTEND_2ND = 0x2, + FB_GFX_BITEXTEND_3RD = 0x3, + + FB_GFX_BITEXTEND_BUTT +} fb_gfx_bitextend; +typedef td_s32 (*vo_fb_intcallback)(const td_void *paraml, ot_vo_dev vo_dev, const td_void *paramr); + +unsigned int *fb_get_gfbg_irq(td_void); +graphic_layer_context *fb_graphics_get_gfx_layer_ctx(td_void); +td_s32 fb_graphics_enable_dcmp(ot_gfx_layer gfx_layer, td_bool enable); +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC +td_s32 fb_graphics_get_dcmp_enable_state(ot_gfx_layer gfx_layer, td_bool *enable); +td_s32 fb_graphics_set_dcmp_info(ot_gfx_layer gfx_layer, const gfbg_graphic_dcmp_info *dcmp_info); +#endif + +td_s32 fb_graphics_set_gfx_ext(ot_gfx_layer gfx_layer, fb_gfx_bitextend mode); +td_s32 fb_graphics_set_gfx_palpha(ot_gfx_layer gfx_layer, td_u32 alpha_en, td_u32 arange, td_u8 alpha0, td_u8 alpha1); +td_s32 fb_graphics_set_layer_galpha(ot_gfx_layer gfx_layer, td_u8 alpha0); +td_s32 fb_graphics_set_csc_en(ot_gfx_layer gfx_layer, td_bool csc_en); +td_s32 fb_graphics_set_gfx_addr(ot_gfx_layer gfx_layer, td_phys_addr_t laddr); +td_s32 fb_graphics_set_gfx_stride(ot_gfx_layer gfx_layer, td_u16 pitch); + +td_s32 fb_graphics_get_gfx_pre_mult(ot_gfx_layer gfx_layer, td_u32 *enable); +td_s32 fb_graphics_set_gfx_pre_mult(ot_gfx_layer gfx_layer, td_u32 enable); +td_s32 fb_graphics_set_layer_data_fmt(ot_gfx_layer gfx_layer, gfbg_disp_pixel_format enDataFmt); +td_s32 fb_graphics_set_layer_in_rect(ot_gfx_layer gfx_layer, const ot_fb_rect *rect); +td_s32 fb_graphics_set_layer_src_image_reso(ot_gfx_layer gfx_layer, const ot_fb_rect *rect); +td_s32 fb_graphics_set_layer_out_rect(ot_gfx_layer gfx_layer, const ot_fb_rect *rect); +td_s32 fb_graphics_set_color_key_value(ot_gfx_layer gfx_layer, fb_gfx_key_max key_max, fb_gfx_key_min key_min); +td_s32 fb_graphics_set_color_key_mask(ot_gfx_layer gfx_layer, fb_gfx_mask msk); +td_s32 graphic_drv_get_dev_enable(ot_vo_dev vo_dev, td_bool *intf_en); +td_s32 graphic_drv_get_intf_sync(ot_vo_dev vo_dev, hal_disp_syncinfo *sync_info); +td_s32 graphic_drv_get_intf_mux_sel(ot_vo_dev vo_dev, vo_intf_type *intf_type); +td_s32 fb_graphics_set_gfx_key_en(ot_gfx_layer gfx_layer, td_u32 key_enable); +td_s32 fb_graphics_set_gfx_key_mode(ot_gfx_layer gfx_layer, td_u32 key_out); + +td_s32 fb_graphics_set_reg_up(ot_gfx_layer gfx_layer); +td_void fb_graphics_set_color_reg(td_u32 layer_id, td_phys_addr_t clut_phy_addr); +td_void fb_graphics_set_color_reg_up(td_u32 layer_id); +td_s32 fb_graphics_get_layer_galpha(ot_gfx_layer gfx_layer, td_u8 *alpha0); +td_s32 fb_graphics_get_layer_data_fmt(ot_gfx_layer gfx_layer, td_u32 *fmt); +td_s32 fb_graphics_get_gfx_stride(ot_gfx_layer gfx_layer, td_u32 *gfx_stride); +td_s32 fb_graphics_get_gfx_addr(ot_gfx_layer gfx_layer, td_phys_addr_t *gfx_addr); + +td_s32 fb_graphics_get_dev_mode(hal_disp_layer layer, fb_scan_mode *scan_mode, td_bool *feild_update); + +td_s32 fb_graphics_resource_init(td_void); +td_s32 fb_graphics_resource_deinit(td_void); + +td_s32 fb_graphics_open_layer(ot_gfx_layer gfx_layer); +td_s32 fb_graphics_close_layer(ot_gfx_layer gfx_layer); +td_s32 fb_graphics_set_layer_enable(ot_gfx_layer gfx_layer, td_bool enable); +td_s32 fb_graphics_get_layer_enable(ot_gfx_layer gfx_layer, td_bool *enable); +td_s32 fb_graphics_set_callback(ot_gfx_layer gfx_layer, gfbg_int_type int_type, vo_fb_intcallback callback, + td_void *arg); +td_s32 fb_graphics_get_intf_size(ot_gfx_layer gfx_layer, td_u32 *width, td_u32 *height); + +td_s32 fb_graphics_set_csc_coef(ot_gfx_layer gfx_layer); + +td_s32 fb_graphics_get_int(td_u32 *int_staus); +td_s32 fb_graphics_get_interrupt_dev(td_u32 int_status, ot_vo_dev *vo_dev); + +// for ZME +td_s32 fb_graphics_enable_zme(ot_gfx_layer gfx_layer, const ot_fb_rect *in_rect, const ot_fb_rect *out_rect, + td_bool enable); + +/* for low delay */ +td_void fb_graphics_set_tde_sync(const gfbg_bind_tde_cfg *bind_tde_cfg); +/* for smart rect */ +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC +td_s32 fb_graphics_set_frame_reg(td_u32 layer_id, td_phys_addr_t phys_addr); +td_void fb_graphics_up_frame_param(td_u32 layer_id); +td_void fb_graphics_close_smart_rect(td_s32 layer_id); +#endif + +#endif /* GFBG_GRAPHICS_H */ + diff --git a/kernel/gfbg/hi3519dv500/drv/adp/gfbg_graphics_drv.c b/kernel/gfbg/hi3519dv500/drv/adp/gfbg_graphics_drv.c new file mode 100755 index 00000000..cdba696e --- /dev/null +++ b/kernel/gfbg/hi3519dv500/drv/adp/gfbg_graphics_drv.c @@ -0,0 +1,1824 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ +#include "gfbg_graphics_drv.h" +#include "proc_ext.h" +#include "securec.h" +#include "mm_ext.h" +#include "mod_ext.h" +#include "sys_ext.h" +#include "ot_debug.h" +#include "gfbg_comm.h" +#include "gfbg_graphics.h" +#include "gfbg_main.h" +#include "ot_math.h" + +#define GFX_CSC_SCALE 0xa +#define GFX_CSC_CLIP_MIN 0x0 +#define GFX_CSC_CLIP_MAX 0x3ff + +#define GFX_LAYER_CSC_MIN_COEF_VAL (-2048) /* 12bit min */ +#define GFX_LAYER_CSC_MAX_COEF_VAL 2047 /* 12bit max */ + +#define GFX_CSC_VALUE_TIMES 100 +#define GFX_CSC_TABLE_TIMES 1000 + + +#define GRAPHICS_LAYER_G0 0 +#define GRAPHICS_LAYER_G1 1 +#define GRAPHICS_LAYER_G2 2 +#define GRAPHICS_LAYER_G3 3 +#define GRAPHICS_LAYER_G4 4 + +#define GFX_MAX_CSC_TABLE 61 + +#define GFBG_DATEARR_RANGE 4 + +gfbg_coef_addr g_gfbg_coef_buf_addr; +#ifdef CONFIG_TDE_CLUT_RECT_SUPPORT_G0 +gfbg_mmz_buffer g_clut_table_addr_g0; +#else +gfbg_mmz_buffer g_clut_table_addr_g3; +#endif +#ifdef CONFIG_TDE_CLUT_RECT_SUPPORT_G4 +gfbg_mmz_buffer g_clut_table_addr_g4; +#endif + +/* gfbg interrupt mask type */ +typedef enum { + GFBG_INTMSK_NONE = 0, + GFBG_INTMSK_DHD0_VTTHD1 = 0x1, + GFBG_INTMSK_DHD0_VTTHD2 = 0x2, + GFBG_INTMSK_DHD0_VTTHD3 = 0x4, + GFBG_INTMSK_DHD0_UFINT = 0x8, + + GFBG_INTMSK_DHD1_VTTHD1 = 0x10, + GFBG_INTMSK_DHD1_VTTHD2 = 0x20, + GFBG_INTMSK_DHD1_VTTHD3 = 0x40, + GFBG_INTMSK_DHD1_UFINT = 0x80, + + GFBG_INTMSK_DSD_VTTHD1 = 0x100, + GFBG_INTMSK_DSD_VTTHD2 = 0x200, + GFBG_INTMSK_DSD_VTTHD3 = 0x400, + GFBG_INTMSK_DSD_UFINT = 0x800, + + GFBG_INTMSK_B0_ERR = 0x1000, + GFBG_INTMSK_B1_ERR = 0x2000, + GFBG_INTMSK_B2_ERR = 0x4000, + + GFBG_INTMSK_WBC_DHDOVER = 0x8000, + GFBG_INTREPORT_ALL = 0xffffffff +} gfbg_int_mask; + +/* output 601 limit */ +const csc_coef g_fb_csc_yuv601limit_to_yuv601limit = { + 1024, 0, 0, 0, 1024, 0, 0, 0, 1024, + -16, -128, -128, + 16, 128, 128 +}; + +const csc_coef g_fb_csc_yuv601full_to_yuv601limit = { + 879, 0, 0, 0, 900, 0, 0, 0, 900, + 0, -128, -128, + 16, 128, 128 +}; + +const csc_coef g_fb_csc_yuv709limit_to_yuv601limit = { + 1024, 102, 196, 0, 1014, -113, 0, -74, 1007, + -16, -128, -128, + 16, 128, 128 +}; + +const csc_coef g_fb_csc_yuv709full_to_yuv601limit = { + 879, 89, 172, 0, 890, -100, 0, -65, 885, + 0, -128, -128, + 16, 128, 128 +}; + +/* output 709 limit */ +const csc_coef g_fb_csc_yuv601limit_to_yuv709limit = { + 1024, -118, -213, 0, 1043, 117, 0, 77, 1050, + -16, -128, -128, + 16, 128, 128 +}; + +const csc_coef g_fb_csc_yuv601full_to_yuv709limit = { + 879, -104, -187, 0, 916, 103, 0, 68, 922, + 0, -128, -128, + 16, 128, 128 +}; + +const csc_coef g_fb_csc_yuv709limit_to_yuv709limit = { + 1024, 0, 0, 0, 1024, 0, 0, 0, 1024, + -16, -128, -128, + 16, 128, 128 +}; + +const csc_coef g_fb_csc_yuv709full_to_yuv709limit = { + 879, 0, 0, 0, 900, 0, 0, 0, 900, + 0, -128, -128, + 16, 128, 128 +}; + +/* output 601 full */ +const csc_coef g_fb_csc_yuv601limit_to_yuv601full = { + 1192, 0, 0, 0, 1166, 0, 0, 0, 1166, + -16, -128, -128, + 0, 128, 128 +}; + +const csc_coef g_fb_csc_yuv601full_to_yuv601full = { + 1024, 0, 0, 0, 1024, 0, 0, 0, 1024, + 0, -128, -128, + 0, 128, 128 +}; + +const csc_coef g_fb_csc_yuv709limit_to_yuv601full = { + 1192, 118, 229, 0, 1154, -129, 0, -84, 1146, + -16, -128, -128, + 0, 128, 128 +}; + +const csc_coef g_fb_csc_yuv709full_to_yuv601full = { + 1024, 104, 201, 0, 1014, -113, 0, -74, 1007, + 0, -128, -128, + 0, 128, 128 +}; + +/* output 709 full */ +const csc_coef g_fb_csc_yuv601limit_to_yuv709full = { + 1192, -138, -248, 0, 1187, 134, 0, 87, 1195, + -16, -128, -128, + 0, 128, 128 +}; + +const csc_coef g_fb_csc_yuv601full_to_yuv709full = { + 1024, -121, -218, 0, 1043, 117, 0, 77, 1050, + 0, -128, -128, + 0, 128, 128 +}; + +const csc_coef g_fb_csc_yuv709limit_to_yuv709full = { + 1192, 0, 0, 0, 1166, 0, 0, 0, 1166, + -16, -128, -128, + 0, 128, 128 +}; + +const csc_coef g_fb_csc_yuv709full_to_yuv709full = { + 1024, 0, 0, 0, 1024, 0, 0, 0, 1024, + 0, -128, -128, + 0, 128, 128 +}; + +/* output rgb full 0~255 */ +const csc_coef g_fb_csc_yuv601limit_to_rgbfull = { + 1192, 0, 1634, 1192, -401, -832, 1192, 2066, 0, + -16, -128, -128, + 0, 0, 0 +}; + +const csc_coef g_fb_csc_yuv601full_to_rgbfull = { + 1024, 0, 1436, 1024, -352, -731, 1024, 1815, 0, + 0, -128, -128, + 0, 0, 0 +}; + +const csc_coef g_fb_csc_yuv709limit_to_rgbfull = { + 1192, 0, 1836, 1192, -218, -546, 1192, 2163, 0, + -16, -128, -128, + 0, 0, 0 +}; + +const csc_coef g_fb_csc_yuv709full_to_rgbfull = { + 1024, 0, 1613, 1024, -192, -479, 1024, 1900, 0, + 0, -128, -128, + 0, 0, 0 +}; + +/* output rgb limit 16~235 */ +const csc_coef g_fb_csc_yuv601limit_to_rgblimit = { + 1024, 0, 1404, 1024, -345, -715, 1024, 1774, 0, + -16, -128, -128, + 16, 16, 16 +}; + +const csc_coef g_fb_csc_yuv601full_to_rgblimit = { + 879, 0, 1233, 879, -303, -628, 879, 1558, 0, + 0, -128, -128, + 16, 16, 16 +}; + +const csc_coef g_fb_csc_yuv709limit_to_rgblimit = { + 1024, 0, 1577, 1024, -188, -469, 1024, 1858, 0, + -16, -128, -128, + 16, 16, 16 +}; + +const csc_coef g_fb_csc_yuv709full_to_rgblimit = { + 879, 0, 1385, 879, -165, -412, 879, 1632, 0, + 0, -128, -128, + 16, 16, 16 +}; + +/* input rgb full */ +const csc_coef g_fb_csc_rgbfull_to_yuv601limit = { + 263, 516, 100, -152, -298, 450, 450, -377, -73, + 0, 0, 0, + 16, 128, 128 +}; +const csc_coef g_fb_csc_rgbfull_to_yuv601full = { + 306, 601, 117, -173, -339, 512, 512, -429, -83, + 0, 0, 0, + 0, 128, 128 +}; +const csc_coef g_fb_csc_rgbfull_to_yuv709limit = { + 187, 629, 63, -103, -347, 450, 450, -409, -41, + 0, 0, 0, + 16, 128, 128 +}; +const csc_coef g_fb_csc_rgbfull_to_yuv709full = { + 218, 732, 74, -117, -395, 512, 512, -465, -47, + 0, 0, 0, + 0, 128, 128 +}; + +const int g_gfbg_sin_table[GFX_MAX_CSC_TABLE] = { + -500, -485, -469, -454, -438, -422, -407, -391, -374, -358, + -342, -325, -309, -292, -276, -259, -242, -225, -208, -191, + -174, -156, -139, -122, -104, -87, -70, -52, -35, -17, + 0, 17, 35, 52, 70, 87, 104, 122, 139, 156, + 174, 191, 208, 225, 242, 259, 276, 292, 309, 325, + 342, 358, 374, 391, 407, 422, 438, 454, 469, 485, + 500 +}; + +const int g_gfbg_cos_table[GFX_MAX_CSC_TABLE] = { + 866, 875, 883, 891, 899, 906, 914, 921, 927, 934, + 940, 946, 951, 956, 961, 966, 970, 974, 978, 982, + 985, 988, 990, 993, 995, 996, 998, 999, 999, 1000, + 1000, 1000, 999, 999, 998, 996, 995, 993, 990, 988, + 985, 982, 978, 974, 970, 966, 961, 956, 951, 946, + 940, 934, 927, 921, 914, 906, 899, 891, 883, 875, + 866 +}; + +static td_s32 graphic_drv_get_hal_csc_mode(ot_fb_layer_csc_matrix csc_matrix, hal_csc_mode *csc_mode) +{ + td_u32 loop; + td_u32 len; + hal_csc_matrix_mode csc_matrix_mode[] = { + {OT_FB_CSC_MATRIX_BT601LIMIT_TO_BT601LIMIT, HAL_CSC_MODE_BT601LIMIT_TO_BT601LIMIT}, + {OT_FB_CSC_MATRIX_BT601FULL_TO_BT601LIMIT, HAL_CSC_MODE_BT601FULL_TO_BT601LIMIT}, + {OT_FB_CSC_MATRIX_BT709LIMIT_TO_BT601LIMIT, HAL_CSC_MODE_BT709LIMIT_TO_BT601LIMIT}, + {OT_FB_CSC_MATRIX_BT709FULL_TO_BT601LIMIT, HAL_CSC_MODE_BT709FULL_TO_BT601LIMIT}, + {OT_FB_CSC_MATRIX_BT601LIMIT_TO_BT709LIMIT, HAL_CSC_MODE_BT601LIMIT_TO_BT709LIMIT}, + {OT_FB_CSC_MATRIX_BT601FULL_TO_BT709LIMIT, HAL_CSC_MODE_BT601FULL_TO_BT709LIMIT}, + {OT_FB_CSC_MATRIX_BT709LIMIT_TO_BT709LIMIT, HAL_CSC_MODE_BT709LIMIT_TO_BT709LIMIT}, + {OT_FB_CSC_MATRIX_BT709FULL_TO_BT709LIMIT, HAL_CSC_MODE_BT709FULL_TO_BT709LIMIT}, + {OT_FB_CSC_MATRIX_BT601LIMIT_TO_BT601FULL, HAL_CSC_MODE_BT601LIMIT_TO_BT601FULL}, + {OT_FB_CSC_MATRIX_BT601FULL_TO_BT601FULL, HAL_CSC_MODE_BT601FULL_TO_BT601FULL}, + {OT_FB_CSC_MATRIX_BT709LIMIT_TO_BT601FULL, HAL_CSC_MODE_BT709LIMIT_TO_BT601FULL}, + {OT_FB_CSC_MATRIX_BT709FULL_TO_BT601FULL, HAL_CSC_MODE_BT709FULL_TO_BT601FULL}, + {OT_FB_CSC_MATRIX_BT601LIMIT_TO_BT709FULL, HAL_CSC_MODE_BT601LIMIT_TO_BT709FULL}, + {OT_FB_CSC_MATRIX_BT601FULL_TO_BT709FULL, HAL_CSC_MODE_BT601FULL_TO_BT709FULL}, + {OT_FB_CSC_MATRIX_BT709LIMIT_TO_BT709FULL, HAL_CSC_MODE_BT709LIMIT_TO_BT709FULL}, + {OT_FB_CSC_MATRIX_BT709FULL_TO_BT709FULL, HAL_CSC_MODE_BT709FULL_TO_BT709FULL}, + {OT_FB_CSC_MATRIX_BT601LIMIT_TO_RGBFULL, HAL_CSC_MODE_BT601LIMIT_TO_RGBFULL}, + {OT_FB_CSC_MATRIX_BT601FULL_TO_RGBFULL, HAL_CSC_MODE_BT601FULL_TO_RGBFULL}, + {OT_FB_CSC_MATRIX_BT709LIMIT_TO_RGBFULL, HAL_CSC_MODE_BT709LIMIT_TO_RGBFULL}, + {OT_FB_CSC_MATRIX_BT709FULL_TO_RGBFULL, HAL_CSC_MODE_BT709FULL_TO_RGBFULL}, + {OT_FB_CSC_MATRIX_BT601LIMIT_TO_RGBLIMIT, HAL_CSC_MODE_BT601LIMIT_TO_RGBLIMIT}, + {OT_FB_CSC_MATRIX_BT601FULL_TO_RGBLIMIT, HAL_CSC_MODE_BT601FULL_TO_RGBLIMIT}, + {OT_FB_CSC_MATRIX_BT709LIMIT_TO_RGBLIMIT, HAL_CSC_MODE_BT709LIMIT_TO_RGBLIMIT}, + {OT_FB_CSC_MATRIX_BT709FULL_TO_RGBLIMIT, HAL_CSC_MODE_BT709FULL_TO_RGBLIMIT}, + {OT_FB_CSC_MATRIX_RGBFULL_TO_BT601LIMIT, HAL_CSC_MODE_RGBFULL_TO_BT601LIMIT}, + {OT_FB_CSC_MATRIX_RGBFULL_TO_BT601FULL, HAL_CSC_MODE_RGBFULL_TO_BT601FULL}, + {OT_FB_CSC_MATRIX_RGBFULL_TO_BT709LIMIT, HAL_CSC_MODE_RGBFULL_TO_BT709LIMIT}, + {OT_FB_CSC_MATRIX_RGBFULL_TO_BT709FULL, HAL_CSC_MODE_RGBFULL_TO_BT709FULL} + }; + len = sizeof(csc_matrix_mode) / sizeof(hal_csc_matrix_mode); + for (loop = 0; loop < len; loop++) { + if (csc_matrix_mode[loop].csc_matrix == csc_matrix) { + *csc_mode = csc_matrix_mode[loop].csc_mode; + return TD_SUCCESS; + } + } + return TD_FAILURE; +} +static td_s32 graphic_drv_get_csc_matrix(hal_csc_mode csc_mode, const csc_coef **csc_tmp) +{ + td_u32 loop; + td_u32 len; + hal_csc_mode_coef csc_mode_coef[] = { + {HAL_CSC_MODE_BT601LIMIT_TO_BT601LIMIT, &g_fb_csc_yuv601limit_to_yuv601limit}, + {HAL_CSC_MODE_BT601FULL_TO_BT601LIMIT, &g_fb_csc_yuv601full_to_yuv601limit}, + {HAL_CSC_MODE_BT709LIMIT_TO_BT601LIMIT, &g_fb_csc_yuv709limit_to_yuv601limit}, + {HAL_CSC_MODE_BT709FULL_TO_BT601LIMIT, &g_fb_csc_yuv709full_to_yuv601limit}, + {HAL_CSC_MODE_BT601LIMIT_TO_BT601FULL, &g_fb_csc_yuv601limit_to_yuv601full}, + {HAL_CSC_MODE_BT601FULL_TO_BT601FULL, &g_fb_csc_yuv601full_to_yuv601full}, + {HAL_CSC_MODE_BT709LIMIT_TO_BT601FULL, &g_fb_csc_yuv709limit_to_yuv601full}, + {HAL_CSC_MODE_BT709FULL_TO_BT601FULL, &g_fb_csc_yuv709full_to_yuv601full}, + {HAL_CSC_MODE_BT601LIMIT_TO_BT709LIMIT, &g_fb_csc_yuv601limit_to_yuv709limit}, + {HAL_CSC_MODE_BT601FULL_TO_BT709LIMIT, &g_fb_csc_yuv601full_to_yuv709limit}, + {HAL_CSC_MODE_BT709LIMIT_TO_BT709LIMIT, &g_fb_csc_yuv709limit_to_yuv709limit}, + {HAL_CSC_MODE_BT709FULL_TO_BT709LIMIT, &g_fb_csc_yuv709full_to_yuv709limit}, + {HAL_CSC_MODE_BT601LIMIT_TO_BT709FULL, &g_fb_csc_yuv601limit_to_yuv709full}, + {HAL_CSC_MODE_BT601FULL_TO_BT709FULL, &g_fb_csc_yuv601full_to_yuv709full}, + {HAL_CSC_MODE_BT709LIMIT_TO_BT709FULL, &g_fb_csc_yuv709limit_to_yuv709full}, + {HAL_CSC_MODE_BT709FULL_TO_BT709FULL, &g_fb_csc_yuv709full_to_yuv709full}, + {HAL_CSC_MODE_BT601LIMIT_TO_RGBFULL, &g_fb_csc_yuv601limit_to_rgbfull}, + {HAL_CSC_MODE_BT601FULL_TO_RGBFULL, &g_fb_csc_yuv601full_to_rgbfull}, + {HAL_CSC_MODE_BT709LIMIT_TO_RGBFULL, &g_fb_csc_yuv709limit_to_rgbfull}, + {HAL_CSC_MODE_BT709FULL_TO_RGBFULL, &g_fb_csc_yuv709full_to_rgbfull}, + {HAL_CSC_MODE_BT601LIMIT_TO_RGBLIMIT, &g_fb_csc_yuv601limit_to_rgblimit}, + {HAL_CSC_MODE_BT601FULL_TO_RGBLIMIT, &g_fb_csc_yuv601full_to_rgblimit}, + {HAL_CSC_MODE_BT709LIMIT_TO_RGBLIMIT, &g_fb_csc_yuv709limit_to_rgblimit}, + {HAL_CSC_MODE_BT709FULL_TO_RGBLIMIT, &g_fb_csc_yuv709full_to_rgblimit}, + {HAL_CSC_MODE_RGBFULL_TO_BT601LIMIT, &g_fb_csc_rgbfull_to_yuv601limit}, + {HAL_CSC_MODE_RGBFULL_TO_BT601FULL, &g_fb_csc_rgbfull_to_yuv601full}, + {HAL_CSC_MODE_RGBFULL_TO_BT709LIMIT, &g_fb_csc_rgbfull_to_yuv709limit}, + {HAL_CSC_MODE_RGBFULL_TO_BT709FULL, &g_fb_csc_rgbfull_to_yuv709full}, + }; + len = sizeof(csc_mode_coef) / sizeof(hal_csc_mode_coef); + for (loop = 0; loop < len; loop++) { + if (csc_mode_coef[loop].csc_mode == csc_mode) { + *csc_tmp = csc_mode_coef[loop].coef; + return TD_SUCCESS; + } + } + return TD_FAILURE; +} +td_s32 fb_graphic_drv_get_layer_index(hal_disp_layer disp_layer, td_u32 *layer) +{ + switch (disp_layer) { + case HAL_DISP_LAYER_GFX0: + *layer = GRAPHICS_LAYER_G0; + break; +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC + case HAL_DISP_LAYER_GFX1: + *layer = GRAPHICS_LAYER_G1; + break; + case HAL_DISP_LAYER_GFX2: + *layer = GRAPHICS_LAYER_G2; + break; + case HAL_DISP_LAYER_GFX3: + *layer = GRAPHICS_LAYER_G3; + break; + case HAL_DISP_LAYER_GFX4: + *layer = GRAPHICS_LAYER_G4; + break; +#endif + default: + graphics_drv_error("hal_disp_layer(%u) is invalid!\n", (td_u32)disp_layer); + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +td_s32 graphic_drv_set_gfx_key_mode(hal_disp_layer layer, td_u32 key_out) +{ + if (fb_hal_graphic_set_gfx_key_mode(layer, key_out) != TD_SUCCESS) { + return TD_FAILURE; + } + return TD_SUCCESS; +} + +td_s32 graphic_drv_set_gfx_ext(hal_disp_layer layer, hal_gfx_bitextend mode) +{ + if (fb_hal_graphic_set_gfx_ext(layer, mode) != TD_SUCCESS) { + return TD_FAILURE; + } + return TD_SUCCESS; +} + +td_s32 graphic_drv_set_gfx_palpha(hal_disp_layer layer, td_u32 alpha_en, td_u32 arange, td_u8 alpha0, + td_u8 alpha1) +{ + ot_unused(arange); + if (fb_hal_graphic_set_gfx_palpha(layer, alpha_en, TD_TRUE, alpha0, alpha1) != TD_SUCCESS) { + return TD_FAILURE; + } + return TD_SUCCESS; +} + +td_s32 graphic_drv_layer_set_layer_galpha(hal_disp_layer layer, td_u8 alpha0) +{ + if (fb_hal_layer_set_layer_galpha(layer, alpha0) != TD_SUCCESS) { + return TD_FAILURE; + } + return TD_SUCCESS; +} + +td_s32 graphic_drv_layer_set_csc_en(hal_disp_layer layer, td_bool csc_en) +{ + if (fb_hal_layer_set_csc_en(layer, csc_en) != TD_SUCCESS) { + return TD_FAILURE; + } + + if (layer == HAL_DISP_LAYER_GFX0) { + return TD_SUCCESS; + } + return TD_SUCCESS; +} + +td_s32 graphic_drv_set_layer_addr(hal_disp_layer layer, td_phys_addr_t addr) +{ + td_u32 layer_index; + + if (fb_graphic_drv_get_layer_index(layer, &layer_index) != TD_SUCCESS) { + graphics_drv_error("gfx_layer(%u) is invalid!\n", (td_u32)layer); + return TD_FAILURE; + } + + if (fb_hal_graphic_set_gfx_addr(layer, addr) != TD_SUCCESS) { + return TD_FAILURE; + } + return TD_SUCCESS; +} + +td_s32 graphic_drv_set_gfx_stride(hal_disp_layer layer, td_u16 pitch) +{ + td_u32 layer_index = 0; + td_u16 depth; + + if (fb_graphic_drv_get_layer_index(layer, &layer_index) != TD_SUCCESS) { + graphics_drv_error("gfx_layer(%u) is invalid!\n", (td_u32)layer); + return TD_FAILURE; + } + /* 4:Stride need be divided by 16 before setting the register */ + depth = pitch >> 4; + if (fb_hal_graphic_set_gfx_stride(layer, depth) != TD_SUCCESS) { + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +td_s32 graphic_drv_get_gfx_pre_mult(hal_disp_layer layer, td_u32 *enable) +{ + if (fb_hal_graphic_get_gfx_premult(layer, enable) != TD_SUCCESS) { + return TD_FAILURE; + } + return TD_SUCCESS; +} + +td_s32 graphic_drv_set_gfx_pre_mult(hal_disp_layer layer, td_u32 enable) +{ + if (fb_hal_graphic_set_gfx_pre_mult(layer, enable) != TD_SUCCESS) { + return TD_FAILURE; + } + return TD_SUCCESS; +} + +td_s32 graphic_drv_set_layer_data_fmt(hal_disp_layer layer, hal_disp_pixel_format data_fmt) +{ + td_u32 layer_index = 0; + if (fb_graphic_drv_get_layer_index(layer, &layer_index) != TD_SUCCESS) { + graphics_drv_error("gfx_layer(%u) is invalid!\n", (td_u32)layer); + return TD_FAILURE; + } + + if (fb_hal_layer_set_layer_data_fmt(layer, data_fmt) != TD_SUCCESS) { + return TD_FAILURE; + } + graphics_drv_info("Set Layer%d DataFmt: %d!\n", (td_u32)layer, data_fmt); + return TD_SUCCESS; +} + +td_s32 graphic_drv_set_layer_in_rect(hal_disp_layer layer, const ot_fb_rect *rect) +{ + if (fb_hal_layer_set_layer_in_rect(layer, rect) != TD_SUCCESS) { + return TD_FAILURE; + } + + if (fb_hal_video_set_layer_disp_rect(layer, rect) != TD_SUCCESS) { + return TD_FAILURE; + } + if (fb_hal_video_set_layer_video_rect(layer, rect) != TD_SUCCESS) { + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +/* + * Name : graphic_drv_set_src_image_resolution + * Desc : set the original resolution of the frame. + */ +td_s32 graphic_drv_set_src_image_resolution(hal_disp_layer layer, const ot_fb_rect *rect) +{ + if (fb_hal_layer_set_src_resolution(layer, rect) != TD_SUCCESS) { + return TD_FAILURE; + } + + if (fb_hal_layer_set_layer_in_rect(layer, rect) != TD_SUCCESS) { + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +td_s32 graphic_drv_set_layer_out_rect(hal_disp_layer layer, const ot_fb_rect *rect) +{ + if (fb_hal_layer_set_layer_out_rect(layer, rect) != TD_SUCCESS) { + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +td_s32 graphic_drv_set_color_key_value(hal_disp_layer layer, hal_gfx_key_max key_max, hal_gfx_key_min key_min) +{ + if (fb_hal_graphic_set_color_key_value(layer, key_max, key_min) != TD_SUCCESS) { + return TD_FAILURE; + } + return TD_SUCCESS; +} + +td_s32 graphic_drv_set_color_key_mask(hal_disp_layer layer, hal_gfx_mask msk) +{ + if (fb_hal_graphic_set_color_key_mask(layer, msk) != TD_SUCCESS) { + return TD_FAILURE; + } + return TD_SUCCESS; +} + +td_s32 graphic_drv_set_gfx_key_en(hal_disp_layer layer, td_u32 key_enable) +{ + if (fb_hal_graphic_set_gfx_key_en(layer, key_enable) != TD_SUCCESS) { + return TD_FAILURE; + } + return TD_SUCCESS; +} + +td_s32 graphic_drv_set_reg_up(hal_disp_layer layer) +{ + if (fb_hal_layer_set_reg_up(layer) != TD_SUCCESS) { + return TD_FAILURE; + } + return TD_SUCCESS; +} + +td_void graphic_drv_set_clut_reg(td_u32 layer_id, td_phys_addr_t clut_phy_addr) +{ + hal_clut_set_up_param(layer_id, clut_phy_addr); + return; +} + +td_void graphic_drv_set_clut_reg_up(td_u32 layer_id) +{ + hal_clut_set_up(layer_id); + return; +} +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC +td_s32 graphic_drv_set_smart_rect_reg(td_u32 layer_id, td_phys_addr_t phys_addr) +{ + hal_smart_rect_set_up(layer_id, phys_addr); + return TD_SUCCESS; +} + +td_void graphic_drv_smart_rect_up_param(td_u32 layer_id) +{ + hal_smart_rect_up_param(layer_id); +} + +td_void graphic_drv_smart_rect_disable(td_u32 layer_id) +{ + hal_smart_rect_disable(layer_id); +} +#endif + +td_s32 graphic_drv_get_layer_galpha(hal_disp_layer layer, td_u8 *alpha0) +{ + if (fb_hal_layer_get_layer_galpha(layer, alpha0) != TD_SUCCESS) { + return TD_FAILURE; + } + return TD_SUCCESS; +} + +td_s32 graphic_drv_get_layer_data_fmt(hal_disp_layer layer, td_u32 *fmt) +{ + if (fb_hal_layer_get_layer_data_fmt(layer, fmt) != TD_SUCCESS) { + return TD_FAILURE; + } + return TD_SUCCESS; +} + +td_s32 graphic_drv_get_gfx_addr(hal_disp_layer layer, td_phys_addr_t *gfx_addr) +{ + if (fb_hal_graphic_get_gfx_addr(layer, gfx_addr) != TD_SUCCESS) { + return TD_FAILURE; + } + return TD_SUCCESS; +} + +td_s32 graphic_drv_get_gfx_stride(hal_disp_layer layer, td_u32 *gfx_stride) +{ + if (fb_hal_graphic_get_gfx_stride(layer, gfx_stride) != TD_SUCCESS) { + return TD_FAILURE; + } + return TD_SUCCESS; +} + +td_s32 fb_graphic_drv_get_scan_mode(ot_vo_dev vo_dev, td_bool *iop) +{ + if (fb_hal_disp_get_disp_iop(vo_dev, iop) != TD_SUCCESS) { + return TD_FAILURE; + } + return TD_SUCCESS; +} + +td_s32 graphic_drv_enable_dcmp(hal_disp_layer layer, td_bool enable) +{ + td_u32 layer_index = 0; + if (fb_graphic_drv_get_layer_index(layer, &layer_index) != TD_SUCCESS) { + graphics_drv_error("gfx_layer(%u) is invalid!\n", (td_u32)layer); + return TD_FAILURE; + } + if (fb_hal_graphic_set_gfx_dcmp_enable(layer, enable) != TD_SUCCESS) { + return TD_FAILURE; + } + return TD_SUCCESS; +} + +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC +td_s32 graphic_drv_get_dcmp_enable_state(hal_disp_layer layer, td_bool *enable) +{ + if (fb_hal_graphic_get_gfx_dcmp_enable_state(layer, enable) != TD_SUCCESS) { + return TD_FAILURE; + } + return TD_SUCCESS; +} + +#ifdef CONFIG_TDE_GFBG_COMPRESS_V1 +td_s32 graphic_drv_set_dcmp_info(hal_disp_layer layer, const graphic_dcmp_info *dcmp_info) +{ + td_u32 layer_index; + gfbg_dcmp_src_mode dcmp_src_mode = GFBG_DCMP_SRC_MODE_ARGB8888; + + if (fb_graphic_drv_get_layer_index(layer, &layer_index) != TD_SUCCESS) { + graphics_drv_error("gfx_layer(%u) is invalid!\n", (td_u32)layer); + return TD_FAILURE; + } + + if (fb_hal_graphic_set_gfx_dcmp_addr(layer, dcmp_info->ar_phy_addr) != TD_SUCCESS) { + return TD_FAILURE; + } + + /* 4:divided by 16 before setting register */ + if (fb_hal_graphic_set_gfx_stride(layer, dcmp_info->stride >> 4) != TD_SUCCESS) { + return TD_FAILURE; + } + if (dcmp_info->pixel_fmt == HAL_INPUTFMT_ARGB_8888) { + dcmp_src_mode = GFBG_DCMP_SRC_MODE_ARGB8888; + } else if (dcmp_info->pixel_fmt == HAL_INPUTFMT_ARGB_1555) { + dcmp_src_mode = GFBG_DCMP_SRC_MODE_ARGB1555; + } else if (dcmp_info->pixel_fmt == HAL_INPUTFMT_ARGB_4444) { + dcmp_src_mode = GFBG_DCMP_SRC_MODE_ARGB4444; + } + + fb_hal_fdr_gfx_set_source_mode(layer_index, dcmp_src_mode); + fb_hal_fdr_gfx_set_cmp_mode(layer_index, 0); + fb_hal_fdr_gfx_set_is_loss_lessa(layer_index, dcmp_info->is_lossless_a); + fb_hal_fdr_gfx_set_is_loss_less(layer_index, dcmp_info->is_lossless); + return TD_SUCCESS; +} +#endif + +#ifdef CONFIG_TDE_GFBG_COMPRESS_V2 +td_s32 graphic_drv_set_dcmp_info(hal_disp_layer layer, const graphic_dcmp_info *dcmp_info) +{ + td_u32 layer_index; + gfbg_dcmp_src_mode dcmp_src_mode = GFBG_DCMP_SRC_MODE_ARGB8888; + td_u32 conv_en = 1; + + if (dcmp_info == TD_NULL) { + return TD_FAILURE; + } + + if (fb_graphic_drv_get_layer_index(layer, &layer_index) != TD_SUCCESS) { + graphics_drv_error("gfx_layer(%u) is invalid!\n", (td_u32)layer); + return TD_FAILURE; + } + + if (fb_hal_graphic_set_gfx_dcmp_addr(layer, dcmp_info->ar_phy_addr) != TD_SUCCESS) { + return TD_FAILURE; + } + + /* 4:divided by 16 before setting register */ + if (fb_hal_graphic_set_gfx_stride(layer, dcmp_info->stride >> 4) != TD_SUCCESS) { + return TD_FAILURE; + } + + if (dcmp_info->pixel_fmt == HAL_INPUTFMT_ARGB_8888) { + dcmp_src_mode = GFBG_DCMP_SRC_MODE_ARGB8888; + } else if (dcmp_info->pixel_fmt == HAL_INPUTFMT_ARGB_1555) { + dcmp_src_mode = GFBG_DCMP_SRC_MODE_ARGB1555; + } else if (dcmp_info->pixel_fmt == HAL_INPUTFMT_ARGB_4444) { + dcmp_src_mode = GFBG_DCMP_SRC_MODE_ARGB4444; + } else if (dcmp_info->pixel_fmt == HAL_INPUTFMT_RGB_888) { + dcmp_src_mode = GFBG_DCMP_SRC_MODE_RGB888; + } + + if (dcmp_src_mode > 1) { + /* 1555 4444 don't need RGB2YUV */ + conv_en = 0; + } + + fb_hal_v3r2_gfx_set_source_mode(layer_index, dcmp_src_mode); + fb_hal_v3r2_gfx_set_is_loss_less(layer_index, dcmp_info->is_lossless); + fb_hal_v3r2_gfx_set_is_conv_en(layer_index, conv_en); + fb_hal_v3r2_gfx_set_cmp_mode(layer_index, 0); + fb_hal_v3r2_gfx_set_is_ice_en(layer_index, 1); + fb_hal_v3r2_gfx_set_frame_size(layer_index, dcmp_info->width, dcmp_info->height); + + return TD_SUCCESS; +} +#endif +#endif + +td_s32 graphic_drv_get_vt_thd_mode(ot_vo_dev vo_dev, td_bool *feild_update) +{ + if (fb_hal_disp_get_vt_thd_mode(vo_dev, feild_update) != TD_SUCCESS) { + return TD_FAILURE; + } + return TD_SUCCESS; +} +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC +td_void graphic_drv_calculate_yuv2rgb(const hal_csc_value *csc_value, const csc_coef *csc_tmp, csc_coef *coef) +{ + const td_s32 csc_value_times = GFX_CSC_VALUE_TIMES; + const td_s32 table_times = GFX_CSC_TABLE_TIMES; + td_s32 square_cv_times = csc_value_times * csc_value_times; + const td_s32 *cos_table = g_gfbg_cos_table; + const td_s32 *sin_table = g_gfbg_sin_table; + + /* yuv->rgb */ + coef->csc_coef00 = (csc_value->contrast * csc_tmp->csc_coef00) / csc_value_times; + coef->csc_coef01 = (csc_value->contrast * csc_value->satu * ((csc_tmp->csc_coef01 * cos_table[csc_value->hue] - + csc_tmp->csc_coef02 * sin_table[csc_value->hue]) / table_times)) / square_cv_times; + coef->csc_coef02 = (csc_value->contrast * csc_value->satu * ((csc_tmp->csc_coef01 * sin_table[csc_value->hue] + + csc_tmp->csc_coef02 * cos_table[csc_value->hue]) / table_times)) / square_cv_times; + coef->csc_coef10 = (csc_value->contrast * csc_tmp->csc_coef10) / csc_value_times; + coef->csc_coef11 = (csc_value->contrast * csc_value->satu * ((csc_tmp->csc_coef11 * cos_table[csc_value->hue] - + csc_tmp->csc_coef12 * sin_table[csc_value->hue]) / table_times)) / square_cv_times; + coef->csc_coef12 = (csc_value->contrast * csc_value->satu * ((csc_tmp->csc_coef11 * sin_table[csc_value->hue] + + csc_tmp->csc_coef12 * cos_table[csc_value->hue]) / table_times)) / square_cv_times; + coef->csc_coef20 = (csc_value->contrast * csc_tmp->csc_coef20) / csc_value_times; + coef->csc_coef21 = (csc_value->contrast * csc_value->satu * ((csc_tmp->csc_coef21 * cos_table[csc_value->hue] - + csc_tmp->csc_coef22 * sin_table[csc_value->hue]) / table_times)) / square_cv_times; + coef->csc_coef22 = (csc_value->contrast * csc_value->satu * ((csc_tmp->csc_coef21 * sin_table[csc_value->hue] + + csc_tmp->csc_coef22 * cos_table[csc_value->hue]) / table_times)) / square_cv_times; + coef->csc_in_dc0 += ((csc_value->contrast != 0) ? (csc_value->luma * csc_value_times / csc_value->contrast) : + (csc_value->luma * csc_value_times)); /* 100 : trans coef */ +} +#endif +td_void graphic_drv_calculate_rgb2yuv(const hal_csc_value *csc_value, const csc_coef *csc_tmp, csc_coef *coef) +{ + const td_s32 csc_value_times = GFX_CSC_VALUE_TIMES; + const td_s32 table_times = GFX_CSC_TABLE_TIMES; + td_s32 square_cv_times = csc_value_times * csc_value_times; + const td_s32 *cos_table = g_gfbg_cos_table; + const td_s32 *sin_table = g_gfbg_sin_table; + + /* rgb->yuv or yuv->yuv */ + coef->csc_coef00 = (csc_value->contrast * csc_tmp->csc_coef00) / csc_value_times; + coef->csc_coef01 = (csc_value->contrast * csc_tmp->csc_coef01) / csc_value_times; + coef->csc_coef02 = (csc_value->contrast * csc_tmp->csc_coef02) / csc_value_times; + coef->csc_coef10 = (csc_value->contrast * csc_value->satu * ((csc_tmp->csc_coef10 * cos_table[csc_value->hue] + + csc_tmp->csc_coef20 * sin_table[csc_value->hue]) / table_times)) / square_cv_times; + coef->csc_coef11 = (csc_value->contrast * csc_value->satu * ((csc_tmp->csc_coef11 * cos_table[csc_value->hue] + + csc_tmp->csc_coef21 * sin_table[csc_value->hue]) / table_times)) / square_cv_times; + coef->csc_coef12 = (csc_value->contrast * csc_value->satu * ((csc_tmp->csc_coef12 * cos_table[csc_value->hue] + + csc_tmp->csc_coef22 * sin_table[csc_value->hue]) / table_times)) / square_cv_times; + coef->csc_coef20 = (csc_value->contrast * csc_value->satu * ((csc_tmp->csc_coef20 * cos_table[csc_value->hue] - + csc_tmp->csc_coef10 * sin_table[csc_value->hue]) / table_times)) / square_cv_times; + coef->csc_coef21 = (csc_value->contrast * csc_value->satu * ((csc_tmp->csc_coef21 * cos_table[csc_value->hue] - + csc_tmp->csc_coef11 * sin_table[csc_value->hue]) / table_times)) / square_cv_times; + coef->csc_coef22 = (csc_value->contrast * csc_value->satu * ((csc_tmp->csc_coef22 * cos_table[csc_value->hue] - + csc_tmp->csc_coef12 * sin_table[csc_value->hue]) / table_times)) / square_cv_times; + coef->csc_out_dc0 += csc_value->luma; +} + +/* + * Name : graphic_drv_calc_csc_matrix + * Desc : Calculate csc matrix. + */ +static td_s32 graphic_drv_calc_csc_matrix(const ot_fb_layer_csc *csc, hal_csc_mode csc_mode, csc_coef *coef) +{ + const csc_coef *csc_tmp = TD_NULL; + td_s32 ret; + hal_csc_value csc_value; + + if (csc->ex_csc_en == TD_FALSE) { + csc_value.luma = (td_s32)csc->luma * 64 / 100 - 32; /* 64: -32~32 100: trans coef */ + } else { + csc_value.luma = (td_s32)csc->luma * 256 / 100 - 128; /* 256: -128~128 128 100 */ + } + csc_value.contrast = ((td_s32)csc->contrast - 50) * 2 + 100; /* 50 2 100 alg data */ + csc_value.hue = (td_s32)csc->hue * 60 / 100; /* 60 100 alg data */ + csc_value.satu = ((td_s32)csc->saturation - 50) * 2 + 100; /* 50 2 100 alg data */ + + ret = graphic_drv_get_csc_matrix(csc_mode, &csc_tmp); + if (ret != TD_SUCCESS) { + return ret; + } + coef->csc_in_dc0 = csc_tmp->csc_in_dc0; + coef->csc_in_dc1 = csc_tmp->csc_in_dc1; + coef->csc_in_dc2 = csc_tmp->csc_in_dc2; + coef->csc_out_dc0 = csc_tmp->csc_out_dc0; + coef->csc_out_dc1 = csc_tmp->csc_out_dc1; + coef->csc_out_dc2 = csc_tmp->csc_out_dc2; + + /* + * the adjustment range of c_ratio is 0–1.99, c_ratio=contrast/100 + * the adjustment range of S is generally 0 to 1.99., S=satu/100 + * The range of tone adjustment parameters is generally -30° ~30° + * Obtain the COS and SIN values by looking up the table and/1000 + */ +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC + if ((csc_mode >= HAL_CSC_MODE_BT601LIMIT_TO_RGBFULL) && + (csc_mode <= HAL_CSC_MODE_BT709FULL_TO_RGBLIMIT)) { + graphic_drv_calculate_yuv2rgb(&csc_value, csc_tmp, coef); + } else { + graphic_drv_calculate_rgb2yuv(&csc_value, csc_tmp, coef); + } +#else + graphic_drv_calculate_rgb2yuv(&csc_value, csc_tmp, coef); +#endif + + return TD_SUCCESS; +} + +/* coef need clip in range */ +td_void graphic_drv_clip_layer_csc_coef(csc_coef *coef) +{ + td_s32 min_coef = GFX_LAYER_CSC_MIN_COEF_VAL; + td_s32 max_coef = GFX_LAYER_CSC_MAX_COEF_VAL; + + coef->csc_coef00 = clip3(coef->csc_coef00, min_coef, max_coef); + coef->csc_coef01 = clip3(coef->csc_coef01, min_coef, max_coef); + coef->csc_coef02 = clip3(coef->csc_coef02, min_coef, max_coef); + + coef->csc_coef10 = clip3(coef->csc_coef10, min_coef, max_coef); + coef->csc_coef11 = clip3(coef->csc_coef11, min_coef, max_coef); + coef->csc_coef12 = clip3(coef->csc_coef12, min_coef, max_coef); + + coef->csc_coef20 = clip3(coef->csc_coef20, min_coef, max_coef); + coef->csc_coef21 = clip3(coef->csc_coef21, min_coef, max_coef); + coef->csc_coef22 = clip3(coef->csc_coef22, min_coef, max_coef); +} + +td_void graphic_drv_get_int_state_vcnt(ot_vo_dev vo_dev, td_u32 *vcnt) +{ + fb_hal_disp_get_int_state_vcnt(vo_dev, vcnt); + return; +} + +td_s32 graphic_drv_get_dev_enable(ot_vo_dev vo_dev, td_bool *intf_en) +{ + if (fb_hal_disp_get_intf_enable(vo_dev, intf_en) != TD_SUCCESS) { + return TD_FAILURE; + } + return TD_SUCCESS; +} + +td_s32 graphic_drv_get_intf_sync(ot_vo_dev vo_dev, hal_disp_syncinfo *sync_info) +{ + if (fb_hal_disp_get_intf_sync(vo_dev, sync_info) != TD_SUCCESS) { + return TD_FAILURE; + } + return TD_SUCCESS; +} + +td_s32 graphic_drv_get_intf_mux_sel(ot_vo_dev vo_dev, vo_intf_type *intf_type) +{ + if (fb_hal_disp_get_intf_mux_sel(vo_dev, intf_type) != TD_SUCCESS) { + return TD_FAILURE; + } + return TD_SUCCESS; +} + +static td_s32 graphic_drv_allocate_mem(td_u32 size, gfbg_mmz_buffer *vdp_mmz_buffer, const char *name) +{ + td_s32 ret; + ot_mpp_chn chn; + mm_malloc_param malloc_param = {0}; + + chn.mod_id = OT_ID_FB; + chn.dev_id = 0; + chn.chn_id = 0; + + if (func_entry(sys_export_func, OT_ID_SYS) == TD_NULL || + func_entry(sys_export_func, OT_ID_SYS)->pfn_get_mmz_name == TD_NULL) { + graphics_drv_error("func_entry is NULL!\n"); + return TD_FAILURE; + } + + if (func_entry(sys_export_func, OT_ID_SYS)->pfn_get_mmz_name(&chn, (td_void **)&malloc_param.mmz_name)) { + graphics_drv_error("get mmz name fail!\n"); + return TD_FAILURE; + } + + malloc_param.buf_name = name; + malloc_param.size = size; + malloc_param.kernel_only = TD_TRUE; + ret = cmpi_mmz_malloc_nocache(&malloc_param, &vdp_mmz_buffer->start_phy_addr, &vdp_mmz_buffer->start_vir_addr); + if (ret != 0) { + graphics_drv_error("GFBG DDR CFG failed\n"); + return TD_FAILURE; + } + + vdp_mmz_buffer->size = size; + (td_void)memset_s(vdp_mmz_buffer->start_vir_addr, size, 0, size); + return TD_SUCCESS; +} + +static td_void graphic_drv_delete_mem(gfbg_mmz_buffer *vdp_mmz_buffer) +{ + if (vdp_mmz_buffer != TD_NULL) { + cmpi_mmz_free(vdp_mmz_buffer->start_phy_addr, vdp_mmz_buffer->start_vir_addr); + vdp_mmz_buffer->start_phy_addr = 0; + vdp_mmz_buffer->start_vir_addr = TD_NULL; + } +} +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC +static td_void graphic_drv_vhd_coef_buf_addr_distribute(gfbg_coef_addr *vdp_coef_buf_addr) +{ + vdp_coef_buf_addr->coef_vir_addr[GFBG_COEF_BUF_G0ZME] = vdp_coef_buf_addr->buf_base_addr.start_vir_addr; + vdp_coef_buf_addr->coef_phy_addr[GFBG_COEF_BUF_G0ZME] = vdp_coef_buf_addr->buf_base_addr.start_phy_addr; + + fb_hal_para_set_para_addr_vhd_chn06(vdp_coef_buf_addr->coef_phy_addr[GFBG_COEF_BUF_G0ZME]); +} +#endif +#ifdef CONFIG_GFBG_ZME_SUPPORT_G0 +td_s32 graphic_zme_coef_init(td_void) +{ + td_s32 ret; + char name[16] = "gfbg_coef"; /* 16 name length */ + /* gfbg only need zme coef size */ + ret = graphic_drv_allocate_mem(COEF_SIZE_G0ZME, &g_gfbg_coef_buf_addr.buf_base_addr, name); + if (ret != TD_SUCCESS) { + return ret; + } + + graphic_drv_vhd_coef_buf_addr_distribute(&g_gfbg_coef_buf_addr); + return TD_SUCCESS; +} +#endif + +#ifdef CONFIG_TDE_CLUT_RECT_SUPPORT_G0 +/* only G0 can support clut */ +static td_s32 graphic_clut_table_init_g0(td_void) +{ + td_s32 ret; + char name[19] = "gfbg_clut_table_g0"; /* 19 name length */ + ret = graphic_drv_allocate_mem(CLUT_TABLE_SIZE, &g_clut_table_addr_g0, name); + if (ret != TD_SUCCESS) { + return ret; + } + return TD_SUCCESS; +} +#else +/* only G3 can support clut */ +static td_s32 graphic_clut_table_init_g3(td_void) +{ + td_s32 ret; + char name[19] = "gfbg_clut_table_g3"; /* 19 name length */ + ret = graphic_drv_allocate_mem(CLUT_TABLE_SIZE, &g_clut_table_addr_g3, name); + if (ret != TD_SUCCESS) { + return ret; + } + return TD_SUCCESS; +} +#endif + +#ifdef CONFIG_TDE_CLUT_RECT_SUPPORT_G4 +/* only G4 can support clut */ +static td_s32 graphic_clut_table_init_g4(td_void) +{ + td_s32 ret; + char name[19] = "gfbg_clut_table_g4"; /* 19 name length */ + ret = graphic_drv_allocate_mem(CLUT_TABLE_SIZE, &g_clut_table_addr_g4, name); + if (ret != TD_SUCCESS) { + return ret; + } + return TD_SUCCESS; +} +#endif + +/* + * only G3 can get bind + */ +static td_s32 graphic_drv_get_layer_bind_dev(ot_gfx_layer gfx_layer, ot_vo_dev *vo_dev) +{ + hal_disp_layer layer; + graphic_layer_context *gfx_layer_ctx = fb_graphics_get_gfx_layer_ctx(); + /* G3 index is 2 */ + if ((gfx_layer != GRAPHICS_LAYER_G3) && (gfx_layer != GRAPHICS_LAYER_G2) && (gfx_layer != GRAPHICS_LAYER_G4)) { + graphics_drv_error("gfx_layer %d is illeagal\n", (td_s32)gfx_layer); + return TD_FAILURE; + } + + layer = gfx_layer + HAL_DISP_LAYER_GFX0; + fb_hal_link_get_hc_link(layer, vo_dev); + + gfx_layer_ctx[gfx_layer].binded_dev = *vo_dev; + gfx_layer_ctx[gfx_layer].binded = TD_TRUE; + return TD_SUCCESS; +} +/* + * VTTHD1 : gfbg Vertical Timing Interrupt + * VTTHD3 : gfbg SOF interrupt + */ +static td_u32 graphic_drv_get_gfbg_basic_int_type(ot_vo_dev dev) +{ + td_u32 gfbg_int_type = 0; + + if (dev == VO_DEV_DHD0) { + gfbg_int_type = GFBG_INTMSK_DHD0_VTTHD1 | GFBG_INTMSK_DHD0_VTTHD3; + } else if (dev == VO_DEV_DHD1) { + gfbg_int_type = GFBG_INTMSK_DHD1_VTTHD1 | GFBG_INTMSK_DHD1_VTTHD3; + } else if (dev == VO_DEV_DSD0) { + gfbg_int_type = GFBG_INTMSK_DSD_VTTHD1 | GFBG_INTMSK_DSD_VTTHD3; + } + return gfbg_int_type; +} + +td_s32 graphic_drv_dev_gfbg_int_enable(td_u32 layer_id, td_bool enable) +{ + td_u32 ret, gfbg_int_type; + ot_vo_dev dev; + + dev = graphic_drv_get_bind_dev(layer_id); + gfbg_int_type = graphic_drv_get_gfbg_basic_int_type(dev); + if (enable == TD_TRUE) { + ret = fb_hal_disp_set_int_mask1(gfbg_int_type); + if (ret != TD_SUCCESS) { + return ret; + } + } else { + ret = fb_hal_disp_clr_int_mask1(gfbg_int_type); + if (ret != TD_SUCCESS) { + return ret; + } + } + return TD_SUCCESS; +} + +td_s32 fb_graphic_drv_init(td_void) +{ + td_s32 ret; + td_s32 i; + graphic_layer_context *gfx_layer_ctx = fb_graphics_get_gfx_layer_ctx(); + ot_vo_dev vo_dev; + + for (i = GRAPHICS_LAYER_G0; i <= GRAPHICS_LAYER_G1; ++i) { /* 2 alg data */ + gfx_layer_ctx[i].layer_id = HAL_DISP_LAYER_GFX0 + i; /* HAL_DISP_LAYER_GFX0+1 */ + gfx_layer_ctx[i].binded_dev = i; /* 0 */ + gfx_layer_ctx[i].binded = TD_TRUE; + } + + /* init G2~G4 */ + for (i = GRAPHICS_LAYER_G2; i <= GRAPHICS_LAYER_G4; i++) { + gfx_layer_ctx[i].layer_id = HAL_DISP_LAYER_GFX0 + i; + gfx_layer_ctx[i].binded = TD_TRUE; + ret = graphic_drv_get_layer_bind_dev(i, &vo_dev); + if (ret != TD_SUCCESS) { + return ret; + } + gfx_layer_ctx[i].binded_dev = vo_dev; + } + + for (i = 0; i < GFBG_MAX_LAYER_NUM; ++i) { + gfx_layer_ctx[i].gfx_csc.csc_matrix = OT_FB_CSC_MATRIX_RGBFULL_TO_BT601LIMIT; + gfx_layer_ctx[i].gfx_csc.luma = 50; /* 50 alg data */ + gfx_layer_ctx[i].gfx_csc.contrast = 50; /* 50 alg data */ + gfx_layer_ctx[i].gfx_csc.hue = 50; /* 50 alg data */ + gfx_layer_ctx[i].gfx_csc.saturation = 50; /* 50 alg data */ + gfx_layer_ctx[i].gfx_csc.ex_csc_en = TD_FALSE; /* default: 0 */ + + /* CSC extra coef */ + gfx_layer_ctx[i].coef_param.csc_scale2p = GFX_CSC_SCALE; + gfx_layer_ctx[i].coef_param.csc_clip_min = GFX_CSC_CLIP_MIN; + gfx_layer_ctx[i].coef_param.csc_clip_max = GFX_CSC_CLIP_MAX; + } + + /* DDR detect coef */ + gfx_layer_ctx[GRAPHICS_LAYER_G0].start_section = 0; + gfx_layer_ctx[GRAPHICS_LAYER_G0].zone_nums = 16; /* 16 alg data */ + gfx_layer_ctx[GRAPHICS_LAYER_G1].start_section = 16; /* 16 alg data */ + gfx_layer_ctx[GRAPHICS_LAYER_G1].zone_nums = 16; /* 16 alg data */ + + return TD_SUCCESS; +} + +td_s32 graphic_drv_get_bind_dev(td_s32 layer_id) +{ + graphic_layer_context *gfx_layer_ctx = fb_graphics_get_gfx_layer_ctx(); + return gfx_layer_ctx[layer_id].binded_dev; +} + +td_s32 fb_graphic_drv_exit(td_void) +{ + return TD_SUCCESS; +} + +static td_s32 graphic_drv_reg_and_lock_init(graphic_layer_context *gfx_layer_ctx) +{ + td_s32 ret, i, j; + + ret = fb_hal_gfbg_init(); + if (ret != TD_SUCCESS) { + return TD_FAILURE; + } + + /* lock init */ + ret = graphic_drv_vdp_state_count_lock_init(); + if (ret != TD_SUCCESS) { + fb_hal_gfbg_deinit(); + return TD_FAILURE; + } + + for (i = 0; i < GFBG_MAX_LAYER_NUM; ++i) { + (td_void)memset_s(&gfx_layer_ctx[i], sizeof(graphic_layer_context), 0, sizeof(graphic_layer_context)); + if (gfx_spin_lock_init(&gfx_layer_ctx[i].spin_lock) != 0) { + for (j = 0; j < i; j++) { + gfx_spin_lock_deinit(&gfx_layer_ctx[j].spin_lock); + } + graphic_drv_vdp_state_count_lock_deinit(); + fb_hal_gfbg_deinit(); + return TD_FAILURE; + } + } + + return TD_SUCCESS; +} + +static td_void graphic_drv_reg_and_lock_deinit(graphic_layer_context *gfx_layer_ctx) +{ + td_s32 i; + /* lock deinit */ + for (i = 0; i < GFBG_MAX_LAYER_NUM; ++i) { + gfx_spin_lock_deinit(&gfx_layer_ctx[i].spin_lock); + } + graphic_drv_vdp_state_count_lock_deinit(); + fb_hal_gfbg_deinit(); + return; +} + +td_s32 graphic_drv_resource_init(td_void) +{ + td_s32 ret; + graphic_layer_context *gfx_layer_ctx = fb_graphics_get_gfx_layer_ctx(); + + ret = graphic_drv_reg_and_lock_init(gfx_layer_ctx); + if (ret != TD_SUCCESS) { + graphics_drv_error("GFBG LOCK INIT failed\n"); + return TD_FAILURE; + } + +#ifdef CONFIG_GFBG_ZME_SUPPORT_G0 + /* mem alloc */ + ret = graphic_zme_coef_init(); + if (ret != TD_SUCCESS) { + graphic_drv_reg_and_lock_deinit(gfx_layer_ctx); + return TD_FAILURE; + } +#endif + +#ifdef CONFIG_TDE_CLUT_RECT_SUPPORT_G0 + ret = graphic_clut_table_init_g0(); + if (ret != TD_SUCCESS) { + goto err1; + } +#else + ret = graphic_clut_table_init_g3(); + if (ret != TD_SUCCESS) { + goto err1; + } +#endif + +#ifdef CONFIG_TDE_CLUT_RECT_SUPPORT_G4 + ret = graphic_clut_table_init_g4(); + if (ret != TD_SUCCESS) { +#ifdef CONFIG_TDE_CLUT_RECT_SUPPORT_G0 + graphic_drv_delete_mem(&g_clut_table_addr_g0); +#else + graphic_drv_delete_mem(&g_clut_table_addr_g3); +#endif + goto err1; + } +#endif + return TD_SUCCESS; + +err1: +#ifdef CONFIG_GFBG_ZME_SUPPORT_G0 + graphic_drv_delete_mem(&g_gfbg_coef_buf_addr.buf_base_addr); +#endif + graphic_drv_reg_and_lock_deinit(gfx_layer_ctx); + return TD_FAILURE; +} + +td_s32 graphic_drv_resource_exit(td_void) +{ + graphic_layer_context *gfx_layer_ctx = fb_graphics_get_gfx_layer_ctx(); + + /* mem delete */ + graphic_drv_delete_mem(&g_gfbg_coef_buf_addr.buf_base_addr); +#ifdef CONFIG_TDE_CLUT_RECT_SUPPORT_G0 + graphic_drv_delete_mem(&g_clut_table_addr_g0); +#else + graphic_drv_delete_mem(&g_clut_table_addr_g3); +#endif + +#ifdef CONFIG_TDE_CLUT_RECT_SUPPORT_G4 + graphic_drv_delete_mem(&g_clut_table_addr_g4); +#endif + /* lock deinit */ + graphic_drv_reg_and_lock_deinit(gfx_layer_ctx); + + return TD_SUCCESS; +} + +td_s32 graphic_drv_set_layer_enable(hal_disp_layer gfx_layer, td_bool enable) +{ + if (fb_hal_set_layer_enable(gfx_layer, enable) != TD_SUCCESS) { + graphics_drv_error("graphics layer %d enable failed!\n", gfx_layer); + return TD_FAILURE; + } + fb_hal_set_layer_ck_gt_en(gfx_layer, enable); + return TD_SUCCESS; +} + +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC +td_s32 graphic_drv_get_layer_enable(hal_disp_layer gfx_layer, td_bool *enable) +{ + if (fb_hal_get_layer_enable(gfx_layer, enable) != TD_SUCCESS) { + graphics_drv_error("graphics layer %d enable failed!\n", gfx_layer); + return TD_FAILURE; + } + return TD_SUCCESS; +} +#endif + +#ifdef CONFIG_TDE_CLUT_RECT_SUPPORT_G0 +gfbg_mmz_buffer *graphic_drv_get_clut_table_g0(td_void) +{ + return &g_clut_table_addr_g0; +} +#else +gfbg_mmz_buffer *graphic_drv_get_clut_table_g3(td_void) +{ + return &g_clut_table_addr_g3; +} +#endif + +#ifdef CONFIG_TDE_CLUT_RECT_SUPPORT_G4 +gfbg_mmz_buffer *graphic_drv_get_clut_table_g4(td_void) +{ + return &g_clut_table_addr_g4; +} +#endif + +td_s32 fb_graphic_drv_set_csc_coef(hal_disp_layer gfx_layer, const ot_fb_layer_csc *gfx_csc, + const csc_coef_param *csc_param) +{ + csc_coef coef; + hal_csc_mode csc_mode = HAL_CSC_MODE_BUTT; + td_s32 ret; + const td_u32 dc_pre = 4; + + if (gfx_csc == TD_NULL || csc_param == TD_NULL) { + return TD_FAILURE; + } + + ret = graphic_drv_get_hal_csc_mode(gfx_csc->csc_matrix, &csc_mode); + if (ret != TD_SUCCESS) { + graphics_drv_error("gfx_layer(%u) get CSC mode failed!\n", (td_u32)gfx_layer); + return ret; + } + + /* cal CSC coef and CSC dc coef */ + ret = graphic_drv_calc_csc_matrix(gfx_csc, csc_mode, &coef); + if (ret != TD_SUCCESS) { + graphics_drv_error("gfx_layer(%u) calculate CSC materix failed!\n", (td_u32)gfx_layer); + return ret; + } + + coef.csc_in_dc0 = (td_s32)dc_pre * coef.csc_in_dc0; + coef.csc_in_dc1 = (td_s32)dc_pre * coef.csc_in_dc1; + coef.csc_in_dc2 = (td_s32)dc_pre * coef.csc_in_dc2; + + coef.csc_out_dc0 = (td_s32)dc_pre * coef.csc_out_dc0; + coef.csc_out_dc1 = (td_s32)dc_pre * coef.csc_out_dc1; + coef.csc_out_dc2 = (td_s32)dc_pre * coef.csc_out_dc2; + + /* coef need clip in range */ + graphic_drv_clip_layer_csc_coef(&coef); + + /* set CSC coef and CSC dc coef */ + ret = fb_hal_layer_set_csc_coef(gfx_layer, &coef, csc_param); + if (ret != TD_SUCCESS) { + return TD_FAILURE; + } + return TD_SUCCESS; +} + +td_void gf_func_set_g0zme_mode(td_u32 layer, gf_g0_zme_mode g0_zme_mode, const gf_zme_cfg *cfg) +{ + /* filed declare */ + const td_u32 hfir_order = 1; + td_s32 lhfir_offset = 0; + td_s32 chfir_offset = 0; + td_s32 vtp_offset = 0; + td_s32 vbtm_offset = 0; + + const td_ulong zme_hprec = ZME_HPREC; + const td_ulong zme_vprec = ZME_VPREC; + td_u32 hratio, vratio; + ot_unused(layer); + if (cfg == TD_NULL) { + return; + } + + hratio = (cfg->in_width * zme_hprec) / cfg->out_width; + vratio = (cfg->in_height * zme_vprec) / cfg->out_height; + + if (g0_zme_mode == VDP_G0_ZME_TYP) { + /* typ mode */ + lhfir_offset = 0; + chfir_offset = 0; + vtp_offset = 0; + vbtm_offset = (-1) * (td_s64)zme_vprec / 2; /* 2 alg data */ + } + + /* drv transfer */ + hal_g0_zme_set_ck_gt_en(cfg->ck_gt_en); + hal_g0_zme_set_out_width(cfg->out_width); + hal_g0_zme_set_hfir_en(cfg->hfir_en); + hal_g0_zme_set_ahfir_mid_en(cfg->ahmid_en); + hal_g0_zme_set_lhfir_mid_en(cfg->lhmid_en); + hal_g0_zme_set_chfir_mid_en(cfg->lhmid_en); + hal_g0_zme_set_lhfir_mode(cfg->lhfir_mode); + hal_g0_zme_set_ahfir_mode(cfg->ahfir_mode); + hal_g0_zme_set_hfir_order(hfir_order); + hal_g0_zme_set_hratio(hratio); + hal_g0_zme_set_lhfir_offset(lhfir_offset); + hal_g0_zme_set_chfir_offset(chfir_offset); + hal_g0_zme_set_out_pro(cfg->out_pro); + hal_g0_zme_set_out_height(cfg->out_height); + hal_g0_zme_set_vfir_en(cfg->vfir_en); + hal_g0_zme_set_avfir_mid_en(cfg->avmid_en); + hal_g0_zme_set_lvfir_mid_en(cfg->lvmid_en); + hal_g0_zme_set_cvfir_mid_en(cfg->lvmid_en); + hal_g0_zme_set_lvfir_mode(cfg->lvfir_mode); + hal_g0_zme_set_vafir_mode(cfg->avfir_mode); + hal_g0_zme_set_vratio(vratio); + hal_g0_zme_set_vtp_offset(vtp_offset); + hal_g0_zme_set_vbtm_offset(vbtm_offset); +} + +#ifdef CONFIG_GFBG_G1_SUPPORT_ZME +td_void gf_func_set_g1zme_mode(td_u32 layer, gf_g1_zme_mode g1_zme_mode, const gf_zme_cfg *cfg) +{ + /* filed declare */ + const td_u32 hfir_order = 1; + td_s32 lhfir_offset = 0; + td_s32 chfir_offset = 0; + td_s32 vtp_offset = 0; + td_s32 vbtm_offset = 0; + + const td_ulong zme_hprec = ZME_HPREC; + const td_ulong zme_vprec = ZME_VPREC; + td_u32 hratio, vratio; + ot_unused(layer); + if (cfg == TD_NULL) { + return; + } + + hratio = (cfg->in_width * zme_hprec) / cfg->out_width; + vratio = (cfg->in_height * zme_vprec) / cfg->out_height; + + if (g1_zme_mode == VDP_G1_ZME_TYP) { + /* typ mode */ + lhfir_offset = 0; + chfir_offset = 0; + vtp_offset = 0; + vbtm_offset = (-1) * (td_s64)zme_vprec / 2; /* 2 alg data */ + } + + /* drv transfer */ + hal_g1_zme_set_ck_gt_en(cfg->ck_gt_en); + hal_g1_zme_set_out_width(cfg->out_width); + hal_g1_zme_set_hfir_en(cfg->hfir_en); + hal_g1_zme_set_ahfir_mid_en(cfg->ahmid_en); + hal_g1_zme_set_lhfir_mid_en(cfg->lhmid_en); + hal_g1_zme_set_chfir_mid_en(cfg->lhmid_en); + hal_g1_zme_set_lhfir_mode(cfg->lhfir_mode); + hal_g1_zme_set_ahfir_mode(cfg->ahfir_mode); + hal_g1_zme_set_hfir_order(hfir_order); + hal_g1_zme_set_hratio(hratio); + hal_g1_zme_set_lhfir_offset(lhfir_offset); + hal_g1_zme_set_chfir_offset(chfir_offset); + hal_g1_zme_set_out_pro(cfg->out_pro); + hal_g1_zme_set_out_height(cfg->out_height); + hal_g1_zme_set_vfir_en(cfg->vfir_en); + hal_g1_zme_set_avfir_mid_en(cfg->avmid_en); + hal_g1_zme_set_lvfir_mid_en(cfg->lvmid_en); + hal_g1_zme_set_cvfir_mid_en(cfg->lvmid_en); + hal_g1_zme_set_lvfir_mode(cfg->lvfir_mode); + hal_g1_zme_set_vafir_mode(cfg->avfir_mode); + hal_g1_zme_set_vratio(vratio); + hal_g1_zme_set_vtp_offset(vtp_offset); + hal_g1_zme_set_vbtm_offset(vbtm_offset); +} +#endif +#ifdef CONFIG_GFBG_ZME_SUPPORT_G0 +static td_u32 vo_drv_write_ddr(td_u8 *addr, gfbg_drv_u128 *data128) +{ + td_u32 ii; + td_u32 data_arr[GFBG_DATEARR_RANGE] = { + data128->data0, data128->data1, + data128->data2, data128->data3 + }; + td_u8 *addr_tmp = TD_NULL; + + td_u32 data_tmp; + + for (ii = 0; ii < GFBG_DATEARR_RANGE; ii++) { + addr_tmp = addr + ii * GFBG_DATEARR_RANGE; + data_tmp = data_arr[ii]; + *(td_u32 *)addr_tmp = data_tmp; + } + + return 0; +} + +static td_s32 vo_drv_push128(gfbg_drv_u128 *data128, td_u32 coef_data, td_u32 bit_len) +{ + td_u32 tmp_coef_data = coef_data & (0xFFFFFFFF >> (32 - bit_len)); /* 32 alg data */ + + if (data128->depth < 32) { /* 32 alg data */ + if ((data128->depth + bit_len) <= 32) { /* 32 alg data */ + data128->data0 = (tmp_coef_data << data128->depth) | data128->data0; + } else { + data128->data0 = (tmp_coef_data << data128->depth) | data128->data0; + data128->data1 = tmp_coef_data >> (32 - data128->depth % 32); /* 32 alg data */ + } + } else if ((data128->depth >= 32) && (data128->depth < 64)) { /* 32 64 alg data */ + if ((data128->depth + bit_len) <= 64) { + data128->data1 = (tmp_coef_data << (data128->depth % 32)) | data128->data1; /* 32 alg data */ + } else { + data128->data1 = (tmp_coef_data << (data128->depth % 32)) | data128->data1; /* 32 alg data */ + data128->data2 = tmp_coef_data >> (32 - data128->depth % 32); /* 32 alg data */ + } + } else if ((data128->depth >= 64) && (data128->depth < 96)) { /* 96 64 alg data */ + if ((data128->depth + bit_len) <= 96) { /* 96 alg data */ + data128->data2 = (tmp_coef_data << (data128->depth % 32)) | data128->data2; /* 32 alg data */ + } else { + data128->data2 = (tmp_coef_data << (data128->depth % 32)) | data128->data2; /* 32 alg data */ + data128->data3 = tmp_coef_data >> (32 - data128->depth % 32); /* 32 alg data */ + } + } else if (data128->depth >= 96) { /* 96 alg data */ + if ((data128->depth + bit_len) <= 128) { /* 128 alg data */ + data128->data3 = (tmp_coef_data << (data128->depth % 32)) | data128->data3; /* 32 alg data */ + } + } + + data128->depth = data128->depth + bit_len; + + if (data128->depth <= 128) { /* 128 alg data */ + return TD_SUCCESS; + } else { + return TD_FAILURE; + } +} + +static td_u32 vo_drv_find_max(const td_u32 *array, td_u32 num) +{ + td_u32 ii; + td_u32 tmp_data = array[0]; + + for (ii = 1; ii < num; ii++) { + if (tmp_data < array[ii]) { + tmp_data = array[ii]; + } + } + + return tmp_data; +} + +static td_void send_coef_coef_array(const gfbg_drv_coef_send_cfg *cfg, gfbg_drv_u128 *data128, td_u32 coef_cnt) +{ + td_s32 tmp_data = 0; + td_u32 nn; + for (nn = 0; nn < cfg->lut_num; nn++) { + switch (cfg->data_type) { + case DRV_COEF_DATA_TYPE_S16: + if (coef_cnt < cfg->lut_length[nn]) { + tmp_data = (((td_s16 **)cfg->coef_array)[nn][coef_cnt]); + } + break; + case DRV_COEF_DATA_TYPE_U16: + if (coef_cnt < cfg->lut_length[nn]) { + tmp_data = (((td_u16 **)cfg->coef_array)[nn][coef_cnt]); + } + break; + case DRV_COEF_DATA_TYPE_U32: + if (coef_cnt < cfg->lut_length[nn]) { + tmp_data = (((td_u32 **)cfg->coef_array)[nn][coef_cnt]); + } + break; + case DRV_COEF_DATA_TYPE_S32: + if (coef_cnt < cfg->lut_length[nn]) { + tmp_data = (((td_s32 **)cfg->coef_array)[nn][coef_cnt]); + } + break; + case DRV_COEF_DATA_TYPE_S8: + if (coef_cnt < cfg->lut_length[nn]) { + tmp_data = (((td_s8 **)cfg->coef_array)[nn][coef_cnt]); + } + break; + case DRV_COEF_DATA_TYPE_U8: + if (coef_cnt < cfg->lut_length[nn]) { + tmp_data = (((td_u8 **)cfg->coef_array)[nn][coef_cnt]); + } + break; + default: + break; + } + + if (vo_drv_push128(data128, tmp_data, cfg->coef_bit_length[nn]) != TD_SUCCESS) { + gfbg_error("WARNING: data128's depth bigger than 128\n"); + } + } + return; +} + +static td_u8 *vo_drv_send_coef(const gfbg_drv_coef_send_cfg *cfg) +{ + td_u32 kk, mm; + td_u8 *addr_base; + td_u32 addr_offset = 0; + td_u8 *addr; + + td_u32 cycle_num; + + gfbg_drv_u128 data128 = {0}; + td_u32 coef_cnt; + + td_u32 total_burst_num; + td_u32 max_len; + + addr_base = cfg->coef_addr; + + /* data type conversion */ + addr = addr_base; + + cycle_num = cfg->cycle_num; + + /* send data */ + max_len = vo_drv_find_max(cfg->lut_length, cfg->lut_num); + if (cfg->burst_num == 1 && (cfg->data_type < DRV_COEF_DATA_TYPE_BUTT && cfg->data_type >= 0)) { + total_burst_num = (max_len + cycle_num - 1) / cycle_num; + for (kk = 0; kk < total_burst_num; kk++) { + (td_void)memset_s((td_void *)&data128, sizeof(data128), 0, sizeof(data128)); + + for (mm = 0; mm < cycle_num; mm++) { + coef_cnt = kk * cycle_num + mm; + send_coef_coef_array(cfg, &data128, coef_cnt); + } + addr = addr_base + addr_offset; + addr_offset = addr_offset + 16; /* 16 alg data */ + vo_drv_write_ddr(addr, &data128); + } + } + + return (addr_base + addr_offset); +} + +td_void gf_drv_set_g0zme_coef(td_s16 *coef_h, td_s16 *coef_v) +{ + gfbg_drv_coef_send_cfg coef_send; + td_u8 *addr = 0; + + td_void *coef_array[1] = { coef_h }; + td_u32 lut_length[1] = { 64 }; + td_u32 coef_bit_length[1] = { 16 }; + + addr = g_gfbg_coef_buf_addr.coef_vir_addr[GFBG_COEF_BUF_G0ZME]; + + coef_send.coef_addr = addr; + coef_send.lut_num = 1; + coef_send.burst_num = 1; + coef_send.cycle_num = 8; /* 8 alg data */ + coef_send.coef_array = coef_array; + coef_send.lut_length = lut_length; + coef_send.coef_bit_length = coef_bit_length; + coef_send.data_type = DRV_COEF_DATA_TYPE_S16; + + addr = vo_drv_send_coef(&coef_send); + coef_array[0] = coef_v; + lut_length[0] = 128; /* 128 alg data */ + coef_bit_length[0] = 16; /* 16 alg data */ + + coef_send.coef_addr = addr; + coef_send.cycle_num = 8; /* 8 alg data */ + coef_send.coef_array = coef_array; + coef_send.lut_length = lut_length; + coef_send.coef_bit_length = coef_bit_length; + coef_send.data_type = DRV_COEF_DATA_TYPE_S16; + + vo_drv_send_coef(&coef_send); +} +#endif +#define GFBG_COEF_V_RANGE 16 +#define GFBG_COEF_H_RANGE 8 +#define GFBG_COEF_RANGE 8 +#define GFBG_COEF_V_NEW_RANGE 128 +#define GFBG_COEF_H_NEW_RANGE 64 + +td_s16 g_coef_v[GFBG_COEF_V_RANGE][GFBG_COEF_RANGE] = { + { 0, 0, 0, 0, 0, 63, 0, 0 }, + { 0, 0, 0, 0, 6, 51, 13, -6 }, + { 0, 0, 0, 0, 4, 51, 16, -7 }, + { 0, 0, 0, 0, 1, 50, 20, -7 }, + { 0, 0, 0, 0, -1, 49, 24, -8 }, + { 0, 0, 0, 0, -3, 47, 28, -8 }, + { 0, 0, 0, 0, -4, 45, 31, -8 }, + { 0, 0, 0, 0, -6, 42, 35, -7 }, + { 0, 0, 0, 0, -7, 39, 39, -7 }, + { 0, 0, 0, 0, -7, 35, 42, -6 }, + { 0, 0, 0, 0, -8, 31, 45, -4 }, + { 0, 0, 0, 0, -8, 28, 47, -3 }, + { 0, 0, 0, 0, -8, 24, 49, -1 }, + { 0, 0, 0, 0, -7, 20, 50, 1 }, + { 0, 0, 0, 0, -7, 16, 51, 4 }, + { 0, 0, 0, 0, -6, 13, 51, 6 } +}; + +td_s16 g_coef_h[GFBG_COEF_H_RANGE][GFBG_COEF_RANGE] = { + { 0, 0, 0, 0, 63, 0, 0, 0 }, + { 0, 0, -4, 4, 52, 16, -6, 2 }, + { 0, 0, -2, -1, 48, 24, -7, 2 }, + { 0, 0, -1, -4, 44, 31, -7, 1 }, + { 0, 0, 1, -7, 38, 38, -7, 1 }, + { 0, 0, 1, -7, 31, 44, -4, -1 }, + { 0, 0, 2, -7, 24, 48, -1, -2 }, + { 0, 0, 2, -6, 16, 52, 4, -4 } +}; + +td_s16 g_coef_h_new[GFBG_COEF_H_NEW_RANGE]; +td_s16 g_coef_v_new[GFBG_COEF_V_NEW_RANGE]; + +#ifdef CONFIG_GFBG_ZME_SUPPORT_G0 +td_void gf_vset_g0zme_coef(gf_rm_coef_mode coef_mode) +{ + td_u32 ii; + + if (coef_mode == GF_RM_COEF_MODE_TYP) { + for (ii = 0; ii < 8; ii++) { /* 8 alg data */ + g_coef_h_new[ii * 8 + 0] = g_coef_h[ii][7]; /* 8 7 alg data */ + g_coef_h_new[ii * 8 + 1] = g_coef_h[ii][6]; /* 8 6 alg data */ + g_coef_h_new[ii * 8 + 2] = g_coef_h[ii][5]; /* 8 5 2 alg data */ + g_coef_h_new[ii * 8 + 3] = g_coef_h[ii][4]; /* 8 4 3 alg data */ + g_coef_h_new[ii * 8 + 4] = g_coef_h[ii][3]; /* 8 4 3 alg data */ + g_coef_h_new[ii * 8 + 5] = g_coef_h[ii][2]; /* 8 5 2 alg data */ + g_coef_h_new[ii * 8 + 6] = g_coef_h[ii][1]; /* 8 6 alg data */ + g_coef_h_new[ii * 8 + 7] = g_coef_h[ii][0]; /* 8 7 alg data */ + } + + for (ii = 0; ii < 16; ii++) { /* 16 alg data */ + g_coef_v_new[ii * 8 + 0] = g_coef_v[ii][7]; /* 8 7 alg data */ + g_coef_v_new[ii * 8 + 1] = g_coef_v[ii][6]; /* 8 6 alg data */ + g_coef_v_new[ii * 8 + 2] = g_coef_v[ii][5]; /* 8 5 2 alg data */ + g_coef_v_new[ii * 8 + 3] = g_coef_v[ii][4]; /* 8 4 3 alg data */ + g_coef_v_new[ii * 8 + 4] = g_coef_v[ii][3]; /* 8 4 3 alg data */ + g_coef_v_new[ii * 8 + 5] = g_coef_v[ii][2]; /* 8 5 2 alg data */ + g_coef_v_new[ii * 8 + 6] = g_coef_v[ii][1]; /* 8 6 alg data */ + g_coef_v_new[ii * 8 + 7] = g_coef_v[ii][0]; /* 8 7 alg data */ + } + } + + /* send coef to DDR */ + gf_drv_set_g0zme_coef(g_coef_h_new, g_coef_v_new); +} +#endif +td_s32 graphic_drv_enable_zme(td_u32 layer, const gf_zme_cfg *zme_cfg, td_bool enable_zme) +{ + gf_zme_cfg cfg; + + if ((zme_cfg == TD_NULL) || (zme_cfg->in_width == 0) || (zme_cfg->in_height == 0) || + (zme_cfg->out_width == 0) || (zme_cfg->out_height == 0)) { + return TD_FAILURE; + } + + cfg.ck_gt_en = 1; + cfg.out_pro = VDP_RMODE_PROGRESSIVE; + + cfg.in_width = zme_cfg->in_width; + cfg.in_height = zme_cfg->in_height; + cfg.out_width = zme_cfg->out_width; + cfg.out_height = zme_cfg->out_height; + cfg.lhmid_en = 1; + cfg.ahmid_en = 1; + cfg.lhfir_mode = 1; + cfg.ahfir_mode = 1; + cfg.lvmid_en = 1; + cfg.avmid_en = 1; + cfg.lvfir_mode = 1; + cfg.avfir_mode = 1; +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC + if (enable_zme) { + cfg.hfir_en = 1; + cfg.vfir_en = 1; + + if (layer == HAL_DISP_LAYER_GFX0) { + gf_func_set_g0zme_mode(HAL_DISP_LAYER_GFX0, VDP_G0_ZME_TYP, &cfg); + } else { +#ifdef CONFIG_GFBG_G1_SUPPORT_ZME + gf_func_set_g1zme_mode(HAL_DISP_LAYER_GFX1, VDP_G1_ZME_TYP, &cfg); +#endif + } + /* It will be reset when VO exit, so config again */ + graphic_drv_vhd_coef_buf_addr_distribute(&g_gfbg_coef_buf_addr); + gf_vset_g0zme_coef(GF_RM_COEF_MODE_TYP); + } else { +#endif + cfg.hfir_en = 0; + cfg.vfir_en = 0; + + if (layer == HAL_DISP_LAYER_GFX0) { + gf_func_set_g0zme_mode(HAL_DISP_LAYER_GFX0, VDP_G0_ZME_TYP, &cfg); +#ifdef CONFIG_GFBG_G1_SUPPORT_ZME + } else { + gf_func_set_g1zme_mode(HAL_DISP_LAYER_GFX1, VDP_G1_ZME_TYP, &cfg); +#endif + } +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC + } +#endif + + return TD_SUCCESS; +} + +td_void graphic_drv_int_clear(td_u32 int_clear, td_s32 irq) +{ + ot_unused(irq); + /* vo double interrupt, read and mask use interrupt 1, but clear use interrupt 0 as video */ + fb_hal_disp_clear_int_status(int_clear); + return; +} + +td_u32 graphic_drv_int_get_status(td_void) +{ + return fb_hal_disp_get_int_status(GFBG_INTREPORT_ALL); +} + +td_s32 graphic_drv_get_interrupt_dev(td_u32 int_status, ot_vo_dev *vo_dev) +{ + if (vo_dev == TD_NULL) { + gfbg_error("vo_dev pointer NULL\n"); + return TD_FAILURE; + } + if (int_status & GFBG_INTMSK_DHD0_VTTHD1) { + graphics_drv_debug("Graphic: DHD0 INTERRUPT\n"); + graphic_drv_int_clear(GFBG_INTMSK_DHD0_VTTHD1, GFBG_IRQ_NR); + *vo_dev = VO_DEV_DHD0; + } else if (int_status & GFBG_INTMSK_DHD0_VTTHD3) { + graphics_drv_debug("Graphic: DHD0 INTERRUPT\n"); + graphic_drv_int_clear(GFBG_INTMSK_DHD0_VTTHD3, GFBG_IRQ_NR); + *vo_dev = VO_DEV_DHD0; + } else if (int_status & GFBG_INTMSK_DHD1_VTTHD1) { + graphics_drv_debug("Graphic: DHD1 INTERRUPT\n"); + graphic_drv_int_clear(GFBG_INTMSK_DHD1_VTTHD1, GFBG_IRQ_NR); + *vo_dev = VO_DEV_DHD1; + } else if (int_status & GFBG_INTMSK_DHD1_VTTHD3) { + graphics_drv_debug("Graphic: DHD1 INTERRUPT\n"); + graphic_drv_int_clear(GFBG_INTMSK_DHD1_VTTHD3, GFBG_IRQ_NR); + *vo_dev = VO_DEV_DHD1; + } else if (int_status & GFBG_INTMSK_DSD_VTTHD1) { + graphics_drv_debug("Graphic: DSD INTERRUPT\n"); + graphic_drv_int_clear(GFBG_INTMSK_DSD_VTTHD1, GFBG_IRQ_NR); + *vo_dev = VO_DEV_DSD0; + } else if (int_status & GFBG_INTMSK_DSD_VTTHD3) { + graphics_drv_debug("Graphic: DSD INTERRUPT\n"); + graphic_drv_int_clear(GFBG_INTMSK_DSD_VTTHD3, GFBG_IRQ_NR); + *vo_dev = VO_DEV_DSD0; + } else { + return TD_FAILURE; + } + return TD_SUCCESS; +} + +td_void graphics_drv_set_tde_sync(td_bool is_sync, td_bool is_hw_mute_clr_en, td_bool is_mute_en, + td_u32 safe_dist) +{ + hal_gfx_set_bind_mode(is_sync); + hal_gfx_set_hardware_mute_clr(is_hw_mute_clr_en); + hal_gfx_set_tde_safe_dis(safe_dist); + hal_gfx_set_ld_mute_en(is_mute_en); + return; +} diff --git a/kernel/gfbg/hi3519dv500/drv/adp/gfbg_graphics_drv.h b/kernel/gfbg/hi3519dv500/drv/adp/gfbg_graphics_drv.h new file mode 100755 index 00000000..268572bd --- /dev/null +++ b/kernel/gfbg/hi3519dv500/drv/adp/gfbg_graphics_drv.h @@ -0,0 +1,350 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef GFBG_GRAPHICS_DRV_H +#define GFBG_GRAPHICS_DRV_H + +#include "ot_osal.h" +#include "ot_type.h" +#include "ot_common.h" +#include "gfbg_graphic_hal.h" + +#define COEF_SIZE_G0ZME (4096 * 128 / 8) +#define CLUT_TABLE_SIZE (256 * 4) + +/* debug print format */ +#define gfbg_graphics_error(format, ...) \ + OT_ERR_TRACE(OT_ID_FB, "[Func]:%s [Line]:%d [Info]:" format, __FUNCTION__, __LINE__, ##__VA_ARGS__) \ + +typedef td_s32 (*fb_intcallback)(const td_void *paraml, ot_vo_dev vo_dev, const td_void *paramr); + +#define GRAPHIC_ALPHA_OPACITY 0xff + +#define GFX_SPIN_LOCK_FLAG td_ulong +#define GFX_SPIN_LOCK_S osal_spinlock +#define gfx_spin_lock_init(pLock) osal_spin_lock_init(pLock) +#define gfx_spin_lock_deinit(pLock) osal_spin_lock_destroy(pLock) +#define gfx_spin_lock_irqsave(pLock, flag) osal_spin_lock_irqsave(pLock, flag) +#define gfx_spin_unlock_irqrestore(pLock, flag) osal_spin_unlock_irqrestore(pLock, flag) + +/* debug print format */ +#define graphics_drv_error(format, ...) \ + OT_ERR_TRACE(OT_ID_FB, "[Func]:%s [Line]:%d [Info]:" format, __FUNCTION__, __LINE__, ##__VA_ARGS__) \ + +#define graphics_drv_debug(format, ...) \ + OT_DEBUG_TRACE(OT_ID_FB, "[Func]:%s [Line]:%d [Info]:" format, __FUNCTION__, __LINE__, ##__VA_ARGS__) \ + +#define graphics_drv_info(format, ...) \ + OT_INFO_TRACE(OT_ID_FB, "[Func]:%s [Line]:%d [Info]:" format, __FUNCTION__, __LINE__, ##__VA_ARGS__) \ + +typedef struct { + hal_disp_pixel_format pixel_fmt; + td_phys_addr_t ar_phy_addr; + td_phys_addr_t gb_phy_addr; + td_u32 frame_size0; + td_u32 frame_size1; + td_u32 width; + td_u32 height; + td_bool is_lossless_a; + td_bool is_lossless; + td_u32 offset; + td_u32 stride; +} graphic_dcmp_info; + +typedef struct { + hal_disp_layer layer_id; + td_bool opened; + td_bool binded; + ot_vo_dev binded_dev; + + fb_intcallback vo_callback; /* VSYNC interrupt callback function */ + td_void *vo_callback_arg; + + ot_fb_layer_csc gfx_csc; + csc_coef_param coef_param; + GFX_SPIN_LOCK_S spin_lock; + + /* DDR detection area used in this layer */ + td_u32 start_section; + td_u32 zone_nums; +} graphic_layer_context; + +typedef enum { + VDP_G0_ZME_TYP = 0, + VDP_G0_ZME_TYP1, + VDP_G0_ZME_RAND, + VDP_G0_ZME_MAX, + VDP_G0_ZME_MIN, + VDP_G0_ZME_ZERO, + VDP_G0_ZME_BUTT +} gf_g0_zme_mode; + +#ifdef CONFIG_GFBG_G1_SUPPORT_ZME +typedef enum { + VDP_G1_ZME_TYP = 0, + VDP_G1_ZME_TYP1, + VDP_G1_ZME_RAND, + VDP_G1_ZME_MAX, + VDP_G1_ZME_MIN, + VDP_G1_ZME_ZERO, + VDP_G1_ZME_BUTT +} gf_g1_zme_mode; +#endif + +typedef struct { + td_u32 ck_gt_en; + td_u32 in_width; + td_u32 out_width; + td_u32 out_pro; + + td_u32 hfir_en; + td_u32 lhmid_en; + td_u32 ahmid_en; + td_u32 lhfir_mode; + td_u32 ahfir_mode; + + td_u32 in_height; + td_u32 out_height; + + td_u32 vfir_en; + td_u32 lvmid_en; + td_u32 avmid_en; + td_u32 lvfir_mode; + td_u32 avfir_mode; +} gf_zme_cfg; + +typedef enum { + GF_RM_COEF_MODE_TYP = 0x0, + GF_RM_COEF_MODE_RAN = 0x1, + GF_RM_COEF_MODE_MIN = 0x2, + GF_RM_COEF_MODE_MAX = 0x3, + GF_RM_COEF_MODE_ZRO = 0x4, + GF_RM_COEF_MODE_CUS = 0x5, + GF_RM_COEF_MODE_UP = 0x6, + GF_RM_COEF_MODE_BUTT +} gf_rm_coef_mode; + +#ifdef CONFIG_TDE_GFBG_COMPRESS_V2 +typedef enum { + GFX_DCMP_SRC_MODE_RGB888 = 0, + GFX_DCMP_SRC_MODE_ARGB8888, + GFX_DCMP_SRC_MODE_ARGB1555, + GFX_DCMP_SRC_MODE_ARGB4444, + GFX_DCMP_SRC_MODE_BUTT +} gfx_dcmp_src_mode; +#endif +#ifdef CONFIG_TDE_GFBG_COMPRESS_V1 +typedef enum { + GFX_DCMP_SRC_MODE_ARGB8888 = 0, + GFX_DCMP_SRC_MODE_ARGB6888, + GFX_DCMP_SRC_MODE_ARGB1555, + GFX_DCMP_SRC_MODE_ARGB4444, + GFX_DCMP_SRC_MODE_BUTT +} gfx_dcmp_src_mode; +#endif + +typedef struct { + td_phys_addr_t start_phy_addr; + td_void *start_vir_addr; + td_u32 size; +} gfbg_mmz_buffer; + +typedef enum { + GFBG_COEF_BUF_V0_HZME = 0, + GFBG_COEF_BUF_V0_VZME = 1, + GFBG_COEF_BUF_V0_HDRD = 2, + GFBG_COEF_BUF_V0_HDRS = 3, + GFBG_COEF_BUF_G0_HDR_TMAP = 4, + GFBG_COEF_BUF_G0_HDR_GMM = 5, + GFBG_COEF_BUF_G0ZME = 6, + GFBG_COEF_BUF_WD_HZME = 7, + GFBG_COEF_BUF_WD_VZME = 8, + GFBG_COEF_BUF_WD_HDRD = 9, + GFBG_COEF_BUF_WD_HDRS = 10, + + GFBG_COEF_BUF_REGION_V0 = 12, + GFBG_COEF_BUF_REGION_V1 = 13, + GFBG_COEF_BUF_SHARPEN, + GFBG_COEF_BUF_DCI, + GFBG_COEF_BUF_ACM, + GFBG_COEF_BUF_VZME, + GFBG_COEF_BUF_HZME, + GFBG_COEF_BUF_GPZME, + GFBG_COEF_BUF_DIM, + GFBG_COEF_BUF_GMM, + GFBG_COEF_BUF_OD, + GFBG_COEF_BUF_CLUT, + GFBG_COEF_BUF_PCID, + + GFBG_COEF_BUF_ALL = 32, + GFBG_COEF_BUF_BUTT = 33 +} gfbg_coef_buf; + +typedef struct { + gfbg_mmz_buffer buf_base_addr; + td_u32 size; + + td_u8 *coef_vir_addr[GFBG_COEF_BUF_BUTT]; + td_phys_addr_t coef_phy_addr[GFBG_COEF_BUF_BUTT]; +} gfbg_coef_addr; + +#ifdef CONFIG_TDE_GFBG_COMPRESS_V2 +typedef enum { + GFBG_DCMP_SRC_MODE_RGB888 = 0, + GFBG_DCMP_SRC_MODE_ARGB8888, + GFBG_DCMP_SRC_MODE_ARGB1555, + GFBG_DCMP_SRC_MODE_ARGB4444, + GFBG_DCMP_SRC_MODE_BUTT +} gfbg_dcmp_src_mode; +#endif +#ifdef CONFIG_TDE_GFBG_COMPRESS_V1 +typedef enum { + GFBG_DCMP_SRC_MODE_ARGB8888 = 0, + GFBG_DCMP_SRC_MODE_ARGB1555, + GFBG_DCMP_SRC_MODE_ARGB4444, + GFBG_DCMP_SRC_MODE_RGB565, + GFBG_DCMP_SRC_MODE_RGB888, + GFBG_DCMP_SRC_MODE_YUV444, + GFBG_DCMP_SRC_MODE_BUTT +} gfbg_dcmp_src_mode; +#endif + +typedef struct { + td_u32 data3; + td_u32 data2; + td_u32 data1; + td_u32 data0; + td_u32 depth; +} gfbg_drv_u128; + +typedef enum { + DRV_COEF_DATA_TYPE_U8 = 0, + DRV_COEF_DATA_TYPE_S8, + DRV_COEF_DATA_TYPE_U16, + DRV_COEF_DATA_TYPE_S16, + DRV_COEF_DATA_TYPE_U32, + DRV_COEF_DATA_TYPE_S32, + DRV_COEF_DATA_TYPE_BUTT +} gfbg_drv_coef_data_type; + +typedef struct { + td_u8 *coef_addr; + td_u32 lut_num; + td_u32 burst_num; + td_u32 cycle_num; + void **coef_array; + td_u32 *lut_length; + td_u32 *coef_bit_length; + gfbg_drv_coef_data_type data_type; +} gfbg_drv_coef_send_cfg; + +typedef enum { + GFBG_RM_COEF_MODE_TYP = 0x0, + GFBG_RM_COEF_MODE_RAN = 0x1, + GFBG_RM_COEF_MODE_MIN = 0x2, + GFBG_RM_COEF_MODE_MAX = 0x3, + GFBG_RM_COEF_MODE_ZRO = 0x4, + GFBG_RM_COEF_MODE_CUS = 0x5, + GFBG_RM_COEF_MODE_UP = 0x6, + GFBG_RM_COEF_MODE_BUTT +} gfbg_rm_coef_mode; + +typedef struct { + void *p_coef; + void *p_coef_new; + gfbg_drv_coef_data_type coef_data_type; + td_u32 length; + gfbg_rm_coef_mode coef_data_mode; + td_s32 coef_max; + td_s32 coef_min; +} gfbg_drv_coef_gen_cfg; + +td_s32 graphic_drv_enable_dcmp(hal_disp_layer layer, td_bool enable); +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC +td_s32 graphic_drv_get_dcmp_enable_state(hal_disp_layer layer, td_bool *enable); +td_s32 graphic_drv_set_dcmp_info(hal_disp_layer layer, const graphic_dcmp_info *dcmp_info); +#endif + +td_s32 fb_graphic_drv_get_layer_index(hal_disp_layer disp_layer, td_u32 *layer); + +td_s32 graphic_drv_set_gfx_key_mode(hal_disp_layer layer, td_u32 key_out); +td_s32 graphic_drv_set_gfx_ext(hal_disp_layer layer, hal_gfx_bitextend mode); +td_s32 graphic_drv_set_gfx_palpha(hal_disp_layer layer, td_u32 alpha_en, td_u32 arange, td_u8 alpha0, td_u8 alpha1); +td_s32 graphic_drv_layer_set_layer_galpha(hal_disp_layer layer, td_u8 alpha0); +td_s32 graphic_drv_layer_set_csc_en(hal_disp_layer layer, td_bool csc_en); +td_s32 graphic_drv_set_layer_addr(hal_disp_layer layer, td_phys_addr_t addr); +td_s32 graphic_drv_set_gfx_stride(hal_disp_layer layer, td_u16 pitch); +td_s32 graphic_drv_get_gfx_pre_mult(hal_disp_layer layer, td_u32 *enable); +td_s32 graphic_drv_set_gfx_pre_mult(hal_disp_layer layer, td_u32 enable); +td_s32 graphic_drv_set_layer_data_fmt(hal_disp_layer layer, hal_disp_pixel_format data_fmt); +td_s32 graphic_drv_set_layer_in_rect(hal_disp_layer layer, const ot_fb_rect *rect); +td_s32 graphic_drv_set_src_image_resolution(hal_disp_layer layer, const ot_fb_rect *rect); +td_s32 graphic_drv_set_layer_out_rect(hal_disp_layer layer, const ot_fb_rect *rect); +td_s32 graphic_drv_set_color_key_value(hal_disp_layer layer, hal_gfx_key_max key_max, hal_gfx_key_min key_min); +td_s32 graphic_drv_set_color_key_mask(hal_disp_layer layer, hal_gfx_mask msk); +td_s32 graphic_drv_set_gfx_key_en(hal_disp_layer layer, td_u32 key_enable); +td_s32 graphic_drv_set_reg_up(hal_disp_layer layer); +#ifdef CONFIG_TDE_CLUT_RECT_SUPPORT_G0 +gfbg_mmz_buffer *graphic_drv_get_clut_table_g0(td_void); +#else +gfbg_mmz_buffer *graphic_drv_get_clut_table_g3(td_void); +#endif +#ifdef CONFIG_TDE_CLUT_RECT_SUPPORT_G4 +gfbg_mmz_buffer *graphic_drv_get_clut_table_g4(td_void); +#endif +gfbg_mmz_buffer *graphic_drv_get_smart_rect_memory(td_void); +td_void graphic_drv_set_clut_reg(td_u32 layer_id, td_phys_addr_t clut_phy_addr); +td_void graphic_drv_set_clut_reg_up(td_u32 layer_id); +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC +td_s32 graphic_drv_set_smart_rect_reg(td_u32 layer_id, td_phys_addr_t phys_addr); +td_void graphic_drv_smart_rect_up_param(td_u32 layer_id); +td_void graphic_drv_smart_rect_disable(td_u32 layer_id); +#endif +td_s32 graphic_drv_get_layer_galpha(hal_disp_layer layer, td_u8 *alpha0); +td_s32 graphic_drv_get_layer_data_fmt(hal_disp_layer layer, td_u32 *fmt); +td_s32 graphic_drv_get_gfx_addr(hal_disp_layer layer, td_phys_addr_t *gfx_addr); +td_s32 graphic_drv_get_gfx_stride(hal_disp_layer layer, td_u32 *gfx_stride); +td_s32 fb_graphic_drv_get_scan_mode(ot_vo_dev vo_dev, td_bool *iop); + +td_void graphic_drv_clr_wbc_mask(hal_disp_layer disp_layer); +td_void graphic_drv_clear_wbc_int_status(hal_disp_layer disp_layer); +td_s32 graphic_drv_get_vt_thd_mode(ot_vo_dev vo_dev, td_bool *feild_update); + +td_s32 graphic_zme_coef_init(td_void); +td_s32 graphic_drv_get_bind_dev(td_s32 layer_id); +td_s32 graphic_drv_dev_gfbg_int_enable(td_u32 layer_id, td_bool enable); + +td_s32 fb_graphic_drv_init(td_void); +td_s32 fb_graphic_drv_exit(td_void); +td_s32 graphic_drv_resource_init(td_void); +td_s32 graphic_drv_resource_exit(td_void); + +td_s32 graphic_drv_set_layer_enable(hal_disp_layer gfx_layer, td_bool enable); +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC +td_s32 graphic_drv_get_layer_enable(hal_disp_layer gfx_layer, td_bool *enable); +#endif + +td_s32 fb_graphic_drv_set_csc_coef(hal_disp_layer gfx_layer, const ot_fb_layer_csc *gfx_csc, + const csc_coef_param *coef_param); + +td_void graphic_drv_int_clear(td_u32 int_clear, td_s32 irq); +td_u32 graphic_drv_int_get_status(td_void); +td_s32 graphic_drv_get_interrupt_dev(td_u32 int_status, ot_vo_dev *vo_dev); +td_void graphics_drv_set_tde_sync(td_bool is_sync, td_bool is_hw_mute_clr_en, td_bool is_mute_en, + td_u32 safe_dist); +td_s32 fb_graphics_init(td_void); +td_s32 fb_graphics_deinit(td_void); + +td_void gf_func_set_g0zme_mode(td_u32 layer, gf_g0_zme_mode g0_zme_mode, const gf_zme_cfg *cfg); +#ifdef CONFIG_GFBG_G1_SUPPORT_ZME +td_void gf_func_set_g1zme_mode(td_u32 layer, gf_g1_zme_mode g1_zme_mode, const gf_zme_cfg *cfg); +#endif +#ifdef CONFIG_GFBG_ZME_SUPPORT_G0 +td_void gf_drv_set_g0zme_coef(td_s16 *coef_h, td_s16 *coef_v); +td_void gf_vset_g0zme_coef(gf_rm_coef_mode coef_mode); +#endif +td_s32 graphic_drv_enable_zme(td_u32 layer, const gf_zme_cfg *zme_cfg, td_bool enable_zme); +td_void graphic_drv_get_int_state_vcnt(ot_vo_dev vo_dev, td_u32 *vcnt); + +#endif diff --git a/kernel/gfbg/hi3519dv500/drv/adp/gfbg_reg.h b/kernel/gfbg/hi3519dv500/drv/adp/gfbg_reg.h new file mode 100644 index 00000000..de2e701e --- /dev/null +++ b/kernel/gfbg/hi3519dv500/drv/adp/gfbg_reg.h @@ -0,0 +1,18504 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef GFBG_REG_H +#define GFBG_REG_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif +/* Define the union u_voctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 23; /* [22..0] */ + unsigned int g3_ck_gt_en : 1; /* [23] */ + unsigned int v2_ck_gt_en : 1; /* [24] */ + unsigned int wbc_dhd_ck_gt_en : 1; /* [25] */ + unsigned int g1_ck_gt_en : 1; /* [26] */ + unsigned int g0_ck_gt_en : 1; /* [27] */ + unsigned int v1_ck_gt_en : 1; /* [28] */ + unsigned int v0_ck_gt_en : 1; /* [29] */ + unsigned int chk_sum_en : 1; /* [30] */ + unsigned int vo_ck_gt_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_voctrl; + +/* Define the union u_vointsta */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dhd0vtthd1_int : 1; /* [0] */ + unsigned int dhd0vtthd2_int : 1; /* [1] */ + unsigned int dhd0vtthd3_int : 1; /* [2] */ + unsigned int dhd0uf_int : 1; /* [3] */ + unsigned int dhd1vtthd1_int : 1; /* [4] */ + unsigned int dhd1vtthd2_int : 1; /* [5] */ + unsigned int dhd1vtthd3_int : 1; /* [6] */ + unsigned int dhd1uf_int : 1; /* [7] */ + unsigned int dsdvtthd1_int : 1; /* [8] */ + unsigned int dsdvtthd2_int : 1; /* [9] */ + unsigned int dsdvtthd3_int : 1; /* [10] */ + unsigned int dsduf_int : 1; /* [11] */ + unsigned int b0_err_int : 1; /* [12] */ + unsigned int b1_err_int : 1; /* [13] */ + unsigned int b2_err_int : 1; /* [14] */ + unsigned int wbc_dhd_over_int : 1; /* [15] */ + unsigned int vdac0_int : 1; /* [16] */ + unsigned int vdac1_int : 1; /* [17] */ + unsigned int vdac2_int : 1; /* [18] */ + unsigned int vdac3_int : 1; /* [19] */ + unsigned int reserved_0 : 12; /* [31..20] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vointsta; + +/* Define the union u_vomskintsta */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dhd0vtthd1_clr : 1; /* [0] */ + unsigned int dhd0vtthd2_clr : 1; /* [1] */ + unsigned int dhd0vtthd3_clr : 1; /* [2] */ + unsigned int dhd0uf_clr : 1; /* [3] */ + unsigned int dhd1vtthd1_clr : 1; /* [4] */ + unsigned int dhd1vtthd2_clr : 1; /* [5] */ + unsigned int dhd1vtthd3_clr : 1; /* [6] */ + unsigned int dhd1uf_clr : 1; /* [7] */ + unsigned int dsdvtthd1_clr : 1; /* [8] */ + unsigned int dsdvtthd2_clr : 1; /* [9] */ + unsigned int dsdvtthd3_clr : 1; /* [10] */ + unsigned int dsduf_clr : 1; /* [11] */ + unsigned int b0_err_clr : 1; /* [12] */ + unsigned int b1_err_clr : 1; /* [13] */ + unsigned int b2_err_clr : 1; /* [14] */ + unsigned int wbc_dhd_over_clr : 1; /* [15] */ + unsigned int vdac0_clr : 1; /* [16] */ + unsigned int vdac1_clr : 1; /* [17] */ + unsigned int vdac2_clr : 1; /* [18] */ + unsigned int vdac3_clr : 1; /* [19] */ + unsigned int reserved_0 : 12; /* [31..20] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vomskintsta; + +/* Define the union u_vointmsk */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dhd0vtthd1_intmask : 1; /* [0] */ + unsigned int dhd0vtthd2_intmask : 1; /* [1] */ + unsigned int dhd0vtthd3_intmask : 1; /* [2] */ + unsigned int dhd0uf_intmask : 1; /* [3] */ + unsigned int dhd1vtthd1_intmask : 1; /* [4] */ + unsigned int dhd1vtthd2_intmask : 1; /* [5] */ + unsigned int dhd1vtthd3_intmask : 1; /* [6] */ + unsigned int dhd1uf_intmask : 1; /* [7] */ + unsigned int dsdvtthd1_intmask : 1; /* [8] */ + unsigned int dsdvtthd2_intmask : 1; /* [9] */ + unsigned int dsdvtthd3_intmask : 1; /* [10] */ + unsigned int dsduf_intmask : 1; /* [11] */ + unsigned int b0_err_intmask : 1; /* [12] */ + unsigned int b1_err_intmask : 1; /* [13] */ + unsigned int b2_err_intmask : 1; /* [14] */ + unsigned int wbc_dhd_over_intmask : 1; /* [15] */ + unsigned int vdac0_intmask : 1; /* [16] */ + unsigned int vdac1_intmask : 1; /* [17] */ + unsigned int vdac2_intmask : 1; /* [18] */ + unsigned int vdac3_intmask : 1; /* [19] */ + unsigned int reserved_0 : 12; /* [31..20] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vointmsk; + +/* Define the union u_vodebug */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int rm_en_chn : 4; /* [3..0] */ + unsigned int dhd0_ff_info : 2; /* [5..4] */ + unsigned int dhd1_ff_info : 2; /* [7..6] */ + unsigned int dsd0_ff_info : 2; /* [9..8] */ + unsigned int bfm_vga_en : 1; /* [10] */ + unsigned int bfm_cvbs_en : 1; /* [11] */ + unsigned int bfm_lcd_en : 1; /* [12] */ + unsigned int bfm_bt1120_en : 1; /* [13] */ + unsigned int wbc2_ff_info : 2; /* [15..14] */ + unsigned int wbc_mode : 4; /* [19..16] */ + unsigned int node_num : 4; /* [23..20] */ + unsigned int wbc_cmp_mode : 2; /* [25..24] */ + unsigned int bfm_mode : 3; /* [28..26] */ + unsigned int bfm_clk_sel : 3; /* [31..29] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vodebug; + +/* Define the union u_vointsta1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dhd0vtthd1_int : 1; /* [0] */ + unsigned int dhd0vtthd2_int : 1; /* [1] */ + unsigned int dhd0vtthd3_int : 1; /* [2] */ + unsigned int dhd0uf_int : 1; /* [3] */ + unsigned int dhd1vtthd1_int : 1; /* [4] */ + unsigned int dhd1vtthd2_int : 1; /* [5] */ + unsigned int dhd1vtthd3_int : 1; /* [6] */ + unsigned int dhd1uf_int : 1; /* [7] */ + unsigned int dsdvtthd1_int : 1; /* [8] */ + unsigned int dsdvtthd2_int : 1; /* [9] */ + unsigned int dsdvtthd3_int : 1; /* [10] */ + unsigned int dsduf_int : 1; /* [11] */ + unsigned int b0_err_int : 1; /* [12] */ + unsigned int b1_err_int : 1; /* [13] */ + unsigned int b2_err_int : 1; /* [14] */ + unsigned int wbc_dhd_over_int : 1; /* [15] */ + unsigned int vdac0_int : 1; /* [16] */ + unsigned int vdac1_int : 1; /* [17] */ + unsigned int vdac2_int : 1; /* [18] */ + unsigned int vdac3_int : 1; /* [19] */ + unsigned int reserved_0 : 12; /* [31..20] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vointsta1; + +/* Define the union u_vomskintsta1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dhd0vtthd1_clr : 1; /* [0] */ + unsigned int dhd0vtthd2_clr : 1; /* [1] */ + unsigned int dhd0vtthd3_clr : 1; /* [2] */ + unsigned int dhd0uf_clr : 1; /* [3] */ + unsigned int dhd1vtthd1_clr : 1; /* [4] */ + unsigned int dhd1vtthd2_clr : 1; /* [5] */ + unsigned int dhd1vtthd3_clr : 1; /* [6] */ + unsigned int dhd1uf_clr : 1; /* [7] */ + unsigned int dsdvtthd1_clr : 1; /* [8] */ + unsigned int dsdvtthd2_clr : 1; /* [9] */ + unsigned int dsdvtthd3_clr : 1; /* [10] */ + unsigned int dsduf_clr : 1; /* [11] */ + unsigned int b0_err_clr : 1; /* [12] */ + unsigned int b1_err_clr : 1; /* [13] */ + unsigned int b2_err_clr : 1; /* [14] */ + unsigned int wbc_dhd_over_clr : 1; /* [15] */ + unsigned int vdac0_clr : 1; /* [16] */ + unsigned int vdac1_clr : 1; /* [17] */ + unsigned int vdac2_clr : 1; /* [18] */ + unsigned int vdac3_clr : 1; /* [19] */ + unsigned int reserved_0 : 12; /* [31..20] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vomskintsta1; + +/* Define the union u_vointmsk1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dhd0vtthd1_intmask : 1; /* [0] */ + unsigned int dhd0vtthd2_intmask : 1; /* [1] */ + unsigned int dhd0vtthd3_intmask : 1; /* [2] */ + unsigned int dhd0uf_intmask : 1; /* [3] */ + unsigned int dhd1vtthd1_intmask : 1; /* [4] */ + unsigned int dhd1vtthd2_intmask : 1; /* [5] */ + unsigned int dhd1vtthd3_intmask : 1; /* [6] */ + unsigned int dhd1uf_intmask : 1; /* [7] */ + unsigned int dsdvtthd1_intmask : 1; /* [8] */ + unsigned int dsdvtthd2_intmask : 1; /* [9] */ + unsigned int dsdvtthd3_intmask : 1; /* [10] */ + unsigned int dsduf_intmask : 1; /* [11] */ + unsigned int b0_err_intmask : 1; /* [12] */ + unsigned int b1_err_intmask : 1; /* [13] */ + unsigned int b2_err_intmask : 1; /* [14] */ + unsigned int wbc_dhd_over_intmask : 1; /* [15] */ + unsigned int vdac0_intmask : 1; /* [16] */ + unsigned int vdac1_intmask : 1; /* [17] */ + unsigned int vdac2_intmask : 1; /* [18] */ + unsigned int vdac3_intmask : 1; /* [19] */ + unsigned int reserved_0 : 12; /* [31..20] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vointmsk1; + +/* Define the union u_volowpower_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int rfs_ema : 3; /* [2..0] */ + unsigned int rfs_emaw : 2; /* [4..3] */ + unsigned int ret1n : 1; /* [5] */ + unsigned int rft_emaa : 3; /* [8..6] */ + unsigned int rft_emab : 3; /* [11..9] */ + unsigned int rfs_colldisn : 1; /* [12] */ + unsigned int rft_emasa : 1; /* [13] */ + unsigned int rftuhd_ema : 3; /* [16..14] */ + unsigned int rftuhd_emaw : 2; /* [18..17] */ + unsigned int rftuhd_emas : 1; /* [19] */ + unsigned int rftuhd_emap : 1; /* [20] */ + unsigned int rftuhd_stov : 1; /* [21] */ + unsigned int rftuhd_stovab : 1; /* [22] */ + unsigned int rfs_wabl : 1; /* [23] */ + unsigned int rfs_wablm : 2; /* [25..24] */ + unsigned int ras_ema : 3; /* [28..26] */ + unsigned int ras_emaw : 2; /* [30..29] */ + unsigned int ras_stov : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_volowpower_ctrl; + +/* Define the union u_voufsta */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int v0_uf_sta : 1; /* [0] */ + unsigned int v1_uf_sta : 1; /* [1] */ + unsigned int reserved_0 : 1; /* [2] */ + unsigned int v3_uf_sta : 1; /* [3] */ + unsigned int reserved_1 : 4; /* [7..4] */ + unsigned int g0_uf_sta : 1; /* [8] */ + unsigned int g1_uf_sta : 1; /* [9] */ + unsigned int g2_uf_sta : 1; /* [10] */ + unsigned int g3_uf_sta : 1; /* [11] */ + unsigned int g4_uf_sta : 1; /* [12] */ + unsigned int reserved_2 : 19; /* [31..13] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_voufsta; + +/* Define the union u_voufclr */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int v0_uf_clr : 1; /* [0] */ + unsigned int v1_uf_clr : 1; /* [1] */ + unsigned int reserved_0 : 1; /* [2] */ + unsigned int v3_uf_clr : 1; /* [3] */ + unsigned int reserved_1 : 4; /* [7..4] */ + unsigned int g0_uf_clr : 1; /* [8] */ + unsigned int g1_uf_clr : 1; /* [9] */ + unsigned int g2_uf_clr : 1; /* [10] */ + unsigned int g3_uf_clr : 1; /* [11] */ + unsigned int g4_uf_clr : 1; /* [12] */ + unsigned int reserved_2 : 19; /* [31..13] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_voufclr; + +/* Define the union u_vointproc_tim */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vointproc_time : 24; /* [23..0] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vointproc_tim; + +/* Define the union u_volowpower_ctrl1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int rftf_rct : 2; /* [1..0] */ + unsigned int rftf_kp : 3; /* [4..2] */ + unsigned int rft_wtsel : 2; /* [6..5] */ + unsigned int rft_rtsel : 2; /* [8..7] */ + unsigned int rft_mtsel : 2; /* [10..9] */ + unsigned int rasshds_wtsel : 2; /* [12..11] */ + unsigned int rasshds_rtsel : 2; /* [14..13] */ + unsigned int rasshdm_wtsel : 2; /* [16..15] */ + unsigned int rasshdm_rtsel : 2; /* [18..17] */ + unsigned int rashds_wtsel : 2; /* [20..19] */ + unsigned int rashds_rtsel : 2; /* [22..21] */ + unsigned int rashdm_wtsel : 2; /* [24..23] */ + unsigned int rashdm_rtsel : 2; /* [26..25] */ + unsigned int ras_wtsel : 2; /* [28..27] */ + unsigned int ras_rtsel : 2; /* [30..29] */ + unsigned int ras_emas : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_volowpower_ctrl1; + +/* Define the union u_vofpgadef */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_hdr_v_def : 1; /* [0] */ + unsigned int ot_hdr_g_def : 1; /* [1] */ + unsigned int ot_hdr_wd_def : 1; /* [2] */ + unsigned int reserved_0 : 29; /* [31..3] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vofpgadef; + +/* Define the union u_volowpower_ctrl2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int s14_rfshd_rm : 4; /* [3..0] */ + unsigned int s14_rfshs_rm : 4; /* [7..4] */ + unsigned int s14_rasehd_rm : 4; /* [11..8] */ + unsigned int s14_rashd_rm : 4; /* [15..12] */ + unsigned int s14_rfshd_rme : 1; /* [16] */ + unsigned int s14_rfshs_rme : 1; /* [17] */ + unsigned int s14_rasehd_rme : 1; /* [18] */ + unsigned int s14_rashd_rme : 1; /* [19] */ + unsigned int s14_rfthd_rma : 4; /* [23..20] */ + unsigned int s14_rfthd_rmb : 4; /* [27..24] */ + unsigned int s14_rfthd_rmea : 1; /* [28] */ + unsigned int s14_rfthd_rmeb : 1; /* [29] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_volowpower_ctrl2; + +/* Define the union u_volowpower_ctrl3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int s14_rom_rm : 4; /* [3..0] */ + unsigned int s14_rom_rme : 1; /* [4] */ + unsigned int reserved_0 : 27; /* [31..5] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_volowpower_ctrl3; + +/* Define the union u_vomux_dac */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dac0_sel : 4; /* [3..0] */ + unsigned int dac1_sel : 4; /* [7..4] */ + unsigned int dac2_sel : 4; /* [11..8] */ + unsigned int dac3_sel : 4; /* [15..12] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vomux_dac; + +/* Define the union u_vomux_testsync */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int test_dv : 1; /* [0] */ + unsigned int test_hsync : 1; /* [1] */ + unsigned int test_vsync : 1; /* [2] */ + unsigned int test_field : 1; /* [3] */ + unsigned int reserved_0 : 27; /* [30..4] */ + unsigned int vo_test_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vomux_testsync; + +/* Define the union u_vomux_testdata */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int test_data : 30; /* [29..0] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vomux_testdata; + +/* Define the union u_vo_dac_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dac_reg_rev : 16; /* [15..0] */ + unsigned int enctr : 4; /* [19..16] */ + unsigned int enextref : 1; /* [20] */ + unsigned int pdchopper : 1; /* [21] */ + unsigned int envbg : 1; /* [22] */ + unsigned int reserved_0 : 9; /* [31..23] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vo_dac_ctrl; + +/* Define the union u_vo_dac_otp */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dac_otp_reg : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vo_dac_otp; + +/* Define the union u_vo_dac0_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cablectr : 2; /* [1..0] */ + unsigned int reserved_0 : 2; /* [3..2] */ + unsigned int dacgc : 6; /* [9..4] */ + unsigned int reserved_1 : 21; /* [30..10] */ + unsigned int dac_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vo_dac0_ctrl; + +/* Define the union u_vo_dac1_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cablectr : 2; /* [1..0] */ + unsigned int reserved_0 : 2; /* [3..2] */ + unsigned int dacgc : 6; /* [9..4] */ + unsigned int reserved_1 : 21; /* [30..10] */ + unsigned int dac_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vo_dac1_ctrl; + +/* Define the union u_vo_dac2_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cablectr : 2; /* [1..0] */ + unsigned int reserved_0 : 2; /* [3..2] */ + unsigned int dacgc : 6; /* [9..4] */ + unsigned int reserved_1 : 21; /* [30..10] */ + unsigned int dac_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vo_dac2_ctrl; + +/* Define the union u_vo_dac3_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cablectr : 2; /* [1..0] */ + unsigned int reserved_0 : 2; /* [3..2] */ + unsigned int dacgc : 6; /* [9..4] */ + unsigned int reserved_1 : 21; /* [30..10] */ + unsigned int dac_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vo_dac3_ctrl; + +/* Define the union u_vo_dac_stat0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cableout0 : 1; /* [0] */ + unsigned int cableout1 : 1; /* [1] */ + unsigned int cableout2 : 1; /* [2] */ + unsigned int cableout3 : 1; /* [3] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vo_dac_stat0; + +/* Define the union u_cbm_bkg1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cbm_bkgcr1 : 10; /* [9..0] */ + unsigned int cbm_bkgcb1 : 10; /* [19..10] */ + unsigned int cbm_bkgy1 : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_cbm_bkg1; + +/* Define the union u_cbm_mix1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mixer_prio0 : 4; /* [3..0] */ + unsigned int mixer_prio1 : 4; /* [7..4] */ + unsigned int mixer_prio2 : 4; /* [11..8] */ + unsigned int mixer_prio3 : 4; /* [15..12] */ + unsigned int mixer_prio4 : 4; /* [19..16] */ + unsigned int reserved_0 : 12; /* [31..20] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_cbm_mix1; + +/* Define the union u_wbc_bmp_thd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int wbc_bmp_thd : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_bmp_thd; + +/* Define the union u_cbm_bkg2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cbm_bkgcr2 : 10; /* [9..0] */ + unsigned int cbm_bkgcb2 : 10; /* [19..10] */ + unsigned int cbm_bkgy2 : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_cbm_bkg2; + +/* Define the union u_cbm_mix2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mixer_prio0 : 4; /* [3..0] */ + unsigned int mixer_prio1 : 4; /* [7..4] */ + unsigned int mixer_prio2 : 4; /* [11..8] */ + unsigned int mixer_prio3 : 4; /* [15..12] */ + unsigned int mixer_prio4 : 4; /* [19..16] */ + unsigned int reserved_0 : 12; /* [31..20] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_cbm_mix2; + +/* Define the union u_hc_bmp_thd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hc_bmp_thd : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_hc_bmp_thd; + +/* Define the union u_cbm_bkg3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cbm_bkgcr3 : 10; /* [9..0] */ + unsigned int cbm_bkgcb3 : 10; /* [19..10] */ + unsigned int cbm_bkgy3 : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_cbm_bkg3; + +/* Define the union u_cbm_mix3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mixer_prio0 : 4; /* [3..0] */ + unsigned int mixer_prio1 : 4; /* [7..4] */ + unsigned int mixer_prio2 : 4; /* [11..8] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_cbm_mix3; + +/* Define the union u_mixv0_bkg */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mixer_bkgcr : 10; /* [9..0] */ + unsigned int mixer_bkgcb : 10; /* [19..10] */ + unsigned int mixer_bkgy : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_mixv0_bkg; + +/* Define the union u_mixv0_mix */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mixer_prio0 : 4; /* [3..0] */ + unsigned int mixer_prio1 : 4; /* [7..4] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_mixv0_mix; + +/* Define the union u_mixg0_bkg */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mixer_bkgcr : 10; /* [9..0] */ + unsigned int mixer_bkgcb : 10; /* [19..10] */ + unsigned int mixer_bkgy : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_mixg0_bkg; + +/* Define the union u_mixg0_bkalpha */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mixer_alpha : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_mixg0_bkalpha; + +/* Define the union u_mixg0_mix */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mixer_prio0 : 4; /* [3..0] */ + unsigned int mixer_prio1 : 4; /* [7..4] */ + unsigned int mixer_prio2 : 4; /* [11..8] */ + unsigned int mixer_prio3 : 4; /* [15..12] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_mixg0_mix; + +#if (defined CONFIG_GFBG_DPU_V1) || (defined CONFIG_GFBG_DPU_V2) +typedef union { + struct { + unsigned int g2_link : 2; /* [1..0] */ + unsigned int wbc_dhd_link : 2; /* [3..2] */ + unsigned int v2_link : 1; /* [4] */ + unsigned int v1_link : 1; /* [5] */ + unsigned int reserved_0 : 1; /* [6] */ + unsigned int g3_link : 2; /* [8..7] */ + unsigned int g4_link : 2; /* borrow 2 bits from reserved for complie */ + unsigned int reserved_1 : 21; /* [31..11] */ + } bits; + unsigned int u32; +} u_link_ctrl; +#elif (defined CONFIG_GFBG_DPU_V3) +typedef union { + struct { + unsigned int v2_link : 2; /* [1..0] */ + unsigned int g3_link : 2; /* [3..2] */ + unsigned int g2_link : 2; /* borrow 2 bits from reserved for complie */ + unsigned int g4_link : 2; /* borrow 2 bits from reserved for complie */ + unsigned int reserved : 24; /* [31..8] */ + } bits; + unsigned int u32; +} u_link_ctrl; +#else +typedef union { + struct { + unsigned int g2_link : 2; /* [1..0] */ + unsigned int wbc_dhd_link : 2; /* [3..2] */ + unsigned int v3_link : 2; /* [5..4] */ + unsigned int v2_link : 2; /* [7..6] */ + unsigned int v2v3_link : 2; /* [9..8] */ + unsigned int g4_link : 2; /* [11..10] */ + unsigned int g3_link : 2; /* [13..12] */ + unsigned int g3g4_link : 2; /* [15..14] */ + unsigned int reserved : 16; /* [31..16] */ + } bits; + unsigned int u32; +} u_link_ctrl; +#endif +/* Define the union u_vpss_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vpss_en : 1; /* [0] */ + unsigned int chk_sum_en : 1; /* [1] */ + unsigned int dei_en : 1; /* [2] */ + unsigned int mcdi_en : 1; /* [3] */ + unsigned int nx2_vc1_en : 1; /* [4] */ + unsigned int rgme_en : 1; /* [5] */ + unsigned int meds_en : 1; /* [6] */ + unsigned int hsp_en : 1; /* [7] */ + unsigned int snr_en : 1; /* [8] */ + unsigned int tnr_en : 1; /* [9] */ + unsigned int rfr_en : 1; /* [10] */ + unsigned int ifmd_en : 1; /* [11] */ + unsigned int igbm_en : 1; /* [12] */ + unsigned int cue_en : 1; /* [13] */ + unsigned int scd_en : 1; /* [14] */ + unsigned int blk_det_en : 1; /* [15] */ + unsigned int reserved_0 : 7; /* [22..16] */ + unsigned int vpss_node_init : 1; /* [23] */ + unsigned int ram_bank : 4; /* [27..24] */ + unsigned int dei_debug_en : 1; /* [28] */ + unsigned int dei_repeat_mode : 1; /* [29] */ + unsigned int reserved_1 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vpss_ctrl; + +/* Define the union u_vpss_miscellaneous */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 4; /* [3..0] */ + unsigned int reserved_1 : 4; /* [7..4] */ + unsigned int reserved_2 : 16; /* [23..8] */ + unsigned int ck_gt_en : 1; /* [24] */ + unsigned int ck_gt_en_calc : 1; /* [25] */ + unsigned int reserved_3 : 2; /* [27..26] */ + unsigned int reserved_4 : 4; /* [31..28] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vpss_miscellaneous; + +/* Define the union u_vpss_ftconfig */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int node_rst_en : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vpss_ftconfig; + +/* Define the union u_para_up_vhd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int para_up_vhd_chn00 : 1; /* [0] */ + unsigned int para_up_vhd_chn01 : 1; /* [1] */ + unsigned int para_up_vhd_chn02 : 1; /* [2] */ + unsigned int para_up_vhd_chn03 : 1; /* [3] */ + unsigned int para_up_vhd_chn04 : 1; /* [4] */ + unsigned int para_up_vhd_chn05 : 1; /* [5] */ + unsigned int para_up_vhd_chn06 : 1; /* [6] */ + unsigned int para_up_vhd_chn07 : 1; /* [7] */ + unsigned int para_up_vhd_chn08 : 1; /* [8] */ + unsigned int para_up_vhd_chn09 : 1; /* [9] */ + unsigned int para_up_vhd_chn10 : 1; /* [10] */ + unsigned int para_up_vhd_chn11 : 1; /* [11] */ + unsigned int para_up_vhd_chn12 : 1; /* [12] */ + unsigned int para_up_vhd_chn13 : 1; /* [13] */ + unsigned int para_up_vhd_chn14 : 1; /* [14] */ + unsigned int para_up_vhd_chn15 : 1; /* [15] */ + unsigned int para_up_vhd_chn16 : 1; /* [16] */ + unsigned int para_up_vhd_chn17 : 1; /* [17] */ + unsigned int para_up_vhd_chn18 : 1; /* [18] */ + unsigned int para_up_vhd_chn19 : 1; /* [19] */ + unsigned int para_up_vhd_chn20 : 1; /* [20] */ + unsigned int para_up_vhd_chn21 : 1; /* [21] */ + unsigned int para_up_vhd_chn22 : 1; /* [22] */ + unsigned int para_up_vhd_chn23 : 1; /* [23] */ + unsigned int para_up_vhd_chn24 : 1; /* [24] */ + unsigned int para_up_vhd_chn25 : 1; /* [25] */ + unsigned int para_up_vhd_chn26 : 1; /* [26] */ + unsigned int para_up_vhd_chn27 : 1; /* [27] */ + unsigned int para_up_vhd_chn28 : 1; /* [28] */ + unsigned int para_up_vhd_chn29 : 1; /* [29] */ + unsigned int para_up_vhd_chn30 : 1; /* [30] */ + unsigned int para_up_vhd_chn31 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_para_up_vhd; + +/* Define the union u_para_up_vsd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int para_up_vsd_chn00 : 1; /* [0] */ + unsigned int para_up_vsd_chn01 : 1; /* [1] */ + unsigned int para_up_vsd_chn02 : 1; /* [2] */ + unsigned int para_up_vsd_chn03 : 1; /* [3] */ + unsigned int para_up_vsd_chn04 : 1; /* [4] */ + unsigned int para_up_vsd_chn05 : 1; /* [5] */ + unsigned int para_up_vsd_chn06 : 1; /* [6] */ + unsigned int para_up_vsd_chn07 : 1; /* [7] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_para_up_vsd; + +/* Define the union u_para_conflict_clr */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int para_conflict_clr_hd : 1; /* [0] */ + unsigned int para_conflict_clr_sd : 1; /* [1] */ + unsigned int reserved_0 : 30; /* [31..2] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_para_conflict_clr; + +/* Define the union u_para_conflict_sta */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int para_conflict_hd : 1; /* [0] */ + unsigned int para_conflict_sd : 1; /* [1] */ + unsigned int reserved_0 : 30; /* [31..2] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_para_conflict_sta; + +/* Define the union u_v0_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int galpha : 8; /* [7..0] */ + unsigned int reserved_0 : 20; /* [27..8] */ + unsigned int rupd_field : 1; /* [28] */ + unsigned int rgup_mode : 1; /* [29] */ + unsigned int nosec_flag : 1; /* [30] */ + unsigned int surface_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ctrl; + +/* Define the union u_v0_upd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int regup : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_upd; + +/* Define the union u_v0_0reso_read */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ow : 16; /* [15..0] */ + unsigned int oh : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_0reso_read; + +/* Define the union u_v0_ireso */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int iw : 16; /* [15..0] */ + unsigned int ih : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ireso; + +/* Define the union u_v0_dfpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int disp_xfpos : 16; /* [15..0] */ + unsigned int disp_yfpos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_dfpos; + +/* Define the union u_v0_dlpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int disp_xlpos : 16; /* [15..0] */ + unsigned int disp_ylpos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_dlpos; + +/* Define the union u_v0_vfpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int video_xfpos : 16; /* [15..0] */ + unsigned int video_yfpos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_vfpos; + +/* Define the union u_v0_vlpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int video_xlpos : 16; /* [15..0] */ + unsigned int video_ylpos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_vlpos; + +/* Define the union u_v0_bk */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vbk_cr : 10; /* [9..0] */ + unsigned int vbk_cb : 10; /* [19..10] */ + unsigned int vbk_y : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_bk; + +/* Define the union u_v0_alpha */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vbk_alpha : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_alpha; + +/* Define the union u_v0_mute_bk */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mute_cr : 10; /* [9..0] */ + unsigned int mute_cb : 10; /* [19..10] */ + unsigned int mute_y : 10; /* [29..20] */ + unsigned int reserved_0 : 1; /* [30] */ + unsigned int mute_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_mute_bk; + +/* Define the union u_v0_rimwidth */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int v0_rim_width : 5; /* [4..0] */ + unsigned int reserved_0 : 27; /* [31..5] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_rimwidth; + +/* Define the union u_v0_rimcol0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int v0_rim_v0 : 10; /* [9..0] */ + unsigned int v0_rim_u0 : 10; /* [19..10] */ + unsigned int v0_rim_y0 : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_rimcol0; + +/* Define the union u_v0_rimcol1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int v0_rim_v1 : 10; /* [9..0] */ + unsigned int v0_rim_u1 : 10; /* [19..10] */ + unsigned int v0_rim_y1 : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_rimcol1; + +/* Define the union u_v0_ot_pp_csc_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_en : 1; /* [0] */ + unsigned int ot_pp_csc_demo_en : 1; /* [1] */ + unsigned int ot_pp_csc_ck_gt_en : 1; /* [2] */ + unsigned int reserved_0 : 29; /* [31..3] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc_ctrl; + +/* Define the union u_v0_ot_pp_csc_coef00 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef00 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc_coef00; + +/* Define the union u_v0_ot_pp_csc_coef01 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef01 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc_coef01; + +/* Define the union u_v0_ot_pp_csc_coef02 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef02 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc_coef02; + +/* Define the union u_v0_ot_pp_csc_coef10 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef10 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc_coef10; + +/* Define the union u_v0_ot_pp_csc_coef11 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef11 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc_coef11; + +/* Define the union u_v0_ot_pp_csc_coef12 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef12 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc_coef12; + +/* Define the union u_v0_ot_pp_csc_coef20 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef20 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc_coef20; + +/* Define the union u_v0_ot_pp_csc_coef21 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef21 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc_coef21; + +/* Define the union u_v0_ot_pp_csc_coef22 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef22 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc_coef22; + +/* Define the union u_v0_ot_pp_csc_scale */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_scale : 4; /* [3..0] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc_scale; + +/* Define the union u_v0_ot_pp_csc_idc0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_idc0 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc_idc0; + +/* Define the union u_v0_ot_pp_csc_idc1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_idc1 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc_idc1; + +/* Define the union u_v0_ot_pp_csc_idc2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_idc2 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc_idc2; + +/* Define the union u_v0_ot_pp_csc_odc0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_odc0 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc_odc0; + +/* Define the union u_v0_ot_pp_csc_odc1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_odc1 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc_odc1; + +/* Define the union u_v0_ot_pp_csc_odc2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_odc2 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc_odc2; + +/* Define the union u_v0_ot_pp_csc_min_y */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_min_y : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc_min_y; + +/* Define the union u_v0_ot_pp_csc_min_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_min_c : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc_min_c; + +/* Define the union u_v0_ot_pp_csc_max_y */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_max_y : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc_max_y; + +/* Define the union u_v0_ot_pp_csc_max_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_max_c : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc_max_c; + +/* Define the union u_v0_ot_pp_csc2_coef00 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef00 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc2_coef00; + +/* Define the union u_v0_ot_pp_csc2_coef01 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef01 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc2_coef01; + +/* Define the union u_v0_ot_pp_csc2_coef02 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef02 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc2_coef02; + +/* Define the union u_v0_ot_pp_csc2_coef10 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef10 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc2_coef10; + +/* Define the union u_v0_ot_pp_csc2_coef11 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef11 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc2_coef11; + +/* Define the union u_v0_ot_pp_csc2_coef12 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef12 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc2_coef12; + +/* Define the union u_v0_ot_pp_csc2_coef20 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef20 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc2_coef20; + +/* Define the union u_v0_ot_pp_csc2_coef21 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef21 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc2_coef21; + +/* Define the union u_v0_ot_pp_csc2_coef22 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef22 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc2_coef22; + +/* Define the union u_v0_ot_pp_csc2_scale */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_scale : 4; /* [3..0] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc2_scale; + +/* Define the union u_v0_ot_pp_csc2_idc0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_idc0 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc2_idc0; + +/* Define the union u_v0_ot_pp_csc2_idc1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_idc1 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc2_idc1; + +/* Define the union u_v0_ot_pp_csc2_idc2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_idc2 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc2_idc2; + +/* Define the union u_v0_ot_pp_csc2_odc0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_odc0 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc2_odc0; + +/* Define the union u_v0_ot_pp_csc2_odc1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_odc1 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc2_odc1; + +/* Define the union u_v0_ot_pp_csc2_odc2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_odc2 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc2_odc2; + +/* Define the union u_v0_ot_pp_csc2_min_y */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_min_y : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc2_min_y; + +/* Define the union u_v0_ot_pp_csc2_min_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_min_c : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc2_min_c; + +/* Define the union u_v0_ot_pp_csc2_max_y */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_max_y : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc2_max_y; + +/* Define the union u_v0_ot_pp_csc2_max_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_max_c : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc2_max_c; + +/* Define the union u_v0_ot_pp_csc_ink_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ink_en : 1; /* [0] */ + unsigned int ink_sel : 1; /* [1] */ + unsigned int data_fmt : 1; /* [2] */ + unsigned int cross_enable : 1; /* [3] */ + unsigned int color_mode : 2; /* [5..4] */ + unsigned int reserved_0 : 26; /* [31..6] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc_ink_ctrl; + +/* Define the union u_v0_ot_pp_csc_ink_pos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int x_pos : 16; /* [15..0] */ + unsigned int y_pos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_ot_pp_csc_ink_pos; + +/* Define the union u_v0_zme_hinfo */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int out_width : 16; /* [15..0] */ + unsigned int hzme_ck_gt_en : 1; /* [16] */ + unsigned int reserved_0 : 15; /* [31..17] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_zme_hinfo; + +/* Define the union u_v0_zme_hsp */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hratio : 24; /* [23..0] */ + unsigned int hfir_order : 1; /* [24] */ + unsigned int chfir_mode : 1; /* [25] */ + unsigned int lhfir_mode : 1; /* [26] */ + unsigned int non_lnr_en : 1; /* [27] */ + unsigned int chmid_en : 1; /* [28] */ + unsigned int lhmid_en : 1; /* [29] */ + unsigned int chfir_en : 1; /* [30] */ + unsigned int lhfir_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_zme_hsp; + +/* Define the union u_v0_zme_hloffset */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int lhfir_offset : 28; /* [27..0] */ + unsigned int reserved_0 : 4; /* [31..28] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_zme_hloffset; + +/* Define the union u_v0_zme_hcoffset */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int chfir_offset : 28; /* [27..0] */ + unsigned int reserved_0 : 4; /* [31..28] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_zme_hcoffset; + +/* Define the union u_v0_zme_hzone0delta */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int zone0_delta : 22; /* [21..0] */ + unsigned int reserved_0 : 10; /* [31..22] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_zme_hzone0delta; + +/* Define the union u_v0_zme_hzone2delta */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int zone2_delta : 22; /* [21..0] */ + unsigned int reserved_0 : 10; /* [31..22] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_zme_hzone2delta; + +/* Define the union u_v0_zme_hzoneend */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int zone0_end : 12; /* [11..0] */ + unsigned int zone1_end : 12; /* [23..12] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_zme_hzoneend; + +/* Define the union u_v0_zme_hl_shootctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hl_coring : 8; /* [7..0] */ + unsigned int hl_gain : 6; /* [13..8] */ + unsigned int hl_coringadj_en : 1; /* [14] */ + unsigned int hl_flatdect_mode : 1; /* [15] */ + unsigned int hl_shootctrl_mode : 1; /* [16] */ + unsigned int reserved_0 : 1; /* [17] */ + unsigned int hl_shootctrl_en : 1; /* [18] */ + unsigned int reserved_1 : 13; /* [31..19] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_zme_hl_shootctrl; + +/* Define the union u_v0_zme_hc_shootctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hc_coring : 8; /* [7..0] */ + unsigned int hc_gain : 6; /* [13..8] */ + unsigned int hc_coringadj_en : 1; /* [14] */ + unsigned int hc_flatdect_mode : 1; /* [15] */ + unsigned int hc_shootctrl_mode : 1; /* [16] */ + unsigned int reserved_0 : 1; /* [17] */ + unsigned int hc_shootctrl_en : 1; /* [18] */ + unsigned int reserved_1 : 13; /* [31..19] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_zme_hc_shootctrl; + +/* Define the union u_v0_zme_hcoef_ren */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int apb_vhd_hf_cren : 1; /* [0] */ + unsigned int apb_vhd_hf_lren : 1; /* [1] */ + unsigned int reserved_0 : 30; /* [31..2] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_zme_hcoef_ren; + +/* Define the union u_v0_zme_hcoef_rdata */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int apb_vhd_hcoef_raddr : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_zme_hcoef_rdata; + +/* Define the union u_v0_zme_vinfo */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int out_height : 16; /* [15..0] */ + unsigned int out_fmt : 2; /* [17..16] */ + unsigned int out_pro : 1; /* [18] */ + unsigned int vzme_ck_gt_en : 1; /* [19] */ + unsigned int reserved_0 : 12; /* [31..20] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_zme_vinfo; + +/* Define the union u_v0_zme_vsp */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vratio : 16; /* [15..0] */ + unsigned int graphdet_en : 1; /* [16] */ + unsigned int reserved_0 : 8; /* [24..17] */ + unsigned int cvfir_mode : 1; /* [25] */ + unsigned int lvfir_mode : 1; /* [26] */ + unsigned int vfir_1tap_en : 1; /* [27] */ + unsigned int cvmid_en : 1; /* [28] */ + unsigned int lvmid_en : 1; /* [29] */ + unsigned int cvfir_en : 1; /* [30] */ + unsigned int lvfir_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_zme_vsp; + +/* Define the union u_v0_zme_voffset */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vchroma_offset : 16; /* [15..0] */ + unsigned int vluma_offset : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_zme_voffset; + +/* Define the union u_v0_zme_vboffset */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vbchroma_offset : 16; /* [15..0] */ + unsigned int vbluma_offset : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_zme_vboffset; + +/* Define the union u_v0_zme_vl_shootctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vl_coring : 8; /* [7..0] */ + unsigned int vl_gain : 6; /* [13..8] */ + unsigned int vl_coringadj_en : 1; /* [14] */ + unsigned int vl_flatdect_mode : 1; /* [15] */ + unsigned int vl_shootctrl_mode : 1; /* [16] */ + unsigned int reserved_0 : 1; /* [17] */ + unsigned int vl_shootctrl_en : 1; /* [18] */ + unsigned int reserved_1 : 13; /* [31..19] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_zme_vl_shootctrl; + +/* Define the union u_v0_zme_vc_shootctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vc_coring : 8; /* [7..0] */ + unsigned int vc_gain : 6; /* [13..8] */ + unsigned int vc_coringadj_en : 1; /* [14] */ + unsigned int vc_flatdect_mode : 1; /* [15] */ + unsigned int vc_shootctrl_mode : 1; /* [16] */ + unsigned int reserved_0 : 1; /* [17] */ + unsigned int vc_shootctrl_en : 1; /* [18] */ + unsigned int reserved_1 : 13; /* [31..19] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_zme_vc_shootctrl; + +/* Define the union u_v0_zme_vcoef_ren */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int apb_vhd_vf_cren : 1; /* [0] */ + unsigned int apb_vhd_vf_lren : 1; /* [1] */ + unsigned int reserved_0 : 30; /* [31..2] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_zme_vcoef_ren; + +/* Define the union u_v0_zme_vcoef_rdata */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int apb_vhd_vcoef_raddr : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_zme_vcoef_rdata; + +/* Define the union u_v0_hfir_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 1; /* [0] */ + unsigned int hfir_mode : 2; /* [2..1] */ + unsigned int mid_en : 1; /* [3] */ + unsigned int ck_gt_en : 1; /* [4] */ + unsigned int reserved_1 : 27; /* [31..5] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_hfir_ctrl; + +/* Define the union u_v0_hfircoef01 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int coef0 : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int coef1 : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_hfircoef01; + +/* Define the union u_v0_hfircoef23 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int coef2 : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int coef3 : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_hfircoef23; + +/* Define the union u_v0_hfircoef45 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int coef4 : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int coef5 : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_hfircoef45; + +/* Define the union u_v0_hfircoef67 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int coef6 : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int coef7 : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_hfircoef67; + +/* Define the union u_v1_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int galpha : 8; /* [7..0] */ + unsigned int reserved_0 : 20; /* [27..8] */ + unsigned int rupd_field : 1; /* [28] */ + unsigned int rgup_mode : 1; /* [29] */ + unsigned int nosec_flag : 1; /* [30] */ + unsigned int surface_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ctrl; + +/* Define the union u_v1_upd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int regup : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_upd; + +/* Define the union u_v1_0reso_read */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ow : 16; /* [15..0] */ + unsigned int oh : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_0reso_read; + +/* Define the union u_v1_ireso */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int iw : 16; /* [15..0] */ + unsigned int ih : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ireso; + +/* Define the union u_v1_dfpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int disp_xfpos : 16; /* [15..0] */ + unsigned int disp_yfpos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_dfpos; + +/* Define the union u_v1_dlpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int disp_xlpos : 16; /* [15..0] */ + unsigned int disp_ylpos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_dlpos; + +/* Define the union u_v1_vfpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int video_xfpos : 16; /* [15..0] */ + unsigned int video_yfpos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_vfpos; + +/* Define the union u_v1_vlpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int video_xlpos : 16; /* [15..0] */ + unsigned int video_ylpos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_vlpos; + +/* Define the union u_v1_bk */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vbk_cr : 10; /* [9..0] */ + unsigned int vbk_cb : 10; /* [19..10] */ + unsigned int vbk_y : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_bk; + +/* Define the union u_v1_alpha */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vbk_alpha : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_alpha; + +/* Define the union u_v1_mute_bk */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mute_cr : 10; /* [9..0] */ + unsigned int mute_cb : 10; /* [19..10] */ + unsigned int mute_y : 10; /* [29..20] */ + unsigned int reserved_0 : 1; /* [30] */ + unsigned int mute_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_mute_bk; + +/* Define the union u_v1_rimwidth */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int v0_rim_width : 5; /* [4..0] */ + unsigned int reserved_0 : 27; /* [31..5] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_rimwidth; + +/* Define the union u_v1_rimcol0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int v0_rim_v0 : 10; /* [9..0] */ + unsigned int v0_rim_u0 : 10; /* [19..10] */ + unsigned int v0_rim_y0 : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_rimcol0; + +/* Define the union u_v1_rimcol1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int v0_rim_v1 : 10; /* [9..0] */ + unsigned int v0_rim_u1 : 10; /* [19..10] */ + unsigned int v0_rim_y1 : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_rimcol1; + +/* Define the union u_v1_ot_pp_csc_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_en : 1; /* [0] */ + unsigned int ot_pp_csc_demo_en : 1; /* [1] */ + unsigned int ot_pp_csc_ck_gt_en : 1; /* [2] */ + unsigned int reserved_0 : 29; /* [31..3] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc_ctrl; + +/* Define the union u_v1_ot_pp_csc_coef00 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef00 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc_coef00; + +/* Define the union u_v1_ot_pp_csc_coef01 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef01 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc_coef01; + +/* Define the union u_v1_ot_pp_csc_coef02 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef02 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc_coef02; + +/* Define the union u_v1_ot_pp_csc_coef10 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef10 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc_coef10; + +/* Define the union u_v1_ot_pp_csc_coef11 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef11 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc_coef11; + +/* Define the union u_v1_ot_pp_csc_coef12 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef12 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc_coef12; + +/* Define the union u_v1_ot_pp_csc_coef20 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef20 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc_coef20; + +/* Define the union u_v1_ot_pp_csc_coef21 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef21 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc_coef21; + +/* Define the union u_v1_ot_pp_csc_coef22 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef22 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc_coef22; + +/* Define the union u_v1_ot_pp_csc_scale */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_scale : 4; /* [3..0] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc_scale; + +/* Define the union u_v1_ot_pp_csc_idc0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_idc0 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc_idc0; + +/* Define the union u_v1_ot_pp_csc_idc1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_idc1 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc_idc1; + +/* Define the union u_v1_ot_pp_csc_idc2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_idc2 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc_idc2; + +/* Define the union u_v1_ot_pp_csc_odc0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_odc0 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc_odc0; + +/* Define the union u_v1_ot_pp_csc_odc1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_odc1 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc_odc1; + +/* Define the union u_v1_ot_pp_csc_odc2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_odc2 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc_odc2; + +/* Define the union u_v1_ot_pp_csc_min_y */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_min_y : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc_min_y; + +/* Define the union u_v1_ot_pp_csc_min_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_min_c : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc_min_c; + +/* Define the union u_v1_ot_pp_csc_max_y */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_max_y : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc_max_y; + +/* Define the union u_v1_ot_pp_csc_max_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_max_c : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc_max_c; + +/* Define the union u_v1_ot_pp_csc2_coef00 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef00 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc2_coef00; + +/* Define the union u_v1_ot_pp_csc2_coef01 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef01 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc2_coef01; + +/* Define the union u_v1_ot_pp_csc2_coef02 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef02 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc2_coef02; + +/* Define the union u_v1_ot_pp_csc2_coef10 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef10 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc2_coef10; + +/* Define the union u_v1_ot_pp_csc2_coef11 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef11 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc2_coef11; + +/* Define the union u_v1_ot_pp_csc2_coef12 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef12 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc2_coef12; + +/* Define the union u_v1_ot_pp_csc2_coef20 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef20 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc2_coef20; + +/* Define the union u_v1_ot_pp_csc2_coef21 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef21 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc2_coef21; + +/* Define the union u_v1_ot_pp_csc2_coef22 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef22 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc2_coef22; + +/* Define the union u_v1_ot_pp_csc2_scale */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_scale : 4; /* [3..0] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc2_scale; + +/* Define the union u_v1_ot_pp_csc2_idc0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_idc0 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc2_idc0; + +/* Define the union u_v1_ot_pp_csc2_idc1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_idc1 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc2_idc1; + +/* Define the union u_v1_ot_pp_csc2_idc2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_idc2 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc2_idc2; + +/* Define the union u_v1_ot_pp_csc2_odc0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_odc0 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc2_odc0; + +/* Define the union u_v1_ot_pp_csc2_odc1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_odc1 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc2_odc1; + +/* Define the union u_v1_ot_pp_csc2_odc2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_odc2 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc2_odc2; + +/* Define the union u_v1_ot_pp_csc2_min_y */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_min_y : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc2_min_y; + +/* Define the union u_v1_ot_pp_csc2_min_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_min_c : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc2_min_c; + +/* Define the union u_v1_ot_pp_csc2_max_y */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_max_y : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc2_max_y; + +/* Define the union u_v1_ot_pp_csc2_max_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_max_c : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc2_max_c; + +/* Define the union u_v1_ot_pp_csc_ink_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ink_en : 1; /* [0] */ + unsigned int ink_sel : 1; /* [1] */ + unsigned int data_fmt : 1; /* [2] */ + unsigned int cross_enable : 1; /* [3] */ + unsigned int color_mode : 2; /* [5..4] */ + unsigned int reserved_0 : 26; /* [31..6] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc_ink_ctrl; + +/* Define the union u_v1_ot_pp_csc_ink_pos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int x_pos : 16; /* [15..0] */ + unsigned int y_pos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_ot_pp_csc_ink_pos; + +/* Define the union u_v1_cvfir_vinfo */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int out_height : 16; /* [15..0] */ + unsigned int out_fmt : 2; /* [17..16] */ + unsigned int out_pro : 1; /* [18] */ + unsigned int vzme_ck_gt_en : 1; /* [19] */ + unsigned int reserved_0 : 12; /* [31..20] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_cvfir_vinfo; + +/* Define the union u_v1_cvfir_vsp */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vratio : 16; /* [15..0] */ + unsigned int reserved_0 : 1; /* [16] */ + unsigned int reserved_1 : 8; /* [24..17] */ + unsigned int cvfir_mode : 1; /* [25] */ + unsigned int reserved_2 : 1; /* [26] */ + unsigned int reserved_3 : 1; /* [27] */ + unsigned int cvmid_en : 1; /* [28] */ + unsigned int reserved_4 : 1; /* [29] */ + unsigned int cvfir_en : 1; /* [30] */ + unsigned int reserved_5 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_cvfir_vsp; + +/* Define the union u_v1_cvfir_voffset */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vchroma_offset : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_cvfir_voffset; + +/* Define the union u_v1_cvfir_vboffset */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vbchroma_offset : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_cvfir_vboffset; + +/* Define the union u_v1_cvfir_vcoef0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vccoef02 : 10; /* [9..0] */ + unsigned int vccoef01 : 10; /* [19..10] */ + unsigned int vccoef00 : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_cvfir_vcoef0; + +/* Define the union u_v1_cvfir_vcoef1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vccoef11 : 10; /* [9..0] */ + unsigned int vccoef10 : 10; /* [19..10] */ + unsigned int vccoef03 : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_cvfir_vcoef1; + +/* Define the union u_v1_cvfir_vcoef2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vccoef13 : 10; /* [9..0] */ + unsigned int vccoef12 : 10; /* [19..10] */ + unsigned int reserved_0 : 12; /* [31..20] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_cvfir_vcoef2; + +/* Define the union u_v1_hfir_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 1; /* [0] */ + unsigned int hfir_mode : 2; /* [2..1] */ + unsigned int mid_en : 1; /* [3] */ + unsigned int ck_gt_en : 1; /* [4] */ + unsigned int reserved_1 : 27; /* [31..5] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_hfir_ctrl; + +/* Define the union u_v1_hfircoef01 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int coef0 : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int coef1 : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_hfircoef01; + +/* Define the union u_v1_hfircoef23 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int coef2 : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int coef3 : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_hfircoef23; + +/* Define the union u_v1_hfircoef45 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int coef4 : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int coef5 : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_hfircoef45; + +/* Define the union u_v1_hfircoef67 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int coef6 : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int coef7 : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_hfircoef67; + +/* Define the union u_v2_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int galpha : 8; /* [7..0] */ + unsigned int reserved_0 : 20; /* [27..8] */ + unsigned int rupd_field : 1; /* [28] */ + unsigned int rgup_mode : 1; /* [29] */ + unsigned int nosec_flag : 1; /* [30] */ + unsigned int surface_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ctrl; + +/* Define the union u_v2_upd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int regup : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_upd; + +/* Define the union u_v2_0reso_read */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ow : 16; /* [15..0] */ + unsigned int oh : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_0reso_read; + +/* Define the union u_v2_ireso */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int iw : 16; /* [15..0] */ + unsigned int ih : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ireso; + +/* Define the union u_v2_dfpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int disp_xfpos : 16; /* [15..0] */ + unsigned int disp_yfpos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_dfpos; + +/* Define the union u_v2_dlpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int disp_xlpos : 16; /* [15..0] */ + unsigned int disp_ylpos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_dlpos; + +/* Define the union u_v2_vfpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int video_xfpos : 16; /* [15..0] */ + unsigned int video_yfpos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_vfpos; + +/* Define the union u_v2_vlpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int video_xlpos : 16; /* [15..0] */ + unsigned int video_ylpos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_vlpos; + +/* Define the union u_v2_bk */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vbk_cr : 10; /* [9..0] */ + unsigned int vbk_cb : 10; /* [19..10] */ + unsigned int vbk_y : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_bk; + +/* Define the union u_v2_alpha */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vbk_alpha : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_alpha; + +/* Define the union u_v2_mute_bk */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mute_cr : 10; /* [9..0] */ + unsigned int mute_cb : 10; /* [19..10] */ + unsigned int mute_y : 10; /* [29..20] */ + unsigned int reserved_0 : 1; /* [30] */ + unsigned int mute_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_mute_bk; + +/* Define the union u_v2_ot_pp_csc_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_en : 1; /* [0] */ + unsigned int ot_pp_csc_demo_en : 1; /* [1] */ + unsigned int ot_pp_csc_ck_gt_en : 1; /* [2] */ + unsigned int reserved_0 : 29; /* [31..3] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc_ctrl; + +/* Define the union u_v2_ot_pp_csc_coef00 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef00 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc_coef00; + +/* Define the union u_v2_ot_pp_csc_coef01 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef01 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc_coef01; + +/* Define the union u_v2_ot_pp_csc_coef02 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef02 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc_coef02; + +/* Define the union u_v2_ot_pp_csc_coef10 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef10 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc_coef10; + +/* Define the union u_v2_ot_pp_csc_coef11 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef11 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc_coef11; + +/* Define the union u_v2_ot_pp_csc_coef12 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef12 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc_coef12; + +/* Define the union u_v2_ot_pp_csc_coef20 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef20 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc_coef20; + +/* Define the union u_v2_ot_pp_csc_coef21 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef21 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc_coef21; + +/* Define the union u_v2_ot_pp_csc_coef22 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef22 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc_coef22; + +/* Define the union u_v2_ot_pp_csc_scale */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_scale : 4; /* [3..0] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc_scale; + +/* Define the union u_v2_ot_pp_csc_idc0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_idc0 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc_idc0; + +/* Define the union u_v2_ot_pp_csc_idc1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_idc1 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc_idc1; + +/* Define the union u_v2_ot_pp_csc_idc2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_idc2 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc_idc2; + +/* Define the union u_v2_ot_pp_csc_odc0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_odc0 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc_odc0; + +/* Define the union u_v2_ot_pp_csc_odc1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_odc1 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc_odc1; + +/* Define the union u_v2_ot_pp_csc_odc2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_odc2 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc_odc2; + +/* Define the union u_v2_ot_pp_csc_min_y */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_min_y : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc_min_y; + +/* Define the union u_v2_ot_pp_csc_min_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_min_c : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc_min_c; + +/* Define the union u_v2_ot_pp_csc_max_y */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_max_y : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc_max_y; + +/* Define the union u_v2_ot_pp_csc_max_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_max_c : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc_max_c; + +/* Define the union u_v2_ot_pp_csc2_coef00 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef00 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc2_coef00; + +/* Define the union u_v2_ot_pp_csc2_coef01 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef01 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc2_coef01; + +/* Define the union u_v2_ot_pp_csc2_coef02 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef02 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc2_coef02; + +/* Define the union u_v2_ot_pp_csc2_coef10 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef10 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc2_coef10; + +/* Define the union u_v2_ot_pp_csc2_coef11 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef11 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc2_coef11; + +/* Define the union u_v2_ot_pp_csc2_coef12 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef12 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc2_coef12; + +/* Define the union u_v2_ot_pp_csc2_coef20 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef20 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc2_coef20; + +/* Define the union u_v2_ot_pp_csc2_coef21 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef21 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc2_coef21; + +/* Define the union u_v2_ot_pp_csc2_coef22 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef22 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc2_coef22; + +/* Define the union u_v2_ot_pp_csc2_scale */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_scale : 4; /* [3..0] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc2_scale; + +/* Define the union u_v2_ot_pp_csc2_idc0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_idc0 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc2_idc0; + +/* Define the union u_v2_ot_pp_csc2_idc1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_idc1 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc2_idc1; + +/* Define the union u_v2_ot_pp_csc2_idc2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_idc2 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc2_idc2; + +/* Define the union u_v2_ot_pp_csc2_odc0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_odc0 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc2_odc0; + +/* Define the union u_v2_ot_pp_csc2_odc1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_odc1 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc2_odc1; + +/* Define the union u_v2_ot_pp_csc2_odc2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_odc2 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc2_odc2; + +/* Define the union u_v2_ot_pp_csc2_min_y */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_min_y : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc2_min_y; + +/* Define the union u_v2_ot_pp_csc2_min_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_min_c : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc2_min_c; + +/* Define the union u_v2_ot_pp_csc2_max_y */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_max_y : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc2_max_y; + +/* Define the union u_v2_ot_pp_csc2_max_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_max_c : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc2_max_c; + +/* Define the union u_v2_ot_pp_csc_ink_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ink_en : 1; /* [0] */ + unsigned int ink_sel : 1; /* [1] */ + unsigned int data_fmt : 1; /* [2] */ + unsigned int cross_enable : 1; /* [3] */ + unsigned int color_mode : 2; /* [5..4] */ + unsigned int reserved_0 : 26; /* [31..6] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc_ink_ctrl; + +/* Define the union u_v2_ot_pp_csc_ink_pos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int x_pos : 16; /* [15..0] */ + unsigned int y_pos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_ot_pp_csc_ink_pos; + +/* Define the union u_v2_cvfir_vinfo */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int out_height : 16; /* [15..0] */ + unsigned int out_fmt : 2; /* [17..16] */ + unsigned int out_pro : 1; /* [18] */ + unsigned int vzme_ck_gt_en : 1; /* [19] */ + unsigned int reserved_0 : 12; /* [31..20] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_cvfir_vinfo; + +/* Define the union u_v2_cvfir_vsp */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vratio : 16; /* [15..0] */ + unsigned int reserved_0 : 1; /* [16] */ + unsigned int reserved_1 : 8; /* [24..17] */ + unsigned int cvfir_mode : 1; /* [25] */ + unsigned int reserved_2 : 1; /* [26] */ + unsigned int reserved_3 : 1; /* [27] */ + unsigned int cvmid_en : 1; /* [28] */ + unsigned int reserved_4 : 1; /* [29] */ + unsigned int cvfir_en : 1; /* [30] */ + unsigned int reserved_5 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_cvfir_vsp; + +/* Define the union u_v2_cvfir_voffset */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vchroma_offset : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_cvfir_voffset; + +/* Define the union u_v2_cvfir_vboffset */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vbchroma_offset : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_cvfir_vboffset; + +/* Define the union u_v2_cvfir_vcoef0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vccoef02 : 10; /* [9..0] */ + unsigned int vccoef01 : 10; /* [19..10] */ + unsigned int vccoef00 : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_cvfir_vcoef0; + +/* Define the union u_v2_cvfir_vcoef1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vccoef11 : 10; /* [9..0] */ + unsigned int vccoef10 : 10; /* [19..10] */ + unsigned int vccoef03 : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_cvfir_vcoef1; + +/* Define the union u_v2_cvfir_vcoef2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vccoef13 : 10; /* [9..0] */ + unsigned int vccoef12 : 10; /* [19..10] */ + unsigned int reserved_0 : 12; /* [31..20] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_cvfir_vcoef2; + +/* Define the union u_v2_hfir_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 1; /* [0] */ + unsigned int hfir_mode : 2; /* [2..1] */ + unsigned int mid_en : 1; /* [3] */ + unsigned int ck_gt_en : 1; /* [4] */ + unsigned int reserved_1 : 27; /* [31..5] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_hfir_ctrl; + +/* Define the union u_v2_hfircoef01 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int coef0 : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int coef1 : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_hfircoef01; + +/* Define the union u_v2_hfircoef23 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int coef2 : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int coef3 : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_hfircoef23; + +/* Define the union u_v2_hfircoef45 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int coef4 : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int coef5 : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_hfircoef45; + +/* Define the union u_v2_hfircoef67 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int coef6 : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int coef7 : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_hfircoef67; + +/* Define the union u_v3_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int galpha : 8; /* [7..0] */ + unsigned int reserved_0 : 20; /* [27..8] */ + unsigned int rupd_field : 1; /* [28] */ + unsigned int rgup_mode : 1; /* [29] */ + unsigned int nosec_flag : 1; /* [30] */ + unsigned int surface_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ctrl; + +/* Define the union u_v3_upd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int regup : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_upd; + +/* Define the union u_v3_0reso_read */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ow : 16; /* [15..0] */ + unsigned int oh : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_0reso_read; + +/* Define the union u_v3_ireso */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int iw : 16; /* [15..0] */ + unsigned int ih : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ireso; + +/* Define the union u_v3_dfpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int disp_xfpos : 16; /* [15..0] */ + unsigned int disp_yfpos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_dfpos; + +/* Define the union u_v3_dlpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int disp_xlpos : 16; /* [15..0] */ + unsigned int disp_ylpos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_dlpos; + +/* Define the union u_v3_vfpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int video_xfpos : 16; /* [15..0] */ + unsigned int video_yfpos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_vfpos; + +/* Define the union u_v3_vlpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int video_xlpos : 16; /* [15..0] */ + unsigned int video_ylpos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_vlpos; + +/* Define the union u_v3_bk */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vbk_cr : 10; /* [9..0] */ + unsigned int vbk_cb : 10; /* [19..10] */ + unsigned int vbk_y : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_bk; + +/* Define the union u_v3_alpha */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vbk_alpha : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_alpha; + +/* Define the union u_v3_mute_bk */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mute_cr : 10; /* [9..0] */ + unsigned int mute_cb : 10; /* [19..10] */ + unsigned int mute_y : 10; /* [29..20] */ + unsigned int reserved_0 : 1; /* [30] */ + unsigned int mute_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_mute_bk; + +/* Define the union u_v3_rimwidth */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int v0_rim_width : 5; /* [4..0] */ + unsigned int reserved_0 : 27; /* [31..5] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_rimwidth; + +/* Define the union u_v3_rimcol0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int v0_rim_v0 : 10; /* [9..0] */ + unsigned int v0_rim_u0 : 10; /* [19..10] */ + unsigned int v0_rim_y0 : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_rimcol0; + +/* Define the union u_v3_rimcol1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int v0_rim_v1 : 10; /* [9..0] */ + unsigned int v0_rim_u1 : 10; /* [19..10] */ + unsigned int v0_rim_y1 : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_rimcol1; + +/* Define the union u_v3_ot_pp_csc_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_en : 1; /* [0] */ + unsigned int ot_pp_csc_demo_en : 1; /* [1] */ + unsigned int ot_pp_csc_ck_gt_en : 1; /* [2] */ + unsigned int reserved_0 : 29; /* [31..3] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc_ctrl; + +/* Define the union u_v3_ot_pp_csc_coef00 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef00 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc_coef00; + +/* Define the union u_v3_ot_pp_csc_coef01 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef01 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc_coef01; + +/* Define the union u_v3_ot_pp_csc_coef02 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef02 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc_coef02; + +/* Define the union u_v3_ot_pp_csc_coef10 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef10 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc_coef10; + +/* Define the union u_v3_ot_pp_csc_coef11 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef11 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc_coef11; + +/* Define the union u_v3_ot_pp_csc_coef12 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef12 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc_coef12; + +/* Define the union u_v3_ot_pp_csc_coef20 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef20 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc_coef20; + +/* Define the union u_v3_ot_pp_csc_coef21 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef21 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc_coef21; + +/* Define the union u_v3_ot_pp_csc_coef22 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef22 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc_coef22; + +/* Define the union u_v3_ot_pp_csc_scale */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_scale : 4; /* [3..0] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc_scale; + +/* Define the union u_v3_ot_pp_csc_idc0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_idc0 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc_idc0; + +/* Define the union u_v3_ot_pp_csc_idc1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_idc1 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc_idc1; + +/* Define the union u_v3_ot_pp_csc_idc2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_idc2 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc_idc2; + +/* Define the union u_v3_ot_pp_csc_odc0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_odc0 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc_odc0; + +/* Define the union u_v3_ot_pp_csc_odc1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_odc1 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc_odc1; + +/* Define the union u_v3_ot_pp_csc_odc2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_odc2 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc_odc2; + +/* Define the union u_v3_ot_pp_csc_min_y */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_min_y : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc_min_y; + +/* Define the union u_v3_ot_pp_csc_min_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_min_c : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc_min_c; + +/* Define the union u_v3_ot_pp_csc_max_y */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_max_y : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc_max_y; + +/* Define the union u_v3_ot_pp_csc_max_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_max_c : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc_max_c; + +/* Define the union u_v3_ot_pp_csc2_coef00 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef00 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc2_coef00; + +/* Define the union u_v3_ot_pp_csc2_coef01 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef01 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc2_coef01; + +/* Define the union u_v3_ot_pp_csc2_coef02 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef02 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc2_coef02; + +/* Define the union u_v3_ot_pp_csc2_coef10 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef10 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc2_coef10; + +/* Define the union u_v3_ot_pp_csc2_coef11 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef11 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc2_coef11; + +/* Define the union u_v3_ot_pp_csc2_coef12 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef12 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc2_coef12; + +/* Define the union u_v3_ot_pp_csc2_coef20 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef20 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc2_coef20; + +/* Define the union u_v3_ot_pp_csc2_coef21 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef21 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc2_coef21; + +/* Define the union u_v3_ot_pp_csc2_coef22 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef22 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc2_coef22; + +/* Define the union u_v3_ot_pp_csc2_scale */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_scale : 4; /* [3..0] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc2_scale; + +/* Define the union u_v3_ot_pp_csc2_idc0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_idc0 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc2_idc0; + +/* Define the union u_v3_ot_pp_csc2_idc1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_idc1 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc2_idc1; + +/* Define the union u_v3_ot_pp_csc2_idc2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_idc2 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc2_idc2; + +/* Define the union u_v3_ot_pp_csc2_odc0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_odc0 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc2_odc0; + +/* Define the union u_v3_ot_pp_csc2_odc1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_odc1 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc2_odc1; + +/* Define the union u_v3_ot_pp_csc2_odc2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_odc2 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc2_odc2; + +/* Define the union u_v3_ot_pp_csc2_min_y */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_min_y : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc2_min_y; + +/* Define the union u_v3_ot_pp_csc2_min_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_min_c : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc2_min_c; + +/* Define the union u_v3_ot_pp_csc2_max_y */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_max_y : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc2_max_y; + +/* Define the union u_v3_ot_pp_csc2_max_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_max_c : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc2_max_c; + +/* Define the union u_v3_ot_pp_csc_ink_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ink_en : 1; /* [0] */ + unsigned int ink_sel : 1; /* [1] */ + unsigned int data_fmt : 1; /* [2] */ + unsigned int cross_enable : 1; /* [3] */ + unsigned int color_mode : 2; /* [5..4] */ + unsigned int reserved_0 : 26; /* [31..6] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc_ink_ctrl; + +/* Define the union u_v3_ot_pp_csc_ink_pos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int x_pos : 16; /* [15..0] */ + unsigned int y_pos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_ot_pp_csc_ink_pos; + +/* Define the union u_v3_hfir_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 1; /* [0] */ + unsigned int hfir_mode : 2; /* [2..1] */ + unsigned int mid_en : 1; /* [3] */ + unsigned int ck_gt_en : 1; /* [4] */ + unsigned int reserved_1 : 27; /* [31..5] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_hfir_ctrl; + +/* Define the union u_v3_hfircoef01 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int coef0 : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int coef1 : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_hfircoef01; + +/* Define the union u_v3_hfircoef23 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int coef2 : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int coef3 : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_hfircoef23; + +/* Define the union u_v3_hfircoef45 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int coef4 : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int coef5 : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_hfircoef45; + +/* Define the union u_v3_hfircoef67 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int coef6 : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int coef7 : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v3_hfircoef67; + +/* Define the union u_vp0_upd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int regup : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vp0_upd; + +/* Define the union u_vp0_ireso */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int iw : 16; /* [15..0] */ + unsigned int ih : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vp0_ireso; + +/* Define the union u_vp0_lbox_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mute_en : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vp0_lbox_ctrl; + +/* Define the union u_vp0_galpha */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int galpha : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vp0_galpha; + +/* Define the union u_vp0_dfpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int disp_xfpos : 12; /* [11..0] */ + unsigned int disp_yfpos : 12; /* [23..12] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vp0_dfpos; + +/* Define the union u_vp0_dlpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int disp_xlpos : 12; /* [11..0] */ + unsigned int disp_ylpos : 12; /* [23..12] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vp0_dlpos; + +/* Define the union u_vp0_vfpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int video_xfpos : 12; /* [11..0] */ + unsigned int video_yfpos : 12; /* [23..12] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vp0_vfpos; + +/* Define the union u_vp0_vlpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int video_xlpos : 12; /* [11..0] */ + unsigned int video_ylpos : 12; /* [23..12] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vp0_vlpos; + +/* Define the union u_vp0_bk */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vbk_cr : 10; /* [9..0] */ + unsigned int vbk_cb : 10; /* [19..10] */ + unsigned int vbk_y : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vp0_bk; + +/* Define the union u_vp0_alpha */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vbk_alpha : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vp0_alpha; + +/* Define the union u_vp0_mute_bk */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mute_cr : 10; /* [9..0] */ + unsigned int mute_cb : 10; /* [19..10] */ + unsigned int mute_y : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vp0_mute_bk; + +/* Define the union u_g0_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int galpha : 8; /* [7..0] */ + unsigned int reserved_0 : 19; /* [26..8] */ + unsigned int g0_depremult : 1; /* [27] */ + unsigned int rupd_field : 1; /* [28] */ + unsigned int rgup_mode : 1; /* [29] */ + unsigned int nosec_flag : 1; /* [30] */ + unsigned int surface_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ctrl; + +/* Define the union u_g0_upd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int regup : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_upd; + +/* Define the union u_g0_0reso_read */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ow : 16; /* [15..0] */ + unsigned int oh : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_0reso_read; + +/* Define the union u_g0_ireso */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int iw : 16; /* [15..0] */ + unsigned int ih : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ireso; + +/* Define the union u_g0_dfpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int disp_xfpos : 16; /* [15..0] */ + unsigned int disp_yfpos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_dfpos; + +/* Define the union u_g0_dlpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int disp_xlpos : 16; /* [15..0] */ + unsigned int disp_ylpos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_dlpos; + +/* Define the union u_g0_vfpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int video_xfpos : 16; /* [15..0] */ + unsigned int video_yfpos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_vfpos; + +/* Define the union u_g0_vlpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int video_xlpos : 16; /* [15..0] */ + unsigned int video_ylpos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_vlpos; + +/* Define the union u_g0_bk */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vbk_cr : 10; /* [9..0] */ + unsigned int vbk_cb : 10; /* [19..10] */ + unsigned int vbk_y : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_bk; + +/* Define the union u_g0_alpha */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vbk_alpha : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_alpha; + +/* Define the union u_g0_mute_bk */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mute_cr : 10; /* [9..0] */ + unsigned int mute_cb : 10; /* [19..10] */ + unsigned int mute_y : 10; /* [29..20] */ + unsigned int reserved_0 : 1; /* [30] */ + unsigned int mute_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_mute_bk; + +/* Define the union u_g0_lbox_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mute_en : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_lbox_ctrl; + +/* Define the union u_g0_ot_pp_csc_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_en : 1; /* [0] */ + unsigned int ot_pp_csc_demo_en : 1; /* [1] */ + unsigned int ot_pp_csc_ck_gt_en : 1; /* [2] */ + unsigned int reserved_0 : 29; /* [31..3] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc_ctrl; + +/* Define the union u_g0_ot_pp_csc_coef00 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef00 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc_coef00; + +/* Define the union u_g0_ot_pp_csc_coef01 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef01 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc_coef01; + +/* Define the union u_g0_ot_pp_csc_coef02 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef02 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc_coef02; + +/* Define the union u_g0_ot_pp_csc_coef10 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef10 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc_coef10; + +/* Define the union u_g0_ot_pp_csc_coef11 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef11 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc_coef11; + +/* Define the union u_g0_ot_pp_csc_coef12 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef12 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc_coef12; + +/* Define the union u_g0_ot_pp_csc_coef20 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef20 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc_coef20; + +/* Define the union u_g0_ot_pp_csc_coef21 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef21 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc_coef21; + +/* Define the union u_g0_ot_pp_csc_coef22 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef22 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc_coef22; + +/* Define the union u_g0_ot_pp_csc_scale */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_scale : 4; /* [3..0] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc_scale; + +/* Define the union u_g0_ot_pp_csc_idc0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_idc0 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc_idc0; + +/* Define the union u_g0_ot_pp_csc_idc1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_idc1 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc_idc1; + +/* Define the union u_g0_ot_pp_csc_idc2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_idc2 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc_idc2; + +/* Define the union u_g0_ot_pp_csc_odc0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_odc0 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc_odc0; + +/* Define the union u_g0_ot_pp_csc_odc1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_odc1 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc_odc1; + +/* Define the union u_g0_ot_pp_csc_odc2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_odc2 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc_odc2; + +/* Define the union u_g0_ot_pp_csc_min_y */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_min_y : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc_min_y; + +/* Define the union u_g0_ot_pp_csc_min_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_min_c : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc_min_c; + +/* Define the union u_g0_ot_pp_csc_max_y */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_max_y : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc_max_y; + +/* Define the union u_g0_ot_pp_csc_max_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_max_c : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc_max_c; + +/* Define the union u_g0_ot_pp_csc2_coef00 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef00 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc2_coef00; + +/* Define the union u_g0_ot_pp_csc2_coef01 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef01 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc2_coef01; + +/* Define the union u_g0_ot_pp_csc2_coef02 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef02 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc2_coef02; + +/* Define the union u_g0_ot_pp_csc2_coef10 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef10 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc2_coef10; + +/* Define the union u_g0_ot_pp_csc2_coef11 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef11 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc2_coef11; + +/* Define the union u_g0_ot_pp_csc2_coef12 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef12 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc2_coef12; + +/* Define the union u_g0_ot_pp_csc2_coef20 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef20 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc2_coef20; + +/* Define the union u_g0_ot_pp_csc2_coef21 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef21 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc2_coef21; + +/* Define the union u_g0_ot_pp_csc2_coef22 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef22 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc2_coef22; + +/* Define the union u_g0_ot_pp_csc2_scale */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_scale : 4; /* [3..0] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc2_scale; + +/* Define the union u_g0_ot_pp_csc2_idc0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_idc0 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc2_idc0; + +/* Define the union u_g0_ot_pp_csc2_idc1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_idc1 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc2_idc1; + +/* Define the union u_g0_ot_pp_csc2_idc2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_idc2 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc2_idc2; + +/* Define the union u_g0_ot_pp_csc2_odc0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_odc0 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc2_odc0; + +/* Define the union u_g0_ot_pp_csc2_odc1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_odc1 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc2_odc1; + +/* Define the union u_g0_ot_pp_csc2_odc2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_odc2 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc2_odc2; + +/* Define the union u_g0_ot_pp_csc2_min_y */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_min_y : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc2_min_y; + +/* Define the union u_g0_ot_pp_csc2_min_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_min_c : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc2_min_c; + +/* Define the union u_g0_ot_pp_csc2_max_y */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_max_y : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc2_max_y; + +/* Define the union u_g0_ot_pp_csc2_max_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_max_c : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc2_max_c; + +/* Define the union u_g0_ot_pp_csc_ink_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ink_en : 1; /* [0] */ + unsigned int ink_sel : 1; /* [1] */ + unsigned int data_fmt : 1; /* [2] */ + unsigned int cross_enable : 1; /* [3] */ + unsigned int color_mode : 2; /* [5..4] */ + unsigned int reserved_0 : 26; /* [31..6] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc_ink_ctrl; + +/* Define the union u_g0_ot_pp_csc_ink_pos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int x_pos : 16; /* [15..0] */ + unsigned int y_pos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_ot_pp_csc_ink_pos; + +/* Define the union u_g0_dof_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 31; /* [30..0] */ + unsigned int dof_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_dof_ctrl; + +/* Define the union u_g0_dof_step */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int left_step : 8; /* [7..0] */ + unsigned int right_step : 8; /* [15..8] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_dof_step; + +/* Define the union u_g0_dof_bkg */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dof_bk_cr : 10; /* [9..0] */ + unsigned int dof_bk_cb : 10; /* [19..10] */ + unsigned int dof_bk_y : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_dof_bkg; + +/* Define the union u_g0_dof_alpha */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dof_bk_alpha : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_dof_alpha; + +/* Define the union u_g0_zme_hinfo */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int out_width : 16; /* [15..0] */ + unsigned int ck_gt_en : 1; /* [16] */ + unsigned int reserved_0 : 15; /* [31..17] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_zme_hinfo; + +/* Define the union u_g0_zme_hsp */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hratio : 24; /* [23..0] */ + unsigned int hfir_order : 1; /* [24] */ + unsigned int ahfir_mode : 1; /* [25] */ + unsigned int lhfir_mode : 1; /* [26] */ + unsigned int reserved_0 : 1; /* [27] */ + unsigned int chfir_mid_en : 1; /* [28] */ + unsigned int lhfir_mid_en : 1; /* [29] */ + unsigned int ahfir_mid_en : 1; /* [30] */ + unsigned int hfir_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_zme_hsp; + +/* Define the union u_g0_zme_hloffset */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int lhfir_offset : 24; /* [23..0] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_zme_hloffset; + +/* Define the union u_g0_zme_hcoffset */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int chfir_offset : 24; /* [23..0] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_zme_hcoffset; + +/* Define the union u_g0_zme_coef_ren */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 1; /* [0] */ + unsigned int apb_g0_vf_lren : 1; /* [1] */ + unsigned int reserved_1 : 1; /* [2] */ + unsigned int apb_g0_hf_lren : 1; /* [3] */ + unsigned int reserved_2 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_zme_coef_ren; + +/* Define the union u_g0_zme_coef_rdata */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int apb_vhd_coef_raddr : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_zme_coef_rdata; + +/* Define the union u_g0_zme_vinfo */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int out_height : 16; /* [15..0] */ + unsigned int reserved_0 : 2; /* [17..16] */ + unsigned int out_pro : 1; /* [18] */ + unsigned int reserved_1 : 13; /* [31..19] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_zme_vinfo; + +/* Define the union u_g0_zme_vsp */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vratio : 16; /* [15..0] */ + unsigned int reserved_0 : 9; /* [24..16] */ + unsigned int vafir_mode : 1; /* [25] */ + unsigned int lvfir_mode : 1; /* [26] */ + unsigned int reserved_1 : 1; /* [27] */ + unsigned int cvfir_mid_en : 1; /* [28] */ + unsigned int lvfir_mid_en : 1; /* [29] */ + unsigned int avfir_mid_en : 1; /* [30] */ + unsigned int vfir_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_zme_vsp; + +/* Define the union u_g0_zme_voffset */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vbtm_offset : 16; /* [15..0] */ + unsigned int vtp_offset : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g0_zme_voffset; + +/* Define the union u_g1_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int galpha : 8; /* [7..0] */ + unsigned int reserved_0 : 19; /* [26..8] */ + unsigned int g1_depremult : 1; /* [27] */ + unsigned int rupd_field : 1; /* [28] */ + unsigned int rgup_mode : 1; /* [29] */ + unsigned int nosec_flag : 1; /* [30] */ + unsigned int surface_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ctrl; + +/* Define the union u_g1_upd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int regup : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_upd; + +/* Define the union u_g1_0reso_read */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ow : 16; /* [15..0] */ + unsigned int oh : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_0reso_read; + +/* Define the union u_g1_ireso */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int iw : 16; /* [15..0] */ + unsigned int ih : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ireso; + +/* Define the union u_g1_dfpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int disp_xfpos : 16; /* [15..0] */ + unsigned int disp_yfpos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_dfpos; + +/* Define the union u_g1_dlpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int disp_xlpos : 16; /* [15..0] */ + unsigned int disp_ylpos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_dlpos; + +/* Define the union u_g1_vfpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int video_xfpos : 16; /* [15..0] */ + unsigned int video_yfpos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_vfpos; + +/* Define the union u_g1_vlpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int video_xlpos : 16; /* [15..0] */ + unsigned int video_ylpos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_vlpos; + +/* Define the union u_g1_bk */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vbk_cr : 10; /* [9..0] */ + unsigned int vbk_cb : 10; /* [19..10] */ + unsigned int vbk_y : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_bk; + +/* Define the union u_g1_alpha */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vbk_alpha : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_alpha; + +/* Define the union u_g1_mute_bk */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mute_cr : 10; /* [9..0] */ + unsigned int mute_cb : 10; /* [19..10] */ + unsigned int mute_y : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_mute_bk; + +/* Define the union u_g1_lbox_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mute_en : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_lbox_ctrl; + +/* Define the union u_g1_ot_pp_csc_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_en : 1; /* [0] */ + unsigned int ot_pp_csc_demo_en : 1; /* [1] */ + unsigned int ot_pp_csc_ck_gt_en : 1; /* [2] */ + unsigned int reserved_0 : 29; /* [31..3] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc_ctrl; + +/* Define the union u_g1_ot_pp_csc_coef00 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef00 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc_coef00; + +/* Define the union u_g1_ot_pp_csc_coef01 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef01 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc_coef01; + +/* Define the union u_g1_ot_pp_csc_coef02 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef02 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc_coef02; + +/* Define the union u_g1_ot_pp_csc_coef10 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef10 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc_coef10; + +/* Define the union u_g1_ot_pp_csc_coef11 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef11 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc_coef11; + +/* Define the union u_g1_ot_pp_csc_coef12 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef12 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc_coef12; + +/* Define the union u_g1_ot_pp_csc_coef20 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef20 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc_coef20; + +/* Define the union u_g1_ot_pp_csc_coef21 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef21 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc_coef21; + +/* Define the union u_g1_ot_pp_csc_coef22 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef22 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc_coef22; + +/* Define the union u_g1_ot_pp_csc_scale */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_scale : 4; /* [3..0] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc_scale; + +/* Define the union u_g1_ot_pp_csc_idc0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_idc0 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc_idc0; + +/* Define the union u_g1_ot_pp_csc_idc1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_idc1 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc_idc1; + +/* Define the union u_g1_ot_pp_csc_idc2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_idc2 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc_idc2; + +/* Define the union u_g1_ot_pp_csc_odc0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_odc0 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc_odc0; + +/* Define the union u_g1_ot_pp_csc_odc1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_odc1 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc_odc1; + +/* Define the union u_g1_ot_pp_csc_odc2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_odc2 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc_odc2; + +/* Define the union u_g1_ot_pp_csc_min_y */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_min_y : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc_min_y; + +/* Define the union u_g1_ot_pp_csc_min_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_min_c : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc_min_c; + +/* Define the union u_g1_ot_pp_csc_max_y */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_max_y : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc_max_y; + +/* Define the union u_g1_ot_pp_csc_max_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_max_c : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc_max_c; + +/* Define the union u_g1_ot_pp_csc2_coef00 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef00 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc2_coef00; + +/* Define the union u_g1_ot_pp_csc2_coef01 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef01 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc2_coef01; + +/* Define the union u_g1_ot_pp_csc2_coef02 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef02 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc2_coef02; + +/* Define the union u_g1_ot_pp_csc2_coef10 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef10 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc2_coef10; + +/* Define the union u_g1_ot_pp_csc2_coef11 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef11 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc2_coef11; + +/* Define the union u_g1_ot_pp_csc2_coef12 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef12 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc2_coef12; + +/* Define the union u_g1_ot_pp_csc2_coef20 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef20 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc2_coef20; + +/* Define the union u_g1_ot_pp_csc2_coef21 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef21 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc2_coef21; + +/* Define the union u_g1_ot_pp_csc2_coef22 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef22 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc2_coef22; + +/* Define the union u_g1_ot_pp_csc2_scale */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_scale : 4; /* [3..0] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc2_scale; + +/* Define the union u_g1_ot_pp_csc2_idc0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_idc0 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc2_idc0; + +/* Define the union u_g1_ot_pp_csc2_idc1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_idc1 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc2_idc1; + +/* Define the union u_g1_ot_pp_csc2_idc2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_idc2 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc2_idc2; + +/* Define the union u_g1_ot_pp_csc2_odc0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_odc0 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc2_odc0; + +/* Define the union u_g1_ot_pp_csc2_odc1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_odc1 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc2_odc1; + +/* Define the union u_g1_ot_pp_csc2_odc2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_odc2 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc2_odc2; + +/* Define the union u_g1_ot_pp_csc2_min_y */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_min_y : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc2_min_y; + +/* Define the union u_g1_ot_pp_csc2_min_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_min_c : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc2_min_c; + +/* Define the union u_g1_ot_pp_csc2_max_y */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_max_y : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc2_max_y; + +/* Define the union u_g1_ot_pp_csc2_max_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_max_c : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc2_max_c; + +/* Define the union u_g1_ot_pp_csc_ink_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ink_en : 1; /* [0] */ + unsigned int ink_sel : 1; /* [1] */ + unsigned int data_fmt : 1; /* [2] */ + unsigned int cross_enable : 1; /* [3] */ + unsigned int color_mode : 2; /* [5..4] */ + unsigned int reserved_0 : 26; /* [31..6] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc_ink_ctrl; + +/* Define the union u_g1_ot_pp_csc_ink_pos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int x_pos : 16; /* [15..0] */ + unsigned int y_pos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_ot_pp_csc_ink_pos; + +/* Define the union u_g1_zme_hinfo */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int out_width : 16; /* [15..0] */ + unsigned int ck_gt_en : 1; /* [16] */ + unsigned int reserved_0 : 15; /* [31..17] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_zme_hinfo; + +/* Define the union u_g1_zme_hsp */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hratio : 24; /* [23..0] */ + unsigned int hfir_order : 1; /* [24] */ + unsigned int ahfir_mode : 1; /* [25] */ + unsigned int lhfir_mode : 1; /* [26] */ + unsigned int reserved_0 : 1; /* [27] */ + unsigned int chfir_mid_en : 1; /* [28] */ + unsigned int lhfir_mid_en : 1; /* [29] */ + unsigned int ahfir_mid_en : 1; /* [30] */ + unsigned int hfir_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_zme_hsp; + +/* Define the union u_g1_zme_hloffset */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int lhfir_offset : 24; /* [23..0] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_zme_hloffset; + +/* Define the union u_g1_zme_hcoffset */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int chfir_offset : 24; /* [23..0] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_zme_hcoffset; + +/* Define the union u_g1_zme_coef_ren */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 1; /* [0] */ + unsigned int apb_g1_vf_lren : 1; /* [1] */ + unsigned int reserved_1 : 1; /* [2] */ + unsigned int apb_g1_hf_lren : 1; /* [3] */ + unsigned int reserved_2 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_zme_coef_ren; + +/* Define the union u_g1_zme_coef_rdata */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int apb_vhd_coef_raddr : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_zme_coef_rdata; + +/* Define the union u_g1_zme_vinfo */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int out_height : 16; /* [15..0] */ + unsigned int reserved_0 : 2; /* [17..16] */ + unsigned int out_pro : 1; /* [18] */ + unsigned int reserved_1 : 13; /* [31..19] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_zme_vinfo; + +/* Define the union u_g1_zme_vsp */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vratio : 16; /* [15..0] */ + unsigned int reserved_0 : 9; /* [24..16] */ + unsigned int vafir_mode : 1; /* [25] */ + unsigned int lvfir_mode : 1; /* [26] */ + unsigned int reserved_1 : 1; /* [27] */ + unsigned int cvfir_mid_en : 1; /* [28] */ + unsigned int lvfir_mid_en : 1; /* [29] */ + unsigned int avfir_mid_en : 1; /* [30] */ + unsigned int vfir_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_zme_vsp; + +/* Define the union u_g1_zme_voffset */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vbtm_offset : 16; /* [15..0] */ + unsigned int vtp_offset : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_zme_voffset; + +/* Define the union u_g2_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int galpha : 8; /* [7..0] */ + unsigned int reserved_0 : 19; /* [26..8] */ + unsigned int g1_depremult : 1; /* [27] */ + unsigned int rupd_field : 1; /* [28] */ + unsigned int rgup_mode : 1; /* [29] */ + unsigned int nosec_flag : 1; /* [30] */ + unsigned int surface_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ctrl; + +/* Define the union u_g2_upd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int regup : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_upd; + +/* Define the union u_g2_0reso_read */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ow : 16; /* [15..0] */ + unsigned int oh : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_0reso_read; + +/* Define the union u_g2_ireso */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int iw : 16; /* [15..0] */ + unsigned int ih : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ireso; + +/* Define the union u_g2_dfpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int disp_xfpos : 16; /* [15..0] */ + unsigned int disp_yfpos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_dfpos; + +/* Define the union u_g2_dlpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int disp_xlpos : 16; /* [15..0] */ + unsigned int disp_ylpos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_dlpos; + +/* Define the union u_g2_vfpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int video_xfpos : 16; /* [15..0] */ + unsigned int video_yfpos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_vfpos; + +/* Define the union u_g2_vlpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int video_xlpos : 16; /* [15..0] */ + unsigned int video_ylpos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_vlpos; + +/* Define the union u_g2_bk */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vbk_cr : 10; /* [9..0] */ + unsigned int vbk_cb : 10; /* [19..10] */ + unsigned int vbk_y : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_bk; + +/* Define the union u_g2_alpha */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vbk_alpha : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_alpha; + +/* Define the union u_g2_mute_bk */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mute_cr : 10; /* [9..0] */ + unsigned int mute_cb : 10; /* [19..10] */ + unsigned int mute_y : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_mute_bk; + +/* Define the union u_g2_lbox_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mute_en : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_lbox_ctrl; + +/* Define the union u_g2_ot_pp_csc_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_en : 1; /* [0] */ + unsigned int ot_pp_csc_demo_en : 1; /* [1] */ + unsigned int ot_pp_csc_ck_gt_en : 1; /* [2] */ + unsigned int reserved_0 : 29; /* [31..3] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc_ctrl; + +/* Define the union u_g2_ot_pp_csc_coef00 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef00 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc_coef00; + +/* Define the union u_g2_ot_pp_csc_coef01 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef01 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc_coef01; + +/* Define the union u_g2_ot_pp_csc_coef02 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef02 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc_coef02; + +/* Define the union u_g2_ot_pp_csc_coef10 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef10 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc_coef10; + +/* Define the union u_g2_ot_pp_csc_coef11 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef11 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc_coef11; + +/* Define the union u_g2_ot_pp_csc_coef12 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef12 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc_coef12; + +/* Define the union u_g2_ot_pp_csc_coef20 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef20 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc_coef20; + +/* Define the union u_g2_ot_pp_csc_coef21 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef21 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc_coef21; + +/* Define the union u_g2_ot_pp_csc_coef22 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef22 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc_coef22; + +/* Define the union u_g2_ot_pp_csc_scale */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_scale : 4; /* [3..0] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc_scale; + +/* Define the union u_g2_ot_pp_csc_idc0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_idc0 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc_idc0; + +/* Define the union u_g2_ot_pp_csc_idc1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_idc1 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc_idc1; + +/* Define the union u_g2_ot_pp_csc_idc2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_idc2 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc_idc2; + +/* Define the union u_g2_ot_pp_csc_odc0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_odc0 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc_odc0; + +/* Define the union u_g2_ot_pp_csc_odc1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_odc1 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc_odc1; + +/* Define the union u_g2_ot_pp_csc_odc2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_odc2 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc_odc2; + +/* Define the union u_g2_ot_pp_csc_min_y */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_min_y : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc_min_y; + +/* Define the union u_g2_ot_pp_csc_min_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_min_c : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc_min_c; + +/* Define the union u_g2_ot_pp_csc_max_y */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_max_y : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc_max_y; + +/* Define the union u_g2_ot_pp_csc_max_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_max_c : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc_max_c; + +/* Define the union u_g2_ot_pp_csc2_coef00 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef00 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc2_coef00; + +/* Define the union u_g2_ot_pp_csc2_coef01 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef01 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc2_coef01; + +/* Define the union u_g2_ot_pp_csc2_coef02 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef02 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc2_coef02; + +/* Define the union u_g2_ot_pp_csc2_coef10 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef10 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc2_coef10; + +/* Define the union u_g2_ot_pp_csc2_coef11 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef11 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc2_coef11; + +/* Define the union u_g2_ot_pp_csc2_coef12 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef12 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc2_coef12; + +/* Define the union u_g2_ot_pp_csc2_coef20 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef20 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc2_coef20; + +/* Define the union u_g2_ot_pp_csc2_coef21 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef21 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc2_coef21; + +/* Define the union u_g2_ot_pp_csc2_coef22 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef22 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc2_coef22; + +/* Define the union u_g2_ot_pp_csc2_scale */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_scale : 4; /* [3..0] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc2_scale; + +/* Define the union u_g2_ot_pp_csc2_idc0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_idc0 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc2_idc0; + +/* Define the union u_g2_ot_pp_csc2_idc1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_idc1 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc2_idc1; + +/* Define the union u_g2_ot_pp_csc2_idc2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_idc2 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc2_idc2; + +/* Define the union u_g2_ot_pp_csc2_odc0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_odc0 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc2_odc0; + +/* Define the union u_g2_ot_pp_csc2_odc1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_odc1 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc2_odc1; + +/* Define the union u_g2_ot_pp_csc2_odc2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_odc2 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc2_odc2; + +/* Define the union u_g2_ot_pp_csc2_min_y */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_min_y : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc2_min_y; + +/* Define the union u_g2_ot_pp_csc2_min_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_min_c : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc2_min_c; + +/* Define the union u_g2_ot_pp_csc2_max_y */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_max_y : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc2_max_y; + +/* Define the union u_g2_ot_pp_csc2_max_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_max_c : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc2_max_c; + +/* Define the union u_g2_ot_pp_csc_ink_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ink_en : 1; /* [0] */ + unsigned int ink_sel : 1; /* [1] */ + unsigned int data_fmt : 1; /* [2] */ + unsigned int cross_enable : 1; /* [3] */ + unsigned int color_mode : 2; /* [5..4] */ + unsigned int reserved_0 : 26; /* [31..6] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc_ink_ctrl; + +/* Define the union u_g2_ot_pp_csc_ink_pos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int x_pos : 16; /* [15..0] */ + unsigned int y_pos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g2_ot_pp_csc_ink_pos; + +/* Define the union u_g3_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int galpha : 8; /* [7..0] */ + unsigned int reserved_0 : 19; /* [26..8] */ + unsigned int g1_depremult : 1; /* [27] */ + unsigned int rupd_field : 1; /* [28] */ + unsigned int rgup_mode : 1; /* [29] */ + unsigned int nosec_flag : 1; /* [30] */ + unsigned int surface_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ctrl; + +/* Define the union u_g3_upd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int regup : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_upd; + +/* Define the union u_g3_0reso_read */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ow : 16; /* [15..0] */ + unsigned int oh : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_0reso_read; + +/* Define the union u_g3_ireso */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int iw : 16; /* [15..0] */ + unsigned int ih : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ireso; + +/* Define the union u_g3_dfpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int disp_xfpos : 16; /* [15..0] */ + unsigned int disp_yfpos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_dfpos; + +/* Define the union u_g3_dlpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int disp_xlpos : 16; /* [15..0] */ + unsigned int disp_ylpos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_dlpos; + +/* Define the union u_g3_vfpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int video_xfpos : 16; /* [15..0] */ + unsigned int video_yfpos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_vfpos; + +/* Define the union u_g3_vlpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int video_xlpos : 16; /* [15..0] */ + unsigned int video_ylpos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_vlpos; + +/* Define the union u_g3_bk */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vbk_cr : 10; /* [9..0] */ + unsigned int vbk_cb : 10; /* [19..10] */ + unsigned int vbk_y : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_bk; + +/* Define the union u_g3_alpha */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vbk_alpha : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_alpha; + +/* Define the union u_g3_mute_bk */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mute_cr : 10; /* [9..0] */ + unsigned int mute_cb : 10; /* [19..10] */ + unsigned int mute_y : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_mute_bk; + +/* Define the union u_g3_lbox_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mute_en : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_lbox_ctrl; + +/* Define the union u_g3_ot_pp_csc_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_en : 1; /* [0] */ + unsigned int ot_pp_csc_demo_en : 1; /* [1] */ + unsigned int ot_pp_csc_ck_gt_en : 1; /* [2] */ + unsigned int reserved_0 : 29; /* [31..3] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc_ctrl; + +/* Define the union u_g3_ot_pp_csc_coef00 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef00 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc_coef00; + +/* Define the union u_g3_ot_pp_csc_coef01 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef01 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc_coef01; + +/* Define the union u_g3_ot_pp_csc_coef02 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef02 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc_coef02; + +/* Define the union u_g3_ot_pp_csc_coef10 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef10 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc_coef10; + +/* Define the union u_g3_ot_pp_csc_coef11 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef11 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc_coef11; + +/* Define the union u_g3_ot_pp_csc_coef12 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef12 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc_coef12; + +/* Define the union u_g3_ot_pp_csc_coef20 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef20 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc_coef20; + +/* Define the union u_g3_ot_pp_csc_coef21 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef21 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc_coef21; + +/* Define the union u_g3_ot_pp_csc_coef22 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_coef22 : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc_coef22; + +/* Define the union u_g3_ot_pp_csc_scale */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_scale : 4; /* [3..0] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc_scale; + +/* Define the union u_g3_ot_pp_csc_idc0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_idc0 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc_idc0; + +/* Define the union u_g3_ot_pp_csc_idc1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_idc1 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc_idc1; + +/* Define the union u_g3_ot_pp_csc_idc2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_idc2 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc_idc2; + +/* Define the union u_g3_ot_pp_csc_odc0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_odc0 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc_odc0; + +/* Define the union u_g3_ot_pp_csc_odc1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_odc1 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc_odc1; + +/* Define the union u_g3_ot_pp_csc_odc2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_odc2 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc_odc2; + +/* Define the union u_g3_ot_pp_csc_min_y */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_min_y : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc_min_y; + +/* Define the union u_g3_ot_pp_csc_min_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_min_c : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc_min_c; + +/* Define the union u_g3_ot_pp_csc_max_y */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_max_y : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc_max_y; + +/* Define the union u_g3_ot_pp_csc_max_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc_max_c : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc_max_c; + +/* Define the union u_g3_ot_pp_csc2_coef00 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef00 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc2_coef00; + +/* Define the union u_g3_ot_pp_csc2_coef01 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef01 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc2_coef01; + +/* Define the union u_g3_ot_pp_csc2_coef02 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef02 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc2_coef02; + +/* Define the union u_g3_ot_pp_csc2_coef10 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef10 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc2_coef10; + +/* Define the union u_g3_ot_pp_csc2_coef11 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef11 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc2_coef11; + +/* Define the union u_g3_ot_pp_csc2_coef12 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef12 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc2_coef12; + +/* Define the union u_g3_ot_pp_csc2_coef20 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef20 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc2_coef20; + +/* Define the union u_g3_ot_pp_csc2_coef21 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef21 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc2_coef21; + +/* Define the union u_g3_ot_pp_csc2_coef22 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_coef22 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc2_coef22; + +/* Define the union u_g3_ot_pp_csc2_scale */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_scale : 4; /* [3..0] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc2_scale; + +/* Define the union u_g3_ot_pp_csc2_idc0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_idc0 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc2_idc0; + +/* Define the union u_g3_ot_pp_csc2_idc1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_idc1 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc2_idc1; + +/* Define the union u_g3_ot_pp_csc2_idc2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_idc2 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc2_idc2; + +/* Define the union u_g3_ot_pp_csc2_odc0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_odc0 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc2_odc0; + +/* Define the union u_g3_ot_pp_csc2_odc1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_odc1 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc2_odc1; + +/* Define the union u_g3_ot_pp_csc2_odc2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_odc2 : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc2_odc2; + +/* Define the union u_g3_ot_pp_csc2_min_y */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_min_y : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc2_min_y; + +/* Define the union u_g3_ot_pp_csc2_min_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_min_c : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc2_min_c; + +/* Define the union u_g3_ot_pp_csc2_max_y */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_max_y : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc2_max_y; + +/* Define the union u_g3_ot_pp_csc2_max_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ot_pp_csc2_max_c : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc2_max_c; + +/* Define the union u_g3_ot_pp_csc_ink_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ink_en : 1; /* [0] */ + unsigned int ink_sel : 1; /* [1] */ + unsigned int data_fmt : 1; /* [2] */ + unsigned int cross_enable : 1; /* [3] */ + unsigned int color_mode : 2; /* [5..4] */ + unsigned int reserved_0 : 26; /* [31..6] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc_ink_ctrl; + +/* Define the union u_g3_ot_pp_csc_ink_pos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int x_pos : 16; /* [15..0] */ + unsigned int y_pos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_ot_pp_csc_ink_pos; + +/* define the union reg_osb_mute_bk */ +typedef union { + /* define the struct bits */ + struct { + unsigned int osb_bk_v : 10; /* [9..0] */ + unsigned int osb_bk_u : 10; /* [19..10] */ + unsigned int osb_bk_y : 10; /* [29..20] */ + unsigned int reserved_0 : 1; /* [30] */ + unsigned int osb_mute_en : 1; /* [31] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} u_osb_mute_bk; + +/* define the union reg_osb_bk_alpha */ +typedef union { + /* define the struct bits */ + struct { + unsigned int osb_bk_alpha : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} u_osb_bk_alpha; + +/* define the union reg_osb_coef_rd_en */ +typedef union { + /* define the struct bits */ + struct { + unsigned int osb_rd_en : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} u_osb_coef_rd_en; + +/* Define the union u_gp0_upd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int regup : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gp0_upd; + +/* Define the union u_gp0_ireso */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int iw : 16; /* [15..0] */ + unsigned int ih : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gp0_ireso; + +/* Define the union u_gp0_lbox_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mute_en : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gp0_lbox_ctrl; + +/* Define the union u_gp0_galpha */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int galpha : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gp0_galpha; + +/* Define the union u_gp0_dfpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int disp_xfpos : 12; /* [11..0] */ + unsigned int disp_yfpos : 12; /* [23..12] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gp0_dfpos; + +/* Define the union u_gp0_dlpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int disp_xlpos : 12; /* [11..0] */ + unsigned int disp_ylpos : 12; /* [23..12] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gp0_dlpos; + +/* Define the union u_gp0_vfpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int video_xfpos : 12; /* [11..0] */ + unsigned int video_yfpos : 12; /* [23..12] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gp0_vfpos; + +/* Define the union u_gp0_vlpos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int video_xlpos : 12; /* [11..0] */ + unsigned int video_ylpos : 12; /* [23..12] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gp0_vlpos; + +/* Define the union u_gp0_bk */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vbk_cr : 10; /* [9..0] */ + unsigned int vbk_cb : 10; /* [19..10] */ + unsigned int vbk_y : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gp0_bk; + +/* Define the union u_gp0_alpha */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vbk_alpha : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gp0_alpha; + +/* Define the union u_gp0_mute_bk */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mute_cr : 10; /* [9..0] */ + unsigned int mute_cb : 10; /* [19..10] */ + unsigned int mute_y : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gp0_mute_bk; + +/* Define the union u_gp0_csc_idc */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscidc0 : 11; /* [10..0] */ + unsigned int cscidc1 : 11; /* [21..11] */ + unsigned int csc_en : 1; /* [22] */ + unsigned int reserved_0 : 9; /* [31..23] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gp0_csc_idc; + +/* Define the union u_gp0_csc_odc */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscodc0 : 11; /* [10..0] */ + unsigned int cscodc1 : 11; /* [21..11] */ + unsigned int csc_sign_mode : 1; /* [22] */ + unsigned int reserved_0 : 9; /* [31..23] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gp0_csc_odc; + +/* Define the union u_gp0_csc_iodc */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscidc2 : 11; /* [10..0] */ + unsigned int cscodc2 : 11; /* [21..11] */ + unsigned int reserved_0 : 10; /* [31..22] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gp0_csc_iodc; + +/* Define the union u_gp0_csc_p0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp00 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp01 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gp0_csc_p0; + +/* Define the union u_gp0_csc_p1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp02 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp10 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gp0_csc_p1; + +/* Define the union u_gp0_csc_p2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp11 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp12 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gp0_csc_p2; + +/* Define the union u_gp0_csc_p3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp20 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp21 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gp0_csc_p3; + +/* Define the union u_gp0_csc_p4 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp22 : 15; /* [14..0] */ + unsigned int reserved_0 : 17; /* [31..15] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gp0_csc_p4; + +/* Define the union u_wbc_g0_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int req_interval : 10; /* [9..0] */ + unsigned int auto_stop_en : 1; /* [10] */ + unsigned int reserved_0 : 15; /* [25..11] */ + unsigned int format_out : 2; /* [27..26] */ + unsigned int reserved_1 : 3; /* [30..28] */ + unsigned int wbc_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_g0_ctrl; + +/* Define the union u_wbc_g0_upd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int regup : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_g0_upd; + +/* Define the union u_wbc_g0_cmp */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cmp_lossy_en : 1; /* [0] */ + unsigned int reserved_0 : 3; /* [3..1] */ + unsigned int cmp_drr : 4; /* [7..4] */ + unsigned int reserved_1 : 23; /* [30..8] */ + unsigned int cmp_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_g0_cmp; + +/* Define the union u_wbc_g0_stride */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int wbcstride : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_g0_stride; + +/* Define the union u_wbc_g0_oreso */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ow : 12; /* [11..0] */ + unsigned int oh : 12; /* [23..12] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_g0_oreso; + +/* Define the union u_wbc_g0_fcrop */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int wfcrop : 12; /* [11..0] */ + unsigned int hfcrop : 12; /* [23..12] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_g0_fcrop; + +/* Define the union u_wbc_g0_lcrop */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int wlcrop : 12; /* [11..0] */ + unsigned int hlcrop : 12; /* [23..12] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_g0_lcrop; + +/* Define the union u_wbc_gp0_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int req_interval : 10; /* [9..0] */ + unsigned int auto_stop_en : 1; /* [10] */ + unsigned int reserved_0 : 1; /* [11] */ + unsigned int wbc_vtthd_mode : 1; /* [12] */ + unsigned int reserved_1 : 5; /* [17..13] */ + unsigned int three_d_mode : 2; /* [19..18] */ + unsigned int reserved_2 : 3; /* [22..20] */ + unsigned int flip_en : 1; /* [23] */ + unsigned int format_out : 4; /* [27..24] */ + unsigned int mode_out : 2; /* [29..28] */ + unsigned int reserved_3 : 1; /* [30] */ + unsigned int wbc_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_gp0_ctrl; + +/* Define the union u_wbc_gp0_upd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int regup : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_gp0_upd; + +/* Define the union u_wbc_gp0_stride */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int wbclstride : 16; /* [15..0] */ + unsigned int wbccstride : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_gp0_stride; + +/* Define the union u_wbc_gp0_oreso */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ow : 12; /* [11..0] */ + unsigned int oh : 12; /* [23..12] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_gp0_oreso; + +/* Define the union u_wbc_gp0_fcrop */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int wfcrop : 12; /* [11..0] */ + unsigned int hfcrop : 12; /* [23..12] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_gp0_fcrop; + +/* Define the union u_wbc_gp0_lcrop */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int wlcrop : 12; /* [11..0] */ + unsigned int hlcrop : 12; /* [23..12] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_gp0_lcrop; + +/* Define the union u_wbc_gp0_dither_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 29; /* [28..0] */ + unsigned int dither_round : 1; /* [29] */ + unsigned int dither_mode : 1; /* [30] */ + unsigned int dither_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_gp0_dither_ctrl; + +/* Define the union u_wbc_gp0_dither_coef0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_coef0 : 8; /* [7..0] */ + unsigned int dither_coef1 : 8; /* [15..8] */ + unsigned int dither_coef2 : 8; /* [23..16] */ + unsigned int dither_coef3 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_gp0_dither_coef0; + +/* Define the union u_wbc_gp0_dither_coef1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_coef4 : 8; /* [7..0] */ + unsigned int dither_coef5 : 8; /* [15..8] */ + unsigned int dither_coef6 : 8; /* [23..16] */ + unsigned int dither_coef7 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_gp0_dither_coef1; + +/* Define the union u_wbc_gp0_hpzme */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 29; /* [28..0] */ + unsigned int hpzme_mode : 1; /* [29] */ + unsigned int hpzme_mid_en : 1; /* [30] */ + unsigned int hpzme_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_gp0_hpzme; + +/* Define the union u_wbc_me_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int req_interval : 10; /* [9..0] */ + unsigned int reserved_0 : 10; /* [19..10] */ + unsigned int ofl_master : 1; /* [20] */ + unsigned int reserved_1 : 2; /* [22..21] */ + unsigned int mad_data_mode : 1; /* [23] */ + unsigned int format_out : 4; /* [27..24] */ + unsigned int reserved_2 : 1; /* [28] */ + unsigned int c_wbc_en : 1; /* [29] */ + unsigned int reserved_3 : 1; /* [30] */ + unsigned int wbc_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_me_ctrl; + +/* Define the union u_wbc_me_upd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int regup : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_me_upd; + +/* Define the union u_wbc_me_wlen_sel */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int wlen_sel : 2; /* [1..0] */ + unsigned int reserved_0 : 30; /* [31..2] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_me_wlen_sel; + +/* Define the union u_wbc_me_stride */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int wbclstride : 16; /* [15..0] */ + unsigned int wbccstride : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_me_stride; + +/* Define the union u_wbc_me_oreso */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ow : 12; /* [11..0] */ + unsigned int oh : 12; /* [23..12] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_me_oreso; + +/* Define the union u_wbc_me_smmu_bypass */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int l_bypass : 1; /* [0] */ + unsigned int c_bypass : 1; /* [1] */ + unsigned int reserved_0 : 30; /* [31..2] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_me_smmu_bypass; + +/* Define the union u_wbc_me_paraup */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int wbc_hlcoef_upd : 1; /* [0] */ + unsigned int wbc_hccoef_upd : 1; /* [1] */ + unsigned int wbc_vlcoef_upd : 1; /* [2] */ + unsigned int wbc_vccoef_upd : 1; /* [3] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_me_paraup; + +/* Define the union u_wbc_me_dither_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 29; /* [28..0] */ + unsigned int dither_round : 1; /* [29] */ + unsigned int dither_mode : 1; /* [30] */ + unsigned int dither_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_me_dither_ctrl; + +/* Define the union u_wbc_me_dither_coef0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_coef0 : 8; /* [7..0] */ + unsigned int dither_coef1 : 8; /* [15..8] */ + unsigned int dither_coef2 : 8; /* [23..16] */ + unsigned int dither_coef3 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_me_dither_coef0; + +/* Define the union u_wbc_me_dither_coef1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_coef4 : 8; /* [7..0] */ + unsigned int dither_coef5 : 8; /* [15..8] */ + unsigned int dither_coef6 : 8; /* [23..16] */ + unsigned int dither_coef7 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_me_dither_coef1; + +/* Define the union u_wbc_me_zme_hsp */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hratio : 24; /* [23..0] */ + unsigned int hfir_order : 1; /* [24] */ + unsigned int hchfir_en : 1; /* [25] */ + unsigned int hlfir_en : 1; /* [26] */ + unsigned int reserved_0 : 1; /* [27] */ + unsigned int hchmid_en : 1; /* [28] */ + unsigned int hlmid_en : 1; /* [29] */ + unsigned int hchmsc_en : 1; /* [30] */ + unsigned int hlmsc_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_me_zme_hsp; + +/* Define the union u_wbc_me_zme_hloffset */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hor_loffset : 28; /* [27..0] */ + unsigned int reserved_0 : 4; /* [31..28] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_me_zme_hloffset; + +/* Define the union u_wbc_me_zme_hcoffset */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hor_coffset : 28; /* [27..0] */ + unsigned int reserved_0 : 4; /* [31..28] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_me_zme_hcoffset; + +/* Define the union u_wbc_me_zme_vsp */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 19; /* [18..0] */ + unsigned int zme_in_fmt : 2; /* [20..19] */ + unsigned int zme_out_fmt : 2; /* [22..21] */ + unsigned int vchfir_en : 1; /* [23] */ + unsigned int vlfir_en : 1; /* [24] */ + unsigned int reserved_1 : 3; /* [27..25] */ + unsigned int vchmid_en : 1; /* [28] */ + unsigned int vlmid_en : 1; /* [29] */ + unsigned int vchmsc_en : 1; /* [30] */ + unsigned int vlmsc_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_me_zme_vsp; + +/* Define the union u_wbc_me_zme_vsr */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vratio : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_me_zme_vsr; + +/* Define the union u_wbc_me_zme_voffset */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vchroma_offset : 16; /* [15..0] */ + unsigned int vluma_offset : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_me_zme_voffset; + +/* Define the union u_wbc_me_zme_vboffset */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vbchroma_offset : 16; /* [15..0] */ + unsigned int vbluma_offset : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_me_zme_vboffset; + +/* Define the union u_wbc_fi_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int req_interval : 10; /* [9..0] */ + unsigned int reserved_0 : 3; /* [12..10] */ + unsigned int addr_mode : 1; /* [13] */ + unsigned int fsize_mode : 1; /* [14] */ + unsigned int tnr_nrds_en : 1; /* [15] */ + unsigned int reserved_1 : 4; /* [19..16] */ + unsigned int ofl_master : 1; /* [20] */ + unsigned int data_width : 1; /* [21] */ + unsigned int reserved_2 : 2; /* [23..22] */ + unsigned int format_out : 4; /* [27..24] */ + unsigned int reserved_3 : 2; /* [29..28] */ + unsigned int cmp_en : 1; /* [30] */ + unsigned int wbc_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_fi_ctrl; + +/* Define the union u_wbc_fi_upd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int regup : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_fi_upd; + +/* Define the union u_wbc_fi_wlen_sel */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int wlen_sel : 2; /* [1..0] */ + unsigned int reserved_0 : 30; /* [31..2] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_fi_wlen_sel; + +/* Define the union u_wbc_fi_stride */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int wbclstride : 16; /* [15..0] */ + unsigned int wbccstride : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_fi_stride; + +/* Define the union u_wbc_fi_oreso */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ow : 12; /* [11..0] */ + unsigned int oh : 12; /* [23..12] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_fi_oreso; + +/* Define the union u_wbc_fi_smmu_bypass */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int l_bypass : 1; /* [0] */ + unsigned int c_bypass : 1; /* [1] */ + unsigned int reserved_0 : 30; /* [31..2] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_fi_smmu_bypass; + +/* Define the union u_wbc_fi_frame_size */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int frame_size : 23; /* [22..0] */ + unsigned int reserved_0 : 9; /* [31..23] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_fi_frame_size; + +/* Define the union u_wbc_fi_hcds */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 29; /* [28..0] */ + unsigned int hchfir_en : 1; /* [29] */ + unsigned int hchmid_en : 1; /* [30] */ + unsigned int hcds_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_fi_hcds; + +/* Define the union u_wbc_fi_hcds_coef0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int coef0 : 10; /* [9..0] */ + unsigned int coef1 : 10; /* [19..10] */ + unsigned int coef2 : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_fi_hcds_coef0; + +/* Define the union u_wbc_fi_hcds_coef1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int coef3 : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_fi_hcds_coef1; + +/* Define the union u_wbc_fi_cmp_mb */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mb_bits : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_fi_cmp_mb; + +/* Define the union u_wbc_fi_cmp_max_min */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int min_bits_cnt : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int max_bits_cnt : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_fi_cmp_max_min; + +/* Define the union u_wbc_fi_cmp_adj_thr */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int adj_sad_thr : 12; /* [11..0] */ + unsigned int reserved_0 : 4; /* [15..12] */ + unsigned int adj_sad_bit_thr : 8; /* [23..16] */ + unsigned int adj_spec_bit_thr : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_fi_cmp_adj_thr; + +/* Define the union u_wbc_fi_cmp_big_grad */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int big_grad_thr : 7; /* [6..0] */ + unsigned int reserved_0 : 1; /* [7] */ + unsigned int big_grad_num_thr : 5; /* [12..8] */ + unsigned int reserved_1 : 19; /* [31..13] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_fi_cmp_big_grad; + +/* Define the union u_wbc_fi_cmp_blk */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int smth_thr : 6; /* [5..0] */ + unsigned int reserved_0 : 2; /* [7..6] */ + unsigned int blk_comp_thr : 3; /* [10..8] */ + unsigned int reserved_1 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_fi_cmp_blk; + +/* Define the union u_wbc_fi_cmp_graphic_judge */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int graphic_en : 1; /* [0] */ + unsigned int reserved_0 : 15; /* [15..1] */ + unsigned int video_sad_thr : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_fi_cmp_graphic_judge; + +/* Define the union u_wbc_fi_cmp_rc */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int sadbits_ngain : 3; /* [2..0] */ + unsigned int reserved_0 : 5; /* [7..3] */ + unsigned int rc_smth_gain : 3; /* [10..8] */ + unsigned int reserved_1 : 5; /* [15..11] */ + unsigned int max_trow_bits : 6; /* [21..16] */ + unsigned int reserved_2 : 10; /* [31..22] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_fi_cmp_rc; + +/* Define the union u_wbc_fi_cmp_frame_size */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int frame_size : 21; /* [20..0] */ + unsigned int reserved_0 : 11; /* [31..21] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_fi_cmp_frame_size; + +/* Define the union u_wbc_cmp_glb_info */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int is_lossless : 1; /* [0] */ + unsigned int cmp_mode : 1; /* [1] */ + unsigned int dw_mode : 1; /* [2] */ + unsigned int sep_cmp_en : 1; /* [3] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_cmp_glb_info; + +/* Define the union u_wbc_cmp_framesize */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int frame_width : 13; /* [12..0] */ + unsigned int reserved_0 : 3; /* [15..13] */ + unsigned int frame_height : 13; /* [28..16] */ + unsigned int reserved_1 : 3; /* [31..29] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_cmp_framesize; + +/* Define the union u_wbc_cmp_rc_cfg0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mb_bits_y : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int min_mb_bits_y : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_cmp_rc_cfg0; + +/* Define the union u_wbc_cmp_rc_cfg2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int max_qp_y : 4; /* [3..0] */ + unsigned int reserved_0 : 4; /* [7..4] */ + unsigned int sad_bits_ngain : 4; /* [11..8] */ + unsigned int reserved_1 : 4; /* [15..12] */ + unsigned int rc_smth_ngain : 3; /* [18..16] */ + unsigned int reserved_2 : 5; /* [23..19] */ + unsigned int max_trow_bits : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_cmp_rc_cfg2; + +/* Define the union u_wbc_cmp_rc_cfg3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int max_sad_thr : 7; /* [6..0] */ + unsigned int reserved_0 : 9; /* [15..7] */ + unsigned int min_sad_thr : 7; /* [22..16] */ + unsigned int reserved_1 : 9; /* [31..23] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_cmp_rc_cfg3; + +/* Define the union u_wbc_cmp_rc_cfg4 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int smth_thr : 7; /* [6..0] */ + unsigned int reserved_0 : 1; /* [7] */ + unsigned int still_thr : 7; /* [14..8] */ + unsigned int reserved_1 : 1; /* [15] */ + unsigned int big_grad_thr : 10; /* [25..16] */ + unsigned int reserved_2 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_cmp_rc_cfg4; + +/* Define the union u_wbc_cmp_rc_cfg5 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int smth_pix_num_thr : 6; /* [5..0] */ + unsigned int reserved_0 : 2; /* [7..6] */ + unsigned int still_pix_num_thr : 6; /* [13..8] */ + unsigned int reserved_1 : 2; /* [15..14] */ + unsigned int noise_pix_num_thr : 6; /* [21..16] */ + unsigned int reserved_2 : 10; /* [31..22] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_cmp_rc_cfg5; + +/* Define the union u_wbc_cmp_rc_cfg6 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int noise_sad : 7; /* [6..0] */ + unsigned int reserved_0 : 9; /* [15..7] */ + unsigned int pix_diff_thr : 9; /* [24..16] */ + unsigned int reserved_1 : 7; /* [31..25] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_cmp_rc_cfg6; + +/* Define the union u_wbc_cmp_rc_cfg7 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int adj_sad_bits_thr : 7; /* [6..0] */ + unsigned int reserved_0 : 25; /* [31..7] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_cmp_rc_cfg7; + +/* Define the union u_wbc_cmp_rc_cfg8 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int qp_inc1_bits_thr_y : 8; /* [7..0] */ + unsigned int qp_inc2_bits_thr_y : 8; /* [15..8] */ + unsigned int qp_dec1_bits_thr_y : 8; /* [23..16] */ + unsigned int qp_dec2_bits_thr_y : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_cmp_rc_cfg8; + +/* Define the union u_wbc_cmp_rc_cfg10 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int est_err_gain : 5; /* [4..0] */ + unsigned int reserved_0 : 11; /* [15..5] */ + unsigned int max_est_err_level : 9; /* [24..16] */ + unsigned int max_vbv_buf_loss_thr : 7; /* [31..25] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_cmp_rc_cfg10; + +/* Define the union u_wbc_cmp_outsize0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int frame_size0_reg : 22; /* [21..0] */ + unsigned int reserved_0 : 10; /* [31..22] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_cmp_outsize0; + +/* Define the union u_wbc_cmp_max_row */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int frame_size1_reg : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_cmp_max_row; + +/* Define the union u_wbc_bmp_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int req_interval : 10; /* [9..0] */ + unsigned int reserved_0 : 10; /* [19..10] */ + unsigned int ofl_master : 1; /* [20] */ + unsigned int data_width : 1; /* [21] */ + unsigned int reserved_1 : 2; /* [23..22] */ + unsigned int format_out : 4; /* [27..24] */ + unsigned int reserved_2 : 3; /* [30..28] */ + unsigned int wbc_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_bmp_ctrl; + +/* Define the union u_wbc_bmp_upd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int regup : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_bmp_upd; + +/* Define the union u_wbc_bmp_oreso */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ow : 12; /* [11..0] */ + unsigned int oh : 12; /* [23..12] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_bmp_oreso; + +/* Define the union u_wbc_bmp_sum */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int bmp_sum : 25; /* [24..0] */ + unsigned int reserved_0 : 7; /* [31..25] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_bmp_sum; + +/* Define the union u_wbc_dhd0_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int p2i_en : 1; /* [0] */ + unsigned int root_path : 2; /* [2..1] */ + unsigned int reserved_0 : 19; /* [21..3] */ + unsigned int mode_out : 2; /* [23..22] */ + unsigned int three_d_mode : 2; /* [25..24] */ + unsigned int auto_stop_en : 1; /* [26] */ + unsigned int wbc_vtthd_mode : 1; /* [27] */ + unsigned int rupd_field : 1; /* [28] */ + unsigned int rgup_mode : 1; /* [29] */ + unsigned int nosec_flag : 1; /* [30] */ + unsigned int wbc_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_dhd0_ctrl; + +/* Define the union u_wbc_dhd0_upd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int regup : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_dhd0_upd; + +/* Define the union u_wbc_dhd0_oreso */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ow : 16; /* [15..0] */ + unsigned int oh : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_dhd0_oreso; + +/* Define the union u_wd_hpzme_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hfir_en : 1; /* [0] */ + unsigned int hfir_mode : 2; /* [2..1] */ + unsigned int mid_en : 1; /* [3] */ + unsigned int ck_gt_en : 1; /* [4] */ + unsigned int reserved_0 : 27; /* [31..5] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wd_hpzme_ctrl; + +/* Define the union u_wd_hpzmecoef01 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 10; /* [9..0] */ + unsigned int reserved_1 : 6; /* [15..10] */ + unsigned int reserved_2 : 10; /* [25..16] */ + unsigned int reserved_3 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wd_hpzmecoef01; + +/* Define the union u_wd_hpzmecoef23 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 10; /* [9..0] */ + unsigned int reserved_1 : 6; /* [15..10] */ + unsigned int reserved_2 : 10; /* [25..16] */ + unsigned int reserved_3 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wd_hpzmecoef23; + +/* Define the union u_wd_hpzmecoef45 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 10; /* [9..0] */ + unsigned int reserved_1 : 6; /* [15..10] */ + unsigned int reserved_2 : 10; /* [25..16] */ + unsigned int reserved_3 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wd_hpzmecoef45; + +/* Define the union u_wd_hpzmecoef67 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 10; /* [9..0] */ + unsigned int reserved_1 : 6; /* [15..10] */ + unsigned int reserved_2 : 10; /* [25..16] */ + unsigned int reserved_3 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wd_hpzmecoef67; + +/* Define the union u_wd_hcds_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hfir_en : 1; /* [0] */ + unsigned int hfir_mode : 2; /* [2..1] */ + unsigned int mid_en : 1; /* [3] */ + unsigned int ck_gt_en : 1; /* [4] */ + unsigned int reserved_0 : 27; /* [31..5] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wd_hcds_ctrl; + +/* Define the union u_wd_hcdscoef01 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int coef0 : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int coef1 : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wd_hcdscoef01; + +/* Define the union u_wd_hcdscoef23 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int coef2 : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int coef3 : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wd_hcdscoef23; + +/* Define the union u_wd_hcdscoef45 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 10; /* [9..0] */ + unsigned int reserved_1 : 6; /* [15..10] */ + unsigned int reserved_2 : 10; /* [25..16] */ + unsigned int reserved_3 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wd_hcdscoef45; + +/* Define the union u_wd_hcdscoef67 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 10; /* [9..0] */ + unsigned int reserved_1 : 6; /* [15..10] */ + unsigned int reserved_2 : 10; /* [25..16] */ + unsigned int reserved_3 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wd_hcdscoef67; + +/* Define the union u_dither_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_tap_mode : 2; /* [1..0] */ + unsigned int dither_domain_mode : 1; /* [2] */ + unsigned int dither_round : 1; /* [3] */ + unsigned int dither_mode : 1; /* [4] */ + unsigned int dither_en : 1; /* [5] */ + unsigned int dither_round_unlim : 1; /* [6] */ + unsigned int i_data_width_dither : 3; /* [9..7] */ + unsigned int o_data_width_dither : 3; /* [12..10] */ + unsigned int reserved_0 : 19; /* [31..13] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dither_ctrl; + +/* Define the union u_dither_sed_y0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_y0 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dither_sed_y0; + +/* Define the union u_dither_sed_u0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_u0 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dither_sed_u0; + +/* Define the union u_dither_sed_v0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_v0 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dither_sed_v0; + +/* Define the union u_dither_sed_w0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_w0 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dither_sed_w0; + +/* Define the union u_dither_sed_y1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_y1 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dither_sed_y1; + +/* Define the union u_dither_sed_u1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_u1 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dither_sed_u1; + +/* Define the union u_dither_sed_v1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_v1 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dither_sed_v1; + +/* Define the union u_dither_sed_w1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_w1 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dither_sed_w1; + +/* Define the union u_dither_sed_y2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_y2 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dither_sed_y2; + +/* Define the union u_dither_sed_u2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_u2 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dither_sed_u2; + +/* Define the union u_dither_sed_v2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_v2 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dither_sed_v2; + +/* Define the union u_dither_sed_w2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_w2 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dither_sed_w2; + +/* Define the union u_dither_sed_y3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_y3 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dither_sed_y3; + +/* Define the union u_dither_sed_u3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_u3 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dither_sed_u3; + +/* Define the union u_dither_sed_v3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_v3 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dither_sed_v3; + +/* Define the union u_dither_sed_w3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_w3 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dither_sed_w3; + +/* Define the union u_dither_thr */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_thr_min : 16; /* [15..0] */ + unsigned int dither_thr_max : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dither_thr; + +/* Define the union u_wd_zme_hinfo */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int out_width : 16; /* [15..0] */ + unsigned int hzme_ck_gt_en : 1; /* [16] */ + unsigned int reserved_0 : 15; /* [31..17] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wd_zme_hinfo; + +/* Define the union u_wd_zme_hsp */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 24; /* [23..0] */ + unsigned int hfir_order : 1; /* [24] */ + unsigned int chfir_mode : 1; /* [25] */ + unsigned int lhfir_mode : 1; /* [26] */ + unsigned int non_lnr_en : 1; /* [27] */ + unsigned int chmid_en : 1; /* [28] */ + unsigned int lhmid_en : 1; /* [29] */ + unsigned int chfir_en : 1; /* [30] */ + unsigned int lhfir_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wd_zme_hsp; + +/* Define the union u_wd_zme_hloffset */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int lhfir_offset : 28; /* [27..0] */ + unsigned int reserved_0 : 4; /* [31..28] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wd_zme_hloffset; + +/* Define the union u_wd_zme_hcoffset */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int chfir_offset : 28; /* [27..0] */ + unsigned int reserved_0 : 4; /* [31..28] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wd_zme_hcoffset; + +/* Define the union u_wd_zme_hcoef_ren */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int apb_vhd_hf_cren : 1; /* [0] */ + unsigned int apb_vhd_hf_lren : 1; /* [1] */ + unsigned int reserved_0 : 30; /* [31..2] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wd_zme_hcoef_ren; + +/* Define the union u_wd_zme_hcoef_rdata */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int apb_vhd_hcoef_raddr : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wd_zme_hcoef_rdata; + +/* Define the union u_wd_zme_hdraw */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hdraw_mode : 2; /* [1..0] */ + unsigned int reserved_0 : 30; /* [31..2] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wd_zme_hdraw; + +/* Define the union u_wd_zme_hratio */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hratio : 27; /* [26..0] */ + unsigned int reserved_0 : 5; /* [31..27] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wd_zme_hratio; + +/* Define the union u_wd_zme_vinfo */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int out_height : 16; /* [15..0] */ + unsigned int out_fmt : 2; /* [17..16] */ + unsigned int out_pro : 1; /* [18] */ + unsigned int vzme_ck_gt_en : 1; /* [19] */ + unsigned int reserved_0 : 12; /* [31..20] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wd_zme_vinfo; + +/* Define the union u_wd_zme_vsp */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 16; /* [15..0] */ + unsigned int graphdet_en : 1; /* [16] */ + unsigned int reserved_1 : 8; /* [24..17] */ + unsigned int cvfir_mode : 1; /* [25] */ + unsigned int lvfir_mode : 1; /* [26] */ + unsigned int vfir_1tap_en : 1; /* [27] */ + unsigned int cvmid_en : 1; /* [28] */ + unsigned int lvmid_en : 1; /* [29] */ + unsigned int cvfir_en : 1; /* [30] */ + unsigned int lvfir_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wd_zme_vsp; + +/* Define the union u_wd_zme_voffset */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vchroma_offset : 16; /* [15..0] */ + unsigned int vluma_offset : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wd_zme_voffset; + +/* Define the union u_wd_zme_vboffset */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vbchroma_offset : 16; /* [15..0] */ + unsigned int vbluma_offset : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wd_zme_vboffset; + +/* Define the union u_wd_zme_vcoef_ren */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int apb_vhd_vf_cren : 1; /* [0] */ + unsigned int apb_vhd_vf_lren : 1; /* [1] */ + unsigned int reserved_0 : 30; /* [31..2] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wd_zme_vcoef_ren; + +/* Define the union u_wd_zme_vcoef_rdata */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int apb_vhd_vcoef_raddr : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wd_zme_vcoef_rdata; + +/* Define the union u_wd_zme_vdraw */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vdraw_mode : 2; /* [1..0] */ + unsigned int reserved_0 : 30; /* [31..2] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wd_zme_vdraw; + +/* Define the union u_wd_zme_vratio */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vratio : 19; /* [18..0] */ + unsigned int reserved_0 : 13; /* [31..19] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wd_zme_vratio; + +/* Define the union u_dhd0_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int regup : 1; /* [0] */ + unsigned int disp_mode : 3; /* [3..1] */ + unsigned int iop : 1; /* [4] */ + unsigned int intf_ivs : 1; /* [5] */ + unsigned int intf_ihs : 1; /* [6] */ + unsigned int intf_idv : 1; /* [7] */ + unsigned int reserved_0 : 1; /* [8] */ + unsigned int hdmi420c_sel : 1; /* [9] */ + unsigned int hdmi420_en : 1; /* [10] */ + unsigned int uf_offline_en : 1; /* [11] */ + unsigned int reserved_1 : 2; /* [13..12] */ + unsigned int hdmi_mode : 1; /* [14] */ + unsigned int twochn_debug : 1; /* [15] */ + unsigned int twochn_en : 1; /* [16] */ + unsigned int reserved_2 : 1; /* [17] */ + unsigned int cbar_mode : 1; /* [18] */ + unsigned int sin_en : 1; /* [19] */ + unsigned int fpga_lmt_width : 7; /* [26..20] */ + unsigned int fpga_lmt_en : 1; /* [27] */ + unsigned int p2i_en : 1; /* [28] */ + unsigned int cbar_sel : 1; /* [29] */ + unsigned int cbar_en : 1; /* [30] */ + unsigned int intf_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd0_ctrl; + +/* Define the union u_dhd0_vsync1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vact : 16; /* [15..0] */ + unsigned int vbb : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd0_vsync1; + +/* Define the union u_dhd0_vsync2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vfb : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd0_vsync2; + +/* Define the union u_dhd0_hsync1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hact : 16; /* [15..0] */ + unsigned int hbb : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd0_hsync1; + +/* Define the union u_dhd0_hsync2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hfb : 16; /* [15..0] */ + unsigned int hmid : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd0_hsync2; + +/* Define the union u_dhd0_vplus1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int bvact : 16; /* [15..0] */ + unsigned int bvbb : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd0_vplus1; + +/* Define the union u_dhd0_vplus2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int bvfb : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd0_vplus2; + +/* Define the union u_dhd0_pwr */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hpw : 16; /* [15..0] */ + unsigned int vpw : 8; /* [23..16] */ + unsigned int reserved_0 : 3; /* [26..24] */ + unsigned int multichn_en : 2; /* [28..27] */ + unsigned int reserved_1 : 3; /* [31..29] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd0_pwr; + +/* Define the union u_dhd0_vtthd3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vtmgthd3 : 13; /* [12..0] */ + unsigned int reserved_0 : 2; /* [14..13] */ + unsigned int thd3_mode : 1; /* [15] */ + unsigned int vtmgthd4 : 13; /* [28..16] */ + unsigned int reserved_1 : 2; /* [30..29] */ + unsigned int thd4_mode : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd0_vtthd3; + +/* Define the union u_dhd0_vtthd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vtmgthd1 : 13; /* [12..0] */ + unsigned int reserved_0 : 2; /* [14..13] */ + unsigned int thd1_mode : 1; /* [15] */ + unsigned int vtmgthd2 : 13; /* [28..16] */ + unsigned int reserved_1 : 2; /* [30..29] */ + unsigned int thd2_mode : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd0_vtthd; + +/* Define the union u_dhd0_parathd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int para_thd : 8; /* [7..0] */ + unsigned int reserved_0 : 23; /* [30..8] */ + unsigned int dfs_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd0_parathd; + +/* Define the union u_dhd0_precharge_thd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int tcon_precharge_thd : 17; /* [16..0] */ + unsigned int reserved_0 : 3; /* [19..17] */ + unsigned int vsync_te_mode : 1; /* [20] */ + unsigned int reserved_1 : 11; /* [31..21] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd0_precharge_thd; + +/* Define the union u_dhd0_start_pos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int start_pos : 8; /* [7..0] */ + unsigned int timing_start_pos : 8; /* [15..8] */ + unsigned int fi_start_pos : 4; /* [19..16] */ + unsigned int req_start_pos : 12; /* [31..20] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd0_start_pos; + +/* Define the union u_dhd0_start_pos1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int req_start_pos1 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd0_start_pos1; + +/* Define the union u_dhd0_paraup */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 31; /* [30..0] */ + unsigned int paraup_mode : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd0_paraup; + +/* Define the union u_dhd0_sync_inv */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int lcd_dv_inv : 1; /* [0] */ + unsigned int lcd_hs_inv : 1; /* [1] */ + unsigned int lcd_vs_inv : 1; /* [2] */ + unsigned int reserved_0 : 1; /* [3] */ + unsigned int vga_dv_inv : 1; /* [4] */ + unsigned int vga_hs_inv : 1; /* [5] */ + unsigned int vga_vs_inv : 1; /* [6] */ + unsigned int reserved_1 : 1; /* [7] */ + unsigned int hdmi_dv_inv : 1; /* [8] */ + unsigned int hdmi_hs_inv : 1; /* [9] */ + unsigned int hdmi_vs_inv : 1; /* [10] */ + unsigned int hdmi_f_inv : 1; /* [11] */ + unsigned int date_dv_inv : 1; /* [12] */ + unsigned int date_hs_inv : 1; /* [13] */ + unsigned int date_vs_inv : 1; /* [14] */ + unsigned int date_f_inv : 1; /* [15] */ + unsigned int reserved_2 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd0_sync_inv; + +/* Define the union u_dhd0_clk_dv_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int intf_clk_mux : 1; /* [0] */ + unsigned int intf_dv_mux : 1; /* [1] */ + unsigned int no_active_area_pos : 16; /* [17..2] */ + unsigned int reserved_0 : 14; /* [31..18] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd0_clk_dv_ctrl; + +/* Define the union u_dhd0_rgb_fix_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int fix_b : 10; /* [9..0] */ + unsigned int fix_g : 10; /* [19..10] */ + unsigned int fix_r : 10; /* [29..20] */ + unsigned int rgb_fix_mux : 1; /* [30] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd0_rgb_fix_ctrl; + +/* Define the union u_dhd0_lockcfg */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int measure_en : 1; /* [0] */ + unsigned int lock_cnt_en : 1; /* [1] */ + unsigned int vdp_measure_en : 1; /* [2] */ + unsigned int reserved_0 : 29; /* [31..3] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd0_lockcfg; + +/* Define the union u_dhd0_intf_chksum_high1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int r0_sum_high : 8; /* [7..0] */ + unsigned int g0_sum_high : 8; /* [15..8] */ + unsigned int b0_sum_high : 8; /* [23..16] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd0_intf_chksum_high1; + +/* Define the union u_dhd0_intf_chksum_high2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int r1_sum_high : 8; /* [7..0] */ + unsigned int g1_sum_high : 8; /* [15..8] */ + unsigned int b1_sum_high : 8; /* [23..16] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd0_intf_chksum_high2; + +/* Define the union u_dhd0_state */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vback_blank : 1; /* [0] */ + unsigned int vblank : 1; /* [1] */ + unsigned int bottom_field : 1; /* [2] */ + unsigned int vcnt : 13; /* [15..3] */ + unsigned int count_int : 8; /* [23..16] */ + unsigned int dhd_even : 1; /* [24] */ + unsigned int reserved_0 : 7; /* [31..25] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd0_state; + +/* Define the union u_dhd0_uf_state */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ud_first_cnt : 13; /* [12..0] */ + unsigned int reserved_0 : 3; /* [15..13] */ + unsigned int start_pos : 8; /* [23..16] */ + unsigned int reserved_1 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd0_uf_state; + +/* Define the union u_vo_mux */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mipi_sel : 4; /* [3..0] */ + unsigned int lcd_sel : 4; /* [7..4] */ + unsigned int bt_sel : 4; /* [11..8] */ + unsigned int sddate_sel : 4; /* [15..12] */ + unsigned int hdmi_sel : 4; /* [19..16] */ + unsigned int hdmi1_sel : 4; /* [23..20] */ + unsigned int vga_sel : 4; /* [27..24] */ + unsigned int digital_sel : 4; /* [31..28] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vo_mux; + +/* Define the union u_vo_mux_sync */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int sync_dv : 1; /* [0] */ + unsigned int sync_hsync : 1; /* [1] */ + unsigned int sync_vsync : 1; /* [2] */ + unsigned int sync_field : 1; /* [3] */ + unsigned int reserved_0 : 27; /* [30..4] */ + unsigned int sync_test_mode : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vo_mux_sync; + +/* Define the union u_vo_mux_data */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vomux_data : 30; /* [29..0] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vo_mux_data; + +/* Define the union u_dhd0_vsync_te_state */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vsync_te_start_sta : 8; /* [7..0] */ + unsigned int vsync_te_start_sta1 : 8; /* [15..8] */ + unsigned int vsync_te_end_sta : 8; /* [23..16] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd0_vsync_te_state; + +/* Define the union u_dhd0_vsync_te_state1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vsync_te_vfb : 16; /* [15..0] */ + unsigned int vsync_te_width : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd0_vsync_te_state1; + +/* Define the union u_dhd0_ccdoimgmod */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int img_mode : 7; /* [6..0] */ + unsigned int img_right : 1; /* [7] */ + unsigned int img_id : 2; /* [9..8] */ + unsigned int slave_mode : 1; /* [10] */ + unsigned int ccd_en : 1; /* [11] */ + unsigned int reserved_0 : 4; /* [15..12] */ + unsigned int vbi_pos : 8; /* [23..16] */ + unsigned int reserved_1 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd0_ccdoimgmod; + +/* Define the union u_dhd0_ccdoposmskh */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int p32_en : 1; /* [0] */ + unsigned int p33_en : 1; /* [1] */ + unsigned int p34_en : 1; /* [2] */ + unsigned int p35_en : 1; /* [3] */ + unsigned int p36_en : 1; /* [4] */ + unsigned int p37_en : 1; /* [5] */ + unsigned int p38_en : 1; /* [6] */ + unsigned int p39_en : 1; /* [7] */ + unsigned int p40_en : 1; /* [8] */ + unsigned int p41_en : 1; /* [9] */ + unsigned int p42_en : 1; /* [10] */ + unsigned int p43_en : 1; /* [11] */ + unsigned int p44_en : 1; /* [12] */ + unsigned int p45_en : 1; /* [13] */ + unsigned int p46_en : 1; /* [14] */ + unsigned int p47_en : 1; /* [15] */ + unsigned int p48_en : 1; /* [16] */ + unsigned int p49_en : 1; /* [17] */ + unsigned int p50_en : 1; /* [18] */ + unsigned int p51_en : 1; /* [19] */ + unsigned int p52_en : 1; /* [20] */ + unsigned int p53_en : 1; /* [21] */ + unsigned int p54_en : 1; /* [22] */ + unsigned int p55_en : 1; /* [23] */ + unsigned int p56_en : 1; /* [24] */ + unsigned int p57_en : 1; /* [25] */ + unsigned int p58_en : 1; /* [26] */ + unsigned int p59_en : 1; /* [27] */ + unsigned int p60_en : 1; /* [28] */ + unsigned int p61_en : 1; /* [29] */ + unsigned int p62_en : 1; /* [30] */ + unsigned int p63_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd0_ccdoposmskh; + +/* Define the union u_dhd0_ccdoposmskl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int p0_en : 1; /* [0] */ + unsigned int p1_en : 1; /* [1] */ + unsigned int p2_en : 1; /* [2] */ + unsigned int p3_en : 1; /* [3] */ + unsigned int p4_en : 1; /* [4] */ + unsigned int p5_en : 1; /* [5] */ + unsigned int p6_en : 1; /* [6] */ + unsigned int p7_en : 1; /* [7] */ + unsigned int p8_en : 1; /* [8] */ + unsigned int p9_en : 1; /* [9] */ + unsigned int p10_en : 1; /* [10] */ + unsigned int p11_en : 1; /* [11] */ + unsigned int p12_en : 1; /* [12] */ + unsigned int p13_en : 1; /* [13] */ + unsigned int p14_en : 1; /* [14] */ + unsigned int p15_en : 1; /* [15] */ + unsigned int p16_en : 1; /* [16] */ + unsigned int p17_en : 1; /* [17] */ + unsigned int p18_en : 1; /* [18] */ + unsigned int p19_en : 1; /* [19] */ + unsigned int p20_en : 1; /* [20] */ + unsigned int p21_en : 1; /* [21] */ + unsigned int p22_en : 1; /* [22] */ + unsigned int p23_en : 1; /* [23] */ + unsigned int p24_en : 1; /* [24] */ + unsigned int p25_en : 1; /* [25] */ + unsigned int p26_en : 1; /* [26] */ + unsigned int p27_en : 1; /* [27] */ + unsigned int p28_en : 1; /* [28] */ + unsigned int p29_en : 1; /* [29] */ + unsigned int p30_en : 1; /* [30] */ + unsigned int p31_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd0_ccdoposmskl; + +/* Define the union u_dhd0_dacdet1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vdac_det_high : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int det_line : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd0_dacdet1; + +/* Define the union u_dhd0_dacdet2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int det_pixel_sta : 11; /* [10..0] */ + unsigned int reserved_0 : 5; /* [15..11] */ + unsigned int det_pixel_wid : 11; /* [26..16] */ + unsigned int reserved_1 : 4; /* [30..27] */ + unsigned int vdac_det_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd0_dacdet2; + +/* Define the union u_dhd0_ccd_info1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int img_mode : 7; /* [6..0] */ + unsigned int img_right : 1; /* [7] */ + unsigned int img_id : 2; /* [9..8] */ + unsigned int reserved_0 : 1; /* [10] */ + unsigned int ccd_en : 1; /* [11] */ + unsigned int reserved_1 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd0_ccd_info1; + +/* Define the union u_dhd0_ccd_info2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int p32_en : 1; /* [0] */ + unsigned int p33_en : 1; /* [1] */ + unsigned int p34_en : 1; /* [2] */ + unsigned int p35_en : 1; /* [3] */ + unsigned int p36_en : 1; /* [4] */ + unsigned int p37_en : 1; /* [5] */ + unsigned int p38_en : 1; /* [6] */ + unsigned int p39_en : 1; /* [7] */ + unsigned int p40_en : 1; /* [8] */ + unsigned int p41_en : 1; /* [9] */ + unsigned int p42_en : 1; /* [10] */ + unsigned int p43_en : 1; /* [11] */ + unsigned int p44_en : 1; /* [12] */ + unsigned int p45_en : 1; /* [13] */ + unsigned int p46_en : 1; /* [14] */ + unsigned int p47_en : 1; /* [15] */ + unsigned int p48_en : 1; /* [16] */ + unsigned int p49_en : 1; /* [17] */ + unsigned int p50_en : 1; /* [18] */ + unsigned int p51_en : 1; /* [19] */ + unsigned int p52_en : 1; /* [20] */ + unsigned int p53_en : 1; /* [21] */ + unsigned int p54_en : 1; /* [22] */ + unsigned int p55_en : 1; /* [23] */ + unsigned int p56_en : 1; /* [24] */ + unsigned int p57_en : 1; /* [25] */ + unsigned int p58_en : 1; /* [26] */ + unsigned int p59_en : 1; /* [27] */ + unsigned int p60_en : 1; /* [28] */ + unsigned int p61_en : 1; /* [29] */ + unsigned int p62_en : 1; /* [30] */ + unsigned int p63_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd0_ccd_info2; + +/* Define the union u_dhd0_ccd_info3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int p0_en : 1; /* [0] */ + unsigned int p1_en : 1; /* [1] */ + unsigned int p2_en : 1; /* [2] */ + unsigned int p3_en : 1; /* [3] */ + unsigned int p4_en : 1; /* [4] */ + unsigned int p5_en : 1; /* [5] */ + unsigned int p6_en : 1; /* [6] */ + unsigned int p7_en : 1; /* [7] */ + unsigned int p8_en : 1; /* [8] */ + unsigned int p9_en : 1; /* [9] */ + unsigned int p10_en : 1; /* [10] */ + unsigned int p11_en : 1; /* [11] */ + unsigned int p12_en : 1; /* [12] */ + unsigned int p13_en : 1; /* [13] */ + unsigned int p14_en : 1; /* [14] */ + unsigned int p15_en : 1; /* [15] */ + unsigned int p16_en : 1; /* [16] */ + unsigned int p17_en : 1; /* [17] */ + unsigned int p18_en : 1; /* [18] */ + unsigned int p19_en : 1; /* [19] */ + unsigned int p20_en : 1; /* [20] */ + unsigned int p21_en : 1; /* [21] */ + unsigned int p22_en : 1; /* [22] */ + unsigned int p23_en : 1; /* [23] */ + unsigned int p24_en : 1; /* [24] */ + unsigned int p25_en : 1; /* [25] */ + unsigned int p26_en : 1; /* [26] */ + unsigned int p27_en : 1; /* [27] */ + unsigned int p28_en : 1; /* [28] */ + unsigned int p29_en : 1; /* [29] */ + unsigned int p30_en : 1; /* [30] */ + unsigned int p31_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd0_ccd_info3; + +/* Define the union u_intf_hdmi_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int intf_422_en : 1; /* [0] */ + unsigned int intf_420_en : 1; /* [1] */ + unsigned int intf_420_mode : 2; /* [3..2] */ + unsigned int hdmi_mode : 2; /* [5..4] */ + unsigned int reserved_0 : 26; /* [31..6] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf_hdmi_ctrl; + +/* Define the union u_intf_hdmi_upd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int regup : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf_hdmi_upd; + +/* Define the union u_intf_hdmi_sync_inv */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dv_inv : 1; /* [0] */ + unsigned int hs_inv : 1; /* [1] */ + unsigned int vs_inv : 1; /* [2] */ + unsigned int f_inv : 1; /* [3] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf_hdmi_sync_inv; + +/* Define the union u_hdmi_intf_chksum_high */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int r0_sum_high : 8; /* [7..0] */ + unsigned int g0_sum_high : 8; /* [15..8] */ + unsigned int b0_sum_high : 8; /* [23..16] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_hdmi_intf_chksum_high; + +/* Define the union u_hdmi_intf1_chksum_high */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int r1_sum_high : 8; /* [7..0] */ + unsigned int g1_sum_high : 8; /* [15..8] */ + unsigned int b1_sum_high : 8; /* [23..16] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_hdmi_intf1_chksum_high; + +/* Define the union u_hdmi_hfir_coef0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hfir_coef0 : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int hfir_coef1 : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_hdmi_hfir_coef0; + +/* Define the union u_hdmi_hfir_coef1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hfir_coef2 : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int hfir_coef3 : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_hdmi_hfir_coef1; + +/* Define the union u_hdmi_hfir_coef2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hfir_coef4 : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int hfir_coef5 : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_hdmi_hfir_coef2; + +/* Define the union u_hdmi_hfir_coef3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hfir_coef6 : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_hdmi_hfir_coef3; + +/* Define the union u_hdmi_csc_idc */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscidc0 : 11; /* [10..0] */ + unsigned int cscidc1 : 11; /* [21..11] */ + unsigned int csc_en : 1; /* [22] */ + unsigned int reserved_0 : 9; /* [31..23] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_hdmi_csc_idc; + +/* Define the union u_hdmi_csc_odc */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscodc0 : 11; /* [10..0] */ + unsigned int cscodc1 : 11; /* [21..11] */ + unsigned int csc_sign_mode : 1; /* [22] */ + unsigned int reserved_0 : 9; /* [31..23] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_hdmi_csc_odc; + +/* Define the union u_hdmi_csc_iodc */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscidc2 : 11; /* [10..0] */ + unsigned int cscodc2 : 11; /* [21..11] */ + unsigned int reserved_0 : 10; /* [31..22] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_hdmi_csc_iodc; + +/* Define the union u_hdmi_csc_p0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp00 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp01 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_hdmi_csc_p0; + +/* Define the union u_hdmi_csc_p1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp02 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp10 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_hdmi_csc_p1; + +/* Define the union u_hdmi_csc_p2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp11 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp12 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_hdmi_csc_p2; + +/* Define the union u_hdmi_csc_p3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp20 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp21 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_hdmi_csc_p3; + +/* Define the union u_hdmi_csc_p4 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp22 : 15; /* [14..0] */ + unsigned int reserved_0 : 17; /* [31..15] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_hdmi_csc_p4; + +/* Define the union u_intf_mipi_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int intf_422_en : 1; /* [0] */ + unsigned int intf_420_en : 1; /* [1] */ + unsigned int intf_420_mode : 2; /* [3..2] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf_mipi_ctrl; + +/* Define the union u_intf_mipi_upd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int regup : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf_mipi_upd; + +/* Define the union u_intf_mipi_sync_inv */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dv_inv : 1; /* [0] */ + unsigned int hs_inv : 1; /* [1] */ + unsigned int vs_inv : 1; /* [2] */ + unsigned int f_inv : 1; /* [3] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf_mipi_sync_inv; + +/* Define the union u_mipi_intf_chksum_high */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int b0_sum_high : 8; /* [7..0] */ + unsigned int g0_sum_high : 8; /* [15..8] */ + unsigned int r0_sum_high : 8; /* [23..16] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_mipi_intf_chksum_high; + +/* Define the union u_mipi_intf1_chksum_high */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int b1_sum_high : 8; /* [7..0] */ + unsigned int g1_sum_high : 8; /* [15..8] */ + unsigned int r1_sum_high : 8; /* [23..16] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_mipi_intf1_chksum_high; + +/* Define the union u_mipi_hfir_coef0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hfir_coef0 : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int hfir_coef1 : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_mipi_hfir_coef0; + +/* Define the union u_mipi_hfir_coef1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hfir_coef2 : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int hfir_coef3 : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_mipi_hfir_coef1; + +/* Define the union u_mipi_hfir_coef2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hfir_coef4 : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int hfir_coef5 : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_mipi_hfir_coef2; + +/* Define the union u_mipi_hfir_coef3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hfir_coef6 : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_mipi_hfir_coef3; + +/* Define the union u_intf_bt_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 16; /* [15..0] */ + unsigned int data_width : 1; /* [16] */ + unsigned int bit_inv : 1; /* [17] */ + unsigned int uv_mode : 1; /* [18] */ + unsigned int yc_mode : 1; /* [19] */ + unsigned int reserved_1 : 10; /* [29..20] */ + unsigned int dfir_en : 1; /* [30] */ + unsigned int hdmi_mode : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf_bt_ctrl; + +/* Define the union u_intf_bt_upd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int regup : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf_bt_upd; + +/* Define the union u_intf_bt_sync_inv */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dv_inv : 1; /* [0] */ + unsigned int hs_inv : 1; /* [1] */ + unsigned int vs_inv : 1; /* [2] */ + unsigned int f_inv : 1; /* [3] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf_bt_sync_inv; + +/* Define the union u_bt_clip0_l */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int clip_cl0 : 10; /* [9..0] */ + unsigned int clip_cl1 : 10; /* [19..10] */ + unsigned int clip_cl2 : 10; /* [29..20] */ + unsigned int reserved_0 : 1; /* [30] */ + unsigned int clip_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_bt_clip0_l; + +/* Define the union u_bt_clip0_h */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int clip_ch0 : 10; /* [9..0] */ + unsigned int clip_ch1 : 10; /* [19..10] */ + unsigned int clip_ch2 : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_bt_clip0_h; + +/* Define the union u_bt_dither_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_tap_mode : 2; /* [1..0] */ + unsigned int dither_domain_mode : 1; /* [2] */ + unsigned int dither_round : 1; /* [3] */ + unsigned int dither_mode : 1; /* [4] */ + unsigned int dither_en : 1; /* [5] */ + unsigned int dither_round_unlim : 1; /* [6] */ + unsigned int i_data_width_dither : 3; /* [9..7] */ + unsigned int o_data_width_dither : 3; /* [12..10] */ + unsigned int reserved_0 : 19; /* [31..13] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_bt_dither_ctrl; + +/* Define the union u_bt_dither_sed_y0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_y0 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_bt_dither_sed_y0; + +/* Define the union u_bt_dither_sed_u0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_u0 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_bt_dither_sed_u0; + +/* Define the union u_bt_dither_sed_v0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_v0 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_bt_dither_sed_v0; + +/* Define the union u_bt_dither_sed_w0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_w0 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_bt_dither_sed_w0; + +/* Define the union u_bt_dither_sed_y1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_y1 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_bt_dither_sed_y1; + +/* Define the union u_bt_dither_sed_u1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_u1 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_bt_dither_sed_u1; + +/* Define the union u_bt_dither_sed_v1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_v1 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_bt_dither_sed_v1; + +/* Define the union u_bt_dither_sed_w1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_w1 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_bt_dither_sed_w1; + +/* Define the union u_bt_dither_sed_y2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_y2 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_bt_dither_sed_y2; + +/* Define the union u_bt_dither_sed_u2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_u2 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_bt_dither_sed_u2; + +/* Define the union u_bt_dither_sed_v2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_v2 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_bt_dither_sed_v2; + +/* Define the union u_bt_dither_sed_w2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_w2 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_bt_dither_sed_w2; + +/* Define the union u_bt_dither_sed_y3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_y3 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_bt_dither_sed_y3; + +/* Define the union u_bt_dither_sed_u3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_u3 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_bt_dither_sed_u3; + +/* Define the union u_bt_dither_sed_v3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_v3 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_bt_dither_sed_v3; + +/* Define the union u_bt_dither_sed_w3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_w3 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_bt_dither_sed_w3; + +/* Define the union u_bt_dither_thr */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_thr_min : 16; /* [15..0] */ + unsigned int dither_thr_max : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_bt_dither_thr; + +/* Define the union u_intf_lcd_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 20; /* [19..0] */ + unsigned int lcd_format : 4; /* [23..20] */ + unsigned int lcd_bit_inv : 1; /* [24] */ + unsigned int lcd_comp_order : 1; /* [25] */ + unsigned int lcd_serial_perd : 1; /* [26] */ + unsigned int reserved_1 : 3; /* [29..27] */ + unsigned int dfir_en : 1; /* [30] */ + unsigned int hdmi_mode : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf_lcd_ctrl; + +/* Define the union u_intf_lcd_upd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int regup : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf_lcd_upd; + +/* Define the union u_intf_lcd_sync_inv */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dv_inv : 1; /* [0] */ + unsigned int hs_inv : 1; /* [1] */ + unsigned int vs_inv : 1; /* [2] */ + unsigned int f_inv : 1; /* [3] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf_lcd_sync_inv; + +/* Define the union u_lcd_dither_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_tap_mode : 2; /* [1..0] */ + unsigned int dither_domain_mode : 1; /* [2] */ + unsigned int dither_round : 1; /* [3] */ + unsigned int dither_mode : 1; /* [4] */ + unsigned int dither_en : 1; /* [5] */ + unsigned int dither_round_unlim : 1; /* [6] */ + unsigned int i_data_width_dither : 3; /* [9..7] */ + unsigned int o_data_width_dither : 3; /* [12..10] */ + unsigned int reserved_0 : 19; /* [31..13] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_lcd_dither_ctrl; + +/* Define the union u_lcd_dither_sed_y0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_y0 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_lcd_dither_sed_y0; + +/* Define the union u_lcd_dither_sed_u0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_u0 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_lcd_dither_sed_u0; + +/* Define the union u_lcd_dither_sed_v0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_v0 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_lcd_dither_sed_v0; + +/* Define the union u_lcd_dither_sed_w0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_w0 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_lcd_dither_sed_w0; + +/* Define the union u_lcd_dither_sed_y1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_y1 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_lcd_dither_sed_y1; + +/* Define the union u_lcd_dither_sed_u1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_u1 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_lcd_dither_sed_u1; + +/* Define the union u_lcd_dither_sed_v1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_v1 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_lcd_dither_sed_v1; + +/* Define the union u_lcd_dither_sed_w1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_w1 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_lcd_dither_sed_w1; + +/* Define the union u_lcd_dither_sed_y2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_y2 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_lcd_dither_sed_y2; + +/* Define the union u_lcd_dither_sed_u2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_u2 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_lcd_dither_sed_u2; + +/* Define the union u_lcd_dither_sed_v2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_v2 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_lcd_dither_sed_v2; + +/* Define the union u_lcd_dither_sed_w2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_w2 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_lcd_dither_sed_w2; + +/* Define the union u_lcd_dither_sed_y3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_y3 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_lcd_dither_sed_y3; + +/* Define the union u_lcd_dither_sed_u3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_u3 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_lcd_dither_sed_u3; + +/* Define the union u_lcd_dither_sed_v3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_v3 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_lcd_dither_sed_v3; + +/* Define the union u_lcd_dither_sed_w3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_w3 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_lcd_dither_sed_w3; + +/* Define the union u_lcd_dither_thr */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_thr_min : 16; /* [15..0] */ + unsigned int dither_thr_max : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_lcd_dither_thr; + +/* Define the union u_intf_hdmi1_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int intf_422_en : 1; /* [0] */ + unsigned int intf_420_en : 1; /* [1] */ + unsigned int intf_420_mode : 2; /* [3..2] */ + unsigned int hdmi_mode : 2; /* [5..4] */ + unsigned int reserved_0 : 26; /* [31..6] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf_hdmi1_ctrl; + +/* Define the union u_intf_hdmi1_upd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int regup : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf_hdmi1_upd; + +/* Define the union u_intf_hdmi1_sync_inv */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dv_inv : 1; /* [0] */ + unsigned int hs_inv : 1; /* [1] */ + unsigned int vs_inv : 1; /* [2] */ + unsigned int f_inv : 1; /* [3] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf_hdmi1_sync_inv; + +/* Define the union u_hdmi1_intf_chksum_high */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int r0_sum_high : 8; /* [7..0] */ + unsigned int g0_sum_high : 8; /* [15..8] */ + unsigned int b0_sum_high : 8; /* [23..16] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_hdmi1_intf_chksum_high; + +/* Define the union u_hdmi1_intf1_chksum_high */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int r1_sum_high : 8; /* [7..0] */ + unsigned int g1_sum_high : 8; /* [15..8] */ + unsigned int b1_sum_high : 8; /* [23..16] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_hdmi1_intf1_chksum_high; + +/* Define the union u_hdmi1_hfir_coef0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hfir_coef0 : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int hfir_coef1 : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_hdmi1_hfir_coef0; + +/* Define the union u_hdmi1_hfir_coef1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hfir_coef2 : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int hfir_coef3 : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_hdmi1_hfir_coef1; + +/* Define the union u_hdmi1_hfir_coef2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hfir_coef4 : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int hfir_coef5 : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_hdmi1_hfir_coef2; + +/* Define the union u_hdmi1_hfir_coef3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hfir_coef6 : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_hdmi1_hfir_coef3; + +/* Define the union u_intf_vga_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 24; /* [23..0] */ + unsigned int yc_mode : 1; /* [24] */ + unsigned int lcd_parallel_mode : 1; /* [25] */ + unsigned int lcd_data_inv : 1; /* [26] */ + unsigned int lcd_parallel_order : 1; /* [27] */ + unsigned int lcd_serial_perd : 1; /* [28] */ + unsigned int lcd_serial_mode : 1; /* [29] */ + unsigned int dfir_en : 1; /* [30] */ + unsigned int hdmi_mode : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf_vga_ctrl; + +/* Define the union u_intf_vga_upd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int regup : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf_vga_upd; + +/* Define the union u_intf_vga_sync_inv */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dv_inv : 1; /* [0] */ + unsigned int hs_inv : 1; /* [1] */ + unsigned int vs_inv : 1; /* [2] */ + unsigned int f_inv : 1; /* [3] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf_vga_sync_inv; + +/* Define the union u_vga_csc_idc */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscidc0 : 11; /* [10..0] */ + unsigned int cscidc1 : 11; /* [21..11] */ + unsigned int csc_en : 1; /* [22] */ + unsigned int reserved_0 : 9; /* [31..23] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vga_csc_idc; + +/* Define the union u_vga_csc_odc */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscodc0 : 11; /* [10..0] */ + unsigned int cscodc1 : 11; /* [21..11] */ + unsigned int csc_sign_mode : 1; /* [22] */ + unsigned int reserved_0 : 9; /* [31..23] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vga_csc_odc; + +/* Define the union u_vga_csc_iodc */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscidc2 : 11; /* [10..0] */ + unsigned int cscodc2 : 11; /* [21..11] */ + unsigned int reserved_0 : 10; /* [31..22] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vga_csc_iodc; + +/* Define the union u_vga_csc_p0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp00 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp01 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vga_csc_p0; + +/* Define the union u_vga_csc_p1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp02 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp10 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vga_csc_p1; + +/* Define the union u_vga_csc_p2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp11 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp12 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vga_csc_p2; + +/* Define the union u_vga_csc_p3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp20 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp21 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vga_csc_p3; + +/* Define the union u_vga_csc_p4 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp22 : 15; /* [14..0] */ + unsigned int reserved_0 : 17; /* [31..15] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vga_csc_p4; + +/* Define the union u_vga_hspcfg0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hsp_hf0_tmp0 : 8; /* [7..0] */ + unsigned int hsp_hf0_tmp1 : 8; /* [15..8] */ + unsigned int hsp_hf0_tmp2 : 8; /* [23..16] */ + unsigned int hsp_hf0_tmp3 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vga_hspcfg0; + +/* Define the union u_vga_hspcfg1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hsp_hf0_coring : 8; /* [7..0] */ + unsigned int reserved_0 : 23; /* [30..8] */ + unsigned int hsp_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vga_hspcfg1; + +/* Define the union u_vga_hspcfg5 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hsp_hf0_gainpos : 11; /* [10..0] */ + unsigned int reserved_0 : 5; /* [15..11] */ + unsigned int hsp_hf0_gainneg : 11; /* [26..16] */ + unsigned int reserved_1 : 5; /* [31..27] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vga_hspcfg5; + +/* Define the union u_vga_hspcfg6 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hsp_hf0_overth : 8; /* [7..0] */ + unsigned int hsp_hf0_underth : 8; /* [15..8] */ + unsigned int hsp_hf0_mixratio : 8; /* [23..16] */ + unsigned int reserved_0 : 4; /* [27..24] */ + unsigned int hsp_hf0_winsize : 3; /* [30..28] */ + unsigned int hsp_hf0_adpshoot_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vga_hspcfg6; + +/* Define the union u_vga_hspcfg7 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hsp_hf1_tmp0 : 8; /* [7..0] */ + unsigned int hsp_hf1_tmp1 : 8; /* [15..8] */ + unsigned int hsp_hf1_tmp2 : 8; /* [23..16] */ + unsigned int hsp_hf1_tmp3 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vga_hspcfg7; + +/* Define the union u_vga_hspcfg8 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hsp_hf1_coring : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vga_hspcfg8; + +/* Define the union u_vga_hspcfg12 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hsp_hf1_gainpos : 11; /* [10..0] */ + unsigned int reserved_0 : 5; /* [15..11] */ + unsigned int hsp_hf1_gainneg : 11; /* [26..16] */ + unsigned int reserved_1 : 5; /* [31..27] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vga_hspcfg12; + +/* Define the union u_vga_hspcfg13 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hsp_hf1_overth : 8; /* [7..0] */ + unsigned int hsp_hf1_underth : 8; /* [15..8] */ + unsigned int hsp_hf1_mixratio : 8; /* [23..16] */ + unsigned int reserved_0 : 4; /* [27..24] */ + unsigned int hsp_hf1_winsize : 3; /* [30..28] */ + unsigned int hsp_hf1_adpshoot_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vga_hspcfg13; + +/* Define the union u_vga_hspcfg14 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hsp_cdti_gain : 8; /* [7..0] */ + unsigned int hsp_ldti_gain : 8; /* [15..8] */ + unsigned int hsp_lti_ratio : 8; /* [23..16] */ + unsigned int hsp_hf_shootdiv : 3; /* [26..24] */ + unsigned int reserved_0 : 1; /* [27] */ + unsigned int hsp_ctih_en : 1; /* [28] */ + unsigned int hsp_ltih_en : 1; /* [29] */ + unsigned int hsp_h1_en : 1; /* [30] */ + unsigned int hsp_h0_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vga_hspcfg14; + +/* Define the union u_vga_hspcfg15 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hsp_glb_underth : 9; /* [8..0] */ + unsigned int reserved_0 : 1; /* [9] */ + unsigned int hsp_glb_overth : 9; /* [18..10] */ + unsigned int reserved_1 : 1; /* [19] */ + unsigned int hsp_peak_ratio : 8; /* [27..20] */ + unsigned int reserved_2 : 4; /* [31..28] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vga_hspcfg15; + +/* Define the union u_intf_date_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 23; /* [22..0] */ + unsigned int uv_mode : 1; /* [23] */ + unsigned int yc_mode : 1; /* [24] */ + unsigned int lcd_parallel_mode : 1; /* [25] */ + unsigned int lcd_data_inv : 1; /* [26] */ + unsigned int lcd_parallel_order : 1; /* [27] */ + unsigned int lcd_serial_perd : 1; /* [28] */ + unsigned int lcd_serial_mode : 1; /* [29] */ + unsigned int dfir_en : 1; /* [30] */ + unsigned int hdmi_mode : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf_date_ctrl; + +/* Define the union u_intf_date_upd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int regup : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf_date_upd; + +/* Define the union u_intf_date_sync_inv */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dv_inv : 1; /* [0] */ + unsigned int hs_inv : 1; /* [1] */ + unsigned int vs_inv : 1; /* [2] */ + unsigned int f_inv : 1; /* [3] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf_date_sync_inv; + +/* Define the union u_date_clip0_l */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int clip_cl0 : 10; /* [9..0] */ + unsigned int clip_cl1 : 10; /* [19..10] */ + unsigned int clip_cl2 : 10; /* [29..20] */ + unsigned int reserved_0 : 1; /* [30] */ + unsigned int clip_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_clip0_l; + +/* Define the union u_date_clip0_h */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int clip_ch0 : 10; /* [9..0] */ + unsigned int clip_ch1 : 10; /* [19..10] */ + unsigned int clip_ch2 : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_clip0_h; + +/* Define the union u_intf0_dither_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_tap_mode : 2; /* [1..0] */ + unsigned int dither_domain_mode : 1; /* [2] */ + unsigned int dither_round : 1; /* [3] */ + unsigned int dither_mode : 1; /* [4] */ + unsigned int dither_en : 1; /* [5] */ + unsigned int dither_round_unlim : 1; /* [6] */ + unsigned int i_data_width_dither : 3; /* [9..7] */ + unsigned int o_data_width_dither : 3; /* [12..10] */ + unsigned int reserved_0 : 19; /* [31..13] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf0_dither_ctrl; + +/* Define the union u_intf0_dither_sed_y0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_y0 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf0_dither_sed_y0; + +/* Define the union u_intf0_dither_sed_u0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_u0 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf0_dither_sed_u0; + +/* Define the union u_intf0_dither_sed_v0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_v0 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf0_dither_sed_v0; + +/* Define the union u_intf0_dither_sed_w0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_w0 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf0_dither_sed_w0; + +/* Define the union u_intf0_dither_sed_y1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_y1 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf0_dither_sed_y1; + +/* Define the union u_intf0_dither_sed_u1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_u1 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf0_dither_sed_u1; + +/* Define the union u_intf0_dither_sed_v1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_v1 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf0_dither_sed_v1; + +/* Define the union u_intf0_dither_sed_w1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_w1 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf0_dither_sed_w1; + +/* Define the union u_intf0_dither_sed_y2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_y2 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf0_dither_sed_y2; + +/* Define the union u_intf0_dither_sed_u2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_u2 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf0_dither_sed_u2; + +/* Define the union u_intf0_dither_sed_v2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_v2 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf0_dither_sed_v2; + +/* Define the union u_intf0_dither_sed_w2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_w2 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf0_dither_sed_w2; + +/* Define the union u_intf0_dither_sed_y3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_y3 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf0_dither_sed_y3; + +/* Define the union u_intf0_dither_sed_u3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_u3 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf0_dither_sed_u3; + +/* Define the union u_intf0_dither_sed_v3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_v3 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf0_dither_sed_v3; + +/* Define the union u_intf0_dither_sed_w3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_w3 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf0_dither_sed_w3; + +/* Define the union u_intf0_dither_thr */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_thr_min : 16; /* [15..0] */ + unsigned int dither_thr_max : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf0_dither_thr; + +/* Define the union u_dhd1_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int regup : 1; /* [0] */ + unsigned int disp_mode : 3; /* [3..1] */ + unsigned int iop : 1; /* [4] */ + unsigned int intf_ivs : 1; /* [5] */ + unsigned int intf_ihs : 1; /* [6] */ + unsigned int intf_idv : 1; /* [7] */ + unsigned int reserved_0 : 1; /* [8] */ + unsigned int hdmi420c_sel : 1; /* [9] */ + unsigned int hdmi420_en : 1; /* [10] */ + unsigned int uf_offline_en : 1; /* [11] */ + unsigned int reserved_1 : 2; /* [13..12] */ + unsigned int hdmi_mode : 1; /* [14] */ + unsigned int twochn_debug : 1; /* [15] */ + unsigned int twochn_en : 1; /* [16] */ + unsigned int reserved_2 : 1; /* [17] */ + unsigned int cbar_mode : 1; /* [18] */ + unsigned int sin_en : 1; /* [19] */ + unsigned int fpga_lmt_width : 7; /* [26..20] */ + unsigned int fpga_lmt_en : 1; /* [27] */ + unsigned int p2i_en : 1; /* [28] */ + unsigned int cbar_sel : 1; /* [29] */ + unsigned int cbar_en : 1; /* [30] */ + unsigned int intf_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd1_ctrl; + +/* Define the union u_dhd1_vsync1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vact : 16; /* [15..0] */ + unsigned int vbb : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd1_vsync1; + +/* Define the union u_dhd1_vsync2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vfb : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd1_vsync2; + +/* Define the union u_dhd1_hsync1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hact : 16; /* [15..0] */ + unsigned int hbb : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd1_hsync1; + +/* Define the union u_dhd1_hsync2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hfb : 16; /* [15..0] */ + unsigned int hmid : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd1_hsync2; + +/* Define the union u_dhd1_vplus1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int bvact : 16; /* [15..0] */ + unsigned int bvbb : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd1_vplus1; + +/* Define the union u_dhd1_vplus2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int bvfb : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd1_vplus2; + +/* Define the union u_dhd1_pwr */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hpw : 16; /* [15..0] */ + unsigned int vpw : 8; /* [23..16] */ + unsigned int reserved_0 : 3; /* [26..24] */ + unsigned int multichn_en : 2; /* [28..27] */ + unsigned int reserved_1 : 3; /* [31..29] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd1_pwr; + +/* Define the union u_dhd1_vtthd3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vtmgthd3 : 13; /* [12..0] */ + unsigned int reserved_0 : 2; /* [14..13] */ + unsigned int thd3_mode : 1; /* [15] */ + unsigned int vtmgthd4 : 13; /* [28..16] */ + unsigned int reserved_1 : 2; /* [30..29] */ + unsigned int thd4_mode : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd1_vtthd3; + +/* Define the union u_dhd1_vtthd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vtmgthd1 : 13; /* [12..0] */ + unsigned int reserved_0 : 2; /* [14..13] */ + unsigned int thd1_mode : 1; /* [15] */ + unsigned int vtmgthd2 : 13; /* [28..16] */ + unsigned int reserved_1 : 2; /* [30..29] */ + unsigned int thd2_mode : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd1_vtthd; + +/* Define the union u_dhd1_parathd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int para_thd : 8; /* [7..0] */ + unsigned int reserved_0 : 23; /* [30..8] */ + unsigned int dfs_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd1_parathd; + +/* Define the union u_dhd1_precharge_thd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int tcon_precharge_thd : 17; /* [16..0] */ + unsigned int reserved_0 : 3; /* [19..17] */ + unsigned int vsync_te_mode : 1; /* [20] */ + unsigned int reserved_1 : 11; /* [31..21] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd1_precharge_thd; + +/* Define the union u_dhd1_start_pos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int start_pos : 8; /* [7..0] */ + unsigned int timing_start_pos : 8; /* [15..8] */ + unsigned int fi_start_pos : 4; /* [19..16] */ + unsigned int req_start_pos : 12; /* [31..20] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd1_start_pos; + +/* Define the union u_dhd1_start_pos1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int req_start_pos1 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd1_start_pos1; + +/* Define the union u_dhd1_paraup */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 31; /* [30..0] */ + unsigned int paraup_mode : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd1_paraup; + +/* Define the union u_dhd1_sync_inv */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int lcd_dv_inv : 1; /* [0] */ + unsigned int lcd_hs_inv : 1; /* [1] */ + unsigned int lcd_vs_inv : 1; /* [2] */ + unsigned int reserved_0 : 1; /* [3] */ + unsigned int vga_dv_inv : 1; /* [4] */ + unsigned int vga_hs_inv : 1; /* [5] */ + unsigned int vga_vs_inv : 1; /* [6] */ + unsigned int reserved_1 : 1; /* [7] */ + unsigned int hdmi_dv_inv : 1; /* [8] */ + unsigned int hdmi_hs_inv : 1; /* [9] */ + unsigned int hdmi_vs_inv : 1; /* [10] */ + unsigned int hdmi_f_inv : 1; /* [11] */ + unsigned int date_dv_inv : 1; /* [12] */ + unsigned int date_hs_inv : 1; /* [13] */ + unsigned int date_vs_inv : 1; /* [14] */ + unsigned int date_f_inv : 1; /* [15] */ + unsigned int reserved_2 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd1_sync_inv; + +/* Define the union u_dhd1_clk_dv_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int intf_clk_mux : 1; /* [0] */ + unsigned int intf_dv_mux : 1; /* [1] */ + unsigned int no_active_area_pos : 16; /* [17..2] */ + unsigned int reserved_0 : 14; /* [31..18] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd1_clk_dv_ctrl; + +/* Define the union u_dhd1_rgb_fix_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int fix_b : 10; /* [9..0] */ + unsigned int fix_g : 10; /* [19..10] */ + unsigned int fix_r : 10; /* [29..20] */ + unsigned int rgb_fix_mux : 1; /* [30] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd1_rgb_fix_ctrl; + +/* Define the union u_dhd1_lockcfg */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int measure_en : 1; /* [0] */ + unsigned int lock_cnt_en : 1; /* [1] */ + unsigned int vdp_measure_en : 1; /* [2] */ + unsigned int reserved_0 : 29; /* [31..3] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd1_lockcfg; + +/* Define the union u_dhd1_intf_chksum_high1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int y0_sum_high : 8; /* [7..0] */ + unsigned int g0_sum_high : 8; /* [15..8] */ + unsigned int b0_sum_high : 8; /* [23..16] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd1_intf_chksum_high1; + +/* Define the union u_dhd1_intf_chksum_high2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int y1_sum_high : 8; /* [7..0] */ + unsigned int g1_sum_high : 8; /* [15..8] */ + unsigned int b1_sum_high : 8; /* [23..16] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd1_intf_chksum_high2; + +/* Define the union u_dhd1_state */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vback_blank : 1; /* [0] */ + unsigned int vblank : 1; /* [1] */ + unsigned int bottom_field : 1; /* [2] */ + unsigned int vcnt : 13; /* [15..3] */ + unsigned int count_int : 8; /* [23..16] */ + unsigned int dhd_even : 1; /* [24] */ + unsigned int reserved_0 : 7; /* [31..25] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd1_state; + +/* Define the union u_dhd1_uf_state */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ud_first_cnt : 13; /* [12..0] */ + unsigned int reserved_0 : 3; /* [15..13] */ + unsigned int start_pos : 8; /* [23..16] */ + unsigned int reserved_1 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd1_uf_state; + +/* Define the union u_dhd1_vsync_te_state */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vsync_te_start_sta : 8; /* [7..0] */ + unsigned int vsync_te_start_sta1 : 8; /* [15..8] */ + unsigned int vsync_te_end_sta : 8; /* [23..16] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd1_vsync_te_state; + +/* Define the union u_dhd1_vsync_te_state1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vsync_te_vfb : 16; /* [15..0] */ + unsigned int vsync_te_width : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd1_vsync_te_state1; + +/* Define the union u_intf1_dither_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_tap_mode : 2; /* [1..0] */ + unsigned int dither_domain_mode : 1; /* [2] */ + unsigned int dither_round : 1; /* [3] */ + unsigned int dither_mode : 1; /* [4] */ + unsigned int dither_en : 1; /* [5] */ + unsigned int dither_round_unlim : 1; /* [6] */ + unsigned int i_data_width_dither : 3; /* [9..7] */ + unsigned int o_data_width_dither : 3; /* [12..10] */ + unsigned int reserved_0 : 19; /* [31..13] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf1_dither_ctrl; + +/* Define the union u_intf1_dither_sed_y0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_y0 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf1_dither_sed_y0; + +/* Define the union u_intf1_dither_sed_u0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_u0 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf1_dither_sed_u0; + +/* Define the union u_intf1_dither_sed_v0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_v0 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf1_dither_sed_v0; + +/* Define the union u_intf1_dither_sed_w0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_w0 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf1_dither_sed_w0; + +/* Define the union u_intf1_dither_sed_y1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_y1 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf1_dither_sed_y1; + +/* Define the union u_intf1_dither_sed_u1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_u1 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf1_dither_sed_u1; + +/* Define the union u_intf1_dither_sed_v1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_v1 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf1_dither_sed_v1; + +/* Define the union u_intf1_dither_sed_w1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_w1 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf1_dither_sed_w1; + +/* Define the union u_intf1_dither_sed_y2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_y2 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf1_dither_sed_y2; + +/* Define the union u_intf1_dither_sed_u2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_u2 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf1_dither_sed_u2; + +/* Define the union u_intf1_dither_sed_v2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_v2 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf1_dither_sed_v2; + +/* Define the union u_intf1_dither_sed_w2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_w2 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf1_dither_sed_w2; + +/* Define the union u_intf1_dither_sed_y3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_y3 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf1_dither_sed_y3; + +/* Define the union u_intf1_dither_sed_u3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_u3 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf1_dither_sed_u3; + +/* Define the union u_intf1_dither_sed_v3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_v3 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf1_dither_sed_v3; + +/* Define the union u_intf1_dither_sed_w3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_w3 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf1_dither_sed_w3; + +/* Define the union u_intf1_dither_thr */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_thr_min : 16; /* [15..0] */ + unsigned int dither_thr_max : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf1_dither_thr; + +/* Define the union u_dhd2_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int regup : 1; /* [0] */ + unsigned int disp_mode : 3; /* [3..1] */ + unsigned int iop : 1; /* [4] */ + unsigned int intf_ivs : 1; /* [5] */ + unsigned int intf_ihs : 1; /* [6] */ + unsigned int intf_idv : 1; /* [7] */ + unsigned int reserved_0 : 1; /* [8] */ + unsigned int hdmi420c_sel : 1; /* [9] */ + unsigned int hdmi420_en : 1; /* [10] */ + unsigned int uf_offline_en : 1; /* [11] */ + unsigned int reserved_1 : 2; /* [13..12] */ + unsigned int hdmi_mode : 1; /* [14] */ + unsigned int twochn_debug : 1; /* [15] */ + unsigned int twochn_en : 1; /* [16] */ + unsigned int reserved_2 : 1; /* [17] */ + unsigned int cbar_mode : 1; /* [18] */ + unsigned int sin_en : 1; /* [19] */ + unsigned int fpga_lmt_width : 7; /* [26..20] */ + unsigned int fpga_lmt_en : 1; /* [27] */ + unsigned int p2i_en : 1; /* [28] */ + unsigned int cbar_sel : 1; /* [29] */ + unsigned int cbar_en : 1; /* [30] */ + unsigned int intf_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd2_ctrl; + +/* Define the union u_dhd2_vsync1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vact : 16; /* [15..0] */ + unsigned int vbb : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd2_vsync1; + +/* Define the union u_dhd2_vsync2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vfb : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd2_vsync2; + +/* Define the union u_dhd2_hsync1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hact : 16; /* [15..0] */ + unsigned int hbb : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd2_hsync1; + +/* Define the union u_dhd2_hsync2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hfb : 16; /* [15..0] */ + unsigned int hmid : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd2_hsync2; + +/* Define the union u_dhd2_vplus1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int bvact : 16; /* [15..0] */ + unsigned int bvbb : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd2_vplus1; + +/* Define the union u_dhd2_vplus2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int bvfb : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd2_vplus2; + +/* Define the union u_dhd2_pwr */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int hpw : 16; /* [15..0] */ + unsigned int vpw : 8; /* [23..16] */ + unsigned int reserved_0 : 3; /* [26..24] */ + unsigned int multichn_en : 2; /* [28..27] */ + unsigned int reserved_1 : 3; /* [31..29] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd2_pwr; + +/* Define the union u_dhd2_vtthd3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vtmgthd3 : 13; /* [12..0] */ + unsigned int reserved_0 : 2; /* [14..13] */ + unsigned int thd3_mode : 1; /* [15] */ + unsigned int vtmgthd4 : 13; /* [28..16] */ + unsigned int reserved_1 : 2; /* [30..29] */ + unsigned int thd4_mode : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd2_vtthd3; + +/* Define the union u_dhd2_vtthd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vtmgthd1 : 13; /* [12..0] */ + unsigned int reserved_0 : 2; /* [14..13] */ + unsigned int thd1_mode : 1; /* [15] */ + unsigned int vtmgthd2 : 13; /* [28..16] */ + unsigned int reserved_1 : 2; /* [30..29] */ + unsigned int thd2_mode : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd2_vtthd; + +/* Define the union u_dhd2_parathd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int para_thd : 8; /* [7..0] */ + unsigned int reserved_0 : 23; /* [30..8] */ + unsigned int dfs_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd2_parathd; + +/* Define the union u_dhd2_precharge_thd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int tcon_precharge_thd : 17; /* [16..0] */ + unsigned int reserved_0 : 3; /* [19..17] */ + unsigned int vsync_te_mode : 1; /* [20] */ + unsigned int reserved_1 : 11; /* [31..21] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd2_precharge_thd; + +/* Define the union u_dhd2_start_pos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int start_pos : 8; /* [7..0] */ + unsigned int timing_start_pos : 8; /* [15..8] */ + unsigned int fi_start_pos : 4; /* [19..16] */ + unsigned int req_start_pos : 12; /* [31..20] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd2_start_pos; + +/* Define the union u_dhd2_start_pos1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int req_start_pos1 : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd2_start_pos1; + +/* Define the union u_dhd2_paraup */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 31; /* [30..0] */ + unsigned int paraup_mode : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd2_paraup; + +/* Define the union u_dhd2_sync_inv */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int lcd_dv_inv : 1; /* [0] */ + unsigned int lcd_hs_inv : 1; /* [1] */ + unsigned int lcd_vs_inv : 1; /* [2] */ + unsigned int reserved_0 : 1; /* [3] */ + unsigned int vga_dv_inv : 1; /* [4] */ + unsigned int vga_hs_inv : 1; /* [5] */ + unsigned int vga_vs_inv : 1; /* [6] */ + unsigned int reserved_1 : 1; /* [7] */ + unsigned int hdmi_dv_inv : 1; /* [8] */ + unsigned int hdmi_hs_inv : 1; /* [9] */ + unsigned int hdmi_vs_inv : 1; /* [10] */ + unsigned int hdmi_f_inv : 1; /* [11] */ + unsigned int date_dv_inv : 1; /* [12] */ + unsigned int date_hs_inv : 1; /* [13] */ + unsigned int date_vs_inv : 1; /* [14] */ + unsigned int date_f_inv : 1; /* [15] */ + unsigned int reserved_2 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd2_sync_inv; + +/* Define the union u_dhd2_clk_dv_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int intf_clk_mux : 1; /* [0] */ + unsigned int intf_dv_mux : 1; /* [1] */ + unsigned int no_active_area_pos : 16; /* [17..2] */ + unsigned int reserved_0 : 14; /* [31..18] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd2_clk_dv_ctrl; + +/* Define the union u_dhd2_rgb_fix_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int fix_b : 10; /* [9..0] */ + unsigned int fix_g : 10; /* [19..10] */ + unsigned int fix_r : 10; /* [29..20] */ + unsigned int rgb_fix_mux : 1; /* [30] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd2_rgb_fix_ctrl; + +/* Define the union u_dhd2_lockcfg */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int measure_en : 1; /* [0] */ + unsigned int lock_cnt_en : 1; /* [1] */ + unsigned int vdp_measure_en : 1; /* [2] */ + unsigned int reserved_0 : 29; /* [31..3] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd2_lockcfg; + +/* Define the union u_dhd2_intf_chksum_high1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int y0_sum_high : 8; /* [7..0] */ + unsigned int g0_sum_high : 8; /* [15..8] */ + unsigned int b0_sum_high : 8; /* [23..16] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd2_intf_chksum_high1; + +/* Define the union u_dhd2_intf_chksum_high2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int y1_sum_high : 8; /* [7..0] */ + unsigned int g1_sum_high : 8; /* [15..8] */ + unsigned int b1_sum_high : 8; /* [23..16] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd2_intf_chksum_high2; + +/* Define the union u_dhd2_state */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vback_blank : 1; /* [0] */ + unsigned int vblank : 1; /* [1] */ + unsigned int bottom_field : 1; /* [2] */ + unsigned int vcnt : 13; /* [15..3] */ + unsigned int count_int : 8; /* [23..16] */ + unsigned int dhd_even : 1; /* [24] */ + unsigned int reserved_0 : 7; /* [31..25] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd2_state; + +/* Define the union u_dhd2_uf_state */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ud_first_cnt : 13; /* [12..0] */ + unsigned int reserved_0 : 3; /* [15..13] */ + unsigned int start_pos : 8; /* [23..16] */ + unsigned int reserved_1 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd2_uf_state; + +/* Define the union u_dhd2_vsync_te_state */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vsync_te_start_sta : 8; /* [7..0] */ + unsigned int vsync_te_start_sta1 : 8; /* [15..8] */ + unsigned int vsync_te_end_sta : 8; /* [23..16] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd2_vsync_te_state; + +/* Define the union u_dhd2_vsync_te_state1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vsync_te_vfb : 16; /* [15..0] */ + unsigned int vsync_te_width : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_dhd2_vsync_te_state1; + +/* Define the union u_intf2_dither_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_tap_mode : 2; /* [1..0] */ + unsigned int dither_domain_mode : 1; /* [2] */ + unsigned int dither_round : 1; /* [3] */ + unsigned int dither_mode : 1; /* [4] */ + unsigned int dither_en : 1; /* [5] */ + unsigned int dither_round_unlim : 1; /* [6] */ + unsigned int i_data_width_dither : 3; /* [9..7] */ + unsigned int o_data_width_dither : 3; /* [12..10] */ + unsigned int reserved_0 : 19; /* [31..13] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf2_dither_ctrl; + +/* Define the union u_intf2_dither_sed_y0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_y0 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf2_dither_sed_y0; + +/* Define the union u_intf2_dither_sed_u0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_u0 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf2_dither_sed_u0; + +/* Define the union u_intf2_dither_sed_v0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_v0 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf2_dither_sed_v0; + +/* Define the union u_intf2_dither_sed_w0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_w0 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf2_dither_sed_w0; + +/* Define the union u_intf2_dither_sed_y1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_y1 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf2_dither_sed_y1; + +/* Define the union u_intf2_dither_sed_u1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_u1 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf2_dither_sed_u1; + +/* Define the union u_intf2_dither_sed_v1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_v1 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf2_dither_sed_v1; + +/* Define the union u_intf2_dither_sed_w1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_w1 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf2_dither_sed_w1; + +/* Define the union u_intf2_dither_sed_y2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_y2 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf2_dither_sed_y2; + +/* Define the union u_intf2_dither_sed_u2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_u2 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf2_dither_sed_u2; + +/* Define the union u_intf2_dither_sed_v2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_v2 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf2_dither_sed_v2; + +/* Define the union u_intf2_dither_sed_w2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_w2 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf2_dither_sed_w2; + +/* Define the union u_intf2_dither_sed_y3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_y3 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf2_dither_sed_y3; + +/* Define the union u_intf2_dither_sed_u3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_u3 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf2_dither_sed_u3; + +/* Define the union u_intf2_dither_sed_v3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_v3 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf2_dither_sed_v3; + +/* Define the union u_intf2_dither_sed_w3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_sed_w3 : 31; /* [30..0] */ + unsigned int reserved_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf2_dither_sed_w3; + +/* Define the union u_intf2_dither_thr */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dither_thr_min : 16; /* [15..0] */ + unsigned int dither_thr_max : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_intf2_dither_thr; + +/* Define the union u_date_coeff0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int tt_seq : 1; /* [0] */ + unsigned int chgain_en : 1; /* [1] */ + unsigned int sylp_en : 1; /* [2] */ + unsigned int chlp_en : 1; /* [3] */ + unsigned int oversam2_en : 1; /* [4] */ + unsigned int lunt_en : 1; /* [5] */ + unsigned int oversam_en : 2; /* [7..6] */ + unsigned int reserved_0 : 1; /* [8] */ + unsigned int luma_dl : 4; /* [12..9] */ + unsigned int agc_amp_sel : 1; /* [13] */ + unsigned int length_sel : 1; /* [14] */ + unsigned int sync_mode_scart : 1; /* [15] */ + unsigned int sync_mode_sel : 2; /* [17..16] */ + unsigned int style_sel : 4; /* [21..18] */ + unsigned int fm_sel : 1; /* [22] */ + unsigned int vbi_lpf_en : 1; /* [23] */ + unsigned int rgb_en : 1; /* [24] */ + unsigned int scanline : 1; /* [25] */ + unsigned int pbpr_lpf_en : 1; /* [26] */ + unsigned int pal_half_en : 1; /* [27] */ + unsigned int reserved_1 : 1; /* [28] */ + unsigned int dis_ire : 1; /* [29] */ + unsigned int clpf_sel : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff0; + +/* Define the union u_date_coeff1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dac_test : 10; /* [9..0] */ + unsigned int date_test_mode : 2; /* [11..10] */ + unsigned int date_test_en : 1; /* [12] */ + unsigned int amp_outside : 10; /* [22..13] */ + unsigned int c_limit_en : 1; /* [23] */ + unsigned int cc_seq : 1; /* [24] */ + unsigned int cgms_seq : 1; /* [25] */ + unsigned int vps_seq : 1; /* [26] */ + unsigned int wss_seq : 1; /* [27] */ + unsigned int cvbs_limit_en : 1; /* [28] */ + unsigned int c_gain : 3; /* [31..29] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff1; + +/* Define the union u_date_coeff3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int coef03 : 26; /* [25..0] */ + unsigned int reserved_0 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff3; + +/* Define the union u_date_coeff4 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int coef04 : 30; /* [29..0] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff4; + +/* Define the union u_date_coeff5 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int coef05 : 29; /* [28..0] */ + unsigned int reserved_0 : 3; /* [31..29] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff5; + +/* Define the union u_date_coeff6 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int coef06_1 : 23; /* [22..0] */ + unsigned int reserved_0 : 8; /* [30..23] */ + unsigned int coef06_0 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff6; + +/* Define the union u_date_coeff7 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int tt07_enf2 : 1; /* [0] */ + unsigned int tt08_enf2 : 1; /* [1] */ + unsigned int tt09_enf2 : 1; /* [2] */ + unsigned int tt10_enf2 : 1; /* [3] */ + unsigned int tt11_enf2 : 1; /* [4] */ + unsigned int tt12_enf2 : 1; /* [5] */ + unsigned int tt13_enf2 : 1; /* [6] */ + unsigned int tt14_enf2 : 1; /* [7] */ + unsigned int tt15_enf2 : 1; /* [8] */ + unsigned int tt16_enf2 : 1; /* [9] */ + unsigned int tt17_enf2 : 1; /* [10] */ + unsigned int tt18_enf2 : 1; /* [11] */ + unsigned int tt19_enf2 : 1; /* [12] */ + unsigned int tt20_enf2 : 1; /* [13] */ + unsigned int tt21_enf2 : 1; /* [14] */ + unsigned int tt22_enf2 : 1; /* [15] */ + unsigned int tt07_enf1 : 1; /* [16] */ + unsigned int tt08_enf1 : 1; /* [17] */ + unsigned int tt09_enf1 : 1; /* [18] */ + unsigned int tt10_enf1 : 1; /* [19] */ + unsigned int tt11_enf1 : 1; /* [20] */ + unsigned int tt12_enf1 : 1; /* [21] */ + unsigned int tt13_enf1 : 1; /* [22] */ + unsigned int tt14_enf1 : 1; /* [23] */ + unsigned int tt15_enf1 : 1; /* [24] */ + unsigned int tt16_enf1 : 1; /* [25] */ + unsigned int tt17_enf1 : 1; /* [26] */ + unsigned int tt18_enf1 : 1; /* [27] */ + unsigned int tt19_enf1 : 1; /* [28] */ + unsigned int tt20_enf1 : 1; /* [29] */ + unsigned int tt21_enf1 : 1; /* [30] */ + unsigned int tt22_enf1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff7; + +/* Define the union u_date_coeff10 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int tt_pktoff : 8; /* [7..0] */ + unsigned int tt_mode : 2; /* [9..8] */ + unsigned int tt_highest : 1; /* [10] */ + unsigned int full_page : 1; /* [11] */ + unsigned int nabts_100ire : 1; /* [12] */ + unsigned int reserved_0 : 18; /* [30..13] */ + unsigned int tt_ready : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff10; + +/* Define the union u_date_coeff11 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int date_clf2 : 10; /* [9..0] */ + unsigned int date_clf1 : 10; /* [19..10] */ + unsigned int cc_enf2 : 1; /* [20] */ + unsigned int cc_enf1 : 1; /* [21] */ + unsigned int reserved_0 : 10; /* [31..22] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff11; + +/* Define the union u_date_coeff12 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cc_f2data : 16; /* [15..0] */ + unsigned int cc_f1data : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff12; + +/* Define the union u_date_coeff13 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cg_f1data : 20; /* [19..0] */ + unsigned int cg_enf2 : 1; /* [20] */ + unsigned int cg_enf1 : 1; /* [21] */ + unsigned int reserved_0 : 10; /* [31..22] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff13; + +/* Define the union u_date_coeff14 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cg_f2data : 20; /* [19..0] */ + unsigned int reserved_0 : 12; /* [31..20] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff14; + +/* Define the union u_date_coeff15 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int wss_data : 14; /* [13..0] */ + unsigned int wss_en : 1; /* [14] */ + unsigned int reserved_0 : 17; /* [31..15] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff15; + +/* Define the union u_date_coeff16 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vps_data : 24; /* [23..0] */ + unsigned int vps_en : 1; /* [24] */ + unsigned int reserved_0 : 7; /* [31..25] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff16; + +/* Define the union u_date_coeff19 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vps_data : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff19; + +/* Define the union u_date_coeff20 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int tt05_enf2 : 1; /* [0] */ + unsigned int tt06_enf2 : 1; /* [1] */ + unsigned int tt06_enf1 : 1; /* [2] */ + unsigned int reserved_0 : 29; /* [31..3] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff20; + +/* Define the union u_date_coeff21 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dac0_in_sel : 3; /* [2..0] */ + unsigned int reserved_0 : 1; /* [3] */ + unsigned int dac1_in_sel : 3; /* [6..4] */ + unsigned int reserved_1 : 1; /* [7] */ + unsigned int dac2_in_sel : 3; /* [10..8] */ + unsigned int reserved_2 : 1; /* [11] */ + unsigned int dac3_in_sel : 3; /* [14..12] */ + unsigned int reserved_3 : 1; /* [15] */ + unsigned int dac4_in_sel : 3; /* [18..16] */ + unsigned int reserved_4 : 1; /* [19] */ + unsigned int dac5_in_sel : 3; /* [22..20] */ + unsigned int reserved_5 : 9; /* [31..23] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff21; + +/* Define the union u_date_coeff22 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int video_phase_delta : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff22; + +/* Define the union u_date_coeff23 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dac0_out_dly : 3; /* [2..0] */ + unsigned int reserved_0 : 1; /* [3] */ + unsigned int dac1_out_dly : 3; /* [6..4] */ + unsigned int reserved_1 : 1; /* [7] */ + unsigned int dac2_out_dly : 3; /* [10..8] */ + unsigned int reserved_2 : 1; /* [11] */ + unsigned int dac3_out_dly : 3; /* [14..12] */ + unsigned int reserved_3 : 1; /* [15] */ + unsigned int dac4_out_dly : 3; /* [18..16] */ + unsigned int reserved_4 : 1; /* [19] */ + unsigned int dac5_out_dly : 3; /* [22..20] */ + unsigned int reserved_5 : 9; /* [31..23] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff23; + +/* Define the union u_date_coeff25 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int x_n_coef : 13; /* [12..0] */ + unsigned int reserved_0 : 3; /* [15..13] */ + unsigned int x_n_1_coef : 13; /* [28..16] */ + unsigned int reserved_1 : 3; /* [31..29] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff25; + +/* Define the union u_date_coeff26 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int x_n_1_coef : 13; /* [12..0] */ + unsigned int reserved_0 : 19; /* [31..13] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff26; + +/* Define the union u_date_coeff27 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int y_n_coef : 11; /* [10..0] */ + unsigned int reserved_0 : 5; /* [15..11] */ + unsigned int y_n_1_coef : 11; /* [26..16] */ + unsigned int reserved_1 : 5; /* [31..27] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff27; + +/* Define the union u_date_coeff28 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int pixel_begin1 : 11; /* [10..0] */ + unsigned int reserved_0 : 5; /* [15..11] */ + unsigned int pixel_begin2 : 11; /* [26..16] */ + unsigned int reserved_1 : 5; /* [31..27] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff28; + +/* Define the union u_date_coeff29 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int pixel_end : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff29; + +/* Define the union u_date_coeff30 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int g_secam : 7; /* [6..0] */ + unsigned int reserved_0 : 25; /* [31..7] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff30; + +/* Define the union u_date_isrmask */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int tt_mask : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_isrmask; + +/* Define the union u_date_isrstate */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int tt_status : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_isrstate; + +/* Define the union u_date_isr */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int tt_int : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_isr; + +/* Define the union u_date_coeff37 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int fir_y1_coeff0 : 8; /* [7..0] */ + unsigned int fir_y1_coeff1 : 8; /* [15..8] */ + unsigned int fir_y1_coeff2 : 8; /* [23..16] */ + unsigned int fir_y1_coeff3 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff37; + +/* Define the union u_date_coeff38 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int fir_y2_coeff0 : 16; /* [15..0] */ + unsigned int fir_y2_coeff1 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff38; + +/* Define the union u_date_coeff39 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int fir_y2_coeff2 : 16; /* [15..0] */ + unsigned int fir_y2_coeff3 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff39; + +/* Define the union u_date_coeff40 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int fir_c1_coeff0 : 8; /* [7..0] */ + unsigned int fir_c1_coeff1 : 8; /* [15..8] */ + unsigned int fir_c1_coeff2 : 8; /* [23..16] */ + unsigned int fir_c1_coeff3 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff40; + +/* Define the union u_date_coeff41 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int fir_c2_coeff0 : 16; /* [15..0] */ + unsigned int fir_c2_coeff1 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff41; + +/* Define the union u_date_coeff42 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int fir_c2_coeff2 : 16; /* [15..0] */ + unsigned int fir_c2_coeff3 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff42; + +/* Define the union u_date_dacdet1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vdac_det_high : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int det_line : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_dacdet1; + +/* Define the union u_date_dacdet2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int det_pixel_sta : 11; /* [10..0] */ + unsigned int reserved_0 : 5; /* [15..11] */ + unsigned int det_pixel_wid : 11; /* [26..16] */ + unsigned int reserved_1 : 4; /* [30..27] */ + unsigned int vdac_det_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_dacdet2; + +/* Define the union u_date_coeff50 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ovs_coeff0 : 11; /* [10..0] */ + unsigned int reserved_0 : 5; /* [15..11] */ + unsigned int ovs_coeff1 : 11; /* [26..16] */ + unsigned int reserved_1 : 5; /* [31..27] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff50; + +/* Define the union u_date_coeff51 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ovs_coeff0 : 11; /* [10..0] */ + unsigned int reserved_0 : 5; /* [15..11] */ + unsigned int ovs_coeff1 : 11; /* [26..16] */ + unsigned int reserved_1 : 5; /* [31..27] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff51; + +/* Define the union u_date_coeff52 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ovs_coeff0 : 11; /* [10..0] */ + unsigned int reserved_0 : 5; /* [15..11] */ + unsigned int ovs_coeff1 : 11; /* [26..16] */ + unsigned int reserved_1 : 5; /* [31..27] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff52; + +/* Define the union u_date_coeff53 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ovs_coeff0 : 11; /* [10..0] */ + unsigned int reserved_0 : 5; /* [15..11] */ + unsigned int ovs_coeff1 : 11; /* [26..16] */ + unsigned int reserved_1 : 5; /* [31..27] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff53; + +/* Define the union u_date_coeff54 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ovs_coeff0 : 11; /* [10..0] */ + unsigned int reserved_0 : 5; /* [15..11] */ + unsigned int ovs_coeff1 : 11; /* [26..16] */ + unsigned int reserved_1 : 5; /* [31..27] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff54; + +/* Define the union u_date_coeff55 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ovs_coeff0 : 11; /* [10..0] */ + unsigned int reserved_0 : 5; /* [15..11] */ + unsigned int ovs_coeff1 : 11; /* [26..16] */ + unsigned int reserved_1 : 5; /* [31..27] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_date_coeff55; + +/* Define the union u_mac_outstanding */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mstr0_routstanding : 4; /* [3..0] */ + unsigned int mstr0_woutstanding : 4; /* [7..4] */ + unsigned int mstr1_routstanding : 4; /* [11..8] */ + unsigned int mstr1_woutstanding : 4; /* [15..12] */ + unsigned int mstr2_routstanding : 4; /* [19..16] */ + unsigned int mstr2_woutstanding : 4; /* [23..20] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_mac_outstanding; + +/* Define the union u_mac_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int split_mode : 4; /* [3..0] */ + unsigned int arb_mode : 4; /* [7..4] */ + unsigned int mid_enable : 1; /* [8] */ + unsigned int reserved_0 : 3; /* [11..9] */ + unsigned int wport_sel : 4; /* [15..12] */ + unsigned int reserved_1 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_mac_ctrl; + +/* Define the union u_mac_rchn_prio */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int para_prio : 1; /* [0] */ + unsigned int v0l_prio : 1; /* [1] */ + unsigned int v0c_prio : 1; /* [2] */ + unsigned int v0lh_prio : 1; /* [3] */ + unsigned int v0ch_prio : 1; /* [4] */ + unsigned int v1l_prio : 1; /* [5] */ + unsigned int v1c_prio : 1; /* [6] */ + unsigned int v1lh_prio : 1; /* [7] */ + unsigned int v1ch_prio : 1; /* [8] */ + unsigned int g0ar_prio : 1; /* [9] */ + unsigned int g0gb_prio : 1; /* [10] */ + unsigned int g1ar_prio : 1; /* [11] */ + unsigned int g1gb_prio : 1; /* [12] */ + unsigned int v2l_prio : 1; /* [13] */ + unsigned int v2c_prio : 1; /* [14] */ + unsigned int v2lh_prio : 1; /* [15] */ + unsigned int v2ch_prio : 1; /* [16] */ + unsigned int g3ar_prio : 1; /* [17] */ + unsigned int g3gb_prio : 1; /* [18] */ + unsigned int reserved_0 : 13; /* [31..19] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_mac_rchn_prio; + +/* Define the union u_mac_wchn_prio */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int wbcl_prio : 1; /* [0] */ + unsigned int wbcc_prio : 1; /* [1] */ + unsigned int wbclh_prio : 1; /* [2] */ + unsigned int wbcch_prio : 1; /* [3] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_mac_wchn_prio; + +/* Define the union u_mac_rchn_sel0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int para_sel : 2; /* [1..0] */ + unsigned int v0l_sel : 2; /* [3..2] */ + unsigned int v0c_sel : 2; /* [5..4] */ + unsigned int v0lh_sel : 2; /* [7..6] */ + unsigned int v0ch_sel : 2; /* [9..8] */ + unsigned int v1l_sel : 2; /* [11..10] */ + unsigned int v1c_sel : 2; /* [13..12] */ + unsigned int v1lh_sel : 2; /* [15..14] */ + unsigned int v1ch_sel : 2; /* [17..16] */ + unsigned int g0ar_sel : 2; /* [19..18] */ + unsigned int g0gb_sel : 2; /* [21..20] */ + unsigned int g1ar_sel : 2; /* [23..22] */ + unsigned int g1gb_sel : 2; /* [25..24] */ + unsigned int v2_sel : 2; /* [27..26] */ + unsigned int g3_sel : 2; /* [29..28] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_mac_rchn_sel0; + +/* Define the union u_mac_wchn_sel0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int wbcl_sel : 2; /* [1..0] */ + unsigned int wbcc_sel : 2; /* [3..2] */ + unsigned int wbclh_sel : 2; /* [5..4] */ + unsigned int wbcch_sel : 2; /* [7..6] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_mac_wchn_sel0; + +/* Define the union u_mac_bus_err_clr */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int bus_error_clr : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_mac_bus_err_clr; + +/* Define the union u_mac_bus_err */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mst0_r_error : 1; /* [0] */ + unsigned int mst0_w_error : 1; /* [1] */ + unsigned int mst1_r_error : 1; /* [2] */ + unsigned int mst1_w_error : 1; /* [3] */ + unsigned int mst2_r_error : 1; /* [4] */ + unsigned int mst2_w_error : 1; /* [5] */ + unsigned int reserved_0 : 26; /* [31..6] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_mac_bus_err; + +/* Define the union u_mac_debug_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int axi_det_enable : 1; /* [0] */ + unsigned int reserved_0 : 3; /* [3..1] */ + unsigned int fifo_det_mode : 4; /* [7..4] */ + unsigned int reserved_1 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_mac_debug_ctrl; + +/* Define the union u_mac_debug_clr */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int axi_det_clr : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_mac_debug_clr; + +/* Define the union u_vid_read_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int chm_rmode : 3; /* [2..0] */ + unsigned int reserved_0 : 1; /* [3] */ + unsigned int lm_rmode : 3; /* [6..4] */ + unsigned int reserved_1 : 1; /* [7] */ + unsigned int chm_draw_mode : 2; /* [9..8] */ + unsigned int lm_draw_mode : 2; /* [11..10] */ + unsigned int flip_en : 1; /* [12] */ + unsigned int chm_copy_en : 1; /* [13] */ + unsigned int reserved_2 : 2; /* [15..14] */ + unsigned int mute_en : 1; /* [16] */ + unsigned int mute_req_en : 1; /* [17] */ + unsigned int vicap_mute_en : 1; /* [18] */ + unsigned int mrg_enable : 1; /* [19] */ + unsigned int mrg_mute_mode : 1; /* [20] */ + unsigned int fdr_ck_gt_en : 1; /* [21] */ + unsigned int reserved_3 : 10; /* [31..22] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vid_read_ctrl; + +/* Define the union u_vid_mac_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int req_ctrl : 2; /* [1..0] */ + unsigned int req_len : 2; /* [3..2] */ + unsigned int reserved_0 : 4; /* [7..4] */ + unsigned int ofl_master : 1; /* [8] */ + unsigned int reserved_1 : 22; /* [30..9] */ + unsigned int pre_rd_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vid_mac_ctrl; + +/* Define the union u_vid_out_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int draw_pixel_mode : 3; /* [2..0] */ + unsigned int draw_pixel_en : 1; /* [3] */ + unsigned int uv_order_en : 1; /* [4] */ + unsigned int single_port_mode : 1; /* [5] */ + unsigned int testpattern_en : 1; /* [6] */ + unsigned int reserved_0 : 25; /* [31..7] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vid_out_ctrl; + +/* Define the union u_vid_mute_alpha */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mute_alpha : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vid_mute_alpha; + +/* Define the union u_vid_mute_bk */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mute_cr : 10; /* [9..0] */ + unsigned int mute_cb : 10; /* [19..10] */ + unsigned int mute_y : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vid_mute_bk; + +/* Define the union u_vid_src_info */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int data_type : 3; /* [2..0] */ + unsigned int data_fmt : 2; /* [4..3] */ + unsigned int reserved_0 : 3; /* [7..5] */ + unsigned int data_width : 2; /* [9..8] */ + unsigned int reserved_1 : 2; /* [11..10] */ + unsigned int field_type : 1; /* [12] */ + unsigned int reserved_2 : 3; /* [15..13] */ + unsigned int disp_mode : 4; /* [19..16] */ + unsigned int dcmp_en : 2; /* [21..20] */ + unsigned int reserved_3 : 10; /* [31..22] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vid_src_info; + +/* Define the union u_vid_src_reso */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int src_w : 16; /* [15..0] */ + unsigned int src_h : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vid_src_reso; + +/* Define the union u_vid_src_crop */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int src_crop_x : 16; /* [15..0] */ + unsigned int src_crop_y : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vid_src_crop; + +/* Define the union u_vid_in_reso */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ireso_w : 16; /* [15..0] */ + unsigned int ireso_h : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vid_in_reso; + +/* Define the union u_vid_stride */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int lm_stride : 16; /* [15..0] */ + unsigned int chm_stride : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vid_stride; + +/* Define the union u_vid_2bit_stride */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int lm_tile_stride : 16; /* [15..0] */ + unsigned int chm_tile_stride : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vid_2bit_stride; + +/* Define the union u_vid_head_stride */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int lm_head_stride : 16; /* [15..0] */ + unsigned int chm_head_stride : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vid_head_stride; + +/* Define the union u_vid_smmu_bypass */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int lm_bypass_2d : 1; /* [0] */ + unsigned int chm_bypass_2d : 1; /* [1] */ + unsigned int lm_bypass_3d : 1; /* [2] */ + unsigned int chm_bypass_3d : 1; /* [3] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vid_smmu_bypass; + +/* Define the union u_vid_testpat_cfg */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int tp_speed : 10; /* [9..0] */ + unsigned int reserved_0 : 2; /* [11..10] */ + unsigned int tp_line_w : 1; /* [12] */ + unsigned int tp_color_mode : 1; /* [13] */ + unsigned int reserved_1 : 2; /* [15..14] */ + unsigned int tp_mode : 2; /* [17..16] */ + unsigned int reserved_2 : 14; /* [31..18] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vid_testpat_cfg; + +/* Define the union u_vid_testpat_seed */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int tp_seed : 30; /* [29..0] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vid_testpat_seed; + +/* Define the union u_vid_dcmp_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int c_is_lossless : 1; /* [0] */ + unsigned int l_is_lossless : 1; /* [1] */ + unsigned int c_cmp_mode : 1; /* [2] */ + unsigned int l_cmp_mode : 1; /* [3] */ + unsigned int c_cmp_rate : 2; /* [5..4] */ + unsigned int l_cmp_rate : 2; /* [7..6] */ + unsigned int mem_mode : 1; /* [8] */ + unsigned int reserved_0 : 23; /* [31..9] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vid_dcmp_ctrl; + +/* Define the union u_vdp_v3r2_lineseg_dcmp_glb_info */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ice_en : 1; /* [0] */ + unsigned int is_lossless : 1; /* [1] */ + unsigned int cmp_mode : 1; /* [2] */ + unsigned int max_mb_qp_y : 3; /* [5..3] */ + unsigned int reserved_0 : 10; /* [15..6] */ + unsigned int max_mb_qp_c : 3; /* [18..16] */ + unsigned int seg_en : 1; /* [19] */ + unsigned int bit_depth : 1; /* [20] */ + unsigned int reserved_1 : 11; /* [31..21] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vdp_v3r2_lineseg_dcmp_glb_info; + +/* Define the union u_vdp_v3r2_lineseg_dcmp_frame_size */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int frame_height : 14; /* [13..0] */ + unsigned int reserved_0 : 2; /* [15..14] */ + unsigned int frame_width : 14; /* [29..16] */ + unsigned int reserved_1 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vdp_v3r2_lineseg_dcmp_frame_size; + +/* Define the union u_vdp_v3r2_lineseg_dcmp_smth_deltabits_thr */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int smooth_deltabits_thr : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vdp_v3r2_lineseg_dcmp_smth_deltabits_thr; + +/* Define the union u_vdp_v3r2_lineseg_dcmp_error_sta */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dcmp_error : 1; /* [0] */ + unsigned int forgive : 1; /* [1] */ + unsigned int consume : 1; /* [2] */ + unsigned int reserved_0 : 29; /* [31..3] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vdp_v3r2_lineseg_dcmp_error_sta; + +/* Define the union u_vdp_v3r2_lineseg_dcmp_glb_info_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ice_en : 1; /* [0] */ + unsigned int is_lossless : 1; /* [1] */ + unsigned int cmp_mode : 1; /* [2] */ + unsigned int max_mb_qp_y : 3; /* [5..3] */ + unsigned int reserved_0 : 10; /* [15..6] */ + unsigned int max_mb_qp_c : 3; /* [18..16] */ + unsigned int seg_en : 1; /* [19] */ + unsigned int bit_depth : 1; /* [20] */ + unsigned int reserved_1 : 11; /* [31..21] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vdp_v3r2_lineseg_dcmp_glb_info_c; + +/* Define the union u_vdp_v3r2_lineseg_dcmp_frame_size_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int frame_height : 14; /* [13..0] */ + unsigned int reserved_0 : 2; /* [15..14] */ + unsigned int frame_width : 14; /* [29..16] */ + unsigned int reserved_1 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vdp_v3r2_lineseg_dcmp_frame_size_c; + +/* Define the union u_vdp_v3r2_lineseg_dcmp_smth_deltabits_thr_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int smooth_deltabits_thr : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vdp_v3r2_lineseg_dcmp_smth_deltabits_thr_c; + +/* Define the union u_vdp_v3r2_lineseg_dcmp_error_sta_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dcmp_error : 1; /* [0] */ + unsigned int forgive : 1; /* [1] */ + unsigned int consume : 1; /* [2] */ + unsigned int reserved_0 : 29; /* [31..3] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vdp_v3r2_lineseg_dcmp_error_sta_c; + +/* Define the union u_gfx_read_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int read_mode : 2; /* [1..0] */ + unsigned int reserved_0 : 2; /* [3..2] */ + unsigned int draw_mode : 2; /* [5..4] */ + unsigned int reserved_1 : 2; /* [7..6] */ + unsigned int flip_en : 1; /* [8] */ + unsigned int reserved_2 : 1; /* [9] */ + unsigned int mute_en : 1; /* [10] */ + unsigned int mute_req_en : 1; /* [11] */ + unsigned int fdr_ck_gt_en : 1; /* [12] */ + unsigned int reserved_3 : 19; /* [31..13] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gfx_read_ctrl; + +/* Define the union u_gfx_mac_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int req_ctrl : 2; /* [1..0] */ + unsigned int req_len : 2; /* [3..2] */ + unsigned int reserved_0 : 4; /* [7..4] */ + unsigned int ofl_master : 1; /* [8] */ + unsigned int dcmp_thd_close : 1; /* [9] */ + unsigned int dcmp_mute_ctrl : 1; /* [10] */ + unsigned int reserved_1 : 13; /* [23..11] */ + unsigned int req_ld_mode : 2; /* [25..24] */ + unsigned int reserved_2 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gfx_mac_ctrl; + +/* Define the union u_gfx_out_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int palpha_range : 1; /* [0] */ + unsigned int palpha_en : 1; /* [1] */ + unsigned int reserved_0 : 2; /* [3..2] */ + unsigned int key_mode : 1; /* [4] */ + unsigned int enable : 1; /* [5] */ + unsigned int reserved_1 : 2; /* [7..6] */ + unsigned int bitext : 2; /* [9..8] */ + unsigned int premulti_en : 1; /* [10] */ + unsigned int testpattern_en : 1; /* [11] */ + unsigned int reserved_2 : 20; /* [31..12] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gfx_out_ctrl; + +/* Define the union u_gfx_mute_alpha */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mute_alpha : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gfx_mute_alpha; + +/* Define the union u_gfx_mute_bk */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mute_cr : 10; /* [9..0] */ + unsigned int mute_cb : 10; /* [19..10] */ + unsigned int mute_y : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gfx_mute_bk; + +/* Define the union u_gfx_smmu_bypass */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int smmu_bypass_2d : 1; /* [0] */ + unsigned int smmu_bypass_3d : 1; /* [1] */ + unsigned int reserved_0 : 30; /* [31..2] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gfx_smmu_bypass; + +/* Define the union u_gfx_1555_alpha */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int alpha_0 : 8; /* [7..0] */ + unsigned int alpha_1 : 8; /* [15..8] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gfx_1555_alpha; + +/* Define the union u_gfx_src_info */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ifmt : 8; /* [7..0] */ + unsigned int reserved_0 : 8; /* [15..8] */ + unsigned int disp_mode : 4; /* [19..16] */ + unsigned int dcmp_en : 1; /* [20] */ + unsigned int reserved_1 : 11; /* [31..21] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gfx_src_info; + +/* Define the union u_gfx_src_reso */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int src_w : 16; /* [15..0] */ + unsigned int src_h : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gfx_src_reso; + +/* Define the union u_gfx_src_crop */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int src_crop_x : 16; /* [15..0] */ + unsigned int src_crop_y : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gfx_src_crop; + +/* Define the union u_gfx_ireso */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ireso_w : 16; /* [15..0] */ + unsigned int ireso_h : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gfx_ireso; + +/* Define the union u_gfx_stride */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int surface_stride : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gfx_stride; + +/* Define the union u_gfx_ckey_max */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int key_b_max : 8; /* [7..0] */ + unsigned int key_g_max : 8; /* [15..8] */ + unsigned int key_r_max : 8; /* [23..16] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gfx_ckey_max; + +/* Define the union u_gfx_ckey_min */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int key_b_min : 8; /* [7..0] */ + unsigned int key_g_min : 8; /* [15..8] */ + unsigned int key_r_min : 8; /* [23..16] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gfx_ckey_min; + +/* Define the union u_gfx_ckey_mask */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int key_b_msk : 8; /* [7..0] */ + unsigned int key_g_msk : 8; /* [15..8] */ + unsigned int key_r_msk : 8; /* [23..16] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gfx_ckey_mask; + +/* Define the union u_gfx_testpat_cfg */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int tp_speed : 10; /* [9..0] */ + unsigned int reserved_0 : 2; /* [11..10] */ + unsigned int tp_line_w : 1; /* [12] */ + unsigned int tp_color_mode : 1; /* [13] */ + unsigned int reserved_1 : 2; /* [15..14] */ + unsigned int tp_mode : 2; /* [17..16] */ + unsigned int reserved_2 : 14; /* [31..18] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gfx_testpat_cfg; + +/* Define the union u_gfx_testpat_seed */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int tp_seed : 30; /* [29..0] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gfx_testpat_seed; + +/* Define the union u_gfx_ld_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 1; /* [0] */ + unsigned int hw_mute_clr : 1; /* [1] */ + unsigned int ld_mute_en : 1; /* [2] */ + unsigned int ld_err_mute_en : 1; /* [3] */ + unsigned int reserved_1 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gfx_ld_ctrl; + +/* Define the union u_gfx_ld_smute_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved : 31; /* [30..0] */ + unsigned int sw_mute_clr : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gfx_ld_smute_ctrl; + +/* Define the union u_gfx_ld_err_sta */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ld_err_clr : 1; /* [0] */ + unsigned int reserved : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gfx_ld_err_sta; + +#ifdef CONFIG_TDE_GFBG_COMPRESS_V1 +/* Define the union u_gfx_dcmp_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int is_lossless : 1; /* [0] */ + unsigned int is_lossless_a : 1; /* [1] */ + unsigned int cmp_mode : 1; /* [2] */ + unsigned int osd_mode : 2; /* [4..3] */ + unsigned int reserved_0 : 27; /* [31..5] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gfx_dcmp_ctrl; + +/* Define the union u_gfx_dcmp_wrong_sta */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int bs_err : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gfx_dcmp_wrong_sta; +#endif /* CONFIG_TDE_GFBG_COMPRESS_V1 */ + +#ifdef CONFIG_TDE_GFBG_COMPRESS_V2 +/* define the union reg_vdp_v3r2_line_osd_dcmp_glb_info */ +typedef union { + /* define the struct bits */ + struct { + unsigned int ice_en : 1; /* [0] */ + unsigned int cmp_mode : 1; /* [1] */ + unsigned int conv_en : 1; /* [2] */ + unsigned int is_lossless : 1; /* [3] */ + unsigned int osd_mode : 2; /* [5..4] */ + unsigned int max_mb_qp : 3; /* [8..6] */ + unsigned int excess_err_mask : 1; /* [9] */ + unsigned int rw_reg_add : 6; /* [15..10] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} u_vdp_v3r2_line_osd_dcmp_glb_info; + +/* define the union reg_vdp_v3r2_line_osd_dcmp_frame_size */ +typedef union { + /* define the struct bits */ + struct { + unsigned int frame_width : 14; /* [13..0] */ + unsigned int reserved_0 : 2; /* [15..14] */ + unsigned int frame_height : 14; /* [29..16] */ + unsigned int reserved_1 : 2; /* [31..30] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} u_vdp_v3r2_line_osd_dcmp_frame_size; + +/* define the union reg_vdp_v3r2_line_osd_dcmp_error_sta */ +typedef union { + /* define the struct bits */ + struct { + unsigned int dcmp_error : 1; /* [0] */ + unsigned int o_pix_forgive : 1; /* [1] */ + unsigned int o_pix_consume : 1; /* [2] */ + unsigned int o_mb_qp_error : 1; /* [3] */ + unsigned int o_dcmp_excess_err : 1; /* [4] */ + unsigned int o_dcmp_err_add : 5; /* [9..5] */ + unsigned int o_dcmp_debug : 22; /* [31..10] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} u_vdp_v3r2_line_osd_dcmp_error_sta; +#endif /* CONFIG_TDE_GFBG_COMPRESS_V2 */ + +/* Define the union u_wbc_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 4; /* [3..0] */ + unsigned int data_width : 1; /* [4] */ + unsigned int reserved_1 : 3; /* [7..5] */ + unsigned int uv_order : 1; /* [8] */ + unsigned int flip_en : 1; /* [9] */ + unsigned int align_mode : 1; /* [10] */ + unsigned int reserved_2 : 3; /* [13..11] */ + unsigned int cap_ck_gt_en : 1; /* [14] */ + unsigned int reserved_3 : 14; /* [28..15] */ + unsigned int wbc_cmp_en : 1; /* [29] */ + unsigned int reserved_4 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_ctrl; + +/* Define the union u_wbc_mac_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int req_interval : 10; /* [9..0] */ + unsigned int reserved_0 : 2; /* [11..10] */ + unsigned int wbc_len : 2; /* [13..12] */ + unsigned int reserved_1 : 18; /* [31..14] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_mac_ctrl; + +/* Define the union u_wbc_smmu_bypass */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int l_bypass : 1; /* [0] */ + unsigned int c_bypass : 1; /* [1] */ + unsigned int reserved_0 : 30; /* [31..2] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_smmu_bypass; + +/* Define the union u_wbc_lowdlyctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int wb_per_line_num : 12; /* [11..0] */ + unsigned int partfns_line_num : 12; /* [23..12] */ + unsigned int reserved_0 : 6; /* [29..24] */ + unsigned int lowdly_test : 1; /* [30] */ + unsigned int lowdly_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_lowdlyctrl; + +/* Define the union u_wbc_lowdlysta */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 31; /* [30..0] */ + unsigned int part_finish : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_lowdlysta; + +/* Define the union u_wbc_ystride */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int wbc_ystride : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_ystride; + +/* Define the union u_wbc_cstride */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int wbc_cstride : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_cstride; + +/* Define the union u_wbc_ynstride */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int wbc_ynstride : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_ynstride; + +/* Define the union u_wbc_cnstride */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int wbc_cnstride : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_cnstride; + +/* Define the union u_wbc_sta */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int wbc_l_busy : 1; /* [0] */ + unsigned int wbc_c_busy : 1; /* [1] */ + unsigned int wbc_lh_busy : 1; /* [2] */ + unsigned int wbc_ch_busy : 1; /* [3] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_sta; + +/* Define the union u_wbc_line_num */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int wbc_l_linenum : 16; /* [15..0] */ + unsigned int wbc_c_linenum : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_line_num; + +/* Define the union u_wbc_cap_reso */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cap_width : 16; /* [15..0] */ + unsigned int cap_height : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_cap_reso; + +/* Define the union u_vdp_v3r2_lineseg_cmp_glb_info */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ice_en : 1; /* [0] */ + unsigned int cmp_mode : 1; /* [1] */ + unsigned int is_lossless : 1; /* [2] */ + unsigned int chroma_en : 1; /* [3] */ + unsigned int esl_qp : 3; /* [6..4] */ + unsigned int bit_depth : 1; /* [7] */ + unsigned int mirror_en : 1; /* [8] */ + unsigned int seg_en : 1; /* [9] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vdp_v3r2_lineseg_cmp_glb_info; + +/* Define the union u_vdp_v3r2_lineseg_cmp_frame_size */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int frame_width : 14; /* [13..0] */ + unsigned int reserved_0 : 2; /* [15..14] */ + unsigned int frame_height : 14; /* [29..16] */ + unsigned int reserved_1 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vdp_v3r2_lineseg_cmp_frame_size; + +/* Define the union u_vdp_v3r2_lineseg_cmp_rc_cfg0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int big_grad_thr : 8; /* [7..0] */ + unsigned int diff_thr : 8; /* [15..8] */ + unsigned int noise_pix_num_thr : 6; /* [21..16] */ + unsigned int reserved_0 : 10; /* [31..22] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vdp_v3r2_lineseg_cmp_rc_cfg0; + +/* Define the union u_vdp_v3r2_lineseg_cmp_rc_cfg1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int qp_inc1_bits_thr : 8; /* [7..0] */ + unsigned int qp_inc2_bits_thr : 8; /* [15..8] */ + unsigned int qp_dec1_bits_thr : 8; /* [23..16] */ + unsigned int qp_dec2_bits_thr : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vdp_v3r2_lineseg_cmp_rc_cfg1; + +/* Define the union u_vdp_v3r2_lineseg_cmp_rc_cfg12 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int buffer_init_bits : 16; /* [15..0] */ + unsigned int buffer_size : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vdp_v3r2_lineseg_cmp_rc_cfg12; + +/* Define the union u_vdp_v3r2_lineseg_cmp_rc_cfg13 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int budget_mb_bits : 10; /* [9..0] */ + unsigned int budget_mb_bits_last : 10; /* [19..10] */ + unsigned int min_mb_bits : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vdp_v3r2_lineseg_cmp_rc_cfg13; + +/* Define the union u_vdp_v3r2_lineseg_cmp_rc_cfg16 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int smooth_status_thr : 4; /* [3..0] */ + unsigned int smooth_deltabits_thr : 8; /* [11..4] */ + unsigned int max_mb_qp : 3; /* [14..12] */ + unsigned int reserved_0 : 17; /* [31..15] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vdp_v3r2_lineseg_cmp_rc_cfg16; + +/* Define the union u_vdp_v3r2_lineseg_cmp_glb_st */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int max_left_bits_buffer : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vdp_v3r2_lineseg_cmp_glb_st; + +/* Define the union u_vdp_v3r2_lineseg_cmp_glb_info_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ice_en : 1; /* [0] */ + unsigned int cmp_mode : 1; /* [1] */ + unsigned int is_lossless : 1; /* [2] */ + unsigned int chroma_en : 1; /* [3] */ + unsigned int esl_qp : 3; /* [6..4] */ + unsigned int bit_depth : 1; /* [7] */ + unsigned int mirror_en : 1; /* [8] */ + unsigned int seg_en : 1; /* [9] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vdp_v3r2_lineseg_cmp_glb_info_c; + +/* Define the union u_vdp_v3r2_lineseg_cmp_frame_size_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int frame_width : 14; /* [13..0] */ + unsigned int reserved_0 : 2; /* [15..14] */ + unsigned int frame_height : 14; /* [29..16] */ + unsigned int reserved_1 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vdp_v3r2_lineseg_cmp_frame_size_c; + +/* Define the union u_vdp_v3r2_lineseg_cmp_rc_cfg0_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int big_grad_thr : 8; /* [7..0] */ + unsigned int diff_thr : 8; /* [15..8] */ + unsigned int noise_pix_num_thr : 6; /* [21..16] */ + unsigned int reserved_0 : 10; /* [31..22] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vdp_v3r2_lineseg_cmp_rc_cfg0_c; + +/* Define the union u_vdp_v3r2_lineseg_cmp_rc_cfg1_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int qp_inc1_bits_thr : 8; /* [7..0] */ + unsigned int qp_inc2_bits_thr : 8; /* [15..8] */ + unsigned int qp_dec1_bits_thr : 8; /* [23..16] */ + unsigned int qp_dec2_bits_thr : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vdp_v3r2_lineseg_cmp_rc_cfg1_c; + +/* Define the union u_vdp_v3r2_lineseg_cmp_rc_cfg12_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int buffer_init_bits : 16; /* [15..0] */ + unsigned int buffer_size : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vdp_v3r2_lineseg_cmp_rc_cfg12_c; + +/* Define the union u_vdp_v3r2_lineseg_cmp_rc_cfg13_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int budget_mb_bits : 10; /* [9..0] */ + unsigned int budget_mb_bits_last : 10; /* [19..10] */ + unsigned int min_mb_bits : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vdp_v3r2_lineseg_cmp_rc_cfg13_c; + +/* Define the union u_vdp_v3r2_lineseg_cmp_rc_cfg16_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int smooth_status_thr : 4; /* [3..0] */ + unsigned int smooth_deltabits_thr : 8; /* [11..4] */ + unsigned int max_mb_qp : 3; /* [14..12] */ + unsigned int reserved_0 : 17; /* [31..15] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vdp_v3r2_lineseg_cmp_rc_cfg16_c; + +/* Define the union u_vdp_v3r2_lineseg_cmp_glb_st_c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int max_left_bits_buffer : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_vdp_v3r2_lineseg_cmp_glb_st_c; + +/* Define the union u_wbc_cmp_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int req_interval : 10; /* [9..0] */ + unsigned int reserved_0 : 17; /* [26..10] */ + unsigned int mem_mode : 1; /* [27] */ + unsigned int data_width : 1; /* [28] */ + unsigned int reserved_1 : 1; /* [29] */ + unsigned int l_cmp_en : 1; /* [30] */ + unsigned int wbc_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_cmp_ctrl; + +/* Define the union u_wbc_cmp_upd */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int regup : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_cmp_upd; + +/* Define the union u_wbc_cmp_height */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int c_max_height : 13; /* [12..0] */ + unsigned int l_max_height : 13; /* [25..13] */ + unsigned int addr_mode : 1; /* [26] */ + unsigned int fsize_mode : 1; /* [27] */ + unsigned int rgb_cmp_mode : 2; /* [29..28] */ + unsigned int pause_mode : 1; /* [30] */ + unsigned int buffer_mode : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_cmp_height; + +/* Define the union u_wbc_cmp_oreso */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ow : 12; /* [11..0] */ + unsigned int oh : 12; /* [23..12] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_cmp_oreso; + +/* Define the union u_wbc_od_state */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int addr_err : 1; /* [0] */ + unsigned int he_addr_err0 : 1; /* [1] */ + unsigned int he_addr_err1 : 1; /* [2] */ + unsigned int he_addr_err2 : 1; /* [3] */ + unsigned int w_addr_err : 1; /* [4] */ + unsigned int he_fsize_err0 : 1; /* [5] */ + unsigned int he_fsize_err1 : 1; /* [6] */ + unsigned int he_fsize_err2 : 1; /* [7] */ + unsigned int w_fsize_err : 1; /* [8] */ + unsigned int he_fsize_war0 : 1; /* [9] */ + unsigned int he_fsize_war1 : 1; /* [10] */ + unsigned int he_fsize_war2 : 1; /* [11] */ + unsigned int w_fsize_war : 1; /* [12] */ + unsigned int reserved_0 : 19; /* [31..13] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_wbc_od_state; + +/* Define the union u_od_pic_osd_glb_info */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int is_lossless : 1; /* [0] */ + unsigned int is_lossless_a : 1; /* [1] */ + unsigned int cmp_mode : 1; /* [2] */ + unsigned int source_mode : 3; /* [5..3] */ + unsigned int part_cmp_en : 1; /* [6] */ + unsigned int top_pred_en : 1; /* [7] */ + unsigned int graphic_en : 1; /* [8] */ + unsigned int reserved_0 : 23; /* [31..9] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_od_pic_osd_glb_info; + +/* Define the union u_od_pic_osd_frame_size */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int frame_width : 13; /* [12..0] */ + unsigned int reserved_0 : 3; /* [15..13] */ + unsigned int frame_height : 13; /* [28..16] */ + unsigned int reserved_1 : 3; /* [31..29] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_od_pic_osd_frame_size; + +/* Define the union u_od_pic_osd_rc_cfg0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mb_bits : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int min_mb_bits : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_od_pic_osd_rc_cfg0; + +/* Define the union u_od_pic_osd_rc_cfg1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int max_qp : 4; /* [3..0] */ + unsigned int reserved_0 : 4; /* [7..4] */ + unsigned int sad_bits_gain : 4; /* [11..8] */ + unsigned int reserved_1 : 4; /* [15..12] */ + unsigned int rc_smth_ngain : 3; /* [18..16] */ + unsigned int reserved_2 : 5; /* [23..19] */ + unsigned int max_trow_bits : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_od_pic_osd_rc_cfg1; + +/* Define the union u_od_pic_osd_rc_cfg2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int max_sad_thr : 7; /* [6..0] */ + unsigned int reserved_0 : 9; /* [15..7] */ + unsigned int min_sad_thr : 7; /* [22..16] */ + unsigned int reserved_1 : 9; /* [31..23] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_od_pic_osd_rc_cfg2; + +/* Define the union u_od_pic_osd_rc_cfg3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int smth_thr : 7; /* [6..0] */ + unsigned int reserved_0 : 1; /* [7] */ + unsigned int still_thr : 7; /* [14..8] */ + unsigned int reserved_1 : 1; /* [15] */ + unsigned int big_grad_thr : 10; /* [25..16] */ + unsigned int reserved_2 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_od_pic_osd_rc_cfg3; + +/* Define the union u_od_pic_osd_rc_cfg4 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int smth_pix_num_thr : 6; /* [5..0] */ + unsigned int reserved_0 : 2; /* [7..6] */ + unsigned int still_pix_num_thr : 6; /* [13..8] */ + unsigned int reserved_1 : 2; /* [15..14] */ + unsigned int noise_pix_num_thr : 6; /* [21..16] */ + unsigned int reserved_2 : 10; /* [31..22] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_od_pic_osd_rc_cfg4; + +/* Define the union u_od_pic_osd_rc_cfg5 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int noise_sad : 7; /* [6..0] */ + unsigned int reserved_0 : 9; /* [15..7] */ + unsigned int pix_diff_thr : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_od_pic_osd_rc_cfg5; + +/* Define the union u_od_pic_osd_rc_cfg6 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int adj_sad_bits_thr : 7; /* [6..0] */ + unsigned int reserved_0 : 25; /* [31..7] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_od_pic_osd_rc_cfg6; + +/* Define the union u_od_pic_osd_rc_cfg7 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int qp_inc1_bits_thr : 8; /* [7..0] */ + unsigned int qp_inc2_bits_thr : 8; /* [15..8] */ + unsigned int qp_dec1_bits_thr : 8; /* [23..16] */ + unsigned int qp_dec2_bits_thr : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_od_pic_osd_rc_cfg7; + +/* Define the union u_od_pic_osd_rc_cfg8 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int est_err_gain : 5; /* [4..0] */ + unsigned int reserved_0 : 11; /* [15..5] */ + unsigned int max_est_err_level : 9; /* [24..16] */ + unsigned int reserved_1 : 7; /* [31..25] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_od_pic_osd_rc_cfg8; + +/* Define the union u_od_pic_osd_rc_cfg9 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 16; /* [15..0] */ + unsigned int vbv_buf_loss1_thr : 7; /* [22..16] */ + unsigned int reserved_1 : 1; /* [23] */ + unsigned int vbv_buf_loss2_thr : 7; /* [30..24] */ + unsigned int reserved_2 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_od_pic_osd_rc_cfg9; + +/* Define the union u_od_pic_osd_rc_cfg10 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int qp_thr0 : 3; /* [2..0] */ + unsigned int reserved_0 : 5; /* [7..3] */ + unsigned int qp_thr1 : 3; /* [10..8] */ + unsigned int reserved_1 : 5; /* [15..11] */ + unsigned int qp_thr2 : 3; /* [18..16] */ + unsigned int reserved_2 : 13; /* [31..19] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_od_pic_osd_rc_cfg10; + +/* Define the union u_od_pic_osd_rc_cfg11 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int grph_bias_bit_thr0 : 8; /* [7..0] */ + unsigned int grph_bias_bit_thr1 : 8; /* [15..8] */ + unsigned int grph_ideal_bit_thr : 10; /* [25..16] */ + unsigned int reserved_0 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_od_pic_osd_rc_cfg11; + +/* Define the union u_od_pic_osd_rc_cfg12 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int force_rc_en : 1; /* [0] */ + unsigned int reserved_0 : 7; /* [7..1] */ + unsigned int forcerc_bits_diff_thr : 8; /* [15..8] */ + unsigned int reserved_1 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_od_pic_osd_rc_cfg12; + +/* Define the union u_od_pic_osd_rc_cfg13 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int maxdiff_ctrl_en : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_od_pic_osd_rc_cfg13; + +/* Define the union u_od_pic_osd_rc_cfg14 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mb_bits_cap : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int init_buf_bits_cap : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_od_pic_osd_rc_cfg14; + +/* Define the union u_od_pic_osd_rc_cfg15 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int lfw_mb_len : 7; /* [6..0] */ + unsigned int reserved_0 : 1; /* [7] */ + unsigned int cmplx_sad_thr : 4; /* [11..8] */ + unsigned int reserved_1 : 4; /* [15..12] */ + unsigned int err_thr0 : 4; /* [19..16] */ + unsigned int reserved_2 : 4; /* [23..20] */ + unsigned int err_thr1 : 4; /* [27..24] */ + unsigned int reserved_3 : 4; /* [31..28] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_od_pic_osd_rc_cfg15; + +/* Define the union u_od_pic_osd_rc_cfg16 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int sim_num_thr : 3; /* [2..0] */ + unsigned int reserved_0 : 5; /* [7..3] */ + unsigned int sum_y_err_thr : 7; /* [14..8] */ + unsigned int reserved_1 : 1; /* [15] */ + unsigned int sum_c_err_thr : 7; /* [22..16] */ + unsigned int reserved_2 : 9; /* [31..23] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_od_pic_osd_rc_cfg16; + +/* Define the union u_od_pic_osd_rc_cfg17 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cpmlx_sad_thr_y : 4; /* [3..0] */ + unsigned int reserved_0 : 4; /* [7..4] */ + unsigned int smpl_sad_thr_c : 4; /* [11..8] */ + unsigned int reserved_1 : 4; /* [15..12] */ + unsigned int smpl_sumsad_thr_y : 8; /* [23..16] */ + unsigned int smpl_sumsad_thr_c : 8; /* [31..24] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_od_pic_osd_rc_cfg17; + +/* Define the union u_od_pic_osd_rc_cfg18 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int future_sad_y_thr0 : 4; /* [3..0] */ + unsigned int reserved_0 : 4; /* [7..4] */ + unsigned int future_sad_c_thr0 : 4; /* [11..8] */ + unsigned int reserved_1 : 4; /* [15..12] */ + unsigned int future_sad_y_thr1 : 4; /* [19..16] */ + unsigned int reserved_2 : 4; /* [23..20] */ + unsigned int future_sad_c_thr1 : 4; /* [27..24] */ + unsigned int reserved_3 : 4; /* [31..28] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_od_pic_osd_rc_cfg18; + +/* Define the union u_od_pic_osd_rc_cfg19 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cmplx_sumsad_thr_y : 8; /* [7..0] */ + unsigned int cmplx_sumsad_thr_c : 8; /* [15..8] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_od_pic_osd_rc_cfg19; + +/* Define the union u_od_pic_osd_stat_thr */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int max_gap_bw_row_len_thr : 7; /* [6..0] */ + unsigned int reserved_0 : 25; /* [31..7] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_od_pic_osd_stat_thr; + +/* Define the union u_od_pic_osd_pcmp */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int pcmp_start_hpos : 13; /* [12..0] */ + unsigned int reserved_0 : 3; /* [15..13] */ + unsigned int pcmp_end_hpos : 13; /* [28..16] */ + unsigned int reserved_1 : 3; /* [31..29] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_od_pic_osd_pcmp; + +/* Define the union u_od_pic_osd_bs_size */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int frame_size_reg : 22; /* [21..0] */ + unsigned int reserved_0 : 10; /* [31..22] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_od_pic_osd_bs_size; + +/* Define the union u_od_pic_osd_worst_row */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int max_frm_row_len : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_od_pic_osd_worst_row; + +/* Define the union u_od_pic_osd_best_row */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int min_frm_row_len : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_od_pic_osd_best_row; + +/* Define the union u_od_pic_osd_stat_info */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int max_gap_bw_row_len_cnt : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_od_pic_osd_stat_info; + +/* Define the union u_v0_mrg_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mrg_y_l4_addr : 4; /* [3..0] */ + unsigned int mrg_c_l4_addr : 4; /* [7..4] */ + unsigned int reserved_0 : 12; /* [19..8] */ + unsigned int mrg_edge_en : 1; /* [20] */ + unsigned int reserved_1 : 4; /* [24..21] */ + unsigned int mrg_edge_typ : 1; /* [25] */ + unsigned int reserved_2 : 2; /* [27..26] */ + unsigned int mrg_crop_en : 1; /* [28] */ + unsigned int mrg_dcmp_en : 1; /* [29] */ + unsigned int mrg_mute_en : 1; /* [30] */ + unsigned int mrg_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_mrg_ctrl; + +/* Define the union u_v0_mrg_disp_pos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mrg_xpos : 16; /* [15..0] */ + unsigned int mrg_ypos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_mrg_disp_pos; + +/* Define the union u_v0_mrg_disp_reso */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mrg_width : 16; /* [15..0] */ + unsigned int mrg_height : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_mrg_disp_reso; + +/* Define the union u_v0_mrg_src_reso */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mrg_src_width : 16; /* [15..0] */ + unsigned int mrg_src_height : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_mrg_src_reso; + +/* Define the union u_v0_mrg_src_offset */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mrg_src_hoffset : 16; /* [15..0] */ + unsigned int mrg_src_voffset : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_mrg_src_offset; + +/* Define the union u_v0_mrg_stride */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mrg_c_stride : 16; /* [15..0] */ + unsigned int mrg_y_stride : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_mrg_stride; + +/* Define the union u_v0_mrg_hstride */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mrg_ch_stride : 16; /* [15..0] */ + unsigned int mrg_yh_stride : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_mrg_hstride; + +/* Define the union u_v0_mrg_read_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int rd_region : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_mrg_read_ctrl; + +/* Define the union u_v0_mrg_read_en */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int rd_en : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_mrg_read_en; + +/* Define the union u_v1_mrg_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mrg_y_l4_addr : 4; /* [3..0] */ + unsigned int mrg_c_l4_addr : 4; /* [7..4] */ + unsigned int reserved_0 : 12; /* [19..8] */ + unsigned int mrg_edge_en : 1; /* [20] */ + unsigned int reserved_1 : 4; /* [24..21] */ + unsigned int mrg_edge_typ : 1; /* [25] */ + unsigned int reserved_2 : 2; /* [27..26] */ + unsigned int mrg_crop_en : 1; /* [28] */ + unsigned int mrg_dcmp_en : 1; /* [29] */ + unsigned int mrg_mute_en : 1; /* [30] */ + unsigned int mrg_en : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_mrg_ctrl; + +/* Define the union u_v1_mrg_disp_pos */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mrg_xpos : 16; /* [15..0] */ + unsigned int mrg_ypos : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_mrg_disp_pos; + +/* Define the union u_v1_mrg_disp_reso */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mrg_width : 16; /* [15..0] */ + unsigned int mrg_height : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_mrg_disp_reso; + +/* Define the union u_v1_mrg_src_reso */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mrg_src_width : 16; /* [15..0] */ + unsigned int mrg_src_height : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_mrg_src_reso; + +/* Define the union u_v1_mrg_src_offset */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mrg_src_hoffset : 16; /* [15..0] */ + unsigned int mrg_src_voffset : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_mrg_src_offset; + +/* Define the union u_v1_mrg_stride */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mrg_c_stride : 16; /* [15..0] */ + unsigned int mrg_y_stride : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_mrg_stride; + +/* Define the union u_v1_mrg_hstride */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int mrg_ch_stride : 16; /* [15..0] */ + unsigned int mrg_yh_stride : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_mrg_hstride; + +/* Define the union u_v1_mrg_read_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int rd_region : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_mrg_read_ctrl; + +/* Define the union u_v1_mrg_read_en */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int rd_en : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_mrg_read_en; + +/* define the union reg_osb_ctrl1_box_0 */ +typedef union { + /* define the struct bits */ + struct { + unsigned int mode_0 : 2; /* [1..0] */ + unsigned int thick_w_0 : 6; /* [7..2] */ + unsigned int arm_w_0 : 8; /* [15..8] */ + unsigned int edge_v_0 : 4; /* [19..16] */ + unsigned int edge_reg_0 : 4; /* [23..20] */ + unsigned int edge_y_0 : 4; /* [27..24] */ + unsigned int edge_alpha_0 : 4; /* [31..28] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} u_osb_ctrl1_box_0; + +/* define the union reg_osb_ctrl2_box_0 */ +typedef union { + /* define the struct bits */ + struct { + unsigned int hstr_pos_0 : 12; /* [11..0] */ + unsigned int reserved_0 : 4; /* [15..12] */ + unsigned int hend_pos_0 : 12; /* [27..16] */ + unsigned int reserved_1 : 4; /* [31..28] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} u_osb_ctrl2_box_0; + +/* define the union reg_osb_ctrl3_box_0 */ +typedef union { + /* define the struct bits */ + struct { + unsigned int vstr_pos_0 : 12; /* [11..0] */ + unsigned int reserved_0 : 4; /* [15..12] */ + unsigned int vend_pos_0 : 12; /* [27..16] */ + unsigned int reserved_1 : 4; /* [31..28] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} u_osb_ctrl3_box_0; + +/* Define the union u_v1_csc_idc */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscidc0 : 11; /* [10..0] */ + unsigned int cscidc1 : 11; /* [21..11] */ + unsigned int csc_en : 1; /* [22] */ + unsigned int csc_mode : 3; /* [25..23] */ + unsigned int csc_ck_gt_en : 1; /* [26] */ + unsigned int reserved_0 : 5; /* [31..27] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_csc_idc; + +/* Define the union u_v1_csc_odc */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscodc0 : 11; /* [10..0] */ + unsigned int cscodc1 : 11; /* [21..11] */ + unsigned int csc_sign_mode : 1; /* [22] */ + unsigned int reserved_0 : 9; /* [31..23] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_csc_odc; + +/* Define the union u_v1_csc_iodc */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscidc2 : 11; /* [10..0] */ + unsigned int cscodc2 : 11; /* [21..11] */ + unsigned int reserved_0 : 10; /* [31..22] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_csc_iodc; + +/* Define the union u_v1_csc_p0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp00 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp01 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_csc_p0; + +/* Define the union u_v1_csc_p1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp02 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp10 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_csc_p1; + +/* Define the union u_v1_csc_p2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp11 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp12 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_csc_p2; + +/* Define the union u_v1_csc_p3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp20 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp21 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_csc_p3; + +/* Define the union u_v1_csc_p4 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp22 : 15; /* [14..0] */ + unsigned int reserved_0 : 17; /* [31..15] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_csc_p4; + +/* Define the union u_v1_csc1_idc */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscidc0 : 11; /* [10..0] */ + unsigned int cscidc1 : 11; /* [21..11] */ + unsigned int csc_en : 1; /* [22] */ + unsigned int csc_mode : 3; /* [25..23] */ + unsigned int reserved_0 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_csc1_idc; + +/* Define the union u_v1_csc1_odc */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscodc0 : 11; /* [10..0] */ + unsigned int cscodc1 : 11; /* [21..11] */ + unsigned int csc_sign_mode : 1; /* [22] */ + unsigned int reserved_0 : 9; /* [31..23] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_csc1_odc; + +/* Define the union u_v1_csc1_iodc */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscidc2 : 11; /* [10..0] */ + unsigned int cscodc2 : 11; /* [21..11] */ + unsigned int reserved_0 : 10; /* [31..22] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_csc1_iodc; + +/* Define the union u_v1_csc1_p0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp00 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp01 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_csc1_p0; + +/* Define the union u_v1_csc1_p1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp02 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp10 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_csc1_p1; + +/* Define the union u_v1_csc1_p2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp11 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp12 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_csc1_p2; + +/* Define the union u_v1_csc1_p3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp20 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp21 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_csc1_p3; + +/* Define the union u_v1_csc1_p4 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp22 : 15; /* [14..0] */ + unsigned int reserved_0 : 17; /* [31..15] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v1_csc1_p4; + +/* Define the union u_v2_csc_idc */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscidc0 : 11; /* [10..0] */ + unsigned int cscidc1 : 11; /* [21..11] */ + unsigned int csc_en : 1; /* [22] */ + unsigned int csc_mode : 3; /* [25..23] */ + unsigned int csc_ck_gt_en : 1; /* [26] */ + unsigned int reserved_0 : 5; /* [31..27] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_csc_idc; + +/* Define the union u_v2_csc_odc */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscodc0 : 11; /* [10..0] */ + unsigned int cscodc1 : 11; /* [21..11] */ + unsigned int csc_sign_mode : 1; /* [22] */ + unsigned int reserved_0 : 9; /* [31..23] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_csc_odc; + +/* Define the union u_v2_csc_iodc */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscidc2 : 11; /* [10..0] */ + unsigned int cscodc2 : 11; /* [21..11] */ + unsigned int reserved_0 : 10; /* [31..22] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_csc_iodc; + +/* Define the union u_v2_csc_p0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp00 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp01 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_csc_p0; + +/* Define the union u_v2_csc_p1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp02 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp10 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_csc_p1; + +/* Define the union u_v2_csc_p2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp11 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp12 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_csc_p2; + +/* Define the union u_v2_csc_p3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp20 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp21 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_csc_p3; + +/* Define the union u_v2_csc_p4 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp22 : 15; /* [14..0] */ + unsigned int reserved_0 : 17; /* [31..15] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_csc_p4; + +/* Define the union u_v2_csc1_idc */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscidc0 : 11; /* [10..0] */ + unsigned int cscidc1 : 11; /* [21..11] */ + unsigned int csc_en : 1; /* [22] */ + unsigned int csc_mode : 3; /* [25..23] */ + unsigned int reserved_0 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_csc1_idc; + +/* Define the union u_v2_csc1_odc */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscodc0 : 11; /* [10..0] */ + unsigned int cscodc1 : 11; /* [21..11] */ + unsigned int csc_sign_mode : 1; /* [22] */ + unsigned int reserved_0 : 9; /* [31..23] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_csc1_odc; + +/* Define the union u_v2_csc1_iodc */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscidc2 : 11; /* [10..0] */ + unsigned int cscodc2 : 11; /* [21..11] */ + unsigned int reserved_0 : 10; /* [31..22] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_csc1_iodc; + +/* Define the union u_v2_csc1_p0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp00 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp01 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_csc1_p0; + +/* Define the union u_v2_csc1_p1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp02 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp10 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_csc1_p1; + +/* Define the union u_v2_csc1_p2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp11 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp12 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_csc1_p2; + +/* Define the union u_v2_csc1_p3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp20 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp21 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_csc1_p3; + +/* Define the union u_v2_csc1_p4 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp22 : 15; /* [14..0] */ + unsigned int reserved_0 : 17; /* [31..15] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v2_csc1_p4; + +/* Define the union u_g1_csc_idc */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscidc0 : 11; /* [10..0] */ + unsigned int cscidc1 : 11; /* [21..11] */ + unsigned int csc_en : 1; /* [22] */ + unsigned int csc_mode : 3; /* [25..23] */ + unsigned int csc_ck_gt_en : 1; /* [26] */ + unsigned int reserved_0 : 5; /* [31..27] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_csc_idc; + +/* Define the union u_g1_csc_odc */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscodc0 : 11; /* [10..0] */ + unsigned int cscodc1 : 11; /* [21..11] */ + unsigned int csc_sign_mode : 1; /* [22] */ + unsigned int reserved_0 : 9; /* [31..23] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_csc_odc; + +/* Define the union u_g1_csc_iodc */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscidc2 : 11; /* [10..0] */ + unsigned int cscodc2 : 11; /* [21..11] */ + unsigned int reserved_0 : 10; /* [31..22] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_csc_iodc; + +/* Define the union u_g1_csc_p0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp00 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp01 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_csc_p0; + +/* Define the union u_g1_csc_p1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp02 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp10 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_csc_p1; + +/* Define the union u_g1_csc_p2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp11 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp12 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_csc_p2; + +/* Define the union u_g1_csc_p3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp20 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp21 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_csc_p3; + +/* Define the union u_g1_csc_p4 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp22 : 15; /* [14..0] */ + unsigned int reserved_0 : 17; /* [31..15] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_csc_p4; + +/* Define the union u_g1_csc1_idc */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscidc0 : 11; /* [10..0] */ + unsigned int cscidc1 : 11; /* [21..11] */ + unsigned int csc_en : 1; /* [22] */ + unsigned int csc_mode : 3; /* [25..23] */ + unsigned int reserved_0 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_csc1_idc; + +/* Define the union u_g1_csc1_odc */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscodc0 : 11; /* [10..0] */ + unsigned int cscodc1 : 11; /* [21..11] */ + unsigned int csc_sign_mode : 1; /* [22] */ + unsigned int reserved_0 : 9; /* [31..23] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_csc1_odc; + +/* Define the union u_g1_csc1_iodc */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscidc2 : 11; /* [10..0] */ + unsigned int cscodc2 : 11; /* [21..11] */ + unsigned int reserved_0 : 10; /* [31..22] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_csc1_iodc; + +/* Define the union u_g1_csc1_p0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp00 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp01 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_csc1_p0; + +/* Define the union u_g1_csc1_p1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp02 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp10 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_csc1_p1; + +/* Define the union u_g1_csc1_p2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp11 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp12 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_csc1_p2; + +/* Define the union u_g1_csc1_p3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp20 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp21 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_csc1_p3; + +/* Define the union u_g1_csc1_p4 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp22 : 15; /* [14..0] */ + unsigned int reserved_0 : 17; /* [31..15] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g1_csc1_p4; + +/* Define the union u_g3_csc_idc */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscidc0 : 11; /* [10..0] */ + unsigned int cscidc1 : 11; /* [21..11] */ + unsigned int csc_en : 1; /* [22] */ + unsigned int csc_mode : 3; /* [25..23] */ + unsigned int csc_ck_gt_en : 1; /* [26] */ + unsigned int reserved_0 : 5; /* [31..27] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_csc_idc; + +/* Define the union u_g3_csc_odc */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscodc0 : 11; /* [10..0] */ + unsigned int cscodc1 : 11; /* [21..11] */ + unsigned int csc_sign_mode : 1; /* [22] */ + unsigned int reserved_0 : 9; /* [31..23] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_csc_odc; + +/* Define the union u_g3_csc_iodc */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscidc2 : 11; /* [10..0] */ + unsigned int cscodc2 : 11; /* [21..11] */ + unsigned int reserved_0 : 10; /* [31..22] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_csc_iodc; + +/* Define the union u_g3_csc_p0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp00 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp01 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_csc_p0; + +/* Define the union u_g3_csc_p1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp02 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp10 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_csc_p1; + +/* Define the union u_g3_csc_p2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp11 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp12 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_csc_p2; + +/* Define the union u_g3_csc_p3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp20 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp21 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_csc_p3; + +/* Define the union u_g3_csc_p4 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp22 : 15; /* [14..0] */ + unsigned int reserved_0 : 17; /* [31..15] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_csc_p4; + +/* Define the union u_g3_csc1_idc */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscidc0 : 11; /* [10..0] */ + unsigned int cscidc1 : 11; /* [21..11] */ + unsigned int csc_en : 1; /* [22] */ + unsigned int csc_mode : 3; /* [25..23] */ + unsigned int reserved_0 : 6; /* [31..26] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_csc1_idc; + +/* Define the union u_g3_csc1_odc */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscodc0 : 11; /* [10..0] */ + unsigned int cscodc1 : 11; /* [21..11] */ + unsigned int csc_sign_mode : 1; /* [22] */ + unsigned int reserved_0 : 9; /* [31..23] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_csc1_odc; + +/* Define the union u_g3_csc1_iodc */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscidc2 : 11; /* [10..0] */ + unsigned int cscodc2 : 11; /* [21..11] */ + unsigned int reserved_0 : 10; /* [31..22] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_csc1_iodc; + +/* Define the union u_g3_csc1_p0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp00 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp01 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_csc1_p0; + +/* Define the union u_g3_csc1_p1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp02 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp10 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_csc1_p1; + +/* Define the union u_g3_csc1_p2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp11 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp12 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_csc1_p2; + +/* Define the union u_g3_csc1_p3 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp20 : 15; /* [14..0] */ + unsigned int reserved_0 : 1; /* [15] */ + unsigned int cscp21 : 15; /* [30..16] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_csc1_p3; + +/* Define the union u_g3_csc1_p4 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int cscp22 : 15; /* [14..0] */ + unsigned int reserved_0 : 17; /* [31..15] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_g3_csc1_p4; + +/* Define the union u_v0_cvfir_vinfo */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int out_height : 16; /* [15..0] */ + unsigned int out_fmt : 2; /* [17..16] */ + unsigned int out_pro : 1; /* [18] */ + unsigned int vzme_ck_gt_en : 1; /* [19] */ + unsigned int reserved_0 : 12; /* [31..20] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_cvfir_vinfo; + +/* Define the union u_v0_cvfir_vsp */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vratio : 16; /* [15..0] */ + unsigned int reserved_0 : 1; /* [16] */ + unsigned int reserved_1 : 8; /* [24..17] */ + unsigned int cvfir_mode : 1; /* [25] */ + unsigned int reserved_2 : 1; /* [26] */ + unsigned int reserved_3 : 1; /* [27] */ + unsigned int cvmid_en : 1; /* [28] */ + unsigned int reserved_4 : 1; /* [29] */ + unsigned int cvfir_en : 1; /* [30] */ + unsigned int reserved_5 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_cvfir_vsp; + +/* Define the union u_v0_cvfir_voffset */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vchroma_offset : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_cvfir_voffset; + +/* Define the union u_v0_cvfir_vboffset */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vbchroma_offset : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_cvfir_vboffset; + +/* Define the union u_v0_cvfir_vcoef0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vccoef02 : 10; /* [9..0] */ + unsigned int vccoef01 : 10; /* [19..10] */ + unsigned int vccoef00 : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_cvfir_vcoef0; + +/* Define the union u_v0_cvfir_vcoef1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vccoef11 : 10; /* [9..0] */ + unsigned int vccoef10 : 10; /* [19..10] */ + unsigned int vccoef03 : 10; /* [29..20] */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_cvfir_vcoef1; + +/* Define the union u_v0_cvfir_vcoef2 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int vccoef13 : 10; /* [9..0] */ + unsigned int vccoef12 : 10; /* [19..10] */ + unsigned int reserved_0 : 12; /* [31..20] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_v0_cvfir_vcoef2; + +/* Define the union u_gfx_osd_glb_info */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int dcmp_en : 1; /* [0] */ + unsigned int is_lossless : 1; /* [1] */ + unsigned int is_lossless_a : 1; /* [2] */ + unsigned int cmp_mode : 1; /* [3] */ + unsigned int source_mode : 3; /* [6..4] */ + unsigned int tpred_en : 1; /* [7] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gfx_osd_glb_info; + +/* Define the union u_gfx_osd_frame_size */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int frame_width : 13; /* [12..0] */ + unsigned int reserved_0 : 3; /* [15..13] */ + unsigned int frame_height : 13; /* [28..16] */ + unsigned int reserved_1 : 3; /* [31..29] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gfx_osd_frame_size; + +/* Define the union u_gfx_osd_dbg_reg */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 30; /* [29..0] */ + unsigned int dcmp_err0 : 1; /* [30] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gfx_osd_dbg_reg; + +/* Define the union u_gfx_osd_dbg_reg1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reserved_0 : 30; /* [29..0] */ + unsigned int dcmp_err1 : 1; /* [30] */ + unsigned int reserved_1 : 1; /* [31] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} u_gfx_osd_dbg_reg1; + +/* Define the global struct */ +typedef struct { + volatile u_voctrl voctrl; /* 0x0 */ + volatile u_vointsta vointsta; /* 0x4 */ + volatile u_vomskintsta vomskintsta; /* 0x8 */ + volatile u_vointmsk vointmsk; /* 0xc */ + volatile u_vodebug vodebug; /* 0x10 */ + volatile u_vointsta1 vointsta1; /* 0x14 */ + volatile u_vomskintsta1 vomskintsta1; /* 0x18 */ + volatile u_vointmsk1 vointmsk1; /* 0x1c */ + volatile unsigned int vdpversion1; /* 0x20 */ + volatile unsigned int vdpversion2; /* 0x24 */ + volatile u_volowpower_ctrl volowpower_ctrl; /* 0x28 */ + volatile u_voufsta voufsta; /* 0x2c */ + volatile u_voufclr voufclr; /* 0x30 */ + volatile u_vointproc_tim vointproc_tim; /* 0x34 */ + volatile unsigned int vofpgatest; /* 0x38 */ + volatile unsigned int reserved_0[3]; /* 0x3c~0x44 */ + volatile u_volowpower_ctrl1 volowpower_ctrl1; /* 0x48 */ + volatile u_vofpgadef vofpgadef; /* 0x4c */ + volatile u_volowpower_ctrl2 volowpower_ctrl2; /* 0x50 */ + volatile u_volowpower_ctrl3 volowpower_ctrl3; /* 0x54 */ + volatile unsigned int reserved_1[43]; /* 43:0x58~0x100 */ + volatile u_vomux_dac vomux_dac; /* 0x104 */ + volatile u_vomux_testsync vomux_testsync; /* 0x108 */ + volatile u_vomux_testdata vomux_testdata; /* 0x10c */ + volatile unsigned int reserved_2[4]; /* 4:0x110~0x11c */ + volatile u_vo_dac_ctrl vo_dac_ctrl; /* 0x120 */ + volatile u_vo_dac_otp vo_dac_otp; /* 0x124 */ + volatile unsigned int reserved_3[2]; /* 2:0x128~0x12c */ + volatile u_vo_dac0_ctrl vo_dac0_ctrl; /* 0x130 */ + volatile u_vo_dac1_ctrl vo_dac1_ctrl; /* 0x134 */ + volatile u_vo_dac2_ctrl vo_dac2_ctrl; /* 0x138 */ + volatile u_vo_dac3_ctrl vo_dac3_ctrl; /* 0x13c */ + volatile u_vo_dac_stat0 vo_dac_stat0; /* 0x140 */ + volatile unsigned int reserved_4[111]; /* 111:0x144~0x2fc */ + volatile u_cbm_bkg1 cbm_bkg1; /* 0x300 */ + volatile unsigned int reserved_5; /* 0x304 */ + volatile u_cbm_mix1 cbm_mix1; /* 0x308 */ + volatile unsigned int reserved_6[14]; /* 14:0x30c~0x340 */ + volatile u_wbc_bmp_thd wbc_bmp_thd; /* 0x344 */ + volatile unsigned int reserved_7[2]; /* 2:0x348~0x34c */ + volatile unsigned int cbm1_lay0_debug; /* 0x350 */ + volatile unsigned int cbm1_lay1_debug; /* 0x354 */ + volatile unsigned int cbm1_lay2_debug; /* 0x358 */ + volatile unsigned int cbm1_lay3_debug; /* 0x35c */ + volatile unsigned int cbm1_lay4_debug; /* 0x360 */ + volatile unsigned int cbm1_lay0_last_debug; /* 0x364 */ + volatile unsigned int cbm1_lay1_last_debug; /* 0x368 */ + volatile unsigned int cbm1_lay2_last_debug; /* 0x36c */ + volatile unsigned int cbm1_lay3_last_debug; /* 0x370 */ + volatile unsigned int cbm1_lay4_last_debug; /* 0x374 */ + volatile unsigned int reserved_8[2]; /* 2:0x378~0x37c */ + volatile u_cbm_bkg2 cbm_bkg2; /* 0x380 */ + volatile unsigned int reserved_9; /* 0x384 */ + volatile u_cbm_mix2 cbm_mix2; /* 0x388 */ + volatile unsigned int reserved_10[14]; /* 14:0x38c~0x3c0 */ + volatile u_hc_bmp_thd hc_bmp_thd; /* 0x3c4 */ + volatile unsigned int reserved_11[2]; /* 2:0x3c8~0x3cc */ + volatile unsigned int cbm2_lay0_debug; /* 0x3d0 */ + volatile unsigned int cbm2_lay1_debug; /* 0x3d4 */ + volatile unsigned int cbm2_lay2_debug; /* 0x3d8 */ + volatile unsigned int cbm2_lay3_debug; /* 0x3dc */ + volatile unsigned int cbm2_lay4_debug; /* 0x3e0 */ + volatile unsigned int cbm2_lay0_last_debug; /* 0x3e4 */ + volatile unsigned int cbm2_lay1_last_debug; /* 0x3e8 */ + volatile unsigned int cbm2_lay2_last_debug; /* 0x3ec */ + volatile unsigned int cbm2_lay3_last_debug; /* 0x3f0 */ + volatile unsigned int cbm2_lay4_last_debug; /* 0x3f4 */ + volatile unsigned int reserved_12[2]; /* 2:0x3f8~0x3fc */ + volatile u_cbm_bkg3 cbm_bkg3; /* 0x400 */ + volatile unsigned int reserved_13; /* 0x404 */ + volatile u_cbm_mix3 cbm_mix3; /* 0x408 */ + volatile unsigned int reserved_14[17]; /* 17:0x40c~0x44c */ + volatile unsigned int cbm3_lay0_debug; /* 0x450 */ + volatile unsigned int cbm3_lay1_debug; /* 0x454 */ + volatile unsigned int cbm3_lay2_debug; /* 0x458 */ + volatile unsigned int cbm3_lay3_debug; /* 0x45c */ + volatile unsigned int cbm3_lay4_debug; /* 0x460 */ + volatile unsigned int cbm3_lay0_last_debug; /* 0x464 */ + volatile unsigned int cbm3_lay1_last_debug; /* 0x468 */ + volatile unsigned int cbm3_lay2_last_debug; /* 0x46c */ + volatile unsigned int cbm3_lay3_last_debug; /* 0x470 */ + volatile unsigned int cbm3_lay4_last_debug; /* 0x474 */ + volatile unsigned int reserved_15[98]; /* 98:0x478~0x5fc */ + volatile u_mixv0_bkg mixv0_bkg; /* 0x600 */ + volatile unsigned int reserved_16; /* 0x604 */ + volatile u_mixv0_mix mixv0_mix; /* 0x608 */ + volatile unsigned int reserved_17[189]; /* 189:0x60c~0x8fc */ + volatile u_mixg0_bkg mixg0_bkg; /* 0x900 */ + volatile u_mixg0_bkalpha mixg0_bkalpha; /* 0x904 */ + volatile u_mixg0_mix mixg0_mix; /* 0x908 */ + volatile unsigned int reserved_18[189]; /* 189:0x90c~0xbfc */ + volatile u_link_ctrl link_ctrl; /* 0xc00 */ + volatile unsigned int reserved_19[63]; /* 63:0xc04~0xcfc */ + volatile u_vpss_ctrl vpss_ctrl; /* 0xd00 */ + volatile u_vpss_miscellaneous vpss_miscellaneous; /* 0xd04 */ + volatile u_vpss_ftconfig vpss_ftconfig; /* 0xd08 */ + volatile unsigned int reserved_20[5]; /* 5:0xd0c~0xd1c */ + volatile unsigned int vpss_version; /* 0xd20 */ + volatile unsigned int vpss_debug0; /* 0xd24 */ + volatile unsigned int vpss_debug1; /* 0xd28 */ + volatile unsigned int vpss_debug2; /* 0xd2c */ + volatile unsigned int vpss_debug3; /* 0xd30 */ + volatile unsigned int vpss_debug4; /* 0xd34 */ + volatile unsigned int vpss_debug5; /* 0xd38 */ + volatile unsigned int vpss_debug6; /* 0xd3c */ + volatile unsigned int reserved_21[48]; /* 48:0xd40~0xdfc */ + volatile unsigned int para_haddr_vhd_chn00; /* 0xe00 */ + volatile unsigned int para_addr_vhd_chn00; /* 0xe04 */ + volatile unsigned int para_haddr_vhd_chn01; /* 0xe08 */ + volatile unsigned int para_addr_vhd_chn01; /* 0xe0c */ + volatile unsigned int para_haddr_vhd_chn02; /* 0xe10 */ + volatile unsigned int para_addr_vhd_chn02; /* 0xe14 */ + volatile unsigned int para_haddr_vhd_chn03; /* 0xe18 */ + volatile unsigned int para_addr_vhd_chn03; /* 0xe1c */ + volatile unsigned int para_haddr_vhd_chn04; /* 0xe20 */ + volatile unsigned int para_addr_vhd_chn04; /* 0xe24 */ + volatile unsigned int para_haddr_vhd_chn05; /* 0xe28 */ + volatile unsigned int para_addr_vhd_chn05; /* 0xe2c */ + volatile unsigned int para_haddr_vhd_chn06; /* 0xe30 */ + volatile unsigned int para_addr_vhd_chn06; /* 0xe34 */ + volatile unsigned int para_haddr_vhd_chn07; /* 0xe38 */ + volatile unsigned int para_addr_vhd_chn07; /* 0xe3c */ + volatile unsigned int para_haddr_vhd_chn08; /* 0xe40 */ + volatile unsigned int para_addr_vhd_chn08; /* 0xe44 */ + volatile unsigned int para_haddr_vhd_chn09; /* 0xe48 */ + volatile unsigned int para_addr_vhd_chn09; /* 0xe4c */ + volatile unsigned int para_haddr_vhd_chn10; /* 0xe50 */ + volatile unsigned int para_addr_vhd_chn10; /* 0xe54 */ + volatile unsigned int para_haddr_vhd_chn11; /* 0xe58 */ + volatile unsigned int para_addr_vhd_chn11; /* 0xe5c */ + volatile unsigned int para_haddr_vhd_chn12; /* 0xe60 */ + volatile unsigned int para_addr_vhd_chn12; /* 0xe64 */ + volatile unsigned int para_haddr_vhd_chn13; /* 0xe68 */ + volatile unsigned int para_addr_vhd_chn13; /* 0xe6c */ + volatile unsigned int para_haddr_vhd_chn14; /* 0xe70 */ + volatile unsigned int para_addr_vhd_chn14; /* 0xe74 */ + volatile unsigned int para_haddr_vhd_chn15; /* 0xe78 */ + volatile unsigned int para_addr_vhd_chn15; /* 0xe7c */ + volatile unsigned int para_haddr_vhd_chn16; /* 0xe80 */ + volatile unsigned int para_addr_vhd_chn16; /* 0xe84 */ + volatile unsigned int para_haddr_vhd_chn17; /* 0xe88 */ + volatile unsigned int para_addr_vhd_chn17; /* 0xe8c */ + volatile unsigned int para_haddr_vhd_chn18; /* 0xe90 */ + volatile unsigned int para_addr_vhd_chn18; /* 0xe94 */ + volatile unsigned int para_haddr_vhd_chn19; /* 0xe98 */ + volatile unsigned int para_addr_vhd_chn19; /* 0xe9c */ + volatile unsigned int para_haddr_vhd_chn20; /* 0xea0 */ + volatile unsigned int para_addr_vhd_chn20; /* 0xea4 */ + volatile unsigned int para_haddr_vhd_chn21; /* 0xea8 */ + volatile unsigned int para_addr_vhd_chn21; /* 0xeac */ + volatile unsigned int para_haddr_vhd_chn22; /* 0xeb0 */ + volatile unsigned int para_addr_vhd_chn22; /* 0xeb4 */ + volatile unsigned int para_haddr_vhd_chn23; /* 0xeb8 */ + volatile unsigned int para_addr_vhd_chn23; /* 0xebc */ + volatile unsigned int para_haddr_vhd_chn24; /* 0xec0 */ + volatile unsigned int para_addr_vhd_chn24; /* 0xec4 */ + volatile unsigned int para_haddr_vhd_chn25; /* 0xec8 */ + volatile unsigned int para_addr_vhd_chn25; /* 0xecc */ + volatile unsigned int para_haddr_vhd_chn26; /* 0xed0 */ + volatile unsigned int para_addr_vhd_chn26; /* 0xed4 */ + volatile unsigned int para_haddr_vhd_chn27; /* 0xed8 */ + volatile unsigned int para_addr_vhd_chn27; /* 0xedc */ + volatile unsigned int para_haddr_vhd_chn28; /* 0xee0 */ + volatile unsigned int para_addr_vhd_chn28; /* 0xee4 */ + volatile unsigned int para_haddr_vhd_chn29; /* 0xee8 */ + volatile unsigned int para_addr_vhd_chn29; /* 0xeec */ + volatile unsigned int para_haddr_vhd_chn30; /* 0xef0 */ + volatile unsigned int para_addr_vhd_chn30; /* 0xef4 */ + volatile unsigned int para_haddr_vhd_chn31; /* 0xef8 */ + volatile unsigned int para_addr_vhd_chn31; /* 0xefc */ + volatile u_para_up_vhd para_up_vhd; /* 0xf00 */ + volatile unsigned int para_haddr_vsd_chn00; /* 0xf04 */ + volatile unsigned int para_addr_vsd_chn00; /* 0xf08 */ + volatile unsigned int para_haddr_vsd_chn01; /* 0xf0c */ + volatile unsigned int para_addr_vsd_chn01; /* 0xf10 */ + volatile unsigned int para_haddr_vsd_chn02; /* 0xf14 */ + volatile unsigned int para_addr_vsd_chn02; /* 0xf18 */ + volatile unsigned int para_haddr_vsd_chn03; /* 0xf1c */ + volatile unsigned int para_addr_vsd_chn03; /* 0xf20 */ + volatile unsigned int para_haddr_vsd_chn04; /* 0xf24 */ + volatile unsigned int para_addr_vsd_chn04; /* 0xf28 */ + volatile unsigned int para_haddr_vsd_chn05; /* 0xf2c */ + volatile unsigned int para_addr_vsd_chn05; /* 0xf30 */ + volatile unsigned int para_haddr_vsd_chn06; /* 0xf34 */ + volatile unsigned int para_addr_vsd_chn06; /* 0xf38 */ + volatile unsigned int para_haddr_vsd_chn07; /* 0xf3c */ + volatile unsigned int para_addr_vsd_chn07; /* 0xf40 */ + volatile u_para_up_vsd para_up_vsd; /* 0xf44 */ + volatile u_para_conflict_clr para_conflict_clr; /* 0xf48 */ + volatile u_para_conflict_sta para_conflict_sta; /* 0xf4c */ + volatile unsigned int reserved_22[44]; /* 44:0xf50~0xffc */ + volatile u_v0_ctrl v0_ctrl; /* 0x1000 */ + volatile u_v0_upd v0_upd; /* 0x1004 */ + volatile u_v0_0reso_read v0_0reso_read; /* 0x1008 */ + volatile unsigned int reserved_23; /* 0x100c */ + volatile u_v0_ireso v0_ireso; /* 0x1010 */ + volatile unsigned int reserved_24[27]; /* 27:0x1014~0x107c */ + volatile u_v0_dfpos v0_dfpos; /* 0x1080 */ + volatile u_v0_dlpos v0_dlpos; /* 0x1084 */ + volatile u_v0_vfpos v0_vfpos; /* 0x1088 */ + volatile u_v0_vlpos v0_vlpos; /* 0x108c */ + volatile u_v0_bk v0_bk; /* 0x1090 */ + volatile u_v0_alpha v0_alpha; /* 0x1094 */ + volatile u_v0_mute_bk v0_mute_bk; /* 0x1098 */ + volatile unsigned int reserved_25; /* 0x109c */ + volatile u_v0_rimwidth v0_rimwidth; /* 0x10a0 */ + volatile u_v0_rimcol0 v0_rimcol0; /* 0x10a4 */ + volatile u_v0_rimcol1 v0_rimcol1; /* 0x10a8 */ + volatile unsigned int reserved_26[85]; /* 85:0x10ac~0x11fc */ + volatile u_v0_ot_pp_csc_ctrl v0_ot_pp_csc_ctrl; /* 0x1200 */ + volatile u_v0_ot_pp_csc_coef00 v0_ot_pp_csc_coef00; /* 0x1204 */ + volatile u_v0_ot_pp_csc_coef01 v0_ot_pp_csc_coef01; /* 0x1208 */ + volatile u_v0_ot_pp_csc_coef02 v0_ot_pp_csc_coef02; /* 0x120c */ + volatile u_v0_ot_pp_csc_coef10 v0_ot_pp_csc_coef10; /* 0x1210 */ + volatile u_v0_ot_pp_csc_coef11 v0_ot_pp_csc_coef11; /* 0x1214 */ + volatile u_v0_ot_pp_csc_coef12 v0_ot_pp_csc_coef12; /* 0x1218 */ + volatile u_v0_ot_pp_csc_coef20 v0_ot_pp_csc_coef20; /* 0x121c */ + volatile u_v0_ot_pp_csc_coef21 v0_ot_pp_csc_coef21; /* 0x1220 */ + volatile u_v0_ot_pp_csc_coef22 v0_ot_pp_csc_coef22; /* 0x1224 */ + volatile u_v0_ot_pp_csc_scale v0_ot_pp_csc_scale; /* 0x1228 */ + volatile u_v0_ot_pp_csc_idc0 v0_ot_pp_csc_idc0; /* 0x122c */ + volatile u_v0_ot_pp_csc_idc1 v0_ot_pp_csc_idc1; /* 0x1230 */ + volatile u_v0_ot_pp_csc_idc2 v0_ot_pp_csc_idc2; /* 0x1234 */ + volatile u_v0_ot_pp_csc_odc0 v0_ot_pp_csc_odc0; /* 0x1238 */ + volatile u_v0_ot_pp_csc_odc1 v0_ot_pp_csc_odc1; /* 0x123c */ + volatile u_v0_ot_pp_csc_odc2 v0_ot_pp_csc_odc2; /* 0x1240 */ + volatile u_v0_ot_pp_csc_min_y v0_ot_pp_csc_min_y; /* 0x1244 */ + volatile u_v0_ot_pp_csc_min_c v0_ot_pp_csc_min_c; /* 0x1248 */ + volatile u_v0_ot_pp_csc_max_y v0_ot_pp_csc_max_y; /* 0x124c */ + volatile u_v0_ot_pp_csc_max_c v0_ot_pp_csc_max_c; /* 0x1250 */ + volatile u_v0_ot_pp_csc2_coef00 v0_ot_pp_csc2_coef00; /* 0x1254 */ + volatile u_v0_ot_pp_csc2_coef01 v0_ot_pp_csc2_coef01; /* 0x1258 */ + volatile u_v0_ot_pp_csc2_coef02 v0_ot_pp_csc2_coef02; /* 0x125c */ + volatile u_v0_ot_pp_csc2_coef10 v0_ot_pp_csc2_coef10; /* 0x1260 */ + volatile u_v0_ot_pp_csc2_coef11 v0_ot_pp_csc2_coef11; /* 0x1264 */ + volatile u_v0_ot_pp_csc2_coef12 v0_ot_pp_csc2_coef12; /* 0x1268 */ + volatile u_v0_ot_pp_csc2_coef20 v0_ot_pp_csc2_coef20; /* 0x126c */ + volatile u_v0_ot_pp_csc2_coef21 v0_ot_pp_csc2_coef21; /* 0x1270 */ + volatile u_v0_ot_pp_csc2_coef22 v0_ot_pp_csc2_coef22; /* 0x1274 */ + volatile u_v0_ot_pp_csc2_scale v0_ot_pp_csc2_scale; /* 0x1278 */ + volatile u_v0_ot_pp_csc2_idc0 v0_ot_pp_csc2_idc0; /* 0x127c */ + volatile u_v0_ot_pp_csc2_idc1 v0_ot_pp_csc2_idc1; /* 0x1280 */ + volatile u_v0_ot_pp_csc2_idc2 v0_ot_pp_csc2_idc2; /* 0x1284 */ + volatile u_v0_ot_pp_csc2_odc0 v0_ot_pp_csc2_odc0; /* 0x1288 */ + volatile u_v0_ot_pp_csc2_odc1 v0_ot_pp_csc2_odc1; /* 0x128c */ + volatile u_v0_ot_pp_csc2_odc2 v0_ot_pp_csc2_odc2; /* 0x1290 */ + volatile u_v0_ot_pp_csc2_min_y v0_ot_pp_csc2_min_y; /* 0x1294 */ + volatile u_v0_ot_pp_csc2_min_c v0_ot_pp_csc2_min_c; /* 0x1298 */ + volatile u_v0_ot_pp_csc2_max_y v0_ot_pp_csc2_max_y; /* 0x129c */ + volatile u_v0_ot_pp_csc2_max_c v0_ot_pp_csc2_max_c; /* 0x12a0 */ + volatile unsigned int reserved_27[19]; /* 19:0x12a4~0x12ec */ + volatile u_v0_ot_pp_csc_ink_ctrl v0_ot_pp_csc_ink_ctrl; /* 0x12f0 */ + volatile u_v0_ot_pp_csc_ink_pos v0_ot_pp_csc_ink_pos; /* 0x12f4 */ + volatile unsigned int v0_ot_pp_csc_ink_data; /* 0x12f8 */ + volatile unsigned int v0_ot_pp_csc_ink_data2; /* 0x12fc */ + volatile u_v0_zme_hinfo v0_zme_hinfo; /* 0x1300 */ + volatile u_v0_zme_hsp v0_zme_hsp; /* 0x1304 */ + volatile u_v0_zme_hloffset v0_zme_hloffset; /* 0x1308 */ + volatile u_v0_zme_hcoffset v0_zme_hcoffset; /* 0x130c */ + volatile u_v0_zme_hzone0delta v0_zme_hzone0delta; /* 0x1310 */ + volatile u_v0_zme_hzone2delta v0_zme_hzone2delta; /* 0x1314 */ + volatile u_v0_zme_hzoneend v0_zme_hzoneend; /* 0x1318 */ + volatile u_v0_zme_hl_shootctrl v0_zme_hl_shootctrl; /* 0x131c */ + volatile u_v0_zme_hc_shootctrl v0_zme_hc_shootctrl; /* 0x1320 */ + volatile u_v0_zme_hcoef_ren v0_zme_hcoef_ren; /* 0x1324 */ + volatile u_v0_zme_hcoef_rdata v0_zme_hcoef_rdata; /* 0x1328 */ + volatile unsigned int reserved_28[53]; /* 53:0x132c~0x13fc */ + volatile u_v0_zme_vinfo v0_zme_vinfo; /* 0x1400 */ + volatile u_v0_zme_vsp v0_zme_vsp; /* 0x1404 */ + volatile u_v0_zme_voffset v0_zme_voffset; /* 0x1408 */ + volatile u_v0_zme_vboffset v0_zme_vboffset; /* 0x140c */ + volatile unsigned int reserved_29[3]; /* 3:0x1410~0x1418 */ + volatile u_v0_zme_vl_shootctrl v0_zme_vl_shootctrl; /* 0x141c */ + volatile u_v0_zme_vc_shootctrl v0_zme_vc_shootctrl; /* 0x1420 */ + volatile u_v0_zme_vcoef_ren v0_zme_vcoef_ren; /* 0x1424 */ + volatile u_v0_zme_vcoef_rdata v0_zme_vcoef_rdata; /* 0x1428 */ + volatile unsigned int reserved_30[53]; /* 53:0x142c~0x14fc */ + volatile u_v0_hfir_ctrl v0_hfir_ctrl; /* 0x1500 */ + volatile u_v0_hfircoef01 v0_hfircoef01; /* 0x1504 */ + volatile u_v0_hfircoef23 v0_hfircoef23; /* 0x1508 */ + volatile u_v0_hfircoef45 v0_hfircoef45; /* 0x150c */ + volatile u_v0_hfircoef67 v0_hfircoef67; /* 0x1510 */ + volatile unsigned int reserved_31[699]; /* 699:0x1514~0x1ffc */ + volatile u_v1_ctrl v1_ctrl; /* 0x2000 */ + volatile u_v1_upd v1_upd; /* 0x2004 */ + volatile u_v1_0reso_read v1_0reso_read; /* 0x2008 */ + volatile unsigned int reserved_32; /* 0x200c */ + volatile u_v1_ireso v1_ireso; /* 0x2010 */ + volatile unsigned int reserved_33[27]; /* 27:0x2014~0x207c */ + volatile u_v1_dfpos v1_dfpos; /* 0x2080 */ + volatile u_v1_dlpos v1_dlpos; /* 0x2084 */ + volatile u_v1_vfpos v1_vfpos; /* 0x2088 */ + volatile u_v1_vlpos v1_vlpos; /* 0x208c */ + volatile u_v1_bk v1_bk; /* 0x2090 */ + volatile u_v1_alpha v1_alpha; /* 0x2094 */ + volatile u_v1_mute_bk v1_mute_bk; /* 0x2098 */ + volatile unsigned int reserved_34; /* 0x209c */ + volatile u_v1_rimwidth v1_rimwidth; /* 0x20a0 */ + volatile u_v1_rimcol0 v1_rimcol0; /* 0x20a4 */ + volatile u_v1_rimcol1 v1_rimcol1; /* 0x20a8 */ + volatile unsigned int reserved_35[85]; /* 85:0x20ac~0x21fc */ + volatile u_v1_ot_pp_csc_ctrl v1_ot_pp_csc_ctrl; /* 0x2200 */ + volatile u_v1_ot_pp_csc_coef00 v1_ot_pp_csc_coef00; /* 0x2204 */ + volatile u_v1_ot_pp_csc_coef01 v1_ot_pp_csc_coef01; /* 0x2208 */ + volatile u_v1_ot_pp_csc_coef02 v1_ot_pp_csc_coef02; /* 0x220c */ + volatile u_v1_ot_pp_csc_coef10 v1_ot_pp_csc_coef10; /* 0x2210 */ + volatile u_v1_ot_pp_csc_coef11 v1_ot_pp_csc_coef11; /* 0x2214 */ + volatile u_v1_ot_pp_csc_coef12 v1_ot_pp_csc_coef12; /* 0x2218 */ + volatile u_v1_ot_pp_csc_coef20 v1_ot_pp_csc_coef20; /* 0x221c */ + volatile u_v1_ot_pp_csc_coef21 v1_ot_pp_csc_coef21; /* 0x2220 */ + volatile u_v1_ot_pp_csc_coef22 v1_ot_pp_csc_coef22; /* 0x2224 */ + volatile u_v1_ot_pp_csc_scale v1_ot_pp_csc_scale; /* 0x2228 */ + volatile u_v1_ot_pp_csc_idc0 v1_ot_pp_csc_idc0; /* 0x222c */ + volatile u_v1_ot_pp_csc_idc1 v1_ot_pp_csc_idc1; /* 0x2230 */ + volatile u_v1_ot_pp_csc_idc2 v1_ot_pp_csc_idc2; /* 0x2234 */ + volatile u_v1_ot_pp_csc_odc0 v1_ot_pp_csc_odc0; /* 0x2238 */ + volatile u_v1_ot_pp_csc_odc1 v1_ot_pp_csc_odc1; /* 0x223c */ + volatile u_v1_ot_pp_csc_odc2 v1_ot_pp_csc_odc2; /* 0x2240 */ + volatile u_v1_ot_pp_csc_min_y v1_ot_pp_csc_min_y; /* 0x2244 */ + volatile u_v1_ot_pp_csc_min_c v1_ot_pp_csc_min_c; /* 0x2248 */ + volatile u_v1_ot_pp_csc_max_y v1_ot_pp_csc_max_y; /* 0x224c */ + volatile u_v1_ot_pp_csc_max_c v1_ot_pp_csc_max_c; /* 0x2250 */ + volatile u_v1_ot_pp_csc2_coef00 v1_ot_pp_csc2_coef00; /* 0x2254 */ + volatile u_v1_ot_pp_csc2_coef01 v1_ot_pp_csc2_coef01; /* 0x2258 */ + volatile u_v1_ot_pp_csc2_coef02 v1_ot_pp_csc2_coef02; /* 0x225c */ + volatile u_v1_ot_pp_csc2_coef10 v1_ot_pp_csc2_coef10; /* 0x2260 */ + volatile u_v1_ot_pp_csc2_coef11 v1_ot_pp_csc2_coef11; /* 0x2264 */ + volatile u_v1_ot_pp_csc2_coef12 v1_ot_pp_csc2_coef12; /* 0x2268 */ + volatile u_v1_ot_pp_csc2_coef20 v1_ot_pp_csc2_coef20; /* 0x226c */ + volatile u_v1_ot_pp_csc2_coef21 v1_ot_pp_csc2_coef21; /* 0x2270 */ + volatile u_v1_ot_pp_csc2_coef22 v1_ot_pp_csc2_coef22; /* 0x2274 */ + volatile u_v1_ot_pp_csc2_scale v1_ot_pp_csc2_scale; /* 0x2278 */ + volatile u_v1_ot_pp_csc2_idc0 v1_ot_pp_csc2_idc0; /* 0x227c */ + volatile u_v1_ot_pp_csc2_idc1 v1_ot_pp_csc2_idc1; /* 0x2280 */ + volatile u_v1_ot_pp_csc2_idc2 v1_ot_pp_csc2_idc2; /* 0x2284 */ + volatile u_v1_ot_pp_csc2_odc0 v1_ot_pp_csc2_odc0; /* 0x2288 */ + volatile u_v1_ot_pp_csc2_odc1 v1_ot_pp_csc2_odc1; /* 0x228c */ + volatile u_v1_ot_pp_csc2_odc2 v1_ot_pp_csc2_odc2; /* 0x2290 */ + volatile u_v1_ot_pp_csc2_min_y v1_ot_pp_csc2_min_y; /* 0x2294 */ + volatile u_v1_ot_pp_csc2_min_c v1_ot_pp_csc2_min_c; /* 0x2298 */ + volatile u_v1_ot_pp_csc2_max_y v1_ot_pp_csc2_max_y; /* 0x229c */ + volatile u_v1_ot_pp_csc2_max_c v1_ot_pp_csc2_max_c; /* 0x22a0 */ + volatile unsigned int reserved_36[19]; /* 19:0x22a4~0x22ec */ + volatile u_v1_ot_pp_csc_ink_ctrl v1_ot_pp_csc_ink_ctrl; /* 0x22f0 */ + volatile u_v1_ot_pp_csc_ink_pos v1_ot_pp_csc_ink_pos; /* 0x22f4 */ + volatile unsigned int v1_ot_pp_csc_ink_data; /* 0x22f8 */ + volatile unsigned int v1_ot_pp_csc_ink_data2; /* 0x22fc */ + volatile unsigned int reserved_37[64]; /* 64:0x2300~0x23fc */ + volatile u_v1_cvfir_vinfo v1_cvfir_vinfo; /* 0x2400 */ + volatile u_v1_cvfir_vsp v1_cvfir_vsp; /* 0x2404 */ + volatile u_v1_cvfir_voffset v1_cvfir_voffset; /* 0x2408 */ + volatile u_v1_cvfir_vboffset v1_cvfir_vboffset; /* 0x240c */ + volatile unsigned int reserved_38[8]; /* 8:0x2410~0x242c */ + volatile u_v1_cvfir_vcoef0 v1_cvfir_vcoef0; /* 0x2430 */ + volatile u_v1_cvfir_vcoef1 v1_cvfir_vcoef1; /* 0x2434 */ + volatile u_v1_cvfir_vcoef2 v1_cvfir_vcoef2; /* 0x2438 */ + volatile unsigned int reserved_39[49]; /* 49:0x243c~0x24fc */ + volatile u_v1_hfir_ctrl v1_hfir_ctrl; /* 0x2500 */ + volatile u_v1_hfircoef01 v1_hfircoef01; /* 0x2504 */ + volatile u_v1_hfircoef23 v1_hfircoef23; /* 0x2508 */ + volatile u_v1_hfircoef45 v1_hfircoef45; /* 0x250c */ + volatile u_v1_hfircoef67 v1_hfircoef67; /* 0x2510 */ + volatile unsigned int reserved_40[699]; /* 699:0x2514~0x2ffc */ + volatile u_v2_ctrl v2_ctrl; /* 0x3000 */ + volatile u_v2_upd v2_upd; /* 0x3004 */ + volatile u_v2_0reso_read v2_0reso_read; /* 0x3008 */ + volatile unsigned int reserved_41; /* 0x300c */ + volatile u_v2_ireso v2_ireso; /* 0x3010 */ + volatile unsigned int reserved_42[27]; /* 27:0x3014~0x307c */ + volatile u_v2_dfpos v2_dfpos; /* 0x3080 */ + volatile u_v2_dlpos v2_dlpos; /* 0x3084 */ + volatile u_v2_vfpos v2_vfpos; /* 0x3088 */ + volatile u_v2_vlpos v2_vlpos; /* 0x308c */ + volatile u_v2_bk v2_bk; /* 0x3090 */ + volatile u_v2_alpha v2_alpha; /* 0x3094 */ + volatile u_v2_mute_bk v2_mute_bk; /* 0x3098 */ + volatile unsigned int reserved_43[89]; /* 89:0x309c~0x31fc */ + volatile u_v2_ot_pp_csc_ctrl v2_ot_pp_csc_ctrl; /* 0x3200 */ + volatile u_v2_ot_pp_csc_coef00 v2_ot_pp_csc_coef00; /* 0x3204 */ + volatile u_v2_ot_pp_csc_coef01 v2_ot_pp_csc_coef01; /* 0x3208 */ + volatile u_v2_ot_pp_csc_coef02 v2_ot_pp_csc_coef02; /* 0x320c */ + volatile u_v2_ot_pp_csc_coef10 v2_ot_pp_csc_coef10; /* 0x3210 */ + volatile u_v2_ot_pp_csc_coef11 v2_ot_pp_csc_coef11; /* 0x3214 */ + volatile u_v2_ot_pp_csc_coef12 v2_ot_pp_csc_coef12; /* 0x3218 */ + volatile u_v2_ot_pp_csc_coef20 v2_ot_pp_csc_coef20; /* 0x321c */ + volatile u_v2_ot_pp_csc_coef21 v2_ot_pp_csc_coef21; /* 0x3220 */ + volatile u_v2_ot_pp_csc_coef22 v2_ot_pp_csc_coef22; /* 0x3224 */ + volatile u_v2_ot_pp_csc_scale v2_ot_pp_csc_scale; /* 0x3228 */ + volatile u_v2_ot_pp_csc_idc0 v2_ot_pp_csc_idc0; /* 0x322c */ + volatile u_v2_ot_pp_csc_idc1 v2_ot_pp_csc_idc1; /* 0x3230 */ + volatile u_v2_ot_pp_csc_idc2 v2_ot_pp_csc_idc2; /* 0x3234 */ + volatile u_v2_ot_pp_csc_odc0 v2_ot_pp_csc_odc0; /* 0x3238 */ + volatile u_v2_ot_pp_csc_odc1 v2_ot_pp_csc_odc1; /* 0x323c */ + volatile u_v2_ot_pp_csc_odc2 v2_ot_pp_csc_odc2; /* 0x3240 */ + volatile u_v2_ot_pp_csc_min_y v2_ot_pp_csc_min_y; /* 0x3244 */ + volatile u_v2_ot_pp_csc_min_c v2_ot_pp_csc_min_c; /* 0x3248 */ + volatile u_v2_ot_pp_csc_max_y v2_ot_pp_csc_max_y; /* 0x324c */ + volatile u_v2_ot_pp_csc_max_c v2_ot_pp_csc_max_c; /* 0x3250 */ + volatile u_v2_ot_pp_csc2_coef00 v2_ot_pp_csc2_coef00; /* 0x3254 */ + volatile u_v2_ot_pp_csc2_coef01 v2_ot_pp_csc2_coef01; /* 0x3258 */ + volatile u_v2_ot_pp_csc2_coef02 v2_ot_pp_csc2_coef02; /* 0x325c */ + volatile u_v2_ot_pp_csc2_coef10 v2_ot_pp_csc2_coef10; /* 0x3260 */ + volatile u_v2_ot_pp_csc2_coef11 v2_ot_pp_csc2_coef11; /* 0x3264 */ + volatile u_v2_ot_pp_csc2_coef12 v2_ot_pp_csc2_coef12; /* 0x3268 */ + volatile u_v2_ot_pp_csc2_coef20 v2_ot_pp_csc2_coef20; /* 0x326c */ + volatile u_v2_ot_pp_csc2_coef21 v2_ot_pp_csc2_coef21; /* 0x3270 */ + volatile u_v2_ot_pp_csc2_coef22 v2_ot_pp_csc2_coef22; /* 0x3274 */ + volatile u_v2_ot_pp_csc2_scale v2_ot_pp_csc2_scale; /* 0x3278 */ + volatile u_v2_ot_pp_csc2_idc0 v2_ot_pp_csc2_idc0; /* 0x327c */ + volatile u_v2_ot_pp_csc2_idc1 v2_ot_pp_csc2_idc1; /* 0x3280 */ + volatile u_v2_ot_pp_csc2_idc2 v2_ot_pp_csc2_idc2; /* 0x3284 */ + volatile u_v2_ot_pp_csc2_odc0 v2_ot_pp_csc2_odc0; /* 0x3288 */ + volatile u_v2_ot_pp_csc2_odc1 v2_ot_pp_csc2_odc1; /* 0x328c */ + volatile u_v2_ot_pp_csc2_odc2 v2_ot_pp_csc2_odc2; /* 0x3290 */ + volatile u_v2_ot_pp_csc2_min_y v2_ot_pp_csc2_min_y; /* 0x3294 */ + volatile u_v2_ot_pp_csc2_min_c v2_ot_pp_csc2_min_c; /* 0x3298 */ + volatile u_v2_ot_pp_csc2_max_y v2_ot_pp_csc2_max_y; /* 0x329c */ + volatile u_v2_ot_pp_csc2_max_c v2_ot_pp_csc2_max_c; /* 0x32a0 */ + volatile unsigned int reserved_44[19]; /* 19:0x32a4~0x32ec */ + volatile u_v2_ot_pp_csc_ink_ctrl v2_ot_pp_csc_ink_ctrl; /* 0x32f0 */ + volatile u_v2_ot_pp_csc_ink_pos v2_ot_pp_csc_ink_pos; /* 0x32f4 */ + volatile unsigned int v2_ot_pp_csc_ink_data; /* 0x32f8 */ + volatile unsigned int v2_ot_pp_csc_ink_data2; /* 0x32fc */ + volatile unsigned int reserved_45[64]; /* 64:0x3300~0x33fc */ + volatile u_v2_cvfir_vinfo v2_cvfir_vinfo; /* 0x3400 */ + volatile u_v2_cvfir_vsp v2_cvfir_vsp; /* 0x3404 */ + volatile u_v2_cvfir_voffset v2_cvfir_voffset; /* 0x3408 */ + volatile u_v2_cvfir_vboffset v2_cvfir_vboffset; /* 0x340c */ + volatile unsigned int reserved_46[8]; /* 8:0x3410~0x342c */ + volatile u_v2_cvfir_vcoef0 v2_cvfir_vcoef0; /* 0x3430 */ + volatile u_v2_cvfir_vcoef1 v2_cvfir_vcoef1; /* 0x3434 */ + volatile u_v2_cvfir_vcoef2 v2_cvfir_vcoef2; /* 0x3438 */ + volatile unsigned int reserved_47[49]; /* 49:0x343c~0x34fc */ + volatile u_v2_hfir_ctrl v2_hfir_ctrl; /* 0x3500 */ + volatile u_v2_hfircoef01 v2_hfircoef01; /* 0x3504 */ + volatile u_v2_hfircoef23 v2_hfircoef23; /* 0x3508 */ + volatile u_v2_hfircoef45 v2_hfircoef45; /* 0x350c */ + volatile u_v2_hfircoef67 v2_hfircoef67; /* 0x3510 */ + volatile unsigned int reserved_48[699]; /* 699:0x3514~0x3ffc */ + volatile u_v3_ctrl v3_ctrl; /* 0x4000 */ + volatile u_v3_upd v3_upd; /* 0x4004 */ + volatile u_v3_0reso_read v3_0reso_read; /* 0x4008 */ + volatile unsigned int reserved_49; /* 0x400c */ + volatile u_v3_ireso v3_ireso; /* 0x4010 */ + volatile unsigned int reserved_50[27]; /* 27:0x4014~0x407c */ + volatile u_v3_dfpos v3_dfpos; /* 0x4080 */ + volatile u_v3_dlpos v3_dlpos; /* 0x4084 */ + volatile u_v3_vfpos v3_vfpos; /* 0x4088 */ + volatile u_v3_vlpos v3_vlpos; /* 0x408c */ + volatile u_v3_bk v3_bk; /* 0x4090 */ + volatile u_v3_alpha v3_alpha; /* 0x4094 */ + volatile u_v3_mute_bk v3_mute_bk; /* 0x4098 */ + volatile unsigned int reserved_51; /* 0x409c */ + volatile u_v3_rimwidth v3_rimwidth; /* 0x40a0 */ + volatile u_v3_rimcol0 v3_rimcol0; /* 0x40a4 */ + volatile u_v3_rimcol1 v3_rimcol1; /* 0x40a8 */ + volatile unsigned int reserved_52[85]; /* 85:0x40ac~0x41fc */ + volatile u_v3_ot_pp_csc_ctrl v3_ot_pp_csc_ctrl; /* 0x4200 */ + volatile u_v3_ot_pp_csc_coef00 v3_ot_pp_csc_coef00; /* 0x4204 */ + volatile u_v3_ot_pp_csc_coef01 v3_ot_pp_csc_coef01; /* 0x4208 */ + volatile u_v3_ot_pp_csc_coef02 v3_ot_pp_csc_coef02; /* 0x420c */ + volatile u_v3_ot_pp_csc_coef10 v3_ot_pp_csc_coef10; /* 0x4210 */ + volatile u_v3_ot_pp_csc_coef11 v3_ot_pp_csc_coef11; /* 0x4214 */ + volatile u_v3_ot_pp_csc_coef12 v3_ot_pp_csc_coef12; /* 0x4218 */ + volatile u_v3_ot_pp_csc_coef20 v3_ot_pp_csc_coef20; /* 0x421c */ + volatile u_v3_ot_pp_csc_coef21 v3_ot_pp_csc_coef21; /* 0x4220 */ + volatile u_v3_ot_pp_csc_coef22 v3_ot_pp_csc_coef22; /* 0x4224 */ + volatile u_v3_ot_pp_csc_scale v3_ot_pp_csc_scale; /* 0x4228 */ + volatile u_v3_ot_pp_csc_idc0 v3_ot_pp_csc_idc0; /* 0x422c */ + volatile u_v3_ot_pp_csc_idc1 v3_ot_pp_csc_idc1; /* 0x4230 */ + volatile u_v3_ot_pp_csc_idc2 v3_ot_pp_csc_idc2; /* 0x4234 */ + volatile u_v3_ot_pp_csc_odc0 v3_ot_pp_csc_odc0; /* 0x4238 */ + volatile u_v3_ot_pp_csc_odc1 v3_ot_pp_csc_odc1; /* 0x423c */ + volatile u_v3_ot_pp_csc_odc2 v3_ot_pp_csc_odc2; /* 0x4240 */ + volatile u_v3_ot_pp_csc_min_y v3_ot_pp_csc_min_y; /* 0x4244 */ + volatile u_v3_ot_pp_csc_min_c v3_ot_pp_csc_min_c; /* 0x4248 */ + volatile u_v3_ot_pp_csc_max_y v3_ot_pp_csc_max_y; /* 0x424c */ + volatile u_v3_ot_pp_csc_max_c v3_ot_pp_csc_max_c; /* 0x4250 */ + volatile u_v3_ot_pp_csc2_coef00 v3_ot_pp_csc2_coef00; /* 0x4254 */ + volatile u_v3_ot_pp_csc2_coef01 v3_ot_pp_csc2_coef01; /* 0x4258 */ + volatile u_v3_ot_pp_csc2_coef02 v3_ot_pp_csc2_coef02; /* 0x425c */ + volatile u_v3_ot_pp_csc2_coef10 v3_ot_pp_csc2_coef10; /* 0x4260 */ + volatile u_v3_ot_pp_csc2_coef11 v3_ot_pp_csc2_coef11; /* 0x4264 */ + volatile u_v3_ot_pp_csc2_coef12 v3_ot_pp_csc2_coef12; /* 0x4268 */ + volatile u_v3_ot_pp_csc2_coef20 v3_ot_pp_csc2_coef20; /* 0x426c */ + volatile u_v3_ot_pp_csc2_coef21 v3_ot_pp_csc2_coef21; /* 0x4270 */ + volatile u_v3_ot_pp_csc2_coef22 v3_ot_pp_csc2_coef22; /* 0x4274 */ + volatile u_v3_ot_pp_csc2_scale v3_ot_pp_csc2_scale; /* 0x4278 */ + volatile u_v3_ot_pp_csc2_idc0 v3_ot_pp_csc2_idc0; /* 0x427c */ + volatile u_v3_ot_pp_csc2_idc1 v3_ot_pp_csc2_idc1; /* 0x4280 */ + volatile u_v3_ot_pp_csc2_idc2 v3_ot_pp_csc2_idc2; /* 0x4284 */ + volatile u_v3_ot_pp_csc2_odc0 v3_ot_pp_csc2_odc0; /* 0x4288 */ + volatile u_v3_ot_pp_csc2_odc1 v3_ot_pp_csc2_odc1; /* 0x428c */ + volatile u_v3_ot_pp_csc2_odc2 v3_ot_pp_csc2_odc2; /* 0x4290 */ + volatile u_v3_ot_pp_csc2_min_y v3_ot_pp_csc2_min_y; /* 0x4294 */ + volatile u_v3_ot_pp_csc2_min_c v3_ot_pp_csc2_min_c; /* 0x4298 */ + volatile u_v3_ot_pp_csc2_max_y v3_ot_pp_csc2_max_y; /* 0x429c */ + volatile u_v3_ot_pp_csc2_max_c v3_ot_pp_csc2_max_c; /* 0x42a0 */ + volatile unsigned int reserved_53[19]; /* 19:0x42a4~0x42ec */ + volatile u_v3_ot_pp_csc_ink_ctrl v3_ot_pp_csc_ink_ctrl; /* 0x42f0 */ + volatile u_v3_ot_pp_csc_ink_pos v3_ot_pp_csc_ink_pos; /* 0x42f4 */ + volatile unsigned int v3_ot_pp_csc_ink_data; /* 0x42f8 */ + volatile unsigned int v3_ot_pp_csc_ink_data2; /* 0x42fc */ + volatile unsigned int reserved_54[128]; /* 128:0x4300~0x44fc */ + volatile u_v3_hfir_ctrl v3_hfir_ctrl; /* 0x4500 */ + volatile u_v3_hfircoef01 v3_hfircoef01; /* 0x4504 */ + volatile u_v3_hfircoef23 v3_hfircoef23; /* 0x4508 */ + volatile u_v3_hfircoef45 v3_hfircoef45; /* 0x450c */ + volatile u_v3_hfircoef67 v3_hfircoef67; /* 0x4510 */ + volatile unsigned int reserved_55[1211]; /* 1211:0x4514~0x57fc */ + volatile unsigned int vp0_ctrl; /* 0x5800 */ + volatile u_vp0_upd vp0_upd; /* 0x5804 */ + volatile u_vp0_ireso vp0_ireso; /* 0x5808 */ + volatile unsigned int reserved_56[29]; /* 29:0x580c~0x587c */ + volatile u_vp0_lbox_ctrl vp0_lbox_ctrl; /* 0x5880 */ + volatile u_vp0_galpha vp0_galpha; /* 0x5884 */ + volatile u_vp0_dfpos vp0_dfpos; /* 0x5888 */ + volatile u_vp0_dlpos vp0_dlpos; /* 0x588c */ + volatile u_vp0_vfpos vp0_vfpos; /* 0x5890 */ + volatile u_vp0_vlpos vp0_vlpos; /* 0x5894 */ + volatile u_vp0_bk vp0_bk; /* 0x5898 */ + volatile u_vp0_alpha vp0_alpha; /* 0x589c */ + volatile u_vp0_mute_bk vp0_mute_bk; /* 0x58a0 */ + volatile unsigned int reserved_57[1495]; /* 1495:0x58a4~0x6ffc */ + volatile u_g0_ctrl g0_ctrl; /* 0x7000 */ + volatile u_g0_upd g0_upd; /* 0x7004 */ + volatile unsigned int g0_galpha_sum; /* 0x7008 */ + volatile u_g0_0reso_read g0_0reso_read; /* 0x700c */ + volatile u_g0_ireso g0_ireso; /* 0x7010 */ + volatile unsigned int reserved_58[27]; /* 27:0x7014~0x707c */ + volatile u_g0_dfpos g0_dfpos; /* 0x7080 */ + volatile u_g0_dlpos g0_dlpos; /* 0x7084 */ + volatile u_g0_vfpos g0_vfpos; /* 0x7088 */ + volatile u_g0_vlpos g0_vlpos; /* 0x708c */ + volatile u_g0_bk g0_bk; /* 0x7090 */ + volatile u_g0_alpha g0_alpha; /* 0x7094 */ + volatile u_g0_mute_bk g0_mute_bk; /* 0x7098 */ + volatile u_g0_lbox_ctrl g0_lbox_ctrl; /* 0x709c */ + volatile unsigned int reserved_59[24]; /* 24:0x70a0~0x70fc */ + volatile u_g0_ot_pp_csc_ctrl g0_ot_pp_csc_ctrl; /* 0x7100 */ + volatile u_g0_ot_pp_csc_coef00 g0_ot_pp_csc_coef00; /* 0x7104 */ + volatile u_g0_ot_pp_csc_coef01 g0_ot_pp_csc_coef01; /* 0x7108 */ + volatile u_g0_ot_pp_csc_coef02 g0_ot_pp_csc_coef02; /* 0x710c */ + volatile u_g0_ot_pp_csc_coef10 g0_ot_pp_csc_coef10; /* 0x7110 */ + volatile u_g0_ot_pp_csc_coef11 g0_ot_pp_csc_coef11; /* 0x7114 */ + volatile u_g0_ot_pp_csc_coef12 g0_ot_pp_csc_coef12; /* 0x7118 */ + volatile u_g0_ot_pp_csc_coef20 g0_ot_pp_csc_coef20; /* 0x711c */ + volatile u_g0_ot_pp_csc_coef21 g0_ot_pp_csc_coef21; /* 0x7120 */ + volatile u_g0_ot_pp_csc_coef22 g0_ot_pp_csc_coef22; /* 0x7124 */ + volatile u_g0_ot_pp_csc_scale g0_ot_pp_csc_scale; /* 0x7128 */ + volatile u_g0_ot_pp_csc_idc0 g0_ot_pp_csc_idc0; /* 0x712c */ + volatile u_g0_ot_pp_csc_idc1 g0_ot_pp_csc_idc1; /* 0x7130 */ + volatile u_g0_ot_pp_csc_idc2 g0_ot_pp_csc_idc2; /* 0x7134 */ + volatile u_g0_ot_pp_csc_odc0 g0_ot_pp_csc_odc0; /* 0x7138 */ + volatile u_g0_ot_pp_csc_odc1 g0_ot_pp_csc_odc1; /* 0x713c */ + volatile u_g0_ot_pp_csc_odc2 g0_ot_pp_csc_odc2; /* 0x7140 */ + volatile u_g0_ot_pp_csc_min_y g0_ot_pp_csc_min_y; /* 0x7144 */ + volatile u_g0_ot_pp_csc_min_c g0_ot_pp_csc_min_c; /* 0x7148 */ + volatile u_g0_ot_pp_csc_max_y g0_ot_pp_csc_max_y; /* 0x714c */ + volatile u_g0_ot_pp_csc_max_c g0_ot_pp_csc_max_c; /* 0x7150 */ + volatile u_g0_ot_pp_csc2_coef00 g0_ot_pp_csc2_coef00; /* 0x7154 */ + volatile u_g0_ot_pp_csc2_coef01 g0_ot_pp_csc2_coef01; /* 0x7158 */ + volatile u_g0_ot_pp_csc2_coef02 g0_ot_pp_csc2_coef02; /* 0x715c */ + volatile u_g0_ot_pp_csc2_coef10 g0_ot_pp_csc2_coef10; /* 0x7160 */ + volatile u_g0_ot_pp_csc2_coef11 g0_ot_pp_csc2_coef11; /* 0x7164 */ + volatile u_g0_ot_pp_csc2_coef12 g0_ot_pp_csc2_coef12; /* 0x7168 */ + volatile u_g0_ot_pp_csc2_coef20 g0_ot_pp_csc2_coef20; /* 0x716c */ + volatile u_g0_ot_pp_csc2_coef21 g0_ot_pp_csc2_coef21; /* 0x7170 */ + volatile u_g0_ot_pp_csc2_coef22 g0_ot_pp_csc2_coef22; /* 0x7174 */ + volatile u_g0_ot_pp_csc2_scale g0_ot_pp_csc2_scale; /* 0x7178 */ + volatile u_g0_ot_pp_csc2_idc0 g0_ot_pp_csc2_idc0; /* 0x717c */ + volatile u_g0_ot_pp_csc2_idc1 g0_ot_pp_csc2_idc1; /* 0x7180 */ + volatile u_g0_ot_pp_csc2_idc2 g0_ot_pp_csc2_idc2; /* 0x7184 */ + volatile u_g0_ot_pp_csc2_odc0 g0_ot_pp_csc2_odc0; /* 0x7188 */ + volatile u_g0_ot_pp_csc2_odc1 g0_ot_pp_csc2_odc1; /* 0x718c */ + volatile u_g0_ot_pp_csc2_odc2 g0_ot_pp_csc2_odc2; /* 0x7190 */ + volatile u_g0_ot_pp_csc2_min_y g0_ot_pp_csc2_min_y; /* 0x7194 */ + volatile u_g0_ot_pp_csc2_min_c g0_ot_pp_csc2_min_c; /* 0x7198 */ + volatile u_g0_ot_pp_csc2_max_y g0_ot_pp_csc2_max_y; /* 0x719c */ + volatile u_g0_ot_pp_csc2_max_c g0_ot_pp_csc2_max_c; /* 0x71a0 */ + volatile unsigned int reserved_60[19]; /* 19:0x71a4~0x71ec */ + volatile u_g0_ot_pp_csc_ink_ctrl g0_ot_pp_csc_ink_ctrl; /* 0x71f0 */ + volatile u_g0_ot_pp_csc_ink_pos g0_ot_pp_csc_ink_pos; /* 0x71f4 */ + volatile unsigned int g0_ot_pp_csc_ink_data; /* 0x71f8 */ + volatile unsigned int g0_ot_pp_csc_ink_data2; /* 0x71fc */ + volatile u_g0_dof_ctrl g0_dof_ctrl; /* 0x7200 */ + volatile u_g0_dof_step g0_dof_step; /* 0x7204 */ + volatile u_g0_dof_bkg g0_dof_bkg; /* 0x7208 */ + volatile u_g0_dof_alpha g0_dof_alpha; /* 0x720c */ + volatile unsigned int reserved_61[60]; /* 60:0x7210~0x72fc */ + volatile u_g0_zme_hinfo g0_zme_hinfo; /* 0x7300 */ + volatile u_g0_zme_hsp g0_zme_hsp; /* 0x7304 */ + volatile u_g0_zme_hloffset g0_zme_hloffset; /* 0x7308 */ + volatile u_g0_zme_hcoffset g0_zme_hcoffset; /* 0x730c */ + volatile unsigned int reserved_62[5]; /* 5:0x7310~0x7320 */ + volatile u_g0_zme_coef_ren g0_zme_coef_ren; /* 0x7324 */ + volatile u_g0_zme_coef_rdata g0_zme_coef_rdata; /* 0x7328 */ + volatile unsigned int reserved_63[21]; /* 21:0x732c~0x737c */ + volatile u_g0_zme_vinfo g0_zme_vinfo; /* 0x7380 */ + volatile u_g0_zme_vsp g0_zme_vsp; /* 0x7384 */ + volatile u_g0_zme_voffset g0_zme_voffset; /* 0x7388 */ + volatile unsigned int reserved_64[285]; /* 285:0x738c~0x77fc */ + volatile u_g1_ctrl g1_ctrl; /* 0x7800 */ + volatile u_g1_upd g1_upd; /* 0x7804 */ + volatile unsigned int g1_galpha_sum; /* 0x7808 */ + volatile u_g1_0reso_read g1_0reso_read; /* 0x780c */ + volatile u_g1_ireso g1_ireso; /* 0x7810 */ + volatile unsigned int reserved_65[27]; /* 27:0x7814~0x787c */ + volatile u_g1_dfpos g1_dfpos; /* 0x7880 */ + volatile u_g1_dlpos g1_dlpos; /* 0x7884 */ + volatile u_g1_vfpos g1_vfpos; /* 0x7888 */ + volatile u_g1_vlpos g1_vlpos; /* 0x788c */ + volatile u_g1_bk g1_bk; /* 0x7890 */ + volatile u_g1_alpha g1_alpha; /* 0x7894 */ + volatile u_g1_mute_bk g1_mute_bk; /* 0x7898 */ + volatile u_g1_lbox_ctrl g1_lbox_ctrl; /* 0x789c */ + volatile unsigned int reserved_66[24]; /* 24:0x78a0~0x78fc */ + volatile u_g1_ot_pp_csc_ctrl g1_ot_pp_csc_ctrl; /* 0x7900 */ + volatile u_g1_ot_pp_csc_coef00 g1_ot_pp_csc_coef00; /* 0x7904 */ + volatile u_g1_ot_pp_csc_coef01 g1_ot_pp_csc_coef01; /* 0x7908 */ + volatile u_g1_ot_pp_csc_coef02 g1_ot_pp_csc_coef02; /* 0x790c */ + volatile u_g1_ot_pp_csc_coef10 g1_ot_pp_csc_coef10; /* 0x7910 */ + volatile u_g1_ot_pp_csc_coef11 g1_ot_pp_csc_coef11; /* 0x7914 */ + volatile u_g1_ot_pp_csc_coef12 g1_ot_pp_csc_coef12; /* 0x7918 */ + volatile u_g1_ot_pp_csc_coef20 g1_ot_pp_csc_coef20; /* 0x791c */ + volatile u_g1_ot_pp_csc_coef21 g1_ot_pp_csc_coef21; /* 0x7920 */ + volatile u_g1_ot_pp_csc_coef22 g1_ot_pp_csc_coef22; /* 0x7924 */ + volatile u_g1_ot_pp_csc_scale g1_ot_pp_csc_scale; /* 0x7928 */ + volatile u_g1_ot_pp_csc_idc0 g1_ot_pp_csc_idc0; /* 0x792c */ + volatile u_g1_ot_pp_csc_idc1 g1_ot_pp_csc_idc1; /* 0x7930 */ + volatile u_g1_ot_pp_csc_idc2 g1_ot_pp_csc_idc2; /* 0x7934 */ + volatile u_g1_ot_pp_csc_odc0 g1_ot_pp_csc_odc0; /* 0x7938 */ + volatile u_g1_ot_pp_csc_odc1 g1_ot_pp_csc_odc1; /* 0x793c */ + volatile u_g1_ot_pp_csc_odc2 g1_ot_pp_csc_odc2; /* 0x7940 */ + volatile u_g1_ot_pp_csc_min_y g1_ot_pp_csc_min_y; /* 0x7944 */ + volatile u_g1_ot_pp_csc_min_c g1_ot_pp_csc_min_c; /* 0x7948 */ + volatile u_g1_ot_pp_csc_max_y g1_ot_pp_csc_max_y; /* 0x794c */ + volatile u_g1_ot_pp_csc_max_c g1_ot_pp_csc_max_c; /* 0x7950 */ + volatile u_g1_ot_pp_csc2_coef00 g1_ot_pp_csc2_coef00; /* 0x7954 */ + volatile u_g1_ot_pp_csc2_coef01 g1_ot_pp_csc2_coef01; /* 0x7958 */ + volatile u_g1_ot_pp_csc2_coef02 g1_ot_pp_csc2_coef02; /* 0x795c */ + volatile u_g1_ot_pp_csc2_coef10 g1_ot_pp_csc2_coef10; /* 0x7960 */ + volatile u_g1_ot_pp_csc2_coef11 g1_ot_pp_csc2_coef11; /* 0x7964 */ + volatile u_g1_ot_pp_csc2_coef12 g1_ot_pp_csc2_coef12; /* 0x7968 */ + volatile u_g1_ot_pp_csc2_coef20 g1_ot_pp_csc2_coef20; /* 0x796c */ + volatile u_g1_ot_pp_csc2_coef21 g1_ot_pp_csc2_coef21; /* 0x7970 */ + volatile u_g1_ot_pp_csc2_coef22 g1_ot_pp_csc2_coef22; /* 0x7974 */ + volatile u_g1_ot_pp_csc2_scale g1_ot_pp_csc2_scale; /* 0x7978 */ + volatile u_g1_ot_pp_csc2_idc0 g1_ot_pp_csc2_idc0; /* 0x797c */ + volatile u_g1_ot_pp_csc2_idc1 g1_ot_pp_csc2_idc1; /* 0x7980 */ + volatile u_g1_ot_pp_csc2_idc2 g1_ot_pp_csc2_idc2; /* 0x7984 */ + volatile u_g1_ot_pp_csc2_odc0 g1_ot_pp_csc2_odc0; /* 0x7988 */ + volatile u_g1_ot_pp_csc2_odc1 g1_ot_pp_csc2_odc1; /* 0x798c */ + volatile u_g1_ot_pp_csc2_odc2 g1_ot_pp_csc2_odc2; /* 0x7990 */ + volatile u_g1_ot_pp_csc2_min_y g1_ot_pp_csc2_min_y; /* 0x7994 */ + volatile u_g1_ot_pp_csc2_min_c g1_ot_pp_csc2_min_c; /* 0x7998 */ + volatile u_g1_ot_pp_csc2_max_y g1_ot_pp_csc2_max_y; /* 0x799c */ + volatile u_g1_ot_pp_csc2_max_c g1_ot_pp_csc2_max_c; /* 0x79a0 */ + volatile unsigned int reserved_67[19]; /* 19:0x79a4~0x79ec */ + volatile u_g1_ot_pp_csc_ink_ctrl g1_ot_pp_csc_ink_ctrl; /* 0x79f0 */ + volatile u_g1_ot_pp_csc_ink_pos g1_ot_pp_csc_ink_pos; /* 0x79f4 */ + volatile unsigned int g1_ot_pp_csc_ink_data; /* 0x79f8 */ + volatile unsigned int g1_ot_pp_csc_ink_data2; /* 0x79fc */ + volatile unsigned int reserved_68[64]; /* 64:0x7a00~0x7afc */ + volatile u_g1_zme_hinfo g1_zme_hinfo; /* 0x7b00 */ + volatile u_g1_zme_hsp g1_zme_hsp; /* 0x7b04 */ + volatile u_g1_zme_hloffset g1_zme_hloffset; /* 0x7b08 */ + volatile u_g1_zme_hcoffset g1_zme_hcoffset; /* 0x7b0c */ + volatile unsigned int reserved_69[5]; /* 5:0x7b10~0x7b20 */ + volatile u_g1_zme_coef_ren g1_zme_coef_ren; /* 0x7b24 */ + volatile u_g1_zme_coef_rdata g1_zme_coef_rdata; /* 0x7b28 */ + volatile unsigned int reserved_70[21]; /* 21:0x7b2c~0x7b7c */ + volatile u_g1_zme_vinfo g1_zme_vinfo; /* 0x7b80 */ + volatile u_g1_zme_vsp g1_zme_vsp; /* 0x7b84 */ + volatile u_g1_zme_voffset g1_zme_voffset; /* 0x7b88 */ + volatile unsigned int reserved_71[285]; /* 285:0x7b8c~0x7ffc */ + volatile u_g2_ctrl g2_ctrl; /* 0x8000 */ + volatile u_g2_upd g2_upd; /* 0x8004 */ + volatile unsigned int g2_galpha_sum; /* 0x8008 */ + volatile u_g2_0reso_read g2_0reso_read; /* 0x800c */ + volatile u_g2_ireso g2_ireso; /* 0x8010 */ + volatile unsigned int reserved_72[27]; /* 27:0x8014~0x807c */ + volatile u_g2_dfpos g2_dfpos; /* 0x8080 */ + volatile u_g2_dlpos g2_dlpos; /* 0x8084 */ + volatile u_g2_vfpos g2_vfpos; /* 0x8088 */ + volatile u_g2_vlpos g2_vlpos; /* 0x808c */ + volatile u_g2_bk g2_bk; /* 0x8090 */ + volatile u_g2_alpha g2_alpha; /* 0x8094 */ + volatile u_g2_mute_bk g2_mute_bk; /* 0x8098 */ + volatile u_g2_lbox_ctrl g2_lbox_ctrl; /* 0x809c */ + volatile unsigned int reserved_73[24]; /* 24:0x80a0~0x80fc */ + volatile u_g2_ot_pp_csc_ctrl g2_ot_pp_csc_ctrl; /* 0x8100 */ + volatile u_g2_ot_pp_csc_coef00 g2_ot_pp_csc_coef00; /* 0x8104 */ + volatile u_g2_ot_pp_csc_coef01 g2_ot_pp_csc_coef01; /* 0x8108 */ + volatile u_g2_ot_pp_csc_coef02 g2_ot_pp_csc_coef02; /* 0x810c */ + volatile u_g2_ot_pp_csc_coef10 g2_ot_pp_csc_coef10; /* 0x8110 */ + volatile u_g2_ot_pp_csc_coef11 g2_ot_pp_csc_coef11; /* 0x8114 */ + volatile u_g2_ot_pp_csc_coef12 g2_ot_pp_csc_coef12; /* 0x8118 */ + volatile u_g2_ot_pp_csc_coef20 g2_ot_pp_csc_coef20; /* 0x811c */ + volatile u_g2_ot_pp_csc_coef21 g2_ot_pp_csc_coef21; /* 0x8120 */ + volatile u_g2_ot_pp_csc_coef22 g2_ot_pp_csc_coef22; /* 0x8124 */ + volatile u_g2_ot_pp_csc_scale g2_ot_pp_csc_scale; /* 0x8128 */ + volatile u_g2_ot_pp_csc_idc0 g2_ot_pp_csc_idc0; /* 0x812c */ + volatile u_g2_ot_pp_csc_idc1 g2_ot_pp_csc_idc1; /* 0x8130 */ + volatile u_g2_ot_pp_csc_idc2 g2_ot_pp_csc_idc2; /* 0x8134 */ + volatile u_g2_ot_pp_csc_odc0 g2_ot_pp_csc_odc0; /* 0x8138 */ + volatile u_g2_ot_pp_csc_odc1 g2_ot_pp_csc_odc1; /* 0x813c */ + volatile u_g2_ot_pp_csc_odc2 g2_ot_pp_csc_odc2; /* 0x8140 */ + volatile u_g2_ot_pp_csc_min_y g2_ot_pp_csc_min_y; /* 0x8144 */ + volatile u_g2_ot_pp_csc_min_c g2_ot_pp_csc_min_c; /* 0x8148 */ + volatile u_g2_ot_pp_csc_max_y g2_ot_pp_csc_max_y; /* 0x814c */ + volatile u_g2_ot_pp_csc_max_c g2_ot_pp_csc_max_c; /* 0x8150 */ + volatile u_g2_ot_pp_csc2_coef00 g2_ot_pp_csc2_coef00; /* 0x8154 */ + volatile u_g2_ot_pp_csc2_coef01 g2_ot_pp_csc2_coef01; /* 0x8158 */ + volatile u_g2_ot_pp_csc2_coef02 g2_ot_pp_csc2_coef02; /* 0x815c */ + volatile u_g2_ot_pp_csc2_coef10 g2_ot_pp_csc2_coef10; /* 0x8160 */ + volatile u_g2_ot_pp_csc2_coef11 g2_ot_pp_csc2_coef11; /* 0x8164 */ + volatile u_g2_ot_pp_csc2_coef12 g2_ot_pp_csc2_coef12; /* 0x8168 */ + volatile u_g2_ot_pp_csc2_coef20 g2_ot_pp_csc2_coef20; /* 0x816c */ + volatile u_g2_ot_pp_csc2_coef21 g2_ot_pp_csc2_coef21; /* 0x8170 */ + volatile u_g2_ot_pp_csc2_coef22 g2_ot_pp_csc2_coef22; /* 0x8174 */ + volatile u_g2_ot_pp_csc2_scale g2_ot_pp_csc2_scale; /* 0x8178 */ + volatile u_g2_ot_pp_csc2_idc0 g2_ot_pp_csc2_idc0; /* 0x817c */ + volatile u_g2_ot_pp_csc2_idc1 g2_ot_pp_csc2_idc1; /* 0x8180 */ + volatile u_g2_ot_pp_csc2_idc2 g2_ot_pp_csc2_idc2; /* 0x8184 */ + volatile u_g2_ot_pp_csc2_odc0 g2_ot_pp_csc2_odc0; /* 0x8188 */ + volatile u_g2_ot_pp_csc2_odc1 g2_ot_pp_csc2_odc1; /* 0x818c */ + volatile u_g2_ot_pp_csc2_odc2 g2_ot_pp_csc2_odc2; /* 0x8190 */ + volatile u_g2_ot_pp_csc2_min_y g2_ot_pp_csc2_min_y; /* 0x8194 */ + volatile u_g2_ot_pp_csc2_min_c g2_ot_pp_csc2_min_c; /* 0x8198 */ + volatile u_g2_ot_pp_csc2_max_y g2_ot_pp_csc2_max_y; /* 0x819c */ + volatile u_g2_ot_pp_csc2_max_c g2_ot_pp_csc2_max_c; /* 0x81a0 */ + volatile unsigned int reserved_74[19]; /* 19:0x81a4~0x81ec */ + volatile u_g2_ot_pp_csc_ink_ctrl g2_ot_pp_csc_ink_ctrl; /* 0x81f0 */ + volatile u_g2_ot_pp_csc_ink_pos g2_ot_pp_csc_ink_pos; /* 0x81f4 */ + volatile unsigned int g2_ot_pp_csc_ink_data; /* 0x81f8 */ + volatile unsigned int g2_ot_pp_csc_ink_data2; /* 0x81fc */ + volatile unsigned int reserved_75[384]; /* 384:0x8200~0x87fc */ + volatile u_g3_ctrl g3_ctrl; /* 0x8800 */ + volatile u_g3_upd g3_upd; /* 0x8804 */ + volatile unsigned int g3_galpha_sum; /* 0x8808 */ + volatile u_g3_0reso_read g3_0reso_read; /* 0x880c */ + volatile u_g3_ireso g3_ireso; /* 0x8810 */ + volatile unsigned int reserved_76[27]; /* 27:0x8814~0x887c */ + volatile u_g3_dfpos g3_dfpos; /* 0x8880 */ + volatile u_g3_dlpos g3_dlpos; /* 0x8884 */ + volatile u_g3_vfpos g3_vfpos; /* 0x8888 */ + volatile u_g3_vlpos g3_vlpos; /* 0x888c */ + volatile u_g3_bk g3_bk; /* 0x8890 */ + volatile u_g3_alpha g3_alpha; /* 0x8894 */ + volatile u_g3_mute_bk g3_mute_bk; /* 0x8898 */ + volatile u_g3_lbox_ctrl g3_lbox_ctrl; /* 0x889c */ + volatile unsigned int reserved_77[24]; /* 24:0x88a0~0x88fc */ + volatile u_g3_ot_pp_csc_ctrl g3_ot_pp_csc_ctrl; /* 0x8900 */ + volatile u_g3_ot_pp_csc_coef00 g3_ot_pp_csc_coef00; /* 0x8904 */ + volatile u_g3_ot_pp_csc_coef01 g3_ot_pp_csc_coef01; /* 0x8908 */ + volatile u_g3_ot_pp_csc_coef02 g3_ot_pp_csc_coef02; /* 0x890c */ + volatile u_g3_ot_pp_csc_coef10 g3_ot_pp_csc_coef10; /* 0x8910 */ + volatile u_g3_ot_pp_csc_coef11 g3_ot_pp_csc_coef11; /* 0x8914 */ + volatile u_g3_ot_pp_csc_coef12 g3_ot_pp_csc_coef12; /* 0x8918 */ + volatile u_g3_ot_pp_csc_coef20 g3_ot_pp_csc_coef20; /* 0x891c */ + volatile u_g3_ot_pp_csc_coef21 g3_ot_pp_csc_coef21; /* 0x8920 */ + volatile u_g3_ot_pp_csc_coef22 g3_ot_pp_csc_coef22; /* 0x8924 */ + volatile u_g3_ot_pp_csc_scale g3_ot_pp_csc_scale; /* 0x8928 */ + volatile u_g3_ot_pp_csc_idc0 g3_ot_pp_csc_idc0; /* 0x892c */ + volatile u_g3_ot_pp_csc_idc1 g3_ot_pp_csc_idc1; /* 0x8930 */ + volatile u_g3_ot_pp_csc_idc2 g3_ot_pp_csc_idc2; /* 0x8934 */ + volatile u_g3_ot_pp_csc_odc0 g3_ot_pp_csc_odc0; /* 0x8938 */ + volatile u_g3_ot_pp_csc_odc1 g3_ot_pp_csc_odc1; /* 0x893c */ + volatile u_g3_ot_pp_csc_odc2 g3_ot_pp_csc_odc2; /* 0x8940 */ + volatile u_g3_ot_pp_csc_min_y g3_ot_pp_csc_min_y; /* 0x8944 */ + volatile u_g3_ot_pp_csc_min_c g3_ot_pp_csc_min_c; /* 0x8948 */ + volatile u_g3_ot_pp_csc_max_y g3_ot_pp_csc_max_y; /* 0x894c */ + volatile u_g3_ot_pp_csc_max_c g3_ot_pp_csc_max_c; /* 0x8950 */ + volatile u_g3_ot_pp_csc2_coef00 g3_ot_pp_csc2_coef00; /* 0x8954 */ + volatile u_g3_ot_pp_csc2_coef01 g3_ot_pp_csc2_coef01; /* 0x8958 */ + volatile u_g3_ot_pp_csc2_coef02 g3_ot_pp_csc2_coef02; /* 0x895c */ + volatile u_g3_ot_pp_csc2_coef10 g3_ot_pp_csc2_coef10; /* 0x8960 */ + volatile u_g3_ot_pp_csc2_coef11 g3_ot_pp_csc2_coef11; /* 0x8964 */ + volatile u_g3_ot_pp_csc2_coef12 g3_ot_pp_csc2_coef12; /* 0x8968 */ + volatile u_g3_ot_pp_csc2_coef20 g3_ot_pp_csc2_coef20; /* 0x896c */ + volatile u_g3_ot_pp_csc2_coef21 g3_ot_pp_csc2_coef21; /* 0x8970 */ + volatile u_g3_ot_pp_csc2_coef22 g3_ot_pp_csc2_coef22; /* 0x8974 */ + volatile u_g3_ot_pp_csc2_scale g3_ot_pp_csc2_scale; /* 0x8978 */ + volatile u_g3_ot_pp_csc2_idc0 g3_ot_pp_csc2_idc0; /* 0x897c */ + volatile u_g3_ot_pp_csc2_idc1 g3_ot_pp_csc2_idc1; /* 0x8980 */ + volatile u_g3_ot_pp_csc2_idc2 g3_ot_pp_csc2_idc2; /* 0x8984 */ + volatile u_g3_ot_pp_csc2_odc0 g3_ot_pp_csc2_odc0; /* 0x8988 */ + volatile u_g3_ot_pp_csc2_odc1 g3_ot_pp_csc2_odc1; /* 0x898c */ + volatile u_g3_ot_pp_csc2_odc2 g3_ot_pp_csc2_odc2; /* 0x8990 */ + volatile u_g3_ot_pp_csc2_min_y g3_ot_pp_csc2_min_y; /* 0x8994 */ + volatile u_g3_ot_pp_csc2_min_c g3_ot_pp_csc2_min_c; /* 0x8998 */ + volatile u_g3_ot_pp_csc2_max_y g3_ot_pp_csc2_max_y; /* 0x899c */ + volatile u_g3_ot_pp_csc2_max_c g3_ot_pp_csc2_max_c; /* 0x89a0 */ + volatile unsigned int reserved_78[19]; /* 19:0x89a4~0x89ec */ + volatile u_g3_ot_pp_csc_ink_ctrl g3_ot_pp_csc_ink_ctrl; /* 0x89f0 */ + volatile u_g3_ot_pp_csc_ink_pos g3_ot_pp_csc_ink_pos; /* 0x89f4 */ + volatile unsigned int g3_ot_pp_csc_ink_data; /* 0x89f8 */ + volatile unsigned int g3_ot_pp_csc_ink_data2; /* 0x89fc */ + volatile u_osb_mute_bk osb_mute_bk; /* 0x8a00 */ + volatile u_osb_bk_alpha osb_bk_alpha; /* 0x8a04 */ + volatile u_osb_coef_rd_en osb_coef_rd_en; /* 0x8a08 */ + volatile unsigned int osb_coef_rd_addr; /* 0x8a0c */ + volatile unsigned int reserved_79[892]; /* 892:0x8a10~0x97fc 892 regs */ + volatile unsigned int gp0_ctrl; /* 0x9800 */ + volatile u_gp0_upd gp0_upd; /* 0x9804 */ + volatile u_gp0_ireso gp0_ireso; /* 0x9808 */ + volatile unsigned int reserved_80[29]; /* 29:0x980c~0x987c */ + volatile u_gp0_lbox_ctrl gp0_lbox_ctrl; /* 0x9880 */ + volatile u_gp0_galpha gp0_galpha; /* 0x9884 */ + volatile unsigned int gp0_galpha_sum; /* 0x9888 */ + volatile u_gp0_dfpos gp0_dfpos; /* 0x988c */ + volatile u_gp0_dlpos gp0_dlpos; /* 0x9890 */ + volatile u_gp0_vfpos gp0_vfpos; /* 0x9894 */ + volatile u_gp0_vlpos gp0_vlpos; /* 0x9898 */ + volatile u_gp0_bk gp0_bk; /* 0x989c */ + volatile u_gp0_alpha gp0_alpha; /* 0x98a0 */ + volatile u_gp0_mute_bk gp0_mute_bk; /* 0x98a4 */ + volatile unsigned int reserved_81[22]; /* 22:0x98a8~0x98fc */ + volatile u_gp0_csc_idc gp0_csc_idc; /* 0x9900 */ + volatile u_gp0_csc_odc gp0_csc_odc; /* 0x9904 */ + volatile u_gp0_csc_iodc gp0_csc_iodc; /* 0x9908 */ + volatile u_gp0_csc_p0 gp0_csc_p0; /* 0x990c */ + volatile u_gp0_csc_p1 gp0_csc_p1; /* 0x9910 */ + volatile u_gp0_csc_p2 gp0_csc_p2; /* 0x9914 */ + volatile u_gp0_csc_p3 gp0_csc_p3; /* 0x9918 */ + volatile u_gp0_csc_p4 gp0_csc_p4; /* 0x991c */ + volatile unsigned int reserved_82[1464]; /* 1464:0x9920~0xaffc */ + volatile u_wbc_g0_ctrl wbc_g0_ctrl; /* 0xb000 */ + volatile u_wbc_g0_upd wbc_g0_upd; /* 0xb004 */ + volatile u_wbc_g0_cmp wbc_g0_cmp; /* 0xb008 */ + volatile unsigned int reserved_83; /* 0xb00c */ + volatile unsigned int wbc_g0_ar_addr; /* 0xb010 */ + volatile unsigned int wbc_g0_gb_addr; /* 0xb014 */ + volatile u_wbc_g0_stride wbc_g0_stride; /* 0xb018 */ + volatile unsigned int wbc_g0_offset; /* 0xb01c */ + volatile u_wbc_g0_oreso wbc_g0_oreso; /* 0xb020 */ + volatile u_wbc_g0_fcrop wbc_g0_fcrop; /* 0xb024 */ + volatile u_wbc_g0_lcrop wbc_g0_lcrop; /* 0xb028 */ + volatile unsigned int reserved_84[501]; /* 501:0xb02c~0xb7fc */ + volatile u_wbc_gp0_ctrl wbc_gp0_ctrl; /* 0xb800 */ + volatile u_wbc_gp0_upd wbc_gp0_upd; /* 0xb804 */ + volatile unsigned int reserved_85[2]; /* 2:0xb808~0xb80c */ + volatile unsigned int wbc_gp0_yaddr; /* 0xb810 */ + volatile unsigned int wbc_gp0_caddr; /* 0xb814 */ + volatile u_wbc_gp0_stride wbc_gp0_stride; /* 0xb818 */ + volatile unsigned int reserved_86; /* 0xb81c */ + volatile u_wbc_gp0_oreso wbc_gp0_oreso; /* 0xb820 */ + volatile u_wbc_gp0_fcrop wbc_gp0_fcrop; /* 0xb824 */ + volatile u_wbc_gp0_lcrop wbc_gp0_lcrop; /* 0xb828 */ + volatile unsigned int reserved_87[53]; /* 53:0xb82c~0xb8fc */ + volatile u_wbc_gp0_dither_ctrl wbc_gp0_dither_ctrl; /* 0xb900 */ + volatile u_wbc_gp0_dither_coef0 wbc_gp0_dither_coef0; /* 0xb904 */ + volatile u_wbc_gp0_dither_coef1 wbc_gp0_dither_coef1; /* 0xb908 */ + volatile unsigned int reserved_88[17]; /* 17:0xb90c~0xb94c */ + volatile u_wbc_gp0_hpzme wbc_gp0_hpzme; /* 0xb950 */ + volatile unsigned int reserved_89[43]; /* 43:0xb954~0xb9fc */ + volatile u_wbc_me_ctrl wbc_me_ctrl; /* 0xba00 */ + volatile u_wbc_me_upd wbc_me_upd; /* 0xba04 */ + volatile u_wbc_me_wlen_sel wbc_me_wlen_sel; /* 0xba08 */ + volatile unsigned int reserved_90; /* 0xba0c */ + volatile unsigned int wbc_me_yaddr; /* 0xba10 */ + volatile unsigned int wbc_me_caddr; /* 0xba14 */ + volatile u_wbc_me_stride wbc_me_stride; /* 0xba18 */ + volatile unsigned int reserved_91; /* 0xba1c */ + volatile u_wbc_me_oreso wbc_me_oreso; /* 0xba20 */ + volatile unsigned int reserved_92[2]; /* 2:0xba24~0xba28 */ + volatile u_wbc_me_smmu_bypass wbc_me_smmu_bypass; /* 0xba2c */ + volatile unsigned int reserved_93[4]; /* 4:0xba30~0xba3c */ + volatile u_wbc_me_paraup wbc_me_paraup; /* 0xba40 */ + volatile unsigned int reserved_94[3]; /* 3:0xba44~0xba4c */ + volatile unsigned int wbc_me_hlcoefad; /* 0xba50 */ + volatile unsigned int wbc_me_hccoefad; /* 0xba54 */ + volatile unsigned int wbc_me_vlcoefad; /* 0xba58 */ + volatile unsigned int wbc_me_vccoefad; /* 0xba5c */ + volatile unsigned int reserved_95[36]; /* 36:0xba60~0xbaec */ + volatile unsigned int wbc_me_checksum_y; /* 0xbaf0 */ + volatile unsigned int wbc_me_checksum_c; /* 0xbaf4 */ + volatile unsigned int reserved_96[2]; /* 2:0xbaf8~0xbafc */ + volatile u_wbc_me_dither_ctrl wbc_me_dither_ctrl; /* 0xbb00 */ + volatile u_wbc_me_dither_coef0 wbc_me_dither_coef0; /* 0xbb04 */ + volatile u_wbc_me_dither_coef1 wbc_me_dither_coef1; /* 0xbb08 */ + volatile unsigned int reserved_97[109]; /* 109:0xbb0c~0xbcbc */ + volatile u_wbc_me_zme_hsp wbc_me_zme_hsp; /* 0xbcc0 */ + volatile u_wbc_me_zme_hloffset wbc_me_zme_hloffset; /* 0xbcc4 */ + volatile u_wbc_me_zme_hcoffset wbc_me_zme_hcoffset; /* 0xbcc8 */ + volatile unsigned int reserved_98[3]; /* 3:0xbccc~0xbcd4 */ + volatile u_wbc_me_zme_vsp wbc_me_zme_vsp; /* 0xbcd8 */ + volatile u_wbc_me_zme_vsr wbc_me_zme_vsr; /* 0xbcdc */ + volatile u_wbc_me_zme_voffset wbc_me_zme_voffset; /* 0xbce0 */ + volatile u_wbc_me_zme_vboffset wbc_me_zme_vboffset; /* 0xbce4 */ + volatile unsigned int reserved_99[6]; /* 6:0xbce8~0xbcfc */ + volatile u_wbc_fi_ctrl wbc_fi_ctrl; /* 0xbd00 */ + volatile u_wbc_fi_upd wbc_fi_upd; /* 0xbd04 */ + volatile u_wbc_fi_wlen_sel wbc_fi_wlen_sel; /* 0xbd08 */ + volatile unsigned int reserved_100; /* 0xbd0c */ + volatile unsigned int wbc_fi_yaddr; /* 0xbd10 */ + volatile unsigned int wbc_fi_caddr; /* 0xbd14 */ + volatile u_wbc_fi_stride wbc_fi_stride; /* 0xbd18 */ + volatile unsigned int reserved_101; /* 0xbd1c */ + volatile u_wbc_fi_oreso wbc_fi_oreso; /* 0xbd20 */ + volatile unsigned int reserved_102[2]; /* 2:0xbd24~0xbd28 */ + volatile u_wbc_fi_smmu_bypass wbc_fi_smmu_bypass; /* 0xbd2c */ + volatile unsigned int reserved_103[5]; /* 5:0xbd30~0xbd40 */ + volatile u_wbc_fi_frame_size wbc_fi_frame_size; /* 0xbd44 */ + volatile unsigned int wbc_fi_y_raddr; /* 0xbd48 */ + volatile unsigned int wbc_fi_c_raddr; /* 0xbd4c */ + volatile unsigned int reserved_104[40]; /* 40:0xbd50~0xbdec */ + volatile unsigned int wbc_fi_checksum_y; /* 0xbdf0 */ + volatile unsigned int wbc_fi_checksum_c; /* 0xbdf4 */ + volatile unsigned int reserved_105[6]; /* 6:0xbdf8~0xbe0c */ + volatile u_wbc_fi_hcds wbc_fi_hcds; /* 0xbe10 */ + volatile u_wbc_fi_hcds_coef0 wbc_fi_hcds_coef0; /* 0xbe14 */ + volatile u_wbc_fi_hcds_coef1 wbc_fi_hcds_coef1; /* 0xbe18 */ + volatile unsigned int reserved_106; /* 0xbe1c */ + volatile u_wbc_fi_cmp_mb wbc_fi_cmp_mb; /* 0xbe20 */ + volatile u_wbc_fi_cmp_max_min wbc_fi_cmp_max_min; /* 0xbe24 */ + volatile u_wbc_fi_cmp_adj_thr wbc_fi_cmp_adj_thr; /* 0xbe28 */ + volatile u_wbc_fi_cmp_big_grad wbc_fi_cmp_big_grad; /* 0xbe2c */ + volatile u_wbc_fi_cmp_blk wbc_fi_cmp_blk; /* 0xbe30 */ + volatile u_wbc_fi_cmp_graphic_judge wbc_fi_cmp_graphic_judge; /* 0xbe34 */ + volatile u_wbc_fi_cmp_rc wbc_fi_cmp_rc; /* 0xbe38 */ + volatile u_wbc_fi_cmp_frame_size wbc_fi_cmp_frame_size; /* 0xbe3c */ + volatile unsigned int reserved_107[48]; /* 48:0xbe40~0xbefc */ + volatile u_wbc_cmp_glb_info wbc_cmp_glb_info; /* 0xbf00 */ + volatile u_wbc_cmp_framesize wbc_cmp_framesize; /* 0xbf04 */ + volatile u_wbc_cmp_rc_cfg0 wbc_cmp_rc_cfg0; /* 0xbf08 */ + volatile u_wbc_cmp_rc_cfg2 wbc_cmp_rc_cfg2; /* 0xbf0c */ + volatile u_wbc_cmp_rc_cfg3 wbc_cmp_rc_cfg3; /* 0xbf10 */ + volatile u_wbc_cmp_rc_cfg4 wbc_cmp_rc_cfg4; /* 0xbf14 */ + volatile u_wbc_cmp_rc_cfg5 wbc_cmp_rc_cfg5; /* 0xbf18 */ + volatile u_wbc_cmp_rc_cfg6 wbc_cmp_rc_cfg6; /* 0xbf1c */ + volatile u_wbc_cmp_rc_cfg7 wbc_cmp_rc_cfg7; /* 0xbf20 */ + volatile u_wbc_cmp_rc_cfg8 wbc_cmp_rc_cfg8; /* 0xbf24 */ + volatile u_wbc_cmp_rc_cfg10 wbc_cmp_rc_cfg10; /* 0xbf28 */ + volatile u_wbc_cmp_outsize0 wbc_cmp_outsize0; /* 0xbf2c */ + volatile unsigned int wbc_cmp_dbg_reg0; /* 0xbf30 */ + volatile u_wbc_cmp_max_row wbc_cmp_max_row; /* 0xbf34 */ + volatile u_wbc_bmp_ctrl wbc_bmp_ctrl; /* 0xbf38 */ + volatile u_wbc_bmp_upd wbc_bmp_upd; /* 0xbf3c */ + volatile unsigned int wbc_bmp_yaddr; /* 0xbf40 */ + volatile unsigned int reserved_108[23]; /* 23:0xbf44~0xbf9c */ + volatile u_wbc_bmp_oreso wbc_bmp_oreso; /* 0xbfa0 */ + volatile u_wbc_bmp_sum wbc_bmp_sum; /* 0xbfa4 */ + volatile unsigned int reserved_109[18]; /* 18:0xbfa8~0xbfec */ + volatile unsigned int wbc_bmp_checksum_y; /* 0xbff0 */ + volatile unsigned int wbc_bmp_checksum_c; /* 0xbff4 */ + volatile unsigned int reserved_110[2]; /* 2:0xbff8~0xbffc */ + volatile u_wbc_dhd0_ctrl wbc_dhd0_ctrl; /* 0xc000 */ + volatile u_wbc_dhd0_upd wbc_dhd0_upd; /* 0xc004 */ + volatile u_wbc_dhd0_oreso wbc_dhd0_oreso; /* 0xc008 */ + volatile unsigned int reserved_111[29]; /* 29:0xc00c~0xc07c */ + volatile u_wd_hpzme_ctrl wd_hpzme_ctrl; /* 0xc080 */ + volatile u_wd_hpzmecoef01 wd_hpzmecoef01; /* 0xc084 */ + volatile u_wd_hpzmecoef23 wd_hpzmecoef23; /* 0xc088 */ + volatile u_wd_hpzmecoef45 wd_hpzmecoef45; /* 0xc08c */ + volatile u_wd_hpzmecoef67 wd_hpzmecoef67; /* 0xc090 */ + volatile unsigned int reserved_112[91]; /* 91:0xc094~0xc1fc */ + volatile u_wd_hcds_ctrl wd_hcds_ctrl; /* 0xc200 */ + volatile u_wd_hcdscoef01 wd_hcdscoef01; /* 0xc204 */ + volatile u_wd_hcdscoef23 wd_hcdscoef23; /* 0xc208 */ + volatile u_wd_hcdscoef45 wd_hcdscoef45; /* 0xc20c */ + volatile u_wd_hcdscoef67 wd_hcdscoef67; /* 0xc210 */ + volatile unsigned int reserved_113[27]; /* 27:0xc214~0xc27c */ + volatile u_dither_ctrl dither_ctrl; /* 0xc280 */ + volatile u_dither_sed_y0 dither_sed_y0; /* 0xc284 */ + volatile u_dither_sed_u0 dither_sed_u0; /* 0xc288 */ + volatile u_dither_sed_v0 dither_sed_v0; /* 0xc28c */ + volatile u_dither_sed_w0 dither_sed_w0; /* 0xc290 */ + volatile u_dither_sed_y1 dither_sed_y1; /* 0xc294 */ + volatile u_dither_sed_u1 dither_sed_u1; /* 0xc298 */ + volatile u_dither_sed_v1 dither_sed_v1; /* 0xc29c */ + volatile u_dither_sed_w1 dither_sed_w1; /* 0xc2a0 */ + volatile u_dither_sed_y2 dither_sed_y2; /* 0xc2a4 */ + volatile u_dither_sed_u2 dither_sed_u2; /* 0xc2a8 */ + volatile u_dither_sed_v2 dither_sed_v2; /* 0xc2ac */ + volatile u_dither_sed_w2 dither_sed_w2; /* 0xc2b0 */ + volatile u_dither_sed_y3 dither_sed_y3; /* 0xc2b4 */ + volatile u_dither_sed_u3 dither_sed_u3; /* 0xc2b8 */ + volatile u_dither_sed_v3 dither_sed_v3; /* 0xc2bc */ + volatile u_dither_sed_w3 dither_sed_w3; /* 0xc2c0 */ + volatile u_dither_thr dither_thr; /* 0xc2c4 */ + volatile unsigned int reserved_114[14]; /* 14:0xc2c8~0xc2fc */ + volatile u_wd_zme_hinfo wd_zme_hinfo; /* 0xc300 */ + volatile u_wd_zme_hsp wd_zme_hsp; /* 0xc304 */ + volatile u_wd_zme_hloffset wd_zme_hloffset; /* 0xc308 */ + volatile u_wd_zme_hcoffset wd_zme_hcoffset; /* 0xc30c */ + volatile unsigned int reserved_115[5]; /* 5:0xc310~0xc320 */ + volatile u_wd_zme_hcoef_ren wd_zme_hcoef_ren; /* 0xc324 */ + volatile u_wd_zme_hcoef_rdata wd_zme_hcoef_rdata; /* 0xc328 */ + volatile u_wd_zme_hdraw wd_zme_hdraw; /* 0xc32c */ + volatile u_wd_zme_hratio wd_zme_hratio; /* 0xc330 */ + volatile unsigned int reserved_116[51]; /* 51:0xc334~0xc3fc */ + volatile u_wd_zme_vinfo wd_zme_vinfo; /* 0xc400 */ + volatile u_wd_zme_vsp wd_zme_vsp; /* 0xc404 */ + volatile u_wd_zme_voffset wd_zme_voffset; /* 0xc408 */ + volatile u_wd_zme_vboffset wd_zme_vboffset; /* 0xc40c */ + volatile unsigned int reserved_117[5]; /* 5:0xc410~0xc420 */ + volatile u_wd_zme_vcoef_ren wd_zme_vcoef_ren; /* 0xc424 */ + volatile u_wd_zme_vcoef_rdata wd_zme_vcoef_rdata; /* 0xc428 */ + volatile u_wd_zme_vdraw wd_zme_vdraw; /* 0xc42c */ + volatile u_wd_zme_vratio wd_zme_vratio; /* 0xc430 */ + volatile unsigned int reserved_118[755]; /* 755:0xc434~0xcffc */ + volatile u_dhd0_ctrl dhd0_ctrl; /* 0xd000 */ + volatile u_dhd0_vsync1 dhd0_vsync1; /* 0xd004 */ + volatile u_dhd0_vsync2 dhd0_vsync2; /* 0xd008 */ + volatile u_dhd0_hsync1 dhd0_hsync1; /* 0xd00c */ + volatile u_dhd0_hsync2 dhd0_hsync2; /* 0xd010 */ + volatile u_dhd0_vplus1 dhd0_vplus1; /* 0xd014 */ + volatile u_dhd0_vplus2 dhd0_vplus2; /* 0xd018 */ + volatile u_dhd0_pwr dhd0_pwr; /* 0xd01c */ + volatile u_dhd0_vtthd3 dhd0_vtthd3; /* 0xd020 */ + volatile u_dhd0_vtthd dhd0_vtthd; /* 0xd024 */ + volatile u_dhd0_parathd dhd0_parathd; /* 0xd028 */ + volatile u_dhd0_precharge_thd dhd0_precharge_thd; /* 0xd02c */ + volatile u_dhd0_start_pos dhd0_start_pos; /* 0xd030 */ + volatile u_dhd0_start_pos1 dhd0_start_pos1; /* 0xd034 */ + volatile u_dhd0_paraup dhd0_paraup; /* 0xd038 */ + volatile u_dhd0_sync_inv dhd0_sync_inv; /* 0xd03c */ + volatile u_dhd0_clk_dv_ctrl dhd0_clk_dv_ctrl; /* 0xd040 */ + volatile u_dhd0_rgb_fix_ctrl dhd0_rgb_fix_ctrl; /* 0xd044 */ + volatile u_dhd0_lockcfg dhd0_lockcfg; /* 0xd048 */ + volatile unsigned int dhd0_cap_frm_cnt; /* 0xd04c */ + volatile unsigned int dhd0_vdp_frm_cnt; /* 0xd050 */ + volatile unsigned int dhd0_vsync_cap_vdp_cnt; /* 0xd054 */ + volatile unsigned int dhd0_intf_chksum_y; /* 0xd058 */ + volatile unsigned int dhd0_intf_chksum_u; /* 0xd05c */ + volatile unsigned int dhd0_intf_chksum_v; /* 0xd060 */ + volatile unsigned int dhd0_intf1_chksum_y; /* 0xd064 */ + volatile unsigned int dhd0_intf1_chksum_u; /* 0xd068 */ + volatile unsigned int dhd0_intf1_chksum_v; /* 0xd06c */ + volatile u_dhd0_intf_chksum_high1 dhd0_intf_chksum_high1; /* 0xd070 */ + volatile u_dhd0_intf_chksum_high2 dhd0_intf_chksum_high2; /* 0xd074 */ + volatile unsigned int reserved_119[3]; /* 3:0xd078~0xd080 */ + volatile unsigned int dhd0_afifo_pre_thd; /* 0xd084 */ + volatile u_dhd0_state dhd0_state; /* 0xd088 */ + volatile u_dhd0_uf_state dhd0_uf_state; /* 0xd08c */ + volatile u_vo_mux vo_mux; /* 0xd090 */ + volatile u_vo_mux_sync vo_mux_sync; /* 0xd094 */ + volatile u_vo_mux_data vo_mux_data; /* 0xd098 */ + volatile unsigned int reserved_120; /* 0xd09c */ + volatile u_dhd0_vsync_te_state dhd0_vsync_te_state; /* 0xd0a0 */ + volatile u_dhd0_vsync_te_state1 dhd0_vsync_te_state1; /* 0xd0a4 */ + volatile unsigned int reserved_121[6]; /* 6:0xd0a8~0xd0bc */ + volatile u_dhd0_ccdoimgmod dhd0_ccdoimgmod; /* 0xd0c0 */ + volatile u_dhd0_ccdoposmskh dhd0_ccdoposmskh; /* 0xd0c4 */ + volatile u_dhd0_ccdoposmskl dhd0_ccdoposmskl; /* 0xd0c8 */ + volatile unsigned int reserved_122; /* 0xd0cc */ + volatile u_dhd0_dacdet1 dhd0_dacdet1; /* 0xd0d0 */ + volatile u_dhd0_dacdet2 dhd0_dacdet2; /* 0xd0d4 */ + volatile unsigned int reserved_123[2]; /* 2:0xd0d8~0xd0dc */ + volatile u_dhd0_ccd_info1 dhd0_ccd_info1; /* 0xd0e0 */ + volatile u_dhd0_ccd_info2 dhd0_ccd_info2; /* 0xd0e4 */ + volatile u_dhd0_ccd_info3 dhd0_ccd_info3; /* 0xd0e8 */ + volatile unsigned int reserved_124[5]; /* 5:0xd0ec~0xd0fc */ + volatile u_intf_hdmi_ctrl intf_hdmi_ctrl; /* 0xd100 */ + volatile u_intf_hdmi_upd intf_hdmi_upd; /* 0xd104 */ + volatile u_intf_hdmi_sync_inv intf_hdmi_sync_inv; /* 0xd108 */ + volatile unsigned int reserved_125; /* 0xd10c */ + volatile unsigned int hdmi_intf_chksum_y; /* 0xd110 */ + volatile unsigned int hdmi_intf_chksum_u; /* 0xd114 */ + volatile unsigned int hdmi_intf_chksum_v; /* 0xd118 */ + volatile u_hdmi_intf_chksum_high hdmi_intf_chksum_high; /* 0xd11c */ + volatile unsigned int hdmi_intf1_chksum_y; /* 0xd120 */ + volatile unsigned int hdmi_intf1_chksum_u; /* 0xd124 */ + volatile unsigned int hdmi_intf1_chksum_v; /* 0xd128 */ + volatile u_hdmi_intf1_chksum_high hdmi_intf1_chksum_high; /* 0xd12c */ + volatile unsigned int reserved_126[8]; /* 8:0xd130~0xd14c */ + volatile u_hdmi_hfir_coef0 hdmi_hfir_coef0; /* 0xd150 */ + volatile u_hdmi_hfir_coef1 hdmi_hfir_coef1; /* 0xd154 */ + volatile u_hdmi_hfir_coef2 hdmi_hfir_coef2; /* 0xd158 */ + volatile u_hdmi_hfir_coef3 hdmi_hfir_coef3; /* 0xd15c */ + volatile u_hdmi_csc_idc hdmi_csc_idc; /* 0xd160 */ + volatile u_hdmi_csc_odc hdmi_csc_odc; /* 0xd164 */ + volatile u_hdmi_csc_iodc hdmi_csc_iodc; /* 0xd168 */ + volatile u_hdmi_csc_p0 hdmi_csc_p0; /* 0xd16c */ + volatile u_hdmi_csc_p1 hdmi_csc_p1; /* 0xd170 */ + volatile u_hdmi_csc_p2 hdmi_csc_p2; /* 0xd174 */ + volatile u_hdmi_csc_p3 hdmi_csc_p3; /* 0xd178 */ + volatile u_hdmi_csc_p4 hdmi_csc_p4; /* 0xd17c */ + volatile u_intf_mipi_ctrl intf_mipi_ctrl; /* 0xd180 */ + volatile u_intf_mipi_upd intf_mipi_upd; /* 0xd184 */ + volatile u_intf_mipi_sync_inv intf_mipi_sync_inv; /* 0xd188 */ + volatile unsigned int reserved_127; /* 0xd18c */ + volatile unsigned int mipi_intf_chksum_y; /* 0xd190 */ + volatile unsigned int mipi_intf_chksum_u; /* 0xd194 */ + volatile unsigned int mipi_intf_chksum_v; /* 0xd198 */ + volatile u_mipi_intf_chksum_high mipi_intf_chksum_high; /* 0xd19c */ + volatile unsigned int mipi_intf1_chksum_y; /* 0xd1a0 */ + volatile unsigned int mipi_intf1_chksum_u; /* 0xd1a4 */ + volatile unsigned int mipi_intf1_chksum_v; /* 0xd1a8 */ + volatile u_mipi_intf1_chksum_high mipi_intf1_chksum_high; /* 0xd1ac */ + volatile unsigned int reserved_128[8]; /* 8:0xd1b0~0xd1cc */ + volatile u_mipi_hfir_coef0 mipi_hfir_coef0; /* 0xd1d0 */ + volatile u_mipi_hfir_coef1 mipi_hfir_coef1; /* 0xd1d4 */ + volatile u_mipi_hfir_coef2 mipi_hfir_coef2; /* 0xd1d8 */ + volatile u_mipi_hfir_coef3 mipi_hfir_coef3; /* 0xd1dc */ + volatile unsigned int reserved_129[8]; /* 8:0xd1e0~0xd1fc */ + volatile u_intf_bt_ctrl intf_bt_ctrl; /* 0xd200 */ + volatile u_intf_bt_upd intf_bt_upd; /* 0xd204 */ + volatile u_intf_bt_sync_inv intf_bt_sync_inv; /* 0xd208 */ + volatile unsigned int reserved_130; /* 0xd20c */ + volatile u_bt_clip0_l bt_clip0_l; /* 0xd210 */ + volatile u_bt_clip0_h bt_clip0_h; /* 0xd214 */ + volatile unsigned int reserved_131[26]; /* 26:0xd218~0xd27c */ + volatile u_bt_dither_ctrl bt_dither_ctrl; /* 0xd280 */ + volatile u_bt_dither_sed_y0 bt_dither_sed_y0; /* 0xd284 */ + volatile u_bt_dither_sed_u0 bt_dither_sed_u0; /* 0xd288 */ + volatile u_bt_dither_sed_v0 bt_dither_sed_v0; /* 0xd28c */ + volatile u_bt_dither_sed_w0 bt_dither_sed_w0; /* 0xd290 */ + volatile u_bt_dither_sed_y1 bt_dither_sed_y1; /* 0xd294 */ + volatile u_bt_dither_sed_u1 bt_dither_sed_u1; /* 0xd298 */ + volatile u_bt_dither_sed_v1 bt_dither_sed_v1; /* 0xd29c */ + volatile u_bt_dither_sed_w1 bt_dither_sed_w1; /* 0xd2a0 */ + volatile u_bt_dither_sed_y2 bt_dither_sed_y2; /* 0xd2a4 */ + volatile u_bt_dither_sed_u2 bt_dither_sed_u2; /* 0xd2a8 */ + volatile u_bt_dither_sed_v2 bt_dither_sed_v2; /* 0xd2ac */ + volatile u_bt_dither_sed_w2 bt_dither_sed_w2; /* 0xd2b0 */ + volatile u_bt_dither_sed_y3 bt_dither_sed_y3; /* 0xd2b4 */ + volatile u_bt_dither_sed_u3 bt_dither_sed_u3; /* 0xd2b8 */ + volatile u_bt_dither_sed_v3 bt_dither_sed_v3; /* 0xd2bc */ + volatile u_bt_dither_sed_w3 bt_dither_sed_w3; /* 0xd2c0 */ + volatile u_bt_dither_thr bt_dither_thr; /* 0xd2c4 */ + volatile unsigned int reserved_132[10]; /* 10:0xd2c8~0xd2ec */ + volatile unsigned int bt_intf_chksum_y; /* 0xd2f0 */ + volatile unsigned int bt_intf_chksum_u; /* 0xd2f4 */ + volatile unsigned int bt_intf_chksum_v; /* 0xd2f8 */ + volatile unsigned int reserved_133; /* 0xd2fc */ + volatile u_intf_lcd_ctrl intf_lcd_ctrl; /* 0xd300 */ + volatile u_intf_lcd_upd intf_lcd_upd; /* 0xd304 */ + volatile u_intf_lcd_sync_inv intf_lcd_sync_inv; /* 0xd308 */ + volatile unsigned int reserved_134[29]; /* 29:0xd30c~0xd37c */ + volatile u_lcd_dither_ctrl lcd_dither_ctrl; /* 0xd380 */ + volatile u_lcd_dither_sed_y0 lcd_dither_sed_y0; /* 0xd384 */ + volatile u_lcd_dither_sed_u0 lcd_dither_sed_u0; /* 0xd388 */ + volatile u_lcd_dither_sed_v0 lcd_dither_sed_v0; /* 0xd38c */ + volatile u_lcd_dither_sed_w0 lcd_dither_sed_w0; /* 0xd390 */ + volatile u_lcd_dither_sed_y1 lcd_dither_sed_y1; /* 0xd394 */ + volatile u_lcd_dither_sed_u1 lcd_dither_sed_u1; /* 0xd398 */ + volatile u_lcd_dither_sed_v1 lcd_dither_sed_v1; /* 0xd39c */ + volatile u_lcd_dither_sed_w1 lcd_dither_sed_w1; /* 0xd3a0 */ + volatile u_lcd_dither_sed_y2 lcd_dither_sed_y2; /* 0xd3a4 */ + volatile u_lcd_dither_sed_u2 lcd_dither_sed_u2; /* 0xd3a8 */ + volatile u_lcd_dither_sed_v2 lcd_dither_sed_v2; /* 0xd3ac */ + volatile u_lcd_dither_sed_w2 lcd_dither_sed_w2; /* 0xd3b0 */ + volatile u_lcd_dither_sed_y3 lcd_dither_sed_y3; /* 0xd3b4 */ + volatile u_lcd_dither_sed_u3 lcd_dither_sed_u3; /* 0xd3b8 */ + volatile u_lcd_dither_sed_v3 lcd_dither_sed_v3; /* 0xd3bc */ + volatile u_lcd_dither_sed_w3 lcd_dither_sed_w3; /* 0xd3c0 */ + volatile u_lcd_dither_thr lcd_dither_thr; /* 0xd3c4 */ + volatile unsigned int reserved_135[10]; /* 10:0xd3c8~0xd3ec */ + volatile unsigned int lcd_intf_chksum_y; /* 0xd3f0 */ + volatile unsigned int lcd_intf_chksum_u; /* 0xd3f4 */ + volatile unsigned int lcd_intf_chksum_v; /* 0xd3f8 */ + volatile unsigned int reserved_136; /* 0xd3fc */ + volatile u_intf_hdmi1_ctrl intf_hdmi1_ctrl; /* 0xd400 */ + volatile u_intf_hdmi1_upd intf_hdmi1_upd; /* 0xd404 */ + volatile u_intf_hdmi1_sync_inv intf_hdmi1_sync_inv; /* 0xd408 */ + volatile unsigned int reserved_137; /* 0xd40c */ + volatile unsigned int hdmi1_intf_chksum_y; /* 0xd410 */ + volatile unsigned int hdmi1_intf_chksum_u; /* 0xd414 */ + volatile unsigned int hdmi1_intf_chksum_v; /* 0xd418 */ + volatile u_hdmi1_intf_chksum_high hdmi1_intf_chksum_high; /* 0xd41c */ + volatile unsigned int hdmi1_intf1_chksum_y; /* 0xd420 */ + volatile unsigned int hdmi1_intf1_chksum_u; /* 0xd424 */ + volatile unsigned int hdmi1_intf1_chksum_v; /* 0xd428 */ + volatile u_hdmi1_intf1_chksum_high hdmi1_intf1_chksum_high; /* 0xd42c */ + volatile unsigned int reserved_138[8]; /* 8:0xd430~0xd44c */ + volatile u_hdmi1_hfir_coef0 hdmi1_hfir_coef0; /* 0xd450 */ + volatile u_hdmi1_hfir_coef1 hdmi1_hfir_coef1; /* 0xd454 */ + volatile u_hdmi1_hfir_coef2 hdmi1_hfir_coef2; /* 0xd458 */ + volatile u_hdmi1_hfir_coef3 hdmi1_hfir_coef3; /* 0xd45c */ + volatile unsigned int reserved_139[40]; /* 40:0xd460~0xd4fc */ + volatile u_intf_vga_ctrl intf_vga_ctrl; /* 0xd500 */ + volatile u_intf_vga_upd intf_vga_upd; /* 0xd504 */ + volatile u_intf_vga_sync_inv intf_vga_sync_inv; /* 0xd508 */ + volatile unsigned int reserved_140[5]; /* 5:0xd50c~0xd51c */ + volatile u_vga_csc_idc vga_csc_idc; /* 0xd520 */ + volatile u_vga_csc_odc vga_csc_odc; /* 0xd524 */ + volatile u_vga_csc_iodc vga_csc_iodc; /* 0xd528 */ + volatile u_vga_csc_p0 vga_csc_p0; /* 0xd52c */ + volatile u_vga_csc_p1 vga_csc_p1; /* 0xd530 */ + volatile u_vga_csc_p2 vga_csc_p2; /* 0xd534 */ + volatile u_vga_csc_p3 vga_csc_p3; /* 0xd538 */ + volatile u_vga_csc_p4 vga_csc_p4; /* 0xd53c */ + volatile u_vga_hspcfg0 vga_hspcfg0; /* 0xd540 */ + volatile u_vga_hspcfg1 vga_hspcfg1; /* 0xd544 */ + volatile unsigned int reserved_141[3]; /* 3:0xd548~0xd550 */ + volatile u_vga_hspcfg5 vga_hspcfg5; /* 0xd554 */ + volatile u_vga_hspcfg6 vga_hspcfg6; /* 0xd558 */ + volatile u_vga_hspcfg7 vga_hspcfg7; /* 0xd55c */ + volatile u_vga_hspcfg8 vga_hspcfg8; /* 0xd560 */ + volatile unsigned int reserved_142[3]; /* 3:0xd564~0xd56c */ + volatile u_vga_hspcfg12 vga_hspcfg12; /* 0xd570 */ + volatile u_vga_hspcfg13 vga_hspcfg13; /* 0xd574 */ + volatile u_vga_hspcfg14 vga_hspcfg14; /* 0xd578 */ + volatile u_vga_hspcfg15 vga_hspcfg15; /* 0xd57c */ + volatile unsigned int reserved_143[28]; /* 28:0xd580~0xd5ec */ + volatile unsigned int vga_intf_chksum_y; /* 0xd5f0 */ + volatile unsigned int vga_intf_chksum_u; /* 0xd5f4 */ + volatile unsigned int vga_intf_chksum_v; /* 0xd5f8 */ + volatile unsigned int reserved_144; /* 0xd5fc */ + volatile u_intf_date_ctrl intf_date_ctrl; /* 0xd600 */ + volatile u_intf_date_upd intf_date_upd; /* 0xd604 */ + volatile u_intf_date_sync_inv intf_date_sync_inv; /* 0xd608 */ + volatile unsigned int reserved_145; /* 0xd60c */ + volatile u_date_clip0_l date_clip0_l; /* 0xd610 */ + volatile u_date_clip0_h date_clip0_h; /* 0xd614 */ + volatile unsigned int reserved_146[58]; /* 58:0xd618~0xd6fc */ + volatile u_intf0_dither_ctrl intf0_dither_ctrl; /* 0xd700 */ + volatile u_intf0_dither_sed_y0 intf0_dither_sed_y0; /* 0xd704 */ + volatile u_intf0_dither_sed_u0 intf0_dither_sed_u0; /* 0xd708 */ + volatile u_intf0_dither_sed_v0 intf0_dither_sed_v0; /* 0xd70c */ + volatile u_intf0_dither_sed_w0 intf0_dither_sed_w0; /* 0xd710 */ + volatile u_intf0_dither_sed_y1 intf0_dither_sed_y1; /* 0xd714 */ + volatile u_intf0_dither_sed_u1 intf0_dither_sed_u1; /* 0xd718 */ + volatile u_intf0_dither_sed_v1 intf0_dither_sed_v1; /* 0xd71c */ + volatile u_intf0_dither_sed_w1 intf0_dither_sed_w1; /* 0xd720 */ + volatile u_intf0_dither_sed_y2 intf0_dither_sed_y2; /* 0xd724 */ + volatile u_intf0_dither_sed_u2 intf0_dither_sed_u2; /* 0xd728 */ + volatile u_intf0_dither_sed_v2 intf0_dither_sed_v2; /* 0xd72c */ + volatile u_intf0_dither_sed_w2 intf0_dither_sed_w2; /* 0xd730 */ + volatile u_intf0_dither_sed_y3 intf0_dither_sed_y3; /* 0xd734 */ + volatile u_intf0_dither_sed_u3 intf0_dither_sed_u3; /* 0xd738 */ + volatile u_intf0_dither_sed_v3 intf0_dither_sed_v3; /* 0xd73c */ + volatile u_intf0_dither_sed_w3 intf0_dither_sed_w3; /* 0xd740 */ + volatile u_intf0_dither_thr intf0_dither_thr; /* 0xd744 */ + volatile unsigned int reserved_147[558]; /* 558:0xd748~0xdffc */ + volatile u_dhd1_ctrl dhd1_ctrl; /* 0xe000 */ + volatile u_dhd1_vsync1 dhd1_vsync1; /* 0xe004 */ + volatile u_dhd1_vsync2 dhd1_vsync2; /* 0xe008 */ + volatile u_dhd1_hsync1 dhd1_hsync1; /* 0xe00c */ + volatile u_dhd1_hsync2 dhd1_hsync2; /* 0xe010 */ + volatile u_dhd1_vplus1 dhd1_vplus1; /* 0xe014 */ + volatile u_dhd1_vplus2 dhd1_vplus2; /* 0xe018 */ + volatile u_dhd1_pwr dhd1_pwr; /* 0xe01c */ + volatile u_dhd1_vtthd3 dhd1_vtthd3; /* 0xe020 */ + volatile u_dhd1_vtthd dhd1_vtthd; /* 0xe024 */ + volatile u_dhd1_parathd dhd1_parathd; /* 0xe028 */ + volatile u_dhd1_precharge_thd dhd1_precharge_thd; /* 0xe02c */ + volatile u_dhd1_start_pos dhd1_start_pos; /* 0xe030 */ + volatile u_dhd1_start_pos1 dhd1_start_pos1; /* 0xe034 */ + volatile u_dhd1_paraup dhd1_paraup; /* 0xe038 */ + volatile u_dhd1_sync_inv dhd1_sync_inv; /* 0xe03c */ + volatile u_dhd1_clk_dv_ctrl dhd1_clk_dv_ctrl; /* 0xe040 */ + volatile u_dhd1_rgb_fix_ctrl dhd1_rgb_fix_ctrl; /* 0xe044 */ + volatile u_dhd1_lockcfg dhd1_lockcfg; /* 0xe048 */ + volatile unsigned int dhd1_cap_frm_cnt; /* 0xe04c */ + volatile unsigned int dhd1_vdp_frm_cnt; /* 0xe050 */ + volatile unsigned int dhd1_vsync_cap_vdp_cnt; /* 0xe054 */ + volatile unsigned int dhd1_intf_chksum_y; /* 0xe058 */ + volatile unsigned int dhd1_intf_chksum_u; /* 0xe05c */ + volatile unsigned int dhd1_intf_chksum_v; /* 0xe060 */ + volatile unsigned int dhd1_intf1_chksum_y; /* 0xe064 */ + volatile unsigned int dhd1_intf1_chksum_u; /* 0xe068 */ + volatile unsigned int dhd1_intf1_chksum_v; /* 0xe06c */ + volatile u_dhd1_intf_chksum_high1 dhd1_intf_chksum_high1; /* 0xe070 */ + volatile u_dhd1_intf_chksum_high2 dhd1_intf_chksum_high2; /* 0xe074 */ + volatile unsigned int reserved_148[3]; /* 3:0xe078~0xe080 */ + volatile unsigned int dhd1_afifo_pre_thd; /* 0xe084 */ + volatile u_dhd1_state dhd1_state; /* 0xe088 */ + volatile u_dhd1_uf_state dhd1_uf_state; /* 0xe08c */ + volatile unsigned int reserved_149[4]; /* 4:0xe090~0xe09c */ + volatile u_dhd1_vsync_te_state dhd1_vsync_te_state; /* 0xe0a0 */ + volatile u_dhd1_vsync_te_state1 dhd1_vsync_te_state1; /* 0xe0a4 */ + volatile unsigned int reserved_150[406]; /* 406:0xe0a8~0xe6fc */ + volatile u_intf1_dither_ctrl intf1_dither_ctrl; /* 0xe700 */ + volatile u_intf1_dither_sed_y0 intf1_dither_sed_y0; /* 0xe704 */ + volatile u_intf1_dither_sed_u0 intf1_dither_sed_u0; /* 0xe708 */ + volatile u_intf1_dither_sed_v0 intf1_dither_sed_v0; /* 0xe70c */ + volatile u_intf1_dither_sed_w0 intf1_dither_sed_w0; /* 0xe710 */ + volatile u_intf1_dither_sed_y1 intf1_dither_sed_y1; /* 0xe714 */ + volatile u_intf1_dither_sed_u1 intf1_dither_sed_u1; /* 0xe718 */ + volatile u_intf1_dither_sed_v1 intf1_dither_sed_v1; /* 0xe71c */ + volatile u_intf1_dither_sed_w1 intf1_dither_sed_w1; /* 0xe720 */ + volatile u_intf1_dither_sed_y2 intf1_dither_sed_y2; /* 0xe724 */ + volatile u_intf1_dither_sed_u2 intf1_dither_sed_u2; /* 0xe728 */ + volatile u_intf1_dither_sed_v2 intf1_dither_sed_v2; /* 0xe72c */ + volatile u_intf1_dither_sed_w2 intf1_dither_sed_w2; /* 0xe730 */ + volatile u_intf1_dither_sed_y3 intf1_dither_sed_y3; /* 0xe734 */ + volatile u_intf1_dither_sed_u3 intf1_dither_sed_u3; /* 0xe738 */ + volatile u_intf1_dither_sed_v3 intf1_dither_sed_v3; /* 0xe73c */ + volatile u_intf1_dither_sed_w3 intf1_dither_sed_w3; /* 0xe740 */ + volatile u_intf1_dither_thr intf1_dither_thr; /* 0xe744 */ + volatile unsigned int reserved_151[558]; /* 558:0xe748~0xeffc */ + volatile u_dhd2_ctrl dhd2_ctrl; /* 0xf000 */ + volatile u_dhd2_vsync1 dhd2_vsync1; /* 0xf004 */ + volatile u_dhd2_vsync2 dhd2_vsync2; /* 0xf008 */ + volatile u_dhd2_hsync1 dhd2_hsync1; /* 0xf00c */ + volatile u_dhd2_hsync2 dhd2_hsync2; /* 0xf010 */ + volatile u_dhd2_vplus1 dhd2_vplus1; /* 0xf014 */ + volatile u_dhd2_vplus2 dhd2_vplus2; /* 0xf018 */ + volatile u_dhd2_pwr dhd2_pwr; /* 0xf01c */ + volatile u_dhd2_vtthd3 dhd2_vtthd3; /* 0xf020 */ + volatile u_dhd2_vtthd dhd2_vtthd; /* 0xf024 */ + volatile u_dhd2_parathd dhd2_parathd; /* 0xf028 */ + volatile u_dhd2_precharge_thd dhd2_precharge_thd; /* 0xf02c */ + volatile u_dhd2_start_pos dhd2_start_pos; /* 0xf030 */ + volatile u_dhd2_start_pos1 dhd2_start_pos1; /* 0xf034 */ + volatile u_dhd2_paraup dhd2_paraup; /* 0xf038 */ + volatile u_dhd2_sync_inv dhd2_sync_inv; /* 0xf03c */ + volatile u_dhd2_clk_dv_ctrl dhd2_clk_dv_ctrl; /* 0xf040 */ + volatile u_dhd2_rgb_fix_ctrl dhd2_rgb_fix_ctrl; /* 0xf044 */ + volatile u_dhd2_lockcfg dhd2_lockcfg; /* 0xf048 */ + volatile unsigned int dhd2_cap_frm_cnt; /* 0xf04c */ + volatile unsigned int dhd2_vdp_frm_cnt; /* 0xf050 */ + volatile unsigned int dhd2_vsync_cap_vdp_cnt; /* 0xf054 */ + volatile unsigned int dhd2_intf_chksum_y; /* 0xf058 */ + volatile unsigned int dhd2_intf_chksum_u; /* 0xf05c */ + volatile unsigned int dhd2_intf_chksum_v; /* 0xf060 */ + volatile unsigned int dhd2_intf1_chksum_y; /* 0xf064 */ + volatile unsigned int dhd2_intf1_chksum_u; /* 0xf068 */ + volatile unsigned int dhd2_intf1_chksum_v; /* 0xf06c */ + volatile u_dhd2_intf_chksum_high1 dhd2_intf_chksum_high1; /* 0xf070 */ + volatile u_dhd2_intf_chksum_high2 dhd2_intf_chksum_high2; /* 0xf074 */ + volatile unsigned int reserved_152[3]; /* 3:0xf078~0xf080 */ + volatile unsigned int dhd2_afifo_pre_thd; /* 0xf084 */ + volatile u_dhd2_state dhd2_state; /* 0xf088 */ + volatile u_dhd2_uf_state dhd2_uf_state; /* 0xf08c */ + volatile unsigned int reserved_153[4]; /* 4:0xf090~0xf09c */ + volatile u_dhd2_vsync_te_state dhd2_vsync_te_state; /* 0xf0a0 */ + volatile u_dhd2_vsync_te_state1 dhd2_vsync_te_state1; /* 0xf0a4 */ + volatile unsigned int reserved_154[406]; /* 406:0xf0a8~0xf6fc */ + volatile u_intf2_dither_ctrl intf2_dither_ctrl; /* 0xf700 */ + volatile u_intf2_dither_sed_y0 intf2_dither_sed_y0; /* 0xf704 */ + volatile u_intf2_dither_sed_u0 intf2_dither_sed_u0; /* 0xf708 */ + volatile u_intf2_dither_sed_v0 intf2_dither_sed_v0; /* 0xf70c */ + volatile u_intf2_dither_sed_w0 intf2_dither_sed_w0; /* 0xf710 */ + volatile u_intf2_dither_sed_y1 intf2_dither_sed_y1; /* 0xf714 */ + volatile u_intf2_dither_sed_u1 intf2_dither_sed_u1; /* 0xf718 */ + volatile u_intf2_dither_sed_v1 intf2_dither_sed_v1; /* 0xf71c */ + volatile u_intf2_dither_sed_w1 intf2_dither_sed_w1; /* 0xf720 */ + volatile u_intf2_dither_sed_y2 intf2_dither_sed_y2; /* 0xf724 */ + volatile u_intf2_dither_sed_u2 intf2_dither_sed_u2; /* 0xf728 */ + volatile u_intf2_dither_sed_v2 intf2_dither_sed_v2; /* 0xf72c */ + volatile u_intf2_dither_sed_w2 intf2_dither_sed_w2; /* 0xf730 */ + volatile u_intf2_dither_sed_y3 intf2_dither_sed_y3; /* 0xf734 */ + volatile u_intf2_dither_sed_u3 intf2_dither_sed_u3; /* 0xf738 */ + volatile u_intf2_dither_sed_v3 intf2_dither_sed_v3; /* 0xf73c */ + volatile u_intf2_dither_sed_w3 intf2_dither_sed_w3; /* 0xf740 */ + volatile u_intf2_dither_thr intf2_dither_thr; /* 0xf744 */ + volatile unsigned int reserved_155[46]; /* 46:0xf748~0xf7fc */ + volatile u_date_coeff0 date_coeff0; /* 0xf800 */ + volatile u_date_coeff1 date_coeff1; /* 0xf804 */ + volatile unsigned int date_coeff2; /* 0xf808 */ + volatile u_date_coeff3 date_coeff3; /* 0xf80c */ + volatile u_date_coeff4 date_coeff4; /* 0xf810 */ + volatile u_date_coeff5 date_coeff5; /* 0xf814 */ + volatile u_date_coeff6 date_coeff6; /* 0xf818 */ + volatile u_date_coeff7 date_coeff7; /* 0xf81c */ + volatile unsigned int date_coeff8; /* 0xf820 */ + volatile unsigned int date_coeff9; /* 0xf824 */ + volatile u_date_coeff10 date_coeff10; /* 0xf828 */ + volatile u_date_coeff11 date_coeff11; /* 0xf82c */ + volatile u_date_coeff12 date_coeff12; /* 0xf830 */ + volatile u_date_coeff13 date_coeff13; /* 0xf834 */ + volatile u_date_coeff14 date_coeff14; /* 0xf838 */ + volatile u_date_coeff15 date_coeff15; /* 0xf83c */ + volatile u_date_coeff16 date_coeff16; /* 0xf840 */ + volatile unsigned int date_coeff17; /* 0xf844 */ + volatile unsigned int date_coeff18; /* 0xf848 */ + volatile u_date_coeff19 date_coeff19; /* 0xf84c */ + volatile u_date_coeff20 date_coeff20; /* 0xf850 */ + volatile u_date_coeff21 date_coeff21; /* 0xf854 */ + volatile u_date_coeff22 date_coeff22; /* 0xf858 */ + volatile u_date_coeff23 date_coeff23; /* 0xf85c */ + volatile unsigned int date_coeff24; /* 0xf860 */ + volatile u_date_coeff25 date_coeff25; /* 0xf864 */ + volatile u_date_coeff26 date_coeff26; /* 0xf868 */ + volatile u_date_coeff27 date_coeff27; /* 0xf86c */ + volatile u_date_coeff28 date_coeff28; /* 0xf870 */ + volatile u_date_coeff29 date_coeff29; /* 0xf874 */ + volatile u_date_coeff30 date_coeff30; /* 0xf878 */ + volatile unsigned int reserved_156; /* 0xf87c */ + volatile u_date_isrmask date_isrmask; /* 0xf880 */ + volatile u_date_isrstate date_isrstate; /* 0xf884 */ + volatile u_date_isr date_isr; /* 0xf888 */ + volatile unsigned int reserved_157; /* 0xf88c */ + volatile unsigned int date_version; /* 0xf890 */ + volatile u_date_coeff37 date_coeff37; /* 0xf894 */ + volatile u_date_coeff38 date_coeff38; /* 0xf898 */ + volatile u_date_coeff39 date_coeff39; /* 0xf89c */ + volatile u_date_coeff40 date_coeff40; /* 0xf8a0 */ + volatile u_date_coeff41 date_coeff41; /* 0xf8a4 */ + volatile u_date_coeff42 date_coeff42; /* 0xf8a8 */ + volatile unsigned int reserved_158[5]; /* 5:0xf8ac~0xf8bc */ + volatile u_date_dacdet1 date_dacdet1; /* 0xf8c0 */ + volatile u_date_dacdet2 date_dacdet2; /* 0xf8c4 */ + volatile u_date_coeff50 date_coeff50; /* 0xf8c8 */ + volatile u_date_coeff51 date_coeff51; /* 0xf8cc */ + volatile u_date_coeff52 date_coeff52; /* 0xf8d0 */ + volatile u_date_coeff53 date_coeff53; /* 0xf8d4 */ + volatile u_date_coeff54 date_coeff54; /* 0xf8d8 */ + volatile u_date_coeff55 date_coeff55; /* 0xf8dc */ + volatile unsigned int reserved_159[456]; /* 456:0xf8e0~0xfffc */ + volatile u_mac_outstanding mac_outstanding; /* 0x10000 */ + volatile u_mac_ctrl mac_ctrl; /* 0x10004 */ + volatile unsigned int reserved_160[2]; /* 2:0x10008~0x1000c */ + volatile u_mac_rchn_prio mac_rchn_prio; /* 0x10010 */ + volatile unsigned int reserved_161; /* 0x10014 */ + volatile u_mac_wchn_prio mac_wchn_prio; /* 0x10018 */ + volatile unsigned int reserved_162; /* 0x1001c */ + volatile u_mac_rchn_sel0 mac_rchn_sel0; /* 0x10020 */ + volatile unsigned int mac_rchn_sel1; /* 0x10024 */ + volatile unsigned int reserved_163[2]; /* 2:0x10028~0x1002c */ + volatile u_mac_wchn_sel0 mac_wchn_sel0; /* 0x10030 */ + volatile unsigned int reserved_164[3]; /* 3:0x10034~0x1003c */ + volatile u_mac_bus_err_clr mac_bus_err_clr; /* 0x10040 */ + volatile u_mac_bus_err mac_bus_err; /* 0x10044 */ + volatile unsigned int reserved_165[2]; /* 2:0x10048~0x1004c */ + volatile unsigned int mac_src0_status0; /* 0x10050 */ + volatile unsigned int mac_src0_status1; /* 0x10054 */ + volatile unsigned int mac_src1_status0; /* 0x10058 */ + volatile unsigned int mac_src1_status1; /* 0x1005c */ + volatile unsigned int mac_src2_status0; /* 0x10060 */ + volatile unsigned int mac_src2_status1; /* 0x10064 */ + volatile unsigned int reserved_166[2]; /* 2:0x10068~0x1006c */ + volatile u_mac_debug_ctrl mac_debug_ctrl; /* 0x10070 */ + volatile u_mac_debug_clr mac_debug_clr; /* 0x10074 */ + volatile unsigned int reserved_167[2]; /* 2:0x10078~0x1007c */ + volatile unsigned int mac0_debug_info; /* 0x10080 */ + volatile unsigned int reserved_168[3]; /* 3:0x10084~0x1008c */ + volatile unsigned int mac0_rd_info; /* 0x10090 */ + volatile unsigned int mac0_wr_info; /* 0x10094 */ + volatile unsigned int mac1_rd_info; /* 0x10098 */ + volatile unsigned int mac1_wr_info; /* 0x1009c */ + volatile unsigned int mac2_rd_info; /* 0x100a0 */ + volatile unsigned int mac2_wr_info; /* 0x100a4 */ + volatile unsigned int reserved_169[2]; /* 2:0x100a8~0x100ac */ + volatile unsigned int mac0_det_latency0; /* 0x100b0 */ + volatile unsigned int mac0_det_latency1; /* 0x100b4 */ + volatile unsigned int mac0_det_latency2; /* 0x100b8 */ + volatile unsigned int mac0_det_latency3; /* 0x100bc */ + volatile unsigned int mac0_det_latency4; /* 0x100c0 */ + volatile unsigned int mac0_det_latency5; /* 0x100c4 */ + volatile unsigned int mac1_det_latency0; /* 0x100c8 */ + volatile unsigned int mac1_det_latency1; /* 0x100cc */ + volatile unsigned int mac1_det_latency2; /* 0x100d0 */ + volatile unsigned int mac1_det_latency3; /* 0x100d4 */ + volatile unsigned int mac1_det_latency4; /* 0x100d8 */ + volatile unsigned int mac1_det_latency5; /* 0x100dc */ + volatile unsigned int reserved_170[72]; /* 72:0x100e0~0x101fc */ + volatile u_vid_read_ctrl vid_read_ctrl; /* 0x10200 */ + volatile u_vid_mac_ctrl vid_mac_ctrl; /* 0x10204 */ + volatile unsigned int reserved_171[2]; /* 2:0x10208~0x1020c */ + volatile u_vid_out_ctrl vid_out_ctrl; /* 0x10210 */ + volatile u_vid_mute_alpha vid_mute_alpha; /* 0x10214 */ + volatile unsigned int reserved_172; /* 0x10218 */ + volatile u_vid_mute_bk vid_mute_bk; /* 0x1021c */ + volatile unsigned int reserved_173[8]; /* 8:0x10220~0x1023c */ + volatile u_vid_src_info vid_src_info; /* 0x10240 */ + volatile u_vid_src_reso vid_src_reso; /* 0x10244 */ + volatile u_vid_src_crop vid_src_crop; /* 0x10248 */ + volatile u_vid_in_reso vid_in_reso; /* 0x1024c */ + volatile unsigned int vid_addr_h; /* 0x10250 */ + volatile unsigned int vid_addr_l; /* 0x10254 */ + volatile unsigned int vid_caddr_h; /* 0x10258 */ + volatile unsigned int vid_caddr_l; /* 0x1025c */ + volatile unsigned int vid_naddr_h; /* 0x10260 */ + volatile unsigned int vid_naddr_l; /* 0x10264 */ + volatile unsigned int vid_ncaddr_h; /* 0x10268 */ + volatile unsigned int vid_ncaddr_l; /* 0x1026c */ + volatile u_vid_stride vid_stride; /* 0x10270 */ + volatile u_vid_2bit_stride vid_2bit_stride; /* 0x10274 */ + volatile u_vid_head_stride vid_head_stride; /* 0x10278 */ + volatile unsigned int reserved_174; /* 0x1027c */ + volatile u_vid_smmu_bypass vid_smmu_bypass; /* 0x10280 */ + volatile unsigned int reserved_175[3]; /* 3:0x10284~0x1028c */ + volatile unsigned int vid_head_addr_h; /* 0x10290 */ + volatile unsigned int vid_head_addr_l; /* 0x10294 */ + volatile unsigned int vid_head_caddr_h; /* 0x10298 */ + volatile unsigned int vid_head_caddr_l; /* 0x1029c */ + volatile u_vid_testpat_cfg vid_testpat_cfg; /* 0x102a0 */ + volatile u_vid_testpat_seed vid_testpat_seed; /* 0x102a4 */ + volatile unsigned int vid_testpat_chksum_y; /* 0x102a8 */ + volatile unsigned int vid_testpat_chksum_c; /* 0x102ac */ + volatile unsigned int reserved_176[20]; /* 20:0x102b0~0x102fc */ + volatile unsigned int vid_l_cur_flow; /* 0x10300 */ + volatile unsigned int vid_l_cur_sreq_time; /* 0x10304 */ + volatile unsigned int vid_c_cur_flow; /* 0x10308 */ + volatile unsigned int vid_c_cur_sreq_time; /* 0x1030c */ + volatile unsigned int vid_l_last_flow; /* 0x10310 */ + volatile unsigned int vid_l_last_sreq_time; /* 0x10314 */ + volatile unsigned int vid_c_last_flow; /* 0x10318 */ + volatile unsigned int vid_c_last_sreq_time; /* 0x1031c */ + volatile unsigned int vid_l_busy_time; /* 0x10320 */ + volatile unsigned int vid_l_neednordy_time; /* 0x10324 */ + volatile unsigned int vid_l2_neednordy_time; /* 0x10328 */ + volatile unsigned int vid_c_busy_time; /* 0x1032c */ + volatile unsigned int vid_c_neednordy_time; /* 0x10330 */ + volatile unsigned int vid_c2_neednordy_time; /* 0x10334 */ + volatile unsigned int reserved_177[2]; /* 2:0x10338~0x1033c */ + volatile u_vid_dcmp_ctrl vid_dcmp_ctrl; /* 0x10340 */ + volatile unsigned int vid_dcmp_l_fsize; /* 0x10344 */ + volatile unsigned int reserved_178[14]; /* 14:0x10348~0x1037c */ + volatile u_vdp_v3r2_lineseg_dcmp_glb_info vdp_v3r2_lineseg_dcmp_glb_info; /* 0x10380 */ + volatile u_vdp_v3r2_lineseg_dcmp_frame_size vdp_v3r2_lineseg_dcmp_frame_size; /* 0x10384 */ + volatile unsigned int vdp_v3r2_lineseg_dcmp_adpqp_thr0; /* 0x10388 */ + volatile unsigned int vdp_v3r2_lineseg_dcmp_adpqp_thr1; /* 0x1038c */ + volatile u_vdp_v3r2_lineseg_dcmp_smth_deltabits_thr vdp_v3r2_lineseg_dcmp_smth_deltabits_thr; /* 0x10390 */ + volatile u_vdp_v3r2_lineseg_dcmp_error_sta vdp_v3r2_lineseg_dcmp_error_sta; /* 0x10394 */ + volatile unsigned int vdp_v3r2_lineseg_dcmp_extra; /* 0x10398 */ + volatile unsigned int vdp_v3r2_lineseg_dcmp_dbg_reg; /* 0x1039c */ + volatile unsigned int reserved_179[8]; /* 8:0x103a0~0x103bc */ + volatile u_vdp_v3r2_lineseg_dcmp_glb_info_c vdp_v3r2_lineseg_dcmp_glb_info_c; /* 0x103c0 */ + volatile u_vdp_v3r2_lineseg_dcmp_frame_size_c vdp_v3r2_lineseg_dcmp_frame_size_c; /* 0x103c4 */ + volatile unsigned int vdp_v3r2_lineseg_dcmp_adpqp_thr0_c; /* 0x103c8 */ + volatile unsigned int vdp_v3r2_lineseg_dcmp_adpqp_thr1_c; /* 0x103cc */ + volatile u_vdp_v3r2_lineseg_dcmp_smth_deltabits_thr_c vdp_v3r2_lineseg_dcmp_smth_deltabits_thr_c; /* 0x103d0 */ + volatile u_vdp_v3r2_lineseg_dcmp_error_sta_c vdp_v3r2_lineseg_dcmp_error_sta_c; /* 0x103d4 */ + volatile unsigned int vdp_v3r2_lineseg_dcmp_extra_c; /* 0x103d8 */ + volatile unsigned int vdp_v3r2_lineseg_dcmp_dbg_reg_c; /* 0x103dc */ + volatile unsigned int reserved_180[648]; /* 648:0x103e0~0x10dfc */ + volatile u_gfx_read_ctrl gfx_read_ctrl; /* 0x10e00 */ + volatile u_gfx_mac_ctrl gfx_mac_ctrl; /* 0x10e04 */ + volatile u_gfx_out_ctrl gfx_out_ctrl; /* 0x10e08 */ + volatile unsigned int reserved_181; /* 0x10e0c */ + volatile u_gfx_mute_alpha gfx_mute_alpha; /* 0x10e10 */ + volatile u_gfx_mute_bk gfx_mute_bk; /* 0x10e14 */ + volatile unsigned int reserved_182[2]; /* 2:0x10e18~0x10e1c */ + volatile u_gfx_smmu_bypass gfx_smmu_bypass; /* 0x10e20 */ + volatile unsigned int reserved_183; /* 0x10e24 */ + volatile u_gfx_1555_alpha gfx_1555_alpha; /* 0x10e28 */ + volatile unsigned int reserved_184[5]; /* 5:0x10e2c~0x10e3c */ + volatile u_gfx_src_info gfx_src_info; /* 0x10e40 */ + volatile u_gfx_src_reso gfx_src_reso; /* 0x10e44 */ + volatile u_gfx_src_crop gfx_src_crop; /* 0x10e48 */ + volatile u_gfx_ireso gfx_ireso; /* 0x10e4c */ + volatile unsigned int gfx_addr_h; /* 0x10e50 */ + volatile unsigned int gfx_addr_l; /* 0x10e54 */ + volatile unsigned int gfx_naddr_h; /* 0x10e58 */ + volatile unsigned int gfx_naddr_l; /* 0x10e5c */ + volatile u_gfx_stride gfx_stride; /* 0x10e60 */ + volatile unsigned int reserved_185[3]; /* 3:0x10e64~0x10e6c */ + volatile unsigned int gfx_dcmp_addr_h; /* 0x10e70 */ + volatile unsigned int gfx_dcmp_addr_l; /* 0x10e74 */ + volatile unsigned int gfx_dcmp_naddr_h; /* 0x10e78 */ + volatile unsigned int gfx_dcmp_naddr_l; /* 0x10e7c */ + volatile unsigned int reserved_186[32]; /* 32:0x10e80~0x10efc */ + volatile u_gfx_ckey_max gfx_ckey_max; /* 0x10f00 */ + volatile u_gfx_ckey_min gfx_ckey_min; /* 0x10f04 */ + volatile u_gfx_ckey_mask gfx_ckey_mask; /* 0x10f08 */ + volatile unsigned int reserved_187; /* 0x10f0c */ + volatile u_gfx_testpat_cfg gfx_testpat_cfg; /* 0x10f10 */ + volatile u_gfx_testpat_seed gfx_testpat_seed; /* 0x10f14 */ + volatile unsigned int reserved_188[2]; /* 2:0x10f18~0x10f1c */ + volatile unsigned int gfx_dcmp_framesize0; /* 0x10f20 */ + volatile unsigned int gfx_dcmp_framesize1; /* 0x10f24 */ + volatile unsigned int reserved_189[2]; /* 2:0x10f28~0x10f2c */ + volatile unsigned int gfx_cur_flow; /* 0x10f30 */ + volatile unsigned int gfx_cur_sreq_time; /* 0x10f34 */ + volatile unsigned int gfx_last_flow; /* 0x10f38 */ + volatile unsigned int gfx_last_sreq_time; /* 0x10f3c */ + volatile unsigned int gfx_busy_time; /* 0x10f40 */ + volatile unsigned int gfx_ar_neednordy_time; /* 0x10f44 */ + volatile unsigned int gfx_gb_neednordy_time; /* 0x10f48 */ + volatile unsigned int reserved_190_1[1]; /* 0x10f4c */ + volatile u_gfx_ld_ctrl gfx_ld_ctrl; /* 0x10f50 */ + volatile unsigned int gfx_tde_safe_dis; /* 0x10f54 */ + volatile u_gfx_ld_smute_ctrl gfx_ld_smute_ctrl; /* 0x10f58 */ + volatile u_gfx_ld_err_sta gfx_ld_err_sta; /* 0x10f5c */ + volatile unsigned int gfx_ld_debug0; /* 0x10f60 */ + volatile unsigned int gfx_ld_debug1; /* 0x10f64 */ + volatile unsigned int gfx_ld_debug2; /* 0x10f68 */ + volatile unsigned int gfx_ld_debug3; /* 0x10f6c */ + volatile unsigned int gfx_ld_debug4; /* 0x10f70 */ + volatile unsigned int gfx_ld_debug5; /* 0x10f74 */ + volatile unsigned int reserved_190_2[2]; /* 2:0x10f78~0x10f7c */ +#ifdef CONFIG_TDE_GFBG_COMPRESS_V2 + volatile u_vdp_v3r2_line_osd_dcmp_glb_info vdp_v3r2_line_osd_dcmp_glb_info; /* 0x10f80 */ + volatile u_vdp_v3r2_line_osd_dcmp_frame_size vdp_v3r2_line_osd_dcmp_frame_size; /* 0x10f84 */ + volatile u_vdp_v3r2_line_osd_dcmp_error_sta vdp_v3r2_line_osd_dcmp_error_sta; /* 0x10f88 */ + volatile unsigned int reserved_191[541]; /* 0x10f8c~0x117fc 541 regs */ +#endif +#ifdef CONFIG_TDE_GFBG_COMPRESS_V1 + volatile u_gfx_dcmp_ctrl gfx_dcmp_ctrl; /* 0x10f80 */ + volatile unsigned int reserved_191[3]; /* 3:0x10f84~0x10f8c */ + volatile u_gfx_dcmp_wrong_sta gfx_dcmp_wrong_sta; /* 0x10f90 */ + volatile unsigned int gfx_dcmp_debug_sta0; /* 0x10f94 */ + volatile unsigned int reserved_192[538]; /* 538:0x10f98~0x117fc */ +#endif + volatile u_wbc_ctrl wbc_ctrl; /* 0x11800 */ + volatile u_wbc_mac_ctrl wbc_mac_ctrl; /* 0x11804 */ + volatile unsigned int reserved_193[3]; /* 3:0x11808~0x11810 */ + volatile u_wbc_smmu_bypass wbc_smmu_bypass; /* 0x11814 */ + volatile unsigned int reserved_194[2]; /* 2:0x11818~0x1181c */ + volatile u_wbc_lowdlyctrl wbc_lowdlyctrl; /* 0x11820 */ + volatile unsigned int wbc_tunladdr_h; /* 0x11824 */ + volatile unsigned int wbc_tunladdr_l; /* 0x11828 */ + volatile u_wbc_lowdlysta wbc_lowdlysta; /* 0x1182c */ + volatile unsigned int reserved_195[8]; /* 8:0x11830~0x1184c */ + volatile unsigned int wbc_yaddr_h; /* 0x11850 */ + volatile unsigned int wbc_yaddr_l; /* 0x11854 */ + volatile unsigned int wbc_caddr_h; /* 0x11858 */ + volatile unsigned int wbc_caddr_l; /* 0x1185c */ + volatile u_wbc_ystride wbc_ystride; /* 0x11860 */ + volatile u_wbc_cstride wbc_cstride; /* 0x11864 */ + volatile unsigned int reserved_196[2]; /* 2:0x11868~0x1186c */ + volatile unsigned int wbc_ynaddr_h; /* 0x11870 */ + volatile unsigned int wbc_ynaddr_l; /* 0x11874 */ + volatile unsigned int wbc_cnaddr_h; /* 0x11878 */ + volatile unsigned int wbc_cnaddr_l; /* 0x1187c */ + volatile u_wbc_ynstride wbc_ynstride; /* 0x11880 */ + volatile u_wbc_cnstride wbc_cnstride; /* 0x11884 */ + volatile unsigned int reserved_197[10]; /* 10:0x11888~0x118ac */ + volatile u_wbc_sta wbc_sta; /* 0x118b0 */ + volatile u_wbc_line_num wbc_line_num; /* 0x118b4 */ + volatile u_wbc_cap_reso wbc_cap_reso; /* 0x118b8 */ + volatile unsigned int wbc_cap_info; /* 0x118bc */ + volatile unsigned int reserved_198[16]; /* 16:0x118c0~0x118fc */ + volatile u_vdp_v3r2_lineseg_cmp_glb_info vdp_v3r2_lineseg_cmp_glb_info; /* 0x11900 */ + volatile u_vdp_v3r2_lineseg_cmp_frame_size vdp_v3r2_lineseg_cmp_frame_size; /* 0x11904 */ + volatile u_vdp_v3r2_lineseg_cmp_rc_cfg0 vdp_v3r2_lineseg_cmp_rc_cfg0; /* 0x11908 */ + volatile u_vdp_v3r2_lineseg_cmp_rc_cfg1 vdp_v3r2_lineseg_cmp_rc_cfg1; /* 0x1190c */ + volatile unsigned int vdp_v3r2_lineseg_cmp_rc_cfg2; /* 0x11910 */ + volatile unsigned int vdp_v3r2_lineseg_cmp_rc_cfg3; /* 0x11914 */ + volatile unsigned int vdp_v3r2_lineseg_cmp_rc_cfg4; /* 0x11918 */ + volatile unsigned int vdp_v3r2_lineseg_cmp_rc_cfg5; /* 0x1191c */ + volatile unsigned int vdp_v3r2_lineseg_cmp_rc_cfg6; /* 0x11920 */ + volatile unsigned int vdp_v3r2_lineseg_cmp_rc_cfg7; /* 0x11924 */ + volatile unsigned int vdp_v3r2_lineseg_cmp_rc_cfg8; /* 0x11928 */ + volatile unsigned int vdp_v3r2_lineseg_cmp_rc_cfg9; /* 0x1192c */ + volatile unsigned int vdp_v3r2_lineseg_cmp_rc_cfg10; /* 0x11930 */ + volatile unsigned int vdp_v3r2_lineseg_cmp_rc_cfg11; /* 0x11934 */ + volatile u_vdp_v3r2_lineseg_cmp_rc_cfg12 vdp_v3r2_lineseg_cmp_rc_cfg12; /* 0x11938 */ + volatile u_vdp_v3r2_lineseg_cmp_rc_cfg13 vdp_v3r2_lineseg_cmp_rc_cfg13; /* 0x1193c */ + volatile unsigned int vdp_v3r2_lineseg_cmp_rc_cfg14; /* 0x11940 */ + volatile unsigned int vdp_v3r2_lineseg_cmp_rc_cfg15; /* 0x11944 */ + volatile unsigned int vdp_v3r2_lineseg_cmp_adpqp_thr0; /* 0x11948 */ + volatile unsigned int vdp_v3r2_lineseg_cmp_adpqp_thr1; /* 0x1194c */ + volatile u_vdp_v3r2_lineseg_cmp_rc_cfg16 vdp_v3r2_lineseg_cmp_rc_cfg16; /* 0x11950 */ + volatile unsigned int vdp_v3r2_lineseg_cmp_glb_cfg; /* 0x11954 */ + volatile u_vdp_v3r2_lineseg_cmp_glb_st vdp_v3r2_lineseg_cmp_glb_st; /* 0x11958 */ + volatile unsigned int vdp_v3r2_lineseg_cmp_dbg_reg; /* 0x1195c */ + volatile unsigned int reserved_199[8]; /* 8:0x11960~0x1197c */ + volatile u_vdp_v3r2_lineseg_cmp_glb_info_c vdp_v3r2_lineseg_cmp_glb_info_c; /* 0x11980 */ + volatile u_vdp_v3r2_lineseg_cmp_frame_size_c vdp_v3r2_lineseg_cmp_frame_size_c; /* 0x11984 */ + volatile u_vdp_v3r2_lineseg_cmp_rc_cfg0_c vdp_v3r2_lineseg_cmp_rc_cfg0_c; /* 0x11988 */ + volatile u_vdp_v3r2_lineseg_cmp_rc_cfg1_c vdp_v3r2_lineseg_cmp_rc_cfg1_c; /* 0x1198c */ + volatile unsigned int vdp_v3r2_lineseg_cmp_rc_cfg2_c; /* 0x11990 */ + volatile unsigned int vdp_v3r2_lineseg_cmp_rc_cfg3_c; /* 0x11994 */ + volatile unsigned int vdp_v3r2_lineseg_cmp_rc_cfg4_c; /* 0x11998 */ + volatile unsigned int vdp_v3r2_lineseg_cmp_rc_cfg5_c; /* 0x1199c */ + volatile unsigned int vdp_v3r2_lineseg_cmp_rc_cfg6_c; /* 0x119a0 */ + volatile unsigned int vdp_v3r2_lineseg_cmp_rc_cfg7_c; /* 0x119a4 */ + volatile unsigned int vdp_v3r2_lineseg_cmp_rc_cfg8_c; /* 0x119a8 */ + volatile unsigned int vdp_v3r2_lineseg_cmp_rc_cfg9_c; /* 0x119ac */ + volatile unsigned int vdp_v3r2_lineseg_cmp_rc_cfg10_c; /* 0x119b0 */ + volatile unsigned int vdp_v3r2_lineseg_cmp_rc_cfg11_c; /* 0x119b4 */ + volatile u_vdp_v3r2_lineseg_cmp_rc_cfg12_c vdp_v3r2_lineseg_cmp_rc_cfg12_c; /* 0x119b8 */ + volatile u_vdp_v3r2_lineseg_cmp_rc_cfg13_c vdp_v3r2_lineseg_cmp_rc_cfg13_c; /* 0x119bc */ + volatile unsigned int vdp_v3r2_lineseg_cmp_rc_cfg14_c; /* 0x119c0 */ + volatile unsigned int vdp_v3r2_lineseg_cmp_rc_cfg15_c; /* 0x119c4 */ + volatile unsigned int vdp_v3r2_lineseg_cmp_adpqp_thr0_c; /* 0x119c8 */ + volatile unsigned int vdp_v3r2_lineseg_cmp_adpqp_thr1_c; /* 0x119cc */ + volatile u_vdp_v3r2_lineseg_cmp_rc_cfg16_c vdp_v3r2_lineseg_cmp_rc_cfg16_c; /* 0x119d0 */ + volatile unsigned int vdp_v3r2_lineseg_cmp_glb_cfg_c; /* 0x119d4 */ + volatile u_vdp_v3r2_lineseg_cmp_glb_st_c vdp_v3r2_lineseg_cmp_glb_st_c; /* 0x119d8 */ + volatile unsigned int vdp_v3r2_lineseg_cmp_dbg_reg_c; /* 0x119dc */ + volatile unsigned int reserved_200[264]; /* 264:0x119e0~0x11dfc */ + volatile u_wbc_cmp_ctrl wbc_cmp_ctrl; /* 0x11e00 */ + volatile u_wbc_cmp_upd wbc_cmp_upd; /* 0x11e04 */ + volatile u_wbc_cmp_height wbc_cmp_height; /* 0x11e08 */ + volatile u_wbc_cmp_oreso wbc_cmp_oreso; /* 0x11e0c */ + volatile unsigned int wbc_cmp_yaddr; /* 0x11e10 */ + volatile unsigned int wbc_cmp_yaddr1; /* 0x11e14 */ + volatile unsigned int wbc_cmp_caddr; /* 0x11e18 */ + volatile unsigned int wbc_cmp_caddr1; /* 0x11e1c */ + volatile unsigned int wbc_cmp_addr0_t0; /* 0x11e20 */ + volatile unsigned int wbc_cmp_addr1_t0; /* 0x11e24 */ + volatile unsigned int wbc_cmp_addr0_t1; /* 0x11e28 */ + volatile unsigned int wbc_cmp_addr1_t1; /* 0x11e2c */ + volatile unsigned int wbc_cmp_l_fsize; /* 0x11e30 */ + volatile unsigned int wbc_cmp_c_fsize; /* 0x11e34 */ + volatile unsigned int wbc_cmp_t0_fsize; /* 0x11e38 */ + volatile unsigned int wbc_cmp_t1_fsize; /* 0x11e3c */ + volatile unsigned int wbc_sety_fsize; /* 0x11e40 */ + volatile unsigned int wbc_setc_fsize; /* 0x11e44 */ + volatile unsigned int wbc_sett0_fsize; /* 0x11e48 */ + volatile unsigned int wbc_sett1_fsize; /* 0x11e4c */ + volatile u_wbc_od_state wbc_od_state; /* 0x11e50 */ + volatile unsigned int reserved_201[43]; /* 43:0x11e54~0x11efc */ + volatile u_od_pic_osd_glb_info od_pic_osd_glb_info; /* 0x11f00 */ + volatile u_od_pic_osd_frame_size od_pic_osd_frame_size; /* 0x11f04 */ + volatile u_od_pic_osd_rc_cfg0 od_pic_osd_rc_cfg0; /* 0x11f08 */ + volatile u_od_pic_osd_rc_cfg1 od_pic_osd_rc_cfg1; /* 0x11f0c */ + volatile u_od_pic_osd_rc_cfg2 od_pic_osd_rc_cfg2; /* 0x11f10 */ + volatile u_od_pic_osd_rc_cfg3 od_pic_osd_rc_cfg3; /* 0x11f14 */ + volatile u_od_pic_osd_rc_cfg4 od_pic_osd_rc_cfg4; /* 0x11f18 */ + volatile u_od_pic_osd_rc_cfg5 od_pic_osd_rc_cfg5; /* 0x11f1c */ + volatile u_od_pic_osd_rc_cfg6 od_pic_osd_rc_cfg6; /* 0x11f20 */ + volatile u_od_pic_osd_rc_cfg7 od_pic_osd_rc_cfg7; /* 0x11f24 */ + volatile u_od_pic_osd_rc_cfg8 od_pic_osd_rc_cfg8; /* 0x11f28 */ + volatile u_od_pic_osd_rc_cfg9 od_pic_osd_rc_cfg9; /* 0x11f2c */ + volatile u_od_pic_osd_rc_cfg10 od_pic_osd_rc_cfg10; /* 0x11f30 */ + volatile u_od_pic_osd_rc_cfg11 od_pic_osd_rc_cfg11; /* 0x11f34 */ + volatile u_od_pic_osd_rc_cfg12 od_pic_osd_rc_cfg12; /* 0x11f38 */ + volatile u_od_pic_osd_rc_cfg13 od_pic_osd_rc_cfg13; /* 0x11f3c */ + volatile u_od_pic_osd_rc_cfg14 od_pic_osd_rc_cfg14; /* 0x11f40 */ + volatile u_od_pic_osd_rc_cfg15 od_pic_osd_rc_cfg15; /* 0x11f44 */ + volatile u_od_pic_osd_rc_cfg16 od_pic_osd_rc_cfg16; /* 0x11f48 */ + volatile u_od_pic_osd_rc_cfg17 od_pic_osd_rc_cfg17; /* 0x11f4c */ + volatile u_od_pic_osd_rc_cfg18 od_pic_osd_rc_cfg18; /* 0x11f50 */ + volatile u_od_pic_osd_rc_cfg19 od_pic_osd_rc_cfg19; /* 0x11f54 */ + volatile unsigned int reserved_202[2]; /* 2:0x11f58~0x11f5c */ + volatile u_od_pic_osd_stat_thr od_pic_osd_stat_thr; /* 0x11f60 */ + volatile u_od_pic_osd_pcmp od_pic_osd_pcmp; /* 0x11f64 */ + volatile unsigned int reserved_203[6]; /* 6:0x11f68~0x11f7c */ + volatile u_od_pic_osd_bs_size od_pic_osd_bs_size; /* 0x11f80 */ + volatile u_od_pic_osd_worst_row od_pic_osd_worst_row; /* 0x11f84 */ + volatile u_od_pic_osd_best_row od_pic_osd_best_row; /* 0x11f88 */ + volatile u_od_pic_osd_stat_info od_pic_osd_stat_info; /* 0x11f8c */ + volatile unsigned int od_pic_osd_debug0; /* 0x11f90 */ + volatile unsigned int od_pic_osd_debug1; /* 0x11f94 */ + volatile unsigned int reserved_204[26]; /* 26:0x11f98~0x11ffc */ + volatile u_v0_mrg_ctrl v0_mrg_ctrl; /* 0x12000 */ + volatile u_v0_mrg_disp_pos v0_mrg_disp_pos; /* 0x12004 */ + volatile u_v0_mrg_disp_reso v0_mrg_disp_reso; /* 0x12008 */ + volatile u_v0_mrg_src_reso v0_mrg_src_reso; /* 0x1200c */ + volatile u_v0_mrg_src_offset v0_mrg_src_offset; /* 0x12010 */ + volatile unsigned int v0_mrg_y_addr; /* 0x12014 */ + volatile unsigned int v0_mrg_c_addr; /* 0x12018 */ + volatile u_v0_mrg_stride v0_mrg_stride; /* 0x1201c */ + volatile unsigned int v0_mrg_yh_addr; /* 0x12020 */ + volatile unsigned int v0_mrg_ch_addr; /* 0x12024 */ + volatile u_v0_mrg_hstride v0_mrg_hstride; /* 0x12028 */ + volatile unsigned int reserved_205[5]; /* 5:0x1202c~0x1203c */ + volatile u_v0_mrg_read_ctrl v0_mrg_read_ctrl; /* 0x12040 */ + volatile u_v0_mrg_read_en v0_mrg_read_en; /* 0x12044 */ + volatile unsigned int reserved_206[750]; /* 750:0x12048~0x12bfc */ + volatile u_v1_mrg_ctrl v1_mrg_ctrl; /* 0x12c00 */ + volatile u_v1_mrg_disp_pos v1_mrg_disp_pos; /* 0x12c04 */ + volatile u_v1_mrg_disp_reso v1_mrg_disp_reso; /* 0x12c08 */ + volatile u_v1_mrg_src_reso v1_mrg_src_reso; /* 0x12c0c */ + volatile u_v1_mrg_src_offset v1_mrg_src_offset; /* 0x12c10 */ + volatile unsigned int v1_mrg_y_addr; /* 0x12c14 */ + volatile unsigned int v1_mrg_c_addr; /* 0x12c18 */ + volatile u_v1_mrg_stride v1_mrg_stride; /* 0x12c1c */ + volatile unsigned int v1_mrg_yh_addr; /* 0x12c20 */ + volatile unsigned int v1_mrg_ch_addr; /* 0x12c24 */ + volatile u_v1_mrg_hstride v1_mrg_hstride; /* 0x12c28 */ + volatile unsigned int reserved_207[5]; /* 5:0x12c2c~0x12c3c */ + volatile u_v1_mrg_read_ctrl v1_mrg_read_ctrl; /* 0x12c40 */ + volatile u_v1_mrg_read_en v1_mrg_read_en; /* 0x12c44 */ + volatile unsigned int reserved_208_1[1262]; /* 1262:0x12c48~0x14ffc */ + volatile u_osb_ctrl1_box_0 osb_ctrl1_box_0; /* 0x14000 */ + volatile u_osb_ctrl2_box_0 osb_ctrl2_box_0; /* 0x14004 */ + volatile u_osb_ctrl3_box_0 osb_ctrl3_box_0; /* 0x14008 */ + volatile unsigned int reserved_208_2[1021]; /* 1021:0x1400c~0x14ffc 1021 regs */ + volatile u_v1_csc_idc v1_csc_idc; /* 0x15000 */ + volatile u_v1_csc_odc v1_csc_odc; /* 0x15004 */ + volatile u_v1_csc_iodc v1_csc_iodc; /* 0x15008 */ + volatile u_v1_csc_p0 v1_csc_p0; /* 0x1500c */ + volatile u_v1_csc_p1 v1_csc_p1; /* 0x15010 */ + volatile u_v1_csc_p2 v1_csc_p2; /* 0x15014 */ + volatile u_v1_csc_p3 v1_csc_p3; /* 0x15018 */ + volatile u_v1_csc_p4 v1_csc_p4; /* 0x1501c */ + volatile u_v1_csc1_idc v1_csc1_idc; /* 0x15020 */ + volatile u_v1_csc1_odc v1_csc1_odc; /* 0x15024 */ + volatile u_v1_csc1_iodc v1_csc1_iodc; /* 0x15028 */ + volatile u_v1_csc1_p0 v1_csc1_p0; /* 0x1502c */ + volatile u_v1_csc1_p1 v1_csc1_p1; /* 0x15030 */ + volatile u_v1_csc1_p2 v1_csc1_p2; /* 0x15034 */ + volatile u_v1_csc1_p3 v1_csc1_p3; /* 0x15038 */ + volatile u_v1_csc1_p4 v1_csc1_p4; /* 0x1503c */ + volatile unsigned int reserved_209[48]; /* 48:0x15040~0x150fc */ + volatile u_v2_csc_idc v2_csc_idc; /* 0x15100 */ + volatile u_v2_csc_odc v2_csc_odc; /* 0x15104 */ + volatile u_v2_csc_iodc v2_csc_iodc; /* 0x15108 */ + volatile u_v2_csc_p0 v2_csc_p0; /* 0x1510c */ + volatile u_v2_csc_p1 v2_csc_p1; /* 0x15110 */ + volatile u_v2_csc_p2 v2_csc_p2; /* 0x15114 */ + volatile u_v2_csc_p3 v2_csc_p3; /* 0x15118 */ + volatile u_v2_csc_p4 v2_csc_p4; /* 0x1511c */ + volatile u_v2_csc1_idc v2_csc1_idc; /* 0x15120 */ + volatile u_v2_csc1_odc v2_csc1_odc; /* 0x15124 */ + volatile u_v2_csc1_iodc v2_csc1_iodc; /* 0x15128 */ + volatile u_v2_csc1_p0 v2_csc1_p0; /* 0x1512c */ + volatile u_v2_csc1_p1 v2_csc1_p1; /* 0x15130 */ + volatile u_v2_csc1_p2 v2_csc1_p2; /* 0x15134 */ + volatile u_v2_csc1_p3 v2_csc1_p3; /* 0x15138 */ + volatile u_v2_csc1_p4 v2_csc1_p4; /* 0x1513c */ + volatile unsigned int reserved_210[48]; /* 48:0x15140~0x151fc */ + volatile u_g1_csc_idc g1_csc_idc; /* 0x15200 */ + volatile u_g1_csc_odc g1_csc_odc; /* 0x15204 */ + volatile u_g1_csc_iodc g1_csc_iodc; /* 0x15208 */ + volatile u_g1_csc_p0 g1_csc_p0; /* 0x1520c */ + volatile u_g1_csc_p1 g1_csc_p1; /* 0x15210 */ + volatile u_g1_csc_p2 g1_csc_p2; /* 0x15214 */ + volatile u_g1_csc_p3 g1_csc_p3; /* 0x15218 */ + volatile u_g1_csc_p4 g1_csc_p4; /* 0x1521c */ + volatile u_g1_csc1_idc g1_csc1_idc; /* 0x15220 */ + volatile u_g1_csc1_odc g1_csc1_odc; /* 0x15224 */ + volatile u_g1_csc1_iodc g1_csc1_iodc; /* 0x15228 */ + volatile u_g1_csc1_p0 g1_csc1_p0; /* 0x1522c */ + volatile u_g1_csc1_p1 g1_csc1_p1; /* 0x15230 */ + volatile u_g1_csc1_p2 g1_csc1_p2; /* 0x15234 */ + volatile u_g1_csc1_p3 g1_csc1_p3; /* 0x15238 */ + volatile u_g1_csc1_p4 g1_csc1_p4; /* 0x1523c */ + volatile unsigned int reserved_211[48]; /* 48:0x15240~0x152fc */ + volatile u_g3_csc_idc g3_csc_idc; /* 0x15300 */ + volatile u_g3_csc_odc g3_csc_odc; /* 0x15304 */ + volatile u_g3_csc_iodc g3_csc_iodc; /* 0x15308 */ + volatile u_g3_csc_p0 g3_csc_p0; /* 0x1530c */ + volatile u_g3_csc_p1 g3_csc_p1; /* 0x15310 */ + volatile u_g3_csc_p2 g3_csc_p2; /* 0x15314 */ + volatile u_g3_csc_p3 g3_csc_p3; /* 0x15318 */ + volatile u_g3_csc_p4 g3_csc_p4; /* 0x1531c */ + volatile u_g3_csc1_idc g3_csc1_idc; /* 0x15320 */ + volatile u_g3_csc1_odc g3_csc1_odc; /* 0x15324 */ + volatile u_g3_csc1_iodc g3_csc1_iodc; /* 0x15328 */ + volatile u_g3_csc1_p0 g3_csc1_p0; /* 0x1532c */ + volatile u_g3_csc1_p1 g3_csc1_p1; /* 0x15330 */ + volatile u_g3_csc1_p2 g3_csc1_p2; /* 0x15334 */ + volatile u_g3_csc1_p3 g3_csc1_p3; /* 0x15338 */ + volatile u_g3_csc1_p4 g3_csc1_p4; /* 0x1533c */ + volatile unsigned int reserved_212[48]; /* 48:0x15340~0x153fc */ + volatile u_v0_cvfir_vinfo v0_cvfir_vinfo; /* 0x15400 */ + volatile u_v0_cvfir_vsp v0_cvfir_vsp; /* 0x15404 */ + volatile u_v0_cvfir_voffset v0_cvfir_voffset; /* 0x15408 */ + volatile u_v0_cvfir_vboffset v0_cvfir_vboffset; /* 0x1540c */ + volatile unsigned int reserved_213[8]; /* 8:0x15410~0x1542c */ + volatile u_v0_cvfir_vcoef0 v0_cvfir_vcoef0; /* 0x15430 */ + volatile u_v0_cvfir_vcoef1 v0_cvfir_vcoef1; /* 0x15434 */ + volatile u_v0_cvfir_vcoef2 v0_cvfir_vcoef2; /* 0x15438 */ + volatile unsigned int reserved_214[721]; /* 721:0x1543c~0x15f7c */ + volatile u_gfx_osd_glb_info gfx_osd_glb_info; /* 0x15f80 */ + volatile u_gfx_osd_frame_size gfx_osd_frame_size; /* 0x15f84 */ + volatile unsigned int reserved_215[2]; /* 2:0x15f88~0x15f8c */ + volatile u_gfx_osd_dbg_reg gfx_osd_dbg_reg; /* 0x15f90 */ + volatile u_gfx_osd_dbg_reg1 gfx_osd_dbg_reg1; /* 0x15f94 */ +} vdp_regs_type; + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* GFBG_REG_H */ diff --git a/kernel/gfbg/hi3519dv500/drv/adp/gfbg_rotate.c b/kernel/gfbg/hi3519dv500/drv/adp/gfbg_rotate.c new file mode 100755 index 00000000..a4662eaa --- /dev/null +++ b/kernel/gfbg/hi3519dv500/drv/adp/gfbg_rotate.c @@ -0,0 +1,38 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "gfbg_rotate.h" + +static drv_tde_func_callback g_tde_rotate_call_back; + +gfbg_rotate_ops g_gfbg_rotate_ops = {0}; + +td_void gfbg_rotation_register(td_void) +{ + g_gfbg_rotate_ops.gfbg_drv_rotate = gfbg_drv_rotate_process; + g_gfbg_rotate_ops.is_support = TD_TRUE; + return; +} + +td_bool gfbg_get_rotation_support(td_void) +{ + return g_gfbg_rotate_ops.is_support; +} + +gfbg_rotate gfbg_get_rotation(td_void) +{ + return g_gfbg_rotate_ops.gfbg_drv_rotate; +} + +td_s32 gfbg_drv_set_tde_rotate_callback(drv_tde_func_callback tde_rot_callback) +{ + g_tde_rotate_call_back = tde_rot_callback; + return TD_SUCCESS; +} + +drv_tde_func_callback gfbg_drv_get_tde_rotate_callback(td_void) +{ + return g_tde_rotate_call_back; +} + diff --git a/kernel/gfbg/hi3519dv500/drv/adp/gfbg_rotate.h b/kernel/gfbg/hi3519dv500/drv/adp/gfbg_rotate.h new file mode 100755 index 00000000..04b33ca7 --- /dev/null +++ b/kernel/gfbg/hi3519dv500/drv/adp/gfbg_rotate.h @@ -0,0 +1,40 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef GFBG_ROTATE_H +#define GFBG_ROTATE_H + +#include "ot_type.h" +#include "ot_common.h" +#include "drv_tde.h" +#include "gfbg_main.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* End of #ifdef __cplusplus */ + +typedef td_s32 (*gfbg_rotate)(const ot_fb_buf *, const ot_fb_buf *, const gfbg_rotate_opt *, td_bool); + +typedef struct { + td_bool is_support; + gfbg_rotate gfbg_drv_rotate; +} gfbg_rotate_ops; + +td_void gfbg_rotation_register(td_void); +td_bool gfbg_get_rotation_support(td_void); +gfbg_rotate gfbg_get_rotation(td_void); +td_s32 gfbg_drv_rotate_process(const ot_fb_buf *src_img, const ot_fb_buf *dst_img, const gfbg_rotate_opt *rotate_opt, + td_bool is_refresh_screen); +td_s32 gfbg_drv_set_tde_rotate_callback(drv_tde_func_callback tde_rot_callback); +drv_tde_func_callback gfbg_drv_get_tde_rotate_callback(td_void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* GFBG_ROTATE_H */ \ No newline at end of file diff --git a/kernel/gfbg/hi3519dv500/drv/adp/gfbg_rotate_tde.c b/kernel/gfbg/hi3519dv500/drv/adp/gfbg_rotate_tde.c new file mode 100755 index 00000000..e2325137 --- /dev/null +++ b/kernel/gfbg/hi3519dv500/drv/adp/gfbg_rotate_tde.c @@ -0,0 +1,178 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "gfbg_rotate.h" +#include "mod_ext.h" +#include "drv_tde.h" +#include "gfbg_comm.h" +#include "gfbg_drv.h" +#include "gfbg_blit.h" + +static td_void drv_rotate_init_tde(drv_tde_surface *surface, drv_tde_rect *rect, const ot_fb_buf *src_img, + const ot_fb_buf *dst_img); +static td_void drv_get_rotate_mode(const gfbg_rotate_opt *rotate_opt, drv_tde_rotate_angle *tde_rotate_angle); +static td_s32 drv_rotate_start_tde(td_s32 *handle, drv_tde_single_src *single_src, + drv_tde_rotate_angle tde_rotate_angle, const gfbg_rotate_opt *rotate_opt, + const ot_tde_export_func *tde_export_func); + + +/* rotate with tde */ +td_s32 gfbg_drv_rotate_process(const ot_fb_buf *src_img, const ot_fb_buf *dst_img, const gfbg_rotate_opt *rotate_opt, + td_bool is_refresh_screen) +{ + td_s32 ret; + td_s32 handle = -1; + drv_tde_surface src_surface = {0}; + drv_tde_surface dst_surface = {0}; + drv_tde_rect src_rect = {0}; + drv_tde_rect dst_rect = {0}; + ot_tde_export_func *tde_export_func = TD_NULL; + drv_tde_rotate_angle tde_rotate_angle = DRV_TDE_ROTATE_MAX; + drv_tde_single_src single_src = {0}; + ot_unused(is_refresh_screen); + tde_export_func = func_entry(ot_tde_export_func, OT_ID_TDE); + if ((tde_export_func == TD_NULL) || (tde_export_func->drv_tde_module_begin_job == TD_NULL) || + (tde_export_func->drv_tde_module_rotate == TD_NULL) || + (tde_export_func->drv_tde_module_cancel_job == TD_NULL) || + (tde_export_func->drv_tde_module_end_job == TD_NULL)) { + gfbg_error("TDE tde_export_func is NULL!\n"); + return TD_FAILURE; + } + + /* src init */ + drv_rotate_init_tde(&src_surface, &src_rect, src_img, TD_NULL); + /* dst_init */ + drv_rotate_init_tde(&dst_surface, &dst_rect, src_img, dst_img); + + /* get rotate mode */ + drv_get_rotate_mode(rotate_opt, &tde_rotate_angle); + + /* rotate start */ + single_src.src_surface = &src_surface; + single_src.src_rect = &src_rect; + single_src.dst_surface = &dst_surface; + single_src.dst_rect = &dst_rect; + ret = drv_rotate_start_tde(&handle, &single_src, tde_rotate_angle, rotate_opt, tde_export_func); + if (ret != TD_SUCCESS) { + gfbg_error("drv_rotate_start_tde failed!\n"); + return ret; + } + + return handle; +} + +static td_void drv_rotate_init_tde(drv_tde_surface *surface, drv_tde_rect *rect, const ot_fb_buf *src_img, + const ot_fb_buf *dst_img) +{ + if (dst_img == TD_NULL) { + surface->phys_addr = src_img->canvas.phys_addr; + surface->width = src_img->canvas.width; + surface->height = src_img->canvas.height; + surface->stride = src_img->canvas.pitch; + surface->alpha_max_is_255 = TD_TRUE; + surface->is_ycbcr_clut = TD_FALSE; + surface->color_format = gfbg_drv_conv_fmt(src_img->canvas.format); + rect->pos_x = src_img->update_rect.x; + rect->pos_y = src_img->update_rect.y; + rect->width = src_img->update_rect.width; + rect->height = src_img->update_rect.height; + } else { + surface->phys_addr = dst_img->canvas.phys_addr; + surface->width = dst_img->canvas.width; + surface->height = dst_img->canvas.height; + surface->stride = dst_img->canvas.pitch; + surface->alpha_max_is_255 = TD_TRUE; + surface->is_ycbcr_clut = TD_FALSE; + surface->color_format = gfbg_drv_conv_fmt(dst_img->canvas.format); + rect->pos_x = dst_img->update_rect.x; + rect->pos_y = dst_img->update_rect.y; + rect->width = src_img->update_rect.height; + rect->height = src_img->update_rect.width; + } + + return; +} + +static td_void drv_get_rotate_mode(const gfbg_rotate_opt *rotate_opt, drv_tde_rotate_angle *tde_rotate_angle) +{ + switch (rotate_opt->rotate_mode) { + case OT_FB_ROTATE_90: + *tde_rotate_angle = DRV_TDE_ROTATE_CLOCKWISE_90; + break; + case OT_FB_ROTATE_180: + *tde_rotate_angle = DRV_TDE_ROTATE_CLOCKWISE_180; + break; + case OT_FB_ROTATE_270: + *tde_rotate_angle = DRV_TDE_ROTATE_CLOCKWISE_270; + break; + default: + break; + } + return; +} + +static td_s32 drv_rotate_start_tde(td_s32 *handle, drv_tde_single_src *single_src, + drv_tde_rotate_angle tde_rotate_angle, const gfbg_rotate_opt *rotate_opt, const ot_tde_export_func *tde_export_func) +{ + td_s32 ret; + gfbg_tde_callback_param *param = TD_NULL; + const td_u32 time_out = 100; + drv_tde_end_job_cmd end_job; + ret = tde_export_func->drv_tde_module_begin_job(handle); + if (ret != TD_SUCCESS) { + return ret; + } + + ret = tde_export_func->drv_tde_module_rotate(*handle, single_src, tde_rotate_angle); + if (ret != TD_SUCCESS) { + gfbg_error("tde rotate failed ret = 0x%x handle %d \n", ret, *handle); + tde_export_func->drv_tde_module_cancel_job(*handle); + return ret; + } + + if (rotate_opt->call_back) { + if (in_atomic()) { + param = osal_kmalloc(sizeof(gfbg_tde_callback_param), OSAL_GFP_ATOMIC); + } else { + param = osal_kmalloc(sizeof(gfbg_tde_callback_param), OSAL_GFP_KERNEL); + } + if (param == TD_NULL) { + tde_export_func->drv_tde_module_cancel_job(*handle); + return TD_FAILURE; + } + + param->layer_id = *(td_u32 *)rotate_opt->param; + fb_drv_tde_end_job_val(end_job, *handle, rotate_opt->block, time_out, TD_FALSE); + ret = tde_export_func->drv_tde_module_end_job(&end_job, gfbg_drv_get_tde_rotate_callback(), param); + } else { + fb_drv_tde_end_job_val(end_job, *handle, rotate_opt->block, time_out, TD_FALSE); + ret = tde_export_func->drv_tde_module_end_job(&end_job, TD_NULL, TD_NULL); + } + if (ret != TD_SUCCESS) { + ret = tde_export_func->drv_tde_module_cancel_job(*handle); + if (ret == TD_SUCCESS) { + /* + * job is not submitted to the logic for processing + * callback function is not invoked + * memory needs to be released here + */ + if (param != TD_NULL) { + osal_kfree(param); + param = TD_NULL; + } + } else { + /* + * job has been submitted to the logic for processing + * memory will be released in the callback function + */ + gfbg_error("cancel job failed!ret = %x\n", ret); + } + return TD_FAILURE; + } + /* + * memory has been released in the callback function + * or after cancel_job executed successfully + */ + return TD_SUCCESS; +} diff --git a/kernel/gfbg/hi3519dv500/drv/adp/mddrc_reg.h b/kernel/gfbg/hi3519dv500/drv/adp/mddrc_reg.h new file mode 100644 index 00000000..1082173c --- /dev/null +++ b/kernel/gfbg/hi3519dv500/drv/adp/mddrc_reg.h @@ -0,0 +1,65 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef MDDDRC_REG_H +#define MDDDRC_REG_H + +#include "ot_type.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +typedef union { + struct { + unsigned int mem_mode : 1; // [0] + unsigned int mem_comb : 2; // [2..1] + unsigned int reserved : 29; // [31..3] + } bits; + unsigned int u32; +} u_ddr_mode; + +typedef union { + struct { + unsigned int apg_gt_en : 1; // [0] + unsigned int muxcmd_gt_en : 1; // [1] + unsigned int detaddr_gt_en : 1; // [2] + unsigned int reserved : 29; // [31..3] + } bits; + unsigned int u32; +} u_clk_cfg; + +typedef union { + struct { + unsigned int awaddr_srvlnc_start : 32; // [31..0] + } bits; + unsigned int u32; +} u_awaddr_srvlnc_start; + +typedef union { + struct { + unsigned int awaddr_srvlnc_end : 32; // [31..0] + } bits; + unsigned int u32; +} u_awaddr_srvlnc_end; + +typedef struct { + u_ddr_mode ddr_mode; + u_clk_cfg clk_cfg; + unsigned int reserved_1[62]; /* 62 reserved length */ + u_awaddr_srvlnc_start awaddr_srvlnc_start; + u_awaddr_srvlnc_end awaddr_srvlnc_end; + unsigned int reserved_2[62]; /* 62 reserved length */ + unsigned int awaddr_srvlnc_status; +} mddrc_regs; + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* MDDDRC_REG_H */ \ No newline at end of file diff --git a/kernel/gfbg/hi3519dv500/drv/include/gfbg_drv.h b/kernel/gfbg/hi3519dv500/drv/include/gfbg_drv.h new file mode 100755 index 00000000..e8a00bcc --- /dev/null +++ b/kernel/gfbg/hi3519dv500/drv/include/gfbg_drv.h @@ -0,0 +1,338 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ +#ifndef GFBG_DRV_H +#define GFBG_DRV_H +#ifdef __LITEOS__ +#include +#endif +#include "gfbg.h" +#include "ot_debug.h" +#include "gfbg_graphics_drv.h" + + +#ifdef __cplusplus +#if __cplusplus +extern "C"{ +#endif +#endif /* End of #ifdef __cplusplus */ + +#ifdef __LITEOS__ +typedef struct { + struct gfbg_info *info; + td_ulong layer_size; + td_u32 curosr_buf_size; /* For soft cursor */ +} gfbg_layer; + +#else +typedef struct { + struct fb_info *info; + td_ulong layer_size; /* layer_size = fb.smem_len, For display buf, KB */ + td_u32 curosr_buf_size; /* For soft cursor */ +} gfbg_layer; +#endif + +td_s32 gfbg_vou_get_dev_id(td_u32 layer_id); + +typedef td_s32 (*int_callback)(const td_void *paraml, const td_void *paramr); +typedef td_s32 (*int_vo_callback)(const td_void *paraml, ot_vo_dev vo_dev, const td_void *paramr); + +#define gfbg_debug(fmt, ...) \ + OT_DEBUG_TRACE(OT_ID_FB, "[Func]:%s [Line]:%d [Info]:" fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__) \ + +#define gfbg_fatal(fmt, ...) \ + OT_EMERG_TRACE(OT_ID_FB, "[Func]:%s [Line]:%d [Info]:" fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__) \ + +#define gfbg_error(fmt, ...) \ + OT_ERR_TRACE(OT_ID_FB, "[Func]:%s [Line]:%d [Info]:" fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__) \ + +#define gfbg_warning(fmt, ...) \ + OT_WARN_TRACE(OT_ID_FB, "[Func]:%s [Line]:%d [Info]:" fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__) \ + +#define gfbg_info(fmt, ...) \ + OT_INFO_TRACE(OT_ID_FB, "[Func]:%s [Line]:%d [Info]:" fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__) \ + +typedef td_u32 gfbg_layer_id; /* start from 0 */ +hal_disp_layer gfbg_drv_gfbglayer_to_hwlayer(td_u32 layer_id); + +td_bool is_4k_layer(td_u32 layer_id); +td_bool is_hd_layer(td_u32 layer_id); +td_bool is_sd_layer(td_u32 layer_id); +td_bool is_ad_layer(td_u32 layer_id); +td_bool is_cursor_layer(td_u32 layer_id); +td_bool is_layer_support_low_delay(td_u32 layer_id); + +typedef struct { + td_bool key_enable; /* colorkey */ + td_bool mask_enable; /* key mask */ + td_u32 key; + td_u8 red_mask; /* red mask */ + td_u8 green_mask; /* green mask */ + td_u8 blue_mask; /* blue mask */ + td_u8 reserved; + td_u32 key_mode; /* 0:In region; 1:Out region */ + td_u8 red_max; /* colorkey red max */ + td_u8 green_max; /* colorkey green max */ + td_u8 blue_max; /* colorkey blue max */ + td_u8 reserved1; + td_u8 red_min; /* colorkey red min */ + td_u8 green_min; /* colorkey green min */ + td_u8 blue_min; /* colorkey blue min */ + td_u8 reserved2; +} gfbg_colorkeyex; + +typedef struct { + ot_fb_rect clip_rect; + td_bool in_region_clip; + td_bool clip; +} gfbg_clip; + +typedef struct { + ot_fb_alpha alpha; + gfbg_colorkeyex ckey; + gfbg_clip clip; + ot_fb_layer_antiflicker_level antiflicker_level; + td_bool scale; + td_bool block; + td_bool is_sync; + td_bool call_back; + td_void *param; + td_phys_addr_t cmap_addr; + td_bool soft_cursor_update; + ot_fb_mirror_mode mirror_mode; + td_bool compress; +}gfbg_blit_opt; + +/* for graphic rotation. */ +typedef struct { + td_bool block; + td_bool call_back; + td_void *param; + ot_fb_rotate_mode rotate_mode; +}gfbg_rotate_opt; + +typedef enum { + GFBG_SCANMODE_P, + GFBG_SCANMODE_I, + GFBG_SCANMODE_BUTT, +} gfbg_scan_mode; + +/* layer state */ +typedef enum { + GFBG_LAYER_STATE_ENABLE = 0x0, + + GFBG_LAYER_STATE_DISABLE, + + GFBG_LAYER_STATE_INVALID, + + GFBG_LAYER_STATE_BUTT +} gfbg_layer_state; + +typedef struct { + gfbg_scan_mode scan_mode; + td_u32 screen_width; + td_u32 screen_height; +} disp_info; + +typedef struct { + td_phys_addr_t buffer_phy_addr; + td_u32 stride; + td_bool feild_update; /* field update mode or not */ + gfbg_scan_mode scan_mode; + td_u32 screen_width; /* current sync width */ + td_u32 screen_height; /* current sync height */ +} gfbg_osd_data; + +/* mask bit */ +typedef enum { + GFBG_LAYER_PARAMODIFY_FMT = 0x1, /* color format */ + GFBG_LAYER_PARAMODIFY_STRIDE = 0x2, /* stride, line spacing */ + GFBG_LAYER_PARAMODIFY_ALPHA = 0x4, /* alpha */ + GFBG_LAYER_PARAMODIFY_COLORKEY = 0x8, /* colorkey */ + GFBG_LAYER_PARAMODIFY_INRECT = 0x10, /* input rect */ + GFBG_LAYER_PARAMODIFY_OUTRECT = 0x20, /* output rect */ + GFBG_LAYER_PARAMODIFY_DISPLAYADDR = 0x40, /* display addr */ + GFBG_LAYER_PARAMODIFY_SHOW = 0x80, /* show or hide */ + GFBG_LAYER_PARAMODIFY_BMUL = 0x100, /* be pre-multi data */ + GFBG_LAYER_PARAMODIFY_ANTIFLICKERLEVEL = 0x200, /* ANTIFLICKERLEVEL */ + GFBG_LAYER_PARAMODIFY_DYNAMICRANGE = 0x400, /* DYNAMICRANGE */ + GFBG_LAYER_PARAMODIEY_SMART_RECT = 0x800, /* SMART RECT */ + GFBG_LAYER_PARAMODIEY_CLUT_UP = 0x1000, /* CLUT UP */ + GFBG_LAYER_PARAMODIEY_COMPRESS = 0x2000, /* compress */ + GFBG_LAYER_PARAMODIFY_BUTT +} gfbg_layer_paramodify_maskbit; + +typedef struct { + td_u32 phy_addr; + ot_fb_color_format color_format; + ot_fb_size resolution; + td_u32 stride; +} gfbg_vcmp_inbufinfo; + +typedef struct { + td_u32 bank_width; + td_u32 stride; + td_u32 alpha_addr; + td_u32 red_addr; + td_u32 green_addr; + td_u32 blue_addr; +} gfbg_vcmp_outbufinfo; + +typedef enum { + GFBG_INPUTFMT_CLUT_2BPP = 0x10, + GFBG_INPUTFMT_CLUT_4BPP = 0x20, + GFBG_INPUTFMT_ARGB_4444 = 0x48, + GFBG_INPUTFMT_ARGB_1555 = 0x49, + GFBG_INPUTFMT_ARGB_8888 = 0x68, + + GFBG_DISP_PIXELFORMAT_BUTT +} gfbg_disp_pixel_format; + +typedef struct { + gfbg_disp_pixel_format pixel_fmt; + td_phys_addr_t ar_phy_addr; + td_phys_addr_t gb_phy_addr; + td_u32 frame_size0; + td_u32 frame_size1; + td_u32 width; + td_u32 height; + td_bool is_lossless_a; + td_bool is_lossless; + td_u32 offset; + td_u32 stride; +} gfbg_graphic_dcmp_info; + +typedef enum { + GFBG_INTTYPE_VO, /* Vertical timing interrupt */ + GFBG_INTTYPE_VO_DISP, /* Timing switch notification */ + GFBG_INTTYPE_WBC, /* Compression completion interrupt */ + GFBG_INTTYPE_BUTT, +} gfbg_int_type; + +typedef struct { + td_u32 safe_dist; + td_bool is_hw_mute_clr_en; + td_bool is_mute_en; + td_bool is_sync; +} gfbg_bind_tde_cfg; + +typedef struct { + td_bool is_sync; + td_u32 safe_dist; +} gfbg_sync_attr; + +typedef struct { + const char *chip_name; /* chip name */ + td_u32 layer_count; /* support how many layers */ + ot_fb_capability *capability; /* capability */ + + /* init DRV */ + td_s32 (*gfbg_drv_init)(td_void); + + /* De init DRV */ + td_s32 (*gfbg_drv_deinit)(td_void); + td_s32 (*gfbg_drv_layer_default_setting)(td_u32 layer_id); + + /* enable/disable layer */ + td_s32 (*gfbg_drv_set_layer_enable)(td_u32 layer_id, td_bool enable); + + /* enable/disable layer */ +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC + td_s32 (*gfbg_drv_get_layer_enable)(td_u32 layer_id, td_bool *enable); +#endif + + /* set layer address */ + td_s32 (*gfbg_drv_set_layer_addr)(td_u32 layer_id, td_phys_addr_t addr); + + /* get layer address */ + td_s32 (*gfbg_drv_get_layer_addr)(td_u32 layer_id, td_phys_addr_t *phys_addr); + + /* set layer stride */ + td_s32 (*gfbg_drv_set_layer_stride)(td_u32 layer_id, td_u32 stride); + + /* set layer pixel format */ + td_s32 (*gfbg_drv_set_layer_data_fmt)(td_u32 layer_id, ot_fb_color_format data_fmt); + + /* set color registers */ + td_s32 (*gfbg_drv_set_color_reg)(td_u32 layer_id, td_u32 offset, td_u32 color, td_s32 up_flag); + + /* set color registers up */ + td_void (*gfbg_drv_set_color_reg_up)(td_u32 layer_id); + + /* wait until vblank, it's a block interface */ + td_s32 (*gfbg_drv_wait_v_blank)(td_u32 layer_id); + + /* set layer alpha */ + td_s32 (*gfbg_drv_set_layer_alpha)(td_u32 layer_id, ot_fb_alpha alpha); + + /* set layer start position and size */ + td_s32 (*gfbg_drv_set_layer_rect)(td_u32 layer_id, const ot_fb_rect *input_rect, const ot_fb_rect *output_rect); + + /* set layer src image resolution */ + td_s32 (*gfbg_drv_set_layer_src_image_reso)(td_u32 layer_id, const ot_fb_rect *rect); + + /* other color format convert to RGB888 format */ +#ifdef __LITEOS__ + td_s32 (*gfbg_drv_color_convert)(const struct gfbg_info *info, gfbg_colorkeyex *ckey); +#else + td_s32 (*gfbg_drv_color_convert)(const struct fb_var_screeninfo *var, gfbg_colorkeyex *ckey); +#endif + /* set layer colorkey */ + td_s32 (*gfbg_drv_set_layer_key_mask)(td_u32 layer_id, const gfbg_colorkeyex *color_key); + + /* update layer register */ + td_s32 (*gfbg_drv_updata_layer_reg)(td_u32 layer_id); + + /* set premul data */ + td_s32 (*gfbg_drv_set_pre_mul)(td_u32 layer_id, td_bool is_premul); + + td_s32 (*gfbg_drv_set_clut_addr)(td_u32 layer_id, td_u32 phy_data); + /* get osd data */ + td_s32 (*gfbg_drv_get_osd_data)(td_u32 layer_id, gfbg_osd_data *layer_data); + /* register call back function */ + td_s32 (*gfbg_drv_set_int_callback)(gfbg_int_type eIntType, int_vo_callback call_back, td_u32 layer_id, + td_void *call_back_arg); + /* open */ + td_s32 (*gfbg_drv_open_display)(td_void); + + /* close */ + td_s32 (*gfbg_drv_close_display)(td_void); + + td_s32 (*gfbg_open_layer)(td_u32 layer_id); + td_s32 (*gfbg_close_layer)(td_u32 layer_id); + + /* for compression */ + td_s32 (*gfbg_drv_enable_dcmp)(td_u32 layer_id, td_bool enable); + td_s32 (*gfbg_drv_get_dcmp_enable_state)(td_u32 layer_id, td_bool *enable); + td_s32 (*gfbg_drv_set_dcmp_info)(td_u32 layer_id, gfbg_graphic_dcmp_info *dcmp_info); + + /* for ZME */ + td_s32 (*gfbg_drv_enable_zme)(td_u32 layer_id, const ot_fb_rect *in_rect, const ot_fb_rect *out_rect, + td_bool enable); + td_bool (*gfbg_drv_is_layer_support_zoom_out)(td_u32 layer_id); + /* for int */ + td_bool (*gfbg_drv_graphics_enable_int)(td_u32 layer_id, td_bool enable); + td_bool (*gfbg_drv_graphics_clear_int)(td_u32 int_clear, td_s32 irq); + td_s32 (*gfbg_drv_graphics_get_int)(td_u32 *int_status); + td_bool (*gfbg_drv_graphics_clear_int_status)(td_u32 int_status); + td_s32 (*gfbg_drv_graphics_get_int_dev)(td_u32 int_status, ot_vo_dev* dev); + /* for LOW DELAY */ + td_void (*gfbg_drv_set_tde_sync)(td_u32 layer_id, const gfbg_sync_attr *sync_info); + /* for smart rect */ + td_s32 (*gfbg_drv_set_smart_rect)(td_u32 layer_id, td_u32 max_width, td_u32 max_height, + const ot_fb_smart_rect_param *param, const gfbg_mmz_buffer *osb_chn); + td_void (*gfbg_drv_smart_rect_up_param)(td_u32 layer_id); + td_void (*gfbg_close_smart_rect)(td_u32 layer_id); +} gfbg_drv_ops; + +td_void gfbg_drv_get_ops(gfbg_drv_ops *ops); +gfbg_disp_pixel_format gfbg_drv_convert_pixel_format(ot_fb_color_format color_format); +td_phys_addr_t gfbg_drv_get_dcmp_offset_addr(td_phys_addr_t dcmp_addr); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* GFBG_DRV_H */ diff --git a/kernel/gfbg/hi3519dv500/ext_inc/gfbg_ext.h b/kernel/gfbg/hi3519dv500/ext_inc/gfbg_ext.h new file mode 100755 index 00000000..8cac7d68 --- /dev/null +++ b/kernel/gfbg/hi3519dv500/ext_inc/gfbg_ext.h @@ -0,0 +1,41 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef GFBG_EXT_H +#define GFBG_EXT_H + +#include "ot_type.h" +#include "ot_common.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C"{ +#endif +#endif /* __cplusplus */ + +typedef struct { + td_bool (*fb_get_fb_open_state)(td_void); + td_void (*fb_set_vdp_clk_state)(td_bool enable); +} ot_fb_export_func; + +#define ckfn_fb_get_fb_open_state() \ + (func_entry(ot_fb_export_func, OT_ID_FB) != NULL) && \ + (func_entry(ot_fb_export_func, OT_ID_FB)->fb_get_fb_open_state != NULL) +#define call_fb_get_fb_open_state() \ + func_entry(ot_fb_export_func, OT_ID_FB)->fb_get_fb_open_state() + +#define ckfn_fb_set_vdp_clk_state() \ + (func_entry(ot_fb_export_func, OT_ID_FB) != NULL) && \ + (func_entry(ot_fb_export_func, OT_ID_FB)->fb_set_vdp_clk_state != NULL) +#define call_fb_set_vdp_clk_state(enable) \ + func_entry(ot_fb_export_func, OT_ID_FB)->fb_set_vdp_clk_state(enable) + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + + +#endif /* GFBG_EXT_H */ \ No newline at end of file diff --git a/kernel/gfbg/hi3519dv500/include/gfbg.h b/kernel/gfbg/hi3519dv500/include/gfbg.h new file mode 100755 index 00000000..40456a78 --- /dev/null +++ b/kernel/gfbg/hi3519dv500/include/gfbg.h @@ -0,0 +1,349 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef GFBG_H +#define GFBG_H + +#include +#include "osal_ioctl.h" +#include "ot_type.h" +#include "ot_common.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C"{ +#endif +#endif /* __cplusplus */ + +#define IOC_TYPE_GFBG 'F' +/* To obtain the colorkey of an overlay layer */ +#define FBIOGET_COLORKEY_GFBG _IOR(IOC_TYPE_GFBG, 90, ot_fb_colorkey) +/* To set the colorkey of an overlay layer */ +#define FBIOPUT_COLORKEY_GFBG _IOW(IOC_TYPE_GFBG, 91, ot_fb_colorkey) +/* To get the alpha of an overlay layer */ +#define FBIOGET_ALPHA_GFBG _IOR(IOC_TYPE_GFBG, 92, ot_fb_alpha) +/* To set the alpha of an overlay layer */ +#define FBIOPUT_ALPHA_GFBG _IOW(IOC_TYPE_GFBG, 93, ot_fb_alpha) +/* To get the origin of an overlay layer on the screen */ +#define FBIOGET_SCREEN_ORIGIN_GFBG _IOR(IOC_TYPE_GFBG, 94, ot_fb_point) +/* To set the origin of an overlay layer on the screen */ +#define FBIOPUT_SCREEN_ORIGIN_GFBG _IOW(IOC_TYPE_GFBG, 95, ot_fb_point) +/* To wait for the vertical blanking region of an overlay layer */ +#define FBIOGET_VER_BLANK_GFBG _IO(IOC_TYPE_GFBG, 100) +/* To set the display state of an overlay layer */ +#define FBIOPUT_SHOW_GFBG _IOW(IOC_TYPE_GFBG, 101, td_bool) +/* To obtain the display state of an overlay layer */ +#define FBIOGET_SHOW_GFBG _IOR(IOC_TYPE_GFBG, 102, td_bool) +/* to obtain the capability of an overlay layer */ +#define FBIOGET_CAPABILITY_GFBG _IOR(IOC_TYPE_GFBG, 103, ot_fb_capability) +/* set the screen output size */ +#define FBIOPUT_SCREEN_SIZE _IOW(IOC_TYPE_GFBG, 130, ot_fb_size) +/* get the screen output size */ +#define FBIOGET_SCREEN_SIZE _IOR(IOC_TYPE_GFBG, 131, ot_fb_size) +/* To display multiple surfaces in turn and set the alpha and colorkey attributes */ +#define FBIOFLIP_SURFACE _IOW(IOC_TYPE_GFBG, 132, ot_fb_surfaceex) +/* To set the compression function status of an overlay layer */ +#define FBIOPUT_COMPRESSION_GFBG _IOW(IOC_TYPE_GFBG, 133, td_bool) +/* To obtain the compression function status of an overlay layer */ +#define FBIOGET_COMPRESSION_GFBG _IOR(IOC_TYPE_GFBG, 134, td_bool) +/* To create the layer */ +#define FBIO_CREATE_LAYER _IO(IOC_TYPE_GFBG, 149) +/* To destroy the layer */ +#define FBIO_DESTROY_LAYER _IO(IOC_TYPE_GFBG, 150) +/* To set the layer information */ +#define FBIOPUT_LAYER_INFO _IOW(IOC_TYPE_GFBG, 120, ot_fb_layer_info) +/* To get the layer information */ +#define FBIOGET_LAYER_INFO _IOR(IOC_TYPE_GFBG, 121, ot_fb_layer_info) +/* To get canvas buf */ +#define FBIOGET_CANVAS_BUF _IOR(IOC_TYPE_GFBG, 123, ot_fb_buf) +/* To refresh the displayed contents in extended mode */ +#define FBIO_REFRESH _IOW(IOC_TYPE_GFBG, 124, ot_fb_buf) +/* sync refresh */ +#define FBIO_WAITFOR_FREFRESH_DONE _IO(IOC_TYPE_GFBG, 125) +/* To set the mirror mode */ +#define FBIOPUT_MIRROR_MODE _IOW(IOC_TYPE_GFBG, 126, ot_fb_mirror_mode) +/* To get the mirror mode */ +#define FBIOGET_MIRROR_MODE _IOW(IOC_TYPE_GFBG, 127, ot_fb_mirror_mode) +/* To set the rotate mode */ +#define FBIOPUT_ROTATE_MODE _IOW(IOC_TYPE_GFBG, 128, ot_fb_rotate_mode) +/* To get the rotate mode */ +#define FBIOGET_ROTATE_MODE _IOW(IOC_TYPE_GFBG, 129, ot_fb_rotate_mode) +/* To draw smart rect */ +#define FBIO_DRAW_SMART_RECT _IOW(IOC_TYPE_GFBG, 151, ot_fb_smart_rect_param) +/* To set graphic layer csc */ +#define FBIOPUT_GRAPHIC_LAYER_CSC_GFBG _IOW(IOC_TYPE_GFBG, 152, ot_fb_layer_csc) +/* To get graphic layer csc */ +#define FBIOGET_GRAPHIC_LAYER_CSC_GFBG _IOW(IOC_TYPE_GFBG, 153, ot_fb_layer_csc) + + +typedef struct { + td_u32 width; + td_u32 height; +} ot_fb_size; + +typedef struct { + td_bool enable; /* colorkey enable flag */ + td_u32 value; /* colorkey value, maybe contains alpha */ +} ot_fb_colorkey; + +typedef struct { + td_s32 x; + td_s32 y; + td_s32 width; + td_s32 height; +} ot_fb_rect; + +typedef struct { + td_s32 x_pos; /* < horizontal position */ + td_s32 y_pos; /* < vertical position */ +} ot_fb_point; + +/* Alpha info */ +typedef struct { + td_bool pixel_alpha; /* pixel alpha enable flag */ + td_bool global_alpha_en; /* global alpha enable flag */ + td_u8 alpha0; /* alpha0 value, used in ARGB1555 */ + td_u8 alpha1; /* alpha1 value, used in ARGB1555 */ + td_u8 global_alpha; /* global alpha value */ +} ot_fb_alpha; + +typedef enum { + OT_FB_FORMAT_RGB565 = 0, + OT_FB_FORMAT_RGB888, /* RGB888 24bpp */ + + OT_FB_FORMAT_KRGB444, /* RGB444 16bpp */ + OT_FB_FORMAT_KRGB555, /* RGB555 16bpp */ + OT_FB_FORMAT_KRGB888, /* RGB888 32bpp */ + + OT_FB_FORMAT_ARGB4444, /* ARGB4444 */ + OT_FB_FORMAT_ARGB1555, /* ARGB1555 */ + OT_FB_FORMAT_ARGB8888, /* ARGB8888 */ + OT_FB_FORMAT_ARGB8565, /* ARGB8565 */ + + OT_FB_FORMAT_RGBA4444, /* ARGB4444 */ + OT_FB_FORMAT_RGBA5551, /* RGBA5551 */ + OT_FB_FORMAT_RGBA5658, /* RGBA5658 */ + OT_FB_FORMAT_RGBA8888, /* RGBA8888 */ + + OT_FB_FORMAT_BGR565, /* BGR565 */ + OT_FB_FORMAT_BGR888, /* BGR888 */ + OT_FB_FORMAT_ABGR4444, /* ABGR4444 */ + OT_FB_FORMAT_ABGR1555, /* ABGR1555 */ + OT_FB_FORMAT_ABGR8888, /* ABGR8888 */ + OT_FB_FORMAT_ABGR8565, /* ABGR8565 */ + OT_FB_FORMAT_KBGR444, /* BGR444 16bpp */ + OT_FB_FORMAT_KBGR555, /* BGR555 16bpp */ + OT_FB_FORMAT_KBGR888, /* BGR888 32bpp */ + + OT_FB_FORMAT_1BPP, /* clut1 */ + OT_FB_FORMAT_2BPP, /* clut2 */ + OT_FB_FORMAT_4BPP, /* clut4 */ + OT_FB_FORMAT_8BPP, /* clut8 */ + OT_FB_FORMAT_ACLUT44, /* AClUT44 */ + OT_FB_FORMAT_ACLUT88, /* ACLUT88 */ + OT_FB_FORMAT_PUYVY, /* UYVY */ + OT_FB_FORMAT_PYUYV, /* YUYV */ + OT_FB_FORMAT_PYVYU, /* YVYU */ + OT_FB_FORMAT_YUV888, /* YUV888 */ + OT_FB_FORMAT_AYUV8888, /* AYUV8888 */ + OT_FB_FORMAT_YUVA8888, /* YUVA8888 */ + OT_FB_FORMAT_BUTT +} ot_fb_color_format; + +typedef struct { + td_bool is_key_rgb; + td_bool is_key_alpha; /* whether support colorkey alpha */ + td_bool is_global_alpha; /* whether support global alpha */ + td_bool is_cmap; /* whether support color map */ + td_bool has_cmap_reg; /* whether has color map register */ + td_bool is_color_format[OT_FB_FORMAT_BUTT]; /* support which color format */ + td_bool is_vo_scale; /* support vo scale */ + /* whether support a certain layer */ + td_bool is_layer_support; + td_u32 max_width; /* the max pixels per line */ + td_u32 max_height; /* the max lines */ + td_u32 min_width; /* the min pixels per line */ + td_u32 min_height; /* the min lines */ + td_u32 ver_deflicker_level; /* vertical deflicker level, 0 means vertical deflicker is unsupporteded. */ + td_u32 hor_deflicker_level; /* horizontal deflicker level, 0 means horizontal deflicker is unsupporteded. */ + td_bool is_decompress; + td_bool is_premul; + td_bool is_ghdr; /* new feature. is ghdr supported. */ + td_bool is_osb; /* new feature. is smart rect supported */ +} ot_fb_capability; + +/* refresh mode */ +typedef enum { + OT_FB_LAYER_BUF_DOUBLE = 0x0, /* 2 display buf in fb */ + OT_FB_LAYER_BUF_ONE = 0x1, /* 1 display buf in fb */ + OT_FB_LAYER_BUF_NONE = 0x2, /* no display buf in fb,the buf user refreshed will be directly set to VO */ + OT_FB_LAYER_BUF_DOUBLE_IMMEDIATE = 0x3, /* 2 display buf in fb, each refresh will be displayed */ + OT_FB_LAYER_BUF_BUTT +} ot_fb_layer_buf; + +/* surface info */ +typedef struct { + td_phys_addr_t phys_addr; /* start physical address */ + td_u32 width; /* width pixels */ + td_u32 height; /* height pixels */ + td_u32 pitch; /* line pixels */ + ot_fb_color_format format; /* color format */ +} ot_fb_surface; + +typedef struct { + td_phys_addr_t phys_addr; + ot_fb_alpha alpha; + ot_fb_colorkey colorkey; +} ot_fb_surfaceex; + +/* refresh surface info */ +typedef struct { + ot_fb_surface canvas; + ot_fb_rect update_rect; /* refresh region */ +} ot_fb_buf; + +/* cursor info */ +typedef struct { + ot_fb_surface cursor; + ot_fb_point hot_pos; +} ot_fb_cursor; + +/* antiflicker level */ +/* Auto means fb will choose a appropriate antiflicker level automatically according to the color info of map */ +typedef enum { + OT_FB_LAYER_ANTIFLICKER_NONE = 0x0, /* no antiflicker */ + OT_FB_LAYER_ANTIFLICKER_LOW = 0x1, /* low level */ + OT_FB_LAYER_ANTIFLICKER_MID = 0x2, /* middle level */ + OT_FB_LAYER_ANTIFLICKER_HIGH = 0x3, /* high level */ + OT_FB_LAYER_ANTIFLICKER_AUTO = 0x4, /* auto */ + OT_FB_LAYER_ANTIFLICKER_BUTT +} ot_fb_layer_antiflicker_level; + +/* mirror mode */ +typedef enum { + OT_FB_MIRROR_NONE = 0x0, + OT_FB_MIRROR_HOR = 0x1, + OT_FB_MIRROR_VER = 0x2, + OT_FB_MIRROR_BOTH = 0x3, + OT_FB_MIRROR_BUTT +} ot_fb_mirror_mode; + +/* rotate mode */ +typedef enum { + OT_FB_ROTATE_NONE = 0x0, + OT_FB_ROTATE_90 = 0x1, + OT_FB_ROTATE_180 = 0x2, + OT_FB_ROTATE_270 = 0x3, + OT_FB_ROTATE_BUTT +} ot_fb_rotate_mode; + +/* layer info maskbit */ +typedef enum { + OT_FB_LAYER_MASK_BUF_MODE = 0x1, /* buf mode bitmask */ + OT_FB_LAYER_MASK_ANTIFLICKER_MODE = 0x2, /* antiflicker mode bitmask */ + OT_FB_LAYER_MASK_POS = 0x4, /* the position bitmask */ + OT_FB_LAYER_MASK_CANVAS_SIZE = 0x8, /* canvassize bitmask */ + OT_FB_LAYER_MASK_DISPLAY_SIZE = 0x10, /* displaysize bitmask */ + OT_FB_LAYER_MASK_SCREEN_SIZE = 0x20, /* screensize bitmask */ + OT_FB_LAYER_MASK_MUL = 0x40, /* pre-mult bitmask */ + OT_FB_LAYER_MASK_BUTT +} ot_fb_layer_info_maskbit; + +/* layer info */ +typedef struct { + ot_fb_layer_buf buf_mode; + ot_fb_layer_antiflicker_level antiflicker_level; + td_s32 x_pos; /* the x pos of origin point in screen */ + td_s32 y_pos; /* the y pos of origin point in screen */ + td_u32 canvas_width; /* the width of canvas buffer */ + td_u32 canvas_height; /* the height of canvas buffer */ + /* the width of display buf in fb.for 0 buf, there is no display buf in fb, so it's effectless */ + td_u32 display_width; + td_u32 display_height; /* the height of display buf in fb. */ + td_u32 screen_width; /* the width of screen */ + td_u32 screen_height; /* the height of screen */ + td_bool is_premul; /* The data drawn in buf is premul data or not */ + td_u32 mask; /* param modify mask bit */ +} ot_fb_layer_info; + +/* smart rect mode */ +typedef enum { + OT_FB_SMART_RECT_NONE = 0x0, /* disable smart rect */ + OT_FB_SMART_RECT_SOLID = 0x1, + OT_FB_SMART_RECT_FILLED = 0x2, + OT_FB_SMART_RECT_CORNER = 0x3, + OT_FB_SMART_RECT_BUTT +} ot_fb_smart_rect_mode; + +/* smart rect */ +typedef struct { + ot_fb_smart_rect_mode mode; + ot_fb_rect rect; + td_u32 corner_length; /* max 255 only use for OT_FB_SMART_RECT_CORNER mode */ + td_u32 thick; /* max 32 */ + td_u32 color_value; +} ot_fb_smart_rect; + +typedef struct { + td_u32 num; /* max 128 */ + ot_fb_smart_rect *rect_start; +} ot_fb_smart_rect_param; + +typedef enum { + OT_FB_CSC_MATRIX_BT601LIMIT_TO_BT601LIMIT = 0, /* BT601LIMIT to BT601LIMIT */ + OT_FB_CSC_MATRIX_BT601FULL_TO_BT601LIMIT, /* BT601FULL to BT601LIMIT */ + OT_FB_CSC_MATRIX_BT709LIMIT_TO_BT601LIMIT, /* BT709LIMIT to BT601LIMIT */ + OT_FB_CSC_MATRIX_BT709FULL_TO_BT601LIMIT, /* BT709FULL to BT601LIMIT */ + + OT_FB_CSC_MATRIX_BT601LIMIT_TO_BT709LIMIT, /* BT601LIMIT to BT709LIMIT */ + OT_FB_CSC_MATRIX_BT601FULL_TO_BT709LIMIT, /* BT601FULL to BT709LIMIT */ + OT_FB_CSC_MATRIX_BT709LIMIT_TO_BT709LIMIT, /* BT709LIMIT to BT709LIMIT */ + OT_FB_CSC_MATRIX_BT709FULL_TO_BT709LIMIT, /* BT709FULL to BT709LIMIT */ + + OT_FB_CSC_MATRIX_BT601LIMIT_TO_BT601FULL, /* BT601LIMIT to BT601FULL */ + OT_FB_CSC_MATRIX_BT601FULL_TO_BT601FULL, /* BT601FULL to BT601FULL */ + OT_FB_CSC_MATRIX_BT709LIMIT_TO_BT601FULL, /* BT709LIMIT to BT601FULL */ + OT_FB_CSC_MATRIX_BT709FULL_TO_BT601FULL, /* BT709FULL to BT601FULL */ + + OT_FB_CSC_MATRIX_BT601LIMIT_TO_BT709FULL, /* BT601LIMIT to BT709FULL */ + OT_FB_CSC_MATRIX_BT601FULL_TO_BT709FULL, /* BT601FULL to BT709FULL */ + OT_FB_CSC_MATRIX_BT709LIMIT_TO_BT709FULL, /* BT709LIMIT to BT709FULL */ + OT_FB_CSC_MATRIX_BT709FULL_TO_BT709FULL, /* BT709FULL to BT709FULL */ + + OT_FB_CSC_MATRIX_BT601LIMIT_TO_RGBFULL, /* BT601LIMIT to RGBFULL */ + OT_FB_CSC_MATRIX_BT601FULL_TO_RGBFULL, /* BT601FULL to RGBFULL */ + OT_FB_CSC_MATRIX_BT709LIMIT_TO_RGBFULL, /* BT709LIMIT to RGBFULL */ + OT_FB_CSC_MATRIX_BT709FULL_TO_RGBFULL, /* BT709FULL to RGBFULL */ + + OT_FB_CSC_MATRIX_BT601LIMIT_TO_RGBLIMIT, /* BT601LIMIT to RGBLIMIT */ + OT_FB_CSC_MATRIX_BT601FULL_TO_RGBLIMIT, /* BT601FULL to RGBLIMIT */ + OT_FB_CSC_MATRIX_BT709LIMIT_TO_RGBLIMIT, /* BT709LIMIT to RGBLIMIT */ + OT_FB_CSC_MATRIX_BT709FULL_TO_RGBLIMIT, /* BT709FULL to RGBLIMIT */ + + OT_FB_CSC_MATRIX_RGBFULL_TO_BT601LIMIT, /* RGBFULL to BT601LIMIT */ + OT_FB_CSC_MATRIX_RGBFULL_TO_BT601FULL, /* RGBFULL to BT601FULL */ + OT_FB_CSC_MATRIX_RGBFULL_TO_BT709LIMIT, /* RGBFULL to BT709LIMIT */ + OT_FB_CSC_MATRIX_RGBFULL_TO_BT709FULL, /* RGBFULL to BT709FULL */ + + OT_FB_CSC_MATRIX_BUTT +} ot_fb_layer_csc_matrix; + +typedef struct { + ot_fb_layer_csc_matrix csc_matrix; /* CSC matrix */ + td_u32 luma; /* RW Range: [0, 100] luminance, default: 50 */ + td_u32 contrast; /* RW Range: [0, 100] contrast, default: 50 */ + td_u32 hue; /* RW Range: [0, 100] hue, default: 50 */ + td_u32 saturation; /* RW Range: [0, 100] saturation, default: 50 */ + td_bool ex_csc_en; /* RW; range: [0, 1]; extended csc switch for luminance, default: 0 */ +} ot_fb_layer_csc; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + + +#endif /* GFBG_H */ + diff --git a/kernel/gfbg/hi3519dv500/src/Makefile b/kernel/gfbg/hi3519dv500/src/Makefile new file mode 100644 index 00000000..b1375e55 --- /dev/null +++ b/kernel/gfbg/hi3519dv500/src/Makefile @@ -0,0 +1,10 @@ +# Enum the C files needed to be compiled, using the relative path +SRCS+=src/gfbg_main.c +ifdef CONFIG_OT_PROC_SHOW_SUPPORT +SRCS+=src/gfbg_proc.c +endif +ifeq ($(OSTYPE),linux) + SRCS+=src/init/linux/gfbg_init.c +else ifeq ($(OSTYPE),liteos) + SRCS+=src/init/liteos/gfbg_init.c +endif diff --git a/kernel/gfbg/hi3519dv500/src/gfbg_main.c b/kernel/gfbg/hi3519dv500/src/gfbg_main.c new file mode 100755 index 00000000..6e2cefc5 --- /dev/null +++ b/kernel/gfbg/hi3519dv500/src/gfbg_main.c @@ -0,0 +1,8040 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "gfbg_main.h" +#include "ot_debug.h" +#include "mm_ext.h" +#include "securec.h" +#include "drv_tde.h" +#include "gfbg_graphics.h" +#ifdef CONFIG_OT_PROC_SHOW_SUPPORT +#include "gfbg_proc.h" +#endif +#include "gfbg.h" +#include "gfbg_blit.h" +#include "gfbg_ext.h" +#include "gfbg_def.h" +#include "gfbg_rotate.h" +#include "gfbg_comm.h" +#include "gfbg_init.h" +#include "sys_ext.h" +#include "proc_ext.h" + +#define mkstr(exp) # exp +#define mkmarcotostr(exp) mkstr(exp) + +#define GFBG_CMAP_LEN 256 +#define GFBG_ROTBUF_NAME_LEN 16 + +typedef td_s32(*drv_gfbg_ioctl_func)(struct fb_info *info, unsigned long arg); + +typedef struct { + td_u32 cmd; + drv_gfbg_ioctl_func func; +}drv_gfbg_ioctl_func_item; + +#define PAGE_SIZE_ALIGN_MAX ((~0ul - PAGE_SIZE) / 1024) + +#ifdef __LITEOS__ +#define in_atomic() (TD_FALSE) +#endif + +#define GFBG_ALIGNMENT 0xf +#define GFBG_ALIGN 16 + +#define gfbg_debug_print_vcnt(dev, format, args...) \ + do { \ + td_u32 __vcnt = 0; \ + graphic_drv_get_int_state_vcnt(dev, &__vcnt); \ + gfbg_debug("dev %d cnt %d in "format"\n", dev, __vcnt, ##args); \ + } while (0) + +/* + * the interface to operate the chip + * Collection of properties and methods,filled in gfbg_init + */ +static gfbg_drv_ops g_drv_ops; + +static td_bool g_soft_cursor = TD_FALSE; +static td_bool g_display_on = TD_FALSE; +static td_bool g_gfbg_register = TD_TRUE; +static osal_spinlock g_gfbg_vdp_state_count_lock; +static td_u32 g_gfbg_open_layer_count = 0; +static td_bool g_gfbg_vdp_clk_state = TD_FALSE; +#define VO_INVALID_DEV (-1) +#define VO_DEV_DHD0 0 +#define VO_DEV_DHD1 1 +#define VO_DEV_DSD0 2 + +#define GFBG_INTMSK_HD0_VTTHD1 0x1 +#define GFBG_INTMSK_HD0_VTTHD2 0x2 +#define GFBG_INTMSK_HD0_VTTHD3 0x4 +#define GFBG_INTMSK_HD1_VTTHD1 0x10 +#define GFBG_INTMSK_HD1_VTTHD2 0x20 +#define GFBG_INTMSK_HD1_VTTHD3 0x40 +#define GFBG_INTMSK_SD0_VTTHD1 0x100 +#define GFBG_INTMSK_SD0_VTTHD2 0x200 +#define GFBG_INTMSK_SD0_VTTHD3 0x400 + +#define DRV_GFBG_IOCTL_CMD_NUM_MAX 154 +#define DRV_GFBG_IOCTL_FUNC_ITEM_NUM_MAX 30 + +static td_s32 gfbg_parse_cfg(td_void); +static td_s32 gfbg_overlay_probe(td_u32 layer_id); +static td_void gfbg_overlay_cleanup(td_u32 layer_id, td_bool unregister); +#ifdef __LITEOS__ +typedef gfbg_info fb_info; +typedef fb_cmap_s fb_cmap; +static td_s32 gfbg_pan_display(struct fb_vtable_s *vtable, struct fb_overlayinfo_s *oinfo); +#else +static td_s32 gfbg_pan_display(struct fb_var_screeninfo *var, struct fb_info *info); +#endif +static ot_fb_color_format gfbg_getfmtbyargb(const struct fb_bitfield *red, const struct fb_bitfield *green, + const struct fb_bitfield *blue, const struct fb_bitfield *transp, + td_u32 color_depth); +static td_void gfbg_buf_freemem(td_phys_addr_t phyaddr); +static td_phys_addr_t gfbg_buf_allocmem(const td_char *buf_name, td_u32 buf_name_size, td_ulong layer_size, + const td_char *mmz_name); + +static td_s32 gfbg_wait_regconfig_work(td_u32 layer_id); +static td_s32 gfbg_freeccanbuf(gfbg_par *par); +static td_void gfbg_set_dispbufinfo(td_u32 layer_id); +static td_void gfbg_set_bufmode(td_u32 layer_id, ot_fb_layer_buf layer_buf_mode); +static inline td_void gfbg_get_bufmode(const gfbg_par *par, ot_fb_layer_buf *buf_mode); +static td_s32 gfbg_onrefresh(gfbg_par* par, td_void __user *argp); +static td_s32 gfbg_refresh_0buf(td_u32 layer_id, const ot_fb_buf *canvas_buf); +static td_s32 gfbg_refresh_1buf(td_u32 layer_id, const ot_fb_buf *canvas_buf); +static td_s32 gfbg_refresh_2buf(td_u32 layer_id, const ot_fb_buf *canvas_buf); +static td_s32 gfbg_refresh_2buf_immediate_display(td_u32 layer_id, const ot_fb_buf *canvas_buf); +static td_s32 gfbg_set_mirrormode(gfbg_par *par, ot_fb_mirror_mode mirror_mode); +static td_s32 gfbg_set_rotatemode(const struct fb_info *info, ot_fb_rotate_mode rotate_mode); +static td_s32 gfbg_onputlayerinfo(struct fb_info *info, gfbg_par* par, const td_void __user *argp); +static td_void gfbg_get_layerinfo(const gfbg_par *par, ot_fb_layer_info *layer_info); +static inline td_void gfbg_get_antiflickerlevel(const gfbg_par *par, ot_fb_layer_antiflicker_level *antiflicker_level); +static td_void gfbg_set_antiflickerlevel(td_u32 layer_id, ot_fb_layer_antiflicker_level antiflicker_level); +static inline td_void gfbg_get_fmt(const gfbg_par *par, ot_fb_color_format *color_format); +static inline td_void gfbg_set_fmt(gfbg_par *par, ot_fb_color_format color_fmt); +static inline td_void gfbg_set_alpha(gfbg_par *par, const ot_fb_alpha *alpha); +static inline td_void gfbg_get_alpha(const gfbg_par *par, ot_fb_alpha *alpha); +static inline td_void gfbg_set_key(gfbg_par *par, const gfbg_colorkeyex *key); +static inline td_void gfbg_get_key(const gfbg_par *par, gfbg_colorkeyex *key); +static inline td_void gfbg_get_layerpos(const gfbg_par *par, ot_fb_point *pos); +static td_void gfbg_get_screensize(const gfbg_par *par, td_u32 *width, td_u32 *height); +static td_s32 gfbg_set_screensize(gfbg_par *par, const td_u32 *width, const td_u32 *height); +static td_void gfbg_get_maxscreensize(gfbg_par *par, td_u32 *width, td_u32 *height); +static td_void gfbg_get_dispsize(const gfbg_par *par, td_u32 *width, td_u32 *height); +static inline td_void gfbg_get_premul(const gfbg_par *par, td_bool *premul); +static inline td_bool gfbg_get_show(const gfbg_par *par); +static inline td_void gfbg_set_show(gfbg_par *par, td_bool show); +static td_void gfbg_set_layerpos(gfbg_par *par, const ot_fb_point *pos); +static td_void gfbg_tde_rotate_callback(const td_void *paraml, const td_void *paramr); +static td_void gfbg_tde_callback(const td_void *paraml, const td_void *paramr); +static td_s32 gfbg_interrupt_process(td_u32 layer_id); +static td_void gfbg_get_idledispbuf(const gfbg_par *par, td_phys_addr_t *phy_addr); +static td_void gfbg_get_workdispbuf(const gfbg_par *par, td_phys_addr_t *phy_addr); +static inline td_bool gfbg_is_interlace(const gfbg_par *par); + +static td_s32 gfbg_read_proc(struct osal_proc_dir_entry *entry); +static td_s32 gfbg_write_proc(struct osal_proc_dir_entry *entry, const char *buf, int count, long long *); + +static td_s32 drv_gfbg_get_colorkey(struct fb_info *info, unsigned long arg); +static td_s32 drv_gfbg_set_colorkey(struct fb_info *info, unsigned long arg); +static td_s32 drv_gfbg_get_layer_alpha(struct fb_info *info, unsigned long arg); +static td_s32 drv_gfbg_set_layer_alpha(struct fb_info *info, unsigned long arg); +static td_s32 drv_gfbg_get_screen_origin_pos(struct fb_info *info, unsigned long arg); +static td_s32 drv_gfbg_set_screen_origin_pos(struct fb_info *info, unsigned long arg); +static td_s32 drv_gfbg_get_vblank(struct fb_info *info, unsigned long arg); +static td_s32 drv_gfbg_show_layer(struct fb_info *info, unsigned long arg); +static td_s32 drv_gfbg_get_layer_show_state(struct fb_info *info, unsigned long arg); +static td_s32 drv_gfbg_get_capability(struct fb_info *info, unsigned long arg); +static td_s32 drv_gfbg_set_layer_info(struct fb_info *info, unsigned long arg); +static td_s32 drv_gfbg_get_layer_info(struct fb_info *info, unsigned long arg); +static td_s32 drv_gfbg_get_canvas_buffer(struct fb_info *info, unsigned long arg); +static td_s32 drv_gfbg_refresh_layer(struct fb_info *info, unsigned long arg); +static td_s32 drv_gfbg_wait_refresh_finish(struct fb_info *info, unsigned long arg); +static td_s32 drv_gfbg_set_mirror_mode(struct fb_info *info, unsigned long arg); +static td_s32 drv_gfbg_get_mirror_mode(struct fb_info *info, unsigned long arg); +static td_s32 drv_gfbg_set_rotate_mode(struct fb_info *info, unsigned long arg); +static td_s32 drv_gfbg_get_rotate_mode(struct fb_info *info, unsigned long arg); +static td_s32 drv_gfbg_set_screen_size(struct fb_info *info, unsigned long arg); +static td_s32 drv_gfbg_get_screen_size(struct fb_info *info, unsigned long arg); +static td_s32 drv_gfbg_flip_surface(struct fb_info *info, unsigned long arg); +static td_s32 drv_gfbg_get_compression_mode(struct fb_info *info, unsigned long arg); +static td_s32 drv_gfbg_create(struct fb_info *info, unsigned long arg); +static td_s32 drv_gfbg_release(struct fb_info *info, unsigned long arg); +static td_s32 drv_gfbg_set_compression_mode(struct fb_info *info, unsigned long arg); +static td_s32 drv_gfbg_draw_frame(struct fb_info *info, unsigned long arg); + +static td_s32 drv_gfbg_set_layer_csc(struct fb_info *info, unsigned long arg); +static td_s32 drv_gfbg_get_layer_csc(struct fb_info *info, unsigned long arg); + +static td_s32 g_drv_gfbg_ctl_num[DRV_GFBG_IOCTL_CMD_NUM_MAX] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 0, 0, + 7, 8, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 11, 12, 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 26, 27, 28, 29 +}; + +static drv_gfbg_ioctl_func_item g_drv_gfbg_ioctl_func[DRV_GFBG_IOCTL_FUNC_ITEM_NUM_MAX] = { + {0, TD_NULL}, + {FBIOGET_COLORKEY_GFBG, drv_gfbg_get_colorkey}, + {FBIOPUT_COLORKEY_GFBG, drv_gfbg_set_colorkey}, + {FBIOGET_ALPHA_GFBG, drv_gfbg_get_layer_alpha}, + {FBIOPUT_ALPHA_GFBG, drv_gfbg_set_layer_alpha}, + {FBIOGET_SCREEN_ORIGIN_GFBG, drv_gfbg_get_screen_origin_pos}, + {FBIOPUT_SCREEN_ORIGIN_GFBG, drv_gfbg_set_screen_origin_pos}, + {FBIOGET_VER_BLANK_GFBG, drv_gfbg_get_vblank}, + {FBIOPUT_SHOW_GFBG, drv_gfbg_show_layer}, + {FBIOGET_SHOW_GFBG, drv_gfbg_get_layer_show_state}, + {FBIOGET_CAPABILITY_GFBG, drv_gfbg_get_capability}, + {FBIOPUT_LAYER_INFO, drv_gfbg_set_layer_info}, + {FBIOGET_LAYER_INFO, drv_gfbg_get_layer_info}, + {FBIOGET_CANVAS_BUF, drv_gfbg_get_canvas_buffer}, + {FBIO_REFRESH, drv_gfbg_refresh_layer}, + {FBIO_WAITFOR_FREFRESH_DONE, drv_gfbg_wait_refresh_finish}, + {FBIOPUT_MIRROR_MODE, drv_gfbg_set_mirror_mode}, + {FBIOGET_MIRROR_MODE, drv_gfbg_get_mirror_mode}, + {FBIOPUT_ROTATE_MODE, drv_gfbg_set_rotate_mode}, + {FBIOGET_ROTATE_MODE, drv_gfbg_get_rotate_mode}, + {FBIOPUT_SCREEN_SIZE, drv_gfbg_set_screen_size}, + {FBIOGET_SCREEN_SIZE, drv_gfbg_get_screen_size}, + {FBIOFLIP_SURFACE, drv_gfbg_flip_surface}, + {FBIOPUT_COMPRESSION_GFBG, drv_gfbg_set_compression_mode}, + {FBIOGET_COMPRESSION_GFBG, drv_gfbg_get_compression_mode}, + {FBIO_CREATE_LAYER, drv_gfbg_create}, + {FBIO_DESTROY_LAYER, drv_gfbg_release}, + {FBIO_DRAW_SMART_RECT, drv_gfbg_draw_frame}, + {FBIOPUT_GRAPHIC_LAYER_CSC_GFBG, drv_gfbg_set_layer_csc}, + {FBIOGET_GRAPHIC_LAYER_CSC_GFBG, drv_gfbg_get_layer_csc}, +}; + +td_s32 graphic_drv_vdp_state_count_lock_init(td_void) +{ + return osal_spin_lock_init(&g_gfbg_vdp_state_count_lock); +} +td_void graphic_drv_vdp_state_count_lock_deinit(td_void) +{ + osal_spin_lock_destroy(&g_gfbg_vdp_state_count_lock); +} + +static td_bool is_soft_cursor(td_void) +{ + return g_soft_cursor; +} + +static td_bool gfbg_check_memory_enough(const struct fb_info *info, td_u32 stride) +{ + if ((stride * info->var.yres * 2) <= info->fix.smem_len) { /* 2 two buffer */ + return TD_TRUE; + } + return TD_FALSE; +} + +#ifndef __LITEOS__ +static td_phys_addr_t gfbg_get_smem_start(const struct fb_info* info) +{ + return (td_phys_addr_t)info->fix.smem_start; +} + +static td_s8 *gfbg_get_screen_base(const struct fb_info* info) +{ + return (td_s8*)info->screen_base; +} + +static td_u32 gfbg_get_xres(const struct fb_info* info) +{ + return (td_u32)info->var.xres; +} + +static td_u32 gfbg_get_yres(const struct fb_info* info) +{ + return (td_u32)info->var.yres; +} + +static td_u32 gfbg_get_xres_virtual(const struct fb_info* info) +{ + return (td_u32)info->var.xres_virtual; +} + +static td_u32 gfbg_get_yres_virtual(const struct fb_info* info) +{ + return (td_u32)info->var.yres_virtual; +} + +static td_u32 gfbg_get_smem_len(const struct fb_info* info) +{ + return (td_u32)info->fix.smem_len; +} + +static td_u32 gfbg_get_line_length(const struct fb_info* info) +{ + return (td_u32)info->fix.line_length; +} + +/* when compress to uncompress,use for calculate xoffset,yoffset */ +static td_u32 gfbg_get_line_length_ex(const struct fb_info* info) +{ + td_u32 uncompress_stride; + uncompress_stride = (info->var.xres_virtual * info->var.bits_per_pixel / 8 + /* 8 one byte */ + GFBG_ALIGNMENT) & (~GFBG_ALIGNMENT); + if (gfbg_check_memory_enough(info, uncompress_stride) == TD_TRUE) { + return uncompress_stride; + } else { + return (td_u32)info->fix.line_length; + } +} + +static td_u32 gfbg_get_bits_per_pixel(const struct fb_info* info) +{ + return (td_u32)info->var.bits_per_pixel; +} + +static td_u32 gfbg_get_yoffset(const struct fb_info* info) +{ + return (td_u32)info->var.yoffset; +} + +static td_u32 gfbg_get_xoffset(const struct fb_info* info) +{ + return (td_u32)info->var.xoffset; +} + +static struct fb_fix_screeninfo g_default_fix[GFBG_MAX_LAYER_NUM] = { + { + .id = "gfbg", /* String identifierString identifier */ + .type = FB_TYPE_PACKED_PIXELS, /* FB type */ + .visual = FB_VISUAL_TRUECOLOR, + .xpanstep = 1, + .ypanstep = 1, + .ywrapstep = 0, + .line_length = GFBG_4K_DEF_STRIDE, + .accel = FB_ACCEL_NONE, + .mmio_len = 0, + .mmio_start = 0, + }, + { + .id = "gfbg", + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_TRUECOLOR, + .xpanstep = 1, + .ypanstep = 1, + .ywrapstep = 0, + .line_length = GFBG_HD_DEF_STRIDE, + .accel = FB_ACCEL_NONE, + .mmio_len = 0, + .mmio_start = 0, + }, + { + .id = "gfbg", + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_TRUECOLOR, + .xpanstep = 1, + .ypanstep = 1, + .ywrapstep = 0, + .line_length = GFBG_SD_DEF_STRIDE, + .accel = FB_ACCEL_NONE, + .mmio_len = 0, + .mmio_start = 0, + }, + { + .id = "gfbg", + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_TRUECOLOR, + .xpanstep = 1, + .ypanstep = 1, + .ywrapstep = 0, + .line_length = GFBG_SD_DEF_STRIDE, + .accel = FB_ACCEL_NONE, + .mmio_len = 0, + .mmio_start = 0, + }, + { + .id = "gfbg", + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_TRUECOLOR, + .xpanstep = 1, + .ypanstep = 1, + .ywrapstep = 0, + .line_length = GFBG_HD_DEF_STRIDE, + .accel = FB_ACCEL_NONE, + .mmio_len = 0, + .mmio_start = 0, + } +}; + +/* default variable information */ +/* + * Name : g_default_var + * Desc : default variable info: g_default_var + * See : gfbg_open + */ +static struct fb_var_screeninfo g_default_var[GFBG_MAX_LAYER_NUM] = { + /* for 4K layer */ + { + .xres = GFBG_4K_DEF_WIDTH, + .yres = GFBG_4K_DEF_HEIGHT, + .xres_virtual = GFBG_4K_DEF_WIDTH, + .yres_virtual = GFBG_4K_DEF_HEIGHT, + .xoffset = 0, + .yoffset = 0, + .bits_per_pixel = GFBG_DEF_DEPTH, + .red = {10, 5, 0}, + .green = {5, 5, 0}, + .blue = {0, 5, 0}, + .transp = {15, 1, 0}, + .activate = FB_ACTIVATE_NOW, + .pixclock = -1, /* pixel clock in ps (pico seconds) */ + .left_margin = 0, /* time from sync to picture */ + .right_margin = 0, /* time from picture to sync */ + .upper_margin = 0, /* time from sync to picture */ + .lower_margin = 0, + .hsync_len = 0, /* length of horizontal sync */ + .vsync_len = 0, /* length of vertical sync */ + }, + /* for HD layer */ + { + .xres = GFBG_HD_DEF_WIDTH, + .yres = GFBG_HD_DEF_HEIGHT, + .xres_virtual = GFBG_HD_DEF_WIDTH, + .yres_virtual = GFBG_HD_DEF_HEIGHT, + .xoffset = 0, + .yoffset = 0, + .bits_per_pixel = GFBG_DEF_DEPTH, + .red = {10, 5, 0}, + .green = {5, 5, 0}, + .blue = {0, 5, 0}, + .transp = {15, 1, 0}, + .activate = FB_ACTIVATE_NOW, + .pixclock = -1, /* pixel clock in ps (pico seconds) */ + .left_margin = 0, /* time from sync to picture */ + .right_margin = 0, /* time from picture to sync */ + .upper_margin = 0, /* time from sync to picture */ + .lower_margin = 0, + .hsync_len = 0, /* length of horizontal sync */ + .vsync_len = 0, /* length of vertical sync */ + }, + /* for SD layer */ + { + .xres = GFBG_SD_DEF_WIDTH, + .yres = GFBG_SD_DEF_HEIGHT, + .xres_virtual = GFBG_SD_DEF_WIDTH, + .yres_virtual = GFBG_SD_DEF_HEIGHT, + .xoffset = 0, + .yoffset = 0, + .bits_per_pixel = GFBG_DEF_DEPTH, + .red = {10, 5, 0}, + .green = {5, 5, 0}, + .blue = {0, 5, 0}, + .transp = {15, 1, 0}, + .activate = FB_ACTIVATE_NOW, + .pixclock = -1, /* pixel clock in ps (pico seconds) */ + .left_margin = 0, /* time from sync to picture */ + .right_margin = 0, /* time from picture to sync */ + .upper_margin = 0, /* time from sync to picture */ + .lower_margin = 0, + .hsync_len = 0, /* length of horizontal sync */ + .vsync_len = 0, /* length of vertical sync */ + }, + /* for AD layer */ + { + .xres = GFBG_AD_DEF_WIDTH, + .yres = GFBG_AD_DEF_HEIGHT, + .xres_virtual = GFBG_AD_DEF_WIDTH, + .yres_virtual = GFBG_AD_DEF_HEIGHT, + .xoffset = 0, + .yoffset = 0, + .bits_per_pixel = GFBG_DEF_DEPTH, + .red = {10, 5, 0}, + .green = {5, 5, 0}, + .blue = {0, 5, 0}, + .transp = {15, 1, 0}, + .activate = FB_ACTIVATE_NOW, + .pixclock = -1, /* pixel clock in ps (pico seconds) */ + .left_margin = 0, /* time from sync to picture */ + .right_margin = 0, /* time from picture to sync */ + .upper_margin = 0, /* time from sync to picture */ + .lower_margin = 0, + .hsync_len = 0, /* length of horizontal sync */ + .vsync_len = 0, /* length of vertical sync */ + }, + /* for cursor layer */ + { + .xres = GFBG_CURSOR_DEF_WIDTH, + .yres = GFBG_CURSOR_DEF_HEIGHT, + .xres_virtual = GFBG_CURSOR_DEF_WIDTH, + .yres_virtual = GFBG_CURSOR_DEF_HEIGHT, + .xoffset = 0, + .yoffset = 0, + .bits_per_pixel = GFBG_DEF_DEPTH, + .red = {10, 5, 0}, + .green = {5, 5, 0}, + .blue = {0, 5, 0}, + .transp = {15, 1, 0}, + .activate = FB_ACTIVATE_NOW, + .pixclock = -1, /* pixel clock in ps (pico seconds) */ + .left_margin = 0, /* time from sync to picture */ + .right_margin = 0, /* time from picture to sync */ + .upper_margin = 0, /* time from sync to picture */ + .lower_margin = 0, + .hsync_len = 0, /* length of horizontal sync */ + .vsync_len = 0, /* length of vertical sync */ + } +}; +#else +static td_phys_addr_t gfbg_get_smem_start(const struct gfbg_info* info) +{ + return (td_phys_addr_t)(uintptr_t)info->oinfo.fbmem; +} + +static td_s8 *gfbg_get_screen_base(const struct gfbg_info* info) +{ + return (td_s8 *)info->oinfo.fbmem; +} + +static td_u32 gfbg_get_xres(const struct gfbg_info* info) +{ + return (td_u32)info->vinfo.xres; +} + +static td_u32 gfbg_get_yres(const struct gfbg_info* info) +{ + return (td_u32)info->vinfo.yres; +} + +static td_u32 gfbg_get_xres_virtual(const struct gfbg_info* info) +{ + return (td_u32)info->oinfo.sarea.width; +} + +static td_u32 gfbg_get_yres_virtual(const struct gfbg_info* info) +{ + return (td_u32)info->oinfo.sarea.height; +} + +static td_u32 gfbg_get_smem_len(const struct gfbg_info* info) +{ + return (td_u32)info->oinfo.fblen; +} + +static td_u32 gfbg_get_line_length(const struct gfbg_info* info) +{ + return (td_u32)info->oinfo.stride; +} + +static td_u32 gfbg_get_bits_per_pixel(const struct gfbg_info* info) +{ + return (td_u32)info->oinfo.bpp; +} + +static td_u32 gfbg_get_yoffset(const struct gfbg_info* info) +{ + return (td_u32)info->oinfo.sarea.y; +} + +static td_u32 gfbg_get_xoffset(const struct gfbg_info* info) +{ + return (td_u32)info->oinfo.sarea.x; +} + +struct gfbg_screeninfo { + uint8_t format; /* see FB_FMT_* */ + fb_coord_t xres; /* Horizontal resolution in pixel columns */ + fb_coord_t yres; /* Vertical resolution in pixel rows */ + struct fb_area_s sarea; /* Selected area within the overlay */ + fb_coord_t stride; /* Length of a line in bytes */ + uint8_t bpp; /* Bits per pixel */ + uint32_t accl; /* Supported hardware acceleration */ + uint8_t nplanes; /* Number of color planes supported */ + uint8_t noverlays; /* Number of overlays supported */ +}; + +static struct gfbg_screeninfo g_default_info[GFBG_MAX_LAYER_NUM] = { + /* for 4K layer */ + { + .format = OT_FB_FORMAT_ARGB1555, + .xres = GFBG_4K_DEF_WIDTH, + .yres = GFBG_4K_DEF_HEIGHT, + .sarea = {0, 0, GFBG_4K_DEF_WIDTH, GFBG_4K_DEF_HEIGHT}, + .stride = GFBG_4K_DEF_STRIDE, + .bpp = GFBG_DEF_DEPTH, + .accl = 0, + .nplanes = 1, + .noverlays = 1, + }, + /* for HD layer */ + { + .format = OT_FB_FORMAT_ARGB1555, + .xres = GFBG_HD_DEF_WIDTH, + .yres = GFBG_HD_DEF_HEIGHT, + .sarea = {0, 0, GFBG_HD_DEF_WIDTH, GFBG_HD_DEF_HEIGHT}, + .stride = GFBG_HD_DEF_STRIDE, + .bpp = GFBG_DEF_DEPTH, + .accl = 0, + .nplanes = 1, + .noverlays = 1, + }, + /* for SD layer */ + { + .format = OT_FB_FORMAT_ARGB1555, + .xres = GFBG_SD_DEF_WIDTH, + .yres = GFBG_SD_DEF_HEIGHT, + .sarea = {0, 0, GFBG_SD_DEF_WIDTH, GFBG_SD_DEF_HEIGHT}, + .stride = GFBG_SD_DEF_STRIDE, + .bpp = GFBG_DEF_DEPTH, + .accl = 0, + .nplanes = 1, + .noverlays = 1, + }, + /* for AD layer */ + { + .format = OT_FB_FORMAT_ARGB1555, + .xres = GFBG_AD_DEF_WIDTH, + .yres = GFBG_AD_DEF_HEIGHT, + .sarea = {0, 0, GFBG_AD_DEF_WIDTH, GFBG_AD_DEF_HEIGHT}, + .stride = GFBG_AD_DEF_STRIDE, + .bpp = GFBG_DEF_DEPTH, + .accl = 0, + .nplanes = 1, + .noverlays = 1, + }, + /* for cursor layer */ + { + .format = OT_FB_FORMAT_ARGB1555, + .xres = GFBG_CURSOR_DEF_WIDTH, + .yres = GFBG_CURSOR_DEF_HEIGHT, + .sarea = {0, 0, GFBG_CURSOR_DEF_WIDTH, GFBG_CURSOR_DEF_HEIGHT}, + .stride = GFBG_CURSOR_DEF_STRIDE, + .bpp = GFBG_DEF_DEPTH, + .accl = 0, + .nplanes = 1, + .noverlays = 1, + }, +}; + +static void gfbg_screeninfo_init(struct gfbg_info *info, struct gfbg_screeninfo *sinfo) +{ + info->vinfo.xres = sinfo->xres; + info->vinfo.yres = sinfo->yres; + info->oinfo.sarea = sinfo->sarea; + info->oinfo.bpp = sinfo->bpp; + info->oinfo.stride = sinfo->stride; + info->oinfo.accl = sinfo->accl; + info->vinfo.nplanes = sinfo->nplanes; + info->vinfo.noverlays = sinfo->noverlays; +}; +#endif + +/* + * Name : g_argb_bit_field + * Desc : bit fields of each color format in GFBG_COLOR_FMT_E, + * the order must be the same as that of GFBG_COLOR_FMT_E + */ +static gfbg_argb_bitinfo g_argb_bit_field[] = { + /* RGB565 */ + { + .red = {11, 5, 0}, + .green = {5, 6, 0}, + .blue = {0, 5, 0}, + .transp = {0, 0, 0}, + }, + /* RGB888 */ + { + .red = {16, 8, 0}, + .green = {8, 8, 0}, + .blue = {0, 8, 0}, + .transp = {0, 0, 0}, + }, + /* KRGB444 */ + { + .red = {8, 4, 0}, + .green = {4, 4, 0}, + .blue = {0, 4, 0}, + .transp = {0, 0, 0}, + }, + /* KRGB555 */ + { + .red = {10, 5, 0}, + .green = {5, 5, 0}, + .blue = {0, 5, 0}, + .transp = {0, 0, 0}, + }, + /* KRGB888 */ + { + .red = {16, 8, 0}, + .green = {8, 8, 0}, + .blue = {0, 8, 0}, + .transp = {0, 0, 0}, + }, + /* ARGB4444 */ + { + .red = {8, 4, 0}, + .green = {4, 4, 0}, + .blue = {0, 4, 0}, + .transp = {12, 4, 0}, + }, + /* ARGB1555 */ + { + .red = {10, 5, 0}, + .green = {5, 5, 0}, + .blue = {0, 5, 0}, + .transp = {15, 1, 0}, + }, + /* ARGB8888 */ + { + .red = {16, 8, 0}, + .green = {8, 8, 0}, + .blue = {0, 8, 0}, + .transp = {24, 8, 0}, + }, + /* ARGB8565 */ + { + .red = {11, 5, 0}, + .green = {5, 6, 0}, + .blue = {0, 5, 0}, + .transp = {16, 8, 0}, + }, + /* RGBA4444 */ + { + .red = {12, 4, 0}, + .green = {8, 4, 0}, + .blue = {4, 4, 0}, + .transp = {0, 4, 0}, + }, + /* RGBA5551 */ + { + .red = {11, 5, 0}, + .green = {6, 5, 0}, + .blue = {1, 5, 0}, + .transp = {0, 1, 0}, + }, + /* RGBA5658 */ + { + .red = {19, 5, 0}, + .green = {13, 6, 0}, + .blue = {8, 5, 0}, + .transp = {0, 8, 0}, + }, + /* RGBA8888 */ + { + .red = {24, 8, 0}, + .green = {16, 8, 0}, + .blue = {8, 8, 0}, + .transp = {0, 8, 0}, + }, + /* BGR565 */ + { + .red = {0, 5, 0}, + .green = {5, 6, 0}, + .blue = {11, 5, 0}, + .transp = {0, 0, 0}, + }, + /* BGR888 */ + { + .red = {0, 8, 0}, + .green = {8, 8, 0}, + .blue = {16, 8, 0}, + .transp = {0, 0, 0}, + }, + /* ABGR4444 */ + { + .red = {0, 4, 0}, + .green = {4, 4, 0}, + .blue = {8, 4, 0}, + .transp = {12, 4, 0}, + }, + /* ABGR1555 */ + { + .red = {0, 5, 0}, + .green = {5, 5, 0}, + .blue = {10, 5, 0}, + .transp = {15, 1, 0}, + }, + /* ABGR8888 */ + { + .red = {0, 8, 0}, + .green = {8, 8, 0}, + .blue = {16, 8, 0}, + .transp = {24, 8, 0}, + }, + /* ABGR8565 */ + { + .red = {0, 5, 0}, + .green = {5, 6, 0}, + .blue = {11, 5, 0}, + .transp = {16, 8, 0}, + }, + /* KBGR444 16bpp */ + { + .red = {0, 4, 0}, + .green = {4, 4, 0}, + .blue = {8, 4, 0}, + .transp = {0, 0, 0}, + }, + /* KBGR555 16bpp */ + { + .red = {0, 5, 0}, + .green = {5, 5, 0}, + .blue = {10, 5, 0}, + .transp = {0, 0, 0}, + }, + /* KBGR888 32bpp */ + { + .red = {0, 8, 0}, + .green = {8, 8, 0}, + .blue = {16, 8, 0}, + .transp = {0, 0, 0}, + }, + + /* 1bpp */ + { + .red = {0, 1, 0}, + .green = {0, 1, 0}, + .blue = {0, 1, 0}, + .transp = {0, 0, 0}, + }, + /* 2bpp */ + { + .red = {0, 2, 0}, + .green = {0, 2, 0}, + .blue = {0, 2, 0}, + .transp = {0, 0, 0}, + }, + /* 4bpp */ + { + .red = {0, 4, 0}, + .green = {0, 4, 0}, + .blue = {0, 4, 0}, + .transp = {0, 0, 0}, + }, + /* 8bpp */ + { + .red = {0, 8, 0}, + .green = {0, 8, 0}, + .blue = {0, 8, 0}, + .transp = {0, 0, 0}, + }, + /* ACLUT44 */ + { + .red = {4, 4, 0}, + .green = {4, 4, 0}, + .blue = {4, 4, 0}, + .transp = {0, 4, 0}, + }, + /* ACLUT88 */ + { + .red = {8, 8, 0}, + .green = {8, 8, 0}, + .blue = {8, 8, 0}, + .transp = {0, 8, 0}, + } +}; + +static td_s32 tde_cal_scale_rect_gfbg(const drv_tde_rect* src_rect, const drv_tde_rect* dst_rect, + const drv_tde_rect* rect_in_src, drv_tde_rect* rect_in_dst) +{ + rect_in_dst->pos_x = rect_in_src->pos_x * dst_rect->width / src_rect->width; + rect_in_dst->pos_y = rect_in_src->pos_y * dst_rect->height / src_rect->height; + rect_in_dst->height = dst_rect->height; + rect_in_dst->width = dst_rect->width; + + return TD_SUCCESS; +} + +static td_void gfbg_version(td_void); +static td_s32 gfbg_refresh(td_u32 layer_id, const ot_fb_buf *canvas_buf, ot_fb_layer_buf buf_mode); +static td_void gfbg_select_antiflicker_mode(gfbg_par *par); +static td_s32 gfbg_setcolreg(unsigned regno, unsigned red, unsigned green, + unsigned blue, unsigned transp, struct fb_info *info); + +gfbg_layer g_layer[GFBG_MAX_LAYER_NUM]; +char *g_video; /* 128 for vram length */ + +static char g_display[8] = "off"; /* 8:open vo or not */ +static char g_softcursor[8] = "off"; /* 8:use soft cursor or not */ + +td_void set_video_name(char *temp_video) +{ + g_video = temp_video; +} + +static td_s32 gfbg_drv_set_mmz_addr(td_phys_addr_t phys_addr, td_u32 phys_len, td_u32 layer_id) +{ + td_s32 ret; + ot_tde_export_func *tde_export_func = func_entry(ot_tde_export_func, OT_ID_TDE); + if ((tde_export_func == TD_NULL) || (tde_export_func->drv_tde_module_set_gfbg_mmz_addr == TD_NULL)) { + gfbg_error("TDE tde_export_func is NULL!\n"); + return TD_FAILURE; + } + + ret = tde_export_func->drv_tde_module_set_gfbg_mmz_addr(phys_addr, phys_len, layer_id); + if (ret != TD_SUCCESS) { + osal_printk("GFBG Warning: TDE set gfbg mmz addr failed\n"); + return ret; + } + + return TD_SUCCESS; +} + +/* + * Name : gfbg_fill_data + * Desc : fill buffer, it is faster than memset_s. + * See : Called by gfbg_overlay_probe + */ +static td_u32 gfbg_fill_data(const struct fb_info* info, td_u32 fill_data, size_t n) +{ + ot_fb_buf dst_img; + td_s8 *rest = TD_NULL; + const td_u32 can_pitch = GFBG_TDE_MEMSET_WIDTH * 4; /* 4 alg data */ + + /* + * Assume that the image width is 3840, the format is ARBG8888, and the image is filled by TDE. + * Since the size of the image that TDE can handle is limited, + * the width and height are limited to GFBG_TDE_MEMSET_WIDTH + * and GFBG_TDE_MEMSET_HEIGHT, Exceeded parts are cleared using memset_s + * Configure the target image, pitch, format, width and height, physical address (pointing to the memory start + * address) + */ + dst_img.canvas.phys_addr = gfbg_get_smem_start(info); + dst_img.canvas.pitch = can_pitch; + dst_img.canvas.format = OT_FB_FORMAT_ABGR8888; + dst_img.canvas.width = GFBG_TDE_MEMSET_WIDTH; + dst_img.canvas.height = n / can_pitch; + + if (dst_img.canvas.height > GFBG_TDE_MEMSET_HEIGHT) { + dst_img.canvas.height = GFBG_TDE_MEMSET_HEIGHT; + } + if (dst_img.canvas.height != 0) { + if (gfbg_drv_fill(&dst_img, fill_data) != TD_SUCCESS) { + gfbg_error("gfbg_drv_fill fail!\n"); + return TD_FAILURE; + } + } + + /* The memory not in the canvas is set by memset_s */ + if ((n - dst_img.canvas.height * can_pitch) != 0) { + rest = gfbg_get_screen_base(info) + can_pitch * (dst_img.canvas.height); + (td_void)memset_s(rest, n - dst_img.canvas.height * can_pitch, fill_data, + n - dst_img.canvas.height * can_pitch); + } + return TD_SUCCESS; +} + +/* + * Name : gfbg_set_dcmp_info + * Desc : set the decompression info. + */ +static td_void gfbg_set_dcmp_info(struct fb_info *info) +{ + gfbg_par *par = (gfbg_par *)(info->par); + volatile gfbg_compress_info *compress_info = TD_NULL; + gfbg_refresh_info *refresh_info = TD_NULL; + gfbg_display_info *display_info = TD_NULL; + gfbg_graphic_dcmp_info dcmp_info; + ot_fb_color_format gfbg_color_fmt; + + if (par == TD_NULL) { + return; + } + + compress_info = &par->compress_info; + refresh_info = &par->refresh_info; + display_info = &par->display_info; + + if ((refresh_info->screen_addr == 0) || (refresh_info->gb_screen_addr == 0)) { + /* close the dcmp */ + g_drv_ops.gfbg_drv_enable_dcmp(par->layer_id, TD_FALSE); + gfbg_warning("Compression is opened, but compressed buffer phyaddr for refreshing is NULL(0)\n"); + return; + } + + /* + * Decompressing information from compressed information: compression channels AR, GB address, and its size size0, + * size1 + */ + gfbg_color_fmt = refresh_info->user_buffer.canvas.format; + switch (gfbg_color_fmt) { + case OT_FB_FORMAT_ARGB4444: + dcmp_info.pixel_fmt = GFBG_INPUTFMT_ARGB_4444; + break; + case OT_FB_FORMAT_ARGB1555: + dcmp_info.pixel_fmt = GFBG_INPUTFMT_ARGB_1555; + break; + case OT_FB_FORMAT_ARGB8888: + dcmp_info.pixel_fmt = GFBG_INPUTFMT_ARGB_8888; + break; + default: + gfbg_error("Pixel format(%d) is invalid!\n", gfbg_color_fmt); + return; + } + dcmp_info.ar_phy_addr = gfbg_drv_get_dcmp_offset_addr(refresh_info->screen_addr); + dcmp_info.gb_phy_addr = gfbg_drv_get_dcmp_offset_addr(refresh_info->gb_screen_addr); + dcmp_info.width = display_info->display_width; + dcmp_info.height = display_info->display_height; + + dcmp_info.frame_size0 = compress_info->frame_size0; + dcmp_info.frame_size1 = compress_info->frame_size1; + dcmp_info.is_lossless_a = TD_FALSE; /* Whether lossless,FALSE:Lossy,TRUE:lossless */ + dcmp_info.is_lossless = TD_FALSE; /* Whether lossless,FALSE:Lossy,TRUE:lossless */ + + /* Decompressing information to drv level */ + if (g_drv_ops.gfbg_drv_set_dcmp_info(par->layer_id, &dcmp_info) != TD_SUCCESS) { + /* close dcmp */ + g_drv_ops.gfbg_drv_enable_dcmp(par->layer_id, TD_FALSE); + } +#ifdef CONFIG_COMPRESS_ECONOMIZE_MEMERY + /* for compress, we should replace the stride */ + info->fix.line_length = dcmp_info.stride; +#endif +} + +static int gfbg_interrupt_route(td_s32 irq, td_void *dev_id); + +static td_s32 drv_gfbg_alloc_cmap(td_u32 layer_id) +{ + const td_u32 cmap_len = 256; + struct fb_info *info = g_layer[layer_id].info; + + if (info == TD_NULL) { + gfbg_error("drv_gfbg_alloc_cmap failed\n"); + return TD_FAILURE; + } + + if (g_drv_ops.capability[layer_id].is_cmap != TD_TRUE) { + return TD_FAILURE; + } + + if (fb_alloc_cmap(&info->cmap, cmap_len, 1) < 0) { + info->cmap.len = 0; + gfbg_error("fb_alloc_cmap failed\n"); + return TD_FAILURE; + } + + info->cmap.len = cmap_len; + + return TD_SUCCESS; +} + +static td_void drv_gfbg_free_cmap(td_u32 layer_id) +{ + struct fb_cmap *cmap = NULL; + struct fb_info *info = g_layer[layer_id].info; + + if (info == TD_NULL) { + return; + } + + cmap = &info->cmap; + if (cmap->len != 0) { + fb_dealloc_cmap(cmap); + info->cmap.len = 0; + } + + return; +} + +static td_void fb_increase_open_cnt(td_void) +{ + unsigned long lock_flag; + osal_spin_lock_irqsave(&g_gfbg_vdp_state_count_lock, &lock_flag); + g_gfbg_open_layer_count++; + osal_spin_unlock_irqrestore(&g_gfbg_vdp_state_count_lock, &lock_flag); +} + +static td_void fb_decrease_open_cnt(td_void) +{ + unsigned long lock_flag; + osal_spin_lock_irqsave(&g_gfbg_vdp_state_count_lock, &lock_flag); + g_gfbg_open_layer_count--; + osal_spin_unlock_irqrestore(&g_gfbg_vdp_state_count_lock, &lock_flag); +} + +static td_bool fb_osi_get_fb_open_state(td_void) +{ + return (g_gfbg_open_layer_count > 0) ? TD_TRUE : TD_FALSE; +} + +static td_void fb_osi_set_vdp_clk_state(td_bool enable) +{ + unsigned long lock_flag; + osal_spin_lock_irqsave(&g_gfbg_vdp_state_count_lock, &lock_flag); + g_gfbg_vdp_clk_state = enable; + osal_spin_unlock_irqrestore(&g_gfbg_vdp_state_count_lock, &lock_flag); +} + +static td_bool fb_get_vdp_clk_state(td_void) +{ + return g_gfbg_vdp_clk_state; +} + +static ot_fb_export_func g_gfbg_export_func = { + .fb_get_fb_open_state = fb_osi_get_fb_open_state, + .fb_set_vdp_clk_state = fb_osi_set_vdp_clk_state, +}; + +static td_s32 gfbg_cmpi_init(td_void *args) +{ + ot_unused(args); + return 0; +} +static td_void gfbg_cmpi_exit(td_void) +{ + return; +} +static td_void gfbg_cmpi_notify(mod_notice_id notice) +{ + ot_unused(notice); + return; +} +static td_void gfbg_cmpi_query_state(mod_state *state) +{ + if (state == TD_NULL) { + return; + } + *state = MOD_STATE_FREE; + return; +} +static td_u32 gfbg_cmpi_get_ver_magic(td_void) +{ + return VERSION_MAGIC; +} +static umap_module g_gfbg_module = { + .mod_id = OT_ID_FB, + .mod_name = "gfbg", + .pfn_init = gfbg_cmpi_init, + .pfn_exit = gfbg_cmpi_exit, + .pfn_query_state = gfbg_cmpi_query_state, + .pfn_notify = gfbg_cmpi_notify, + .pfn_ver_checker = gfbg_cmpi_get_ver_magic, + .export_funcs = &g_gfbg_export_func, + .data = TD_NULL, +}; + +static td_s32 gfbg_register(td_u32 index) +{ +#ifdef CONFIG_OT_PROC_SHOW_SUPPORT + const td_char *entry_name[5] = { /* 5 max */ + "gfbg0", + "gfbg1", + "gfbg2", + "gfbg3", + "gfbg4" + }; +#endif + td_s32 ret; + ret = gfbg_overlay_probe(index); + if (ret != TD_SUCCESS) { + return TD_FAILURE; + } + + ret = drv_gfbg_alloc_cmap(index); + if (ret != TD_SUCCESS) { + /* clean up over layer */ + gfbg_overlay_cleanup(index, TD_TRUE); + return TD_FAILURE; + } + + /* create a proc entry in 'gfbg' for the layer */ + gfbg_proc_add_module(entry_name[index], gfbg_read_proc, gfbg_write_proc, TD_NULL, g_layer[index].info); + + return TD_SUCCESS; +} + +static td_void gfbg_unregister(td_u32 index) +{ +#ifdef CONFIG_OT_PROC_SHOW_SUPPORT + const td_char *entry_name[5] = { /* 5 max */ + "gfbg0", + "gfbg1", + "gfbg2", + "gfbg3", + "gfbg4" + }; +#endif + if (g_drv_ops.capability[index].is_layer_support == TD_FALSE) { + return; + } + drv_gfbg_free_cmap(index); +#ifdef CONFIG_OT_PROC_SHOW_SUPPORT + /* destroy a proc entry in 'gfbg' for the layer */ + gfbg_proc_remove_module(entry_name[index]); +#endif + /* unregister the layer */ + gfbg_overlay_cleanup(index, TD_TRUE); + + return; +} + +static td_s32 gfbg_init_register(td_void) +{ + td_s32 i, j; +#ifdef CONFIG_OT_PROC_SHOW_SUPPORT + gfbg_proc_init(); +#endif + /* initialize fb file according the config */ + for (i = 0; i < g_drv_ops.layer_count; i++) { + if (g_drv_ops.capability[i].is_layer_support == TD_FALSE) { + continue; + } + + if (gfbg_register(i) != TD_SUCCESS) { + for (j = i - 1; j >= 0; j--) { + gfbg_unregister(j); + } + osal_printk("ERROR: Load gfbg.ko ....FAILED!\n"); + return TD_FAILURE; + } + } + return TD_SUCCESS; +} + +static td_void gfbg_deinit_register(td_void) +{ + td_u32 i; + + for (i = 0; i < g_drv_ops.layer_count; i++) { + gfbg_unregister(i); + } + return; +} + +static td_void gfbg_deinit_process(td_void) +{ + g_drv_ops.gfbg_drv_deinit(); + + gfbg_drv_set_tde_callback(TD_NULL); + gfbg_drv_set_tde_rotate_callback(TD_NULL); + return; +} + +static td_s32 gfbg_init_process(td_void) +{ + /* initial adoption layer */ + if (g_drv_ops.gfbg_drv_init() != TD_SUCCESS) { + gfbg_error("drv init failed\n"); + return TD_FAILURE; + } + + /* register rotation */ + gfbg_rotation_register(); + + gfbg_drv_set_tde_callback(gfbg_tde_callback); + gfbg_drv_set_tde_rotate_callback(gfbg_tde_rotate_callback); + + return TD_SUCCESS; +} + +#ifdef __LITEOS__ +td_s32 gfbg_init(td_void* args) +{ + if (gfbg_get_module_para(args) != TD_SUCCESS) { + return TD_FAILURE; + } + + /* get the chip operation method */ + gfbg_drv_get_ops(&g_drv_ops); + if (cmpi_register_module(&g_gfbg_module)) { + gfbg_error("cmpi_register_module for Gfbg failure!\n"); + return TD_FAILURE; + } + + /* parse the \arg video && g_softcursor && display string */ + if (gfbg_parse_cfg() < 0) { + gfbg_error("Usage: insmod gfbg.ko video=\"gfbg: vrami_size:xxx,vramj_size: xxx, ...\"\n"); + gfbg_error("i, j means layer id, xxx means layer size in kbytes!\n"); + gfbg_error("example: insmod gfbg.ko video=\"gfbg: vram0_size: 810, vram1_size: 810\"\n\n"); + goto ERR0; + } + + /* initialize fb file according the config */ + if (gfbg_init_register() != TD_SUCCESS) { + goto ERR0; + } + + /* open vo and initial layer */ + if (gfbg_init_process() != TD_SUCCESS) { + goto ERR1; + } + + /* show version */ + gfbg_version(); + + osal_printk("load gfbg.ko ....OK!\n"); + + return TD_SUCCESS; + +ERR1: + /* do with gfbg init err1 */ + gfbg_deinit_register(); +ERR0: + cmpi_unregister_module(OT_ID_FB); + return TD_FAILURE; +} +#else +td_s32 gfbg_init(td_void) +{ + if (ckfn_sys_entry() == TD_FALSE) { + gfbg_error("no sys ko!\n"); + return TD_FAILURE; + } + + /* get the chip operation method */ + gfbg_drv_get_ops(&g_drv_ops); + + if (cmpi_register_module(&g_gfbg_module)) { + gfbg_error("cmpi_register_module for Gfbg failure!\n"); + g_gfbg_register = TD_FALSE; + return TD_FAILURE; + } + + /* parse the \arg video && g_softcursor && display string */ + if (gfbg_parse_cfg() < 0) { + gfbg_error("Usage: insmod gfbg.ko video=\"gfbg: vrami_size:xxx, vramj_size:xxx, ...\"\n"); + gfbg_error("i, j means layer id, xxx means layer size in kbytes!\n"); + osal_printk("ERROR: Load gfbg.ko ....FAILED!\n"); + goto err0; + } + + /* initialize fb file according the config */ + if (gfbg_init_register() != TD_SUCCESS) { + goto err0; + } + + /* open vo and initial layer */ + if (gfbg_init_process() != TD_SUCCESS) { + goto err1; + } + + /* + * Interrupt registration interrupt is placed at the end. + * Since the interrupt will be opened in the boot screen, + * it will respond when loading ko, and the context is used in the interrupt. + */ + if (osal_irq_request(*(fb_get_gfbg_irq()), gfbg_interrupt_route, TD_NULL, "GFBG Int", gfbg_interrupt_route)) { + gfbg_error("request_irq for Gfbg failure!\n"); + goto err2; + } + + /* show version */ + gfbg_version(); + osal_printk("load gfbg.ko ....OK!\n"); + + return TD_SUCCESS; + +err2: + gfbg_deinit_process(); +err1: + gfbg_deinit_register(); +err0: + cmpi_unregister_module(OT_ID_FB); + g_gfbg_register = TD_FALSE; + osal_printk("ERROR: Load gfbg.ko ....FAILED!\n"); + return TD_FAILURE; +} +#endif + +td_void gfbg_cleanup(td_void) +{ + if (g_gfbg_register) { + osal_irq_free(*(fb_get_gfbg_irq()), gfbg_interrupt_route); + gfbg_deinit_process(); + gfbg_deinit_register(); + } + cmpi_unregister_module(OT_ID_FB); + osal_printk("unload gfbg.ko ....OK!\n"); + return; +} + +static td_s32 gfbg_interrupt(td_void) +{ + td_u32 int_status = 0; + ot_vo_dev vo_dev = VO_INVALID_DEV; + td_s32 i; + struct fb_info *info = TD_NULL; + gfbg_par *par = TD_NULL; + td_u32 vtthd_flag = 0x0; + td_u32 frm_start_flag = 0x0; + + g_drv_ops.gfbg_drv_graphics_get_int(&int_status); + /* + * GFBG_DRV_GraphicsClearINTStatus will clear all reported interrupts. + * If devices' interrupt are reported at the same time, + * Will cause only one device to be processed, the interruption of other devices is ignored, + * so it cannot be cleared here. + * All reported interrupts can only be cleared one by one in GFBG_DRV_GraphicsGetINTDev + */ + gfbg_debug("intstatus : %d\n", int_status); + if (g_drv_ops.gfbg_drv_graphics_get_int_dev(int_status, &vo_dev) != TD_SUCCESS) { + return OSAL_IRQ_HANDLED; + } + + if (vo_dev == VO_INVALID_DEV) { + gfbg_error("unknown dev:%d \n", vo_dev); + return OSAL_IRQ_HANDLED; + } + + /* Handling all graphics layers on this device */ + for (i = 0; i < GFBG_MAX_LAYER_NUM; i++) { + if (g_drv_ops.capability[i].is_layer_support == TD_FALSE) { + continue; + } + info = g_layer[i].info; + par = (gfbg_par *)(info->par); + /* If the layer is not open, do not act. if the layer is bound to the device. */ + if ((par->layer_open == TD_FALSE) || (vo_dev != graphic_drv_get_bind_dev(i))) { + continue; + } + + if (vo_dev == VO_DEV_DHD0) { + vtthd_flag = GFBG_INTMSK_HD0_VTTHD1; + frm_start_flag = GFBG_INTMSK_HD0_VTTHD3; + } else if (vo_dev == VO_DEV_DHD1) { + vtthd_flag = GFBG_INTMSK_HD1_VTTHD1; + frm_start_flag = GFBG_INTMSK_HD1_VTTHD3; + } else if (vo_dev == VO_DEV_DSD0) { + vtthd_flag = GFBG_INTMSK_SD0_VTTHD1; + frm_start_flag = GFBG_INTMSK_SD0_VTTHD3; + } + /* + * 1. The frame start interrupt and the vertical timing interrupt appear + * in the interrupt status register at the same time. + * Frame start interrupts and vertical timing interrupts + * are processed one by one and cannot be processed at the same time because + * interrupts are cleared one by one, and the interrupt processing order + * and the clearing order should be also consistent. + * The first clear must be processed first, then the post-cleared + * 2, as long as there is a vertical timing interrupt, it is necessary to drive the g_display + */ + if (int_status & vtthd_flag) { /* VO vertical timing interrupt */ + gfbg_debug_print_vcnt(vo_dev, "vtth1"); + par->refresh_info.do_refresh_job = TD_FALSE; + gfbg_interrupt_process(i); + } else if (int_status & frm_start_flag) { /* VO frame start interrupt */ + gfbg_debug_print_vcnt(vo_dev, "vtth3"); + par->refresh_info.do_refresh_job = TD_TRUE; + wake_up(&(par->do_refresh_job)); + } + } + return OSAL_IRQ_HANDLED; +} +static int gfbg_interrupt_route(td_s32 irq, td_void *dev_id) +{ + ot_unused(irq); + ot_unused(dev_id); + return gfbg_interrupt(); +} + +static td_s32 gfbg_open_check_param(const struct fb_info *info) +{ + gfbg_par *par = TD_NULL; + if ((info == TD_NULL) || (info->par == TD_NULL)) { + return TD_FAILURE; + } + + par = (gfbg_par *)info->par; + if (par->layer_id >= GFBG_MAX_LAYER_NUM) { + gfbg_error("layer %u is not supported!\n", par->layer_id); + return TD_FAILURE; + } + + /* assure layer is legal */ + if (!g_drv_ops.capability[par->layer_id].is_layer_support) { + gfbg_error("layer %u is not supported!\n", par->layer_id); + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +static td_bool gfbg_open_is_cursor_layer(struct fb_info *info) +{ + gfbg_par *par = TD_NULL; + td_u32 layer_id; + ot_fb_alpha alpha = { + TD_TRUE, TD_FALSE, GFBG_ALPHA_TRANSPARENT, + GFBG_ALPHA_OPAQUE, GFBG_ALPHA_OPAQUE + }; + + par = (gfbg_par *)info->par; + layer_id = par->layer_id; + + if (is_cursor_layer(par->layer_id) && is_soft_cursor()) { + if (!atomic_read(&par->ref_count)) { + (td_void)memset_s(par, sizeof(gfbg_par), 0, sizeof(gfbg_par)); + + par->layer_id = layer_id; + atomic_set(&par->ref_count, 0); + + /* Configuring alpha properties */ + gfbg_set_alpha(par, &alpha); + } + atomic_inc(&par->ref_count); + + return TD_TRUE; + } + return TD_FALSE; +} + +#ifdef __LITEOS__ +static td_s32 gfbg_open_default_param(struct fb_info *info, ot_fb_color_format *color_format) +{ + gfbg_par *par = TD_NULL; + td_u32 layer_id; + par = (gfbg_par *)info->par; + layer_id = par->layer_id; + + if (is_4k_layer(layer_id)) { + gfbg_screeninfo_init(info, &g_default_info[GFBG_LAYER_TYPE_4K]); + } else if (is_hd_layer(layer_id)) { + gfbg_screeninfo_init(info, &g_default_info[GFBG_LAYER_TYPE_HD]); + } else if (is_sd_layer(layer_id)) { + gfbg_screeninfo_init(info, &g_default_info[GFBG_LAYER_TYPE_SD]); + } else if (is_ad_layer(layer_id)) { + gfbg_screeninfo_init(info, &g_default_info[GFBG_LAYER_TYPE_AD]); + } else if (is_cursor_layer(layer_id)) { + gfbg_screeninfo_init(info, &g_default_info[GFBG_LAYER_TYPE_CURSOR]); + } else { + gfbg_error("error layer id:%u\n", par->layer_id); + } + *color_format = info->vinfo.format; + if (*color_format == OT_FB_FORMAT_BUTT) { + gfbg_error("Invalid default color format!\n"); + return TD_FAILURE; + } + + info->oinfo.stride = (info->oinfo.sarea.width * (info->oinfo.bpp >> 3) + GFBG_ALIGNMENT) & /* 8 is bits 2^3 */ + (~GFBG_ALIGNMENT); + + return TD_SUCCESS; +} +#else +static td_s32 gfbg_open_default_param(struct fb_info *info, ot_fb_color_format *color_format) +{ + gfbg_par *par = TD_NULL; + td_u32 layer_id; + struct fb_var_screeninfo *var = TD_NULL; + struct fb_fix_screeninfo *fix = TD_NULL; +#ifdef CONFIG_COMPRESS_ECONOMIZE_MEMERY + gfbg_stride_attr attr = {0}; +#endif + var = &info->var; + fix = &info->fix; + + par = (gfbg_par *)info->par; + layer_id = par->layer_id; + + if (is_4k_layer(layer_id)) { + *var = g_default_var[GFBG_LAYER_TYPE_4K]; + } else if (is_hd_layer(layer_id)) { + *var = g_default_var[GFBG_LAYER_TYPE_HD]; + } else if (is_sd_layer(layer_id)) { + *var = g_default_var[GFBG_LAYER_TYPE_SD]; + } else if (is_ad_layer(layer_id)) { + *var = g_default_var[GFBG_LAYER_TYPE_AD]; + } else if (is_cursor_layer(layer_id)) { + *var = g_default_var[GFBG_LAYER_TYPE_CURSOR]; + } else { + gfbg_error("error layer id:%u\n", par->layer_id); + } + /* transform colorfmt form bitfiled to gfbg format, and record it */ + *color_format = gfbg_getfmtbyargb(&var->red, &var->green, &var->blue, + &var->transp, var->bits_per_pixel); + if (*color_format == OT_FB_FORMAT_BUTT) { + gfbg_error("Invalid default color format!\n"); + return TD_FAILURE; + } + /* By default it is width*4 (32 bits per pixel / 8) */ +#ifdef CONFIG_COMPRESS_ECONOMIZE_MEMERY + attr.is_lossless = TD_FALSE; + attr.is_losslessa = TD_FALSE; + attr.width = var->xres_virtual; + attr.format = *color_format; + /* 3 for 8bits */ + fix->line_length = (var->xres_virtual * (var->bits_per_pixel >> 3) + GFBG_ALIGNMENT) & + (~GFBG_ALIGNMENT); + gfbg_recalculate_stride(NULL, &(fix->line_length), &attr); +#else + /* 3 for 8bits */ + fix->line_length = (var->xres_virtual * (var->bits_per_pixel >> 3) + GFBG_ALIGNMENT) & + (~GFBG_ALIGNMENT); +#endif + return TD_SUCCESS; +} +#endif + +static td_void gfbg_open_init_display(const struct fb_info *info, td_u32 layer_id, const gfbg_osd_data *osd_data) +{ + gfbg_par *par = TD_NULL; + gfbg_display_info *display_info = TD_NULL; + par = (gfbg_par *)info->par; + + (td_void)memset_s(par, sizeof(gfbg_par), 0, sizeof(gfbg_par)); + par->layer_id = layer_id; + atomic_set(&par->ref_count, 0); + + display_info = &par->display_info; + display_info->display_width = gfbg_get_xres(info); + display_info->display_height = gfbg_get_yres(info); + display_info->screen_width = gfbg_get_xres(info); + display_info->screen_height = gfbg_get_yres(info); + display_info->vir_x_res = gfbg_get_xres_virtual(info); + display_info->vir_y_res = gfbg_get_yres_virtual(info); + display_info->x_res = gfbg_get_xres(info); + display_info->y_res = gfbg_get_yres(info); + display_info->max_screen_width = osd_data->screen_width; + display_info->max_screen_height = osd_data->screen_height; + display_info->mirror_mode = OT_FB_MIRROR_NONE; + display_info->rotate_mode = OT_FB_ROTATE_NONE; + par->rotate_vb = 0; + + init_waitqueue_head(&(par->vbl_event)); + init_waitqueue_head(&(par->do_refresh_job)); + + return; +} + +static td_void gfbg_open_init_config(const struct fb_info *info, td_u32 layer_id, gfbg_osd_data *osd_data, + ot_fb_color_format color_format, gfbg_cursor_info *cursor_info) +{ + gfbg_par *par = TD_NULL; + ot_fb_alpha alpha = { + TD_TRUE, TD_FALSE, GFBG_ALPHA_TRANSPARENT, + GFBG_ALPHA_OPAQUE, GFBG_ALPHA_OPAQUE + }; + gfbg_display_info *display_info = TD_NULL; + unsigned long lock_flag; + par = (gfbg_par *)info->par; + display_info = &par->display_info; + ot_unused(cursor_info); + + osal_spin_lock_irqsave(&par->lock, &lock_flag); + gfbg_set_bufmode(par->layer_id, OT_FB_LAYER_BUF_BUTT); + gfbg_set_alpha(par, &alpha); + gfbg_set_dispbufinfo(layer_id); + gfbg_set_fmt(par, color_format); + /* Anti-flicker when interlaced */ + display_info->need_antiflicker = (osd_data->scan_mode == GFBG_SCANMODE_I) ? (TD_TRUE) : (TD_FALSE); + gfbg_set_antiflickerlevel(par->layer_id, OT_FB_LAYER_ANTIFLICKER_AUTO); + + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + g_drv_ops.gfbg_drv_layer_default_setting(layer_id); + g_drv_ops.gfbg_drv_set_layer_alpha(layer_id, par->alpha); + g_drv_ops.gfbg_drv_set_layer_data_fmt(layer_id, par->color_format); +} + +static td_void gfbg_open_init_compress(const struct fb_info *info) +{ + gfbg_par *par = TD_NULL; + volatile gfbg_compress_info *compress_info = TD_NULL; + gfbg_refresh_info *refresh_info = TD_NULL; + gfbg_display_info *display_info = TD_NULL; + ot_fb_rect rect; + td_u32 layer_id; + par = (gfbg_par *)info->par; + display_info = &par->display_info; + layer_id = par->layer_id; + compress_info = &par->compress_info; + refresh_info = &par->refresh_info; + + /* Decompression information settings */ + compress_info->new_start_section = compress_info->start_section; + compress_info->new_zone_nums = compress_info->zone_nums; + compress_info->clear_zone = TD_FALSE; + + g_drv_ops.gfbg_drv_enable_dcmp(layer_id, TD_FALSE); /* Clear decompression status */ + + rect.x = 0; + rect.y = 0; + rect.width = (td_s32)gfbg_get_xres(info); + rect.height = (td_s32)gfbg_get_yres(info); + + g_drv_ops.gfbg_drv_set_layer_rect(par->layer_id, &rect, &rect); + g_drv_ops.gfbg_drv_set_layer_src_image_reso(par->layer_id, &rect); + + g_drv_ops.gfbg_drv_set_layer_stride(par->layer_id, gfbg_get_line_length(info)); + + g_drv_ops.gfbg_drv_set_pre_mul(par->layer_id, display_info->is_premul); + if (g_drv_ops.capability[layer_id].is_key_rgb || g_drv_ops.capability[layer_id].is_key_alpha) { + g_drv_ops.gfbg_drv_set_layer_key_mask(par->layer_id, &par->ckey); + } + + /* Set to memory address */ + g_drv_ops.gfbg_drv_set_layer_addr(par->layer_id, gfbg_get_smem_start(info)); + refresh_info->screen_addr = gfbg_get_smem_start(info); + refresh_info->gb_screen_addr = 0x0; /* Clear the decompression address */ + compress_info->layer_addr_update = TD_TRUE; + + return; +} + +static td_void gfbg_open_init_finish(const struct fb_info *info) +{ + gfbg_par *par = TD_NULL; + volatile gfbg_compress_info *compress_info = TD_NULL; + unsigned long lock_flag; + + par = (gfbg_par *)info->par; + compress_info = &par->compress_info; + + osal_spin_lock_irqsave(&par->lock, &lock_flag); + + compress_info->compress_open = TD_FALSE; + compress_info->is_losslessa = TD_FALSE; + compress_info->is_lossless = TD_FALSE; + + par->modifying = TD_TRUE; + gfbg_set_show(par, TD_TRUE); + par->param_modify_mask = GFBG_LAYER_PARAMODIFY_SHOW; + par->modifying = TD_FALSE; + par->layer_open = TD_TRUE; + + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + + /* enable layer for vo to decide config csc or not */ + g_drv_ops.gfbg_drv_set_layer_enable(par->layer_id, TD_TRUE); + + return; +} + +static td_void gfbg_open_init_information(const struct fb_info *info, td_u32 layer_id, gfbg_osd_data *osd_data, + ot_fb_color_format color_format, gfbg_cursor_info *cursor_info) +{ + /* gfbg set bufmode\alpha\displaybufinfo\fmt */ + gfbg_open_init_config(info, layer_id, osd_data, color_format, cursor_info); + + /* gfbg compress init */ + gfbg_open_init_compress(info); + + /* gfbg set callback and init finish */ + gfbg_open_init_finish(info); + + return; +} + +static td_s32 gfbg_open_start(struct fb_info *info) +{ + gfbg_par *par = TD_NULL; + gfbg_cursor_info cursor_info; + gfbg_osd_data osd_data = {0}; + td_u32 layer_id; + ot_fb_color_format color_format; + + par = (gfbg_par *)info->par; + layer_id = par->layer_id; + if (layer_id >= GFBG_MAX_LAYER_NUM) { + gfbg_error("layer_id is [%u] and more than max[%u]\n", layer_id, GFBG_MAX_LAYER_NUM); + return TD_FAILURE; + } + + if (!atomic_read(&par->ref_count)) { + fb_increase_open_cnt(); + if (fb_get_vdp_clk_state() != TD_TRUE) { + fb_decrease_open_cnt(); + gfbg_error("vo apb clk is close!\n"); + return TD_FAILURE; + } + fb_graphics_init(); + if (graphic_drv_dev_gfbg_int_enable(layer_id, TD_TRUE) != TD_SUCCESS) { + fb_decrease_open_cnt(); + gfbg_error("set graphic layer %u# vointmsk failed!\n", layer_id); + return TD_FAILURE; + } + + (td_void)memset_s(&cursor_info, sizeof(gfbg_cursor_info), 0, sizeof(gfbg_cursor_info)); + if (g_drv_ops.gfbg_drv_get_osd_data(layer_id, &osd_data) != TD_SUCCESS) { + fb_decrease_open_cnt(); + gfbg_error("Failed to get osd data!\n"); + return TD_FAILURE; + } + + /* Configure the layer's default variable parameter var_info according to the type of layer */ + if (g_drv_ops.gfbg_open_layer(layer_id) != TD_SUCCESS) { + fb_decrease_open_cnt(); + gfbg_error("Open graphic layer %u# failed!\n", layer_id); + return TD_FAILURE; + } + + /* get default var and fix */ + if (gfbg_open_default_param(info, &color_format) != TD_SUCCESS) { + fb_decrease_open_cnt(); + return TD_FAILURE; + } + + /* Initialize the display information in private data */ + gfbg_open_init_display(info, layer_id, &osd_data); + + /* Initialization lock */ + if (osal_spin_lock_init(&par->lock) != TD_SUCCESS) { + fb_decrease_open_cnt(); + return TD_FAILURE; + } + + gfbg_open_init_information(info, layer_id, &osd_data, color_format, &cursor_info); + } + return TD_SUCCESS; +} + +/* + * Function : gfbg_open + * Description : open the framebuffer and using the default parameter to set the layer + struct fb_info *info + * Return : return 0 + */ +#ifdef __LITEOS__ +void *g_gfbg_info_ptr = TD_NULL; +static td_s32 gfbg_open(struct fb_vtable_s *vtable) +#else +static td_s32 gfbg_open(struct fb_info *info, td_s32 user) +#endif +{ +#ifdef __LITEOS__ + struct gfbg_info *info = (struct gfbg_info *)vtable; +#endif + gfbg_par *par = TD_NULL; + ot_unused(user); + + /* check input param */ + if (gfbg_open_check_param(info) != TD_SUCCESS) { + return TD_FAILURE; + } + par = (gfbg_par *)info->par; + /* check layer is cursor and is soft cursor */ + if (gfbg_open_is_cursor_layer(info) == TD_TRUE) { + return TD_SUCCESS; + } + + /* open the layer first */ + if (gfbg_open_start(info) != TD_SUCCESS) { + return TD_FAILURE; + } + + /* increase reference count */ + atomic_inc(&par->ref_count); +#ifdef __LITEOS__ + g_gfbg_info_ptr = (void *)info; +#endif + return TD_SUCCESS; +} + +/* + * Function : gfbg_release + * Description : open the framebuffer and disable the layer + struct fb_info *info + * Return : return 0 if succeed, otherwise return -EINVAL + */ +static td_void gfbg_release_info(gfbg_par *par) +{ + td_u32 layer_id; + unsigned long lock_flag; + + if ((g_drv_ops.gfbg_drv_set_layer_enable == TD_NULL) || (g_drv_ops.gfbg_drv_updata_layer_reg == TD_NULL) || + (g_drv_ops.gfbg_drv_set_int_callback == TD_NULL) || (g_drv_ops.gfbg_close_smart_rect == TD_NULL) || + (g_drv_ops.gfbg_close_layer == TD_NULL)) { + gfbg_error("gfbg_release_info failed!\n"); + return; + } + + osal_spin_lock_irqsave(&par->lock, &lock_flag); + layer_id = par->layer_id; + gfbg_set_show(par, TD_FALSE); + + if ((!is_cursor_layer(par->layer_id)) || (!is_soft_cursor())) { + /* disable the compress */ + if (par->compress_info.compress_open) { + /* No memory alloc, no need to release */ + par->compress_info.compress_open = TD_FALSE; + par->compress_info.is_losslessa = TD_FALSE; + par->compress_info.is_lossless = TD_FALSE; + } + + /* clear wbc interrupt when close fb */ + g_drv_ops.gfbg_drv_set_layer_enable(par->layer_id, TD_FALSE); + g_drv_ops.gfbg_drv_updata_layer_reg(par->layer_id); + + /* vo has spin lock, you need to release the spin lock first */ + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + g_drv_ops.gfbg_drv_set_int_callback(GFBG_INTTYPE_VO, TD_NULL, layer_id, TD_NULL); + osal_spin_lock_irqsave(&par->lock, &lock_flag); + + g_drv_ops.gfbg_close_smart_rect(par->layer_id); + g_drv_ops.gfbg_close_layer(par->layer_id); + + par->compress_info.start_section = 0; + par->compress_info.zone_nums = 0; + par->compress_info.new_start_section = 0; + par->compress_info.new_zone_nums = 0; + par->compress_info.clear_zone = TD_TRUE; + + /* MMzFree in gfbg_freeccanbuf has a sleep function call, you need to release the spin lock first. */ + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + gfbg_freeccanbuf(par); + osal_spin_lock_irqsave(&par->lock, &lock_flag); + } + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); +} + +static td_void gfbg_set_dev_int_enable(gfbg_par *par) +{ +#if defined(DCONFIG_CHIP_GFBG_SUPPORT_G3) && !defined(__LITEOS__) + ot_vo_dev dev; + struct fb_info *info = TD_NULL; + gfbg_par *par_layer = TD_NULL; + info = g_layer[2].info; /* 2 G2 */ + par_layer = (gfbg_par *)(info->par); + if (par_layer->layer_open == TD_TRUE) { + dev = graphic_drv_get_bind_dev(par_layer->layer_id); + if (dev == VO_DEV_DHD0) { + info = g_layer[0].info; /* 0 G0 */ + par_layer = (gfbg_par *)(info->par); + if (par_layer->layer_open == TD_TRUE) { + return; + } + } else { + info = g_layer[1].info; /* 1 G1 */ + par_layer = (gfbg_par *)(info->par); + if (par_layer->layer_open == TD_TRUE) { + return; + } + } + } +#endif + graphic_drv_dev_gfbg_int_enable(par->layer_id, TD_FALSE); +} + +static td_s32 gfbg_release(struct fb_info *info, td_s32 user) +{ + gfbg_par *par = TD_NULL; + td_u32 mem_len; + td_s8 *screen_base = TD_NULL; + ot_unused(user); + + if (info == TD_NULL) { + return TD_FAILURE; + } + if (info->par == TD_NULL) { + return TD_FAILURE; + } + par = (gfbg_par *)info->par; + + if (atomic_dec_and_test(&par->ref_count)) { + gfbg_release_info(par); + gfbg_set_dev_int_enable(par); + + screen_base = gfbg_get_screen_base(info); + mem_len = gfbg_get_smem_len(info); + if ((screen_base != TD_NULL) && (mem_len != 0)) { + (td_void)memset_s(screen_base, mem_len, 0, mem_len); + } + fb_graphics_deinit(); + par->layer_open = TD_FALSE; + par->refresh_info.do_refresh_job = TD_FALSE; + wait_event_timeout(par->do_refresh_job, par->refresh_info.do_refresh_job, + (td_s32)msecs_to_jiffies(40)); /* 40 for timeout */ + osal_spin_lock_destroy(&par->lock); + fb_decrease_open_cnt(); + } + + return 0; +} + +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC +static td_s32 gfbg_draw_smart_rect(const struct fb_info *info, const ot_fb_smart_rect_param *param) +{ + gfbg_mmz_buffer osb_chn = {0}; + gfbg_par *par = (gfbg_par *)info->par; + + osb_chn.start_phy_addr = gfbg_get_smem_start(info); + osb_chn.start_vir_addr = gfbg_get_screen_base(info); + osb_chn.size = SMART_RECT_SIZE; + if (g_drv_ops.gfbg_drv_set_smart_rect == TD_NULL || par == TD_NULL) { + gfbg_error("gfbg_draw_smart_rect failed!\n"); + return TD_FAILURE; + } + if (g_drv_ops.gfbg_drv_set_smart_rect(par->layer_id, par->display_info.x_res, + par->display_info.y_res, param, &osb_chn) != TD_SUCCESS) { + return TD_FAILURE; + } + return TD_SUCCESS; +} +#endif + +static td_s32 gfbg_ioctl_check_param(const struct fb_info *info, td_u32 cmd, td_void *argp) +{ + gfbg_par *par = TD_NULL; + td_u32 layer_id; + + if ((info == TD_NULL) || (info->par == TD_NULL)) { + gfbg_error("NULL arg!\n"); + return TD_FAILURE; + } + par = (gfbg_par *)info->par; + layer_id = par->layer_id; + if (layer_id >= GFBG_MAX_LAYER_NUM) { + gfbg_error("layer_id (%u) is invalid!\n", layer_id); + return TD_FAILURE; + } + + if ((argp == TD_NULL) && (cmd != FBIOGET_VER_BLANK_GFBG) && (cmd != FBIO_WAITFOR_FREFRESH_DONE) && + (cmd != FBIO_CREATE_LAYER) && (cmd != FBIO_DESTROY_LAYER)) { + gfbg_error("NULL arg!\n"); + return TD_FAILURE; + } + + if ((!g_drv_ops.capability[layer_id].is_layer_support) && + (!is_cursor_layer(layer_id) || (!is_soft_cursor()))) { + gfbg_error("not support layer %u!\n", layer_id); + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +static td_s32 drv_gfbg_get_colorkey(struct fb_info *info, unsigned long arg) +{ + ot_fb_colorkey colorkey = {0}; + gfbg_colorkeyex colorkey_ex = {0}; + gfbg_par *par = TD_NULL; + par = (gfbg_par *)info->par; + + if ((!g_drv_ops.capability[par->layer_id].is_key_rgb) && + (!g_drv_ops.capability[par->layer_id].is_key_alpha)) { + gfbg_error("Layer %u doesn't support colorkey!\n", par->layer_id); + return TD_FAILURE; + } + + gfbg_get_key(par, &colorkey_ex); + + colorkey.enable = colorkey_ex.key_enable; + colorkey.value = colorkey_ex.key; + + return osal_copy_to_user((td_void __user *)(td_uintptr_t)arg, &colorkey, sizeof(ot_fb_colorkey)); +} + +static td_s32 drv_gfbg_set_clut_ck(const struct fb_info *info, const ot_fb_colorkey *colorkey, + gfbg_colorkeyex *colorkey_ex) +{ + if (colorkey->value >= (td_u32)(1 << gfbg_get_bits_per_pixel(info))) { + gfbg_error("The value :%u is out of range the palette: %u!\n", colorkey->value, + 1 << gfbg_get_bits_per_pixel(info)); + return TD_FAILURE; + } + + if ((info->cmap.blue == NULL) || (info->cmap.green == NULL) || (info->cmap.red == NULL)) { + gfbg_error("error:cmap is NULL!\n"); + return TD_FAILURE; + } + + colorkey_ex->blue_max = colorkey_ex->blue_min = info->cmap.blue[colorkey->value]; + colorkey_ex->green_max = colorkey_ex->green_min = info->cmap.green[colorkey->value]; + colorkey_ex->red_max = colorkey_ex->red_min = info->cmap.red[colorkey->value]; + colorkey_ex->red_mask = 0xff; + colorkey_ex->green_mask = 0xff; + colorkey_ex->blue_mask = 0xff; + colorkey_ex->key_mode = 0; + colorkey_ex->mask_enable = TD_TRUE; + return TD_SUCCESS; +} + +static td_s32 drv_gfbg_set_colorkey(struct fb_info *info, unsigned long arg) +{ + ot_fb_colorkey colorkey; + gfbg_colorkeyex colorkey_ex; + unsigned long lock_flag; + gfbg_par *par = (gfbg_par *)info->par; + gfbg_display_info *display_info = &par->display_info; + + if (osal_copy_from_user(&colorkey, (td_void __user *)(td_uintptr_t)arg, sizeof(ot_fb_colorkey))) { + return -EFAULT; + } + + if ((colorkey.enable != TD_TRUE) && (colorkey.enable != TD_FALSE)) { + gfbg_error("enable(%d) should be TRUE or FALSE!\n", colorkey.enable); + return TD_FAILURE; + } + + if ((!g_drv_ops.capability[par->layer_id].is_key_rgb) && (!g_drv_ops.capability[par->layer_id].is_key_alpha)) { + gfbg_error("Layer %u doesn't support colorkey!\n", par->layer_id); + return TD_FAILURE; + } + + if (colorkey.enable && display_info->is_premul) { + gfbg_error("colorkey and premul couldn't take effect at the same time!\n"); + return TD_FAILURE; + } + + colorkey_ex.key = colorkey.value; + colorkey_ex.key_enable = colorkey.enable; + + if (gfbg_get_bits_per_pixel(info) <= 8) { /* 8 bits */ + if (drv_gfbg_set_clut_ck(info, &colorkey, &colorkey_ex) != TD_SUCCESS) { + return TD_FAILURE; + } + } else { + if (g_drv_ops.gfbg_drv_color_convert == TD_NULL) { + return TD_FAILURE; + } +#ifdef __LITEOS__ + g_drv_ops.gfbg_drv_color_convert(info, &colorkey_ex); +#else + g_drv_ops.gfbg_drv_color_convert(&info->var, &colorkey_ex); +#endif + } + + osal_spin_lock_irqsave(&par->lock, &lock_flag); + par->modifying = TD_TRUE; + gfbg_set_key(par, &colorkey_ex); + par->param_modify_mask |= GFBG_LAYER_PARAMODIFY_COLORKEY; + par->modifying = TD_FALSE; + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + return TD_SUCCESS; +} + +static td_s32 drv_gfbg_get_layer_alpha(struct fb_info *info, unsigned long arg) +{ + gfbg_par *par = TD_NULL; + ot_fb_alpha alpha = {0}; + + par = (gfbg_par *)info->par; + gfbg_get_alpha(par, &alpha); + return osal_copy_to_user((td_void __user *)(td_uintptr_t)arg, &alpha, sizeof(ot_fb_alpha)); +} + +static td_s32 drv_gfbg_set_layer_alpha(struct fb_info *info, unsigned long arg) +{ + gfbg_par *par = TD_NULL; + unsigned long lock_flag; + ot_fb_alpha alpha = {0}; + + par = (gfbg_par *)info->par; + if (osal_copy_from_user(&alpha, (td_void __user *)(td_uintptr_t)arg, sizeof(ot_fb_alpha))) { + return -EFAULT; + } + + if ((alpha.pixel_alpha != TD_TRUE) && (alpha.pixel_alpha != TD_FALSE)) { + gfbg_error("alpha->pixel_alpha should be TRUE or FALSE!\n"); + return TD_FAILURE; + } + + if ((alpha.global_alpha_en != TD_TRUE) && (alpha.global_alpha_en != TD_FALSE)) { + gfbg_error("alpha->global_alpha_en should be TRUE or FALSE!\n"); + return TD_FAILURE; + } + osal_spin_lock_irqsave(&par->lock, &lock_flag); + par->modifying = TD_TRUE; + gfbg_set_alpha(par, &alpha); + par->param_modify_mask |= GFBG_LAYER_PARAMODIFY_ALPHA; + + par->modifying = TD_FALSE; + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + return TD_SUCCESS; +} + +static td_s32 drv_gfbg_get_screen_origin_pos(struct fb_info *info, unsigned long arg) +{ + gfbg_par *par = TD_NULL; + + ot_fb_point pos = {0}; + + par = (gfbg_par *)info->par; + gfbg_get_layerpos(par, &pos); + + return osal_copy_to_user((td_void __user *)(td_uintptr_t)arg, &pos, sizeof(ot_fb_point)); +} + +static td_s32 drv_gfbg_set_screen_origin_pos(struct fb_info *info, unsigned long arg) +{ + gfbg_par *par = TD_NULL; + ot_fb_point expected_pos; + td_u32 layer_id; + unsigned long lock_flag; + td_bool is_interlace; + par = (gfbg_par *)info->par; + layer_id = par->layer_id; + is_interlace = gfbg_is_interlace(par); + + if (is_cursor_layer(layer_id) && is_soft_cursor()) { + gfbg_error("you shouldn't set soft cursor origin by this cmd, try FBIOPUT_CURSOR_POS\n"); + return TD_FAILURE; + } + + if (osal_copy_from_user(&expected_pos, (td_void __user *)(td_uintptr_t)arg, sizeof(ot_fb_point))) { + return -EFAULT; + } + + if (expected_pos.x_pos < 0 || expected_pos.y_pos < 0) { + gfbg_error("It's not supported to set start pos of layer to negative!\n"); + return TD_FAILURE; + } + + if (is_interlace && (expected_pos.y_pos % 2 != 0)) { /* 2 alg data */ + gfbg_error("y_pos should be even for interlace vodev!\n"); + return TD_FAILURE; + } + + osal_spin_lock_irqsave(&par->lock, &lock_flag); + par->modifying = TD_TRUE; + + /* Record the old location first */ + gfbg_set_layerpos(par, &expected_pos); + par->modifying = TD_FALSE; + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + + return TD_SUCCESS; +} + +static td_s32 drv_gfbg_get_vblank(struct fb_info *info, unsigned long arg) +{ + gfbg_par *par = TD_NULL; + par = (gfbg_par *)info->par; + ot_unused(arg); + if (gfbg_wait_regconfig_work(par->layer_id)) { + gfbg_error("It is not support VBL!\n"); + return -EPERM; + } + + return TD_SUCCESS; +} + +static td_s32 drv_gfbg_show_layer(struct fb_info *info, unsigned long arg) +{ + gfbg_par *par = TD_NULL; + td_bool is_show = TD_FALSE; + unsigned long lock_flag; + td_u32 layer_id; + + par = (gfbg_par *)info->par; + layer_id = par->layer_id; + if (is_cursor_layer(layer_id) && is_soft_cursor()) { + gfbg_error("you shouldn't show sot cursor by this cmd, try FBIOPUT_CURSOR_STATE!\n"); + return TD_FAILURE; + } + + if (osal_copy_from_user(&is_show, (td_void __user *)(td_uintptr_t)arg, sizeof(td_bool))) { + return -EFAULT; + } + + if ((is_show != TD_TRUE) && (is_show != TD_FALSE)) { + gfbg_error("show(%d) should be TRUE or FALSE!\n", is_show); + return TD_FAILURE; + } + + if (is_show == gfbg_get_show(par)) { + gfbg_info("The layer is show(%d) now!\n", par->show); + return TD_SUCCESS; + } + + osal_spin_lock_irqsave(&par->lock, &lock_flag); + par->modifying = TD_TRUE; + + gfbg_set_show(par, is_show); + par->param_modify_mask |= GFBG_LAYER_PARAMODIFY_SHOW; + + par->modifying = TD_FALSE; + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + + return TD_SUCCESS; +} + +static td_s32 drv_gfbg_get_layer_show_state(struct fb_info *info, unsigned long arg) +{ + gfbg_par *par = TD_NULL; + td_bool is_show; + par = (gfbg_par *)info->par; + is_show = par->show; + return osal_copy_to_user((td_void __user *)(td_uintptr_t)arg, &is_show, sizeof(td_bool)); +} + + +static td_s32 drv_gfbg_get_capability(struct fb_info *info, unsigned long arg) +{ + gfbg_par *par = TD_NULL; + ot_fb_capability capability = {0}; + + par = (gfbg_par *)info->par; + capability = g_drv_ops.capability[par->layer_id]; + return osal_copy_to_user((td_void __user *)(td_uintptr_t)arg, (td_void *)&capability, sizeof(ot_fb_capability)); +} + +static td_s32 drv_gfbg_set_layer_info(struct fb_info *info, unsigned long arg) +{ + gfbg_par *par = TD_NULL; + + par = (gfbg_par *)info->par; + return gfbg_onputlayerinfo(info, par, (td_void __user *)(td_uintptr_t)arg); +} + +static td_s32 drv_gfbg_get_layer_info(struct fb_info *info, unsigned long arg) +{ + gfbg_par *par = TD_NULL; + ot_fb_layer_info layer_info = {0}; + par = (gfbg_par *)info->par; + gfbg_get_layerinfo(par, &layer_info); + return osal_copy_to_user((td_void __user *)(td_uintptr_t)arg, &layer_info, sizeof(ot_fb_layer_info)); +} + +static td_s32 drv_gfbg_get_canvas_buffer(struct fb_info *info, unsigned long arg) +{ + td_s32 ret; + gfbg_par *par = TD_NULL; + ot_fb_buf buf = {0}; + gfbg_refresh_info *refresh_info = TD_NULL; + par = (gfbg_par *)info->par; + refresh_info = &par->refresh_info; + if (!osal_in_interrupt()) { + ret = ot_mmz_check_phys_addr(par->canvas_sur.phys_addr, par->canvas_sur.pitch * par->canvas_sur.height); + if (ret != TD_SUCCESS) { + gfbg_error("Failed to Physical address(0x%lx) process isolation check !\n", + (td_ulong)par->canvas_sur.phys_addr); + return TD_FAILURE; + } + } + ret = memcpy_s(&(buf.canvas), sizeof(ot_fb_surface), &(par->canvas_sur), sizeof(ot_fb_surface)); + gfbg_unequal_eok_return(ret); + ret = memcpy_s(&(buf.update_rect), sizeof(ot_fb_rect), &(refresh_info->user_buffer.update_rect), + sizeof(ot_fb_rect)); + gfbg_unequal_eok_return(ret); + if (osal_copy_to_user((td_void __user *)(td_uintptr_t)arg, &(buf), sizeof(ot_fb_buf))) { + return -EFAULT; + } + return TD_SUCCESS; +} + +static td_s32 drv_gfbg_refresh_layer(struct fb_info *info, unsigned long arg) +{ + gfbg_par *par = TD_NULL; + par = (gfbg_par *)info->par; + return gfbg_onrefresh(par, (td_void __user *)(td_uintptr_t)arg); +} + +static td_s32 drv_gfbg_wait_refresh_finish(struct fb_info *info, unsigned long arg) +{ + gfbg_par *par = TD_NULL; + ot_fb_layer_buf buf_mode; + par = (gfbg_par *)info->par; + ot_unused(arg); + gfbg_get_bufmode(par, &buf_mode); + if ((buf_mode != OT_FB_LAYER_BUF_NONE) && (buf_mode != OT_FB_LAYER_BUF_BUTT)) { + /* 80 is timeout */ + if (wait_event_timeout(par->vbl_event, par->vblflag, (td_s32)osal_msecs_to_jiffies(80)) == 0) { + return TD_FAILURE; + } + } else { + gfbg_error("doesn't support FBIO_WAITFOR_FREFRESH_DONE operation when in standard mode" + "or FB_LAYER_BUF_NONE!\n"); + return TD_FAILURE; + } + return TD_SUCCESS; +} + +static td_s32 drv_gfbg_set_mirror_mode(struct fb_info *info, unsigned long arg) +{ + gfbg_par *par = TD_NULL; + ot_fb_mirror_mode mirror_mode; + par = (gfbg_par *)info->par; + if (osal_copy_from_user(&mirror_mode, (td_void __user *)(td_uintptr_t)arg, sizeof(ot_fb_mirror_mode))) { + return -EFAULT; + } + if (gfbg_set_mirrormode(par, mirror_mode) != TD_SUCCESS) { + return TD_FAILURE; + } + return TD_SUCCESS; +} + +static td_s32 drv_gfbg_get_mirror_mode(struct fb_info *info, unsigned long arg) +{ + gfbg_par *par = TD_NULL; + gfbg_display_info *display_info = TD_NULL; + ot_fb_layer_buf buf_mode = 0; + ot_fb_mirror_mode mirror_mode; + par = (gfbg_par *)info->par; + display_info = &par->display_info; + gfbg_get_bufmode(par, &buf_mode); + mirror_mode = display_info->mirror_mode; + if ((buf_mode == OT_FB_LAYER_BUF_BUTT) || (buf_mode == OT_FB_LAYER_BUF_NONE)) { + gfbg_error("doesn't support FBIOGET_MIRROR_MODE operation when in standard mode" + "or FB_LAYER_BUF_NONE!\n"); + return TD_FAILURE; + } + if (osal_copy_to_user((td_void __user *)(td_uintptr_t)arg, &mirror_mode, sizeof(ot_fb_mirror_mode))) { + return -EFAULT; + } + return TD_SUCCESS; +} + +static td_s32 drv_gfbg_set_rotate_mode(struct fb_info *info, unsigned long arg) +{ + ot_fb_rotate_mode rotate_mode; + + if (osal_copy_from_user(&rotate_mode, (td_void __user *)(td_uintptr_t)arg, sizeof(ot_fb_rotate_mode))) { + return -EFAULT; + /* Reset compression information */ + } + if (gfbg_get_rotation_support() != TD_TRUE) { + gfbg_error("doesn't support rotate\n"); + return TD_FAILURE; + } + if (gfbg_set_rotatemode(info, rotate_mode) != TD_SUCCESS) { + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +static td_s32 drv_gfbg_get_rotate_mode(struct fb_info *info, unsigned long arg) +{ + gfbg_par *par = TD_NULL; + gfbg_display_info *display_info = TD_NULL; + ot_fb_layer_buf buf_mode = 0; + ot_fb_rotate_mode rotate_mode; + + if (gfbg_get_rotation_support() != TD_TRUE) { + gfbg_error("doesn't support rotate\n"); + return TD_FAILURE; + } + par = (gfbg_par *)info->par; + display_info = &par->display_info; + gfbg_get_bufmode(par, &buf_mode); + + if ((buf_mode == OT_FB_LAYER_BUF_BUTT) || (buf_mode == OT_FB_LAYER_BUF_NONE)) { + gfbg_error("doesn't support FBIOGET_ROTATE_MODE operation when in standard mode" + "or FB_LAYER_BUF_NONE!\n"); + return TD_FAILURE; + } + rotate_mode = display_info->rotate_mode; + if (osal_copy_to_user((td_void __user *)(td_uintptr_t)arg, &rotate_mode, sizeof(ot_fb_rotate_mode))) { + return -EFAULT; + } + return TD_SUCCESS; +} + +static td_s32 drv_gfbg_set_screen_size(struct fb_info *info, unsigned long arg) +{ + gfbg_par *par = TD_NULL; + ot_fb_size screen_size; + ot_fb_size max_screen_size = {0}; + ot_fb_point pos = {0}; + unsigned long lock_flag; + + par = (gfbg_par *)info->par; + if (is_cursor_layer(par->layer_id) && is_soft_cursor()) { + gfbg_error("you shouldn't set soft cursor screensize!"); + return TD_FAILURE; + } + + if (osal_copy_from_user(&screen_size, (td_void __user *)(td_uintptr_t)arg, sizeof(ot_fb_size))) { + return -EFAULT; + } + if ((screen_size.width == 0) || (screen_size.height == 0)) { + gfbg_error("screen width(%u) height(%u) shouldn't be 0\n", screen_size.width, screen_size.height); + return TD_FAILURE; + } + if (screen_size.width % 2 || screen_size.height % 2) { /* 2 for align */ + gfbg_error("stScreenSize (%u, %u) should align to 2!\n", screen_size.width, screen_size.height); + return TD_FAILURE; + } + gfbg_get_maxscreensize(par, &max_screen_size.width, &max_screen_size.height); + gfbg_get_layerpos(par, &pos); + if (screen_size.width > max_screen_size.width - pos.x_pos) { + gfbg_warning("the sum of width(%d) and x_pos(%d) larger than Vodev screen width(%d)," + "width will be changed!\n", + screen_size.width, pos.x_pos, max_screen_size.width); + screen_size.width = max_screen_size.width - pos.x_pos; + } + if (screen_size.height > max_screen_size.height - pos.y_pos) { + gfbg_warning("the sum of height(%d) and y_pos(%d) larger than Vodev screen height(%d)," + "width will be changed!\n", + screen_size.height, pos.y_pos, max_screen_size.height); + screen_size.height = max_screen_size.height - pos.y_pos; + } + osal_spin_lock_irqsave(&par->lock, &lock_flag); + par->modifying = TD_TRUE; + if (gfbg_set_screensize(par, &screen_size.width, &screen_size.height) == TD_SUCCESS) { + par->param_modify_mask |= GFBG_LAYER_PARAMODIFY_OUTRECT; + } + par->modifying = TD_FALSE; + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + return TD_SUCCESS; +} + +static td_s32 drv_gfbg_get_screen_size(struct fb_info *info, unsigned long arg) +{ + gfbg_par *par = TD_NULL; + ot_fb_size screen_size = {0}; + par = (gfbg_par *)info->par; + gfbg_get_screensize(par, &screen_size.width, &screen_size.height); + return osal_copy_to_user((td_void __user *)(td_uintptr_t)arg, &screen_size, sizeof(ot_fb_size)); +} + +static td_s32 flip_surface_check_param(const struct fb_info *info, const ot_fb_surfaceex *surface_ex) +{ + gfbg_par *par = TD_NULL; + gfbg_display_info *display_info = TD_NULL; + td_phys_addr_t addr; + td_phys_addr_t smem_end; + par = (gfbg_par *)info->par; + display_info = &par->display_info; + if (surface_ex->colorkey.enable != TD_TRUE && surface_ex->colorkey.enable != TD_FALSE) { + gfbg_error("colorkey.enable(%d) should be TRUE or FALSE!\n", surface_ex->colorkey.enable); + return TD_FAILURE; + } + + if (surface_ex->alpha.pixel_alpha != TD_TRUE && surface_ex->alpha.pixel_alpha != TD_FALSE) { + gfbg_error("alpha.pixel_alpha(%d) should be TRUE or FALSE!\n", surface_ex->alpha.pixel_alpha); + return TD_FAILURE; + } + + if (surface_ex->alpha.global_alpha_en != TD_TRUE && surface_ex->alpha.global_alpha_en != TD_FALSE) { + gfbg_error("alpha.global_alpha_en (%d) should be TRUE or FALSE!\n", surface_ex->alpha.global_alpha_en); + return TD_FAILURE; + } + + if ((surface_ex->colorkey.enable && !g_drv_ops.capability[par->layer_id].is_key_rgb) && + (!g_drv_ops.capability[par->layer_id].is_key_alpha)) { + gfbg_error("Layer %d doesn't support colorkey!\n", par->layer_id); + return TD_FAILURE; + } + + if (surface_ex->colorkey.enable && display_info->is_premul) { + gfbg_error("colorkey and premul couldn't take effect at the same time!\n"); + return TD_FAILURE; + } + + addr = surface_ex->phys_addr; + smem_end = gfbg_get_smem_start(info) + gfbg_get_smem_len(info) - gfbg_get_yres(info) * gfbg_get_line_length(info); + if ((addr < gfbg_get_smem_start(info)) || (addr > smem_end)) { + gfbg_error("the addr is out of range!\n"); + return TD_FAILURE; + } + + if (gfbg_get_line_length(info) == 0) { + return TD_FAILURE; + } + + if (gfbg_get_bits_per_pixel(info) == 0) { + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +#ifdef __LITEOS__ +static td_s32 flip_surface_pan_display(struct fb_info *info, const ot_fb_surfaceex *surface_ex, + gfbg_colorkeyex *colorkey_ex) +{ + td_s32 ret; + td_phys_addr_t addr; + unsigned int differ; + unsigned int x_offset; + unsigned int y_offset; + struct fb_overlayinfo_s oinfo; + addr = surface_ex->phys_addr; + differ = addr - gfbg_get_smem_start(info); + y_offset = differ / gfbg_get_line_length(info); + /* 3 is 8 bit */ + x_offset = (((differ % gfbg_get_line_length(info)) << 3) / (gfbg_get_bits_per_pixel(info))); + + ret = memcpy_s(&oinfo, sizeof(oinfo), &info->oinfo, sizeof(oinfo)); + gfbg_unequal_eok_return(ret); + oinfo.sarea.x = x_offset; + oinfo.sarea.y = y_offset; + + if (gfbg_pan_display(info, &oinfo) < 0) { + gfbg_error("error!\n"); + return TD_FAILURE; + } + + info->oinfo.sarea.x = x_offset; + info->oinfo.sarea.y = y_offset; + colorkey_ex->key = surface_ex->colorkey.value; + colorkey_ex->key_enable = surface_ex->colorkey.enable; + if (gfbg_get_bits_per_pixel(info) <= 8) { /* 8 bit */ + if (surface_ex->colorkey.value >= (1 << gfbg_get_bits_per_pixel(info))) { + gfbg_error("The value :%d is out of range the palette: %d!\n", surface_ex->colorkey.value, + 1 << gfbg_get_bits_per_pixel(info)); + return TD_FAILURE; + } + if ((info->cmap.blue != NULL) || (info->cmap.green != NULL) || (info->cmap.red != NULL)) { + colorkey_ex.blue_max = colorkey_ex.blue_min = info->cmap.blue[surface_ex->colorkey.value]; + colorkey_ex.green_max = colorkey_ex.green_min = info->cmap.green[surface_ex->colorkey.value]; + colorkey_ex.red_max = colorkey_ex.red_min = info->cmap.red[surface_ex->colorkey.value]; + colorkey_ex.red_mask = 0xff; + colorkey_ex.green_mask = 0xff; + colorkey_ex.blue_mask = 0xff; + colorkey_ex.key_mode = 0; + colorkey_ex.mask_enable = TD_TRUE; + } + } else { + g_drv_ops.gfbg_drv_color_convert(info, colorkey_ex); + } + return TD_SUCCESS; +} +#else +static td_s32 flip_surface_pan_display(struct fb_info *info, const ot_fb_surfaceex *surface_ex, + gfbg_colorkeyex *colorkey_ex) +{ + td_s32 ret; + td_phys_addr_t addr; + unsigned int differ; + unsigned int x_offset; + unsigned int y_offset; + struct fb_var_screeninfo var; + addr = surface_ex->phys_addr; + differ = addr - gfbg_get_smem_start(info); + y_offset = differ / gfbg_get_line_length(info); + /* 8 bit (2^3) */ + x_offset = (((differ % gfbg_get_line_length(info)) << 3) / (gfbg_get_bits_per_pixel(info))); + ret = memcpy_s(&var, sizeof(var), &info->var, sizeof(var)); + gfbg_unequal_eok_return(ret); + var.xoffset = x_offset; + var.yoffset = y_offset; + + if (fb_pan_display(info, &var) < 0) { + gfbg_error("pan_display error!\n"); + return TD_FAILURE; + } + + colorkey_ex->key = surface_ex->colorkey.value; + colorkey_ex->key_enable = surface_ex->colorkey.enable; + + if (gfbg_get_bits_per_pixel(info) <= 8UL) { /* 8 bits */ + if (surface_ex->colorkey.value >= (2UL << gfbg_get_bits_per_pixel(info))) { /* 2 for calculate */ + gfbg_error("The value :%d is out of range the palette: %d!\n", surface_ex->colorkey.value, + 2 << gfbg_get_bits_per_pixel(info)); /* 2 for calculate */ + return TD_FAILURE; + } + + colorkey_ex->blue_max = colorkey_ex->blue_min = info->cmap.blue[surface_ex->colorkey.value]; + colorkey_ex->green_max = colorkey_ex->green_min = info->cmap.green[surface_ex->colorkey.value]; + colorkey_ex->red_max = colorkey_ex->red_min = info->cmap.red[surface_ex->colorkey.value]; + } else { + g_drv_ops.gfbg_drv_color_convert(&info->var, colorkey_ex); + } + + return TD_SUCCESS; +} +#endif + +static td_s32 drv_gfbg_flip_surface(struct fb_info *info, unsigned long arg) +{ + gfbg_par *par = TD_NULL; + ot_fb_surfaceex surface_ex; + unsigned long lock_flag; + gfbg_colorkeyex colorkey_ex = {0}; + + par = (gfbg_par *)info->par; + + if (is_cursor_layer(par->layer_id) && is_soft_cursor()) { + gfbg_error("you shouldn't use FBIOFLIP_SURFACE for soft cursor!"); + return TD_FAILURE; + } + + if (osal_copy_from_user(&surface_ex, (td_void __user *)(td_uintptr_t)arg, sizeof(ot_fb_surfaceex))) { + return -EFAULT; + } + + /* check surface is value or not */ + if (flip_surface_check_param(info, &surface_ex) != TD_SUCCESS) { + return TD_FAILURE; + } + + /* refresh and color convert */ + if (flip_surface_pan_display(info, &surface_ex, &colorkey_ex) != TD_SUCCESS) { + return TD_FAILURE; + } + + osal_spin_lock_irqsave(&par->lock, &lock_flag); + par->modifying = TD_TRUE; + gfbg_set_alpha(par, &surface_ex.alpha); + par->param_modify_mask |= GFBG_LAYER_PARAMODIFY_ALPHA; + if (g_drv_ops.capability[par->layer_id].is_key_rgb || g_drv_ops.capability[par->layer_id].is_key_alpha) { + gfbg_set_key(par, &colorkey_ex); + par->param_modify_mask |= GFBG_LAYER_PARAMODIFY_COLORKEY; + } + par->modifying = TD_FALSE; + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + + return TD_SUCCESS; +} + +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC +static td_s32 set_compression_process(const struct fb_info *info) +{ + gfbg_par *par = TD_NULL; + volatile gfbg_compress_info *compress_info = TD_NULL; + ot_fb_layer_buf buf_mode; + unsigned long lock_flag; + td_u32 buf_size, cmp_stride; + gfbg_stride_attr attr = {0}; + + par = (gfbg_par *)info->par; + compress_info = &par->compress_info; + attr.format = par->color_format; + attr.width = par->display_info.display_width; + cmp_stride = 0; + if (par->color_format == OT_FB_FORMAT_ARGB1555 || par->color_format == OT_FB_FORMAT_ARGB4444) { + gfbg_recalculate_stride(&cmp_stride, NULL, &attr); + buf_size = ((cmp_stride * gfbg_get_yres(info)) + GFBG_ALIGNMENT) & (~GFBG_ALIGNMENT); + if (gfbg_get_smem_len(info) < (buf_size * 2)) { /* 2 for cal */ + gfbg_error("Memory is too small. ARGB1555 or ARGB4444 compression needs to allocate more memory.\n"); + gfbg_error("Memory should be greater than or equal to %d byte\n", (buf_size * 2)); /* 2 for cal */ + return TD_FAILURE; + } + } + + if (par->color_format != OT_FB_FORMAT_ARGB8888 && par->color_format != OT_FB_FORMAT_ARGB1555 && + par->color_format != OT_FB_FORMAT_ARGB4444) { + gfbg_error("compression only support pixel format (ARGB8888,ARGB1555,ARGB4444)\n"); + return TD_FAILURE; + } + if (par->display_info.mirror_mode != OT_FB_MIRROR_NONE || par->display_info.rotate_mode != OT_FB_ROTATE_NONE) { + gfbg_error("Can't do compression when mirror or rotate!\n"); + return TD_FAILURE; + } + gfbg_get_bufmode(par, &buf_mode); + + /* FB uses frame decompression, can not be displayed while refreshing, so only supports double buf mode */ + if ((buf_mode != OT_FB_LAYER_BUF_DOUBLE) && (buf_mode != OT_FB_LAYER_BUF_DOUBLE_IMMEDIATE)) { + gfbg_error("only FB_LAYER_BUF_DOUBLE or FB_LAYER_BUF_DOUBLE_IMMEDIATE mode support compress!\n"); + return TD_FAILURE; + } + + /* Record the entire image as the area to be compressed */ + osal_spin_lock_irqsave(&par->lock, &lock_flag); + compress_info->compress_rect.x = 0; + compress_info->compress_rect.y = 0; + compress_info->compress_rect.width = par->display_info.display_width; + compress_info->compress_rect.height = par->display_info.display_height; + compress_info->update_finished = TD_TRUE; + compress_info->delay = TD_TRUE; + compress_info->compress_open = TD_TRUE; + compress_info->is_losslessa = TD_FALSE; + compress_info->is_lossless = TD_FALSE; + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + + return TD_SUCCESS; +} + +static td_s32 set_compression_start(const struct fb_info *info, td_bool is_compress) +{ + gfbg_par *par = TD_NULL; + volatile gfbg_compress_info *compress_info = TD_NULL; + unsigned long lock_flag; + par = (gfbg_par *)info->par; + compress_info = &par->compress_info; + if (is_compress != TD_TRUE && is_compress != TD_FALSE) { + gfbg_error("compress(%d) should be TRUE or FALSE!\n", is_compress); + return TD_FAILURE; + } + if ((compress_info->is_economize_memory) == TD_TRUE && (is_compress != TD_TRUE)) { + gfbg_error("memory not enough, should be start compress!\n"); + return TD_FAILURE; + } + if (is_compress != compress_info->compress_open) { + if (is_compress) { + /* + * FB uses frame decompression, can not be displayed while refreshing + * so only supports double buf mode + * Record the entire image as the area to be compressed + */ + if (set_compression_process(info) != TD_SUCCESS) { + return TD_FAILURE; + } + } else { + osal_spin_lock_irqsave(&par->lock, &lock_flag); + par->param_modify_mask |= GFBG_LAYER_PARAMODIEY_COMPRESS; + compress_info->compress_open = TD_FALSE; + compress_info->is_losslessa = TD_FALSE; + compress_info->is_lossless = TD_FALSE; + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + /* Waiting for an interrupt before proceeding to the next two operations */ + gfbg_wait_regconfig_work(par->layer_id); + /* Reset compression information */ + compress_info->update_rect.width = 0; + compress_info->update_rect.height = 0; + } + } + return TD_SUCCESS; +} +#endif + +static td_s32 drv_gfbg_set_compression_mode(struct fb_info *info, unsigned long arg) +{ + gfbg_par *par = TD_NULL; + td_bool is_compress = TD_FALSE; + par = (gfbg_par *)info->par; + if (!g_drv_ops.capability[par->layer_id].is_decompress) { + gfbg_error("Layer %d doesn't support compression operation!\n", par->layer_id); + return TD_FAILURE; + } + +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC + if (osal_copy_from_user(&is_compress, (td_void __user *)(td_uintptr_t)arg, sizeof(td_bool))) { + return -EFAULT; + } + + /* set compress config */ + if (set_compression_start(info, is_compress) != TD_SUCCESS) { + return TD_FAILURE; + } +#else + ot_unused(is_compress); + ot_unused(arg); +#endif + return TD_SUCCESS; +} + +static td_s32 drv_gfbg_get_compression_mode(struct fb_info *info, unsigned long arg) +{ + gfbg_par *par = TD_NULL; + volatile gfbg_compress_info *compress_info = TD_NULL; + td_bool is_compress = TD_FALSE; + par = (gfbg_par *)info->par; + compress_info = &par->compress_info; + + if (!g_drv_ops.capability[par->layer_id].is_decompress) { + gfbg_warning("Layer %d doesn't support get compression!\n", par->layer_id); + } else { + is_compress = compress_info->compress_open; + } + return osal_copy_to_user((td_void __user *)(td_uintptr_t)arg, &is_compress, sizeof(td_bool)); +} + +static td_s32 drv_gfbg_create(struct fb_info *info, unsigned long arg) +{ + gfbg_par *par = TD_NULL; + td_u32 layer_id; + unsigned long lock_flag; + ot_unused(arg); + par = (gfbg_par *)info->par; + if (par == TD_NULL) { + gfbg_error("par is NULL failed!\n"); + return TD_FAILURE; + } + layer_id = par->layer_id; + + /* when unbind/bind */ + if (g_drv_ops.gfbg_open_layer(layer_id) != TD_SUCCESS) { + gfbg_error("Open graphic layer %u# failed!\n", layer_id); + return TD_FAILURE; + } + + if (g_drv_ops.gfbg_drv_set_layer_enable(layer_id, TD_TRUE) != TD_SUCCESS) { + gfbg_error("enable graphic layer %u# failed!\n", layer_id); + return TD_FAILURE; + } + osal_spin_lock_irqsave(&par->lock, &lock_flag); + par->show = TD_TRUE; + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + return TD_SUCCESS; +} + +static td_s32 drv_gfbg_release(struct fb_info *info, unsigned long arg) +{ + gfbg_par *par = TD_NULL; + td_u32 layer_id; + unsigned long lock_flag; + ot_unused(arg); + par = (gfbg_par *)info->par; + if (par == TD_NULL) { + gfbg_error("par is NULL failed!\n"); + return TD_FAILURE; + } + layer_id = par->layer_id; + + if (g_drv_ops.gfbg_drv_set_layer_enable(layer_id, TD_FALSE) != TD_SUCCESS) { + gfbg_error("disable graphic layer %u# failed!\n", layer_id); + return TD_FAILURE; + } + osal_spin_lock_irqsave(&par->lock, &lock_flag); + par->show = TD_FALSE; + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + return TD_SUCCESS; +} + +static td_s32 drv_gfbg_draw_frame(struct fb_info *info, td_ulong arg) +{ + gfbg_par *par = NULL; + ot_fb_smart_rect_param frame_param = {0}; + td_ulong lock_flag; + td_char *vir = TD_NULL; + par = (gfbg_par *)info->par; + if (g_drv_ops.capability[par->layer_id].is_osb == TD_FALSE) { + gfbg_error("Layer %d# doesn't support draw smart rect function.\n", par->layer_id); + return TD_FAILURE; + } +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC + if (osal_copy_from_user(&frame_param, (td_void __user *)(td_uintptr_t)arg, sizeof(ot_fb_smart_rect_param))) { + return -EFAULT; + } + if (frame_param.num > 128) { /* frame max is 128 */ + gfbg_error("actual %d,support draw smart rect max 128.\n", frame_param.num); + return TD_FAILURE; + } + if (frame_param.rect_start == NULL) { + return TD_FAILURE; + } + vir = osal_kmalloc(sizeof(ot_fb_smart_rect) * 128, OSAL_GFP_KERNEL); /* frame max is 128 */ + if (vir == TD_NULL) { + return TD_FAILURE; + } + + if (osal_copy_from_user(vir, (td_void __user *)frame_param.rect_start, + (td_ulong)(sizeof(ot_fb_smart_rect) * frame_param.num))) { + osal_kfree(vir); + return -EFAULT; + } + frame_param.rect_start = (ot_fb_smart_rect *)vir; + osal_spin_lock_irqsave(&par->lock, &lock_flag); + par->modifying = TD_TRUE; + if (gfbg_draw_smart_rect(info, &frame_param) != TD_SUCCESS) { + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + osal_kfree(vir); + return TD_FAILURE; + } + par->param_modify_mask |= GFBG_LAYER_PARAMODIEY_SMART_RECT; + par->modifying = TD_FALSE; + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + osal_kfree(vir); +#else + ot_unused(lock_flag); + ot_unused(frame_param); + ot_unused(vir); +#endif + return TD_SUCCESS; +} + +static td_s32 drv_gfbg_check_layer_csc(td_u32 layer, const ot_fb_layer_csc *csc) +{ + if (csc->csc_matrix < OT_FB_CSC_MATRIX_RGBFULL_TO_BT601LIMIT || + csc->csc_matrix > OT_FB_CSC_MATRIX_RGBFULL_TO_BT709FULL) { + gfbg_error("fb layer(%d) csc matrix type(%u) should be [%u, %u]!\n", layer, csc->csc_matrix, + OT_FB_CSC_MATRIX_RGBFULL_TO_BT601LIMIT, OT_FB_CSC_MATRIX_RGBFULL_TO_BT709FULL); + return TD_FAILURE; + } + + if (csc->luma > FB_CSC_LUMA_MAX) { + gfbg_error("fb csc luma value %u out of range!\n", csc->luma); + return TD_FAILURE; + } + + if (csc->contrast > FB_CSC_CONT_MAX) { + gfbg_error("fb csc contrast value %u out of range!\n", csc->contrast); + return TD_FAILURE; + } + + if (csc->hue > FB_CSC_HUE_MAX) { + gfbg_error("fb csc hue value %u out of range!\n", csc->hue); + return TD_FAILURE; + } + + if (csc->saturation > FB_CSC_SAT_MAX) { + gfbg_error("fb csc saturation value %u out of range!\n", csc->saturation); + return TD_FAILURE; + } + + if ((csc->ex_csc_en != TD_TRUE) && (csc->ex_csc_en != TD_FALSE)) { + gfbg_error("fb csc ext csc switch %u out of range!\n", csc->ex_csc_en); + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +static td_s32 drv_gfbg_set_layer_csc(struct fb_info *info, unsigned long arg) +{ + gfbg_par *par = (gfbg_par *)info->par; + ot_fb_layer_csc layer_csc; + td_s32 ret; + graphic_layer_context *gfx_layer_ctx = fb_graphics_get_gfx_layer_ctx(); + hal_disp_layer gfx_layer = gfbg_drv_gfbglayer_to_hwlayer(par->layer_id); + + if (osal_copy_from_user(&layer_csc, (td_void __user *)(td_uintptr_t)arg, sizeof(ot_fb_layer_csc))) { + gfbg_error("copy from user failed!\n"); + return -EFAULT; + } + + ret = drv_gfbg_check_layer_csc(par->layer_id, &layer_csc); + if (ret != TD_SUCCESS) { + return TD_FAILURE; + } + + if (gfx_layer_ctx[par->layer_id].opened != TD_TRUE) { + gfbg_error("The graphic layer %u# is not open!\n", par->layer_id); + return TD_FAILURE; + } + + ret = memcpy_s(&gfx_layer_ctx[par->layer_id].gfx_csc, sizeof(ot_fb_layer_csc), &layer_csc, sizeof(ot_fb_layer_csc)); + gfbg_unequal_eok_return(ret); + + ret = fb_graphic_drv_set_csc_coef(gfx_layer, &gfx_layer_ctx[par->layer_id].gfx_csc, + &gfx_layer_ctx[par->layer_id].coef_param); + if (ret != TD_SUCCESS) { + gfbg_error("The graphic %u set csc coef failed!\n", par->layer_id); + return TD_FAILURE; + } + ret = fb_graphics_set_csc_en(gfx_layer, TD_TRUE); + if (ret != TD_SUCCESS) { + gfbg_error("The graphics %u set csc en failed!\n", par->layer_id); + return TD_FAILURE; + } + return TD_SUCCESS; +} + +static td_s32 drv_gfbg_get_layer_csc(struct fb_info *info, unsigned long arg) +{ + gfbg_par *par = (gfbg_par *)info->par; + ot_fb_layer_csc layer_csc; + td_s32 ret; + graphic_layer_context *gfx_layer_ctx = fb_graphics_get_gfx_layer_ctx(); + + ret = memcpy_s(&layer_csc, sizeof(ot_fb_layer_csc), &gfx_layer_ctx[par->layer_id].gfx_csc, sizeof(ot_fb_layer_csc)); + gfbg_unequal_eok_return(ret); + + if (osal_copy_to_user((td_void __user *)(td_uintptr_t)arg, &layer_csc, sizeof(ot_fb_layer_csc))) { + gfbg_error("copy to user failed!\n"); + return -EFAULT; + } + return TD_SUCCESS; +} + +#ifdef __LITEOS__ +static td_s32 gfbg_ioctl_liteos_standard_io(struct fb_info *info, td_u32 cmd, unsigned long arg, td_bool *is_continue) +{ + td_s32 ret; + /* for FBIOPUT_SCREENINFO_GFBG */ + struct gfbg_info *info_temp = (struct gfbg_info *)arg; + struct gfbg_info info_copy; + /* for FBIOPAN_DISPLAY_GFBG */ + struct fb_overlayinfo_s *oinfo = (struct fb_overlayinfo_s *)arg; + + switch (cmd) { + case FBIOGET_SCREENINFO_GFBG: + ret = memcpy_s((void *)arg, sizeof(struct gfbg_info), info, sizeof(struct gfbg_info)); + gfbg_unequal_eok_return(ret); + break; + case FBIOPUT_SCREENINFO_GFBG: + ret = memcpy_s(&info_copy, sizeof(info_copy), info, sizeof(info_copy)); + gfbg_unequal_eok_return(ret); + if (info->vtable.fb_set_par) { + info->vinfo.xres = info_temp->vinfo.xres; + info->vinfo.yres = info_temp->vinfo.yres; + info->vinfo.format = info_temp->vinfo.format; + info->oinfo.sarea.width = info_temp->oinfo.sarea.width; + info->oinfo.sarea.height = info_temp->oinfo.sarea.height; + info->oinfo.sarea.x = info_temp->oinfo.sarea.x; + info->oinfo.sarea.y = info_temp->oinfo.sarea.y; + info->oinfo.bpp = info_temp->oinfo.bpp; + if (info->vtable.fb_set_par(&info->vtable) != TD_SUCCESS) { + gfbg_error("Put screeninfo error! ret=%d\n", ret); + ret = memcpy_s(info, sizeof(info_copy), &info_copy, sizeof(info_copy)); + gfbg_unequal_eok_return(ret); + return TD_FAILURE; + } + gfbg_pan_display(&info->vtable, &info->oinfo); + } + break; + case FBIOPAN_DISPLAY_GFBG: + if (info->vtable.fb_pan_display) { + if (info->vtable.fb_pan_display(&info->vtable, oinfo) != TD_SUCCESS) { + gfbg_error("Put screeninfo error! ret=%d\n", ret); + ret = memcpy_s(info, sizeof(info_copy), &info_copy, sizeof(info_copy)); + gfbg_unequal_eok_return(ret); + return TD_FAILURE; + } + info->oinfo.sarea.x = oinfo->sarea.x; + info->oinfo.sarea.y = oinfo->sarea.y; + } + break; + default: + *is_continue = TD_TRUE; + break; + } + return TD_SUCCESS; +} +#endif + +/* + * Function : gfbg_ioctl + * Description : set the colorkey or alpha for overlay + * Return : return 0 if succeed, otherwise return error code + */ +static td_s32 gfbg_ioctl(struct fb_info *info, td_u32 cmd, unsigned long arg) +{ + td_u8 gfbg_cmd = _IOC_NR(cmd); +#ifdef __LITEOS__ + td_bool is_continue = TD_FALSE; +#endif + if (gfbg_ioctl_check_param(info, cmd, (td_void __user *)(td_uintptr_t)arg) != TD_SUCCESS) { + return TD_FAILURE; + } + + /* liteos deal with FBIOGET_SCREENINFO_GFBG\FBIOPUT_SCREENINFO_GFBG\FBIOPAN_DISPLAY_GFBG */ +#ifdef __LITEOS__ + if (gfbg_ioctl_liteos_standard_io(info, cmd, arg, &is_continue) != TD_SUCCESS) { + return TD_FAILURE; + } + if (is_continue != TD_TRUE) { + return TD_SUCCESS; + } +#endif + if ((gfbg_cmd < 1) || (gfbg_cmd >= DRV_GFBG_IOCTL_CMD_NUM_MAX) || (g_drv_gfbg_ctl_num[gfbg_cmd] < 1) || + (g_drv_gfbg_ctl_num[gfbg_cmd] >= DRV_GFBG_IOCTL_FUNC_ITEM_NUM_MAX)) { + return TD_FAILURE; + } + if (g_drv_gfbg_ioctl_func[g_drv_gfbg_ctl_num[gfbg_cmd]].func == TD_NULL) { + return TD_FAILURE; + } + + if (cmd != g_drv_gfbg_ioctl_func[g_drv_gfbg_ctl_num[gfbg_cmd]].cmd) { + gfbg_error("the command:0x%x is unsupported!\n", cmd); + return TD_FAILURE; + } + return g_drv_gfbg_ioctl_func[g_drv_gfbg_ctl_num[gfbg_cmd]].func(info, arg); +} + +#ifdef CONFIG_COMPAT +static td_s32 gfbg_compat_ioctl(struct fb_info *info, unsigned cmd, unsigned long arg) +{ + return gfbg_ioctl(info, cmd, arg); +} +#endif + +static td_void gfbg_version(td_void) +{ + /* 80length:Use "strings gfbg.ko | grep "GFBG_MAIN_VERSION"" to get the version */ + td_char gfbg_version[80] = + "GFBG_MAIN_VERSION[" mkmarcotostr(GFBG_MAIN_VERSION) "] Build Time[" __DATE__ ", "__TIME__ "]"; + gfbg_info("%s\n", gfbg_version); +} + +static td_s32 gfbg_bitfieldcmp(struct fb_bitfield x, struct fb_bitfield y) +{ + if ((x.offset == y.offset) && (x.length == y.length) && (x.msb_right == y.msb_right)) { + return 0; + } else { + return -1; + } +} + +static td_u32 gfbg_getbppbyfmt(ot_fb_color_format color_fmt) +{ + switch (color_fmt) { + case OT_FB_FORMAT_RGB565: + case OT_FB_FORMAT_KRGB444: + case OT_FB_FORMAT_KRGB555: + case OT_FB_FORMAT_ARGB4444: + case OT_FB_FORMAT_ARGB1555: + case OT_FB_FORMAT_RGBA4444: + case OT_FB_FORMAT_RGBA5551: + case OT_FB_FORMAT_ACLUT88: + case OT_FB_FORMAT_BGR565: + case OT_FB_FORMAT_ABGR1555: + case OT_FB_FORMAT_ABGR4444: + case OT_FB_FORMAT_KBGR444: + case OT_FB_FORMAT_KBGR555: + return 16; /* 16 bit width */ + case OT_FB_FORMAT_RGB888: + case OT_FB_FORMAT_ARGB8565: + case OT_FB_FORMAT_RGBA5658: + case OT_FB_FORMAT_ABGR8565: + case OT_FB_FORMAT_BGR888: + return 24; /* 24 bit width */ + case OT_FB_FORMAT_KRGB888: + case OT_FB_FORMAT_ARGB8888: + case OT_FB_FORMAT_RGBA8888: + case OT_FB_FORMAT_ABGR8888: + case OT_FB_FORMAT_KBGR888: + return 32; /* 32 bit width */ + case OT_FB_FORMAT_1BPP: + return 1; + case OT_FB_FORMAT_2BPP: + return 2; /* 2 bit width */ + case OT_FB_FORMAT_4BPP: + return 4; /* 4 bit width */ + case OT_FB_FORMAT_8BPP: + case OT_FB_FORMAT_ACLUT44: + return 8; /* 8 bit width */ + default: + return 0; + } +} + +static ot_fb_color_format gfbg_getfmtbyargb(const struct fb_bitfield *red, const struct fb_bitfield *green, + const struct fb_bitfield *blue, const struct fb_bitfield *transp, + td_u32 color_depth) +{ + td_u32 i; + td_u32 bpp; + + if ((red == TD_NULL) || (green == TD_NULL) || (blue == TD_NULL) || (transp == TD_NULL)) { + return OT_FB_FORMAT_BUTT; + } + + /* not support color palette low than 8bit */ + if (color_depth < 2) { /* 2 bit */ + return OT_FB_FORMAT_BUTT; + } + + if (color_depth == 2) { /* 2 bit */ + return OT_FB_FORMAT_2BPP; + } + + if (color_depth == 4) { /* 4 bit */ + return OT_FB_FORMAT_4BPP; + } + + if (color_depth == 8) { /* 8 bit */ + return OT_FB_FORMAT_8BPP; + } + + /* + * Find the pixel format (gfbg_argb_bitinfo) corresponding to the given red, + * green, and blue bit field information and the number of bits per pixel (bpp) + */ + for (i = 0; i < sizeof(g_argb_bit_field) / sizeof(gfbg_argb_bitinfo); i++) { + if ((gfbg_bitfieldcmp(*red, g_argb_bit_field[i].red) == 0) && + (gfbg_bitfieldcmp(*green, g_argb_bit_field[i].green) == 0) && + (gfbg_bitfieldcmp(*blue, g_argb_bit_field[i].blue) == 0) && + (gfbg_bitfieldcmp(*transp, g_argb_bit_field[i].transp) == 0)) { + bpp = gfbg_getbppbyfmt(i); + if (bpp == color_depth) { + return i; + } + } + } + i = OT_FB_FORMAT_BUTT; + return i; +} + +static td_s32 gfbg_check_mem_enough(const struct fb_info *info, td_u32 pitch, td_u32 height) +{ + td_u32 buffer_num = 0; + td_u32 buffer_size; + gfbg_par *par = TD_NULL; + gfbg_refresh_info *refresh_info = TD_NULL; + if (info == TD_NULL) { + return TD_FAILURE; + } + if (info->par == TD_NULL) { + return TD_FAILURE; + } + par = (gfbg_par *)info->par; + refresh_info = &par->refresh_info; + + switch (refresh_info->buf_mode) { + case OT_FB_LAYER_BUF_DOUBLE: + case OT_FB_LAYER_BUF_DOUBLE_IMMEDIATE: + buffer_num = 2; /* 2 buffer num */ + break; + + case OT_FB_LAYER_BUF_ONE: + buffer_num = 1; + break; + + default: + return TD_SUCCESS; + } + /* The interface setting requires uBuffersize, the actual memory size info->fix.smem_len */ + buffer_size = buffer_num * pitch * height; + if (gfbg_get_smem_len(info) >= buffer_size) { + return TD_SUCCESS; + } + gfbg_error("memory is not enough! now is %d u32Pitch %d u32Height %d expect %d\n", gfbg_get_smem_len(info), pitch, + height, buffer_size); + return TD_FAILURE; +} + +/* Address check only for uncompressed data */ +static td_s32 gfbg_check_phyaddr(const ot_fb_buf *canvas_buf) +{ + td_u64 len; + td_u32 bpp; + + bpp = gfbg_getbppbyfmt(canvas_buf->canvas.format); + if (bpp == 0) { + gfbg_error("Unsupported PIXEL FORMAT!\n"); + return TD_FAILURE; + } + len = canvas_buf->update_rect.height * (canvas_buf->update_rect.width * bpp / 8); /* 8 alg data */ + + return ot_mmz_check_phys_addr(canvas_buf->canvas.phys_addr, (td_ulong)len); +} + +#ifndef __LITEOS__ +static td_s32 gfbg_check_fmt(const struct fb_var_screeninfo *var, const struct fb_info *info) +{ + ot_fb_color_format format; + gfbg_par *par = TD_NULL; + td_u32 layer_id; + + par = (gfbg_par *)info->par; + layer_id = par->layer_id; + + format = gfbg_getfmtbyargb(&var->red, &var->green, &var->blue, &var->transp, var->bits_per_pixel); + if (format == OT_FB_FORMAT_BUTT) { + gfbg_error("Unknown format(offset, length) r:(%d, %d, %d) ,g:(%d, %d, %d), b(%d, %d, %d), \ + a(%d, %d, %d), bpp:%d!\n", + var->red.offset, var->red.length, var->red.msb_right, + var->green.offset, var->green.length, var->green.msb_right, + var->blue.offset, var->blue.length, var->blue.msb_right, + var->transp.offset, var->transp.length, var->transp.msb_right, + var->bits_per_pixel); + return -EINVAL; + } + + if (!g_drv_ops.capability[layer_id].is_color_format[format]) { + gfbg_error("Unsupported PIXEL FORMAT!\n"); + return -EINVAL; + } + + return TD_SUCCESS; +} +#endif + +/* + * Name : gfbg_buf_map + * Desc : Memory mapping, which generates virtual addresses based on physical address mappings. + */ +static td_void *gfbg_buf_map(td_phys_addr_t phys_addr, td_u32 size) +{ + return cmpi_remap_nocache(phys_addr, size); +} + +static td_void gfbg_buf_ummap(td_void *vir_addr) +{ + cmpi_unmap(vir_addr); + return; +} + +#ifndef __LITEOS__ +static td_s32 gfbg_check_output(const struct fb_var_screeninfo *var, const struct fb_info *info) +{ + gfbg_par *par = TD_NULL; + td_u32 layer_id; + par = (gfbg_par *)info->par; + layer_id = par->layer_id; + + if (((var->yres % 2) != 0) && (gfbg_is_interlace(par))) { /* 2 for calculate */ + gfbg_error("yres(%d) of layer_id %d should be even when vodev output is interlace\n", var->yres, layer_id); + return TD_FAILURE; + } + return TD_SUCCESS; +} + +static td_s32 gfbg_check_virtual_resolution(const struct fb_var_screeninfo *var, const struct fb_info *info) +{ + gfbg_par *par = TD_NULL; + td_u32 layer_id; + par = (gfbg_par *)info->par; + layer_id = par->layer_id; + + if (var->xres < g_drv_ops.capability[layer_id].min_width) { + gfbg_error("xres(%d) of layer_id %d can't be less than min_width(%d)\n", var->xres, layer_id, + g_drv_ops.capability[layer_id].min_width); + return TD_FAILURE; + } + if (var->yres < g_drv_ops.capability[layer_id].min_height) { + gfbg_error("yres(%d) of layer_id %d can't be less than min_height(%d)\n", var->yres, layer_id, + g_drv_ops.capability[layer_id].min_height); + return TD_FAILURE; + } + + if (var->xres > var->xres_virtual) { + gfbg_error("xres(%d) of layer_id %d should be less than xres_virtual(%d)\n", var->xres, layer_id, + var->xres_virtual); + return TD_FAILURE; + } + if (var->yres > var->yres_virtual) { + gfbg_error("yres(%d) of layer_id %d should be less than yres_virtual(%d)\n", var->yres, layer_id, + var->yres_virtual); + return TD_FAILURE; + } + return TD_SUCCESS; +} + +static td_s32 gfbg_check_offset(const struct fb_var_screeninfo *var, const struct fb_info *info) +{ + gfbg_par *par = TD_NULL; + td_u32 layer_id; + par = (gfbg_par *)info->par; + layer_id = par->layer_id; + + if ((var->xoffset + var->xres > var->xres_virtual) || (var->xoffset > var->xres_virtual)) { + gfbg_error("the sum of layer%d's xoffset(%d) and xres(%d) should be less than xres_virtual(%d)\n", layer_id, + var->xoffset, var->xres, var->xres_virtual); + return -EINVAL; + } + + if ((var->yoffset + var->yres > var->yres_virtual) || (var->yoffset > var->yres_virtual)) { + gfbg_error("the sum of layer%d's yoffset(%d) and yres(%d) should be less than yres_virtual(%d)\n", layer_id, + var->yoffset, var->yres, var->yres_virtual); + return -EINVAL; + } + return TD_SUCCESS; +} + +static td_s32 gfbg_check_total(const struct fb_var_screeninfo *var, const struct fb_info *info) +{ + td_u32 hor_total; + td_u32 ver_total; + gfbg_par *par = TD_NULL; + td_u32 layer_id; + par = (gfbg_par *)info->par; + layer_id = par->layer_id; + + hor_total = var->left_margin + var->xres + var->right_margin + var->hsync_len; + if (hor_total == 0) { + gfbg_error("the sum of layer%d's left_margin(%d),xres(%d),right_margin(%d),hsync_len(%d) can't be 0\n", + layer_id, var->left_margin, var->xres, var->right_margin, var->hsync_len); + return TD_FAILURE; + } + ver_total = var->yres + var->lower_margin + var->vsync_len + var->upper_margin; + if (ver_total == 0) { + gfbg_error("the sum of layer%d's left_margin(%d),xres(%d),right_margin(%d),hsync_len(%d) can't be 0\n", + layer_id, var->upper_margin, var->yres, var->lower_margin, var->vsync_len); + return TD_FAILURE; + } + return TD_SUCCESS; +} + +/* + * Function : gfbg_check_var + * Description : check if the parameter for framebuffer is supported. + * Return : return 0, if the parameter is supported, otherwise,return error + */ +static td_s32 gfbg_check_var(struct fb_var_screeninfo *var, struct fb_info *info) +{ + gfbg_par *par = TD_NULL; + td_u32 expected_len; + td_u32 layer_id; + + if ((info == TD_NULL) || (var == TD_NULL) || (info->par == TD_NULL)) { + return TD_FAILURE; + } + + par = (gfbg_par *)info->par; + layer_id = par->layer_id; + + if (is_cursor_layer(par->layer_id) && is_soft_cursor()) { + gfbg_error("cursor layer doesn't support this operation!\n"); + return TD_FAILURE; + } + + if (gfbg_check_fmt(var, info) != TD_SUCCESS) { + return TD_FAILURE; + } + + /* + * For interlaced output check + * the actual height of the layer must be an even number + * Progressive output without this limit + */ + if (gfbg_check_output(var, info) != TD_SUCCESS) { + return TD_FAILURE; + } + /* + * for virtual resolution check + * virtual resolution can't be less than minimal resolution + */ + if (gfbg_check_virtual_resolution(var, info) != TD_SUCCESS) { + return TD_FAILURE; + } + /* check if the offset is valid */ + if (gfbg_check_offset(var, info) != TD_SUCCESS) { + return TD_FAILURE; + } + /* + * for hor_total and ver_total check + * The FB driver in the Linux kernel will use u32HTotal and u32VTotal as divisors + * so they cannot be 0 + */ + if (gfbg_check_total(var, info) != TD_SUCCESS) { + return TD_FAILURE; + } + + gfbg_info("xres:%d, yres:%d, xres_virtual:%d, yres_virtual:%d\n", var->xres, var->yres, var->xres_virtual, + var->yres_virtual); + /* for mem len check */ + expected_len = var->yres_virtual * ((((var->xres_virtual * var->bits_per_pixel) >> 3) + /* 8 bit (2^3) */ + GFBG_ALIGNMENT) & (~GFBG_ALIGNMENT)); + + if (info->fix.smem_len && (expected_len > info->fix.smem_len)) { + gfbg_error("layer %d don't has enough mem! expected: %d KBytes, real:%d KBytes\n", layer_id, + expected_len / 1024, info->fix.smem_len / 1024); /* 1024 for KB */ + return -EINVAL; + } + + return TD_SUCCESS; +} +#endif + +static td_void gfbg_set_dispbufinfo(td_u32 layer_id) +{ + struct fb_info *info = g_layer[layer_id].info; + gfbg_par *par = (gfbg_par *)(info->par); + gfbg_refresh_info *refresh_info = &par->refresh_info; + gfbg_dispbuf_info *disp_buf_info = &refresh_info->disp_buf_info; + td_u32 uncompress_stride, buf_size; + uncompress_stride = (info->var.xres_virtual * info->var.bits_per_pixel / 8 + /* 8 one byte */ + GFBG_ALIGNMENT) & (~GFBG_ALIGNMENT); + + /* + * there's a limit from hardware that screen buf should be 16 bytes aligned,maybe it's proper + * to get this info from drv adapter + */ + if (gfbg_check_memory_enough(info, uncompress_stride) == TD_TRUE && + info->var.bits_per_pixel == 32) { /* 32 only for argb8888 */ + buf_size = ((uncompress_stride * gfbg_get_yres(info)) + GFBG_ALIGNMENT) & (~GFBG_ALIGNMENT); + } else { + /* according real stride,calculate offset */ + buf_size = ((gfbg_get_line_length(info) * gfbg_get_yres(info)) + GFBG_ALIGNMENT) & (~GFBG_ALIGNMENT); + } + if (gfbg_get_smem_len(info) == 0) { + return; + } else if ((gfbg_get_smem_len(info) >= buf_size) && (gfbg_get_smem_len(info) < buf_size * 2)) { /* 2 alg data */ + disp_buf_info->phys_addr[0] = gfbg_get_smem_start(info); + disp_buf_info->phys_addr[1] = gfbg_get_smem_start(info); +#ifdef CONFIG_COMPRESS_ECONOMIZE_MEMERY + disp_buf_info->vir_addr[0] = gfbg_get_screen_base(info); + disp_buf_info->vir_addr[1] = gfbg_get_screen_base(info); +#endif + } else if (gfbg_get_smem_len(info) >= buf_size * 2) { /* 2 alg data */ + disp_buf_info->phys_addr[0] = gfbg_get_smem_start(info); + disp_buf_info->phys_addr[1] = gfbg_get_smem_start(info) + buf_size; +#ifdef CONFIG_COMPRESS_ECONOMIZE_MEMERY + disp_buf_info->vir_addr[0] = gfbg_get_screen_base(info); + disp_buf_info->vir_addr[1] = gfbg_get_screen_base(info) + buf_size; +#endif + } + return; +} + +static td_s32 gfbg_refresh_1buf_prepare_dst(ot_fb_buf *dst_rect, const gfbg_par *par, + const gfbg_display_info *display_info, + const gfbg_dispbuf_info *display_buf_info, const struct fb_info *info) +{ + td_u32 bytes_per_pixel = 2; + + dst_rect->canvas.format = par->color_format; + dst_rect->canvas.height = display_info->display_height; + dst_rect->canvas.width = display_info->display_width; + dst_rect->canvas.pitch = gfbg_get_line_length(info); + + if (display_info->rotate_mode == OT_FB_ROTATE_90 || display_info->rotate_mode == OT_FB_ROTATE_270) { + dst_rect->canvas.height = display_info->display_width; + dst_rect->canvas.width = display_info->display_height; + if (dst_rect->canvas.format == OT_FB_FORMAT_ARGB1555 || dst_rect->canvas.format == OT_FB_FORMAT_ARGB4444) { + bytes_per_pixel = 2; /* 2 for bit */ + } else if (dst_rect->canvas.format == OT_FB_FORMAT_ARGB8888) { + bytes_per_pixel = 4; /* 4 for bit */ + } + dst_rect->canvas.pitch = ((bytes_per_pixel * dst_rect->canvas.width + GFBG_ALIGN - 1) / + GFBG_ALIGN) * GFBG_ALIGN; + + if ((par->color_format != OT_FB_FORMAT_ARGB4444) && (par->color_format != OT_FB_FORMAT_ARGB1555) && + (par->color_format != OT_FB_FORMAT_ARGB8888)) { + gfbg_error("rotate only support ARGB4444, ARGB1555, ARGB8888 which is %d\n", par->color_format); + return TD_FAILURE; + } + dst_rect->canvas.phys_addr = par->rotate_vb; + } else { + /* + * The target address is selected as the display buf configured for the interrupt, + * which is indicated by index for interrupt. + */ + dst_rect->canvas.phys_addr = display_buf_info->phys_addr[display_buf_info->index_for_int]; + + /* If compression is not open, you do not have to configure a compressed address for this refresh */ + } + return TD_SUCCESS; +} + +static td_void gfbg_refresh_1buf_prepare_addr(gfbg_refresh_info *refresh_info, td_u32 layer_id, gfbg_osd_data *osd_data, + struct fb_info *info, ot_fb_buf *dst_rect) +{ + unsigned long lock_flag; + gfbg_par *par = (gfbg_par *)info->par; + gfbg_dispbuf_info *display_buf_info = &refresh_info->disp_buf_info; + td_u32 buf_size = ((gfbg_get_line_length(info) * gfbg_get_yres(info)) + GFBG_ALIGNMENT) & (~GFBG_ALIGNMENT); + /* 1buf does not support compression, close compression configuration */ + refresh_info->disp_buf_info.compress = TD_FALSE; + + g_drv_ops.gfbg_drv_get_osd_data(layer_id, osd_data); + + if (osd_data->buffer_phy_addr != par->refresh_info.disp_buf_info.phys_addr[0] && display_buf_info->phys_addr[0]) { + osal_spin_lock_irqsave(&par->lock, &lock_flag); + par->modifying = TD_TRUE; + /* Notify the interrupt handler to modify the display address. */ + par->param_modify_mask |= GFBG_LAYER_PARAMODIFY_DISPLAYADDR; + + /* + * The buf address in the display information is configured to + * the screen display address for refreshing the screen. + */ + refresh_info->screen_addr = display_buf_info->phys_addr[display_buf_info->index_for_int]; + /* If compression is not open, you do not have to configure a compressed address for this refresh */ + if (par->compress_info.compress_open) { + /* Use half of the video memory instead of another buffer */ + refresh_info->gb_screen_addr = refresh_info->screen_addr + buf_size / 2; /* 2 part */ + } + display_buf_info->stride = 4 * dst_rect->canvas.width; /* 4 for argb 8888 */ + + par->modifying = TD_FALSE; + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + } +} + +static td_void gfbg_refresh_1buf_prepare_opt(gfbg_blit_opt *blit_opt, gfbg_par *par) +{ + blit_opt->call_back = TD_TRUE; + /* Non-blocking mode */ + blit_opt->block = TD_FALSE; + + if (par->display_info.antiflicker_mode == GFBG_ANTIFLICKER_TDE) { + blit_opt->antiflicker_level = OT_FB_LAYER_ANTIFLICKER_NONE; + } + + blit_opt->param = &(par->layer_id); + + if (par->display_info.rotate_mode == OT_FB_ROTATE_180) { + blit_opt->mirror_mode = OT_FB_MIRROR_BOTH; + } else { + blit_opt->mirror_mode = par->display_info.mirror_mode; + } +} + +static td_void gfbg_refresh_1buf_prepare_global_refresh(const ot_fb_buf *canvas_buf, ot_fb_buf *dst_rect, + gfbg_blit_opt *blit_opt) +{ + if (canvas_buf->canvas.height != dst_rect->canvas.height || canvas_buf->canvas.width != dst_rect->canvas.width) { + /* Rotate 0 or 180 degrees, zoomed, then global refresh */ + blit_opt->scale = TD_TRUE; + + dst_rect->update_rect.x = 0; + dst_rect->update_rect.y = 0; + dst_rect->update_rect.width = dst_rect->canvas.width; + dst_rect->update_rect.height = dst_rect->canvas.height; + } else { + /* Rotate 0 or 180 degrees, no zoomed, then partial refresh */ + dst_rect->update_rect = canvas_buf->update_rect; + } +} + +static td_void gfbg_refresh_1buf_prepare_compress(volatile gfbg_compress_info *compress_info, ot_fb_buf *dst_rect, + gfbg_par *par, gfbg_blit_opt *blit_opt) +{ + td_s32 ret; + unsigned long lock_flag; + osal_spin_lock_irqsave(&par->lock, &lock_flag); + if (compress_info->compress_open) { + /* + * This is just updating the refresh area. The refresh flag is first set to FALSE to + * indicate that the TDE has not been moved yet, and is set to TRUE in the TDE callback. + */ + ret = memcpy_s((void *)&compress_info->update_rect, sizeof(ot_fb_rect), &dst_rect->update_rect, + sizeof(ot_fb_rect)); + gfbg_unlock_unequal_eok_return_void(ret, &par->lock, &lock_flag); + compress_info->update_finished = TD_FALSE; + blit_opt->compress = TD_TRUE; + } else { + blit_opt->compress = TD_FALSE; + } + + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); +} + +static td_s32 gfbg_refresh_1buf_blit(const ot_fb_buf *canvas_buf, const ot_fb_buf *dst_rect, + const gfbg_blit_opt *blit_opt) +{ + ot_tde_export_func *tde_export_func = TD_NULL; + + tde_export_func = func_entry(ot_tde_export_func, OT_ID_TDE); + if ((tde_export_func == TD_NULL) || (tde_export_func->drv_tde_module_begin_job == TD_NULL) || + (tde_export_func->drv_tde_module_end_job == TD_NULL)) { + gfbg_error("can't get TDE export function, it may be TDE module has not been inserted!\n"); + return TD_FAILURE; + } + /* + * The user buf is used as the source by blit, and the user buf is moved to the display buf with + * the target set (with the target showing the buff address) as the target. + */ + if (gfbg_drv_blit(canvas_buf, dst_rect, blit_opt, TD_TRUE) < 0) { + return TD_FAILURE; + } + return TD_SUCCESS; +} +#ifdef CONFIG_GFBG_LOW_DELAY_SUPPORT +static td_bool gfbg_refresh_check_low_delay_support(const gfbg_par *par, const ot_fb_surface *canvas) +{ + if (par->refresh_info.buf_mode == OT_FB_LAYER_BUF_ONE && + (par->display_info.rotate_mode == OT_FB_ROTATE_90 || + par->display_info.rotate_mode == OT_FB_ROTATE_270)) { + gfbg_info("one buf mode and 90 degree or 270 degree rotations do not support low delay!\n"); + return TD_FALSE; + } + + if (par->refresh_info.buf_mode == OT_FB_LAYER_BUF_ONE && + (par->display_info.mirror_mode == OT_FB_MIRROR_VER || + par->display_info.mirror_mode == OT_FB_MIRROR_BOTH)) { + gfbg_info("one buf mode and ver mirror do not support low delay!\n"); + return TD_FALSE; + } + + if (canvas->width < GFBG_MIN_LOW_DELAY_WIDTH && canvas->height < GFBG_MIN_LOW_DELAY_HEIGHT) { + gfbg_info("low latency is not supported when the width is less than 1920 and height is less than 1080!\n"); + return TD_FALSE; + } + return TD_TRUE; +} +#endif +/* This function has a lock operation, so you can't call it if the caller has a lock operation. */ +static td_s32 gfbg_refresh_1buf(td_u32 layer_id, const ot_fb_buf *canvas_buf) +{ + struct fb_info *info = g_layer[layer_id].info; + gfbg_par *par = (gfbg_par *)info->par; + gfbg_display_info *display_info = &par->display_info; + gfbg_refresh_info *refresh_info = &par->refresh_info; + gfbg_dispbuf_info *display_buf_info = &refresh_info->disp_buf_info; + volatile gfbg_compress_info *compress_info = &par->compress_info; + gfbg_osd_data osd_data; + td_s32 ret; + gfbg_blit_opt blit_opt = {0}; + ot_fb_buf dst_rect; + + ret = gfbg_refresh_1buf_prepare_dst(&dst_rect, par, display_info, display_buf_info, info); + if (ret != TD_SUCCESS) { + return ret; + } + + gfbg_refresh_1buf_prepare_addr(refresh_info, layer_id, &osd_data, info, &dst_rect); + + gfbg_refresh_1buf_prepare_opt(&blit_opt, par); + + gfbg_refresh_1buf_prepare_global_refresh(canvas_buf, &dst_rect, &blit_opt); + + gfbg_refresh_1buf_prepare_compress(compress_info, &dst_rect, par, &blit_opt); + +#ifdef CONFIG_GFBG_LOW_DELAY_SUPPORT + if (is_layer_support_low_delay(layer_id) == TD_TRUE && + gfbg_refresh_check_low_delay_support(par, &(canvas_buf->canvas)) == TD_TRUE) { + blit_opt.is_sync = TD_TRUE; + blit_opt.block = TD_TRUE; + } +#endif + + ret = gfbg_refresh_1buf_blit(canvas_buf, &dst_rect, &blit_opt); + if (ret != TD_SUCCESS) { + return ret; + } + + display_buf_info->refresh_handle = ret; + ret = memcpy_s(&(refresh_info->user_buffer), sizeof(ot_fb_buf), canvas_buf, sizeof(ot_fb_buf)); + gfbg_unequal_eok_return(ret); + return TD_SUCCESS; +} + +/* unit rect */ +static td_void gfbg_unite_rect(ot_fb_rect *dst_rect, const ot_fb_rect *src_rect) +{ + td_s32 ret; + ot_fb_rect rect; + rect.x = (dst_rect->x < src_rect->x) ? dst_rect->x : src_rect->x; + rect.y = (dst_rect->y < src_rect->y) ? dst_rect->y : src_rect->y; + rect.width = ((dst_rect->x + dst_rect->width) > (src_rect->x + src_rect->width)) ? + (dst_rect->x + dst_rect->width - rect.x) : (src_rect->x + src_rect->width - rect.x); + rect.height = ((dst_rect->y + dst_rect->height) > (src_rect->y + src_rect->height)) ? + (dst_rect->y + dst_rect->height - rect.y) : (src_rect->y + src_rect->height - rect.y); + ret = memcpy_s(dst_rect, sizeof(ot_fb_rect), &rect, sizeof(ot_fb_rect)); + gfbg_unequal_eok_return_void(ret); + return; +} + +/* check these two rectangle cover each other */ +static td_bool gfbg_iscontain(ot_fb_rect parent_rect, ot_fb_rect child_rect) +{ + ot_fb_point point; + point.x_pos = child_rect.x; + point.y_pos = child_rect.y; + if ((point.x_pos < parent_rect.x) || (point.x_pos > (parent_rect.x + parent_rect.width)) || + (point.y_pos < parent_rect.y) || (point.y_pos > (parent_rect.y + parent_rect.height))) { + return TD_FALSE; + } + point.x_pos = child_rect.x + child_rect.width; + point.y_pos = child_rect.y + child_rect.height; + if ((point.x_pos < parent_rect.x) || (point.x_pos > (parent_rect.x + parent_rect.width)) || + (point.y_pos < parent_rect.y) || (point.y_pos > (parent_rect.y + parent_rect.height))) { + return TD_FALSE; + } + return TD_TRUE; +} + +static td_s32 refresh_2buf_prepare_back_buf(const struct fb_info *info, ot_fb_buf *back_buf, td_u32 *bytes_per_pixel) +{ + gfbg_par *par = (gfbg_par *)info->par; + gfbg_refresh_info *refresh_info = &par->refresh_info; + gfbg_display_info *display_info = &par->display_info; + + refresh_info->disp_buf_info.need_flip = TD_FALSE; + refresh_info->disp_buf_info.refresh_handle = 0; + + back_buf->canvas.format = par->color_format; + back_buf->canvas.height = display_info->display_height; + back_buf->canvas.width = display_info->display_width; + back_buf->canvas.pitch = gfbg_get_line_length(info); + + if (display_info->rotate_mode == OT_FB_ROTATE_90 || display_info->rotate_mode == OT_FB_ROTATE_270) { + back_buf->canvas.width = display_info->display_height; + back_buf->canvas.height = display_info->display_width; + if (back_buf->canvas.format == OT_FB_FORMAT_ARGB1555 || back_buf->canvas.format == OT_FB_FORMAT_ARGB4444) { + *bytes_per_pixel = 2; /* 2 bit per pixel */ + } else if (back_buf->canvas.format == OT_FB_FORMAT_ARGB8888) { + *bytes_per_pixel = 4; /* 4 bit per pixel */ + } + back_buf->canvas.pitch = ((*bytes_per_pixel * back_buf->canvas.width + GFBG_ALIGN - 1) / GFBG_ALIGN) * + GFBG_ALIGN; + + if ((par->color_format != OT_FB_FORMAT_ARGB4444) && (par->color_format != OT_FB_FORMAT_ARGB1555) && + (par->color_format != OT_FB_FORMAT_ARGB8888)) { + gfbg_error("The rotate mode only support FB_FORMAT_ARGB4444,FB_FORMAT_ARGB1555," + "FB_FORMAT_ARGB8888 which is %d\n!\n", par->color_format); + return TD_FAILURE; + } + back_buf->canvas.phys_addr = par->rotate_vb; + } else { + /* Set the background buf as the target, get the free buf to the background buf */ + gfbg_get_idledispbuf(par, (td_phys_addr_t*)(&back_buf->canvas.phys_addr)); + } + return TD_SUCCESS; +} + +static td_void refresh_2buf_get_new_rect(const ot_fb_buf *canvas_buf, const ot_fb_buf *back_buf, + ot_fb_rect *new_union_rect, gfbg_blit_opt *blit_opt) +{ + drv_tde_rect src_rect = {0}; + drv_tde_rect dst_rect = {0}; + drv_tde_rect inner_src_rect = {0}; + drv_tde_rect inner_dst_rect = {0}; + + if (canvas_buf->canvas.height != back_buf->canvas.height || canvas_buf->canvas.width != back_buf->canvas.width) { + src_rect.width = canvas_buf->canvas.width; + src_rect.height = canvas_buf->canvas.height; + dst_rect.width = back_buf->canvas.width; + dst_rect.height = back_buf->canvas.height; + inner_src_rect.pos_x = canvas_buf->update_rect.x; + inner_src_rect.pos_y = canvas_buf->update_rect.y; + inner_src_rect.width = (td_u32)canvas_buf->update_rect.width; + inner_src_rect.height = (td_u32)canvas_buf->update_rect.height; + tde_cal_scale_rect_gfbg(&src_rect, &dst_rect, &inner_src_rect, &inner_dst_rect); + + new_union_rect->x = inner_dst_rect.pos_x; + new_union_rect->y = inner_dst_rect.pos_y; + new_union_rect->width = (td_s32)inner_dst_rect.width; + new_union_rect->height = (td_s32)inner_dst_rect.height; + blit_opt->scale = TD_TRUE; + } else { + *new_union_rect = canvas_buf->update_rect; + } + return; +} + +static td_s32 refresh_2buf_blit(gfbg_par *par, td_phys_addr_t osd_buf_addr, ot_fb_buf *back_buf, + ot_fb_rect *new_union_rect) +{ + td_s32 ret; + gfbg_blit_opt tmp = {0}; + gfbg_refresh_info *refresh_info = &par->refresh_info; + gfbg_display_info *display_info = &par->display_info; + ot_fb_buf fore_buf = {0}; + td_phys_addr_t work_buf_addr = 0; + + gfbg_get_workdispbuf(par, &work_buf_addr); + + if ((refresh_info->disp_buf_info.fliped == TD_FALSE) || + ((osd_buf_addr != work_buf_addr) && (par->compress_info.compress_open == TD_FALSE))) { + return TD_SUCCESS; + } + /* Background as a target pointing to an idle buf */ + ret = memcpy_s(&fore_buf, sizeof(ot_fb_buf), back_buf, sizeof(ot_fb_buf)); + gfbg_unequal_eok_return(ret); + /* Foreground as a source points to the buf at work */ + gfbg_get_workdispbuf(par, (td_phys_addr_t*)(&fore_buf.canvas.phys_addr)); + /* The union rect is also used as an update area for the foreground and background. */ + ret = memcpy_s(&fore_buf.update_rect, sizeof(ot_fb_rect), &refresh_info->disp_buf_info.union_rect, + sizeof(ot_fb_rect)); + gfbg_unequal_eok_return(ret); + ret = memcpy_s(&back_buf->update_rect, sizeof(ot_fb_rect), &fore_buf.update_rect, sizeof(ot_fb_rect)); + gfbg_unequal_eok_return(ret); + (td_void)memset_s(&tmp, sizeof(gfbg_blit_opt), 0x0, sizeof(gfbg_blit_opt)); + /* blit with union rect */ + if ((display_info->rotate_mode != OT_FB_ROTATE_90) && (display_info->rotate_mode != OT_FB_ROTATE_270)) { + if (gfbg_iscontain(*new_union_rect, refresh_info->disp_buf_info.union_rect) == TD_FALSE) { + if (gfbg_drv_blit(&fore_buf, back_buf, &tmp, TD_TRUE) < 0) { + gfbg_error("blit err!\n"); + return TD_FAILURE; + } + } + } + /* clear union rect */ + (td_void)memset_s(&(refresh_info->disp_buf_info.union_rect), sizeof(ot_fb_rect), 0, sizeof(ot_fb_rect)); + + refresh_info->disp_buf_info.fliped = TD_FALSE; + return TD_SUCCESS; +} + +static td_void refresh_2buf_prepare_opt(gfbg_par *par, const ot_fb_buf *canvas_buf, ot_fb_buf *back_buf, + td_u32 bytes_per_pixel, gfbg_blit_opt *blit_opt) +{ + gfbg_display_info *display_info = &par->display_info; + blit_opt->call_back = TD_TRUE; + blit_opt->param = &(par->layer_id); + + if (display_info->antiflicker_mode == GFBG_ANTIFLICKER_TDE) { + blit_opt->antiflicker_level = OT_FB_LAYER_ANTIFLICKER_NONE; + } + if (blit_opt->scale == TD_TRUE) { + /* actual area, calculate by TDE, here is just use for let pass the test */ + back_buf->update_rect.x = 0; + back_buf->update_rect.y = 0; + back_buf->update_rect.width = back_buf->canvas.width; + back_buf->update_rect.height = back_buf->canvas.height; + } else { + back_buf->update_rect = canvas_buf->update_rect; + } + + if (par->display_info.rotate_mode == OT_FB_ROTATE_90 || par->display_info.rotate_mode == OT_FB_ROTATE_270) { + back_buf->canvas.height = par->display_info.display_width; + back_buf->canvas.width = par->display_info.display_height; + back_buf->canvas.pitch = ((bytes_per_pixel * back_buf->canvas.width + + (GFBG_ALIGN - 1)) / GFBG_ALIGN) * GFBG_ALIGN; + back_buf->update_rect = canvas_buf->update_rect; + } + + if (display_info->rotate_mode == OT_FB_ROTATE_180) { + blit_opt->mirror_mode = OT_FB_MIRROR_BOTH; + } else { + blit_opt->mirror_mode = display_info->mirror_mode; + } + return; +} + +static td_s32 refresh_2buf_prepare_compress(gfbg_par *par, const ot_fb_buf *back_buf, gfbg_blit_opt *blit_opt) +{ + unsigned long lock_flag; + td_s32 ret; + + osal_spin_lock_irqsave(&par->lock, &lock_flag); + if (par->compress_info.compress_open) { + /* + * This is just updating the refresh area. The refresh flag is first set to FALSE + * to indicate that the TDE has not been moved yet, and is set to TRUE in the TDE callback. + */ + ret = memcpy_s((void *)&par->compress_info.update_rect, sizeof(ot_fb_rect), &back_buf->update_rect, + sizeof(ot_fb_rect)); + gfbg_unlock_unequal_eok_return(ret, &par->lock, &lock_flag); + par->compress_info.update_finished = TD_FALSE; + blit_opt->compress = TD_TRUE; + } else if (par->compress_info.is_economize_memory == TD_TRUE) { + gfbg_error("memory not enough ,should be start compress!\n"); + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + return TD_FAILURE; + } else { + blit_opt->compress = TD_FALSE; + } + + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + return TD_SUCCESS; +} + +static td_void refresh_2buf_update_rect(gfbg_refresh_info *refresh_info, const ot_fb_rect *new_union_rect) +{ + td_s32 ret; + if ((refresh_info->disp_buf_info.union_rect.width == 0) || (refresh_info->disp_buf_info.union_rect.height == 0)) { + ret = memcpy_s(&refresh_info->disp_buf_info.union_rect, sizeof(ot_fb_rect), new_union_rect, sizeof(ot_fb_rect)); + gfbg_unequal_eok_return_void(ret); + } else { + gfbg_unite_rect(&refresh_info->disp_buf_info.union_rect, new_union_rect); + } + return; +} + +static td_void gfbg_dynamic_set_compress(const struct fb_info *info) +{ + td_u32 uncompress_stride; + gfbg_par *par = (gfbg_par *)info->par; + + uncompress_stride = (info->var.xres_virtual * info->var.bits_per_pixel / 8 + /* 8 one byte */ + GFBG_ALIGNMENT) & (~GFBG_ALIGNMENT); + if (uncompress_stride == info->fix.line_length) { + /* last and next frame are uncompress */ + return; + } + + if (gfbg_check_memory_enough(info, uncompress_stride) == TD_TRUE) { + /* memory enough to compress to uncompress */ + return; + } else { + if (par->compress_info.compress_open == TD_FALSE) { + par->compress_info.compress_open = TD_TRUE; + gfbg_error("memory not enough ,should not be refresh by uncompress!\n"); + } + } + return; +} + +/* This function has a lock operation, so you can't call it if the caller has a lock operation. */ +static td_s32 gfbg_refresh_2buf(td_u32 layer_id, const ot_fb_buf *canvas_buf) +{ + struct fb_info *info = g_layer[layer_id].info; + gfbg_par *par = (gfbg_par *)info->par; + gfbg_refresh_info *refresh_info = &par->refresh_info; + gfbg_blit_opt blit_opt = {0}; + ot_fb_buf back_buf = {0}; + ot_fb_rect new_union_rect = {0}; + unsigned long lock_flag; + td_phys_addr_t osd_buf_addr; + td_u32 bytes_per_pixel = 2; + td_s32 ret; + /* + * Refresh task submitted between VO vertical timing interrupt and frame start interrupt + * Will cause TDE/VGS to write the buffer being displayed, and a split screen will appear. + * Blocked here, it is forbidden to submit the refresh task during this time. + */ + ret = wait_event_timeout(par->do_refresh_job, par->refresh_info.do_refresh_job, + (td_s32)msecs_to_jiffies(40)); /* 40 for timeout */ + if (ret == 0) { + gfbg_error("wait timeout!\n"); + } + + refresh_info->refresh_num++; + + /* get osd buffer addr */ + g_drv_ops.gfbg_drv_get_layer_addr(layer_id, &osd_buf_addr); + osal_spin_lock_irqsave(&par->lock, &lock_flag); + /* dynamic change compress,when compress to uncompress, reset state */ + gfbg_dynamic_set_compress(info); + /* prepare back buf and get bytes_per_pixel */ + if (refresh_2buf_prepare_back_buf(info, &back_buf, &bytes_per_pixel) != TD_SUCCESS) { + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + return TD_FAILURE; + } + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + /* according to the hw arithmetic, calculate source and dst fresh rectangle */ + refresh_2buf_get_new_rect(canvas_buf, &back_buf, &new_union_rect, &blit_opt); + /* + * We should check is address changed, + * for make sure that the address configured to the hw register is in effec + */ + osal_spin_lock_irqsave(&par->lock, &lock_flag); + /* refresh_2buf_blit */ + if (refresh_2buf_blit(par, osd_buf_addr, &back_buf, &new_union_rect) != TD_SUCCESS) { + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + return TD_FAILURE; + } + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + + /* update union rect */ + refresh_2buf_update_rect(refresh_info, &new_union_rect); + + /* prepare opt */ + refresh_2buf_prepare_opt(par, canvas_buf, &back_buf, bytes_per_pixel, &blit_opt); + + /* prepare compress */ + if (refresh_2buf_prepare_compress(par, &back_buf, &blit_opt) != TD_SUCCESS) { + return TD_FAILURE; + } + + /* blit with refresh rect */ + ret = gfbg_drv_blit(canvas_buf, &back_buf, &blit_opt, TD_TRUE); + if (ret < 0) { + gfbg_error("blit err:0x%x!\n", ret); + return TD_FAILURE; + } + + refresh_info->disp_buf_info.refresh_handle = ret; + + ret = memcpy_s(&(refresh_info->user_buffer), sizeof(ot_fb_buf), canvas_buf, sizeof(ot_fb_buf)); + gfbg_unequal_eok_return(ret); + return TD_SUCCESS; +} + +static td_s32 gfbg_wait_regconfig_work(td_u32 layer_id) +{ + td_s32 ret; + gfbg_par *par = TD_NULL; + + if (layer_id >= GFBG_MAX_LAYER_NUM) { + return TD_FAILURE; + } + par = (gfbg_par *)g_layer[layer_id].info->par; + if (par == TD_NULL) { + return TD_FAILURE; + } + par->vblflag = 0; + /* Assuming TDE is fast enough, 40ms */ + ret = wait_event_timeout(par->vbl_event, par->vblflag, (td_s32)msecs_to_jiffies(40)); + if (ret == 0) { + gfbg_error("Wait vblank failed!"); + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +static td_s32 refresh_2buf_immediate_prepare_back_buf(const struct fb_info *info, ot_fb_buf *back_buf, + td_u32 *bytes_per_pixel, td_u32 index) +{ + gfbg_par *par = (gfbg_par *)info->par; + gfbg_display_info *display_info = &par->display_info; + gfbg_refresh_info *refresh_info = &par->refresh_info; + + /* forbid changing display buffer in interrupt handle */ + refresh_info->disp_buf_info.fliped = TD_FALSE; + refresh_info->disp_buf_info.need_flip = TD_FALSE; + refresh_info->disp_buf_info.refresh_handle = 0; + + back_buf->canvas.format = par->color_format; + back_buf->canvas.height = display_info->display_height; + back_buf->canvas.width = display_info->display_width; + back_buf->canvas.pitch = gfbg_get_line_length(info); + if (display_info->rotate_mode == OT_FB_ROTATE_90 || display_info->rotate_mode == OT_FB_ROTATE_270) { + back_buf->canvas.width = display_info->display_height; + back_buf->canvas.height = display_info->display_width; + if (back_buf->canvas.format == OT_FB_FORMAT_ARGB1555 || back_buf->canvas.format == OT_FB_FORMAT_ARGB4444) { + *bytes_per_pixel = 2; /* 2 depth per pixel */ + } else if (back_buf->canvas.format == OT_FB_FORMAT_ARGB8888) { + *bytes_per_pixel = 4; /* 4 depth per pixel */ + } + back_buf->canvas.pitch = (((*bytes_per_pixel)*back_buf->canvas.width + GFBG_ALIGN - 1) / GFBG_ALIGN) * + GFBG_ALIGN; + if ((par->color_format != OT_FB_FORMAT_ARGB4444) && (par->color_format != OT_FB_FORMAT_ARGB1555) && + (par->color_format != OT_FB_FORMAT_ARGB8888)) { + gfbg_error("The rotate mode only support ARGB4444 and ARGB1555 which is %d\n!\n", par->color_format); + return TD_FAILURE; + } + back_buf->canvas.phys_addr = par->rotate_vb; + } else { + back_buf->canvas.phys_addr = refresh_info->disp_buf_info.phys_addr[1 - index]; + } + return TD_SUCCESS; +} + +static td_s32 refresh_2buf_imediate_blit(gfbg_par *par, ot_fb_buf *back_buf, ot_fb_rect *new_union_rect, td_u32 index) +{ + gfbg_display_info *display_info = &par->display_info; + gfbg_refresh_info *refresh_info = &par->refresh_info; + ot_fb_buf fore_buf = {0}; + gfbg_blit_opt tmp_opt = {0}; + unsigned long lock_flag; + td_s32 ret; + + osal_spin_lock_irqsave(&par->lock, &lock_flag); + if (display_info->rotate_mode != OT_FB_ROTATE_90 && display_info->rotate_mode != OT_FB_ROTATE_270) { + /* + * because reverse, the 2 buffer needed to sync contain, + * if the fresh area has cover last fresh area, then no need to sync + */ + if (!gfbg_iscontain(*new_union_rect, refresh_info->disp_buf_info.union_rect) && + refresh_info->disp_buf_info.union_rect.width && refresh_info->disp_buf_info.union_rect.height) { + ret = memcpy_s(&fore_buf, sizeof(ot_fb_buf), back_buf, sizeof(ot_fb_buf)); + gfbg_unlock_unequal_eok_return(ret, &par->lock, &lock_flag); + fore_buf.canvas.phys_addr = refresh_info->disp_buf_info.phys_addr[index]; + ret = memcpy_s(&fore_buf.update_rect, sizeof(ot_fb_rect), &refresh_info->disp_buf_info.union_rect, + sizeof(ot_fb_rect)); + gfbg_unlock_unequal_eok_return(ret, &par->lock, &lock_flag); + ret = memcpy_s(&back_buf->update_rect, sizeof(ot_fb_rect), &fore_buf.update_rect, sizeof(ot_fb_rect)); + gfbg_unlock_unequal_eok_return(ret, &par->lock, &lock_flag); + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + if (gfbg_drv_blit(&fore_buf, back_buf, &tmp_opt, TD_TRUE) < 0) { + return TD_FAILURE; + } + osal_spin_lock_irqsave(&par->lock, &lock_flag); + } + } + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + return TD_SUCCESS; +} + +static td_s32 refresh_2buf_imediate_prepare_opt(gfbg_par *par, const ot_fb_buf *canvas_buf, ot_fb_buf *back_buf, + gfbg_blit_opt *blit_opt) +{ + gfbg_display_info *display_info = &par->display_info; + td_s32 ret; + + blit_opt->call_back = TD_TRUE; + blit_opt->param = &(par->layer_id); + blit_opt->block = TD_TRUE; + + if (display_info->antiflicker_mode == GFBG_ANTIFLICKER_TDE) { + blit_opt->antiflicker_level = OT_FB_LAYER_ANTIFLICKER_NONE; + } + + if (blit_opt->scale == TD_TRUE) { + /* actual area, calculate by TDE, here is just use for let pass the test */ + back_buf->update_rect.x = 0; + back_buf->update_rect.y = 0; + back_buf->update_rect.width = back_buf->canvas.width; + back_buf->update_rect.height = back_buf->canvas.height; + } else { + back_buf->update_rect = canvas_buf->update_rect; + } + + if (display_info->rotate_mode == OT_FB_ROTATE_180) { + blit_opt->mirror_mode = OT_FB_MIRROR_BOTH; + } else { + blit_opt->mirror_mode = display_info->mirror_mode; + } + + if (par->compress_info.compress_open) { + /* + * This is just updating the refresh area. The refresh flag is first set to FALSE to + * indicate that the TDE has not been moved yet, and is set to TRUE in the TDE callback. + */ + ret = memcpy_s((void *)&par->compress_info.update_rect, sizeof(ot_fb_rect), &back_buf->update_rect, + sizeof(ot_fb_rect)); + gfbg_unequal_eok_return(ret); + par->compress_info.update_finished = TD_FALSE; + blit_opt->compress = TD_TRUE; + } else if (par->compress_info.is_economize_memory == TD_TRUE) { + gfbg_error("memory not enough ,should be start compress!\n"); + return TD_FAILURE; + } + return TD_SUCCESS; +} + +static td_void refresh_2buf_imediate_backup_buffer(const struct fb_info *info, const ot_fb_buf *back_buf, + const ot_fb_rect *new_union_rect, const gfbg_blit_opt *blit_opt, + td_u32 *index) +{ + gfbg_par *par = (gfbg_par *)info->par; + gfbg_refresh_info *refresh_info = &par->refresh_info; + volatile gfbg_compress_info *compress_info = &par->compress_info; + td_u32 buf_size; + unsigned long lock_flag; + td_s32 ret; + ot_unused(back_buf); + ot_unused(blit_opt); + + buf_size = ((gfbg_get_line_length(info) * gfbg_get_yres(info)) + GFBG_ALIGNMENT) & (~GFBG_ALIGNMENT); + osal_spin_lock_irqsave(&par->lock, &lock_flag); + *index = 1 - *index; + refresh_info->disp_buf_info.index_for_int = *index; + par->modifying = TD_TRUE; + par->param_modify_mask |= GFBG_LAYER_PARAMODIFY_DISPLAYADDR; + refresh_info->screen_addr = refresh_info->disp_buf_info.phys_addr[*index]; + refresh_info->gb_screen_addr = refresh_info->screen_addr + buf_size / 2; /* 2 for half */ + refresh_info->disp_buf_info.compress = compress_info->compress_open; + par->modifying = TD_FALSE; + + if (par->compress_info.compress_open) { + par->compress_info.update_finished = TD_TRUE; + ret = memcpy_s((ot_fb_rect*)(&par->compress_info.update_rect), sizeof(ot_fb_rect), new_union_rect, + sizeof(ot_fb_rect)); + gfbg_unlock_unequal_eok_return_void(ret, &par->lock, &lock_flag); + /* + * When blocking, if there is a callback, + * still get FrameSize0 and FrameSize1 here as early as possible. + */ + } + + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + return; +} + +/* + * In this function we should wait the new contain has been show on the screen before return, + * and the operations such as address configuration no needed do in interrupt handle + */ +static td_s32 gfbg_refresh_2buf_immediate_display(td_u32 layer_id, const ot_fb_buf *canvas_buf) +{ + struct fb_info *info = g_layer[layer_id].info; + gfbg_par *par = (gfbg_par *)info->par; + gfbg_refresh_info *refresh_info = &par->refresh_info; + gfbg_blit_opt blit_opt = {0}; + td_u32 index = refresh_info->disp_buf_info.index_for_int; + ot_fb_buf back_buf = {0}; + td_s32 ret; + ot_fb_rect new_union_rect = {0}; + unsigned long lock_flag; + td_u32 bytes_per_pixel = 2; + + /* + * Refresh task submitted between VO vertical timing interrupt and frame start interrupt + * Will cause TDE/VGS to write the buffer being displayed, and a split screen will appear. + * Blocked here, it is forbidden to submit the refresh task during this time. + */ + if (wait_event_timeout(par->do_refresh_job, par->refresh_info.do_refresh_job, + (td_s32)msecs_to_jiffies(40)) == 0) { /* 40 for timeout */ + osal_printk("Func:%s, Line:%d, wait event timeout.\n", __FUNCTION__, __LINE__); + } + /* + * TDE use the blocking mode + * Immediate refresh mode requires blocking mode, non-callback mode, + * avoiding callback mode when scrolling subtitles. + * Return immediately. Maybe the next time the user quickly call the interface refresh, + * it may flush the last content. + */ + refresh_info->refresh_num++; + + osal_spin_lock_irqsave(&par->lock, &lock_flag); + /* dynamic change compress,when compress to uncompress, reset state */ + gfbg_dynamic_set_compress(info); + /* prepare for back buf and get bytes per pixel */ + if (refresh_2buf_immediate_prepare_back_buf(info, &back_buf, &bytes_per_pixel, index) != TD_SUCCESS) { + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + return TD_FAILURE; + } + /* according to the hw arithmetic, calculate source and Dst fresh rectangle */ + refresh_2buf_get_new_rect(canvas_buf, &back_buf, &new_union_rect, &blit_opt); + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + /* blit */ + if (refresh_2buf_imediate_blit(par, &back_buf, &new_union_rect, index) != TD_SUCCESS) { + return TD_FAILURE; + } + + osal_spin_lock_irqsave(&par->lock, &lock_flag); + /* record the fresh area */ + ret = memcpy_s(&refresh_info->disp_buf_info.union_rect, sizeof(ot_fb_rect), &new_union_rect, sizeof(ot_fb_rect)); + gfbg_unlock_unequal_eok_return(ret, &par->lock, &lock_flag); + /* prepare for opt */ + if (refresh_2buf_imediate_prepare_opt(par, canvas_buf, &back_buf, &blit_opt) != TD_SUCCESS) { + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + return TD_FAILURE; + } + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + + /* blit with refresh rect */ + if (gfbg_drv_blit(canvas_buf, &back_buf, &blit_opt, TD_TRUE) < 0) { + return TD_FAILURE; + } + refresh_info->disp_buf_info.refresh_handle = ret; + /* set the backup buffer to register and show it */ + refresh_2buf_imediate_backup_buffer(info, &back_buf, &new_union_rect, &blit_opt, &index); + osal_spin_lock_irqsave(&par->lock, &lock_flag); + ret = memcpy_s(&(refresh_info->user_buffer), sizeof(ot_fb_buf), canvas_buf, sizeof(ot_fb_buf)); + gfbg_unlock_unequal_eok_return(ret, &par->lock, &lock_flag); + par->vblflag = 0; + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + /* wait the address register's configuration take effect before return */ + if (in_atomic() == TD_FALSE) { + gfbg_wait_regconfig_work(layer_id); + } + + return TD_SUCCESS; +} + +static td_void gfbg_refresh_again(td_u32 layer_id) +{ + struct fb_info *info = g_layer[layer_id].info; + gfbg_par *par = (gfbg_par *)info->par; + gfbg_refresh_info *refresh_info = &par->refresh_info; + ot_fb_buf canvas; + + /* Prerequisites for the canvas to be refreshed */ + if (!(par->param_modify_mask & GFBG_LAYER_PARAMODIFY_INRECT)) { + return; + } + + if (refresh_info->user_buffer.canvas.phys_addr == 0) { + return; + } + + if (refresh_info->buf_mode == OT_FB_LAYER_BUF_NONE) { + return; + } + /* Fills the canvas object with refresh information from private data for refresh. */ + canvas = refresh_info->user_buffer; + canvas.update_rect.x = 0; + canvas.update_rect.y = 0; + canvas.update_rect.width = canvas.canvas.width; + canvas.update_rect.height = canvas.canvas.height; + gfbg_refresh(layer_id, &canvas, refresh_info->buf_mode); +} + +static td_s32 gfbg_disp_check_param(const struct fb_info *info, td_u32 width, td_u32 height) +{ + gfbg_par *par = (gfbg_par *)info->par; + ot_fb_size max_screen_size = {0}; + td_u32 pitch; + + if (!g_drv_ops.capability[par->layer_id].is_vo_scale) { + gfbg_get_maxscreensize(par, &max_screen_size.width, &max_screen_size.height); +#ifdef CONFIG_GFBG_RESOLUTION_SUPPORT_SQUARE + max_screen_size.height = g_drv_ops.capability[par->layer_id].max_height; +#endif + if ((par->layer_id == 3 || par->layer_id == 4) && /* 3 G3 clut2 and clut4 support 4K */ + ((gfbg_get_bits_per_pixel(info) == 4) || (gfbg_get_bits_per_pixel(info) == 2))) { /* 4,2 bits */ + if ((width > max_screen_size.width) || (height > max_screen_size.height) || + (width > GFBG_MAX_LAYER_WIDTH_CLUT_G3) || (height > GFBG_MAX_LAYER_HEIGTH_CLUT_G3)) { + gfbg_error("(%u, %u)larger than the max size of the screen(%u, %u) or the layer(%u, %u)!\n", width, + height, max_screen_size.width, max_screen_size.height, GFBG_MAX_LAYER_WIDTH_CLUT_G3, + GFBG_MAX_LAYER_HEIGTH_CLUT_G3); + return TD_FAILURE; + } + } else { + if ((width > max_screen_size.width) || (height > max_screen_size.height) || + (width > g_drv_ops.capability[par->layer_id].max_width) || + (height > g_drv_ops.capability[par->layer_id].max_height)) { + gfbg_error("(%u, %u)larger than the max size of the screen(%u, %u) or the layer(%u, %u)!\n", width, + height, max_screen_size.width, max_screen_size.height, + g_drv_ops.capability[par->layer_id].max_width, + g_drv_ops.capability[par->layer_id].max_height); + return TD_FAILURE; + } + } + } + /* 3 is 8 bits */ + pitch = (((width * gfbg_get_bits_per_pixel(info)) >> 3) + GFBG_ALIGNMENT) & (~GFBG_ALIGNMENT); + if (gfbg_check_mem_enough(info, pitch, height) != TD_SUCCESS) { + gfbg_error("++ setdispsize .memory is not enough!\n"); + return TD_FAILURE; + } + return TD_SUCCESS; +} + +/* + * This function has a lock inside, and there is a call to the sleep function. + * Before calling this function, you must first unlock the spin lock. + */ +#ifdef __LITEOS__ +static td_s32 gfbg_disp_setdispsize(td_u32 layer_id, td_u32 width, td_u32 height) +{ + struct fb_info *info = g_layer[layer_id].info; + gfbg_par *par = (gfbg_par *)info->par; + gfbg_display_info *display_info = &par->display_info; + td_u32 pitch; + unsigned long lock_flag; + + osal_spin_lock_irqsave(&par->lock, &lock_flag); + if ((display_info->display_width == width) && (display_info->display_height == height)) { + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + return TD_SUCCESS; + } + /* + * for width and height check + * width and height should less than max_screen_size + */ + if (gfbg_disp_check_param(info, width, height) != TD_SUCCESS) { + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + return TD_FAILURE; + } + + display_info->display_width = width; + display_info->display_height = height; + par->param_modify_mask |= GFBG_LAYER_PARAMODIFY_INRECT; + + pitch = (((width * gfbg_get_bits_per_pixel(info)) >> 3) + GFBG_ALIGNMENT) & (~GFBG_ALIGNMENT); /* 3: 8bits */ + if (pitch > info->oinfo.stride) { + info->oinfo.stride = pitch; + info->oinfo.sarea.height = info->vinfo.yres = display_info->display_height; + info->oinfo.sarea.width = info->vinfo.xres = display_info->display_width; + par->param_modify_mask |= GFBG_LAYER_PARAMODIFY_STRIDE; + } + + gfbg_set_dispbufinfo(layer_id); + + if (!g_drv_ops.capability[par->layer_id].is_vo_scale) { + display_info->screen_width = width; + display_info->screen_height = height; + par->param_modify_mask |= GFBG_LAYER_PARAMODIFY_OUTRECT; + } + + /* + * here we need to think about how to resist flicker again, + * we use VO do flicker resist before , but now if the display H size is the same as the screen, + * VO will not do flicker resist, so should choose TDE to do flicker resist + */ + gfbg_select_antiflicker_mode(par); + osal_spin_unlock_irqrestore(&par->lock, lock_flag); + + return TD_SUCCESS; +} +#else +static td_void gfbg_fill_var_info(gfbg_display_info *display_info, struct fb_var_screeninfo *var) +{ + var->xres = display_info->display_width; + var->yres = display_info->display_height; + if (var->xres_virtual < display_info->display_width) { + var->xres_virtual = display_info->display_width; + } + + if (var->yres_virtual < display_info->display_height) { + var->yres_virtual = display_info->display_height; + } + return; +} + +static td_s32 gfbg_disp_setdispsize(td_u32 layer_id, td_u32 width, td_u32 height) +{ + struct fb_info *info = g_layer[layer_id].info; + gfbg_par *par = (gfbg_par *)info->par; + struct fb_var_screeninfo *var = &info->var; + struct fb_fix_screeninfo *fix = &info->fix; + gfbg_display_info *display_info = &par->display_info; + td_u32 pitch; + unsigned long lock_flag; +#ifdef CONFIG_COMPRESS_ECONOMIZE_MEMERY + gfbg_stride_attr attr = {0}; +#endif + osal_spin_lock_irqsave(&par->lock, &lock_flag); + if ((display_info->display_width == width) && (display_info->display_height == height)) { + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + return TD_SUCCESS; + } + /* + * for width and height check + * width and height should less than max_screen_size + */ + if (gfbg_disp_check_param(info, width, height) != TD_SUCCESS) { + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + return TD_FAILURE; + } + + display_info->display_width = width; + display_info->display_height = height; + par->param_modify_mask |= GFBG_LAYER_PARAMODIFY_INRECT; +#ifdef CONFIG_COMPRESS_ECONOMIZE_MEMERY + attr.is_lossless = TD_FALSE; + attr.is_losslessa = TD_FALSE; + attr.width = width; + attr.format = gfbg_getfmtbyargb(&var->red, &var->green, &var->blue, &var->transp, var->bits_per_pixel); + pitch = (((width * gfbg_get_bits_per_pixel(info))>> 3) + GFBG_ALIGNMENT) & (~GFBG_ALIGNMENT); /* 3: 8bits */ + gfbg_recalculate_stride(NULL, &pitch, &attr); +#else + pitch = (((width * gfbg_get_bits_per_pixel(info))>> 3) + GFBG_ALIGNMENT) & (~GFBG_ALIGNMENT); /* 3: 8bits */ +#endif + if (pitch > fix->line_length) { + fix->line_length = pitch; + par->param_modify_mask |= GFBG_LAYER_PARAMODIFY_STRIDE; + } + /* + * If the user calls FBIOPUT_LAYER_INFO to set display_width and display_height,then sync to xres yres, + * Otherwise, there will be an error in the memory address in gfbg_set_dispbufinfo. + */ + gfbg_fill_var_info(display_info, var); + gfbg_set_dispbufinfo(layer_id); + + if (!g_drv_ops.capability[par->layer_id].is_vo_scale) { + display_info->screen_width = width; + display_info->screen_height = height; + par->param_modify_mask |= GFBG_LAYER_PARAMODIFY_OUTRECT; + } + + /* + * here we need to think about how to resist flicker again, + * we use VO do flicker resist before , but now if the display H size is the same as the screen, + * VO will not do flicker resist, so should choose TDE to do flicker resist + */ + gfbg_select_antiflicker_mode(par); + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + + return TD_SUCCESS; +} +#endif + +/* + * we handle it by two case: + * case 1 : if VO support Zoom, we only change screen size, g_display size keep not change + * case 2: if VO can't support zoom, g_display size should keep the same as screen size + */ +static td_s32 gfbg_disp_setscreensize(td_u32 layer_id, td_u32 width, td_u32 height) +{ + struct fb_info *info = g_layer[layer_id].info; + gfbg_par *par = (gfbg_par *)info->par; + gfbg_display_info *display_info = &par->display_info; + + /* If the chip does not support scaling, it is consistent with the process of setting the display area. */ + if (!g_drv_ops.capability[par->layer_id].is_vo_scale) { + return gfbg_disp_setdispsize(layer_id, width, height); + } + + display_info->screen_width = width; + display_info->screen_height = height; + + par->param_modify_mask |= GFBG_LAYER_PARAMODIFY_OUTRECT; + + /* Here we need to think about how to resist flicker again, we use VO do flicker resist before , + * but now if the g_display H size is the same as the screen, VO will not do flicker resist, so should choose + * TDE to do flicker resist + */ + gfbg_select_antiflicker_mode(par); + + return TD_SUCCESS; +} + +static td_void gfbg_buf_freemem(td_phys_addr_t phyaddr) +{ + cmpi_mmz_free(phyaddr, TD_NULL); +} + +static td_s32 gfbg_freeccanbuf(gfbg_par *par) +{ + ot_fb_surface *canvas_sur = TD_NULL; + if (par == TD_NULL) { + return TD_FAILURE; + } + canvas_sur = &par->canvas_sur; + + if (canvas_sur->phys_addr != 0) { + gfbg_buf_freemem(canvas_sur->phys_addr); + } + canvas_sur->phys_addr = 0; + + if (par->rotate_vb != 0) { + cmpi_mmz_free(par->rotate_vb, TD_NULL); + par->rotate_vb = 0; + } + + return TD_SUCCESS; +} + +static td_void set_par_stride(struct fb_info *info) +{ + gfbg_par *par = (gfbg_par *)info->par; + gfbg_display_info *display_info = &par->display_info; + gfbg_refresh_info *refresh_info = &par->refresh_info; + td_u32 stride; + td_phys_addr_t display_addr; +#ifdef CONFIG_COMPRESS_ECONOMIZE_MEMERY + gfbg_stride_attr attr = {0}; + attr.is_lossless = TD_FALSE; + attr.is_losslessa = TD_FALSE; + attr.width = gfbg_get_xres_virtual(info); + attr.format = gfbg_getfmtbyargb(&info->var.red, &info->var.green, &info->var.blue, &info->var.transp, + info->var.bits_per_pixel); + stride = (((gfbg_get_xres_virtual(info) * gfbg_get_bits_per_pixel(info)) >> 3) + GFBG_ALIGNMENT) & /* 2^3 */ + (~GFBG_ALIGNMENT); + gfbg_recalculate_stride(NULL, &stride, &attr); +#else + stride = (((gfbg_get_xres_virtual(info) * gfbg_get_bits_per_pixel(info)) >> 3) + GFBG_ALIGNMENT) & /* 2^3 */ + (~GFBG_ALIGNMENT); +#endif + if (stride != gfbg_get_line_length(info) || (gfbg_get_yres(info) != display_info->y_res)) { +#ifdef __LITEOS__ + info->oinfo.stride = stride; +#else + info->fix.line_length = stride; +#endif + gfbg_set_dispbufinfo(par->layer_id); + par->param_modify_mask |= GFBG_LAYER_PARAMODIFY_STRIDE; + } + + display_addr = (gfbg_get_smem_start(info) + stride * gfbg_get_yoffset(info) + + gfbg_get_xoffset(info) * (gfbg_get_bits_per_pixel(info) >> 3)) & /* 3 /8bits */ + 0xfffffff0; /* 0xfffffff0 16 align */ + if (display_addr != refresh_info->screen_addr) { + refresh_info->screen_addr = display_addr; + par->param_modify_mask |= GFBG_LAYER_PARAMODIFY_DISPLAYADDR; + } + return; +} + +static td_s32 set_par_resolution(const struct fb_info *info) +{ + gfbg_par *par = (gfbg_par *)info->par; + gfbg_display_info *display_info = &par->display_info; + unsigned long lock_flag; + + osal_spin_lock_irqsave(&par->lock, &lock_flag); + if (gfbg_get_xres(info) != display_info->x_res || gfbg_get_yres(info) != display_info->y_res) { + if ((gfbg_get_xres(info) == 0) || (gfbg_get_yres(info) == 0)) { + if (par->show == TD_TRUE) { + par->show = TD_FALSE; + par->param_modify_mask |= GFBG_LAYER_PARAMODIFY_SHOW; + } + } + + /* + * The following two functions have a sleep operation, you must unlock before calling, + * and lock the global variable inside the function. + */ + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + if (gfbg_disp_setdispsize(par->layer_id, gfbg_get_xres(info), gfbg_get_yres(info)) != TD_SUCCESS) { + return TD_FAILURE; + } + if (gfbg_disp_setscreensize(par->layer_id, gfbg_get_xres(info), gfbg_get_yres(info)) != TD_SUCCESS) { + return TD_FAILURE; + } + + osal_spin_lock_irqsave(&par->lock, &lock_flag); + } + + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + return TD_SUCCESS; +} + +/* + * Function : gfbg_set_par + * Description : set the variable parmater and make it use + * Input : struct fb_info *info + * Return : return 0 + */ +static td_s32 gfbg_set_par(struct fb_info *info) +{ + gfbg_par *par = (gfbg_par *)info->par; + gfbg_display_info *display_info = &par->display_info; + ot_fb_color_format format; + unsigned long lock_flag; + + osal_spin_lock_irqsave(&par->lock, &lock_flag); + + par->modifying = TD_TRUE; + + /* set the stride if stride change */ + set_par_stride(info); + + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + /* If xres or yres change */ + if (set_par_resolution(info) != TD_SUCCESS) { + return TD_FAILURE; + } + +#ifdef __LITEOS__ + format = info->vinfo.format; +#else + format = gfbg_getfmtbyargb(&info->var.red, &info->var.green, &info->var.blue, &info->var.transp, + gfbg_get_bits_per_pixel(info)); +#endif + if ((par->color_format != format)) { + gfbg_freeccanbuf(par); + gfbg_set_fmt(par, format); + par->cursor_info.cursor.cursor.format = format; + par->param_modify_mask |= GFBG_LAYER_PARAMODIFY_FMT; + } + + osal_spin_lock_irqsave(&par->lock, &lock_flag); + display_info->x_res = gfbg_get_xres(info); + display_info->y_res = gfbg_get_yres(info); + display_info->vir_x_res = gfbg_get_xres_virtual(info); + display_info->vir_y_res = gfbg_get_yres_virtual(info); + + par->modifying = TD_FALSE; + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + + return 0; +} + +/* + * Function : gfbg_pan_display + * Description : pan g_display. + * Input : struct fb_var_screeninfo *var + * Return : return 0 + */ +#ifdef __LITEOS__ +static td_s32 gfbg_pan_display(struct fb_vtable_s *vtable, struct fb_overlayinfo_s *oinfo) +#else +static td_s32 gfbg_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) +#endif +{ +#ifdef __LITEOS__ + struct gfbg_info *info = (struct gfbg_info *)vtable; +#endif + + gfbg_par* par = (gfbg_par *)info->par; + gfbg_refresh_info* refresh_info = &par->refresh_info; + td_phys_addr_t display_addr; + td_u32 stride; + ot_fb_buf canvas_buf; + td_s32 ret; + + /* set the stride and display start address */ + stride = gfbg_get_line_length(info); + +#ifdef __LITEOS__ + display_addr = (gfbg_get_smem_start(info) + (td_u64)stride * oinfo->sarea.y + (td_u64)oinfo->sarea.x * + (gfbg_get_bits_per_pixel(info) >> 3)) & 0xfffffffffffffff0; /* 3 is 8 bits */ +#else + /* 3 is 8 bits */ + display_addr = (gfbg_get_smem_start(info) + (td_u64)stride * var->yoffset + (td_u64)var->xoffset * + (gfbg_get_bits_per_pixel(info) >> 3)) & 0xfffffffffffffff0; /* 3 is 8 bits */ +#endif + canvas_buf.canvas.format = par->color_format; + canvas_buf.canvas.phys_addr = display_addr; + canvas_buf.canvas.pitch = stride; + canvas_buf.update_rect.x = 0; + canvas_buf.update_rect.y = 0; +#ifdef __LITEOS__ + canvas_buf.canvas.width = info->vinfo.xres; + canvas_buf.canvas.height = info->vinfo.yres; + canvas_buf.update_rect.width = info->vinfo.xres; + canvas_buf.update_rect.height = info->vinfo.xres; + g_layer[par->layer_id].info->activate = info->activate; +#else + canvas_buf.canvas.width = gfbg_get_xres(info); + canvas_buf.canvas.height = gfbg_get_yres(info); + canvas_buf.update_rect.width = (td_s32)gfbg_get_xres(info); + canvas_buf.update_rect.height = (td_s32)gfbg_get_yres(info); + g_layer[par->layer_id].info->var.activate = info->var.activate; +#endif + refresh_info->buf_mode = OT_FB_LAYER_BUF_BUTT; + ret = gfbg_refresh_0buf(par->layer_id, &canvas_buf); + + return ret; +} + +static inline td_void gfbg_get_fmt(const gfbg_par *par, ot_fb_color_format *color_format) +{ + *color_format = par->color_format; + return; +} + +static inline td_void gfbg_set_fmt(gfbg_par *par, ot_fb_color_format color_fmt) +{ + par->color_format = color_fmt; + + return; +} + +static inline td_void gfbg_set_alpha(gfbg_par *par, const ot_fb_alpha *alpha) +{ + td_s32 ret; + ret = memcpy_s(&par->alpha, sizeof(ot_fb_alpha), alpha, sizeof(ot_fb_alpha)); + gfbg_unequal_eok_return_void(ret); + return; +} + +static inline td_void gfbg_get_alpha(const gfbg_par *par, ot_fb_alpha *alpha) +{ + td_s32 ret; + ret = memcpy_s(alpha, sizeof(ot_fb_alpha), &par->alpha, sizeof(ot_fb_alpha)); + gfbg_unequal_eok_return_void(ret); + return; +} + +static inline td_void gfbg_set_key(gfbg_par *par, const gfbg_colorkeyex *key) +{ + td_s32 ret; + ret = memcpy_s(&par->ckey, sizeof(gfbg_colorkeyex), key, sizeof(gfbg_colorkeyex)); + gfbg_unequal_eok_return_void(ret); + return; +} + +static inline td_void gfbg_get_key(const gfbg_par *par, gfbg_colorkeyex *key) +{ + td_s32 ret; + ret = memcpy_s(key, sizeof(gfbg_colorkeyex), &par->ckey, sizeof(gfbg_colorkeyex)); + gfbg_unequal_eok_return_void(ret); + return; +} + +static td_void gfbg_set_layerpos(gfbg_par *par, const ot_fb_point *pos) +{ + td_s32 x_pos; + td_s32 y_pos; + ot_size max_screensize = {0}; + td_u32 layer_id; + gfbg_display_info *display_info = TD_NULL; + + layer_id = par->layer_id; + display_info = &par->display_info; + + gfbg_get_maxscreensize(par, &max_screensize.width, &max_screensize.height); + x_pos = pos->x_pos; + y_pos = pos->y_pos; + if (x_pos > (td_s32)(max_screensize.width - g_drv_ops.capability[layer_id].min_width)) { + gfbg_warning("the sum of x_pos(%d) and min_width(%d) larger than Vodev screen width(%d)!\n", x_pos, + g_drv_ops.capability[layer_id].min_width, max_screensize.width); + x_pos = max_screensize.width - g_drv_ops.capability[layer_id].min_width; + } + + if (y_pos > (td_s32)(max_screensize.height - g_drv_ops.capability[layer_id].min_height)) { + gfbg_warning("the sum of y_pos(%d) and min_height(%d) larger than Vodev screen height(%d)!\n", y_pos, + g_drv_ops.capability[layer_id].min_height, max_screensize.height); + y_pos = max_screensize.height - g_drv_ops.capability[layer_id].min_height; + } + + display_info->pos.x_pos = x_pos; + display_info->pos.y_pos = y_pos; + + par->param_modify_mask |= GFBG_LAYER_PARAMODIFY_OUTRECT; + + return; +} +static inline td_bool gfbg_get_show(const gfbg_par *par) +{ + if (par != TD_NULL) { + return par->show; + } else { + return TD_FALSE; + } +} + +static inline td_void gfbg_set_show(gfbg_par *par, td_bool show) +{ + if (par != TD_NULL) { + par->show = show; + } +} + +static td_void gfbg_get_layerinfo(const gfbg_par *par, ot_fb_layer_info *layer_info) +{ + ot_fb_point pos = {0}; + if ((par != TD_NULL) && (layer_info != TD_NULL)) { + gfbg_get_premul(par, &layer_info->is_premul); + gfbg_get_bufmode(par, &layer_info->buf_mode); + gfbg_get_antiflickerlevel(par, &layer_info->antiflicker_level); + gfbg_get_layerpos(par, &pos); + layer_info->x_pos = pos.x_pos; + layer_info->y_pos = pos.y_pos; + gfbg_get_dispsize(par, &layer_info->display_width, &layer_info->display_height); + gfbg_get_screensize(par, &layer_info->screen_width, &layer_info->screen_height); + layer_info->canvas_width = par->canvas_sur.width; + layer_info->canvas_height = par->canvas_sur.height; + + layer_info->mask = OT_FB_LAYER_MASK_BUTT; + } + + return; +} + +static td_void gfbg_get_idledispbuf(const gfbg_par *par, td_phys_addr_t *phy_addr) +{ + const gfbg_refresh_info *refresh_info = TD_NULL; + td_u32 index_for_int; + if ((par == TD_NULL) || (phy_addr == TD_NULL)) { + return; + } + refresh_info = &par->refresh_info; + index_for_int = refresh_info->disp_buf_info.index_for_int; + /* + * Only the 2buf refresh mode allows to get free buf, otherwise it is the buf in the current + * interrupt processing. + */ + if ((refresh_info->buf_mode == OT_FB_LAYER_BUF_DOUBLE) || + (refresh_info->buf_mode == OT_FB_LAYER_BUF_DOUBLE_IMMEDIATE)) { + *phy_addr = refresh_info->disp_buf_info.phys_addr[1 - index_for_int]; + } else { + *phy_addr = refresh_info->disp_buf_info.phys_addr[index_for_int]; + } + return; +} + +static td_void gfbg_get_workdispbuf(const gfbg_par *par, td_phys_addr_t *phy_addr) +{ + const gfbg_refresh_info *refresh_info = TD_NULL; + td_u32 index_for_int; + if ((par == TD_NULL) || (phy_addr == TD_NULL)) { + return; + } + refresh_info = &par->refresh_info; + index_for_int = refresh_info->disp_buf_info.index_for_int; + + *phy_addr = refresh_info->disp_buf_info.phys_addr[index_for_int]; + + return; +} + +static td_void gfbg_get_dispsize(const gfbg_par *par, td_u32 *width, td_u32 *height) +{ + const gfbg_display_info *display_info = TD_NULL; + + display_info = &par->display_info; + + if ((width != TD_NULL) && (height != TD_NULL)) { + *width = display_info->display_width; + *height = display_info->display_height; + } + + return; +} + +static inline td_void gfbg_set_dispbufflip(gfbg_par *par, td_bool need_flip) +{ + par->refresh_info.disp_buf_info.need_flip = need_flip; + + return; +} + +static inline td_void gfbg_get_bufmode(const gfbg_par *par, ot_fb_layer_buf *buf_mode) +{ + *buf_mode = par->refresh_info.buf_mode; + + return; +} + +static inline td_void gfbg_get_premul(const gfbg_par *par, td_bool *premul) +{ + *premul = par->display_info.is_premul; + + return; +} + +static inline td_void gfbg_get_antiflickerlevel(const gfbg_par *par, ot_fb_layer_antiflicker_level *antiflicker_level) +{ + *antiflicker_level = par->display_info.antiflicker_level; + + return; +} + +static inline td_void gfbg_get_layerpos(const gfbg_par *par, ot_fb_point *pos) +{ + td_s32 ret; + ret = memcpy_s(pos, sizeof(ot_fb_point), &par->display_info.pos, sizeof(ot_fb_point)); + gfbg_unequal_eok_return_void(ret); + return; +} + +static td_void gfbg_get_screensize(const gfbg_par *par, td_u32 *width, td_u32 *height) +{ + const gfbg_display_info *display_info = TD_NULL; + if (par == TD_NULL) { + return; + } + display_info = &par->display_info; + + if ((width != TD_NULL) && (height != TD_NULL)) { + *width = display_info->screen_width; + *height = display_info->screen_height; + } + + return; +} + +static td_s32 gfbg_set_screensize(gfbg_par *par, const td_u32 *width, const td_u32 *height) +{ + td_s32 ret; + gfbg_display_info *display_info = TD_NULL; + + ret = TD_SUCCESS; + if ((par == TD_NULL) || (width == TD_NULL) || (height == TD_NULL)) { + return TD_FAILURE; + } + display_info = &par->display_info; + + if (g_drv_ops.capability[par->layer_id].is_vo_scale) { + display_info->screen_width = *width; + display_info->screen_height = *height; + } else { + if ((display_info->display_width != *width) || (display_info->display_height != *height)) { + gfbg_error("ScreenSize(%u, %u) can't be different with DisplaySize(%u, %u) when layer %u don't scale\n", + *width, *height, display_info->display_width, display_info->display_height, par->layer_id); + ret = TD_FAILURE; + } + } + + return ret; +} + +static td_void gfbg_get_maxscreensize(gfbg_par *par, td_u32 *width, td_u32 *height) +{ + gfbg_osd_data layer_data; + gfbg_display_info *display_info = TD_NULL; + if (par == TD_NULL) { + return; + } + display_info = &par->display_info; + + if (g_drv_ops.gfbg_drv_get_osd_data(par->layer_id, &layer_data) == TD_SUCCESS) { + display_info->max_screen_width = layer_data.screen_width; + display_info->max_screen_height = layer_data.screen_height; + } + + if ((width != TD_NULL) && (height != TD_NULL)) { + *width = display_info->max_screen_width; + *height = display_info->max_screen_height; + } + + return; +} + +static td_void gfbg_tde_rotate_callback(const td_void *paraml, const td_void *paramr) +{ + td_u32 layer_id = 0; + td_s32 tde_finish_handle; + gfbg_par *par = TD_NULL; + gfbg_refresh_info *refresh_info = TD_NULL; + ot_fb_layer_buf buf_mode; + unsigned long lockflag; + gfbg_tde_callback_param *param = (gfbg_tde_callback_param *)paraml; + tde_finish_handle = *(td_s32 *)paramr; + + if (param != TD_NULL) { + layer_id = param->layer_id; + } else { + gfbg_error("pParam is NULL\n"); + return; + } + if (layer_id <= g_drv_ops.layer_count) { + par = (gfbg_par *)(g_layer[layer_id].info->par); + } else { + osal_kfree(param); + param = TD_NULL; + gfbg_error("layer_id = %d is invalid\n", layer_id); + return; + } + refresh_info = &par->refresh_info; + gfbg_get_bufmode(par, &buf_mode); + + osal_spin_lock_irqsave(&par->lock, &lockflag); + + if ((buf_mode == OT_FB_LAYER_BUF_DOUBLE) && (refresh_info->disp_buf_info.refresh_handle == tde_finish_handle)) { + /* Notify VO, it can be updated now */ + gfbg_set_dispbufflip(par, TD_TRUE); + + /* Compression is not supported when there is rotation */ + par->refresh_info.disp_buf_info.compress = TD_FALSE; + } + osal_spin_unlock_irqrestore(&par->lock, &lockflag); + if (param != TD_NULL) { + osal_kfree(param); + param = TD_NULL; + } + return; +} + +static td_void tde_callback_src_init(const gfbg_par *par, ot_fb_buf *src_img) +{ + const gfbg_display_info *display_info = &par->display_info; + td_u32 bytes_per_pixel = 2; + src_img->canvas.phys_addr = par->rotate_vb; + src_img->canvas.width = display_info->display_height; + src_img->canvas.height = display_info->display_width; + src_img->update_rect.x = 0; + src_img->update_rect.y = 0; + src_img->update_rect.width = src_img->canvas.width; + src_img->update_rect.height = src_img->canvas.height; + + src_img->canvas.format = par->color_format; + if (src_img->canvas.format == OT_FB_FORMAT_ARGB1555 || src_img->canvas.format == OT_FB_FORMAT_ARGB4444) { + bytes_per_pixel = 2; /* 2 is PerPixel */ + } else if (src_img->canvas.format == OT_FB_FORMAT_ARGB8888) { + bytes_per_pixel = 4; /* 4 is PerPixel */ + } + src_img->canvas.pitch = ((bytes_per_pixel * src_img->canvas.width + GFBG_ALIGN - 1) / GFBG_ALIGN) * GFBG_ALIGN; + return; +} + +static td_void tde_callback_dst_init(const gfbg_par *par, ot_fb_buf *dst_img, ot_fb_layer_buf buf_mode) +{ + td_u32 bytes_per_pixel = 2; + const gfbg_refresh_info *refresh_info = &par->refresh_info; + const gfbg_display_info *display_info = &par->display_info; + if (buf_mode == OT_FB_LAYER_BUF_DOUBLE) { + gfbg_get_idledispbuf(par, (td_phys_addr_t*)(&dst_img->canvas.phys_addr)); + } else if (buf_mode == OT_FB_LAYER_BUF_ONE) { + dst_img->canvas.phys_addr = + refresh_info->disp_buf_info.phys_addr[refresh_info->disp_buf_info.index_for_int]; + } else if (buf_mode == OT_FB_LAYER_BUF_DOUBLE_IMMEDIATE) { + dst_img->canvas.phys_addr = + refresh_info->disp_buf_info.phys_addr[1 - refresh_info->disp_buf_info.index_for_int]; + } + dst_img->canvas.width = display_info->display_width; + dst_img->canvas.height = display_info->display_height; + dst_img->canvas.format = par->color_format; + dst_img->update_rect.x = 0; + dst_img->update_rect.y = 0; + dst_img->update_rect.width = dst_img->canvas.width; + dst_img->update_rect.height = dst_img->canvas.height; + if (dst_img->canvas.format == OT_FB_FORMAT_ARGB1555 || dst_img->canvas.format == OT_FB_FORMAT_ARGB4444) { + bytes_per_pixel = 2; /* 2 is PerPixel */ + } else if (dst_img->canvas.format == OT_FB_FORMAT_ARGB8888) { + bytes_per_pixel = 4; /* 4 is PerPixel */ + } + dst_img->canvas.pitch = ((bytes_per_pixel * dst_img->canvas.width + GFBG_ALIGN - 1) / GFBG_ALIGN) * GFBG_ALIGN; + return; +} + +static td_void tde_callback_with_rotate(gfbg_par *par, ot_fb_layer_buf buf_mode) +{ + ot_fb_buf src_img; + ot_fb_buf dst_img; + gfbg_rotate_opt rot_opt; + td_bool is_refresh_screen; + gfbg_display_info *display_info = &par->display_info; + gfbg_refresh_info *refresh_info = &par->refresh_info; + + /* fill src image info */ + tde_callback_src_init(par, &src_img); + + /* fill dst image info */ + tde_callback_dst_init(par, &dst_img, buf_mode); + + /* fill rot option info */ + rot_opt.rotate_mode = display_info->rotate_mode; + /* + * Note: After turning on the callback, the rotation job callback function may not be called. + * Need to wait until the next tde task is called, the direct phenomenon is: if the last run + * In the use case, the rotation angle of 90 or 270 is set and the tde rotation branch is entered. + * Unloading ko and loading ko will result in core dump. + */ + rot_opt.call_back = (buf_mode == OT_FB_LAYER_BUF_DOUBLE) ? TD_TRUE : TD_FALSE; + /* In the interrupt, the blocking mode is not allowed, so the non-blocking mode is used. */ + rot_opt.block = TD_FALSE; + rot_opt.param = &(par->layer_id); + + /* Fill is_refresh_screen.Not used now */ + is_refresh_screen = TD_TRUE; + if (gfbg_get_rotation() != TD_NULL) { + refresh_info->disp_buf_info.refresh_handle = gfbg_get_rotation()(&src_img, &dst_img, &rot_opt, + is_refresh_screen); + } + return; +} + +static td_void tde_callback_without_rotate(gfbg_par *par, ot_fb_layer_buf buf_mode, const td_void *paraml, + const td_void *paramr) +{ + gfbg_refresh_info *refresh_info = &par->refresh_info; + gfbg_tde_callback_param *param = (gfbg_tde_callback_param *)paraml; + td_s32 tde_finish_handle = *(td_s32 *)paramr; + + if ((buf_mode == OT_FB_LAYER_BUF_DOUBLE) && (refresh_info->disp_buf_info.refresh_handle == tde_finish_handle)) { + /* Notify VO, can be updated */ + gfbg_set_dispbufflip(par, TD_TRUE); + par->refresh_info.disp_buf_info.compress = param->compress; + } + par->compress_info.update_finished = TD_TRUE; + return; +} + +static td_void gfbg_tde_callback(const td_void *paraml, const td_void *paramr) +{ + td_u32 layer_id = 0; + td_s32 tde_finish_handle; + struct fb_info *info = TD_NULL; + gfbg_par *par = TD_NULL; + gfbg_refresh_info *refresh_info = TD_NULL; + gfbg_display_info *display_info = TD_NULL; + ot_fb_layer_buf buf_mode; + unsigned long lock_flag; + gfbg_tde_callback_param *param = (gfbg_tde_callback_param *)paraml; + tde_finish_handle = *(td_s32 *)paramr; + /* here get a wrong layer_id, make gfbg core dump here */ + if (param != TD_NULL) { + layer_id = param->layer_id; + } else { + gfbg_error("paraml is NULL\n"); + return; + } + if (layer_id <= g_drv_ops.layer_count) { + info = g_layer[layer_id].info; + } else { + osal_kfree(param); + param = TD_NULL; + gfbg_error("layer_id = %d is invalid\n", layer_id); + return; + } + par = (gfbg_par *)(info->par); + refresh_info = &par->refresh_info; + display_info = &par->display_info; + gfbg_info("tde callback blit handle:%x, end handle:%x\n", refresh_info->disp_buf_info.refresh_handle, + tde_finish_handle); + + gfbg_get_bufmode(par, &buf_mode); + osal_spin_lock_irqsave(&par->lock, &lock_flag); + + if ((display_info->rotate_mode == OT_FB_ROTATE_90 || display_info->rotate_mode == OT_FB_ROTATE_270)) { + /* gfbg callback with rotate */ + tde_callback_with_rotate(par, buf_mode); + } else { + /* gfbg callback without rotate */ + tde_callback_without_rotate(par, buf_mode, paraml, paramr); + } + + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + if (param != TD_NULL) { + osal_kfree(param); + param = TD_NULL; + } + return; +} + +static inline td_bool gfbg_is_interlace(const gfbg_par *par) +{ + gfbg_osd_data osd_data = {0}; + if (par != TD_NULL) { + g_drv_ops.gfbg_drv_get_osd_data(par->layer_id, &osd_data); + } + return (osd_data.scan_mode == GFBG_SCANMODE_I); +} + +static td_phys_addr_t gfbg_buf_allocmem(const td_char *buf_name, td_u32 buf_name_size, td_ulong layer_size, + const td_char *mmz_name) +{ + td_phys_addr_t addr; + mm_malloc_param malloc_param; + ot_unused(buf_name_size); + + if ((layer_size == 0) || (layer_size > 0x40000000)) { + return 0; + } + + malloc_param.mmz_name = mmz_name; + malloc_param.buf_name = buf_name; + malloc_param.size = layer_size; + malloc_param.kernel_only = TD_FALSE; + addr = cmpi_mmz_malloc(&malloc_param); + if ((addr == MMB_ADDR_INVALID) && (mmz_name != TD_NULL)) { + malloc_param.mmz_name = TD_NULL; + addr = cmpi_mmz_malloc(&malloc_param); + } + + if (addr == MMB_ADDR_INVALID) { + gfbg_error("alloc mem failed!\n"); + return 0; + } + + return addr; +} + +static td_void gfbg_set_bufmode(td_u32 layer_id, ot_fb_layer_buf layer_buf_mode) +{ + struct fb_info *info = g_layer[layer_id].info; + gfbg_par *par = (gfbg_par *)info->par; + gfbg_refresh_info *refresh_info = &par->refresh_info; + + /* in 0 buf mode ,maybe the stride or format will be changed! */ + if ((refresh_info->buf_mode == OT_FB_LAYER_BUF_NONE) && (refresh_info->buf_mode != layer_buf_mode)) { + par->modifying = TD_TRUE; + + par->param_modify_mask |= GFBG_LAYER_PARAMODIFY_STRIDE; + + par->param_modify_mask |= GFBG_LAYER_PARAMODIFY_FMT; + + par->modifying = TD_FALSE; + } + + refresh_info->buf_mode = layer_buf_mode; +} + +/* + * choose the module to do flicker resiting, TDE or VOU ? the rule is as this ,the module should do flicker resisting + * who has do scaling + */ +static td_void gfbg_select_antiflicker_mode(gfbg_par *par) +{ + gfbg_display_info *display_info = TD_NULL; + + display_info = &par->display_info; + + /* if the usr's configuration is no needed to do flicker resisting, so no needed to do it */ + if (display_info->antiflicker_level == OT_FB_LAYER_ANTIFLICKER_NONE) { + display_info->antiflicker_mode = GFBG_ANTIFLICKER_NONE; + } else { + /* current standard no needed to do flicker resisting */ + if (!display_info->need_antiflicker) { + display_info->antiflicker_mode = GFBG_ANTIFLICKER_NONE; + } else { + /* VO has done scaling , so should do flicker resisting at the same time */ + if ((display_info->display_width != display_info->screen_width) || + (display_info->display_height != display_info->screen_height)) { + display_info->antiflicker_mode = GFBG_ANTIFLICKER_VO; + } else { + display_info->antiflicker_mode = GFBG_ANTIFLICKER_TDE; + } + } + } +} + +static td_void gfbg_set_antiflickerlevel(td_u32 layer_id, ot_fb_layer_antiflicker_level antiflicker_level) +{ + struct fb_info *info = g_layer[layer_id].info; + gfbg_par *par = (gfbg_par *)info->par; + gfbg_display_info *display_info = &par->display_info; + + display_info->antiflicker_level = antiflicker_level; + gfbg_select_antiflicker_mode(par); + + return; +} + +/* Does the chip support scaling */ +static td_s32 gfbg_check_imagezoomenable(td_u32 layer_id, const ot_fb_rect *in_rect, const ot_fb_rect *out_rect) +{ + td_bool is_layer_support_zoom_out = TD_TRUE; + td_bool need_zoom; + + if (!g_drv_ops.capability[layer_id].is_vo_scale) { + return TD_FAILURE; + } + + if (g_drv_ops.gfbg_drv_is_layer_support_zoom_out) { + is_layer_support_zoom_out = g_drv_ops.gfbg_drv_is_layer_support_zoom_out(layer_id); + } + + /* The chip does not support zoomout, and the current image output size is smaller than the input size. */ + if ((is_layer_support_zoom_out == TD_FALSE) && + ((out_rect->width < in_rect->width) || (out_rect->height < in_rect->height))) { + gfbg_error("GFBG layer%d not support zoomout, please check the display and screen size!\n", layer_id); + return TD_FAILURE; + } + + /* The chip zoomin ratio exceeds the maximum allowed by the chip, and the error is returned. */ + if (out_rect->width > (in_rect->width * GFBG_MAX_ZOOMIN) || + out_rect->height > (in_rect->height * GFBG_MAX_ZOOMIN)) { + gfbg_error("GFBG layer%d in_size(%d, %d) and out_size(%d, %d) do out of ZoomRatio[1, %d]!!\n", layer_id, + in_rect->width, in_rect->height, out_rect->width, out_rect->height, GFBG_MAX_ZOOMIN); + return TD_FAILURE; + } + + need_zoom = (out_rect->width != in_rect->width || out_rect->height != in_rect->height); + if (need_zoom == TD_FALSE) { + return TD_FAILURE; + } + + if (need_zoom && (in_rect->width > GFBG_LINE_BUF)) { + gfbg_error("GFBG layer%d in width: %u is bigger than %d, will not zoom in!!\n", layer_id, in_rect->width, + GFBG_LINE_BUF); + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +static td_void gfbg_dcmp_config(td_u32 layer_id) +{ + struct fb_info *info = g_layer[layer_id].info; + gfbg_par *par = (gfbg_par *)(info->par); + gfbg_refresh_info *refresh_info = &par->refresh_info; + td_bool dcmp_state_en = TD_FALSE; + + /* + * In order to support compressed and non-compressed dynamic switching, you cannot use + * pstCompressInfo->bCompressOpen to determine whether to open compression. + * To use the compression information that follows the frame, and whether or not + * to flip to decide whether to switch compression or non-compression + */ + if (refresh_info->disp_buf_info.compress) { + /* See GFBG_DRV_EnableDcmp */ + g_drv_ops.gfbg_drv_enable_dcmp(layer_id, TD_TRUE); + /* See GFBG_DRV_GetDcmpEnableState */ + g_drv_ops.gfbg_drv_get_dcmp_enable_state(layer_id, &dcmp_state_en); + if (dcmp_state_en) { + gfbg_set_dcmp_info(info); +#ifdef CONFIG_COMPRESS_ECONOMIZE_MEMERY + /* after recalculate stride, set buf[1] again */ + gfbg_set_dispbufinfo(layer_id); +#endif + } + } else { + /* + * Set the address and stride to ensure that the compression will g_display correctly when switched to + * non-compressed + */ + g_drv_ops.gfbg_drv_set_layer_addr(layer_id, refresh_info->screen_addr); + if ((refresh_info->buf_mode == OT_FB_LAYER_BUF_NONE) && refresh_info->user_buffer.canvas.phys_addr) { + g_drv_ops.gfbg_drv_set_layer_stride(layer_id, refresh_info->user_buffer.canvas.pitch); + } else { + /* dynamic change compress,when compress to uncompress, reset stride */ + if (par->param_modify_mask & GFBG_LAYER_PARAMODIEY_COMPRESS) { + info->fix.line_length = (info->var.xres_virtual * info->var.bits_per_pixel / 8 + /* 8 one byte */ + GFBG_ALIGNMENT) & (~GFBG_ALIGNMENT); + par->param_modify_mask &= ~GFBG_LAYER_PARAMODIEY_COMPRESS; + } + g_drv_ops.gfbg_drv_set_layer_stride(layer_id, gfbg_get_line_length(info)); + } + + g_drv_ops.gfbg_drv_enable_dcmp(layer_id, TD_FALSE); + } +} + +/* Callback function for VO vertical timing interrupt */ +static td_s32 callback_get_osd_data(gfbg_par *par, td_u32 layer_id) +{ + gfbg_osd_data layer_data = {0}; + gfbg_display_info *display_info = TD_NULL; + gfbg_refresh_info *refresh_info = TD_NULL; + + display_info = &par->display_info; + refresh_info = &par->refresh_info; + + if (g_drv_ops.gfbg_drv_get_osd_data(par->layer_id, &layer_data) != TD_SUCCESS) { + gfbg_error("failed to get layer%d's osd data!\n", par->layer_id); + return TD_FAILURE; + } + display_info->max_screen_width = layer_data.screen_width; + display_info->max_screen_height = layer_data.screen_height; + if (par->param_modify_mask & GFBG_LAYER_PARAMODIFY_ALPHA) { + g_drv_ops.gfbg_drv_set_layer_alpha(layer_id, par->alpha); + par->param_modify_mask &= ~GFBG_LAYER_PARAMODIFY_ALPHA; + } + + if (par->param_modify_mask & GFBG_LAYER_PARAMODIFY_COLORKEY) { + g_drv_ops.gfbg_drv_set_layer_key_mask(layer_id, &par->ckey); + par->param_modify_mask &= ~GFBG_LAYER_PARAMODIFY_COLORKEY; + } + + if (par->param_modify_mask & GFBG_LAYER_PARAMODIFY_FMT) { + if ((refresh_info->buf_mode == OT_FB_LAYER_BUF_NONE) && refresh_info->user_buffer.canvas.phys_addr) { + g_drv_ops.gfbg_drv_set_layer_data_fmt(layer_id, refresh_info->user_buffer.canvas.format); + } else { + g_drv_ops.gfbg_drv_set_layer_data_fmt(layer_id, par->color_format); + } + par->param_modify_mask &= ~GFBG_LAYER_PARAMODIFY_FMT; + } + return TD_SUCCESS; +} + +static td_void callback_modify_dynamic_range(gfbg_par *par, td_u32 layer_id) +{ + gfbg_display_info *display_info = TD_NULL; + gfbg_refresh_info *refresh_info = TD_NULL; + struct fb_info *info = TD_NULL; + + display_info = &par->display_info; + refresh_info = &par->refresh_info; + info = g_layer[layer_id].info; + + if (par->param_modify_mask & GFBG_LAYER_PARAMODIFY_BMUL) { + if (g_drv_ops.gfbg_drv_set_pre_mul(layer_id, display_info->is_premul) != TD_SUCCESS) { + if (par->display_info.is_premul == TD_TRUE) { + par->display_info.is_premul = TD_FALSE; + } else { + par->display_info.is_premul = TD_TRUE; + } + } + par->param_modify_mask &= ~GFBG_LAYER_PARAMODIFY_BMUL; + } + + if (par->param_modify_mask & GFBG_LAYER_PARAMODIFY_STRIDE) { + if ((refresh_info->buf_mode == OT_FB_LAYER_BUF_NONE) && refresh_info->user_buffer.canvas.phys_addr) { + g_drv_ops.gfbg_drv_set_layer_stride(layer_id, refresh_info->user_buffer.canvas.pitch); + } else { + g_drv_ops.gfbg_drv_set_layer_stride(layer_id, gfbg_get_line_length(info)); + } + par->param_modify_mask &= ~GFBG_LAYER_PARAMODIFY_STRIDE; + } + return; +} + +static td_void callback_init_rect(ot_fb_rect *in_rect, ot_fb_rect *out_rect, const gfbg_display_info *display_info) +{ + in_rect->x = display_info->pos.x_pos; + in_rect->y = display_info->pos.y_pos; + in_rect->width = (td_s32)display_info->display_width; + in_rect->height = (td_s32)display_info->display_height; + + out_rect->x = display_info->pos.x_pos; + out_rect->y = display_info->pos.y_pos; + out_rect->width = display_info->screen_width; + out_rect->height = display_info->screen_height; + + if (out_rect->x + out_rect->width > (td_s32)display_info->max_screen_width) { + out_rect->width = (td_s32)(display_info->max_screen_width - out_rect->x); + } + + if (out_rect->y + out_rect->height > (td_s32)display_info->max_screen_height) { + out_rect->height = (td_s32)(display_info->max_screen_height - out_rect->y); + } + + /* after cut off, the input rectangle keep rate with output rectangle */ + /* Prevent the occurrence of the divide-by-zero error */ + if ((display_info->screen_width != 0) && (display_info->screen_height != 0)) { + in_rect->width = in_rect->width * out_rect->width / (td_s32)display_info->screen_width; + in_rect->height = in_rect->height * out_rect->height / (td_s32)display_info->screen_height; + } + return; +} + +static td_void callback_modify_sizes(gfbg_par *par, td_u32 layer_id) +{ + gfbg_display_info *display_info = TD_NULL; + ot_fb_rect in_rect = {0}; + ot_fb_rect out_rect = {0}; + td_bool zme_en; + + display_info = &par->display_info; + /* Handles requests to modify input and output sizes. */ + if ((par->param_modify_mask & GFBG_LAYER_PARAMODIFY_INRECT) || + (par->param_modify_mask & GFBG_LAYER_PARAMODIFY_OUTRECT)) { + /* if VO can't support scaling, we set the screen's H/W as the same as display */ + if (!g_drv_ops.capability[layer_id].is_vo_scale) { + display_info->screen_width = display_info->display_width; + display_info->screen_height = display_info->display_height; + } + + /* for init rect */ + callback_init_rect(&in_rect, &out_rect, display_info); + if (gfbg_check_imagezoomenable(layer_id, &in_rect, &out_rect) == TD_SUCCESS) { + /* + * If you want to go through the zoom module, you need to correct it to 2 alignment, + * otherwise it will appear abnormal. + */ + in_rect.width = ALIGN_DOWN((td_u32)in_rect.width, 2); /* 2 align */ + in_rect.height = ALIGN_DOWN((td_u32)in_rect.height, 2); /* 2 align */ + + if (g_drv_ops.gfbg_drv_set_layer_rect) { + g_drv_ops.gfbg_drv_set_layer_rect(layer_id, &in_rect, &out_rect); + } + + if (g_drv_ops.gfbg_drv_set_layer_src_image_reso) { + g_drv_ops.gfbg_drv_set_layer_src_image_reso(layer_id, &in_rect); + } + + /* NEW!!! Set zoom */ + /* See out width and height not equal to in width and height,then enable zme. */ + zme_en = (out_rect.width != in_rect.width || out_rect.height != in_rect.height); + if (g_drv_ops.gfbg_drv_enable_zme) { + g_drv_ops.gfbg_drv_enable_zme(layer_id, &in_rect, &out_rect, zme_en); + } + } else { + /* + * If scaling is not enabled, + * the input size is used as the output size and the zoom module is closed. + */ + if (g_drv_ops.gfbg_drv_set_layer_rect) { + g_drv_ops.gfbg_drv_set_layer_rect(layer_id, &in_rect, &in_rect); + } + + if (g_drv_ops.gfbg_drv_set_layer_src_image_reso) { + g_drv_ops.gfbg_drv_set_layer_src_image_reso(layer_id, &in_rect); + } + + if (g_drv_ops.gfbg_drv_enable_zme) { + g_drv_ops.gfbg_drv_enable_zme(layer_id, &in_rect, &out_rect, TD_FALSE); + } + } + + /* Processing completed, clear mask */ + par->param_modify_mask &= ~GFBG_LAYER_PARAMODIFY_INRECT; + par->param_modify_mask &= ~GFBG_LAYER_PARAMODIFY_OUTRECT; + } + return; +} + +static td_void callback_set_fmt_and_stride(const gfbg_par *par, td_u32 layer_id) +{ + struct fb_info *info = TD_NULL; + const gfbg_refresh_info *refresh_info = TD_NULL; + + info = g_layer[layer_id].info; + refresh_info = &par->refresh_info; + if (par->param_modify_mask & GFBG_LAYER_PARAMODIFY_FMT) { + if ((refresh_info->buf_mode == OT_FB_LAYER_BUF_NONE) && refresh_info->user_buffer.canvas.phys_addr) { + g_drv_ops.gfbg_drv_set_layer_data_fmt(layer_id, refresh_info->user_buffer.canvas.format); + } else { + g_drv_ops.gfbg_drv_set_layer_data_fmt(layer_id, par->color_format); + } + } + + if (par->param_modify_mask & GFBG_LAYER_PARAMODIFY_STRIDE) { + if ((refresh_info->buf_mode == OT_FB_LAYER_BUF_NONE) && refresh_info->user_buffer.canvas.phys_addr) { + g_drv_ops.gfbg_drv_set_layer_stride(layer_id, refresh_info->user_buffer.canvas.pitch); + } else { + g_drv_ops.gfbg_drv_set_layer_stride(layer_id, gfbg_get_line_length(info)); + } + } + return; +} + +static td_void callback_update_refresh_info(gfbg_par *par, td_u32 layer_id) +{ + gfbg_refresh_info *refresh_info = TD_NULL; + struct fb_info *info = TD_NULL; + volatile gfbg_compress_info *compress_info = TD_NULL; + td_u32 index, buf_size; + + refresh_info = &par->refresh_info; + index = refresh_info->disp_buf_info.index_for_int; + info = g_layer[layer_id].info; + buf_size = ((gfbg_get_line_length(info) * gfbg_get_yres(info)) + GFBG_ALIGNMENT) & (~GFBG_ALIGNMENT); + compress_info = &par->compress_info; + if ((refresh_info->buf_mode == OT_FB_LAYER_BUF_DOUBLE) && (refresh_info->disp_buf_info.need_flip == TD_TRUE)) { + /* Work buf to change to free buf. Take free buf to display */ + index = 1 - index; + refresh_info->disp_buf_info.index_for_int = index; + /* + * The display address is set to the address of the free buf, + * which is set to the screen buf address differently from 0buf + */ + g_drv_ops.gfbg_drv_set_layer_addr(layer_id, refresh_info->disp_buf_info.phys_addr[index]); + refresh_info->screen_addr = refresh_info->disp_buf_info.phys_addr[index]; + refresh_info->gb_screen_addr = refresh_info->screen_addr + buf_size / 2; /* 2 alg data */ + compress_info->layer_addr_update = TD_TRUE; +#ifdef __LITEOS__ + if (info->oinfo.stride != 0) { + info->oinfo.sarea.y = (par->refresh_info.disp_buf_info.phys_addr[index] - + (td_u32)(uintptr_t)info->oinfo.fbmem) / info->oinfo.stride; + if ((info->oinfo.bpp >> 3) != 0) { /* 3 is 8 bits */ + info->oinfo.sarea.x = ((par->refresh_info.disp_buf_info.phys_addr[index] - + (td_u32)(uintptr_t)info->oinfo.fbmem) % info->oinfo.stride) / + (info->oinfo.bpp >> 3); /* 3 is 8 bits */ + } + } +#else + info->var.yoffset = osal_div_u64((refresh_info->disp_buf_info.phys_addr[index] - gfbg_get_smem_start(info)), + gfbg_get_line_length_ex(info)); + if ((gfbg_get_line_length(info) != 0) && ((gfbg_get_bits_per_pixel(info)>> 3) != 0)) { /* 3 is 8 bits */ + info->var.xoffset = ((td_ulong)(refresh_info->disp_buf_info.phys_addr[index] - gfbg_get_smem_start(info)) % + gfbg_get_line_length_ex(info)) / + (gfbg_get_bits_per_pixel(info)>> 3); /* 3 is 8 bits */ + } +#endif + refresh_info->disp_buf_info.fliped = TD_TRUE; + refresh_info->disp_buf_info.need_flip = TD_FALSE; + refresh_info->disp_buf_info.int_pic_num++; + } + return; +} + +static td_void callback_modify_address(gfbg_par *par, td_u32 layer_id) +{ + gfbg_refresh_info *refresh_info = TD_NULL; + gfbg_display_info *display_info = TD_NULL; + volatile gfbg_compress_info *compress_info = TD_NULL; + struct fb_info *info = TD_NULL; + ot_fb_rect in_rect = {0}; + ot_fb_rect out_rect = {0}; + + refresh_info = &par->refresh_info; + display_info = &par->display_info; + compress_info = &par->compress_info; + info = g_layer[layer_id].info; + /* The display address is refreshed and the display address is modified. */ + if (!(par->param_modify_mask & GFBG_LAYER_PARAMODIFY_DISPLAYADDR)) { + /* according to the index, decide which buf set to the screen */ + callback_update_refresh_info(par, layer_id); + return; + } + /* SetLayerDataFmt and SetLayerStride */ + callback_set_fmt_and_stride(par, layer_id); + + if ((par->param_modify_mask & GFBG_LAYER_PARAMODIFY_INRECT) || + (par->param_modify_mask & GFBG_LAYER_PARAMODIFY_OUTRECT)) { + /* if VO can't support scaling, we set the screen's H/W as the same as display */ + if (!g_drv_ops.capability[layer_id].is_vo_scale) { + display_info->screen_width = display_info->display_width; + display_info->screen_height = display_info->display_height; + } + + /* for init rect */ + callback_init_rect(&in_rect, &out_rect, display_info); + + if (gfbg_check_imagezoomenable(layer_id, &in_rect, &out_rect) == TD_SUCCESS) { + g_drv_ops.gfbg_drv_set_layer_rect(layer_id, &in_rect, &out_rect); + if (g_drv_ops.gfbg_drv_set_layer_src_image_reso) { + g_drv_ops.gfbg_drv_set_layer_src_image_reso(layer_id, &in_rect); + } + } + } + + g_drv_ops.gfbg_drv_set_layer_addr(layer_id, refresh_info->screen_addr); + + par->param_modify_mask &= ~GFBG_LAYER_PARAMODIFY_DISPLAYADDR; + compress_info->layer_addr_update = TD_TRUE; + + if ((refresh_info->disp_buf_info.phys_addr[0] != refresh_info->disp_buf_info.phys_addr[1]) && + (refresh_info->disp_buf_info.phys_addr[0])) { + if (refresh_info->screen_addr >= refresh_info->disp_buf_info.phys_addr[0] && + refresh_info->screen_addr < refresh_info->disp_buf_info.phys_addr[1]) { + refresh_info->disp_buf_info.index_for_int = 0; + } else if ((refresh_info->screen_addr >= refresh_info->disp_buf_info.phys_addr[1]) && + (refresh_info->screen_addr < (refresh_info->disp_buf_info.phys_addr[0] + gfbg_get_smem_len(info)))) { + refresh_info->disp_buf_info.index_for_int = 1; + } + } + /* according to the index, decide which buf set to the screen */ + callback_update_refresh_info(par, layer_id); + return; +} + +static td_void callback_modify_smart_rect(const gfbg_par *par, td_u32 layer_id) +{ + if (par->param_modify_mask & GFBG_LAYER_PARAMODIEY_SMART_RECT) { + if (!g_drv_ops.capability[layer_id].is_osb) { + return; + } + g_drv_ops.gfbg_drv_smart_rect_up_param(par->layer_id); + } + return; +} + +static td_void callback_modify_clut_up(gfbg_par *par, td_u32 layer_id) +{ + if (par->param_modify_mask & GFBG_LAYER_PARAMODIEY_CLUT_UP) { + if (!g_drv_ops.capability[layer_id].is_cmap) { + return; + } + g_drv_ops.gfbg_drv_set_color_reg_up(par->layer_id); + par->param_modify_mask &= ~GFBG_LAYER_PARAMODIEY_CLUT_UP; + } + return; +} + +static td_s32 vo_callback_process(gfbg_par *par, td_u32 layer_id, td_bool *is_continue) +{ + unsigned long lock_flag; + gfbg_sync_attr sync_attr; + osal_spin_lock_irqsave(&par->lock, &lock_flag); + /* If not displayed, close the graphics layer and exit */ + if (par->show == TD_FALSE) { + if (g_drv_ops.gfbg_drv_set_layer_enable) { + g_drv_ops.gfbg_drv_set_layer_enable(layer_id, TD_FALSE); + } + if (g_drv_ops.gfbg_drv_updata_layer_reg) { + g_drv_ops.gfbg_drv_updata_layer_reg(layer_id); + } + *is_continue = TD_FALSE; + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + return TD_SUCCESS; + } + + /* Non-modified status, modified, can be modified */ + if (!par->modifying) { + /* + * 1.Get osd data + * 2.Set layer alpha + * 3.Set layer keymask + * 4.Set layer data fmt + */ + if (callback_get_osd_data(par, layer_id) != TD_SUCCESS) { + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + return TD_FAILURE; + } + + /* + * 1.NEW modify graphic dynamic range + * 2.Set premul + * 3.Set layer stride + * 4.Set layer deflicker + */ + callback_modify_dynamic_range(par, layer_id); + + /* + * Handles requests to modify input and output sizes + * Set layer rect + * Set layer srcImage reso + * if enable ZME or not + */ + callback_modify_sizes(par, layer_id); + + /* + * The display address is refreshed and the display address is modified + * set layer data fmt + * set layer stride + * set layer rect + * set layer addr + */ + callback_modify_address(par, layer_id); + + /* set smart rect */ + callback_modify_smart_rect(par, layer_id); + + /* set clut up */ + callback_modify_clut_up(par, layer_id); + + /* gfbg_drv_set_layer_enable */ + g_drv_ops.gfbg_drv_set_layer_enable(layer_id, par->show); + } + /* Decompression configuration */ + gfbg_dcmp_config(layer_id); + + /* support low delay (only G0 support low delay) */ + sync_attr.is_sync = TD_TRUE; + sync_attr.safe_dist = par->display_info.display_width * 3 * /* 3 rgb888 calculate */ + par->display_info.display_height / 2; /* 2 half frame */ + if (g_drv_ops.gfbg_drv_set_tde_sync != TD_NULL) { + g_drv_ops.gfbg_drv_set_tde_sync(layer_id, &sync_attr); + } + /* gfbg_drv_updata_layer_reg */ + g_drv_ops.gfbg_drv_updata_layer_reg(layer_id); + *is_continue = TD_TRUE; + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + return TD_SUCCESS; +} + +/* Callback function for VO vertical timing interrupt */ +static td_s32 gfbg_interrupt_process(td_u32 layer_id) +{ + struct fb_info *info = TD_NULL; + gfbg_par *par = TD_NULL; + td_bool is_continue = TD_FALSE; + + if (layer_id >= GFBG_MAX_LAYER_NUM) { + return TD_FAILURE; + } + info = g_layer[layer_id].info; + if (info == TD_NULL) { + return TD_FAILURE; + } + if (info->par == TD_NULL) { + return TD_FAILURE; + } + par = (gfbg_par *)(info->par); + if (vo_callback_process(par, layer_id, &is_continue) != TD_SUCCESS) { + return TD_FAILURE; + } + if (is_continue != TD_TRUE) { + return TD_SUCCESS; + } + + /* Field blanking mark */ + par->vblflag = 1; + wake_up(&(par->vbl_event)); + return TD_SUCCESS; +} + +static td_s32 refresh_0buf_process(gfbg_par *par, const ot_fb_buf *canvas_buf) +{ + volatile gfbg_compress_info *compress_info = &par->compress_info; + gfbg_refresh_info *refresh_info = &par->refresh_info; + unsigned long lock_flag; + + osal_spin_lock_irqsave(&par->lock, &lock_flag); + if (compress_info->compress_open == TD_TRUE) { + gfbg_error("only FB_LAYER_BUF_DOUBLE or FB_LAYER_BUF_DOUBLE_IMMEDIATE support compress!\n"); + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + return TD_FAILURE; + } + + refresh_info->disp_buf_info.compress = TD_FALSE; + + par->modifying = TD_TRUE; + /* modify by wxl : if change flush type between 2buffer and 0 buffer, the addr couldn't be changed */ + par->param_modify_mask |= GFBG_LAYER_PARAMODIFY_DISPLAYADDR; + /* + * The graphic address is taken from the canvas of the user data and + * filled in the screen address of the refresh information. + */ + refresh_info->screen_addr = canvas_buf->canvas.phys_addr; + + par->param_modify_mask |= GFBG_LAYER_PARAMODIFY_STRIDE; + refresh_info->user_buffer.canvas.pitch = canvas_buf->canvas.pitch; + + par->param_modify_mask |= GFBG_LAYER_PARAMODIFY_FMT; + refresh_info->user_buffer.canvas.format = canvas_buf->canvas.format; + + /* NEW feature: zme */ + par->param_modify_mask |= GFBG_LAYER_PARAMODIFY_OUTRECT; + + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + return TD_SUCCESS; +} + +static td_s32 gfbg_refresh_0buf(td_u32 layer_id, const ot_fb_buf *canvas_buf) +{ + struct fb_info *info = g_layer[layer_id].info; + gfbg_par *par = (gfbg_par *)info->par; + gfbg_refresh_info *refresh_info = &par->refresh_info; + unsigned long lock_flag; + td_s32 ret; + + ret = refresh_0buf_process(par, canvas_buf); + if (ret != TD_SUCCESS) { + return TD_FAILURE; + } + /* + * In gfbg_disp_setdispsize, it is possible that kmalloc + * allocates memory in a non-atomic manner, so the lock must be released first + */ + if (gfbg_disp_setdispsize(layer_id, canvas_buf->canvas.width, canvas_buf->canvas.height) != TD_SUCCESS) { + return TD_FAILURE; + } + + osal_spin_lock_irqsave(&par->lock, &lock_flag); + par->modifying = TD_FALSE; + ret = memcpy_s(&(refresh_info->user_buffer), sizeof(ot_fb_buf), canvas_buf, sizeof(ot_fb_buf)); + gfbg_unlock_unequal_eok_return(ret, &par->lock, &lock_flag); + if (par->compress_info.compress_open) { + ret = memcpy_s((td_void *)&par->compress_info.update_rect, sizeof(ot_fb_rect), &canvas_buf->update_rect, + sizeof(ot_fb_rect)); + gfbg_unlock_unequal_eok_return(ret, &par->lock, &lock_flag); + par->compress_info.update_finished = TD_TRUE; + } + par->vblflag = 0; + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + + /* if the flag "FB_ACTIVATE_VBL" has been set, we should wait for register update finish */ +#ifdef __LITEOS__ + if (!in_atomic()) { +#else + if (!in_atomic() && (info->var.activate & FB_ACTIVATE_VBL)) { +#endif + gfbg_wait_regconfig_work(layer_id); + } + + return TD_SUCCESS; +} + +static td_void refresh_is_cursor_overlay(const gfbg_par *par, const ot_fb_buf *canvas_buf, td_bool *is_overlay) +{ + gfbg_par *cursor_par = TD_NULL; + const gfbg_cursor_info *cursor_info = &par->cursor_info; + ot_fb_rect rc_cursor; + cursor_par = (gfbg_par *)g_layer[par->cursor_info.attached_cursor_id].info->par; + if (cursor_info->attached != 0) { + rc_cursor.x = cursor_par->display_info.pos.x_pos - cursor_par->cursor_info.cursor.hot_pos.x_pos; + rc_cursor.y = cursor_par->display_info.pos.y_pos - cursor_par->cursor_info.cursor.hot_pos.y_pos; + rc_cursor.width = cursor_par->cursor_info.cursor.cursor.width; + rc_cursor.height = cursor_par->cursor_info.cursor.cursor.height; + + /* check the cusor overlay with refresh area */ + if (cursor_par->show && (((rc_cursor.x >= canvas_buf->update_rect.x && + rc_cursor.x <= canvas_buf->update_rect.x + canvas_buf->update_rect.width)) || + (rc_cursor.x < canvas_buf->update_rect.x && rc_cursor.x + rc_cursor.width >= canvas_buf->update_rect.x))) { + if (((rc_cursor.y >= canvas_buf->update_rect.y && + rc_cursor.y <= canvas_buf->update_rect.y + canvas_buf->update_rect.height)) || + (rc_cursor.y < canvas_buf->update_rect.y && + rc_cursor.y + rc_cursor.height >= canvas_buf->update_rect.y)) { + *is_overlay = TD_TRUE; + } + } + } + return; +} + +/* + * Name : gfbg_refresh + * Desc : It is refreshed according to the canvas information and the layer's buf refresh mode. + * It is called indirectly when setting the layer attr. + * See : references gfbg_refresh_again,gfbg_onrefresh + * calls gfbg_refresh_0buf,gfbg_refresh_1buf,gfbg_refresh_2buf + */ +static td_s32 gfbg_refresh(td_u32 layer_id, const ot_fb_buf *canvas_buf, ot_fb_layer_buf buf_mode) +{ + td_s32 ret = TD_FAILURE; + gfbg_par *par = (gfbg_par *)g_layer[layer_id].info->par; + td_bool is_overlay = TD_FALSE; /* is the cusor overlay with refresh area */ + + if (canvas_buf == TD_NULL) { + return TD_FAILURE; + } + /* + * For cursor layer + * you can quary whether cursor attach to a certain layer for general layer + * when attached not zero, we should check whether the cusor overlay with refresh area or not + */ + refresh_is_cursor_overlay(par, canvas_buf, &is_overlay); + + switch (buf_mode) { + case OT_FB_LAYER_BUF_DOUBLE: + ret = gfbg_refresh_2buf(layer_id, canvas_buf); + break; + case OT_FB_LAYER_BUF_ONE: + ret = gfbg_refresh_1buf(layer_id, canvas_buf); + break; + case OT_FB_LAYER_BUF_NONE: + ret = gfbg_refresh_0buf(layer_id, canvas_buf); + break; + case OT_FB_LAYER_BUF_DOUBLE_IMMEDIATE: + ret = gfbg_refresh_2buf_immediate_display(layer_id, canvas_buf); + break; + default: + break; + } + + return ret; +} + +#ifdef __LITEOS__ +static struct gfbg_info *gfbg_alloc(size_t size) +{ + td_s32 gfbg_info_len = sizeof(struct gfbg_info); + struct gfbg_info *info = TD_NULL; + + gfbg_info_len = ALIGN(gfbg_info_len, sizeof(unsigned long)); + + info = (struct gfbg_info *)malloc(gfbg_info_len + size); + if (info == NULL) { + return NULL; + } + (td_void)memset_s(info, (gfbg_info_len + size), 0, (gfbg_info_len + size)); + + info->par = (void *)((char *)info + gfbg_info_len); + + return info; +} + +static td_s32 alloc_new_canvas_buffer(const struct fb_info *info, const ot_fb_layer_info *layer_info) +{ + gfbg_par *par = (gfbg_par *)info->par; + ot_fb_surface *canvas_surface = &par->canvas_sur; + td_u32 layer_size; + td_u32 pitch; + td_char *buf = TD_NULL; + td_char name[16]; /* 16 name max length */ + struct fb_info *info_temp = TD_NULL; + /* + * Applying fb_info without private data is not for registration, + * but for the convenience of passing to gfbg_fill_data to empty the memory. + */ + info_temp = gfbg_alloc(0); + if (info_temp == TD_NULL) { + return TD_FAILURE; + } + + /* 16 bytes alignment */ + pitch = (((layer_info->canvas_width * gfbg_get_bits_per_pixel(info)) >> 3) + 15) >> 4; /* 3 15 4 for align */ + pitch = pitch << 4; /* 4 for align */ + + layer_size = pitch * layer_info->canvas_height; + /* alloc new buffer */ + if (snprintf_s(name, sizeof(name), 13, "gfbg_canvas%01u", par->layer_id) < 0) { /* 13:for char length */ + gfbg_error("%s:%d:snprintf_s failure\n", __FUNCTION__, __LINE__); + free(info_temp); + return TD_FAILURE; + } + canvas_surface->phys_addr = gfbg_buf_allocmem(name, strlen(name), layer_size, + gfbg_get_layer_mmz_names(par->layer_id)); + if (canvas_surface->phys_addr == 0) { + gfbg_error("alloc canvas buffer no mem"); + free(info_temp); + return TD_FAILURE; + } + + buf = (td_char *)gfbg_buf_map(canvas_surface->phys_addr, layer_size); + if (buf == TD_NULL) { + gfbg_error("map canvas buffer failed!\n"); + gfbg_buf_freemem(canvas_surface->phys_addr); + free(info_temp); + return TD_FAILURE; + } + /* gfbg_fill_data is faster than memset_s */ + info_temp->oinfo.fbmem = (uintptr_t)canvas_surface->phys_addr; + (td_void)memset_s(info_temp->oinfo.fbmem, layer_size, 0x0, layer_size); + + gfbg_buf_ummap(buf); + + gfbg_info("alloc new memory for canvas buffer success\n"); + canvas_surface->width = layer_info->canvas_width; + canvas_surface->height = layer_info->canvas_height; + canvas_surface->pitch = pitch; + par->canvas_sur.format = info->vinfo.format; + free(info_temp); + + return TD_SUCCESS; +} +#else +static td_s32 alloc_new_canvas_buffer(const struct fb_info *info, const ot_fb_layer_info *layer_info) +{ + gfbg_par *par = (gfbg_par *)info->par; + ot_fb_surface *canvas_surface = &par->canvas_sur; + td_u32 layer_size; + td_u32 pitch; + td_char *buf = TD_NULL; + td_char name[16]; /* 16 name max length */ + struct fb_info *info_temp = TD_NULL; + /* + * Applying fb_info without private data is not for registration, + * but for the convenience of passing to gfbg_fill_data to empty the memory. + */ + info_temp = framebuffer_alloc(0, TD_NULL); + if (info_temp == TD_NULL) { + return TD_FAILURE; + } + + /* 16 bytes alignment */ + pitch = (((layer_info->canvas_width * gfbg_get_bits_per_pixel(info)) >> 3) + 15) >> 4; /* 3 4 15 alg data */ + pitch = pitch << 4; /* 4 alg data */ + + layer_size = pitch * layer_info->canvas_height; + /* alloc new buffer */ + if (snprintf_s(name, sizeof(name), 13, "gfbg_canvas%01u", par->layer_id) < 0) { /* 13:for char length */ + gfbg_error("%s:%d:snprintf_s failure\n", __FUNCTION__, __LINE__); + framebuffer_release(info_temp); + return TD_FAILURE; + } + canvas_surface->phys_addr = gfbg_buf_allocmem(name, strlen(name), layer_size, + gfbg_get_layer_mmz_names(par->layer_id)); + if (canvas_surface->phys_addr == 0) { + gfbg_error("alloc canvas buffer no mem"); + framebuffer_release(info_temp); + return TD_FAILURE; + } + + buf = (td_char *)gfbg_buf_map(canvas_surface->phys_addr, layer_size); + if (buf == TD_NULL) { + gfbg_error("map canvas buffer failed!\n"); + gfbg_buf_freemem(canvas_surface->phys_addr); + framebuffer_release(info_temp); + return TD_FAILURE; + } + /* gfbg_fill_data is faster than memset_s */ + info_temp->fix.smem_start = (td_ulong)canvas_surface->phys_addr; + info_temp->screen_base = buf; + if (gfbg_fill_data(info_temp, 0, layer_size) != TD_SUCCESS) { + gfbg_error("gfbg_fill_data failed!\n"); + } + gfbg_buf_ummap(buf); + + gfbg_info("alloc new memory for canvas buffer success\n"); + canvas_surface->width = layer_info->canvas_width; + canvas_surface->height = layer_info->canvas_height; + canvas_surface->pitch = pitch; + canvas_surface->format = gfbg_getfmtbyargb(&info->var.red, &info->var.green, &info->var.blue, &info->var.transp, + info->var.bits_per_pixel); + framebuffer_release(info_temp); + return TD_SUCCESS; +} +#endif + +static td_s32 gfbg_alloccanbuf(const struct fb_info *info, const ot_fb_layer_info *layer_info) +{ + gfbg_par *par = TD_NULL; + ot_fb_surface *canvas_surface = TD_NULL; + + if ((info == TD_NULL) || (layer_info == TD_NULL)) { + return TD_FAILURE; + } + par = (gfbg_par *)info->par; + canvas_surface = &par->canvas_sur; + + if (!(layer_info->mask & OT_FB_LAYER_MASK_CANVAS_SIZE)) { + return TD_SUCCESS; + } + + /* if with old canvas buffer */ + if (canvas_surface->phys_addr != 0) { + /* if old is the same with new , then return, else free the old buffer */ + if ((layer_info->canvas_width == canvas_surface->width) && + (layer_info->canvas_height == canvas_surface->height)) { + gfbg_info("mem size is the same , no need alloc new memory"); + return TD_SUCCESS; + } + + /* free new old buffer */ + gfbg_info("free old canvas buffer\n"); + gfbg_freeccanbuf(par); + } + if (layer_info->canvas_width > GFBG_4K_DEF_WIDTH || layer_info->canvas_height > GFBG_4K_DEF_HEIGHT) { + gfbg_info("unsupported too large w(%d) and h(%d)!max width (%d), max height (%d)\n", + layer_info->canvas_width, layer_info->canvas_height, GFBG_4K_DEF_WIDTH, GFBG_4K_DEF_HEIGHT); + return TD_FAILURE; + } + /* new canvas buffer */ + if (alloc_new_canvas_buffer(info, layer_info) != TD_SUCCESS) { + return TD_FAILURE; + } + return TD_SUCCESS; +} + +static td_s32 onrefresh_check_param(const gfbg_par* par, const ot_fb_buf *canvas_buf, ot_fb_layer_buf buf_mode) +{ + ot_unused(par); + if (canvas_buf->canvas.format >= OT_FB_FORMAT_BUTT) { + return TD_FAILURE; + } + + if (buf_mode == OT_FB_LAYER_BUF_BUTT) { + gfbg_error("doesn't support FBIO_REFRESH operation when refresh mode is FB_LAYER_BUF_BUTT!\n"); + return TD_FAILURE; + } + + if ((canvas_buf->update_rect.x >= (td_s32)canvas_buf->canvas.width) || + (canvas_buf->update_rect.y >= (td_s32)canvas_buf->canvas.height) || + (canvas_buf->update_rect.width <= 0) || (canvas_buf->update_rect.height <= 0) || + (canvas_buf->canvas.width == 0) || (canvas_buf->canvas.height == 0)) { + gfbg_error("rect error: update rect:(%d,%d,%d,%d), canvas range:(%d,%d)\n", + canvas_buf->update_rect.x, canvas_buf->update_rect.y, + canvas_buf->update_rect.width, canvas_buf->update_rect.height, + canvas_buf->canvas.width, canvas_buf->canvas.height); + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +static td_s32 onrefresh_get_canvas_buf(gfbg_par *par, td_void __user *argp, ot_fb_buf *canvas_buf) +{ + unsigned long lock_flag; + ot_fb_layer_buf buf_mode; + if (osal_copy_from_user(canvas_buf, argp, sizeof(ot_fb_buf))) { + return -EFAULT; + } + + gfbg_get_bufmode(par, &buf_mode); + /* + * check canvas format + * check canvas phyaddr + * check buf_mode + * check canvas update rect legality + */ + if (onrefresh_check_param(par, canvas_buf, buf_mode) != TD_SUCCESS) { + return TD_FAILURE; + } + + /* update canvas update_rect */ + if (canvas_buf->update_rect.x + canvas_buf->update_rect.width > (td_s32)canvas_buf->canvas.width) { + canvas_buf->update_rect.width = canvas_buf->canvas.width - canvas_buf->update_rect.x; + } + + if (canvas_buf->update_rect.y + canvas_buf->update_rect.height > (td_s32)canvas_buf->canvas.height) { + canvas_buf->update_rect.height = canvas_buf->canvas.height - canvas_buf->update_rect.y; + } + + /* Check the legality of physical address and size */ + /* CMPI_CheckMmzphy_addr Call a semaphore, Cannot be used in the interrupt */ + if (!osal_in_interrupt()) { + if (gfbg_check_phyaddr(canvas_buf) != TD_SUCCESS) { + gfbg_error("mmz phy addr 0x%lx invalid.\n", (td_ulong)canvas_buf->canvas.phys_addr); + return TD_FAILURE; + } + } + + if (buf_mode == OT_FB_LAYER_BUF_NONE) { + /* Check if the format of the canvas supported or not by gfbg */ + if ((par->layer_id >= GFBG_MAX_LAYER_NUM) || (canvas_buf->canvas.format >= OT_FB_FORMAT_BUTT)) { + return TD_FAILURE; + } + if (!g_drv_ops.capability[par->layer_id].is_color_format[canvas_buf->canvas.format]) { + gfbg_error("Unsupported PIXEL FORMAT!\n"); + return -EINVAL; + } + /* + * there's a limit from hardware that the start address of screen buf + * should be 16byte aligned. + */ + osal_spin_lock_irqsave(&par->lock, &lock_flag); + if ((canvas_buf->canvas.phys_addr & 0xf) || (canvas_buf->canvas.pitch & 0xf)) { + gfbg_error("addr 0x%lx or pitch: 0x%x is not 16 bytes align !\n", (td_ulong)canvas_buf->canvas.phys_addr, + canvas_buf->canvas.pitch); + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + return TD_FAILURE; + } + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + } else { + /* + * Check if the format of the canvas and the format of + * GFBG belong to the category that TDE can support + */ + if ((!gfbg_tde_is_support_fmt(canvas_buf->canvas.format)) || (!gfbg_tde_is_support_fmt(par->color_format))) { + gfbg_error("Unsupported PIXEL FORMAT!CanvasFmt:%d,par->color_format:%d\n", canvas_buf->canvas.format, + par->color_format); + return -EINVAL; + } + } + return TD_SUCCESS; +} + +static td_s32 gfbg_onrefresh(gfbg_par* par, td_void __user *argp) +{ + td_s32 ret; + ot_fb_buf canvas_buf; + ot_fb_layer_buf buf_mode; + gfbg_display_info *diplay_info = &par->display_info; + + if (is_cursor_layer(par->layer_id) && is_soft_cursor()) { + gfbg_warning("you shouldn't refresh cursor layer!\n"); + return TD_SUCCESS; + } + + if (argp == TD_NULL) { + gfbg_error("NULL arg!\n"); + return -EINVAL; + } + + /* get canvas buffer and check legality */ + ret = onrefresh_get_canvas_buf(par, argp, &canvas_buf); + if (ret != TD_SUCCESS) { + return TD_FAILURE; + } + + gfbg_get_bufmode(par, &buf_mode); + if ((buf_mode == OT_FB_LAYER_BUF_NONE) && (diplay_info->mirror_mode != OT_FB_MIRROR_NONE)) { + gfbg_error("Can't do mirror when the layer buf is none!\n"); + return -EINVAL; + } + + if ((buf_mode == OT_FB_LAYER_BUF_NONE) && (diplay_info->rotate_mode != OT_FB_ROTATE_NONE)) { + gfbg_error("Can't do rotate when the layer buf is none!\n"); + return -EINVAL; + } + ret = gfbg_refresh(par->layer_id, &canvas_buf, buf_mode); + + return ret; +} + +static td_s32 gfbg_set_mirrormode(gfbg_par *par, ot_fb_mirror_mode mirror_mode) +{ + gfbg_display_info *display_info = &par->display_info; + volatile gfbg_compress_info *compress_info = &par->compress_info; + ot_fb_layer_buf buf_mode; + + gfbg_get_bufmode(par, &buf_mode); + + if ((buf_mode == OT_FB_LAYER_BUF_BUTT) || (buf_mode == OT_FB_LAYER_BUF_NONE)) { + gfbg_error("doesn't support FBIOPUT_MIRROR_MODE operation when in standard mode or FB_LAYER_BUF_NONE!\n"); + return TD_FAILURE; + } + + if ((par->color_format != OT_FB_FORMAT_ARGB4444) && (par->color_format != OT_FB_FORMAT_ARGB1555) && + (par->color_format != OT_FB_FORMAT_ARGB8888)) { + gfbg_error("Mirror doesn't support this format:%d.\n!\n", par->color_format); + return -EINVAL; + } + + if (mirror_mode >= OT_FB_MIRROR_BUTT) { + gfbg_error("The input mirror mode is wrong!\n"); + return -EINVAL; + } + + if ((mirror_mode != OT_FB_MIRROR_NONE) && (display_info->rotate_mode != OT_FB_ROTATE_NONE)) { + gfbg_error("Can't do mirror when rotate!\n"); + return -EINVAL; + } + + if ((mirror_mode != OT_FB_MIRROR_NONE) && (compress_info->compress_open == TD_TRUE)) { + gfbg_error("Can't do mirror when compression is on!\n"); + return -EINVAL; + } + + display_info->mirror_mode = mirror_mode; + return TD_SUCCESS; +} + +static td_s32 rotate_vb_init(const struct fb_info *info) +{ + gfbg_par *par = (gfbg_par *)info->par; + gfbg_display_info *display_info = &par->display_info; + td_u32 size; + td_char name[GFBG_ROTBUF_NAME_LEN]; + td_u64 *vir_rotate_vb = TD_NULL; + ot_mpp_chn chn; + mm_malloc_param malloc_param = {0}; + + chn.mod_id = OT_ID_FB; + chn.dev_id = gfbg_vou_get_dev_id(par->layer_id); + chn.chn_id = 0; + + size = gfbg_get_line_length(info) * (((display_info->display_height + 15) / 16) * 16); /* 15 16 align */ + + if (func_entry(sys_export_func, OT_ID_SYS)->pfn_get_mmz_name(&chn, (td_void **)&malloc_param.mmz_name)) { + gfbg_error("get mmz name fail!\n"); + return ENOMEM; + } + + if (snprintf_s(name, sizeof(name), 13, "gfbg%01d_rotate", par->layer_id) < 0) { /* 13:for char length */ + gfbg_error("%s:%d:snprintf_s failure\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + malloc_param.buf_name = name; + malloc_param.size = size; + malloc_param.kernel_only = TD_TRUE; + par->rotate_vb = cmpi_mmz_malloc(&malloc_param); + if (par->rotate_vb == 0) { + gfbg_error("get buffer fail,size %d !\n", size); + return ENOMEM; + } + + vir_rotate_vb = cmpi_remap_nocache(par->rotate_vb, size); + if (vir_rotate_vb == TD_NULL) { + gfbg_error("get buffer fail,size %d !\n", size); + cmpi_mmz_free(par->rotate_vb, TD_NULL); + return ENOMEM; + } + + (td_void)memset_s(vir_rotate_vb, size, 0x0, size); + + cmpi_unmap(vir_rotate_vb); + return TD_SUCCESS; +} + +static td_s32 gfbg_set_rotatemode(const struct fb_info *info, ot_fb_rotate_mode rotate_mode) +{ + gfbg_par *par = (gfbg_par *)info->par; + gfbg_display_info *display_info = &par->display_info; + ot_fb_layer_buf buf_mode; + volatile gfbg_compress_info *compress_info = &par->compress_info; + + gfbg_get_bufmode(par, &buf_mode); + + if (buf_mode == OT_FB_LAYER_BUF_BUTT || buf_mode == OT_FB_LAYER_BUF_NONE) { + gfbg_error("doesn't support FBIOPUT_ROTATE_MODE when in standard mode or FB_LAYER_BUF_NONE!\n"); + return TD_FAILURE; + } + + if ((par->color_format != OT_FB_FORMAT_ARGB4444) && (par->color_format != OT_FB_FORMAT_ARGB1555) && + (par->color_format != OT_FB_FORMAT_ARGB8888)) { + gfbg_error("rotate only support FB_FORMAT_ARGB4444 and FB_FORMAT_ARGB1555 which is %d\n!\n", + par->color_format); + return -EINVAL; + } + + if (rotate_mode >= OT_FB_ROTATE_BUTT) { + gfbg_error("The input rotate mode is wrong!\n"); + return -EINVAL; + } + + if (compress_info->compress_open && rotate_mode != OT_FB_ROTATE_NONE) { + gfbg_error("Can't rotate when in compress mode!\n"); + return -EINVAL; + } + + if ((rotate_mode != OT_FB_ROTATE_NONE) && (display_info->mirror_mode != OT_FB_MIRROR_NONE)) { + gfbg_error("Can't do rotate when mirror!\n"); + return -EINVAL; + } + + if ((rotate_mode == OT_FB_ROTATE_90 || rotate_mode == OT_FB_ROTATE_270) && (par->rotate_vb == 0)) { + /* init rotate vb */ + if (rotate_vb_init(info) != TD_SUCCESS) { + return ENOMEM; + } + } + + display_info->rotate_mode = rotate_mode; + + return TD_SUCCESS; +} + +/* + * Name : gfbg_check_layerinfo + * Desc :check layer information: buf refresh mode,position,canvas width + and height, display width and height, screen width and height. + */ +static td_s32 gfbg_check_layerinfo(const ot_fb_layer_info* layer_info) +{ + if (layer_info->mask & OT_FB_LAYER_MASK_BUF_MODE) { + if (layer_info->buf_mode > OT_FB_LAYER_BUF_DOUBLE_IMMEDIATE) { + gfbg_error("buf_mode(%d) is error, should between %d and %d\n", layer_info->buf_mode, + OT_FB_LAYER_BUF_DOUBLE, OT_FB_LAYER_BUF_DOUBLE_IMMEDIATE); + return TD_FAILURE; + } + } + + /* Detection of anti-flicker mode */ + if (layer_info->mask & OT_FB_LAYER_MASK_ANTIFLICKER_MODE) { + if (layer_info->antiflicker_level > OT_FB_LAYER_ANTIFLICKER_AUTO) { + gfbg_error("antiflicker_level(%d) is error, should between %d and %d\n", layer_info->antiflicker_level, + OT_FB_LAYER_ANTIFLICKER_NONE, OT_FB_LAYER_ANTIFLICKER_AUTO); + return TD_FAILURE; + } + } + + /* check the width and height */ + if (layer_info->mask & OT_FB_LAYER_MASK_DISPLAY_SIZE) { + if (layer_info->display_width % 2 || layer_info->display_height % 2) { /* 2 pixel align */ + gfbg_error("Disaplay W(%u) and H(%u) should align to 2!\n", layer_info->display_width, + layer_info->display_height); + return TD_FAILURE; + } + } + + if (layer_info->mask & OT_FB_LAYER_MASK_SCREEN_SIZE) { + if (layer_info->screen_width % 2 || layer_info->screen_height % 2) { /* 2 pixel align */ + gfbg_error("Screenaplay W(%u) and H(%u) should align to 2!\n", layer_info->screen_width, + layer_info->screen_height); + return TD_FAILURE; + } + } + + /* check pre-multiplier value. */ + if (layer_info->mask & OT_FB_LAYER_MASK_MUL) { + if (TD_TRUE != layer_info->is_premul && TD_FALSE != layer_info->is_premul) { + gfbg_error("pstLayerInfo->is_premul should be TRUE or FALSE but it is %d\n", layer_info->is_premul); + return TD_FAILURE; + } + } + return TD_SUCCESS; +} + +static td_s32 check_display_size(const struct fb_info *info, const gfbg_par *par, const ot_fb_layer_info *layer_info, + td_bool is_interlace) +{ + td_u32 pitch; + if (!g_drv_ops.capability[par->layer_id].is_vo_scale) { + /* + * If the chip does not support scaling, + * if both the display size and the screen size are set , both must be equal. + */ + if ((layer_info->mask & OT_FB_LAYER_MASK_DISPLAY_SIZE) && (layer_info->mask & OT_FB_LAYER_MASK_SCREEN_SIZE)) { + if ((layer_info->display_width != layer_info->screen_width) || + (layer_info->display_height != layer_info->screen_height)) { + gfbg_error("Layer %d doesn't support scaling. Display(%d, %d) is different with Screen(%d, %d).\n", + par->layer_id, layer_info->display_width, layer_info->display_height, + layer_info->screen_width, layer_info->screen_height); + return TD_FAILURE; + } + } + } + + /* Modify the display size, the memory size has changed, limited by the size of the memory */ + if (layer_info->mask & OT_FB_LAYER_MASK_DISPLAY_SIZE) { + pitch = (layer_info->display_width * gfbg_get_bits_per_pixel(info)) >> 3; /* 3 for 8bit */ + pitch = (pitch + 0xf) & 0xfffffff0; + if (gfbg_check_mem_enough(info, pitch, layer_info->display_height) != TD_SUCCESS) { + gfbg_error("memory is not enough!\n"); + return TD_FAILURE; + } + + if (layer_info->display_width == 0 || layer_info->display_height == 0) { + gfbg_error("display width/height shouldn't be 0!\n"); + return TD_FAILURE; + } + /* + * For interlaced output, the height of the layer must be even. + * Progressive output without this limit. + */ + if (is_interlace && ((layer_info->display_height % 2) != 0)) { /* 2 for align */ + gfbg_error("display_height(%d) of layer_id %d should be even when vodev output is interlace\n", + layer_info->display_height, par->layer_id); + return TD_FAILURE; + } + } + return TD_SUCCESS; +} + +static td_s32 onputlayerinfo_check_size(const struct fb_info *info, const gfbg_par *par, + const ot_fb_layer_info *layer_info, td_bool is_interlace) +{ + /* Check the display size */ + if (check_display_size(info, par, layer_info, is_interlace) != TD_SUCCESS) { + return TD_FAILURE; + } + + /* Check the canvas size */ + if (layer_info->mask & OT_FB_LAYER_MASK_CANVAS_SIZE) { + if ((layer_info->canvas_width == 0) || (layer_info->canvas_height == 0)) { + gfbg_error("canvas width/height shouldn't be 0\n"); + return TD_FAILURE; + } + } + + /* Check the screen size */ + if (layer_info->mask & OT_FB_LAYER_MASK_SCREEN_SIZE) { + if ((layer_info->screen_width == 0) || (layer_info->screen_height == 0)) { + gfbg_error("screen width/height shouldn't be 0\n"); + return TD_FAILURE; + } + /* + * For interlaced output, the height of the layer must be even. + * Progressive output without this limit. + */ + if (is_interlace && ((layer_info->screen_height % 2) != 0)) { /* 2 for align */ + gfbg_error("screen_height(%d) of layer_id %d should be even when vodev output is interlace\n", + layer_info->screen_height, par->layer_id); + return TD_FAILURE; + } + } + return TD_SUCCESS; +} + +static td_void gfbg_calculate_argb8888_cmp_stride(const struct fb_info *info, td_u32 *cmp_stride, td_u32 *uncmp_stride) +{ + gfbg_stride_attr attr = {0}; + + /* only argb8888 can support compress with economize memory */ + attr.format = gfbg_getfmtbyargb(&info->var.red, &info->var.green, &info->var.blue, + &info->var.transp, info->var.bits_per_pixel); + attr.width = gfbg_get_xres(info); + attr.is_lossless = TD_FALSE; + attr.is_losslessa = TD_FALSE; + + if (attr.format == OT_FB_FORMAT_ARGB8888) { + gfbg_recalculate_stride(cmp_stride, uncmp_stride, &attr); + } else { + *cmp_stride = *uncmp_stride = gfbg_get_line_length(info); + } + + return; +} + +static td_s32 onputlayerinfo_check_buf_mode(struct fb_info *info, gfbg_par *par, ot_fb_layer_info *layer_info, + td_bool is_interlace) +{ + td_u32 uncmp_layer_size, cmp_layer_size; + td_u32 uncmp_stride, cmp_stride; + + /* Modify the display buf mode, the memory size has changed, limited by the size of the memory */ + if (layer_info->mask & OT_FB_LAYER_MASK_BUF_MODE) { + if (layer_info->buf_mode == OT_FB_LAYER_BUF_ONE) { + uncmp_layer_size = gfbg_get_line_length(info) * gfbg_get_yres(info); + cmp_layer_size = uncmp_layer_size; + } else if ((layer_info->buf_mode == OT_FB_LAYER_BUF_DOUBLE) || + (layer_info->buf_mode == OT_FB_LAYER_BUF_DOUBLE_IMMEDIATE)) { + gfbg_calculate_argb8888_cmp_stride(info, &cmp_stride, &uncmp_stride); + uncmp_layer_size = 2 * uncmp_stride * gfbg_get_yres(info); /* 2 buf */ + cmp_layer_size = 2 * cmp_stride * gfbg_get_yres(info); /* 2 buf */ + } else { + uncmp_layer_size = 0; + cmp_layer_size = 0; + } + + if (gfbg_get_smem_len(info) < uncmp_layer_size && gfbg_get_smem_len(info) < cmp_layer_size) { + /* + * layer real memory size:%d KBytes, expected:%d KBtyes + * real:gfbg_get_smem_len(info)/1024, expectde:uncmp_layer_size/1024 or cmp_layer_size/1024 + */ + gfbg_error("No enough mem!real:%dKB;expected:uncmp%dKB;cmp%dKB\n", + gfbg_get_smem_len(info) / 1024, uncmp_layer_size / 1024, cmp_layer_size / 1024); /* 1024 for KB */ + return TD_FAILURE; + } + + if (gfbg_get_smem_len(info) < uncmp_layer_size && gfbg_get_smem_len(info) >= cmp_layer_size) { + /* this should be FBIOPUT_COMPRESSION_GFBG */ + par->compress_info.is_economize_memory = TD_TRUE; + } + + /* If compression is enabled, only 2buf mode can be set. */ + if (par->compress_info.compress_open) { + if (layer_info->buf_mode != OT_FB_LAYER_BUF_DOUBLE && + layer_info->buf_mode != OT_FB_LAYER_BUF_DOUBLE_IMMEDIATE) { + gfbg_error("only GFBG_LAYER_BUF_DOUBLE/GFBG_LAYER_BUF_DOUBLE_IMMEDIATE support compress!\n"); + return TD_FAILURE; + } + } + } + + /* if x>width or y>height ,how to deal with: see nothing in screen or return failure. */ + if (layer_info->mask & OT_FB_LAYER_MASK_POS) { + if ((layer_info->x_pos < 0) || (layer_info->y_pos < 0)) { + gfbg_error("It's not supported to set start pos of layer to negative!\n"); + return TD_FAILURE; + } + /* + * For interlaced output, the start of the layer must be even. + * Progressive output without this limit. + */ + if (is_interlace && (layer_info->y_pos % 2 != 0)) { /* 2 for align */ + gfbg_error("y_pos should be even for interlace vodev!\n"); + return TD_FAILURE; + } + } + return TD_SUCCESS; +} + +static td_s32 onputlayerinfo_check_premult(const gfbg_par* par, const ot_fb_layer_info *layer_info) +{ + /* Limit the pre-multiplication and color value. */ + if ((layer_info->mask & OT_FB_LAYER_MASK_MUL) && par->ckey.key_enable) { + gfbg_error("Colorkey and premul couldn't take effect at same time!\n"); + return TD_FAILURE; + } + + /* return TD_FAILURE, not allow to set pre-mult mode when the color format is ARGB1555 or ARGB4444 */ + if ((layer_info->mask & OT_FB_LAYER_MASK_MUL) && (layer_info->is_premul == TD_TRUE) && + (par->color_format == OT_FB_FORMAT_ARGB4444 || par->color_format == OT_FB_FORMAT_ARGB1555)) { + gfbg_error("not allow to set pre-mult mode when the color format is ARGB1555 or ARGB4444\n"); + return TD_FAILURE; + } + /* not allow to set pre-mult mode when the GlobalAlpha is 1 */ + if ((layer_info->mask & OT_FB_LAYER_MASK_MUL) && (layer_info->is_premul == TD_TRUE) && + (par->alpha.global_alpha_en == TD_TRUE && par->alpha.global_alpha == 1)) { + gfbg_error("not allow to set pre-mult mode when the GlobalAlpha is 1\n"); + return TD_FAILURE; + } + return TD_SUCCESS; +} + +static td_void onputlayerinfo_set_with_mask(gfbg_par* par, const ot_fb_layer_info *layer_info) +{ + gfbg_display_info *display_info = &par->display_info; + ot_fb_point pos; + + if (layer_info->mask & OT_FB_LAYER_MASK_MUL) { + display_info->is_premul = layer_info->is_premul; + par->param_modify_mask |= GFBG_LAYER_PARAMODIFY_BMUL; + } + + if (layer_info->mask & OT_FB_LAYER_MASK_BUF_MODE) { + gfbg_set_bufmode(par->layer_id, layer_info->buf_mode); + } + + if (layer_info->mask & OT_FB_LAYER_MASK_POS) { + pos.x_pos = layer_info->x_pos; + pos.y_pos = layer_info->y_pos; + gfbg_set_layerpos(par, &pos); + } + + if (layer_info->mask & OT_FB_LAYER_MASK_ANTIFLICKER_MODE) { + gfbg_set_antiflickerlevel(par->layer_id, layer_info->antiflicker_level); + } + return; +} + +static td_s32 onputlayerinfo_process(gfbg_par* par, const ot_fb_layer_info *layer_info) +{ + gfbg_refresh_info *refresh_info = &par->refresh_info; + td_s32 ret = TD_SUCCESS; + unsigned long lock_flag; + + osal_spin_lock_irqsave(&par->lock, &lock_flag); + par->modifying = TD_TRUE; + + /* deal with layer_info->mask */ + onputlayerinfo_set_with_mask(par, layer_info); + + /* set screen size in the scaling mode */ + if (g_drv_ops.capability[par->layer_id].is_vo_scale) { + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + /* + * The following two functions have a sleep operation inside, + * you must unlock before calling, and lock the global amount inside the function. + */ + if (layer_info->mask & OT_FB_LAYER_MASK_SCREEN_SIZE) { + ret = gfbg_disp_setscreensize(par->layer_id, layer_info->screen_width, layer_info->screen_height); + if (ret != TD_SUCCESS) { + return ret; + } + } + if (layer_info->mask & OT_FB_LAYER_MASK_DISPLAY_SIZE) { + ret = gfbg_disp_setdispsize(par->layer_id, layer_info->display_width, layer_info->display_height); + if (ret != TD_SUCCESS) { + return ret; + } + } + osal_spin_lock_irqsave(&par->lock, &lock_flag); + } else { + /* no scaling mode, no buffer mode, screen size and display size can be set */ + if (refresh_info->buf_mode != OT_FB_LAYER_BUF_NONE) { + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + if (layer_info->mask & OT_FB_LAYER_MASK_SCREEN_SIZE) { + ret = gfbg_disp_setscreensize(par->layer_id, layer_info->screen_width, layer_info->screen_height); + } + if (ret != TD_SUCCESS) { + return ret; + } + if (layer_info->mask & OT_FB_LAYER_MASK_DISPLAY_SIZE) { + ret = gfbg_disp_setdispsize(par->layer_id, layer_info->display_width, layer_info->display_height); + } + if (ret != TD_SUCCESS) { + return ret; + } + osal_spin_lock_irqsave(&par->lock, &lock_flag); + } + } + + par->modifying = TD_FALSE; + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + return TD_SUCCESS; +} + +static td_s32 gfbg_onputlayerinfo(struct fb_info *info, gfbg_par* par, const td_void __user *argp) +{ + td_s32 ret = TD_SUCCESS; + ot_fb_layer_info layer_info; + td_bool is_interlace = TD_FALSE; + + if (is_cursor_layer(par->layer_id) && is_soft_cursor()) { + gfbg_warning("you shouldn't put cursor layer info!"); + return TD_SUCCESS; + } + + if (argp == TD_NULL) { + gfbg_error("NULL arg!\n"); + return -EINVAL; + } + + if (osal_copy_from_user(&layer_info, argp, sizeof(ot_fb_layer_info))) { + return -EFAULT; + } + + ret = gfbg_check_layerinfo(&layer_info); + if (ret != TD_SUCCESS) { + return TD_FAILURE; + } + /* + * Check the display size + * Check the canvas size + * Check the screen size + */ + is_interlace = gfbg_is_interlace(par); + if (onputlayerinfo_check_size(info, par, &layer_info, is_interlace) != TD_SUCCESS) { + return TD_FAILURE; + } + /* + * Check when modify buf mode + * Check when modify pos + */ + if (onputlayerinfo_check_buf_mode(info, par, &layer_info, is_interlace) != TD_SUCCESS) { + return TD_FAILURE; + } + /* Check pre-mult */ + if (onputlayerinfo_check_premult(par, &layer_info) != TD_SUCCESS) { + return TD_FAILURE; + } + /* + * avoid modifying register in vo isr before all params has been recorded! + * In vo irq,flag modifying will be checked. + */ + ret = onputlayerinfo_process(par, &layer_info); + if (ret != TD_SUCCESS) { + return ret; + } + ret = gfbg_alloccanbuf(info, &layer_info); + if (ret != TD_SUCCESS) { + /* + * There is no error returned here, because the user can also + * specify this memory; in addition, even if the allocation is successful, + * The user also needs to call FBIOGET_CANVAS_BUF to get it to operate. + */ + gfbg_warning("alloc canvas buffer failed\n"); + } + gfbg_refresh_again(par->layer_id); + return ret; +} + +static td_s32 gfbg_dosetcolreg(const gfbg_cmp_reg *color_reg, const struct fb_info *info, td_bool update_finished_reg) +{ + gfbg_par *par = (gfbg_par *)info->par; + + td_u32 argb = ((color_reg->transp & 0xff) << 24) | ((color_reg->red & 0xff) << 16) | /* 16 24 alg data */ + ((color_reg->green & 0xff) << 8) | (color_reg->blue & 0xff); /* 8 alg data */ + + if (color_reg->regno > 255) { /* 255 is larger than */ + gfbg_warning("regno: %d, larger than 255!\n", color_reg->regno); + return TD_FAILURE; + } + g_drv_ops.gfbg_drv_set_color_reg(par->layer_id, color_reg->regno, argb, update_finished_reg); + return TD_SUCCESS; +} + +static td_s32 gfbg_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, + struct fb_info *info) +{ + gfbg_cmp_reg cmp_reg = {0}; + cmp_reg.regno = regno; + cmp_reg.red = red; + cmp_reg.green = green; + cmp_reg.blue = blue; + cmp_reg.transp = transp; + return gfbg_dosetcolreg(&cmp_reg, info, TD_TRUE); +} + +static td_void gfbg_set_color_reg(struct fb_cmap *cmap, struct fb_info *info) +{ + td_u32 i; + td_s32 start; + unsigned short *red = TD_NULL; + unsigned short *green = TD_NULL; + unsigned short *blue = TD_NULL; + unsigned short *transp = TD_NULL; + gfbg_cmp_reg cmp_reg = {0}; + + cmp_reg.transp = 0xffff; + red = cmap->red; + green = cmap->green; + blue = cmap->blue; + transp = cmap->transp; + +#ifdef __LITEOS__ + start = cmap->first; +#else + start = cmap->start; +#endif + + for (i = 0; i < cmap->len; i++) { + cmp_reg.red = *red++; + cmp_reg.green = *green++; + cmp_reg.blue = *blue++; + if (transp != TD_NULL) { + cmp_reg.transp = *transp++; + } + cmp_reg.regno = start; + if (i < cmap->len - 1) { + if (gfbg_dosetcolreg(&cmp_reg, info, TD_FALSE)) { + break; + } + } else { /* the last time update register */ + if (gfbg_dosetcolreg(&cmp_reg, info, TD_TRUE)) { + break; + } + } + start++; + } + return; +} + +static td_s32 gfbg_setcmap(struct fb_cmap *cmap, struct fb_info *info) +{ + unsigned long lock_flag; + gfbg_par *par = (gfbg_par *)info->par; + +#ifdef CONFIG_GFBG_G0_FHD_SUPPORT + if ((is_hd_layer(par->layer_id)) == TD_FALSE) { + return -EINVAL; + } +#else + if ((is_sd_layer(par->layer_id)) == TD_FALSE) { + return -EINVAL; + } +#endif + + if (g_drv_ops.capability[par->layer_id].is_cmap == TD_FALSE) { + /* AE6D03519, delete this color map warning! */ + return -EPERM; + } + + osal_spin_lock_irqsave(&par->lock, &lock_flag); + par->modifying = TD_TRUE; + gfbg_set_color_reg(cmap, info); + par->param_modify_mask |= GFBG_LAYER_PARAMODIEY_CLUT_UP; + par->modifying = TD_FALSE; + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + + return 0; +} + +#ifdef CONFIG_FB_CFB_IMAGEBLIT +static td_void gfbg_imageblit(struct fb_info *p, const struct fb_image *image) +{ + cfb_imageblit(p, image); +} +#endif + +#ifdef __LITEOS__ +static struct gfbg_info *g_gfbg[GFBG_MAX_LAYER_NUM] = {TD_NULL}; + +static td_s32 copy_rgb_to_cmap(td_u8 *cmap_start, const struct fb_cmap_s *src, struct fb_cmap_s *dst) +{ + td_s32 offset; + td_s32 copy_size; + int cmap_size; + + cmap_size = dst->len * sizeof(u_short); + offset = src->first - dst->first; + copy_size = (src->len > (dst->len - offset)) ? (dst->len - offset) : src->len; + + if (copy_size <= 0) { + return -EINVAL; + } + copy_size *= sizeof(u_short); + + ret = memcpy_s(cmap_start + offset, copy_size, src->red, copy_size); + gfbg_unequal_eok_return(ret); + cmap_start += cmap_size; + ret = memcpy_s(cmap_start + offset, copy_size, src->green, copy_size); + gfbg_unequal_eok_return(ret); + cmap_start += cmap_size; + ret = memcpy_s(cmap_start + offset, copy_size, src->blue, copy_size); + gfbg_unequal_eok_return(ret); + cmap_start += cmap_size; + if (src->transp && dst->transp) { + ret = memcpy_s(cmap_start + offset, copy_size, src->transp, copy_size); + gfbg_unequal_eok_return(ret); + } + return TD_SUCCESS; +} + +static int fb_copy_cmap(const struct fb_cmap_s *src, struct fb_cmap_s *dst) +{ + int offset; + int copy_size; + td_u8 *cmap_start = TD_NULL; + int cmap_size; + int ret; + + if ((src == TD_NULL) || (dst == TD_NULL)) { + return -EINVAL; + } + + cmap_start = dst->red; + if (cmap_start == TD_NULL) + return -EINVAL; + + cmap_size = dst->len * sizeof(u_short); + + if (src->first > dst->first) { + ret = copy_rgb_to_cmap(cmap_start, src, dst); + if (ret != TD_SUCCESS) { + return TD_FAILURE; + } + } else { + offset = dst->first - src->first; + copy_size = ((src->len - offset) > dst->len) ? dst->len : (src->len - offset); + + if (copy_size <= 0) { + return -EINVAL; + } + copy_size *= sizeof(u_short); + + ret = memcpy_s(cmap_start, copy_size, src->red + offset, copy_size); + gfbg_unequal_eok_return(ret); + cmap_start += cmap_size; + ret = memcpy_s(cmap_start, copy_size, src->green + offset, copy_size); + gfbg_unequal_eok_return(ret); + cmap_start += cmap_size; + ret = memcpy_s(cmap_start, copy_size, src->blue + offset, copy_size); + gfbg_unequal_eok_return(ret); + cmap_start += cmap_size; + if (src->transp && dst->transp) { + ret = memcpy_s(cmap_start, copy_size, src->transp + offset, copy_size); + gfbg_unequal_eok_return(ret); + } + } + return 0; +} + +int fb_set_cmap(struct fb_cmap_s *cmap, struct gfbg_info *info) +{ + int ret; + + if (cmap == TD_NULL) { + return -EINVAL; + } + + if ((cmap->first < 0) || (info == TD_NULL)) + return -EINVAL; + + ret = gfbg_setcmap(cmap, info); + if (ret == 0) + fb_copy_cmap(cmap, &info->cmap); + + return ret; +} + +FAR struct fb_vtable_s *up_fbgetvplane(int display, int vplane) +{ + (void)vplane; + if (g_gfbg[display] == TD_NULL) + return TD_NULL; + + return &g_gfbg[display]->vtable; +} + +static int gfbg_getvideoinfo(FAR struct fb_vtable_s *vtable, FAR struct fb_videoinfo_s *vinfo) +{ + struct gfbg_info *info = (struct gfbg_info *)vtable; + td_s32 ret; + + if ((info == TD_NULL) || (vinfo == TD_NULL)) + return -EINVAL; + + ret = memcpy_s(vinfo, sizeof(struct fb_videoinfo_s), &info->vinfo, sizeof(struct fb_videoinfo_s)); + gfbg_unequal_eok_return(ret); + return 0; +} + +static int gfbg_getplaneinfo(FAR struct fb_vtable_s *vtable, int planeno, FAR struct fb_planeinfo_s *pinfo) +{ + struct gfbg_info *info = (struct gfbg_info *)vtable; + + if ((info == TD_NULL) || (pinfo == TD_NULL)) + return -EINVAL; + + pinfo->fbmem = info->oinfo.fbmem; + pinfo->fblen = info->oinfo.fblen; + pinfo->display = info->oinfo.overlay; + pinfo->bpp = info->oinfo.bpp; + pinfo->stride = info->oinfo.stride; + + return 0; +} + +static int gfbg_getoverlayinfo(FAR struct fb_vtable_s *vtable, int overlayno, FAR struct fb_overlayinfo_s *oinfo) +{ + struct gfbg_info *info = (struct gfbg_info *)vtable; + td_s32 ret; + + if ((info == TD_NULL) || (oinfo == TD_NULL)) + return -EINVAL; + + ret = memcpy_s(oinfo, sizeof(struct fb_overlayinfo_s), &info->oinfo, sizeof(struct fb_overlayinfo_s)); + gfbg_unequal_eok_return(ret); + + return 0; +} + +static int gfbg_getcmap(FAR struct fb_vtable_s *vtable, FAR struct fb_cmap_s *cmap) +{ + struct gfbg_info *info = (struct gfbg_info *)vtable; + + if ((info == TD_NULL) || (cmap == TD_NULL)) + return -EINVAL; + + return fb_copy_cmap(&info->cmap, cmap); +} + +static int gfbg_putcmap(FAR struct fb_vtable_s *vtable, FAR const struct fb_cmap_s *cmap) +{ + struct gfbg_info *info = (struct gfbg_info *)vtable; + int cpopy_size; + + if ((info == TD_NULL) || (cmap == TD_NULL)) + return -EINVAL; + + if ((cpopy_size = cmap->len * sizeof(td_u16)) < 0) + return -EINVAL; + + return fb_set_cmap(cmap, info); +} + +static td_s32 fbinitialize_alloc_mem(struct gfbg_info *info) +{ + td_char name[16] = {'\0'}; /* 16 name max length */ + gfbg_par *par = TD_NULL; + par = (gfbg_par *)(info->par); + + if (g_layer[par->layer_id].layer_size != 0) { + /* initialize the fix screen info */ + if (is_4k_layer(par->layer_id)) { + gfbg_screeninfo_init(info, &g_default_info[GFBG_LAYER_TYPE_4K]); + } else if (is_hd_layer(par->layer_id)) { + gfbg_screeninfo_init(info, &g_default_info[GFBG_LAYER_TYPE_HD]); + } else if (is_sd_layer(par->layer_id)) { + gfbg_screeninfo_init(info, &g_default_info[GFBG_LAYER_TYPE_SD]); + } else if (is_ad_layer(par->layer_id)) { + gfbg_screeninfo_init(info, &g_default_info[GFBG_LAYER_TYPE_AD]); + } else if (is_cursor_layer(par->layer_id)) { + gfbg_screeninfo_init(info, &g_default_info[GFBG_LAYER_TYPE_CURSOR]); + } + if (snprintf_s(name, sizeof(name), 12, "gfbg_layer%01u", par->layer_id) < 0) { /* 12:for char length */ + gfbg_error("%s:%d:snprintf_s failure\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + + info->oinfo.fbmem = (void *)gfbg_buf_allocmem(name, strlen(name), (g_layer[par->layer_id].layer_size + + /* 1024 alg data */ + g_layer[par->layer_id].curosr_buf_size) * 1024, g_layer_mmz_names[par->layer_id]); + if (info->oinfo.fbmem == TD_NULL) { + gfbg_error("%s:failed to malloc the video memory, size: %ld KBtyes!\n", name, + (g_layer[par->layer_id].layer_size + g_layer[par->layer_id].curosr_buf_size)); + gfbg_free(info); + g_layer[par->layer_id].info = TD_NULL; + return TD_FAILURE; + } + /* 1024:u32LayerSize is KB */ + info->oinfo.fblen = g_layer[par->layer_id].layer_size * 1024; + + /* initialize the virtual address and clear memory */ + info->oinfo.fbmem = gfbg_buf_map((td_u32)(uintptr_t)info->oinfo.fbmem, + (g_layer[par->layer_id].layer_size + + g_layer[par->layer_id].curosr_buf_size) * 1024); /* 1024 alg data */ + if (info->oinfo.fbmem == TD_NULL) { + gfbg_warning("Failed to call map video memory,size:0x%x, start: 0x%lx\n", info->oinfo.fblen, + info->oinfo.fbmem); + } + + (td_void)memset_s(info->oinfo.fbmem, info->oinfo.fblen, 0, info->oinfo.fblen); + + /* alloc color map */ + if (g_drv_ops.capability[par->layer_id].is_cmap) { + /* now unsupported cmap function */ + } + } + return TD_SUCCESS; +} + +static int up_fbinitialize(int display) +{ + td_s32 ret; + struct gfbg_info *info = TD_NULL; + gfbg_par *par = TD_NULL; + + /* Creates a new frame buffer info structure. reserves gfbg_par for driver private data (info->par) */ + info = gfbg_alloc(sizeof(gfbg_par)); + if (info == TD_NULL) { + gfbg_error("failed to malloc the gfbg_info!\n"); + return -ENOMEM; + } + + /* save the info pointer in global pointer array */ + g_layer[display].info = info; + + info->oinfo.overlay = display; + info->vtable.fb_open = gfbg_open; + info->vtable.fb_release = gfbg_release; + info->vtable.fb_set_par = gfbg_set_par; + info->vtable.fb_pan_display = gfbg_pan_display; + info->vtable.fb_ioctl = gfbg_ioctl; + info->vtable.getvideoinfo = gfbg_getvideoinfo; + info->vtable.getplaneinfo = gfbg_getplaneinfo; + info->vtable.getoverlayinfo = gfbg_getoverlayinfo; + info->vtable.getcmap = TD_NULL; + info->vtable.putcmap = TD_NULL; + + par = (gfbg_par *)(info->par); + (td_void)memset_s(par, sizeof(gfbg_par), 0, sizeof(gfbg_par)); + par->layer_id = display; + par->color_format = OT_FB_FORMAT_ARGB1555; + info->vinfo.format = OT_FB_FORMAT_ARGB1555; + + /* It's not need to alloc mem for cursor layer if use g_softcursor */ + ret = fbinitialize_alloc_mem(info); + if (ret != TD_SUCCESS) { + return ret; + } + + g_gfbg[display] = info; + + return TD_SUCCESS; +} + +static td_void up_fbuninitialize(td_s32 display) +{ + struct gfbg_info* info = TD_NULL; + + /* get framebuffer info structure pointer */ + info = g_layer[display].info; + if (info != TD_NULL) { + if (info->oinfo.fbmem) { + gfbg_buf_ummap(info->oinfo.fbmem); + gfbg_buf_freemem((td_u32)(uintptr_t)info->oinfo.fbmem); + } + + gfbg_free(info); + g_layer[display].info = TD_NULL; + g_gfbg[display] = TD_NULL; + } +} + +static td_void gfbg_overlay_cleanup(td_u32 layer_id, td_bool unregister) +{ + td_s32 ret; + + ret = fb_unregister(layer_id); + if (ret < 0) { + gfbg_error("gfbg overlay cleanup fail!\n"); + } + + return; +} + +static td_s32 gfbg_overlay_probe(td_u32 layer_id) +{ + td_s32 ret = TD_FAILURE; + + if ((ret = fb_register(layer_id, 0)) < 0) { + gfbg_error("failed to register_framebuffer!\n"); + ret = -EINVAL; + goto ERR; + } + + return TD_SUCCESS; + +ERR: + gfbg_overlay_cleanup(layer_id, TD_FALSE); + + return ret; +} + +#else +/* + * Name : g_ot_fb_ops + * Desc : fb struct + * See : gfbg_overlay_probe + */ +static struct fb_ops g_ot_fb_ops = { + .owner = THIS_MODULE, + .fb_open = gfbg_open, + .fb_release = gfbg_release, + .fb_check_var = gfbg_check_var, + .fb_set_par = gfbg_set_par, + .fb_pan_display = gfbg_pan_display, + .fb_ioctl = gfbg_ioctl, + .fb_setcolreg = gfbg_setcolreg, + .fb_setcmap = gfbg_setcmap, +#ifdef CONFIG_COMPAT + .fb_compat_ioctl = gfbg_compat_ioctl, +#endif +#ifdef CONFIG_FB_CFB_IMAGEBLIT + .fb_imageblit = gfbg_imageblit, +#endif +}; + +/* + * Function : gfbg_overlay_cleanup + * Description : releae the resource for certain framebuffer + */ +static td_void gfbg_overlay_cleanup(td_u32 layer_id, td_bool unregister) +{ + struct fb_info* info = TD_NULL; + + /* get framebuffer info structure pointer */ + info = g_layer[layer_id].info; + if (info != TD_NULL) { + if (gfbg_get_screen_base(info)) { + gfbg_buf_ummap(gfbg_get_screen_base(info)); + } + + if (gfbg_get_smem_start(info)) { + gfbg_buf_freemem(gfbg_get_smem_start(info)); + } + + if (unregister) { + unregister_framebuffer(info); + } + + framebuffer_release(info); + g_layer[layer_id].info = TD_NULL; + } + + return; +} + +static td_s32 overlay_probe_alloc_mem(struct fb_info *info, struct fb_fix_screeninfo *fix, + struct fb_var_screeninfo *var) +{ + gfbg_par *par = TD_NULL; + td_u32 layer_id; + td_char name[16]; /* 16 for length of name */ + + par = (gfbg_par *)(info->par); + layer_id = par->layer_id; + + if (g_layer[layer_id].layer_size != 0) { + /* initialize the fix screen info */ + if (is_4k_layer(layer_id)) { + *fix = g_default_fix[GFBG_LAYER_TYPE_4K]; + *var = g_default_var[GFBG_LAYER_TYPE_4K]; + } else if (is_hd_layer(layer_id)) { + *fix = g_default_fix[GFBG_LAYER_TYPE_HD]; + *var = g_default_var[GFBG_LAYER_TYPE_HD]; + } else if (is_sd_layer(layer_id)) { + *fix = g_default_fix[GFBG_LAYER_TYPE_SD]; + *var = g_default_var[GFBG_LAYER_TYPE_SD]; + } else if (is_ad_layer(layer_id)) { + *fix = g_default_fix[GFBG_LAYER_TYPE_AD]; + *var = g_default_var[GFBG_LAYER_TYPE_AD]; + } else if (is_cursor_layer(layer_id)) { + *fix = g_default_fix[GFBG_LAYER_TYPE_CURSOR]; + *var = g_default_var[GFBG_LAYER_TYPE_CURSOR]; + } + if (snprintf_s(name, sizeof(name), 12, "gfbg_layer%01u", layer_id) < 0) { /* 12:for char length */ + gfbg_error("%s:%d:snprintf_s failure\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + fix->smem_start = (td_ulong)gfbg_buf_allocmem(name, strlen(name), + (g_layer[layer_id].layer_size + g_layer[layer_id].curosr_buf_size) * 1024, /* 1024 for 1k */ + gfbg_get_layer_mmz_names(layer_id)); + if (fix->smem_start == 0) { + gfbg_error("%s:failed to malloc the video memory, size: %ld KBtyes!\n", name, + (g_layer[layer_id].layer_size + g_layer[layer_id].curosr_buf_size)); + return TD_FAILURE; + } + /* u32LayerSize is KB */ + fix->smem_len = g_layer[layer_id].layer_size * 1024; /* 1024 for 1k */ + + /* initialize the virtual address and clear memory */ + info->screen_base = gfbg_buf_map(fix->smem_start, (g_layer[layer_id].layer_size + + g_layer[layer_id].curosr_buf_size) * 1024); /* 1024 for 1k */ + + if (info->screen_base == TD_NULL) { + gfbg_error("Failed to call map video memory,size:0x%x, start: 0x%lx\n", + fix->smem_len, fix->smem_start); + gfbg_buf_freemem(fix->smem_start); + fix->smem_start = 0; + return TD_FAILURE; + } + gfbg_drv_set_mmz_addr(fix->smem_start, fix->smem_len, layer_id); + + /* Initialize the memory to 0. Call TDE to do it. */ + gfbg_fill_data(info, 0, gfbg_get_smem_len(info)); + } + return TD_SUCCESS; +} + +static td_s32 gfbg_overlay_probe(td_u32 layer_id) +{ + td_s32 ret = TD_FAILURE; + struct fb_info *info = TD_NULL; + struct fb_fix_screeninfo *fix = TD_NULL; + struct fb_var_screeninfo *var = TD_NULL; + gfbg_par *par = TD_NULL; + + /* + * The size of the size represents the private data space of the device, + * and the par of fb_info points to the private space, that is, + * info->par already points to the memory space + */ + info = framebuffer_alloc(sizeof(gfbg_par), TD_NULL); + if (info == TD_NULL) { + gfbg_error("failed to malloc the fb_info!\n"); + return -ENOMEM; + } + fix = &info->fix; + var = &info->var; + /* save the info pointer in global pointer array */ + g_layer[layer_id].info = info; + + info->flags = FBINFO_FLAG_DEFAULT | FBINFO_HWACCEL_YPAN | FBINFO_HWACCEL_XPAN; + /* fbops members in fb_info point to g_ot_fb_ops, so open, release, ioctl, etc. can get fb_info. */ + info->fbops = &g_ot_fb_ops; + + par = (gfbg_par *)(info->par); + (td_void)memset_s(par, sizeof(gfbg_par), 0, sizeof(gfbg_par)); + par->layer_id = layer_id; + par->color_format = OT_FB_FORMAT_ARGB1555; + + if (snprintf_s(fix->id, sizeof(fix->id), 5, "ovl%01u", layer_id) < 0) { /* 5:for char length */ + gfbg_error("%s:%d:snprintf_s failure\n", __FUNCTION__, __LINE__); + ret = TD_FAILURE; + goto ERR; + } + /* It's not need to alloc mem for cursor layer if use g_softcursor */ + ret = overlay_probe_alloc_mem(info, fix, var); + if (ret != TD_SUCCESS) { + goto ERR; + } + + if ((ret = register_framebuffer(info)) < 0) { + gfbg_error("failed to register_framebuffer!layerid = %d, s32Ret = %d\n", layer_id, ret); + ret = -EINVAL; + goto ERR; + } + + gfbg_info("succeed in registering the fb%d: %s frame buffer device\n", info->node, fix->id); + + return TD_SUCCESS; + +ERR: + gfbg_overlay_cleanup(layer_id, TD_FALSE); + + return ret; +} + +#endif + +/* + * Function : gfbg_get_vram_size + * Description : parse the parameter string and get the size. if + the parameter is invalid, the size is default value. + * Input : const char* pstr the string for the vram size + * Return : the video memory size + */ +static unsigned long gfbg_get_vram_size(const char* pstr) +{ + td_s32 str_is_valid = TD_TRUE; + unsigned long vram_size = 0; + unsigned long vram_size_temp; + const char* ptr = pstr; + + if ((ptr == TD_NULL) || (*ptr == '\0')) { + return 0; + } + + /* check if the string is valid */ + while (*ptr != '\0') { + if (*ptr == ',') { + break; + } else if ((!((*ptr) >= '0' && (*ptr) <= '9')) && (*ptr != 'X') && (*ptr != 'x') && + ((*ptr > 'f' && *ptr <= 'z') || (*ptr > 'F' && *ptr <= 'Z'))) { + str_is_valid = TD_FALSE; + break; + } + + ptr++; + } + + if (str_is_valid) { + vram_size = osal_strtoul(pstr, (char **)TD_NULL, 0); + if (vram_size > PAGE_SIZE_ALIGN_MAX) { + gfbg_error("vram_size(%lu)( > %lu) is overflow, it will be set to %u!\n", vram_size, + PAGE_SIZE_ALIGN_MAX, 0); + vram_size = 0; + } + + vram_size_temp = vram_size; + /* make the size PAGE_SIZE align */ + vram_size = ((vram_size * 1024 + PAGE_SIZE - 1) & PAGE_MASK) / 1024; /* 2^10 1024 */ + if (vram_size_temp != vram_size) { + gfbg_error("vram_size(%lu) if not align in 4, it will be set to %lu!\n", vram_size_temp, vram_size); + } + } + return vram_size; +} + +static td_void parse_cfg_start(td_char **sc_str) +{ + /* judge the cursor if use soft or hard layer */ + if (!osal_strcmp("off", g_softcursor)) { + g_soft_cursor = TD_FALSE; + } else { + g_soft_cursor = TD_TRUE; + } + + /* judge the display is need on */ + if (!osal_strcmp("on", g_display)) { + g_display_on = TD_TRUE; + } else { + g_display_on = TD_FALSE; + } + + /* get the string before next varm */ + *sc_str = osal_strstr(g_video, "vram"); + gfbg_info("video:%s\n", g_video); + + return; +} + +static td_void parse_cfg_change_layer_size(const td_char *sc_str, td_u32 layer_id) +{ + td_ulong layer_size; + layer_size = gfbg_get_vram_size(sc_str); + + if (g_drv_ops.capability[layer_id].is_layer_support) { + if (is_cursor_layer(layer_id)) { + if (!is_soft_cursor()) { + g_layer[layer_id].layer_size = layer_size; + } + } else { + g_layer[layer_id].layer_size = layer_size; + if (is_soft_cursor() && layer_size) { + g_layer[layer_id].curosr_buf_size = GFBG_CURSOR_DEF_VRAM; + } + } + } + return; +} + +static td_s32 parse_cfg_change_layer_id(td_u32 *layer_id, const td_char *number, td_u32 length) +{ + if (length > 4) { /* 4 for array number max length */ + gfbg_error("length = %d; out of range!\n", length); + return TD_FAILURE; + } + + *layer_id = osal_strtoul(number, (char **)TD_NULL, 10); /* 10 for length */ + if (*layer_id >= g_drv_ops.layer_count) { + gfbg_error("Layer %d is in module_param---video out of range!\n", *layer_id); + return TD_FAILURE; + } + + if (!g_drv_ops.capability[*layer_id].is_layer_support) { + gfbg_error("Layer %d unsupported, so module_param---video can't contain vram_size for it!\n", *layer_id); + return TD_FAILURE; + } + return TD_SUCCESS; +} + +/* + * Name : gfbg_parse_cfg + * Desc : Parse the parameters. + * See : gfbg_overlay_probe + */ +static td_s32 gfbg_parse_cfg(td_void) +{ + td_char *sc_str = TD_NULL; + td_char number[4] = {0}; /* 4 cfg num */ + td_u32 i; + td_u32 j; + td_u32 layer_id; + td_char ac_param[12] = {0}; /* 12 param length */ + td_char ac_temp[12] = {0}; /* 12 param length */ + td_bool is_param_valid = TD_FALSE; + + /* + * 1.judge the cursor if use soft or hard layer + * 2.judge the display is need on + * 3.get the string before next varm + */ + parse_cfg_start(&sc_str); + + /* parse cfg process */ + while (sc_str != TD_NULL) { + /* parse the layer id and save it in a string */ + i = 0; + + /* if the number of graphics layers is 10 or more, the string is risky */ + for (j = 0; j < g_drv_ops.layer_count; j++) { + if (snprintf_s(ac_param, sizeof(ac_param), 11, "vram%01u_size", j) < 0) { /* 11:for char length */ + gfbg_error("%s:%d:snprintf_s failure!\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + if (strncpy_s(ac_temp, sizeof(ac_temp), sc_str, 10) != EOK) { /* 10 cpy num */ + gfbg_error("%s:%d:strncpy_s failure!\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } + if (!osal_strcmp(ac_param, ac_temp)) { + is_param_valid = TD_TRUE; + } + } + if (!is_param_valid) { + gfbg_error("insmod parameter is invalid!\n"); + return TD_FAILURE; + } + /* 4:skip "vram" */ + sc_str += 4; + while (*sc_str != '_') { + /* i>1 means layer id is bigger than 100, it's obviously out of range! */ + if (i > 1) { + gfbg_error("layer id is out of range!\n"); + return -1; + } + + number[i] = *sc_str; + i++; + sc_str++; + } + + number[i] = '\0'; + + /* change the layer id string into digital and assure it's legal */ + if (parse_cfg_change_layer_id(&layer_id, number, sizeof(number)) != TD_SUCCESS) { + return TD_FAILURE; + } + + sc_str += sizeof("size") + i; + /* get the layer size string and change it to digital */ + parse_cfg_change_layer_size(sc_str, layer_id); + + /* get next layer string */ + sc_str = osal_strstr(sc_str, "vram"); + } + + return TD_SUCCESS; +} + +#ifdef CONFIG_OT_PROC_SHOW_SUPPORT +static const td_char* g_fmt_name[] = { + "RGB565", + "RGB888", + "KRGB444", + "KRGB555", + "KRGB888", + "ARGB4444", + "ARGB1555", + "ARGB8888", + "ARGB8565", + "RGBA4444", + "RGBA5551", + "RGBA5658", + "RGBA8888", + "BGR565", + "BGR888", + "ABGR4444", + "ABGR1555", + "ABGR8888", + "ABGR8565", + "KBGR444", + "KBGR555", + "KBGR888", + "1BPP", + "2BPP", + "4BPP", + "8BPP", + "ACLUT44", + "ACLUT88", + "PUYVY", + "PYUYV", + "PYVYU", + "YUV888", + "AYUV8888", + "YUVA8888", + "BUTT" +}; + +static const td_char *g_layer_name[] = {"layer_0", "layer_1", "layer_2", "layer_3", "layer_4"}; +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC +static td_s32 gfbg_print_softcursor_proc(struct fb_info *info, osal_proc_entry *p, td_void *v) +{ + gfbg_par *par = (gfbg_par *)info->par; + const td_char *layer_name = TD_NULL; + ot_unused(v); + + if (par->layer_id >= sizeof(g_layer_name) / sizeof(td_char *)) { + layer_name = "unknown layer"; + } else { + layer_name = g_layer_name[par->layer_id]; + } + + osal_seq_printf(p->seqfile, "layer_name \t: %s \n", layer_name); + osal_seq_printf(p->seqfile, "show_state \t :%s\n", par->show ? "ON" : "OFF"); + osal_seq_printf(p->seqfile, "referecce_count \t :%d\n", atomic_read(&par->ref_count)); + osal_seq_printf(p->seqfile, "position \t :(%d, %d)\n", par->display_info.pos.x_pos, + par->display_info.pos.y_pos); + osal_seq_printf(p->seqfile, "color_format: \t :%s\n", g_fmt_name[par->color_format]); + osal_seq_printf(p->seqfile, "pixel_alpha \t :%s\n", par->alpha.pixel_alpha ? "ON" : "OFF"); + osal_seq_printf(p->seqfile, "global_alpha_en \t :%s\n", par->alpha.global_alpha_en ? "ON" : "OFF"); + osal_seq_printf(p->seqfile, "alpha0, alpha1 \t :%d, %d\n", par->alpha.alpha0, par->alpha.alpha1); + osal_seq_printf(p->seqfile, "alpha_global \t :%d\n", par->alpha.global_alpha); + osal_seq_printf(p->seqfile, "colorkey_en \t :%s\n", par->ckey.key_enable ? "ON" : "OFF"); + osal_seq_printf(p->seqfile, "colorkey_value \t :0x%x\n", par->ckey.key); + osal_seq_printf(p->seqfile, "cursor_hot_pos(x, y) \t :(%d, %d)\n", par->cursor_info.cursor.hot_pos.x_pos, + par->cursor_info.cursor.hot_pos.y_pos); + return 0; +} + +static td_void print_cursor_proc(osal_proc_entry *p, const gfbg_par *par) +{ + osal_seq_printf(p->seqfile, "attach_cursor_id: \t :%d \n", par->cursor_info.attached_cursor_id); + osal_seq_printf(p->seqfile, "backup_cursor_addr \t :0x%ld\n", + (td_ulong)par->cursor_info.cursor.cursor.phys_addr); + osal_seq_printf(p->seqfile, "backup_cursor_format \t :%s\n", g_fmt_name[par->cursor_info.cursor.cursor.format]); + osal_seq_printf(p->seqfile, "backup_cursor_stride \t :%d\n", par->cursor_info.cursor.cursor.pitch); + osal_seq_printf(p->seqfile, "backup_cursor (width, h) \t :(%d, %d)\n", + par->cursor_info.cursor.cursor.width, par->cursor_info.cursor.cursor.height); + osal_seq_printf(p->seqfile, "cursor_rect in display buffer \t :(%d, %d, %d, %d)\n", + par->cursor_info.rect_in_disp_buf.x, par->cursor_info.rect_in_disp_buf.y, + par->cursor_info.rect_in_disp_buf.width, par->cursor_info.rect_in_disp_buf.height); + osal_seq_printf(p->seqfile, "cursor_pos in cursor image \t :(%d, %d)\n", + par->cursor_info.pos_in_cursor.x_pos, par->cursor_info.pos_in_cursor.y_pos); + return; +} +#endif + +static td_void print_canvas_proc(osal_proc_entry *p, const gfbg_par *par) +{ + const gfbg_refresh_info *refresh_info = &par->refresh_info; + const volatile gfbg_compress_info *compress_info = &par->compress_info; + graphic_layer_context *gfx_layer_ctx = fb_graphics_get_gfx_layer_ctx(); + + osal_seq_printf(p->seqfile, "canavas_updated_addr \t :0x%lx\n", + (td_ulong)refresh_info->user_buffer.canvas.phys_addr + + refresh_info->user_buffer.update_rect.y * refresh_info->user_buffer.update_rect.width + + refresh_info->user_buffer.update_rect.x); + osal_seq_printf(p->seqfile, "canavas_updated (w, h) \t :%d,%d \n", refresh_info->user_buffer.update_rect.width, + refresh_info->user_buffer.update_rect.height); + osal_seq_printf(p->seqfile, "canvas_width \t :%d\n", refresh_info->user_buffer.canvas.width); + osal_seq_printf(p->seqfile, "canvas_height \t :%d\n", refresh_info->user_buffer.canvas.height); + osal_seq_printf(p->seqfile, "canvas_pitch \t :%d\n", refresh_info->user_buffer.canvas.pitch); + osal_seq_printf(p->seqfile, "canvas_format \t :%s\n", + g_fmt_name[refresh_info->user_buffer.canvas.format]); + osal_seq_printf(p->seqfile, "is_compress \t :%s\n", compress_info->compress_open ? "YES" : "NO"); + osal_seq_printf(p->seqfile, "is_ddr_dettect \t :%s\n", (compress_info->compress_open && + compress_info->zone_nums && (refresh_info->buf_mode == OT_FB_LAYER_BUF_NONE || + refresh_info->buf_mode == OT_FB_LAYER_BUF_BUTT)) ? "YES" : "NO"); + osal_seq_printf(p->seqfile, "ddr_detect_zones \t :%d\n", (compress_info->compress_open && + (refresh_info->buf_mode == OT_FB_LAYER_BUF_NONE || + refresh_info->buf_mode == OT_FB_LAYER_BUF_BUTT)) ? compress_info->zone_nums : 0); + osal_seq_printf(p->seqfile, "premul_enable \t :%s\n", par->display_info.is_premul ? "ON" : "OFF"); + osal_seq_printf(p->seqfile, "layer_csc_matrix: \t :%d\n", gfx_layer_ctx[par->layer_id].gfx_csc.csc_matrix); + osal_seq_printf(p->seqfile, "layer_luma: \t :%d\n", gfx_layer_ctx[par->layer_id].gfx_csc.luma); + osal_seq_printf(p->seqfile, "layer_contrast: \t :%d\n", gfx_layer_ctx[par->layer_id].gfx_csc.contrast); + osal_seq_printf(p->seqfile, "layer_hue: \t :%d\n", gfx_layer_ctx[par->layer_id].gfx_csc.hue); + osal_seq_printf(p->seqfile, "layer_saturation: \t :%d\n", gfx_layer_ctx[par->layer_id].gfx_csc.saturation); + osal_seq_printf(p->seqfile, "layer_ex_csc_en: \t :%s\n", + gfx_layer_ctx[par->layer_id].gfx_csc.ex_csc_en == TD_TRUE ? "ON" : "OFF"); + return; +} + +static td_void print_display_proc(osal_proc_entry *p, gfbg_par *par) +{ + const td_char *buf_mode[] = {"triple", "double", "single", "triple( no frame discarded)", "unknown"}; + gfbg_display_info *display_info = &par->display_info; + gfbg_refresh_info *refresh_info = &par->refresh_info; + + osal_seq_printf(p->seqfile, "display_buffer_mode(+usr_buf)\t :%s\n", buf_mode[refresh_info->buf_mode]); + osal_seq_printf(p->seqfile, "displaying_addr (register) \t :0x%lx\n", (td_ulong)refresh_info->screen_addr); + osal_seq_printf(p->seqfile, "display_buffer[0] addr \t :0x%lx\n", + (td_ulong)refresh_info->disp_buf_info.phys_addr[0]); + osal_seq_printf(p->seqfile, "display_buffer[1] addr \t :0x%lx\n", + (td_ulong)refresh_info->disp_buf_info.phys_addr[1]); + osal_seq_printf(p->seqfile, "is_premul_mode: \t :%s\n", + (display_info->is_premul == TD_TRUE) ? "YES" : "NO"); + osal_seq_printf(p->seqfile, "display_rect \t :(%d, %d)\n", display_info->display_width, + display_info->display_height); + osal_seq_printf(p->seqfile, "screen_rect \t :(%d, %d)\n", display_info->screen_width, + display_info->screen_height); + osal_seq_printf(p->seqfile, "device_max_resolution \t :%d, %d\n", display_info->max_screen_width, + display_info->max_screen_height); + osal_seq_printf(p->seqfile, "is_need_flip(2buf) \t :%s\n", + refresh_info->disp_buf_info.need_flip ? "YES" : "NO"); + osal_seq_printf(p->seqfile, "buf_index_displaying(2buf)\t :%d\n", refresh_info->disp_buf_info.index_for_int); + osal_seq_printf(p->seqfile, "refresh_request_num(2buf) \t :%d\n", refresh_info->refresh_num); + osal_seq_printf(p->seqfile, "switch_buf_num(2buf) \t :%d\n", refresh_info->disp_buf_info.int_pic_num); + osal_seq_printf(p->seqfile, "union_rect (2buf) \t :(%d,%d,%d,%d)\n", + refresh_info->disp_buf_info.union_rect.x, refresh_info->disp_buf_info.union_rect.y, + refresh_info->disp_buf_info.union_rect.width, refresh_info->disp_buf_info.union_rect.height); + return; +} + +static td_void print_common_proc(osal_proc_entry *p, struct fb_info *info, const td_char *layer_name) +{ + gfbg_par *par = (gfbg_par *)info->par; + gfbg_display_info *display_info = &par->display_info; + gfbg_refresh_info *refresh_info = &par->refresh_info; + const td_char *antiflicer_level[] = {"NONE", "LOW", "MIDDLE", "HIGH", "AUTO", "ERROR"}; + const td_char *mirror_mode[] = {"NONE", "HORIZONTAL", "VERTICAL", "BOTH", "unknown"}; + const td_char *anti_mode[] = {"NONE", "TDE", "VOU", "ERROR"}; + const td_char *rotation_mode[] = {"0", "90", "180", "270", "-"}; + + osal_seq_printf(p->seqfile, "\n[GFBG] Version: ["OT_MPP_VERSION"], Build Time["__DATE__", "__TIME__"]\n"); + osal_seq_printf(p->seqfile, "\n"); + osal_seq_printf(p->seqfile, "layer_name \t :%s \n", layer_name); + osal_seq_printf(p->seqfile, "open_count \t :%d\n", atomic_read(&par->ref_count)); + osal_seq_printf(p->seqfile, "show_state \t :%s\n", (par->show) ? "ON" : "OFF"); + osal_seq_printf(p->seqfile, "graphic_enable \t :%s\n", (par->layer_open == TD_TRUE) ? "ON" : "OFF"); + osal_seq_printf(p->seqfile, "start_position \t :(%d, %d)\n", display_info->pos.x_pos, + display_info->pos.y_pos); + osal_seq_printf(p->seqfile, "xres, yres \t :(%d, %d)\n", gfbg_get_xres(info), gfbg_get_yres(info)); + osal_seq_printf(p->seqfile, "xres_virtual, yres_virtual \t :(%d, %d)\n", gfbg_get_xres_virtual(info), + gfbg_get_yres_virtual(info)); + osal_seq_printf(p->seqfile, "xoffset, yoffset \t :(%d, %d)\n", gfbg_get_xoffset(info), + gfbg_get_yoffset(info)); + osal_seq_printf(p->seqfile, "fix.line_length \t :%d\n", gfbg_get_line_length(info)); + osal_seq_printf(p->seqfile, "mem_size: \t :%d KB\n", gfbg_get_smem_len(info) / 1024); /* 1024 1K */ + osal_seq_printf(p->seqfile, "layer_scale (hw): \t :%s \n", + g_drv_ops.capability[par->layer_id].is_vo_scale ? "YES" : "NO"); + osal_seq_printf(p->seqfile, "color_format: \t :%s\n", g_fmt_name[par->color_format]); + osal_seq_printf(p->seqfile, "pixel_alpha \t :%s\n", par->alpha.pixel_alpha ? "ON" : "OFF"); + osal_seq_printf(p->seqfile, "global_alpha_en \t :%s\n", par->alpha.global_alpha_en ? "ON" : "OFF"); + osal_seq_printf(p->seqfile, "alpha0, alpha1 \t :%d, %d\n", par->alpha.alpha0, par->alpha.alpha1); + osal_seq_printf(p->seqfile, "alpha_global \t :%d\n", par->alpha.global_alpha); + osal_seq_printf(p->seqfile, "colorkey_en \t :%s\n", par->ckey.key_enable ? "ON" : "OFF"); + osal_seq_printf(p->seqfile, "colorkey_value \t :0x%x\n", par->ckey.key); + osal_seq_printf(p->seqfile, "mirror_mode: \t :%s\n", mirror_mode[display_info->mirror_mode]); + osal_seq_printf(p->seqfile, "dynamic_range: \t :%s\n", "SDR8"); + osal_seq_printf(p->seqfile, "deflicker_mode: \t :%s\n", anti_mode[display_info->antiflicker_mode]); + osal_seq_printf(p->seqfile, "rotation_mode: \t :%s\n", rotation_mode[display_info->rotate_mode]); + osal_seq_printf(p->seqfile, "deflicker_level: \t :%s\n", + antiflicer_level[display_info->antiflicker_level]); + osal_seq_printf(p->seqfile, "gfbg_mode: \t :%s\n", + (refresh_info->buf_mode == OT_FB_LAYER_BUF_BUTT) ? "STANDARD" : "EXTEND"); + return; +} + +static td_s32 gfbg_print_layer_proc(struct fb_info *info, osal_proc_entry *p, td_void *v) +{ + gfbg_par *par = (gfbg_par *)info->par; + gfbg_display_info *display_info = &par->display_info; + const td_char *layer_name = TD_NULL; + ot_unused(v); + + if (par->layer_id >= sizeof(g_layer_name) / sizeof(td_char *)) { + layer_name = "unknown layer"; + } else { + layer_name = g_layer_name[par->layer_id]; + } + + if (display_info->antiflicker_mode > GFBG_ANTIFLICKER_BUTT) { + display_info->antiflicker_mode = GFBG_ANTIFLICKER_BUTT; + } + + if (display_info->antiflicker_level > OT_FB_LAYER_ANTIFLICKER_BUTT) { + display_info->antiflicker_level = OT_FB_LAYER_ANTIFLICKER_BUTT; + } + + print_common_proc(p, info, layer_name); + + print_display_proc(p, par); + + print_canvas_proc(p, par); + +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC + if (par->cursor_info.attached && is_soft_cursor()) { + print_cursor_proc(p, par); + } +#endif + return TD_SUCCESS; +} + +static td_s32 gfbg_read_proc(osal_proc_entry *entry) +{ + struct fb_info *info = TD_NULL; + gfbg_par *par = TD_NULL; + if (entry == TD_NULL) { + return TD_FAILURE; + } + info = (struct fb_info *)(entry->private_data); + if (info == TD_NULL) { + return TD_FAILURE; + } + par = (gfbg_par *)info->par; + if (par == TD_NULL) { + return TD_FAILURE; + } + + if (!is_cursor_layer(par->layer_id) || !is_soft_cursor()) { + return gfbg_print_layer_proc(info, entry, TD_NULL); +#ifdef CONFIG_GFBG_NOT_SUPPORT_FUNC + } else { + return gfbg_print_softcursor_proc(info, entry, TD_NULL); +#endif + } + + return TD_SUCCESS; +} + +static td_void parse_procmd_help(const gfbg_par *par, const td_char *cmd) +{ + if (osal_strncmp("help", cmd, 4) == 0) { /* 4 cmp */ + osal_printk("help info:\n"); + osal_printk("echo cmd > proc file\n"); + osal_printk("gfbg support cmd:\n"); + osal_printk("show:show layer\n"); + osal_printk("hide:hide layer\n"); + osal_printk("For example, if you want to hide layer 0,you can input:\n"); + osal_printk(" echo hide > /proc/umap/gfbg0\n"); + } else { + gfbg_error("layer_id %d doesn't support cmd:%s, use help cmd to show help info!\n", + par->layer_id, cmd); + } + return; +} + +static td_void gfbg_parse_proccmd(const osal_proc_entry *p, td_u32 layer_id, const td_char *cmd) +{ + struct fb_info *info = g_layer[layer_id].info; + gfbg_par *par = (gfbg_par *)info->par; + td_s32 cnt; + unsigned long lock_flag; + ot_unused(p); + + osal_spin_lock_irqsave(&par->lock, &lock_flag); + cnt = atomic_read(&par->ref_count); + + if (osal_strncmp("show", cmd, 4) == 0) { /* 4 cmp */ + if (cnt == 0) { + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + gfbg_error("err:layer_id %d no open!\n", par->layer_id); + return; + } + + if (is_cursor_layer(par->layer_id) && is_soft_cursor()) { + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + gfbg_error("cursor layer %d doesn't support this cmd!\n", par->layer_id); + return; + } + + if (!par->show) { + par->modifying = TD_TRUE; + par->show = TD_TRUE; + par->param_modify_mask |= GFBG_LAYER_PARAMODIFY_SHOW; + par->modifying = TD_FALSE; + } + } else if (osal_strncmp("hide", cmd, 4) == 0) { /* 4 cmp */ + if (cnt == 0) { + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + gfbg_error("err:layer_id %d no open!\n", par->layer_id); + return; + } + + if (is_cursor_layer(par->layer_id) && is_soft_cursor()) { + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + gfbg_error("cursor layer %d doesn't support this cmd!\n", par->layer_id); + return; + } + + if (par->show) { + par->modifying = TD_TRUE; + par->show = TD_FALSE; + par->param_modify_mask |= GFBG_LAYER_PARAMODIFY_SHOW; + par->modifying = TD_FALSE; + } + } + + osal_spin_unlock_irqrestore(&par->lock, &lock_flag); + + parse_procmd_help(par, cmd); + return; +} + +static td_s32 gfbg_write_proc(osal_proc_entry *entry, const char *buf, int count, long long *ppos) +{ +#ifndef __LITEOS__ +#define TMP_BUF_LEN 32 + struct fb_info *info = TD_NULL; + gfbg_par *par = TD_NULL; + char tmp_buf[TMP_BUF_LEN] = {0}; + int len; + + if (entry == TD_NULL) { + return -ENOSYS; + } + + if (count <= 0) { + return -ENOSYS; + } + + len = (count >= TMP_BUF_LEN) ? TMP_BUF_LEN : count; + + if (osal_copy_from_user(tmp_buf, buf, len)) { + return TD_FAILURE; + } + tmp_buf[len - 1] = '\0'; + + info = (struct fb_info *)(entry->private_data); + if (info == TD_NULL) { + return TD_FAILURE; + } + par = (gfbg_par *)(info->par); + if (par == TD_NULL) { + return TD_FAILURE; + } + + gfbg_parse_proccmd(entry, par->layer_id, (td_char*)tmp_buf); + if (memset_s((td_void *)tmp_buf, TMP_BUF_LEN, 0, count) != EOK) { + gfbg_error("%s:%d:memset_s failed!\n", __FUNCTION__, __LINE__); + return TD_FAILURE; + } +#endif + ot_unused(ppos); + return count; +} +#endif + diff --git a/kernel/gfbg/hi3519dv500/src/gfbg_main.h b/kernel/gfbg/hi3519dv500/src/gfbg_main.h new file mode 100755 index 00000000..8f999bec --- /dev/null +++ b/kernel/gfbg/hi3519dv500/src/gfbg_main.h @@ -0,0 +1,225 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ +#ifndef GFBG_MAIN_H +#define GFBG_MAIN_H +#include "gfbg_drv.h" + +/* define the value of default set of each layer */ +#define GFBG_4K_DEF_WIDTH 3840 +#define GFBG_4K_DEF_HEIGHT 2160 +#define GFBG_4K_DEF_STRIDE (GFBG_4K_DEF_WIDTH * 4) +#define GFBG_4K_DEF_VRAM 64800 /* unit:KB 3840 * 2160 * 4 * 2 */ + +#define GFBG_HD_DEF_WIDTH 1920 /* unit: pixel */ +#define GFBG_HD_DEF_HEIGHT 1080 /* unit: pixel */ +#define GFBG_HD_DEF_STRIDE (GFBG_HD_DEF_WIDTH * 4) /* unit: byte */ +#define GFBG_HD_DEF_VRAM 16200 /* unit:KB 1280*720*4*2 */ /* unit:KB 1920*1080*4*2 */ + +#define GFBG_SD_DEF_WIDTH 720 +#define GFBG_SD_DEF_HEIGHT 576 +#define GFBG_SD_DEF_STRIDE 1440 +#define GFBG_SD_DEF_VRAM 3240 /* unit:KB 720*576*4 */ + +#define GFBG_AD_DEF_WIDTH 720 +#define GFBG_AD_DEF_HEIGHT 576 +#define GFBG_AD_DEF_STRIDE 1440 +#define GFBG_AD_DEF_VRAM 3240 /* unit:KB 720*576*4 */ + +#define GFBG_CURSOR_DEF_WIDTH 256 +#define GFBG_CURSOR_DEF_HEIGHT 256 +#define GFBG_CURSOR_DEF_STRIDE 512 +#define GFBG_CURSOR_DEF_VRAM 512 /* unit:KB for doudble buffer mode, we need 2 memory buffer, save cursor */ + +#define GFBG_SOFTCURSOR_STRIDE 512 + +#define GFBG_DEF_DEPTH 16 /* unit: bits */ +#define GFBG_DEF_XSTART 0 +#define GFBG_DEF_YSTART 0 +#define GFBG_DEF_ALPHA 0xff + +#define GFBG_MAX_ZOOMIN 15 + +#define GFBG_TDE_MEMSET_WIDTH 3840 +#define GFBG_TDE_MEMSET_HEIGHT 2160 + +#define SMART_RECT_SIZE (128 * 16) + +#define GFBG_CMAP_SIZE 0 /* unit:KB 256*4 */ +#define MMB_ADDR_INVALID (0) + +#define gfbg_is_clutfmt(eFmt) (OT_FB_FORMAT_1BPP <= (eFmt) && (eFmt) <= OT_FB_FORMAT_ACLUT88) +#define GFBG_ALPHA_OPAQUE 0xff +#define GFBG_ALPHA_TRANSPARENT 0x00 + +#define gfbg_min(m, n) (((m) > (n)) ? (n) : (m)) + +#define GFBG_DEFLICKER_LEVEL_MAX 5 /* support level 5 deflicker most */ + +#define GFBG_MAX_CURSOR_WIDTH 128 +#define GFBG_MAX_CURSOR_HEIGHT 128 + +#define GFBG_MIN_LOW_DELAY_WIDTH 1920 +#define GFBG_MIN_LOW_DELAY_HEIGHT 1080 + +#define GFBG_MAX_LAYER_WIDTH_CLUT_G3 3840 +#define GFBG_MAX_LAYER_HEIGTH_CLUT_G3 2160 + +typedef enum { + GFBG_ANTIFLICKER_NONE, /* no antiflicker.If scan mode is progressive, gfbg will set antiflicker mode to none */ + GFBG_ANTIFLICKER_TDE, /* tde antiflicker mode, it's effect for 1buf or 2buf only */ + GFBG_ANTIFLICKER_VO, /* vo antiflicker mode, need hardware support */ + GFBG_ANTIFLICKER_BUTT +} gfbg_layer_antiflicker_mode; + +typedef struct { + ot_fb_point pos; + td_u32 display_width; + td_u32 display_height; + td_u32 screen_width; + td_u32 screen_height; + td_bool is_premul; + td_bool need_antiflicker; + ot_fb_layer_antiflicker_level antiflicker_level; /* antiflicker level */ + gfbg_layer_antiflicker_mode antiflicker_mode; /* antiflicker mode */ + td_u32 vir_x_res; + td_u32 vir_y_res; + td_u32 x_res; + td_u32 y_res; + td_u32 max_screen_width; + td_u32 max_screen_height; + ot_fb_mirror_mode mirror_mode; + ot_fb_rotate_mode rotate_mode; +} gfbg_display_info; + +typedef struct { + td_char *vir_addr[2]; /* 2 for y or uv vir address */ + td_phys_addr_t phys_addr[2]; /* 2 for y or uv address */ + td_u32 stride; /* buf stride */ + td_bool need_flip; + td_bool fliped; + td_u32 index_for_int; + td_u32 int_pic_num; + ot_fb_rect union_rect; + td_s32 refresh_handle; + td_bool compress; /* Identifies whether the frame to be displayed is compressed */ +} gfbg_dispbuf_info; + +typedef struct { + ot_fb_layer_buf buf_mode; /* buffer mode */ + ot_fb_buf user_buffer; + td_phys_addr_t screen_addr; /* screen buf addr */ + td_phys_addr_t gb_screen_addr; /* new GB screen buf addr */ + gfbg_dispbuf_info disp_buf_info; + td_u32 refresh_num; /* refresh request num in 2 buf mode */ + td_bool do_refresh_job; +} gfbg_refresh_info; + +typedef struct { + /* For cursor layer, cursor means cursor buffer, it is allocated and freed + both by user;for general layer,cursor means back buf */ + ot_fb_cursor cursor; + + /* For cursor layer,you can quary whether cursor attach to a certain layer + for general layer, you can quary whether cursor attach to it */ + td_u32 attached; + + /* valid area:overlap region between attached layer and cursor layer */ + ot_fb_rect rect_in_disp_buf; + + /* the original position of cursor, usually is (0,0) but also has different when at margin */ + ot_fb_point pos_in_cursor; + + td_u32 attached_cursor_id; +} gfbg_cursor_info; + +typedef struct { + td_bool is_economize_memory; + td_bool compress_open; + td_bool is_losslessa; + td_bool is_lossless; + td_bool decompress_open; + td_bool update_finished; + + ot_fb_rect update_rect; + + ot_fb_rect compress_rect; + + td_bool delay; + + td_phys_addr_t ar_buf_phy_addr; + td_phys_addr_t gb_buf_phy_addr; + td_u32 frame_size0; + td_u32 frame_size1; + td_u32 header_size; + td_u32 stride; + + td_bool layer_addr_update; + + td_u32 start_section; + td_u32 zone_nums; + td_bool clear_zone; + + td_u32 new_start_section; + td_u32 new_zone_nums; +} gfbg_compress_info; + +typedef struct { + td_u32 layer_id; /* layer id */ + atomic_t ref_count; /* framebuffer reference count */ + td_bool show; /* show status */ + ot_fb_color_format color_format; /* color format */ + ot_fb_alpha alpha; /* alpha attribution */ + gfbg_colorkeyex ckey; /* colorkey attribution */ + gfbg_display_info display_info; /* display info */ + gfbg_refresh_info refresh_info; + gfbg_cursor_info cursor_info; + volatile gfbg_compress_info compress_info; + td_u32 param_modify_mask; + volatile td_bool modifying; + ot_fb_surface canvas_sur; /* canvas surface */ + td_u32 h_dflevel; /* horizontal deflicker level */ + td_u32 v_dflevel; /* vertical deflicker level */ + unsigned char h_dfcoef[GFBG_DEFLICKER_LEVEL_MAX - 1]; /* horizontal deflicker coefficients */ + unsigned char v_dfcoef[GFBG_DEFLICKER_LEVEL_MAX - 1]; /* vertical deflicker coefficients */ + volatile td_u32 vblflag; + wait_queue_head_t vbl_event; + wait_queue_head_t do_refresh_job; + osal_spinlock lock; + td_bool layer_open; + td_phys_addr_t rotate_vb; +} gfbg_par; + +typedef enum { + GFBG_LAYER_TYPE_4K, + GFBG_LAYER_TYPE_HD, + GFBG_LAYER_TYPE_SD, + GFBG_LAYER_TYPE_AD, + GFBG_LAYER_TYPE_CURSOR, + GFBG_LAYER_TYPE_BUTT, +} gfbg_layer_type; + +typedef struct { + struct fb_bitfield red; /* bitfield in fb mem if true color, */ + struct fb_bitfield green; /* else only length is significant */ + struct fb_bitfield blue; + struct fb_bitfield transp; /* transparency */ +} gfbg_argb_bitinfo; + +typedef struct { + td_u32 layer_id; + td_bool soft_cursor_update; + td_bool compress; /* if this tde task is compress output */ +} gfbg_tde_callback_param; + +typedef struct { + unsigned regno; + unsigned red; + unsigned green; + unsigned blue; + unsigned transp; +} gfbg_cmp_reg; + +td_s32 graphic_drv_vdp_state_count_lock_init(td_void); +td_void graphic_drv_vdp_state_count_lock_deinit(td_void); +#endif diff --git a/kernel/gfbg/hi3519dv500/src/gfbg_proc.c b/kernel/gfbg/hi3519dv500/src/gfbg_proc.c new file mode 100755 index 00000000..cd56deaf --- /dev/null +++ b/kernel/gfbg/hi3519dv500/src/gfbg_proc.c @@ -0,0 +1,78 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "gfbg_proc.h" +#include "proc_ext.h" +#include "securec.h" +#include "gfbg_main.h" +#include "gfbg_comm.h" + +#ifdef CONFIG_OT_PROC_SHOW_SUPPORT + +#define MAX_PROC_ENTRIES 16 + +static osal_proc_entry g_proc_items[MAX_PROC_ENTRIES]; + +td_void gfbg_proc_add_module(const td_char *entry_name, gfbg_proc_show show, gfbg_proc_write write, + gfbg_proc_ioctl ioctl, td_void *data) +{ + td_s32 i, ret; + osal_proc_entry* proc_item = TD_NULL; + ot_unused(ioctl); + + for (i = 0; i < MAX_PROC_ENTRIES; i++) { + if (!g_proc_items[i].proc_dir_entry) { + break; + } + } + if (i == MAX_PROC_ENTRIES) { + osal_printk("gfbg proc num full. \n"); + return; + } + + proc_item = osal_create_proc_entry(entry_name, TD_NULL); + if (proc_item == TD_NULL) { + osal_printk("create proc err. \n"); + return; + } + + proc_item->write = write; + proc_item->read = show, + proc_item->private_data = data; + + ret = memcpy_s(&g_proc_items[i], sizeof(osal_proc_entry), proc_item, sizeof(osal_proc_entry)); + gfbg_unequal_eok_return_void(ret); +} + +td_void gfbg_proc_remove_module(const char *entry_name) +{ + td_s32 i; + + if (entry_name == TD_NULL) { + return; + } + + for (i = 0; i < MAX_PROC_ENTRIES; i++) { + if (!strcmp(g_proc_items[i].name, entry_name)) { + break; + } + } + + if (i == MAX_PROC_ENTRIES) { + return; + } + + osal_remove_proc_entry(entry_name, TD_NULL); + (td_void)memset_s(&g_proc_items[i], sizeof(osal_proc_entry), 0, sizeof(osal_proc_entry)); + + return; +} + +td_void gfbg_proc_init(td_void) +{ + /* gfbg proc:Uniformly hang under umap, not separately under graphic */ + (td_void)memset_s(g_proc_items, sizeof(g_proc_items), 0, sizeof(g_proc_items)); +} + +#endif diff --git a/kernel/gfbg/hi3519dv500/src/gfbg_proc.h b/kernel/gfbg/hi3519dv500/src/gfbg_proc.h new file mode 100755 index 00000000..5678328a --- /dev/null +++ b/kernel/gfbg/hi3519dv500/src/gfbg_proc.h @@ -0,0 +1,32 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef GFBG_PROC_H +#define GFBG_PROC_H + +#include "ot_type.h" +#include "ot_osal.h" + +#define GFBG_ENTRY_NAME_RANGE 32 + +typedef td_s32 (*gfbg_proc_show)(struct osal_proc_dir_entry *entry); + +typedef td_s32 (*gfbg_proc_write)(struct osal_proc_dir_entry *entry, const char *buf, int count, long long *); + +typedef td_s32 (*gfbg_proc_ioctl)(unsigned int cmd, unsigned long arg, td_u32 *private_data); + +typedef struct { + td_char entry_name[GFBG_ENTRY_NAME_RANGE]; + struct osal_proc_dir_entry *entry; + gfbg_proc_show show; + gfbg_proc_write write; + gfbg_proc_ioctl ioctl; + td_void *data; +} gfbg_proc_item; + +extern td_void gfbg_proc_add_module(const td_char *, gfbg_proc_show, gfbg_proc_write, gfbg_proc_ioctl, td_void *); +extern td_void gfbg_proc_remove_module(const td_char *); +extern td_void gfbg_proc_init(td_void); + +#endif /* GFBG_PROC_H */ diff --git a/kernel/gfbg/hi3519dv500/src/init/gfbg_init.h b/kernel/gfbg/hi3519dv500/src/init/gfbg_init.h new file mode 100644 index 00000000..79ab7d4c --- /dev/null +++ b/kernel/gfbg/hi3519dv500/src/init/gfbg_init.h @@ -0,0 +1,31 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ +#ifndef GFBG_INIT_H +#define GFBG_INIT_H +#include +#include "ot_type.h" +#include "gfbg_graphics.h" +#include "gfbg.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +td_void set_video_name(char *temp_video); + +char *gfbg_get_layer_mmz_names(td_u32 layer_id); + +td_void gfbg_cleanup(td_void); + +td_s32 gfbg_init(td_void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif diff --git a/kernel/gfbg/hi3519dv500/src/init/linux/gfbg_init.c b/kernel/gfbg/hi3519dv500/src/init/linux/gfbg_init.c new file mode 100755 index 00000000..be781495 --- /dev/null +++ b/kernel/gfbg/hi3519dv500/src/init/linux/gfbg_init.c @@ -0,0 +1,96 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ +#include "gfbg_init.h" +#include +#include +#include +#include "ot_type.h" +#include "ot_osal.h" +#ifndef MODULE +#include "securec.h" + +char g_layer_mmz_names[GFBG_MAX_LAYER_NUM][OT_MAX_MMZ_NAME_LEN] = { TD_NULL }; +#else +char *g_layer_mmz_names[GFBG_MAX_LAYER_NUM] = { [0 ... GFBG_MAX_LAYER_NUM - 1] = TD_NULL }; +#endif +char g_tmp_video[128] = "gfbg:vram0_size:8100"; /* 128 The length of the array */ + +#ifndef MODULE +osal_setup_str_param(video, g_tmp_video); +static int __init parse_kern_str_layer_mmz_names(char *line) +{ + const td_char *delim = ","; + td_char *token = TD_NULL; + td_char *cur = line; + td_u32 i = 0; + + while ((token = osal_strsep(&cur, delim)) && (i < GFBG_MAX_LAYER_NUM)) { + if (strncpy_s(g_layer_mmz_names[i], OT_MAX_MMZ_NAME_LEN, token, OT_MAX_MMZ_NAME_LEN - 1) != EOK) { + osal_printk("parse param g_layer_mmz_names failed\n"); + return -1; + } + i++; + } + return 0; +} +__setup("g_layer_mmz_names=", parse_kern_str_layer_mmz_names); +#else +module_param_string(video, g_tmp_video, 128, 0); + +module_param_array(g_layer_mmz_names, charp, TD_NULL, S_IRUGO); +MODULE_PARM_DESC(g_layer_mmz_names, "The mmz names for the graphics layers."); +#endif + +char *gfbg_get_layer_mmz_names(td_u32 layer_id) +{ + if (layer_id >= GFBG_MAX_LAYER_NUM) { + return TD_NULL; + } + return g_layer_mmz_names[layer_id]; +} + +#define GFBG_INT_NAME_LENGTH 10 + +static int ot_gfbg_probe(struct platform_device *pdev) +{ + td_char gfbg_int_name[GFBG_INT_NAME_LENGTH] = "gfbg"; + int *fifb_irq = (int *)(fb_get_gfbg_irq()); + set_video_name(g_tmp_video); + *fifb_irq = osal_platform_get_irq_byname(pdev, gfbg_int_name); + if (*fifb_irq <= 0) { + dev_err(&pdev->dev, "cannot find gfbg IRQ\n"); + return TD_FAILURE; + } + if (gfbg_init() != TD_SUCCESS) { + osal_printk("gfbg_init FAILURE!\n"); + return TD_FAILURE; + } + return 0; +} + +static int ot_gfbg_remove(struct platform_device *pdev) +{ + ot_unused(pdev); + gfbg_cleanup(); + return 0; +} + +static const struct of_device_id ot_gfbg_match[] = { + { .compatible = "vendor,gfbg" }, + {}, +}; +MODULE_DEVICE_TABLE(of, ot_gfbg_match); + +static struct platform_driver ot_gfbg_driver = { + .probe = ot_gfbg_probe, + .remove = ot_gfbg_remove, + .driver = { + .name = "ot_gfbg", + .of_match_table = ot_gfbg_match, + }, +}; + +osal_module_platform_driver(ot_gfbg_driver); +MODULE_LICENSE("GPL"); + diff --git a/kernel/hi3519dv500.kbuild b/kernel/hi3519dv500.kbuild index 796bc350..28fcf9da 100644 --- a/kernel/hi3519dv500.kbuild +++ b/kernel/hi3519dv500.kbuild @@ -232,3 +232,118 @@ ccflags-y += -I$(src)/sensor_spi/hi3519dv500/hi3519dv500 ccflags-y += -I$(src)/mipi_rx/hi3519dv500 $(PREFIX)mipi_rx-objs := mipi_rx/hi3519dv500/mipi_rx.o mipi_rx/hi3519dv500/mipi_rx_hal.o $(DV500_SDRV_INIT)/mipi_rx_init.o obj-m += $(PREFIX)mipi_rx.o + +# MIPI TX (display output) — vendor source + init wrapper (interdrv/init/linux) +ccflags-y += -I$(src)/mipi_tx/hi3519dv500 +$(PREFIX)mipi_tx-objs := mipi_tx/hi3519dv500/mipi_tx.o mipi_tx/hi3519dv500/mipi_tx_hal.o $(DV500_SDRV_INIT)/mipi_tx_init.o +obj-m += $(PREFIX)mipi_tx.o + +# gfbg (graphics framebuffer / OSD) — full vendor source (depends on TDE headers) +DV500_GFBG = gfbg/hi3519dv500 +# gfbg feature config (matches the vendor gfbg Makefile -D flags; e.g. +# CONFIG_TDE_GFBG_COMPRESS_V2 gates gfbg_recalculate_stride). +# dv500-specific gfbg flags (the `ifneq findstring hi3519dv500` branch of the +# vendor gfbg Makefile, plus the unconditional ones). NOT CONFIG_GFBG_NOT_SUPPORT_FUNC +# — that is the non-dv500 branch and would enable a call to the (gated-out) +# gf_vset_g0zme_coef. +ccflags-y += -DCONFIG_TDE_GFBG_COMPRESS_V2 -DCONFIG_COMPRESS_ECONOMIZE_MEMERY \ + -DCONFIG_GFBG_FENCE_SUPPORT -DCONFIG_GFBG_G0_FHD_SUPPORT \ + -DCONFIG_GFBG_LOW_DELAY_SUPPORT \ + -DCONFIG_GFBG_RESOLUTION_SUPPORT_SQUARE -DCONFIG_TDE_CLUT_RECT_SUPPORT_G0 \ + -DCONFIG_TDE_CLUT_RECT_V2 +ccflags-y += -I$(src)/$(DV500_GFBG)/include +ccflags-y += -I$(src)/$(DV500_GFBG)/ext_inc +ccflags-y += -I$(src)/$(DV500_GFBG)/drv +ccflags-y += -I$(src)/$(DV500_GFBG)/drv/include +ccflags-y += -I$(src)/$(DV500_GFBG)/drv/adp +ccflags-y += -I$(src)/$(DV500_GFBG)/src +$(PREFIX)gfbg-objs := \ + $(DV500_GFBG)/src/gfbg_main.o \ + $(DV500_GFBG)/src/gfbg_proc.o \ + $(DV500_GFBG)/src/init/linux/gfbg_init.o \ + $(DV500_GFBG)/drv/adp/gfbg_drv.o \ + $(DV500_GFBG)/drv/adp/gfbg_comm.o \ + $(DV500_GFBG)/drv/adp/gfbg_blit.o \ + $(DV500_GFBG)/drv/adp/gfbg_graphics.o \ + $(DV500_GFBG)/drv/adp/gfbg_graphics_drv.o \ + $(DV500_GFBG)/drv/adp/gfbg_graphic_hal.o \ + $(DV500_GFBG)/drv/adp/gfbg_rotate.o \ + $(DV500_GFBG)/drv/adp/gfbg_rotate_tde.o +obj-m += $(PREFIX)gfbg.o +ccflags-y += -I$(src)/gfbg/hi3519dv500/src/init + +# Security subsystem — full vendor source (no blobs). Each crypto .ko pulls +# the shared security_subsys_common framework (drv/kapi/dispatch/hal). +DV500_SEC = security_subsys/hi3519dv500 +ccflags-y += -DCONFIG_CRYPTO_CHIP_HI3519DV500 -DCRYPTO_CTR_NON_ALIGN_SUPPORT -DCRYPTO_SYMC_ADDR_NOT_ALIGN_SUPPORT +ccflags-y += -I$(src)/$(DV500_SEC)/security_subsys_common/include/common_include +ccflags-y += -I$(src)/$(DV500_SEC)/security_subsys_common/include/drv_include +ccflags-y += -I$(src)/$(DV500_SEC)/security_subsys_common/include/hal_include +ccflags-y += -I$(src)/$(DV500_SEC)/security_subsys_common/include/ioctl_include +ccflags-y += -I$(src)/$(DV500_SEC)/security_subsys_common/include/kapi_include +ccflags-y += -I$(src)/$(DV500_SEC)/security_subsys_common/dispatch_code +ccflags-y += -I$(src)/$(DV500_SEC)/security_subsys_common/drv_code +ccflags-y += -I$(src)/$(DV500_SEC)/security_subsys_common/kapi_code +ccflags-y += -I$(src)/$(DV500_SEC)/crypto_osal_lib +ccflags-y += -I$(src)/$(DV500_SEC)/cipher/mkp +ccflags-y += -I$(src)/$(DV500_SEC) + +DV500_SEC_COMMON := \ + $(DV500_SEC)/security_subsys_common/drv_code/crypto_drv_common.o \ + $(DV500_SEC)/crypto_osal_lib/crypto_osal_lib.o \ + $(DV500_SEC)/security_subsys_common/drv_code/drv_trng.o \ + $(DV500_SEC)/security_subsys_common/drv_code/drv_symc.o \ + $(DV500_SEC)/security_subsys_common/drv_code/drv_symc_mac_hard.o \ + $(DV500_SEC)/security_subsys_common/drv_code/drv_hash.o \ + $(DV500_SEC)/security_subsys_common/drv_code/drv_pbkdf2_hard.o \ + $(DV500_SEC)/security_subsys_common/drv_code/drv_pke.o \ + $(DV500_SEC)/security_subsys_common/drv_code/drv_pke_ecc.o \ + $(DV500_SEC)/security_subsys_common/drv_code/drv_pke_ecc_curve.o \ + $(DV500_SEC)/security_subsys_common/drv_code/drv_pke_rsa.o \ + $(DV500_SEC)/security_subsys_common/kapi_code/kapi_init.o \ + $(DV500_SEC)/security_subsys_common/kapi_code/kapi_trng.o \ + $(DV500_SEC)/security_subsys_common/kapi_code/kapi_symc.o \ + $(DV500_SEC)/security_subsys_common/kapi_code/kapi_hash.o \ + $(DV500_SEC)/security_subsys_common/kapi_code/kapi_pke.o \ + $(DV500_SEC)/security_subsys_common/dispatch_code/crypto_dispatch.o \ + $(DV500_SEC)/security_subsys_common/hal_code/trng_v4/hal_trng.o \ + $(DV500_SEC)/security_subsys_common/hal_code/spacc_v4/hal_symc.o \ + $(DV500_SEC)/security_subsys_common/hal_code/spacc_v4/hal_hash.o \ + $(DV500_SEC)/security_subsys_common/hal_code/pke_v4/hal_pke.o + +$(PREFIX)cipher-objs := $(DV500_SEC)/cipher/mkp/crypto_drv_init.o $(DV500_SEC)/cipher/mkp/crypto_drv_irq.o $(DV500_SEC_COMMON) +obj-m += $(PREFIX)cipher.o + +# km (key management) — disjoint subset; imports cipher's framework at load +ccflags-y += -I$(src)/$(DV500_SEC)/security_subsys_common/hal_code/km_v4 +ccflags-y += -I$(src)/$(DV500_SEC)/security_subsys_common/hal_code/trng_v4 +ccflags-y += -I$(src)/$(DV500_SEC)/km/mkp +$(PREFIX)km-objs := \ + $(DV500_SEC)/km/mkp/crypto_km_drv_init.o \ + $(DV500_SEC)/km/mkp/init_km.o \ + $(DV500_SEC)/security_subsys_common/dispatch_code/dispatch_km.o \ + $(DV500_SEC)/security_subsys_common/drv_code/drv_klad.o \ + $(DV500_SEC)/security_subsys_common/drv_code/drv_keyslot.o \ + $(DV500_SEC)/security_subsys_common/hal_code/km_v4/hal_rkp.o \ + $(DV500_SEC)/security_subsys_common/hal_code/km_v4/hal_klad.o \ + $(DV500_SEC)/security_subsys_common/hal_code/km_v4/hal_keyslot.o \ + $(DV500_SEC)/security_subsys_common/kapi_code/kapi_km.o +obj-m += $(PREFIX)km.o + +# otp (one-time-programmable fuses) +ccflags-y += -I$(src)/$(DV500_SEC)/otp/mkp +$(PREFIX)otp-objs := \ + $(DV500_SEC)/otp/mkp/crypto_otp_drv_init.o \ + $(DV500_SEC)/otp/mkp/init_otp.o \ + $(DV500_SEC)/security_subsys_common/dispatch_code/dispatch_otp.o \ + $(DV500_SEC)/security_subsys_common/kapi_code/kapi_otp.o \ + $(DV500_SEC)/security_subsys_common/drv_code/drv_otp.o +obj-m += $(PREFIX)otp.o + +# hardware_cryptodev (/dev/crypto interface) — self-contained +ccflags-y += -I$(src)/$(DV500_SEC)/hardware_cryptodev +$(PREFIX)hardware_cryptodev-objs := \ + $(DV500_SEC)/hardware_cryptodev/reg_aes.o \ + $(DV500_SEC)/hardware_cryptodev/reg_hash.o \ + $(DV500_SEC)/hardware_cryptodev/ot_reg.o +obj-m += $(PREFIX)hardware_cryptodev.o diff --git a/kernel/init/hi3519dv500/source_drv_init/mipi_tx_init.c b/kernel/init/hi3519dv500/source_drv_init/mipi_tx_init.c new file mode 100644 index 00000000..b387f90d --- /dev/null +++ b/kernel/init/hi3519dv500/source_drv_init/mipi_tx_init.c @@ -0,0 +1,77 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include +#include +#include +#include +#include +#include "ot_mipi_tx_mod_init.h" +#include "ot_osal.h" + +static int g_smooth = 0; + +int mipi_tx_get_smooth(void) +{ + return g_smooth; +} + +static int mipi_tx_probe(struct platform_device *pdev) +{ + struct resource *mem = NULL; + int irq_num; + void *regs = NULL; + + mem = osal_platform_get_resource_byname(pdev, IORESOURCE_MEM, "mipi_tx"); + regs = devm_ioremap_resource(&pdev->dev, mem); + if (IS_ERR(regs)) { + dev_err(&pdev->dev, "mipi_tx remap mem error.\n"); + return PTR_ERR(regs); + } + mipi_tx_set_regs(regs); + + irq_num = osal_platform_get_irq_byname(pdev, "mipi_tx"); + if (irq_num <= 0) { + dev_err(&pdev->dev, "can not find mipi_tx IRQ\n"); + } + mipi_tx_set_irq_num((unsigned int)irq_num); + + return mipi_tx_module_init(g_smooth); +} + +static int mipi_tx_remove(struct platform_device *pdev) +{ + (void)pdev; + + mipi_tx_module_exit(); + mipi_tx_set_regs(NULL); + + return 0; +} + +static const struct of_device_id mipi_tx_match[] = { + { .compatible = "vendor,mipi_tx" }, + {}, +}; +MODULE_DEVICE_TABLE(of, mipi_tx_match); + +static struct platform_driver mipi_tx_driver = { + .probe = mipi_tx_probe, + .remove = mipi_tx_remove, + .driver = { + .name = "mipi_tx", + .of_match_table = mipi_tx_match, + }, +}; + +#ifndef MODULE +osal_setup_num_param(g_smooth, g_smooth); +#else +module_param(g_smooth, int, S_IRUGO); +#endif +module_platform_driver(mipi_tx_driver); + +MODULE_DESCRIPTION("mipi_tx driver"); +MODULE_VERSION("mipi_tx"); +MODULE_LICENSE("GPL"); diff --git a/kernel/init/hi3519dv500/source_drv_init/ot_mipi_tx_mod_init.h b/kernel/init/hi3519dv500/source_drv_init/ot_mipi_tx_mod_init.h new file mode 100644 index 00000000..5f969e9d --- /dev/null +++ b/kernel/init/hi3519dv500/source_drv_init/ot_mipi_tx_mod_init.h @@ -0,0 +1,28 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef OT_MIPI_TX_MOD_INIT_H +#define OT_MIPI_TX_MOD_INIT_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* end of #ifdef __cplusplus */ + +void mipi_tx_set_irq_num(unsigned int irq_num); +void mipi_tx_set_regs(const void *regs); + +int mipi_tx_module_init(int smooth); +void mipi_tx_module_exit(void); + +int mipi_tx_get_smooth(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* end of #ifdef __cplusplus */ + +#endif /* end of #ifndef OT_MIPI_TX_MOD_INIT_H */ diff --git a/kernel/mipi_tx/hi3519dv500/mipi_tx.c b/kernel/mipi_tx/hi3519dv500/mipi_tx.c new file mode 100644 index 00000000..55d5c100 --- /dev/null +++ b/kernel/mipi_tx/hi3519dv500/mipi_tx.c @@ -0,0 +1,1004 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "mipi_tx.h" +#include "mipi_tx_hal.h" +#include "mipi_tx_reg.h" +#include "autoconf.h" +#include "ot_mipi_tx_mod_init.h" +#include "ot_osal.h" +#include "type.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#define MIPI_TX_DEV_NAME "ot_mipi_tx" +#define MIPI_TX_PROC_NAME "mipi_tx" + +#define OT_MEDIA_DYNAMIC_MINOR 255 + +#define mipi_tx_down_sem_return() \ + do { \ + if (osal_sem_down_interruptible(&g_mipi_tx_dev_sem)) { \ + return (-1); \ + } \ + } while (0) + +#define mipi_tx_up_sem() osal_sem_up(&g_mipi_tx_dev_sem) + +#if mipi_tx_desc("pub") + +static int g_en_dev = FALSE; +static int g_en_dev_cfg = FALSE; + +static osal_dev *g_mipi_tx_dev; +static osal_semaphore g_mipi_tx_dev_sem; + +static mipi_tx_dev_ctx_t g_mipi_tx_dev_ctx; + +void mipi_tx_set_irq_num(unsigned int irq_num) +{ + mipi_tx_drv_set_irq_num(irq_num); +} + +void mipi_tx_set_regs(const void *regs) +{ + mipi_tx_drv_set_regs((const mipi_tx_regs_type_t *)regs); +} + +void mipi_tx_set_work_mode(mipi_tx_work_mode_t work_mode) +{ + g_mipi_tx_dev_ctx.work_param.work_mode = work_mode; +} + +mipi_tx_work_mode_t mipi_tx_get_work_mode(void) +{ + return g_mipi_tx_dev_ctx.work_param.work_mode; +} + +void mipi_tx_set_lp_clk_en(unsigned char lp_clk_en) +{ + g_mipi_tx_dev_ctx.work_param.lp_clk_en = lp_clk_en; +} + +unsigned char mipi_tx_get_lp_clk_en(void) +{ + return g_mipi_tx_dev_ctx.work_param.lp_clk_en; +} + +int mipi_tx_get_lane_num(const short lane_id[], int lane_id_len) +{ + int lane_num = 0; + int i; + + for (i = 0; i < lane_id_len; i++) { + if (lane_id[i] != MIPI_TX_DISABLE_LANE_ID) { + lane_num++; + } + } + return lane_num; +} + +static int mipi_tx_check_temp_lane_id(int lane_index, int valid_lane_num, const short lane_id[], int lane_id_len) +{ + int j; + int temp_id; + temp_id = lane_id[lane_index]; + + if ((temp_id < MIPI_TX_DISABLE_LANE_ID) || (temp_id >= LANE_MAX_NUM)) { + mipi_tx_err("lane_id[%d] is invalid value %d.\n", lane_index, temp_id); + return -1; + } + + if (temp_id == MIPI_TX_DISABLE_LANE_ID) { + return 0; + } + + /* + * lanex_id and lane num: + * 1 lane: lane0_id, lane1/2/3_id must be different from lane0_id + * 2 lane: lane0/1_id, lane2/3_id must be different from lane0/1_id + * 3 lane: lane0/1/2_id, lane3_id must be different from lane0/1/2_id + */ + if (temp_id > valid_lane_num) { + mipi_tx_err("lane_id[%d]=%d is illegal, lane%d_id can't be set in %d lane mode\n", lane_index, temp_id, + temp_id, valid_lane_num); + return -1; + } + + /* valid lane id must be different. */ + for (j = lane_index + 1; j < lane_id_len; j++) { + if (temp_id == lane_id[j]) { + mipi_tx_err("lane_id[%d] can't be same value %d as lane_id[%d]\n", lane_index, temp_id, j); + return -1; + } + } + + return 0; +} + +static int mipi_tx_check_dev_cfg_lane_id(const combo_dev_cfg_t *dev_cfg) +{ + int i; + const int max_lane_num = LANE_MAX_NUM; + int lane_num; + + lane_num = mipi_tx_get_lane_num(dev_cfg->lane_id, LANE_MAX_NUM); + if (lane_num == 0) { + mipi_tx_err("all lane_id is invalid!\n"); + return -1; + } + + for (i = 0; i < max_lane_num; i++) { + if (mipi_tx_check_temp_lane_id(i, lane_num, dev_cfg->lane_id, LANE_MAX_NUM) != 0) { + return -1; + } + } + + return 0; +} + +static int mipi_tx_check_dev_cfg_out_mode(const combo_dev_cfg_t *dev_cfg) +{ + if (dev_cfg->out_mode >= OUT_MODE_BUTT) { + mipi_tx_err("mipi_tx dev output_mode(%d) err!\n", dev_cfg->out_mode); + return -1; + } + return 0; +} + +static int mipi_tx_check_dev_cfg_video_mode(const combo_dev_cfg_t *dev_cfg) +{ + if (dev_cfg->video_mode >= VIDEO_DATA_MODE_BUTT) { + mipi_tx_err("mipi_tx dev video_mode(%d) err!\n", dev_cfg->video_mode); + return -1; + } + return 0; +} + +static int mipi_tx_check_dev_cfg_out_format(const combo_dev_cfg_t *dev_cfg) +{ + if (dev_cfg->out_format >= OUT_FORMAT_BUTT) { + mipi_tx_err("mipi_tx dev format(%d) err!\n", dev_cfg->out_format); + return -1; + } + return 0; +} + +static int mipi_tx_check_dev_vertical_sync_info(const sync_info_t *sync_info) +{ + if ((sync_info->vact < MIPI_TX_MIN_SYNC_VACT) || (sync_info->vact > MIPI_TX_MAX_SYNC_VACT)) { + mipi_tx_err("mipi tx sync's vact(%u) should be [%u, %u]!\n", sync_info->vact, MIPI_TX_MIN_SYNC_VACT, + MIPI_TX_MAX_SYNC_VACT); + return -1; + } + + if ((sync_info->vbp < MIPI_TX_MIN_SYNC_VBP) || (sync_info->vbp > MIPI_TX_MAX_SYNC_VBP)) { + mipi_tx_err("mipi tx sync's vbb(%u) should be [%u, %u]!\n", sync_info->vbp, MIPI_TX_MIN_SYNC_VBP, + MIPI_TX_MAX_SYNC_VBP); + return -1; + } + + if ((sync_info->vfp < MIPI_TX_MIN_SYNC_VFP) || (sync_info->vfp > MIPI_TX_MAX_SYNC_VFP)) { + mipi_tx_err("mipi tx sync's vfb(%u) should be [%u, %u]!\n", sync_info->vfp, MIPI_TX_MIN_SYNC_VFP, + MIPI_TX_MAX_SYNC_VFP); + return -1; + } + + return 0; +} + +static int mipi_tx_check_dev_horizontal_sync_info(const sync_info_t *sync_info) +{ + if ((sync_info->hact < MIPI_TX_MIN_SYNC_HACT) || (sync_info->hact > MIPI_TX_MAX_SYNC_HACT)) { + mipi_tx_err("mipi tx sync's hact(%u) should be [%u, %u]!\n", sync_info->hact, MIPI_TX_MIN_SYNC_HACT, + MIPI_TX_MAX_SYNC_HACT); + return -1; + } + + if (sync_info->hbp < MIPI_TX_MIN_SYNC_HBP) { + mipi_tx_err("mipi tx sync's hbb(%u) should be [%u, %u]!\n", sync_info->hbp, MIPI_TX_MIN_SYNC_HBP, + MIPI_TX_MAX_SYNC_HBP); + return -1; + } + + if (sync_info->hfp < MIPI_TX_MIN_SYNC_HFP) { + mipi_tx_err("mipi tx sync's hfb(%u) should be [%u, %u]!\n", sync_info->hfp, MIPI_TX_MIN_SYNC_HFP, + MIPI_TX_MAX_SYNC_HFP); + return -1; + } + + return 0; +} + +static int mipi_tx_check_dev_pulse_sync_info(const sync_info_t *sync_info) +{ + if (sync_info->hpw < MIPI_TX_MIN_SYNC_HPW) { + mipi_tx_err("mipi tx sync's hpw(%u) should be [%u, %u]!\n", sync_info->hpw, MIPI_TX_MIN_SYNC_HPW, + MIPI_TX_MAX_SYNC_HPW); + return -1; + } + + if ((sync_info->vpw < MIPI_TX_MIN_SYNC_VPW) || (sync_info->vpw > MIPI_TX_MAX_SYNC_VPW)) { + mipi_tx_err("mipi tx sync's vpw(%u) should be [%u, %u]!\n", sync_info->vpw, MIPI_TX_MIN_SYNC_VPW, + MIPI_TX_MAX_SYNC_VPW); + return -1; + } + + return 0; +} + +static int mipi_tx_check_dev_cfg_sync_info(const combo_dev_cfg_t *dev_cfg) +{ + int ret; + + ret = mipi_tx_check_dev_vertical_sync_info(&dev_cfg->sync_info); + if (ret != 0) { + return ret; + } + + ret = mipi_tx_check_dev_horizontal_sync_info(&dev_cfg->sync_info); + if (ret != 0) { + return ret; + } + + return mipi_tx_check_dev_pulse_sync_info(&dev_cfg->sync_info); +} + +static int mipi_tx_check_dev_cfg_phy_data_rate(const combo_dev_cfg_t *dev_cfg) +{ + if ((dev_cfg->phy_data_rate < MIPI_TX_MIN_PHY_DATA_RATE) || + (dev_cfg->phy_data_rate > MIPI_TX_MAX_PHY_DATA_RATE)) { + mipi_tx_err("mipi_tx dev phy data rate(%u) should be in [%d, %d]\n", dev_cfg->phy_data_rate, + MIPI_TX_MIN_PHY_DATA_RATE, MIPI_TX_MAX_PHY_DATA_RATE); + return -1; + } + return 0; +} + +static int mipi_tx_check_dev_cfg_pixel_clk(const combo_dev_cfg_t *dev_cfg) +{ + if ((dev_cfg->pixel_clk < MIPI_TX_MIN_PIXEL_CLK) || + (dev_cfg->pixel_clk > MIPI_TX_MAX_PIXEL_CLK)) { + mipi_tx_err("mipi_tx dev pixel clk(%u) should be in [%d, %d]\n", dev_cfg->pixel_clk, + MIPI_TX_MIN_PIXEL_CLK, MIPI_TX_MAX_PIXEL_CLK); + return -1; + } + return 0; +} + +static int mipi_tx_is_format_for_dsi_mode(out_format_t out_format) +{ + if ((out_format >= OUT_FORMAT_RGB_16BIT) && (out_format <= OUT_FORMAT_YUV422_16BIT)) { + return 1; + } + return 0; +} + +static int mipi_tx_is_format_for_csi_mode(out_format_t out_format) +{ + if ((out_format >= OUT_FORMAT_YUV420_8BIT_NORMAL) && (out_format <= OUT_FORMAT_RAW_16BIT)) { + return 1; + } + return 0; +} + +static int mipi_tx_is_dsi_mode(out_mode_t out_mode) +{ + if ((out_mode == OUT_MODE_DSI_VIDEO) || (out_mode == OUT_MODE_DSI_CMD)) { + return 1; + } + return 0; +} + +static int mipi_tx_is_csi_mode(out_mode_t out_mode) +{ + if (out_mode == OUT_MODE_CSI) { + return 1; + } + return 0; +} + +static int mipi_tx_check_dev_out_mode_and_out_format(const combo_dev_cfg_t *dev_cfg) +{ + if ((mipi_tx_is_dsi_mode(dev_cfg->out_mode) == 1) && + (mipi_tx_is_format_for_dsi_mode(dev_cfg->out_format) != 1)) { + mipi_tx_err("mipi_tx dev out mode(%d) does not match the out data format(%d)\n", + dev_cfg->out_mode, dev_cfg->out_format); + return -1; + } + + if ((mipi_tx_is_csi_mode(dev_cfg->out_mode) == 1) && + (mipi_tx_is_format_for_csi_mode(dev_cfg->out_format) != 1)) { + mipi_tx_err("mipi_tx dev out mode(%d) does not match the out data format(%d)\n", + dev_cfg->out_mode, dev_cfg->out_format); + return -1; + } + return 0; +} + +static int mipi_tx_check_dev_clklane_continue_mode(const combo_dev_cfg_t *dev_cfg) +{ + if ((dev_cfg->clklane_continue_mode < MIPI_TX_CLK_LANE_CONTINUE) || + (dev_cfg->clklane_continue_mode >= MIPI_TX_CLK_LANE_BUTT)) { + mipi_tx_err("mipi_tx dev continue mode (%u) should be in [%d, %d]\n", dev_cfg->clklane_continue_mode, + MIPI_TX_CLK_LANE_CONTINUE, MIPI_TX_CLK_LANE_NON_CONTINUE); + return -1; + } + + return 0; +} + +static int mipi_tx_check_comb_dev_cfg(const combo_dev_cfg_t *dev_cfg) +{ + int ret; + if (g_en_dev == TRUE) { + mipi_tx_err("mipi_tx dev has enable!\n"); + return -1; + } + + if (dev_cfg->devno != 0) { + mipi_tx_err("mipi_tx dev devno err!\n"); + return -1; + } + + ret = mipi_tx_check_dev_cfg_lane_id(dev_cfg); + if (ret != 0) { + return ret; + } + + ret = mipi_tx_check_dev_cfg_out_mode(dev_cfg); + if (ret != 0) { + return ret; + } + + ret = mipi_tx_check_dev_cfg_video_mode(dev_cfg); + if (ret != 0) { + return ret; + } + + ret = mipi_tx_check_dev_cfg_out_format(dev_cfg); + if (ret != 0) { + return ret; + } + + ret = mipi_tx_check_dev_cfg_sync_info(dev_cfg); + if (ret != 0) { + return ret; + } + + ret = mipi_tx_check_dev_cfg_phy_data_rate(dev_cfg); + if (ret != 0) { + return ret; + } + + ret = mipi_tx_check_dev_cfg_pixel_clk(dev_cfg); + if (ret != 0) { + return ret; + } + + ret = mipi_tx_check_dev_out_mode_and_out_format(dev_cfg); + if (ret != 0) { + return ret; + } + return mipi_tx_check_dev_clklane_continue_mode(dev_cfg); +} + +static int mipi_tx_set_combo_dev_cfg(const combo_dev_cfg_t *dev_cfg) +{ + int ret; + + mipi_tx_check_null_ptr_return(dev_cfg); + mipi_tx_down_sem_return(); + + ret = mipi_tx_check_comb_dev_cfg(dev_cfg); + if (ret < 0) { + mipi_tx_up_sem(); + mipi_tx_err("mipi_tx check combo_dev config failed!\n"); + return ret; + } + + /* set controller config */ + mipi_tx_drv_set_controller_cfg(dev_cfg); + + /* set phy config */ + mipi_tx_drv_set_phy_cfg(); + + mipi_tx_set_work_mode(MIPI_TX_WORK_MODE_LP); + mipi_tx_set_lp_clk_en(FALSE); + + (void)memcpy_s(&g_mipi_tx_dev_ctx.dev_cfg, sizeof(combo_dev_cfg_t), dev_cfg, sizeof(combo_dev_cfg_t)); + g_en_dev_cfg = TRUE; + + mipi_tx_up_sem(); + + return ret; +} + +#endif /* #if mipi_tx_desc("pub") */ + +#if mipi_tx_desc("set & get cmd") + +static int mipi_tx_check_pub_info(const mipi_tx_pub_info *pub_info) +{ + if (g_en_dev_cfg != TRUE) { + mipi_tx_err("mipi_tx dev has not configured!\n"); + return -1; + } + + if (pub_info->devno != 0) { + mipi_tx_err("mipi_tx devno(%u) illegal!\n", pub_info->devno); + return -1; + } + + if ((pub_info->work_param.work_mode != MIPI_TX_WORK_MODE_LP) && + (pub_info->work_param.work_mode != MIPI_TX_WORK_MODE_HS)) { + mipi_tx_err("mipi_tx work_mode(%d) is illegal!\n", pub_info->work_param.work_mode); + return -1; + } + + if ((pub_info->work_param.lp_clk_en != 0) && (pub_info->work_param.lp_clk_en != 1)) { + mipi_tx_err("mipi_tx lp_clk_en(%d) is illegal!\n", pub_info->work_param.lp_clk_en); + return -1; + } + + /* lp_clk_en must be 1 when work mode is hs mode */ + if ((pub_info->work_param.work_mode == MIPI_TX_WORK_MODE_HS) && (pub_info->work_param.lp_clk_en != 1)) { + mipi_tx_err("mipi_tx lp_clk_en(%d) is not support in work_mode(%d)!\n", + pub_info->work_param.lp_clk_en, pub_info->work_param.work_mode); + return -1; + } + + return 0; +} + +static int mipi_tx_check_set_cmd_info(const cmd_info_t *cmd_info) +{ + mipi_tx_pub_info pub_info = { 0 }; + int ret; + + pub_info.devno = cmd_info->devno; + pub_info.work_param.work_mode = cmd_info->work_mode; + pub_info.work_param.lp_clk_en = cmd_info->lp_clk_en; + + ret = mipi_tx_check_pub_info(&pub_info); + if (ret != 0) { + return ret; + } + + /* When cmd is not NULL,cmd_size means the length of cmd or it means cmd and addr */ + if (cmd_info->cmd != NULL) { + if ((cmd_info->cmd_size > MIPI_TX_SET_DATA_SIZE) || (cmd_info->cmd_size == 0)) { + mipi_tx_err("mipi_tx dev cmd_size(%d) is illegal, it should be in (%d, %d].\n", cmd_info->cmd_size, + 0, MIPI_TX_SET_DATA_SIZE); + return -1; + } + } + + return 0; +} + +static int mipi_tx_set_cmd(const cmd_info_t *cmd_info) +{ + int ret; + + mipi_tx_check_null_ptr_return(cmd_info); + mipi_tx_down_sem_return(); + + ret = mipi_tx_check_set_cmd_info(cmd_info); + if (ret < 0) { + mipi_tx_up_sem(); + mipi_tx_err("mipi_tx check set cmd info failed!\n"); + return ret; + } + ret = mipi_tx_drv_set_cmd_info(cmd_info); + mipi_tx_up_sem(); + return ret; +} + +static int mipi_tx_check_get_cmd_info(const get_cmd_info_t *get_cmd_info) +{ + mipi_tx_pub_info pub_info = { 0 }; + int ret; + + pub_info.devno = get_cmd_info->devno; + pub_info.work_param.work_mode = get_cmd_info->work_mode; + pub_info.work_param.lp_clk_en = get_cmd_info->lp_clk_en; + + ret = mipi_tx_check_pub_info(&pub_info); + if (ret != 0) { + return ret; + } + + if ((get_cmd_info->get_data_size == 0) || (get_cmd_info->get_data_size > MIPI_TX_GET_DATA_SIZE)) { + mipi_tx_err("mipi_tx dev get_data_size(%d) illegal, it should be in (%d, %d].\n", + get_cmd_info->get_data_size, 0, MIPI_TX_GET_DATA_SIZE); + return -1; + } + + if (get_cmd_info->get_data == NULL) { + mipi_tx_err("mipi_tx dev get_data is null!\n"); + return -1; + } + + return 0; +} + +static int mipi_tx_get_cmd(const get_cmd_info_t *get_cmd_info) +{ + int ret; + + mipi_tx_check_null_ptr_return(get_cmd_info); + mipi_tx_down_sem_return(); + ret = mipi_tx_check_get_cmd_info(get_cmd_info); + if (ret < 0) { + mipi_tx_up_sem(); + mipi_tx_err("mipi_tx check get cmd info failed!\n"); + return ret; + } + ret = mipi_tx_drv_get_cmd_info(get_cmd_info); + mipi_tx_up_sem(); + + return ret; +} + +#endif /* #if mipi_tx_desc("set & get cmd") */ + +#ifndef OT_FPGA +#if mipi_tx_desc("pn swap") + +static int mipi_tx_check_set_pn_swap(const combo_dev_pn_swap_t *tx_pn_swap) +{ + int i; + + if (g_en_dev_cfg != TRUE) { + mipi_tx_err("mipi_tx dev has not configured!\n"); + return -1; + } + + if (g_en_dev == TRUE) { + mipi_tx_err("mipi_tx dev has enable!\n"); + return -1; + } + + if (tx_pn_swap->devno != 0) { + mipi_tx_err("mipi_tx devno(%u) illegal!\n", tx_pn_swap->devno); + return -1; + } + + for (i = 0; i < MIPI_LANE_NUM_PER_DEV; i++) { + if ((tx_pn_swap->pn_swap[i] != TRUE) && (tx_pn_swap->pn_swap[i] != FALSE)) { + mipi_tx_err("pn_swap (%u) is illegal!\n", tx_pn_swap->pn_swap[i]); + return -1; + } + } + + return 0; +} + +static int mipi_tx_set_pn_swap(const combo_dev_pn_swap_t *pn_swap) +{ + int ret; + + mipi_tx_check_null_ptr_return(pn_swap); + mipi_tx_down_sem_return(); + + ret = mipi_tx_check_set_pn_swap(pn_swap); + if (ret < 0) { + mipi_tx_up_sem(); + mipi_tx_err("mipi_tx check pn swap failed!\n"); + return ret; + } + mipi_tx_drv_set_pn_swap(pn_swap); + mipi_tx_up_sem(); + + return ret; +} + +#endif /* #if mipi_tx_desc("pn swap") */ +#endif + +#if mipi_tx_desc("enable & disable") + +static int mipi_tx_enable(void) +{ + out_mode_t output_mode; + + mipi_tx_down_sem_return(); + if (g_en_dev_cfg == FALSE) { + mipi_tx_up_sem(); + return -1; + } + + output_mode = g_mipi_tx_dev_ctx.dev_cfg.out_mode; + mipi_tx_drv_enable_input(output_mode); + if (output_mode == OUT_MODE_DSI_CMD) { + mipi_tx_set_work_mode(MIPI_TX_WORK_MODE_HS); + } + mipi_tx_set_lp_clk_en(TRUE); + g_en_dev = TRUE; + mipi_tx_up_sem(); + + return 0; +} + +static int mipi_tx_disable(void) +{ + mipi_tx_down_sem_return(); + mipi_tx_drv_disable_input(); + + mipi_tx_drv_reset_pn_swap(); + mipi_tx_set_work_mode(MIPI_TX_WORK_MODE_LP); + mipi_tx_set_lp_clk_en(FALSE); + mipi_tx_drv_set_ctrl_clk(0); + + g_en_dev = FALSE; + g_en_dev_cfg = FALSE; + mipi_tx_up_sem(); + + return 0; +} + +#endif /* #if mipi_tx_desc("enable & disable") */ + +#if mipi_tx_desc("proc") + +#ifdef CONFIG_OT_PROC_SHOW_SUPPORT +static int mipi_tx_get_sync_same(sync_info_t *psync_info, mipi_tx_dev_phy_t mipi_tx_phy_ctx) +{ + if ((psync_info->hact != mipi_tx_phy_ctx.hact_det) || (psync_info->hpw != mipi_tx_phy_ctx.hsa_det) || + (psync_info->hbp != mipi_tx_phy_ctx.hbp_det) || (psync_info->vpw != mipi_tx_phy_ctx.vsa_det) || + (psync_info->vact != mipi_tx_phy_ctx.vact_det)) { + return 0; + } + + return 1; +} + +static void mipi_tx_proc_module_show(osal_proc_entry *s) +{ + int smooth = mipi_tx_get_smooth(); + osal_seq_printf(s->seqfile, "----------mipi_tx module config------------------------\n"); + osal_seq_printf(s->seqfile, "%8s\n", "smooth"); + osal_seq_printf(s->seqfile, "%8d\n", smooth); + osal_seq_printf(s->seqfile, "\r\n"); +} + +static char* mipi_tx_proc_continue(continue_mode_t clklane_continue_mode) +{ + if (clklane_continue_mode == MIPI_TX_CLK_LANE_CONTINUE) { + return "CONTINUE"; + } else { + return "NON-CONTINUE"; + } +} + +static void mipi_tx_proc_dev_show(osal_proc_entry *s) +{ + combo_dev_cfg_t *pdev_cfg = NULL; + sync_info_t *psync_info = NULL; + pdev_cfg = &g_mipi_tx_dev_ctx.dev_cfg; + psync_info = &g_mipi_tx_dev_ctx.dev_cfg.sync_info; + + /* mipi tx device config */ + osal_seq_printf(s->seqfile, "----------mipi_tx dev config---------------------------\n"); + + osal_seq_printf(s->seqfile, "%8s%8s%8s%8s%8s%15s%15s%15s%15s%15s%26s\n", + "devno", "lane0", "lane1", "lane2", "lane3", "output_mode", "phy_data_rate", "pixel_clk(KHz)", + "video_mode", "output_fmt", "clklane_continue_mode"); + + if (g_en_dev == TRUE) { + osal_seq_printf(s->seqfile, "%8d%8d%8d%8d%8d%15d%15d%15d%15d%15d%26s\n", + pdev_cfg->devno, + pdev_cfg->lane_id[0], + pdev_cfg->lane_id[1], + pdev_cfg->lane_id[2], /* lane id 2 */ + pdev_cfg->lane_id[3], /* lane id 3 */ + pdev_cfg->out_mode, + pdev_cfg->phy_data_rate, + pdev_cfg->pixel_clk, + pdev_cfg->video_mode, + pdev_cfg->out_format, + mipi_tx_proc_continue(pdev_cfg->clklane_continue_mode)); + } + osal_seq_printf(s->seqfile, "\r\n"); + + /* mipi tx device sync config */ + osal_seq_printf(s->seqfile, "----------mipi_tx sync config---------------------------\n"); + + osal_seq_printf(s->seqfile, "%14s%14s%14s%14s%14s%14s%14s%14s\n", + "hact", "hbp", "hfp", "hsa", "vact", "vbp", "vfp", "vsa"); + + if (g_en_dev == TRUE) { + osal_seq_printf(s->seqfile, "%14d%14d%14d%14d%14d%14d%14d%14d\n", + psync_info->hact, + psync_info->hbp, + psync_info->hfp, + psync_info->hpw, + psync_info->vact, + psync_info->vbp, + psync_info->vfp, + psync_info->vpw); + } + osal_seq_printf(s->seqfile, "\r\n"); +} + +static int mipi_tx_proc_dev_lane_pn_status_show(osal_proc_entry *s) +{ + combo_dev_pn_swap_t pn_status; + + /* mipi tx device pn_swap config */ + osal_seq_printf(s->seqfile, "----------mipi_tx pn_swap config------------------------\n"); + osal_seq_printf(s->seqfile, "%14s%14s%14s%14s\n", "lane0_pn", "lane1_pn", "lane2_pn", "lane3_pn"); + mipi_tx_drv_get_pn_swap(&pn_status); + if (g_en_dev == TRUE) { + osal_seq_printf(s->seqfile, "%14d%14d%14d%14d\n", + pn_status.pn_swap[0], /* lane id 0 */ + pn_status.pn_swap[1], /* lane id 1 */ + pn_status.pn_swap[2], /* lane id 2 */ + pn_status.pn_swap[3]); /* lane id 3 */ + } + + osal_seq_printf(s->seqfile, "\r\n"); + return 0; +} + +static void mipi_tx_proc_dev_status_show(osal_proc_entry *s) +{ + int check_sync_same; + mipi_tx_dev_phy_t mipi_tx_phy_ctx; + sync_info_t *psync_info = &g_mipi_tx_dev_ctx.dev_cfg.sync_info; + + mipi_tx_drv_get_dev_status(&mipi_tx_phy_ctx); + + /* mipi tx phy status */ + osal_seq_printf(s->seqfile, "----------mipi_tx dev status---------------------------\n"); + osal_seq_printf(s->seqfile, "%8s%8s%8s%8s%8s%8s%8s%12s\n", + "width", "height", "horiall", "vertall", "hbp", "hsa", "vsa", "sync_check"); + + if (g_en_dev == TRUE) { + check_sync_same = mipi_tx_get_sync_same(psync_info, mipi_tx_phy_ctx); + osal_seq_printf(s->seqfile, "%8u%8u%8u%8u%8u%8u%8u%12u\n", + mipi_tx_phy_ctx.hact_det, + mipi_tx_phy_ctx.vact_det, + mipi_tx_phy_ctx.hall_det, + mipi_tx_phy_ctx.vall_det, + mipi_tx_phy_ctx.hbp_det, + mipi_tx_phy_ctx.hsa_det, + mipi_tx_phy_ctx.vsa_det, + check_sync_same); + } + osal_seq_printf(s->seqfile, "\r\n"); +} + +static int mipi_tx_proc_show(osal_proc_entry *s) +{ + osal_seq_printf(s->seqfile, "\nModule: [MIPI_TX], Build Time["__DATE__", "__TIME__"]\n"); + mipi_tx_proc_module_show(s); + mipi_tx_proc_dev_show(s); + mipi_tx_proc_dev_lane_pn_status_show(s); + mipi_tx_proc_dev_status_show(s); + return 0; +} +#endif +#endif /* #if mipi_tx_desc("proc") */ + +#if mipi_tx_desc("init & ioctl") +static int ot_mipi_tx_set_dev_cfg_job(unsigned int cmd, void *arg, void *private_data) +{ + mipi_tx_unused(cmd); + mipi_tx_unused(private_data); + return mipi_tx_set_combo_dev_cfg((const combo_dev_cfg_t *)(uintptr_t)arg); +} + +static int ot_mipi_tx_set_cmd_job(unsigned int cmd, void *arg, void *private_data) +{ + mipi_tx_unused(cmd); + mipi_tx_unused(private_data); + return mipi_tx_set_cmd((const cmd_info_t *)(uintptr_t)arg); +} + +static int ot_mipi_tx_get_cmd_job(unsigned int cmd, void *arg, void *private_data) +{ + mipi_tx_unused(cmd); + mipi_tx_unused(private_data); + return mipi_tx_get_cmd((const get_cmd_info_t *)(uintptr_t)arg); +} + +static int ot_mipi_tx_enable_job(unsigned int cmd, void *arg, void *private_data) +{ + mipi_tx_unused(cmd); + mipi_tx_unused(arg); + mipi_tx_unused(private_data); + return mipi_tx_enable(); +} + +static int ot_mipi_tx_disable_job(unsigned int cmd, void *arg, void *private_data) +{ + mipi_tx_unused(cmd); + mipi_tx_unused(arg); + mipi_tx_unused(private_data); + return mipi_tx_disable(); +} + +#ifndef OT_FPGA +static int ot_mipi_tx_set_pn_swap_job(unsigned int cmd, void *arg, void *private_data) +{ + mipi_tx_unused(cmd); + mipi_tx_unused(private_data); + return mipi_tx_set_pn_swap((const combo_dev_pn_swap_t *)(uintptr_t)arg); +} + +#else +static int ot_mipi_tx_set_pn_swap_job(unsigned int cmd, void *arg, void *private_data) +{ + mipi_tx_unused(cmd); + mipi_tx_unused(arg); + mipi_tx_unused(private_data); + mipi_tx_err("mipi_tx not support pn swap!\n"); + return -1; +} + +#endif + +static osal_ioctl_cmd g_mipi_tx_ioctl_cmd_list[] = { + { OT_MIPI_TX_SET_DEV_CFG, ot_mipi_tx_set_dev_cfg_job }, + { OT_MIPI_TX_SET_CMD, ot_mipi_tx_set_cmd_job }, + { OT_MIPI_TX_GET_CMD, ot_mipi_tx_get_cmd_job }, + { OT_MIPI_TX_ENABLE, ot_mipi_tx_enable_job }, + { OT_MIPI_TX_DISABLE, ot_mipi_tx_disable_job }, + { OT_MIPI_TX_SET_PN_SWAP, ot_mipi_tx_set_pn_swap_job }, +}; + +void mipi_tx_set_ioctl_cmd_list(osal_fileops *mipi_tx_fops) +{ + mipi_tx_fops->cmd_list = g_mipi_tx_ioctl_cmd_list; + mipi_tx_fops->cmd_cnt = sizeof(g_mipi_tx_ioctl_cmd_list) / sizeof(g_mipi_tx_ioctl_cmd_list[0]); +} + +static int mipi_tx_init(int smooth) +{ + return mipi_tx_drv_init(smooth); +} + +static void mipi_tx_exit(void) +{ + mipi_tx_drv_exit(); +} + +static int mipi_tx_open(void *private_data) +{ + mipi_tx_unused(private_data); + return 0; +} + +static int mipi_tx_release(void *private_data) +{ + mipi_tx_unused(private_data); + return 0; +} + +static osal_fileops g_mipi_tx_fops = { + .open = mipi_tx_open, + .release = mipi_tx_release, +}; + +static int mipi_tx_register_device(void) +{ + int ret; + g_mipi_tx_dev = osal_dev_create(MIPI_TX_DEV_NAME); + if (g_mipi_tx_dev == NULL) { + mipi_tx_err("create mipi_tx device failed!\n"); + return -1; + } + + mipi_tx_set_ioctl_cmd_list(&g_mipi_tx_fops); + g_mipi_tx_dev->fops = &g_mipi_tx_fops; + g_mipi_tx_dev->minor = OT_MEDIA_DYNAMIC_MINOR; + + ret = osal_dev_register(g_mipi_tx_dev); + if (ret != 0) { + osal_dev_destroy(g_mipi_tx_dev); + g_mipi_tx_dev = NULL; + mipi_tx_err("register mipi_tx device failed!\n"); + return -1; + } + return 0; +} + +static void mipi_tx_unregister_device(void) +{ + osal_dev_unregister(g_mipi_tx_dev); + osal_dev_destroy(g_mipi_tx_dev); + g_mipi_tx_dev = NULL; + return; +} + +static int mipi_tx_check_smooth(int smooth) +{ + if ((smooth != TRUE) && (smooth != FALSE)) { + mipi_tx_err("module param smooth(%d) is illegal!\n", smooth); + return -1; + } + return 0; +} + +int mipi_tx_module_init(int smooth) +{ + int ret; +#ifdef CONFIG_OT_PROC_SHOW_SUPPORT + osal_proc_entry *mipi_tx_proc_entry = NULL; +#endif + + ret = mipi_tx_check_smooth(smooth); + if (ret != 0) { + goto fail0; + } + + ret = mipi_tx_register_device(); + if (ret != 0) { + goto fail0; + } + +#ifdef CONFIG_OT_PROC_SHOW_SUPPORT + mipi_tx_proc_entry = osal_create_proc_entry(MIPI_TX_PROC_NAME, NULL); + if (mipi_tx_proc_entry == NULL) { + mipi_tx_err("create mipi_tx proc(%s) failed!\n", MIPI_TX_PROC_NAME); + goto fail1; + } + + mipi_tx_proc_entry->read = mipi_tx_proc_show; + mipi_tx_proc_entry->write = NULL; +#endif + + ret = mipi_tx_init(smooth); + if (ret != 0) { + mipi_tx_err("mipi init failed!\n"); + goto fail2; + } + + ret = osal_sem_init(&g_mipi_tx_dev_sem, 1); + if (ret != 0) { + mipi_tx_err("init sema error!\n"); + goto fail3; + } + + osal_printk("load mipi_tx.ko ....OK!\n"); + return 0; + +fail3: + mipi_tx_exit(); +fail2: +#ifdef CONFIG_OT_PROC_SHOW_SUPPORT + osal_remove_proc_entry(MIPI_TX_PROC_NAME, NULL); +fail1: +#endif + mipi_tx_unregister_device(); +fail0: + mipi_tx_err("load mipi_tx.ko ....failed!\n"); + return -1; +} + +void mipi_tx_module_exit(void) +{ + osal_sem_destroy(&g_mipi_tx_dev_sem); + mipi_tx_exit(); +#ifdef CONFIG_OT_PROC_SHOW_SUPPORT + osal_remove_proc_entry(MIPI_TX_PROC_NAME, NULL); +#endif + mipi_tx_unregister_device(); + osal_printk("unload mipi_tx.ko ....OK!\n"); +} + +#endif /* #if mipi_tx_desc("init & ioctl") */ + +#ifdef __cplusplus +#if __cplusplus +} + +#endif +#endif diff --git a/kernel/mipi_tx/hi3519dv500/mipi_tx.h b/kernel/mipi_tx/hi3519dv500/mipi_tx.h new file mode 100644 index 00000000..5234f56f --- /dev/null +++ b/kernel/mipi_tx/hi3519dv500/mipi_tx.h @@ -0,0 +1,70 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef MIPI_TX_H +#define MIPI_TX_H +#include "securec.h" +#include "ot_mipi_tx.h" + +#define MIPI_TX_MAX_SYNC_VACT 4096 +#define MIPI_TX_MIN_SYNC_VACT 100 +#define MIPI_TX_MAX_SYNC_VBP 256 +#define MIPI_TX_MIN_SYNC_VBP 1 +#define MIPI_TX_MAX_SYNC_VFP 256 +#define MIPI_TX_MIN_SYNC_VFP 1 +#define MIPI_TX_MAX_SYNC_HACT 4096 +#define MIPI_TX_MIN_SYNC_HACT 1 +#define MIPI_TX_MAX_SYNC_HBP 65535 +#define MIPI_TX_MIN_SYNC_HBP 1 +#define MIPI_TX_MAX_SYNC_HFP 65535 +#define MIPI_TX_MIN_SYNC_HFP 1 +#define MIPI_TX_MAX_SYNC_HPW 65535 +#define MIPI_TX_MIN_SYNC_HPW 1 +#define MIPI_TX_MAX_SYNC_VPW 256 +#define MIPI_TX_MIN_SYNC_VPW 1 + +#define MIPI_TX_MAX_PHY_DATA_RATE 1800 /* Mbps */ +#define MIPI_TX_MIN_PHY_DATA_RATE 120 /* Mbps */ + +#define MIPI_TX_MAX_PIXEL_CLK ((MIPI_TX_MAX_PHY_DATA_RATE) * (LANE_MAX_NUM) * 1000 / 8) /* KHz , 8: min 8bit/pixel */ +#define MIPI_TX_MIN_PIXEL_CLK ((MIPI_TX_MIN_PHY_DATA_RATE) * (1) * 1000 / 24) /* KHz, 24: max 24bit/pixel */ + +#define mipi_tx_err(x, ...) \ + do { \ + osal_printk("%s(%d): "x, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + } while (0) + +#define mipi_tx_check_null_ptr_return(ptr) \ + do { \ + if ((ptr) == NULL) { \ + mipi_tx_err("NULL pointer\r\n"); \ + return (-1); \ + } \ + } while (0) + +#define mipi_tx_desc(x) 1 +#define mipi_tx_unused(x) ((void)(x)) + +typedef struct { + mipi_tx_work_mode_t work_mode; + unsigned char lp_clk_en; +} mipi_tx_work_param; + +typedef struct { + unsigned int devno; + mipi_tx_work_param work_param; +} mipi_tx_pub_info; + +typedef struct { + combo_dev_cfg_t dev_cfg; + mipi_tx_work_param work_param; +} mipi_tx_dev_ctx_t; + +void mipi_tx_set_work_mode(mipi_tx_work_mode_t work_mode); +mipi_tx_work_mode_t mipi_tx_get_work_mode(void); +void mipi_tx_set_lp_clk_en(unsigned char lp_clk_en); +unsigned char mipi_tx_get_lp_clk_en(void); +int mipi_tx_get_lane_num(const short lane_id[], int lane_id_len); + +#endif diff --git a/kernel/mipi_tx/hi3519dv500/mipi_tx_def.h b/kernel/mipi_tx/hi3519dv500/mipi_tx_def.h new file mode 100644 index 00000000..3c4a84c2 --- /dev/null +++ b/kernel/mipi_tx/hi3519dv500/mipi_tx_def.h @@ -0,0 +1,77 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef MIPI_TX_DEF_H +#define MIPI_TX_DEF_H + +typedef enum { + MIPI_TX_DSI_RGB_16BIT = 0x00, + MIPI_TX_DSI_RGB_18BIT = 0x03, + MIPI_TX_DSI_RGB_18BIT_LOOSELY = 0x04, + MIPI_TX_DSI_RGB_24BIT = 0x05, + MIPI_TX_DSI_YCBCR422_20BIT = 0x06, + MIPI_TX_DSI_YCBCR422_16BIT = 0x08, + MIPI_TX_DSI_RGB_30BIT = 0x09, + MIPI_TX_DSI_RGB_36BIT = 0x0A, + MIPI_TX_DSI_YCBCR420_12BIT = 0x0b, + MIPI_TX_DSC24_COMPRESSED_DATA = 0x0f, + MIPI_TX_CSI_YUV422_8BIT = 0x10, + MIPI_TX_CSI_YUV422_10BIT = 0x11, + MIPI_TX_CSI_LEGACY_YUV420_8BIT = 0x12, + MIPI_TX_CSI_YUV420_8BIT = 0x13, + MIPI_TX_CSI_YUV420_10BIT = 0x14, + MIPI_TX_CSI_RGB888 = 0x15, + MIPI_TX_CSI_RGB666 = 0x16, + MIPI_TX_CSI_RGB565 = 0x17, + MIPI_TX_CSI_RGB555 = 0x18, + MIPI_TX_CSI_RGB444 = 0x19, + MIPI_TX_CSI_RAW8 = 0x1A, + MIPI_TX_CSI_RAW10 = 0x1B, + MIPI_TX_CSI_RAW12 = 0x1C, + MIPI_TX_CSI_RAW14 = 0x1D, + MIPI_TX_CSI_RAW16 = 0x1E, + + MIPI_TX_DATA_TYPE_BUTT, +} mipi_tx_data_type; + +typedef enum { + CMD_TRANS_DCS_LW_LOWPOWER_MODE = (0x01L << 0), /* 0: the 0 bit */ + CMD_TRANS_DCS_SR_0P_LOWPOWER_MODE = (0x01L << 1), /* 1: the 1st bit */ + CMD_TRANS_DCS_SW_1P_LOWPOWER_MODE = (0x01L << 2), /* 2: the 2nd bit */ + CMD_TRANS_DCS_SW_0P_LOWPOWER_MODE = (0x01L << 3), /* 3: the 3rd bit */ + CMD_TRANS_GEN_LW_LOWPOWER_MODE = (0x01L << 4), /* 4: the 4th bit */ + CMD_TRANS_GEN_SR_2P_LOWPOWER_MODE = (0x01L << 5), /* 5: the 5th bit */ + CMD_TRANS_GEN_SR_1P_LOWPOWER_MODE = (0x01L << 6), /* 6: the 6th bit */ + CMD_TRANS_GEN_SR_0P_LOWPOWER_MODE = (0x01L << 7), /* 7: the 7th bit */ + CMD_TRANS_GEN_SW_2P_LOWPOWER_MODE = (0x01L << 8), /* 8: the 8th bit */ + CMD_TRANS_GEN_SW_1P_LOWPOWER_MODE = (0x01L << 9), /* 9: the 9th bit */ + CMD_TRANS_GEN_SW_0P_LOWPOWER_MODE = (0x01L << 10), /* 10: the 10th bit */ + CMD_TRANS_MAX_RD_PKT_SIZE_TRAN_LOWPOWER_MODE = (0x01L << 11), /* 11: the 11th bit */ + + CMD_TRANS_BUTT, +} cmd_trans_mode; + +typedef enum { + VIDEO_MODE = 0, + COMMAND_MODE = 1, + + CMD_VIDEO_BUTT, +} cmd_video_mode; + +typedef enum { + DCS_LONG_WRITE = 0x39, + DCS_SHORT_READ_0PARAM = 0x06, + DCS_SHORT_WRITE_1PARAM = 0x15, + DCS_SHORT_WRITE_0PARAM = 0x05, + GEN_LONG_WRITE = 0x29, + GEN_SHORT_READ_2PARAM = 0x24, + GEN_SHORT_READ_1PARAM = 0x14, + GEN_SHORT_READ_0PARAM = 0x04, + GEN_SHORT_WRITE_2PARAM = 0x23, + GEN_SHORT_WRITE_1PARAM = 0x13, + GEN_SHORT_WRITE_0PARAM = 0x03, + MAX_READ_PACKET_SIZE_TRAN = 0x37, +} mipi_tx_dcs_data_type; + +#endif /* MIPI_TX_DEF_H */ diff --git a/kernel/mipi_tx/hi3519dv500/mipi_tx_hal.c b/kernel/mipi_tx/hi3519dv500/mipi_tx_hal.c new file mode 100644 index 00000000..a83c153e --- /dev/null +++ b/kernel/mipi_tx/hi3519dv500/mipi_tx_hal.c @@ -0,0 +1,1837 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "mipi_tx_hal.h" +#include "mipi_tx.h" +#include "ot_osal.h" +#include "type.h" +#include "mipi_tx_reg.h" +#include "mipi_tx_phy_reg.h" +#include "mipi_tx_def.h" +#include "ot_mipi_tx.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#if mipi_tx_desc("pub") + +#define mipi_tx_readl(x) (*(const volatile unsigned int *)(x)) +#define mipi_tx_writel(v, x) (*(volatile unsigned int *)(x) = (v)) + +static volatile mipi_tx_regs_type_t *g_mipi_tx_regs_va = NULL; +static volatile mipi_tx_phy_regs_type_t *g_mipi_tx_phy_regs_va = NULL; +static unsigned int g_mipi_tx_irq_num = MIPI_TX_IRQ; +static unsigned int g_actual_phy_data_rate; +static unsigned int g_reg_map_flag = 0; +static unsigned int g_phy_reg_map_flag = 0; + +unsigned int hal_read_reg(const unsigned int *address) +{ + return *(volatile unsigned int *)(address); +} + +void hal_write_reg(unsigned int *address, unsigned int value) +{ + *(volatile unsigned int *)address = value; +} + +void mipi_tx_drv_set_irq_num(unsigned int irq_num) +{ + g_mipi_tx_irq_num = irq_num; +} + +void mipi_tx_drv_set_regs(const mipi_tx_regs_type_t *regs) +{ + g_mipi_tx_regs_va = (mipi_tx_regs_type_t *)regs; +} + +static void mipi_tx_set_actual_phy_data_rate(unsigned int actual_date_rate) +{ + g_actual_phy_data_rate = actual_date_rate; +} + +static unsigned int mipi_tx_get_actual_phy_data_rate(void) +{ + return g_actual_phy_data_rate; +} + +static void write_reg32(unsigned long addr, unsigned int value, unsigned int mask) +{ + unsigned int t; + + t = mipi_tx_readl((const volatile void *)(uintptr_t)addr); + t &= ~mask; + t |= value & mask; + mipi_tx_writel(t, (volatile void *)(uintptr_t)addr); +} + +#ifdef OT_FPGA +static void set_phy_reg(unsigned int addr, unsigned char value) +{ + osal_isb(); + osal_dsb(); + osal_dmb(); + g_mipi_tx_regs_va->phy_reg_cfg1.u32 = (0x10000 + addr); + osal_isb(); + osal_dsb(); + osal_dmb(); + g_mipi_tx_regs_va->phy_reg_cfg0.u32 = 0x2; + osal_isb(); + osal_dsb(); + osal_dmb(); + g_mipi_tx_regs_va->phy_reg_cfg0.u32 = 0x0; + osal_isb(); + osal_dsb(); + osal_dmb(); + g_mipi_tx_regs_va->phy_reg_cfg1.u32 = value; + osal_isb(); + osal_dsb(); + osal_dmb(); + g_mipi_tx_regs_va->phy_reg_cfg0.u32 = 0x2; + osal_isb(); + osal_dsb(); + osal_dmb(); + g_mipi_tx_regs_va->phy_reg_cfg0.u32 = 0x0; + osal_isb(); + osal_dsb(); + osal_dmb(); +} +#endif + +void mipi_tx_drv_get_dev_status(mipi_tx_dev_phy_t *mipi_tx_phy_ctx) +{ + volatile reg_hori0_det hori0_det; + volatile reg_hori1_det hori1_det; + volatile reg_vert_det vert_det; + volatile reg_vsa_det vsa_det; + + hori0_det.u32 = g_mipi_tx_regs_va->hori0_det.u32; + hori1_det.u32 = g_mipi_tx_regs_va->hori1_det.u32; + vert_det.u32 = g_mipi_tx_regs_va->vert_det.u32; + vsa_det.u32 = g_mipi_tx_regs_va->vsa_det.u32; + + mipi_tx_phy_ctx->hact_det = hori0_det.bits.hact_det; + mipi_tx_phy_ctx->hall_det = hori0_det.bits.hline_det; + mipi_tx_phy_ctx->hbp_det = hori1_det.bits.hbp_det; + mipi_tx_phy_ctx->hsa_det = hori1_det.bits.hsa_det; + + mipi_tx_phy_ctx->vact_det = vert_det.bits.vact_det; + mipi_tx_phy_ctx->vall_det = vert_det.bits.vall_det; + mipi_tx_phy_ctx->vsa_det = vsa_det.bits.vsa_det; +} + +#endif + +#if mipi_tx_desc("phy pll") + +#ifdef OT_FPGA +static void mipi_tx_drv_set_phy_pll_setx(unsigned int phy_data_rate) +{ + unsigned char pll_set0; + unsigned char pll_set1; + unsigned char pll_set2; + unsigned char pll_set3; + unsigned char pll_set4; + + /* step2 : */ + /* pll_set0 */ + pll_set0 = 0x18; + set_phy_reg(PLL_SET_0X14, pll_set0); + + /* pll_set1 */ + pll_set1 = 0x8; + set_phy_reg(PLL_SET_0X15, pll_set1); + + /* pll_set2 */ + pll_set2 = 0x21; + set_phy_reg(PLL_SET_0X16, pll_set2); + + /* pll_set3 */ + pll_set3 = 0x1; + set_phy_reg(PLL_SET_0X17, pll_set3); + + /* pll_set4 */ + pll_set4 = 0x28; + set_phy_reg(PLL_SET_0X1E, pll_set4); + +#ifdef MIPI_TX_DEBUG + osal_printk("\n==========phy pll info=======\n"); + osal_printk("pll_set0(0x14): 0x%x\n", pll_set0); + osal_printk("pll_set1(0x15): 0x%x\n", pll_set1); + osal_printk("pll_set2(0x16): 0x%x\n", pll_set2); + osal_printk("pll_set3(0x17): 0x%x\n", pll_set3); + osal_printk("pll_set4(0x1e): 0x%x\n", pll_set4); + osal_printk("=========================\n"); +#endif +} + +#else + +static void mipi_tx_drv_set_phy_ictrl(unsigned int loop_div) +{ + unsigned int phy_ictrl = 0; + unsigned int phy_vco = MIPI_TX_REF_CLK * loop_div / 10; /* 10: phy_vco MHZ */ + + if (phy_vco > 1770) { /* VCO: 1770 MHZ */ + phy_ictrl = 14; /* 14: phy params after optimization */ + } else if (phy_vco > 1680) { /* VCO: 1680 MHZ */ + phy_ictrl = 13; /* 13: phy params after optimization */ + } else if (phy_vco > 1560) { /* VCO: 1560 MHZ */ + phy_ictrl = 12; /* 12: phy params after optimization */ + } else if (phy_vco > 1450) { /* VCO: 1450 MHZ */ + phy_ictrl = 11; /* 11: phy params after optimization */ + } else if (phy_vco > 1330) { /* VCO: 1330 MHZ */ + phy_ictrl = 10; /* 10: phy params after optimization */ + } else if (phy_vco > 1220) { /* VCO: 1220 MHZ */ + phy_ictrl = 9; /* 9: phy params after optimization */ + } else if (phy_vco > 1100) { /* VCO: 1100 MHZ */ + phy_ictrl = 8; /* 8: phy params after optimization */ + } else { + phy_ictrl = 7; /* 7: phy params after optimization */ + } + g_mipi_tx_phy_regs_va->aphy_txpll_inctrl.u32 = phy_ictrl; + +#ifdef MIPI_TX_DEBUG + osal_printk("pll ctrl (0x10): 0x%x\n", g_mipi_tx_phy_regs_va->aphy_txpll_inctrl.u32); +#endif +} + + +static int mipi_tx_drv_get_phy_pll_post_div(unsigned int phy_data_rate, unsigned int *conf_post_div) +{ + int post_div = 1; + + if (phy_data_rate < 62) { /* below 62: need 32 div */ + post_div = 32; /* 62: need 32 div */ + *conf_post_div = 0b101; + } else if (phy_data_rate < 124) { /* 62-124: need 16 div */ + post_div = 16; /* 62-124: need 16 div */ + *conf_post_div = 0b100; + } else if (phy_data_rate < 249) { /* 124-249: need 8 div */ + post_div = 8; /* 124-249: need 8 div */ + *conf_post_div = 0b11; + } else if (phy_data_rate < 499) { /* 249-499: need 4 div */ + post_div = 4; /* 249-499: need 4 div */ + *conf_post_div = 0b10; + } else if (phy_data_rate < 998) { /* 499-998: need 2 div */ + post_div = 2; /* 499-998: need 2 div */ + *conf_post_div = 0b1; + } else { + post_div = 1; /* larger 998: need 1 div */ + *conf_post_div = 0b0; + } + + return post_div; +} + +static void mipi_tx_drv_set_phy_pll_setx(unsigned int phy_data_rate) +{ + volatile u_common_reg_48 common_reg_48; + volatile u_common_reg_49 common_reg_49; + volatile u_common_reg_4a common_reg_4a; + volatile u_common_reg_4b common_reg_4b; + unsigned int *addr_reg; + unsigned int conf_post_div = 0; + unsigned int loop_div; + unsigned int input_div = 0; + /* 10: unit trans to MHZ */ + unsigned int post_div = mipi_tx_drv_get_phy_pll_post_div(phy_data_rate / 10, &conf_post_div); + + loop_div = (phy_data_rate * post_div) / + (MIPI_TX_REF_CLK * (input_div + 1)); /* phy_data_rate & MIPI_TX_REF_CLK unit is MHZ*10 */ + + addr_reg = (unsigned int *)((uintptr_t)(void *)&(g_mipi_tx_phy_regs_va->common_reg_48)); + common_reg_48.u32 = hal_read_reg(addr_reg); + common_reg_48.bits.reg_pll_phy_posdiv = conf_post_div; + hal_write_reg(addr_reg, common_reg_48.u32); + + addr_reg = (unsigned int *)((uintptr_t)(void *)&(g_mipi_tx_phy_regs_va->common_reg_49)); + common_reg_49.u32 = hal_read_reg(addr_reg); + common_reg_49.bits.reg_pll_phy_prediv = input_div; + common_reg_49.bits.reg_pll_phy_div_int_bit10to8 = 0x0; + hal_write_reg(addr_reg, common_reg_49.u32); + + addr_reg = (unsigned int *)((uintptr_t)(void *)&(g_mipi_tx_phy_regs_va->common_reg_4a)); + common_reg_4a.u32 = hal_read_reg(addr_reg); + common_reg_4a.bits.reg_pll_phy_div_int_bit7to0 = loop_div; + hal_write_reg(addr_reg, common_reg_4a.u32); + + addr_reg = (unsigned int *)((uintptr_t)(void *)&(g_mipi_tx_phy_regs_va->common_reg_4b)); + common_reg_4b.u32 = hal_read_reg(addr_reg); + common_reg_4b.bits.reg_pll_phy_div_update = 1; + hal_write_reg(addr_reg, common_reg_4b.u32); + + mipi_tx_drv_set_phy_ictrl(loop_div); +#ifdef MIPI_TX_DEBUG + osal_printk("\n==========phy pll info=======\n"); + osal_printk("loop_div: %d\n", loop_div); + osal_printk("post_div: %d\n", post_div); + osal_printk("conf_post_div: 0x%d\n", conf_post_div); + osal_printk("phy_data_rate: %dMHZ\n", phy_data_rate / 10); /* phy_data_rate unit is MHZ*10 */ + osal_printk("=========================\n"); +#endif + return; +} +#endif /* end of #ifdef OT_FPGA */ + +#endif /* end of #if mipi_tx_desc("phy pll") */ + +#if mipi_tx_desc("phy time parameter") + +#ifdef OT_FPGA + +static void mipi_tx_drv_get_phy_timing_parameters(mipi_tx_phy_timing_parameters *tp) +{ + tp->data_tpre_delay = DATA0_TPRE_DELAY_VALUE; + tp->clk_post_delay = CLK_POST_DELAY_VALUE; + tp->clk_tlpx = CLK_TLPX_VALUE; + tp->clk_tclk_prepare = CLK_TCLK_PREPARE_VALUE; + tp->clk_tclk_zero = CLK_TCLK_ZERO_VALUE; + tp->clk_tclk_trail = CLK_TCLK_TRAIL_VALUE; + tp->data_tlpx = DATA0_TLPX_VALUE; + tp->data_ths_prepare = DATA0_THS_PREPARE_VALUE; + tp->data_ths_zero = DATA0_THS_ZERO_VALUE; + tp->data_ths_trail = DATA0_THS_TRAIL_VALUE; +} + +#else + +static inline unsigned char mipi_tx_drv_get_phy_timing_parameters_by_type(unsigned int timing_type, + unsigned char round_type) +{ + unsigned int actual_phy_data_rate = mipi_tx_get_actual_phy_data_rate(); + unsigned int round_value = (round_type == 0 ? ROUNDUP_VALUE : (INNER_PEROID / 2)); /* 2: half */ + /* actual_phy_data_rate unit is MHZ*10 */ + return ((actual_phy_data_rate * timing_type / PREPARE_COMPENSATE + round_value) / + INNER_PEROID - 1); /* -1: logical add 1 itself */ +} + +static void mipi_tx_drv_get_phy_timing_parameters(mipi_tx_phy_timing_parameters *tp) +{ + unsigned int ths_prepare; + unsigned int ths_zero; + unsigned int ths_trail; + unsigned int actual_data_rate = mipi_tx_get_actual_phy_data_rate() / PREPARE_COMPENSATE; /* converted to Mbps */ + + ths_prepare = (125 / 2) + (5000 / actual_data_rate); /* 125, 2, 5000 phy timing params after optimization */ + ths_zero = 195 + (10000 / actual_data_rate) - ths_prepare; /* 195, 10000 phy timing params after optimization */ + ths_trail = 61 + (4000 / actual_data_rate); /* 61, 4000 phy timing params after optimization */ + + /* CLK_TLPX */ + tp->clk_tlpx = mipi_tx_drv_get_phy_timing_parameters_by_type(TLPX, 0); + + /* CLK_TCLK_PREPARE */ + tp->clk_tclk_prepare = mipi_tx_drv_get_phy_timing_parameters_by_type(TCLK_PREPARE, 1); + + /* CLK_TCLK_ZERO */ + tp->clk_tclk_zero = mipi_tx_drv_get_phy_timing_parameters_by_type(TCLK_ZERO, 0) + 1; /* +1: logical param */ + + /* CLK_TCLK_TRAIL */ + tp->clk_tclk_trail = mipi_tx_drv_get_phy_timing_parameters_by_type(TCLK_TRAIL, 0); + + /* DATA_TLPX */ + tp->data_tlpx = mipi_tx_drv_get_phy_timing_parameters_by_type(TLPX, 0); + + /* DATA_TPRE_DELAY */ + tp->data_tpre_delay = tp->data_tlpx + tp->clk_tclk_prepare + tp->clk_tclk_zero + + mipi_tx_drv_get_phy_timing_parameters_by_type(TPRE_DELAY, 1) + 8; /* +8: logical param */ + + /* DATA_THS_PREPARE */ + tp->data_ths_prepare = mipi_tx_drv_get_phy_timing_parameters_by_type(ths_prepare, 1); + + /* DATA_THS_ZERO */ + tp->data_ths_zero = mipi_tx_drv_get_phy_timing_parameters_by_type(ths_zero, 0) + 1; /* +1: logical param */ + + /* DATA_THS_TRAIL */ + tp->data_ths_trail = mipi_tx_drv_get_phy_timing_parameters_by_type(ths_trail, 0) - 1; /* -1: logical param */ + + /* CLK POST DELAY */ + tp->clk_post_delay = mipi_tx_drv_get_phy_timing_parameters_by_type(TCLK_POST, 0) + + tp->data_ths_trail + 10; /* +10: logical param */ +} +#endif + +#ifdef OT_FPGA + +/* + * set global operation timing parameters. + */ +static void mipi_tx_drv_set_phy_timing_parameters(const mipi_tx_phy_timing_parameters *tp) +{ + /* DATA0~3 TPRE-DELAY */ + set_phy_reg(DATA0_TPRE_DELAY, tp->data_tpre_delay); + set_phy_reg(DATA1_TPRE_DELAY, tp->data_tpre_delay); + set_phy_reg(DATA2_TPRE_DELAY, tp->data_tpre_delay); + set_phy_reg(DATA3_TPRE_DELAY, tp->data_tpre_delay); + + /* CLK_POST_DELAY */ + set_phy_reg(CLK_POST_DELAY, tp->clk_post_delay); + + /* CLK_TLPX */ + set_phy_reg(CLK_TLPX, tp->clk_tlpx); + + /* CLK_TCLK_PREPARE */ + set_phy_reg(CLK_TCLK_PREPARE, tp->clk_tclk_prepare); + + /* CLK_TCLK_ZERO */ + set_phy_reg(CLK_TCLK_ZERO, tp->clk_tclk_zero); + + /* CLK_TCLK_TRAIL */ + set_phy_reg(CLK_TCLK_TRAIL, tp->clk_tclk_trail); + + /* + * DATA_TLPX + * DATA_THS_PREPARE + * DATA_THS_ZERO + * DATA_THS_TRAIL + */ + set_phy_reg(DATA0_TLPX, tp->data_tlpx); + set_phy_reg(DATA0_THS_PREPARE, tp->data_ths_prepare); + set_phy_reg(DATA0_THS_ZERO, tp->data_ths_zero); + set_phy_reg(DATA0_THS_TRAIL, tp->data_ths_trail); + set_phy_reg(DATA1_TLPX, tp->data_tlpx); + set_phy_reg(DATA1_THS_PREPARE, tp->data_ths_prepare); + set_phy_reg(DATA1_THS_ZERO, tp->data_ths_zero); + set_phy_reg(DATA1_THS_TRAIL, tp->data_ths_trail); + set_phy_reg(DATA2_TLPX, tp->data_tlpx); + set_phy_reg(DATA2_THS_PREPARE, tp->data_ths_prepare); + set_phy_reg(DATA2_THS_ZERO, tp->data_ths_zero); + set_phy_reg(DATA2_THS_TRAIL, tp->data_ths_trail); + set_phy_reg(DATA3_TLPX, tp->data_tlpx); + set_phy_reg(DATA3_THS_PREPARE, tp->data_ths_prepare); + set_phy_reg(DATA3_THS_ZERO, tp->data_ths_zero); + set_phy_reg(DATA3_THS_TRAIL, tp->data_ths_trail); + +#ifdef MIPI_TX_DEBUG + osal_printk("\n==========phy timing parameters=======\n"); + osal_printk("data_tpre_delay(0x30/40/50/60): 0x%x\n", tp->data_tpre_delay); + osal_printk("clk_post_delay(0x21): 0x%x\n", tp->clk_post_delay); + osal_printk("clk_tlpx(0x22): 0x%x\n", tp->clk_tlpx); + osal_printk("clk_tclk_prepare(0x23): 0x%x\n", tp->clk_tclk_prepare); + osal_printk("clk_tclk_zero(0x24): 0x%x\n", tp->clk_tclk_zero); + osal_printk("clk_tclk_trail(0x25): 0x%x\n", tp->clk_tclk_trail); + osal_printk("data_tlpx(0x32/42/52/62): 0x%x\n", tp->data_tlpx); + osal_printk("data_ths_prepare(0x33/43/53/63): 0x%x\n", tp->data_ths_prepare); + osal_printk("data_ths_zero(0x34/44/54/64): 0x%x\n", tp->data_ths_zero); + osal_printk("data_ths_trail(0x35/45/55/65): 0x%x\n", tp->data_ths_trail); + osal_printk("=========================\n"); +#endif +} + +#else + +static void mipi_tx_drv_set_phy_timing_cfg(int offset, const mipi_tx_phy_timing_parameters *tp) +{ + volatile u_lane_reg_10 lane_reg_10; + volatile u_lane_reg_11 lane_reg_11; + volatile u_lane_reg_12 lane_reg_12; + volatile u_lane_reg_13 lane_reg_13; + volatile u_lane_reg_14 lane_reg_14; + volatile u_lane_reg_15 lane_reg_15; + volatile u_lane_reg_16 lane_reg_16; + unsigned int *addr_reg; + unsigned char data_tpre_delay; + unsigned char tlpx; + unsigned char ths_prepare; + unsigned char ths_zero; + unsigned char ths_trail; + + if (offset == 2 * 0x80) { /* clk lane is 2 */ + tlpx = tp->clk_tlpx; + ths_prepare = tp->clk_tclk_prepare; + ths_zero = tp->clk_tclk_zero; + ths_trail = tp->clk_tclk_trail; + } else { + data_tpre_delay = tp->data_tpre_delay; + tlpx = tp->data_tlpx; + ths_prepare = tp->data_ths_prepare; + ths_zero = tp->data_ths_zero; + ths_trail = tp->data_ths_trail; + } + + addr_reg = (unsigned int *)((uintptr_t)(void *)&(g_mipi_tx_phy_regs_va->lane_reg_12) + offset); + lane_reg_12.u32 = hal_read_reg(addr_reg); + lane_reg_12.bits.reg_tlpx = tlpx; + hal_write_reg(addr_reg, lane_reg_12.u32); + + addr_reg = (unsigned int *)((uintptr_t)(void *)&(g_mipi_tx_phy_regs_va->lane_reg_13) + offset); + lane_reg_13.u32 = hal_read_reg(addr_reg); + lane_reg_13.bits.reg_tprepare = ths_prepare; + hal_write_reg(addr_reg, lane_reg_13.u32); + + addr_reg = (unsigned int *)((uintptr_t)(void *)&(g_mipi_tx_phy_regs_va->lane_reg_14) + offset); + lane_reg_14.u32 = hal_read_reg(addr_reg); + lane_reg_14.bits.reg_tzero = ths_zero; + hal_write_reg(addr_reg, lane_reg_14.u32); + + addr_reg = (unsigned int *)((uintptr_t)(void *)&(g_mipi_tx_phy_regs_va->lane_reg_15) + offset); + lane_reg_15.u32 = hal_read_reg(addr_reg); + lane_reg_15.bits.reg_thstrail = ths_trail; + hal_write_reg(addr_reg, lane_reg_15.u32); + + if (offset == 2 * 0x80) { /* clk lane is 2 */ + addr_reg = (unsigned int *)((uintptr_t)(void *)&(g_mipi_tx_phy_regs_va->lane_reg_11) + offset); + lane_reg_11.u32 = hal_read_reg(addr_reg); + lane_reg_11.bits.reg_pos_req_dy = tp->clk_post_delay; + hal_write_reg(addr_reg, lane_reg_11.u32); + + addr_reg = (unsigned int *)((uintptr_t)(void *)&(g_mipi_tx_phy_regs_va->lane_reg_16) + offset); + lane_reg_16.u32 = hal_read_reg(addr_reg); + lane_reg_16.bits.reg_clock_val = 0x55; + hal_write_reg(addr_reg, lane_reg_16.u32); + } else { + addr_reg = (unsigned int *)((uintptr_t)(void *)&(g_mipi_tx_phy_regs_va->lane_reg_10) + offset); + lane_reg_10.u32 = hal_read_reg(addr_reg); + lane_reg_10.bits.reg_pre_req_dy = data_tpre_delay; + hal_write_reg(addr_reg, lane_reg_10.u32); + } + + return; +} + +static void mipi_tx_drv_set_phy_timing_parameters(const mipi_tx_phy_timing_parameters *tp) +{ + /* + * DATA_TLPX + * DATA_THS_PREPARE + * DATA_THS_ZERO + * DATA_THS_TRAIL + * DATA0/DATA1/CLK/DATA2/DATA3 + */ + mipi_tx_drv_set_phy_timing_cfg(0, tp); /* 0: DATA0 */ + mipi_tx_drv_set_phy_timing_cfg(1 * 0x80, tp); /* 1: DATA1 */ + mipi_tx_drv_set_phy_timing_cfg(2 * 0x80, tp); /* 2: CLK */ + mipi_tx_drv_set_phy_timing_cfg(3 * 0x80, tp); /* 3: DATA2 */ + mipi_tx_drv_set_phy_timing_cfg(4 * 0x80, tp); /* 4: DATA3 */ + +#ifdef MIPI_TX_DEBUG + osal_printk("\n==========phy timing parameters=======\n"); + osal_printk("clk_post_delay: 0x%x\n", tp->clk_post_delay); + osal_printk("clk_tlpx: 0x%x\n", tp->clk_tlpx); + osal_printk("clk_tclk_prepare: 0x%x\n", tp->clk_tclk_prepare); + osal_printk("clk_tclk_zero: 0x%x\n", tp->clk_tclk_zero); + osal_printk("clk_tclk_trail: 0x%x\n", tp->clk_tclk_trail); + osal_printk("data_tlpx: 0x%x\n", tp->data_tlpx); + osal_printk("data_ths_prepare: 0x%x\n", tp->data_ths_prepare); + osal_printk("data_ths_zero: 0x%x\n", tp->data_ths_zero); + osal_printk("data_ths_trail: 0x%x\n", tp->data_ths_trail); + osal_printk("=========================\n"); +#endif +} +#endif + +#endif /* end of #if mipi_tx_desc("phy time parameter") */ + +#if mipi_tx_desc("phy cfg") + +#ifdef OT_FPGA +static void mipi_tx_drv_set_phy_hs_lp_switch_time(const mipi_tx_phy_timing_parameters *tp) +{ + /* data lp2hs,hs2lp time */ + g_mipi_tx_regs_va->datalane_time.u32 = 0x6001D; + /* clk lp2hs,hs2lp time */ + g_mipi_tx_regs_va->clklane_time.u32 = 0x26001E; + +#ifdef MIPI_TX_DEBUG + osal_printk("datalane_time(0x9C): 0x%x\n", g_mipi_tx_regs_va->datalane_time.u32); + osal_printk("clklane_time(0x98): 0x%x\n", g_mipi_tx_regs_va->clklane_time.u32); +#endif +} + +#else + +/* + * set data lp2hs,hs2lp time + * set clk lp2hs,hs2lp time + * unit: hsclk + */ +static void mipi_tx_drv_set_phy_hs_lp_switch_time(const mipi_tx_phy_timing_parameters *tp) +{ + unsigned char clk_post_delay = tp->clk_post_delay + 1; /* 1: logical add 1 itself */ + unsigned char tlpx = tp->clk_tlpx + 1; /* 1: logical add 1 itself */ + unsigned char clk_tclk_prepare = tp->clk_tclk_prepare + 1; /* 1: logical add 1 itself */ + unsigned char clk_tclk_zero = tp->clk_tclk_zero + 1; /* 1: logical add 1 itself */ + unsigned char data_tpre_delay = tp->data_tpre_delay + 1; /* 1: logical add 1 itself */ + unsigned char data_ths_prepare = tp->data_ths_prepare + 1; /* 1: logical add 1 itself */ + unsigned char data_ths_zero = tp->data_ths_zero + 1; /* 1: logical add 1 itself */ + unsigned char data_ths_trail = tp->data_ths_trail + 1; /* 1: logical add 1 itself */ + + /* data lp2hs,hs2lp time */ + g_mipi_tx_regs_va->datalane_time.u32 = data_tpre_delay + tlpx + data_ths_prepare + data_ths_zero + + data_ths_trail * 65536; /* 65536: phy timing params */ + + /* clk lp2hs,hs2lp time */ + g_mipi_tx_regs_va->clklane_time.u32 = tlpx + clk_tclk_prepare + clk_tclk_zero + + (clk_post_delay + data_ths_trail - 1) * 65536; /* 1, 65536: phy timing params */ + +#ifdef MIPI_TX_DEBUG + osal_printk("datalane_time(0x9C): 0x%x\n", g_mipi_tx_regs_va->datalane_time.u32); + osal_printk("clklane_time(0x98): 0x%x\n", g_mipi_tx_regs_va->clklane_time.u32); +#endif +} +#endif + + +static void mipi_tx_drv_set_phy_default_setting(void) +{ + g_mipi_tx_phy_regs_va->aphy_test_atop_1.u32 = 0x3000080; /* 0x10 TEST_ATOP_H LP */ + g_mipi_tx_phy_regs_va->common_reg_52.u32 = 0xfc; /* 0xd48 clk lane pattern */ + g_mipi_tx_phy_regs_va->common_reg_53.u32 = 0x8; /* 0xd4c ser_psave */ + g_mipi_tx_phy_regs_va->common_reg_56.u32 = 0x7; /* 0xd58 lprxcd en */ + g_mipi_tx_phy_regs_va->common_reg_57.u32 = 0x0; /* 0xd5c cphy pre de drv */ + g_mipi_tx_phy_regs_va->aphy_bg_cfg.u32 = 0x3; /* 0x1c phy gate clk */ + +#ifdef MIPI_TX_DEBUG + osal_printk("atop h lp (0x10): 0x%x\n", g_mipi_tx_phy_regs_va->aphy_test_atop_1.u32); + osal_printk("clk lane pattern (0xd48): 0x%x\n", g_mipi_tx_phy_regs_va->common_reg_52.u32); + osal_printk("ser psave (0xd4c): 0x%x\n", g_mipi_tx_phy_regs_va->common_reg_53.u32); + osal_printk("lp rx cd en (0xd58): 0x%x\n", g_mipi_tx_phy_regs_va->common_reg_56.u32); + osal_printk("cphy pre de drv(0xd5c): 0x%x\n", g_mipi_tx_phy_regs_va->common_reg_57.u32); +#endif +} + + +static void mipi_tx_drv_set_input_enable(unsigned char input_en) +{ + volatile reg_operation_mode operation_mode = {0}; + + operation_mode.u32 = g_mipi_tx_regs_va->operation_mode.u32; + if (input_en == 0) { + operation_mode.u32 = 0; + g_mipi_tx_regs_va->operation_mode.u32 = operation_mode.u32; + return; + } + + operation_mode.bits.mem_ck_en = 1; + operation_mode.bits.input_en = 1; + operation_mode.bits.hss_abnormal_rst = 1; + operation_mode.bits.read_empty_vsync_en = 1; + g_mipi_tx_regs_va->operation_mode.u32 = operation_mode.u32; +} + +void mipi_tx_drv_set_phy_cfg(void) +{ + unsigned int actual_data_rate = mipi_tx_get_actual_phy_data_rate(); + mipi_tx_phy_timing_parameters tp = {0}; + + /* + * reset phy before setting phy: + * forcepll: pll enable + * enableclk: enable clk lane + * rstz: unreset + * shutdownz: powerup + */ + g_mipi_tx_regs_va->phy_ctrl.u32 = 0x0; + osal_udelay(1000); /* 1000: 1000us */ + + /* disable input, done in mipi_tx_drv_set_controller_cfg */ + mipi_tx_drv_set_input_enable(0); + + /* pwr_up unreset */ + g_mipi_tx_regs_va->ctrl_reset.u32 = 0x0; + osal_udelay(1); + g_mipi_tx_regs_va->ctrl_reset.u32 = 0x1; + + /* set phy pll parameters setx to generate data rate */ + mipi_tx_drv_set_phy_pll_setx(actual_data_rate); + + /* get global operation timing parameters */ + mipi_tx_drv_get_phy_timing_parameters(&tp); + + /* set global operation timing parameters */ + mipi_tx_drv_set_phy_timing_parameters(&tp); + + /* + * dsi controller + * set hs switch to lp and lp switch to hs time + */ + mipi_tx_drv_set_phy_hs_lp_switch_time(&tp); + + /* mipitx clk default */ + mipi_tx_drv_set_phy_default_setting(); + + /* + * unreset phy after setting phy: + * forcepll: pll enable + * enableclk: enable clk lane + * rstz: unreset + * shutdownz: powerup + */ + + /* pwr_up unreset */ + g_mipi_tx_regs_va->ctrl_reset.u32 = 0x0; + g_mipi_tx_regs_va->phy_ctrl.u32 = 0xF; + osal_udelay(200); /* 200: 200us */ + g_mipi_tx_regs_va->ctrl_reset.u32 = 0x1; + osal_msleep(1); +} + +#endif /* #if mipi_tx_desc("phy cfg") */ + +#if mipi_tx_desc("controller cfg") + +static void set_output_format(const combo_dev_cfg_t *dev_cfg) +{ + int color_coding = 0; + + if (dev_cfg->out_mode == OUT_MODE_CSI) { + if (dev_cfg->out_format == OUT_FORMAT_YUV420_8BIT_NORMAL) { + color_coding = MIPI_TX_CSI_YUV420_8BIT; + } else if (dev_cfg->out_format == OUT_FORMAT_YUV420_8BIT_LEGACY) { + color_coding = MIPI_TX_CSI_LEGACY_YUV420_8BIT; + } else if (dev_cfg->out_format == OUT_FORMAT_YUV422_8BIT) { + color_coding = MIPI_TX_CSI_YUV422_8BIT; + } else if (dev_cfg->out_format == OUT_FORMAT_RGB_888) { + color_coding = MIPI_TX_CSI_RGB888; + } else if (dev_cfg->out_format == OUT_FORMAT_RAW_8BIT) { + color_coding = MIPI_TX_CSI_RAW8; + } else if (dev_cfg->out_format == OUT_FORMAT_RAW_10BIT) { + color_coding = MIPI_TX_CSI_RAW10; + } else if (dev_cfg->out_format == OUT_FORMAT_RAW_12BIT) { + color_coding = MIPI_TX_CSI_RAW12; + } else if (dev_cfg->out_format == OUT_FORMAT_RAW_14BIT) { + color_coding = MIPI_TX_CSI_RAW14; + } else if (dev_cfg->out_format == OUT_FORMAT_RAW_16BIT) { + color_coding = MIPI_TX_CSI_RAW16; + } + } else { + if (dev_cfg->out_format == OUT_FORMAT_RGB_16BIT) { + color_coding = MIPI_TX_DSI_RGB_16BIT; + } else if (dev_cfg->out_format == OUT_FORMAT_RGB_18BIT) { + color_coding = MIPI_TX_DSI_RGB_18BIT; + } else if (dev_cfg->out_format == OUT_FORMAT_RGB_18BIT_LOOSELY) { + color_coding = MIPI_TX_DSI_RGB_18BIT_LOOSELY; + } else if (dev_cfg->out_format == OUT_FORMAT_RGB_24BIT) { + color_coding = MIPI_TX_DSI_RGB_24BIT; + } else if (dev_cfg->out_format == OUT_FORMAT_YUV420_12BIT) { + color_coding = MIPI_TX_DSI_YCBCR420_12BIT; + } else if (dev_cfg->out_format == OUT_FORMAT_YUV422_16BIT) { + color_coding = MIPI_TX_DSI_YCBCR422_16BIT; + } + } + + g_mipi_tx_regs_va->data_type.u32 = color_coding; +#ifdef MIPI_TX_DEBUG + osal_printk("set_output_format: 0x%x\n", color_coding); +#endif +} + +static void mipi_tx_hal_set_cmd_video_mode(cmd_video_mode cmd_video) +{ + volatile reg_mode_cfg mode_cfg; + mode_cfg.u32 = g_mipi_tx_regs_va->mode_cfg.u32; + mode_cfg.bits.cmd_video_mode = cmd_video; + g_mipi_tx_regs_va->mode_cfg.u32 = mode_cfg.u32; +} + +static void mipi_tx_hal_set_video_mode_type(unsigned int video_mode_type) +{ + volatile reg_mode_cfg mode_cfg; + + mode_cfg.u32 = g_mipi_tx_regs_va->mode_cfg.u32; + mode_cfg.bits.video_mode_type = video_mode_type; + g_mipi_tx_regs_va->mode_cfg.u32 = mode_cfg.u32; +} + +static void set_video_mode_cfg(const combo_dev_cfg_t *dev_cfg) +{ + int video_mode_type; + volatile reg_read_memory_delay_ctrl read_memory_delay_ctrl; + + if (dev_cfg->video_mode == NON_BURST_MODE_SYNC_PULSES) { + video_mode_type = 0; /* 0: Non-burst with sync pulse */ + } else if (dev_cfg->video_mode == NON_BURST_MODE_SYNC_EVENTS) { + video_mode_type = 1; /* 1: Non-burst with sync */ + } else { + video_mode_type = 2; /* 2: burst mode */ + } + + if ((dev_cfg->out_mode == OUT_MODE_CSI) || + (dev_cfg->out_mode == OUT_MODE_DSI_CMD)) { + video_mode_type = 2; /* 2: burst mode */ + } + + /* + * mode config + * other: burst mode + * 00: Non-burst with sync pulse + * 01: Non-burst with sync + */ + mipi_tx_hal_set_cmd_video_mode(COMMAND_MODE); + mipi_tx_hal_set_video_mode_type(video_mode_type); + + g_mipi_tx_regs_va->video_lp_en.u32 = 0x3f; + + /* delay value setting. */ + read_memory_delay_ctrl.u32 = g_mipi_tx_regs_va->read_memory_delay_ctrl.u32; + if ((dev_cfg->video_mode == NON_BURST_MODE_SYNC_PULSES) || + (dev_cfg->video_mode == NON_BURST_MODE_SYNC_EVENTS)) { + read_memory_delay_ctrl.bits.delay_abnormal = 0x1; + } else if (dev_cfg->video_mode == BURST_MODE) { + read_memory_delay_ctrl.bits.delay_abnormal = 0x0; + } + g_mipi_tx_regs_va->read_memory_delay_ctrl.u32 = read_memory_delay_ctrl.u32; + + if ((dev_cfg->out_mode == OUT_MODE_DSI_VIDEO) || + (dev_cfg->out_mode == OUT_MODE_CSI)) { + g_mipi_tx_regs_va->videom_pkt_size.u32 = dev_cfg->sync_info.hact; + } else { + g_mipi_tx_regs_va->command_pkt_size.u32 = dev_cfg->sync_info.hact; + } + + /* num_chunks/null_size */ + g_mipi_tx_regs_va->videom_num_chunks.u32 = 0x0; + g_mipi_tx_regs_va->videom_null_size.u32 = 0x0; +} + +static void set_timing_config(const combo_dev_cfg_t *dev_cfg) +{ + unsigned int hsa_time; + unsigned int hbp_time; + unsigned int hline_time; + unsigned int actual_phy_data_rate = mipi_tx_get_actual_phy_data_rate(); + const unsigned int htime_tmp = 1000 / 8; /* 1000, 8: 1000Hz / 8bit */ + + if (dev_cfg->pixel_clk == 0) { + osal_printk("dev_cfg->pixel_clk is 0, illegal.\n"); + return; + } + + actual_phy_data_rate = actual_phy_data_rate / 10; /* 10: actual_phy_data_rate unit trans to MHZ */ + + hsa_time = actual_phy_data_rate * dev_cfg->sync_info.hpw * htime_tmp / dev_cfg->pixel_clk; + hbp_time = actual_phy_data_rate * dev_cfg->sync_info.hbp * htime_tmp / dev_cfg->pixel_clk; + hline_time = actual_phy_data_rate * (dev_cfg->sync_info.hpw + + dev_cfg->sync_info.hact + + dev_cfg->sync_info.hbp + + dev_cfg->sync_info.hfp) * htime_tmp / dev_cfg->pixel_clk; + + g_mipi_tx_regs_va->videom_hsa_size.u32 = hsa_time; + g_mipi_tx_regs_va->videom_hbp_size.u32 = hbp_time; + g_mipi_tx_regs_va->videom_hline_size.u32 = hline_time; + + g_mipi_tx_regs_va->videom_vsa_lines.u32 = dev_cfg->sync_info.vpw; + g_mipi_tx_regs_va->videom_vbp_lines.u32 = dev_cfg->sync_info.vbp; + g_mipi_tx_regs_va->videom_vfp_lines.u32 = dev_cfg->sync_info.vfp; + g_mipi_tx_regs_va->videom_vactive_lines.u32 = dev_cfg->sync_info.vact; + +#ifdef MIPI_TX_DEBUG + osal_printk("hpw(0x48): 0x%x\n", dev_cfg->sync_info.hpw); + osal_printk("hbp(0x4c): 0x%x\n", dev_cfg->sync_info.hbp); + osal_printk("hact(0x50): 0x%x\n", dev_cfg->sync_info.hact); + osal_printk("hfp(0x50): 0x%x\n", dev_cfg->sync_info.hfp); + osal_printk("vact(0x54): 0x%x\n", dev_cfg->sync_info.vact); + osal_printk("vbp(0x58): 0x%x\n", dev_cfg->sync_info.vbp); + osal_printk("vfp(0x5c): 0x%x\n", dev_cfg->sync_info.vfp); + osal_printk("vpw(0x60): 0x%x\n", dev_cfg->sync_info.vpw); +#endif +} + +static void mipi_tx_set_lane_id(int lane_idx, short lane_id) +{ + reg_lane_id lane_id_reg; + lane_id_reg.u32 = g_mipi_tx_regs_va->lane_id.u32; + + switch (lane_id) { + case 0: + lane_id_reg.bits.lane0_id = lane_idx; + break; + + case 1: + lane_id_reg.bits.lane1_id = lane_idx; + break; + + case 2: /* 2: lane2 */ + lane_id_reg.bits.lane2_id = lane_idx; + break; + + case 3: /* 3: lane3 */ + lane_id_reg.bits.lane3_id = lane_idx; + break; + + default: + break; + } + g_mipi_tx_regs_va->lane_id.u32 = lane_id_reg.u32; +} + +static void mipi_tx_set_disable_lane_id(int lane_idx, short invalid_lane_num) +{ + reg_lane_id lane_id_reg; + lane_id_reg.u32 = g_mipi_tx_regs_va->lane_id.u32; + + switch (invalid_lane_num) { + case 1: + lane_id_reg.bits.lane3_id = lane_idx; + break; + + case 2: /* 2: 2lanes */ + lane_id_reg.bits.lane2_id = lane_idx; + break; + + case 3: /* 3: 3lanes */ + lane_id_reg.bits.lane1_id = lane_idx; + break; + + default: + break; + } + + g_mipi_tx_regs_va->lane_id.u32 = lane_id_reg.u32; +} + +static void set_lane_config(const short lane_id[], int lane_id_len) +{ + const int max_lane_num = LANE_MAX_NUM; + int i; + int invalid_lane_num = 0; + const int unused_id = 3; /* 3, for unused lane */ +#ifdef MIPI_TX_DEBUG + reg_lane_id lane_id_reg; +#endif + + g_mipi_tx_regs_va->lane_num.u32 = mipi_tx_get_lane_num(lane_id, lane_id_len) - 1; + + for (i = 0; i < max_lane_num; i++) { + if (lane_id[i] == MIPI_TX_DISABLE_LANE_ID) { + invalid_lane_num++; + mipi_tx_set_disable_lane_id(unused_id, invalid_lane_num); + continue; + } + mipi_tx_set_lane_id(i, lane_id[i]); + } + +#ifdef MIPI_TX_DEBUG + lane_id_reg.u32 = g_mipi_tx_regs_va->lane_id.u32; + osal_printk("LANE_ID: 0x%x\n", lane_id_reg.u32); +#endif +} + +static void mipi_tx_hal_set_request_hsclk_en(unsigned char clk_en) +{ + volatile reg_clklane_ctrl clk_lane_ctrl; + + clk_lane_ctrl.u32 = g_mipi_tx_regs_va->clklane_ctrl.u32; + clk_lane_ctrl.bits.txrequesthsclk = clk_en; + g_mipi_tx_regs_va->clklane_ctrl.u32 = clk_lane_ctrl.u32; +} + +static void mipi_tx_hal_set_clklane_continue_en(unsigned char clk_en) +{ + volatile reg_clklane_ctrl clk_lane_ctrl; + + clk_lane_ctrl.u32 = g_mipi_tx_regs_va->clklane_ctrl.u32; + clk_lane_ctrl.bits.clklane_continue = clk_en; + g_mipi_tx_regs_va->clklane_ctrl.u32 = clk_lane_ctrl.u32; +} + +static void mipi_tx_drv_phy_reset(void) +{ + volatile reg_phy_ctrl phy_ctrl; + + phy_ctrl.u32 = g_mipi_tx_regs_va->phy_ctrl.u32; + phy_ctrl.bits.rstz = 0x0; + g_mipi_tx_regs_va->phy_ctrl.u32 = phy_ctrl.u32; +} + +static void mipi_tx_drv_phy_unreset(void) +{ + volatile reg_phy_ctrl phy_ctrl; + + phy_ctrl.u32 = g_mipi_tx_regs_va->phy_ctrl.u32; + phy_ctrl.bits.rstz = 0x1; + g_mipi_tx_regs_va->phy_ctrl.u32 = phy_ctrl.u32; +} + +void mipi_tx_drv_phy_power_down(void) +{ + volatile reg_phy_ctrl phy_ctrl; + + phy_ctrl.u32 = g_mipi_tx_regs_va->phy_ctrl.u32; + phy_ctrl.bits.shutdownz = 0x0; + g_mipi_tx_regs_va->phy_ctrl.u32 = phy_ctrl.u32; +} + +static void mipi_tx_drv_set_clkmgr_cfg(void) +{ + unsigned int actual_phy_data_rate; + + actual_phy_data_rate = mipi_tx_get_actual_phy_data_rate() / 10; /* 10: actual_phy_data_rate unit trans to MHZ */ + if (actual_phy_data_rate / 160 < 2) { /* 160: half of 320, 2: half */ + g_mipi_tx_regs_va->crg_cfg.u32 = 0x102; /* 258 */ + } else { + g_mipi_tx_regs_va->crg_cfg.u32 = 0x100 + + (actual_phy_data_rate + 160 - 1) / 160; /* align to 160 */ + } +#ifdef MIPI_TX_DEBUG + osal_printk("crg_cfg: 0x%x\n", g_mipi_tx_regs_va->crg_cfg.u32); +#endif +} + +static void mipi_tx_drv_set_controller_cmd_tran_mode(command_trans_mode trans_mode) +{ + volatile reg_command_tran_mode command_tran_mode; + + command_tran_mode.u32 = g_mipi_tx_regs_va->command_tran_mode.u32; + command_tran_mode.bits.max_rd_pkt_size_tran = trans_mode; + command_tran_mode.bits.gen_sw_0p = trans_mode; + command_tran_mode.bits.gen_sw_1p = trans_mode; + command_tran_mode.bits.gen_sw_2p = trans_mode; + command_tran_mode.bits.gen_sr_0p = trans_mode; + command_tran_mode.bits.gen_sr_1p = trans_mode; + command_tran_mode.bits.gen_sr_2p = trans_mode; + command_tran_mode.bits.gen_lw = trans_mode; + command_tran_mode.bits.dcs_sw_0p = trans_mode; + command_tran_mode.bits.dcs_sw_1p = trans_mode; + command_tran_mode.bits.dcs_sr_0p = trans_mode; + command_tran_mode.bits.dcs_lw = trans_mode; + g_mipi_tx_regs_va->command_tran_mode.u32 = command_tran_mode.u32; +} + +static void mipi_tx_drv_set_controller_video_tran_mode(command_trans_mode trans_mode) +{ + volatile reg_mode_cfg mode_cfg; + + mode_cfg.u32 = g_mipi_tx_regs_va->mode_cfg.u32; + mode_cfg.bits.cmd_mode_tran_type = trans_mode; + g_mipi_tx_regs_va->mode_cfg.u32 = mode_cfg.u32; +} + +static void mipi_tx_drv_set_controller_cmd_datatype(const combo_dev_cfg_t *dev_cfg) +{ + volatile reg_datatype0 datatype0; + unsigned int dt_pixel = MIPI_TX_CSI_DATA_TYPE_RAW_16BIT; + if (dev_cfg->out_mode == OUT_MODE_CSI) { + if (dev_cfg->out_format == OUT_FORMAT_YUV420_8BIT_NORMAL) { + dt_pixel = MIPI_TX_CSI_DATA_TYPE_YUV420_8BIT_NORMAL; + } else if (dev_cfg->out_format == OUT_FORMAT_YUV420_8BIT_LEGACY) { + dt_pixel = MIPI_TX_CSI_DATA_TYPE_YUV420_8BIT_LEGACY; + } else if (dev_cfg->out_format == OUT_FORMAT_YUV422_8BIT) { + dt_pixel = MIPI_TX_CSI_DATA_TYPE_YUV422_8BIT; + } else if (dev_cfg->out_format == OUT_FORMAT_RGB_888) { + dt_pixel = MIPI_TX_CSI_DATA_TYPE_RBG_888; + } else if (dev_cfg->out_format == OUT_FORMAT_RAW_8BIT) { + dt_pixel = MIPI_TX_CSI_DATA_TYPE_RAW_8BIT; + } else if (dev_cfg->out_format == OUT_FORMAT_RAW_10BIT) { + dt_pixel = MIPI_TX_CSI_DATA_TYPE_RAW_10BIT; + } else if (dev_cfg->out_format == OUT_FORMAT_RAW_12BIT) { + dt_pixel = MIPI_TX_CSI_DATA_TYPE_RAW_12BIT; + } else if (dev_cfg->out_format == OUT_FORMAT_RAW_14BIT) { + dt_pixel = MIPI_TX_CSI_DATA_TYPE_RAW_14BIT; + } else if (dev_cfg->out_format == OUT_FORMAT_RAW_16BIT) { + dt_pixel = MIPI_TX_CSI_DATA_TYPE_RAW_16BIT; + } + datatype0.u32 = g_mipi_tx_regs_va->datatype0.u32; + datatype0.bits.dt_pixel = dt_pixel; + datatype0.bits.dt_hss = MIPI_TX_CSI_DATA_TYPE_LINE_START; + datatype0.bits.dt_vse = MIPI_TX_CSI_DATA_TYPE_FRAME_END; + datatype0.bits.dt_vss = MIPI_TX_CSI_DATA_TYPE_FRAME_START; + g_mipi_tx_regs_va->datatype0.u32 = datatype0.u32; + g_mipi_tx_regs_va->datatype1.u32 = 0x31081909; + g_mipi_tx_regs_va->csi_ctrl.u32 = 0x1111; + } else { + g_mipi_tx_regs_va->datatype0.u32 = 0x111213D; + g_mipi_tx_regs_va->datatype1.u32 = 0x31081909; + g_mipi_tx_regs_va->csi_ctrl.u32 = 0x10100; + } +} + +static void mipi_tx_cal_actual_phy_data_rate(unsigned int input_data_rate) +{ + unsigned int data_rate; + unsigned int actual_data_rate; + unsigned int ratio_data_rate; + + data_rate = input_data_rate * 110 / 100; /* 110, 100: data_rate * 1.1 for datatype, ECC, Checksum, lp~hs turn */ + + data_rate = data_rate * 10; /* data_rate unit is MHZ*10 */ + actual_data_rate = mipi_tx_align_up(data_rate, MIPI_TX_REF_CLK); + if (actual_data_rate > (MIPI_TX_MAX_PHY_DATA_RATE * 10)) { /* data_rate unit is MHZ * 10 */ + ratio_data_rate = (MIPI_TX_MAX_PHY_DATA_RATE * 10) / MIPI_TX_REF_CLK; /* data_rate unit is MHZ * 10 */ + actual_data_rate = ratio_data_rate * MIPI_TX_REF_CLK; + } + + mipi_tx_set_actual_phy_data_rate(actual_data_rate); +} + +void mipi_tx_drv_set_ctrl_clk(unsigned int enable) +{ + unsigned long mipi_tx_crg_cfg1_addr; + + mipi_tx_crg_cfg1_addr = (unsigned long)(uintptr_t)osal_ioremap(MIPI_TX_CRG, (unsigned long)0x4); + /* mipi_tx gate clk */ + write_reg32(mipi_tx_crg_cfg1_addr, enable, 0x1); /* bit 1 */ + osal_iounmap((void *)(uintptr_t)mipi_tx_crg_cfg1_addr, (unsigned long)0x4); +} + +void mipi_tx_drv_set_controller_cfg(const combo_dev_cfg_t *dev_cfg) +{ + mipi_tx_drv_set_ctrl_clk(1); + + /* set 1st level int mask */ + g_mipi_tx_regs_va->gint_msk = 0x1ffff; + + /* OPERATION_MODE, disable input */ + mipi_tx_drv_set_input_enable(0); + + /* vc_id */ + g_mipi_tx_regs_va->video_vc.u32 = 0x0; + + /* output format */ + set_output_format(dev_cfg); + + /* txescclk,timeout */ + mipi_tx_cal_actual_phy_data_rate(dev_cfg->phy_data_rate); + mipi_tx_drv_set_clkmgr_cfg(); + + /* cmd transmission mode */ + mipi_tx_drv_set_controller_cmd_tran_mode(LOW_POWER_MODE); + + /* crc,ecc,eotp tran */ + if (dev_cfg->out_mode == OUT_MODE_CSI) { + g_mipi_tx_regs_va->pck_en.u32 = 0x0C; /* csi */ + } else { + g_mipi_tx_regs_va->pck_en.u32 = 0x1E; /* dsi */ + } + /* gen_vcid_rx */ + g_mipi_tx_regs_va->gen_vc.u32 = 0x0; + + /* video mode cfg */ + set_video_mode_cfg(dev_cfg); + + /* timing config */ + set_timing_config(dev_cfg); + + /* invact,outvact time */ + g_mipi_tx_regs_va->lp_cmd_byte.u32 = 0xff0000; + + if (dev_cfg->out_mode == OUT_MODE_CSI) { + g_mipi_tx_regs_va->command_pkt_size.u32 = 0; + g_mipi_tx_regs_va->hsrd_to_set.u32 = 0x0; + } + g_mipi_tx_regs_va->hs_lp_to_set.u32 = 0x0; + g_mipi_tx_regs_va->lprd_to_set.u32 = 0x0; + g_mipi_tx_regs_va->hswr_to_set.u32 = 0x0; + /* lp_wr_to_cnt */ + g_mipi_tx_regs_va->lpwr_to_set.u32 = 0x0; + /* bta_to_cnt */ + g_mipi_tx_regs_va->bta_to_set.u32 = 0x0; + /* read cmd hsclk */ + g_mipi_tx_regs_va->read_cmd_time.u32 = 0x7fff; /* 0x7fff hsclk */ + + /* set data type */ + mipi_tx_drv_set_controller_cmd_datatype(dev_cfg); + + /* lanes num and id */ + set_lane_config(dev_cfg->lane_id, LANE_MAX_NUM); + + /* phy_txrequlpsclk */ + g_mipi_tx_regs_va->ulps_ctrl.u32 = 0x0; + + /* tx triggers */ + g_mipi_tx_regs_va->tx_triggers.u32 = 0x0; + + g_mipi_tx_regs_va->vid_shadow_ctrl.u32 = 0x0; + + /* int0 mask disable */ + g_mipi_tx_regs_va->int0_mask.u32 = 0x0; + + /* clk continue set */ + mipi_tx_hal_set_clklane_continue_en(dev_cfg->clklane_continue_mode); +} + +#endif /* #if mipi_tx_desc("controller cfg") */ + +#if mipi_tx_desc("set cmd") + +static int mipi_tx_wait_cmd_fifo_empty(void) +{ + reg_command_status cmd_pkt_status; + unsigned int wait_count; + + wait_count = 0; + do { + cmd_pkt_status.u32 = g_mipi_tx_regs_va->command_status.u32; + + wait_count++; + + osal_udelay(1); + + if (wait_count > MIPI_TX_READ_TIMEOUT_CNT) { + mipi_tx_err("timeout when send cmd buffer \n"); + return -1; + } + } while (cmd_pkt_status.bits.command_empty == 0); + + return 0; +} + +static int mipi_tx_wait_write_fifo_empty(void) +{ + reg_command_status cmd_pkt_status; + unsigned int wait_count; + + wait_count = 0; + do { + cmd_pkt_status.u32 = g_mipi_tx_regs_va->command_status.u32; + + wait_count++; + + osal_udelay(1); + + if (wait_count > MIPI_TX_READ_TIMEOUT_CNT) { + mipi_tx_err("timeout when send data buffer \n"); + return -1; + } + } while (cmd_pkt_status.bits.pld_write_empty == 0); + + return 0; +} + +static int mipi_tx_wait_write_fifo_not_full(void) +{ + reg_command_status cmd_pkt_status; + unsigned int wait_count; + + wait_count = 0; + do { + cmd_pkt_status.u32 = g_mipi_tx_regs_va->command_status.u32; + if (wait_count > 0) { + osal_udelay(1); + mipi_tx_err("write fifo full happened wait count = %u\n", wait_count); + } + if (wait_count > MIPI_TX_READ_TIMEOUT_CNT) { + mipi_tx_err("timeout when wait write fifo not full buffer \n"); + return -1; + } + wait_count++; + } while (cmd_pkt_status.bits.pld_write_full == 1); + + return 0; +} + +/* + * set payloads data by writing register + * each 4 bytes in cmd corresponds to one register + */ +static void mipi_tx_drv_set_payload_data(const unsigned char *cmd, unsigned short cmd_size) +{ + reg_command_payload gen_pld_data; + int i, j; + + gen_pld_data.u32 = g_mipi_tx_regs_va->command_payload.u32; + + for (i = 0; i < (cmd_size / MIPI_TX_BYTES_PER_WORD); i++) { + gen_pld_data.bits.command_pld_b1 = cmd[i * MIPI_TX_BYTES_PER_WORD + MIPI_TX_CMD_BYTE1]; + gen_pld_data.bits.command_pld_b2 = cmd[i * MIPI_TX_BYTES_PER_WORD + MIPI_TX_CMD_BYTE2]; + gen_pld_data.bits.command_pld_b3 = cmd[i * MIPI_TX_BYTES_PER_WORD + MIPI_TX_CMD_BYTE3]; + gen_pld_data.bits.command_pld_b4 = cmd[i * MIPI_TX_BYTES_PER_WORD + MIPI_TX_CMD_BYTE4]; + + mipi_tx_wait_write_fifo_not_full(); + g_mipi_tx_regs_va->command_payload.u32 = gen_pld_data.u32; + } + + j = cmd_size % MIPI_TX_BYTES_PER_WORD; + if (j != 0) { + if (j > 0) { + gen_pld_data.bits.command_pld_b1 = cmd[i * MIPI_TX_BYTES_PER_WORD + MIPI_TX_CMD_BYTE1]; + } + if (j > 1) { + gen_pld_data.bits.command_pld_b2 = cmd[i * MIPI_TX_BYTES_PER_WORD + MIPI_TX_CMD_BYTE2]; + } + if (j > 2) { /* 2 bytes */ + gen_pld_data.bits.command_pld_b3 = cmd[i * MIPI_TX_BYTES_PER_WORD + MIPI_TX_CMD_BYTE3]; + } + + mipi_tx_wait_write_fifo_not_full(); + g_mipi_tx_regs_va->command_payload.u32 = gen_pld_data.u32; + } + +#ifdef MIPI_TX_DEBUG + osal_printk("\n=====set cmd=======\n"); + osal_printk("gen_pld_data(0x70): 0x%x\n", gen_pld_data.u32); +#endif + + return; +} + +static void mipi_tx_drv_set_cmd_work_param(mipi_tx_work_mode_t work_mode, unsigned char lp_clk_en) +{ + command_trans_mode trans_mode[MIPI_TX_WORK_MODE_BUTT] = {LOW_POWER_MODE, HIGH_SPEED_MODE}; + + /* set cmd tran work mode */ + mipi_tx_drv_set_controller_cmd_tran_mode(trans_mode[work_mode]); + + /* set video tran work mode */ + mipi_tx_drv_set_controller_video_tran_mode(trans_mode[work_mode]); + + /* set lp clk en */ + mipi_tx_hal_set_request_hsclk_en(lp_clk_en); +} + +static void mipi_tx_drv_set_command_header(unsigned short data_type, unsigned short data_param) +{ + volatile reg_command_header gen_hdr; + + gen_hdr.u32 = g_mipi_tx_regs_va->command_header.u32; + gen_hdr.bits.command_virtualchannel = 0; /* always 0 */ + gen_hdr.bits.command_datatype = data_type; + gen_hdr.bits.command_wordcount_low = get_low_byte(data_param); + gen_hdr.bits.command_wordcount_high = get_high_byte(data_param); + g_mipi_tx_regs_va->command_header.u32 = gen_hdr.u32; +#ifdef MIPI_TX_DEBUG + osal_printk("\n=====set cmd=======\n"); + osal_printk("gen_hdr(0x6C): 0x%x\n", gen_hdr.u32); +#endif +} + +int mipi_tx_drv_set_cmd_info(const cmd_info_t *cmd_info) +{ + unsigned char *cmd = NULL; + + /* set work mode and clk lane en */ + mipi_tx_drv_set_cmd_work_param(cmd_info->work_mode, cmd_info->lp_clk_en); + + if (cmd_info->cmd != NULL) { + cmd = (unsigned char *)osal_kmalloc(cmd_info->cmd_size, OSAL_GFP_KERNEL); + if (cmd == NULL) { + mipi_tx_err("kmalloc fail,please check,need %d bytes\n", cmd_info->cmd_size); + return -1; + } + + if (osal_copy_from_user(cmd, cmd_info->cmd, cmd_info->cmd_size)) { + osal_kfree(cmd); + cmd = NULL; + return -1; + } + + mipi_tx_drv_set_payload_data(cmd, cmd_info->cmd_size); + + osal_kfree(cmd); + cmd = NULL; + } + + mipi_tx_drv_set_command_header(cmd_info->data_type, cmd_info->cmd_size); + + /* wait transfer end */ + osal_udelay(350); /* 350us */ + + mipi_tx_wait_cmd_fifo_empty(); + mipi_tx_wait_write_fifo_empty(); + +#ifdef MIPI_TX_DEBUG + osal_printk("cmd_info->data_type: 0x%x\n", cmd_info->data_type); + osal_printk("cmd_info->cmd_size: 0x%x\n", cmd_info->cmd_size); +#endif + + /* resume work mode and clk lane en */ + mipi_tx_drv_set_cmd_work_param(mipi_tx_get_work_mode(), mipi_tx_get_lp_clk_en()); + + return 0; +} + +#endif /* #if mipi_tx_desc("set cmd") */ + +#if mipi_tx_desc("get cmd") + +static int mipi_tx_wait_read_fifo_not_empty(void) +{ + reg_int0_status int_st0; + reg_int1_status int_st1; + unsigned int wait_count; + reg_command_status cmd_pkt_status; + + wait_count = 0; + do { + int_st1.u32 = g_mipi_tx_regs_va->int1_status.u32; + int_st0.u32 = g_mipi_tx_regs_va->int0_status.u32; + + /* + * 0x0000101e: + * to_lp_rx, rxecc_multi_err, rxecc_single_err, rxcrc_err, rxpkt_size_err + */ + if ((int_st1.u32 & 0x0000101e) != 0) { + mipi_tx_err("err happened when read data, int_st1 = 0x%x,int_st0 = %x\n", int_st1.u32, int_st0.u32); + return -1; + } + + if (wait_count > MIPI_TX_READ_TIMEOUT_CNT) { + mipi_tx_err("timeout when read data\n"); + return -1; + } + + wait_count++; + + osal_udelay(1); + + cmd_pkt_status.u32 = g_mipi_tx_regs_va->command_status.u32; + } while (cmd_pkt_status.bits.pld_read_empty == 0x1); + + return 0; +} + +static int mipi_tx_wait_read_fifo_empty(void) +{ + reg_command_payload pld_data; + reg_int1_status int_st1; + unsigned int wait_count; + + wait_count = 0; + do { + int_st1.u32 = g_mipi_tx_regs_va->int1_status.u32; + if ((int_st1.bits.rxpld_rd_err) == 0x0) { + pld_data.u32 = g_mipi_tx_regs_va->command_payload.u32; + } + wait_count++; + osal_udelay(1); + if (wait_count > MIPI_TX_READ_TIMEOUT_CNT) { + mipi_tx_err("timeout when clear cmd data buffer, the last read data is 0x%x\n", pld_data.u32); + return -1; + } + } while ((int_st1.bits.rxpld_rd_err) == 0x0); + + return 0; +} + +static int mipi_tx_send_short_packet(short unsigned data_type, unsigned short data_param) +{ + mipi_tx_drv_set_command_header(data_type, data_param); + + if (mipi_tx_wait_cmd_fifo_empty() != 0) { + return -1; + } + + return 0; +} + +static int mipi_tx_get_read_fifo_data(unsigned int get_data_size, unsigned char *data_buf) +{ + reg_command_payload pld_data; + unsigned int i, j; + + for (i = 0; i < get_data_size / MIPI_TX_BYTES_PER_WORD; i++) { + if (mipi_tx_wait_read_fifo_not_empty() != 0) { + return -1; + } + pld_data.u32 = g_mipi_tx_regs_va->command_payload.u32; + data_buf[i * MIPI_TX_BYTES_PER_WORD + MIPI_TX_CMD_BYTE1] = pld_data.bits.command_pld_b1; + data_buf[i * MIPI_TX_BYTES_PER_WORD + MIPI_TX_CMD_BYTE2] = pld_data.bits.command_pld_b2; + data_buf[i * MIPI_TX_BYTES_PER_WORD + MIPI_TX_CMD_BYTE3] = pld_data.bits.command_pld_b3; + data_buf[i * MIPI_TX_BYTES_PER_WORD + MIPI_TX_CMD_BYTE4] = pld_data.bits.command_pld_b4; + } + + j = get_data_size % MIPI_TX_BYTES_PER_WORD; + + if (j != 0) { + if (mipi_tx_wait_read_fifo_not_empty() != 0) { + return -1; + } + pld_data.u32 = g_mipi_tx_regs_va->command_payload.u32; + if (j > 0) { + data_buf[i * MIPI_TX_BYTES_PER_WORD + MIPI_TX_CMD_BYTE1] = pld_data.bits.command_pld_b1; + } + if (j > 1) { + data_buf[i * MIPI_TX_BYTES_PER_WORD + MIPI_TX_CMD_BYTE2] = pld_data.bits.command_pld_b2; + } + if (j > 2) { /* 2 bytes */ + data_buf[i * MIPI_TX_BYTES_PER_WORD + MIPI_TX_CMD_BYTE3] = pld_data.bits.command_pld_b3; + } + } + + return 0; +} + +static void mipi_tx_reset(void) +{ + volatile reg_phy_ctrl phy_ctrl = {0}; + volatile reg_ctrl_reset ctrl_reset = {0}; + + ctrl_reset.u32 = g_mipi_tx_regs_va->ctrl_reset.u32; + ctrl_reset.bits.ctrl_reset = 0x0; + g_mipi_tx_regs_va->ctrl_reset.u32 = ctrl_reset.u32; + + phy_ctrl.u32 = g_mipi_tx_regs_va->phy_ctrl.u32; + phy_ctrl.bits.rstz = 0x0; + g_mipi_tx_regs_va->phy_ctrl.u32 = phy_ctrl.u32; + osal_udelay(1); + + ctrl_reset.u32 = g_mipi_tx_regs_va->ctrl_reset.u32; + ctrl_reset.bits.ctrl_reset = 0x1; + g_mipi_tx_regs_va->ctrl_reset.u32 = ctrl_reset.u32; + + phy_ctrl.u32 = g_mipi_tx_regs_va->phy_ctrl.u32; + phy_ctrl.bits.rstz = 0x1; + g_mipi_tx_regs_va->phy_ctrl.u32 = phy_ctrl.u32; + osal_udelay(1); + return; +} + +int mipi_tx_drv_get_cmd_info(const get_cmd_info_t *get_cmd_info) +{ + unsigned char* data_buf = NULL; + + data_buf = (unsigned char*)osal_kmalloc(get_cmd_info->get_data_size, OSAL_GFP_KERNEL); + if (data_buf == NULL) { + return -1; + } + + if (mipi_tx_wait_read_fifo_empty() != 0) { + goto fail0; + } + + /* set work mode and clk lane en */ + mipi_tx_drv_set_cmd_work_param(get_cmd_info->work_mode, get_cmd_info->lp_clk_en); + + if (mipi_tx_send_short_packet(get_cmd_info->data_type, get_cmd_info->data_param) != 0) { + goto fail0; + } + + if (mipi_tx_get_read_fifo_data(get_cmd_info->get_data_size, data_buf) != 0) { + /* fail will block mipi data lane ,so need reset */ + mipi_tx_reset(); + goto fail0; + } + + /* resume work mode and clk lane en */ + mipi_tx_drv_set_cmd_work_param(mipi_tx_get_work_mode(), mipi_tx_get_lp_clk_en()); + + osal_copy_to_user(get_cmd_info->get_data, data_buf, get_cmd_info->get_data_size); + + osal_kfree(data_buf); + data_buf = NULL; + return 0; + +fail0: + osal_kfree(data_buf); + data_buf = NULL; + return -1; +} + +#endif /* #if mipi_tx_desc("get cmd") */ + +#if mipi_tx_desc("set pn swap") + +static void mipi_tx_hal_set_pn_swap(int offset, char swap) +{ + volatile u_lane_reg_06 lane_reg_06; + unsigned int *addr_reg; + + addr_reg = (unsigned int *)((uintptr_t)(void *)&(g_mipi_tx_phy_regs_va->lane_reg_06) + offset); + lane_reg_06.u32 = hal_read_reg(addr_reg); + lane_reg_06.bits.reg_wire_swap = swap; + hal_write_reg(addr_reg, lane_reg_06.u32); +} + +void mipi_tx_drv_set_pn_swap(const combo_dev_pn_swap_t *pn_swap) +{ + /* + * PN SWAP + * DATA0/DATA1/DATA2/DATA3 + */ + mipi_tx_hal_set_pn_swap(0, pn_swap->pn_swap[0]); /* 0: DATA0 */ + mipi_tx_hal_set_pn_swap(1 * 0x80, pn_swap->pn_swap[1]); /* 1: DATA1 */ + mipi_tx_hal_set_pn_swap(3 * 0x80, pn_swap->pn_swap[2]); /* 3: DATA2 */ + mipi_tx_hal_set_pn_swap(4 * 0x80, pn_swap->pn_swap[3]); /* 4: DATA3 */ +} + +static char mipi_tx_hal_get_pn_swap(int offset) +{ + volatile u_lane_reg_06 lane_reg_06; + unsigned int *addr_reg; + char pn_sw_value; + + addr_reg = (unsigned int *)((uintptr_t)(void *)&(g_mipi_tx_phy_regs_va->lane_reg_06) + offset); + lane_reg_06.u32 = hal_read_reg(addr_reg); + pn_sw_value = lane_reg_06.bits.reg_wire_swap; + return pn_sw_value; +} + +void mipi_tx_drv_get_pn_swap(combo_dev_pn_swap_t *pn_swap) +{ + pn_swap->pn_swap[0] = mipi_tx_hal_get_pn_swap(0); /* 0: DATA lane0 */ + pn_swap->pn_swap[1] = mipi_tx_hal_get_pn_swap(1 * 0x80); /* 1: DATA lane1 */ + pn_swap->pn_swap[2] = mipi_tx_hal_get_pn_swap(3 * 0x80); /* 3: DATA lane2 */ + pn_swap->pn_swap[3] = mipi_tx_hal_get_pn_swap(4 * 0x80); /* 4: DATA lane3 */ +} + +#endif /* #if mipi_tx_desc("set pn swap") */ + + +#if mipi_tx_desc("enable & disable") + +void mipi_tx_drv_enable_input(const out_mode_t output_mode) +{ + if ((output_mode == OUT_MODE_DSI_VIDEO) || + (output_mode == OUT_MODE_CSI)) { + mipi_tx_hal_set_cmd_video_mode(VIDEO_MODE); + } + + /* set to high speed mode */ + if (output_mode == OUT_MODE_DSI_CMD) { + mipi_tx_drv_set_controller_cmd_tran_mode(HIGH_SPEED_MODE); + } + + osal_udelay(1); + mipi_tx_hal_set_request_hsclk_en(1); + osal_udelay(1); + + /* enable input */ + mipi_tx_drv_set_input_enable(1); + + /* reset mipi_tx controller */ + g_mipi_tx_regs_va->ctrl_reset.u32 = 0x0; + /* reset phy digital module by controller */ + mipi_tx_drv_phy_reset(); + osal_udelay(1); + mipi_tx_drv_phy_unreset(); + g_mipi_tx_regs_va->ctrl_reset.u32 = 0x1; + +#if MIPI_TX_INTERRUPTS_ENABLE + /* enable int */ + mipi_tx_enable_int(0x1); +#endif +} + +void mipi_tx_drv_reset_pn_swap(void) +{ + combo_dev_pn_swap_t tx_pn_swap = {0}; + + tx_pn_swap.pn_swap[0] = 0; /* 0: DATA0 */ + tx_pn_swap.pn_swap[1] = 0; /* 1: DATA1 */ + tx_pn_swap.pn_swap[2] = 0; /* 3: DATA2 */ + tx_pn_swap.pn_swap[3] = 0; /* 4: DATA3 */ + mipi_tx_drv_set_pn_swap(&tx_pn_swap); +} + +void mipi_tx_drv_disable_input(void) +{ + volatile reg_operation_mode operation_mode; + + /* disable int */ +#if MIPI_TX_INTERRUPTS_ENABLE + mipi_tx_enable_int(0x0); +#endif + + /* set to disable input */ + operation_mode.u32 = g_mipi_tx_regs_va->operation_mode.u32; + operation_mode.bits.input_en = 0x0; + g_mipi_tx_regs_va->operation_mode.u32 = operation_mode.u32; + + /* set to lp mode */ + mipi_tx_drv_set_controller_cmd_tran_mode(LOW_POWER_MODE); + + /* set to command mode */ + mipi_tx_hal_set_cmd_video_mode(COMMAND_MODE); + + /* default: clklane disable */ + mipi_tx_hal_set_request_hsclk_en(0); + mipi_tx_hal_set_clklane_continue_en(0); + + mipi_tx_drv_phy_power_down(); + mipi_tx_reset(); +} + +#endif /* #if mipi_tx_desc("enable & disable") */ + +#if mipi_tx_desc("init") + +static int mipi_tx_drv_reg_init(void) +{ + if (g_mipi_tx_regs_va == NULL) { + g_mipi_tx_regs_va = (volatile mipi_tx_regs_type_t *)osal_ioremap( + MIPI_TX_REGS_ADDR, (unsigned int)MIPI_TX_REGS_SIZE); + if (g_mipi_tx_regs_va == NULL) { + mipi_tx_err("remap mipi_tx reg addr fail\n"); + return -1; + } + g_reg_map_flag = 1; + } + + if (g_mipi_tx_phy_regs_va == NULL) { + g_mipi_tx_phy_regs_va = (volatile mipi_tx_phy_regs_type_t *)osal_ioremap( + MIPI_TX_PHY_REGS_ADDR, (unsigned int)MIPI_TX_PHY_REGS_SIZE); + if (g_mipi_tx_phy_regs_va == NULL) { + mipi_tx_err("remap mipi_tx phy reg addr fail\n"); + return -1; + } + g_phy_reg_map_flag = 1; + } + + return 0; +} + +static void mipi_tx_drv_reg_exit(void) +{ + if (g_reg_map_flag == 1) { + if (g_mipi_tx_regs_va != NULL) { + osal_iounmap((void *)g_mipi_tx_regs_va, (unsigned long)MIPI_TX_REGS_SIZE); + g_mipi_tx_regs_va = NULL; + } + g_reg_map_flag = 0; + } + + if (g_phy_reg_map_flag == 1) { + if (g_mipi_tx_phy_regs_va != NULL) { + osal_iounmap((void *)g_mipi_tx_phy_regs_va, (unsigned long)MIPI_TX_PHY_REGS_SIZE); + g_mipi_tx_phy_regs_va = NULL; + } + g_phy_reg_map_flag = 0; + } +} + +#if MIPI_TX_INTERRUPTS_ENABLE +static void mipi_tx_enable_int(int enable) +{ + volatile reg_int1_mask int1_mask; + + int1_mask.u32 = g_mipi_tx_regs_va->int1_mask.u32; + int1_mask.bits.mask_vss = enable & 0x1; + g_mipi_tx_regs_va->int1_mask.u32 = int1_mask.u32; +} + +static void mipi_tx_clear_int(void) +{ + volatile reg_int1_status int1_stat; + volatile reg_int0_status int0_stat; + + /* warning: read register to clear interrupt status, do not delete it. */ + int1_stat.u32 = g_mipi_tx_regs_va->int1_status.u32; + int0_stat.u32 = g_mipi_tx_regs_va->int0_status.u32; + + /* ignore compile warning: variable 'int_stat' set but not used */ + (void)int1_stat.u32; + (void)int0_stat.u32; +} + +static int mipi_tx_interrupt_route(int irq, void* dev_id) +{ + mipi_tx_clear_int(); + return OSAL_IRQ_HANDLED; +} + +static int mipi_tx_register_irq(void) +{ + int ret; + ret = osal_irq_request(g_mipi_tx_irq_num, mipi_tx_interrupt_route, NULL, "MIPI_TX", mipi_tx_interrupt_route); + if (ret < 0) { + mipi_tx_err("mipi_tx: failed to register irq.\n"); + return -1; + } + + return 0; +} + +static void mipi_tx_unregister_irq(void) +{ + osal_irq_free(g_mipi_tx_irq_num, mipi_tx_interrupt_route); +} +#endif + +static void mipi_tx_drv_hw_init(int smooth) +{ +#ifdef OT_FPGA + /* + * reset operation for fpga version. + */ + unsigned long mipi_tx_crg_addr; + + mipi_tx_crg_addr = (unsigned long)(uintptr_t)osal_ioremap(MIPI_TX_CRG, (unsigned long)0x4); + if (mipi_tx_crg_addr == 0) { + return; + } + + write_reg32(mipi_tx_crg_addr, 0x3, 0x3); + write_reg32(mipi_tx_crg_addr, 0x0, 0x3); + + osal_iounmap((void *)(uintptr_t)mipi_tx_crg_addr, (unsigned long)0x4); + +#else + unsigned long mipi_tx_crg_cfg1_addr; + unsigned long mipi_tx_crg_cfg2_addr; + + mipi_tx_crg_cfg1_addr = (unsigned long)(uintptr_t)osal_ioremap(MIPI_TX_CRG, (unsigned long)0x4); + mipi_tx_crg_cfg2_addr = + (unsigned long)(uintptr_t)osal_ioremap(MIPI_TX_CRG + (unsigned long)0x8, (unsigned long)0x4); + + /* mipi_tx gate clk enable */ + write_reg32(mipi_tx_crg_cfg1_addr, 1, 0x1); + + /* reset */ + if (smooth == FALSE) { + write_reg32(mipi_tx_crg_cfg1_addr, 1 << 1, 0x1 << 1); /* 1: bit1 */ + osal_udelay(1); + } + + /* unreset */ + write_reg32(mipi_tx_crg_cfg1_addr, 0 << 1, 0x1 << 1); /* 1: bit1 */ + + /* select ref clk 19.2MHz */ + write_reg32(mipi_tx_crg_cfg1_addr, 0 << 2, 0x3 << 2); /* 2: bit2 */ + + /* reset mipitx */ + write_reg32(mipi_tx_crg_cfg2_addr, 0 << 8, 0x1 << 8); /* 8: bit8 */ + + write_reg32(mipi_tx_crg_cfg2_addr, 1 << 4, 0x1 << 4); /* 4: bit4 */ + + write_reg32(mipi_tx_crg_cfg2_addr, 0 << 0, 0x1 << 0); /* 0: bit0 */ + + if (smooth == FALSE) { + /* mipi_tx gate clk disable */ + write_reg32(mipi_tx_crg_cfg1_addr, 0, 0x1); + } + osal_iounmap((void *)(uintptr_t)mipi_tx_crg_cfg1_addr, (unsigned long)0x4); + osal_iounmap((void *)(uintptr_t)mipi_tx_crg_cfg2_addr, (unsigned long)0x4); +#endif +} + +int mipi_tx_drv_init(int smooth) +{ + int ret; + + ret = mipi_tx_drv_reg_init(); + if (ret < 0) { + mipi_tx_err("mipi_tx_drv_reg_init fail!\n"); + goto fail0; + } + + mipi_tx_drv_hw_init(smooth); + +#if MIPI_TX_INTERRUPTS_ENABLE + ret = mipi_tx_register_irq(); + if (ret < 0) { + mipi_tx_err("mipi_tx_register_irq fail!\n"); + goto fail1; + } +#endif + + return 0; + +#if MIPI_TX_INTERRUPTS_ENABLE +fail1: + mipi_tx_drv_reg_exit(); +#endif + +fail0: + return -1; +} + +void mipi_tx_drv_exit(void) +{ +#if MIPI_TX_INTERRUPTS_ENABLE + mipi_tx_unregister_irq(); +#endif + mipi_tx_drv_reg_exit(); +} + +#endif /* #if mipi_tx_desc("init") */ + +#ifdef __cplusplus +#if __cplusplus +} + +#endif +#endif diff --git a/kernel/mipi_tx/hi3519dv500/mipi_tx_hal.h b/kernel/mipi_tx/hi3519dv500/mipi_tx_hal.h new file mode 100644 index 00000000..b0d0a75d --- /dev/null +++ b/kernel/mipi_tx/hi3519dv500/mipi_tx_hal.h @@ -0,0 +1,214 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef MIPI_TX_HAL_H +#define MIPI_TX_HAL_H + +#include "securec.h" +#include "ot_mipi_tx.h" +#include "mipi_tx_reg.h" + +#define MIPI_TX_BITS_PER_BYTE 8 +#define MIPI_TX_INTERRUPTS_ENABLE 0 + +#define MIPI_TX_BYTES_PER_WORD 4 +#define MIPI_TX_CMD_BYTE1 0 +#define MIPI_TX_CMD_BYTE2 1 +#define MIPI_TX_CMD_BYTE3 2 +#define MIPI_TX_CMD_BYTE4 3 + +#define MIPI_TX_REGS_ADDR 0x10270000 +#define MIPI_TX_REGS_SIZE 0x2000 + +#define MIPI_TX_PHY_REGS_ADDR 0x10272000 +#define MIPI_TX_PHY_REGS_SIZE 0x2000 + +#define MIPI_TX_IRQ 83 + +#define MIPI_TX_REF_CLK 192 + +#ifdef OT_FPGA + +/* crg */ +#define MIPI_TX_CRG 0x11018140 + +/* phy addr */ +#define PLL_SET_0X14 0x14 +#define PLL_SET_0X15 0x15 +#define PLL_SET_0X16 0x16 +#define PLL_SET_0X17 0x17 +#define PLL_SET_0X1E 0x1E +#define PLL_SET_0X12 0x12 +#define PLL_SET_0X13 0x13 + +#define DATA0_TPRE_DELAY 0x30 +#define DATA1_TPRE_DELAY 0x40 +#define DATA2_TPRE_DELAY 0x50 +#define DATA3_TPRE_DELAY 0x60 + +/* clk */ +#define CLK_POST_DELAY 0x21 +#define CLK_TLPX 0x22 +#define CLK_TCLK_PREPARE 0x23 +#define CLK_TCLK_ZERO 0x24 +#define CLK_TCLK_TRAIL 0x25 + +/* data0 */ +#define DATA0_TLPX 0x32 +#define DATA0_THS_PREPARE 0x33 +#define DATA0_THS_ZERO 0x34 +#define DATA0_THS_TRAIL 0x35 + +/* data1 */ +#define DATA1_TLPX 0x42 +#define DATA1_THS_PREPARE 0x43 +#define DATA1_THS_ZERO 0x44 +#define DATA1_THS_TRAIL 0x45 + +/* data2 */ +#define DATA2_TLPX 0x52 +#define DATA2_THS_PREPARE 0x53 +#define DATA2_THS_ZERO 0x54 +#define DATA2_THS_TRAIL 0x55 + +/* data3 */ +#define DATA3_TLPX 0x62 +#define DATA3_THS_PREPARE 0x63 +#define DATA3_THS_ZERO 0x64 +#define DATA3_THS_TRAIL 0x65 + +#define DATA0_TPRE_DELAY_VALUE 0x6 +#define DATA1_TPRE_DELAY_VALUE 0x6 +#define DATA2_TPRE_DELAY_VALUE 0x6 +#define DATA3_TPRE_DELAY_VALUE 0x6 + +#define CLK_POST_DELAY_VALUE 0x0 +#define CLK_TLPX_VALUE 0x4 +#define CLK_TCLK_PREPARE_VALUE 0x3 +#define CLK_TCLK_ZERO_VALUE 0xc +#define CLK_TCLK_TRAIL_VALUE 0x4 + +#define DATA0_TLPX_VALUE 0x4 +#define DATA0_THS_PREPARE_VALUE 0x3 +#define DATA0_THS_ZERO_VALUE 0x6 +#define DATA0_THS_TRAIL_VALUE 0x4 + +#define DATA1_TLPX_VALUE 0x4 +#define DATA1_THS_PREPARE_VALUE 0x3 +#define DATA1_THS_ZERO_VALUE 0x6 +#define DATA1_THS_TRAIL_VALUE 0x4 + +#define DATA2_TLPX_VALUE 0x4 +#define DATA2_THS_PREPARE_VALUE 0x3 +#define DATA2_THS_ZERO_VALUE 0x6 +#define DATA2_THS_TRAIL_VALUE 0x4 + +#define DATA3_TLPX_VALUE 0x4 +#define DATA3_THS_PREPARE_VALUE 0x3 +#define DATA3_THS_ZERO_VALUE 0x6 +#define DATA3_THS_TRAIL_VALUE 0x4 + +#else + +/* crg */ +#define MIPI_TX_CRG 0x11018140 + +/* timing parameter */ +#define TLPX 60 +#define TCLK_PREPARE 60 +#define TCLK_ZERO 285 +#define TCLK_TRAIL 60 +#define TCLK_POST 95 +#define TPRE_DELAY 10 + +#endif /* end of #ifdef OT_FPGA */ + +#define MIPI_TX_CSI_DATA_TYPE_FRAME_START 0x00 +#define MIPI_TX_CSI_DATA_TYPE_FRAME_END 0x01 +#define MIPI_TX_CSI_DATA_TYPE_LINE_START 0x02 +#define MIPI_TX_CSI_DATA_TYPE_LINE_END 0x03 + +#define MIPI_TX_CSI_DATA_TYPE_YUV420_8BIT_NORMAL 0x18 +#define MIPI_TX_CSI_DATA_TYPE_YUV420_8BIT_LEGACY 0x1A +#define MIPI_TX_CSI_DATA_TYPE_YUV422_8BIT 0x1E +#define MIPI_TX_CSI_DATA_TYPE_RBG_888 0x24 +#define MIPI_TX_CSI_DATA_TYPE_RAW_8BIT 0x2A +#define MIPI_TX_CSI_DATA_TYPE_RAW_10BIT 0x2B +#define MIPI_TX_CSI_DATA_TYPE_RAW_12BIT 0x2C +#define MIPI_TX_CSI_DATA_TYPE_RAW_14BIT 0x2D +#define MIPI_TX_CSI_DATA_TYPE_RAW_16BIT 0x2E + +#define MIPI_TX_READ_TIMEOUT_CNT 1000 +#define MIPI_TX_MAX_RESET_PHY_TIMES 10 + +#define PREPARE_COMPENSATE 10 +#define ROUNDUP_VALUE 7999 +#define INNER_PEROID 8000 /* 8 * 1000 ,1000 is 1us = 1000ns, 8 is division ratio */ + +#define mipi_tx_align_up(x, a) ((((x) + ((a) - 1)) / (a)) * (a)) +#define mipi_tx_ceil(x, a) (((x) + (a)-1) / (a)) + +/* + * global operation timing parameters + */ +typedef struct { + unsigned char data_tpre_delay; + unsigned char clk_post_delay; + unsigned char clk_tlpx; + unsigned char clk_tclk_prepare; + unsigned char clk_tclk_zero; + unsigned char clk_tclk_trail; + unsigned char data_tlpx; + unsigned char data_ths_prepare; + unsigned char data_ths_zero; + unsigned char data_ths_trail; +} mipi_tx_phy_timing_parameters; + +typedef struct { + unsigned int vall_det; + unsigned int vact_det; + unsigned int hall_det; + unsigned int hact_det; + unsigned int hbp_det; + unsigned int hsa_det; + unsigned int vsa_det; +} mipi_tx_dev_phy_t; + +typedef enum { + HIGH_SPEED_MODE = 0, + LOW_POWER_MODE = 1, +} command_trans_mode; + +__inline static unsigned char get_low_byte(unsigned short short_data) +{ + return (unsigned char)(short_data & 0xff); +} + +__inline static unsigned char get_high_byte(unsigned short short_data) +{ + return (unsigned char)((short_data & 0xff00) >> MIPI_TX_BITS_PER_BYTE); +} + +void mipi_tx_drv_set_irq_num(unsigned int irq_num); +void mipi_tx_drv_set_regs(const mipi_tx_regs_type_t *regs); + +void mipi_tx_drv_set_phy_cfg(void); +void mipi_tx_drv_get_dev_status(mipi_tx_dev_phy_t *mipi_tx_phy_ctx); +void mipi_tx_drv_set_controller_cfg(const combo_dev_cfg_t *dev_cfg); + +int mipi_tx_drv_set_cmd_info(const cmd_info_t *cmd_info); + +int mipi_tx_drv_get_cmd_info(const get_cmd_info_t *get_cmd_info); +void mipi_tx_drv_enable_input(const out_mode_t output_mode); +void mipi_tx_drv_set_pn_swap(const combo_dev_pn_swap_t *pn_swap); +void mipi_tx_drv_get_pn_swap(combo_dev_pn_swap_t *pn_swap); +void mipi_tx_drv_reset_pn_swap(void); +void mipi_tx_drv_disable_input(void); +void mipi_tx_drv_set_ctrl_clk(unsigned int enable); +void mipi_tx_drv_phy_power_down(void); + +int mipi_tx_drv_init(int smooth); +void mipi_tx_drv_exit(void); + +#endif /* end of #ifndef MIPI_TX_HAL_H */ diff --git a/kernel/mipi_tx/hi3519dv500/mipi_tx_phy_reg.h b/kernel/mipi_tx/hi3519dv500/mipi_tx_phy_reg.h new file mode 100644 index 00000000..6c689961 --- /dev/null +++ b/kernel/mipi_tx/hi3519dv500/mipi_tx_phy_reg.h @@ -0,0 +1,2196 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef MIPI_TX_PHY_REG_H +#define MIPI_TX_PHY_REG_H +/* Define the union u_pll_status */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ad_txpll_hvflag : 1; /* [0] */ + unsigned int ad_txpll_lock : 1; /* [1] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 30; /* [31..2] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} u_pll_status; +/* Define the union u_aphy_txpll_test */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: RG_TXPLL_TEST + /* + [29]:LOCK_OV + [28]:SEL_LOCK + [26]:EN_DIV_PLANB + [25:22]:SEL_TST_CLK + [21]:EN_TEST + [20]:EN_LCKDET + [14:13]:SEL_LDO_LV + [12]:LDO_BYPASS_LV + [11]:LPF_HBW_LV + [10:8]:TEST_PLL_LV + [7]:PD_CMP_LV + [6:5]:SEL_CMP_LV + [4]:RESET_VCO_LV + [3]:PULLH_UP_LV + [2]:PULLH_DN_LV + [1]:EN_FREERUN_LV + [0]:DISC_EXT_LV + */ + unsigned int rg_txpll_test : 32; /* [31..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} u_aphy_txpll_test; +/* Define the union u_aphy_txpll_inctrl */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int rg_txpll_ictrl : 5; /* [4..0] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 27; /* [31..5] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} u_aphy_txpll_inctrl; +/* Define the union u_aphy_test_atop_0 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int rg_test_atop_l : 32; /* [31..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} u_aphy_test_atop_0; +/* Define the union u_aphy_test_atop_1 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int rg_test_atop_h : 32; /* [31..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} u_aphy_test_atop_1; +/* Define the union u_aphy_sel_ldo_cfg */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int rg_sel_ldo : 4; /* [3..0] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} u_aphy_sel_ldo_cfg; +/* Define the union u_aphy_enable_cfg */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int rg_sel_bg : 2; /* [1..0] */ + unsigned int rg_en_ldo : 2; /* [3..2] */ + // Comment of field: reserved_0 + /* Reserved */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} u_aphy_enable_cfg; +/* Define the union u_aphy_bg_cfg */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int rg_en_bg : 1; /* [0] */ + unsigned int rg_bg_en : 1; /* [1] */ + unsigned int rg_test_bg : 2; /* [3..2] */ + // Comment of field: reserved_0 + /* Reserved */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} u_aphy_bg_cfg; +/* Define the union u_aphy_pll_div_cfg */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: RG_TXPLL_DIVSEL_FB + /* PLL frequency division coefficient of Hiwing V300.fb_div must be greater than 103. If fb_div is less + than 103, + set this parameter to 2 x fb_div and perform frequency division by multiple times.The value must be less + than 256. If the value is greater than 256, + set this parameter to fb_div / 2 and then double the frequency division.In later versions, + the reg_pll_div_int in the pcs_old sheet is used. */ + unsigned int rg_txpll_divsel_fb : 11; /* [10..0] */ + unsigned int reserved_0 : 1; /* [11] */ + unsigned int rg_en_sscdiv : 1; /* [12] */ + // Comment of field: reserved_1 + /* Reserved */ + unsigned int reserved_1 : 19; /* [31..13] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} u_aphy_pll_div_cfg; +/* Define the union u_aphy_self_bist_rsl */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: AD_BISTCLK + /* APHY self - test BIST test result */ + unsigned int ad_bistclk : 10; /* [9..0] */ + // Comment of field: reserved_0 + /* Reserved */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} u_aphy_self_bist_rsl; +/* Define the union u_aphy_self_bist_cfg */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: RG_BIST_DELAY_SEL + /* APHY self - test BISTdelay SEL configuration */ + unsigned int rg_bist_delay_sel : 4; /* [3..0] */ + unsigned int reserved_0 : 4; /* [7..4] */ + // Comment of field: RG_BIST_EN + /* APHY self - test BIST EN configuration */ + unsigned int rg_bist_en : 5; /* [12..8] */ + // Comment of field: reserved_1 + /* Reserved */ + unsigned int reserved_1 : 19; /* [31..13] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} u_aphy_self_bist_cfg; +/* Define the union u_aphy_ssc_set */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: reg_set + /* Setting the Frequency Divider Ratio */ + unsigned int reg_set : 30; /* [29..0] */ + // Comment of field: reserved_0 + /* Reserved */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} u_aphy_ssc_set; +/* Define the union u_aphy_ssc_ctrl0 */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: reg_reset + /* SSC reset signal */ + unsigned int reg_reset : 1; /* [0] */ + // Comment of field: reg_ssc_sel + /* SSC block to be selected(The ssmod_top block output is connected to the APHY PLL by default.) */ + unsigned int reg_ssc_sel : 1; /* [1] */ + // Comment of field: reg_downspread + /* Downward Spreading */ + unsigned int reg_downspread : 1; /* [2] */ + // Comment of field: reg_sel_extwave + /* Whether to select external values to control SSC output */ + unsigned int reg_sel_extwave : 1; /* [3] */ + // Comment of field: reg_disable_sscg + /* Whether to disable SSC */ + unsigned int reg_disable_sscg : 1; /* [4] */ + // Comment of field: reg_hkmash_en + /* Whether to enable HKMASH */ + unsigned int reg_hkmash_en : 1; /* [5] */ + // Comment of field: reg_mash111_hk_sel + /* Whether to enable MASH111_HK */ + unsigned int reg_mash111_hk_sel : 1; /* [6] */ + // Comment of field: reserved_0 + /* Reserved */ + unsigned int reserved_0 : 1; /* [7] */ + // Comment of field: reg_spread + /* Control SSC Spreading Amplitude */ + unsigned int reg_spread : 5; /* [12..8] */ + unsigned int reserved_1 : 19; /* [31..13] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} u_aphy_ssc_ctrl0; +/* Define the union u_aphy_ssc_ctrl1 */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: reg_extwaveval + /* External Control Value */ + unsigned int reg_extwaveval : 8; /* [7..0] */ + // Comment of field: reg_ext_maxaddr + /* External Control Address */ + unsigned int reg_ext_maxaddr : 8; /* [15..8] */ + // Comment of field: reserved_0 + /* Reserved */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} u_aphy_ssc_ctrl1; +/* Define the union u_aphy_ssc_ctrl2 */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: reg_sld + /* Load divider value */ + unsigned int reg_sld : 1; /* [0] */ + // Comment of field: reg_ssc_sync + /* SSC loading synchronization signal */ + unsigned int reg_ssc_sync : 1; /* [1] */ + // Comment of field: reg_clr + /* SSC reset signal */ + unsigned int reg_clr : 1; /* [2] */ + // Comment of field: reserved_0 + /* Reserved */ + unsigned int reserved_0 : 13; /* [15..3] */ + // Comment of field: reg_span + /* Controls the frequency of the SSC spread spectrum. */ + unsigned int reg_span : 12; /* [27..16] */ + // Comment of field: reserved_1 + /* Reserved */ + unsigned int reserved_1 : 4; /* [31..28] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} u_aphy_ssc_ctrl2; +/* Define the union u_aphy_ssc_ctrl3 */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: reg_step + /* Control the amplitude of the SSC. */ + unsigned int reg_step : 15; /* [14..0] */ + unsigned int reserved_0 : 17; /* [31..15] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} u_aphy_ssc_ctrl3; +/* Define the union u_aphy_ssc_status0 */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: ssc_offset + /* SSC OFFSET Output */ + unsigned int ssc_offset : 30; /* [29..0] */ + // Comment of field: reserved_0 + /* Reserved */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} u_aphy_ssc_status0; +/* Define the union u_aphy_ssc_status1 */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: set_offset + /* SSC OFFSET Output */ + unsigned int set_offset : 30; /* [29..0] */ + // Comment of field: reserved_0 + /* Reserved */ + unsigned int reserved_0 : 2; /* [31..30] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} u_aphy_ssc_status1; +/* Define the union u_aphy_ssc_status2 */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: tbladdr + /* SSC Lookup Table Address */ + unsigned int tbladdr : 8; /* [7..0] */ + // Comment of field: fb_div_ssc + /* Connected to APHY RG_TXPLL_DIV_SSC<10 : 0> */ + unsigned int fb_div_ssc : 11; /* [18..8] */ + // Comment of field: reserved_0 + /* Reserved */ + unsigned int reserved_0 : 13; /* [31..19] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} u_aphy_ssc_status2; +/* Define the union u_aphy_ssc_status3 */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: ssc_off + /* Whether the SSC has stopped spreading */ + unsigned int ssc_off : 1; /* [0] */ + // Comment of field: segment + /* SSC Spread Range */ + unsigned int segment : 1; /* [1] */ + // Comment of field: stop_flag + /* Whether the SSC has stopped spreading */ + unsigned int stop_flag : 1; /* [2] */ + // Comment of field: reverse_flag + /* SSC reverse signal */ + unsigned int reverse_flag : 1; /* [3] */ + // Comment of field: reserved_0 + /* Reserved */ + unsigned int reserved_0 : 12; /* [15..4] */ + // Comment of field: span_cnt + /* SSC inverted value */ + unsigned int span_cnt : 12; /* [27..16] */ + // Comment of field: reserved_1 + /* Reserved */ + unsigned int reserved_1 : 4; /* [31..28] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} u_aphy_ssc_status3; +/* Define the union u_aphy_ssc_fb_div_cfg */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: cfg_fb_div_ssc_value + /* Software configuration value of fb_div_ssc */ + unsigned int cfg_fb_div_ssc_value : 11; /* [10..0] */ + // Comment of field: reserved_0 + /* Reserved */ + unsigned int reserved_0 : 5; /* [15..11] */ + // Comment of field: cfg_fb_div_ssc_ovr + /* fb_div_ssc software configuration enable 0 : disabled 1 : enabled */ + unsigned int cfg_fb_div_ssc_ovr : 1; /* [16] */ + // Comment of field: reserved_1 + /* Reserved */ + unsigned int reserved_1 : 15; /* [31..17] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} u_aphy_ssc_fb_div_cfg; +/* Define the union u_pll_lock0 */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: reg_fb_prd_sel + /* The pll feedback clock has a period selection.Cycle configuration of the crystal oscillator to be + detected 3'b00 : 2 ^ + 4 / clk_xtal; + 3'b01 : 2 ^ 5 / clk_xtal; + 3'b10 : 2 ^ 6 / clk_xtal; + 3'b11 : 2 ^ 7 / clk_xtal.others : 2 ^ 8 / clk_xtal */ + unsigned int reg_fb_prd_sel : 3; /* [2..0] */ + // Comment of field: reserved_0 + /* Reserved */ + unsigned int reserved_0 : 1; /* [3] */ + // Comment of field: reg_fb_div_sel + /* PLL feedback clock frequency division select.Frequency division configuration of the clock to be + detected 2'b00 : div 8; + 2'b01 : div 16; + 2'b10 : div 32; + 2'b11 : div 64. others : div 128. */ + unsigned int reg_fb_div_sel : 3; /* [6..4] */ + // Comment of field: reserved_1 + /* Reserved */ + unsigned int reserved_1 : 1; /* [7] */ + // Comment of field: reg_ref_unlock_timer + /* PLL reference clock out - of - lock timing period; + 1 indicates 2 ^ 4 clk_ref clocks. */ + unsigned int reg_ref_unlock_timer : 8; /* [15..8] */ + // Comment of field: reg_ref_lock_timer + /* PLL reference clock lock timing period; + 1 indicates 2 ^ 8 clk_ref clocks. */ + unsigned int reg_ref_lock_timer : 8; /* [23..16] */ + // Comment of field: reserved_2 + /* Reserved */ + unsigned int reserved_2 : 8; /* [31..24] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} u_pll_lock0; +/* Define the union u_pll_lock1 */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: reg_pll_lock_sel + /* PLL feedback clock lock select .2'b00 : 1 / 10000 jitter; + 2'b01 : 5 / 10000 jitter; + 2'b10 : 1 / 1000 jitter; + 2'b11 : 1 / 100 jitter. */ + unsigned int reg_pll_lock_sel : 2; /* [1..0] */ + // Comment of field: reg_pll_lock_times + /* PLL feedback clock lock period .1'b0 : 1 time; + 1'b1 : 2 times */ + unsigned int reg_pll_lock_times : 1; /* [2] */ + // Comment of field: reg_pll_unlock_sel + /* PLL feedback clock out - of - lock select .0 : 10 % jitter; + 1 : 20 % jitter. */ + unsigned int reg_pll_unlock_sel : 1; /* [3] */ + // Comment of field: reg_pll_lockext_sel + /* Number of waiting crystal oscillator cycles after extend pll lock.pll lock 0xx : no extend; + 100 : 2 ^ 5 extend; + 101 : 2 ^ 6 extend; + 110 : 2 ^ 7 extend; + 111 : 2 ^ 8 extend. */ + unsigned int reg_pll_lockext_sel : 3; /* [6..4] */ + // Comment of field: reserved_0 + /* Reserved */ + unsigned int reserved_0 : 25; /* [31..7] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} u_pll_lock1; +/* Define the union u_pll_lock2 */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: mipi_clk_lock + /* pll lock 0 : pll unlock 1 : pll lock */ + unsigned int mipi_clk_lock : 1; /* [0] */ + // Comment of field: clk_fb_exist + /* fb clock exist 0 : clk_fb does not exist .1 : clk_fb exists. */ + unsigned int clk_fb_exist : 1; /* [1] */ + unsigned int reserved_0 : 6; /* [7..2] */ + // Comment of field: pll_cnt + /* pll counter */ + unsigned int pll_cnt : 17; /* [24..8] */ + // Comment of field: reserved_1 + /* Reserved */ + unsigned int reserved_1 : 7; /* [31..25] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} u_pll_lock2; +/* Define the union u_aphy_gpio_sel */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: cfg_gpio_sel + /* GPIO signal selection configuration */ + unsigned int cfg_gpio_sel : 5; /* [4..0] */ + // Comment of field: reserved_0 + /* Reserved */ + unsigned int reserved_0 : 27; /* [31..5] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} u_aphy_gpio_sel; +/* Define the union u_phy_config0 */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: phy_testclr + /* + CDPHY test interface clear + It is used when active performs vendor specific interface initialization + (Active High). + */ + unsigned int phy_testclr : 1; /* [0] */ + // Comment of field: phy_testclk + /* + CDPHY test interface strobe signal + It is used to clock TESTDIN bus into the D-PHY. In conjunction with + TESTEN signal controls the operation selection. + */ + unsigned int phy_testclk : 1; /* [1] */ + unsigned int reserved_0 : 30; /* [31..2] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} u_phy_config0; +/* Define the union u_phy_config1 */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: phy_testdin + /* + CDPHY test interface input 8-bit data bus for internal register + programming and test functionalities access. + */ + unsigned int phy_testdin : 8; /* [7..0] */ + // Comment of field: phy_testdout + /* + CDPHY output 8-bit data bus for read-back and internal probing + functionalities. + */ + unsigned int phy_testdout : 8; /* [15..8] */ + // Comment of field: phy_testen + /* + CDPHY test interface operation selector: + - 1: Configures address write operation on the falling edge of + TESTCLK + - 0: Configures a data write operation on the rising edge of TESTCLK. + */ + unsigned int phy_testen : 1; /* [16] */ + // Comment of field: reserved_0 + /* Reserved */ + unsigned int reserved_0 : 15; /* [31..17] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} u_phy_config1; +/* Define the union u_freq_det_hw_0 */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: cfg_freq_det_clr + /* Clears the maximum and minimum detected values .0 : not cleared 1 : cleared */ + unsigned int cfg_freq_det_clr : 1; /* [0] */ + // Comment of field: reserved_0 + /* Reserved */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} u_freq_det_hw_0; +/* Define the union u_freq_det_hw_1 */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: freq_det_hw + /* Detected real - time frequency, in 10 kHz. */ + unsigned int freq_det_hw : 20; /* [19..0] */ + // Comment of field: reserved_0 + /* Reserved */ + unsigned int reserved_0 : 12; /* [31..20] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} u_freq_det_hw_1; +/* Define the union u_freq_det_hw_2 */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: freq_det_hw_max + /* Maximum detected frequency, in 10 kHz. */ + unsigned int freq_det_hw_max : 20; /* [19..0] */ + // Comment of field: reserved_0 + /* Reserved */ + unsigned int reserved_0 : 12; /* [31..20] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} u_freq_det_hw_2; +/* Define the union u_freq_det_hw_3 */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: freq_det_hw_min + /* Indicates the minimum frequency detected.The unit is 10 kHz. */ + unsigned int freq_det_hw_min : 20; /* [19..0] */ + // Comment of field: reserved_0 + /* Reserved */ + unsigned int reserved_0 : 12; /* [31..20] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} u_freq_det_hw_3; +/* Define the union u_lp_bist_err_cnt0 */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: comp_lp_err_cnt_l0 + /* LP bsit error statistics of channel 0 */ + unsigned int comp_lp_err_cnt_l0 : 16; /* [15..0] */ + // Comment of field: comp_lp_err_cnt_l1 + /* Channel 1 LP bsit error statistics */ + unsigned int comp_lp_err_cnt_l1 : 16; /* [31..16] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} u_lp_bist_err_cnt0; +/* Define the union u_lp_bist_err_cnt1 */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: comp_lp_err_cnt_l2 + /* Channel 2 LP bsit error statistics */ + unsigned int comp_lp_err_cnt_l2 : 16; /* [15..0] */ + // Comment of field: comp_lp_err_cnt_l3 + /* Channel 3 LP bsit error statistics */ + unsigned int comp_lp_err_cnt_l3 : 16; /* [31..16] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} u_lp_bist_err_cnt1; +/* Define the union u_common_reg_00 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_burst_ena : 1; /* [0] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 3; /* [3..1] */ + unsigned int reg_preamble_len_bit7to6 : 2; /* [5..4] */ + // Comment of field: reserved_1 + /* + reserved + */ + unsigned int reserved_1 : 2; /* [7..6] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_00; +/* Define the union u_common_reg_01 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_preamble_len_bit5to0 : 6; /* [5..0] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 1; /* [6] */ + unsigned int reg_preamble_ena : 1; /* [7] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_01; +/* Define the union u_common_reg_02 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_post_len : 6; /* [5..0] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 2; /* [7..6] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_02; +/* Define the union u_common_reg_03 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_preamble_0_bit5to0 : 6; /* [5..0] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 2; /* [7..6] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_03; +/* Define the union u_common_reg_04 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_preamble_0_bit11to6 : 6; /* [5..0] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 2; /* [7..6] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_04; +/* Define the union u_common_reg_05 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_preamble_0_bit117to12 : 6; /* [5..0] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 2; /* [7..6] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_05; +/* Define the union u_common_reg_06 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_preamble_0_bit20to18 : 3; /* [2..0] */ + unsigned int reg_preamble_1_bit2to0 : 3; /* [5..3] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 2; /* [7..6] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_06; +/* Define the union u_common_reg_07 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_preamble_1_bit8to3 : 6; /* [5..0] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 2; /* [7..6] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_07; +/* Define the union u_common_reg_08 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_preamble_1_bit14to9 : 6; /* [5..0] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 2; /* [7..6] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_08; +/* Define the union u_common_reg_09 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_preamble_1_bit20to15 : 6; /* [5..0] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 2; /* [7..6] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_09; +/* Define the union u_common_reg_0d */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_cphy_calb : 2; /* [1..0] */ + unsigned int reserved_0 : 2; /* [3..2] */ + unsigned int reg_tcalaltseq_bit10to8 : 3; /* [6..4] */ + // Comment of field: reserved_1 + /* Reserved */ + unsigned int reserved_1 : 1; /* [7] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_0d; +/* Define the union u_common_reg_0e */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_tcalaltseq_bit7to0 : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_0e; +/* Define the union u_common_reg_10 */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: reg_tm_pll_200us + /* Counter, 200 us(not used in the current version) */ + unsigned int reg_tm_pll_200us : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_10; +/* Define the union u_common_reg_11 */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: reg_tm_pll_1us + /* Counter, timing 1 us */ + unsigned int reg_tm_pll_1us : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_11; +/* Define the union u_common_reg_12 */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: reg_tm_pll_5us + /* Counter, timing 5us */ + unsigned int reg_tm_pll_5us : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_12; +/* Define the union u_common_reg_13 */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: reg_lock_time_bit7to0 + /* pll_lock counter */ + unsigned int reg_lock_time_bit7to0 : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_13; +/* Define the union u_common_reg_14 */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: reg_lock_time_bit11to8 + /* pll_lock counter */ + unsigned int reg_lock_time_bit11to8 : 4; /* [3..0] */ + // Comment of field: reg_div_sel + /* cfg_clk frequency division coefficient selection; + The frequency division coefficient is an exponential multiple of 2 of the configured value. */ + unsigned int reg_div_sel : 3; /* [6..4] */ + // Comment of field: reg_fdec_enb + /* Clock frequency ratio detection enable after frequency division between + lanebyteclk and cfg_clk.The detection is enabled when the value 0 is configured. */ + unsigned int reg_fdec_enb : 1; /* [7] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_14; +/* Define the union u_common_reg_15 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ad_pll_band : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_15; +/* Define the union u_common_reg_16 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ad_pll_band_bit8 : 1; /* [0] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 3; /* [3..1] */ + unsigned int ad_ssc_div_mode_dbgo_bit3to0 : 4; /* [7..4] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_16; +/* Define the union u_common_reg_17 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ad_ssc_div_mode_dbgo_bit11to4 : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_17; +/* Define the union u_common_reg_18 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ad_ssc_div_mode_dbgo_bit16to12 : 5; /* [4..0] */ + // Comment of field: reserved_0 + /* Reserved */ + unsigned int reserved_0 : 3; /* [7..5] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_18; +/* Define the union u_common_reg_19 */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: det_value + /* Frequency ratio of lanebyteclk to cfg_clk after frequency division */ + unsigned int det_value : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_19; +/* Define the union u_common_reg_1a */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int afe_monitor_bit7to0 : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_1a; +/* Define the union u_common_reg_1b */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int afe_monitor_bit15to8 : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_1b; +/* Define the union u_common_reg_1c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int afe_monitor_bit23to16 : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_1c; +/* Define the union u_common_reg_1d */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int afe_monitor_bit31to24 : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_1d; +/* Define the union u_common_reg_1e */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: lanebyteclk + /* Clock monitor */ + unsigned int lanebyteclk : 1; /* [0] */ + // Comment of field: reserved_0 + /* Reserved */ + unsigned int reserved_0 : 1; /* [1] */ + // Comment of field: txclkesc + /* Clock monitor */ + unsigned int txclkesc : 1; /* [2] */ + // Comment of field: reserved_1 + /* Reserved */ + unsigned int reserved_1 : 5; /* [7..3] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_1e; +/* Define the union u_common_reg_20 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_ate_bist_en : 1; /* [0] */ + // Comment of field: reserved_0 + /* Reserved */ + unsigned int reserved_0 : 7; /* [7..1] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_20; +/* Define the union u_common_reg_21 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_hsbist_en : 1; /* [0] */ + unsigned int reg_hscalib_en : 1; /* [1] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 2; /* [3..2] */ + unsigned int reg_lpbist_en : 1; /* [4] */ + // Comment of field: reserved_1 + /* + reserved + */ + unsigned int reserved_1 : 3; /* [7..5] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_21; +/* Define the union u_common_reg_22 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_bist_alive : 1; /* [0] */ + unsigned int reserved_0 : 3; /* [3..1] */ + unsigned int reg_bist_sel : 2; /* [5..4] */ + // Comment of field: reserved_1 + /* + reserved + */ + unsigned int reserved_1 : 2; /* [7..6] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_22; +/* Define the union u_common_reg_23 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_bist_seed_bit7to0 : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_23; +/* Define the union u_common_reg_24 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_bist_seed_bit15to8 : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_24; +/* Define the union u_common_reg_25 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_bist_data_bit7to0 : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_25; +/* Define the union u_common_reg_26 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_bist_data_bit15to8 : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_26; +/* Define the union u_common_reg_27 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_bist_round_bit7to0 : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_27; +/* Define the union u_common_reg_28 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_sync_insert : 1; /* [0] */ + unsigned int reg_sync_type : 3; /* [3..1] */ + unsigned int reg_sync_intv_bit11to8 : 4; /* [7..4] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_28; +/* Define the union u_common_reg_29 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_sync_intv_bit7to0 : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_29; +/* Define the union u_common_reg_2a */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_pwr_val_bit7to0 : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_2a; +/* Define the union u_common_reg_2b */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_pwr_val_bit9to8 : 2; /* [1..0] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 6; /* [7..2] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_2b; +/* Define the union u_common_reg_2c */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: reg_pwr_txclkesc + /* When pwr_dwn_req is enabled, txclkesc is output. */ + unsigned int reg_pwr_txclkesc : 1; /* [0] */ + // Comment of field: reg_pwr_refclk + /* When pwr_dwn_req is enabled, refclk is output. */ + unsigned int reg_pwr_refclk : 1; /* [1] */ + // Comment of field: reg_pwr_cfgclk + /* When pwr_dwn_req is enabled, cfgclk is output. */ + unsigned int reg_pwr_cfgclk : 1; /* [2] */ + // Comment of field: reg_pwr_testen + /* Output testen when pwr_dwn_req is enabled. */ + unsigned int reg_pwr_testen : 1; /* [3] */ + // Comment of field: reg_pwr_forcepll + /* When pwr_dwn_req is enabled, forcepll is output. */ + unsigned int reg_pwr_forcepll : 1; /* [4] */ + // Comment of field: reg_pwr_cfg_cdphy + /* When pwr_dwn_req is enabled, + the cdphy value is output.The default value is dphy. */ + unsigned int reg_pwr_cfg_cdphy : 1; /* [5] */ + // Comment of field: reserved_0 + /* Reserved */ + unsigned int reserved_0 : 2; /* [7..6] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_2c; +/* Define the union u_common_reg_2d */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_gbl_lane : 5; /* [4..0] */ + // Comment of field: reserved_0 + /* Reserved */ + unsigned int reserved_0 : 3; /* [7..5] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_2d; +/* Define the union u_common_reg_2e */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: reg_config + /* + Overwrite enable for the cdphy and lane modes + */ + unsigned int reg_config : 1; /* [0] */ + // Comment of field: reg_cfg_cdphy + /* cdphy overwtite value.The default value is dphy. */ + unsigned int reg_cfg_cdphy : 1; /* [1] */ + // Comment of field: reg_cfg_dphylane + /* Overwtite value of lane count */ + unsigned int reg_cfg_dphylane : 5; /* [6..2] */ + unsigned int reg_cal_policy : 1; /* [7] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_2e; +/* Define the union u_common_reg_2f */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_test_lane : 4; /* [3..0] */ + // Comment of field: reserved_0 + /* Reserved */ + unsigned int reserved_0 : 4; /* [7..4] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_2f; +/* Define the union u_common_reg_30 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_test_mode_bit7to0 : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_30; +/* Define the union u_common_reg_31 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_test_mode_bit15to8 : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_31; +/* Define the union u_common_reg_32 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_test_mode_bit18to16 : 3; /* [2..0] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 5; /* [7..3] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_32; +/* Define the union u_common_reg_33 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_t_da_cphy_a1 : 7; /* [6..0] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 1; /* [7] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_33; +/* Define the union u_common_reg_34 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_t_da_cphy_a2 : 7; /* [6..0] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 1; /* [7] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_34; +/* Define the union u_common_reg_35 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_t_da_cphy_b1 : 7; /* [6..0] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 1; /* [7] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_35; +/* Define the union u_common_reg_36 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_t_da_cphy_b2 : 7; /* [6..0] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 1; /* [7] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_36; +/* Define the union u_common_reg_37 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_t_da_cphy_c1 : 7; /* [6..0] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 1; /* [7] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_37; +/* Define the union u_common_reg_38 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_t_da_cphy_c2 : 7; /* [6..0] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 1; /* [7] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_38; +/* Define the union u_common_reg_39 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_t_da_hstx_data : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_39; +/* Define the union u_common_reg_3a */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_t_da_hstx_data_clk : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_3a; +/* Define the union u_common_reg_3b */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_t_da_lprxcd_en : 1; /* [0] */ + unsigned int reg_t_da_lptx_dp : 1; /* [1] */ + unsigned int reg_t_da_lptx_dn : 1; /* [2] */ + unsigned int reg_t_da_lptx_en : 1; /* [3] */ + unsigned int reg_t_da_lptx_enbias : 1; /* [4] */ + unsigned int reg_t_da_lptx_enb_ulps : 1; /* [5] */ + unsigned int reg_t_da_hstx_swten : 1; /* [6] */ + unsigned int reg_t_rg_hsclk_en : 1; /* [7] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_3b; +/* Define the union u_common_reg_3c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_t_rg_pll_bias_en : 1; /* [0] */ + unsigned int reg_t_rg_pll_en : 1; /* [1] */ + unsigned int reg_t_rg_ssc_resetj : 1; /* [2] */ + unsigned int reg_t_rg_ssc_resetn : 1; /* [3] */ + unsigned int reg_t_rg_ssc_resetsj : 1; /* [4] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 3; /* [7..5] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_3c; +/* Define the union u_common_reg_3d */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_t_rg_lptx_bias_en : 1; /* [0] */ + unsigned int reg_t_rg_refen : 1; /* [1] */ + unsigned int reg_t_rg_vcm_en : 1; /* [2] */ + unsigned int reg_t_rg_hstx_bias_en : 1; /* [3] */ + unsigned int reg_t_rg_pll_ser_ck_en : 1; /* [4] */ + unsigned int reg_t_rg_ch_en : 1; /* [5] */ + unsigned int reg_t_rg_ch_en_eq : 1; /* [6] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 1; /* [7] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_3d; +/* Define the union u_common_reg_3f */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_bist_round_bit15to8 : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_3f; +/* Define the union u_common_reg_40 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_ssc_r_prbs1_en : 1; /* [0] */ + unsigned int reg_ssc_r_prbs2_en : 1; /* [1] */ + unsigned int reg_ssc_r_prbs3_en : 1; /* [2] */ + unsigned int reg_ssc_r_fracssc_en : 1; /* [3] */ + unsigned int reg_ssc_r_frac_en : 1; /* [4] */ + unsigned int reg_ssc_r_sscdiv_en : 1; /* [5] */ + unsigned int reg_ssc_r_sdmtype : 1; /* [6] */ + unsigned int reg_ssc_r_spread_en : 1; /* [7] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_40; +/* Define the union u_common_reg_41 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_ssc_r_div_frac : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_41; +/* Define the union u_common_reg_42 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_ssc_r_triinc : 7; /* [6..0] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 1; /* [7] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_42; +/* Define the union u_common_reg_43 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_ssc_r_sscdivnum : 4; /* [3..0] */ + unsigned int reg_ssc_r_triangular_sel : 1; /* [4] */ + unsigned int reg_ssc_r_ups_en : 1; /* [5] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 2; /* [7..6] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_43; +/* Define the union u_common_reg_44 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_ssc_r_spreadmax : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_44; +/* Define the union u_common_reg_45 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_pll_load_band_en : 1; /* [0] */ + unsigned int reg_pll_lat_en : 1; /* [1] */ + unsigned int reg_pll_lat_enb : 1; /* [2] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 1; /* [3] */ + unsigned int reg_pll_lpf_r : 2; /* [5..4] */ + // Comment of field: reserved_1 + /* Reserved */ + unsigned int reserved_1 : 1; /* [6] */ + unsigned int reg_pll_band_bit8 : 1; /* [7] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_45; +/* Define the union u_common_reg_46 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_pll_band_bit7to0 : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_46; +/* Define the union u_common_reg_48 */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: reg_pll_phy_posdiv + /* PHY PLL POSDIV Parameter Configuration */ + unsigned int reg_pll_phy_posdiv : 3; /* [2..0] */ + // Comment of field: reserved_0 + /* Reserved */ + unsigned int reserved_0 : 5; /* [7..3] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_48; +/* Define the union u_common_reg_49 */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: reg_pll_phy_div_int_bit10to8 + /* PHY PLL DIV_INT [10:8] parameter configuration */ + unsigned int reg_pll_phy_div_int_bit10to8 : 3; /* [2..0] */ + // Comment of field: reserved_0 + /* Reserved */ + unsigned int reserved_0 : 1; /* [3] */ + // Comment of field: reg_pll_phy_prediv + /* PHY PLL PREDIV Parameter Configuration */ + unsigned int reg_pll_phy_prediv : 3; /* [6..4] */ + // Comment of field: reserved_1 + /* Reserved */ + unsigned int reserved_1 : 1; /* [7] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_49; +/* Define the union u_common_reg_4a */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: reg_pll_phy_div_int_bit7to0 + /* PHY PLL POSDIV Parameter Configuration */ + unsigned int reg_pll_phy_div_int_bit7to0 : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_4a; +/* Define the union u_common_reg_4b */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: reg_pll_phy_div_update + /* PHY parameter configuration update register */ + unsigned int reg_pll_phy_div_update : 1; /* [0] */ + // Comment of field: reserved_0 + /* Reserved */ + unsigned int reserved_0 : 7; /* [7..1] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_4b; +/* Define the union u_common_reg_50 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_hstx_ser_ckneg : 1; /* [0] */ + unsigned int reg_vcm_meth : 2; /* [2..1] */ + unsigned int reg_vcmsel : 5; /* [7..3] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_50; +/* Define the union u_common_reg_51 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_dphy_emi_mode : 1; /* [0] */ + unsigned int reg_encs : 1; /* [1] */ + unsigned int reg_en_bw : 2; /* [3..2] */ + unsigned int reg_lprxcd_selenfor : 1; /* [4] */ + unsigned int reg_lprxcd_selforhi : 1; /* [5] */ + unsigned int reg_lptx_selenfor : 1; /* [6] */ + unsigned int reg_lptx_selforhi : 1; /* [7] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_51; +/* Define the union u_common_reg_52 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_lptx_sri_dn : 4; /* [3..0] */ + unsigned int reg_lptx_sri_pu : 4; /* [7..4] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_52; +/* Define the union u_common_reg_53 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_cphy_deemp_mode : 1; /* [0] */ + unsigned int reg_cphy_t1mode_en : 1; /* [1] */ + unsigned int reg_en_v1d2 : 1; /* [2] */ + unsigned int reg_ser_psave : 1; /* [3] */ + unsigned int reg_lprxcd_en_bit9to8 : 2; /* [5..4] */ + unsigned int reg_ch_en_eq_bit9to8 : 2; /* [7..6] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_53; +/* Define the union u_common_reg_54 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_lprxcd_en_bit7to0 : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_54; +/* Define the union u_common_reg_55 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_ch_en_eq_bit7to0 : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_55; +/* Define the union u_common_reg_56 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_dphy_drv_en : 6; /* [5..0] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 2; /* [7..6] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_56; +/* Define the union u_common_reg_57 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_cphy_dedrv_en : 5; /* [4..0] */ + unsigned int reg_cphy_predrv_en : 3; /* [7..5] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_57; +/* Define the union u_common_reg_58 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_eq_sel_even_bit9to8 : 2; /* [1..0] */ + unsigned int reg_eq_sel_odd_bit9to8 : 2; /* [3..2] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 4; /* [7..4] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_58; +/* Define the union u_common_reg_59 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_eq_sel_even_bit7to0 : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_59; +/* Define the union u_common_reg_5a */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_eq_sel_odd_bit7to0 : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_5a; +/* Define the union u_common_reg_5e */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_top_dmy_bit7to0 : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_5e; +/* Define the union u_common_reg_5f */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_top_dmy_bit15to8 : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_common_reg_5f; +/* Define the union u_lane_reg_01 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_dbug_pat : 4; /* [3..0] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 1; /* [4] */ + unsigned int reg_prbs_pat : 3; /* [7..5] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_lane_reg_01; +/* Define the union u_lane_reg_02 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_prbs_seed0 : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_lane_reg_02; +/* Define the union u_lane_reg_03 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_prbs_seed1 : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_lane_reg_03; +/* Define the union u_lane_reg_04 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_prbs_seed2 : 2; /* [1..0] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 6; /* [7..2] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_lane_reg_04; +/* Define the union u_lane_reg_05 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_comp_round_bit7to0 : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_lane_reg_05; +/* Define the union u_lane_reg_06 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_wire_swap : 1; /* [0] */ + unsigned int reg_lp_cmd : 1; /* [1] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 2; /* [3..2] */ + unsigned int reg_tri_type : 1; /* [4] */ + unsigned int reg_sdw_enb : 1; /* [5] */ + // Comment of field: reserved_1 + /* + reserved + */ + unsigned int reserved_1 : 2; /* [7..6] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_lane_reg_06; +/* Define the union u_lane_reg_07 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_comp_round_bit15to8 : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_lane_reg_07; +/* Define the union u_lane_reg_08 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ctrl_lp_monitor_bit7to0 : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_lane_reg_08; +/* Define the union u_lane_reg_09 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ctrl_lp_monitor_bit15to8 : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_lane_reg_09; +/* Define the union u_lane_reg_0a */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int lp_rev_state : 4; /* [3..0] */ + unsigned int hs_fsm_state : 4; /* [7..4] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_lane_reg_0a; +/* Define the union u_lane_reg_0b */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int lp_fwd_state : 7; /* [6..0] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 1; /* [7] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_lane_reg_0b; +/* Define the union u_lane_reg_0c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int comp_lp_ok : 1; /* [0] */ + unsigned int comp_lp_done : 1; /* [1] */ + unsigned int det_lp_fail : 1; /* [2] */ + unsigned int det_lp_on_comp : 1; /* [3] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 4; /* [7..4] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_lane_reg_0c; +/* Define the union u_lane_reg_0d */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ctrl_monitor_bit7to0 : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_lane_reg_0d; +/* Define the union u_lane_reg_0e */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ctrl_monitor_bit15to8 : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_lane_reg_0e; +/* Define the union u_lane_reg_0f */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int ctrl_monitor_bit21to16 : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_lane_reg_0f; +/* Define the union u_lane_reg_10 */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: reg_pre_req_dy + /* The clock lane enters from txrequesthsclk.Indicates the delay time of the HS mode.The unit is hsclk period. + */ + unsigned int reg_pre_req_dy : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_lane_reg_10; +/* Define the union u_lane_reg_11 */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: reg_pos_req_dy + /* The clock lane exits from txrequesthsclk.Indicates the delay time in HS mode.The unit is hsclk cycle. */ + unsigned int reg_pos_req_dy : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_lane_reg_11; +/* Define the union u_lane_reg_12 */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: reg_tlpx + /* Lane TLPX time, in hsclk period. */ + unsigned int reg_tlpx : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_lane_reg_12; +/* Define the union u_lane_reg_13 */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: reg_tprepare + /* Lane Tprepare time, in hsclk period. */ + unsigned int reg_tprepare : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_lane_reg_13; +/* Define the union u_lane_reg_14 */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: reg_tzero + /* Lane Tzero time, in hsclk cycle. */ + unsigned int reg_tzero : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_lane_reg_14; +/* Define the union u_lane_reg_15 */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: reg_thstrail + /* Lane Ths_trail time, in hsclk period. */ + unsigned int reg_thstrail : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_lane_reg_15; +/* Define the union u_lane_reg_16 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_clock_val : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_lane_reg_16; +/* Define the union u_lane_reg_17 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_symb_init : 3; /* [2..0] */ + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 1; /* [3] */ + unsigned int reg_lpx_or : 2; /* [5..4] */ + unsigned int reg_eot_end_off : 1; /* [6] */ + unsigned int reg_force_eot : 1; /* [7] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_lane_reg_17; +/* Define the union u_lane_reg_18 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_prepr_offset : 8; /* [7..0] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_lane_reg_18; +/* Define the union u_lane_reg_19 */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_bias_and : 2; /* [1..0] */ + unsigned int reg_bias_or : 2; /* [3..2] */ + unsigned int reg_vcm_and : 2; /* [5..4] */ + unsigned int reg_vcm_or : 2; /* [7..6] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_lane_reg_19; +/* Define the union u_lane_reg_1a */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_drv_and : 2; /* [1..0] */ + unsigned int reg_drv_or : 2; /* [3..2] */ + unsigned int reg_drv2_and : 2; /* [5..4] */ + unsigned int reg_drv2_or : 2; /* [7..6] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_lane_reg_1a; +/* Define the union u_lane_reg_1b */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: reserved_0 + /* + reserved + */ + unsigned int reserved_0 : 1; /* [0] */ + unsigned int reg_drv_ext_on : 1; /* [1] */ + unsigned int reg_lpx_and : 2; /* [3..2] */ + // Comment of field: reserved_1 + /* + reserved + */ + unsigned int reserved_1 : 4; /* [7..4] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_lane_reg_1b; +/* Define the union u_lane_reg_1c */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_clkesc_inv : 1; /* [0] */ + unsigned int reg_errcd_sel : 1; /* [1] */ + unsigned int reg_rx_dly_sel : 1; /* [2] */ + // Comment of field: reserved_0 + /* Reserved */ + unsigned int reserved_0 : 1; /* [3] */ + unsigned int reg_ulps_dly : 3; /* [6..4] */ + // Comment of field: reserved_1 + /* Reserved */ + unsigned int reserved_1 : 1; /* [7] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_lane_reg_1c; +/* Define the union u_lane_reg_1d */ +typedef union { + /* Define the struct bits */ + struct { + // Comment of field: reg_ttago + /* Lane Tta_go time, in txclkesc period. */ + unsigned int reg_ttago : 4; /* [3..0] */ + // Comment of field: reg_ttaget + /* Lane Tta_get time, in txclkesc period. */ + unsigned int reg_ttaget : 4; /* [7..4] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_lane_reg_1d; +/* Define the union u_lane_reg_1e */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int reg_comp_clr : 1; /* [0] */ + unsigned int reg_comp_round_end : 1; /* [1] */ + unsigned int reserved_0 : 6; /* [7..2] */ + } bits; + /* Define an unsigned member */ + unsigned int u32 : 8; +} u_lane_reg_1e; +// ============================================================================== +/* Define the global struct */ +typedef struct { + u_pll_status pll_status; /* 0x0 */ + u_aphy_txpll_test aphy_txpll_test; /* 0x4 */ + u_aphy_txpll_inctrl aphy_txpll_inctrl; /* 0x8 */ + u_aphy_test_atop_0 aphy_test_atop_0; /* 0xc */ + u_aphy_test_atop_1 aphy_test_atop_1; /* 0x10 */ + u_aphy_sel_ldo_cfg aphy_sel_ldo_cfg; /* 0x14 */ + u_aphy_enable_cfg aphy_enable_cfg; /* 0x18 */ + u_aphy_bg_cfg aphy_bg_cfg; /* 0x1c */ + u_aphy_pll_div_cfg aphy_pll_div_cfg; /* 0x20 */ + u_aphy_self_bist_rsl aphy_self_bist_rsl; /* 0x24 */ + u_aphy_self_bist_cfg aphy_self_bist_cfg; /* 0x28 */ + unsigned int reserved_18[7]; /* 0x2c~0x44 */ + u_aphy_ssc_set aphy_ssc_set; /* 0x48 */ + u_aphy_ssc_ctrl0 aphy_ssc_ctrl0; /* 0x4c */ + u_aphy_ssc_ctrl1 aphy_ssc_ctrl1; /* 0x50 */ + u_aphy_ssc_ctrl2 aphy_ssc_ctrl2; /* 0x54 */ + u_aphy_ssc_ctrl3 aphy_ssc_ctrl3; /* 0x58 */ + u_aphy_ssc_status0 aphy_ssc_status0; /* 0x5c */ + u_aphy_ssc_status1 aphy_ssc_status1; /* 0x60 */ + u_aphy_ssc_status2 aphy_ssc_status2; /* 0x64 */ + u_aphy_ssc_status3 aphy_ssc_status3; /* 0x68 */ + u_aphy_ssc_fb_div_cfg aphy_ssc_fb_div_cfg; /* 0x6c */ + unsigned int reserved_19[11]; /* 0x70~0x98 */ + u_pll_lock0 pll_lock0; /* 0x9c */ + u_pll_lock1 pll_lock1; /* 0xa0 */ + u_pll_lock2 pll_lock2; /* 0xa4 */ + u_aphy_gpio_sel aphy_gpio_sel; /* 0xa8 */ + unsigned int reserved_20[85]; /* 0xac~0x1fc */ + u_phy_config0 phy_config0; /* 0x200 */ + u_phy_config1 phy_config1; /* 0x204 */ + u_freq_det_hw_0 freq_det_hw_0; /* 0x208 */ + u_freq_det_hw_1 freq_det_hw_1; /* 0x20c */ + u_freq_det_hw_2 freq_det_hw_2; /* 0x210 */ + u_freq_det_hw_3 freq_det_hw_3; /* 0x214 */ + unsigned int reserved_21[6]; /* 0x218~0x22c */ + u_lp_bist_err_cnt0 lp_bist_err_cnt0; /* 0x230 */ + u_lp_bist_err_cnt1 lp_bist_err_cnt1; /* 0x234 */ + unsigned int reserved_22[626]; /* 0x238~0xbff */ + u_common_reg_00 common_reg_00; /* 0xc00 */ + u_common_reg_01 common_reg_01; /* 0xc04 */ + u_common_reg_02 common_reg_02; /* 0xc08 */ + u_common_reg_03 common_reg_03; /* 0xc0c */ + u_common_reg_04 common_reg_04; /* 0xc10 */ + u_common_reg_05 common_reg_05; /* 0xc14 */ + u_common_reg_06 common_reg_06; /* 0xc18 */ + u_common_reg_07 common_reg_07; /* 0xc1c */ + u_common_reg_08 common_reg_08; /* 0xc20 */ + u_common_reg_09 common_reg_09; /* 0xc24 */ + unsigned int reserved_32[3]; /* 0xc28~0xc30 */ + u_common_reg_0d common_reg_0d; /* 0xc34 */ + u_common_reg_0e common_reg_0e; /* 0xc38 */ + unsigned int reserved_34; /* 0xc3c */ + u_common_reg_10 common_reg_10; /* 0xc40 */ + u_common_reg_11 common_reg_11; /* 0xc44 */ + u_common_reg_12 common_reg_12; /* 0xc48 */ + u_common_reg_13 common_reg_13; /* 0xc4c */ + u_common_reg_14 common_reg_14; /* 0xc50 */ + u_common_reg_15 common_reg_15; /* 0xc54 */ + u_common_reg_16 common_reg_16; /* 0xc58 */ + u_common_reg_17 common_reg_17; /* 0xc5c */ + u_common_reg_18 common_reg_18; /* 0xc60 */ + u_common_reg_19 common_reg_19; /* 0xc64 */ + u_common_reg_1a common_reg_1a; /* 0xc68 */ + u_common_reg_1b common_reg_1b; /* 0xc6c */ + u_common_reg_1c common_reg_1c; /* 0xc70 */ + u_common_reg_1d common_reg_1d; /* 0xc74 */ + u_common_reg_1e common_reg_1e; /* 0xc78 */ + unsigned int reserved_49; /* 0xc7c */ + u_common_reg_20 common_reg_20; /* 0xc80 */ + u_common_reg_21 common_reg_21; /* 0xc84 */ + u_common_reg_22 common_reg_22; /* 0xc88 */ + u_common_reg_23 common_reg_23; /* 0xc8c */ + u_common_reg_24 common_reg_24; /* 0xc90 */ + u_common_reg_25 common_reg_25; /* 0xc94 */ + u_common_reg_26 common_reg_26; /* 0xc98 */ + u_common_reg_27 common_reg_27; /* 0xc9c */ + u_common_reg_28 common_reg_28; /* 0xca0 */ + u_common_reg_29 common_reg_29; /* 0xca4 */ + u_common_reg_2a common_reg_2a; /* 0xca8 */ + u_common_reg_2b common_reg_2b; /* 0xcac */ + u_common_reg_2c common_reg_2c; /* 0xcb0 */ + u_common_reg_2d common_reg_2d; /* 0xcb4 */ + u_common_reg_2e common_reg_2e; /* 0xcb8 */ + u_common_reg_2f common_reg_2f; /* 0xcbc */ + u_common_reg_30 common_reg_30; /* 0xcc0 */ + u_common_reg_31 common_reg_31; /* 0xcc4 */ + u_common_reg_32 common_reg_32; /* 0xcc8 */ + u_common_reg_33 common_reg_33; /* 0xccc */ + u_common_reg_34 common_reg_34; /* 0xcd0 */ + u_common_reg_35 common_reg_35; /* 0xcd4 */ + u_common_reg_36 common_reg_36; /* 0xcd8 */ + u_common_reg_37 common_reg_37; /* 0xcdc */ + u_common_reg_38 common_reg_38; /* 0xce0 */ + u_common_reg_39 common_reg_39; /* 0xce4 */ + u_common_reg_3a common_reg_3a; /* 0xce8 */ + u_common_reg_3b common_reg_3b; /* 0xcec */ + u_common_reg_3c common_reg_3c; /* 0xcf0 */ + u_common_reg_3d common_reg_3d; /* 0xcf4 */ + u_common_reg_3f common_reg_3f; /* 0xcf8 */ + unsigned int reserved_80; /* 0xcfc */ + u_common_reg_40 common_reg_40; /* 0xd00 */ + u_common_reg_41 common_reg_41; /* 0xd04 */ + u_common_reg_42 common_reg_42; /* 0xd08 */ + u_common_reg_43 common_reg_43; /* 0xd0c */ + u_common_reg_44 common_reg_44; /* 0xd10 */ + u_common_reg_45 common_reg_45; /* 0xd14 */ + u_common_reg_46 common_reg_46; /* 0xd18 */ + unsigned int reserved_87; /* 0xd1c */ + u_common_reg_48 common_reg_48; /* 0xd20 */ + u_common_reg_49 common_reg_49; /* 0xd24 */ + u_common_reg_4a common_reg_4a; /* 0xd28 */ + u_common_reg_4b common_reg_4b; /* 0xd2c */ + unsigned int reserved_91[4]; /* 0xd30~0xd3c */ + u_common_reg_50 common_reg_50; /* 0xd40 */ + u_common_reg_51 common_reg_51; /* 0xd44 */ + u_common_reg_52 common_reg_52; /* 0xd48 */ + u_common_reg_53 common_reg_53; /* 0xd4c */ + u_common_reg_54 common_reg_54; /* 0xd50 */ + u_common_reg_55 common_reg_55; /* 0xd54 */ + u_common_reg_56 common_reg_56; /* 0xd58 */ + u_common_reg_57 common_reg_57; /* 0xd5c */ + u_common_reg_58 common_reg_58; /* 0xd60 */ + u_common_reg_59 common_reg_59; /* 0xd64 */ + u_common_reg_5a common_reg_5a; /* 0xd68 */ + unsigned int reserved_102[3]; /* 0xd6c~0xd74 */ + u_common_reg_5e common_reg_5e; /* 0xd78 */ + u_common_reg_5f common_reg_5f; /* 0xd7c */ + unsigned int reserved_104; /* 0xd80 */ + u_lane_reg_01 lane_reg_01; /* 0xd84~0xf84 */ + u_lane_reg_02 lane_reg_02; /* 0xd88~0xf88 */ + u_lane_reg_03 lane_reg_03; /* 0xd8c~0xf8c */ + u_lane_reg_04 lane_reg_04; /* 0xd90~0xf90 */ + u_lane_reg_05 lane_reg_05; /* 0xd94~0xf94 */ + u_lane_reg_06 lane_reg_06; /* 0xd98~0xf98 */ + u_lane_reg_07 lane_reg_07; /* 0xd9c~0xf9c */ + u_lane_reg_08 lane_reg_08; /* 0xda0~0xfa0 */ + u_lane_reg_09 lane_reg_09; /* 0xda4~0xfa4 */ + u_lane_reg_0a lane_reg_0a; /* 0xda8~0xfa8 */ + u_lane_reg_0b lane_reg_0b; /* 0xdac~0xfac */ + u_lane_reg_0c lane_reg_0c; /* 0xdb0~0xfb0 */ + u_lane_reg_0d lane_reg_0d; /* 0xdb4~0xfb4 */ + u_lane_reg_0e lane_reg_0e; /* 0xdb8~0xfb8 */ + u_lane_reg_0f lane_reg_0f; /* 0xdbc~0xfbc */ + u_lane_reg_10 lane_reg_10; /* 0xdc0~0xfc0 */ + u_lane_reg_11 lane_reg_11; /* 0xdc4~0xfc4 */ + u_lane_reg_12 lane_reg_12; /* 0xdc8~0xfc8 */ + u_lane_reg_13 lane_reg_13; /* 0xdcc~0xfcc */ + u_lane_reg_14 lane_reg_14; /* 0xdd0~0xfd0 */ + u_lane_reg_15 lane_reg_15; /* 0xdd4~0xfd4 */ + u_lane_reg_16 lane_reg_16; /* 0xdd8~0xfd8 */ + u_lane_reg_17 lane_reg_17; /* 0xddc~0xfdc */ + u_lane_reg_18 lane_reg_18; /* 0xde0~0xfe0 */ + u_lane_reg_19 lane_reg_19; /* 0xde4~0xfe4 */ + u_lane_reg_1a lane_reg_1a; /* 0xde8~0xfe8 */ + u_lane_reg_1b lane_reg_1b; /* 0xdec~0xfec */ + u_lane_reg_1c lane_reg_1c; /* 0xdf0~0xff0 */ + u_lane_reg_1d lane_reg_1d; /* 0xdf4~0xff4 */ + u_lane_reg_1e lane_reg_1e; /* 0xdf8~0xff8 */ +} mipi_tx_phy_regs_type_t; + +#endif /* MIPI_TX_PHY_REG_H */ diff --git a/kernel/mipi_tx/hi3519dv500/mipi_tx_reg.h b/kernel/mipi_tx/hi3519dv500/mipi_tx_reg.h new file mode 100644 index 00000000..36c03296 --- /dev/null +++ b/kernel/mipi_tx/hi3519dv500/mipi_tx_reg.h @@ -0,0 +1,1483 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef MIPI_TX_REG_H +#define MIPI_TX_REG_H + +/* define the union reg_ctrl_reset */ +typedef union { + /* define the struct bits */ + struct { + unsigned int ctrl_reset : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_ctrl_reset; + +/* define the union reg_crg_cfg */ +typedef union { + /* define the struct bits */ + struct { + unsigned int txescclk_div : 8; /* [7..0] */ + unsigned int toclk_div : 8; /* [15..8] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_crg_cfg; + +/* define the union reg_video_vc */ +typedef union { + /* define the struct bits */ + struct { + unsigned int vcid : 2; /* [1..0] */ + unsigned int reserved_0 : 2; /* [3..2] */ + unsigned int vcid_sel : 1; /* [4] */ + unsigned int reserved_1 : 27; /* [31..5] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_video_vc; + +/* define the union reg_data_type */ +typedef union { + /* define the struct bits */ + struct { + unsigned int data_type : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_data_type; + +/* define the union reg_lp_cmd_byte */ +typedef union { + /* define the struct bits */ + struct { + unsigned int invact_lpcmd_byte : 8; /* [7..0] */ + unsigned int reserved_0 : 8; /* [15..8] */ + unsigned int outvact_lpcmd_byte : 8; /* [23..16] */ + unsigned int reserved_1 : 8; /* [31..24] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_lp_cmd_byte; + +/* define the union reg_pck_en */ +typedef union { + /* define the struct bits */ + struct { + unsigned int eotp_tx_en : 1; /* [0] */ + unsigned int eotp_rx_en : 1; /* [1] */ + unsigned int crc_rx_en : 1; /* [2] */ + unsigned int ecc_rx_en : 1; /* [3] */ + unsigned int bta_en : 1; /* [4] */ + unsigned int tear_fx_en : 1; /* [5] */ + unsigned int ack_rqst_en : 1; /* [6] */ + unsigned int frame_ack_en : 1; /* [7] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_pck_en; + +/* define the union reg_gen_vc */ +typedef union { + /* define the struct bits */ + struct { + unsigned int gen_vcid : 2; /* [1..0] */ + unsigned int reserved_0 : 30; /* [31..2] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_gen_vc; + +/* define the union reg_mode_cfg */ +typedef union { + /* define the struct bits */ + struct { + unsigned int cmd_video_mode : 1; /* [0] */ + unsigned int reserved_0 : 3; /* [3..1] */ + unsigned int cmd_mode_tran_type : 1; /* [4] */ + unsigned int reserved_1 : 3; /* [7..5] */ + unsigned int video_mode_type : 2; /* [9..8] */ + unsigned int reserved_2 : 2; /* [11..10] */ + unsigned int dualpix_en : 1; /* [12] */ + unsigned int reserved_3 : 3; /* [15..13] */ + unsigned int scramb_en : 1; /* [16] */ + unsigned int reserved_4 : 3; /* [19..17] */ + unsigned int cphy_ppi_dw_sel : 1; /* [20] */ + unsigned int reserved_5 : 11; /* [31..21] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_mode_cfg; + +/* define the union reg_video_lp_en */ +typedef union { + /* define the struct bits */ + struct { + unsigned int vsa_lp_en : 1; /* [0] */ + unsigned int vbp_lp_en : 1; /* [1] */ + unsigned int vfp_lp_en : 1; /* [2] */ + unsigned int vact_lp_en : 1; /* [3] */ + unsigned int hbp_lp_en : 1; /* [4] */ + unsigned int hfp_lp_en : 1; /* [5] */ + unsigned int reserved_0 : 26; /* [31..6] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_video_lp_en; + +/* define the union reg_videom_pkt_size */ +typedef union { + /* define the struct bits */ + struct { + unsigned int videom_pkt_size : 14; /* [13..0] */ + unsigned int reserved_0 : 18; /* [31..14] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_videom_pkt_size; + +/* define the union reg_videom_num_chunks */ +typedef union { + /* define the struct bits */ + struct { + unsigned int videom_num_chunks : 13; /* [12..0] */ + unsigned int reserved_0 : 19; /* [31..13] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_videom_num_chunks; + +/* define the union reg_videom_null_size */ +typedef union { + /* define the struct bits */ + struct { + unsigned int videom_null_size : 13; /* [12..0] */ + unsigned int reserved_0 : 19; /* [31..13] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_videom_null_size; + +/* define the union reg_videom_hsa_size */ +typedef union { + /* define the struct bits */ + struct { + unsigned int videom_hsa_size : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_videom_hsa_size; + +/* define the union reg_videom_hbp_size */ +typedef union { + /* define the struct bits */ + struct { + unsigned int videom_hbp_size : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_videom_hbp_size; + +/* define the union reg_videom_hline_size */ +typedef union { + /* define the struct bits */ + struct { + unsigned int video_hline_size : 15; /* [14..0] */ + unsigned int reserved_0 : 17; /* [31..15] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_videom_hline_size; + +/* define the union reg_videom_vsa_lines */ +typedef union { + /* define the struct bits */ + struct { + unsigned int vpw : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_videom_vsa_lines; + +/* define the union reg_videom_vbp_lines */ +typedef union { + /* define the struct bits */ + struct { + unsigned int vbp : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_videom_vbp_lines; + +/* define the union reg_videom_vfp_lines */ +typedef union { + /* define the struct bits */ + struct { + unsigned int vfp : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_videom_vfp_lines; + +/* define the union reg_videom_vactive_lines */ +typedef union { + /* define the struct bits */ + struct { + unsigned int v_active_lines : 14; /* [13..0] */ + unsigned int reserved_0 : 18; /* [31..14] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_videom_vactive_lines; + +/* define the union reg_command_pkt_size */ +typedef union { + /* define the struct bits */ + struct { + unsigned int cmd_pkt_size : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_command_pkt_size; + +/* define the union reg_command_tran_mode */ +typedef union { + /* define the struct bits */ + struct { + unsigned int max_rd_pkt_size_tran : 1; /* [0] */ + unsigned int gen_sw_0p : 1; /* [1] */ + unsigned int gen_sw_1p : 1; /* [2] */ + unsigned int gen_sw_2p : 1; /* [3] */ + unsigned int gen_sr_0p : 1; /* [4] */ + unsigned int gen_sr_1p : 1; /* [5] */ + unsigned int gen_sr_2p : 1; /* [6] */ + unsigned int gen_lw : 1; /* [7] */ + unsigned int dcs_sw_0p : 1; /* [8] */ + unsigned int dcs_sw_1p : 1; /* [9] */ + unsigned int dcs_sr_0p : 1; /* [10] */ + unsigned int dcs_lw : 1; /* [11] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_command_tran_mode; + +/* define the union reg_command_header */ +typedef union { + /* define the struct bits */ + struct { + unsigned int command_datatype : 6; /* [5..0] */ + unsigned int command_virtualchannel : 2; /* [7..6] */ + unsigned int command_wordcount_low : 8; /* [15..8] */ + unsigned int command_wordcount_high : 8; /* [23..16] */ + unsigned int reserved_0 : 8; /* [31..24] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_command_header; + +/* define the union reg_command_payload */ +typedef union { + /* define the struct bits */ + struct { + unsigned int command_pld_b1 : 8; /* [7..0] */ + unsigned int command_pld_b2 : 8; /* [15..8] */ + unsigned int command_pld_b3 : 8; /* [23..16] */ + unsigned int command_pld_b4 : 8; /* [31..24] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_command_payload; + +/* define the union reg_command_status */ +typedef union { + /* define the struct bits */ + struct { + unsigned int command_empty : 1; /* [0] */ + unsigned int command_full : 1; /* [1] */ + unsigned int pld_write_empty : 1; /* [2] */ + unsigned int pld_write_full : 1; /* [3] */ + unsigned int pld_read_empty : 1; /* [4] */ + unsigned int pld_read_full : 1; /* [5] */ + unsigned int rd_cmd_busy : 1; /* [6] */ + unsigned int command_idle : 1; /* [7] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_command_status; + +/* define the union reg_hs_lp_to_set */ +typedef union { + /* define the struct bits */ + struct { + unsigned int lprx_to_cnt : 16; /* [15..0] */ + unsigned int hstx_to_cnt : 16; /* [31..16] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_hs_lp_to_set; + +/* define the union reg_hsrd_to_set */ +typedef union { + /* define the struct bits */ + struct { + unsigned int hsrd_to_set : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_hsrd_to_set; + +/* define the union reg_lprd_to_set */ +typedef union { + /* define the struct bits */ + struct { + unsigned int lprd_to_set : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_lprd_to_set; + +/* define the union reg_hswr_to_set */ +typedef union { + /* define the struct bits */ + struct { + unsigned int hswr_to_set : 16; /* [15..0] */ + unsigned int reserved_0 : 8; /* [23..16] */ + unsigned int pre_to_mode : 1; /* [24] */ + unsigned int reserved_1 : 7; /* [31..25] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_hswr_to_set; + +/* define the union reg_lpwr_to_set */ +typedef union { + /* define the struct bits */ + struct { + unsigned int lpwr_to_set : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_lpwr_to_set; + +/* define the union reg_bta_to_set */ +typedef union { + /* define the struct bits */ + struct { + unsigned int bta_to_set : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_bta_to_set; + +/* define the union reg_clklane_ctrl */ +typedef union { + /* define the struct bits */ + struct { + unsigned int txrequesthsclk : 1; /* [0] */ + unsigned int clklane_continue : 1; /* [1] */ + unsigned int cphy_clklane_sel_qst : 1; /* [2] */ + unsigned int reserved_0 : 29; /* [31..3] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_clklane_ctrl; + +/* define the union reg_clklane_time */ +typedef union { + /* define the struct bits */ + struct { + unsigned int clklane_lp2hs_time : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int clklane_hs2lp_time : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_clklane_time; + +/* define the union reg_datalane_time */ +typedef union { + /* define the struct bits */ + struct { + unsigned int datalane_lp2hs_time : 10; /* [9..0] */ + unsigned int reserved_0 : 6; /* [15..10] */ + unsigned int datalane_hs2lp_time : 10; /* [25..16] */ + unsigned int reserved_1 : 6; /* [31..26] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_datalane_time; + +/* define the union reg_phy_ctrl */ +typedef union { + /* define the struct bits */ + struct { + unsigned int shutdownz : 1; /* [0] */ + unsigned int rstz : 1; /* [1] */ + unsigned int enableclk : 1; /* [2] */ + unsigned int forcepll : 1; /* [3] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_phy_ctrl; + +/* define the union reg_lane_num */ +typedef union { + /* define the struct bits */ + struct { + unsigned int lane_num : 2; /* [1..0] */ + unsigned int reserved_0 : 6; /* [7..2] */ + unsigned int stopstate_time : 8; /* [15..8] */ + unsigned int reserved_1 : 16; /* [31..16] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_lane_num; + +/* define the union reg_ulps_ctrl */ +typedef union { + /* define the struct bits */ + struct { + unsigned int txulpsclklane : 1; /* [0] */ + unsigned int txulpsexitclklane : 1; /* [1] */ + unsigned int txulpsdatalane : 1; /* [2] */ + unsigned int txulpsexitdatalane : 1; /* [3] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_ulps_ctrl; + +/* define the union reg_tx_triggers */ +typedef union { + /* define the struct bits */ + struct { + unsigned int tx_triggers : 4; /* [3..0] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_tx_triggers; + +/* define the union reg_ppi_status */ +typedef union { + /* define the struct bits */ + struct { + unsigned int phy_pll_lock : 1; /* [0] */ + unsigned int phy_tran_direction : 1; /* [1] */ + unsigned int stopstateclklane : 1; /* [2] */ + unsigned int ulpsactivenotclk : 1; /* [3] */ + unsigned int stopstate0lane : 1; /* [4] */ + unsigned int ulpsactivenot0lane : 1; /* [5] */ + unsigned int rxulpsesc0lane : 1; /* [6] */ + unsigned int stopstate1lane : 1; /* [7] */ + unsigned int ulpsactivenot1lane : 1; /* [8] */ + unsigned int stopstate2lane : 1; /* [9] */ + unsigned int ulpsactivenot2lane : 1; /* [10] */ + unsigned int stopstate3lane : 1; /* [11] */ + unsigned int ulpsactivenot3lane : 1; /* [12] */ + unsigned int reserved_0 : 19; /* [31..13] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_ppi_status; + +/* define the union reg_phy_reg_cfg0 */ +typedef union { + /* define the struct bits */ + struct { + unsigned int testclr : 1; /* [0] */ + unsigned int testclk : 1; /* [1] */ + unsigned int reserved_0 : 30; /* [31..2] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_phy_reg_cfg0; + +/* define the union reg_phy_reg_cfg1 */ +typedef union { + /* define the struct bits */ + struct { + unsigned int testdin : 8; /* [7..0] */ + unsigned int testdout : 8; /* [15..8] */ + unsigned int testen : 1; /* [16] */ + unsigned int reserved_0 : 15; /* [31..17] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_phy_reg_cfg1; + +/* define the union reg_int0_status */ +typedef union { + /* define the struct bits */ + struct { + unsigned int error_report_0 : 1; /* [0] */ + unsigned int error_report_1 : 1; /* [1] */ + unsigned int error_report_2 : 1; /* [2] */ + unsigned int error_report_3 : 1; /* [3] */ + unsigned int error_report_4 : 1; /* [4] */ + unsigned int error_report_5 : 1; /* [5] */ + unsigned int error_report_6 : 1; /* [6] */ + unsigned int error_report_7 : 1; /* [7] */ + unsigned int error_report_8 : 1; /* [8] */ + unsigned int error_report_9 : 1; /* [9] */ + unsigned int error_report_10 : 1; /* [10] */ + unsigned int error_report_11 : 1; /* [11] */ + unsigned int error_report_12 : 1; /* [12] */ + unsigned int error_report_13 : 1; /* [13] */ + unsigned int error_report_14 : 1; /* [14] */ + unsigned int error_report_15 : 1; /* [15] */ + unsigned int errescentry : 1; /* [16] */ + unsigned int errsyncesc : 1; /* [17] */ + unsigned int errcontrol : 1; /* [18] */ + unsigned int errcontentionlp0 : 1; /* [19] */ + unsigned int errcontentionlp1 : 1; /* [20] */ + unsigned int reserved_0 : 11; /* [31..21] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_int0_status; + +/* define the union reg_int1_status */ +typedef union { + /* define the struct bits */ + struct { + unsigned int eotp_rx_err : 1; /* [0] */ + unsigned int rxpkt_size_err : 1; /* [1] */ + unsigned int rxcrc_err : 1; /* [2] */ + unsigned int rxecc_single_err : 1; /* [3] */ + unsigned int rxecc_multi_err : 1; /* [4] */ + unsigned int pld_wr_err : 1; /* [5] */ + unsigned int pld_rd_err : 1; /* [6] */ + unsigned int cmd_wr_err : 1; /* [7] */ + unsigned int cmd_pld_wr_err : 1; /* [8] */ + unsigned int cmd_pld_rd_err : 1; /* [9] */ + unsigned int rxpld_rd_err : 1; /* [10] */ + unsigned int rxpld_wr_err : 1; /* [11] */ + unsigned int to_lp_rx : 1; /* [12] */ + unsigned int to_hs_tx : 1; /* [13] */ + unsigned int phy_pll_lock_err : 1; /* [14] */ + unsigned int cmd_tran_end : 1; /* [15] */ + unsigned int line_length_change : 1; /* [16] */ + unsigned int hss_abnormal : 1; /* [17] */ + unsigned int fifo_nempty_when_vsync : 1; /* [18] */ + unsigned int reserved_0 : 1; /* [19] */ + unsigned int vss : 1; /* [20] */ + unsigned int reserved_1 : 3; /* [23..21] */ + unsigned int rxtrigger0 : 1; /* [24] */ + unsigned int rxtrigger1 : 1; /* [25] */ + unsigned int rxtrigger2 : 1; /* [26] */ + unsigned int rxtrigger3 : 1; /* [27] */ + unsigned int reserved_2 : 4; /* [31..28] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_int1_status; + +/* define the union reg_int0_mask */ +typedef union { + /* define the struct bits */ + struct { + unsigned int mask_error_report_0 : 1; /* [0] */ + unsigned int mask_error_report_1 : 1; /* [1] */ + unsigned int mask_error_report_2 : 1; /* [2] */ + unsigned int mask_error_report_3 : 1; /* [3] */ + unsigned int mask_error_report_4 : 1; /* [4] */ + unsigned int mask_error_report_5 : 1; /* [5] */ + unsigned int mask_error_report_6 : 1; /* [6] */ + unsigned int mask_error_report_7 : 1; /* [7] */ + unsigned int mask_error_report_8 : 1; /* [8] */ + unsigned int mask_error_report_9 : 1; /* [9] */ + unsigned int mask_error_report_10 : 1; /* [10] */ + unsigned int mask_error_report_11 : 1; /* [11] */ + unsigned int mask_error_report_12 : 1; /* [12] */ + unsigned int mask_error_report_13 : 1; /* [13] */ + unsigned int mask_error_report_14 : 1; /* [14] */ + unsigned int mask_error_report_15 : 1; /* [15] */ + unsigned int mask_errescentry : 1; /* [16] */ + unsigned int mask_errsyncesc : 1; /* [17] */ + unsigned int mask_errcontrol : 1; /* [18] */ + unsigned int mask_errcontentionlp0 : 1; /* [19] */ + unsigned int mask_errcontentionlp1 : 1; /* [20] */ + unsigned int reserved_0 : 11; /* [31..21] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_int0_mask; + +/* define the union reg_int1_mask */ +typedef union { + /* define the struct bits */ + struct { + unsigned int mask_eotp_rx_err : 1; /* [0] */ + unsigned int mask_rxpkt_size_err : 1; /* [1] */ + unsigned int mask_rxcrc_err : 1; /* [2] */ + unsigned int mask_rxecc_single_err : 1; /* [3] */ + unsigned int mask_rxecc_multi_err : 1; /* [4] */ + unsigned int mask_pld_wr_err : 1; /* [5] */ + unsigned int mask_pld_rd_err : 1; /* [6] */ + unsigned int mask_cmd_wr_err : 1; /* [7] */ + unsigned int mask_cmd_pld_wr_err : 1; /* [8] */ + unsigned int mask_cmd_pld_rd_err : 1; /* [9] */ + unsigned int mask_rxpld_rd_err : 1; /* [10] */ + unsigned int mask_rxpld_wr_err : 1; /* [11] */ + unsigned int mask_to_lp_rx : 1; /* [12] */ + unsigned int mask_to_hs_tx : 1; /* [13] */ + unsigned int mask_phy_pll_lock_err : 1; /* [14] */ + unsigned int mask_cmd_tran_end : 1; /* [15] */ + unsigned int mask_line_length_change : 1; /* [16] */ + unsigned int mask_hss_abnormal : 1; /* [17] */ + unsigned int mask_fifo_nempty_when_vsync : 1; /* [18] */ + unsigned int reserved_0 : 1; /* [19] */ + unsigned int mask_vss : 1; /* [20] */ + unsigned int reserved_1 : 3; /* [23..21] */ + unsigned int mask_rxtrigger0 : 1; /* [24] */ + unsigned int mask_rxtrigger1 : 1; /* [25] */ + unsigned int mask_rxtrigger2 : 1; /* [26] */ + unsigned int mask_rxtrigger3 : 1; /* [27] */ + unsigned int reserved_2 : 4; /* [31..28] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_int1_mask; + +/* define the union reg_phy_cal */ +typedef union { + /* define the struct bits */ + struct { + unsigned int txskewcalhs : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_phy_cal; + +/* define the union reg_auto_ulps_mode */ +typedef union { + /* define the struct bits */ + struct { + unsigned int auto_ulps : 1; /* [0] */ + unsigned int reserved_0 : 15; /* [15..1] */ + unsigned int pll_off_ulps : 1; /* [16] */ + unsigned int reserved_1 : 15; /* [31..17] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_auto_ulps_mode; + +/* define the union reg_auto_ulps_wakeup_time */ +typedef union { + /* define the struct bits */ + struct { + unsigned int twakeup_clk_div : 16; /* [15..0] */ + unsigned int twakeup_cnt : 16; /* [31..16] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_auto_ulps_wakeup_time; + +/* define the union reg_dsc_config */ +typedef union { + /* define the struct bits */ + struct { + unsigned int compression_mode : 1; /* [0] */ + unsigned int reserved_0 : 7; /* [7..1] */ + unsigned int algorithm_mode : 2; /* [9..8] */ + unsigned int reserved_1 : 6; /* [15..10] */ + unsigned int pps : 2; /* [17..16] */ + unsigned int reserved_2 : 6; /* [23..18] */ + unsigned int video_lpcmd : 1; /* [24] */ + unsigned int reserved_3 : 7; /* [31..25] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_dsc_config; + +/* define the union reg_read_cmd_time */ +typedef union { + /* define the struct bits */ + struct { + unsigned int read_cmd_time : 15; /* [14..0] */ + unsigned int reserved_0 : 17; /* [31..15] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_read_cmd_time; + +/* define the union reg_auto_ulps_min_time */ +typedef union { + /* define the struct bits */ + struct { + unsigned int auto_ulps_min_time : 12; /* [11..0] */ + unsigned int reserved_0 : 20; /* [31..12] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_auto_ulps_min_time; + +/* define the union reg_phy_mode */ +typedef union { + /* define the struct bits */ + struct { + unsigned int phy_mode : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_phy_mode; + +/* define the union reg_vid_shadow_ctrl */ +typedef union { + /* define the struct bits */ + struct { + unsigned int vid_shadow_en : 1; /* [0] */ + unsigned int reserved_0 : 7; /* [7..1] */ + unsigned int vid_shadow_req : 1; /* [8] */ + unsigned int reserved_1 : 23; /* [31..9] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_vid_shadow_ctrl; + +/* define the union reg_dsi_dbg0 */ +typedef union { + /* define the struct bits */ + struct { + unsigned int vid_delay : 17; /* [16..0] */ + unsigned int phyfsm_st : 3; /* [19..17] */ + unsigned int dbips_st : 4; /* [23..20] */ + unsigned int vidregion : 3; /* [26..24] */ + unsigned int dpips_st : 5; /* [31..27] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_dsi_dbg0; + +/* define the union reg_phy_pll_start_time */ +typedef union { + /* define the struct bits */ + struct { + unsigned int phy_pll_start_time_qst : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_phy_pll_start_time; + +/* define the union reg_dbg_crc_ctrl */ +typedef union { + /* define the struct bits */ + struct { + unsigned int dbg_crc_init : 1; /* [0] */ + unsigned int dbg_crc_lane_sel : 2; /* [2..1] */ + unsigned int dbg_crc_en : 1; /* [3] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_dbg_crc_ctrl; + +/* define the union reg_secu_cfg_en */ +typedef union { + /* define the struct bits */ + struct { + unsigned int secu_cfg_en : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_secu_cfg_en; + +/* define the union reg_polarity_ctrl */ +typedef union { + /* define the struct bits */ + struct { + unsigned int vsync_plr : 1; /* [0] */ + unsigned int hsync_plr : 1; /* [1] */ + unsigned int reserved_0 : 1; /* [2] */ + unsigned int data_en_plr : 1; /* [3] */ + unsigned int reserved_1 : 28; /* [31..4] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_polarity_ctrl; + +/* define the union reg_dual_pixelmode */ +typedef union { + /* define the struct bits */ + struct { + unsigned int reserved_0 : 5; /* [4..0] */ + unsigned int dual_mode_en : 1; /* [5] */ + unsigned int reserved_1 : 7; /* [12..6] */ + unsigned int dual_mode_ctrl : 1; /* [13] */ + unsigned int reserved_2 : 18; /* [31..14] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_dual_pixelmode; + +/* define the union reg_hrz_ctrl */ +typedef union { + /* define the struct bits */ + struct { + unsigned int dsi_hsize : 13; /* [12..0] */ + unsigned int reserved_0 : 19; /* [31..13] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_hrz_ctrl; + +/* define the union reg_vrt_ctrl */ +typedef union { + /* define the struct bits */ + struct { + unsigned int dsi_vsize : 13; /* [12..0] */ + unsigned int reserved_0 : 19; /* [31..13] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_vrt_ctrl; + +/* define the union reg_int_pro_msk */ +typedef union { + /* define the struct bits */ + struct { + unsigned int int_pro_msk : 17; /* [16..0] */ + unsigned int reserved_0 : 15; /* [31..17] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_int_pro_msk; + +/* define the union reg_vstate */ +typedef union { + /* define the struct bits */ + struct { + unsigned int vstate : 11; /* [10..0] */ + unsigned int reserved_0 : 21; /* [31..11] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_vstate; + +/* define the union reg_hstate */ +typedef union { + /* define the struct bits */ + struct { + unsigned int hstate : 6; /* [5..0] */ + unsigned int reserved_0 : 26; /* [31..6] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_hstate; + +/* define the union reg_dphytx_ctrl */ +typedef union { + /* define the struct bits */ + struct { + unsigned int dphytx_ctrl : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_dphytx_ctrl; + +/* define the union reg_phytx_trstop_flag */ +typedef union { + /* define the struct bits */ + struct { + unsigned int phytx_trstop_flag : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_phytx_trstop_flag; + +/* define the union reg_mipi_dsi_mem_control */ +typedef union { + /* define the struct bits */ + struct { + unsigned int tselr : 2; /* [1..0] */ + unsigned int tselw : 2; /* [3..2] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_mipi_dsi_mem_control; + +/* define the union reg_display_control */ +typedef union { + /* define the struct bits */ + struct { + unsigned int dpishutdn : 1; /* [0] */ + unsigned int dpicolorm : 1; /* [1] */ + unsigned int vsync_f_sub : 1; /* [2] */ + unsigned int vsync_b_sub : 1; /* [3] */ + unsigned int v1_sel : 3; /* [6..4] */ + unsigned int reserved_0 : 1; /* [7] */ + unsigned int u1_sel : 3; /* [10..8] */ + unsigned int reserved_1 : 1; /* [11] */ + unsigned int y1_sel : 3; /* [14..12] */ + unsigned int reserved_2 : 1; /* [15] */ + unsigned int v2_sel : 3; /* [18..16] */ + unsigned int reserved_3 : 1; /* [19] */ + unsigned int u2_sel : 3; /* [22..20] */ + unsigned int reserved_4 : 1; /* [23] */ + unsigned int y2_sel : 3; /* [26..24] */ + unsigned int reserved_5 : 1; /* [27] */ + unsigned int dataen_f_sub : 1; /* [28] */ + unsigned int dataen_b_sub : 1; /* [29] */ + unsigned int hsync_f_sub : 1; /* [30] */ + unsigned int hsync_b_sub : 1; /* [31] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_display_control; + +/* define the union reg_operation_mode */ +typedef union { + /* define the struct bits */ + struct { + unsigned int reserved_0 : 1; /* [0] */ + unsigned int mem_ck_en : 1; /* [1] */ + unsigned int reserved_1 : 3; /* [4..2] */ + unsigned int init_skew_en : 1; /* [5] */ + unsigned int period_skew_en : 1; /* [6] */ + unsigned int reserved_2 : 1; /* [7] */ + unsigned int colorbar_en : 1; /* [8] */ + unsigned int colorbar_orien : 1; /* [9] */ + unsigned int colorbar_test_en : 1; /* [10] */ + unsigned int reserved_3 : 1; /* [11] */ + unsigned int colorbar_mode : 4; /* [15..12] */ + unsigned int read_empty_vsync_en : 1; /* [16] */ + unsigned int reserved_4 : 3; /* [19..17] */ + unsigned int hss_abnormal_rst : 1; /* [20] */ + unsigned int rxesc_buf_en : 1; /* [21] */ + unsigned int reserved_5 : 2; /* [23..22] */ + unsigned int turndisable : 1; /* [24] */ + unsigned int forcerxmode : 1; /* [25] */ + unsigned int forcetxstopmode : 1; /* [26] */ + unsigned int video_te_en : 1; /* [27] */ + unsigned int reserved_6 : 3; /* [30..28] */ + unsigned int input_en : 1; /* [31] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_operation_mode; + +/* define the union reg_hfp_hact_in */ +typedef union { + /* define the struct bits */ + struct { + unsigned int hact_in : 16; /* [15..0] */ + unsigned int hfp_in : 16; /* [31..16] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_hfp_hact_in; + +/* define the union reg_hbp_hsa_in */ +typedef union { + /* define the struct bits */ + struct { + unsigned int hsa_in : 16; /* [15..0] */ + unsigned int hbp_in : 16; /* [31..16] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_hbp_hsa_in; + +/* define the union reg_vert_det */ +typedef union { + /* define the struct bits */ + struct { + unsigned int vact_det : 16; /* [15..0] */ + unsigned int vall_det : 16; /* [31..16] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_vert_det; + +/* define the union reg_hori0_det */ +typedef union { + /* define the struct bits */ + struct { + unsigned int hact_det : 16; /* [15..0] */ + unsigned int hline_det : 16; /* [31..16] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_hori0_det; + +/* define the union reg_hori1_det */ +typedef union { + /* define the struct bits */ + struct { + unsigned int hsa_det : 16; /* [15..0] */ + unsigned int hbp_det : 16; /* [31..16] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_hori1_det; + +/* define the union reg_vsa_det */ +typedef union { + /* define the struct bits */ + struct { + unsigned int vsa_det : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_vsa_det; + +/* define the union reg_v_h_send */ +typedef union { + /* define the struct bits */ + struct { + unsigned int h_send : 16; /* [15..0] */ + unsigned int v_send : 16; /* [31..16] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_v_h_send; + +/* define the union reg_lanereqhs_width */ +typedef union { + /* define the struct bits */ + struct { + unsigned int lanerequesths_width : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_lanereqhs_width; + +/* define the union reg_hs_data */ +typedef union { + /* define the struct bits */ + struct { + unsigned int l0hsdata : 8; /* [7..0] */ + unsigned int l1hsdata : 8; /* [15..8] */ + unsigned int l2hsdata : 8; /* [23..16] */ + unsigned int l3hsdata : 8; /* [31..24] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_hs_data; + +/* define the union reg_datatype0 */ +typedef union { + /* define the struct bits */ + struct { + unsigned int dt_pixel : 6; /* [5..0] */ + unsigned int reserved_0 : 2; /* [7..6] */ + unsigned int dt_hss : 6; /* [13..8] */ + unsigned int reserved_1 : 2; /* [15..14] */ + unsigned int dt_vse : 6; /* [21..16] */ + unsigned int reserved_2 : 2; /* [23..22] */ + unsigned int dt_vss : 6; /* [29..24] */ + unsigned int reserved_3 : 2; /* [31..30] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_datatype0; + +/* define the union reg_datatype1 */ +typedef union { + /* define the struct bits */ + struct { + unsigned int dt_null : 6; /* [5..0] */ + unsigned int reserved_0 : 2; /* [7..6] */ + unsigned int dt_blank : 6; /* [13..8] */ + unsigned int reserved_1 : 2; /* [15..14] */ + unsigned int dt_etop : 6; /* [21..16] */ + unsigned int reserved_2 : 2; /* [23..22] */ + unsigned int dt_hse : 6; /* [29..24] */ + unsigned int reserved_3 : 2; /* [31..30] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_datatype1; + +/* define the union reg_csi_ctrl */ +typedef union { + /* define the struct bits */ + struct { + unsigned int csi_en : 1; /* [0] */ + unsigned int reserved_0 : 3; /* [3..1] */ + unsigned int csi_vse_position : 1; /* [4] */ + unsigned int reserved_1 : 3; /* [7..5] */ + unsigned int frame_num_inc : 1; /* [8] */ + unsigned int reserved_2 : 3; /* [11..9] */ + unsigned int dt_config : 1; /* [12] */ + unsigned int reserved_3 : 3; /* [15..13] */ + unsigned int csi_hss_en : 1; /* [16] */ + unsigned int reserved_4 : 15; /* [31..17] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_csi_ctrl; + +/* define the union reg_lane_id */ +typedef union { + /* define the struct bits */ + struct { + unsigned int lane0_id : 2; /* [1..0] */ + unsigned int reserved_0 : 2; /* [3..2] */ + unsigned int lane1_id : 2; /* [5..4] */ + unsigned int reserved_1 : 2; /* [7..6] */ + unsigned int lane2_id : 2; /* [9..8] */ + unsigned int reserved_2 : 2; /* [11..10] */ + unsigned int lane3_id : 2; /* [13..12] */ + unsigned int reserved_3 : 18; /* [31..14] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_lane_id; + +/* define the union reg_read_memory_delay_ctrl */ +typedef union { + /* define the struct bits */ + struct { + unsigned int delay_regin : 17; /* [16..0] */ + unsigned int reserved_0 : 3; /* [19..17] */ + unsigned int delay_abnormal : 1; /* [20] */ + unsigned int delay_from_reg : 1; /* [21] */ + unsigned int reserved_1 : 10; /* [31..22] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_read_memory_delay_ctrl; + +/* define the union reg_ppi_v_send0 */ +typedef union { + /* define the struct bits */ + struct { + unsigned int vsa_length : 16; /* [15..0] */ + unsigned int vsa_vbp_length : 16; /* [31..16] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_ppi_v_send0; + +/* define the union reg_ppi_v_send1 */ +typedef union { + /* define the struct bits */ + struct { + unsigned int vactive_length : 16; /* [15..0] */ + unsigned int vtotal_length : 16; /* [31..16] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_ppi_v_send1; + +/* define the union reg_ppi_h_send0 */ +typedef union { + /* define the struct bits */ + struct { + unsigned int hsa_length : 16; /* [15..0] */ + unsigned int hsa_hbp_length : 16; /* [31..16] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_ppi_h_send0; + +/* define the union reg_ppi_h_send1 */ +typedef union { + /* define the struct bits */ + struct { + unsigned int hactive_length : 16; /* [15..0] */ + unsigned int htotal_length : 16; /* [31..16] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_ppi_h_send1; + +/* define the union reg_ppi_h_send2 */ +typedef union { + /* define the struct bits */ + struct { + unsigned int pix_pkt_length : 16; /* [15..0] */ + unsigned int pix_pkt_distance : 16; /* [31..16] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_ppi_h_send2; + +/* define the union reg_ppi_h_send3 */ +typedef union { + /* define the struct bits */ + struct { + unsigned int line_length_send_diff : 16; /* [15..0] */ + unsigned int reserved_0 : 16; /* [31..16] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_ppi_h_send3; + +/* define the union reg_dft_control */ +typedef union { + /* define the struct bits */ + struct { + unsigned int code_length : 17; /* [16..0] */ + unsigned int reserved_0 : 3; /* [19..17] */ + unsigned int pattern_type : 2; /* [21..20] */ + unsigned int reserved_1 : 2; /* [23..22] */ + unsigned int hs_lp_mode : 2; /* [25..24] */ + unsigned int txskewcalhs_dft : 1; /* [26] */ + unsigned int bist_mode : 1; /* [27] */ + unsigned int compare_done : 1; /* [28] */ + unsigned int compare : 1; /* [29] */ + unsigned int compare_result : 1; /* [30] */ + unsigned int reserved_2 : 1; /* [31] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_dft_control; + +/* define the union reg_dft_prbs_init */ +typedef union { + /* define the struct bits */ + struct { + unsigned int prbs_init : 7; /* [6..0] */ + unsigned int reserved_0 : 25; /* [31..7] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} reg_dft_prbs_init; + +// ============================================================================== +/* define the global struct */ +typedef struct { + volatile reg_ctrl_reset ctrl_reset; /* 0x0 */ + volatile unsigned int reserved_0; /* 0x4 */ + volatile reg_crg_cfg crg_cfg; /* 0x8 */ + volatile reg_video_vc video_vc; /* 0xc */ + volatile reg_data_type data_type; /* 0x10 */ + volatile unsigned int reserved_1; /* 0x14 */ + volatile reg_lp_cmd_byte lp_cmd_byte; /* 0x18 */ + volatile unsigned int reserved_2[4]; /* 0x1c~0x28 */ + volatile reg_pck_en pck_en; /* 0x2c */ + volatile reg_gen_vc gen_vc; /* 0x30 */ + volatile reg_mode_cfg mode_cfg; /* 0x34 */ + volatile reg_video_lp_en video_lp_en; /* 0x38 */ + volatile reg_videom_pkt_size videom_pkt_size; /* 0x3c */ + volatile reg_videom_num_chunks videom_num_chunks; /* 0x40 */ + volatile reg_videom_null_size videom_null_size; /* 0x44 */ + volatile reg_videom_hsa_size videom_hsa_size; /* 0x48 */ + volatile reg_videom_hbp_size videom_hbp_size; /* 0x4c */ + volatile reg_videom_hline_size videom_hline_size; /* 0x50 */ + volatile reg_videom_vsa_lines videom_vsa_lines; /* 0x54 */ + volatile reg_videom_vbp_lines videom_vbp_lines; /* 0x58 */ + volatile reg_videom_vfp_lines videom_vfp_lines; /* 0x5c */ + volatile reg_videom_vactive_lines videom_vactive_lines; /* 0x60 */ + volatile reg_command_pkt_size command_pkt_size; /* 0x64 */ + volatile reg_command_tran_mode command_tran_mode; /* 0x68 */ + volatile reg_command_header command_header; /* 0x6c */ + volatile reg_command_payload command_payload; /* 0x70 */ + volatile reg_command_status command_status; /* 0x74 */ + volatile reg_hs_lp_to_set hs_lp_to_set; /* 0x78 */ + volatile reg_hsrd_to_set hsrd_to_set; /* 0x7c */ + volatile reg_lprd_to_set lprd_to_set; /* 0x80 */ + volatile reg_hswr_to_set hswr_to_set; /* 0x84 */ + volatile reg_lpwr_to_set lpwr_to_set; /* 0x88 */ + volatile reg_bta_to_set bta_to_set; /* 0x8c */ + volatile unsigned int reserved_3; /* 0x90 */ + volatile reg_clklane_ctrl clklane_ctrl; /* 0x94 */ + volatile reg_clklane_time clklane_time; /* 0x98 */ + volatile reg_datalane_time datalane_time; /* 0x9c */ + volatile reg_phy_ctrl phy_ctrl; /* 0xa0 */ + volatile reg_lane_num lane_num; /* 0xa4 */ + volatile reg_ulps_ctrl ulps_ctrl; /* 0xa8 */ + volatile reg_tx_triggers tx_triggers; /* 0xac */ + volatile reg_ppi_status ppi_status; /* 0xb0 */ + volatile reg_phy_reg_cfg0 phy_reg_cfg0; /* 0xb4 */ + volatile reg_phy_reg_cfg1 phy_reg_cfg1; /* 0xb8 */ + volatile reg_int0_status int0_status; /* 0xbc */ + volatile reg_int1_status int1_status; /* 0xc0 */ + volatile reg_int0_mask int0_mask; /* 0xc4 */ + volatile reg_int1_mask int1_mask; /* 0xc8 */ + volatile reg_phy_cal phy_cal; /* 0xcc */ + volatile unsigned int reserved_4[2]; /* 0xd0~0xd4 */ + volatile unsigned int int_force0; /* 0xd8 */ + volatile unsigned int int_force1; /* 0xdc */ + volatile reg_auto_ulps_mode auto_ulps_mode; /* 0xe0 */ + volatile unsigned int auto_ulps_entry_delay; /* 0xe4 */ + volatile reg_auto_ulps_wakeup_time auto_ulps_wakeup_time; /* 0xe8 */ + volatile unsigned int reserved_5; /* 0xec */ + volatile reg_dsc_config dsc_config; /* 0xf0 */ + volatile reg_read_cmd_time read_cmd_time; /* 0xf4 */ + volatile reg_auto_ulps_min_time auto_ulps_min_time; /* 0xf8 */ + volatile reg_phy_mode phy_mode; /* 0xfc */ + volatile reg_vid_shadow_ctrl vid_shadow_ctrl; /* 0x100 */ + volatile unsigned int reserved_6[38]; /* 0x104~0x198 */ + volatile reg_dsi_dbg0 dsi_dbg0; /* 0x19c */ + volatile reg_phy_pll_start_time phy_pll_start_time; /* 0x1a0 */ + volatile reg_dbg_crc_ctrl dbg_crc_ctrl; /* 0x1a4 */ + volatile unsigned int dbg_crc_val; /* 0x1a8 */ + volatile reg_secu_cfg_en secu_cfg_en; /* 0x1ac */ + volatile reg_polarity_ctrl polarity_ctrl; /* 0x1b0 */ + volatile unsigned int reserved_7; /* 0x1b4 */ + volatile reg_dual_pixelmode dual_pixelmode; /* 0x1b8 */ + volatile unsigned int reserved_8[7]; /* 0x1bc~0x1d4 */ + volatile unsigned int frm_valid_dbg; /* 0x1d8 */ + volatile unsigned int reserved_9[4]; /* 0x1dc~0x1e8 */ + volatile reg_hrz_ctrl hrz_ctrl; /* 0x1ec */ + volatile reg_vrt_ctrl vrt_ctrl; /* 0x1f0 */ + volatile unsigned int reserved_10; /* 0x1f4 */ + volatile reg_int_pro_msk int_pro_msk; /* 0x1f8 */ + volatile reg_vstate vstate; /* 0x1fc */ + volatile reg_hstate hstate; /* 0x200 */ + volatile unsigned int reserved_11[8]; /* 0x204~0x220 */ + volatile unsigned int phytx_stopsnt; /* 0x224 */ + volatile reg_dphytx_ctrl dphytx_ctrl; /* 0x228 */ + volatile reg_phytx_trstop_flag phytx_trstop_flag; /* 0x22c */ + volatile unsigned int phytx_status; /* 0x230 */ + volatile unsigned int reserved_12[6]; /* 0x234~0x248 */ + volatile unsigned int gint_msk; /* 0x24c */ + volatile unsigned int reserved_13[44]; /* 0x250~0x2fc */ + volatile reg_mipi_dsi_mem_control mipi_dsi_mem_control; /* 0x300 */ + volatile reg_display_control display_control; /* 0x304 */ + volatile reg_operation_mode operation_mode; /* 0x308 */ + volatile reg_hfp_hact_in hfp_hact_in; /* 0x30c */ + volatile reg_hbp_hsa_in hbp_hsa_in; /* 0x310 */ + volatile reg_vert_det vert_det; /* 0x314 */ + volatile reg_hori0_det hori0_det; /* 0x318 */ + volatile reg_hori1_det hori1_det; /* 0x31c */ + volatile reg_vsa_det vsa_det; /* 0x320 */ + volatile reg_v_h_send v_h_send; /* 0x324 */ + volatile reg_lanereqhs_width lanereqhs_width; /* 0x328 */ + volatile reg_hs_data hs_data; /* 0x32c */ + volatile reg_datatype0 datatype0; /* 0x330 */ + volatile reg_datatype1 datatype1; /* 0x334 */ + volatile reg_csi_ctrl csi_ctrl; /* 0x338 */ + volatile unsigned int skew_begin; /* 0x33c */ + volatile unsigned int skew_end; /* 0x340 */ + volatile unsigned int reserved_14[3]; /* 0x344~0x34c */ + volatile reg_lane_id lane_id; /* 0x350 */ + volatile reg_read_memory_delay_ctrl read_memory_delay_ctrl; /* 0x354 */ + volatile reg_ppi_v_send0 ppi_v_send0; /* 0x358 */ + volatile reg_ppi_v_send1 ppi_v_send1; /* 0x35c */ + volatile reg_ppi_h_send0 ppi_h_send0; /* 0x360 */ + volatile reg_ppi_h_send1 ppi_h_send1; /* 0x364 */ + volatile reg_ppi_h_send2 ppi_h_send2; /* 0x368 */ + volatile reg_ppi_h_send3 ppi_h_send3; /* 0x36c */ + volatile unsigned int reserved_15[12]; /* 0x370~0x39c */ + volatile unsigned int te_length; /* 0x3a0 */ + volatile unsigned int reserved_16[15]; /* 0x3a4~0x3dc */ + volatile reg_dft_control dft_control; /* 0x3e0 */ + volatile unsigned int dft_skew_period; /* 0x3e4 */ + volatile reg_dft_prbs_init dft_prbs_init; /* 0x3e8 */ +} mipi_tx_regs_type_t; + +#endif /* MIPI_TX_REG_H */ diff --git a/kernel/mipi_tx/hi3519dv500/ot_mipi_tx.h b/kernel/mipi_tx/hi3519dv500/ot_mipi_tx.h new file mode 100644 index 00000000..36dcfefd --- /dev/null +++ b/kernel/mipi_tx/hi3519dv500/ot_mipi_tx.h @@ -0,0 +1,127 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef OT_MIPI_TX_H +#define OT_MIPI_TX_H + +#include "osal_ioctl.h" + +#define CMD_MAX_NUM 4 +#define LANE_MAX_NUM 4 +#define MIPI_LANE_NUM_PER_DEV 4 +#define MIPI_TX_DISABLE_LANE_ID (-1) +#define MIPI_TX_SET_DATA_SIZE 800 +#define MIPI_TX_GET_DATA_SIZE 160 + +#define OT_ALIGN_NUM 8 +#define ATTRIBUTE __attribute__((aligned(OT_ALIGN_NUM))) + +typedef enum { + OUT_MODE_CSI = 0x0, /* csi mode */ + OUT_MODE_DSI_VIDEO = 0x1, /* dsi video mode */ + OUT_MODE_DSI_CMD = 0x2, /* dsi command mode */ + + OUT_MODE_BUTT +} out_mode_t; + +typedef enum { + MIPI_TX_WORK_MODE_LP = 0x0, /* LP(Low Power) work mode */ + MIPI_TX_WORK_MODE_HS = 0x1, /* HS(High Speed) work mode */ + + MIPI_TX_WORK_MODE_BUTT +} mipi_tx_work_mode_t; + +typedef enum { + BURST_MODE = 0x0, + NON_BURST_MODE_SYNC_PULSES = 0x1, + NON_BURST_MODE_SYNC_EVENTS = 0x2, + + VIDEO_DATA_MODE_BUTT +} video_mode_t; + +typedef enum { + OUT_FORMAT_RGB_16BIT = 0x0, /* DSI */ + OUT_FORMAT_RGB_18BIT = 0x1, + OUT_FORMAT_RGB_18BIT_LOOSELY = 0x2, + OUT_FORMAT_RGB_24BIT = 0x3, + OUT_FORMAT_YUV420_12BIT = 0x4, + OUT_FORMAT_YUV422_16BIT = 0x5, + + OUT_FORMAT_YUV420_8BIT_NORMAL = 0x6, /* CSI */ + OUT_FORMAT_YUV420_8BIT_LEGACY = 0x7, + OUT_FORMAT_YUV422_8BIT = 0x8, + OUT_FORMAT_RGB_888 = 0x9, + OUT_FORMAT_RAW_8BIT = 0xa, + OUT_FORMAT_RAW_10BIT = 0xb, + OUT_FORMAT_RAW_12BIT = 0xc, + OUT_FORMAT_RAW_14BIT = 0xd, + OUT_FORMAT_RAW_16BIT = 0xe, + OUT_FORMAT_BUTT +} out_format_t; + +typedef struct { + unsigned short vact; + unsigned short vbp; + unsigned short vfp; + + unsigned short hact; + unsigned short hbp; + unsigned short hfp; + + unsigned short hpw; + unsigned short vpw; +} sync_info_t; + +typedef enum { + MIPI_TX_CLK_LANE_CONTINUE = 0x0, + MIPI_TX_CLK_LANE_NON_CONTINUE = 0x1, + MIPI_TX_CLK_LANE_BUTT +} continue_mode_t; + +typedef struct { + unsigned int devno; /* device number */ + short lane_id[LANE_MAX_NUM]; /* lane_id: -1 - disable */ + out_mode_t out_mode; /* output mode: CSI/DSI_VIDEO/DSI_CMD */ + video_mode_t video_mode; + out_format_t out_format; + sync_info_t sync_info; + unsigned int phy_data_rate; /* Mbps */ + unsigned int pixel_clk; /* KHz */ + continue_mode_t clklane_continue_mode; +} combo_dev_cfg_t; + +typedef struct { + unsigned int devno; /* device number */ + mipi_tx_work_mode_t work_mode; /* work mode: low power mode, high speed mode. */ + unsigned char lp_clk_en; /* low power clock enable. */ + unsigned short data_type; /* data type */ + unsigned short cmd_size; + const unsigned char ATTRIBUTE *cmd; +} cmd_info_t; + +typedef struct { + unsigned int devno; /* device number */ + mipi_tx_work_mode_t work_mode; /* work mode: low power mode, high speed mode. */ + unsigned char lp_clk_en; /* low power clock enable. */ + unsigned short data_type; /* DSI data type */ + unsigned short data_param; /* data param,low 8 bit:first param.high 8 bit:second param, set 0 if not use */ + unsigned short get_data_size; /* read data size */ + unsigned char ATTRIBUTE *get_data; /* read data memory address, should malloc by user */ +} get_cmd_info_t; + +typedef struct { + unsigned int devno; + unsigned char pn_swap[MIPI_LANE_NUM_PER_DEV]; +} combo_dev_pn_swap_t; + +#define OT_MIPI_TX_IOC_MAGIC 't' + +#define OT_MIPI_TX_SET_DEV_CFG _IOW(OT_MIPI_TX_IOC_MAGIC, 0x01, combo_dev_cfg_t) +#define OT_MIPI_TX_SET_CMD _IOW(OT_MIPI_TX_IOC_MAGIC, 0x02, cmd_info_t) +#define OT_MIPI_TX_ENABLE _IO(OT_MIPI_TX_IOC_MAGIC, 0x03) +#define OT_MIPI_TX_GET_CMD _IOWR(OT_MIPI_TX_IOC_MAGIC, 0x04, get_cmd_info_t) +#define OT_MIPI_TX_DISABLE _IO(OT_MIPI_TX_IOC_MAGIC, 0x05) +#define OT_MIPI_TX_SET_PN_SWAP _IOW(OT_MIPI_TX_IOC_MAGIC, 0x06, combo_dev_pn_swap_t) + +#endif /* end of #ifndef OT_MIPI_TX_H */ diff --git a/kernel/mipi_tx/hi3519dv500/type.h b/kernel/mipi_tx/hi3519dv500/type.h new file mode 100644 index 00000000..799e8f42 --- /dev/null +++ b/kernel/mipi_tx/hi3519dv500/type.h @@ -0,0 +1,32 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ +#ifndef TYPE_H +#define TYPE_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +#ifndef NULL +#define NULL 0L +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif /* TYPE_H */ + diff --git a/kernel/security_subsys/hi3519dv500/Makefile b/kernel/security_subsys/hi3519dv500/Makefile new file mode 100644 index 00000000..d4cdb70a --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/Makefile @@ -0,0 +1,59 @@ +ifeq ($(PARAM_FILE), ) + PARAM_FILE:=../../../Makefile.param + include $(PARAM_FILE) +endif + +export CONFIG_SECURITY_SUBSYS_BUILD_ENV=sdk +export SECURITY_SUBSYS_WORK_ROOT_DIR=$(PWD) + +default: km_ko_build km_lib_build otp_ko_build otp_lib_build cipher_ko_build cipher_lib_build mbedtls_harden_build hardware_cryptodev_build + +clean: km_ko_clean km_lib_clean otp_ko_clean otp_lib_clean cipher_ko_clean cipher_lib_clean mbedtls_harden_clean hardware_cryptodev_clean + +cipher_ko_build: + @cd cipher/mkp && make + +cipher_ko_clean: + @cd cipher/mkp && make clean + +cipher_lib_build: cipher_ko_build + @cd cipher/mpi && make + +cipher_lib_clean: + @cd cipher/mpi && make clean + +km_ko_build: cipher_ko_build + @cd km/mkp && make + +km_lib_build: cipher_ko_build + @cd km/mpi && make + +km_ko_clean: + @cd km/mkp && make clean + +km_lib_clean: + @cd km/mpi && make clean + +otp_ko_build: cipher_ko_build + @cd otp/mkp && make + +otp_lib_build: cipher_ko_build + @cd otp/mpi && make + +otp_ko_clean: + @cd otp/mkp && make clean + +otp_lib_clean: + @cd otp/mpi && make clean + +mbedtls_harden_build: cipher_ko_build + @cd mbedtls_harden_adapt && make + +mbedtls_harden_clean: + @cd mbedtls_harden_adapt && make clean + +hardware_cryptodev_build: + @cd hardware_cryptodev && make -j + +hardware_cryptodev_clean: + @cd hardware_cryptodev && make clean \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/cipher/mkp/Makefile b/kernel/security_subsys/hi3519dv500/cipher/mkp/Makefile new file mode 100644 index 00000000..ef22776b --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/cipher/mkp/Makefile @@ -0,0 +1,104 @@ +#************************************************************************* +ifeq ($(PARAM_FILE), ) + PARAM_FILE:=../../../../../Makefile.param + include $(PARAM_FILE) +endif + +ifeq ($(CBB_PARAM_FILE), ) + CBB_PARAM_FILE:=../../../Makefile.param + include $(CBB_PARAM_FILE) +endif + +SECURITY_SUBSYS_DIR := $(PWD) +MKP_CFLAGS += -DCONFIG_CRYPTO_CHIP_HI3519DV500 + +# all source file in this module +SRCS:= + +# init +SRCS += crypto_drv_init.c +INIT_FILE := $(SECURITY_SUBSYS_DIR)/crypto_drv_init.c +INIT_INC := $(SECURITY_SUBSYS_DIR)/crypto_drv_init.h + +# IRQ +SRCS += crypto_drv_irq.c + +# Common +SRCS += ../../security_subsys_common/drv_code/crypto_drv_common.c + +# crypto_osal +SRCS += ../../crypto_osal_lib/crypto_osal_lib.c + +# DRV +SRCS += ../../security_subsys_common/drv_code/drv_trng.c +SRCS += ../../security_subsys_common/drv_code/drv_symc.c +SRCS += ../../security_subsys_common/drv_code/drv_symc_mac_hard.c +SRCS += ../../security_subsys_common/drv_code/drv_hash.c +SRCS += ../../security_subsys_common/drv_code/drv_pbkdf2_hard.c +SRCS += ../../security_subsys_common/drv_code/drv_pke.c +SRCS += ../../security_subsys_common/drv_code/drv_pke_ecc.c +SRCS += ../../security_subsys_common/drv_code/drv_pke_ecc_curve.c +SRCS += ../../security_subsys_common/drv_code/drv_pke_rsa.c + +# KAPI +SRCS += ../../security_subsys_common/kapi_code/kapi_init.c +SRCS += ../../security_subsys_common/kapi_code/kapi_trng.c +SRCS += ../../security_subsys_common/kapi_code/kapi_symc.c +SRCS += ../../security_subsys_common/kapi_code/kapi_hash.c +SRCS += ../../security_subsys_common/kapi_code/kapi_pke.c + +# Dispatch +SRCS += ../../security_subsys_common/dispatch_code/crypto_dispatch.c + +# TRNG HAL +SRCS += ../../security_subsys_common/hal_code/trng_v4/hal_trng.c + +# SPACC HAL +SRCS += ../../security_subsys_common/hal_code/spacc_v4/hal_symc.c +SRCS += ../../security_subsys_common/hal_code/spacc_v4/hal_hash.c + +# PKE HAL +SRCS += ../../security_subsys_common/hal_code/pke_v4/hal_pke.c + +# Include +MKP_CFLAGS += -I$(SECURITY_SUBSYS_DIR)/../../security_subsys_common/include/common_include +MKP_CFLAGS += -I$(SECURITY_SUBSYS_DIR)/../../security_subsys_common/include/drv_include +MKP_CFLAGS += -I$(SECURITY_SUBSYS_DIR)/../../security_subsys_common/include/hal_include +MKP_CFLAGS += -I$(SECURITY_SUBSYS_DIR)/../../security_subsys_common/include/ioctl_include +MKP_CFLAGS += -I$(SECURITY_SUBSYS_DIR)/../../security_subsys_common/include/kapi_include + +MKP_CFLAGS += -I$(SECURITY_SUBSYS_DIR) +MKP_CFLAGS += -I$(SECURITY_SUBSYS_DIR)/../.. +MKP_CFLAGS += -I$(SECURITY_SUBSYS_DIR)/../../crypto_osal_lib/ +MKP_CFLAGS += -I$(SECURITY_SUBSYS_DIR)/../../security_subsys_common/dispatch_code +MKP_CFLAGS += -I$(SECURITY_SUBSYS_DIR)/../../security_subsys_common/drv_code +MKP_CFLAGS += -I$(SECURITY_SUBSYS_DIR)/../../security_subsys_common/kapi_code + +# Debug +# MKP_CFLAGS += -DCRYPTO_LOG_LEVEL=4 +# MKP_CFLAGS += -DCRYPTO_CTR_TRACE_ENABLE +# MKP_CFLAGS += -DCRYPTO_NORMAL_TRACE_ENABLE +# MKP_CFLAGS += -DCRYPTO_CCM_TRACE_ENABLE +# MKP_CFLAGS += -DCRYPTO_GCM_TRACE_ENABLE +# MKP_CFLAGS += -DCRYPTO_DISPATCH_FUNC_TRACE_ENABLE +# MKP_CFLAGS += -DCRYPTO_KAPI_FUNC_TRACE_ENABLE +# MKP_CFLAGS += -DCRYPTO_HAL_FUNC_TRACE_ENABLE +# MKP_CFLAGS += -DCRYPTO_SYMC_HAL_NODE_DEBUG_ENABLE +# MKP_CFLAGS += -DCRYPTO_DRV_FUNC_TRACE_ENABLE +# MKP_CFLAGS += -DCRYPTO_MAC_TRACE_ENABLE + +MKP_CFLAGS += -DCRYPTO_CTR_NON_ALIGN_SUPPORT +MKP_CFLAGS += -DCRYPTO_SYMC_ADDR_NOT_ALIGN_SUPPORT + +SRCS_O := $(SRCS) + +#************************************************************************* +# release header +INC_FILE := $(wildcard ../../security_subsys_common/include/common_include/*.h) + +#************************************************************************* +TARGET := $(KO_PREFIX)_cipher + +#************************************************************************* +# compile linux or liteos +include $(MAKE_DRV_FILE) \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/cipher/mkp/crypto_drv_init.c b/kernel/security_subsys/hi3519dv500/cipher/mkp/crypto_drv_init.c new file mode 100644 index 00000000..e54d1745 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/cipher/mkp/crypto_drv_init.c @@ -0,0 +1,400 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "crypto_drv_init.h" + +#include +#include +#include +#include +#include + +#include "ot_osal.h" +#include "ot_common.h" + +#include "mm_ext.h" + +#include "crypto_common_macro.h" +#include "crypto_drv_common.h" +#include "crypto_dispatch.h" +#include "kapi_inner.h" +#include "kapi_hash.h" +#include "kapi_symc.h" +#include "hal_ca_misc_reg.h" + +#include "drv_common.h" +#include "drv_symc.h" +#include "crypto_drv_irq.h" + +#if defined(CRYPTO_UT_TEST_ENABLE) +#include "hal_test.h" +#include "drv_test.h" +#include "kapi_test.h" +#endif + +#define OT_PROC_SUPPORT +#define CRYPTO_MAX_MEMORY_POOL_NUM 100 +#define CRYPTO_DEV_CIPHER_NAME "soc_cipher" + +td_s32 g_spacc_tee_irq_num; +td_s32 g_spacc_ree_irq_num; +td_s32 g_pke_tee_irq_num; +td_s32 g_pke_ree_irq_num; + +static const char *alg_str[] = { "AES ", "SM4 " }; +static const char *mode_str[] = { "ECB", "CBC", "CTR", "OFB", "CFB", "CCM", "GCM", + "CBC-MAC", "CMAC"}; +static const char *key_len_str[] = { "64 ", "128 ", "256" }; + +static crypto_mutex g_mem_pool_lock; + +static osal_dev g_cipher_dev = {{0}}; + +/* ****** proc function begin ******* */ +#ifdef OT_PROC_SUPPORT +static td_void hex2str(td_u8 *buf, td_u32 buf_len) +{ + td_s32 i; + + if (buf == TD_NULL) { + return; + } + + for (i = 0; i < buf_len; i++) { + if (buf[i] <= 9) { /* 0~9 */ + buf[i] = buf[i] + '0'; + } else { + buf[i] = (buf[i] - 0x0A) + 'A'; /* 0x0A~0x0F */ + } + } + + return; +} + +td_s32 symc_proc_read(osal_proc_entry *s) +{ + td_u32 i; + crypto_symc_proc_info proc_symc_info = {0}; + + if (s == TD_NULL) { + crypto_log_err("Invalid pointer!\n"); + return TD_FAILURE; + } + + osal_seq_printf(s->seqfile, "\n[CIPHER] Version: [%s], Build Time[%s, %s]\n\n", OT_MPP_VERSION, __DATE__, __TIME__); + osal_seq_printf(s->seqfile, "\n---------------------------------------- cipher status ---------------------------" + "--------------------------------------\n"); + osal_seq_printf(s->seqfile, "chn_id status decrypt alg mode key_len addr in/out key_from " + "int_raw int_en int_status iv_out\n"); + + for (i = 0; i < CRYPTO_SYMC_HARD_CHANNEL_MAX; i++) { + if (((0x1 << i) & CRYPTO_SYMC_HARD_CHANNEL_MASK) == 0x00) { + continue; + } + (td_void)memset_s(&proc_symc_info, sizeof(proc_symc_info), 0, sizeof(proc_symc_info)); + drv_cipher_symc_get_proc_info(i, &proc_symc_info); + hex2str(proc_symc_info.iv, CRYPTO_AES_IV_SIZE + CRYPTO_AES_IV_SIZE); + + osal_seq_printf(s->seqfile, " %02u %s %s %s %s %s %08x/%08x " + "%s %u %u %u %s\n", + i, + proc_symc_info.open == 0 ? "close" : " open ", proc_symc_info.is_decrypt ? "DEC" : "ENC", + alg_str[proc_symc_info.alg], mode_str[proc_symc_info.mode], + key_len_str[proc_symc_info.key_len], proc_symc_info.in_node_head, + proc_symc_info.out_node_head, proc_symc_info.key_source ? "HW" : "SW", + proc_symc_info.int_raw, proc_symc_info.int_en, + proc_symc_info.int_status, proc_symc_info.iv); + } + + return TD_SUCCESS; +} + +static td_u32 symc_proc_init(td_void) +{ + osal_proc_entry *proc_entry = TD_NULL; + + proc_entry = osal_create_proc_entry("cipher", TD_NULL); + if (proc_entry == TD_NULL) { + crypto_print("cipher: can't create proc.\n"); + return TD_FAILURE; + } + proc_entry->read = symc_proc_read; + return TD_SUCCESS; +} + +static td_void symc_proc_deinit(td_void) +{ + osal_remove_proc_entry("cipher", TD_NULL); +} +#endif /* ****** proc function end ******* */ + +static int crypto_reg_map(td_void) +{ + td_s32 ret; + + /* SPACC Region. */ + ret = crypto_register_reg_map_region(REG_REGION_SPACC); + crypto_chk_return(ret != TD_SUCCESS, ret, "crypto_register_reg_map_region failed, ret is 0x%x\n", ret); + + /* CS MISC Region. */ + ret = crypto_register_reg_map_region(REG_REGION_CA_MISC); + crypto_chk_goto(ret != TD_SUCCESS, error_spacc_unmap, "crypto_register_reg_map_region failed, ret is 0x%x\n", ret); + + /* PKE Region. */ + ret = crypto_register_reg_map_region(REG_REGION_PKE); + crypto_chk_goto(ret != TD_SUCCESS, error_ca_misc_unmap, + "crypto_register_reg_map_region failed, ret is 0x%x\n", ret); + + /* TRNG Region. */ + ret = crypto_register_reg_map_region(REG_REGION_TRNG); + crypto_chk_goto(ret != TD_SUCCESS, error_pke_unmap, "crypto_register_reg_map_region failed, ret is 0x%x\n", ret); + + /* KM Region. */ + ret = crypto_register_reg_map_region(REG_REGION_KM); + crypto_chk_goto(ret != TD_SUCCESS, error_trng_unmap, "crypto_register_reg_map_region failed, ret is 0x%x\n", ret); + + return TD_SUCCESS; + +error_trng_unmap: + crypto_unregister_reg_map_region(REG_REGION_TRNG); +error_pke_unmap: + crypto_unregister_reg_map_region(REG_REGION_PKE); +error_ca_misc_unmap: + crypto_unregister_reg_map_region(REG_REGION_CA_MISC); +error_spacc_unmap: + crypto_unregister_reg_map_region(REG_REGION_SPACC); + return TD_FAILURE; +} + +static void crypto_reg_unmap(td_void) +{ + crypto_unregister_reg_map_region(REG_REGION_KM); + crypto_unregister_reg_map_region(REG_REGION_TRNG); + crypto_unregister_reg_map_region(REG_REGION_PKE); + crypto_unregister_reg_map_region(REG_REGION_CA_MISC); + crypto_unregister_reg_map_region(REG_REGION_SPACC); +} + +typedef struct crypto_compat_addr { + td_phys_addr_t phys_addr; + td_void *virt_addr; + td_u32 length; + td_bool is_used; +} crypto_compat_addr_t; + +static crypto_compat_addr_t g_crypto_mem_list[CRYPTO_MAX_MEMORY_POOL_NUM]; + +static td_void *crypto_malloc_ex(td_u32 size, crypto_mem_type mem_type, const td_char *buffer_name) +{ + td_u32 i; + td_s32 ret = TD_SUCCESS; + crypto_compat_addr_t *compat_addr = TD_NULL; + mm_malloc_param malloc_param = {0}; + + crypto_unused(mem_type); + + crypto_mutex_lock(&g_mem_pool_lock); + for (i = 0; i < CRYPTO_MAX_MEMORY_POOL_NUM; i++) { + if (g_crypto_mem_list[i].is_used == TD_FALSE) { + compat_addr = &g_crypto_mem_list[i]; + break; + } + } + if (compat_addr == TD_NULL) { + crypto_print("mem pool is Full!\n"); + goto exit_unlock; + } + malloc_param.buf_name = buffer_name; + malloc_param.size = size; + malloc_param.kernel_only = TD_TRUE; + ret = cmpi_mmz_malloc_nocache(&malloc_param, &compat_addr->phys_addr, &compat_addr->virt_addr); + if (ret != TD_SUCCESS) { + crypto_print("cmpi_mmz_malloc_nocache failed, ret is 0x%x\n", ret); + goto exit_unlock; + } +#if defined(CONFIG_MALLOC_DEBUG) + crypto_print("mmz_malloc virt_addr is 0x%lx, phys_addr is 0x%llx\n", (td_uintptr_t)compat_addr->virt_addr, + compat_addr->phys_addr); +#endif + compat_addr->is_used = TD_TRUE; + compat_addr->length = size; + crypto_mutex_unlock(&g_mem_pool_lock); + return compat_addr->virt_addr; +exit_unlock: + crypto_mutex_unlock(&g_mem_pool_lock); + return TD_NULL; +} + +static td_void crypto_free_ex(td_void *ptr) +{ + td_u32 i; + crypto_compat_addr_t *compat_addr = TD_NULL; + crypto_mutex_lock(&g_mem_pool_lock); + for (i = 0; i < CRYPTO_MAX_MEMORY_POOL_NUM; i++) { + if (g_crypto_mem_list[i].virt_addr == ptr && g_crypto_mem_list[i].is_used) { + compat_addr = &g_crypto_mem_list[i]; + break; + } + } + if (compat_addr == TD_NULL) { + goto exit_unlock; + } +#if defined(CONFIG_MALLOC_DEBUG) + crypto_print("mmz_free virt_addr is 0x%lx, phys_addr is 0x%llx\n", (td_uintptr_t)compat_addr->virt_addr, + compat_addr->phys_addr); +#endif + cmpi_mmz_free(compat_addr->phys_addr, compat_addr->virt_addr); + (td_void)memset_s(compat_addr, sizeof(crypto_compat_addr_t), 0, sizeof(crypto_compat_addr_t)); + + compat_addr->is_used = TD_FALSE; +exit_unlock: + crypto_mutex_unlock(&g_mem_pool_lock); +} + +static td_void crypto_mem_pool_release(td_void) +{ + td_u32 i; + for (i = 0; i < CRYPTO_MAX_MEMORY_POOL_NUM; i++) { + if (g_crypto_mem_list[i].is_used) { + crypto_print("mem pool idx[%u] is not free!\n", i); + crypto_free_ex(g_crypto_mem_list[i].virt_addr); + } + } +} + +static td_phys_addr_t inner_get_phys_addr(td_void *virt_addr) +{ + td_u32 i; + crypto_compat_addr_t *compat_addr = TD_NULL; + for (i = 0; i < CRYPTO_MAX_MEMORY_POOL_NUM; i++) { + compat_addr = &g_crypto_mem_list[i]; + if (virt_addr >= compat_addr->virt_addr && virt_addr < compat_addr->virt_addr + compat_addr->length) { + return compat_addr->phys_addr + (virt_addr - compat_addr->virt_addr); + } + } + return 0; +} + +static td_s32 crypto_drv_release(td_void *private_data) +{ + kapi_cipher_symc_process_release(); + kapi_cipher_hash_process_release(); + return TD_SUCCESS; +} + +static osal_fileops g_cipher_fops = { + .open = TD_NULL, + .write = TD_NULL, + .llseek = TD_NULL, + .release = crypto_drv_release, + .cmd_list = TD_NULL, + .cmd_cnt = 0, +}; + +static int ot_cipher_probe(struct platform_device *pdev) +{ + td_s32 ret = TD_SUCCESS; + crypto_drv_func drv_func_list = { 0 }; + + ret = crypto_mutex_init(&g_mem_pool_lock); + crypto_chk_return(ret != TD_SUCCESS, ret, "crypto_mutex_init failed\n"); + + /* Register Common Lib Function. */ + drv_func_list.malloc_coherent = crypto_malloc_ex; + drv_func_list.free_coherent = crypto_free_ex; + drv_func_list.get_phys_addr = inner_get_phys_addr; + + g_spacc_tee_irq_num = osal_platform_get_irq_byname(pdev, "spacc_tee"); + g_spacc_ree_irq_num = osal_platform_get_irq_byname(pdev, "spacc_ree"); + g_pke_tee_irq_num = osal_platform_get_irq_byname(pdev, "pke_tee"); + g_pke_ree_irq_num = osal_platform_get_irq_byname(pdev, "pke_ree"); + + (td_void)drv_cipher_register_func(&drv_func_list); + + ret = crypto_reg_map(); + crypto_chk_goto(ret != TD_SUCCESS, error_destroy_mutex, "crypto_reg_map failed.\n"); + + /* Create Device Node. */ + ret = strncpy_s(g_cipher_dev.name, sizeof(g_cipher_dev.name), CRYPTO_DEV_CIPHER_NAME, + sizeof(CRYPTO_DEV_CIPHER_NAME)); + crypto_chk_goto(ret != EOK, error_destroy_mutex, "strncpy failed. ret(%d).\n", ret); + + g_cipher_fops.cmd_list = crypto_get_ioctl_cmd_list(); + g_cipher_fops.cmd_cnt = crypto_get_ioctl_cmd_cnt(); + g_cipher_dev.fops = &g_cipher_fops; + + ret = osal_dev_register(&g_cipher_dev); + crypto_chk_goto(ret != TD_SUCCESS, error_destroy_mutex, "osal_dev_register failed. ret is 0x%x.\n", ret); + + /* KAPI Init. */ + ret = kapi_env_init(); + crypto_chk_goto(ret != TD_SUCCESS, error_unregister_dev, "kapi_env_init failed. ret is 0x%x.\n", ret); + +#ifdef OT_PROC_SUPPORT + ret = symc_proc_init(); + if (ret != TD_SUCCESS) { + kapi_env_deinit(); + crypto_print("symc_proc_init failed\n"); + goto error_unregister_dev; + } +#endif + +#if defined(CRYPTO_OS_INT_SUPPORT) + ret = crypto_irq_init(); + if (ret != TD_SUCCESS) { + symc_proc_deinit(); + kapi_env_deinit(); + crypto_print("crypto_irq_init failed\n"); + goto error_unregister_dev; + } +#endif + + crypto_print("load ot_cipher.ko ....OK!\n"); + return TD_SUCCESS; + +error_unregister_dev: + osal_dev_unregister(&g_cipher_dev); +error_destroy_mutex: + crypto_mutex_destroy(&g_mem_pool_lock); + crypto_print("load ot_cipher.ko failed!\n"); + return ret; +} + +static int ot_cipher_remove(struct platform_device *pdev) +{ + /* ****** proc function begin ******* */ +#ifdef OT_PROC_SUPPORT + symc_proc_deinit(); +#endif /* ****** proc function end ******* */ + + kapi_env_deinit(); +#if defined(CRYPTO_OS_INT_SUPPORT) + crypto_irq_deinit(); +#endif + crypto_unused(pdev); + osal_dev_unregister(&g_cipher_dev); + crypto_reg_unmap(); + crypto_mem_pool_release(); + crypto_mutex_destroy(&g_mem_pool_lock); + crypto_print("unload ot_cipher.ko ....OK!\n"); + return TD_SUCCESS; +} + +static const struct of_device_id g_ot_cipher_match[] = { + { .compatible = "vendor,cipher" }, + { }, +}; +MODULE_DEVICE_TABLE(of, g_ot_cipher_match); + +static struct platform_driver g_ot_cipher_driver = { + .probe = ot_cipher_probe, + .remove = ot_cipher_remove, + .driver = { + .name = "ot_cipher", + .of_match_table = g_ot_cipher_match, + }, +}; + +osal_module_platform_driver(g_ot_cipher_driver); +MODULE_LICENSE("GPL"); diff --git a/kernel/security_subsys/hi3519dv500/cipher/mkp/crypto_drv_init.h b/kernel/security_subsys/hi3519dv500/cipher/mkp/crypto_drv_init.h new file mode 100644 index 00000000..2ed31fad --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/cipher/mkp/crypto_drv_init.h @@ -0,0 +1,31 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef CRYPTO_INIT_H +#define CRYPTO_INIT_H + +#include "crypto_type.h" + +#define UMAP_SPACC_MINOR_BASE 53 +#define UMAP_KM_MINOR_BASE 54 +#define UMAP_PKE_MINOR_BASE 56 +#define UMAP_OTP_MINOR_BASE 57 + +/* SPACC. */ +td_s32 crypto_spacc_init(td_void); +td_void crypto_spacc_deinit(td_void); + +/* KM. */ +td_s32 crypto_km_init(td_void); +td_void crypto_km_deinit(td_void); + +/* PKE. */ +td_s32 crypto_pke_init(td_void); +td_void crypto_pke_deinit(td_void); + +/* OTP. */ +td_s32 crypto_otp_init(td_void); +td_void crypto_otp_deinit(td_void); + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/cipher/mkp/crypto_drv_irq.c b/kernel/security_subsys/hi3519dv500/cipher/mkp/crypto_drv_irq.c new file mode 100644 index 00000000..42ee4d21 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/cipher/mkp/crypto_drv_irq.c @@ -0,0 +1,204 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "crypto_drv_irq.h" +#include "crypto_hash_struct.h" +#include "hal_hash.h" +#include "hal_symc.h" +#include "hal_pke.h" + +#include "drv_hash.h" +#include "drv_inner.h" + +#include "crypto_drv_common.h" +#include "crypto_common_macro.h" + +#if defined(CRYPTO_OS_INT_SUPPORT) + +#define SPACC_REE_IRQ_NUM 60 +#define SPACC_TEE_IRQ_NUM 59 +#define PKE_REE_IRQ_NUM 62 +#define PKE_TEE_IRQ_NUM 61 + +#define IRQ_TIMEOUT_MS (1000 * 5) + +#define CONFIG_PKE_IRQ_ENABLE +#define CONFIG_SPACC_IRQ_ENABLE + +#ifdef CONFIG_PKE_IRQ_ENABLE +static osal_wait g_pke_wait_queue = { 0 }; +#endif + +#ifdef CONFIG_SPACC_IRQ_ENABLE +static osal_wait g_spacc_wait_queue = { 0 }; +#endif + +#ifdef CONFIG_SPACC_IRQ_ENABLE + +static int spacc_interrupt_irq(int irq, void *param) +{ + td_u32 i; + for (i = 0; i < CRYPTO_HASH_HARD_CHN_CNT; i++) { + if (((1 << i) & CRYPTO_HASH_HARD_CHN_MASK) == 0) { + continue; + } + if (hal_cipher_hash_done_try(i)) { + hal_cipher_hash_done_notify(i); + osal_wait_wakeup(&g_spacc_wait_queue); + return 0; + } + } + for (i = 1; i < CRYPTO_SYMC_HARD_CHANNEL_MAX; i++) { + if (((1 << i) & CRYPTO_SYMC_HARD_CHANNEL_MASK) == 0) { + continue; + } + + if (hal_cipher_symc_done_try(i) == TD_SUCCESS) { + hal_cipher_symc_done_notify(i); + osal_wait_wakeup(&g_spacc_wait_queue); + return 0; + } + } + return 0; +} +#endif + +static td_s32 spacc_irq_init(td_void) +{ +#ifdef CONFIG_SPACC_IRQ_ENABLE + td_s32 ret = TD_SUCCESS; + crypto_cpu_type cpu_type; + td_u32 i; + + /* IRQ Init. */ + ret = osal_wait_init(&g_spacc_wait_queue); + crypto_chk_return(ret != TD_SUCCESS, ret, "osal_wait_init failed, ret is 0x%x\n", ret); + + for (i = 0; i < CRYPTO_HASH_HARD_CHN_CNT; i++) { + if (((1 << i) & CRYPTO_HASH_HARD_CHN_MASK) == 0) { + continue; + } + (td_void)hal_cipher_hash_register_wait_func(i, &g_spacc_wait_queue, + (crypto_wait_timeout_interruptible)osal_wait_timeout_interruptible, IRQ_TIMEOUT_MS); + } + for (i = 0; i < CRYPTO_SYMC_HARD_CHANNEL_MAX; i++) { + if (((1 << i) & CRYPTO_SYMC_HARD_CHANNEL_MASK) == 0) { + continue; + } + (td_void)hal_cipher_symc_register_wait_func(i, &g_spacc_wait_queue, + (crypto_wait_timeout_interruptible)osal_wait_timeout_interruptible, IRQ_TIMEOUT_MS); + } + + cpu_type = crypto_get_cpu_type(); + if (cpu_type == CRYPTO_CPU_TYPE_ACPU) { + ret = osal_irq_request(g_spacc_ree_irq_num, spacc_interrupt_irq, TD_NULL, "nsec_spacc", TD_NULL); + crypto_chk_goto(ret != TD_SUCCESS, error_spacc_wait_deinit, "osal_irq_request failed, ret is 0x%x\n", ret); + } else if (cpu_type == CRYPTO_CPU_TYPE_SCPU) { + ret = osal_irq_request(g_spacc_tee_irq_num, spacc_interrupt_irq, TD_NULL, "sec_spacc", TD_NULL); + crypto_chk_goto(ret != TD_SUCCESS, error_spacc_wait_deinit, "osal_irq_request failed, ret is 0x%x\n", ret); + } + + return ret; +error_spacc_wait_deinit: + osal_wait_destroy(&g_spacc_wait_queue); + return ret; +#endif + return CRYPTO_SUCCESS; +} + +static td_void spacc_irq_deinit(td_void) +{ +#ifdef CONFIG_SPACC_IRQ_ENABLE + crypto_cpu_type cpu_type; + cpu_type = crypto_get_cpu_type(); + if (cpu_type == CRYPTO_CPU_TYPE_ACPU) { + osal_irq_free(g_spacc_ree_irq_num, TD_NULL); + } else if (cpu_type == CRYPTO_CPU_TYPE_SCPU) { + osal_irq_free(g_spacc_tee_irq_num, TD_NULL); + } + osal_wait_destroy(&g_spacc_wait_queue); +#endif +} + +#ifdef CONFIG_PKE_IRQ_ENABLE +static int pke_irq_handler(int a __attribute__((unused)), void *param __attribute__((unused))) +{ + if (hal_pke_done_try()) { + hal_pke_done_notify(); + osal_wait_wakeup(&g_pke_wait_queue); + return 0; + } + + return 0; +} +#endif + +static td_s32 pke_irq_init(td_void) +{ +#ifdef CONFIG_PKE_IRQ_ENABLE + td_s32 ret = TD_SUCCESS; + crypto_cpu_type cpu_type; + + /* IRQ Init. */ + ret = osal_wait_init(&g_pke_wait_queue); + crypto_chk_return(ret != TD_SUCCESS, ret, "osal_wait_init failed, ret is 0x%x\n", ret); + + (td_void)hal_cipher_pke_register_wait_func(&g_pke_wait_queue, + (crypto_wait_timeout_interruptible)osal_wait_timeout_interruptible, IRQ_TIMEOUT_MS); + + cpu_type = crypto_get_cpu_type(); + if (cpu_type == CRYPTO_CPU_TYPE_ACPU) { + ret = osal_irq_request(g_pke_ree_irq_num, pke_irq_handler, TD_NULL, "nsec_pke", TD_NULL); + crypto_chk_goto(ret != TD_SUCCESS, error_pke_wait_deinit, "osal_irq_request failed, ret is 0x%x\n", ret); + } else if (cpu_type == CRYPTO_CPU_TYPE_SCPU) { + ret = osal_irq_request(g_pke_tee_irq_num, pke_irq_handler, TD_NULL, "sec_pke", TD_NULL); + crypto_chk_goto(ret != TD_SUCCESS, error_pke_wait_deinit, "osal_irq_request failed, ret is 0x%x\n", ret); + } + + return ret; + +error_pke_wait_deinit: + osal_wait_destroy(&g_pke_wait_queue); + return ret; + +#endif + return 0; +} + +td_void pke_irq_deinit(td_void) +{ +#ifdef CONFIG_PKE_IRQ_ENABLE + crypto_cpu_type cpu_type; + cpu_type = crypto_get_cpu_type(); + if (cpu_type == CRYPTO_CPU_TYPE_ACPU) { + osal_irq_free(g_pke_ree_irq_num, TD_NULL); + } else if (cpu_type == CRYPTO_CPU_TYPE_SCPU) { + osal_irq_free(g_pke_tee_irq_num, TD_NULL); + } + osal_wait_destroy(&g_pke_wait_queue); +#endif +} + +td_s32 crypto_irq_init(td_void) +{ + td_s32 ret; + ret = spacc_irq_init(); + crypto_chk_return(ret != TD_SUCCESS, ret, "spacc_irq_init failed\n"); + + ret = pke_irq_init(); + crypto_chk_goto(ret != TD_SUCCESS, error_spacc_irq_deinit, "pke_irq_init failed\n"); + + return ret; +error_spacc_irq_deinit: + spacc_irq_deinit(); + return ret; +} + +td_void crypto_irq_deinit(td_void) +{ + spacc_irq_deinit(); + pke_irq_deinit(); +} + +#endif /* CRYPTO_OS_INT_SUPPORT */ \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/cipher/mkp/crypto_drv_irq.h b/kernel/security_subsys/hi3519dv500/cipher/mkp/crypto_drv_irq.h new file mode 100644 index 00000000..d0b95ee8 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/cipher/mkp/crypto_drv_irq.h @@ -0,0 +1,20 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef CRYPTO_IRQ_H +#define CRYPTO_IRQ_H + +#include "crypto_type.h" + +/* IRQ NUM */ +extern td_s32 g_spacc_tee_irq_num; +extern td_s32 g_spacc_ree_irq_num; +extern td_s32 g_pke_tee_irq_num; +extern td_s32 g_pke_ree_irq_num; + +td_s32 crypto_irq_init(td_void); + +td_void crypto_irq_deinit(td_void); + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/cipher/mkp/hal_ca_misc_reg.h b/kernel/security_subsys/hi3519dv500/cipher/mkp/hal_ca_misc_reg.h new file mode 100644 index 00000000..1ece55a1 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/cipher/mkp/hal_ca_misc_reg.h @@ -0,0 +1,19 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef HAL_CA_MISC_REG_H +#define HAL_CA_MISC_REG_H + +/* ! Define the crg control reg */ +#define CPU_ID_STAT (0x0018) + +typedef enum { + CPU_ID_AIDSP = 0x00000035, + CPU_ID_PCPU = 0x0000006a, + CPU_ID_SCPU = 0x000000a5, + CPU_ID_ACPU = 0x000000aa, + CPU_ID_INVALID = 0xffffffff +} ca_misc_cpu_id; + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/cipher/mpi/Makefile b/kernel/security_subsys/hi3519dv500/cipher/mpi/Makefile new file mode 100644 index 00000000..568a1b58 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/cipher/mpi/Makefile @@ -0,0 +1,31 @@ +ifeq ($(PARAM_FILE), ) + PARAM_FILE:=../../../../../Makefile.param + include $(PARAM_FILE) +endif + +ifeq ($(CBB_PARAM_FILE), ) + CBB_PARAM_FILE:=../../../Makefile.param + include $(CBB_PARAM_FILE) +endif + +MPI_SRC_DIR += $(PWD)/../../security_subsys_common/uapi_code +MPI_SRC_DIR += $(PWD)/../../security_subsys_common/ot_mpi +MPI_SRC_C := ot_mpi_hash.c ot_mpi_kdf.c ot_mpi_pke.c ot_mpi_symc.c ot_mpi_trng.c +MPI_SRC_C += uapi_hash.c uapi_kdf.c uapi_pke.c uapi_symc.c uapi_trng.c uapi_common.c +MPI_CFLAGS += -I$(PWD)/../../crypto_osal_lib +MPI_CFLAGS += -I$(PWD)/../../security_subsys_common/include/uapi_include +MPI_CFLAGS += -I$(PWD)/../../security_subsys_common/include/common_include +MPI_CFLAGS += -I$(PWD)/../../security_subsys_common/include/ioctl_include +MPI_CFLAGS += -I$(PWD)/../../security_subsys_common/ot_mpi_api +MPI_CFLAGS += -I$(PWD)/../.. +MPI_CFLAGS += -I$(REL_INC) + +MPI_CFLAGS += -DCONFIG_CRYPTO_CHIP_HI3519DV500 + +#************************************************************************* +# release header +INC_FILE := $(wildcard ../../security_subsys_common/ot_mpi_api/ot_mpi_cipher.h) + +LIB_NAME := ot_mpi_cipher + +include $(MAKE_MPI_FILE) \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/crypto_osal_lib/crypto_osal_lib.c b/kernel/security_subsys/hi3519dv500/crypto_osal_lib/crypto_osal_lib.c new file mode 100644 index 00000000..af9ea230 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/crypto_osal_lib/crypto_osal_lib.c @@ -0,0 +1,323 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "crypto_osal_adapt.h" +#include "crypto_drv_common.h" +#include "crypto_common_macro.h" +#include "hal_common.h" +#include "mmz.h" +#include "mm_ext.h" + +/* Register Operation. */ +typedef struct { + td_char *reg_region_name; + td_phys_addr_t reg_base_addr; + td_u32 reg_size; + td_void *virt_addr; + td_bool is_used; + reg_region_e region; +} reg_region_t; + +static reg_region_t g_reg_region_list[REG_REGION_NUM] = { + { + .reg_region_name = "SPACC", .reg_base_addr = SPACC_REG_BASE_ADDR, .reg_size = SPACC_REG_SIZE, + .virt_addr = TD_NULL, .is_used = TD_FALSE, .region = REG_REGION_SPACC + }, + { + .reg_region_name = "TRNG", .reg_base_addr = TRNG_REG_BASE_ADDR, .reg_size = TRNG_REG_SIZE, + .virt_addr = TD_NULL, .is_used = TD_FALSE, .region = REG_REGION_TRNG + }, + { + .reg_region_name = "PKE", .reg_base_addr = PKE_REG_BASE_ADDR, .reg_size = PKE_REG_SIZE, + .virt_addr = TD_NULL, .is_used = TD_FALSE, .region = REG_REGION_PKE + }, + { + .reg_region_name = "CA_MISC", .reg_base_addr = CA_MISC_REG_BASE_ADDR, .reg_size = CA_MISC_REG_SIZE, + .virt_addr = TD_NULL, .is_used = TD_FALSE, .region = REG_REGION_CA_MISC + }, + { + .reg_region_name = "KM", .reg_base_addr = KM_REG_BASE_ADDR, .reg_size = KM_REG_SIZE, + .virt_addr = TD_NULL, .is_used = TD_FALSE, .region = REG_REGION_KM + }, + { + .reg_region_name = "OTPC", .reg_base_addr = OTPC_BASE_ADDR, .reg_size = OTPC_ADDR_SIZE, + .virt_addr = TD_NULL, .is_used = TD_FALSE, .region = REG_REGION_OTPC + }, +}; + +td_s32 crypto_register_reg_map_region(reg_region_e region) +{ + reg_region_t *reg_region = TD_NULL; + if (region >= REG_REGION_NUM) { + crypto_log_err("Invalid region\n"); + return TD_FAILURE; + } + + reg_region = &g_reg_region_list[region]; + if (reg_region->region != region) { + crypto_log_err("Region is Mismatched!\n"); + return TD_FAILURE; + } + if (reg_region->is_used == TD_TRUE) { + crypto_print("Reg Region %s has remap!\n", reg_region->reg_region_name); + return TD_SUCCESS; + } + + reg_region->virt_addr = crypto_ioremap_nocache(reg_region->reg_base_addr, reg_region->reg_size); + if (reg_region->virt_addr == TD_NULL) { + crypto_log_err("crypto_ioremap_nocache failed\n"); + return TD_FAILURE; + } + + reg_region->is_used = TD_TRUE; + +#if defined(CONFIG_MEMORY_DEBUG) + crypto_print("Region %s map virt_addr 0x%llx to phys_addr 0x%x, size 0x%x Bytes\n", + reg_region->reg_region_name, reg_region->virt_addr, reg_region->reg_base_addr, reg_region->reg_size); +#endif + return TD_SUCCESS; +} + +void crypto_unregister_reg_map_region(reg_region_e region) +{ + reg_region_t *reg_region = TD_NULL; + + if (region >= REG_REGION_NUM) { + crypto_log_err("Invalid region\n"); + return; + } + + reg_region = &g_reg_region_list[region]; + if (reg_region->region != region) { + crypto_log_err("Region is Mismatched!\n"); + return; + } + if (reg_region->is_used == TD_FALSE) { + crypto_print("Reg Region %s has unmap!\n", reg_region->reg_region_name); + return; + } + +#if defined(CONFIG_MEMORY_DEBUG) + crypto_print("Region %s unmap virt_addr 0x%llx to phys_addr 0x%x, size 0x%x Bytes\n", + reg_region->reg_region_name, reg_region->virt_addr, reg_region->reg_base_addr, reg_region->reg_size); +#endif + reg_region->is_used = TD_FALSE; + crypto_iounmap(reg_region->virt_addr, reg_region->reg_size); + reg_region->virt_addr = TD_NULL; +} + + +#define REG_MAGIC_NUM 0xDEAFBEEF +td_u32 crypto_ex_reg_read(reg_region_e region, td_u32 offset) +{ + reg_region_t *reg_region = TD_NULL; + td_u32 value = 0; + + if (region >= REG_REGION_NUM) { + crypto_log_err("Invalid region\n"); + return REG_MAGIC_NUM; + } + + reg_region = &g_reg_region_list[region]; + if (reg_region->region != region) { + crypto_log_err("Region is Mismatched!\n"); + return REG_MAGIC_NUM; + } + if (reg_region->is_used == TD_FALSE) { + crypto_log_err("Reg Region %s is not remap!\n", reg_region->reg_region_name); + return REG_MAGIC_NUM; + } + if (offset >= reg_region->reg_size) { + crypto_log_err("offset 0x%x is not in reg region %s\n", offset, reg_region->reg_region_name); + return REG_MAGIC_NUM; + } + + value = crypto_reg_read((volatile td_void *)(reg_region->virt_addr + offset)); + + return value; +} + +td_void crypto_ex_reg_write(reg_region_e region, td_u32 offset, td_u32 value) +{ + reg_region_t *reg_region = TD_NULL; + + if (region >= REG_REGION_NUM) { + crypto_log_err("Invalid region\n"); + return; + } + + reg_region = &g_reg_region_list[region]; + if (reg_region->region != region) { + crypto_log_err("Region is Mismatched!\n"); + return; + } + if (reg_region->is_used == TD_FALSE) { + crypto_log_err("Reg Region %s is not remap!\n", reg_region->reg_region_name); + return; + } + if (offset >= reg_region->reg_size) { + crypto_log_err("offset 0x%x is not in reg region %s\n", offset, reg_region->reg_region_name); + return; + } + + crypto_reg_write((volatile td_void *)(reg_region->virt_addr + offset), value); +} + +unsigned long crypto_osal_get_phys_addr(const crypto_buf_attr *buf) +{ + return buf->phys_addr; +} + +td_bool crypto_data_buf_check(const crypto_buf_attr *buf_attr, td_u32 length) +{ + td_s32 ret; + if (buf_attr == TD_NULL) { + return TD_FALSE; + } + if (length == 0) { + return TD_TRUE; + } + + ret = ot_mmz_check_phys_addr(buf_attr->phys_addr, length); + if (ret != TD_SUCCESS) { + return TD_FALSE; + } + + return TD_TRUE; +} + +#if defined(CONFIG_PHYS_ADDR_DUMP_ENABLE) +void crypto_dump_phys_addr(const char *name, const td_phys_addr_t phys_addr, td_u32 data_len) +{ + td_u8 *buffer = crypto_ioremap_nocache(phys_addr, data_len); + if (buffer == TD_NULL) { + return; + } + crypto_dump_data(name, buffer, data_len); + crypto_iounmap(buffer, data_len); +} +#endif + +#define OTP_BASE_ADDR 0x101E0000 +#define OTP_REG_SIZE 0x100 +#define OTP_SM2_BIT_OFFSET 25 +#define OTP_SM3_BIT_OFFSET 26 +#define OTP_SM4_BIT_OFFSET 27 + +td_bool crypto_sm_support(crypto_sm_alg alg) +{ + td_u32 value = 0; + td_u32 bit_offset = 0; + td_void *addr = crypto_ioremap_nocache(OTP_BASE_ADDR, OTP_REG_SIZE); + crypto_chk_return(addr == TD_NULL, TD_FALSE, "ioremap failed\n"); + + value = crypto_reg_read(addr); + crypto_iounmap(addr, OTP_REG_SIZE); + + if (alg == CRYPTO_SM_ALG_SM2) { + bit_offset = OTP_SM2_BIT_OFFSET; + } else if (alg == CRYPTO_SM_ALG_SM3) { + bit_offset = OTP_SM3_BIT_OFFSET; + } else if (alg == CRYPTO_SM_ALG_SM4) { + bit_offset = OTP_SM4_BIT_OFFSET; + } else { + return TD_FALSE; + } + + if (value & (1 << bit_offset)) { + return TD_FALSE; + } + return TD_TRUE; +} + +#define CPU_ID_STAT (0x0018) +#define CRYPTO_CPU_ID_SCPU (0xa5) +#define CRYPTO_CPU_ID_ACPU (0xaa) + +crypto_cpu_type crypto_get_cpu_type(td_void) +{ + td_u32 cpu_id = ca_misc_reg_read(CPU_ID_STAT) & 0x00ff; + if (cpu_id == CRYPTO_CPU_ID_SCPU) { + return CRYPTO_CPU_TYPE_SCPU; + } else if (cpu_id == CRYPTO_CPU_ID_ACPU) { + return CRYPTO_CPU_TYPE_ACPU; + } + return CRYPTO_CPU_TYPE_INVALID; +} + +td_s32 crypto_virt_xor_phys_copy_to_phys(td_phys_addr_t dst_phys_addr, const td_u8 *a_virt_addr, + td_phys_addr_t b_phys_addr, td_u32 length) +{ + td_s32 ret; + td_u32 i; + td_u8 *b_virt_addr = TD_NULL; + td_u8 *dst_virt_addr = TD_NULL; + + b_virt_addr = cmpi_remap_nocache(b_phys_addr, length); + crypto_chk_goto_with_ret(b_virt_addr == TD_NULL, exit, TD_FAILURE, "cmpi_remap_nocache failed\n"); + + dst_virt_addr = cmpi_remap_nocache(dst_phys_addr, length); + crypto_chk_goto_with_ret(dst_virt_addr == TD_NULL, exit, TD_FAILURE, "cmpi_remap_nocache failed\n"); + +#if defined(CRYPTO_CTR_TRACE_ENABLE) + crypto_dump_data("a_virt_addr", a_virt_addr, length); + crypto_dump_data("b_virt_addr", b_virt_addr, length); +#endif + + for (i = 0; i < length; i++) { + dst_virt_addr[i] = a_virt_addr[i] ^ b_virt_addr[i]; + } + +#if defined(CRYPTO_CTR_TRACE_ENABLE) + crypto_dump_data("dst_virt_addr", dst_virt_addr, length); +#endif + ret = TD_SUCCESS; +exit: + if (b_virt_addr != TD_NULL) { + cmpi_unmap(b_virt_addr); + } + if (dst_virt_addr != TD_NULL) { + cmpi_unmap(dst_virt_addr); + } + return ret; +} + +td_s32 crypto_virt_copy_to_phys(td_phys_addr_t dst_phys_addr, const td_u8 *src_virt_addr, td_u32 length) +{ + td_s32 ret; + td_u8 *dst_virt_addr = TD_NULL; + + dst_virt_addr = cmpi_remap_nocache(dst_phys_addr, length); + crypto_chk_goto_with_ret(dst_virt_addr == TD_NULL, exit, TD_FAILURE, "cmpi_remap_nocache failed\n"); + + ret = memcpy_s(dst_virt_addr, length, src_virt_addr, length); + crypto_chk_goto_with_ret(ret != EOK, exit, TD_FAILURE, "memcpy_s failed\n"); + + ret = TD_SUCCESS; +exit: + if (dst_virt_addr != TD_NULL) { + cmpi_unmap(dst_virt_addr); + } + return ret; +} + + +td_s32 crypto_phys_copy_to_virt(td_u8 *dst_virt_addr, td_phys_addr_t src_phys_addr, td_u32 length) +{ + td_s32 ret; + td_u8 *src_virt_addr = TD_NULL; + + src_virt_addr = cmpi_remap_nocache(src_phys_addr, length); + crypto_chk_goto_with_ret(src_virt_addr == TD_NULL, exit, TD_FAILURE, "cmpi_remap_nocache failed\n"); + + ret = memcpy_s(dst_virt_addr, length, src_virt_addr, length); + crypto_chk_goto_with_ret(ret != EOK, exit, TD_FAILURE, "memcpy_s failed\n"); + + ret = TD_SUCCESS; +exit: + if (src_virt_addr != TD_NULL) { + cmpi_unmap(src_virt_addr); + } + return ret; +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/crypto_osal_lib/crypto_osal_lib.h b/kernel/security_subsys/hi3519dv500/crypto_osal_lib/crypto_osal_lib.h new file mode 100644 index 00000000..6b27fda7 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/crypto_osal_lib/crypto_osal_lib.h @@ -0,0 +1,80 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef CRYPTO_OSAL_LIB_H +#define CRYPTO_OSAL_LIB_H + +#include "ot_osal.h" +#include "crypto_type.h" +#include "crypto_platform.h" +#include "crypto_common_struct.h" + +#include + +unsigned long crypto_osal_get_phys_addr(const crypto_buf_attr *buf); +#define crypto_osal_put_phys_addr(...) +#define crypto_osal_mem_handle_get(fd, module_id) 1 +#define crypto_osal_mem_handle_put(...) + +#define crypto_getpid() osal_get_current_tgid() +#define crypto_gettid() osal_get_current_tid() + +/* Register Read&Write. */ +typedef enum { + REG_REGION_SPACC = 0x0, + REG_REGION_TRNG, + REG_REGION_PKE, + REG_REGION_CA_MISC, + REG_REGION_KM, + REG_REGION_OTPC, + REG_REGION_NUM +} reg_region_e; + +td_s32 crypto_get_random(td_u32 *randnum); + +td_s32 crypto_register_reg_map_region(reg_region_e region); + +void crypto_unregister_reg_map_region(reg_region_e region); + +td_u32 crypto_ex_reg_read(reg_region_e region, td_u32 offset); + +td_void crypto_ex_reg_write(reg_region_e region, td_u32 offset, td_u32 value); + +#define spacc_reg_read(offset) crypto_ex_reg_read(REG_REGION_SPACC, offset) +#define spacc_reg_write(offset, value) crypto_ex_reg_write(REG_REGION_SPACC, offset, value) + +#define trng_reg_read(offset) crypto_ex_reg_read(REG_REGION_TRNG, offset) +#define trng_reg_write(offset, value) crypto_ex_reg_write(REG_REGION_TRNG, offset, value) + +#define pke_reg_read(offset) crypto_ex_reg_read(REG_REGION_PKE, offset) +#define pke_reg_write(offset, value) crypto_ex_reg_write(REG_REGION_PKE, offset, value) + +#define km_reg_read(offset) crypto_ex_reg_read(REG_REGION_KM, offset) +#define km_reg_write(offset, value) crypto_ex_reg_write(REG_REGION_KM, offset, value) + +#define otpc_reg_read(offset) crypto_ex_reg_read(REG_REGION_OTPC, offset) +#define otpc_reg_write(offset, value) crypto_ex_reg_write(REG_REGION_OTPC, offset, value) + +#define ca_misc_reg_read(offset) crypto_ex_reg_read(REG_REGION_CA_MISC, offset) +#define ca_misc_reg_write(offset, value) crypto_ex_reg_write(REG_REGION_CA_MISC, offset, value) + +#define CRYPTO_EXPORT_SYMBOL EXPORT_SYMBOL + +typedef enum { + CRYPTO_OSAL_MMZ_TYPE, + CRYPTO_OSAL_NSSMMU_TYPE, + CRYPTO_OSAL_ERROR_TYPE, +} crypto_osal_mem_type; + +crypto_osal_mem_type crypto_osal_get_mem_type(td_void *mem_handle); + +#define crypto_osal_mem_phys(mem_handle) osal_mem_phys(mem_handle) +#define crypto_osal_mem_nssmmu_map(mem_handle) osal_mem_nssmmu_map(mem_handle, 0) +#define crypto_osal_mem_nssmmu_unmap(mem_handle, smmu_addr) osal_mem_nssmmu_unmap(mem_handle, smmu_addr, 0) + +#define crypto_memory_barrier() do { osal_mb(); osal_isb(); osal_dsb(); } while (0) + +#define CRYPTO_ERROR_ENV ERROR_ENV_LINUX + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/crypto_osal_lib/crypto_osal_user_lib.h b/kernel/security_subsys/hi3519dv500/crypto_osal_lib/crypto_osal_user_lib.h new file mode 100644 index 00000000..ba71969d --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/crypto_osal_lib/crypto_osal_user_lib.h @@ -0,0 +1,37 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef CRYPTO_OSAL_USER_LIB_H +#define CRYPTO_OSAL_USER_LIB_H + +#include +#include +#include +#include +#include +#include +#include "ot_type.h" + +#define crypto_print printf +#define crypto_log_err(fmt, ...) crypto_log_fmt("ERROR", fmt, ##__VA_ARGS__) +#define crypto_log_fmt(LOG_LEVEL_LABEL, fmt, ...) \ + crypto_print("[%s:%d]" LOG_LEVEL_LABEL ": " fmt, __func__, __LINE__, ##__VA_ARGS__) + +#define crypto_malloc(x) (((x) > 0) ? malloc((x)) : TD_NULL) +#define crypto_free(x) {if (((x) != TD_NULL)) free((x));} + +#define crypto_open open +#define crypto_close close +#define crypto_ioctl ioctl +#define crypto_km_ioctl ioctl +#define crypto_otp_ioctl ioctl + +typedef pthread_mutex_t crypto_mutex_t; +#define crypto_pthread_mutex_lock(lock) pthread_mutex_lock(lock) +#define crypto_pthread_mutex_unlock(lock) pthread_mutex_unlock(lock) +#define CRYPTO_PTHREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER + +#define CRYPTO_ERROR_ENV ERROR_ENV_LINUX + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/crypto_platform.h b/kernel/security_subsys/hi3519dv500/crypto_platform.h new file mode 100644 index 00000000..dbb73e8c --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/crypto_platform.h @@ -0,0 +1,45 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef CRYPTO_PLATFORM_H +#define CRYPTO_PLATFORM_H + +#define SOC_ID_CIPHER 0x6c + +/* Register Base Addr. */ +#define SEC_SUBSYS_BASE_ADDR 0x10100000 + +#define SPACC_REG_BASE_ADDR (SEC_SUBSYS_BASE_ADDR + 0xF0000) +#define SPACC_REG_SIZE (0x10000) + +#define TRNG_REG_BASE_ADDR (SEC_SUBSYS_BASE_ADDR + 0xEE000) +#define TRNG_REG_SIZE (0x1000) + +#define PKE_REG_BASE_ADDR (SEC_SUBSYS_BASE_ADDR + 0xEC000) +#define PKE_REG_SIZE (0x2000) + +#define CA_MISC_REG_BASE_ADDR (SEC_SUBSYS_BASE_ADDR + 0xE8000) +#define CA_MISC_REG_SIZE (0x1000) + +#define KM_REG_BASE_ADDR (SEC_SUBSYS_BASE_ADDR + 0xEA000) +#define KM_REG_SIZE (0x2000) + +#define OTPC_BASE_ADDR (SEC_SUBSYS_BASE_ADDR + 0xE0000) +#define OTPC_ADDR_SIZE (0x2000) + +/* symc hard channel num. */ +#define CRYPTO_SYMC_HARD_CHANNEL_MAX 3 +#define CRYPTO_SYMC_HARD_CHANNEL_MASK (0xFFFE) + +/* hash hard channel num. */ +#define CRYPTO_HASH_HARD_CHN_CNT 3 +#define CRYPTO_HASH_HARD_CHN_MASK (0xFFFE) + +#define CRYPTO_DRV_AAD_SIZE (4 * 1024) +#define CRYPTO_HASH_DRV_BUFFER_SIZE (128 * 1024) + +/* whether to enable the DFA function */ +#define CRYPTO_DRV_DFA_ENABLE + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/hardware_cryptodev/Makefile b/kernel/security_subsys/hi3519dv500/hardware_cryptodev/Makefile new file mode 100644 index 00000000..0ba04d3c --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/hardware_cryptodev/Makefile @@ -0,0 +1,37 @@ +ifeq ($(PARAM_FILE), ) + PARAM_FILE:=../../../../Makefile.param + include $(PARAM_FILE) +endif + +ifeq ($(CBB_PARAM_FILE), ) + CBB_PARAM_FILE:=../../Makefile.param + include $(CBB_PARAM_FILE) +endif + +ifeq ($(arch), ) + arch := arm64 +endif + +CRYPTO_HARDEN_DIR := $(PWD) +SUBSYS_DTR := $(CRYPTO_HARDEN_DIR)/.. + +SRCS := reg_aes.o +SRCS += reg_hash.o +SRCS += ot_reg.o + +MKP_CFLAGS += -DCONFIG_CRYPTO_CHIP_HI3519DV500 +MKP_CFLAGS += -I$(SUBSYS_DTR)/security_subsys_common/include/kapi_include +MKP_CFLAGS += -I$(SUBSYS_DTR)/security_subsys_common/drv_code +MKP_CFLAGS += -I$(SUBSYS_DTR)/security_subsys_common/include/drv_include +MKP_CFLAGS += -I$(SUBSYS_DTR)/security_subsys_common/include/hal_include +MKP_CFLAGS += -I$(SUBSYS_DTR)/security_subsys_common/include/common_include +MKP_CFLAGS += -I$(SUBSYS_DTR)/crypto_osal_lib +MKP_CFLAGS += -I$(SUBSYS_DTR) +MKP_CFLAGS += -I$(SUBSYS_DTR)/../../../osal/include/ +MKP_CFLAGS += -I$(SUBSYS_DTR)/../../../bsp/components/secure_c/include/ + +SRCS_O := $(SRCS) + +TARGET := $(KO_PREFIX)_hardware_cryptodev + +include $(MAKE_DRV_FILE) \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/hardware_cryptodev/ot_reg.c b/kernel/security_subsys/hi3519dv500/hardware_cryptodev/ot_reg.c new file mode 100644 index 00000000..03237ea9 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/hardware_cryptodev/ot_reg.c @@ -0,0 +1,428 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "ot_reg.h" +#include +#include +#include +#include +#include +#include + +#define TEE_DISABLE 0x42 +#define TEE_STATUS_OFFSET 0x12 + +static int aes_init(struct cipher_aes_ctx *ctx) +{ + int ret = TD_SUCCESS; + + ret = kapi_cipher_symc_init(); + cryptodev_chk_return(ret != TD_SUCCESS, ret, "kapi_cipher_symc_init failed\r\n"); + + ret = kapi_cipher_symc_create(&ctx->symc_handle, &ctx->cipher_attr); + cryptodev_chk_goto_with_ret(ret != TD_SUCCESS, cipher_deinit, ret, "kapi_cipher_symc_create failed\r\n"); + + ret = kapi_keyslot_create(&ctx->keyslot_handle, ctx->keyslot_type); + cryptodev_chk_goto_with_ret(ret != TD_SUCCESS, cipher_destroy, ret, "kapi_keyslot_create failed\r\n"); + + ret = kapi_cipher_symc_attach(ctx->symc_handle, ctx->keyslot_handle); + cryptodev_chk_goto_with_ret(ret != TD_SUCCESS, keyslot_destroy, ret, "kapi_cipher_symc_attach failed\r\n"); + + return 0; +keyslot_destroy: + kapi_keyslot_destroy(ctx->keyslot_handle); +cipher_destroy: + kapi_cipher_symc_destroy(ctx->symc_handle); +cipher_deinit: + kapi_cipher_symc_deinit(); + + return ret; +} + +static void aes_deinit(struct cipher_aes_ctx *ctx) +{ + if (ctx->keyslot_handle != INVALID_HANDLE) { + kapi_keyslot_destroy(ctx->keyslot_handle); + } + + if (ctx->symc_handle != INVALID_HANDLE) { + kapi_cipher_symc_destroy(ctx->symc_handle); + } + kapi_cipher_symc_deinit(); +} + +static td_s32 priv_check_tee_is_open(td_bool *is_open) +{ + td_s32 ret = TD_FAILURE; + td_u8 value = 0; + *is_open = TD_TRUE; + + ret = kapi_otp_read_byte(TEE_STATUS_OFFSET, &value); + cryptodev_chk_return(ret != TD_SUCCESS, ret, "kapi_otp_read_byte failed\r\n"); + + if (value == TEE_DISABLE) { + *is_open = TD_FALSE; + } + + return TD_SUCCESS; +} + +int inner_cipher_set_key(td_handle keyslot_handle, const u8 *key, unsigned int keylen) +{ + int ret; + td_handle klad; + td_bool tee_is_open = TD_FALSE; + km_klad_attr klad_attr = { + .key_cfg = { + .engine = KM_CRYPTO_ALG_AES, + .decrypt_support = TD_TRUE, + .encrypt_support = TD_TRUE + }, + .key_sec_cfg = { + .key_sec = KM_KLAD_SEC_DISABLE, + .master_only_enable = TD_TRUE, + .dest_buf_sec_support = TD_TRUE, + .dest_buf_non_sec_support = TD_FALSE, + .src_buf_sec_support = TD_TRUE, + .src_buf_non_sec_support = TD_FALSE + } + }; + + km_klad_clear_key clr_key = { + .key = (td_u8 *)key, + .key_size = keylen, + }; + + ret = priv_check_tee_is_open(&tee_is_open); + cryptodev_chk_return(ret != TD_SUCCESS, ret, "priv_check_tee_is_open failed\r\n"); + + if (tee_is_open == TD_TRUE) { + klad_attr.key_sec_cfg.key_sec = KM_KLAD_SEC_ENABLE; + klad_attr.key_sec_cfg.master_only_enable = TD_FALSE; + klad_attr.key_sec_cfg.dest_buf_sec_support = TD_FALSE; + klad_attr.key_sec_cfg.src_buf_sec_support = TD_FALSE; + klad_attr.key_sec_cfg.dest_buf_non_sec_support = TD_TRUE; + klad_attr.key_sec_cfg.src_buf_non_sec_support = TD_TRUE; + } + + ret = kapi_klad_create(&klad); + cryptodev_chk_return(ret != TD_SUCCESS, ret, "kapi_klad_create failed\r\n"); + + ret = kapi_klad_set_attr(klad, &klad_attr); + cryptodev_chk_goto_with_ret(ret != TD_SUCCESS, klad_destroy, ret, "kapi_klad_set_attr failed\r\n"); + + ret = kapi_klad_attach(klad, KM_KLAD_DEST_TYPE_MCIPHER, keyslot_handle); + cryptodev_chk_goto_with_ret(ret != TD_SUCCESS, klad_destroy, ret, "kapi_klad_attach failed\r\n"); + + ret = kapi_klad_set_clear_key(klad, &clr_key); + cryptodev_chk_goto_with_ret(ret != TD_SUCCESS, klad_detach, ret, "kapi_klad_set_clear_key failed\r\n"); +klad_detach: + kapi_klad_detach(klad, KM_KLAD_DEST_TYPE_MCIPHER, keyslot_handle); +klad_destroy: + kapi_klad_destroy(klad); + + return ret; +} + +static int crypto_set_config(struct skcipher_request *req, struct cipher_aes_ctx *ctx, + crypto_symc_work_mode work_mode, crypto_symc_alg cipher_alg) +{ + int ret; + crypto_symc_ctrl_t cipher_ctrl = {0}; + cipher_ctrl.symc_alg = cipher_alg; + cipher_ctrl.work_mode = work_mode; + + cipher_ctrl.symc_bit_width = CRYPTO_SYMC_BIT_WIDTH_128BIT; + cipher_ctrl.iv_change_flag = CRYPTO_SYMC_IV_DO_NOT_CHANGE; + cipher_ctrl.iv_length = AES_BLOCK_SIZE; + + switch (ctx->key_len) { + case AES_128_KEY_SIZE: + cipher_ctrl.symc_key_length = CRYPTO_SYMC_KEY_128BIT; + break; + case AES_192_KEY_SIZE: + cipher_ctrl.symc_key_length = CRYPTO_SYMC_KEY_192BIT; + break; + case AES_256_KEY_SIZE: + cipher_ctrl.symc_key_length = CRYPTO_SYMC_KEY_256BIT; + break; + default: + cprint("the key length is %d, not support yet\r\n", ctx->key_len); + return -1; + } + + ret = memcpy_s(cipher_ctrl.iv, sizeof(cipher_ctrl.iv), req->iv, AES_BLOCK_SIZE); + cryptodev_chk_return(ret != EOK, ret, "set iv failed\r\n"); + + ret = kapi_cipher_symc_set_config(ctx->symc_handle, &cipher_ctrl); + cryptodev_chk_return(ret != TD_SUCCESS, ret, "kapi_cipher_symc_set_config failed\r\n"); + + return ret; +} + +static int aead_ivformat_trans(struct aead_request *req, crypto_symc_work_mode work_mode, + crypto_symc_ctrl_t *cipher_ctrl, td_bool direct) +{ + int ret; + int offset = (work_mode == CRYPTO_SYMC_WORK_MODE_CCM) ? 1 : 0; + + if (work_mode == CRYPTO_SYMC_WORK_MODE_CCM && (req->iv[0] < 1 || req->iv[0] > 7)) { // iv[0] limited in [1, 7] + cprint("CCM mode iv size range from [7, 13]\r\n"); + return -EINVAL; + } + + cipher_ctrl->iv_length = offset ? 14 - req->iv[0] : crypto_aead_ivsize(crypto_aead_reqtfm(req)); // ccm base iv 14 + + if (direct == TD_TRUE) { + ret = memcpy_s(cipher_ctrl->iv, sizeof(cipher_ctrl->iv), req->iv + offset, cipher_ctrl->iv_length); + cryptodev_chk_return(ret != TD_SUCCESS, ret, "ex iv memcpy_s failed\r\n"); + } else { + ret = memcpy_s(req->iv + offset, cipher_ctrl->iv_length, cipher_ctrl->iv, cipher_ctrl->iv_length); + cryptodev_chk_return(ret != TD_SUCCESS, ret, "ex iv memcpy_s failed\r\n"); + } + + return ret; +} + +static int crypto_set_config_ex(struct aead_request *req, struct cipher_aes_ctx *ctx, + crypto_symc_work_mode work_mode, crypto_symc_alg cipher_alg) +{ + int ret; + crypto_symc_ctrl_t cipher_ctrl = {0}; + crypto_symc_config_aes_ccm_gcm ctrl_aes_ex = { + .aad_len = req->assoclen, + .tag_len = ctx->authsize, + .data_len = ctx->cryptlen, + .aad_buf.virt_addr = ctx->aad_mem_virt + }; + + cipher_ctrl.symc_alg = cipher_alg; + cipher_ctrl.work_mode = work_mode; + cipher_ctrl.symc_bit_width = CRYPTO_SYMC_BIT_WIDTH_128BIT; + cipher_ctrl.iv_change_flag = (work_mode == CRYPTO_SYMC_WORK_MODE_CCM) ? + CRYPTO_SYMC_CCM_IV_CHANGE_START : CRYPTO_SYMC_GCM_IV_CHANGE_START; + cipher_ctrl.param = (td_void *)&ctrl_aes_ex; + + switch (ctx->key_len) { + case AES_128_KEY_SIZE: + cipher_ctrl.symc_key_length = CRYPTO_SYMC_KEY_128BIT; + break; + case AES_192_KEY_SIZE: + cipher_ctrl.symc_key_length = CRYPTO_SYMC_KEY_192BIT; + break; + case AES_256_KEY_SIZE: + cipher_ctrl.symc_key_length = CRYPTO_SYMC_KEY_256BIT; + break; + default: + cprint("the key length is %d, not support yet\r\n", ctx->key_len); + return -1; + } + + ret = aead_ivformat_trans(req, work_mode, &cipher_ctrl, TD_TRUE); + cryptodev_chk_return(ret != TD_SUCCESS, ret, "inner_ivformat_transto_drv failed\r\n"); + + // copy src aad data to drv + sg_copy_buffer(req->src, sg_nents(req->src), ctx->aad_mem_virt, req->assoclen, 0, true); + + ret = kapi_cipher_symc_set_config(ctx->symc_handle, &cipher_ctrl); + cryptodev_chk_return(ret != TD_SUCCESS, ret, "ot_drv_cipher_set_cfg failed\r\n"); + return ret; +} + +static int cryptodev_cipher_crypto(struct cipher_aes_ctx *ctx, unsigned int len, cipher_param *param) +{ + int ret = TD_SUCCESS; + crypto_symc_work_mode mode = param->work_mode; + crypt_flag flag = param->flag; + unsigned int remain_len = len % AES_BLOCK_SIZE; + crypto_buf_attr src_buf = { + .phys_addr = ctx->mem_phys, + .virt_addr = (void *)ctx->mem_virt + }; + crypto_buf_attr dst_buf = { + .phys_addr = ctx->mem_phys, + .virt_addr = (void *)ctx->mem_virt + }; + + if (mode != CRYPTO_SYMC_WORK_MODE_CTR && mode != CRYPTO_SYMC_WORK_MODE_GCM && + mode != CRYPTO_SYMC_WORK_MODE_CCM && remain_len) { + cprint("The value to be calculated must be aligned with 16 bytes."); + return -EINVAL; + } + + if (len != 0 || mode == CRYPTO_SYMC_WORK_MODE_GCM || mode == CRYPTO_SYMC_WORK_MODE_CCM) { + if (flag == OT_DRV_ENCRYPT) { + ret = kapi_cipher_symc_encrypt(ctx->symc_handle, &src_buf, &dst_buf, len); + } else { + ret = kapi_cipher_symc_decrypt(ctx->symc_handle, &src_buf, &dst_buf, len); + } + cryptodev_chk_return(ret != TD_SUCCESS, ret, "ot_drv_cipher_encrypt failed\r\n"); + } + + return ret; +} + +int inner_aes_crypt(struct skcipher_request *req, cipher_param *param) +{ + int ret; + unsigned int len = 0; + unsigned int total = 0; + crypto_symc_ctrl_t cipher_ctrl = {0}; + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct cipher_aes_ctx *ctx = crypto_skcipher_ctx(tfm); + + struct scatterlist *src = req->src; + struct scatterlist *dst = req->dst; + + if (ctx->is_init == 0) { + cprint("aes_crypt failed. init first\r\n"); + return -EINVAL; + } + + ret = aes_init(ctx); + cryptodev_chk_return(ret != TD_SUCCESS, ret, "inner_aes_init failed\r\n"); + + ret = inner_cipher_set_key(ctx->keyslot_handle, ctx->key, ctx->key_len); + cryptodev_chk_goto_with_ret(ret != TD_SUCCESS, aes_deinit, ret, "inner_cipher_set_key failed\r\n"); + + ret = crypto_set_config(req, ctx, param->work_mode, param->cipher_alg); + cryptodev_chk_goto_with_ret(ret != TD_SUCCESS, aes_deinit, ret, "crypto_set_config failed\r\n"); + + while (total < req->cryptlen) { + len = min(req->cryptlen - total, (unsigned int)CIPHER_BUFF_LENGTH); + sg_copy_buffer(src, sg_nents(src), ctx->mem_virt, len, total, true); + crypto_flush_dcache(ctx->mem_virt, ctx->mem_phys, len); + + ret = cryptodev_cipher_crypto(ctx, len, param); + cryptodev_chk_goto_with_ret(ret != TD_SUCCESS, aes_deinit, ret, "ot_cipher_crypt failed\r\n"); + + sg_copy_buffer(dst, sg_nents(dst), ctx->mem_virt, len, total, false); + total += len; + } + + ret = kapi_cipher_symc_get_config(ctx->symc_handle, &cipher_ctrl); + cryptodev_chk_goto_with_ret(ret != TD_SUCCESS, aes_deinit, ret, "kapi_cipher_symc_get_config failed\r\n"); + + ret = memcpy_s(req->iv, AES_BLOCK_SIZE, cipher_ctrl.iv, sizeof(cipher_ctrl.iv)); + cryptodev_chk_goto_with_ret(ret != EOK, aes_deinit, ret, "memcpy_s iv failed\r\n"); +aes_deinit: + (void)memset_s(cipher_ctrl.iv, sizeof(cipher_ctrl.iv), 0, sizeof(cipher_ctrl.iv)); + (void)memset_s(ctx->mem_virt, CIPHER_BUFF_LENGTH, 0, CIPHER_BUFF_LENGTH); + aes_deinit(ctx); + + return ret; +} + +int inner_aes_aead_crypt(struct aead_request *req, cipher_param *param) +{ + int ret; + unsigned int len = 0; + unsigned int total = 0; + u8 tag[MAX_TAG_LEN] = {0}; + u8 verify_tag[MAX_TAG_LEN] = {0}; + unsigned int nbytes = req->cryptlen; + struct cipher_aes_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req)); + unsigned int tag_len = ctx->authsize; + + if (ctx->is_init == 0) { + cprint("crypto need init first!\r\n"); + return -1; + } + + ctx->cryptlen = nbytes; + if (param->flag == OT_DRV_DECRYPT) { + if (nbytes < tag_len) { + cprint("crypt data's length is invalid\r\n"); + return -1; + } + ctx->cryptlen = (nbytes -= tag_len); + // store tag to verify decryt result + sg_copy_buffer(req->src, sg_nents(req->src), verify_tag, tag_len, req->assoclen + nbytes, true); + } + + ret = aes_init(ctx); + cryptodev_chk_return(ret != TD_SUCCESS, ret, "inner_aes_init failed\r\n"); + + ret = inner_cipher_set_key(ctx->keyslot_handle, ctx->key, ctx->key_len); + cryptodev_chk_goto_with_ret(ret != TD_SUCCESS, aes_deinit, ret, "inner_cipher_set_key failed\r\n"); + + ret = crypto_set_config_ex(req, ctx, param->work_mode, param->cipher_alg); + cryptodev_chk_goto_with_ret(ret != TD_SUCCESS, aes_deinit, ret, "crypto_set_config_ex failed\r\n"); + + do { + len = min(nbytes - total, (unsigned int)CIPHER_BUFF_LENGTH); + sg_copy_buffer(req->src, sg_nents(req->src), ctx->mem_virt, len, total + req->assoclen, true); + crypto_flush_dcache(ctx->mem_virt, ctx->mem_phys, len); + + ret = cryptodev_cipher_crypto(ctx, len, param); + cryptodev_chk_goto_with_ret(ret != TD_SUCCESS, aes_deinit, ret, "ot_cipher_crypt failed\r\n"); + + sg_copy_buffer(req->dst, sg_nents(req->dst), ctx->mem_virt, len, total + req->assoclen, false); + total += len; + } while (total < nbytes); + + ret = kapi_cipher_symc_get_tag(ctx->symc_handle, tag, sizeof(tag)); + cryptodev_chk_goto_with_ret(ret != TD_SUCCESS, aes_deinit, ret, "ot_drv_cipher_get_tag failed\r\n"); + + if (param->flag == OT_DRV_ENCRYPT) { + sg_copy_buffer(req->dst, sg_nents(req->dst), tag, tag_len, total + req->assoclen, false); + } else { + ret = memcmp(tag, verify_tag, tag_len); + cryptodev_chk_goto_with_ret(ret != TD_SUCCESS, aes_deinit, -1, "decrypt tag not right\r\n"); + } +aes_deinit: + (void)memset_s(ctx->mem_virt, CIPHER_BUFF_LENGTH, 0, CIPHER_BUFF_LENGTH); + aes_deinit(ctx); + + return ret; +} + +static int __init hardware_crypto_init(void) +{ + int ret = osal_mutex_init(&hash_channel_lock); + cryptodev_chk_return(ret != TD_SUCCESS, -EFAULT, "hash_channel_lock init failed\r\n"); + + ret = osal_mutex_init(&aes_lock); + cryptodev_chk_goto_with_ret(ret != TD_SUCCESS, hash_lock_destroy, -EFAULT, "aes_lock init failed\r\n"); + + ret = crypto_register_skciphers(aes_algs, ARRAY_SIZE(aes_algs)); + cryptodev_chk_goto_with_ret(ret != TD_SUCCESS, aes_lock_destroy, -EFAULT, "crypto_register_alg failed\r\n"); + + ret = crypto_register_shashes(shash_alges, ARRAY_SIZE(shash_alges)); + cryptodev_chk_goto_with_ret(ret != TD_SUCCESS, unreg_skcipher, -EFAULT, "crypto_register_shashes failed\r\n"); + + ret = crypto_register_aeads(aes_aead_algs, ARRAY_SIZE(aes_aead_algs)); + cryptodev_chk_goto_with_ret(ret != TD_SUCCESS, unreg_hash, ret, "crypto_register_shashes failed\r\n"); + + printk(KERN_INFO "hardware algorithm registered\n"); + return TD_SUCCESS; +unreg_hash: + crypto_unregister_shashes(shash_alges, ARRAY_SIZE(shash_alges)); +unreg_skcipher: + crypto_unregister_skciphers(aes_algs, ARRAY_SIZE(aes_algs)); +aes_lock_destroy: + osal_mutex_destroy(&aes_lock); +hash_lock_destroy: + osal_mutex_destroy(&hash_channel_lock); + return -EINVAL; +} + +static void __exit hardware_crypto_exit(void) +{ + crypto_unregister_aeads(aes_aead_algs, ARRAY_SIZE(aes_aead_algs)); + crypto_unregister_skciphers(aes_algs, ARRAY_SIZE(aes_algs)); + crypto_unregister_shashes(shash_alges, ARRAY_SIZE(shash_alges)); + osal_mutex_destroy(&hash_channel_lock); + osal_mutex_destroy(&aes_lock); + printk(KERN_INFO "hardware algorithm unregistered\n"); +} + +int hard_crypto_debug = 0; +module_param(hard_crypto_debug, int, 0644); +MODULE_PARM_DESC(hard_crypto_debug, "0: normal, other: debug"); + +module_init(hardware_crypto_init); +module_exit(hardware_crypto_exit); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("component of hardware crypto algorithm"); \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/hardware_cryptodev/ot_reg.h b/kernel/security_subsys/hi3519dv500/hardware_cryptodev/ot_reg.h new file mode 100644 index 00000000..23188e0b --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/hardware_cryptodev/ot_reg.h @@ -0,0 +1,130 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef OT_REG_H +#define OT_REG_H + +#include +#include +#include +#include +#include +#include "mm_ext.h" +#include "kapi_symc.h" +#include "kapi_km.h" +#include "kapi_otp.h" +#include "kapi_hash.h" + +#define AES_MIN_KEY_SIZE 16 +#define AES_MAX_KEY_SIZE 32 +#define AES_BLOCK_SIZE 16 + +#define AES_128_KEY_SIZE 16 +#define AES_192_KEY_SIZE 24 +#define AES_256_KEY_SIZE 32 +#define GCM_IV_SIZE 12 +#define MAX_TAG_LEN 16 +#define MAX_AAD_LEN (8 * 1024) + +#define CIPHER_BUFF_LENGTH (64 * 1024) + +#define INVALID_HANDLE 0xffffffff + +/* debug flag */ +extern int hard_crypto_debug; + +#define cprint(format, ...) \ + do { \ + if (hard_crypto_debug) \ + printk("ERRO hard crypto" "%s[%u] (%s:%u): " format "\n", \ + current->comm, current->pid, \ + __func__, __LINE__, ##__VA_ARGS__); \ + } while (0) + +#define cryptodev_chk_return(cond, err_ret, fmt, ...) do { \ + if (cond) { \ + cprint(fmt, ##__VA_ARGS__); \ + return err_ret; \ + } \ +} while (0) + +#define cryptodev_chk_goto_with_ret(cond, label, err_ret, fmt, ...) do { \ + if (cond) { \ + cprint(fmt, ##__VA_ARGS__); \ + ret = err_ret; \ + goto label; \ + } \ +} while (0) + +#ifdef crypto_tarce_debug +#define enter_func() printk("[thread id: %d ]enter func %s ========>\r\n", current->pid, __func__) +#define exit_func() printk("[thread id: %d ]exit func %s <=========\r\n", current->pid, __func__) +#else +#define enter_func() +#define exit_func() +#endif + +typedef enum { + OT_DRV_ENCRYPT = 0, + OT_DRV_DECRYPT = 1 +} crypt_flag; + +typedef struct { + td_u32 length[2]; + td_u32 state[CRYPTO_HASH_RESULT_SIZE_MAX_IN_WORD]; + td_u32 tail_len; + crypto_hash_type hash_type; + td_u8 tail[CRYPTO_HASH_BLOCK_SIZE_MAX]; +} hardware_hash_clone_ctx; + +struct hash_ctx { + td_handle hash_handle; + crypto_hash_attr hash_attr; + unsigned int digest_lenth; + td_bool is_init; + hardware_hash_clone_ctx clone_ctx; +}; + +typedef struct { + crypto_symc_work_mode work_mode; + crypto_symc_alg cipher_alg; + crypt_flag flag; +} cipher_param; + +// crypto context which contains harden info +struct cipher_aes_ctx { + unsigned int key_len; + td_handle symc_handle; + td_handle keyslot_handle; + td_handle klad_handle; + td_phys_addr_t mem_phys; + td_void *mem_virt; + td_phys_addr_t aad_mem_phys; + td_void *aad_mem_virt; + unsigned int cryptlen; + crypto_symc_attr cipher_attr; + km_keyslot_type keyslot_type; + unsigned int is_init; + unsigned int authsize; + u8 key[AES_MAX_KEY_SIZE]; +}; + +extern struct skcipher_alg aes_algs[2]; +extern struct shash_alg shash_alges[3]; +extern struct aead_alg aes_aead_algs[2]; +extern osal_mutex hash_channel_lock; +extern osal_mutex aes_lock; + +int inner_cipher_set_key(unsigned int keyslot_handle, const u8 *key, unsigned int keylen); + +int inner_aes_crypt(struct skcipher_request *req, cipher_param *param); + +int inner_aes_aead_crypt(struct aead_request *req, cipher_param *param); + +static inline void crypto_flush_dcache(void *kvirt, unsigned long phys_addr, unsigned long length) +{ + osal_dcache_region_wb(kvirt, phys_addr, length); +} + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/hardware_cryptodev/reg_aes.c b/kernel/security_subsys/hi3519dv500/hardware_cryptodev/reg_aes.c new file mode 100644 index 00000000..0f505f7f --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/hardware_cryptodev/reg_aes.c @@ -0,0 +1,454 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "ot_reg.h" +#include +#include +#include +#include +#include +#include +#include + +osal_mutex aes_lock; + +static int alg_name_2_workmode(const char *alg_name, crypto_symc_work_mode *mode) +{ + if (!strcmp(alg_name, "cbc(aes)")) { + *mode = CRYPTO_SYMC_WORK_MODE_CBC; + } else if (!strcmp(alg_name, "ctr(aes)")) { + *mode = CRYPTO_SYMC_WORK_MODE_CTR; + } else if (!strcmp(alg_name, "gcm(aes)")) { + *mode = CRYPTO_SYMC_WORK_MODE_GCM; + } else if (!strcmp(alg_name, "ccm(aes)")) { + *mode = CRYPTO_SYMC_WORK_MODE_CCM; + } else { + *mode = CRYPTO_SYMC_WORK_MODE_INVALID; + cprint("the %s mode is not support now!\r\n", alg_name); + return -EFAULT; + } + return 0; +} + +static int normal_aes_init(struct crypto_tfm *tfm) +{ + // init transform + int ret; + const mm_malloc_param mmz_param = { + .size = CIPHER_BUFF_LENGTH, + .kernel_only = TD_FALSE + }; + + const char *alg_name = crypto_tfm_alg_name(tfm); + struct cipher_aes_ctx *ctx = crypto_tfm_ctx(tfm); + ret = memset_s(ctx, sizeof(struct cipher_aes_ctx), 0, sizeof(struct cipher_aes_ctx)); + cryptodev_chk_return(ret != TD_SUCCESS, ret, "normal_aes_init failed\r\n"); + + ctx->cipher_attr.symc_type = CRYPTO_SYMC_TYPE_NORMAL; + ctx->cipher_attr.symc_alg = CRYPTO_SYMC_ALG_AES; + ctx->cipher_attr.is_long_term = TD_TRUE; + ctx->keyslot_type = KM_KEYSLOT_TYPE_MCIPHER; + ctx->keyslot_handle = INVALID_HANDLE; + ctx->symc_handle = INVALID_HANDLE; + + ret = alg_name_2_workmode(alg_name, &ctx->cipher_attr.work_mode); + cryptodev_chk_return(ret != TD_SUCCESS, -EFAULT, "input alg name not support yet\r\n"); + + ret = cmpi_mmz_malloc_cached(&mmz_param, &ctx->mem_phys, (td_void **)&ctx->mem_virt); + cryptodev_chk_return(ret != TD_SUCCESS, -EFAULT, "cmpi_mmz_malloc_cached failed\r\n"); + cryptodev_chk_return(ctx->mem_virt == NULL, -EFAULT, "buff piont to null addr!\r\n"); + ctx->is_init = 1; + + return 0; +} + +static void normal_aes_deinit(struct crypto_tfm *tfm) +{ + // destroy transform + struct cipher_aes_ctx *ctx = crypto_tfm_ctx(tfm); + + if (ctx->is_init == 1) { + (void)memset_s(ctx->mem_virt, CIPHER_BUFF_LENGTH, 0, CIPHER_BUFF_LENGTH); + cmpi_mmz_free(ctx->mem_phys, ctx->mem_virt); + (void)memset_s(ctx, sizeof(struct cipher_aes_ctx), 0, sizeof(struct cipher_aes_ctx)); + ctx->is_init = 0; + } +} + +static int normal_aes_set_key(struct crypto_tfm *tfm, const u8 *key, + unsigned int keylen) +{ + struct cipher_aes_ctx *ctx = crypto_tfm_ctx(tfm); + + if (ctx->is_init == 0) { + cprint("set_key failed. init first\r\n"); + return -EINVAL; + } + + if (key == NULL || keylen > AES_MAX_KEY_SIZE) { + cprint("key length is overflow\r\n"); + return -EINVAL; + } + + ctx->key_len = keylen; + cryptodev_chk_return(memcpy_s(ctx->key, sizeof(ctx->key), key, keylen) != EOK, + -EFAULT, "key set failed\r\n"); + + return 0; +} + +static int normal_aes_encrypt(struct skcipher_request *req) +{ + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct crypto_tfm *cry_tfm = crypto_skcipher_tfm(tfm); + const char *alg_name = crypto_tfm_alg_name(cry_tfm); + cipher_param param = { + .cipher_alg = CRYPTO_SYMC_ALG_AES, + .flag = OT_DRV_ENCRYPT + }; + + cryptodev_chk_return(alg_name_2_workmode(alg_name, ¶m.work_mode) != TD_SUCCESS, + -EFAULT, "alg not support!\r\n"); + + if (inner_aes_crypt(req, ¶m) != 0) { + return -EINVAL; + } + return 0; +} + +static int normal_aes_decrypt(struct skcipher_request *req) +{ + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct crypto_tfm *cry_tfm = crypto_skcipher_tfm(tfm); + const char *alg_name = crypto_tfm_alg_name(cry_tfm); + cipher_param param = { + .cipher_alg = CRYPTO_SYMC_ALG_AES, + .flag = OT_DRV_DECRYPT + }; + + cryptodev_chk_return(alg_name_2_workmode(alg_name, ¶m.work_mode) != TD_SUCCESS, + -EFAULT, "alg not support!\r\n"); + + if (inner_aes_crypt(req, ¶m) != 0) { + return -EINVAL; + } + return 0; +} + +static int lock_aes_init(struct crypto_skcipher *tfm) +{ + int ret; + enter_func(); + osal_mutex_lock(&aes_lock); + ret = normal_aes_init(&tfm->base); + osal_mutex_unlock(&aes_lock); + exit_func(); + cryptodev_chk_return(ret != TD_SUCCESS, -EINVAL, "aes_init failed\r\n"); + return ret; +} + +static void lock_aes_deinit(struct crypto_skcipher *tfm) +{ + enter_func(); + osal_mutex_lock(&aes_lock); + normal_aes_deinit(&tfm->base); + osal_mutex_unlock(&aes_lock); + exit_func(); +} + +static int lock_aes_set_key(struct crypto_skcipher *tfm, const u8 *key, + unsigned int keylen) +{ + int ret; + enter_func(); + osal_mutex_lock(&aes_lock); + ret = normal_aes_set_key(&tfm->base, key, keylen); + osal_mutex_unlock(&aes_lock); + exit_func(); + cryptodev_chk_return(ret != TD_SUCCESS, -EINVAL, "aes_set_key failed\r\n"); + return ret; +} + +static int lock_aes_encrypt(struct skcipher_request *req) +{ + int ret; + enter_func(); + osal_mutex_lock(&aes_lock); + ret = normal_aes_encrypt(req); + osal_mutex_unlock(&aes_lock); + exit_func(); + cryptodev_chk_return(ret != TD_SUCCESS, -EINVAL, "aes_encrypt failed\r\n"); + return ret; +} + +static int lock_aes_decrypt(struct skcipher_request *req) +{ + int ret; + enter_func(); + osal_mutex_lock(&aes_lock); + ret = normal_aes_decrypt(req); + osal_mutex_unlock(&aes_lock); + exit_func(); + cryptodev_chk_return(ret != TD_SUCCESS, -EINVAL, "aes_decrypt failed\r\n"); + return ret; +} + +struct skcipher_alg aes_algs[2] = { + { + .base.cra_name = "cbc(aes)", + .base.cra_driver_name = "ot_drv", + .base.cra_priority = 2000, + .base.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER, + .base.cra_blocksize = AES_BLOCK_SIZE, + .base.cra_ctxsize = sizeof(struct cipher_aes_ctx), + .base.cra_module = THIS_MODULE, + .init = lock_aes_init, + .exit = lock_aes_deinit, + .setkey = lock_aes_set_key, + .encrypt = lock_aes_encrypt, + .decrypt = lock_aes_decrypt, + .ivsize = AES_BLOCK_SIZE, + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + }, + { + .base.cra_name = "ctr(aes)", + .base.cra_driver_name = "ot_drv", + .base.cra_priority = 2000, + .base.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER, + .base.cra_blocksize = 1, + .base.cra_ctxsize = sizeof(struct cipher_aes_ctx), + .base.cra_module = THIS_MODULE, + .init = lock_aes_init, + .exit = lock_aes_deinit, + .setkey = lock_aes_set_key, + .encrypt = lock_aes_encrypt, + .decrypt = lock_aes_decrypt, + .ivsize = AES_BLOCK_SIZE, + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + } +}; + +static int aes_aead_gcm_setauthsize(struct crypto_aead *tfm, unsigned int authsize) +{ + struct cipher_aes_ctx *ctx = crypto_aead_ctx(tfm); + // gcm tag len should below 16 + if (authsize > 16) { + cprint("set authsize not successful\r\n"); + return -EINVAL; + } + ctx->authsize = authsize; + return 0; +} + +static int aes_aead_ccm_setauthsize(struct crypto_aead *tfm, unsigned int authsize) +{ + struct cipher_aes_ctx *ctx = crypto_aead_ctx(tfm); + // ccm tag len Can only be 4 6 8 10 12 14 16 + switch (authsize) { + case 4: + case 6: + case 8: + case 10: + case 12: + case 14: + case 16: + break; + default: + cprint("set authsize not successful\r\n"); + return -EINVAL; + } + + ctx->authsize = authsize; + return 0; +} + +static int aead_aes_init(struct crypto_tfm *tfm) +{ + // init transform + int ret; + const mm_malloc_param cipher_param = { + .size = CIPHER_BUFF_LENGTH, + .kernel_only = TD_FALSE + }; + const mm_malloc_param aad_param = { + .size = MAX_AAD_LEN, + .kernel_only = TD_FALSE + }; + + const char *alg_name = crypto_tfm_alg_name(tfm); + struct cipher_aes_ctx *ctx = crypto_tfm_ctx(tfm); + ret = memset_s(ctx, sizeof(struct cipher_aes_ctx), 0, sizeof(struct cipher_aes_ctx)); + cryptodev_chk_return(ret != TD_SUCCESS, ret, "normal_aes_init failed\r\n"); + + ctx->cipher_attr.symc_type = CRYPTO_SYMC_TYPE_NORMAL; + ctx->cipher_attr.symc_alg = CRYPTO_SYMC_ALG_AES; + ctx->cipher_attr.is_long_term = TD_TRUE; + ctx->keyslot_type = KM_KEYSLOT_TYPE_MCIPHER; + ctx->keyslot_handle = INVALID_HANDLE; + ctx->symc_handle = INVALID_HANDLE; + + ret = alg_name_2_workmode(alg_name, &ctx->cipher_attr.work_mode); + cryptodev_chk_return(ret != TD_SUCCESS, -EFAULT, "input alg name not support yet\r\n"); + + ret = cmpi_mmz_malloc_cached(&cipher_param, &ctx->mem_phys, (td_void **)&ctx->mem_virt); + cryptodev_chk_return(ret != TD_SUCCESS, -EFAULT, "cmpi_mmz_malloc_cached failed\r\n"); + cryptodev_chk_return(ctx->mem_virt == NULL, -EFAULT, "buff piont to null addr!\r\n"); + + ret = cmpi_mmz_malloc_nocache(&aad_param, &ctx->aad_mem_phys, (td_void **)&ctx->aad_mem_virt); + cryptodev_chk_goto_with_ret(ret != TD_SUCCESS, buff_free, ret, "cmpi_mmz_malloc_cached failed\r\n"); + cryptodev_chk_goto_with_ret(ctx->aad_mem_virt == TD_NULL, buff_free, ret, "buff point to nullptr\r\n"); + ctx->is_init = 1; + return 0; +buff_free: + cmpi_mmz_free(ctx->mem_phys, ctx->mem_virt); + return -EFAULT; +} + +static void aead_aes_deinit(struct crypto_tfm *tfm) +{ + // destroy transform + struct cipher_aes_ctx *ctx = crypto_tfm_ctx(tfm); + + if (ctx->is_init == 1) { + (void)memset_s(ctx->mem_virt, CIPHER_BUFF_LENGTH, 0, CIPHER_BUFF_LENGTH); + (void)memset_s(ctx->aad_mem_virt, MAX_AAD_LEN, 0, MAX_AAD_LEN); + cmpi_mmz_free(ctx->mem_phys, ctx->mem_virt); + cmpi_mmz_free(ctx->aad_mem_phys, ctx->aad_mem_virt); + (void)memset_s(ctx, sizeof(struct cipher_aes_ctx), 0, sizeof(struct cipher_aes_ctx)); + ctx->is_init = 0; + } +} + +static int lock_aes_aead_init(struct crypto_aead *tfm) +{ + int ret; + enter_func(); + osal_mutex_lock(&aes_lock); + ret = aead_aes_init(&tfm->base); + osal_mutex_unlock(&aes_lock); + exit_func(); + cryptodev_chk_return(ret != TD_SUCCESS, -EINVAL, "lock_aes_aead_init failed\r\n"); + return ret; +} + +static void lock_aes_aead_deinit(struct crypto_aead *tfm) +{ + enter_func(); + osal_mutex_lock(&aes_lock); + aead_aes_deinit(&tfm->base); + osal_mutex_unlock(&aes_lock); + exit_func(); +} + +static int lock_aes_aead_set_key(struct crypto_aead *tfm, const u8 *key, unsigned int keylen) +{ + int ret; + enter_func(); + osal_mutex_lock(&aes_lock); + ret = normal_aes_set_key(&tfm->base, key, keylen); + osal_mutex_unlock(&aes_lock); + exit_func(); + cryptodev_chk_return(ret != TD_SUCCESS, -EINVAL, "lock_aes_aead_set_key failed\r\n"); + return ret; +} + +static int aes_aead_encrypt(struct aead_request *req) +{ + int ret; + const char *alg_name = crypto_aead_alg(crypto_aead_reqtfm(req))->base.cra_name; + cipher_param param = { + .cipher_alg = CRYPTO_SYMC_ALG_AES, + .flag = OT_DRV_ENCRYPT + }; + + ret = alg_name_2_workmode(alg_name, ¶m.work_mode); + cryptodev_chk_return(ret != TD_SUCCESS, ret, "aes_aead_encrypt failed\r\n"); + + ret = inner_aes_aead_crypt(req, ¶m); + cryptodev_chk_return(ret != TD_SUCCESS, -EFAULT, "aes_aead_encrypt failed\r\n"); + return 0; +} + +static int aes_aead_decrypt(struct aead_request *req) +{ + int ret; + const char *alg_name = crypto_aead_alg(crypto_aead_reqtfm(req))->base.cra_name; + + cipher_param param = { + .cipher_alg = CRYPTO_SYMC_ALG_AES, + .flag = OT_DRV_DECRYPT + }; + + ret = alg_name_2_workmode(alg_name, ¶m.work_mode); + cryptodev_chk_return(ret != TD_SUCCESS, ret, "aes_aead_decrypt failed\r\n"); + + ret = inner_aes_aead_crypt(req, ¶m); + cryptodev_chk_return(ret != TD_SUCCESS, -EFAULT, "aes_aead_decrypt failed\r\n"); + return 0; +} + +static int lock_aes_aead_encrypt(struct aead_request *req) +{ + int ret; + enter_func(); + osal_mutex_lock(&aes_lock); + ret = aes_aead_encrypt(req); + osal_mutex_unlock(&aes_lock); + exit_func(); + cryptodev_chk_return(ret != TD_SUCCESS, -EINVAL, "lock_aes_aead_encrypt failed\r\n"); + return ret; +} + +static int lock_aes_aead_decrypt(struct aead_request *req) +{ + int ret; + enter_func(); + osal_mutex_lock(&aes_lock); + ret = aes_aead_decrypt(req); + osal_mutex_unlock(&aes_lock); + exit_func(); + cryptodev_chk_return(ret != TD_SUCCESS, -EINVAL, "lock_aes_aead_decrypt failed\r\n"); + return ret; +} + +struct aead_alg aes_aead_algs[2] = { + { + .base.cra_name = "gcm(aes)", + .base.cra_driver_name = "ot_drv", + .base.cra_priority = 2000, + .base.cra_flags = CRYPTO_ALG_TYPE_AEAD, + .base.cra_blocksize = 1, + .base.cra_ctxsize = sizeof(struct cipher_aes_ctx), + .base.cra_module = THIS_MODULE, + + .ivsize = GCM_IV_SIZE, + .maxauthsize = AES_BLOCK_SIZE, + .init = lock_aes_aead_init, + .exit = lock_aes_aead_deinit, + .encrypt = lock_aes_aead_encrypt, + .decrypt = lock_aes_aead_decrypt, + .setkey = lock_aes_aead_set_key, + .setauthsize = aes_aead_gcm_setauthsize, + }, + { + .base.cra_name = "ccm(aes)", + .base.cra_driver_name = "ot_drv", + .base.cra_priority = 2000, + .base.cra_flags = CRYPTO_ALG_TYPE_AEAD, + .base.cra_blocksize = 1, + .base.cra_ctxsize = sizeof(struct cipher_aes_ctx), + .base.cra_module = THIS_MODULE, + + .ivsize = AES_BLOCK_SIZE, + .maxauthsize = AES_BLOCK_SIZE, + .init = lock_aes_aead_init, + .exit = lock_aes_aead_deinit, + .encrypt = lock_aes_aead_encrypt, + .decrypt = lock_aes_aead_decrypt, + .setkey = lock_aes_aead_set_key, + .setauthsize = aes_aead_ccm_setauthsize, + } +}; \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/hardware_cryptodev/reg_hash.c b/kernel/security_subsys/hi3519dv500/hardware_cryptodev/reg_hash.c new file mode 100644 index 00000000..a7b4afb1 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/hardware_cryptodev/reg_hash.c @@ -0,0 +1,305 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "ot_reg.h" +#include +#include +#include +#include + +osal_mutex hash_channel_lock; + +static int get_hash_type(struct hash_ctx *ctx, const char *alg_name) +{ + ctx->hash_attr.is_long_term = TD_FALSE; + + if (!strcmp(alg_name, "sha256")) { + ctx->hash_attr.hash_type = CRYPTO_HASH_TYPE_SHA256; + ctx->digest_lenth = SHA256_DIGEST_SIZE; + } else if (!strcmp(alg_name, "sha384")) { + ctx->hash_attr.hash_type = CRYPTO_HASH_TYPE_SHA384; + ctx->digest_lenth = SHA384_DIGEST_SIZE; + } else if (!strcmp(alg_name, "sha512")) { + ctx->hash_attr.hash_type = CRYPTO_HASH_TYPE_SHA512; + ctx->digest_lenth = SHA512_DIGEST_SIZE; + } else { + cprint("input hash type is %s, not support yet\r\n", alg_name); + return -EINVAL; + } + + return TD_SUCCESS; +} + +static int crypto_hash_ctx_get(td_handle handle, hardware_hash_clone_ctx *hard_ctx) +{ + int ret; + crypto_hash_clone_ctx crypto_ctx; + + ret = kapi_cipher_hash_get(handle, &crypto_ctx); + cryptodev_chk_return(ret != TD_SUCCESS, -EINVAL, "drv get ctx failed\r\n"); + + hard_ctx->tail_len = crypto_ctx.tail_len; + hard_ctx->hash_type = crypto_ctx.hash_type; + ret = memcpy_s(hard_ctx->length, sizeof(hard_ctx->length), crypto_ctx.length, sizeof(crypto_ctx.length)); + cryptodev_chk_return(ret != TD_SUCCESS, -EINVAL, "memcpy_s failed\r\n"); + ret = memcpy_s(hard_ctx->state, sizeof(hard_ctx->state), crypto_ctx.state, sizeof(crypto_ctx.state)); + cryptodev_chk_return(ret != TD_SUCCESS, -EINVAL, "memcpy_s failed\r\n"); + ret = memcpy_s(hard_ctx->tail, sizeof(hard_ctx->tail), crypto_ctx.tail, sizeof(crypto_ctx.tail)); + cryptodev_chk_return(ret != TD_SUCCESS, -EINVAL, "memcpy_s failed\r\n"); + + return TD_SUCCESS; +} + +static int crypto_hash_ctx_set(td_handle handle, hardware_hash_clone_ctx *hard_ctx) +{ + int ret; + crypto_hash_clone_ctx crypto_ctx; + + crypto_ctx.tail_len = hard_ctx->tail_len; + crypto_ctx.hash_type = hard_ctx->hash_type; + ret = memcpy_s(crypto_ctx.length, sizeof(crypto_ctx.length), hard_ctx->length, sizeof(hard_ctx->length)); + cryptodev_chk_return(ret != TD_SUCCESS, -EINVAL, "memcpy_s failed\r\n"); + ret = memcpy_s(crypto_ctx.state, sizeof(crypto_ctx.state), hard_ctx->state, sizeof(hard_ctx->state)); + cryptodev_chk_return(ret != TD_SUCCESS, -EINVAL, "memcpy_s failed\r\n"); + ret = memcpy_s(crypto_ctx.tail, sizeof(crypto_ctx.tail), hard_ctx->tail, sizeof(hard_ctx->tail)); + cryptodev_chk_return(ret != TD_SUCCESS, -EINVAL, "memcpy_s failed\r\n"); + + ret = kapi_cipher_hash_set(handle, &crypto_ctx); + cryptodev_chk_return(ret != TD_SUCCESS, -EINVAL, "drv get ctx failed\r\n"); + + return TD_SUCCESS; +} + +static int hash_init(struct shash_desc *desc) +{ + int ret = TD_FAILURE; + struct hash_ctx *ctx = NULL; + const char *alg_name = NULL; + + ctx = shash_desc_ctx(desc); + ctx->is_init = TD_FALSE; + alg_name = crypto_tfm_alg_name(&desc->tfm->base); + + ret = get_hash_type(ctx, alg_name); + cryptodev_chk_return(ret != TD_SUCCESS, -EINVAL, "get_hash_type failed\r\n"); + + ret = kapi_cipher_hash_init(); + cryptodev_chk_goto_with_ret(ret != TD_SUCCESS, channel_free, -EINVAL, "kapi_cipher_hash_init failed\r\n"); + + ret = kapi_cipher_hash_start(&ctx->hash_handle, &ctx->hash_attr); + cryptodev_chk_goto_with_ret(ret != TD_SUCCESS, hash_deinit, -EINVAL, "kapi_cipher_hash_start failed\r\n"); + + ret = crypto_hash_ctx_get(ctx->hash_handle, &ctx->clone_ctx); + cryptodev_chk_goto_with_ret(ret != TD_SUCCESS, hash_destory, -EINVAL, "kapi_cipher_hash_set failed\r\n"); + + ctx->is_init = TD_TRUE; +hash_destory: + (void)kapi_cipher_hash_destroy(ctx->hash_handle); +hash_deinit: + (void)kapi_cipher_hash_deinit(); +channel_free: + return ret; +} + + +static int hash_update(struct shash_desc *desc, const u8 *data, + unsigned int len) +{ + int ret = TD_FAILURE; + struct hash_ctx *ctx = NULL; + const crypto_buf_attr src_buf = { + .virt_addr = (u8 *)data + }; + + ctx = shash_desc_ctx(desc); + cryptodev_chk_goto_with_ret(ctx->is_init != TD_TRUE, not_init_exit, -EINVAL, "hash channel not init\r\n"); + + ret = kapi_cipher_hash_init(); + cryptodev_chk_goto_with_ret(ret != TD_SUCCESS, not_init_exit, -EINVAL, "kapi_cipher_hash_init failed\r\n"); + + ret = kapi_cipher_hash_start(&ctx->hash_handle, &ctx->hash_attr); + cryptodev_chk_goto_with_ret(ret != TD_SUCCESS, hash_deinit, -EINVAL, "kapi_cipher_hash_start failed\r\n"); + + ret = crypto_hash_ctx_set(ctx->hash_handle, &ctx->clone_ctx); + cryptodev_chk_goto_with_ret(ret != TD_SUCCESS, hash_destroy, -EINVAL, "kapi_cipher_hash_set failed\r\n"); + + ret = kapi_cipher_hash_update(ctx->hash_handle, &src_buf, len); + cryptodev_chk_goto_with_ret(ret != TD_SUCCESS, hash_destroy, -EINVAL, "kapi_cipher_hash_update failed\r\n"); + + ret = crypto_hash_ctx_get(ctx->hash_handle, &ctx->clone_ctx); +hash_destroy: + (void)kapi_cipher_hash_destroy(ctx->hash_handle); +hash_deinit: + (void)kapi_cipher_hash_deinit(); +not_init_exit: + if (ret != TD_SUCCESS) { + ctx->is_init = TD_FALSE; + } + return ret; +} + +static int hash_final(struct shash_desc *desc, u8 *out) +{ + int ret = TD_FAILURE; + struct hash_ctx *ctx = NULL; + + ctx = shash_desc_ctx(desc); + cryptodev_chk_goto_with_ret(ctx->is_init != TD_TRUE, not_init_exit, -EINVAL, "hash channel not init\r\n"); + + ret = kapi_cipher_hash_init(); + cryptodev_chk_goto_with_ret(ret != TD_SUCCESS, not_init_exit, -EINVAL, "kapi_cipher_hash_init failed\r\n"); + + ret = kapi_cipher_hash_start(&ctx->hash_handle, &ctx->hash_attr); + cryptodev_chk_goto_with_ret(ret != TD_SUCCESS, hash_deinit, -EINVAL, "kapi_cipher_hash_start failed\r\n"); + + ret = crypto_hash_ctx_set(ctx->hash_handle, &ctx->clone_ctx); + cryptodev_chk_goto_with_ret(ret != TD_SUCCESS, hash_destroy, -EINVAL, "kapi_cipher_hash_set failed\r\n"); + + ret = kapi_cipher_hash_finish(ctx->hash_handle, out, &ctx->digest_lenth); + if (ret == TD_SUCCESS) { + goto hash_deinit; + } +hash_destroy: + (void)kapi_cipher_hash_destroy(ctx->hash_handle); +hash_deinit: + (void)kapi_cipher_hash_deinit(); +not_init_exit: + ctx->is_init = TD_FALSE; + return ret; +} + +static int hash_finup(struct shash_desc *desc, const u8 *data, + unsigned int len, u8 *out) +{ + int ret; + struct hash_ctx *ctx = NULL; + const crypto_buf_attr src_buf = { + .virt_addr = (u8 *)data + }; + + ctx = shash_desc_ctx(desc); + cryptodev_chk_goto_with_ret(ctx->is_init != TD_TRUE, not_init_exit, -EINVAL, "hash channel not init\r\n"); + + ret = kapi_cipher_hash_init(); + cryptodev_chk_goto_with_ret(ret != TD_SUCCESS, not_init_exit, -EINVAL, "kapi_cipher_hash_init failed\r\n"); + + ret = kapi_cipher_hash_start(&ctx->hash_handle, &ctx->hash_attr); + cryptodev_chk_goto_with_ret(ret != TD_SUCCESS, hash_deinit, -EINVAL, "kapi_cipher_hash_start failed\r\n"); + + ret = crypto_hash_ctx_set(ctx->hash_handle, &ctx->clone_ctx); + cryptodev_chk_goto_with_ret(ret != TD_SUCCESS, hash_destroy, -EINVAL, "kapi_cipher_hash_set failed\r\n"); + + ret = kapi_cipher_hash_update(ctx->hash_handle, &src_buf, len); + cryptodev_chk_goto_with_ret(ret != TD_SUCCESS, hash_destroy, -EINVAL, "kapi_cipher_hash_update failed\r\n"); + + ret = kapi_cipher_hash_finish(ctx->hash_handle, out, &ctx->digest_lenth); + if (ret == TD_SUCCESS) { + goto hash_deinit; + } +hash_destroy: + (void)kapi_cipher_hash_destroy(ctx->hash_handle); +hash_deinit: + (void)kapi_cipher_hash_deinit(); +not_init_exit: + ctx->is_init = TD_FALSE; + return ret; +} + +static int lock_hash_init(struct shash_desc *desc) +{ + int ret; + enter_func(); + osal_mutex_lock(&hash_channel_lock); + ret = hash_init(desc); + osal_mutex_unlock(&hash_channel_lock); + exit_func(); + cryptodev_chk_return(ret != TD_SUCCESS, -EINVAL, "lock_hash_init failed\r\n"); + return ret; +} + +static int lock_hash_update(struct shash_desc *desc, const u8 *data, + unsigned int len) +{ + int ret; + enter_func(); + osal_mutex_lock(&hash_channel_lock); + ret = hash_update(desc, data, len); + osal_mutex_unlock(&hash_channel_lock); + exit_func(); + cryptodev_chk_return(ret != TD_SUCCESS, -EINVAL, "lock_hash_update failed\r\n"); + return ret; +} + +static int lock_hash_final(struct shash_desc *desc, u8 *out) +{ + int ret; + enter_func(); + osal_mutex_lock(&hash_channel_lock); + ret = hash_final(desc, out); + osal_mutex_unlock(&hash_channel_lock); + exit_func(); + cryptodev_chk_return(ret != TD_SUCCESS, -EINVAL, "lock_hash_final failed\r\n"); + return ret; +} + +static int lock_hash_finup(struct shash_desc *desc, const u8 *data, + unsigned int len, u8 *out) +{ + int ret; + enter_func(); + osal_mutex_lock(&hash_channel_lock); + ret = hash_finup(desc, data, len, out); + osal_mutex_unlock(&hash_channel_lock); + exit_func(); + cryptodev_chk_return(ret != TD_SUCCESS, -EINVAL, "lock_hash_finup failed\r\n"); + return ret; +} + +struct shash_alg shash_alges[3] = { + { + .digestsize = SHA256_DIGEST_SIZE, + .init = lock_hash_init, + .update = lock_hash_update, + .final = lock_hash_final, + .finup = lock_hash_finup, + .descsize = sizeof(struct hash_ctx), + .base = { + .cra_name = "sha256", + .cra_driver_name = "ot_drv", + .cra_priority = 2000, + .cra_blocksize = SHA256_BLOCK_SIZE, + .cra_module = THIS_MODULE, + } + }, + { + .digestsize = SHA384_DIGEST_SIZE, + .init = lock_hash_init, + .update = lock_hash_update, + .final = lock_hash_final, + .finup = lock_hash_finup, + .descsize = sizeof(struct hash_ctx), + .base = { + .cra_name = "sha384", + .cra_driver_name = "ot_drv", + .cra_priority = 2000, + .cra_blocksize = SHA384_BLOCK_SIZE, + .cra_module = THIS_MODULE, + } + }, + { + .digestsize = SHA512_DIGEST_SIZE, + .init = lock_hash_init, + .update = lock_hash_update, + .final = lock_hash_final, + .finup = lock_hash_finup, + .descsize = sizeof(struct hash_ctx), + .base = { + .cra_name = "sha512", + .cra_driver_name = "ot_drv", + .cra_priority = 2000, + .cra_blocksize = SHA512_BLOCK_SIZE, + .cra_module = THIS_MODULE, + } + } +}; \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/km/mkp/Makefile b/kernel/security_subsys/hi3519dv500/km/mkp/Makefile new file mode 100644 index 00000000..ac78f9df --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/km/mkp/Makefile @@ -0,0 +1,63 @@ +#************************************************************************* +ifeq ($(PARAM_FILE), ) + PARAM_FILE:=../../../../../Makefile.param + include $(PARAM_FILE) +endif + +ifeq ($(CBB_PARAM_FILE), ) + CBB_PARAM_FILE:=../../../Makefile.param + include $(CBB_PARAM_FILE) +endif + +KM_MKP_DIR := $(PWD) +export CONFIG_DRIVER_KM_SUPPORT=y + +# all source file in this module +SRCS:= + +# add include files +MKP_CFLAGS += -I$(KM_MKP_DIR) -I$(KM_MKP_DIR)/../../crypto_osal_lib \ + -I$(KM_MKP_DIR)/../../security_subsys_common/include/common_include \ + -I$(KM_MKP_DIR)/../../security_subsys_common/include/drv_include \ + -I$(KM_MKP_DIR)/../../security_subsys_common/include/ioctl_include \ + -I$(KM_MKP_DIR)/../../security_subsys_common/include/kapi_include \ + -I$(KM_MKP_DIR)/../../security_subsys_common/include/hal_include \ + -I$(KM_MKP_DIR)/../../security_subsys_common/hal_code/km_v4 \ + -I$(KM_MKP_DIR)/../../security_subsys_common/hal_code/trng_v4 \ + -I$(KM_MKP_DIR)/../../security_subsys_common/dispatch_code \ + -I$(KM_MKP_DIR)/../../security_subsys_common/drv_code \ + -I$(KM_MKP_DIR)/../../cipher/mkp -I$(KM_MKP_DIR)/../../ + +# add compiling macros +MKP_CFLAGS += -DCONFIG_CRYPTO_CHIP_HI3519DV500 + +INIT_FILE := $(KM_MKP_DIR)/crypto_km_drv_init.c +INIT_INC := $(KM_MKP_DIR)/init_km.h + +MKP_SRCS := crypto_km_drv_init.c init_km.c \ + ../../security_subsys_common/dispatch_code/dispatch_km.c \ + ../../security_subsys_common/drv_code/drv_klad.c \ + ../../security_subsys_common/drv_code/drv_keyslot.c \ + ../../security_subsys_common/hal_code/km_v4/hal_rkp.c \ + ../../security_subsys_common/hal_code/km_v4/hal_klad.c \ + ../../security_subsys_common/hal_code/km_v4/hal_keyslot.c \ + ../../security_subsys_common/kapi_code/kapi_km.c + +DRIVER_OBJS-y += $(patsubst %.c, %.o, $(MKP_SRCS)) + +SRCS += $(MKP_SRCS) + +# Debug +# MKP_CFLAGS += -DCRYPTO_HAL_FUNC_TRACE_ENABLE +# MKP_CFLAGS += -DCRYPTO_KAPI_FUNC_TRACE_ENABLE +# MKP_CFLAGS += -DCRYPTO_DRV_FUNC_TRACE_ENABLE +# MKP_CFLAGS += -DCRYPTO_DISPATCH_FUNC_TRACE_ENABLE + +SRCS_O := $(SRCS) + +#************************************************************************* +TARGET := $(KO_PREFIX)_km + +#************************************************************************* + +include $(MAKE_DRV_FILE) \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/km/mkp/crypto_km_drv_init.c b/kernel/security_subsys/hi3519dv500/km/mkp/crypto_km_drv_init.c new file mode 100644 index 00000000..66810dae --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/km/mkp/crypto_km_drv_init.c @@ -0,0 +1,201 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include +#include +#include +#include + +#include + +#include "ot_osal.h" +#include "mm_ext.h" +#include "crypto_common_macro.h" +#include "crypto_drv_common.h" +#include "init_km.h" + +#ifdef MODULE +#define CPU_ID_STAT (0x0018) +#define CRYPTO_CPU_ID_SCPU (0xa5) +#define CRYPTO_CPU_ID_ACPU (0xaa) + +crypto_cpu_type crypto_get_cpu_type(td_void) +{ + td_u32 cpu_id = ca_misc_reg_read(CPU_ID_STAT) & 0x00ff; + if (cpu_id == CRYPTO_CPU_ID_SCPU) { + return CRYPTO_CPU_TYPE_SCPU; + } else if (cpu_id == CRYPTO_CPU_ID_ACPU) { + return CRYPTO_CPU_TYPE_ACPU; + } + return CRYPTO_CPU_TYPE_INVALID; +} + +static td_void *g_km_reg_virt = TD_NULL; +static td_void *g_ca_misc_reg_virt = TD_NULL; + +td_u32 crypto_ex_reg_read(reg_region_e region, td_u32 offset) +{ + if (region == REG_REGION_CA_MISC) { + return crypto_reg_read((volatile td_void *)(g_ca_misc_reg_virt + offset)); + } + return crypto_reg_read((volatile td_void *)(g_km_reg_virt + offset)); +} + +td_void crypto_ex_reg_write(reg_region_e region, td_u32 offset, td_u32 value) +{ + if (region == REG_REGION_CA_MISC) { + crypto_reg_write((volatile td_void *)(g_ca_misc_reg_virt + offset), value); + } + crypto_reg_write((volatile td_void *)(g_km_reg_virt + offset), value); +} + +td_s32 crypto_copy_from_user(td_void *to, unsigned long to_len, const td_void *from, unsigned long from_len) +{ + if (from_len == 0) { + return TD_SUCCESS; + } + + if (to == TD_NULL) { + crypto_log_err("to is NULL\n"); + return TD_FAILURE; + } + if (from == TD_NULL) { + crypto_log_err("from is NULL\n"); + return TD_FAILURE; + } + if (to_len < from_len) { + crypto_log_err("to_len is Less Than from_len!\n"); + return TD_FAILURE; + } + + return osal_copy_from_user(to, from, from_len); +} + +td_u32 crypto_get_value_by_index(const crypto_table_item *table, td_u32 table_size, + td_u32 index, td_u32 *value) +{ + const crypto_table_item *item = TD_NULL; + td_u32 i; + + crypto_chk_return(table == TD_NULL, TD_FAILURE, "table is NULL\n"); + crypto_chk_return(value == TD_NULL, TD_FAILURE, "value is NULL\n"); + + for (i = 0; i < table_size; i++) { + item = &table[i]; + if (item->index == index) { + *value = item->value; + return TD_SUCCESS; + } + } + crypto_log_err("Invalid Index!\n"); + return TD_FAILURE; +} +#else +static int crypto_reg_map(td_void) +{ + td_s32 ret; + + /* CS MISC Region. */ + ret = crypto_register_reg_map_region(REG_REGION_CA_MISC); + crypto_chk_return(ret != TD_SUCCESS, ret, "crypto_register_reg_map_region CA_MISC failed, ret is 0x%x\n", ret); + + /* KM Region. */ + ret = crypto_register_reg_map_region(REG_REGION_KM); + crypto_chk_goto(ret != TD_SUCCESS, error_ca_misc_unmap, "crypto_register_reg_map_region KM failed, \ + ret is 0x%x\n", ret); + + return TD_SUCCESS; + +error_ca_misc_unmap: + crypto_unregister_reg_map_region(REG_REGION_CA_MISC); + return TD_FAILURE; +} + +static void crypto_reg_unmap(td_void) +{ + crypto_unregister_reg_map_region(REG_REGION_KM); + crypto_unregister_reg_map_region(REG_REGION_CA_MISC); +} +#endif + +td_s32 g_klad_tee_irq_num; +td_s32 g_klad_ree_irq_num; +td_s32 g_rkp_tee_irq_num; +td_s32 g_rkp_ree_irq_num; + +static int ot_km_probe(struct platform_device *pdev) +{ + td_s32 ret = TD_SUCCESS; + + g_rkp_tee_irq_num = osal_platform_get_irq_byname(pdev, "rkp_tee"); + g_rkp_ree_irq_num = osal_platform_get_irq_byname(pdev, "rkp_ree"); + g_klad_tee_irq_num = osal_platform_get_irq_byname(pdev, "klad_tee"); + g_klad_ree_irq_num = osal_platform_get_irq_byname(pdev, "klad_ree"); + +#ifdef MODULE + g_km_reg_virt = crypto_ioremap_nocache(KM_REG_BASE_ADDR, KM_REG_SIZE); + if (g_km_reg_virt == TD_NULL) { + crypto_log_err("crypto_ioremap_nocache failed for km_reg\n"); + return TD_FAILURE; + } + + g_ca_misc_reg_virt = crypto_ioremap_nocache(CA_MISC_REG_BASE_ADDR, CA_MISC_REG_SIZE); + if (g_ca_misc_reg_virt == TD_NULL) { + crypto_log_err("crypto_ioremap_nocache failed for ca_misc_reg\n"); + crypto_iounmap(g_km_reg_virt, KM_REG_SIZE); + return TD_FAILURE; + } +#else + ret = crypto_reg_map(); + crypto_chk_return(ret != TD_SUCCESS, ret, "crypto_reg_map failed, ret is 0x%x\n", ret); +#endif + + ret = crypto_km_init(); + crypto_chk_goto(ret != TD_SUCCESS, reg_unmap_error, "crypto_otp_init failed, ret is 0x%x\n", ret); + + crypto_print("load ot_km.ko ....OK!\n"); + + return ret; + +reg_unmap_error: +#ifdef MODULE + crypto_iounmap(g_ca_misc_reg_virt, CA_MISC_REG_SIZE); + crypto_iounmap(g_km_reg_virt, KM_REG_SIZE); +#else + crypto_reg_unmap(); +#endif + return ret; +} + +static int ot_km_remove(struct platform_device *pdev) +{ + crypto_unused(pdev); + crypto_km_deinit(); +#ifdef MODULE + crypto_iounmap(g_ca_misc_reg_virt, CA_MISC_REG_SIZE); + crypto_iounmap(g_km_reg_virt, KM_REG_SIZE); +#else + crypto_reg_unmap(); +#endif + crypto_print("unload ot_km.ko ....OK!\n"); + return TD_SUCCESS; +} + +static const struct of_device_id g_ot_km_match[] = { + { .compatible = "vendor,km" }, + { }, +}; +MODULE_DEVICE_TABLE(of, g_ot_km_match); + +static struct platform_driver g_ot_km_driver = { + .probe = ot_km_probe, + .remove = ot_km_remove, + .driver = { + .name = "ot_km", + .of_match_table = g_ot_km_match, + }, +}; + +osal_module_platform_driver(g_ot_km_driver); +MODULE_LICENSE("GPL"); diff --git a/kernel/security_subsys/hi3519dv500/km/mkp/init_km.c b/kernel/security_subsys/hi3519dv500/km/mkp/init_km.c new file mode 100644 index 00000000..6170083d --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/km/mkp/init_km.c @@ -0,0 +1,83 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "init_km.h" + +#include +#include +#include +#include + +#include + +#include "drv_klad.h" +#include "ot_osal.h" +#include "mm_ext.h" +#include "kapi_km.h" +#include "dispatch_km.h" +#include "crypto_common_macro.h" +#include "crypto_osal_lib.h" + +#define IRQ_TIMEOUT_MS (1000 * 5) + +static td_s32 ot_km_open(td_void *private_data) +{ + crypto_unused(private_data); + return TD_SUCCESS; +} + +static td_s32 ot_km_release(td_void *private_data) +{ + crypto_unused(private_data); + kapi_km_deinit(); + return TD_SUCCESS; +} + +static osal_fileops g_dev_km_fops = { + .open = ot_km_open, + .release = ot_km_release, + .cmd_list = TD_NULL, + .cmd_cnt = 0 +}; + +static osal_dev *g_km_dev = TD_NULL; + +td_s32 crypto_km_init(td_void) +{ + td_s32 ret; + + g_km_dev = osal_dev_create("km"); + crypto_chk_return(g_km_dev == TD_NULL, TD_FAILURE, "osal_dev_create failed\n"); + + g_dev_km_fops.cmd_list = get_km_func_list(); + g_dev_km_fops.cmd_cnt = get_km_func_num(); + + g_km_dev->minor = UMAP_KM_MINOR_BASE; + g_km_dev->fops = &g_dev_km_fops; + + ret = osal_dev_register(g_km_dev); + crypto_chk_goto(ret != TD_SUCCESS, error_dev_destroy, "osal_dev_register failed, ret is 0x%x\n", ret); + + ret = kapi_km_env_init(); + crypto_chk_goto(ret != TD_SUCCESS, error_dev_unregister, "kapi_km_init failed, ret is 0x%x\n", ret); + + return ret; + +error_dev_unregister: + osal_dev_unregister(g_km_dev); +error_dev_destroy: + if (g_km_dev != TD_NULL) { + osal_dev_destroy(g_km_dev); + g_km_dev = TD_NULL; + } + return TD_FAILURE; +} + +td_void crypto_km_deinit(td_void) +{ + kapi_km_env_deinit(); + osal_dev_unregister(g_km_dev); + osal_dev_destroy(g_km_dev); + g_km_dev = TD_NULL; +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/km/mkp/init_km.h b/kernel/security_subsys/hi3519dv500/km/mkp/init_km.h new file mode 100644 index 00000000..141cb0e1 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/km/mkp/init_km.h @@ -0,0 +1,22 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef CRYPTO_KM_INIT_H +#define CRYPTO_KM_INIT_H + +#include "ot_type.h" +#include "ca_misc_register.h" + +#define UMAP_KM_MINOR_BASE 54 +/* KM INIT */ +td_s32 crypto_km_init(td_void); +td_void crypto_km_deinit(td_void); + +/* IRQ NUM */ +extern td_s32 g_rkp_tee_irq_num; +extern td_s32 g_rkp_ree_irq_num; +extern td_s32 g_klad_tee_irq_num; +extern td_s32 g_klad_ree_irq_num; + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/km/mpi/Makefile b/kernel/security_subsys/hi3519dv500/km/mpi/Makefile new file mode 100644 index 00000000..1df65b4b --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/km/mpi/Makefile @@ -0,0 +1,30 @@ +ifeq ($(PARAM_FILE), ) + PARAM_FILE:=../../../../../Makefile.param + include $(PARAM_FILE) +endif + +ifeq ($(CBB_PARAM_FILE), ) + CBB_PARAM_FILE:=../../../Makefile.param + include $(CBB_PARAM_FILE) +endif + +MPI_SRC_DIR += $(PWD)/../../security_subsys_common/ot_mpi +MPI_SRC_DIR += $(PWD)/../../security_subsys_common/uapi_code +MPI_SRC_C := ot_mpi_km.c uapi_km.c +MPI_CFLAGS += -I$(PWD)/../../crypto_osal_lib \ + -I$(PWD)/../../security_subsys_common/include/uapi_include \ + -I$(PWD)/../../security_subsys_common/include/common_include \ + -I$(PWD)/../../security_subsys_common/include/ioctl_include \ + -I$(PWD)/../../security_subsys_common/ot_mpi_api + +# Debug +# MPI_CFLAGS += -DCRYPTO_UAPI_TRNG_DEBUG_ENABLE +MPI_CFLAGS += -DCONFIG_CRYPTO_CHIP_HI3519DV500 + +#************************************************************************* +# release header +INC_FILE := $(wildcard ../../security_subsys_common/ot_mpi_api/ot_mpi_km.h) + +LIB_NAME := ot_mpi_km + +include $(MAKE_MPI_FILE) \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/mbedtls_harden_adapt/Makefile b/kernel/security_subsys/hi3519dv500/mbedtls_harden_adapt/Makefile new file mode 100644 index 00000000..fbb85ae2 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/mbedtls_harden_adapt/Makefile @@ -0,0 +1,28 @@ +ifeq ($(PARAM_FILE), ) + PARAM_FILE:=../../../../Makefile.param + include $(PARAM_FILE) +endif + +ifeq ($(CBB_PARAM_FILE), ) + CBB_PARAM_FILE:=../../Makefile.param + include $(CBB_PARAM_FILE) +endif + +MPI_SRC_DIR += $(PWD) +MPI_SRC_C := mbedtls_harden_adapt.c +MPI_CFLAGS += -I$(PWD)/../security_subsys_common/include/uapi_include +MPI_CFLAGS += -I$(PWD)/../security_subsys_common/include/common_include +MPI_CFLAGS += -I$(PWD)/../crypto_osal_lib +MPI_CFLAGS += -I$(PWD)/.. +MPI_CFLAGS += -I$(MEM_ROOT)/include +MPI_CFLAGS += -I$(REL_INC) + +MPI_CFLAGS += -DCONFIG_CRYPTO_CHIP_HI3519DV500 + +#************************************************************************* +# release header +INC_FILE := $(wildcard mbedtls_harden_adapt.h) + +LIB_NAME := mbedtls_harden_adapt + +include $(MAKE_MPI_FILE) \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/mbedtls_harden_adapt/mbedtls_harden_adapt.c b/kernel/security_subsys/hi3519dv500/mbedtls_harden_adapt/mbedtls_harden_adapt.c new file mode 100644 index 00000000..9d892988 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/mbedtls_harden_adapt/mbedtls_harden_adapt.c @@ -0,0 +1,463 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "mbedtls_harden_adapt.h" +#include "crypto_osal_user_lib.h" +#include "ot_mpi_sys_mem.h" +#include "uapi_hash.h" +#include "uapi_kdf.h" +#include "uapi_km.h" +#include "uapi_pke.h" +#include "uapi_symc.h" +#include "uapi_trng.h" +#include "uapi_otp.h" +#include "crypto_platform.h" + +#define TEE_ENABLE_OFFSET 0x12 +#define TEE_DISABLE_VALUE 0x42 + +typedef enum { + KM_KEYSLOT_ENGINE_AES = 0, + KM_KEYSLOT_ENGINE_SM4, + KM_KEYSLOT_ENGINE_HMAC_SHA1, + KM_KEYSLOT_ENGINE_HMAC_SHA224, + KM_KEYSLOT_ENGINE_HMAC_SHA256, + KM_KEYSLOT_ENGINE_HMAC_SHA384, + KM_KEYSLOT_ENGINE_HMAC_SHA512, + KM_KEYSLOT_ENGINE_HMAC_SM3 +} km_keyslot_engine; + +typedef struct { + crypto_hash_type hmac_type; + td_u8 *salt; + td_u32 salt_length; + td_u8 *ikm; + td_u32 ikm_length; +} crypto_hkdf_extract_t; + +typedef struct { + crypto_hash_type hmac_type; + td_u8 *prk; + td_u32 prk_length; + td_u8 *info; + td_u32 info_length; +} crypto_hkdf_expand_t; + +typedef struct { + crypto_hash_type hmac_type; + td_u8 *salt; + td_u32 salt_length; + td_u8 *ikm; + td_u32 ikm_length; + td_u8 *info; + td_u32 info_length; +} crypto_hkdf_t; + +/* HASH */ +typedef td_s32 (*func_hash_init)(td_void); +typedef td_s32 (*func_hash_deinit)(td_void); +typedef td_s32 (*func_hash_start)(td_handle *uapi_hash_handle, const crypto_hash_attr *hash_attr); +typedef td_s32 (*func_hash_update)(td_handle uapi_hash_handle, const crypto_buf_attr *src_buf, const td_u32 len); +typedef td_s32 (*func_hash_get)(td_handle uapi_hash_handle, crypto_hash_clone_ctx *hash_clone_ctx); +typedef td_s32 (*func_hash_set)(td_handle uapi_hash_handle, const crypto_hash_clone_ctx *hash_clone_ctx); +typedef td_s32 (*func_hash_destroy)(td_handle uapi_hash_handle); +typedef td_s32 (*func_hash_finish)(td_handle uapi_hash_handle, td_u8 *out, td_u32 *out_len); + +/* HKDF */ +typedef td_s32 (*func_hkdf)(crypto_hkdf_t *hkdf_param, td_u8 *okm, td_u32 okm_length); +typedef td_s32 (*func_hkdf_extract)(crypto_hkdf_extract_t *extract_param, td_u8 *prk, td_u32 *prk_length); +typedef td_s32 (*func_hkdf_expand)(const crypto_hkdf_expand_t *expand_param, td_u8 *okm, td_u32 okm_length); + +/* TRNG */ +typedef td_s32 (*func_trng_get_random)(td_u32 *randnum); +typedef td_s32 (*func_trng_get_multi_random)(td_u32 size, td_u8 *randnum); + +/* PBKDF2 */ +typedef td_s32 (*func_pbkdf2)(const crypto_kdf_pbkdf2_param *param, td_u8 *out, const td_u32 out_len); + +/* SYMC */ +typedef td_s32 (*func_symc_init)(td_void); +typedef td_s32 (*func_symc_deinit)(td_void); +typedef td_s32 (*func_symc_create)(td_handle *symc_handle, const crypto_symc_attr *symc_attr); +typedef td_s32 (*func_symc_destroy)(td_handle symc_handle); +typedef td_s32 (*func_symc_set_config)(td_handle symc_handle, const crypto_symc_ctrl_t *symc_ctrl); +typedef td_s32 (*func_symc_get_config)(td_handle symc_handle, crypto_symc_ctrl_t *symc_ctrl); +typedef td_s32 (*func_symc_attach)(td_handle symc_handle, td_handle keyslot_handle); +typedef td_s32 (*func_symc_encrypt)(td_handle symc_handle, const crypto_buf_attr *src_buf, + const crypto_buf_attr *dst_buf, td_u32 length); +typedef td_s32 (*func_symc_decrypt)(td_handle symc_handle, const crypto_buf_attr *src_buf, + const crypto_buf_attr *dst_buf, td_u32 length); +typedef td_s32 (*func_symc_get_tag)(td_handle symc_handle, td_u8 *tag, td_u32 tag_length); +typedef td_s32 (*func_symc_mac_start)(td_handle *symc_handle, const crypto_symc_mac_attr *mac_attr); +typedef td_s32 (*func_symc_mac_update)(td_handle symc_handle, const crypto_buf_attr *src_buf, td_u32 length); +typedef td_s32 (*func_symc_mac_finish)(td_handle symc_handle, td_u8 *mac, td_u32 *mac_length); + +/* PKE */ +typedef td_s32 (*func_pke_init)(td_void); +typedef td_s32 (*func_pke_deinit)(td_void); +typedef td_s32 (*func_pke_mod)(const drv_pke_data *a, const drv_pke_data *p, const drv_pke_data *c); +typedef td_s32 (*func_pke_exp_mod)(const drv_pke_data *n, const drv_pke_data *k, + const drv_pke_data *in, const drv_pke_data *out); +typedef td_s32 (*func_pke_ecc_gen_key)(drv_pke_ecc_curve_type curve_type, const drv_pke_data *input_priv_key, + const drv_pke_data *output_priv_key, const drv_pke_ecc_point *output_pub_key); +typedef td_s32 (*func_pke_ecdsa_sign)(drv_pke_ecc_curve_type curve_type, const drv_pke_data *priv_key, + const drv_pke_data *hash, const drv_pke_ecc_sig *sig); +typedef td_s32 (*func_pke_ecdsa_verify)(drv_pke_ecc_curve_type curve_type, const drv_pke_ecc_point *pub_key, + const drv_pke_data *hash, const drv_pke_ecc_sig *sig); +typedef td_s32 (*func_pke_eddsa_sign)(drv_pke_ecc_curve_type curve_type, const drv_pke_data *priv_key, + const drv_pke_msg *msg, const drv_pke_ecc_sig *sig); +typedef td_s32 (*func_pke_eddsa_verify)(drv_pke_ecc_curve_type curve_type, const drv_pke_ecc_point *pub_key, + const drv_pke_msg *msg, const drv_pke_ecc_sig *sig); +typedef td_s32 (*func_pke_gen_ecdh_key)(drv_pke_ecc_curve_type curve_type, const drv_pke_ecc_point *input_pub_key, + const drv_pke_data *input_priv_key, const drv_pke_data *output_shared_key); +typedef td_s32 (*func_pke_check_dot_on_curve)(drv_pke_ecc_curve_type curve_type, const drv_pke_ecc_point *pub_key, + td_bool *is_on_curve); +typedef td_s32 (*func_pke_rsa_sign)(const drv_pke_rsa_priv_key *priv_key, drv_pke_rsa_scheme scheme, + drv_pke_hash_type hash_type, const drv_pke_data *input_hash, + drv_pke_data *sign); +typedef td_s32 (*func_pke_rsa_verify)(const drv_pke_rsa_pub_key *pub_key, drv_pke_rsa_scheme scheme, + drv_pke_hash_type hash_type, drv_pke_data *input_hash, const drv_pke_data *sig); +typedef td_s32 (*func_pke_rsa_public_encrypt)(drv_pke_rsa_scheme scheme, drv_pke_hash_type hash_type, + const drv_pke_rsa_pub_key *pub_key, const drv_pke_data *input, const drv_pke_data *label, + drv_pke_data *output); +typedef td_s32 (*func_pke_rsa_private_decrypt)(drv_pke_rsa_scheme scheme, drv_pke_hash_type hash_type, + const drv_pke_rsa_priv_key *priv_key, const drv_pke_data *input, const drv_pke_data *label, + drv_pke_data *output); + +/* KM */ +typedef td_s32 (*func_km_init)(td_void); +typedef td_s32 (*func_km_deinit)(td_void); +typedef td_s32 (*func_km_create_keyslot)(td_handle *keyslot_handle, km_keyslot_engine key_engine); +typedef td_void (*func_km_destroy_keyslot)(td_handle keyslot_handle); +typedef td_s32 (*func_km_set_clear_key)(td_handle keyslot_handle, td_u8 *key, td_u32 keylen, + km_keyslot_engine key_engine); + +/* MEM */ +typedef td_s32 (*func_alloc_phys_buf)(crypto_buf_attr *buf_attr, td_void **virt_addr, td_u32 size); +typedef td_void (*func_free_phys_buf)(crypto_buf_attr *buf_attr, td_void *virt_addr, td_u32 size); +typedef td_s32 (*func_get_phys_addr)(td_void *virt_addr, td_ulong *phys_addr); + +typedef struct { + func_hash_init harden_hash_init; + func_hash_deinit harden_hash_deinit; + func_hash_start harden_hash_start; + func_hash_update harden_hash_update; + func_hash_get harden_hash_get; + func_hash_set harden_hash_set; + func_hash_destroy harden_hash_destroy; + func_hash_finish harden_hash_finish; + func_hkdf harden_hkdf; + func_hkdf_extract harden_hkdf_extract; + func_hkdf_expand harden_hkdf_expand; + func_trng_get_random harden_trng_get_random; + func_trng_get_multi_random harden_trng_get_multi_random; + func_pbkdf2 harden_pbkdf2; + func_symc_init harden_symc_init; + func_symc_deinit harden_symc_deinit; + func_symc_create harden_symc_create; + func_symc_destroy harden_symc_destroy; + func_symc_set_config harden_symc_set_config; + func_symc_get_config harden_symc_get_config; + func_symc_attach harden_symc_attach; + func_symc_encrypt harden_symc_encrypt; + func_symc_decrypt harden_symc_decrypt; + func_symc_get_tag harden_symc_get_tag; + func_symc_mac_start harden_symc_mac_start; + func_symc_mac_update harden_symc_mac_update; + func_symc_mac_finish harden_symc_mac_finish; + func_pke_init harden_pke_init; + func_pke_deinit harden_pke_deinit; + func_pke_mod harden_pke_mod; + func_pke_exp_mod harden_pke_exp_mod; + func_pke_ecc_gen_key harden_pke_ecc_gen_key; + func_pke_ecdsa_sign harden_pke_ecdsa_sign; + func_pke_ecdsa_verify harden_pke_ecdsa_verify; + func_pke_eddsa_sign harden_pke_eddsa_sign; + func_pke_eddsa_verify harden_pke_eddsa_verify; + func_pke_gen_ecdh_key harden_pke_gen_ecdh_key; + func_pke_check_dot_on_curve harden_pke_check_dot_on_curve; + func_pke_rsa_sign harden_pke_rsa_sign; + func_pke_rsa_verify harden_pke_rsa_verify; + func_pke_rsa_public_encrypt harden_pke_rsa_public_encrypt; + func_pke_rsa_private_decrypt harden_pke_rsa_private_decrypt; +} mbedtls_harden_cipher_func; + +typedef struct { + func_km_init harden_km_init; + func_km_deinit harden_km_deinit; + func_km_create_keyslot harden_km_create_keyslot; + func_km_destroy_keyslot harden_km_destroy_keyslot; + func_km_set_clear_key harden_km_set_clear_key; +} mbedtls_harden_km_func; + +typedef struct { + func_alloc_phys_buf harden_alloc_phys_buf; + func_free_phys_buf harden_free_phys_buf; + func_get_phys_addr harden_get_phys_addr; +} mbedtls_harden_mem_func; + +td_void mbedtls_cipher_adapt_register_func(mbedtls_harden_cipher_func *harden_cipher_func); +td_void mbedtls_km_adapt_register_func(mbedtls_harden_km_func *harden_km_func); +td_void mbedtls_mem_adapt_register_func(mbedtls_harden_mem_func *harden_mem_func); + +td_s32 mbedtls_adapt_create_keyslot(td_handle *keyslot_handle, km_keyslot_engine key_engine) +{ + td_s32 ret = TD_SUCCESS; + crypto_handle ks_handle = 0; + km_keyslot_type keyslot_type = KM_KEYSLOT_TYPE_MCIPHER; + crypto_chk_return(keyslot_handle == TD_NULL, TD_FAILURE, "keyslot_handle is null\n"); + if (key_engine == KM_KEYSLOT_ENGINE_HMAC_SHA1 || key_engine == KM_KEYSLOT_ENGINE_HMAC_SHA224 || + key_engine == KM_KEYSLOT_ENGINE_HMAC_SHA256 || key_engine == KM_KEYSLOT_ENGINE_HMAC_SHA384 || + key_engine == KM_KEYSLOT_ENGINE_HMAC_SHA512 || key_engine == KM_KEYSLOT_ENGINE_HMAC_SM3) { + keyslot_type = KM_KEYSLOT_TYPE_HMAC; + } + ret = uapi_keyslot_create(&ks_handle, keyslot_type); + if (ret != TD_SUCCESS) { + crypto_print("uapi_keyslot_create failed\n"); + return ret; + } + *keyslot_handle = (td_handle)ks_handle; + return ret; +} + +static td_s32 inner_set_klad_attr(km_klad_attr *klad_attr, km_keyslot_engine key_engine) +{ + td_u32 offset = TEE_ENABLE_OFFSET; + td_u8 tee_enable = 0; + klad_attr->key_cfg.decrypt_support = TD_TRUE; + klad_attr->key_cfg.encrypt_support = TD_TRUE; + (td_void)uapi_otp_init(); + (td_void)uapi_otp_read_byte(offset, &tee_enable); + (td_void)uapi_otp_deinit(); + if (tee_enable != TEE_DISABLE_VALUE) { + klad_attr->key_sec_cfg.key_sec = KM_KLAD_SEC_DISABLE; + klad_attr->key_sec_cfg.master_only_enable = TD_FALSE; + klad_attr->key_sec_cfg.dest_buf_sec_support = TD_FALSE; + klad_attr->key_sec_cfg.src_buf_sec_support = TD_FALSE; + klad_attr->key_sec_cfg.dest_buf_non_sec_support = TD_TRUE; + klad_attr->key_sec_cfg.src_buf_non_sec_support = TD_TRUE; + } else { + klad_attr->key_sec_cfg.key_sec = KM_KLAD_SEC_ENABLE; + klad_attr->key_sec_cfg.master_only_enable = TD_TRUE; + klad_attr->key_sec_cfg.dest_buf_sec_support = TD_TRUE; + klad_attr->key_sec_cfg.src_buf_sec_support = TD_TRUE; + klad_attr->key_sec_cfg.dest_buf_non_sec_support = TD_FALSE; + klad_attr->key_sec_cfg.src_buf_non_sec_support = TD_FALSE; + } + switch (key_engine) { + case KM_KEYSLOT_ENGINE_AES: + klad_attr->key_cfg.engine = KM_CRYPTO_ALG_AES; + break; + case KM_KEYSLOT_ENGINE_SM4: + klad_attr->key_cfg.engine = KM_CRYPTO_ALG_SM4; + break; + case KM_KEYSLOT_ENGINE_HMAC_SHA1: + klad_attr->key_cfg.engine = KM_CRYPTO_ALG_HMAC_SHA1; + break; + case KM_KEYSLOT_ENGINE_HMAC_SHA224: + case KM_KEYSLOT_ENGINE_HMAC_SHA256: + case KM_KEYSLOT_ENGINE_HMAC_SHA384: + case KM_KEYSLOT_ENGINE_HMAC_SHA512: + klad_attr->key_cfg.engine = KM_CRYPTO_ALG_HMAC_SHA2; + break; + case KM_KEYSLOT_ENGINE_HMAC_SM3: + klad_attr->key_cfg.engine = KM_CRYPTO_ALG_HMAC_SM3; + break; + default: + crypto_print("invalid keyslot_engine\n"); + return TD_FAILURE; + } + return TD_SUCCESS; +} + +static td_s32 inner_set_key_cfg(km_klad_clear_key *clear_key, td_u8 *key, td_u32 keylen, km_keyslot_engine key_engine) +{ + clear_key->key = key; + clear_key->key_size = keylen; + switch (key_engine) { + case KM_KEYSLOT_ENGINE_AES: + case KM_KEYSLOT_ENGINE_SM4: + break; + case KM_KEYSLOT_ENGINE_HMAC_SHA1: + clear_key->hmac_type = KM_KLAD_HMAC_SHA1; + break; + case KM_KEYSLOT_ENGINE_HMAC_SHA224: + clear_key->hmac_type = KM_KLAD_HMAC_SHA224; + break; + case KM_KEYSLOT_ENGINE_HMAC_SHA256: + clear_key->hmac_type = KM_KLAD_HMAC_SHA256; + break; + case KM_KEYSLOT_ENGINE_HMAC_SHA384: + clear_key->hmac_type = KM_KLAD_HMAC_SHA384; + break; + case KM_KEYSLOT_ENGINE_HMAC_SHA512: + clear_key->hmac_type = KM_KLAD_HMAC_SHA512; + break; + case KM_KEYSLOT_ENGINE_HMAC_SM3: + clear_key->hmac_type = KM_KLAD_HMAC_SM3; + break; + default: + crypto_print("invalid keyslot_engine\n"); + return TD_FAILURE; + } + return TD_SUCCESS; +} + +td_s32 mbedtls_adapt_set_clear_key(td_handle keyslot_handle, td_u8 *key, td_u32 keylen, km_keyslot_engine key_engine) +{ + crypto_handle klad_handle = 0; + td_s32 ret = TD_SUCCESS; + km_klad_attr klad_attr = {0}; + km_klad_clear_key clear_key = {0}; + km_klad_dest_type klad_type = KM_KLAD_DEST_TYPE_MCIPHER; + + crypto_chk_return(key == TD_NULL, TD_FAILURE, "key is null\n"); + + if (key_engine == KM_KEYSLOT_ENGINE_HMAC_SHA1 || key_engine == KM_KEYSLOT_ENGINE_HMAC_SHA224 || + key_engine == KM_KEYSLOT_ENGINE_HMAC_SHA256 || key_engine == KM_KEYSLOT_ENGINE_HMAC_SHA384 || + key_engine == KM_KEYSLOT_ENGINE_HMAC_SHA512 || key_engine == KM_KEYSLOT_ENGINE_HMAC_SM3) { + klad_type = KM_KLAD_DEST_TYPE_HMAC; + } + + ret = inner_set_klad_attr(&klad_attr, key_engine); + crypto_chk_return(ret != TD_SUCCESS, TD_FAILURE); + + ret = inner_set_key_cfg(&clear_key, key, keylen, key_engine); + crypto_chk_return(ret != TD_SUCCESS, TD_FAILURE); + + ret = uapi_klad_create(&klad_handle); + crypto_chk_return(ret != TD_SUCCESS, TD_FAILURE, "uapi_klad_create failed\n"); + + ret = uapi_klad_attach(klad_handle, klad_type, keyslot_handle); + crypto_chk_goto(ret != TD_SUCCESS, error_destroy_klad, "uapi_klad_attach failed\n"); + + ret = uapi_klad_set_attr(klad_handle, &klad_attr); + crypto_chk_goto(ret != TD_SUCCESS, error_klad_detach, "uapi_klad_set_attr failed\n"); + + ret = uapi_klad_set_clear_key(klad_handle, &clear_key); + crypto_chk_goto(ret != TD_SUCCESS, error_klad_detach, "uapi_klad_set_clear_key failed\n"); + + (td_void)uapi_klad_detach(klad_handle, klad_type, keyslot_handle); + (td_void)uapi_klad_destroy(klad_handle); + + return ret; +error_klad_detach: + (td_void)uapi_klad_detach(klad_handle, klad_type, keyslot_handle); +error_destroy_klad: + (td_void)uapi_klad_destroy(klad_handle); + return ret; +} + +td_void mbedtls_adapt_destroy_keyslot(td_handle keyslot_handle) +{ + crypto_handle ks_handle = 0; + ks_handle = keyslot_handle; + (td_void)uapi_keyslot_destroy(ks_handle); +} + +td_s32 mbedtls_adapt_alloc_buf_attr(crypto_buf_attr *buf_attr, td_void **virt_addr, td_u32 size) +{ + td_s32 ret; + crypto_chk_return(buf_attr == TD_NULL, TD_FAILURE, "buf_attr is null\n"); + td_phys_addr_t phys_addr; + ret = ot_mpi_sys_mmz_alloc(&phys_addr, virt_addr, NULL, NULL, size); + if (ret != TD_SUCCESS) { + crypto_print("uapi_sys_mmz_alloc failed\n"); + return -1; + } + buf_attr->phys_addr = (td_ulong)phys_addr; + return TD_SUCCESS; +} + +td_void mbedtls_adapt_free_buf_attr(crypto_buf_attr *buf_attr, td_void *virt_addr, td_u32 size) +{ + (td_void)(size); + if (buf_attr == TD_NULL) { + crypto_print("buf_attr is null\n"); + return; + } + if (virt_addr != TD_NULL) { + (td_void)ot_mpi_sys_mmz_free((td_phys_addr_t)buf_attr->phys_addr, virt_addr); + } +} + +td_s32 mbedtls_adapt_get_phys_mem(td_void *virt_addr, td_ulong *phys_addr) +{ + td_s32 ret; + ot_sys_mem_info mem_info = {0}; + crypto_chk_return(phys_addr == TD_NULL, TD_FAILURE, "phys_addr is null\n"); + ret = ot_mpi_sys_get_mem_info_by_virt(virt_addr, &mem_info); + if (ret == TD_SUCCESS) { + *phys_addr = (td_ulong)mem_info.phys_addr + (td_ulong)mem_info.offset; + return ret; + } + return TD_FAILURE; +} + +mbedtls_harden_cipher_func harden_cipher_func = { + .harden_hash_init = unify_uapi_cipher_hash_init, + .harden_hash_deinit = unify_uapi_cipher_hash_deinit, + .harden_hash_start = unify_uapi_cipher_hash_start, + .harden_hash_update = unify_uapi_cipher_hash_update, + .harden_hash_get = unify_uapi_cipher_hash_get, + .harden_hash_set = unify_uapi_cipher_hash_set, + .harden_hash_destroy = unify_uapi_cipher_hash_destroy, + .harden_hash_finish = unify_uapi_cipher_hash_finish, + .harden_hkdf = TD_NULL, + .harden_hkdf_extract = TD_NULL, + .harden_hkdf_expand = TD_NULL, + .harden_trng_get_random = unify_uapi_cipher_trng_get_random, + .harden_trng_get_multi_random = unify_uapi_cipher_trng_get_multi_random, + .harden_pbkdf2 = unify_uapi_cipher_pbkdf2, + .harden_symc_init = unify_uapi_cipher_symc_init, + .harden_symc_deinit = unify_uapi_cipher_symc_deinit, + .harden_symc_create = unify_uapi_cipher_symc_create, + .harden_symc_destroy = unify_uapi_cipher_symc_destroy, + .harden_symc_set_config = unify_uapi_cipher_symc_set_config, + .harden_symc_get_config = unify_uapi_cipher_symc_get_config, + .harden_symc_attach = unify_uapi_cipher_symc_attach, + .harden_symc_encrypt = unify_uapi_cipher_symc_encrypt, + .harden_symc_decrypt = unify_uapi_cipher_symc_decrypt, + .harden_symc_get_tag= unify_uapi_cipher_symc_get_tag, + .harden_symc_mac_start = unify_uapi_cipher_mac_start, + .harden_symc_mac_update = unify_uapi_cipher_mac_update, + .harden_symc_mac_finish = unify_uapi_cipher_mac_finish, + .harden_pke_init = unify_uapi_cipher_pke_init, + .harden_pke_deinit = unify_uapi_cipher_pke_deinit, + .harden_pke_mod = unify_uapi_cipher_pke_mod, + .harden_pke_exp_mod = unify_uapi_cipher_pke_exp_mod, + .harden_pke_ecc_gen_key = unify_uapi_cipher_pke_ecc_gen_key, + .harden_pke_ecdsa_sign = unify_uapi_cipher_pke_ecdsa_sign, + .harden_pke_ecdsa_verify = unify_uapi_cipher_pke_ecdsa_verify, + .harden_pke_eddsa_sign = unify_uapi_cipher_pke_eddsa_sign, + .harden_pke_eddsa_verify = unify_uapi_cipher_pke_eddsa_verify, + .harden_pke_gen_ecdh_key = unify_uapi_cipher_pke_ecc_gen_ecdh_key, + .harden_pke_check_dot_on_curve = unify_uapi_cipher_pke_check_dot_on_curve, + .harden_pke_rsa_sign = unify_uapi_cipher_pke_rsa_sign, + .harden_pke_rsa_verify = unify_uapi_cipher_pke_rsa_verify, + .harden_pke_rsa_public_encrypt = unify_uapi_cipher_pke_rsa_public_encrypt, + .harden_pke_rsa_private_decrypt = unify_uapi_cipher_pke_rsa_private_decrypt, +}; + +mbedtls_harden_km_func harden_km_func = { + .harden_km_init = uapi_km_init, + .harden_km_deinit = uapi_km_deinit, + .harden_km_create_keyslot = mbedtls_adapt_create_keyslot, + .harden_km_destroy_keyslot = mbedtls_adapt_destroy_keyslot, + .harden_km_set_clear_key = mbedtls_adapt_set_clear_key, +}; + +mbedtls_harden_mem_func harden_mem_func = { + .harden_alloc_phys_buf = mbedtls_adapt_alloc_buf_attr, + .harden_free_phys_buf = mbedtls_adapt_free_buf_attr, + .harden_get_phys_addr = mbedtls_adapt_get_phys_mem, +}; + +td_s32 mbedtls_adapt_register_func() +{ + mbedtls_cipher_adapt_register_func(&harden_cipher_func); + mbedtls_km_adapt_register_func(&harden_km_func); + mbedtls_mem_adapt_register_func(&harden_mem_func); + return TD_SUCCESS; +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/mbedtls_harden_adapt/mbedtls_harden_adapt.h b/kernel/security_subsys/hi3519dv500/mbedtls_harden_adapt/mbedtls_harden_adapt.h new file mode 100644 index 00000000..453c2600 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/mbedtls_harden_adapt/mbedtls_harden_adapt.h @@ -0,0 +1,10 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef CRYPTO_MBEDTLS_HARDEN_ADAPT_H +#define CRYPTO_MBEDTLS_HARDEN_ADAPT_H + +int mbedtls_adapt_register_func(void); + +#endif /* CRYPTO_MBEDTLS_HARDEN_ADAPT_H */ \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/otp/mkp/Makefile b/kernel/security_subsys/hi3519dv500/otp/mkp/Makefile new file mode 100644 index 00000000..6f3f5a82 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/otp/mkp/Makefile @@ -0,0 +1,54 @@ +#************************************************************************* +ifeq ($(PARAM_FILE), ) + PARAM_FILE:=../../../../../Makefile.param + include $(PARAM_FILE) +endif + +ifeq ($(CBB_PARAM_FILE), ) + CBB_PARAM_FILE:=../../../Makefile.param + include $(CBB_PARAM_FILE) +endif + +OTP_MKP_DIR := $(PWD) + +# all source file in this module +SRCS:= + +# add include files +MKP_CFLAGS += -I$(OTP_MKP_DIR) -I$(OTP_MKP_DIR)/../../crypto_osal_lib \ + -I$(OTP_MKP_DIR)/../../security_subsys_common/include/common_include \ + -I$(OTP_MKP_DIR)/../../security_subsys_common/include/drv_include \ + -I$(OTP_MKP_DIR)/../../security_subsys_common/include/ioctl_include \ + -I$(OTP_MKP_DIR)/../../security_subsys_common/include/kapi_include \ + -I$(OTP_MKP_DIR)/../../security_subsys_common/include/hal_include \ + -I$(OTP_MKP_DIR)/../../security_subsys_common/dispatch_code \ + -I$(OTP_MKP_DIR)/../../security_subsys_common/drv_code \ + -I$(OTP_MKP_DIR)/../../cipher/mkp -I$(OTP_MKP_DIR)/../../ + +# add compiling macros +MKP_CFLAGS += -DCONFIG_CRYPTO_CHIP_HI3519DV500 + +INIT_FILE := $(OTP_MKP_DIR)/crypto_otp_drv_init.c +INIT_INC := $(OTP_MKP_DIR)/init_otp.h + +MKP_SRCS := crypto_otp_drv_init.c init_otp.c ../../security_subsys_common/dispatch_code/dispatch_otp.c \ + ../../security_subsys_common/kapi_code/kapi_otp.c ../../security_subsys_common/drv_code/drv_otp.c + +DRIVER_OBJS-y += $(patsubst %.c, %.o, $(MKP_SRCS)) + +SRCS += $(MKP_SRCS) + +# Debug +# MKP_CFLAGS += -DCRYPTO_HAL_FUNC_TRACE_ENABLE +# MKP_CFLAGS += -DCRYPTO_KAPI_FUNC_TRACE_ENABLE +# MKP_CFLAGS += -DCRYPTO_DRV_FUNC_TRACE_ENABLE +# MKP_CFLAGS += -DCRYPTO_DISPATCH_FUNC_TRACE_ENABLE + +SRCS_O := $(SRCS) + +#************************************************************************* +TARGET := $(KO_PREFIX)_otp + +#************************************************************************* + +include $(MAKE_DRV_FILE) \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/otp/mkp/crypto_otp_drv_init.c b/kernel/security_subsys/hi3519dv500/otp/mkp/crypto_otp_drv_init.c new file mode 100644 index 00000000..abb206dc --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/otp/mkp/crypto_otp_drv_init.c @@ -0,0 +1,134 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include +#include +#include +#include + +#include + +#include "ot_osal.h" +#include "mm_ext.h" +#include "crypto_common_macro.h" +#include "crypto_osal_lib.h" +#include "crypto_osal_adapt.h" +#include "init_otp.h" + +#ifdef MODULE +static td_void *g_otp_reg_virt = TD_NULL; +static td_void *g_ca_misc_reg_virt = TD_NULL; + +td_u32 crypto_ex_reg_read(reg_region_e region, td_u32 offset) +{ + if (region == REG_REGION_CA_MISC) { + return crypto_reg_read((volatile td_void *)(g_ca_misc_reg_virt + offset)); + } + return crypto_reg_read((volatile td_void *)(g_otp_reg_virt + offset)); +} + +td_void crypto_ex_reg_write(reg_region_e region, td_u32 offset, td_u32 value) +{ + if (region == REG_REGION_CA_MISC) { + crypto_reg_write((volatile td_void *)(g_ca_misc_reg_virt + offset), value); + } + crypto_reg_write((volatile td_void *)(g_otp_reg_virt + offset), value); +} +#else +static int crypto_reg_map(td_void) +{ + td_s32 ret; + + /* CS MISC Region. */ + ret = crypto_register_reg_map_region(REG_REGION_CA_MISC); + crypto_chk_return(ret != TD_SUCCESS, ret, "crypto_register_reg_map_region CA_MISC failed, ret is 0x%x\n", ret); + + /* OTPC Region. */ + ret = crypto_register_reg_map_region(REG_REGION_OTPC); + crypto_chk_goto(ret != TD_SUCCESS, error_ca_misc_unmap, "crypto_register_reg_map_region OTPC failed, \ + ret is 0x%x\n", ret); + + return TD_SUCCESS; +error_ca_misc_unmap: + crypto_unregister_reg_map_region(REG_REGION_CA_MISC); + return TD_FAILURE; +} + +static void crypto_reg_unmap(td_void) +{ + crypto_unregister_reg_map_region(REG_REGION_OTPC); + crypto_unregister_reg_map_region(REG_REGION_CA_MISC); +} +#endif + +static int ot_otp_probe(struct platform_device *pdev) +{ + td_s32 ret = TD_SUCCESS; + +#ifdef MODULE + g_otp_reg_virt = crypto_ioremap_nocache(OTPC_BASE_ADDR, OTPC_ADDR_SIZE); + if (g_otp_reg_virt == TD_NULL) { + crypto_log_err("crypto_ioremap_nocache failed for otp_reg\n"); + return TD_FAILURE; + } + + g_ca_misc_reg_virt = crypto_ioremap_nocache(CA_MISC_REG_BASE_ADDR, CA_MISC_REG_SIZE); + if (g_ca_misc_reg_virt == TD_NULL) { + crypto_log_err("crypto_ioremap_nocache failed for ca_misc_reg\n"); + crypto_iounmap(g_otp_reg_virt, OTPC_ADDR_SIZE); + return TD_FAILURE; + } +#else + ret = crypto_reg_map(); + crypto_chk_return(ret != TD_SUCCESS, ret, "crypto_reg_map failed, ret is 0x%x\n", ret); +#endif + + ret = crypto_otp_init(); + crypto_chk_goto(ret != TD_SUCCESS, reg_unmap_error, "crypto_otp_init failed, ret is 0x%x\n", ret); + + crypto_print("load ot_otp.ko ....OK!\n"); + + return ret; + +reg_unmap_error: +#ifdef MODULE + crypto_iounmap(g_ca_misc_reg_virt, CA_MISC_REG_SIZE); + crypto_iounmap(g_otp_reg_virt, OTPC_ADDR_SIZE); +#else + crypto_reg_unmap(); +#endif + return ret; +} + +static int ot_otp_remove(struct platform_device *pdev) +{ + crypto_unused(pdev); + crypto_otp_deinit(); +#ifdef MODULE + crypto_iounmap(g_ca_misc_reg_virt, CA_MISC_REG_SIZE); + crypto_iounmap(g_otp_reg_virt, OTPC_ADDR_SIZE); +#else + crypto_reg_unmap(); +#endif + crypto_print("unload ot_otp.ko ....OK!\n"); + return TD_SUCCESS; +} + +static const struct of_device_id g_ot_otp_match[] = { + { .compatible = "vendor,otp" }, + { }, +}; +MODULE_DEVICE_TABLE(of, g_ot_otp_match); + +static struct platform_driver g_ot_otp_driver = { + .probe = ot_otp_probe, + .remove = ot_otp_remove, + .driver = { + .name = "ot_otp", + .of_match_table = g_ot_otp_match, + }, +}; + +osal_module_platform_driver(g_ot_otp_driver); +MODULE_LICENSE("GPL"); diff --git a/kernel/security_subsys/hi3519dv500/otp/mkp/init_otp.c b/kernel/security_subsys/hi3519dv500/otp/mkp/init_otp.c new file mode 100644 index 00000000..df9d4b8f --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/otp/mkp/init_otp.c @@ -0,0 +1,81 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "init_otp.h" + +#include +#include +#include +#include + +#include + +#include "ot_osal.h" +#include "mm_ext.h" +#include "kapi_otp.h" +#include "dispatch_otp.h" +#include "crypto_osal_adapt.h" +#include "crypto_common_macro.h" +#include "crypto_osal_lib.h" + +static td_s32 ot_otp_open(td_void *private_data) +{ + crypto_unused(private_data); + return TD_SUCCESS; +} + +static td_s32 ot_otp_release(td_void *private_data) +{ + crypto_unused(private_data); + return TD_SUCCESS; +} + +static osal_fileops g_dev_otp_fops = { + .open = ot_otp_open, + .release = ot_otp_release, + .cmd_list = TD_NULL, + .cmd_cnt = 0 +}; + +static osal_dev *g_otp_dev = TD_NULL; + +td_s32 crypto_otp_init(td_void) +{ + td_s32 ret; + + g_otp_dev = osal_dev_create("otp"); + crypto_chk_return(g_otp_dev == TD_NULL, TD_FAILURE, "osal_dev_create failed\n"); + + g_dev_otp_fops.cmd_list = get_otp_func_list(); + g_dev_otp_fops.cmd_cnt = get_otp_func_num(); + + g_otp_dev->minor = UMAP_OTP_MINOR_BASE; + g_otp_dev->fops = &g_dev_otp_fops; + + ret = osal_dev_register(g_otp_dev); + crypto_chk_goto(ret != TD_SUCCESS, error_dev_destroy, "osal_dev_register failed, ret is 0x%x\n", ret); + + ret = kapi_otp_init(); + crypto_chk_goto(ret != TD_SUCCESS, error_dev_unregister, "kapi_otp_init failed, ret is 0x%x\n", ret); + + return ret; + +error_dev_unregister: + osal_dev_unregister(g_otp_dev); +error_dev_destroy: + if (g_otp_dev != TD_NULL) { + osal_dev_destroy(g_otp_dev); + g_otp_dev = TD_NULL; + } + return TD_FAILURE; +} + +td_void crypto_otp_deinit(td_void) +{ + kapi_otp_deinit(); + osal_dev_unregister(g_otp_dev); + osal_dev_destroy(g_otp_dev); + + g_otp_dev = TD_NULL; +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/otp/mkp/init_otp.h b/kernel/security_subsys/hi3519dv500/otp/mkp/init_otp.h new file mode 100644 index 00000000..3e43f42b --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/otp/mkp/init_otp.h @@ -0,0 +1,16 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef CRYPTO_OTP_INIT_H +#define CRYPTO_OTP_INIT_H + +#include "ot_type.h" + +#define UMAP_OTP_MINOR_BASE 57 + +/* OTP. */ +td_s32 crypto_otp_init(td_void); +td_void crypto_otp_deinit(td_void); + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/otp/mpi/Makefile b/kernel/security_subsys/hi3519dv500/otp/mpi/Makefile new file mode 100644 index 00000000..f301fef0 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/otp/mpi/Makefile @@ -0,0 +1,30 @@ +ifeq ($(PARAM_FILE), ) + PARAM_FILE:=../../../../../Makefile.param + include $(PARAM_FILE) +endif + +ifeq ($(CBB_PARAM_FILE), ) + CBB_PARAM_FILE:=../../../Makefile.param + include $(CBB_PARAM_FILE) +endif + +MPI_SRC_DIR += $(PWD)/../../security_subsys_common/ot_mpi +MPI_SRC_DIR += $(PWD)/../../security_subsys_common/uapi_code +MPI_SRC_C := ot_mpi_otp.c uapi_otp.c +MPI_CFLAGS += -I$(PWD)/../../crypto_osal_lib \ + -I$(PWD)/../../security_subsys_common/include/uapi_include \ + -I$(PWD)/../../security_subsys_common/include/common_include \ + -I$(PWD)/../../security_subsys_common/include/ioctl_include \ + -I$(PWD)/../../security_subsys_common/ot_mpi_api + +# Debug +# MPI_CFLAGS += -DCRYPTO_UAPI_TRNG_DEBUG_ENABLE +MPI_CFLAGS += -DCONFIG_CRYPTO_CHIP_HI3519DV500 + +#************************************************************************* +# release header +INC_FILE := $(wildcard ../../security_subsys_common/ot_mpi_api/ot_mpi_otp.h) + +LIB_NAME := ot_mpi_otp + +include $(MAKE_MPI_FILE) \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/dispatch_code/crypto_dispatch.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/dispatch_code/crypto_dispatch.c new file mode 100644 index 00000000..f238db00 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/dispatch_code/crypto_dispatch.c @@ -0,0 +1,2125 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "crypto_dispatch.h" +#include "crypto_ioctl_cmd.h" +#include "kapi_hash.h" +#include "kapi_trng.h" +#include "kapi_symc.h" +#include "kapi_pke.h" + +#define SYMC_COMPAT_ERRNO(err_code) DISPATCH_COMPAT_ERRNO(ERROR_MODULE_SYMC, err_code) +#define HASH_COMPAT_ERRNO(err_code) DISPATCH_COMPAT_ERRNO(ERROR_MODULE_HASH, err_code) +#define PKE_COMPAT_ERRNO(err_code) DISPATCH_COMPAT_ERRNO(ERROR_MODULE_PKE, err_code) +#define TRNG_COMPAT_ERRNO(err_code) DISPATCH_COMPAT_ERRNO(ERROR_MODULE_TRNG, err_code) + +#if defined(CONFIG_CRYPTO_DISPATCH_CMD_CHK_ENABLE) +#define dispatch_symc_cmd_chk(expected_cmd) \ + crypto_chk_return(cmd != (expected_cmd), SYMC_COMPAT_ERRNO(ERROR_CMD_DISMATCH), \ + "cmd is dismatched, real cmd is 0x%x, expected_cmd is 0x%x\n", cmd, (td_u32)(expected_cmd)) +#define dispatch_hash_cmd_chk(expected_cmd) \ + crypto_chk_return(cmd != (expected_cmd), HASH_COMPAT_ERRNO(ERROR_CMD_DISMATCH), \ + "cmd is dismatched, real cmd is 0x%x, expected_cmd is 0x%x\n", cmd, (td_u32)(expected_cmd)) +#define dispatch_pke_cmd_chk(expected_cmd) \ + crypto_chk_return(cmd != (expected_cmd), PKE_COMPAT_ERRNO(ERROR_CMD_DISMATCH), \ + "cmd is dismatched, real cmd is 0x%x, expected_cmd is 0x%x\n", cmd, (td_u32)(expected_cmd)) +#define dispatch_trng_cmd_chk(expected_cmd) \ + crypto_chk_return(cmd != (expected_cmd), TRNG_COMPAT_ERRNO(ERROR_CMD_DISMATCH), \ + "cmd is dismatched, real cmd is 0x%x, expected_cmd is 0x%x\n", cmd, (td_u32)(expected_cmd)) +#else +#define dispatch_symc_cmd_chk(expected_cmd) +#define dispatch_hash_cmd_chk(expected_cmd) +#define dispatch_pke_cmd_chk(expected_cmd) +#define dispatch_trng_cmd_chk(expected_cmd) +#endif + +#define symc_null_ptr_chk(ptr) \ + crypto_chk_return((ptr) == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), #ptr" is NULL\n") +#define hash_null_ptr_chk(ptr) \ + crypto_chk_return((ptr) == TD_NULL, HASH_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), #ptr" is NULL\n") +#define pke_null_ptr_chk(ptr) \ + crypto_chk_return((ptr) == TD_NULL, PKE_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), #ptr" is NULL\n") +#define trng_null_ptr_chk(ptr) \ + crypto_chk_return((ptr) == TD_NULL, TRNG_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), #ptr" is NULL\n") + +#define CRYPTO_MAX_DATA_LEN (64 * 1024) + +/* Notice: For Sensitive Information, You Should Clean it Before Free. */ +#define crypto_chk_free_with_clean(ptr, length, free_func) do { \ + if ((ptr) != NULL) { \ + (td_void)memset_s(ptr, length, 0, length); \ + free_func(ptr); \ + ptr = NULL; \ + } \ +} while (0) + +#define crypto_chk_crypto_free_with_clean(ptr, length) crypto_chk_free_with_clean(ptr, length, crypto_free) + +static td_s32 dispatch_hash_init(td_u32 cmd, td_void *argp, td_void *private_data) +{ + crypto_unused(argp); + crypto_unused(private_data); + dispatch_hash_cmd_chk(CRYPTO_CMD_HASH_INIT); + return kapi_cipher_hash_init(); +} + +static td_s32 dispatch_hash_deinit(td_u32 cmd, td_void *argp, td_void *private_data) +{ + crypto_unused(argp); + crypto_unused(private_data); + dispatch_hash_cmd_chk(CRYPTO_CMD_HASH_DEINIT); + return kapi_cipher_hash_deinit(); +} + +static td_s32 dispatch_hash_start(td_u32 cmd, td_void *argp, td_void *private_data) +{ + td_s32 ret = CRYPTO_SUCCESS; + hash_start_ctl_t *start_ctl = (hash_start_ctl_t *)argp; + crypto_hash_attr hash_attr = { + .hash_type = start_ctl->hash_type, + .is_long_term = start_ctl->is_long_term, + .is_keyslot = start_ctl->is_keyslot, + .key_len = start_ctl->key_len, + .drv_keyslot_handle = start_ctl->drv_keyslot_handle, + }; + td_u8 *hmac_key = TD_NULL; + + crypto_dispatch_func_enter(); + dispatch_hash_cmd_chk(CRYPTO_CMD_HASH_START); + crypto_unused(private_data); + + if ((hash_attr.is_keyslot == TD_FALSE) && (CRYPTO_HASH_IS_HMAC(hash_attr.hash_type) == TD_TRUE) && + (hash_attr.key_len != 0)) { + hash_null_ptr_chk(start_ctl->key.p); + crypto_chk_return(hash_attr.key_len > CRYPTO_HASH_KEY_MAX_LENGTH, HASH_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "key length is too long\n"); + hmac_key = crypto_malloc(hash_attr.key_len); + crypto_chk_return(hmac_key == TD_NULL, HASH_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + + ret = crypto_copy_from_user(hmac_key, hash_attr.key_len, start_ctl->key.p, start_ctl->key_len); + crypto_chk_goto_with_ret(ret != CRYPTO_SUCCESS, exit_clean, HASH_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed\n"); + } + hash_attr.key = hmac_key; + + ret = kapi_cipher_hash_start(&start_ctl->kapi_hash_handle, &hash_attr); + if (ret != CRYPTO_SUCCESS) { + crypto_log_err("kapi_cipher_hash_start failed\n"); + goto exit_clean; + } + +exit_clean: + if (hmac_key != TD_NULL) { + (td_void)memset_s(hmac_key, start_ctl->key_len, 0, start_ctl->key_len); + crypto_free(hmac_key); + } + + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_hash_update(td_u32 cmd, td_void *argp, td_void *private_data) +{ + td_s32 ret = CRYPTO_SUCCESS; + crypto_buf_attr src_buf = {0}; + hash_update_ctl_t *update_ctl = (hash_update_ctl_t *)argp; + td_u8 *data_buffer = TD_NULL; + td_u32 left = update_ctl->len; + td_u32 malloc_size = 0; + td_u32 processing_len = 0; + td_u32 processed_len = 0; + + crypto_dispatch_func_enter(); + crypto_unused(private_data); + dispatch_hash_cmd_chk(CRYPTO_CMD_HASH_UPDATE); + hash_null_ptr_chk(update_ctl->src_buf.p); + + crypto_chk_return(update_ctl->len == 0 || update_ctl->len > CRYPTO_HASH_UPDATE_MAX_LEN, + HASH_COMPAT_ERRNO(ERROR_INVALID_PARAM), "len is invalid\n"); + + malloc_size = crypto_min(CRYPTO_MAX_DATA_LEN, left); + data_buffer = crypto_malloc(malloc_size); + crypto_chk_return(data_buffer == TD_NULL, HASH_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + src_buf.virt_addr = data_buffer; + + while (left > 0) { + processing_len = crypto_min(CRYPTO_MAX_DATA_LEN, left); + ret = crypto_copy_from_user(data_buffer, malloc_size, (td_u8 *)update_ctl->src_buf.p + processed_len, + processing_len); + crypto_chk_goto_with_ret(ret != CRYPTO_SUCCESS, exit_clean, HASH_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed\n"); + + ret = kapi_cipher_hash_update(update_ctl->kapi_hash_handle, &src_buf, processing_len); + crypto_chk_goto(ret != CRYPTO_SUCCESS, exit_clean, "kapi_cipher_hash_update failed\n"); + left -= processing_len; + processed_len += processing_len; + } + +exit_clean: + (td_void)memset_s(data_buffer, malloc_size, 0, malloc_size); + crypto_free(data_buffer); + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_hash_finish(td_u32 cmd, td_void *argp, td_void *private_data) +{ + td_s32 ret = CRYPTO_SUCCESS; + hash_finish_ctl_t *finish_ctl = (hash_finish_ctl_t *)argp; + td_u8 out_hash[CRYPTO_HASH_MAX_LEN] = {0}; + td_u32 out_len = CRYPTO_HASH_MAX_LEN; + + crypto_dispatch_func_enter(); + crypto_unused(private_data); + dispatch_hash_cmd_chk(CRYPTO_CMD_HASH_FINISH); + hash_null_ptr_chk(finish_ctl->out.p); + + ret = kapi_cipher_hash_finish(finish_ctl->kapi_hash_handle, out_hash, &out_len); + crypto_chk_return(ret != CRYPTO_SUCCESS, ret, "kapi_cipher_hash_finish failed\n"); + + ret = crypto_copy_to_user(finish_ctl->out.p, finish_ctl->out_len, out_hash, out_len); + crypto_chk_goto_with_ret(ret != CRYPTO_SUCCESS, exit_clean, HASH_COMPAT_ERRNO(ERROR_COPY_TO_USER), + "crypto_copy_to_user failed\n"); + finish_ctl->out_len = out_len; + +exit_clean: + (td_void)memset_s(out_hash, sizeof(out_hash), 0, sizeof(out_hash)); + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_hash_get(td_u32 cmd, td_void *argp, td_void *private_data) +{ + td_s32 ret = CRYPTO_SUCCESS; + hash_clone_ctl_t *clone_ctl = (hash_clone_ctl_t *)argp; + crypto_hash_clone_ctx *clone_ctx = TD_NULL; + + crypto_unused(private_data); + dispatch_hash_cmd_chk(CRYPTO_CMD_HASH_GET); + hash_null_ptr_chk(clone_ctl->hash_clone_ctx.p); + crypto_chk_return(clone_ctl->ctx_size != sizeof(crypto_hash_clone_ctx), HASH_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "clone_ctx's size is invalid\n"); + clone_ctx = (crypto_hash_clone_ctx *)crypto_malloc(sizeof(crypto_hash_clone_ctx)); + crypto_chk_return(clone_ctx == TD_NULL, HASH_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + + ret = kapi_cipher_hash_get(clone_ctl->kapi_hash_handle, clone_ctx); + crypto_chk_goto(ret != CRYPTO_SUCCESS, exit_clean, "kapi_cipher_hash_get failed\n"); + + ret = crypto_copy_to_user(clone_ctl->hash_clone_ctx.p, clone_ctl->ctx_size, + clone_ctx, sizeof(crypto_hash_clone_ctx)); + crypto_chk_goto_with_ret(ret != CRYPTO_SUCCESS, exit_clean, HASH_COMPAT_ERRNO(ERROR_COPY_TO_USER), + "crypto_copy_to_user failed\n"); + +exit_clean: + (td_void)memset_s(clone_ctx, sizeof(crypto_hash_clone_ctx), 0, sizeof(crypto_hash_clone_ctx)); + crypto_free(clone_ctx); + + return ret; +} + +static td_s32 dispatch_hash_set(td_u32 cmd, td_void *argp, td_void *private_data) +{ + td_s32 ret = CRYPTO_SUCCESS; + hash_clone_ctl_t *clone_ctl = (hash_clone_ctl_t *)argp; + crypto_hash_clone_ctx *clone_ctx = TD_NULL; + crypto_unused(private_data); + dispatch_hash_cmd_chk(CRYPTO_CMD_HASH_SET); + + hash_null_ptr_chk(clone_ctl->hash_clone_ctx.p); + crypto_chk_return(clone_ctl->ctx_size != sizeof(crypto_hash_clone_ctx), HASH_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "clone_ctx's size is invalid\n"); + + clone_ctx = (crypto_hash_clone_ctx *)crypto_malloc(sizeof(crypto_hash_clone_ctx)); + crypto_chk_return(clone_ctx == TD_NULL, HASH_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + + ret = crypto_copy_from_user(clone_ctx, sizeof(crypto_hash_clone_ctx), + clone_ctl->hash_clone_ctx.p, clone_ctl->ctx_size); + crypto_chk_goto_with_ret(ret != CRYPTO_SUCCESS, exit_clean, HASH_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed\n"); + + ret = kapi_cipher_hash_set(clone_ctl->kapi_hash_handle, clone_ctx); + crypto_chk_goto(ret != CRYPTO_SUCCESS, exit_clean, "kapi_cipher_hash_set failed\n"); + +exit_clean: + (td_void)memset_s(clone_ctx, sizeof(crypto_hash_clone_ctx), 0, sizeof(crypto_hash_clone_ctx)); + crypto_free(clone_ctx); + return ret; +} + +static td_s32 dispatch_hash_destroy(td_u32 cmd, td_void *argp, td_void *private_data) +{ + td_s32 ret = CRYPTO_SUCCESS; + hash_handle_ctl_t *handle_ctl = (hash_handle_ctl_t *)argp; + crypto_unused(private_data); + dispatch_hash_cmd_chk(CRYPTO_CMD_HASH_DESTROY); + + ret = kapi_cipher_hash_destroy(handle_ctl->kapi_hash_handle); + if (ret != CRYPTO_SUCCESS) { + crypto_log_err("kapi_cipher_hash_destroy failed, ret is 0x%x\n", ret); + return ret; + } + + return ret; +} + +static td_s32 dispatch_cipher_pbkdf2(td_u32 cmd, td_void *argp, td_void *private_data) +{ + td_s32 ret = CRYPTO_SUCCESS; + pbkdf2_ctl_t *pbkdf2_ctl = (pbkdf2_ctl_t *)argp; + td_u8 *password = TD_NULL; + td_u8 *salt = TD_NULL; + td_u8 *out = TD_NULL; + td_u8 *buffer = TD_NULL; + crypto_kdf_pbkdf2_param param = {0}; + td_u32 total_len = 0; + crypto_unused(private_data); + dispatch_hash_cmd_chk(CRYPTO_CMD_PBKDF2); + + hash_null_ptr_chk(pbkdf2_ctl->out.p); + crypto_chk_return(pbkdf2_ctl->out_len == 0 || pbkdf2_ctl->out_len > CRYPTO_PBKDF2_OUT_MAX_LENGTH, + HASH_COMPAT_ERRNO(ERROR_INVALID_PARAM), "out_len is Invalid\n"); + crypto_chk_return(pbkdf2_ctl->plen > CRYPTO_PBKDF2_PASS_MAX_LENGTH, HASH_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "plen is too long!\n"); + crypto_chk_return(pbkdf2_ctl->slen > CRYPTO_PBKDF2_SALT_MAX_LENGTH, HASH_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "slen is too long!\n"); + + total_len = pbkdf2_ctl->plen + pbkdf2_ctl->slen + pbkdf2_ctl->out_len; + buffer = crypto_malloc(total_len); + crypto_chk_return(buffer == TD_NULL, HASH_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + + password = buffer; + if (pbkdf2_ctl->plen != 0) { + crypto_chk_goto_with_ret(pbkdf2_ctl->password.p == TD_NULL, exit_free, HASH_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), + "pbkdf2_ctl->password.p is NULL\n"); + ret = crypto_copy_from_user(password, total_len, pbkdf2_ctl->password.p, pbkdf2_ctl->plen); + crypto_chk_goto_with_ret(ret != CRYPTO_SUCCESS, exit_free, HASH_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed\n"); + } + + salt = password + pbkdf2_ctl->plen; + if (pbkdf2_ctl->slen != 0) { + crypto_chk_goto_with_ret(pbkdf2_ctl->salt.p == TD_NULL, exit_free, HASH_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), + "pbkdf2_ctl->salt.p is NULL\n"); + ret = crypto_copy_from_user(salt, total_len - pbkdf2_ctl->plen, pbkdf2_ctl->salt.p, pbkdf2_ctl->slen); + crypto_chk_goto_with_ret(ret != CRYPTO_SUCCESS, exit_free, HASH_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed\n"); + } + + out = salt + pbkdf2_ctl->slen; + param.hash_type = pbkdf2_ctl->hash_type; + param.password = (pbkdf2_ctl->plen == 0) ? TD_NULL : password; + param.plen = pbkdf2_ctl->plen; + param.salt = (pbkdf2_ctl->slen == 0) ? TD_NULL : salt; + param.slen = pbkdf2_ctl->slen; + param.count = pbkdf2_ctl->count; + + ret = kapi_cipher_pbkdf2(¶m, out, pbkdf2_ctl->out_len); + crypto_chk_goto(ret != CRYPTO_SUCCESS, exit_free, "kapi_cipher_pbkdf2 failed\n"); + + ret = crypto_copy_to_user(pbkdf2_ctl->out.p, pbkdf2_ctl->out_len, out, pbkdf2_ctl->out_len); + crypto_chk_goto_with_ret(ret != CRYPTO_SUCCESS, exit_free, HASH_COMPAT_ERRNO(ERROR_COPY_TO_USER), + "crypto_copy_to_user failed\n"); + +exit_free: + (td_void)memset_s(buffer, total_len, 0, total_len); + crypto_free(buffer); + return ret; +} + +static td_s32 dispatch_trng_get_random(td_u32 cmd, td_void *argp, td_void *private_data) +{ + td_s32 ret = CRYPTO_SUCCESS; + trng_ctl_t *trng_ctl = (trng_ctl_t *)argp; + crypto_unused(private_data); + dispatch_trng_cmd_chk(CRYPTO_CMD_TRNG_GET_RANDOM); + ret = kapi_cipher_trng_get_random(&trng_ctl->randnum); + if (ret != CRYPTO_SUCCESS) { + crypto_log_err("kapi_cipher_trng_get_random failed\n"); + return ret; + } + return ret; +} + +static td_s32 dispatch_trng_get_multi_random(td_u32 cmd, td_void *argp, td_void *private_data) +{ + td_s32 ret = CRYPTO_SUCCESS; + trng_multi_ctl_t *trng_multi_ctl = (trng_multi_ctl_t *)argp; + td_u32 size = 0; + td_u8 *randnum; + crypto_unused(private_data); + dispatch_trng_cmd_chk(CRYPTO_CMD_TRNG_GET_MULTI_RANDOM); + + trng_null_ptr_chk(trng_multi_ctl->randnum.p); + size = trng_multi_ctl->size; + crypto_chk_return(size == 0 || size > CRYPTO_MULTI_RANDOM_MAX_LENGTH, TRNG_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "size is invalid!\n"); + randnum = crypto_malloc(size); + crypto_chk_return(randnum == TD_NULL, TRNG_COMPAT_ERRNO(ERROR_INVALID_PARAM), "crypto_malloc failed\n"); + ret = kapi_cipher_trng_get_multi_random(size, randnum); + if (ret != CRYPTO_SUCCESS) { + crypto_log_err("kapi_cipher_trng_get_multi_random failed\n"); + goto exit_free; + } + ret = crypto_copy_to_user(trng_multi_ctl->randnum.p, size, randnum, size); + crypto_chk_goto_with_ret(ret != CRYPTO_SUCCESS, exit_free, TRNG_COMPAT_ERRNO(ERROR_COPY_TO_USER), + "crypto_copy_to_user failed\n"); +exit_free: + if (randnum != TD_NULL) { + (void)memset_s(randnum, size, 0, size); + crypto_free(randnum); + } + return ret; +} + +static td_s32 dispatch_symc_init(td_u32 cmd, td_void *argp, td_void *private_data) +{ + crypto_unused(argp); + crypto_unused(private_data); + dispatch_symc_cmd_chk(CRYPTO_CMD_SYMC_INIT); + return kapi_cipher_symc_init(); +} + +static td_s32 dispatch_symc_deinit(td_u32 cmd, td_void *argp, td_void *private_data) +{ + crypto_unused(argp); + crypto_unused(private_data); + dispatch_symc_cmd_chk(CRYPTO_CMD_SYMC_DEINIT); + return kapi_cipher_symc_deinit(); +} + +static td_s32 dispatch_symc_create(td_u32 cmd, td_void *argp, td_void *private_data) +{ + td_s32 ret; + symc_create_t *symc_create = (symc_create_t *)argp; + crypto_dispatch_func_enter(); + crypto_unused(private_data); + dispatch_symc_cmd_chk(CRYPTO_CMD_SYMC_CREATE); + + ret = kapi_cipher_symc_create(&symc_create->symc_handle, &symc_create->symc_attr); + if (ret != CRYPTO_SUCCESS) { + crypto_log_err("kapi_cipher_symc_create failed\n"); + return ret; + } + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_symc_destroy(td_u32 cmd, td_void *argp, td_void *private_data) +{ + td_s32 ret; + symc_destroy_t *symc_destroy = (symc_destroy_t *)argp; + crypto_dispatch_func_enter(); + crypto_unused(private_data); + dispatch_symc_cmd_chk(CRYPTO_CMD_SYMC_DESTROY); + + ret = kapi_cipher_symc_destroy(symc_destroy->symc_handle); + if (ret != CRYPTO_SUCCESS) { + crypto_log_err("kapi_cipher_symc_destroy failed\n"); + return ret; + } + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_symc_set_config(td_u32 cmd, td_void *argp, td_void *private_data) +{ + td_s32 ret; + symc_config_t *symc_config = (symc_config_t *)argp; + crypto_symc_ctrl_t symc_ctrl = {0}; + crypto_symc_config_aes_ccm_gcm ccm_gcm_config; + td_u8 *aad_buf = TD_NULL; + td_u32 aad_len = symc_config->aad_len; + + crypto_dispatch_func_enter(); + crypto_unused(private_data); + dispatch_symc_cmd_chk(CRYPTO_CMD_SYMC_SET_CONFIG); + + (td_void)memset_s(&ccm_gcm_config, sizeof(ccm_gcm_config), 0, sizeof(ccm_gcm_config)); + symc_ctrl.symc_alg = symc_config->symc_alg; + symc_ctrl.work_mode = symc_config->work_mode; + symc_ctrl.symc_bit_width = symc_config->symc_bit_width; + symc_ctrl.symc_key_length = symc_config->symc_key_length; + symc_ctrl.iv_change_flag = symc_config->iv_change_flag; + symc_ctrl.iv_length = symc_config->iv_length; + ret = memcpy_s(symc_ctrl.iv, sizeof(symc_ctrl.iv), symc_config->iv, sizeof(symc_config->iv)); + crypto_chk_return(ret != EOK, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + if (symc_config->work_mode == CRYPTO_SYMC_WORK_MODE_GCM || symc_config->work_mode == CRYPTO_SYMC_WORK_MODE_CCM) { + crypto_chk_return(aad_len > CRYPTO_SYMC_AAD_MAX_SIZE, SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "aad_len is too long\n"); + ccm_gcm_config.aad_len = aad_len; + ccm_gcm_config.data_len = symc_config->data_len; + ccm_gcm_config.tag_len = symc_config->tag_len; + if (aad_len != 0) { + symc_null_ptr_chk(symc_config->aad.p); + aad_buf = crypto_malloc(aad_len); + crypto_chk_return(aad_buf == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + + ret = crypto_copy_from_user(aad_buf, aad_len, symc_config->aad.p, aad_len); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, exit_free, SYMC_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed\n"); + ccm_gcm_config.aad_buf.virt_addr = aad_buf; + } + symc_ctrl.param = (td_void *)&ccm_gcm_config; + } + + ret = kapi_cipher_symc_set_config(symc_config->symc_handle, &symc_ctrl); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "kapi_cipher_symc_set_config failed\n"); + +exit_free: + if (aad_buf != TD_NULL) { + (td_void)memset_s(aad_buf, aad_len, 0, aad_len); + crypto_free(aad_buf); + } + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_symc_get_config(td_u32 cmd, td_void *argp, td_void *private_data) +{ + td_s32 ret; + symc_config_t *symc_config = (symc_config_t *)argp; + crypto_symc_ctrl_t symc_ctrl = {0}; + crypto_symc_config_aes_ccm_gcm ccm_gcm_config; + + crypto_dispatch_func_enter(); + crypto_unused(private_data); + dispatch_symc_cmd_chk(CRYPTO_CMD_SYMC_GET_CONFIG); + + (td_void)memset_s(&ccm_gcm_config, sizeof(ccm_gcm_config), 0, sizeof(ccm_gcm_config)); + symc_ctrl.param = (td_void *)&ccm_gcm_config; + + ret = kapi_cipher_symc_get_config(symc_config->symc_handle, &symc_ctrl); + crypto_chk_return(ret != TD_SUCCESS, ret, "kapi_cipher_symc_get_config failed\n"); + + symc_config->symc_alg = symc_ctrl.symc_alg; + symc_config->work_mode = symc_ctrl.work_mode; + symc_config->symc_bit_width = symc_ctrl.symc_bit_width; + symc_config->symc_key_length = symc_ctrl.symc_key_length; + symc_config->iv_change_flag = symc_ctrl.iv_change_flag; + symc_config->iv_length = symc_ctrl.iv_length; + ret = memcpy_s(symc_config->iv, sizeof(symc_config->iv), symc_ctrl.iv, sizeof(symc_ctrl.iv)); + crypto_chk_return(ret != EOK, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + if (symc_config->work_mode == CRYPTO_SYMC_WORK_MODE_GCM || symc_config->work_mode == CRYPTO_SYMC_WORK_MODE_CCM) { + symc_config->aad_len = ccm_gcm_config.aad_len; + symc_config->data_len = ccm_gcm_config.data_len; + symc_config->tag_len = ccm_gcm_config.tag_len; + } + + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_symc_attach(td_u32 cmd, td_void *argp, td_void *private_data) +{ + td_s32 ret; + symc_attach_t *symc_attch = (symc_attach_t *)argp; + crypto_dispatch_func_enter(); + crypto_unused(private_data); + dispatch_symc_cmd_chk(CRYPTO_CMD_SYMC_ATTACH); + + ret = kapi_cipher_symc_attach(symc_attch->symc_handle, symc_attch->keyslot_handle); + if (ret != CRYPTO_SUCCESS) { + crypto_log_err("kapi_cipher_symc_attach failed\n"); + return ret; + } + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_symc_crypto(td_u32 cmd, td_void *argp, td_void *private_data, td_u32 crypto_type) +{ + td_s32 ret; + symc_crypto_t *symc_crypto = (symc_crypto_t *)argp; + crypto_buf_attr src_buf = {0}; + crypto_buf_attr dst_buf = {0}; + td_u32 length = symc_crypto->length; + crypto_unused(cmd); + crypto_unused(private_data); + + src_buf.kapi_mem_handle = + (td_void *)crypto_osal_mem_handle_get((unsigned long)symc_crypto->src_mem_handle, SOC_ID_CIPHER); + crypto_chk_goto_with_ret(src_buf.kapi_mem_handle == TD_NULL, mem_handle_put_exit, + SYMC_COMPAT_ERRNO(ERROR_MEM_HANDLE_GET), "crypto_osal_mem_handle_get failed\n"); + src_buf.phys_addr = symc_crypto->src_phys_addr; + src_buf.buf_sec = symc_crypto->src_buf_sec; + src_buf.addr_offset = symc_crypto->src_addr_offset; + dst_buf.kapi_mem_handle = + (td_void *)crypto_osal_mem_handle_get((unsigned long)symc_crypto->dst_mem_handle, SOC_ID_CIPHER); + crypto_chk_goto_with_ret(dst_buf.kapi_mem_handle == TD_NULL, mem_handle_put_exit, + SYMC_COMPAT_ERRNO(ERROR_MEM_HANDLE_GET), "crypto_osal_mem_handle_get failed\n"); + dst_buf.phys_addr = symc_crypto->dst_phys_addr; + dst_buf.buf_sec = symc_crypto->dst_buf_sec; + dst_buf.addr_offset = symc_crypto->dst_addr_offset; + + switch (crypto_type) { + case CRYPTO_TYPE_ENCRYPT: + ret = kapi_cipher_symc_encrypt(symc_crypto->symc_handle, &src_buf, &dst_buf, length); + break; + case CRYPTO_TYPE_DECRYPT: + ret = kapi_cipher_symc_decrypt(symc_crypto->symc_handle, &src_buf, &dst_buf, length); + break; + default: + crypto_log_err("Invalid Crypto Type!\n"); + ret = SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM); + } + +mem_handle_put_exit: + crypto_osal_mem_handle_put(src_buf.kapi_mem_handle, SOC_ID_CIPHER); + crypto_osal_mem_handle_put(dst_buf.kapi_mem_handle, SOC_ID_CIPHER); + return ret; +} + +static td_s32 dispatch_symc_encrypt(td_u32 cmd, td_void *argp, td_void *private_data) +{ + td_s32 ret; + crypto_dispatch_func_enter(); + dispatch_symc_cmd_chk(CRYPTO_CMD_SYMC_ENCRYPT); + ret = dispatch_symc_crypto(cmd, argp, private_data, CRYPTO_TYPE_ENCRYPT); + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_symc_decrypt(td_u32 cmd, td_void *argp, td_void *private_data) +{ + td_s32 ret; + crypto_dispatch_func_enter(); + dispatch_symc_cmd_chk(CRYPTO_CMD_SYMC_DECRYPT); + ret = dispatch_symc_crypto(cmd, argp, private_data, CRYPTO_TYPE_DECRYPT); + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 priv_dispatch_symc_multi_config_ctrl(const crypto_symc_multi_t *symc_multi, crypto_symc_ctrl_t *symc_ctrl) +{ + td_s32 ret; + + symc_ctrl->symc_alg = symc_multi->symc_alg; + symc_ctrl->work_mode = symc_multi->work_mode; + symc_ctrl->symc_bit_width = symc_multi->symc_bit_width; + symc_ctrl->symc_key_length = symc_multi->symc_key_length; + symc_ctrl->iv_change_flag = symc_multi->iv_change_flag; + symc_ctrl->iv_length = symc_multi->iv_length; + ret = memcpy_s(symc_ctrl->iv, sizeof(symc_ctrl->iv), symc_multi->iv, sizeof(symc_multi->iv)); + crypto_chk_return(ret != EOK, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + return ret; +} + +static td_void priv_dispatch_symc_multi_handle_put(const crypto_symc_pack *src_buf_pack, + const crypto_symc_pack *dst_buf_pack, td_u32 pack_num) +{ + td_u32 i; + for (i = 0; i < pack_num; i++) { + if (src_buf_pack[i].buf_attr.kapi_mem_handle != TD_NULL) { + crypto_osal_mem_handle_put(src_buf_pack[i].buf_attr.kapi_mem_handle, SOC_ID_CIPHER); + } + if (dst_buf_pack[i].buf_attr.kapi_mem_handle != TD_NULL) { + crypto_osal_mem_handle_put(dst_buf_pack[i].buf_attr.kapi_mem_handle, SOC_ID_CIPHER); + } + } +} + +static td_s32 priv_dispatch_symc_multi_config_pack(const crypto_symc_multi_t *symc_multi, + crypto_symc_pack *src_buf_pack, crypto_symc_pack *dst_buf_pack, + crypto_mem_pack *src_buf_mem_pack, crypto_mem_pack *dst_buf_mem_pack) +{ + td_u32 ret; + td_u32 i; + td_u32 pack_num = symc_multi->pack_num; + td_u32 mem_size = sizeof(crypto_mem_pack) * pack_num; + + ret = crypto_copy_from_user(src_buf_mem_pack, mem_size, symc_multi->src_pack_addr.p, mem_size); + crypto_chk_return(ret != TD_SUCCESS, SYMC_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = crypto_copy_from_user(dst_buf_mem_pack, mem_size, symc_multi->dst_pack_addr.p, mem_size); + crypto_chk_return(ret != TD_SUCCESS, SYMC_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + for (i = 0; i < pack_num; i++) { + /* transfer uapi mem handle to kapi mem handle. */ + src_buf_pack[i].buf_attr.kapi_mem_handle = (td_void *)crypto_osal_mem_handle_get( + (unsigned long)src_buf_mem_pack[i].uapi_mem_handle, SOC_ID_CIPHER); + crypto_chk_goto_with_ret(src_buf_pack[i].buf_attr.kapi_mem_handle == TD_NULL, error_mem_handle_put, + SYMC_COMPAT_ERRNO(ERROR_MEM_HANDLE_GET), "crypto_osal_mem_handle_get failed\n"); + src_buf_pack[i].length = src_buf_mem_pack[i].length; + src_buf_pack[i].buf_attr.phys_addr = src_buf_mem_pack[i].phys_addr; + src_buf_pack[i].buf_attr.buf_sec = src_buf_mem_pack[i].buf_sec; + dst_buf_pack[i].buf_attr.kapi_mem_handle = (td_void *)crypto_osal_mem_handle_get( + (unsigned long)dst_buf_mem_pack[i].uapi_mem_handle, SOC_ID_CIPHER); + crypto_chk_goto_with_ret(dst_buf_pack[i].buf_attr.kapi_mem_handle == TD_NULL, error_mem_handle_put, + SYMC_COMPAT_ERRNO(ERROR_MEM_HANDLE_GET), "crypto_osal_mem_handle_get failed\n"); + dst_buf_pack[i].length = dst_buf_mem_pack[i].length; + dst_buf_pack[i].buf_attr.phys_addr = dst_buf_mem_pack[i].phys_addr; + dst_buf_pack[i].buf_attr.buf_sec = dst_buf_mem_pack[i].buf_sec; + } + + return TD_SUCCESS; + +error_mem_handle_put: + priv_dispatch_symc_multi_handle_put(src_buf_pack, dst_buf_pack, pack_num); + return ret; +} + +static td_s32 dispatch_symc_crypto_multi(td_u32 cmd, td_void *argp, td_void *private_data, td_u32 crypto_type) +{ + td_s32 ret; + td_u8 *buffer = TD_NULL; + crypto_symc_multi_t *symc_multi = (crypto_symc_multi_t *)argp; + td_u32 pack_num = symc_multi->pack_num; + crypto_mem_pack *src_buf_mem_pack = TD_NULL; + crypto_mem_pack *dst_buf_mem_pack = TD_NULL; + crypto_symc_pack *src_buf_pack = TD_NULL; + crypto_symc_pack *dst_buf_pack = TD_NULL; + td_u32 pack_size = (sizeof(crypto_mem_pack) + sizeof(crypto_symc_pack)) * pack_num; + crypto_symc_ctrl_t symc_ctrl = {0}; + crypto_unused(cmd); + crypto_unused(private_data); + + symc_null_ptr_chk(symc_multi->src_pack_addr.p); + symc_null_ptr_chk(symc_multi->dst_pack_addr.p); + crypto_chk_return(pack_num > CRYPTO_SYMC_MULTI_PACK_MAX_SIZE, SYMC_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), + "pack_num is too large\n"); + + ret = priv_dispatch_symc_multi_config_ctrl(symc_multi, &symc_ctrl); + crypto_chk_return(ret != TD_SUCCESS, ret, "priv_dispatch_symc_multi_config failed\n"); + + buffer = crypto_malloc(pack_size * 2); /* 2: For Both src and dst. */ + crypto_chk_return(buffer == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + (td_void)memset_s(buffer, pack_size * 2, 0, pack_size * 2); /* 2: For Both src and dst. */ + + src_buf_mem_pack = (void *)buffer; + dst_buf_mem_pack = (void *)((td_u8 *)src_buf_mem_pack + sizeof(crypto_mem_pack) * pack_num); + src_buf_pack = (void *)((td_u8 *)dst_buf_mem_pack + sizeof(crypto_mem_pack) * pack_num); + dst_buf_pack = (void *)((td_u8 *)src_buf_pack + sizeof(crypto_symc_pack) * pack_num); + + ret = priv_dispatch_symc_multi_config_pack(symc_multi, src_buf_pack, dst_buf_pack, + src_buf_mem_pack, dst_buf_mem_pack); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "priv_dispatch_symc_multi_config_pack failed, ret is 0x%x\n", ret); + + switch (crypto_type) { + case CRYPTO_TYPE_ENCRYPT: + ret = kapi_cipher_symc_encrypt_multi(symc_multi->symc_handle, &symc_ctrl, + src_buf_pack, dst_buf_pack, pack_num); + break; + case CRYPTO_TYPE_DECRYPT: + ret = kapi_cipher_symc_decrypt_multi(symc_multi->symc_handle, &symc_ctrl, + src_buf_pack, dst_buf_pack, pack_num); + break; + default: + crypto_log_err("Invalid Crypto Type!\n"); + ret = SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM); + } + + priv_dispatch_symc_multi_handle_put(src_buf_pack, dst_buf_pack, pack_num); +exit_free: + (td_void)memset_s(buffer, pack_size * 2, 0, pack_size * 2); /* 2: For Both src and dst. */ + crypto_free(buffer); + return ret; +} + +static td_s32 dispatch_symc_encrypt_multi(td_u32 cmd, td_void *argp, td_void *private_data) +{ + td_s32 ret; + crypto_dispatch_func_enter(); + dispatch_symc_cmd_chk(CRYPTO_CMD_SYMC_ENCRYPT_MULTI); + ret = dispatch_symc_crypto_multi(cmd, argp, private_data, CRYPTO_TYPE_ENCRYPT); + crypto_chk_return(ret != TD_SUCCESS, ret, "dispatch_symc_crypto_multi for Encrypt failed\n"); + + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_symc_decrypt_multi(td_u32 cmd, td_void *argp, td_void *private_data) +{ + td_s32 ret; + crypto_dispatch_func_enter(); + dispatch_symc_cmd_chk(CRYPTO_CMD_SYMC_DECRYPT_MULTI); + ret = dispatch_symc_crypto_multi(cmd, argp, private_data, CRYPTO_TYPE_DECRYPT); + crypto_chk_return(ret != TD_SUCCESS, ret, "dispatch_symc_crypto_multi for Decrypt failed\n"); + + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_symc_get_tag(td_u32 cmd, td_void *argp, td_void *private_data) +{ + td_s32 ret; + symc_get_tag_t *symc_get_tag = (symc_get_tag_t *)argp; + + crypto_dispatch_func_enter(); + crypto_unused(private_data); + dispatch_symc_cmd_chk(CRYPTO_CMD_SYMC_GET_TAG); + + ret = kapi_cipher_symc_get_tag(symc_get_tag->symc_handle, symc_get_tag->tag, symc_get_tag->tag_length); + crypto_chk_return(ret != TD_SUCCESS, ret, "kapi_cipher_symc_get_tag failed\n"); + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_symc_mac_start(td_u32 cmd, td_void *argp, td_void *private_data) +{ + td_s32 ret; + symc_mac_start_t *mac_start = (symc_mac_start_t *)argp; + crypto_dispatch_func_enter(); + crypto_unused(private_data); + dispatch_symc_cmd_chk(CRYPTO_CMD_SYMC_MAC_START); + + ret = kapi_cipher_mac_start(&mac_start->symc_handle, &mac_start->mac_attr); + crypto_chk_return(ret != TD_SUCCESS, ret, "kapi_cipher_mac_start failed, ret is 0x%x\n", ret); + + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_symc_mac_update(td_u32 cmd, td_void *argp, td_void *private_data) +{ + td_s32 ret; + symc_mac_update_t *mac_update = (symc_mac_update_t *)argp; + td_u8 *data_buffer = TD_NULL; + td_u32 left = mac_update->length; + td_u32 malloc_size = 0; + td_u32 processing_len = 0; + td_u32 processed_len = 0; + crypto_buf_attr src_buf = {0}; + crypto_dispatch_func_enter(); + crypto_unused(private_data); + dispatch_symc_cmd_chk(CRYPTO_CMD_SYMC_MAC_UPDATE); + symc_null_ptr_chk(mac_update->src_buf.p); + crypto_chk_return(mac_update->length == 0 || mac_update->length > CRYPTO_SYMC_MAC_UPDATE_MAX_LEN, + SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM), "length is Invalid\n"); + + malloc_size = crypto_min(CRYPTO_MAX_DATA_LEN, left); + data_buffer = crypto_malloc(malloc_size); + src_buf.virt_addr = data_buffer; + crypto_chk_return(data_buffer == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + + while (left > 0) { + processing_len = crypto_min(CRYPTO_MAX_DATA_LEN, left); + ret = crypto_copy_from_user(data_buffer, malloc_size, (td_u8 *)mac_update->src_buf.p + processed_len, + processing_len); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, exit_free, SYMC_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = kapi_cipher_mac_update(mac_update->symc_handle, &src_buf, processing_len); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "kapi_cipher_mac_update failed, ret is 0x%x\n", ret); + left -= processing_len; + processed_len += processing_len; + } + +exit_free: + (td_void)memset_s(data_buffer, malloc_size, 0, malloc_size); + crypto_free(data_buffer); + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_symc_mac_finish(td_u32 cmd, td_void *argp, td_void *private_data) +{ + td_s32 ret; + symc_mac_finish_t *mac_finish = (symc_mac_finish_t *)argp; + crypto_dispatch_func_enter(); + crypto_unused(private_data); + dispatch_symc_cmd_chk(CRYPTO_CMD_SYMC_MAC_FINISH); + mac_finish->mac_length = CRYPTO_AES_BLOCK_SIZE_IN_BYTES; + ret = kapi_cipher_mac_finish(mac_finish->symc_handle, mac_finish->mac, &mac_finish->mac_length); + crypto_chk_return(ret != TD_SUCCESS, ret, "kapi_cipher_mac_finish failed, ret is 0x%x\n", ret); + + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_pke_ecc_gen_key(unsigned int cmd, td_void *argp, void *private_data) +{ + td_s32 ret = TD_SUCCESS; + pke_ecc_gen_key_ctl_t *gen_key_ctl = (pke_ecc_gen_key_ctl_t *)argp; + drv_pke_ecc_curve_type curve_type = 0; + drv_pke_data input_priv_key = { 0 }; + drv_pke_data output_priv_key = { 0 }; + drv_pke_ecc_point output_pub_key = { 0 }; + td_u32 klen = 0; + crypto_dispatch_func_enter(); + dispatch_pke_cmd_chk(CRYPTO_CMD_PKE_ECC_GEN_KEY); + + crypto_chk_return(gen_key_ctl->curve_type >= DRV_PKE_ECC_TYPE_MAX, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "Invalid curve_type\n"); + + crypto_unused(private_data); + pke_null_ptr_chk(gen_key_ctl->output_priv_key.data.p); + + if (gen_key_ctl->curve_type != DRV_PKE_ECC_TYPE_RFC8032) { + pke_null_ptr_chk(gen_key_ctl->output_pub_key.x.p); + } + if (gen_key_ctl->curve_type != DRV_PKE_ECC_TYPE_RFC7748) { + pke_null_ptr_chk(gen_key_ctl->output_pub_key.y.p); + } + curve_type = gen_key_ctl->curve_type; + klen = gen_key_ctl->output_priv_key.length; + crypto_chk_return(klen < CRYPTO_PKE_ECC_KEY_MIN_SIZE || klen > CRYPTO_PKE_ECC_KEY_MAX_SIZE, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "klen is Invalid\n"); + + crypto_chk_return(gen_key_ctl->output_pub_key.length != klen, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "gen_key_ctl->output_pub_key.length is invalid\n"); + + /* alloc memory. */ + if (gen_key_ctl->input_priv_key.length != 0) { + pke_null_ptr_chk(gen_key_ctl->input_priv_key.data.p); + crypto_chk_return(gen_key_ctl->input_priv_key.length != klen, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "gen_key_ctl->input_priv_key.length is invalid\n"); + /* input_priv_key. */ + input_priv_key.data = crypto_malloc(klen); + crypto_chk_goto_with_ret(input_priv_key.data == TD_NULL, free_exit, + PKE_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + input_priv_key.length = klen; + + ret = crypto_copy_from_user(input_priv_key.data, klen, gen_key_ctl->input_priv_key.data.p, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, + PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), "crypto_copy_from_user failed, ret is 0x%x\n", ret); + } + + /* output_priv_key. */ + output_priv_key.data = crypto_malloc(klen); + crypto_chk_goto_with_ret(output_priv_key.data == TD_NULL, free_exit, + PKE_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + output_priv_key.length = klen; + + /* output_pub_key. */ + if (gen_key_ctl->curve_type != DRV_PKE_ECC_TYPE_RFC8032) { + output_pub_key.x = crypto_malloc(klen); + crypto_chk_goto_with_ret(output_pub_key.x == TD_NULL, free_exit, + PKE_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + } + if (gen_key_ctl->curve_type != DRV_PKE_ECC_TYPE_RFC7748) { + output_pub_key.y = crypto_malloc(klen); + crypto_chk_goto_with_ret(output_pub_key.y == TD_NULL, free_exit, + PKE_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + } + output_pub_key.length = klen; + + if (gen_key_ctl->input_priv_key.length != 0) { + ret = kapi_pke_ecc_gen_key(curve_type, &input_priv_key, &output_priv_key, &output_pub_key); + } else { + ret = kapi_pke_ecc_gen_key(curve_type, TD_NULL, &output_priv_key, &output_pub_key); + } + crypto_chk_goto(ret != TD_SUCCESS, free_exit, "kapi_pke_ecc_gen_key failed, ret is 0x%x\n", ret); + /* copy to user. */ + ret = crypto_copy_to_user(gen_key_ctl->output_priv_key.data.p, klen, output_priv_key.data, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_TO_USER), + "crypto_copy_to_user failed, ret is 0x%x\n", ret); + if (gen_key_ctl->curve_type != DRV_PKE_ECC_TYPE_RFC8032) { + ret = crypto_copy_to_user(gen_key_ctl->output_pub_key.x.p, klen, output_pub_key.x, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_TO_USER), + "crypto_copy_to_user failed, ret is 0x%x\n", ret); + } + if (gen_key_ctl->curve_type != DRV_PKE_ECC_TYPE_RFC7748) { + ret = crypto_copy_to_user(gen_key_ctl->output_pub_key.y.p, klen, output_pub_key.y, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_TO_USER), + "crypto_copy_to_user failed, ret is 0x%x\n", ret); + } + +free_exit: + if (gen_key_ctl->curve_type != DRV_PKE_ECC_TYPE_RFC7748) { + crypto_chk_crypto_free_with_clean(output_pub_key.y, klen); + } + if (gen_key_ctl->curve_type != DRV_PKE_ECC_TYPE_RFC8032) { + crypto_chk_crypto_free_with_clean(output_pub_key.x, klen); + } + crypto_chk_crypto_free_with_clean(output_priv_key.data, klen); + crypto_chk_crypto_free_with_clean(input_priv_key.data, klen); + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_pke_ecc_gen_ecdh_key(unsigned int cmd, td_void *argp, void *private_data) +{ + td_s32 ret = TD_SUCCESS; + pke_ecc_gen_ecdh_key_ctl_t *gen_ecdh_key_ctl = (pke_ecc_gen_ecdh_key_ctl_t *)argp; + drv_pke_ecc_curve_type curve_type = 0; + drv_pke_data input_priv_key = { 0 }; + drv_pke_data output_shared_key = { 0 }; + drv_pke_ecc_point input_pub_key = { 0 }; + td_u32 klen = 0; + + crypto_dispatch_func_enter(); + dispatch_pke_cmd_chk(CRYPTO_CMD_PKE_ECC_GEN_ECDH_KEY); + + crypto_unused(private_data); + crypto_chk_return(gen_ecdh_key_ctl->curve_type >= DRV_PKE_ECC_TYPE_MAX, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "Invalid curve_type\n"); + pke_null_ptr_chk(gen_ecdh_key_ctl->input_priv_key.data.p); + pke_null_ptr_chk(gen_ecdh_key_ctl->input_pub_key.x.p); + pke_null_ptr_chk(gen_ecdh_key_ctl->output_shared_key.data.p); + if (gen_ecdh_key_ctl->curve_type != DRV_PKE_ECC_TYPE_RFC7748) { + pke_null_ptr_chk(gen_ecdh_key_ctl->input_pub_key.y.p); + } + + klen = gen_ecdh_key_ctl->input_priv_key.length; + crypto_chk_return(klen < CRYPTO_PKE_ECC_KEY_MIN_SIZE || klen > CRYPTO_PKE_ECC_KEY_MAX_SIZE, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "klen is Invalid\n"); + crypto_chk_return(gen_ecdh_key_ctl->input_pub_key.length != klen, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "gen_ecdh_key_ctl->input_pub_key.length is Invalid\n"); + crypto_chk_return(gen_ecdh_key_ctl->output_shared_key.length != klen, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "gen_ecdh_key_ctl->output_shared_key.length is Invalid\n"); + + curve_type = gen_ecdh_key_ctl->curve_type; + input_priv_key.length = klen; + input_pub_key.length = klen; + output_shared_key.length = klen; + /* input_priv_key. */ + input_priv_key.data = crypto_malloc(klen); + crypto_chk_goto_with_ret(input_priv_key.data == TD_NULL, free_exit, + PKE_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + + ret = crypto_copy_from_user(input_priv_key.data, klen, gen_ecdh_key_ctl->input_priv_key.data.p, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + /* output_shared_key. */ + output_shared_key.data = crypto_malloc(klen); + crypto_chk_goto_with_ret(output_shared_key.data == TD_NULL, free_exit, + PKE_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + + /* input_pub_key. */ + input_pub_key.x = crypto_malloc(klen); + crypto_chk_goto_with_ret(input_pub_key.x == TD_NULL, free_exit, + PKE_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + + if (gen_ecdh_key_ctl->curve_type != DRV_PKE_ECC_TYPE_RFC7748) { + input_pub_key.y = crypto_malloc(klen); + crypto_chk_goto_with_ret(input_pub_key.y == TD_NULL, free_exit, + PKE_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + } + + ret = crypto_copy_from_user(input_pub_key.x, klen, gen_ecdh_key_ctl->input_pub_key.x.p, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + if (gen_ecdh_key_ctl->curve_type != DRV_PKE_ECC_TYPE_RFC7748) { + ret = crypto_copy_from_user(input_pub_key.y, klen, gen_ecdh_key_ctl->input_pub_key.y.p, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + } + + ret = kapi_pke_ecc_gen_ecdh_key(curve_type, &input_pub_key, &input_priv_key, &output_shared_key); + crypto_chk_goto(ret != TD_SUCCESS, free_exit, "kapi_pke_ecc_gen_key failed, ret is 0x%x\n", ret); + + /* copy to user. */ + ret = crypto_copy_to_user(gen_ecdh_key_ctl->output_shared_key.data.p, klen, output_shared_key.data, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_TO_USER), + "crypto_copy_to_user failed, ret is 0x%x\n", ret); +free_exit: + if (gen_ecdh_key_ctl->curve_type != DRV_PKE_ECC_TYPE_RFC7748) { + crypto_chk_crypto_free_with_clean(input_pub_key.y, klen); + } + crypto_chk_crypto_free_with_clean(input_pub_key.x, klen); + crypto_chk_crypto_free_with_clean(output_shared_key.data, klen); + crypto_chk_crypto_free_with_clean(input_priv_key.data, klen); + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_pke_ecdsa_sign(unsigned int cmd, td_void *argp, void *private_data) +{ + td_s32 ret = TD_SUCCESS; + pke_ecdsa_sign_ctl_t *ecdsa_sign_ctl = (pke_ecdsa_sign_ctl_t *)argp; + drv_pke_ecc_curve_type curve_type = 0; + drv_pke_data priv_key = { 0 }; + drv_pke_data hash = { 0 }; + drv_pke_ecc_sig sig = { 0 }; + td_u32 klen = 0; + td_u32 hash_len = 0; + td_u8 *buffer = TD_NULL; + td_u32 buffer_size = 0; + crypto_dispatch_func_enter(); + + dispatch_pke_cmd_chk(CRYPTO_CMD_PKE_ECDSA_SIGN); + crypto_unused(private_data); + + pke_null_ptr_chk(ecdsa_sign_ctl->priv_key.data.p); + pke_null_ptr_chk(ecdsa_sign_ctl->hash.data.p); + pke_null_ptr_chk(ecdsa_sign_ctl->sig.r.p); + pke_null_ptr_chk(ecdsa_sign_ctl->sig.s.p); + klen = ecdsa_sign_ctl->priv_key.length; + hash_len = ecdsa_sign_ctl->hash.length; + + crypto_chk_return(klen < CRYPTO_PKE_ECC_KEY_MIN_SIZE || klen > CRYPTO_PKE_ECC_KEY_MAX_SIZE, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "klen is Invalid\n"); + crypto_chk_return(hash_len < CRYPTO_HASH_MIN_LEN || hash_len > CRYPTO_HASH_MAX_LEN, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "hash_len is Invalid\n"); + crypto_chk_return(ecdsa_sign_ctl->sig.length != klen, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "ecdsa_sign_ctl->sig.length is Invalid\n"); + curve_type = ecdsa_sign_ctl->curve_type; + + /* alloc memory. */ + buffer_size = klen * 3 + hash_len; // 3: for priv->d, sig->r and sig->s + buffer = crypto_malloc(buffer_size); + crypto_chk_return(buffer == TD_NULL, PKE_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + + priv_key.data = buffer; + priv_key.length = klen; + + hash.data = priv_key.data + priv_key.length; + hash.length = hash_len; + + sig.r = hash.data + hash.length; + sig.s = sig.r + klen; + sig.length = klen; + + /* copy from user. */ + ret = crypto_copy_from_user(priv_key.data, klen, ecdsa_sign_ctl->priv_key.data.p, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = crypto_copy_from_user(hash.data, hash_len, ecdsa_sign_ctl->hash.data.p, hash_len); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = kapi_pke_ecdsa_sign(curve_type, &priv_key, &hash, &sig); + crypto_chk_goto(ret != TD_SUCCESS, free_exit, "kapi_pke_ecdsa_sign failed, ret is 0x%x\n", ret); + + /* copy to user. */ + ret = crypto_copy_to_user(ecdsa_sign_ctl->sig.r.p, klen, sig.r, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_TO_USER), + "crypto_copy_to_user failed, ret is 0x%x\n", ret); + + ret = crypto_copy_to_user(ecdsa_sign_ctl->sig.s.p, klen, sig.s, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_TO_USER), + "crypto_copy_to_user failed, ret is 0x%x\n", ret); +free_exit: + crypto_chk_crypto_free_with_clean(buffer, buffer_size); + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_pke_ecdsa_verify(unsigned int cmd, td_void *argp, void *private_data) +{ + td_s32 ret = TD_SUCCESS; + pke_ecdsa_verify_ctl_t *ecdsa_verify_ctl = (pke_ecdsa_verify_ctl_t *)argp; + drv_pke_ecc_curve_type curve_type = 0; + drv_pke_ecc_point pub_key = { 0 }; + drv_pke_data hash = { 0 }; + drv_pke_ecc_sig sig = { 0 }; + td_u32 klen = 0; + td_u32 hash_length = 0; + td_u8 *buffer = TD_NULL; + td_u32 buffer_size = 0; + + crypto_dispatch_func_enter(); + dispatch_pke_cmd_chk(CRYPTO_CMD_PKE_ECDSA_VERIFY); + crypto_unused(private_data); + + pke_null_ptr_chk(ecdsa_verify_ctl->pub_key.x.p); + pke_null_ptr_chk(ecdsa_verify_ctl->pub_key.y.p); + pke_null_ptr_chk(ecdsa_verify_ctl->hash.data.p); + pke_null_ptr_chk(ecdsa_verify_ctl->sig.r.p); + pke_null_ptr_chk(ecdsa_verify_ctl->sig.s.p); + + klen = ecdsa_verify_ctl->pub_key.length; + hash_length = ecdsa_verify_ctl->hash.length; + crypto_chk_return(klen < CRYPTO_PKE_ECC_KEY_MIN_SIZE || klen > CRYPTO_PKE_ECC_KEY_MAX_SIZE, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "klen is Invalid\n"); + crypto_chk_return(hash_length < CRYPTO_HASH_MIN_LEN || hash_length > CRYPTO_HASH_MAX_LEN, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "hash_len is Invalid\n"); + crypto_chk_return(ecdsa_verify_ctl->sig.length != klen, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "ecdsa_verify_ctl->sig.length is Invalid\n"); + + curve_type = ecdsa_verify_ctl->curve_type; + + /* alloc memory. */ + buffer_size = klen * 4 + hash_length; // 4: for pub.x, pub.y, sig.r, sig.s + buffer = crypto_malloc(buffer_size); + crypto_chk_goto_with_ret(buffer == TD_NULL, free_exit, PKE_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + + pub_key.x = buffer; + pub_key.y = buffer + klen; + pub_key.length = klen; + + hash.data = pub_key.y + pub_key.length; + hash.length = hash_length; + + sig.r = hash.data + hash.length; + sig.s = sig.r + klen; + sig.length = klen; + + /* copy from user. */ + ret = crypto_copy_from_user(pub_key.x, klen, ecdsa_verify_ctl->pub_key.x.p, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = crypto_copy_from_user(pub_key.y, klen, ecdsa_verify_ctl->pub_key.y.p, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = crypto_copy_from_user(hash.data, hash_length, ecdsa_verify_ctl->hash.data.p, hash_length); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = crypto_copy_from_user(sig.r, klen, ecdsa_verify_ctl->sig.r.p, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = crypto_copy_from_user(sig.s, klen, ecdsa_verify_ctl->sig.s.p, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = kapi_pke_ecdsa_verify(curve_type, &pub_key, &hash, &sig); + crypto_chk_goto(ret != TD_SUCCESS, free_exit, "kapi_pke_ecdsa_verify failed, ret is 0x%x\n", ret); + +free_exit: + crypto_chk_crypto_free_with_clean(buffer, buffer_size); + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_pke_eddsa_sign(unsigned int cmd, td_void *argp, void *private_data) +{ + td_s32 ret = TD_SUCCESS; + pke_eddsa_sign_ctl_t *eddsa_sign_ctl = (pke_eddsa_sign_ctl_t *)argp; + drv_pke_ecc_curve_type curve_type = 0; + drv_pke_data priv_key = { 0 }; + drv_pke_msg msg = { 0 }; + drv_pke_ecc_sig sig = { 0 }; + td_u32 klen = 0; + td_u32 msg_len = 0; + td_u8 *buffer = TD_NULL; + td_u32 buffer_size = 0; + crypto_dispatch_func_enter(); + + dispatch_pke_cmd_chk(CRYPTO_CMD_PKE_EDDSA_SIGN); + crypto_unused(private_data); + + pke_null_ptr_chk(eddsa_sign_ctl->priv_key.data.p); + pke_null_ptr_chk(eddsa_sign_ctl->msg.data.p); + pke_null_ptr_chk(eddsa_sign_ctl->sig.r.p); + pke_null_ptr_chk(eddsa_sign_ctl->sig.s.p); + klen = eddsa_sign_ctl->priv_key.length; + msg_len = eddsa_sign_ctl->msg.length; + crypto_chk_return(klen < CRYPTO_PKE_ECC_KEY_MIN_SIZE || klen > CRYPTO_PKE_ECC_KEY_MAX_SIZE, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "klen is Invalid\n"); + crypto_chk_return(msg_len < CRYPTO_PKE_MSG_MIN_SIZE || msg_len > CRYPTO_PKE_MSG_MAX_SIZE, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "msg_len is Invalid\n"); + crypto_chk_return(eddsa_sign_ctl->sig.length != klen, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "eddsa_sign_ctl->sig.length is Invalid\n"); + + curve_type = eddsa_sign_ctl->curve_type; + + /* alloc memory. */ + buffer_size = klen * 3 + msg_len; // 3: for priv.d, sig.r, sig.s + buffer = crypto_malloc(buffer_size); + crypto_chk_return(buffer == TD_NULL, PKE_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + + priv_key.data = buffer; + priv_key.length = klen; + + msg.data = priv_key.data + priv_key.length; + msg.length = msg_len; + msg.buf_sec = eddsa_sign_ctl->msg.buf_sec; + + sig.r = msg.data + msg.length; + sig.s = sig.r + klen; + sig.length = klen; + + /* copy from user. */ + ret = crypto_copy_from_user(priv_key.data, klen, eddsa_sign_ctl->priv_key.data.p, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = crypto_copy_from_user(msg.data, msg_len, eddsa_sign_ctl->msg.data.p, msg_len); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = kapi_pke_eddsa_sign(curve_type, &priv_key, &msg, &sig); + crypto_chk_goto(ret != TD_SUCCESS, free_exit, "kapi_pke_ecdsa_sign failed, ret is 0x%x\n", ret); + + /* copy to user. */ + ret = crypto_copy_to_user(eddsa_sign_ctl->sig.r.p, klen, sig.r, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_TO_USER), + "crypto_copy_to_user failed, ret is 0x%x\n", ret); + + ret = crypto_copy_to_user(eddsa_sign_ctl->sig.s.p, klen, sig.s, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_TO_USER), + "crypto_copy_to_user failed, ret is 0x%x\n", ret); +free_exit: + crypto_chk_crypto_free_with_clean(buffer, buffer_size); + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_pke_eddsa_verify(unsigned int cmd, td_void *argp, void *private_data) +{ + td_s32 ret = TD_SUCCESS; + pke_eddsa_verify_ctl_t *eddsa_verify_ctl = (pke_eddsa_verify_ctl_t *)argp; + drv_pke_ecc_curve_type curve_type = 0; + drv_pke_ecc_point pub_key = { 0 }; + drv_pke_msg msg = { 0 }; + drv_pke_ecc_sig sig = { 0 }; + td_u32 klen = 0; + td_u32 msg_len = 0; + td_u8 *buffer = TD_NULL; + td_u32 buffer_size = 0; + crypto_dispatch_func_enter(); + dispatch_pke_cmd_chk(CRYPTO_CMD_PKE_EDDSA_VERIFY); + crypto_unused(private_data); + + pke_null_ptr_chk(eddsa_verify_ctl->pub_key.y.p); + pke_null_ptr_chk(eddsa_verify_ctl->msg.data.p); + pke_null_ptr_chk(eddsa_verify_ctl->sig.r.p); + pke_null_ptr_chk(eddsa_verify_ctl->sig.s.p); + + klen = eddsa_verify_ctl->pub_key.length; + msg_len = eddsa_verify_ctl->msg.length; + crypto_chk_return(klen < CRYPTO_PKE_ECC_KEY_MIN_SIZE || klen > CRYPTO_PKE_ECC_KEY_MAX_SIZE, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "klen is Invalid\n"); + crypto_chk_return(msg_len < CRYPTO_PKE_MSG_MIN_SIZE || msg_len > CRYPTO_PKE_MSG_MAX_SIZE, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "msg_len is Invalid\n"); + crypto_chk_return(eddsa_verify_ctl->sig.length != klen, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "eddsa_verify_ctl->sig.length is Invalid\n"); + curve_type = eddsa_verify_ctl->curve_type; + + /* alloc memory. */ + buffer_size = klen * 3 + msg_len; // 3: for pub_key.y, sig.r, sig.s + buffer = crypto_malloc(buffer_size); + crypto_chk_return(buffer == TD_NULL, PKE_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + + pub_key.y = buffer; + pub_key.length = klen; + + msg.data = pub_key.y + klen; + msg.length = msg_len; + msg.buf_sec = eddsa_verify_ctl->msg.buf_sec; + + sig.r = msg.data + msg.length; + sig.s = sig.r + klen; + sig.length = klen; + + /* copy from user. */ + + ret = crypto_copy_from_user(pub_key.y, klen, eddsa_verify_ctl->pub_key.y.p, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = crypto_copy_from_user(msg.data, msg_len, eddsa_verify_ctl->msg.data.p, msg_len); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = crypto_copy_from_user(sig.r, klen, eddsa_verify_ctl->sig.r.p, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = crypto_copy_from_user(sig.s, klen, eddsa_verify_ctl->sig.s.p, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = kapi_pke_eddsa_verify(curve_type, &pub_key, &msg, &sig); + crypto_chk_goto(ret != TD_SUCCESS, free_exit, "kapi_pke_ecdsa_verify failed, ret is 0x%x\n", ret); + +free_exit: + crypto_chk_crypto_free_with_clean(buffer, buffer_size); + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_pke_check_dot_on_curve(unsigned int cmd, td_void *argp, void *private_data) +{ + td_s32 ret = TD_SUCCESS; + pke_check_dot_on_curve_ctl_t *dot_on_curve_ctl = (pke_check_dot_on_curve_ctl_t *)argp; + drv_pke_ecc_curve_type curve_type = 0; + drv_pke_ecc_point pub_key = { 0 }; + td_u32 klen = 0; + td_u8 *buffer = TD_NULL; + td_u32 buffer_size = 0; + crypto_dispatch_func_enter(); + + dispatch_pke_cmd_chk(CRYPTO_CMD_PKE_CHECK_DOT_ON_CURVE); + + crypto_unused(private_data); + + pke_null_ptr_chk(dot_on_curve_ctl->pub_key.x.p); + pke_null_ptr_chk(dot_on_curve_ctl->pub_key.y.p); + klen = dot_on_curve_ctl->pub_key.length; + + crypto_chk_return(klen < CRYPTO_PKE_ECC_KEY_MIN_SIZE || klen > CRYPTO_PKE_ECC_KEY_MAX_SIZE, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "klen is invalid\n"); + curve_type = dot_on_curve_ctl->curve_type; + + buffer_size = klen * 2; // 2: for pub_key.x, pub_key.y + buffer = crypto_malloc(buffer_size); + crypto_chk_return(buffer == TD_NULL, PKE_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + + /* pub_key. */ + pub_key.x = buffer; + pub_key.y = buffer + klen; + pub_key.length = klen; + /* copy from user. */ + ret = crypto_copy_from_user(pub_key.x, klen, dot_on_curve_ctl->pub_key.x.p, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = crypto_copy_from_user(pub_key.y, klen, dot_on_curve_ctl->pub_key.y.p, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = kapi_pke_check_dot_on_curve(curve_type, &pub_key, &dot_on_curve_ctl->is_on_curve); + crypto_chk_goto(ret != TD_SUCCESS, free_exit, "kapi_pke_check_dot_on_curve failed, ret is 0x%x\n", ret); +free_exit: + crypto_chk_crypto_free_with_clean(buffer, buffer_size); + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_pke_sm2_dsa_hash(unsigned int cmd, td_void *argp, void *private_data) +{ + td_s32 ret = TD_SUCCESS; + pke_sm2_dsa_hash_ctl_t *dsa_hash_ctl = (pke_sm2_dsa_hash_ctl_t *)argp; + drv_pke_data sm2_id = { 0 }; + drv_pke_ecc_point pub_key = { 0 }; + drv_pke_msg msg = { 0 }; + drv_pke_data hash = { 0 }; + td_u32 klen = 0; + td_u32 msg_len = 0; + td_u32 hash_len = 0; + td_u32 sm2_id_len = 0; + td_u8 *buffer = TD_NULL; + td_u32 buffer_size = 0; + crypto_dispatch_func_enter(); + + dispatch_pke_cmd_chk(CRYPTO_CMD_PKE_SM2_DSA_HASH); + + crypto_unused(private_data); + + pke_null_ptr_chk(dsa_hash_ctl->sm2_id.data.p); + pke_null_ptr_chk(dsa_hash_ctl->pub_key.x.p); + pke_null_ptr_chk(dsa_hash_ctl->pub_key.y.p); + pke_null_ptr_chk(dsa_hash_ctl->msg.data.p); + pke_null_ptr_chk(dsa_hash_ctl->hash.data.p); + klen = dsa_hash_ctl->pub_key.length; + msg_len = dsa_hash_ctl->msg.length; + hash_len = dsa_hash_ctl->hash.length; + sm2_id_len = dsa_hash_ctl->sm2_id.length; + + crypto_chk_return(klen < CRYPTO_PKE_ECC_KEY_MIN_SIZE || klen > CRYPTO_PKE_ECC_KEY_MAX_SIZE, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "klen is Invalid\n"); + crypto_chk_return(msg_len < CRYPTO_PKE_MSG_MIN_SIZE || msg_len > CRYPTO_PKE_MSG_MAX_SIZE, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "msg_len is Invalid\n"); + crypto_chk_return(hash_len < CRYPTO_HASH_MIN_LEN || hash_len > CRYPTO_HASH_MAX_LEN, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "hash_len is Invalid\n"); + crypto_chk_return(sm2_id_len < CRYPTO_PKE_SM2_ID_MIN_SIZE || sm2_id_len > CRYPTO_PKE_SM2_ID_MAX_SIZE, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "sm2_id_len is Invalid\n"); + + buffer_size = sm2_id_len + klen * 2 + msg_len + hash_len; // 2: for pub_key.x, pub_key.y + buffer = crypto_malloc(buffer_size); + crypto_chk_return(buffer == TD_NULL, PKE_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + + sm2_id.data = buffer; + sm2_id.length = sm2_id_len; + + pub_key.x = sm2_id.data + sm2_id.length; + pub_key.y = pub_key.x + klen; + pub_key.length = klen; + + msg.data = pub_key.y + pub_key.length; + msg.length = msg_len; + msg.buf_sec = dsa_hash_ctl->msg.buf_sec; + + hash.data = msg.data + msg.length; + hash.length = hash_len; + + /* copy from user. */ + ret = crypto_copy_from_user(sm2_id.data, sm2_id_len, dsa_hash_ctl->sm2_id.data.p, sm2_id_len); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = crypto_copy_from_user(pub_key.x, klen, dsa_hash_ctl->pub_key.x.p, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = crypto_copy_from_user(pub_key.y, klen, dsa_hash_ctl->pub_key.y.p, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = crypto_copy_from_user(msg.data, msg_len, dsa_hash_ctl->msg.data.p, msg_len); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = kapi_pke_sm2_dsa_hash(&sm2_id, &pub_key, &msg, &hash); + crypto_chk_goto(ret != TD_SUCCESS, free_exit, "kapi_pke_sm2_dsa_hash failed, ret is 0x%x\n", ret); + + ret = crypto_copy_to_user(dsa_hash_ctl->hash.data.p, hash_len, hash.data, hash_len); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_TO_USER), + "crypto_copy_to_user failed, ret is 0x%x\n", ret); + +free_exit: + crypto_chk_crypto_free_with_clean(buffer, buffer_size); + crypto_dispatch_func_exit(); + + return ret; +} + +static td_s32 dispatch_pke_sm2_public_encrypt(unsigned int cmd, td_void *argp, void *private_data) +{ + td_s32 ret = TD_SUCCESS; + pke_sm2_public_encrypt_ctl_t *public_encrypt_ctl = (pke_sm2_public_encrypt_ctl_t *)argp; + drv_pke_ecc_point pub_key = { 0 }; + drv_pke_data plain_text = { 0 }; + drv_pke_data cipher_text = { 0 }; + td_u32 klen = 0; + td_u32 plain_text_len = 0; + td_u32 cipher_text_len = 0; + td_u8 *buffer = TD_NULL; + td_u32 buffer_size = 0; + + crypto_dispatch_func_enter(); + dispatch_pke_cmd_chk(CRYPTO_CMD_PKE_SM2_PUBLIC_ENCRYPT); + crypto_unused(private_data); + + pke_null_ptr_chk(public_encrypt_ctl->pub_key.x.p); + pke_null_ptr_chk(public_encrypt_ctl->pub_key.y.p); + pke_null_ptr_chk(public_encrypt_ctl->plain_text.data.p); + pke_null_ptr_chk(public_encrypt_ctl->cipher_text.data.p); + + klen = public_encrypt_ctl->pub_key.length; + plain_text_len = public_encrypt_ctl->plain_text.length; + cipher_text_len = public_encrypt_ctl->cipher_text.length; + + crypto_chk_return(klen < CRYPTO_PKE_ECC_KEY_MIN_SIZE || klen > CRYPTO_PKE_ECC_KEY_MAX_SIZE, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "klen is Invalid\n"); + crypto_chk_return(plain_text_len < CRYPTO_PKE_SM2_PLAIN_TEXT_MIN_SIZE || + plain_text_len > CRYPTO_PKE_SM2_PLAIN_TEXT_MAX_SIZE, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "plain_text_len is Invalid\n"); + crypto_chk_return(cipher_text_len < CRYPTO_PKE_SM2_PLAIN_TEXT_MIN_SIZE || + cipher_text_len > CRYPTO_PKE_SM2_PLAIN_TEXT_MAX_SIZE, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "cipher_text_len is Invalid\n"); + + buffer_size = klen * 2 + plain_text_len + cipher_text_len; // 2: for pub_key.x, pub_key.y + buffer = crypto_malloc(buffer_size); + crypto_chk_return(buffer == TD_NULL, PKE_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + + pub_key.x = buffer; + pub_key.y = buffer + klen; + pub_key.length = klen; + + plain_text.data = pub_key.y + klen; + plain_text.length = plain_text_len; + + cipher_text.data = plain_text.data + plain_text.length; + cipher_text.length = cipher_text_len; + + /* copy from user. */ + ret = crypto_copy_from_user(plain_text.data, plain_text_len, public_encrypt_ctl->plain_text.data.p, plain_text_len); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = crypto_copy_from_user(pub_key.x, klen, public_encrypt_ctl->pub_key.x.p, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = crypto_copy_from_user(pub_key.y, klen, public_encrypt_ctl->pub_key.y.p, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = kapi_pke_sm2_public_encrypt(&pub_key, &plain_text, &cipher_text); + crypto_chk_goto(ret != TD_SUCCESS, free_exit, "kapi_pke_sm2_public_encrypt failed, ret is 0x%x\n", ret); + + ret = crypto_copy_to_user(public_encrypt_ctl->cipher_text.data.p, public_encrypt_ctl->cipher_text.length, + cipher_text.data, cipher_text.length); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_TO_USER), + "crypto_copy_to_user failed, ret is 0x%x\n", ret); + public_encrypt_ctl->cipher_text.length = cipher_text.length; +free_exit: + crypto_chk_crypto_free_with_clean(buffer, buffer_size); + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_pke_sm2_private_decrypt(unsigned int cmd, td_void *argp, void *private_data) +{ + td_s32 ret = TD_SUCCESS; + pke_sm2_private_decrypt_ctl_t *private_decrypt_ctl = (pke_sm2_private_decrypt_ctl_t *)argp; + drv_pke_data priv_key = { 0 }; + drv_pke_data cipher_text = { 0 }; + drv_pke_data plain_text = { 0 }; + td_u32 klen = 0; + td_u32 plain_text_len = 0; + td_u32 cipher_text_len = 0; + td_u8 *buffer = TD_NULL; + td_u32 buffer_size = 0; + crypto_dispatch_func_enter(); + dispatch_pke_cmd_chk(CRYPTO_CMD_PKE_SM2_PRIVATE_DECRYPT); + + crypto_unused(private_data); + + pke_null_ptr_chk(private_decrypt_ctl->priv_key.data.p); + pke_null_ptr_chk(private_decrypt_ctl->cipher_text.data.p); + pke_null_ptr_chk(private_decrypt_ctl->plain_text.data.p); + + klen = private_decrypt_ctl->priv_key.length; + plain_text_len = private_decrypt_ctl->plain_text.length; + cipher_text_len = private_decrypt_ctl->cipher_text.length; + + crypto_chk_return(klen < CRYPTO_PKE_ECC_KEY_MIN_SIZE || klen > CRYPTO_PKE_ECC_KEY_MAX_SIZE, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "klen is Invalid\n"); + crypto_chk_return(plain_text_len < CRYPTO_PKE_SM2_PLAIN_TEXT_MIN_SIZE || + plain_text_len > CRYPTO_PKE_SM2_PLAIN_TEXT_MAX_SIZE, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "plain_text_len is Invalid\n"); + crypto_chk_return(cipher_text_len < CRYPTO_PKE_SM2_PLAIN_TEXT_MIN_SIZE || + cipher_text_len > CRYPTO_PKE_SM2_PLAIN_TEXT_MAX_SIZE, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "cipher_text_len is Invalid\n"); + buffer_size = klen + plain_text_len + cipher_text_len; + buffer = crypto_malloc(buffer_size); + crypto_chk_return(buffer == TD_NULL, PKE_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + + priv_key.data = buffer; + priv_key.length = klen; + + cipher_text.data = priv_key.data + priv_key.length; + cipher_text.length = cipher_text_len; + + plain_text.data = cipher_text.data + cipher_text.length; + plain_text.length = plain_text_len; + + /* copy from user. */ + ret = crypto_copy_from_user(cipher_text.data, cipher_text_len, private_decrypt_ctl->cipher_text.data.p, + cipher_text_len); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = crypto_copy_from_user(priv_key.data, klen, private_decrypt_ctl->priv_key.data.p, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = kapi_pke_sm2_private_decrypt(&priv_key, &cipher_text, &plain_text); + crypto_chk_goto(ret != TD_SUCCESS, free_exit, "kapi_pke_sm2_private_decrypt failed, ret is 0x%x\n", ret); + + ret = crypto_copy_to_user(private_decrypt_ctl->plain_text.data.p, private_decrypt_ctl->plain_text.length, + plain_text.data, plain_text.length); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_TO_USER), + "crypto_copy_to_user failed, ret is 0x%x\n", ret); + private_decrypt_ctl->plain_text.length = plain_text.length; +free_exit: + crypto_chk_crypto_free_with_clean(buffer, buffer_size); + crypto_dispatch_func_exit(); + + return ret; +} + +static td_s32 dispatch_pke_mod(unsigned int cmd, td_void *argp, void *private_data) +{ + td_s32 ret = TD_SUCCESS; + pke_mod_ctl_t *mod_ctr = (pke_mod_ctl_t *)argp; + drv_pke_data a; + drv_pke_data p; + drv_pke_data c; + td_u8 *buffer = TD_NULL; + td_u32 buffer_size = 0; + td_u32 klen; + crypto_dispatch_func_enter(); + + dispatch_pke_cmd_chk(CRYPTO_CMD_PKE_MOD); + crypto_unused(private_data); + + pke_null_ptr_chk(mod_ctr->a.data.p); + pke_null_ptr_chk(mod_ctr->p.data.p); + pke_null_ptr_chk(mod_ctr->c.data.p); + + klen = mod_ctr->p.length; + crypto_chk_return(klen < CRYPTO_PKE_RSA_KEY_MIN_SIZE || klen > CRYPTO_PKE_RSA_KEY_MAX_SIZE, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "klen is Invalid\n"); + crypto_chk_return(mod_ctr->a.length != klen || mod_ctr->c.length != klen, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "mod_ctr->a.length or mod_ctr->c.length is Invalid\n"); + + buffer_size = klen * 3; // 3: for a、p、c + buffer = crypto_malloc(buffer_size); + crypto_chk_return(buffer == TD_NULL, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "crypto_malloc failed\n"); + (void)memset_s(buffer, buffer_size, 0, buffer_size); + + a.data = buffer; + a.length = klen; + + p.data = buffer + klen; + p.length = klen; + + c.data = buffer + klen + klen; + c.length = klen; + + /* copy from user. */ + ret = crypto_copy_from_user(a.data, a.length, mod_ctr->a.data.p, mod_ctr->a.length); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + ret = crypto_copy_from_user(p.data, p.length, mod_ctr->p.data.p, mod_ctr->p.length); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = kapi_cipher_pke_mod(&a, &p, &c); + crypto_chk_goto(ret != TD_SUCCESS, free_exit, "kapi_cipher_pke_mod failed, ret is 0x%x\n", ret); + + /* copy to user. */ + ret = crypto_copy_to_user(mod_ctr->c.data.p, mod_ctr->c.length, c.data, c.length); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_TO_USER), + "crypto_copy_to_user failed, ret is 0x%x\n", ret); + +free_exit: + crypto_chk_crypto_free_with_clean(buffer, buffer_size); + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_pke_exp_mod(unsigned int cmd, td_void *argp, void *private_data) +{ + td_s32 ret = TD_SUCCESS; + pke_exp_mod_ctl_t *exp_mod_ctr = (pke_exp_mod_ctl_t *)argp; + drv_pke_data n; + drv_pke_data k; + drv_pke_data in; + drv_pke_data out; + td_u8 *buffer = TD_NULL; + td_u32 buffer_size = 0; + td_u32 klen; + crypto_dispatch_func_enter(); + + dispatch_pke_cmd_chk(CRYPTO_CMD_PKE_EXP_MOD); + crypto_unused(private_data); + + pke_null_ptr_chk(exp_mod_ctr->n.data.p); + pke_null_ptr_chk(exp_mod_ctr->k.data.p); + pke_null_ptr_chk(exp_mod_ctr->in.data.p); + pke_null_ptr_chk(exp_mod_ctr->out.data.p); + + klen = exp_mod_ctr->n.length; + crypto_chk_return(klen < CRYPTO_PKE_RSA_KEY_MIN_SIZE || klen > CRYPTO_PKE_RSA_KEY_MAX_SIZE, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "klen is Invalid\n"); + crypto_chk_return(exp_mod_ctr->k.length != klen || exp_mod_ctr->in.length != klen || + exp_mod_ctr->out.length != klen, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "exp_mod_ctr->k.length or exp_mod_ctr->in.length or exp_mod_ctr->out.length is Invalid\n"); + + buffer_size = klen * 4; // 4: for n、k、in、out + buffer = crypto_malloc(buffer_size); + crypto_chk_return(buffer == TD_NULL, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "crypto_malloc failed\n"); + (void)memset_s(buffer, buffer_size, 0, buffer_size); + + n.data = buffer; + n.length = klen; + + k.data = buffer + klen; + k.length = klen; + + in.data = buffer + klen + klen; + in.length = klen; + + out.data = buffer + klen + klen; + out.length = klen; + + /* copy from user. */ + ret = crypto_copy_from_user(n.data, n.length, exp_mod_ctr->n.data.p, exp_mod_ctr->n.length); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + ret = crypto_copy_from_user(k.data, k.length, exp_mod_ctr->k.data.p, exp_mod_ctr->k.length); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + ret = crypto_copy_from_user(in.data, in.length, exp_mod_ctr->in.data.p, exp_mod_ctr->in.length); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = kapi_cipher_pke_exp_mod(&n, &k, &in, &out); + crypto_chk_goto(ret != TD_SUCCESS, free_exit, "kapi_cipher_pke_exp_mod failed, ret is 0x%x\n", ret); + + /* copy to user. */ + ret = crypto_copy_to_user(exp_mod_ctr->out.data.p, exp_mod_ctr->out.length, out.data, out.length); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_TO_USER), + "crypto_copy_to_user failed, ret is 0x%x\n", ret); + +free_exit: + crypto_chk_crypto_free_with_clean(buffer, buffer_size); + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_pke_rsa_sign(unsigned int cmd, td_void *argp, void *private_data) +{ + td_s32 ret = TD_SUCCESS; + pke_rsa_sign_ctl_t *rsa_sign_ctl = (pke_rsa_sign_ctl_t *)argp; + drv_pke_rsa_priv_key priv_key; + drv_pke_rsa_scheme scheme; + drv_pke_hash_type hash_type; + drv_pke_data input_hash; + drv_pke_data sig; + td_u32 klen = 0; + td_u32 hash_length = 0; + td_u8 *buffer = TD_NULL; + td_u32 buffer_size = 0; + crypto_dispatch_func_enter(); + + dispatch_pke_cmd_chk(CRYPTO_CMD_PKE_RSA_SIGN); + crypto_unused(private_data); + + pke_null_ptr_chk(rsa_sign_ctl->priv_key.d.p); + pke_null_ptr_chk(rsa_sign_ctl->priv_key.n.p); + pke_null_ptr_chk(rsa_sign_ctl->input_hash.data.p); + pke_null_ptr_chk(rsa_sign_ctl->sig.data.p); + + klen = rsa_sign_ctl->priv_key.d_len; + hash_length = rsa_sign_ctl->input_hash.length; + crypto_chk_return(klen < CRYPTO_PKE_RSA_KEY_MIN_SIZE || klen > CRYPTO_PKE_RSA_KEY_MAX_SIZE, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "klen is Invalid\n"); + crypto_chk_return(hash_length < CRYPTO_HASH_MIN_LEN || hash_length > CRYPTO_HASH_MAX_LEN, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "hash_len is Invalid\n"); + crypto_chk_return(rsa_sign_ctl->sig.length < klen, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "rsa_sign_ctl->sig.length is Invalid\n"); + crypto_chk_return(rsa_sign_ctl->priv_key.n_len != klen, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "rsa_sign_ctl->priv_key.n_len is Invalid\n"); + + scheme = rsa_sign_ctl->scheme; + hash_type = rsa_sign_ctl->hash_type; + + /* alloc memory. */ + buffer_size = hash_length + klen * 3; // 3: for priv_key.n, priv_key.d, sign + buffer = crypto_malloc(buffer_size); + crypto_chk_return(buffer == TD_NULL, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "crypto_malloc failed\n"); + + input_hash.data = buffer; + input_hash.length = hash_length; + + sig.data = input_hash.data + input_hash.length; + sig.length = klen; + + priv_key.n = sig.data + sig.length; + priv_key.n_len = klen; + + priv_key.d = priv_key.n + priv_key.n_len; + priv_key.d_len = klen; + + /* copy from user. */ + ret = crypto_copy_from_user(input_hash.data, hash_length, rsa_sign_ctl->input_hash.data.p, hash_length); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = crypto_copy_from_user(priv_key.n, klen, rsa_sign_ctl->priv_key.n.p, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = crypto_copy_from_user(priv_key.d, klen, rsa_sign_ctl->priv_key.d.p, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = kapi_pke_rsa_sign(&priv_key, scheme, hash_type, &input_hash, &sig); + crypto_chk_goto(ret != TD_SUCCESS, free_exit, "kapi_pke_rsa_sign failed, ret is 0x%x\n", ret); + + /* copy to user. */ + ret = crypto_copy_to_user(rsa_sign_ctl->sig.data.p, klen, sig.data, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_TO_USER), + "crypto_copy_to_user failed, ret is 0x%x\n", ret); + rsa_sign_ctl->sig.length = klen; + +free_exit: + crypto_chk_crypto_free_with_clean(buffer, buffer_size); + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_pke_rsa_verify(unsigned int cmd, td_void *argp, void *private_data) +{ + td_s32 ret = TD_SUCCESS; + pke_rsa_verify_ctl_t *rsa_verify_ctl = (pke_rsa_verify_ctl_t *)argp; + + drv_pke_rsa_pub_key pub_key = { 0 }; + drv_pke_data input_hash = { 0 }; + drv_pke_data sig = { 0 }; + td_u32 klen = 0; + td_u32 hash_len = 0; + td_u8 *buffer = TD_NULL; + td_u32 buffer_size = 0; + crypto_dispatch_func_enter(); + dispatch_pke_cmd_chk(CRYPTO_CMD_PKE_RSA_VERIFY); + + crypto_unused(private_data); + pke_null_ptr_chk(rsa_verify_ctl->pub_key.e.p); + pke_null_ptr_chk(rsa_verify_ctl->pub_key.n.p); + pke_null_ptr_chk(rsa_verify_ctl->input_hash.data.p); + pke_null_ptr_chk(rsa_verify_ctl->sig.data.p); + + klen = rsa_verify_ctl->pub_key.len; + hash_len = rsa_verify_ctl->input_hash.length; + crypto_chk_return(klen < CRYPTO_PKE_RSA_KEY_MIN_SIZE || klen > CRYPTO_PKE_RSA_KEY_MAX_SIZE, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "klen is Invalid\n"); + crypto_chk_return(hash_len < CRYPTO_HASH_MIN_LEN || hash_len > CRYPTO_HASH_MAX_LEN, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "hash_len is Invalid\n"); + + crypto_chk_return(rsa_verify_ctl->sig.length < klen, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "klen is Invalid\n"); + + /* alloc memory. */ + buffer_size = klen * 3 + hash_len; // 3: for pub_key.n, pub_key.e, sign hash_len: for input_hash + buffer = crypto_malloc(buffer_size); + crypto_chk_return(buffer == TD_NULL, PKE_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + + pub_key.n = buffer; + pub_key.e = buffer + klen; + pub_key.len = klen; + + input_hash.data = pub_key.e + pub_key.len; + input_hash.length = hash_len; + + sig.data = input_hash.data + input_hash.length; + sig.length = klen; + + /* copy from user. */ + ret = crypto_copy_from_user(pub_key.n, klen, rsa_verify_ctl->pub_key.n.p, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = crypto_copy_from_user(pub_key.e, klen, rsa_verify_ctl->pub_key.e.p, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = crypto_copy_from_user(input_hash.data, hash_len, rsa_verify_ctl->input_hash.data.p, hash_len); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = crypto_copy_from_user(sig.data, klen, rsa_verify_ctl->sig.data.p, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = kapi_pke_rsa_verify(&pub_key, rsa_verify_ctl->scheme, rsa_verify_ctl->hash_type, &input_hash, &sig); + crypto_chk_goto(ret != TD_SUCCESS, free_exit, "kapi_pke_rsa_verify failed, ret is 0x%x\n", ret); + +free_exit: + crypto_chk_crypto_free_with_clean(buffer, buffer_size); + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_pke_rsa_public_encrypt(unsigned int cmd, td_void *argp, void *private_data) +{ + td_s32 ret = TD_SUCCESS; + td_u8 *data_buffer = TD_NULL; + pke_rsa_pub_crypto_ctl_t *crypto_ctl = (pke_rsa_pub_crypto_ctl_t *)argp; + drv_pke_rsa_pub_key pub_key = { 0 }; + drv_pke_data input = { 0 }; + drv_pke_data label = { 0 }; + drv_pke_data output = { 0 }; + td_u32 total_len = 0; + td_u32 klen = 0; + td_u32 input_len = 0; + td_u32 label_len = 0; + crypto_dispatch_func_enter(); + dispatch_pke_cmd_chk(CRYPTO_CMD_PKE_RSA_PUBLIC_ENCRYPT); + + crypto_unused(private_data); + pke_null_ptr_chk(crypto_ctl->pub_key.e.p); + pke_null_ptr_chk(crypto_ctl->pub_key.n.p); + pke_null_ptr_chk(crypto_ctl->input.data.p); + pke_null_ptr_chk(crypto_ctl->output.data.p); + + klen = crypto_ctl->pub_key.len; + input_len = crypto_ctl->input.length; + label_len = crypto_ctl->label.length; + crypto_chk_return(klen < CRYPTO_PKE_RSA_KEY_MIN_SIZE || klen > CRYPTO_PKE_RSA_KEY_MAX_SIZE, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "klen is Invalid\n"); + crypto_chk_return(input_len == 0 || input_len > CRYPTO_PKE_RSA_KEY_MAX_SIZE, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "input_len is Invalid\n"); + crypto_chk_return(crypto_ctl->output.length < klen, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "crypto_ctl->output.length is Invalid\n"); + crypto_chk_return(label_len > CRYPTO_PKE_RSA_LABLE_MAX_SIZE, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "label_len is Invalid\n"); + + /* 2 pub_key len */ + total_len = klen * 3 + input_len + label_len; // 3: for pub_key.n, pub_key.e,output_data + /* alloc memory. */ + data_buffer = crypto_malloc(total_len); + crypto_chk_return(data_buffer == TD_NULL, PKE_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + + pub_key.n = data_buffer; + pub_key.e = pub_key.n + klen; + pub_key.len = klen; + + input.data = pub_key.e + klen; + input.length = input_len; + + output.data = input.data + input.length; + output.length = klen; + + label.data = output.data + output.length; + label.length = label_len; + + ret = crypto_copy_from_user(pub_key.n, klen, crypto_ctl->pub_key.n.p, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = crypto_copy_from_user(pub_key.e, klen, crypto_ctl->pub_key.e.p, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = crypto_copy_from_user(input.data, input_len, crypto_ctl->input.data.p, input_len); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + if (label_len != 0) { + ret = crypto_copy_from_user(label.data, label_len, crypto_ctl->label.data.p, label_len); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + ret = kapi_pke_rsa_public_encrypt(crypto_ctl->scheme, crypto_ctl->hash_type, &pub_key, &input, &label, &output); + } else { + ret = + kapi_pke_rsa_public_encrypt(crypto_ctl->scheme, crypto_ctl->hash_type, &pub_key, &input, TD_NULL, &output); + } + crypto_chk_goto(ret != TD_SUCCESS, free_exit, "kapi_pke_rsa_public_encrypt failed, ret is 0x%x\n", ret); + /* copy to user. */ + ret = crypto_copy_to_user(crypto_ctl->output.data.p, klen, output.data, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_TO_USER), + "crypto_copy_to_user failed, ret is 0x%x\n", ret); + crypto_ctl->output.length = klen; +free_exit: + crypto_chk_crypto_free_with_clean(data_buffer, total_len); + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_pke_rsa_private_decrypt(unsigned int cmd, td_void *argp, void *private_data) +{ + td_s32 ret = TD_SUCCESS; + td_u8 *data_buffer = TD_NULL; + pke_rsa_priv_crypto_ctl_t *crypto_ctl = (pke_rsa_priv_crypto_ctl_t *)argp; + + drv_pke_rsa_priv_key priv_key = { 0 }; + drv_pke_data input = { 0 }; + drv_pke_data label = { 0 }; + drv_pke_data output = { 0 }; + + td_u32 total_len = 0; + td_u32 klen = 0; + td_u32 label_len = 0; + crypto_dispatch_func_enter(); + dispatch_pke_cmd_chk(CRYPTO_CMD_PKE_RSA_PRIVATE_DECRYPT); + + crypto_unused(private_data); + pke_null_ptr_chk(crypto_ctl->priv_key.d.p); + pke_null_ptr_chk(crypto_ctl->priv_key.n.p); + pke_null_ptr_chk(crypto_ctl->input.data.p); + pke_null_ptr_chk(crypto_ctl->output.data.p); + + klen = crypto_ctl->priv_key.n_len; + label_len = crypto_ctl->label.length; + crypto_chk_return(klen < CRYPTO_PKE_RSA_KEY_MIN_SIZE || klen > CRYPTO_PKE_RSA_KEY_MAX_SIZE, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "klen is Invalid\n"); + crypto_chk_return(crypto_ctl->priv_key.d_len != klen, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "crypto_ctl->priv_key.d_len is Invalid\n"); + crypto_chk_return(crypto_ctl->input.length != klen, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "crypto_ctl->input.length is Invalid\n"); + crypto_chk_return(crypto_ctl->output.length == 0, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "crypto_ctl->output.length is Invalid\n"); + crypto_chk_return(label_len > CRYPTO_PKE_RSA_LABLE_MAX_SIZE, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "label_len is Invalid\n"); + + total_len = klen * 4 + label_len; // 4: for priv_key.n, priv_key.d, input.data, output.data + /* alloc memory. */ + data_buffer = crypto_malloc(total_len); + crypto_chk_return(data_buffer == TD_NULL, PKE_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + + priv_key.n = data_buffer; + priv_key.n_len = klen; + priv_key.d = priv_key.n + priv_key.n_len; + priv_key.d_len = klen; + + input.data = priv_key.d + priv_key.d_len; + input.length = klen; + + output.data = input.data + input.length; + output.length = klen; + + label.data = output.data + output.length; + label.length = label_len; + + ret = crypto_copy_from_user(priv_key.n, klen, crypto_ctl->priv_key.n.p, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = crypto_copy_from_user(priv_key.d, klen, crypto_ctl->priv_key.d.p, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + ret = crypto_copy_from_user(input.data, klen, crypto_ctl->input.data.p, klen); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + if (label_len != 0) { + ret = crypto_copy_from_user(label.data, label_len, crypto_ctl->label.data.p, label_len); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_FROM_USER), + "crypto_copy_from_user failed, ret is 0x%x\n", ret); + ret = + kapi_pke_rsa_private_decrypt(crypto_ctl->scheme, crypto_ctl->hash_type, &priv_key, &input, &label, &output); + } else { + ret = kapi_pke_rsa_private_decrypt(crypto_ctl->scheme, crypto_ctl->hash_type, &priv_key, &input, TD_NULL, + &output); + } + crypto_chk_goto(ret != TD_SUCCESS, free_exit, "kapi_pke_rsa_private_decrypt failed, ret is 0x%x\n", ret); + /* copy to user. */ + ret = crypto_copy_to_user(crypto_ctl->output.data.p, crypto_ctl->output.length, output.data, output.length); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, free_exit, PKE_COMPAT_ERRNO(ERROR_COPY_TO_USER), + "crypto_copy_to_user failed, ret is 0x%x\n", ret); + crypto_ctl->output.length = output.length; +free_exit: + crypto_chk_crypto_free_with_clean(data_buffer, total_len); + crypto_dispatch_func_exit(); + return ret; +} + +static crypto_ioctl_cmd g_dispatch_func[] = { + { CRYPTO_CMD_HASH_INIT, dispatch_hash_init }, + { CRYPTO_CMD_HASH_DEINIT, dispatch_hash_deinit }, + { CRYPTO_CMD_HASH_START, dispatch_hash_start }, + { CRYPTO_CMD_HASH_UPDATE, dispatch_hash_update }, + { CRYPTO_CMD_HASH_FINISH, dispatch_hash_finish }, + { CRYPTO_CMD_HASH_GET, dispatch_hash_get }, + { CRYPTO_CMD_HASH_SET, dispatch_hash_set }, + { CRYPTO_CMD_HASH_DESTROY, dispatch_hash_destroy }, + { CRYPTO_CMD_PBKDF2, dispatch_cipher_pbkdf2 }, + { CRYPTO_CMD_TRNG_GET_RANDOM, dispatch_trng_get_random }, + { CRYPTO_CMD_TRNG_GET_MULTI_RANDOM, dispatch_trng_get_multi_random }, + + { CRYPTO_CMD_SYMC_INIT, dispatch_symc_init }, + { CRYPTO_CMD_SYMC_DEINIT, dispatch_symc_deinit }, + { CRYPTO_CMD_SYMC_CREATE, dispatch_symc_create }, + { CRYPTO_CMD_SYMC_DESTROY, dispatch_symc_destroy }, + { CRYPTO_CMD_SYMC_SET_CONFIG, dispatch_symc_set_config }, + { CRYPTO_CMD_SYMC_GET_CONFIG, dispatch_symc_get_config }, + { CRYPTO_CMD_SYMC_ATTACH, dispatch_symc_attach }, + { CRYPTO_CMD_SYMC_ENCRYPT, dispatch_symc_encrypt }, + { CRYPTO_CMD_SYMC_DECRYPT, dispatch_symc_decrypt }, + { CRYPTO_CMD_SYMC_ENCRYPT_MULTI, dispatch_symc_encrypt_multi }, + { CRYPTO_CMD_SYMC_DECRYPT_MULTI, dispatch_symc_decrypt_multi }, + { CRYPTO_CMD_SYMC_GET_TAG, dispatch_symc_get_tag }, + { CRYPTO_CMD_SYMC_MAC_START, dispatch_symc_mac_start }, + { CRYPTO_CMD_SYMC_MAC_UPDATE, dispatch_symc_mac_update }, + { CRYPTO_CMD_SYMC_MAC_FINISH, dispatch_symc_mac_finish }, + + { CRYPTO_CMD_PKE_ECC_GEN_KEY, dispatch_pke_ecc_gen_key}, + { CRYPTO_CMD_PKE_ECC_GEN_ECDH_KEY, dispatch_pke_ecc_gen_ecdh_key}, + { CRYPTO_CMD_PKE_ECDSA_SIGN, dispatch_pke_ecdsa_sign}, + { CRYPTO_CMD_PKE_ECDSA_VERIFY, dispatch_pke_ecdsa_verify}, + { CRYPTO_CMD_PKE_EDDSA_SIGN, dispatch_pke_eddsa_sign}, + { CRYPTO_CMD_PKE_EDDSA_VERIFY, dispatch_pke_eddsa_verify}, + { CRYPTO_CMD_PKE_CHECK_DOT_ON_CURVE, dispatch_pke_check_dot_on_curve}, + + { CRYPTO_CMD_PKE_SM2_DSA_HASH, dispatch_pke_sm2_dsa_hash}, + { CRYPTO_CMD_PKE_SM2_PUBLIC_ENCRYPT, dispatch_pke_sm2_public_encrypt}, + { CRYPTO_CMD_PKE_SM2_PRIVATE_DECRYPT, dispatch_pke_sm2_private_decrypt}, + + { CRYPTO_CMD_PKE_MOD, dispatch_pke_mod}, + { CRYPTO_CMD_PKE_EXP_MOD, dispatch_pke_exp_mod}, + + { CRYPTO_CMD_PKE_RSA_SIGN, dispatch_pke_rsa_sign}, + { CRYPTO_CMD_PKE_RSA_VERIFY, dispatch_pke_rsa_verify}, + { CRYPTO_CMD_PKE_RSA_PUBLIC_ENCRYPT, dispatch_pke_rsa_public_encrypt}, + { CRYPTO_CMD_PKE_RSA_PRIVATE_DECRYPT, dispatch_pke_rsa_private_decrypt}, +}; + +crypto_ioctl_cmd *crypto_get_ioctl_cmd_list(td_void) +{ + return g_dispatch_func; +} + +td_u32 crypto_get_ioctl_cmd_cnt(td_void) +{ + return sizeof(g_dispatch_func) / sizeof(crypto_ioctl_cmd); +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/dispatch_code/crypto_dispatch.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/dispatch_code/crypto_dispatch.h new file mode 100644 index 00000000..47c3c05f --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/dispatch_code/crypto_dispatch.h @@ -0,0 +1,16 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef CRYPTO_DISPATCH_H +#define CRYPTO_DISPATCH_H + +#include "crypto_type.h" + +#include "crypto_osal_adapt.h" + +crypto_ioctl_cmd *crypto_get_ioctl_cmd_list(td_void); + +td_u32 crypto_get_ioctl_cmd_cnt(td_void); + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/dispatch_code/dispatch_km.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/dispatch_code/dispatch_km.c new file mode 100644 index 00000000..b0570dab --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/dispatch_code/dispatch_km.c @@ -0,0 +1,281 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "dispatch_km.h" +#include "crypto_common_macro.h" +#include "kapi_km.h" + +#define KM_COMPAT_ERRNO(err_code) DISPATCH_COMPAT_ERRNO(ERROR_MODULE_KM, err_code) +#define km_null_ptr_chk(ptr) \ + crypto_chk_return((ptr) == TD_NULL, KM_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), #ptr" is NULL\n") + +static td_s32 dispatch_keyslot_create(unsigned int cmd, td_void *argp, void *private_data) +{ + td_s32 ret = TD_SUCCESS; + keyslot_create_ctl_t *keyslot_create_t = TD_NULL; + td_handle keyslot_handle; + crypto_dispatch_func_enter(); + + crypto_unused(cmd); + crypto_unused(private_data); + + keyslot_create_t = (keyslot_create_ctl_t *)argp; + ret = kapi_keyslot_create(&keyslot_handle, keyslot_create_t->keyslot_type); + crypto_chk_return(ret != TD_SUCCESS, ret, "kapi_keyslot_create failed, ret is 0x%x\n", ret); + keyslot_create_t->kapi_keyslot_handle = (crypto_handle)keyslot_handle; + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_keyslot_destroy(unsigned int cmd, td_void *argp, void *private_data) +{ + td_s32 ret = TD_SUCCESS; + keyslot_destroy_ctl_t *keyslot_destroy_t = TD_NULL; + crypto_dispatch_func_enter(); + + crypto_unused(cmd); + crypto_unused(private_data); + + keyslot_destroy_t = (keyslot_destroy_ctl_t *)argp; + ret = kapi_keyslot_destroy(keyslot_destroy_t->kapi_keyslot_handle); + crypto_chk_return(ret != TD_SUCCESS, ret, "kapi_keyslot_destroy failed, ret is 0x%x\n", ret); + + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_klad_create(unsigned int cmd, td_void *argp, void *private_data) +{ + td_s32 ret = TD_SUCCESS; + klad_handle_ctl_t *klad_handle_ctl = TD_NULL; + td_handle klad_handle; + crypto_dispatch_func_enter(); + + crypto_unused(cmd); + crypto_unused(private_data); + + klad_handle_ctl = (klad_handle_ctl_t *)argp; + ret = kapi_klad_create(&klad_handle); + crypto_chk_return(ret != TD_SUCCESS, ret, "kapi_keyslot_create failed, ret is 0x%x\n", ret); + klad_handle_ctl->kapi_klad_handle = (crypto_handle)klad_handle; + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_klad_destroy(unsigned int cmd, td_void *argp, void *private_data) +{ + td_s32 ret = TD_SUCCESS; + klad_handle_ctl_t *klad_handle_ctl = TD_NULL; + crypto_dispatch_func_enter(); + + crypto_unused(cmd); + crypto_unused(private_data); + + klad_handle_ctl = (klad_handle_ctl_t *)argp; + ret = kapi_klad_destroy(klad_handle_ctl->kapi_klad_handle); + crypto_chk_return(ret != TD_SUCCESS, ret, "kapi_klad_destroy failed, ret is 0x%x\n", ret); + + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_klad_set_attr(unsigned int cmd, td_void *argp, void *private_data) +{ + td_s32 ret = TD_SUCCESS; + klad_attr_ctl_t *klad_attr_ctl = TD_NULL; + crypto_dispatch_func_enter(); + + crypto_unused(cmd); + crypto_unused(private_data); + + klad_attr_ctl = (klad_attr_ctl_t *)argp; + ret = kapi_klad_set_attr(klad_attr_ctl->kapi_klad_handle, &klad_attr_ctl->attr); + crypto_chk_return(ret != TD_SUCCESS, ret, "kapi_klad_set_attr failed, ret is 0x%x\n", ret); + + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_klad_get_attr(unsigned int cmd, td_void *argp, void *private_data) +{ + td_s32 ret = TD_SUCCESS; + klad_attr_ctl_t *klad_attr_ctl = TD_NULL; + crypto_dispatch_func_enter(); + + crypto_unused(cmd); + crypto_unused(private_data); + + klad_attr_ctl = (klad_attr_ctl_t *)argp; + + ret = kapi_klad_get_attr(klad_attr_ctl->kapi_klad_handle, &klad_attr_ctl->attr); + crypto_chk_return(ret != TD_SUCCESS, ret, "kapi_klad_get_attr failed, ret is 0x%x\n", ret); + + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_klad_attach(unsigned int cmd, td_void *argp, void *private_data) +{ + td_s32 ret = TD_SUCCESS; + klad_attach_ctl_t *klad_attach_ctl = TD_NULL; + crypto_dispatch_func_enter(); + + crypto_unused(cmd); + crypto_unused(private_data); + + klad_attach_ctl = (klad_attach_ctl_t *)argp; + ret = kapi_klad_attach(klad_attach_ctl->kapi_klad_handle, klad_attach_ctl->klad_type, + klad_attach_ctl->kapi_keyslot_handle); + crypto_chk_return(ret != TD_SUCCESS, ret, "kapi_klad_attach failed, ret is 0x%x\n", ret); + + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_klad_detach(unsigned int cmd, td_void *argp, void *private_data) +{ + td_s32 ret = TD_SUCCESS; + klad_attach_ctl_t *klad_attach_ctl = TD_NULL; + crypto_dispatch_func_enter(); + + crypto_unused(cmd); + crypto_unused(private_data); + + klad_attach_ctl = (klad_attach_ctl_t *)argp; + ret = kapi_klad_detach(klad_attach_ctl->kapi_klad_handle, klad_attach_ctl->klad_type, + klad_attach_ctl->kapi_keyslot_handle); + crypto_chk_return(ret != TD_SUCCESS, ret, "kapi_klad_detach failed, ret is 0x%x\n", ret); + + crypto_dispatch_func_exit(); + return ret; +} + +#define MAX_KEY_LEN 128 +static td_s32 dispatch_klad_set_clear_key(unsigned int cmd, td_void *argp, void *private_data) +{ + td_s32 ret = TD_SUCCESS; + klad_set_clear_key_ctl_t *klad_set_clear_key_ctl = TD_NULL; + td_u8 key[MAX_KEY_LEN] = {0}; + km_klad_clear_key clear_key = {0}; + crypto_dispatch_func_enter(); + + crypto_unused(cmd); + crypto_unused(private_data); + + klad_set_clear_key_ctl = (klad_set_clear_key_ctl_t *)argp; + + crypto_chk_return(klad_set_clear_key_ctl->key_size > MAX_KEY_LEN, KM_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "Unsupported key_len, the max lenth of the key is: %d\n", MAX_KEY_LEN); + crypto_param_require(klad_set_clear_key_ctl->key.p != TD_NULL); + + ret = crypto_copy_from_user(key, MAX_KEY_LEN, klad_set_clear_key_ctl->key.p, \ + klad_set_clear_key_ctl->key_size); + crypto_chk_return(ret != TD_SUCCESS, ret, "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + clear_key.key = key; + clear_key.hmac_type = klad_set_clear_key_ctl->hmac_type; + clear_key.key_size = klad_set_clear_key_ctl->key_size; + clear_key.key_parity = klad_set_clear_key_ctl->key_parity; + + ret = kapi_klad_set_clear_key(klad_set_clear_key_ctl->kapi_klad_handle, &clear_key); + crypto_chk_goto(ret != TD_SUCCESS, exit, "kapi_klad_set_clear_key failed, ret is 0x%x\n", ret); + +exit: + (td_void)memset_s(key, MAX_KEY_LEN, 0, MAX_KEY_LEN); + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_klad_set_session_key(unsigned int cmd, td_void *argp, void *private_data) +{ + td_s32 ret = TD_SUCCESS; + klad_set_session_key_ctl_t *klad_set_session_key_ctl = TD_NULL; + td_u8 key[MAX_KEY_LEN] = {0}; + km_klad_session_key session_key = {0}; + crypto_dispatch_func_enter(); + + crypto_unused(cmd); + crypto_unused(private_data); + + klad_set_session_key_ctl = (klad_set_session_key_ctl_t *)argp; + + crypto_chk_return(klad_set_session_key_ctl->key_size > MAX_KEY_LEN, KM_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "Unsupported key_len, the max lenth of the key is: %d\n", MAX_KEY_LEN); + crypto_param_require(klad_set_session_key_ctl->key.p != TD_NULL); + + ret = crypto_copy_from_user(key, MAX_KEY_LEN, klad_set_session_key_ctl->key.p, \ + klad_set_session_key_ctl->key_size); + crypto_chk_return(ret != TD_SUCCESS, ret, "crypto_copy_from_user failed, ret is 0x%x\n", ret); + session_key.key = key; + session_key.alg = klad_set_session_key_ctl->alg; + session_key.key_size = klad_set_session_key_ctl->key_size; + session_key.level = klad_set_session_key_ctl->level; + + ret = kapi_klad_set_session_key(klad_set_session_key_ctl->kapi_klad_handle, &session_key); + crypto_chk_goto(ret != TD_SUCCESS, exit, "kapi_klad_set_session_key failed, ret is 0x%x\n", ret); + +exit: + (td_void)memset_s(key, MAX_KEY_LEN, 0, MAX_KEY_LEN); + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_klad_set_content_key(unsigned int cmd, td_void *argp, void *private_data) +{ + td_s32 ret = TD_SUCCESS; + klad_set_content_key_ctl_t *klad_set_content_key_ctl = TD_NULL; + td_u8 key[MAX_KEY_LEN] = {0}; + km_klad_content_key content_key = {0}; + crypto_dispatch_func_enter(); + + crypto_unused(cmd); + crypto_unused(private_data); + + klad_set_content_key_ctl = (klad_set_content_key_ctl_t *)argp; + + crypto_chk_return(klad_set_content_key_ctl->key_size > MAX_KEY_LEN, KM_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "Unsupported key_len, the max lenth of the key is: %d\n", MAX_KEY_LEN); + crypto_param_require(klad_set_content_key_ctl->key.p != TD_NULL); + + ret = crypto_copy_from_user(key, MAX_KEY_LEN, klad_set_content_key_ctl->key.p, \ + klad_set_content_key_ctl->key_size); + crypto_chk_return(ret != TD_SUCCESS, ret, "crypto_copy_from_user failed, ret is 0x%x\n", ret); + + content_key.key = key; + content_key.alg = klad_set_content_key_ctl->alg; + content_key.key_size = klad_set_content_key_ctl->key_size; + content_key.key_parity = klad_set_content_key_ctl->key_parity; + + ret = kapi_klad_set_content_key(klad_set_content_key_ctl->kapi_klad_handle, &content_key); + crypto_chk_goto(ret != TD_SUCCESS, exit, "kapi_klad_set_content_key failed, ret is 0x%x\n", ret); + +exit: + (td_void)memset_s(key, MAX_KEY_LEN, 0, MAX_KEY_LEN); + crypto_dispatch_func_exit(); + return ret; +} + +static crypto_ioctl_cmd g_km_func_list[] = { + {CMD_KEYSLOT_CREATE_HANDLE, dispatch_keyslot_create}, + {CMD_KEYSLOT_DESTROY_HANDLE, dispatch_keyslot_destroy}, + {CMD_KLAD_CREATE_HANDLE, dispatch_klad_create}, + {CMD_KLAD_DESTROY_HANDLE, dispatch_klad_destroy}, + {CMD_KLAD_ATTACH, dispatch_klad_attach}, + {CMD_KLAD_DETACH, dispatch_klad_detach}, + {CMD_KLAD_SET_ATTR, dispatch_klad_set_attr}, + {CMD_KLAD_GET_ATTR, dispatch_klad_get_attr}, + {CMD_KLAD_SET_SESSION_KEY, dispatch_klad_set_session_key}, + {CMD_KLAD_SET_CONTENT_KEY, dispatch_klad_set_content_key}, + {CMD_KLAD_SET_CLEAR_KEY, dispatch_klad_set_clear_key}, +}; + +crypto_ioctl_cmd *get_km_func_list(td_void) +{ + return g_km_func_list; +} + +td_u32 get_km_func_num(td_void) +{ + return crypto_array_size(g_km_func_list); +} diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/dispatch_code/dispatch_km.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/dispatch_code/dispatch_km.h new file mode 100644 index 00000000..e4e8e39b --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/dispatch_code/dispatch_km.h @@ -0,0 +1,16 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef DISPATCH_KM_H +#define DISPATCH_KM_H + +#include "crypto_osal_lib.h" +#include "crypto_osal_adapt.h" +#include "ioctl_km.h" + +crypto_ioctl_cmd *get_km_func_list(td_void); + +td_u32 get_km_func_num(td_void); + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/dispatch_code/dispatch_otp.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/dispatch_code/dispatch_otp.c new file mode 100644 index 00000000..b50c510f --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/dispatch_code/dispatch_otp.c @@ -0,0 +1,83 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "dispatch_otp.h" +#include "crypto_osal_lib.h" +#include "crypto_common_macro.h" +#include "kapi_otp.h" + +static td_s32 dispatch_otp_read_word(unsigned int cmd, td_void *argp, void *private_data) +{ + td_s32 ret = TD_SUCCESS; + otp_word_ctl_t *otp_word_ctl = TD_NULL; + crypto_dispatch_func_enter(); + + crypto_unused(cmd); + crypto_unused(private_data); + + otp_word_ctl = (otp_word_ctl_t *)argp; + + ret = kapi_otp_read_word(otp_word_ctl->addr, &otp_word_ctl->word); + crypto_chk_return(ret != TD_SUCCESS, ret, "kapi_otp_read_word failed, ret is 0x%x\n", ret); + + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_otp_read_byte(unsigned int cmd, td_void *argp, void *private_data) +{ + td_s32 ret = TD_SUCCESS; + otp_byte_ctl_t *otp_byte_ctl = TD_NULL; + crypto_dispatch_func_enter(); + + crypto_unused(cmd); + crypto_unused(private_data); + + otp_byte_ctl = (otp_byte_ctl_t *)argp; + +#ifdef CONFIG_DISPATCH_DEBUG + crypto_print("addr is 0x%x\n", otp_byte_ctl->addr); + crypto_print("byte is 0x%x\n", &otp_byte_ctl->byte); +#endif + + ret = kapi_otp_read_byte(otp_byte_ctl->addr, &otp_byte_ctl->byte); + crypto_chk_return(ret != TD_SUCCESS, ret, "kapi_otp_read_byte failed, ret is 0x%x\n", ret); + + crypto_dispatch_func_exit(); + return ret; +} + +static td_s32 dispatch_otp_write_byte(unsigned int cmd, td_void *argp, void *private_data) +{ + td_s32 ret = TD_SUCCESS; + otp_byte_ctl_t *otp_byte_ctl = TD_NULL; + crypto_dispatch_func_enter(); + + crypto_unused(cmd); + crypto_unused(private_data); + + otp_byte_ctl = (otp_byte_ctl_t *)argp; + + ret = kapi_otp_write_byte(otp_byte_ctl->addr, otp_byte_ctl->byte); + crypto_chk_return(ret != TD_SUCCESS, ret, "kapi_otp_write_byte failed, ret is 0x%x\n", ret); + + crypto_dispatch_func_exit(); + return ret; +} + +static crypto_ioctl_cmd g_otp_func_list[] = { + {CMD_OTP_READ_WORD, dispatch_otp_read_word}, + {CMD_OTP_READ_BYTE, dispatch_otp_read_byte}, + {CMD_OTP_WRITE_BYTE, dispatch_otp_write_byte}, +}; + +crypto_ioctl_cmd *get_otp_func_list(td_void) +{ + return g_otp_func_list; +} + +td_u32 get_otp_func_num(td_void) +{ + return crypto_array_size(g_otp_func_list); +} diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/dispatch_code/dispatch_otp.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/dispatch_code/dispatch_otp.h new file mode 100644 index 00000000..d999ca61 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/dispatch_code/dispatch_otp.h @@ -0,0 +1,15 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef DISPATCH_OTP_H +#define DISPATCH_OTP_H + +#include "crypto_osal_adapt.h" +#include "ioctl_otp.h" + +crypto_ioctl_cmd *get_otp_func_list(td_void); + +td_u32 get_otp_func_num(td_void); + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/ca_misc_register.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/ca_misc_register.h new file mode 100644 index 00000000..af85f679 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/ca_misc_register.h @@ -0,0 +1,26 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef CA_MISC_REGISTER_H +#define CA_MISC_REGISTER_H + +/* ! Define the crg control reg */ +#define PKE_CRG_CTRL (0x0028) +#define CORE_LP_CTRL (0x002C) + +#define CPU_ID_STAT (0x0018) + +typedef enum { + CPU_ID_AIDSP = 0x00000035, + CPU_ID_PCPU = 0x0000006a, + CPU_ID_SCPU = 0x000000a5, + CPU_ID_ACPU = 0x000000aa, + CPU_ID_INVALID = 0xffffffff +} ca_misc_cpu_id; + +#define SPACC_SEC_DFA_EN (0x0120) +#define SPACC_DFA_ENABLE (0x05) +#define SPACC_DFA_DISABLE (0x0A) + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/crypto_drv_common.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/crypto_drv_common.c new file mode 100644 index 00000000..87e46036 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/crypto_drv_common.c @@ -0,0 +1,486 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "drv_common.h" +#include "drv_trng.h" +#include "crypto_drv_common.h" + +/* crypto dump functions. */ +#define MAX_DUMP_LENGHT (256) +#define BYTES_IN_ONE_LINE (16) +#ifndef KERN_CONT +#define KERN_CONT +#endif + +static crypto_drv_func g_drv_func = { + .malloc_coherent = TD_NULL, + .free_coherent = TD_NULL, + .get_phys_addr = TD_NULL +}; + +td_void __attribute__((weak)) *crypto_malloc_coherent(td_u32 size, td_char *buffer_name) +{ + crypto_mem_type mem_type = CRYPTO_MEM_TYPE_MMZ; + if (g_drv_func.malloc_coherent == TD_NULL) { + return TD_NULL; + } + if (crypto_smmu_support()) { + mem_type = CRYPTO_MEM_TYPE_SMMU; + } + return g_drv_func.malloc_coherent(size, mem_type, buffer_name); +} + +td_void __attribute__((weak)) *crypto_malloc_mmz(td_u32 size, td_char *buffer_name) +{ + if (g_drv_func.malloc_coherent == TD_NULL) { + return TD_NULL; + } + return g_drv_func.malloc_coherent(size, CRYPTO_MEM_TYPE_MMZ, buffer_name); +} + +td_void __attribute__((weak)) crypto_free_coherent(td_void *ptr) +{ + if (g_drv_func.free_coherent == TD_NULL) { + return; + } + g_drv_func.free_coherent(ptr); +} + +td_phys_addr_t __attribute__((weak)) crypto_get_phys_addr(td_void *ptr) +{ + if (g_drv_func.get_phys_addr == TD_NULL) { + return 0; + } + return g_drv_func.get_phys_addr(ptr); +} + +td_bool __attribute__((weak)) crypto_smmu_support(td_void) +{ + if (g_drv_func.get_smmu_table_addr != TD_NULL) { + return TD_TRUE; + } else { + return TD_FALSE; + } +} + +td_s32 drv_cipher_register_func(const crypto_drv_func *drv_func_list) +{ + if (drv_func_list == TD_NULL) { + return TD_FAILURE; + } + if (drv_func_list->malloc_coherent == TD_NULL || + drv_func_list->free_coherent == TD_NULL || + drv_func_list->get_phys_addr == TD_NULL) { + return TD_FAILURE; + } + + g_drv_func.malloc_coherent = drv_func_list->malloc_coherent; + g_drv_func.free_coherent = drv_func_list->free_coherent; + g_drv_func.get_phys_addr = drv_func_list->get_phys_addr; + g_drv_func.get_smmu_table_addr = drv_func_list->get_smmu_table_addr; + g_drv_func.get_cpu_type = drv_func_list->get_cpu_type; + + return TD_SUCCESS; +} + +void __attribute__((weak)) crypto_cache_flush(uintptr_t base_addr, td_u32 size) +{ + crypto_unused(base_addr); + crypto_unused(size); +} + +void __attribute__((weak)) crypto_dcache_enable(void) +{ +} + +void __attribute__((weak)) crypto_dcache_disable(void) +{ +} + +typedef struct { + drv_pke_ecc_curve_type curve_type; + td_bool is_support; +} ecc_alg_support_t; + +static ecc_alg_support_t g_ecc_alg_support[] = { + {DRV_PKE_ECC_TYPE_RFC5639_P256, TD_TRUE}, + {DRV_PKE_ECC_TYPE_RFC5639_P384, TD_TRUE}, + {DRV_PKE_ECC_TYPE_RFC5639_P512, TD_TRUE}, + {DRV_PKE_ECC_TYPE_FIPS_P256K, TD_FALSE}, + {DRV_PKE_ECC_TYPE_FIPS_P256R, TD_FALSE}, + {DRV_PKE_ECC_TYPE_FIPS_P384R, TD_FALSE}, + {DRV_PKE_ECC_TYPE_FIPS_P521R, TD_FALSE}, + {DRV_PKE_ECC_TYPE_RFC7748, TD_TRUE}, + {DRV_PKE_ECC_TYPE_RFC8032, TD_TRUE}, + {DRV_PKE_ECC_TYPE_SM2, TD_TRUE}, +}; + +td_bool crypto_ecc_support(drv_pke_ecc_curve_type curve_type) +{ + td_u32 i; + for (i = 0; i < crypto_array_size(g_ecc_alg_support); i++) { + if (curve_type == g_ecc_alg_support[i].curve_type) { + return g_ecc_alg_support[i].is_support; + } + } + return TD_FALSE; +} + +typedef struct { + td_u32 klen; + td_bool is_support; +} rsa_alg_keylen_support_t; + +static rsa_alg_keylen_support_t g_rsa_alg_keylen_support[] = { + {CRYPTO_RSA_2048_LEN, TD_FALSE}, + {CRYPTO_RSA_3072_LEN, TD_TRUE}, + {CRYPTO_RSA_4096_LEN, TD_TRUE}, +}; + +typedef struct { + drv_pke_rsa_scheme scheme; + td_bool is_support; +} rsa_alg_scheme_support_t; + +static rsa_alg_scheme_support_t g_rsa_alg_scheme_support[] = { + {DRV_PKE_RSA_SCHEME_PKCS1_V15, TD_FALSE}, + {DRV_PKE_RSA_SCHEME_PKCS1_V21, TD_TRUE}, +}; + +td_bool crypto_rsa_support(td_u32 klen, drv_pke_rsa_scheme scheme) +{ + td_u32 i; + td_bool is_support = TD_FALSE; + for (i = 0; i < crypto_array_size(g_rsa_alg_keylen_support); i++) { + if (g_rsa_alg_keylen_support[i].klen == klen) { + is_support = g_rsa_alg_keylen_support[i].is_support; + break; + } + } + for (i = 0; i < crypto_array_size(g_rsa_alg_scheme_support); i++) { + if (g_rsa_alg_scheme_support[i].scheme == scheme) { + is_support = (is_support && g_rsa_alg_scheme_support[i].is_support); + break; + } + } + return is_support; +} + +typedef struct { + crypto_hash_type hash_type; + td_bool is_support; +} hash_alg_support_t; + +static hash_alg_support_t g_hash_alg_support[] = { + {CRYPTO_HASH_TYPE_SHA256, TD_TRUE}, + {CRYPTO_HASH_TYPE_SHA384, TD_TRUE}, + {CRYPTO_HASH_TYPE_SHA512, TD_TRUE}, + {CRYPTO_HASH_TYPE_SM3, TD_TRUE}, + {CRYPTO_HASH_TYPE_HMAC_SHA256, TD_TRUE}, + {CRYPTO_HASH_TYPE_HMAC_SHA384, TD_TRUE}, + {CRYPTO_HASH_TYPE_HMAC_SHA512, TD_TRUE}, + {CRYPTO_HASH_TYPE_HMAC_SM3, TD_TRUE}, +}; + +td_bool crypto_hash_support(crypto_hash_type hash_type) +{ + td_u32 i; + for (i = 0; i < crypto_array_size(g_hash_alg_support); i++) { + if (hash_type == g_hash_alg_support[i].hash_type) { + return g_hash_alg_support[i].is_support; + } + } + return TD_FALSE; +} + +typedef struct { + crypto_symc_alg alg; + td_bool is_support; +} symc_alg_support_t; + +static symc_alg_support_t g_symc_alg_support[] = { + {CRYPTO_SYMC_ALG_TDES, TD_FALSE}, + {CRYPTO_SYMC_ALG_AES, TD_TRUE}, + {CRYPTO_SYMC_ALG_SM4, TD_TRUE}, + {CRYPTO_SYMC_ALG_LEA, TD_FALSE}, + {CRYPTO_SYMC_ALG_DMA, TD_FALSE}, +}; + +typedef struct { + crypto_symc_work_mode mode; + td_bool is_support; +} symc_alg_work_mode_support_t; + +static symc_alg_work_mode_support_t g_symc_alg_work_mode_support[] = { + {CRYPTO_SYMC_WORK_MODE_ECB, TD_FALSE}, + {CRYPTO_SYMC_WORK_MODE_CBC, TD_TRUE}, + {CRYPTO_SYMC_WORK_MODE_CTR, TD_TRUE}, + {CRYPTO_SYMC_WORK_MODE_OFB, TD_TRUE}, + {CRYPTO_SYMC_WORK_MODE_CFB, TD_TRUE}, + {CRYPTO_SYMC_WORK_MODE_CCM, TD_TRUE}, + {CRYPTO_SYMC_WORK_MODE_GCM, TD_TRUE}, + {CRYPTO_SYMC_WORK_MODE_CBC_MAC, TD_TRUE}, + {CRYPTO_SYMC_WORK_MODE_CMAC, TD_TRUE}, +}; + +typedef struct { + crypto_symc_key_length key_len; + td_bool is_support; +} symc_alg_keylen_support_t; + +static symc_alg_keylen_support_t g_symc_alg_keylen_support[] = { + {CRYPTO_SYMC_KEY_64BIT, TD_FALSE}, + {CRYPTO_SYMC_KEY_128BIT, TD_TRUE}, + {CRYPTO_SYMC_KEY_192BIT, TD_TRUE}, + {CRYPTO_SYMC_KEY_256BIT, TD_TRUE}, +}; + +typedef struct { + crypto_symc_bit_width bit_width; + td_bool is_support; +} symc_alg_bit_width_support_t; + +static symc_alg_bit_width_support_t g_symc_alg_bit_width_support[] = { + {CRYPTO_SYMC_BIT_WIDTH_1BIT, TD_TRUE}, + {CRYPTO_SYMC_BIT_WIDTH_8BIT, TD_TRUE}, + {CRYPTO_SYMC_BIT_WIDTH_64BIT, TD_FALSE}, + {CRYPTO_SYMC_BIT_WIDTH_128BIT, TD_TRUE}, +}; + +td_bool crypto_symc_support(crypto_symc_alg alg, crypto_symc_work_mode mode, crypto_symc_key_length key_len, + crypto_symc_bit_width bit_width) +{ + td_u32 i; + td_bool is_support = TD_FALSE; + for (i = 0; i < crypto_array_size(g_symc_alg_support); i++) { + if (g_symc_alg_support[i].alg == alg) { + is_support = g_symc_alg_support[i].is_support; + break; + } + } + for (i = 0; i < crypto_array_size(g_symc_alg_work_mode_support); i++) { + if (g_symc_alg_work_mode_support[i].mode == mode) { + is_support = (is_support && g_symc_alg_work_mode_support[i].is_support); + break; + } + } + for (i = 0; i < crypto_array_size(g_symc_alg_keylen_support); i++) { + if (g_symc_alg_keylen_support[i].key_len == key_len) { + is_support = (is_support && g_symc_alg_keylen_support[i].is_support); + break; + } + } + for (i = 0; i < crypto_array_size(g_symc_alg_bit_width_support); i++) { + if (g_symc_alg_bit_width_support[i].bit_width == bit_width) { + is_support = (is_support && g_symc_alg_bit_width_support[i].is_support); + break; + } + } + + return is_support; +} + +/* copy from/to user. */ +#if !defined(CRYPTO_COPY_XXX_USER_DEF) && (CRYPTO_ERROR_ENV != ERROR_ENV_NOOS) +td_s32 crypto_copy_from_user(td_void *to, unsigned long to_len, const td_void *from, unsigned long from_len) +{ + if (from_len == 0) { + return TD_SUCCESS; + } + + if (to == TD_NULL) { + crypto_log_err("to is NULL\n"); + return TD_FAILURE; + } + if (from == TD_NULL) { + crypto_log_err("from is NULL\n"); + return TD_FAILURE; + } + if (to_len < from_len) { + crypto_log_err("to_len is Less Than from_len!\n"); + return TD_FAILURE; + } + + return osal_copy_from_user(to, from, from_len); +} +td_s32 crypto_copy_to_user(td_void *to, unsigned long to_len, const td_void *from, unsigned long from_len) +{ + if (from_len == 0) { + return TD_SUCCESS; + } + if (to == TD_NULL) { + crypto_log_err("to is NULL\n"); + return TD_FAILURE; + } + if (from == TD_NULL) { + crypto_log_err("from is NULL\n"); + return TD_FAILURE; + } + if (to_len < from_len) { + crypto_log_err("to_len is Less Than from_len!\n"); + return TD_FAILURE; + } + + return osal_copy_to_user(to, from, from_len); +} +#endif + +#if defined(CONFIG_HEX_DATA_DUMP_ENABLE) +void crypto_dump_data(const char *name, const td_u8 *data, td_u32 data_len) +{ + td_u32 i; + crypto_unused(name); + crypto_unused(data); + if (data == TD_NULL) { + crypto_log_err("data is NULL\n"); + return; + } + + crypto_print("%s:\n", name); + data_len = data_len > MAX_DUMP_LENGHT ? MAX_DUMP_LENGHT : data_len; + for (i = 0; i < data_len; i++) { + if (i % BYTES_IN_ONE_LINE == 0) { + crypto_print("%04x: ", i); + } + crypto_print(KERN_CONT"%02x ", data[i]); + if ((i + 1) % BYTES_IN_ONE_LINE == 0) { + crypto_print("\n"); + } + } + if (data_len % BYTES_IN_ONE_LINE != 0) { + crypto_print("\n"); + } +} +#endif + +td_u32 crypto_get_value_by_index(const crypto_table_item *table, td_u32 table_size, + td_u32 index, td_u32 *value) +{ + const crypto_table_item *item = TD_NULL; + td_u32 i; + + crypto_chk_return(table == TD_NULL, TD_FAILURE, "table is NULL\n"); + crypto_chk_return(value == TD_NULL, TD_FAILURE, "value is NULL\n"); + + for (i = 0; i < table_size; i++) { + item = &table[i]; + if (item->index == index) { + *value = item->value; + return TD_SUCCESS; + } + } + crypto_log_err("Invalid Index!\n"); + return TD_FAILURE; +} + +td_u32 crypto_get_index_by_value(const crypto_table_item *table, td_u32 table_size, + td_u32 value, td_u32 *index) +{ + const crypto_table_item *item = TD_NULL; + td_u32 i; + + crypto_chk_return(table == TD_NULL, TD_FAILURE, "table is NULL\n"); + crypto_chk_return(index == TD_NULL, TD_FAILURE, "index is NULL\n"); + + for (i = 0; i < table_size; i++) { + item = &table[i]; + if (item->value == value) { + *index = item->index; + return TD_SUCCESS; + } + } + crypto_log_err("Invalid Value!\n"); + return TD_FAILURE; +} + +td_s32 __attribute__((weak)) crypto_virt_xor_phys_copy_to_phys(td_phys_addr_t dst_phys_addr, const td_u8 *a_virt_addr, + td_phys_addr_t b_phys_addr, td_u32 length) +{ + td_s32 ret; + td_u32 i; + td_u8 *b_virt_addr = TD_NULL; + td_u8 *dst_virt_addr = TD_NULL; + + b_virt_addr = crypto_ioremap_nocache(b_phys_addr, length); + crypto_chk_goto_with_ret(b_virt_addr == TD_NULL, exit, TD_FAILURE, "crypto_ioremap_nocache failed\n"); + + dst_virt_addr = crypto_ioremap_nocache(dst_phys_addr, length); + crypto_chk_goto_with_ret(dst_virt_addr == TD_NULL, exit, TD_FAILURE, "crypto_ioremap_nocache failed\n"); + +#if defined(CRYPTO_CTR_TRACE_ENABLE) + crypto_dump_data("a_virt_addr", a_virt_addr, length); + crypto_dump_data("b_virt_addr", b_virt_addr, length); +#endif + + for (i = 0; i < length; i++) { + dst_virt_addr[i] = a_virt_addr[i] ^ b_virt_addr[i]; + } + +#if defined(CRYPTO_CTR_TRACE_ENABLE) + crypto_dump_data("dst_virt_addr", dst_virt_addr, length); +#endif + ret = TD_SUCCESS; +exit: + if (b_virt_addr != TD_NULL) { + crypto_iounmap(b_virt_addr, length); + } + if (dst_virt_addr != TD_NULL) { + crypto_iounmap(dst_virt_addr, length); + } + return ret; +} + +td_s32 __attribute__((weak)) crypto_virt_copy_to_phys(td_phys_addr_t dst_phys_addr, + const td_u8 *src_virt_addr, td_u32 length) +{ + td_s32 ret; + td_u8 *dst_virt_addr = TD_NULL; + + dst_virt_addr = crypto_ioremap_nocache(dst_phys_addr, length); + crypto_chk_goto_with_ret(dst_virt_addr == TD_NULL, exit, TD_FAILURE, "crypto_ioremap_nocache failed\n"); + + ret = memcpy_s(dst_virt_addr, length, src_virt_addr, length); + crypto_chk_goto_with_ret(ret != EOK, exit, TD_FAILURE, "memcpy_s failed\n"); + + ret = TD_SUCCESS; +exit: + if (dst_virt_addr != TD_NULL) { + crypto_iounmap(dst_virt_addr, length); + } + return ret; +} + + +td_s32 __attribute__((weak)) crypto_phys_copy_to_virt(td_u8 *dst_virt_addr, + td_phys_addr_t src_phys_addr, td_u32 length) +{ + td_s32 ret; + td_u8 *src_virt_addr = TD_NULL; + + src_virt_addr = crypto_ioremap_nocache(src_phys_addr, length); + crypto_chk_goto_with_ret(src_virt_addr == TD_NULL, exit, TD_FAILURE, "crypto_ioremap_nocache failed\n"); + + ret = memcpy_s(dst_virt_addr, length, src_virt_addr, length); + crypto_chk_goto_with_ret(ret != EOK, exit, TD_FAILURE, "memcpy_s failed\n"); + + ret = TD_SUCCESS; +exit: + if (src_virt_addr != TD_NULL) { + crypto_iounmap(src_virt_addr, length); + } + return ret; +} + +unsigned int crypto_align(unsigned int original_length, unsigned int aligned_length) +{ + if (aligned_length == 0) { + return 0; + } + + if ((original_length % aligned_length) != 0) { + original_length += (aligned_length - original_length % aligned_length); + } + + return original_length; +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/crypto_drv_common.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/crypto_drv_common.h new file mode 100644 index 00000000..a65c7d84 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/crypto_drv_common.h @@ -0,0 +1,121 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef CRYPTO_DRV_COMMON_H +#define CRYPTO_DRV_COMMON_H + +#include "crypto_type.h" +#include "drv_common.h" +#include "crypto_osal_adapt.h" +#include "crypto_pke_struct.h" +#include "crypto_hash_struct.h" +#include "crypto_symc_struct.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +td_void *crypto_malloc_coherent(td_u32 size, td_char *buffer_name); + +td_void *crypto_malloc_mmz(td_u32 size, td_char *buffer_name); + +td_void crypto_free_coherent(td_void *ptr); + +td_phys_addr_t crypto_get_phys_addr(td_void *ptr); + +td_bool crypto_smmu_support(td_void); + +td_void crypto_get_smmu_table_addr(td_u64 *table, td_u64 *rdaddr, td_u64 *wraddr); + +crypto_cpu_type crypto_get_cpu_type(td_void); + +void crypto_cache_flush(uintptr_t base_addr, td_u32 size); + +void crypto_cache_inv(uintptr_t base_addr, td_u32 size); + +void crypto_cache_all(void); + +void crypto_dcache_enable(void); + +void crypto_dcache_disable(void); + +td_bool crypto_ecc_support(drv_pke_ecc_curve_type curve_type); + +td_bool crypto_rsa_support(td_u32 klen, drv_pke_rsa_scheme scheme); + +td_bool crypto_hash_support(crypto_hash_type hash_type); + +td_bool crypto_symc_support(crypto_symc_alg alg, crypto_symc_work_mode mode, crypto_symc_key_length key_len, + crypto_symc_bit_width bit_width); + +typedef enum { + CRYPTO_SM_ALG_SM2, + CRYPTO_SM_ALG_SM3, + CRYPTO_SM_ALG_SM4 +} crypto_sm_alg; + +td_bool crypto_sm_support(crypto_sm_alg alg); + +typedef struct { + const td_char *name; + td_u32 offset; +} reg_item_t; + +typedef td_u32 (*reg_read_func)(td_u32 offset); + +typedef enum { + TIMER_ID_0 = 0, + TIMER_ID_1, + TIMER_ID_2, + TIMER_ID_3, + TIMER_ID_4, + TIMER_ID_5, + TIMER_ID_6, + TIMER_ID_7, + TIMER_ID_8, + TIMER_ID_9, +} crypto_timer_id; +#if defined(CONFIG_CRYPTO_PERF_STATISTICS) +td_void crypto_timer_start(td_u32 timer_id, const td_char *name); + +td_u64 crypto_timer_end(td_u32 timer_id, const td_char *item_name); + +td_void crypto_timer_print(td_u32 timer_id); + +td_void crypto_timer_print_all(td_void); +#else +#define crypto_timer_start(...) +#define crypto_timer_end(...) +#define crypto_timer_print(...) +#define crypto_timer_print_all(...) +#endif + +typedef struct { + td_u32 index; + td_u32 value; +} crypto_table_item; + +td_u32 crypto_get_value_by_index(const crypto_table_item *table, td_u32 table_size, + td_u32 index, td_u32 *value); +td_u32 crypto_get_index_by_value(const crypto_table_item *table, td_u32 table_size, + td_u32 value, td_u32 *index); + +td_s32 crypto_virt_xor_phys_copy_to_phys(td_phys_addr_t dst_phys_addr, const td_u8 *a_virt_addr, + td_phys_addr_t b_phys_addr, td_u32 length); + +td_s32 crypto_virt_copy_to_phys(td_phys_addr_t dst_phys_addr, const td_u8 *src_virt_addr, td_u32 length); + +td_s32 crypto_phys_copy_to_virt(td_u8 *dst_virt_addr, td_phys_addr_t src_phys_addr, td_u32 length); + +unsigned int crypto_align(unsigned int original_length, unsigned int aligned_length); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/crypto_osal_adapt.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/crypto_osal_adapt.h new file mode 100644 index 00000000..78203993 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/crypto_osal_adapt.h @@ -0,0 +1,126 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef CRYPTO_OSAL_ADAPT_H +#define CRYPTO_OSAL_ADAPT_H + +#include "crypto_osal_lib.h" +#include "crypto_common_struct.h" + +/* Timer. */ +#ifndef crypto_msleep +#define crypto_msleep osal_msleep +#endif + +#ifndef crypto_udelay +#define crypto_udelay osal_udelay +#endif + +/* map. */ +#ifndef crypto_ioremap_nocache +#define crypto_ioremap_nocache osal_ioremap_nocache +#define crypto_iounmap osal_iounmap +#endif + +/* Mutex. */ +#ifndef crypto_mutex_init +#define crypto_mutex osal_mutex +#define crypto_mutex_init osal_mutex_init +#define crypto_mutex_destroy osal_mutex_destroy +#define crypto_mutex_lock osal_mutex_lock +#define crypto_mutex_unlock osal_mutex_unlock +#endif + +/* Log. */ +#ifndef crypto_print +#define crypto_print osal_printk +#endif + +#if !defined(CRYPTO_LOG_DEF) +#define crypto_log_fmt(LOG_LEVEL_LABEL, fmt, ...) \ + crypto_print("[%s:%d]" LOG_LEVEL_LABEL ": " fmt, __func__, __LINE__, ##__VA_ARGS__) + +#ifndef CRYPTO_LOG_LEVEL +#define CRYPTO_LOG_LEVEL 0 +#endif +#if defined(CRYPTO_LOG_LEVEL) && (CRYPTO_LOG_LEVEL == 0) +#define crypto_log_err(fmt, ...) crypto_log_fmt("ERROR", fmt, ##__VA_ARGS__) +#define crypto_log_warn(fmt, ...) +#define crypto_log_notice(fmt, ...) +#define crypto_log_dbg(fmt, ...) +#define crypto_log_trace(fmt, ...) +#elif defined(CRYPTO_LOG_LEVEL) && (CRYPTO_LOG_LEVEL == 1) +#define crypto_log_err(fmt, ...) crypto_log_fmt("ERROR", fmt, ##__VA_ARGS__) +#define crypto_log_warn(fmt, ...) crypto_log_fmt("WARN:", fmt, ##__VA_ARGS__) +#define crypto_log_notice(fmt, ...) +#define crypto_log_dbg(fmt, ...) +#define crypto_log_trace(fmt, ...) +#elif defined(CRYPTO_LOG_LEVEL) && (CRYPTO_LOG_LEVEL == 2) +#define crypto_log_err(fmt, ...) crypto_log_fmt("ERROR", fmt, ##__VA_ARGS__) +#define crypto_log_warn(fmt, ...) crypto_log_fmt("WARN:", fmt, ##__VA_ARGS__) +#define crypto_log_notice(fmt, ...) crypto_log_fmt("NOTICE", fmt, ##__VA_ARGS__) +#define crypto_log_dbg(fmt, ...) +#define crypto_log_trace(fmt, ...) +#elif defined(CRYPTO_LOG_LEVEL) && (CRYPTO_LOG_LEVEL == 3) +#define crypto_log_err(fmt, ...) crypto_log_fmt("ERROR", fmt, ##__VA_ARGS__) +#define crypto_log_warn(fmt, ...) crypto_log_fmt("WARN:", fmt, ##__VA_ARGS__) +#define crypto_log_notice(fmt, ...) crypto_log_fmt("NOTICE", fmt, ##__VA_ARGS__) +#define crypto_log_dbg(fmt, ...) crypto_log_fmt("DBG", fmt, ##__VA_ARGS__) +#define crypto_log_trace(fmt, ...) +#elif defined(CRYPTO_LOG_LEVEL) && (CRYPTO_LOG_LEVEL == 4) +#define crypto_log_err(fmt, ...) crypto_log_fmt("ERROR", fmt, ##__VA_ARGS__) +#define crypto_log_warn(fmt, ...) crypto_log_fmt("WARN:", fmt, ##__VA_ARGS__) +#define crypto_log_notice(fmt, ...) crypto_log_fmt("NOTICE", fmt, ##__VA_ARGS__) +#define crypto_log_dbg(fmt, ...) crypto_log_fmt("DBG", fmt, ##__VA_ARGS__) +#define crypto_log_trace(fmt, ...) crypto_log_fmt("TRACE", fmt, ##__VA_ARGS__) +#endif + +#endif + +/* Malloc. */ +#ifndef crypto_malloc +#define crypto_malloc(x) (((x) > 0) ? osal_kmalloc((x), OSAL_GFP_KERNEL) : TD_NULL) +#define crypto_free(x) {if (((x) != TD_NULL)) osal_kfree(x);} +#endif + +/* align check */ +#ifndef crypto_addr_align_check +#define crypto_addr_align_check(addr) ((((addr) % 4) != 0) ? TD_FALSE : TD_TRUE) +#endif + +/* ioctl_cmd. */ +#ifndef CRYPTO_IOCTL_CMD_DEF +#define crypto_ioctl_cmd osal_ioctl_cmd +#endif + +/* copy from/to user. */ +td_s32 crypto_copy_from_user(td_void *to, unsigned long to_len, const td_void *from, unsigned long from_len); +td_s32 crypto_copy_to_user(td_void *to, unsigned long to_len, const td_void *from, unsigned long from_len); + +/* crypto dump functions. */ +#if defined(CONFIG_HEX_DATA_DUMP_ENABLE) +void crypto_dump_data(const char *name, const td_u8 *data, td_u32 data_len); +#else +#define crypto_dump_data(...) +#endif +void crypto_dump_phys_addr(const char *name, const td_phys_addr_t phys_addr, td_u32 data_len); + +/* Check the Validation of but_attr. */ +td_bool crypto_data_buf_check(const crypto_buf_attr *buf_attr, td_u32 length); + +/* Crypto Owner Operation. */ +#if !defined(crypto_owner) && (CRYPTO_ERROR_ENV != ERROR_ENV_NOOS) +#define crypto_owner td_u32 +#define crypto_owner_dump(owner) crypto_log_dbg("Owner's pid is 0x%x\n", owner) +static inline td_s32 crypto_get_owner(crypto_owner *owner) +{ + if (owner == TD_NULL) { + return CRYPTO_FAILURE; + } + *owner = crypto_getpid(); + return CRYPTO_SUCCESS; +} +#endif + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_hash.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_hash.c new file mode 100644 index 00000000..4a08e672 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_hash.c @@ -0,0 +1,784 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "drv_hash.h" +#include "drv_inner.h" + +#include "hal_hash.h" + +#include "crypto_drv_common.h" + +#define CRYPTO_INVALID_CHN_NUM (0xFFFFFFFF) +#define HASH_COMPAT_ERRNO(err_code) DRV_COMPAT_ERRNO(ERROR_MODULE_HASH, err_code) +#define hash_null_ptr_chk(ptr) \ + crypto_chk_return((ptr) == TD_NULL, HASH_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), #ptr" is NULL\n") + +#define CRYPTO_DRV_HASH_MAX_DMA_SIZE (CRYPTO_HASH_DRV_BUFFER_SIZE * CRYPTO_HASH_HARD_CHN_CNT) +static td_u8 *g_drv_dma_buf = TD_NULL; + +typedef struct { + td_u32 length[2]; + td_u32 state[CRYPTO_HASH_RESULT_SIZE_MAX_IN_WORD]; + td_u8 o_key_pad[CRYPTO_HASH_BLOCK_SIZE_MAX]; + td_u8 i_key_pad[CRYPTO_HASH_BLOCK_SIZE_MAX]; + td_u8 tail[CRYPTO_HASH_BLOCK_SIZE_MAX]; + td_u32 tail_len; + td_u8 *data_buffer; + td_u32 data_buffer_len; +} crypto_hash_ctx; + +typedef struct { + td_bool open; + td_bool is_keyslot; + crypto_hash_type hash_type; + crypto_hash_ctx hash_ctx; +} hal_hash_channel_context; + +static hal_hash_channel_context g_hash_channel_ctx_list[CRYPTO_HASH_HARD_CHN_CNT]; + +// SHA-256, the initial hash value +static const td_u8 g_sha256_ival[32] = { + 0x6A, 0x09, 0xE6, 0x67, + 0xBB, 0x67, 0xAE, 0x85, + 0x3C, 0x6E, 0xF3, 0x72, + 0xA5, 0x4F, 0xF5, 0x3A, + 0x51, 0x0E, 0x52, 0x7F, + 0x9B, 0x05, 0x68, 0x8C, + 0x1F, 0x83, 0xD9, 0xAB, + 0x5B, 0xE0, 0xCD, 0x19 +}; + +// SHA-384, the initial hash value +static const td_u8 g_sha384_ival[64] = { + 0xCB, 0xBB, 0x9D, 0x5D, 0xC1, 0x05, 0x9E, 0xD8, + 0x62, 0x9A, 0x29, 0x2A, 0x36, 0x7C, 0xD5, 0x07, + 0x91, 0x59, 0x01, 0x5A, 0x30, 0x70, 0xDD, 0x17, + 0x15, 0x2F, 0xEC, 0xD8, 0xF7, 0x0E, 0x59, 0x39, + 0x67, 0x33, 0x26, 0x67, 0xFF, 0xC0, 0x0B, 0x31, + 0x8E, 0xB4, 0x4A, 0x87, 0x68, 0x58, 0x15, 0x11, + 0xDB, 0x0C, 0x2E, 0x0D, 0x64, 0xF9, 0x8F, 0xA7, + 0x47, 0xB5, 0x48, 0x1D, 0xBE, 0xFA, 0x4F, 0xA4 +}; + +// SHA-512, the initial hash value +static const td_u8 g_sha512_ival[64] = { + 0x6A, 0x09, 0xE6, 0x67, 0xF3, 0xBC, 0xC9, 0x08, + 0xBB, 0x67, 0xAE, 0x85, 0x84, 0xCA, 0xA7, 0x3B, + 0x3C, 0x6E, 0xF3, 0x72, 0xFE, 0x94, 0xF8, 0x2B, + 0xA5, 0x4F, 0xF5, 0x3A, 0x5F, 0x1D, 0x36, 0xF1, + 0x51, 0x0E, 0x52, 0x7F, 0xAD, 0xE6, 0x82, 0xD1, + 0x9B, 0x05, 0x68, 0x8C, 0x2B, 0x3E, 0x6C, 0x1F, + 0x1F, 0x83, 0xD9, 0xAB, 0xFB, 0x41, 0xBD, 0x6B, + 0x5B, 0xE0, 0xCD, 0x19, 0x13, 0x7E, 0x21, 0x79 +}; + +// SM3, the initial hash value +static const td_u8 g_sm3_ival[32] = { + 0x73, 0x80, 0x16, 0x6F, + 0x49, 0x14, 0xB2, 0xB9, + 0x17, 0x24, 0x42, 0xD7, + 0xDA, 0x8A, 0x06, 0x00, + 0xA9, 0x6F, 0x30, 0xBC, + 0x16, 0x31, 0x38, 0xAA, + 0xE3, 0x8D, 0xEE, 0x4D, + 0xB0, 0xFB, 0x0E, 0x4E +}; + +static td_void inner_drv_hash_length_add(td_u32 length[2], td_u32 addition) +{ + td_u32 diff = 0; + if (length[1] > length[1] + addition) { + length[0]++; + diff = 0xFFFFFFFF - length[1] + 1; + length[1] = addition - diff; + return; + } + length[1] += addition; +} + +static td_s32 drv_hash_get_state(crypto_hash_type hash_type, td_u32 *state, td_u32 state_size) +{ + td_s32 ret = TD_SUCCESS; + td_u32 hash_alg = CRYPTO_HASH_GET_ALG(hash_type); + td_u32 hash_mode = CRYPTO_HASH_GET_MODE(hash_type); + + switch (hash_mode) { + case CRYPTO_HASH_MODE_256: { + if (hash_alg == CRYPTO_HASH_ALG_SHA2) { + ret = memcpy_s(state, state_size, g_sha256_ival, sizeof(g_sha256_ival)); + crypto_chk_return(ret != EOK, HASH_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + } else if (hash_alg == CRYPTO_HASH_ALG_SM3) { + ret = memcpy_s(state, state_size, g_sm3_ival, sizeof(g_sm3_ival)); + crypto_chk_return(ret != EOK, HASH_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + } else { + crypto_log_err("Invalid Hash Alg!\n"); + ret = HASH_COMPAT_ERRNO(ERROR_INVALID_PARAM); + } + break; + } + case CRYPTO_HASH_MODE_384: { + ret = memcpy_s(state, state_size, g_sha384_ival, sizeof(g_sha384_ival)); + crypto_chk_return(ret != EOK, HASH_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + break; + } + case CRYPTO_HASH_MODE_512: { + ret = memcpy_s(state, state_size, g_sha512_ival, sizeof(g_sha512_ival)); + crypto_chk_return(ret != EOK, HASH_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + break; + } + default: { + crypto_log_err("Invalid Hash Mode!\n"); + ret = HASH_COMPAT_ERRNO(ERROR_INVALID_PARAM); + break; + } + } + return ret; +} + +td_s32 drv_cipher_hash_init(td_void) +{ + td_s32 ret = TD_SUCCESS; + + crypto_drv_func_enter(); + + ret = hal_cipher_hash_init(); + crypto_chk_return(ret != CRYPTO_SUCCESS, ret, "hal_cipher_hash_init failed\n"); + + g_drv_dma_buf = crypto_malloc_mmz(CRYPTO_DRV_HASH_MAX_DMA_SIZE, "cipher_hash_drv"); + if (g_drv_dma_buf == TD_NULL) { + crypto_log_err("crypto_malloc_mmz failed\n"); + hal_cipher_hash_deinit(); + return HASH_COMPAT_ERRNO(ERROR_MALLOC); + } + + crypto_drv_func_exit(); + return ret; +} + +td_s32 drv_cipher_hash_deinit(td_void) +{ + td_u32 i; + hal_hash_channel_context *ctx = TD_NULL; + crypto_drv_func_enter(); + + for (i = 0; i < CRYPTO_HASH_HARD_CHN_CNT; i++) { + ctx = &g_hash_channel_ctx_list[i]; + if (ctx->open == TD_FALSE) { + continue; + } + (td_void)drv_cipher_hash_destroy(i); + } + + if (g_drv_dma_buf != TD_NULL) { + (td_void)memset_s(g_drv_dma_buf, CRYPTO_DRV_HASH_MAX_DMA_SIZE, 0, CRYPTO_DRV_HASH_MAX_DMA_SIZE); + crypto_free_coherent(g_drv_dma_buf); + g_drv_dma_buf = TD_NULL; + } + hal_cipher_hash_deinit(); + crypto_drv_func_exit(); + return TD_SUCCESS; +} + +static td_s32 drv_hash_lock_chn(td_u32 *chn_num) +{ + td_u32 i; + td_s32 ret = TD_SUCCESS; + *chn_num = CRYPTO_INVALID_CHN_NUM; + /* Lock one free Hash Hard Channel. */ + for (i = 0; i < CRYPTO_HASH_HARD_CHN_CNT; i++) { + if (g_hash_channel_ctx_list[i].open == TD_TRUE) { + continue; + } + + ret = hal_hash_lock(i); + if (ret == TD_SUCCESS) { + *chn_num = i; + break; + } + } + + if (*chn_num == CRYPTO_INVALID_CHN_NUM) { + crypto_log_err("Hash Channel is Busy\n"); + return HASH_COMPAT_ERRNO(ERROR_CHN_BUSY); + } + return TD_SUCCESS; +} + +static td_s32 inner_drv_hmac_start(td_u32 chn_num, hal_hash_channel_context *ctx, const crypto_hash_attr *hash_attr) +{ + td_s32 ret = TD_SUCCESS; + td_u32 i; + td_u32 block_size = CRYPTO_HASH_GET_BLOCK_SIZE(hash_attr->hash_type) / CRYPTO_BITS_IN_BYTE; + if (hash_attr->key_len != 0) { + ret = memcpy_s(ctx->hash_ctx.tail, sizeof(ctx->hash_ctx.tail), hash_attr->key, hash_attr->key_len); + crypto_chk_return(ret != EOK, HASH_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + } + + /* Calc o_key_pad and i_key_pad */ + for (i = 0; i < block_size; i++) { + ctx->hash_ctx.o_key_pad[i] = 0x5c ^ ctx->hash_ctx.tail[i]; + ctx->hash_ctx.i_key_pad[i] = 0x36 ^ ctx->hash_ctx.tail[i]; + } + ret = memcpy_s(ctx->hash_ctx.data_buffer, ctx->hash_ctx.data_buffer_len, ctx->hash_ctx.i_key_pad, block_size); + crypto_chk_return(ret != EOK, HASH_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + inner_drv_hash_length_add(ctx->hash_ctx.length, block_size * CRYPTO_BITS_IN_BYTE); + + crypto_cache_flush((uintptr_t)ctx->hash_ctx.data_buffer, block_size); + ret = hal_cipher_hash_add_in_node(chn_num, crypto_get_phys_addr(ctx->hash_ctx.data_buffer), block_size, + IN_NODE_TYPE_FIRST | IN_NODE_TYPE_LAST); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_hash_add_in_node failed\n"); + + ret = hal_cipher_hash_start(chn_num, TD_FALSE); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_hash_start failed\n"); + + ret = hal_cipher_hash_wait_done(chn_num, ctx->hash_ctx.state, sizeof(ctx->hash_ctx.state)); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_hash_wait_done failed\n"); + + return ret; +} + +td_s32 drv_cipher_hash_start(td_handle *drv_hash_handle, const crypto_hash_attr *hash_attr) +{ + td_u32 chn_num = CRYPTO_INVALID_CHN_NUM; + td_s32 ret = TD_FAILURE; + hal_hash_channel_context *ctx = TD_NULL; + crypto_drv_func_enter(); + + ret = inner_hash_start_param_chk(drv_hash_handle, hash_attr); + if (ret != TD_SUCCESS) { + return ret; + } + crypto_chk_return(crypto_hash_support(hash_attr->hash_type) == TD_FALSE, HASH_COMPAT_ERRNO(ERROR_UNSUPPORT), + "alg is unsupport\n"); + if (hash_attr->hash_type == CRYPTO_HASH_TYPE_SM3 || hash_attr->hash_type == CRYPTO_HASH_TYPE_HMAC_SM3) { + crypto_chk_return(crypto_sm_support(CRYPTO_SM_ALG_SM3) == TD_FALSE, HASH_COMPAT_ERRNO(ERROR_UNSUPPORT), + "alg is unsupport\n"); + } + + /* Lock one free Hash Hard Channel. */ + ret = drv_hash_lock_chn(&chn_num); + if (ret != TD_SUCCESS) { + crypto_log_err("drv_hash_lock_chn failed\n"); + return ret; + } + crypto_chk_return(g_drv_dma_buf == TD_NULL, HASH_COMPAT_ERRNO(ERROR_UNEXPECTED), "g_drv_dma_buf == TD_NULL\n"); + ctx = &g_hash_channel_ctx_list[chn_num]; + (td_void)memset_s(ctx, sizeof(hal_hash_channel_context), 0, sizeof(hal_hash_channel_context)); + + /* Alloc data_buffer. */ + ctx->hash_ctx.data_buffer = g_drv_dma_buf + CRYPTO_HASH_DRV_BUFFER_SIZE * chn_num; + ctx->hash_ctx.data_buffer_len = CRYPTO_HASH_DRV_BUFFER_SIZE; + (td_void)memset_s(ctx->hash_ctx.data_buffer, ctx->hash_ctx.data_buffer_len, 0, ctx->hash_ctx.data_buffer_len); + ctx->hash_type = hash_attr->hash_type; + /* Set Config. */ + ret = drv_hash_get_state(hash_attr->hash_type, ctx->hash_ctx.state, sizeof(ctx->hash_ctx.state)); + crypto_chk_goto(ret != CRYPTO_SUCCESS, error_hash_unlock, "drv_hash_get_state failed\n"); + + ret = hal_cipher_hash_config(chn_num, hash_attr->hash_type, ctx->hash_ctx.state); + crypto_chk_goto(ret != CRYPTO_SUCCESS, error_hash_unlock, "hal_cipher_hash_config failed\n"); + + if (CRYPTO_HASH_IS_HMAC(hash_attr->hash_type) == TD_TRUE) { + if (hash_attr->is_keyslot) { + ret = hal_cipher_hash_attach(chn_num, hash_attr->drv_keyslot_handle); + crypto_chk_goto(ret != CRYPTO_SUCCESS, error_hash_unlock, "hal_cipher_hash_attach failed\n"); + } else { + ret = inner_drv_hmac_start(chn_num, ctx, hash_attr); + crypto_chk_goto(ret != TD_SUCCESS, error_hash_unlock, "inner_drv_hmac_start failed\n"); + } + ctx->is_keyslot = hash_attr->is_keyslot; + } + + *drv_hash_handle = chn_num; + ctx->open = TD_TRUE; + crypto_drv_func_exit(); + return ret; +error_hash_unlock: + (td_void)hal_hash_unlock(chn_num); + return ret; +} + +td_s32 drv_cipher_hash_update(td_handle drv_hash_handle, const crypto_buf_attr *src_buf, const td_u32 len) +{ + td_s32 ret = TD_SUCCESS; + td_u32 chn_num = (td_u32)drv_hash_handle; + hal_hash_channel_context *ctx = TD_NULL; + td_u32 tail_len = 0; + td_u32 *length = TD_NULL; + td_u32 block_size; + td_u32 processing_len = 0; + td_u32 processed_len = 0; + td_u8 *data_buffer = TD_NULL; + td_u32 left = 0; + in_node_type_e node_type = IN_NODE_TYPE_FIRST; + crypto_drv_func_enter(); + + hash_null_ptr_chk(src_buf); + hash_null_ptr_chk(src_buf->virt_addr); + crypto_chk_return(len == 0 || len > CRYPTO_HASH_UPDATE_MAX_LEN, HASH_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "len is invalid\n"); + + ret = inner_hash_drv_handle_chk(drv_hash_handle); + if (ret != TD_SUCCESS) { + return ret; + } + + ctx = &g_hash_channel_ctx_list[chn_num]; + crypto_chk_return(ctx->open == TD_FALSE, HASH_COMPAT_ERRNO(ERROR_CTX_CLOSED), "ctx is closed!\n"); + + data_buffer = ctx->hash_ctx.data_buffer; + crypto_chk_return(data_buffer == TD_NULL, HASH_COMPAT_ERRNO(ERROR_UNEXPECTED), "unexpected error\n"); + + left = len; + tail_len = ctx->hash_ctx.tail_len; + length = ctx->hash_ctx.length; + block_size = CRYPTO_HASH_GET_BLOCK_SIZE(ctx->hash_type) / CRYPTO_BITS_IN_BYTE; + if (ctx->is_keyslot == TD_FALSE) { + node_type |= IN_NODE_TYPE_LAST; + } + /* If the data can be saved to Tail, Update only copies the data. */ + if (tail_len + left < block_size) { + processing_len = left; + ret = memcpy_s(ctx->hash_ctx.tail + tail_len, sizeof(ctx->hash_ctx.tail) - tail_len, + src_buf->virt_addr, processing_len); + crypto_chk_return(ret != EOK, HASH_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + inner_drv_hash_length_add(length, processing_len * CRYPTO_BITS_IN_BYTE); + ctx->hash_ctx.tail_len += processing_len; + return TD_SUCCESS; + } + + /* Process the tail. */ + ret = memcpy_s(data_buffer, ctx->hash_ctx.data_buffer_len, ctx->hash_ctx.tail, tail_len); + crypto_chk_return(ret != EOK, HASH_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + processing_len = block_size - tail_len; + ret = memcpy_s(data_buffer + tail_len, ctx->hash_ctx.data_buffer_len - tail_len, + src_buf->virt_addr, processing_len); + crypto_chk_return(ret != EOK, HASH_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + crypto_cache_flush((uintptr_t)data_buffer, block_size); + ret = hal_cipher_hash_add_in_node(chn_num, crypto_get_phys_addr(data_buffer), block_size, node_type); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_hash_add_in_node failed\n"); + + ret = hal_cipher_hash_start(chn_num, TD_FALSE); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_hash_start failed\n"); + + ret = hal_cipher_hash_wait_done(chn_num, ctx->hash_ctx.state, sizeof(ctx->hash_ctx.state)); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_hash_wait_done failed\n"); + + left -= processing_len; + processed_len += processing_len; + ctx->hash_ctx.tail_len = 0; + + /* Process the Remain Data. */ + while (left >= block_size) { + if (left >= ctx->hash_ctx.data_buffer_len) { + processing_len = ctx->hash_ctx.data_buffer_len; + } else { + processing_len = left - left % block_size; + } + ret = memcpy_s(data_buffer, ctx->hash_ctx.data_buffer_len, (td_u8 *)src_buf->virt_addr + processed_len, + processing_len); + crypto_chk_return(ret != EOK, HASH_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + crypto_cache_flush((uintptr_t)data_buffer, processing_len); + ret = hal_cipher_hash_add_in_node(chn_num, crypto_get_phys_addr(data_buffer), processing_len, node_type); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_hash_add_in_node failed\n"); + + ret = hal_cipher_hash_start(chn_num, TD_TRUE); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_hash_start failed\n"); + + ret = hal_cipher_hash_wait_done(chn_num, ctx->hash_ctx.state, sizeof(ctx->hash_ctx.state)); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_hash_wait_done failed\n"); + + left -= processing_len; + processed_len += processing_len; + } + + if (left != 0) { + ret = memcpy_s(ctx->hash_ctx.tail, sizeof(ctx->hash_ctx.tail), (td_u8 *)src_buf->virt_addr + processed_len, + left); + crypto_chk_return(ret != EOK, HASH_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + } + ctx->hash_ctx.tail_len = left; + inner_drv_hash_length_add(length, len * CRYPTO_BITS_IN_BYTE); + crypto_drv_func_exit(); + return ret; +} + +static td_s32 drv_process_tail(td_u32 chn_num, hal_hash_channel_context *ctx) +{ + td_s32 ret = TD_SUCCESS; + td_u8 *buffer = ctx->hash_ctx.data_buffer; + td_u32 buffer_len = ctx->hash_ctx.data_buffer_len; + td_u32 tail_len = ctx->hash_ctx.tail_len; + td_u32 *length = ctx->hash_ctx.length; + td_u32 max_message_len = CRYPTO_HASH_GET_MESSAGE_LEN(ctx->hash_type) / CRYPTO_BITS_IN_BYTE; + td_u32 block_size = CRYPTO_HASH_GET_BLOCK_SIZE(ctx->hash_type) / CRYPTO_BITS_IN_BYTE; + td_u32 processing_len = 0; + + ret = memcpy_s(buffer, buffer_len, ctx->hash_ctx.tail, tail_len); + crypto_chk_return(ret != EOK, HASH_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + (td_void)memset_s(buffer + tail_len, ctx->hash_ctx.data_buffer_len - tail_len, + 0x00, ctx->hash_ctx.data_buffer_len - tail_len); + + if (tail_len + 1 + max_message_len > block_size) { + processing_len = block_size * 2; // in this case , we need 2 buffer + } else { + processing_len = block_size; + } + buffer[tail_len] = 0x80; + if (ctx->is_keyslot) { + inner_drv_hash_length_add(length, block_size * CRYPTO_BITS_IN_BYTE); + } + length[1] = crypto_cpu_to_be32(length[1]); + length[0] = crypto_cpu_to_be32(length[0]); + + ret = memcpy_s(buffer + processing_len - sizeof(ctx->hash_ctx.length), sizeof(ctx->hash_ctx.length), + length, sizeof(ctx->hash_ctx.length)); + crypto_chk_return(ret != EOK, HASH_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + crypto_cache_flush((uintptr_t)buffer, processing_len); + ret = hal_cipher_hash_add_in_node(chn_num, crypto_get_phys_addr(buffer), processing_len, + IN_NODE_TYPE_FIRST | IN_NODE_TYPE_LAST); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_hash_add_in_node failed\n"); + + ret = hal_cipher_hash_start(chn_num, TD_TRUE); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_hash_start failed\n"); + + ret = hal_cipher_hash_wait_done(chn_num, ctx->hash_ctx.state, sizeof(ctx->hash_ctx.state)); + if (ret != TD_SUCCESS) { + crypto_print("hal_cipher_hash_wait_done failed\n"); + return ret; + } + + return ret; +} + +static td_s32 drv_hmac_finish_process(td_u32 chn_num, hal_hash_channel_context *ctx, td_u8 *out, td_u32 out_len) +{ + td_s32 ret = TD_SUCCESS; + td_u8 *buffer = ctx->hash_ctx.data_buffer; + td_u32 buffer_len = ctx->hash_ctx.data_buffer_len; + td_u32 *length = ctx->hash_ctx.length; + td_u32 processed_len = 0; + td_u32 block_size = CRYPTO_HASH_GET_BLOCK_SIZE(ctx->hash_type) / 8; // 8 means 1 byte = 8 bits + + (td_void)memset_s(buffer, buffer_len, 0, buffer_len); + /* Copy o_key_pad */ + ret = memcpy_s(buffer, buffer_len, ctx->hash_ctx.o_key_pad, block_size); + crypto_chk_return(ret != EOK, HASH_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + processed_len += block_size; + + /* Copy hash. */ + ret = memcpy_s(buffer + processed_len, buffer_len - processed_len, out, out_len); + crypto_chk_return(ret != EOK, HASH_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + processed_len += out_len; + buffer[processed_len] = 0x80; + length[1] = crypto_cpu_to_be32(processed_len * 8); // 8 means 1 byte = 8 bits + ret = memcpy_s(buffer + 2 * block_size - sizeof(ctx->hash_ctx.length), // 2 block offset + sizeof(ctx->hash_ctx.length), length, sizeof(ctx->hash_ctx.length)); + crypto_chk_return(ret != EOK, HASH_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + ret = drv_hash_get_state(ctx->hash_type, ctx->hash_ctx.state, sizeof(ctx->hash_ctx.state)); + if (ret != TD_SUCCESS) { + crypto_log_err("drv_hash_get_state failed\n"); + return ret; + } + ret = hal_cipher_hash_config(chn_num, ctx->hash_type, ctx->hash_ctx.state); + if (ret != TD_SUCCESS) { + crypto_log_err("hal_cipher_hash_config failed\n"); + return ret; + } + + crypto_cache_flush((uintptr_t)buffer, 2 * block_size); // 2 block_size needed + ret = hal_cipher_hash_add_in_node(chn_num, crypto_get_phys_addr(buffer), 2 * block_size, // 2 block_size needed + IN_NODE_TYPE_FIRST | IN_NODE_TYPE_LAST); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_hash_add_in_node failed\n"); + + ret = hal_cipher_hash_start(chn_num, TD_TRUE); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_hash_start failed\n"); + + ret = hal_cipher_hash_wait_done(chn_num, ctx->hash_ctx.state, sizeof(ctx->hash_ctx.state)); + if (ret != TD_SUCCESS) { + crypto_print("hal_cipher_hash_wait_done failed\n"); + return ret; + } + + return ret; +} + +td_s32 drv_cipher_hash_finish(td_handle drv_hash_handle, td_u8 *out, td_u32 *out_len) +{ + td_u32 i; + td_s32 ret = TD_FAILURE; + td_u32 chn_num = (td_u32)drv_hash_handle; + hal_hash_channel_context *ctx = TD_NULL; + td_u32 result_size; + + crypto_drv_func_enter(); + + hash_null_ptr_chk(out); + hash_null_ptr_chk(out_len); + + ret = inner_hash_drv_handle_chk(drv_hash_handle); + if (ret != TD_SUCCESS) { + return ret; + } + + ctx = &g_hash_channel_ctx_list[chn_num]; + crypto_chk_return(ctx->open == TD_FALSE, HASH_COMPAT_ERRNO(ERROR_CTX_CLOSED), "ctx is closed!\n"); + + crypto_chk_return(ctx->hash_ctx.data_buffer == TD_NULL, HASH_COMPAT_ERRNO(ERROR_UNEXPECTED), "unexpected error\n"); + + result_size = CRYPTO_HASH_GET_RESULT_SIZE(ctx->hash_type) / CRYPTO_BITS_IN_BYTE; + crypto_chk_return(*out_len < result_size, HASH_COMPAT_ERRNO(ERROR_INVALID_PARAM), "out's size is not enough\n"); + + /* Process the Tail Data. */ + ret = drv_process_tail(chn_num, ctx); + crypto_chk_goto(ret != TD_SUCCESS, exit_hash_unlock, "drv_process_tail failed\n"); + + for (i = 0; i < result_size / CRYPTO_WORD_WIDTH; i++) { + (td_void)memcpy_s(&out[i * CRYPTO_WORD_WIDTH], sizeof(td_u32), &ctx->hash_ctx.state[i], sizeof(td_u32)); + } + + if (CRYPTO_HASH_IS_HMAC(ctx->hash_type) && ctx->is_keyslot == TD_FALSE) { + ret = drv_hmac_finish_process(chn_num, ctx, out, result_size); + crypto_chk_goto(ret != TD_SUCCESS, exit_hash_unlock, "drv_hmac_finish_process failed\n"); + for (i = 0; i < result_size / CRYPTO_WORD_WIDTH; i++) { + (td_void)memcpy_s(&out[i * CRYPTO_WORD_WIDTH], sizeof(td_u32), &ctx->hash_ctx.state[i], sizeof(td_u32)); + } + } + *out_len = result_size; +exit_hash_unlock: + hal_hash_unlock(chn_num); + (td_void)memset_s(ctx, sizeof(hal_hash_channel_context), 0, sizeof(hal_hash_channel_context)); + + crypto_drv_func_exit(); + return ret; +} + +td_s32 drv_cipher_hash_get(td_handle drv_hash_handle, crypto_hash_clone_ctx *hash_ctx) +{ + td_s32 ret = TD_SUCCESS; + td_u32 chn_num = (td_u32)drv_hash_handle; + hal_hash_channel_context *ctx = TD_NULL; + crypto_drv_func_enter(); + + hash_null_ptr_chk(hash_ctx); + ret = inner_hash_drv_handle_chk(drv_hash_handle); + if (ret != TD_SUCCESS) { + return ret; + } + + ctx = &g_hash_channel_ctx_list[chn_num]; + crypto_chk_return(ctx->open == TD_FALSE, HASH_COMPAT_ERRNO(ERROR_CTX_CLOSED), "ctx is closed!\n"); + + (td_void)memset_s(hash_ctx, sizeof(crypto_hash_clone_ctx), 0, sizeof(crypto_hash_clone_ctx)); + /* Clone Length. */ + ret = memcpy_s(hash_ctx->length, sizeof(hash_ctx->length), ctx->hash_ctx.length, sizeof(ctx->hash_ctx.length)); + crypto_chk_goto_with_ret(ret != EOK, error_clear_hash_ctx, HASH_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + /* Clone state. */ + ret = memcpy_s(hash_ctx->state, sizeof(hash_ctx->state), ctx->hash_ctx.state, sizeof(ctx->hash_ctx.state)); + crypto_chk_goto_with_ret(ret != EOK, error_clear_hash_ctx, HASH_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + /* Clone o_key_pad. */ + ret = memcpy_s(hash_ctx->o_key_pad, sizeof(hash_ctx->o_key_pad), + ctx->hash_ctx.o_key_pad, sizeof(ctx->hash_ctx.o_key_pad)); + crypto_chk_goto_with_ret(ret != EOK, error_clear_hash_ctx, HASH_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + /* Clone i_key_pad. */ + ret = memcpy_s(hash_ctx->i_key_pad, sizeof(hash_ctx->i_key_pad), + ctx->hash_ctx.i_key_pad, sizeof(ctx->hash_ctx.i_key_pad)); + crypto_chk_goto_with_ret(ret != EOK, error_clear_hash_ctx, HASH_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + /* Clone tail. */ + ret = memcpy_s(hash_ctx->tail, sizeof(hash_ctx->tail), ctx->hash_ctx.tail, ctx->hash_ctx.tail_len); + crypto_chk_goto_with_ret(ret != EOK, error_clear_hash_ctx, HASH_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + hash_ctx->tail_len = ctx->hash_ctx.tail_len; + + /* Clone Hash Type. */ + hash_ctx->hash_type = ctx->hash_type; + crypto_drv_func_exit(); + + return ret; +error_clear_hash_ctx: + (td_void)memset_s(hash_ctx, sizeof(crypto_hash_clone_ctx), 0, sizeof(crypto_hash_clone_ctx)); + return ret; +} + +td_s32 drv_cipher_hash_set(td_handle drv_hash_handle, const crypto_hash_clone_ctx *hash_ctx) +{ + td_s32 ret = TD_SUCCESS; + td_u32 chn_num = (td_u32)drv_hash_handle; + hal_hash_channel_context *ctx = TD_NULL; + crypto_drv_func_enter(); + + hash_null_ptr_chk(hash_ctx); + ret = inner_hash_drv_handle_chk(drv_hash_handle); + if (ret != TD_SUCCESS) { + return ret; + } + crypto_chk_return(g_drv_dma_buf == TD_NULL, HASH_COMPAT_ERRNO(ERROR_UNEXPECTED), "g_drv_dma_buf == TD_NULL\n"); + + ctx = &g_hash_channel_ctx_list[chn_num]; + crypto_chk_return(ctx->open == TD_FALSE, HASH_COMPAT_ERRNO(ERROR_CTX_CLOSED), "ctx is closed!\n"); + + /* Clone Length. */ + ret = memcpy_s(ctx->hash_ctx.length, sizeof(ctx->hash_ctx.length), hash_ctx->length, sizeof(hash_ctx->length)); + crypto_chk_goto_with_ret(ret != EOK, error_clear_hash_ctx, HASH_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + /* Clone state. */ + ret = memcpy_s(ctx->hash_ctx.state, sizeof(ctx->hash_ctx.state), hash_ctx->state, sizeof(hash_ctx->state)); + crypto_chk_goto_with_ret(ret != EOK, error_clear_hash_ctx, HASH_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + /* Clone o_key_pad. */ + ret = memcpy_s(ctx->hash_ctx.o_key_pad, sizeof(ctx->hash_ctx.o_key_pad), + hash_ctx->o_key_pad, sizeof(hash_ctx->o_key_pad)); + crypto_chk_goto_with_ret(ret != EOK, error_clear_hash_ctx, HASH_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + /* Clone i_key_pad. */ + ret = memcpy_s(ctx->hash_ctx.i_key_pad, sizeof(ctx->hash_ctx.i_key_pad), + hash_ctx->i_key_pad, sizeof(hash_ctx->i_key_pad)); + crypto_chk_goto_with_ret(ret != EOK, error_clear_hash_ctx, HASH_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + /* Clone tail. */ + ret = memcpy_s(ctx->hash_ctx.tail, sizeof(ctx->hash_ctx.tail), hash_ctx->tail, sizeof(hash_ctx->tail)); + crypto_chk_goto_with_ret(ret != EOK, error_clear_hash_ctx, HASH_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + ctx->hash_ctx.tail_len = hash_ctx->tail_len; + + /* Clone Hash Type. */ + ctx->hash_type = hash_ctx->hash_type; + + /* Set Hash Config. */ + ret = hal_cipher_hash_config(chn_num, ctx->hash_type, ctx->hash_ctx.state); + if (ret != TD_SUCCESS) { + crypto_print("hal_cipher_hash_config expected is 0x%x, real ret is 0x%x\n", TD_SUCCESS, ret); + goto error_clear_hash_ctx; + } + /* Set Data Buffer. */ + ctx->hash_ctx.data_buffer = g_drv_dma_buf + CRYPTO_HASH_DRV_BUFFER_SIZE * chn_num; + ctx->hash_ctx.data_buffer_len = CRYPTO_HASH_DRV_BUFFER_SIZE; + crypto_drv_func_exit(); + + return ret; +error_clear_hash_ctx: + (td_void)memset_s(ctx, sizeof(hal_hash_channel_context), 0, sizeof(hal_hash_channel_context)); + return ret; +} + +td_s32 drv_cipher_hash_destroy(td_handle drv_hash_handle) +{ + td_s32 ret = TD_SUCCESS; + td_u32 chn_num = (td_u32)drv_hash_handle; + hal_hash_channel_context *ctx = TD_NULL; + crypto_drv_func_enter(); + + ret = inner_hash_drv_handle_chk(drv_hash_handle); + if (ret != TD_SUCCESS) { + return ret; + } + ctx = &g_hash_channel_ctx_list[chn_num]; + crypto_chk_return(ctx->open == TD_FALSE, HASH_COMPAT_ERRNO(ERROR_CTX_CLOSED), "ctx is closed!\n"); + + hal_hash_unlock(chn_num); +#if defined(CRYPTO_DEBUG_ON) + crypto_print("Unlock Hash CHN %u success\n", chn_num); + hal_hash_debug(); +#endif + (td_void)memset_s(ctx, sizeof(hal_hash_channel_context), 0, sizeof(hal_hash_channel_context)); + crypto_drv_func_exit(); + return ret; +} + +td_u32 drv_hash_get_state_iv(crypto_hash_type hash_type, td_u32 *iv_size, td_u32 *state_iv, td_u32 state_iv_len) +{ + td_s32 ret = TD_SUCCESS; + td_u32 hash_alg = CRYPTO_HASH_GET_ALG(hash_type); + td_u32 hash_mode = CRYPTO_HASH_GET_MODE(hash_type); + + crypto_chk_return(iv_size == TD_NULL, TD_NULL, "iv_size is NULL!\n"); + + switch (hash_mode) { + case CRYPTO_HASH_MODE_256: { + if (hash_alg == CRYPTO_HASH_ALG_SHA2) { + ret = memcpy_s(state_iv, state_iv_len, g_sha256_ival, sizeof(g_sha256_ival)); + crypto_chk_return(ret != EOK, HASH_COMPAT_ERRNO(ERROR_MEMCPY_S), "MEMCPY_S FAILED\n"); + *iv_size = sizeof(g_sha256_ival); + } else if (hash_alg == CRYPTO_HASH_ALG_SM3) { + ret = memcpy_s(state_iv, state_iv_len, g_sm3_ival, sizeof(g_sm3_ival)); + crypto_chk_return(ret != EOK, HASH_COMPAT_ERRNO(ERROR_MEMCPY_S), "MEMCPY_S FAILED\n"); + *iv_size = sizeof(g_sm3_ival); + } + break; + } + case CRYPTO_HASH_MODE_384: { + ret = memcpy_s(state_iv, state_iv_len, g_sha384_ival, sizeof(g_sha384_ival)); + crypto_chk_return(ret != EOK, HASH_COMPAT_ERRNO(ERROR_MEMCPY_S), "MEMCPY_S FAILED\n"); + *iv_size = sizeof(g_sha384_ival); + break; + } + case CRYPTO_HASH_MODE_512: { + ret = memcpy_s(state_iv, state_iv_len, g_sha512_ival, sizeof(g_sha512_ival)); + crypto_chk_return(ret != EOK, HASH_COMPAT_ERRNO(ERROR_MEMCPY_S), "MEMCPY_S FAILED\n"); + *iv_size = sizeof(g_sha512_ival); + break; + } + default: { + crypto_log_err("Invalid Hash Mode!\n"); + return HASH_COMPAT_ERRNO(ERROR_INVALID_PARAM); + break; + } + } + return ret; +} + +td_s32 inner_hash_drv_handle_chk(td_handle hash_handle) +{ + td_u32 chn_num = (td_u32)hash_handle; + crypto_chk_return(chn_num >= CRYPTO_HASH_HARD_CHN_CNT, HASH_COMPAT_ERRNO(ERROR_INVALID_HANDLE), + "hash_handle is invalid\n"); + crypto_chk_return(((1 << chn_num) & CRYPTO_HASH_HARD_CHN_MASK) == 0, HASH_COMPAT_ERRNO(ERROR_INVALID_HANDLE), + "hash_handle is invalid\n"); + + return TD_SUCCESS; +} + +td_s32 inner_hash_start_param_chk(td_handle *drv_hash_handle, const crypto_hash_attr *hash_attr) +{ + crypto_hash_type type; + td_u32 block_size = 0; + + hash_null_ptr_chk(drv_hash_handle); + hash_null_ptr_chk(hash_attr); + + type = hash_attr->hash_type; + crypto_chk_return(type != CRYPTO_HASH_TYPE_SHA256 && type != CRYPTO_HASH_TYPE_SHA384 && + type != CRYPTO_HASH_TYPE_SHA512 && type != CRYPTO_HASH_TYPE_SM3 && + type != CRYPTO_HASH_TYPE_HMAC_SHA256 && type != CRYPTO_HASH_TYPE_HMAC_SHA384 && + type != CRYPTO_HASH_TYPE_HMAC_SHA512 && type != CRYPTO_HASH_TYPE_HMAC_SM3, + HASH_COMPAT_ERRNO(ERROR_INVALID_PARAM), "hash_type is invalid!\n"); + + if (CRYPTO_HASH_IS_HMAC(type) != TD_TRUE) { + return TD_SUCCESS; + } + + /* HMAC Check. */ + block_size = CRYPTO_HASH_GET_BLOCK_SIZE(type) / CRYPTO_BITS_IN_BYTE; + if (hash_attr->is_keyslot == TD_TRUE) { + } else { + if (hash_attr->key_len != 0) { + crypto_chk_return(hash_attr->key == TD_NULL, HASH_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "key is NULL\n"); + } + crypto_chk_return(hash_attr->key_len > block_size, HASH_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "key_len shouldn't larget than block_size\n"); + } + return TD_SUCCESS; +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_inner.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_inner.h new file mode 100644 index 00000000..cece82af --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_inner.h @@ -0,0 +1,129 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef DRV_INNER_H +#define DRV_INNER_H + +#include "crypto_hash_struct.h" +#include "crypto_kdf_struct.h" +#include "crypto_symc_struct.h" +#include "crypto_pke_struct.h" + +typedef struct { + td_u8 mac[CRYPTO_IV_LEN_IN_BYTES]; + td_u32 mac_length; + td_u8 tail[CRYPTO_IV_LEN_IN_BYTES]; + td_u32 tail_length; +} crypto_symc_mac_ctx; + +typedef struct { + td_u8 iv[CRYPTO_IV_LEN_IN_BYTES]; + td_u32 iv_length; + td_u32 chn_num; + td_phys_addr_t aad_phys; + td_u8 *aad_virt; + td_u32 aad_len; + crypto_symc_alg symc_alg; + crypto_symc_work_mode work_mode; + crypto_symc_key_length symc_key_length; + td_u32 last_pattern_len; + union { + crypto_symc_config_aes_ccm_gcm ccm_config; + } param; + /* + * For CBC_MAC, store data copy; + * For CCM, store N + ccm_header + ccm_padding + * For GCM, store aad_padding + clen + */ + td_u8 *dma_addr; + td_u32 dma_size; + td_u32 data_len; /* For CCM/GCM. */ + td_u32 processed_len; /* For CCM/GCM. */ + td_u8 tail[CRYPTO_AES_BLOCK_SIZE_IN_BYTES]; + td_u32 tail_length; + td_bool is_create_keyslot; + td_handle keyslot_handle; + td_bool is_open; + td_bool is_config; + td_bool is_attached; + td_u32 iv_change_flag; +#if defined(CRYPTO_CTR_NON_ALIGN_SUPPORT) + td_u32 ctr_offset; + td_u32 ctr_used; + td_u8 ctr_last_block[CRYPTO_AES_BLOCK_SIZE_IN_BYTES]; +#endif +} drv_symc_context_t; + + +td_s32 drv_cipher_pke_clean_ram(void); + +td_s32 drv_cipher_pke_add_mod(const drv_pke_data *a, const drv_pke_data *b, + const drv_pke_data *p, const drv_pke_data *c); + +td_s32 drv_cipher_pke_sub_mod(const drv_pke_data *a, const drv_pke_data *b, + const drv_pke_data *p, const drv_pke_data *c); + +td_s32 drv_cipher_pke_mul_dot(const drv_pke_ecc_curve *ecc, const drv_pke_data *k, const drv_pke_ecc_point *p, + const drv_pke_ecc_point *r); + +td_s32 drv_cipher_pke_mul_mod(const drv_pke_data *a, const drv_pke_data *b, const drv_pke_data *p, + const drv_pke_data *c); + +td_s32 drv_cipher_pke_inv_mod(const drv_pke_data *a, const drv_pke_data *p, drv_pke_data *c); + +td_s32 drv_cipher_pke_add_dot(const drv_pke_ecc_curve *ecc, const drv_pke_ecc_point *s, const drv_pke_ecc_point *r, + const drv_pke_ecc_point *c); + +td_s32 drv_cipher_pke_mg_mul_dot(const drv_pke_data *k, const drv_pke_data *U, const drv_pke_data *p, + const drv_pke_data *a24, const drv_pke_data *rx); + +td_s32 drv_cipher_pke_ed_mul_dot(const drv_pke_data *k, const drv_pke_ecc_point *U, const drv_pke_data *p, + const drv_pke_ecc_point *r); + +td_s32 drv_cipher_pke_ed_add_dot(const drv_pke_ecc_curve *ecc, const drv_pke_ecc_point *s, + const drv_pke_ecc_point *r, const drv_pke_ecc_point *c); + +td_s32 drv_cipher_pke_calc_hash(const drv_pke_data* arr, td_u32 arr_len, const drv_pke_hash_type hash_type, + drv_pke_data *hash); + +drv_symc_context_t *inner_get_symc_ctx(td_handle symc_handle); + +td_u32 drv_hash_get_state_iv(crypto_hash_type hash_type, td_u32 *iv_size, td_u32 *state_iv, td_u32 state_iv_len); + +td_s32 inner_hash_drv_handle_chk(td_handle hash_handle); + +td_s32 inner_hash_start_param_chk(td_handle *drv_hash_handle, const crypto_hash_attr *hash_attr); + +td_s32 inner_drv_symc_crypto_chk(td_handle symc_handle, const crypto_buf_attr *src_buf, + const crypto_buf_attr *dst_buf, td_u32 length); + +td_s32 inner_symc_drv_handle_chk(td_handle symc_handle); + +td_s32 inner_drv_get_mac_ctx(td_handle symc_handle, crypto_symc_mac_ctx *mac_ctx); + +td_s32 inner_drv_set_mac_ctx(td_handle symc_handle, const crypto_symc_mac_ctx *mac_ctx); + +td_s32 inner_symc_cfg_param_check(const crypto_symc_ctrl_t *symc_ctrl); + +typedef struct { + td_u8 *iv0; + td_u32 iv0_length; + td_u8 *iv_mac; + td_u32 iv_mac_length; + td_u32 data_length; + td_u32 processed_length; + td_u32 aad_len; +} drv_symc_ex_context_t; + +td_s32 inner_drv_symc_get_iv0(td_handle symc_handle, td_u8 *iv0, td_u32 iv0_length); + +td_s32 inner_drv_symc_get_iv_mac(td_handle symc_handle, td_u8 *iv_mac, td_u32 iv_mac_length); + +td_s32 inner_drv_symc_ex_restore(td_handle symc_handle, const drv_symc_ex_context_t *symc_ex_ctx); + +td_s32 inner_drv_symc_set_ctr_block(td_handle symc_handle, const td_u8 *block, td_u32 block_size, td_u32 ctr_offset); + +td_s32 inner_drv_symc_get_ctr_block(td_handle symc_handle, td_u8 *block, td_u32 block_size, td_u32 *ctr_offset); + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_keyslot.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_keyslot.c new file mode 100644 index 00000000..baf81bb4 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_keyslot.c @@ -0,0 +1,72 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "drv_keyslot.h" +#include "hal_keyslot.h" + +#include "crypto_drv_common.h" +#include "crypto_common_macro.h" + +#define EXT_ID_KM 0x55 + +#define id_2_handle(id, key) \ + (td_handle)((((EXT_ID_KM) & 0xff) << 24) | ((((key) & 0xff)<< 16)) | (((id) & 0xffff))) +#define handle_2_modid(handle) (((handle) >> 24) & 0xff) +#define handle_2_id(handle) (((handle)) & 0xffff) +#define handle_get_type(handle) (((handle) >> 16) & 0xff) + +#define KEYSLOT_MCIPHER_KEYSLOT_CNT 8 +#define KEYSLOT_HMAC_KEYSLOT_CNT 2 + +#define KM_COMPAT_ERRNO(err_code) DRV_COMPAT_ERRNO(ERROR_MODULE_KM, err_code) +#define km_null_ptr_chk(ptr) \ + crypto_chk_return((ptr) == TD_NULL, KM_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), #ptr" is NULL\n") + +td_s32 drv_keyslot_init(td_void) +{ + return TD_SUCCESS; +} + +td_s32 drv_keyslot_deinit(td_void) +{ + return TD_SUCCESS; +} + +td_s32 drv_keyslot_create(td_handle *keyslot_handle, crypto_keyslot_type keyslot_type) +{ + volatile td_s32 ret = TD_FAILURE; + td_u32 i; + td_u32 keyslot_cnt = 0; + km_null_ptr_chk(keyslot_handle); + + if (keyslot_type == CRYPTO_KEYSLOT_TYPE_MCIPHER) { + keyslot_cnt = KEYSLOT_MCIPHER_KEYSLOT_CNT; + } else if (keyslot_type == CRYPTO_KEYSLOT_TYPE_HMAC) { + keyslot_cnt = KEYSLOT_HMAC_KEYSLOT_CNT; + } else { + crypto_log_err("invalid keyslot_type\n"); + return KM_COMPAT_ERRNO(ERROR_INVALID_PARAM); + } + + for (i = 0; i < keyslot_cnt; i++) { + ret = hal_keyslot_lock(i, keyslot_type); + if (ret == TD_SUCCESS) { + break; + } + } + if (i >= keyslot_cnt) { + crypto_log_err("all keyslot channels are busy\n"); + return KM_COMPAT_ERRNO(ERROR_CHN_BUSY); + } + + *keyslot_handle = id_2_handle(i, (td_u32)keyslot_type); + return ret; +} + +td_s32 drv_keyslot_destroy(td_handle keyslot_handle) +{ + crypto_keyslot_type keyslot_type_get = handle_get_type(keyslot_handle); + + return hal_keyslot_unlock(handle_2_id(keyslot_handle), keyslot_type_get); +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_klad.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_klad.c new file mode 100644 index 00000000..7534faa5 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_klad.c @@ -0,0 +1,302 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "drv_klad.h" + +#include "crypto_drv_common.h" +#include "crypto_common_macro.h" + +#include "hal_klad.h" +#include "hal_rkp.h" + +#define KM_COMPAT_ERRNO(err_code) DRV_COMPAT_ERRNO(ERROR_MODULE_KM, err_code) +#define km_null_ptr_chk(ptr) \ + crypto_chk_return((ptr) == TD_NULL, KM_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), #ptr" is NULL\n") + +typedef struct { + crypto_kdf_hard_key_type hard_key_type; + crypto_klad_dest klad_dest; + crypto_klad_attr klad_attr; + td_handle keyslot_handle; + td_u32 rkp_sw_cfg; + td_bool is_open; + td_bool is_attached; + td_bool is_set_attr; + td_bool is_set_key; + td_bool is_set_session_key; + crypto_klad_session_key session_key; +} drv_klad_context; + +static drv_klad_context g_klad_ctx = {0}; + +#define KLAD_VALID_HANDLE 0x2D3C4B5A + +td_s32 drv_klad_create(td_handle *klad_handle) +{ + crypto_drv_func_enter(); + + km_null_ptr_chk(klad_handle); + + (td_void)memset_s(&g_klad_ctx, sizeof(drv_klad_context), 0, sizeof(drv_klad_context)); + + g_klad_ctx.is_open = TD_TRUE; + + *klad_handle = KLAD_VALID_HANDLE; + crypto_drv_func_enter(); + return TD_SUCCESS; +} + +td_s32 drv_klad_destroy(td_handle klad_handle) +{ + crypto_drv_func_enter(); + + crypto_chk_return(klad_handle != KLAD_VALID_HANDLE, KM_COMPAT_ERRNO(ERROR_INVALID_HANDLE), "invalid klad_handle\n"); + if (g_klad_ctx.is_open == TD_FALSE) { + return TD_SUCCESS; + } + (td_void)memset_s(&g_klad_ctx, sizeof(drv_klad_context), 0, sizeof(drv_klad_context)); + + crypto_drv_func_enter(); + return TD_SUCCESS; +} + +td_s32 drv_klad_attach(td_handle klad_handle, crypto_klad_dest klad_dest, td_handle keyslot_handle) +{ + volatile td_s32 ret = TD_FAILURE; + crypto_klad_flash_key_type flash_key_type = CRYPTO_KLAD_FLASH_KEY_TYPE_INVALID; + crypto_drv_func_enter(); + + crypto_chk_return(klad_handle != KLAD_VALID_HANDLE, KM_COMPAT_ERRNO(ERROR_INVALID_HANDLE), "invalid klad_handle\n"); + crypto_chk_return(g_klad_ctx.is_open == TD_FALSE, KM_COMPAT_ERRNO(ERROR_CTX_CLOSED), "call create first\n"); + + if (klad_dest == CRYPTO_KLAD_DEST_FLASH) { + flash_key_type = (crypto_klad_flash_key_type)keyslot_handle; + } else if (klad_dest == CRYPTO_KLAD_DEST_MCIPHER || klad_dest == CRYPTO_KLAD_DEST_HMAC) { + ret = hal_klad_set_key_addr(klad_dest, keyslot_handle); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_klad_set_key_addr failed\n"); + } else if (klad_dest == CRYPTO_KLAD_DEST_NPU) { + ret = hal_klad_set_key_addr(klad_dest, keyslot_handle); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_klad_set_key_addr failed\n"); + } else { + crypto_log_err("invalid klad_dest\n"); + return KM_COMPAT_ERRNO(ERROR_INVALID_PARAM); + } + + ret = hal_klad_set_key_dest_cfg(klad_dest, flash_key_type); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_klad_set_key_dest_cfg failed\n"); + + g_klad_ctx.keyslot_handle = keyslot_handle; + g_klad_ctx.klad_dest = klad_dest; + g_klad_ctx.is_attached = TD_TRUE; + crypto_drv_func_enter(); + return ret; +} + +td_s32 drv_klad_detach(td_handle klad_handle, crypto_klad_dest klad_dest, td_handle keyslot_handle) +{ + crypto_unused(keyslot_handle); + crypto_chk_return(klad_handle != KLAD_VALID_HANDLE, KM_COMPAT_ERRNO(ERROR_INVALID_HANDLE), "invalid klad_handle\n"); + crypto_chk_return(g_klad_ctx.is_open == TD_FALSE, KM_COMPAT_ERRNO(ERROR_CTX_CLOSED), "call create first\n"); + crypto_chk_return(g_klad_ctx.klad_dest != klad_dest, KM_COMPAT_ERRNO(ERROR_INVALID_PARAM), "invalid klad_dest\n"); + crypto_chk_return(g_klad_ctx.keyslot_handle != keyslot_handle, KM_COMPAT_ERRNO(ERROR_INVALID_HANDLE), + "invalid keyslot_handle\n"); + + if (g_klad_ctx.is_attached == TD_FALSE) { + return TD_SUCCESS; + } + + g_klad_ctx.is_attached = TD_FALSE; + g_klad_ctx.keyslot_handle = 0; + g_klad_ctx.klad_dest = 0; + + return TD_SUCCESS; +} + +td_s32 drv_klad_set_attr(td_handle klad_handle, const crypto_klad_attr *klad_attr) +{ + volatile td_s32 ret = TD_FAILURE; + const crypto_klad_key_config *key_cfg = TD_NULL; + const crypto_klad_key_secure_config *key_sec_cfg = TD_NULL; + crypto_drv_func_enter(); + + km_null_ptr_chk(klad_attr); + crypto_chk_return(klad_handle != KLAD_VALID_HANDLE, KM_COMPAT_ERRNO(ERROR_INVALID_HANDLE), "invalid klad_handle\n"); + crypto_chk_return(g_klad_ctx.is_open == TD_FALSE, KM_COMPAT_ERRNO(ERROR_CTX_CLOSED), "call create first\n"); + + ret = memcpy_s(&g_klad_ctx.klad_attr, sizeof(crypto_klad_attr), klad_attr, sizeof(crypto_klad_attr)); + crypto_chk_return(ret != EOK, KM_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + key_cfg = &(klad_attr->key_cfg); + key_sec_cfg = &(klad_attr->key_sec_cfg); + + ret = hal_klad_set_key_crypto_cfg(key_cfg->encrypt_support, key_cfg->decrypt_support, key_cfg->engine); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_klad_set_key_crypto_cfg failed\n"); + + ret = hal_klad_set_key_secure_cfg(key_sec_cfg); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_klad_set_key_secure_cfg failed\n"); + + g_klad_ctx.hard_key_type = klad_attr->klad_cfg.rootkey_type; + g_klad_ctx.is_set_attr = TD_TRUE; + g_klad_ctx.rkp_sw_cfg = klad_attr->rkp_sw_cfg; + + crypto_drv_func_enter(); + return ret; +} + +td_s32 drv_klad_get_attr(td_handle klad_handle, crypto_klad_attr *klad_attr) +{ + volatile td_s32 ret = TD_FAILURE; + crypto_drv_func_enter(); + + km_null_ptr_chk(klad_attr); + crypto_chk_return(klad_handle != KLAD_VALID_HANDLE, KM_COMPAT_ERRNO(ERROR_INVALID_HANDLE), "invalid klad_handle\n"); + crypto_chk_return(g_klad_ctx.is_open == TD_FALSE, KM_COMPAT_ERRNO(ERROR_CTX_CLOSED), "call create first\n"); + crypto_chk_return(g_klad_ctx.is_set_attr == TD_FALSE, KM_COMPAT_ERRNO(ERROR_NOT_SET_CONFIG), + "call set_attr first\n"); + + ret = memcpy_s(klad_attr, sizeof(crypto_klad_attr), &g_klad_ctx.klad_attr, sizeof(crypto_klad_attr)); + crypto_chk_return(ret != EOK, KM_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + crypto_drv_func_enter(); + return ret; +} + +td_s32 drv_klad_set_clear_key(td_handle klad_handle, const crypto_klad_clear_key *clear_key) +{ + volatile td_s32 ret = TD_FAILURE; + crypto_drv_func_enter(); + + crypto_chk_return(klad_handle != KLAD_VALID_HANDLE, KM_COMPAT_ERRNO(ERROR_INVALID_HANDLE), "invalid klad_handle\n"); + km_null_ptr_chk(clear_key); + km_null_ptr_chk(clear_key->key); + + crypto_chk_return(g_klad_ctx.is_open == TD_FALSE, KM_COMPAT_ERRNO(ERROR_CTX_CLOSED), "call create first\n"); + crypto_chk_return(g_klad_ctx.is_set_attr == TD_FALSE, KM_COMPAT_ERRNO(ERROR_NOT_SET_CONFIG), + "call set_attr first\n"); + + ret = hal_klad_start_clr_route(g_klad_ctx.klad_dest, clear_key); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_klad_start_clr_route failed\n"); + + g_klad_ctx.is_set_key = TD_TRUE; + + crypto_drv_func_enter(); + return ret; +} + +td_s32 drv_klad_set_session_key(td_handle klad_handle, const crypto_klad_session_key *session_key) +{ + volatile td_s32 ret = TD_FAILURE; + crypto_drv_func_enter(); + + crypto_chk_return(klad_handle != KLAD_VALID_HANDLE, KM_COMPAT_ERRNO(ERROR_INVALID_HANDLE), "invalid klad_handle\n"); + km_null_ptr_chk(session_key); + + ret = memcpy_s(&g_klad_ctx.session_key, sizeof (crypto_klad_session_key), + session_key, sizeof(crypto_klad_session_key)); + crypto_chk_return(ret != EOK, KM_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + g_klad_ctx.is_set_session_key = TD_TRUE; + + crypto_drv_func_enter(); + return 0; +} + +static td_s32 inner_drv_set_content_key(const crypto_klad_content_key *content_key) +{ + volatile td_s32 ret = TD_FAILURE; + td_bool is_odd = content_key->key_parity; + crypto_klad_key_size key_size = CRYPTO_KLAD_KEY_SIZE_128BIT; + + /* set session key. */ + ret = hal_klad_set_data(g_klad_ctx.session_key.key, CRYPTO_128_KEY_LEN); + crypto_chk_goto(ret != TD_SUCCESS, exit_clean, "hal_klad_set_data failed\n"); + + ret = hal_klad_com_start(CRYPTO_KLAD_LEVEL_SEL_FIRST, g_klad_ctx.session_key.alg, + CRYPTO_KLAD_KEY_SIZE_128BIT, g_klad_ctx.hard_key_type); + crypto_chk_goto(ret != TD_SUCCESS, exit_clean, "hal_klad_com_start failed\n"); + + ret = hal_klad_wait_com_route_done(); + crypto_chk_goto(ret != TD_SUCCESS, exit_clean, "hal_klad_wait_com_route_done failed\n"); + + /* + * For MCipher: + * If key_length is 16, the key_parity is passed by caller; + * If key_length is 32, the high 128bit's key_parity is even, + the low 128bit's key_parity is odd. + */ + if (content_key->key_length == CRYPTO_256_KEY_LEN) { + is_odd = TD_FALSE; + key_size = CRYPTO_KLAD_KEY_SIZE_256BIT; + } + /* config the high 128bit */ + if (g_klad_ctx.klad_dest == CRYPTO_KLAD_DEST_MCIPHER) { + hal_klad_set_key_odd(is_odd); + } + + ret = hal_klad_set_data(content_key->key, CRYPTO_128_KEY_LEN); + crypto_chk_goto(ret != TD_SUCCESS, exit_clean, "hal_klad_set_data failed\n"); + + ret = hal_klad_com_start(CRYPTO_KLAD_LEVEL_SEL_SECOND, g_klad_ctx.session_key.alg, + key_size, g_klad_ctx.hard_key_type); + crypto_chk_goto(ret != TD_SUCCESS, exit_clean, "hal_klad_com_start failed\n"); + + ret = hal_klad_wait_com_route_done(); + crypto_chk_goto(ret != TD_SUCCESS, exit_clean, "hal_klad_wait_com_route_done failed\n"); + + /* config the low 128bit */ + if (content_key->key_length == CRYPTO_256_KEY_LEN) { + if (g_klad_ctx.klad_dest == CRYPTO_KLAD_DEST_MCIPHER) { + hal_klad_set_key_odd(TD_TRUE); + } + ret = hal_klad_set_data(content_key->key + CRYPTO_128_KEY_LEN, CRYPTO_128_KEY_LEN); + crypto_chk_goto(ret != TD_SUCCESS, exit_clean, "hal_klad_set_data failed\n"); + + ret = hal_klad_com_start(CRYPTO_KLAD_LEVEL_SEL_SECOND, g_klad_ctx.session_key.alg, + key_size, g_klad_ctx.hard_key_type); + crypto_chk_goto(ret != TD_SUCCESS, exit_clean, "hal_klad_com_start failed\n"); + + ret = hal_klad_wait_com_route_done(); + crypto_chk_goto(ret != TD_SUCCESS, exit_clean, "hal_klad_wait_com_route_done failed\n"); + } +exit_clean: + hal_klad_clear_data(); + return ret; +} + +td_s32 drv_klad_set_content_key(const td_handle klad_handle, const crypto_klad_content_key *content_key) +{ + volatile td_s32 ret = TD_FAILURE; + crypto_kdf_hard_calc_param param = {0}; + (td_void)(klad_handle); + + km_null_ptr_chk(content_key); + crypto_chk_return(content_key->key_length != CRYPTO_128_KEY_LEN && content_key->key_length != CRYPTO_256_KEY_LEN, + KM_COMPAT_ERRNO(ERROR_INVALID_PARAM), "invalid key_length\n"); + + (td_void)memset_s(¶m, sizeof(crypto_kdf_hard_calc_param), 0, sizeof(crypto_kdf_hard_calc_param)); + + /* lock klad */ + ret = hal_klad_lock(); + crypto_chk_return((ret != TD_SUCCESS), ret, "hal_klad_lock failed, ret is 0x%x\n", ret); + + /* lock rkp */ + ret = hal_rkp_lock(); + crypto_chk_goto((ret != TD_SUCCESS), exit_klad_unlock, "hal_rkp_lock failed, ret is 0x%x\n", ret); + + param.hard_key_type = g_klad_ctx.hard_key_type; + param.hard_alg = CRYPTO_KDF_HARD_ALG_SHA256; /* default is SHA256. */ + param.rkp_sw_cfg = g_klad_ctx.rkp_sw_cfg; + + ret = hal_rkp_kdf_hard_calculation(¶m); + crypto_chk_goto(ret != TD_SUCCESS, exit_rkp_unlock, "hal_rkp_kdf_hard_calculation failed\n"); + + ret = inner_drv_set_content_key(content_key); + crypto_chk_goto(ret != TD_SUCCESS, exit_rkp_unlock, "inner_drv_set_content_key failed\n"); + +exit_rkp_unlock: + hal_rkp_unlock(); +exit_klad_unlock: + hal_klad_unlock(); + return ret; +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_otp.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_otp.c new file mode 100644 index 00000000..924bec45 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_otp.c @@ -0,0 +1,244 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "drv_otp.h" + +#include "crypto_osal_lib.h" +#include "otpc_register.h" +#include "ca_misc_register.h" +#include "crypto_osal_adapt.h" +#include "crypto_common_macro.h" + +#define OTP_READ_DELAY_TIME_IN_US 1 +#define OTP_WRITE_DELAY_TIME_IN_US 1 +#define OTP_NON_SPECIAL_VAL 0xA5C36987 + +#define OTP_TIMEOUT 1000000 +#define OTP_MEMORY_MAX_ADDR 0xfff +#define OTP_ADDR_4BYTES_ALIGN 4 +#define OTP_DIE_ID_OFFSET 0xf0 +#define OTP_DIE_ID_LEN 16 +#define OTP_WORD_LEN 4 + +#define OTP_COMPAT_ERRNO(err_code) DRV_COMPAT_ERRNO(ERROR_MODULE_OTP, err_code) + +td_s32 otp_lock_on(void); +void otp_unlock_off(void); + +td_s32 otp_lock_on(void) +{ + otp_lock lock_ctrl = {.u32 = OTP_NON_SPECIAL_VAL}; + td_u32 lock_status = OTP_NON_SPECIAL_VAL; + td_u32 lock_code = ca_misc_reg_read(CPU_ID_STAT); + td_u32 i = 0; + + /* lock otp */ + for (i = 0; i < OTP_LOCK_TIMEOUT; i++) { + /* otp unlock ? */ + lock_status = otpc_reg_read(OTP_LOCK_STATUS); + if (lock_status != OTP_LOCK_UNLOCK) { + crypto_udelay(OTP_READ_DELAY_TIME_IN_US); + continue; + } + + /* try to lock otp */ + lock_ctrl.u32 = otpc_reg_read(OTP_LOCK); + lock_ctrl.bits.otp_lock_type = OTP_LOCK_TYPE_LOCK; /* lock command */ + lock_ctrl.bits.otp_lock = OTP_LOCK_CMD; + otpc_reg_write(OTP_LOCK, lock_ctrl.u32); + + /* check lock result */ + lock_status = otpc_reg_read(OTP_LOCK_STATUS); + if (lock_status == lock_code) { + break; + } + } + + if (i >= OTP_LOCK_TIMEOUT) { + crypto_log_err("otp lock timeout\n"); + return OTP_COMPAT_ERRNO(ERROR_CHN_BUSY); + } + + return TD_SUCCESS; +} + +void otp_unlock_off(void) +{ + otp_lock lock_ctrl = {.u32 = OTP_NON_SPECIAL_VAL}; + + /* unlock otp */ + lock_ctrl.u32 = otpc_reg_read(OTP_LOCK); + lock_ctrl.bits.otp_lock_type = OTP_LOCK_TYPE_UNLOCK; /* unlock command */ + lock_ctrl.bits.otp_lock = OTP_LOCK_CMD; + otpc_reg_write(OTP_LOCK, lock_ctrl.u32); +} + +td_s32 drv_otp_read_word(const td_u32 addr, td_u32 *data) +{ + otp_rw_ctrl_u un_otp_rw_ctrl = {.u32 = OTP_NON_SPECIAL_VAL}; + otp_status otp_status_reg = {.u32 = OTP_NON_SPECIAL_VAL}; + td_u32 time_out = 0; + volatile td_s32 ret = TD_FAILURE; + + crypto_param_check(addr > OTP_MEMORY_MAX_ADDR); + crypto_param_check(data == TD_NULL); + crypto_chk_return((addr % OTP_ADDR_4BYTES_ALIGN) != 0, OTP_COMPAT_ERRNO(ERROR_OTP_ADDR_NOT_ALIGNED)); + + ret = otp_lock_on(); + if (ret != TD_SUCCESS) { + return ret; + } + + // 1.Configure Address OTP_ADDR + otpc_reg_write(OTP_ADDR, addr); + crypto_chk_print(otpc_reg_read(OTP_ADDR) != addr, "%s:%d: check equal failed\n", __func__, __LINE__); + + // 2.Configure OTP_RW_CTRL + un_otp_rw_ctrl.u32 = otpc_reg_read(OTP_RW_CTRL); +#ifdef EFUSE_OTP + un_otp_rw_ctrl.bits.wr_sel = OTP_WR_SEL_TSMC_EFUSE_NORMAL_RD; +#else + un_otp_rw_ctrl.bits.wr_sel = OTP_WR_SEL_OTP_RD; +#endif + un_otp_rw_ctrl.bits.start = OTP_START_BUSY; // 1'b1 means busy. + un_otp_rw_ctrl.bits.test_mode = OTP_TEST_MODE_NORMAL; // 3'b000 means normal mode; + otpc_reg_write(OTP_RW_CTRL, un_otp_rw_ctrl.u32); + + // 3.Wait idle + while (time_out++ < OTP_TIMEOUT) { + if ((otpc_reg_read(OTP_RW_CTRL) & 0x1) == OTP_START_IDLE) { + break; + } + crypto_udelay(OTP_READ_DELAY_TIME_IN_US); + } + if (time_out >= OTP_TIMEOUT) { + crypto_log_err("err:otp time out on read!\n"); + otp_unlock_off(); + return OTP_COMPAT_ERRNO(ERROR_OTP_TIMEOUT); + } + + // 4.Check OTP_STATUS. + otp_status_reg.u32 = otpc_reg_read(OTP_STATUS); + if (otp_status_reg.bits.check_fail == OTP_CHECK_FAIL) { // 0x0 means pass; 0x1 means fail. + crypto_log_err("\nerr: OTP read fail\n"); + otp_unlock_off(); + return OTP_COMPAT_ERRNO(ERROR_OTP_PERMISSION); + } + + // 5.Read Data + *data = otpc_reg_read(OTP_RDATA); + + otp_unlock_off(); + return TD_SUCCESS; +} + +td_s32 drv_otp_read_byte(const td_u32 addr, td_u8 *data) +{ + td_u32 read_data = 0; + volatile td_s32 ret = TD_FAILURE; + td_u32 align_addr = OTP_NON_SPECIAL_VAL; + + crypto_drv_func_enter(); + + crypto_param_check(addr > OTP_MEMORY_MAX_ADDR); + crypto_param_check(data == TD_NULL); + + align_addr = addr - (addr % OTP_ADDR_4BYTES_ALIGN); + + ret = drv_otp_read_word(align_addr, &read_data); + if (ret != TD_SUCCESS) { + crypto_log_err("\nerr: OTP read word fail\n"); + return ret; + } + + *data = (td_u8)(read_data >> (8 * (addr % OTP_ADDR_4BYTES_ALIGN))); // 8 bits one byte + + crypto_drv_func_exit(); + return TD_SUCCESS; +} + +td_s32 drv_otp_write_byte(const td_u32 addr, const td_u8 data) +{ + otp_rw_ctrl_u un_otp_rw_ctrl = {.u32 = OTP_NON_SPECIAL_VAL}; + otp_status otp_status_reg = {.u32 = OTP_NON_SPECIAL_VAL}; + td_u32 time_out = 0; + volatile td_s32 ret = TD_FAILURE; + + crypto_param_check(addr > OTP_MEMORY_MAX_ADDR); + + if (data == 0) { // Default value is 0, no need and no necessary to write 0 directly + return TD_SUCCESS; + } + + ret = otp_lock_on(); + if (ret != TD_SUCCESS) { + return ret; + } + + // 1.Configure Address OTP_ADDR, + otpc_reg_write(OTP_ADDR, addr); + crypto_chk_print(otpc_reg_read(OTP_ADDR) != addr, "%s:%d: check equal failed\n", __func__, __LINE__); + // 2.OTP_RW_ST_1 Check:(1)Readback Address (2)whether write is successful or not + + // 3.Write Data + otpc_reg_write(OTP_WDATA, data); + crypto_chk_print(otpc_reg_read(OTP_WDATA) != data, "%s:%d: check equal failed\n", __func__, __LINE__); + + // 4.Configure OTP_RW_CTRL + un_otp_rw_ctrl.u32 = otpc_reg_read(OTP_RW_CTRL); + un_otp_rw_ctrl.bits.wr_sel = OTP_WR_SEL_PGM_ACCESS; // (3'b010) 0x2 means pgm access; + un_otp_rw_ctrl.bits.start = OTP_START_BUSY; // (1'b1) 0x1 means busy. 0x0: idle. + un_otp_rw_ctrl.bits.test_mode = OTP_TEST_MODE_NORMAL; // (3'b000) 0x0 means normal mode; + otpc_reg_write(OTP_RW_CTRL, un_otp_rw_ctrl.u32); + + // 5.Wait idle + while (time_out++ < OTP_TIMEOUT) { + un_otp_rw_ctrl.u32 = otpc_reg_read(OTP_RW_CTRL); + if (un_otp_rw_ctrl.bits.start == OTP_START_IDLE) { // 0x0: idle. + break; + } + crypto_udelay(OTP_WRITE_DELAY_TIME_IN_US); + } + if (time_out >= OTP_TIMEOUT) { + crypto_log_err("err: OTP write time out!\n"); + otp_unlock_off(); + return OTP_COMPAT_ERRNO(ERROR_OTP_TIMEOUT); + } + + // 6.Check OTP_STATUS. + otp_status_reg.u32 = otpc_reg_read(OTP_STATUS); + if (otp_status_reg.bits.check_fail == OTP_CHECK_PASS) { // 0x0 means pass; 0x1 means fail. + otp_unlock_off(); + return TD_SUCCESS; + } else { + crypto_log_err("err: OTP write fail\n"); + otp_unlock_off(); + return OTP_COMPAT_ERRNO(ERROR_OTP_PERMISSION); + } +} + +td_s32 drv_otp_get_die_id(td_u8 *die_id, const td_u32 len) +{ + volatile td_s32 ret = TD_FAILURE; + td_u32 addr = OTP_DIE_ID_OFFSET; + td_u32 word_data = 0; + td_u32 i = 0; + + crypto_chk_return(len < OTP_DIE_ID_LEN, OTP_COMPAT_ERRNO(ERROR_INVALID_PARAM), "len < OTP_DIE_ID_LEN\n"); + + for (i = 0; i < OTP_DIE_ID_LEN; i += OTP_WORD_LEN) { + ret = drv_otp_read_word(addr, &word_data); + if (ret != TD_SUCCESS) { + crypto_log_err("\nerr: OTP read word fail\n"); + return ret; + } + (void)memcpy_s(die_id, len, &word_data, OTP_WORD_LEN); + addr += OTP_WORD_LEN; + die_id += OTP_WORD_LEN; + } + + crypto_chk_print(i != OTP_DIE_ID_LEN, "i == OTP_DIE_ID_LEN check equal failed\n"); + + return TD_SUCCESS; +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_pbkdf2_hard.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_pbkdf2_hard.c new file mode 100644 index 00000000..2eedc139 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_pbkdf2_hard.c @@ -0,0 +1,535 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "drv_hash.h" +#include "drv_inner.h" +#include "drv_trng.h" + +#include "hal_hash.h" + +#include "crypto_drv_common.h" + +#define PBKDF2_COMPAT_ERRNO(err_code) DRV_COMPAT_ERRNO(ERROR_MODULE_HASH, err_code) +#define pbkdf2_null_ptr_chk(ptr) \ + crypto_chk_return((ptr) == TD_NULL, PBKDF2_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), #ptr" is NULL\n") +#define CRYPTO_U8_TO_U32_BIT_SHIFT(data, i) \ + ((td_u32)(data)[(i)*4] | ((td_u32)(data)[(i)*4+1] << 8) | ((td_u32)(data)[(i)*4+2] << 16) | \ + ((td_u32)(data)[(i)*4+3]<< 24)) + +/* Current CPU ID Status . +8'h35: AIDSP; +8'h6a: PCPU; +8'ha5: TEE; +8'haa: ACPU. +*/ +#define PCPU_STAT 0x6a +#define AIDSP_STAT 0x35 +#define TEE_STAT 0xa5 +#define ACPU_STAT 0xaa + +/* KDF */ + +#define KM_CPU_PCPU 4 +#define KM_CPU_AIDSP 5 +#define KM_CPU_TEE 2 +#define KM_CPU_REE 1 +#define KM_CPU_IDLE 0 + +#define PBKDF2_ALG_HMAC_SHA1 1 +#define PBKDF2_ALG_HMAC_SHA256 0 +#define PBKDF2_ALG_HMAC_SHA384 3 +#define PBKDF2_ALG_HMAC_SHA512 4 +#define PBKDF2_ALG_HMAC_SM3 5 + +#define HMAC_SHA1_OUTPUT_LEN 20 +#define HMAC_SHA256_OUTPUT_LEN 32 +#define HMAC_SHA384_OUTPUT_LEN 48 +#define HMAC_SHA512_OUTPUT_LEN 64 +#define HMAC_SM3_OUTPUT_LEN 32 + +#define KDF_KEY_BLOCK_SIZE_512 64 +#define KDF_KEY_BLOCK_SIZE_1024 128 +#define KDF_KEY_CONFIG_LEN 32 +#define KDF_SALT_CONFIG_LEN 32 +#define KDF_VAL_CONFIG_LEN 16 +#define KDF_ALG_TYPE 5 +#define DRV_KDF_OTP_KEY_MRK1 0 +#define DRV_KDF_OTP_KEY_USK 1 +#define DRV_KDF_OTP_KEY_RUSK 2 + +/* + pbkdf2_key_config +*/ +#define KDF_SW_GEN 3 + +/* + * rkp + */ +#define RKP_LOCK (0x000) +#define RKP_CMD_CFG (0x004) +#define KDF_ERROR (0x008) +#define RKP_DEOB_CFG (0x020) +#define DEOB_ERROR (0x028) +#define RK_RDY (0x050) +#define RKP_USD_DIS (0x054) +#define RKP_LOW_POWER (0x058) +#define RKP_INIT (0x05C) +#define SW_CFG (0x060) +#define RKP_RAW_INT (0x010) +#define RKP_INT_ENABLE (0x014) +#define RKP_INT (0x018) +#define RKP_PBKDF2_DATA(a) (0x100 + 4 * (a)) /* a 0~31 */ +#define RKP_PBKDF2_KEY(a) (0x180 + 4 * (a)) /* a 0~31 */ +#define RKP_PBKDF2_VAL(b) (0x200 + 4 * (b)) /* b 0~16 */ +#define RKP_USD(c) (0x300 + 4 * (c)) /* c 0~8 */ + +/* salt len */ +#define SALT_RESERVED_LEN_512 21 +#define SALT_RESERVED_LEN_256 13 + +/* Define the union U_RKP_RKP_LOCK */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int km_lock_status : 3; /* [2..0] */ + unsigned int reserved : 29; /* [31..3] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} rkp_lock; + +/* Define the union U_RKP_CMD_CFG */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int sw_calc_req : 1; /* [0] */ + unsigned int pbkdf2_alg_sel_cfg : 3; /* [3..1] */ + unsigned int pbkdf2_key_sel_cfg : 5; /* [8..4] */ + unsigned int reserved : 7; /* [15..9] */ + unsigned int rkp_pbkdf_calc_time : 16; /* [31..16] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} rkp_cmd_cfg; + +static td_s32 priv_wait_rkp_to_be_lock(void) +{ + rkp_lock lock_val = {0}; + td_u32 rkp_config_val = KM_CPU_IDLE; + crypto_cpu_type cpu = crypto_get_cpu_type(); + switch (cpu) { + case CRYPTO_CPU_TYPE_SCPU: + rkp_config_val = KM_CPU_TEE; + break; + case CRYPTO_CPU_TYPE_ACPU: + rkp_config_val = KM_CPU_REE; + break; + default: + return PBKDF2_COMPAT_ERRNO(ERROR_UNEXPECTED); + } + + km_reg_write(RKP_LOCK, rkp_config_val); + lock_val.u32 = km_reg_read(RKP_LOCK); + if (lock_val.bits.km_lock_status != rkp_config_val) { + return PBKDF2_COMPAT_ERRNO(ERROR_CHN_BUSY); + } + + return TD_SUCCESS; +} + +#define RKP_TIME_OUT 1000000 +static td_s32 priv_rkp_lock(td_void) +{ + td_u32 i = 0; + td_s32 ret; + + for (i = 0; i < RKP_TIME_OUT; i++) { + ret = priv_wait_rkp_to_be_lock(); + if (ret == TD_SUCCESS) { + break; + } + crypto_udelay(1); + } + + if (i >= RKP_TIME_OUT) { + crypto_log_err("priv_rkp_lock busy.\n"); + return PBKDF2_COMPAT_ERRNO(ERROR_RKP_LOCK_TIMEOUT); + } + + return TD_SUCCESS; +} + +static td_void priv_rkp_unlock(void) +{ + km_reg_write(RKP_LOCK, KM_CPU_IDLE); +} + +static td_s32 priv_kdf_param_salt_padding(td_u8 *salt_pad, td_u32 pad_len, td_u32 block_len, + const crypto_kdf_pbkdf2_param *param, td_u32 cnt_bit) +{ + td_u32 i = 0; + td_u32 j = 0; + td_u32 salt_pad_total_len = 0; + td_u32 random_val = 0; + td_s32 ret; + crypto_unused(pad_len); + /* Formatting of the PBKDF2 salt Padding + * The PBKDF2 salt Padding formatted as shown below: + * big endian + * salt length || 32 bit(i) || 1 bit(1) || 2 word tail length + * + * sm3: + * sha1: + * sha256: salt_len || 32 bit || 8 bit || 64 bit + * + * sha384: + * sha512: salt_len || 32 bit || 8 bit || 128 bit + */ + ret = drv_cipher_trng_get_random(&random_val); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_trng_get_random failed\n"); + + for (i = 0, j = random_val % param->slen; i < param->slen; i++) { + salt_pad[j] = param->salt[j]; /* copy salt */ + j++; + j %= param->slen; + } + + salt_pad[i + 3] = cnt_bit & 0xff; /* 3: need fill 32bit i, big endian padding */ + salt_pad[i + 2] = (cnt_bit >> 8) & 0xff; /* 2/8: need fill 32bit i, big endian padding */ + salt_pad[i + 1] = (cnt_bit >> 16) & 0xff; /* 16: need fill 32bit i, big endian padding */ + salt_pad[i] = (cnt_bit >> 24) & 0xff; /* 24: need fill 32bit i, big endian padding */ + salt_pad[i + 4] = 0x80; /* 4: message data fill 1 */ + + if (block_len == KDF_KEY_BLOCK_SIZE_512) { + /* need to connect i_key_pad length, the i_key_pad length is block size */ + salt_pad_total_len = KDF_KEY_BLOCK_SIZE_512 * CRYPTO_BITS_IN_BYTE; + } else { + /* need to connect i_key_pad length, the i_key_pad length is block size */ + salt_pad_total_len = KDF_KEY_BLOCK_SIZE_1024 * CRYPTO_BITS_IN_BYTE; + } + salt_pad_total_len += 32 + param->slen * 8; /* length: 32 bit i + slen * 8 */ + + salt_pad[block_len - 1] = salt_pad_total_len & 0xff; + salt_pad[block_len - 2] = (salt_pad_total_len >> 8) & 0xff; /* 2: 2bit 8: right move 8 */ + salt_pad[block_len - 3] = (salt_pad_total_len >> 16) & 0xff; /* 3: 3bit 16: right move 16 */ + salt_pad[block_len - 4] = (salt_pad_total_len >> 24) & 0xff; /* 4: 4bit 24: right move 24 */ + + return TD_SUCCESS; +} + + +static td_s32 priv_kdf_config_val(crypto_hash_type hash_type) +{ + td_u32 i = 0; + td_s32 ret = TD_SUCCESS; + td_u32 val_len = 0; + td_u32 state_iv[64]; + + ret = drv_hash_get_state_iv(hash_type, &val_len, state_iv, sizeof(state_iv)); + if (ret != TD_SUCCESS) { + return PBKDF2_COMPAT_ERRNO(ERROR_UNEXPECTED); + } + + val_len /= CRYPTO_WORD_WIDTH; + + for (i = 0; i < val_len; i++) { + km_reg_write(RKP_PBKDF2_VAL(i), state_iv[i]); + } + + return TD_SUCCESS; +} + +static td_s32 priv_kdf_config_data(const td_u8 *pswd_pad, td_u32 pswd_len, const td_u8 *salt_pad, td_u32 salt_len) +{ + td_u32 ret; + td_u32 i = 0; + td_u32 j = 0; + td_u32 random_val = 0; + td_u32 x = sizeof(td_u32) / sizeof(td_u8); + td_u32 pswd_tmp = 0; + td_u32 salt_tmp = 0; + + if (pswd_len != KDF_KEY_CONFIG_LEN * x || + salt_len != KDF_KEY_CONFIG_LEN * x) { + return PBKDF2_COMPAT_ERRNO(ERROR_INVALID_PARAM); + } + + ret = drv_cipher_trng_get_random(&random_val); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_trng_get_random failed\n"); + + for (i = 0, j = random_val % KDF_KEY_CONFIG_LEN; i < KDF_KEY_CONFIG_LEN; i++) { + pswd_tmp = CRYPTO_U8_TO_U32_BIT_SHIFT(pswd_pad, j); + km_reg_write(RKP_PBKDF2_KEY(j), pswd_tmp); + j++; + j %= KDF_KEY_CONFIG_LEN; + } + + ret = drv_cipher_trng_get_random(&random_val); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_trng_get_random failed\n"); + + for (i = 0, j = random_val % KDF_SALT_CONFIG_LEN; i < KDF_SALT_CONFIG_LEN; i++) { + salt_tmp = CRYPTO_U8_TO_U32_BIT_SHIFT(salt_pad, j); + km_reg_write(RKP_PBKDF2_DATA(j), salt_tmp); + j++; + j %= KDF_SALT_CONFIG_LEN; + } + + return TD_SUCCESS; +} + +static td_void priv_kdf_sw_config_start(td_u32 alg_cfg, td_u16 count) +{ + rkp_cmd_cfg cfgval = {0}; + + cfgval.u32 = km_reg_read(RKP_CMD_CFG); + cfgval.bits.rkp_pbkdf_calc_time = count; + cfgval.bits.pbkdf2_alg_sel_cfg = alg_cfg; + cfgval.bits.pbkdf2_key_sel_cfg = KDF_SW_GEN; + cfgval.bits.sw_calc_req = 0x1; /* start calculation */ + km_reg_write(RKP_CMD_CFG, cfgval.u32); +} + +static td_s32 priv_rkp_wait_idle(void) +{ + rkp_cmd_cfg cfg_val = {0}; + td_s32 ret; + td_u32 i = 0; + + for (i = 0; i < RKP_TIME_OUT; ++i) { + cfg_val.u32 = km_reg_read(RKP_CMD_CFG); + if (cfg_val.bits.sw_calc_req == 0x0) { + km_reg_write(RKP_RAW_INT, 0x1); + break; + } + crypto_udelay(1); + } + if (i < RKP_TIME_OUT) { + ret = TD_SUCCESS; + } else { + ret = PBKDF2_COMPAT_ERRNO(ERROR_RKP_CALC_TIMEOUT); + } + + return ret; +} + +static td_void priv_rkp_chk_err(void) +{ + td_s32 kdf_err; + + kdf_err = km_reg_read(KDF_ERROR); + if (kdf_err != 0) { + crypto_log_err("KDF Error: 0x%x\n", kdf_err); + } +} + +static td_s32 priv_kdf_calculation(const crypto_kdf_pbkdf2_param *param, td_u32 alg_cfg, td_u32 block_size, + td_u32 cnt_bit) +{ + td_u8 kdf_passwd_pad[KDF_KEY_BLOCK_SIZE_1024]; + td_u8 kdf_salt_pad[KDF_KEY_BLOCK_SIZE_1024]; + + td_s32 ret; + + (td_void)memset_s(kdf_passwd_pad, KDF_KEY_BLOCK_SIZE_1024, 0, KDF_KEY_BLOCK_SIZE_1024); + (td_void)memset_s(kdf_salt_pad, KDF_KEY_BLOCK_SIZE_1024, 0, KDF_KEY_BLOCK_SIZE_1024); + + /* password padding */ + if (param->plen != 0) { + ret = memcpy_s(kdf_passwd_pad, KDF_KEY_BLOCK_SIZE_1024, param->password, param->plen); + crypto_chk_return(ret != EOK, ret, "memcpy_s failed\n"); + } + + /* salt padding */ + ret = priv_kdf_param_salt_padding(kdf_salt_pad, KDF_KEY_BLOCK_SIZE_1024, block_size, param, cnt_bit); + crypto_chk_goto(ret != TD_SUCCESS, exit_clean, "priv_kdf_param_salt_padding failed\n"); + + ret = priv_kdf_config_val(param->hash_type); + crypto_chk_goto(ret != TD_SUCCESS, exit_clean, "priv_kdf_config_val failed\n"); + + ret = priv_kdf_config_data(kdf_passwd_pad, KDF_KEY_BLOCK_SIZE_1024, kdf_salt_pad, KDF_KEY_BLOCK_SIZE_1024); + crypto_chk_goto(ret != TD_SUCCESS, exit_clean, "priv_kdf_config_data failed\n"); + + priv_kdf_sw_config_start(alg_cfg, param->count); + ret = priv_rkp_wait_idle(); + crypto_chk_goto(ret != TD_SUCCESS, exit_clean, "priv_rkp_wait_idle failed\n"); + + priv_rkp_chk_err(); + +exit_clean: + (td_void)memset_s(kdf_passwd_pad, KDF_KEY_BLOCK_SIZE_1024, 0, KDF_KEY_BLOCK_SIZE_1024); + (td_void)memset_s(kdf_salt_pad, KDF_KEY_BLOCK_SIZE_1024, 0, KDF_KEY_BLOCK_SIZE_1024); + return ret; +} + +static td_void priv_kdf_clear_reg_key(td_void) +{ + td_u32 i = 0; + td_u32 clear_key_val = 0; + + (td_void)drv_cipher_trng_get_random(&clear_key_val); + + for (i = 0; i < KDF_KEY_CONFIG_LEN; i++) { + km_reg_write(RKP_PBKDF2_KEY(i), clear_key_val); + } + + for (i = 0; i < KDF_SALT_CONFIG_LEN; i++) { + km_reg_write(RKP_PBKDF2_DATA(i), clear_key_val); + } + + for (i = 0; i < KDF_VAL_CONFIG_LEN; i++) { + km_reg_write(RKP_PBKDF2_VAL(i), clear_key_val); + } +} + +#define PBKDF2_ALG_HMAC_SHA256 0 +#define PBKDF2_ALG_HMAC_SHA384 3 +#define PBKDF2_ALG_HMAC_SHA512 4 +#define PBKDF2_ALG_HMAC_SM3 5 + +static td_s32 priv_get_alg_cfg(crypto_hash_type hash_type, td_u32 *alg_cfg, td_u32 *block_size, td_u32 *out_key_len) +{ + *block_size = CRYPTO_HASH_GET_BLOCK_SIZE(hash_type) / CRYPTO_BITS_IN_BYTE; + *out_key_len = CRYPTO_HASH_GET_RESULT_SIZE(hash_type) / CRYPTO_BITS_IN_BYTE; + switch (hash_type) { + case CRYPTO_HASH_TYPE_HMAC_SHA256: + *alg_cfg = PBKDF2_ALG_HMAC_SHA256; + break; + case CRYPTO_HASH_TYPE_HMAC_SHA384: + *alg_cfg = PBKDF2_ALG_HMAC_SHA384; + break; + case CRYPTO_HASH_TYPE_HMAC_SHA512: + *alg_cfg = PBKDF2_ALG_HMAC_SHA512; + break; + case CRYPTO_HASH_TYPE_HMAC_SM3: + *alg_cfg = PBKDF2_ALG_HMAC_SM3; + break; + default: + return PBKDF2_COMPAT_ERRNO(ERROR_INVALID_PARAM); + } + return TD_SUCCESS; +} + +static td_s32 priv_kdf_output_key_remain(td_u8 *out, const td_u32 out_len, td_u32 out_key_len, td_u32 cnt_count, + td_u32 remain_num) +{ + td_s32 ret; + td_u32 i = 0; + td_u32 readval[KDF_VAL_CONFIG_LEN]; + for (i = 0; i < out_key_len / CRYPTO_WORD_WIDTH; i++) { + readval[i] = km_reg_read(RKP_PBKDF2_VAL(i)); + } + + ret = memcpy_s(out + cnt_count * out_key_len, out_len - cnt_count * out_key_len, readval, remain_num); + crypto_chk_return(ret != EOK, PBKDF2_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + return TD_SUCCESS; +} + +static td_s32 priv_kdf_output_key(td_u8 *out, const td_u32 out_len, td_u32 out_key_len, td_u32 cnt_count) +{ + td_u32 i = 0; + td_u32 j = 0; + td_u32 readval[KDF_VAL_CONFIG_LEN]; + td_u32 random_val = 0; + td_u32 ret; + + ret = drv_cipher_trng_get_random(&random_val); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_trng_get_random failed\n"); + + for (i = 0, j = random_val % (out_key_len / CRYPTO_WORD_WIDTH); i < out_key_len / CRYPTO_WORD_WIDTH; i++) { + readval[j] = km_reg_read(RKP_PBKDF2_VAL(j)); + j++; + j %= (out_key_len / CRYPTO_WORD_WIDTH); + } + + ret = memcpy_s(out + cnt_count * out_key_len, out_len - cnt_count * out_key_len, readval, out_key_len); + crypto_chk_return(ret != EOK, PBKDF2_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + return TD_SUCCESS; +} + +td_s32 drv_cipher_pbkdf2(const crypto_kdf_pbkdf2_param *param, td_u8 *out, const td_u32 out_len) +{ + td_s32 ret; + td_u32 alg_cfg = 0; + td_u32 block_size = 0; + td_u32 out_key_len = 0; + td_u32 cal_count = 0; + td_u32 remain_num = 0; + td_u32 i = 0; + + pbkdf2_null_ptr_chk(param); + pbkdf2_null_ptr_chk(out); + if (param->plen != 0) { + pbkdf2_null_ptr_chk(param->password); + } + if (param->slen != 0) { + pbkdf2_null_ptr_chk(param->salt); + } + + if (param->hash_type == CRYPTO_HASH_TYPE_HMAC_SM3) { + crypto_chk_return(crypto_sm_support(CRYPTO_SM_ALG_SM3) == TD_FALSE, PBKDF2_COMPAT_ERRNO(ERROR_UNSUPPORT), + "SM3 alg is unsupport\n"); + } + + ret = priv_get_alg_cfg(param->hash_type, &alg_cfg, &block_size, &out_key_len); + crypto_chk_return(ret != TD_SUCCESS, ret, "priv_get_alg_cfg failed\n"); + crypto_chk_return(param->plen > block_size, PBKDF2_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "plen should not be Bigger Than Block Size!\n"); + crypto_chk_return(out_key_len == 0, PBKDF2_COMPAT_ERRNO(ERROR_INVALID_PARAM), "out_key_len is Invalid!\n"); + + /* Formatting of the PBKDF2 salt Padding + * The PBKDF2 salt Padding formatted as shown below: + * big endian + * salt length || 32 bit(i) || 1 bit(1) || 2 word tail length + * + * sm3: + * sha1: + * sha256: salt_len || 4 byte || 1 byte || 8 byte + * so salt_len smaller block_size - (4 + 1 + 8 = 13) + * sha384: + * sha512: salt_len || 4 byte || 1 byte || 16 byte + * so salt_len smaller block_size - (4 + 1 + 16 = 21) + */ + if (block_size == KDF_KEY_BLOCK_SIZE_512) { + crypto_chk_return(param->slen > block_size - SALT_RESERVED_LEN_256, PBKDF2_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "Invalid Salt Len!\n"); /* 13: byte */ + } else { + crypto_chk_return(param->slen > block_size - SALT_RESERVED_LEN_512, PBKDF2_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "Invalid Salt Len!\n"); /* 21: byte */ + } + + remain_num = out_len % out_key_len; /* residual processing */ + if (remain_num != 0) { + cal_count = (out_len / out_key_len) + 1; /* if remain_num is not 0, need to calculate one more block. */ + } else { + cal_count = out_len / out_key_len; + } + ret = priv_rkp_lock(); + crypto_chk_return(ret != TD_SUCCESS, ret, "priv_rkp_lock failed\n"); + + for (i = 0; i < cal_count; i++) { + ret = priv_kdf_calculation(param, alg_cfg, block_size, i + 1); + crypto_chk_goto(ret != TD_SUCCESS, exit_rkp_unlock, "priv_kdf_calculation failed\n"); + if (remain_num != 0) { + if (i == cal_count - 1) { /* calculation the last conut */ + ret = priv_kdf_output_key_remain(out, out_len, out_key_len, i, remain_num); + crypto_chk_goto(ret != TD_SUCCESS, exit_rkp_unlock, "priv_kdf_output_key_remain failed\n"); + } else { + ret = priv_kdf_output_key(out, out_len, out_key_len, i); + crypto_chk_goto(ret != TD_SUCCESS, exit_rkp_unlock, "priv_kdf_output_key failed\n"); + } + } else { + ret = priv_kdf_output_key(out, out_len, out_key_len, i); + crypto_chk_goto(ret != TD_SUCCESS, exit_rkp_unlock, "priv_kdf_output_key failed\n"); + } + } + + /* clear key */ + priv_kdf_clear_reg_key(); + +exit_rkp_unlock: + priv_rkp_unlock(); /* unlock rkp */ + return ret; +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_pke.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_pke.c new file mode 100644 index 00000000..c1380f6c --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_pke.c @@ -0,0 +1,792 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "hal_pke.h" +#include "drv_pke.h" +#include "crypto_hash_struct.h" +#include "crypto_drv_common.h" +#include "securec.h" +#include "drv_hash.h" +#include "drv_trng.h" +#include "drv_inner.h" +#define PKE_COMPAT_ERRNO(err_code) DRV_COMPAT_ERRNO(ERROR_MODULE_PKE, err_code) + +static td_u32 g_drv_pke_initialize = TD_FALSE; + +static td_u8 g_ed_pd[] = { + 0x59, 0x04, 0x56, 0xb4, 0xe5, 0x3f, 0x8a, 0x4d, 0xcb, 0x27, 0x24, 0x0f, 0x78, 0x31, 0x0d, 0x20, + 0x21, 0x43, 0x0e, 0xef, 0x5f, 0x8c, 0x52, 0xe7, 0x01, 0xdb, 0x17, 0xfd, 0xbe, 0x8f, 0xd3, 0xf4, +}; + +td_s32 drv_cipher_pke_init(void) +{ + g_drv_pke_initialize = TD_TRUE; + return hal_pke_init(); +} + +td_s32 drv_cipher_pke_deinit(void) +{ + g_drv_pke_initialize = TD_FALSE; + return hal_pke_deinit(); +} + +td_s32 drv_cipher_pke_lock_secure(void) +{ + td_s32 ret = TD_FAILURE; + crypto_chk_return(g_drv_pke_initialize != TD_TRUE, PKE_COMPAT_ERRNO(ERROR_NOT_INIT), "pke not init!\n"); + ret = hal_pke_lock(); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_lock failed, ret is 0x%x\n", ret); + hal_pke_secure(TD_TRUE); + return TD_SUCCESS; +} + +td_s32 drv_cipher_pke_unlock_secure(void) +{ + td_s32 ret = TD_FAILURE; + ret = hal_pke_unlock(); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_unlock failed, ret is 0x%x\n", ret); + hal_pke_secure(TD_FALSE); + return TD_SUCCESS; +} + +td_s32 drv_cipher_pke_clean_ram(void) +{ + td_s32 ret = TD_FAILURE; + + ret = hal_pke_wait_free(); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_wait_free failed, ret is 0x%x\n", ret); + + ret = hal_pke_set_mode(HAL_PKE_MODE_CLR_RAM, DRV_PKE_LEN_4096); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_set_mode failed, ret is 0x%x\n", ret); + + hal_pke_start(); + + ret = hal_pke_wait_done(); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_wait_done failed, ret is 0x%x\n", ret); + + // Redundant cleaning + ret = hal_pke_wait_free(); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_wait_free failed, ret is 0x%x\n", ret); + + ret = hal_pke_set_mode(HAL_PKE_MODE_CLR_RAM, DRV_PKE_LEN_4096); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_set_mode failed, ret is 0x%x\n", ret); + + hal_pke_start(); + + ret = hal_pke_wait_done(); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_wait_done failed, ret is 0x%x\n", ret); + + return TD_SUCCESS; +} + +static td_s32 drv_cipher_pke_exp_mod_param_chk(const drv_pke_data *n, const drv_pke_data *k, const drv_pke_data *in, + const drv_pke_data *out) +{ + crypto_param_check(n == TD_NULL); + crypto_param_check(n->data == TD_NULL); + crypto_param_check(k == TD_NULL); + crypto_param_check(k->data == TD_NULL); + crypto_param_check(in == TD_NULL); + crypto_param_check(in->data == TD_NULL); + crypto_param_check(out == TD_NULL); + crypto_param_check(out->data == TD_NULL); + crypto_param_check(n->length != k->length); + crypto_param_check(n->length != in->length); + crypto_param_check(n->length > out->length); + crypto_param_check(n->length != DRV_PKE_LEN_2048 && n->length != DRV_PKE_LEN_3072 && + n->length != DRV_PKE_LEN_4096); + return TD_SUCCESS; +} + +/* out = in ^ k mod n */ +td_s32 drv_cipher_pke_exp_mod(const drv_pke_data *n, const drv_pke_data *k, const drv_pke_data *in, + const drv_pke_data *out) +{ + td_s32 ret = TD_FAILURE; + td_u32 klen = 0; + pke_block random; + td_u8 *key = TD_NULL; + td_u32 key_buf_len = 0; + + ret = drv_cipher_pke_exp_mod_param_chk(n, k, in, out); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_pke_exp_mod_param_chk failed, ret is 0x%x\n", ret); + + klen = n->length; + + ret = hal_pke_wait_free(); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_wait_free failed, ret is 0x%x\n", ret); + + key_buf_len = klen * 2; // 2: for n & k + key = crypto_malloc(key_buf_len); + crypto_chk_return(key == TD_NULL, PKE_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + + ret = drv_cipher_trng_get_random(&random.word[0]); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "drv_cipher_trng_get_random failed, ret is 0x%x\n", ret); + + ret = drv_cipher_trng_get_random(&random.word[1]); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "drv_cipher_trng_get_random failed, ret is 0x%x\n", ret); + + ret = hal_pke_set_mode(HAL_PKE_MODE_EXP_MOD, klen); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "hal_pke_set_mode failed, ret is 0x%x\n", ret); + + /* key xor random */ + if (memcpy_s(key, klen, n->data, klen) != EOK || memcpy_s(key + klen, klen, k->data, klen) != EOK) { + crypto_log_err("memcpy_s(key, klen, k, klen) != EOK\n"); + ret = PKE_COMPAT_ERRNO(ERROR_MEMCPY_S); + goto exit_free; + } + +#if defined(CONFIG_CRYPTO_CHIP_SHAOLINSWORD) || defined(CONFIG_CRYPTO_CHIP_HI3751V811) + hal_pke_set_key(key, key, klen + klen, &random, klen + klen); +#endif + + hal_pke_set_ram(PKE_NRAM, key, klen, klen); + hal_pke_set_ram(PKE_KRAM, key + klen, klen, klen); + hal_pke_set_ram(PKE_MRAM, in->data, klen, klen); + + hal_pke_start(); + + ret = hal_pke_wait_done(); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "hal_pke_wait_done failed, ret is 0x%x\n", ret); + + hal_pke_get_ram(PKE_RRAM, out->data, klen); +exit_free: + if (key != TD_NULL) { + (void)memset_s(key, key_buf_len, 0, key_buf_len); + crypto_free(key); + } + return ret; +} + +static td_s32 drv_cipher_pke_add_mod_param_chk(const drv_pke_data *a, const drv_pke_data *b, const drv_pke_data *p, + const drv_pke_data *c) +{ + crypto_param_check(a == TD_NULL); + crypto_param_check(a->data == TD_NULL); + crypto_param_check(b == TD_NULL); + crypto_param_check(b->data == TD_NULL); + crypto_param_check(p == TD_NULL); + crypto_param_check(p->data == TD_NULL); + crypto_param_check(c == TD_NULL); + crypto_param_check(c->data == TD_NULL); + crypto_param_check(p->length == 0); + crypto_param_check(p->length != b->length); + crypto_param_check(p->length != c->length); + return TD_SUCCESS; +} + +/* c = a + b mod p */ +td_s32 drv_cipher_pke_add_mod(const drv_pke_data *a, const drv_pke_data *b, const drv_pke_data *p, + const drv_pke_data *c) +{ + td_s32 ret = TD_FAILURE; + td_u32 max_len = 0; + ret = drv_cipher_pke_add_mod_param_chk(a, b, p, c); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_pke_add_mod_param_chk failed, ret is 0x%x\n", ret); + + ret = hal_pke_align_len(crypto_max(p->length, a->length), &max_len, HAL_ALIGN_LEN); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_align_len failed, ret is 0x%x\n", ret); + + ret = hal_pke_wait_free(); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_wait_free failed, ret is 0x%x\n", ret); + + ret = hal_pke_set_mode(HAL_PKE_MODE_ADD_MOD, max_len); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_set_mode failed, ret is 0x%x\n", ret); + + hal_pke_set_ram(PKE_NRAM, a->data, a->length, max_len); + hal_pke_set_ram(PKE_KRAM, b->data, b->length, max_len); + hal_pke_set_ram(PKE_RRAM, p->data, p->length, max_len); + + hal_pke_start(); + + ret = hal_pke_wait_done(); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_wait_done failed, ret is 0x%x\n", ret); + + hal_pke_get_ram(PKE_MRAM, c->data, c->length); + + return TD_SUCCESS; +} + +static td_s32 drv_cipher_pke_sub_mod_param_chk(const drv_pke_data *a, const drv_pke_data *b, const drv_pke_data *p, + const drv_pke_data *c) +{ + crypto_param_check(a == TD_NULL); + crypto_param_check(b == TD_NULL); + crypto_param_check(c == TD_NULL); + crypto_param_check(p == TD_NULL); + crypto_param_check(a->data == TD_NULL); + crypto_param_check(b->data == TD_NULL); + crypto_param_check(c->data == TD_NULL); + crypto_param_check(p->data == TD_NULL); + crypto_param_check(a->length == 0); + crypto_param_check(a->length != b->length); + crypto_param_check(a->length != p->length); + crypto_param_check(a->length != c->length); + return TD_SUCCESS; +} + +/* c = (a - b) mod p */ +td_s32 drv_cipher_pke_sub_mod(const drv_pke_data *a, const drv_pke_data *b, const drv_pke_data *p, + const drv_pke_data *c) +{ + td_s32 ret = TD_FAILURE; + td_u32 klen = 0; + td_u32 max_len = 0; + ret = drv_cipher_pke_sub_mod_param_chk(a, b, p, c); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_pke_sub_mod_param_chk failed, ret is 0x%x\n", ret); + + klen = a->length; + + ret = hal_pke_align_len(klen, &max_len, HAL_ALIGN_LEN); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_align_len failed, ret is 0x%x\n", ret); + + ret = hal_pke_wait_free(); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_wait_free failed, ret is 0x%x\n", ret); + + ret = hal_pke_set_mode(HAL_PKE_MODE_SUB_MOD, max_len); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_set_mode failed, ret is 0x%x\n", ret); + + hal_pke_set_ram(PKE_NRAM, a->data, klen, max_len); + hal_pke_set_ram(PKE_KRAM, b->data, klen, max_len); + hal_pke_set_ram(PKE_RRAM, p->data, klen, max_len); + + hal_pke_start(); + + ret = hal_pke_wait_done(); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_wait_done failed, ret is 0x%x\n", ret); + + hal_pke_get_ram(PKE_MRAM, c->data, klen); + return TD_SUCCESS; +} + +static td_s32 drv_cipher_pke_mod_param_chk(const drv_pke_data *a, const drv_pke_data *p, const drv_pke_data *c) +{ + crypto_param_check(a == TD_NULL); + crypto_param_check(a->data == TD_NULL); + crypto_param_check(p == TD_NULL); + crypto_param_check(p->data == TD_NULL); + crypto_param_check(c == TD_NULL); + crypto_param_check(c->data == TD_NULL); + crypto_param_check(p->length == 0); + crypto_param_check(p->length != c->length); + return TD_SUCCESS; +} + +/* c = a mod p */ +td_s32 drv_cipher_pke_mod(const drv_pke_data *a, const drv_pke_data *p, const drv_pke_data *c) +{ + td_s32 ret = TD_FAILURE; + td_u32 max_len = 0; + ret = drv_cipher_pke_mod_param_chk(a, p, c); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_pke_mod_param_chk failed, ret is 0x%x\n", ret); + + ret = hal_pke_align_len(crypto_max(a->length, p->length), &max_len, HAL_ALIGN_LEN); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_align_len failed, ret is 0x%x\n", ret); + + ret = hal_pke_wait_free(); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_wait_free failed, ret is 0x%x\n", ret); + + ret = hal_pke_set_mode(HAL_PKE_MODE_MOD, max_len); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_set_mode failed, ret is 0x%x\n", ret); + + hal_pke_set_ram(PKE_MRAM, a->data, a->length, max_len); + hal_pke_set_ram(PKE_KRAM, p->data, p->length, max_len); + + hal_pke_start(); + + ret = hal_pke_wait_done(); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_wait_done failed, ret is 0x%x\n", ret); + + hal_pke_get_ram(PKE_RRAM, c->data, c->length); + + return TD_SUCCESS; +} + +static td_s32 drv_cipher_pke_mul_dot_param_chk(const drv_pke_ecc_curve *ecc, const drv_pke_data *k, + const drv_pke_ecc_point *p, const drv_pke_ecc_point *r) +{ + crypto_param_check(ecc == TD_NULL); + crypto_param_check(ecc->gx == TD_NULL); + crypto_param_check(ecc->gy == TD_NULL); + crypto_param_check(ecc->n == TD_NULL); + crypto_param_check(ecc->b == TD_NULL); + crypto_param_check(ecc->a == TD_NULL); + crypto_param_check(ecc->p == TD_NULL); + crypto_param_check(k == TD_NULL); + crypto_param_check(k->data == TD_NULL); + crypto_param_check(p == TD_NULL); + crypto_param_check(p->x == TD_NULL); + crypto_param_check(p->y == TD_NULL); + crypto_param_check(r == TD_NULL); + crypto_param_check(r->x == TD_NULL); + crypto_param_check(ecc->ksize != k->length); + crypto_param_check(ecc->ksize != p->length); + crypto_param_check(ecc->ksize != r->length); + crypto_param_check(ecc->ksize != DRV_PKE_LEN_256 && ecc->ksize != DRV_PKE_LEN_384 && + ecc->ksize != DRV_PKE_LEN_512 && ecc->ksize != DRV_PKE_LEN_521); + return TD_SUCCESS; +} + +/* *** R = k . P(x,y) *** */ +td_s32 drv_cipher_pke_mul_dot(const drv_pke_ecc_curve *ecc, const drv_pke_data *k, const drv_pke_ecc_point *p, + const drv_pke_ecc_point *r) +{ + td_s32 ret = TD_FAILURE; + td_u32 klen; + td_u32 max_len = 0; + td_u8 *key = TD_NULL; + td_u32 id; + pke_block random; + td_u32 ram_section_len = 0; + td_u32 set_key_len = 0; + ret = drv_cipher_pke_mul_dot_param_chk(ecc, k, p, r); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_pke_mul_dot_param_chk failed, ret is 0x%x\n", ret); + + klen = ecc->ksize; + + ret = hal_pke_align_len(0, &ram_section_len, HAL_RAM_SECTION_LEN); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_align_len failed, ret is 0x%x\n", ret); + ret = hal_pke_align_len(0, &set_key_len, HAL_SET_KEY_LEN); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_align_len failed, ret is 0x%x\n", ret); + ret = hal_pke_align_len(klen, &max_len, HAL_ALIGN_LEN); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_align_len failed, ret is 0x%x\n", ret); + + key = crypto_malloc(set_key_len); + if (key == TD_NULL) { + crypto_log_err("%s:%d Error! Malloc memory failed!\n", __FUNCTION__, __LINE__); + return PKE_COMPAT_ERRNO(ERROR_MALLOC); + } + ret = hal_pke_wait_free(); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "hal_pke_wait_free failed, ret is 0x%x\n", ret); + + ret = hal_pke_set_mode(HAL_PKE_MODE_MUL_DOT, max_len); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "hal_pke_set_mode failed, ret is 0x%x\n", ret); + + ret = drv_cipher_trng_get_random(&random.word[0]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_trng_get_random failed, ret is 0x%x\n", ret); + ret = drv_cipher_trng_get_random(&random.word[1]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_trng_get_random failed, ret is 0x%x\n", ret); + + hal_pke_set_key(k->data, key, klen, &random, set_key_len); + + id = 0; + hal_pke_set_ram(PKE_MRAM + (id++) * ram_section_len, p->x, klen, ram_section_len); + hal_pke_set_ram(PKE_MRAM + (id++) * ram_section_len, p->y, klen, ram_section_len); + hal_pke_set_ram(PKE_MRAM + (id++) * ram_section_len, ecc->gx, klen, ram_section_len); + hal_pke_set_ram(PKE_MRAM + (id++) * ram_section_len, ecc->gy, klen, ram_section_len); + + id = 0; + hal_pke_set_ram(PKE_KRAM, key, set_key_len, set_key_len); + hal_pke_set_ram(PKE_KRAM + set_key_len + (id++) * ram_section_len, ecc->n, klen, ram_section_len); + hal_pke_set_ram(PKE_KRAM + set_key_len + (id++) * ram_section_len, ecc->b, klen, ram_section_len); + hal_pke_set_ram(PKE_KRAM + set_key_len + (id++) * ram_section_len, ecc->a, klen, ram_section_len); + hal_pke_set_ram(PKE_KRAM + set_key_len + (id++) * ram_section_len, ecc->p, klen, ram_section_len); + + hal_pke_start(); + + ret = hal_pke_wait_done(); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "hal_pke_wait_done failed, ret is 0x%x\n", ret); + + hal_pke_get_ram(PKE_RRAM, r->x, klen); + // r->y does not need to be provided in the ECDH + if (r->y != TD_NULL) { + hal_pke_get_ram(PKE_RRAM + ram_section_len, r->y, klen); + } +exit__: + if (key != TD_NULL) { + (void)memset_s(key, set_key_len, 0, set_key_len); + crypto_free(key); + } + return ret; +} + +static td_s32 drv_cipher_pke_mul_mod_param_chk(const drv_pke_data *a, const drv_pke_data *b, const drv_pke_data *p, + const drv_pke_data *c) +{ + crypto_param_check(a == TD_NULL); + crypto_param_check(a->data == TD_NULL); + crypto_param_check(b == TD_NULL); + crypto_param_check(b->data == TD_NULL); + crypto_param_check(p == TD_NULL); + crypto_param_check(p->data == TD_NULL); + crypto_param_check(c == TD_NULL); + crypto_param_check(c->data == TD_NULL); + crypto_param_check(a->length == 0); + crypto_param_check(a->length != b->length); + crypto_param_check(a->length != p->length); + crypto_param_check(a->length != c->length); + return TD_SUCCESS; +} + +/* c = a * b mod p */ +td_s32 drv_cipher_pke_mul_mod(const drv_pke_data *a, const drv_pke_data *b, const drv_pke_data *p, + const drv_pke_data *c) +{ + td_s32 ret = TD_FAILURE; + td_u32 klen = 0; + td_u32 max_len = 0; + + ret = drv_cipher_pke_mul_mod_param_chk(a, b, p, c); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_pke_mul_mod_param_chk failed, ret is 0x%x\n", ret); + + klen = a->length; + + ret = hal_pke_align_len(klen, &max_len, HAL_ALIGN_LEN); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_align_len failed, ret is 0x%x\n", ret); + ret = hal_pke_wait_free(); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_wait_free failed, ret is 0x%x\n", ret); + ret = hal_pke_set_mode(HAL_PKE_MODE_MUL_MOD, max_len); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_set_mode failed, ret is 0x%x\n", ret); + + hal_pke_set_ram(PKE_MRAM, a->data, klen, max_len); + hal_pke_set_ram(PKE_KRAM, b->data, klen, max_len); + hal_pke_set_ram(PKE_NRAM, p->data, klen, max_len); + + hal_pke_start(); + ret = hal_pke_wait_done(); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_wait_done failed, ret is 0x%x\n", ret); + hal_pke_get_ram(PKE_RRAM, c->data, klen); + return TD_SUCCESS; +} + +static td_s32 drv_cipher_pke_inv_mod_param_chk(const drv_pke_data *a, const drv_pke_data *p, drv_pke_data *c) +{ + crypto_param_check(p == TD_NULL); + crypto_param_check(p->data == TD_NULL); + crypto_param_check(a == TD_NULL); + crypto_param_check(a->data == TD_NULL); + crypto_param_check(c == TD_NULL); + crypto_param_check(c->data == TD_NULL); + crypto_param_check(a->length != p->length); + crypto_param_check(a->length != c->length); + crypto_param_check(a->length != DRV_PKE_LEN_256 && a->length != DRV_PKE_LEN_384 && + a->length != DRV_PKE_LEN_512 && a->length != DRV_PKE_LEN_521); + return TD_SUCCESS; +} + +/* c = a ^ -1 mod p */ +td_s32 drv_cipher_pke_inv_mod(const drv_pke_data *a, const drv_pke_data *p, drv_pke_data *c) +{ + td_s32 ret = TD_FAILURE; + td_u32 klen = 0; + td_u32 max_len = 0; + ret = drv_cipher_pke_inv_mod_param_chk(a, p, c); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_pke_inv_mod_param_chk failed, ret is 0x%x\n", ret); + + klen = a->length; + + ret = hal_pke_align_len(klen, &max_len, HAL_ALIGN_LEN); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_align_len failed, ret is 0x%x\n", ret); + + ret = hal_pke_wait_free(); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_wait_free failed, ret is 0x%x\n", ret); + + ret = hal_pke_set_mode(HAL_PKE_MODE_MINV_MOD, max_len); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_set_mode failed, ret is 0x%x\n", ret); + + hal_pke_set_ram(PKE_MRAM, a->data, klen, max_len); + hal_pke_set_ram(PKE_KRAM, p->data, klen, max_len); + + hal_pke_start(); + + ret = hal_pke_wait_done(); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_wait_done failed, ret is 0x%x\n", ret); + + hal_pke_get_ram(PKE_RRAM, c->data, klen); + + return TD_SUCCESS; +} + +static td_s32 drv_cipher_pke_add_dot_param_chk(const drv_pke_ecc_curve *ecc, const drv_pke_ecc_point *s, + const drv_pke_ecc_point *r, const drv_pke_ecc_point *c) +{ + crypto_param_check(ecc->a == TD_NULL); + crypto_param_check(ecc->p == TD_NULL); + crypto_param_check(s == TD_NULL); + crypto_param_check(s->x == TD_NULL); + crypto_param_check(s->y == TD_NULL); + crypto_param_check(r == TD_NULL); + crypto_param_check(r->x == TD_NULL); + crypto_param_check(r->y == TD_NULL); + crypto_param_check(c == TD_NULL); + crypto_param_check(c->x == TD_NULL); + crypto_param_check(c->y == TD_NULL); + crypto_param_check(ecc->ksize != c->length); + crypto_param_check(ecc->ksize != s->length); + crypto_param_check(ecc->ksize != r->length); + crypto_param_check(ecc->ksize != DRV_PKE_LEN_256 && ecc->ksize != DRV_PKE_LEN_384 + && ecc->ksize != DRV_PKE_LEN_512 && ecc->ksize != DRV_PKE_LEN_521); + return TD_SUCCESS; +} + +/* C(x,y) = S(x,y) + R(x,y) */ +td_s32 drv_cipher_pke_add_dot(const drv_pke_ecc_curve *ecc, const drv_pke_ecc_point *s, const drv_pke_ecc_point *r, + const drv_pke_ecc_point *c) +{ + td_s32 ret = TD_FAILURE; + td_u32 klen = 0; + td_u32 max_len = 0; + td_u32 id = 0; + td_u32 ram_section_len = 0; + td_u32 set_key_len = 0; + ret = drv_cipher_pke_add_dot_param_chk(ecc, s, r, c); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_pke_add_dot_param_chk failed, ret is 0x%x\n", ret); + + klen = ecc->ksize; + + ret = hal_pke_align_len(0, &ram_section_len, HAL_RAM_SECTION_LEN); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_align_len failed, ret is 0x%x\n", ret); + ret = hal_pke_align_len(0, &set_key_len, HAL_SET_KEY_LEN); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_align_len failed, ret is 0x%x\n", ret); + ret = hal_pke_align_len(klen, &max_len, HAL_ALIGN_LEN); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_align_len failed, ret is 0x%x\n", ret); + + ret = hal_pke_wait_free(); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_wait_free failed, ret is 0x%x\n", ret); + + ret = hal_pke_set_mode(HAL_PKE_MODE_ADD_DOT, max_len); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_set_mode failed, ret is 0x%x\n", ret); + + hal_pke_set_ram(PKE_MRAM + (id++) * ram_section_len, s->x, klen, ram_section_len); + hal_pke_set_ram(PKE_MRAM + (id++) * ram_section_len, s->y, klen, ram_section_len); + hal_pke_set_ram(PKE_MRAM + (id++) * ram_section_len, r->x, klen, ram_section_len); + hal_pke_set_ram(PKE_MRAM + id * ram_section_len, r->y, klen, ram_section_len); + id = 2; // KRAM start form 2 ram_section + hal_pke_set_ram(PKE_KRAM + set_key_len + (id++) * ram_section_len, ecc->a, klen, ram_section_len); + hal_pke_set_ram(PKE_KRAM + set_key_len + (id++) * ram_section_len, ecc->p, klen, ram_section_len); + hal_pke_start(); + ret = hal_pke_wait_done(); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_wait_done failed, ret is 0x%x\n", ret); + + hal_pke_get_ram(PKE_RRAM, c->x, klen); + hal_pke_get_ram(PKE_RRAM + ram_section_len, c->y, klen); + + return TD_SUCCESS; +} + +static td_s32 drv_cipher_pke_mg_mul_dot_param_chk(const drv_pke_data *k, const drv_pke_data *U, const drv_pke_data *p, + const drv_pke_data *a24, const drv_pke_data *rx) +{ + crypto_param_check(k == TD_NULL); + crypto_param_check(k->data == TD_NULL); + crypto_param_check(U == TD_NULL); + crypto_param_check(U->data == TD_NULL); + crypto_param_check(p == TD_NULL); + crypto_param_check(p->data == TD_NULL); + crypto_param_check(a24 == TD_NULL); + crypto_param_check(a24->data == TD_NULL); + crypto_param_check(rx == TD_NULL); + crypto_param_check(rx->data == TD_NULL); + crypto_param_check(k->length != U->length); + crypto_param_check(k->length != p->length); + crypto_param_check(k->length != a24->length); + crypto_param_check(k->length != rx->length); + crypto_param_check(k->length != DRV_PKE_LEN_256); + return TD_SUCCESS; +} + +/* R = k * U(x) */ +td_s32 drv_cipher_pke_mg_mul_dot(const drv_pke_data *k, const drv_pke_data *U, const drv_pke_data *p, + const drv_pke_data *a24, const drv_pke_data *rx) +{ + td_s32 ret = TD_FAILURE; + pke_block random; + td_u32 klen = DRV_PKE_LEN_256; + td_u8 key[DRV_PKE_LEN_256] = {0}; + + ret = drv_cipher_pke_mg_mul_dot_param_chk(k, U, p, a24, rx); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_pke_mg_mul_dot_param_chk failed, ret is 0x%x\n", ret); + + ret = hal_pke_wait_free(); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_wait_free failed, ret is 0x%x\n", ret); + + ret = hal_pke_set_mode(HAL_PKE_MODE_MG_MUL_DOT, klen); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_set_mode failed, ret is 0x%x\n", ret); + + ret = drv_cipher_trng_get_random(&random.word[0]); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_trng_get_random failed, ret is 0x%x\n", ret); + + hal_pke_set_key(k->data, key, klen, &random, klen); + hal_pke_set_ram(PKE_MRAM, U->data, klen, klen); + hal_pke_set_ram(PKE_MG_A24, a24->data, klen, klen); + hal_pke_set_ram(PKE_KRAM, p->data, klen, klen); + hal_pke_set_ram(PKE_MG_K, key, klen, klen); + + hal_pke_start(); + + ret = hal_pke_wait_done(); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_wait_done failed, ret is 0x%x\n", ret); + hal_pke_get_ram(PKE_RRAM, rx->data, klen); + return TD_SUCCESS; +} + +static td_s32 drv_cipher_pke_ed_mul_dot_param_chk(const drv_pke_data *k, const drv_pke_ecc_point *U, + const drv_pke_data *p, const drv_pke_ecc_point *r) +{ + crypto_param_check(k == TD_NULL); + crypto_param_check(k->data == TD_NULL); + crypto_param_check(U == TD_NULL); + crypto_param_check(U->x == TD_NULL); + crypto_param_check(U->y == TD_NULL); + crypto_param_check(p == TD_NULL); + crypto_param_check(p->data == TD_NULL); + crypto_param_check(r == TD_NULL); + crypto_param_check(r->x == TD_NULL); + crypto_param_check(r->y == TD_NULL); + crypto_param_check(k->length != DRV_PKE_LEN_256); + crypto_param_check(U->length != DRV_PKE_LEN_256); + crypto_param_check(p->length != DRV_PKE_LEN_256); + crypto_param_check(r->length != DRV_PKE_LEN_256); + return TD_SUCCESS; +} + +/* R = k * U(x,y) */ +td_s32 drv_cipher_pke_ed_mul_dot(const drv_pke_data *k, const drv_pke_ecc_point *U, const drv_pke_data *p, + const drv_pke_ecc_point *r) +{ + td_s32 ret = TD_FAILURE; + pke_block random; + td_u32 klen = DRV_PKE_LEN_256; + td_u8 key[DRV_PKE_LEN_256] = {0}; + + ret = drv_cipher_pke_ed_mul_dot_param_chk(k, U, p, r); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_pke_ed_mul_dot_param_chk failed, ret is 0x%x\n", ret); + + ret = hal_pke_wait_free(); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_wait_free failed, ret is 0x%x\n", ret); + + ret = hal_pke_set_mode(HAL_PKE_MODE_ED_MUL_DOT, klen); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_set_mode failed, ret is 0x%x\n", ret); + + ret = drv_cipher_trng_get_random(&random.word[0]); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_trng_get_random failed, ret is 0x%x\n", ret); + ret = drv_cipher_trng_get_random(&random.word[1]); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_trng_get_random failed, ret is 0x%x\n", ret); + + hal_pke_set_key(k->data, key, klen, &random, klen); + + hal_pke_set_ram(PKE_ED_MRAM(0), U->x, klen, klen); + hal_pke_set_ram(PKE_ED_MRAM(1), U->y, klen, klen); + hal_pke_set_ram(PKE_ED_PD, g_ed_pd, klen, klen); + hal_pke_set_ram(PKE_KRAM, p->data, klen, klen); + hal_pke_set_ram(PKE_ED_K, key, klen, klen); + + hal_pke_start(); + + ret = hal_pke_wait_done(); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_wait_done failed, ret is 0x%x\n", ret); + + hal_pke_get_ram(PKE_ED_RRAM(0), r->x, klen); + hal_pke_get_ram(PKE_ED_RRAM(1), r->y, klen); + return TD_SUCCESS; +} + +static td_s32 drv_cipher_pke_ed_add_dot_param_chk(const drv_pke_ecc_curve *ecc, const drv_pke_ecc_point *s, + const drv_pke_ecc_point *r, const drv_pke_ecc_point *c) +{ + crypto_param_check(ecc == TD_NULL); + crypto_param_check(ecc->a == TD_NULL); + crypto_param_check(ecc->p == TD_NULL); + crypto_param_check(s == TD_NULL); + crypto_param_check(s->x == TD_NULL); + crypto_param_check(s->y == TD_NULL); + crypto_param_check(r == TD_NULL); + crypto_param_check(r->x == TD_NULL); + crypto_param_check(r->y == TD_NULL); + crypto_param_check(c == TD_NULL); + crypto_param_check(c->x == TD_NULL); + crypto_param_check(c->y == TD_NULL); + crypto_param_check(ecc->ksize != DRV_PKE_LEN_256); + return TD_SUCCESS; +} + +/* brief: C = S(x,y) + R(x,y) for Ed25519 curve */ +td_s32 drv_cipher_pke_ed_add_dot(const drv_pke_ecc_curve *ecc, const drv_pke_ecc_point *s, + const drv_pke_ecc_point *r, const drv_pke_ecc_point *c) +{ + td_s32 ret = TD_FAILURE; + td_u32 ram_section_len = 0; + td_u32 klen = DRV_PKE_LEN_256; + ret = drv_cipher_pke_ed_add_dot_param_chk(ecc, s, r, c); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_pke_ed_add_dot_param_chk failed, ret is 0x%x\n", ret); + + ret = hal_pke_align_len(0, &ram_section_len, HAL_RAM_SECTION_LEN); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_align_len failed, ret is 0x%x\n", ret); + + ret = hal_pke_wait_free(); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_wait_free failed, ret is 0x%x\n", ret); + + ret = hal_pke_set_mode(HAL_PKE_MODE_ED_ADD_DOT, klen); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_set_mode failed, ret is 0x%x\n", ret); + + hal_pke_set_ram(PKE_ED_MRAM(0), s->x, klen, ram_section_len); // 0: slot0 + hal_pke_set_ram(PKE_ED_MRAM(1), s->y, klen, ram_section_len); // 1: slot1 + hal_pke_set_ram(PKE_ED_NRAM(0), r->x, klen, ram_section_len); // 0: slot0 + hal_pke_set_ram(PKE_ED_NRAM(1), r->y, klen, ram_section_len); // 1: slot1 + hal_pke_set_ram(PKE_ED_NRAM(2), g_ed_pd, klen, ram_section_len); // 2: slot2 + hal_pke_set_ram(PKE_KRAM, ecc->p, klen, ram_section_len); + + hal_pke_start(); + + ret = hal_pke_wait_done(); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_wait_done failed, ret is 0x%x\n", ret); + + hal_pke_get_ram(PKE_ED_RRAM(0), c->x, DRV_PKE_LEN_256); // 0: slot0 + hal_pke_get_ram(PKE_ED_RRAM(1), c->y, DRV_PKE_LEN_256); // 1: slot1 + + return TD_SUCCESS; +} + +static crypto_hash_type drv_pke_get_hash_type(drv_pke_hash_type hash_type) +{ + switch (hash_type) { + case DRV_PKE_HASH_TYPE_SHA224: + return CRYPTO_HASH_TYPE_SHA224; + case DRV_PKE_HASH_TYPE_SHA256: + return CRYPTO_HASH_TYPE_SHA256; + case DRV_PKE_HASH_TYPE_SHA384: + return CRYPTO_HASH_TYPE_SHA384; + case DRV_PKE_HASH_TYPE_SHA512: + return CRYPTO_HASH_TYPE_SHA512; + case DRV_PKE_HASH_TYPE_SM3: + return CRYPTO_HASH_TYPE_SM3; + default: + return CRYPTO_HASH_TYPE_INVALID; + } +} + +td_s32 drv_cipher_pke_calc_hash(const drv_pke_data* arr, td_u32 arr_len, + const drv_pke_hash_type hash_type, drv_pke_data *hash) +{ + td_s32 ret = TD_FAILURE; + td_handle h_handle = 0; + crypto_buf_attr src_buf = {0}; + td_u32 i; + crypto_hash_type hash_alg; + crypto_hash_attr hash_attr; + crypto_param_check(arr == TD_NULL); + crypto_param_check(hash == TD_NULL); + crypto_param_check(hash->data == TD_NULL); + + hash_alg = drv_pke_get_hash_type(hash_type); + if (hash_alg == CRYPTO_HASH_TYPE_INVALID) { + return PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM); + } + hash_attr = (crypto_hash_attr){.hash_type = hash_alg}; + + ret = drv_cipher_hash_start(&h_handle, &hash_attr); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_hash_start failed, ret is 0x%x\n", ret); + + for (i = 0;i < arr_len; i++) { + src_buf.virt_addr = arr[i].data; + ret = drv_cipher_hash_update(h_handle, &src_buf, arr[i].length); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_hash_update failed, ret is 0x%x\n", ret); + } + ret = drv_cipher_hash_finish(h_handle, hash->data, &(hash->length)); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_hash_finish failed, ret is 0x%x\n", ret); + return TD_SUCCESS; +exit__: + (void)drv_cipher_hash_destroy(h_handle); + return ret; +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_pke_ecc.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_pke_ecc.c new file mode 100644 index 00000000..c524cbf2 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_pke_ecc.c @@ -0,0 +1,2235 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "hal_pke.h" +#include "drv_pke.h" +#include "crypto_hash_struct.h" +#include "crypto_ecc_curve.h" +#include "securec.h" +#include "drv_hash.h" +#include "drv_trng.h" +#include "crypto_drv_common.h" +#include "drv_inner.h" + +#define PKE_COMPAT_ERRNO(err_code) DISPATCH_COMPAT_ERRNO(ERROR_MODULE_PKE, err_code) + +#define pke_null_ptr_chk(ptr) \ + crypto_chk_return((ptr) == TD_NULL, PKE_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), #ptr" is NULL\n") + +#define ED25519_MAX_HASH_ELEMENTS 3 +#define SM2_CRYPTO_ADD_LENGTH_IN_BYTE 97 // 97 = SM2_LEN + SM2_LEN + SM3_LEN + 1 +#define ECC_CHECK_DOT_BUF_CNT 11 +#define SM2_SIGN_BUF_CNT 19 +#define SM2_VERIFY_BUF_CNT 10 +#define ECDSA_SIGN_BUF_CNT 15 +#define ECDSA_VERIFY_BUF_CNT 19 +#define GENERATE_X_BUF_CNT 13 +#define POINT_DECOMPRESS_BUF_CNT 13 +#define EDDSA_SIGN_BUF_CNT 14 +#define EDDSA_VERIFY_BUF_CNT 12 +#define RANDNUM_TRY_TIMES 20 + +typedef enum { + // need buffer + CHECKDOT_MONTGOMERY_P = 0, + CHECKDOT_MX, + CHECKDOT_MX2, + CHECKDOT_MX3, + CHECKDOT_MA, + CHECKDOT_MAX, + CHECKDOT_MB, + CHECKDOT_MY, + CHECKDOT_MY2, + CHECKDOT_MX3_MAX, + CHECKDOT_MX3_MAX_MB, + // no need buffer + CHECKDOT_ECC_P, + CHECKDOT_ECC_A, + CHECKDOT_ECC_B, + CHECKDOT_X, + CHECKDOT_Y, + PKE_CHECK_DOT_ON_CURVE_VAR_MAX +} pke_check_dot_on_curve_var; + +typedef enum { + // need buffer + SM2SIGN_E = 0, + SM2SIGN_MONTGOMERY_N, + SM2SIGN_K, + SM2SIGN_R_X, + SM2SIGN_R_Y, + SM2SIGN_RK, + SM2SIGN_MY, + SM2SIGN_MR, + SM2SIGN_MS, + SM2SIGN_MK, + SM2SIGN_MRK, + SM2SIGN_MRKY, + SM2SIGN_TA, + SM2SIGN_MTA, + SM2SIGN_MTY, + SM2SIGN_MTZ, + SM2SIGN_MINV, + SM2SIGN_ZERO, + SM2SIGN_ONE, + // no need buffer + SM2SIGN_SM2_N, + SM2SIGN_SIG_R, + SM2SIGN_SIG_S, + PKE_SM2_SIGN_VAR_MAX +} pke_sm2_sign_var; + +typedef enum { + // need buffer + SM2VERIFY_T = 0, + SM2VERIFY_E, + SM2VERIFY_V, + SM2VERIFY_S_GX, + SM2VERIFY_S_GY, + SM2VERIFY_T_PAX, + SM2VERIFY_T_PAY, + SM2VERIFY_RX, + SM2VERIFY_RY, + SM2VERIFY_ZERO, + // no need buffer + SM2VERIFY_SM2_N, + SM2VERIFY_SIG_R, + SM2VERIFY_SIG_S, + PKE_SM2_VERIFY_VAR_MAX +} pke_sm2_verify_var; + +typedef enum { + // need buffer + ECCSIGN_K = 0, + ECCSIGN_E, + ECCSIGN_RX, + ECCSIGN_RY, + ECCSIGN_MONTGOMERY_N, + ECCSIGN_ME, + ECCSIGN_MR, + ECCSIGN_MS, + ECCSIGN_MD, + ECCSIGN_MRD, + ECCSIGN_MK, + ECCSIGN_MKNI, + ECCSIGN_Y, + ECCSIGN_ZERO, + ECCSIGN_ONE, + // no need buffer + ECCSIGN_ECC_N, + ECCSIGN_SIG_R, + ECCSIGN_SIG_S, + ECCSIGN_HASH, + PKE_ECDSA_SIGN_VAR_MAX +} pke_ecdsa_sign_var; + +typedef enum { + // need buffer + ECCVERIFY_E = 0, + ECCVERIFY_V, + ECCVERIFY_U1, + ECCVERIFY_U2, + ECCVERIFY_ME, + ECCVERIFY_MS, + ECCVERIFY_MR, + ECCVERIFY_MSNI, + ECCVERIFY_MU1, + ECCVERIFY_MU2, + ECCVERIFY_RX, + ECCVERIFY_RY, + ECCVERIFY_U1X, + ECCVERIFY_U1Y, + ECCVERIFY_U2X, + ECCVERIFY_U2Y, + ECCVERIFY_MONTGOMERY_N, + ECCVERIFY_ZERO, + ECCVERIFY_ONE, + // no need buffer + ECCVERIFY_ECC_N, + ECCVERIFY_SIG_R, + ECCVERIFY_SIG_S, + ECCVERIFY_HASH, + PKE_ECDSA_VERIFY_VAR_MAX +} pke_ecdsa_verify_var; + +typedef enum { + // need buffer + GENERATEX_MAX = 0, + GENERATEX_P38, + GENERATEX_XX, + GENERATEX_C, + GENERATEX_P14, + GENERATEX_S, + GENERATEX_MONTGOMERY_P, + GENERATEX_MX, + GENERATEX_MS, + GENERATEX_MXS, + GENERATEX_ONE, + GENERATEX_TWO, + GENERATEX_THREE, + // no need buffer + GENERATEX_ECC_P, + GENERATEX_X, + GENERATEX_X2, + GENERATE_X_VAR_MAX +} generate_x_var; + +typedef enum { + // need buffer + POINTDECOMPRESS_MONTGOMERY_P = 0, + POINTDECOMPRESS_MY, + POINTDECOMPRESS_MY2, + POINTDECOMPRESS_MY21, + POINTDECOMPRESS_MD, + POINTDECOMPRESS_MDY2, + POINTDECOMPRESS_MDY21, + POINTDECOMPRESS_MINV, + POINTDECOMPRESS_X, + POINTDECOMPRESS_X2, + POINTDECOMPRESS_MX2, + POINTDECOMPRESS_ONE, + POINTDECOMPRESS_MONE, + // no need buffer + POINTDECOMPRESS_ECC_P, + POINTDECOMPRESS_ECC_A, + POINTDECOMPRESS_OUTX, + POINTDECOMPRESS_OUTY, + POINT_DECOMPRESS_VAR_MAX +} point_decompress_var; + +typedef enum { + // need buffer + EDDSIGN_A = 0, + EDDSIGN_PREFIX, + EDDSIGN_PUBKEY, + EDDSIGN_R, + EDDSIGN_S, + EDDSIGN_RS, + EDDSIGN_H, + EDDSIGN_MONTGOMERY_N, + EDDSIGN_MH, + EDDSIGN_MA, + EDDSIGN_MHA, + EDDSIGN_MR, + EDDSIGN_MS, + EDDSIGN_ONE, + // no need buffer + EDDSIGN_ECC_N, + EDDSIGN_MSG, + PKE_EDDSA_SIGN_VAR_MAX +} pke_eddsa_sign_var; + +/* + * generate randnum. if max != TD_NULL. then randnum will < max + */ +static td_s32 get_randnum(td_u8 *randnum, td_u8 *max, td_u32 klen) +{ + td_s32 ret = TD_FAILURE; + td_u32 i; + td_u32 index; + + if (max == NULL) { + return drv_cipher_trng_get_multi_random(klen, randnum); + } + + for (index = 0; index < klen && max[index] == 0; ++index) {} + + if (index == klen) { + return TD_FAILURE; + } + + (void)memset_s(randnum, klen, 0, klen); + + randnum[index] = max[index]; + + for (i = 0; i < RANDNUM_TRY_TIMES; i++) { + ret = drv_cipher_trng_get_multi_random(klen - index - 1, randnum + index + 1); + if (ret != TD_SUCCESS) { + crypto_log_err("drv_cipher_trng_get_multi_random failed, ret is 0x%x\n", ret); + return ret; + } + + if (memcmp(randnum, max, klen) < 0) { + return TD_SUCCESS; + } + } + + crypto_log_err("%s:%d Error! Can't gen randnum < max in %d times!\n", __FUNCTION__, __LINE__, RANDNUM_TRY_TIMES); + return TD_FAILURE; +} + +/* check val =? zero */ +static td_bool drv_ecc_is_zero(const td_u8 *val, td_u32 klen) +{ + td_u32 i = 0; + for (i = 0; i < klen; i++) { + if (val[i] != 0x00) { + return TD_FALSE; + } + } + return TD_TRUE; +} + +/* check 0 < val < max */ +static td_s32 drv_range_check(const td_u8 *val, const td_u8 *max, td_u32 klen) +{ + if (drv_ecc_is_zero(val, klen)) { + return PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM); + } + + if (memcmp(val, max, klen) < 0) { + return TD_SUCCESS; + } + return TD_FAILURE; +} + +/* + * montgomery_n = (r ^ 2 mod mod_n) = (2 ^ (2 * klen) mod mod_n) + */ +static td_s32 cal_montgomery_n(const drv_pke_data *mod_n, const drv_pke_data *montgomery_n) +{ + td_s32 ret = TD_FAILURE; + td_u32 klen = 0; + td_u32 max_len = 0; + td_u32 r2_len; + td_u8 *r2; + drv_pke_data r2_data; + + klen = mod_n->length; + // for some chips, the 512 length needs to be aligned into 521 length + ret = hal_pke_align_len(klen, &max_len, HAL_ALIGN_LEN); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_pke_align_len failed, ret is 0x%x\n", ret); + // r_len = 2k_len + 1 + r2_len = 2 * max_len + 1; // 2 : see comment above + r2 = crypto_malloc(r2_len); + if (r2 == TD_NULL) { + crypto_log_err("%s:%d Error! Malloc memory failed!\n", __FUNCTION__, __LINE__); + return PKE_COMPAT_ERRNO(ERROR_MALLOC); + } + (void)memset_s(r2, r2_len, 0, r2_len); + r2[0] = 1; + r2_data = (drv_pke_data){r2_len, r2}; + ret = drv_cipher_pke_mod(&r2_data, mod_n, montgomery_n); + (void)memset_s(r2, r2_len, 0, r2_len); + crypto_free(r2); + return ret; +} + +/* + * check point->y ^ 2 ?= point->x ^ 3 + ecc->a * point->x + ecc->b + */ +static td_s32 pke_check_dot_on_curve(const drv_pke_ecc_curve *ecc, const drv_pke_ecc_point *point, td_bool *is_on_curve) +{ + td_s32 ret = TD_FAILURE; + td_u32 i; + drv_pke_data var_arr[PKE_CHECK_DOT_ON_CURVE_VAR_MAX]; + td_u8 *buffer; + + buffer = crypto_malloc(ecc->ksize * ECC_CHECK_DOT_BUF_CNT); + crypto_chk_return(buffer == TD_NULL, PKE_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + (void)memset_s(buffer, ecc->ksize * ECC_CHECK_DOT_BUF_CNT, 0, ecc->ksize * ECC_CHECK_DOT_BUF_CNT); + + for (i = 0; i < PKE_CHECK_DOT_ON_CURVE_VAR_MAX; i++) { + if (i <= CHECKDOT_MX3_MAX_MB) { + var_arr[i].data = buffer + ecc->ksize * i; + } + var_arr[i].length = ecc->ksize; + } + var_arr[CHECKDOT_ECC_P].data = (td_u8 *)ecc->p; + var_arr[CHECKDOT_ECC_A].data = (td_u8 *)ecc->a; + var_arr[CHECKDOT_ECC_B].data = (td_u8 *)ecc->b; + var_arr[CHECKDOT_X].data = point->x; + var_arr[CHECKDOT_Y].data = point->y; + + // Step 1: N = r^2 mod p where N is montgomery multiplier + ret = cal_montgomery_n(&var_arr[CHECKDOT_ECC_P], &var_arr[CHECKDOT_MONTGOMERY_P]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "cal_montgomery_n failed, ret is 0x%x\n", ret); + + /* Step 1: mx = point->x * N mod p */ + ret = drv_cipher_pke_mul_mod(&var_arr[CHECKDOT_X], &var_arr[CHECKDOT_MONTGOMERY_P], &var_arr[CHECKDOT_ECC_P], + &var_arr[CHECKDOT_MX]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + /* Step 2: my = point->y * N mod p */ + ret = drv_cipher_pke_mul_mod(&var_arr[CHECKDOT_Y], &var_arr[CHECKDOT_MONTGOMERY_P], &var_arr[CHECKDOT_ECC_P], + &var_arr[CHECKDOT_MY]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + /* Step 3: mx2 = mx * mx mod p */ + ret = drv_cipher_pke_mul_mod(&var_arr[CHECKDOT_MX], &var_arr[CHECKDOT_MX], &var_arr[CHECKDOT_ECC_P], + &var_arr[CHECKDOT_MX2]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + /* Step 4: mx3 = mx2 * mx mod p */ + ret = drv_cipher_pke_mul_mod(&var_arr[CHECKDOT_MX2], &var_arr[CHECKDOT_MX], &var_arr[CHECKDOT_ECC_P], + &var_arr[CHECKDOT_MX3]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + /* Step 5: ma = a * N mod p */ + ret = drv_cipher_pke_mul_mod(&var_arr[CHECKDOT_ECC_A], &var_arr[CHECKDOT_MONTGOMERY_P], &var_arr[CHECKDOT_ECC_P], + &var_arr[CHECKDOT_MA]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + /* Step 6: max = ma * mx mod p */ + ret = drv_cipher_pke_mul_mod(&var_arr[CHECKDOT_MA], &var_arr[CHECKDOT_MX], &var_arr[CHECKDOT_ECC_P], + &var_arr[CHECKDOT_MAX]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + /* Step 7: mx3_max = mx3 + max mod p */ + ret = drv_cipher_pke_add_mod(&var_arr[CHECKDOT_MX3], &var_arr[CHECKDOT_MAX], &var_arr[CHECKDOT_ECC_P], + &var_arr[CHECKDOT_MX3_MAX]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_add_mod failed, ret is 0x%x\n", ret); + + /* Step 8: mb = b * N mod p */ + ret = drv_cipher_pke_mul_mod(&var_arr[CHECKDOT_ECC_B], &var_arr[CHECKDOT_MONTGOMERY_P], &var_arr[CHECKDOT_ECC_P], + &var_arr[CHECKDOT_MB]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + /* Step 9: mx3_max_mb = mx3_max + mb mod p */ + ret = drv_cipher_pke_add_mod(&var_arr[CHECKDOT_MX3_MAX], &var_arr[CHECKDOT_MB], &var_arr[CHECKDOT_ECC_P], + &var_arr[CHECKDOT_MX3_MAX_MB]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_add_mod failed, ret is 0x%x\n", ret); + + /* Step 10: my2 = my * my mod p */ + ret = drv_cipher_pke_mul_mod(&var_arr[CHECKDOT_MY], &var_arr[CHECKDOT_MY], &var_arr[CHECKDOT_ECC_P], + &var_arr[CHECKDOT_MY2]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + /* Step 11: my2 ?= mx3_max_mb */ + *is_on_curve = memcmp(var_arr[CHECKDOT_MY2].data, var_arr[CHECKDOT_MX3_MAX_MB].data, ecc->ksize) == 0; + +exit__: + (void)drv_cipher_pke_clean_ram(); + if (buffer != TD_NULL) { + (void)memset_s(buffer, ecc->ksize * ECC_CHECK_DOT_BUF_CNT, 0, ecc->ksize * ECC_CHECK_DOT_BUF_CNT); + crypto_free(buffer); + } + return ret; +} + +static td_s32 sm2_encrypt_decrypt_hash(const drv_pke_ecc_point *param, const drv_pke_data *msg, drv_pke_data *hash) +{ + td_s32 ret = TD_FAILURE; + drv_pke_data arr[3]; // The capacity of the array is 3. + + arr[0].data = param->x; + arr[0].length = DRV_PKE_SM2_LEN_IN_BYTES; + arr[1].data = msg->data; + arr[1].length = msg->length; + arr[2].data = param->y; // 2 is data of the 3th element + arr[2].length = DRV_PKE_SM2_LEN_IN_BYTES; // 2 is data of the 3th element + + /* C3 = SM3( x2 || M || y2 ) */ + ret = drv_cipher_pke_calc_hash(arr, sizeof(arr) / sizeof(arr[0]), DRV_PKE_HASH_TYPE_SM3, hash); + return ret; +} + +static td_s32 sm2_kdf(const drv_pke_ecc_point *param, td_u8 *out, const td_u32 klen) +{ + td_s32 ret = TD_FAILURE; + td_u32 block = 0; + td_u32 i = 0; + td_u32 ct = 0; + drv_pke_data arr[3]; // The capacity of the array is 3. + td_u8 h[DRV_PKE_SM2_LEN_IN_BYTES] = {0}; + drv_pke_data hash = {DRV_PKE_SM2_LEN_IN_BYTES, h}; + + arr[0].data = param->x; + arr[0].length = DRV_PKE_SM2_LEN_IN_BYTES; + arr[1].data = param->y; + arr[1].length = DRV_PKE_SM2_LEN_IN_BYTES; + arr[2].data = (td_u8 *)&ct; // 2 is data of the 3th element + arr[2].length = sizeof(ct); // 2 is data of the 3th element + if (klen == 0) { + return TD_SUCCESS; + } + + block = (klen + DRV_PKE_SM2_LEN_IN_BYTES - 1) / DRV_PKE_SM2_LEN_IN_BYTES; + for (i = 0; i < block; i++) { + ct = crypto_cpu_to_be32(i + 1); + /* H = SM3( X || Y || CT ) */ + ret = drv_cipher_pke_calc_hash(arr, sizeof(arr) / sizeof(arr[0]), DRV_PKE_HASH_TYPE_SM3, &hash); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_pke_calc_hash failed, ret is 0x%x\n", ret); + + if (i == (block - 1)) { + ret = memcpy_s(out + i * DRV_PKE_SM2_LEN_IN_BYTES, klen - i * DRV_PKE_SM2_LEN_IN_BYTES, h, + klen - i * DRV_PKE_SM2_LEN_IN_BYTES); + crypto_chk_return(ret != TD_SUCCESS, ret, "memcpy_s failed, ret is 0x%x\n", ret); + } else { + ret = memcpy_s(out + i * DRV_PKE_SM2_LEN_IN_BYTES, klen - i * DRV_PKE_SM2_LEN_IN_BYTES, h, + DRV_PKE_SM2_LEN_IN_BYTES); + crypto_chk_return(ret != TD_SUCCESS, ret, "memcpy_s failed, ret is 0x%x\n", ret); + } + } + if (drv_ecc_is_zero(out, klen)) { + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +static td_s32 pke_sm2_public_encrypt(const drv_pke_ecc_point *pub_key, const drv_pke_data *plain_text, + drv_pke_data *cipher_text) +{ + // declaration and assignment of variables and parameter verification + td_s32 ret = TD_FAILURE; + td_u32 klen = DRV_PKE_SM2_LEN_IN_BYTES; + td_u32 c1_index = 1; + td_u32 c3_index = c1_index + klen * 2; // 2 : see the start position of algorithm C3. + td_u32 c2_index = c1_index + klen * 3; // 3 : see the start position of algorithm C2. + td_u32 i = 0; + td_u8 k[DRV_PKE_SM2_LEN_IN_BYTES] = {0}; + td_u8 C1x[DRV_PKE_SM2_LEN_IN_BYTES] = {0}; + td_u8 C1y[DRV_PKE_SM2_LEN_IN_BYTES] = {0}; + td_u8 kPBx[DRV_PKE_SM2_LEN_IN_BYTES] = {0}; + td_u8 kPBy[DRV_PKE_SM2_LEN_IN_BYTES] = {0}; + td_u8 *t = cipher_text->data + c2_index; + drv_pke_data k_data = {klen, k}; + drv_pke_data C3_data = {klen, cipher_text->data + c3_index}; + drv_pke_ecc_point C1_point = {C1x, C1y, klen}; + drv_pke_ecc_point kPB_point = {kPBx, kPBy, klen}; + drv_pke_ecc_point sm2_gpoint; + const drv_pke_ecc_curve *sm2 = get_ecc_curve(DRV_PKE_ECC_TYPE_SM2); + crypto_chk_return(sm2 == TD_NULL, PKE_COMPAT_ERRNO(ERROR_UNSUPPORT), "unsupport alg\n"); + + sm2_gpoint = (drv_pke_ecc_point){(td_u8 *)sm2->gx, (td_u8 *)sm2->gy, klen}; + (void)memset_s(cipher_text->data, cipher_text->length, 0, cipher_text->length); + // the beginning of the algorithm + cipher_text->data[0] = SM2_PC_UNCOMPRESS; + + for (i = 0; i < ECC_TRY_CNT; i++) { + /* Step 1: random k */ + ret = get_randnum(k_data.data, (td_u8 *)sm2->n, sm2->ksize); + crypto_chk_return(ret != TD_SUCCESS, ret, "get_randnum failed, ret is 0x%x\n", ret); + + /* Step 2: C1 = k * G */ + ret = drv_cipher_pke_mul_dot(sm2, &k_data, &sm2_gpoint, &C1_point); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_dot failed, ret is 0x%x\n", ret); + + /* Step 3: kPB = k * PB */ + ret = drv_cipher_pke_mul_dot(sm2, &k_data, pub_key, &kPB_point); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_dot failed, ret is 0x%x\n", ret); + + /* Step 4: t = kdf( kPBx || kPBy, plain_text->length ) */ + ret = sm2_kdf(&kPB_point, t, plain_text->length); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "sm2_kdf failed, ret is 0x%x\n", ret); + + /* Step 5: t ?= 0 */ + if (drv_ecc_is_zero(t, plain_text->length) != TD_TRUE) { + break; + } + } + if (i == ECC_TRY_CNT) { + crypto_log_err("%s:%d Error! Can't gen t in %d times!\n", __FUNCTION__, __LINE__, ECC_TRY_CNT); + ret = PKE_COMPAT_ERRNO(ERROR_TRY_TIMES); + goto exit__; + } + ret = memcpy_s(cipher_text->data + c1_index, cipher_text->length - c1_index, C1_point.x, klen); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "memcpy_s failed, ret is 0x%x\n", ret); + + ret = memcpy_s(cipher_text->data + c1_index + klen, cipher_text->length - c1_index - klen, C1_point.y, klen); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "memcpy_s failed, ret is 0x%x\n", ret); + + for (i = 0; i < plain_text->length; i++) { + *(t + i) ^= *(plain_text->data + i); + } + ret = sm2_encrypt_decrypt_hash(&kPB_point, plain_text, &C3_data); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "sm2_encrypt_decrypt_hash failed, ret is 0x%x\n", ret); + +exit__: + (void)drv_cipher_pke_clean_ram(); + return ret; +} + +static td_s32 pke_sm2_private_decrypt( + const drv_pke_data *priv_key, + const drv_pke_data *cipher_text, + const drv_pke_data *plain_text) +{ + td_s32 ret = TD_FAILURE; + td_u32 klen = DRV_PKE_SM2_LEN_IN_BYTES; + td_u32 c1_index = 1; + td_u32 c2_index = c1_index + klen * 3; // 3 : see the start position of algorithm C2. + td_u32 c3_index = c1_index + klen * 2; // 2 : see the start position of algorithm C3. + td_u32 i = 0; + td_bool is_on_curve = TD_FALSE; + td_u8 u[DRV_PKE_SM2_LEN_IN_BYTES]; + td_u8 C1x[DRV_PKE_SM2_LEN_IN_BYTES]; + td_u8 C1y[DRV_PKE_SM2_LEN_IN_BYTES]; + td_u8 x2[DRV_PKE_SM2_LEN_IN_BYTES]; + td_u8 y2[DRV_PKE_SM2_LEN_IN_BYTES]; + drv_pke_data u_data = {klen, u}; + drv_pke_data plain_data; + const drv_pke_ecc_point C1_point = {C1x, C1y, klen}; + const drv_pke_ecc_point dBC1_point = {x2, y2, klen}; + const drv_pke_ecc_curve *sm2 = get_ecc_curve(DRV_PKE_ECC_TYPE_SM2); + crypto_chk_return(sm2 == TD_NULL, PKE_COMPAT_ERRNO(ERROR_UNSUPPORT), "unsupport alg\n"); + + crypto_param_check(cipher_text->data[0] != SM2_PC_UNCOMPRESS); + plain_data = (drv_pke_data){cipher_text->length - SM2_CRYPTO_ADD_LENGTH_IN_BYTE, plain_text->data}; + + ret = memcpy_s(C1x, sizeof(C1x), cipher_text->data + c1_index, klen); + crypto_chk_return(ret != TD_SUCCESS, ret, "memcpy_s failed, ret is 0x%x\n", ret); + ret = memcpy_s(C1y, sizeof(C1y), cipher_text->data + c1_index + klen, klen); + crypto_chk_return(ret != TD_SUCCESS, ret, "memcpy_s failed, ret is 0x%x\n", ret); + + /* Step 1: check C1x, C1y on curve */ + ret = pke_check_dot_on_curve(sm2, &C1_point, &is_on_curve); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "pke_check_dot_on_curve failed, ret is 0x%x\n", ret); + crypto_chk_goto(is_on_curve != TD_TRUE, exit__, "pke_check_dot_on_curve failed, ret is 0x%x\n", ret); + + /* Step 2: (x2, y2) = dB * C1 */ + ret = drv_cipher_pke_mul_dot(sm2, priv_key, &C1_point, &dBC1_point); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_dot failed, ret is 0x%x\n", ret); + + /* Step 3: check x2, y2 on curve */ + ret = pke_check_dot_on_curve(sm2, &dBC1_point, &is_on_curve); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "pke_check_dot_on_curve failed, ret is 0x%x\n", ret); + crypto_chk_goto(is_on_curve != TD_TRUE, exit__, + "pke_check_dot_on_curve failed, is_on_curve is 0x%x\n", is_on_curve); + + ret = sm2_kdf(&dBC1_point, plain_data.data, plain_data.length); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "sm2_kdf failed, ret is 0x%x\n", ret); + + if (drv_ecc_is_zero(plain_data.data, plain_data.length)) { + crypto_log_err("%s:%d Error! Can't gen t in %d times!\n", __FUNCTION__, __LINE__, ECC_TRY_CNT); + ret = PKE_COMPAT_ERRNO(ERROR_PKE_SM2_DECRYPT); + goto exit__; + } + + for (i = 0; i < plain_data.length; i++) { + *(plain_data.data + i) ^= *(cipher_text->data + c2_index + i); + } + + ret = sm2_encrypt_decrypt_hash(&dBC1_point, &plain_data, &u_data); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "sm2_encrypt_decrypt_hash failed, ret is 0x%x\n", ret); + + ret = memcmp(cipher_text->data + c3_index, u, DRV_PKE_SM2_LEN_IN_BYTES); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "memcmp failed, ret is 0x%x\n", ret); +exit__: + (void)drv_cipher_pke_clean_ram(); + return ret; +} + +/* Decode the private key for X25519 curve */ +static td_void decode_priv_key(td_u8 *output_key, const td_u8 *input_key, td_u32 klen) +{ + td_u32 i = 0; + /* Step 1: Do byte reverse on input_key */ + for (i = 0; i < klen; i++) { + output_key[i] = input_key[klen - 1 - i]; + } + + /* Step 2: the priv_key[255], priv_key[254], priv_key[2], priv_key[1], priv_key[0] must be 0,1,0,0,0 */ + output_key[klen - 1] = output_key[klen - 1] & 0xF8; // 0xF8 : see comment above + output_key[0] = output_key[0] & 0x7F; // 0x7F : see comment above + output_key[0] = output_key[0] | 0x40; // 0x40 : see commnet above + return; +} + +/* Decode the public key for X25519 curve */ +static td_void decode_pub_key(td_u8 *output_key, const td_u8 *input_key, td_u32 klen) +{ + td_u32 i = 0; + /* Step 1: Do byte reverse on input_key */ + for (i = 0; i < klen; i++) { + output_key[i] = input_key[klen - 1 - i]; + } + /* Step 2: the pub_key[255] must be 0 */ + output_key[0] = output_key[0] & 0x7F; // 0x7F : see comment above + return; +} + +static td_s32 secret_expand(const td_u8 *secret, td_u8 *a, td_u8 *prefix, const td_u32 len) +{ + td_s32 ret = TD_FAILURE; + td_u32 i = 0; + td_u8 hash[DRV_PKE_LEN_512]; + drv_pke_data arr[1]; + drv_pke_data hash_data = {DRV_PKE_LEN_512, hash}; + + arr[0].data = (td_u8 *)secret; + arr[0].length = len; + ret = drv_cipher_pke_calc_hash(arr, 1, DRV_PKE_HASH_TYPE_SHA512, &hash_data); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_pke_calc_hash failed, ret is 0x%x\n", ret); + + for (i = 0; i < DRV_PKE_LEN_256; i++) { + a[i] = hash[DRV_PKE_LEN_256 - 1 - i]; + } + /* [255], [254], [2], [1], [0] must be 0,1,0,0,0 */ + a[DRV_PKE_LEN_256 - 1] &= 0xF8; + a[0] &= 0x7F; // 0x7F : see comment above + a[0] |= 0x40; // 0x40 : see commnet above + (void)memcpy_s(prefix, DRV_PKE_LEN_256, hash + DRV_PKE_LEN_256, DRV_PKE_LEN_256); + return TD_SUCCESS; +} + +static td_s32 point_mul_compress(const drv_pke_ecc_curve *ecc, const td_u8 *k, td_u8 *out, td_u32 len) +{ + td_s32 ret = TD_FAILURE; + td_u32 i; + td_u8 rx[DRV_PKE_LEN_256] = {0}; + td_u8 ry[DRV_PKE_LEN_256] = {0}; + + const drv_pke_data k_data = {DRV_PKE_LEN_256, (td_u8 *)k}; + const drv_pke_data ecc_p_data = {DRV_PKE_LEN_256, (td_u8 *)ecc->p}; + const drv_pke_ecc_point ecc_gpoint = {(td_u8 *)ecc->gx, (td_u8 *)ecc->gy, DRV_PKE_LEN_256}; + const drv_pke_ecc_point r_point = {rx, ry, DRV_PKE_LEN_256}; + + crypto_param_check(len != DRV_PKE_LEN_256); + + /* R = k * G */ + ret = drv_cipher_pke_ed_mul_dot(&k_data, &ecc_gpoint, &ecc_p_data, &r_point); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_ed_mul_dot failed, ret is 0x%x\n", ret); + for (i = 0; i < DRV_PKE_LEN_256; i++) { + out[i] = ry[DRV_PKE_LEN_256 - 1 - i]; + } + /* copy the least significant bit of the x coordinate to the most significant bit of the final octet. */ + out[DRV_PKE_LEN_256 - 1] |= (rx[DRV_PKE_LEN_256 - 1] & 0x1) << 7; /* shift 7 */ +exit__: + (void)drv_cipher_pke_clean_ram(); + return ret; +} + +static td_s32 ed_secret_to_public(const drv_pke_ecc_curve *ecc, const drv_pke_data *priv_key, + const drv_pke_ecc_point *pub_key) +{ + td_s32 ret = TD_FAILURE; + td_u8 a[DRV_PKE_LEN_256] = {0}; + td_u8 dummy[DRV_PKE_LEN_256]; + + /* Operation: a, prefix = secret_expand(secret) */ + ret = secret_expand(priv_key->data, a, dummy, DRV_PKE_LEN_256); + crypto_chk_return(ret != TD_SUCCESS, ret, "secret_expand failed, ret is 0x%x\n", ret); + /* Operation: A = point_compress(point_mul(a, G)) */ + (void)memset_s(pub_key->y, DRV_PKE_LEN_256, 0x00, DRV_PKE_LEN_256); + ret = point_mul_compress(ecc, a, pub_key->y, DRV_PKE_LEN_256); + crypto_chk_return(ret != TD_SUCCESS, ret, "point_mul_compress failed, ret is 0x%x\n", ret); + + return TD_SUCCESS; +} + +static td_s32 pke_ecc_gen_key(const drv_pke_ecc_curve *ecc, const drv_pke_data *input_priv_key, + const drv_pke_data *output_priv_key, const drv_pke_ecc_point *output_pub_key) +{ + td_s32 ret = TD_FAILURE; + td_u32 i = 0; + td_u8 key[DRV_PKE_LEN_256] = {0}; + td_u8 montgomery_p[DRV_PKE_LEN_256] = {0}; + td_u8 A24[DRV_PKE_LEN_256] = {0}; + td_u8 temp_result[DRV_PKE_LEN_256] = {0}; + const drv_pke_data key_data = {DRV_PKE_LEN_256, key}; + const drv_pke_data montgomery_p_data = {DRV_PKE_LEN_256, montgomery_p}; + const drv_pke_data A24_data = {DRV_PKE_LEN_256, A24}; + const drv_pke_data temp_result_data = {DRV_PKE_LEN_256, temp_result}; + const drv_pke_data ecc_p_data = {DRV_PKE_LEN_256, (td_u8 *)ecc->p}; + const drv_pke_data ecc_a_data = {DRV_PKE_LEN_256, (td_u8 *)ecc->a}; + const drv_pke_data ecc_gx_data = {DRV_PKE_LEN_256, (td_u8 *)ecc->gx}; + const drv_pke_ecc_point ecc_gpoint = {(td_u8 *)ecc->gx, (td_u8 *)ecc->gy, ecc->ksize}; + + if ((input_priv_key != TD_NULL) && (input_priv_key->data != TD_NULL)) { + // check whether the input priv key is valid + if ((ecc->ecc_type != DRV_PKE_ECC_TYPE_RFC7748) && (ecc->ecc_type != DRV_PKE_ECC_TYPE_RFC8032)) { + /* check 1 < input_priv_key < n */ + ret = drv_range_check(input_priv_key->data, ecc->n, ecc->ksize); + crypto_chk_return(ret != TD_SUCCESS, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "drv_range_check failed, ret is 0x%x\n", ret); + } + (void)memcpy_s(output_priv_key->data, ecc->ksize, input_priv_key->data, ecc->ksize); + } else { + if ((ecc->ecc_type == DRV_PKE_ECC_TYPE_RFC7748) || (ecc->ecc_type == DRV_PKE_ECC_TYPE_RFC8032)) { + /* Generate key with no limit */ + ret = get_randnum(output_priv_key->data, TD_NULL, ecc->ksize); + } else { /* Generate key: 0 < key < n */ + ret = get_randnum(output_priv_key->data, (td_u8 *)ecc->n, ecc->ksize); + } + crypto_chk_return(ret != TD_SUCCESS, ret, "get_randnum failed, ret is 0x%x\n", ret); + } + /* PA = dA * G */ + if (ecc->ecc_type == DRV_PKE_ECC_TYPE_RFC7748) { + /* The private key need to be decoded */ + ret = cal_montgomery_n(&ecc_p_data, &montgomery_p_data); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "cal_montgomery_n failed, ret is 0x%x\n", ret); + ret = drv_cipher_pke_mul_mod(&ecc_a_data, &montgomery_p_data, &ecc_p_data, &A24_data); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + decode_priv_key(key, output_priv_key->data, ecc->ksize); + ret = drv_cipher_pke_mg_mul_dot(&key_data, &ecc_gx_data, &ecc_p_data, &A24_data, &temp_result_data); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mg_mul_dot failed, ret is 0x%x\n", ret); + /* The output should be byte reversed */ + for (i = 0; i < ecc->ksize; i++) { + output_pub_key->x[i] = temp_result[ecc->ksize - 1 - i]; + } + /* Returned priv_key[0]=.....000, priv_key[255] = 0....1.. */ + output_priv_key->data[0] = output_priv_key->data[0] & 0xF8; // 0xF8 : see comment above + output_priv_key->data[ecc->ksize - 1] = + output_priv_key->data[ecc->ksize - 1] & 0x7F; // 0x7F : see comment above + output_priv_key->data[ecc->ksize - 1] = + output_priv_key->data[ecc->ksize - 1] | 0x40; // 0x40 : see comment above + } else if (ecc->ecc_type == DRV_PKE_ECC_TYPE_RFC8032) { + ret = ed_secret_to_public(ecc, output_priv_key, output_pub_key); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "ed_secret_to_public failed, ret is 0x%x\n", ret); + } else { + ret = drv_cipher_pke_mul_dot(ecc, output_priv_key, &ecc_gpoint, output_pub_key); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_dot failed, ret is 0x%x\n", ret); + } +exit__: + (void)drv_cipher_pke_clean_ram(); + return ret; +} + +/* z = d * p(x,y), sharekey = z(x) */ +static td_s32 pke_ecc_gen_ecdh_key( + const drv_pke_ecc_curve *ecc, + const drv_pke_ecc_point *input_pub_key, + const drv_pke_data *input_priv_key, + const drv_pke_data *output_shared_key) +{ + td_s32 ret = TD_FAILURE; + // for RFC7748 + td_u32 i = 0; + td_u8 buffer[DRV_PKE_LEN_256 * 5] = {0}; // need buffer num is 5 + const drv_pke_data montgomery_p_data = {DRV_PKE_LEN_256, buffer + DRV_PKE_LEN_256 * i++}; + const drv_pke_data A24_data = {DRV_PKE_LEN_256, buffer + DRV_PKE_LEN_256 * i++}; + const drv_pke_data priv_key_data = {DRV_PKE_LEN_256, buffer + DRV_PKE_LEN_256 * i++}; + const drv_pke_data pub_key_data = {DRV_PKE_LEN_256, buffer + DRV_PKE_LEN_256 * i++}; + const drv_pke_data temp_result_data = {DRV_PKE_LEN_256, buffer + DRV_PKE_LEN_256 * i++}; + const drv_pke_data ecc_p_data = {DRV_PKE_LEN_256, (td_u8 *)ecc->p}; + const drv_pke_data ecc_a_data = {DRV_PKE_LEN_256, (td_u8 *)ecc->a}; + // for another curve type + const drv_pke_ecc_point shared_point = {output_shared_key->data, TD_NULL, ecc->ksize}; + + if (ecc->ecc_type == DRV_PKE_ECC_TYPE_RFC7748) { + /* A24 = (a * 2 ^ len_n) mod p */ + ret = cal_montgomery_n(&ecc_p_data, &montgomery_p_data); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "cal_montgomery_n failed, ret is 0x%x\n", ret); + ret = drv_cipher_pke_mul_mod(&ecc_a_data, &montgomery_p_data, &ecc_p_data, &A24_data); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + /* The private and public key need to be decoded */ + decode_priv_key(priv_key_data.data, input_priv_key->data, DRV_PKE_LEN_256); + decode_pub_key(pub_key_data.data, input_pub_key->x, DRV_PKE_LEN_256); + + ret = drv_cipher_pke_mg_mul_dot(&priv_key_data, &pub_key_data, &ecc_p_data, &A24_data, &temp_result_data); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mg_mul_dot failed, ret is 0x%x\n", ret); + + /* The output should be byte reversed */ + for (i = 0; i < ecc->ksize; i++) { + output_shared_key->data[i] = temp_result_data.data[ecc->ksize - 1 - i]; + } + } else { + ret = drv_cipher_pke_mul_dot(ecc, input_priv_key, input_pub_key, &shared_point); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_dot failed, ret is 0x%x\n", ret); + } +exit__: + (void)drv_cipher_pke_clean_ram(); + return ret; +} + +static td_s32 sm2_sign_verify_hash(const sm2_sign_verify_hash_pack *param, const drv_pke_msg *msg, drv_pke_data *hash) +{ + td_s32 ret = TD_FAILURE; + td_u8 entla[ENTLA_LEN]; + td_u8 h[DRV_PKE_SM2_LEN_IN_BYTES]; + drv_pke_data hh = {DRV_PKE_SM2_LEN_IN_BYTES, h}; + drv_pke_data arr[8]; // The capacity of the array is 8. + drv_pke_data arr2[2]; // The capacity of the array is 2. + const drv_pke_ecc_curve *sm2 = get_ecc_curve(DRV_PKE_ECC_TYPE_SM2); + crypto_chk_return(sm2 == TD_NULL, PKE_COMPAT_ERRNO(ERROR_UNSUPPORT), "unsupport alg\n"); + + entla[0] = (td_u8)((param->id_len * BYTE_BITS) >> BYTE_BITS); + entla[1] = (td_u8)((param->id_len * BYTE_BITS)); + + /* ENTLA */ + arr[0].data = entla; + arr[0].length = ENTLA_LEN; + /* IDA */ + arr[1].data = param->id; + arr[1].length = param->id_len; + /* a */ + arr[2].data = (td_u8 *)sm2->a; // 2 is data of the 3th element + arr[2].length = DRV_PKE_SM2_LEN_IN_BYTES; // 2 is length of the 3th element + /* b */ + arr[3].data = (td_u8 *)sm2->b; // 3 is data of the 4th element + arr[3].length = DRV_PKE_SM2_LEN_IN_BYTES; // 3 is length of the 4th element + /* xG */ + arr[4].data = (td_u8 *)sm2->gx; // 4 is data of the 5th element + arr[4].length = DRV_PKE_SM2_LEN_IN_BYTES; // 4 is length of the 5th element + /* yG */ + arr[5].data = (td_u8 *)sm2->gy; // 5 is data of the 6th element + arr[5].length = DRV_PKE_SM2_LEN_IN_BYTES; // 5 is length of the 6th element + /* xA */ + arr[6].data = param->px; // 6 is data of the 7th element + arr[6].length = DRV_PKE_SM2_LEN_IN_BYTES; // 6 islength of the 7th element + /* yA */ + arr[7].data = param->py; // 7 is data of the 8th element + arr[7].length = DRV_PKE_SM2_LEN_IN_BYTES; // 7 is length of the 8th element + + /* ZA */ + arr2[0].data = h; + arr2[0].length = DRV_PKE_SM2_LEN_IN_BYTES; + /* M */ + arr2[1].data = msg->data; + arr2[1].length = msg->length; + + /* ZA = SM3( ENTLA || IDA || a || b || xG || yG || xA || yA ) */ + ret = drv_cipher_pke_calc_hash(arr, sizeof(arr) / sizeof(arr[0]), DRV_PKE_HASH_TYPE_SM3, &hh); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_pke_calc_hash failed, ret is 0x%x\n", ret); + /* e = SM3( ZA || M ) */ + ret = drv_cipher_pke_calc_hash(arr2, sizeof(arr2) / sizeof(arr2[0]), DRV_PKE_HASH_TYPE_SM3, hash); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_pke_calc_hash failed, ret is 0x%x\n", ret); + + return ret; +} + +static td_s32 pke_sm2_sign(const drv_pke_data *priv_key, const drv_pke_data *hash, const drv_pke_ecc_sig *sig) +{ + td_s32 ret = TD_FAILURE; + td_u32 klen = DRV_PKE_SM2_LEN_IN_BYTES; + td_u32 i; + drv_pke_data var_arr[PKE_SM2_SIGN_VAR_MAX]; + const drv_pke_ecc_curve *sm2; + drv_pke_ecc_point sm2_gpoint; + drv_pke_ecc_point r_point; + td_u8 *buffer; + + sm2 = get_ecc_curve(DRV_PKE_ECC_TYPE_SM2); + crypto_chk_return(sm2 == TD_NULL, PKE_COMPAT_ERRNO(ERROR_UNSUPPORT), "unsupport alg\n"); + + buffer = crypto_malloc(klen * SM2_SIGN_BUF_CNT); + if (buffer == TD_NULL) { + crypto_log_err("%s:%d Error! Malloc memory failed!\n", __FUNCTION__, __LINE__); + return PKE_COMPAT_ERRNO(ERROR_MALLOC); + } + (void)memset_s(buffer, klen * SM2_SIGN_BUF_CNT, 0, klen * SM2_SIGN_BUF_CNT); + + for (i = 0; i < PKE_SM2_SIGN_VAR_MAX; i++) { + if (i <= SM2SIGN_ONE) { + var_arr[i].data = buffer + klen * i; + } + var_arr[i].length = klen; + } + + var_arr[SM2SIGN_SM2_N].data = (td_u8 *)sm2->n; + var_arr[SM2SIGN_SIG_R].data = sig->r; + var_arr[SM2SIGN_SIG_S].data = sig->s; + var_arr[SM2SIGN_ONE].data[klen - 1] = 0x1; + sm2_gpoint = (drv_pke_ecc_point){(td_u8 *)sm2->gx, (td_u8 *)sm2->gy, klen}; + r_point = (drv_pke_ecc_point){var_arr[SM2SIGN_R_X].data, var_arr[SM2SIGN_R_Y].data, klen}; + + // Step 1: N = r^2 mod p where N is montgomery multiplier + ret = cal_montgomery_n(&var_arr[SM2SIGN_SM2_N], &var_arr[SM2SIGN_MONTGOMERY_N]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "cal_montgomery_n failed, ret is 0x%x\n", ret); + + for (i = 0; i < PKE_MAX_TIMES; i++) { + /* Step 1: random k */ + ret = get_randnum(var_arr[SM2SIGN_K].data, (td_u8 *)sm2->n, klen); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "get_randnum failed, ret is 0x%x\n", ret); + + /* Step 2: R = k * G */ + ret = drv_cipher_pke_mul_dot(sm2, &var_arr[SM2SIGN_K], &sm2_gpoint, &r_point); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_dot failed, ret is 0x%x\n", ret); + + /* Step 3: E = e + 0 mod n */ + ret = drv_cipher_pke_add_mod(hash, &var_arr[SM2SIGN_ZERO], &var_arr[SM2SIGN_SM2_N], &var_arr[SM2SIGN_E]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_add_mod failed, ret is 0x%x\n", ret); + + /* Step 4: r = E + Rx mod n */ + ret = drv_cipher_pke_add_mod(&var_arr[SM2SIGN_E], &var_arr[SM2SIGN_R_X], &var_arr[SM2SIGN_SM2_N], + &var_arr[SM2SIGN_SIG_R]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_add_mod failed, ret is 0x%x\n", ret); + + /* Step 5: r = 0 ? */ + if (drv_ecc_is_zero(var_arr[SM2SIGN_SIG_R].data, klen)) { + continue; + } + /* Step 6: rk = r + k mod n */ + ret = drv_cipher_pke_add_mod(&var_arr[SM2SIGN_SIG_R], &var_arr[SM2SIGN_K], &var_arr[SM2SIGN_SM2_N], + &var_arr[SM2SIGN_RK]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_add_mod failed, ret is 0x%x\n", ret); + + /* Step 7: rk = 0 ? */ + if (drv_ecc_is_zero(var_arr[SM2SIGN_RK].data, klen)) { + continue; + } + + /* Step 8: random my */ + ret = get_randnum(var_arr[SM2SIGN_MY].data, (td_u8 *)sm2->n, klen); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "get_randnum failed, ret is 0x%x\n", ret); + + /* Step 9: mr = r * N mod n */ + ret = drv_cipher_pke_mul_mod(&var_arr[SM2SIGN_SIG_R], &var_arr[SM2SIGN_MONTGOMERY_N], &var_arr[SM2SIGN_SM2_N], + &var_arr[SM2SIGN_MR]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + /* Step 10: mk = k * N mod n */ + ret = drv_cipher_pke_mul_mod(&var_arr[SM2SIGN_K], &var_arr[SM2SIGN_MONTGOMERY_N], &var_arr[SM2SIGN_SM2_N], + &var_arr[SM2SIGN_MK]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + /* Step 11: mrk = mr + mk mod n */ + ret = drv_cipher_pke_add_mod(&var_arr[SM2SIGN_MR], &var_arr[SM2SIGN_MK], + &var_arr[SM2SIGN_SM2_N], &var_arr[SM2SIGN_MRK]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_add_mod failed, ret is 0x%x\n", ret); + + /* Step 12: mrky = mrk * my mod n */ + ret = drv_cipher_pke_mul_mod(&var_arr[SM2SIGN_MRK], &var_arr[SM2SIGN_MY], + &var_arr[SM2SIGN_SM2_N], &var_arr[SM2SIGN_MRKY]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + /* Step 13: TA = dA * my mod n */ + ret = drv_cipher_pke_mul_mod(priv_key, &var_arr[SM2SIGN_MY], &var_arr[SM2SIGN_SM2_N], &var_arr[SM2SIGN_TA]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + /* Step 14: mTA = TA * N mod n */ + ret = drv_cipher_pke_mul_mod(&var_arr[SM2SIGN_TA], &var_arr[SM2SIGN_MONTGOMERY_N], &var_arr[SM2SIGN_SM2_N], + &var_arr[SM2SIGN_MTA]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + /* Step 15: mTy = mTA + my mod n */ + ret = drv_cipher_pke_add_mod(&var_arr[SM2SIGN_MTA], &var_arr[SM2SIGN_MY], &var_arr[SM2SIGN_SM2_N], + &var_arr[SM2SIGN_MTY]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_add_mod failed, ret is 0x%x\n", ret); + + /* Step 16: minv = mTy^-1 mod n */ + ret = drv_cipher_pke_inv_mod(&var_arr[SM2SIGN_MTY], &var_arr[SM2SIGN_SM2_N], &var_arr[SM2SIGN_MINV]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_inv_mod failed, ret is 0x%x\n", ret); + + /* Step 20: mTz = mrky * minv mod n */ + ret = drv_cipher_pke_mul_mod(&var_arr[SM2SIGN_MRKY], &var_arr[SM2SIGN_MINV], &var_arr[SM2SIGN_SM2_N], + &var_arr[SM2SIGN_MTZ]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + /* Step 21: ms = mTz - mr mod n */ + ret = drv_cipher_pke_sub_mod(&var_arr[SM2SIGN_MTZ], &var_arr[SM2SIGN_MR], + &var_arr[SM2SIGN_SM2_N], &var_arr[SM2SIGN_MS]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_sub_mod failed, ret is 0x%x\n", ret); + + /* Step 22: s = ms * 1 mod n */ + ret = drv_cipher_pke_mul_mod(&var_arr[SM2SIGN_MS], &var_arr[SM2SIGN_ONE], &var_arr[SM2SIGN_SM2_N], + &var_arr[SM2SIGN_SIG_S]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + /* Step 23: s = 0 ? */ + if (drv_ecc_is_zero(var_arr[SM2SIGN_SIG_S].data, klen) == TD_FALSE) { + break; + } + } + + if (i >= PKE_MAX_TIMES) { + crypto_log_err("Generate rk timeout!\n"); + ret = PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM); + goto exit__; + } + +exit__: + (void)drv_cipher_pke_clean_ram(); + if (buffer != TD_NULL) { + (void)memset_s(buffer, klen * SM2_SIGN_BUF_CNT, 0, klen * SM2_SIGN_BUF_CNT); + crypto_free(buffer); + } + return ret; +} + +static td_s32 pke_sm2_verify(const drv_pke_ecc_point *pub_key, const drv_pke_data *hash, + const drv_pke_ecc_sig *sig) +{ + td_s32 ret = TD_FAILURE; + td_u32 klen = DRV_PKE_SM2_LEN_IN_BYTES; + td_u32 i; + drv_pke_data var_arr[PKE_SM2_VERIFY_VAR_MAX]; + const drv_pke_ecc_curve *sm2; + drv_pke_ecc_point sm2_gpoint; + drv_pke_ecc_point sG_point; + drv_pke_ecc_point tPA_point; + drv_pke_ecc_point r_point; + td_u8 *buffer; + + sm2 = get_ecc_curve(DRV_PKE_ECC_TYPE_SM2); + crypto_chk_return(sm2 == TD_NULL, PKE_COMPAT_ERRNO(ERROR_UNSUPPORT), "unsupport alg\n"); + + if (drv_range_check(sig->r, sm2->n, DRV_PKE_SM2_LEN_IN_BYTES) != TD_SUCCESS) { + crypto_log_err("%s:%d: sig->r check range failed!\n", __func__, __LINE__); + return PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM); + } + if (drv_range_check(sig->s, sm2->n, DRV_PKE_SM2_LEN_IN_BYTES) != TD_SUCCESS) { + crypto_log_err("%s:%d: sig->s check range failed!\n", __func__, __LINE__); + return PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM); + } + + buffer = crypto_malloc(klen * SM2_VERIFY_BUF_CNT); + if (buffer == TD_NULL) { + crypto_log_err("%s:%d Error! Malloc memory failed!\n", __FUNCTION__, __LINE__); + return PKE_COMPAT_ERRNO(ERROR_MALLOC); + } + (void)memset_s(buffer, klen * SM2_VERIFY_BUF_CNT, 0, klen * SM2_VERIFY_BUF_CNT); + for (i = 0; i < PKE_SM2_VERIFY_VAR_MAX; i++) { + if (i <= SM2VERIFY_ZERO) { + var_arr[i].data = buffer + klen * i; + } + var_arr[i].length = klen; + } + var_arr[SM2VERIFY_SM2_N].data = (td_u8 *)sm2->n; + var_arr[SM2VERIFY_SIG_R].data = sig->r; + var_arr[SM2VERIFY_SIG_S].data = sig->s; + sm2_gpoint = (drv_pke_ecc_point){(td_u8 *)sm2->gx, (td_u8 *)sm2->gy, klen}; + sG_point = (drv_pke_ecc_point){var_arr[SM2VERIFY_S_GX].data, var_arr[SM2VERIFY_S_GY].data, klen}; + tPA_point = (drv_pke_ecc_point){var_arr[SM2VERIFY_T_PAX].data, var_arr[SM2VERIFY_T_PAY].data, klen}; + r_point = (drv_pke_ecc_point){var_arr[SM2VERIFY_RX].data, var_arr[SM2VERIFY_RY].data, klen}; + /* Step 1: t = r + s mod n */ + ret = drv_cipher_pke_add_mod(&var_arr[SM2VERIFY_SIG_R], &var_arr[SM2VERIFY_SIG_S], &var_arr[SM2VERIFY_SM2_N], + &var_arr[SM2VERIFY_T]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_add_mod failed, ret is 0x%x\n", ret); + /* Step 2: t = 0 ? */ + if (drv_ecc_is_zero(var_arr[SM2VERIFY_T].data, klen)) { + crypto_log_err("t = 0!\n"); + ret = TD_FAILURE; + goto exit__; + } + /* Step 3: sG = s * G */ + ret = drv_cipher_pke_mul_dot(sm2, &var_arr[SM2VERIFY_SIG_S], &sm2_gpoint, &sG_point); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_dot failed, ret is 0x%x\n", ret); + /* Step 4: tPA = t * PA */ + ret = drv_cipher_pke_mul_dot(sm2, &var_arr[SM2VERIFY_T], pub_key, &tPA_point); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_dot failed, ret is 0x%x\n", ret); + /* Step 5: R = sG + tPA */ + ret = drv_cipher_pke_add_dot(sm2, &sG_point, &tPA_point, &r_point); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_add_dot failed, ret is 0x%x\n", ret); + /* Step 6: e = hash + 0 mod n */ + ret = drv_cipher_pke_add_mod(hash, &var_arr[SM2VERIFY_ZERO], &var_arr[SM2VERIFY_SM2_N], &var_arr[SM2VERIFY_E]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_add_mod failed, ret is 0x%x\n", ret); + /* Step 7: v = e + Rx mod n */ + ret = drv_cipher_pke_add_mod(&var_arr[SM2VERIFY_E], &var_arr[SM2VERIFY_RX], &var_arr[SM2VERIFY_SM2_N], + &var_arr[SM2VERIFY_V]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_add_mod failed, ret is 0x%x\n", ret); + /* Step 8: v = r ? */ + if (memcmp(sig->r, var_arr[SM2VERIFY_V].data, klen) != 0) { + crypto_log_err("v != r!\n"); + ret = TD_FAILURE; + } +exit__: + (void)drv_cipher_pke_clean_ram(); + if (buffer != TD_NULL) { + (void)memset_s(buffer, klen * SM2_VERIFY_BUF_CNT, 0, klen * SM2_VERIFY_BUF_CNT); + crypto_free(buffer); + } + return ret; +} + +static td_s32 pke_ecdsa_sign( + const drv_pke_ecc_curve *ecc, + const drv_pke_data *priv_key, + const drv_pke_data *hash, + const drv_pke_ecc_sig *sig) +{ + td_s32 ret = TD_FAILURE; + td_u32 klen = ecc->ksize; + td_u32 i; + drv_pke_data var_arr[PKE_ECDSA_SIGN_VAR_MAX]; + drv_pke_ecc_point ecc_gpoint; + drv_pke_ecc_point r_point; + td_u8 *buffer; + + if (ecc->ecc_type == DRV_PKE_ECC_TYPE_SM2) { + return pke_sm2_sign(priv_key, hash, sig); + } + buffer = crypto_malloc(klen * ECDSA_SIGN_BUF_CNT); + crypto_chk_return(buffer == TD_NULL, PKE_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + + (void)memset_s(buffer, klen * ECDSA_SIGN_BUF_CNT, 0, klen * ECDSA_SIGN_BUF_CNT); + for (i = 0; i < PKE_ECDSA_SIGN_VAR_MAX - 1; i++) { + if (i <= ECCSIGN_ONE) { + var_arr[i].data = buffer + klen * i; + } + var_arr[i].length = klen; + } + var_arr[ECCSIGN_ECC_N].data = (td_u8 *)ecc->n; + var_arr[ECCSIGN_SIG_R].data = sig->r; + var_arr[ECCSIGN_SIG_S].data = sig->s; + var_arr[ECCSIGN_HASH].data = hash->data; + var_arr[ECCSIGN_HASH].length = crypto_min(hash->length, ecc->ksize); + var_arr[ECCSIGN_ONE].data[klen - 1] = 0x1; + ecc_gpoint = (drv_pke_ecc_point){(td_u8 *)ecc->gx, (td_u8 *)ecc->gy, klen}; + r_point = (drv_pke_ecc_point){var_arr[ECCSIGN_RX].data, var_arr[ECCSIGN_RY].data, klen}; + + // 1. N = 2 ^ 2len_n mod n where N = R ^ 2 + ret = cal_montgomery_n(&var_arr[ECCSIGN_ECC_N], &var_arr[ECCSIGN_MONTGOMERY_N]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "cal_montgomery_n failed, ret is 0x%x\n", ret); + + for (i = 0; i < ECC_TRY_CNT; i++) { + // 2. generate randnum k + ret = get_randnum(var_arr[ECCSIGN_K].data, (td_u8 *)ecc->n, klen); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "get_randnum failed, ret is 0x%x\n", ret); + // 3. R = k*G + ret = drv_cipher_pke_mul_dot(ecc, &var_arr[ECCSIGN_K], &ecc_gpoint, &r_point); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_dot failed, ret is 0x%x\n", ret); + // 4. r= (xR + 0) mod n + ret = drv_cipher_pke_add_mod(&var_arr[ECCSIGN_RX], &var_arr[ECCSIGN_ZERO], &var_arr[ECCSIGN_ECC_N], + &var_arr[ECCSIGN_SIG_R]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_add_mod failed, ret is 0x%x\n", ret); + // 5. check r ?=0 + if (drv_ecc_is_zero(var_arr[ECCSIGN_SIG_R].data, klen)) { + continue; + } + + // 6. E = hash + 0 mod n + ret = drv_cipher_pke_add_mod(&var_arr[ECCSIGN_HASH], &var_arr[ECCSIGN_ZERO], &var_arr[ECCSIGN_ECC_N], + &var_arr[ECCSIGN_E]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_add_mod failed, ret is 0x%x\n", ret); + + // 7. mE = E * N mod n + ret = drv_cipher_pke_mul_mod(&var_arr[ECCSIGN_E], &var_arr[ECCSIGN_MONTGOMERY_N], &var_arr[ECCSIGN_ECC_N], + &var_arr[ECCSIGN_ME]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + // 8. mr = r * N mod n + ret = drv_cipher_pke_mul_mod(&var_arr[ECCSIGN_SIG_R], &var_arr[ECCSIGN_MONTGOMERY_N], &var_arr[ECCSIGN_ECC_N], + &var_arr[ECCSIGN_MR]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + // 9. md = d * N mod n + ret = drv_cipher_pke_mul_mod(priv_key, &var_arr[ECCSIGN_MONTGOMERY_N], &var_arr[ECCSIGN_ECC_N], + &var_arr[ECCSIGN_MD]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + // 10. mrd = md * mr mod n + ret = drv_cipher_pke_mul_mod(&var_arr[ECCSIGN_MD], &var_arr[ECCSIGN_MR], &var_arr[ECCSIGN_ECC_N], + &var_arr[ECCSIGN_MRD]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + // 11. y = mE + mrd mod n + ret = drv_cipher_pke_add_mod(&var_arr[ECCSIGN_ME], &var_arr[ECCSIGN_MRD], &var_arr[ECCSIGN_ECC_N], + &var_arr[ECCSIGN_Y]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_add_mod failed, ret is 0x%x\n", ret); + + // 12. mk = k * N mod n + ret = drv_cipher_pke_mul_mod(&var_arr[ECCSIGN_K], &var_arr[ECCSIGN_MONTGOMERY_N], &var_arr[ECCSIGN_ECC_N], + &var_arr[ECCSIGN_MK]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + // 13. mkni = mk ^ -1 mod n + ret = drv_cipher_pke_inv_mod(&var_arr[ECCSIGN_MK], &var_arr[ECCSIGN_ECC_N], &var_arr[ECCSIGN_MKNI]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_inv_mod failed, ret is 0x%x\n", ret); + + // 14. ms = mkni * y mod n + ret = drv_cipher_pke_mul_mod(&var_arr[ECCSIGN_MKNI], &var_arr[ECCSIGN_Y], &var_arr[ECCSIGN_ECC_N], + &var_arr[ECCSIGN_MS]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + // 15. s = ms * 1 mod n + ret = drv_cipher_pke_mul_mod(&var_arr[ECCSIGN_MS], &var_arr[ECCSIGN_ONE], &var_arr[ECCSIGN_ECC_N], + &var_arr[ECCSIGN_SIG_S]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + // 16. check s ?=0 + if (drv_ecc_is_zero(var_arr[ECCSIGN_SIG_S].data, klen)) { + continue; + } + break; + } + if (i == ECC_TRY_CNT) { + crypto_log_err("Error! K is Invalid!\n"); + ret = PKE_COMPAT_ERRNO(ERROR_TRY_TIMES); + goto exit__; + } +exit__: + (void)drv_cipher_pke_clean_ram(); + if (buffer != TD_NULL) { + (void)memset_s(buffer, klen * ECDSA_SIGN_BUF_CNT, 0, klen * ECDSA_SIGN_BUF_CNT); + crypto_free(buffer); + buffer = TD_NULL; + } + return ret; +} + +static td_s32 pke_ecdsa_verify( + const drv_pke_ecc_curve *ecc, + const drv_pke_ecc_point *pub_key, + const drv_pke_data *hash, + const drv_pke_ecc_sig *sig) +{ + td_s32 ret = TD_FAILURE; + td_u32 klen = ecc->ksize; + td_u32 i; + drv_pke_data var_arr[PKE_ECDSA_VERIFY_VAR_MAX]; + drv_pke_ecc_point ecc_gpoint; + drv_pke_ecc_point r_point; + drv_pke_ecc_point u1_point; + drv_pke_ecc_point u2_point; + td_u8 *buffer; + + if (ecc->ecc_type == DRV_PKE_ECC_TYPE_SM2) { + return pke_sm2_verify(pub_key, hash, sig); + } + buffer = crypto_malloc(klen * ECDSA_VERIFY_BUF_CNT); + crypto_chk_return(buffer == TD_NULL, PKE_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + (void)memset_s(buffer, klen * ECDSA_VERIFY_BUF_CNT, 0, klen * ECDSA_VERIFY_BUF_CNT); + + for (i = 0; i < PKE_ECDSA_VERIFY_VAR_MAX - 1; i++) { + if (i <= ECCVERIFY_ONE) { + var_arr[i].data = buffer + klen * i; + } + var_arr[i].length = klen; + } + var_arr[ECCVERIFY_ECC_N].data = (td_u8 *)ecc->n; + var_arr[ECCVERIFY_SIG_R].data = sig->r; + var_arr[ECCVERIFY_SIG_S].data = sig->s; + var_arr[ECCVERIFY_HASH].data = hash->data; + var_arr[ECCVERIFY_HASH].length = crypto_min(hash->length, klen); + var_arr[ECCVERIFY_ONE].data[klen - 1] = 0x1; + + ecc_gpoint = (drv_pke_ecc_point){(td_u8 *)ecc->gx, (td_u8 *)ecc->gy, klen}; + r_point = (drv_pke_ecc_point){var_arr[ECCVERIFY_RX].data, var_arr[ECCVERIFY_RY].data, klen}; + u1_point = (drv_pke_ecc_point){var_arr[ECCVERIFY_U1X].data, var_arr[ECCVERIFY_U1Y].data, klen}; + u2_point = (drv_pke_ecc_point){var_arr[ECCVERIFY_U2X].data, var_arr[ECCVERIFY_U2Y].data, klen}; + + /* check 0 < r < n ? */ + if (drv_range_check(sig->r, ecc->n, klen) != TD_SUCCESS) { + ret = PKE_COMPAT_ERRNO(ERROR_PKE_ECDSA_VERIFY_CHECK); + goto exit__; + } + + /* check 0< s < n ? */ + if (drv_range_check(sig->s, ecc->n, klen) != TD_SUCCESS) { + ret = PKE_COMPAT_ERRNO(ERROR_PKE_ECDSA_VERIFY_CHECK); + goto exit__; + } + + // 1. N =2 ^ 2len_n mod n + ret = cal_montgomery_n(&var_arr[ECCVERIFY_ECC_N], &var_arr[ECCVERIFY_MONTGOMERY_N]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "cal_montgomery_n failed, ret is 0x%x\n", ret); + + // 2. ms = s * N mod n + ret = drv_cipher_pke_mul_mod(&var_arr[ECCVERIFY_SIG_S], &var_arr[ECCVERIFY_MONTGOMERY_N], &var_arr[ECCVERIFY_ECC_N], + &var_arr[ECCVERIFY_MS]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + // 3. msni = ms ^ -1 mod n + ret = drv_cipher_pke_inv_mod(&var_arr[ECCVERIFY_MS], &var_arr[ECCVERIFY_ECC_N], &var_arr[ECCVERIFY_MSNI]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_inv_mod failed, ret is 0x%x\n", ret); + + // 4. E = hash + 0 mod n + ret = drv_cipher_pke_add_mod(&var_arr[ECCVERIFY_HASH], &var_arr[ECCVERIFY_ZERO], &var_arr[ECCVERIFY_ECC_N], + &var_arr[ECCVERIFY_E]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_add_mod failed, ret is 0x%x\n", ret); + + // 5. mE = E * N mod n + ret = drv_cipher_pke_mul_mod(&var_arr[ECCVERIFY_E], &var_arr[ECCVERIFY_MONTGOMERY_N], &var_arr[ECCVERIFY_ECC_N], + &var_arr[ECCVERIFY_ME]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + // 6. mu1 = mE * msni mod n + ret = drv_cipher_pke_mul_mod(&var_arr[ECCVERIFY_ME], &var_arr[ECCVERIFY_MSNI], &var_arr[ECCVERIFY_ECC_N], + &var_arr[ECCVERIFY_MU1]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + // 7. u1 = mu1 * 1 mod n + ret = drv_cipher_pke_mul_mod(&var_arr[ECCVERIFY_MU1], &var_arr[ECCVERIFY_ONE], &var_arr[ECCVERIFY_ECC_N], + &var_arr[ECCVERIFY_U1]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + // 8. mr = r * N mod n + ret = drv_cipher_pke_mul_mod(&var_arr[ECCVERIFY_SIG_R], &var_arr[ECCVERIFY_MONTGOMERY_N], &var_arr[ECCVERIFY_ECC_N], + &var_arr[ECCVERIFY_MR]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + // 9. mu2 = mr * msni mod n + ret = drv_cipher_pke_mul_mod(&var_arr[ECCVERIFY_MR], &var_arr[ECCVERIFY_MSNI], &var_arr[ECCVERIFY_ECC_N], + &var_arr[ECCVERIFY_MU2]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + // 10. u2 = mu2 * 1 mod n + ret = drv_cipher_pke_mul_mod(&var_arr[ECCVERIFY_MU2], &var_arr[ECCVERIFY_ONE], &var_arr[ECCVERIFY_ECC_N], + &var_arr[ECCVERIFY_U2]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + // 11. u1G = u1 * G + ret = drv_cipher_pke_mul_dot(ecc, &var_arr[ECCVERIFY_U1], &ecc_gpoint, &u1_point); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_dot failed, ret is 0x%x\n", ret); + + // 12. u2Q = u2 * Qu + ret = drv_cipher_pke_mul_dot(ecc, &var_arr[ECCVERIFY_U2], pub_key, &u2_point); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_dot failed, ret is 0x%x\n", ret); + + // 13. R = u1G + u2Q + ret = drv_cipher_pke_add_dot(ecc, &u1_point, &u2_point, &r_point); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_add_dot failed, ret is 0x%x\n", ret); + + // 14. v= (xR + 0) mod n + ret = drv_cipher_pke_add_mod(&var_arr[ECCVERIFY_RX], &var_arr[ECCVERIFY_ZERO], &var_arr[ECCVERIFY_ECC_N], + &var_arr[ECCVERIFY_V]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_add_mod failed, ret is 0x%x\n", ret); + + // v = r ? + if (memcmp(sig->r, var_arr[ECCVERIFY_V].data, klen) != 0) { + crypto_log_err("Error! r != v!\n"); + ret = PKE_COMPAT_ERRNO(ERROR_PKE_ECDSA_VERIFY_CHECK); + } + +exit__: + (void)drv_cipher_pke_clean_ram(); + if (buffer != TD_NULL) { + (void)memset_s(buffer, klen * ECDSA_VERIFY_BUF_CNT, 0, klen * ECDSA_VERIFY_BUF_CNT); + crypto_free(buffer); + buffer = TD_NULL; + } + return ret; +} + +static td_s32 sha512_modq(const drv_pke_data *q, const drv_pke_data *in1, const drv_pke_data *in2, + const drv_pke_data *in3, const drv_pke_data *out) +{ + td_s32 ret = TD_FAILURE; + td_u8 h[DRV_PKE_LEN_512]; + td_u8 hash[DRV_PKE_LEN_512]; + td_u32 i = 0; + drv_pke_data arr[ED25519_MAX_HASH_ELEMENTS]; + drv_pke_data hash_data = {DRV_PKE_LEN_512, hash}; + const drv_pke_data h_data = {DRV_PKE_LEN_512, h}; + + /* H = Hash(in1 || in2 || in3) */ + if ((in1 != TD_NULL) && (in1->data != TD_NULL)) { + arr[i].data = in1->data; + arr[i].length = in1->length; + i++; + } + if ((in2 != TD_NULL) && (in2->data != TD_NULL)) { + arr[i].data = in2->data; + arr[i].length = in2->length; + i++; + } + if ((in3 != TD_NULL) && (in3->data != TD_NULL)) { + arr[i].data = in3->data; + arr[i].length = in3->length; + i++; + } + ret = drv_cipher_pke_calc_hash(arr, i, DRV_PKE_HASH_TYPE_SHA512, &hash_data); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_pke_calc_hash failed, ret is 0x%x\n", ret); + for (i = 0; i < DRV_PKE_LEN_512; i++) { + h[i] = hash[DRV_PKE_LEN_512 - 1 - i]; + } + /* For efficiency, reduce k modulo L first. L equals to ecc->n */ + ret = drv_cipher_pke_mod(&h_data, q, out); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mod failed, ret is 0x%x\n", ret); +exit__: + (void)drv_cipher_pke_clean_ram(); + return ret; +} + +/* out = in ^ k mod n */ +static td_s32 ed_exp_mod(const td_u8 *n, const td_u8 *k, const td_u8 *in, td_u8 *out) +{ + td_s32 ret = TD_FAILURE; + td_u8 *nn; + td_u8 *kk; + td_u8 *ii; + td_u8 *oo; + td_u32 i = 0; + drv_pke_data n_data; + drv_pke_data k_data; + drv_pke_data i_data; + drv_pke_data o_data; + td_u8 *buffer; + buffer = crypto_malloc(DRV_PKE_LEN_2048 * 4); // need buffer num is 4 + if (buffer == TD_NULL) { + crypto_log_err("%s:%d Error! Malloc memory failed!\n", __FUNCTION__, __LINE__); + return PKE_COMPAT_ERRNO(ERROR_MALLOC); + } + (void)memset_s(buffer, DRV_PKE_LEN_2048 * 4, 0x00, DRV_PKE_LEN_2048 * 4); // need buffer num is 4 + + nn = buffer + DRV_PKE_LEN_2048 * i++; + kk = buffer + DRV_PKE_LEN_2048 * i++; + ii = buffer + DRV_PKE_LEN_2048 * i++; + oo = buffer + DRV_PKE_LEN_2048 * i++; + n_data = (drv_pke_data){DRV_PKE_LEN_2048, nn}; + k_data = (drv_pke_data){DRV_PKE_LEN_2048, kk}; + i_data = (drv_pke_data){DRV_PKE_LEN_2048, ii}; + o_data = (drv_pke_data){DRV_PKE_LEN_2048, oo}; + + for (i = 0; i < DRV_PKE_LEN_256; i++) { + nn[i + DRV_PKE_LEN_2048 - DRV_PKE_LEN_256] = n[i]; + kk[i + DRV_PKE_LEN_2048 - DRV_PKE_LEN_256] = k[i]; + ii[i + DRV_PKE_LEN_2048 - DRV_PKE_LEN_256] = in[i]; + } + ret = drv_cipher_pke_exp_mod(&n_data, &k_data, &i_data, &o_data); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_exp_mod failed, ret is 0x%x\n", ret); + for (i = 0; i < DRV_PKE_LEN_256; i++) { + out[i] = oo[i + DRV_PKE_LEN_2048 - DRV_PKE_LEN_256]; + } +exit__: + (void)drv_cipher_pke_clean_ram(); + if (buffer != TD_NULL) { + (void)memset_s(buffer, DRV_PKE_LEN_2048 * 4, 0x00, DRV_PKE_LEN_2048 * 4); // need free buffer num is 4 + crypto_free(buffer); + } + return ret; +} + +static td_s32 generate_x(const drv_pke_ecc_curve *ecc, const td_u8 *x2, td_u8 *x, const td_u32 klen) +{ + td_s32 ret = TD_FAILURE; + td_u32 i; + drv_pke_data var_arr[GENERATE_X_VAR_MAX]; + td_u8 *buffer; + + buffer = crypto_malloc(klen * GENERATE_X_BUF_CNT); + if (buffer == TD_NULL) { + crypto_log_err("%s:%d Error! Malloc memory failed!\n", __FUNCTION__, __LINE__); + return PKE_COMPAT_ERRNO(ERROR_MALLOC); + } + (void)memset_s(buffer, klen * GENERATE_X_BUF_CNT, 0, klen * GENERATE_X_BUF_CNT); + + for (i = 0; i < GENERATE_X_VAR_MAX; i++) { + if (i <= GENERATEX_THREE) { + var_arr[i].data = buffer + klen * i; + } + var_arr[i].length = klen; + } + var_arr[GENERATEX_ECC_P].data = (td_u8 *)ecc->p; + var_arr[GENERATEX_X].data = x; + var_arr[GENERATEX_X2].data = (td_u8 *)x2; + var_arr[GENERATEX_ONE].data[klen - 1] = 0x1; + var_arr[GENERATEX_TWO].data[klen - 1] = 0x2; // 0x2 : GENERATEX_TWO + var_arr[GENERATEX_THREE].data[klen - 1] = 0x3; // 0x3 : GENERATEX_THREE + + /* x = x2 ^ ((p + 3) // 8) mod p */ + ret = drv_cipher_pke_add_mod(&var_arr[GENERATEX_ECC_P], &var_arr[GENERATEX_THREE], &var_arr[GENERATEX_MAX], + &var_arr[GENERATEX_P38]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_add_mod failed, ret is 0x%x\n", ret); + + for (i = DRV_PKE_LEN_256 - 1; i > 0; i--) { + var_arr[GENERATEX_P38].data[i] = ((var_arr[GENERATEX_P38].data[i] & 0xF8) >> 3) | /* shift 3 */ + ((var_arr[GENERATEX_P38].data[i - 1] & 0x07) << 5); /* shift 3 5 */ + } + var_arr[GENERATEX_P38].data[0] = (var_arr[GENERATEX_P38].data[0] & 0xF8) >> 3; /* shift 3 */ + ret = ed_exp_mod(ecc->p, var_arr[GENERATEX_P38].data, x2, x); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "ed_exp_mod failed, ret is 0x%x\n", ret); + /* xx = x ^ 2 mod p */ + ret = ed_exp_mod(ecc->p, var_arr[GENERATEX_TWO].data, x, var_arr[GENERATEX_XX].data); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "ed_exp_mod failed, ret is 0x%x\n", ret); + /* c = xx - x2 mod p */ + ret = drv_cipher_pke_sub_mod(&var_arr[GENERATEX_XX], &var_arr[GENERATEX_X2], &var_arr[GENERATEX_ECC_P], + &var_arr[GENERATEX_C]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_sub_mod failed, ret is 0x%x\n", ret); + if (drv_ecc_is_zero(var_arr[GENERATEX_C].data, klen)) { + ret = TD_SUCCESS; + goto exit__; + } + /* c = xx + x2 mod p */ + ret = drv_cipher_pke_add_mod(&var_arr[GENERATEX_XX], &var_arr[GENERATEX_X2], &var_arr[GENERATEX_ECC_P], + &var_arr[GENERATEX_C]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_add_mod failed, ret is 0x%x\n", ret); + if (drv_ecc_is_zero(var_arr[GENERATEX_C].data, klen) != TD_TRUE) { + ret = TD_FAILURE; + goto exit__; + } + /* s = 2 ^ ((p - 1) / 4) mod p */ + ret = drv_cipher_pke_sub_mod(&var_arr[GENERATEX_ECC_P], &var_arr[GENERATEX_ONE], &var_arr[GENERATEX_ECC_P], + &var_arr[GENERATEX_P14]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_sub_mod failed, ret is 0x%x\n", ret); + for (i = DRV_PKE_LEN_256 - 1; i > 0; i--) { + var_arr[GENERATEX_P14].data[i] = ((var_arr[GENERATEX_P14].data[i] & 0xFC) >> 2) | /* shift 2 */ + ((var_arr[GENERATEX_P14].data[i - 1] & 0x03) << 6); /* shift 2 6 */ + } + var_arr[GENERATEX_P14].data[0] = (var_arr[GENERATEX_P14].data[0] & 0xFC) >> 2; /* shift 2 */ + ret = ed_exp_mod(ecc->p, var_arr[GENERATEX_P14].data, var_arr[GENERATEX_TWO].data, var_arr[GENERATEX_S].data); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "ed_exp_mod failed, ret is 0x%x\n", ret); + ret = cal_montgomery_n(&var_arr[GENERATEX_ECC_P], &var_arr[GENERATEX_MONTGOMERY_P]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "cal_montgomery_n failed, ret is 0x%x\n", ret); + /* x = x * sqrt mod p */ + /* x -> mx */ + ret = drv_cipher_pke_mul_mod(&var_arr[GENERATEX_X], &var_arr[GENERATEX_MONTGOMERY_P], &var_arr[GENERATEX_ECC_P], + &var_arr[GENERATEX_MX]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + /* s -> ms */ + ret = drv_cipher_pke_mul_mod(&var_arr[GENERATEX_S], &var_arr[GENERATEX_MONTGOMERY_P], &var_arr[GENERATEX_ECC_P], + &var_arr[GENERATEX_MS]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + /* mxs = mx * ms mod p */ + ret = drv_cipher_pke_mul_mod(&var_arr[GENERATEX_MX], &var_arr[GENERATEX_MS], &var_arr[GENERATEX_ECC_P], + &var_arr[GENERATEX_MXS]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + /* x' = mxs * 1 mod p */ + ret = drv_cipher_pke_mul_mod(&var_arr[GENERATEX_MXS], &var_arr[GENERATEX_ONE], &var_arr[GENERATEX_ECC_P], + &var_arr[GENERATEX_X]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); +exit__: + (void)drv_cipher_pke_clean_ram(); + if (buffer != TD_NULL) { + (void)memset_s(buffer, klen * GENERATE_X_BUF_CNT, 0, klen * GENERATE_X_BUF_CNT); + crypto_free(buffer); + } + return ret; +} + +static td_s32 point_decompress(const drv_pke_ecc_curve *ecc, const drv_pke_data *in, const drv_pke_ecc_point *out) +{ + td_s32 ret = TD_FAILURE; + td_u32 i; + td_u32 sign = 0; + td_u32 klen = DRV_PKE_LEN_256; + drv_pke_data var_arr[POINT_DECOMPRESS_VAR_MAX]; + td_u8 *buffer; + + buffer = crypto_malloc(klen * POINT_DECOMPRESS_BUF_CNT); + if (buffer == TD_NULL) { + crypto_log_err("%s:%d Error! Malloc memory failed!\n", __FUNCTION__, __LINE__); + return PKE_COMPAT_ERRNO(ERROR_MALLOC); + } + (void)memset_s(buffer, klen * POINT_DECOMPRESS_BUF_CNT, 0, klen * POINT_DECOMPRESS_BUF_CNT); + for (i = 0; i < POINT_DECOMPRESS_VAR_MAX; i++) { + if (i <= POINTDECOMPRESS_MONE) { + var_arr[i].data = buffer + klen * i; + } + var_arr[i].length = klen; + } + var_arr[POINTDECOMPRESS_ECC_P].data = (td_u8 *)ecc->p; + var_arr[POINTDECOMPRESS_ECC_A].data = (td_u8 *)ecc->a; + var_arr[POINTDECOMPRESS_OUTX].data = out->x; + var_arr[POINTDECOMPRESS_OUTY].data = out->y; + var_arr[POINTDECOMPRESS_ONE].data[klen - 1] = 0x1; + + for (i = 0; i < klen; i++) { + out->y[i] = in->data[klen - 1 - i]; + } + sign = out->y[0] >> 7; /* shift 7 */ + out->y[0] &= 0x7F; /* y is recovered by clearing 255 bit */ + + ret = cal_montgomery_n(&var_arr[POINTDECOMPRESS_ECC_P], &var_arr[POINTDECOMPRESS_MONTGOMERY_P]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "cal_montgomery_n failed, ret is 0x%x\n", ret); + /* y -> my */ + ret = drv_cipher_pke_mul_mod(&var_arr[POINTDECOMPRESS_OUTY], &var_arr[POINTDECOMPRESS_MONTGOMERY_P], + &var_arr[POINTDECOMPRESS_ECC_P], &var_arr[POINTDECOMPRESS_MY]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + /* my2 = my * my mod p */ + ret = drv_cipher_pke_mul_mod(&var_arr[POINTDECOMPRESS_MY], &var_arr[POINTDECOMPRESS_MY], + &var_arr[POINTDECOMPRESS_ECC_P], &var_arr[POINTDECOMPRESS_MY2]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + /* 1 -> m1 */ + ret = drv_cipher_pke_mul_mod(&var_arr[POINTDECOMPRESS_ONE], &var_arr[POINTDECOMPRESS_MONTGOMERY_P], + &var_arr[POINTDECOMPRESS_ECC_P], &var_arr[POINTDECOMPRESS_MONE]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + /* my21 = my2 - m1 mod p */ + ret = drv_cipher_pke_sub_mod(&var_arr[POINTDECOMPRESS_MY2], &var_arr[POINTDECOMPRESS_MONE], + &var_arr[POINTDECOMPRESS_ECC_P], &var_arr[POINTDECOMPRESS_MY21]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + /* d -> md */ + ret = drv_cipher_pke_mul_mod(&var_arr[POINTDECOMPRESS_ECC_A], &var_arr[POINTDECOMPRESS_MONTGOMERY_P], + &var_arr[POINTDECOMPRESS_ECC_P], &var_arr[POINTDECOMPRESS_MD]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + /* mdy2 = md * my2 mod p */ + ret = drv_cipher_pke_mul_mod(&var_arr[POINTDECOMPRESS_MD], &var_arr[POINTDECOMPRESS_MY2], + &var_arr[POINTDECOMPRESS_ECC_P], &var_arr[POINTDECOMPRESS_MDY2]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + /* mdy21 = mdy2 + m1 mod p */ + ret = drv_cipher_pke_add_mod(&var_arr[POINTDECOMPRESS_MDY2], &var_arr[POINTDECOMPRESS_MONE], + &var_arr[POINTDECOMPRESS_ECC_P], &var_arr[POINTDECOMPRESS_MDY21]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_add_mod failed, ret is 0x%x\n", ret); + /* minv = mdy21 ^ -1 mod p */ + ret = drv_cipher_pke_inv_mod(&var_arr[POINTDECOMPRESS_MDY21], &var_arr[POINTDECOMPRESS_ECC_P], + &var_arr[POINTDECOMPRESS_MINV]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_inv_mod failed, ret is 0x%x\n", ret); + /* mx2 = my21 * minv */ + ret = drv_cipher_pke_mul_mod(&var_arr[POINTDECOMPRESS_MY21], &var_arr[POINTDECOMPRESS_MINV], + &var_arr[POINTDECOMPRESS_ECC_P], &var_arr[POINTDECOMPRESS_MX2]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + /* x2 = mx2 * 1 mod p */ + ret = drv_cipher_pke_mul_mod(&var_arr[POINTDECOMPRESS_MX2], &var_arr[POINTDECOMPRESS_ONE], + &var_arr[POINTDECOMPRESS_ECC_P], &var_arr[POINTDECOMPRESS_X2]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + if (drv_ecc_is_zero(var_arr[POINTDECOMPRESS_X2].data, klen)) { + if (sign == 0) { + (void)memset_s(out->x, klen, 0x00, klen); + ret = TD_SUCCESS; + goto exit__; + } else { + ret = TD_FAILURE; + goto exit__; + } + } + ret = generate_x(ecc, var_arr[POINTDECOMPRESS_X2].data, var_arr[POINTDECOMPRESS_X].data, klen); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "generate_x failed, ret is 0x%x\n", ret); + if ((var_arr[POINTDECOMPRESS_X].data[klen - 1] & 0x1) != sign) { + /* x = p - x */ + ret = drv_cipher_pke_sub_mod(&var_arr[POINTDECOMPRESS_ECC_P], &var_arr[POINTDECOMPRESS_X], + &var_arr[POINTDECOMPRESS_ECC_P], &var_arr[POINTDECOMPRESS_OUTX]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_sub_mod failed, ret is 0x%x\n", ret); + } else { + ret = memcpy_s(out->x, out->length, var_arr[POINTDECOMPRESS_X].data, klen); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "memcpy_s failed, ret is 0x%x\n", ret); + } +exit__: + (void)drv_cipher_pke_clean_ram(); + if (buffer != TD_NULL) { + (void)memset_s(buffer, klen * POINT_DECOMPRESS_BUF_CNT, 0, klen * POINT_DECOMPRESS_BUF_CNT); + crypto_free(buffer); + } + return ret; +} + +static td_s32 pke_eddsa_sign(const drv_pke_ecc_curve *ecc, const drv_pke_data *priv_key, + const drv_pke_msg *msg, const drv_pke_ecc_sig *sig) +{ + td_s32 ret = TD_FAILURE; + td_u32 i; + td_u32 klen = DRV_PKE_LEN_256; + drv_pke_data var_arr[PKE_EDDSA_SIGN_VAR_MAX]; + td_u8 *buffer; + + buffer = crypto_malloc(klen * EDDSA_SIGN_BUF_CNT); + crypto_chk_return(buffer == TD_NULL, PKE_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + (void)memset_s(buffer, klen * EDDSA_SIGN_BUF_CNT, 0, klen * EDDSA_SIGN_BUF_CNT); + + for (i = 0; i < PKE_EDDSA_SIGN_VAR_MAX - 1; i++) { + if (i <= EDDSIGN_ONE) { + var_arr[i].data = buffer + klen * i; + } + var_arr[i].length = klen; + } + var_arr[EDDSIGN_ECC_N].data = (td_u8 *)ecc->n; + var_arr[EDDSIGN_MSG].data = msg->data; + var_arr[EDDSIGN_MSG].length = msg->length; + var_arr[EDDSIGN_ONE].data[klen - 1] = 0x1; + + /* Operation: a, prefix = secret_expand(secret) */ + ret = secret_expand(priv_key->data, var_arr[EDDSIGN_A].data, var_arr[EDDSIGN_PREFIX].data, klen); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "secret_expand failed, ret is 0x%x\n", ret); + + /* Operation: A = point_compress(point_mul(a, G)) */ + ret = point_mul_compress(ecc, var_arr[EDDSIGN_A].data, var_arr[EDDSIGN_PUBKEY].data, klen); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "point_mul_compress failed, ret is 0x%x\n", ret); + + /* Operation: r = sha512_modq(prefix + msg) */ + ret = sha512_modq(&var_arr[EDDSIGN_ECC_N], TD_NULL, &var_arr[EDDSIGN_PREFIX], &var_arr[EDDSIGN_MSG], + &var_arr[EDDSIGN_R]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "sha512_modq failed, ret is 0x%x\n", ret); + + /* Operation: Rs = point_compress(point_mul(r, G)) */ + ret = point_mul_compress(ecc, var_arr[EDDSIGN_R].data, var_arr[EDDSIGN_RS].data, klen); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "point_mul_compress failed, ret is 0x%x\n", ret); + + /* Operation: h = sha512_modq(Rs + A + msg) */ + ret = sha512_modq(&var_arr[EDDSIGN_ECC_N], &var_arr[EDDSIGN_RS], &var_arr[EDDSIGN_PUBKEY], + &var_arr[EDDSIGN_MSG], &var_arr[EDDSIGN_H]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "sha512_modq failed, ret is 0x%x\n", ret); + + ret = cal_montgomery_n(&var_arr[EDDSIGN_ECC_N], &var_arr[EDDSIGN_MONTGOMERY_N]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "cal_montgomery_n failed, ret is 0x%x\n", ret); + + /* Operation: pseudocode is s = (r + h * a) % q; h -> mh */ + ret = drv_cipher_pke_mul_mod(&var_arr[EDDSIGN_H], &var_arr[EDDSIGN_MONTGOMERY_N], &var_arr[EDDSIGN_ECC_N], + &var_arr[EDDSIGN_MH]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + /* Operation: a -> ma */ + ret = drv_cipher_pke_mul_mod(&var_arr[EDDSIGN_A], &var_arr[EDDSIGN_MONTGOMERY_N], &var_arr[EDDSIGN_ECC_N], + &var_arr[EDDSIGN_MA]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + /* Operation: mha = mh * ma mod q */ + ret = drv_cipher_pke_mul_mod(&var_arr[EDDSIGN_MH], &var_arr[EDDSIGN_MA], &var_arr[EDDSIGN_ECC_N], + &var_arr[EDDSIGN_MHA]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + /* Operation: r -> mr */ + ret = drv_cipher_pke_mul_mod(&var_arr[EDDSIGN_R], &var_arr[EDDSIGN_MONTGOMERY_N], &var_arr[EDDSIGN_ECC_N], + &var_arr[EDDSIGN_MR]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + /* Operation: ms = mr + mha mod q */ + ret = drv_cipher_pke_add_mod(&var_arr[EDDSIGN_MHA], &var_arr[EDDSIGN_MR], &var_arr[EDDSIGN_ECC_N], + &var_arr[EDDSIGN_MS]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_add_mod failed, ret is 0x%x\n", ret); + + /* Operation: s = ms * 1 mod q */ + ret = drv_cipher_pke_mul_mod(&var_arr[EDDSIGN_MS], &var_arr[EDDSIGN_ONE], &var_arr[EDDSIGN_ECC_N], + &var_arr[EDDSIGN_S]); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_mul_mod failed, ret is 0x%x\n", ret); + + /* Operation: return Rs + int.to_bytes(s, 32, "little") */ + ret = memcpy_s(sig->r, sig->length, var_arr[EDDSIGN_RS].data, klen); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "memcpy_s failed, ret is 0x%x\n", ret); + for (i = 0; i < klen; i++) { + sig->s[i] = var_arr[EDDSIGN_S].data[klen - 1 - i]; + } +exit__: + (void)drv_cipher_pke_clean_ram(); + if (buffer != TD_NULL) { + (void)memset_s(buffer, klen * EDDSA_SIGN_BUF_CNT, 0, klen * EDDSA_SIGN_BUF_CNT); + crypto_free(buffer); + } + return ret; +} + +static td_s32 pke_eddsa_verify(const drv_pke_ecc_curve *ecc, const drv_pke_ecc_point *pub_key, + const drv_pke_msg *msg, const drv_pke_ecc_sig *sig) +{ + td_s32 ret = TD_FAILURE; + td_u32 klen = DRV_PKE_LEN_256; + td_u32 i = 0; + drv_pke_data h_data = {.length = klen}; + drv_pke_data s_data = {.length = klen}; + drv_pke_data pubkey_y_data = {klen, pub_key->y}; + drv_pke_data sig_r_data = {klen, sig->r}; + drv_pke_data ecc_n_data = {klen, (td_u8 *)ecc->n}; + drv_pke_data ecc_p_data = {klen, (td_u8 *)ecc->p}; + drv_pke_data msg_data = {msg->length, msg->data}; + drv_pke_ecc_point ecc_a_point = {.length = klen}; + drv_pke_ecc_point ecc_g_point = {(td_u8 *)ecc->gx, (td_u8 *)ecc->gy, klen}; + drv_pke_ecc_point ecc_r_point = {.length = klen}; + drv_pke_ecc_point ecc_sB_point = {.length = klen}; + drv_pke_ecc_point ecc_hA_point = {.length = klen}; + drv_pke_ecc_point ecc_rhA_point = {.length = klen}; + td_u8 *buffer; + + buffer = crypto_malloc(klen * EDDSA_VERIFY_BUF_CNT); + crypto_chk_return(buffer == TD_NULL, PKE_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + (void)memset_s(buffer, klen * EDDSA_VERIFY_BUF_CNT, 0, klen * EDDSA_VERIFY_BUF_CNT); + + h_data.data = buffer + klen * i++; + s_data.data = buffer + klen * i++; + ecc_a_point.x = buffer + klen * i++; + ecc_a_point.y = buffer + klen * i++; + ecc_r_point.x = buffer + klen * i++; + ecc_r_point.y = buffer + klen * i++; + ecc_sB_point.x = buffer + klen * i++; + ecc_sB_point.y = buffer + klen * i++; + ecc_hA_point.x = buffer + klen * i++; + ecc_hA_point.y = buffer + klen * i++; + ecc_rhA_point.x = buffer + klen * i++; + ecc_rhA_point.y = buffer + klen * i++; + /* ecc_a = point_decompress(public) */ + ret = point_decompress(ecc, &pubkey_y_data, &ecc_a_point); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "point_mul_compress failed, ret is 0x%x\n", ret); + /* ecc_rs = signature[:32] */ + /* ecc_r = point_decompress(Rs) */ + ret = point_decompress(ecc, &sig_r_data, &ecc_r_point); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "point_mul_compress failed, ret is 0x%x\n", ret); + /* s = int.from_bytes(signature[32:], "little") */ + for (i = 0; i < klen; i++) { + s_data.data[i] = sig->s[klen - 1 - i]; + } + /* h = sha512_modq(Rs + public + msg) */ + ret = sha512_modq(&ecc_n_data, &sig_r_data, &pubkey_y_data, &msg_data, &h_data); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "sha512_modq failed, ret is 0x%x\n", ret); + /* ecc_sb = point_mul(ecc_s, ecc_g) */ + ret = drv_cipher_pke_ed_mul_dot(&s_data, &ecc_g_point, &ecc_p_data, &ecc_sB_point); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_ed_mul_dot failed, ret is 0x%x\n", ret); + /* ecc_ha = point_mul(h, ecc_a) */ + ret = drv_cipher_pke_ed_mul_dot(&h_data, &ecc_a_point, &ecc_p_data, &ecc_hA_point); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_ed_mul_dot failed, ret is 0x%x\n", ret); + /* return point_equal(ecc_sb, point_add(ecc_r, ecc_ha)) */ + ret = drv_cipher_pke_ed_add_dot(ecc, &ecc_r_point, &ecc_hA_point, &ecc_rhA_point); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_ed_add_dot failed, ret is 0x%x\n", ret); + + if ((memcmp(ecc_sB_point.x, ecc_rhA_point.x, klen) != 0) || (memcmp(ecc_sB_point.y, ecc_rhA_point.y, klen) != 0)) { + ret = TD_FAILURE; + goto exit__; + } +exit__: + (void)drv_cipher_pke_clean_ram(); + if (buffer != TD_NULL) { + (void)memset_s(buffer, klen * EDDSA_VERIFY_BUF_CNT, 0, klen * EDDSA_VERIFY_BUF_CNT); + crypto_free(buffer); + } + return ret; +} + +/* expose layer, do param check here */ +td_s32 drv_cipher_pke_ecc_gen_key( + drv_pke_ecc_curve_type curve_type, + const drv_pke_data *input_priv_key, + const drv_pke_data *output_priv_key, + const drv_pke_ecc_point *output_pub_key) +{ + td_s32 ret = TD_FAILURE; + td_u32 klen = 0; + const drv_pke_ecc_curve *ecc_curve = get_ecc_curve(curve_type); + crypto_chk_return(ecc_curve == TD_NULL, PKE_COMPAT_ERRNO(ERROR_UNSUPPORT), "unsupport alg\n"); + + /* check ptr. */ + if (input_priv_key != TD_NULL) { + pke_null_ptr_chk(input_priv_key->data); + } + pke_null_ptr_chk(output_priv_key); + pke_null_ptr_chk(output_priv_key->data); + pke_null_ptr_chk(output_pub_key); + if (curve_type != DRV_PKE_ECC_TYPE_RFC8032) { + pke_null_ptr_chk(output_pub_key->x); + } + if (curve_type != DRV_PKE_ECC_TYPE_RFC7748) { + pke_null_ptr_chk(output_pub_key->y); + } + + /* check curve_type. */ + crypto_chk_return(curve_type >= DRV_PKE_ECC_TYPE_MAX, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "curve_type is Invalid\n"); + + /* check length. */ + klen = ecc_curve->ksize; + if (input_priv_key != TD_NULL) { + crypto_chk_return(input_priv_key->length != klen, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "input_priv_key->length is Invalid\n"); + } + crypto_chk_return(output_priv_key->length != klen, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "output_priv_key->length is Invalid\n"); + crypto_chk_return(output_pub_key->length != klen, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "output_pub_key->length is Invalid\n"); + + ret = drv_cipher_pke_lock_secure(); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_pke_lock_secure failed, ret is 0x%x\n", ret); + ret = pke_ecc_gen_key(ecc_curve, input_priv_key, output_priv_key, output_pub_key); + (void)drv_cipher_pke_unlock_secure(); + return ret; +} + +td_s32 drv_cipher_pke_ecc_gen_ecdh_key( + drv_pke_ecc_curve_type curve_type, + const drv_pke_ecc_point *input_pub_key, + const drv_pke_data *input_priv_key, + const drv_pke_data *output_shared_key) +{ + td_s32 ret = TD_FAILURE; + td_u32 klen = 0; + const drv_pke_ecc_curve *ecc_curve = get_ecc_curve(curve_type); + crypto_chk_return(curve_type >= DRV_PKE_ECC_TYPE_MAX, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "Invalid curve_type\n"); + crypto_chk_return(ecc_curve == TD_NULL, PKE_COMPAT_ERRNO(ERROR_UNSUPPORT), "unsupport alg\n"); + + /* check ptr. */ + pke_null_ptr_chk(input_pub_key); + pke_null_ptr_chk(input_pub_key->x); + if (curve_type != DRV_PKE_ECC_TYPE_RFC7748) { + pke_null_ptr_chk(input_pub_key->y); + } + pke_null_ptr_chk(input_priv_key); + pke_null_ptr_chk(input_priv_key->data); + pke_null_ptr_chk(output_shared_key); + pke_null_ptr_chk(output_shared_key->data); + + /* check curve_type. */ + crypto_chk_return(curve_type >= DRV_PKE_ECC_TYPE_MAX || curve_type == DRV_PKE_ECC_TYPE_RFC8032, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "curve_type is Invalid\n"); + + /* check length. */ + klen = ecc_curve->ksize; + crypto_chk_return(input_pub_key->length != klen, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "input_pub_key->length is Invalid\n"); + crypto_chk_return(input_priv_key->length != klen, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "input_priv_key->length is Invalid\n"); + crypto_chk_return(output_shared_key->length != klen, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "output_shared_key->length is Invalid\n"); + + ret = drv_cipher_pke_lock_secure(); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_pke_lock_secure failed, ret is 0x%x\n", ret); + ret = pke_ecc_gen_ecdh_key(ecc_curve, input_pub_key, input_priv_key, output_shared_key); + (void)drv_cipher_pke_unlock_secure(); + return ret; +} + +td_s32 drv_cipher_pke_ecdsa_sign( + drv_pke_ecc_curve_type curve_type, + const drv_pke_data *priv_key, + const drv_pke_data *hash, + const drv_pke_ecc_sig *sig) +{ + td_s32 ret = TD_FAILURE; + td_u32 klen = 0; + td_u32 hash_len = 0; + const drv_pke_ecc_curve *ecc_curve = get_ecc_curve(curve_type); + crypto_chk_return(ecc_curve == TD_NULL, PKE_COMPAT_ERRNO(ERROR_UNSUPPORT), "unsupport alg\n"); + + /* check ptr. */ + pke_null_ptr_chk(priv_key); + pke_null_ptr_chk(priv_key->data); + pke_null_ptr_chk(hash); + pke_null_ptr_chk(hash->data); + pke_null_ptr_chk(sig); + pke_null_ptr_chk(sig->r); + pke_null_ptr_chk(sig->s); + + /* check curve_type. */ + crypto_chk_return(curve_type >= DRV_PKE_ECC_TYPE_MAX || curve_type == DRV_PKE_ECC_TYPE_RFC8032 || + curve_type == DRV_PKE_ECC_TYPE_RFC7748, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "curve_type is Invalid\n"); + + /* check length. */ + klen = ecc_curve->ksize; + hash_len = hash->length; + if ((priv_key->length != klen) || + (hash_len != DRV_PKE_LEN_256 && hash_len != DRV_PKE_LEN_384 && hash_len != DRV_PKE_LEN_512)) { + ret = PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM); + crypto_log_err("priv_key->length or hash_len is Invaild!\n"); + return ret; + } + crypto_chk_return(sig->length != klen, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "sig->length is Invalid\n"); + + ret = drv_cipher_pke_lock_secure(); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_pke_lock_secure failed, ret is 0x%x\n", ret); + ret = pke_ecdsa_sign(ecc_curve, priv_key, hash, sig); + (void)drv_cipher_pke_unlock_secure(); + return ret; +} + +td_s32 drv_cipher_pke_ecdsa_verify( + drv_pke_ecc_curve_type curve_type, + const drv_pke_ecc_point *pub_key, + const drv_pke_data *hash, + const drv_pke_ecc_sig *sig) +{ + td_s32 ret = TD_FAILURE; + td_u32 klen = 0; + td_u32 hash_len = 0; + const drv_pke_ecc_curve *ecc_curve = get_ecc_curve(curve_type); + crypto_chk_return(ecc_curve == TD_NULL, PKE_COMPAT_ERRNO(ERROR_UNSUPPORT), "unsupport alg\n"); + + /* check ptr. */ + pke_null_ptr_chk(pub_key); + pke_null_ptr_chk(pub_key->x); + pke_null_ptr_chk(pub_key->y); + pke_null_ptr_chk(hash); + pke_null_ptr_chk(hash->data); + pke_null_ptr_chk(sig); + pke_null_ptr_chk(sig->r); + pke_null_ptr_chk(sig->s); + + /* check curve_type. */ + crypto_chk_return(curve_type >= DRV_PKE_ECC_TYPE_MAX || curve_type == DRV_PKE_ECC_TYPE_RFC8032 || + curve_type == DRV_PKE_ECC_TYPE_RFC7748, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "curve_type is Invalid\n"); + + /* check length. */ + klen = ecc_curve->ksize; + hash_len = hash->length; + if ((pub_key->length != klen) || + (hash_len != DRV_PKE_LEN_256 && hash_len != DRV_PKE_LEN_384 && hash_len != DRV_PKE_LEN_512)) { + ret = PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM); + crypto_log_err("pub_key->length or hash_len is Invaild!\n"); + return ret; + } + crypto_chk_return(sig->length != klen, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "sig->length is Invalid\n"); + + ret = drv_cipher_pke_lock_secure(); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_pke_lock_secure failed, ret is 0x%x\n", ret); + ret = pke_ecdsa_verify(ecc_curve, pub_key, hash, sig); + (void)drv_cipher_pke_unlock_secure(); + return ret; +} + +td_s32 drv_cipher_pke_eddsa_sign( + drv_pke_ecc_curve_type curve_type, + const drv_pke_data *priv_key, + const drv_pke_msg *msg, + const drv_pke_ecc_sig *sig) +{ + td_s32 ret = TD_FAILURE; + td_u32 klen = 0; + const drv_pke_ecc_curve *ecc_curve = get_ecc_curve(curve_type); + crypto_chk_return(ecc_curve == TD_NULL, PKE_COMPAT_ERRNO(ERROR_UNSUPPORT), "unsupport alg\n"); + + /* check ptr. */ + pke_null_ptr_chk(priv_key); + pke_null_ptr_chk(priv_key->data); + pke_null_ptr_chk(msg); + pke_null_ptr_chk(msg->data); + pke_null_ptr_chk(sig); + pke_null_ptr_chk(sig->r); + pke_null_ptr_chk(sig->s); + + /* check curve_type. */ + crypto_chk_return(curve_type != DRV_PKE_ECC_TYPE_RFC8032, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "curve_type is Invalid\n"); + + /* check length. */ + klen = ecc_curve->ksize; + crypto_chk_return(priv_key->length != klen, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "priv_key->length is Invalid\n"); + crypto_chk_return(sig->length != klen, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "sig->length is Invalid\n"); + + ret = drv_cipher_pke_lock_secure(); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_pke_lock_secure failed, ret is 0x%x\n", ret); + ret = pke_eddsa_sign(ecc_curve, priv_key, msg, sig); + (void)drv_cipher_pke_unlock_secure(); + return ret; +} + +td_s32 drv_cipher_pke_eddsa_verify( + drv_pke_ecc_curve_type curve_type, + const drv_pke_ecc_point *pub_key, + const drv_pke_msg *msg, + const drv_pke_ecc_sig *sig) +{ + td_s32 ret = TD_FAILURE; + td_u32 klen = 0; + const drv_pke_ecc_curve *ecc_curve = get_ecc_curve(curve_type); + crypto_chk_return(ecc_curve == TD_NULL, PKE_COMPAT_ERRNO(ERROR_UNSUPPORT), "unsupport alg\n"); + + /* check ptr. */ + pke_null_ptr_chk(pub_key); + pke_null_ptr_chk(pub_key->y); + pke_null_ptr_chk(msg); + pke_null_ptr_chk(msg->data); + pke_null_ptr_chk(sig); + pke_null_ptr_chk(sig->r); + pke_null_ptr_chk(sig->s); + + /* check curve_type. */ + crypto_chk_return(curve_type != DRV_PKE_ECC_TYPE_RFC8032, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "curve_type is Invalid\n"); + + /* check length. */ + klen = ecc_curve->ksize; + crypto_chk_return(pub_key->length != klen, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "pub_key->length is Invalid\n"); + crypto_chk_return(sig->length != klen, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "sig->length is Invalid\n"); + + ret = drv_cipher_pke_lock_secure(); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_pke_lock_secure failed, ret is 0x%x\n", ret); + ret = pke_eddsa_verify(ecc_curve, pub_key, msg, sig); + (void)drv_cipher_pke_unlock_secure(); + return ret; +} + +td_s32 drv_cipher_pke_sm2_public_encrypt( + const drv_pke_ecc_point *pub_key, + const drv_pke_data *plain_text, + drv_pke_data *cipher_text) +{ + td_s32 ret = TD_FAILURE; + td_u32 plain_text_len = 0; + td_u32 cipher_text_len = 0; + + /* check ptr. */ + pke_null_ptr_chk(pub_key); + pke_null_ptr_chk(pub_key->x); + pke_null_ptr_chk(pub_key->y); + pke_null_ptr_chk(plain_text); + pke_null_ptr_chk(plain_text->data); + pke_null_ptr_chk(cipher_text); + pke_null_ptr_chk(cipher_text->data); + + /* check length. */ + plain_text_len = plain_text->length; + cipher_text_len = cipher_text->length; + crypto_chk_return(pub_key->length != DRV_PKE_LEN_256, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "pub_key->length is Invalid\n"); + /* For SM2 Crypto, the cipher_text is 97 longer than plain_text. */ + crypto_chk_return(cipher_text_len < plain_text_len + SM2_CRYPTO_ADD_LENGTH_IN_BYTE, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "cipher_text_len is not enough\n"); + + ret = drv_cipher_pke_lock_secure(); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_pke_lock_secure failed, ret is 0x%x\n", ret); + ret = pke_sm2_public_encrypt(pub_key, plain_text, cipher_text); + if (ret == TD_SUCCESS) { + cipher_text->length = plain_text->length + SM2_CRYPTO_ADD_LENGTH_IN_BYTE; + } + (void)drv_cipher_pke_unlock_secure(); + return ret; +} + +td_s32 drv_cipher_pke_sm2_private_decrypt( + const drv_pke_data *priv_key, + const drv_pke_data *cipher_text, + drv_pke_data *plain_text) +{ + td_s32 ret = TD_FAILURE; + td_u32 plain_text_len = 0; + td_u32 cipher_text_len = 0; + + /* check ptr. */ + pke_null_ptr_chk(priv_key); + pke_null_ptr_chk(priv_key->data); + pke_null_ptr_chk(cipher_text); + pke_null_ptr_chk(cipher_text->data); + pke_null_ptr_chk(plain_text); + pke_null_ptr_chk(plain_text->data); + + /* check length. */ + plain_text_len = plain_text->length; + cipher_text_len = cipher_text->length; + crypto_chk_return(priv_key->length != DRV_PKE_LEN_256, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "priv_key->length is Invalid\n"); + /* For SM2 Crypto, the cipher_text is 97 longer than plain_text. */ + crypto_chk_return(plain_text_len > CRYPTO_PKE_SM2_PLAIN_TEXT_MAX_SIZE || + plain_text_len + SM2_CRYPTO_ADD_LENGTH_IN_BYTE < cipher_text_len, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "plain_text_len is not enough\n"); + + ret = drv_cipher_pke_lock_secure(); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_pke_lock_secure failed, ret is 0x%x\n", ret); + ret = pke_sm2_private_decrypt(priv_key, cipher_text, plain_text); + if (ret == TD_SUCCESS) { + plain_text->length = cipher_text_len - SM2_CRYPTO_ADD_LENGTH_IN_BYTE; + } + (void)drv_cipher_pke_unlock_secure(); + return ret; +} + +td_s32 drv_cipher_pke_check_dot_on_curve(drv_pke_ecc_curve_type curve_type, const drv_pke_ecc_point *pub_key, + td_bool *is_on_curve) +{ + td_s32 ret = TD_FAILURE; + td_u32 klen = 0; + const drv_pke_ecc_curve *ecc_curve = get_ecc_curve(curve_type); + crypto_chk_return(ecc_curve == TD_NULL, PKE_COMPAT_ERRNO(ERROR_UNSUPPORT), "unsupport alg\n"); + + /* check ptr. */ + pke_null_ptr_chk(pub_key); + pke_null_ptr_chk(pub_key->x); + pke_null_ptr_chk(pub_key->y); + pke_null_ptr_chk(is_on_curve); + + /* check curve_type. */ + crypto_chk_return(curve_type == DRV_PKE_ECC_TYPE_RFC7748 || curve_type == DRV_PKE_ECC_TYPE_RFC8032, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "curve_type is Invalid\n"); + + /* check length. */ + klen = ecc_curve->ksize; + crypto_chk_return(pub_key->length != klen, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "pub_key->length is Invalid\n"); + + ret = drv_cipher_pke_lock_secure(); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_pke_lock_secure failed, ret is 0x%x\n", ret); + ret = pke_check_dot_on_curve(ecc_curve, pub_key, is_on_curve); + (void)drv_cipher_pke_unlock_secure(); + return ret; +} + +td_s32 drv_cipher_pke_sm2_dsa_hash(const drv_pke_data *sm2_id, const drv_pke_ecc_point *pub_key, + const drv_pke_msg *msg, drv_pke_data *hash) +{ + td_s32 ret = TD_FAILURE; + sm2_sign_verify_hash_pack hash_param; + drv_pke_data hash_data; + + /* check ptr. */ + pke_null_ptr_chk(sm2_id); + pke_null_ptr_chk(sm2_id->data); + pke_null_ptr_chk(pub_key); + pke_null_ptr_chk(pub_key->x); + pke_null_ptr_chk(pub_key->y); + pke_null_ptr_chk(msg); + pke_null_ptr_chk(msg->data); + pke_null_ptr_chk(hash); + pke_null_ptr_chk(hash->data); + + /* check length. */ + crypto_chk_return(pub_key->length != DRV_PKE_SM2_LEN_IN_BYTES, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "pub_key->length is Invalid\n"); + crypto_chk_return(hash->length != DRV_PKE_SM2_LEN_IN_BYTES, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "hash_len is Invalid\n"); + crypto_chk_return(sm2_id->length > PKE_U16_MAX / BYTE_BITS, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "sm2_id_len is Invalid\n"); + + hash_param.px = pub_key->x; + hash_param.py = pub_key->y; + hash_param.id = sm2_id->data; + hash_param.id_len = sm2_id->length; + hash_data.data = hash->data; + hash_data.length = hash->length; + + /* e = Hash */ + ret = sm2_sign_verify_hash(&hash_param, msg, &hash_data); + crypto_chk_return(ret != TD_SUCCESS, ret, "sm2_sign_verify_hash failed, ret is 0x%x\n", ret); + return TD_SUCCESS; +} diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_pke_ecc_curve.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_pke_ecc_curve.c new file mode 100644 index 00000000..a8d7e494 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_pke_ecc_curve.c @@ -0,0 +1,592 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "crypto_hash_struct.h" +#include "drv_pke.h" +#include "crypto_drv_common.h" +#include "crypto_ecc_curve.h" + +static const td_u8 ecc_brainpool_256_p[] = { + 0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, + 0x3E, 0x66, 0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x72, + 0x6E, 0x3B, 0xF6, 0x23, 0xD5, 0x26, 0x20, 0x28, + 0x20, 0x13, 0x48, 0x1D, 0x1F, 0x6E, 0x53, 0x77 +}; +static const td_u8 ecc_brainpool_256_a[] = { + 0x7D, 0x5A, 0x09, 0x75, 0xFC, 0x2C, 0x30, 0x57, + 0xEE, 0xF6, 0x75, 0x30, 0x41, 0x7A, 0xFF, 0xE7, + 0xFB, 0x80, 0x55, 0xC1, 0x26, 0xDC, 0x5C, 0x6C, + 0xE9, 0x4A, 0x4B, 0x44, 0xF3, 0x30, 0xB5, 0xD9 +}; +static const td_u8 ecc_brainpool_256_b[] = { + 0x26, 0xDC, 0x5C, 0x6C, 0xE9, 0x4A, 0x4B, 0x44, + 0xF3, 0x30, 0xB5, 0xD9, 0xBB, 0xD7, 0x7C, 0xBF, + 0x95, 0x84, 0x16, 0x29, 0x5C, 0xF7, 0xE1, 0xCE, + 0x6B, 0xCC, 0xDC, 0x18, 0xFF, 0x8C, 0x07, 0xB6 +}; +static const td_u8 ecc_brainpool_256_gx[] = { + 0x8B, 0xD2, 0xAE, 0xB9, 0xCB, 0x7E, 0x57, 0xCB, + 0x2C, 0x4B, 0x48, 0x2F, 0xFC, 0x81, 0xB7, 0xAF, + 0xB9, 0xDE, 0x27, 0xE1, 0xE3, 0xBD, 0x23, 0xC2, + 0x3A, 0x44, 0x53, 0xBD, 0x9A, 0xCE, 0x32, 0x62 +}; +static const td_u8 ecc_brainpool_256_gy[] = { + 0x54, 0x7E, 0xF8, 0x35, 0xC3, 0xDA, 0xC4, 0xFD, + 0x97, 0xF8, 0x46, 0x1A, 0x14, 0x61, 0x1D, 0xC9, + 0xC2, 0x77, 0x45, 0x13, 0x2D, 0xED, 0x8E, 0x54, + 0x5C, 0x1D, 0x54, 0xC7, 0x2F, 0x04, 0x69, 0x97 +}; +static const td_u8 ecc_brainpool_256_n[] = { + 0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, + 0x3E, 0x66, 0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x71, + 0x8C, 0x39, 0x7A, 0xA3, 0xB5, 0x61, 0xA6, 0xF7, + 0x90, 0x1E, 0x0E, 0x82, 0x97, 0x48, 0x56, 0xA7 +}; + +static const drv_pke_ecc_curve g_brainpool_p256_curve = { + .p = ecc_brainpool_256_p, + .a = ecc_brainpool_256_a, + .b = ecc_brainpool_256_b, + .gx = ecc_brainpool_256_gx, + .gy = ecc_brainpool_256_gy, + .n = ecc_brainpool_256_n, + .h = 0x1, + .ksize = DRV_PKE_LEN_256, + .ecc_type = DRV_PKE_ECC_TYPE_RFC5639_P256 +}; + +static const td_u8 ecc_brainpool_384_p[] = { + 0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, + 0x0F, 0x5D, 0x6F, 0x7E, 0x50, 0xE6, 0x41, 0xDF, + 0x15, 0x2F, 0x71, 0x09, 0xED, 0x54, 0x56, 0xB4, + 0x12, 0xB1, 0xDA, 0x19, 0x7F, 0xB7, 0x11, 0x23, + 0xAC, 0xD3, 0xA7, 0x29, 0x90, 0x1D, 0x1A, 0x71, + 0x87, 0x47, 0x00, 0x13, 0x31, 0x07, 0xEC, 0x53 +}; +static const td_u8 ecc_brainpool_384_a[] = { + 0x7B, 0xC3, 0x82, 0xC6, 0x3D, 0x8C, 0x15, 0x0C, + 0x3C, 0x72, 0x08, 0x0A, 0xCE, 0x05, 0xAF, 0xA0, + 0xC2, 0xBE, 0xA2, 0x8E, 0x4F, 0xB2, 0x27, 0x87, + 0x13, 0x91, 0x65, 0xEF, 0xBA, 0x91, 0xF9, 0x0F, + 0x8A, 0xA5, 0x81, 0x4A, 0x50, 0x3A, 0xD4, 0xEB, + 0x04, 0xA8, 0xC7, 0xDD, 0x22, 0xCE, 0x28, 0x26 +}; +static const td_u8 ecc_brainpool_384_b[] = { + 0x04, 0xA8, 0xC7, 0xDD, 0x22, 0xCE, 0x28, 0x26, + 0x8B, 0x39, 0xB5, 0x54, 0x16, 0xF0, 0x44, 0x7C, + 0x2F, 0xB7, 0x7D, 0xE1, 0x07, 0xDC, 0xD2, 0xA6, + 0x2E, 0x88, 0x0E, 0xA5, 0x3E, 0xEB, 0x62, 0xD5, + 0x7C, 0xB4, 0x39, 0x02, 0x95, 0xDB, 0xC9, 0x94, + 0x3A, 0xB7, 0x86, 0x96, 0xFA, 0x50, 0x4C, 0x11 +}; +static const td_u8 ecc_brainpool_384_gx[] = { + 0x1D, 0x1C, 0x64, 0xF0, 0x68, 0xCF, 0x45, 0xFF, + 0xA2, 0xA6, 0x3A, 0x81, 0xB7, 0xC1, 0x3F, 0x6B, + 0x88, 0x47, 0xA3, 0xE7, 0x7E, 0xF1, 0x4F, 0xE3, + 0xDB, 0x7F, 0xCA, 0xFE, 0x0C, 0xBD, 0x10, 0xE8, + 0xE8, 0x26, 0xE0, 0x34, 0x36, 0xD6, 0x46, 0xAA, + 0xEF, 0x87, 0xB2, 0xE2, 0x47, 0xD4, 0xAF, 0x1E +}; +static const td_u8 ecc_brainpool_384_gy[] = { + 0x8A, 0xBE, 0x1D, 0x75, 0x20, 0xF9, 0xC2, 0xA4, + 0x5C, 0xB1, 0xEB, 0x8E, 0x95, 0xCF, 0xD5, 0x52, + 0x62, 0xB7, 0x0B, 0x29, 0xFE, 0xEC, 0x58, 0x64, + 0xE1, 0x9C, 0x05, 0x4F, 0xF9, 0x91, 0x29, 0x28, + 0x0E, 0x46, 0x46, 0x21, 0x77, 0x91, 0x81, 0x11, + 0x42, 0x82, 0x03, 0x41, 0x26, 0x3C, 0x53, 0x15 +}; +static const td_u8 ecc_brainpool_384_n[] = { + 0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, + 0x0F, 0x5D, 0x6F, 0x7E, 0x50, 0xE6, 0x41, 0xDF, + 0x15, 0x2F, 0x71, 0x09, 0xED, 0x54, 0x56, 0xB3, + 0x1F, 0x16, 0x6E, 0x6C, 0xAC, 0x04, 0x25, 0xA7, + 0xCF, 0x3A, 0xB6, 0xAF, 0x6B, 0x7F, 0xC3, 0x10, + 0x3B, 0x88, 0x32, 0x02, 0xE9, 0x04, 0x65, 0x65 +}; + +static const drv_pke_ecc_curve g_brainpool_p384_curve = { + .p = ecc_brainpool_384_p, + .a = ecc_brainpool_384_a, + .b = ecc_brainpool_384_b, + .gx = ecc_brainpool_384_gx, + .gy = ecc_brainpool_384_gy, + .n = ecc_brainpool_384_n, + .h = 0x1, + .ksize = DRV_PKE_LEN_384, + .ecc_type = DRV_PKE_ECC_TYPE_RFC5639_P384 +}; + +static const td_u8 ecc_brainpool_512_p[] = { + 0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, + 0x3F, 0xD4, 0xE6, 0xAE, 0x33, 0xC9, 0xFC, 0x07, + 0xCB, 0x30, 0x8D, 0xB3, 0xB3, 0xC9, 0xD2, 0x0E, + 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33, 0x08, 0x71, + 0x7D, 0x4D, 0x9B, 0x00, 0x9B, 0xC6, 0x68, 0x42, + 0xAE, 0xCD, 0xA1, 0x2A, 0xE6, 0xA3, 0x80, 0xE6, + 0x28, 0x81, 0xFF, 0x2F, 0x2D, 0x82, 0xC6, 0x85, + 0x28, 0xAA, 0x60, 0x56, 0x58, 0x3A, 0x48, 0xF3 +}; +static const td_u8 ecc_brainpool_512_a[] = { + 0x78, 0x30, 0xA3, 0x31, 0x8B, 0x60, 0x3B, 0x89, + 0xE2, 0x32, 0x71, 0x45, 0xAC, 0x23, 0x4C, 0xC5, + 0x94, 0xCB, 0xDD, 0x8D, 0x3D, 0xF9, 0x16, 0x10, + 0xA8, 0x34, 0x41, 0xCA, 0xEA, 0x98, 0x63, 0xBC, + 0x2D, 0xED, 0x5D, 0x5A, 0xA8, 0x25, 0x3A, 0xA1, + 0x0A, 0x2E, 0xF1, 0xC9, 0x8B, 0x9A, 0xC8, 0xB5, + 0x7F, 0x11, 0x17, 0xA7, 0x2B, 0xF2, 0xC7, 0xB9, + 0xE7, 0xC1, 0xAC, 0x4D, 0x77, 0xFC, 0x94, 0xCA +}; +static const td_u8 ecc_brainpool_512_b[] = { + 0x3D, 0xF9, 0x16, 0x10, 0xA8, 0x34, 0x41, 0xCA, + 0xEA, 0x98, 0x63, 0xBC, 0x2D, 0xED, 0x5D, 0x5A, + 0xA8, 0x25, 0x3A, 0xA1, 0x0A, 0x2E, 0xF1, 0xC9, + 0x8B, 0x9A, 0xC8, 0xB5, 0x7F, 0x11, 0x17, 0xA7, + 0x2B, 0xF2, 0xC7, 0xB9, 0xE7, 0xC1, 0xAC, 0x4D, + 0x77, 0xFC, 0x94, 0xCA, 0xDC, 0x08, 0x3E, 0x67, + 0x98, 0x40, 0x50, 0xB7, 0x5E, 0xBA, 0xE5, 0xDD, + 0x28, 0x09, 0xBD, 0x63, 0x80, 0x16, 0xF7, 0x23 +}; +static const td_u8 ecc_brainpool_512_gx[] = { + 0x81, 0xAE, 0xE4, 0xBD, 0xD8, 0x2E, 0xD9, 0x64, + 0x5A, 0x21, 0x32, 0x2E, 0x9C, 0x4C, 0x6A, 0x93, + 0x85, 0xED, 0x9F, 0x70, 0xB5, 0xD9, 0x16, 0xC1, + 0xB4, 0x3B, 0x62, 0xEE, 0xF4, 0xD0, 0x09, 0x8E, + 0xFF, 0x3B, 0x1F, 0x78, 0xE2, 0xD0, 0xD4, 0x8D, + 0x50, 0xD1, 0x68, 0x7B, 0x93, 0xB9, 0x7D, 0x5F, + 0x7C, 0x6D, 0x50, 0x47, 0x40, 0x6A, 0x5E, 0x68, + 0x8B, 0x35, 0x22, 0x09, 0xBC, 0xB9, 0xF8, 0x22 +}; +static const td_u8 ecc_brainpool_512_gy[] = { + 0x7D, 0xDE, 0x38, 0x5D, 0x56, 0x63, 0x32, 0xEC, + 0xC0, 0xEA, 0xBF, 0xA9, 0xCF, 0x78, 0x22, 0xFD, + 0xF2, 0x09, 0xF7, 0x00, 0x24, 0xA5, 0x7B, 0x1A, + 0xA0, 0x00, 0xC5, 0x5B, 0x88, 0x1F, 0x81, 0x11, + 0xB2, 0xDC, 0xDE, 0x49, 0x4A, 0x5F, 0x48, 0x5E, + 0x5B, 0xCA, 0x4B, 0xD8, 0x8A, 0x27, 0x63, 0xAE, + 0xD1, 0xCA, 0x2B, 0x2F, 0xA8, 0xF0, 0x54, 0x06, + 0x78, 0xCD, 0x1E, 0x0F, 0x3A, 0xD8, 0x08, 0x92 +}; +static const td_u8 ecc_brainpool_512_n[] = { + 0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, + 0x3F, 0xD4, 0xE6, 0xAE, 0x33, 0xC9, 0xFC, 0x07, + 0xCB, 0x30, 0x8D, 0xB3, 0xB3, 0xC9, 0xD2, 0x0E, + 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33, 0x08, 0x70, + 0x55, 0x3E, 0x5C, 0x41, 0x4C, 0xA9, 0x26, 0x19, + 0x41, 0x86, 0x61, 0x19, 0x7F, 0xAC, 0x10, 0x47, + 0x1D, 0xB1, 0xD3, 0x81, 0x08, 0x5D, 0xDA, 0xDD, + 0xB5, 0x87, 0x96, 0x82, 0x9C, 0xA9, 0x00, 0x69 +}; + +static const drv_pke_ecc_curve g_brainpool_p512_curve = { + .p = ecc_brainpool_512_p, + .a = ecc_brainpool_512_a, + .b = ecc_brainpool_512_b, + .gx = ecc_brainpool_512_gx, + .gy = ecc_brainpool_512_gy, + .n = ecc_brainpool_512_n, + .h = 0x1, + .ksize = DRV_PKE_LEN_512, + .ecc_type = DRV_PKE_ECC_TYPE_RFC5639_P512 +}; + +static const td_u8 ecc_fp_256k_p[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x2F +}; +static const td_u8 ecc_fp_256k_a[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +static const td_u8 ecc_fp_256k_b[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07 +}; +static const td_u8 ecc_fp_256k_gx[] = { + 0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, + 0x55, 0xA0, 0x62, 0x95, 0xCE, 0x87, 0x0B, 0x07, + 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9, + 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, 0x98 +}; +static const td_u8 ecc_fp_256k_gy[] = { + 0x48, 0x3A, 0xDA, 0x77, 0x26, 0xA3, 0xC4, 0x65, + 0x5D, 0xA4, 0xFB, 0xFC, 0x0E, 0x11, 0x08, 0xA8, + 0xFD, 0x17, 0xB4, 0x48, 0xA6, 0x85, 0x54, 0x19, + 0x9C, 0x47, 0xD0, 0x8F, 0xFB, 0x10, 0xD4, 0xB8 +}; +static const td_u8 ecc_fp_256k_n[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, + 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41 +}; + +static const drv_pke_ecc_curve g_fips_256k_curve = { + .p = ecc_fp_256k_p, + .a = ecc_fp_256k_a, + .b = ecc_fp_256k_b, + .gx = ecc_fp_256k_gx, + .gy = ecc_fp_256k_gy, + .n = ecc_fp_256k_n, + .h = 0x1, + .ksize = DRV_PKE_LEN_256, + .ecc_type = DRV_PKE_ECC_TYPE_FIPS_P256K +}; + +static const td_u8 ecc_fp_256r_p[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; +static const td_u8 ecc_fp_256r_a[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC +}; +static const td_u8 ecc_fp_256r_b[] = { + 0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, + 0xB3, 0xEB, 0xBD, 0x55, 0x76, 0x98, 0x86, 0xBC, + 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6, + 0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B +}; +static const td_u8 ecc_fp_256r_gx[] = { + 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, + 0xF8, 0xBC, 0xE6, 0xE5, 0x63, 0xA4, 0x40, 0xF2, + 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0, + 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96 +}; +static const td_u8 ecc_fp_256r_gy[] = { + 0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B, + 0x8E, 0xE7, 0xEB, 0x4A, 0x7C, 0x0F, 0x9E, 0x16, + 0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE, + 0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5 +}; +static const td_u8 ecc_fp_256r_n[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84, + 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51 +}; + +static const drv_pke_ecc_curve g_fips_256r_curve = { + .p = ecc_fp_256r_p, + .a = ecc_fp_256r_a, + .b = ecc_fp_256r_b, + .gx = ecc_fp_256r_gx, + .gy = ecc_fp_256r_gy, + .n = ecc_fp_256r_n, + .h = 0x1, + .ksize = DRV_PKE_LEN_256, + .ecc_type = DRV_PKE_ECC_TYPE_FIPS_P256R +}; + +static const td_u8 ecc_fp_384r_p[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF +}; +static const td_u8 ecc_fp_384r_a[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC +}; +static const td_u8 ecc_fp_384r_b[] = { + 0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, + 0x98, 0x8E, 0x05, 0x6B, 0xE3, 0xF8, 0x2D, 0x19, + 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12, + 0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, + 0xC6, 0x56, 0x39, 0x8D, 0x8A, 0x2E, 0xD1, 0x9D, + 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF +}; +static const td_u8 ecc_fp_384r_gx[] = { + 0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, + 0x8E, 0xB1, 0xC7, 0x1E, 0xF3, 0x20, 0xAD, 0x74, + 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98, + 0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, + 0x55, 0x02, 0xF2, 0x5D, 0xBF, 0x55, 0x29, 0x6C, + 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7 +}; +static const td_u8 ecc_fp_384r_gy[] = { + 0x36, 0x17, 0xDE, 0x4A, 0x96, 0x26, 0x2C, 0x6F, + 0x5D, 0x9E, 0x98, 0xBF, 0x92, 0x92, 0xDC, 0x29, + 0xF8, 0xF4, 0x1D, 0xBD, 0x28, 0x9A, 0x14, 0x7C, + 0xE9, 0xDA, 0x31, 0x13, 0xB5, 0xF0, 0xB8, 0xC0, + 0x0A, 0x60, 0xB1, 0xCE, 0x1D, 0x7E, 0x81, 0x9D, + 0x7A, 0x43, 0x1D, 0x7C, 0x90, 0xEA, 0x0E, 0x5F +}; +static const td_u8 ecc_fp_384r_n[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, + 0x58, 0x1A, 0x0D, 0xB2, 0x48, 0xB0, 0xA7, 0x7A, + 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73 +}; + +static const drv_pke_ecc_curve g_fips_384r_curve = { + .p = ecc_fp_384r_p, + .a = ecc_fp_384r_a, + .b = ecc_fp_384r_b, + .gx = ecc_fp_384r_gx, + .gy = ecc_fp_384r_gy, + .n = ecc_fp_384r_n, + .h = 0x1, + .ksize = DRV_PKE_LEN_384, + .ecc_type = DRV_PKE_ECC_TYPE_FIPS_P384R +}; + +static const td_u8 ecc_fp_521r_p[] = { + 0x00, 0x00, 0x01, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; +static const td_u8 ecc_fp_521r_a[] = { + 0x00, 0x00, 0x01, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC +}; +static const td_u8 ecc_fp_521r_b[] = { + 0x00, 0x00, 0x00, 0x51, + 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, + 0x92, 0x9A, 0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, + 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3, 0x15, 0xF3, + 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1, + 0x56, 0x19, 0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, + 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1, 0xBF, 0x07, + 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, + 0xEF, 0x45, 0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00 +}; +static const td_u8 ecc_fp_521r_gx[] = { + 0x00, 0x00, 0x00, 0xC6, + 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, + 0x9E, 0x3E, 0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, + 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F, 0xB5, 0x21, + 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, + 0xA1, 0x4B, 0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, + 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF, 0xA8, 0xDE, + 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, + 0xF9, 0x7E, 0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66 +}; +static const td_u8 ecc_fp_521r_gy[] = { + 0x00, 0x00, 0x01, 0x18, + 0x39, 0x29, 0x6A, 0x78, 0x9A, 0x3B, 0xC0, 0x04, + 0x5C, 0x8A, 0x5F, 0xB4, 0x2C, 0x7D, 0x1B, 0xD9, + 0x98, 0xF5, 0x44, 0x49, 0x57, 0x9B, 0x44, 0x68, + 0x17, 0xAF, 0xBD, 0x17, 0x27, 0x3E, 0x66, 0x2C, + 0x97, 0xEE, 0x72, 0x99, 0x5E, 0xF4, 0x26, 0x40, + 0xC5, 0x50, 0xB9, 0x01, 0x3F, 0xAD, 0x07, 0x61, + 0x35, 0x3C, 0x70, 0x86, 0xA2, 0x72, 0xC2, 0x40, + 0x88, 0xBE, 0x94, 0x76, 0x9F, 0xD1, 0x66, 0x50 +}; +static const td_u8 ecc_fp_521r_n[] = { + 0x00, 0x00, 0x01, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, + 0x51, 0x86, 0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, + 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09, 0xA5, 0xD0, + 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, + 0xBB, 0x6F, 0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09 +}; + +static const drv_pke_ecc_curve g_fips_521r_curve = { + .p = ecc_fp_521r_p, + .a = ecc_fp_521r_a, + .b = ecc_fp_521r_b, + .gx = ecc_fp_521r_gx, + .gy = ecc_fp_521r_gy, + .n = ecc_fp_521r_n, + .h = 0x1, + .ksize = DRV_PKE_LEN_521, + .ecc_type = DRV_PKE_ECC_TYPE_FIPS_P521R +}; + +static const td_u8 ecc_rfc_7748_p[] = { + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xED +}; +static const td_u8 ecc_rfc_7748_a[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xDB, 0x41 +}; +static const td_u8 ecc_rfc_7748_n[] = { + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x14, 0xDE, 0xF9, 0xDE, 0xA2, 0xF7, 0x9C, 0xD6, + 0x58, 0x12, 0x63, 0x1A, 0x5C, 0xF5, 0xD3, 0xED +}; +static const td_u8 ecc_rfc_7748_gx[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09 +}; + +static const drv_pke_ecc_curve g_rfc7748_curve = { + .p = ecc_rfc_7748_p, + .a = ecc_rfc_7748_a, + .gx = ecc_rfc_7748_gx, + .n = ecc_rfc_7748_n, + .h = 0x8, + .ksize = DRV_PKE_LEN_256, + .ecc_type = DRV_PKE_ECC_TYPE_RFC7748 +}; + +static const td_u8 ecc_rfc_8032_p[] = { + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xED +}; + +static const td_u8 ecc_rfc_8032_d[] = { + 0x52, 0x03, 0x6c, 0xee, 0x2b, 0x6f, 0xfe, 0x73, + 0x8c, 0xc7, 0x40, 0x79, 0x77, 0x79, 0xe8, 0x98, + 0x00, 0x70, 0x0a, 0x4d, 0x41, 0x41, 0xd8, 0xab, + 0x75, 0xeb, 0x4d, 0xca, 0x13, 0x59, 0x78, 0xa3 +}; + +static const td_u8 ecc_rfc_8032_n[] = { + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x14, 0xDE, 0xF9, 0xDE, 0xA2, 0xF7, 0x9C, 0xD6, + 0x58, 0x12, 0x63, 0x1A, 0x5C, 0xF5, 0xD3, 0xED +}; + +static const td_u8 ecc_rfc_8032_gx[] = { + 0x21, 0x69, 0x36, 0xd3, 0xcd, 0x6e, 0x53, 0xfe, + 0xc0, 0xa4, 0xe2, 0x31, 0xfd, 0xd6, 0xdc, 0x5c, + 0x69, 0x2c, 0xc7, 0x60, 0x95, 0x25, 0xa7, 0xb2, + 0xc9, 0x56, 0x2d, 0x60, 0x8f, 0x25, 0xd5, 0x1a +}; + +static const td_u8 ecc_rfc_8032_gy[] = { + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x58 +}; + +static const drv_pke_ecc_curve g_rfc8032_curve = { + .p = ecc_rfc_8032_p, + .a = ecc_rfc_8032_d, + .gx = ecc_rfc_8032_gx, + .gy = ecc_rfc_8032_gy, + .n = ecc_rfc_8032_n, + .h = 0x8, + .ksize = DRV_PKE_LEN_256, + .ecc_type = DRV_PKE_ECC_TYPE_RFC8032 +}; + +static const td_u8 ecc_sm2_p[] = { + 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +static const td_u8 ecc_sm2_a[] = { + 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, +}; + +static const td_u8 ecc_sm2_b[] = { + 0x28, 0xE9, 0xFA, 0x9E, 0x9D, 0x9F, 0x5E, 0x34, + 0x4D, 0x5A, 0x9E, 0x4B, 0xCF, 0x65, 0x09, 0xA7, + 0xF3, 0x97, 0x89, 0xF5, 0x15, 0xAB, 0x8F, 0x92, + 0xDD, 0xBC, 0xBD, 0x41, 0x4D, 0x94, 0x0E, 0x93, +}; + +static const td_u8 ecc_sm2_n[] = { + 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x72, 0x03, 0xDF, 0x6B, 0x21, 0xC6, 0x05, 0x2B, + 0x53, 0xBB, 0xF4, 0x09, 0x39, 0xD5, 0x41, 0x23, +}; + +static const td_u8 ecc_sm2_gx[] = { + 0x32, 0xC4, 0xAE, 0x2C, 0x1F, 0x19, 0x81, 0x19, + 0x5F, 0x99, 0x04, 0x46, 0x6A, 0x39, 0xC9, 0x94, + 0x8F, 0xE3, 0x0B, 0xBF, 0xF2, 0x66, 0x0B, 0xE1, + 0x71, 0x5A, 0x45, 0x89, 0x33, 0x4C, 0x74, 0xC7, +}; + +static const td_u8 ecc_sm2_gy[] = { + 0xBC, 0x37, 0x36, 0xA2, 0xF4, 0xF6, 0x77, 0x9C, + 0x59, 0xBD, 0xCE, 0xE3, 0x6B, 0x69, 0x21, 0x53, + 0xD0, 0xA9, 0x87, 0x7C, 0xC6, 0x2A, 0x47, 0x40, + 0x02, 0xDF, 0x32, 0xE5, 0x21, 0x39, 0xF0, 0xA0, +}; + +static const drv_pke_ecc_curve g_sm2_curve = { + .p = ecc_sm2_p, + .a = ecc_sm2_a, + .b = ecc_sm2_b, + .gx = ecc_sm2_gx, + .gy = ecc_sm2_gy, + .n = ecc_sm2_n, + .h = 0x1, + .ksize = DRV_PKE_LEN_256, + .ecc_type = DRV_PKE_ECC_TYPE_SM2 +}; + +static const drv_pke_ecc_curve * const g_ecc_curve_list[DRV_PKE_ECC_TYPE_MAX] = { + &g_brainpool_p256_curve, + &g_brainpool_p384_curve, + &g_brainpool_p512_curve, + &g_fips_256k_curve, + &g_fips_256r_curve, + &g_fips_384r_curve, + &g_fips_521r_curve, + &g_rfc7748_curve, + &g_rfc8032_curve, + &g_sm2_curve, +}; + +const drv_pke_ecc_curve *get_ecc_curve(drv_pke_ecc_curve_type curve_type) +{ + if (curve_type >= DRV_PKE_ECC_TYPE_MAX) { + return TD_NULL; + } + + if (crypto_ecc_support(curve_type) == TD_FALSE) { + return TD_NULL; + } + if (curve_type == DRV_PKE_ECC_TYPE_SM2 && !crypto_sm_support(CRYPTO_SM_ALG_SM2)) { + return TD_NULL; + } + return g_ecc_curve_list[curve_type]; +} diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_pke_rsa.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_pke_rsa.c new file mode 100644 index 00000000..a0149d05 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_pke_rsa.c @@ -0,0 +1,1208 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "hal_pke.h" +#include "drv_pke.h" +#include "crypto_hash_struct.h" +#include "securec.h" +#include "drv_hash.h" +#include "drv_trng.h" +#include "crypto_drv_common.h" +#include "drv_inner.h" + +#define RANDOM_TRY_TIME 100 +#define RSA_GEN_KEY_WAIT_TIMES 10 +#define RSA_GEN_KEY_TRY_TIMES 10 +#define BYTE_MAX 0xFF +#define PKE_COMPAT_ERRNO(err_code) DISPATCH_COMPAT_ERRNO(ERROR_MODULE_PKE, err_code) + +#define pke_null_ptr_chk(ptr) \ + crypto_chk_return((ptr) == TD_NULL, PKE_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), #ptr" is NULL\n") + +// hash ASN.1 +static const td_u8 g_asn1_sha1[] = { + 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, + 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, +}; + +static const td_u8 g_asn1_sha256[] = { + 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, + 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, + 0x00, 0x04, 0x20, +}; + +static const td_u8 g_asn1_sha384[] = { + 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, + 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, + 0x00, 0x04, 0x30, +}; + +static const td_u8 g_asn1_sha512[] = { + 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, + 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, + 0x00, 0x04, 0x40, +}; + +static const td_u8 g_empty_l_sha1[] = { + 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, + 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, + 0xaf, 0xd8, 0x07, 0x09, +}; + +static const td_u8 g_empty_l_sha256[] = { + 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, + 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, + 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, + 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55, +}; + +static const td_u8 g_empty_l_sha384[] = { + 0x38, 0xb0, 0x60, 0xa7, 0x51, 0xac, 0x96, 0x38, + 0x4c, 0xd9, 0x32, 0x7e, 0xb1, 0xb1, 0xe3, 0x6a, + 0x21, 0xfd, 0xb7, 0x11, 0x14, 0xbe, 0x07, 0x43, + 0x4c, 0x0c, 0xc7, 0xbf, 0x63, 0xf6, 0xe1, 0xda, + 0x27, 0x4e, 0xde, 0xbf, 0xe7, 0x6f, 0x65, 0xfb, + 0xd5, 0x1a, 0xd2, 0xf1, 0x48, 0x98, 0xb9, 0x5b, +}; + +static const td_u8 g_empty_l_sha512[] = { + 0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd, + 0xf1, 0x54, 0x28, 0x50, 0xd6, 0x6d, 0x80, 0x07, + 0xd6, 0x20, 0xe4, 0x05, 0x0b, 0x57, 0x15, 0xdc, + 0x83, 0xf4, 0xa9, 0x21, 0xd3, 0x6c, 0xe9, 0xce, + 0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0, + 0xff, 0x83, 0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f, + 0x63, 0xb9, 0x31, 0xbd, 0x47, 0x41, 0x7a, 0x81, + 0xa5, 0x38, 0x32, 0x7a, 0xf9, 0x27, 0xda, 0x3e, +}; + +static const td_s8 g_bits[] = {0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4}; + +static td_u8 g_l_hash[HASH_SIZE_SHA_512] = {0x0}; + +static const pke_hash_properties_type g_pke_hash_properties[] = { + {DRV_PKE_HASH_TYPE_SHA1, SHA1_BLOCK_LENGTH, SHA1_RESULT_LENGTH}, + {DRV_PKE_HASH_TYPE_SHA224, SHA224_BLOCK_LENGTH, SHA224_RESULT_LENGTH}, + {DRV_PKE_HASH_TYPE_SHA256, SHA256_BLOCK_LENGTH, SHA256_RESULT_LENGTH}, + {DRV_PKE_HASH_TYPE_SHA384, SHA384_BLOCK_LENGTH, SHA384_RESULT_LENGTH}, + {DRV_PKE_HASH_TYPE_SHA512, SHA512_BLOCK_LENGTH, SHA512_RESULT_LENGTH}, + {DRV_PKE_HASH_TYPE_SM3, SM3_BLOCK_LENGTH, SM3_RESULT_LENGTH} +}; + +static td_s32 drv_get_hash_len(const drv_pke_hash_type hash_type) +{ + td_u32 i = 0; + + for (i = 0; i < sizeof(g_pke_hash_properties) / sizeof(pke_hash_properties_type); i++) { + if (g_pke_hash_properties[i].hash_type == hash_type) { + return g_pke_hash_properties[i].result_len; + } + } + return 0; +} + +static td_s32 rsa_exp_mod(const td_u8 *n, const td_u8 *k, const td_u32 klen, + const drv_pke_data *in, const drv_pke_data *out) +{ + td_s32 ret = TD_FAILURE; + drv_pke_data n_data = {klen, (td_u8 *)n}; + drv_pke_data k_data = {klen, (td_u8 *)k}; + + ret = drv_cipher_pke_exp_mod(&n_data, &k_data, in, out); + crypto_chk_goto(ret != TD_SUCCESS, exit__, "drv_cipher_pke_exp_mod failed, ret is 0x%x\n", ret); +exit__: + (void)drv_cipher_pke_clean_ram(); + return ret; +} + +static td_s32 get_random(td_u8 *rand, const td_u32 size) +{ + td_s32 ret = TD_FAILURE; + td_u32 k = 0; + td_u32 i = 0; + td_u32 randnum = 0; + + ret = drv_cipher_trng_get_multi_random(size, rand); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_trng_get_multi_random failed, ret is 0x%x\n", ret); + + k = 0; + while (k < size) { // It's almost impossible to randomize 100 times and not get a non-zero value. + if (rand[k] != 0x00) { + i = 0; + k++; + continue; + } + crypto_chk_return(i == RANDOM_TRY_TIME, PKE_COMPAT_ERRNO(ERROR_TRY_TIMES), + "drv_cipher_trng_get_random failed!\n"); + i++; + ret = drv_cipher_trng_get_random(&randnum); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_trng_get_random failed, ret is 0x%x\n", ret); + rand[k] = (td_u8)(randnum & BYTE_MAX); + } + return ret; +} + +static td_u32 rsa_get_bit_num(const td_u8 *big_num, td_u32 num_len) +{ + td_u32 i = 0; + td_s8 num = 0; + + for (i = 0; i < num_len; i++) { + if (big_num[i] == 0x00) { + continue; + } + num = g_bits[(big_num[i] & (MAX_LOW_8BITS - MAX_LOW_4BITS)) >> SHIFT_4BITS]; + if (num > 0) { + return (num_len - i - BOUND_VALUE_1) * BYTE_BITS + num + DRV_WORD_WIDTH; + } + + num = g_bits[big_num[i] & MAX_LOW_4BITS]; + if (num > 0) { + return (num_len - i - BOUND_VALUE_1) * BYTE_BITS + num; + } + } + return 0; +} + +static td_s32 pkcs1_mgf(const rsa_pkcs1_hash_info *hash_info, const td_u8 *seed, const td_u32 seed_len, + td_u8 *mask, const td_u32 mask_len) +{ + td_s32 ret = TD_FAILURE; + td_u32 i = 0; + td_u32 j = 0; + td_u32 out_len = 0; + td_u8 cnt[DRV_WORD_WIDTH]; + td_u8 md[HASH_SIZE_SHA_MAX]; + drv_pke_data hash = {0}; + td_u8 seed_buf[DRV_PKE_LEN_4096]; + drv_pke_data arr[2]; + + (void)memset_s(cnt, DRV_WORD_WIDTH, 0x00, DRV_WORD_WIDTH); + (void)memset_s(md, HASH_SIZE_SHA_MAX, 0x00, HASH_SIZE_SHA_MAX); + ret = memcpy_s(seed_buf, DRV_PKE_LEN_4096, seed, seed_len); + crypto_chk_return(ret != TD_SUCCESS, ret, "memcpy_s failed, ret is 0x%x\n", ret); + + hash.length = HASH_SIZE_SHA_MAX; + hash.data = md; + + arr[0].data = seed_buf; + arr[0].length = seed_len; + arr[1].data = cnt; + arr[1].length = (uintptr_t)sizeof(cnt); + + for (i = 0; out_len < mask_len; i++) { + cnt[WORD_INDEX_0] = (td_u8)((i >> SHIFT_24BITS) & MAX_LOW_8BITS); + cnt[WORD_INDEX_1] = (td_u8)((i >> SHIFT_16BITS) & MAX_LOW_8BITS); + cnt[WORD_INDEX_2] = (td_u8)((i >> SHIFT_8BITS)) & MAX_LOW_8BITS; + cnt[WORD_INDEX_3] = (td_u8)(i & MAX_LOW_8BITS); + + /* H = Hash(seedbuf || cnt) */ + ret = drv_cipher_pke_calc_hash(arr, sizeof(arr) / sizeof(arr[0]), hash_info->hash_type, &hash); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_pke_calc_hash failed, ret is 0x%x\n", ret); + + for (j = 0; (j < hash_info->hash_len) && (out_len < mask_len); j++) { + mask[out_len++] ^= md[j]; + } + } + return ret; +} + +static td_s32 pkcs1_get_hash(const drv_pke_hash_type hash_type, const drv_pke_data *label, + rsa_pkcs1_hash_info *hash_info) +{ + td_s32 ret = TD_FAILURE; + drv_pke_data h_hash = {0}; + switch (hash_type) { + case DRV_PKE_HASH_TYPE_SHA1: + hash_info->hash_type = DRV_PKE_HASH_TYPE_SHA1; + hash_info->hash_len = HASH_SIZE_SHA_1; + hash_info->asn1_data = (td_u8 *)g_asn1_sha1; + hash_info->asn1_len = sizeof(g_asn1_sha1); + hash_info->lhash_data = (td_u8 *)g_empty_l_sha1; + break; + case DRV_PKE_HASH_TYPE_SHA256: + hash_info->hash_type = DRV_PKE_HASH_TYPE_SHA256; + hash_info->hash_len = HASH_SIZE_SHA_256; + hash_info->asn1_data = (td_u8 *)g_asn1_sha256; + hash_info->asn1_len = sizeof(g_asn1_sha256); + hash_info->lhash_data = (td_u8 *)g_empty_l_sha256; + break; + case DRV_PKE_HASH_TYPE_SHA384: + hash_info->hash_type = DRV_PKE_HASH_TYPE_SHA384; + hash_info->hash_len = HASH_SIZE_SHA_384; + hash_info->asn1_data = (td_u8 *)g_asn1_sha384; + hash_info->asn1_len = sizeof(g_asn1_sha384); + hash_info->lhash_data = (td_u8 *)g_empty_l_sha384; + break; + case DRV_PKE_HASH_TYPE_SHA512: + hash_info->hash_type = DRV_PKE_HASH_TYPE_SHA512; + hash_info->hash_len = HASH_SIZE_SHA_512; + hash_info->asn1_data = (td_u8 *)g_asn1_sha512; + hash_info->asn1_len = sizeof(g_asn1_sha512); + hash_info->lhash_data = (td_u8 *)g_empty_l_sha512; + break; + default: + crypto_log_err("unsupport hash type\n"); + return PKE_COMPAT_ERRNO(ERROR_UNSUPPORT); + } + + if (label != TD_NULL && label->data != TD_NULL && label->length != 0) { + hash_info->lhash_data = g_l_hash; + h_hash.data = hash_info->lhash_data; + h_hash.length = hash_info->hash_len; + + ret = drv_cipher_pke_calc_hash(label, 1, hash_info->hash_type, &h_hash); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_pke_calc_hash failed, ret is 0x%x\n", ret); + } + + return TD_SUCCESS; +} + +/* H = Hash( M' ) = Hash( Padding1 || mHash || salt ) */ +static td_s32 pkcs1_pss_hash(const rsa_pkcs1_hash_info *hash_info, const td_u8 *m_hash, td_u32 klen, + const drv_pke_data *salt, td_u8 *hash) +{ + td_s32 ret = TD_FAILURE; + td_u8 ps[RSA_PADLEN_8] = {0}; + td_u32 h_len = HASH_SIZE_SHA_MAX; + drv_pke_data h_hash = {0}; + drv_pke_data arr[3]; // The capacity of the array is 3. + + h_hash.length = h_len; + h_hash.data = hash; + + /* H = Hash(PS || MHash || SALT) */ + arr[0].data = ps; // 0 th element is ps + arr[0].length = RSA_PADLEN_8; // 0 element is PS + arr[1].data = (td_u8 *)m_hash; // 1 element is MHash + arr[1].length = klen; // 1 element is MHash + arr[2].data = (td_u8 *)salt->data; // 2 element is SALT + arr[2].length = salt->length; // 2 element is SALT + ret = drv_cipher_pke_calc_hash(arr, sizeof(arr) / sizeof(arr[0]), hash_info->hash_type, &h_hash); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_pke_calc_hash failed, ret is 0x%x\n", ret); + + return ret; +} + +#if defined(CONFIG_PKE_RSA_V15_SUPPORT) +/* EM = 00 || 01 || PS || 00 || T */ +static td_s32 pkcs1_v15_sign(const drv_pke_hash_type hash_type, const rsa_pkcs1_pack *pack) +{ + td_s32 ret = TD_FAILURE; + rsa_pkcs1_hash_info hash_info = {0}; + td_u8 *p = TD_NULL; + td_u32 idx = 0; + + ret = pkcs1_get_hash(hash_type, TD_NULL, &hash_info); + crypto_chk_return(ret != TD_SUCCESS, ret, "pkcs1_get_hash failed, ret is 0x%x\n", ret); + + p = pack->em; + p[idx++] = 0x00; + p[idx++] = 0x01; + + /* PS */ + while (idx < (pack->em_len - hash_info.hash_len - hash_info.asn1_len - 1)) { + p[idx++] = BYTE_MAX; + } + + p[idx++] = 0x00; + + /* T */ + ret = memcpy_s(&p[idx], pack->em_len - idx, hash_info.asn1_data, hash_info.asn1_len); + crypto_chk_return(ret != TD_SUCCESS, ret, "memcpy_s failed, ret is 0x%x\n", ret); + idx += hash_info.asn1_len; + ret = memcpy_s(&p[idx], pack->em_len - idx, pack->hash, hash_info.hash_len); + crypto_chk_return(ret != TD_SUCCESS, ret, "memcpy_s failed, ret is 0x%x\n", ret); + + return ret; +} + +/* check EM = 00 || 01 || PS || 00 || T */ +static td_s32 pkcs1_v15_verify(const drv_pke_hash_type hash_type, const rsa_pkcs1_pack *pack) +{ + td_s32 ret = TD_FAILURE; + rsa_pkcs1_hash_info hash_info = {0}; + td_u8 *p = TD_NULL; + td_u32 idx = 0; + + ret = pkcs1_get_hash(hash_type, TD_NULL, &hash_info); + crypto_chk_return(ret != TD_SUCCESS, ret, "pkcs1_get_hash failed, ret is 0x%x\n", ret); + + p = pack->em; + if (p[idx++] != 0x00) { + return PKE_COMPAT_ERRNO(ERROR_PKE_RSA_VERIFY_V15_CHECK); + } + if (p[idx++] != 0x01) { + return PKE_COMPAT_ERRNO(ERROR_PKE_RSA_VERIFY_V15_CHECK); + } + + /* PS */ + while (idx < (pack->em_len - hash_info.hash_len - hash_info.asn1_len - 1)) { + if (p[idx++] != BYTE_MAX) { + return PKE_COMPAT_ERRNO(ERROR_PKE_RSA_VERIFY_V15_CHECK); + } + } + if (p[idx++] != 0x00) { + return PKE_COMPAT_ERRNO(ERROR_PKE_RSA_VERIFY_V15_CHECK); + } + + /* T */ + if (memcmp(&p[idx], hash_info.asn1_data, hash_info.asn1_len) != 0) { + crypto_log_err("check v15 asn1 failed!\n"); + return PKE_COMPAT_ERRNO(ERROR_PKE_RSA_VERIFY_V15_CHECK); + } + + idx += hash_info.asn1_len; + if (memcmp(&p[idx], pack->hash, hash_info.hash_len) != 0) { + crypto_log_err("check v15 hash failed!\n"); + return PKE_COMPAT_ERRNO(ERROR_PKE_RSA_VERIFY_V15_CHECK); + } + + return ret; +} +#endif + +static td_s32 pkcs1_pss_sign(const drv_pke_hash_type hash_type, const rsa_pkcs1_pack *pack) +{ + td_s32 ret = TD_FAILURE; + rsa_pkcs1_hash_info hash_info = {0}; + td_u8 salt_data[HASH_SIZE_SHA_MAX]; + td_u32 salt_len = 0; + td_u32 tmp_len = 0; + td_u32 ms_bits = 0; + td_u8 *masked_db = TD_NULL; + td_u32 masked_db_len = pack->em_len - pack->hash_len - 1; /* 1 byte for bound. */ + td_u8 *masked_seed = TD_NULL; + drv_pke_data salt = {0}; + + ret = pkcs1_get_hash(hash_type, TD_NULL, &hash_info); + crypto_chk_return(ret != TD_SUCCESS, ret, "pkcs1_get_hash failed, ret is 0x%x\n", ret); + + salt_len = hash_info.hash_len; + + /* em_bit is the number of bits of key n. */ + ms_bits = (pack->em_bit - BOUND_VALUE_1) & MAX_LOW_3BITS; + + ret = get_random((td_u8 *)salt_data, salt_len); + crypto_chk_return(ret != TD_SUCCESS, ret, "get_random failed, ret is 0x%x\n", ret); + + /* EM = masked_db || masked_seed || 0xbc */ + masked_db = pack->em; + masked_seed = pack->em + masked_db_len; + + salt.data = salt_data; + salt.length = salt_len; + ret = pkcs1_pss_hash(&hash_info, pack->hash, pack->hash_len, &salt, masked_seed); + crypto_chk_return(ret != TD_SUCCESS, ret, "pkcs1_pss_hash failed, ret is 0x%x\n", ret); + + /* DB = PS || 0x01 || salt */ + /* set PS, here tmp_len means the length of PS */ + tmp_len = pack->em_len - pack->hash_len - salt_len - RSA_PADLEN_2; /* padding2.length - 1 */ + (void)memset_s(masked_db, tmp_len, 0x00, tmp_len); + + /* set 0x01 after PS */ + masked_db[tmp_len++] = 0x01; + + /* set salt */ + ret = memcpy_s(masked_db + tmp_len, pack->em_len - tmp_len, salt_data, salt_len); + crypto_chk_return(ret != TD_SUCCESS, ret, "memcpy_s failed, ret is 0x%x\n", ret); + + ret = pkcs1_mgf(&hash_info, masked_seed, pack->hash_len, masked_db, masked_db_len); + crypto_chk_return(ret != TD_SUCCESS, ret, "pkcs1_mgf failed, ret is 0x%x\n", ret); + + pack->em[0] &= MAX_LOW_8BITS >> (BYTE_BITS - ms_bits); + pack->em[pack->em_len - 1] = RSA_PAD_XBC; /* 1 byte for bound. */ + return ret; +} + +static td_s32 pkcs1_pss_verify(const drv_pke_hash_type hash_type, const rsa_pkcs1_pack *pack) +{ + td_s32 ret = TD_FAILURE; + rsa_pkcs1_hash_info hash_info = {0}; + td_u8 em[DRV_PKE_LEN_4096]; + td_u8 hash[HASH_SIZE_SHA_MAX]; + td_u32 salt_len = 0; + td_u32 ms_bits = 0; + td_u8 *masked_db = TD_NULL; + td_u32 masked_db_len = pack->em_len - pack->hash_len - 1; /* 1 byte for bound. */ + td_u8 *masked_seed = TD_NULL; + drv_pke_data salt = {0}; + + ret = pkcs1_get_hash(hash_type, TD_NULL, &hash_info); + crypto_chk_return(ret != TD_SUCCESS, ret, "pkcs1_get_hash failed, ret is 0x%x\n", ret); + + if (pack->em[pack->em_len - 1] != RSA_PAD_XBC) { + return PKE_COMPAT_ERRNO(ERROR_PKE_RSA_VERIFY_PSS_CHECK); + } + + ms_bits = (pack->em_bit - BOUND_VALUE_1) & MAX_LOW_3BITS; + if ((pack->em[0] & (MAX_LOW_8BITS << ms_bits))) { + return PKE_COMPAT_ERRNO(ERROR_PKE_RSA_VERIFY_PSS_CHECK); + } + + ret = memcpy_s(em, DRV_PKE_LEN_4096, pack->em, pack->em_len); + crypto_chk_return(ret != TD_SUCCESS, ret, "memcpy_s failed, ret is 0x%x\n", ret); + + masked_db = em; + masked_seed = em + masked_db_len; + ret = pkcs1_mgf(&hash_info, masked_seed, pack->hash_len, masked_db, masked_db_len); + crypto_chk_return(ret != TD_SUCCESS, ret, "pkcs1_mgf failed, ret is 0x%x\n", ret); + + em[0] &= MAX_LOW_8BITS >> (BYTE_BITS - ms_bits); + + while (masked_db < masked_seed - 1 && *masked_db == 0) { + masked_db++; + } + + if (*masked_db++ != 0x01) { + crypto_log_err("pss padding check failed!\n"); + return PKE_COMPAT_ERRNO(ERROR_PKE_RSA_VERIFY_PSS_CHECK); + } + + salt_len = masked_seed - masked_db; + salt.length = salt_len; + salt.data = masked_db; + + ret = pkcs1_pss_hash(&hash_info, pack->hash, pack->hash_len, &salt, (td_u8 *)hash); + crypto_chk_return(ret != TD_SUCCESS, ret, "pkcs1_pss_hash failed, ret is 0x%x\n", ret); + + if (memcmp(masked_seed, hash, hash_info.hash_len) != 0) { + crypto_log_err("pss hash check failed!\n"); + return PKE_COMPAT_ERRNO(ERROR_PKE_RSA_VERIFY_PSS_CHECK); + } + + return ret; +} + +#if defined(CONFIG_PKE_RSA_V15_SUPPORT) +/* EM = 00 || 02 || PS || 00 || M */ +static td_s32 pkcs1_v15_encrypt(const rsa_pkcs1_pack *pack) +{ + td_s32 ret = TD_FAILURE; + td_u8 *p = TD_NULL; + td_u32 idx = 0; + td_u32 ps_len = pack->em_len - pack->data_len - RSA_PADLEN_3; + + p = pack->em; + p[idx++] = 0x00; + p[idx++] = 0x02; // 0x02 see comment above func + + /* PS */ + ret = get_random(&p[idx], ps_len); + if (ret != TD_SUCCESS) { + crypto_log_err("get random ps failed!\n"); + return ret; + } + idx += ps_len; + + p[idx++] = 0x00; + /* M */ + if (pack->data_len != 0) { + ret = memcpy_s(&p[idx], pack->em_len - idx, pack->data, pack->data_len); + crypto_chk_return(ret != TD_SUCCESS, ret, "memcpy_s failed, ret is 0x%x\n", ret); + } + + return ret; +} + +/* check EM = 00 || 02 || PS || 00 || M */ +static td_s32 pkcs1_v15_decrypt(rsa_pkcs1_pack *pack) +{ + td_s32 ret = TD_FAILURE; + td_u8 *p = TD_NULL; + td_u32 idx = 0; + td_u32 len = 0; + + p = pack->em; + if (p[idx++] != 0x00) { + crypto_log_err("padding check failed!\n"); + return PKE_COMPAT_ERRNO(ERROR_PKE_RSA_CRYPTO_V15_CHECK); + } + + if (p[idx++] != 0x02) { // 0x02 see comment above func + crypto_log_err("padding check failed!\n"); + return PKE_COMPAT_ERRNO(ERROR_PKE_RSA_CRYPTO_V15_CHECK); + } + + /* PS */ + while ((idx < (pack->em_len - RSA_PADLEN_1)) && p[idx] != 0x00) { + idx++; + } + + if (p[idx++] != 0x00) { + crypto_log_err("padding check failed!\n"); + return PKE_COMPAT_ERRNO(ERROR_PKE_RSA_CRYPTO_V15_CHECK); + } + + len = pack->em_len - idx; + if (len > pack->em_len - RSA_PADLEN_11) { + crypto_log_err("padding check failed!\n"); + return PKE_COMPAT_ERRNO(ERROR_PKE_RSA_CRYPTO_V15_CHECK); + } + + /* M */ + if (len != 0) { + ret = memcpy_s(pack->data, pack->data_len, &p[idx], len); + crypto_chk_return(ret != TD_SUCCESS, ret, "memcpy_s failed, ret is 0x%x\n", ret); + } + pack->data_len = len; // record length of plain text for return + + return TD_SUCCESS; +} +#endif + +static td_s32 pkcs1_oaep_encrypt(const drv_pke_hash_type hash_type, const rsa_pkcs1_pack *pack, + const drv_pke_data *label) +{ + td_s32 ret = TD_FAILURE; + rsa_pkcs1_hash_info hash_info = {0}; + td_u8 *p = TD_NULL; + td_u8 *db = TD_NULL; + td_u8 *seed = TD_NULL; + td_u32 idx = 0; + td_u32 hash_len = 0; + td_u32 tmp_len = 0; + + ret = pkcs1_get_hash(hash_type, label, &hash_info); + crypto_chk_return(ret != TD_SUCCESS, ret, "pkcs1_get_hash failed, ret is 0x%x\n", ret); + hash_len = hash_info.hash_len; + + p = pack->em; + seed = p + 1; + db = p + hash_len + 1; + + /* 1. set data[0] = 0 */ + p[idx++] = 0x00; + + /* 2. set data[1, hash_len + 1] = random */ + ret = get_random(&p[idx], hash_len); + crypto_chk_return(ret != TD_SUCCESS, ret, "get_random failed, ret is 0x%x\n", ret); + idx += hash_len; + + /* 3. set data[hash_len + 1, 2hash_len + 1] = lHash */ + ret = memcpy_s(p + idx, pack->em_len - idx, hash_info.lhash_data, hash_len); + crypto_chk_return(ret != TD_SUCCESS, ret, "memcpy_s failed, ret is 0x%x\n", ret); + idx += hash_len; + + /* 4. set PS with 0x00 */ + tmp_len = pack->klen - pack->data_len - 2 * hash_len - 2; /* 2 */ + (void)memset_s(p + idx, tmp_len, 0x00, tmp_len); + idx += tmp_len; + + /* 5. set 0x01 after PS */ + p[idx++] = 0x01; + + /* 6. set M */ + if (pack->data_len != 0) { + ret = memcpy_s(p + idx, pack->em_len - idx, pack->data, pack->data_len); + crypto_chk_return(ret != TD_SUCCESS, ret, "memcpy_s failed, ret is 0x%x\n", ret); + } + /* 7. MGF: seed -> db */ + tmp_len = pack->klen - hash_len - 1; + ret = pkcs1_mgf(&hash_info, seed, hash_len, db, tmp_len); + crypto_chk_return(ret != TD_SUCCESS, ret, "pkcs1_mgf failed, ret is 0x%x\n", ret); + + /* 8. MGF: db -> seed */ + ret = pkcs1_mgf(&hash_info, db, tmp_len, seed, hash_len); + crypto_chk_return(ret != TD_SUCCESS, ret, "pkcs1_mgf failed, ret is 0x%x\n", ret); + + return ret; +} + +static td_s32 pkcs1_oaep_decrypt(const drv_pke_hash_type hash_type, rsa_pkcs1_pack *pack, + const drv_pke_data *label) +{ + td_s32 ret = TD_FAILURE; + rsa_pkcs1_hash_info hash_info = {0}; + td_u32 idx = 0; + td_u32 hash_len = 0; + td_u32 tmp_len = 0; + td_u8 *p = TD_NULL; + td_u8 *db = TD_NULL; + td_u8 *seed = TD_NULL; + + ret = pkcs1_get_hash(hash_type, label, &hash_info); + crypto_chk_return(ret != TD_SUCCESS, ret, "pkcs1_get_hash failed, ret is 0x%x\n", ret); + + hash_len = hash_info.hash_len; + + p = pack->em; + seed = p + 1; + db = p + hash_len + 1; + + /* 1. check data[0] = 0 */ + if (p[idx++] != 0x00) { + crypto_log_err("oaep padding check failed!\n"); + return PKE_COMPAT_ERRNO(ERROR_PKE_RSA_CRYPTO_OAEP_CHECK); + } + + /* 2. MGF: db -> seed */ + tmp_len = pack->klen - hash_len - 1; + ret = pkcs1_mgf(&hash_info, db, tmp_len, seed, hash_len); + crypto_chk_return(ret != TD_SUCCESS, ret, "pkcs1_mgf failed, ret is 0x%x\n", ret); + + /* 3. MGF: seed -> db */ + ret = pkcs1_mgf(&hash_info, seed, hash_len, db, tmp_len); + crypto_chk_return(ret != TD_SUCCESS, ret, "pkcs1_mgf failed, ret is 0x%x\n", ret); + + /* 4. check data[hash + 1, 2hash + 1] */ + idx += hash_len; + if (memcmp(p + idx, hash_info.lhash_data, hash_len) != 0) { + crypto_log_err("oaep lhash check failed!\n"); + return PKE_COMPAT_ERRNO(ERROR_PKE_RSA_CRYPTO_OAEP_CHECK); + } + + /* 5. remove PS */ + idx += hash_len; + for (; idx < pack->klen - 1; idx++) { + if (p[idx] != 0x00) { + break; + } + } + + /* 6. check 0x01 */ + if (p[idx++] != 0x01) { + crypto_log_err("oaep check failed!\n"); + return PKE_COMPAT_ERRNO(ERROR_PKE_RSA_CRYPTO_OAEP_CHECK); + } + + /* 7. check data length */ + tmp_len = pack->klen - idx; + if (tmp_len > pack->klen - 2 * hash_len - 2) { /* 2 */ + crypto_log_err("PS error.\n"); + return PKE_COMPAT_ERRNO(ERROR_PKE_RSA_CRYPTO_OAEP_CHECK); + } + + if (tmp_len > pack->data_len) { + crypto_log_err("Input buffer too small.\n"); + return PKE_COMPAT_ERRNO(ERROR_PKE_RSA_CRYPTO_OAEP_CHECK); + } + + if (tmp_len != 0) { + ret = memcpy_s(pack->data, pack->data_len, p + idx, tmp_len); + crypto_chk_return(ret != TD_SUCCESS, ret, "memcpy_s failed, ret is 0x%x\n", ret); + } + pack->data_len = tmp_len; // record length of plain text for return + + return ret; +} + +static td_s32 rsa_sign( + drv_pke_rsa_scheme scheme, + drv_pke_hash_type hash_type, + td_u8 *em, + td_u32 klen, + td_u32 em_bit, + const drv_pke_data *msg) +{ + td_s32 ret = TD_FAILURE; + rsa_pkcs1_pack sg_pack = { + .klen = klen, + .em_bit = em_bit, + .em = em, + .em_len = klen, + .hash = msg->data, + .hash_len = msg->length, + .data = TD_NULL, + .data_len = 0 + }; + + switch (scheme) { +#if defined(CONFIG_PKE_RSA_V15_SUPPORT) + case DRV_PKE_RSA_SCHEME_PKCS1_V15: { + ret = pkcs1_v15_sign(hash_type, &sg_pack); + crypto_chk_return(ret != TD_SUCCESS, ret, "pkcs1_v15_sign failed, ret is 0x%x\n", ret); + break; + } +#endif + case DRV_PKE_RSA_SCHEME_PKCS1_V21: { + ret = pkcs1_pss_sign(hash_type, &sg_pack); + crypto_chk_return(ret != TD_SUCCESS, ret, "pkcs1_pss_sign failed, ret is 0x%x\n", ret); + break; + } + default: + crypto_log_err("Invalid rsa sign padding type.\n"); + return PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM); + } + return ret; +} + +static td_s32 rsa_verify( + const drv_pke_rsa_scheme scheme, + const drv_pke_hash_type hash_type, + td_u8 *em, + const td_u32 klen, + const td_u32 em_bit, + const drv_pke_data *msg) +{ + td_s32 ret = TD_FAILURE; + rsa_pkcs1_pack vf_pack = { + .klen = klen, + .em_bit = em_bit, + .em = em, + .em_len = klen, + .hash = msg->data, + .hash_len = msg->length, + .data = TD_NULL, + .data_len = 0 + }; + + switch (scheme) { +#if defined(CONFIG_PKE_RSA_V15_SUPPORT) + case DRV_PKE_RSA_SCHEME_PKCS1_V15: { + ret = pkcs1_v15_verify(hash_type, &vf_pack); + crypto_chk_return(ret != TD_SUCCESS, ret, "pkcs1_v15_verify failed, ret is 0x%x\n", ret); + break; + } +#endif + case DRV_PKE_RSA_SCHEME_PKCS1_V21: { + ret = pkcs1_pss_verify(hash_type, &vf_pack); + crypto_chk_return(ret != TD_SUCCESS, ret, "pkcs1_pss_verify failed, ret is 0x%x\n", ret); + break; + } + default: + crypto_log_err("Invalid rsa verify padding type.\n"); + return PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM); + } + return ret; +} + +static td_s32 rsa_encrypt( + const drv_pke_rsa_scheme scheme, + const drv_pke_hash_type hash_type, + td_u8 *em, + const td_u32 klen, + const drv_pke_data *msg, + const drv_pke_data *label) +{ + td_s32 ret = TD_FAILURE; + rsa_pkcs1_pack en_pack = { + .klen = klen, + .em_bit = 0, + .em = em, + .em_len = klen, + .hash = TD_NULL, + .hash_len = 0, + .data = msg->data, + .data_len = msg->length + }; + + switch (scheme) { +#if defined(CONFIG_PKE_RSA_V15_SUPPORT) + case DRV_PKE_RSA_SCHEME_PKCS1_V15: { + ret = pkcs1_v15_encrypt(&en_pack); + crypto_chk_return(ret != TD_SUCCESS, ret, "pkcs1_v15_encrypt failed, ret is 0x%x\n", ret); + break; + } +#endif + case DRV_PKE_RSA_SCHEME_PKCS1_V21: { + ret = pkcs1_oaep_encrypt(hash_type, &en_pack, label); + crypto_chk_return(ret != TD_SUCCESS, ret, "pkcs1_oaep_encrypt failed, ret is 0x%x\n", ret); + break; + } + default: + crypto_log_err("Invalid rsa encrypt padding type.\n"); + return PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM); + } + return ret; +} + +static td_s32 rsa_decrypt(const drv_pke_rsa_scheme scheme, const drv_pke_hash_type hash_type, td_u8 *em, + const td_u32 klen, const drv_pke_data *label, drv_pke_data *msg) +{ + td_s32 ret = TD_FAILURE; + rsa_pkcs1_pack de_pack = { + .klen = klen, + .em_bit = 0, + .em = em, + .em_len = klen, + .hash = TD_NULL, + .hash_len = 0, + .data = msg->data, + .data_len = msg->length + }; + + switch (scheme) { +#if defined(CONFIG_PKE_RSA_V15_SUPPORT) + case DRV_PKE_RSA_SCHEME_PKCS1_V15: { + ret = pkcs1_v15_decrypt(&de_pack); + crypto_chk_return(ret != TD_SUCCESS, ret, "pkcs1_v15_decrypt failed, ret is 0x%x\n", ret); + msg->length = de_pack.data_len; // record length of plain text for return + break; + } +#endif + case DRV_PKE_RSA_SCHEME_PKCS1_V21: { + ret = pkcs1_oaep_decrypt(hash_type, &de_pack, label); + crypto_chk_return(ret != TD_SUCCESS, ret, "pkcs1_oaep_decrypt failed, ret is 0x%x\n", ret); + msg->length = de_pack.data_len; // record length of plain text for return + break; + } + default: + crypto_log_err("Invalid rsa decrypt padding type.\n"); + return PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM); + } + return ret; +} + +static td_s32 pke_rsa_sign( + const drv_pke_rsa_priv_key *priv_key, + drv_pke_rsa_scheme scheme, + drv_pke_hash_type hash_type, + const drv_pke_data *input_hash, + drv_pke_data *sign) +{ + td_s32 ret = TD_FAILURE; + td_u8 *em; + td_u32 klen = priv_key->n_len; + td_u32 em_bit = 0; + drv_pke_data in = {0}; + + em = crypto_malloc(DRV_PKE_LEN_4096); + if (em == TD_NULL) { + crypto_log_err("%s:%d Error! Malloc memory failed!\n", __FUNCTION__, __LINE__); + return PKE_COMPAT_ERRNO(ERROR_MALLOC); + } + (void)memset_s(em, DRV_PKE_LEN_4096, 0x00, DRV_PKE_LEN_4096); + + em_bit = rsa_get_bit_num((const td_u8 *)priv_key->n, priv_key->n_len); + ret = rsa_sign(scheme, hash_type, em, klen, em_bit, input_hash); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, exit__, ret, "rsa_sign failed, ret is 0x%x\n", ret); + + in = (drv_pke_data) {.length = klen, .data = em}; + ret = rsa_exp_mod(priv_key->n, priv_key->d, priv_key->n_len, &in, sign); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, exit__, ret, "rsa_exp_mod failed, ret is 0x%x\n", ret); + + if (memcmp(input_hash->data, sign->data, input_hash->length) == 0) { + ret = PKE_COMPAT_ERRNO(ERROR_PKE_RSA_SAME_DATA); + } + +exit__: + if (em != TD_NULL) { + (void)memset_s(em, DRV_PKE_LEN_4096, 0, DRV_PKE_LEN_4096); + crypto_free(em); + } + return ret; +} + +static td_s32 pke_rsa_verify( + const drv_pke_rsa_pub_key *pub_key, + drv_pke_rsa_scheme scheme, + drv_pke_hash_type hash_type, + const drv_pke_data *input_hash, + const drv_pke_data *sign) +{ + td_s32 ret = TD_FAILURE; + td_u8 *em; + td_u8 *pem; + td_u32 klen = pub_key->len; + td_u32 em_bit = 0; + drv_pke_data out = {0}; + + em = crypto_malloc(DRV_PKE_LEN_4096); + if (em == TD_NULL) { + crypto_log_err("%s:%d Error! Malloc memory failed!\n", __FUNCTION__, __LINE__); + return PKE_COMPAT_ERRNO(ERROR_MALLOC); + } + (void)memset_s(em, DRV_PKE_LEN_4096, 0x00, DRV_PKE_LEN_4096); + pem = em; + + out = (drv_pke_data) {.length = klen, .data = em}; + ret = rsa_exp_mod(pub_key->n, pub_key->e, pub_key->len, sign, &out); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, exit__, ret, "rsa_exp_mod failed, ret is 0x%x\n", ret); + + if (memcmp(sign->data, pem, pub_key->len) == 0) { + ret = PKE_COMPAT_ERRNO(ERROR_PKE_RSA_SAME_DATA); + goto exit__; + } + + em_bit = rsa_get_bit_num((const td_u8 *)pub_key->n, pub_key->len); + ret = rsa_verify(scheme, hash_type, em, klen, em_bit, input_hash); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, exit__, ret, "rsa_verify failed, ret is 0x%x\n", ret); + +exit__: + if (em != TD_NULL) { + (void)memset_s(em, DRV_PKE_LEN_4096, 0, DRV_PKE_LEN_4096); + crypto_free(em); + } + return ret; +} + +static td_s32 pke_rsa_encrypt( + drv_pke_rsa_scheme scheme, + drv_pke_hash_type hash_type, + const drv_pke_rsa_pub_key *pub_key, + const drv_pke_data *input, + const drv_pke_data *label, + const drv_pke_data *output) +{ + td_s32 ret = TD_FAILURE; + td_u8 em[DRV_PKE_LEN_4096]; + td_u32 klen = pub_key->len; + td_u8 *n = pub_key->n; + td_u8 *key = pub_key->e; + drv_pke_data data_in = {0}; + + (void)memset_s(em, sizeof(em), 0x00, sizeof(em)); + ret = rsa_encrypt(scheme, hash_type, em, klen, input, label); + crypto_chk_return(ret != TD_SUCCESS, ret, "rsa_encrypt failed, ret is 0x%x\n", ret); + data_in = (drv_pke_data) {.length = klen, .data = em}; + ret = rsa_exp_mod(n, key, klen, &data_in, output); + crypto_chk_return(ret != TD_SUCCESS, ret, "rsa_exp_mod failed, ret is 0x%x\n", ret); + if (memcmp(input->data, output->data, input->length) == 0) { + return PKE_COMPAT_ERRNO(ERROR_PKE_RSA_SAME_DATA); + } + + return ret; +} + +static td_s32 pke_rsa_decrypt( + drv_pke_rsa_scheme scheme, + drv_pke_hash_type hash_type, + const drv_pke_rsa_priv_key *priv_key, + const drv_pke_data *input, + const drv_pke_data *label, + drv_pke_data *output) +{ + td_s32 ret = TD_FAILURE; + td_u8 em[DRV_PKE_LEN_4096]; + td_u32 klen = priv_key->n_len; + td_u8 *n = priv_key->n; + td_u8 *key = priv_key->d; + drv_pke_data data_out = {0}; + + (void)memset_s(em, sizeof(em), 0x00, sizeof(em)); + + data_out = (drv_pke_data) {.length = klen, .data = em}; + ret = rsa_exp_mod(n, key, klen, input, &data_out); + crypto_chk_return(ret != TD_SUCCESS, ret, "rsa_exp_mod failed, ret is 0x%x\n", ret); + ret = rsa_decrypt(scheme, hash_type, em, klen, label, output); + crypto_chk_return(ret != TD_SUCCESS, ret, "rsa_decrypt failed, ret is 0x%x\n", ret); + if (memcmp(input->data, output->data, output->length) == 0) { + return PKE_COMPAT_ERRNO(ERROR_PKE_RSA_SAME_DATA); + } + return ret; +} + +// expose layer +td_s32 drv_cipher_pke_rsa_sign( + const drv_pke_rsa_priv_key *priv_key, + const drv_pke_rsa_scheme scheme, + const drv_pke_hash_type hash_type, + const drv_pke_data *input_hash, + drv_pke_data *sign) +{ + td_s32 ret = TD_FAILURE; + td_u32 klen = 0; + td_u32 hash_len = 0; + /* check ptr. */ + pke_null_ptr_chk(priv_key); + pke_null_ptr_chk(priv_key->n); + pke_null_ptr_chk(priv_key->d); + pke_null_ptr_chk(input_hash); + pke_null_ptr_chk(input_hash->data); + pke_null_ptr_chk(sign); + pke_null_ptr_chk(sign->data); + + /* check enum. */ + crypto_chk_return(scheme >= DRV_PKE_RSA_SCHEME_MAX, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "scheme is Invalid\n"); + crypto_chk_return(hash_type < DRV_PKE_HASH_TYPE_SHA256 || hash_type > DRV_PKE_HASH_TYPE_SHA512, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "hash_type is Invalid\n"); + + /* check length. */ + klen = priv_key->n_len; + hash_len = drv_get_hash_len(hash_type); + crypto_chk_return(input_hash->length != hash_len, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "input_hash->length is Invalid\n"); + + crypto_chk_return(klen != DRV_PKE_LEN_2048 && klen != DRV_PKE_LEN_3072 && klen != DRV_PKE_LEN_4096, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "n_len is Invalid\n"); + if ((priv_key->d_len != klen)) { + ret = PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM); + crypto_log_err("d_len is Invalid!\n"); + return ret; + } + crypto_chk_return(sign->length < klen, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "sign_len is Invalid\n"); + crypto_chk_return(crypto_rsa_support(klen, scheme) == TD_FALSE, PKE_COMPAT_ERRNO(ERROR_UNSUPPORT), + "alg is unsupport\n"); + ret = drv_cipher_pke_lock_secure(); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_pke_lock_secure failed, ret is 0x%x\n", ret); + ret = pke_rsa_sign(priv_key, scheme, hash_type, input_hash, sign); + if (ret == TD_SUCCESS) { + sign->length = klen; + } + (void)drv_cipher_pke_unlock_secure(); + return ret; +} + +td_s32 drv_cipher_pke_rsa_verify( + const drv_pke_rsa_pub_key *pub_key, + const drv_pke_rsa_scheme scheme, + const drv_pke_hash_type hash_type, + const drv_pke_data *input_hash, + const drv_pke_data *sign) +{ + td_s32 ret = TD_FAILURE; + td_u32 klen = 0; + td_u32 hash_len; + /* check ptr. */ + pke_null_ptr_chk(pub_key); + pke_null_ptr_chk(pub_key->n); + pke_null_ptr_chk(pub_key->e); + pke_null_ptr_chk(input_hash); + pke_null_ptr_chk(input_hash->data); + pke_null_ptr_chk(sign); + pke_null_ptr_chk(sign->data); + + /* check enum. */ + crypto_chk_return(scheme >= DRV_PKE_RSA_SCHEME_MAX, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "scheme is Invalid\n"); + crypto_chk_return(hash_type < DRV_PKE_HASH_TYPE_SHA1 || hash_type > DRV_PKE_HASH_TYPE_SHA512, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "hash_type is Invalid\n"); + + /* check length. */ + hash_len = drv_get_hash_len(hash_type); + crypto_chk_return(input_hash->length != hash_len, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "input_hash->length is Invalid\n"); + + klen = pub_key->len; + if ((klen != DRV_PKE_LEN_2048 && klen != DRV_PKE_LEN_3072 && klen != DRV_PKE_LEN_4096)) { + ret = PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM); + crypto_log_err("k_len is Invalid!\n"); + return ret; + } + crypto_chk_return(sign->length < klen, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "sign_len is Invalid\n"); + crypto_chk_return(crypto_rsa_support(klen, scheme) == TD_FALSE, PKE_COMPAT_ERRNO(ERROR_UNSUPPORT), + "alg is unsupport\n"); + ret = drv_cipher_pke_lock_secure(); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_pke_lock_secure failed, ret is 0x%x\n", ret); + ret = pke_rsa_verify(pub_key, scheme, hash_type, input_hash, sign); + (void)drv_cipher_pke_unlock_secure(); + return ret; +} + +td_s32 drv_cipher_pke_rsa_public_encrypt( + const drv_pke_rsa_scheme scheme, + const drv_pke_hash_type hash_type, + const drv_pke_rsa_pub_key *pub_key, + const drv_pke_data *input, + const drv_pke_data *label, + drv_pke_data *output) +{ + td_s32 ret = TD_FAILURE; + td_u32 klen = 0; + td_u32 hash_len = 0; + td_u32 input_len = 0; + /* check ptr. */ + pke_null_ptr_chk(pub_key); + pke_null_ptr_chk(pub_key->n); + pke_null_ptr_chk(pub_key->e); + pke_null_ptr_chk(input); + pke_null_ptr_chk(input->data); + pke_null_ptr_chk(output); + pke_null_ptr_chk(output->data); + if (label != TD_NULL) { + pke_null_ptr_chk(label->data); + } + + /* check enum. */ + crypto_chk_return(scheme >= DRV_PKE_RSA_SCHEME_MAX, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "scheme is Invalid\n"); + crypto_chk_return(hash_type < DRV_PKE_HASH_TYPE_SHA256 || hash_type > DRV_PKE_HASH_TYPE_SHA512, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "hash_type is Invalid\n"); + + /* check length. */ + klen = pub_key->len; + input_len = input->length; + hash_len = drv_get_hash_len(hash_type); + crypto_chk_return(hash_len == 0, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "hash_type is Invalid\n"); + + crypto_chk_return(klen != DRV_PKE_LEN_2048 && klen != DRV_PKE_LEN_3072 && klen != DRV_PKE_LEN_4096, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "n_len is Invalid\n"); + /* + * For V15, the plain_text's max length is klen - 11. + * For OAEP, the plain_text's max length is klen - 2 * hash_len - 2. + */ + if (scheme == DRV_PKE_RSA_SCHEME_PKCS1_V15) { + crypto_chk_return(input_len > klen - RSA_PADLEN_11, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "input_len is too long for V15\n"); + } else { + crypto_chk_return(input_len > klen - 2 * hash_len - 2, // 2: refer to comment. + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "input_len is too long for V21\n"); + } + crypto_chk_return(input_len == 0, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "input_len is zero\n"); + crypto_chk_return(output->length < klen, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "output_len is Invalid\n"); + crypto_chk_return(crypto_rsa_support(klen, scheme) == TD_FALSE, PKE_COMPAT_ERRNO(ERROR_UNSUPPORT), + "alg is unsupport\n"); + ret = drv_cipher_pke_lock_secure(); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_pke_lock_secure failed, ret is 0x%x\n", ret); + ret = pke_rsa_encrypt(scheme, hash_type, pub_key, input, label, output); + if (ret == TD_SUCCESS) { + output->length = klen; + } + (void)drv_cipher_pke_unlock_secure(); + return ret; +} + +td_s32 drv_cipher_pke_rsa_private_decrypt( + const drv_pke_rsa_scheme scheme, + const drv_pke_hash_type hash_type, + const drv_pke_rsa_priv_key *priv_key, + const drv_pke_data *input, + const drv_pke_data *label, + drv_pke_data *output) +{ + td_s32 ret = TD_FAILURE; + + td_u32 klen = 0; + td_u32 hash_len = 0; + td_u32 output_len = 0; + /* check ptr. */ + pke_null_ptr_chk(priv_key); + pke_null_ptr_chk(priv_key->n); + pke_null_ptr_chk(priv_key->d); + pke_null_ptr_chk(input); + pke_null_ptr_chk(input->data); + pke_null_ptr_chk(output); + pke_null_ptr_chk(output->data); + if (label != TD_NULL) { + pke_null_ptr_chk(label->data); + } + + /* check enum. */ + crypto_chk_return(scheme >= DRV_PKE_RSA_SCHEME_MAX, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "scheme is Invalid\n"); + crypto_chk_return(hash_type < DRV_PKE_HASH_TYPE_SHA256 || hash_type > DRV_PKE_HASH_TYPE_SHA512, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "hash_type is Invalid\n"); + + /* check length. */ + klen = priv_key->n_len; + output_len = output->length; + hash_len = drv_get_hash_len(hash_type); + crypto_chk_return(hash_len == 0, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "hash_type is Invalid\n"); + + crypto_chk_return(klen != DRV_PKE_LEN_2048 && klen != DRV_PKE_LEN_3072 && klen != DRV_PKE_LEN_4096, + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "n_len is Invalid\n"); + crypto_chk_return(priv_key->d_len != klen, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "d_len is Invalid\n"); + crypto_chk_return(input->length != klen, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "input_len is Invalid\n"); + + /* + * For V15, the plain_text's max length is klen - 11. + * For OAEP, the plain_text's max length is klen - 2 * hash_len - 2. + */ + if (scheme == DRV_PKE_RSA_SCHEME_PKCS1_V15) { + crypto_chk_return(output_len < klen - RSA_PADLEN_11, PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "output_len is not enough for V15\n"); + } else { + crypto_chk_return(output_len < klen - 2 * hash_len - 2, // 2: refer to comment. + PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM), "input_len is not enough for V21\n"); + } + crypto_chk_return(crypto_rsa_support(klen, scheme) == TD_FALSE, PKE_COMPAT_ERRNO(ERROR_UNSUPPORT), + "alg is unsupport\n"); + ret = drv_cipher_pke_lock_secure(); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_pke_lock_secure failed, ret is 0x%x\n", ret); + ret = pke_rsa_decrypt(scheme, hash_type, priv_key, input, label, output); + (void)drv_cipher_pke_unlock_secure(); + return ret; +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_symc.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_symc.c new file mode 100644 index 00000000..948f7544 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_symc.c @@ -0,0 +1,1392 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "drv_symc.h" +#include "drv_inner.h" +#include "hal_symc.h" +#include "crypto_drv_common.h" + +#define SYMC_COMPAT_ERRNO(err_code) DRV_COMPAT_ERRNO(ERROR_MODULE_SYMC, err_code) +#define symc_null_ptr_chk(ptr) \ + crypto_chk_return((ptr) == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), #ptr" is NULL\n") + +#define CRYPTO_DRV_CCM_DMA_SIZE (CRYPTO_AES_BLOCK_SIZE_IN_BYTES * 3) /* For N + ccm_header + ccm_padding. */ +#define CRYPTO_DRV_GCM_DMA_SIZE (CRYPTO_AES_BLOCK_SIZE_IN_BYTES * 2) /* For aad_padding + clen. */ +#define CRYPTO_DRV_DMA_SIZE (4 * 1024) +#define CRYPTO_DRV_DMA_TOTAL_SIZE (CRYPTO_DRV_DMA_SIZE * CRYPTO_SYMC_HARD_CHANNEL_MAX) + +static td_u8 *g_drv_dma_buf = TD_NULL; + +static drv_symc_context_t g_drv_symc_ctx_list[CRYPTO_SYMC_HARD_CHANNEL_MAX]; + +td_s32 inner_symc_drv_handle_chk(td_handle symc_handle) +{ + td_u32 chn_num = (td_u32)symc_handle; + if (chn_num >= CRYPTO_SYMC_HARD_CHANNEL_MAX) { + return SYMC_COMPAT_ERRNO(ERROR_INVALID_HANDLE); + } + if (((1 << chn_num) & CRYPTO_SYMC_HARD_CHANNEL_MASK) == 0) { + return SYMC_COMPAT_ERRNO(ERROR_INVALID_HANDLE); + } + return TD_SUCCESS; +} + +drv_symc_context_t *inner_get_symc_ctx(td_handle symc_handle) +{ + td_s32 ret; + td_u32 chn_num = (td_u32)symc_handle; + ret = inner_symc_drv_handle_chk(symc_handle); + if (ret != TD_SUCCESS) { + return TD_NULL; + } + return &g_drv_symc_ctx_list[chn_num]; +} + +td_s32 drv_cipher_symc_init(td_void) +{ + td_s32 ret; + crypto_drv_func_enter(); + ret = hal_cipher_symc_init(); + if (ret != TD_SUCCESS) { + crypto_log_err("hal_cipher_symc_init failed, ret is 0x%x\n", ret); + return ret; + } + g_drv_dma_buf = crypto_malloc_coherent(CRYPTO_DRV_DMA_TOTAL_SIZE, "cipher_symc_drv"); + if (g_drv_dma_buf == TD_NULL) { + hal_cipher_symc_deinit(); + return SYMC_COMPAT_ERRNO(ERROR_MALLOC); + } + + crypto_drv_func_exit(); + return ret; +} + +td_s32 drv_cipher_symc_deinit(td_void) +{ + crypto_drv_func_enter(); + if (g_drv_dma_buf != TD_NULL) { + (td_void)memset_s(g_drv_dma_buf, CRYPTO_DRV_DMA_TOTAL_SIZE, 0, CRYPTO_DRV_DMA_TOTAL_SIZE); + crypto_free_coherent(g_drv_dma_buf); + g_drv_dma_buf = TD_NULL; + } + hal_cipher_symc_deinit(); + crypto_drv_func_exit(); + return TD_SUCCESS; +} + +td_s32 drv_cipher_symc_create(td_handle *symc_handle, const crypto_symc_attr *symc_attr) +{ + td_u32 i; + td_s32 ret = CRYPTO_SUCCESS; + drv_symc_context_t *symc_ctx = TD_NULL; + crypto_drv_func_enter(); + + symc_null_ptr_chk(symc_handle); + symc_null_ptr_chk(symc_attr); + + for (i = 1; i < CRYPTO_SYMC_HARD_CHANNEL_MAX; i++) { + symc_ctx = &g_drv_symc_ctx_list[i]; + if (symc_ctx->is_open == TD_TRUE) { + continue; + } + ret = hal_cipher_symc_lock_chn(i); + if (ret == CRYPTO_SUCCESS) { + break; + } + } + if (i >= CRYPTO_SYMC_HARD_CHANNEL_MAX) { + crypto_log_err("All SYMC Channels are busy!\n"); + return SYMC_COMPAT_ERRNO(ERROR_CHN_BUSY); + } + symc_ctx = &g_drv_symc_ctx_list[i]; + (td_void)memset_s(symc_ctx, sizeof(drv_symc_context_t), 0, sizeof(drv_symc_context_t)); + + /* + * For CBC_MAC, store data copy; + * For CCM, store N + ccm_header + ccm_padding + * For GCM, store aad_padding + clen + */ + symc_ctx->dma_addr = g_drv_dma_buf + i * CRYPTO_DRV_DMA_SIZE; + symc_ctx->dma_size = CRYPTO_DRV_DMA_SIZE; + symc_ctx->chn_num = i; + symc_ctx->is_open = TD_TRUE; + *symc_handle = i; + + crypto_drv_func_exit(); + return CRYPTO_SUCCESS; +} + +td_s32 drv_cipher_symc_destroy(td_handle symc_handle) +{ + td_s32 ret; + drv_symc_context_t *symc_ctx = TD_NULL; + td_u32 chn_num = (td_u32)symc_handle; + crypto_drv_func_enter(); + + ret = inner_symc_drv_handle_chk(symc_handle); + if (ret != TD_SUCCESS) { + crypto_log_err("Invalid Handle\n"); + return ret; + } + symc_ctx = &g_drv_symc_ctx_list[chn_num]; + +#if defined(CONFIG_CRYPTO_SOFT_CENC_SUPPORT) + cenc_ddr_release(); + cenc_ddr_unmap_input(chn_num); +#endif + (td_void)memset_s(symc_ctx, sizeof(drv_symc_context_t), 0, sizeof(drv_symc_context_t)); + ret = hal_cipher_symc_unlock_chn(chn_num); + if (ret != TD_SUCCESS) { + crypto_log_err("hal_cipher_symc_unlock_chn failed, ret is 0x%x\n", ret); + } + + crypto_drv_func_exit(); + return TD_SUCCESS; +} + +static td_s32 inner_format_ccm_iv(const td_u8 *iv, td_u32 iv_length, td_u8 *ccm_iv, td_u32 *ccm_iv_length) +{ + td_s32 ret; + ccm_iv[0] = CRYPTO_AES_CCM_NQ_LEN - iv_length; + ret = memcpy_s(&ccm_iv[1], *ccm_iv_length - 1, iv, iv_length); + if (ret != EOK) { + crypto_log_err("memcpy_s failed\n"); + return TD_FAILURE; + } + *ccm_iv_length = iv_length + 1; + return TD_SUCCESS; +} + +static td_void inner_format_ccm_header(td_u32 aad_len, td_u8 *ccm_header, td_u32 *ccm_header_len) +{ + td_u32 idx = 0; + ccm_header[idx++] = (td_u8)(aad_len >> 8); /* 8: bits 15-8 */ + ccm_header[idx++] = (td_u8)(aad_len); + *ccm_header_len = idx; +} + +static td_s32 priv_symc_cfg_ex_param_check(const crypto_symc_ctrl_t *symc_ctrl) +{ + crypto_symc_work_mode mode = symc_ctrl->work_mode; + crypto_symc_config_aes_ccm_gcm *ccm_gcm_param = (crypto_symc_config_aes_ccm_gcm *)symc_ctrl->param; + td_u32 iv_length = symc_ctrl->iv_length; + td_u32 tag_len; + td_u32 data_len; + td_u32 diff = 0; + + crypto_chk_return(ccm_gcm_param == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "param is NULL\n"); + tag_len = ccm_gcm_param->tag_len; + data_len = ccm_gcm_param->data_len; + /* Check for CCM. */ + if (mode == CRYPTO_SYMC_WORK_MODE_CCM && symc_ctrl->iv_change_flag == CRYPTO_SYMC_CCM_IV_CHANGE_START) { + /* IV lenght for CCM, which should be 7~13. */ + crypto_chk_return(iv_length > 13 || iv_length < 7, // 7: min iv_len for ccm, 13: max iv_len for ccm. + SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM), "iv_len must be 7~13 for CCM\n"); + /* Tag length for CCM should be 4,6,8,10,12,14,16. */ + crypto_chk_return( + tag_len % 2 != 0 || tag_len < 4 || tag_len > 16, // 4: min tag_len, 16: max tag_len, 2: judge if even. + SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM), "tag_len must be 4,6,8,10,12,14,16 for CCM\n"); + diff = CRYPTO_IV_LEN_IN_BYTES - iv_length - 1; + if (diff == 2) { // 2: 2 * 8 bits to represent data_len. + crypto_chk_return(data_len > 0xFFFF, SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM), // 0xFFFF: 2^16 - 1 + "data_len is too long\n"); + } + if (diff == 3) { // 3: 3 * 8 bits to represent data_len. + crypto_chk_return(data_len > 0xFFFFFF, SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM), // 0xFFFFFF: 2^24 - 1 + "data_len is too long\n"); + } + } + + /* Check for GCM. */ + if (mode == CRYPTO_SYMC_WORK_MODE_GCM && symc_ctrl->iv_change_flag == CRYPTO_SYMC_CCM_IV_CHANGE_START) { + /* IV lenght for GCM, which should be 1~16. */ + crypto_chk_return(iv_length == 0 || iv_length > CRYPTO_IV_LEN_IN_BYTES, SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "iv_len must be 1~16 for GCM.\n"); + /* Tag length for GCM should be 1~16.. */ + crypto_chk_return(tag_len == 0 || tag_len > CRYPTO_AES_MAX_TAG_SIZE, SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "tag_len must be 1~16 for GCM.\n"); + } + return TD_SUCCESS; +} + +td_s32 inner_symc_cfg_param_check(const crypto_symc_ctrl_t *symc_ctrl) +{ + td_bool is_support = TD_FALSE; + crypto_symc_alg symc_alg = symc_ctrl->symc_alg; + crypto_symc_work_mode mode = symc_ctrl->work_mode; + crypto_symc_key_length key_length = symc_ctrl->symc_key_length; + crypto_symc_bit_width bit_width = symc_ctrl->symc_bit_width; + crypto_symc_iv_change_type iv_change_flag = symc_ctrl->iv_change_flag; + td_u32 iv_length = symc_ctrl->iv_length; + + /* Check Common Params. */ + crypto_chk_return(symc_alg != CRYPTO_SYMC_ALG_AES && symc_alg != CRYPTO_SYMC_ALG_SM4, + SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM), "symc_alg is invalid\n"); + crypto_chk_return(mode > CRYPTO_SYMC_WORK_MODE_GCM, SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM), "mode is invalid\n"); + crypto_chk_return(key_length < CRYPTO_SYMC_KEY_128BIT || key_length > CRYPTO_SYMC_KEY_256BIT, + SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM), "key_length is invalid\n"); + crypto_chk_return(bit_width >= CRYPTO_SYMC_BIT_WIDTH_MAX, + SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM), "bit_width is invalid\n"); + crypto_chk_return(iv_change_flag >= CRYPTO_SYMC_IV_CHANGE_MAX, SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "iv_change_flag is invalid\n"); + + /* Check Mode. && Check key_length. */ + if (symc_alg == CRYPTO_SYMC_ALG_SM4) { + /* SM4 only support ECB/CBC/CTR. */ + crypto_chk_return(mode != CRYPTO_SYMC_WORK_MODE_ECB && mode != CRYPTO_SYMC_WORK_MODE_CBC && + mode != CRYPTO_SYMC_WORK_MODE_CTR, SYMC_COMPAT_ERRNO(ERROR_UNSUPPORT), "sm4 unsupport this mode\n"); + /* SM4's keylength must be 128. */ + crypto_chk_return(key_length != CRYPTO_SYMC_KEY_128BIT, SYMC_COMPAT_ERRNO(ERROR_UNSUPPORT), + "sm4's key_len only support 128-bit\n"); + } + + /* Check bit_width. */ + if (mode == CRYPTO_SYMC_WORK_MODE_CFB) { + crypto_chk_return(bit_width == CRYPTO_SYMC_BIT_WIDTH_64BIT, SYMC_COMPAT_ERRNO(ERROR_UNSUPPORT), + "CFB's bit-width don't support 64-bit\n"); + } else { + crypto_chk_return(bit_width != CRYPTO_SYMC_BIT_WIDTH_128BIT, SYMC_COMPAT_ERRNO(ERROR_UNSUPPORT), + "bit-width only support 128-bit\n"); + } + + /* Check iv_change_flag. */ + + /* Check iv_length. */ + if (mode != CRYPTO_SYMC_WORK_MODE_CCM && mode != CRYPTO_SYMC_WORK_MODE_GCM && mode != CRYPTO_SYMC_WORK_MODE_ECB) { + crypto_chk_return(iv_length != CRYPTO_IV_LEN_IN_BYTES, SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "iv_length is invalid\n"); + } + + if (mode == CRYPTO_SYMC_WORK_MODE_CCM || mode == CRYPTO_SYMC_WORK_MODE_GCM) { + return priv_symc_cfg_ex_param_check(symc_ctrl); + } + + is_support = crypto_symc_support(symc_ctrl->symc_alg, symc_ctrl->work_mode, + symc_ctrl->symc_key_length, symc_ctrl->symc_bit_width); + crypto_chk_return(is_support == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_UNSUPPORT), "alg is unsupport\n"); + if (symc_ctrl->symc_alg == CRYPTO_SYMC_ALG_SM4) { + is_support = crypto_sm_support(CRYPTO_SM_ALG_SM4); + } + crypto_chk_return(is_support == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_UNSUPPORT), "alg is unsupport\n"); + + return TD_SUCCESS; +} + +static td_s32 inner_drv_set_config_ex(drv_symc_context_t *drv_symc_ctx, const crypto_symc_ctrl_t *symc_ctrl, + hal_symc_config_t *hal_symc_config) +{ + td_s32 ret; + crypto_symc_config_aes_ccm_gcm *ccm_gcm_config = TD_NULL; + + if (symc_ctrl->iv_change_flag == CRYPTO_SYMC_CCM_IV_CHANGE_UPDATE || + symc_ctrl->iv_change_flag == CRYPTO_SYMC_GCM_IV_CHANGE_UPDATE) { + drv_symc_ctx->iv_change_flag = symc_ctrl->iv_change_flag; + drv_symc_ctx->is_config = TD_TRUE; + return TD_SUCCESS; + } + + /* CCM. */ + ccm_gcm_config = (crypto_symc_config_aes_ccm_gcm *)symc_ctrl->param; + crypto_chk_return(ccm_gcm_config->aad_len > CRYPTO_SYMC_AAD_MAX_SIZE, SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "aad_len is too long\n"); + drv_symc_ctx->aad_len = ccm_gcm_config->aad_len; + drv_symc_ctx->data_len = ccm_gcm_config->data_len; + drv_symc_ctx->processed_len = 0; + if (ccm_gcm_config->aad_len != 0) { + symc_null_ptr_chk(ccm_gcm_config->aad_buf.virt_addr); + drv_symc_ctx->aad_phys = ccm_gcm_config->aad_buf.phys_addr; + drv_symc_ctx->aad_virt = ccm_gcm_config->aad_buf.virt_addr; + } + + ret = memcpy_s(&drv_symc_ctx->param.ccm_config, sizeof(crypto_symc_config_aes_ccm_gcm), + symc_ctrl->param, sizeof(crypto_symc_config_aes_ccm_gcm)); + crypto_chk_return(ret != EOK, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed, ret is 0x%x\n", ret); + + hal_symc_config->gcm_iv_ptr = symc_ctrl->iv; + hal_symc_config->gcm_iv_len = symc_ctrl->iv_length; + + if (symc_ctrl->work_mode == CRYPTO_SYMC_WORK_MODE_CCM + && drv_symc_ctx->iv_change_flag == CRYPTO_SYMC_CCM_IV_CHANGE_START) { + drv_symc_ctx->iv_length = sizeof(drv_symc_ctx->iv); + ret = inner_format_ccm_iv(symc_ctrl->iv, symc_ctrl->iv_length, drv_symc_ctx->iv, &(drv_symc_ctx->iv_length)); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_format_ccm_iv failed, ret is 0x%x\n", ret); + } + return TD_SUCCESS; +} + +td_s32 drv_cipher_symc_set_config(td_handle symc_handle, const crypto_symc_ctrl_t *symc_ctrl) +{ + td_s32 ret; + td_u32 chn_num = symc_handle; + hal_symc_config_t hal_symc_config = {0}; + drv_symc_context_t *drv_symc_ctx = TD_NULL; + crypto_drv_func_enter(); + ret = inner_symc_drv_handle_chk(symc_handle); + if (ret != TD_SUCCESS) { + return ret; + } + symc_null_ptr_chk(symc_ctrl); + ret = inner_symc_cfg_param_check(symc_ctrl); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_symc_cfg_param_check failed, ret is 0x%x\n", ret); + + drv_symc_ctx = &g_drv_symc_ctx_list[chn_num]; + crypto_chk_return(drv_symc_ctx->is_open == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_CTX_CLOSED), "ctx is closed\n"); + + drv_symc_ctx->work_mode = symc_ctrl->work_mode; + drv_symc_ctx->iv_change_flag = symc_ctrl->iv_change_flag; + (td_void)memset_s(drv_symc_ctx->iv, sizeof(drv_symc_ctx->iv), 0, sizeof(drv_symc_ctx->iv)); + ret = memcpy_s(drv_symc_ctx->iv, sizeof(drv_symc_ctx->iv), symc_ctrl->iv, symc_ctrl->iv_length); + crypto_chk_return(ret != EOK, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + if (symc_ctrl->work_mode == CRYPTO_SYMC_WORK_MODE_CCM || symc_ctrl->work_mode == CRYPTO_SYMC_WORK_MODE_GCM) { + ret = inner_drv_set_config_ex(drv_symc_ctx, symc_ctrl, &hal_symc_config); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_drv_set_config_ex failed, ret is 0x%x\n", ret); + } + + ret = hal_cipher_symc_set_iv(chn_num, drv_symc_ctx->iv, sizeof(drv_symc_ctx->iv)); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_set_iv failed, ret is 0x%x\n", ret); + + hal_symc_config.symc_alg = symc_ctrl->symc_alg; + hal_symc_config.work_mode = symc_ctrl->work_mode; + hal_symc_config.symc_bit_width = symc_ctrl->symc_bit_width; + hal_symc_config.symc_key_length = symc_ctrl->symc_key_length; + hal_symc_config.iv_change_flag = symc_ctrl->iv_change_flag; + ret = hal_cipher_symc_config(chn_num, &hal_symc_config); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_config failed, ret is 0x%x\n", ret); + +#if defined(CRYPTO_CTR_NON_ALIGN_SUPPORT) + drv_symc_ctx->ctr_offset = 0; +#endif + drv_symc_ctx->is_config = TD_TRUE; + crypto_drv_func_exit(); + return ret; +} + +td_s32 drv_cipher_symc_get_module_info(crypto_symc_module_info *module_info) +{ + return hal_cipher_symc_get_module_info(module_info); +} + +td_s32 drv_cipher_symc_get_proc_info(td_handle symc_handle, crypto_symc_proc_info *proc_symc_info) +{ + td_s32 ret; + td_u32 chn_num; + drv_symc_context_t *drv_symc_ctx = TD_NULL; + + crypto_drv_func_enter(); + ret = inner_symc_drv_handle_chk(symc_handle); + if (ret != TD_SUCCESS) { + return ret; + } + symc_null_ptr_chk(proc_symc_info); + + chn_num = symc_handle; + drv_symc_ctx = &g_drv_symc_ctx_list[chn_num]; + proc_symc_info->chn_id = chn_num; + proc_symc_info->open = drv_symc_ctx->is_open; + + if (drv_symc_ctx->is_open == TD_FALSE) { + return SYMC_COMPAT_ERRNO(ERROR_CTX_CLOSED); + } + + if (drv_symc_ctx->is_config == TD_FALSE) { + return SYMC_COMPAT_ERRNO(ERROR_NOT_SET_CONFIG); + } + + ret = hal_cipher_symc_get_proc_info(chn_num, proc_symc_info); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_get_proc_info, ret is 0x%x\n", ret); + + ret = hal_cipher_symc_get_iv(chn_num, proc_symc_info->iv, sizeof(proc_symc_info->iv)); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_get_iv failed, ret is 0x%x\n", ret); + + crypto_drv_func_exit(); + return ret; +} + +td_s32 drv_cipher_symc_get_config(td_handle symc_handle, crypto_symc_ctrl_t *symc_ctrl) +{ + td_s32 ret; + td_u32 chn_num; + hal_symc_config_t hal_symc_config = {0}; + drv_symc_context_t *drv_symc_ctx = TD_NULL; + + crypto_drv_func_enter(); + ret = inner_symc_drv_handle_chk(symc_handle); + if (ret != TD_SUCCESS) { + return ret; + } + symc_null_ptr_chk(symc_ctrl); + + chn_num = symc_handle; + drv_symc_ctx = &g_drv_symc_ctx_list[chn_num]; + crypto_chk_return(drv_symc_ctx->is_open == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_CTX_CLOSED), "ctx is closed\n"); + crypto_chk_return(drv_symc_ctx->is_config == TD_FALSE, + SYMC_COMPAT_ERRNO(ERROR_NOT_SET_CONFIG), "call set_config first\n"); + + ret = hal_cipher_symc_get_config(chn_num, &hal_symc_config); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_unlock_chn failed, ret is 0x%x\n", ret); + + symc_ctrl->symc_alg = hal_symc_config.symc_alg; + symc_ctrl->work_mode = hal_symc_config.work_mode; + symc_ctrl->symc_bit_width = hal_symc_config.symc_bit_width; + symc_ctrl->symc_key_length = hal_symc_config.symc_key_length; + symc_ctrl->iv_length = CRYPTO_IV_LEN_IN_BYTES; + symc_ctrl->iv_change_flag = hal_symc_config.iv_change_flag; + + ret = memcpy_s(symc_ctrl->iv, symc_ctrl->iv_length, drv_symc_ctx->iv, sizeof(drv_symc_ctx->iv)); + crypto_chk_return(ret != EOK, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed, ret is 0x%x\n", ret); + + /* CCM. */ + if (symc_ctrl->work_mode == CRYPTO_SYMC_WORK_MODE_CCM || symc_ctrl->work_mode == CRYPTO_SYMC_WORK_MODE_GCM) { + crypto_chk_return(symc_ctrl->param == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "Param is NULL!\n"); + ret = memcpy_s(symc_ctrl->param, sizeof(crypto_symc_config_aes_ccm_gcm), + &drv_symc_ctx->param.ccm_config, sizeof(crypto_symc_config_aes_ccm_gcm)); + crypto_chk_return(ret != EOK, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed, ret is 0x%x\n", ret); + } + + crypto_drv_func_exit(); + return ret; +} + +td_s32 drv_cipher_symc_attach(td_handle symc_handle, td_handle keyslot_handle) +{ + td_s32 ret; + td_u32 symc_chn_num = symc_handle; + td_u32 keyslot_chn_num = keyslot_handle; + drv_symc_context_t *drv_symc_ctx = TD_NULL; + + crypto_drv_func_enter(); + ret = inner_symc_drv_handle_chk(symc_handle); + if (ret != TD_SUCCESS) { + return ret; + } + + drv_symc_ctx = &g_drv_symc_ctx_list[symc_chn_num]; + crypto_chk_return(drv_symc_ctx->is_open == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_CTX_CLOSED), "ctx is closed\n"); + crypto_chk_return(drv_symc_ctx->is_create_keyslot == TD_TRUE, SYMC_COMPAT_ERRNO(ERROR_CTX_CLOSED), + "has been create\n"); + + ret = hal_cipher_symc_attach(symc_chn_num, keyslot_chn_num); + if (ret != TD_SUCCESS) { + crypto_log_err("hal_cipher_symc_attach failed, ret is 0x%x\n", ret); + return ret; + } + + drv_symc_ctx->keyslot_handle = keyslot_handle; + drv_symc_ctx->is_attached = TD_TRUE; + + crypto_drv_func_exit(); + return ret; +} + +static td_s32 inner_drv_cipher_symc_normal_process(td_u32 chn_num, td_phys_addr_t src_phys_addr, + td_phys_addr_t dst_phys_addr, td_u32 length) +{ + td_s32 ret; + in_node_type_e node_type = IN_NODE_TYPE_FIRST | IN_NODE_TYPE_LAST; + +#if defined(CRYPTO_NORMAL_TRACE_ENABLE) + crypto_dump_phys_addr("normal_process_in_buf", src_phys_addr, length); +#endif + ret = hal_cipher_symc_add_in_node(chn_num, src_phys_addr, length, node_type); + if (ret != TD_SUCCESS) { + crypto_log_err("hal_cipher_symc_add_in_node failed, ret is 0x%x\n", ret); + return ret; + } + + ret = hal_cipher_symc_add_out_node(chn_num, dst_phys_addr, length); + if (ret != TD_SUCCESS) { + crypto_log_err("hal_cipher_symc_add_out_node failed, ret is 0x%x\n", ret); + return ret; + } + + return ret; +} + +static td_s32 inner_symc_ccm_process_N(td_u8 *N, td_u32 N_len, const drv_symc_context_t *drv_symc_ctx, td_u32 length) +{ + td_s32 ret; + td_u32 ccm_n_node_type = 0; + const crypto_symc_config_aes_ccm_gcm *ccm_config = &drv_symc_ctx->param.ccm_config; + td_u32 data_len = ccm_config->data_len; + td_u32 chn_num = drv_symc_ctx->chn_num; + td_u32 idx = 0; + td_u32 q; + + /* CCM ADD N. */ + (td_void)memset_s(N, N_len, 0, N_len); + /* First byte of N. */ + N[idx] = (ccm_config->aad_len > 0 ? 1 : 0) << CRYPTO_BIT_6; + N[idx] |= ((ccm_config->tag_len - 2) / 2) << CRYPTO_BIT_3; /* 2: ccm require */ + N[idx] |= (CRYPTO_AES_BLOCK_SIZE_IN_BYTES - 1 - drv_symc_ctx->iv_length); + idx++; + /* copy ccm_iv[1..] to N[1..] */ + ret = memcpy_s(&N[idx], N_len - idx, &(drv_symc_ctx->iv[1]), drv_symc_ctx->iv_length - 1); + crypto_chk_return(ret != EOK, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + idx += drv_symc_ctx->iv_length - 1; + + q = N_len - idx; + if (q >= CRYPTO_SYMC_CCM_Q_LEN_4B) { + idx = CRYPTO_AES_BLOCK_SIZE_IN_BYTES - CRYPTO_SYMC_CCM_Q_LEN_4B; + N[idx++] = (td_u8)(data_len >> 24); /* 24: bits 31-24 */ + N[idx++] = (td_u8)(data_len >> 16); /* 16: bits 23-16 */ + N[idx++] = (td_u8)(data_len >> 8); /* 8: bits 15-8 */ + N[idx++] = (td_u8)(data_len); + } else if (q == CRYPTO_SYMC_CCM_Q_LEN_3B) { + N[idx++] = (td_u8)(data_len >> 16); /* 16: bits 23-16 */ + N[idx++] = (td_u8)(data_len >> 8); /* 8: bits 15-8 */ + N[idx++] = (td_u8)(data_len); + } else if (q == CRYPTO_SYMC_CCM_Q_LEN_2B) { + N[idx++] = (td_u8)(data_len >> 8); /* 8: bits 15-8 */ + N[idx++] = (td_u8)(data_len); + } else { + crypto_log_err("Invalid iv_len\n"); + return SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM); + } + + ccm_n_node_type = IN_NODE_TYPE_CCM_N | IN_NODE_TYPE_FIRST | IN_NODE_TYPE_LAST; + if ((length == 0) && (ccm_config->aad_len == 0)) { + ccm_n_node_type |= IN_NODE_TYPE_CCM_LAST; + } + +#ifdef CRYPTO_CCM_TRACE_ENABLE + crypto_dump_data("N", N, N_len); +#endif + ret = hal_cipher_symc_add_in_node(chn_num, crypto_get_phys_addr(N), N_len, ccm_n_node_type); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_add_in_node failed\n"); + + return ret; +} + +#define AAD_BUF_SIZE (4096) +static td_s32 inner_symc_ccm_process_aad(const drv_symc_context_t *drv_symc_ctx, td_u32 length) +{ + td_s32 ret = TD_SUCCESS; + td_u32 chn_num = drv_symc_ctx->chn_num; + td_u32 ccm_header_len = CRYPTO_AES_BLOCK_SIZE_IN_BYTES; + td_u32 aad_len = drv_symc_ctx->aad_len; + td_u8 *buffer = TD_NULL; + td_u32 buffer_length = AAD_BUF_SIZE; + in_node_type_e node_type = IN_NODE_TYPE_CCM_AAD | IN_NODE_TYPE_FIRST | IN_NODE_TYPE_LAST; + td_u32 left = 0; + td_u32 processed_length = 0; + td_u32 processing_length = 0; + + if (aad_len == 0) { + return TD_SUCCESS; + } + + buffer = crypto_malloc_coherent(buffer_length, "cipher_aad_body"); + crypto_chk_return(buffer == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc_coherent failed\n"); + + (td_void)memset_s(buffer, buffer_length, 0, buffer_length); + + /* AAD Header. */ + inner_format_ccm_header(aad_len, buffer, &ccm_header_len); + ret = memcpy_s(buffer + ccm_header_len, buffer_length - ccm_header_len, drv_symc_ctx->aad_virt, + crypto_min(aad_len, buffer_length - ccm_header_len)); + crypto_chk_goto_with_ret(ret != EOK, exit_free, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + left = ccm_header_len + aad_len; + left = crypto_align(left, CRYPTO_AES_BLOCK_SIZE_IN_BYTES); + processing_length = crypto_min(left, buffer_length); + + ret = hal_cipher_symc_add_in_node(chn_num, crypto_get_phys_addr(buffer), processing_length, node_type); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "hal_cipher_symc_add_in_node failed\n"); + + left -= processing_length; + processed_length += (processing_length - ccm_header_len); + + while (left > 0) { + processing_length = crypto_min(left, buffer_length); + ret = memcpy_s(buffer, buffer_length, drv_symc_ctx->aad_virt + processed_length, + crypto_min(processing_length, aad_len - processed_length)); + crypto_chk_goto_with_ret(ret != EOK, exit_free, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + ret = hal_cipher_symc_add_in_node(chn_num, crypto_get_phys_addr(buffer), processing_length, node_type); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "hal_cipher_symc_add_in_node failed\n"); + + left -= processing_length; + processed_length += processing_length; + + (td_void)memset_s(buffer, buffer_length, 0, buffer_length); + } + +exit_free: + (td_void)memset_s(buffer, buffer_length, 0, buffer_length); + crypto_free_coherent(buffer); + return ret; +} + +static td_s32 inner_drv_cipher_symc_ccm_process(drv_symc_context_t *symc_ctx, td_phys_addr_t src_phys_addr, + td_phys_addr_t dst_phys_addr, td_u32 length) +{ + td_s32 ret; + td_u32 chn_num = symc_ctx->chn_num; + td_u32 ccm_p_node_type = 0; + td_u8 *N = symc_ctx->dma_addr; + td_u32 N_len = CRYPTO_AES_BLOCK_SIZE_IN_BYTES; + + crypto_chk_return(symc_ctx->dma_addr == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_UNEXPECTED), "unexpected error\n"); + + if (symc_ctx->iv_change_flag == CRYPTO_SYMC_CCM_IV_CHANGE_START) { + /* CCM ADD N. */ + crypto_log_dbg("ccm start process aad N\n"); + ret = inner_symc_ccm_process_N(N, N_len, symc_ctx, length); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_symc_ccm_process_N failed\n"); + + /* CCM ADD AAD. */ + crypto_log_dbg("ccm start process aad, length is %d\n", symc_ctx->aad_len); + ret = inner_symc_ccm_process_aad(symc_ctx, length); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_symc_ccm_process_aad failed\n"); + + symc_ctx->iv_change_flag = CRYPTO_SYMC_CCM_IV_CHANGE_UPDATE; + } + + /* CCM ADD P. */ + if (length != 0) { + crypto_log_dbg("ccm start process P\n"); + ccm_p_node_type = IN_NODE_TYPE_CCM_P | IN_NODE_TYPE_FIRST | IN_NODE_TYPE_LAST; + if (symc_ctx->processed_len + length == symc_ctx->data_len) { + ccm_p_node_type |= IN_NODE_TYPE_CCM_LAST; + } + ret = hal_cipher_symc_add_in_node(chn_num, src_phys_addr, length, ccm_p_node_type); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_add_in_node failed\n"); + + ret = hal_cipher_symc_add_out_node(chn_num, dst_phys_addr, length); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_add_out_node failed, ret is 0x%x\n", ret); + } + symc_ctx->processed_len += length; + return ret; +} + +static td_s32 inner_drv_symc_gcm_process_aad(td_u8 *aad_padding, td_u32 aad_padding_len, + const drv_symc_context_t *drv_symc_ctx) +{ + td_s32 ret = TD_SUCCESS; + td_u32 chn_num = drv_symc_ctx->chn_num; + td_u32 gcm_a_node_type = 0; + const crypto_symc_config_aes_ccm_gcm *gcm_config = &drv_symc_ctx->param.ccm_config; + + /* GCM ADD AAD. */ + if (gcm_config->aad_len != 0) { + aad_padding_len = CRYPTO_AES_BLOCK_SIZE_IN_BYTES - gcm_config->aad_len % CRYPTO_AES_BLOCK_SIZE_IN_BYTES; + gcm_a_node_type = IN_NODE_TYPE_GCM_A | IN_NODE_TYPE_FIRST | IN_NODE_TYPE_GCM_FIRST; + if (aad_padding_len == CRYPTO_AES_BLOCK_SIZE_IN_BYTES) { + gcm_a_node_type |= IN_NODE_TYPE_LAST; + } +#if defined(CRYPTO_GCM_TRACE_ENABLE) + crypto_dump_phys_addr("ccm aad", drv_symc_ctx->aad_phys, drv_symc_ctx->aad_len); +#endif + ret = hal_cipher_symc_add_in_node(chn_num, drv_symc_ctx->aad_phys, drv_symc_ctx->aad_len, + gcm_a_node_type); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_add_in_node failed, ret is 0x%x\n", ret); + + if (aad_padding_len != CRYPTO_AES_BLOCK_SIZE_IN_BYTES) { + /* padding must be zeros. */ + (td_void)memset_s(aad_padding, aad_padding_len, 0, aad_padding_len); +#if defined(CRYPTO_GCM_TRACE_ENABLE) + crypto_dump_data("ccm aad_padding", aad_padding, aad_padding_len); +#endif + ret = hal_cipher_symc_add_in_node(chn_num, crypto_get_phys_addr(aad_padding), + aad_padding_len, IN_NODE_TYPE_GCM_A | IN_NODE_TYPE_LAST); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_add_in_node failed, ret is 0x%x\n", ret); + } + } + return ret; +} + +static td_s32 inner_drv_symc_gcm_process_P(drv_symc_context_t *drv_symc_ctx, + td_phys_addr_t src_phys_addr, td_phys_addr_t dst_phys_addr, td_u32 length) +{ + td_s32 ret = TD_SUCCESS; + td_u32 gcm_p_node_type = 0; + td_u32 chn_num = drv_symc_ctx->chn_num; + const crypto_symc_config_aes_ccm_gcm *gcm_config = &drv_symc_ctx->param.ccm_config; + + /* GCM ADD P. */ + if (length != 0) { + gcm_p_node_type = IN_NODE_TYPE_GCM_P | IN_NODE_TYPE_FIRST | IN_NODE_TYPE_LAST; + if (gcm_config->aad_len == 0) { + gcm_p_node_type |= IN_NODE_TYPE_GCM_FIRST; + } + ret = hal_cipher_symc_add_in_node(chn_num, src_phys_addr, length, gcm_p_node_type); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_add_in_node failed, ret is 0x%x\n", ret); + + ret = hal_cipher_symc_add_out_node(chn_num, dst_phys_addr, length); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_add_out_node failed, ret is 0x%x\n", ret); + } + drv_symc_ctx->processed_len += length; + return ret; +} + +static td_s32 inner_drv_symc_gcm_process_clen(td_u8 *clen_buf, td_u32 clen_buf_len, + const drv_symc_context_t *drv_symc_ctx, td_u32 length) +{ + td_s32 ret = TD_SUCCESS; + td_u32 aad_len_in_bit = 0; + td_u32 data_len_in_bit = 0; + td_u32 gcm_len_node_type = 0; + const crypto_symc_config_aes_ccm_gcm *gcm_config = &drv_symc_ctx->param.ccm_config; + + /* GCM ADD LEN. */ + aad_len_in_bit = crypto_cpu_to_be32(gcm_config->aad_len * CRYPTO_BITS_IN_BYTE); + data_len_in_bit = crypto_cpu_to_be32(length * CRYPTO_BITS_IN_BYTE); + (td_void)memset_s(clen_buf, clen_buf_len, 0x00, clen_buf_len); + (td_void)memcpy_s(clen_buf + 8 - sizeof(td_u32), /* 8: bit15~8 for aad_len. */ + sizeof(td_u32), &aad_len_in_bit, sizeof(td_u32)); + (td_void)memcpy_s(clen_buf + 16 - sizeof(td_u32), sizeof(td_u32), /* 16: bit7~0 for data_len. */ + &data_len_in_bit, sizeof(td_u32)); + + gcm_len_node_type = IN_NODE_TYPE_GCM_LEN | IN_NODE_TYPE_FIRST | IN_NODE_TYPE_LAST; + if (gcm_config->aad_len == 0 && length == 0) { + gcm_len_node_type |= IN_NODE_TYPE_GCM_FIRST; + } +#if defined(CRYPTO_GCM_TRACE_ENABLE) + crypto_dump_data("gcm_clen_buf", clen_buf, clen_buf_len); +#endif + ret = hal_cipher_symc_add_in_node(drv_symc_ctx->chn_num, crypto_get_phys_addr(clen_buf), + clen_buf_len, gcm_len_node_type); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_add_in_node failed, ret is 0x%x\n", ret); + + return ret; +} + +static td_s32 inner_drv_cipher_symc_gcm_process(drv_symc_context_t *drv_symc_ctx, td_phys_addr_t src_phys_addr, + td_phys_addr_t dst_phys_addr, td_u32 length) +{ + td_s32 ret; + td_u8 *aad_padding = drv_symc_ctx->dma_addr; + td_u32 aad_padding_len = CRYPTO_AES_BLOCK_SIZE_IN_BYTES; + + crypto_chk_return(drv_symc_ctx->dma_addr == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_UNEXPECTED), "unexpected error\n"); + if (drv_symc_ctx->processed_len == 0) { + /* GCM ADD AAD. */ + crypto_log_dbg("gcm start process aad\n"); + ret = inner_drv_symc_gcm_process_aad(aad_padding, aad_padding_len, drv_symc_ctx); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_drv_symc_gcm_process_aad failed, ret is 0x%x\n", ret); + } + /* GCM ADD P. */ + crypto_log_dbg("gcm start process p\n"); + ret = inner_drv_symc_gcm_process_P(drv_symc_ctx, src_phys_addr, dst_phys_addr, length); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_drv_symc_gcm_process_P failed, ret is 0x%x\n", ret); + + return ret; +} + +static td_s32 inner_drv_cipher_wait_func(td_u32 chn_num, drv_symc_context_t *symc_ctx) +{ + td_s32 ret; + + ret = hal_cipher_symc_start(chn_num); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_start failed\n"); + + ret = hal_cipher_symc_wait_done(chn_num, TD_TRUE); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_wait_done failed\n"); + + ret = hal_cipher_symc_get_iv(chn_num, symc_ctx->iv, sizeof(symc_ctx->iv)); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_get_iv failed\n"); + + return ret; +} + +#if defined(CRYPTO_CTR_NON_ALIGN_SUPPORT) +td_s32 inner_drv_symc_set_ctr_block(td_handle symc_handle, const td_u8 *block, td_u32 block_size, td_u32 ctr_offset) +{ + td_s32 ret; + drv_symc_context_t *symc_ctx = TD_NULL; + + ret = inner_symc_drv_handle_chk(symc_handle); + if (ret != TD_SUCCESS) { + return ret; + } + + symc_null_ptr_chk(block); + crypto_chk_return(block_size != CRYPTO_AES_BLOCK_SIZE_IN_BYTES, SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "block_size is invalid\n"); + + symc_ctx = &g_drv_symc_ctx_list[symc_handle]; + + ret = memcpy_s(symc_ctx->ctr_last_block, sizeof(symc_ctx->ctr_last_block), block, block_size); + crypto_chk_return(ret != EOK, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + symc_ctx->ctr_offset = ctr_offset; + return TD_SUCCESS; +} + +td_s32 inner_drv_symc_get_ctr_block(td_handle symc_handle, td_u8 *block, td_u32 block_size, td_u32 *ctr_offset) +{ + td_s32 ret; + drv_symc_context_t *symc_ctx = TD_NULL; + + ret = inner_symc_drv_handle_chk(symc_handle); + if (ret != TD_SUCCESS) { + return ret; + } + + symc_null_ptr_chk(block); + symc_null_ptr_chk(ctr_offset); + crypto_chk_return(block_size != CRYPTO_AES_BLOCK_SIZE_IN_BYTES, SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "block_size is invalid\n"); + + symc_ctx = &g_drv_symc_ctx_list[symc_handle]; + + ret = memcpy_s(block, block_size, symc_ctx->ctr_last_block, sizeof(symc_ctx->ctr_last_block)); + crypto_chk_return(ret != EOK, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + *ctr_offset = symc_ctx->ctr_offset; + return TD_SUCCESS; +} + +static td_s32 inner_drv_cipher_ctr_process_one_zero_block(td_u32 chn_num, drv_symc_context_t *symc_ctx) +{ + td_u32 ret; + td_u8 *zero_block = crypto_malloc_coherent(CRYPTO_AES_BLOCK_SIZE_IN_BYTES, "cipher_ctr_zero"); + crypto_chk_return(zero_block == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc_coherent failed\n"); + + (td_void)memset_s(zero_block, CRYPTO_AES_BLOCK_SIZE_IN_BYTES, 0, CRYPTO_AES_BLOCK_SIZE_IN_BYTES); +#if defined(CRYPTO_CTR_TRACE_ENABLE) + crypto_dump_data("zero_block_before_iv", symc_ctx->iv, sizeof(symc_ctx->iv)); +#endif + ret = hal_cipher_symc_set_iv(chn_num, symc_ctx->iv, sizeof(symc_ctx->iv)); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "hal_cipher_symc_set_iv failed\n"); + + ret = hal_cipher_symc_add_in_node(chn_num, crypto_get_phys_addr(zero_block), + CRYPTO_AES_BLOCK_SIZE_IN_BYTES, IN_NODE_TYPE_FIRST | IN_NODE_TYPE_LAST); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "hal_cipher_symc_add_in_node failed\n"); + + ret = hal_cipher_symc_add_out_node(chn_num, crypto_get_phys_addr(zero_block), CRYPTO_AES_BLOCK_SIZE_IN_BYTES); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "hal_cipher_symc_add_in_node failed\n"); + + ret = inner_drv_cipher_wait_func(chn_num, symc_ctx); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "inner_drv_cipher_wait_func failed\n"); + + ret = memcpy_s(symc_ctx->ctr_last_block, sizeof(symc_ctx->ctr_last_block), + zero_block, CRYPTO_AES_BLOCK_SIZE_IN_BYTES); + crypto_chk_goto_with_ret(ret != EOK, exit_free, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); +#if defined(CRYPTO_CTR_TRACE_ENABLE) + crypto_dump_data("zero_block_after_iv", symc_ctx->iv, sizeof(symc_ctx->iv)); + crypto_dump_data("zero_block_after", zero_block, CRYPTO_AES_BLOCK_SIZE_IN_BYTES); +#endif +exit_free: + crypto_free_coherent(zero_block); + return ret; +} +#endif + +static td_s32 inner_drv_cipher_symc_crypto_for_ctr(td_u32 chn_num, drv_symc_context_t *symc_ctx, + td_phys_addr_t src_phys_addr, td_phys_addr_t dst_phys_addr, td_u32 length) +{ + td_s32 ret; + td_u32 processing_length = length; +#if defined(CRYPTO_CTR_NON_ALIGN_SUPPORT) + if (symc_ctx->ctr_offset != 0) { + symc_ctx->ctr_used = crypto_min(CRYPTO_AES_BLOCK_SIZE_IN_BYTES - symc_ctx->ctr_offset, length); + ret = crypto_virt_xor_phys_copy_to_phys(dst_phys_addr, symc_ctx->ctr_last_block + symc_ctx->ctr_offset, + src_phys_addr, symc_ctx->ctr_used); + crypto_chk_return(ret != TD_SUCCESS, ret, "crypto_virt_xor_copy_to_phys failed\n"); + src_phys_addr += symc_ctx->ctr_used; + dst_phys_addr += symc_ctx->ctr_used; + crypto_log_dbg("ctr skip %d bytes\n", symc_ctx->ctr_used); + if (length == symc_ctx->ctr_used) { + symc_ctx->ctr_offset = (symc_ctx->ctr_offset + symc_ctx->ctr_used) % CRYPTO_AES_BLOCK_SIZE_IN_BYTES; + return TD_SUCCESS; + } + processing_length -= symc_ctx->ctr_used; + } + + symc_ctx->ctr_offset = processing_length % CRYPTO_AES_BLOCK_SIZE_IN_BYTES; + processing_length -= symc_ctx->ctr_offset; +#endif + ret = hal_cipher_symc_set_iv(chn_num, symc_ctx->iv, sizeof(symc_ctx->iv)); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_set_iv failed\n"); + + if (processing_length != 0) { + ret = inner_drv_cipher_symc_normal_process(chn_num, src_phys_addr, dst_phys_addr, processing_length); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_drv_cipher_symc_normal_process failed\n"); + + ret = inner_drv_cipher_wait_func(chn_num, symc_ctx); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_drv_cipher_wait_func failed\n"); + } + +#if defined(CRYPTO_CTR_NON_ALIGN_SUPPORT) + if (symc_ctx->ctr_offset != 0) { + ret = inner_drv_cipher_ctr_process_one_zero_block(chn_num, symc_ctx); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_drv_cipher_ctr_process_one_zero_block failed\n"); + + crypto_log_dbg("ctr xor %d bytes, processing_length is %d, ctr_used is %d\n", + symc_ctx->ctr_offset, processing_length, symc_ctx->ctr_used); + ret = crypto_virt_xor_phys_copy_to_phys(dst_phys_addr + processing_length, + symc_ctx->ctr_last_block, src_phys_addr + processing_length, symc_ctx->ctr_offset); + crypto_chk_return(ret != TD_SUCCESS, ret, "crypto_virt_xor_copy_to_phys failed\n"); + } +#endif + return ret; +} + +static td_s32 inner_drv_cipher_symc_crypto_for_others(td_u32 chn_num, drv_symc_context_t *symc_ctx, + td_phys_addr_t src_phys_addr, td_phys_addr_t dst_phys_addr, td_u32 length) +{ + td_s32 ret; + if (symc_ctx->work_mode == CRYPTO_SYMC_WORK_MODE_CCM) { + ret = inner_drv_cipher_symc_ccm_process(symc_ctx, src_phys_addr, dst_phys_addr, length); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_drv_cipher_symc_ccm_process failed\n"); + } else if (symc_ctx->work_mode == CRYPTO_SYMC_WORK_MODE_GCM) { + ret = inner_drv_cipher_symc_gcm_process(symc_ctx, src_phys_addr, dst_phys_addr, length); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_drv_cipher_symc_gcm_process failed\n"); + } else { + ret = hal_cipher_symc_set_iv(chn_num, symc_ctx->iv, sizeof(symc_ctx->iv)); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_set_iv failed\n"); + + ret = inner_drv_cipher_symc_normal_process(chn_num, src_phys_addr, dst_phys_addr, length); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_drv_cipher_symc_normal_process failed\n"); + } + + ret = inner_drv_cipher_wait_func(chn_num, symc_ctx); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_drv_cipher_wait_func failed\n"); + + return ret; +} + +#if defined(CRYPTO_SYMC_ADDR_NOT_ALIGN_SUPPORT) +#define SYMC_BUFFER_SIZE 4096 +static td_s32 inner_drv_cipher_symc_crypto_process_unalign_addr(td_u32 chn_num, drv_symc_context_t *symc_ctx, + const crypto_buf_attr *src_buf, const crypto_buf_attr *dst_buf, td_u32 length) +{ + td_s32 ret; + td_u32 left = length; + td_u32 processed_length = 0; + td_u32 processing_length = 0; + td_u8 *buffer = TD_NULL; + td_phys_addr_t buffer_phys_addr = 0; + + buffer = crypto_malloc_coherent(SYMC_BUFFER_SIZE, "cipher_unalign"); + crypto_chk_return(buffer == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc_coherent failed\n"); + + buffer_phys_addr = crypto_get_phys_addr(buffer); + while (left > 0) { + processing_length = crypto_min(left, SYMC_BUFFER_SIZE); + crypto_log_dbg("left is %d, processing_length is %d, processed_length is %d\n", + left, processing_length, processed_length); + ret = crypto_phys_copy_to_virt(buffer, src_buf->phys_addr + processed_length, processing_length); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "crypto_phys_copy_to_virt failed\n"); + + if (symc_ctx->work_mode == CRYPTO_SYMC_WORK_MODE_CTR) { + ret = inner_drv_cipher_symc_crypto_for_ctr(chn_num, symc_ctx, buffer_phys_addr, + buffer_phys_addr, processing_length); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "inner_drv_cipher_symc_crypto_for_ctr failed\n"); + } else { + ret = inner_drv_cipher_symc_crypto_for_others(chn_num, symc_ctx, + buffer_phys_addr, buffer_phys_addr, processing_length); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "inner_drv_cipher_symc_crypto_for_others failed\n"); + } + ret = crypto_virt_copy_to_phys(dst_buf->phys_addr + processed_length, buffer, processing_length); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "crypto_phys_copy_to_virt failed\n"); + + left -= processing_length; + processed_length += processing_length; + } + +exit_free: + (td_void)memset_s(buffer, SYMC_BUFFER_SIZE, 0, SYMC_BUFFER_SIZE); + crypto_free_coherent(buffer); + return ret; +} +#endif + +static td_s32 inner_drv_cipher_symc_crypto(td_handle symc_handle, const crypto_buf_attr *src_buf, + const crypto_buf_attr *dst_buf, td_u32 length, td_bool is_decrypt) +{ + td_s32 ret; + hal_symc_config_t hal_symc_config = {0}; + drv_symc_context_t *symc_ctx = TD_NULL; + td_u32 chn_num = (td_u32)symc_handle; + + crypto_drv_func_enter(); + + ret = inner_drv_symc_crypto_chk(symc_handle, src_buf, dst_buf, length); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_drv_symc_crypto_chk failed\n"); + + symc_ctx = &g_drv_symc_ctx_list[chn_num]; + crypto_chk_return(symc_ctx->is_open == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_CTX_CLOSED), "ctx is closed\n"); + crypto_chk_return(symc_ctx->is_config == TD_FALSE, + SYMC_COMPAT_ERRNO(ERROR_NOT_SET_CONFIG), "call set_config first\n"); + crypto_chk_return(symc_ctx->is_attached == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_NOT_ATTACHED), "call attach first\n"); + + (td_void)hal_cipher_set_chn_secure(chn_num, dst_buf->buf_sec == CRYPTO_BUF_SECURE, + src_buf->buf_sec == CRYPTO_BUF_SECURE); + + ret = hal_cipher_symc_get_config(chn_num, &hal_symc_config); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_get_config failed\n"); + + hal_symc_config.is_decrypt = is_decrypt; + ret = hal_cipher_symc_config(chn_num, &hal_symc_config); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_config failed\n"); + + if ((crypto_addr_align_check(src_buf->phys_addr) == TD_TRUE) && + (crypto_addr_align_check(dst_buf->phys_addr) == TD_TRUE)) { + if (symc_ctx->work_mode == CRYPTO_SYMC_WORK_MODE_CTR) { + ret = inner_drv_cipher_symc_crypto_for_ctr(chn_num, symc_ctx, src_buf->phys_addr, + dst_buf->phys_addr, length); + } else { + ret = inner_drv_cipher_symc_crypto_for_others(chn_num, symc_ctx, + src_buf->phys_addr, dst_buf->phys_addr, length); + } + } else { +#if defined(CRYPTO_SYMC_ADDR_NOT_ALIGN_SUPPORT) + ret = inner_drv_cipher_symc_crypto_process_unalign_addr(chn_num, symc_ctx, src_buf, dst_buf, length); +#else + ret = SYMC_COMPAT_ERRNO(ERROR_UNSUPPORT); + crypto_log_err("unsupport unalign address\n"); +#endif + } + + crypto_drv_func_exit(); + return ret; +} + +td_s32 drv_cipher_symc_encrypt(td_handle symc_handle, const crypto_buf_attr *src_buf, const crypto_buf_attr *dst_buf, + td_u32 length) +{ + td_s32 ret; + crypto_drv_func_enter(); + + ret = inner_drv_cipher_symc_crypto(symc_handle, src_buf, dst_buf, length, TD_FALSE); + if (ret != TD_SUCCESS) { + crypto_log_err("inner_drv_cipher_symc_crypto failed, ret is 0x%x\n", ret); + return ret; + } + + crypto_drv_func_exit(); + return ret; +} + +td_s32 drv_cipher_symc_decrypt(td_handle symc_handle, const crypto_buf_attr *src_buf, const crypto_buf_attr *dst_buf, + td_u32 length) +{ + td_s32 ret; + crypto_drv_func_enter(); + + ret = inner_drv_cipher_symc_crypto(symc_handle, src_buf, dst_buf, length, TD_TRUE); + if (ret != TD_SUCCESS) { + crypto_log_err("inner_drv_cipher_symc_crypto failed, ret is 0x%x\n", ret); + return ret; + } + + crypto_drv_func_exit(); + return ret; +} + +static td_s32 priv_drv_symc_add_node(td_u32 chn_num, const crypto_buf_attr *src_buf, + const crypto_buf_attr *dst_buf, td_u32 length, in_node_type_e node_type) +{ + td_s32 ret; + + ret = hal_cipher_symc_add_in_node(chn_num, src_buf->phys_addr, length, node_type); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_add_in_node failed, ret is 0x%x\n", ret); + + ret = hal_cipher_symc_add_out_node(chn_num, dst_buf->phys_addr, length); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_add_out_node failed, ret is 0x%x\n", ret); + + return ret; +} + +static td_s32 priv_drv_symc_crypto_multi(td_handle symc_handle, const crypto_symc_ctrl_t *symc_ctrl, + const crypto_symc_pack *src_buf_pack, const crypto_symc_pack *dst_buf_pack, td_u32 pack_num, td_u32 crypto_type) +{ + td_s32 ret; + td_u32 i; + hal_symc_config_t hal_symc_config = {0}; + td_u32 chn_num = symc_handle; + in_node_type_e node_type = IN_NODE_TYPE_NORMAL; + drv_symc_context_t *symc_ctx = TD_NULL; + + crypto_drv_func_enter(); + + symc_null_ptr_chk(symc_ctrl); + symc_null_ptr_chk(src_buf_pack); + symc_null_ptr_chk(dst_buf_pack); + + ret = inner_symc_drv_handle_chk(symc_handle); + if (ret != TD_SUCCESS) { + return ret; + } + + symc_ctx = &g_drv_symc_ctx_list[chn_num]; + crypto_chk_return(symc_ctx->is_open == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_CTX_CLOSED), "ctx is closed\n"); + + hal_symc_config.symc_alg = symc_ctrl->symc_alg; + hal_symc_config.work_mode = symc_ctrl->work_mode; + hal_symc_config.symc_bit_width = symc_ctrl->symc_bit_width; + hal_symc_config.symc_key_length = symc_ctrl->symc_key_length; + hal_symc_config.is_decrypt = (crypto_type == CRYPTO_TYPE_ENCRYPT) ? TD_FALSE : TD_TRUE; + + ret = hal_cipher_symc_config(chn_num, &hal_symc_config); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_config failed, ret is 0x%x\n", ret); + + if (symc_ctrl->iv_change_flag == CRYPTO_SYMC_IV_CHANGE_ONE_PKG) { + for (i = 0; i < pack_num; i++, node_type = IN_NODE_TYPE_NORMAL) { + ret = hal_cipher_symc_set_iv(chn_num, symc_ctrl->iv, symc_ctrl->iv_length); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_set_iv failed, ret is 0x%x\n", ret); + node_type = IN_NODE_TYPE_FIRST | IN_NODE_TYPE_LAST; + + ret = priv_drv_symc_add_node(chn_num, &src_buf_pack[i].buf_attr, &dst_buf_pack[i].buf_attr, + src_buf_pack[i].length, node_type); + crypto_chk_return(ret != TD_SUCCESS, ret, "priv_drv_symc_add_node failed, ret is 0x%x\n", ret); + + ret = hal_cipher_symc_start(chn_num); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_start failed, ret is 0x%x\n", ret); + + ret = hal_cipher_symc_wait_done(chn_num, TD_TRUE); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_wait_done failed, ret is 0x%x\n", ret); + ret = hal_cipher_symc_get_iv(chn_num, (td_u8 *)symc_ctrl->iv, symc_ctrl->iv_length); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_get_iv failed, ret is 0x%x\n", ret); + } + } else if (symc_ctrl->iv_change_flag == CRYPTO_SYMC_IV_CHANGE_ALL_PKG) { + for (i = 0; i < pack_num; i++) { + ret = hal_cipher_symc_set_iv(chn_num, symc_ctrl->iv, symc_ctrl->iv_length); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_set_iv failed, ret is 0x%x\n", ret); + + ret = priv_drv_symc_add_node(chn_num, &src_buf_pack[i].buf_attr, &dst_buf_pack[i].buf_attr, + src_buf_pack[i].length, IN_NODE_TYPE_FIRST | IN_NODE_TYPE_LAST); + crypto_chk_return(ret != TD_SUCCESS, ret, "priv_drv_symc_add_node failed, ret is 0x%x\n", ret); + + ret = hal_cipher_symc_start(chn_num); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_start failed, ret is 0x%x\n", ret); + + ret = hal_cipher_symc_wait_done(chn_num, TD_TRUE); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_wait_done failed, ret is 0x%x\n", ret); + } + } else { + crypto_log_err("Invalid iv_change_flag!\n"); + return TD_FAILURE; + } + + crypto_drv_func_exit(); + return ret; +} + +td_s32 drv_cipher_symc_encrypt_multi(td_handle symc_handle, const crypto_symc_ctrl_t *symc_ctrl, + const crypto_symc_pack *src_buf_pack, const crypto_symc_pack *dst_buf_pack, td_u32 pack_num) +{ + td_s32 ret; + crypto_drv_func_enter(); + + ret = priv_drv_symc_crypto_multi(symc_handle, symc_ctrl, src_buf_pack, dst_buf_pack, pack_num, CRYPTO_TYPE_ENCRYPT); + crypto_chk_return(ret != TD_SUCCESS, ret, "priv_drv_symc_crypto_multi for Encrypt failed\n"); + + crypto_drv_func_exit(); + return ret; +} + +td_s32 drv_cipher_symc_decrypt_multi(td_handle symc_handle, const crypto_symc_ctrl_t *symc_ctrl, + const crypto_symc_pack *src_buf_pack, const crypto_symc_pack *dst_buf_pack, td_u32 pack_num) +{ + td_s32 ret; + crypto_drv_func_enter(); + + ret = priv_drv_symc_crypto_multi(symc_handle, symc_ctrl, src_buf_pack, dst_buf_pack, pack_num, CRYPTO_TYPE_DECRYPT); + crypto_chk_return(ret != TD_SUCCESS, ret, "priv_drv_symc_crypto_multi for Encrypt failed\n"); + + crypto_drv_func_exit(); + return ret; +} + +td_s32 drv_cipher_symc_get_tag(td_handle symc_handle, td_u8 *tag, td_u32 tag_length) +{ + td_s32 ret; + td_u32 chn_num; + td_u8 *clen_buf; + td_u32 clen_buf_len = CRYPTO_AES_BLOCK_SIZE_IN_BYTES; + drv_symc_context_t *symc_ctx = TD_NULL; + crypto_drv_func_enter(); + ret = inner_symc_drv_handle_chk(symc_handle); + if (ret != TD_SUCCESS) { + return ret; + } + symc_null_ptr_chk(tag); + crypto_chk_return(tag_length == 0 || tag_length > CRYPTO_AES_MAX_TAG_SIZE, + SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM), "tag_length is invalid\n"); + chn_num = symc_handle; + symc_ctx = &g_drv_symc_ctx_list[chn_num]; + crypto_chk_return(symc_ctx->is_open == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_CTX_CLOSED), "ctx is closed\n"); + crypto_chk_return(symc_ctx->is_config == TD_FALSE, + SYMC_COMPAT_ERRNO(ERROR_NOT_SET_CONFIG), "call set_config first\n"); + crypto_chk_return(symc_ctx->is_attached == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_NOT_ATTACHED), "call attach first\n"); + + /* if work mode equals GCM, process clen. */ + if (symc_ctx->work_mode == CRYPTO_SYMC_WORK_MODE_GCM) { + crypto_log_dbg("gcm start process clen\n"); + clen_buf = symc_ctx->dma_addr + CRYPTO_AES_BLOCK_SIZE_IN_BYTES; + ret = inner_drv_symc_gcm_process_clen(clen_buf, clen_buf_len, symc_ctx, symc_ctx->processed_len); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_drv_symc_gcm_process_clen failed, ret is 0x%x\n", ret); + } + + ret = hal_cipher_symc_get_tag(chn_num, tag, tag_length); + if (ret != TD_SUCCESS) { + crypto_log_err("hal_cipher_symc_get_tag failed, ret is 0x%x\n", ret); + return ret; + } + + crypto_drv_func_exit(); + return ret; +} + +td_s32 inner_drv_get_mac_ctx(td_handle symc_handle, crypto_symc_mac_ctx *mac_ctx) +{ + td_s32 ret; + drv_symc_context_t *symc_ctx = TD_NULL; + + symc_null_ptr_chk(mac_ctx); + symc_ctx = inner_get_symc_ctx(symc_handle); + crypto_chk_return(symc_ctx == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_INVALID_HANDLE), "symc_handle is invalid\n"); + crypto_chk_return(symc_ctx->is_open == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_CTX_CLOSED), "ctx is closed\n"); + + ret = memcpy_s(mac_ctx->tail, sizeof(mac_ctx->tail), symc_ctx->tail, symc_ctx->tail_length); + crypto_chk_return(ret != EOK, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + mac_ctx->tail_length = symc_ctx->tail_length; + + ret = memcpy_s(mac_ctx->mac, sizeof(mac_ctx->mac), symc_ctx->iv, sizeof(symc_ctx->iv)); + crypto_chk_return(ret != EOK, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + return ret; +} + +td_s32 inner_drv_set_mac_ctx(td_handle symc_handle, const crypto_symc_mac_ctx *mac_ctx) +{ + td_s32 ret; + drv_symc_context_t *symc_ctx = TD_NULL; + + symc_null_ptr_chk(mac_ctx); + symc_ctx = inner_get_symc_ctx(symc_handle); + crypto_chk_return(symc_ctx == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_INVALID_HANDLE), "symc_handle is invalid\n"); + crypto_chk_return(symc_ctx->is_open == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_CTX_CLOSED), "ctx is closed\n"); + + ret = memcpy_s(symc_ctx->tail, sizeof(symc_ctx->tail), mac_ctx->tail, mac_ctx->tail_length); + crypto_chk_return(ret != EOK, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + symc_ctx->tail_length = mac_ctx->tail_length; + + ret = memcpy_s(symc_ctx->iv, sizeof(symc_ctx->iv), mac_ctx->mac, sizeof(mac_ctx->mac)); + crypto_chk_return(ret != EOK, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + return ret; +} + +td_s32 inner_drv_symc_crypto_chk(td_handle symc_handle, const crypto_buf_attr *src_buf, + const crypto_buf_attr *dst_buf, td_u32 length) +{ + td_s32 ret; + drv_symc_context_t *symc_ctx = TD_NULL; + crypto_symc_work_mode mode; + + ret = inner_symc_drv_handle_chk(symc_handle); + if (ret != TD_SUCCESS) { + return ret; + } + symc_ctx = &g_drv_symc_ctx_list[symc_handle]; + + symc_null_ptr_chk(src_buf); + symc_null_ptr_chk(dst_buf); + crypto_chk_return(src_buf->phys_addr == 0, SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "src_buf's phys_addr is invalid\n"); + crypto_chk_return(dst_buf->phys_addr == 0, SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "dst_buf's phys_addr is invalid\n"); + + crypto_chk_return(length == 0, SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM), "length is zero!\n"); + mode = symc_ctx->work_mode; + if (mode == CRYPTO_SYMC_WORK_MODE_CBC || mode == CRYPTO_SYMC_WORK_MODE_ECB) { + crypto_chk_return((length % CRYPTO_AES_BLOCK_SIZE_IN_BYTES) != 0, SYMC_COMPAT_ERRNO(ERROR_SYMC_LEN_NOT_ALIGNED), + "length must be aligned to 16-Byte\n"); + } + return TD_SUCCESS; +} + +td_s32 inner_drv_symc_ex_restore(td_handle symc_handle, const drv_symc_ex_context_t *symc_ex_ctx) +{ + td_s32 ret; + td_u32 chn_num = symc_handle; + hal_symc_config_t config = {0}; + drv_symc_context_t *symc_ctx = TD_NULL; + + ret = inner_symc_drv_handle_chk(symc_handle); + if (ret != TD_SUCCESS) { + return ret; + } + + symc_null_ptr_chk(symc_ex_ctx); + symc_null_ptr_chk(symc_ex_ctx->iv0); + symc_null_ptr_chk(symc_ex_ctx->iv_mac); + crypto_chk_return(symc_ex_ctx->iv0_length != sizeof(config.iv0), SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "iv0_length is invalid\n"); + crypto_chk_return(symc_ex_ctx->iv_mac_length != sizeof(config.iv_mac), SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "iv_mac_length is invalid\n"); + + symc_ctx = &g_drv_symc_ctx_list[symc_handle]; + + ret = hal_cipher_symc_get_config(chn_num, &config); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_get_config failed\n"); + + ret = memcpy_s(config.iv0, sizeof(config.iv0), symc_ex_ctx->iv0, symc_ex_ctx->iv0_length); + crypto_chk_return(ret != EOK, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + ret = memcpy_s(config.iv_mac, sizeof(config.iv_mac), symc_ex_ctx->iv_mac, symc_ex_ctx->iv_mac_length); + crypto_chk_return(ret != EOK, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + ret = hal_cipher_symc_config(chn_num, &config); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_config failed\n"); + + symc_ctx->param.ccm_config.aad_len = symc_ex_ctx->aad_len; + symc_ctx->data_len = symc_ex_ctx->data_length; + symc_ctx->processed_len = symc_ex_ctx->processed_length; + + return TD_SUCCESS; +} + +td_s32 inner_drv_symc_get_iv0(td_handle symc_handle, td_u8 *iv0, td_u32 iv0_length) +{ + td_s32 ret; + td_u32 chn_num = symc_handle; + hal_symc_config_t config = {0}; + + ret = inner_symc_drv_handle_chk(symc_handle); + if (ret != TD_SUCCESS) { + return ret; + } + + symc_null_ptr_chk(iv0); + crypto_chk_return(iv0_length != sizeof(config.iv0), SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "iv0_length is invalid\n"); + + ret = hal_cipher_symc_get_config(chn_num, &config); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_get_config failed\n"); + + ret = memcpy_s(iv0, iv0_length, config.iv0, sizeof(config.iv0)); + crypto_chk_return(ret != EOK, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + return TD_SUCCESS; +} + +td_s32 inner_drv_symc_get_iv_mac(td_handle symc_handle, td_u8 *iv_mac, td_u32 iv_mac_length) +{ + td_s32 ret; + td_u32 chn_num = symc_handle; + hal_symc_config_t config = {0}; + + ret = inner_symc_drv_handle_chk(symc_handle); + if (ret != TD_SUCCESS) { + return ret; + } + + symc_null_ptr_chk(iv_mac); + crypto_chk_return(iv_mac_length != sizeof(config.iv_mac), SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "iv_mac_length is invalid\n"); + + ret = hal_cipher_symc_get_config(chn_num, &config); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_get_config failed\n"); + + ret = memcpy_s(iv_mac, iv_mac_length, config.iv_mac, sizeof(config.iv_mac)); + crypto_chk_return(ret != EOK, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + return TD_SUCCESS; +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_symc_mac_hard.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_symc_mac_hard.c new file mode 100644 index 00000000..435e51bc --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_symc_mac_hard.c @@ -0,0 +1,291 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "drv_symc.h" +#include "drv_inner.h" + +#include "hal_symc.h" +#include "crypto_drv_common.h" + +#define SYMC_COMPAT_ERRNO(err_code) DRV_COMPAT_ERRNO(ERROR_MODULE_SYMC, err_code) +#define symc_null_ptr_chk(ptr) \ + crypto_chk_return((ptr) == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), #ptr" is NULL\n") + +#define CRYPTO_SYMC_CBC_MAC_BUFFER_LEN (4 * 1024) + +td_s32 drv_cipher_mac_start(td_handle *symc_handle, const crypto_symc_mac_attr *mac_attr) +{ + td_s32 ret; + crypto_symc_attr symc_attr = {0}; + drv_symc_context_t *symc_ctx = TD_NULL; + td_u32 chn_num; + hal_symc_config_t symc_config = {0}; + td_u8 iv_zeros[CRYPTO_IV_LEN_IN_BYTES] = {0}; + crypto_drv_func_enter(); + + symc_null_ptr_chk(symc_handle); + symc_null_ptr_chk(mac_attr); + + crypto_chk_return(mac_attr->symc_alg != CRYPTO_SYMC_ALG_AES, SYMC_COMPAT_ERRNO(ERROR_UNSUPPORT), + "MAC only support AES\n"); + + ret = drv_cipher_symc_create(symc_handle, &symc_attr); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_symc_create failed\n"); + + symc_ctx = inner_get_symc_ctx(*symc_handle); + crypto_chk_goto_with_ret(symc_ctx == TD_NULL, error_symc_destroy, + SYMC_COMPAT_ERRNO(ERROR_INVALID_HANDLE), "symc_handle is invalid\n"); + crypto_chk_goto_with_ret(symc_ctx->is_open == TD_FALSE, error_symc_destroy, + SYMC_COMPAT_ERRNO(ERROR_CTX_CLOSED), "ctx is closed\n"); + + chn_num = *symc_handle; + symc_config.symc_alg = mac_attr->symc_alg; + // For Both CBC_MAC and CMAC, the first work_mdoe is CBC_MAC + symc_config.work_mode = CRYPTO_SYMC_WORK_MODE_CBC_MAC; + symc_config.symc_bit_width = CRYPTO_SYMC_BIT_WIDTH_128BIT; + symc_config.symc_key_length = mac_attr->symc_key_length; + + ret = hal_cipher_symc_config(chn_num, &symc_config); + crypto_chk_goto(ret != TD_SUCCESS, error_symc_destroy, "hal_cipher_symc_config failed\n"); + + ret = hal_cipher_symc_attach(chn_num, mac_attr->keyslot_chn); + crypto_chk_goto(ret != TD_SUCCESS, error_symc_destroy, "hal_cipher_symc_config failed\n"); + + ret = hal_cipher_symc_set_iv(chn_num, iv_zeros, sizeof(iv_zeros)); + crypto_chk_goto(ret != TD_SUCCESS, error_symc_destroy, "hal_cipher_symc_set_iv failed\n"); + + symc_ctx->work_mode = mac_attr->work_mode; + symc_ctx->symc_alg = mac_attr->symc_alg; + symc_ctx->symc_key_length = mac_attr->symc_key_length; + + return ret; +error_symc_destroy: + drv_cipher_symc_destroy(*symc_handle); + crypto_drv_func_exit(); + return ret; +} + +static td_s32 inner_mac_process(td_u32 chn_num, drv_symc_context_t *symc_ctx, + td_phys_addr_t data_phys_addr, td_u32 length) +{ + td_s32 ret; + +#if defined(CRYPTO_MAC_TRACE_ENABLE) + crypto_dump_phys_addr("mac_process_data", data_phys_addr, length); + crypto_dump_data("set_mac_iv", symc_ctx->iv, sizeof(symc_ctx->iv)); +#endif + + ret = hal_cipher_symc_set_iv(chn_num, symc_ctx->iv, sizeof(symc_ctx->iv)); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_set_iv failed, ret is 0x%x\n", ret); + + ret = hal_cipher_symc_add_in_node(chn_num, data_phys_addr, length, IN_NODE_TYPE_FIRST | IN_NODE_TYPE_LAST); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_add_in_node failed\n"); + + ret = hal_cipher_symc_start(chn_num); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_start failed\n"); + + ret = hal_cipher_symc_wait_done(chn_num, TD_TRUE); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_wait_done failed\n"); + + ret = hal_cipher_symc_get_iv(chn_num, symc_ctx->iv, sizeof(symc_ctx->iv)); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_get_iv failed, ret is 0x%x\n", ret); + +#if defined(CRYPTO_MAC_TRACE_ENABLE) + crypto_dump_data("get_mac_iv", symc_ctx->iv, sizeof(symc_ctx->iv)); +#endif + return ret; +} + + +static td_s32 inner_mac_update(td_u32 chn_num, drv_symc_context_t *symc_ctx, const crypto_buf_attr *src_buf, + td_u32 length) +{ + td_s32 ret = CRYPTO_SUCCESS; + td_u32 processing_length = 0; + td_u32 processed_length = 0; + td_u32 left = length; + + /* process one tail. */ + processing_length = sizeof(symc_ctx->tail) - symc_ctx->tail_length; + if (processing_length != 0) { + ret = memcpy_s(symc_ctx->tail + symc_ctx->tail_length, processing_length, + src_buf->virt_addr, processing_length); + crypto_chk_return(ret != EOK, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + } + + ret = memcpy_s(symc_ctx->dma_addr, symc_ctx->dma_size, symc_ctx->tail, sizeof(symc_ctx->tail)); + crypto_chk_return(ret != EOK, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + ret = inner_mac_process(chn_num, symc_ctx, crypto_get_phys_addr(symc_ctx->dma_addr), sizeof(symc_ctx->tail)); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_mac_process failed\n"); + + processed_length += processing_length; + left -= processing_length; + symc_ctx->tail_length = 0; + + while (left > sizeof(symc_ctx->tail)) { + if (left > symc_ctx->dma_size) { + processing_length = symc_ctx->dma_size; + } else if (left % CRYPTO_AES_BLOCK_SIZE_IN_BYTES == 0) { + processing_length = left - CRYPTO_AES_BLOCK_SIZE_IN_BYTES; // remain the last block. + } else { + processing_length = left - left % CRYPTO_AES_BLOCK_SIZE_IN_BYTES; + } + ret = memcpy_s(symc_ctx->dma_addr, symc_ctx->dma_size, + (td_u8 *)src_buf->virt_addr + processed_length, processing_length); + crypto_chk_return(ret != EOK, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + ret = inner_mac_process(chn_num, symc_ctx, crypto_get_phys_addr(symc_ctx->dma_addr), processing_length); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_mac_process failed, ret is 0x%x\n", ret); + + processed_length += processing_length; + left -= processing_length; + } + + symc_ctx->tail_length = left; + if (left != 0) { + ret = memcpy_s(symc_ctx->tail, sizeof(symc_ctx->tail), (td_u8 *)src_buf->virt_addr + processed_length, left); + crypto_chk_return(ret != EOK, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + } + return CRYPTO_SUCCESS; +} + +td_s32 drv_cipher_mac_update(td_handle symc_handle, const crypto_buf_attr *src_buf, td_u32 length) +{ + td_s32 ret; + td_u32 chn_num; + drv_symc_context_t *symc_ctx = TD_NULL; + + crypto_drv_func_enter(); + + symc_null_ptr_chk(src_buf); + crypto_chk_return(length == 0 || length > CRYPTO_SYMC_MAC_UPDATE_MAX_LEN, + SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM), "length is Invalid\n"); + + ret = inner_symc_drv_handle_chk(symc_handle); + if (ret != TD_SUCCESS) { + return ret; + } + + chn_num = symc_handle; + symc_ctx = inner_get_symc_ctx(symc_handle); + crypto_chk_return(symc_ctx == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_INVALID_HANDLE), "symc_handle is invalid\n"); + crypto_chk_return(symc_ctx->is_open == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_CTX_CLOSED), "ctx is closed\n"); + + if ((symc_ctx->tail_length + length) <= sizeof(symc_ctx->tail)) { + ret = memcpy_s(symc_ctx->tail + symc_ctx->tail_length, sizeof(symc_ctx->tail) - symc_ctx->tail_length, + src_buf->virt_addr, length); + crypto_chk_return(ret != EOK, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + symc_ctx->tail_length += length; + crypto_drv_func_exit(); + return TD_SUCCESS; + } + + ret = inner_mac_update(chn_num, symc_ctx, src_buf, length); + crypto_chk_return(ret != CRYPTO_SUCCESS, ret, "inner_mac_update failed\n"); + + crypto_drv_func_exit(); + return ret; +} + +static td_s32 inner_cmac_finish(td_u32 chn_num, drv_symc_context_t *symc_ctx) +{ + td_s32 ret = TD_SUCCESS; + td_u8 *result_mac = TD_NULL; + td_u8 *tail = symc_ctx->dma_addr; + hal_symc_config_t symc_config = {0}; + + result_mac = crypto_malloc_coherent(CRYPTO_AES_BLOCK_SIZE_IN_BYTES, "cipher_cmac"); + crypto_chk_return(result_mac == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc_coherent failed\n"); + + symc_config.symc_alg = symc_ctx->symc_alg; + symc_config.work_mode = symc_ctx->work_mode; + symc_config.symc_bit_width = CRYPTO_SYMC_BIT_WIDTH_128BIT; + symc_config.symc_key_length = symc_ctx->symc_key_length; + + ret = hal_cipher_symc_config(chn_num, &symc_config); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "hal_cipher_symc_config failed\n"); + + ret = hal_cipher_symc_set_iv(chn_num, symc_ctx->iv, sizeof(symc_ctx->iv)); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "hal_cipher_symc_set_iv failed, ret is 0x%x\n", ret); + + ret = memcpy_s(tail, symc_ctx->dma_size, symc_ctx->tail, symc_ctx->tail_length); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, exit_free, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + ret = hal_cipher_symc_add_in_node(chn_num, crypto_get_phys_addr(tail), symc_ctx->tail_length, + IN_NODE_TYPE_FIRST | IN_NODE_TYPE_LAST); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "hal_cipher_symc_add_in_node failed\n"); + + ret = hal_cipher_symc_add_out_node(chn_num, crypto_get_phys_addr(result_mac), CRYPTO_AES_BLOCK_SIZE_IN_BYTES); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "hal_cipher_symc_add_in_node failed\n"); + + ret = hal_cipher_symc_start(chn_num); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "hal_cipher_symc_start failed\n"); + + ret = hal_cipher_symc_wait_done(chn_num, TD_TRUE); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "hal_cipher_symc_wait_done failed\n"); + +exit_free: + (td_void)memset_s(result_mac, CRYPTO_AES_BLOCK_SIZE_IN_BYTES, 0, CRYPTO_AES_BLOCK_SIZE_IN_BYTES); + crypto_free_coherent(result_mac); + return ret; +} + +td_s32 drv_cipher_mac_finish(td_handle symc_handle, td_u8 *mac, td_u32 *mac_length) +{ + td_s32 ret; + td_s32 final_ret = TD_SUCCESS; + drv_symc_context_t *symc_ctx = TD_NULL; + td_u32 chn_num = 0; + + crypto_drv_func_enter(); + + symc_null_ptr_chk(mac); + symc_null_ptr_chk(mac_length); + crypto_chk_return(*mac_length < CRYPTO_AES_BLOCK_SIZE_IN_BYTES, SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "mac_length is not enough\n"); + ret = inner_symc_drv_handle_chk(symc_handle); + if (ret != TD_SUCCESS) { + return ret; + } + + symc_ctx = inner_get_symc_ctx(symc_handle); + crypto_chk_return(symc_ctx == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_INVALID_HANDLE), "symc_handle is invalid\n"); + crypto_chk_return(symc_ctx->is_open == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_CTX_CLOSED), "ctx is closed\n"); + + chn_num = (td_u32)symc_handle; + /* For CBC_MAC, the tail_length must be 16-Byte Aligned.. */ + if (symc_ctx->work_mode == CRYPTO_SYMC_WORK_MODE_CBC_MAC) { + crypto_chk_return(symc_ctx->tail_length % CRYPTO_AES_BLOCK_SIZE_IN_BYTES, + SYMC_COMPAT_ERRNO(ERROR_SYMC_LEN_NOT_ALIGNED), "length must be 16-Byte Aligned for CBC_MAC\n"); + if (symc_ctx->tail_length != 0) { + ret = memcpy_s(symc_ctx->dma_addr, symc_ctx->dma_size, symc_ctx->tail, symc_ctx->tail_length); + crypto_chk_return(ret != EOK, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + ret = inner_mac_process(chn_num, symc_ctx, crypto_get_phys_addr(symc_ctx->dma_addr), symc_ctx->tail_length); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_mac_process failed, ret is 0x%x\n", ret); + } + } else { /* For CMAC */ + if (symc_ctx->tail_length == 0) { + crypto_log_err("the last block size is zero for CMAC!\n"); + return SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM); + } + ret = inner_cmac_finish(chn_num, symc_ctx); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_cmac_finish failed, ret is 0x%x\n", ret); + } + + ret = hal_cipher_symc_get_iv(chn_num, mac, *mac_length); + if (ret != TD_SUCCESS) { + crypto_log_err("hal_cipher_symc_get_iv failed, ret is 0x%x\n", ret); + final_ret = ret; + } + *mac_length = CRYPTO_AES_BLOCK_SIZE_IN_BYTES; +#if defined(CRYPTO_MAC_TRACE_ENABLE) + crypto_dump_data("mac_result", mac, *mac_length); +#endif + (td_void)drv_cipher_symc_destroy(symc_handle); + + crypto_drv_func_exit(); + return final_ret; +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_trng.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_trng.c new file mode 100644 index 00000000..08941a6d --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/drv_trng.c @@ -0,0 +1,82 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "drv_trng.h" +#include "drv_inner.h" + +#include "hal_trng.h" +#include "crypto_drv_common.h" +#include "crypto_common_macro.h" + +#define TRNG_COMPAT_ERRNO(err_code) DRV_COMPAT_ERRNO(ERROR_MODULE_TRNG, err_code) +#define TRNG_ONCE_WIDTH_IN_BYTE 4 + +static td_bool g_drv_trng_init_flag = TD_FALSE; + +td_s32 drv_cipher_trng_init(td_void) +{ + td_s32 ret; + if (g_drv_trng_init_flag == TD_TRUE) { + return TD_SUCCESS; + } + ret = hal_cipher_trng_init(); + g_drv_trng_init_flag = TD_TRUE; + + return ret; +} + +/* times try to read rang */ +#define RANG_READ_TRY_TIME 0x40 + +td_s32 drv_cipher_trng_get_random(td_u32 *randnum) +{ + td_s32 ret = TD_SUCCESS; + td_u32 i; + crypto_chk_return(g_drv_trng_init_flag == TD_FALSE, TRNG_COMPAT_ERRNO(ERROR_NOT_INIT), "call init first!\n"); + crypto_chk_return(randnum == TD_NULL, TRNG_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "randnum is NULL\n"); + + for (i = 0; i < RANG_READ_TRY_TIME; i++) { + ret = hal_cipher_trng_get_random(randnum); + if (ret == TD_SUCCESS) { + return ret; + } + } + + return TD_FAILURE; +} + +td_s32 drv_cipher_trng_get_multi_random(td_u32 size, td_u8 *randnum) +{ + td_s32 ret = TD_FAILURE; + td_u32 cnt; + td_u32 i; + td_u32 randnum_once = 0; + td_u32 tail = 0; + crypto_chk_return(g_drv_trng_init_flag == TD_FALSE, TRNG_COMPAT_ERRNO(ERROR_NOT_INIT), "call init first!\n"); + crypto_chk_return(randnum == TD_NULL, TRNG_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "randnum is NULL\n"); + cnt = size / TRNG_ONCE_WIDTH_IN_BYTE; + for (i = 0; i < cnt; i++) { + ret = drv_cipher_trng_get_random(&randnum_once); + crypto_chk_return(ret != TD_SUCCESS, ret, "ERROR! drv_cipher_trng_get_random failed!\n"); + (void)memcpy_s(randnum, TRNG_ONCE_WIDTH_IN_BYTE, &randnum_once, TRNG_ONCE_WIDTH_IN_BYTE); + randnum += TRNG_ONCE_WIDTH_IN_BYTE; + } + /* less then 4 byte */ + tail = size - cnt * TRNG_ONCE_WIDTH_IN_BYTE; + if (tail != 0) { + ret = drv_cipher_trng_get_random(&randnum_once); + crypto_chk_return(ret != TD_SUCCESS, ret, "ERROR! drv_cipher_trng_get_random failed!\n"); + memcpy_s(randnum, tail, &randnum_once, tail); + } + return ret; +} + +td_s32 drv_cipher_trng_deinit(td_void) +{ + if (g_drv_trng_init_flag == TD_FALSE) { + return TD_SUCCESS; + } + g_drv_trng_init_flag = TD_FALSE; + return hal_cipher_trng_deinit(); +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/otpc_register.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/otpc_register.h new file mode 100644 index 00000000..4e9f34a4 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/drv_code/otpc_register.h @@ -0,0 +1,137 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef OTPC_REGISTER_H +#define OTPC_REGISTER_H + +#include "ot_type.h" + +#define OTP_RW_CTRL (0x1000) + +// [9:0] -- otp_addr , OTP read only support word operation, so addr[1:0] will be ignored. +#define OTP_ADDR (0x1004) + +#define OTP_WDATA (0x1008) +#define OTP_RDATA (0x100C) +#define OTP_STATUS (0x1010) +#define OTP_UPDATE (0x1014) +#define OTP_LOCK (0x1038) +#define OTP_LOCK_STATUS (0x103C) +#define OTP_AUTO_SB_CTRL (0x1050) + +#define OTP_LOCK_UNLOCK 0x0 +#define OTP_LOCK_TIMEOUT 1000000 + +#define OTP_LOCK_CMD 1 +#define OTP_UNLOCK_CMD 0 +#define OTP_LOCK_TYPE_LOCK 0 +#define OTP_LOCK_TYPE_UNLOCK 1 + +#define OTP_AUTO_STANDBY_ENABLE 1 +#define OTP_AUTO_STANDBY_DISABLE 0 + +#define OTP_TEST_MODE_NORMAL 0x0 +#define OTP_WR_SEL_TSMC_EFUSE_NORMAL_RD 0x4 + +#define OTP_WR_SEL_OTP_STANDBY 0x0 +#define OTP_WR_SEL_OTP_RD 0x1 +#define OTP_WR_SEL_PGM_ACCESS 0x2 + +#define OTP_START_BUSY 0x1 +#define OTP_START_IDLE 0x0 + +#define OTP_CHECK_PASS 0x0 +#define OTP_CHECK_FAIL 0x1 + +#define OTP_UPDATE_REQ_BUSY 0x1 +#define OTP_UPDATE_REQ_IDLE 0x0 + +/* ! Define the offset of OTPC Shadow reg */ +#define SOC_TEE_ENABLE_REG (0x0010) + +#define TEE_NOT_ENABLE 0x42 +/* Define the union U_OTP_BYTE_ALIGNED_LOCKABLE_0 */ +typedef union { + struct { + td_u32 otp_not_blank : 16; /* [15:0] */ + td_u32 soc_tee_enable : 8; /* [23:16] */ + td_u32 obfu_mrk1_owner_id_low : 8; /* [31:24] */ + } bits; + td_u32 u32; +} otp_byte_aligned_lockable_0; /* 0x10 */ + +/* +1.otp_start: [0] + OTP operation start. + 1'b0: idle; + 1'b1: busy. + Software sets 1'b1 to start operation, logic clears to 1'b0 after operation is done. +2.otp_wr_sel: [3:1] + OTP normal mode control. + Ememory: + 3'b000: standby; + 3'b001: read access; + 3'b010: pgm access; + 3'b011: pgm verify; (recommend) + 3'b100: pgm margin read; + 3'b101: initial margin read single; + others: standby. +3.otp_test_mode: [6:4] + OTP test mode control. Only used for SOC JTAG in blank chipset. + Ememory: + 3'b000: normal mode; + 3'b001: initial margin read; + 3'b010: repair margin read; + 3'b011: repair check mode; + 3'b100: repair pgm mode; + 3'b101: puf auto enrollment; + 3'b110: puf check mode; + others: normal mode. +*/ +typedef union { + struct { + td_u32 start : 1; // [0] + td_u32 wr_sel : 3; // [3:1] + td_u32 test_mode : 3; // [4:6] + td_u32 reserved : 25; // [31:7] + } bits; + td_u32 u32; +} otp_rw_ctrl_u; + +typedef union { + struct { + td_u32 init_rdy : 1; // [0] + td_u32 check_fail : 1; // [1] 1'b0: pass; 1'b1: fail. + td_u32 check_alarm : 1; // [2] + td_u32 reserved : 29; // [31:3] + } bits; + td_u32 u32; +} otp_status; + +typedef union { + struct { + td_u32 req : 1; // [0] 0: idle; 1: busy + td_u32 reserved : 31; // [31:1] + } bits; + td_u32 u32; +} otp_update; + +typedef union { + struct { + td_u32 otp_lock : 1; // [0] + td_u32 otp_lock_type : 1; // [1] 1'b0: lock command; 1'b1: unlock command. + td_u32 reserved : 30; // [31:2] + } bits; + td_u32 u32; +} otp_lock; + +typedef union { + struct { + td_u32 otp_auto_sb_en : 1; // [0] 1'b0: disable; 1'b1: enable. + td_u32 reserved : 31; // [31:1] + } bits; + td_u32 u32; +} otp_auto_sb_ctrl; + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/km_v4/README.md b/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/km_v4/README.md new file mode 100644 index 00000000..ea92e421 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/km_v4/README.md @@ -0,0 +1,6 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + */ + + +# hicfbb km hal \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/km_v4/hal_keyslot.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/km_v4/hal_keyslot.c new file mode 100644 index 00000000..7f359179 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/km_v4/hal_keyslot.c @@ -0,0 +1,208 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "hal_keyslot.h" +#include "hal_keyslot_reg.h" +#include "crypto_drv_common.h" +#include "crypto_common_macro.h" + +#define KEYSLOT_TYPE_MCIPHER 0 +#define KEYSLOT_TYPE_HMAC 1 + +#define KM_COMPAT_ERRNO(err_code) HAL_COMPAT_ERRNO(ERROR_MODULE_KM, err_code) +#define km_null_ptr_chk(ptr) \ + crypto_chk_return((ptr) == TD_NULL, KM_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), #ptr" is NULL\n") + +static td_bool inner_kslot_chn_is_locked(td_u32 keyslot_num, td_u32 keyslot_type_reg_value, td_u32 *locked_cpu) +{ + kc_rd_slot_num slot = {0}; + kc_rd_lock_status stat = {0}; + + slot.u32 = km_reg_read(KC_RD_SLOT_NUM); + slot.bits.slot_cfg_type = keyslot_type_reg_value; /* sym or hash */ + slot.bits.slot_num_cfg = keyslot_num; + km_reg_write(KC_RD_SLOT_NUM, slot.u32); + + stat.u32 = km_reg_read(KC_RD_LOCK_STATUS); + if (locked_cpu != TD_NULL) { + *locked_cpu = stat.bits.rd_lock_status; + } + if (stat.bits.rd_lock_status) { + return TD_TRUE; + } + return TD_FALSE; +} + +static td_bool inner_kslot_is_busy(td_void) +{ + kc_flush_busy kc_busy = {0}; + crypto_cpu_type cpu_type = crypto_get_cpu_type(); + switch (cpu_type) { + case CRYPTO_CPU_TYPE_ACPU: + kc_busy.u32 = km_reg_read(KC_REECPU_FLUSH_BUSY); + break; + case CRYPTO_CPU_TYPE_SCPU: + kc_busy.u32 = km_reg_read(KC_TEECPU_FLUSH_BUSY); + break; + default: + crypto_log_err("invalid cpu type\n"); + return TD_TRUE; + } + if (kc_busy.bits.flush_busy) { + return TD_TRUE; + } + return TD_FALSE; +} + +static td_bool inner_kslot_is_unlock_failed(td_void) +{ + kc_flush_busy kc_busy = {0}; + crypto_cpu_type cpu_type = crypto_get_cpu_type(); + switch (cpu_type) { + case CRYPTO_CPU_TYPE_ACPU: + kc_busy.u32 = km_reg_read(KC_REECPU_FLUSH_BUSY); + break; + case CRYPTO_CPU_TYPE_SCPU: + kc_busy.u32 = km_reg_read(KC_TEECPU_FLUSH_BUSY); + break; + default: + crypto_log_err("invalid cpu type\n"); + return TD_TRUE; + } + if (kc_busy.bits.flush_unlock_fail) { + return TD_TRUE; + } + return TD_FALSE; +} + +#define KSLOT_TIMEOUT 1000000 +static td_s32 inner_kslot_wait_idle(void) +{ + td_u32 time_out = KSLOT_TIMEOUT; + + while (time_out) { + if (inner_kslot_is_busy() == TD_FALSE) { + break; + } + crypto_udelay(1); + --time_out; + } + if (time_out == 0) { + return KM_COMPAT_ERRNO(ERROR_KEYSLOT_TIMEOUT); + } + + return TD_SUCCESS; +} + +#define KS_STAT_UN_LOCK 0x0 +#define KS_STAT_REE_LOCK 0x1 +#define KS_STAT_TEE_LOCK 0x2 + +#define KS_CPU_LOCK 1 +#define KS_CPU_UNLOCK 0 +td_s32 hal_keyslot_lock(td_u32 keyslot_num, crypto_keyslot_type keyslot_type) +{ + td_u32 keyslot_type_reg_value = 0; + crypto_cpu_type cpu_type = crypto_get_cpu_type(); + td_u32 cpu_reg_addr = KC_REECPU_LOCK_CMD; /* default is ree cpu. */ + td_u32 lock_state_expected = KS_STAT_REE_LOCK; /* default is ree cpu. */ + td_u32 lock_state = 0; + kc_cpu_lock_cmd lock_cmd = {0}; + + switch (keyslot_type) { + case CRYPTO_KEYSLOT_TYPE_MCIPHER: + keyslot_type_reg_value = KEYSLOT_TYPE_MCIPHER; + break; + case CRYPTO_KEYSLOT_TYPE_HMAC: + keyslot_type_reg_value = KEYSLOT_TYPE_HMAC; + break; + default: + crypto_log_err("invalid keyslot_type\n"); + return KM_COMPAT_ERRNO(ERROR_INVALID_PARAM); + } + + if (inner_kslot_chn_is_locked(keyslot_num, keyslot_type_reg_value, TD_NULL)) { + return KM_COMPAT_ERRNO(ERROR_KEYSLOT_LOCK); + } + + if (inner_kslot_is_busy()) { + return KM_COMPAT_ERRNO(ERROR_CHN_BUSY); + } + + if (cpu_type == CRYPTO_CPU_TYPE_SCPU) { + lock_state_expected = KS_STAT_TEE_LOCK; + cpu_reg_addr = KC_TEECPU_LOCK_CMD; + } + + lock_cmd.u32 = km_reg_read(cpu_reg_addr); + lock_cmd.bits.flush_hmac_kslot_ind = keyslot_type_reg_value; + lock_cmd.bits.key_slot_num = keyslot_num; + lock_cmd.bits.lock_cmd = KS_CPU_LOCK; /* start lock and unlock */ + km_reg_write(cpu_reg_addr, lock_cmd.u32); + + if (inner_kslot_chn_is_locked(keyslot_num, keyslot_type_reg_value, &lock_state) == TD_FALSE) { + crypto_log_err("lock failed\n"); + return KM_COMPAT_ERRNO(ERROR_KEYSLOT_LOCK); + } + if (lock_state != lock_state_expected) { + crypto_log_err("lock failed\n"); + return KM_COMPAT_ERRNO(ERROR_KEYSLOT_LOCK); + } + return TD_SUCCESS; +} + +td_s32 hal_keyslot_unlock(td_u32 keyslot_num, crypto_keyslot_type keyslot_type) +{ + volatile td_s32 ret = TD_FAILURE; + td_u32 keyslot_type_reg_value = 0; + crypto_cpu_type cpu_type = crypto_get_cpu_type(); + td_u32 cpu_reg_addr = 0; + kc_cpu_lock_cmd lock_cmd = {0}; + + switch (keyslot_type) { + case CRYPTO_KEYSLOT_TYPE_MCIPHER: + keyslot_type_reg_value = KEYSLOT_TYPE_MCIPHER; + break; + case CRYPTO_KEYSLOT_TYPE_HMAC: + keyslot_type_reg_value = KEYSLOT_TYPE_HMAC; + break; + default: + crypto_log_err("invalid keyslot_type\n"); + return KM_COMPAT_ERRNO(ERROR_INVALID_PARAM); + } + + if (inner_kslot_is_busy()) { + return KM_COMPAT_ERRNO(ERROR_CHN_BUSY); + } + if (inner_kslot_chn_is_locked(keyslot_num, keyslot_type_reg_value, TD_NULL) == TD_FALSE) { + return TD_SUCCESS; + } + + switch (cpu_type) { + case CRYPTO_CPU_TYPE_SCPU: + cpu_reg_addr = KC_TEECPU_LOCK_CMD; + break; + case CRYPTO_CPU_TYPE_ACPU: + cpu_reg_addr = KC_REECPU_LOCK_CMD; + break; + default: + crypto_log_err("invalid cpu type\n"); + return KM_COMPAT_ERRNO(ERROR_INVALID_CPU_TYPE); + } + + lock_cmd.u32 = km_reg_read(cpu_reg_addr); + lock_cmd.bits.flush_hmac_kslot_ind = keyslot_type_reg_value; + lock_cmd.bits.key_slot_num = keyslot_num; + lock_cmd.bits.lock_cmd = KS_CPU_UNLOCK; /* start lock and unlock */ + km_reg_write(cpu_reg_addr, lock_cmd.u32); + + ret = inner_kslot_wait_idle(); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_kslot_wait_idle failed\n"); + + if (inner_kslot_is_unlock_failed() == TD_TRUE) { + crypto_log_err("kslot unlock failed\n"); + return KM_COMPAT_ERRNO(ERROR_KEYSLOT_LOCK); + } + return TD_SUCCESS; +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/km_v4/hal_keyslot_reg.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/km_v4/hal_keyslot_reg.h new file mode 100644 index 00000000..b717e546 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/km_v4/hal_keyslot_reg.h @@ -0,0 +1,153 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef HAL_KEYSLOT_REG_H +#define HAL_KEYSLOT_REG_H + +#define KS_CPU_LOCK 1 +#define KS_CPU_UNLOCK 0 + +#define KCTRL_REG_OFFSET (0x00001000) + +#define KC_TEECPU_LOCK_CMD (KCTRL_REG_OFFSET + 0xB00) +#define KC_REECPU_LOCK_CMD (KCTRL_REG_OFFSET + 0xB04) +#define KC_PCPU_LOCK_CMD (KCTRL_REG_OFFSET + 0xB08) +#define KC_AIDSP_LOCK_CMD (KCTRL_REG_OFFSET + 0xB0c) +#define KC_TEECPU_FLUSH_BUSY (KCTRL_REG_OFFSET + 0xB10) +#define KC_REECPU_FLUSH_BUSY (KCTRL_REG_OFFSET + 0xB14) +#define KC_PCPU_FLUSH_BUSY (KCTRL_REG_OFFSET + 0xB18) +#define KC_AIDSP_FLUSH_BUSY (KCTRL_REG_OFFSET + 0xB1c) +#define KC_RD_SLOT_NUM (KCTRL_REG_OFFSET + 0xB30) +#define KC_RD_LOCK_STATUS (KCTRL_REG_OFFSET + 0xB34) + +typedef enum { + KS_STAT_UN_LOCK = 0x0, + KS_STAT_REE_LOCK = 0x1, + KS_STAT_TEE_LOCK = 0x2, + KS_STAT_PCPU_LOCK = 0x4, + KS_STAT_AIDSP_LOCK = 0x6, + KS_STAT_MAX +} ks_slot_stat; + +/* define the union u_kc_cpu_lock_cmd */ +typedef union { + struct { + unsigned int key_slot_num : 10; /* [9..0] */ + unsigned int reserved_0 : 5; /* [14..10] */ + unsigned int flush_hmac_kslot_ind : 1; /* [15] */ + unsigned int tscipher_ind : 1; /* [16] */ + unsigned int reserved_1 : 3; /* [19..17] */ + unsigned int lock_cmd : 1; /* [20] */ + unsigned int reserved_2 : 11; /* [31..21] */ + } bits; + unsigned int u32; +} kc_cpu_lock_cmd; + +/* define the union u_kc_teecpu_lock_cmd */ +typedef union { + struct { + unsigned int tee_key_slot_num : 10; /* [9..0] */ + unsigned int reserved_0 : 5; /* [14..10] */ + unsigned int tee_flush_hmac_kslot_ind : 1; /* [15] */ + unsigned int tee_tscipher_ind : 1; /* [16] */ + unsigned int reserved_1 : 3; /* [19..17] */ + unsigned int tee_lock_cmd : 1; /* [20] */ + unsigned int reserved_2 : 11; /* [31..21] */ + } bits; + unsigned int u32; +} kc_tee_lock_cmd; + +/* define the union u_kc_reecpu_lock_cmd */ +typedef union { + struct { + unsigned int ree_key_slot_num : 10; /* [9..0] */ + unsigned int reserved_0 : 5; /* [14..10] */ + unsigned int ree_flush_hmac_kslot_ind : 1; /* [15] */ + unsigned int ree_tscipher_ind : 1; /* [16] */ + unsigned int reserved_1 : 3; /* [19..17] */ + unsigned int ree_lock_cmd : 1; /* [20] */ + unsigned int reserved_2 : 11; /* [31..21] */ + } bits; + unsigned int u32; +} kc_ree_lock_cmd; + +/* define the union u_kc_pcpu_lock_cmd */ +typedef union { + struct { + unsigned int pcpu_key_slot_num : 10; /* [9..0] */ + unsigned int reserved_0 : 5; /* [14..10] */ + unsigned int pcpu_flush_hmac_kslot_ind : 1; /* [15] */ + unsigned int pcpu_tscipher_ind : 1; /* [16] */ + unsigned int reserved_1 : 3; /* [19..17] */ + unsigned int pcpu_lock_cmd : 1; /* [20] */ + unsigned int reserved_2 : 11; /* [31..21] */ + } bits; + unsigned int u32; +} kc_pcpu_lock_cmd; + +/* define the union u_kc_aidsp_lock_cmd */ +typedef union { + struct { + unsigned int aidsp_key_slot_num : 10; /* [9..0] */ + unsigned int reserved_0 : 5; /* [14..10] */ + unsigned int aidsp_flush_hmac_kslot_ind : 1; /* [15] */ + unsigned int aidsp_tscipher_ind : 1; /* [16] */ + unsigned int reserved_1 : 3; /* [19..17] */ + unsigned int aidsp_lock_cmd : 1; /* [20] */ + unsigned int reserved_2 : 11; /* [31..21] */ + } bits; + unsigned int u32; +} kc_aidsp_lock_cmd; + +/* define the union kc_flush_busy */ +typedef union { + struct { + unsigned int flush_busy : 1; /* [0] */ + unsigned int flush_unlock_fail : 1; /* [1] */ + unsigned int flush_timeout_err : 1; /* [2] */ + unsigned int reserved_0 : 29; /* [31..3] */ + } bits; + unsigned int u32; +} kc_flush_busy; + +/* define the union kc_send_dbg */ +typedef union { + struct { + unsigned int main_fsm_cur : 8; /* [7..0] */ + unsigned int reserved_1 : 24; /* [31..8] */ + } bits; + unsigned int u32; +} kc_send_dbg; + +/* define the union kc_rob_alarm */ +typedef union { + struct { + unsigned int kc_rob_alarm : 4; /* [3..0] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + unsigned int u32; +} kc_rob_alarm; + +/* define the union kc_rd_slot_num */ +typedef union { + struct { + unsigned int slot_num_cfg : 10; /* [9..0] */ + unsigned int reserved_0 : 5; /* [14..10] */ + unsigned int slot_cfg_type : 1; /* [15] */ + unsigned int tscipher_slot_ind : 1; /* [16] */ + unsigned int reserved_1 : 15; /* [31..17] */ + } bits; + unsigned int u32; +} kc_rd_slot_num; + +/* define the union kc_rd_lock_status */ +typedef union { + struct { + unsigned int rd_lock_status : 3; /* [2..0] */ + unsigned int reserved_0 : 29; /* [31..3] */ + } bits; + unsigned int u32; +} kc_rd_lock_status; + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/km_v4/hal_klad.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/km_v4/hal_klad.c new file mode 100644 index 00000000..62b806bc --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/km_v4/hal_klad.c @@ -0,0 +1,648 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "hal_klad.h" +#include "hal_klad_reg.h" + +#include "crypto_drv_common.h" +#include "crypto_common_macro.h" + +#define CRYPTO_U8_TO_U32_BIT_SHIFT(data) \ + ((td_u32)(data)[i] | ((td_u32)(data)[i+1] << 8) | ((td_u32)(data)[i+2] << 16) | ((td_u32)(data)[i+3]<< 24)) + +#define HKL_COM_LOCK_STAT_TEE_LOCK 0xa5 +#define HKL_COM_LOCK_STAT_REE_LOCK 0xaa + +#define KM_COMPAT_ERRNO(err_code) HAL_COMPAT_ERRNO(ERROR_MODULE_KM, err_code) +#define km_null_ptr_chk(ptr) \ + crypto_chk_return((ptr) == TD_NULL, KM_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), #ptr" is NULL\n") + +static td_s32 inner_klad_to_be_lock(td_void) +{ + td_u32 lock_stat_expected = 0; + hkl_lock_ctrl lock_ctl = {0}; + hkl_com_lock_info lock_info = {0}; + hkl_com_lock_status lock_status = {0}; + crypto_cpu_type cpu_type = crypto_get_cpu_type(); + + switch (cpu_type) { + case CRYPTO_CPU_TYPE_ACPU: + lock_stat_expected = HKL_COM_LOCK_STAT_REE_LOCK; + break; + case CRYPTO_CPU_TYPE_SCPU: + lock_stat_expected = HKL_COM_LOCK_STAT_TEE_LOCK; + break; + default: + crypto_log_err("invalid cpu_type\n"); + return KM_COMPAT_ERRNO(ERROR_INVALID_CPU_TYPE); + } + + lock_ctl.bits.kl_lock = 0x1; + km_reg_write(KL_LOCK_CTRL, lock_ctl.u32); + + lock_info.u32 = km_reg_read(KL_COM_LOCK_INFO); + if (lock_info.bits.kl_com_lock_fail == 0x1) { + return KM_COMPAT_ERRNO(ERROR_KLAD_LOCK); + } + + lock_status.u32 = km_reg_read(KL_COM_LOCK_STATUS); + if (lock_status.bits.kl_com_lock_stat != lock_stat_expected) { + return KM_COMPAT_ERRNO(ERROR_KLAD_LOCK); + } + + return TD_SUCCESS; +} + +#define HKL_LOCK_TIMEOUT 100 +td_s32 hal_klad_lock(td_void) +{ + volatile td_s32 ret = TD_FAILURE; + td_u32 i = 0; + for (i = 0; i < HKL_LOCK_TIMEOUT; i++) { + ret = inner_klad_to_be_lock(); + if (ret == TD_SUCCESS) { + break; + } + + crypto_udelay(1); + } + + if (i >= HKL_LOCK_TIMEOUT) { + crypto_log_err("klad is busy, lock failed\n"); + return KM_COMPAT_ERRNO(ERROR_KLAD_TIMEOUT); + } + + return TD_SUCCESS; +} + +td_s32 hal_klad_unlock(td_void) +{ + hkl_unlock_ctrl unlock_ctl = {0}; + hkl_com_lock_info lock_info = {0}; + hkl_com_lock_status lock_status = {0}; + td_u32 lock_stat_expected = 0; + + crypto_cpu_type cpu_type = crypto_get_cpu_type(); + switch (cpu_type) { + case CRYPTO_CPU_TYPE_ACPU: + lock_stat_expected = HKL_COM_LOCK_STAT_REE_LOCK; + break; + case CRYPTO_CPU_TYPE_SCPU: + lock_stat_expected = HKL_COM_LOCK_STAT_TEE_LOCK; + break; + default: + crypto_log_err("invalid cpu_type\n"); + return KM_COMPAT_ERRNO(ERROR_INVALID_CPU_TYPE); + } + + lock_status.u32 = km_reg_read(KL_COM_LOCK_STATUS); + if (lock_status.bits.kl_com_lock_stat != lock_stat_expected || lock_status.bits.kl_com_lock_stat == 0) { + return TD_SUCCESS; + } + + unlock_ctl.bits.kl_unlock = 0x1; + km_reg_write(KL_UNLOCK_CTRL, unlock_ctl.u32); + + lock_info.u32 = km_reg_read(KL_COM_LOCK_INFO); + if (lock_info.bits.kl_com_unlock_fail == 0x1) { + return KM_COMPAT_ERRNO(ERROR_KLAD_LOCK); + } + + return TD_SUCCESS; +} + +#define HKL_ENGINE_AES 0x20 +#define HKL_ENGINE_SM4 0x50 +#define HKL_ENGINE_SHA1_HMAC 0xa0 +#define HKL_ENGINE_SHA2_HMAC 0xa1 +#define HKL_ENGINE_SM3_HMAC 0xa2 + +td_s32 hal_klad_set_key_crypto_cfg(td_bool encrypt_support, td_bool decrypt_support, crypto_klad_engine engine) +{ + hkl_key_cfg key_cfg = {0}; + td_u32 alg_engine_reg_value = 0; + + switch (engine) { + case CRYPTO_KLAD_ENGINE_AES: + alg_engine_reg_value = HKL_ENGINE_AES; + break; + case CRYPTO_KLAD_ENGINE_SM4: + alg_engine_reg_value = HKL_ENGINE_SM4; + break; + case CRYPTO_KLAD_ENGINE_SHA1_HMAC: + alg_engine_reg_value = HKL_ENGINE_SHA1_HMAC; + break; + case CRYPTO_KLAD_ENGINE_SHA2_HMAC: + alg_engine_reg_value = HKL_ENGINE_SHA2_HMAC; + break; + case CRYPTO_KLAD_ENGINE_SM3_HMAC: + alg_engine_reg_value = HKL_ENGINE_SM3_HMAC; + break; + default: + crypto_log_err("invalid engine\n"); + return KM_COMPAT_ERRNO(ERROR_INVALID_PARAM); + } + + key_cfg.u32 = km_reg_read(KL_KEY_CFG); + key_cfg.bits.key_dec = decrypt_support; + key_cfg.bits.key_enc = encrypt_support; + key_cfg.bits.dsc_code = alg_engine_reg_value; + + km_reg_write(KL_KEY_CFG, key_cfg.u32); + + return TD_SUCCESS; +} + +#define HKL_PORT_SEL_MCIPHER 0x1 +#define HKL_PORT_SEL_HMAC 0x1 /* the sample as MCIPHER. */ +#define HKL_PORT_SEL_NPU 0x5 +#define HKL_PORT_SEL_FLASH 0x7 + +#define HKL_FLASH_SEL_REE_DEC 0 + +td_s32 hal_klad_set_key_dest_cfg(crypto_klad_dest dest, crypto_klad_flash_key_type flash_key_type) +{ + hkl_key_cfg key_cfg = {0}; + td_u32 port_sel_reg_val = 0; + td_u32 flash_sel_reg_val = 0; + + switch (dest) { + case CRYPTO_KLAD_DEST_MCIPHER: + port_sel_reg_val = HKL_PORT_SEL_MCIPHER; + break; + case CRYPTO_KLAD_DEST_HMAC: + port_sel_reg_val = HKL_PORT_SEL_HMAC; + break; + case CRYPTO_KLAD_DEST_FLASH: + port_sel_reg_val = HKL_PORT_SEL_FLASH; + break; + case CRYPTO_KLAD_DEST_NPU: + port_sel_reg_val = HKL_PORT_SEL_NPU; + break; + default: + crypto_log_err("invalid dest\n"); + return KM_COMPAT_ERRNO(ERROR_INVALID_PARAM); + } + if (dest == CRYPTO_KLAD_DEST_FLASH) { + switch (flash_key_type) { + case CRYPTO_KLAD_FLASH_KEY_TYPE_REE_DEC: + flash_sel_reg_val = HKL_FLASH_SEL_REE_DEC; + break; + default: + crypto_log_err("invalid flash_key_type\n"); + return KM_COMPAT_ERRNO(ERROR_INVALID_PARAM); + } + } + + key_cfg.u32 = km_reg_read(KL_KEY_CFG); + key_cfg.bits.port_sel = port_sel_reg_val; + if (dest == CRYPTO_KLAD_DEST_FLASH) { + key_cfg.bits.kl_flash_sel = flash_sel_reg_val; + } + km_reg_write(KL_KEY_CFG, key_cfg.u32); + + return TD_SUCCESS; +} + +td_s32 hal_klad_set_key_secure_cfg(const crypto_klad_key_secure_config *secure_cfg) +{ + hkl_key_sec_cfg sec_cfg = {0}; + + km_null_ptr_chk(secure_cfg); + + sec_cfg.u32 = km_reg_read(KL_KEY_SEC_CFG); + sec_cfg.bits.master_only = secure_cfg->master_only_enable; + sec_cfg.bits.dest_sec = secure_cfg->dest_buf_sec_support; + sec_cfg.bits.dest_nsec = secure_cfg->dest_buf_non_sec_support; + sec_cfg.bits.src_sec = secure_cfg->src_buf_sec_support; + sec_cfg.bits.src_nsec = secure_cfg->src_buf_non_sec_support; + sec_cfg.bits.key_sec = secure_cfg->key_sec; + km_reg_write(KL_KEY_SEC_CFG, sec_cfg.u32); + + return TD_SUCCESS; +} + +td_s32 hal_klad_set_key_addr(crypto_klad_dest klad_dest, td_u32 keyslot_chn) +{ + hkl_key_addr key_addr = {0}; + + if (klad_dest == CRYPTO_KLAD_DEST_MCIPHER) { /* symc */ + key_addr.u32 = km_reg_read(KL_KEY_ADDR); + key_addr.bits.key_addr = (keyslot_chn << 1); + km_reg_write(KL_KEY_ADDR, key_addr.u32); + } else if (klad_dest == CRYPTO_KLAD_DEST_HMAC || klad_dest == CRYPTO_KLAD_DEST_NPU) { /* hmac & NPU */ + key_addr.u32 = km_reg_read(KL_KEY_ADDR); + key_addr.bits.key_addr = keyslot_chn; + km_reg_write(KL_KEY_ADDR, key_addr.u32); + } else { + crypto_log_err("invalid klad_dest\n"); + return KM_COMPAT_ERRNO(ERROR_INVALID_PARAM); + } + + return TD_SUCCESS; +} + +td_void hal_klad_clear_data(td_void) +{ + td_u32 i = 0; + td_u32 clear_key_val = 0; + + for (i = 0; i < HKL_KEY_LEN / CRYPTO_WORD_WIDTH; i += CRYPTO_WORD_WIDTH) { + km_reg_write(KL_DATA_IN_0 + i, clear_key_val); + } +} + +td_s32 hal_klad_set_data(const td_u8 *data, td_u32 data_length) +{ + td_u32 i = 0; + td_u32 data_word = 0; + if (data_length == 0) { /* do nothing. */ + return TD_SUCCESS; + } + + km_null_ptr_chk(data); + crypto_chk_return(data_length > HKL_KEY_LEN, KM_COMPAT_ERRNO(ERROR_INVALID_PARAM), "invalid data_length\n"); + crypto_chk_return((data_length % CRYPTO_WORD_WIDTH) != 0, KM_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "data_length must be aligned to 4-byte\n"); + for (i = 0; i < HKL_KEY_LEN; i += CRYPTO_WORD_WIDTH) { + if (i < data_length) { + data_word = CRYPTO_U8_TO_U32_BIT_SHIFT(data); + km_reg_write(KL_DATA_IN_0 + i, data_word); + } else { + km_reg_write(KL_DATA_IN_0 + i, 0); /* padding with zero. */ + } + } + return TD_SUCCESS; +} + +td_void hal_klad_set_key_odd(td_bool odd) +{ + hkl_key_addr key_addr = {0}; + key_addr.u32 = km_reg_read(KL_KEY_ADDR); + if (odd) { + key_addr.u32 |= 0x1; /* set bit0. */ + } else { + key_addr.u32 &= ~(0x1); /* clear bit0. */ + } + km_reg_write(KL_KEY_ADDR, key_addr.u32); +} + +static td_s32 inner_klad_error_check(td_void) +{ + td_u32 klad_err = 0; + td_u32 kctrl_err = 0; + + klad_err = km_reg_read(KL_ERROR); + if (klad_err) { + crypto_log_err("klad_err is 0x%x\n", klad_err); + } + kctrl_err = km_reg_read(KC_ERROR); + if (kctrl_err) { + crypto_log_err("kctrl_err is 0x%x\n", kctrl_err); + } + if (klad_err | kctrl_err) { + return KM_COMPAT_ERRNO(ERROR_KM_LOGIC); + } + return TD_SUCCESS; +} + +#define KLAD_CLR_ROUTE_TIMEOUT 1000000 +static td_s32 inner_klad_wait_clr_route_done(td_void) +{ + volatile td_s32 ret = TD_FAILURE; + kl_clr_ctrl clr_ctrl = { 0 }; + kl_int_raw int_raw = {0}; + td_u32 i = 0; + + for (i = 0; i < KLAD_CLR_ROUTE_TIMEOUT; ++i) { + clr_ctrl.u32 = km_reg_read(KL_CLR_CTRL); + if (clr_ctrl.bits.kl_clr_start == 0) { + int_raw.u32 = km_reg_read(KL_INT_RAW); + int_raw.bits.clr_kl_int_raw = 0x1; + km_reg_write(KL_INT_RAW, int_raw.u32); + break; + } + crypto_udelay(1); + } + if (i < KLAD_CLR_ROUTE_TIMEOUT) { + ret = TD_SUCCESS; + } + + ret = inner_klad_error_check(); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_klad_error_check failed\n"); + + return ret; +} + +#define HKL_CLR_KEY_SIZE_128 0x1 +#define HKL_CLR_KEY_SIZE_192 0x2 +#define HKL_CLR_KEY_SIZE_256 0x3 +static td_s32 inner_klad_symc_start_clr_route(const td_u8 *key, td_u32 key_length, td_bool odd) +{ + volatile td_s32 ret = TD_FAILURE; + td_bool key_parity = TD_FALSE; + td_u32 key_size_reg_val = 0; + kl_clr_ctrl clr_ctrl = {0}; + + switch (key_length) { + case CRYPTO_128_KEY_LEN: + key_size_reg_val = HKL_CLR_KEY_SIZE_128; + break; + case CRYPTO_192_KEY_LEN: + key_size_reg_val = HKL_CLR_KEY_SIZE_192; + break; + case CRYPTO_256_KEY_LEN: + key_size_reg_val = HKL_CLR_KEY_SIZE_256; + break; + default: + crypto_log_err("invalid key_length\n"); + return KM_COMPAT_ERRNO(ERROR_INVALID_PARAM); + } + /* + * If key_length is 16, the key_parity is passed by caller; + * If key_length is 24/32, the high 128bit's key_parity is even, + the low 128bit's(padding 0 for 192bit) key_parity is odd. + */ + if (key_length == HKL_KEY_LEN) { + key_parity = odd; + } + /* config the high 128bit */ + hal_klad_set_key_odd(key_parity); + ret = hal_klad_set_data(key, HKL_KEY_LEN); + crypto_chk_goto(ret != TD_SUCCESS, exit_clean, "hal_klad_set_data failed\n"); + + /* config clr_ctrl */ + clr_ctrl.u32 = km_reg_read(KL_CLR_CTRL); + clr_ctrl.bits.kl_clr_key_size = key_size_reg_val; /* symc key need to config */ + clr_ctrl.bits.kl_clr_start = 0x1; /* start calculation */ + km_reg_write(KL_CLR_CTRL, clr_ctrl.u32); + + ret = inner_klad_wait_clr_route_done(); + crypto_chk_goto(ret != TD_SUCCESS, exit_clean, "inner_klad_wait_clr_route_done failed\n"); + + /* config the low 64bit/128bit */ + if (key_length != HKL_KEY_LEN) { + hal_klad_set_key_odd(TD_TRUE); + ret = hal_klad_set_data(key + HKL_KEY_LEN, key_length - HKL_KEY_LEN); + crypto_chk_goto(ret != TD_SUCCESS, exit_clean, "hal_klad_set_data failed\n"); + + /* config clr_ctrl */ + clr_ctrl.u32 = km_reg_read(KL_CLR_CTRL); + clr_ctrl.bits.kl_clr_key_size = key_size_reg_val; /* symc key need to config */ + clr_ctrl.bits.kl_clr_start = 0x1; /* start calculation */ + km_reg_write(KL_CLR_CTRL, clr_ctrl.u32); + + ret = inner_klad_wait_clr_route_done(); + crypto_chk_goto(ret != TD_SUCCESS, exit_clean, "inner_klad_wait_clr_route_done failed\n"); + } + +exit_clean: + hal_klad_clear_data(); + return ret; +} + +#define HMAC_KEY_BLOCK_SIZE_512 64 +#define HMAC_KEY_BLOCK_SIZE_1024 128 +#define HMAC_KEY_CAL_CNT_512 4 +#define HMAC_KEY_CAL_CNT_1024 8 +#define HKL_HMAC_KEY_MAX_SIZE 128 +static td_s32 inner_klad_hmac_start_clr_route(const td_u8 *key, td_u32 key_length, crypto_klad_hmac_type hmac_type) +{ + volatile td_s32 ret = TD_FAILURE; + td_u32 hmac_cal_cnt = HMAC_KEY_CAL_CNT_512; + td_u32 i; + kl_clr_ctrl clr_ctrl = {0}; + td_u8 key_padding[128] = {0}; + + km_null_ptr_chk(key); + crypto_chk_return(hmac_type != CRYPTO_KLAD_HMAC_TYPE_SHA1 && hmac_type != CRYPTO_KLAD_HMAC_TYPE_SHA224 && + hmac_type != CRYPTO_KLAD_HMAC_TYPE_SHA256 && hmac_type != CRYPTO_KLAD_HMAC_TYPE_SHA384 && + hmac_type != CRYPTO_KLAD_HMAC_TYPE_SHA512 && hmac_type != CRYPTO_KLAD_HMAC_TYPE_SM3, + KM_COMPAT_ERRNO(ERROR_INVALID_PARAM), "invalid hmac_type\n"); + + ret = memcpy_s(key_padding, sizeof(key_padding), key, key_length); + crypto_chk_return(ret != EOK, KM_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + if (hmac_type == CRYPTO_KLAD_HMAC_TYPE_SHA384 || hmac_type == CRYPTO_KLAD_HMAC_TYPE_SHA512) { + hmac_cal_cnt = HMAC_KEY_CAL_CNT_1024; + } + + for (i = 0; i < hmac_cal_cnt; i++) { + ret = hal_klad_set_data(key_padding + HKL_KEY_LEN * i, HKL_KEY_LEN); + crypto_chk_goto(ret != TD_SUCCESS, exit_clean, "hal_klad_set_data failed\n"); + + clr_ctrl.bits.kl_clr_key_cnt = i; /* only software Hmac mode need to config */ + clr_ctrl.bits.kl_clr_start = 0x1; /* start calculation */ + km_reg_write(KL_CLR_CTRL, clr_ctrl.u32); + + ret = inner_klad_wait_clr_route_done(); + crypto_chk_goto(ret != TD_SUCCESS, exit_clean, "inner_klad_wait_clr_route_done failed\n"); + } + +exit_clean: + hal_klad_clear_data(); + return ret; +} +td_s32 hal_klad_start_clr_route(crypto_klad_dest klad_dest, const crypto_klad_clear_key *clear_key) +{ + volatile td_s32 ret = TD_FAILURE; + + km_null_ptr_chk(clear_key); + km_null_ptr_chk(clear_key->key); + + if (klad_dest == CRYPTO_KLAD_DEST_MCIPHER || klad_dest == CRYPTO_KLAD_DEST_FLASH) { + ret = inner_klad_symc_start_clr_route(clear_key->key, clear_key->key_length, clear_key->key_parity); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_klad_symc_start_clr_route failed\n"); + } else if (klad_dest == CRYPTO_KLAD_DEST_HMAC) { + ret = inner_klad_hmac_start_clr_route(clear_key->key, clear_key->key_length, clear_key->hmac_type); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_klad_hmac_start_clr_route failed\n"); + } else { + crypto_log_err("invalid klad_dest\n"); + return KM_COMPAT_ERRNO(ERROR_INVALID_PARAM); + } + return ret; +} + +#define KLAD_COM_ROUTE_TIMEOUT 1000000 +td_s32 hal_klad_wait_com_route_done(td_void) +{ + volatile td_s32 ret = TD_FAILURE; + kl_com_ctrl com_ctrl = { 0 }; + kl_int_raw int_raw = {0}; + kl_com_status com_status = {0}; + td_u32 i = 0; + + for (i = 0; i < KLAD_COM_ROUTE_TIMEOUT; ++i) { + com_ctrl.u32 = km_reg_read(KL_COM_CTRL); + if (com_ctrl.bits.kl_com_start == 0) { + int_raw.u32 = km_reg_read(KL_INT_RAW); + int_raw.bits.com_kl_int_raw = 0x1; + km_reg_write(KL_INT_RAW, int_raw.u32); + break; + } + crypto_udelay(1); + } + if (i < KLAD_COM_ROUTE_TIMEOUT) { + ret = TD_SUCCESS; + } + + com_status.u32 = km_reg_read(KL_COM_STATUS); + if (com_status.bits.kl_com_rk_rdy == 0) { + crypto_log_err("root key is not ready!\n"); + } + if (com_status.bits.kl_com_lv1_rdy == 0) { + crypto_log_err("level 1 is not ready!\n"); + } + + ret = inner_klad_error_check(); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_klad_error_check failed\n"); + + return ret; +} + +#define HKL_COM_KEY_SIZE_128 0x1 +#define HKL_COM_KEY_SIZE_192 0x2 +#define HKL_COM_KEY_SIZE_256 0x3 +static crypto_table_item g_klad_key_size_table[] = { + { + .index = CRYPTO_KLAD_KEY_SIZE_128BIT, .value = HKL_COM_KEY_SIZE_128 + }, + { + .index = CRYPTO_KLAD_KEY_SIZE_192BIT, .value = HKL_COM_KEY_SIZE_192 + }, + { + .index = CRYPTO_KLAD_KEY_SIZE_256BIT, .value = HKL_COM_KEY_SIZE_256 + }, +}; + +#define HKL_COM_RK_CHOOSE_ODRK0 0x5 +#define HKL_COM_RK_CHOOSE_OARK0 0x6 +#define HKL_COM_RK_CHOOSE_ODRK1 0x7 +#define HKL_COM_RK_CHOOSE_ABRK_REE 0x15 +#define HKL_COM_RK_CHOOSE_RDRK_REE 0x17 + +#define HKL_COM_RK_CHOOSE_SBRK0 0x0 +#define HKL_COM_RK_CHOOSE_SBRK1 0x1 +#define HKL_COM_RK_CHOOSE_ABRK0 0x2 +#define HKL_COM_RK_CHOOSE_ABRK1 0x3 +#define HKL_COM_RK_CHOOSE_DRK0 0xc +#define HKL_COM_RK_CHOOSE_DRK1 0xd +#define HKL_COM_RK_CHOOSE_RDRK0 0xe +#define HKL_COM_RK_CHOOSE_RDRK1 0xf +#define HKL_COM_RK_CHOOSE_SBRK2 0x10 +#define HKL_COM_RK_CHOOSE_ABRK2 0x11 +#define HKL_COM_RK_CHOOSE_MDRK0 0x8 +#define HKL_COM_RK_CHOOSE_MDRK1 0x9 +#define HKL_COM_RK_CHOOSE_MDRK2 0xa +#define HKL_COM_RK_CHOOSE_MDRK3 0xb +#define HKL_COM_RK_CHOOSE_PSK 0x12 + +static crypto_table_item g_klad_rk_table[] = { + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_ODRK0, .value = HKL_COM_RK_CHOOSE_ODRK0 + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_OARK0, .value = HKL_COM_RK_CHOOSE_OARK0 + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_ODRK1, .value = HKL_COM_RK_CHOOSE_ODRK1 + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_ABRK_REE, .value = HKL_COM_RK_CHOOSE_ABRK_REE + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_RDRK_REE, .value = HKL_COM_RK_CHOOSE_RDRK_REE + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_ABRK0, .value = HKL_COM_RK_CHOOSE_ABRK0 + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_ABRK1, .value = HKL_COM_RK_CHOOSE_ABRK1 + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_ABRK2, .value = HKL_COM_RK_CHOOSE_ABRK2 + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_SBRK0, .value = HKL_COM_RK_CHOOSE_SBRK0 + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_SBRK1, .value = HKL_COM_RK_CHOOSE_SBRK1 + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_SBRK2, .value = HKL_COM_RK_CHOOSE_SBRK2 + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_DRK0, .value = HKL_COM_RK_CHOOSE_DRK0 + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_DRK1, .value = HKL_COM_RK_CHOOSE_DRK1 + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_RDRK0, .value = HKL_COM_RK_CHOOSE_RDRK0 + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_RDRK1, .value = HKL_COM_RK_CHOOSE_RDRK1 + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_MDRK0, .value = HKL_COM_RK_CHOOSE_MDRK0 + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_MDRK1, .value = HKL_COM_RK_CHOOSE_MDRK1 + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_MDRK2, .value = HKL_COM_RK_CHOOSE_MDRK2 + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_MDRK3, .value = HKL_COM_RK_CHOOSE_MDRK3 + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_PSK, .value = HKL_COM_RK_CHOOSE_PSK + } +}; + +#define HKL_COM_ALG_TDES_SEL_VAL (0x0) +#define HKL_COM_ALG_AES_SEL_VAL (0x1) +#define HKL_COM_ALG_SM4_SEL_VAL (0x2) +static crypto_table_item g_klad_alg_sel_table[] = { + { + .index = CRYPTO_KLAD_ALG_SEL_TDES, .value = HKL_COM_ALG_TDES_SEL_VAL + }, + { + .index = CRYPTO_KLAD_ALG_SEL_AES, .value = HKL_COM_ALG_AES_SEL_VAL + }, + { + .index = CRYPTO_KLAD_ALG_SEL_SM4, .value = HKL_COM_ALG_SM4_SEL_VAL + }, +}; +td_s32 hal_klad_com_start(crypto_klad_level_sel level, crypto_klad_alg_sel alg, crypto_klad_key_size key_size, + crypto_kdf_hard_key_type rk_type) +{ + volatile td_s32 ret = TD_FAILURE; + kl_com_ctrl com_ctrl = {0}; + td_u32 key_size_reg_val = 0; + td_u32 alg_sel_reg_val = 0; + td_u32 rk_choose_reg_val = 0; + + ret = crypto_get_value_by_index(g_klad_key_size_table, crypto_array_size(g_klad_key_size_table), + key_size, &key_size_reg_val); + crypto_chk_return(ret != TD_SUCCESS, ret, "get key_size failed\n"); + + ret = crypto_get_value_by_index(g_klad_alg_sel_table, crypto_array_size(g_klad_alg_sel_table), + alg, &alg_sel_reg_val); + crypto_chk_return(ret != TD_SUCCESS, ret, "get alg_sel failed\n"); + + ret = crypto_get_value_by_index(g_klad_rk_table, crypto_array_size(g_klad_rk_table), + rk_type, &rk_choose_reg_val); + crypto_chk_return(ret != TD_SUCCESS, ret, "get rootkey failed\n"); + + com_ctrl.u32 = km_reg_read(KL_COM_CTRL); + com_ctrl.bits.kl_com_key_size = key_size_reg_val; /* size */ + com_ctrl.bits.kl_com_alg_sel = alg_sel_reg_val; /* alg */ + com_ctrl.bits.kl_com_level_sel = level; /* level */ + com_ctrl.bits.rk_choose = rk_choose_reg_val; /* rk_choose. */ + com_ctrl.bits.kl_com_start = 1; /* start calculation */ + km_reg_write(KL_COM_CTRL, com_ctrl.u32); + + return TD_SUCCESS; +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/km_v4/hal_klad_reg.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/km_v4/hal_klad_reg.h new file mode 100644 index 00000000..aaca2d24 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/km_v4/hal_klad_reg.h @@ -0,0 +1,636 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef HAL_KLAD_REG_H +#define HAL_KLAD_REG_H + +#define KEY_SIZE_64_BIT 8 +#define KEY_SIZE_128_BIT 16 +#define KEY_SIZE_192_BIT 24 +#define KEY_SIZE_256_BIT 32 +#define SBRK_DISABLE_VAL 0x5 +#define ABRK_DISABLE_VAL 0x5 + +#define KEY_SIZE_64_BIT_REG_VAL 0x0 +#define KEY_SIZE_128_BIT_REG_VAL 0x1 +#define KEY_SIZE_192_BIT_REG_VAL 0x2 +#define KEY_SIZE_256_BIT_REG_VAL 0x3 +#define KLAD_LOCK_REG_CONFIG_VALUE 1 +#define KLAD_UNLOCK_REG_CONFIG_VALUE 1 +#define KLAD_INVALID_HANDLE_INDEX (-1) + +/* + * keyload + */ +#define KLAD_REG_OFFSET (0x00001000) + +#define KL_DATA_IN_0 (KLAD_REG_OFFSET + 0x000) +#define KL_DATA_IN_1 (KLAD_REG_OFFSET + 0x004) +#define KL_DATA_IN_2 (KLAD_REG_OFFSET + 0x008) +#define KL_DATA_IN_3 (KLAD_REG_OFFSET + 0x00c) +#define KL_DATA_IN(n) (KLAD_REG_OFFSET + 0x000 + ((n) * 0x4)) /* n 0~3 */ +#define KL_KEY_ADDR (KLAD_REG_OFFSET + 0x010) +#define KL_KEY_CFG (KLAD_REG_OFFSET + 0x014) +#define KL_KEY_SEC_CFG (KLAD_REG_OFFSET + 0x018) +#define KL_STATE (KLAD_REG_OFFSET + 0x030) +#define KL_CRC (KLAD_REG_OFFSET + 0x034) +#define KL_ERROR (KLAD_REG_OFFSET + 0x038) +#define KC_ERROR (KLAD_REG_OFFSET + 0x03c) +#define KL_INT_EN (KLAD_REG_OFFSET + 0x040) +#define KL_INT_RAW (KLAD_REG_OFFSET + 0x044) +#define KL_INT (KLAD_REG_OFFSET + 0x048) +#define SBRK_DISABLE (KLAD_REG_OFFSET + 0x060) +#define ABRK_DISABLE (KLAD_REG_OFFSET + 0x064) +#define KL_RK_GEN_STATUS (KLAD_REG_OFFSET + 0x070) +#define KL_LOCK_CTRL (KLAD_REG_OFFSET + 0x074) +#define KL_UNLOCK_CTRL (KLAD_REG_OFFSET + 0x078) +#define KL_COM_LOCK_INFO (KLAD_REG_OFFSET + 0x07c) +#define KL_COM_LOCK_STATUS (KLAD_REG_OFFSET + 0x080) +#define KL_COM_CTRL (KLAD_REG_OFFSET + 0x084) +#define KL_COM_STATUS (KLAD_REG_OFFSET + 0x088) +#define KL_CLR_CTRL (KLAD_REG_OFFSET + 0x438) +#define KL_ALARM_INFO (KLAD_REG_OFFSET + 0x600) + +/* + klad attach kslot type +*/ +#define ATTACH_FLASH 2 +#define ATTACH_MCIPHER 3 +#define ATTACH_HMAC 4 + +/* + klad data in reg num +*/ +#define KALD_DATA_IN_REG_NUM 4 + +/* + pbkdf2_key_config +*/ +#define KDF_SW_GEN 3 +#define KDF_USD 4 +#define KDF_SBRK 5 +#define KDF_ABRK 6 +#define KDF_ODRK0 7 +#define KDF_ODRK1 8 +#define KDF_RDRK 9 +#define KDF_MDRK0 10 +#define KDF_FDRK 11 +#define KDF_MDRK1 12 +#define KDF_DRK 13 +#define KDF_MDRK2 14 +#define KDF_MDRK3 15 +#define KDF_SBRK2 16 +#define KDF_ABRK2 17 +#define KDF_PSK 18 +#define KDF_ABRK_REE 20 +#define KDF_RDRK_REE 22 + +#define KLAD_KEY_TYPE_SBRK0 0x0 +#define KLAD_KEY_TYPE_SBRK1 0x1 +#define KLAD_KEY_TYPE_SBRK2 0x10 +#define KLAD_KEY_TYPE_ABRK0 0x2 +#define KLAD_KEY_TYPE_ABRK1 0x3 +#define KLAD_KEY_TYPE_ABRK2 0x11 +#define KLAD_KEY_TYPE_DRK0 0xc +#define KLAD_KEY_TYPE_DRK1 0xd +#define KLAD_KEY_TYPE_RDRK0 0xe +#define KLAD_KEY_TYPE_RDRK1 0xf +#define KLAD_KEY_TYPE_PSK 0x12 +#define KLAD_KEY_TYPE_FDRK0 0x4 +#define KLAD_KEY_TYPE_ODRK0 0x5 +#define KLAD_KEY_TYPE_OARK0 0x6 +#define KLAD_KEY_TYPE_ODRK1 0x7 +#define KLAD_KEY_TYPE_MDRK0 0x8 +#define KLAD_KEY_TYPE_ABRK_REE 0x15 +#define KLAD_KEY_TYPE_RDRK_REE 0x17 + +#define KDF_FUNC_JTAG 0x13 +#define KDF_TEE_JTAG 0x14 +#define KDF_DFT_JTAG 0x15 + +#define KLAD_DEST_TYPE_INVALID 0 +#define KLAD_DEST_TYPE_MCIPHER 1 +#define KLAD_DEST_TYPE_AI_AUDIO 4 +#define KLAD_DEST_TYPE_AI_NPU 5 +#define KLAD_DEST_TYPE_FLASH 7 +#define KLAD_UNLOCK_STATUS 0x0 + +#define KLAD_DEST_TYPE_INVALID_KSLOT 0xffffffff +#define KLAD_CLEAR_KEY_INVALID_HMAC 0xff + +#define CLEAR_HMAC_KEY_BLOCK_SIZE_512 64 +#define CLEAR_HMAC_KEY_BLOCK_SIZE_1024 128 +#define CLEAR_HMAC_KEY_CAL_CNT_512 4 +#define CLEAR_HMAC_KEY_CAL_CNT_1024 8 +#define BYTE_TO_BITS 8 +#define HKL_KEY_LEN 16 +#define HKL_KEY_LEN_32 32 + +#define KLAD_CHANNEL_MAX_SUPPORT 1 + +/* define the union hkl_lock_ctrl */ +typedef union { + /* define the struct bits */ + struct { + unsigned int kl_lock : 1; /* [0] */ + unsigned int reserved_0 : 3; /* [3..1] */ + unsigned int kl_lock_num : 3; /* [6..4] */ + unsigned int reserved_1 : 25; /* [31..7] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} hkl_lock_ctrl; + +/* define the union hkl_com_lock_info */ +typedef union { + /* define the struct bits */ + struct { + unsigned int kl_com_lock_busy : 2; /* [1..0] */ + unsigned int kl_com_lock_fail : 2; /* [3..2] */ + unsigned int kl_com_unlock_fail : 2; /* [5..4] */ + unsigned int reserved_0 : 2; /* [7..6] */ + unsigned int kl_com_lock_num : 3; /* [10..8] */ + unsigned int reserved_1 : 21; /* [31..11] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} hkl_com_lock_info; + +/* Define the union U_KL_COM_LOCK_STATUS */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int kl_com_lock_stat : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} hkl_com_lock_status; + +/* define the union hkl_unlock_ctrl */ +typedef union { + /* define the struct bits */ + struct { + unsigned int kl_unlock : 1; /* [0] */ + unsigned int reserved_0 : 3; /* [3..1] */ + unsigned int kl_unlock_num : 3; /* [6..4] */ + unsigned int reserved_1 : 1; /* [7] */ + unsigned int kl_com_unlock_num : 3; /* [10..8] */ + unsigned int reserved_2 : 21; /* [31..11] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} hkl_unlock_ctrl; + +/* Define the union KL_COM_CTRL */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int kl_com_start : 1; /* [0] */ + unsigned int kl_com_level_sel : 3; /* [3..1] */ + unsigned int kl_com_alg_sel : 2; /* [5..4] */ + unsigned int kl_com_key_size : 2; /* [7..6] */ + unsigned int rk_choose : 5; /* [12..8] */ + unsigned int reserved_1 : 19; /* [31..13] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} kl_com_ctrl; + +/* Define the union U_KL_COM_STATUS */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int kl_com_rk_rdy : 1; /* [0] */ + unsigned int kl_com_lv1_rdy : 1; /* [1] */ + unsigned int reserved_0 : 30; /* [31..2] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} kl_com_status; + +/* define the union hkl_key_sec_cfg */ +typedef union { + /* define the struct bits */ + struct { + unsigned int key_sec : 1; /* [0] */ + unsigned int src_nsec : 1; /* [1] */ + unsigned int src_sec : 1; /* [2] */ + unsigned int dest_nsec : 1; /* [3] */ + unsigned int dest_sec : 1; /* [4] */ + unsigned int master_only : 1; /* [5] */ + unsigned int reserved_0 : 26; /* [31..6] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} hkl_key_sec_cfg; + +/* define the union u_kl_key_addr */ +typedef union { + /* define the struct bits */ + struct { + unsigned int key_addr : 10; /* [9..0] */ + unsigned int reserved_0 : 22; /* [31..10] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} hkl_key_addr; + +/* define the union hkl_key_cfg */ +typedef union { + /* define the struct bits */ + struct { + unsigned int port_sel : 3; /* [2..0] */ + unsigned int reserved_0 : 1; /* [3] */ + unsigned int dsc_code : 8; /* [11..4] */ + unsigned int reserved_1 : 4; /* [15..12] */ + unsigned int key_enc : 1; /* [16] */ + unsigned int key_dec : 1; /* [17] */ + unsigned int kl_flash_sel : 2; /* [19..18] */ + unsigned int reserved_2 : 12; /* [31..20] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} hkl_key_cfg; + +/* Define the union U_KL_CLR_CTRL */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int kl_clr_start : 1; /* [0] */ + unsigned int reserved_0 : 1; /* [1] */ + unsigned int kl_clr_key_size : 2; /* [3..2] */ + unsigned int reserved_1 : 9; /* [12..4] */ + unsigned int kl_clr_key_cnt : 3; /* [15..13] */ + unsigned int reserved_2 : 16; /* [31..16] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} kl_clr_ctrl; + +/* define the union hkl_nonce_ctrl */ +typedef union { + /* define the struct bits */ + struct { + unsigned int kl_nonce_start : 1; /* [0] */ + unsigned int reserved_0 : 3; /* [3..1] */ + unsigned int kl_nonce_alg_sel : 2; /* [5..4] */ + unsigned int reserved_1 : 26; /* [31..6] */ + } bits; + /* define an unsigned member */ + unsigned int u32; +} hkl_nonce_ctrl; + +/* define the union hkl_nonce_status */ +typedef union { + /* define the struct bits */ + struct { + unsigned int kl_nonce_rk_rdy : 1; /* [0] */ + unsigned int kl_nonce_lvl1_rdy : 1; /* [1] */ + unsigned int kl_nonce_lvl2_rdy : 1; /* [2] */ + unsigned int reserved_0 : 29; /* [31..3] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} hkl_nonce_status; + +/* define the union hkl_clr_lock_info */ +typedef union { + /* define the struct bits */ + struct { + unsigned int kl_clr_lock_busy : 2; /* [1..0] */ + unsigned int kl_clr_lock_fail : 2; /* [3..2] */ + unsigned int kl_clr_unlock_fail : 2; /* [5..4] */ + unsigned int reserved_0 : 26; /* [31..6] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} hkl_clr_lock_info; + +/* define the union hkl_clr_lock_status */ +typedef union { + /* define the struct bits */ + struct { + unsigned int kl_clr_lock_stat : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} hkl_clr_lock_status; + +/* define the union hkl_clr_ctrl */ +typedef union { + /* define the struct bits */ + struct { + unsigned int kl_clr_start : 1; /* [0] */ + unsigned int kl_clr_iv_sel : 1; /* [1] */ + unsigned int kl_clr_key_size : 2; /* [3..2] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} hkl_clr_ctrl; + +/* define the union hkl_fp_lock_info */ +typedef union { + /* define the struct bits */ + struct { + unsigned int kl_fp_lock_busy : 2; /* [1..0] */ + unsigned int kl_fp_lock_fail : 2; /* [3..2] */ + unsigned int kl_fp_unlock_fail : 2; /* [5..4] */ + unsigned int reserved_0 : 26; /* [31..6] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} hkl_fp_lock_info; + +/* define the union hkl_fp_lock_status */ +typedef union { + /* define the struct bits */ + struct { + unsigned int kl_fp_lock_stat : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} hkl_fp_lock_status; + +/* define the union hkl_fp_rk_sel */ +typedef union { + /* define the struct bits */ + struct { + unsigned int kl_fp_rk_sel : 3; /* [2..0] */ + unsigned int reserved_0 : 29; /* [31..3] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} hkl_fp_rk_sel; + +/* define the union hkl_fp_ctrl */ +typedef union { + /* define the struct bits */ + struct { + unsigned int kl_fp_start : 1; /* [0] */ + unsigned int kl_fp_level_sel : 1; /* [1] */ + unsigned int reserved_0 : 4; /* [5..2] */ + unsigned int kl_fp_dec_sel : 1; /* [6] */ + unsigned int reserved_1 : 25; /* [31..7] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} hkl_fp_ctrl; + +/* define the union hkl_fp_status */ +typedef union { + /* define the struct bits */ + struct { + unsigned int kl_fp_rk_rdy : 1; /* [0] */ + unsigned int kl_fp_lv1_enc_rdy : 1; /* [1] */ + unsigned int kl_fp_lv1_dec_rdy : 1; /* [2] */ + unsigned int reserved_0 : 29; /* [31..3] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} hkl_fp_status; + +/* define the union hkl_fp_dec_ctrl */ +typedef union { + /* define the struct bits */ + struct { + unsigned int kl_fp_dec_rd_dis : 4; /* [3..0] */ + unsigned int kl_fp_dec_route_dis : 4; /* [7..4] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} hkl_fp_dec_ctrl; + +/* define the union hkl_ta_lock_info */ +typedef union { + /* define the struct bits */ + struct { + unsigned int kl_ta_lock_busy : 2; /* [1..0] */ + unsigned int kl_ta_lock_fail : 2; /* [3..2] */ + unsigned int kl_ta_unlock_fail : 2; /* [5..4] */ + unsigned int reserved_0 : 26; /* [31..6] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} hkl_ta_lock_info; + +/* define the union hkl_ta_lock_status */ +typedef union { + /* define the struct bits */ + struct { + unsigned int kl_ta_lock_stat : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} hkl_ta_lock_status; + +/* define the union hkl_ta_ctrl */ +typedef union { + /* define the struct bits */ + struct { + unsigned int kl_ta_start : 1; /* [0] */ + unsigned int kl_ta_level_sel : 2; /* [2..1] */ + unsigned int reserved_0 : 2; /* [4..3] */ + unsigned int kl_ta_cur_128bit_cnt : 6; /* [10..5] */ + unsigned int kl_ta_last_time : 1; /* [11] */ + unsigned int kl_ta_lut_alg_sel : 1; /* [12] */ + unsigned int reserved_1 : 19; /* [31..13] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} hkl_ta_ctrl; + +/* define the union hkl_ta_status */ +typedef union { + /* define the struct bits */ + struct { + unsigned int kl_ta_rk_rdy : 1; /* [0] */ + unsigned int kl_ta_lvl1_rdy : 1; /* [1] */ + unsigned int kl_ta_lvl2_rdy : 1; /* [2] */ + unsigned int kl_ta_lvl3_rdy : 1; /* [3] */ + unsigned int kl_ta_f_lut_rdy : 1; /* [4] */ + unsigned int kl_ta_f_m_rdy : 1; /* [5] */ + unsigned int kl_ta_f_bc_rdy : 1; /* [6] */ + unsigned int reserved_0 : 25; /* [31..7] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} hkl_ta_status; + +/* define the union hkl_csgk2_lock_info */ +typedef union { + /* define the struct bits */ + struct { + unsigned int kl_csgk2_lock_busy : 2; /* [1..0] */ + unsigned int kl_csgk2_lock_fail : 2; /* [3..2] */ + unsigned int kl_csgk2_unlock_fail : 2; /* [5..4] */ + unsigned int reserved_0 : 26; /* [31..6] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} hkl_csgk2_lock_info; + +/* define the union hkl_csgk2_lock_status */ +typedef union { + /* define the struct bits */ + struct { + unsigned int kl_csgk2_lock_stat : 8; /* [7..0] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} hkl_csgk2_lock_status; + +/* define the union hkl_csgk2_ctrl */ +typedef union { + /* define the struct bits */ + struct { + unsigned int kl_csgk2_start : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} hkl_csgk2_ctrl; + +/* define the union hkl_csgk2_disable */ +typedef union { + /* define the struct bits */ + struct { + unsigned int kl_csgk2_dis : 4; /* [3..0] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} hkl_csgk2_disable; + +/* define the union hkl_csgk2_disable_lock */ +typedef union { + /* define the struct bits */ + struct { + unsigned int kl_csgk2_dis_lock : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} hkl_csgk2_disable_lock; + +/* define the union hkl_alarm_info */ +typedef union { + /* define the struct bits */ + struct { + unsigned int rng_crc4_alarm : 1; /* [0] */ + unsigned int kl_cfg_sig_alarm : 1; /* [1] */ + unsigned int kl_rk_tag_sig_alarm : 1; /* [2] */ + unsigned int kl_rk_tag_crc16_alarm : 1; /* [3] */ + unsigned int kl_rk_info_crc4_alarm : 1; /* [4] */ + unsigned int kl_sel_sig_alarm : 1; /* [5] */ + unsigned int kl_com_crc16_alarm : 1; /* [6] */ + unsigned int kl_nonce_crc16_alarm : 1; /* [7] */ + unsigned int kl_fp_crc16_alarm : 1; /* [8] */ + unsigned int kl_ta_crc16_alarm : 1; /* [9] */ + unsigned int kl_ta_fsm_alarm : 1; /* [10] */ + unsigned int reserved_0 : 13; /* [23..11] */ + unsigned int cm_core_alarm : 1; /* [24] */ + unsigned int reserved_1 : 7; /* [31..25] */ + } bits; + + /* define an unsigned member */ + unsigned int u32; +} hkl_alarm_info; + +/* Define the union sbrk_disable */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int sbrk0_disable : 4; /* [3..0] */ + unsigned int sbrk1_disable : 4; /* [7..4] */ + unsigned int reserved : 24; /* [31..8] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} sbrk_disable; + +/* Define the union sbrk_disable */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int abrk0_disable : 4; /* [3..0] */ + unsigned int reserved : 28; /* [31..4] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} abrk_disable; + +/* Define the union kl_int_en */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int kl_int_en : 1; /* [0] */ + unsigned int reserved : 31; /* [31..1] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} kl_int_cfg; + +/* Define the union kl_int */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int kl_int : 1; /* [0] */ + unsigned int reserved : 31; /* [31..1] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} kl_int_status; + +/* Define the union kl_int_raw */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int com_kl_int_raw : 1; /* [0] */ + unsigned int reserved0 : 3; /* [3..1] */ + unsigned int kl_int_num : 5; /* [8..4] */ + unsigned int reserved1 : 5; /* [13..9] */ + unsigned int clr_kl_int_raw : 1; /* [14] */ + unsigned int reserved2 : 18; /* [31..15] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} kl_int_raw; + + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/km_v4/hal_rkp.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/km_v4/hal_rkp.c new file mode 100644 index 00000000..5ba8b266 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/km_v4/hal_rkp.c @@ -0,0 +1,551 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "hal_rkp.h" +#include "hal_rkp_reg.h" +#include "crypto_drv_common.h" +#include "crypto_common_macro.h" + +#define CRYPTO_U8_TO_U32_BIT_SHIFT(data, i) \ + ((td_u32)(data)[(i)*4] | ((td_u32)(data)[(i)*4+1] << 8) | ((td_u32)(data)[(i)*4+2] << 16) | \ + ((td_u32)(data)[(i)*4+3]<< 24)) + +#define KM_COMPAT_ERRNO(err_code) HAL_COMPAT_ERRNO(ERROR_MODULE_KM, err_code) +#define km_null_ptr_chk(ptr) \ + crypto_chk_return((ptr) == TD_NULL, KM_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), #ptr" is NULL\n") + +#define RKP_LOCK_TIMEOUT_IN_US 1000000 +td_s32 hal_rkp_lock(td_void) +{ + td_u32 i = 0; + rkp_lock lock_val = {0}; + td_u32 rkp_config_val = RKP_LOCK_CPU_REE; + crypto_cpu_type cpu_type = crypto_get_cpu_type(); + if (cpu_type == CRYPTO_CPU_TYPE_SCPU) { + rkp_config_val = RKP_LOCK_CPU_TEE; + } + + for (i = 0; i < RKP_LOCK_TIMEOUT_IN_US; i++) { + km_reg_write(RKP_LOCK, rkp_config_val); + lock_val.u32 = km_reg_read(RKP_LOCK); + if (lock_val.bits.km_lock_status == rkp_config_val) { + break; + } + crypto_udelay(1); + } + + if (i >= RKP_LOCK_TIMEOUT_IN_US) { + crypto_log_err("drv_rkp_lock busy.\n"); + return KM_COMPAT_ERRNO(ERROR_RKP_LOCK_TIMEOUT); + } + + return TD_SUCCESS; +} + +td_s32 hal_rkp_unlock(void) +{ + km_reg_write(RKP_LOCK, RKP_LOCK_CPU_IDLE); + return TD_SUCCESS; +} + +#define DEOB_UPDATE_KEY_SEL_MRK1 0 +#define DEOB_UPDATE_KEY_SEL_USK 1 +#define DEOB_UPDATE_KEY_SEL_RUSK 2 + +#define DEOB_UPDATE_ALG_SEL_AES 0 +#define DEOB_UPDATE_ALG_SEL_SM4 1 + +#define RKP_DEOB_UPDATE_TIMEOUT_IN_US 1000000 + +td_s32 hal_rkp_deob_update(crypto_kdf_otp_key otp_key, crypto_kdf_update_alg alg) +{ + volatile td_s32 ret = TD_FAILURE; + td_u8 deob_key_reg_val = 0; + td_u8 deob_alg_reg_val = 0; + rkp_deob_cfg deob_cfg = { 0 }; + + if (otp_key == CRYPTO_KDF_OTP_KEY_MRK1) { + deob_key_reg_val = DEOB_UPDATE_KEY_SEL_MRK1; + } else if (otp_key == CRYPTO_KDF_OTP_KEY_USK) { + deob_key_reg_val = DEOB_UPDATE_KEY_SEL_USK; + } else if (otp_key == CRYPTO_KDF_OTP_KEY_RUSK) { + deob_key_reg_val = DEOB_UPDATE_KEY_SEL_RUSK; + } else { + crypto_log_err("invalid otp_key\n"); + return KM_COMPAT_ERRNO(ERROR_INVALID_PARAM); + } + + if (alg == CRYPTO_KDF_UPDATE_ALG_AES) { + deob_alg_reg_val = DEOB_UPDATE_ALG_SEL_AES; + } else if (alg == CRYPTO_KDF_UPDATE_ALG_SM4) { + deob_alg_reg_val = DEOB_UPDATE_ALG_SEL_SM4; + } else { + crypto_log_err("invalid alg\n"); + return KM_COMPAT_ERRNO(ERROR_INVALID_PARAM); + } + + deob_cfg.u32 = km_reg_read(RKP_DEOB_CFG); + deob_cfg.bits.deob_update_alg_sel = deob_alg_reg_val; + deob_cfg.bits.deob_update_sel = deob_key_reg_val; + deob_cfg.bits.deob_update_req = 0x1; /* start calculation */ + km_reg_write(RKP_DEOB_CFG, deob_cfg.u32); + + ret = hal_rkp_deob_wait_done(); + if (ret != TD_SUCCESS) { + crypto_log_err("hal_rkp_deob_wait_done failed\n"); + ret = KM_COMPAT_ERRNO(ERROR_RKP_CALC_TIMEOUT); + } + + return ret; +} + +#define KDF_MAX_VAL_LENGTH 64 + +td_s32 hal_rkp_kdf_set_val(const td_u8 *kdf_val, td_u32 val_length) +{ + td_u32 i; + td_u32 kdf_val_word = 0; + + km_null_ptr_chk(kdf_val); + crypto_chk_return(val_length > KDF_MAX_VAL_LENGTH, KM_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "val_length is too long\n"); + crypto_chk_return((val_length % CRYPTO_WORD_WIDTH) != 0, KM_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "invalid val_length\n"); + + for (i = 0; i < val_length / CRYPTO_WORD_WIDTH; i++) { + kdf_val_word = CRYPTO_U8_TO_U32_BIT_SHIFT(kdf_val, i); + km_reg_write(RKP_PBKDF2_VAL(i), kdf_val_word); + } + return TD_SUCCESS; +} + +#define KDF_PADDING_VAL_LEN 64 +td_s32 hal_rkp_kdf_get_val(td_u8 *kdf_val, td_u32 val_length) +{ + td_u32 i; + td_u32 kdf_val_word = 0; + + km_null_ptr_chk(kdf_val); + crypto_chk_return(val_length > KDF_MAX_VAL_LENGTH, KM_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "val_length is too long\n"); + crypto_chk_return((val_length % CRYPTO_WORD_WIDTH) != 0, KM_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "invalid val_length\n"); + + for (i = 0; i < val_length / CRYPTO_WORD_WIDTH; i++) { + kdf_val_word = km_reg_read(RKP_PBKDF2_VAL(i)); + (td_void)memcpy_s(kdf_val + i * CRYPTO_WORD_WIDTH, sizeof(kdf_val_word), &kdf_val_word, sizeof(kdf_val_word)); + } + return TD_SUCCESS; +} + +#define KDF_PADDING_SALT_LEN 128 +td_s32 hal_rkp_kdf_set_padding_salt(const td_u8 *padding_salt, td_u32 salt_length) +{ + td_u32 i; + td_u32 salt_word = 0; + + km_null_ptr_chk(padding_salt); + crypto_chk_return(salt_length != KDF_PADDING_SALT_LEN, KM_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "invalid salt_length\n"); + + for (i = 0; i < salt_length / CRYPTO_WORD_WIDTH; i++) { + salt_word = CRYPTO_U8_TO_U32_BIT_SHIFT(padding_salt, i); + km_reg_write(RKP_PBKDF2_DATA(i), salt_word); + } + + return TD_SUCCESS; +} + +#define KDF_PADDING_KEY_LEN 128 +td_s32 hal_rkp_kdf_set_padding_key(const td_u8 *padding_key, td_u32 key_length) +{ + td_u32 i; + td_u32 key_word = 0; + + km_null_ptr_chk(padding_key); + crypto_chk_return(key_length != KDF_PADDING_KEY_LEN, KM_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "invalid key_length\n"); + + for (i = 0; i < key_length / CRYPTO_WORD_WIDTH; i++) { + key_word = CRYPTO_U8_TO_U32_BIT_SHIFT(padding_key, i); + km_reg_write(RKP_PBKDF2_KEY(i), key_word); + } + + return TD_SUCCESS; +} + +/* + pbkdf2_key_config +*/ +#define KDF_SW_GEN 3 + +#define PBKDF2_ALG_SEL_SHA1 1 +#define PBKDF2_ALG_SEL_SHA256 0 +#define PBKDF2_ALG_SEL_SHA384 3 +#define PBKDF2_ALG_SEL_SHA512 4 +#define PBKDF2_ALG_SEL_SM3 5 +static crypto_table_item g_rkp_alg_sel_table[] = { + { + .index = CRYPTO_KDF_SW_ALG_SHA1, .value = PBKDF2_ALG_SEL_SHA1 + }, + { + .index = CRYPTO_KDF_SW_ALG_SHA256, .value = PBKDF2_ALG_SEL_SHA256 + }, + { + .index = CRYPTO_KDF_SW_ALG_SHA384, .value = PBKDF2_ALG_SEL_SHA384 + }, + { + .index = CRYPTO_KDF_SW_ALG_SHA512, .value = PBKDF2_ALG_SEL_SHA512 + }, + { + .index = CRYPTO_KDF_SW_ALG_SM3, .value = PBKDF2_ALG_SEL_SM3 + }, +}; + +td_s32 hal_rkp_kdf_sw_start(crypto_kdf_sw_alg sw_alg, td_u32 count, td_bool is_wait) +{ + rkp_cmd_cfg cfgval = {0}; + td_u32 alg_reg_val = 0; + volatile td_s32 ret = TD_FAILURE; + + crypto_unused(is_wait); + + /* get alg_sel. */ + ret = crypto_get_value_by_index(g_rkp_alg_sel_table, crypto_array_size(g_rkp_alg_sel_table), + sw_alg, &alg_reg_val); + crypto_chk_return(ret != TD_SUCCESS, ret, "get alg_sel failed\n"); + + cfgval.u32 = km_reg_read(RKP_CMD_CFG); + cfgval.bits.rkp_pbkdf_calc_time = count; + cfgval.bits.pbkdf2_alg_sel_cfg = alg_reg_val; + cfgval.bits.pbkdf2_key_sel_cfg = KDF_SW_GEN; + cfgval.bits.sw_calc_req = 0x1; /* start calculation */ + km_reg_write(RKP_CMD_CFG, cfgval.u32); + + return TD_SUCCESS; +} + +#define RKP_WAIT_TIMEOUT_IN_US 1000000 +td_s32 hal_rkp_kdf_wait_done(td_void) +{ + td_u32 i; + volatile td_s32 ret = TD_FAILURE; + td_u32 kdf_err = 0; + rkp_cmd_cfg cmd_cfg = { 0 }; + + for (i = 0; i < RKP_WAIT_TIMEOUT_IN_US; ++i) { + cmd_cfg.u32 = km_reg_read(RKP_CMD_CFG); + if (cmd_cfg.bits.sw_calc_req == 0x0) { + km_reg_write(RKP_RAW_INT, 0x1); + break; + } + crypto_udelay(1); + } + if (i >= RKP_WAIT_TIMEOUT_IN_US) { + ret = KM_COMPAT_ERRNO(ERROR_RKP_CALC_TIMEOUT); + } else { + ret = TD_SUCCESS; + } + + /* check kdf err. */ + kdf_err = km_reg_read(KDF_ERROR); + if (kdf_err != 0) { + crypto_log_err("kdf_err is 0x%x\n", kdf_err); + ret = KM_COMPAT_ERRNO(ERROR_KM_LOGIC); + } + + return ret; +} + +td_s32 hal_rkp_deob_wait_done(td_void) +{ + td_u32 i; + volatile td_s32 ret = TD_FAILURE; + td_u32 deob_err = 0; + rkp_deob_cfg deob_cfg = { 0 }; + + for (i = 0; i < RKP_WAIT_TIMEOUT_IN_US; ++i) { + deob_cfg.u32 = km_reg_read(RKP_DEOB_CFG); + if (deob_cfg.bits.deob_update_req == 0x0) { + break; + } + crypto_udelay(1); + } + if (i >= RKP_WAIT_TIMEOUT_IN_US) { + ret = KM_COMPAT_ERRNO(ERROR_RKP_CALC_TIMEOUT); + } else { + ret = TD_SUCCESS; + } + + /* check deob err. */ + deob_err = km_reg_read(DEOB_ERROR); + if (deob_err != 0) { + crypto_log_err("deob_err is 0x%x\n", deob_err); + ret = KM_COMPAT_ERRNO(ERROR_KM_LOGIC); + } + + return ret; +} + +#define PBKDF2_KEY_SEL_ABRK_REE 20 +#define PBKDF2_KEY_SEL_RDRK_REE 22 + +#define PBKDF2_KEY_SEL_SBRK1 5 +#define PBKDF2_KEY_SEL_ABRK1 6 +#define PBKDF2_KEY_SEL_ODRK0 7 +#define PBKDF2_KEY_SEL_ODRK1 8 +#define PBKDF2_KEY_SEL_RDRK 9 +#define PBKDF2_KEY_SEL_MDRK0 10 +#define PBKDF2_KEY_SEL_FDRK 11 +#define PBKDF2_KEY_SEL_MDRK1 12 +#define PBKDF2_KEY_SEL_DRK 13 +#define PBKDF2_KEY_SEL_MDRK2 14 +#define PBKDF2_KEY_SEL_MDRK3 15 +#define PBKDF2_KEY_SEL_SBRK2 16 +#define PBKDF2_KEY_SEL_ABRK2 17 +#define PBKDF2_KEY_SEL_PSK 18 + +static crypto_table_item g_rkp_key_sel_table[] = { + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_ODRK0, .value = PBKDF2_KEY_SEL_ODRK0 + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_OARK0, .value = PBKDF2_KEY_SEL_ODRK0 + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_ODRK1, .value = PBKDF2_KEY_SEL_ODRK1 + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_ABRK_REE, .value = PBKDF2_KEY_SEL_ABRK_REE + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_RDRK_REE, .value = PBKDF2_KEY_SEL_RDRK_REE + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_SBRK0, .value = PBKDF2_KEY_SEL_SBRK1 + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_SBRK1, .value = PBKDF2_KEY_SEL_SBRK1 + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_SBRK2, .value = PBKDF2_KEY_SEL_SBRK2 + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_ABRK0, .value = PBKDF2_KEY_SEL_ABRK1 + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_ABRK1, .value = PBKDF2_KEY_SEL_ABRK1 + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_ABRK2, .value = PBKDF2_KEY_SEL_ABRK2 + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_DRK0, .value = PBKDF2_KEY_SEL_DRK + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_DRK1, .value = PBKDF2_KEY_SEL_DRK + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_RDRK0, .value = PBKDF2_KEY_SEL_RDRK + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_RDRK1, .value = PBKDF2_KEY_SEL_RDRK + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_MDRK0, .value = PBKDF2_KEY_SEL_MDRK0 + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_MDRK1, .value = PBKDF2_KEY_SEL_MDRK1 + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_MDRK2, .value = PBKDF2_KEY_SEL_MDRK2 + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_MDRK3, .value = PBKDF2_KEY_SEL_MDRK3 + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_PSK, .value = PBKDF2_KEY_SEL_PSK + } +}; + +#define PBKDF2_KEY_LEN_128BIT 1 +#define PBKDF2_KEY_LEN_192BIT 2 +#define PBKDF2_KEY_LEN_256BIT 3 +static crypto_table_item g_rkp_key_len_table[] = { + { + .index = CRYPTO_KDF_HARD_KEY_SIZE_128BIT, .value = PBKDF2_KEY_LEN_128BIT + }, + { + .index = CRYPTO_KDF_HARD_KEY_SIZE_192BIT, .value = PBKDF2_KEY_LEN_192BIT + }, + { + .index = CRYPTO_KDF_HARD_KEY_SIZE_256BIT, .value = PBKDF2_KEY_LEN_256BIT + }, +}; + +#define KDF_HARD_SALT_LEN 28 + +#if defined(CRYPTO_IOT_V200) +#define PBKDF2_RDRK_REE_ONEWAY_OFFSET 0 +#define PBKDF2_ABRK_REE_ONEWAY_OFFSET 1 +#define PBKDF2_ODRK1_ONEWAY_OFFSET 2 +static crypto_table_item g_rkp_oneway_offset_table[] = { + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_RDRK_REE, .value = PBKDF2_RDRK_REE_ONEWAY_OFFSET + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_ABRK_REE, .value = PBKDF2_ABRK_REE_ONEWAY_OFFSET + }, + { + .index = CRYPTO_KDF_HARD_KEY_TYPE_ODRK1, .value = PBKDF2_ODRK1_ONEWAY_OFFSET + }, +}; +#endif + +static crypto_table_item g_rkp_hard_alg_sel_table[] = { + { + .index = CRYPTO_KDF_HARD_ALG_SHA256, .value = PBKDF2_ALG_SEL_SHA256 + }, + { + .index = CRYPTO_KDF_HARD_ALG_SM3, .value = PBKDF2_ALG_SEL_SM3 + }, +}; +td_s32 hal_rkp_kdf_hard_calculation(const crypto_kdf_hard_calc_param *param) +{ + volatile td_s32 ret = TD_FAILURE; + td_u32 i; + td_u32 key_sel_reg_val = 0; + td_u32 alg_reg_val = 0; + td_u32 key_len_reg_val = 0; +#if defined(CRYPTO_IOT_V200) + rkp_oneway_ree onewayval = {0}; + td_u32 oneway_offset = 0; +#endif + rkp_cmd_cfg cfgval = {0}; + td_u32 salt_word = 0; + + km_null_ptr_chk(param); + if (param->salt != TD_NULL) { + crypto_chk_return(param->salt_length != KDF_HARD_SALT_LEN, KM_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "invalid param->salt_length\n"); + } + crypto_chk_return(param->hard_alg != CRYPTO_KDF_HARD_ALG_SHA256 && param->hard_alg != CRYPTO_KDF_HARD_ALG_SM3, + KM_COMPAT_ERRNO(ERROR_INVALID_PARAM), "invalid param->hard->alg\n"); + + /* get key_sel. */ + ret = crypto_get_value_by_index(g_rkp_key_sel_table, crypto_array_size(g_rkp_key_sel_table), + param->hard_key_type, &key_sel_reg_val); + crypto_chk_return(ret != TD_SUCCESS, ret, "get key_sel failed\n"); + + /* get alg_sel. */ + ret = crypto_get_value_by_index(g_rkp_hard_alg_sel_table, crypto_array_size(g_rkp_hard_alg_sel_table), + param->hard_alg, &alg_reg_val); + crypto_chk_return(ret != TD_SUCCESS, ret, "get alg_sel failed\n"); + + /* get key_len. */ + ret = crypto_get_value_by_index(g_rkp_key_len_table, crypto_array_size(g_rkp_key_len_table), + param->hard_key_size, &key_len_reg_val); + crypto_chk_return(ret != TD_SUCCESS, ret, "get key_len failed\n"); + +#if defined(CRYPTO_IOT_V200) + /* get oneway_offset. */ + ret = crypto_get_value_by_index(g_rkp_oneway_offset_table, crypto_array_size(g_rkp_oneway_offset_table), + param->hard_key_type, &oneway_offset); + crypto_chk_return(ret != TD_SUCCESS, ret, "get oneway_offset failed\n"); + + /* config oneway. */ + onewayval.u32 = km_reg_read(RKP_ONEWAY); + onewayval.u32 |= (param->is_oneway << oneway_offset); + km_reg_write(RKP_ONEWAY, onewayval.u32); +#endif + /* config salt. */ + if (param->salt != TD_NULL) { + for (i = 0; i < param->salt_length / CRYPTO_WORD_WIDTH; i++) { + salt_word = CRYPTO_U8_TO_U32_BIT_SHIFT(param->salt, i); + km_reg_write(RKP_SALT(i), salt_word); + } + } + /* config sw_cfg for MDRK0 MDRK1 MDRK2 MDRK3 */ + if (param->hard_key_type == CRYPTO_KDF_HARD_KEY_TYPE_MDRK0 || + param->hard_key_type == CRYPTO_KDF_HARD_KEY_TYPE_MDRK1 || + param->hard_key_type == CRYPTO_KDF_HARD_KEY_TYPE_MDRK2 || + param->hard_key_type == CRYPTO_KDF_HARD_KEY_TYPE_MDRK3) { + km_reg_write(SW_CFG, param->rkp_sw_cfg); + } + /* config rkp_cmd_cfg. */ + cfgval.u32 = km_reg_read(RKP_CMD_CFG); + cfgval.bits.pbkdf2_key_len = key_len_reg_val; + cfgval.bits.pbkdf2_alg_sel_cfg = alg_reg_val; + cfgval.bits.pbkdf2_key_sel_cfg = key_sel_reg_val; + + cfgval.bits.sw_calc_req = 0x1; /* start kdf calculation */ + km_reg_write(RKP_CMD_CFG, cfgval.u32); + + ret = hal_rkp_kdf_wait_done(); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_rkp_kdf_wait_done failed\n"); + + return ret; +} + +td_s32 hal_rkp_clear_reg_key(td_void) +{ + td_u32 i = 0; + td_u32 clear_key_val = 0; + + for (i = 0; i < KDF_PADDING_KEY_LEN / CRYPTO_WORD_WIDTH; i++) { + km_reg_write(RKP_PBKDF2_KEY(i), clear_key_val); + } + + for (i = 0; i < KDF_PADDING_SALT_LEN / CRYPTO_WORD_WIDTH; i++) { + km_reg_write(RKP_PBKDF2_DATA(i), clear_key_val); + } + + for (i = 0; i < KDF_PADDING_VAL_LEN / CRYPTO_WORD_WIDTH; i++) { + km_reg_write(RKP_PBKDF2_VAL(i), clear_key_val); + } + return TD_SUCCESS; +} + +td_void hal_rkp_debug(td_void) +{ + td_u32 i; + td_u32 reg_value = 0; + rkp_cmd_cfg cmd_cfg; + /* RKP_LOCK. */ + reg_value = km_reg_read(RKP_LOCK); + if (reg_value == RKP_LOCK_CPU_REE) { + crypto_print("RKP locked by REE CPU!\r\n"); + } else if (reg_value == RKP_LOCK_CPU_TEE) { + crypto_print("RKP locked by TEE CPU!\r\n"); + } + + /* RKP_CMD_CFG. */ + cmd_cfg.u32 = km_reg_read(RKP_CMD_CFG); + crypto_print("RKP_CMD_CFG: sw_calc_req is 0x%x\r\n", cmd_cfg.bits.sw_calc_req); + crypto_print("RKP_CMD_CFG: pbkdf2_alg_sel_cfg is 0x%x\r\n", cmd_cfg.bits.pbkdf2_alg_sel_cfg); + crypto_print("RKP_CMD_CFG: pbkdf2_key_sel_cfg is 0x%x\r\n", cmd_cfg.bits.pbkdf2_key_sel_cfg); + crypto_print("RKP_CMD_CFG: pbkdf2_key_len is 0x%x\r\n", cmd_cfg.bits.pbkdf2_key_len); + crypto_print("RKP_CMD_CFG: rkp_pbkdf_calc_time is 0x%x\r\n", cmd_cfg.bits.rkp_pbkdf_calc_time); + + /* KDF_ERROR. */ + crypto_print("KDF_ERROR is 0x%x\r\n", km_reg_read(KDF_ERROR)); + /* RKP_RAW_INT */ + crypto_print("RKP_RAW_INT is 0x%x\r\n", km_reg_read(RKP_RAW_INT)); + /* RKP_INT_ENABLE */ + crypto_print("RKP_INT_ENABLE is 0x%x\r\n", km_reg_read(RKP_INT_ENABLE)); + /* RKP_INT */ + crypto_print("RKP_INT is 0x%x\r\n", km_reg_read(RKP_INT)); + /* RKP_DEOB_CFG */ + crypto_print("RKP_DEOB_CFG is 0x%x\r\n", km_reg_read(RKP_DEOB_CFG)); + /* DEOB_ERROR */ + crypto_print("DEOB_ERROR is 0x%x\r\n", km_reg_read(DEOB_ERROR)); + /* RK_RDY */ + crypto_print("RK_RDY is 0x%x\r\n", km_reg_read(RK_RDY)); + /* RKP_SALT */ + for (i = 0; i < KDF_HARD_SALT_LEN / CRYPTO_WORD_WIDTH; i++) { + crypto_print("RK_RDY is 0x%x\r\n", km_reg_read(RKP_SALT(i))); + } + /* RKP_ONEWAY */ + crypto_print("RKP_ONEWAY is 0x%x\r\n", km_reg_read(RKP_ONEWAY)); +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/km_v4/hal_rkp_reg.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/km_v4/hal_rkp_reg.h new file mode 100644 index 00000000..cd038621 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/km_v4/hal_rkp_reg.h @@ -0,0 +1,147 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef HAL_RKP_REG_H +#define HAL_RKP_REG_H + +#define RKP_LOCK_CPU_IDLE 0 +#define RKP_LOCK_CPU_REE 1 +#define RKP_LOCK_CPU_TEE 2 +#define RKP_LOCK_CPU_PCPU 4 +#define RKP_LOCK_CPU_AIDSP 5 + +/* Current CPU ID Status . +8'h35: AIDSP; +8'h6a: PCPU; +8'ha5: TEE; +8'haa: ACPU. +*/ +#define PCPU_STAT 0x6a +#define AIDSP_STAT 0x35 +#define TEE_STAT 0xa5 +#define ACPU_STAT 0xaa + +#define PBKDF2_ALG_HMAC_SHA1 1 +#define PBKDF2_ALG_HMAC_SHA256 0 +#define PBKDF2_ALG_HMAC_SHA384 3 +#define PBKDF2_ALG_HMAC_SHA512 4 +#define PBKDF2_ALG_HMAC_SM3 5 + +#define HMAC_SHA1_OUTPUT_LEN 20 +#define HMAC_SHA256_OUTPUT_LEN 32 +#define HMAC_SHA384_OUTPUT_LEN 48 +#define HMAC_SHA512_OUTPUT_LEN 64 +#define HMAC_SM3_OUTPUT_LEN 32 + +#define KDF_KEY_BLOCK_SIZE_512 64 +#define KDF_KEY_BLOCK_SIZE_1024 128 +#define KDF_KEY_CONFIG_LEN 32 +#define KDF_SALT_CONFIG_LEN 32 +#define KDF_VAL_CONFIG_LEN 16 +#define KDF_ALG_TYPE 5 +#define DRV_KDF_OTP_KEY_MRK1 0 +#define DRV_KDF_OTP_KEY_USK 1 +#define DRV_KDF_OTP_KEY_RUSK 2 +#define DRV_KDF_DEOB_ALG_AES 0 +#define DRV_KDF_DEOB_ALG_SM4 1 + +/* + * rkp + */ +#define RKP_LOCK (0x000) +#define RKP_CMD_CFG (0x004) +#define KDF_ERROR (0x008) +#define RKP_DEOB_CFG (0x020) +#define DEOB_ERROR (0x028) +#define RK_RDY (0x050) +#define RKP_USD_DIS (0x054) +#define RKP_LOW_POWER (0x058) +#define RKP_INIT (0x05C) +#define SW_CFG (0x060) +#define RKP_RAW_INT (0x010) +#define RKP_INT_ENABLE (0x014) +#define RKP_INT (0x018) +#define RKP_PBKDF2_DATA(a) (0x100 + 4 * (a)) /* a 0~31 */ +#define RKP_PBKDF2_KEY(a) (0x180 + 4 * (a)) /* a 0~31 */ +#define RKP_PBKDF2_VAL(b) (0x200 + 4 * (b)) /* b 0~16 */ +#define RKP_USD(c) (0x300 + 4 * (c)) /* c 0~8 */ +#define RKP_SALT(e) (0x340 + 4 * (e)) /* e 0~6 */ +#define RKP_ONEWAY (0x360) +#define RKP_ALARM (0x400) + +/* Define the union U_RKP_RKP_LOCK */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int km_lock_status : 3; /* [2..0] */ + unsigned int reserved : 29; /* [31..3] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} rkp_lock; + +/* Define the union U_RKP_CMD_CFG */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int sw_calc_req : 1; /* [0] */ + unsigned int pbkdf2_alg_sel_cfg : 3; /* [3..1] */ + unsigned int pbkdf2_key_sel_cfg : 5; /* [8..4] */ + unsigned int reserved : 5; /* [13..9] */ + unsigned int pbkdf2_key_len : 2; /* [15..14] */ + unsigned int rkp_pbkdf_calc_time : 16; /* [31..16] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} rkp_cmd_cfg; + +/* Define the union rkp_oneway_ree */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int pbkdf2_rdrk_oneway : 1; /* [0] */ + unsigned int pbkdf2_abrk_oneway : 1; /* [1] */ + unsigned int pbkdf2_odrk1_oneway : 1; /* [2] */ + unsigned int reserved : 29; /* [31..3] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} rkp_oneway_ree; + +/* Define the union rkp_deob_cfg */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int deob_update_req : 1; /* [0] */ + unsigned int deob_update_sel : 2; /* [2..1] */ + unsigned int deob_update_alg_sel : 1; /* [3] */ + unsigned int reserved : 29; /* [31..4] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} rkp_deob_cfg; + +/* Define the union rkp_int_enable */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int rkp_int_enable : 1; /* [0] */ + unsigned int reserved : 31; /* [31..1] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} rkp_int_cfg; + +/* Define the union rkp_int */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int rkp_int : 1; /* [0] */ + unsigned int reserved : 31; /* [31..1] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} rkp_int_status; + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/pke_v4/hal_pke.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/pke_v4/hal_pke.c new file mode 100644 index 00000000..914ba5dd --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/pke_v4/hal_pke.c @@ -0,0 +1,557 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "hal_pke.h" +#include "hal_pke_reg.h" +#include "crypto_drv_common.h" +#include "securec.h" +#include "hal_common.h" + +#define PKE_TIME_OUT 6000000 +#define BYTE_BITS 0x08 +#define BYTE_MASK 0xFF +#define U16_MSB 0x8000 +#define CRC16_POLYNOMIAL 0x1021 +#define BITS_PER_BYTE 8 +#define BYTES_PER_WORD 4 +#define PKE_COMPAT_ERRNO(err_code) HAL_COMPAT_ERRNO(ERROR_MODULE_PKE, err_code) + +typedef struct { + const td_void *wait; + crypto_wait_timeout_interruptible wait_func; + td_u32 timeout_ms; + td_bool wait_done; +} pke_wait_event_type; + +static td_u32 g_pke_initialize = TD_FALSE; +static pke_wait_event_type g_pke_wait_event = { + .wait = TD_NULL, + .wait_func = TD_NULL, + .timeout_ms = 0, + .wait_done = TD_FALSE +}; + +typedef struct { + hal_pke_len pke_len; + td_u32 pke_data_len_reg; +} pke_len_reg_map; + +// Define the union of pke module interrupt enable register +typedef union { + // Define the struct bits + struct { + td_u32 pke_ie : 1; + td_u32 reserved : 31; + } bits; + + // Define an unsigned member + td_u32 u32; +} pke_ie; + +static const pke_len_reg_map g_pke_len_reg_table[] = { + {HAL_PKE_LEN_256, 0}, + {HAL_PKE_LEN_384, 1}, + {HAL_PKE_LEN_512, 2}, + {HAL_PKE_LEN_521, 2}, + {HAL_PKE_LEN_2048, 3}, + {HAL_PKE_LEN_3072, 4}, + {HAL_PKE_LEN_4096, 5} +}; + +#if defined(CONFIG_PKE_TIMEOUT_DEBUG) +static td_void hal_cipher_pke_debug(td_void) +{ + crypto_log_dbg("PKE_BUSY is 0x%x\n", pke_reg_read(PKE_BUSY)); + crypto_log_dbg("PKE_WORK_MODE is 0x%x\n", pke_reg_read(PKE_WORK_MODE)); + crypto_log_dbg("PKE_INT_ENABLE is 0x%x\n", pke_reg_read(PKE_INT_ENABLE)); + crypto_log_dbg("PKE_LOCK_INT_ENABLE is 0x%x\n", pke_reg_read(PKE_LOCK_INT_ENABLE)); + crypto_log_dbg("PKE_INT_STATUS is 0x%x\n", pke_reg_read(PKE_INT_STATUS)); + crypto_log_dbg("PKE_INT_NOMASK_STATUS is 0x%x\n", pke_reg_read(PKE_INT_NOMASK_STATUS)); + crypto_log_dbg("PKE_NOISE_EN is 0x%x\n", pke_reg_read(PKE_NOISE_EN)); + crypto_log_dbg("PKE_LOCK_STATUS is 0x%x\n", pke_reg_read(PKE_LOCK_STATUS)); + crypto_log_dbg("PKE_INT_RAW is 0x%x\n", pke_reg_read(PKE_INT_RAW)); +} +#else +#define hal_cipher_pke_debug(...) +#endif + +td_s32 hal_pke_init(void) +{ + g_pke_initialize = TD_TRUE; + return TD_SUCCESS; +} + +td_s32 hal_pke_deinit(void) +{ + g_pke_initialize = TD_FALSE; + return TD_SUCCESS; +} + +static td_bool pke_wait_condition(const td_void *param __attribute__((unused))) +{ + if (g_pke_wait_event.wait_done == TD_TRUE) { + g_pke_wait_event.wait_done = TD_FALSE; + return TD_TRUE; + } + return TD_FALSE; +} + +static td_void inner_pke_lock_irq_enable(td_bool enable) +{ + pke_lock_int_enable pke_lock_en; + + if (g_pke_wait_event.wait_func == TD_NULL) { + return; + } + pke_lock_en.u32 = pke_reg_read(PKE_LOCK_INT_ENABLE); + pke_lock_en.bits.pke_lock_int_en = enable; + pke_reg_write(PKE_LOCK_INT_ENABLE, pke_lock_en.u32); +} + +static td_void inner_pke_irq_enable(td_bool enable) +{ + pke_int_enable pke_int_en; + if (g_pke_wait_event.wait_func == TD_NULL) { + return; + } + pke_int_en.u32 = pke_reg_read(PKE_INT_ENABLE); + pke_int_en.bits.finish_int_enable = enable; + pke_reg_write(PKE_INT_ENABLE, pke_int_en.u32); +} + +td_s32 hal_pke_lock(void) +{ + pke_lock_ctrl lock_ctrl; + pke_lock_status lock_status; + td_u32 lock_type; + td_s32 ret = TD_FAILURE; + td_u32 i = 0; + if (g_pke_initialize == TD_FALSE) { + crypto_log_err("pke must be initialized!\n"); + return TD_FAILURE; + } + if (crypto_get_cpu_type() == CRYPTO_CPU_TYPE_SCPU) { + lock_type = LOCK_STATUS_SCPU; + } else { + lock_type = LOCK_STATUS_ACPU; + } + + inner_pke_lock_irq_enable(TD_TRUE); + /* lock pke */ + lock_ctrl.u32 = pke_reg_read(PKE_LOCK_CTRL); + lock_ctrl.bits.pke_lock_type = 0; /* lock command */ + lock_ctrl.bits.pke_lock = 1; + pke_reg_write(PKE_LOCK_CTRL, lock_ctrl.u32); + + if (g_pke_wait_event.wait_func != TD_NULL) { + g_pke_wait_event.wait_done = TD_FALSE; + ret = g_pke_wait_event.wait_func(g_pke_wait_event.wait, pke_wait_condition, (td_void *)(uintptr_t)lock_type, + g_pke_wait_event.timeout_ms); + if (ret <= 0) { + ret = PKE_COMPAT_ERRNO(ERROR_PKE_LOCK_TIMEOUT); + } + } else { + for (i = 0; i < PKE_TIME_OUT; i++) { + /* check lock result */ + lock_status.u32 = pke_reg_read(PKE_LOCK_STATUS); + if (lock_status.bits.pke_lock_stat == lock_type) { + break; + } + crypto_udelay(1); // 1 us is empirical value of register lock read + } + if (i >= PKE_TIME_OUT) { + crypto_log_err("pke lock timeout\n"); + ret = PKE_COMPAT_ERRNO(ERROR_PKE_LOCK_TIMEOUT); + } + } + if (ret == PKE_COMPAT_ERRNO(ERROR_PKE_LOCK_TIMEOUT)) { + hal_cipher_pke_debug(); + } else { + ret = CRYPTO_SUCCESS; + } + inner_pke_lock_irq_enable(TD_FALSE); + + inner_pke_irq_enable(TD_TRUE); + + return ret; +} + +td_s32 hal_pke_unlock(void) +{ + pke_lock_ctrl lock_ctrl; + pke_lock_status lock_status; + + inner_pke_irq_enable(TD_FALSE); + + /* unlock pke */ + lock_ctrl.u32 = pke_reg_read(PKE_LOCK_CTRL); + lock_ctrl.bits.pke_lock_type = 1; /* unlock command */ + lock_ctrl.bits.pke_lock = 1; + pke_reg_write(PKE_LOCK_CTRL, lock_ctrl.u32); + + /* check unlock result */ + lock_status.u32 = pke_reg_read(PKE_LOCK_STATUS); + if ((lock_status.bits.pke_lock_stat != PKE_LOCK_UNLOCK) || + (lock_status.bits.pke_unlock_fail == 1)) { + crypto_log_err("pke unlock timeout\n"); + return TD_FAILURE; + } + return TD_SUCCESS; +} + +td_void hal_pke_secure(td_bool enable) +{ + pke_noise_en noise; + + /* enable noise */ + noise.u32 = pke_reg_read(PKE_NOISE_EN); + noise.bits.noise_en = 0; + if (enable) { + noise.bits.noise_en = 1; + } + pke_reg_write(PKE_NOISE_EN, noise.u32); +} + +#if defined(CRYPTO_OS_INT_SUPPORT) +td_u32 hal_pke_done_try(void) +{ + pke_lock_int_dat lock_int_dat = {0}; + pke_int_dat int_dat = {0}; + + lock_int_dat.u32 = pke_reg_read(PKE_INT_RAW); + int_dat.u32 = pke_reg_read(PKE_INT_NOMASK_STATUS); + + if (lock_int_dat.bits.pke_lock_int_raw == 0x1) { + lock_int_dat.bits.pke_lock_int_raw = 0x1; + pke_reg_write(PKE_INT_RAW, lock_int_dat.u32); + return 1; + } + + if (int_dat.bits.finish_int_nomask == 0x5) { + int_dat.bits.finish_int_nomask = 0x1; + pke_reg_write(PKE_INT_NOMASK_STATUS, int_dat.u32); + return 1; + } + + return 0; +} + +td_void hal_pke_done_notify(void) +{ + g_pke_wait_event.wait_done = TD_TRUE; +} +#endif + +td_s32 hal_pke_wait_free(void) +{ + td_u32 i = 0; + pke_busy busy; + /* wait ready */ + for (i = 0; i < PKE_TIME_OUT; i++) { + busy.u32 = pke_reg_read(PKE_BUSY); + if (!busy.bits.pke_busy) { + break; + } + crypto_udelay(1); + } + + if (i >= PKE_TIME_OUT) { + crypto_log_err("error, pke wait free timeout\n"); + return PKE_COMPAT_ERRNO(ERROR_PKE_WAIT_DONE_TIMEOUT); + } + return CRYPTO_SUCCESS; +} + +static pke_mode mode_map(hal_pke_mode mode) +{ + switch (mode) { + case HAL_PKE_MODE_CLR_RAM: + return PKE_MODE_CLR_RAM ; + case HAL_PKE_MODE_EXP_MOD: + return PKE_MODE_EXP_MOD; + case HAL_PKE_MODE_MUL_DOT: + return PKE_MODE_MUL_DOT; + case HAL_PKE_MODE_ADD_DOT: + return PKE_MODE_ADD_DOT; + case HAL_PKE_MODE_TIMES_DOT: + return PKE_MODE_TIMES_DOT; + case HAL_PKE_MODE_MINV_MOD: + return PKE_MODE_MINV_MOD; + case HAL_PKE_MODE_SUB_MOD: + return PKE_MODE_SUB_MOD; + case HAL_PKE_MODE_MUL_MOD: + return PKE_MODE_MUL_MOD; + case HAL_PKE_MODE_ADD_MOD: + return PKE_MODE_ADD_MOD; + case HAL_PKE_MODE_MOD: + return PKE_MODE_MOD; + case HAL_PKE_MODE_MUL: + return PKE_MODE_MUL; + case HAL_PKE_MODE_MG_MUL_DOT: + return PKE_MODE_MG_MUL_DOT; + case HAL_PKE_MODE_ED_MUL_DOT: + return PKE_MODE_ED_MUL_DOT; + case HAL_PKE_MODE_ED_ADD_DOT: + return PKE_MODE_ED_ADD_DOT; + default: + return PKE_MODE_UNSUPPORTTED; + } +} + +td_s32 hal_pke_set_mode(hal_pke_mode mode, td_u32 len) +{ + td_u32 i = 0; + pke_work_mode work; + pke_mode mode_mapped = mode_map(mode); + + work.u32 = pke_reg_read(PKE_WORK_MODE); + + if (mode_mapped == PKE_MODE_UNSUPPORTTED) { + crypto_log_err("This soc doesn't support this work mode!"); + return PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM); + } + work.bits.mode_sel = mode_mapped; + + for (i = 0; i < sizeof(g_pke_len_reg_table) / sizeof(pke_len_reg_map); i++) { + if (len == g_pke_len_reg_table[i].pke_len) { + work.bits.data_len = g_pke_len_reg_table[i].pke_data_len_reg; + break; + } + } + + pke_reg_write(PKE_WORK_MODE, work.u32); + return TD_SUCCESS; +} + +td_void hal_pke_set_ram(td_u32 addr, const td_u8 *ram, td_u32 data_len, td_u32 padded_len) +{ + td_u32 start, val, i, j; + start = addr; + + /* Input the data which is aligned with 4 bytes; + For little-endian system, on reading one word from ram to val, byte sequence should be adjusted as - + in ram: Byte1 | Byte2 | Byte3 | Byte4 (addr low <--> addr high) + to val: Byte4 | Byte3 | Byte2 | Byte1 (MSB <--> LSB) + */ + for (i = data_len; i >= WORD_WIDTH; i -= WORD_WIDTH) { + val = ram[i - 4] << 24; /* i-4 index shift 24 bits */ + val |= ram[i - 3] << 16; /* i-3 index shift 16 bits */ + val |= ram[i - 2] << 8; /* i-2 index shift 8 bits */ + val |= ram[i - 1]; + pke_reg_write(start, val); + start += WORD_WIDTH; + } + + /* Input the data which is not aligned with 4 bytes */ + if (i != 0) { + val = 0; + for (j = 0; j < i; j++) { + val |= ram[j] << (8 * (i - 1 - j)); // 8 bit = 1 byte + } + pke_reg_write(start, val); + start += WORD_WIDTH; + } + + /* Pad the remaining part with 0x00 */ + for (; start < addr + padded_len; start += WORD_WIDTH) { + val = 0x0; + pke_reg_write(start, val); + } + return; +} + +td_void hal_pke_start(void) +{ + pke_start start; + + start.u32 = 0x00; + start.bits.pke_start = PKE_START_CODE; + + pke_reg_write(PKE_START, start.u32); + + return; +} + +static td_s32 hal_pke_wait_free_int(void) +{ + td_s32 ret = TD_FAILURE; + /* wait ready */ + if (g_pke_wait_event.wait_func != TD_NULL) { + ret = g_pke_wait_event.wait_func(g_pke_wait_event.wait, pke_wait_condition, TD_NULL, + g_pke_wait_event.timeout_ms); + if (ret > 0) { + return TD_SUCCESS; + } else { + hal_cipher_pke_debug(); + return PKE_COMPAT_ERRNO(ERROR_PKE_WAIT_DONE_TIMEOUT); + } + } + + return hal_pke_wait_free(); +} + +static td_s32 hal_pke_check_robust_warn(void) +{ + pke_robust_warn result; + + result.u32 = pke_reg_read(PKE_INT_NOMASK_STATUS); + if (result.bits.alarm_int_nomask == PKE_INT_NOMASK_ALARM) { + result.u32 = PKE_INT_NOMASK_CLR; // clear warn interrupt + pke_reg_write(PKE_INT_NOMASK_STATUS, result.u32); + return TD_SUCCESS; + } + return TD_FAILURE; +} + +static td_s32 hal_pke_error_code(void) +{ + pke_failure_flag result; + result.u32 = pke_reg_read(PKE_FAILURE_FLAG); + return result.u32; +} + +/* wait pke done */ +td_s32 hal_pke_wait_done(void) +{ + td_s32 ret = TD_FAILURE; + + ret = hal_pke_wait_free_int(); + if (ret != TD_SUCCESS) { + hal_cipher_pke_debug(); + return ret; + } + + if (hal_pke_check_robust_warn() == TD_SUCCESS) { + return TD_FAILURE; + } + + ret = hal_pke_error_code(); + if (ret != 0) { + return ret; + } + return TD_SUCCESS; +} + +td_void hal_pke_get_ram(td_u32 addr, td_u8 *ram, td_u32 klen) +{ + td_u32 val, i; + if (ram == TD_NULL) { + return; + } + for (i = klen; i >= WORD_WIDTH; i -= WORD_WIDTH) { + val = pke_reg_read(addr + i - WORD_WIDTH); + ram[klen - i + 0] = (val >> 24) & 0xFF; /* byte 0: bit 31~24 */ + ram[klen - i + 1] = (val >> 16) & 0xFF; /* byte 1: bit 23~16 */ + ram[klen - i + 2] = (val >> 8) & 0xFF; /* byte 2: bit 15~8 */ + ram[klen - i + 3] = (val) & 0xFF; /* byte 3: bit 7~0 */ + } + return; +} + +static td_u16 crc_table(td_u8 byte) +{ + td_u16 n_remainder = (td_u16)byte << BYTE_BITS; + td_u16 m = 0; + for (m = BYTE_BITS; m > 0; m--) { + if (n_remainder & U16_MSB) { + n_remainder = (n_remainder << 1) ^ CRC16_POLYNOMIAL; + } else { + n_remainder = (n_remainder << 1); + } + } + return n_remainder; +} + +static td_u16 hal_pke_crc16(td_u16 initial, const td_u8 *input, td_u32 len) +{ + td_u16 crc = initial, idx; + td_s32 i, j; + + for (i = len - 1; i >= 0; i--) { + j = (i % BYTES_PER_WORD) * 2; // 2 * len + idx = ((crc >> BITS_PER_BYTE) ^ (*(input + i + 3 - j))) & 0xFF; // 3: offset + crc = crc_table(idx) ^ (crc << BITS_PER_BYTE); + } + + return crc; +} + + +td_void hal_pke_set_key(const td_u8 *inkey, td_u8 *outkey, td_u32 klen, pke_block *random, td_u32 pad_len) +{ + td_u32 i = 0; + td_u16 crc16 = 0; + + /* The padded data will be 0x0 */ + for (i = (pad_len - 1); i >= klen; i--) { + td_u32 idx = (pad_len - 1 - i) & PKE_LEN_BLOCK_MASK; + outkey[pad_len - 1 - i] = random->byte[idx]; + } + + /* key must be protected */ + for (i = 0; i < klen; i++) { + outkey[pad_len - 1 - i] = inkey[klen - 1 - i] ^ random->byte[(pad_len - 1 - i) & PKE_LEN_BLOCK_MASK]; + } + + crc16 = hal_pke_crc16(0x0000, random->byte, 4); // 4 is len of cube in crc + crc16 = hal_pke_crc16(crc16, outkey, pad_len); + + /* set Random */ + pke_reg_write(PKE_KEY_RANDOM, crypto_cpu_to_be32(random->word[0])); + + /* set crc16 */ + pke_reg_write(PKE_KEY_CRC, crc16); + + return; +} + +td_s32 hal_pke_align_len(td_u32 a_len, td_u32 *a_len_aligned, diff_len_in_chips len) +{ + crypto_param_require(a_len_aligned != TD_NULL); + if (len == HAL_ALIGN_LEN) { + if (a_len <= HAL_PKE_LEN_256) { + *a_len_aligned = HAL_PKE_LEN_256; + } else if (a_len <= HAL_PKE_LEN_384) { + *a_len_aligned = HAL_PKE_LEN_384; + } else if (a_len <= HAL_PKE_LEN_521) { + *a_len_aligned = HAL_PKE_LEN_521; + } else if (a_len <= HAL_PKE_LEN_2048) { + *a_len_aligned = HAL_PKE_LEN_2048; + } else if (a_len <= HAL_PKE_LEN_3072) { + *a_len_aligned = HAL_PKE_LEN_3072; + } else if (a_len <= HAL_PKE_LEN_4096) { + *a_len_aligned = HAL_PKE_LEN_4096; + } else { + return PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM); + } + return TD_SUCCESS; + } else if (len == HAL_SET_KEY_LEN) { + *a_len_aligned = SET_KEY_LEN; + } else if (len == HAL_RAM_SECTION_LEN) { + *a_len_aligned = RAM_SECTION_LEN; + } else if (len == HAL_ECC_512_LEN) { + *a_len_aligned = HAL_PKE_LEN_512; + } else if (len == HAL_ECC_521_LEN) { + *a_len_aligned = HAL_PKE_LEN_521; + } else { + return PKE_COMPAT_ERRNO(ERROR_INVALID_PARAM); + } + return TD_SUCCESS; +} + +#if defined(CRYPTO_OS_INT_SUPPORT) +td_s32 hal_cipher_pke_register_wait_func(td_void *wait, + crypto_wait_timeout_interruptible wait_func, td_u32 timeout_ms) +{ + crypto_hal_func_enter(); + + g_pke_wait_event.wait = wait; + g_pke_wait_event.wait_func = wait_func; + g_pke_wait_event.timeout_ms = timeout_ms; + g_pke_wait_event.wait_done = TD_FALSE; + + crypto_hal_func_exit(); + return CRYPTO_SUCCESS; +} +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/pke_v4/hal_pke_reg.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/pke_v4/hal_pke_reg.h new file mode 100644 index 00000000..bb2ffdff --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/pke_v4/hal_pke_reg.h @@ -0,0 +1,254 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef HAL_PKE_REG_H +#define HAL_PKE_REG_H + +#define PKE_INT_NOMASK_ALARM 0x5 +#define PKE_INT_NOMASK_CLR 0x6b4a89c6 +#define PKE_LEN_BLOCK_MASK 0x03 + +#define PKE_KEY_RANDOM (0x24) + +#define PKE_BUSY 0x4 +#define PKE_WORK_MODE 0x8 +#define PKE_START 0xc +#define PKE_INT_ENABLE 0x10 +#define PKE_INT_STATUS 0x14 +#define PKE_INT_NOMASK_STATUS 0x18 +#define PKE_NOISE_EN (0x1c) +#define PKE_LOCK_INT_ENABLE (0x1c00) +#define PKE_INT_RAW (0x1c04) +#define PKE_LOCK_CTRL (0x1C10) +#define PKE_LOCK_STATUS (0x1c14) +#define PKE_LOCK_UNLOCK 0x00 + +#define PKE_FAILURE_FLAG (0x28) +#define PKE_START_CODE 0x05 + +#define SET_KEY_LEN 0x48 +#define RAM_SECTION_LEN 0x44 + +#define LOCK_STATUS_SCPU 0xa5 +#define LOCK_STATUS_ACPU 0xaa +// same with v900 +typedef union { + struct { + unsigned int pke_lock : 1; /* [0] */ + unsigned int pke_lock_type : 1; /* [1] */ + unsigned int reserved_0 : 30; /* [31..2] */ + } bits; + unsigned int u32; +} pke_lock_ctrl; + +typedef union { + struct { + unsigned int pke_lock_busy : 1; /* [0] */ + unsigned int pke_unlock_fail : 1; /* [1] */ + unsigned int reserved_0 : 2; /* [3..2] */ + unsigned int pke_lock_cnt : 3; /* [6..4] */ + unsigned int reserved_1 : 1; /* [7] */ + unsigned int pke_lock_stat : 8; /* [15..8] */ + unsigned int reserved_2 : 16; /* [31..16] */ + } bits; + unsigned int u32; +} pke_lock_status; + +typedef union { + struct { + unsigned int pke_start : 4; /* [3..0] */ + }bits; + unsigned int u32; +} pke_start; + +// difference with v900 + +typedef enum { + HAL_PKE_LEN_256 = 32, + HAL_PKE_LEN_384 = 48, + HAL_PKE_LEN_512 = 64, + HAL_PKE_LEN_521 = 68, // deference with v900 + HAL_PKE_LEN_2048 = 256, + HAL_PKE_LEN_3072 = 384, + HAL_PKE_LEN_4096 = 512, +} hal_pke_len; + +/*! \Define the operation mode */ +typedef enum { + PKE_MODE_CLR_RAM = 0x0, + PKE_MODE_EXP_MOD = 0x1, + PKE_MODE_MUL_DOT = 0x2, + PKE_MODE_ADD_DOT = 0x3, + PKE_MODE_TIMES_DOT = 0x4, + PKE_MODE_MINV_MOD = 0x5, + PKE_MODE_SUB_MOD = 0x6, + PKE_MODE_MUL_MOD = 0x7, + PKE_MODE_ADD_MOD = 0x8, + PKE_MODE_MOD = 0x9, + PKE_MODE_MUL = 0xa, + PKE_MODE_MG_MUL_DOT = 0xb, + PKE_MODE_ED_MUL_DOT = 0xc, + PKE_MODE_ED_ADD_DOT = 0xd, + PKE_MODE_UNSUPPORTTED = 0xff +} pke_mode; + +typedef union { + struct { + unsigned int power_en : 4; /* [3..0] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + unsigned int u32; +} pke_power_on; + +typedef union { + struct { + unsigned int finish_int : 4; /* [3..0] */ + unsigned int alarm_int : 4; /* [7..4] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + unsigned int u32; +} pke_int_status; + +typedef union { + struct { + unsigned int finish_int_nomask : 4; /* [3..0] */ + unsigned int alarm_int_nomask : 4; /* [7..4] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + unsigned int u32; +} pke_int_nomask_status; + +typedef union { + struct { + unsigned int finish_int_enable : 1; /* [0] */ + unsigned int reserved : 31; /* [31..1] */ + } bits; + unsigned int u32; +} pke_int_enable; + +typedef union { + struct { + unsigned int pke_lock_int_en : 1; /* [0] */ + unsigned int reserved : 31; /* [31..1] */ + } bits; + unsigned int u32; +} pke_lock_int_enable; + +typedef union { + struct { + unsigned int pke_busy : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + unsigned int u32; +} pke_busy; + +typedef union { + struct { + unsigned int pke_result_flag : 4; /* [3..0] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + unsigned int u32; +} pke_result_flag; + +typedef union { + struct { + unsigned int otp_key_sel : 4; /* [3..0] */ + unsigned int reserved_0 : 28; /* [31..4] */ + } bits; + unsigned int u32; +} pke_otp_key_sel; + +typedef enum { + PKE_RESULT_FLAG_IDLE = 0x00, + PKE_RESULT_FLAG_OK = 0x05, + PKE_RESULT_FLAG_FAIL = 0x0A, +} pke_result_code; + +typedef union { + /* Define the struct bits */ + struct { + unsigned int mode_sel : 4; /* [3..0] */ + unsigned int data_len : 3; /* [6..4] */ + unsigned int reserved_0 : 25; /* [31..7] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} pke_work_mode; + +typedef union { + /* Define the struct bits */ + struct { + unsigned int finish_int_nomask : 4; /* [3..0] */ + unsigned int alarm_int_nomask : 4; /* [7..4] */ + unsigned int reserved_0 : 24; /* [31..8] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} pke_robust_warn; + +/* Define the union U_PKE_FAILURE_FLAG */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int invalid_k : 1; /* [0] */ + unsigned int invalid_len_cfg : 1; /* [1] */ + unsigned int invalid_mode : 1; /* [2] */ + unsigned int invalid_p : 1; /* [3] */ + unsigned int invalid_n : 1; /* [4] */ + unsigned int invalid_crc : 1; /* [5] */ + unsigned int invalid_data_len : 1; /* [6] */ + unsigned int infinite_dot : 1; /* [7] */ + unsigned int in_dot_not_on_curve : 1; /* [8] */ + unsigned int out_dot_not_on_curve : 1; /* [9] */ + unsigned int no_result_in_inv_mod : 1; /* [10] */ + unsigned int invalid_n_in_inv_mod : 1; /* [11] */ + unsigned int invalid_pm_in_mg : 1; /* [12] */ + unsigned int invalid_x2_in_mg : 1; /* [13] */ + unsigned int invalid_hpi_cfg : 1; /* [14] */ + unsigned int reserved_0 : 17; /* [31..15] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} pke_failure_flag; + +/* Define the union U_PKE_POWER_NOISE_LOCK */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int noise_en : 1; /* [0] */ + unsigned int reserved_0 : 31; /* [31..1] */ + } bits; + + /* Define an unsigned member */ + unsigned int u32; +} pke_noise_en; + +typedef union { + // Define the struct bits + struct { + td_u32 pke_lock_int_raw : 1; + td_u32 pke_int_raw : 1; + td_u32 reserved : 30; + } bits; + + // Define an unsigned member + td_u32 u32; +} pke_lock_int_dat; + +typedef union { + // Define the struct bits + struct { + td_u32 finish_int_nomask : 4; + td_u32 alarm_int_nomask : 4; + td_u32 reserved : 24; + } bits; + + // Define an unsigned member + td_u32 u32; +} pke_int_dat; + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/spacc_v4/hal_hash.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/spacc_v4/hal_hash.c new file mode 100644 index 00000000..dd6501ab --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/spacc_v4/hal_hash.c @@ -0,0 +1,654 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "hal_hash.h" + +#include "crypto_drv_common.h" +#include "hal_spacc_reg.h" + +#ifndef crypto_memory_barrier +#define crypto_memory_barrier() +#endif + +#define HASH_TIME_OUT_US (1 * 1000 * 1000) /* 1s. */ +#define CACHE_LINE_SIZE 32 +#define HASH_COMPAT_ERRNO(err_code) HAL_COMPAT_ERRNO(ERROR_MODULE_HASH, err_code) + +typedef struct { + td_u32 hash_first_node : 1; + td_u32 hash_last_node : 1; + td_u32 reserved_0 : 30; // reserve + td_u32 hash_alg_length; // hash message length + td_u32 hash_start_addr_l; // hash message address + td_u32 hash_start_addr_h : 4; // hash message address +} hash_entry_in; + +typedef struct { + hash_entry_in *entry_in; /* ! spacc digest in entry struct */ + td_u32 idx_in; /* !< current hash nodes to be used */ + td_u32 idx_cnt; /* !< total hash nodes */ + td_void *wait; + crypto_wait_timeout_interruptible wait_func; + td_bool done; + td_bool is_wait; + td_bool is_last; + td_u32 timeout_ms; +} hal_hash_hard_chn_ctx; + +typedef enum { + HASH_CHN_ALG_SEL_SHA1 = 0xa, + HASH_CHN_ALG_SEL_SHA2 = 0xb, + HASH_CHN_ALG_SEL_SM3 = 0xc, +} hash_chn_alg_sel_e; + +typedef enum { + HASH_CHN_ALG_MODE_224 = 0x0, + HASH_CHN_ALG_MODE_256 = 0x1, + HASH_CHN_ALG_MODE_384 = 0x2, + HASH_CHN_ALG_MODE_512 = 0x3, +} hash_chn_alg_mode_e; + +#define HASH_MAX_DEPTH 2 +#define HASH_NODE_SIZE (sizeof(hash_entry_in) * HASH_MAX_DEPTH) + +static hal_hash_hard_chn_ctx g_hash_hard_ctx[CRYPTO_HASH_HARD_CHN_CNT]; +static td_bool g_hal_hash_initialize = TD_FALSE; + +static void priv_hal_hash_chn_interrupt_config(td_u32 chn_num, td_bool enable) +{ + td_u32 reg_val; + + reg_val = spacc_reg_read(HASH_CHANN_RAW_INT_EN); + if (enable == TD_TRUE) { + reg_val |= (1 << chn_num); + } else { + reg_val &= ~(1 << chn_num); + } + spacc_reg_write(HASH_CHANN_RAW_INT_EN, reg_val); +} + +static td_s32 hal_hash_clear_channel(td_u32 chn_num) +{ + td_u32 i = 0; + td_u32 clear_finish_reg = 0; + td_u32 mask = 0x01 << chn_num; + + priv_hal_hash_chn_interrupt_config(chn_num, TD_FALSE); + + spacc_reg_write(SPACC_HASH_CHN_CLEAR_REQ, mask); + for (i = 0; i < HASH_TIME_OUT_US; i++) { + clear_finish_reg = spacc_reg_read(SPACC_INT_RAW_HASH_CLEAR_FINISH); + if (mask & clear_finish_reg) { + spacc_reg_write(SPACC_INT_RAW_HASH_CLEAR_FINISH, mask); + break; + } + crypto_udelay(1); + } + + crypto_chk_return((i >= HASH_TIME_OUT_US), TD_FAILURE, "hash clear channel timeout\n"); + + return TD_SUCCESS; +} + +#define HASH_STATE_SIZE_256 32 +#define HASH_STATE_SIZE_512 64 + +static td_s32 priv_hal_hash_get_cfg(crypto_hash_type hash_type, hash_chn_alg_mode_e *mode, + hash_chn_alg_sel_e *alg, td_u32 *state_size) +{ + td_s32 ret = TD_SUCCESS; + td_u32 hash_alg = CRYPTO_HASH_GET_ALG(hash_type); + td_u32 hash_mode = CRYPTO_HASH_GET_MODE(hash_type); + + switch (hash_mode) { + case CRYPTO_HASH_MODE_256: { + *state_size = HASH_STATE_SIZE_256; + if (hash_alg == CRYPTO_HASH_ALG_SHA2) { + *mode = HASH_CHN_ALG_MODE_256; + *alg = HASH_CHN_ALG_SEL_SHA2; + } else if (hash_alg == CRYPTO_HASH_ALG_SM3) { + *mode = HASH_CHN_ALG_MODE_224; + *alg = HASH_CHN_ALG_SEL_SM3; + } else { + crypto_log_err("Invalid Hash Alg!\n"); + ret = TD_FAILURE; + } + break; + } + case CRYPTO_HASH_MODE_384: { + *state_size = HASH_STATE_SIZE_512; + *mode = HASH_CHN_ALG_MODE_384; + *alg = HASH_CHN_ALG_SEL_SHA2; + break; + } + case CRYPTO_HASH_MODE_512: { + *state_size = HASH_STATE_SIZE_512; + *mode = HASH_CHN_ALG_MODE_512; + *alg = HASH_CHN_ALG_SEL_SHA2; + break; + } + default: { + crypto_log_err("Invalid Hash Mode!\n"); + ret = HASH_COMPAT_ERRNO(ERROR_UNSUPPORT); + break; + } + } + return ret; +} + +static void inner_hash_irq_enable(td_u8 chn_num, td_bool enable) +{ + td_u32 reg_val; + + reg_val = spacc_reg_read(HASH_CHANN_RAW_INT_EN); + if (enable == TD_TRUE) { + reg_val |= (1 << chn_num); + } else { + reg_val &= ~(1 << chn_num); + } + spacc_reg_write(HASH_CHANN_RAW_INT_EN, reg_val); +} + +#if defined(CONFIG_HASH_TIMEOUT_DEBUG) +static td_void hal_hash_debug(td_void) +{ + td_u32 i; + td_u32 chnn_who_used; + td_u32 used; + crypto_hal_func_enter(); + + used = spacc_reg_read(SPACC_HASH_CHN_LOCK); + + crypto_print("The Status of Hash Hard Channel:\n"); + for (i = 0; i < CRYPTO_HASH_HARD_CHN_CNT; i++) { + chnn_who_used = CHN_WHO_USED_GET(used, i); + if (chnn_who_used == SPACC_CPU_REE) { + crypto_print("CHN %d is locked by REE CPU\n", i); + } else if (chnn_who_used == SPACC_CPU_TEE) { + crypto_print("CHN %d is locked by TEE CPU\n", i); + } else { + crypto_print("CHN %d is idle\n", i); + } + } + crypto_print("HASH_CHANN_RAW_INT is 0x%x\n", spacc_reg_read(HASH_CHANN_RAW_INT)); + crypto_print("HASH_CHANN_RAW_INT_EN is 0x%x\n", spacc_reg_read(HASH_CHANN_RAW_INT_EN)); + + crypto_print("TEE_HASH_CALC_CTRL_CHECK_ERR is 0x%x\n", spacc_reg_read(TEE_HASH_CALC_CTRL_CHECK_ERR)); + crypto_print("TEE_HASH_CALC_CTRL_CHECK_ERR_STATUS is 0x%x\n", spacc_reg_read(TEE_HASH_CALC_CTRL_CHECK_ERR_STATUS)); + + crypto_print("REE_HASH_CALC_CTRL_CHECK_ERR is 0x%x\n", spacc_reg_read(REE_HASH_CALC_CTRL_CHECK_ERR)); + crypto_print("REE_HASH_CALC_CTRL_CHECK_ERR_STATUS is 0x%x\n", spacc_reg_read(REE_HASH_CALC_CTRL_CHECK_ERR_STATUS)); + + crypto_hal_func_exit(); +} + +static td_void hal_hash_debug_chn(td_u32 chn_num) +{ + td_u32 i; + hal_hash_hard_chn_ctx *hard_ctx = TD_NULL; + hash_entry_in *entry_in = TD_NULL; + crypto_hal_func_enter(); + + crypto_unused(entry_in); + if (chn_num >= CRYPTO_HASH_HARD_CHN_CNT) { + crypto_log_err("Invalid chn_num!\n"); + return; + } + + hard_ctx = &g_hash_hard_ctx[chn_num]; + + crypto_print("The Status of Hash Hard Channel %d:\n", chn_num); + crypto_print("IN_HASH_CHN_CTRL is 0x%x\n", spacc_reg_read(IN_HASH_CHN_CTRL(chn_num))); + crypto_print("IN_HASH_CHN_KEY_CTRL is 0x%x\n", spacc_reg_read(IN_HASH_CHN_KEY_CTRL(chn_num))); + crypto_print("IN_HASH_CHN_NODE_LENGTH: 0x%x\n", spacc_reg_read(IN_HASH_CHN_NODE_LENGTH(chn_num))); + crypto_print("IN_HASH_CHN_NODE_START_ADDR_L: 0x%x\n", spacc_reg_read(IN_HASH_CHN_NODE_START_ADDR_L(chn_num))); + crypto_print("IN_HASH_CHN_NODE_START_ADDR_H: 0x%x\n", spacc_reg_read(IN_HASH_CHN_NODE_START_ADDR_H(chn_num))); + + crypto_print("IN_HASH_CHN_NODE_WR_POINT: 0x%x\n", spacc_reg_read(IN_HASH_CHN_NODE_WR_POINT(chn_num))); + crypto_print("IN_HASH_CHN_NODE_RD_POINT: 0x%x\n", spacc_reg_read(IN_HASH_CHN_NODE_RD_POINT(chn_num))); + + crypto_print("entry_in's virtual addr is %p, physical addr is 0x%lx\n", hard_ctx->entry_in, + (td_ulong)crypto_get_phys_addr(hard_ctx->entry_in)); + crypto_print("Total Entry Count is %u, Current Entry IDX is %u\n", hard_ctx->idx_cnt, hard_ctx->idx_in); + if (hard_ctx->wait_func != TD_NULL) { + crypto_print("Register Wait Func, timeout is %u ms, done flag is %s\n", hard_ctx->timeout_ms, hard_ctx->done ? + "TD_TRUE" : "TD_FALSE"); + } + + /* Print Entry_In. */ + for (i = 0; i < HASH_MAX_DEPTH; i++) { + crypto_print("Entry_IN[%u]:\n", i); + entry_in = &hard_ctx->entry_in[i]; + crypto_print("hash_first_node is 0x%x\n", entry_in->hash_first_node); + crypto_print("hash_last_node is 0x%x\n", entry_in->hash_last_node); + crypto_print("hash_alg_length is 0x%x\n", entry_in->hash_alg_length); + crypto_print("hash_start_addr_l is 0x%x\n", entry_in->hash_start_addr_l); + crypto_print("hash_start_addr_h is 0x%x\n", entry_in->hash_start_addr_h); + } + + /* Print last state */ + for (i = 0; i < CRYPTO_HASH_RESULT_SIZE_MAX_IN_WORD; i++) { + spacc_reg_write(CHANN_HASH_STATE_VAL_ADDR(chn_num), i); + crypto_print("CHANn_HASH_STATE_VAL[%d] is 0x%x\n", i, spacc_reg_read(CHANN_HASH_STATE_VAL(chn_num))); + } + crypto_hal_func_exit(); +} +#else +#define hal_hash_debug(...) +#define hal_hash_debug_chn(...) +#endif + +td_s32 hal_cipher_hash_init(td_void) +{ + td_u32 i; + td_s32 ret = TD_FAILURE; + hal_hash_hard_chn_ctx *hard_ctx = TD_NULL; + td_void *node_buffer = TD_NULL; + crypto_hal_func_enter(); + + if (g_hal_hash_initialize == TD_TRUE) { + return TD_SUCCESS; + } + (td_void)memset_s(g_hash_hard_ctx, sizeof(g_hash_hard_ctx), 0, sizeof(g_hash_hard_ctx)); + + node_buffer = crypto_malloc_mmz(HASH_NODE_SIZE * CRYPTO_HASH_HARD_CHN_CNT, "cipher_hash_node"); + if (node_buffer == TD_NULL) { + crypto_log_err("crypto_malloc_mmz failed\n"); + return TD_FAILURE; + } + + for (i = 0; i < CRYPTO_HASH_HARD_CHN_CNT; i++) { + hard_ctx = &g_hash_hard_ctx[i]; + hard_ctx->entry_in = (hash_entry_in *)(node_buffer) + HASH_MAX_DEPTH * i; + hard_ctx->idx_cnt = HASH_MAX_DEPTH; + hard_ctx->idx_in = 0; + } + + g_hal_hash_initialize = TD_TRUE; + + ret = TD_SUCCESS; + crypto_hal_func_exit(); + return ret; +} + +td_s32 hal_cipher_hash_deinit(td_void) +{ + td_u32 i; + td_s32 ret = TD_FAILURE; + td_void *node_buffer = TD_NULL; + td_u32 node_size = HASH_NODE_SIZE * CRYPTO_HASH_HARD_CHN_CNT; + crypto_hal_func_enter(); + + if (g_hal_hash_initialize == TD_FALSE) { + return TD_SUCCESS; + } + + node_buffer = (td_void *)g_hash_hard_ctx[0].entry_in; + for (i = 0; i < CRYPTO_HASH_HARD_CHN_CNT; i++) { + hal_hash_unlock(i); + } + (td_void)memset_s(node_buffer, node_size, 0, node_size); + crypto_free_coherent(node_buffer); + g_hal_hash_initialize = TD_FALSE; + ret = TD_SUCCESS; + crypto_hal_func_exit(); + return ret; +} + +#define HASH_SS_SECURE_VAL 0x5 +#define HASH_SS_NONSECURE_VAL 0xa + +td_s32 hal_hash_lock(td_u32 chn_num) +{ + td_u32 used = 0; + td_u32 chnn_who_used = 0; + spacc_cpu_mask cpu_mask = SPACC_CPU_IDLE; + in_hash_chn_ctrl ctrl = { 0 }; + hal_hash_hard_chn_ctx *hard_ctx = TD_NULL; + + crypto_hal_func_enter(); + + if (chn_num > CRYPTO_HASH_HARD_CHN_CNT || chn_num == 0) { + return TD_FAILURE; + } + + hard_ctx = &g_hash_hard_ctx[chn_num]; + if (crypto_get_cpu_type() == CRYPTO_CPU_TYPE_SCPU) { + cpu_mask = SPACC_CPU_TEE; + } else { + cpu_mask = SPACC_CPU_REE; + } + + used = spacc_reg_read(SPACC_HASH_CHN_LOCK); + + /* try to use this channel. */ + chnn_who_used = CHN_WHO_USED_GET(used, chn_num); + if (chnn_who_used != SPACC_CPU_IDLE) { + return HASH_COMPAT_ERRNO(ERROR_CHN_BUSY); + } + CHN_WHO_USED_SET(used, chn_num, cpu_mask); + spacc_reg_write(SPACC_HASH_CHN_LOCK, used); + + /* check if lock success. */ + used = spacc_reg_read(SPACC_HASH_CHN_LOCK); + chnn_who_used = CHN_WHO_USED_GET(used, chn_num); + if (chnn_who_used != cpu_mask) { + return HASH_COMPAT_ERRNO(ERROR_CHN_BUSY); + } + + /* clear hash channel. */ + hal_hash_clear_channel(chn_num); + + /* set secure cfg. */ + ctrl.bits.hash_chn_en = 1; + if (crypto_get_cpu_type() == CRYPTO_CPU_TYPE_SCPU) { + ctrl.bits.hash_chn_ss = HASH_SS_SECURE_VAL; + } else { + ctrl.bits.hash_chn_ss = HASH_SS_NONSECURE_VAL; + } + spacc_reg_write(IN_HASH_CHN_CTRL(chn_num), ctrl.u32); + + /* set node start addr and node length. */ + spacc_reg_write(IN_HASH_CHN_NODE_START_ADDR_L(chn_num), crypto_get_phys_addr(hard_ctx->entry_in)); + spacc_reg_write(IN_HASH_CHN_NODE_START_ADDR_H(chn_num), 0); + spacc_reg_write(IN_HASH_CHN_NODE_LENGTH(chn_num), HASH_MAX_DEPTH); + + hal_cipher_hash_done_try(chn_num); + + hard_ctx->idx_in = 0; + (td_void)memset_s(hard_ctx->entry_in, HASH_NODE_SIZE, 0, HASH_NODE_SIZE); + + crypto_hal_func_exit(); + return TD_SUCCESS; +} + +td_s32 hal_hash_unlock(td_u32 chn_num) +{ + td_u32 used; + crypto_hal_func_enter(); + + used = spacc_reg_read(SPACC_HASH_CHN_LOCK); + CHN_WHO_USED_CLR(used, chn_num); + spacc_reg_write(SPACC_HASH_CHN_LOCK, used); + + crypto_hal_func_exit(); + return TD_SUCCESS; +} + +td_s32 hal_cipher_hash_config(td_u32 chn_num, crypto_hash_type hash_type, const td_u32 *state) +{ + td_s32 ret; + td_u32 i; + in_hash_chn_key_ctrl hash_key_ctrl = { 0 }; + hash_chn_alg_mode_e mode; + hash_chn_alg_sel_e alg; + td_u32 state_size = 0; + + crypto_param_require(g_hal_hash_initialize == TD_TRUE); + crypto_param_require(chn_num <= CRYPTO_HASH_HARD_CHN_CNT); + crypto_param_require(state != TD_NULL); + + ret = priv_hal_hash_get_cfg(hash_type, &mode, &alg, &state_size); + crypto_chk_return(ret != TD_SUCCESS, ret, "priv_hal_hash_get_cfg failed\n"); + + hash_key_ctrl.u32 = spacc_reg_read(IN_HASH_CHN_KEY_CTRL(chn_num)); + hash_key_ctrl.bits.hash_chn_alg_mode = mode; + hash_key_ctrl.bits.hash_chn_alg_sel = alg; + spacc_reg_write(IN_HASH_CHN_KEY_CTRL(chn_num), hash_key_ctrl.u32); + + /* Write last state */ + for (i = 0; i < state_size / CRYPTO_WORD_WIDTH; i++) { + spacc_reg_write(CHANN_HASH_STATE_VAL_ADDR(chn_num), i); + spacc_reg_write(CHANN_HASH_STATE_VAL(chn_num), state[i]); + } + + return TD_SUCCESS; +} + +td_s32 hal_cipher_hash_attach(td_u32 chn_num, td_u32 keyslot_chn_num) +{ + in_hash_chn_key_ctrl hash_key_ctrl = { 0 }; + hash_key_ctrl.u32 = spacc_reg_read(IN_HASH_CHN_KEY_CTRL(chn_num)); + hash_key_ctrl.bits.hash_key_chn_id = keyslot_chn_num; + hash_key_ctrl.bits.hmac_vld = 1; + spacc_reg_write(IN_HASH_CHN_KEY_CTRL(chn_num), hash_key_ctrl.u32); + return CRYPTO_SUCCESS; +} + +td_s32 hal_cipher_hash_add_in_node(td_u32 chn_num, td_phys_addr_t data_phys, td_u32 data_len, + in_node_type_e in_node_type) +{ + td_u32 idx; + hal_hash_hard_chn_ctx *hard_ctx = TD_NULL; + hash_entry_in *entry_in = TD_NULL; + + crypto_chk_return(data_phys == 0, HASH_COMPAT_ERRNO(ERROR_INVALID_PHYS_ADDR), "data_phys is invalid\n"); + + hard_ctx = &g_hash_hard_ctx[chn_num]; + + /* clear entry_in. */ + idx = hard_ctx->idx_in++; + hard_ctx->idx_in %= hard_ctx->idx_cnt; + + entry_in = &hard_ctx->entry_in[idx]; + (td_void)memset_s(entry_in, sizeof(hash_entry_in), 0, sizeof(hash_entry_in)); + + /* set addr and length. */ + entry_in->hash_first_node = (in_node_type & IN_NODE_TYPE_FIRST) ? 1 : 0; + entry_in->hash_last_node = (in_node_type & IN_NODE_TYPE_LAST) ? 1 : 0; + entry_in->hash_start_addr_l = data_phys; + entry_in->hash_start_addr_h = 0; + entry_in->hash_alg_length = data_len; + + if (in_node_type & IN_NODE_TYPE_LAST) { + hard_ctx->is_last = TD_TRUE; + } else { + hard_ctx->is_last = TD_FALSE; + } + + return CRYPTO_SUCCESS; +} + +td_s32 hal_cipher_hash_start(td_u32 chn_num, td_bool is_wait) +{ + td_u32 ptr; + in_hash_chn_node_wr_point in_node_wr_ptr; + hal_hash_hard_chn_ctx *hard_ctx = TD_NULL; + crypto_hal_func_enter(); + + hard_ctx = &g_hash_hard_ctx[chn_num]; + + if (hard_ctx->wait_func != TD_NULL && is_wait) { + hard_ctx->done = TD_FALSE; + hard_ctx->is_wait = TD_TRUE; + inner_hash_irq_enable(chn_num, TD_TRUE); + } else { + hard_ctx->is_wait = TD_FALSE; + inner_hash_irq_enable(chn_num, TD_FALSE); + } + + /* configure in-node, only compute one nodes */ + in_node_wr_ptr.u32 = spacc_reg_read(IN_HASH_CHN_NODE_WR_POINT(chn_num)); + + ptr = in_node_wr_ptr.bits.hash_chn_node_wr_point + 1; + in_node_wr_ptr.bits.hash_chn_node_wr_point = ptr % hard_ctx->idx_cnt; + + /* make sure all the above explicit memory accesses and instructions are completed + * before start the hardware. + */ + crypto_memory_barrier(); + crypto_cache_flush((uintptr_t)hard_ctx->entry_in, HASH_NODE_SIZE); + /* Start */ + spacc_reg_write(IN_HASH_CHN_NODE_WR_POINT(chn_num), in_node_wr_ptr.u32); + + crypto_hal_func_exit(); + return TD_SUCCESS; +} + +static td_bool hal_hash_condition(const td_void *param) +{ + hal_hash_hard_chn_ctx *hard_ctx = TD_NULL; + td_u32 chn_num = *(td_u32 *)param; + + hard_ctx = &g_hash_hard_ctx[chn_num]; + if (hard_ctx->done == TD_TRUE) { + hard_ctx->done = TD_FALSE; + return TD_TRUE; + } else { + return TD_FALSE; + } +} + +#define CRYPTO_HAL_HASH_CALC_TIMEOUT (2000) +static td_s32 inner_hash_wait_chain_done(td_u32 chn_num, hal_hash_hard_chn_ctx *hard_ctx) +{ + td_s32 ret = TD_SUCCESS; + td_u32 i; + + if ((hard_ctx->is_wait == TD_TRUE) && (hard_ctx->wait_func != TD_NULL)) { + ret = hard_ctx->wait_func(hard_ctx->wait, hal_hash_condition, (td_void *)(&chn_num), hard_ctx->timeout_ms); + if (ret <= 0) { + crypto_log_err("wait_func Timeout!\n"); + ret = HASH_COMPAT_ERRNO(ERROR_HASH_CALC_TIMEOUT); + } + } else { + for (i = 0; i < CRYPTO_HAL_HASH_CALC_TIMEOUT; i++) { + if (hal_cipher_hash_done_try(chn_num) != 0) { + break; + } + if (i <= MS_TO_US) { + crypto_udelay(1); /* short waitting for 1000 us */ + } else { + crypto_msleep(1); /* long waitting for 5000 ms */ + } + } + if (i >= CRYPTO_HAL_HASH_CALC_TIMEOUT) { + crypto_log_err("hash wait done timeout, chn=%d\n", chn_num); + ret = HASH_COMPAT_ERRNO(ERROR_HASH_CALC_TIMEOUT); + } + } + return ret; +} + +static td_s32 inner_hash_wait_node_done(td_u32 chn_num) +{ + td_u32 i; + td_u32 unproc_data_len = 0; + in_hash_chn_node_wr_point hash_wr_ptr = { 0 }; + in_hash_chn_node_rd_point hash_rd_ptr = { 0 }; + + for (i = 0; i < CRYPTO_HAL_HASH_CALC_TIMEOUT; i++) { + hash_rd_ptr.u32 = spacc_reg_read(IN_HASH_CHN_NODE_RD_POINT(chn_num)); + hash_wr_ptr.u32 = spacc_reg_read(IN_HASH_CHN_NODE_WR_POINT(chn_num)); + if (hash_rd_ptr.u32 == hash_wr_ptr.u32) { + break; + } + if (i <= MS_TO_US) { + crypto_udelay(1); /* short waitting for 1000 us */ + } else { + crypto_msleep(1); /* long waitting for 5000 ms */ + } + } + + if (i >= CRYPTO_HAL_HASH_CALC_TIMEOUT) { + return HASH_COMPAT_ERRNO(ERROR_HASH_CALC_TIMEOUT); + } + + // After the value of the read pointer is increased by 1, wait a microsecond to ensure that the + // value of IN_HASH_CHN_DATA_LEN is switched from 0 to the actual unprocessed data length. + crypto_udelay(1); + for (i = 0; i < CRYPTO_HAL_HASH_CALC_TIMEOUT; i++) { + unproc_data_len = spacc_reg_read(IN_HASH_CHN_DATA_LEN(chn_num)); + if (unproc_data_len == 0) { + break; + } + if (i <= MS_TO_US) { + crypto_udelay(1); /* short waitting for 1000 us */ + } else { + crypto_msleep(1); /* long waitting for 5000 ms */ + } + } + if (i >= CRYPTO_HAL_HASH_CALC_TIMEOUT) { + return HASH_COMPAT_ERRNO(ERROR_HASH_CALC_TIMEOUT); + } + + return CRYPTO_SUCCESS; +} + +td_s32 hal_cipher_hash_wait_done(td_u32 chn_num, td_u32 *state, td_u32 state_size) +{ + td_u32 i; + td_s32 ret = TD_SUCCESS; + hal_hash_hard_chn_ctx *hard_ctx = TD_NULL; + crypto_hal_func_enter(); + + crypto_chk_return(state_size > CRYPTO_HASH_RESULT_SIZE_MAX, HASH_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "state_size is invalid\n"); + + hard_ctx = &g_hash_hard_ctx[chn_num]; + + if (hard_ctx->is_last) { + ret = inner_hash_wait_chain_done(chn_num, hard_ctx); + } else { + ret = inner_hash_wait_node_done(chn_num); + } + inner_hash_irq_enable(chn_num, TD_FALSE); + if (ret == HASH_COMPAT_ERRNO(ERROR_HASH_CALC_TIMEOUT)) { + hal_hash_debug(); + hal_hash_debug_chn(chn_num); + } else { + ret = CRYPTO_SUCCESS; + } + + /* read hash result */ + if (state != TD_NULL) { + for (i = 0; i < state_size / CRYPTO_WORD_WIDTH; i++) { + spacc_reg_write(CHANN_HASH_STATE_VAL_ADDR(chn_num), i); + state[i] = spacc_reg_read(CHANN_HASH_STATE_VAL(chn_num)); + } + } + + crypto_hal_func_exit(); + return ret; +} + +#if defined(CRYPTO_OS_INT_SUPPORT) +td_s32 hal_cipher_hash_register_wait_func(td_u32 chn_num, td_void *wait, + crypto_wait_timeout_interruptible wait_func, td_u32 timeout_ms) +{ + hal_hash_hard_chn_ctx *hard_ctx = TD_NULL; + crypto_hal_func_enter(); + + hard_ctx = &g_hash_hard_ctx[chn_num]; + hard_ctx->wait = wait; + hard_ctx->wait_func = wait_func; + hard_ctx->timeout_ms = timeout_ms; + + crypto_hal_func_exit(); + return TD_SUCCESS; +} + +td_s32 hal_cipher_hash_done_notify(td_u32 chn_num) +{ + hal_hash_hard_chn_ctx *hard_ctx = TD_NULL; + crypto_hal_func_enter(); + + hard_ctx = &g_hash_hard_ctx[chn_num]; + hard_ctx->done = TD_TRUE; + + crypto_hal_func_exit(); + return TD_SUCCESS; +} +#endif + +td_u32 hal_cipher_hash_done_try(td_u32 chn_num) +{ + hash_chann_raw_int hash_fin_int_raw = { 0 }; + + hash_fin_int_raw.u32 = spacc_reg_read(HASH_CHANN_RAW_INT); + hash_fin_int_raw.u32 &= (0x01 << chn_num); + spacc_reg_write(HASH_CHANN_RAW_INT, hash_fin_int_raw.u32); + + return hash_fin_int_raw.u32; +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/spacc_v4/hal_spacc_reg.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/spacc_v4/hal_spacc_reg.h new file mode 100644 index 00000000..d29b115e --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/spacc_v4/hal_spacc_reg.h @@ -0,0 +1,665 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef HAL_HASH_REG_H +#define HAL_HASH_REG_H + +typedef enum { + SPACC_CPU_IDLE = 0x00000000, + SPACC_CPU_REE = 0x00000001, + SPACC_CPU_TEE = 0x00000002, + SPACC_CPU_PCPU = 0x00000004, + SPACC_CPU_AIDSP = 0x00000005, + SPACC_CPU_INVALID = 0xffffffff +} spacc_cpu_mask; + +#define SPACC_CALC_CRG_CFG (0x8030) + +#define SPACC_IE (0x00000004) + +#define CHN_WHO_USED_CLR(used, chn) (used) &= ~(0x0fU << ((chn) * 4U)) +#define CHN_WHO_USED_SET(used, chn, who) (used) |= (td_u32)(who) << ((td_u32)(chn) * 4U) +#define CHN_WHO_USED_GET(used, chn) ((((used) >> ((chn) * 4U))) & 0x0fU) + +/*! \Define the offset of HASH reg */ +#define SPACC_HASH_CHN_LOCK 0x0040 +#define SPACC_HASH_CHN_CLEAR_REQ 0x0068 +#define SPACC_INT_RAW_HASH_CLEAR_FINISH 0x0014 +#define CHANN_HASH_STATE_VAL_ADDR(id) (0xa004 + (id) * 0x80) +#define CHANN_HASH_STATE_VAL(id) (0xa000 + (id) * 0x80) +#define IN_HASH_CHN_CTRL(id) (0x5100 + ((id) - 1) * 0x100) +#define IN_HASH_CHN_KEY_CTRL(id) (0x5110 + ((id) - 1) * 0x100) +#define IN_HASH_CHN_NODE_START_ADDR_H(id) (0x5120 + ((id) - 1) * 0x100) +#define IN_HASH_CHN_NODE_START_ADDR_L(id) (0x5124 + ((id) - 1) * 0x100) +#define IN_HASH_CHN_NODE_LENGTH(id) (0x512c + ((id) - 1) * 0x100) +#define IN_HASH_CHN_NODE_WR_POINT(id) (0x5130 + ((id) - 1) * 0x100) +#define IN_HASH_CHN_NODE_RD_POINT(id) (0x5134 + ((id) - 1) * 0x100) +#define IN_HASH_CHN_DATA_LEN(id) (0x51C0 + ((id) - 1) * 0x100) +#define HASH_CHANN_RAW_INT 0x8600 +#define HASH_CHANN_RAW_INT_EN 0x8604 +#define TEE_HASH_CALC_CTRL_CHECK_ERR 0x8068 +#define TEE_HASH_CALC_CTRL_CHECK_ERR_STATUS 0x806c +#define REE_HASH_CALC_CTRL_CHECK_ERR 0x8078 +#define REE_HASH_CALC_CTRL_CHECK_ERR_STATUS 0x807c +#define PCPU_HASH_CALC_CTRL_CHECK_ERR 0x8088 +#define PCPU_HASH_CALC_CTRL_CHECK_ERR_STATUS 0x808c +#define AIDSP_HASH_CALC_CTRL_CHECK_ERR 0x8098 +#define AIDSP_HASH_CALC_CTRL_CHECK_ERR_STATUS 0x809c + +#define SYM_CALC_CTRL_CHECK_ERR(cpu) (0x8000 + 0x80 - (cpu) * 0x10) + +#define ENCRYPT 0x5A +#define DECRYPT 0xA5 + +/* ! \Define the offset of Cipher reg */ +#define SPACC_SYM_CHN_LOCK 0x0020 +#define SPACC_INT_RAW_SYM_CLEAR_FINISH 0x0008 +#define SPACC_EN_INT_RAW_SYM_CLEAR_FINISH 0x000c +#define SPACC_SYM_CHN_CLEAR_REQ 0x0060 +#define SPACC_BUS_ERR 0x0200 +#define IN_SYM_CHN_CTRL(id) (0x4100 + ((id) - 1) * 0x100) +#define IN_SYM_OUT_CTRL(id) (0x4104 + ((id) - 1) * 0x100) +#define IN_SYM_CHN_KEY_CTRL(id) (0x4110 + ((id) - 1) * 0x100) +#define IN_SYM_CHN_NODE_START_ADDR_H(id) (0x4120 + ((id) - 1) * 0x100) +#define IN_SYM_CHN_NODE_START_ADDR_L(id) (0x4124 + ((id) - 1) * 0x100) +#define IN_SYM_CHN_NODE_LENGTH(id) (0x412c + ((id) - 1) * 0x100) +#define IN_SYM_CHN_NODE_WR_POINT(id) (0x4130 + ((id) - 1) * 0x100) +#define IN_SYM_CHN_NODE_RD_POINT(id) (0x4134 + ((id) - 1) * 0x100) +#define IN_SYM_CHN_NODE_CTRL(id) (0x4140 + ((id) - 1) * 0x100) +#define DBG_IN_SYM_CHN_RD_ADDR_H(id) (0x41a0 + ((id) - 1) * 0x100) +#define DBG_IN_SYM_CHN_RD_ADDR_L(id) (0x41a4 + ((id) - 1) * 0x100) +#define DBG_IN_SYM_CHN_DATA_LEN(id) (0x41c0 + ((id) - 1) * 0x100) + +#define TEE_SYM_CALC_CTRL_CHECK_ERR 0x8060 +#define TEE_SYM_CALC_CTRL_CHECK_ERR_STATUS 0x8064 +#define REE_SYM_CALC_CTRL_CHECK_ERR 0x8070 +#define REE_SYM_CALC_CTRL_CHECK_ERR_STATUS 0x8074 +#define PCPU_SYM_CALC_CTRL_CHECK_ERR 0x8080 +#define PCPU_SYM_CALC_CTRL_CHECK_ERR_STATUS 0x8084 +#define AIDSP_SYM_CALC_CTRL_CHECK_ERR 0x8090 +#define AIDSP_SYM_CALC_CTRL_CHECK_ERR_STATUS 0x8094 + +#define SYM_CHANN_RAW_INT 0x8610 +#define SYM_CHANN_RAW_INT_EN 0x8614 +#define SYM_CHANN_INT 0x8618 + +#define CHANN_CIPHER_IVOUT(id) (0x9000 + (id) * 0x80) +#define CHANN_CIPHER_DFA_EN(id) (0x9020 + (id) * 0x80) + +#define OUT_SYM_CHAN_RAW_LAST_NODE_INT 0xc000 +#define OUT_SYM_CHAN_RAW_LAST_NODE_INT_EN 0xc004 +#define OUT_SYM_CHAN_LAST_NODE_INT 0xc008 +#define OUT_SYM_CHAN_RAW_LEVEL_INT 0xc010 +#define OUT_SYM_CHAN_RAW_LEVEL_INT_EN 0xc014 +#define OUT_SYM_CHAN_LEVEL_INT 0xc018 + +#define OUT_SYM_CHN_STATUS(id) (0xD004 + ((id) - 1) * 0x100) +#define OUT_SYM_CHN_NODE_START_ADDR_H(id) (0xD020 + ((id) - 1) * 0x100) +#define OUT_SYM_CHN_NODE_START_ADDR_L(id) (0xD024 + ((id) - 1) * 0x100) +#define OUT_SYM_CHN_NODE_LENGTH(id) (0xD028 + ((id) - 1) * 0x100) +#define OUT_SYM_CHN_NODE_WR_POINT(id) (0xD030 + ((id) - 1) * 0x100) +#define OUT_SYM_CHN_NODE_RD_POINT(id) (0xD034 + ((id) - 1) * 0x100) +#define OUT_SYM_CHN_NODE_CTRL(id) (0xD040 + ((id) - 1) * 0x100) +#define DBG_OUT_SYM_CHN_RD_ADDR_H(id) (0xD0a0 + ((id) - 1) * 0x100) +#define DBG_OUT_SYM_CHN_RD_ADDR_L(id) (0xD0a4 + ((id) - 1) * 0x100) +#define DBG_OUT_SYM_CHN_NODE_LEFT_BUF_LEN(id) (0xD0a8 + ((id) - 1) * 0x100) + +#define IN_SYM_CHN0_CTRL 0x4000 +#define IN_SYM_CHN0_SPECIAL_CTRL 0x4004 +#define IN_SYM_CHN0_KEY_CTRL 0x4010 +#define IN_SYM_CHN0_IV_DATA_CTRL 0x4030 +#define IN_SYM_CHN0_IV0 0x4040 +#define IN_SYM_CHN0_IV1 0x4044 +#define IN_SYM_CHN0_IV2 0x4048 +#define IN_SYM_CHN0_IV3 0x404C +#define IN_SYM_CHN0_DATA0 0x4050 +#define IN_SYM_CHN0_DATA1 0x4054 +#define IN_SYM_CHN0_DATA2 0x4058 +#define IN_SYM_CHN0_DATA3 0x405C +#define CHAN0_CIPHER_DOUT0 0x8100 + +#define SYMC_KEY_SIZE (32) +#define NODE_DEPTH (2) + +#define SYMC_CFG_SECURE (0x05) +#define SYMC_CFG_NON_SECURE (0x0A) + + +#define ALG_DMA_REG (0) +#define ALG_AES_REG (2) +#define ALG_LEA_REG (4) +#define ALG_SM4_REG (5) +#define ALG_GHASH_REG (6) +#define ALG_TDES_REG (7) + +#define MODE_ECB_REG (0x01) +#define MODE_CBC_REG (0x03) +#define MODE_CTR_REG (0x06) +#define MODE_OFB_REG (0x07) +#define MODE_CFB_REG (0x08) +#define MODE_CCM_REG (0x09) +#define MODE_GCM_REG (0x0A) +#define MODE_GCTR_REG (0x0B) +#define MODE_CMAC_REG (0x0C) +#define MODE_CBC_NOOUT_REG (0x0D) +#define MODE_GCTR_NOOUT_REG (0x0E) + +#define BIT_WIDTH_1_REG (2) +#define BIT_WIDTH_8_REG (1) +#define BIT_WIDTH_64_REG (3) +#define BIT_WIDTH_128_REG (3) + +// internal iv state +#define SYMC_IV_STATE_START (0) +#define SYMC_IV_STATE_UPDATE (1) +#define SYMC_IV_STATE_FINISH (2) + +typedef union { + struct { + td_u32 reserved_0 : 8; + td_u32 hash_chn_ss : 4; + td_u32 reserved_1 : 19; + td_u32 hash_chn_en : 1; + } bits; + td_u32 u32; +} in_hash_chn_ctrl; + +typedef union { + struct { + td_u32 hash_key_chn_id : 4; + td_u32 reserved_0 : 5; + td_u32 hmac_vld : 1; + td_u32 reserved_1 : 6; + td_u32 hash_chn_alg_sel : 4; + td_u32 hash_chn_alg_mode : 4; + td_u32 reserved_2 : 8; + } bits; + td_u32 u32; +} in_hash_chn_key_ctrl; + +// Define the union in_hash_chn_node_wr_point +typedef union { + // Define the struct bits + struct { + td_u32 hash_chn_node_wr_point : 8; // [7..0] + td_u32 reserved_0 : 24; // [31..8] + } bits; + + // Define an unsigned member + td_u32 u32; +} in_hash_chn_node_wr_point; + +// Define the union in_hash_chn_node_wr_point +typedef union { + // Define the struct bits + struct { + td_u32 hash_chn_node_rd_point : 8; // [7..0] + td_u32 reserved_0 : 24; // [31..8] + } bits; + + // Define an unsigned member + td_u32 u32; +} in_hash_chn_node_rd_point; + +// Define the union hash_chann_raw_int +typedef union { + // Define the struct bits + struct { + td_u32 hash_chann_raw_int : 16; // [15..0] + td_u32 reserved_0 : 16; // [31..16] + } bits; + + // Define an unsigned member + td_u32 u32; +} hash_chann_raw_int; + +// Define the union tee_hash_calc_ctrl_check_err +typedef union { + // Define the struct bits + struct { + td_u32 reserved_0 : 1; + td_u32 hash_check_ss_error : 1; + td_u32 hash_check_alg_error : 1; + td_u32 hash_check_alg_invld_error : 1; + td_u32 reserved_1 : 2; + td_u32 hash_check_sc_error : 1; + td_u32 reserved_2 : 6; + td_u32 hash_check_sm3_disable_error : 1; + td_u32 hash_check_sha1_disable_error : 1; + td_u32 reserved_3 : 2; + td_u32 hash_tonly_error : 1; + td_u32 hash_aidsp_error : 1; + td_u32 reserved_4 : 13; + } bits; + + // Define an unsigned member + td_u32 u32; +} hash_calc_ctrl_check_err; + +// Define the union tee_hash_calc_ctrl_check_err +typedef union { + // Define the struct bits + struct { + td_u32 hash_error_code_clr : 1; + td_u32 reserved_0 : 15; + td_u32 error_hash_chan_id : 4; + td_u32 reserved_1 : 12; + } bits; + + // Define an unsigned member + td_u32 u32; +} hash_calc_ctrl_check_err_status; + +/* Define the union in_sym_out_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + td_u32 sym_dma_copy : 2; /* [1..0] */ + td_u32 reserved : 30; /* [31..2] */ + } bits; + /* Define an unsigned member */ + td_u32 u32; +} in_sym_out_ctrl; + +/* Define the union in_sym_chn_key_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + td_u32 sym_key_chn_id : 9; /* [8..0] */ + td_u32 reserved : 7; /* [15..9] */ + td_u32 sym_alg_sel : 4; /* [19..16] */ + td_u32 sym_alg_mode : 4; /* [23..20] */ + td_u32 sym_alg_key_len : 2; /* [25..24] */ + td_u32 sym_alg_data_width : 2; /* [27..26] */ + td_u32 sym_alg_decrypt : 1; /* [28] */ + td_u32 reserved_2 : 3; /* [31..29] */ + } bits; + /* Define an unsigned member */ + td_u32 u32; +} in_sym_chn_key_ctrl; + +/* Define the union in_sym_chn_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + td_u32 reserved : 8; /* [7..0] */ + td_u32 sym_chn_ss : 4; /* [8..11] */ + td_u32 sym_chn_ds : 4; /* [12..15] */ + td_u32 reserved_2 : 15; /* [30..16] */ + td_u32 sym_chn_en : 1; /* [31] */ + } bits; + /* Define an unsigned member */ + td_u32 u32; +} in_sym_chn_ctrl; + +/* Define the union in_sym_chn0_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + td_u32 reserved : 31; /* [30..0] */ + td_u32 sym_chn0_req : 1; /* [31] */ + } bits; + /* Define an unsigned member */ + td_u32 u32; +} in_sym_chn0_ctrl; + +/* Define the union in_sym_chn0_special_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + td_u32 sym_chn0_odd_even : 1; /* [0] */ + td_u32 reserved : 31; /* [31..1] */ + } bits; + /* Define an unsigned member */ + td_u32 u32; +} in_sym_chn0_special_ctrl; + +/* Define the union in_sym_chn0_iv_data_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + td_u32 sym_chn0_first_block : 1; /* [0] */ + td_u32 sym_chn0_last_block : 1; /* [1] */ + td_u32 reserved : 14; /* [15..2] */ + td_u32 sym_chn0_block_len : 5; /* [20..16] */ + td_u32 reserved2 : 11; /* [31..21] */ + } bits; + /* Define an unsigned member */ + td_u32 u32; +} in_sym_chn0_iv_data_ctrl; + +/* Define the union out_sym_chan_raw_int */ +typedef union { + /* Define the struct bits */ + struct { + td_u32 out_sym_chan_raw_int : 16; /* [15..0] */ + td_u32 reserved_1 : 16; /* [31..16] */ + } bits; + /* Define an unsigned member */ + td_u32 u32; +} out_sym_chan_raw_int; + +/* Define the union out_sym_chan_raw_int_en */ +typedef union { + /* Define the struct bits */ + struct { + u32 out_sym_chan_int_en : 16; /* [15..1] */ + u32 reserved_1 : 16; /* [31..16] */ + } bits; + /* Define an unsigned member */ + u32 u32; +} out_sym_chan_raw_int_en; + +/* Define the union out_sym_chn_status */ +typedef union { + /* Define the struct bits */ + struct { + u32 out_sym_chn_int_status : 16; /* [15..1] */ + u32 reserved_1 : 16; /* [31..16] */ + } bits; + /* Define an unsigned member */ + u32 u32; +} out_sym_chn_status; + +/* Define the union out_sym_chn_node_wr_point */ +typedef union { + /* Define the struct bits */ + struct { + td_u32 sym_chn_node_wr_point : 8; /* [7..0] */ + td_u32 reserved_1 : 24; /* [31..8] */ + } bits; + /* Define an unsigned member */ + td_u32 u32; +} out_sym_chn_node_wr_point; + +/* Define the union out_sym_chn_node_wr_point */ +typedef union { + /* Define the struct bits */ + struct { + td_u32 sym_chn_node_wr_point : 8; /* [7..0] */ + td_u32 reserved_1 : 24; /* [31..8] */ + } bits; + /* Define an unsigned member */ + td_u32 u32; +} in_sym_chn_node_wr_point; + +/* Define the union out_sym_chn_node_rd_point */ +typedef union { + /* Define the struct bits */ + struct { + td_u32 sym_chn_node_rd_point : 8; /* [7..0] */ + td_u32 reserved_1 : 24; /* [31..8] */ + } bits; + /* Define an unsigned member */ + td_u32 u32; +} out_sym_chn_node_rd_point; + +/* Define the union out_sym_chn_node_rd_point */ +typedef union { + /* Define the struct bits */ + struct { + td_u32 sym_chn_node_rd_point : 8; /* [7..0] */ + td_u32 reserved_1 : 24; /* [31..8] */ + } bits; + /* Define an unsigned member */ + td_u32 u32; +} in_sym_chn_node_rd_point; + +/* Define the union in_sym_chn_node_length */ +typedef union { + /* Define the struct bits */ + struct { + td_u32 sym_chn_node_length : 8; /* [7..0] */ + td_u32 reserved_1 : 24; /* [31..8] */ + } bits; + /* Define an unsigned member */ + td_u32 u32; +} in_sym_chn_node_length; + +/* Define the union out_sym_chn_node_length */ +typedef union { + /* Define the struct bits */ + struct { + td_u32 sym_chn_node_length : 8; /* [7..0] */ + td_u32 reserved_1 : 24; /* [31..8] */ + } bits; + /* Define an unsigned member */ + td_u32 u32; +} out_sym_chn_node_length; + +/* Define the union dbg_in_sym_chn_rd_addr_h */ +typedef union { + /* Define the struct bits */ + struct { + td_u32 dbg_sym_chn_rd_addr_h : 4; /* [3..0] */ + td_u32 reserved : 28; /* [31..4] */ + } bits; + /* Define an unsigned member */ + td_u32 u32; +} dbg_in_sym_chn_rd_addr_h; + +/* Define the union dbg_out_sym_chn_rd_addr_h */ +typedef union { + /* Define the struct bits */ + struct { + td_u32 dbg_sym_chn_rd_addr_h : 4; /* [3..0] */ + td_u32 reserved : 28; /* [31..4] */ + } bits; + /* Define an unsigned member */ + td_u32 u32; +} dbg_out_sym_chn_rd_addr_h; + +/* Define the union sym_calc_ctrl_check_err */ +typedef union { + /* Define the struct bits */ + struct { + td_u32 calc_ctrl_check_ds_error : 1; /* [0] */ + td_u32 calc_ctrl_check_ss_error : 1; /* [1] */ + td_u32 calc_ctrl_check_alg_error : 1; /* [2] */ + td_u32 calc_ctrl_check_alg_invld_error : 1; /* [3] */ + td_u32 calc_ctrl_check_dec_error : 1; /* [4] */ + td_u32 reserved0 : 1; /* [5] */ + td_u32 calc_ctrl_check_sc_error : 1; /* [6] */ + td_u32 calc_ctrl_check_key_size_error : 1; /* [7] */ + td_u32 reserved : 8; /* [15..8] */ + td_u32 calc_ctrl_big_key_info_diff_error : 1; /* [16] */ + td_u32 calc_ctrl_tonly_error : 1; /* [17] */ + td_u32 calc_ctrl_aidsp_error : 1; /* [18] */ + td_u32 reserved2 : 13; /* [31..19] */ + } bits; + /* Define an unsigned member */ + td_u32 u32; +} sym_calc_ctrl_check_err; + +/* Define the union sym_calc_ctrl_check_err_status */ +typedef union { + /* Define the struct bits */ + struct { + td_u32 sym_error_code_clr : 1; /* [0] */ + td_u32 reserved : 15; /* [15..1] */ + td_u32 error_sym_chan_id : 4; /* [19..16] */ + td_u32 reserved1 : 12; /* [31..20] */ + } bits; + /* Define an unsigned member */ + td_u32 u32; +} sym_calc_ctrl_check_err_status; + +/* Define the union in_sym_chn_node_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + td_u32 sym_chn_node_level : 8; /* [7..0] */ + td_u32 reserved_0 : 8; /* [15..8] */ + td_u32 sym_chn_node_cnt : 8; /* [23..16] */ + td_u32 reserved_1 : 7; /* [30..24] */ + td_u32 sym_chn_node_cnt_clear : 1; /* [31] */ + } bits; + /* Define an unsigned member */ + td_u32 u32; +} in_sym_chn_node_ctrl; + +/* Define the union out_sym_chn_node_ctrl */ +typedef union { + /* Define the struct bits */ + struct { + td_u32 out_sym_chn_node_level : 8; /* [7..0] */ + td_u32 reserved_0 : 24; /* [31..8] */ + } bits; + /* Define an unsigned member */ + td_u32 u32; +} out_sym_chn_node_ctrl; + +/* Define the union spacc_sym_chn_clear_req */ +typedef union { + /* Define the struct bits */ + struct { + td_u32 sym_chn_clear_req : 16; /* [15..0] */ + td_u32 reserved_0 : 16; /* [31..16] */ + } bits; + /* Define an unsigned member */ + td_u32 u32; +} spacc_sym_chn_clear_req; + +/* Define the union spacc_int_raw_sym_clear_finish */ +typedef union { + /* Define the struct bits */ + struct { + td_u32 int_raw_sym_clear_finish : 16; /* [15..0] */ + td_u32 reserved_0 : 16; /* [31..16] */ + } bits; + /* Define an unsigned member */ + td_u32 u32; +} spacc_int_raw_sym_clear_finish; + +/* Define the union sym_chann_raw_int */ +typedef union { + /* Define the struct bits */ + struct { + td_u32 sym_chann_raw_int : 16; /* [0] */ + td_u32 reserved_0 : 16; /* [31..16] */ + } bits; + /* Define an unsigned member */ + td_u32 u32; +} sym_chann_raw_int; + +/* Define the union sym_chann_raw_int_en */ +typedef union { + /* Define the struct bits */ + struct { + td_u32 sym_chann_int_en : 16; /* [0] */ + td_u32 reserved_0 : 16; /* [31..16] */ + } bits; + /* Define an unsigned member */ + td_u32 u32; +} sym_chann_raw_int_en; + +/* Define the union sym_chann_int */ +typedef union { + /* Define the struct bits */ + struct { + td_u32 sym_chann_int : 16; /* [0] */ + td_u32 reserved_0 : 16; /* [31..16] */ + } bits; + /* Define an unsigned member */ + td_u32 u32; +} sym_chann_int; + +/* Define the union sym_chan0_finish_raw_int */ +typedef union { + /* Define the struct bits */ + struct { + td_u32 sym_chan0_finish_raw_int : 1; /* [0] */ + td_u32 reserved_0 : 31; /* [31..1] */ + } bits; + /* Define an unsigned member */ + td_u32 u32; +} sym_chan0_finish_raw_int; + +/* Define the union sym_chan0_finish_raw_int_en */ +typedef union { + /* Define the struct bits */ + struct { + td_u32 sym_chan0_finish_int_en : 1; /* [0] */ + td_u32 reserved_0 : 31; /* [31..1] */ + } bits; + /* Define an unsigned member */ + td_u32 u32; +} sym_chan0_finish_raw_int_en; + +/* Define the union sym_chan0_finish_int */ +typedef union { + /* Define the struct bits */ + struct { + td_u32 sym_chan0_finish_int : 1; /* [0] */ + td_u32 reserved_0 : 31; /* [31..1] */ + } bits; + /* Define an unsigned member */ + td_u32 u32; +} sym_chan0_finish_int; + +/* Define the union sym_chann_error_raw_int */ +typedef union { + /* Define the struct bits */ + struct { + td_u32 sym_chan_raw_err_int : 16; /* [0] */ + td_u32 reserved_0 : 16; /* [31..16] */ + } bits; + /* Define an unsigned member */ + td_u32 u32; +} sym_chann_error_raw_int; + +/* Define the union sym_chann_error_raw_int_en */ +typedef union { + /* Define the struct bits */ + struct { + td_u32 sym_chan_err_int_en : 16; /* [0] */ + td_u32 reserved_0 : 16; /* [31..16] */ + } bits; + /* Define an unsigned member */ + td_u32 u32; +} sym_chann_error_raw_int_en; + +typedef union { + struct { + td_u32 chann_dfa_en : 4; /* [3..0] */ + td_u32 reserved : 28; /* [31..4] */ + } bits; + td_u32 u32; +} symc_chann_dfa_en; + +/* Define the union sym_chann_error_int */ +typedef union { + /* Define the struct bits */ + struct { + td_u32 sym_chan_err_int : 16; /* [0] */ + td_u32 reserved_0 : 16; /* [31..16] */ + } bits; + /* Define an unsigned member */ + td_u32 u32; +} sym_chann_error_int; + +typedef union { + struct { + td_u32 sec_dfa_en : 4; /* [3..0] */ + td_u32 reserved : 28; /* [31..4] */ + } bits; + td_u32 u32; +} spacc_sec_dfa_en; + +/* Define the union spacc_ie */ +typedef union { + /* Define the struct bits */ + struct { + unsigned int spacc_ie_ree : 1; /* [0] */ + unsigned int reserved_0 : 3; /* [3..1] */ + unsigned int spacc_ie_tee : 1; /* [4] */ + unsigned int reserved_1 : 3; /* [7..5] */ + unsigned int spacc_ie_hpp : 1; /* [8] */ + unsigned int reserved_2 : 23; /* [31..9] */ + } bits; + /* Define an unsigned member */ + unsigned int u32; +} spacc_ie; + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/spacc_v4/hal_symc.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/spacc_v4/hal_symc.c new file mode 100644 index 00000000..d1c5448f --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/spacc_v4/hal_symc.c @@ -0,0 +1,1859 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "hal_symc.h" +#include "hal_spacc_reg.h" + +#include "crypto_drv_common.h" + +#ifndef crypto_memory_barrier +#define crypto_memory_barrier() +#endif + +/* current cpu */ +#define SPACC_CPU_CUR ((crypto_get_cpu_type() == CRYPTO_CPU_TYPE_SCPU) ? SPACC_CPU_TEE : SPACC_CPU_REE) + +/* ! \Numbers of nodes list */ +#define CRYPTO_SYMC_MAX_LIST_NUM 2 + +#define CRYPTO_SYMC_IN_NODE_SIZE (sizeof(crypto_symc_entry_in) * CRYPTO_SYMC_MAX_LIST_NUM) +#define CRYPTO_SYMC_OUT_NODE_SIZE (sizeof(crypto_symc_entry_out) * CRYPTO_SYMC_MAX_LIST_NUM) +#define CRYPTO_SYMC_NODE_SIZE (CRYPTO_SYMC_IN_NODE_SIZE + CRYPTO_SYMC_OUT_NODE_SIZE) +#define CRYPTO_SYMC_NODE_LIST_SIZE (CRYPTO_SYMC_NODE_SIZE * CRYPTO_SYMC_HARD_CHANNEL_MAX) +#define CRYPTO_SYMC_WAIT_TIMEOUT (6000000) + +#define CRYPTO_SYMC_DFA_ENABLE_VAL 0x1 +#define CRYPTO_SYMC_DFA_DISABLE_VAL 0xa + +#define CACHE_LINE_SIZE 32 +#define SYMC_COMPAT_ERRNO(err_code) HAL_COMPAT_ERRNO(ERROR_MODULE_SYMC, err_code) + +/* ! spacc symc int entry struct which is defined by hardware, you can't change it */ +typedef struct { + td_u32 sym_first_node : 1; /* !< Indicates whether the node is the first node */ + td_u32 sym_last_node : 1; /* !< Indicates whether the node is the last node */ + td_u32 rev1 : 7; /* !< reserve */ + td_u32 odd_even : 1; /* !< Indicates whether the key is an odd key or even key */ + td_u32 rev2 : 22; /* !< reserve */ + td_u32 sym_alg_length; /* !< symc data length */ + td_u32 sym_start_addr; /* !< symc start low addr */ + td_u32 sym_start_high; /* !< symc start high addr */ + td_u32 iv[CRYPTO_AES_IV_SIZE_IN_WORD]; /* !< symc IV */ +} crypto_symc_entry_in; + +/* ! spacc symc out entry struct which is defined by hardware, you can't change it */ +typedef struct { + td_u32 rev1; /* !< reserve */ + td_u32 sym_alg_length; /* !< syma data length */ + td_u32 sym_start_addr; /* !< syma start low addr */ + td_u32 sym_start_high; /* !< syma start high addr */ +} crypto_symc_entry_out; + +typedef struct { + crypto_symc_entry_in *entry_in; + crypto_symc_entry_out *entry_out; + td_u32 idx_in; + td_u32 idx_out; + td_u32 cnt_in; + td_u32 cnt_out; + td_void *wait; + crypto_wait_timeout_interruptible wait_func; + td_bool done; + td_bool is_wait; + td_u32 timeout_ms; + td_u8 iv_ctr[CRYPTO_AES_IV_SIZE]; + td_u8 gcm_iv[CRYPTO_AES_IV_SIZE]; + td_phys_addr_t gcm_len_addr; + hal_symc_config_t symc_config; +} crypto_symc_hard_context; + +#if defined(CRYPTO_CONFIG_ROMBOOT_ENV) +static td_u8 g_symc_node_buffer[CRYPTO_SYMC_NODE_LIST_SIZE]; +#endif + +static crypto_symc_hard_context g_symc_hard_context[CRYPTO_SYMC_HARD_CHANNEL_MAX]; +static td_s32 hal_cipher_symc_ccm_mac_update(td_u32 chn_num, td_phys_addr_t data_phys_addr, td_u32 data_len, + in_node_type_e in_node_type); +static td_s32 hal_cipher_symc_gcm_mac_update(td_u32 chn_num, td_phys_addr_t data_phys_addr, td_u32 data_len, + in_node_type_e in_node_type); + +#define CRYPTO_SYMC_CLEAR_TIMEOUT 6000 + +static td_s32 hal_cipher_symc_out_node_done_try(td_u32 chn_num); + +#if defined(CONFIG_SYMC_TIMEOUT_DEBUG) +static td_s32 hal_cipher_symc_debug(td_void) +{ + crypto_print("CRYPTO_SYMC_IN_NODE_SIZE is 0x%x\n", CRYPTO_SYMC_IN_NODE_SIZE); + crypto_print("CRYPTO_SYMC_OUT_NODE_SIZE is 0x%x\n", CRYPTO_SYMC_OUT_NODE_SIZE); + crypto_print("CRYPTO_SYMC_NODE_SIZE is 0x%x\n", CRYPTO_SYMC_NODE_SIZE); + crypto_print("CRYPTO_SYMC_NODE_LIST_SIZE is 0x%x\n", CRYPTO_SYMC_NODE_LIST_SIZE); + crypto_print("SPACC_IE is 0x%x\n", spacc_reg_read(SPACC_IE)); + crypto_print("SPACC_SYMC_CHN_LOCK is 0x%x\n", spacc_reg_read(SPACC_SYM_CHN_LOCK)); + crypto_print("OUT_SYM_CHAN_RAW_LAST_NODE_INT is 0x%x\n", spacc_reg_read(OUT_SYM_CHAN_RAW_LAST_NODE_INT)); + crypto_print("OUT_SYM_CHAN_RAW_LAST_NODE_INT_EN is 0x%x\n", spacc_reg_read(OUT_SYM_CHAN_RAW_LAST_NODE_INT_EN)); + crypto_print("OUT_SYM_CHAN_RAW_LEVEL_INT is 0x%x\n", spacc_reg_read(OUT_SYM_CHAN_RAW_LEVEL_INT)); + crypto_print("SYM_CHANN_RAW_INT is 0x%x\n", spacc_reg_read(SYM_CHANN_RAW_INT)); + crypto_print("SYM_CHANN_RAW_INT_EN is 0x%x\n", spacc_reg_read(SYM_CHANN_RAW_INT_EN)); + crypto_print("TEE_SYM_CALC_CTRL_CHECK_ERR is 0x%x\n", spacc_reg_read(TEE_SYM_CALC_CTRL_CHECK_ERR)); + crypto_print("REE_SYM_CALC_CTRL_CHECK_ERR is 0x%x\n", spacc_reg_read(REE_SYM_CALC_CTRL_CHECK_ERR)); + crypto_print("TEE_SYM_CALC_CTRL_CHECK_ERR_STATUS is 0x%x\n", spacc_reg_read(TEE_SYM_CALC_CTRL_CHECK_ERR_STATUS)); + crypto_print("REE_SYM_CALC_CTRL_CHECK_ERR_STATUS is 0x%x\n", spacc_reg_read(REE_SYM_CALC_CTRL_CHECK_ERR_STATUS)); + + return TD_SUCCESS; +} + +static td_void hal_cipher_symc_print_entry_in(const crypto_symc_entry_in *entry_in) +{ + crypto_unused(entry_in); + crypto_print("The Details of Entry In:\n"); + crypto_print("sym_first_node is 0x%x\n", entry_in->sym_first_node); + crypto_print("sym_last_node is 0x%x\n", entry_in->sym_last_node); + crypto_print("odd_even is 0x%x\n", entry_in->odd_even); + crypto_print("sym_alg_length is 0x%x\n", entry_in->sym_alg_length); + crypto_print("sym_start_addr is 0x%x\n", entry_in->sym_start_addr); + crypto_print("sym_start_high is 0x%x\n", entry_in->sym_start_high); + crypto_dump_data("iv", (td_u8 *)entry_in->iv, sizeof(entry_in->iv)); +} + +static td_void hal_cipher_symc_print_entry_out(const crypto_symc_entry_out *entry_in) +{ + crypto_unused(entry_in); + crypto_print("The Details of Entry Out:\n"); + crypto_print("sym_alg_length is 0x%x\n", entry_in->sym_alg_length); + crypto_print("sym_start_addr is 0x%x\n", entry_in->sym_start_addr); + crypto_print("sym_start_high is 0x%x\n", entry_in->sym_start_high); +} + +static td_s32 hal_cipher_symc_debug_chn(td_u32 chn_num) +{ + crypto_symc_hard_context *hard_ctx = TD_NULL; + crypto_symc_entry_in *entry_in = TD_NULL; + crypto_symc_entry_out *entry_out = TD_NULL; + td_u32 i; + td_u8 iv[CRYPTO_IV_LEN_IN_BYTES] = {0}; + + hard_ctx = &g_symc_hard_context[chn_num]; + entry_in = hard_ctx->entry_in; + entry_out = hard_ctx->entry_out; + + crypto_print("The Status of SYMC CHN %u:\n", chn_num); + crypto_print("IN_SYM_CHN_NODE_START_ADDR_L is 0x%x\n", spacc_reg_read(IN_SYM_CHN_NODE_START_ADDR_L(chn_num))); + crypto_print("IN_SYM_CHN_NODE_START_ADDR_H is 0x%x\n", spacc_reg_read(IN_SYM_CHN_NODE_START_ADDR_H(chn_num))); + crypto_print("IN_SYM_CHN_NODE_LENGTH is 0x%x\n", spacc_reg_read(IN_SYM_CHN_NODE_LENGTH(chn_num))); + + crypto_print("OUT_SYM_CHN_NODE_START_ADDR_L is 0x%x\n", spacc_reg_read(OUT_SYM_CHN_NODE_START_ADDR_L(chn_num))); + crypto_print("OUT_SYM_CHN_NODE_START_ADDR_H is 0x%x\n", spacc_reg_read(OUT_SYM_CHN_NODE_START_ADDR_H(chn_num))); + crypto_print("OUT_SYM_CHN_NODE_LENGTH is 0x%x\n", spacc_reg_read(OUT_SYM_CHN_NODE_LENGTH(chn_num))); + + crypto_print("IN_SYM_CHN_CTRL is 0x%x\n", spacc_reg_read(IN_SYM_CHN_CTRL(chn_num))); + crypto_print("IN_SYM_OUT_CTRL is 0x%x\n", spacc_reg_read(IN_SYM_OUT_CTRL(chn_num))); + crypto_print("IN_SYM_CHN_KEY_CTRL is 0x%x\n", spacc_reg_read(IN_SYM_CHN_KEY_CTRL(chn_num))); + + crypto_print("OUT_SYM_CHN_NODE_WR_POINT is 0x%x\n", spacc_reg_read(OUT_SYM_CHN_NODE_WR_POINT(chn_num))); + crypto_print("OUT_SYM_CHN_NODE_RD_POINT is 0x%x\n", spacc_reg_read(OUT_SYM_CHN_NODE_RD_POINT(chn_num))); + + crypto_print("IN_SYM_CHN_NODE_WR_POINT is 0x%x\n", spacc_reg_read(IN_SYM_CHN_NODE_WR_POINT(chn_num))); + crypto_print("IN_SYM_CHN_NODE_RD_POINT is 0x%x\n", spacc_reg_read(IN_SYM_CHN_NODE_RD_POINT(chn_num))); + + for (i = 0; i < CRYPTO_SYMC_MAX_LIST_NUM; i++) { + crypto_print("IDX_IN %u:\n", i); + hal_cipher_symc_print_entry_in(&entry_in[i]); + } + for (i = 0; i < CRYPTO_SYMC_MAX_LIST_NUM; i++) { + crypto_print("IDX_OUT %u:\n", i); + hal_cipher_symc_print_entry_out(&entry_out[i]); + } + + hal_cipher_symc_get_iv(chn_num, iv, sizeof(iv)); + crypto_dump_data("Current IV", iv, sizeof(iv)); + + return TD_SUCCESS; +} +#else +#define hal_cipher_symc_debug(...) +#define hal_cipher_symc_debug_chn(...) +#endif + +static void inner_symc_irq_enable(td_u8 chn_num, td_bool enable) +{ + td_u32 reg_val; + + reg_val = spacc_reg_read(OUT_SYM_CHAN_RAW_LAST_NODE_INT_EN); + if (enable == TD_TRUE) { + reg_val |= (1 << chn_num); + } else { + reg_val &= ~(1 << chn_num); + } + spacc_reg_write(OUT_SYM_CHAN_RAW_LAST_NODE_INT_EN, reg_val); +} + +static void inner_symc_int_raw_enable(td_u8 chn_num, td_bool enable) +{ + td_u32 reg_val; + + reg_val = spacc_reg_read(SYM_CHANN_RAW_INT_EN); + if (enable == TD_TRUE) { + reg_val |= (1 << chn_num); + } else { + reg_val &= ~(1 << chn_num); + } + spacc_reg_write(SYM_CHANN_RAW_INT_EN, reg_val); +} + +static td_s32 hal_cipher_symc_clear_channel(td_u32 chn_num) +{ + td_s32 ret = TD_SUCCESS; + td_u32 i; + td_u32 chn_mask; + spacc_sym_chn_clear_req symc_chn_clear = {0}; + spacc_int_raw_sym_clear_finish symc_chn_clear_finish = {0}; + + chn_mask = 0x1 << chn_num; + symc_chn_clear.u32 = spacc_reg_read(SPACC_SYM_CHN_CLEAR_REQ); + symc_chn_clear.bits.sym_chn_clear_req |= chn_mask; + spacc_reg_write(SPACC_SYM_CHN_CLEAR_REQ, symc_chn_clear.u32); + + for (i = 0; i < CRYPTO_SYMC_CLEAR_TIMEOUT; i++) { + symc_chn_clear_finish.u32 = spacc_reg_read(SPACC_INT_RAW_SYM_CLEAR_FINISH); + symc_chn_clear_finish.bits.int_raw_sym_clear_finish &= chn_mask; + if (symc_chn_clear_finish.bits.int_raw_sym_clear_finish != 0) { + spacc_reg_write(SPACC_INT_RAW_SYM_CLEAR_FINISH, symc_chn_clear.u32); + break; + } + if (i <= MS_TO_US) { + crypto_udelay(1); /* short waitting for 1000 us */ + } else { + crypto_msleep(1); /* long waitting for 5000 ms */ + } + } + if (i >= CRYPTO_SYMC_CLEAR_TIMEOUT) { + crypto_log_err("SYMC CHN %u Clear Channel Timeout\n", chn_num); + return TD_FAILURE; + } + inner_symc_int_raw_enable(chn_num, TD_FALSE); + + return ret; +} + +static td_void hal_cipher_symc_dfa_config(td_u32 chn_num, td_bool enable) +{ + symc_chann_dfa_en dfa_en = { 0 }; + + dfa_en.u32 = spacc_reg_read(CHANN_CIPHER_DFA_EN(chn_num)); + if (enable == TD_TRUE) { + dfa_en.bits.chann_dfa_en = CRYPTO_SYMC_DFA_ENABLE_VAL; + } else { + dfa_en.bits.chann_dfa_en = CRYPTO_SYMC_DFA_DISABLE_VAL; + } + spacc_reg_write(CHANN_CIPHER_DFA_EN(chn_num), dfa_en.u32); +} + +static td_void hal_cipher_symc_set_entry_node(td_u32 chn_num, crypto_symc_hard_context *hard_ctx) +{ + in_sym_chn_node_length symc_in_node_length; + out_sym_chn_node_length symc_out_node_length; + td_ulong entry_in_phy = (td_ulong)crypto_get_phys_addr((td_void *)hard_ctx->entry_in); + td_ulong entry_out_phy = (td_ulong)crypto_get_phys_addr((td_void *)hard_ctx->entry_out); + + /* set start addr for cipher in node and node length. */ + spacc_reg_write(IN_SYM_CHN_NODE_START_ADDR_L(chn_num), entry_in_phy); + spacc_reg_write(IN_SYM_CHN_NODE_START_ADDR_H(chn_num), 0); + + symc_in_node_length.u32 = spacc_reg_read(IN_SYM_CHN_NODE_LENGTH(chn_num)); + symc_in_node_length.bits.sym_chn_node_length = CRYPTO_SYMC_MAX_LIST_NUM; + spacc_reg_write(IN_SYM_CHN_NODE_LENGTH(chn_num), symc_in_node_length.u32); + + /* set start addr for cipher out node and node length. */ + spacc_reg_write(OUT_SYM_CHN_NODE_START_ADDR_L(chn_num), entry_out_phy); + spacc_reg_write(OUT_SYM_CHN_NODE_START_ADDR_H(chn_num), 0); + + symc_out_node_length.u32 = spacc_reg_read(OUT_SYM_CHN_NODE_LENGTH(chn_num)); + symc_out_node_length.bits.sym_chn_node_length = CRYPTO_SYMC_MAX_LIST_NUM; + spacc_reg_write(OUT_SYM_CHN_NODE_LENGTH(chn_num), symc_out_node_length.u32); + + hard_ctx->idx_in = 0; + hard_ctx->idx_out = 0; + hard_ctx->cnt_in = 0; + hard_ctx->cnt_out = 0; + (td_void)memset_s(hard_ctx->entry_in, CRYPTO_SYMC_IN_NODE_SIZE, 0, CRYPTO_SYMC_IN_NODE_SIZE); + (td_void)memset_s(hard_ctx->entry_out, CRYPTO_SYMC_OUT_NODE_SIZE, 0, CRYPTO_SYMC_OUT_NODE_SIZE); +} + +static td_s32 hal_cipher_symc_wait_noout_done(td_u32 chn_num) +{ + td_u32 i = 0; + td_s32 ret; + crypto_hal_func_enter(); + + for (i = 0; i < CRYPTO_SYMC_WAIT_TIMEOUT; i++) { + ret = hal_cipher_symc_out_node_done_try(chn_num); + if (ret == TD_SUCCESS) { + break; + } + crypto_udelay(1); + } + + if (i >= CRYPTO_SYMC_WAIT_TIMEOUT) { + ret = SYMC_COMPAT_ERRNO(ERROR_HASH_CALC_TIMEOUT); + } + if (ret == SYMC_COMPAT_ERRNO(ERROR_HASH_CALC_TIMEOUT)) { + crypto_log_err("symc wait done timeout, chn is %u\n", chn_num); + hal_cipher_symc_debug(); + hal_cipher_symc_debug_chn(chn_num); + return ret; + } + + crypto_hal_func_exit(); + return TD_SUCCESS; +} + +static td_s32 priv_set_in_node(td_u32 chn_num, td_phys_addr_t data_phys_addr, td_u32 data_len, in_node_type_e type) +{ + crypto_symc_hard_context *hard_ctx = TD_NULL; + crypto_symc_entry_in *entry_in = TD_NULL; + +#if defined(CONFIG_CRYPTO_CHIP_HI3892WV100) + crypto_chk_return((data_phys_addr % CRYPTO_WORD_WIDTH) != 0, SYMC_COMPAT_ERRNO(ERROR_SYMC_LEN_NOT_ALIGNED), + "phys_addr should align to %u-Byte\n", CRYPTO_WORD_WIDTH); +#endif + hard_ctx = &g_symc_hard_context[chn_num]; + entry_in = &hard_ctx->entry_in[hard_ctx->idx_in]; + + entry_in->sym_first_node = (type & IN_NODE_TYPE_FIRST) ? 0x1 : 0; + entry_in->sym_last_node = (type & IN_NODE_TYPE_LAST) ? 0x1 : 0; + entry_in->sym_alg_length = data_len; + entry_in->sym_start_addr = data_phys_addr; + entry_in->sym_start_high = 0; + return TD_SUCCESS; +} + +static td_void inner_spacc_interrupt_enable(td_bool enable) +{ + spacc_ie cfg_val = { 0 }; + cfg_val.u32 = spacc_reg_read(SPACC_IE); + if (crypto_get_cpu_type() == CRYPTO_CPU_TYPE_SCPU) { + cfg_val.bits.spacc_ie_tee = enable; + } else { + cfg_val.bits.spacc_ie_ree = enable; + } + + spacc_reg_write(SPACC_IE, cfg_val.u32); +} + +td_s32 hal_cipher_symc_init(td_void) +{ + td_s32 ret = TD_SUCCESS; + td_u32 i; + td_u8 *entry_buffer = TD_NULL; + crypto_symc_hard_context *hard_ctx = TD_NULL; + + crypto_hal_func_enter(); + /* Node Buffer must be MMZ. */ +#if defined(CRYPTO_CONFIG_ROMBOOT_ENV) + entry_buffer = g_symc_node_buffer; +#else + entry_buffer = crypto_malloc_mmz(CRYPTO_SYMC_NODE_LIST_SIZE, "cipher_symc_node"); + if (entry_buffer == TD_NULL) { + crypto_log_err("crypto_malloc_mmz failed\n"); + return TD_FAILURE; + } +#endif + (td_void)memset_s(g_symc_hard_context, sizeof(g_symc_hard_context), 0, sizeof(g_symc_hard_context)); + for (i = 0; i < CRYPTO_SYMC_HARD_CHANNEL_MAX; i++) { + hard_ctx = &g_symc_hard_context[i]; + hard_ctx->entry_in = (void *)(entry_buffer + i * CRYPTO_SYMC_NODE_SIZE); + hard_ctx->entry_out = (void *)(entry_buffer + i * CRYPTO_SYMC_NODE_SIZE + + CRYPTO_SYMC_IN_NODE_SIZE); + } + + inner_spacc_interrupt_enable(TD_FALSE); + +#if defined(CRYPTO_ERROR_ENV) + if (CRYPTO_ERROR_ENV != ERROR_ENV_NOOS) { + /* release all previously locked channels */ + for (i = 1; i < CRYPTO_SYMC_HARD_CHANNEL_MAX; i++) { + (td_void)hal_cipher_symc_unlock_chn(i); + } + } +#endif + + crypto_hal_func_exit(); + return ret; +} + +td_s32 hal_cipher_symc_deinit(td_void) +{ + td_u8 *entry_buffer = TD_NULL; + td_u32 i; + crypto_hal_func_enter(); + + entry_buffer = (td_u8 *)g_symc_hard_context[0].entry_in; + (td_void)memset_s(entry_buffer, CRYPTO_SYMC_NODE_LIST_SIZE, 0, CRYPTO_SYMC_NODE_LIST_SIZE); +#if !defined(CRYPTO_CONFIG_ROMBOOT_ENV) + crypto_free_coherent(entry_buffer); +#endif + (td_void)memset_s(g_symc_hard_context, sizeof(g_symc_hard_context), 0, sizeof(g_symc_hard_context)); + for (i = 0; i < CRYPTO_SYMC_HARD_CHANNEL_MAX; i++) { + hal_cipher_symc_unlock_chn(i); + } + crypto_hal_func_exit(); + return TD_SUCCESS; +} + +td_s32 hal_cipher_symc_lock_chn(td_u32 chn_num) +{ + td_s32 ret = TD_SUCCESS; + td_u32 used; + td_u32 chnn_who_used = 0; + spacc_cpu_mask cpu_mask = SPACC_CPU_IDLE; + crypto_symc_hard_context *hard_ctx = TD_NULL; + in_sym_chn_ctrl in_ctrl; + crypto_hal_func_enter(); + + cpu_mask = (crypto_get_cpu_type() == CRYPTO_CPU_TYPE_SCPU) ? SPACC_CPU_TEE : SPACC_CPU_REE; + + used = spacc_reg_read(SPACC_SYM_CHN_LOCK); + chnn_who_used = CHN_WHO_USED_GET(used, chn_num); + if (chnn_who_used != SPACC_CPU_IDLE) { + return TD_FAILURE; + } + CHN_WHO_USED_SET(used, chn_num, cpu_mask); + spacc_reg_write(SPACC_SYM_CHN_LOCK, used); + + /* Read Back. */ + used = spacc_reg_read(SPACC_SYM_CHN_LOCK); + chnn_who_used = CHN_WHO_USED_GET(used, chn_num); + crypto_chk_return(chnn_who_used != cpu_mask, TD_FAILURE, "Lock SYMC CHN %u Failed\n", chn_num); + + ret = hal_cipher_symc_clear_channel(chn_num); + if (ret != TD_SUCCESS) { + crypto_log_err("hal_cipher_symc_clear_channel failed\n"); + hal_cipher_symc_unlock_chn(chn_num); + return ret; + } + hard_ctx = &g_symc_hard_context[chn_num]; + hal_cipher_symc_set_entry_node(chn_num, hard_ctx); + + /* enable channel. */ + in_ctrl.u32 = spacc_reg_read(IN_SYM_CHN_CTRL(chn_num)); + in_ctrl.bits.sym_chn_en = 1; + if (crypto_get_cpu_type() == CRYPTO_CPU_TYPE_SCPU) { + in_ctrl.bits.sym_chn_ss = SYMC_CFG_SECURE; + in_ctrl.bits.sym_chn_ds = SYMC_CFG_SECURE; + } else { + in_ctrl.bits.sym_chn_ss = SYMC_CFG_NON_SECURE; + in_ctrl.bits.sym_chn_ds = SYMC_CFG_NON_SECURE; + } + spacc_reg_write(IN_SYM_CHN_CTRL(chn_num), in_ctrl.u32); + + hal_cipher_symc_done_try(chn_num); + hal_cipher_symc_out_node_done_try(chn_num); + +#if defined(CRYPTO_DRV_DFA_ENABLE) + /* DFA Enable */ + hal_cipher_symc_dfa_config(chn_num, TD_TRUE); +#else + /* DFA Disable */ + hal_cipher_symc_dfa_config(chn_num, TD_FALSE); +#endif + + crypto_hal_func_exit(); + return ret; +} + +td_s32 hal_cipher_symc_unlock_chn(td_u32 chn_num) +{ + td_s32 ret = TD_SUCCESS; + td_u32 used; + td_u32 chnn_who_used = 0; + spacc_cpu_mask cpu_mask = SPACC_CPU_IDLE; + crypto_hal_func_enter(); + + if (crypto_get_cpu_type() == CRYPTO_CPU_TYPE_SCPU) { + cpu_mask = SPACC_CPU_TEE; + } else { + cpu_mask = SPACC_CPU_REE; + } + + used = spacc_reg_read(SPACC_SYM_CHN_LOCK); + chnn_who_used = CHN_WHO_USED_GET(used, chn_num); + if (chnn_who_used != cpu_mask) { + return TD_SUCCESS; + } + + ret = hal_cipher_symc_clear_channel(chn_num); + if (ret != TD_SUCCESS) { + crypto_log_err("hal_cipher_symc_clear_channel failed\n"); + } + + used = spacc_reg_read(SPACC_SYM_CHN_LOCK); + CHN_WHO_USED_CLR(used, chn_num); + spacc_reg_write(SPACC_SYM_CHN_LOCK, used); + + crypto_hal_func_exit(); + return ret; +} + +td_s32 hal_cipher_symc_attach(td_u32 symc_chn_num, td_u32 keyslot_chn_num) +{ + in_sym_chn_key_ctrl in_key_ctrl; + crypto_hal_func_enter(); + + in_key_ctrl.u32 = spacc_reg_read(IN_SYM_CHN_KEY_CTRL(symc_chn_num)); + /* Keyslot CHN Num. */ + in_key_ctrl.bits.sym_key_chn_id = keyslot_chn_num; + spacc_reg_write(IN_SYM_CHN_KEY_CTRL(symc_chn_num), in_key_ctrl.u32); + + crypto_hal_func_exit(); + return TD_SUCCESS; +} + +td_s32 hal_cipher_symc_set_iv(td_u32 chn_num, const td_u8 *iv, td_u32 iv_len) +{ + td_s32 ret; + crypto_symc_hard_context *hard_ctx = TD_NULL; + crypto_symc_entry_in *entry_in = TD_NULL; + td_u32 idx; + crypto_hal_func_enter(); + +#if defined(CRYPTO_SYMC_HAL_DEBUG_ENABLE) + crypto_dump_data("iv", iv, iv_len); +#endif + + hard_ctx = &g_symc_hard_context[chn_num]; + idx = hard_ctx->idx_in; + entry_in = &hard_ctx->entry_in[idx]; + + ret = memcpy_s(entry_in->iv, sizeof(entry_in->iv), iv, iv_len); + if (ret != TD_SUCCESS) { + crypto_log_err("memcpy_s failed, ret is 0x%x\n", ret); + return ret; + } + + crypto_hal_func_exit(); + return TD_SUCCESS; +} + +td_s32 hal_cipher_symc_get_iv(td_u32 chn_num, td_u8 *iv, td_u32 iv_len) +{ + td_u32 i; + td_u32 iv_get[CRYPTO_AES_IV_SIZE_IN_WORD] = {0}; + crypto_hal_func_enter(); + (td_void)iv_len; + + for (i = 0; i < CRYPTO_AES_IV_SIZE_IN_WORD; i++) { + iv_get[i] = spacc_reg_read(CHANN_CIPHER_IVOUT(chn_num) + i * CRYPTO_WORD_WIDTH); + } + + (td_void)memcpy_s(iv, CRYPTO_IV_LEN_IN_BYTES, iv_get, CRYPTO_IV_LEN_IN_BYTES); + + crypto_hal_func_exit(); + return TD_SUCCESS; +} + +/* 1. Key Length. */ +#define SYMC_KEY_64BIT_VAL 0 +#define SYMC_KEY_128BIT_VAL 1 +#define SYMC_KEY_192BIT_VAL 2 +#define SYMC_KEY_256BIT_VAL 3 + +static crypto_table_item g_symc_key_length_table[] = { + { + .index = CRYPTO_SYMC_KEY_64BIT, .value = SYMC_KEY_64BIT_VAL + }, + { + .index = CRYPTO_SYMC_KEY_128BIT, .value = SYMC_KEY_128BIT_VAL + }, +#if defined(CRYPTO_IOT_V200) + { + .index = CRYPTO_SYMC_KEY_192BIT, .value = SYMC_KEY_192BIT_VAL + }, +#endif + { + .index = CRYPTO_SYMC_KEY_256BIT, .value = SYMC_KEY_256BIT_VAL + }, +}; + +/* 2. ALg Mode. */ +#define SYMC_ALG_MODE_ECB_VAL 0x1 +#define SYMC_ALG_MODE_CBC_VAL 0x3 +#define SYMC_ALG_MODE_CTR_VAL 0x6 +#define SYMC_ALG_MODE_OFB_VAL 0x7 +#define SYMC_ALG_MODE_CFB_VAL 0x8 +#define SYMC_ALG_MODE_GCTR_VAL 0xb +#define SYMC_ALG_MODE_CMAC_VAL 0xc +#define SYMC_ALG_MODE_CBC_NOOUT_VAL 0xd +#define SYMC_ALG_MODE_GCTR_NOOUT_VAL 0xe + +static crypto_table_item g_symc_alg_mode_table[] = { + { + .index = CRYPTO_SYMC_WORK_MODE_ECB, .value = SYMC_ALG_MODE_ECB_VAL + }, + { + .index = CRYPTO_SYMC_WORK_MODE_CBC, .value = SYMC_ALG_MODE_CBC_VAL + }, + { + .index = CRYPTO_SYMC_WORK_MODE_CTR, .value = SYMC_ALG_MODE_CTR_VAL + }, + { + .index = CRYPTO_SYMC_WORK_MODE_OFB, .value = SYMC_ALG_MODE_OFB_VAL + }, + { + .index = CRYPTO_SYMC_WORK_MODE_CFB, .value = SYMC_ALG_MODE_CFB_VAL + }, + { + .index = CRYPTO_SYMC_WORK_MODE_CCM, .value = SYMC_ALG_MODE_CTR_VAL + }, + { + .index = CRYPTO_SYMC_WORK_MODE_GCM, .value = SYMC_ALG_MODE_GCTR_VAL + }, + { + .index = CRYPTO_SYMC_WORK_MODE_CBC_MAC, .value = SYMC_ALG_MODE_CBC_NOOUT_VAL + }, + { + .index = CRYPTO_SYMC_WORK_MODE_CMAC, .value = SYMC_ALG_MODE_CMAC_VAL + } +}; + +/* 3. Alg. */ +#define SYMC_ALG_AES_VAL 0x2 +#define SYMC_ALG_SM4_VAL 0x5 +#define SYMC_ALG_GHASH_VAL 0x6 + +static crypto_table_item g_symc_alg_table[] = { + { + .index = CRYPTO_SYMC_ALG_AES, .value = SYMC_ALG_AES_VAL + }, + { + .index = CRYPTO_SYMC_ALG_SM4, .value = SYMC_ALG_SM4_VAL + }, +}; + +/* 4. Bit Width. */ +#define SYMC_ALG_BIT_WIDTH_128BIT 0 +#define SYMC_ALG_BIT_WIDTH_64BIT 1 +#define SYMC_ALG_BIT_WIDTH_8BIT 1 + +static crypto_table_item g_symc_bit_width_table[] = { + { + .index = CRYPTO_SYMC_BIT_WIDTH_128BIT, .value = SYMC_ALG_BIT_WIDTH_128BIT + }, + { + .index = CRYPTO_SYMC_BIT_WIDTH_64BIT, .value = SYMC_ALG_BIT_WIDTH_64BIT + }, + { + .index = CRYPTO_SYMC_BIT_WIDTH_8BIT, .value = SYMC_ALG_BIT_WIDTH_8BIT + }, +}; + +static td_s32 hal_cipher_symc_ccm_get_s0_and_iv_ctr(td_u32 chn_num, crypto_symc_hard_context *hard_ctx) +{ + td_s32 ret = TD_SUCCESS; + td_u8 *head = TD_NULL; + + if (hard_ctx->symc_config.iv_change_flag == CRYPTO_SYMC_CCM_IV_CHANGE_START) { + (td_void)memset_s(hard_ctx->iv_ctr, sizeof(hard_ctx->iv_ctr), 0, sizeof(hard_ctx->iv_ctr)); + (td_void)memset_s(hard_ctx->symc_config.iv_mac, sizeof(hard_ctx->symc_config.iv_mac), + 0, sizeof(hard_ctx->symc_config.iv_mac)); + + head = crypto_malloc_coherent(CRYPTO_AES_BLOCK_SIZE_IN_BYTES, "cipher_ccm_head"); + crypto_chk_return(head == TD_NULL, TD_FAILURE, "crypto_malloc_coherent failed\n"); + (td_void)memset_s(head, CRYPTO_AES_BLOCK_SIZE_IN_BYTES, 0, CRYPTO_AES_BLOCK_SIZE_IN_BYTES); + + ret = hal_cipher_symc_add_in_node(chn_num, crypto_get_phys_addr(head), CRYPTO_AES_BLOCK_SIZE_IN_BYTES, + IN_NODE_TYPE_FIRST | IN_NODE_TYPE_LAST); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "hal_cipher_symc_add_in_node failed\n"); + + ret = hal_cipher_symc_add_out_node(chn_num, crypto_get_phys_addr(head), CRYPTO_AES_BLOCK_SIZE_IN_BYTES); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "hal_cipher_symc_add_out_node failed\n"); + + ret = hal_cipher_symc_start(chn_num); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "hal_cipher_symc_start failed\n"); + + ret = hal_cipher_symc_wait_done(chn_num, TD_FALSE); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "hal_cipher_symc_wait_done failed\n"); + + ret = memcpy_s(hard_ctx->symc_config.iv0, sizeof(hard_ctx->symc_config.iv0), + head, CRYPTO_AES_BLOCK_SIZE_IN_BYTES); + crypto_chk_goto(ret != EOK, exit_free, "memcpy_s failed\n"); + + hal_cipher_symc_get_iv(chn_num, hard_ctx->iv_ctr, sizeof(hard_ctx->iv_ctr)); + + hard_ctx->symc_config.iv_change_flag = CRYPTO_SYMC_CCM_IV_CHANGE_UPDATE; +#if defined(CRYPTO_CCM_TRACE_ENABLE) + crypto_dump_data("s0", hard_ctx->symc_config.iv0, sizeof(hard_ctx->symc_config.iv0)); + crypto_dump_data("iv_ctr", hard_ctx->iv_ctr, sizeof(hard_ctx->iv_ctr)); +#endif + } +exit_free: + if (head != TD_NULL) { + (td_void)memset_s(head, CRYPTO_AES_BLOCK_SIZE_IN_BYTES, 0, CRYPTO_AES_BLOCK_SIZE_IN_BYTES); + crypto_free_coherent(head); + } + return ret; +} + +static td_s32 gcm_inc(const td_u8 *input, td_u32 input_len, td_u8 *output, td_u32 output_len) +{ + td_u32 i = 0; + + if (input_len != output_len) { + crypto_log_err("input_len must be equal to output_len for gcm_inc\n"); + return TD_FAILURE; + } + + for (i = 0; i < input_len; i++) { + output[i] = input[i]; + } + + for (i = input_len; i > input_len - CRYPTO_WORD_WIDTH; i--) { + if (++(output[i - 1]) != 0) { + break; + } + } + return TD_SUCCESS; +} + +static td_s32 hal_gcm_get_j0_by_iv(td_u32 chn_num, crypto_symc_hard_context *hard_ctx, + const td_u8 *gcm_iv_ptr, td_u32 gcm_iv_len) +{ + td_s32 ret; + td_u8 *buffer = TD_NULL; + td_u32 buffer_len = CRYPTO_AES_BLOCK_SIZE_IN_BYTES * 2; /* 2: Store iv and Padding. */ + td_u32 iv_bits_len = 0; + + buffer = crypto_malloc_coherent(buffer_len, "cipher_gcm_head"); + crypto_chk_return(buffer == TD_NULL, TD_FAILURE, "crypto_malloc_coherent failed\n"); + /* padding must be zeros. */ + (td_void)memset_s(buffer, buffer_len, 0, buffer_len); + + ret = memcpy_s(buffer, buffer_len, gcm_iv_ptr, gcm_iv_len); + crypto_chk_goto(ret != EOK, exit_free, "memcpy_s failed\n"); + + // Set iv total bits to last 4 bytes. + iv_bits_len = gcm_iv_len * CRYPTO_BITS_IN_BYTE; + iv_bits_len = crypto_cpu_to_be32(iv_bits_len); + ret = memcpy_s(buffer + buffer_len - CRYPTO_WORD_WIDTH, CRYPTO_WORD_WIDTH, + (td_u8 *)(&iv_bits_len), CRYPTO_WORD_WIDTH); + crypto_chk_goto(ret != EOK, exit_free, "memcpy_s failed\n"); + + ret = hal_cipher_symc_gcm_mac_update(chn_num, crypto_get_phys_addr(buffer), buffer_len, + IN_NODE_TYPE_FIRST | IN_NODE_TYPE_LAST | IN_NODE_TYPE_GCM_IV); + crypto_chk_goto(ret != EOK, exit_free, "hal_cipher_symc_gcm_mac_update failed\n"); + + // get J0 + ret = hal_cipher_symc_get_iv(chn_num, hard_ctx->symc_config.iv0, sizeof(hard_ctx->symc_config.iv0)); + crypto_chk_goto(ret != EOK, exit_free, "hal_cipher_symc_get_iv failed\n"); + +exit_free: + (td_void)memset_s(buffer, buffer_len, 0, buffer_len); + crypto_free_coherent(buffer); + return ret; +} + +static td_s32 hal_cipher_symc_gcm_get_j0(td_u32 chn_num, crypto_symc_hard_context *hard_ctx) +{ + td_s32 ret; + td_u32 i = 0; + const td_u8 *gcm_iv_ptr = hard_ctx->symc_config.gcm_iv_ptr; + td_u32 iv_len = hard_ctx->symc_config.gcm_iv_len; + + crypto_chk_return(gcm_iv_ptr == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "gcm_iv_ptr is NULL\n"); + /* Before Calculate j0, iv_ghash must be clear. */ + (td_void)memset_s(hard_ctx->symc_config.iv_mac, sizeof(hard_ctx->symc_config.iv_mac), 0, + sizeof(hard_ctx->symc_config.iv_mac)); + (td_void)memset_s(hard_ctx->symc_config.iv0, sizeof(hard_ctx->symc_config.iv0), + 0, sizeof(hard_ctx->symc_config.iv0)); + /* If the IV length is 12 bytes, J0 = IV || 00000000 00000000 00000000 00000001 */ + if (iv_len == CRYPTO_GCM_SPECIAL_IV_BYTES) { // for 96 bits, J0 = IV || 00000001 + for (i = 0; i < iv_len; i++) { + hard_ctx->symc_config.iv0[i] = gcm_iv_ptr[i]; + } + hard_ctx->symc_config.iv0[CRYPTO_AES_IV_SIZE - 1] = 0x01; // j0[15] = 0x01 + } else { /* If the IV length is not 12 bytes, J0 = GHASH{IV || [00..00] || len(IV)} */ + ret = hal_gcm_get_j0_by_iv(chn_num, hard_ctx, gcm_iv_ptr, iv_len); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_gcm_get_j0_by_iv failed\n"); + } + + /* get the initial vertor by j0. */ + ret = gcm_inc(hard_ctx->symc_config.iv0, sizeof(hard_ctx->symc_config.iv0), + hard_ctx->iv_ctr, sizeof(hard_ctx->iv_ctr)); + crypto_chk_return(ret != TD_SUCCESS, ret, "gcm_inc failed\n"); + +#ifdef CRYPTO_GCM_TRACE_ENABLE + crypto_dump_data("gcm_j0", hard_ctx->symc_config.iv0, sizeof(hard_ctx->symc_config.iv0)); + crypto_dump_data("gcm_iv", hard_ctx->iv_ctr, sizeof(hard_ctx->iv_ctr)); +#endif + + return ret; +} + +static td_s32 inner_symc_config_key_ctrl(td_u32 chn_num, const hal_symc_config_t *symc_config) +{ + volatile td_s32 ret = TD_FAILURE; + td_u32 reg_value = 0; + in_sym_chn_key_ctrl in_key_ctrl = {0}; + td_bool is_decrypt = symc_config->is_decrypt; + crypto_symc_alg symc_alg = symc_config->symc_alg; + crypto_symc_work_mode work_mode = symc_config->work_mode; + crypto_symc_key_length symc_key_length = symc_config->symc_key_length; + crypto_symc_bit_width symc_bit_width = symc_config->symc_bit_width; + + in_key_ctrl.u32 = spacc_reg_read(IN_SYM_CHN_KEY_CTRL(chn_num)); + + /* alg_decrypt. */ + in_key_ctrl.bits.sym_alg_decrypt = is_decrypt; + + /* alg_sel. */ + ret = crypto_get_value_by_index(g_symc_alg_table, crypto_array_size(g_symc_alg_table), + symc_alg, ®_value); + crypto_chk_return(ret != TD_SUCCESS, SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM), "Invalid Alg!\n"); + in_key_ctrl.bits.sym_alg_sel = reg_value; + + /* alg_mode. */ + ret = crypto_get_value_by_index(g_symc_alg_mode_table, crypto_array_size(g_symc_alg_mode_table), + work_mode, ®_value); + crypto_chk_return(ret != TD_SUCCESS, SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM), "Invalid Alg_Mode!\n"); + in_key_ctrl.bits.sym_alg_mode = reg_value; + + /* alg_key_len. */ + ret = crypto_get_value_by_index(g_symc_key_length_table, crypto_array_size(g_symc_key_length_table), + symc_key_length, ®_value); + crypto_chk_return(ret != TD_SUCCESS, SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM), "Invalid key_len!\n"); + in_key_ctrl.bits.sym_alg_key_len = reg_value; + + /* alg_data_width. */ + ret = crypto_get_value_by_index(g_symc_bit_width_table, crypto_array_size(g_symc_bit_width_table), + symc_bit_width, ®_value); + crypto_chk_return(ret != TD_SUCCESS, SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM), "Invalid alg_data_width!\n"); + in_key_ctrl.bits.sym_alg_data_width = reg_value; + + spacc_reg_write(IN_SYM_CHN_KEY_CTRL(chn_num), in_key_ctrl.u32); + return TD_SUCCESS; +} + +td_s32 hal_cipher_symc_config(td_u32 chn_num, const hal_symc_config_t *symc_config) +{ + td_s32 ret; + in_sym_out_ctrl cipher_dma_ctrl = { 0 }; + crypto_symc_alg symc_alg = symc_config->symc_alg; + crypto_symc_work_mode work_mode = symc_config->work_mode; + crypto_symc_hard_context *hard_ctx = TD_NULL; + + crypto_hal_func_enter(); + + /* dma enable. */ + cipher_dma_ctrl.u32 = spacc_reg_read(IN_SYM_OUT_CTRL(chn_num)); + if (symc_alg == CRYPTO_SYMC_ALG_DMA) { + cipher_dma_ctrl.bits.sym_dma_copy = TD_TRUE; + spacc_reg_write(IN_SYM_OUT_CTRL(chn_num), cipher_dma_ctrl.u32); + return TD_SUCCESS; + } + cipher_dma_ctrl.bits.sym_dma_copy = TD_FALSE; + spacc_reg_write(IN_SYM_OUT_CTRL(chn_num), cipher_dma_ctrl.u32); + + ret = inner_symc_config_key_ctrl(chn_num, symc_config); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_symc_config_key_ctrl failed\n"); + + hard_ctx = &g_symc_hard_context[chn_num]; + + (td_void)memcpy_s(&(hard_ctx->symc_config), sizeof(hal_symc_config_t), symc_config, sizeof(hal_symc_config_t)); + + /* For ccm, you should calculate s0 and iv_ctr first. */ + if (work_mode == CRYPTO_SYMC_WORK_MODE_CCM && symc_config->iv_change_flag == CRYPTO_SYMC_CCM_IV_CHANGE_START) { + crypto_log_dbg("ccm calculate s0 and iv_ctr\n"); + hal_cipher_symc_ccm_get_s0_and_iv_ctr(chn_num, hard_ctx); + hard_ctx->symc_config.iv_change_flag = CRYPTO_SYMC_CCM_IV_CHANGE_UPDATE; + } + /* for gcm, you should calculate j0 first. */ + /* you need get j0 only once. */ + if (work_mode == CRYPTO_SYMC_WORK_MODE_GCM && symc_config->iv_change_flag == CRYPTO_SYMC_GCM_IV_CHANGE_START) { + crypto_log_dbg("gcm calculate j0.\n"); + ret = hal_cipher_symc_gcm_get_j0(chn_num, hard_ctx); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_gcm_get_j0 failed\n"); + hard_ctx->symc_config.iv_change_flag = CRYPTO_SYMC_GCM_IV_CHANGE_UPDATE; + } + + crypto_hal_func_exit(); + + return ret; +} + +td_s32 hal_cipher_symc_get_module_info(crypto_symc_module_info *module_info) +{ + spacc_ie st_int_en; + + crypto_hal_func_enter(); + crypto_chk_return(module_info == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "module_info is NULL\n"); + + /* module info. */ + module_info->sec_cpu = (crypto_get_cpu_type() == CRYPTO_CPU_TYPE_SCPU) ? 1 : 0; + st_int_en.u32 = spacc_reg_read(SPACC_IE); + module_info->int_en = (crypto_get_cpu_type() == CRYPTO_CPU_TYPE_SCPU) ? \ + st_int_en.bits.spacc_ie_tee : st_int_en.bits.spacc_ie_ree; + module_info->err_code = spacc_reg_read(SYM_CALC_CTRL_CHECK_ERR(SPACC_CPU_CUR)); + + crypto_hal_func_exit(); + return TD_SUCCESS; +} + +td_s32 hal_cipher_symc_get_proc_info(td_u32 chn_num, crypto_symc_proc_info *proc_symc_info) +{ + td_s32 ret; + td_u32 index; + + in_sym_chn_key_ctrl in_key_ctrl; + + out_sym_chan_raw_int out_raw_int; + out_sym_chan_raw_int_en out_sym_int_en; + out_sym_chn_status out_sym_int_status; + + in_sym_chn_node_wr_point in_node_wr_ptr; + in_sym_chn_node_rd_point in_node_rd_ptr; + in_sym_chn_node_length in_node_depth; + + out_sym_chn_node_wr_point out_node_wr_ptr; + out_sym_chn_node_rd_point out_node_rd_ptr; + out_sym_chn_node_length out_node_depth; + + crypto_hal_func_enter(); + + crypto_chk_return(proc_symc_info == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "proc_symc_info is NULL\n"); + + /* Get Key Ctrl. */ + in_key_ctrl.u32 = spacc_reg_read(IN_SYM_CHN_KEY_CTRL(chn_num)); + proc_symc_info->is_decrypt = in_key_ctrl.bits.sym_alg_decrypt; + + /* Alg. */ + ret = crypto_get_index_by_value(g_symc_alg_table, crypto_array_size(g_symc_alg_table), + in_key_ctrl.bits.sym_alg_sel, &index); + if (ret != TD_SUCCESS) { + return SYMC_COMPAT_ERRNO(ERROR_INVALID_REGISTER_VALUE); + } + proc_symc_info->alg = index; + + /* Alg Mode. */ + ret = crypto_get_index_by_value(g_symc_alg_mode_table, crypto_array_size(g_symc_alg_mode_table), + in_key_ctrl.bits.sym_alg_mode, &index); + if (ret != TD_SUCCESS) { + return SYMC_COMPAT_ERRNO(ERROR_INVALID_REGISTER_VALUE); + } + proc_symc_info->mode = index; + + /* Key Length. */ + ret = crypto_get_index_by_value(g_symc_key_length_table, crypto_array_size(g_symc_key_length_table), + in_key_ctrl.bits.sym_alg_key_len, &index); + if (ret != TD_SUCCESS) { + crypto_log_err("Invalid Key Length in Register!\n"); + return SYMC_COMPAT_ERRNO(ERROR_INVALID_REGISTER_VALUE); + } + proc_symc_info->key_len = index; + + /* Key Source. */ + proc_symc_info->key_source = in_key_ctrl.bits.sym_key_chn_id; + + /* int_raw. */ + out_raw_int.u32 = spacc_reg_read(OUT_SYM_CHAN_RAW_LAST_NODE_INT); + proc_symc_info->int_raw = (out_raw_int.bits.out_sym_chan_raw_int >> chn_num) & 0x1; + + /* int_en. */ + out_sym_int_en.u32 = spacc_reg_read(OUT_SYM_CHAN_RAW_LAST_NODE_INT_EN); + proc_symc_info->int_en = (out_sym_int_en.bits.out_sym_chan_int_en >> chn_num) & 0x1; + + /* int status. */ + out_sym_int_status.u32 = spacc_reg_read(OUT_SYM_CHAN_LAST_NODE_INT); + proc_symc_info->int_status = (out_sym_int_status.bits.out_sym_chn_int_status >> chn_num) & 0x1; + + /* is_secure. */ + proc_symc_info->is_secure = (crypto_get_cpu_type() == CRYPTO_CPU_TYPE_SCPU) ? 1 : 0; + + /* in node: head(r/w/d) */ + in_node_wr_ptr.u32 = spacc_reg_read(IN_SYM_CHN_NODE_WR_POINT(chn_num)); + in_node_rd_ptr.u32 = spacc_reg_read(IN_SYM_CHN_NODE_RD_POINT(chn_num)); + in_node_depth.u32 = spacc_reg_read(IN_SYM_CHN_NODE_LENGTH(chn_num)); + proc_symc_info->in_node_head = spacc_reg_read(IN_SYM_CHN_NODE_START_ADDR_L(chn_num)); + proc_symc_info->in_node_rptr = in_node_rd_ptr.bits.sym_chn_node_rd_point; + proc_symc_info->in_node_wptr = in_node_wr_ptr.bits.sym_chn_node_wr_point; + proc_symc_info->in_node_depth = in_node_depth.bits.sym_chn_node_length; + + /* out node: head(r/w/d) */ + out_node_wr_ptr.u32 = spacc_reg_read(OUT_SYM_CHN_NODE_WR_POINT(chn_num)); + out_node_rd_ptr.u32 = spacc_reg_read(OUT_SYM_CHN_NODE_RD_POINT(chn_num)); + out_node_depth.u32 = spacc_reg_read(OUT_SYM_CHN_NODE_LENGTH(chn_num)); + proc_symc_info->out_node_head = spacc_reg_read(OUT_SYM_CHN_NODE_START_ADDR_L(chn_num)); + proc_symc_info->out_node_rptr = out_node_rd_ptr.bits.sym_chn_node_rd_point; + proc_symc_info->out_node_wptr = out_node_wr_ptr.bits.sym_chn_node_wr_point; + proc_symc_info->out_node_depth = out_node_depth.bits.sym_chn_node_length; + + crypto_hal_func_exit(); + + return TD_SUCCESS; +} + +td_s32 hal_cipher_symc_get_config(td_u32 chn_num, hal_symc_config_t *symc_config) +{ + td_s32 ret; + crypto_symc_hard_context *hard_ctx = TD_NULL; + + crypto_hal_func_enter(); + + hard_ctx = &g_symc_hard_context[chn_num]; + + ret = memcpy_s(symc_config, sizeof(hal_symc_config_t), &hard_ctx->symc_config, sizeof(hal_symc_config_t)); + crypto_chk_return(ret != TD_SUCCESS, ret, "memcpy_s failed\n"); + + crypto_hal_func_exit(); + return TD_SUCCESS; +} + +td_s32 hal_cipher_symc_start(td_u32 chn_num) +{ + in_sym_chn_node_wr_point in_node_wr_ptr; + out_sym_chn_node_wr_point out_node_wr_ptr; + crypto_symc_hard_context *hard_ctx = TD_NULL; + td_u32 ptr; + + crypto_hal_func_enter(); + + hard_ctx = &g_symc_hard_context[chn_num]; + + /* if wait_func registered, enable interrupt */ + if (hard_ctx->wait_func != TD_NULL) { + hard_ctx->done = TD_FALSE; + hard_ctx->is_wait = TD_TRUE; + inner_symc_irq_enable(chn_num, TD_TRUE); + } else { + hard_ctx->is_wait = TD_FALSE; + inner_symc_irq_enable(chn_num, TD_FALSE); + } + + /* configure out nodes. */ + out_node_wr_ptr.u32 = spacc_reg_read(OUT_SYM_CHN_NODE_WR_POINT(chn_num)); + ptr = out_node_wr_ptr.bits.sym_chn_node_wr_point + hard_ctx->cnt_out; + out_node_wr_ptr.bits.sym_chn_node_wr_point = ptr % CRYPTO_SYMC_MAX_LIST_NUM; + + /* make sure all the above explicit memory accesses and instructions are completed + * before start the hardware. + */ + crypto_memory_barrier(); + + spacc_reg_write(OUT_SYM_CHN_NODE_WR_POINT(chn_num), out_node_wr_ptr.u32); + + /* configure in nodes. */ + in_node_wr_ptr.u32 = spacc_reg_read(IN_SYM_CHN_NODE_WR_POINT(chn_num)); + + ptr = in_node_wr_ptr.bits.sym_chn_node_wr_point + hard_ctx->cnt_in; + in_node_wr_ptr.bits.sym_chn_node_wr_point = ptr % CRYPTO_SYMC_MAX_LIST_NUM; + + /* make sure all the above explicit memory accesses and instructions are completed + * before start the hardware. + */ + crypto_memory_barrier(); + + crypto_dcache_disable(); + + spacc_reg_write(IN_SYM_CHN_NODE_WR_POINT(chn_num), in_node_wr_ptr.u32); + + hard_ctx->cnt_in = 0; + hard_ctx->cnt_out = 0; + + crypto_hal_func_exit(); + return TD_SUCCESS; +} + +td_s32 hal_cipher_symc_done_try(td_u32 chn_num) +{ + out_sym_chan_raw_int last_raw; + + td_u32 mask; + + last_raw.u32 = spacc_reg_read(OUT_SYM_CHAN_RAW_LAST_NODE_INT); + last_raw.bits.out_sym_chan_raw_int &= (0x01 << chn_num); + spacc_reg_write(OUT_SYM_CHAN_RAW_LAST_NODE_INT, last_raw.u32); + + mask = last_raw.bits.out_sym_chan_raw_int; + if (mask == 0) { + return CRYPTO_FAILURE; + } + + return CRYPTO_SUCCESS; +} + +#if defined(CRYPTO_OS_INT_SUPPORT) +td_s32 hal_cipher_symc_done_notify(td_u32 chn_num) +{ + crypto_symc_hard_context *hard_ctx = TD_NULL; + crypto_hal_func_enter(); + + hard_ctx = &g_symc_hard_context[chn_num]; + hard_ctx->done = TD_TRUE; + + crypto_hal_func_exit(); + return TD_SUCCESS; +} +#endif + +static td_s32 hal_cipher_symc_out_node_done_try(td_u32 chn_num) +{ + sym_chann_raw_int raw_int; + td_u32 mask; + crypto_hal_func_enter(); + + raw_int.u32 = spacc_reg_read(SYM_CHANN_RAW_INT); + raw_int.bits.sym_chann_raw_int &= (0x01 << chn_num); + spacc_reg_write(SYM_CHANN_RAW_INT, raw_int.u32); + + mask = raw_int.bits.sym_chann_raw_int; + if (mask == 0) { + return TD_FAILURE; + } + + crypto_hal_func_exit(); + return TD_SUCCESS; +} + +static td_bool hal_symc_condition(const td_void *param) +{ + crypto_symc_hard_context *hard_ctx = TD_NULL; + td_u32 chn_num = *(td_u32 *)param; + + hard_ctx = &g_symc_hard_context[chn_num]; + if (hard_ctx->done == TD_TRUE) { + hard_ctx->done = TD_FALSE; + return TD_TRUE; + } else { + return TD_FALSE; + } +} + +/* + * Notice: CCM process don't care about multiple encrypt operations, so don't support ccm update. + */ +static td_s32 hal_symc_process_ccm_p_pre(td_u32 chn_num, td_phys_addr_t data_phys_addr, td_u32 data_len) +{ + td_s32 ret; + td_u8 *ccm_p_padding = TD_NULL; + td_u32 ccm_p_padding_len = 0; + in_node_type_e ccm_p_type = IN_NODE_TYPE_NORMAL; + + ccm_p_padding = crypto_malloc_coherent(CRYPTO_AES_BLOCK_SIZE_IN_BYTES, "cipher_ccm_p_p"); + crypto_chk_return(ccm_p_padding == TD_NULL, TD_FAILURE, "crypto_malloc_coherent failed\n"); + /* ccm_p_padding must be zeros. */ + (td_void)memset_s(ccm_p_padding, CRYPTO_AES_BLOCK_SIZE_IN_BYTES, 0, CRYPTO_AES_BLOCK_SIZE_IN_BYTES); + + if (data_len % CRYPTO_AES_BLOCK_SIZE_IN_BYTES != 0) { + ccm_p_padding_len = CRYPTO_AES_BLOCK_SIZE_IN_BYTES - data_len % CRYPTO_AES_BLOCK_SIZE_IN_BYTES; + } + /* If padding_len == 0, then as the last node. */ + ccm_p_type |= (ccm_p_padding_len == 0 ? IN_NODE_TYPE_LAST : 0); + ret = hal_cipher_symc_ccm_mac_update(chn_num, data_phys_addr, data_len, IN_NODE_TYPE_FIRST | ccm_p_type); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "hal_cipher_symc_ccm_mac_update failed\n"); + + /* If paddding_len != 0, then ccm_p_padding as the last node. */ + if (ccm_p_padding_len != 0) { + ret = hal_cipher_symc_ccm_mac_update(chn_num, crypto_get_phys_addr(ccm_p_padding), ccm_p_padding_len, + IN_NODE_TYPE_LAST); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "hal_cipher_symc_ccm_mac_update failed\n"); + } + +exit_free: + (td_void)memset_s(ccm_p_padding, CRYPTO_AES_BLOCK_SIZE_IN_BYTES, 0, CRYPTO_AES_BLOCK_SIZE_IN_BYTES); + crypto_free_coherent(ccm_p_padding); + return ret; +} + +static td_s32 hal_symc_process_ccm_p_final(td_u32 chn_num) +{ + td_s32 ret; + td_u32 pre_idx_out = 0; + crypto_symc_entry_out *pre_entry_out = TD_NULL; + td_phys_addr_t pre_phys_addr = 0; + td_u8 *ccm_p_padding = TD_NULL; + td_u32 ccm_p_padding_len = 0; + td_u32 pre_length = 0; + in_node_type_e ccm_p_type = IN_NODE_TYPE_NORMAL; + + crypto_symc_hard_context *hard_ctx = TD_NULL; + hard_ctx = &g_symc_hard_context[chn_num]; + + ccm_p_padding = crypto_malloc_coherent(CRYPTO_AES_BLOCK_SIZE_IN_BYTES, "cipher_ccm_p_f"); + crypto_chk_return(ccm_p_padding == TD_NULL, TD_FAILURE, "crypto_malloc_coherent failed\n"); + /* ccm_p_padding must be zeros. */ + (td_void)memset_s(ccm_p_padding, CRYPTO_AES_BLOCK_SIZE_IN_BYTES, 0, CRYPTO_AES_BLOCK_SIZE_IN_BYTES); + + /* Get the previous node, beacuse it contains the plain_text's addr&length. */ + pre_idx_out = (hard_ctx->idx_out + CRYPTO_SYMC_MAX_LIST_NUM - 1) % CRYPTO_SYMC_MAX_LIST_NUM; + pre_entry_out = &hard_ctx->entry_out[pre_idx_out]; + pre_phys_addr = pre_entry_out->sym_start_addr; + pre_length = pre_entry_out->sym_alg_length; + + if (pre_length % CRYPTO_AES_BLOCK_SIZE_IN_BYTES != 0) { + ccm_p_padding_len = CRYPTO_AES_BLOCK_SIZE_IN_BYTES - pre_length % CRYPTO_AES_BLOCK_SIZE_IN_BYTES; + } + + /* If padding_len == 0, then as the last node. */ + ccm_p_type |= (ccm_p_padding_len == 0 ? IN_NODE_TYPE_LAST : 0); + ret = hal_cipher_symc_ccm_mac_update(chn_num, pre_phys_addr, pre_length, IN_NODE_TYPE_FIRST | ccm_p_type); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "hal_cipher_symc_ccm_mac_update failed\n"); + + /* If paddding_len != 0, then ccm_p_padding as the last node. */ + if (ccm_p_padding_len != 0) { + ret = hal_cipher_symc_ccm_mac_update(chn_num, crypto_get_phys_addr(ccm_p_padding), + ccm_p_padding_len, IN_NODE_TYPE_LAST); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "hal_cipher_symc_ccm_mac_update failed\n"); + } + +exit_free: + if (ccm_p_padding != TD_NULL) { + (td_void)memset_s(ccm_p_padding, CRYPTO_AES_BLOCK_SIZE_IN_BYTES, 0, CRYPTO_AES_BLOCK_SIZE_IN_BYTES); + crypto_free_coherent(ccm_p_padding); + } + return TD_SUCCESS; +} + +static td_s32 hal_symc_process_gcm_p_pre(td_u32 chn_num, td_phys_addr_t data_phys_addr, td_u32 data_len) +{ + td_s32 ret; + td_u8 *gcm_p_padding = TD_NULL; + td_u32 gcm_p_padding_len = 0; + in_node_type_e gcm_p_type = IN_NODE_TYPE_NORMAL; + + gcm_p_padding = crypto_malloc_coherent(CRYPTO_AES_BLOCK_SIZE_IN_BYTES, "cipher_gcm_p_p"); + crypto_chk_return(gcm_p_padding == TD_NULL, TD_FAILURE, "crypto_malloc_coherent failed\n"); + /* gcm_p_padding must be zeros. */ + (td_void)memset_s(gcm_p_padding, CRYPTO_AES_BLOCK_SIZE_IN_BYTES, 0, CRYPTO_AES_BLOCK_SIZE_IN_BYTES); + + if (data_len % CRYPTO_AES_BLOCK_SIZE_IN_BYTES != 0) { + gcm_p_padding_len = CRYPTO_AES_BLOCK_SIZE_IN_BYTES - data_len % CRYPTO_AES_BLOCK_SIZE_IN_BYTES; + } + /* If padding_len == 0, then as the last node. */ + gcm_p_type |= (gcm_p_padding_len == 0 ? IN_NODE_TYPE_LAST : 0); + ret = hal_cipher_symc_gcm_mac_update(chn_num, data_phys_addr, data_len, IN_NODE_TYPE_FIRST | gcm_p_type); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "hal_cipher_symc_gcm_mac_update failed\n"); + + /* If paddding_len != 0, then gcm_p_padding as the last node. */ + if (gcm_p_padding_len != 0) { + ret = hal_cipher_symc_gcm_mac_update(chn_num, crypto_get_phys_addr(gcm_p_padding), gcm_p_padding_len, + IN_NODE_TYPE_LAST); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "hal_cipher_symc_gcm_mac_update failed\n"); + } + +exit_free: + (td_void)memset_s(gcm_p_padding, CRYPTO_AES_BLOCK_SIZE_IN_BYTES, 0, CRYPTO_AES_BLOCK_SIZE_IN_BYTES); + crypto_free_coherent(gcm_p_padding); + return ret; +} + +static td_s32 hal_symc_process_gcm_p_final(td_u32 chn_num) +{ + td_s32 ret; + td_u32 pre_idx_out = 0; + crypto_symc_entry_out *pre_entry_out = TD_NULL; + td_phys_addr_t pre_phys_addr = 0; + td_u8 *gcm_p_padding = TD_NULL; + td_u32 gcm_p_padding_len = 0; + td_u32 pre_length = 0; + in_node_type_e gcm_p_type = IN_NODE_TYPE_NORMAL; + + crypto_symc_hard_context *hard_ctx = TD_NULL; + hard_ctx = &g_symc_hard_context[chn_num]; + + gcm_p_padding = crypto_malloc_coherent(CRYPTO_AES_BLOCK_SIZE_IN_BYTES, "cipher_gcm_p_f"); + crypto_chk_return(gcm_p_padding == TD_NULL, TD_FAILURE, "crypto_malloc_coherent failed\n"); + /* gcm_p_padding must be zeros. */ + (td_void)memset_s(gcm_p_padding, CRYPTO_AES_BLOCK_SIZE_IN_BYTES, 0, CRYPTO_AES_BLOCK_SIZE_IN_BYTES); + + /* Get the previous node, beacuse it contains the cipher_text's addr&length. */ + pre_idx_out = (hard_ctx->idx_out + CRYPTO_SYMC_MAX_LIST_NUM - 1) % CRYPTO_SYMC_MAX_LIST_NUM; + pre_entry_out = &hard_ctx->entry_out[pre_idx_out]; + pre_phys_addr = pre_entry_out->sym_start_addr; + pre_length = pre_entry_out->sym_alg_length; + + if (pre_length % CRYPTO_AES_BLOCK_SIZE_IN_BYTES != 0) { + gcm_p_padding_len = CRYPTO_AES_BLOCK_SIZE_IN_BYTES - pre_length % CRYPTO_AES_BLOCK_SIZE_IN_BYTES; + } + + /* If padding_len == 0, then as the last node. */ + gcm_p_type |= (gcm_p_padding_len == 0 ? IN_NODE_TYPE_LAST : 0); + ret = hal_cipher_symc_gcm_mac_update(chn_num, pre_phys_addr, pre_length, IN_NODE_TYPE_FIRST | gcm_p_type); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "hal_cipher_symc_gcm_mac_update failed\n"); + + /* If paddding_len != 0, then gcm_p_padding as the last node. */ + if (gcm_p_padding_len != 0) { + ret = hal_cipher_symc_gcm_mac_update(chn_num, crypto_get_phys_addr(gcm_p_padding), + gcm_p_padding_len, IN_NODE_TYPE_LAST); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "hal_cipher_symc_gcm_mac_update failed\n"); + } + +exit_free: + if (gcm_p_padding != TD_NULL) { + (td_void)memset_s(gcm_p_padding, CRYPTO_AES_BLOCK_SIZE_IN_BYTES, 0, CRYPTO_AES_BLOCK_SIZE_IN_BYTES); + crypto_free_coherent(gcm_p_padding); + } + return TD_SUCCESS; +} + +static td_s32 hal_wait_in_node_done(td_u32 chn_num) +{ + td_u32 i; + td_u32 data_len = 0; + in_sym_chn_node_wr_point in_node_wr_ptr = {0}; + in_sym_chn_node_rd_point in_node_rd_ptr = {0}; + + for (i = 0; i < CRYPTO_SYMC_WAIT_TIMEOUT; i++) { + in_node_wr_ptr.u32 = spacc_reg_read(IN_SYM_CHN_NODE_WR_POINT(chn_num)); + in_node_rd_ptr.u32 = spacc_reg_read(IN_SYM_CHN_NODE_RD_POINT(chn_num)); + data_len = spacc_reg_read(DBG_IN_SYM_CHN_DATA_LEN(chn_num)); + if ((in_node_rd_ptr.bits.sym_chn_node_rd_point == in_node_wr_ptr.bits.sym_chn_node_wr_point) && + (data_len == 0)) { + break; + } + crypto_udelay(1); + } + + if (i >= CRYPTO_SYMC_WAIT_TIMEOUT) { + crypto_log_err("hal_wait_in_node_done Timeout!\n"); + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +static td_s32 hal_wait_out_node_done(td_u32 chn_num) +{ + td_u32 i; + + out_sym_chn_node_wr_point out_node_wr_ptr = {0}; + out_sym_chn_node_rd_point out_node_rd_ptr = {0}; + + for (i = 0; i < CRYPTO_SYMC_WAIT_TIMEOUT; i++) { + out_node_wr_ptr.u32 = spacc_reg_read(OUT_SYM_CHN_NODE_WR_POINT(chn_num)); + out_node_rd_ptr.u32 = spacc_reg_read(OUT_SYM_CHN_NODE_RD_POINT(chn_num)); + if (out_node_rd_ptr.bits.sym_chn_node_rd_point == out_node_wr_ptr.bits.sym_chn_node_wr_point) { + break; + } + crypto_udelay(1); + } + + if (i >= CRYPTO_SYMC_WAIT_TIMEOUT) { + crypto_log_err("hal_wait_out_node_done Timeout!\n"); + return TD_FAILURE; + } + + return TD_SUCCESS; +} + +static td_s32 symc_wait_done(td_u32 chn_num, td_bool is_wait, crypto_symc_hard_context *hard_ctx) +{ + td_s32 ret = CRYPTO_SUCCESS; + td_u32 i = 0; + (void)(is_wait); + if ((hard_ctx->is_wait == TD_TRUE) && (hard_ctx->wait_func != TD_NULL)) { + ret = hard_ctx->wait_func(hard_ctx->wait, hal_symc_condition, (td_void *)(&chn_num), hard_ctx->timeout_ms); + if (ret <= 0) { + crypto_log_err("wait_func Timeout!\n"); + ret = SYMC_COMPAT_ERRNO(ERROR_SYMC_CALC_TIMEOUT); + } + } else { + for (i = 0; i < CRYPTO_SYMC_WAIT_TIMEOUT; i++) { + ret = hal_cipher_symc_done_try(chn_num); + if (ret == TD_SUCCESS) { + break; + } + crypto_udelay(1); + } + if (i >= CRYPTO_SYMC_WAIT_TIMEOUT) { + ret = SYMC_COMPAT_ERRNO(ERROR_SYMC_CALC_TIMEOUT); + } + } + if (ret == SYMC_COMPAT_ERRNO(ERROR_SYMC_CALC_TIMEOUT)) { + hal_cipher_symc_debug(); + hal_cipher_symc_debug_chn(chn_num); + } else { + ret = CRYPTO_SUCCESS; + } + + return ret; +} + +td_s32 hal_cipher_symc_wait_done(td_u32 chn_num, td_bool is_wait) +{ + td_s32 ret; + crypto_symc_hard_context *hard_ctx = TD_NULL; + crypto_hal_func_enter(); + + hard_ctx = &g_symc_hard_context[chn_num]; + + if (hard_ctx->symc_config.work_mode == CRYPTO_SYMC_WORK_MODE_CBC_MAC) { + ret = hal_cipher_symc_wait_noout_done(chn_num); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_wait_noout_done failed\n"); + return ret; + } + + ret = symc_wait_done(chn_num, is_wait, hard_ctx); + inner_symc_irq_enable(chn_num, TD_FALSE); + if (ret == SYMC_COMPAT_ERRNO(ERROR_HASH_CALC_TIMEOUT)) { + crypto_log_err("symc wait done timeout, chn is %u\n", chn_num); + hal_cipher_symc_debug(); + hal_cipher_symc_debug_chn(chn_num); + return ret; + } + + hal_cipher_symc_get_iv(chn_num, hard_ctx->iv_ctr, sizeof(hard_ctx->iv_ctr)); + + /* For CCM Decrypt, you should mac_update plain_text after decrypt. */ + if (hard_ctx->symc_config.work_mode == CRYPTO_SYMC_WORK_MODE_CCM && hard_ctx->symc_config.is_decrypt == TD_TRUE) { + ret = hal_symc_process_ccm_p_final(chn_num); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_symc_process_ccm_p_final failed\n"); + } + + /* For GCM Encrypt, you should mac_update cipher_text after encrypt. */ + if (hard_ctx->symc_config.work_mode == CRYPTO_SYMC_WORK_MODE_GCM && hard_ctx->symc_config.is_decrypt == TD_FALSE) { + ret = hal_symc_process_gcm_p_final(chn_num); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_symc_process_gcm_p_final failed\n"); + } + + crypto_dcache_enable(); + + crypto_hal_func_exit(); + return TD_SUCCESS; +} + +static td_s32 hal_cipher_symc_ccm_mac_update(td_u32 chn_num, td_phys_addr_t data_phys_addr, td_u32 data_len, + in_node_type_e in_node_type) +{ + td_s32 ret; + in_sym_chn_key_ctrl in_key_ctrl = {0}; + crypto_symc_hard_context *hard_ctx = TD_NULL; + + crypto_hal_func_enter(); + + hard_ctx = &g_symc_hard_context[chn_num]; + + ret = priv_set_in_node(chn_num, data_phys_addr, data_len, in_node_type); + crypto_chk_return(ret != TD_SUCCESS, ret, "priv_set_in_node failed\n"); + + /* To mac_update, you should choose MODE_CBC_NOOUT. */ + in_key_ctrl.u32 = spacc_reg_read(IN_SYM_CHN_KEY_CTRL(chn_num)); + in_key_ctrl.bits.sym_alg_mode = SYMC_ALG_MODE_CBC_NOOUT_VAL; + in_key_ctrl.bits.sym_alg_decrypt = TD_FALSE; + spacc_reg_write(IN_SYM_CHN_KEY_CTRL(chn_num), in_key_ctrl.u32); + +#if defined(CRYPTO_CCM_TRACE_ENABLE) + crypto_dump_data("iv_mac before update", hard_ctx->symc_config.iv_mac, sizeof(hard_ctx->symc_config.iv_mac)); +#endif + /* You should set iv_mac before mac_update. */ + ret = hal_cipher_symc_set_iv(chn_num, hard_ctx->symc_config.iv_mac, sizeof(hard_ctx->symc_config.iv_mac)); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_set_iv failed\n"); + + hard_ctx->cnt_in++; + hard_ctx->idx_in++; + hard_ctx->idx_in %= CRYPTO_SYMC_MAX_LIST_NUM; + + hal_cipher_symc_start(chn_num); + + /** + * For last node, you need to wait until the interrupt(SYM_CHANN_RAW_INT) occurs; + * Others, you only need to wait until in_node_wr_ptr == in_node_rd_ptr. + * + **/ + if (in_node_type & IN_NODE_TYPE_LAST) { + ret = hal_cipher_symc_wait_noout_done(chn_num); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_wait_noout_done failed\n"); + } else { + ret = hal_wait_in_node_done(chn_num); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_wait_in_node_done failed\n"); + } + + /* You should update iv_mac after mac_update. */ + ret = hal_cipher_symc_get_iv(chn_num, hard_ctx->symc_config.iv_mac, sizeof(hard_ctx->symc_config.iv_mac)); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_get_iv failed\n"); + +#if defined(CRYPTO_CCM_TRACE_ENABLE) + crypto_dump_phys_addr("ccm update data", data_phys_addr, data_len); + crypto_dump_data("ccm iv_mac update", hard_ctx->symc_config.iv_mac, sizeof(hard_ctx->symc_config.iv_mac)); +#endif + return TD_SUCCESS; +} + +static td_s32 hal_cipher_symc_gcm_mac_update(td_u32 chn_num, td_phys_addr_t data_phys_addr, td_u32 data_len, + in_node_type_e in_node_type) +{ + td_s32 ret; + in_sym_chn_key_ctrl in_key_ctrl = {0}; + crypto_symc_hard_context *hard_ctx = TD_NULL; + + crypto_hal_func_enter(); + + hard_ctx = &g_symc_hard_context[chn_num]; + + ret = priv_set_in_node(chn_num, data_phys_addr, data_len, in_node_type); + crypto_chk_return(ret != TD_SUCCESS, ret, "priv_set_in_node failed\n"); + + /* To gcm_mac_update, you should choose ALG_GHASH. */ + in_key_ctrl.u32 = spacc_reg_read(IN_SYM_CHN_KEY_CTRL(chn_num)); + in_key_ctrl.bits.sym_alg_sel = SYMC_ALG_GHASH_VAL; + /* symc_alg_mode must be 0 for GHASH, otherwise the calculation will timeout. */ + in_key_ctrl.bits.sym_alg_mode = 0; + in_key_ctrl.bits.sym_alg_decrypt = TD_FALSE; + spacc_reg_write(IN_SYM_CHN_KEY_CTRL(chn_num), in_key_ctrl.u32); + + /** + * You should set iv before mac_update. + * For GCM_HASH, the iv is gcm_j0; otherwise the iv is iv_ghash. + **/ + if (in_node_type & IN_NODE_TYPE_GCM_GHASH) { + ret = hal_cipher_symc_set_iv(chn_num, hard_ctx->symc_config.iv0, sizeof(hard_ctx->symc_config.iv0)); + } else { + ret = hal_cipher_symc_set_iv(chn_num, hard_ctx->symc_config.iv_mac, sizeof(hard_ctx->symc_config.iv_mac)); + } + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_set_iv failed\n"); + + hard_ctx->cnt_in++; + hard_ctx->idx_in++; + hard_ctx->idx_in %= CRYPTO_SYMC_MAX_LIST_NUM; + + hal_cipher_symc_start(chn_num); + + /** + * For last node, you need to wait until the interrupt(SYM_CHANN_RAW_INT) occurs; + * Others, you only need to wait until in_node_wr_ptr == in_node_rd_ptr. + * + **/ + if (in_node_type & IN_NODE_TYPE_LAST) { + ret = hal_cipher_symc_wait_noout_done(chn_num); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_wait_noout_done failed\n"); + } else { + ret = hal_wait_in_node_done(chn_num); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_wait_in_node_done failed\n"); + } + +#ifdef CRYPTO_GCM_TRACE_ENABLE + crypto_dump_data("iv_ghash", hard_ctx->symc_config.iv_mac, sizeof(hard_ctx->symc_config.iv_mac)); +#endif + + /* You should update iv_ghash after mac_update. For GCM_IV, no need to update iv_ghash. */ + if (!(in_node_type & IN_NODE_TYPE_GCM_IV)) { + ret = hal_cipher_symc_get_iv(chn_num, hard_ctx->symc_config.iv_mac, sizeof(hard_ctx->symc_config.iv_mac)); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_get_iv failed\n"); + } +#ifdef CRYPTO_GCM_TRACE_ENABLE + crypto_dump_data("iv_ghash_next", hard_ctx->symc_config.iv_mac, sizeof(hard_ctx->symc_config.iv_mac)); +#endif + return TD_SUCCESS; +} + +static td_s32 add_normal_in_node(td_u32 chn_num, td_phys_addr_t data_phys_addr, td_u32 data_len, + in_node_type_e in_node_type) +{ + td_s32 ret; + crypto_symc_hard_context *hard_ctx = TD_NULL; + crypto_hal_func_enter(); + + hard_ctx = &g_symc_hard_context[chn_num]; + + ret = priv_set_in_node(chn_num, data_phys_addr, data_len, in_node_type); + crypto_chk_return(ret != TD_SUCCESS, ret, "priv_set_in_node failed\n"); + + hard_ctx->idx_in++; + hard_ctx->cnt_in++; + hard_ctx->idx_in %= CRYPTO_SYMC_MAX_LIST_NUM; + + crypto_hal_func_exit(); + return TD_SUCCESS; +} + +static td_s32 add_ccm_in_node(td_u32 chn_num, td_phys_addr_t data_phys_addr, td_u32 data_len, + in_node_type_e in_node_type) +{ + td_s32 ret; + crypto_symc_hard_context *hard_ctx = TD_NULL; + in_sym_chn_key_ctrl in_key_ctrl; + + crypto_hal_func_enter(); + + hard_ctx = &g_symc_hard_context[chn_num]; + + /* For CCM_N and CCM_AAD, you should mac_update them. */ + if ((in_node_type & IN_NODE_TYPE_CCM_N) || (in_node_type & IN_NODE_TYPE_CCM_AAD)) { + ret = hal_cipher_symc_ccm_mac_update(chn_num, data_phys_addr, data_len, in_node_type); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_ccm_mac_update failed\n"); + return TD_SUCCESS; + } + + /* For CCM Encrypt, you should mac_update plain_text before encrypt. */ + if ((in_node_type & IN_NODE_TYPE_CCM_P) && (hard_ctx->symc_config.is_decrypt == TD_FALSE)) { + hal_symc_process_ccm_p_pre(chn_num, data_phys_addr, data_len); + } + + /* For ccm, the work_mode is CTR and the iv is iv_ctr. */ + if (in_node_type & IN_NODE_TYPE_CCM_P) { + in_key_ctrl.u32 = spacc_reg_read(IN_SYM_CHN_KEY_CTRL(chn_num)); + in_key_ctrl.bits.sym_alg_mode = SYMC_ALG_MODE_CTR_VAL; + spacc_reg_write(IN_SYM_CHN_KEY_CTRL(chn_num), in_key_ctrl.u32); + hal_cipher_symc_set_iv(chn_num, hard_ctx->iv_ctr, sizeof(hard_ctx->iv_ctr)); + } + + ret = priv_set_in_node(chn_num, data_phys_addr, data_len, in_node_type); + crypto_chk_return(ret != TD_SUCCESS, ret, "priv_set_in_node failed\n"); + + hard_ctx->idx_in++; + hard_ctx->cnt_in++; + hard_ctx->idx_in %= CRYPTO_SYMC_MAX_LIST_NUM; + + crypto_hal_func_exit(); + return TD_SUCCESS; +} + +static td_s32 add_gcm_in_node(td_u32 chn_num, td_phys_addr_t data_phys_addr, td_u32 data_len, + in_node_type_e in_node_type) +{ + td_s32 ret; + crypto_symc_hard_context *hard_ctx = TD_NULL; + in_sym_chn_key_ctrl in_key_ctrl; + + crypto_hal_func_enter(); + + hard_ctx = &g_symc_hard_context[chn_num]; + + /* For GCM_AAD, you should mac_update it. */ + if (in_node_type & IN_NODE_TYPE_GCM_A) { + ret = hal_cipher_symc_gcm_mac_update(chn_num, data_phys_addr, data_len, in_node_type); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_gcm_mac_update failed\n"); + return TD_SUCCESS; + } + /* For GCM_LEN, you should store it and mac_update it when get_tag. */ + if (in_node_type & IN_NODE_TYPE_GCM_LEN) { + hard_ctx->gcm_len_addr = data_phys_addr; + return TD_SUCCESS; + } + + /* For GCM Decrypt, you should mac_update plain_text before decrypt. */ + if ((in_node_type & IN_NODE_TYPE_GCM_P) && (hard_ctx->symc_config.is_decrypt == TD_TRUE)) { + hal_symc_process_gcm_p_pre(chn_num, data_phys_addr, data_len); + } + + /* For GCM_GHASH, the work_mode is MODE_GCTR_NOOUT and the iv is j0. */ + if (in_node_type & IN_NODE_TYPE_GCM_GHASH) { + in_key_ctrl.u32 = spacc_reg_read(IN_SYM_CHN_KEY_CTRL(chn_num)); + in_key_ctrl.bits.sym_alg_sel = SYMC_ALG_AES_VAL; + in_key_ctrl.bits.sym_alg_mode = SYMC_ALG_MODE_GCTR_NOOUT_VAL; + spacc_reg_write(IN_SYM_CHN_KEY_CTRL(chn_num), in_key_ctrl.u32); + hal_cipher_symc_set_iv(chn_num, hard_ctx->symc_config.iv0, sizeof(hard_ctx->symc_config.iv0)); + } + + /* For gcm, the work_mode is GCTR and the iv is gcm_iv. */ + if (in_node_type & IN_NODE_TYPE_GCM_P) { + in_key_ctrl.u32 = spacc_reg_read(IN_SYM_CHN_KEY_CTRL(chn_num)); + in_key_ctrl.bits.sym_alg_sel = SYMC_ALG_AES_VAL; + in_key_ctrl.bits.sym_alg_mode = SYMC_ALG_MODE_GCTR_VAL; + spacc_reg_write(IN_SYM_CHN_KEY_CTRL(chn_num), in_key_ctrl.u32); + hal_cipher_symc_set_iv(chn_num, hard_ctx->iv_ctr, sizeof(hard_ctx->iv_ctr)); + } + ret = priv_set_in_node(chn_num, data_phys_addr, data_len, in_node_type); + crypto_chk_return(ret != TD_SUCCESS, ret, "priv_set_in_node failed\n"); + + hard_ctx->idx_in++; + hard_ctx->cnt_in++; + hard_ctx->idx_in %= CRYPTO_SYMC_MAX_LIST_NUM; + + crypto_hal_func_exit(); + return TD_SUCCESS; +} + +static td_s32 add_cbc_mac_in_node(td_u32 chn_num, td_phys_addr_t data_phys_addr, td_u32 data_len, + in_node_type_e in_node_type) +{ + td_s32 ret; + crypto_symc_hard_context *hard_ctx = TD_NULL; + in_sym_chn_key_ctrl in_key_ctrl; + + crypto_hal_func_enter(); + + hard_ctx = &g_symc_hard_context[chn_num]; + + in_key_ctrl.u32 = spacc_reg_read(IN_SYM_CHN_KEY_CTRL(chn_num)); + in_key_ctrl.bits.sym_alg_sel = SYMC_ALG_AES_VAL; + in_key_ctrl.bits.sym_alg_mode = SYMC_ALG_MODE_CBC_NOOUT_VAL; + spacc_reg_write(IN_SYM_CHN_KEY_CTRL(chn_num), in_key_ctrl.u32); + + ret = priv_set_in_node(chn_num, data_phys_addr, data_len, in_node_type); + crypto_chk_return(ret != TD_SUCCESS, ret, "priv_set_in_node failed\n"); + + hard_ctx->idx_in++; + hard_ctx->cnt_in++; + hard_ctx->idx_in %= CRYPTO_SYMC_MAX_LIST_NUM; + + crypto_hal_func_exit(); + return TD_SUCCESS; +} + +td_s32 hal_cipher_symc_add_in_node(td_u32 chn_num, td_phys_addr_t data_phys_addr, td_u32 data_len, + in_node_type_e in_node_type) +{ + td_s32 ret; + crypto_symc_hard_context *hard_ctx = TD_NULL; + + crypto_hal_func_enter(); + crypto_chk_return(data_phys_addr == 0, SYMC_COMPAT_ERRNO(ERROR_INVALID_PHYS_ADDR), "data_phys_addr is invalid\n"); + + hard_ctx = &g_symc_hard_context[chn_num]; + switch (hard_ctx->symc_config.work_mode) { + case CRYPTO_SYMC_WORK_MODE_CCM: + ret = add_ccm_in_node(chn_num, data_phys_addr, data_len, in_node_type); + break; + case CRYPTO_SYMC_WORK_MODE_GCM: + ret = add_gcm_in_node(chn_num, data_phys_addr, data_len, in_node_type); + break; + case CRYPTO_SYMC_WORK_MODE_CBC_MAC: + ret = add_cbc_mac_in_node(chn_num, data_phys_addr, data_len, in_node_type); + break; + default: + ret = add_normal_in_node(chn_num, data_phys_addr, data_len, in_node_type); + break; + } + + crypto_hal_func_exit(); + return ret; +} + +td_s32 hal_cipher_symc_add_out_node(td_u32 chn_num, td_phys_addr_t data_phys_addr, td_u32 data_len) +{ + td_s32 ret; + crypto_symc_hard_context *hard_ctx = TD_NULL; + crypto_symc_entry_out *entry_out = TD_NULL; + td_u32 idx_in; + td_u32 idx_out; + crypto_hal_func_enter(); + crypto_chk_return(data_phys_addr == 0, SYMC_COMPAT_ERRNO(ERROR_INVALID_PHYS_ADDR), "data_phys_addr is invalid\n"); + + hard_ctx = &g_symc_hard_context[chn_num]; + idx_out = hard_ctx->idx_out; + if (hard_ctx->entry_out == TD_NULL) { + crypto_log_err("hard_ctx->entry_out is NULL\n"); + return TD_FAILURE; + } + entry_out = &hard_ctx->entry_out[idx_out]; + + entry_out->sym_alg_length = data_len; + entry_out->sym_start_addr = data_phys_addr; + entry_out->sym_start_high = 0; + + hard_ctx->idx_out++; + hard_ctx->cnt_out++; + hard_ctx->idx_out %= CRYPTO_SYMC_MAX_LIST_NUM; + + idx_in = (hard_ctx->idx_in + CRYPTO_SYMC_MAX_LIST_NUM - 1) % CRYPTO_SYMC_MAX_LIST_NUM; + + if (hard_ctx->entry_in[idx_in].sym_last_node == 0 && + hard_ctx->symc_config.work_mode != CRYPTO_SYMC_WORK_MODE_CCM && + hard_ctx->symc_config.work_mode != CRYPTO_SYMC_WORK_MODE_GCM) { + ret = hal_cipher_symc_start(chn_num); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_start failed\n"); + + ret = hal_wait_out_node_done(chn_num); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_wait_out_node_done failed\n"); + } + + crypto_hal_func_exit(); + return TD_SUCCESS; +} + +td_s32 hal_cipher_symc_get_tag(td_u32 chn_num, td_u8 *tag, td_u32 tag_len) +{ + td_s32 ret; + td_u32 i; + crypto_symc_hard_context *hard_ctx = TD_NULL; + td_u8 *iv_ghash = TD_NULL; + + hard_ctx = &g_symc_hard_context[chn_num]; + /* For CCM, the tag is MSB(s0^iv_mac). */ + if (hard_ctx->symc_config.work_mode == CRYPTO_SYMC_WORK_MODE_CCM) { +#if defined(CRYPTO_CCM_TRACE_ENABLE) + crypto_dump_data("get tag s0", hard_ctx->symc_config.iv0, sizeof(hard_ctx->symc_config.iv0)); + crypto_dump_data("get tag iv_mac", hard_ctx->symc_config.iv_mac, sizeof(hard_ctx->symc_config.iv_mac)); +#endif + for (i = 0; i < tag_len; i++) { + tag[i] = hard_ctx->symc_config.iv0[i] ^ hard_ctx->symc_config.iv_mac[i]; + } + } else if (hard_ctx->symc_config.work_mode == CRYPTO_SYMC_WORK_MODE_GCM) { + if (hard_ctx->gcm_len_addr == 0) { + crypto_log_err("hard_ctx->gcm_len_addr is zero\n"); + return SYMC_COMPAT_ERRNO(ERROR_UNEXPECTED); + } +#if defined(CRYPTO_GCM_TRACE_ENABLE) + crypto_log_dbg("gcm_len_addr is 0x%llx\n", hard_ctx->gcm_len_addr); + crypto_dump_phys_addr("get tag gcm_len", hard_ctx->gcm_len_addr, CRYPTO_AES_IV_SIZE); +#endif + ret = hal_cipher_symc_gcm_mac_update(chn_num, hard_ctx->gcm_len_addr, CRYPTO_AES_IV_SIZE, + IN_NODE_TYPE_FIRST | IN_NODE_TYPE_LAST); + crypto_chk_return(ret != TD_SUCCESS, ret, "hal_cipher_symc_gcm_mac_update failed\n"); + + iv_ghash = crypto_malloc_coherent(sizeof(hard_ctx->symc_config.iv_mac), "cipher_get_tag"); + crypto_chk_return(iv_ghash == TD_NULL, TD_FAILURE, "crypto_malloc_coherent failed\n"); + + ret = memcpy_s(iv_ghash, sizeof(hard_ctx->symc_config.iv_mac), + hard_ctx->symc_config.iv_mac, sizeof(hard_ctx->symc_config.iv_mac)); + crypto_chk_goto(ret != EOK, exit_free, "memcpy_s failed\n"); + + ret = hal_cipher_symc_add_in_node(chn_num, crypto_get_phys_addr(iv_ghash), sizeof(hard_ctx->symc_config.iv_mac), + IN_NODE_TYPE_FIRST | IN_NODE_TYPE_LAST | IN_NODE_TYPE_GCM_GHASH); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "hal_cipher_symc_add_in_node failed\n"); + + ret = hal_cipher_symc_start(chn_num); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "hal_cipher_symc_start failed\n"); + + ret = hal_cipher_symc_wait_noout_done(chn_num); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "hal_cipher_symc_wait_noout_done failed\n"); + + ret = hal_cipher_symc_get_iv(chn_num, tag, tag_len); + crypto_chk_goto(ret != TD_SUCCESS, exit_free, "hal_cipher_symc_get_iv failed\n"); +#if defined(CRYPTO_CCM_TRACE_ENABLE) || defined(CRYPTO_GCM_TRACE_ENABLE) + crypto_dump_data("get tag", tag, tag_len); +#endif + } + + /* Clear iv_ghash. */ + (td_void)memset_s(hard_ctx->symc_config.iv_mac, sizeof(hard_ctx->symc_config.iv_mac), + 0, sizeof(hard_ctx->symc_config.iv_mac)); + (td_void)memset_s(hard_ctx->symc_config.iv0, sizeof(hard_ctx->symc_config.iv0), + 0, sizeof(hard_ctx->symc_config.iv0)); +exit_free: + if (iv_ghash != TD_NULL) { + (td_void)memset_s(iv_ghash, sizeof(hard_ctx->symc_config.iv_mac), 0, sizeof(hard_ctx->symc_config.iv_mac)); + crypto_free_coherent(iv_ghash); + } + + return TD_SUCCESS; +} + +#if defined(CRYPTO_OS_INT_SUPPORT) +td_s32 hal_cipher_symc_register_wait_func(td_u32 chn_num, td_void *wait, + crypto_wait_timeout_interruptible wait_func, td_u32 timeout_ms) +{ + crypto_symc_hard_context *hard_ctx = TD_NULL; + crypto_hal_func_enter(); + + hard_ctx = &g_symc_hard_context[chn_num]; + hard_ctx->wait = wait; + hard_ctx->wait_func = wait_func; + hard_ctx->timeout_ms = timeout_ms; + + if (wait_func != TD_NULL) { + inner_spacc_interrupt_enable(TD_TRUE); + } + crypto_hal_func_exit(); + return TD_SUCCESS; +} +#endif + +td_void hal_cipher_set_chn_secure(td_u32 chn_num, td_bool dest_sec, td_bool src_sec) +{ + crypto_unused(chn_num); + crypto_unused(dest_sec); + crypto_unused(src_sec); + + return; +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/trng_v4/hal_trng.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/trng_v4/hal_trng.c new file mode 100644 index 00000000..85d05122 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/trng_v4/hal_trng.c @@ -0,0 +1,73 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "hal_trng.h" +#include "hal_trng_reg.h" + +#include "crypto_drv_common.h" + +#define TRNG_OSC_SEL 0x02 +#define TRNG_POWER_ON 0x05 +#define TRNG_POWER_OFF 0x0a + +#define TRNG_COMPAT_ERRNO(err_code) HAL_COMPAT_ERRNO(ERROR_MODULE_TRNG, err_code) + +static td_bool g_hal_trng_init_flag = TD_FALSE; + +td_s32 hal_cipher_trng_init(td_void) +{ + g_hal_trng_init_flag = TD_TRUE; + return TD_SUCCESS; +} + +td_s32 hal_cipher_trng_deinit(void) +{ + g_hal_trng_init_flag = TD_FALSE; + return TD_SUCCESS; +} + +#define CRYPTO_TRNG_TIMEOUT_IN_US 1000000 /* 10ms. */ +static td_bool is_trng_ready(void) +{ + hisc_com_trng_fifo_ready trng_ready = {0}; + + if (crypto_get_cpu_type() != CRYPTO_CPU_TYPE_SCPU) { /* Not check status on non-secure Core */ + return TD_TRUE; + } + + trng_ready.u32 = 0; /* trng not done, and not ready. */ + trng_ready.u32 = trng_reg_read(HISC_COM_TRNG_FIFO_READY); + + if ((trng_ready.bits).trng_done != TRNG_DONE || + (trng_ready.bits).trng_data_ready != TRNG_DATA_READY) { + return TD_FALSE; + } + return TD_TRUE; +} + +td_s32 hal_cipher_trng_get_random(td_u32 *randnum) +{ + td_u32 times = 0; + td_u32 chk_randnum = 0; + + crypto_chk_return(g_hal_trng_init_flag == TD_FALSE, TRNG_COMPAT_ERRNO(ERROR_NOT_INIT), "call init first!\n"); + crypto_chk_return(randnum == TD_NULL, TRNG_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "randnum is NULL\n"); + + while (times < CRYPTO_TRNG_TIMEOUT_IN_US) { + times++; + if (is_trng_ready() == TD_FALSE) { + continue; + } + + if (is_trng_ready() == TD_TRUE) { + *randnum = trng_reg_read(HISC_COM_TRNG_FIFO_DATA); + chk_randnum = trng_reg_read(HISC_COM_TRNG_FIFO_DATA); + if ((*randnum != 0x00000000) && (*randnum != 0xffffffff) && (*randnum != chk_randnum)) { + return TD_SUCCESS; + } + } + } + + return TRNG_COMPAT_ERRNO(ERROR_GET_TRNG_TIMEOUT); +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/trng_v4/hal_trng_reg.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/trng_v4/hal_trng_reg.h new file mode 100644 index 00000000..5a2a22fa --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/hal_code/trng_v4/hal_trng_reg.h @@ -0,0 +1,31 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef HAL_TRNG_REG_H +#define HAL_TRNG_REG_H + +#include "crypto_type.h" + +/*! \Define the offset of TRNG reg */ +#define HISC_COM_TRNG_FIFO_DATA (0x100) +#define HISC_COM_TRNG_FIFO_READY (0x104) +#define HISC_COM_TRNG_DATA_ST (0x108) + +#define TRNG_DONE 1 +#define TRNG_DATA_READY 1 + +/* Define the union hisc_com_trng_fifo_ready */ +typedef union { + /* Define the struct bits */ + struct { + td_u32 trng_data_ready : 1; /* [0] */ + td_u32 trng_done : 1; /* [1] */ + td_u32 reserved_0 : 30; /* [31..2] */ + } bits; + + /* Define an unsigned member */ + td_u32 u32; +} hisc_com_trng_fifo_ready; + +#endif diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_common_def.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_common_def.h new file mode 100644 index 00000000..82ce0a18 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_common_def.h @@ -0,0 +1,127 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef CRYPTO_COMMON_DEF_H +#define CRYPTO_COMMON_DEF_H + +#define MS_TO_US 1000 + +#define CRYPTO_BITS_IN_BYTE 8 + +#define CRYPTO_AES_IV_SIZE 16 +#define CRYPTO_AES_IV_SIZE_IN_WORD 4 +#define CRYPTO_WORD_WIDTH 4 +#define CRYPTO_IV_LEN_IN_BYTES 16 + +#define CRYPTO_128_KEY_LEN 16 +#define CRYPTO_192_KEY_LEN 24 +#define CRYPTO_256_KEY_LEN 32 + +#define CRYPTO_AES_MAX_TAG_SIZE 16 +#define CRYPTO_AES_CCM_N_LEN_IN_BYTES 16 + +#define CRYPTO_AES_BLOCK_SIZE_IN_BYTES 16 + +#define CRYPTO_BIT_3 3 +#define CRYPTO_BIT_6 6 +#define CRYPTO_BIT_8 8 +#define CRYPTO_BIT_16 16 +#define CRYPTO_BIT_24 24 +#define CRYPTO_BYTE_1 1 +#define CRYPTO_BYTE_2 2 +#define CRYPTO_BYTE_3 3 + +#define CRYPTO_AES_CCM_NQ_LEN 14 +#define CRYPTO_SYMC_CCM_Q_LEN_2B 2 +#define CRYPTO_SYMC_CCM_Q_LEN_3B 3 +#define CRYPTO_SYMC_CCM_Q_LEN_4B 4 + + +#define CRYPTO_GCM_SPECIAL_IV_BYTES 12 +#define CRYPTO_AES_MAX_TAG_LEN 16 + +#define CRYPTO_CENC_IV_LEN 8 + +#define CRYPTO_TYPE_ENCRYPT 0x0 +#define CRYPTO_TYPE_DECRYPT 0x1 +#define CRYPTO_TYPE_DMA 0x2 + +#define CRYPTO_RSA_2048_LEN 256 +#define CRYPTO_RSA_3072_LEN 384 +#define CRYPTO_RSA_4096_LEN 512 + +/* Memory Limit. */ +#define CRYPTO_MAX_AAD_SIZE (4 * 1024) +#define CRYPTO_MAX_CRYPTO_SIZE (4 * 1024) + +/* PBKDF2 Limits. */ +#define CRYPTO_PBKDF2_PASS_MAX_LENGTH 1024 +#define CRYPTO_PBKDF2_SALT_MAX_LENGTH 1024 +#define CRYPTO_PBKDF2_OUT_MAX_LENGTH 1024 +#define CRYPTO_PBKDF2_MAX_COUNT 100000 + +/* Hash Limits. */ +#define CRYPTO_HASH_KEY_MAX_LENGTH 128 +#define CRYPTO_HASH_MIN_LEN 20 +#define CRYPTO_HASH_MAX_LEN 64 +#define CRYPTO_HASH_UPDATE_MAX_LEN 0xffff0000 +#define CRYPTO_SHA256_BLOCK_SIZE 64 + +/* CENC Limits. */ +#define CRYPTO_SYMC_CENC_SUBSAMPLE_MAX_SIZE 200 + +/* SYMC Limits. */ +#define CRYPTO_SYMC_MULTI_PACK_MAX_SIZE 200 +#define CRYPTO_SYMC_AAD_MAX_SIZE (4 * 1024) +#define CRYPTO_SYMC_MAC_UPDATE_MAX_LEN 0xffff0000 + +/* PKE Limits. */ +#define CRYPTO_PKE_ECC_KEY_MIN_SIZE 32 +#define CRYPTO_PKE_ECC_KEY_MAX_SIZE 72 +#define CRYPTO_PKE_RSA_KEY_MIN_SIZE 256 +#define CRYPTO_PKE_RSA_KEY_MAX_SIZE 512 + +/* TRNG Limits. */ +#define CRYPTO_MULTI_RANDOM_MAX_LENGTH 1024 + +#define CRYPTO_PKE_MSG_MIN_SIZE 1 +#define CRYPTO_PKE_MSG_MAX_SIZE (2 * 1024 * 1024) +#define CRYPTO_PKE_SM2_ID_MIN_SIZE 1 +#define CRYPTO_PKE_SM2_ID_MAX_SIZE 1024 +#define CRYPTO_PKE_SM2_PLAIN_TEXT_MIN_SIZE 1 +#define CRYPTO_PKE_SM2_PLAIN_TEXT_MAX_SIZE 1024 +#define CRYPTO_PKE_RSA_LABLE_MAX_SIZE 1024 + +#define KAPI_SYMC_MODULE_ID 0x01 +#define KAPI_HASH_MODULE_ID 0x02 +#define KAPI_KEYSLOT_MODULE_ID 0x03 +#define KAPI_KLAD_MODULE_ID 0x04 +/* + * Handle Process + * Kapi Handle consists of the following parts: + *|<---- SOC_ID_CIPHER(8-bit) --->|<---- Reserved(7-bit) --->| + * <- Soft alg flag(1-bit) ->|<---- Module ID(8-bit) ---->|<---- Context Idx(8-bit)---->| + */ +#define crypto_set_soft_alg_flag(handle) ((handle) | 0x10000) +#define crypto_check_soft_alg_flag(handle) (((handle) >> 16) & 0x1) +#define crypto_get_soft_channel_id(handle) ((handle) & 0xff) + +#define kapi_get_module_id(kapi_handle) (((kapi_handle) >> 8) & 0xff) +#define kapi_get_ctx_idx(kapi_handle) ((kapi_handle) & 0xff) +#define synthesize_kapi_handle(module_id, ctx_id) (((0x33) << 24) | ((module_id) << 8) | (ctx_id)) + +/* + *|<---- Reserved(8-bit) --->|<- keyslot_type(8-bit) ->|<---- Module ID(8-bit) ---->|<---- Context Idx(8-bit)---->| + * keyslot_type: 0 - MCIPHER, 1 - HMAC + */ +#define crypto_keyslot_compat_handle(keyslot_type, idx) \ + (((keyslot_type) << 16) | ((KAPI_KEYSLOT_MODULE_ID) << 8) | (idx)) +#define crypto_keyslot_compat_hmac_handle(idx) crypto_keyslot_compat_handle(1, idx) +#define crypto_keyslot_compat_mcipher_handle(idx) crypto_keyslot_compat_handle(0, idx) +#define crypto_keyslot_is_hmac(handle) ((((handle) >> 16) & 0xff) == 0x1) +#define crypto_keyslot_is_mcipher(handle) ((((handle) >> 16) & 0xff) == 0) +#define crypto_keyslot_get_idx(handle) ((handle) & 0xff) +#define crypto_keyslot_get_module_id(handle) (((handle) >> 8) & 0xff) + +#endif diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_common_macro.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_common_macro.h new file mode 100644 index 00000000..688366e0 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_common_macro.h @@ -0,0 +1,148 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef CRYPTO_COMMON_MACRO_H +#define CRYPTO_COMMON_MACRO_H + +#define crypto_cpu_to_be32(v) ((((td_u32)(v))>>24) | ((((td_u32)(v))>>8)&0xff00) \ + | ((((td_u32)(v))<<8)&0xff0000) | (((td_u32)(v))<<24)) + +#define crypto_max(a, b) ((a) > (b)) ? (a) : (b) +#define crypto_min(a, b) ((a) > (b)) ? (b) : (a) + +#ifndef crypto_unused +#define crypto_unused(x) (td_void)(x) +#endif + +#define crypto_array_size(arr) (sizeof(arr) / sizeof((arr)[0])) + +#define crypto_reg_read(reg_addr) (*(volatile td_u32 *)(uintptr_t)(reg_addr)) +#define crypto_reg_write(reg_addr, value) (*(volatile td_u32 *)(uintptr_t)(reg_addr) = (value)) + +#define crypto_set_bits(src, bit) ((src) |= (1 << (bit))) +#define crypto_clear_bits(src, bit) ((src) &= ~(1 << (bit))) +/* Error Check. */ +#define crypto_chk_print(cond, ...) do { \ + if (cond) { \ + crypto_log_err(__VA_ARGS__); \ + } \ +} while (0) + +#define crypto_chk_return(cond, err_ret, ...) do { \ + if (cond) { \ + crypto_log_err("%s:%d:", __func__, __LINE__); \ + crypto_log_err(__VA_ARGS__); \ + return err_ret; \ + } \ +} while (0) + +#define crypto_chk_return_void(cond, ...) do { \ + if (cond) { \ + crypto_log_err(__VA_ARGS__); \ + return; \ + } \ +} while (0) + +#define crypto_chk_goto(cond, label, ...) do { \ + if (cond) { \ + crypto_log_err("%s:%d:", __func__, __LINE__); \ + crypto_log_err(__VA_ARGS__); \ + goto label; \ + } \ +} while (0) + +/* Input Params Check. */ +#define crypto_param_require(cond) do { \ + if (!(cond)) { \ + crypto_log_err("Param Check %s failed\n", #cond); \ + return CRYPTO_FAILURE; \ + } \ +} while (0) + +#define crypto_param_check(cond) do { \ + if (cond) { \ + crypto_log_err("Param Check %s failed\n", #cond); \ + return CRYPTO_FAILURE; \ + } \ +} while (0) + +#define crypto_chk_goto_with_ret(cond, label, err_ret, fmt, ...) do { \ + if (cond) { \ + crypto_log_err(fmt, ##__VA_ARGS__); \ + ret = err_ret; \ + goto label; \ + } \ +} while (0) + +#if defined(CRYPTO_HAL_FUNC_TRACE_ENABLE) +#define crypto_hal_func_enter() crypto_log_trace("%s===>Enter\n", __func__) +#define crypto_hal_func_exit() crypto_log_trace("%s<===Exit\n", __func__) +#else +#define crypto_hal_func_enter() +#define crypto_hal_func_exit() +#endif + +#if defined(CRYPTO_KAPI_FUNC_TRACE_ENABLE) +#define crypto_kapi_func_enter() crypto_log_trace("%s===>Enter\n", __func__) +#define crypto_kapi_func_exit() crypto_log_trace("%s<===Exit\n", __func__) +#else +#define crypto_kapi_func_enter() +#define crypto_kapi_func_exit() +#endif + +#if defined(CRYPTO_DRV_FUNC_TRACE_ENABLE) +#define crypto_drv_func_enter() crypto_log_trace("%s===>Enter\n", __func__) +#define crypto_drv_func_exit() crypto_log_trace("%s<===Exit\n", __func__) +#else +#define crypto_drv_func_enter() +#define crypto_drv_func_exit() +#endif + +#if defined(CRYPTO_DISPATCH_FUNC_TRACE_ENABLE) +#define crypto_dispatch_func_enter() crypto_log_trace("%s===>Enter\n", __func__) +#define crypto_dispatch_func_exit() crypto_log_trace("%s<===Exit\n", __func__) +#else +#define crypto_dispatch_func_enter() +#define crypto_dispatch_func_exit() +#endif + +#if defined(CRYPTO_UAPI_TRNG_DEBUG_ENABLE) +#define crypto_uapi_func_enter() crypto_log_trace("%s ===>Enter\n", __func__) +#define crypto_uapi_func_exit() crypto_log_trace("%s <===Exit\n", __func__) +#else +#define crypto_uapi_func_enter() +#define crypto_uapi_func_exit() +#endif + +#ifndef crypto_print_func_err +#define crypto_print_func_err(_func, _err_code) do { \ + crypto_log_err("%s failed! error code: 0x%x \r\n", #_func, _err_code); \ +} while (0) +#endif + +#ifndef crypto_chk_func_return +#define crypto_chk_func_return(func, ret) do { \ + if ((ret) != TD_SUCCESS) { \ + crypto_print_func_err(func, ret); \ + return ret; \ + } \ +} while (0) +#endif + +#ifndef crypto_check_param +#define crypto_check_param(err_level, module, cond, err_code) do { \ + if (cond) { \ + crypto_log_err("invalid parameter: %s \r\n", #cond); \ + return CRYPTO_COMPAT_ERRNO(CRYPTO_ERROR_ENV, err_level, module, err_code); \ + } \ +} while (0) +#endif + +#ifndef crypto_check_param_null +#define crypto_check_param_null(err_level, module, _val) do { \ + crypto_check_param(err_level, module, ((_val) == TD_NULL), ERROR_PARAM_IS_NULL); \ +} while (0) +#endif + +#endif diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_common_struct.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_common_struct.h new file mode 100644 index 00000000..4261098d --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_common_struct.h @@ -0,0 +1,50 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef CRYPTO_COMMON_STRUCT_H +#define CRYPTO_COMMON_STRUCT_H + +#include "crypto_type.h" + +/* ! \union of compat addr */ +typedef union { + void *p; /* !< virtual address */ + unsigned long long phy; /* !< physical address */ + unsigned int word[2]; /* !< 2 word of address */ +} crypto_compat_addr; + +#ifndef ADDR_H32 +#define ADDR_H32(addr) (addr).word[1] /* !< High 32 bit of td_u64 */ +#endif +#ifndef ADDR_L32 +#define ADDR_L32(addr) (addr).word[0] /* !< Low 32 bit of td_u64 */ +#endif +#ifndef ADDR_U64 +#define ADDR_U64(addr) (addr).phy /* !< 64 bit of td_u64 */ +#endif +#ifndef ADDR_VIA +#define ADDR_VIA(addr) (addr).p /* !< buffer point */ +#endif + +typedef enum { + CRYPTO_BUF_SECURE, + CRYPTO_BUF_NONSECURE, +} crypto_buffer_secure; + +typedef struct { + unsigned long long uapi_mem_handle; /* Handle to buffer header address */ + unsigned long long addr_offset; /* buffer offset, unused. */ + td_void *kapi_mem_handle; + + unsigned long phys_addr; + void *virt_addr; + crypto_buffer_secure buf_sec; /* NONSECURE or SECURE */ +} crypto_buf_attr; + +typedef enum { + KEYSLOT_ENGINE_AES, + KEYSLOT_ENGINE_SM4 +} keyslot_engine; + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_ecc_curve.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_ecc_curve.h new file mode 100644 index 00000000..64d5efdc --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_ecc_curve.h @@ -0,0 +1,12 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef CRYPTO_ECC_CURVE_H +#define CRYPTO_ECC_CURVE_H + +#include "crypto_pke_struct.h" + +const drv_pke_ecc_curve *get_ecc_curve(drv_pke_ecc_curve_type curve_type); + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_errno.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_errno.h new file mode 100644 index 00000000..a18638ea --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_errno.h @@ -0,0 +1,145 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef CRYPTO_ERRNO_H +#define CRYPTO_ERRNO_H + +/** + * The Struction of Error Number is as follows: + * Env(4 bits) | Layer(4 bits) | Modules(4 bits) | Reserved(12 bits) | Error Code(8 bits) + **/ + +/* Error for Environments Definition. */ +#define ERROR_ENV_LINUX 0x1 +#define ERROR_ENV_ITRUSTEE 0x2 +#define ERROR_ENV_OPTEE 0x3 +#define ERROR_ENV_LITEOS 0x4 +#define ERROR_ENV_SELITEOS 0x5 +#define ERROR_ENV_NOOS 0x6 + +/* Error for Layer Enumerations. */ +enum { + ERROR_LAYER_UAPI = 0x1, + ERROR_LAYER_DISPATCH, + ERROR_LAYER_KAPI, + ERROR_LAYER_DRV, + ERROR_LAYER_HAL, +}; + +/* Error for Module Enumerations. */ +enum { + ERROR_MODULE_SYMC = 0x1, + ERROR_MODULE_HASH, + ERROR_MODULE_PKE, + ERROR_MODULE_TRNG, + ERROR_MODULE_KM, + ERROR_MODULE_OTP, + ERROR_MODULE_OTHER +}; + +/* Error for Error Code Enumerations. */ +enum { + /* Common Error Code. 0x00 ~ 0x3F. */ + ERROR_INVALID_PARAM = 0x0, /* return when the input param's value is not in the valid range. */ + ERROR_PARAM_IS_NULL, /* return when the input param is NULL and required not NULL. */ + ERROR_NOT_INIT, /* return when call other functions before call init function. */ + ERROR_UNSUPPORT, /* return when some configuration is unsupport. */ + ERROR_UNEXPECTED, /* reture when unexpected error occurs. */ + ERROR_TRY_TIMES, /* return when the number of try attempts failed. */ + ERROR_CHN_BUSY, /* return when try to create one channel but all channels are busy. */ + ERROR_CTX_CLOSED, /* return when using one ctx to do something but has been closed. */ + ERROR_NOT_SET_CONFIG, /* return when not set_config but need for symc. */ + ERROR_NOT_ATTACHED, /* return when not attach but need for symc. */ + ERROR_NOT_SET_SESSION_KEY, /* return when not set_session_key but need for klad. */ + ERROR_NOT_MAC_START, /* return when not mac_start but need for symc. */ + ERROR_INVALID_HANDLE, /* return when pass one invalid handle. */ + ERROR_GET_PHYS_ADDR, /* return when transfer from virt_addr to phys_addr failed. */ + ERROR_SYMC_LEN_NOT_ALIGNED, /* return when length isn't aligned to 16-Byte except CTR/CCM/GCM. */ + ERROR_SYMC_ADDR_NOT_ALIGNED, /* return when the phys_addr writing to register is not aligned to 4-Byte. */ + ERROR_PKE_RSA_SAME_DATA, /* return when rsa exp_mod, the input is equal to output. */ + ERROR_PKE_RSA_CRYPTO_V15_CHECK, /* return when rsa crypto v15 padding check failed. */ + ERROR_PKE_RSA_CRYPTO_OAEP_CHECK, /* return when rsa crypto oaep padding check failed. */ + ERROR_PKE_RSA_VERIFY_V15_CHECK, /* return when rsa verify v15 padding check failed. */ + ERROR_PKE_RSA_VERIFY_PSS_CHECK, /* return when rsa verify pss padding check failed. */ + ERROR_PKE_RSA_GEN_KEY, /* return when rsa generate key failed. */ + ERROR_PKE_SM2_DECRYPT, /* return when sm2 decrypt failed. */ + ERROR_PKE_ECDSA_VERIFY_CHECK, /* return when ecdsa verify check failed. */ + ERROR_OTP_ADDR_NOT_ALIGNED, /* return when otp address is not aligned to 4. */ + + /* Outer's Error Code. 0x40 ~ 0x5F. */ + ERROR_MEMCPY_S = 0x40, /* return when call memcpy_s failed. */ + ERROR_MALLOC, /* return when call xxx_malloc failed. */ + ERROR_MUTEX_INIT, /* return when call xxx_mutex_init failed. */ + ERROR_MUTEX_LOCK, /* return when call xxx_lock failed. */ + /* Specific Error Code for UAPI. 0x60 ~ 0x6F. */ + ERROR_DEV_OPEN_FAILED, /* return when open dev failed. */ + ERROR_COUNT_OVERFLOW, /* return when call init too many times. */ + + /* Specific Error Code for Dispatch. 0x70 ~ 0x7F. */ + ERROR_CMD_DISMATCH = 0x70, /* return when cmd is dismatched. */ + ERROR_COPY_FROM_USER, /* return when call copy_from_user failed. */ + ERROR_COPY_TO_USER, /* return when call copy_to_user failed. */ + ERROR_MEM_HANDLE_GET, /* return when parse user's mem handle to kernel's mem handle failed. */ + ERROR_GET_OWNER, /* return when call crypto_get_owner failed. */ + + /* Specific Error Code for KAPI. 0x80 ~ 0x8F. */ + ERROR_PROCESS_NOT_INIT = 0x80, /* return when one process not call kapi_xxx_init first. */ + ERROR_MAX_PROCESS, /* return when process's num is over the limit. */ + ERROR_MEMORY_ACCESS, /* return when access the memory that does not belong to itself. */ + ERROR_INVALID_PROCESS, /* return when the process accesses resources of other processes. */ + /* Specific Error Code for DRV. 0x90 ~ 0x9F. */ + + /* Specific Error Code for HAL. 0xA0 ~ 0xAF. */ + ERROR_HASH_LOGIC = 0xA0, /* return when hash logic's error occurs. */ + ERROR_PKE_LOGIC, /* return when pke logic's error occurs. */ + ERROR_INVALID_CPU_TYPE, /* return when logic get the invalid cpu type. */ + ERROR_INVALID_REGISTER_VALUE, /* return when value in register is invalid. */ + ERROR_INVALID_PHYS_ADDR, /* return when phys_addr is invalid. */ + ERROR_OTP_PERMISSION, /* return when otp access is forbidden. */ + ERROR_KM_LOGIC, /* return when km logic's error occurs. */ + + /* Specific Error Code for Timeout. 0xB0 ~ 0xBF. */ + ERROR_GET_TRNG_TIMEOUT = 0xB0, /* return when logic get rnd timeout. */ + ERROR_HASH_CLEAR_CHN_TIMEOUT, /* return when clear hash channel timeout. */ + ERROR_HASH_CALC_TIMEOUT, /* return when hash calculation timeout. */ + ERROR_SYMC_CLEAR_CHN_TIMEOUT, /* return when clear symc channel timeout. */ + ERROR_SYMC_CALC_TIMEOUT, /* return when symc crypto timeout. */ + ERROR_SYMC_GET_TAG_TIMEOUT, /* return when symc get tag timeout. */ + ERROR_PKE_LOCK_TIMEOUT, /* return when pke lock timeout. */ + ERROR_PKE_WAIT_DONE_TIMEOUT, /* return when pke wait done timeout. */ + ERROR_PKE_ROBUST_WARNING, /* return when pke wait done timeout. */ + ERROR_RKP_LOCK_TIMEOUT, /* return when rkp lock timeout. */ + ERROR_RKP_CALC_TIMEOUT, /* return when rkp calculate timeout. */ + ERROR_OTP_TIMEOUT, /* return when otp wait timeout. */ + ERROR_KEYSLOT_TIMEOUT, /* return when keyslot wait timeout. */ + ERROR_KEYSLOT_LOCK, /* return when keyslot lock or unlock fail. */ + ERROR_KLAD_TIMEOUT, /* return when klad wait timeout. */ + ERROR_KLAD_LOCK, /* return when klad lock or unlock fail. */ +}; + +#define CRYPTO_COMPAT_ERRNO(env, layer, module, err_code) \ + ((((env) & 0xF) << 28) | (((layer) & 0xF) << 24) | (((module) & 0xF) << 20) | ((err_code) & 0xFF)) + +/* Notice: you should define CRYPTO_ERROR_ENV as one of ERROR_ENV_XXX before using these macros. */ +#define UAPI_COMPAT_ERRNO(module, err_code) \ + CRYPTO_COMPAT_ERRNO(CRYPTO_ERROR_ENV, ERROR_LAYER_UAPI, module, err_code) + +#define DISPATCH_COMPAT_ERRNO(module, err_code) \ + CRYPTO_COMPAT_ERRNO(CRYPTO_ERROR_ENV, ERROR_LAYER_DISPATCH, module, err_code) + +#define KAPI_COMPAT_ERRNO(module, err_code) \ + CRYPTO_COMPAT_ERRNO(CRYPTO_ERROR_ENV, ERROR_LAYER_KAPI, module, err_code) + +#define DRV_COMPAT_ERRNO(module, err_code) \ + CRYPTO_COMPAT_ERRNO(CRYPTO_ERROR_ENV, ERROR_LAYER_DRV, module, err_code) + +#define HAL_COMPAT_ERRNO(module, err_code) \ + CRYPTO_COMPAT_ERRNO(CRYPTO_ERROR_ENV, ERROR_LAYER_HAL, module, err_code) + +enum { + CRYPTO_SUCCESS = 0, + CRYPTO_FAILURE = 0xffffffff, +}; + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_hash_struct.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_hash_struct.h new file mode 100644 index 00000000..81e9aad0 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_hash_struct.h @@ -0,0 +1,170 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef CRYPTO_HASH_STRUCT_H +#define CRYPTO_HASH_STRUCT_H + +#include "crypto_common_struct.h" + +/* + * Component of crypto_hash_type. + * is_hmac(4 bits) | alg(4 bits) | mode(4 bits) | max_message_length(4 bits) | block_size(4 bits) | result_size(12 bits) + * is_hmac: h'0 - hash + * h'1 - hmac + * alg: h'0 - sha1 + * h'1 - sha2 + * h'2 - sm3 + * mode: h'0 - 224 + * h'1 - 256 + * h'2 - 384 + * h'3 - 512 + * max_message_length: + * h'6 - 2**6 -> 64, longest 2**64 Bits. For SHA256. + * h'7 - 2**7 -> 128, longest 2**128 Bits. For SHA384/SHA512. + * block_size: + * h'9 - 2**9 -> 512, Block Size is 512 Bits. For SHA256. + * h'a - 2**10 -> 1024, Block Size is 1024 Bits. For SHA384/SHA512. + * result_size: + * h'100 - 256, Result Size is 256 Bits. For SHA256. + * h'180 - 384, Result Size is 384 Bits. For SHA384. + * h'200 - 512, Result Size is 512 Bits. For SHA512. + */ +#define compat_hash_type(is_hmac, alg, mode, max_message_length, block_size, result_size) \ + ((((is_hmac) & 0xF) << 28) | (((alg) & 0xF) << 24) | (((mode) & 0xF) << 20) | \ + (((max_message_length) & 0xF) << 16) | (((block_size) & 0xF) << 12) | ((result_size) & 0xFFF)) + +#define CRYPTO_HASH_TYPE 0 +#define CRYPTO_HMAC_TYPE 1 +#define CRYPTO_IS_HMAC_MASK 0xF0000000 +#define CRYPTO_IS_HMAC_SHIFT 28 + +#define CRYPTO_HASH_ALG_SHA1 0 +#define CRYPTO_HASH_ALG_SHA2 1 +#define CRYPTO_HASH_ALG_SM3 2 +#define CRYPTO_HASH_ALG_MASK 0x0F000000 +#define CRYPTO_HASH_ALG_SHIFT 24 + +#define CRYPTO_HASH_MODE_224 0 +#define CRYPTO_HASH_MODE_256 1 +#define CRYPTO_HASH_MODE_384 2 +#define CRYPTO_HASH_MODE_512 3 +#define CRYPTO_HASH_MODE_UNDEF 0xf +#define CRYPTO_HASH_MODE_MASK 0x00F00000 +#define CRYPTO_HASH_MODE_SHIFT 20 + +#define CRYPTO_HASH_MAX_MESSAGE_LEN_64BIT 0x6 +#define CRYPTO_HASH_MAX_MESSAGE_LEN_128BIT 0x7 +#define CRYPTO_HASH_MAX_MESSAGE_LEN_MASK 0x000F0000 +#define CRYPTO_HASH_MAX_MESSAGE_LEN_SHIFT 16 + +#define CRYPTO_HASH_BLOCK_SIZE_512BIT 0x9 +#define CRYPTO_HASH_BLOCK_SIZE_1024BIT 0xa +#define CRYPTO_HASH_BLOCK_SIZE_MASK 0x0000F000 +#define CRYPTO_HASH_BLOCK_SIZE_SHIFT 12 + +#define CRYPTO_HASH_RESULT_SIZE_160BIT 0xa0 +#define CRYPTO_HASH_RESULT_SIZE_224BIT 0xe0 +#define CRYPTO_HASH_RESULT_SIZE_256BIT 0x100 +#define CRYPTO_HASH_RESULT_SIZE_384BIT 0x180 +#define CRYPTO_HASH_RESULT_SIZE_512BIT 0x200 +#define CRYPTO_HASH_RESULT_SIZE_MASK 0x00000FFF +#define CRYPTO_HASH_RESULT_SIZE_SHIFT 0 + +#define CRYPTO_GET_ATTR(value, mask, shift) (((value) & (mask)) >> (shift)) +#define CRYPTO_MATCH(value, mask, target, shift) (CRYPTO_GET_ATTR(value, mask, shift) == (target)) + +#define CRYPTO_HASH_GET_ALG(hash_type) \ + CRYPTO_GET_ATTR(hash_type, CRYPTO_HASH_ALG_MASK, CRYPTO_HASH_ALG_SHIFT) +#define CRYPTO_HASH_GET_MODE(hash_type) \ + CRYPTO_GET_ATTR(hash_type, CRYPTO_HASH_MODE_MASK, CRYPTO_HASH_MODE_SHIFT) +#define CRYPTO_HASH_IS_HMAC(hash_type) \ + CRYPTO_MATCH(hash_type, CRYPTO_IS_HMAC_MASK, CRYPTO_HMAC_TYPE, CRYPTO_IS_HMAC_SHIFT) +#define CRYPTO_HASH_GET_MESSAGE_LEN(hash_type) \ + (1 << CRYPTO_GET_ATTR(hash_type, CRYPTO_HASH_MAX_MESSAGE_LEN_MASK, CRYPTO_HASH_MAX_MESSAGE_LEN_SHIFT)) +#define CRYPTO_HASH_GET_BLOCK_SIZE(hash_type) \ + (1 << CRYPTO_GET_ATTR(hash_type, CRYPTO_HASH_BLOCK_SIZE_MASK, CRYPTO_HASH_BLOCK_SIZE_SHIFT)) +#define CRYPTO_HASH_GET_RESULT_SIZE(hash_type) \ + CRYPTO_GET_ATTR(hash_type, CRYPTO_HASH_RESULT_SIZE_MASK, CRYPTO_HASH_RESULT_SIZE_SHIFT) + +typedef enum { + /* Hash. */ + CRYPTO_HASH_TYPE_SHA1 = compat_hash_type( + CRYPTO_HASH_TYPE, CRYPTO_HASH_ALG_SHA1, CRYPTO_HASH_MODE_UNDEF, CRYPTO_HASH_MAX_MESSAGE_LEN_64BIT, + CRYPTO_HASH_BLOCK_SIZE_512BIT, CRYPTO_HASH_RESULT_SIZE_160BIT + ), + CRYPTO_HASH_TYPE_SHA224 = compat_hash_type( + CRYPTO_HASH_TYPE, CRYPTO_HASH_ALG_SHA2, CRYPTO_HASH_MODE_224, CRYPTO_HASH_MAX_MESSAGE_LEN_64BIT, + CRYPTO_HASH_BLOCK_SIZE_512BIT, CRYPTO_HASH_RESULT_SIZE_224BIT + ), + CRYPTO_HASH_TYPE_SHA256 = compat_hash_type( + CRYPTO_HASH_TYPE, CRYPTO_HASH_ALG_SHA2, CRYPTO_HASH_MODE_256, CRYPTO_HASH_MAX_MESSAGE_LEN_64BIT, + CRYPTO_HASH_BLOCK_SIZE_512BIT, CRYPTO_HASH_RESULT_SIZE_256BIT + ), + CRYPTO_HASH_TYPE_SHA384 = compat_hash_type( + CRYPTO_HASH_TYPE, CRYPTO_HASH_ALG_SHA2, CRYPTO_HASH_MODE_384, CRYPTO_HASH_MAX_MESSAGE_LEN_128BIT, + CRYPTO_HASH_BLOCK_SIZE_1024BIT, CRYPTO_HASH_RESULT_SIZE_384BIT + ), + CRYPTO_HASH_TYPE_SHA512 = compat_hash_type( + CRYPTO_HASH_TYPE, CRYPTO_HASH_ALG_SHA2, CRYPTO_HASH_MODE_512, CRYPTO_HASH_MAX_MESSAGE_LEN_128BIT, + CRYPTO_HASH_BLOCK_SIZE_1024BIT, CRYPTO_HASH_RESULT_SIZE_512BIT + ), + CRYPTO_HASH_TYPE_SM3 = compat_hash_type( + CRYPTO_HASH_TYPE, CRYPTO_HASH_ALG_SM3, CRYPTO_HASH_MODE_256, CRYPTO_HASH_MAX_MESSAGE_LEN_64BIT, + CRYPTO_HASH_BLOCK_SIZE_512BIT, CRYPTO_HASH_RESULT_SIZE_256BIT + ), + + /* HMAC. */ + CRYPTO_HASH_TYPE_HMAC_SHA1 = compat_hash_type( + CRYPTO_HMAC_TYPE, CRYPTO_HASH_ALG_SHA1, CRYPTO_HASH_MODE_UNDEF, CRYPTO_HASH_MAX_MESSAGE_LEN_64BIT, + CRYPTO_HASH_BLOCK_SIZE_512BIT, CRYPTO_HASH_RESULT_SIZE_160BIT + ), + CRYPTO_HASH_TYPE_HMAC_SHA224 = compat_hash_type( + CRYPTO_HMAC_TYPE, CRYPTO_HASH_ALG_SHA2, CRYPTO_HASH_MODE_224, CRYPTO_HASH_MAX_MESSAGE_LEN_64BIT, + CRYPTO_HASH_BLOCK_SIZE_512BIT, CRYPTO_HASH_RESULT_SIZE_224BIT + ), + CRYPTO_HASH_TYPE_HMAC_SHA256 = compat_hash_type( + CRYPTO_HMAC_TYPE, CRYPTO_HASH_ALG_SHA2, CRYPTO_HASH_MODE_256, CRYPTO_HASH_MAX_MESSAGE_LEN_64BIT, + CRYPTO_HASH_BLOCK_SIZE_512BIT, CRYPTO_HASH_RESULT_SIZE_256BIT + ), + CRYPTO_HASH_TYPE_HMAC_SHA384 = compat_hash_type( + CRYPTO_HMAC_TYPE, CRYPTO_HASH_ALG_SHA2, CRYPTO_HASH_MODE_384, CRYPTO_HASH_MAX_MESSAGE_LEN_128BIT, + CRYPTO_HASH_BLOCK_SIZE_1024BIT, CRYPTO_HASH_RESULT_SIZE_384BIT + ), + CRYPTO_HASH_TYPE_HMAC_SHA512 = compat_hash_type( + CRYPTO_HMAC_TYPE, CRYPTO_HASH_ALG_SHA2, CRYPTO_HASH_MODE_512, CRYPTO_HASH_MAX_MESSAGE_LEN_128BIT, + CRYPTO_HASH_BLOCK_SIZE_1024BIT, CRYPTO_HASH_RESULT_SIZE_512BIT + ), + CRYPTO_HASH_TYPE_HMAC_SM3 = compat_hash_type( + CRYPTO_HMAC_TYPE, CRYPTO_HASH_ALG_SM3, CRYPTO_HASH_MODE_256, CRYPTO_HASH_MAX_MESSAGE_LEN_64BIT, + CRYPTO_HASH_BLOCK_SIZE_512BIT, CRYPTO_HASH_RESULT_SIZE_256BIT + ), + + CRYPTO_HASH_TYPE_INVALID = 0xffffffff, +} crypto_hash_type; + +typedef struct { + td_u8 *key; + td_u32 key_len; + td_handle drv_keyslot_handle; + crypto_hash_type hash_type; + td_bool is_keyslot; + td_bool is_long_term; +} crypto_hash_attr; + +/* Structure for HASH. */ +#define CRYPTO_HASH_RESULT_SIZE_MAX 64 // for SHA-512 +#define CRYPTO_HASH_RESULT_SIZE_MAX_IN_WORD 16 // for SHA-512 +#define CRYPTO_HASH_BLOCK_SIZE_MAX 128 // for SHA-512 + +typedef struct { + td_u32 length[2]; + td_u32 state[CRYPTO_HASH_RESULT_SIZE_MAX_IN_WORD]; + td_u32 tail_len; + crypto_hash_type hash_type; + td_u8 o_key_pad[CRYPTO_HASH_BLOCK_SIZE_MAX]; + td_u8 i_key_pad[CRYPTO_HASH_BLOCK_SIZE_MAX]; + td_u8 tail[CRYPTO_HASH_BLOCK_SIZE_MAX]; +} crypto_hash_clone_ctx; + +#endif diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_kdf_struct.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_kdf_struct.h new file mode 100644 index 00000000..5e79241a --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_kdf_struct.h @@ -0,0 +1,20 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef CRYPTO_KDF_STRUCT_H +#define CRYPTO_KDF_STRUCT_H + +#include "crypto_common_struct.h" +#include "crypto_hash_struct.h" + +typedef struct { + crypto_hash_type hash_type; + td_u8 *password; + td_u32 plen; + td_u8 *salt; + td_u32 slen; + td_u16 count; +} crypto_kdf_pbkdf2_param; + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_km_struct.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_km_struct.h new file mode 100644 index 00000000..8975f377 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_km_struct.h @@ -0,0 +1,469 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef OT_KM_STRUCT_H +#define OT_KM_STRUCT_H + +#include "ot_type.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +typedef uintptr_t crypto_handle; + +typedef td_bool (*drv_kdf_wait_condition_func)(const td_void *param); + +typedef td_bool (*drv_klad_wait_condition_func)(const td_void *param); + +typedef td_s32 (*osal_kdf_wait_timeout_uninterruptible)(const td_void *wait, drv_kdf_wait_condition_func func, + const td_void *param, const td_u32 timeout_ms); + +typedef td_s32 (*osal_klad_wait_timeout_uninterruptible)(const td_void *wait, drv_klad_wait_condition_func func, + const td_void *param, const td_u32 timeout_ms); + +/* soc kald */ +#define KM_KDF_OTP_KEY (0x02000000) +#define KM_OTP_KEY(n) (KM_KDF_OTP_KEY | (n)) + +#define KM_KDF_OTP_KEY_MRK1 KM_OTP_KEY(0x00) +#define KM_KDF_OTP_KEY_USK KM_OTP_KEY(0x01) +#define KM_KDF_OTP_KEY_RUSK KM_OTP_KEY(0x02) + +#define KM_KLAD_ROOTKEY (0x03000000) +#define KM_ROOT_KEY(n) (KM_KLAD_ROOTKEY | (n)) + +/* SBRK0, TEE Global Boot Root Key0, delivered from MRK1, soc_tee_enable and Hash of TEE Root Public Key */ +#define KM_KLAD_KEY_TYPE_SBRK0 KM_ROOT_KEY(0x00) +/* SBRK1, TEE Global Boot Root Key1, delivered from MRK1, soc_tee_enable and Hash of TEE Root Public Key */ +#define KM_KLAD_KEY_TYPE_SBRK1 KM_ROOT_KEY(0x01) +/* SBRK2, TEE Global Boot Root Key2, delivered from MRK1, soc_tee_enable and Hash of TEE Root Public Key */ +#define KM_KLAD_KEY_TYPE_SBRK2 KM_ROOT_KEY(0x02) +#define KM_KLAD_KEY_TYPE_ABRK0 KM_ROOT_KEY(0x03) /* ABRK0, REE Global Boot Root Key0, delivered from MRK1 */ +#define KM_KLAD_KEY_TYPE_ABRK1 KM_ROOT_KEY(0x04) /* ABRK1, REE Global Boot Root Key1, delivered from MRK1 */ +#define KM_KLAD_KEY_TYPE_ABRK2 KM_ROOT_KEY(0x05) /* ABRK2, REE Global Boot Root Key2, delivered from MRK1 */ +/* DRK0, TEE unique data decryption root key, delivered from USK */ +#define KM_KLAD_KEY_TYPE_DRK0 KM_ROOT_KEY(0x06) +/* DRK1, REE unique data decryption root key, delivered from USK */ +#define KM_KLAD_KEY_TYPE_DRK1 KM_ROOT_KEY(0x07) +/* RDRK0, TEE random data decryption root key, delivered from RUSK */ +#define KM_KLAD_KEY_TYPE_RDRK0 KM_ROOT_KEY(0x08) +/* RDRK1, REE random data decryption root key, delivered from RUSK */ +#define KM_KLAD_KEY_TYPE_RDRK1 KM_ROOT_KEY(0x09) +#define KM_KLAD_KEY_TYPE_PSK KM_ROOT_KEY(0x0A) /* PSK, delivered from MRK1 */ +/* ODRK0, TEE flash online decryptin root key, delivered from MRK0/1, soc_tee_enable and Hash of TEE Root Public Key */ +#define KM_KLAD_KEY_TYPE_ODRK0 KM_ROOT_KEY(0x0B) +/* OARK0 TEE flash online authentication root key, delivered from MRK0/1, + soc_tee_enable and Hash of TEE Root Public Key */ +#define KM_KLAD_KEY_TYPE_OARK0 KM_ROOT_KEY(0x0C) +/* ODRK1, REE flash online decryption root key, delivered from MRK1 */ +#define KM_KLAD_KEY_TYPE_ODRK1 KM_ROOT_KEY(0x0D) +/* MDRK0 */ +#define KM_KLAD_KEY_TYPE_MDRK0 KM_ROOT_KEY(0x0E) +/* MDRK1 */ +#define KM_KLAD_KEY_TYPE_MDRK1 KM_ROOT_KEY(0x0F) +/* MDRK2 */ +#define KM_KLAD_KEY_TYPE_MDRK2 KM_ROOT_KEY(0x10) +/* MDRK3 */ +#define KM_KLAD_KEY_TYPE_MDRK3 KM_ROOT_KEY(0x11) + +typedef enum { + KM_KLAD_HMAC_SHA1 = 0x20, /* Do Not Recommend to Use */ + KM_KLAD_HMAC_SHA224, /* Software Kdf not support */ + KM_KLAD_HMAC_SHA256, + KM_KLAD_HMAC_SHA384, + KM_KLAD_HMAC_SHA512, + KM_KLAD_HMAC_SM3 = 0x30, + KM_KLAD_HMAC_MAX, + KM_KLAD_HMAC_INVALID = 0xffffffff, +} km_klad_hmac_type; + +/* Define the key security attribute. */ +typedef enum { + KM_KLAD_SEC_DISABLE = 0, + KM_KLAD_SEC_ENABLE, + KM_KLAD_SEC_MAX, + KM_KLAD_SEC_INVALID = 0xffffffff, +} km_klad_sec; + +/* Define the keyladder level. */ +typedef enum { + KM_KLAD_LEVEL1 = 0, + KM_KLAD_LEVEL_MAX, + KM_KLAD_LEVEL_INVALID = 0xffffffff, +} km_klad_level; + +/* Define the keyladder algorithm. */ +typedef enum { + KM_KLAD_ALG_TYPE_TDES = 0, /* Do Not Recommend to Use */ + KM_KLAD_ALG_TYPE_AES, + KM_KLAD_ALG_TYPE_SM4, + KM_KLAD_ALG_TYPE_MAX, + KM_KLAD_ALG_TYPE_INVALID = 0xffffffff, +} km_klad_alg_type; + +/* Define the algorithm of crypto engine. */ +typedef enum { + KM_CRYPTO_ALG_AES = 0x20, + KM_CRYPTO_ALG_LEA = 0x40, /* Flash online decryption and Cipher offline encryption */ + KM_CRYPTO_ALG_SM4 = 0x50, + KM_CRYPTO_ALG_TDES = 0x70, /* Do Not Recommend to Use */ + KM_CRYPTO_ALG_HMAC_SHA1 = 0xA0, /* Do Not Recommend to Use */ + KM_CRYPTO_ALG_HMAC_SHA2 = 0xA1, + KM_CRYPTO_ALG_HMAC_SM3 = 0xA2, + KM_CRYPTO_ALG_MAX, + KM_CRYPTO_ALG_INVALID = 0xffffffff, +} km_crypto_alg; + +/* Define the destination type of keyladder. */ +typedef enum { + KM_KLAD_DEST_TYPE_MCIPHER = 0x00, /* keyslot for mcipher */ + KM_KLAD_DEST_TYPE_HMAC, /* keyslot for hmac */ + KM_KLAD_DEST_TYPE_FLASH, /* flash controller, for flash on line decryption and authentication */ + KM_KLAD_DEST_TYPE_NPU, /* for NPU */ + KM_KLAD_DEST_TYPE_MAX, + KM_KLAD_DEST_TYPE_INVALID = 0xffffffff, +} km_klad_dest_type; + +/* Define the flash online decryption key type it's valid for non-TEE platform, it's will be ignored on TEE platform */ +typedef enum { + KM_KLAD_FLASH_KEY_TYPE_REE_DEC = 0x00, /* REE flash online decryption key */ + KM_KLAD_FLASH_KEY_TYPE_TEE_DEC, /* TEE flash online decryption key */ + KM_KLAD_FLASH_KEY_TYPE_TEE_AUT, /* TEE flash online authentication key */ + KM_KLAD_FLASH_KEY_TYPE_MAX, + KM_KLAD_FLASH_KEY_TYPE_INVALID = 0xffffffff, +} km_klad_flash_key_type; + +/* * Key parity, valid when key length is not more than 128bit */ +/* * CNcomment: Key Parity Attribute */ +typedef enum { + KM_KLAD_KEY_EVEN = 0x0, /* *< even key */ + KM_KLAD_KEY_ODD = 0x1, /* *< odd key */ + KM_KLAD_KEY_PARITY_MAX, + KM_KLAD_KEY_PARITY_INVALID = 0xffffffff, +} km_klad_key_parity; + +/* Define the structure of keyladder configuration. */ +typedef struct { + td_u32 rootkey_type; /* Keyladder rootkey type, KM_KLAD_KEY_TYPE_xxx. */ +} km_klad_config; + +/* Define the structure of content key security configurations. */ +/* when cipher work mode is CBC_MAC, dest_buf_sec_support and dest_buf_non_sec_support cannot be both false */ +typedef struct { + km_klad_sec key_sec; /* Secure key can only be used by TEE CPU and AIDSP locked cipher and hash channel */ + /* Only the cipher or hash channel which is locked by same CPU as keyladder can use this key, + valid only for TEE CPU and AIDSP */ + td_bool master_only_enable; + td_bool dest_buf_sec_support; /* The destination buffer of target engine can be secure. */ + td_bool dest_buf_non_sec_support; /* The destination buffer of target engine can be non-secure. */ + td_bool src_buf_sec_support; /* The source buffer of target engine can be secure. */ + td_bool src_buf_non_sec_support; /* The source buffer of target engine can be non-secure. */ +} km_klad_key_secure_config; + +/* Define the structure of content key configurations. */ +typedef struct { + km_crypto_alg engine; /* The content key can be used for which algorithm of the crypto engine. */ + td_bool decrypt_support; /* The content key can be used for decrypting. */ + td_bool encrypt_support; /* The content key can be used for encrypting. */ +} km_klad_key_config; + +/* Structure of keyladder extend attributes. */ +typedef struct { + km_klad_config klad_cfg; /* The keyladder configuration, valid for harware key. */ + km_klad_key_config key_cfg; /* The content key configuration. */ + km_klad_key_secure_config key_sec_cfg; /* The content key security configuration. */ + td_u32 rkp_sw_cfg; /* The software configuration for NPU */ +} km_klad_attr; + +/* Structure of setting session key. */ +typedef struct { + km_klad_level level; /* the level of session key. */ + km_klad_alg_type alg; /* the algorithm used to decrypt session key. */ + td_u32 key_size; /* the size of session key, should be 16. */ + td_u8 *key; /* the session key. */ +} km_klad_session_key; + +/* Structure of setting content key. */ +typedef struct { + km_klad_alg_type alg; /* The algorithm of the content key. */ + td_u32 key_size; /* The size of content key, should be 16 or 32. */ + td_u8 *key; /* The content key. */ + km_klad_key_parity key_parity; /* Odd or even key flag. */ +} km_klad_content_key; + +/* Structure of sending clear key. */ +typedef struct { + km_klad_hmac_type hmac_type; /* hmac type, only send hmac key need to config. */ + td_u32 key_size; /* The size of content key, 16 or 32 for cipher, + not more than block size for HMAC. */ + td_u8 *key; /* The content key. */ + km_klad_key_parity key_parity; /* Odd or even key flag. */ +} km_klad_clear_key; + +/* soc keyslot */ +/* Define the keyslot type. */ +typedef enum { + KM_KEYSLOT_TYPE_MCIPHER = 0x00, + KM_KEYSLOT_TYPE_HMAC, + KM_KEYSLOT_TYPE_MAX, + KM_KEYSLOT_TYPE_INVALID = 0xffffffff, +} km_keyslot_type; + +/** + * @brief Root key selection during KDF key derivation. + */ +typedef enum { + CRYPTO_KDF_OTP_KEY_MRK1 = 0, + CRYPTO_KDF_OTP_KEY_USK, + CRYPTO_KDF_OTP_KEY_RUSK +} crypto_kdf_otp_key; + +/** + * @brief Symmetric algorithm selection during KDF key derivation. + */ +typedef enum { + CRYPTO_KDF_UPDATE_ALG_AES = 0, + CRYPTO_KDF_UPDATE_ALG_SM4 +} crypto_kdf_update_alg; + +/** + * @brief Hash algorithm selection when the software PBKDF2 algorithm is used. + */ +typedef enum { + CRYPTO_KDF_SW_ALG_SHA1 = 0, + CRYPTO_KDF_SW_ALG_SHA256, + CRYPTO_KDF_SW_ALG_SHA384, + CRYPTO_KDF_SW_ALG_SHA512, + CRYPTO_KDF_SW_ALG_SM3 +} crypto_kdf_sw_alg; + +/** + * @brief Select the derived key type during KDF key derivation. + */ +typedef enum { + CRYPTO_KDF_HARD_KEY_TYPE_SBRK0 = 0x03000000, + CRYPTO_KDF_HARD_KEY_TYPE_SBRK1, + CRYPTO_KDF_HARD_KEY_TYPE_SBRK2, + CRYPTO_KDF_HARD_KEY_TYPE_ABRK0, + CRYPTO_KDF_HARD_KEY_TYPE_ABRK1, + CRYPTO_KDF_HARD_KEY_TYPE_ABRK2, + CRYPTO_KDF_HARD_KEY_TYPE_DRK0, + CRYPTO_KDF_HARD_KEY_TYPE_DRK1, + CRYPTO_KDF_HARD_KEY_TYPE_RDRK0, + CRYPTO_KDF_HARD_KEY_TYPE_RDRK1, + CRYPTO_KDF_HARD_KEY_TYPE_PSK, + CRYPTO_KDF_HARD_KEY_TYPE_ODRK0, + CRYPTO_KDF_HARD_KEY_TYPE_OARK0, + CRYPTO_KDF_HARD_KEY_TYPE_ODRK1, + CRYPTO_KDF_HARD_KEY_TYPE_MDRK0, + CRYPTO_KDF_HARD_KEY_TYPE_MDRK1, + CRYPTO_KDF_HARD_KEY_TYPE_MDRK2, + CRYPTO_KDF_HARD_KEY_TYPE_MDRK3, + + CRYPTO_KDF_HARD_KEY_TYPE_ABRK_REE, + CRYPTO_KDF_HARD_KEY_TYPE_ABRK_TEE, + CRYPTO_KDF_HARD_KEY_TYPE_RDRK_REE, + CRYPTO_KDF_HARD_KEY_TYPE_RDRK_TEE, +} crypto_kdf_hard_key_type; + +/** + * @brief KDF key derivation, hash algorithm selection when the hardware PBKDF2 algorithm is used. + */ +typedef enum { + CRYPTO_KDF_HARD_ALG_SHA256 = 0, + CRYPTO_KDF_HARD_ALG_SM3 +} crypto_kdf_hard_alg; + +typedef enum { + CRYPTO_KDF_HARD_KEY_SIZE_128BIT = 0, + CRYPTO_KDF_HARD_KEY_SIZE_192BIT, + CRYPTO_KDF_HARD_KEY_SIZE_256BIT, +} crypto_kdf_hard_key_size; + +typedef struct { + crypto_kdf_hard_key_type hard_key_type; + crypto_kdf_hard_alg hard_alg; + crypto_kdf_hard_key_size hard_key_size; + td_u32 rkp_sw_cfg; + td_u8 *salt; + td_u32 salt_length; + td_bool is_oneway; +} crypto_kdf_hard_calc_param; + +/** + * @brief The klad target module's algorithm engine, determining the algorithm supported by the sent key. + */ +typedef enum { + CRYPTO_KLAD_ENGINE_AES = 0x20, + CRYPTO_KLAD_ENGINE_LAE = 0x40, + CRYPTO_KLAD_ENGINE_SM4 = 0x50, + CRYPTO_KLAD_ENGINE_TDES = 0x70, + CRYPTO_KLAD_ENGINE_SHA1_HMAC = 0xA0, + CRYPTO_KLAD_ENGINE_SHA2_HMAC = 0xA1, + CRYPTO_KLAD_ENGINE_SM3_HMAC = 0xA2, +} crypto_klad_engine; + +/** + * @brief The klad target module, determining the module to which the key is sent. + */ +typedef enum { + CRYPTO_KLAD_DEST_MCIPHER = 0, + CRYPTO_KLAD_DEST_HMAC, + CRYPTO_KLAD_DEST_FLASH, + CRYPTO_KLAD_DEST_NPU, + CRYPTO_KLAD_DEST_AIDSP, +} crypto_klad_dest; + +/** + * @brief Flash online decryption mode, determining the mode used after the key is sent. + */ +typedef enum { + CRYPTO_KLAD_FLASH_KEY_TYPE_REE_DEC = 0x00, /* REE flash online decryption key */ + CRYPTO_KLAD_FLASH_KEY_TYPE_TEE_DEC, /* TEE flash online decryption key */ + CRYPTO_KLAD_FLASH_KEY_TYPE_TEE_AUT, /* TEE flash online authentication key */ + CRYPTO_KLAD_FLASH_KEY_TYPE_INVALID, +} crypto_klad_flash_key_type; + +/** + * @brief Symmetric key length. Determines the length of the final working key. + */ +typedef enum { + CRYPTO_KLAD_KEY_SIZE_128BIT, + CRYPTO_KLAD_KEY_SIZE_192BIT, + CRYPTO_KLAD_KEY_SIZE_256BIT, +} crypto_klad_key_size; + +/** + * @brief When the target engine is HMAC, determine the HAMC algorithm to be used. + */ +typedef enum { + CRYPTO_KLAD_HMAC_TYPE_SHA1 = 0x20, /* Insecure algorithm, not recommended. */ + CRYPTO_KLAD_HMAC_TYPE_SHA224, + CRYPTO_KLAD_HMAC_TYPE_SHA256, + CRYPTO_KLAD_HMAC_TYPE_SHA384, + CRYPTO_KLAD_HMAC_TYPE_SHA512, + CRYPTO_KLAD_HMAC_TYPE_SM3 = 0x30, + CRYPTO_KLAD_HMAC_TYPE_MAX, + CRYPTO_KLAD_HMAC_TYPE_INVALID = 0xffffffff, +} crypto_klad_hmac_type; + +/** + * @brief Determines the current derived key level during klad key derivation. + */ +typedef enum { + CRYPTO_KLAD_LEVEL_SEL_FIRST = 0, + CRYPTO_KLAD_LEVEL_SEL_SECOND +} crypto_klad_level_sel; + +/** + * @brief Determines the symmetric algorithm used for derivation during klad key derivation. + */ +typedef enum { + CRYPTO_KLAD_ALG_SEL_TDES = 0, + CRYPTO_KLAD_ALG_SEL_AES, + CRYPTO_KLAD_ALG_SEL_SM4, +} crypto_klad_alg_sel; + +/** + * @brief Clear key structure when klad sends a clear key. + */ +typedef struct { + td_u8 *key; /* Clear key content. */ + td_u32 key_length; /* Length of the clear key, in bytes. + For the symmetric algorithm, the value can only be 16, 24, or 32. + For HMAC-SH1/SHA224/SHA256/SM3, the value cannot exceed 64. + For HMAC-SHA384/SHA512, the value cannot exceed 128. */ + td_bool key_parity; /* Indicates the parity attribute of a key. + Valid when the target is a symmetric algorithm engine and key_length is set to 16. */ + crypto_klad_hmac_type hmac_type; /* Indicates the HMAC algorithm. + Valid only when the target is the HMAC algorithm engine. */ +} crypto_klad_clear_key; + +/** + * @brief Keyladder root key type selection. + */ +typedef struct { + crypto_kdf_hard_key_type rootkey_type; +} crypto_klad_config; + +/** + * @brief Keyladder working key attribute configuration. + */ +typedef struct { + crypto_klad_engine engine; /* The working key can be used for which algorithm of the crypto engine. */ + td_bool decrypt_support; /* The working key can be used for decrypting. */ + td_bool encrypt_support; /* The working key can be used for encrypting. */ +} crypto_klad_key_config; + +/** + * @brief Security attribute of the key. + when cipher work mode is CBC_MAC, dest_buf_sec_support and dest_buf_non_sec_support cannot be both false + */ +typedef struct { + td_bool key_sec; /* Secure key can only be used by TEE CPU and AIDSP locked cipher and hash channel. */ + td_bool master_only_enable; /* Only the cipher or hash channel which is locked by same CPU as keyladder + can use this key, valid only for TEE CPU and AIDSP. */ + td_bool dest_buf_sec_support; /* The destination buffer of target engine can be secure. */ + td_bool dest_buf_non_sec_support; /* The destination buffer of target engine can be secure. */ + td_bool src_buf_sec_support; /* The destination buffer of target engine can be secure. */ + td_bool src_buf_non_sec_support; /* The destination buffer of target engine can be secure. */ +} crypto_klad_key_secure_config; + +/** + * @brief Keyladder configuration attributes. + */ +typedef struct { + crypto_klad_config klad_cfg; /* The keyladder configuration, valid for harware key. */ + crypto_klad_key_config key_cfg; /* The working key configuration. */ + crypto_klad_key_secure_config key_sec_cfg; /* The working key security configuration. */ + td_u32 rkp_sw_cfg; +} crypto_klad_attr; + +/** + * @brief Keyladder hardware key configuration attributes. + */ +typedef struct { + crypto_kdf_hard_alg kdf_hard_alg; + td_bool key_parity; /* Indicates the parity attribute of a key. + Valid when the target is a symmetric algorithm engine and key_length is set to 16. */ + crypto_klad_key_size key_size; + td_u8 *salt; /* Salt content. Used as user input materials for key derivation. + The final working key varies according to the salt value. */ + td_u32 salt_length; /* Salt length, in bytes. It can only be 28. */ + td_bool oneway; /* Salt length, in bytes. It can only be 28. */ +} crypto_klad_hard_key; + +typedef struct { + td_u8 key[16]; + td_u32 key_length; + crypto_klad_level_sel level; + crypto_klad_alg_sel alg; +} crypto_klad_session_key; + +typedef struct { + td_u8 key[32]; + td_u32 key_length; + crypto_klad_alg_sel alg; + td_bool key_parity; +} crypto_klad_content_key; + +/** + * @brief Keyslot type selection. + */ +typedef enum { + CRYPTO_KEYSLOT_TYPE_MCIPHER = 0, + CRYPTO_KEYSLOT_TYPE_HMAC, + CRYPTO_KEYSLOT_TYPE_FLASH, +} crypto_keyslot_type; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif /* OT_KM_STRUCT_H */ diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_pke_struct.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_pke_struct.h new file mode 100644 index 00000000..97d5962d --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_pke_struct.h @@ -0,0 +1,132 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef CRYPTO_PKE_STRUCT_H +#define CRYPTO_PKE_STRUCT_H + +#include "crypto_common_struct.h" + +typedef enum { + DRV_PKE_LEN_256 = 32, + DRV_PKE_LEN_384 = 48, + DRV_PKE_LEN_512 = 64, + DRV_PKE_LEN_521 = 68, + DRV_PKE_LEN_576 = 72, + DRV_PKE_LEN_2048 = 256, + DRV_PKE_LEN_3072 = 384, + DRV_PKE_LEN_4096 = 512, + DRV_PKE_LEN_MAX, + DRV_PKE_LEN_INVALID = 0xffffffff, +} drv_pke_len; + +typedef enum { + DRV_PKE_ECC_TYPE_RFC5639_P256 = 0, /* RFC 5639 - Brainpool P256/384/512 */ + DRV_PKE_ECC_TYPE_RFC5639_P384, /* RFC 5639 - Brainpool P256/384/512 */ + DRV_PKE_ECC_TYPE_RFC5639_P512, /* RFC 5639 - Brainpool P256/384/512 */ + DRV_PKE_ECC_TYPE_FIPS_P256K, /* NIST FIPS 186-4 P256/384/521, suggest not to use */ + DRV_PKE_ECC_TYPE_FIPS_P256R, /* NIST FIPS 186-4 P256/384/521, suggest not to use */ + DRV_PKE_ECC_TYPE_FIPS_P384R, /* NIST FIPS 186-4 P256/384/521, suggest not to use */ + DRV_PKE_ECC_TYPE_FIPS_P521R, /* NIST FIPS 186-4 P256/384/521, suggest not to use */ + DRV_PKE_ECC_TYPE_RFC7748, /* RFC 7748 - Curve25519 */ + DRV_PKE_ECC_TYPE_RFC8032, /* RFC 8032 - ED25519 */ + DRV_PKE_ECC_TYPE_SM2, /* GMT 0003.2-2012 */ + DRV_PKE_ECC_TYPE_MAX, + DRV_PKE_ECC_TYPE_INVALID = 0xffffffff, +} drv_pke_ecc_curve_type; + +typedef enum { + DRV_PKE_RSA_SCHEME_PKCS1_V15 = 0x00, /* PKCS#1 V15 */ + DRV_PKE_RSA_SCHEME_PKCS1_V21, /* PKCS#1 V21, PSS for signning, OAEP for encryption */ + DRV_PKE_RSA_SCHEME_MAX, + DRV_PKE_RSA_SCHEME_INVALID = 0xffffffff, +} drv_pke_rsa_scheme; + +typedef enum { + DRV_PKE_HASH_TYPE_SHA1 = 0x00, /* Suggest Not to use */ + DRV_PKE_HASH_TYPE_SHA224, + DRV_PKE_HASH_TYPE_SHA256, + DRV_PKE_HASH_TYPE_SHA384, + DRV_PKE_HASH_TYPE_SHA512, + DRV_PKE_HASH_TYPE_SM3, + DRV_PKE_HASH_TYPE_MAX, + DRV_PKE_HASH_TYPE_INVALID = 0xffffffff, +} drv_pke_hash_type; + +typedef enum { + DRV_PKE_BUF_NONSECURE = 0x00, + DRV_PKE_BUF_SECURE, + DRV_PKE_BUF_INVALID = 0xffffffff, +} drv_pke_buffer_secure; + +typedef struct { + td_u32 length; + td_u8 *data; +} drv_pke_data; + +/* * struct of ecc point */ +typedef struct { + td_u8 *x; /* X coordinates of the generated public key, the caller ensures it is padded with leading + zeros if the effective size of this key is smaller than ecc key size. */ + td_u8 *y; /* Y coordinates of the generated public key, the caller ensures it is padded with leading + zeros if the effective size of this key is smaller than ecc key size. */ + td_u32 length; +} drv_pke_ecc_point; + +/* * struct of ecc signature */ +typedef struct { + td_u8 *r; /* r component of the signature. */ + td_u8 *s; /* s component of the signature. */ + td_u32 length; +} drv_pke_ecc_sig; + +/* * struct of ecc curves parameters. */ +typedef struct { + const td_u8 *p; /* prime specifying the base field. It is p (RFC5639), p (FIPS), p (RFC7748). */ + const td_u8 *a; /* Curve parameter a. It is A (RFC5639), c (FIPS), A24 (RFC7748). */ + const td_u8 *b; /* Curve parameter b. It is B (RFC5639), b (FIPS), N/A (RFC7748). */ + const td_u8 *gx; /* X coordinates of G which is a base point on the curve. + It is x (RFC5639), Gx (FIPS), U(P) (RFC7748). */ + const td_u8 *gy; /* Y coordinates of G which is a base point on the curve. + It is y (RFC5639), Gy (FIPS), N/A (RFC7748). */ + const td_u8 *n; /* Prime which is the order of G point. It is q (RFC5639), n (FIPS), N/A (RFC7748). */ + td_u32 h; /* Cofactor, which is the order of the elliptic curve divided by the order of the point G. + It is h (RFC5639), h (FIPS), Cofactor (RFC7748). */ + drv_pke_len ksize; /* Ecc key size in bytes. It corresponds to the size in bytes of the prime. */ + drv_pke_ecc_curve_type ecc_type; /* Type of ECC curve */ +} drv_pke_ecc_curve; + +typedef struct { + td_u32 length; + td_u8 *data; + drv_pke_buffer_secure buf_sec; +} drv_pke_msg; + +/* * RSA private key struct */ +typedef struct { + td_u8 *n; /* *< public modulus */ + td_u8 *e; /* *< public exponent */ + td_u8 *d; /* *< private exponent */ + td_u8 *p; /* *< 1st prime factor */ + td_u8 *q; /* *< 2nd prime factor */ + td_u8 *dp; /* *< D % (P - 1) */ + td_u8 *dq; /* *< D % (Q - 1) */ + td_u8 *qp; /* *< 1 / (Q % P) */ + td_u16 n_len; /* *< length of public modulus */ + td_u16 e_len; /* *< length of public exponent */ + td_u16 d_len; /* *< length of private exponent */ + td_u16 p_len; /* *< length of 1st prime factor,should be half of u16NLen */ + td_u16 q_len; /* *< length of 2nd prime factor,should be half of u16NLen */ + td_u16 dp_len; /* *< length of D % (P - 1),should be half of u16NLen */ + td_u16 dq_len; /* *< length of D % (Q - 1),should be half of u16NLen */ + td_u16 qp_len; /* *< length of 1 / (Q % P),should be half of u16NLen */ +} drv_pke_rsa_priv_key; + +/* * struct of RSA public key */ +typedef struct { + td_u8 *n; /* point to public modulus */ + td_u8 *e; /* point to public exponent */ + td_u16 len; /* length of public modulus, max value is 512Byte */ +} drv_pke_rsa_pub_key; + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_symc_struct.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_symc_struct.h new file mode 100644 index 00000000..c847ba73 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_symc_struct.h @@ -0,0 +1,184 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef CRYPTO_SYMC_STRUCT_H +#define CRYPTO_SYMC_STRUCT_H + +#include "crypto_common_struct.h" + +/* Structure for SYMC Create. */ +typedef enum { + CRYPTO_SYMC_TYPE_NORMAL = 0x0, + CRYPTO_SYMC_TYPE_REG, + CRYPTO_SYMC_TYPE_MAX, + CRYPTO_SYMC_TYPE_INVALID = 0xffffffff, +} crypto_symc_type; + +typedef enum { + CRYPTO_SYMC_ALG_TDES = 0x0, + CRYPTO_SYMC_ALG_AES = 0x1, + CRYPTO_SYMC_ALG_SM4 = 0x2, + CRYPTO_SYMC_ALG_LEA = 0x3, + CRYPTO_SYMC_ALG_DMA = 0x4, + CRYPTO_SYMC_ALG_MAX, + CRYPTO_SYMC_ALG_INVALID = 0xffffffff, +} crypto_symc_alg; + +typedef enum { + CRYPTO_SYMC_WORK_MODE_ECB = 0x0, + CRYPTO_SYMC_WORK_MODE_CBC, + CRYPTO_SYMC_WORK_MODE_CTR, + CRYPTO_SYMC_WORK_MODE_OFB, + CRYPTO_SYMC_WORK_MODE_CFB, + CRYPTO_SYMC_WORK_MODE_CCM, + CRYPTO_SYMC_WORK_MODE_GCM, + CRYPTO_SYMC_WORK_MODE_CBC_MAC, + CRYPTO_SYMC_WORK_MODE_CMAC, + CRYPTO_SYMC_WORK_MODE_MAX, + CRYPTO_SYMC_WORK_MODE_INVALID = 0xffffffff, +} crypto_symc_work_mode; + +typedef enum { + CRYPTO_SYMC_KEY_64BIT = 0x0, + CRYPTO_SYMC_KEY_128BIT = 0x1, + CRYPTO_SYMC_KEY_192BIT = 0x2, + CRYPTO_SYMC_KEY_256BIT = 0x3, + CRYPTO_SYMC_KEY_LENGTH_MAX, + CRYPTO_SYMC_KEY_LENGTH_INVALID = 0xffffffff, +} crypto_symc_key_length; + +typedef enum { + CRYPTO_SYMC_KEY_EVEN = 0x0, + CRYPTO_SYMC_KEY_ODD = 0x1, + CRYPTO_SYMC_KEY_PARITY_MAX, + CRYPTO_SYMC_KEY_PARITY_INVALID = 0xffffffff, +} crypto_symc_key_parity; + +typedef enum { + CRYPTO_SYMC_BIT_WIDTH_1BIT = 0x0, + CRYPTO_SYMC_BIT_WIDTH_8BIT = 0x1, + CRYPTO_SYMC_BIT_WIDTH_64BIT = 0x2, + CRYPTO_SYMC_BIT_WIDTH_128BIT = 0x3, + CRYPTO_SYMC_BIT_WIDTH_MAX, + CRYPTO_SYMC_BIT_WIDTH_INVALID = 0xffffffff, +} crypto_symc_bit_width; + +typedef enum { + CRYPTO_SYMC_IV_DO_NOT_CHANGE = 0, + CRYPTO_SYMC_IV_CHANGE_ONE_PKG, + CRYPTO_SYMC_IV_CHANGE_ALL_PKG, + /* GCM. */ + CRYPTO_SYMC_GCM_IV_DO_NOT_CHANGE, + CRYPTO_SYMC_GCM_IV_CHANGE_START, + CRYPTO_SYMC_GCM_IV_CHANGE_UPDATE, + CRYPTO_SYMC_GCM_IV_CHANGE_FINISH, + /* CCM. */ + CRYPTO_SYMC_CCM_IV_DO_NOT_CHANGE, + CRYPTO_SYMC_CCM_IV_CHANGE_START, + CRYPTO_SYMC_CCM_IV_CHANGE_UPDATE, + CRYPTO_SYMC_CCM_IV_CHANGE_FINISH, + CRYPTO_SYMC_IV_CHANGE_MAX, + CRYPTO_SYMC_IV_CHANGE_INVALID = 0xffffffff, +} crypto_symc_iv_change_type; + +typedef struct { + crypto_symc_alg symc_alg; + crypto_symc_work_mode work_mode; + crypto_symc_type symc_type; + td_bool is_long_term; +} crypto_symc_attr; + +typedef struct { + crypto_buf_attr buf_attr; + td_u32 length; +} crypto_symc_pack; + +typedef struct { + td_u32 clear_header_len; + td_u32 payload_len; + td_u32 payload_pattern_encrypt_len; + td_u32 payload_pattern_clear_len; + td_u32 payload_pattern_offset_len; + td_bool iv_change; + td_u32 iv[CRYPTO_AES_IV_SIZE_IN_WORD]; +} crypto_symc_cenc_subsample; + +typedef struct { + td_bool use_odd_key; + td_u32 first_encrypt_offset; + crypto_symc_cenc_subsample *subsample; + td_u32 subsample_num; + crypto_symc_alg alg; + crypto_symc_work_mode work_mode; + td_u32 iv[CRYPTO_AES_IV_SIZE_IN_WORD]; +} crypto_symc_cenc_param; + +typedef struct { + crypto_buf_attr aad_buf; + td_u32 aad_len; /* Addition Data Length In Bytes. */ + td_u32 data_len; /* Crypto Data Length In Bytes. */ + td_u32 tag_len; /* Tag Length In Bytes. */ +} crypto_symc_config_aes_ccm_gcm; + +typedef struct { + crypto_symc_alg symc_alg; + crypto_symc_work_mode work_mode; + crypto_symc_key_length symc_key_length; + crypto_symc_key_parity key_parity; + crypto_symc_bit_width symc_bit_width; + crypto_symc_iv_change_type iv_change_flag; + td_u8 iv[CRYPTO_IV_LEN_IN_BYTES]; + td_u32 iv_length; + td_void *param; +} crypto_symc_ctrl_t; + +typedef struct { + td_u32 chn_id; /* Channel number */ + td_u32 open; /* Open or closed */ + td_u32 is_decrypt; /* Decrypt or encrypt */ + td_u32 alg; /* Algorithm */ + td_u32 mode; /* Work mode */ + td_u32 key_len; /* Key length */ + td_u32 key_source; /* Hard or soft key */ + td_u32 int_raw; /* Raw intertupt */ + td_u32 int_en; /* Enable interrupt */ + td_u32 int_status; /* Status interrupt */ + td_u32 owner; /* Process PID of owner */ + td_u32 is_secure; /* Secure channel or not */ + td_u32 smmu_enable; /* Smmu enable */ + td_u32 in_node_head; /* In node list head */ + td_u32 in_node_rptr; /* In node list read index */ + td_u32 in_node_wptr; /* In node list write index */ + td_u32 in_node_depth; /* In node depth */ + td_u32 out_node_head; /* Out node list head */ + td_u32 out_node_rptr; /* Out node list read index */ + td_u32 out_node_wptr; /* Out node list write index */ + td_u32 out_node_depth; /* Out node depth */ + td_u8 iv[CRYPTO_AES_IV_SIZE + CRYPTO_AES_IV_SIZE + 1]; /* Out iv */ +} crypto_symc_proc_info; + +typedef struct { + td_u32 allow_reset; /* allow reset CPU or not */ + td_u32 sec_cpu; /* secure CPU or not */ + const char *name; /* interrupt name */ + td_u32 int_num; /* interrupt number */ + td_u32 int_en; /* interrupt enable */ + td_u32 smmu_base; /* smmu base address */ + td_u32 err_code; /* error code */ +} crypto_symc_module_info; + +typedef struct { + td_bool is_long_term; + crypto_symc_alg symc_alg; + crypto_symc_work_mode work_mode; + crypto_symc_key_length symc_key_length; + td_u32 keyslot_chn; +} crypto_symc_mac_attr; + +typedef struct { + td_u8 key[32]; + td_bool is_odd; + td_u32 klen; +} crypto_symc_clear_key; +#endif diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_type.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_type.h new file mode 100644 index 00000000..f8430934 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/common_include/crypto_type.h @@ -0,0 +1,26 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef CRYPTO_TYPE_H +#define CRYPTO_TYPE_H + +#if defined(CONFIG_CRYPTO_CHIP_HI3519DV500) +#include "ot_type.h" +#else +#include "td_type.h" +#endif + +#if defined(CONFIG_CRYPTO_CHIP_HI3892WV100) +#define TD_SUCCESS 0 +#define TD_FAILURE 0xFFFFFFFF +#endif + +#include "crypto_common_def.h" +#include "crypto_common_macro.h" +#include "crypto_errno.h" + +#if defined(__UBOOT__) +#endif + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/drv_include/drv_common.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/drv_include/drv_common.h new file mode 100644 index 00000000..1b3846e9 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/drv_include/drv_common.h @@ -0,0 +1,69 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef DRV_COMMON_H +#define DRV_COMMON_H + +#include "crypto_type.h" +#include "crypto_common_struct.h" +#include "hal_common.h" + +/************************************************** common check log start************************************/ +#ifndef drv_crypto_check_param +#define drv_crypto_check_param(module, cond) do { \ + crypto_check_param(ERROR_LAYER_DRV, module, cond, ERROR_INVALID_PARAM); \ +} while (0) +#endif + +#ifndef drv_crypto_check_param_null +#define drv_crypto_check_param_null(module, _val) do { \ + crypto_check_param_null(ERROR_LAYER_DRV, module, _val); \ +} while (0) +#endif + +#ifndef drv_crypto_pke_check_param +#define drv_crypto_pke_check_param(cond) do { \ + drv_crypto_check_param(ERROR_MODULE_PKE, cond); \ +} while (0) +#endif + +#ifndef drv_crypto_pke_check_param_null +#define drv_crypto_pke_check_param_null(_val) do { \ + drv_crypto_check_param_null(ERROR_MODULE_PKE, _val); \ +} while (0) +#endif +/************************************************** common check log end************************************/ + +typedef enum { + CRYPTO_MEM_TYPE_MMZ, + CRYPTO_MEM_TYPE_SMMU, +} crypto_mem_type; + +typedef void *(*func_malloc)(unsigned int size, crypto_mem_type mem_type, const char *buffer_name); +typedef void (*func_free)(void *ptr); +typedef td_phys_addr_t (*func_get_phys_addr)(void *ptr); +typedef void *(*func_get_virt_addr)(void *ptr); +typedef td_bool (*func_get_smmu_table_addr)(td_u64 *table, td_u64 *rdaddr, td_u64 *wraddr); +typedef void *(*func_register_coherent_mem)(void *virt_addr, td_phys_addr_t phys_addr, unsigned int size); +typedef void (*func_unregister_coherent_mem)(void *virt_addr); +typedef crypto_cpu_type (*func_get_cpu_type)(void); + +typedef struct { + func_malloc malloc_coherent; + func_free free_coherent; + func_get_phys_addr get_phys_addr; + func_get_virt_addr get_virt_addr; + func_get_smmu_table_addr get_smmu_table_addr; + func_register_coherent_mem register_coherent_mem; + func_unregister_coherent_mem unregister_coherent_mem; + func_get_cpu_type get_cpu_type; +} crypto_drv_func; + +td_s32 drv_cipher_register_func(const crypto_drv_func *drv_func_list); + +td_s32 drv_cipher_hash_suspend(td_void); + +td_s32 drv_cipher_hash_resume(td_void); + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/drv_include/drv_hash.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/drv_include/drv_hash.h new file mode 100644 index 00000000..4cda2def --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/drv_include/drv_hash.h @@ -0,0 +1,32 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef DRV_HASH_H +#define DRV_HASH_H + +#include "crypto_type.h" +#include "crypto_hash_struct.h" +#include "crypto_kdf_struct.h" + +td_s32 drv_cipher_hash_init(td_void); + +td_s32 drv_cipher_hash_deinit(td_void); + +td_s32 drv_cipher_hash_start(td_handle *drv_hash_handle, const crypto_hash_attr *hash_attr); + +td_s32 drv_cipher_hash_update(td_handle drv_hash_handle, const crypto_buf_attr *src_buf, const td_u32 len); + +td_s32 drv_cipher_hash_finish(td_handle drv_hash_handle, td_u8 *out, td_u32 *out_len); + +td_s32 drv_cipher_hash_get(td_handle drv_hash_handle, crypto_hash_clone_ctx *hash_ctx); + +td_s32 drv_cipher_hash_set(td_handle drv_hash_handle, const crypto_hash_clone_ctx *hash_ctx); + +td_s32 drv_cipher_hash_destroy(td_handle drv_hash_handle); + +td_s32 drv_cipher_pbkdf2(const crypto_kdf_pbkdf2_param *param, td_u8 *out, const td_u32 out_len); + +td_s32 drv_cipher_hmac256_block(const td_u8 *input_data, td_u32 data_len, td_u8 *hmac, td_u32 hmac_len); + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/drv_include/drv_keyslot.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/drv_include/drv_keyslot.h new file mode 100644 index 00000000..13f2ed01 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/drv_include/drv_keyslot.h @@ -0,0 +1,19 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef DRV_KEYSLOT_H +#define DRV_KEYSLOT_H + +#include "crypto_type.h" +#include "crypto_km_struct.h" + +td_s32 drv_keyslot_init(td_void); + +td_s32 drv_keyslot_deinit(td_void); + +td_s32 drv_keyslot_create(td_handle *keyslot_handle, crypto_keyslot_type keyslot_type); + +td_s32 drv_keyslot_destroy(td_handle keyslot_handle); + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/drv_include/drv_klad.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/drv_include/drv_klad.h new file mode 100644 index 00000000..e2cc5a90 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/drv_include/drv_klad.h @@ -0,0 +1,29 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef DRV_KLAD_H +#define DRV_KLAD_H + +#include "crypto_type.h" +#include "crypto_km_struct.h" + +td_s32 drv_klad_create(td_handle *klad_handle); + +td_s32 drv_klad_destroy(td_handle klad_handle); + +td_s32 drv_klad_attach(td_handle klad_handle, crypto_klad_dest klad_dest, td_handle keyslot_handle); + +td_s32 drv_klad_detach(td_handle klad_handle, crypto_klad_dest klad_dest, td_handle keyslot_handle); + +td_s32 drv_klad_set_attr(td_handle klad_handle, const crypto_klad_attr *attr); + +td_s32 drv_klad_get_attr(td_handle klad_handle, crypto_klad_attr *attr); + +td_s32 drv_klad_set_clear_key(td_handle klad_handle, const crypto_klad_clear_key *clear_key); + +td_s32 drv_klad_set_session_key(td_handle klad_handle, const crypto_klad_session_key *session_key); + +td_s32 drv_klad_set_content_key(td_handle klad_handle, const crypto_klad_content_key *content_key); + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/drv_include/drv_otp.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/drv_include/drv_otp.h new file mode 100644 index 00000000..73abb83a --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/drv_include/drv_otp.h @@ -0,0 +1,72 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef DRV_OTP_API_H +#define DRV_OTP_API_H + +#include "ot_type.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +/** +\brief otp word read. +\attention \n +N/A + +\param[in] addr: read address(0x00 ~ 0x1ff), requires 4 bytes align. +\param[out] data: read word buffer(data is put in little endian). +\param[in] check_word: the checksum of the parameters. +\retval ::TD_SUCCESS Call this API succussful. +\retval ::TD_FAILURE Call this API fails. + +\see \n +N/A +*/ +td_s32 drv_otp_read_word(const td_u32 addr, td_u32 *data); + +/** +\brief otp byte read. +\attention \n +N/A + +\param[in] addr: read address(0x00 ~ 0x1ff). +\param[out] data: read byte buffer(data is put in little endian). +\param[in] chech_word: the checksum of the parameters. +\retval ::TD_SUCCESS Call this API succussful. +\retval ::TD_FAILURE Call this API fails. + +\see \n +N/A +*/ +td_s32 drv_otp_read_byte(const td_u32 addr, td_u8 *data); + +/** +\brief otp byte write. +\attention \n +N/A + +\param[in] addr: write address(0x00 ~ 0x1ff). +\param[in] data: write data. +\param[in] chech_word: the checksum of the parameters. +\retval ::TD_SUCCESS Call this API succussful. +\retval ::TD_FAILURE Call this API fails. + +\see \n +N/A +*/ +td_s32 drv_otp_write_byte(const td_u32 addr, const td_u8 data); + +td_s32 drv_otp_get_die_id(td_u8 *die_id, const td_u32 len); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/drv_include/drv_pke.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/drv_include/drv_pke.h new file mode 100644 index 00000000..b90134c3 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/drv_include/drv_pke.h @@ -0,0 +1,178 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef DRV_PKE_H +#define DRV_PKE_H + +#include "crypto_pke_struct.h" + +/* Define ECC-HASH related data & types */ +#define SHA1_BLOCK_LENGTH 64 +#define SHA224_BLOCK_LENGTH 64 +#define SHA256_BLOCK_LENGTH 64 +#define SHA384_BLOCK_LENGTH 128 +#define SHA512_BLOCK_LENGTH 128 +#define SM3_BLOCK_LENGTH 64 + +#define SHA1_RESULT_LENGTH 20 +#define SHA224_RESULT_LENGTH 28 +#define SHA256_RESULT_LENGTH 32 +#define SHA384_RESULT_LENGTH 48 +#define SHA512_RESULT_LENGTH 64 +#define SM3_RESULT_LENGTH 32 + +/* result size */ +#define HASH_SIZE_SHA_1 20 +#define HASH_SIZE_SHA_224 28 +#define HASH_SIZE_SHA_256 32 +#define HASH_SIZE_SHA_384 48 +#define HASH_SIZE_SHA_512 64 +#define HASH_SIZE_SHA_MAX 64 + +#define DRV_PKE_SM2_LEN_IN_BYTES 32 + +#define PKE_MAX_TIMES 3000 + +#define WORD_INDEX_0 0 +#define WORD_INDEX_1 1 +#define WORD_INDEX_2 2 +#define WORD_INDEX_3 3 + +#define MAX_LOW_2BITS 3 +#define MAX_LOW_3BITS 7 +#define MAX_LOW_4BITS 0xF +#define MAX_LOW_8BITS 0xFF + +#define SHIFT_4BITS 4 +#define SHIFT_8BITS 8 +#define SHIFT_16BITS 16 +#define SHIFT_24BITS 24 + +#define BOUND_VALUE_1 1 + +#define REGISTER_WIDTH 8 +#define DRV_WORD_WIDTH 4 +#define BYTE_BITS 8 + +#define RSA_PUBLIC 0x5A /* public key operation */ +#define RSA_PRIVATE 0xA5 /* private key operation */ + +#define RSA_PADLEN_1 1 +#define RSA_PADLEN_2 2 +#define RSA_PADLEN_3 3 +#define RSA_PADLEN_8 8 +#define RSA_PADLEN_11 11 +#define RSA_PADLEN_19 19 +#define RSA_PADLEN_51 51 +#define RSA_PAD_X12 0x12 +#define RSA_PAD_X55 0x55 +#define RSA_PAD_XBC 0xBC + +#define RSA_MIN_KEY_LEN 32 +#define RSA_MAX_KEY_LEN 512 +#define HASH_SIZE_SHA_MAX 64 + +#define ECC_TRY_CNT 8 + +#define ECC_KEY_LEN_IN_WORD 0x12 +#define ECC_KEY_LEN_IN_BYTE (ECC_KEY_LEN_IN_WORD * 4) +#define ECC_KEY_LEN_IN_BYTE_X2 (ECC_KEY_LEN_IN_BYTE * 2) // 2: x2 is for security enhancement + + +#define SM2_PC_UNCOMPRESS 0x04 +#define SM2_TRY_CNT 8 +#define ENTLA_LEN 2 +#define PKE_U16_MAX 0xFFFF + +typedef struct { + td_u32 klen; + td_u32 em_bit; + td_u8 *em; + td_u32 em_len; + td_u8 *hash; + td_u32 hash_len; + td_u8 *data; + td_u32 data_len; +} rsa_pkcs1_pack; + +typedef struct { + drv_pke_hash_type hash_type; + td_u32 hash_len; + td_u8 *lhash_data; + td_u8 *asn1_data; + td_u32 asn1_len; +} rsa_pkcs1_hash_info; + +typedef struct { + drv_pke_hash_type hash_type; + td_u32 block_len; + td_u32 result_len; +} pke_hash_properties_type; + +typedef struct { + td_u8 *px; + td_u8 *py; + td_u8 *id; + td_u16 id_len; +} sm2_sign_verify_hash_pack; + +td_s32 drv_cipher_pke_init(void); + +td_s32 drv_cipher_pke_deinit(void); + +td_s32 drv_cipher_pke_mod(const drv_pke_data *a, const drv_pke_data *p, const drv_pke_data *c); + +td_s32 drv_cipher_pke_exp_mod(const drv_pke_data *n, const drv_pke_data *k, + const drv_pke_data *in, const drv_pke_data *out); + +td_s32 drv_cipher_pke_lock_secure(void); + +td_s32 drv_cipher_pke_unlock_secure(void); + +td_s32 drv_cipher_pke_rsa_sign(const drv_pke_rsa_priv_key *priv_key, const drv_pke_rsa_scheme scheme, + const drv_pke_hash_type hash_type, const drv_pke_data *input_hash, + drv_pke_data *sign); + +td_s32 drv_cipher_pke_rsa_verify(const drv_pke_rsa_pub_key *pub_key, drv_pke_rsa_scheme scheme, + const drv_pke_hash_type hash_type, const drv_pke_data *input_hash, const drv_pke_data *sign); + +td_s32 drv_cipher_pke_rsa_public_encrypt(const drv_pke_rsa_scheme scheme, const drv_pke_hash_type hash_type, + const drv_pke_rsa_pub_key *pub_key, const drv_pke_data *input, const drv_pke_data *label, + drv_pke_data *output); + +td_s32 drv_cipher_pke_rsa_private_decrypt(const drv_pke_rsa_scheme scheme, const drv_pke_hash_type hash_type, + const drv_pke_rsa_priv_key *priv_key, const drv_pke_data *input, const drv_pke_data *label, + drv_pke_data *output); + +td_s32 drv_cipher_pke_check_dot_on_curve(drv_pke_ecc_curve_type curve_type, const drv_pke_ecc_point *pub_key, + td_bool *is_on_curve); + +td_s32 drv_cipher_pke_ecc_gen_key(drv_pke_ecc_curve_type curve_type, const drv_pke_data *input_priv_key, + const drv_pke_data *output_priv_key, const drv_pke_ecc_point *output_pub_key); + +td_s32 drv_cipher_pke_ecc_gen_ecdh_key(drv_pke_ecc_curve_type curve_type, const drv_pke_ecc_point *input_pub_key, + const drv_pke_data *input_priv_key, const drv_pke_data *output_shared_key); + +td_s32 drv_cipher_pke_ecdsa_sign(drv_pke_ecc_curve_type curve_type, const drv_pke_data *priv_key, + const drv_pke_data *hash, const drv_pke_ecc_sig *sig); + +td_s32 drv_cipher_pke_ecdsa_verify(drv_pke_ecc_curve_type curve_type, const drv_pke_ecc_point *pub_key, + const drv_pke_data *hash, const drv_pke_ecc_sig *sig); + +td_s32 drv_cipher_pke_eddsa_sign(drv_pke_ecc_curve_type curve_type, const drv_pke_data *priv_key, + const drv_pke_msg *msg, const drv_pke_ecc_sig *sig); + +td_s32 drv_cipher_pke_eddsa_verify(drv_pke_ecc_curve_type curve_type, const drv_pke_ecc_point *pub_key, + const drv_pke_msg *msg, const drv_pke_ecc_sig *sig); + +td_s32 drv_cipher_pke_sm2_dsa_hash(const drv_pke_data *sm2_id, const drv_pke_ecc_point *pub_key, + const drv_pke_msg *msg, drv_pke_data *hash); + +td_s32 drv_cipher_pke_sm2_public_encrypt(const drv_pke_ecc_point *pub_key, const drv_pke_data *plain_text, + drv_pke_data *cipher_text); + +td_s32 drv_cipher_pke_sm2_private_decrypt(const drv_pke_data *priv_key, const drv_pke_data *cipher_text, + drv_pke_data *plain_text); + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/drv_include/drv_symc.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/drv_include/drv_symc.h new file mode 100644 index 00000000..c80138c1 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/drv_include/drv_symc.h @@ -0,0 +1,49 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef DRV_SYMC_H +#define DRV_SYMC_H + +#include "crypto_type.h" +#include "crypto_symc_struct.h" + +td_s32 drv_cipher_symc_init(td_void); + +td_s32 drv_cipher_symc_deinit(td_void); + +td_s32 drv_cipher_symc_create(td_handle *symc_handle, const crypto_symc_attr *symc_attr); + +td_s32 drv_cipher_symc_destroy(td_handle symc_handle); + +td_s32 drv_cipher_symc_get_module_info(crypto_symc_module_info *module_info); + +td_s32 drv_cipher_symc_get_proc_info(td_handle symc_handle, crypto_symc_proc_info *proc_symc_info); + +td_s32 drv_cipher_symc_set_config(td_handle symc_handle, const crypto_symc_ctrl_t *symc_ctrl); + +td_s32 drv_cipher_symc_get_config(td_handle symc_handle, crypto_symc_ctrl_t *symc_ctrl); + +td_s32 drv_cipher_symc_attach(td_handle symc_handle, td_handle keyslot_handle); + +td_s32 drv_cipher_symc_encrypt(td_handle symc_handle, const crypto_buf_attr *src_buf, + const crypto_buf_attr *dst_buf, td_u32 length); + +td_s32 drv_cipher_symc_decrypt(td_handle symc_handle, const crypto_buf_attr *src_buf, + const crypto_buf_attr *dst_buf, td_u32 length); + +td_s32 drv_cipher_symc_encrypt_multi(td_handle symc_handle, const crypto_symc_ctrl_t *symc_ctrl, + const crypto_symc_pack *src_buf_pack, const crypto_symc_pack *dst_buf_pack, td_u32 pack_num); + +td_s32 drv_cipher_symc_decrypt_multi(td_handle symc_handle, const crypto_symc_ctrl_t *symc_ctrl, + const crypto_symc_pack *src_buf_pack, const crypto_symc_pack *dst_buf_pack, td_u32 pack_num); + +td_s32 drv_cipher_symc_get_tag(td_handle symc_handle, td_u8 *tag, td_u32 tag_length); + +td_s32 drv_cipher_mac_start(td_handle *symc_handle, const crypto_symc_mac_attr *mac_attr); + +td_s32 drv_cipher_mac_update(td_handle symc_handle, const crypto_buf_attr *src_buf, td_u32 length); + +td_s32 drv_cipher_mac_finish(td_handle symc_handle, td_u8 *mac, td_u32 *mac_length); + +#endif diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/drv_include/drv_trng.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/drv_include/drv_trng.h new file mode 100644 index 00000000..a9c672db --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/drv_include/drv_trng.h @@ -0,0 +1,18 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef DRV_TRNG_H +#define DRV_TRNG_H + +#include "crypto_type.h" + +td_s32 drv_cipher_trng_init(td_void); + +td_s32 drv_cipher_trng_get_random(td_u32 *randnum); + +td_s32 drv_cipher_trng_get_multi_random(td_u32 size, td_u8 *randnum); + +td_s32 drv_cipher_trng_deinit(td_void); + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/hal_include/hal_common.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/hal_include/hal_common.h new file mode 100644 index 00000000..36997fdb --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/hal_include/hal_common.h @@ -0,0 +1,67 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef HAL_COMMON_H +#define HAL_COMMON_H + +#include "crypto_type.h" + +/************************************************** common check log start************************************/ +#ifndef hal_crypto_check_param +#define hal_crypto_check_param(module, cond) do { \ + crypto_check_param(ERROR_LAYER_HAL, module, cond, ERROR_INVALID_PARAM); \ +} while (0) +#endif + +#ifndef hal_crypto_check_param_null +#define hal_crypto_check_param_null(module, _val) do { \ + crypto_check_param_null(ERROR_LAYER_HAL, module, _val); \ +} while (0) +#endif + +#ifndef hal_crypto_pke_check_param +#define hal_crypto_pke_check_param(cond) do { \ + hal_crypto_check_param(ERROR_MODULE_PKE, cond); \ +} while (0) +#endif + +#ifndef hal_crypto_pke_check_param_null +#define hal_crypto_pke_check_param_null(_val) do { \ + hal_crypto_check_param_null(ERROR_MODULE_PKE, _val); \ +} while (0) +#endif +/************************************************** common check log end************************************/ + +typedef enum { + CRYPTO_CPU_TYPE_SCPU, + CRYPTO_CPU_TYPE_ACPU, + CRYPTO_CPU_TYPE_HPPCPU, + CRYPTO_CPU_TYPE_PCPU, + CRYPTO_CPU_TYPE_AIDSP, + CRYPTO_CPU_TYPE_INVALID +} crypto_cpu_type; + +typedef enum { + IN_NODE_TYPE_FIRST = 1 << 0, + IN_NODE_TYPE_NORMAL = 1 << 1, + IN_NODE_TYPE_LAST = 1 << 2, + /* CCM. */ + IN_NODE_TYPE_CCM_N = 1 << 3, + IN_NODE_TYPE_CCM_AAD = 1 << 4, + IN_NODE_TYPE_CCM_P = 1 << 5, + IN_NODE_TYPE_CCM_LAST = 1 << 6, + /* GCM. */ + IN_NODE_TYPE_GCM_FIRST = 1 << 7, + IN_NODE_TYPE_GCM_A = 1 << 8, + IN_NODE_TYPE_GCM_P = 1 << 9, + IN_NODE_TYPE_GCM_LEN = 1 << 10, + IN_NODE_TYPE_GCM_GHASH = 1 << 11, + IN_NODE_TYPE_GCM_IV = 1 << 12, +} in_node_type_e; + +typedef td_bool (*drv_wait_condition_func)(const td_void *param); +typedef td_s32 (*crypto_wait_timeout_interruptible)(const td_void *wait, drv_wait_condition_func func, + const td_void *param, const td_u32 timeout_ms); + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/hal_include/hal_hash.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/hal_include/hal_hash.h new file mode 100644 index 00000000..ef7434c3 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/hal_include/hal_hash.h @@ -0,0 +1,45 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef HAL_HASH_H +#define HAL_HASH_H + +#include "hal_common.h" +#include "crypto_hash_struct.h" + +td_s32 hal_cipher_hash_init(td_void); + +td_s32 hal_cipher_hash_deinit(td_void); + +td_s32 hal_hash_lock(td_u32 chn_num); + +td_s32 hal_hash_unlock(td_u32 chn_num); + +td_s32 hal_cipher_hash_config(td_u32 chn_num, crypto_hash_type hash_type, const td_u32 *state); + +td_s32 hal_cipher_hash_attach(td_u32 chn_num, td_u32 keyslot_chn_num); + +td_s32 hal_cipher_hash_add_in_node(td_u32 chn_num, td_phys_addr_t data_phys, td_u32 data_len, + in_node_type_e in_node_type); + +td_s32 hal_cipher_hash_start(td_u32 chn_num, td_bool is_wait); + +td_s32 hal_cipher_hash_start_calc(td_u32 chn_num, td_u8 *data, td_u32 length); + +td_s32 hal_cipher_hash_wait_done(td_u32 chn_num, td_u32 *state, td_u32 state_size); + +td_s32 hal_cipher_hash_register_wait_func(td_u32 chn_num, td_void *wait, + crypto_wait_timeout_interruptible wait_func, td_u32 timeout_ms); + +td_s32 hal_cipher_hash_done_notify(td_u32 chn_num); + +td_u32 hal_cipher_hash_done_try(td_u32 chn_num); + +td_s32 hal_cipher_hmac256_block(const td_u8 *input_data, td_u32 data_len, td_u8 *hmac, td_u32 hmac_len); + +td_s32 hal_cipher_hash_suspend(td_void); + +td_s32 hal_cipher_hash_resume(td_void); + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/hal_include/hal_keyslot.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/hal_include/hal_keyslot.h new file mode 100644 index 00000000..80a470ca --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/hal_include/hal_keyslot.h @@ -0,0 +1,15 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef HAL_KEYSLOT_H +#define HAL_KEYSLOT_H + +#include "crypto_type.h" +#include "crypto_km_struct.h" + +td_s32 hal_keyslot_lock(td_u32 keyslot_num, crypto_keyslot_type keyslot_type); + +td_s32 hal_keyslot_unlock(td_u32 keyslot_num, crypto_keyslot_type keyslot_type); + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/hal_include/hal_klad.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/hal_include/hal_klad.h new file mode 100644 index 00000000..1cc98c91 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/hal_include/hal_klad.h @@ -0,0 +1,36 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef HAL_KLAD_H +#define HAL_KLAD_H + +#include "crypto_type.h" +#include "crypto_km_struct.h" + +td_s32 hal_klad_lock(td_void); + +td_s32 hal_klad_unlock(td_void); + +td_s32 hal_klad_set_key_crypto_cfg(td_bool encrypt_support, td_bool decrypt_support, crypto_klad_engine engine); + +td_s32 hal_klad_set_key_dest_cfg(crypto_klad_dest dest, crypto_klad_flash_key_type flash_key_type); + +td_s32 hal_klad_set_key_secure_cfg(const crypto_klad_key_secure_config *secure_cfg); + +td_s32 hal_klad_set_key_addr(crypto_klad_dest klad_dest, td_u32 keyslot_chn); + +td_s32 hal_klad_set_data(const td_u8 *data, td_u32 data_length); + +td_s32 hal_klad_start_clr_route(crypto_klad_dest klad_dest, const crypto_klad_clear_key *clear_key); + +td_s32 hal_klad_com_start(crypto_klad_level_sel level, crypto_klad_alg_sel alg, crypto_klad_key_size key_size, + crypto_kdf_hard_key_type rk_type); + +td_s32 hal_klad_wait_com_route_done(td_void); + +td_void hal_klad_clear_data(td_void); + +td_void hal_klad_set_key_odd(td_bool odd); + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/hal_include/hal_pke.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/hal_include/hal_pke.h new file mode 100644 index 00000000..f1f64b8a --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/hal_include/hal_pke.h @@ -0,0 +1,131 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef HAL_PKE_H +#define HAL_PKE_H + + +#include "crypto_common_struct.h" +#include "hal_common.h" + +#define ECC_SET_KEY_LEN 80 // varies from chip to chip + +#define RSA_KEY_LEN_2048 256 +#define RSA_KEY_LEN_3072 384 +#define RSA_KEY_LEN_4096 512 + +#define ECC_MAX_KEY_LEN 72 + +/* ! \Define the offset of reg */ +#define PKE_VERSION_DATE 0x0 + +#define PKE_KEY_CRC 0x20 +#define PKE_MRAM 0x200 +#define PKE_PRAM 0x300 +#define PKE_NRAM 0x600 +#define PKE_KRAM 0xa00 +#define PKE_RRAM 0xe00 + +#define PKE_MG_A24 (PKE_NRAM + 0x120) // 0x720, for MG mul dot +#define PKE_MG_K (PKE_KRAM + 0x20) // 0xa20, for MG mul dot +#define PKE_ED_PD (PKE_NRAM + 0x180) // 0x780, for ED mul dot +#define PKE_ED_K (PKE_KRAM + 0x20) // 0xa20, for ED mul dot +#define PKE_ED_MRAM(i) (PKE_MRAM + 0x20 * (i)) // 0x200 + 0x20 * i, for ED mul dot and ED add dot +#define PKE_ED_RRAM(i) (PKE_RRAM + 0x20 * (i)) // 0xe00 + 0x20 * i, for ED mul dot and ED add dot +#define PKE_ED_NRAM(i) (PKE_NRAM + 0x20 * (i)) // 0x600 + 0x20 * i, for ED add dot + +/* ! Define the length of zero padding for mul-dot */ +#define PKE_LEN_BLOCK_IN_WOED 0x02 +#define PKE_LEN_BLOCK_IN_BYTE 0x08 + +#ifndef WORD_WIDTH +#define WORD_WIDTH 4 +#endif + +typedef enum { + HAL_SET_KEY_LEN = 0, + HAL_RAM_SECTION_LEN, + HAL_ECC_512_LEN, + HAL_ECC_521_LEN, + HAL_ALIGN_LEN = 0xff, +} diff_len_in_chips; + +typedef union { + td_u8 byte[PKE_LEN_BLOCK_IN_BYTE]; + td_u32 word[PKE_LEN_BLOCK_IN_WOED]; +} pke_block; + +typedef enum { + HAL_PKE_MODE_CLR_RAM = 0, + HAL_PKE_MODE_EXP_MOD, + HAL_PKE_MODE_MUL_DOT, + HAL_PKE_MODE_ADD_DOT, + HAL_PKE_MODE_TIMES_DOT, + HAL_PKE_MODE_MINV_MOD, + HAL_PKE_MODE_SUB_MOD, + HAL_PKE_MODE_MUL_MOD, + HAL_PKE_MODE_ADD_MOD, + HAL_PKE_MODE_MOD, + HAL_PKE_MODE_MUL, + HAL_PKE_MODE_MG_MUL_DOT, + HAL_PKE_MODE_ED_MUL_DOT, + HAL_PKE_MODE_ED_ADD_DOT, + HAL_PKE_MODE_KGEN_NO_E, + HAL_PKE_MODE_KGEN_WITH_E, + HAL_PKE_MODE_KTRANS +} hal_pke_mode; + +typedef enum { + PKE_DATA_LEN_BYTE_32 = 4, + PKE_DATA_LEN_BYTE_48 = 6, + PKE_DATA_LEN_BYTE_64 = 8, + PKE_DATA_LEN_BYTE_72 = 9, + PKE_DATA_LEN_BYTE_128 = 16, + PKE_DATA_LEN_BYTE_256 = 32, + PKE_DATA_LEN_BYTE_384 = 48, + PKE_DATA_LEN_BYTE_512 = 64, +} pke_data_len; + +typedef enum { + PKE_RAM_TYPE_MRAM = 0, /* 0x0200 ~ 0x05FF */ + PKE_RAM_TYPE_NRAM, /* 0x0600 ~ 0x09FF */ + PKE_RAM_TYPE_KRAM, /* 0x0a00 ~ 0x0dFF */ + PKE_RAM_TYPE_RRAM, /* 0x0e00 ~ 0x11FF */ +} pke_ram_type; + + +td_s32 hal_pke_init(void); + +td_s32 hal_pke_deinit(void); + +td_s32 hal_pke_lock(void); + +td_s32 hal_pke_unlock(void); + +td_s32 hal_pke_wait_free(void); + +td_void hal_pke_start(void); + +td_u32 hal_pke_done_try(void); + +td_void hal_pke_done_notify(void); + +td_s32 hal_pke_wait_done(void); + +td_s32 hal_pke_set_mode(hal_pke_mode mode, td_u32 len); + +td_void hal_pke_set_ram(td_u32 addr, const td_u8 *ram, td_u32 data_len, td_u32 padded_len); + +td_void hal_pke_get_ram(td_u32 addr, td_u8 *ram, td_u32 klen); + +td_void hal_pke_set_key(const td_u8 *inkey, td_u8 *outkey, td_u32 klen, pke_block *random, td_u32 pad_len); + +td_s32 hal_pke_align_len(td_u32 a_len, td_u32 *a_len_aligned, diff_len_in_chips len); + +td_void hal_pke_secure(td_bool enable); + +td_s32 hal_cipher_pke_register_wait_func(td_void *wait, + crypto_wait_timeout_interruptible wait_func, td_u32 timeout_ms); + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/hal_include/hal_rkp.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/hal_include/hal_rkp.h new file mode 100644 index 00000000..c5f0cdc1 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/hal_include/hal_rkp.h @@ -0,0 +1,37 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef HAL_RKP_H +#define HAL_RKP_H + +#include "crypto_type.h" +#include "crypto_km_struct.h" + +td_s32 hal_rkp_lock(td_void); + +td_s32 hal_rkp_unlock(td_void); + +td_s32 hal_rkp_deob_update(crypto_kdf_otp_key otp_key, crypto_kdf_update_alg alg); + +td_s32 hal_rkp_kdf_set_val(const td_u8 *kdf_val, td_u32 val_length); + +td_s32 hal_rkp_kdf_get_val(td_u8 *kdf_val, td_u32 val_length); + +td_s32 hal_rkp_kdf_set_padding_salt(const td_u8 *padding_salt, td_u32 salt_length); + +td_s32 hal_rkp_kdf_set_padding_key(const td_u8 *padding_key, td_u32 key_length); + +td_s32 hal_rkp_clear_reg_key(td_void); + +td_s32 hal_rkp_kdf_sw_start(crypto_kdf_sw_alg sw_alg, td_u32 count, td_bool is_wait); + +td_s32 hal_rkp_deob_wait_done(td_void); + +td_s32 hal_rkp_kdf_wait_done(td_void); + +td_s32 hal_rkp_kdf_hard_calculation(const crypto_kdf_hard_calc_param *param); + +td_void hal_rkp_debug(td_void); + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/hal_include/hal_symc.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/hal_include/hal_symc.h new file mode 100644 index 00000000..64e07013 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/hal_include/hal_symc.h @@ -0,0 +1,71 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef HAL_SYMC_H +#define HAL_SYMC_H + +#include "hal_common.h" +#include "crypto_symc_struct.h" + +td_s32 hal_cipher_symc_init(td_void); + +td_s32 hal_cipher_symc_deinit(td_void); + +td_s32 hal_cipher_symc_low_power_set(td_bool flag); + +td_s32 hal_cipher_symc_lock_chn(td_u32 chn_num); + +td_s32 hal_cipher_symc_unlock_chn(td_u32 chn_num); + +td_s32 hal_cipher_symc_attach(td_u32 symc_chn_num, td_u32 keyslot_chn_num); + +td_s32 hal_cipher_symc_set_iv(td_u32 chn_num, const td_u8 *iv, td_u32 iv_len); + +td_s32 hal_cipher_symc_get_iv(td_u32 chn_num, td_u8 *iv, td_u32 iv_len); + +typedef struct { + crypto_symc_alg symc_alg; + crypto_symc_work_mode work_mode; + crypto_symc_key_length symc_key_length; + crypto_symc_bit_width symc_bit_width; + td_bool is_decrypt; + crypto_symc_iv_change_type iv_change_flag; + /* iv_mac for ccm, iv_ghash for gcm. */ + td_u8 iv_mac[16]; + /* s0 for ccm, j0 for gcm. */ + td_u8 iv0[16]; + /* for gcm calculate j0. */ + const td_u8 *gcm_iv_ptr; + td_u32 gcm_iv_len; +} hal_symc_config_t; + +td_s32 hal_cipher_symc_config(td_u32 chn_num, const hal_symc_config_t *symc_config); + +td_s32 hal_cipher_symc_get_module_info(crypto_symc_module_info *module_info); + +td_s32 hal_cipher_symc_get_proc_info(td_u32 chn_num, crypto_symc_proc_info *proc_symc_info); + +td_s32 hal_cipher_symc_get_config(td_u32 chn_num, hal_symc_config_t *symc_config); + +td_s32 hal_cipher_symc_add_in_node(td_u32 chn_num, td_phys_addr_t data_phys_addr, td_u32 data_len, + in_node_type_e in_node_type); + +td_s32 hal_cipher_symc_add_out_node(td_u32 chn_num, td_phys_addr_t data_phys_addr, td_u32 data_len); + +td_s32 hal_cipher_symc_get_tag(td_u32 chn_num, td_u8 *tag, td_u32 tag_len); + +td_s32 hal_cipher_symc_start(td_u32 chn_num); + +td_s32 hal_cipher_symc_wait_done(td_u32 chn_num, td_bool is_wait); + +td_s32 hal_cipher_symc_done_try(td_u32 chn_num); + +td_s32 hal_cipher_symc_done_notify(td_u32 chn_num); + +td_s32 hal_cipher_symc_register_wait_func(td_u32 chn_num, td_void *wait, + crypto_wait_timeout_interruptible wait_func, td_u32 timeout_ms); + +td_void hal_cipher_set_chn_secure(td_u32 chn_num, td_bool dest_sec, td_bool src_sec); + +#endif diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/hal_include/hal_trng.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/hal_include/hal_trng.h new file mode 100644 index 00000000..934f286d --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/hal_include/hal_trng.h @@ -0,0 +1,16 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef HAL_TRNG_H +#define HAL_TRNG_H + +#include "crypto_type.h" + +td_s32 hal_cipher_trng_init(td_void); + +td_s32 hal_cipher_trng_get_random(td_u32 *randnum); + +td_s32 hal_cipher_trng_deinit(td_void); + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/ioctl_include/crypto_ioctl.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/ioctl_include/crypto_ioctl.h new file mode 100644 index 00000000..e1c4c88c --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/ioctl_include/crypto_ioctl.h @@ -0,0 +1,21 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef CRYPTO_IOCTL_H +#define CRYPTO_IOCTL_H + +#define CRYPTO_IOC_NA 0U +#define CRYPTO_IOC_W 1U +#define CRYPTO_IOC_R 2U +#define CRYPTO_IOC_RW 3U + +/* Ioctl definitions */ +#define CRYPTO_IOC(dir, type, nr, size) (((dir) << 30) | ((size) << 16) | ((type) << 8) | ((nr) << 0)) + +#define CRYPTO_IOC_DIR(cmd) (((cmd) >> 30) & 0x03) +#define CRYPTO_IOC_TYPE(cmd) (((cmd) >> 8) & 0xFF) +#define CRYPTO_IOC_NR(cmd) (((cmd) >> 0) & 0xFF) +#define CRYPTO_IOC_SIZE(cmd) (((cmd) >> 16) & 0x3FFF) + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/ioctl_include/crypto_ioctl_cmd.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/ioctl_include/crypto_ioctl_cmd.h new file mode 100644 index 00000000..a097ed50 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/ioctl_include/crypto_ioctl_cmd.h @@ -0,0 +1,503 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef CRYPTO_IOCTL_CMD_H +#define CRYPTO_IOCTL_CMD_H + +#include "crypto_ioctl.h" + +#include "crypto_hash_struct.h" +#include "crypto_symc_struct.h" +#include "crypto_pke_struct.h" +#include "crypto_common_def.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define CRYPTO_CIPHER_DEV_NAME "soc_cipher" + +typedef struct { + crypto_compat_addr key; + td_u32 key_len; + td_u32 kapi_hash_handle; + td_handle drv_keyslot_handle; + td_bool is_keyslot; + td_bool is_long_term; + crypto_hash_type hash_type; +} hash_start_ctl_t; + +typedef struct { + crypto_compat_addr src_buf; + td_u32 len; + td_handle kapi_hash_handle; +} hash_update_ctl_t; + +typedef struct { + crypto_compat_addr out; + td_u32 out_len; + td_handle kapi_hash_handle; +} hash_finish_ctl_t; + +typedef struct { + crypto_compat_addr password; + crypto_compat_addr salt; + crypto_compat_addr out; + td_u32 plen; + td_u32 slen; + td_u32 out_len; + td_u16 count; + crypto_hash_type hash_type; +} pbkdf2_ctl_t; + +typedef struct { + crypto_compat_addr hash_clone_ctx; + td_u32 ctx_size; + td_handle kapi_hash_handle; +} hash_clone_ctl_t; + +typedef struct { + td_handle kapi_hash_handle; +} hash_handle_ctl_t; + +typedef struct { + td_u32 randnum; +} trng_ctl_t; + +typedef struct { + td_u32 size; + crypto_compat_addr randnum; +} trng_multi_ctl_t; + +typedef struct { + td_handle symc_handle; + crypto_symc_attr symc_attr; +} symc_create_t; + +typedef struct { + td_handle symc_handle; +} symc_destroy_t; + +typedef struct { + td_handle symc_handle; + crypto_symc_alg symc_alg; + crypto_symc_work_mode work_mode; + crypto_symc_key_length symc_key_length; + crypto_symc_key_parity key_parity; + crypto_symc_bit_width symc_bit_width; + crypto_symc_iv_change_type iv_change_flag; + td_u8 iv[CRYPTO_IV_LEN_IN_BYTES]; + td_u32 iv_length; + td_u32 aad_len; + td_u32 data_len; + td_u32 tag_len; + unsigned long long aad_mem_handle; + td_phys_addr_t aad_phys_addr; + crypto_compat_addr aad; +} symc_config_t; + +typedef struct { + td_handle symc_handle; + td_handle keyslot_handle; +} symc_get_keyslot_t; + +typedef struct { + td_handle symc_handle; + td_handle keyslot_handle; +} symc_attach_t; + +typedef struct { + td_handle symc_handle; + td_u8 key[CRYPTO_256_KEY_LEN]; + td_u32 key_len; +} symc_set_key_t; + +typedef struct { + td_handle symc_handle; + unsigned long long src_mem_handle; + td_phys_addr_t src_phys_addr; + crypto_buffer_secure src_buf_sec; + unsigned long long src_addr_offset; + unsigned long long dst_mem_handle; + td_phys_addr_t dst_phys_addr; + crypto_buffer_secure dst_buf_sec; + unsigned long long dst_addr_offset; + td_u32 length; +} symc_crypto_t; + +typedef struct { + unsigned long long uapi_mem_handle; + td_phys_addr_t phys_addr; + td_u32 length; + crypto_buffer_secure buf_sec; /* NONSECURE or SECURE */ +} crypto_mem_pack; + +typedef struct { + td_handle symc_handle; + crypto_symc_alg symc_alg; + crypto_symc_work_mode work_mode; + crypto_symc_key_length symc_key_length; + crypto_symc_key_parity key_parity; + crypto_symc_bit_width symc_bit_width; + crypto_symc_iv_change_type iv_change_flag; + td_u8 iv[CRYPTO_IV_LEN_IN_BYTES]; + td_u32 iv_length; + crypto_compat_addr src_pack_addr; + crypto_compat_addr dst_pack_addr; + td_u32 pack_num; +} crypto_symc_multi_t; + +typedef struct { + td_handle symc_handle; + crypto_symc_alg alg; + crypto_symc_work_mode work_mode; + td_u32 iv[CRYPTO_AES_IV_SIZE_IN_WORD]; + td_bool use_odd_key; + td_u32 first_encrypt_offset; + td_u32 subsample_num; + crypto_compat_addr subsample_addr; + unsigned long long src_mem_handle; + crypto_buffer_secure src_buf_sec; + unsigned long long dst_mem_handle; + crypto_buffer_secure dst_buf_sec; + td_u32 length; +} crypto_symc_cenc_t; + +typedef struct { + td_handle symc_handle; + td_u8 tag[CRYPTO_AES_MAX_TAG_LEN]; + td_u32 tag_length; +} symc_get_tag_t; + +typedef struct { + td_handle symc_handle; + crypto_symc_mac_attr mac_attr; +} symc_mac_start_t; + +typedef struct { + td_handle symc_handle; + crypto_compat_addr src_buf; + td_u32 length; +} symc_mac_update_t; + +typedef struct { + td_handle symc_handle; + td_u8 mac[CRYPTO_AES_BLOCK_SIZE_IN_BYTES]; + td_u32 mac_length; +} symc_mac_finish_t; + +typedef struct { + td_handle keyslot_handle; + td_u8 key[32]; + td_u32 key_len; + keyslot_engine engine; +} keyslot_create_t; + +typedef struct { + td_handle keyslot_handle; +} keyslot_destroy_t; + +typedef struct { + crypto_compat_addr data; + td_u32 length; +} drv_pke_data_t; + +typedef struct { + td_u32 length; + crypto_compat_addr data; + drv_pke_buffer_secure buf_sec; +} drv_pke_msg_t; + +typedef struct { + crypto_compat_addr x; + crypto_compat_addr y; + td_u32 length; +} drv_pke_ecc_point_t; + +/* * struct of ecc signature */ +typedef struct { + crypto_compat_addr r; /* r component of the signature. */ + crypto_compat_addr s; /* s component of the signature. */ + td_u32 length; +} drv_pke_ecc_sig_t; + +typedef struct { + drv_pke_ecc_curve_type curve_type; + drv_pke_data_t input_priv_key; + drv_pke_data_t output_priv_key; + drv_pke_ecc_point_t output_pub_key; +} pke_ecc_gen_key_ctl_t; + +typedef struct { + drv_pke_ecc_curve_type curve_type; + drv_pke_ecc_point_t input_pub_key; + drv_pke_data_t input_priv_key; + drv_pke_data_t output_shared_key; +} pke_ecc_gen_ecdh_key_ctl_t; + +typedef struct { + drv_pke_ecc_curve_type curve_type; + drv_pke_data_t priv_key; + drv_pke_data_t hash; + drv_pke_ecc_sig_t sig; +} pke_ecdsa_sign_ctl_t; + +typedef struct { + drv_pke_ecc_curve_type curve_type; + drv_pke_ecc_point_t pub_key; + drv_pke_data_t hash; + drv_pke_ecc_sig_t sig; + crypto_compat_addr v; +} pke_ecdsa_verify_ctl_t; + +typedef struct { + drv_pke_ecc_curve_type curve_type; + drv_pke_data_t priv_key; + drv_pke_msg_t msg; + drv_pke_ecc_sig_t sig; +} pke_eddsa_sign_ctl_t; + +typedef struct { + drv_pke_ecc_curve_type curve_type; + drv_pke_ecc_point_t pub_key; + drv_pke_msg_t msg; + drv_pke_ecc_sig_t sig; +} pke_eddsa_verify_ctl_t; + +typedef struct { + drv_pke_ecc_curve_type curve_type; + drv_pke_ecc_point_t pub_key; + td_bool is_on_curve; +} pke_check_dot_on_curve_ctl_t; + +typedef struct pke_sm2_dsa_hash_ctl { + drv_pke_data_t sm2_id; + drv_pke_ecc_point_t pub_key; + drv_pke_msg_t msg; + drv_pke_data_t hash; +} pke_sm2_dsa_hash_ctl_t; + +typedef struct pke_sm2_public_encrypt_ctl { + drv_pke_ecc_point_t pub_key; + drv_pke_data_t plain_text; + drv_pke_data_t cipher_text; +} pke_sm2_public_encrypt_ctl_t; + +typedef struct { + drv_pke_data_t priv_key; + drv_pke_data_t cipher_text; + drv_pke_data_t plain_text; +} pke_sm2_private_decrypt_ctl_t; + +/* * RSA private key struct */ +typedef struct { + crypto_compat_addr n; /* *< public modulus */ + crypto_compat_addr e; /* *< public exponent */ + crypto_compat_addr d; /* *< private exponent */ + crypto_compat_addr p; /* *< 1st prime factor */ + crypto_compat_addr q; /* *< 2nd prime factor */ + crypto_compat_addr dp; /* *< D % (P - 1) */ + crypto_compat_addr dq; /* *< D % (Q - 1) */ + crypto_compat_addr qp; /* *< 1 / (Q % P) */ + td_u16 n_len; /* *< length of public modulus */ + td_u16 e_len; /* *< length of public exponent */ + td_u16 d_len; /* *< length of private exponent */ + td_u16 p_len; /* *< length of 1st prime factor,should be half of u16NLen */ + td_u16 q_len; /* *< length of 2nd prime factor,should be half of u16NLen */ + td_u16 dp_len; /* *< length of D % (P - 1),should be half of u16NLen */ + td_u16 dq_len; /* *< length of D % (Q - 1),should be half of u16NLen */ + td_u16 qp_len; /* *< length of 1 / (Q % P),should be half of u16NLen */ +} drv_pke_rsa_priv_key_t; + +/* * struct of RSA public key */ +typedef struct { + crypto_compat_addr n; /* point to public modulus */ + crypto_compat_addr e; /* point to public exponent */ + td_u16 len; /* length of public modulus, max value is 512Byte */ +} drv_pke_rsa_pub_key_t; + +typedef struct { + drv_pke_data_t a; + drv_pke_data_t p; + drv_pke_data_t c; +} pke_mod_ctl_t; + +typedef struct { + drv_pke_data_t n; + drv_pke_data_t k; + drv_pke_data_t in; + drv_pke_data_t out; +} pke_exp_mod_ctl_t; + +typedef struct { + drv_pke_data_t input_e; + drv_pke_rsa_priv_key_t priv_key; +} pke_rsa_gen_key_ctl_t; + +typedef struct { + drv_pke_rsa_priv_key_t priv_key; + drv_pke_rsa_scheme scheme; + drv_pke_hash_type hash_type; + drv_pke_data_t input_hash; + drv_pke_data_t sig; +} pke_rsa_sign_ctl_t; + +typedef struct { + drv_pke_rsa_pub_key_t pub_key; + drv_pke_rsa_scheme scheme; + drv_pke_hash_type hash_type; + drv_pke_data_t input_hash; + drv_pke_data_t sig; + drv_pke_data_t output_hash; +} pke_rsa_verify_ctl_t; + +typedef struct { + drv_pke_rsa_scheme scheme; + drv_pke_hash_type hash_type; + drv_pke_rsa_pub_key_t pub_key; + drv_pke_data_t input; + drv_pke_data_t label; + drv_pke_data_t output; +} pke_rsa_pub_crypto_ctl_t; + +typedef struct { + drv_pke_rsa_scheme scheme; + drv_pke_hash_type hash_type; + drv_pke_rsa_priv_key_t priv_key; + drv_pke_data_t input; + drv_pke_data_t label; + drv_pke_data_t output; +} pke_rsa_priv_crypto_ctl_t; + + +#define HASH_BLOCK_SIZE 64 + +#define CRYPTO_IO(nr) CRYPTO_IOC(CRYPTO_IOC_NA, SOC_ID_CIPHER, (nr), 0) +#define CRYPTO_IOR(nr, size) CRYPTO_IOC(CRYPTO_IOC_R, SOC_ID_CIPHER, (nr), size) +#define CRYPTO_IOW(nr, size) CRYPTO_IOC(CRYPTO_IOC_W, SOC_ID_CIPHER, (nr), size) +#define CRYPTO_IOWR(nr, size) CRYPTO_IOC(CRYPTO_IOC_RW, SOC_ID_CIPHER, (nr), size) + +enum { + /* Hash. */ + CRYPTO_CMD_HASH_INIT_NR = 0x0, + CRYPTO_CMD_HASH_DEINIT_NR, + CRYPTO_CMD_HASH_START_NR, + CRYPTO_CMD_HASH_UPDATE_NR, + CRYPTO_CMD_HASH_FINISH_NR, + CRYPTO_CMD_HASH_GET_NR, + CRYPTO_CMD_HASH_SET_NR, + CRYPTO_CMD_HASH_DESTROY_NR, + CRYPTO_CMD_PBKDF2_NR, + CRYPTO_CMD_TRNG_GET_RANDOM_NR, + CRYPTO_CMD_TRNG_GET_MULTI_RANDOM_NR, + + /* Cipher. */ + CRYPTO_CMD_CIPHER_INIT_NR, + CRYPTO_CMD_CIPHER_DEINIT_NR, + CRYPTO_CMD_CIPHER_CREATE_NR, + CRYPTO_CMD_CIPHER_DESTROY_NR, + CRYPTO_CMD_CIPHER_SET_CONFIG_NR, + CRYPTO_CMD_CIPHER_GET_CONFIG_NR, + CRYPTO_CMD_CIPHER_ATTACH_NR, + CRYPTO_CMD_CIPHER_ENCRYPT_NR, + CRYPTO_CMD_CIPHER_DECRYPT_NR, + CRYPTO_CMD_CIPHER_ENCRYPT_MULTI_NR, + CRYPTO_CMD_CIPHER_DECRYPT_MULTI_NR, + CRYPTO_CMD_CIPHER_GET_TAG_NR, + CRYPTO_CMD_CIPHER_MAC_START_NR, + CRYPTO_CMD_CIPHER_MAC_UPDATE_NR, + CRYPTO_CMD_CIPHER_MAC_FINISH_NR, + + /* PKE. ECC */ + CRYPTO_CMD_PKE_ECC_GEN_KEY_NR, + CRYPTO_CMD_PKE_ECC_GEN_ECDH_KEY_NR, + CRYPTO_CMD_PKE_ECDSA_SIGN_NR, + CRYPTO_CMD_PKE_ECDSA_VERIFY_NR, + CRYPTO_CMD_PKE_EDDSA_SIGN_NR, + CRYPTO_CMD_PKE_EDDSA_VERIFY_NR, + CRYPTO_CMD_PKE_CHECK_DOT_ON_CURVE_NR, + CRYPTO_CMD_PKE_SM2_DSA_HASH_NR, + CRYPTO_CMD_PKE_SM2_PUBLIC_ENCRYPT_NR, + CRYPTO_CMD_PKE_SM2_PRIVATE_DECRYPT_NR, + /* PKE. BIGNUM */ + CRYPTO_CMD_PKE_MOD_NR, + CRYPTO_CMD_PKE_EXP_MOD_NR, + /* PKE. RSA. */ + CRYPTO_CMD_PKE_RSA_SIGN_NR, + CRYPTO_CMD_PKE_RSA_VERIFY_NR, + CRYPTO_CMD_PKE_RSA_PUBLIC_ENCRYPT_NR, + CRYPTO_CMD_PKE_RSA_PRIVATE_DECRYPT_NR, + + CRYPTO_CMD_COUNT +}; + +#define CRYPTO_CMD_HASH_INIT CRYPTO_IO(CRYPTO_CMD_HASH_INIT_NR) +#define CRYPTO_CMD_HASH_DEINIT CRYPTO_IO(CRYPTO_CMD_HASH_DEINIT_NR) +#define CRYPTO_CMD_HASH_START CRYPTO_IOWR(CRYPTO_CMD_HASH_START_NR, sizeof(hash_start_ctl_t)) +#define CRYPTO_CMD_HASH_UPDATE CRYPTO_IOWR(CRYPTO_CMD_HASH_UPDATE_NR, sizeof(hash_update_ctl_t)) +#define CRYPTO_CMD_HASH_FINISH CRYPTO_IOWR(CRYPTO_CMD_HASH_FINISH_NR, sizeof(hash_finish_ctl_t)) +#define CRYPTO_CMD_HASH_GET CRYPTO_IOWR(CRYPTO_CMD_HASH_GET_NR, sizeof(hash_clone_ctl_t)) +#define CRYPTO_CMD_HASH_SET CRYPTO_IOWR(CRYPTO_CMD_HASH_SET_NR, sizeof(hash_clone_ctl_t)) +#define CRYPTO_CMD_HASH_DESTROY CRYPTO_IOWR(CRYPTO_CMD_HASH_DESTROY_NR, sizeof(hash_handle_ctl_t)) +#define CRYPTO_CMD_PBKDF2 CRYPTO_IOWR(CRYPTO_CMD_PBKDF2_NR, sizeof(pbkdf2_ctl_t)) +#define CRYPTO_CMD_TRNG_GET_RANDOM CRYPTO_IOWR(CRYPTO_CMD_TRNG_GET_RANDOM_NR, sizeof(trng_ctl_t)) +#define CRYPTO_CMD_TRNG_GET_MULTI_RANDOM CRYPTO_IOWR(CRYPTO_CMD_TRNG_GET_MULTI_RANDOM_NR, sizeof(trng_multi_ctl_t)) + +#define CRYPTO_CMD_SYMC_INIT CRYPTO_IO(CRYPTO_CMD_CIPHER_INIT_NR) +#define CRYPTO_CMD_SYMC_DEINIT CRYPTO_IO(CRYPTO_CMD_CIPHER_DEINIT_NR) +#define CRYPTO_CMD_SYMC_CREATE CRYPTO_IOWR(CRYPTO_CMD_CIPHER_CREATE_NR, sizeof(symc_create_t)) +#define CRYPTO_CMD_SYMC_DESTROY CRYPTO_IOWR(CRYPTO_CMD_CIPHER_DESTROY_NR, sizeof(symc_destroy_t)) +#define CRYPTO_CMD_SYMC_SET_CONFIG CRYPTO_IOWR(CRYPTO_CMD_CIPHER_SET_CONFIG_NR, sizeof(symc_config_t)) +#define CRYPTO_CMD_SYMC_GET_CONFIG CRYPTO_IOWR(CRYPTO_CMD_CIPHER_GET_CONFIG_NR, sizeof(symc_config_t)) +#define CRYPTO_CMD_SYMC_ATTACH CRYPTO_IOWR(CRYPTO_CMD_CIPHER_ATTACH_NR, sizeof(symc_attach_t)) +#define CRYPTO_CMD_SYMC_ENCRYPT CRYPTO_IOWR(CRYPTO_CMD_CIPHER_ENCRYPT_NR, sizeof(symc_crypto_t)) +#define CRYPTO_CMD_SYMC_DECRYPT CRYPTO_IOWR(CRYPTO_CMD_CIPHER_DECRYPT_NR, sizeof(symc_crypto_t)) +#define CRYPTO_CMD_SYMC_ENCRYPT_MULTI \ + CRYPTO_IOWR(CRYPTO_CMD_CIPHER_ENCRYPT_MULTI_NR, sizeof(crypto_symc_multi_t)) +#define CRYPTO_CMD_SYMC_DECRYPT_MULTI \ + CRYPTO_IOWR(CRYPTO_CMD_CIPHER_DECRYPT_MULTI_NR, sizeof(crypto_symc_multi_t)) + +#define CRYPTO_CMD_SYMC_GET_TAG CRYPTO_IOWR(CRYPTO_CMD_CIPHER_GET_TAG_NR, sizeof(symc_get_tag_t)) +#define CRYPTO_CMD_SYMC_MAC_START CRYPTO_IOWR(CRYPTO_CMD_CIPHER_MAC_START_NR, sizeof(symc_mac_start_t)) +#define CRYPTO_CMD_SYMC_MAC_UPDATE CRYPTO_IOWR(CRYPTO_CMD_CIPHER_MAC_UPDATE_NR, sizeof(symc_mac_update_t)) +#define CRYPTO_CMD_SYMC_MAC_FINISH CRYPTO_IOWR(CRYPTO_CMD_CIPHER_MAC_FINISH_NR, sizeof(symc_mac_finish_t)) + +#define CRYPTO_CMD_PKE_MOD CRYPTO_IOWR(CRYPTO_CMD_PKE_MOD_NR, sizeof(pke_mod_ctl_t)) +#define CRYPTO_CMD_PKE_EXP_MOD CRYPTO_IOWR(CRYPTO_CMD_PKE_EXP_MOD_NR, sizeof(pke_exp_mod_ctl_t)) + +#define CRYPTO_CMD_PKE_ECC_GEN_KEY \ + CRYPTO_IOWR(CRYPTO_CMD_PKE_ECC_GEN_KEY_NR, sizeof(pke_ecc_gen_key_ctl_t)) +#define CRYPTO_CMD_PKE_ECC_GEN_ECDH_KEY \ + CRYPTO_IOWR(CRYPTO_CMD_PKE_ECC_GEN_ECDH_KEY_NR, sizeof(pke_ecc_gen_ecdh_key_ctl_t)) +#define CRYPTO_CMD_PKE_ECDSA_SIGN \ + CRYPTO_IOWR(CRYPTO_CMD_PKE_ECDSA_SIGN_NR, sizeof(pke_ecdsa_sign_ctl_t)) +#define CRYPTO_CMD_PKE_ECDSA_VERIFY \ + CRYPTO_IOWR(CRYPTO_CMD_PKE_ECDSA_VERIFY_NR, sizeof(pke_ecdsa_verify_ctl_t)) +#define CRYPTO_CMD_PKE_EDDSA_SIGN \ + CRYPTO_IOWR(CRYPTO_CMD_PKE_EDDSA_SIGN_NR, sizeof(pke_eddsa_sign_ctl_t)) +#define CRYPTO_CMD_PKE_EDDSA_VERIFY \ + CRYPTO_IOWR(CRYPTO_CMD_PKE_EDDSA_VERIFY_NR, sizeof(pke_eddsa_verify_ctl_t)) +#define CRYPTO_CMD_PKE_CHECK_DOT_ON_CURVE \ + CRYPTO_IOWR(CRYPTO_CMD_PKE_CHECK_DOT_ON_CURVE_NR, sizeof(pke_check_dot_on_curve_ctl_t)) +#define CRYPTO_CMD_PKE_SM2_DSA_HASH \ + CRYPTO_IOWR(CRYPTO_CMD_PKE_SM2_DSA_HASH_NR, sizeof(pke_sm2_dsa_hash_ctl_t)) +#define CRYPTO_CMD_PKE_SM2_PUBLIC_ENCRYPT \ + CRYPTO_IOWR(CRYPTO_CMD_PKE_SM2_PUBLIC_ENCRYPT_NR, sizeof(pke_sm2_public_encrypt_ctl_t)) +#define CRYPTO_CMD_PKE_SM2_PRIVATE_DECRYPT \ + CRYPTO_IOWR(CRYPTO_CMD_PKE_SM2_PRIVATE_DECRYPT_NR, sizeof(pke_sm2_private_decrypt_ctl_t)) + +#define CRYPTO_CMD_PKE_RSA_SIGN \ + CRYPTO_IOWR(CRYPTO_CMD_PKE_RSA_SIGN_NR, sizeof(pke_rsa_sign_ctl_t)) +#define CRYPTO_CMD_PKE_RSA_VERIFY \ + CRYPTO_IOWR(CRYPTO_CMD_PKE_RSA_VERIFY_NR, sizeof(pke_rsa_verify_ctl_t)) +#define CRYPTO_CMD_PKE_RSA_PUBLIC_ENCRYPT \ + CRYPTO_IOWR(CRYPTO_CMD_PKE_RSA_PUBLIC_ENCRYPT_NR, sizeof(pke_rsa_pub_crypto_ctl_t)) +#define CRYPTO_CMD_PKE_RSA_PRIVATE_DECRYPT \ + CRYPTO_IOWR(CRYPTO_CMD_PKE_RSA_PRIVATE_DECRYPT_NR, sizeof(pke_rsa_priv_crypto_ctl_t)) + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* End of #ifndef CRYPTO_IOCTL_CMD_H */ diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/ioctl_include/ioctl_km.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/ioctl_include/ioctl_km.h new file mode 100644 index 00000000..00794bae --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/ioctl_include/ioctl_km.h @@ -0,0 +1,101 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef OT_KM_IOCTL_CMD_H +#define OT_KM_IOCTL_CMD_H +#include "crypto_ioctl.h" +#include "crypto_common_struct.h" +#include "crypto_km_struct.h" + +#define IOC_TYPE_KM 'n' + +typedef enum { + /* Keyslot. */ + KM_KEYSLOT_IOC_NR_CREATE_HANDLE, + KM_KEYSLOT_IOC_NR_DESTROY_HANDLE, + /* Klad. */ + KM_KLAD_IOC_NR_CREATE_HANDLE, + KM_KLAD_IOC_NR_DESTROY_HANDLE, + KM_KLAD_IOC_NR_ATTACH, + KM_KLAD_IOC_NR_DETACH, + KM_KLAD_IOC_NR_SET_ATTR, + KM_KLAD_IOC_NR_GET_ATTR, + KM_KLAD_IOC_NR_SET_SESSION_KEY, + KM_KLAD_IOC_NR_SET_CONTENT_KEY, + KM_KLAD_IOC_NR_SET_CLEAR_KEY, + /* kdf. */ + KM_KDF_IOC_NR_PBKDF2, + KM_IOC_NR_BUTT, +} km_ioc_nr; + +/* Keyslot. */ +typedef struct { + crypto_handle kapi_keyslot_handle; + km_keyslot_type keyslot_type; +} keyslot_create_ctl_t; + +typedef struct { + crypto_handle kapi_keyslot_handle; +} keyslot_destroy_ctl_t; + +/* Klad. */ +typedef struct { + crypto_handle kapi_klad_handle; +} klad_handle_ctl_t; + +typedef struct { + crypto_handle kapi_klad_handle; + km_klad_dest_type klad_type; + crypto_handle kapi_keyslot_handle; +} klad_attach_ctl_t; + +typedef struct klad_attr_ctl { + crypto_handle kapi_klad_handle; + km_klad_attr attr; +} klad_attr_ctl_t; + +typedef struct klad_set_session_key_ctl { + crypto_handle kapi_klad_handle; + km_klad_level level; + km_klad_alg_type alg; + td_u32 key_size; + crypto_compat_addr key; +} klad_set_session_key_ctl_t; + +typedef struct klad_set_content_key_ctl { + crypto_handle kapi_klad_handle; + km_klad_alg_type alg; + km_klad_key_parity key_parity; + td_u32 key_size; + crypto_compat_addr key; +} klad_set_content_key_ctl_t; + +typedef struct klad_set_clear_key_ctl { + crypto_handle kapi_klad_handle; + km_klad_hmac_type hmac_type; + km_klad_key_parity key_parity; + td_u32 key_size; + crypto_compat_addr key; +} klad_set_clear_key_ctl_t; + +#define KM_IOWR(nr, struct_name) CRYPTO_IOC(CRYPTO_IOC_RW, IOC_TYPE_KM, (nr), sizeof(struct_name)) + +/* Keyslot. */ +#define CMD_KEYSLOT_CREATE_HANDLE KM_IOWR(KM_KEYSLOT_IOC_NR_CREATE_HANDLE, keyslot_create_ctl_t) +#define CMD_KEYSLOT_DESTROY_HANDLE KM_IOWR(KM_KEYSLOT_IOC_NR_DESTROY_HANDLE, keyslot_destroy_ctl_t) + +/* Klad. */ +#define CMD_KLAD_CREATE_HANDLE KM_IOWR(KM_KLAD_IOC_NR_CREATE_HANDLE, klad_handle_ctl_t) +#define CMD_KLAD_DESTROY_HANDLE KM_IOWR(KM_KLAD_IOC_NR_DESTROY_HANDLE, klad_handle_ctl_t) +#define CMD_KLAD_ATTACH KM_IOWR(KM_KLAD_IOC_NR_ATTACH, klad_attach_ctl_t) +#define CMD_KLAD_DETACH KM_IOWR(KM_KLAD_IOC_NR_DETACH, klad_attach_ctl_t) +#define CMD_KLAD_SET_ATTR KM_IOWR(KM_KLAD_IOC_NR_SET_ATTR, klad_attr_ctl_t) +#define CMD_KLAD_GET_ATTR KM_IOWR(KM_KLAD_IOC_NR_GET_ATTR, klad_attr_ctl_t) +#define CMD_KLAD_SET_SESSION_KEY KM_IOWR(KM_KLAD_IOC_NR_SET_SESSION_KEY, klad_set_session_key_ctl_t) +#define CMD_KLAD_SET_CONTENT_KEY KM_IOWR(KM_KLAD_IOC_NR_SET_CONTENT_KEY, klad_set_content_key_ctl_t) +#define CMD_KLAD_SET_CLEAR_KEY KM_IOWR(KM_KLAD_IOC_NR_SET_CLEAR_KEY, klad_set_clear_key_ctl_t) + +#define CMD_KM_MAX_NUM KM_IOC_NR_BUTT + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/ioctl_include/ioctl_otp.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/ioctl_include/ioctl_otp.h new file mode 100644 index 00000000..6e169cd9 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/ioctl_include/ioctl_otp.h @@ -0,0 +1,39 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef IOCTL_CMD_OTP_H +#define IOCTL_CMD_OTP_H + +#include "crypto_ioctl.h" +#include "ot_type.h" + +#define IOC_TYPE_OTP 'm' + +typedef enum { + /* OTP. */ + OTP_IOC_NR_READ_WORD, + OTP_IOC_NR_READ_BYTE, + OTP_IOC_NR_WRITE_BYTE, + OTP_IOC_NR_BUTT, +} otp_ioc_nr; + +typedef struct { + td_u32 addr; + td_u32 word; +} otp_word_ctl_t; + +typedef struct { + td_u32 addr; + td_u8 byte; +} otp_byte_ctl_t; + +#define OTP_IOWR(nr, struct_name) CRYPTO_IOC(CRYPTO_IOC_RW, IOC_TYPE_OTP, (nr), sizeof(struct_name)) + +#define CMD_OTP_READ_WORD OTP_IOWR(OTP_IOC_NR_READ_WORD, otp_word_ctl_t) +#define CMD_OTP_READ_BYTE OTP_IOWR(OTP_IOC_NR_READ_BYTE, otp_byte_ctl_t) +#define CMD_OTP_WRITE_BYTE OTP_IOWR(OTP_IOC_NR_WRITE_BYTE, otp_byte_ctl_t) + +#define CMD_OTP_MAX_NUM OTP_IOC_NR_BUTT + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/kapi_include/kapi_hash.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/kapi_include/kapi_hash.h new file mode 100644 index 00000000..afbc1fa6 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/kapi_include/kapi_hash.h @@ -0,0 +1,54 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef KAPI_HASH_H +#define KAPI_HASH_H + +#include "crypto_type.h" +#include "crypto_hash_struct.h" +#include "crypto_kdf_struct.h" +#include "crypto_drv_common.h" + +#define CRYPTO_HASH_VIRT_CHN_NUM 32 +#define MAX_PROCESS_NUM 10 + +typedef struct { + td_u32 tid; + td_bool is_open; + td_bool is_long_term; + td_handle drv_hash_handle; + crypto_hash_clone_ctx hash_clone_ctx; +} crypto_kapi_hash_ctx; + +typedef struct { + td_u32 pid; + crypto_owner owner; + crypto_kapi_hash_ctx hash_ctx_list[CRYPTO_HASH_VIRT_CHN_NUM]; + crypto_mutex hash_ctx_mutex[CRYPTO_HASH_VIRT_CHN_NUM]; + td_u32 ctx_num; + td_u32 init_counter; + td_bool is_used; +} crypto_kapi_hash_process; + +td_void kapi_cipher_hash_process_release(td_void); + +td_s32 kapi_cipher_hash_init(td_void); + +td_s32 kapi_cipher_hash_deinit(td_void); + +td_s32 kapi_cipher_hash_start(td_handle *kapi_hash_handle, const crypto_hash_attr *hash_attr); + +td_s32 kapi_cipher_hash_update(td_handle kapi_hash_handle, const crypto_buf_attr *src_buf, const td_u32 len); + +td_s32 kapi_cipher_hash_finish(td_handle kapi_hash_handle, td_u8 *out, td_u32 *out_len); + +td_s32 kapi_cipher_hash_get(td_handle kapi_hash_handle, crypto_hash_clone_ctx *hash_clone_ctx); + +td_s32 kapi_cipher_hash_set(td_handle kapi_hash_handle, const crypto_hash_clone_ctx *hash_clone_ctx); + +td_s32 kapi_cipher_hash_destroy(td_handle kapi_hash_handle); + +td_s32 kapi_cipher_pbkdf2(const crypto_kdf_pbkdf2_param *param, td_u8 *out, const td_u32 out_len); + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/kapi_include/kapi_km.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/kapi_include/kapi_km.h new file mode 100644 index 00000000..3af39e6b --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/kapi_include/kapi_km.h @@ -0,0 +1,36 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef KAPI_KM_H +#define KAPI_KM_H + +#include "crypto_km_struct.h" + +td_s32 kapi_km_env_init(td_void); +td_s32 kapi_km_env_deinit(td_void); +td_s32 kapi_km_deinit(td_void); + +/* Keyslot. */ +td_s32 kapi_keyslot_create(td_handle *kapi_keyslot_handle, km_keyslot_type keyslot_type); +td_s32 kapi_keyslot_destroy(td_handle kapi_keyslot_handle); +td_void kapi_keyslot_release_process(td_void); + +/* Klad. */ +td_s32 kapi_klad_create(td_handle *kapi_klad_handle); +td_s32 kapi_klad_destroy(td_handle kapi_klad_handle); + +td_s32 kapi_klad_attach(td_handle kapi_klad_handle, km_klad_dest_type klad_type, + td_handle kapi_keyslot_handle); +td_s32 kapi_klad_detach(td_handle kapi_klad_handle, km_klad_dest_type klad_type, + td_handle kapi_keyslot_handle); + +td_s32 kapi_klad_set_attr(td_handle kapi_klad_handle, const km_klad_attr *attr); +td_s32 kapi_klad_get_attr(td_handle kapi_klad_handle, km_klad_attr *attr); + +td_s32 kapi_klad_set_session_key(td_handle kapi_klad_handle, const km_klad_session_key *key); +td_s32 kapi_klad_set_content_key(td_handle kapi_klad_handle, const km_klad_content_key *key); + +td_s32 kapi_klad_set_clear_key(td_handle kapi_klad_handle, const km_klad_clear_key *key); + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/kapi_include/kapi_otp.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/kapi_include/kapi_otp.h new file mode 100644 index 00000000..04cd5bc8 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/kapi_include/kapi_otp.h @@ -0,0 +1,20 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef KAPI_OTP_H +#define KAPI_OTP_H + +#include "ot_type.h" + +td_s32 kapi_otp_init(td_void); + +td_s32 kapi_otp_deinit(td_void); + +td_s32 kapi_otp_read_word(td_u32 addr, td_u32 *data); + +td_s32 kapi_otp_read_byte(td_u32 addr, td_u8 *data); + +td_s32 kapi_otp_write_byte(td_u32 addr, td_u8 data); + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/kapi_include/kapi_pke.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/kapi_include/kapi_pke.h new file mode 100644 index 00000000..a0d685d5 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/kapi_include/kapi_pke.h @@ -0,0 +1,62 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef KAPI_PKE_H +#define KAPI_PKE_H + +#include "crypto_type.h" +#include "crypto_pke_struct.h" + +td_s32 kapi_cipher_pke_mod(const drv_pke_data *a, const drv_pke_data *p, const drv_pke_data *c); + +td_s32 kapi_cipher_pke_exp_mod(const drv_pke_data *n, const drv_pke_data *k, + const drv_pke_data *in, const drv_pke_data *out); + +td_s32 kapi_pke_ecc_gen_key(drv_pke_ecc_curve_type curve_type, const drv_pke_data *input_priv_key, + const drv_pke_data *output_priv_key, const drv_pke_ecc_point *output_pub_key); + +td_s32 kapi_pke_ecdsa_sign(drv_pke_ecc_curve_type curve_type, const drv_pke_data *priv_key, + const drv_pke_data *hash, const drv_pke_ecc_sig *sig); + +td_s32 kapi_pke_ecdsa_verify(drv_pke_ecc_curve_type curve_type, const drv_pke_ecc_point *pub_key, + const drv_pke_data *hash, const drv_pke_ecc_sig *sig); + +td_s32 kapi_pke_eddsa_sign(drv_pke_ecc_curve_type curve_type, const drv_pke_data *priv_key, + const drv_pke_msg *msg, const drv_pke_ecc_sig *sig); + +td_s32 kapi_pke_eddsa_verify(drv_pke_ecc_curve_type curve_type, const drv_pke_ecc_point *pub_key, + const drv_pke_msg *msg, const drv_pke_ecc_sig *sig); + +td_s32 kapi_pke_ecc_gen_ecdh_key(drv_pke_ecc_curve_type curve_type, const drv_pke_ecc_point *input_pub_key, + const drv_pke_data *input_priv_key, const drv_pke_data *output_shared_key); + +td_s32 kapi_pke_check_dot_on_curve(drv_pke_ecc_curve_type curve_type, const drv_pke_ecc_point *pub_key, + td_bool *is_on_curve); + +td_s32 kapi_pke_sm2_dsa_hash(const drv_pke_data *sm2_id, const drv_pke_ecc_point *pub_key, + const drv_pke_msg *msg, drv_pke_data *hash); + +td_s32 kapi_pke_sm2_public_encrypt(const drv_pke_ecc_point *pub_key, const drv_pke_data *plain_text, + drv_pke_data *cipher_text); + +td_s32 kapi_pke_sm2_private_decrypt(const drv_pke_data *priv_key, const drv_pke_data *cipher_text, + drv_pke_data *plain_text); + +/* RSA. */ +td_s32 kapi_pke_rsa_sign(const drv_pke_rsa_priv_key *priv_key, drv_pke_rsa_scheme scheme, + drv_pke_hash_type hash_type, const drv_pke_data *input_hash, + drv_pke_data *sign); + +td_s32 kapi_pke_rsa_verify(const drv_pke_rsa_pub_key *pub_key, drv_pke_rsa_scheme scheme, + drv_pke_hash_type hash_type, drv_pke_data *input_hash, const drv_pke_data *sig); + +td_s32 kapi_pke_rsa_public_encrypt(drv_pke_rsa_scheme scheme, drv_pke_hash_type hash_type, + const drv_pke_rsa_pub_key *pub_key, const drv_pke_data *input, const drv_pke_data *label, + drv_pke_data *output); + +td_s32 kapi_pke_rsa_private_decrypt(drv_pke_rsa_scheme scheme, drv_pke_hash_type hash_type, + const drv_pke_rsa_priv_key *priv_key, const drv_pke_data *input, const drv_pke_data *label, + drv_pke_data *output); + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/kapi_include/kapi_symc.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/kapi_include/kapi_symc.h new file mode 100644 index 00000000..df2085cc --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/kapi_include/kapi_symc.h @@ -0,0 +1,50 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef KAPI_SYMC_H +#define KAPI_SYMC_H + +#include "crypto_type.h" +#include "crypto_symc_struct.h" + +#define CRYPTO_SYMC_VIRT_CHN_NUM 32 +#define MAX_PROCESS_NUM 10 + +td_void kapi_cipher_symc_process_release(td_void); + +td_s32 kapi_cipher_symc_init(td_void); + +td_s32 kapi_cipher_symc_deinit(td_void); + +td_s32 kapi_cipher_symc_create(td_handle *kapi_symc_handle, const crypto_symc_attr *symc_attr); + +td_s32 kapi_cipher_symc_destroy(td_handle kapi_symc_handle); + +td_s32 kapi_cipher_symc_set_config(td_handle kapi_symc_handle, const crypto_symc_ctrl_t *symc_ctrl); + +td_s32 kapi_cipher_symc_get_config(td_handle kapi_symc_handle, crypto_symc_ctrl_t *symc_ctrl); + +td_s32 kapi_cipher_symc_attach(td_handle kapi_symc_handle, td_handle keyslot_handle); + +td_s32 kapi_cipher_symc_encrypt(td_handle kapi_symc_handle, const crypto_buf_attr *src_buf, + const crypto_buf_attr *dst_buf, td_u32 length); + +td_s32 kapi_cipher_symc_decrypt(td_handle kapi_symc_handle, const crypto_buf_attr *src_buf, + const crypto_buf_attr *dst_buf, td_u32 length); + +td_s32 kapi_cipher_symc_encrypt_multi(td_handle kapi_symc_handle, const crypto_symc_ctrl_t *symc_ctrl, + const crypto_symc_pack *src_buf_pack, const crypto_symc_pack *dst_buf_pack, td_u32 pack_num); + +td_s32 kapi_cipher_symc_decrypt_multi(td_handle kapi_symc_handle, const crypto_symc_ctrl_t *symc_ctrl, + const crypto_symc_pack *src_buf_pack, const crypto_symc_pack *dst_buf_pack, td_u32 pack_num); + +td_s32 kapi_cipher_symc_get_tag(td_handle kapi_symc_handle, td_u8 *tag, td_u32 tag_length); + +td_s32 kapi_cipher_mac_start(td_handle *kapi_symc_handle, const crypto_symc_mac_attr *mac_attr); + +td_s32 kapi_cipher_mac_update(td_handle kapi_symc_handle, const crypto_buf_attr *src_buf, td_u32 length); + +td_s32 kapi_cipher_mac_finish(td_handle kapi_symc_handle, td_u8 *mac, td_u32 *mac_length); + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/kapi_include/kapi_trng.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/kapi_include/kapi_trng.h new file mode 100644 index 00000000..fd8dbcdc --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/kapi_include/kapi_trng.h @@ -0,0 +1,14 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef KAPI_TRNG_H +#define KAPI_TRNG_H + +#include "crypto_type.h" + +td_s32 kapi_cipher_trng_get_random(td_u32 *randnum); + +td_s32 kapi_cipher_trng_get_multi_random(td_u32 size, td_u8 *randnum); + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/uapi_include/uapi_hash.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/uapi_include/uapi_hash.h new file mode 100644 index 00000000..1d49ebe9 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/uapi_include/uapi_hash.h @@ -0,0 +1,27 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef UAPI_HASH_H +#define UAPI_HASH_H + +#include "crypto_type.h" +#include "crypto_hash_struct.h" + +td_s32 unify_uapi_cipher_hash_init(td_void); + +td_s32 unify_uapi_cipher_hash_deinit(td_void); + +td_s32 unify_uapi_cipher_hash_start(td_handle *uapi_hash_handle, const crypto_hash_attr *hash_attr); + +td_s32 unify_uapi_cipher_hash_update(td_handle uapi_hash_handle, const crypto_buf_attr *src_buf, const td_u32 len); + +td_s32 unify_uapi_cipher_hash_finish(td_handle uapi_hash_handle, td_u8 *out, td_u32 *out_len); + +td_s32 unify_uapi_cipher_hash_get(td_handle uapi_hash_handle, crypto_hash_clone_ctx *hash_clone_ctx); + +td_s32 unify_uapi_cipher_hash_set(td_handle uapi_hash_handle, const crypto_hash_clone_ctx *hash_clone_ctx); + +td_s32 unify_uapi_cipher_hash_destroy(td_handle uapi_hash_handle); + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/uapi_include/uapi_kdf.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/uapi_include/uapi_kdf.h new file mode 100644 index 00000000..15d269e1 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/uapi_include/uapi_kdf.h @@ -0,0 +1,13 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef UAPI_KDF_H +#define UAPI_KDF_H + +#include "crypto_type.h" +#include "crypto_kdf_struct.h" + +td_s32 unify_uapi_cipher_pbkdf2(const crypto_kdf_pbkdf2_param *param, td_u8 *out, const td_u32 out_len); + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/uapi_include/uapi_km.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/uapi_include/uapi_km.h new file mode 100644 index 00000000..461fab53 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/uapi_include/uapi_km.h @@ -0,0 +1,46 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef UAPI_KM_H +#define UAPI_KM_H + +#include "crypto_km_struct.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +td_s32 uapi_km_init(td_void); +td_s32 uapi_km_deinit(td_void); + +/* Keyslot. */ +td_s32 uapi_keyslot_create(crypto_handle *mpi_keyslot_handle, km_keyslot_type keyslot_type); +td_s32 uapi_keyslot_destroy(crypto_handle mpi_keyslot_handle); + +/* Klad. */ +td_s32 uapi_klad_create(crypto_handle *mpi_klad_handle); +td_s32 uapi_klad_destroy(crypto_handle mpi_klad_handle); + +td_s32 uapi_klad_attach(crypto_handle mpi_klad_handle, km_klad_dest_type klad_type, + crypto_handle mpi_keyslot_handle); +td_s32 uapi_klad_detach(crypto_handle mpi_klad_handle, km_klad_dest_type klad_type, + crypto_handle mpi_keyslot_handle); + +td_s32 uapi_klad_set_attr(crypto_handle mpi_klad_handle, const km_klad_attr *attr); +td_s32 uapi_klad_get_attr(crypto_handle mpi_klad_handle, km_klad_attr *attr); + +td_s32 uapi_klad_set_session_key(crypto_handle mpi_klad_handle, const km_klad_session_key *key); +td_s32 uapi_klad_set_content_key(crypto_handle mpi_klad_handle, const km_klad_content_key *key); + +td_s32 uapi_klad_set_clear_key(crypto_handle mpi_klad_handle, const km_klad_clear_key *key); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/uapi_include/uapi_otp.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/uapi_include/uapi_otp.h new file mode 100644 index 00000000..645c49a1 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/uapi_include/uapi_otp.h @@ -0,0 +1,32 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef UAPI_OTP_H +#define UAPI_OTP_H + +#include "ot_type.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +td_s32 uapi_otp_init(td_void); + +td_s32 uapi_otp_deinit(td_void); + +td_s32 uapi_otp_read_word(td_u32 offset, td_u32 *data); + +td_s32 uapi_otp_read_byte(td_u32 offset, td_u8 *data); + +td_s32 uapi_otp_write_byte(td_u32 offset, td_u8 data); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/uapi_include/uapi_pke.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/uapi_include/uapi_pke.h new file mode 100644 index 00000000..9b02032b --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/uapi_include/uapi_pke.h @@ -0,0 +1,68 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef UAPI_CIPHER_PKE_H +#define UAPI_CIPHER_PKE_H + +#include "crypto_type.h" +#include "crypto_pke_struct.h" + +td_s32 unify_uapi_cipher_pke_init(td_void); +td_s32 unify_uapi_cipher_pke_deinit(td_void); + +/* + * input_priv_key: Could be NULL. + */ +td_s32 unify_uapi_cipher_pke_ecc_gen_key(drv_pke_ecc_curve_type curve_type, const drv_pke_data *input_priv_key, + const drv_pke_data *output_priv_key, const drv_pke_ecc_point *output_pub_key); + +td_s32 unify_uapi_cipher_pke_ecc_gen_ecdh_key(drv_pke_ecc_curve_type curve_type, const drv_pke_ecc_point *input_pub_key, + const drv_pke_data *input_priv_key, const drv_pke_data *output_shared_key); + +td_s32 unify_uapi_cipher_pke_ecdsa_sign(drv_pke_ecc_curve_type curve_type, const drv_pke_data *priv_key, + const drv_pke_data *hash, const drv_pke_ecc_sig *sig); + +td_s32 unify_uapi_cipher_pke_ecdsa_verify(drv_pke_ecc_curve_type curve_type, const drv_pke_ecc_point *pub_key, + const drv_pke_data *hash, const drv_pke_ecc_sig *sig); + +td_s32 unify_uapi_cipher_pke_eddsa_sign(drv_pke_ecc_curve_type curve_type, const drv_pke_data *priv_key, + const drv_pke_msg *msg, const drv_pke_ecc_sig *sig); + +td_s32 unify_uapi_cipher_pke_eddsa_verify(drv_pke_ecc_curve_type curve_type, const drv_pke_ecc_point *pub_key, + const drv_pke_msg *msg, const drv_pke_ecc_sig *sig); + +td_s32 unify_uapi_cipher_pke_check_dot_on_curve(drv_pke_ecc_curve_type curve_type, const drv_pke_ecc_point *pub_key, + td_bool *is_on_curve); + +td_s32 unify_uapi_cipher_pke_sm2_dsa_hash(const drv_pke_data *sm2_id, const drv_pke_ecc_point *pub_key, + const drv_pke_msg *msg, drv_pke_data *hash); + +td_s32 unify_uapi_cipher_pke_sm2_public_encrypt(const drv_pke_ecc_point *pub_key, const drv_pke_data *plain_text, + drv_pke_data *cipher_text); + +td_s32 unify_uapi_cipher_pke_sm2_private_decrypt(const drv_pke_data *priv_key, const drv_pke_data *cipher_text, + drv_pke_data *plain_text); + +td_s32 unify_uapi_cipher_pke_mod(const drv_pke_data *a, const drv_pke_data *p, const drv_pke_data *c); + +td_s32 unify_uapi_cipher_pke_exp_mod(const drv_pke_data *n, const drv_pke_data *k, + const drv_pke_data *in, const drv_pke_data *out); + +/* RSA. */ +td_s32 unify_uapi_cipher_pke_rsa_sign(const drv_pke_rsa_priv_key *priv_key, drv_pke_rsa_scheme scheme, + drv_pke_hash_type hash_type, const drv_pke_data *input_hash, + drv_pke_data *sign); + +td_s32 unify_uapi_cipher_pke_rsa_verify(const drv_pke_rsa_pub_key *pub_key, drv_pke_rsa_scheme scheme, + drv_pke_hash_type hash_type, drv_pke_data *input_hash, const drv_pke_data *sig); + +td_s32 unify_uapi_cipher_pke_rsa_public_encrypt(drv_pke_rsa_scheme scheme, drv_pke_hash_type hash_type, + const drv_pke_rsa_pub_key *pub_key, const drv_pke_data *input, const drv_pke_data *label, + drv_pke_data *output); + +td_s32 unify_uapi_cipher_pke_rsa_private_decrypt(drv_pke_rsa_scheme scheme, drv_pke_hash_type hash_type, + const drv_pke_rsa_priv_key *priv_key, const drv_pke_data *input, const drv_pke_data *label, + drv_pke_data *output); + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/uapi_include/uapi_symc.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/uapi_include/uapi_symc.h new file mode 100644 index 00000000..665740e2 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/uapi_include/uapi_symc.h @@ -0,0 +1,45 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef UAPI_SYMC_H +#define UAPI_SYMC_H + +#include "crypto_type.h" +#include "crypto_symc_struct.h" + +td_s32 unify_uapi_cipher_symc_init(td_void); + +td_s32 unify_uapi_cipher_symc_deinit(td_void); + +td_s32 unify_uapi_cipher_symc_create(td_handle *symc_handle, const crypto_symc_attr *symc_attr); + +td_s32 unify_uapi_cipher_symc_destroy(td_handle symc_handle); + +td_s32 unify_uapi_cipher_symc_set_config(td_handle symc_handle, const crypto_symc_ctrl_t *symc_ctrl); + +td_s32 unify_uapi_cipher_symc_get_config(td_handle symc_handle, crypto_symc_ctrl_t *symc_ctrl); + +td_s32 unify_uapi_cipher_symc_attach(td_handle symc_handle, td_handle keyslot_handle); + +td_s32 unify_uapi_cipher_symc_encrypt(td_handle symc_handle, const crypto_buf_attr *src_buf, + const crypto_buf_attr *dst_buf, td_u32 length); + +td_s32 unify_uapi_cipher_symc_decrypt(td_handle symc_handle, const crypto_buf_attr *src_buf, + const crypto_buf_attr *dst_buf, td_u32 length); + +td_s32 unify_uapi_cipher_symc_encrypt_multi(td_handle symc_handle, const crypto_symc_ctrl_t *symc_ctrl, + const crypto_symc_pack *src_buf_pack, const crypto_symc_pack *dst_buf_pack, td_u32 pack_num); + +td_s32 unify_uapi_cipher_symc_decrypt_multi(td_handle symc_handle, const crypto_symc_ctrl_t *symc_ctrl, + const crypto_symc_pack *src_buf_pack, const crypto_symc_pack *dst_buf_pack, td_u32 pack_num); + +td_s32 unify_uapi_cipher_symc_get_tag(td_handle symc_handle, td_u8 *tag, td_u32 tag_length); + +td_s32 unify_uapi_cipher_mac_start(td_handle *symc_handle, const crypto_symc_mac_attr *mac_attr); + +td_s32 unify_uapi_cipher_mac_update(td_handle symc_handle, const crypto_buf_attr *src_buf, td_u32 length); + +td_s32 unify_uapi_cipher_mac_finish(td_handle symc_handle, td_u8 *mac, td_u32 *mac_length); + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/include/uapi_include/uapi_trng.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/uapi_include/uapi_trng.h new file mode 100644 index 00000000..0a095d00 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/include/uapi_include/uapi_trng.h @@ -0,0 +1,14 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef UAPI_TRNG_H +#define UAPI_TRNG_H + +#include "crypto_type.h" + +td_s32 unify_uapi_cipher_trng_get_random(td_u32 *randnum); + +td_s32 unify_uapi_cipher_trng_get_multi_random(td_u32 size, td_u8 *randnum); + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/kapi_code/kapi_hash.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/kapi_code/kapi_hash.c new file mode 100644 index 00000000..0a6c19c1 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/kapi_code/kapi_hash.c @@ -0,0 +1,595 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "kapi_hash.h" +#include "kapi_inner.h" +#include "drv_hash.h" +#include "crypto_common_macro.h" +#include "crypto_errno.h" +#include "crypto_drv_common.h" + +#define HASH_COMPAT_ERRNO(err_code) KAPI_COMPAT_ERRNO(ERROR_MODULE_HASH, err_code) + +#define CRYPTO_HASH_INIT_MAX_NUM 0xffffffff + +static crypto_kapi_hash_process g_kapi_hash_channel[MAX_PROCESS_NUM]; + +static crypto_mutex g_hash_mutex; + +#define kapi_hash_lock() do { \ + crypto_mutex_lock(&g_hash_mutex); \ +} while (0) +#define kapi_hash_unlock() do { \ + crypto_mutex_unlock(&g_hash_mutex); \ +} while (0) + +static td_s32 priv_hash_handle_check(td_handle kapi_hash_handle) +{ + crypto_chk_return(kapi_get_module_id(kapi_hash_handle) != KAPI_HASH_MODULE_ID, + HASH_COMPAT_ERRNO(ERROR_INVALID_HANDLE), "Invalid Hash Handle! 0x%x\n", kapi_hash_handle); + crypto_chk_return(kapi_get_ctx_idx(kapi_hash_handle) >= CRYPTO_HASH_VIRT_CHN_NUM, + HASH_COMPAT_ERRNO(ERROR_INVALID_HANDLE), "Invalid Hash Handle! 0x%x\n", kapi_hash_handle); + return TD_SUCCESS; +} + +static crypto_kapi_hash_process *priv_get_current_hash_channel(td_void) +{ + td_u32 i; + crypto_owner owner; + if (crypto_get_owner(&owner) != CRYPTO_SUCCESS) { + return TD_NULL; + } + for (i = 0; i < MAX_PROCESS_NUM; i++) { + if (memcmp(&owner, &g_kapi_hash_channel[i].owner, sizeof(crypto_owner)) == 0) { + return &g_kapi_hash_channel[i]; + } + } + return TD_NULL; +} + +static crypto_kapi_hash_ctx *priv_occupy_hash_soft_chn(crypto_kapi_hash_process *hash_channel, td_u32 *idx) +{ + td_u32 i; + td_u32 tid = crypto_gettid(); + crypto_kapi_hash_ctx *hash_ctx_list = TD_NULL; + crypto_kapi_hash_ctx *hash_ctx = TD_NULL; + + kapi_hash_lock(); + + hash_ctx_list = hash_channel->hash_ctx_list; + for (i = 0; i < CRYPTO_HASH_VIRT_CHN_NUM; i++) { + if (hash_ctx_list[i].is_open == TD_FALSE) { + break; + } + } + if (i >= CRYPTO_HASH_VIRT_CHN_NUM) { + crypto_log_err("All Hash Channels are busy!\n"); + goto exit_unlock; + } + hash_ctx = &hash_channel->hash_ctx_list[i]; + (td_void)memset_s(hash_ctx, sizeof(crypto_kapi_hash_ctx), 0, sizeof(crypto_kapi_hash_ctx)); + hash_ctx->is_open = TD_TRUE; + hash_ctx->tid = tid; + + *idx = i; + +exit_unlock: + kapi_hash_unlock(); + return hash_ctx; +} + +static td_void priv_release_hash_soft_chn(crypto_kapi_hash_ctx *hash_ctx) +{ + kapi_hash_lock(); + (td_void)memset_s(hash_ctx, sizeof(crypto_kapi_hash_ctx), 0, sizeof(crypto_kapi_hash_ctx)); + kapi_hash_unlock(); +} + +static td_bool priv_check_is_init(crypto_owner *owner) +{ + td_u32 i; + for (i = 0; i < MAX_PROCESS_NUM; i++) { + if (memcmp(owner, &g_kapi_hash_channel[i].owner, sizeof(crypto_owner)) == 0) { + return TD_TRUE; + } + } + return TD_FALSE; +} + +static td_s32 priv_process_hash_init(td_void) +{ + td_u32 i; + td_u32 ret = TD_SUCCESS; + crypto_owner owner; + crypto_kapi_hash_process *hash_channel = TD_NULL; + + crypto_kapi_func_enter(); + kapi_hash_lock(); + ret = crypto_get_owner(&owner); + crypto_chk_goto_with_ret(ret != CRYPTO_SUCCESS, exit_unlock, HASH_COMPAT_ERRNO(ERROR_GET_OWNER), + "crypto_get_owner failed\n"); + if (priv_check_is_init(&owner) == TD_TRUE) { + hash_channel = priv_get_current_hash_channel(); + if (hash_channel->init_counter >= CRYPTO_HASH_INIT_MAX_NUM) { + ret = HASH_COMPAT_ERRNO(ERROR_COUNT_OVERFLOW); + } else { + ret = TD_SUCCESS; + ++(hash_channel->init_counter); + } + goto exit_unlock; + } + for (i = 0; i < MAX_PROCESS_NUM; i++) { + if (g_kapi_hash_channel[i].is_used == TD_FALSE) { + break; + } + } + if (i >= MAX_PROCESS_NUM) { + crypto_log_err("Process Num is More Than %u\n", MAX_PROCESS_NUM); + ret = HASH_COMPAT_ERRNO(ERROR_MAX_PROCESS); + goto exit_unlock; + } + hash_channel = &g_kapi_hash_channel[i]; + (td_void)memset_s(hash_channel, sizeof(crypto_kapi_hash_process), 0, sizeof(crypto_kapi_hash_process)); + + for (i = 0; i < CRYPTO_HASH_VIRT_CHN_NUM; ++i) { + ret = crypto_mutex_init(&hash_channel->hash_ctx_mutex[i]); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, exit_destroy, HASH_COMPAT_ERRNO(ERROR_MUTEX_INIT), + "hash ctx mutex init failed at chn: %u\n", i); + } + (td_void)memcpy_s(&hash_channel->owner, sizeof(crypto_owner), &owner, sizeof(crypto_owner)); + hash_channel->is_used = TD_TRUE; + hash_channel->ctx_num = CRYPTO_HASH_VIRT_CHN_NUM; + ++(hash_channel->init_counter); + (td_void)memset_s(hash_channel->hash_ctx_list, sizeof(crypto_kapi_hash_ctx) * CRYPTO_HASH_VIRT_CHN_NUM, + 0, sizeof(crypto_kapi_hash_ctx) * CRYPTO_HASH_VIRT_CHN_NUM); + kapi_hash_unlock(); + + crypto_kapi_func_exit(); + return ret; + +exit_destroy: + for (i = 0; i < CRYPTO_HASH_VIRT_CHN_NUM; ++i) { + crypto_mutex_destroy(&hash_channel->hash_ctx_mutex[i]); + } +exit_unlock: + kapi_hash_unlock(); + crypto_kapi_func_exit(); + return ret; +} + +static td_void priv_process_release(crypto_kapi_hash_process *hash_channel) +{ + td_u32 i; + crypto_kapi_hash_ctx *hash_ctx_list = TD_NULL; + crypto_kapi_hash_ctx *hash_ctx = TD_NULL; + hash_ctx_list = hash_channel->hash_ctx_list; + for (i = 0; i < CRYPTO_HASH_VIRT_CHN_NUM; ++i) { + hash_ctx = &hash_ctx_list[i]; + crypto_mutex_destroy(&hash_channel->hash_ctx_mutex[i]); + if (hash_ctx->is_open == TD_TRUE && hash_ctx->is_long_term) { + drv_cipher_hash_destroy(hash_ctx->drv_hash_handle); + } + } + (td_void)memset_s(hash_channel, sizeof(crypto_kapi_hash_process), 0, sizeof(crypto_kapi_hash_process)); +} + +static td_void priv_process_hash_deinit(td_void) +{ + crypto_kapi_hash_process *hash_channel = TD_NULL; + crypto_kapi_func_enter(); + kapi_hash_lock(); + hash_channel = priv_get_current_hash_channel(); + if (hash_channel == TD_NULL) { + kapi_hash_unlock(); + return; + } + if (hash_channel->init_counter > 1) { + --(hash_channel->init_counter); + kapi_hash_unlock(); + return; + } + priv_process_release(hash_channel); + kapi_hash_unlock(); + crypto_kapi_func_exit(); +} + +static td_s32 priv_drv_lock_start(crypto_kapi_hash_ctx *hash_ctx, const crypto_hash_attr *hash_attr) +{ + td_s32 ret = TD_SUCCESS; + kapi_hash_lock(); + ret = drv_cipher_hash_start(&hash_ctx->drv_hash_handle, hash_attr); + kapi_hash_unlock(); + return ret; +} + +static td_s32 priv_drv_lock_finish(td_handle drv_hash_handle, td_u8 *out, td_u32 *out_len) +{ + td_s32 ret = TD_SUCCESS; + kapi_hash_lock(); + ret = drv_cipher_hash_finish(drv_hash_handle, out, out_len); + kapi_hash_unlock(); + return ret; +} + +static td_void priv_drv_lock_destroy(td_handle drv_hash_handle) +{ + kapi_hash_lock(); + (td_void)drv_cipher_hash_destroy(drv_hash_handle); + kapi_hash_unlock(); +} + +td_void kapi_cipher_hash_process_release(td_void) +{ + crypto_kapi_hash_process *hash_channel = TD_NULL; + crypto_kapi_func_enter(); + kapi_hash_lock(); + hash_channel = priv_get_current_hash_channel(); + if (hash_channel == TD_NULL) { + kapi_hash_unlock(); + return; + } + priv_process_release(hash_channel); + kapi_hash_unlock(); + crypto_kapi_func_exit(); +} + +td_s32 kapi_cipher_hash_env_init(td_void) +{ + td_s32 ret = TD_SUCCESS; + crypto_kapi_func_enter(); + + ret = drv_cipher_hash_init(); + if (ret != TD_SUCCESS) { + crypto_log_err("drv_cipher_hash_init failed\n"); + return ret; + } + + (td_void)memset_s(&g_kapi_hash_channel, sizeof(g_kapi_hash_channel), 0, sizeof(g_kapi_hash_channel)); + ret = crypto_mutex_init(&g_hash_mutex); + if (ret != TD_SUCCESS) { + crypto_log_err("crypto_mutex_init failed\n"); + ret = HASH_COMPAT_ERRNO(ERROR_MUTEX_INIT); + goto error_hash_deinit; + } + + crypto_kapi_func_exit(); + return ret; + +error_hash_deinit: + drv_cipher_hash_deinit(); + return ret; +} + +td_s32 kapi_cipher_hash_env_deinit(td_void) +{ + td_s32 ret = TD_SUCCESS; + td_u32 i, j; + crypto_kapi_hash_process *hash_channel = TD_NULL; + crypto_kapi_hash_ctx *hash_ctx = TD_NULL; + crypto_kapi_func_enter(); + + /* release all the resource. */ + for (i = 0; i < MAX_PROCESS_NUM; i++) { + hash_channel = &g_kapi_hash_channel[i]; + if (hash_channel->is_used == TD_FALSE) { + continue; + } + for (j = 0; j < CRYPTO_HASH_VIRT_CHN_NUM; j++) { + hash_ctx = &hash_channel->hash_ctx_list[j]; + if (hash_ctx->is_open == TD_FALSE) { + continue; + } + priv_release_hash_soft_chn(hash_ctx); + hash_ctx->is_open = TD_FALSE; + } + hash_channel->is_used = TD_FALSE; + } + crypto_mutex_destroy(&g_hash_mutex); + (td_void)memset_s(&g_kapi_hash_channel, sizeof(g_kapi_hash_channel), 0, sizeof(g_kapi_hash_channel)); + drv_cipher_hash_deinit(); + crypto_kapi_func_exit(); + return ret; +} + +td_s32 kapi_cipher_hash_init(td_void) +{ + td_s32 ret = TD_SUCCESS; + crypto_kapi_func_enter(); + + ret = priv_process_hash_init(); + if (ret != TD_SUCCESS) { + crypto_log_err("hash priv_process_hash_init failed\n"); + return ret; + } + + crypto_kapi_func_exit(); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_cipher_hash_init); + +td_s32 kapi_cipher_hash_deinit(td_void) +{ + crypto_kapi_func_enter(); + priv_process_hash_deinit(); + crypto_kapi_func_exit(); + return TD_SUCCESS; +} +CRYPTO_EXPORT_SYMBOL(kapi_cipher_hash_deinit); + +td_s32 kapi_cipher_hash_start(td_handle *kapi_hash_handle, const crypto_hash_attr *hash_attr) +{ + td_s32 ret = TD_SUCCESS; + crypto_kapi_hash_process *hash_channel = TD_NULL; + crypto_kapi_hash_ctx *hash_ctx = TD_NULL; + td_u32 idx = 0; + + crypto_kapi_func_enter(); + crypto_chk_return(kapi_hash_handle == TD_NULL, HASH_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), + "kapi_hash_handle is NULL\n"); + crypto_chk_return(hash_attr == TD_NULL, HASH_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "hash_attr is NULL\n"); + + if (CRYPTO_HASH_IS_HMAC(hash_attr->hash_type) == TD_TRUE) { + crypto_chk_return(hash_attr->is_long_term != TD_TRUE && hash_attr->is_keyslot == TD_TRUE, + HASH_COMPAT_ERRNO(ERROR_UNSUPPORT), "Hmac does not support short term calculation for keyslot\n"); + } + + hash_channel = priv_get_current_hash_channel(); + crypto_chk_return(hash_channel == TD_NULL, HASH_COMPAT_ERRNO(ERROR_PROCESS_NOT_INIT), "call init first!\n"); + + hash_ctx = priv_occupy_hash_soft_chn(hash_channel, &idx); + crypto_chk_return(hash_ctx == TD_NULL, HASH_COMPAT_ERRNO(ERROR_CHN_BUSY), "all hash soft chns are busy\n"); + + /* lock soft chn. */ + crypto_mutex_lock(&hash_channel->hash_ctx_mutex[idx]); + + if (hash_attr->is_long_term == TD_TRUE) { + ret = priv_drv_lock_start(hash_ctx, hash_attr); + crypto_chk_goto(ret != TD_SUCCESS, error_unlock_hash_ctx, "priv_drv_lock_start failed\n"); + } else { + ret = priv_drv_lock_start(hash_ctx, hash_attr); + crypto_chk_goto(ret != TD_SUCCESS, error_unlock_hash_ctx, "priv_drv_lock_start failed\n"); + ret = drv_cipher_hash_get(hash_ctx->drv_hash_handle, &hash_ctx->hash_clone_ctx); + crypto_chk_goto(ret != TD_SUCCESS, error_unlock_drv_hash_ctx, "drv_cipher_hash_get failed\n"); + priv_drv_lock_destroy(hash_ctx->drv_hash_handle); + } + + hash_ctx->is_long_term = hash_attr->is_long_term; + + crypto_mutex_unlock(&hash_channel->hash_ctx_mutex[idx]); + + *kapi_hash_handle = synthesize_kapi_handle(KAPI_HASH_MODULE_ID, idx); + + crypto_kapi_func_exit(); + return ret; +error_unlock_drv_hash_ctx: + priv_drv_lock_destroy(hash_ctx->drv_hash_handle); +error_unlock_hash_ctx: + priv_release_hash_soft_chn(hash_ctx); + crypto_mutex_unlock(&hash_channel->hash_ctx_mutex[idx]); + crypto_kapi_func_exit(); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_cipher_hash_start); + +td_s32 kapi_cipher_hash_update(td_handle kapi_hash_handle, const crypto_buf_attr *src_buf, const td_u32 len) +{ + td_s32 ret = TD_SUCCESS; + crypto_kapi_hash_process *hash_channel = TD_NULL; + crypto_kapi_hash_ctx *hash_ctx = TD_NULL; + crypto_hash_attr default_hash_attr = { + .hash_type = CRYPTO_HASH_TYPE_SHA256, + .is_long_term = TD_TRUE + }; + td_u32 idx; + crypto_kapi_func_enter(); + + ret = priv_hash_handle_check(kapi_hash_handle); + crypto_chk_return(ret != TD_SUCCESS, ret, "priv_hash_handle_check failed, ret is 0x%x\n", ret); + idx = kapi_get_ctx_idx(kapi_hash_handle); + + hash_channel = priv_get_current_hash_channel(); + crypto_chk_return(hash_channel == TD_NULL, HASH_COMPAT_ERRNO(ERROR_PROCESS_NOT_INIT), "call init first!\n"); + + hash_ctx = &hash_channel->hash_ctx_list[idx]; + crypto_chk_return(hash_ctx->is_open == TD_FALSE, HASH_COMPAT_ERRNO(ERROR_CTX_CLOSED), "ctx is closed!\n"); + + /* lock soft chn. */ + crypto_mutex_lock(&hash_channel->hash_ctx_mutex[idx]); + if (hash_ctx->is_long_term == TD_TRUE) { + ret = drv_cipher_hash_update(hash_ctx->drv_hash_handle, src_buf, len); + crypto_chk_goto(ret != TD_SUCCESS, error_unlock_hash_ctx, "drv_cipher_hash_update failed\n"); + } else { + ret = priv_drv_lock_start(hash_ctx, &default_hash_attr); + crypto_chk_goto(ret != TD_SUCCESS, error_unlock_hash_ctx, "priv_drv_lock_start failed\n"); + ret = drv_cipher_hash_set(hash_ctx->drv_hash_handle, &hash_ctx->hash_clone_ctx); + crypto_chk_goto(ret != TD_SUCCESS, hash_destroy_exit, "drv_cipher_hash_set failed\n"); + ret = drv_cipher_hash_update(hash_ctx->drv_hash_handle, src_buf, len); + crypto_chk_goto(ret != TD_SUCCESS, hash_destroy_exit, "drv_cipher_hash_update failed\n"); + ret = drv_cipher_hash_get(hash_ctx->drv_hash_handle, &hash_ctx->hash_clone_ctx); + crypto_chk_goto(ret != TD_SUCCESS, hash_destroy_exit, "drv_cipher_hash_set failed\n"); + priv_drv_lock_destroy(hash_ctx->drv_hash_handle); + } + crypto_mutex_unlock(&hash_channel->hash_ctx_mutex[idx]); + crypto_kapi_func_exit(); + return ret; + +hash_destroy_exit: + priv_drv_lock_destroy(hash_ctx->drv_hash_handle); +error_unlock_hash_ctx: + crypto_mutex_unlock(&hash_channel->hash_ctx_mutex[idx]); + crypto_kapi_func_exit(); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_cipher_hash_update); + +td_s32 kapi_cipher_hash_finish(td_handle kapi_hash_handle, td_u8 *out, td_u32 *out_len) +{ + td_s32 ret = TD_SUCCESS; + crypto_kapi_hash_process *hash_channel = TD_NULL; + crypto_kapi_hash_ctx *hash_ctx = TD_NULL; + crypto_hash_attr default_hash_attr = { + .hash_type = CRYPTO_HASH_TYPE_SHA256, + .is_long_term = TD_TRUE + }; + td_u32 idx = 0; + crypto_kapi_func_enter(); + + ret = priv_hash_handle_check(kapi_hash_handle); + crypto_chk_return(ret != TD_SUCCESS, ret, "priv_hash_handle_check failed, ret is 0x%x\n", ret); + idx = kapi_get_ctx_idx(kapi_hash_handle); + + hash_channel = priv_get_current_hash_channel(); + crypto_chk_return(hash_channel == TD_NULL, HASH_COMPAT_ERRNO(ERROR_PROCESS_NOT_INIT), "call init first!\n"); + + hash_ctx = &hash_channel->hash_ctx_list[idx]; + crypto_chk_return(hash_ctx->is_open == TD_FALSE, HASH_COMPAT_ERRNO(ERROR_CTX_CLOSED), "ctx is closed!\n"); + + /* lock soft chn. */ + crypto_mutex_lock(&hash_channel->hash_ctx_mutex[idx]); + if (hash_ctx->is_long_term == TD_TRUE) { + ret = priv_drv_lock_finish(hash_ctx->drv_hash_handle, out, out_len); + crypto_chk_goto(ret != TD_SUCCESS, error_unlock_hash_ctx, "priv_drv_lock_finish failed\n"); + } else { + ret = priv_drv_lock_start(hash_ctx, &default_hash_attr); + crypto_chk_goto(ret != TD_SUCCESS, error_unlock_hash_ctx, "priv_drv_lock_start failed\n"); + ret = drv_cipher_hash_set(hash_ctx->drv_hash_handle, &hash_ctx->hash_clone_ctx); + crypto_chk_goto(ret != TD_SUCCESS, hash_destroy_exit, "drv_cipher_hash_set failed\n"); + ret = priv_drv_lock_finish(hash_ctx->drv_hash_handle, out, out_len); + crypto_chk_goto(ret != TD_SUCCESS, error_unlock_hash_ctx, "priv_drv_lock_finish failed\n"); + } + + priv_release_hash_soft_chn(hash_ctx); + crypto_mutex_unlock(&hash_channel->hash_ctx_mutex[idx]); + crypto_kapi_func_exit(); + return ret; + +hash_destroy_exit: + priv_drv_lock_destroy(hash_ctx->drv_hash_handle); +error_unlock_hash_ctx: + crypto_mutex_unlock(&hash_channel->hash_ctx_mutex[idx]); + crypto_kapi_func_exit(); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_cipher_hash_finish); + +td_s32 kapi_cipher_hash_get(td_handle kapi_hash_handle, crypto_hash_clone_ctx *hash_clone_ctx) +{ + td_s32 ret = TD_SUCCESS; + crypto_kapi_hash_process *hash_channel = TD_NULL; + crypto_kapi_hash_ctx *hash_ctx = TD_NULL; + td_u32 idx = 0; + crypto_kapi_func_enter(); + + crypto_chk_return(hash_clone_ctx == TD_NULL, HASH_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "hash_clone_ctx is NULL\n"); + + ret = priv_hash_handle_check(kapi_hash_handle); + crypto_chk_return(ret != TD_SUCCESS, ret, "priv_hash_handle_check failed, ret is 0x%x\n", ret); + idx = kapi_get_ctx_idx(kapi_hash_handle); + + hash_channel = priv_get_current_hash_channel(); + crypto_chk_return(hash_channel == TD_NULL, HASH_COMPAT_ERRNO(ERROR_PROCESS_NOT_INIT), "call init first!\n"); + + hash_ctx = &hash_channel->hash_ctx_list[idx]; + crypto_chk_return(hash_ctx->is_open == TD_FALSE, HASH_COMPAT_ERRNO(ERROR_CTX_CLOSED), "ctx is closed!\n"); + + /* lock soft chn. */ + crypto_mutex_lock(&hash_channel->hash_ctx_mutex[idx]); + if (hash_ctx->is_long_term == TD_TRUE) { + ret = drv_cipher_hash_get(hash_ctx->drv_hash_handle, hash_clone_ctx); + crypto_chk_goto(ret != TD_SUCCESS, exit_unlock, "drv_cipher_hash_get failed\n"); + } else { + ret = memcpy_s(hash_clone_ctx, sizeof(crypto_hash_clone_ctx), + &hash_ctx->hash_clone_ctx, sizeof(crypto_hash_clone_ctx)); + crypto_chk_goto_with_ret(ret != EOK, exit_unlock, HASH_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + } + +exit_unlock: + crypto_mutex_unlock(&hash_channel->hash_ctx_mutex[idx]); + crypto_kapi_func_exit(); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_cipher_hash_get); + +td_s32 kapi_cipher_hash_set(td_handle kapi_hash_handle, const crypto_hash_clone_ctx *hash_clone_ctx) +{ + td_s32 ret = TD_SUCCESS; + crypto_kapi_hash_process *hash_channel = TD_NULL; + crypto_kapi_hash_ctx *hash_ctx = TD_NULL; + td_u32 idx = 0; + crypto_kapi_func_enter(); + + crypto_chk_return(hash_clone_ctx == TD_NULL, HASH_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "hash_clone_ctx is NULL\n"); + ret = priv_hash_handle_check(kapi_hash_handle); + crypto_chk_return(ret != TD_SUCCESS, ret, "priv_hash_handle_check failed, ret is 0x%x\n", ret); + idx = kapi_get_ctx_idx(kapi_hash_handle); + + hash_channel = priv_get_current_hash_channel(); + crypto_chk_return(hash_channel == TD_NULL, HASH_COMPAT_ERRNO(ERROR_PROCESS_NOT_INIT), "call init first!\n"); + + hash_ctx = &hash_channel->hash_ctx_list[idx]; + crypto_chk_return(hash_ctx->is_open == TD_FALSE, HASH_COMPAT_ERRNO(ERROR_CTX_CLOSED), "ctx is closed!\n"); + + /* lock soft chn. */ + crypto_mutex_lock(&hash_channel->hash_ctx_mutex[idx]); + if (hash_ctx->is_long_term == TD_TRUE) { + ret = drv_cipher_hash_set(hash_ctx->drv_hash_handle, hash_clone_ctx); + crypto_chk_goto(ret != TD_SUCCESS, exit_unlock, "drv_cipher_hash_set failed\n"); + } else { + ret = memcpy_s(&hash_ctx->hash_clone_ctx, sizeof(hash_ctx->hash_clone_ctx), \ + hash_clone_ctx, sizeof(crypto_hash_clone_ctx)); + crypto_chk_goto_with_ret(ret != EOK, exit_unlock, HASH_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + } + +exit_unlock: + crypto_mutex_unlock(&hash_channel->hash_ctx_mutex[idx]); + crypto_kapi_func_exit(); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_cipher_hash_set); + +td_s32 kapi_cipher_hash_destroy(td_handle kapi_hash_handle) +{ + td_s32 ret = TD_SUCCESS; + crypto_kapi_hash_process *hash_channel = TD_NULL; + crypto_kapi_hash_ctx *hash_ctx = TD_NULL; + td_u32 idx = 0; + crypto_kapi_func_enter(); + + ret = priv_hash_handle_check(kapi_hash_handle); + crypto_chk_return(ret != TD_SUCCESS, ret, "priv_hash_handle_check failed, ret is 0x%x\n", ret); + idx = kapi_get_ctx_idx(kapi_hash_handle); + + hash_channel = priv_get_current_hash_channel(); + crypto_chk_return(hash_channel == TD_NULL, HASH_COMPAT_ERRNO(ERROR_PROCESS_NOT_INIT), "call init first!\n"); + + hash_ctx = &hash_channel->hash_ctx_list[idx]; + crypto_chk_return(hash_ctx->is_open == TD_FALSE, HASH_COMPAT_ERRNO(ERROR_CTX_CLOSED), "ctx is closed!\n"); + + /* lock soft chn. */ + crypto_mutex_lock(&hash_channel->hash_ctx_mutex[idx]); + if (hash_ctx->is_long_term == TD_TRUE) { + priv_drv_lock_destroy(hash_ctx->drv_hash_handle); + } + + priv_release_hash_soft_chn(hash_ctx); + + crypto_mutex_unlock(&hash_channel->hash_ctx_mutex[idx]); + + crypto_kapi_func_exit(); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_cipher_hash_destroy); + +td_s32 kapi_cipher_pbkdf2(const crypto_kdf_pbkdf2_param *param, td_u8 *out, const td_u32 out_len) +{ + td_s32 ret = TD_SUCCESS; + crypto_kapi_func_enter(); + + kapi_hash_lock(); + ret = drv_cipher_pbkdf2(param, out, out_len); + kapi_hash_unlock(); + crypto_kapi_func_exit(); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_cipher_pbkdf2); \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/kapi_code/kapi_init.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/kapi_code/kapi_init.c new file mode 100644 index 00000000..d8f178ae --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/kapi_code/kapi_init.c @@ -0,0 +1,44 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "kapi_inner.h" + +#include "crypto_drv_common.h" + +td_s32 kapi_env_init(td_void) +{ + td_s32 ret; + /* KAPI Init. */ + ret = kapi_cipher_hash_env_init(); + crypto_chk_return(ret != TD_SUCCESS, ret, "kapi_cipher_hash_env_init failed, ret is 0x%x.\n", ret); + + ret = kapi_cipher_trng_env_init(); + crypto_chk_goto(ret != TD_SUCCESS, error_kapi_hash_env_deinit, + "kapi_cipher_trng_env_init failed, ret is 0x%x.\n", ret); + + ret = kapi_cipher_symc_env_init(); + crypto_chk_goto(ret != TD_SUCCESS, error_kapi_trng_env_deinit, + "kapi_cipher_symc_env_init failed, ret is 0x%x.\n", ret); + + ret = kapi_cipher_pke_env_init(); + crypto_chk_goto(ret != TD_SUCCESS, error_kapi_symc_env_deinit, + "kapi_cipher_pke_env_init failed, ret is 0x%x.\n", ret); + + return ret; +error_kapi_symc_env_deinit: + kapi_cipher_symc_env_deinit(); +error_kapi_trng_env_deinit: + kapi_cipher_trng_env_deinit(); +error_kapi_hash_env_deinit: + kapi_cipher_hash_env_deinit(); + return ret; +} + +td_void kapi_env_deinit(td_void) +{ + kapi_cipher_pke_env_deinit(); + kapi_cipher_symc_env_deinit(); + kapi_cipher_trng_env_deinit(); + kapi_cipher_hash_env_deinit(); +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/kapi_code/kapi_inner.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/kapi_code/kapi_inner.h new file mode 100644 index 00000000..6eba21c4 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/kapi_code/kapi_inner.h @@ -0,0 +1,30 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef KAPI_INNER_H +#define KAPI_INNER_H + +#include "crypto_type.h" + +td_s32 kapi_cipher_hash_env_init(td_void); + +td_s32 kapi_cipher_hash_env_deinit(td_void); + +td_s32 kapi_cipher_symc_env_init(td_void); + +td_s32 kapi_cipher_symc_env_deinit(td_void); + +td_s32 kapi_cipher_trng_env_init(td_void); + +td_s32 kapi_cipher_trng_env_deinit(td_void); + +td_s32 kapi_cipher_pke_env_init(td_void); + +td_s32 kapi_cipher_pke_env_deinit(td_void); + +td_s32 kapi_env_init(td_void); + +td_void kapi_env_deinit(td_void); + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/kapi_code/kapi_km.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/kapi_code/kapi_km.c new file mode 100644 index 00000000..4a9b8a2c --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/kapi_code/kapi_km.c @@ -0,0 +1,684 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "kapi_km.h" + +#include "crypto_common_def.h" +#include "crypto_common_macro.h" +#include "crypto_drv_common.h" +#include "drv_klad.h" +#include "drv_keyslot.h" + +typedef struct { + crypto_owner owner; + td_bool is_open; + td_handle keyslot_handle; + crypto_keyslot_type type; +} crypto_kapi_keyslot_ctx; + +typedef struct { + crypto_owner owner; + td_bool is_open; + td_bool is_attached; + td_bool is_set_attr; + td_bool is_set_session_key; + td_handle drv_klad_handle; + td_handle drv_keyslot_handle; + crypto_klad_dest klad_type; + crypto_klad_attr klad_attr; + crypto_klad_session_key session_key; + td_handle keyslot_handle; +} crypto_kapi_klad_ctx; + +crypto_mutex g_klad_mutex; +crypto_mutex g_keyslot_mutex; + +#define CRYPTO_MCIPHER_KEYSLOT_NUM 8 +#define CRYPTO_HMAC_KEYSLOT_NUM 2 +#define CRYPTO_KLAD_VIRT_NUM 16 + +static crypto_kapi_keyslot_ctx g_keyslot_symc_ctx_list[CRYPTO_MCIPHER_KEYSLOT_NUM] = {0}; +static crypto_kapi_keyslot_ctx g_keyslot_hmac_ctx_list[CRYPTO_HMAC_KEYSLOT_NUM] = {0}; + +static crypto_kapi_klad_ctx g_klad_ctx_list[CRYPTO_KLAD_VIRT_NUM] = {0}; + +#define kapi_klad_mutex_lock() do { \ + crypto_mutex_lock(&g_klad_mutex); \ +} while (0) + +#define kapi_klad_mutex_unlock() do { \ + crypto_mutex_unlock(&g_klad_mutex); \ +} while (0) + +#define kapi_keyslot_mutex_lock() do { \ + crypto_mutex_lock(&g_keyslot_mutex); \ +} while (0) + +#define kapi_keyslot_mutex_unlock() do { \ + crypto_mutex_unlock(&g_keyslot_mutex); \ +} while (0) + +#define KM_COMPAT_ERRNO(err_code) KAPI_COMPAT_ERRNO(ERROR_MODULE_KM, err_code) +#define km_null_ptr_chk(ptr) \ + crypto_chk_return((ptr) == TD_NULL, KM_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), #ptr" is NULL\n") + +static td_void inner_kapi_release_all_hardware_resource(td_void) +{ + td_s32 i; + crypto_kapi_keyslot_ctx *keyslot_ctx = TD_NULL; + /* mcipher keyslot. */ + for (i = 0; i < CRYPTO_MCIPHER_KEYSLOT_NUM; i++) { + keyslot_ctx = &g_keyslot_symc_ctx_list[i]; + if (keyslot_ctx->is_open == TD_TRUE) { + (td_void)drv_keyslot_destroy(keyslot_ctx->keyslot_handle); + } + } + /* hmac keyslot. */ + for (i = 0; i < CRYPTO_HMAC_KEYSLOT_NUM; i++) { + keyslot_ctx = &g_keyslot_hmac_ctx_list[i]; + if (keyslot_ctx->is_open == TD_TRUE) { + (td_void)drv_keyslot_destroy(keyslot_ctx->keyslot_handle); + } + } +} + +td_s32 kapi_km_env_init(td_void) +{ + td_s32 ret; + + ret = crypto_mutex_init(&g_klad_mutex); + crypto_chk_return(ret != TD_SUCCESS, ret, "crypto_mutex_init failed, ret is 0x%x\n", ret); + + ret = crypto_mutex_init(&g_keyslot_mutex); + crypto_chk_goto(ret != TD_SUCCESS, klad_mutex_destroy_exit, "crypto_mutex_init failed, ret is 0x%x\n", ret); + + ret = drv_keyslot_init(); + crypto_chk_goto(ret != TD_SUCCESS, keyslot_mutex_destroy_exit, "drv_keyslot_init failed, ret is 0x%x\n", ret); + + return TD_SUCCESS; + +keyslot_mutex_destroy_exit: + crypto_mutex_destroy(&g_keyslot_mutex); +klad_mutex_destroy_exit: + crypto_mutex_destroy(&g_klad_mutex); + return TD_FAILURE; +} + +td_s32 kapi_km_env_deinit(td_void) +{ + crypto_mutex_destroy(&g_keyslot_mutex); + crypto_mutex_destroy(&g_klad_mutex); + + inner_kapi_release_all_hardware_resource(); + (td_void)memset_s(g_keyslot_symc_ctx_list, sizeof(g_keyslot_symc_ctx_list), 0, sizeof(g_keyslot_symc_ctx_list)); + (td_void)memset_s(g_keyslot_hmac_ctx_list, sizeof(g_keyslot_hmac_ctx_list), 0, sizeof(g_keyslot_hmac_ctx_list)); + + (td_void)drv_keyslot_deinit(); + + (td_void)memset_s(g_klad_ctx_list, sizeof(g_klad_ctx_list), 0, sizeof(g_klad_ctx_list)); + + return TD_SUCCESS; +} + +td_s32 kapi_km_deinit(td_void) +{ + td_s32 i; + crypto_owner owner; + crypto_kapi_keyslot_ctx *keyslot_ctx = TD_NULL; + crypto_kapi_klad_ctx *klad_ctx = TD_NULL; + + crypto_get_owner(&owner); + kapi_keyslot_mutex_lock(); + /* mcipher keyslot. */ + for (i = 0; i < CRYPTO_MCIPHER_KEYSLOT_NUM; i++) { + keyslot_ctx = &g_keyslot_symc_ctx_list[i]; + if (memcmp(&owner, &keyslot_ctx->owner, sizeof(crypto_owner)) == 0 && keyslot_ctx->is_open == TD_TRUE) { + (td_void)drv_keyslot_destroy(keyslot_ctx->keyslot_handle); + (td_void)memset_s(keyslot_ctx, sizeof(crypto_kapi_keyslot_ctx), 0, sizeof(crypto_kapi_keyslot_ctx)); + } + } + /* hmac keyslot. */ + for (i = 0; i < CRYPTO_HMAC_KEYSLOT_NUM; i++) { + keyslot_ctx = &g_keyslot_hmac_ctx_list[i]; + if (memcmp(&owner, &keyslot_ctx->owner, sizeof(crypto_owner)) == 0 && keyslot_ctx->is_open == TD_TRUE) { + (td_void)drv_keyslot_destroy(keyslot_ctx->keyslot_handle); + (td_void)memset_s(keyslot_ctx, sizeof(crypto_kapi_keyslot_ctx), 0, sizeof(crypto_kapi_keyslot_ctx)); + } + } + kapi_keyslot_mutex_unlock(); + + /* klad. */ + kapi_klad_mutex_lock(); + for (i = 0; i < CRYPTO_KLAD_VIRT_NUM; i++) { + klad_ctx = &g_klad_ctx_list[i]; + if (memcmp(&owner, &klad_ctx->owner, sizeof(crypto_owner)) == 0 && klad_ctx->is_open == TD_TRUE) { + (td_void)memset_s(klad_ctx, sizeof(crypto_kapi_klad_ctx), 0, sizeof(crypto_kapi_klad_ctx)); + } + } + kapi_klad_mutex_unlock(); + + return TD_SUCCESS; +} + +static crypto_kapi_keyslot_ctx *inner_keyslot_get_ctx(td_handle keyslot_handle) +{ + td_u32 i = 0; + crypto_owner owner; + crypto_kapi_keyslot_ctx *keyslot_ctx; + crypto_get_owner(&owner); + /* check mcipher keyslot. */ + for (i = 0; i < CRYPTO_MCIPHER_KEYSLOT_NUM; i++) { + keyslot_ctx = &g_keyslot_symc_ctx_list[i]; + if (memcmp(&owner, &keyslot_ctx->owner, sizeof(crypto_owner)) == 0 && keyslot_ctx->is_open == TD_TRUE && + keyslot_handle == keyslot_ctx->keyslot_handle) { + return keyslot_ctx; + } + } + /* check hmac keyslot. */ + for (i = 0; i < CRYPTO_HMAC_KEYSLOT_NUM; i++) { + keyslot_ctx = &g_keyslot_hmac_ctx_list[i]; + if (memcmp(&owner, &keyslot_ctx->owner, sizeof(crypto_owner)) == 0 && keyslot_ctx->is_open == TD_TRUE && + keyslot_handle == keyslot_ctx->keyslot_handle) { + return keyslot_ctx; + } + } + crypto_log_err("invalid keyslot_handle\n"); + return TD_NULL; +} + +static td_s32 inner_klad_handle_chk(td_handle klad_handle) +{ + td_u32 idx = 0; + if (kapi_get_module_id(klad_handle) != KAPI_KLAD_MODULE_ID) { + crypto_log_err("invalid module id\n"); + return KM_COMPAT_ERRNO(ERROR_INVALID_HANDLE); + } + idx = kapi_get_ctx_idx(klad_handle); + crypto_chk_return(idx >= CRYPTO_KLAD_VIRT_NUM, KM_COMPAT_ERRNO(ERROR_INVALID_HANDLE), + "idx overflow for klad\n"); + + return TD_SUCCESS; +} + +/* Keyslot. Long-term occupation by default */ +td_s32 kapi_keyslot_create(td_handle *kapi_keyslot_handle, km_keyslot_type keyslot_type) +{ + td_u32 i; + td_s32 ret = TD_SUCCESS; + crypto_kapi_keyslot_ctx *ctx_list = TD_NULL; + crypto_kapi_keyslot_ctx *current_ctx = TD_NULL; + td_u32 ctx_num = 0; + + km_null_ptr_chk(kapi_keyslot_handle); + if (keyslot_type == (km_keyslot_type)CRYPTO_KEYSLOT_TYPE_MCIPHER) { + ctx_list = g_keyslot_symc_ctx_list; + ctx_num = crypto_array_size(g_keyslot_symc_ctx_list); + } else if (keyslot_type == (km_keyslot_type)CRYPTO_KEYSLOT_TYPE_HMAC) { + ctx_list = g_keyslot_hmac_ctx_list; + ctx_num = crypto_array_size(g_keyslot_hmac_ctx_list); + } else { + crypto_log_err("invalid keyslot_type\n"); + return KM_COMPAT_ERRNO(ERROR_INVALID_PARAM); + } + + kapi_keyslot_mutex_lock(); + for (i = 0; i < ctx_num; i++) { + if (ctx_list[i].is_open == TD_FALSE) { + current_ctx = &ctx_list[i]; + break; + } + } + if (current_ctx == TD_NULL) { + crypto_log_err("all keyslot contexts are busy\n"); + ret = KM_COMPAT_ERRNO(ERROR_CHN_BUSY); + goto exit_unlock; + } + + ret = drv_keyslot_create(¤t_ctx->keyslot_handle, (crypto_keyslot_type)keyslot_type); + crypto_chk_goto(ret != TD_SUCCESS, exit_unlock, "drv_keyslot_create failed, ret is 0x%x\n", ret); + + current_ctx->type = (crypto_keyslot_type)keyslot_type; + current_ctx->is_open = TD_TRUE; + crypto_get_owner(¤t_ctx->owner); + + *kapi_keyslot_handle = current_ctx->keyslot_handle; + +exit_unlock: + kapi_keyslot_mutex_unlock(); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_keyslot_create); + +td_s32 kapi_keyslot_destroy(td_handle kapi_keyslot_handle) +{ + td_s32 ret = TD_SUCCESS; + crypto_owner owner; + crypto_kapi_keyslot_ctx *current_ctx = TD_NULL; + + current_ctx = inner_keyslot_get_ctx(kapi_keyslot_handle); + crypto_chk_return(current_ctx == TD_NULL, KM_COMPAT_ERRNO(ERROR_INVALID_HANDLE), "inner_keyslot_get_ctx failed\n"); + + kapi_keyslot_mutex_lock(); + if (current_ctx->is_open == TD_FALSE) { + ret = TD_SUCCESS; + goto exit_unlock; + } + + crypto_get_owner(&owner); + if (memcmp(&owner, ¤t_ctx->owner, sizeof(crypto_owner)) != 0) { + crypto_log_err("invalid process\n"); + ret = KM_COMPAT_ERRNO(ERROR_INVALID_PROCESS); + goto exit_unlock; + } + + ret = drv_keyslot_destroy(current_ctx->keyslot_handle); + crypto_chk_goto(ret != TD_SUCCESS, exit_unlock, "drv_keyslot_destroy failed, ret is 0x%x\n", ret); + + (td_void)memset_s(current_ctx, sizeof(crypto_kapi_keyslot_ctx), 0, sizeof(crypto_kapi_keyslot_ctx)); + +exit_unlock: + kapi_keyslot_mutex_unlock(); + + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_keyslot_destroy); + +/* Klad. Short-term occupation by default */ +td_s32 kapi_klad_create(td_handle *kapi_klad_handle) +{ + td_s32 i; + td_s32 ret = TD_SUCCESS; + crypto_kapi_klad_ctx *ctx = TD_NULL; + + km_null_ptr_chk(kapi_klad_handle); + + kapi_klad_mutex_lock(); + for (i = 0; i < CRYPTO_KLAD_VIRT_NUM; i++) { + if (g_klad_ctx_list[i].is_open == TD_FALSE) { + ctx = &g_klad_ctx_list[i]; + break; + } + } + if (ctx == TD_NULL) { + crypto_log_err("all klad contexts are busy\n"); + ret = KM_COMPAT_ERRNO(ERROR_CHN_BUSY); + goto exit_unlock; + } + + crypto_get_owner(&ctx->owner); + ctx->is_open = TD_TRUE; + *kapi_klad_handle = synthesize_kapi_handle(KAPI_KLAD_MODULE_ID, i); + +exit_unlock: + kapi_klad_mutex_unlock(); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_klad_create); + +td_s32 kapi_klad_destroy(td_handle kapi_klad_handle) +{ + td_s32 ret = TD_SUCCESS; + td_u32 idx = 0; + crypto_kapi_klad_ctx *ctx = TD_NULL; + crypto_owner owner; + + ret = inner_klad_handle_chk(kapi_klad_handle); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_klad_handle_chk failed\n"); + + idx = kapi_get_ctx_idx(kapi_klad_handle); + ctx = &g_klad_ctx_list[idx]; + if (ctx->is_open == TD_FALSE) { + return KM_COMPAT_ERRNO(ERROR_CTX_CLOSED); + } + kapi_klad_mutex_lock(); + + crypto_get_owner(&owner); + if (memcmp(&owner, &ctx->owner, sizeof(crypto_owner)) != 0) { + crypto_log_err("invalid process\n"); + ret = KM_COMPAT_ERRNO(ERROR_INVALID_PROCESS); + goto exit_unlock; + } + + (td_void)memset_s(ctx, sizeof(crypto_kapi_klad_ctx), 0, sizeof(crypto_kapi_klad_ctx)); + +exit_unlock: + kapi_klad_mutex_unlock(); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_klad_destroy); + +td_s32 kapi_klad_attach(td_handle kapi_klad_handle, km_klad_dest_type klad_type, + td_handle kapi_keyslot_handle) +{ + td_s32 ret = TD_SUCCESS; + td_u32 idx = 0; + crypto_kapi_klad_ctx *klad_ctx = TD_NULL; + crypto_kapi_keyslot_ctx *keyslot_ctx = TD_NULL; + crypto_owner owner; + crypto_get_owner(&owner); + + crypto_chk_return (klad_type >= KM_KLAD_DEST_TYPE_MAX, KM_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "Invalid klad_dest_type\n"); + + ret = inner_klad_handle_chk(kapi_klad_handle); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_klad_handle_chk failed\n"); + + idx = kapi_get_ctx_idx(kapi_klad_handle); + klad_ctx = &g_klad_ctx_list[idx]; + + kapi_klad_mutex_lock(); + crypto_chk_goto_with_ret(klad_ctx->is_open == TD_FALSE, exit_unlock, + KM_COMPAT_ERRNO(ERROR_CTX_CLOSED), "call klad_create first\n"); + crypto_chk_goto_with_ret(memcmp(&owner, &klad_ctx->owner, sizeof(crypto_owner)) != 0, exit_unlock, + KM_COMPAT_ERRNO(ERROR_INVALID_PROCESS), "invalid process\n"); + + if (klad_type != KM_KLAD_DEST_TYPE_NPU) { + keyslot_ctx = inner_keyslot_get_ctx(kapi_keyslot_handle); + crypto_chk_goto_with_ret(keyslot_ctx == TD_NULL, exit_unlock, KM_COMPAT_ERRNO(ERROR_INVALID_HANDLE), + "inner_keyslot_get_ctx failed\n"); + if (memcmp(&owner, &keyslot_ctx->owner, sizeof(crypto_owner)) != 0) { + crypto_log_err("invalid process\n"); + ret = KM_COMPAT_ERRNO(ERROR_INVALID_PROCESS); + goto exit_unlock; + } + klad_ctx->keyslot_handle = keyslot_ctx->keyslot_handle; + } else { + klad_ctx->keyslot_handle = kapi_keyslot_handle; + } + + klad_ctx->is_attached = TD_TRUE; + klad_ctx->klad_type = (crypto_klad_dest)klad_type; + +exit_unlock: + kapi_klad_mutex_unlock(); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_klad_attach); + +td_s32 kapi_klad_detach(td_handle kapi_klad_handle, km_klad_dest_type klad_type, + td_handle kapi_keyslot_handle) +{ + td_s32 ret = TD_SUCCESS; + td_u32 idx = 0; + crypto_kapi_klad_ctx *klad_ctx = TD_NULL; + crypto_kapi_keyslot_ctx *keyslot_ctx = TD_NULL; + crypto_owner owner; + + crypto_chk_return (klad_type >= KM_KLAD_DEST_TYPE_MAX, KM_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "Invalid klad_dest_type\n"); + + ret = inner_klad_handle_chk(kapi_klad_handle); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_klad_handle_chk failed\n"); + + crypto_get_owner(&owner); + idx = kapi_get_ctx_idx(kapi_klad_handle); + klad_ctx = &g_klad_ctx_list[idx]; + kapi_klad_mutex_lock(); + + crypto_chk_goto_with_ret(memcmp(&owner, &klad_ctx->owner, sizeof(crypto_owner)) != 0, exit_unlock, + KM_COMPAT_ERRNO(ERROR_INVALID_PROCESS), "invalid process\n"); + crypto_chk_goto_with_ret(klad_ctx->is_open == TD_FALSE, exit_unlock, KM_COMPAT_ERRNO(ERROR_CTX_CLOSED), + "call klad_create first\n"); + crypto_chk_goto_with_ret(klad_ctx->is_attached == TD_FALSE, exit_unlock, KM_COMPAT_ERRNO(ERROR_NOT_ATTACHED), + "call klad_attach first\n"); + + crypto_chk_goto_with_ret(klad_ctx->klad_type != (crypto_klad_dest)klad_type, exit_unlock, + KM_COMPAT_ERRNO(ERROR_INVALID_PARAM), "invalid klad_type\n"); + if (klad_type != KM_KLAD_DEST_TYPE_NPU) { + keyslot_ctx = inner_keyslot_get_ctx(kapi_keyslot_handle); + crypto_chk_goto_with_ret(keyslot_ctx == TD_NULL, exit_unlock, KM_COMPAT_ERRNO(ERROR_INVALID_HANDLE), + "inner_keyslot_get_ctx failed\n"); + crypto_chk_goto_with_ret(keyslot_ctx->keyslot_handle != klad_ctx->keyslot_handle, exit_unlock, + KM_COMPAT_ERRNO(ERROR_INVALID_HANDLE), "invalid keyslot_handle\n"); + } else { + crypto_chk_goto_with_ret(klad_ctx->keyslot_handle != kapi_keyslot_handle, exit_unlock, + KM_COMPAT_ERRNO(ERROR_INVALID_HANDLE), "invalid npu keyslot_handle\n"); + } + + klad_ctx->is_attached = TD_FALSE; + klad_ctx->keyslot_handle = 0; + klad_ctx->klad_type = 0; + +exit_unlock: + kapi_klad_mutex_unlock(); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_klad_detach); + +td_s32 kapi_klad_set_attr(td_handle kapi_klad_handle, const km_klad_attr *attr) +{ + td_s32 ret = TD_SUCCESS; + td_u32 idx = 0; + crypto_kapi_klad_ctx *klad_ctx = TD_NULL; + crypto_owner owner; + + km_null_ptr_chk(attr); + crypto_chk_return(attr->key_sec_cfg.key_sec >= KM_KLAD_SEC_MAX, KM_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "km_klad_attr.key_sec_cfg.key_sec >= KM_KLAD_SEC_MAX\n"); + crypto_chk_return(attr->key_cfg.engine >= KM_CRYPTO_ALG_MAX, KM_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "km_klad_attr.key_cfg.engine >= KM_CRYPTO_ALG_MAX\n"); + + ret = inner_klad_handle_chk(kapi_klad_handle); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_klad_handle_chk failed\n"); + + crypto_get_owner(&owner); + idx = kapi_get_ctx_idx(kapi_klad_handle); + klad_ctx = &g_klad_ctx_list[idx]; + kapi_klad_mutex_lock(); + + crypto_chk_goto_with_ret(memcmp(&owner, &klad_ctx->owner, sizeof(crypto_owner)) != 0, exit_unlock, + KM_COMPAT_ERRNO(ERROR_INVALID_PROCESS), "invalid process\n"); + crypto_chk_goto_with_ret(klad_ctx->is_open == TD_FALSE, exit_unlock, + KM_COMPAT_ERRNO(ERROR_CTX_CLOSED), "call klad_create first\n"); + + ret = memcpy_s(&klad_ctx->klad_attr, sizeof(crypto_klad_attr), attr, sizeof(km_klad_attr)); + crypto_chk_goto_with_ret(ret != EOK, exit_unlock, KM_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + klad_ctx->is_set_attr = TD_TRUE; + +exit_unlock: + kapi_klad_mutex_unlock(); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_klad_set_attr); + +td_s32 kapi_klad_get_attr(td_handle kapi_klad_handle, km_klad_attr *attr) +{ + td_s32 ret = TD_SUCCESS; + td_u32 idx = 0; + crypto_kapi_klad_ctx *klad_ctx = TD_NULL; + crypto_owner owner; + + km_null_ptr_chk(attr); + ret = inner_klad_handle_chk(kapi_klad_handle); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_klad_handle_chk failed\n"); + + crypto_get_owner(&owner); + idx = kapi_get_ctx_idx(kapi_klad_handle); + klad_ctx = &g_klad_ctx_list[idx]; + kapi_klad_mutex_lock(); + + crypto_chk_goto_with_ret(memcmp(&owner, &klad_ctx->owner, sizeof(crypto_owner)) != 0, exit_unlock, + KM_COMPAT_ERRNO(ERROR_INVALID_PROCESS), "invalid process\n"); + crypto_chk_goto_with_ret(klad_ctx->is_open == TD_FALSE, exit_unlock, + KM_COMPAT_ERRNO(ERROR_CTX_CLOSED), "call klad_create first\n"); + crypto_chk_goto_with_ret(klad_ctx->is_set_attr == TD_FALSE, exit_unlock, + KM_COMPAT_ERRNO(ERROR_NOT_SET_CONFIG), "call klad_set_attr first\n"); + + ret = memcpy_s(attr, sizeof(km_klad_attr), &klad_ctx->klad_attr, sizeof(crypto_klad_attr)); + crypto_chk_goto_with_ret(ret != EOK, exit_unlock, KM_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + +exit_unlock: + kapi_klad_mutex_unlock(); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_klad_get_attr); + +td_s32 kapi_klad_set_clear_key(td_handle kapi_klad_handle, const km_klad_clear_key *key) +{ + td_s32 ret = TD_SUCCESS; + td_u32 idx = 0; + td_handle hard_klad_handle; + crypto_kapi_klad_ctx *klad_ctx = TD_NULL; + crypto_owner owner; + crypto_klad_clear_key clear_key; + + km_null_ptr_chk(key); + ret = inner_klad_handle_chk(kapi_klad_handle); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_klad_handle_chk failed\n"); + crypto_chk_return(key->key_parity >= KM_KLAD_KEY_PARITY_MAX, KM_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "klad_clear_key.key_parity >= KM_KLAD_KEY_PARITY_MAX\n"); + + clear_key.key = key->key; + clear_key.key_parity = (td_bool)key->key_parity; + clear_key.key_length = key->key_size; + clear_key.hmac_type = (crypto_klad_hmac_type)key->hmac_type; + + crypto_get_owner(&owner); + idx = kapi_get_ctx_idx(kapi_klad_handle); + klad_ctx = &g_klad_ctx_list[idx]; + kapi_klad_mutex_lock(); + + crypto_chk_goto_with_ret(memcmp(&owner, &klad_ctx->owner, sizeof(crypto_owner)) != 0, exit_unlock, + KM_COMPAT_ERRNO(ERROR_INVALID_PROCESS), "invalid process\n"); + crypto_chk_goto_with_ret(klad_ctx->is_open == TD_FALSE, exit_unlock, + KM_COMPAT_ERRNO(ERROR_CTX_CLOSED), "call klad_create first\n"); + crypto_chk_goto_with_ret(klad_ctx->is_attached == TD_FALSE, exit_unlock, + KM_COMPAT_ERRNO(ERROR_NOT_ATTACHED), "call klad_attach first\n"); + crypto_chk_goto_with_ret(klad_ctx->is_set_attr == TD_FALSE, exit_unlock, + KM_COMPAT_ERRNO(ERROR_NOT_SET_CONFIG), "call klad_set_attr first\n"); + + ret = drv_klad_create(&hard_klad_handle); + crypto_chk_goto(ret != TD_SUCCESS, exit_unlock, "drv_klad_create failed, ret is 0x%x\n", ret); + + ret = drv_klad_set_attr(hard_klad_handle, &klad_ctx->klad_attr); + crypto_chk_goto(ret != TD_SUCCESS, exit_destroy, "drv_klad_set_attr failed, ret is 0x%x\n", ret); + + ret = drv_klad_attach(hard_klad_handle, klad_ctx->klad_type, klad_ctx->keyslot_handle); + crypto_chk_goto(ret != TD_SUCCESS, exit_destroy, "drv_klad_attach failed, ret is 0x%x\n", ret); + + ret = drv_klad_set_clear_key(hard_klad_handle, &clear_key); + crypto_chk_goto(ret != TD_SUCCESS, exit_detach, "drv_klad_set_clear_key failed, ret is 0x%x\n", ret); + +exit_detach: + drv_klad_detach(hard_klad_handle, klad_ctx->klad_type, klad_ctx->keyslot_handle); +exit_destroy: + drv_klad_destroy(hard_klad_handle); +exit_unlock: + kapi_klad_mutex_unlock(); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_klad_set_clear_key); + +td_s32 kapi_klad_set_session_key(td_handle kapi_klad_handle, const km_klad_session_key *key) +{ + td_s32 ret = TD_SUCCESS; + td_u32 idx = 0; + crypto_kapi_klad_ctx *klad_ctx = TD_NULL; + crypto_owner owner; + + km_null_ptr_chk(key); + km_null_ptr_chk(key->key); + ret = inner_klad_handle_chk(kapi_klad_handle); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_klad_handle_chk failed\n"); + crypto_chk_return(key->key_size != CRYPTO_128_KEY_LEN, KM_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "Session key's size is invalid\n"); + crypto_chk_return(key->alg >= KM_KLAD_ALG_TYPE_MAX, KM_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "session_key.alg >= KM_KLAD_ALG_TYPE_MAX\n"); + crypto_chk_return(key->level >= KM_KLAD_LEVEL_MAX, KM_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "session_key.level >= KM_KLAD_LEVEL_MAX\n"); + + crypto_get_owner(&owner); + idx = kapi_get_ctx_idx(kapi_klad_handle); + klad_ctx = &g_klad_ctx_list[idx]; + kapi_klad_mutex_lock(); + + crypto_chk_goto_with_ret(memcmp(&owner, &klad_ctx->owner, sizeof(crypto_owner)) != 0, exit_unlock, + KM_COMPAT_ERRNO(ERROR_INVALID_PROCESS), "invalid process\n"); + crypto_chk_goto_with_ret(klad_ctx->is_open == TD_FALSE, exit_unlock, + KM_COMPAT_ERRNO(ERROR_CTX_CLOSED), "call klad_create first\n"); + crypto_chk_goto_with_ret(klad_ctx->is_attached == TD_FALSE, exit_unlock, + KM_COMPAT_ERRNO(ERROR_NOT_ATTACHED), "call klad_attach first\n"); + crypto_chk_goto_with_ret(klad_ctx->is_set_attr == TD_FALSE, exit_unlock, + KM_COMPAT_ERRNO(ERROR_NOT_SET_CONFIG), "call klad_set_attr first\n"); + + ret = memcpy_s(klad_ctx->session_key.key, sizeof(klad_ctx->session_key.key), key->key, key->key_size); + crypto_chk_goto_with_ret(ret != EOK, exit_unlock, KM_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + klad_ctx->is_set_session_key = TD_TRUE; + klad_ctx->session_key.level = (crypto_klad_level_sel)key->level; + klad_ctx->session_key.alg = (crypto_klad_alg_sel)key->alg; + klad_ctx->session_key.key_length = key->key_size; + +exit_unlock: + kapi_klad_mutex_unlock(); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_klad_set_session_key); + +td_s32 kapi_klad_set_content_key(td_handle kapi_klad_handle, const km_klad_content_key *key) +{ + td_s32 ret = TD_SUCCESS; + td_u32 idx = 0; + crypto_kapi_klad_ctx *klad_ctx = TD_NULL; + crypto_owner owner; + td_handle hard_klad_handle = 0; + crypto_klad_content_key content_key = {0}; + + km_null_ptr_chk(key); + km_null_ptr_chk(key->key); + ret = inner_klad_handle_chk(kapi_klad_handle); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_klad_handle_chk failed\n"); + crypto_chk_return(key->key_size != CRYPTO_128_KEY_LEN && key->key_size != CRYPTO_256_KEY_LEN, + KM_COMPAT_ERRNO(ERROR_INVALID_PARAM), "Content key's size is invalid\n"); + crypto_chk_return(key->alg >= KM_KLAD_ALG_TYPE_MAX, KM_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "content_key.alg >= KM_KLAD_ALG_TYPE_MAX\n"); + crypto_chk_return(key->key_parity >= KM_KLAD_KEY_PARITY_MAX, KM_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "content_key.key_parity >= KM_KLAD_KEY_PARITY_MAX\n"); + + crypto_get_owner(&owner); + idx = kapi_get_ctx_idx(kapi_klad_handle); + klad_ctx = &g_klad_ctx_list[idx]; + kapi_klad_mutex_lock(); + + crypto_chk_goto_with_ret(memcmp(&owner, &klad_ctx->owner, sizeof(crypto_owner)) != 0, exit_unlock, + KM_COMPAT_ERRNO(ERROR_INVALID_PROCESS), "invalid process\n"); + crypto_chk_goto_with_ret(klad_ctx->is_open == TD_FALSE, exit_unlock, + KM_COMPAT_ERRNO(ERROR_CTX_CLOSED), "call klad_create first\n"); + crypto_chk_goto_with_ret(klad_ctx->is_attached == TD_FALSE, exit_unlock, + KM_COMPAT_ERRNO(ERROR_NOT_ATTACHED), "call klad_attach first\n"); + crypto_chk_goto_with_ret(klad_ctx->is_set_attr == TD_FALSE, exit_unlock, + KM_COMPAT_ERRNO(ERROR_NOT_SET_CONFIG), "call klad_set_attr first\n"); + crypto_chk_goto_with_ret(klad_ctx->is_set_session_key == TD_FALSE, exit_unlock, + KM_COMPAT_ERRNO(ERROR_NOT_SET_SESSION_KEY), "call klad_set_session_key first\n"); + + content_key.key_length = key->key_size; + content_key.alg = (crypto_klad_alg_sel)key->alg; + content_key.key_parity = (td_bool)key->key_parity; + ret = memcpy_s(content_key.key, sizeof(content_key.key), key->key, key->key_size); + crypto_chk_goto_with_ret(ret != EOK, exit_unlock, KM_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + ret = drv_klad_create(&hard_klad_handle); + crypto_chk_goto(ret != TD_SUCCESS, exit_unlock, "drv_klad_create failed, ret is 0x%x\n", ret); + + ret = drv_klad_set_attr(hard_klad_handle, (crypto_klad_attr *)&klad_ctx->klad_attr); + crypto_chk_goto(ret != TD_SUCCESS, destroy_exit, "drv_klad_set_attr failed, ret is 0x%x\n", ret); + + ret = drv_klad_attach(hard_klad_handle, klad_ctx->klad_type, klad_ctx->keyslot_handle); + crypto_chk_goto(ret != TD_SUCCESS, destroy_exit, "drv_klad_attach failed, ret is 0x%x\n", ret); + + ret = drv_klad_set_session_key(hard_klad_handle, &klad_ctx->session_key); + crypto_chk_goto(ret != TD_SUCCESS, detach_exit, "drv_klad_set_session_key failed, ret is 0x%x\n", ret); + + ret = drv_klad_set_content_key(hard_klad_handle, &content_key); + crypto_chk_goto(ret != TD_SUCCESS, detach_exit, "drv_klad_set_content_key failed, ret is 0x%x\n", ret); +detach_exit: + drv_klad_detach(hard_klad_handle, klad_ctx->klad_type, klad_ctx->keyslot_handle); +destroy_exit: + drv_klad_destroy(hard_klad_handle); +exit_unlock: + kapi_klad_mutex_unlock(); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_klad_set_content_key); \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/kapi_code/kapi_otp.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/kapi_code/kapi_otp.c new file mode 100644 index 00000000..afbed969 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/kapi_code/kapi_otp.c @@ -0,0 +1,85 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "kapi_otp.h" + +#include "drv_otp.h" +#include "crypto_common_macro.h" +#include "crypto_osal_adapt.h" +#include "crypto_osal_lib.h" + +crypto_mutex g_otp_mutex; + +#define kapi_otp_mutex_lock() do { \ + crypto_mutex_lock(&g_otp_mutex); \ +} while (0) + +#define kapi_otp_mutex_unlock() do { \ + crypto_mutex_unlock(&g_otp_mutex); \ +} while (0) + +td_s32 kapi_otp_init(td_void) +{ + td_s32 ret = TD_SUCCESS; + crypto_kapi_func_enter(); + + ret = crypto_mutex_init(&g_otp_mutex); + crypto_chk_print(ret != TD_SUCCESS, "crypto_mutex_init failed, ret is 0x%x\n", ret); + crypto_kapi_func_exit(); + + return ret; +} + +td_s32 kapi_otp_deinit(td_void) +{ + crypto_kapi_func_enter(); + crypto_mutex_destroy(&g_otp_mutex); + crypto_kapi_func_exit(); + return TD_SUCCESS; +} + +td_s32 kapi_otp_read_word(td_u32 offset, td_u32 *data) +{ + td_s32 ret = TD_SUCCESS; + crypto_kapi_func_enter(); + + kapi_otp_mutex_lock(); + ret = drv_otp_read_word(offset, data); + crypto_chk_print(ret != TD_SUCCESS, "drv_otp_read_word failed, ret is 0x%x\n", ret); + kapi_otp_mutex_unlock(); + + crypto_kapi_func_exit(); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_otp_read_word); + +td_s32 kapi_otp_read_byte(td_u32 offset, td_u8 *data) +{ + td_s32 ret = TD_SUCCESS; + crypto_kapi_func_enter(); + + kapi_otp_mutex_lock(); + ret = drv_otp_read_byte(offset, data); + crypto_chk_print(ret != TD_SUCCESS, "drv_otp_read_byte failed, ret is 0x%x\n", ret); + kapi_otp_mutex_unlock(); + + crypto_kapi_func_exit(); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_otp_read_byte); + +td_s32 kapi_otp_write_byte(td_u32 offset, td_u8 data) +{ + td_s32 ret = TD_SUCCESS; + crypto_kapi_func_enter(); + + kapi_otp_mutex_lock(); + ret = drv_otp_write_byte(offset, data); + crypto_chk_print(ret != TD_SUCCESS, "drv_otp_write_byte failed, ret is 0x%x\n", ret); + kapi_otp_mutex_unlock(); + + crypto_kapi_func_exit(); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_otp_write_byte); \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/kapi_code/kapi_pke.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/kapi_code/kapi_pke.c new file mode 100644 index 00000000..f77a3e56 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/kapi_code/kapi_pke.c @@ -0,0 +1,281 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "kapi_pke.h" +#include "drv_pke.h" +#include "crypto_hash_struct.h" +#include "crypto_drv_common.h" +#include "kapi_inner.h" + +crypto_mutex g_pke_mutex; + +#define kapi_pke_mutex_lock() do { \ + crypto_mutex_lock(&g_pke_mutex); \ +} while (0) + +#define kapi_pke_mutex_unlock() do { \ + crypto_mutex_unlock(&g_pke_mutex); \ +} while (0) + +td_s32 kapi_cipher_pke_env_init(td_void) +{ + td_s32 ret = TD_SUCCESS; + + ret = drv_cipher_pke_init(); + if (ret != TD_SUCCESS) { + crypto_log_err("drv_cipher_hash_init failed\n"); + return ret; + } + ret = crypto_mutex_init(&g_pke_mutex); + if (ret != TD_SUCCESS) { + crypto_log_err("crypto_mutex_init failed\n"); + goto error_hash_deinit; + } + return ret; + +error_hash_deinit: + drv_cipher_pke_deinit(); + return ret; +} + +td_s32 kapi_cipher_pke_env_deinit(td_void) +{ + td_s32 ret = TD_SUCCESS; + crypto_mutex_destroy(&g_pke_mutex); + drv_cipher_pke_deinit(); + return ret; +} + +td_s32 kapi_cipher_pke_mod(const drv_pke_data *a, const drv_pke_data *p, const drv_pke_data *c) +{ + td_s32 ret = TD_SUCCESS; + + kapi_pke_mutex_lock(); + ret = drv_cipher_pke_lock_secure(); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_pke_lock_secure failed, ret is 0x%x\n", ret); + ret = drv_cipher_pke_mod(a, p, c); + crypto_chk_goto(ret != TD_SUCCESS, unlock_exit, "drv_cipher_pke_mod failed, ret is 0x%x\n", ret); + +unlock_exit: + (void)drv_cipher_pke_unlock_secure(); + kapi_pke_mutex_unlock(); + + return ret; +} + +td_s32 kapi_cipher_pke_exp_mod(const drv_pke_data *n, const drv_pke_data *k, + const drv_pke_data *in, const drv_pke_data *out) +{ + td_s32 ret = TD_SUCCESS; + kapi_pke_mutex_lock(); + ret = drv_cipher_pke_lock_secure(); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_pke_lock_secure failed, ret is 0x%x\n", ret); + ret = drv_cipher_pke_exp_mod(n, k, in, out); + crypto_chk_goto(ret != TD_SUCCESS, unlock_exit, "drv_cipher_pke_exp_mod failed, ret is 0x%x\n", ret); + +unlock_exit: + (void)drv_cipher_pke_unlock_secure(); + kapi_pke_mutex_unlock(); + + return ret; +} + +td_s32 kapi_pke_ecc_gen_key(drv_pke_ecc_curve_type curve_type, const drv_pke_data *input_priv_key, + const drv_pke_data *output_priv_key, const drv_pke_ecc_point *output_pub_key) +{ + td_s32 ret = TD_SUCCESS; + + kapi_pke_mutex_lock(); + ret = drv_cipher_pke_ecc_gen_key(curve_type, input_priv_key, output_priv_key, output_pub_key); + crypto_chk_goto(ret != TD_SUCCESS, unlock_exit, "drv_cipher_pke_ecc_gen_key failed, ret is 0x%x\n", ret); + +unlock_exit: + kapi_pke_mutex_unlock(); + + return ret; +} + +td_s32 kapi_pke_ecdsa_sign(drv_pke_ecc_curve_type curve_type, const drv_pke_data *priv_key, + const drv_pke_data *hash, const drv_pke_ecc_sig *sig) +{ + td_s32 ret = TD_SUCCESS; + + kapi_pke_mutex_lock(); + ret = drv_cipher_pke_ecdsa_sign(curve_type, priv_key, hash, sig); + crypto_chk_goto(ret != TD_SUCCESS, unlock_exit, "drv_cipher_pke_ecdsa_sign failed, ret is 0x%x\n", ret); + +unlock_exit: + kapi_pke_mutex_unlock(); + return ret; +} + +td_s32 kapi_pke_ecdsa_verify(drv_pke_ecc_curve_type curve_type, const drv_pke_ecc_point *pub_key, + const drv_pke_data *hash, const drv_pke_ecc_sig *sig) +{ + td_s32 ret = TD_SUCCESS; + + kapi_pke_mutex_lock(); + ret = drv_cipher_pke_ecdsa_verify(curve_type, pub_key, hash, sig); + crypto_chk_goto(ret != TD_SUCCESS, unlock_exit, "drv_cipher_pke_ecdsa_verify failed, ret is 0x%x\n", ret); + +unlock_exit: + kapi_pke_mutex_unlock(); + return ret; +} + +td_s32 kapi_pke_eddsa_sign(drv_pke_ecc_curve_type curve_type, const drv_pke_data *priv_key, + const drv_pke_msg *msg, const drv_pke_ecc_sig *sig) +{ + td_s32 ret = TD_SUCCESS; + + kapi_pke_mutex_lock(); + ret = drv_cipher_pke_eddsa_sign(curve_type, priv_key, msg, sig); + crypto_chk_goto(ret != TD_SUCCESS, unlock_exit, "drv_cipher_pke_eddsa_sign failed, ret is 0x%x\n", ret); + +unlock_exit: + kapi_pke_mutex_unlock(); + return ret; +} + +td_s32 kapi_pke_eddsa_verify(drv_pke_ecc_curve_type curve_type, const drv_pke_ecc_point *pub_key, + const drv_pke_msg *msg, const drv_pke_ecc_sig *sig) +{ + td_s32 ret = TD_SUCCESS; + + kapi_pke_mutex_lock(); + ret = drv_cipher_pke_eddsa_verify(curve_type, pub_key, msg, sig); + crypto_chk_goto(ret != TD_SUCCESS, unlock_exit, "drv_cipher_pke_eddsa_verify failed, ret is 0x%x\n", ret); + +unlock_exit: + kapi_pke_mutex_unlock(); + return ret; +} + +td_s32 kapi_pke_ecc_gen_ecdh_key(drv_pke_ecc_curve_type curve_type, const drv_pke_ecc_point *input_pub_key, + const drv_pke_data *input_priv_key, const drv_pke_data *output_shared_key) +{ + td_s32 ret = TD_SUCCESS; + + kapi_pke_mutex_lock(); + ret = drv_cipher_pke_ecc_gen_ecdh_key(curve_type, input_pub_key, input_priv_key, output_shared_key); + crypto_chk_goto(ret != TD_SUCCESS, unlock_exit, "drv_cipher_pke_ecc_gen_ecdh_key failed, ret is 0x%x\n", ret); + +unlock_exit: + kapi_pke_mutex_unlock(); + return ret; +} + +td_s32 kapi_pke_check_dot_on_curve(drv_pke_ecc_curve_type curve_type, const drv_pke_ecc_point *pub_key, + td_bool *is_on_curve) +{ + td_s32 ret = TD_SUCCESS; + + kapi_pke_mutex_lock(); + ret = drv_cipher_pke_check_dot_on_curve(curve_type, pub_key, is_on_curve); + crypto_chk_goto(ret != TD_SUCCESS, unlock_exit, "drv_pke_check_don_curve failed, ret is 0x%x\n", ret); + +unlock_exit: + kapi_pke_mutex_unlock(); + return ret; +} + +td_s32 kapi_pke_sm2_dsa_hash(const drv_pke_data *sm2_id, const drv_pke_ecc_point *pub_key, + const drv_pke_msg *msg, drv_pke_data *hash) +{ + td_s32 ret = TD_SUCCESS; + + kapi_pke_mutex_lock(); + ret = drv_cipher_pke_sm2_dsa_hash(sm2_id, pub_key, msg, hash); + crypto_chk_goto(ret != TD_SUCCESS, unlock_exit, "drv_cipher_pke_sm2_dsa_hash failed, ret is 0x%x\n", ret); + +unlock_exit: + kapi_pke_mutex_unlock(); + return ret; +} + +td_s32 kapi_pke_sm2_public_encrypt(const drv_pke_ecc_point *pub_key, const drv_pke_data *plain_text, + drv_pke_data *cipher_text) +{ + td_s32 ret = TD_SUCCESS; + + kapi_pke_mutex_lock(); + ret = drv_cipher_pke_sm2_public_encrypt(pub_key, plain_text, cipher_text); + crypto_chk_goto(ret != TD_SUCCESS, unlock_exit, "drv_cipher_pke_sm2_public_encrypt failed, ret is 0x%x\n", ret); +unlock_exit: + kapi_pke_mutex_unlock(); + return ret; +} + +td_s32 kapi_pke_sm2_private_decrypt(const drv_pke_data *priv_key, const drv_pke_data *cipher_text, + drv_pke_data *plain_text) +{ + td_s32 ret = TD_SUCCESS; + + kapi_pke_mutex_lock(); + ret = drv_cipher_pke_sm2_private_decrypt(priv_key, cipher_text, plain_text); + crypto_chk_goto(ret != TD_SUCCESS, unlock_exit, "drv_cipher_pke_sm2_private_decrypt failed, ret is 0x%x\n", ret); +unlock_exit: + kapi_pke_mutex_unlock(); + return ret; +} + +/* RSA. */ +td_s32 kapi_pke_rsa_sign(const drv_pke_rsa_priv_key *priv_key, drv_pke_rsa_scheme scheme, + drv_pke_hash_type hash_type, const drv_pke_data *input_hash, + drv_pke_data *sign) +{ + td_s32 ret = TD_SUCCESS; + + kapi_pke_mutex_lock(); + ret = drv_cipher_pke_rsa_sign(priv_key, scheme, hash_type, input_hash, sign); + crypto_chk_goto(ret != TD_SUCCESS, unlock_exit, "drv_cipher_pke_rsa_sign failed, ret is 0x%x\n", ret); + +unlock_exit: + kapi_pke_mutex_unlock(); + return ret; +} + +td_s32 kapi_pke_rsa_verify(const drv_pke_rsa_pub_key *pub_key, drv_pke_rsa_scheme scheme, + drv_pke_hash_type hash_type, drv_pke_data *input_hash, const drv_pke_data *sig) +{ + td_s32 ret = TD_SUCCESS; + + kapi_pke_mutex_lock(); + ret = drv_cipher_pke_rsa_verify(pub_key, scheme, hash_type, input_hash, sig); + crypto_chk_goto(ret != TD_SUCCESS, unlock_exit, "drv_cipher_pke_rsa_verify failed, ret is 0x%x\n", ret); + +unlock_exit: + kapi_pke_mutex_unlock(); + return ret; +} + +td_s32 kapi_pke_rsa_public_encrypt(drv_pke_rsa_scheme scheme, drv_pke_hash_type hash_type, + const drv_pke_rsa_pub_key *pub_key, const drv_pke_data *input, const drv_pke_data *label, + drv_pke_data *output) +{ + td_s32 ret = TD_SUCCESS; + + kapi_pke_mutex_lock(); + ret = drv_cipher_pke_rsa_public_encrypt(scheme, hash_type, pub_key, input, label, output); + crypto_chk_goto(ret != TD_SUCCESS, unlock_exit, "drv_cipher_pke_rsa_public_encrypt failed, ret is 0x%x\n", ret); + +unlock_exit: + kapi_pke_mutex_unlock(); + return ret; +} + +td_s32 kapi_pke_rsa_private_decrypt(drv_pke_rsa_scheme scheme, drv_pke_hash_type hash_type, + const drv_pke_rsa_priv_key *priv_key, const drv_pke_data *input, const drv_pke_data *label, + drv_pke_data *output) +{ + td_s32 ret = TD_SUCCESS; + + kapi_pke_mutex_lock(); + ret = drv_cipher_pke_rsa_private_decrypt(scheme, hash_type, priv_key, input, label, output); + crypto_chk_goto(ret != TD_SUCCESS, unlock_exit, "drv_cipher_pke_rsa_private_decrypt failed, ret is 0x%x\n", ret); + +unlock_exit: + kapi_pke_mutex_unlock(); + return ret; +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/kapi_code/kapi_symc.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/kapi_code/kapi_symc.c new file mode 100644 index 00000000..b1e30d74 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/kapi_code/kapi_symc.c @@ -0,0 +1,1216 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "kapi_symc.h" +#include "kapi_inner.h" +#include "drv_symc.h" +#include "drv_inner.h" +#include "crypto_drv_common.h" + +#define CRYPTO_KAPI_DMA_SIZE_ONE_PROCESS (CRYPTO_DRV_AAD_SIZE * CRYPTO_SYMC_VIRT_CHN_NUM) +#define CRYPTO_KAPI_TOTAL_DMA_SIZE (CRYPTO_KAPI_DMA_SIZE_ONE_PROCESS * MAX_PROCESS_NUM) +#define CRYPTO_SYMC_INIT_MAX_NUM 0xffffffff + +static td_u8 *g_kapi_dma_addr = TD_NULL; + +typedef struct { + td_bool is_open; + td_bool is_long_term; + td_bool is_mac; + td_bool is_multi_pack; + td_u32 tid; + td_handle drv_symc_handle; + crypto_symc_attr symc_attr; + td_handle keyslot_handle; + td_bool is_attached; + td_bool is_set_config; + td_u8 *aad_buf; + td_u32 aad_buf_size; + crypto_symc_ctrl_t symc_ctrl; + crypto_symc_config_aes_ccm_gcm ccm_gcm_config; + crypto_symc_mac_attr mac_attr; + crypto_symc_mac_ctx mac_ctx; + /* The length should be processed. */ + td_u32 data_length; + /* The length has been processd. */ + td_u32 processed_length; + /* iv_mac for ccm, iv_ghash for gcm. */ + td_u8 iv_mac[16]; + /* s0 for ccm, j0 for gcm. */ + td_u8 iv0[16]; +#if defined(CRYPTO_CTR_NON_ALIGN_SUPPORT) + td_u32 ctr_offset; + td_u8 ctr_last_block[CRYPTO_AES_BLOCK_SIZE_IN_BYTES]; +#endif +} crypto_kapi_symc_ctx; + +typedef struct { + crypto_owner owner; + crypto_kapi_symc_ctx symc_ctx_list[CRYPTO_SYMC_VIRT_CHN_NUM]; + crypto_mutex symc_ctx_mutex[CRYPTO_SYMC_VIRT_CHN_NUM]; + td_u32 ctx_num; + td_bool is_used; + td_u32 init_counter; + td_u8 *dma_addr; +} crypto_kapi_symc_process; + +static crypto_kapi_symc_process g_kapi_symc_channel[MAX_PROCESS_NUM]; + +static crypto_mutex g_symc_mutex; + +#define kapi_symc_lock() do { \ + crypto_mutex_lock(&g_symc_mutex); \ +} while (0) +#define kapi_symc_unlock() do { \ + crypto_mutex_unlock(&g_symc_mutex); \ +} while (0) + +#define SYMC_COMPAT_ERRNO(err_code) KAPI_COMPAT_ERRNO(ERROR_MODULE_SYMC, err_code) +#define symc_null_ptr_chk(ptr) \ + crypto_chk_return((ptr) == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), #ptr" is NULL\n") + +static td_s32 priv_symc_handle_check(td_handle kapi_symc_handle) +{ + crypto_chk_return(kapi_get_module_id(kapi_symc_handle) != KAPI_SYMC_MODULE_ID, + SYMC_COMPAT_ERRNO(ERROR_INVALID_HANDLE), "Invalid Symc Handle! 0x%x\n", kapi_symc_handle); + crypto_chk_return(kapi_get_ctx_idx(kapi_symc_handle) >= CRYPTO_SYMC_VIRT_CHN_NUM, \ + SYMC_COMPAT_ERRNO(ERROR_INVALID_HANDLE), "Invalid Symc Handle! 0x%x\n", kapi_symc_handle); + return TD_SUCCESS; +} + +static crypto_kapi_symc_process *priv_get_current_symc_channel(td_void) +{ + td_u32 i; + crypto_owner owner; + if (crypto_get_owner(&owner) != CRYPTO_SUCCESS) { + return TD_NULL; + } + for (i = 0; i < MAX_PROCESS_NUM; i++) { + if (memcmp(&owner, &g_kapi_symc_channel[i].owner, sizeof(crypto_owner)) == 0 && + g_kapi_symc_channel[i].is_used == TD_TRUE) { + return &g_kapi_symc_channel[i]; + } + } + return TD_NULL; +} + +static crypto_kapi_symc_ctx *priv_occupy_symc_soft_chn(crypto_kapi_symc_process *symc_channel, td_u32 *idx) +{ + td_u32 i; + td_u32 tid = crypto_gettid(); + crypto_kapi_symc_ctx *symc_ctx_list = TD_NULL; + crypto_kapi_symc_ctx *symc_ctx = TD_NULL; + + kapi_symc_lock(); + + symc_ctx_list = symc_channel->symc_ctx_list; + for (i = 0; i < CRYPTO_SYMC_VIRT_CHN_NUM; i++) { + if (symc_ctx_list[i].is_open == TD_FALSE) { + break; + } + } + if (i >= CRYPTO_SYMC_VIRT_CHN_NUM) { + crypto_log_err("All Symc Channels are busy!\n"); + goto exit_unlock; + } + symc_ctx = &symc_channel->symc_ctx_list[i]; + (td_void)memset_s(symc_ctx, sizeof(crypto_kapi_symc_ctx), 0, sizeof(crypto_kapi_symc_ctx)); + symc_ctx->is_open = TD_TRUE; + symc_ctx->tid = tid; + + *idx = i; + +exit_unlock: + kapi_symc_unlock(); + return symc_ctx; +} + +static td_void priv_release_symc_soft_chn(crypto_kapi_symc_ctx *symc_ctx) +{ + kapi_symc_lock(); + (td_void)memset_s(symc_ctx, sizeof(crypto_kapi_symc_ctx), 0, sizeof(crypto_kapi_symc_ctx)); + kapi_symc_unlock(); +} + +static td_bool priv_check_is_init(crypto_owner *owner) +{ + td_u32 i; + for (i = 0; i < MAX_PROCESS_NUM; i++) { + if (memcmp(owner, &g_kapi_symc_channel[i].owner, sizeof(crypto_owner)) == 0) { + return TD_TRUE; + } + } + return TD_FALSE; +} + +static td_s32 priv_process_symc_init(td_void) +{ + td_u32 i; + td_u32 ret = TD_SUCCESS; + crypto_owner owner; + crypto_kapi_symc_process *symc_channel = TD_NULL; + + crypto_kapi_func_enter(); + kapi_symc_lock(); + ret = crypto_get_owner(&owner); + crypto_chk_goto_with_ret(ret != CRYPTO_SUCCESS, exit_unlock, SYMC_COMPAT_ERRNO(ERROR_GET_OWNER), + "crypto_get_owner failed\n"); + if (priv_check_is_init(&owner) == TD_TRUE) { + symc_channel = priv_get_current_symc_channel(); + if (symc_channel->init_counter >= CRYPTO_SYMC_INIT_MAX_NUM) { + ret = SYMC_COMPAT_ERRNO(ERROR_COUNT_OVERFLOW); + } else { + ret = TD_SUCCESS; + ++(symc_channel->init_counter); + } + goto exit_unlock; + } + for (i = 0; i < MAX_PROCESS_NUM; i++) { + if (g_kapi_symc_channel[i].is_used == TD_FALSE) { + break; + } + } + if (i >= MAX_PROCESS_NUM) { + crypto_log_err("Process Num is More Than %u\n", MAX_PROCESS_NUM); + ret = SYMC_COMPAT_ERRNO(ERROR_MAX_PROCESS); + goto exit_unlock; + } + symc_channel = &g_kapi_symc_channel[i]; + (td_void)memset_s(symc_channel, sizeof(crypto_kapi_symc_process), 0, sizeof(crypto_kapi_symc_process)); + /* Alloc dma memory. */ + symc_channel->dma_addr = g_kapi_dma_addr + i * CRYPTO_KAPI_DMA_SIZE_ONE_PROCESS; + for (i = 0; i < CRYPTO_SYMC_VIRT_CHN_NUM; ++i) { + ret = crypto_mutex_init(&symc_channel->symc_ctx_mutex[i]); + crypto_chk_goto_with_ret(ret != TD_SUCCESS, exit_destroy, SYMC_COMPAT_ERRNO(ERROR_MUTEX_INIT), + "symc ctx mutex init failed at chn: %u\n", i); + } + (td_void)memcpy_s(&symc_channel->owner, sizeof(crypto_owner), &owner, sizeof(crypto_owner)); + symc_channel->is_used = TD_TRUE; + symc_channel->ctx_num = CRYPTO_SYMC_VIRT_CHN_NUM; + ++(symc_channel->init_counter); + (td_void)memset_s(symc_channel->symc_ctx_list, sizeof(crypto_kapi_symc_ctx) * CRYPTO_SYMC_VIRT_CHN_NUM, + 0, sizeof(crypto_kapi_symc_ctx) * CRYPTO_SYMC_VIRT_CHN_NUM); + kapi_symc_unlock(); + + crypto_kapi_func_exit(); + return ret; + +exit_destroy: + for (i = 0; i < CRYPTO_SYMC_VIRT_CHN_NUM; ++i) { + crypto_mutex_destroy(&symc_channel->symc_ctx_mutex[i]); + } +exit_unlock: + kapi_symc_unlock(); + crypto_kapi_func_exit(); + return ret; +} + +static td_s32 priv_drv_lock_create(crypto_kapi_symc_ctx *symc_ctx, const crypto_symc_attr *symc_attr) +{ + td_s32 ret = TD_SUCCESS; + kapi_symc_lock(); + ret = drv_cipher_symc_create(&symc_ctx->drv_symc_handle, symc_attr); + kapi_symc_unlock(); + return ret; +} + +static td_void priv_drv_lock_destroy(td_handle drv_symc_handle) +{ + kapi_symc_lock(); + (td_void)drv_cipher_symc_destroy(drv_symc_handle); + kapi_symc_unlock(); +} + +static td_s32 priv_drv_lock_mac_start(td_handle *kapi_symc_handle, const crypto_symc_mac_attr *mac_attr) +{ + td_s32 ret = TD_SUCCESS; + kapi_symc_lock(); + ret = drv_cipher_mac_start(kapi_symc_handle, mac_attr); + kapi_symc_unlock(); + return ret; +} + +static td_s32 priv_drv_lock_mac_finish(td_handle kapi_symc_handle, td_u8 *mac, td_u32 *mac_length) +{ + td_s32 ret; + kapi_symc_lock(); + ret = drv_cipher_mac_finish(kapi_symc_handle, mac, mac_length); + kapi_symc_unlock(); + return ret; +} + +static td_void priv_process_release(crypto_kapi_symc_process *symc_channel) +{ + td_u32 i; + for (i = 0; i < CRYPTO_SYMC_VIRT_CHN_NUM; ++i) { + crypto_mutex_destroy(&symc_channel->symc_ctx_mutex[i]); + if (symc_channel->symc_ctx_list[i].is_open == TD_TRUE && \ + symc_channel->symc_ctx_list[i].is_long_term == TD_TRUE) { + (td_void)drv_cipher_symc_destroy(symc_channel->symc_ctx_list[i].drv_symc_handle); + } + } + (td_void)memset_s(symc_channel, sizeof(crypto_kapi_symc_process), 0, sizeof(crypto_kapi_symc_process)); +} + +static td_void priv_process_symc_deinit(td_void) +{ + crypto_kapi_symc_process *symc_channel = TD_NULL; + crypto_kapi_func_enter(); + kapi_symc_lock(); + symc_channel = priv_get_current_symc_channel(); + if (symc_channel == TD_NULL) { + kapi_symc_unlock(); + return; + } + if (symc_channel->init_counter > 1) { + --(symc_channel->init_counter); + kapi_symc_unlock(); + return; + } + priv_process_release(symc_channel); + kapi_symc_unlock(); + crypto_kapi_func_exit(); +} + +td_void kapi_cipher_symc_process_release(td_void) +{ + crypto_kapi_symc_process *symc_channel = TD_NULL; + crypto_kapi_func_enter(); + kapi_symc_lock(); + symc_channel = priv_get_current_symc_channel(); + if (symc_channel == TD_NULL) { + kapi_symc_unlock(); + return; + } + priv_process_release(symc_channel); + kapi_symc_unlock(); + crypto_kapi_func_exit(); +} + +td_s32 kapi_cipher_symc_env_init(td_void) +{ + td_s32 ret = TD_SUCCESS; + crypto_kapi_func_enter(); + ret = drv_cipher_symc_init(); + if (ret != TD_SUCCESS) { + crypto_log_err("drv_cipher_symc_init failed\n"); + return ret; + } + + (td_void)memset_s(&g_kapi_symc_channel, sizeof(g_kapi_symc_channel), 0, sizeof(g_kapi_symc_channel)); + ret = crypto_mutex_init(&g_symc_mutex); + if (ret != TD_SUCCESS) { + crypto_log_err("crypto_mutex_init failed\n"); + ret = SYMC_COMPAT_ERRNO(ERROR_MUTEX_INIT); + goto error_symc_deinit; + } + + g_kapi_dma_addr = crypto_malloc_coherent(CRYPTO_KAPI_TOTAL_DMA_SIZE, "cipher_symc_kapi"); + crypto_chk_goto_with_ret(g_kapi_dma_addr == TD_NULL, error_symc_deinit, SYMC_COMPAT_ERRNO(ERROR_MALLOC), + "crypto_malloc_coherent failed\n"); + + crypto_kapi_func_exit(); + return ret; + +error_symc_deinit: + drv_cipher_symc_deinit(); + return ret; +} + +td_s32 kapi_cipher_symc_env_deinit(td_void) +{ + td_u32 i, j; + crypto_kapi_symc_process *symc_channel = TD_NULL; + crypto_kapi_symc_ctx *symc_ctx = TD_NULL; + crypto_kapi_func_enter(); + + if (g_kapi_dma_addr != TD_NULL) { + (td_void)memset_s(g_kapi_dma_addr, CRYPTO_KAPI_TOTAL_DMA_SIZE, 0, CRYPTO_KAPI_TOTAL_DMA_SIZE); + crypto_free_coherent(g_kapi_dma_addr); + g_kapi_dma_addr = TD_NULL; + } + + /* release all the resource. */ + for (i = 0; i < MAX_PROCESS_NUM; i++) { + symc_channel = &g_kapi_symc_channel[i]; + if (symc_channel->is_used == TD_FALSE) { + continue; + } + for (j = 0; j < CRYPTO_SYMC_VIRT_CHN_NUM; j++) { + symc_ctx = &symc_channel->symc_ctx_list[j]; + if (symc_ctx->is_open == TD_FALSE) { + continue; + } + priv_release_symc_soft_chn(symc_ctx); + symc_ctx->is_open = TD_FALSE; + } + symc_channel->is_used = TD_FALSE; + } + crypto_mutex_destroy(&g_symc_mutex); + (td_void)memset_s(&g_kapi_symc_channel, sizeof(g_kapi_symc_channel), 0, sizeof(g_kapi_symc_channel)); + drv_cipher_symc_deinit(); + crypto_kapi_func_exit(); + return TD_SUCCESS; +} + +td_s32 kapi_cipher_symc_init(td_void) +{ + td_s32 ret = TD_SUCCESS; + crypto_kapi_func_enter(); + + ret = priv_process_symc_init(); + if (ret != TD_SUCCESS) { + crypto_log_err("symc priv_process_symc_init failed\n"); + return ret; + } + + crypto_kapi_func_exit(); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_cipher_symc_init); + +td_s32 kapi_cipher_symc_deinit(td_void) +{ + crypto_kapi_func_enter(); + priv_process_symc_deinit(); + crypto_kapi_func_exit(); + return TD_SUCCESS; +} +CRYPTO_EXPORT_SYMBOL(kapi_cipher_symc_deinit); + +td_s32 kapi_cipher_symc_create(td_handle *kapi_symc_handle, const crypto_symc_attr *symc_attr) +{ + td_s32 ret = TD_SUCCESS; + crypto_kapi_symc_process *symc_channel = TD_NULL; + crypto_kapi_symc_ctx *symc_ctx = TD_NULL; + td_u32 idx; + + crypto_kapi_func_enter(); + symc_null_ptr_chk(kapi_symc_handle); + symc_null_ptr_chk(symc_attr); + + symc_channel = priv_get_current_symc_channel(); + crypto_chk_return(symc_channel == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_NOT_INIT), "call init first!\n"); + + symc_ctx = priv_occupy_symc_soft_chn(symc_channel, &idx); + crypto_chk_return(symc_ctx == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_CHN_BUSY), "all symc soft chns are busy\n"); + crypto_chk_return(symc_ctx->is_open == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_CTX_CLOSED), "ctx is closed\n"); + + crypto_mutex_lock(&symc_channel->symc_ctx_mutex[idx]); + + if (symc_attr->is_long_term == TD_TRUE) { + ret = priv_drv_lock_create(symc_ctx, symc_attr); + crypto_chk_goto(ret != TD_SUCCESS, error_unlock_symc_ctx, "drv_cipher_symc_create failed, ret is 0x%x\n", ret); + } + ret = memcpy_s(&symc_ctx->symc_attr, sizeof(crypto_symc_attr), symc_attr, sizeof(crypto_symc_attr)); + crypto_chk_goto_with_ret(ret != EOK, error_unlock_symc_ctx, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + symc_ctx->is_long_term = symc_attr->is_long_term; + + symc_ctx->aad_buf = symc_channel->dma_addr + idx * CRYPTO_DRV_AAD_SIZE; + symc_ctx->aad_buf_size = CRYPTO_DRV_AAD_SIZE; + crypto_mutex_unlock(&symc_channel->symc_ctx_mutex[idx]); + *kapi_symc_handle = synthesize_kapi_handle(KAPI_SYMC_MODULE_ID, idx); + crypto_kapi_func_exit(); + return ret; + +error_unlock_symc_ctx: + priv_release_symc_soft_chn(symc_ctx); + crypto_mutex_unlock(&symc_channel->symc_ctx_mutex[idx]); + crypto_kapi_func_exit(); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_cipher_symc_create); + +td_s32 kapi_cipher_symc_destroy(td_handle kapi_symc_handle) +{ + td_s32 ret = TD_SUCCESS; + crypto_kapi_symc_process *symc_channel = TD_NULL; + crypto_kapi_symc_ctx *symc_ctx = TD_NULL; + td_u32 idx; + crypto_kapi_func_enter(); + + ret = priv_symc_handle_check(kapi_symc_handle); + crypto_chk_return(ret != TD_SUCCESS, ret, "priv_symc_handle_check failed, ret is 0x%x\n", ret); + + idx = kapi_get_ctx_idx(kapi_symc_handle); + symc_channel = priv_get_current_symc_channel(); + crypto_chk_return(symc_channel == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_NOT_INIT), "call init first!\n"); + + symc_ctx = &symc_channel->symc_ctx_list[idx]; + crypto_chk_return(symc_ctx->is_open == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_CTX_CLOSED), "ctx is closed\n"); + + crypto_mutex_lock(&symc_channel->symc_ctx_mutex[idx]); + + if (symc_ctx->is_long_term == TD_TRUE) { + priv_drv_lock_destroy(symc_ctx->drv_symc_handle); + } + priv_release_symc_soft_chn(symc_ctx); + crypto_mutex_unlock(&symc_channel->symc_ctx_mutex[idx]); + crypto_kapi_func_exit(); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_cipher_symc_destroy); + +/* used for CCM&GCM. */ +static td_s32 inner_symc_set_config_ex(crypto_kapi_symc_ctx *symc_ctx, + const crypto_symc_config_aes_ccm_gcm *ccm_gcm_config) +{ + td_s32 ret = TD_FAILURE; + symc_ctx->symc_ctrl.param = (void *)&symc_ctx->ccm_gcm_config; + symc_ctx->data_length = ccm_gcm_config->data_len; + (td_void)memcpy_s(&symc_ctx->ccm_gcm_config, sizeof(crypto_symc_config_aes_ccm_gcm), + ccm_gcm_config, sizeof(crypto_symc_config_aes_ccm_gcm)); + if (ccm_gcm_config->aad_len != 0) { + crypto_chk_return(ccm_gcm_config->aad_buf.virt_addr == TD_NULL, + SYMC_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "aad_virt is NULL\n"); + crypto_chk_return(symc_ctx->aad_buf == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_UNEXPECTED), "unexpected error\n"); + + ret = memcpy_s(symc_ctx->aad_buf, symc_ctx->aad_buf_size, + ccm_gcm_config->aad_buf.virt_addr, ccm_gcm_config->aad_len); + crypto_chk_return(ret != EOK, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + symc_ctx->ccm_gcm_config.aad_buf.virt_addr = symc_ctx->aad_buf; + symc_ctx->ccm_gcm_config.aad_buf.phys_addr = crypto_get_phys_addr(symc_ctx->aad_buf); + } + return TD_SUCCESS; +} + +td_s32 kapi_cipher_symc_set_config(td_handle kapi_symc_handle, const crypto_symc_ctrl_t *symc_ctrl) +{ + td_s32 ret; + crypto_kapi_symc_process *symc_channel = TD_NULL; + crypto_kapi_symc_ctx *symc_ctx = TD_NULL; + crypto_symc_config_aes_ccm_gcm *ccm_gcm_config = TD_NULL; + td_u32 idx; + crypto_kapi_func_enter(); + + symc_null_ptr_chk(symc_ctrl); + + ret = priv_symc_handle_check(kapi_symc_handle); + crypto_chk_return(ret != TD_SUCCESS, ret, "priv_symc_handle_check failed, ret is 0x%x\n", ret); + + idx = kapi_get_ctx_idx(kapi_symc_handle); + symc_channel = priv_get_current_symc_channel(); + crypto_chk_return(symc_channel == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_NOT_INIT), "call init first!\n"); + + symc_ctx = &symc_channel->symc_ctx_list[idx]; + crypto_chk_return(symc_ctx->is_open == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_CTX_CLOSED), "ctx is closed\n"); + + crypto_mutex_lock(&symc_channel->symc_ctx_mutex[idx]); + + (td_void)memset_s(&symc_ctx->ccm_gcm_config, sizeof(crypto_symc_config_aes_ccm_gcm), 0, + sizeof(crypto_symc_config_aes_ccm_gcm)); + (td_void)memcpy_s(&symc_ctx->symc_ctrl, sizeof(crypto_symc_ctrl_t), symc_ctrl, sizeof(crypto_symc_ctrl_t)); + + if (symc_ctrl->work_mode == CRYPTO_SYMC_WORK_MODE_CCM || symc_ctrl->work_mode == CRYPTO_SYMC_WORK_MODE_GCM) { + ccm_gcm_config = symc_ctrl->param; + crypto_chk_goto_with_ret(ccm_gcm_config == TD_NULL, unlock_exit, SYMC_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), + "ccm_gcm_config is NULL\n"); + + ret = inner_symc_set_config_ex(symc_ctx, ccm_gcm_config); + crypto_chk_goto(ret != TD_SUCCESS, unlock_exit, "inner_symc_set_config_ex failed\n"); + } + if (symc_ctx->is_long_term == TD_TRUE) { + ret = drv_cipher_symc_set_config(symc_ctx->drv_symc_handle, &symc_ctx->symc_ctrl); + crypto_chk_goto(ret != TD_SUCCESS, unlock_exit, "drv_cipher_symc_set_config failed\n"); + } else { + ret = inner_symc_cfg_param_check(symc_ctrl); + crypto_chk_goto(ret != TD_SUCCESS, unlock_exit, "inner_symc_cfg_param_check failed\n"); + } + +#if defined(CRYPTO_CTR_NON_ALIGN_SUPPORT) + symc_ctx->ctr_offset = 0; +#endif + symc_ctx->is_set_config = TD_TRUE; + +unlock_exit: + crypto_mutex_unlock(&symc_channel->symc_ctx_mutex[idx]); + crypto_kapi_func_exit(); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_cipher_symc_set_config); + +td_s32 kapi_cipher_symc_get_config(td_handle kapi_symc_handle, crypto_symc_ctrl_t *symc_ctrl) +{ + td_s32 ret; + crypto_kapi_symc_process *symc_channel = TD_NULL; + crypto_kapi_symc_ctx *symc_ctx = TD_NULL; + td_u32 idx; + crypto_kapi_func_enter(); + + symc_null_ptr_chk(symc_ctrl); + + ret = priv_symc_handle_check(kapi_symc_handle); + crypto_chk_return(ret != TD_SUCCESS, ret, "priv_symc_handle_check failed, ret is 0x%x\n", ret); + + idx = kapi_get_ctx_idx(kapi_symc_handle); + symc_channel = priv_get_current_symc_channel(); + crypto_chk_return(symc_channel == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_NOT_INIT), "call init first\n"); + + symc_ctx = &symc_channel->symc_ctx_list[idx]; + crypto_chk_return(symc_ctx->is_open == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_CTX_CLOSED), "ctx is closed\n"); + crypto_chk_return(symc_ctx->is_set_config == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_NOT_SET_CONFIG), + "set config first\n"); + + crypto_mutex_lock(&symc_channel->symc_ctx_mutex[idx]); + + if (symc_ctx->is_long_term == TD_TRUE) { + ret = drv_cipher_symc_get_config(symc_ctx->drv_symc_handle, &symc_ctx->symc_ctrl); + crypto_chk_goto(ret != TD_SUCCESS, unlock_exit, "drv_cipher_symc_get_config failed\n"); + } + (td_void)memcpy_s(symc_ctrl, sizeof(crypto_symc_ctrl_t), &symc_ctx->symc_ctrl, sizeof(crypto_symc_ctrl_t)); + if (symc_ctrl->work_mode == CRYPTO_SYMC_WORK_MODE_CCM || symc_ctrl->work_mode == CRYPTO_SYMC_WORK_MODE_GCM) { + crypto_chk_goto_with_ret(symc_ctrl->param == TD_NULL, unlock_exit, SYMC_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), + "symc_ctrl->param is null\n"); + (td_void)memcpy_s(symc_ctrl->param, sizeof(crypto_symc_config_aes_ccm_gcm), + &symc_ctx->ccm_gcm_config, sizeof(crypto_symc_config_aes_ccm_gcm)); + } + +unlock_exit: + crypto_mutex_unlock(&symc_channel->symc_ctx_mutex[idx]); + crypto_kapi_func_exit(); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_cipher_symc_get_config); + +td_s32 kapi_cipher_symc_attach(td_handle kapi_symc_handle, td_handle keyslot_handle) +{ + td_s32 ret = TD_SUCCESS; + crypto_kapi_symc_process *symc_channel = TD_NULL; + crypto_kapi_symc_ctx *symc_ctx = TD_NULL; + td_u32 idx; + crypto_kapi_func_enter(); + + ret = priv_symc_handle_check(kapi_symc_handle); + crypto_chk_return(ret != TD_SUCCESS, ret, "priv_symc_handle_check failed, ret is 0x%x\n", ret); + + idx = kapi_get_ctx_idx(kapi_symc_handle); + + symc_channel = priv_get_current_symc_channel(); + crypto_chk_return(symc_channel == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_NOT_INIT), "call init first\n"); + + symc_ctx = &symc_channel->symc_ctx_list[idx]; + crypto_chk_return(symc_ctx->is_open == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_CTX_CLOSED), "ctx is closed\n"); + + crypto_mutex_lock(&symc_channel->symc_ctx_mutex[idx]); + + if (symc_ctx->is_long_term == TD_TRUE) { + ret = drv_cipher_symc_attach(symc_ctx->drv_symc_handle, keyslot_handle); + crypto_chk_goto(ret != TD_SUCCESS, unlock_exit, "drv_cipher_symc_attach failed, ret is 0x%x\n", ret); + } + symc_ctx->keyslot_handle = keyslot_handle; + symc_ctx->is_attached = TD_TRUE; + +unlock_exit: + crypto_mutex_unlock(&symc_channel->symc_ctx_mutex[idx]); + crypto_kapi_func_exit(); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_cipher_symc_attach); + +static td_s32 inner_kapi_cipher_symc_crypto(td_handle symc_handle, + const crypto_buf_attr *src_buf, const crypto_buf_attr *dst_buf, td_u32 length, td_u32 crypto_type) +{ + td_s32 ret; + crypto_buf_attr drv_src_buf = {0}; + crypto_buf_attr drv_dst_buf = {0}; + + /* Transfer phys_addr from buf_attr. */ + drv_src_buf.phys_addr = crypto_osal_get_phys_addr(src_buf); + crypto_chk_goto_with_ret(drv_src_buf.phys_addr == 0, exit_put_phys_addr, SYMC_COMPAT_ERRNO(ERROR_GET_PHYS_ADDR), + "crypto_osal_get_phys_addr failed\n"); + drv_src_buf.buf_sec = src_buf->buf_sec; + drv_dst_buf.phys_addr = crypto_osal_get_phys_addr(dst_buf); + crypto_chk_goto_with_ret(drv_dst_buf.phys_addr == 0, exit_put_phys_addr, SYMC_COMPAT_ERRNO(ERROR_GET_PHYS_ADDR), + "crypto_osal_get_phys_addr failed\n"); + drv_dst_buf.buf_sec = dst_buf->buf_sec; + + switch (crypto_type) { + case CRYPTO_TYPE_ENCRYPT: + ret = drv_cipher_symc_encrypt(symc_handle, &drv_src_buf, &drv_dst_buf, length); + break; + case CRYPTO_TYPE_DECRYPT: + ret = drv_cipher_symc_decrypt(symc_handle, &drv_src_buf, &drv_dst_buf, length); + break; + default: + crypto_log_err("Invalid Crypto Type!\n"); + ret = SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM); + } + +exit_put_phys_addr: + if (drv_src_buf.phys_addr != 0) { + crypto_osal_put_phys_addr(src_buf, drv_src_buf.phys_addr); + } + if (drv_dst_buf.phys_addr != 0) { + crypto_osal_put_phys_addr(dst_buf, drv_dst_buf.phys_addr); + } + return ret; +} + +static td_s32 inner_kapi_symc_restore(crypto_kapi_symc_ctx *symc_ctx) +{ + td_s32 ret; + drv_symc_ex_context_t symc_ex_ctx = {0}; + + ret = drv_cipher_symc_attach(symc_ctx->drv_symc_handle, symc_ctx->keyslot_handle); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_symc_attach failed, ret is 0x%x\n", ret); + + ret = drv_cipher_symc_set_config(symc_ctx->drv_symc_handle, &symc_ctx->symc_ctrl); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_symc_set_config failed\n"); + + if (symc_ctx->processed_length == 0) { + ret = inner_drv_symc_get_iv0(symc_ctx->drv_symc_handle, symc_ctx->iv0, sizeof(symc_ctx->iv0)); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_drv_symc_get_iv0 failed\n"); + } + + symc_ex_ctx.iv0 = symc_ctx->iv0; + symc_ex_ctx.iv0_length = sizeof(symc_ctx->iv0); + symc_ex_ctx.iv_mac = symc_ctx->iv_mac; + symc_ex_ctx.iv_mac_length = sizeof(symc_ctx->iv_mac); + symc_ex_ctx.data_length = symc_ctx->data_length; + symc_ex_ctx.processed_length = symc_ctx->processed_length; + symc_ex_ctx.aad_len = symc_ctx->ccm_gcm_config.aad_len; + + ret = inner_drv_symc_ex_restore(symc_ctx->drv_symc_handle, &symc_ex_ctx); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_drv_symc_ex_restore failed\n"); + +#if defined(CRYPTO_CTR_NON_ALIGN_SUPPORT) + ret = inner_drv_symc_set_ctr_block(symc_ctx->drv_symc_handle, symc_ctx->ctr_last_block, + sizeof(symc_ctx->ctr_last_block), symc_ctx->ctr_offset); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_drv_symc_get_ctr_block failed\n"); +#endif + return ret; +} + +static td_s32 inner_kapi_symc_get_config(crypto_kapi_symc_ctx *symc_ctx) +{ + td_s32 ret; + + ret = inner_drv_symc_get_iv_mac(symc_ctx->drv_symc_handle, symc_ctx->iv_mac, sizeof(symc_ctx->iv_mac)); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_drv_symc_get_iv_mac failed\n"); + + ret = drv_cipher_symc_get_config(symc_ctx->drv_symc_handle, &symc_ctx->symc_ctrl); + crypto_chk_return(ret != TD_SUCCESS, ret, "drv_cipher_symc_get_config failed\n"); + +#if defined(CRYPTO_CTR_NON_ALIGN_SUPPORT) + ret = inner_drv_symc_get_ctr_block(symc_ctx->drv_symc_handle, symc_ctx->ctr_last_block, + sizeof(symc_ctx->ctr_last_block), &symc_ctx->ctr_offset); + crypto_chk_return(ret != TD_SUCCESS, ret, "inner_drv_symc_get_ctr_block failed\n"); +#endif + return ret; +} + +static td_s32 inner_kapi_symc_crypto_short_term(crypto_kapi_symc_ctx *symc_ctx, + const crypto_buf_attr *src_buf, const crypto_buf_attr *dst_buf, td_u32 length, td_u32 crypto_type) +{ + td_s32 ret; + + ret = priv_drv_lock_create(symc_ctx, &symc_ctx->symc_attr); + crypto_chk_return(ret != TD_SUCCESS, ret, "priv_drv_lock_create failed, ret is 0x%x\n", ret); + + ret = inner_kapi_symc_restore(symc_ctx); + crypto_chk_goto(ret != TD_SUCCESS, symc_destroy_exit, + "inner_kapi_symc_restore for crypto failed, ret is 0x%x\n", ret); + + ret = inner_kapi_cipher_symc_crypto(symc_ctx->drv_symc_handle, src_buf, dst_buf, length, crypto_type); + crypto_chk_goto(ret != TD_SUCCESS, symc_destroy_exit, + "inner_kapi_cipher_symc_crypto for crypto failed, ret is 0x%x\n", ret); + + ret = inner_kapi_symc_get_config(symc_ctx); + crypto_chk_goto(ret != TD_SUCCESS, symc_destroy_exit, + "inner_kapi_symc_get_config for crypto failed, ret is 0x%x\n", ret); + +symc_destroy_exit: + priv_drv_lock_destroy(symc_ctx->drv_symc_handle); + return ret; +} + +static td_s32 inner_kapi_symc_get_tag_short_term(crypto_kapi_symc_ctx *symc_ctx, td_u8 *tag, td_u32 tag_len) +{ + td_s32 ret; + + ret = priv_drv_lock_create(symc_ctx, &symc_ctx->symc_attr); + crypto_chk_return(ret != TD_SUCCESS, ret, "priv_drv_lock_create failed, ret is 0x%x\n", ret); + + ret = inner_kapi_symc_restore(symc_ctx); + crypto_chk_goto(ret != TD_SUCCESS, symc_destroy_exit, + "inner_kapi_symc_restore for crypto failed, ret is 0x%x\n", ret); + + crypto_log_dbg("processed_length is %d, data_len is %d\n", symc_ctx->processed_length, symc_ctx->data_length); + ret = drv_cipher_symc_get_tag(symc_ctx->drv_symc_handle, tag, tag_len); + crypto_chk_goto(ret != TD_SUCCESS, symc_destroy_exit, "drv_cipher_symc_get_tag failed\n"); + + ret = inner_kapi_symc_get_config(symc_ctx); + crypto_chk_goto(ret != TD_SUCCESS, symc_destroy_exit, + "inner_kapi_symc_get_config for crypto failed, ret is 0x%x\n", ret); + + symc_ctx->processed_length = 0; + +symc_destroy_exit: + priv_drv_lock_destroy(symc_ctx->drv_symc_handle); + return ret; +} + +static td_s32 kapi_cipher_symc_crypto(td_handle kapi_symc_handle, const crypto_buf_attr *src_buf, + const crypto_buf_attr *dst_buf, td_u32 length, td_u32 crypto_type) +{ + td_s32 ret; + crypto_kapi_symc_process *symc_channel = TD_NULL; + crypto_kapi_symc_ctx *symc_ctx = TD_NULL; + td_u32 idx; + + /* Handle Check. */ + ret = priv_symc_handle_check(kapi_symc_handle); + crypto_chk_return(ret != TD_SUCCESS, ret, "priv_symc_handle_check failed, ret is 0x%x\n", ret); + + symc_channel = priv_get_current_symc_channel(); + crypto_chk_return(symc_channel == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_NOT_INIT), "call init first\n"); + + idx = kapi_get_ctx_idx(kapi_symc_handle); + symc_ctx = &symc_channel->symc_ctx_list[idx]; + crypto_chk_return(symc_ctx->is_open == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_CTX_CLOSED), "ctx is closed\n"); + crypto_chk_return(symc_ctx->is_set_config == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_NOT_SET_CONFIG), + "set_config first\n"); + crypto_chk_return(symc_ctx->is_attached == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_NOT_ATTACHED), "attach first\n"); + + crypto_mutex_lock(&symc_channel->symc_ctx_mutex[idx]); + + if (symc_ctx->is_long_term == TD_TRUE) { + ret = inner_kapi_cipher_symc_crypto(symc_ctx->drv_symc_handle, src_buf, dst_buf, length, crypto_type); + crypto_chk_goto(ret != TD_SUCCESS, unlock_exit, + "inner_kapi_cipher_symc_crypto for Encrypt failed, ret is 0x%x\n", ret); + } else { + ret = inner_kapi_symc_crypto_short_term(symc_ctx, src_buf, dst_buf, length, crypto_type); + crypto_chk_goto(ret != TD_SUCCESS, unlock_exit, "inner_kapi_symc_crypto_short_term failed, ret is 0x%x\n", ret); + } + crypto_mutex_unlock(&symc_channel->symc_ctx_mutex[idx]); + + symc_ctx->processed_length += length; + return ret; + +unlock_exit: + crypto_mutex_unlock(&symc_channel->symc_ctx_mutex[idx]); + return ret; +} + +td_s32 kapi_cipher_symc_encrypt(td_handle kapi_symc_handle, const crypto_buf_attr *src_buf, + const crypto_buf_attr *dst_buf, td_u32 length) +{ + td_s32 ret; + crypto_kapi_func_enter(); + + /* Param Check. */ + symc_null_ptr_chk(src_buf); + symc_null_ptr_chk(dst_buf); + crypto_chk_return(crypto_data_buf_check(src_buf, length) == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_MEMORY_ACCESS), + "src_buf access refused\n"); + crypto_chk_return(crypto_data_buf_check(dst_buf, length) == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_MEMORY_ACCESS), + "dst_buf access refused\n"); + + ret = kapi_cipher_symc_crypto(kapi_symc_handle, src_buf, dst_buf, length, CRYPTO_TYPE_ENCRYPT); + + crypto_kapi_func_exit(); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_cipher_symc_encrypt); + +td_s32 kapi_cipher_symc_decrypt(td_handle kapi_symc_handle, const crypto_buf_attr *src_buf, + const crypto_buf_attr *dst_buf, td_u32 length) +{ + td_s32 ret; + crypto_kapi_func_enter(); + + /* Param Check. */ + symc_null_ptr_chk(src_buf); + symc_null_ptr_chk(dst_buf); + crypto_chk_return(crypto_data_buf_check(src_buf, length) == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_MEMORY_ACCESS), + "src_buf access refused\n"); + crypto_chk_return(crypto_data_buf_check(dst_buf, length) == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_MEMORY_ACCESS), + "dst_buf access refused\n"); + + ret = kapi_cipher_symc_crypto(kapi_symc_handle, src_buf, dst_buf, length, CRYPTO_TYPE_DECRYPT); + + crypto_kapi_func_exit(); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_cipher_symc_decrypt); + +typedef struct { + td_handle drv_symc_handle; + td_u32 pack_num; + td_u32 crypto_type; +} priv_multi_param_t; + +static td_s32 priv_kapi_symc_crypto_multi(const priv_multi_param_t *multi_param, const crypto_symc_ctrl_t *symc_ctrl, + const crypto_symc_pack *src_buf_pack, const crypto_symc_pack *dst_buf_pack) +{ + td_s32 ret; + td_u32 i; + crypto_symc_pack *buffer = TD_NULL; + crypto_symc_pack *drv_src_buf_pack = TD_NULL; + crypto_symc_pack *drv_dst_buf_pack = TD_NULL; + td_u32 pack_size = sizeof(crypto_symc_pack) * multi_param->pack_num; + td_u32 buffer_size = pack_size * 2; /* 2: for Both src and dst. */ + + buffer = crypto_malloc(buffer_size); + crypto_chk_return(buffer == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + (td_void)memset_s(buffer, buffer_size, 0, buffer_size); + + drv_src_buf_pack = buffer; + drv_dst_buf_pack = buffer + multi_param->pack_num; + + for (i = 0; i < multi_param->pack_num; i++) { + /* Check buf_attr access. */ + crypto_chk_goto_with_ret(crypto_data_buf_check(&src_buf_pack[i].buf_attr, src_buf_pack[i].length) == TD_FALSE, + exit_put_phys_addr, SYMC_COMPAT_ERRNO(ERROR_MEMORY_ACCESS), "src_buf access refuse\n"); + crypto_chk_goto_with_ret(crypto_data_buf_check(&dst_buf_pack[i].buf_attr, dst_buf_pack[i].length) == TD_FALSE, + exit_put_phys_addr, SYMC_COMPAT_ERRNO(ERROR_MEMORY_ACCESS), "dst_buf access refuse\n"); + /* Transfer phys_addr from buf_attr. */ + drv_src_buf_pack[i].buf_attr.phys_addr = crypto_osal_get_phys_addr(&src_buf_pack[i].buf_attr); + crypto_chk_goto_with_ret(drv_src_buf_pack[i].buf_attr.phys_addr == 0, exit_put_phys_addr, + SYMC_COMPAT_ERRNO(ERROR_GET_PHYS_ADDR), "crypto_osal_get_phys_addr failed\n"); + drv_src_buf_pack[i].length = src_buf_pack[i].length; + + drv_dst_buf_pack[i].buf_attr.phys_addr = crypto_osal_get_phys_addr(&dst_buf_pack[i].buf_attr); + crypto_chk_goto_with_ret(drv_dst_buf_pack[i].buf_attr.phys_addr == 0, exit_put_phys_addr, + SYMC_COMPAT_ERRNO(ERROR_GET_PHYS_ADDR), "crypto_osal_get_phys_addr failed\n"); + drv_dst_buf_pack[i].length = dst_buf_pack[i].length; + } + + switch (multi_param->crypto_type) { + case CRYPTO_TYPE_ENCRYPT: + ret = drv_cipher_symc_encrypt_multi(multi_param->drv_symc_handle, symc_ctrl, drv_src_buf_pack, + drv_dst_buf_pack, multi_param->pack_num); + break; + case CRYPTO_TYPE_DECRYPT: + ret = drv_cipher_symc_decrypt_multi(multi_param->drv_symc_handle, symc_ctrl, drv_src_buf_pack, + drv_dst_buf_pack, multi_param->pack_num); + break; + default: + crypto_log_err("Invalid Crypto Type!\n"); + ret = SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM); + } + +exit_put_phys_addr: + for (i = 0; i < multi_param->pack_num; i++) { + crypto_osal_put_phys_addr(&src_buf_pack[i].buf_attr, drv_src_buf_pack[i].buf_attr.phys_addr); + crypto_osal_put_phys_addr(&dst_buf_pack[i].buf_attr, drv_dst_buf_pack[i].buf_attr.phys_addr); + } + (td_void)memset_s(buffer, buffer_size, 0, buffer_size); + crypto_free(buffer); + return ret; +} + +td_s32 kapi_cipher_symc_encrypt_multi(td_handle kapi_symc_handle, const crypto_symc_ctrl_t *symc_ctrl, + const crypto_symc_pack *src_buf_pack, const crypto_symc_pack *dst_buf_pack, td_u32 pack_num) +{ + td_s32 ret; + priv_multi_param_t multi_param = { + .pack_num = pack_num, + .crypto_type = CRYPTO_TYPE_ENCRYPT + }; + crypto_kapi_symc_process *symc_channel = TD_NULL; + crypto_kapi_symc_ctx *symc_ctx = TD_NULL; + td_u32 idx; + crypto_kapi_func_enter(); + + symc_null_ptr_chk(src_buf_pack); + symc_null_ptr_chk(dst_buf_pack); + crypto_chk_return(pack_num > CRYPTO_SYMC_MULTI_PACK_MAX_SIZE, SYMC_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), + "pack_num is too large\n"); + + ret = priv_symc_handle_check(kapi_symc_handle); + crypto_chk_return(ret != TD_SUCCESS, ret, "priv_symc_handle_check failed, ret is 0x%x\n", ret); + + idx = kapi_get_ctx_idx(kapi_symc_handle); + symc_channel = priv_get_current_symc_channel(); + crypto_chk_return(symc_channel == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_NOT_INIT), "Invalid Process!\n"); + + symc_ctx = &symc_channel->symc_ctx_list[idx]; + crypto_chk_return(symc_ctx->is_open == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_CTX_CLOSED), "ctx is closed\n"); + crypto_chk_return(symc_ctx->is_attached == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_NOT_ATTACHED), "attach first\n"); + + crypto_mutex_lock(&symc_channel->symc_ctx_mutex[idx]); + + if (symc_ctx->is_long_term == TD_TRUE) { + multi_param.drv_symc_handle = symc_ctx->drv_symc_handle; + ret = priv_kapi_symc_crypto_multi(&multi_param, symc_ctrl, src_buf_pack, dst_buf_pack); + crypto_chk_goto(ret != TD_SUCCESS, unlock_exit, "priv_kapi_symc_crypto_multi for Encrypt failed\n"); + } else { + ret = priv_drv_lock_create(symc_ctx, &symc_ctx->symc_attr); + crypto_chk_goto(ret != TD_SUCCESS, unlock_exit, "drv_cipher_symc_create failed, ret is 0x%x\n", ret); + + ret = drv_cipher_symc_attach(symc_ctx->drv_symc_handle, symc_ctx->keyslot_handle); + crypto_chk_goto(ret != TD_SUCCESS, symc_destroy_exit, "drv_cipher_symc_attach failed, ret is 0x%x\n", ret); + + multi_param.drv_symc_handle = symc_ctx->drv_symc_handle; + ret = priv_kapi_symc_crypto_multi(&multi_param, symc_ctrl, src_buf_pack, dst_buf_pack); + crypto_chk_goto(ret != TD_SUCCESS, symc_destroy_exit, "priv_kapi_symc_crypto_multi for Encrypt failed\n"); + + priv_drv_lock_destroy(symc_ctx->drv_symc_handle); + } + + crypto_mutex_unlock(&symc_channel->symc_ctx_mutex[idx]); + crypto_kapi_func_exit(); + return ret; + +symc_destroy_exit: + priv_drv_lock_destroy(symc_ctx->drv_symc_handle); +unlock_exit: + crypto_mutex_unlock(&symc_channel->symc_ctx_mutex[idx]); + crypto_kapi_func_exit(); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_cipher_symc_encrypt_multi); + +td_s32 kapi_cipher_symc_decrypt_multi(td_handle kapi_symc_handle, const crypto_symc_ctrl_t *symc_ctrl, + const crypto_symc_pack *src_buf_pack, const crypto_symc_pack *dst_buf_pack, td_u32 pack_num) +{ + td_s32 ret; + priv_multi_param_t multi_param = { + .pack_num = pack_num, + .crypto_type = CRYPTO_TYPE_DECRYPT + }; + crypto_kapi_symc_process *symc_channel = TD_NULL; + crypto_kapi_symc_ctx *symc_ctx = TD_NULL; + td_u32 idx; + crypto_kapi_func_enter(); + + symc_null_ptr_chk(src_buf_pack); + symc_null_ptr_chk(dst_buf_pack); + + ret = priv_symc_handle_check(kapi_symc_handle); + crypto_chk_return(ret != TD_SUCCESS, ret, "priv_symc_handle_check failed, ret is 0x%x\n", ret); + + idx = kapi_get_ctx_idx(kapi_symc_handle); + symc_channel = priv_get_current_symc_channel(); + crypto_chk_return(symc_channel == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_NOT_INIT), "Invalid Process!\n"); + + symc_ctx = &symc_channel->symc_ctx_list[idx]; + crypto_chk_return(symc_ctx->is_open == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_CTX_CLOSED), "ctx is closed\n"); + crypto_chk_return(symc_ctx->is_attached == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_NOT_ATTACHED), "attach first\n"); + + crypto_mutex_lock(&symc_channel->symc_ctx_mutex[idx]); + + if (symc_ctx->is_long_term == TD_TRUE) { + multi_param.drv_symc_handle = symc_ctx->drv_symc_handle; + ret = priv_kapi_symc_crypto_multi(&multi_param, symc_ctrl, src_buf_pack, dst_buf_pack); + crypto_chk_goto(ret != TD_SUCCESS, unlock_exit, "priv_kapi_symc_crypto_multi for Encrypt failed\n"); + } else { + ret = priv_drv_lock_create(symc_ctx, &symc_ctx->symc_attr); + crypto_chk_goto(ret != TD_SUCCESS, unlock_exit, "drv_cipher_symc_create failed, ret is 0x%x\n", ret); + + ret = drv_cipher_symc_attach(symc_ctx->drv_symc_handle, symc_ctx->keyslot_handle); + crypto_chk_goto(ret != TD_SUCCESS, symc_destroy_exit, "drv_cipher_symc_attach failed, ret is 0x%x\n", ret); + + multi_param.drv_symc_handle = symc_ctx->drv_symc_handle; + ret = priv_kapi_symc_crypto_multi(&multi_param, symc_ctrl, src_buf_pack, dst_buf_pack); + crypto_chk_goto(ret != TD_SUCCESS, symc_destroy_exit, "priv_kapi_symc_crypto_multi for Encrypt failed\n"); + + priv_drv_lock_destroy(symc_ctx->drv_symc_handle); + } + + crypto_mutex_unlock(&symc_channel->symc_ctx_mutex[idx]); + crypto_kapi_func_exit(); + return ret; + +symc_destroy_exit: + priv_drv_lock_destroy(symc_ctx->drv_symc_handle); +unlock_exit: + crypto_mutex_unlock(&symc_channel->symc_ctx_mutex[idx]); + crypto_kapi_func_exit(); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_cipher_symc_decrypt_multi); + +td_s32 kapi_cipher_symc_get_tag(td_handle kapi_symc_handle, td_u8 *tag, td_u32 tag_length) +{ + td_s32 ret; + crypto_kapi_symc_process *symc_channel = TD_NULL; + crypto_kapi_symc_ctx *symc_ctx = TD_NULL; + td_u32 idx; + crypto_kapi_func_enter(); + + symc_null_ptr_chk(tag); + + ret = priv_symc_handle_check(kapi_symc_handle); + crypto_chk_return(ret != TD_SUCCESS, ret, "priv_symc_handle_check failed, ret is 0x%x\n", ret); + + idx = kapi_get_ctx_idx(kapi_symc_handle); + symc_channel = priv_get_current_symc_channel(); + crypto_chk_return(symc_channel == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_NOT_INIT), "call init first\n"); + + symc_ctx = &symc_channel->symc_ctx_list[idx]; + crypto_chk_return(symc_ctx->is_open == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_CTX_CLOSED), "ctx is closed\n"); + crypto_chk_return(symc_ctx->is_set_config == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_NOT_SET_CONFIG), + "set_config first\n"); + crypto_chk_return(symc_ctx->is_attached == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_NOT_ATTACHED), "attach first\n"); + + crypto_mutex_lock(&symc_channel->symc_ctx_mutex[idx]); + + if (symc_ctx->is_long_term == TD_TRUE) { + ret = drv_cipher_symc_get_tag(symc_ctx->drv_symc_handle, tag, tag_length); + crypto_chk_goto(ret != TD_SUCCESS, exit_unlock_mutex, "drv_cipher_symc_get_tag failed\n"); + } else { + ret = inner_kapi_symc_get_tag_short_term(symc_ctx, tag, tag_length); + crypto_chk_goto(ret != TD_SUCCESS, exit_unlock_mutex, "inner_kapi_symc_get_tag_short_term failed\n"); + } + +exit_unlock_mutex: + crypto_mutex_unlock(&symc_channel->symc_ctx_mutex[idx]); + crypto_kapi_func_exit(); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_cipher_symc_get_tag); + +td_s32 kapi_cipher_mac_start(td_handle *kapi_symc_handle, const crypto_symc_mac_attr *mac_attr) +{ + td_s32 ret = CRYPTO_SUCCESS; + crypto_kapi_symc_process *symc_channel = TD_NULL; + crypto_kapi_symc_ctx *symc_ctx = TD_NULL; + td_u32 idx; + + crypto_kapi_func_enter(); + symc_null_ptr_chk(kapi_symc_handle); + symc_null_ptr_chk(mac_attr); + + symc_channel = priv_get_current_symc_channel(); + crypto_chk_return(symc_channel == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_NOT_INIT), "call init first\n"); + + symc_ctx = priv_occupy_symc_soft_chn(symc_channel, &idx); + crypto_chk_return(symc_ctx == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_CHN_BUSY), "all symc soft chns are busy\n"); + crypto_chk_return(symc_ctx->is_open == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_CTX_CLOSED), "ctx is closed\n"); + + crypto_mutex_lock(&symc_channel->symc_ctx_mutex[idx]); + + if (mac_attr->is_long_term == TD_TRUE) { + ret = priv_drv_lock_mac_start(&symc_ctx->drv_symc_handle, mac_attr); + crypto_chk_goto(ret != TD_SUCCESS, error_unlock_symc_ctx, "drv_cipher_mac_start failed, ret is 0x%x\n", ret); + } + (td_void)memcpy_s(&symc_ctx->mac_attr, sizeof(crypto_symc_mac_attr), mac_attr, sizeof(crypto_symc_mac_attr)); + symc_ctx->is_long_term = mac_attr->is_long_term; + symc_ctx->is_mac = TD_TRUE; + crypto_mutex_unlock(&symc_channel->symc_ctx_mutex[idx]); + *kapi_symc_handle = synthesize_kapi_handle(KAPI_SYMC_MODULE_ID, idx); + crypto_kapi_func_exit(); + return ret; + +error_unlock_symc_ctx: + priv_release_symc_soft_chn(symc_ctx); + crypto_mutex_unlock(&symc_channel->symc_ctx_mutex[idx]); + crypto_kapi_func_exit(); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_cipher_mac_start); + +td_s32 kapi_cipher_mac_update(td_handle kapi_symc_handle, const crypto_buf_attr *src_buf, td_u32 length) +{ + td_s32 ret; + crypto_kapi_symc_process *symc_channel = TD_NULL; + crypto_kapi_symc_ctx *symc_ctx = TD_NULL; + td_u32 idx; + crypto_kapi_func_enter(); + + ret = priv_symc_handle_check(kapi_symc_handle); + crypto_chk_return(ret != TD_SUCCESS, ret, "priv_symc_handle_check failed, ret is 0x%x\n", ret); + + idx = kapi_get_ctx_idx(kapi_symc_handle); + symc_channel = priv_get_current_symc_channel(); + crypto_chk_return(symc_channel == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_NOT_INIT), "call init first\n"); + + symc_ctx = &symc_channel->symc_ctx_list[idx]; + crypto_chk_return(symc_ctx == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_CHN_BUSY), "all symc soft chns are busy\n"); + crypto_chk_return(symc_ctx->is_open == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_CTX_CLOSED), "ctx is closed\n"); + crypto_chk_return(symc_ctx->is_mac == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_NOT_MAC_START), "call mac_start first\n"); + + crypto_mutex_lock(&symc_channel->symc_ctx_mutex[idx]); + + if (symc_ctx->is_long_term == TD_TRUE) { + ret = drv_cipher_mac_update(symc_ctx->drv_symc_handle, src_buf, length); + crypto_chk_goto(ret != TD_SUCCESS, unlock_exit, "drv_cipher_mac_update failed, ret is 0x%x\n", ret); + } else { + ret = priv_drv_lock_mac_start(&symc_ctx->drv_symc_handle, &symc_ctx->mac_attr); + crypto_chk_goto(ret != TD_SUCCESS, unlock_exit, "drv_cipher_mac_start failed, ret is 0x%x\n", ret); + + ret = inner_drv_set_mac_ctx(symc_ctx->drv_symc_handle, &symc_ctx->mac_ctx); + crypto_chk_goto(ret != TD_SUCCESS, error_mac_finish, "inner_drv_get_mac_ctx failed, ret is 0x%x\n", ret); + + ret = drv_cipher_mac_update(symc_ctx->drv_symc_handle, src_buf, length); + crypto_chk_goto(ret != TD_SUCCESS, error_mac_finish, "drv_cipher_mac_update failed, ret is 0x%x\n", ret); + + ret = inner_drv_get_mac_ctx(symc_ctx->drv_symc_handle, &symc_ctx->mac_ctx); + crypto_chk_goto(ret != TD_SUCCESS, error_mac_finish, "inner_drv_get_mac_ctx failed, ret is 0x%x\n", ret); + + (td_void)drv_cipher_symc_destroy(symc_ctx->drv_symc_handle); + } + + crypto_mutex_unlock(&symc_channel->symc_ctx_mutex[idx]); + crypto_kapi_func_exit(); + return ret; + +error_mac_finish: + if (symc_ctx->is_long_term == TD_FALSE) { + (td_void)drv_cipher_symc_destroy(symc_ctx->drv_symc_handle); + } +unlock_exit: + crypto_mutex_unlock(&symc_channel->symc_ctx_mutex[idx]); + crypto_kapi_func_exit(); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_cipher_mac_update); + +td_s32 kapi_cipher_mac_finish(td_handle kapi_symc_handle, td_u8 *mac, td_u32 *mac_length) +{ + td_s32 ret; + crypto_kapi_symc_process *symc_channel = TD_NULL; + crypto_kapi_symc_ctx *symc_ctx = TD_NULL; + td_u32 idx; + crypto_kapi_func_enter(); + + symc_null_ptr_chk(mac); + symc_null_ptr_chk(mac_length); + + crypto_chk_return(*mac_length < CRYPTO_AES_BLOCK_SIZE_IN_BYTES, SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "mac_length is not enough\n"); + + ret = priv_symc_handle_check(kapi_symc_handle); + crypto_chk_return(ret != TD_SUCCESS, ret, "priv_symc_handle_check failed, ret is 0x%x\n", ret); + + idx = kapi_get_ctx_idx(kapi_symc_handle); + + symc_channel = priv_get_current_symc_channel(); + crypto_chk_return(symc_channel == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_NOT_INIT), "call init first\n"); + + symc_ctx = &symc_channel->symc_ctx_list[idx]; + crypto_chk_return(symc_ctx == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_CHN_BUSY), "all symc soft chns are busy\n"); + crypto_chk_return(symc_ctx->is_open == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_CTX_CLOSED), "ctx is closed\n"); + crypto_chk_return(symc_ctx->is_mac == TD_FALSE, SYMC_COMPAT_ERRNO(ERROR_NOT_MAC_START), "call mac_start first\n"); + + crypto_mutex_lock(&symc_channel->symc_ctx_mutex[idx]); + + if (symc_ctx->is_long_term == TD_TRUE) { + ret = priv_drv_lock_mac_finish(symc_ctx->drv_symc_handle, mac, mac_length); + crypto_chk_goto(ret != TD_SUCCESS, error_exit, "priv_drv_lock_mac_finish failed, ret is 0x%x\n", ret); + } else { + ret = priv_drv_lock_mac_start(&symc_ctx->drv_symc_handle, &symc_ctx->mac_attr); + crypto_chk_goto(ret != TD_SUCCESS, error_exit, "drv_cipher_mac_start failed, ret is 0x%x\n", ret); + + ret = inner_drv_set_mac_ctx(symc_ctx->drv_symc_handle, &symc_ctx->mac_ctx); + crypto_chk_goto(ret != TD_SUCCESS, error_mac_destroy, "inner_drv_get_mac_ctx failed, ret is 0x%x\n", ret); + + (td_void)priv_drv_lock_mac_finish(symc_ctx->drv_symc_handle, mac, mac_length); + } + + priv_release_symc_soft_chn(symc_ctx); + crypto_mutex_unlock(&symc_channel->symc_ctx_mutex[idx]); + crypto_kapi_func_exit(); + return ret; + +error_mac_destroy: + (td_void)drv_cipher_symc_destroy(symc_ctx->drv_symc_handle); +error_exit: + crypto_mutex_unlock(&symc_channel->symc_ctx_mutex[idx]); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_cipher_mac_finish); diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/kapi_code/kapi_trng.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/kapi_code/kapi_trng.c new file mode 100644 index 00000000..be233065 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/kapi_code/kapi_trng.c @@ -0,0 +1,66 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "kapi_trng.h" +#include "kapi_inner.h" + +#include "drv_trng.h" +#include "crypto_drv_common.h" + +#define TRNG_COMPAT_ERRNO(err_code) KAPI_COMPAT_ERRNO(ERROR_MODULE_TRNG, err_code) + +crypto_mutex g_trng_mutex; + +#define kapi_trng_mutex_lock() do { \ + crypto_mutex_lock(&g_trng_mutex); \ +} while (0) + +#define kapi_trng_mutex_unlock() do { \ + crypto_mutex_unlock(&g_trng_mutex); \ +} while (0) + +td_s32 kapi_cipher_trng_env_init(td_void) +{ + td_s32 ret = TD_SUCCESS; + + ret = drv_cipher_trng_init(); + if (ret != TD_SUCCESS) { + crypto_log_err("drv_cipher_trng_init failed, ret is 0x%x\n", ret); + return ret; + } + + ret = crypto_mutex_init(&g_trng_mutex); + if (ret != TD_SUCCESS) { + crypto_log_err("crypto_mutex_init failed\n"); + goto error_trng_deinit; + } + +error_trng_deinit: + return ret; +} + +td_s32 kapi_cipher_trng_env_deinit(td_void) +{ + crypto_mutex_destroy(&g_trng_mutex); + drv_cipher_trng_deinit(); + return TD_SUCCESS; +} + +td_s32 kapi_cipher_trng_get_random(td_u32 *randnum) +{ + td_s32 ret = TD_FAILURE; + crypto_chk_return(randnum == TD_NULL, TRNG_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "randnum is NULL\n"); + ret = drv_cipher_trng_get_random(randnum); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_cipher_trng_get_random); + +td_s32 kapi_cipher_trng_get_multi_random(td_u32 size, td_u8 *randnum) +{ + td_s32 ret = TD_FAILURE; + crypto_chk_return(randnum == TD_NULL, TRNG_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "randnum is NULL\n"); + ret = drv_cipher_trng_get_multi_random(size, randnum); + return ret; +} +CRYPTO_EXPORT_SYMBOL(kapi_cipher_trng_get_multi_random); \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi/ot_mpi_hash.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi/ot_mpi_hash.c new file mode 100644 index 00000000..b513bcd3 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi/ot_mpi_hash.c @@ -0,0 +1,53 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "ot_mpi_cipher.h" + +#include "crypto_osal_user_lib.h" +#include "uapi_hash.h" + +td_s32 ot_mpi_cipher_hash_init(td_void) +{ + return unify_uapi_cipher_hash_init(); +} + +td_s32 ot_mpi_cipher_hash_deinit(td_void) +{ + return unify_uapi_cipher_hash_deinit(); +} + +td_s32 ot_mpi_cipher_hash_create(td_handle *mpi_hash_handle, const crypto_hash_attr *hash_attr) +{ + return unify_uapi_cipher_hash_start(mpi_hash_handle, hash_attr); +} + +td_s32 ot_mpi_cipher_hash_update(td_handle mpi_hash_handle, const crypto_buf_attr *src_buf, const td_u32 len) +{ + return unify_uapi_cipher_hash_update(mpi_hash_handle, src_buf, len); +} + +td_s32 ot_mpi_cipher_hash_finish(td_handle mpi_hash_handle, td_u8 *virt_addr, td_u32 buffer_len, td_u32 *result_len) +{ + td_s32 ret; + crypto_check_param_null(ERROR_LAYER_UAPI, ERROR_MODULE_HASH, virt_addr); + crypto_check_param_null(ERROR_LAYER_UAPI, ERROR_MODULE_HASH, result_len); + *result_len = buffer_len; + ret = unify_uapi_cipher_hash_finish(mpi_hash_handle, virt_addr, result_len); + return ret; +} + +td_s32 ot_mpi_cipher_hash_get(td_handle mpi_hash_handle, crypto_hash_clone_ctx *hash_clone_ctx) +{ + return unify_uapi_cipher_hash_get(mpi_hash_handle, hash_clone_ctx); +} + +td_s32 ot_mpi_cipher_hash_set(td_handle mpi_hash_handle, const crypto_hash_clone_ctx *hash_clone_ctx) +{ + return unify_uapi_cipher_hash_set(mpi_hash_handle, hash_clone_ctx); +} + +td_s32 ot_mpi_cipher_hash_destroy(td_handle mpi_hash_handle) +{ + return unify_uapi_cipher_hash_destroy(mpi_hash_handle); +} diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi/ot_mpi_kdf.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi/ot_mpi_kdf.c new file mode 100644 index 00000000..61d9f66c --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi/ot_mpi_kdf.c @@ -0,0 +1,12 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "ot_mpi_cipher.h" + +#include "uapi_kdf.h" + +td_s32 ot_mpi_cipher_pbkdf2(const crypto_kdf_pbkdf2_param *param, td_u8 *out, const td_u32 out_len) +{ + return unify_uapi_cipher_pbkdf2(param, out, out_len); +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi/ot_mpi_km.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi/ot_mpi_km.c new file mode 100644 index 00000000..501d05d4 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi/ot_mpi_km.c @@ -0,0 +1,78 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "ot_mpi_km.h" + +#include "crypto_km_struct.h" +#include "uapi_km.h" + +/* Init */ +td_s32 ot_mpi_km_init(td_void) +{ + return uapi_km_init(); +} + +td_s32 ot_mpi_km_deinit(td_void) +{ + return uapi_km_deinit(); +} + +/* Keyslot. */ +td_s32 ot_mpi_keyslot_create(crypto_handle *mpi_keyslot_handle, km_keyslot_type keyslot_type) +{ + return uapi_keyslot_create(mpi_keyslot_handle, keyslot_type); +} + +td_s32 ot_mpi_keyslot_destroy(crypto_handle mpi_keyslot_handle) +{ + return uapi_keyslot_destroy(mpi_keyslot_handle); +} + +/* Klad. */ +td_s32 ot_mpi_klad_create(crypto_handle *mpi_klad_handle) +{ + return uapi_klad_create(mpi_klad_handle); +} + +td_s32 ot_mpi_klad_destroy(crypto_handle mpi_klad_handle) +{ + return uapi_klad_destroy(mpi_klad_handle); +} + +td_s32 ot_mpi_klad_attach(crypto_handle mpi_klad_handle, km_klad_dest_type klad_type, + crypto_handle mpi_keyslot_handle) +{ + return uapi_klad_attach(mpi_klad_handle, klad_type, mpi_keyslot_handle); +} + +td_s32 ot_mpi_klad_detach(crypto_handle mpi_klad_handle, km_klad_dest_type klad_type, + crypto_handle mpi_keyslot_handle) +{ + return uapi_klad_detach(mpi_klad_handle, klad_type, mpi_keyslot_handle); +} + +td_s32 ot_mpi_klad_set_attr(crypto_handle mpi_klad_handle, const km_klad_attr *attr) +{ + return uapi_klad_set_attr(mpi_klad_handle, attr); +} + +td_s32 ot_mpi_klad_get_attr(crypto_handle mpi_klad_handle, km_klad_attr *attr) +{ + return uapi_klad_get_attr(mpi_klad_handle, attr); +} + +td_s32 ot_mpi_klad_set_session_key(crypto_handle mpi_klad_handle, const km_klad_session_key *key) +{ + return uapi_klad_set_session_key(mpi_klad_handle, key); +} + +td_s32 ot_mpi_klad_set_content_key(crypto_handle mpi_klad_handle, const km_klad_content_key *key) +{ + return uapi_klad_set_content_key(mpi_klad_handle, key); +} + +td_s32 ot_mpi_klad_set_clear_key(crypto_handle mpi_klad_handle, const km_klad_clear_key *key) +{ + return uapi_klad_set_clear_key(mpi_klad_handle, key); +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi/ot_mpi_otp.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi/ot_mpi_otp.c new file mode 100644 index 00000000..cb50f53f --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi/ot_mpi_otp.c @@ -0,0 +1,31 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "ot_mpi_otp.h" +#include "uapi_otp.h" + +td_s32 ot_mpi_otp_init(td_void) +{ + return uapi_otp_init(); +} + +td_s32 ot_mpi_otp_deinit(td_void) +{ + return uapi_otp_deinit(); +} + +td_s32 ot_mpi_otp_read_word(td_u32 offset, td_u32 *data) +{ + return uapi_otp_read_word(offset, data); +} + +td_s32 ot_mpi_otp_read_byte(td_u32 offset, td_u8 *data) +{ + return uapi_otp_read_byte(offset, data); +} + +td_s32 ot_mpi_otp_write_byte(td_u32 offset, td_u8 data) +{ + return uapi_otp_write_byte(offset, data); +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi/ot_mpi_pke.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi/ot_mpi_pke.c new file mode 100644 index 00000000..91f353f4 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi/ot_mpi_pke.c @@ -0,0 +1,106 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "ot_mpi_cipher.h" + +#include "uapi_pke.h" + +td_s32 ot_mpi_cipher_pke_init(td_void) +{ + return unify_uapi_cipher_pke_init(); +} + +td_s32 ot_mpi_cipher_pke_deinit(td_void) +{ + return unify_uapi_cipher_pke_deinit(); +} + +td_s32 ot_mpi_cipher_pke_ecc_gen_key(drv_pke_ecc_curve_type curve_type, const drv_pke_data *input_priv_key, + const drv_pke_data *output_priv_key, const drv_pke_ecc_point *output_pub_key) +{ + return unify_uapi_cipher_pke_ecc_gen_key(curve_type, input_priv_key, output_priv_key, output_pub_key); +} + +td_s32 ot_mpi_cipher_pke_ecc_gen_ecdh_key(drv_pke_ecc_curve_type curve_type, const drv_pke_ecc_point *input_pub_key, + const drv_pke_data *input_priv_key, const drv_pke_data *output_shared_key) +{ + return unify_uapi_cipher_pke_ecc_gen_ecdh_key(curve_type, input_pub_key, input_priv_key, output_shared_key); +} + +td_s32 ot_mpi_cipher_pke_ecdsa_sign(drv_pke_ecc_curve_type curve_type, const drv_pke_data *priv_key, + const drv_pke_data *hash, const drv_pke_ecc_sig *sig) +{ + return unify_uapi_cipher_pke_ecdsa_sign(curve_type, priv_key, hash, sig); +} + +td_s32 ot_mpi_cipher_pke_ecdsa_verify(drv_pke_ecc_curve_type curve_type, const drv_pke_ecc_point *pub_key, + const drv_pke_data *hash, const drv_pke_ecc_sig *sig) +{ + return unify_uapi_cipher_pke_ecdsa_verify(curve_type, pub_key, hash, sig); +} + +td_s32 ot_mpi_cipher_pke_eddsa_sign(drv_pke_ecc_curve_type curve_type, const drv_pke_data *priv_key, + const drv_pke_msg *msg, const drv_pke_ecc_sig *sig) +{ + return unify_uapi_cipher_pke_eddsa_sign(curve_type, priv_key, msg, sig); +} + +td_s32 ot_mpi_cipher_pke_eddsa_verify(drv_pke_ecc_curve_type curve_type, const drv_pke_ecc_point *pub_key, + const drv_pke_msg *msg, const drv_pke_ecc_sig *sig) +{ + return unify_uapi_cipher_pke_eddsa_verify(curve_type, pub_key, msg, sig); +} + +td_s32 ot_mpi_cipher_pke_check_dot_on_curve(drv_pke_ecc_curve_type curve_type, const drv_pke_ecc_point *pub_key, + td_bool *is_on_curve) +{ + return unify_uapi_cipher_pke_check_dot_on_curve(curve_type, pub_key, is_on_curve); +} + +td_s32 ot_mpi_cipher_pke_sm2_dsa_hash(const drv_pke_data *sm2_id, const drv_pke_ecc_point *pub_key, + const drv_pke_msg *msg, drv_pke_data *hash) +{ + return unify_uapi_cipher_pke_sm2_dsa_hash(sm2_id, pub_key, msg, hash); +} + +td_s32 ot_mpi_cipher_pke_sm2_public_encrypt(const drv_pke_ecc_point *pub_key, const drv_pke_data *plain_text, + drv_pke_data *cipher_text) +{ + return unify_uapi_cipher_pke_sm2_public_encrypt(pub_key, plain_text, cipher_text); +} + + +td_s32 ot_mpi_cipher_pke_sm2_private_decrypt(const drv_pke_data *priv_key, const drv_pke_data *cipher_text, + drv_pke_data *plain_text) +{ + return unify_uapi_cipher_pke_sm2_private_decrypt(priv_key, cipher_text, plain_text); +} + +/* RSA. */ +td_s32 ot_mpi_cipher_pke_rsa_sign(const drv_pke_rsa_priv_key *priv_key, drv_pke_rsa_scheme scheme, + drv_pke_hash_type hash_type, const drv_pke_data *input_hash, + drv_pke_data *sign) +{ + return unify_uapi_cipher_pke_rsa_sign(priv_key, scheme, hash_type, input_hash, sign); +} + +td_s32 ot_mpi_cipher_pke_rsa_verify(const drv_pke_rsa_pub_key *pub_key, drv_pke_rsa_scheme scheme, + drv_pke_hash_type hash_type, drv_pke_data *input_hash, const drv_pke_data *sig) +{ + return unify_uapi_cipher_pke_rsa_verify(pub_key, scheme, hash_type, input_hash, sig); +} + +td_s32 ot_mpi_cipher_pke_rsa_public_encrypt(drv_pke_rsa_scheme scheme, drv_pke_hash_type hash_type, + const drv_pke_rsa_pub_key *pub_key, const drv_pke_data *input, const drv_pke_data *label, + drv_pke_data *output) +{ + return unify_uapi_cipher_pke_rsa_public_encrypt(scheme, hash_type, pub_key, input, label, output); +} + +td_s32 ot_mpi_cipher_pke_rsa_private_decrypt(drv_pke_rsa_scheme scheme, drv_pke_hash_type hash_type, + const drv_pke_rsa_priv_key *priv_key, const drv_pke_data *input, const drv_pke_data *label, + drv_pke_data *output) +{ + return unify_uapi_cipher_pke_rsa_private_decrypt(scheme, hash_type, priv_key, input, label, output); +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi/ot_mpi_symc.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi/ot_mpi_symc.c new file mode 100644 index 00000000..90e5eb82 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi/ot_mpi_symc.c @@ -0,0 +1,81 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "ot_mpi_cipher.h" + +#include "uapi_symc.h" + +td_s32 ot_mpi_cipher_symc_init(td_void) +{ + return unify_uapi_cipher_symc_init(); +} + +td_s32 ot_mpi_cipher_symc_deinit(td_void) +{ + return unify_uapi_cipher_symc_deinit(); +} + +td_s32 ot_mpi_cipher_symc_create(td_handle *symc_handle, const crypto_symc_attr *symc_attr) +{ + return unify_uapi_cipher_symc_create(symc_handle, symc_attr); +} + +td_s32 ot_mpi_cipher_symc_destroy(td_handle symc_handle) +{ + return unify_uapi_cipher_symc_destroy(symc_handle); +} + +td_s32 ot_mpi_cipher_symc_set_config(td_handle symc_handle, const crypto_symc_ctrl_t *symc_ctrl) +{ + return unify_uapi_cipher_symc_set_config(symc_handle, symc_ctrl); +} + +td_s32 ot_mpi_cipher_symc_attach(td_handle symc_handle, td_handle keyslot_handle) +{ + return unify_uapi_cipher_symc_attach(symc_handle, keyslot_handle); +} + +td_s32 ot_mpi_cipher_symc_encrypt(td_handle symc_handle, const crypto_buf_attr *src_buf, + const crypto_buf_attr *dst_buf, td_u32 length) +{ + return unify_uapi_cipher_symc_encrypt(symc_handle, src_buf, dst_buf, length); +} + +td_s32 ot_mpi_cipher_symc_decrypt(td_handle symc_handle, const crypto_buf_attr *src_buf, + const crypto_buf_attr *dst_buf, td_u32 length) +{ + return unify_uapi_cipher_symc_decrypt(symc_handle, src_buf, dst_buf, length); +} + +td_s32 ot_mpi_cipher_symc_get_tag(td_handle symc_handle, td_u8 *tag, td_u32 tag_length) +{ + return unify_uapi_cipher_symc_get_tag(symc_handle, tag, tag_length); +} + +td_s32 ot_mpi_cipher_mac_start(td_handle *symc_handle, const crypto_symc_mac_attr *mac_attr) +{ + return unify_uapi_cipher_mac_start(symc_handle, mac_attr); +} + +td_s32 ot_mpi_cipher_mac_update(td_handle symc_handle, const crypto_buf_attr *src_buf, td_u32 length) +{ + return unify_uapi_cipher_mac_update(symc_handle, src_buf, length); +} + +td_s32 ot_mpi_cipher_mac_finish(td_handle symc_handle, td_u8 *mac, td_u32 *mac_length) +{ + return unify_uapi_cipher_mac_finish(symc_handle, mac, mac_length); +} + +td_s32 ot_mpi_cipher_symc_encrypt_multi(td_handle symc_handle, const crypto_symc_ctrl_t *symc_ctrl, + const crypto_symc_pack *src_buf_pack, const crypto_symc_pack *dst_buf_pack, td_u32 pack_num) +{ + return unify_uapi_cipher_symc_encrypt_multi(symc_handle, symc_ctrl, src_buf_pack, dst_buf_pack, pack_num); +} + +td_s32 ot_mpi_cipher_symc_decrypt_multi(td_handle symc_handle, const crypto_symc_ctrl_t *symc_ctrl, + const crypto_symc_pack *src_buf_pack, const crypto_symc_pack *dst_buf_pack, td_u32 pack_num) +{ + return unify_uapi_cipher_symc_decrypt_multi(symc_handle, symc_ctrl, src_buf_pack, dst_buf_pack, pack_num); +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi/ot_mpi_trng.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi/ot_mpi_trng.c new file mode 100644 index 00000000..f53ac753 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi/ot_mpi_trng.c @@ -0,0 +1,17 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "ot_mpi_cipher.h" + +#include "uapi_trng.h" + +td_s32 ot_mpi_cipher_trng_get_random(td_u32 *randnum) +{ + return unify_uapi_cipher_trng_get_random(randnum); +} + +td_s32 ot_mpi_cipher_trng_get_multi_random(td_u32 size, td_u8 *randnum) +{ + return unify_uapi_cipher_trng_get_multi_random(size, randnum); +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi_api/ot_mpi_cipher.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi_api/ot_mpi_cipher.h new file mode 100644 index 00000000..88773a35 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi_api/ot_mpi_cipher.h @@ -0,0 +1,134 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef OT_MPI_CIPHER_H +#define OT_MPI_CIPHER_H + +#include "crypto_type.h" +#include "crypto_hash_struct.h" +#include "crypto_kdf_struct.h" +#include "crypto_pke_struct.h" +#include "crypto_symc_struct.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* HASH */ +td_s32 ot_mpi_cipher_hash_init(td_void); + +td_s32 ot_mpi_cipher_hash_deinit(td_void); + +td_s32 ot_mpi_cipher_hash_create(td_handle *mpi_hash_handle, const crypto_hash_attr *hash_attr); + +td_s32 ot_mpi_cipher_hash_update(td_handle mpi_hash_handle, const crypto_buf_attr *src_buf, const td_u32 len); + +td_s32 ot_mpi_cipher_hash_finish(td_handle mpi_hash_handle, td_u8 *virt_addr, td_u32 buffer_len, td_u32 *result_len); + +td_s32 ot_mpi_cipher_hash_get(td_handle mpi_hash_handle, crypto_hash_clone_ctx *hash_clone_ctx); + +td_s32 ot_mpi_cipher_hash_set(td_handle mpi_hash_handle, const crypto_hash_clone_ctx *hash_clone_ctx); + +td_s32 ot_mpi_cipher_hash_destroy(td_handle mpi_hash_handle); + +/* PBKDF2 */ +td_s32 ot_mpi_cipher_pbkdf2(const crypto_kdf_pbkdf2_param *param, td_u8 *out, const td_u32 out_len); + +/* PKE */ +td_s32 ot_mpi_cipher_pke_init(td_void); + +td_s32 ot_mpi_cipher_pke_deinit(td_void); + +td_s32 ot_mpi_cipher_pke_ecc_gen_key(drv_pke_ecc_curve_type curve_type, const drv_pke_data *input_priv_key, + const drv_pke_data *output_priv_key, const drv_pke_ecc_point *output_pub_key); + +td_s32 ot_mpi_cipher_pke_ecc_gen_ecdh_key(drv_pke_ecc_curve_type curve_type, const drv_pke_ecc_point *input_pub_key, + const drv_pke_data *input_priv_key, const drv_pke_data *output_shared_key); + +td_s32 ot_mpi_cipher_pke_ecdsa_sign(drv_pke_ecc_curve_type curve_type, const drv_pke_data *priv_key, + const drv_pke_data *hash, const drv_pke_ecc_sig *sig); + +td_s32 ot_mpi_cipher_pke_ecdsa_verify(drv_pke_ecc_curve_type curve_type, const drv_pke_ecc_point *pub_key, + const drv_pke_data *hash, const drv_pke_ecc_sig *sig); + +td_s32 ot_mpi_cipher_pke_eddsa_sign(drv_pke_ecc_curve_type curve_type, const drv_pke_data *priv_key, + const drv_pke_msg *msg, const drv_pke_ecc_sig *sig); + +td_s32 ot_mpi_cipher_pke_eddsa_verify(drv_pke_ecc_curve_type curve_type, const drv_pke_ecc_point *pub_key, + const drv_pke_msg *msg, const drv_pke_ecc_sig *sig); + +td_s32 ot_mpi_cipher_pke_check_dot_on_curve(drv_pke_ecc_curve_type curve_type, const drv_pke_ecc_point *pub_key, + td_bool *is_on_curve); + +td_s32 ot_mpi_cipher_pke_sm2_dsa_hash(const drv_pke_data *sm2_id, const drv_pke_ecc_point *pub_key, + const drv_pke_msg *msg, drv_pke_data *hash); + +td_s32 ot_mpi_cipher_pke_sm2_public_encrypt(const drv_pke_ecc_point *pub_key, const drv_pke_data *plain_text, + drv_pke_data *cipher_text); + +td_s32 ot_mpi_cipher_pke_sm2_private_decrypt(const drv_pke_data *priv_key, const drv_pke_data *cipher_text, + drv_pke_data *plain_text); + +td_s32 ot_mpi_cipher_pke_rsa_sign(const drv_pke_rsa_priv_key *priv_key, drv_pke_rsa_scheme scheme, + drv_pke_hash_type hash_type, const drv_pke_data *input_hash, + drv_pke_data *sign); + +td_s32 ot_mpi_cipher_pke_rsa_verify(const drv_pke_rsa_pub_key *pub_key, drv_pke_rsa_scheme scheme, + drv_pke_hash_type hash_type, drv_pke_data *input_hash, const drv_pke_data *sig); + +td_s32 ot_mpi_cipher_pke_rsa_public_encrypt(drv_pke_rsa_scheme scheme, drv_pke_hash_type hash_type, + const drv_pke_rsa_pub_key *pub_key, const drv_pke_data *input, const drv_pke_data *label, + drv_pke_data *output); + +td_s32 ot_mpi_cipher_pke_rsa_private_decrypt(drv_pke_rsa_scheme scheme, drv_pke_hash_type hash_type, + const drv_pke_rsa_priv_key *priv_key, const drv_pke_data *input, const drv_pke_data *label, + drv_pke_data *output); + +/* SYMC */ +td_s32 ot_mpi_cipher_symc_init(td_void); + +td_s32 ot_mpi_cipher_symc_deinit(td_void); + +td_s32 ot_mpi_cipher_symc_create(td_handle *symc_handle, const crypto_symc_attr *symc_attr); + +td_s32 ot_mpi_cipher_symc_destroy(td_handle symc_handle); + +td_s32 ot_mpi_cipher_symc_set_config(td_handle symc_handle, const crypto_symc_ctrl_t *symc_ctrl); + +td_s32 ot_mpi_cipher_symc_attach(td_handle symc_handle, td_handle keyslot_handle); + +td_s32 ot_mpi_cipher_symc_encrypt(td_handle symc_handle, const crypto_buf_attr *src_buf, + const crypto_buf_attr *dst_buf, td_u32 length); + +td_s32 ot_mpi_cipher_symc_decrypt(td_handle symc_handle, const crypto_buf_attr *src_buf, + const crypto_buf_attr *dst_buf, td_u32 length); + +td_s32 ot_mpi_cipher_symc_encrypt_multi(td_handle symc_handle, const crypto_symc_ctrl_t *symc_ctrl, + const crypto_symc_pack *src_buf_pack, const crypto_symc_pack *dst_buf_pack, td_u32 pack_num); + +td_s32 ot_mpi_cipher_symc_decrypt_multi(td_handle symc_handle, const crypto_symc_ctrl_t *symc_ctrl, + const crypto_symc_pack *src_buf_pack, const crypto_symc_pack *dst_buf_pack, td_u32 pack_num); + +td_s32 ot_mpi_cipher_symc_get_tag(td_handle symc_handle, td_u8 *tag, td_u32 tag_length); + +td_s32 ot_mpi_cipher_mac_start(td_handle *symc_handle, const crypto_symc_mac_attr *mac_attr); + +td_s32 ot_mpi_cipher_mac_update(td_handle symc_handle, const crypto_buf_attr *src_buf, td_u32 length); + +td_s32 ot_mpi_cipher_mac_finish(td_handle symc_handle, td_u8 *mac, td_u32 *mac_length); + +/* TRNG */ +td_s32 ot_mpi_cipher_trng_get_random(td_u32 *randnum); + +td_s32 ot_mpi_cipher_trng_get_multi_random(td_u32 size, td_u8 *randnum); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi_api/ot_mpi_km.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi_api/ot_mpi_km.h new file mode 100644 index 00000000..e758bf27 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi_api/ot_mpi_km.h @@ -0,0 +1,46 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef OT_MPI_KM_H +#define OT_MPI_KM_H + +#include "crypto_km_struct.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +td_s32 ot_mpi_km_init(td_void); +td_s32 ot_mpi_km_deinit(td_void); + +/* Keyslot. */ +td_s32 ot_mpi_keyslot_create(crypto_handle *mpi_keyslot_handle, km_keyslot_type keyslot_type); +td_s32 ot_mpi_keyslot_destroy(crypto_handle mpi_keyslot_handle); + +/* Klad. */ +td_s32 ot_mpi_klad_create(crypto_handle *mpi_klad_handle); +td_s32 ot_mpi_klad_destroy(crypto_handle mpi_klad_handle); + +td_s32 ot_mpi_klad_attach(crypto_handle mpi_klad_handle, km_klad_dest_type klad_type, + crypto_handle mpi_keyslot_handle); +td_s32 ot_mpi_klad_detach(crypto_handle mpi_klad_handle, km_klad_dest_type klad_type, + crypto_handle mpi_keyslot_handle); + +td_s32 ot_mpi_klad_set_attr(crypto_handle mpi_klad_handle, const km_klad_attr *attr); +td_s32 ot_mpi_klad_get_attr(crypto_handle mpi_klad_handle, km_klad_attr *attr); + +td_s32 ot_mpi_klad_set_session_key(crypto_handle mpi_klad_handle, const km_klad_session_key *key); +td_s32 ot_mpi_klad_set_content_key(crypto_handle mpi_klad_handle, const km_klad_content_key *key); + +td_s32 ot_mpi_klad_set_clear_key(crypto_handle mpi_klad_handle, const km_klad_clear_key *key); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi_api/ot_mpi_otp.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi_api/ot_mpi_otp.h new file mode 100644 index 00000000..fb0eed1e --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/ot_mpi_api/ot_mpi_otp.h @@ -0,0 +1,32 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef OT_MPI_OTP_H +#define OT_MPI_OTP_H + +#include "ot_type.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +td_s32 ot_mpi_otp_init(td_void); + +td_s32 ot_mpi_otp_deinit(td_void); + +td_s32 ot_mpi_otp_read_word(td_u32 offset, td_u32 *data); + +td_s32 ot_mpi_otp_read_byte(td_u32 offset, td_u8 *data); + +td_s32 ot_mpi_otp_write_byte(td_u32 offset, td_u8 data); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_common.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_common.c new file mode 100644 index 00000000..f825adfa --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_common.c @@ -0,0 +1,73 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "uapi_common.h" + +#include "crypto_ioctl_cmd.h" +#include "crypto_osal_user_lib.h" + +static crypto_mutex_t g_crypto_mutex = CRYPTO_PTHREAD_MUTEX_INITIALIZER; + +#define crypto_common_lock() (void)crypto_pthread_mutex_lock(&g_crypto_mutex) +#define crypto_common_unlock() (void)crypto_pthread_mutex_unlock(&g_crypto_mutex) + +static td_u32 g_init_counter = 0; +#define CRYPTO_INIT_MAX_NUM 0xffffffff + +static td_s32 g_dev_fd = -1; + +int crypto_cipher_open(void) +{ + int ret = TD_FAILURE; + crypto_common_lock(); + if (g_init_counter >= CRYPTO_INIT_MAX_NUM) { + ret = ERROR_COUNT_OVERFLOW; + goto exit_unlock; + } + + if (g_init_counter > 0) { + g_init_counter++; + ret = TD_SUCCESS; + goto exit_unlock; + } + + g_dev_fd = crypto_open("/dev/" CRYPTO_CIPHER_DEV_NAME, O_RDWR, 0); + if (g_dev_fd < 0) { + ret = ERROR_DEV_OPEN_FAILED; + goto exit_unlock; + } + g_init_counter++; + + ret = TD_SUCCESS; +exit_unlock: + crypto_common_unlock(); + return ret; +} + +void crypto_cipher_close(void) +{ + crypto_common_lock(); + + if (g_init_counter > 0) { + g_init_counter--; + } + if (g_init_counter == 0) { + crypto_close(g_dev_fd); + g_dev_fd = -1; + } + crypto_common_unlock(); +} + +int crypto_cipher_ioctl(int cmd, void *args) +{ + return crypto_ioctl(g_dev_fd, cmd, args); +} + +int crypto_cipher_is_init(void) +{ + if (g_init_counter == 0) { + return 0; + } + return 1; +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_common.h b/kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_common.h new file mode 100644 index 00000000..a87e9902 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_common.h @@ -0,0 +1,18 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#ifndef UAPI_COMMON_H +#define UAPI_COMMON_H + +#include "crypto_platform.h" + +int crypto_cipher_open(void); + +void crypto_cipher_close(void); + +int crypto_cipher_ioctl(int cmd, void *args); + +int crypto_cipher_is_init(void); + +#endif \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_hash.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_hash.c new file mode 100644 index 00000000..98708864 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_hash.c @@ -0,0 +1,215 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "uapi_hash.h" + +#include + +#include "uapi_common.h" +#include "crypto_ioctl_cmd.h" +#include "crypto_osal_user_lib.h" + +#define HASH_COMPAT_ERRNO(err_code) UAPI_COMPAT_ERRNO(ERROR_MODULE_HASH, err_code) + +#define CRYPTO_HASH_MAX_PROCESS_LEN (4 * 1024) + +#define crypto_hash_init_chk() do { \ + if (crypto_cipher_is_init() == 0) { \ + return HASH_COMPAT_ERRNO(ERROR_NOT_INIT); \ + } \ +} while (0) + +td_s32 unify_uapi_cipher_hash_init(td_void) +{ + td_s32 ret = CRYPTO_SUCCESS; + + crypto_uapi_func_enter(); + + ret = crypto_cipher_open(); + if (ret != TD_SUCCESS) { + return ret; + } + + ret = crypto_cipher_ioctl(CRYPTO_CMD_HASH_INIT, TD_NULL); + if (ret != CRYPTO_SUCCESS) { + printf("crypto_ioctl failed, ret is 0x%x\n", ret); + crypto_cipher_close(); + return ret; + } + + crypto_uapi_func_exit(); + return ret; +} + +td_s32 unify_uapi_cipher_hash_deinit(td_void) +{ + td_s32 ret = CRYPTO_SUCCESS; + + crypto_uapi_func_enter(); + + if (crypto_cipher_is_init() == 0) { + return CRYPTO_SUCCESS; + } + + ret = crypto_cipher_ioctl(CRYPTO_CMD_HASH_DEINIT, TD_NULL); + if (ret != CRYPTO_SUCCESS) { + printf("crypto_ioctl failed, ret is 0x%x\n", ret); + } + + crypto_cipher_close(); + + crypto_uapi_func_exit(); + return ret; +} + +td_s32 unify_uapi_cipher_hash_start(td_handle *uapi_hash_handle, const crypto_hash_attr *hash_attr) +{ + td_s32 ret = CRYPTO_SUCCESS; + hash_start_ctl_t start_ctl; + + crypto_uapi_func_enter(); + crypto_hash_init_chk(); + + crypto_chk_return(uapi_hash_handle == TD_NULL, HASH_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), + "uapi_hash_handle is NULL\n"); + crypto_chk_return(hash_attr == TD_NULL, HASH_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "hash_attr is NULL\n"); + + (td_void)memset_s(&start_ctl, sizeof(start_ctl), 0, sizeof(start_ctl)); + start_ctl.hash_type = hash_attr->hash_type; + start_ctl.is_long_term = hash_attr->is_long_term; + start_ctl.is_keyslot = hash_attr->is_keyslot; + start_ctl.key.p = hash_attr->key; + start_ctl.key_len = hash_attr->key_len; + start_ctl.drv_keyslot_handle = hash_attr->drv_keyslot_handle; + + ret = crypto_cipher_ioctl(CRYPTO_CMD_HASH_START, &start_ctl); + if (ret != TD_SUCCESS) { + printf("crypto_ioctl failed, ret is 0x%x\n", ret); + return ret; + } + + *uapi_hash_handle = start_ctl.kapi_hash_handle; + + crypto_uapi_func_exit(); + return ret; +} + +td_s32 unify_uapi_cipher_hash_update(td_handle uapi_hash_handle, const crypto_buf_attr *src_buf, const td_u32 len) +{ + td_s32 ret = CRYPTO_SUCCESS; + hash_update_ctl_t update_ctl; + + crypto_uapi_func_enter(); + crypto_hash_init_chk(); + + crypto_chk_return(src_buf == TD_NULL, HASH_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "src_buf is NULL\n"); + + (td_void)memset_s(&update_ctl, sizeof(update_ctl), 0, sizeof(update_ctl)); + update_ctl.kapi_hash_handle = uapi_hash_handle; + update_ctl.src_buf.p = src_buf->virt_addr; + update_ctl.len = len; + ret = crypto_cipher_ioctl(CRYPTO_CMD_HASH_UPDATE, &update_ctl); + if (ret != TD_SUCCESS) { + printf("crypto_ioctl failed, ret is 0x%x\n", ret); + return ret; + } + + crypto_uapi_func_exit(); + return ret; +} + +td_s32 unify_uapi_cipher_hash_finish(td_handle uapi_hash_handle, td_u8 *out, td_u32 *out_len) +{ + td_s32 ret = CRYPTO_SUCCESS; + hash_finish_ctl_t finish_ctl; + + crypto_uapi_func_enter(); + crypto_hash_init_chk(); + + crypto_chk_return(out_len == TD_NULL, HASH_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "out_len is NULL\n"); + + (td_void)memset_s(&finish_ctl, sizeof(finish_ctl), 0, sizeof(finish_ctl)); + + finish_ctl.kapi_hash_handle = uapi_hash_handle; + finish_ctl.out.p = out; + finish_ctl.out_len = *out_len; + + ret = crypto_cipher_ioctl(CRYPTO_CMD_HASH_FINISH, &finish_ctl); + if (ret != TD_SUCCESS) { + printf("crypto_ioctl failed, ret is 0x%x\n", ret); + return ret; + } + crypto_chk_return(*out_len < finish_ctl.out_len, HASH_COMPAT_ERRNO(ERROR_INVALID_PARAM), "out_len is not enough\n"); + *out_len = finish_ctl.out_len; + + crypto_uapi_func_exit(); + return ret; +} + +td_s32 unify_uapi_cipher_hash_get(td_handle uapi_hash_handle, crypto_hash_clone_ctx *hash_clone_ctx) +{ + td_s32 ret = CRYPTO_SUCCESS; + hash_clone_ctl_t clone_ctl; + + crypto_uapi_func_enter(); + crypto_hash_init_chk(); + + (td_void)memset_s(&clone_ctl, sizeof(clone_ctl), 0, sizeof(clone_ctl)); + clone_ctl.kapi_hash_handle = uapi_hash_handle; + clone_ctl.hash_clone_ctx.p = (td_void *)hash_clone_ctx; + clone_ctl.ctx_size = sizeof(crypto_hash_clone_ctx); + + ret = crypto_cipher_ioctl(CRYPTO_CMD_HASH_GET, &clone_ctl); + if (ret != TD_SUCCESS) { + printf("crypto_ioctl failed, ret is 0x%x\n", ret); + return ret; + } + + crypto_uapi_func_exit(); + return ret; +} + +td_s32 unify_uapi_cipher_hash_set(td_handle uapi_hash_handle, const crypto_hash_clone_ctx *hash_clone_ctx) +{ + td_s32 ret = CRYPTO_SUCCESS; + hash_clone_ctl_t clone_ctl; + + crypto_uapi_func_enter(); + crypto_hash_init_chk(); + + (td_void)memset_s(&clone_ctl, sizeof(clone_ctl), 0, sizeof(clone_ctl)); + clone_ctl.kapi_hash_handle = uapi_hash_handle; + clone_ctl.hash_clone_ctx.p = (td_void *)hash_clone_ctx; + clone_ctl.ctx_size = sizeof(crypto_hash_clone_ctx); + + ret = crypto_cipher_ioctl(CRYPTO_CMD_HASH_SET, &clone_ctl); + if (ret != TD_SUCCESS) { + printf("crypto_ioctl failed, ret is 0x%x\n", ret); + return ret; + } + + crypto_uapi_func_exit(); + return ret; +} + +td_s32 unify_uapi_cipher_hash_destroy(td_handle uapi_hash_handle) +{ + td_s32 ret = CRYPTO_SUCCESS; + hash_handle_ctl_t handle_ctl; + + crypto_uapi_func_enter(); + crypto_hash_init_chk(); + + (td_void)memset_s(&handle_ctl, sizeof(handle_ctl), 0, sizeof(handle_ctl)); + handle_ctl.kapi_hash_handle = uapi_hash_handle; + + ret = crypto_cipher_ioctl(CRYPTO_CMD_HASH_DESTROY, &handle_ctl); + if (ret != TD_SUCCESS) { + printf("crypto_ioctl failed, ret is 0x%x\n", ret); + return ret; + } + + crypto_uapi_func_exit(); + return ret; +} diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_kdf.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_kdf.c new file mode 100644 index 00000000..20ff6aef --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_kdf.c @@ -0,0 +1,43 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "uapi_kdf.h" + +#include + +#include "uapi_common.h" +#include "crypto_ioctl_cmd.h" +#include "crypto_osal_user_lib.h" + +#define HASH_COMPAT_ERRNO(err_code) UAPI_COMPAT_ERRNO(ERROR_MODULE_HASH, err_code) + +td_s32 unify_uapi_cipher_pbkdf2(const crypto_kdf_pbkdf2_param *param, td_u8 *out, const td_u32 out_len) +{ + td_s32 ret = TD_SUCCESS; + pbkdf2_ctl_t pbkdf2_ctl; + crypto_uapi_func_enter(); + + crypto_chk_return(param == TD_NULL, HASH_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "param is NULL\n"); + + (td_void)memset_s(&pbkdf2_ctl, sizeof(pbkdf2_ctl), 0, sizeof(pbkdf2_ctl)); + pbkdf2_ctl.hash_type = param->hash_type; + pbkdf2_ctl.password.p = param->password; + pbkdf2_ctl.salt.p = param->salt; + pbkdf2_ctl.plen = param->plen; + pbkdf2_ctl.slen = param->slen; + pbkdf2_ctl.count = param->count; + pbkdf2_ctl.out.p = out; + pbkdf2_ctl.out_len = out_len; + + ret = crypto_cipher_open(); + crypto_chk_return(ret != TD_SUCCESS, ret, "crypto_cipher_open failed\n"); + + ret = crypto_cipher_ioctl(CRYPTO_CMD_PBKDF2, &pbkdf2_ctl); + crypto_chk_goto(ret != TD_SUCCESS, exit_close, "crypto_ioctl failed, ret is 0x%x\n", ret); + +exit_close: + crypto_cipher_close(); + crypto_uapi_func_exit(); + return ret; +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_km.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_km.c new file mode 100644 index 00000000..03728b37 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_km.c @@ -0,0 +1,307 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "uapi_km.h" + +#include +#include +#include +#include + +#include "ot_type.h" +#include "crypto_osal_user_lib.h" +#include "crypto_km_struct.h" +#include "crypto_errno.h" +#include "ioctl_km.h" +#include "crypto_common_macro.h" + +#define REF_COUNT_MAX_NUM 0x7FFFFFFF +#define KM_COMPAT_ERRNO(err_code) UAPI_COMPAT_ERRNO(ERROR_MODULE_KM, err_code) +#define km_null_ptr_chk(ptr) \ + crypto_chk_return((ptr) == TD_NULL, KM_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), #ptr" is NULL\n") + +typedef struct mpi_mgnt { + crypto_mutex_t lock; + td_s32 ref_count; + td_s32 dev_fd; +} mpi_mgnt_t; + +static mpi_mgnt_t km_mgnt = { + .lock = CRYPTO_PTHREAD_MUTEX_INITIALIZER, + .ref_count = -1, + .dev_fd = -1 +}; + +static td_bool inner_km_is_init(td_void) +{ + if (km_mgnt.ref_count >= 0) { + return TD_TRUE; + } + return TD_FALSE; +} + +td_s32 uapi_km_init(td_void) +{ + td_s32 ret = TD_SUCCESS; + crypto_uapi_func_enter(); + crypto_pthread_mutex_lock(&km_mgnt.lock); + + if (km_mgnt.ref_count >= 0) { + if (km_mgnt.ref_count < REF_COUNT_MAX_NUM) { + km_mgnt.ref_count++; + goto exit; + } + } + km_mgnt.dev_fd = crypto_open("/dev/km", O_RDWR, 0); + if (km_mgnt.dev_fd < 0) { + printf("open /dev/km failed\n"); + ret = KM_COMPAT_ERRNO(ERROR_DEV_OPEN_FAILED); + goto exit; + } + + km_mgnt.ref_count = 0; + +exit: + crypto_pthread_mutex_unlock(&km_mgnt.lock); + crypto_uapi_func_exit(); + return ret; +} + +td_s32 uapi_km_deinit(td_void) +{ + td_s32 ret = TD_SUCCESS; + crypto_uapi_func_enter(); + crypto_pthread_mutex_lock(&km_mgnt.lock); + + if (km_mgnt.ref_count > 0) { + km_mgnt.ref_count--; + goto exit; + } + + if (km_mgnt.ref_count == 0) { + km_mgnt.ref_count--; + crypto_close(km_mgnt.dev_fd); + km_mgnt.dev_fd = -1; + } + +exit: + crypto_pthread_mutex_unlock(&km_mgnt.lock); + crypto_uapi_func_exit(); + return ret; +} + +/* Keyslot. */ +td_s32 uapi_keyslot_create(crypto_handle *mpi_keyslot_handle, km_keyslot_type keyslot_type) +{ + td_s32 ret = TD_SUCCESS; + keyslot_create_ctl_t keyslot_create_ctl = {0}; + + crypto_uapi_func_enter(); + crypto_chk_return(inner_km_is_init() != TD_TRUE, KM_COMPAT_ERRNO(ERROR_NOT_INIT), "KM not init\n"); + km_null_ptr_chk(mpi_keyslot_handle); + + keyslot_create_ctl.keyslot_type = keyslot_type; + ret = crypto_km_ioctl(km_mgnt.dev_fd, CMD_KEYSLOT_CREATE_HANDLE, &keyslot_create_ctl); + crypto_chk_return(ret != TD_SUCCESS, ret, "crypto_km_ioctl failed, ret is 0x%x\n", ret); + + *mpi_keyslot_handle = keyslot_create_ctl.kapi_keyslot_handle; + + crypto_uapi_func_exit(); + return ret; +} + +td_s32 uapi_keyslot_destroy(crypto_handle mpi_keyslot_handle) +{ + td_s32 ret = TD_SUCCESS; + + keyslot_destroy_ctl_t keyslot_destroy_ctl = {0}; + + crypto_uapi_func_enter(); + crypto_chk_return(inner_km_is_init() != TD_TRUE, KM_COMPAT_ERRNO(ERROR_NOT_INIT), "KM not init\n"); + + keyslot_destroy_ctl.kapi_keyslot_handle = mpi_keyslot_handle; + ret = crypto_km_ioctl(km_mgnt.dev_fd, CMD_KEYSLOT_DESTROY_HANDLE, &keyslot_destroy_ctl); + crypto_chk_return(ret != TD_SUCCESS, ret, "crypto_km_ioctl failed, ret is 0x%x\n", ret); + + crypto_uapi_func_exit(); + return ret; +} + +/* Klad. */ +td_s32 uapi_klad_create(crypto_handle *mpi_klad_handle) +{ + td_s32 ret = TD_SUCCESS; + klad_handle_ctl_t klad_handle_ctl = {0}; + + crypto_uapi_func_enter(); + crypto_chk_return(inner_km_is_init() != TD_TRUE, KM_COMPAT_ERRNO(ERROR_NOT_INIT), "KM not init\n"); + km_null_ptr_chk(mpi_klad_handle); + + ret = crypto_km_ioctl(km_mgnt.dev_fd, CMD_KLAD_CREATE_HANDLE, &klad_handle_ctl); + crypto_chk_return(ret != TD_SUCCESS, ret, "crypto_km_ioctl failed, ret is 0x%x\n", ret); + + *mpi_klad_handle = klad_handle_ctl.kapi_klad_handle; + + crypto_uapi_func_exit(); + return ret; +} + +td_s32 uapi_klad_destroy(crypto_handle mpi_klad_handle) +{ + td_s32 ret = TD_SUCCESS; + klad_handle_ctl_t klad_handle_ctl = {0}; + + crypto_uapi_func_enter(); + crypto_chk_return(inner_km_is_init() != TD_TRUE, KM_COMPAT_ERRNO(ERROR_NOT_INIT), "KM not init\n"); + + klad_handle_ctl.kapi_klad_handle = mpi_klad_handle; + ret = crypto_km_ioctl(km_mgnt.dev_fd, CMD_KLAD_DESTROY_HANDLE, &klad_handle_ctl); + crypto_chk_print(ret != TD_SUCCESS, "crypto_km_ioctl failed, ret is 0x%x\n", ret); + + crypto_uapi_func_exit(); + return ret; +} + +td_s32 uapi_klad_attach(crypto_handle mpi_klad_handle, km_klad_dest_type klad_type, + crypto_handle mpi_keyslot_handle) +{ + td_s32 ret = TD_SUCCESS; + klad_attach_ctl_t klad_attach_ctl = {0}; + + crypto_uapi_func_enter(); + crypto_chk_return(inner_km_is_init() != TD_TRUE, KM_COMPAT_ERRNO(ERROR_NOT_INIT), "KM not init\n"); + + klad_attach_ctl.kapi_klad_handle = mpi_klad_handle; + klad_attach_ctl.kapi_keyslot_handle =mpi_keyslot_handle; + klad_attach_ctl.klad_type = klad_type; + + ret = crypto_km_ioctl(km_mgnt.dev_fd, CMD_KLAD_ATTACH, &klad_attach_ctl); + crypto_chk_return(ret != TD_SUCCESS, ret, "crypto_km_ioctl failed, ret is 0x%x\n", ret); + + crypto_uapi_func_exit(); + return ret; +} + +td_s32 uapi_klad_detach(crypto_handle mpi_klad_handle, km_klad_dest_type klad_type, + crypto_handle mpi_keyslot_handle) +{ + td_s32 ret = TD_SUCCESS; + + klad_attach_ctl_t klad_attach_ctl = {0}; + + crypto_uapi_func_enter(); + crypto_chk_return(inner_km_is_init() != TD_TRUE, KM_COMPAT_ERRNO(ERROR_NOT_INIT), "KM not init\n"); + + klad_attach_ctl.kapi_klad_handle = mpi_klad_handle; + klad_attach_ctl.kapi_keyslot_handle = mpi_keyslot_handle; + klad_attach_ctl.klad_type = klad_type; + + ret = crypto_km_ioctl(km_mgnt.dev_fd, CMD_KLAD_DETACH, &klad_attach_ctl); + crypto_chk_return(ret != TD_SUCCESS, ret, "crypto_km_ioctl failed, ret is 0x%x\n", ret); + + crypto_uapi_func_exit(); + return ret; +} + +td_s32 uapi_klad_set_attr(crypto_handle mpi_klad_handle, const km_klad_attr *attr) +{ + td_s32 ret = TD_SUCCESS; + klad_attr_ctl_t klad_attr_ctl = {0}; + + crypto_uapi_func_enter(); + crypto_chk_return(inner_km_is_init() != TD_TRUE, KM_COMPAT_ERRNO(ERROR_NOT_INIT), "KM not init\n"); + km_null_ptr_chk(attr); + + klad_attr_ctl.kapi_klad_handle = mpi_klad_handle; + (td_void)memcpy_s(&klad_attr_ctl.attr, sizeof(km_klad_attr), attr, sizeof(km_klad_attr)); + ret = crypto_km_ioctl(km_mgnt.dev_fd, CMD_KLAD_SET_ATTR, &klad_attr_ctl); + crypto_chk_return(ret != TD_SUCCESS, ret, "crypto_km_ioctl failed, ret is 0x%x\n", ret); + + crypto_uapi_func_exit(); + return ret; +} + +td_s32 uapi_klad_get_attr(crypto_handle mpi_klad_handle, km_klad_attr *attr) +{ + td_s32 ret = TD_SUCCESS; + klad_attr_ctl_t klad_attr_ctl = {0}; + + crypto_uapi_func_enter(); + crypto_chk_return(inner_km_is_init() != TD_TRUE, KM_COMPAT_ERRNO(ERROR_NOT_INIT), "KM not init\n"); + km_null_ptr_chk(attr); + + klad_attr_ctl.kapi_klad_handle = mpi_klad_handle; + ret = crypto_km_ioctl(km_mgnt.dev_fd, CMD_KLAD_GET_ATTR, &klad_attr_ctl); + crypto_chk_return(ret != TD_SUCCESS, ret, "crypto_km_ioctl failed, ret is 0x%x\n", ret); + (td_void)memcpy_s(attr, sizeof(km_klad_attr), &klad_attr_ctl.attr, sizeof(km_klad_attr)); + + crypto_uapi_func_exit(); + return ret; +} + +td_s32 uapi_klad_set_session_key(crypto_handle mpi_klad_handle, const km_klad_session_key *key) +{ + td_s32 ret = TD_SUCCESS; + klad_set_session_key_ctl_t klad_set_session_key_ctl = {0}; + + crypto_uapi_func_enter(); + crypto_chk_return(inner_km_is_init() != TD_TRUE, KM_COMPAT_ERRNO(ERROR_NOT_INIT), "KM not init\n"); + km_null_ptr_chk(key); + km_null_ptr_chk(key->key); + + klad_set_session_key_ctl.kapi_klad_handle = mpi_klad_handle; + klad_set_session_key_ctl.alg = key->alg; + klad_set_session_key_ctl.level = key->level; + klad_set_session_key_ctl.key_size = key->key_size; + klad_set_session_key_ctl.key.p = key->key; + ret = crypto_km_ioctl(km_mgnt.dev_fd, CMD_KLAD_SET_SESSION_KEY, &klad_set_session_key_ctl); + crypto_chk_return(ret != TD_SUCCESS, ret, "crypto_km_ioctl failed, ret is 0x%x\n", ret); + + crypto_uapi_func_exit(); + return ret; +} + +td_s32 uapi_klad_set_content_key(crypto_handle mpi_klad_handle, const km_klad_content_key *key) +{ + td_s32 ret = TD_SUCCESS; + klad_set_content_key_ctl_t klad_set_content_key_ctl = {0}; + + crypto_uapi_func_enter(); + crypto_chk_return(inner_km_is_init() != TD_TRUE, KM_COMPAT_ERRNO(ERROR_NOT_INIT), "KM not init\n"); + km_null_ptr_chk(key); + km_null_ptr_chk(key->key); + + klad_set_content_key_ctl.kapi_klad_handle = mpi_klad_handle; + klad_set_content_key_ctl.alg = key->alg; + klad_set_content_key_ctl.key_parity = key->key_parity; + klad_set_content_key_ctl.key_size = key->key_size; + klad_set_content_key_ctl.key.p = key->key; + ret = crypto_km_ioctl(km_mgnt.dev_fd, CMD_KLAD_SET_CONTENT_KEY, &klad_set_content_key_ctl); + crypto_chk_return(ret != TD_SUCCESS, ret, "crypto_km_ioctl failed, ret is 0x%x\n", ret); + + crypto_uapi_func_exit(); + return ret; +} + +td_s32 uapi_klad_set_clear_key(crypto_handle mpi_klad_handle, const km_klad_clear_key *key) +{ + td_s32 ret = TD_SUCCESS; + klad_set_clear_key_ctl_t klad_set_clear_key_ctl = {0}; + + crypto_uapi_func_enter(); + crypto_chk_return(inner_km_is_init() != TD_TRUE, KM_COMPAT_ERRNO(ERROR_NOT_INIT), "KM not init\n"); + km_null_ptr_chk(key); + km_null_ptr_chk(key->key); + + klad_set_clear_key_ctl.kapi_klad_handle = mpi_klad_handle; + klad_set_clear_key_ctl.hmac_type = key->hmac_type; + klad_set_clear_key_ctl.key_parity = key->key_parity; + klad_set_clear_key_ctl.key_size = key->key_size; + klad_set_clear_key_ctl.key.p = key->key; + ret = crypto_km_ioctl(km_mgnt.dev_fd, CMD_KLAD_SET_CLEAR_KEY, &klad_set_clear_key_ctl); + crypto_chk_return(ret != TD_SUCCESS, ret, "crypto_km_ioctl failed, ret is 0x%x\n", ret); + + crypto_uapi_func_exit(); + return ret; +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_otp.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_otp.c new file mode 100644 index 00000000..d944e179 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_otp.c @@ -0,0 +1,136 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "uapi_otp.h" + +#include +#include +#include +#include + +#include "ot_type.h" +#include "crypto_errno.h" +#include "crypto_osal_user_lib.h" +#include "crypto_common_macro.h" +#include "ioctl_otp.h" + +#define REF_COUNT_MAX_NUM 0x7FFFFFFF + +typedef struct mpi_mgnt { + crypto_mutex_t lock; + td_s32 ref_count; + td_s32 dev_fd; +} mpi_mgnt_t; + +static mpi_mgnt_t otp_mgnt = { + .lock = CRYPTO_PTHREAD_MUTEX_INITIALIZER, + .ref_count = -1, + .dev_fd = -1 +}; + +td_s32 uapi_otp_init(td_void) +{ + td_s32 ret = TD_SUCCESS; + crypto_uapi_func_enter(); + crypto_pthread_mutex_lock(&otp_mgnt.lock); + + if (otp_mgnt.ref_count >= 0) { + if (otp_mgnt.ref_count < REF_COUNT_MAX_NUM) { + otp_mgnt.ref_count++; + goto exit; + } + } + otp_mgnt.dev_fd = crypto_open("/dev/otp", O_RDWR, 0); + if (otp_mgnt.dev_fd < 0) { + printf("open /dev/otp failed\n"); + ret = TD_FAILURE; + goto exit; + } + + otp_mgnt.ref_count = 0; + +exit: + crypto_pthread_mutex_unlock(&otp_mgnt.lock); + crypto_uapi_func_exit(); + return ret; +} + +td_s32 uapi_otp_deinit(td_void) +{ + td_s32 ret = TD_SUCCESS; + crypto_pthread_mutex_lock(&otp_mgnt.lock); + + if (otp_mgnt.ref_count > 0) { + otp_mgnt.ref_count--; + goto exit; + } + + if (otp_mgnt.ref_count == 0) { + otp_mgnt.ref_count--; + crypto_close(otp_mgnt.dev_fd); + otp_mgnt.dev_fd = -1; + } + +exit: + crypto_pthread_mutex_unlock(&otp_mgnt.lock); + return ret; +} + +td_s32 uapi_otp_read_word(td_u32 offset, td_u32 *data) +{ + td_s32 ret = TD_SUCCESS; + otp_word_ctl_t word_ctl = {0}; + + crypto_uapi_func_enter(); + crypto_param_require(data != TD_NULL); + + word_ctl.addr = offset; + ret = crypto_otp_ioctl(otp_mgnt.dev_fd, CMD_OTP_READ_WORD, &word_ctl); + crypto_chk_goto(ret != TD_SUCCESS, exit, "crypto_otp_ioctl failed, ret is 0x%x\n", ret); + + *data = word_ctl.word; + crypto_uapi_func_exit(); + +exit: + (td_void)memset_s(&word_ctl, sizeof(word_ctl), 0, sizeof(word_ctl)); + return ret; +} + +td_s32 uapi_otp_read_byte(td_u32 offset, td_u8 *data) +{ + td_s32 ret = TD_SUCCESS; + otp_byte_ctl_t byte_ctl = {0}; + + crypto_uapi_func_enter(); + crypto_param_require(data != TD_NULL); + + byte_ctl.addr = offset; + ret = crypto_otp_ioctl(otp_mgnt.dev_fd, CMD_OTP_READ_BYTE, &byte_ctl); + crypto_chk_goto(ret != TD_SUCCESS, exit, "crypto_otp_ioctl failed, ret is 0x%x\n", ret); + + *data = byte_ctl.byte; + + crypto_uapi_func_exit(); +exit: + (td_void)memset_s(&byte_ctl, sizeof(otp_byte_ctl_t), 0, sizeof(otp_byte_ctl_t)); + return ret; +} + +td_s32 uapi_otp_write_byte(td_u32 offset, td_u8 data) +{ + td_s32 ret = TD_SUCCESS; + otp_byte_ctl_t byte_ctl = {0}; + + crypto_uapi_func_enter(); + + byte_ctl.addr = offset; + byte_ctl.byte = data; + ret = crypto_otp_ioctl(otp_mgnt.dev_fd, CMD_OTP_WRITE_BYTE, &byte_ctl); + crypto_chk_goto(ret != TD_SUCCESS, exit, "crypto_otp_ioctl failed, ret is 0x%x\n", ret); + + crypto_uapi_func_exit(); +exit: + (td_void)memset_s(&byte_ctl, sizeof(byte_ctl), 0, sizeof(byte_ctl)); + return ret; +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_pke.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_pke.c new file mode 100644 index 00000000..488ef647 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_pke.c @@ -0,0 +1,608 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "uapi_pke.h" +#include + +#include "uapi_common.h" +#include "crypto_ioctl_cmd.h" +#include "crypto_osal_user_lib.h" + +#define PKE_COMPAT_ERRNO(err_code) UAPI_COMPAT_ERRNO(ERROR_MODULE_PKE, err_code) + +#define pke_null_ptr_chk(ptr) \ + crypto_chk_return((ptr) == TD_NULL, PKE_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), #ptr" is NULL\n") + +#define pke_init_chk() do { \ + if (crypto_cipher_is_init() == 0) { \ + return PKE_COMPAT_ERRNO(ERROR_NOT_INIT); \ + } \ +} while (0) + +td_s32 unify_uapi_cipher_pke_init(td_void) +{ + td_s32 ret = CRYPTO_SUCCESS; + + crypto_uapi_func_enter(); + + ret = crypto_cipher_open(); + if (ret != TD_SUCCESS) { + return ret; + } + + crypto_uapi_func_exit(); + return ret; +} + +td_s32 unify_uapi_cipher_pke_deinit(td_void) +{ + td_s32 ret = CRYPTO_SUCCESS; + + crypto_uapi_func_enter(); + + if (crypto_cipher_is_init() == 0) { + return CRYPTO_SUCCESS; + } + + crypto_cipher_close(); + + crypto_uapi_func_exit(); + return ret; +} + +td_s32 unify_uapi_cipher_pke_ecc_gen_key(drv_pke_ecc_curve_type curve_type, const drv_pke_data *input_priv_key, + const drv_pke_data *output_priv_key, const drv_pke_ecc_point *output_pub_key) +{ + td_s32 ret = TD_SUCCESS; + pke_ecc_gen_key_ctl_t ecc_gen_key_ctl; + + crypto_uapi_func_enter(); + + pke_init_chk(); + + pke_null_ptr_chk(output_priv_key); + pke_null_ptr_chk(output_pub_key); + + (td_void)memset_s(&ecc_gen_key_ctl, sizeof(ecc_gen_key_ctl), 0, sizeof(ecc_gen_key_ctl)); + ecc_gen_key_ctl.curve_type = curve_type; + ecc_gen_key_ctl.output_priv_key.data.p = output_priv_key->data; + ecc_gen_key_ctl.output_priv_key.length = output_priv_key->length; + ecc_gen_key_ctl.output_pub_key.x.p = output_pub_key->x; + ecc_gen_key_ctl.output_pub_key.y.p = output_pub_key->y; + ecc_gen_key_ctl.output_pub_key.length = output_pub_key->length; + + if (input_priv_key != TD_NULL) { + ecc_gen_key_ctl.input_priv_key.data.p = input_priv_key->data; + ecc_gen_key_ctl.input_priv_key.length = input_priv_key->length; + } + ret = crypto_cipher_ioctl(CRYPTO_CMD_PKE_ECC_GEN_KEY, &ecc_gen_key_ctl); + crypto_chk_goto(ret != TD_SUCCESS, exit, "crypto_ioctl failed, ret is 0x%x\n", ret); + + crypto_uapi_func_exit(); +exit: + (td_void)memset_s(&ecc_gen_key_ctl, sizeof(ecc_gen_key_ctl), 0, sizeof(ecc_gen_key_ctl)); + return ret; +} + +td_s32 unify_uapi_cipher_pke_ecc_gen_ecdh_key(drv_pke_ecc_curve_type curve_type, const drv_pke_ecc_point *input_pub_key, + const drv_pke_data *input_priv_key, const drv_pke_data *output_shared_key) +{ + td_s32 ret = TD_SUCCESS; + pke_ecc_gen_ecdh_key_ctl_t gen_ecdh_key_ctl; + crypto_uapi_func_enter(); + pke_init_chk(); + + pke_null_ptr_chk(input_pub_key); + pke_null_ptr_chk(input_priv_key); + pke_null_ptr_chk(output_shared_key); + + (td_void)memset_s(&gen_ecdh_key_ctl, sizeof(gen_ecdh_key_ctl), 0, sizeof(gen_ecdh_key_ctl)); + gen_ecdh_key_ctl.curve_type = curve_type; + gen_ecdh_key_ctl.input_pub_key.x.p = input_pub_key->x; + gen_ecdh_key_ctl.input_pub_key.y.p = input_pub_key->y; + gen_ecdh_key_ctl.input_pub_key.length = input_pub_key->length; + gen_ecdh_key_ctl.input_priv_key.data.p = input_priv_key->data; + gen_ecdh_key_ctl.input_priv_key.length = input_priv_key->length; + gen_ecdh_key_ctl.output_shared_key.data.p = output_shared_key->data; + gen_ecdh_key_ctl.output_shared_key.length = output_shared_key->length; + + ret = crypto_cipher_ioctl(CRYPTO_CMD_PKE_ECC_GEN_ECDH_KEY, &gen_ecdh_key_ctl); + crypto_chk_goto(ret != TD_SUCCESS, exit, "crypto_ioctl failed, ret is 0x%x\n", ret); + + crypto_uapi_func_exit(); + +exit: + (td_void)memset_s(&gen_ecdh_key_ctl, sizeof(gen_ecdh_key_ctl), 0, sizeof(gen_ecdh_key_ctl)); + return ret; +} + +td_s32 unify_uapi_cipher_pke_ecdsa_sign(drv_pke_ecc_curve_type curve_type, const drv_pke_data *priv_key, + const drv_pke_data *hash, const drv_pke_ecc_sig *sig) +{ + td_s32 ret = TD_SUCCESS; + pke_ecdsa_sign_ctl_t ecdsa_sign_ctl; + + crypto_uapi_func_enter(); + pke_init_chk(); + + pke_null_ptr_chk(priv_key); + pke_null_ptr_chk(hash); + pke_null_ptr_chk(sig); + + (td_void)memset_s(&ecdsa_sign_ctl, sizeof(ecdsa_sign_ctl), 0, sizeof(ecdsa_sign_ctl)); + ecdsa_sign_ctl.curve_type = curve_type; + ecdsa_sign_ctl.priv_key.data.p = priv_key->data; + ecdsa_sign_ctl.priv_key.length = priv_key->length; + ecdsa_sign_ctl.hash.data.p = hash->data; + ecdsa_sign_ctl.hash.length = hash->length; + ecdsa_sign_ctl.sig.r.p = sig->r; + ecdsa_sign_ctl.sig.s.p = sig->s; + ecdsa_sign_ctl.sig.length = sig->length; + + ret = crypto_cipher_ioctl(CRYPTO_CMD_PKE_ECDSA_SIGN, &ecdsa_sign_ctl); + crypto_chk_goto(ret != TD_SUCCESS, exit, "crypto_ioctl failed, ret is 0x%x\n", ret); + + crypto_uapi_func_exit(); + +exit: + (td_void)memset_s(&ecdsa_sign_ctl, sizeof(ecdsa_sign_ctl), 0, sizeof(ecdsa_sign_ctl)); + return ret; +} + +td_s32 unify_uapi_cipher_pke_ecdsa_verify(drv_pke_ecc_curve_type curve_type, const drv_pke_ecc_point *pub_key, + const drv_pke_data *hash, const drv_pke_ecc_sig *sig) +{ + td_s32 ret = TD_SUCCESS; + pke_ecdsa_verify_ctl_t ecdsa_verify_ctl; + crypto_uapi_func_enter(); + pke_init_chk(); + + pke_null_ptr_chk(pub_key); + pke_null_ptr_chk(hash); + pke_null_ptr_chk(sig); + + (td_void)memset_s(&ecdsa_verify_ctl, sizeof(ecdsa_verify_ctl), 0, sizeof(ecdsa_verify_ctl)); + ecdsa_verify_ctl.curve_type = curve_type; + ecdsa_verify_ctl.pub_key.x.p = pub_key->x; + ecdsa_verify_ctl.pub_key.y.p = pub_key->y; + ecdsa_verify_ctl.pub_key.length = pub_key->length; + ecdsa_verify_ctl.hash.data.p = hash->data; + ecdsa_verify_ctl.hash.length = hash->length; + ecdsa_verify_ctl.sig.r.p = sig->r; + ecdsa_verify_ctl.sig.s.p = sig->s; + ecdsa_verify_ctl.sig.length = sig->length; + + ret = crypto_cipher_ioctl(CRYPTO_CMD_PKE_ECDSA_VERIFY, &ecdsa_verify_ctl); + crypto_chk_goto(ret != TD_SUCCESS, exit, "crypto_ioctl failed, ret is 0x%x\n", ret); + + crypto_uapi_func_exit(); + +exit: + (td_void)memset_s(&ecdsa_verify_ctl, sizeof(ecdsa_verify_ctl), 0, sizeof(ecdsa_verify_ctl)); + return ret; +} + +td_s32 unify_uapi_cipher_pke_eddsa_sign(drv_pke_ecc_curve_type curve_type, const drv_pke_data *priv_key, + const drv_pke_msg *msg, const drv_pke_ecc_sig *sig) +{ + td_s32 ret = TD_SUCCESS; + pke_eddsa_sign_ctl_t eddsa_sign_ctl = {0}; + + crypto_uapi_func_enter(); + pke_init_chk(); + + pke_null_ptr_chk(priv_key); + pke_null_ptr_chk(msg); + pke_null_ptr_chk(sig); + + eddsa_sign_ctl.curve_type = curve_type; + eddsa_sign_ctl.priv_key.data.p = priv_key->data; + eddsa_sign_ctl.priv_key.length = priv_key->length; + eddsa_sign_ctl.msg.data.p = msg->data; + eddsa_sign_ctl.msg.length = msg->length; + eddsa_sign_ctl.msg.buf_sec = msg->buf_sec; + eddsa_sign_ctl.sig.r.p = sig->r; + eddsa_sign_ctl.sig.s.p = sig->s; + eddsa_sign_ctl.sig.length = sig->length; + + ret = crypto_cipher_ioctl(CRYPTO_CMD_PKE_EDDSA_SIGN, &eddsa_sign_ctl); + crypto_chk_goto(ret != TD_SUCCESS, exit, "crypto_ioctl failed, ret is 0x%x\n", ret); + + crypto_uapi_func_exit(); + +exit: + (td_void)memset_s(&eddsa_sign_ctl, sizeof(eddsa_sign_ctl), 0, sizeof(eddsa_sign_ctl)); + return ret; +} + +td_s32 unify_uapi_cipher_pke_eddsa_verify(drv_pke_ecc_curve_type curve_type, const drv_pke_ecc_point *pub_key, + const drv_pke_msg *msg, const drv_pke_ecc_sig *sig) +{ + td_s32 ret = TD_SUCCESS; + pke_eddsa_verify_ctl_t eddsa_verify_ctl = {0}; + crypto_uapi_func_enter(); + pke_init_chk(); + + pke_null_ptr_chk(pub_key); + pke_null_ptr_chk(msg); + pke_null_ptr_chk(sig); + + eddsa_verify_ctl.curve_type = curve_type; + eddsa_verify_ctl.pub_key.y.p = pub_key->y; + eddsa_verify_ctl.pub_key.length = pub_key->length; + eddsa_verify_ctl.msg.data.p = msg->data; + eddsa_verify_ctl.msg.length = msg->length; + eddsa_verify_ctl.msg.buf_sec = msg->buf_sec; + eddsa_verify_ctl.sig.r.p = sig->r; + eddsa_verify_ctl.sig.s.p = sig->s; + eddsa_verify_ctl.sig.length = sig->length; + + ret = crypto_cipher_ioctl(CRYPTO_CMD_PKE_EDDSA_VERIFY, &eddsa_verify_ctl); + crypto_chk_goto(ret != TD_SUCCESS, exit, "crypto_ioctl failed, ret is 0x%x\n", ret); + + crypto_uapi_func_exit(); + +exit: + (td_void)memset_s(&eddsa_verify_ctl, sizeof(eddsa_verify_ctl), 0, sizeof(eddsa_verify_ctl)); + return ret; +} + +td_s32 unify_uapi_cipher_pke_check_dot_on_curve(drv_pke_ecc_curve_type curve_type, const drv_pke_ecc_point *pub_key, + td_bool *is_on_curve) +{ + td_s32 ret = TD_SUCCESS; + pke_check_dot_on_curve_ctl_t dot_on_curve_ctl; + crypto_uapi_func_enter(); + pke_init_chk(); + + pke_null_ptr_chk(pub_key); + pke_null_ptr_chk(is_on_curve); + + (td_void)memset_s(&dot_on_curve_ctl, sizeof(dot_on_curve_ctl), 0, sizeof(dot_on_curve_ctl)); + dot_on_curve_ctl.curve_type = curve_type; + dot_on_curve_ctl.pub_key.x.p = pub_key->x; + dot_on_curve_ctl.pub_key.y.p = pub_key->y; + dot_on_curve_ctl.pub_key.length = pub_key->length; + + ret = crypto_cipher_ioctl(CRYPTO_CMD_PKE_CHECK_DOT_ON_CURVE, &dot_on_curve_ctl); + crypto_chk_goto(ret != TD_SUCCESS, exit, "crypto_ioctl failed, ret is 0x%x\n", ret); + *is_on_curve = dot_on_curve_ctl.is_on_curve; + + crypto_uapi_func_exit(); + +exit: + (td_void)memset_s(&dot_on_curve_ctl, sizeof(dot_on_curve_ctl), 0, sizeof(dot_on_curve_ctl)); + return ret; +} + +td_s32 unify_uapi_cipher_pke_sm2_dsa_hash(const drv_pke_data *sm2_id, const drv_pke_ecc_point *pub_key, + const drv_pke_msg *msg, drv_pke_data *hash) +{ + td_s32 ret = TD_SUCCESS; + pke_sm2_dsa_hash_ctl_t sm2_dsa_hash_ctl; + crypto_uapi_func_enter(); + pke_init_chk(); + + pke_null_ptr_chk(sm2_id); + pke_null_ptr_chk(pub_key); + pke_null_ptr_chk(msg); + pke_null_ptr_chk(hash); + + (td_void)memset_s(&sm2_dsa_hash_ctl, sizeof(sm2_dsa_hash_ctl), 0, sizeof(sm2_dsa_hash_ctl)); + sm2_dsa_hash_ctl.sm2_id.data.p = sm2_id->data; + sm2_dsa_hash_ctl.sm2_id.length = sm2_id->length; + sm2_dsa_hash_ctl.pub_key.x.p = pub_key->x; + sm2_dsa_hash_ctl.pub_key.y.p = pub_key->y; + sm2_dsa_hash_ctl.pub_key.length = pub_key->length; + sm2_dsa_hash_ctl.msg.buf_sec = msg->buf_sec; + sm2_dsa_hash_ctl.msg.data.p = msg->data; + sm2_dsa_hash_ctl.msg.length = msg->length; + sm2_dsa_hash_ctl.hash.data.p = hash->data; + sm2_dsa_hash_ctl.hash.length = hash->length; + + ret = crypto_cipher_ioctl(CRYPTO_CMD_PKE_SM2_DSA_HASH, &sm2_dsa_hash_ctl); + crypto_chk_goto(ret != TD_SUCCESS, exit, "crypto_ioctl failed, ret is 0x%x\n", ret); + + crypto_uapi_func_exit(); + +exit: + (td_void)memset_s(&sm2_dsa_hash_ctl, sizeof(sm2_dsa_hash_ctl), 0, sizeof(sm2_dsa_hash_ctl)); + return ret; +} + +td_s32 unify_uapi_cipher_pke_sm2_public_encrypt(const drv_pke_ecc_point *pub_key, const drv_pke_data *plain_text, + drv_pke_data *cipher_text) +{ + td_s32 ret = TD_SUCCESS; + pke_sm2_public_encrypt_ctl_t sm2_public_encrypt_ctl; + crypto_uapi_func_enter(); + pke_init_chk(); + + pke_null_ptr_chk(pub_key); + pke_null_ptr_chk(plain_text); + pke_null_ptr_chk(cipher_text); + + (td_void)memset_s(&sm2_public_encrypt_ctl, sizeof(sm2_public_encrypt_ctl), 0, sizeof(sm2_public_encrypt_ctl)); + sm2_public_encrypt_ctl.pub_key.x.p = pub_key->x; + sm2_public_encrypt_ctl.pub_key.y.p = pub_key->y; + sm2_public_encrypt_ctl.pub_key.length = pub_key->length; + sm2_public_encrypt_ctl.plain_text.data.p = plain_text->data; + sm2_public_encrypt_ctl.plain_text.length = plain_text->length; + sm2_public_encrypt_ctl.cipher_text.data.p = cipher_text->data; + sm2_public_encrypt_ctl.cipher_text.length = cipher_text->length; + + ret = crypto_cipher_ioctl(CRYPTO_CMD_PKE_SM2_PUBLIC_ENCRYPT, &sm2_public_encrypt_ctl); + crypto_chk_goto(ret != TD_SUCCESS, exit, "crypto_ioctl failed, ret is 0x%x\n", ret); + cipher_text->length = sm2_public_encrypt_ctl.cipher_text.length; + crypto_uapi_func_exit(); + +exit: + (td_void)memset_s(&sm2_public_encrypt_ctl, sizeof(sm2_public_encrypt_ctl), 0, sizeof(sm2_public_encrypt_ctl)); + return ret; +} + + +td_s32 unify_uapi_cipher_pke_sm2_private_decrypt(const drv_pke_data *priv_key, const drv_pke_data *cipher_text, + drv_pke_data *plain_text) +{ + td_s32 ret = TD_SUCCESS; + pke_sm2_private_decrypt_ctl_t sm2_private_decrypt_ctl; + crypto_uapi_func_enter(); + pke_init_chk(); + + pke_null_ptr_chk(priv_key); + pke_null_ptr_chk(cipher_text); + pke_null_ptr_chk(plain_text); + + (td_void)memset_s(&sm2_private_decrypt_ctl, sizeof(sm2_private_decrypt_ctl), 0, sizeof(sm2_private_decrypt_ctl)); + sm2_private_decrypt_ctl.priv_key.data.p = priv_key->data; + sm2_private_decrypt_ctl.priv_key.length = priv_key->length; + sm2_private_decrypt_ctl.cipher_text.data.p = cipher_text->data; + sm2_private_decrypt_ctl.cipher_text.length = cipher_text->length; + sm2_private_decrypt_ctl.plain_text.data.p = plain_text->data; + sm2_private_decrypt_ctl.plain_text.length = plain_text->length; + + ret = crypto_cipher_ioctl(CRYPTO_CMD_PKE_SM2_PRIVATE_DECRYPT, &sm2_private_decrypt_ctl); + crypto_chk_goto(ret != TD_SUCCESS, exit, "crypto_ioctl failed, ret is 0x%x\n", ret); + plain_text->length = sm2_private_decrypt_ctl.plain_text.length; + crypto_uapi_func_exit(); + +exit: + (td_void)memset_s(&sm2_private_decrypt_ctl, sizeof(sm2_private_decrypt_ctl), 0, sizeof(sm2_private_decrypt_ctl)); + return ret; +} + +td_s32 unify_uapi_cipher_pke_mod(const drv_pke_data *a, const drv_pke_data *p, const drv_pke_data *c) +{ + td_s32 ret = TD_SUCCESS; + pke_mod_ctl_t mod_ctr_ctl; + crypto_uapi_func_enter(); + pke_init_chk(); + + pke_null_ptr_chk(a); + pke_null_ptr_chk(p); + pke_null_ptr_chk(c); + + (td_void)memset_s(&mod_ctr_ctl, sizeof(mod_ctr_ctl), 0, sizeof(mod_ctr_ctl)); + mod_ctr_ctl.a.data.p = a->data; + mod_ctr_ctl.a.length = a->length; + mod_ctr_ctl.p.data.p = p->data; + mod_ctr_ctl.p.length = p->length; + mod_ctr_ctl.c.data.p = c->data; + mod_ctr_ctl.c.length = c->length; + + ret = crypto_cipher_ioctl(CRYPTO_CMD_PKE_MOD, &mod_ctr_ctl); + crypto_chk_goto(ret != TD_SUCCESS, exit, "crypto_ioctl failed, ret is 0x%x\n", ret); + + crypto_uapi_func_exit(); + +exit: + return ret; +} + +td_s32 unify_uapi_cipher_pke_exp_mod(const drv_pke_data *n, const drv_pke_data *k, + const drv_pke_data *in, const drv_pke_data *out) +{ + td_s32 ret = TD_SUCCESS; + pke_exp_mod_ctl_t exp_mod_ctr_ctl; + crypto_uapi_func_enter(); + pke_init_chk(); + + pke_null_ptr_chk(n); + pke_null_ptr_chk(k); + pke_null_ptr_chk(in); + pke_null_ptr_chk(out); + + (td_void)memset_s(&exp_mod_ctr_ctl, sizeof(exp_mod_ctr_ctl), 0, sizeof(exp_mod_ctr_ctl)); + exp_mod_ctr_ctl.n.data.p = n->data; + exp_mod_ctr_ctl.n.length = n->length; + exp_mod_ctr_ctl.k.data.p = k->data; + exp_mod_ctr_ctl.k.length = k->length; + exp_mod_ctr_ctl.in.data.p = in->data; + exp_mod_ctr_ctl.in.length = in->length; + exp_mod_ctr_ctl.out.data.p = out->data; + exp_mod_ctr_ctl.out.length = out->length; + + ret = crypto_cipher_ioctl(CRYPTO_CMD_PKE_EXP_MOD, &exp_mod_ctr_ctl); + crypto_chk_goto(ret != TD_SUCCESS, exit, "crypto_ioctl failed, ret is 0x%x\n", ret); + + crypto_uapi_func_exit(); + +exit: + return ret; +} + +td_s32 unify_uapi_cipher_pke_rsa_sign(const drv_pke_rsa_priv_key *priv_key, drv_pke_rsa_scheme scheme, + drv_pke_hash_type hash_type, const drv_pke_data *input_hash, + drv_pke_data *sign) +{ + td_s32 ret = TD_SUCCESS; + pke_rsa_sign_ctl_t rsa_sign_ctl; + crypto_uapi_func_enter(); + pke_init_chk(); + + pke_null_ptr_chk(priv_key); + pke_null_ptr_chk(input_hash); + pke_null_ptr_chk(sign); + + (td_void)memset_s(&rsa_sign_ctl, sizeof(rsa_sign_ctl), 0, sizeof(rsa_sign_ctl)); + rsa_sign_ctl.scheme = scheme; + rsa_sign_ctl.priv_key.n.p = priv_key->n; + rsa_sign_ctl.priv_key.e.p = priv_key->e; + rsa_sign_ctl.priv_key.d.p = priv_key->d; + rsa_sign_ctl.priv_key.p.p = priv_key->p; + rsa_sign_ctl.priv_key.q.p = priv_key->q; + rsa_sign_ctl.priv_key.dp.p = priv_key->dp; + rsa_sign_ctl.priv_key.dq.p = priv_key->dq; + rsa_sign_ctl.priv_key.qp.p = priv_key->qp; + rsa_sign_ctl.priv_key.n_len = priv_key->n_len; + rsa_sign_ctl.priv_key.e_len = priv_key->e_len; + rsa_sign_ctl.priv_key.d_len = priv_key->d_len; + rsa_sign_ctl.priv_key.p_len = priv_key->p_len; + rsa_sign_ctl.priv_key.q_len = priv_key->q_len; + rsa_sign_ctl.priv_key.dp_len = priv_key->dp_len; + rsa_sign_ctl.priv_key.dq_len = priv_key->dq_len; + rsa_sign_ctl.priv_key.qp_len = priv_key->qp_len; + rsa_sign_ctl.scheme = scheme; + rsa_sign_ctl.hash_type = hash_type; + rsa_sign_ctl.input_hash.data.p = input_hash->data; + rsa_sign_ctl.input_hash.length = input_hash->length; + rsa_sign_ctl.sig.data.p = sign->data; + rsa_sign_ctl.sig.length = sign->length; + + ret = crypto_cipher_ioctl(CRYPTO_CMD_PKE_RSA_SIGN, &rsa_sign_ctl); + crypto_chk_goto(ret != TD_SUCCESS, exit, "crypto_ioctl failed, ret is 0x%x\n", ret); + sign->length = rsa_sign_ctl.sig.length; + crypto_uapi_func_exit(); + +exit: + (td_void)memset_s(&rsa_sign_ctl, sizeof(rsa_sign_ctl), 0, sizeof(rsa_sign_ctl)); + return ret; +} + +td_s32 unify_uapi_cipher_pke_rsa_verify(const drv_pke_rsa_pub_key *pub_key, drv_pke_rsa_scheme scheme, + drv_pke_hash_type hash_type, drv_pke_data *input_hash, const drv_pke_data *sig) +{ + td_s32 ret = TD_SUCCESS; + pke_rsa_verify_ctl_t rsa_verify_ctl; + crypto_uapi_func_enter(); + pke_init_chk(); + + pke_null_ptr_chk(pub_key); + pke_null_ptr_chk(input_hash); + pke_null_ptr_chk(sig); + + (td_void)memset_s(&rsa_verify_ctl, sizeof(rsa_verify_ctl), 0, sizeof(rsa_verify_ctl)); + rsa_verify_ctl.scheme = scheme; + rsa_verify_ctl.hash_type = hash_type; + rsa_verify_ctl.pub_key.e.p = pub_key->e; + rsa_verify_ctl.pub_key.n.p = pub_key->n; + rsa_verify_ctl.pub_key.len = pub_key->len; + rsa_verify_ctl.input_hash.data.p = input_hash->data; + rsa_verify_ctl.input_hash.length = input_hash->length; + rsa_verify_ctl.sig.data.p = sig->data; + rsa_verify_ctl.sig.length = sig->length; + + ret = crypto_cipher_ioctl(CRYPTO_CMD_PKE_RSA_VERIFY, &rsa_verify_ctl); + crypto_chk_goto(ret != TD_SUCCESS, exit, "crypto_ioctl failed, ret is 0x%x\n", ret); + + crypto_uapi_func_exit(); + +exit: + (td_void)memset_s(&rsa_verify_ctl, sizeof(rsa_verify_ctl), 0, sizeof(rsa_verify_ctl)); + return ret; +} + +td_s32 unify_uapi_cipher_pke_rsa_public_encrypt(drv_pke_rsa_scheme scheme, drv_pke_hash_type hash_type, + const drv_pke_rsa_pub_key *pub_key, const drv_pke_data *input, const drv_pke_data *label, + drv_pke_data *output) +{ + td_s32 ret = TD_SUCCESS; + pke_rsa_pub_crypto_ctl_t rsa_pub_crypto_ctl; + crypto_uapi_func_enter(); + pke_init_chk(); + + pke_null_ptr_chk(pub_key); + pke_null_ptr_chk(input); + pke_null_ptr_chk(output); + + (td_void)memset_s(&rsa_pub_crypto_ctl, sizeof(rsa_pub_crypto_ctl), 0, sizeof(rsa_pub_crypto_ctl)); + rsa_pub_crypto_ctl.scheme = scheme; + rsa_pub_crypto_ctl.hash_type = hash_type; + rsa_pub_crypto_ctl.pub_key.e.p = pub_key->e; + rsa_pub_crypto_ctl.pub_key.n.p = pub_key->n; + rsa_pub_crypto_ctl.pub_key.len = pub_key->len; + rsa_pub_crypto_ctl.input.data.p = input->data; + rsa_pub_crypto_ctl.input.length = input->length; + rsa_pub_crypto_ctl.output.data.p = output->data; + rsa_pub_crypto_ctl.output.length = output->length; + if (label != TD_NULL) { + rsa_pub_crypto_ctl.label.data.p = label->data; + rsa_pub_crypto_ctl.label.length = label->length; + } else { + rsa_pub_crypto_ctl.label.data.p = TD_NULL; + } + + ret = crypto_cipher_ioctl(CRYPTO_CMD_PKE_RSA_PUBLIC_ENCRYPT, &rsa_pub_crypto_ctl); + crypto_chk_goto(ret != TD_SUCCESS, exit, "crypto_ioctl failed, ret is 0x%x\n", ret); + output->length = rsa_pub_crypto_ctl.output.length; + crypto_uapi_func_exit(); + +exit: + (td_void)memset_s(&rsa_pub_crypto_ctl, sizeof(rsa_pub_crypto_ctl), 0, sizeof(rsa_pub_crypto_ctl)); + return ret; +} + +td_s32 unify_uapi_cipher_pke_rsa_private_decrypt(drv_pke_rsa_scheme scheme, drv_pke_hash_type hash_type, + const drv_pke_rsa_priv_key *priv_key, const drv_pke_data *input, const drv_pke_data *label, + drv_pke_data *output) +{ + td_s32 ret = TD_SUCCESS; + pke_rsa_priv_crypto_ctl_t rsa_priv_crypto_ctl; + crypto_uapi_func_enter(); + pke_init_chk(); + + pke_null_ptr_chk(priv_key); + pke_null_ptr_chk(input); + pke_null_ptr_chk(output); + + (td_void)memset_s(&rsa_priv_crypto_ctl, sizeof(rsa_priv_crypto_ctl), 0, sizeof(rsa_priv_crypto_ctl)); + rsa_priv_crypto_ctl.scheme = scheme; + rsa_priv_crypto_ctl.hash_type = hash_type; + rsa_priv_crypto_ctl.priv_key.n.p = priv_key->n; + rsa_priv_crypto_ctl.priv_key.e.p = priv_key->e; + rsa_priv_crypto_ctl.priv_key.d.p = priv_key->d; + rsa_priv_crypto_ctl.priv_key.p.p = priv_key->p; + rsa_priv_crypto_ctl.priv_key.q.p = priv_key->q; + rsa_priv_crypto_ctl.priv_key.dp.p = priv_key->dp; + rsa_priv_crypto_ctl.priv_key.dq.p = priv_key->dq; + rsa_priv_crypto_ctl.priv_key.qp.p = priv_key->qp; + rsa_priv_crypto_ctl.priv_key.n_len = priv_key->n_len; + rsa_priv_crypto_ctl.priv_key.e_len = priv_key->e_len; + rsa_priv_crypto_ctl.priv_key.d_len = priv_key->d_len; + rsa_priv_crypto_ctl.priv_key.p_len = priv_key->p_len; + rsa_priv_crypto_ctl.priv_key.q_len = priv_key->q_len; + rsa_priv_crypto_ctl.priv_key.dp_len = priv_key->dp_len; + rsa_priv_crypto_ctl.priv_key.dq_len = priv_key->dq_len; + rsa_priv_crypto_ctl.priv_key.qp_len = priv_key->qp_len; + rsa_priv_crypto_ctl.input.data.p = input->data; + rsa_priv_crypto_ctl.input.length = input->length; + rsa_priv_crypto_ctl.output.data.p = output->data; + rsa_priv_crypto_ctl.output.length = output->length; + if (label != TD_NULL) { + rsa_priv_crypto_ctl.label.data.p = label->data; + rsa_priv_crypto_ctl.label.length = label->length; + } else { + rsa_priv_crypto_ctl.label.data.p = TD_NULL; + } + + ret = crypto_cipher_ioctl(CRYPTO_CMD_PKE_RSA_PRIVATE_DECRYPT, &rsa_priv_crypto_ctl); + crypto_chk_goto(ret != TD_SUCCESS, exit, "crypto_ioctl failed, ret is 0x%x\n", ret); + output->length = rsa_priv_crypto_ctl.output.length; + crypto_uapi_func_exit(); + +exit: + (td_void)memset_s(&rsa_priv_crypto_ctl, sizeof(rsa_priv_crypto_ctl), 0, sizeof(rsa_priv_crypto_ctl)); + return ret; +} \ No newline at end of file diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_symc.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_symc.c new file mode 100644 index 00000000..c681d20f --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_symc.c @@ -0,0 +1,498 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "uapi_symc.h" + +#include + +#include "uapi_common.h" +#include "crypto_ioctl_cmd.h" +#include "crypto_osal_user_lib.h" + +#define SYMC_COMPAT_ERRNO(err_code) UAPI_COMPAT_ERRNO(ERROR_MODULE_SYMC, err_code) + +#define CRYPTO_HASH_MAX_PROCESS_LEN (4 * 1024) + +#define crypto_symc_init_chk() do { \ + if (crypto_cipher_is_init() == 0) { \ + return SYMC_COMPAT_ERRNO(ERROR_NOT_INIT); \ + } \ +} while (0) + +td_s32 unify_uapi_cipher_symc_init(td_void) +{ + td_s32 ret = CRYPTO_SUCCESS; + + crypto_uapi_func_enter(); + + ret = crypto_cipher_open(); + if (ret != TD_SUCCESS) { + return ret; + } + + ret = crypto_cipher_ioctl(CRYPTO_CMD_SYMC_INIT, TD_NULL); + if (ret != CRYPTO_SUCCESS) { + printf("crypto_ioctl failed, ret is 0x%x\n", ret); + crypto_cipher_close(); + return ret; + } + + crypto_uapi_func_exit(); + return ret; +} + +td_s32 unify_uapi_cipher_symc_deinit(td_void) +{ + td_s32 ret = CRYPTO_SUCCESS; + + crypto_uapi_func_enter(); + + if (crypto_cipher_is_init() == 0) { + return CRYPTO_SUCCESS; + } + + ret = crypto_cipher_ioctl(CRYPTO_CMD_SYMC_DEINIT, TD_NULL); + if (ret != CRYPTO_SUCCESS) { + printf("crypto_ioctl failed, ret is 0x%x\n", ret); + } + + crypto_cipher_close(); + + crypto_uapi_func_exit(); + return ret; +} + +td_s32 unify_uapi_cipher_symc_create(td_handle *symc_handle, const crypto_symc_attr *symc_attr) +{ + td_s32 ret = CRYPTO_SUCCESS; + symc_create_t symc_create; + + crypto_uapi_func_enter(); + crypto_symc_init_chk(); + + crypto_chk_return(symc_handle == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "symc_handle is NULL\n"); + crypto_chk_return(symc_attr == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "symc_attr is NULL\n"); + + (td_void)memset_s(&symc_create, sizeof(symc_create), 0, sizeof(symc_create)); + (td_void)memcpy_s(&symc_create.symc_attr, sizeof(crypto_symc_attr), symc_attr, sizeof(crypto_symc_attr)); + + ret = crypto_cipher_ioctl(CRYPTO_CMD_SYMC_CREATE, &symc_create); + if (ret != TD_SUCCESS) { + printf("crypto_ioctl failed, ret is 0x%x\n", ret); + return ret; + } + + *symc_handle = symc_create.symc_handle; + + crypto_uapi_func_exit(); + return ret; +} + +td_s32 unify_uapi_cipher_symc_destroy(td_handle symc_handle) +{ + td_s32 ret = CRYPTO_SUCCESS; + symc_destroy_t symc_destroy; + crypto_uapi_func_enter(); + crypto_symc_init_chk(); + + (td_void)memset_s(&symc_destroy, sizeof(symc_destroy), 0, sizeof(symc_destroy)); + + symc_destroy.symc_handle = symc_handle; + ret = crypto_cipher_ioctl(CRYPTO_CMD_SYMC_DESTROY, &symc_destroy); + if (ret != TD_SUCCESS) { + printf("crypto_ioctl failed, ret is 0x%x\n", ret); + return ret; + } + + crypto_uapi_func_exit(); + return ret; +} + +td_s32 unify_uapi_cipher_symc_set_config(td_handle symc_handle, const crypto_symc_ctrl_t *symc_ctrl) +{ + td_s32 ret = CRYPTO_SUCCESS; + symc_config_t symc_config; + crypto_symc_config_aes_ccm_gcm *ccm_gcm_config = TD_NULL; + crypto_uapi_func_enter(); + crypto_symc_init_chk(); + + crypto_chk_return(symc_ctrl == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "symc_ctrl is NULL\n"); + + (td_void)memset_s(&symc_config, sizeof(symc_config), 0, sizeof(symc_config)); + + symc_config.symc_handle = symc_handle; + symc_config.symc_alg = symc_ctrl->symc_alg; + symc_config.work_mode = symc_ctrl->work_mode; + symc_config.symc_key_length = symc_ctrl->symc_key_length; + symc_config.symc_bit_width = symc_ctrl->symc_bit_width; + symc_config.iv_change_flag = symc_ctrl->iv_change_flag; + ret = memcpy_s(symc_config.iv, sizeof(symc_config.iv), symc_ctrl->iv, symc_ctrl->iv_length); + crypto_chk_return(ret != EOK, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + symc_config.iv_length = symc_ctrl->iv_length; + + if (symc_ctrl->work_mode == CRYPTO_SYMC_WORK_MODE_CCM || symc_ctrl->work_mode == CRYPTO_SYMC_WORK_MODE_GCM) { + crypto_chk_return(symc_ctrl->param == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "param is NULL\n"); + ccm_gcm_config = (crypto_symc_config_aes_ccm_gcm *)symc_ctrl->param; + symc_config.aad_len = ccm_gcm_config->aad_len; + symc_config.data_len = ccm_gcm_config->data_len; + symc_config.tag_len = ccm_gcm_config->tag_len; + symc_config.aad_mem_handle = ccm_gcm_config->aad_buf.uapi_mem_handle; + symc_config.aad_phys_addr = ccm_gcm_config->aad_buf.phys_addr; + symc_config.aad.p = ccm_gcm_config->aad_buf.virt_addr; + } + + ret = crypto_cipher_ioctl(CRYPTO_CMD_SYMC_SET_CONFIG, &symc_config); + if (ret != TD_SUCCESS) { + printf("crypto_ioctl failed, ret is 0x%x\n", ret); + return ret; + } + + crypto_uapi_func_exit(); + return ret; +} + +td_s32 unify_uapi_cipher_symc_get_config(td_handle symc_handle, crypto_symc_ctrl_t *symc_ctrl) +{ + td_s32 ret = CRYPTO_SUCCESS; + symc_config_t symc_config; + crypto_symc_config_aes_ccm_gcm *ccm_gcm_config = TD_NULL; + crypto_uapi_func_enter(); + + crypto_symc_init_chk(); + crypto_chk_return(symc_ctrl == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "symc_ctrl is NULL\n"); + (td_void)memset_s(&symc_config, sizeof(symc_config), 0, sizeof(symc_config)); + ccm_gcm_config = (crypto_symc_config_aes_ccm_gcm *)symc_ctrl->param; + if (ccm_gcm_config != TD_NULL) { + symc_config.aad.p = ccm_gcm_config->aad_buf.virt_addr; + } + symc_config.symc_handle = symc_handle; + + ret = crypto_cipher_ioctl(CRYPTO_CMD_SYMC_GET_CONFIG, &symc_config); + if (ret != TD_SUCCESS) { + printf("%s\n", __func__); + printf("crypto_ioctl failed, ret is 0x%x\n", ret); + return ret; + } + + symc_ctrl->symc_alg = symc_config.symc_alg; + symc_ctrl->work_mode = symc_config.work_mode; + symc_ctrl->symc_key_length = symc_config.symc_key_length; + symc_ctrl->symc_bit_width = symc_config.symc_bit_width; + symc_ctrl->iv_change_flag = symc_config.iv_change_flag; + + symc_ctrl->iv_length = symc_config.iv_length; + ret = memcpy_s(symc_ctrl->iv, sizeof(symc_ctrl->iv), symc_config.iv, sizeof(symc_config.iv)); + crypto_chk_return(ret != EOK, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + if (symc_ctrl->work_mode == CRYPTO_SYMC_WORK_MODE_CCM || symc_ctrl->work_mode == CRYPTO_SYMC_WORK_MODE_GCM) { + crypto_chk_return(ccm_gcm_config == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "param is NULL\n"); + ccm_gcm_config->aad_len = symc_config.aad_len; + ccm_gcm_config->data_len = symc_config.data_len; + ccm_gcm_config->tag_len = symc_config.tag_len; + ccm_gcm_config->aad_buf.uapi_mem_handle = symc_config.aad_mem_handle; + ccm_gcm_config->aad_buf.phys_addr = symc_config.aad_phys_addr; + } + + crypto_uapi_func_exit(); + return ret; +} + +td_s32 unify_uapi_cipher_symc_attach(td_handle symc_handle, td_handle keyslot_handle) +{ + td_s32 ret = CRYPTO_SUCCESS; + symc_attach_t symc_attach; + crypto_uapi_func_enter(); + crypto_symc_init_chk(); + + (td_void)memset_s(&symc_attach, sizeof(symc_attach), 0, sizeof(symc_attach)); + symc_attach.symc_handle = symc_handle; + symc_attach.keyslot_handle = keyslot_handle; + + ret = crypto_cipher_ioctl(CRYPTO_CMD_SYMC_ATTACH, &symc_attach); + if (ret != TD_SUCCESS) { + printf("crypto_ioctl failed, ret is 0x%x\n", ret); + return ret; + } + + crypto_uapi_func_exit(); + return ret; +} + +td_s32 unify_uapi_cipher_symc_encrypt(td_handle symc_handle, const crypto_buf_attr *src_buf, + const crypto_buf_attr *dst_buf, td_u32 length) +{ + td_s32 ret = CRYPTO_SUCCESS; + symc_crypto_t symc_crypto; + crypto_uapi_func_enter(); + crypto_symc_init_chk(); + + crypto_chk_return(src_buf == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "src_buf is NULL\n"); + crypto_chk_return(dst_buf == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "dst_buf is NULL\n"); + + (td_void)memset_s(&symc_crypto, sizeof(symc_crypto), 0, sizeof(symc_crypto)); + symc_crypto.symc_handle = symc_handle; + symc_crypto.src_mem_handle = src_buf->uapi_mem_handle; + symc_crypto.src_phys_addr = src_buf->phys_addr; + symc_crypto.src_buf_sec = src_buf->buf_sec; + symc_crypto.src_addr_offset = src_buf->addr_offset; + symc_crypto.dst_mem_handle = dst_buf->uapi_mem_handle; + symc_crypto.dst_phys_addr = dst_buf->phys_addr; + symc_crypto.dst_buf_sec = dst_buf->buf_sec; + symc_crypto.dst_addr_offset = dst_buf->addr_offset; + symc_crypto.length = length; + ret = crypto_cipher_ioctl(CRYPTO_CMD_SYMC_ENCRYPT, &symc_crypto); + if (ret != TD_SUCCESS) { + printf("crypto_ioctl failed, ret is 0x%x\n", ret); + return ret; + } + + crypto_uapi_func_exit(); + return ret; +} + +td_s32 unify_uapi_cipher_symc_decrypt(td_handle symc_handle, const crypto_buf_attr *src_buf, + const crypto_buf_attr *dst_buf, td_u32 length) +{ + td_s32 ret = CRYPTO_SUCCESS; + symc_crypto_t symc_crypto; + crypto_uapi_func_enter(); + crypto_symc_init_chk(); + + crypto_chk_return(src_buf == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "src_buf is NULL\n"); + crypto_chk_return(dst_buf == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "dst_buf is NULL\n"); + + (td_void)memset_s(&symc_crypto, sizeof(symc_crypto), 0, sizeof(symc_crypto)); + symc_crypto.symc_handle = symc_handle; + symc_crypto.src_mem_handle = src_buf->uapi_mem_handle; + symc_crypto.src_phys_addr = src_buf->phys_addr; + symc_crypto.src_buf_sec = src_buf->buf_sec; + symc_crypto.src_addr_offset = src_buf->addr_offset; + symc_crypto.dst_mem_handle = dst_buf->uapi_mem_handle; + symc_crypto.dst_phys_addr = dst_buf->phys_addr; + symc_crypto.dst_buf_sec = dst_buf->buf_sec; + symc_crypto.dst_addr_offset = dst_buf->addr_offset; + symc_crypto.length = length; + ret = crypto_cipher_ioctl(CRYPTO_CMD_SYMC_DECRYPT, &symc_crypto); + if (ret != TD_SUCCESS) { + printf("crypto_ioctl failed, ret is 0x%x\n", ret); + return ret; + } + + crypto_uapi_func_exit(); + return ret; +} + +td_s32 unify_uapi_cipher_symc_get_tag(td_handle symc_handle, td_u8 *tag, td_u32 tag_length) +{ + td_s32 ret = CRYPTO_SUCCESS; + symc_get_tag_t symc_get_tag; + crypto_uapi_func_enter(); + crypto_symc_init_chk(); + + crypto_chk_return(tag == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "tag is NULL\n"); + + (td_void)memset_s(&symc_get_tag, sizeof(symc_get_tag), 0, sizeof(symc_get_tag)); + symc_get_tag.symc_handle = symc_handle; + symc_get_tag.tag_length = tag_length; + + ret = crypto_cipher_ioctl(CRYPTO_CMD_SYMC_GET_TAG, &symc_get_tag); + if (ret != TD_SUCCESS) { + printf("crypto_ioctl failed, ret is 0x%x\n", ret); + return ret; + } + + ret = memcpy_s(tag, tag_length, symc_get_tag.tag, symc_get_tag.tag_length); + crypto_chk_return(ret != EOK, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + crypto_uapi_func_exit(); + return ret; +} + +td_s32 unify_uapi_cipher_mac_start(td_handle *symc_handle, const crypto_symc_mac_attr *mac_attr) +{ + td_s32 ret = CRYPTO_SUCCESS; + symc_mac_start_t mac_start; + crypto_uapi_func_enter(); + crypto_symc_init_chk(); + + crypto_chk_return(symc_handle == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "symc_handle is NULL\n"); + crypto_chk_return(mac_attr == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "mac_attr is NULL\n"); + + (td_void)memset_s(&mac_start, sizeof(mac_start), 0, sizeof(mac_start)); + (td_void)memcpy_s(&mac_start.mac_attr, sizeof(crypto_symc_mac_attr), mac_attr, sizeof(crypto_symc_mac_attr)); + ret = crypto_cipher_ioctl(CRYPTO_CMD_SYMC_MAC_START, &mac_start); + if (ret != TD_SUCCESS) { + printf("crypto_ioctl failed, ret is 0x%x\n", ret); + return ret; + } + + *symc_handle = mac_start.symc_handle; + crypto_uapi_func_exit(); + return ret; +} + +td_s32 unify_uapi_cipher_mac_update(td_handle symc_handle, const crypto_buf_attr *src_buf, td_u32 length) +{ + td_s32 ret = CRYPTO_SUCCESS; + symc_mac_update_t mac_update; + crypto_uapi_func_enter(); + crypto_symc_init_chk(); + + crypto_chk_return(src_buf == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "src_buf is NULL\n"); + + (td_void)memset_s(&mac_update, sizeof(mac_update), 0, sizeof(mac_update)); + mac_update.symc_handle = symc_handle; + mac_update.src_buf.p = src_buf->virt_addr; + mac_update.length = length; + ret = crypto_cipher_ioctl(CRYPTO_CMD_SYMC_MAC_UPDATE, &mac_update); + if (ret != TD_SUCCESS) { + printf("crypto_ioctl failed, ret is 0x%x\n", ret); + return ret; + } + + crypto_uapi_func_exit(); + return ret; +} + +td_s32 unify_uapi_cipher_mac_finish(td_handle symc_handle, td_u8 *mac, td_u32 *mac_length) +{ + td_s32 ret = CRYPTO_SUCCESS; + symc_mac_finish_t mac_finish; + crypto_uapi_func_enter(); + crypto_symc_init_chk(); + + crypto_chk_return(mac == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "mac is NULL\n"); + crypto_chk_return(mac_length == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "mac_length is NULL\n"); + + (td_void)memset_s(&mac_finish, sizeof(mac_finish), 0, sizeof(mac_finish)); + mac_finish.symc_handle = symc_handle; + ret = crypto_cipher_ioctl(CRYPTO_CMD_SYMC_MAC_FINISH, &mac_finish); + if (ret != TD_SUCCESS) { + printf("crypto_ioctl failed, ret is 0x%x\n", ret); + return ret; + } + crypto_chk_return(*mac_length < mac_finish.mac_length, SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM), + "mac_length is not enough\n"); + ret = memcpy_s(mac, *mac_length, mac_finish.mac, mac_finish.mac_length); + crypto_chk_return(ret != EOK, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + *mac_length = mac_finish.mac_length; + crypto_uapi_func_exit(); + return ret; +} + +static td_s32 priv_uapi_symc_config_ctrl(const crypto_symc_ctrl_t *symc_ctrl, crypto_symc_multi_t *symc_multi) +{ + td_s32 ret; + + symc_multi->symc_alg = symc_ctrl->symc_alg; + symc_multi->work_mode = symc_ctrl->work_mode; + symc_multi->symc_key_length = symc_ctrl->symc_key_length; + symc_multi->key_parity = symc_ctrl->key_parity; + symc_multi->symc_bit_width = symc_ctrl->symc_bit_width; + symc_multi->iv_change_flag = symc_ctrl->iv_change_flag; + symc_multi->iv_length = symc_ctrl->iv_length; + ret = memcpy_s(symc_multi->iv, sizeof(symc_multi->iv), symc_ctrl->iv, symc_ctrl->iv_length); + crypto_chk_return(ret != EOK, SYMC_COMPAT_ERRNO(ERROR_MEMCPY_S), "memcpy_s failed\n"); + + return ret; +} + +typedef struct { + td_handle symc_handle; + td_u32 pack_num; + td_u32 crypto_type; +} priv_multi_param; + +static td_s32 priv_uapi_symc_crypto_multi(const priv_multi_param *multi_param, const crypto_symc_ctrl_t *symc_ctrl, + const crypto_symc_pack *src_buf_pack, const crypto_symc_pack *dst_buf_pack) +{ + td_u32 i; + td_s32 ret = CRYPTO_SUCCESS; + crypto_symc_multi_t symc_multi; + crypto_mem_pack *buffer = TD_NULL; + crypto_mem_pack *src_mem_handle = TD_NULL; + crypto_mem_pack *dst_mem_handle = TD_NULL; + td_u32 pack_size = sizeof(crypto_mem_pack) * multi_param->pack_num; + crypto_symc_init_chk(); + + crypto_chk_return(symc_ctrl == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "symc_ctrl is NULL\n"); + crypto_chk_return(src_buf_pack == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "src_buf_pack is NULL\n"); + crypto_chk_return(dst_buf_pack == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_PARAM_IS_NULL), "dst_buf_pack is NULL\n"); + crypto_chk_return(multi_param->pack_num > CRYPTO_SYMC_MULTI_PACK_MAX_SIZE, + SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM), "pack_num is too large\n"); + + (td_void)memset_s(&symc_multi, sizeof(crypto_symc_multi_t), 0, sizeof(crypto_symc_multi_t)); + symc_multi.symc_handle = multi_param->symc_handle; + + ret = priv_uapi_symc_config_ctrl(symc_ctrl, &symc_multi); + crypto_chk_return(ret != TD_SUCCESS, ret, "priv_uapi_symc_config_ctrl failed\n"); + + buffer = crypto_malloc(pack_size * 2); /* 2: for Both src and dst. */ + crypto_chk_return(buffer == TD_NULL, SYMC_COMPAT_ERRNO(ERROR_MALLOC), "crypto_malloc failed\n"); + + src_mem_handle = buffer; + dst_mem_handle = buffer + multi_param->pack_num; + for (i = 0; i < multi_param->pack_num; i++) { + src_mem_handle[i].uapi_mem_handle = src_buf_pack[i].buf_attr.uapi_mem_handle; + src_mem_handle[i].length = src_buf_pack[i].length; + src_mem_handle[i].phys_addr = src_buf_pack[i].buf_attr.phys_addr; + src_mem_handle[i].buf_sec = src_buf_pack[i].buf_attr.buf_sec; + dst_mem_handle[i].uapi_mem_handle = dst_buf_pack[i].buf_attr.uapi_mem_handle; + dst_mem_handle[i].length = dst_buf_pack[i].length; + dst_mem_handle[i].phys_addr = dst_buf_pack[i].buf_attr.phys_addr; + dst_mem_handle[i].buf_sec = dst_buf_pack[i].buf_attr.buf_sec; + } + symc_multi.src_pack_addr.p = (td_void *)src_mem_handle; + symc_multi.dst_pack_addr.p = (td_void *)dst_mem_handle; + symc_multi.pack_num = multi_param->pack_num; + switch (multi_param->crypto_type) { + case CRYPTO_TYPE_ENCRYPT: + ret = crypto_cipher_ioctl(CRYPTO_CMD_SYMC_ENCRYPT_MULTI, &symc_multi); + break; + case CRYPTO_TYPE_DECRYPT: + ret = crypto_cipher_ioctl(CRYPTO_CMD_SYMC_DECRYPT_MULTI, &symc_multi); + break; + default: + printf("Invalid Crypto Type!\n"); + ret = SYMC_COMPAT_ERRNO(ERROR_INVALID_PARAM); + } + + (td_void)memset_s(buffer, pack_size * 2, 0, pack_size * 2); /* 2: for Both src and dst. */ + crypto_free(buffer); + return ret; +} + +td_s32 unify_uapi_cipher_symc_encrypt_multi(td_handle symc_handle, const crypto_symc_ctrl_t *symc_ctrl, + const crypto_symc_pack *src_buf_pack, const crypto_symc_pack *dst_buf_pack, td_u32 pack_num) +{ + td_s32 ret = CRYPTO_SUCCESS; + priv_multi_param multi_param = { + .symc_handle = symc_handle, + .pack_num = pack_num, + .crypto_type = CRYPTO_TYPE_ENCRYPT, + }; + crypto_uapi_func_enter(); + + ret = priv_uapi_symc_crypto_multi(&multi_param, symc_ctrl, src_buf_pack, dst_buf_pack); + crypto_chk_return(ret != TD_SUCCESS, ret, "priv_uapi_symc_crypto_multi for Encrypt failed\n"); + crypto_uapi_func_exit(); + return ret; +} + +td_s32 unify_uapi_cipher_symc_decrypt_multi(td_handle symc_handle, const crypto_symc_ctrl_t *symc_ctrl, + const crypto_symc_pack *src_buf_pack, const crypto_symc_pack *dst_buf_pack, td_u32 pack_num) +{ + td_s32 ret = CRYPTO_SUCCESS; + priv_multi_param multi_param = { + .symc_handle = symc_handle, + .pack_num = pack_num, + .crypto_type = CRYPTO_TYPE_DECRYPT, + }; + crypto_uapi_func_enter(); + + ret = priv_uapi_symc_crypto_multi(&multi_param, symc_ctrl, src_buf_pack, dst_buf_pack); + crypto_chk_return(ret != TD_SUCCESS, ret, "priv_uapi_symc_crypto_multi for Decrypt failed\n"); + crypto_uapi_func_exit(); + return ret; +} diff --git a/kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_trng.c b/kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_trng.c new file mode 100644 index 00000000..2df9e745 --- /dev/null +++ b/kernel/security_subsys/hi3519dv500/security_subsys_common/uapi_code/uapi_trng.c @@ -0,0 +1,68 @@ +/* + Copyright (c), 2001-2024, Shenshu Tech. Co., Ltd. + */ + +#include "uapi_trng.h" +#include + +#include "uapi_common.h" +#include "crypto_ioctl_cmd.h" +#include "crypto_osal_user_lib.h" + +#define TRNG_COMPAT_ERRNO(err_code) UAPI_COMPAT_ERRNO(ERROR_MODULE_TRNG, err_code) + +td_s32 unify_uapi_cipher_trng_get_random(td_u32 *randnum) +{ + td_s32 ret = TD_SUCCESS; + trng_ctl_t trng_ctl; + crypto_uapi_func_enter(); + + if (randnum == TD_NULL) { + return TRNG_COMPAT_ERRNO(ERROR_PARAM_IS_NULL); + } + ret = crypto_cipher_open(); + if (ret != TD_SUCCESS) { + return ret; + } + + (td_void)memset_s(&trng_ctl, sizeof(trng_ctl), 0, sizeof(trng_ctl)); + ret = crypto_cipher_ioctl(CRYPTO_CMD_TRNG_GET_RANDOM, &trng_ctl); + if (ret != TD_SUCCESS) { + printf("crypto_cipher_ioctl failed, ret is 0x%x\n", ret); + goto exit_close; + } + *randnum = trng_ctl.randnum; + +exit_close: + crypto_cipher_close(); + crypto_uapi_func_exit(); + return ret; +} + +td_s32 unify_uapi_cipher_trng_get_multi_random(td_u32 size, td_u8 *randnum) +{ + td_s32 ret = TD_SUCCESS; + trng_multi_ctl_t trng_multi_ctl; + crypto_uapi_func_enter(); + + if (randnum == TD_NULL) { + return TRNG_COMPAT_ERRNO(ERROR_PARAM_IS_NULL); + } + ret = crypto_cipher_open(); + if (ret != TD_SUCCESS) { + return ret; + } + (td_void)memset_s(&trng_multi_ctl, sizeof(trng_multi_ctl), 0, sizeof(trng_multi_ctl)); + trng_multi_ctl.randnum.p = randnum; + trng_multi_ctl.size = size; + ret = crypto_cipher_ioctl(CRYPTO_CMD_TRNG_GET_MULTI_RANDOM, &trng_multi_ctl); + if (ret != TD_SUCCESS) { + printf("crypto_ioctl failed, ret is 0x%x\n", ret); + goto exit_close; + } + +exit_close: + crypto_cipher_close(); + crypto_uapi_func_exit(); + return ret; +} \ No newline at end of file