From 607778300cbb8f8df13830368081984308a4a1da Mon Sep 17 00:00:00 2001 From: "wangliang.wang" Date: Fri, 10 Mar 2023 00:31:09 +0800 Subject: [PATCH] [uboot] Upgrade the MMF SDK from V4.0.0 to V4.1.0 1. add cv181x functions 2. Delete some useless files and add .gitignore Change-Id: Iea2b2fa43b5a1152e5e99fb32b88f8d2c249251a --- u-boot-2021.10/.gitignore | 1 + u-boot-2021.10/Makefile | 4 +- u-boot-2021.10/arch/arm/dts/.gitignore | 1 + u-boot-2021.10/arch/arm/lib/bootm.c | 3 + u-boot-2021.10/arch/riscv/cpu/generic/cache.c | 2 +- u-boot-2021.10/arch/riscv/dts/.gitignore | 1 + .../riscv/dts/cv1800b_wdmb_0008a_spinor.dts | 14 - .../riscv/dts/cv1800b_wevb_0008a_spinor.dts | 14 - .../riscv/dts/cv1800c_wevb_0009a_spinor.dts | 14 - .../riscv/dts/cv1801b_wevb_0008a_spinor.dts | 14 - .../riscv/dts/cv1801c_wdmb_0009a_spinor.dts | 17 - .../riscv/dts/cv1801c_wevb_0009a_spinand.dts | 13 - .../riscv/dts/cv1801c_wevb_0009a_spinor.dts | 14 - .../arch/riscv/dts/cv180x_asic_bga.dtsi | 12 - .../arch/riscv/dts/cv180x_asic_qfn.dtsi | 114 - .../arch/riscv/dts/cv180x_asic_spinand.dtsi | 5 - .../arch/riscv/dts/cv180x_asic_spinor.dtsi | 5 - .../arch/riscv/dts/cv180x_base.dtsi | 881 ------- .../arch/riscv/dts/cv180x_base_riscv.dtsi | 374 --- .../arch/riscv/dts/cv180x_default_memmap.dtsi | 26 - u-boot-2021.10/arch/riscv/dts/cv180x_fpga.dts | 16 - .../arch/riscv/dts/cv180x_palladium.dts | 22 - .../riscv/dts/cv180zb_wdmb_0008a_spinor.dts | 14 - .../riscv/dts/cv180zb_wevb_0008a_spinor.dts | 14 - u-boot-2021.10/board/cvitek/Kconfig | 1 - u-boot-2021.10/board/cvitek/cv180x/board.c | 37 +- .../board/cvitek/cv180x/cv180x_reg.h | 2 +- u-boot-2021.10/board/cvitek/cv181x/board.c | 68 +- .../board/cvitek/cv181x/cv181x_reg.h | 2 +- u-boot-2021.10/cmd/Kconfig | 29 + u-boot-2021.10/cmd/Makefile | 2 + u-boot-2021.10/cmd/cvi_jpeg.c | 50 + u-boot-2021.10/cmd/cvi_update.c | 29 +- u-boot-2021.10/cmd/cvi_vo.c | 408 ++++ u-boot-2021.10/cmd/efuse.c | 93 +- u-boot-2021.10/common/autoboot.c | 3 + u-boot-2021.10/common/board_f.c | 12 + u-boot-2021.10/common/image.c | 4 + u-boot-2021.10/drivers/Makefile | 2 +- .../utask/cv181x/include/platform_def.h | 2 + .../drivers/cvi_usb/utask/cv181x/usb_tty.c | 30 +- u-boot-2021.10/drivers/jpeg/Makefile | 1 + u-boot-2021.10/drivers/jpeg/config.h | 48 + u-boot-2021.10/drivers/jpeg/cvi_jpeg_cfg.h | 54 + u-boot-2021.10/drivers/jpeg/jdi.c | 537 +++++ u-boot-2021.10/drivers/jpeg/jdi.h | 118 + u-boot-2021.10/drivers/jpeg/jdi_osal.c | 717 ++++++ u-boot-2021.10/drivers/jpeg/jdi_osal.h | 97 + u-boot-2021.10/drivers/jpeg/jpeg.c | 155 ++ u-boot-2021.10/drivers/jpeg/jpeg.h | 6 + u-boot-2021.10/drivers/jpeg/jpuapi.c | 1834 ++++++++++++++ u-boot-2021.10/drivers/jpeg/jpuapi.h | 270 +++ u-boot-2021.10/drivers/jpeg/jpuapifunc.c | 2112 +++++++++++++++++ u-boot-2021.10/drivers/jpeg/jpuapifunc.h | 280 +++ u-boot-2021.10/drivers/jpeg/jpuconfig.h | 36 + u-boot-2021.10/drivers/jpeg/jpuhelper.c | 2015 ++++++++++++++++ u-boot-2021.10/drivers/jpeg/jpuhelper.h | 165 ++ u-boot-2021.10/drivers/jpeg/jpulog.h | 79 + u-boot-2021.10/drivers/jpeg/jpurun.c | 704 ++++++ u-boot-2021.10/drivers/jpeg/jpurun.h | 114 + u-boot-2021.10/drivers/jpeg/jputable.h | 125 + u-boot-2021.10/drivers/jpeg/jputypes.h | 62 + u-boot-2021.10/drivers/jpeg/mixer.c | 373 +++ u-boot-2021.10/drivers/jpeg/mixer.h | 47 + u-boot-2021.10/drivers/jpeg/mm.c | 582 +++++ u-boot-2021.10/drivers/jpeg/mm.h | 71 + u-boot-2021.10/drivers/jpeg/regdefine.h | 162 ++ u-boot-2021.10/drivers/mtd/spi/spi-nor-core.c | 1 + u-boot-2021.10/drivers/mtd/spi/spi-nor-ids.c | 4 + u-boot-2021.10/drivers/net/phy/Kconfig | 6 +- u-boot-2021.10/drivers/net/phy/Makefile | 2 +- .../drivers/net/phy/{cv182xa.c => cvitek.c} | 33 +- u-boot-2021.10/drivers/net/phy/phy.c | 4 +- u-boot-2021.10/drivers/video/Kconfig | 2 + u-boot-2021.10/drivers/video/Makefile | 2 +- u-boot-2021.10/drivers/video/cvitek/Kconfig | 5 + .../drivers/video/cvitek/cvi_disp.c | 32 +- u-boot-2021.10/drivers/video/cvitek/cvi_i80.c | 2 +- .../drivers/video/cvitek/cvi_lvds.c | 211 +- .../drivers/video/cvitek/cvi_mipi.c | 41 +- u-boot-2021.10/drivers/video/cvitek/dsi_phy.c | 17 +- u-boot-2021.10/drivers/video/cvitek/dsi_phy.h | 3 +- u-boot-2021.10/drivers/video/cvitek/scaler.c | 29 +- .../drivers/video/cvitek/scaler_reg.h | 1 + u-boot-2021.10/drivers/video/cvitek/vip_sys.c | 2 +- .../drivers/watchdog/designware_wdt.c | 2 + u-boot-2021.10/include/configs/cv180x-asic.h | 1 - u-boot-2021.10/include/configs/cv180x-fpga.h | 1 - u-boot-2021.10/include/configs/cv181x-asic.h | 12 +- u-boot-2021.10/include/configs/cv181x-fpga.h | 20 +- u-boot-2021.10/include/cvi_efuse.h | 2 +- u-boot-2021.10/include/cvitek/cvi_efuse.h | 2 +- u-boot-2021.10/include/cvitek/cvi_lvds.h | 52 + .../cvitek/cvi_panels/cvi_panel_diffs.h | 9 +- .../include/cvitek/cvi_panels/cvi_panels.h | 7 + .../cvitek/cvi_panels/dsi_hx8394_evb.h | 3 +- .../include/cvitek/cvi_panels/lvds_ek79202.h | 30 + u-boot-2021.10/include/env_default.h | 3 + u-boot-2021.10/include/linux/mtd/spi-nor.h | 1 + u-boot-2021.10/include/phy.h | 2 +- u-boot-2021.10/include/sdhci.h | 2 + u-boot-2021.10/scripts/config_whitelist.txt | 1 + 102 files changed, 11818 insertions(+), 1862 deletions(-) create mode 100644 u-boot-2021.10/arch/arm/dts/.gitignore create mode 100644 u-boot-2021.10/arch/riscv/dts/.gitignore delete mode 100644 u-boot-2021.10/arch/riscv/dts/cv1800b_wdmb_0008a_spinor.dts delete mode 100644 u-boot-2021.10/arch/riscv/dts/cv1800b_wevb_0008a_spinor.dts delete mode 100644 u-boot-2021.10/arch/riscv/dts/cv1800c_wevb_0009a_spinor.dts delete mode 100644 u-boot-2021.10/arch/riscv/dts/cv1801b_wevb_0008a_spinor.dts delete mode 100644 u-boot-2021.10/arch/riscv/dts/cv1801c_wdmb_0009a_spinor.dts delete mode 100644 u-boot-2021.10/arch/riscv/dts/cv1801c_wevb_0009a_spinand.dts delete mode 100644 u-boot-2021.10/arch/riscv/dts/cv1801c_wevb_0009a_spinor.dts delete mode 100644 u-boot-2021.10/arch/riscv/dts/cv180x_asic_bga.dtsi delete mode 100644 u-boot-2021.10/arch/riscv/dts/cv180x_asic_qfn.dtsi delete mode 100644 u-boot-2021.10/arch/riscv/dts/cv180x_asic_spinand.dtsi delete mode 100644 u-boot-2021.10/arch/riscv/dts/cv180x_asic_spinor.dtsi delete mode 100644 u-boot-2021.10/arch/riscv/dts/cv180x_base.dtsi delete mode 100644 u-boot-2021.10/arch/riscv/dts/cv180x_base_riscv.dtsi delete mode 100644 u-boot-2021.10/arch/riscv/dts/cv180x_default_memmap.dtsi delete mode 100644 u-boot-2021.10/arch/riscv/dts/cv180x_fpga.dts delete mode 100644 u-boot-2021.10/arch/riscv/dts/cv180x_palladium.dts delete mode 100644 u-boot-2021.10/arch/riscv/dts/cv180zb_wdmb_0008a_spinor.dts delete mode 100644 u-boot-2021.10/arch/riscv/dts/cv180zb_wevb_0008a_spinor.dts create mode 100644 u-boot-2021.10/cmd/cvi_jpeg.c create mode 100644 u-boot-2021.10/cmd/cvi_vo.c create mode 100644 u-boot-2021.10/drivers/jpeg/Makefile create mode 100644 u-boot-2021.10/drivers/jpeg/config.h create mode 100644 u-boot-2021.10/drivers/jpeg/cvi_jpeg_cfg.h create mode 100644 u-boot-2021.10/drivers/jpeg/jdi.c create mode 100644 u-boot-2021.10/drivers/jpeg/jdi.h create mode 100644 u-boot-2021.10/drivers/jpeg/jdi_osal.c create mode 100644 u-boot-2021.10/drivers/jpeg/jdi_osal.h create mode 100644 u-boot-2021.10/drivers/jpeg/jpeg.c create mode 100644 u-boot-2021.10/drivers/jpeg/jpeg.h create mode 100644 u-boot-2021.10/drivers/jpeg/jpuapi.c create mode 100644 u-boot-2021.10/drivers/jpeg/jpuapi.h create mode 100644 u-boot-2021.10/drivers/jpeg/jpuapifunc.c create mode 100644 u-boot-2021.10/drivers/jpeg/jpuapifunc.h create mode 100644 u-boot-2021.10/drivers/jpeg/jpuconfig.h create mode 100644 u-boot-2021.10/drivers/jpeg/jpuhelper.c create mode 100644 u-boot-2021.10/drivers/jpeg/jpuhelper.h create mode 100644 u-boot-2021.10/drivers/jpeg/jpulog.h create mode 100644 u-boot-2021.10/drivers/jpeg/jpurun.c create mode 100644 u-boot-2021.10/drivers/jpeg/jpurun.h create mode 100644 u-boot-2021.10/drivers/jpeg/jputable.h create mode 100644 u-boot-2021.10/drivers/jpeg/jputypes.h create mode 100644 u-boot-2021.10/drivers/jpeg/mixer.c create mode 100644 u-boot-2021.10/drivers/jpeg/mixer.h create mode 100644 u-boot-2021.10/drivers/jpeg/mm.c create mode 100644 u-boot-2021.10/drivers/jpeg/mm.h create mode 100644 u-boot-2021.10/drivers/jpeg/regdefine.h rename u-boot-2021.10/drivers/net/phy/{cv182xa.c => cvitek.c} (92%) create mode 100644 u-boot-2021.10/include/cvitek/cvi_lvds.h create mode 100644 u-boot-2021.10/include/cvitek/cvi_panels/lvds_ek79202.h diff --git a/u-boot-2021.10/.gitignore b/u-boot-2021.10/.gitignore index a0b890738..e58649e38 100644 --- a/u-boot-2021.10/.gitignore +++ b/u-boot-2021.10/.gitignore @@ -103,3 +103,4 @@ __pycache__ /include/cvi_board_memmap.h tags build +board/cvitek/cvi_board_init.c diff --git a/u-boot-2021.10/Makefile b/u-boot-2021.10/Makefile index 96ce713bc..54e2064ac 100644 --- a/u-boot-2021.10/Makefile +++ b/u-boot-2021.10/Makefile @@ -327,14 +327,14 @@ os_x_before = $(shell if [ $(DARWIN_MAJOR_VERSION) -le $(1) -a \ $(DARWIN_MINOR_VERSION) -le $(2) ] ; then echo "$(3)"; else echo "$(4)"; fi ;) os_x_after = $(shell if [ $(DARWIN_MAJOR_VERSION) -ge $(1) -a \ - $(DARWIN_MINOR_VERSION) -ge $(2) ] ; then echo "$(3)"; else echo "$(4)"; fi ;) + $(DARWIN_MINOR_VERSION) -ge $(2) ] ; then echo "$(3)"; else echo "$(4)"; fi ;) # Snow Leopards build environment has no longer restrictions as described above HOSTCC = $(call os_x_before, 10, 5, "cc", "gcc") KBUILD_HOSTCFLAGS += $(call os_x_before, 10, 4, "-traditional-cpp") KBUILD_HOSTLDFLAGS += $(call os_x_before, 10, 5, "-multiply_defined suppress") -# macOS Mojave (10.14.X) +# macOS Mojave (10.14.X) # Undefined symbols for architecture x86_64: "_PyArg_ParseTuple" KBUILD_HOSTLDFLAGS += $(call os_x_after, 10, 14, "-lpython -dynamclib", "") endif diff --git a/u-boot-2021.10/arch/arm/dts/.gitignore b/u-boot-2021.10/arch/arm/dts/.gitignore new file mode 100644 index 000000000..6d6371a55 --- /dev/null +++ b/u-boot-2021.10/arch/arm/dts/.gitignore @@ -0,0 +1 @@ +cv18* diff --git a/u-boot-2021.10/arch/arm/lib/bootm.c b/u-boot-2021.10/arch/arm/lib/bootm.c index 9143404cd..355cf1bba 100644 --- a/u-boot-2021.10/arch/arm/lib/bootm.c +++ b/u-boot-2021.10/arch/arm/lib/bootm.c @@ -126,8 +126,11 @@ static void announce_and_cleanup(int fake) cleanup_before_linux(); +#if (!defined CONFIG_TARGET_CVITEK_CV181X_FPGA) && (!defined CONFIG_TARGET_CVITEK_ATHENA2_FPGA) && \ + (!defined ATHENA2_FPGA_PALLDIUM_ENV) // Save kernel start time board_save_time_record(TIME_RECORDS_FIELD_KERNEL_START); +#endif } static void setup_start_tag (struct bd_info *bd) diff --git a/u-boot-2021.10/arch/riscv/cpu/generic/cache.c b/u-boot-2021.10/arch/riscv/cpu/generic/cache.c index 8ebe8e2c2..b4cb965ba 100644 --- a/u-boot-2021.10/arch/riscv/cpu/generic/cache.c +++ b/u-boot-2021.10/arch/riscv/cpu/generic/cache.c @@ -48,7 +48,7 @@ void flush_dcache_range(unsigned long start, unsigned long end) * Will enter trap mode. * Comment the implement to avoid problem first */ -#if CV181X_UBOOT_USE_DCACHE_API +#if CV181X_UBOOT_USE_DCACHE_API || ATHENA2_UBOOT_USE_DCACHE_API void dcache_enable(void) { asm volatile( diff --git a/u-boot-2021.10/arch/riscv/dts/.gitignore b/u-boot-2021.10/arch/riscv/dts/.gitignore new file mode 100644 index 000000000..6d6371a55 --- /dev/null +++ b/u-boot-2021.10/arch/riscv/dts/.gitignore @@ -0,0 +1 @@ +cv18* diff --git a/u-boot-2021.10/arch/riscv/dts/cv1800b_wdmb_0008a_spinor.dts b/u-boot-2021.10/arch/riscv/dts/cv1800b_wdmb_0008a_spinor.dts deleted file mode 100644 index 5314a49d9..000000000 --- a/u-boot-2021.10/arch/riscv/dts/cv1800b_wdmb_0008a_spinor.dts +++ /dev/null @@ -1,14 +0,0 @@ -/dts-v1/; -#include "cv180x_base_riscv.dtsi" -#include "cv180x_asic_qfn.dtsi" -#include "cv180x_asic_spinor.dtsi" -#include "cv180x_default_memmap.dtsi" - -&mipi_rx{ - snsr-reset = <&portc 8 GPIO_ACTIVE_LOW>, <&portc 8 GPIO_ACTIVE_LOW>, <&portc 8 GPIO_ACTIVE_LOW>; -}; - -/ { - -}; - diff --git a/u-boot-2021.10/arch/riscv/dts/cv1800b_wevb_0008a_spinor.dts b/u-boot-2021.10/arch/riscv/dts/cv1800b_wevb_0008a_spinor.dts deleted file mode 100644 index a11b17e07..000000000 --- a/u-boot-2021.10/arch/riscv/dts/cv1800b_wevb_0008a_spinor.dts +++ /dev/null @@ -1,14 +0,0 @@ -/dts-v1/; -#include "cv180x_base_riscv.dtsi" -#include "cv180x_asic_qfn.dtsi" -#include "cv180x_asic_spinor.dtsi" -#include "cv180x_default_memmap.dtsi" - -&i2c2 { - status = "disabled"; -}; - -/ { - -}; - diff --git a/u-boot-2021.10/arch/riscv/dts/cv1800c_wevb_0009a_spinor.dts b/u-boot-2021.10/arch/riscv/dts/cv1800c_wevb_0009a_spinor.dts deleted file mode 100644 index 7f59a23a9..000000000 --- a/u-boot-2021.10/arch/riscv/dts/cv1800c_wevb_0009a_spinor.dts +++ /dev/null @@ -1,14 +0,0 @@ -/dts-v1/; -#include "cv180x_base_riscv.dtsi" -#include "cv180x_asic_qfn.dtsi" -#include "cv180x_asic_spinor.dtsi" -#include "cv180x_default_memmap.dtsi" - -&i2c1 { - status = "disabled"; -}; - -/ { - -}; - diff --git a/u-boot-2021.10/arch/riscv/dts/cv1801b_wevb_0008a_spinor.dts b/u-boot-2021.10/arch/riscv/dts/cv1801b_wevb_0008a_spinor.dts deleted file mode 100644 index a11b17e07..000000000 --- a/u-boot-2021.10/arch/riscv/dts/cv1801b_wevb_0008a_spinor.dts +++ /dev/null @@ -1,14 +0,0 @@ -/dts-v1/; -#include "cv180x_base_riscv.dtsi" -#include "cv180x_asic_qfn.dtsi" -#include "cv180x_asic_spinor.dtsi" -#include "cv180x_default_memmap.dtsi" - -&i2c2 { - status = "disabled"; -}; - -/ { - -}; - diff --git a/u-boot-2021.10/arch/riscv/dts/cv1801c_wdmb_0009a_spinor.dts b/u-boot-2021.10/arch/riscv/dts/cv1801c_wdmb_0009a_spinor.dts deleted file mode 100644 index 489ecc71d..000000000 --- a/u-boot-2021.10/arch/riscv/dts/cv1801c_wdmb_0009a_spinor.dts +++ /dev/null @@ -1,17 +0,0 @@ -/dts-v1/; -#include "cv180x_base_riscv.dtsi" -#include "cv180x_asic_qfn.dtsi" -#include "cv180x_asic_spinor.dtsi" -#include "cv180x_default_memmap.dtsi" - -&i2c1 { - status = "disabled"; -}; -&mipi_rx{ - snsr-reset = <&portc 17 GPIO_ACTIVE_LOW>, <&portc 17 GPIO_ACTIVE_LOW>, <&portc 17 GPIO_ACTIVE_LOW>; -}; - -/ { - -}; - diff --git a/u-boot-2021.10/arch/riscv/dts/cv1801c_wevb_0009a_spinand.dts b/u-boot-2021.10/arch/riscv/dts/cv1801c_wevb_0009a_spinand.dts deleted file mode 100644 index f9ec58135..000000000 --- a/u-boot-2021.10/arch/riscv/dts/cv1801c_wevb_0009a_spinand.dts +++ /dev/null @@ -1,13 +0,0 @@ -/dts-v1/; -#include "cv180x_base_riscv.dtsi" -#include "cv180x_asic_qfn.dtsi" -#include "cv180x_asic_spinand.dtsi" -#include "cv180x_default_memmap.dtsi" - -&i2c1 { - status = "disabled"; -}; - -/ { - -}; diff --git a/u-boot-2021.10/arch/riscv/dts/cv1801c_wevb_0009a_spinor.dts b/u-boot-2021.10/arch/riscv/dts/cv1801c_wevb_0009a_spinor.dts deleted file mode 100644 index 7f59a23a9..000000000 --- a/u-boot-2021.10/arch/riscv/dts/cv1801c_wevb_0009a_spinor.dts +++ /dev/null @@ -1,14 +0,0 @@ -/dts-v1/; -#include "cv180x_base_riscv.dtsi" -#include "cv180x_asic_qfn.dtsi" -#include "cv180x_asic_spinor.dtsi" -#include "cv180x_default_memmap.dtsi" - -&i2c1 { - status = "disabled"; -}; - -/ { - -}; - diff --git a/u-boot-2021.10/arch/riscv/dts/cv180x_asic_bga.dtsi b/u-boot-2021.10/arch/riscv/dts/cv180x_asic_bga.dtsi deleted file mode 100644 index 2bcacfb3a..000000000 --- a/u-boot-2021.10/arch/riscv/dts/cv180x_asic_bga.dtsi +++ /dev/null @@ -1,12 +0,0 @@ -&dac{ - mute-gpio-l = <&porta 15 GPIO_ACTIVE_LOW>; - mute-gpio-r = <&porta 30 GPIO_ACTIVE_LOW>; -}; - -/ { - /delete-node/ i2s@04110000; - /delete-node/ i2s@04120000; - /delete-node/ sound_ext1; - /delete-node/ sound_ext2; - /delete-node/ sound_PDM; -}; diff --git a/u-boot-2021.10/arch/riscv/dts/cv180x_asic_qfn.dtsi b/u-boot-2021.10/arch/riscv/dts/cv180x_asic_qfn.dtsi deleted file mode 100644 index 46a54b3ec..000000000 --- a/u-boot-2021.10/arch/riscv/dts/cv180x_asic_qfn.dtsi +++ /dev/null @@ -1,114 +0,0 @@ -&sd { - no-1-8-v; -}; - -&mipi_rx{ - snsr-reset = <&portc 13 GPIO_ACTIVE_LOW>, <&portc 13 GPIO_ACTIVE_LOW>, <&portc 13 GPIO_ACTIVE_LOW>; -}; - -&dac{ - mute-gpio-r = <&porte 2 GPIO_ACTIVE_LOW>; -}; - -&spi0 { - status = "disabled"; - num-cs = <1>; - spidev@0 { - compatible = "rohm,dh2228fv"; - spi-max-frequency = <1000000>; - reg = <0>; - }; -}; - -&spi1 { - status = "disabled"; - num-cs = <1>; - spidev@0 { - compatible = "rohm,dh2228fv"; - spi-max-frequency = <1000000>; - reg = <0>; - }; -}; - -&spi2 { - status = "disabled"; - num-cs = <1>; - spidev@0 { - compatible = "rohm,dh2228fv"; - spi-max-frequency = <1000000>; - reg = <0>; - }; -}; - -&spi3 { - status = "okay"; - num-cs = <1>; - spidev@0 { - compatible = "rohm,dh2228fv"; - spi-max-frequency = <1000000>; - reg = <0>; - }; -}; - -&i2c0 { - /* FMUX_GPIO_REG iic_func_sel gpio_func_sel */ - scl-pinmux = <0x0300104c 0x4 0x3>; // IIC0_SCL/IIC0_SCL/XGPIOA[28] - sda-pinmux = <0x03001050 0x4 0x3>; // IIC0_SDA/IIC0_SDA/XGPIOA[29] - /* gpio port */ - scl-gpios = <&porta 28 GPIO_ACTIVE_HIGH>; - sda-gpios = <&porta 29 GPIO_ACTIVE_HIGH>; -}; - -&i2c1 { - /* FMUX_GPIO_REG iic_func_sel gpio_func_sel */ - scl-pinmux = <0x030010f4 0x4 0x3>; // PAD_MIPIRX0N/IIC1_SCL/XGPIOC[10] - sda-pinmux = <0x030010f0 0x4 0x3>; // PAD_MIPIRX1P/IIC1_SDA/XGPIOC[9] - /* gpio port */ - scl-gpios = <&portc 10 GPIO_ACTIVE_HIGH>; - sda-gpios = <&portc 9 GPIO_ACTIVE_HIGH>; -}; - -&i2c2 { - /* FMUX_GPIO_REG iic_func_sel gpio_func_sel */ - scl-pinmux = <0x03001108 0x4 0x3>; // PAD_MIPI_TXP1/IIC2_SCL/XGPIOC[15] - sda-pinmux = <0x03001104 0x4 0x3>; // PAD_MIPI_TXM1/IIC2_SDA/XGPIOC[14] - /* gpio port */ - scl-gpios = <&portc 15 GPIO_ACTIVE_HIGH>; - sda-gpios = <&portc 14 GPIO_ACTIVE_HIGH>; -}; - -&i2c3 { - /* FMUX_GPIO_REG iic_func_sel gpio_func_sel */ - scl-pinmux = <0x0300109c 0x2 0x3>; // SD1_CMD/IIC3_SCL/PWR_GPIO[22] - sda-pinmux = <0x030010a0 0x2 0x3>; // SD1_CLK/IIC3_SDA/PWR_GPIO[23] - /* gpio port */ - scl-gpios = <&porte 22 GPIO_ACTIVE_HIGH>; - sda-gpios = <&porte 23 GPIO_ACTIVE_HIGH>; - status = "disabled"; -}; - -&i2c4 { - /* FMUX_GPIO_REG iic_func_sel gpio_func_sel */ - scl-pinmux = <0x030010e4 0x5 0x3>; // PAD_MIPIRX2N/IIC4_SCL/XGPIOC[6] - sda-pinmux = <0x030010e8 0x5 0x3>; // PAD_MIPIRX2P/IIC4_SDA/XGPIOC[7] - /* gpio port */ - scl-gpios = <&portc 6 GPIO_ACTIVE_HIGH>; - sda-gpios = <&portc 7 GPIO_ACTIVE_HIGH>; - status = "disabled"; -}; - -/ { - /delete-node/ wifi-sd@4320000; - /delete-node/ i2s@04110000; - /delete-node/ i2s@04120000; - /delete-node/ sound_ext1; - /delete-node/ sound_ext2; - /delete-node/ sound_PDM; - - wifi_pin { - compatible = "cvitek,wifi-pin"; - poweron-gpio = <&porte 2 GPIO_ACTIVE_HIGH>; - wakeup-gpio = <&porte 6 GPIO_ACTIVE_HIGH>; - }; - -}; diff --git a/u-boot-2021.10/arch/riscv/dts/cv180x_asic_spinand.dtsi b/u-boot-2021.10/arch/riscv/dts/cv180x_asic_spinand.dtsi deleted file mode 100644 index 2c3c6065c..000000000 --- a/u-boot-2021.10/arch/riscv/dts/cv180x_asic_spinand.dtsi +++ /dev/null @@ -1,5 +0,0 @@ -/ { - /delete-node/ cvi-spif@10000000; - /delete-node/ cv-emmc@4300000; -}; - diff --git a/u-boot-2021.10/arch/riscv/dts/cv180x_asic_spinor.dtsi b/u-boot-2021.10/arch/riscv/dts/cv180x_asic_spinor.dtsi deleted file mode 100644 index cd1254082..000000000 --- a/u-boot-2021.10/arch/riscv/dts/cv180x_asic_spinor.dtsi +++ /dev/null @@ -1,5 +0,0 @@ -/ { - /delete-node/ cv-emmc@4300000; - /delete-node/ cv-spinf@4060000; -}; - diff --git a/u-boot-2021.10/arch/riscv/dts/cv180x_base.dtsi b/u-boot-2021.10/arch/riscv/dts/cv180x_base.dtsi deleted file mode 100644 index 923618bc3..000000000 --- a/u-boot-2021.10/arch/riscv/dts/cv180x_base.dtsi +++ /dev/null @@ -1,881 +0,0 @@ - -/ { - compatible = "cvitek,cv180x"; - - #size-cells = <0x2>; - #address-cells = <0x2>; - - top_misc:top_misc_ctrl@3000000 { - compatible = "syscon"; - reg = <0x0 0x03000000 0x0 0x8000>; - }; - - clk_rst: clk-reset-controller { - #reset-cells = <1>; - compatible = "cvitek,clk-reset"; - reg = <0x0 0x03002000 0x0 0x8>; - }; - - osc: oscillator { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <25000000>; - clock-output-names = "osc"; - }; - - clk: clock-controller { - compatible = "cvitek,cv180x-clk"; - reg = <0x0 0x03002000 0x0 0x1000>; - clocks = <&osc>; - #clock-cells = <1>; - }; - - rst: reset-controller { - #reset-cells = <1>; - compatible = "cvitek,reset"; - reg = <0x0 0x03003000 0x0 0x10>; - }; - - restart: restart-controller { - compatible = "cvitek,restart"; - reg = <0x0 0x05025000 0x0 0x2000>; - }; - - tpu { - compatible = "cvitek,tpu"; - reg-names = "tdma", "tiu"; - reg = <0x0 0x0C100000 0x0 0x1000>, - <0x0 0x0C101000 0x0 0x1000>; - clocks = <&clk CV180X_CLK_TPU>, <&clk CV180X_CLK_TPU_FAB>; - clock-names = "clk_tpu_axi", "clk_tpu_fab"; - resets = <&rst RST_TDMA>, <&rst RST_TPU>, <&rst RST_TPUSYS>; - reset-names = "res_tdma", "res_tpu", "res_tpusys"; - }; - - mon { - compatible = "cvitek,mon"; - reg-names = "pcmon", "ddr_ctrl", "ddr_phyd", "ddr_aximon", "ddr_top"; - reg = <0x0 0x01040000 0x0 0x1000>, - <0x0 0x08004000 0x0 0x1000>, - <0x0 0x08006000 0x0 0x1000>, - <0x0 0x08008000 0x0 0x1000>, - <0x0 0x0800A000 0x0 0x1000>; - }; - - wiegand0 { - compatible = "cvitek,wiegand"; - reg-names = "wiegand"; - reg = <0x0 0x03030000 0x0 0x1000>; - clocks = <&clk CV180X_CLK_WGN>, <&clk CV180X_CLK_WGN0>; - clock-names = "clk_wgn", "clk_wgn1"; - resets = <&rst RST_WGN0>; - reset-names = "res_wgn"; - }; - - wiegand1 { - compatible = "cvitek,wiegand"; - reg-names = "wiegand"; - reg = <0x0 0x03031000 0x0 0x1000>; - clocks = <&clk CV180X_CLK_WGN>, <&clk CV180X_CLK_WGN1>; - clock-names = "clk_wgn", "clk_wgn1"; - resets = <&rst RST_WGN1>; - reset-names = "res_wgn"; - }; - - wiegand2 { - compatible = "cvitek,wiegand"; - reg-names = "wiegand"; - reg = <0x0 0x03032000 0x0 0x1000>; - clocks = <&clk CV180X_CLK_WGN>, <&clk CV180X_CLK_WGN2>; - clock-names = "clk_wgn", "clk_wgn1"; - resets = <&rst RST_WGN2>; - reset-names = "res_wgn"; - }; - - saradc { - compatible = "cvitek,saradc"; - reg-names = "top_domain_saradc", "rtc_domain_saradc"; - reg = <0x0 0x030F0000 0x0 0x1000>, <0x0 0x0502c000 0x0 0x1000>; - clocks = <&clk CV180X_CLK_SARADC>; - clock-names = "clk_saradc"; - resets = <&rst RST_SARADC>; - reset-names = "res_saradc"; - }; - - rtc { - compatible = "cvitek,rtc"; - reg = <0x0 0x05026000 0x0 0x1000>,<0x0 0x05025000 0x0 0x1000>; - clocks = <&clk CV180X_CLK_RTC_25M>; - clock-names = "clk_rtc"; - }; - - cvitek-ion { - compatible = "cvitek,cvitek-ion"; - - heap_carveout@0 { - compatible = "cvitek,carveout"; - memory-region = <&ion_reserved>; - }; - }; - - sysdma_remap { - compatible = "cvitek,sysdma_remap"; - reg = <0x0 0x03000154 0x0 0x10>; - ch-remap = ; - int_mux_base = <0x03000298>; - }; - - dmac: dma@0x4330000 { - compatible = "snps,dmac-bm"; - reg = <0x0 0x04330000 0x0 0x1000>; - clock-names = "clk_sdma_axi"; - clocks = <&clk CV180X_CLK_SDMA_AXI>; - - dma-channels = /bits/ 8 <8>; - #dma-cells = <3>; - dma-requests = /bits/ 8 <16>; - chan_allocation_order = /bits/ 8 <0>; - chan_priority = /bits/ 8 <1>; - block_size = <1024>; - dma-masters = /bits/ 8 <2>; - data-width = <4 4>; /* bytes */ - axi_tr_width = <4>; /* bytes */ - block-ts = <15>; - }; - - watchdog0: cv-wd@0x3010000 { - compatible = "snps,dw-wdt"; - reg = <0x0 0x03010000 0x0 0x1000>; - resets = <&rst RST_WDT>; - clocks = <&pclk>; - }; - - pwm0: pwm@3060000 { - compatible = "cvitek,cvi-pwm"; - reg = <0x0 0x3060000 0x0 0x1000>; - clocks = <&clk CV180X_CLK_PWM>; - #pwm-cells = <1>; - }; - - pwm1: pwm@3061000 { - compatible = "cvitek,cvi-pwm"; - reg = <0x0 0x3061000 0x0 0x1000>; - clocks = <&clk CV180X_CLK_PWM>; - #pwm-cells = <2>; - }; - - pwm2: pwm@3062000 { - compatible = "cvitek,cvi-pwm"; - reg = <0x0 0x3062000 0x0 0x1000>; - clocks = <&clk CV180X_CLK_PWM>; - #pwm-cells = <3>; - }; - - pwm3: pwm@3063000 { - compatible = "cvitek,cvi-pwm"; - reg = <0x0 0x3063000 0x0 0x1000>; - clocks = <&clk CV180X_CLK_PWM>; - #pwm-cells = <4>; - }; - - pclk: pclk { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <25000000>; - }; - - spinand:cv-spinf@4060000 { - compatible = "cvitek,cv1835-spinf"; - reg = <0x0 0x4060000 0x0 0x1000>; - reg-names = "core_mem"; - bus-width = <4>; - dmas = <&dmac 4 1 1 - &dmac 5 1 1>; - dma-names = "rx","tx"; - }; - - spif:cvi-spif@10000000 { - compatible = "cvitek,cvi-spif"; - bus-num = <0>; - reg = <0x0 0x10000000 0x0 0x10000000>; - reg-names = "spif"; - sck-div = <3>; - sck_mhz = <300>; - spi-max-frequency = <75000000>; - spiflash { - compatible = "jedec,spi-nor"; - spi-rx-bus-width = <4>; - spi-tx-bus-width = <4>; - }; - }; - - spi0:spi0@04180000 { - compatible = "snps,dw-apb-ssi"; - reg = <0x0 0x04180000 0x0 0x10000>; - clocks = <&clk CV180X_CLK_SPI>; - #address-cells = <1>; - #size-cells = <0>; - }; - - spi1:spi1@04190000 { - compatible = "snps,dw-apb-ssi"; - reg = <0x0 0x04190000 0x0 0x10000>; - clocks = <&clk CV180X_CLK_SPI>; - #address-cells = <1>; - #size-cells = <0>; - }; - - spi2:spi2@041A0000 { - compatible = "snps,dw-apb-ssi"; - reg = <0x0 0x041A0000 0x0 0x10000>; - clocks = <&clk CV180X_CLK_SPI>; - #address-cells = <1>; - #size-cells = <0>; - }; - - spi3:spi3@041B0000 { - compatible = "snps,dw-apb-ssi"; - reg = <0x0 0x041B0000 0x0 0x10000>; - clocks = <&clk CV180X_CLK_SPI>; - #address-cells = <1>; - #size-cells = <0>; -#if 0 - dmas = <&dmac 2 1 1 - &dmac 3 1 1>; - dma-names = "rx", "tx"; - capability = "txrx"; -#endif - }; - - uart0: serial@04140000 { - compatible = "snps,dw-apb-uart"; - reg = <0x0 0x04140000 0x0 0x1000>; - clock-frequency = <25000000>; - reg-shift = <2>; - reg-io-width = <4>; - status = "okay"; - }; - - uart1: serial@04150000 { - compatible = "snps,dw-apb-uart"; - reg = <0x0 0x04150000 0x0 0x1000>; - clock-frequency = <25000000>; - reg-shift = <2>; - reg-io-width = <4>; - status = "disabled"; - }; - - uart2: serial@04160000 { - compatible = "snps,dw-apb-uart"; - reg = <0x0 0x04160000 0x0 0x1000>; - clock-frequency = <25000000>; - reg-shift = <2>; - reg-io-width = <4>; - status = "disabled"; - }; - - uart3: serial@04170000 { - compatible = "snps,dw-apb-uart"; - reg = <0x0 0x04170000 0x0 0x1000>; - clock-frequency = <25000000>; - reg-shift = <2>; - reg-io-width = <4>; - status = "disabled"; - }; - - uart4: serial@041C0000 { - compatible = "snps,dw-apb-uart"; - reg = <0x0 0x041C0000 0x0 0x1000>; - clock-frequency = <25000000>; - reg-shift = <2>; - reg-io-width = <4>; - status = "disabled"; - }; - - gpio0: gpio@03020000 { - compatible = "snps,dw-apb-gpio"; - reg = <0x0 0x03020000 0x0 0x1000>; - #address-cells = <1>; - #size-cells = <0>; - - porta: gpio-controller@0 { - compatible = "snps,dw-apb-gpio-port"; - bank-name = "porta"; - gpio-controller; - #gpio-cells = <2>; - snps,nr-gpios = <32>; - reg = <0>; - }; - }; - - gpio1: gpio@03021000 { - compatible = "snps,dw-apb-gpio"; - reg = <0x0 0x03021000 0x0 0x1000>; - #address-cells = <1>; - #size-cells = <0>; - - portb: gpio-controller@1 { - compatible = "snps,dw-apb-gpio-port"; - bank-name = "portb"; - gpio-controller; - #gpio-cells = <2>; - snps,nr-gpios = <32>; - reg = <0>; - }; - }; - - gpio2: gpio@03022000 { - compatible = "snps,dw-apb-gpio"; - reg = <0x0 0x03022000 0x0 0x1000>; - #address-cells = <1>; - #size-cells = <0>; - - portc: gpio-controller@2 { - compatible = "snps,dw-apb-gpio-port"; - bank-name = "portc"; - gpio-controller; - #gpio-cells = <2>; - snps,nr-gpios = <32>; - reg = <0>; - }; - }; - - gpio3: gpio@03023000 { - compatible = "snps,dw-apb-gpio"; - reg = <0x0 0x03023000 0x0 0x1000>; - #address-cells = <1>; - #size-cells = <0>; - - portd: gpio-controller@3 { - compatible = "snps,dw-apb-gpio-port"; - bank-name = "portd"; - gpio-controller; - #gpio-cells = <2>; - snps,nr-gpios = <12>; - reg = <0>; - }; - }; - - gpio4: gpio@05021000 { - compatible = "snps,dw-apb-gpio"; - reg = <0x0 0x05021000 0x0 0x1000>; - #address-cells = <1>; - #size-cells = <0>; - - porte: gpio-controller@4 { - compatible = "snps,dw-apb-gpio-port"; - bank-name = "porte"; - gpio-controller; - #gpio-cells = <2>; - snps,nr-gpios = <24>; - reg = <0>; - }; - }; - - i2c0: i2c@04000000 { - compatible = "snps,designware-i2c"; - clocks = <&clk CV180X_CLK_I2C>; - reg = <0x0 0x04000000 0x0 0x1000>; - clock-frequency = <400000>; - - #size-cells = <0x0>; - #address-cells = <0x1>; - resets = <&rst RST_I2C0>; - reset-names = "i2c0"; - }; - - i2c1: i2c@04010000 { - compatible = "snps,designware-i2c"; - clocks = <&clk CV180X_CLK_I2C>; - reg = <0x0 0x04010000 0x0 0x1000>; - clock-frequency = <400000>; - - #size-cells = <0x0>; - #address-cells = <0x1>; - resets = <&rst RST_I2C1>; - reset-names = "i2c1"; - }; - - i2c2: i2c@04020000 { - compatible = "snps,designware-i2c"; - clocks = <&clk CV180X_CLK_I2C>; - reg = <0x0 0x04020000 0x0 0x1000>; - clock-frequency = <100000>; - - #size-cells = <0x0>; - #address-cells = <0x1>; - resets = <&rst RST_I2C2>; - reset-names = "i2c2"; - }; - - i2c3: i2c@04030000 { - compatible = "snps,designware-i2c"; - clocks = <&clk CV180X_CLK_I2C>; - reg = <0x0 0x04030000 0x0 0x1000>; - clock-frequency = <400000>; - - #size-cells = <0x0>; - #address-cells = <0x1>; - resets = <&rst RST_I2C3>; - reset-names = "i2c3"; - }; - - i2c4: i2c@04040000 { - compatible = "snps,designware-i2c"; - clocks = <&clk CV180X_CLK_I2C>; - reg = <0x0 0x04040000 0x0 0x1000>; - clock-frequency = <400000>; - - #size-cells = <0x0>; - #address-cells = <0x1>; - resets = <&rst RST_I2C4>; - reset-names = "i2c4"; - }; - - eth_csrclk: eth_csrclk { - clock-output-names = "eth_csrclk"; - clock-frequency = <250000000>; - #clock-cells = <0x0>; - compatible = "fixed-clock"; - }; - - eth_ptpclk: eth_ptpclk { - clock-output-names = "eth_ptpclk"; - clock-frequency = <50000000>; - #clock-cells = <0x0>; - compatible = "fixed-clock"; - }; - - stmmac_axi_setup: stmmac-axi-config { - snps,wr_osr_lmt = <1>; - snps,rd_osr_lmt = <2>; - snps,blen = <4 8 16 0 0 0 0>; - }; - - mtl_rx_setup: rx-queues-config { - snps,rx-queues-to-use = <1>; - queue0 {}; - }; - - mtl_tx_setup: tx-queues-config { - snps,tx-queues-to-use = <1>; - queue0 {}; - }; - - ethernet0: ethernet@4070000 { - compatible = "cvitek,ethernet"; - reg = <0x0 0x04070000 0x0 0x10000>; - clock-names = "stmmaceth", "ptp_ref"; - clocks = <ð_csrclk>, <ð_ptpclk>; - //phy-reset-gpios = <&porta 26 0>; - - tx-fifo-depth = <8192>; - rx-fifo-depth = <8192>; - /* no hash filter and perfect filter support */ - snps,multicast-filter-bins = <0>; - snps,perfect-filter-entries = <1>; - - snps,txpbl = <8>; - snps,rxpbl = <8>; - snps,aal; - - snps,axi-config = <&stmmac_axi_setup>; - snps,mtl-rx-config = <&mtl_rx_setup>; - snps,mtl-tx-config = <&mtl_tx_setup>; - - phy-mode = "rmii"; - }; - - sd:cv-sd@4310000 { - compatible = "cvitek,cv180x-sd"; - reg = <0x0 0x4310000 0x0 0x1000>; - reg-names = "core_mem"; - bus-width = <4>; - cap-sd-highspeed; - cap-mmc-highspeed; - sd-uhs-sdr12; - sd-uhs-sdr25; - sd-uhs-sdr50; - sd-uhs-sdr104; - no-sdio; - no-mmc; - /*no-1-8-v;*/ - src-frequency = <375000000>; - min-frequency = <400000>; - max-frequency = <200000000>; - 64_addressing; - reset_tx_rx_phy; - reset-names = "sdhci"; - pll_index = <0x6>; - pll_reg = <0x3002070>; - cvi-cd-gpios = <&porta 13 GPIO_ACTIVE_LOW>; - }; - - wifisd:wifi-sd@4320000 { - compatible = "cvitek,cv180x-sdio"; - bus-width = <4>; - reg = <0x0 0x4320000 0x0 0x1000>; - reg_names = "core_mem"; - src-frequency = <375000000>; - min-frequency = <400000>; - max-frequency = <50000000>; - 64_addressing; - reset_tx_rx_phy; - non-removable; - pll_index = <0x7>; - pll_reg = <0x300207C>; - no-mmc; - no-sd; - status = "disabled"; - }; - - i2s_mclk: i2s_mclk { - clock-output-names = "i2s_mclk"; - clock-frequency = <24576000>; - #clock-cells = <0x0>; - compatible = "fixed-clock"; - }; - - i2s_subsys { - compatible = "cvitek,i2s_tdm_subsys"; - reg = <0x0 0x04108000 0x0 0x100>; - clocks = <&i2s_mclk>, <&clk CV180X_CLK_A0PLL>, - <&clk CV180X_CLK_SDMA_AUD0>, <&clk CV180X_CLK_SDMA_AUD1>, - <&clk CV180X_CLK_SDMA_AUD2>, <&clk CV180X_CLK_SDMA_AUD3>; - clock-names = "i2sclk", "clk_a0pll", - "clk_sdma_aud0", "clk_sdma_aud1", - "clk_sdma_aud2", "clk_sdma_aud3"; - master_base = <0x04110000>; /* I2S1 is master, only useful while using multi I2S IPs work on same IO */ - }; - - i2s0: i2s@04100000 { - compatible = "cvitek,cv1835-i2s"; - reg = <0x0 0x04100000 0x0 0x2000>; - clocks = <&i2s_mclk 0>; - clock-names = "i2sclk"; - dev-id = <0>; - #sound-dai-cells = <0>; - dmas = <&dmac 0 1 1>; /* read channel */ - dma-names = "rx"; - capability = "rx"; /* I2S0 connect to internal ADC as RX */ - mclk_out = "false"; - }; - - i2s1: i2s@04110000 { - compatible = "cvitek,cv1835-i2s"; - reg = <0x0 0x04110000 0x0 0x2000>; - clocks = <&i2s_mclk 0>; - clock-names = "i2sclk"; - dev-id = <1>; - #sound-dai-cells = <0>; - dmas = <&dmac 2 1 1 /* read channel */ - &dmac 3 1 1>; /* write channel */ - dma-names = "rx", "tx"; - capability = "txrx"; - mclk_out = "false"; - }; - - i2s2: i2s@04120000 { - compatible = "cvitek,cv1835-i2s"; - reg = <0x0 0x04120000 0x0 0x2000>; - clocks = <&i2s_mclk 0>; - clock-names = "i2sclk"; - dev-id = <2>; - #sound-dai-cells = <0>; - dmas = <&dmac 6 1 1 /* read channel */ - &dmac 1 1 1>; /* write channel */ - dma-names = "rx", "tx"; - capability = "txrx"; - mclk_out = "false"; - - }; - - i2s3: i2s@04130000 { - compatible = "cvitek,cv1835-i2s"; - reg = <0x0 0x04130000 0x0 0x2000>; - clocks = <&i2s_mclk 0>; - clock-names = "i2sclk"; - dev-id = <3>; - #sound-dai-cells = <0>; - dmas = <&dmac 7 1 1>; /* write channel */ - dma-names = "tx"; - capability = "tx"; /* I2S3 connect to internal DAC as TX */ - mclk_out = "true"; - }; - - adc: adc@0300A100 { - compatible = "cvitek,cv182xaadc"; - reg = <0x0 0x0300A100 0x0 0x100>; - clocks = <&i2s_mclk 0>; - clock-names = "i2sclk"; - clk_source = <0x04130000>; /* MCLK source is I2S3 */ - }; - - dac: dac@0300A000 { - compatible = "cvitek,cv182xadac"; - reg = <0x0 0x0300A000 0x0 0x100>; - clocks = <&i2s_mclk 0>; - clock-names = "i2sclk"; - }; - - pdm: pdm@0x041D0C00 { - compatible = "cvitek,cv1835pdm"; - reg = <0x0 0x041D0C00 0x0 0x100>; - clocks = <&i2s_mclk 0>; - clock-names = "i2sclk"; - }; - - sound_adc { - compatible = "cvitek,cv182xa-adc"; - cvi,model = "CV182XA"; - cvi,card_name = "cv182xa_adc"; - }; - - sound_dac { - compatible = "cvitek,cv182xa-dac"; - cvi,model = "CV182XA"; - cvi,card_name = "cv182xa_dac"; - }; - - sound_PDM { - compatible = "cvitek,cv182x-pdm"; - cvi,model = "CV182X"; - cvi,card_name = "cv182x_internal_PDM"; - }; - - wifi_pin { - compatible = "cvitek,wifi-pin"; - poweron-gpio = <&porta 18 GPIO_ACTIVE_HIGH>; - wakeup-gpio = <&porte 7 GPIO_ACTIVE_HIGH>; - }; - - bt_pin { - compatible = "cvitek,bt-pin"; - poweron-gpio = <&porte 9 GPIO_ACTIVE_HIGH>; - }; - - mipi_rx: cif { - compatible = "cvitek,cif"; - reg = <0x0 0x0a0c2000 0x0 0x2000>, <0x0 0x0a0d0000 0x0 0x1000>, - <0x0 0x0a0c4000 0x0 0x2000>, <0x0 0x03001c30 0x0 0x30>; - reg-names = "csi_mac0", "csi_wrap0", "csi_mac1", "pad_ctrl"; - snsr-reset = <&porta 2 GPIO_ACTIVE_LOW>, <&porta 2 GPIO_ACTIVE_LOW>, <&porta 2 GPIO_ACTIVE_LOW>; - resets = <&rst RST_CSIPHY0>, <&rst RST_CSIPHY1>, - <&rst RST_CSIPHY0RST_APB>, <&rst RST_CSIPHY1RST_APB>; - reset-names = "phy0", "phy1", "phy-apb0", "phy-apb1"; - clocks = <&clk CV180X_CLK_CAM0>, <&clk CV180X_CLK_CAM1>, <&clk CV180X_CLK_SRC_VIP_SYS_2>, - <&clk CV180X_CLK_MIPIMPLL>, <&clk CV180X_CLK_DISPPLL>, <&clk CV180X_CLK_FPLL>; - clock-names = "clk_cam0", "clk_cam1", "clk_sys_2", - "clk_mipimpll", "clk_disppll", "clk_fpll"; - }; - - sys { - compatible = "cvitek,sys"; - }; - - base { - compatible = "cvitek,base"; - reg = <0x0 0x0a0c8000 0x0 0x20>; - reg-names = "vip_sys"; - }; - - vi { - compatible = "cvitek,vi"; - reg = <0x0 0x0a000000 0x0 0x80000>; - clocks = <&clk CV180X_CLK_SRC_VIP_SYS_0>, <&clk CV180X_CLK_SRC_VIP_SYS_1>, - <&clk CV180X_CLK_SRC_VIP_SYS_2>, <&clk CV180X_CLK_SRC_VIP_SYS_3>, - <&clk CV180X_CLK_AXI_VIP>, <&clk CV180X_CLK_CSI_BE_VIP>, - <&clk CV180X_CLK_RAW_VIP>, <&clk CV180X_CLK_ISP_TOP_VIP>, - <&clk CV180X_CLK_CSI_MAC0_VIP>, <&clk CV180X_CLK_CSI_MAC1_VIP>, - <&clk CV180X_CLK_CSI_MAC2_VIP>; - clock-names = "clk_sys_0", "clk_sys_1", "clk_sys_2", "clk_sys_3", - "clk_axi", "clk_csi_be", "clk_raw", "clk_isp_top", - "clk_csi_mac0", "clk_csi_mac1", "clk_csi_mac2"; - clock-freq-vip-sys1 = <300000000>; - }; - - vpss { - compatible = "cvitek,vpss"; - reg = <0x0 0x0a080000 0x0 0x10000>, <0x0 0x0a0d1000 0x0 0x100>; - reg-names = "sc"; - clocks = <&clk CV180X_CLK_SRC_VIP_SYS_0>, <&clk CV180X_CLK_SRC_VIP_SYS_1>, - <&clk CV180X_CLK_SRC_VIP_SYS_2>, <&clk CV180X_CLK_IMG_D_VIP>, - <&clk CV180X_CLK_IMG_V_VIP>, <&clk CV180X_CLK_SC_TOP_VIP>, - <&clk CV180X_CLK_SC_D_VIP>, <&clk CV180X_CLK_SC_V1_VIP>, - <&clk CV180X_CLK_SC_V2_VIP>, <&clk CV180X_CLK_SC_V3_VIP>; - clock-names = "clk_sys_0", "clk_sys_1", - "clk_sys_2", "clk_img_d", - "clk_img_v", "clk_sc_top", - "clk_sc_d", "clk_sc_v1", - "clk_sc_v2", "clk_sc_v3"; - clock-freq-vip-sys1 = <300000000>; - }; - - dwa { - compatible = "cvitek,dwa"; - reg = <0x0 0x0a0c0000 0x0 0x1000>; - reg-names = "dwa"; - clocks = <&clk CV180X_CLK_SRC_VIP_SYS_0>, <&clk CV180X_CLK_SRC_VIP_SYS_1>, - <&clk CV180X_CLK_SRC_VIP_SYS_2>, <&clk CV180X_CLK_SRC_VIP_SYS_3>, - <&clk CV180X_CLK_SRC_VIP_SYS_4>, <&clk CV180X_CLK_DWA_VIP>; - clock-names = "clk_sys_0", "clk_sys_1", - "clk_sys_2", "clk_sys_3", - "clk_sys_4", "clk_dwa"; - clock-freq-vip-sys1 = <300000000>; - }; - - rgn { - compatible = "cvitek,rgn"; - }; - - vcodec { - compatible = "cvitek,asic-vcodec"; - reg = <0x0 0x0B020000 0x0 0x10000>,<0x0 0x0B010000 0x0 0x10000>,<0x0 0x0B030000 0x0 0x100>, - <0x0 0x0B058000 0x0 0x100>,<0x0 0x0B050000 0x0 0x400>; - reg-names = "h265","h264","vc_ctrl","vc_sbm","vc_addr_remap"; - clocks = <&clk CV180X_CLK_AXI_VIDEO_CODEC>, - <&clk CV180X_CLK_H264C>, <&clk CV180X_CLK_APB_H264C>, - <&clk CV180X_CLK_H265C>, <&clk CV180X_CLK_APB_H265C>, - <&clk CV180X_CLK_VC_SRC0>, <&clk CV180X_CLK_VC_SRC1>, - <&clk CV180X_CLK_VC_SRC2>, <&clk CV180X_CLK_CFG_REG_VC>; - clock-names = "clk_axi_video_codec", - "clk_h264c", "clk_apb_h264c", - "clk_h265c", "clk_apb_h265c", - "clk_vc_src0", "clk_vc_src1", - "clk_vc_src2", "clk_cfg_reg_vc"; - }; - - jpu { - compatible = "cvitek,asic-jpeg"; - reg = <0x0 0x0B000000 0x0 0x300>,<0x0 0x0B030000 0x0 0x100>,<0x0 0x0B058000 0x0 0x100>; - reg-names = "jpeg","vc_ctrl","vc_sbm"; - clocks = <&clk CV180X_CLK_AXI_VIDEO_CODEC>, - <&clk CV180X_CLK_JPEG>, <&clk CV180X_CLK_APB_JPEG>, - <&clk CV180X_CLK_VC_SRC0>, <&clk CV180X_CLK_VC_SRC1>, - <&clk CV180X_CLK_VC_SRC2>, <&clk CV180X_CLK_CFG_REG_VC>; - clock-names = "clk_axi_video_codec", - "clk_jpeg", "clk_apb_jpeg", - "clk_vc_src0", "clk_vc_src1", - "clk_vc_src2", "clk_cfg_reg_vc"; - resets = <&rst RST_JPEG>; - reset-names = "jpeg"; - }; - - cvi_vc_drv { - compatible = "cvitek,cvi_vc_drv"; - reg = <0x0 0x0B030000 0x0 0x100>,<0x0 0x0B058000 0x0 0x100>,<0x0 0x0B050000 0x0 0x400>; - reg-names = "vc_ctrl","vc_sbm","vc_addr_remap"; - }; - - rtos_cmdqu { - compatible = "cvitek,rtos_cmdqu"; - reg = <0x0 0x01900000 0x0 0x1000>; - reg-names = "mailbox"; - }; - - usb: usb@04340000 { - compatible = "cvitek,cv182x-usb"; - reg = <0x0 0x04340000 0x0 0x10000>, - <0x0 0x03006000 0x0 0x58>; //USB 2.0 PHY - dr_mode = "otg"; - g-use-dma; - g-rx-fifo-size = <536>; - g-np-tx-fifo-size = <32>; - g-tx-fifo-size = <768 512 512 384 128 128>; - clocks = <&clk CV180X_CLK_AXI4_USB>, - <&clk CV180X_CLK_APB_USB>, - <&clk CV180X_CLK_125M_USB>, - <&clk CV180X_CLK_33K_USB>, - <&clk CV180X_CLK_12M_USB>; - clock-names = "clk_axi", "clk_apb", "clk_125m", "clk_33k", "clk_12m"; - vbus-gpio = <&portb 6 0>; - status = "okay"; - }; - - thermal:thermal@030E0000 { - compatible = "cvitek,cv180x-thermal"; - reg = <0x0 0x030E0000 0x0 0x10000>; - clocks = <&clk CV180X_CLK_TEMPSEN>; - clock-names = "clk_tempsen"; - reset-names = "tempsen"; - #thermal-sensor-cells = <1>; - }; - -#if 0 - cv182x_cooling:cv182x_cooling { - clocks = <&clk CV180X_CLK_A53>, <&clk CV180X_CLK_TPU>; - clock-names = "clk_a53", "clk_tpu_axi"; - dev-freqs = <1000000000 750000000>, - <500000000 375000000>, - <500000000 100000000>; - compatible = "cvitek,cv182x-cooling"; - #cooling-cells = <2>; - }; -#endif - - thermal-zones { - soc_thermal_0: soc_thermal_0 { - polling-delay-passive = <1000>; /* milliseconds */ - polling-delay = <1000>; /* milliseconds */ - thermal-sensors = <&thermal 0>; - - trips { - soc_thermal_trip_0: soc_thermal_trip_0 { - temperature = <100000>; /* millicelsius */ - hysteresis = <5000>; /* millicelsius */ - type = "passive"; - }; - - soc_thermal_trip_1: soc_thermal_trip_1 { - temperature = <110000>; /* millicelsius */ - hysteresis = <5000>; /* millicelsius */ - type = "passive"; - }; - - soc_thermal_crtical_0: soc_thermal_crtical_0 { - temperature = <130000>; /* millicelsius */ - hysteresis = <0>; /* millicelsius */ - type = "critical"; - }; - }; - }; - }; - -#if 0 - cvipctrl: pinctrl@3001000 { - compatible = "cvitek,pinctrl-cv182x"; - reg = <0 0x03001000 0 0x1000>; - }; -#endif - - cviaudio_core { - compatible = "cvitek,audio"; - }; - - audio_clock: audio_clock { - compatible = "fixed-clock"; - #clock-cells = <0>; -#if 0 - clock-frequency = <12288000>; -#else - clock-frequency = <24576000>; -#endif - }; - - - aliases { - i2c0 = &i2c0; - i2c1 = &i2c1; - i2c2 = &i2c2; - i2c3 = &i2c3; - i2c4 = &i2c4; - serial0 = &uart0; - ethernet0 = ðernet0; - }; - - chosen { - stdout-path = "serial0"; - }; -}; - diff --git a/u-boot-2021.10/arch/riscv/dts/cv180x_base_riscv.dtsi b/u-boot-2021.10/arch/riscv/dts/cv180x_base_riscv.dtsi deleted file mode 100644 index ca87a1a85..000000000 --- a/u-boot-2021.10/arch/riscv/dts/cv180x_base_riscv.dtsi +++ /dev/null @@ -1,374 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "cvi_board_memmap.h" - -/* - * OpenSBI will add below subnode into reserved memory automatically - * mmode_resv0@80000000 { - * reg = <0x00 0x80000000 0x00 0x20000>; - * phandle = <0x0d>; - * }; - * Skip below to avoid lmb region reseved conflict in uboot. - * - */ -#ifndef __UBOOT__ -/memreserve/ CVIMMAP_MONITOR_ADDR CVIMMAP_OPENSBI_SIZE; // OpenSBI -#endif - -#include "cv180x_base.dtsi" - -/ { - model = "Cvitek. CV180X ASIC. C906."; - - #size-cells = <0x2>; - #address-cells = <0x2>; - - c906_cpus:cpus { - #address-cells = <0x01>; - #size-cells = <0x00>; - timebase-frequency = <25000000>; - - cpu-map { - - cluster0 { - - core0 { - cpu = <0x01>; - }; - }; - }; - - cpu@0 { - device_type = "cpu"; - reg = <0x00>; - status = "okay"; - compatible = "riscv"; - riscv,isa = "rv64imafdvcsu"; - mmu-type = "riscv,sv39"; - clock-frequency = <25000000>; - - cpu0_intc: interrupt-controller { - #interrupt-cells = <0x01>; - interrupt-controller; - compatible = "riscv,cpu-intc"; - }; - }; - }; - - soc { - #address-cells = <0x02>; - #size-cells = <0x02>; - compatible = "simple-bus"; - ranges; - - plic0: interrupt-controller@70000000 { - riscv,ndev = <101>; - riscv,max-priority = <0x07>; - reg-names = "control"; - reg = <0x00 0x70000000 0x00 0x4000000>; - interrupts-extended = <&cpu0_intc 0xffffffff &cpu0_intc 0x09>; - interrupt-controller; - compatible = "riscv,plic0"; - #interrupt-cells = <0x02>; - #address-cells = <0x00>; - }; - - clint@74000000 { - interrupts-extended = <&cpu0_intc 0x03 &cpu0_intc 0x07>; - reg = <0x00 0x74000000 0x00 0x10000>; - compatible = "riscv,clint0"; - clint,has-no-64bit-mmio; - }; - - }; - - - cv180x_cooling:cv180x_cooling { - clocks = <&clk CV180X_CLK_C906_0>, <&clk CV180X_CLK_TPU>; - clock-names = "clk_cpu", "clk_tpu_axi"; - dev-freqs = <850000000 500000000>, - <425000000 375000000>, - <425000000 300000000>; - compatible = "cvitek,cv180x-cooling"; - #cooling-cells = <2>; - }; - - tpu { - interrupts = <75 IRQ_TYPE_LEVEL_HIGH>, - <76 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "tiu_irq", "tdma_irq"; - interrupt-parent = <&plic0>; - }; - - mon { - interrupts = <93 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "mon_irq"; - interrupt-parent = <&plic0>; - }; - - wiegand0 { - interrupts = <64 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; - - wiegand1 { - interrupts = <65 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; - - wiegand2 { - interrupts = <66 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; - - saradc { - interrupts = <100 IRQ_TYPE_EDGE_RISING>; - interrupt-parent = <&plic0>; - }; - - rtc { - interrupts = <17 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; - - sysdma_remap { - int_mux = <0x7FC00>; /* enable bit [10..18] for CPU1(906B) */ - }; - - dmac: dma@0x4330000 { - interrupts = <29 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; - - watchdog0: cv-wd@0x3010000 { - interrupts = <58 IRQ_TYPE_LEVEL_HIGH>; - }; - - spinand:cv-spinf@4060000 { - interrupts = <39 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; - - spif:cvi-spif@10000000 { - interrupts = <95 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; - - spi0:spi0@04180000 { - interrupts = <54 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; - - spi1:spi1@04190000 { - interrupts = <55 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; - - spi2:spi2@041A0000 { - interrupts = <56 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; - - spi3:spi3@041B0000 { - interrupts = <57 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; - - uart0: serial@04140000 { - interrupts = <44 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; - - uart1: serial@04150000 { - interrupts = <45 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; - - uart2: serial@04160000 { - interrupts = <46 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; - - uart3: serial@04170000 { - interrupts = <47 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; - - uart4: serial@041C0000 { - interrupts = <48 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; - - gpio0: gpio@03020000 { - porta: gpio-controller@0 { - interrupt-controller; - interrupts = <60 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; - }; - - gpio1: gpio@03021000 { - portb: gpio-controller@1 { - interrupt-controller; - interrupts = <61 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; - }; - - gpio2: gpio@03022000 { - portc: gpio-controller@2 { - interrupt-controller; - interrupts = <62 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; - }; - - gpio3: gpio@03023000 { - portd: gpio-controller@3 { - interrupt-controller; - interrupts = <63 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; - }; - - gpio4: gpio@05021000 { - porte: gpio-controller@4 { - interrupt-controller; - interrupts = <70 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; - }; - - i2c0: i2c@04000000 { - interrupts = <49 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; - - i2c1: i2c@04010000 { - interrupts = <50 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; - - i2c2: i2c@04020000 { - interrupts = <51 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; - - i2c3: i2c@04030000 { - interrupts = <52 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; - - i2c4: i2c@04040000 { - interrupts = <53 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; - - ethernet0: ethernet@4070000 { - interrupt-names = "macirq"; - interrupts = <31 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; -#if 0 - emmc:cv-emmc@4300000 { - interrupts = <34 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; -#endif - sd:cv-sd@4310000 { - interrupts = <36 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; - - i2s0: i2s@04100000 { - interrupts = <40 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; - - i2s1: i2s@04110000 { - interrupts = <41 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; - - i2s2: i2s@04120000 { - interrupts = <42 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; - - i2s3: i2s@04130000 { - interrupts = <43 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; - - vi { - interrupts = <24 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - interrupt-names = "isp"; - }; - - vcodec { - interrupts = <22 IRQ_TYPE_LEVEL_HIGH>, - <21 IRQ_TYPE_LEVEL_HIGH>, - <23 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "h265","h264","sbm"; - interrupt-parent = <&plic0>; - }; - - jpu { - interrupts = <20 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "jpeg"; - interrupt-parent = <&plic0>; - }; - - rtos_cmdqu { - interrupts = <101 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "mailbox"; - interrupt-parent = <&plic0>; - }; - - wifisd:wifi-sd@4320000 { - interrupts = <38 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; - - mipi_rx: cif { - interrupts = <26 IRQ_TYPE_LEVEL_HIGH>, - <27 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "csi0", "csi1"; - interrupt-parent = <&plic0>; - }; -#if 0 - ive { - interrupt-names = "ive_irq"; - interrupt-parent = <&plic0>; - interrupts = <97 IRQ_TYPE_LEVEL_HIGH>; - }; -#endif - vpss { - interrupts = <25 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "sc"; - interrupt-parent = <&plic0>; - }; - - dwa { - interrupts = <28 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "dwa"; - interrupt-parent = <&plic0>; - }; - - usb: usb@04340000 { - interrupts = <30 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&plic0>; - }; - - thermal:thermal@030E0000 { - interrupts = <16 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "tempsen"; - interrupt-parent = <&plic0>; - }; - -}; diff --git a/u-boot-2021.10/arch/riscv/dts/cv180x_default_memmap.dtsi b/u-boot-2021.10/arch/riscv/dts/cv180x_default_memmap.dtsi deleted file mode 100644 index 93ab84007..000000000 --- a/u-boot-2021.10/arch/riscv/dts/cv180x_default_memmap.dtsi +++ /dev/null @@ -1,26 +0,0 @@ -/ { - memory@80000000 { - device_type = "memory"; - reg = <0x00 CVIMMAP_KERNEL_MEMORY_ADDR 0x00 CVIMMAP_KERNEL_MEMORY_SIZE>; - }; - - - fast_image { - compatible = "cvitek,rtos_image"; - reg-names = "rtos_region"; - reg = <0x0 CVIMMAP_FREERTOS_ADDR 0x0 CVIMMAP_FREERTOS_SIZE>; - ion-size = ; //reserved ion size for freertos - }; - - reserved-memory { - #size-cells = <0x2>; - #address-cells = <0x2>; - ranges; - - ion_reserved: ion { - compatible = "ion-region"; - alloc-ranges = <0x0 CVIMMAP_ION_ADDR 0 CVIMMAP_ION_SIZE>; - size = <0x0 CVIMMAP_ION_SIZE>; - }; - }; -}; diff --git a/u-boot-2021.10/arch/riscv/dts/cv180x_fpga.dts b/u-boot-2021.10/arch/riscv/dts/cv180x_fpga.dts deleted file mode 100644 index 19b42bf59..000000000 --- a/u-boot-2021.10/arch/riscv/dts/cv180x_fpga.dts +++ /dev/null @@ -1,16 +0,0 @@ -/dts-v1/; -#include "cv180x_base_riscv.dtsi" -#include "cv180x_asic_bga.dtsi" -#include "cv180x_asic_spinor.dtsi" -#include "cv180x_default_memmap.dtsi" - -/ { - -}; - -&sd { - no-1-8-v; - src-frequency = <25000000>; - min-frequency = <400000>; - max-frequency = <12000000>; -}; diff --git a/u-boot-2021.10/arch/riscv/dts/cv180x_palladium.dts b/u-boot-2021.10/arch/riscv/dts/cv180x_palladium.dts deleted file mode 100644 index 46e712f74..000000000 --- a/u-boot-2021.10/arch/riscv/dts/cv180x_palladium.dts +++ /dev/null @@ -1,22 +0,0 @@ -/dts-v1/; -#include "cv180x_base_riscv.dtsi" -#include "cv180x_asic_bga.dtsi" -#include "cv180x_asic_spinor.dtsi" -#include "cv180x_default_memmap.dtsi" - -/ { - -}; - -&c906_cpus { - timebase-frequency = <1000000000>; - - cpu@0 { - clock-frequency = <850000000>; - }; -}; - -&uart0 { - clock-frequency = <307200>; - current-speed = <19200>; -}; diff --git a/u-boot-2021.10/arch/riscv/dts/cv180zb_wdmb_0008a_spinor.dts b/u-boot-2021.10/arch/riscv/dts/cv180zb_wdmb_0008a_spinor.dts deleted file mode 100644 index 5314a49d9..000000000 --- a/u-boot-2021.10/arch/riscv/dts/cv180zb_wdmb_0008a_spinor.dts +++ /dev/null @@ -1,14 +0,0 @@ -/dts-v1/; -#include "cv180x_base_riscv.dtsi" -#include "cv180x_asic_qfn.dtsi" -#include "cv180x_asic_spinor.dtsi" -#include "cv180x_default_memmap.dtsi" - -&mipi_rx{ - snsr-reset = <&portc 8 GPIO_ACTIVE_LOW>, <&portc 8 GPIO_ACTIVE_LOW>, <&portc 8 GPIO_ACTIVE_LOW>; -}; - -/ { - -}; - diff --git a/u-boot-2021.10/arch/riscv/dts/cv180zb_wevb_0008a_spinor.dts b/u-boot-2021.10/arch/riscv/dts/cv180zb_wevb_0008a_spinor.dts deleted file mode 100644 index 5314a49d9..000000000 --- a/u-boot-2021.10/arch/riscv/dts/cv180zb_wevb_0008a_spinor.dts +++ /dev/null @@ -1,14 +0,0 @@ -/dts-v1/; -#include "cv180x_base_riscv.dtsi" -#include "cv180x_asic_qfn.dtsi" -#include "cv180x_asic_spinor.dtsi" -#include "cv180x_default_memmap.dtsi" - -&mipi_rx{ - snsr-reset = <&portc 8 GPIO_ACTIVE_LOW>, <&portc 8 GPIO_ACTIVE_LOW>, <&portc 8 GPIO_ACTIVE_LOW>; -}; - -/ { - -}; - diff --git a/u-boot-2021.10/board/cvitek/Kconfig b/u-boot-2021.10/board/cvitek/Kconfig index f1ca1ce3b..bdef02e43 100644 --- a/u-boot-2021.10/board/cvitek/Kconfig +++ b/u-boot-2021.10/board/cvitek/Kconfig @@ -24,7 +24,6 @@ config TARGET_CVITEK_CV181X config TARGET_CVITEK_CV180X bool "Support CVITEK CV180X" select TARGET_CVITEK - endchoice source "board/cvitek/cv1835/Kconfig" diff --git a/u-boot-2021.10/board/cvitek/cv180x/board.c b/u-boot-2021.10/board/cvitek/cv180x/board.c index fc70cace5..bfd1061b1 100644 --- a/u-boot-2021.10/board/cvitek/cv180x/board.c +++ b/u-boot-2021.10/board/cvitek/cv180x/board.c @@ -157,8 +157,8 @@ void pinmux_config(int io_type) #include "../cvi_board_init.c" -#if defined(CONFIG_PHY_CVITEK_CV182XA) -static void cv182xa_ephy_id_init(void) +#if defined(CONFIG_PHY_CVITEK) +static void cv180x_ephy_id_init(void) { // set rg_ephy_apb_rw_sel 0x0804@[0]=1/APB by using APB interface mmio_write_32(0x03009804, 0x0001); @@ -169,6 +169,23 @@ static void cv182xa_ephy_id_init(void) // Release 0x0800[2]=1/dig_rst_n, Let mii_reg can be accessabile mmio_write_32(0x03009800, 0x0904); + // ANA INIT (PD/EN), switch to MII-page5 + mmio_write_32(0x0300907c, 0x0500); + // Release ANA_PD p5.0x10@[13:8] = 6'b001100 + mmio_write_32(0x03009040, 0x0c00); + // Release ANA_EN p5.0x10@[7:0] = 8'b01111110 + mmio_write_32(0x03009040, 0x0c7e); + + // Wait PLL_Lock, Lock_Status p5.0x12@[15] = 1 + //mdelay(1); + + // Release 0x0800[1] = 1/ana_rst_n + mmio_write_32(0x03009800, 0x0906); + + // ANA INIT + // @Switch to MII-page5 + mmio_write_32(0x0300907c, 0x0500); + // PHY_ID mmio_write_32(0x03009008, 0x0043); mmio_write_32(0x0300900c, 0x5649); @@ -176,6 +193,17 @@ static void cv182xa_ephy_id_init(void) // switch to MDIO control by ETH_MAC mmio_write_32(0x03009804, 0x0000); } + +static void cv180x_ephy_led_pinmux(void) +{ + // LED PAD MUX + mmio_write_32(0x0300109c, 0x05); + mmio_write_32(0x030010a0, 0x05); + //(SD1_CLK selphy) + mmio_write_32(0x050270b0, 0x11111111); + //(SD1_CMD selphy) + mmio_write_32(0x050270b4, 0x11111111); +} #endif int board_init(void) @@ -186,8 +214,9 @@ int board_init(void) // Save uboot start time. time is from boot0.h mmio_write_16(TIME_RECORDS_FIELD_UBOOT_START, start_time); -#if defined(CONFIG_PHY_CVITEK_CV182XA) /* config cvitek cr181x/cr180x eth internal phy on ASIC board */ - cv182xa_ephy_id_init(); +#if defined(CONFIG_PHY_CVITEK) /* config cvitek cv180x eth internal phy on ASIC board */ + cv180x_ephy_id_init(); + cv180x_ephy_led_pinmux(); #endif #if defined(CONFIG_NAND_SUPPORT) diff --git a/u-boot-2021.10/board/cvitek/cv180x/cv180x_reg.h b/u-boot-2021.10/board/cvitek/cv180x/cv180x_reg.h index b6fe5599a..83abc121a 100644 --- a/u-boot-2021.10/board/cvitek/cv180x/cv180x_reg.h +++ b/u-boot-2021.10/board/cvitek/cv180x/cv180x_reg.h @@ -16,7 +16,7 @@ */ #define GP_REG0 (TOP_BASE + 0x80) #define GP_REG1 (TOP_BASE + 0x84) -#define GP_REG2 (TOP_BASE + 0x88 +#define GP_REG2 (TOP_BASE + 0x88) #define GP_REG3 (TOP_BASE + 0x8C) #define GP_REG4 (TOP_BASE + 0x90) #define GP_REG5 (TOP_BASE + 0x94) diff --git a/u-boot-2021.10/board/cvitek/cv181x/board.c b/u-boot-2021.10/board/cvitek/cv181x/board.c index 886b23eee..f3ad35577 100644 --- a/u-boot-2021.10/board/cvitek/cv181x/board.c +++ b/u-boot-2021.10/board/cvitek/cv181x/board.c @@ -123,6 +123,30 @@ void pinmux_config(int io_type) PINMUX_CONFIG(EMMC_CMD, SPINAND_MISO); PINMUX_CONFIG(EMMC_DAT1, SPINAND_CS); break; + case PINMUX_DSI: + PINMUX_CONFIG(PAD_MIPI_TXM0, XGPIOC_12); + PINMUX_CONFIG(PAD_MIPI_TXP0, XGPIOC_13); + PINMUX_CONFIG(PAD_MIPI_TXM1, XGPIOC_14); + PINMUX_CONFIG(PAD_MIPI_TXP1, XGPIOC_15); + PINMUX_CONFIG(PAD_MIPI_TXM2, XGPIOC_16); + PINMUX_CONFIG(PAD_MIPI_TXP2, XGPIOC_17); + PINMUX_CONFIG(PAD_MIPI_TXM3, XGPIOC_20); + PINMUX_CONFIG(PAD_MIPI_TXP3, XGPIOC_21); + PINMUX_CONFIG(PAD_MIPI_TXM4, XGPIOC_18); + PINMUX_CONFIG(PAD_MIPI_TXP4, XGPIOC_19); + break; + case PINMUX_LVDS: + PINMUX_CONFIG(PAD_MIPI_TXM0, XGPIOC_12); + PINMUX_CONFIG(PAD_MIPI_TXP0, XGPIOC_13); + PINMUX_CONFIG(PAD_MIPI_TXM1, XGPIOC_14); + PINMUX_CONFIG(PAD_MIPI_TXP1, XGPIOC_15); + PINMUX_CONFIG(PAD_MIPI_TXM2, XGPIOC_16); + PINMUX_CONFIG(PAD_MIPI_TXP2, XGPIOC_17); + PINMUX_CONFIG(PAD_MIPI_TXM3, XGPIOC_20); + PINMUX_CONFIG(PAD_MIPI_TXP3, XGPIOC_21); + PINMUX_CONFIG(PAD_MIPI_TXM4, XGPIOC_18); + PINMUX_CONFIG(PAD_MIPI_TXP4, XGPIOC_19); + break; default: break; } @@ -130,8 +154,8 @@ void pinmux_config(int io_type) #include "../cvi_board_init.c" -#if defined(CONFIG_PHY_CVITEK_CV182XA) /* config cvitek cv182xa eth internal phy on ASIC board */ -static void cv182xa_ephy_id_init(void) +#if defined(CONFIG_PHY_CVITEK) /* config cvitek cv181x eth internal phy on ASIC board */ +static void cv181x_ephy_id_init(void) { // set rg_ephy_apb_rw_sel 0x0804@[0]=1/APB by using APB interface mmio_write_32(0x03009804, 0x0001); @@ -142,6 +166,23 @@ static void cv182xa_ephy_id_init(void) // Release 0x0800[2]=1/dig_rst_n, Let mii_reg can be accessabile mmio_write_32(0x03009800, 0x0904); + // ANA INIT (PD/EN), switch to MII-page5 + mmio_write_32(0x0300907c, 0x0500); + // Release ANA_PD p5.0x10@[13:8] = 6'b001100 + mmio_write_32(0x03009040, 0x0c00); + // Release ANA_EN p5.0x10@[7:0] = 8'b01111110 + mmio_write_32(0x03009040, 0x0c7e); + + // Wait PLL_Lock, Lock_Status p5.0x12@[15] = 1 + //mdelay(1); + + // Release 0x0800[1] = 1/ana_rst_n + mmio_write_32(0x03009800, 0x0906); + + // ANA INIT + // @Switch to MII-page5 + mmio_write_32(0x0300907c, 0x0500); + // PHY_ID mmio_write_32(0x03009008, 0x0043); mmio_write_32(0x0300900c, 0x5649); @@ -149,6 +190,17 @@ static void cv182xa_ephy_id_init(void) // switch to MDIO control by ETH_MAC mmio_write_32(0x03009804, 0x0000); } + +static void cv181x_ephy_led_pinmux(void) +{ + // LED PAD MUX + mmio_write_32(0x030010e0, 0x05); + mmio_write_32(0x030010e4, 0x05); + //(SD1_CLK selphy) + mmio_write_32(0x050270b0, 0x11111111); + //(SD1_CMD selphy) + mmio_write_32(0x050270b4, 0x11111111); +} #endif void cpu_pwr_ctrl(void) @@ -162,16 +214,19 @@ void cpu_pwr_ctrl(void) int board_init(void) { +#ifndef CONFIG_TARGET_CVITEK_CV181X_FPGA extern volatile uint32_t BOOT0_START_TIME; uint16_t start_time = DIV_ROUND_UP(BOOT0_START_TIME, SYS_COUNTER_FREQ_IN_SECOND / 1000); // Save uboot start time. time is from boot0.h mmio_write_16(TIME_RECORDS_FIELD_UBOOT_START, start_time); +#endif cpu_pwr_ctrl(); -#if defined(CONFIG_PHY_CVITEK_CV182XA) /* config cvitek cv182xa eth internal phy on ASIC board */ - cv182xa_ephy_id_init(); +#if defined(CONFIG_PHY_CVITEK) /* config cvitek cv181x eth internal phy on ASIC board */ + cv181x_ephy_id_init(); + cv181x_ephy_led_pinmux(); #endif #if defined(CONFIG_NAND_SUPPORT) @@ -180,6 +235,11 @@ int board_init(void) pinmux_config(PINMUX_SPI_NOR); #elif defined(CONFIG_EMMC_SUPPORT) pinmux_config(PINMUX_EMMC); +#endif +#ifdef CONFIG_DISPLAY_CVITEK_MIPI + pinmux_config(PINMUX_DSI); +#elif defined(CONFIG_DISPLAY_CVITEK_LVDS) + pinmux_config(PINMUX_LVDS); #endif pinmux_config(PINMUX_SDIO1); cvi_board_init(); diff --git a/u-boot-2021.10/board/cvitek/cv181x/cv181x_reg.h b/u-boot-2021.10/board/cvitek/cv181x/cv181x_reg.h index 3d257030e..53f7aeb60 100644 --- a/u-boot-2021.10/board/cvitek/cv181x/cv181x_reg.h +++ b/u-boot-2021.10/board/cvitek/cv181x/cv181x_reg.h @@ -16,7 +16,7 @@ */ #define GP_REG0 (TOP_BASE + 0x80) #define GP_REG1 (TOP_BASE + 0x84) -#define GP_REG2 (TOP_BASE + 0x88 +#define GP_REG2 (TOP_BASE + 0x88) #define GP_REG3 (TOP_BASE + 0x8C) #define GP_REG4 (TOP_BASE + 0x90) #define GP_REG5 (TOP_BASE + 0x94) diff --git a/u-boot-2021.10/cmd/Kconfig b/u-boot-2021.10/cmd/Kconfig index 8e5aa96bb..152a86f8a 100644 --- a/u-boot-2021.10/cmd/Kconfig +++ b/u-boot-2021.10/cmd/Kconfig @@ -979,6 +979,15 @@ config CMD_GPT_RENAME partitions via the 'gpt swap' command or to rename single partitions via the 'rename' command. +config BOOTLOGO + bool "Show bootlogo" + select CMD_CVI_JPEG + help + Show bootlogo when uboot is booting. + This provides a way to show bootlogo which is saved in MISC partition. + When enable this command it will add a new environment variable showlogo + and will add the showlogo to the beginning of bootcmd + config CMD_IDE bool "ide - Support for IDE drivers" select IDE @@ -2389,6 +2398,26 @@ config CMD_UBIFS help UBIFS is a file system for flash devices which works on top of UBI. +config CMD_CVI_VO + bool "VO command supports mars" + depends on VIDEO_CVITEK + help + Support for the cv1835 vo interface. + This includes controls of vo interface/timing, video layer. + startvo: start interface. + stopvo: stop interface. + startvl: start video layer reading from ddr. + stopvl: stop video layer. + setvobg: set bgcolor. + +config CMD_CVI_JPEG + bool "CVI JPEG decoder" + help + Support for the jpeg decorder + uboot will check the jpeg file, alloc buffer + and decode jpg file to yuv format to the + destination address + config CMD_CVI_UPDATE bool "cvitek update command" default y diff --git a/u-boot-2021.10/cmd/Makefile b/u-boot-2021.10/cmd/Makefile index b75587b55..fa9ad76f9 100644 --- a/u-boot-2021.10/cmd/Makefile +++ b/u-boot-2021.10/cmd/Makefile @@ -68,6 +68,8 @@ obj-$(CONFIG_CMD_FAT) += fat.o obj-$(CONFIG_CMD_FDT) += fdt.o obj-$(CONFIG_CMD_SQUASHFS) += sqfs.o obj-$(CONFIG_CMD_FLASH) += flash.o +obj-$(CONFIG_CMD_CVI_JPEG) += cvi_jpeg.o +obj-$(CONFIG_CMD_CVI_VO) += cvi_vo.o obj-$(CONFIG_CMD_CVI_UPDATE) += cvi_update.o obj-$(CONFIG_CMD_CVI_UPDATE) += cvi_utask.o obj-$(CONFIG_NAND_SUPPORT) += cvi_sd_update.o cvi_sd_update_spinand_v3.o diff --git a/u-boot-2021.10/cmd/cvi_jpeg.c b/u-boot-2021.10/cmd/cvi_jpeg.c new file mode 100644 index 000000000..6cfe1b98a --- /dev/null +++ b/u-boot-2021.10/cmd/cvi_jpeg.c @@ -0,0 +1,50 @@ +#include +#include +#include + +extern int jpeg_decoder(void *bs_addr, void *yuv_addr, int size); +extern int get_jpeg_size(int *width_addr, int *height_addr); + +static int do_cvi_jpeg_dec(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) +{ + char *bs_addr = NULL; + char *yuv_addr = NULL; + int size = 0; + + + if (argc != 4) { + printf("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + bs_addr = (char *)simple_strtol(argv[1], NULL, 16); + + if (!bs_addr) { + printf("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + yuv_addr = (char *)simple_strtol(argv[2], NULL, 16); + + if (!yuv_addr) { + printf("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + size = (int)simple_strtol(argv[3], NULL, 16); + + if (!size) { + printf("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + printf("\nstart jpeg dec task!, bs_addr %p, yuv_addr %p, size %d\n", bs_addr, yuv_addr, size); + + jpeg_decoder(bs_addr, yuv_addr, size); + get_jpeg_size((int *)(bs_addr + size - 8), (int *)(bs_addr + size - 4)); + + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD(cvi_jpeg_dec, 4, 0, do_cvi_jpeg_dec, "Jpeg decoder ", "\n" +); diff --git a/u-boot-2021.10/cmd/cvi_update.c b/u-boot-2021.10/cmd/cvi_update.c index fe4bcfb4f..8a427e4a5 100644 --- a/u-boot-2021.10/cmd/cvi_update.c +++ b/u-boot-2021.10/cmd/cvi_update.c @@ -38,12 +38,15 @@ uint32_t update_magic; enum chunk_type_e { dont_care = 0, check_crc }; enum storage_type_e { sd_dl = 0, usb_dl }; +#if (!defined CONFIG_TARGET_CVITEK_CV181X_FPGA) && (!defined CONFIG_TARGET_CVITEK_ATHENA2_FPGA) && \ + (!defined ATHENA2_FPGA_PALLDIUM_ENV) static uint32_t bcd2hex4(uint32_t bcd) { return ((bcd) & 0x0f) + (((bcd) >> 4) & 0xf0) + (((bcd) >> 8) & 0xf00) + (((bcd) >> 12) & 0xf000); } static int _storage_update(enum storage_type_e type); +#endif int _prgImage(char *file, uint32_t chunk_header_size, char *file_name) { @@ -118,6 +121,8 @@ int _prgImage(char *file, uint32_t chunk_header_size, char *file_name) return size; } +#if (!defined CONFIG_TARGET_CVITEK_CV181X_FPGA) && (!defined CONFIG_TARGET_CVITEK_ATHENA2_FPGA) && \ + (!defined ATHENA2_FPGA_PALLDIUM_ENV) static int _checkHeader(char *file, char strStorage[10]) { char *magic = (void *)HEADER_ADDR; @@ -174,15 +179,20 @@ static int _storage_update(enum storage_type_e type) int ret = 0; char cmd[255] = { '\0' }; char strStorage[10] = { '\0' }; + uint8_t sd_index = 0; if (type == sd_dl) { printf("Start SD downloading...\n"); // Consider SD card with MBR as default #if defined(CONFIG_NAND_SUPPORT) || defined(CONFIG_SPI_FLASH) strlcpy(strStorage, "mmc 0:1", 9); + sd_index = 0; #elif defined(CONFIG_EMMC_SUPPORT) + sd_index = 1; strlcpy(strStorage, "mmc 1:1", 9); #endif + snprintf(cmd, 255, "mmc dev %u:1 SD_HS", sd_index); + run_command(cmd, 0); snprintf(cmd, 255, "fatload %s %p fip.bin;", strStorage, (void *)HEADER_ADDR); ret = run_command(cmd, 0); @@ -191,9 +201,13 @@ static int _storage_update(enum storage_type_e type) printf("** Trying use partition 0 (without MBR) **\n"); #if defined(CONFIG_NAND_SUPPORT) || defined(CONFIG_SPI_FLASH) strlcpy(strStorage, "mmc 0:0", 9); + sd_index = 0; #elif defined(CONFIG_EMMC_SUPPORT) + sd_index = 1; strlcpy(strStorage, "mmc 1:0", 9); #endif + snprintf(cmd, 255, "mmc dev %u:0 SD_HS", sd_index); + run_command(cmd, 0); snprintf(cmd, 255, "fatload %s %p fip.bin;", strStorage, (void *)HEADER_ADDR); ret = run_command(cmd, 0); @@ -218,11 +232,15 @@ static int _storage_update(enum storage_type_e type) run_command(cmd, 0); snprintf(cmd, 255, "mmc write %p 0x800 0x800;;", (void *)HEADER_ADDR); - run_command(cmd, 0); + ret = run_command(cmd, 0); printf("Program fip.bin done\n"); // Switch to user partition run_command("mmc dev 0 0", 0); #endif + if (ret == 0) + SET_DL_COMPLETE(); + else + return ret; } for (int i = 1; i < ARRAY_SIZE(imgs); i++) { snprintf(cmd, 255, "fatload %s %p %s 0x%x 0;", strStorage, @@ -236,8 +254,6 @@ static int _storage_update(enum storage_type_e type) if (_checkHeader(imgs[i], strStorage)) continue; } - if (ret == 0) - SET_DL_COMPLETE(); return 0; } @@ -288,10 +304,14 @@ static int _usb_update(uint32_t usb_pid) }; return 0; } +#endif static int do_cvi_update(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { + +#if (!defined CONFIG_TARGET_CVITEK_CV181X_FPGA) && (!defined CONFIG_TARGET_CVITEK_ATHENA2_FPGA) && \ + (!defined ATHENA2_FPGA_PALLDIUM_ENV) int ret = 1; uint32_t usb_pid = 0; @@ -311,6 +331,9 @@ static int do_cvi_update(struct cmd_tbl *cmdtp, int flag, int argc, } return ret; +#else + return 0; +#endif } U_BOOT_CMD( diff --git a/u-boot-2021.10/cmd/cvi_vo.c b/u-boot-2021.10/cmd/cvi_vo.c new file mode 100644 index 000000000..d71e08f7b --- /dev/null +++ b/u-boot-2021.10/cmd/cvi_vo.c @@ -0,0 +1,408 @@ +/* + * Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include "../drivers/video/cvitek/scaler.h" +#include "../drivers/video/cvitek/dsi_phy.h" + +#include + +#include + +#define PANLE_ADAPTIVITY 0 + +enum sclr_vo_intf intf_type = SCLR_VO_INTF_MIPI; + +static int lvds_panel_init(struct cvi_lvds_cfg_s *lvds_cfg) +{ + int ret = 0; +#ifdef CONFIG_DISPLAY_CVITEK_LVDS + ret = lvds_init(lvds_cfg); +#endif + return ret; +} + +int i80_init(int devno, const struct _VO_I80_INSTR_S *cmds, int size) +{ + int ret = 0; + unsigned int sw_cmd; + + for (int i = 0; i < size; i++) { + sw_cmd = (i80_ctrl[cmds[i].data_type] << 8) | cmds[i].data; + i80_set_cmd(sw_cmd); + + if (cmds[i].delay) + mdelay(cmds[i].delay); + } + // pull high i80-lane + i80_set_cmd(0xffff); + i80_set_cmd(0x2ffff); + + return ret; +} + +static int dsi_init(int devno, const struct dsc_instr *cmds, int size) +{ + int ret; + + for (int i = 0; i < size; i++) { + const struct dsc_instr *instr = &cmds[i]; + struct cmd_info_s cmd_info = { + .devno = devno, + .cmd_size = instr->size, + .data_type = instr->data_type, + .cmd = (void *)instr->data + }; + + ret = mipi_tx_set_cmd(&cmd_info); + if (instr->delay) + mdelay(instr->delay); + + if (ret) { + printf("dsi init failed at %d instr.\n", i); + return ret; + } + } + return ret; +} + +#if PANLE_ADAPTIVITY +static int dsi_get_panel_id(int devno, unsigned int *id) +{ + int ret = 0; + unsigned char param[3] = {0xDA, 0xDB, 0xDC}; + unsigned char buf[4]; + + for (int i = 0; i < 3; i++) { + struct get_cmd_info_s get_cmd_info = { + .devno = devno, + .data_type = 0x06, + .data_param = param[i], + .get_data_size = 0x01, + .get_data = buf + }; + memset(buf, 0, sizeof(buf)); + + ret = mipi_tx_get_cmd(&get_cmd_info); + if (ret < 0) { + printf("dsi get panel id fail.\n"); + return ret; + } + + *id |= (buf[0] << (i * 8)); + } + + return ret; +} + +static void dsi_panel_init_adaptivity(void) +{ + unsigned int panelid = 0; + const struct combo_dev_cfg_s *dev_cfg = NULL; + const struct hs_settle_s *hs_timing_cfg = NULL; + const struct dsc_instr *dsi_init_cmds = NULL; + int size = 0; + + //use one type panel's cfg to init + mipi_tx_set_combo_dev_cfg((struct combo_dev_cfg_s *)&dev_cfg_hx8394_720x1280); + + dsi_get_panel_id(0, &panelid); + debug("[DBG] dsi_get_panel_id: 0x%X\n", panelid); + + switch (panelid) { + case 0xF9483: + dev_cfg = &dev_cfg_hx8394_720x1280; + hs_timing_cfg = &hs_timing_cfg_hx8394_720x1280; + dsi_init_cmds = dsi_init_cmds_hx8394_720x1280; + size = ARRAY_SIZE(dsi_init_cmds_hx8394_720x1280); + break; + + case 0xAA: //modify it before use + dev_cfg = &dev_cfg_ili9881c_720x1280; + hs_timing_cfg = &hs_timing_cfg_ili9881c_720x1280; + dsi_init_cmds = dsi_init_cmds_ili9881c_720x1280; + size = ARRAY_SIZE(dsi_init_cmds_ili9881c_720x1280); + break; + + case 0xBB: //modify it before use + dev_cfg = &dev_cfg_jd9366ab_800x1280; + hs_timing_cfg = &hs_timing_cfg_jd9366ab_800x1280; + dsi_init_cmds = dsi_init_cmds_jd9366ab_800x1280; + size = ARRAY_SIZE(dsi_init_cmds_jd9366ab_800x1280); + break; + + default: + break; + } + + if (panelid != 0xF9483) + mipi_tx_set_combo_dev_cfg(dev_cfg); + dsi_init(0, dsi_init_cmds, size); + dphy_set_hs_settle(hs_timing_cfg->prepare, hs_timing_cfg->zero, hs_timing_cfg->trail); +} +#else +static void dsi_panel_init(void) +{ + u8 prepare = panel_desc.hs_timing_cfg->prepare; + u8 zero = panel_desc.hs_timing_cfg->zero; + u8 trail = panel_desc.hs_timing_cfg->trail; + + debug("Init panel %s\n", panel_desc.panel_name); + mipi_tx_set_combo_dev_cfg(panel_desc.dev_cfg); + dsi_init(0, panel_desc.dsi_init_cmds, panel_desc.dsi_init_cmds_size); + dphy_set_hs_settle(prepare, zero, trail); +} +#endif + +/***************************************************/ +static int do_startvo(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) +{ + struct udevice *udev; + int dev, intf, timing; + char *endp; + + if (argc < 4) + return CMD_RET_USAGE; + + dev = simple_strtoul(argv[1], &endp, 10); + if (*argv[1] == 0 || *endp != 0) + return CMD_RET_USAGE; + intf = simple_strtoul(argv[2], &endp, 10); + if (*argv[2] == 0 || *endp != 0) + return CMD_RET_USAGE; + timing = simple_strtoul(argv[3], &endp, 10); + if (*argv[3] == 0 || *endp != 0) + return CMD_RET_USAGE; + uclass_get_device(UCLASS_VIDEO, 0, &udev); + + switch (intf) { + case VO_INTF_MIPI: { + mipi_tx_set_mode(0); + #if PANLE_ADAPTIVITY + dsi_panel_init_adaptivity(); + #else + dsi_panel_init(); + #endif + mipi_tx_set_mode(1); + } + break; + + case VO_INTF_I80: + intf_type = SCLR_VO_INTF_I80; + i80_set_combo_dev_cfg(panel_desc.i80_cfg); + i80_set_sw_mode(1); + i80_init(0, panel_desc.i80_init_cmds, panel_desc.i80_init_cmds_size); + i80_set_sw_mode(0); + i80_sclr_intr_clr();//intr_status should be clear, otherwise kernel will get stuck + break; + + case VO_INTF_LCD_18BIT: + case VO_INTF_LCD_24BIT: + case VO_INTF_LCD_30BIT: + intf_type = SCLR_VO_INTF_LVDS; + lvds_panel_init(panel_desc.lvds_cfg); + break; + + default: + break; + } + + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD(startvo + , 4, 0, do_startvo + , "open vo device with a certain interface." + , " - startvo [dev intftype sync]" +); + +/***************************************************/ +static int do_stopvo(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) +{ + int dev; + char *endp; + + if (argc < 2) + return CMD_RET_USAGE; + + dev = simple_strtoul(argv[1], &endp, 10); + if (*argv[1] == 0 || *endp != 0) + return CMD_RET_USAGE; + + sclr_disp_tgen_enable(false); + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD(stopvo + , 2, 0, do_stopvo + , "close interface of vo device." + , " - stopvo [dev]" +); + +/***************************************************/ +static int do_startvl(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) +{ + int layer, stride; + struct sclr_rect rect; + struct sclr_disp_cfg *cfg; + struct sclr_disp_timing *timing; + u64 addr_in, addr_out; + char *endp; + int size_offset, align; + + if (argc < 6) + return CMD_RET_USAGE; + + layer = simple_strtoul(argv[1], &endp, 10); + if (*argv[1] == 0 || *endp != 0) + return CMD_RET_USAGE; + addr_in = simple_strtoul(argv[2], &endp, 16); + if (*argv[2] == 0 || *endp != 0) + return CMD_RET_USAGE; + addr_out = simple_strtoul(argv[3], &endp, 16); + if (*argv[3] == 0 || *endp != 0) + return CMD_RET_USAGE; + size_offset = simple_strtoul(argv[4], &endp, 16) - 8; + if (*argv[4] == 0 || *endp != 0) + return CMD_RET_USAGE; + align = simple_strtoul(argv[5], &endp, 10); + if (*argv[5] == 0 || *endp != 0) + return CMD_RET_USAGE; + + timing = sclr_disp_get_timing(); + + rect.w = *(int *)(addr_in + size_offset); + rect.h = *(int *)(addr_in + size_offset + 4); + stride = ALIGN(rect.w, align); + + rect.y = (timing->vmde_end - timing->vmde_start + 1 - rect.h) / 2; + rect.x = (timing->hmde_end - timing->hmde_start + 1 - rect.w) / 2; + + sclr_disp_set_rect(rect); + cfg = sclr_disp_get_cfg(); + + if (intf_type == SCLR_VO_INTF_MIPI || intf_type == SCLR_VO_INTF_LVDS) { + cfg->fmt = SCL_FMT_YUV420; + cfg->in_csc = SCL_CSC_601_LIMIT_YUV2RGB; + cfg->mem.width = rect.w; + cfg->mem.height = rect.h; + cfg->mem.pitch_y = ALIGN(stride, 32); + cfg->mem.pitch_c = ALIGN(stride >> 1, 32); + } else if (intf_type == SCLR_VO_INTF_I80) { + unsigned char *in = (unsigned char *)(addr_in); + unsigned char *out = (unsigned char *)(addr_out); + unsigned short w = (*(in + 25) << 24) | (*(in + 24) << 16) | (*(in + 23) << 8) | *(in + 22); + unsigned short h = (*(in + 21) << 24) | (*(in + 20) << 16) | (*(in + 19) << 8) | *(in + 18); + + debug("%c, %c, w:%d, h:%d\n", *in, *(in + 1), w, h); + debug("in:%p, out:%p\n", in, out); + + if (*(in) == 'B' && *(in + 1) == 'M' && w == rect.w && h == rect.h) { + debug("this is a bmp && %d*%d\n", h, w); + in = in + 54; //Remove the bmp header + } else { + debug("no bmp or rect not match, display white!\n"); + in = in + 54; + memset(in + 54, 0xFF, rect.w * rect.h * 3); + } + i80_package_frame(in, out, stride, 3, rect.w, rect.h); + flush_cache(addr_out, ALIGN(((rect.w * 2 + 1) * 3), align) * rect.h); + cfg->fmt = SCL_FMT_BGR_PACKED; + cfg->in_csc = SCL_CSC_NONE; + cfg->mem.width = rect.w * 2 + 1; + cfg->mem.height = rect.h; + cfg->mem.pitch_y = ALIGN((cfg->mem.width * 3), align); + cfg->mem.pitch_c = 0; + } + + cfg->mem.start_x = 0; + cfg->mem.start_y = 0; + cfg->mem.addr0 = addr_out; + cfg->mem.addr1 = ALIGN(cfg->mem.addr0 + cfg->mem.pitch_y * ALIGN(((rect.h + 1) & ~(BIT(0))), 16), 0x1000); + cfg->mem.addr2 = ALIGN(cfg->mem.addr1 + cfg->mem.pitch_c * ALIGN(((rect.h + 1) >> 1), 16), 0x1000); + + sclr_disp_set_cfg(cfg); + + if (intf_type == SCLR_VO_INTF_I80) { + sclr_disp_reg_force_up(); + i80_set_run(); + } + + sclr_disp_enable_window_bgcolor(false); + debug("\nstart vl(%d) addr_in(%#llx) addr_out(%#llx) stride(%d) rect(%d %d %d %d)!\n" + , layer, addr_in, addr_out, stride, rect.x, rect.y, rect.w, rect.h); + debug("\nstart vl cfg->mem.addr(%#llx-%#llx-%#llx) pitch_y:%d pitch_c:%d.\n" + , cfg->mem.addr0, cfg->mem.addr1, cfg->mem.addr2, cfg->mem.pitch_y, cfg->mem.pitch_c); + + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD(startvl + , 6, 0, do_startvl + , "open video layer of the vo" + , "- startvl [layer address_in address_out img_size_addr_offset alignment]" +); + +/***************************************************/ +static int do_stopvl(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) +{ + int layer; + char *endp; + + if (argc < 2) + return CMD_RET_USAGE; + + layer = simple_strtoul(argv[1], &endp, 10); + if (*argv[1] == 0 || *endp != 0) + return CMD_RET_USAGE; + + sclr_disp_enable_window_bgcolor(true); + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD(stopvl + , 2, 0, do_stopvl + , "close video layer of the vo" + , "- stopvl [layer]" +); + +/***************************************************/ +static int do_setvobg(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) +{ + int dev; + u32 bgcolor; + u16 r, g, b; + char *endp; + + if (argc < 3) + return CMD_RET_USAGE; + + dev = simple_strtoul(argv[1], &endp, 10); + if (*argv[1] == 0 || *endp != 0) + return CMD_RET_USAGE; + bgcolor = simple_strtoul(argv[2], &endp, 16); + if (*argv[2] == 0 || *endp != 0) + return CMD_RET_USAGE; + + r = (bgcolor >> 20) & 0x3ff; + g = (bgcolor >> 10) & 0x3ff; + b = bgcolor & 0x3ff; + sclr_disp_set_frame_bgcolor(r, g, b); + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD(setvobg + , 3, 0, do_setvobg + , "set vo background color" + , " - setvobg [dev bgcolor]" +); + diff --git a/u-boot-2021.10/cmd/efuse.c b/u-boot-2021.10/cmd/efuse.c index c9c3baf2f..921511975 100644 --- a/u-boot-2021.10/cmd/efuse.c +++ b/u-boot-2021.10/cmd/efuse.c @@ -8,6 +8,8 @@ #include #include +#ifdef __riscv + #define EFUSE_DEBUG 0 #define _cc_trace(fmt, ...) __trace("", __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__) @@ -278,7 +280,14 @@ static struct _CVI_EFUSE_USER_S { #define CVI_EFUSE_LOCK_ADDR 0xF8 #define CVI_EFUSE_SECURE_CONF_ADDR 0xA0 -#define CVI_EFUSE_SCS_ENABLE_SHIFT 0 +#define CVI_EFUSE_SCS_ENABLE_SHIFT 0 +// for secure boot sign +#define CVI_EFUSE_TEE_SCS_ENABLE_SHIFT 2 +#define CVI_EFUSE_ROOT_PUBLIC_KEY_SELECTION_SHIFT 20 +// for secure boot encryption +#define CVI_EFUSE_BOOT_LOADER_ENCRYPTION 6 +#define CVI_EFUSE_LDR_KEY_SELECTION_SHIFT 23 + CVI_S32 CVI_EFUSE_GetSize(enum CVI_EFUSE_AREA_E area, CVI_U32 *size) { @@ -417,9 +426,17 @@ CVI_S32 CVI_EFUSE_Write(enum CVI_EFUSE_AREA_E area, const CVI_U8 *buf, CVI_U32 b return CVI_SUCCESS; } -CVI_S32 CVI_EFUSE_EnableSecureBoot(void) +CVI_S32 CVI_EFUSE_EnableSecureBoot(uint32_t sel) { - CVI_U32 value = 0x3 << CVI_EFUSE_SCS_ENABLE_SHIFT; + CVI_U32 value = 0; + + value |= 0x3 << CVI_EFUSE_TEE_SCS_ENABLE_SHIFT; + value |= 0x4 << CVI_EFUSE_ROOT_PUBLIC_KEY_SELECTION_SHIFT; + + if (sel != 1) { + value |= 0x3 << CVI_EFUSE_BOOT_LOADER_ENCRYPTION; + value |= 0x4 << CVI_EFUSE_LDR_KEY_SELECTION_SHIFT; + } return _CVI_EFUSE_Write(CVI_EFUSE_SECURE_CONF_ADDR, &value, sizeof(value)); } @@ -434,8 +451,49 @@ CVI_S32 CVI_EFUSE_IsSecureBootEnabled(void) if (ret < 0) return ret; - value &= 0x3 << CVI_EFUSE_SCS_ENABLE_SHIFT; - return !!value; + ret = (value & (0x3 << CVI_EFUSE_TEE_SCS_ENABLE_SHIFT)) >> CVI_EFUSE_TEE_SCS_ENABLE_SHIFT; + if (ret == 0) { + printf("Secure Boot is disable\n"); + return 0; + } + + ret = (value & (0x7 << CVI_EFUSE_ROOT_PUBLIC_KEY_SELECTION_SHIFT)) >> CVI_EFUSE_ROOT_PUBLIC_KEY_SELECTION_SHIFT; + switch (ret) { + case 0: + printf("Secure Boot sign is enable, verity with rot_pk_a_hash\n"); + break; + case 1: + printf("Secure Boot sign is enable, verity with rot_pk_b_hash\n"); + break; + case 2: + printf("Secure Boot sign is enable, verity with rot_pk_c_hash\n"); + break; + default: + printf("Secure Boot sign is enable, verity with efuse KPUB HASH\n"); + break; + } + + ret = (value & (0x3 << CVI_EFUSE_BOOT_LOADER_ENCRYPTION)) >> CVI_EFUSE_BOOT_LOADER_ENCRYPTION; + if (ret == 0) + return 0; + + ret = (value & (0x7 << CVI_EFUSE_LDR_KEY_SELECTION_SHIFT)) >> CVI_EFUSE_LDR_KEY_SELECTION_SHIFT; + switch (ret) { + case 0: + printf("Secure Boot encryption is enable, decrypt with ldr_ek_a\n"); + break; + case 1: + printf("Secure Boot encryption is enable, decrypt with ldr_ek_b\n"); + break; + case 2: + printf("Secure Boot encryption is enable, decrypt with ldr_ek_c\n"); + break; + default: + printf("Secure Boot encryption is enable, decrypt with efuse LDR DES KEY\n"); + break; + } + + return 0; } CVI_S32 CVI_EFUSE_Lock(enum CVI_EFUSE_LOCK_E lock) @@ -576,14 +634,13 @@ static int do_efuser(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv ret = CVI_EFUSE_IsLocked(idx); printf("%s is %s locked\n", efuse_index[idx], ret ? "" : "not"); return 0; + } else if (idx == CVI_EFUSE_SECUREBOOT) { + ret = CVI_EFUSE_IsSecureBootEnabled(); + return 0; } else if (idx < CVI_EFUSE_LOCK_WRITE_LAST) { ret = CVI_EFUSE_IsWriteLocked(idx); printf("%s is %s write_locked\n", efuse_index[idx], ret ? "" : "not"); return 0; - } else if (idx == CVI_EFUSE_SECUREBOOT) { - ret = CVI_EFUSE_IsSecureBootEnabled(); - printf("Secure Boot is %s\n", ret ? "enabled" : "disabled"); - return 0; } return CMD_RET_FAILURE; @@ -640,6 +697,15 @@ static int do_efusew(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv printf("%s is locked\n", efuse_index[idx]); return 0; + } else if (idx == CVI_EFUSE_SECUREBOOT) { + if (argc != 3) + return CMD_RET_USAGE; + + uint32_t sel = simple_strtoul(argv[2], NULL, 0); + + ret = CVI_EFUSE_EnableSecureBoot(sel); + printf("Enabled Secure Boot is %s\n", ret >= 0 ? "success" : "failed"); + return 0; } else if (idx < CVI_EFUSE_LOCK_WRITE_LAST) { if (CVI_EFUSE_LockWrite(idx) < 0) { printf("Failed to lock write %s\n", efuse_index[idx]); @@ -648,11 +714,6 @@ static int do_efusew(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv printf("%s is locked\n", efuse_index[idx]); return 0; - - } else if (idx == CVI_EFUSE_SECUREBOOT) { - ret = CVI_EFUSE_EnableSecureBoot(); - printf("Enabled Secure Boot is %s\n", ret >= 0 ? "success" : "failed"); - return 0; } return CMD_RET_FAILURE; @@ -708,4 +769,6 @@ U_BOOT_CMD(efusew_word, 9, 1, do_efusew_word, "Write word to efuse", U_BOOT_CMD(efuser_dump, 9, 1, do_efuser_dump, "Read/Dump efuse", "do_efuser_dump\n" - " - args ..."); \ No newline at end of file + " - args ..."); + +#endif diff --git a/u-boot-2021.10/common/autoboot.c b/u-boot-2021.10/common/autoboot.c index eb3dd751e..1589928ea 100644 --- a/u-boot-2021.10/common/autoboot.c +++ b/u-boot-2021.10/common/autoboot.c @@ -486,7 +486,10 @@ void autoboot_command(const char *s) if (lock) prev = disable_ctrlc(1); /* disable Ctrl-C checking */ +#if (!defined CONFIG_TARGET_CVITEK_CV181X_FPGA) && (!defined CONFIG_TARGET_CVITEK_ATHENA2_FPGA) && \ + (!defined ATHENA2_FPGA_PALLDIUM_ENV) board_save_time_record(TIME_RECORDS_FIELD_BOOTCMD_START); +#endif run_command_list(s, -1, 0); if (lock) diff --git a/u-boot-2021.10/common/board_f.c b/u-boot-2021.10/common/board_f.c index 85bcec66e..00dae3f8a 100644 --- a/u-boot-2021.10/common/board_f.c +++ b/u-boot-2021.10/common/board_f.c @@ -368,6 +368,15 @@ static int reserve_ion(void) } #endif +#if (CONFIG_SYS_RESVLOGOSZ != 0) +static int reserve_logo(void) +{ + gd->relocaddr -= CONFIG_SYS_RESVLOGOSZ; + debug("Reserving %dk for bootlogo at %08lx\n", (CONFIG_SYS_RESVLOGOSZ >> 16), gd->relocaddr); + return 0; +} +#endif + #ifdef CONFIG_PRAM /* reserve protected RAM */ static int reserve_pram(void) @@ -918,6 +927,9 @@ static const init_fnc_t init_sequence_f[] = { #if (CONFIG_SYS_RESVIONSZ != 0) reserve_ion, #endif +#if (CONFIG_SYS_RESVLOGOSZ != 0) + reserve_logo, +#endif #ifdef CONFIG_OF_BOARD_FIXUP fix_fdt, diff --git a/u-boot-2021.10/common/image.c b/u-boot-2021.10/common/image.c index 0cad38503..6889153d4 100644 --- a/u-boot-2021.10/common/image.c +++ b/u-boot-2021.10/common/image.c @@ -454,7 +454,11 @@ int image_decomp(int comp, ulong load, ulong image_start, int type, #ifndef USE_HOSTCC // Save decompression start time + +#if (!defined CONFIG_TARGET_CVITEK_CV181X_FPGA) && (!defined CONFIG_TARGET_CVITEK_ATHENA2_FPGA) && \ + (!defined ATHENA2_FPGA_PALLDIUM_ENV) board_save_time_record(TIME_RECORDS_FIELD_DECOMPRESS_KERNEL_START); +#endif start = get_timer(0); #endif diff --git a/u-boot-2021.10/drivers/Makefile b/u-boot-2021.10/drivers/Makefile index fd218c905..53952292e 100644 --- a/u-boot-2021.10/drivers/Makefile +++ b/u-boot-2021.10/drivers/Makefile @@ -32,6 +32,7 @@ obj-$(CONFIG_$(SPL_TPL_)TPM) += tpm/ obj-$(CONFIG_$(SPL_TPL_)ACPI_PMC) += power/acpi_pmc/ obj-$(CONFIG_XEN) += xen/ obj-$(CONFIG_$(SPL_)FPGA) += fpga/ +obj-$(CONFIG_CMD_CVI_JPEG) += jpeg/ ifndef CONFIG_TPL_BUILD ifdef CONFIG_SPL_BUILD @@ -64,7 +65,6 @@ obj-$(CONFIG_OMAP_USB_PHY) += usb/phy/ obj-$(CONFIG_SPL_SATA_SUPPORT) += ata/ scsi/ obj-$(CONFIG_HAVE_BLOCK_DEVICE) += block/ obj-$(CONFIG_SPL_THERMAL) += thermal/ - endif endif diff --git a/u-boot-2021.10/drivers/cvi_usb/utask/cv181x/include/platform_def.h b/u-boot-2021.10/drivers/cvi_usb/utask/cv181x/include/platform_def.h index eef8d15e8..75e62e5c7 100644 --- a/u-boot-2021.10/drivers/cvi_usb/utask/cv181x/include/platform_def.h +++ b/u-boot-2021.10/drivers/cvi_usb/utask/cv181x/include/platform_def.h @@ -15,6 +15,8 @@ #include <../../../board/cvitek/cv181x/cv181x_reg.h> #elif defined(CONFIG_TARGET_CVITEK_CV180X) #include <../../../board/cvitek/cv180x/cv180x_reg.h> +#elif defined(CONFIG_TARGET_CVITEK_ATHENA2) +#include <../../../board/cvitek/athena2/athena2_reg.h> #else #error "use cvi_utask at wrong platform" #endif diff --git a/u-boot-2021.10/drivers/cvi_usb/utask/cv181x/usb_tty.c b/u-boot-2021.10/drivers/cvi_usb/utask/cv181x/usb_tty.c index ed4a641b4..f8c033ee4 100644 --- a/u-boot-2021.10/drivers/cvi_usb/utask/cv181x/usb_tty.c +++ b/u-boot-2021.10/drivers/cvi_usb/utask/cv181x/usb_tty.c @@ -731,9 +731,23 @@ static void bulkOutCmplMain(struct usb_ep *ep, struct usb_request *req) case CVI_USB_S2D: /* INFO("CVI_USB_S2D, addr = 0x%lx, len = 0x%lx\n",dest_addr, msg_s2d->size); */ sendInReq(length, CVI_USB_S2D, bulkCmplEmpty, NULL, 0); + if (dest_addr >= GLOBAL_MEM_START_ADDR) - resetOutReqS2D(dest_addr, msg_s2d->size, - bulkResetOutReq); + { + resetOutReqS2D(dest_addr, msg_s2d->size, bulkResetOutReq); + +#ifdef CONFIG_NAND_SUPPORT + // Erase partition first + if (!strncmp((char *)((uintptr_t)HEADER_ADDR), "CIMG", 4)) { + strlcpy(prevExtra, + (char *)((uintptr_t)HEADER_ADDR + 20), + EXTRA_FLAG_SIZE); + snprintf(cmd, 255, "nand erase.part -y %s", prevExtra); + pr_debug("%s\n", cmd); + run_command(cmd, 0); + } +#endif + } else sramOutReqS2D(dest_addr, msg_s2d->size); return; @@ -779,18 +793,6 @@ static void bulkOutCmplMain(struct usb_ep *ep, struct usb_request *req) resetOutReq(); break; case CVI_USB_PROGRAM: -#ifdef CONFIG_NAND_SUPPORT - // Erase partition first - if (strncmp((char *)((uintptr_t)HEADER_ADDR + 20), prevExtra, - EXTRA_FLAG_SIZE)) { - strlcpy(prevExtra, - (char *)((uintptr_t)HEADER_ADDR + 20), - EXTRA_FLAG_SIZE); - snprintf(cmd, 255, "nand erase.part -y %s", prevExtra); - pr_debug("%s\n", cmd); - run_command(cmd, 0); - } -#endif /* INFO("CVI_USB_PROGRAM\n"); */ _prgImage((void *)UPDATE_ADDR, 0x40, NULL); sendInReq(length, CVI_USB_PROGRAM, bulkResetOutReq, NULL, 0); diff --git a/u-boot-2021.10/drivers/jpeg/Makefile b/u-boot-2021.10/drivers/jpeg/Makefile new file mode 100644 index 000000000..b1f34e8d0 --- /dev/null +++ b/u-boot-2021.10/drivers/jpeg/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_CMD_CVI_JPEG) += mm.o jdi.o jpuapifunc.o jpeg.o jpuhelper.o jdi_osal.o jpuapi.o jpurun.o mixer.o diff --git a/u-boot-2021.10/drivers/jpeg/config.h b/u-boot-2021.10/drivers/jpeg/config.h new file mode 100644 index 000000000..a53eaeaff --- /dev/null +++ b/u-boot-2021.10/drivers/jpeg/config.h @@ -0,0 +1,48 @@ +#ifndef __CONFIG_H__ +#define __CONFIG_H__ + +#if defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) || defined(WIN32) || defined(__MINGW32__) +# define PLATFORM_WIN32 +#elif defined(linux) || defined(__linux) || defined(ANDROID) +# define PLATFORM_LINUX +#else +# define PLATFORM_NON_OS +#endif + +#if defined(_MSC_VER) +# include +# include +# define inline _inline +# define VPU_DELAY_MS(X) Sleep(X) +//should change to delay function which can be delay a microsecond unut. +# define VPU_DELAY_US(X) Sleep(X) +# define kbhit _kbhit +# define getch _getch +#elif defined(__GNUC__) +#ifdef _KERNEL_ +# define VPU_DELAY_MS(X) udelay((X) * 1000) +# define VPU_DELAY_US(X) udelay(X) +#else +# define VPU_DELAY_MS(X) usleep((X) * 1000) +# define VPU_DELAY_US(X) usleep(X) +#endif +#elif defined(__ARMCC__) +#else +# error "Unknown compiler." +#endif + +#define PROJECT_ROOT "..\\..\\..\\" + +#if defined(JPU_FPGA_PLATFORM) +#if defined(ANDROID) || defined(linux) +#else +#define SUPPORT_CONF_TEST +#endif +#endif + +#define API_VERSION 165 + +#define HAVE_STDIN_H 1 +//#define MJPEG_ERROR_CONCEAL + +#endif /* __CONFIG_H__ */ diff --git a/u-boot-2021.10/drivers/jpeg/cvi_jpeg_cfg.h b/u-boot-2021.10/drivers/jpeg/cvi_jpeg_cfg.h new file mode 100644 index 000000000..3d79d11c4 --- /dev/null +++ b/u-boot-2021.10/drivers/jpeg/cvi_jpeg_cfg.h @@ -0,0 +1,54 @@ +/* + * Copyright CviTek Inc. + * + * Created Time: Feb, 2020 + */ +#ifndef __CVI_JPEG_CFG_H__ +#define __CVI_JPEG_CFG_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define BM_DBG_MSG_ENABLE + +#define BM_MASK_ERR 0x1 +#define BM_MASK_FLOW 0x2 +#define BM_MASK_MEM 0x4 +#define BM_MASK_TRACE 0x10 +#define BM_MASK_PERF 0x20 +#define BM_MASK_ALL 0xFFFF + +#ifdef BM_DBG_MSG_ENABLE +#define BM_DBG_ERR(msg, ...) if (jpu_level & BM_MASK_ERR)\ + { printf("[ERR] %s = %d, " msg, __func__, __LINE__, ## __VA_ARGS__); } +#define BM_DBG_FLOW(msg, ...) if (jpu_level & BM_MASK_FLOW)\ + { printf("[FLOW] %s = %d, " msg, __func__, __LINE__, ## __VA_ARGS__); } +#define BM_DBG_MEM(msg, ...) if (jpu_level & BM_MASK_MEM)\ + { printf("[MEM] %s = %d, " msg, __func__, __LINE__, ## __VA_ARGS__); } +#define BM_DBG_TRACE(msg, ...) if (jpu_level & BM_MASK_TRACE)\ + { printf("[TRACE] %s = %d, " msg, __func__, __LINE__, ## __VA_ARGS__); } +#define BM_DBG_PERF(msg, ...) if (jpu_level & BM_MASK_PERF)\ + { printf("[PERF] %s = %d, " msg, __func__, __LINE__, ## __VA_ARGS__); } +extern int jpu_level; +#else +#define BM_DBG_ERR(msg, ...) +#define BM_DBG_FLOW(msg, ...) +#define BM_DBG_MEM(msg, ...) +#define BM_DBG_TRACE(msg, ...) +#define BM_DBG_PERF(msg, ...) +#endif + +//#define PROFILE_PERFORMANCE +#define JPEG_CODEC_INTR_NUM 75 +//#define SUPPORT_INTERRUPT + +#ifdef SUPPORT_INTERRUPT +int irq_handler_jpeg_codec(int irqn, void *priv); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/u-boot-2021.10/drivers/jpeg/jdi.c b/u-boot-2021.10/drivers/jpeg/jdi.c new file mode 100644 index 000000000..0634ef345 --- /dev/null +++ b/u-boot-2021.10/drivers/jpeg/jdi.c @@ -0,0 +1,537 @@ +#if defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) || defined(WIN32) || defined(__MINGW32__) +#elif defined(linux) || defined(__linux) || defined(ANDROID) + +#include +#include "jdi.h" +#include "jpulog.h" +#include "jdi_osal.h" +#include "dm/device.h" +#include "timer.h" +#include "asm/cache.h" + +#define JPU_BIT_REG_SIZE 0x1000 +#define JPU_BIT_REG_BASE (0x0B000000) + +/* + * DRAM Total Size = 256MB = 0x10000000 + * DRAM_PHYSICAL_BASE = 0x100000000 + + | Offset | Size | Note + * System | 0x100000000 | 0x2000000 | 32MB + * System Mem | 0x102000000 | 0x4000000 | 64MB + * File Buf | 0x106000000 | 0x2000000 | 32MB + * Enc BS | 0x108000000 | 0x1000000 | 16MB + * ENC SRC | 0x10C000000 | 0x1000000 | 16MB + * LOAD SRC | 0x10D000000 + */ +//#define SYSTEM_SIZE 0x2000000 +#define JDI_DRAM_PHYSICAL_BASE (0x130000000) +#define JDI_DRAM_PHYSICAL_SIZE 0x00200000 //0x004000000 + +#define JDI_SYSTEM_ENDIAN JDI_LITTLE_ENDIAN + +#define SPM_MEM_PHYSICAL_BASE 0x140000000 +#define SPM_MEM_PHYSICAL_SIZE 0xC0000000 +typedef struct jpu_buffer_t jpudrv_buffer_t; + +typedef struct jpu_buffer_pool_t { + jpudrv_buffer_t jdb; + int inuse; +} jpu_buffer_pool_t; + +static int s_jpu_fd; +static jpu_instance_pool_t *s_pjip; +static jpu_instance_pool_t s_jip; +static int s_task_num; +static int s_clock_state; +static jpudrv_buffer_t s_jdb_video_memory; +static jpudrv_buffer_t s_jdb_register; +static jpu_buffer_pool_t s_jpu_buffer_pool[MAX_JPU_BUFFER_POOL]; +static int s_jpu_buffer_pool_count; + +static int jpu_swap_endian(unsigned char *data, int len, int endian); +int jdi_probe(void) +{ + int ret; + + ret = jdi_init(); + jdi_release(); + + return ret; +} + +int jdi_init(void) +{ + int ret; + void *buf = NULL; + + if (s_jpu_fd != -1 && s_jpu_fd != 0x00) { + s_task_num++; + return 0; + } + + s_jpu_fd = 1; + + memset((void *)&s_jpu_buffer_pool, 0x00, sizeof(jpu_buffer_pool_t) * MAX_JPU_BUFFER_POOL); + s_jpu_buffer_pool_count = 0; + + s_pjip = jdi_get_instance_pool(); + if (!s_pjip) { + JLOG(ERR, "[jdi] fail to create instance pool for saving context\n"); + goto ERR_JDI_INIT; + } + + buf = malloc(JDI_DRAM_PHYSICAL_SIZE); + + if (buf) { + s_jdb_video_memory.phys_addr = (unsigned long)buf; + s_jdb_video_memory.size = JDI_DRAM_PHYSICAL_SIZE; + JLOG(INFO, "alloc s_jdb_video_memory.phys_addr buf %p\n", buf); + } else { + JLOG(ERR, "alloc s_jdb_video_memory.phys_addr failed\n"); + goto ERR_JDI_INIT; + } + + if (!s_pjip->instance_pool_inited) { + memset(&s_pjip->vmem, 0x00, sizeof(jpeg_mm_t)); + ret = jmem_init(&s_pjip->vmem, (unsigned long)s_jdb_video_memory.phys_addr, s_jdb_video_memory.size); + if (ret < 0) { + JLOG(ERR, "[JDI] fail to init jpu memory management logic\n"); + goto ERR_JDI_INIT; + } + } + + s_jdb_register.phys_addr = JPU_BIT_REG_BASE; + s_jdb_register.virt_addr = JPU_BIT_REG_BASE; + s_jdb_register.size = JPU_BIT_REG_SIZE; + + jdi_set_clock_gate(1); + + s_task_num++; + + JLOG(INFO, "[jdi] success to init driver\n"); + return s_jpu_fd; + +ERR_JDI_INIT: + + jdi_release(); + return -1; +} + +int jdi_release(void) +{ + + if (s_jpu_fd == -1 || s_jpu_fd == 0x00) + return 0; + + if (jdi_lock() < 0) { + JLOG(ERR, "[jdi] fail to handle lock function\n"); + return -1; + } + + if (s_task_num > 1) {// means that the opened instance remains + s_task_num--; + jdi_unlock(); + return 0; + } + + if (s_jdb_video_memory.phys_addr) { + JLOG(INFO, "free s_jdb_video_memory.phys_addr buf %p\n", (void *)s_jdb_video_memory.phys_addr); + free((void *)s_jdb_video_memory.phys_addr); + } + s_task_num--; + + jmem_exit(&s_pjip->vmem); + + memset(&s_jdb_register, 0x00, sizeof(jpudrv_buffer_t)); + + if (s_jpu_fd != -1 && s_jpu_fd != 0x00) + s_jpu_fd = -1; + + s_pjip = NULL; + + jdi_unlock(); + + return 0; +} + +jpu_instance_pool_t *jdi_get_instance_pool(void) +{ + if (!s_pjip) { + s_pjip = &s_jip; + + memset(s_pjip, 0x00, sizeof(jpu_instance_pool_t)); + } + + return (jpu_instance_pool_t *)s_pjip; +} + +int jdi_open_instance(unsigned long instIdx) +{ + if (!s_pjip || s_jpu_fd == -1 || s_jpu_fd == 0x00) + return -1; + + s_pjip->jpu_instance_num++; + + return 0; +} + +int jdi_close_instance(unsigned long instIdx) +{ + if (!s_pjip || s_jpu_fd == -1 || s_jpu_fd == 0x00) + return -1; + + s_pjip->jpu_instance_num--; + + return 0; +} + +int jdi_get_instance_num(void) +{ + if (!s_pjip || s_jpu_fd == -1 || s_jpu_fd == 0x00) + return -1; + + return s_pjip->jpu_instance_num; +} + +int jdi_hw_reset(void) +{ + if (!s_pjip || s_jpu_fd == -1 || s_jpu_fd == 0x00) + return -1; + + // to do any action for hw reset + + return 0; +} + +int jdi_lock(void) +{ + return 0; +} + +void jdi_unlock(void) +{ + +} + +void jdi_write_register(unsigned int addr, unsigned int data) +{ + unsigned long reg_addr; + + if (!s_pjip || s_jpu_fd == -1 || s_jpu_fd == 0x00) + return; + + reg_addr = addr + (unsigned long)s_jdb_register.virt_addr; + *(unsigned int *)reg_addr = data; + flush_dcache_range(reg_addr, reg_addr + sizeof(unsigned int)); +// flush_dcache_all(); +} + +unsigned int jdi_read_register(unsigned int addr) +{ + unsigned long reg_addr; + + reg_addr = addr + (unsigned long)s_jdb_register.virt_addr; +// INV_DCACHE_RANGE((unsigned int)reg_addr, sizeof(unsigned int)); +// invalidate_dcache_all(); + invalidate_dcache_range(reg_addr, reg_addr + sizeof(unsigned int)); + + return *(unsigned int *)reg_addr; +} + +int jdi_write_memory(unsigned long addr, unsigned char *data, int len, int endian) +{ + jpudrv_buffer_t jdb = {0, }; + unsigned long offset; + int i; + + if (!s_pjip || s_jpu_fd == -1 || s_jpu_fd == 0x00) + return -1; + + for (i = 0; i < MAX_JPU_BUFFER_POOL; i++) { + if (s_jpu_buffer_pool[i].inuse == 1) { + jdb = s_jpu_buffer_pool[i].jdb; + if (addr >= jdb.phys_addr && addr < (jdb.phys_addr + jdb.size)) + break; + } + } + + if (!jdb.size) { + JLOG(ERR, "address 0x%08lx is not mapped address!!!\n", addr); + return -1; + } + + offset = addr - (unsigned long)jdb.phys_addr; + + jpu_swap_endian(data, len, endian); + + //by zhao for cache testing + OSAL_MEMCPY((void *)((unsigned long)jdb.virt_addr + offset), (void *)data, len); + //josal_memcpy_nocache((void *)((unsigned long)jdb.virt_addr+offset), (void *)data, len); + return len; +} + +int jdi_read_memory(unsigned long addr, unsigned char *data, int len, int endian) +{ + jpudrv_buffer_t jdb = {0}; + unsigned long offset; + int i; + + if (!s_pjip || s_jpu_fd == -1 || s_jpu_fd == 0x00) + return -1; + + for (i = 0; i < MAX_JPU_BUFFER_POOL; i++) { + if (s_jpu_buffer_pool[i].inuse == 1) { + jdb = s_jpu_buffer_pool[i].jdb; + if (addr >= jdb.phys_addr && addr < (jdb.phys_addr + jdb.size)) + break; + } + } + + if (!jdb.size) + return -1; + + offset = addr - (unsigned long)jdb.phys_addr; + + INV_DCACHE_RANGE(((unsigned long)jdb.virt_addr + offset), len); + OSAL_MEMCPY(data, (const void *)((unsigned long)jdb.virt_addr + offset), len); + jpu_swap_endian(data, len, endian); + + return len; +} + +int jdi_allocate_dma_memory(jpu_buffer_t *vb) +{ + int i; + + unsigned long offset; + jpudrv_buffer_t jdb = {0, }; + + if (!s_pjip || s_jpu_fd == -1 || s_jpu_fd == 0x00) + return -1; + + jdb.size = vb->size; + jdb.phys_addr = (unsigned long)jmem_alloc(&s_pjip->vmem, jdb.size, 0); + + if (jdb.phys_addr == (unsigned long)-1) + return -1; // not enough memory + + offset = (unsigned long)(jdb.phys_addr - s_jdb_video_memory.phys_addr); + jdb.base = (unsigned long)s_jdb_video_memory.base + offset; + jdb.virt_addr = jdb.phys_addr; + + vb->phys_addr = (unsigned long)jdb.phys_addr; + vb->base = (unsigned long)jdb.base; + vb->virt_addr = (unsigned long)vb->phys_addr; + + for (i = 0; i < MAX_JPU_BUFFER_POOL; i++) { + if (s_jpu_buffer_pool[i].inuse == 0) { + s_jpu_buffer_pool[i].jdb = jdb; + s_jpu_buffer_pool_count++; + s_jpu_buffer_pool[i].inuse = 1; + break; + } + } + + return 0; +} + +void jdi_free_dma_memory(jpu_buffer_t *vb) +{ + int i; +// int ret = 0; + jpudrv_buffer_t jdb = {0, }; + + if (!s_pjip || s_jpu_fd == -1 || s_jpu_fd == 0x00) + return; + + if (vb->size == 0) + return; + + for (i = 0; i < MAX_JPU_BUFFER_POOL; i++) { + if (s_jpu_buffer_pool[i].jdb.phys_addr == vb->phys_addr) { + s_jpu_buffer_pool[i].inuse = 0; + s_jpu_buffer_pool_count--; + jdb = s_jpu_buffer_pool[i].jdb; + break; + } + } + + if (!jdb.size) { + JLOG(ERR, "[JDI] invalid buffer to free address = 0x%x\n", (int)jdb.virt_addr); + return; + } + + jmem_free(&s_pjip->vmem, (unsigned long)jdb.phys_addr, 0); + memset(vb, 0, sizeof(jpu_buffer_t)); +} + +int jdi_set_clock_gate(int enable) +{ + s_clock_state = enable; + + return 0; +} + +int jdi_get_clock_gate(void) +{ + return s_clock_state; +} + +static int intr_reason; + +int irq_handler_jpeg_codec(int irqn, void *priv) +{ + int curr_int = 0; + +#ifdef PROFILE_PERFORMANCE + int ms; + + ms = timer_meter_get_ms(); + BM_DBG_PERF("time = %d ms\n", ms); +#endif + + curr_int = jdi_read_register(MJPEG_PIC_STATUS_REG); + + intr_reason |= curr_int; + BM_DBG_TRACE("curr_int = 0x%X, intr_reason = 0x%X\n", curr_int, intr_reason); + + JpuWriteReg(MJPEG_PIC_STATUS_REG, curr_int); + + return 0; +} + +int jdi_wait_interrupt(int timeout) +{ +#ifdef SUPPORT_INTERRUPT + int out_reason = 0; + + while (1) { + BM_DBG_TRACE("intr_reason = 0x%X\n", intr_reason); + + out_reason = intr_reason; + if (out_reason) { + int int_en = jdi_read_register(MJPEG_INTR_MASK_REG); + + JpuWriteReg(MJPEG_INTR_MASK_REG, 0); + + intr_reason &= (~out_reason); + BM_DBG_TRACE("out_reason = 0x%X\n", out_reason); + + JpuWriteReg(MJPEG_INTR_MASK_REG, int_en); + break; + } + } + + return out_reason; +#else + + while (1) { + if (jdi_read_register(MJPEG_PIC_STATUS_REG)) + break; + + //Sleep(1); // 1ms sec + //if (count++ > timeout) + // return -1; + } + + return 0; +#endif +} + +void jdi_log(int cmd, int step) +{ + int i; + + switch (cmd) { + case JDI_LOG_CMD_PICRUN: + if (step == 1) { + JLOG(INFO, "\n**PIC_RUN start\n"); + } else { + JLOG(INFO, "\n**PIC_RUN end\n"); + } + break; + } + + for (i = 0; i <= 0x238; i = i + 16) { + JLOG(INFO, "0x%04xh: 0x%08x 0x%08x 0x%08x 0x%08x\n", i, + jdi_read_register(i), jdi_read_register(i + 4), + jdi_read_register(i + 8), jdi_read_register(i + 0xc)); + } +} + +int jpu_swap_endian(unsigned char *data, int len, int endian) +{ + unsigned long *p; + unsigned long v1, v2, v3; + int i; + int swap = 0; + + p = (unsigned long *)data; + + if (endian == JDI_SYSTEM_ENDIAN) + swap = 0; + else + swap = 1; + + if (swap) { + if (endian == JDI_LITTLE_ENDIAN || endian == JDI_BIG_ENDIAN) { + for (i = 0; i < len / 4; i += 2) { + v1 = p[i]; + v2 = (v1 >> 24) & 0xFF; + v2 |= ((v1 >> 16) & 0xFF) << 8; + v2 |= ((v1 >> 8) & 0xFF) << 16; + v2 |= ((v1 >> 0) & 0xFF) << 24; + v3 = v2; + v1 = p[i + 1]; + v2 = (v1 >> 24) & 0xFF; + v2 |= ((v1 >> 16) & 0xFF) << 8; + v2 |= ((v1 >> 8) & 0xFF) << 16; + v2 |= ((v1 >> 0) & 0xFF) << 24; + p[i] = v2; + p[i + 1] = v3; + } + } else { + int sys_endian = JDI_SYSTEM_ENDIAN; + int swap4byte = 0; + + swap = 0; + + if (endian == JDI_32BIT_LITTLE_ENDIAN) { + if (sys_endian == JDI_BIG_ENDIAN) { + swap = 1; + } + } else { + if (sys_endian == JDI_BIG_ENDIAN) { + swap4byte = 1; + } else if (sys_endian == JDI_LITTLE_ENDIAN) { + swap4byte = 1; + swap = 1; + } else { + swap = 1; + } + } + if (swap) { + for (i = 0; i < len / 4; i++) { + v1 = p[i]; + v2 = (v1 >> 24) & 0xFF; + v2 |= ((v1 >> 16) & 0xFF) << 8; + v2 |= ((v1 >> 8) & 0xFF) << 16; + v2 |= ((v1 >> 0) & 0xFF) << 24; + p[i] = v2; + } + } + if (swap4byte) { + for (i = 0; i < len / 4; i += 2) { + v1 = p[i]; + v2 = p[i + 1]; + p[i] = v2; + p[i + 1] = v1; + } + } + } + } + return swap; +} + +#endif diff --git a/u-boot-2021.10/drivers/jpeg/jdi.h b/u-boot-2021.10/drivers/jpeg/jdi.h new file mode 100644 index 000000000..6a89d0400 --- /dev/null +++ b/u-boot-2021.10/drivers/jpeg/jdi.h @@ -0,0 +1,118 @@ + +#ifndef _JDI_HPI_H_ +#define _JDI_HPI_H_ + +#include +//#include +#include "jpuconfig.h" +#include "regdefine.h" +#include "mm.h" +#include "jdi_osal.h" + +#define MAX_JPU_BUFFER_POOL 32 + +#define JpuWriteReg(ADDR, DATA) jdi_write_register(ADDR, DATA) // system register write +#define JpuReadReg(ADDR) jdi_read_register(ADDR) // system register write +#define JpuWriteMem(ADDR, DATA, LEN, ENDIAN) jdi_write_memory(ADDR, DATA, LEN, ENDIAN) // system memory write +#define JpuReadMem(ADDR, DATA, LEN, ENDIAN) jdi_read_memory(ADDR, DATA, LEN, ENDIAN) // system memory write + +typedef struct jpu_buffer_t { + unsigned int size; + unsigned long phys_addr; + unsigned long base; + unsigned long virt_addr; +} jpu_buffer_t; + +typedef struct jpu_instance_pool_t { + unsigned char jpgInstPool[MAX_NUM_INSTANCE][MAX_INST_HANDLE_SIZE]; + void *jpu_mutex; + int jpu_instance_num; + int instance_pool_inited; + void *pendingInst; + jpeg_mm_t vmem; +} jpu_instance_pool_t; + +#ifdef SUPPORT_128BIT_BUS + +typedef enum { + JDI_128BIT_LITTLE_64BIT_LITTLE_ENDIAN = ((0 << 2) + (0 << 1) + (0 << 0)), //128 bit little, 64 bit little + JDI_128BIT_BIG_64BIT_LITTLE_ENDIAN = ((1 << 2) + (0 << 1) + (0 << 0)), //128 bit big , 64 bit little + JDI_128BIT_LITTLE_64BIT_BIG_ENDIAN = ((0 << 2) + (0 << 1) + (1 << 0)), //128 bit little, 64 bit big + JDI_128BIT_BIG_64BIT_BIG_ENDIAN = ((1 << 2) + (0 << 1) + (1 << 0)), //128 bit big, 64 bit big + JDI_128BIT_LITTLE_32BIT_LITTLE_ENDIAN = ((0 << 2) + (1 << 1) + (0 << 0)), //128 bit little, 32 bit little + JDI_128BIT_BIG_32BIT_LITTLE_ENDIAN = ((1 << 2) + (1 << 1) + (0 << 0)), //128 bit big , 32 bit little + JDI_128BIT_LITTLE_32BIT_BIG_ENDIAN = ((0 << 2) + (1 << 1) + (1 << 0)), //128 bit little, 32 bit big + JDI_128BIT_BIG_32BIT_BIG_ENDIAN = ((1 << 2) + (1 << 1) + (1 << 0)), //128 bit big, 32 bit big +} EndianMode; + +#define JDI_LITTLE_ENDIAN JDI_128BIT_LITTLE_64BIT_LITTLE_ENDIAN +#define JDI_BIG_ENDIAN JDI_128BIT_BIG_64BIT_BIG_ENDIAN +#ifndef BIT(x) +#define BIT(x) (1 << (x)) +#endif +#define JDI_128BIT_ENDIAN_MASK BIT(2) +#define JDI_64BIT_ENDIAN_MASK BIT(1) +#define JDI_ENDIAN_MASK BIT(0) + +#define JDI_32BIT_LITTLE_ENDIAN JDI_128BIT_LITTLE_32BIT_LITTLE_ENDIAN +#define JDI_32BIT_BIG_ENDIAN JDI_128BIT_LITTLE_32BIT_BIG_ENDIAN + +#else + +typedef enum { + JDI_LITTLE_ENDIAN = 0, + JDI_BIG_ENDIAN, + JDI_32BIT_LITTLE_ENDIAN, + JDI_32BIT_BIG_ENDIAN, +} EndianMode; +#endif + +typedef enum { + JDI_LOG_CMD_PICRUN = 0, + JDI_LOG_CMD_MAX +} jdi_log_cmd; + +#if defined(__cplusplus) +extern "C" { +#endif + int jdi_probe(void); + int jdi_init(void); + int jdi_release(void); //this function may be called only at system off. + jpu_instance_pool_t *jdi_get_instance_pool(void); + int jdi_allocate_dma_memory(jpu_buffer_t *vb); + void jdi_free_dma_memory(jpu_buffer_t *vb); + + int jdi_wait_interrupt(int timeout); + int jdi_hw_reset(void); + + int jdi_set_clock_gate(int enable); + int jdi_get_clock_gate(void); + + int jdi_open_instance(unsigned long instIdx); + int jdi_close_instance(unsigned long instIdx); + int jdi_get_instance_num(void); + + void jdi_write_register(unsigned int addr, unsigned int data); + unsigned int jdi_read_register(unsigned int addr); + + int jdi_write_memory(unsigned long addr, unsigned char *data, int len, int endian); + int jdi_read_memory(unsigned long addr, unsigned char *data, int len, int endian); + + int jdi_lock(void); + void jdi_unlock(void); + void jdi_log(int cmd, int step); + +#ifdef JPU_FPGA_PLATFORM +#define HPI_SET_TIMING_MAX 1000 + int jdi_set_timing_opt(void); + int jdi_set_clock_freg(int Device, int OutFreqMHz, int InFreqMHz); +#endif + + int getch(void); + int kbhit(void); + +#if defined(__cplusplus) +} +#endif + +#endif //#ifndef _JDI_HPI_H_ diff --git a/u-boot-2021.10/drivers/jpeg/jdi_osal.c b/u-boot-2021.10/drivers/jpeg/jdi_osal.c new file mode 100644 index 000000000..01e9b6496 --- /dev/null +++ b/u-boot-2021.10/drivers/jpeg/jdi_osal.c @@ -0,0 +1,717 @@ +//------------------------------------------------------------------------------ +// File: vdi_osal.c +// +// Copyright (c) 2006, Chips & Media. All rights reserved. +//------------------------------------------------------------------------------ +//#if defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) || defined(WIN32) || defined(__MINGW32__) +//#elif defined(linux) || defined(__linux) || defined(ANDROID) +//#else + +#include +#include +#include + +#include "jdi.h" +#include "jdi_osal.h" +#include "asm/cache.h" +#include "jpulog.h" + +#if defined(JPEG_FVP) +#define FILE_BUFFER_BASE 0xE0000000 +#elif defined(JPEG_FPGA) +#define FILE_BUFFER_BASE 0x116000000 +#endif + +#define FILE_BUFFER_BASE 0x138000000 + +#define MAX_LIST_NUM 1 +#define DEC_BS_FILE_BUFFER_BASE FILE_BUFFER_BASE +#define DEC_BS_FILE_BUFFER_SIZE (0x400000 * MAX_LIST_NUM) +#define DEC_YUV_FILE_BUFFER_BASE (DEC_BS_FILE_BUFFER_BASE + DEC_BS_FILE_BUFFER_SIZE) +#define DEC_YUV_FILE_BUFFER_SIZE (0x800000 * MAX_LIST_NUM) + +#define ENC_YUV_FILE_BUFFER_BASE (DEC_YUV_FILE_BUFFER_BASE + DEC_YUV_FILE_BUFFER_SIZE) +#define ENC_YUV_FILE_BUFFER_SIZE (0x800000 * MAX_LIST_NUM) +#define ENC_BS_FILE_BUFFER_BASE (ENC_YUV_FILE_BUFFER_BASE + ENC_YUV_FILE_BUFFER_SIZE) +#define ENC_BS_FILE_BUFFER_SIZE (0x400000 * MAX_LIST_NUM) +#define ENC_HUFF_FILE_BUFFER_BASE (ENC_BS_FILE_BUFFER_BASE + ENC_BS_FILE_BUFFER_SIZE) +#define ENC_HUFF_FILE_BUFFER_SIZE (0x100000 * MAX_LIST_NUM) +#define ENC_QMAT_FILE_BUFFER_BASE (ENC_HUFF_FILE_BUFFER_BASE + ENC_HUFF_FILE_BUFFER_BASE) +#define ENC_QMAT_FILE_BUFFER_SIZE (0x100000 * MAX_LIST_NUM) +#define ENC_QP_FILE_BUFFER_BASE (ENC_QMAT_FILE_BUFFER_BASE + ENC_QMAT_FILE_BUFFER_SIZE) +#define ENC_QP_FILE_BUFFER_SIZE (0x100000 * MAX_LIST_NUM) +#define ENC_CFG_FILE_BUFFER_BASE (ENC_QP_FILE_BUFFER_BASE + ENC_QP_FILE_BUFFER_SIZE) +#define ENC_CFG_FILE_BUFFER_SIZE (0x10000 * MAX_LIST_NUM) + +#define MULTI_FILE_BUFFER_BASE (ENC_CFG_FILE_BUFFER_BASE + ENC_CFG_FILE_BUFFER_SIZE) +#define MULTI_FILE_BUFFER_SIZE (0x10000) +#define MULTI_YUV_FILE_BUFFER_BASE (MULTI_FILE_BUFFER_BASE + MULTI_FILE_BUFFER_SIZE) +#define MULTI_YUV_FILE_BUFFER_SIZE (0x400000) + +#if defined(JPEG_FVP) +#define LOG_MSG_BUF_BASE 0xD0000000 +#elif defined(JPEG_FPGA) +#define LOG_MSG_BUF_BASE 0x120500000 +#endif + +#define LOG_MSG_BUF_BASE 0x120500000 // fixme fix me + +#define LOG_MSG_BUF_SIZE 0x100000 +static char *LOG_MSG_BUF = (char *)LOG_MSG_BUF_BASE; + +#define MAX_MALLOC_BLOCK_SIZE 0x50000//0x200000 +#define MAX_MALLOC_BLOCK_NUM 7 + +int jpu_level = BM_MASK_ERR; + +//To +#define FILE_BUFFER_SIZE 0x1000000 * (MAX_FD_NUM - 1) +#define CMP_FILE_BUFFER_SIZE 0x1000000 +unsigned char osal_malloc_heap[MAX_MALLOC_BLOCK_NUM][MAX_MALLOC_BLOCK_SIZE]; // allocate 64 4M-block for malloc +unsigned char osal_malloc_used[MAX_MALLOC_BLOCK_NUM] = {0}; + +typedef struct fileio_buf_t { + char *_ptr; + int _cnt; + char *_base; + int _flag; + int _file; + int _charbuf; + int _bufsiz; + char *_tmpfname; +} fileio_buf_t; + +#define MAX_FD_NUM 5 // 0-bitstream file 1-yuv cmp file 2- +static fileio_buf_t s_file[MAX_FD_NUM] = {0}; + +static void myprintf(char *MsgBuf) +{ + int size = strlen(MsgBuf); + + if (size == 0) + return; + + if (LOG_MSG_BUF + size >= (char *)(LOG_MSG_BUF_BASE + LOG_MSG_BUF_SIZE)) + return; + + josal_memcpy(LOG_MSG_BUF, MsgBuf, size); + + LOG_MSG_BUF += size; +} + +void *josal_memcpy(void *dst, const void *src, int count) +{ + void *ret; + + ret = memcpy(dst, src, count); + flush_dcache_range((unsigned long)dst, count); + return ret; +} + +void *josal_memset(void *dst, int val, int count) +{ + return memset(dst, val, count); +} + +int josal_memcmp(const void *src, const void *dst, int size) +{ + return memcmp(src, dst, size); +} + +void *josal_malloc(int size) +{ + int i; + + if (size > MAX_MALLOC_BLOCK_SIZE || size == 0) + return NULL; + + for (i = 0; i < MAX_MALLOC_BLOCK_NUM; i++) + if (osal_malloc_used[i] == 0) + break; + + if (i < MAX_MALLOC_BLOCK_NUM) { + osal_malloc_used[i] = 1; +// JLOG(INFO, "malloc: %d, addr: 0x%p, size: %d\n", i, osal_malloc_heap[i], size); + return (void *)osal_malloc_heap[i]; + } + + return NULL; + +} + +void *josal_realloc(void *ptr, int size) +{ + if (!ptr) + return josal_malloc(size); + + if (size == 0 || size > MAX_MALLOC_BLOCK_SIZE) { + josal_free(ptr); + return NULL; + } + + if (size <= MAX_MALLOC_BLOCK_SIZE) + return ptr; + + return NULL; +} + +void josal_free(void *p) +{ + //free(p); + int i; + + for (i = 0; i < MAX_MALLOC_BLOCK_NUM; i++) + if ((void *)osal_malloc_heap[i] == p) + break; + + osal_malloc_used[i] = 0; +} + +int josal_fflush(osal_file_t fp) +{ + return 1; +} + +int josal_feof(osal_file_t fp) +{ + fileio_buf_t *p_fp = (fileio_buf_t *)fp; + + if ((uint64_t)p_fp->_ptr >= p_fp->_bufsiz) + return 1; + else + return 0; +} + +osal_file_t josal_fopen(const char *osal_file_tname, const char *mode) +{ + int i; + + for (i = 0; i < MAX_FD_NUM; i++) + if (s_file[i]._bufsiz == 0) // not used + break; + + if (i == MAX_FD_NUM) + return NULL; + + if (i != 1) // 1 - cmp file + s_file[i]._bufsiz = FILE_BUFFER_SIZE / (MAX_FD_NUM - 1); + else + s_file[i]._bufsiz = CMP_FILE_BUFFER_SIZE; // 256M for YUV compare file + + if (i == 0) + s_file[i]._base = (char *)FILE_BUFFER_BASE; + else + s_file[i]._base = s_file[i - 1]._base + s_file[i - 1]._bufsiz; + + s_file[i]._ptr = (char *)0; + + for (i = 0; i < MAX_FD_NUM; i++) { + JLOG(INFO, "file = %d, base = 0x%lX, size = 0x%lX\n", i, + (unsigned long)s_file[i]._base, + (unsigned long)s_file[i]._bufsiz); + } + + return &s_file[i]; +} + +size_t josal_fwrite(const void *p, int size, int count, osal_file_t fp) +{ + long addr; + long real_size; + fileio_buf_t *p_fp = (fileio_buf_t *)fp; + + if (!p_fp) + return 0; + + if ((unsigned long)(size * count + p_fp->_ptr) > p_fp->_bufsiz) + real_size = p_fp->_bufsiz - (unsigned long)p_fp->_ptr; + else + real_size = size * count; + + addr = (long)((long)p_fp->_base + (long)p_fp->_ptr); + josal_memcpy((void *)addr, (void *)p, real_size); + p_fp->_ptr += real_size; + + JLOG(INFO, "fp: 0x%lx, size: %ld\n", addr, real_size); + return real_size; +} + +size_t josal_fread(void *p, int size, int count, osal_file_t fp) +{ + long addr; + long real_size; + fileio_buf_t *p_fp = (fileio_buf_t *)fp; + + if (!p_fp) + return 0; + + if ((unsigned long)(size * count + p_fp->_ptr) > p_fp->_bufsiz) + real_size = p_fp->_bufsiz - (unsigned long)p_fp->_ptr; + else + real_size = size * count; + + addr = (long)((long)p_fp->_base + (long)p_fp->_ptr); + josal_memcpy((void *)p, (void *)addr, real_size); + p_fp->_ptr += real_size; + + //printf("p_fp: _ptr = 0x%016llx _base = 0x%016llx _bufsiz = 0x%08x\n", + // (uint64_t)p_fp->_ptr, (uint64_t)p_fp->_base, p_fp->_bufsiz); + + return real_size; +} + +char *josal_fgets(void *p, int size, osal_file_t fp) +{ + int s = josal_fread(p, 1, size, fp); + + if (s == size) + return p; + else + return NULL; +} + +char josal_fgetc(osal_file_t fp) +{ + char *ptr; + fileio_buf_t *p_fp = (fileio_buf_t *)fp; + + if (!p_fp) + return -1; + + if ((unsigned long)p_fp->_ptr + sizeof(char) == p_fp->_bufsiz) + return -1; + + ptr = p_fp->_base + (unsigned long)p_fp->_ptr; + p_fp->_ptr++; + + return *ptr; +} + +size_t josal_fputs(const char *s, osal_file_t fp) +{ + return josal_fwrite(s, sizeof(char), strlen(s), fp); +} + +long josal_ftell(osal_file_t fp) +{ + fileio_buf_t *p_fp = (fileio_buf_t *)fp; + + return p_fp->_bufsiz; +} + +int josal_fseek(osal_file_t fp, long offset, int origin) +{ + char *curr_p; + fileio_buf_t *p_fp = (fileio_buf_t *)fp; + + if (!fp) + return -1; + + switch (origin) { + case SEEK_CUR: + curr_p = (char *)p_fp->_ptr; + break; + case SEEK_END: + curr_p = (char *)(uint64_t)p_fp->_bufsiz; + break; + case SEEK_SET: + curr_p = (char *)0; + break; + default: + return -1; + } + + p_fp->_ptr = curr_p + offset; + if (p_fp->_ptr > p_fp->_base + p_fp->_bufsiz) + p_fp->_ptr = p_fp->_base + p_fp->_bufsiz; + + return 0; +} + +int josal_fclose(osal_file_t fp) +{ + fileio_buf_t *p_fp = (fileio_buf_t *)fp; + + if (!p_fp) + return -1; + + p_fp->_base = (char *)0; + p_fp->_bufsiz = 0; + p_fp->_ptr = (char *)0; + + return 1; +} + +int josal_fscanf(osal_file_t fp, const char *_Format, ...) +{ + return 1; +} + +int josal_fprintf(osal_file_t fp, const char *_Format, ...) +{ + va_list ptr; + char logBuf[MAX_PRINT_LENGTH] = {0}; + + va_start(ptr, _Format); + + vsnprintf(logBuf, MAX_PRINT_LENGTH, _Format, ptr); + + va_end(ptr); + + myprintf(logBuf); + + return 1; + +} + +int josal_kbhit(void) +{ + return 0; +} + +int josal_getch(void) +{ + return -1; +} + +int josal_flush_ch(void) +{ + return -1; +} + +int josal_srand(int seed) +{ + return 0; +} + +/* to return a integer between 0~FEEDING_MAX_SIZE(4M) */ +int josal_rand(void) +{ + return 0x10000; +} + +/* to conver c to upper case */ +int josal_toupper(int c) +{ + int ret = c; + char *ptr = (char *)&ret; + int i; + + for (i = 0; i < sizeof(int); i++) { + if (ptr[i] > 96 && ptr[i] < 123) + ptr[i++] -= 32; + } + return ret; +} + +void jinv_dcache_range(unsigned long start, unsigned long size) +{ + invalidate_dcache_range(start, size); +} + +#ifdef LIB_C_STUB + +/* + * newlib_stubs.c + * the bellow code is just to build ref-code. + * customers will removed the bellow code bacuase they need a library which is related to the + * system library such as newlibc + */ +#include +#include +#include +#include + +#ifndef STDOUT_USART +#define STDOUT_USART 0 +#endif + +#ifndef STDERR_USART +#define STDERR_USART 0 +#endif + +#ifndef STDIN_USART +#define STDIN_USART 0 +#endif + +#undef errno +int errno; +extern int errno; + +/* + * environ + * A pointer to a list of environment variables and their values. + * For a minimal environment, this empty list is adequate: + */ +char *__env[1] = { 0 }; +char **environ = __env; + +//int _write(int file, char *ptr, int len); + +void _exit(int status) +{ + _write(1, "exit", 4); + while (1) { + ; + } +} + +int _close(int file) +{ + return -1; +} + +/* + * execve + * Transfer control to a new process. Minimal implementation (for a system without processes): + */ +int _execve(char *name, char **argv, char **env) +{ + errno = ENOMEM; + return -1; +} + +/* + * fork + * Create a new process. Minimal implementation (for a system without processes): + */ +int _fork(void) +{ + errno = EAGAIN; + return -1; +} + +/* + * fstat + * Status of an open file. For consistency with other minimal implementations in these examples, + * all files are regarded as character special devices. + * The `sys/stat.h' header file required is distributed in the `include' subdirectory for this C library. + */ +int _fstat(int file, struct stat *st) +{ + st->st_mode = S_IFCHR; + return 0; +} + +/* + * getpid + * Process-ID; this is sometimes used to generate strings unlikely to conflict with other processes. + * Minimal implementation, + * for a system without processes: + */ +int _getpid(void) +{ + return 1; +} + +/* + * isatty + * Query whether output stream is a terminal. For consistency with the other minimal implementations, + */ +int _isatty(int file) +{ + switch (file) { + case STDOUT_FILENO: + case STDERR_FILENO: + case STDIN_FILENO: + return 1; + default: + //errno = ENOTTY; + errno = EBADF; + return 0; + } +} + +/* + * kill + * Send a signal. Minimal implementation: + */ +int _kill(int pid, int sig) +{ + errno = EINVAL; + return (-1); +} + +/* + * link + * Establish a new name for an existing file. Minimal implementation: + */ + +int _link(char *old, char *new) +{ + errno = EMLINK; + return -1; +} + +/* + * lseek + * Set position in a file. Minimal implementation: + */ +int _lseek(int file, int ptr, int dir) +{ + return 0; +} + +/* + * sbrk + * Increase program data space. + * Malloc and related functions depend on this + */ +caddr_t _sbrk(int incr) +{ + + // extern char _ebss; // Defined by the linker + char _ebss; + static char *heap_end; + char *prev_heap_end; + + if (heap_end == 0) { + heap_end = &_ebss; + } + prev_heap_end = heap_end; + + heap_end += incr; + return (caddr_t)prev_heap_end; +} + +/* + * read + * Read a character to a file. `libc' subroutines will use this system routine for input from all files, + * including stdin + * Returns -1 on error or blocks until the number of characters have been read. + */ + +int _read(int file, char *ptr, int len) +{ + int n; + int num = 0; + + switch (file) { + case STDIN_FILENO: + for (n = 0; n < len; n++) { + char c = 0; +#if STDIN_USART == 1 + while ((USART1->SR & USART_FLAG_RXNE) == (u16)RESET) { + } + c = (char)(USART1->DR & (u16)0x01FF); +#elif STDIN_USART == 2 + while ((USART2->SR & USART_FLAG_RXNE) == (u16)RESET) { + } + c = (char)(USART2->DR & (u16)0x01FF); +#elif STDIN_USART == 3 + while ((USART3->SR & USART_FLAG_RXNE) == (u16)RESET) { + } + c = (char)(USART3->DR & (u16)0x01FF); +#endif + *ptr++ = c; + num++; + } + break; + default: + errno = EBADF; + return -1; + } + return num; +} + +/* + * stat + * Status of a file (by name). Minimal implementation: + * int _EXFUN(stat,( const char *__path, struct stat *__sbuf )); + */ +int stat(const char *filepath, struct stat *st) +{ + return _stat(filepath, st); +} + +int _stat(const char *filepath, struct stat *st) +{ + st->st_mode = S_IFCHR; + st->st_size = CMP_FILE_BUFFER_SIZE; + return 0; +} + +/* + * times + * Timing information for current process. Minimal implementation: + */ +clock_t _times(struct tms *buf) +{ + return -1; +} + +/* + * unlink + * Remove a file's directory entry. Minimal implementation: + */ +int _unlink(char *name) +{ + errno = ENOENT; + return -1; +} + +/* + * wait + * Wait for a child process. Minimal implementation: + */ +int _wait(int *status) +{ + errno = ECHILD; + return -1; +} + +/* + * write + * Write a character to a file. `libc' subroutines will use this system routine for output to all files, + * including stdout + * Returns -1 on error or number of bytes sent + */ +int _write(int file, char *ptr, int len) +{ + int n; + + switch (file) { + case STDOUT_FILENO: /*stdout*/ + for (n = 0; n < len; n++) { +#if STDOUT_USART == 1 + while ((USART1->SR & USART_FLAG_TC) == (u16)RESET) { + } + USART1->DR = (*ptr++ & (u16)0x01FF); +#elif STDOUT_USART == 2 + while ((USART2->SR & USART_FLAG_TC) == (u16)RESET) { + } + USART2->DR = (*ptr++ & (u16)0x01FF); +#elif STDOUT_USART == 3 + while ((USART3->SR & USART_FLAG_TC) == (u16)RESET) { + } + USART3->DR = (*ptr++ & (u16)0x01FF); +#endif + } + break; + case STDERR_FILENO: /* stderr */ + for (n = 0; n < len; n++) { +#if STDERR_USART == 1 + while ((USART1->SR & USART_FLAG_TC) == (u16)RESET) { + } + USART1->DR = (*ptr++ & (u16)0x01FF); +#elif STDERR_USART == 2 + while ((USART2->SR & USART_FLAG_TC) == (u16)RESET) { + } + USART2->DR = (*ptr++ & (u16)0x01FF); +#elif STDERR_USART == 3 + while ((USART3->SR & USART_FLAG_TC) == (u16)RESET) { + } + USART3->DR = (*ptr++ & (u16)0x01FF); +#endif + } + break; + default: + errno = EBADF; + return -1; + } + return len; +} + +#endif +//#endif + diff --git a/u-boot-2021.10/drivers/jpeg/jdi_osal.h b/u-boot-2021.10/drivers/jpeg/jdi_osal.h new file mode 100644 index 000000000..abd0e4743 --- /dev/null +++ b/u-boot-2021.10/drivers/jpeg/jdi_osal.h @@ -0,0 +1,97 @@ +//------------------------------------------------------------------------------ +// File: log.h +// +// Copyright (c) 2006, Chips & Media. All rights reserved. +//------------------------------------------------------------------------------ + +#ifndef _VDI_OSAL_H_ +#define _VDI_OSAL_H_ + +//#include +#include +//#include +#include "cvi_jpeg_cfg.h" + +#define MAX_PRINT_LENGTH 512 + +typedef void *osal_file_t; +# ifndef SEEK_SET +# define SEEK_SET 0 +# endif + +# ifndef SEEK_CUR +# define SEEK_CUR 1 +# endif + +# ifndef SEEK_END +# define SEEK_END 2 +# endif + +#if defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) || defined(WIN32) || defined(__MINGW32__) +#elif defined(linux) || defined(__linux) || defined(ANDROID) + +//#ifndef stdout +//# define stdout (void * )1 +//#endif +//#ifndef stderr +//# define stderr (void * )1 +//#endif + +#define OSAL_MEMCPY josal_memcpy +#define OSAL_MEMCMP josal_memcmp +#define OSAL_MALLOC josal_malloc +#define OSAL_FREE josal_free +#define OSAL_FOPEN josal_fopen +#define OSAL_FWRITE josal_fwrite +#define OSAL_FREAD josal_fread +#define OSAL_FSEEK josal_fseek +#define OSAL_FCLOSE josal_fclose +#define OSAL_FFLUSH josal_fflush +#define OSAL_FEOF josal_feof +#define OSAL_FGETS josal_fgets +#define INV_DCACHE_RANGE jinv_dcache_range + +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +//memory +void *josal_memcpy(void *dst, const void *src, int count); +void *josal_memset(void *dst, int val, int count); +int josal_memcmp(const void *src, const void *dst, int size); +void *josal_malloc(int size); +void *josal_realloc(void *ptr, int size); +void josal_free(void *p); + +osal_file_t josal_fopen(const char *osal_file_tname, const char *mode); +size_t josal_fwrite(const void *p, int size, int count, osal_file_t fp); +size_t josal_fread(void *p, int size, int count, osal_file_t fp); +long josal_ftell(osal_file_t fp); +int josal_fseek(osal_file_t fp, long offset, int origin); +int josal_fclose(osal_file_t fp); +int josal_fflush(osal_file_t fp); +int josal_fprintf(osal_file_t fp, const char *_Format, ...); +int josal_fscanf(osal_file_t fp, const char *_Format, ...); +int josal_kbhit(void); +int josal_getch(void); +int josal_flush_ch(void); +int josal_feof(osal_file_t fp); +void *josal_create_mutex(const char *name); +void josal_close_mutex(void *handle); +int josal_mutex_lock(void *handle); +int josal_mutex_unlock(void *handle); +char josal_fgetc(osal_file_t fp); +char *josal_fgets(void *p, int size, osal_file_t fp); +int josal_srand(int seed); +int josal_rand(void); +int josal_toupper(int c); +size_t josal_fputs(const char *s, osal_file_t fp); +void jinv_dcache_range(unsigned long start, unsigned long size); + +#if defined(__cplusplus) +} +#endif + +#endif //#ifndef _VDI_OSAL_H diff --git a/u-boot-2021.10/drivers/jpeg/jpeg.c b/u-boot-2021.10/drivers/jpeg/jpeg.c new file mode 100644 index 000000000..5e283fba3 --- /dev/null +++ b/u-boot-2021.10/drivers/jpeg/jpeg.c @@ -0,0 +1,155 @@ +#include "jpuconfig.h" +#include "regdefine.h" +#include "jpulog.h" +#include "jpurun.h" +#include "jpuhelper.h" +#include "jdi_osal.h" +#include + +typedef struct v { + int mode; // 1 = dec, 2 = enc + int comparatorFlag; + int packedFormat; + int chroma_interleave; + int usePartialMode; + int partialBufNum; + int rot_angle; + int mirDir; + int outNum; + int roiEnable; + int roiWidth; + int roiHeight; + int mjpgChromaFormat; + int roiOffsetX; + int roiOffsetY; + int iHorScaleMode; + int iVerScaleMode; + int fileSize; + void *bs_addr; + void *yuv_addr; +} dec_cfg_t; + +#define mmio_write_32(a, v) writel(v, a) +#define mmio_read_32(a) readl(a) + +enum _mode_ { + MODE_DEC = 1, + MODE_ENC, +}; + +enum _packFormat_ { + PACK_PLANAR = 0, + PACK_YUYV, + PACK_UYVY, + PACK_YVYU, + PACK_VYUY, + PACK_YUV_444_PACKED, +} packFormat; + +enum _partialMode_ { + PARTIAL_MODE_DISABLE = 0, + PARTIAL_MODE_ENABLE, +}; + +enum _rorateAngle_ { + ROTATE_0 = 0, + ROTATE_90 = 90, + ROTATE_180 = 180, + ROTATE_270 = 270, +}; + +enum _mirror_dir_ { + MIRROR_NO = 0, + MIRROR_VERTICAL, + MIRROR_HORIZONTAL, + MIRROR_BOTH, +}; + +int jpeg_dec(dec_cfg_t *cfg, void *bs_addr, void *yuv_addr, int size) +{ + int ret = 0; + DecConfigParam decConfig; + + memset(&decConfig, 0x00, sizeof(DecConfigParam)); + + decConfig.bitstreamFileName = NULL; + decConfig.StreamEndian = JPU_STREAM_ENDIAN; + decConfig.FrameEndian = JPU_FRAME_ENDIAN; + decConfig.yuvFileName = NULL; + decConfig.comparatorFlag = cfg->comparatorFlag; + decConfig.packedFormat = cfg->packedFormat; + decConfig.chroma_interleave = cfg->chroma_interleave; + decConfig.usePartialMode = cfg->usePartialMode; + decConfig.partialBufNum = cfg->partialBufNum; + decConfig.rot_angle = cfg->rot_angle; + decConfig.mirDir = cfg->mirDir; + decConfig.outNum = cfg->outNum; + decConfig.roiEnable = cfg->roiEnable; + decConfig.roiWidth = cfg->roiWidth; + decConfig.roiHeight = cfg->roiHeight; + decConfig.roiOffsetX = cfg->roiOffsetX; + decConfig.roiOffsetY = cfg->roiOffsetY; + decConfig.iHorScaleMode = cfg->iHorScaleMode; + decConfig.iVerScaleMode = cfg->iVerScaleMode; + decConfig.bs_addr = bs_addr; + decConfig.yuv_addr = yuv_addr; + decConfig.size = size; + + if (!decConfig.usePartialMode) { + if (decConfig.rot_angle != 0 && decConfig.rot_angle != 90 && + decConfig.rot_angle != 180 && decConfig.rot_angle != 270) { + JLOG(ERR, "Invalid rotation angle.\n"); + return 1; + } + + if (decConfig.mirDir != 0 && decConfig.mirDir != 1 && + decConfig.mirDir != 2 && decConfig.mirDir != 3) { + JLOG(ERR, "Invalid mirror direction.\n"); + return 1; + } + + if (decConfig.rot_angle != 0 || decConfig.mirDir != 0) + decConfig.useRot = 1; + } + + ret = jpeg_decode_helper(&decConfig); + + return 1 - ret; +} + +int jpeg_decoder(void *bs_addr, void *yuv_addr, int size) +{ + dec_cfg_t allCfgs[] = { + // comp + // {MODE_ENC, 1, PACK_PLANAR, 0, PARTIAL_MODE_DISABLE, 2, ROTATE_0, MIRROR_NO, 1, + // 0, 3840, 2160, PACK_PLANAR, 0, 0, 0, 0, 40681 }, + {MODE_DEC, 1, PACK_PLANAR, 0, PARTIAL_MODE_DISABLE, 4, ROTATE_0, MIRROR_NO, 1, + 0, 300, 300, 0, 50, 50, 0, 0, 0x23431}, + }; + + int idx, ret = 0, all = 0; + + mmio_write_32((void *)TOP_DDR_ADDR_MODE_REG, (1 << DAMR_REG_VD_REMAP_ADDR_39_32_OFFSET)); + mmio_write_32((void *)VC_REG_BASE, (mmio_read_32(VC_REG_BASE) | (0x1f))); + +#ifdef SUPPORT_INTERRUPT + request_irq(JPEG_CODEC_INTR_NUM, irq_handler_jpeg_codec, 0, "jpeg int", NULL); + BM_DBG_TRACE("irq num = %d\n", JPEG_INTRPT_REQ); +#endif + + for (idx = 0; idx < sizeof(allCfgs) / sizeof(dec_cfg_t); idx++) { + if (allCfgs[idx].mode == MODE_DEC) + ret = jpeg_dec(&allCfgs[idx], bs_addr, yuv_addr, size); +// else +// ret = jpeg_enc_slt_test(&allCfgs[idx]); + + if (ret) { + JLOG(NONE, "case %d, error\n", idx); + all = 1; + } else + JLOG(NONE, "case %d, success\n", idx); + } + + JLOG(NONE, "jpeg decode %s\n", all ? "failed" : "passed"); + return all; +} diff --git a/u-boot-2021.10/drivers/jpeg/jpeg.h b/u-boot-2021.10/drivers/jpeg/jpeg.h new file mode 100644 index 000000000..dd6e6a14c --- /dev/null +++ b/u-boot-2021.10/drivers/jpeg/jpeg.h @@ -0,0 +1,6 @@ +#ifndef _JPEG_H_ +#define _JPEG_H_ + +int jpeg_decoder(void *bs_addr, void *yuv_addr, int size); + +#endif diff --git a/u-boot-2021.10/drivers/jpeg/jpuapi.c b/u-boot-2021.10/drivers/jpeg/jpuapi.c new file mode 100644 index 000000000..50586bc3b --- /dev/null +++ b/u-boot-2021.10/drivers/jpeg/jpuapi.c @@ -0,0 +1,1834 @@ + +#include "jpuapi.h" +#include "jpuapifunc.h" + +#include "jpulog.h" +#include "dm/device.h" +#include "timer.h" + +static unsigned char sJpuCompInfoTable[5][24] = { + {00, 02, 02, 00, 00, 00, 01, 01, 01, 01, 01, 01, + 02, 01, 01, 01, 01, 01, 03, 00, 00, 00, 00, 00}, // 420 + {00, 02, 01, 00, 00, 00, 01, 01, 01, 01, 01, 01, + 02, 01, 01, 01, 01, 01, 03, 00, 00, 00, 00, 00}, // 422H + {00, 01, 02, 00, 00, 00, 01, 01, 01, 01, 01, 01, + 02, 01, 01, 01, 01, 01, 03, 00, 00, 00, 00, 00}, // 422V + {00, 01, 01, 00, 00, 00, 01, 01, 01, 01, 01, 01, + 02, 01, 01, 01, 01, 01, 03, 00, 00, 00, 00, 00}, // 444 + {00, 01, 01, 00, 00, 00, 01, 00, 00, 00, 00, 00, + 02, 00, 00, 00, 00, 00, 03, 00, 00, 00, 00, 00}, // 400 +}; + +int JPU_IsBusy(void) +{ + Uint32 val; + + val = JpuReadReg(MJPEG_PIC_STATUS_REG); + + if ((val & (1 << INT_JPU_DONE)) || (val & (1 << INT_JPU_ERROR))) + return 0; + + return 1; +} + +void JPU_ClrStatus(Uint32 val) +{ + if (val != 0) + JpuWriteReg(MJPEG_PIC_STATUS_REG, val); +} + +Uint32 JPU_GetStatus(void) +{ + return JpuReadReg(MJPEG_PIC_STATUS_REG); +} + +Uint32 JPU_IsInit(void) +{ + jpu_instance_pool_t *pjip; + + pjip = (jpu_instance_pool_t *)jdi_get_instance_pool(); + + if (!pjip) + return 0; + + return 1; +} + +Uint32 JPU_WaitInterrupt(int timeout) +{ + Uint32 reason = 0; +#ifdef SUPPORT_INTERRUPT + reason = jdi_wait_interrupt(timeout); + BM_DBG_TRACE("reason = 0x%X\n", reason); +#else + + reason = jdi_wait_interrupt(timeout); + BM_DBG_TRACE("reason = 0x%X\n", reason); + + JpgSetClockGate(1); + + if (reason != (Uint32)-1) + reason = JpuReadReg(MJPEG_PIC_STATUS_REG); + + JpgSetClockGate(0); +#endif + return reason; +} + +int JPU_GetOpenInstanceNum(void) +{ + jpu_instance_pool_t *pjip; + + pjip = (jpu_instance_pool_t *)jdi_get_instance_pool(); + if (!pjip) + return -1; + + return pjip->jpu_instance_num; +} + +JpgRet JPU_Init(void) +{ + jpu_instance_pool_t *pjip; + + if (jdi_init() < 0) + return JPG_RET_FAILURE; + + pjip = (jpu_instance_pool_t *)jdi_get_instance_pool(); + if (!pjip) + return JPG_RET_FAILURE; + + InitJpgInstancePool(); + JPU_SWReset(); + return JPG_RET_SUCCESS; +} + +void JPU_DeInit(void) +{ + jdi_release(); +} + +JpgRet JPU_GetVersionInfo(Uint32 *versionInfo) +{ + + if (JPU_IsInit() == 0) { + return JPG_RET_NOT_INITIALIZED; + } + + *versionInfo = API_VERSION; + + return JPG_RET_SUCCESS; +} + +JpgRet JPU_DecOpen(JpgDecHandle *pHandle, JpgDecOpenParam *pop) +{ + JpgInst *pJpgInst; + JpgDecInfo *pDecInfo; + JpgRet ret; + + ret = CheckJpgDecOpenParam(pop); + if (ret != JPG_RET_SUCCESS) { + return ret; + } + + ret = GetJpgInstance(&pJpgInst); + if (ret == JPG_RET_FAILURE) { + *pHandle = 0; + JpgLeaveLock(); + return JPG_RET_FAILURE; + } + + *pHandle = pJpgInst; + + pDecInfo = &pJpgInst->JpgInfo.decInfo; + memset(pDecInfo, 0x00, sizeof(JpgDecInfo)); + + pDecInfo->streamWrPtr = pop->bitstreamBuffer; + pDecInfo->streamRdPtr = pop->bitstreamBuffer; + + pDecInfo->streamBufStartAddr = pop->bitstreamBuffer; + pDecInfo->streamBufSize = pop->bitstreamBufferSize; + pDecInfo->streamBufEndAddr = + pop->bitstreamBuffer + pop->bitstreamBufferSize; + JpuWriteReg(MJPEG_BBC_BAS_ADDR_REG, pDecInfo->streamBufStartAddr); + JpuWriteReg(MJPEG_BBC_END_ADDR_REG, pDecInfo->streamBufEndAddr); + JpuWriteReg(MJPEG_BBC_RD_PTR_REG, pDecInfo->streamRdPtr); + JpuWriteReg(MJPEG_BBC_WR_PTR_REG, pDecInfo->streamWrPtr); + JpuWriteReg(MJPEG_BBC_STRM_CTRL_REG, 0); + + pDecInfo->pBitStream = pop->pBitStream; + pDecInfo->streamEndian = pop->streamEndian; + pDecInfo->frameEndian = pop->frameEndian; + pDecInfo->chroma_interleave = pop->chroma_interleave; + pDecInfo->packedFormat = pop->packedFormat; + pDecInfo->roiEnable = pop->roiEnable; + pDecInfo->roiWidth = pop->roiWidth; + pDecInfo->roiHeight = pop->roiHeight; + pDecInfo->roiOffsetX = pop->roiOffsetX; + pDecInfo->roiOffsetY = pop->roiOffsetY; + + return JPG_RET_SUCCESS; +} + +JpgRet JPU_DecClose(JpgDecHandle handle) +{ + JpgInst *pJpgInst; + JpgRet ret; + + ret = CheckJpgInstValidity(handle); + if (ret != JPG_RET_SUCCESS) + return ret; + + pJpgInst = handle; + + JpgEnterLock(); + FreeJpgInstance(pJpgInst); + JpgLeaveLock(); + + return JPG_RET_SUCCESS; +} + +JpgRet JPU_DecGetInitialInfo(JpgDecHandle handle, JpgDecInitialInfo *info) +{ + JpgInst *pJpgInst; + JpgDecInfo *pDecInfo; + JpgRet ret; + + ret = CheckJpgInstValidity(handle); + if (ret != JPG_RET_SUCCESS) { + BM_DBG_ERR("CheckJpgInstValidity\n"); + return ret; + } + + if (info == 0) { + return JPG_RET_INVALID_PARAM; + } + pJpgInst = handle; + pDecInfo = &pJpgInst->JpgInfo.decInfo; + + if (JpegDecodeHeader(pDecInfo) <= 0) { + BM_DBG_ERR("JpegDecodeHeader\n"); + return JPG_RET_FAILURE; + } + + info->picWidth = pDecInfo->picWidth; + info->picHeight = pDecInfo->picHeight; + info->minFrameBufferCount = 1; + info->sourceFormat = pDecInfo->format; + info->ecsPtr = pDecInfo->ecsPtr; + + JLOG(ERR, "pDecInfo->format %d\n", pDecInfo->format); + + pDecInfo->initialInfoObtained = 1; + pDecInfo->minFrameBufferNum = 1; + +#ifdef MJPEG_ERROR_CONCEAL + pDecInfo->curRstIdx = 0; + pDecInfo->nextRstIdx = -1; +#endif + + if (pDecInfo->packedFormat == PACKED_FORMAT_444 && + pDecInfo->format != FORMAT_444) { + return JPG_RET_INVALID_PARAM; + } + + if (pDecInfo->roiEnable) { + pDecInfo->roiMcuWidth = pDecInfo->roiWidth / pDecInfo->mcuWidth; + pDecInfo->roiMcuHeight = pDecInfo->roiHeight / pDecInfo->mcuHeight; + pDecInfo->roiMcuOffsetX = pDecInfo->roiOffsetX / pDecInfo->mcuWidth; + pDecInfo->roiMcuOffsetY = pDecInfo->roiOffsetY / pDecInfo->mcuHeight; + + if (pDecInfo->roiOffsetX > pDecInfo->alignedWidth || + pDecInfo->roiOffsetY > pDecInfo->alignedHeight || + pDecInfo->roiOffsetX + pDecInfo->roiWidth > pDecInfo->alignedWidth || + pDecInfo->roiOffsetY + pDecInfo->roiHeight > pDecInfo->alignedHeight) + return JPG_RET_INVALID_PARAM; + + if (((pDecInfo->roiOffsetX + pDecInfo->roiWidth) < pDecInfo->mcuWidth) || + ((pDecInfo->roiOffsetY + pDecInfo->roiHeight) < pDecInfo->mcuHeight)) + return JPG_RET_INVALID_PARAM; + + info->roiFrameWidth = pDecInfo->roiMcuWidth * pDecInfo->mcuWidth; + info->roiFrameHeight = pDecInfo->roiMcuHeight * pDecInfo->mcuHeight; + info->roiFrameOffsetX = pDecInfo->roiMcuOffsetX * pDecInfo->mcuWidth; + info->roiFrameOffsetY = pDecInfo->roiMcuOffsetY * pDecInfo->mcuHeight; + info->roiMCUSize = pDecInfo->mcuWidth; + } + info->colorComponents = pDecInfo->compNum; + + return JPG_RET_SUCCESS; +} + +JpgRet JPU_DecRegisterFrameBuffer(JpgDecHandle handle, FrameBuffer *bufArray, + int num, int strideY, int strideC) +{ + JpgInst *pJpgInst; + JpgDecInfo *pDecInfo; + JpgRet ret; + + ret = CheckJpgInstValidity(handle); + if (ret != JPG_RET_SUCCESS) + return ret; + + pJpgInst = handle; + pDecInfo = &pJpgInst->JpgInfo.decInfo; + + if (!pDecInfo->initialInfoObtained) { + return JPG_RET_WRONG_CALL_SEQUENCE; + } + + if (bufArray == 0) { + return JPG_RET_INVALID_FRAME_BUFFER; + } + + if (num < pDecInfo->minFrameBufferNum) { + return JPG_RET_INSUFFICIENT_FRAME_BUFFERS; + } + if (pDecInfo->usePartial && pDecInfo->bufNum == 0) { + return JPG_RET_INSUFFICIENT_FRAME_BUFFERS; + } + if (pDecInfo->usePartial && num < pDecInfo->bufNum) { + return JPG_RET_INSUFFICIENT_FRAME_BUFFERS; + } + + if (!pDecInfo->roiEnable) { + if (strideY < pDecInfo->picWidth >> 3 || strideY % 8 != 0) + return JPG_RET_INVALID_STRIDE; + } + + pDecInfo->frameBufPool = bufArray; + pDecInfo->numFrameBuffers = num; + pDecInfo->stride = strideY; + pDecInfo->strideY = strideY; + pDecInfo->strideC = strideC; + + return JPG_RET_SUCCESS; +} + +JpgRet JPU_DecGetBitstreamBuffer(JpgDecHandle handle, PhysicalAddress *prdPrt, + PhysicalAddress *pwrPtr, int *size) +{ + JpgInst *pJpgInst; + JpgDecInfo *pDecInfo; + JpgRet ret; + PhysicalAddress rdPtr; + PhysicalAddress wrPtr; + int room; + + ret = CheckJpgInstValidity(handle); + if (ret != JPG_RET_SUCCESS) + return ret; + + if (prdPrt == 0 || pwrPtr == 0 || size == 0) { + return JPG_RET_INVALID_PARAM; + } + + pJpgInst = handle; + pDecInfo = &pJpgInst->JpgInfo.decInfo; + + if (GetJpgPendingInst() == pJpgInst) { + rdPtr = JpuReadReg(MJPEG_BBC_RD_PTR_REG); + } else { + rdPtr = pDecInfo->streamRdPtr; + } + + wrPtr = pDecInfo->streamWrPtr; + + if (wrPtr == pDecInfo->streamBufStartAddr) { + if (pDecInfo->frameOffset == 0) { + room = (pDecInfo->streamBufEndAddr -= pDecInfo->streamBufStartAddr); + } else { + room = (pDecInfo->frameOffset); + } + } else { + room = (pDecInfo->streamBufEndAddr - wrPtr); + } + + room = ((room >> 9) << 9); // multiple of 512 + + *prdPrt = rdPtr; + *pwrPtr = wrPtr; + + *size = room; + + return JPG_RET_SUCCESS; +} + +JpgRet JPU_DecUpdateBitstreamBuffer(JpgDecHandle handle, int size) +{ + JpgInst *pJpgInst; + JpgDecInfo *pDecInfo; + PhysicalAddress wrPtr; + PhysicalAddress rdPtr; + JpgRet ret; + int val = 0; + + ret = CheckJpgInstValidity(handle); + if (ret != JPG_RET_SUCCESS) + return ret; + + pJpgInst = handle; + pDecInfo = &pJpgInst->JpgInfo.decInfo; + wrPtr = pDecInfo->streamWrPtr; + + if (size == 0) { + val = (wrPtr - pDecInfo->streamBufStartAddr) / 256; + if ((wrPtr - pDecInfo->streamBufStartAddr) % 256) + val = val + 1; + if (GetJpgPendingInst() == pJpgInst) + JpuWriteReg(MJPEG_BBC_STRM_CTRL_REG, (1 << 31 | val)); + pDecInfo->streamEndflag = 1; + return JPG_RET_SUCCESS; + } + + JpgSetClockGate(1); + + wrPtr = pDecInfo->streamWrPtr; + wrPtr += size; + + if (wrPtr == pDecInfo->streamBufEndAddr) { + wrPtr = pDecInfo->streamBufStartAddr; + } + + pDecInfo->streamWrPtr = wrPtr; + + if (GetJpgPendingInst() == pJpgInst) { + rdPtr = JpuReadReg(MJPEG_BBC_RD_PTR_REG); + + if (rdPtr == (pDecInfo->streamBufEndAddr & 0xffffffff)) { + JpuWriteReg(MJPEG_BBC_CUR_POS_REG, 0); + JpuWriteReg(MJPEG_GBU_TT_CNT_REG, 0); + JpuWriteReg(MJPEG_GBU_TT_CNT_REG + 4, 0); + } + + JpuWriteReg(MJPEG_BBC_WR_PTR_REG, wrPtr); + if (wrPtr == pDecInfo->streamBufStartAddr) { + JpuWriteReg(MJPEG_BBC_END_ADDR_REG, pDecInfo->streamBufEndAddr); + } else { + JpuWriteReg(MJPEG_BBC_END_ADDR_REG, wrPtr); + } + } else { + rdPtr = pDecInfo->streamRdPtr; + } + + pDecInfo->streamRdPtr = rdPtr; + + JpgSetClockGate(0); + return JPG_RET_SUCCESS; +} + +JpgRet JPU_SWReset(void) +{ + Uint32 val; + PhysicalAddress streamBufStartAddr; + PhysicalAddress streamBufEndAddr; + PhysicalAddress streamWrPtr; + PhysicalAddress streamRdPtr; + + JpgEnterLock(); + + streamBufStartAddr = JpuReadReg(MJPEG_BBC_BAS_ADDR_REG); + streamBufEndAddr = JpuReadReg(MJPEG_BBC_END_ADDR_REG); + streamWrPtr = JpuReadReg(MJPEG_BBC_RD_PTR_REG); + streamRdPtr = JpuReadReg(MJPEG_BBC_WR_PTR_REG); + + JpuWriteReg(MJPEG_PIC_START_REG, (1 << JPG_START_INIT)); + + do { + val = JpuReadReg(MJPEG_PIC_START_REG); + } while ((val & (1 << JPG_START_INIT)) == (1 << JPG_START_INIT)); + + JpuWriteReg(MJPEG_BBC_BAS_ADDR_REG, streamBufStartAddr); + JpuWriteReg(MJPEG_BBC_END_ADDR_REG, streamBufEndAddr); + JpuWriteReg(MJPEG_BBC_RD_PTR_REG, streamRdPtr); + JpuWriteReg(MJPEG_BBC_WR_PTR_REG, streamWrPtr); + + JpgLeaveLock(); + + return JPG_RET_SUCCESS; +} + +JpgRet JPU_HWReset(void) +{ + if (jdi_hw_reset() < 0) + return JPG_RET_FAILURE; + + return JPG_RET_SUCCESS; +} + +JpgRet JPU_DecIssueStop(JpgDecHandle handle) +{ + JpgInst *pJpgInst; + // JpgDecInfo * pDecInfo; + JpgRet ret; + + ret = CheckJpgInstValidity(handle); + if (ret != JPG_RET_SUCCESS) + return ret; + + pJpgInst = handle; + // pDecInfo = &pJpgInst->JpgInfo.decInfo; + + if (pJpgInst != GetJpgPendingInst()) { + return JPG_RET_WRONG_CALL_SEQUENCE; + } + + JpgSetClockGate(1); + JpuWriteReg(MJPEG_PIC_START_REG, 1 << JPG_START_STOP); + JpgSetClockGate(0); + return JPG_RET_SUCCESS; +} + +JpgRet JPU_DecCompleteStop(JpgDecHandle handle) +{ + JpgInst *pJpgInst; + // JpgDecInfo * pDecInfo; + JpgRet ret; + Uint32 val; + + ret = CheckJpgInstValidity(handle); + if (ret != JPG_RET_SUCCESS) + return ret; + + pJpgInst = handle; + // pDecInfo = &pJpgInst->JpgInfo.decInfo; + + if (pJpgInst != GetJpgPendingInst()) { + return JPG_RET_WRONG_CALL_SEQUENCE; + } + + JpgSetClockGate(1); + val = JpuReadReg(MJPEG_PIC_STATUS_REG); + + if (val & (1 << INT_JPU_BIT_BUF_STOP)) { + SetJpgPendingInst(0); + JpgSetClockGate(0); + } else { + JpgSetClockGate(0); + return JPG_RET_WRONG_CALL_SEQUENCE; + } + + return JPG_RET_SUCCESS; +} + +JpgRet JPU_DecSetRdPtr(JpgDecHandle handle, PhysicalAddress addr, int updateWrPtr) +{ + JpgInst *pJpgInst; + JpgDecInfo *pDecInfo; + JpgRet ret; + + ret = CheckJpgInstValidity(handle); + if (ret != JPG_RET_SUCCESS) + return ret; + + pJpgInst = handle; + pDecInfo = &pJpgInst->JpgInfo.decInfo; + + JpgEnterLock(); + + if (GetJpgPendingInst()) { + JpgLeaveLock(); + return JPG_RET_FRAME_NOT_COMPLETE; + } + + pDecInfo->streamRdPtr = addr; + if (updateWrPtr) + pDecInfo->streamWrPtr = addr; + + pDecInfo->frameOffset = addr - pDecInfo->streamBufStartAddr; + pDecInfo->consumeByte = 0; + + JpuWriteReg(MJPEG_BBC_RD_PTR_REG, pDecInfo->streamRdPtr); + + JpgLeaveLock(); + + return JPG_RET_SUCCESS; +} + +JpgRet JPU_DecStartOneFrame(JpgDecHandle handle, JpgDecParam *param) +{ + JpgInst *pJpgInst; + JpgDecInfo *pDecInfo; + Uint32 rotMir; + JpgRet ret; + Uint32 val; + int i; + + ret = CheckJpgInstValidity(handle); + if (ret != JPG_RET_SUCCESS) + return ret; + + pJpgInst = handle; + pDecInfo = &pJpgInst->JpgInfo.decInfo; + + if (pDecInfo->frameBufPool == 0) { // This means frame buffers have not been registered. + return JPG_RET_WRONG_CALL_SEQUENCE; + } + + rotMir = 0; + if (pDecInfo->rotationEnable) { + rotMir |= 0x10; // Enable rotator + switch (pDecInfo->rotationAngle) { + case 0: + rotMir |= 0x0; + break; + + case 90: + rotMir |= 0x1; + break; + + case 180: + rotMir |= 0x2; + break; + + case 270: + rotMir |= 0x3; + break; + } + } + + if (pDecInfo->mirrorEnable) { + rotMir |= 0x10; // Enable rotator + switch (pDecInfo->mirrorDirection) { + case MIRDIR_NONE: + rotMir |= 0x0; + break; + + case MIRDIR_VER: + rotMir |= 0x4; + break; + + case MIRDIR_HOR: + rotMir |= 0x8; + break; + + case MIRDIR_HOR_VER: + rotMir |= 0xc; + break; + } + } + JpgEnterLock(); + + if (GetJpgPendingInst()) { + JpgLeaveLock(); + return JPG_RET_FRAME_NOT_COMPLETE; + } + +#ifdef MJPEG_ERROR_CONCEAL + // Error Concealment + if (pDecInfo->errInfo.bError) { + // error conceal main function + val = JpegDecodeConcealError(pDecInfo); + if (val == -1) { + // stream buffer wrap around in error cases. + pDecInfo->frameOffset = 0; + pDecInfo->nextOffset = 0; + + // end of stream + if (pDecInfo->streamEndflag == 1) { + pDecInfo->frameOffset = -1; + SetJpgPendingInst(pJpgInst); + return JPG_RET_EOS; + } + // request data + JpgLeaveLock(); + return JPG_RET_BIT_EMPTY; + } + + // init GBU + JpuWriteReg(MJPEG_GBU_TT_CNT_REG, 0); + JpuWriteReg(MJPEG_GBU_TT_CNT_REG + 4, 0); + + val = pDecInfo->huffAcIdx << 10 | pDecInfo->huffDcIdx << 7 | pDecInfo->userHuffTab << 6; + val |= (JPU_CHECK_WRITE_RESPONSE_BVALID_SIGNAL << 2) | 0; + JpuWriteReg(MJPEG_PIC_CTRL_REG, val); + val = pDecInfo->mcuBlockNum << 16 | pDecInfo->compNum << 12; + val |= pDecInfo->compInfo[0] << 8 | pDecInfo->compInfo[1] << 4 | pDecInfo->compInfo[2]; + JpuWriteReg(MJPEG_MCU_INFO_REG, val); + JpuWriteReg(MJPEG_RST_INTVAL_REG, pDecInfo->rstIntval); + + JpgDecGramSetup(pDecInfo); + + JpuWriteReg(MJPEG_DPCM_DIFF_Y_REG, 0); + JpuWriteReg(MJPEG_DPCM_DIFF_CB_REG, 0); + JpuWriteReg(MJPEG_DPCM_DIFF_CR_REG, 0); + + JpuWriteReg(MJPEG_GBU_FF_RPTR_REG, pDecInfo->bitPtr); + JpuWriteReg(MJPEG_GBU_CTRL_REG, 3); + + val = (pDecInfo->setPosX << 16) | (pDecInfo->setPosY); + JpuWriteReg(MJPEG_PIC_SETMB_REG, val); + JpuWriteReg(MJPEG_PIC_START_REG, (1 << JPG_START_PIC)); + + SetJpgPendingInst(pJpgInst); + return JPG_RET_SUCCESS; + } +#endif + + if (pDecInfo->frameOffset < 0) { + SetJpgPendingInst(pJpgInst); + return JPG_RET_EOS; + } + + val = JpegDecodeHeader(pDecInfo); + if (val == 0) { + JpgLeaveLock(); + return JPG_RET_FAILURE; + } + + if (val == -2) { // wrap around case + pDecInfo->frameOffset = 0; + pDecInfo->ecsPtr = 0; +#ifdef MJPEG_ERROR_CONCEAL + pDecInfo->nextOffset = 0; +#endif + val = JpegDecodeHeader(pDecInfo); + if (val == 0) { + JpgLeaveLock(); + return JPG_RET_FAILURE; + } + } + + if (val == -1) { // stream empty case + if (pDecInfo->streamEndflag == 1) { + SetJpgPendingInst(pJpgInst); + pDecInfo->frameOffset = -1; + return JPG_RET_EOS; + } + JpgLeaveLock(); + return JPG_RET_BIT_EMPTY; + } + + if (pDecInfo->streamRdPtr == pDecInfo->streamBufEndAddr) { + JpuWriteReg(MJPEG_BBC_CUR_POS_REG, 0); + JpuWriteReg(MJPEG_GBU_TT_CNT_REG, 0); + JpuWriteReg(MJPEG_GBU_TT_CNT_REG + 4, 0); + } + + JpuWriteReg(MJPEG_BBC_WR_PTR_REG, pDecInfo->streamWrPtr); + if (pDecInfo->streamWrPtr == pDecInfo->streamBufStartAddr) { + JpuWriteReg(MJPEG_BBC_END_ADDR_REG, pDecInfo->streamBufEndAddr); + } else { + JpuWriteReg(MJPEG_BBC_END_ADDR_REG, pDecInfo->streamWrPtr); + } + + JLOG(INFO, "pDecInfo->streamBufStartAddr %p\n", + (void *)pDecInfo->streamBufStartAddr); + + JpuWriteReg(MJPEG_BBC_BAS_ADDR_REG, pDecInfo->streamBufStartAddr); + + if (pDecInfo->streamEndflag == 1) { + val = JpuReadReg(MJPEG_BBC_STRM_CTRL_REG); + if ((val & (1 << 31)) == 0) { + val = (pDecInfo->streamWrPtr - + pDecInfo->streamBufStartAddr) / + 256; + if ((pDecInfo->streamWrPtr - + pDecInfo->streamBufStartAddr) % + 256) + val = val + 1; + + JpuWriteReg(MJPEG_BBC_STRM_CTRL_REG, (1 << 31 | val)); + } + } else { + JpuWriteReg(MJPEG_BBC_STRM_CTRL_REG, 0); + } + + JpuWriteReg(MJPEG_GBU_TT_CNT_REG, 0); + JpuWriteReg(MJPEG_GBU_TT_CNT_REG + 4, 0); + JpuWriteReg(MJPEG_PIC_ERRMB_REG, 0); + val = pDecInfo->huffAcIdx << 10 | pDecInfo->huffDcIdx << 7 | pDecInfo->userHuffTab << 6; + val |= (JPU_CHECK_WRITE_RESPONSE_BVALID_SIGNAL << 2) | pDecInfo->usePartial); + JpuWriteReg(MJPEG_PIC_CTRL_REG, val); + + JpuWriteReg(MJPEG_PIC_SIZE_REG, (pDecInfo->alignedWidth << 16) | pDecInfo->alignedHeight); + JpuWriteReg(MJPEG_ROT_INFO_REG, 0); + JpuWriteReg(MJPEG_OP_INFO_REG, pDecInfo->lineNum << 16 | pDecInfo->bufNum << 3 | pDecInfo->busReqNum); + val = pDecInfo->mcuBlockNum << 16 | pDecInfo->compNum << 12; + val |= pDecInfo->compInfo[0] << 8 | pDecInfo->compInfo[1] << 4 | pDecInfo->compInfo[2]; + JpuWriteReg(MJPEG_MCU_INFO_REG, val); + + if (pDecInfo->chroma_interleave == 0) + val = 0; + else if (pDecInfo->chroma_interleave == 1) + val = 2; + else + val = 3; + if (pDecInfo->packedFormat == PACKED_FORMAT_NONE) { + val |= (pDecInfo->frameEndian << 6) | (0 << 5) | (0 << 4); + JpuWriteReg(MJPEG_DPB_CONFIG_REG, val); + } else if (pDecInfo->packedFormat == PACKED_FORMAT_444) { + val |= (pDecInfo->frameEndian << 6) | (1 << 5) | (0 << 4) | (0 << 2); + JpuWriteReg(MJPEG_DPB_CONFIG_REG, val); + } else { + val |= (pDecInfo->frameEndian << 6) | (0 << 5) | (1 << 4) | ((pDecInfo->packedFormat - 1) << 2); + JpuWriteReg(MJPEG_DPB_CONFIG_REG, val); + } + JpuWriteReg(MJPEG_RST_INTVAL_REG, pDecInfo->rstIntval); + if (param) { + if (param->scaleDownRatioWidth > 0) + pDecInfo->iHorScaleMode = param->scaleDownRatioWidth; + if (param->scaleDownRatioHeight > 0) + pDecInfo->iVerScaleMode = param->scaleDownRatioHeight; + } + if (pDecInfo->iHorScaleMode | pDecInfo->iVerScaleMode) + val = ((pDecInfo->iHorScaleMode & 0x3) << 2) | + ((pDecInfo->iVerScaleMode & 0x3)) | 0x10; + else { + val = 0; + } + JpuWriteReg(MJPEG_SCL_INFO_REG, val); + + if (pDecInfo->userHuffTab) { + if (!JpgDecHuffTabSetUp(pDecInfo)) { + JpgLeaveLock(); + return JPG_RET_INVALID_PARAM; + } + } + + if (!JpgDecQMatTabSetUp(pDecInfo)) { + JpgLeaveLock(); + return JPG_RET_INVALID_PARAM; + } + + JpgDecGramSetup(pDecInfo); + + JpuWriteReg(MJPEG_RST_INDEX_REG, 0); // RST index at the beginning. + JpuWriteReg(MJPEG_RST_COUNT_REG, 0); + + JpuWriteReg(MJPEG_DPCM_DIFF_Y_REG, 0); + JpuWriteReg(MJPEG_DPCM_DIFF_CB_REG, 0); + JpuWriteReg(MJPEG_DPCM_DIFF_CR_REG, 0); + + JpuWriteReg(MJPEG_GBU_FF_RPTR_REG, pDecInfo->bitPtr); + JpuWriteReg(MJPEG_GBU_CTRL_REG, 3); + + JpuWriteReg(MJPEG_ROT_INFO_REG, rotMir); + + if (rotMir & 1) { + pDecInfo->format = (pDecInfo->format == FORMAT_422) + ? FORMAT_224 + : (pDecInfo->format == FORMAT_224) + ? FORMAT_422 + : pDecInfo->format; + } + + if (rotMir & 0x10) { + JpuWriteReg(MJPEG_DPB_BASE00_REG, pDecInfo->rotatorOutput.bufY); + JpuWriteReg(MJPEG_DPB_BASE01_REG, + pDecInfo->rotatorOutput.bufCb); + JpuWriteReg(MJPEG_DPB_BASE02_REG, + pDecInfo->rotatorOutput.bufCr); + } else if (pDecInfo->usePartial) { + PhysicalAddress addr; + + val = (pDecInfo->frameIdx % (pDecInfo->numFrameBuffers / pDecInfo->bufNum)); + for (i = 0; i < pDecInfo->bufNum; i++) { + addr = pDecInfo->frameBufPool[(val * pDecInfo->bufNum) + i].bufY + JpuWriteReg(MJPEG_DPB_BASE00_REG + (i * 12), addr); + addr = pDecInfo->frameBufPool[(val * pDecInfo->bufNum) + i].bufCb; + JpuWriteReg(MJPEG_DPB_BASE01_REG + (i * 12), addr); + addr = pDecInfo->frameBufPool[(val * pDecInfo->bufNum) + i].bufCr; + JpuWriteReg(MJPEG_DPB_BASE02_REG + (i * 12), addr); + } + } else { + val = (pDecInfo->frameIdx % pDecInfo->numFrameBuffers); + JpuWriteReg(MJPEG_DPB_BASE00_REG, pDecInfo->frameBufPool[val].bufY); + JpuWriteReg(MJPEG_DPB_BASE01_REG, pDecInfo->frameBufPool[val].bufCb); + JpuWriteReg(MJPEG_DPB_BASE02_REG, pDecInfo->frameBufPool[val].bufCr); + } + + if (pDecInfo->rotationEnable) { + JpuWriteReg(MJPEG_DPB_YSTRIDE_REG, pDecInfo->rotatorStride); + val = (pDecInfo->format == FORMAT_420 || + pDecInfo->format == FORMAT_422 || + pDecInfo->format == FORMAT_400) + ? 2 + : 1; + if (pDecInfo->chroma_interleave) + JpuWriteReg(MJPEG_DPB_CSTRIDE_REG, (pDecInfo->rotatorStride / (int)val) * 2); + else + JpuWriteReg(MJPEG_DPB_CSTRIDE_REG, pDecInfo->rotatorStride / (int)val); + } else { + + CVI_JPG_DBG("packedFormat = %d\n", pDecInfo->packedFormat); + if (pDecInfo->packedFormat == PACKED_FORMAT_NONE && pDecInfo->format == FORMAT_420) { + CVI_JPG_DBG("strideY = %d, strideC = %d\n", pDecInfo->strideY, pDecInfo->strideC); + JpuWriteReg(MJPEG_DPB_YSTRIDE_REG, pDecInfo->strideY); + JpuWriteReg(MJPEG_DPB_CSTRIDE_REG, pDecInfo->strideC); + } else { + JpuWriteReg(MJPEG_DPB_YSTRIDE_REG, pDecInfo->stride); + if (pDecInfo->chroma_interleave) + JpuWriteReg(MJPEG_DPB_CSTRIDE_REG, (pDecInfo->stride / (int)val) * 2); + else + JpuWriteReg(MJPEG_DPB_CSTRIDE_REG, pDecInfo->stride / (int)val); + } + } + if (pDecInfo->roiEnable) { + JpuWriteReg(MJPEG_CLP_INFO_REG, 1); + JpuWriteReg(MJPEG_CLP_BASE_REG, pDecInfo->roiOffsetX << 16 | pDecInfo->roiOffsetY); // pixel unit + val = (pDecInfo->roiMcuWidth * pDecInfo->mcuWidth) << 16; + val |= pDecInfo->roiMcuHeight * pDecInfo->mcuHeight; + JpuWriteReg(MJPEG_CLP_SIZE_REG, val); // pixel Unit + } else { + JpuWriteReg(MJPEG_CLP_INFO_REG, 0); + } + + if (pJpgInst->loggingEnable) + jdi_log(JDI_LOG_CMD_PICRUN, 1); + + BM_DBG_FLOW("JPG_START_PIC\n"); + +#ifdef PROFILE_PERFORMANCE + timer_meter_start(); +#endif + + JpuWriteReg(MJPEG_PIC_STATUS_REG, JpuReadReg(MJPEG_PIC_STATUS_REG)); + + JpuWriteReg(MJPEG_PIC_START_REG, (1 << JPG_START_PIC)); + + SetJpgPendingInst(pJpgInst); + + return JPG_RET_SUCCESS; +} + +JpgRet JPU_DecGetOutputInfo(JpgDecHandle handle, JpgDecOutputInfo *info) +{ + JpgInst *pJpgInst; + JpgDecInfo *pDecInfo; + JpgRet ret; + Uint32 val = 0; + + ret = CheckJpgInstValidity(handle); + if (ret != JPG_RET_SUCCESS) { + SetJpgPendingInst(0); + JpgLeaveLock(); + return ret; + } + + if (info == 0) { + SetJpgPendingInst(0); + JpgLeaveLock(); + return JPG_RET_INVALID_PARAM; + } + + pJpgInst = handle; + pDecInfo = &pJpgInst->JpgInfo.decInfo; + + val = JpuReadReg(MJPEG_PIC_STATUS_REG); + + if (pJpgInst != GetJpgPendingInst()) { + SetJpgPendingInst(0); + JpgLeaveLock(); + return JPG_RET_WRONG_CALL_SEQUENCE; + } + + if (pDecInfo->frameOffset < 0) { + info->numOfErrMBs = 0; + info->decodingSuccess = 1; + info->indexFrameDisplay = -1; + SetJpgPendingInst(0); + JpgLeaveLock(); + return JPG_RET_SUCCESS; + } + + if (pDecInfo->roiEnable) { + info->decPicWidth = pDecInfo->roiMcuWidth * pDecInfo->mcuWidth; + info->decPicHeight = + pDecInfo->roiMcuHeight * pDecInfo->mcuHeight; + } else { + info->decPicWidth = pDecInfo->alignedWidth; + info->decPicHeight = pDecInfo->alignedHeight; + } + + info->decPicWidth >>= pDecInfo->iHorScaleMode; + info->decPicHeight >>= pDecInfo->iVerScaleMode; + + info->indexFrameDisplay = + (pDecInfo->frameIdx % pDecInfo->numFrameBuffers); +#ifdef MJPEG_ERROR_CONCEAL + info->consumedByte = + pDecInfo->gbuStartPtr + (JpuReadReg(MJPEG_GBU_TT_CNT_REG)) / 8; +#else + info->consumedByte = (JpuReadReg(MJPEG_GBU_TT_CNT_REG)) / 8; +#endif + pDecInfo->streamRdPtr = JpuReadReg(MJPEG_BBC_RD_PTR_REG); + pDecInfo->consumeByte = info->consumedByte - 16 - pDecInfo->ecsPtr; + info->bytePosFrameStart = pDecInfo->frameOffset; + info->ecsPtr = pDecInfo->ecsPtr; + + pDecInfo->ecsPtr = 0; + pDecInfo->frameIdx++; + + val = JpuReadReg(MJPEG_PIC_STATUS_REG); + + if (val & (1 << INT_JPU_DONE)) { + info->decodingSuccess = 1; + info->numOfErrMBs = 0; + +#ifdef MJPEG_ERROR_CONCEAL + pDecInfo->errInfo.bError = 0; + pDecInfo->nextOffset = 0; + pDecInfo->gbuStartPtr = 0; +#endif + } else if (val & (1 << INT_JPU_ERROR)) { + + info->numOfErrMBs = JpuReadReg(MJPEG_PIC_ERRMB_REG); + info->decodingSuccess = 0; + +#ifdef MJPEG_ERROR_CONCEAL + // info->numOfErrMBs = + // JpuReadReg(MJPEG_PIC_ERRMB_REG); + pDecInfo->errInfo.bError = 1; + pDecInfo->errInfo.errPosY = info->numOfErrMBs & 0xFFF; + pDecInfo->errInfo.errPosX = (info->numOfErrMBs >> 12) & 0xFFF; + + // set search point to find next rstMarker from origin of frame + // buffer by host + pDecInfo->nextOffset = (info->consumedByte) & (~7); + + // prevent to find same position. + if (pDecInfo->currOffset == pDecInfo->nextOffset) + pDecInfo->nextOffset += JPU_GBU_SIZE; +#endif + } + + if (val != 0) + JpuWriteReg(MJPEG_PIC_STATUS_REG, val); + + if (pJpgInst->loggingEnable) { + jdi_log(JDI_LOG_CMD_PICRUN, 0); + } + + SetJpgPendingInst(0); + JpgLeaveLock(); + + return JPG_RET_SUCCESS; +} + +JpgRet JPU_DecGiveCommand(JpgDecHandle handle, JpgCommand cmd, void *param) +{ + JpgInst *pJpgInst; + JpgDecInfo *pDecInfo; + JpgRet ret; + + ret = CheckJpgInstValidity(handle); + if (ret != JPG_RET_SUCCESS) + return ret; + + pJpgInst = handle; + pDecInfo = &pJpgInst->JpgInfo.decInfo; + switch (cmd) { + case ENABLE_JPG_ROTATION: { + if (pDecInfo->roiEnable) { + return JPG_RET_INVALID_PARAM; + } + + if (pDecInfo->rotatorStride == 0) { + return JPG_RET_ROTATOR_STRIDE_NOT_SET; + } + pDecInfo->rotationEnable = 1; + break; + } + + case DISABLE_JPG_ROTATION: { + pDecInfo->rotationEnable = 0; + break; + } + + case ENABLE_JPG_MIRRORING: { + if (pDecInfo->rotatorStride == 0) { + return JPG_RET_ROTATOR_STRIDE_NOT_SET; + } + pDecInfo->mirrorEnable = 1; + break; + } + case DISABLE_JPG_MIRRORING: { + pDecInfo->mirrorEnable = 0; + break; + } + case SET_JPG_MIRROR_DIRECTION: { + + JpgMirrorDirection mirDir; + + if (param == 0) { + return JPG_RET_INVALID_PARAM; + } + mirDir = *(JpgMirrorDirection *)param; + if (!(mirDir >= MIRDIR_NONE && mirDir <= MIRDIR_HOR_VER)) { + return JPG_RET_INVALID_PARAM; + } + pDecInfo->mirrorDirection = mirDir; + + break; + } + case SET_JPG_ROTATION_ANGLE: { + int angle; + + if (param == 0) { + return JPG_RET_INVALID_PARAM; + } + + angle = *(int *)param; + if (angle != 0 && angle != 90 && angle != 180 && angle != 270) { + return JPG_RET_INVALID_PARAM; + } + + pDecInfo->rotationAngle = angle; + break; + } + + case SET_JPG_ROTATOR_OUTPUT: { + FrameBuffer *frame; + + if (param == 0) { + return JPG_RET_INVALID_PARAM; + } + frame = (FrameBuffer *)param; + pDecInfo->rotatorOutput = *frame; + pDecInfo->rotatorOutputValid = 1; + break; + } + + case SET_JPG_ROTATOR_STRIDE: { + int stride; + + if (param == 0) { + return JPG_RET_INVALID_PARAM; + } + stride = *(int *)param; + if (stride % 8 != 0 || stride == 0) { + return JPG_RET_INVALID_STRIDE; + } + + if (pDecInfo->rotationAngle == 90 || + pDecInfo->rotationAngle == 270) { + if (pDecInfo->alignedHeight > stride) { + return JPG_RET_INVALID_STRIDE; + } + } else { + if (pDecInfo->alignedWidth > stride) { + return JPG_RET_INVALID_STRIDE; + } + } + + pDecInfo->rotatorStride = stride; + break; + } + case SET_JPG_SCALE_HOR: { + int scale; + + scale = *(int *)param; + if (pDecInfo->alignedWidth < 128 || + pDecInfo->alignedHeight < 128) { + if (scale) { + return JPG_RET_INVALID_PARAM; + } + } + + pDecInfo->iHorScaleMode = scale; + break; + } + case SET_JPG_SCALE_VER: { + int scale; + + scale = *(int *)param; + if (pDecInfo->alignedWidth < 128 || + pDecInfo->alignedHeight < 128) { + if (scale) { + return JPG_RET_INVALID_PARAM; + } + } + pDecInfo->iVerScaleMode = scale; + break; + } + case SET_JPG_USE_PARTIAL_MODE: { + int enable; + + enable = *(int *)param; + pDecInfo->usePartial = enable; + + break; + } + case SET_JPG_PARTIAL_FRAME_NUM: { + int frame; + + if (pDecInfo->stride != 0) { + return JPG_RET_WRONG_CALL_SEQUENCE; + } + + frame = *(int *)param; + pDecInfo->bufNum = frame; + + break; + } + case SET_JPG_PARTIAL_LINE_NUM: { + int line; + + if (pDecInfo->stride != 0) { + return JPG_RET_WRONG_CALL_SEQUENCE; + } + line = *(int *)param; + pDecInfo->lineNum = line; + + break; + } + case ENABLE_LOGGING: { + pJpgInst->loggingEnable = 1; + } break; + case DISABLE_LOGGING: { + pJpgInst->loggingEnable = 0; + } break; + default: + return JPG_RET_INVALID_COMMAND; + } + return JPG_RET_SUCCESS; +} + +JpgRet JPU_EncOpen(JpgEncHandle *pHandle, JpgEncOpenParam *pop) +{ + JpgInst *pJpgInst; + JpgEncInfo *pEncInfo; + JpgRet ret; + int i; + + ret = CheckJpgEncOpenParam(pop); + if (ret != JPG_RET_SUCCESS) { + BM_DBG_ERR("CheckJpgEncOpenParam\n"); + return ret; + } + + JpgEnterLock(); + ret = GetJpgInstance(&pJpgInst); + if (ret == JPG_RET_FAILURE) { + BM_DBG_ERR("GetJpgInstance\n"); + *pHandle = 0; + JpgLeaveLock(); + return JPG_RET_FAILURE; + } + + *pHandle = pJpgInst; + pEncInfo = &pJpgInst->JpgInfo.encInfo; + memset(pEncInfo, 0x00, sizeof(JpgEncInfo)); + pEncInfo->openParam = *pop; + pEncInfo->streamRdPtr = pop->bitstreamBuffer; + pEncInfo->streamWrPtr = pop->bitstreamBuffer; + + JpuWriteReg(MJPEG_BBC_WR_PTR_REG, pEncInfo->streamWrPtr); + pEncInfo->streamBufStartAddr = pop->bitstreamBuffer; + pEncInfo->streamBufSize = pop->bitstreamBufferSize; + pEncInfo->streamBufEndAddr = + pop->bitstreamBuffer + pop->bitstreamBufferSize; + pEncInfo->streamEndian = pop->streamEndian; + pEncInfo->frameEndian = pop->frameEndian; + pEncInfo->chroma_interleave = pop->chroma_interleave; + + pEncInfo->format = pEncInfo->openParam.sourceFormat; + pEncInfo->picWidth = pEncInfo->openParam.picWidth; + pEncInfo->picHeight = pEncInfo->openParam.picHeight; + // Picture size alignment + if (pEncInfo->format == FORMAT_420 || pEncInfo->format == FORMAT_422) + pEncInfo->alignedWidth = ((pEncInfo->picWidth + 15) / 16) * 16; + else + pEncInfo->alignedWidth = ((pEncInfo->picWidth + 7) / 8) * 8; + + if (pEncInfo->format == FORMAT_420 || pEncInfo->format == FORMAT_224) + pEncInfo->alignedHeight = + ((pEncInfo->picHeight + 15) / 16) * 16; + else + pEncInfo->alignedHeight = ((pEncInfo->picHeight + 7) / 8) * 8; + pEncInfo->rstIntval = pEncInfo->openParam.restartInterval; + + for (i = 0; i < 4; i++) + pEncInfo->pHuffVal[i] = pEncInfo->openParam.huffVal[i]; + for (i = 0; i < 4; i++) + pEncInfo->pHuffBits[i] = pEncInfo->openParam.huffBits[i]; + for (i = 0; i < 4; i++) + pEncInfo->pQMatTab[i] = pEncInfo->openParam.qMatTab[i]; + + pEncInfo->pCInfoTab[0] = sJpuCompInfoTable[/*2*/ pEncInfo->format]; + pEncInfo->pCInfoTab[1] = pEncInfo->pCInfoTab[0] + 6; + pEncInfo->pCInfoTab[2] = pEncInfo->pCInfoTab[1] + 6; + pEncInfo->pCInfoTab[3] = pEncInfo->pCInfoTab[2] + 6; + + if (pop->packedFormat == PACKED_FORMAT_444 && + pEncInfo->format != FORMAT_444) { + BM_DBG_ERR("PACKED_FORMAT_444\n"); + return JPG_RET_INVALID_PARAM; + } + pEncInfo->packedFormat = pop->packedFormat; + + JpgLeaveLock(); + + return JPG_RET_SUCCESS; +} + +JpgRet JPU_EncClose(JpgEncHandle handle) +{ + JpgInst *pJpgInst; + JpgRet ret; + + ret = CheckJpgInstValidity(handle); + if (ret != JPG_RET_SUCCESS) + return ret; + + JpgEnterLock(); + + if (GetJpgPendingInst()) { + JpgLeaveLock(); + return JPG_RET_FRAME_NOT_COMPLETE; + } + + pJpgInst = handle; + JpuWriteReg(MJPEG_BBC_FLUSH_CMD_REG, 0); + FreeJpgInstance(pJpgInst); + JpgLeaveLock(); + + return JPG_RET_SUCCESS; +} + +JpgRet JPU_EncGetInitialInfo(JpgEncHandle handle, JpgEncInitialInfo *info) +{ + JpgInst *pJpgInst; + JpgEncInfo *pEncInfo; + JpgRet ret; + + ret = CheckJpgInstValidity(handle); + if (ret != JPG_RET_SUCCESS) + return ret; + + if (info == 0) { + return JPG_RET_INVALID_PARAM; + } + + pJpgInst = handle; + pEncInfo = &pJpgInst->JpgInfo.encInfo; + + if (pEncInfo->initialInfoObtained) { + return JPG_RET_CALLED_BEFORE; + } + + JpgEnterLock(); + + if (GetJpgPendingInst()) { + JpgLeaveLock(); + return JPG_RET_FRAME_NOT_COMPLETE; + } + + if (pEncInfo->format == FORMAT_400) { + pEncInfo->compInfo[1] = 0; + pEncInfo->compInfo[2] = 0; + } else { + pEncInfo->compInfo[1] = 5; + pEncInfo->compInfo[2] = 5; + } + + if (pEncInfo->format == FORMAT_400) + pEncInfo->compNum = 1; + else + pEncInfo->compNum = 3; + + if (pEncInfo->format == FORMAT_420) { + pEncInfo->mcuBlockNum = 6; + pEncInfo->compInfo[0] = 10; + pEncInfo->busReqNum = 2; + } else if (pEncInfo->format == FORMAT_422) { + pEncInfo->mcuBlockNum = 4; + pEncInfo->busReqNum = 3; + pEncInfo->compInfo[0] = 9; + } else if (pEncInfo->format == FORMAT_224) { + pEncInfo->mcuBlockNum = 4; + pEncInfo->busReqNum = 3; + pEncInfo->compInfo[0] = 6; + } else if (pEncInfo->format == FORMAT_444) { + pEncInfo->mcuBlockNum = 3; + pEncInfo->compInfo[0] = 5; + pEncInfo->busReqNum = 4; + } else if (pEncInfo->format == FORMAT_400) { + pEncInfo->mcuBlockNum = 1; + pEncInfo->busReqNum = 4; + pEncInfo->compInfo[0] = 5; + } + + info->minFrameBufferCount = 0; + info->colorComponents = pEncInfo->compNum; + + pEncInfo->initialInfo = *info; + pEncInfo->initialInfoObtained = 1; + + JpgLeaveLock(); + return JPG_RET_SUCCESS; +} + +JpgRet JPU_EncGetBitstreamBuffer(JpgEncHandle handle, PhysicalAddress *prdPrt, + PhysicalAddress *pwrPtr, int *size) +{ + JpgInst *pJpgInst; + JpgEncInfo *pEncInfo; + JpgRet ret; + + ret = CheckJpgInstValidity(handle); + if (ret != JPG_RET_SUCCESS) + return ret; + + if (prdPrt == 0 || pwrPtr == 0 || size == 0) { + return JPG_RET_INVALID_PARAM; + } + + pJpgInst = handle; + pEncInfo = &pJpgInst->JpgInfo.encInfo; + + JpgSetClockGate(1); + *prdPrt = pEncInfo->streamRdPtr; + + if (GetJpgPendingInst() == pJpgInst) { + *pwrPtr = JpuReadReg(MJPEG_BBC_WR_PTR_REG); + } else { + *pwrPtr = pEncInfo->streamWrPtr; + } + *size = *pwrPtr - *prdPrt; + JpgSetClockGate(0); + + return JPG_RET_SUCCESS; +} + +JpgRet JPU_EncUpdateBitstreamBuffer(JpgEncHandle handle, int size) +{ + JpgInst *pJpgInst; + JpgEncInfo *pEncInfo; + PhysicalAddress rdPtr; + JpgRet ret; + + ret = CheckJpgInstValidity(handle); + if (ret != JPG_RET_SUCCESS) + return ret; + + pJpgInst = handle; + pEncInfo = &pJpgInst->JpgInfo.encInfo; + + JpgSetClockGate(1); + rdPtr = pEncInfo->streamRdPtr; + rdPtr += size; + + if (rdPtr == pEncInfo->streamBufEndAddr) { + rdPtr = pEncInfo->streamBufStartAddr; + } + + pEncInfo->streamRdPtr = pEncInfo->streamBufStartAddr; + + if (GetJpgPendingInst() == pJpgInst) { + pEncInfo->streamWrPtr = JpuReadReg(MJPEG_BBC_WR_PTR_REG); + JpuWriteReg(MJPEG_BBC_CUR_POS_REG, 0); + JpuWriteReg(MJPEG_BBC_EXT_ADDR_REG, + pEncInfo->streamBufStartAddr); + JpuWriteReg(MJPEG_BBC_RD_PTR_REG, pEncInfo->streamBufStartAddr); + JpuWriteReg(MJPEG_BBC_WR_PTR_REG, pEncInfo->streamBufStartAddr); + } + JpgSetClockGate(0); + return JPG_RET_SUCCESS; +} + +JpgRet JPU_EncIssueStop(JpgEncHandle handle) +{ + JpgInst *pJpgInst; + // JpgEncInfo *pEncInfo; + JpgRet ret; + + ret = CheckJpgInstValidity(handle); + if (ret != JPG_RET_SUCCESS) + return ret; + + pJpgInst = handle; + // pEncInfo = &pJpgInst->JpgInfo.encInfo; + + if (pJpgInst != GetJpgPendingInst()) { + return JPG_RET_WRONG_CALL_SEQUENCE; + } + + JpgSetClockGate(1); + JpuWriteReg(MJPEG_PIC_START_REG, 1 << JPG_START_STOP); + JpgSetClockGate(0); + return JPG_RET_SUCCESS; +} + +JpgRet JPU_EncCompleteStop(JpgEncHandle handle) +{ + JpgInst *pJpgInst; + // JpgEncInfo *pEncInfo; + JpgRet ret; + Uint32 val; + + ret = CheckJpgInstValidity(handle); + if (ret != JPG_RET_SUCCESS) + return ret; + + pJpgInst = handle; + // pEncInfo = &pJpgInst->JpgInfo.encInfo; + + if (pJpgInst != GetJpgPendingInst()) { + return JPG_RET_WRONG_CALL_SEQUENCE; + } + + JpgSetClockGate(1); + val = JpuReadReg(MJPEG_PIC_STATUS_REG); + + if (val & (1 << INT_JPU_BIT_BUF_STOP)) { + SetJpgPendingInst(0); + JpgSetClockGate(0); + } else { + JpgSetClockGate(0); + return JPG_RET_WRONG_CALL_SEQUENCE; + } + + return JPG_RET_SUCCESS; +} + +JpgRet JPU_EncStartOneFrame(JpgEncHandle handle, JpgEncParam *param) +{ + JpgInst *pJpgInst; + JpgEncInfo *pEncInfo; + FrameBuffer *pBasFrame; + Uint32 rotMirEnable; + Uint32 rotMirMode; + JpgRet ret; + Uint32 val; + + ret = CheckJpgInstValidity(handle); + if (ret != JPG_RET_SUCCESS) + return ret; + + pJpgInst = handle; + pEncInfo = &pJpgInst->JpgInfo.encInfo; + + ret = CheckJpgEncParam(handle, param); + if (ret != JPG_RET_SUCCESS) { + return ret; + } + + pBasFrame = param->sourceFrame; + rotMirEnable = 0; + rotMirMode = 0; + if (pEncInfo->rotationEnable) { + rotMirEnable = 0x10; // Enable rotator + switch (pEncInfo->rotationAngle) { + case 0: + rotMirMode |= 0x0; + break; + + case 90: + rotMirMode |= 0x1; + break; + + case 180: + rotMirMode |= 0x2; + break; + + case 270: + rotMirMode |= 0x3; + break; + } + } + if (pEncInfo->mirrorEnable) { + rotMirEnable = 0x10; // Enable rotator + + switch (pEncInfo->mirrorDirection) { + case MIRDIR_NONE: + rotMirMode |= 0x0; + break; + + case MIRDIR_VER: + rotMirMode |= 0x4; + break; + + case MIRDIR_HOR: + rotMirMode |= 0x8; + break; + + case MIRDIR_HOR_VER: + rotMirMode |= 0xc; + break; + } + } + + JpgEnterLock(); + + if (GetJpgPendingInst()) { + JpgLeaveLock(); + return JPG_RET_FRAME_NOT_COMPLETE; + } + + // off ROI enable due to not supported feature for encoder. + JpuWriteReg(MJPEG_CLP_INFO_REG, 0); + + JpuWriteReg(MJPEG_BBC_BAS_ADDR_REG, pEncInfo->streamBufStartAddr); + JpuWriteReg(MJPEG_BBC_END_ADDR_REG, pEncInfo->streamBufEndAddr); + JpuWriteReg(MJPEG_BBC_WR_PTR_REG, pEncInfo->streamBufStartAddr); + JpuWriteReg(MJPEG_BBC_RD_PTR_REG, pEncInfo->streamBufStartAddr); + JpuWriteReg(MJPEG_BBC_CUR_POS_REG, 0); + JpuWriteReg(MJPEG_BBC_DATA_CNT_REG, 256 / 4); // 64 * 4 byte == 32 * 8 byte + JpuWriteReg(MJPEG_BBC_EXT_ADDR_REG, pEncInfo->streamBufStartAddr); + JpuWriteReg(MJPEG_BBC_INT_ADDR_REG, 0); + + JpuWriteReg(MJPEG_GBU_BT_PTR_REG, 0); + JpuWriteReg(MJPEG_GBU_WD_PTR_REG, 0); + JpuWriteReg(MJPEG_GBU_BBSR_REG, 0); + JpuWriteReg(MJPEG_GBU_CTRL_REG, 0); + + JpuWriteReg(MJPEG_GBU_BBER_REG, ((256 / 4) * 2) - 1); + JpuWriteReg(MJPEG_GBU_BBIR_REG, 256 / 4); // 64 * 4 byte == 32 * 8 byte + JpuWriteReg(MJPEG_GBU_BBHR_REG, 256 / 4); // 64 * 4 byte == 32 * 8 byte + val = 0x18 | pEncInfo->usePartial | (JPU_CHECK_WRITE_RESPONSE_BVALID_SIGNAL << 2); + JpuWriteReg(MJPEG_PIC_CTRL_REG, val); + JpuWriteReg(MJPEG_SCL_INFO_REG, 0); + if (pEncInfo->chroma_interleave == 0) + val = 0; + else if (pEncInfo->chroma_interleave == 1) + val = 2; + else + val = 3; + if (pEncInfo->packedFormat == PACKED_FORMAT_NONE) { + val |= (pEncInfo->frameEndian << 6) | (0 << 5) | (0 << 4) | (0 << 2); + JpuWriteReg(MJPEG_DPB_CONFIG_REG, val); + } else if (pEncInfo->packedFormat == PACKED_FORMAT_444) { + val |= (pEncInfo->frameEndian << 6) | (1 << 5) | (0 << 4) | (0 << 2); + JpuWriteReg(MJPEG_DPB_CONFIG_REG, val); + } else { + val |= (pEncInfo->frameEndian << 6) | (0 << 5) | (1 << 4) | ((pEncInfo->packedFormat - 1) << 2); + JpuWriteReg(MJPEG_DPB_CONFIG_REG, val); + } + + JpuWriteReg(MJPEG_RST_INTVAL_REG, pEncInfo->rstIntval); + JpuWriteReg(MJPEG_BBC_CTRL_REG, (pEncInfo->streamEndian << 1) | 1); + val = pEncInfo->partiallineNum << 16 | pEncInfo->partialBufNum << 3 | pEncInfo->busReqNum; + JpuWriteReg(MJPEG_OP_INFO_REG, val); + + // Load HUFFTab + if (!JpgEncLoadHuffTab(pEncInfo)) { + JpgLeaveLock(); + return JPG_RET_INVALID_PARAM; + } + + // Load QMATTab + if (!JpgEncLoadQMatTab(pEncInfo)) { + JpgLeaveLock(); + return JPG_RET_INVALID_PARAM; + } + JpgEncEncodeHeader(handle, pEncInfo->paraSet); + // although rotator is enable, this picture size must not be changed + // from widh to height. + JpuWriteReg(MJPEG_PIC_SIZE_REG, pEncInfo->alignedWidth << 16 | pEncInfo->alignedHeight); + JpuWriteReg(MJPEG_ROT_INFO_REG, (rotMirEnable | rotMirMode)); + + val = pEncInfo->mcuBlockNum << 16 | pEncInfo->compNum << 12; + val |= pEncInfo->compInfo[0] << 8 | pEncInfo->compInfo[1] << 4 | pEncInfo->compInfo[2]; + JpuWriteReg(MJPEG_MCU_INFO_REG, val); + + // JpgEncGbuResetReg + JpuWriteReg(MJPEG_GBU_CTRL_REG, pEncInfo->stuffByteEnable << 3); // stuffing "FF" data where frame end + + if (pEncInfo->usePartial) { + int i; + + for (i = 0; i < pEncInfo->partialBufNum; i++) { + JpuWriteReg(MJPEG_DPB_BASE00_REG + (i * 12), pBasFrame[i].bufY); + JpuWriteReg(MJPEG_DPB_BASE01_REG + (i * 12), pBasFrame[i].bufCb); + JpuWriteReg(MJPEG_DPB_BASE02_REG + (i * 12), pBasFrame[i].bufCr); + } + + } else { + JpuWriteReg(MJPEG_DPB_BASE00_REG, pBasFrame->bufY); + JpuWriteReg(MJPEG_DPB_BASE01_REG, pBasFrame->bufCb); + JpuWriteReg(MJPEG_DPB_BASE02_REG, pBasFrame->bufCr); + } + + JpuWriteReg(MJPEG_DPB_YSTRIDE_REG, pBasFrame->stride); + + if (pEncInfo->format == FORMAT_420 || pEncInfo->format == FORMAT_422 || pEncInfo->format == FORMAT_400) + val = 2; + else + val = 1; + + if (pEncInfo->chroma_interleave) + JpuWriteReg(MJPEG_DPB_CSTRIDE_REG, (pBasFrame->stride / (int)val) * 2); + else + JpuWriteReg(MJPEG_DPB_CSTRIDE_REG, pBasFrame->stride / (int)val); + + if (pJpgInst->loggingEnable) + jdi_log(JDI_LOG_CMD_PICRUN, 1); + +#ifdef PROFILE_PERFORMANCE + timer_meter_start(); +#endif + + JpuWriteReg(MJPEG_PIC_STATUS_REG, JpuReadReg(MJPEG_PIC_STATUS_REG)); + if (pEncInfo->usePartial) + JpuWriteReg(MJPEG_PIC_START_REG, (1 << JPG_START_PIC) | (1 << JPG_START_PARTIAL)); + else + JpuWriteReg(MJPEG_PIC_START_REG, (1 << JPG_START_PIC)); + + SetJpgPendingInst(pJpgInst); + return JPG_RET_SUCCESS; +} + +JpgRet JPU_EncGetOutputInfo(JpgEncHandle handle, JpgEncOutputInfo *info) +{ + JpgInst *pJpgInst; + JpgEncInfo *pEncInfo; + Uint32 val; + JpgRet ret; + + ret = CheckJpgInstValidity(handle); + if (ret != JPG_RET_SUCCESS) { + SetJpgPendingInst(0); + JpgLeaveLock(); + return ret; + } + + if (info == 0) { + SetJpgPendingInst(0); + JpgLeaveLock(); + return JPG_RET_INVALID_PARAM; + } + + pJpgInst = handle; + pEncInfo = &pJpgInst->JpgInfo.encInfo; + + if (pJpgInst != GetJpgPendingInst()) { + SetJpgPendingInst(0); + JpgLeaveLock(); + return JPG_RET_WRONG_CALL_SEQUENCE; + } + + val = JpuReadReg(MJPEG_PIC_STATUS_REG); + + if ((val & 0x4) >> 2) { + SetJpgPendingInst(0); + JpgLeaveLock(); + return JPG_RET_WRONG_CALL_SEQUENCE; + } + + if (val != 0) + JpuWriteReg(MJPEG_PIC_STATUS_REG, val); + + info->bitstreamBuffer = pEncInfo->streamBufStartAddr; + info->bitstreamSize = JpuReadReg(MJPEG_BBC_WR_PTR_REG) - pEncInfo->streamBufStartAddr; + pEncInfo->streamWrPtr = JpuReadReg(MJPEG_BBC_WR_PTR_REG); + + JpuWriteReg(MJPEG_BBC_FLUSH_CMD_REG, 0); + + if (pJpgInst->loggingEnable) + jdi_log(JDI_LOG_CMD_PICRUN, 0); + + SetJpgPendingInst(0); + JpgLeaveLock(); + return JPG_RET_SUCCESS; +} + +JpgRet JPU_EncGiveCommand(JpgEncHandle handle, JpgCommand cmd, void *param) +{ + JpgInst *pJpgInst; + JpgEncInfo *pEncInfo; + JpgRet ret; + + ret = CheckJpgInstValidity(handle); + if (ret != JPG_RET_SUCCESS) + return ret; + + pJpgInst = handle; + pEncInfo = &pJpgInst->JpgInfo.encInfo; + switch (cmd) { + case ENABLE_JPG_ROTATION: { + pEncInfo->rotationEnable = 1; + } break; + case DISABLE_JPG_ROTATION: { + pEncInfo->rotationEnable = 0; + } break; + case ENABLE_JPG_MIRRORING: { + pEncInfo->mirrorEnable = 1; + } break; + case DISABLE_JPG_MIRRORING: { + pEncInfo->mirrorEnable = 0; + } break; + case SET_JPG_MIRROR_DIRECTION: { + JpgMirrorDirection mirDir; + + if (param == 0) { + return JPG_RET_INVALID_PARAM; + } + mirDir = *(JpgMirrorDirection *)param; + if (!(mirDir >= MIRDIR_NONE && mirDir <= MIRDIR_HOR_VER)) { + return JPG_RET_INVALID_PARAM; + } + pEncInfo->mirrorDirection = mirDir; + } break; + case SET_JPG_ROTATION_ANGLE: { + int angle; + + if (param == 0) { + return JPG_RET_INVALID_PARAM; + } + angle = *(int *)param; + if (angle != 0 && angle != 90 && angle != 180 && angle != 270) { + return JPG_RET_INVALID_PARAM; + } + if (pEncInfo->initialInfoObtained && (angle == 90 || angle == 270)) { + return JPG_RET_INVALID_PARAM; + } + pEncInfo->rotationAngle = angle; + } break; + case ENC_JPG_GET_HEADER: { + if (param == 0) { + return JPG_RET_INVALID_PARAM; + } + + pEncInfo->paraSet = (JpgEncParamSet *)param; + break; + } + case SET_JPG_USE_PARTIAL_MODE: { + int enable; + + enable = *(int *)param; + pEncInfo->usePartial = enable; + + break; + } + case SET_JPG_PARTIAL_FRAME_NUM: { + int frame; + + frame = *(int *)param; + pEncInfo->partialBufNum = frame; + + break; + } + case SET_JPG_PARTIAL_LINE_NUM: { + int line; + + line = *(int *)param; + pEncInfo->partiallineNum = line; + + break; + } + case SET_JPG_ENCODE_NEXT_LINE: { + JpuWriteReg(MJPEG_PIC_START_REG, (1 << JPG_START_PARTIAL)); + break; + } + case SET_JPG_USE_STUFFING_BYTE_FF: { + int enable; + + enable = *(int *)param; + pEncInfo->stuffByteEnable = enable; + break; + } + case ENABLE_LOGGING: { + pJpgInst->loggingEnable = 1; + break; + } + case DISABLE_LOGGING: { + pJpgInst->loggingEnable = 0; + break; + } + default: + return JPG_RET_INVALID_COMMAND; + } + + return JPG_RET_SUCCESS; +} diff --git a/u-boot-2021.10/drivers/jpeg/jpuapi.h b/u-boot-2021.10/drivers/jpeg/jpuapi.h new file mode 100644 index 000000000..4f47c5a6b --- /dev/null +++ b/u-boot-2021.10/drivers/jpeg/jpuapi.h @@ -0,0 +1,270 @@ +#ifndef _JPU_API_H_ +#define _JPU_API_H_ + +#include "jpuconfig.h" +#include "jdi.h" + +#define CVI_JPG_DBG(msg, ...) \ + do {\ + if (1) {\ + printf("[DBG] %s = %d, " msg, __func__, __LINE__, ##__VA_ARGS__);\ + } \ + } while (0) + +#define ALIGN_X(IN, ALIGN) (((IN) + (ALIGN) - 1) / (ALIGN) * (ALIGN)) +#define ALIGN_32 + +//------------------------------------------------------------------------------ +// common struct and definition +//------------------------------------------------------------------------------ + +typedef enum { + ENABLE_JPG_ROTATION, + DISABLE_JPG_ROTATION, + ENABLE_JPG_MIRRORING, + DISABLE_JPG_MIRRORING, + SET_JPG_MIRROR_DIRECTION, + SET_JPG_ROTATION_ANGLE, + SET_JPG_ROTATOR_OUTPUT, + SET_JPG_ROTATOR_STRIDE, + SET_JPG_SCALE_HOR, + SET_JPG_SCALE_VER, + SET_JPG_USE_PARTIAL_MODE, + SET_JPG_PARTIAL_FRAME_NUM, + SET_JPG_PARTIAL_LINE_NUM, + SET_JPG_ENCODE_NEXT_LINE, + SET_JPG_USE_STUFFING_BYTE_FF, + ENC_JPG_GET_HEADER, + ENABLE_LOGGING, + DISABLE_LOGGING, + JPG_CMD_END +} JpgCommand; + +typedef enum { + JPG_RET_SUCCESS, + JPG_RET_FAILURE, + JPG_RET_BIT_EMPTY, + JPG_RET_EOS, + JPG_RET_INVALID_HANDLE, + JPG_RET_INVALID_PARAM, + JPG_RET_INVALID_COMMAND, + JPG_RET_ROTATOR_OUTPUT_NOT_SET, + JPG_RET_ROTATOR_STRIDE_NOT_SET, + JPG_RET_FRAME_NOT_COMPLETE, + JPG_RET_INVALID_FRAME_BUFFER, + JPG_RET_INSUFFICIENT_FRAME_BUFFERS, + JPG_RET_INVALID_STRIDE, + JPG_RET_WRONG_CALL_SEQUENCE, + JPG_RET_CALLED_BEFORE, + JPG_RET_NOT_INITIALIZED +} JpgRet; + +typedef enum { + MIRDIR_NONE, + MIRDIR_VER, + MIRDIR_HOR, + MIRDIR_HOR_VER +} JpgMirrorDirection; + +typedef enum { + FORMAT_420 = 0, + FORMAT_422 = 1, + FORMAT_224 = 2, + FORMAT_444 = 3, + FORMAT_400 = 4 +} FrameFormat; + +typedef enum { + CBCR_ORDER_NORMAL, + CBCR_ORDER_REVERSED +} CbCrOrder; + +typedef enum { + CBCR_SEPARATED = 0, + CBCR_INTERLEAVE + , + CRCB_INTERLEAVE +} CbCrInterLeave; + +typedef enum { + PACKED_FORMAT_NONE, + PACKED_FORMAT_422_YUYV, + PACKED_FORMAT_422_UYVY, + PACKED_FORMAT_422_YVYU, + PACKED_FORMAT_422_VYUY, + PACKED_FORMAT_444 +} PackedOutputFormat; + +typedef enum { + INT_JPU_DONE = 0, + INT_JPU_ERROR = 1, + INT_JPU_BIT_BUF_EMPTY = 2, + INT_JPU_BIT_BUF_FULL = 2, + INT_JPU_PARIAL_OVERFLOW = 3, + INT_JPU_PARIAL_BUF0_EMPTY = 4, + INT_JPU_PARIAL_BUF1_EMPTY, + INT_JPU_PARIAL_BUF2_EMPTY, + INT_JPU_PARIAL_BUF3_EMPTY, + INT_JPU_BIT_BUF_STOP +} InterruptJpu; + +typedef enum { + JPG_TBL_NORMAL, + JPG_TBL_MERGE +} JpgTableMode; + +typedef enum { + ENC_HEADER_MODE_NORMAL, + ENC_HEADER_MODE_SOS_ONLY +} JpgEncHeaderMode; + +typedef struct { + PhysicalAddress bufY; + PhysicalAddress bufCb; + PhysicalAddress bufCr; + int stride; +} FrameBuffer; + +struct JpgInst; + +//------------------------------------------------------------------------------ +// decode struct and definition +//------------------------------------------------------------------------------ + +typedef struct JpgInst JpgDecInst; +typedef JpgDecInst * JpgDecHandle; + +typedef struct { + PhysicalAddress bitstreamBuffer; + int bitstreamBufferSize; + BYTE *pBitStream; + int streamEndian; + int frameEndian; + CbCrInterLeave chroma_interleave; + int thumbNailEn; + PackedOutputFormat packedFormat; + int roiEnable; + int roiOffsetX; + int roiOffsetY; + int roiWidth; + int roiHeight; + +} JpgDecOpenParam; + +typedef struct { + int picWidth; + int picHeight; + int minFrameBufferCount; + int sourceFormat; + int ecsPtr; + int roiFrameWidth; + int roiFrameHeight; + int roiFrameOffsetX; + int roiFrameOffsetY; + int roiMCUSize; + int colorComponents; +} JpgDecInitialInfo; + +typedef struct { + int scaleDownRatioWidth; + int scaleDownRatioHeight; +} JpgDecParam; + +typedef struct { + int indexFrameDisplay; + int numOfErrMBs; + int decodingSuccess; + int decPicHeight; + int decPicWidth; + int consumedByte; + int bytePosFrameStart; + int ecsPtr; +} JpgDecOutputInfo; + +//------------------------------------------------------------------------------ +// encode struct and definition +//------------------------------------------------------------------------------ + +typedef struct JpgInst JpgEncInst; +typedef JpgEncInst * JpgEncHandle; + +typedef struct { + PhysicalAddress bitstreamBuffer; + Uint32 bitstreamBufferSize; + int picWidth; + int picHeight; + int sourceFormat; + int restartInterval; + int streamEndian; + int frameEndian; + CbCrInterLeave chroma_interleave; + BYTE huffVal[4][162]; + BYTE huffBits[4][256]; + BYTE qMatTab[4][64]; + PackedOutputFormat packedFormat; +} JpgEncOpenParam; + +typedef struct { + int minFrameBufferCount; + int colorComponents; +} JpgEncInitialInfo; + +typedef struct { + FrameBuffer *sourceFrame; +} JpgEncParam; + +typedef struct { + PhysicalAddress bitstreamBuffer; + Uint32 bitstreamSize; +} JpgEncOutputInfo; + +typedef struct { + PhysicalAddress paraSet; + BYTE *pParaSet; + int size; + int headerMode; + int quantMode; + int huffMode; + int disableAPPMarker; +} JpgEncParamSet; + +#ifdef __cplusplus +extern "C" { +#endif + +int JPU_IsBusy(void); +Uint32 JPU_GetStatus(void); +void JPU_ClrStatus(Uint32 val); +Uint32 JPU_IsInit(void); +Uint32 JPU_WaitInterrupt(int timeout); + +JpgRet JPU_Init(void); +void JPU_DeInit(void); +int JPU_GetOpenInstanceNum(void); +JpgRet JPU_GetVersionInfo(Uint32 *versionInfo); + +// function for decode +JpgRet JPU_DecOpen(JpgDecHandle *pHandle, JpgDecOpenParam *pop); +JpgRet JPU_DecClose(JpgDecHandle handle); +JpgRet JPU_DecGetInitialInfo(JpgDecHandle handle, JpgDecInitialInfo *info); + +JpgRet JPU_DecSetRdPtr(JpgDecHandle handle, PhysicalAddress addr, int updateWrPtr); + +JpgRet JPU_DecRegisterFrameBuffer(JpgDecHandle handle, FrameBuffer *bufArray, int num, int strideY, int strideC); +JpgRet JPU_DecGetBitstreamBuffer(JpgDecHandle handle, PhysicalAddress *prdPrt, PhysicalAddress *pwrPtr, int *size); +JpgRet JPU_DecUpdateBitstreamBuffer(JpgDecHandle handle, int size); +JpgRet JPU_HWReset(void); +JpgRet JPU_SWReset(void); +JpgRet JPU_DecStartOneFrame(JpgDecHandle handle, JpgDecParam *param); +JpgRet JPU_DecGetOutputInfo(JpgDecHandle handle, JpgDecOutputInfo *info); +JpgRet JPU_DecIssueStop(JpgDecHandle handle); +JpgRet JPU_DecCompleteStop(JpgDecHandle handle); +JpgRet JPU_DecGiveCommand(JpgDecHandle handle, JpgCommand cmd, void *parameter); +JpgRet JPU_EncGetBitstreamBuffer(JpgEncHandle handle, PhysicalAddress *prdPrt, PhysicalAddress *pwrPtr, int *size); +JpgRet JPU_EncUpdateBitstreamBuffer(JpgEncHandle handle, int size); + +#ifdef __cplusplus +} +#endif + +#endif //_JPU_API_H_ diff --git a/u-boot-2021.10/drivers/jpeg/jpuapifunc.c b/u-boot-2021.10/drivers/jpeg/jpuapifunc.c new file mode 100644 index 000000000..ac5caf1d8 --- /dev/null +++ b/u-boot-2021.10/drivers/jpeg/jpuapifunc.c @@ -0,0 +1,2112 @@ +#include "jdi.h" +#include "jpuapifunc.h" +#include "jpulog.h" +#include "regdefine.h" + +/****************************************************************************** + * Codec Instance Slot Management + ******************************************************************************/ + +// static UINT tGetBits(JpgDecInfo *jpg, int endian, int byteCnt); + +const char lendian[4] = {0x49, 0x49, 0x2A, 0x00}; +const char bendian[4] = {0x4D, 0x4D, 0x00, 0x2A}; + +const char *jfif = "JFIF"; +const char *jfxx = "JFXX"; +const char *exif = "Exif"; + +static unsigned char sJpuCompInfoTable[5][24] = { + {00, 02, 02, 00, 00, 00, 01, 01, 01, 01, 01, 01, + 02, 01, 01, 01, 01, 01, 03, 00, 00, 00, 00, 00}, // 420 + {00, 02, 01, 00, 00, 00, 01, 01, 01, 01, 01, 01, + 02, 01, 01, 01, 01, 01, 03, 00, 00, 00, 00, 00}, // 422H + {00, 01, 02, 00, 00, 00, 01, 01, 01, 01, 01, 01, + 02, 01, 01, 01, 01, 01, 03, 00, 00, 00, 00, 00}, // 422V + {00, 01, 01, 00, 00, 00, 01, 01, 01, 01, 01, 01, + 02, 01, 01, 01, 01, 01, 03, 00, 00, 00, 00, 00}, // 444 + {00, 01, 01, 00, 00, 00, 01, 00, 00, 00, 00, 00, + 02, 00, 00, 00, 00, 00, 03, 00, 00, 00, 00, 00}, // 400 +}; + +JpgRet InitJpgInstancePool(void) +{ + int i; + JpgInst *pJpgInst; + jpu_instance_pool_t *jip; + + jip = (jpu_instance_pool_t *)jdi_get_instance_pool(); + if (!jip) + return JPG_RET_INVALID_HANDLE; + + if (jip->instance_pool_inited == 0) { + for (i = 0; i < MAX_NUM_INSTANCE; i++) { + pJpgInst = (JpgInst *)jip->jpgInstPool[i]; + pJpgInst->instIndex = i; + pJpgInst->inUse = 0; + } + jip->instance_pool_inited = 1; + } + + return JPG_RET_SUCCESS; +} + +/* + * GetJpgInstance() obtains a instance. + * It stores a pointer to the allocated instance in *ppInst + * and returns JPG_RET_SUCCESS on success. + * Failure results in 0(null pointer) in *ppInst and JPG_RET_FAILURE. + */ + +JpgRet GetJpgInstance(JpgInst **ppInst) +{ + int i; + JpgInst *pJpgInst = 0; + jpu_instance_pool_t *jip; + + jip = (jpu_instance_pool_t *)jdi_get_instance_pool(); + if (!jip) + return JPG_RET_INVALID_HANDLE; + + for (i = 0; i < MAX_NUM_INSTANCE; ++i, ++pJpgInst) { + pJpgInst = (JpgInst *)jip->jpgInstPool[i]; + + if (!pJpgInst) { + return JPG_RET_FAILURE; + } + if (!pJpgInst->inUse) + break; + } + + if (i == MAX_NUM_INSTANCE) { + *ppInst = 0; + return JPG_RET_FAILURE; + } + + pJpgInst->inUse = 1; + *ppInst = pJpgInst; + + if (jdi_open_instance(pJpgInst->instIndex) < 0) + return JPG_RET_FAILURE; + + return JPG_RET_SUCCESS; +} + +void FreeJpgInstance(JpgInst *pJpgInst) +{ + pJpgInst->inUse = 0; + + jdi_close_instance(pJpgInst->instIndex); +} + +JpgRet CheckJpgInstValidity(JpgInst *pci) +{ + JpgInst *pJpgInst = 0; + int i; + jpu_instance_pool_t *jip; + + jip = (jpu_instance_pool_t *)jdi_get_instance_pool(); + + if (!jip) { + BM_DBG_ERR("jdi_get_instance_pool\n"); + return JPG_RET_FAILURE; + } + + for (i = 0; i < MAX_NUM_INSTANCE; ++i, ++pJpgInst) { + if ((JpgInst *)jip->jpgInstPool[i] == pci) + return JPG_RET_SUCCESS; + } + return JPG_RET_INVALID_HANDLE; +} + +/****************************************************************************** + * API Subroutines + ******************************************************************************/ + +JpgRet CheckJpgDecOpenParam(JpgDecOpenParam *pop) +{ + if (pop == 0) { + return JPG_RET_INVALID_PARAM; + } + if (pop->bitstreamBuffer % 8) { + return JPG_RET_INVALID_PARAM; + } + if (pop->bitstreamBufferSize % 1024 || + pop->bitstreamBufferSize < 1024) { + return JPG_RET_INVALID_PARAM; + } + + if (pop->chroma_interleave != CBCR_SEPARATED && + pop->chroma_interleave != CBCR_INTERLEAVE && + pop->chroma_interleave != CRCB_INTERLEAVE) { + return JPG_RET_INVALID_PARAM; + } + + if (pop->packedFormat > PACKED_FORMAT_444) { + return JPG_RET_INVALID_PARAM; + } + + if (pop->packedFormat != PACKED_FORMAT_NONE) { + if (pop->chroma_interleave != CBCR_SEPARATED) { + return JPG_RET_INVALID_PARAM; + } + } + + return JPG_RET_SUCCESS; +} + +int JpgDecHuffTabSetUp(JpgDecInfo *jpg) +{ + int i, j; + int HuffData; // 16BITS + int HuffLength; + int temp; + + // MIN Tables + JpuWriteReg(MJPEG_HUFF_CTRL_REG, 0x003); + + // DC Luma + for (j = 0; j < 16; j++) { + HuffData = jpg->huffMin[0][j]; + temp = (HuffData & 0x8000) >> 15; + temp = (temp << 15) | (temp << 14) | (temp << 13) | + (temp << 12) | (temp << 11) | (temp << 10) | + (temp << 9) | (temp << 8) | (temp << 7) | (temp << 6) | + (temp << 5) | (temp << 4) | (temp << 3) | (temp << 2) | + (temp << 1) | (temp); + JpuWriteReg(MJPEG_HUFF_DATA_REG, + (((temp & 0xFFFF) << 16) | HuffData)); // 32-bit + } + + // DC Chroma + for (j = 0; j < 16; j++) { + HuffData = jpg->huffMin[2][j]; + temp = (HuffData & 0x8000) >> 15; + temp = (temp << 15) | (temp << 14) | (temp << 13) | + (temp << 12) | (temp << 11) | (temp << 10) | + (temp << 9) | (temp << 8) | (temp << 7) | (temp << 6) | + (temp << 5) | (temp << 4) | (temp << 3) | (temp << 2) | + (temp << 1) | (temp); + JpuWriteReg(MJPEG_HUFF_DATA_REG, (((temp & 0xFFFF) << 16) | HuffData)); // 32-bit + } + + // AC Luma + for (j = 0; j < 16; j++) { + HuffData = jpg->huffMin[1][j]; + temp = (HuffData & 0x8000) >> 15; + temp = (temp << 15) | (temp << 14) | (temp << 13) | + (temp << 12) | (temp << 11) | (temp << 10) | + (temp << 9) | (temp << 8) | (temp << 7) | (temp << 6) | + (temp << 5) | (temp << 4) | (temp << 3) | (temp << 2) | + (temp << 1) | (temp); + JpuWriteReg(MJPEG_HUFF_DATA_REG, (((temp & 0xFFFF) << 16) | HuffData)); // 32-bit + } + + // AC Chroma + for (j = 0; j < 16; j++) { + HuffData = jpg->huffMin[3][j]; + temp = (HuffData & 0x8000) >> 15; + temp = (temp << 15) | (temp << 14) | (temp << 13) | + (temp << 12) | (temp << 11) | (temp << 10) | + (temp << 9) | (temp << 8) | (temp << 7) | (temp << 6) | + (temp << 5) | (temp << 4) | (temp << 3) | (temp << 2) | + (temp << 1) | (temp); + JpuWriteReg(MJPEG_HUFF_DATA_REG, (((temp & 0xFFFF) << 16) | HuffData)); // 32-bit + } + // MAX Tables + JpuWriteReg(MJPEG_HUFF_CTRL_REG, 0x403); + JpuWriteReg(MJPEG_HUFF_ADDR_REG, 0x440); + + // DC Luma + for (j = 0; j < 16; j++) { + HuffData = jpg->huffMax[0][j]; + temp = (HuffData & 0x8000) >> 15; + temp = (temp << 15) | (temp << 14) | (temp << 13) | + (temp << 12) | (temp << 11) | (temp << 10) | + (temp << 9) | (temp << 8) | (temp << 7) | (temp << 6) | + (temp << 5) | (temp << 4) | (temp << 3) | (temp << 2) | + (temp << 1) | (temp); + JpuWriteReg(MJPEG_HUFF_DATA_REG, (((temp & 0xFFFF) << 16) | HuffData)); + } + // DC Chroma + for (j = 0; j < 16; j++) { + HuffData = jpg->huffMax[2][j]; + temp = (HuffData & 0x8000) >> 15; + temp = (temp << 15) | (temp << 14) | (temp << 13) | + (temp << 12) | (temp << 11) | (temp << 10) | + (temp << 9) | (temp << 8) | (temp << 7) | (temp << 6) | + (temp << 5) | (temp << 4) | (temp << 3) | (temp << 2) | + (temp << 1) | (temp); + JpuWriteReg(MJPEG_HUFF_DATA_REG, (((temp & 0xFFFF) << 16) | HuffData)); + } + // AC Luma + for (j = 0; j < 16; j++) { + HuffData = jpg->huffMax[1][j]; + temp = (HuffData & 0x8000) >> 15; + temp = (temp << 15) | (temp << 14) | (temp << 13) | + (temp << 12) | (temp << 11) | (temp << 10) | + (temp << 9) | (temp << 8) | (temp << 7) | (temp << 6) | + (temp << 5) | (temp << 4) | (temp << 3) | (temp << 2) | + (temp << 1) | (temp); + JpuWriteReg(MJPEG_HUFF_DATA_REG, (((temp & 0xFFFF) << 16) | HuffData)); + } + // AC Chroma + for (j = 0; j < 16; j++) { + HuffData = jpg->huffMax[3][j]; + temp = (HuffData & 0x8000) >> 15; + temp = (temp << 15) | (temp << 14) | (temp << 13) | + (temp << 12) | (temp << 11) | (temp << 10) | + (temp << 9) | (temp << 8) | (temp << 7) | (temp << 6) | + (temp << 5) | (temp << 4) | (temp << 3) | (temp << 2) | + (temp << 1) | (temp); + JpuWriteReg(MJPEG_HUFF_DATA_REG, (((temp & 0xFFFF) << 16) | HuffData)); + } + + // PTR Tables + JpuWriteReg(MJPEG_HUFF_CTRL_REG, 0x803); + JpuWriteReg(MJPEG_HUFF_ADDR_REG, 0x880); + + // DC Luma + for (j = 0; j < 16; j++) { + HuffData = jpg->huffPtr[0][j]; + temp = (HuffData & 0x80) >> 7; + temp = (temp << 23) | (temp << 22) | (temp << 21) | + (temp << 20) | (temp << 19) | (temp << 18) | + (temp << 17) | (temp << 16) | (temp << 15) | + (temp << 14) | (temp << 13) | (temp << 12) | + (temp << 11) | (temp << 10) | (temp << 9) | (temp << 8) | + (temp << 7) | (temp << 6) | (temp << 5) | (temp << 4) | + (temp << 3) | (temp << 2) | (temp << 1) | (temp); + JpuWriteReg(MJPEG_HUFF_DATA_REG, (((temp & 0xFFFFFF) << 8) | HuffData)); + } + // DC Chroma + for (j = 0; j < 16; j++) { + HuffData = jpg->huffPtr[2][j]; + temp = (HuffData & 0x80) >> 7; + temp = (temp << 23) | (temp << 22) | (temp << 21) | + (temp << 20) | (temp << 19) | (temp << 18) | + (temp << 17) | (temp << 16) | (temp << 15) | + (temp << 14) | (temp << 13) | (temp << 12) | + (temp << 11) | (temp << 10) | (temp << 9) | (temp << 8) | + (temp << 7) | (temp << 6) | (temp << 5) | (temp << 4) | + (temp << 3) | (temp << 2) | (temp << 1) | (temp); + JpuWriteReg(MJPEG_HUFF_DATA_REG, (((temp & 0xFFFFFF) << 8) | HuffData)); + } + // AC Luma + for (j = 0; j < 16; j++) { + HuffData = jpg->huffPtr[1][j]; + temp = (HuffData & 0x80) >> 7; + temp = (temp << 23) | (temp << 22) | (temp << 21) | + (temp << 20) | (temp << 19) | (temp << 18) | + (temp << 17) | (temp << 16) | (temp << 15) | + (temp << 14) | (temp << 13) | (temp << 12) | + (temp << 11) | (temp << 10) | (temp << 9) | (temp << 8) | + (temp << 7) | (temp << 6) | (temp << 5) | (temp << 4) | + (temp << 3) | (temp << 2) | (temp << 1) | (temp); + JpuWriteReg(MJPEG_HUFF_DATA_REG, (((temp & 0xFFFFFF) << 8) | HuffData)); + } + // AC Chroma + for (j = 0; j < 16; j++) { + HuffData = jpg->huffPtr[3][j]; + temp = (HuffData & 0x80) >> 7; + temp = (temp << 23) | (temp << 22) | (temp << 21) | + (temp << 20) | (temp << 19) | (temp << 18) | + (temp << 17) | (temp << 16) | (temp << 15) | + (temp << 14) | (temp << 13) | (temp << 12) | + (temp << 11) | (temp << 10) | (temp << 9) | (temp << 8) | + (temp << 7) | (temp << 6) | (temp << 5) | (temp << 4) | + (temp << 3) | (temp << 2) | (temp << 1) | (temp); + JpuWriteReg(MJPEG_HUFF_DATA_REG, (((temp & 0xFFFFFF) << 8) | HuffData)); + } + + // VAL Tables + JpuWriteReg(MJPEG_HUFF_CTRL_REG, 0xC03); + + // VAL DC Luma + HuffLength = 0; + for (i = 0; i < 12; i++) + HuffLength += jpg->huffBits[0][i]; + + for (i = 0; i < HuffLength; + i++) { // 8-bit, 12 row, 1 category (DC Luma) + HuffData = jpg->huffVal[0][i]; + temp = (HuffData & 0x80) >> 7; + temp = (temp << 23) | (temp << 22) | (temp << 21) | + (temp << 20) | (temp << 19) | (temp << 18) | + (temp << 17) | (temp << 16) | (temp << 15) | + (temp << 14) | (temp << 13) | (temp << 12) | + (temp << 11) | (temp << 10) | (temp << 9) | (temp << 8) | + (temp << 7) | (temp << 6) | (temp << 5) | (temp << 4) | + (temp << 3) | (temp << 2) | (temp << 1) | (temp); + JpuWriteReg(MJPEG_HUFF_DATA_REG, (((temp & 0xFFFFFF) << 8) | HuffData)); + } + + for (i = 0; i < 12 - HuffLength; i++) { + JpuWriteReg(MJPEG_HUFF_DATA_REG, 0xFFFFFFFF); + } + + // VAL DC Chroma + HuffLength = 0; + for (i = 0; i < 12; i++) + HuffLength += jpg->huffBits[2][i]; + for (i = 0; i < HuffLength; i++) { // 8-bit, 12 row, 1 category (DC Chroma) + HuffData = jpg->huffVal[2][i]; + temp = (HuffData & 0x80) >> 7; + temp = (temp << 23) | (temp << 22) | (temp << 21) | + (temp << 20) | (temp << 19) | (temp << 18) | + (temp << 17) | (temp << 16) | (temp << 15) | + (temp << 14) | (temp << 13) | (temp << 12) | + (temp << 11) | (temp << 10) | (temp << 9) | (temp << 8) | + (temp << 7) | (temp << 6) | (temp << 5) | (temp << 4) | + (temp << 3) | (temp << 2) | (temp << 1) | (temp); + JpuWriteReg(MJPEG_HUFF_DATA_REG, (((temp & 0xFFFFFF) << 8) | HuffData)); + } + for (i = 0; i < 12 - HuffLength; i++) { + JpuWriteReg(MJPEG_HUFF_DATA_REG, 0xFFFFFFFF); + } + + // VAL AC Luma + HuffLength = 0; + for (i = 0; i < 162; i++) + HuffLength += jpg->huffBits[1][i]; + for (i = 0; i < HuffLength; i++) { // 8-bit, 162 row, 1 category (AC Luma) + HuffData = jpg->huffVal[1][i]; + temp = (HuffData & 0x80) >> 7; + temp = (temp << 23) | (temp << 22) | (temp << 21) | + (temp << 20) | (temp << 19) | (temp << 18) | + (temp << 17) | (temp << 16) | (temp << 15) | + (temp << 14) | (temp << 13) | (temp << 12) | + (temp << 11) | (temp << 10) | (temp << 9) | (temp << 8) | + (temp << 7) | (temp << 6) | (temp << 5) | (temp << 4) | + (temp << 3) | (temp << 2) | (temp << 1) | (temp); + JpuWriteReg(MJPEG_HUFF_DATA_REG, (((temp & 0xFFFFFF) << 8) | HuffData)); + } + for (i = 0; i < 162 - HuffLength; i++) { + JpuWriteReg(MJPEG_HUFF_DATA_REG, 0xFFFFFFFF); + } + + // VAL AC Chroma + HuffLength = 0; + for (i = 0; i < 162; i++) + HuffLength += jpg->huffBits[3][i]; + for (i = 0; i < HuffLength; i++) { // 8-bit, 162 row, 1 category (AC Chroma) + HuffData = jpg->huffVal[3][i]; + temp = (HuffData & 0x80) >> 7; + temp = (temp << 23) | (temp << 22) | (temp << 21) | + (temp << 20) | (temp << 19) | (temp << 18) | + (temp << 17) | (temp << 16) | (temp << 15) | + (temp << 14) | (temp << 13) | (temp << 12) | + (temp << 11) | (temp << 10) | (temp << 9) | (temp << 8) | + (temp << 7) | (temp << 6) | (temp << 5) | (temp << 4) | + (temp << 3) | (temp << 2) | (temp << 1) | (temp); + JpuWriteReg(MJPEG_HUFF_DATA_REG, (((temp & 0xFFFFFF) << 8) | HuffData)); + } + + for (i = 0; i < 162 - HuffLength; i++) { + JpuWriteReg(MJPEG_HUFF_DATA_REG, 0xFFFFFFFF); + } + + // end SerPeriHuffTab + JpuWriteReg(MJPEG_HUFF_CTRL_REG, 0x000); + + return 1; +} + +int JpgDecQMatTabSetUp(JpgDecInfo *jpg) +{ + + int i; + int table; + int val; + + // SetPeriQMatTab + // Comp 0 + JpuWriteReg(MJPEG_QMAT_CTRL_REG, 0x03); + table = jpg->cInfoTab[0][3]; + for (i = 0; i < 64; i++) { + val = jpg->qMatTab[table][i]; + JpuWriteReg(MJPEG_QMAT_DATA_REG, val); + } + JpuWriteReg(MJPEG_QMAT_CTRL_REG, 0x00); + + // Comp 1 + JpuWriteReg(MJPEG_QMAT_CTRL_REG, 0x43); + table = jpg->cInfoTab[1][3]; + for (i = 0; i < 64; i++) { + val = jpg->qMatTab[table][i]; + JpuWriteReg(MJPEG_QMAT_DATA_REG, val); + } + JpuWriteReg(MJPEG_QMAT_CTRL_REG, 0x00); + + // Comp 2 + JpuWriteReg(MJPEG_QMAT_CTRL_REG, 0x83); + table = jpg->cInfoTab[2][3]; + for (i = 0; i < 64; i++) { + val = jpg->qMatTab[table][i]; + JpuWriteReg(MJPEG_QMAT_DATA_REG, val); + } + JpuWriteReg(MJPEG_QMAT_CTRL_REG, 0x00); + return 1; +} + +void JpgDecGramSetup(JpgDecInfo *jpg) +{ + int dExtBitBufCurPos; + int dExtBitBufBaseAddr; + int dMibStatus; + + dMibStatus = 1; + dExtBitBufCurPos = jpg->pagePtr; + dExtBitBufBaseAddr = jpg->streamBufStartAddr; + + JpuWriteReg(MJPEG_BBC_CUR_POS_REG, dExtBitBufCurPos); + JpuWriteReg(MJPEG_BBC_EXT_ADDR_REG, dExtBitBufBaseAddr + (dExtBitBufCurPos << 8)); + JpuWriteReg(MJPEG_BBC_INT_ADDR_REG, (dExtBitBufCurPos & 1) << 6); + JpuWriteReg(MJPEG_BBC_DATA_CNT_REG, 256 / 4); // 64 * 4 byte == 32 * 8 byte + JpuWriteReg(MJPEG_BBC_COMMAND_REG, (jpg->streamEndian << 1) | 0); + + while (dMibStatus == 1) { + dMibStatus = JpuReadReg(MJPEG_BBC_BUSY_REG); + } + + dMibStatus = 1; + dExtBitBufCurPos = dExtBitBufCurPos + 1; + + JpuWriteReg(MJPEG_BBC_CUR_POS_REG, dExtBitBufCurPos); + JpuWriteReg(MJPEG_BBC_EXT_ADDR_REG, dExtBitBufBaseAddr + (dExtBitBufCurPos << 8)); + JpuWriteReg(MJPEG_BBC_INT_ADDR_REG, (dExtBitBufCurPos & 1) << 6); + JpuWriteReg(MJPEG_BBC_DATA_CNT_REG, 256 / 4); // 64 * 4 byte == 32 * 8 byte + JpuWriteReg(MJPEG_BBC_COMMAND_REG, (jpg->streamEndian << 1) | 0); + + while (dMibStatus == 1) { + dMibStatus = JpuReadReg(MJPEG_BBC_BUSY_REG); + } + + dMibStatus = 1; + dExtBitBufCurPos = dExtBitBufCurPos + 1; + + JpuWriteReg(MJPEG_BBC_CUR_POS_REG, dExtBitBufCurPos); // next unit page pointer + + JpuWriteReg(MJPEG_BBC_CTRL_REG, (jpg->streamEndian << 1) | 1); + + JpuWriteReg(MJPEG_GBU_WD_PTR_REG, jpg->wordPtr); + + JpuWriteReg(MJPEG_GBU_BBSR_REG, 0); + JpuWriteReg(MJPEG_GBU_BBER_REG, ((256 / 4) * 2) - 1); + + if (jpg->pagePtr & 1) { + JpuWriteReg(MJPEG_GBU_BBIR_REG, 0); + JpuWriteReg(MJPEG_GBU_BBHR_REG, 0); + } else { + JpuWriteReg(MJPEG_GBU_BBIR_REG, 256 / 4); // 64 * 4 byte == 32 * 8 byte + JpuWriteReg(MJPEG_GBU_BBHR_REG, 256 / 4); // 64 * 4 byte == 32 * 8 byte + } + + JpuWriteReg(MJPEG_GBU_CTRL_REG, 4); + JpuWriteReg(MJPEG_GBU_FF_RPTR_REG, jpg->bitPtr); +} + +enum { + SAMPLE_420 = 0xA, + SAMPLE_H422 = 0x9, + SAMPLE_V422 = 0x6, + SAMPLE_444 = 0x5, + SAMPLE_400 = 0x1 +}; + +const BYTE cDefHuffBits[4][16] = { + {// DC index 0 (Luminance DC) + 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, + {// AC index 0 (Luminance AC) + 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, + 0x00, 0x00, 0x01, 0x7D}, + {// DC index 1 (Chrominance DC) + 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00}, + {// AC index 1 (Chrominance AC) + 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04, + 0x00, 0x01, 0x02, 0x77} +}; + +const BYTE cDefHuffVal[4][162] = { + {// DC index 0 (Luminance DC) + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B}, + {// AC index 0 (Luminance AC) + 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, + 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, + 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24, 0x33, 0x62, 0x72, + 0x82, 0x09, 0x0A, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, + 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, + 0x76, 0x77, 0x78, 0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, + 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, + 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, + 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, + 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, + 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA}, + {// DC index 1 (Chrominance DC) + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B}, + {// AC index 1 (Chrominance AC) + 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, + 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, + 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, + 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, + 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, + 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, + 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, + 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, + 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, + 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, + 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA} +}; + +enum { + Marker = 0xFF, + FF_Marker = 0x00, + + SOI_Marker = 0xFFD8, // Start of image + EOI_Marker = 0xFFD9, // End of image + + JFIF_CODE = 0xFFE0, // Application + EXIF_CODE = 0xFFE1, + + DRI_Marker = 0xFFDD, // Define restart interval + RST_Marker = 0xD, // 0xD0 ~0xD7 + + DQT_Marker = 0xFFDB, // Define quantization table(s) + DHT_Marker = 0xFFC4, // Define Huffman table(s) + + SOF_Marker = 0xFFC0, // Start of frame : Baseline DCT + SOS_Marker = 0xFFDA, // Start of scan +}; + +int check_start_code(JpgDecInfo *jpg) +{ + if (show_bits(&jpg->gbc, 8) == 0xFF) + return 1; + else + return 0; +} + +int find_start_code(JpgDecInfo *jpg) +{ + int word; + + for (;;) { + if (get_bits_left(&jpg->gbc) <= 16) { + ////printf("hit end of stream\n"); + return 0; + } + + word = show_bits(&jpg->gbc, 16); + if (word > 0xFF00 && word < 0xFFFF) + break; + + get_bits(&jpg->gbc, 8); + } + + return word; +} + +int find_start_soi_code(JpgDecInfo *jpg) +{ + int word; + + for (;;) { + if (get_bits_left(&jpg->gbc) <= 16) { + ////printf("hit end of stream\n"); + return 0; + } + + word = show_bits(&jpg->gbc, 16); + if (word > 0xFF00 && word < 0xFFFF) { + if (word != SOI_Marker) + get_bits(&jpg->gbc, 8); + break; + } + + get_bits(&jpg->gbc, 8); + } + + return word; +} + +#ifdef MJPEG_ERROR_CONCEAL +int find_restart_marker(JpgDecInfo *jpg) +{ + int word; + + for (;;) { + if (get_bits_left(&jpg->gbc) <= 16) { + ////printf("hit end of stream\n"); + return -1; + } + + word = show_bits(&jpg->gbc, 16); + if ((word >= 0xFFD0 && word <= 0xFFD7) || word == 0xFFD8 || word == 0xFFD9) + break; + + get_bits(&jpg->gbc, 8); + } + + return word; +} +#endif + +int decode_app_header(JpgDecInfo *jpg) +{ + int length; + + if (get_bits_left(&jpg->gbc) < 16) + return 0; + length = get_bits(&jpg->gbc, 16); + length -= 2; + + while (length-- > 0) { + if (get_bits_left(&jpg->gbc) < 8) + return 0; + get_bits(&jpg->gbc, 8); + } + + return 1; +} + +int decode_dri_header(JpgDecInfo *jpg) +{ + // Length, Lr + if (get_bits_left(&jpg->gbc) < 16 * 2) + return 0; + get_bits(&jpg->gbc, 16); + + jpg->rstIntval = get_bits(&jpg->gbc, 16); + + return 1; +} + +int decode_dqt_header(JpgDecInfo *jpg) +{ + int Pq; + int Tq; + int i; + int tmp; + + if (get_bits_left(&jpg->gbc) < 16) + return 0; + + // Lq, Length of DQT + get_bits(&jpg->gbc, 16); + + do { + + if (get_bits_left(&jpg->gbc) < 4 + 4 + 8 * 64) + return 0; + + // Pq, Quantization Precision + tmp = get_bits(&jpg->gbc, 8); + // Tq, Quantization table destination identifier + Pq = (tmp >> 4) & 0xf; + Tq = tmp & 0xf; + + for (i = 0; i < 64; i++) + jpg->qMatTab[Tq][i] = (BYTE)get_bits(&jpg->gbc, 8); + } while (!check_start_code(jpg)); + + if (Pq != 0) {// not 8-bit + ////printf("pq is not set to zero\n"); + return 0; + } + return 1; +} + +int decode_dth_header(JpgDecInfo *jpg) +{ + int Tc; + int Th; + int ThTc; + int bitCnt; + int i; + int tmp; + // Length, Lh + if (get_bits_left(&jpg->gbc) < 16) + return 0; + + get_bits(&jpg->gbc, 16); + + do { + + if (get_bits_left(&jpg->gbc) < 8 + 8 * 16) + return 0; + + // Table class - DC, AC + tmp = get_bits(&jpg->gbc, 8); + // Table destination identifier + Tc = (tmp >> 4) & 0xf; + Th = tmp & 0xf; + + // DC_ID0 (0x00) -> 0 + // AC_ID0 (0x10) -> 1 + // DC_ID1 (0x01) -> 2 + // AC_ID1 (0x11) -> 3 + ThTc = ((Th & 1) << 1) | (Tc & 1); + + // Get Huff Bits list + bitCnt = 0; + for (i = 0; i < 16; i++) { + jpg->huffBits[ThTc][i] = (BYTE)get_bits(&jpg->gbc, 8); + bitCnt += jpg->huffBits[ThTc][i]; + + if (cDefHuffBits[ThTc][i] != jpg->huffBits[ThTc][i]) + jpg->userHuffTab = 1; + } + + if (get_bits_left(&jpg->gbc) < 8 * bitCnt) + return 0; + + // Get Huff Val list + for (i = 0; i < bitCnt; i++) { + jpg->huffVal[ThTc][i] = (BYTE)get_bits(&jpg->gbc, 8); + if (cDefHuffVal[ThTc][i] != jpg->huffVal[ThTc][i]) + jpg->userHuffTab = 1; + } + } while (!check_start_code(jpg)); + + return 1; +} + +int decode_sof_header(JpgDecInfo *jpg) +{ + int samplePrecision; + int sampleFactor; + int i; + int Tqi; + BYTE compID; + int hSampFact[3] = { + 0, + }; + int vSampFact[3] = { + 0, + }; + int picX, picY; + int numComp; + int tmp; + + if (get_bits_left(&jpg->gbc) < 16 + 8 + 16 + 16 + 8) + return 0; + // LF, Length of SOF + get_bits(&jpg->gbc, 16); + + // Sample Precision: Baseline(8), P + samplePrecision = get_bits(&jpg->gbc, 8); + + if (samplePrecision != 8) { + // printf("Sample Precision is not 8\n"); + return 0; + } + + picY = get_bits(&jpg->gbc, 16); + if (picY > MAX_MJPG_PIC_WIDTH) { + // printf("Picture Vertical Size limits Maximum size\n"); + return 0; + } + + picX = get_bits(&jpg->gbc, 16); + if (picX > MAX_MJPG_PIC_HEIGHT) { + // printf("Picture Horizontal Size limits Maximum size\n"); + return 0; + } + + // Number of Components in Frame: Nf + numComp = get_bits(&jpg->gbc, 8); + if (numComp > 3) { + // printf("Picture Horizontal Size limits Maximum size\n"); + } + + if (get_bits_left(&jpg->gbc) < numComp * (8 + 4 + 4 + 8)) + return 0; + for (i = 0; i < numComp; i++) { + // Component ID, Ci 0 ~ 255 + compID = (BYTE)get_bits(&jpg->gbc, 8); + tmp = get_bits(&jpg->gbc, 8); + // Horizontal Sampling Factor, Hi + hSampFact[i] = (tmp >> 4) & 0xf; + // Vertical Sampling Factor, Vi + vSampFact[i] = tmp & 0xf; + // Quantization Table Selector, Tqi + Tqi = get_bits(&jpg->gbc, 8); + + jpg->cInfoTab[i][0] = compID; + jpg->cInfoTab[i][1] = (BYTE)hSampFact[i]; + jpg->cInfoTab[i][2] = (BYTE)vSampFact[i]; + jpg->cInfoTab[i][3] = (BYTE)Tqi; + } + + // if ( hSampFact[0]>2 || vSampFact[0]>2 || ( numComp == 3 && ( + // hSampFact[1]!=1 || hSampFact[2]!=1 || vSampFact[1]!=1 || + // vSampFact[2]!=1) ) ) printf("Not Supported Sampling Factor\n"); + + if (numComp == 1) + sampleFactor = SAMPLE_400; + else + sampleFactor = ((hSampFact[0] & 3) << 2) | (vSampFact[0] & 3); + + switch (sampleFactor) { + case SAMPLE_420: + jpg->format = FORMAT_420; + break; + case SAMPLE_H422: + jpg->format = FORMAT_422; + break; + case SAMPLE_V422: + jpg->format = FORMAT_224; + break; + case SAMPLE_444: + jpg->format = FORMAT_444; + break; + default: // 4:0:0 + jpg->format = FORMAT_400; + } + + jpg->picWidth = picX; + jpg->picHeight = picY; + + return 1; +} + +int decode_sos_header(JpgDecInfo *jpg) +{ + int i, j; + int len; + int numComp; + int compID; + int ecsPtr; + int ss, se, ah, al; + int dcHufTblIdx[3] = { + 0, + }; + int acHufTblIdx[3] = { + 0, + }; + int tmp; + + if (get_bits_left(&jpg->gbc) < 8) + return 0; + // Length, Ls + len = get_bits(&jpg->gbc, 16); + + jpg->ecsPtr = get_bits_count(&jpg->gbc) / 8 + len - 2; + + ecsPtr = jpg->ecsPtr + jpg->frameOffset; + + // printf("ecsPtr=0x%x frameOffset=0x%x, ecsOffset=0x%x, wrPtr=0x%x, + // rdPtr0x%x\n", jpg->ecsPtr, jpg->frameOffset, ecsPtr, + // jpg->streamWrPtr, jpg->streamRdPtr); + + jpg->pagePtr = ecsPtr >> 8; // page unit ecsPtr/256; + jpg->wordPtr = (ecsPtr & 0xF0) >> 2; // word unit ((ecsPtr % 256) & 0xF0) / 4; + + if (jpg->pagePtr & 1) + jpg->wordPtr += 64; + if (jpg->wordPtr & 1) + jpg->wordPtr -= 1; // to make even. + + jpg->bitPtr = (ecsPtr & 0xF) << 3; // bit unit (ecsPtr & 0xF) * 8; + + if (get_bits_left(&jpg->gbc) < 8) + return 0; + // Number of Components in Scan: Ns + numComp = get_bits(&jpg->gbc, 8); + + if (get_bits_left(&jpg->gbc) < numComp * (8 + 4 + 4)) + return 0; + for (i = 0; i < numComp; i++) { + // Component ID, Csj 0 ~ 255 + compID = get_bits(&jpg->gbc, 8); + tmp = get_bits(&jpg->gbc, 8); + // dc entropy coding table selector, Tdj + dcHufTblIdx[i] = (tmp >> 4) & 0xf; + // ac entropy coding table selector, Taj + acHufTblIdx[i] = tmp & 0xf; + + for (j = 0; j < numComp; j++) { + if (compID == jpg->cInfoTab[j][0]) { + jpg->cInfoTab[j][4] = (BYTE)dcHufTblIdx[i]; + jpg->cInfoTab[j][5] = (BYTE)acHufTblIdx[i]; + } + } + } + + if (get_bits_left(&jpg->gbc) < 8 + 8 + 4 + 4) + return 0; + // Ss 0 + ss = get_bits(&jpg->gbc, 8); + // Se 3F + se = get_bits(&jpg->gbc, 8); + tmp = get_bits(&jpg->gbc, 8); + // Ah 0 + ah = (i >> 4) & 0xf; + // Al 0 + al = tmp & 0xf; + + if (ss != 0 || se != 0x3F || ah != 0 || al != 0) { + // printf("The Jpeg Image must be another profile\n"); + return 0; + } + + return 1; +} + +static void genDecHuffTab(JpgDecInfo *jpg, int tabNum) +{ + unsigned char *huffPtr, *huffBits; + unsigned int *huffMax, *huffMin; + + int ptrCnt = 0; + int huffCode = 0; + int zeroFlag = 0; + int dataFlag = 0; + int i; + + huffBits = jpg->huffBits[tabNum]; + huffPtr = jpg->huffPtr[tabNum]; + huffMax = jpg->huffMax[tabNum]; + huffMin = jpg->huffMin[tabNum]; + + for (i = 0; i < 16; i++) { + if (huffBits[i]) { // if there is bit cnt value + huffPtr[i] = (BYTE)ptrCnt; + ptrCnt += huffBits[i]; + huffMin[i] = huffCode; + huffMax[i] = huffCode + (huffBits[i] - 1); + dataFlag = 1; + zeroFlag = 0; + } else { + huffPtr[i] = 0xFF; + huffMin[i] = 0xFFFF; + huffMax[i] = 0xFFFF; + zeroFlag = 1; + } + + if (dataFlag == 1) { + if (zeroFlag == 1) + huffCode <<= 1; + else + huffCode = (huffMax[i] + 1) << 1; + } + } +} + +int JpuGbuInit(vpu_getbit_context_t *ctx, BYTE *buffer, int size) +{ + + ctx->buffer = buffer; + ctx->index = 0; + ctx->size = size / 8; + + return 1; +} + +int JpuGbuGetUsedBitCount(vpu_getbit_context_t *ctx) { return ctx->index * 8; } + +int JpuGbuGetLeftBitCount(vpu_getbit_context_t *ctx) +{ + return (ctx->size * 8) - JpuGbuGetUsedBitCount(ctx); +} + +unsigned int JpuGbuGetBit(vpu_getbit_context_t *ctx, int bit_num) +{ + BYTE *p; + unsigned int b = 0x0; + + if (bit_num > JpuGbuGetLeftBitCount(ctx)) + return (unsigned int)-1; + + p = ctx->buffer + ctx->index; + + if (bit_num == 8) { + b = *p; + ctx->index++; + } else if (bit_num == 16) { + b = *p++ << 8; + b |= *p++; + ctx->index += 2; + } else if (bit_num == 32) { + b = *p++ << 24; + b |= (*p++ << 16); + b |= (*p++ << 8); + b |= (*p++ << 0); + ctx->index += 4; + } + + return b; +} + +unsigned int JpuGguShowBit(vpu_getbit_context_t *ctx, int bit_num) +{ + BYTE *p; + unsigned int b = 0x0; + + if (bit_num > JpuGbuGetLeftBitCount(ctx)) + return (unsigned int)-1; + + p = ctx->buffer + ctx->index; + + if (bit_num == 8) { + b = *p; + } else if (bit_num == 16) { + b = *p++ << 8; + b |= *p++; + } else if (bit_num == 32) { + b = *p++ << 24; + b |= (*p++ << 16); + b |= (*p++ << 8); + b |= (*p++ << 0); + } + + return b; +} + +static int wraparound_bistream_data(JpgDecInfo *jpg, int return_type) +{ + BYTE *dst; + BYTE *src; + BYTE *data; + int data_size; + int src_size; + int dst_size; + + data_size = jpg->streamWrPtr - jpg->streamBufStartAddr; + data = (BYTE *)OSAL_MALLOC(data_size); + + if (data_size && data) + JpuReadMem(jpg->streamBufStartAddr, data, data_size, + jpg->streamEndian); + + src_size = jpg->streamBufSize - jpg->frameOffset; + src = (BYTE *)OSAL_MALLOC(src_size); + dst_size = ((src_size + (JPU_GBU_SIZE - 1)) & ~(JPU_GBU_SIZE - 1)); + dst = (BYTE *)OSAL_MALLOC(dst_size); + if (dst && src) { + memset(dst, 0x00, dst_size); + JpuReadMem(jpg->streamBufStartAddr + jpg->frameOffset, src, src_size, jpg->streamEndian); + memcpy(dst + (dst_size - src_size), src, src_size); + JpuWriteMem(jpg->streamBufStartAddr, dst, dst_size, jpg->streamEndian); + if (data_size && data) + JpuWriteMem(jpg->streamBufStartAddr + dst_size, data, data_size, jpg->streamEndian); + OSAL_FREE(src); + OSAL_FREE(dst); + } + + if (data_size && data) + OSAL_FREE(data); + + if (return_type == -2) { // header wraparound + jpg->streamWrPtr = jpg->streamBufStartAddr + dst_size + data_size; + jpg->consumeByte = 0; + return -2; + } else if (return_type == -1) { // ecsPtr wraparound + jpg->streamWrPtr = jpg->streamBufStartAddr + dst_size + data_size; + jpg->frameOffset = 0; + return -1; + } + + return 0; // error +} + +#ifdef MJPEG_ERROR_CONCEAL +int JpegDecodeConcealError(JpgDecInfo *jpg) +{ + unsigned int code; + int ret, foced_stop = 0; + BYTE *b; + Uint32 ecsPtr = 0; + Uint32 size, wrOffset; + Uint32 nextMarkerPtr; + Uint32 iRstIdx; + int numMcu = 0, numMcuCol = 0; + + // "nextOffset" is distance between frameOffset and next_restart_index + // that exist. + nextMarkerPtr = jpg->nextOffset + jpg->frameOffset; + + if (jpg->streamWrPtr == jpg->streamBufStartAddr) { + size = jpg->streamBufSize - nextMarkerPtr; + wrOffset = jpg->streamBufSize; + } else { + size = jpg->streamWrPtr - nextMarkerPtr; + wrOffset = (jpg->streamWrPtr - jpg->streamBufStartAddr); + } + + // pointing to find next_restart_marker + b = jpg->pBitStream + nextMarkerPtr; + init_get_bits(&jpg->gbc, b, size * 8); + + for (;;) { + + ret = find_restart_marker(jpg); + if (ret < 0) { + break; + } + + code = get_bits(&jpg->gbc, 16); + if (code == 0xFFD8 || code == 0xFFD9) { + // if next_start_maker meet EOI(end of picture) or next + // SOI(start of image) but decoding is not completed + // yet, To prevent over picture boundary in ringbuffer + // mode, finding previous maker and make decoding forced + // to stop. + b = jpg->pBitStream + jpg->currOffset + jpg->frameOffset; + init_get_bits(&jpg->gbc, b, size * 8); + + nextMarkerPtr = jpg->currOffset + jpg->frameOffset; + foced_stop = 1; + continue; + } + + iRstIdx = (code & 0xF); + // you can find next restart marker which will be. + if (iRstIdx >= 0 && iRstIdx <= 7) { + int numMcuRow; + + if (get_bits_left(&jpg->gbc) < 8) + return (-1); + + jpg->ecsPtr = get_bits_count(&jpg->gbc) / 8; + // set ecsPtr that restart marker is founded. + ecsPtr = jpg->ecsPtr + nextMarkerPtr; + + jpg->pagePtr = ecsPtr >> 8; + jpg->wordPtr = (ecsPtr & 0xF0) >> 2; // word unit + if (jpg->pagePtr & 1) + jpg->wordPtr += 64; + if (jpg->wordPtr & 1) + jpg->wordPtr -= 1; // to make even. + + jpg->bitPtr = (ecsPtr & 0xF) << 3; // bit unit + + numMcuRow = (jpg->alignedWidth / jpg->mcuWidth); + numMcuCol = (jpg->alignedHeight / jpg->mcuHeight); + + // num of restart marker that is rounded can be + // calculated from error position. + // numRstMakerRounding = + // ((jpg->errInfo.errPosY*numMcuRow + + // jpg->errInfo.errPosX) / (jpg->rstIntval*8)); + jpg->curRstIdx = iRstIdx; + if (jpg->curRstIdx < jpg->nextRstIdx) + jpg->numRstMakerRounding++; + + // find mcu position to restart. + numMcu = + (jpg->numRstMakerRounding * jpg->rstIntval * 8) + + (jpg->curRstIdx + 1) * jpg->rstIntval; + // numMcu = jpg->rstIntval; + jpg->setPosX = (numMcu % numMcuRow); + jpg->setPosY = (numMcu / numMcuRow); + jpg->gbuStartPtr = ((ecsPtr - jpg->frameOffset) / 256) * 256; + + // if setPosY is greater than Picture Height, set mcu + // position to last mcu of picture to finish decoding. + if (jpg->setPosY > numMcuCol || foced_stop) { + jpg->setPosX = numMcuRow - 1; + jpg->setPosY = numMcuCol - 1; + } + + // update restart_index to find next. + jpg->nextRstIdx = iRstIdx++; + + ret = 0; + break; + } + } + + // prevent to find same position. + jpg->currOffset = jpg->nextOffset; + + // if the distance between ecsPtr and streamBufEndAddr is less than + // 512byte, that rdPtr run over than streamBufEndAddr without interrupt. + // bellow is workaround to avoid this case. + if (jpg->streamBufSize - (jpg->frameOffset + ecsPtr) < JPU_GBU_SIZE) + // if((jpg->streamBufEndAddr - ecsPtr < JPU_GBU_SIZE) ) + { + ret = wraparound_bistream_data(jpg, -1); + } + + if (wrOffset - (jpg->frameOffset + jpg->ecsPtr) < JPU_GBU_SIZE && jpg->streamEndflag == 0) { + return -1; + } + return ret; +} +#endif + +int JpegDecodeHeader(JpgDecInfo *jpg) +{ + + unsigned int code; + int ret; + int i; + int temp; + int wrOffset; + BYTE *b = jpg->pBitStream + jpg->frameOffset; + int size; + + ret = 1; + if (jpg->streamWrPtr == jpg->streamBufStartAddr) { + size = jpg->streamBufSize - jpg->frameOffset; + wrOffset = jpg->streamBufSize; + } else { + if (jpg->frameOffset >= (int)(jpg->streamWrPtr - jpg->streamBufStartAddr)) + size = jpg->streamBufSize - jpg->frameOffset; + else + size = (jpg->streamWrPtr - jpg->streamBufStartAddr) - jpg->frameOffset; + wrOffset = (jpg->streamWrPtr - jpg->streamBufStartAddr); + } + + if (!b || !size) { + ret = -1; + BM_DBG_ERR("DONE_DEC_HEADER\n"); + goto DONE_DEC_HEADER; + } + + // find start code of next frame + if (!jpg->ecsPtr) { + int nextOffset = 0; + int soiOffset = 0; + + if (jpg->consumeByte != 0) { // meaning is frameIdx > 0 + nextOffset = jpg->consumeByte; + if (nextOffset <= 0) + nextOffset = 2; // in order to consume start code. + } + + // consume to find the start code of next frame. + b += nextOffset; + size -= nextOffset; + + if (size < 0) { + jpg->consumeByte -= (b - (jpg->pBitStream + jpg->streamBufSize)); + if (jpg->consumeByte < 0) { + ret = 0; + goto DONE_DEC_HEADER; + } + ret = -1; + BM_DBG_ERR("DONE_DEC_HEADER\n"); + goto DONE_DEC_HEADER; + } + + init_get_bits(&jpg->gbc, b, size * 8); + for (;;) { + code = find_start_soi_code(jpg); + if (code == 0) { + ret = -1; + BM_DBG_ERR("DONE_DEC_HEADER\n"); + goto DONE_DEC_HEADER; + } + + if (code == SOI_Marker) + break; + } + + soiOffset = get_bits_count(&jpg->gbc) / 8; + + b += soiOffset; + size -= soiOffset; + jpg->frameOffset += (soiOffset + nextOffset); + } + + if (jpg->headerSize > 0 && (jpg->headerSize > (jpg->streamBufSize - jpg->frameOffset))) { + // if header size is smaller than room of stream end. copy the buffer to bistream start. + BM_DBG_ERR("\n"); + return wraparound_bistream_data(jpg, -2); + } + + init_get_bits(&jpg->gbc, b, size * 8); + // Initialize component information table + for (i = 0; i < 4; i++) { + jpg->cInfoTab[i][0] = 0; + jpg->cInfoTab[i][1] = 0; + jpg->cInfoTab[i][2] = 0; + jpg->cInfoTab[i][3] = 0; + jpg->cInfoTab[i][4] = 0; + jpg->cInfoTab[i][5] = 0; + } + + for (;;) { + if (find_start_code(jpg) == 0) { + ret = -1; + BM_DBG_ERR("DONE_DEC_HEADER\n"); + goto DONE_DEC_HEADER; + } + + code = get_bits(&jpg->gbc, 16); // getbit 2byte + + switch (code) { + case SOI_Marker: + break; + case JFIF_CODE: + case EXIF_CODE: { + if (!decode_app_header(jpg)) { + ret = -1; + BM_DBG_ERR("DONE_DEC_HEADER\n"); + goto DONE_DEC_HEADER; + } + } + + break; + case DRI_Marker: + if (!decode_dri_header(jpg)) { + ret = -1; + BM_DBG_ERR("DONE_DEC_HEADER\n"); + goto DONE_DEC_HEADER; + } + break; + case DQT_Marker: + if (!decode_dqt_header(jpg)) { + ret = -1; + BM_DBG_ERR("DONE_DEC_HEADER\n"); + goto DONE_DEC_HEADER; + } + break; + case DHT_Marker: + if (!decode_dth_header(jpg)) { + ret = -1; + BM_DBG_ERR("DONE_DEC_HEADER\n"); + goto DONE_DEC_HEADER; + } + break; + case SOF_Marker: + if (!decode_sof_header(jpg)) { + ret = -1; + BM_DBG_ERR("DONE_DEC_HEADER\n"); + goto DONE_DEC_HEADER; + } + break; + case SOS_Marker: + if (!decode_sos_header(jpg)) { + ret = -1; + BM_DBG_ERR("DONE_DEC_HEADER\n"); + goto DONE_DEC_HEADER; + } + // we assume header size of all frame is same for mjpeg case + if (!jpg->headerSize) + jpg->headerSize = jpg->ecsPtr; + goto DONE_DEC_HEADER; +// break; + case EOI_Marker: + goto DONE_DEC_HEADER; + default: + switch (code & 0xFFF0) { + case 0xFFE0: // 0xFFEX + case 0xFFF0: // 0xFFFX + if (get_bits_left(&jpg->gbc) <= 0) { + { + ret = -1; + BM_DBG_ERR("DONE_DEC_HEADER\n"); + goto DONE_DEC_HEADER; + } + } else { + if (!decode_app_header(jpg)) { + ret = -1; + BM_DBG_ERR("DONE_DEC_HEADER\n"); + goto DONE_DEC_HEADER; + } + break; + } + default: + // in case, restart marker is founded. + if ((code & 0xFFF0) >= 0xFFD0 && (code & 0xFFF0) <= 0xFFD7) + break; + + return 0; + } + break; + } + } + +DONE_DEC_HEADER: + + if (ret == -1) { + if (wrOffset < jpg->frameOffset) { + BM_DBG_ERR("fail\n"); + return -2; + } + + BM_DBG_ERR("fail\n"); + return -1; + } + + if (!jpg->ecsPtr) { + BM_DBG_ERR("fail\n"); + return 0; + } + + if (wrOffset - (jpg->frameOffset + jpg->ecsPtr) < JPU_GBU_SIZE && jpg->streamEndflag == 0) { + BM_DBG_ERR("fail\n"); + return -1; + } + + // this bellow is workaround to avoid the case that JPU is run over + // without interrupt. + if (jpg->streamBufSize - (jpg->frameOffset + jpg->ecsPtr) < JPU_GBU_SIZE) { + BM_DBG_ERR("fail\n"); + return wraparound_bistream_data(jpg, -1); + } + + // Generate Huffman table information + for (i = 0; i < 4; i++) + genDecHuffTab(jpg, i); + + // Q Idx + temp = jpg->cInfoTab[0][3]; + temp = temp << 1 | jpg->cInfoTab[1][3]; + temp = temp << 1 | jpg->cInfoTab[2][3]; + jpg->Qidx = temp; + + // Huff Idx[DC, AC] + temp = jpg->cInfoTab[0][4]; + temp = temp << 1 | jpg->cInfoTab[1][4]; + temp = temp << 1 | jpg->cInfoTab[2][4]; + jpg->huffDcIdx = temp; + + temp = jpg->cInfoTab[0][5]; + temp = temp << 1 | jpg->cInfoTab[1][5]; + temp = temp << 1 | jpg->cInfoTab[2][5]; + jpg->huffAcIdx = temp; + + switch (jpg->format) { + case FORMAT_420: + jpg->busReqNum = 2; + jpg->mcuBlockNum = 6; + jpg->compNum = 3; + jpg->compInfo[0] = 10; + jpg->compInfo[1] = 5; + jpg->compInfo[2] = 5; + jpg->alignedWidth = ((jpg->picWidth + 15) & ~15); + jpg->alignedHeight = ((jpg->picHeight + 15) & ~15); + jpg->mcuWidth = 16; + jpg->mcuHeight = 16; + break; + case FORMAT_422: + jpg->busReqNum = 3; + jpg->mcuBlockNum = 4; + jpg->compNum = 3; + jpg->compInfo[0] = 9; + jpg->compInfo[1] = 5; + jpg->compInfo[2] = 5; + jpg->alignedWidth = ((jpg->picWidth + 15) & ~15); + jpg->alignedHeight = ((jpg->picHeight + 7) & ~7); + jpg->mcuWidth = 16; + jpg->mcuHeight = 8; + break; + case FORMAT_224: + jpg->busReqNum = 3; + jpg->mcuBlockNum = 4; + jpg->compNum = 3; + jpg->compInfo[0] = 6; + jpg->compInfo[1] = 5; + jpg->compInfo[2] = 5; + jpg->alignedWidth = ((jpg->picWidth + 7) & ~7); + jpg->alignedHeight = ((jpg->picHeight + 15) & ~15); + jpg->mcuWidth = 8; + jpg->mcuHeight = 16; + break; + case FORMAT_444: + jpg->busReqNum = 4; + jpg->mcuBlockNum = 3; + jpg->compNum = 3; + jpg->compInfo[0] = 5; + jpg->compInfo[1] = 5; + jpg->compInfo[2] = 5; + jpg->alignedWidth = ((jpg->picWidth + 7) & ~7); + jpg->alignedHeight = ((jpg->picHeight + 7) & ~7); + jpg->mcuWidth = 8; + jpg->mcuHeight = 8; + break; + case FORMAT_400: + jpg->busReqNum = 4; + jpg->mcuBlockNum = 1; + jpg->compNum = 1; + jpg->compInfo[0] = 5; + jpg->compInfo[1] = 0; + jpg->compInfo[2] = 0; + jpg->alignedWidth = ((jpg->picWidth + 7) & ~7); + jpg->alignedHeight = ((jpg->picHeight + 7) & ~7); + jpg->mcuWidth = 8; + jpg->mcuHeight = 8; + break; + } + + return 1; +} + +JpgRet CheckJpgEncOpenParam(JpgEncOpenParam *pop) +{ + int picWidth; + int picHeight; + + if (pop == 0) { + BM_DBG_ERR("JPG_RET_INVALID_PARAM\n"); + return JPG_RET_INVALID_PARAM; + } + + picWidth = pop->picWidth; + picHeight = pop->picHeight; + + if (pop->bitstreamBuffer % 8) { + BM_DBG_ERR("bitstreamBuffer, JPG_RET_INVALID_PARAM\n"); + return JPG_RET_INVALID_PARAM; + } + if (pop->bitstreamBufferSize % 1024 || + pop->bitstreamBufferSize < 1024 || + pop->bitstreamBufferSize > 16383 * 1024) { + BM_DBG_ERR("JPG_RET_INVALID_PARAM\n"); + return JPG_RET_INVALID_PARAM; + } + + if (picWidth < 16 || picWidth > MAX_MJPG_PIC_WIDTH) { + BM_DBG_ERR("JPG_RET_INVALID_PARAM, picWidth = %d\n", picWidth); + return JPG_RET_INVALID_PARAM; + } + if (picHeight < 16 || picHeight > MAX_MJPG_PIC_HEIGHT) { + BM_DBG_ERR("JPG_RET_INVALID_PARAM, picHeight = %d\n", + picHeight); + return JPG_RET_INVALID_PARAM; + } + + return JPG_RET_SUCCESS; +} + +JpgRet CheckJpgEncParam(JpgEncHandle handle, JpgEncParam *param) +{ + JpgInst *pJpgInst; + JpgEncInfo *pEncInfo; + + pJpgInst = handle; + pEncInfo = &pJpgInst->JpgInfo.encInfo; + + if (param == 0) { + return JPG_RET_INVALID_PARAM; + } + + if (pEncInfo->packedFormat != PACKED_FORMAT_NONE) { + if (pEncInfo->packedFormat == PACKED_FORMAT_444) { + if (param->sourceFrame->stride < pEncInfo->openParam.picWidth * 2) { + return JPG_RET_INVALID_PARAM; + } + } + if (pEncInfo->packedFormat == PACKED_FORMAT_444) { + if (param->sourceFrame->stride < pEncInfo->openParam.picWidth * 3) { + return JPG_RET_INVALID_PARAM; + } + } + } + + return JPG_RET_SUCCESS; +} + +int JpgEncGenHuffTab(JpgEncInfo *pEncInfo, int tabNum) +{ + int p, i, l, lastp, si, maxsymbol; + + int huffsize[256] = { + 0, + }; + int huffcode[256] = { + 0, + }; + int code; + + BYTE *bitleng, *huffval; + unsigned int *ehufco, *ehufsi; + + bitleng = pEncInfo->pHuffBits[tabNum]; + huffval = pEncInfo->pHuffVal[tabNum]; + ehufco = pEncInfo->huffCode[tabNum]; + ehufsi = pEncInfo->huffSize[tabNum]; + + maxsymbol = tabNum & 1 ? 256 : 16; + + /* Figure C.1: make table of Huffman code length for each symbol */ + + p = 0; + for (l = 1; l <= 16; l++) { + i = bitleng[l - 1]; + if (i < 0 || p + i > maxsymbol) + return 0; + while (i--) + huffsize[p++] = l; + } + lastp = p; + + /* Figure C.2: generate the codes themselves */ + /* We also validate that the counts represent a legal Huffman code tree. + */ + + code = 0; + si = huffsize[0]; + p = 0; + while (huffsize[p] != 0) { + while (huffsize[p] == si) { + huffcode[p++] = code; + code++; + } + if (code >= (1 << si)) + return 0; + code <<= 1; + si++; + } + + /* Figure C.3: generate encoding tables */ + /* These are code and size indexed by symbol value */ + + for (i = 0; i < 256; i++) + ehufsi[i] = 0x00; + + for (i = 0; i < 256; i++) + ehufco[i] = 0x00; + + for (p = 0; p < lastp; p++) { + i = huffval[p]; + if (i < 0 || i >= maxsymbol || ehufsi[i]) + return 0; + ehufco[i] = huffcode[p]; + ehufsi[i] = huffsize[p]; + } + + return 1; +} + +int JpgEncLoadHuffTab(JpgEncInfo *pEncInfo) +{ + int i, j, t; + int huffData; + + for (i = 0; i < 4; i++) + JpgEncGenHuffTab(pEncInfo, i); + + JpuWriteReg(MJPEG_HUFF_CTRL_REG, 0x3); + + for (j = 0; j < 4; j++) { + + t = (j == 0) ? AC_TABLE_INDEX0 + : (j == 1) ? AC_TABLE_INDEX1 + : (j == 2) ? DC_TABLE_INDEX0 + : DC_TABLE_INDEX1; + + for (i = 0; i < 256; i++) { + if ((t == DC_TABLE_INDEX0 || t == DC_TABLE_INDEX1) && i > 15) // DC + break; + + if (pEncInfo->huffSize[t][i] == 0 && pEncInfo->huffCode[t][i] == 0) + huffData = 0; + else { + huffData = (pEncInfo->huffSize[t][i] - 1); // Code length (1 ~ 16), 4-bit + huffData = (huffData << 16) | (pEncInfo->huffCode[t][i]); // Code word, 16-bit + } + JpuWriteReg(MJPEG_HUFF_DATA_REG, huffData); + } + } + JpuWriteReg(MJPEG_HUFF_CTRL_REG, 0x0); + return 1; +} + +int JpgEncLoadQMatTab(JpgEncInfo *pEncInfo) +{ + +#ifdef WIN32 + __int64 dividend = 0x80000; + __int64 quotient; +#else + long long dividend = 0x80000; + long long quotient; +#endif + int quantID; + int divisor; + int comp; + int i, t; + + for (comp = 0; comp < 3; comp++) { + quantID = pEncInfo->pCInfoTab[comp][3]; + if (quantID >= 4) + return 0; + t = (comp == 0) ? Q_COMPONENT0 + : (comp == 1) ? Q_COMPONENT1 : Q_COMPONENT2; + JpuWriteReg(MJPEG_QMAT_CTRL_REG, 0x3 + t); + for (i = 0; i < 64; i++) { + divisor = pEncInfo->pQMatTab[quantID][i]; + quotient = dividend / divisor; + // enhace bit precision & rounding Q + JpuWriteReg(MJPEG_QMAT_DATA_REG, (int)(divisor << 20) | (int)(quotient & 0xFFFFF)); + } + JpuWriteReg(MJPEG_QMAT_CTRL_REG, t); + } + + return 1; +} + +int JpgEncEncodeHeader(JpgEncHandle handle, JpgEncParamSet *para) +{ + JpgInst *pJpgInst; + JpgEncInfo *pEncInfo; + // BYTE *p; + int i; + BYTE *pCInfoTab[4]; + int frameFormat; + Uint32 val; + + pJpgInst = handle; + pEncInfo = &pJpgInst->JpgInfo.encInfo; + + if (!para) + return 0; + + // p = para->pParaSet; + // len = para->size; + + // SOI Header + JpuWriteReg(MJPEG_GBU_PBIT_16_REG, 0xFFD8); + + if (!para->disableAPPMarker) { + JpuWriteReg(MJPEG_GBU_PBIT_32_REG, 0xFFE90004); + // APP9 Header + JpuWriteReg(MJPEG_GBU_PBIT_16_REG, pEncInfo->frameIdx); + } + + // DRI header + if (pEncInfo->rstIntval) { + JpuWriteReg(MJPEG_GBU_PBIT_32_REG, 0xFFDD0004); + JpuWriteReg(MJPEG_GBU_PBIT_16_REG, pEncInfo->rstIntval); + } + + // DQT Header + JpuWriteReg(MJPEG_GBU_PBIT_16_REG, 0xFFDB); + + if (para->quantMode == JPG_TBL_NORMAL) { + JpuWriteReg(MJPEG_GBU_PBIT_24_REG, 0x004300); + + for (i = 0; i < 64; i += 4) { + val = pEncInfo->pQMatTab[0][i] << 24; + val |= pEncInfo->pQMatTab[0][i + 1] << 16; + val |= pEncInfo->pQMatTab[0][i + 2] << 8; + val |= pEncInfo->pQMatTab[0][i + 3]; + JpuWriteReg(MJPEG_GBU_PBIT_32_REG, val); + } + + if (pEncInfo->format != FORMAT_400) { + JpuWriteReg(MJPEG_GBU_PBIT_32_REG, 0xFFDB0043); + JpuWriteReg(MJPEG_GBU_PBIT_08_REG, 0x01); + + for (i = 0; i < 64; i += 4) { + val = pEncInfo->pQMatTab[1][i] << 24; + val |= pEncInfo->pQMatTab[1][i + 1] << 16; + val |= pEncInfo->pQMatTab[1][i + 2] << 8; + val |= pEncInfo->pQMatTab[1][i + 3]; + JpuWriteReg(MJPEG_GBU_PBIT_32_REG, val); + } + } + } else { // if (para->quantMode == JPG_TBL_MERGE) + if (pEncInfo->format != FORMAT_400) { + JpuWriteReg(MJPEG_GBU_PBIT_24_REG, 0x008400); + } else { + JpuWriteReg(MJPEG_GBU_PBIT_24_REG, 0x004300); + } + + for (i = 0; i < 64; i += 4) { + val = pEncInfo->pQMatTab[0][i] << 24; + val |= pEncInfo->pQMatTab[0][i + 1] << 16; + val |= pEncInfo->pQMatTab[0][i + 2] << 8; + val |= pEncInfo->pQMatTab[0][i + 3]; + JpuWriteReg(MJPEG_GBU_PBIT_32_REG, val); + } + + if (pEncInfo->format != FORMAT_400) { + JpuWriteReg(MJPEG_GBU_PBIT_08_REG, 0x01); + for (i = 0; i < 64; i += 4) { + val = pEncInfo->pQMatTab[0][i] << 24; + val |= pEncInfo->pQMatTab[0][i + 1] << 16; + val |= pEncInfo->pQMatTab[0][i + 2] << 8; + val |= pEncInfo->pQMatTab[0][i + 3]; + JpuWriteReg(MJPEG_GBU_PBIT_32_REG, val); + } + } + } + + // DHT Header + JpuWriteReg(MJPEG_GBU_PBIT_16_REG, 0xFFC4); + + if (para->huffMode == JPG_TBL_NORMAL) { + JpuWriteReg(MJPEG_GBU_PBIT_24_REG, 0x001F00); + + for (i = 0; i < 16; i += 4) { + val = pEncInfo->pHuffBits[0][i] << 24; + val |= pEncInfo->pHuffBits[0][i + 1] << 16; + val |= pEncInfo->pHuffBits[0][i + 2] << 8; + val |= pEncInfo->pHuffBits[0][i + 3]; + JpuWriteReg(MJPEG_GBU_PBIT_32_REG, val); + } + + for (i = 0; i < 12; i += 4) { + val = pEncInfo->pHuffVal[0][i] << 24; + val |= pEncInfo->pHuffVal[0][i + 1] << 16; + val |= pEncInfo->pHuffVal[0][i + 2] << 8; + val |= pEncInfo->pHuffVal[0][i + 3]; + JpuWriteReg(MJPEG_GBU_PBIT_32_REG, val); + } + + JpuWriteReg(MJPEG_GBU_PBIT_32_REG, 0xFFC400B5); + JpuWriteReg(MJPEG_GBU_PBIT_08_REG, 0x10); + + for (i = 0; i < 16; i += 4) { + val = pEncInfo->pHuffBits[1][i] << 24; + val |= pEncInfo->pHuffBits[1][i + 1] << 16; + val |= pEncInfo->pHuffBits[1][i + 2] << 8; + val |= pEncInfo->pHuffBits[1][i + 3]; + JpuWriteReg(MJPEG_GBU_PBIT_32_REG, val); + } + + for (i = 0; i < 160; i += 4) { + val = pEncInfo->pHuffVal[1][i] << 24; + val |= pEncInfo->pHuffVal[1][i + 1] << 16; + val |= pEncInfo->pHuffVal[1][i + 2] << 8; + val |= pEncInfo->pHuffVal[1][i + 3]; + JpuWriteReg(MJPEG_GBU_PBIT_32_REG, val); + } + + JpuWriteReg(MJPEG_GBU_PBIT_16_REG, pEncInfo->pHuffVal[1][160] << 8 | pEncInfo->pHuffVal[1][161]); + + if (pEncInfo->format != FORMAT_400) { + + JpuWriteReg(MJPEG_GBU_PBIT_32_REG, 0xFFC4001F); + JpuWriteReg(MJPEG_GBU_PBIT_08_REG, 0x01); + + for (i = 0; i < 16; i += 4) { + val = pEncInfo->pHuffBits[2][i] << 24; + val |= pEncInfo->pHuffBits[2][i + 1] << 16; + val |= pEncInfo->pHuffBits[2][i + 2] << 8; + val |= pEncInfo->pHuffBits[2][i + 3]; + JpuWriteReg(MJPEG_GBU_PBIT_32_REG, val); + } + + for (i = 0; i < 12; i += 4) { + val = pEncInfo->pHuffVal[2][i] << 24; + val |= pEncInfo->pHuffVal[2][i + 1] << 16; + val |= pEncInfo->pHuffVal[2][i + 2] << 8; + val |= pEncInfo->pHuffVal[2][i + 3]; + JpuWriteReg(MJPEG_GBU_PBIT_32_REG, val); + } + + JpuWriteReg(MJPEG_GBU_PBIT_32_REG, 0xFFC400B5); + JpuWriteReg(MJPEG_GBU_PBIT_08_REG, 0x11); + + for (i = 0; i < 16; i += 4) { + val = pEncInfo->pHuffBits[3][i] << 24; + val |= pEncInfo->pHuffBits[3][i + 1] << 16; + val |= pEncInfo->pHuffBits[3][i + 2] << 8; + val |= pEncInfo->pHuffBits[3][i + 3]; + JpuWriteReg(MJPEG_GBU_PBIT_32_REG, val); + } + + for (i = 0; i < 160; i += 4) { + val = pEncInfo->pHuffVal[3][i] << 24; + val |= pEncInfo->pHuffVal[3][i + 1] << 16; + val |= pEncInfo->pHuffVal[3][i + 2] << 8; + val |= pEncInfo->pHuffVal[3][i + 3]; + JpuWriteReg(MJPEG_GBU_PBIT_32_REG, val); + } + val = pEncInfo->pHuffVal[3][160] << 8 | pEncInfo->pHuffVal[3][161]; + JpuWriteReg(MJPEG_GBU_PBIT_16_REG, val); + } + } else { // if (para->huffMode == JPG_TBL_MERGE) + if (pEncInfo->format != FORMAT_400) { + JpuWriteReg(MJPEG_GBU_PBIT_24_REG, 0x01A200); + } else { + JpuWriteReg(MJPEG_GBU_PBIT_24_REG, 0x00D400); + } + + for (i = 0; i < 16; i += 4) { + val = pEncInfo->pHuffBits[0][i] << 24; + val |= pEncInfo->pHuffBits[0][i + 1] << 16; + val |= pEncInfo->pHuffBits[0][i + 2] << 8; + val |= pEncInfo->pHuffBits[0][i + 3]; + JpuWriteReg(MJPEG_GBU_PBIT_32_REG, val); + } + + for (i = 0; i < 12; i += 4) { + val = pEncInfo->pHuffVal[0][i] << 24; + val |= pEncInfo->pHuffVal[0][i + 1] << 16; + val |= pEncInfo->pHuffVal[0][i + 2] << 8; + val |= pEncInfo->pHuffVal[0][i + 3]; + JpuWriteReg(MJPEG_GBU_PBIT_32_REG, val); + } + + JpuWriteReg(MJPEG_GBU_PBIT_08_REG, 0x10); + + for (i = 0; i < 16; i += 4) { + val = pEncInfo->pHuffBits[1][i] << 24; + val |= pEncInfo->pHuffBits[1][i + 1] << 16; + val |= pEncInfo->pHuffBits[1][i + 2] << 8; + val |= pEncInfo->pHuffBits[1][i + 3]; + JpuWriteReg(MJPEG_GBU_PBIT_32_REG, val); + } + + for (i = 0; i < 160; i += 4) { + val = pEncInfo->pHuffVal[1][i] << 24; + val |= pEncInfo->pHuffVal[1][i + 1] << 16; + val |= pEncInfo->pHuffVal[1][i + 2] << 8; + val |= pEncInfo->pHuffVal[1][i + 3]; + JpuWriteReg(MJPEG_GBU_PBIT_32_REG, val); + } + + JpuWriteReg(MJPEG_GBU_PBIT_16_REG, pEncInfo->pHuffVal[1][160] << 8 | pEncInfo->pHuffVal[1][161]); + + if (pEncInfo->format != FORMAT_400) { + + JpuWriteReg(MJPEG_GBU_PBIT_08_REG, 0x01); + + for (i = 0; i < 16; i += 4) { + val = pEncInfo->pHuffBits[2][i] << 24; + val |= pEncInfo->pHuffBits[2][i + 1] << 16; + val |= pEncInfo->pHuffBits[2][i + 2] << 8; + val |= pEncInfo->pHuffBits[2][i + 3]; + JpuWriteReg(MJPEG_GBU_PBIT_32_REG, val); + } + + for (i = 0; i < 12; i += 4) { + val = pEncInfo->pHuffVal[2][i] << 24; + val |= pEncInfo->pHuffVal[2][i + 1] << 16; + val |= pEncInfo->pHuffVal[2][i + 2] << 8; + val |= pEncInfo->pHuffVal[2][i + 3]; + JpuWriteReg(MJPEG_GBU_PBIT_32_REG, val); + } + + JpuWriteReg(MJPEG_GBU_PBIT_08_REG, 0x11); + + for (i = 0; i < 16; i += 4) { + val = pEncInfo->pHuffBits[3][i] << 24; + val |= pEncInfo->pHuffBits[3][i + 1] << 16; + val |= pEncInfo->pHuffBits[3][i + 2] << 8; + val |= pEncInfo->pHuffBits[3][i + 3]; + JpuWriteReg(MJPEG_GBU_PBIT_32_REG, val); + } + + for (i = 0; i < 160; i += 4) { + val = pEncInfo->pHuffVal[3][i] << 24; + val |= pEncInfo->pHuffVal[3][i + 1] << 16; + val |= pEncInfo->pHuffVal[3][i + 2] << 8; + val |= pEncInfo->pHuffVal[3][i + 3]; + JpuWriteReg(MJPEG_GBU_PBIT_32_REG, val); + } + + val = pEncInfo->pHuffVal[3][160] << 8 | pEncInfo->pHuffVal[3][161]; + JpuWriteReg(MJPEG_GBU_PBIT_16_REG, val); + } + } + + // SOF header + JpuWriteReg(MJPEG_GBU_PBIT_16_REG, 0xFFC0); + JpuWriteReg(MJPEG_GBU_PBIT_16_REG, (8 + (pEncInfo->compNum * 3))); + JpuWriteReg(MJPEG_GBU_PBIT_08_REG, 0x08); + + if (pEncInfo->rotationAngle == 90 || pEncInfo->rotationAngle == 270) { + JpuWriteReg(MJPEG_GBU_PBIT_32_REG, pEncInfo->picWidth << 16 | pEncInfo->picHeight); + } else { + JpuWriteReg(MJPEG_GBU_PBIT_32_REG, pEncInfo->picHeight << 16 | pEncInfo->picWidth); + } + + JpuWriteReg(MJPEG_GBU_PBIT_08_REG, pEncInfo->compNum); + + frameFormat = pEncInfo->format; + if (pEncInfo->rotationEnable && + (pEncInfo->rotationAngle == 90 || pEncInfo->rotationAngle == 270)) { + frameFormat = (frameFormat == FORMAT_422) + ? FORMAT_224 + : (frameFormat == FORMAT_224) ? FORMAT_422 + : frameFormat; + } + + pCInfoTab[0] = sJpuCompInfoTable[frameFormat]; + pCInfoTab[1] = pCInfoTab[0] + 6; + pCInfoTab[2] = pCInfoTab[1] + 6; + pCInfoTab[3] = pCInfoTab[2] + 6; + + for (i = 0; i < pEncInfo->compNum; i++) { + JpuWriteReg(MJPEG_GBU_PBIT_08_REG, (i + 1)); + JpuWriteReg(MJPEG_GBU_PBIT_08_REG, ((pCInfoTab[i][1] << 4) & 0xF0) + (pCInfoTab[i][2] & 0x0F)); + JpuWriteReg(MJPEG_GBU_PBIT_08_REG, pCInfoTab[i][3]); + } + + pEncInfo->frameIdx++; + + return 1; +} + +JpgRet JpgEnterLock(void) +{ + jdi_lock(); + JpgSetClockGate(1); + return JPG_RET_SUCCESS; +} + +JpgRet JpgLeaveLock(void) +{ + JpgSetClockGate(0); + jdi_unlock(); + return JPG_RET_SUCCESS; +} + +JpgRet JpgSetClockGate(Uint32 on) +{ + JpgInst *inst; + jpu_instance_pool_t *jip; + + jip = (jpu_instance_pool_t *)jdi_get_instance_pool(); + if (!jip) + return JPG_RET_FAILURE; + + inst = jip->pendingInst; + if (inst && !on) + return JPG_RET_SUCCESS; + + jdi_set_clock_gate(on); + + return JPG_RET_SUCCESS; +} + +void SetJpgPendingInst(JpgInst *inst) +{ + jpu_instance_pool_t *jip; + + jip = (jpu_instance_pool_t *)jdi_get_instance_pool(); + if (!jip) + return; + + jip->pendingInst = inst; +} + +void ClearJpgPendingInst(void) +{ + jpu_instance_pool_t *jip; + + jip = (jpu_instance_pool_t *)jdi_get_instance_pool(); + if (!jip) + return; + + if (jip->pendingInst) + jip->pendingInst = 0; +} + +JpgInst *GetJpgPendingInst(void) +{ + jpu_instance_pool_t *jip; + + jip = (jpu_instance_pool_t *)jdi_get_instance_pool(); + if (!jip) + return NULL; + + return jip->pendingInst; +} diff --git a/u-boot-2021.10/drivers/jpeg/jpuapifunc.h b/u-boot-2021.10/drivers/jpeg/jpuapifunc.h new file mode 100644 index 000000000..a065ad410 --- /dev/null +++ b/u-boot-2021.10/drivers/jpeg/jpuapifunc.h @@ -0,0 +1,280 @@ +#ifndef _JPUAPI_UTIL_H_ +#define _JPUAPI_UTIL_H_ + +#include "jpuapi.h" +#include "regdefine.h" + +#define DC_TABLE_INDEX0 0 +#define AC_TABLE_INDEX0 1 +#define DC_TABLE_INDEX1 2 +#define AC_TABLE_INDEX1 3 + +#define Q_COMPONENT0 0 +#define Q_COMPONENT1 0x40 +#define Q_COMPONENT2 0x80 + +typedef enum { + JPG_START_PIC = 0, + JPG_START_INIT, + JPG_START_STOP, + JPG_START_PARTIAL +} JpgStartCmd; + +typedef struct{ + UINT tag; + UINT type; + int count; + int offset; +} TAG; + +enum { + JFIF = 0, + JFXX_JPG = 1, + JFXX_PAL = 2, + JFXX_RAW = 3, + EXIF_JPG = 4 +}; + +typedef struct { + int PicX; + int PicY; + int BitPerSample[3]; + int Compression; // 1 for uncompressed / 6 for compressed(jpeg) + int PixelComposition; // 2 for RGB / 6 for YCbCr + int SamplePerPixel; + int PlanrConfig; // 1 for chunky / 2 for planar + int YCbCrSubSample; // 00020002 for YCbCr 4:2:0 / 00020001 for YCbCr 4:2:2 + UINT JpegOffset; + UINT JpegThumbSize; +} EXIF_INFO; + +typedef struct { + BYTE *buffer; + int index; + int size; +} vpu_getbit_context_t; + +#define init_get_bits(CTX, BUFFER, SIZE) JpuGbuInit(CTX, BUFFER, SIZE) +#define show_bits(CTX, NUM) JpuGguShowBit(CTX, NUM) +#define get_bits(CTX, NUM) JpuGbuGetBit(CTX, NUM) +#define get_bits_left(CTX) JpuGbuGetLeftBitCount(CTX) +#define get_bits_count(CTX) JpuGbuGetUsedBitCount(CTX) + +typedef struct { + PhysicalAddress streamWrPtr; + PhysicalAddress streamRdPtr; + int streamEndflag; + PhysicalAddress streamBufStartAddr; + PhysicalAddress streamBufEndAddr; + int streamBufSize; + BYTE *pBitStream; + + int frameOffset; + int consumeByte; + int nextOffset; + int currOffset; + + FrameBuffer *frameBufPool; + int numFrameBuffers; + int stride; + int strideY; + int strideC; + int rotationEnable; + int mirrorEnable; + int mirrorDirection; + int rotationAngle; + FrameBuffer rotatorOutput; + int rotatorStride; + int rotatorOutputValid; + int initialInfoObtained; + int minFrameBufferNum; + int streamEndian; + int frameEndian; + int chroma_interleave; + + int picWidth; + int picHeight; + int alignedWidth; + int alignedHeight; + int headerSize; + int ecsPtr; + int pagePtr; + int wordPtr; + int bitPtr; + int format; + int rstIntval; + + int userHuffTab; + + int huffDcIdx; + int huffAcIdx; + int Qidx; + + BYTE huffVal[4][162]; + BYTE huffBits[4][256]; + BYTE cInfoTab[4][6]; + BYTE qMatTab[4][64]; + + Uint32 huffMin[4][16]; + Uint32 huffMax[4][16]; + BYTE huffPtr[4][16]; + + // partial + int usePartial; + int lineNum; + int bufNum; + + int busReqNum; + int compNum; + int mcuBlockNum; + int compInfo[3]; + int frameIdx; + int bitEmpty; + int iHorScaleMode; + int iVerScaleMode; + int mcuWidth; + int mcuHeight; + vpu_getbit_context_t gbc; + +#ifdef MJPEG_ERROR_CONCEAL + //error conceal + struct{ + int bError; + int rstMarker; + int errPosX; + int errPosY; + } errInfo; + + int curRstIdx; + int nextRstIdx; + int setPosX; + int setPosY; + int gbuStartPtr; // entry point in stream buffer before pic_run + + int numRstMakerRounding; +#endif + + //ROI + int roiEnable; + int roiOffsetX; + int roiOffsetY; + int roiWidth; + int roiHeight; + int roiMcuOffsetX; + int roiMcuOffsetY; + int roiMcuWidth; + int roiMcuHeight; + int packedFormat; +} JpgDecInfo; + +typedef struct { + JpgEncOpenParam openParam; + JpgEncInitialInfo initialInfo; + PhysicalAddress streamRdPtr; + PhysicalAddress streamWrPtr; + PhysicalAddress streamBufStartAddr; + PhysicalAddress streamBufEndAddr; + int streamBufSize; + + FrameBuffer *frameBufPool; + int numFrameBuffers; + int stride; + int rotationEnable; + int mirrorEnable; + int mirrorDirection; + int rotationAngle; + int initialInfoObtained; + + int picWidth; + int picHeight; + int alignedWidth; + int alignedHeight; + int seqInited; + int frameIdx; + int format; + + int streamEndian; + int frameEndian; + int chroma_interleave; + + int rstIntval; + int busReqNum; + int mcuBlockNum; + int compNum; + int compInfo[3]; + + // give command + int disableAPPMarker; + int quantMode; + int stuffByteEnable; + + Uint32 huffCode[4][256]; + Uint32 huffSize[4][256]; + BYTE *pHuffVal[4]; + BYTE *pHuffBits[4]; + BYTE *pCInfoTab[4]; + BYTE *pQMatTab[4]; + // partial + int usePartial; + int partiallineNum; + int partialBufNum; + int packedFormat; + + JpgEncParamSet *paraSet; + +} JpgEncInfo; + +typedef struct JpgInst { + int inUse; + int instIndex; + int loggingEnable; + union { + JpgEncInfo encInfo; + JpgDecInfo decInfo; + } JpgInfo; +} JpgInst; + +#ifdef __cplusplus +extern "C" { +#endif + + JpgRet InitJpgInstancePool(void); + JpgRet GetJpgInstance(JpgInst **ppInst); + void FreeJpgInstance(JpgInst *pJpgInst); + JpgRet CheckJpgInstValidity(JpgInst *pci); + JpgRet CheckJpgDecOpenParam(JpgDecOpenParam *pop); + + int JpuGbuInit(vpu_getbit_context_t *ctx, BYTE *buffer, int size); + int JpuGbuGetUsedBitCount(vpu_getbit_context_t *ctx); + int JpuGbuGetLeftBitCount(vpu_getbit_context_t *ctx); + unsigned int JpuGbuGetBit(vpu_getbit_context_t *ctx, int bit_num); + unsigned int JpuGguShowBit(vpu_getbit_context_t *ctx, int bit_num); + + int JpegDecodeHeader(JpgDecInfo *jpg); + int JpgDecQMatTabSetUp(JpgDecInfo *jpg); + int JpgDecHuffTabSetUp(JpgDecInfo *jpg); + void JpgDecGramSetup(JpgDecInfo *jpg); + + JpgRet CheckJpgEncOpenParam(JpgEncOpenParam *pop); + JpgRet CheckJpgEncParam(JpgEncHandle handle, JpgEncParam *param); + int JpgEncLoadHuffTab(JpgEncInfo *pJpgEncInfo); + int JpgEncLoadQMatTab(JpgEncInfo *pJpgEncInfo); + int JpgEncEncodeHeader(JpgEncHandle handle, JpgEncParamSet *para); + + JpgRet JpgEnterLock(void); + JpgRet JpgLeaveLock(void); + JpgRet JpgSetClockGate(Uint32 on); + + void SetJpgPendingInst(JpgInst *inst); + void ClearJpgPendingInst(void); + JpgInst *GetJpgPendingInst(void); + +#ifdef MJPEG_ERROR_CONCEAL + int JpegDecodeConcealError(JpgDecInfo *jpg); +#endif + +#ifdef __cplusplus +} +#endif + +#endif //_JPUAPI_UTIL_H_ diff --git a/u-boot-2021.10/drivers/jpeg/jpuconfig.h b/u-boot-2021.10/drivers/jpeg/jpuconfig.h new file mode 100644 index 000000000..cc4638fb3 --- /dev/null +++ b/u-boot-2021.10/drivers/jpeg/jpuconfig.h @@ -0,0 +1,36 @@ +#ifndef _JPU_CONFIG_H_ +#define _JPU_CONFIG_H_ + +#include "config.h" +#include "jputypes.h" + +#define MAX_NUM_INSTANCE 8 +#define MAX_INST_HANDLE_SIZE (12 * 1024) + +#ifdef JPU_FPGA_PLATFORM +#define JPU_FRAME_ENDIAN JDI_BIG_ENDIAN +#define JPU_STREAM_ENDIAN JDI_BIG_ENDIAN +#else +#define JPU_FRAME_ENDIAN JDI_LITTLE_ENDIAN +#define JPU_STREAM_ENDIAN JDI_LITTLE_ENDIAN +#endif + +// 0 (chroma separate mode), 1 (cbcr interleave mode), 2 (crcb interleave mode) +#define JPU_CHROMA_INTERLEAVE 1 +#define JPU_INTERRUPT_TIMEOUT_MS 5000 +#define JPU_STUFFING_BYTE_FF 0 // 0 : ON ("0xFF"), 1 : OFF ("0x00") for stuffing +#define JPU_PARTIAL_DECODE 1 // 0 : OFF, 1 : ON + +#define MAX_MJPG_PIC_WIDTH 32768 +#define MAX_MJPG_PIC_HEIGHT 32768 + +// For AVC decoder, 16(reference) + 2(current) + 1(rotator) +#define MAX_FRAME (19 * MAX_NUM_INSTANCE) +#define STREAM_FILL_SIZE 0x10000 +#define STREAM_END_SIZE 0 +#define JPU_GBU_SIZE 512 +#define STREAM_BUF_SIZE 0x100000 + +#define JPU_CHECK_WRITE_RESPONSE_BVALID_SIGNAL 0 + +#endif /* _JPU_CONFIG_H_ */ diff --git a/u-boot-2021.10/drivers/jpeg/jpuhelper.c b/u-boot-2021.10/drivers/jpeg/jpuhelper.c new file mode 100644 index 000000000..97baa2dd5 --- /dev/null +++ b/u-boot-2021.10/drivers/jpeg/jpuhelper.c @@ -0,0 +1,2015 @@ + +#include +#include +#include + +#include "jpuapi.h" +#include "jpuapifunc.h" +#include "jpuhelper.h" +#include "jpulog.h" +#include "jputable.h" +#include "regdefine.h" + +extern int sscanf(const char *str, const char *format, ...); + +static int FillSdramBurst(BufInfo *pBufInfo, Uint64 targetAddr, + PhysicalAddress bsBufStartAddr, + PhysicalAddress bsBufEndAddr, Uint32 size, + int checkeos, int *streameos, int endian); +static int StoreYuvImageBurstFormat(Uint8 *dst, int picWidth, int picHeight, + unsigned long addrY, unsigned long addrCb, + unsigned long addrCr, int stride, + int interLeave, int format, int endian, + int packed); +static void ProcessEncodedBitstreamBurst(osal_file_t *fp, + unsigned long targetAddr, + PhysicalAddress bsBufStartAddr, + PhysicalAddress bsBufEndAddr, int size, + int endian); +static int LoadYuvImageBurstFormat(unsigned char *src, int picWidth, + int picHeight, unsigned long addrY, + unsigned long addrCb, unsigned long addrCr, + int stride, int interLeave, int format, + int endian, int packed); + +// Figure A.6 - Zig-zag sequence of quantized DCT coefficients +const int InvScanTable[64] = { + 0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42, + 3, 8, 12, 17, 25, 30, 41, 43, 9, 11, 18, 24, 31, 40, 44, 53, + 10, 19, 23, 32, 39, 45, 52, 54, 20, 22, 33, 38, 46, 51, 55, 60, + 21, 34, 37, 47, 50, 56, 59, 61, 35, 36, 48, 49, 57, 58, 62, 63 +}; + +const int ScanTable[64] = { + 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, + 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, + 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, + 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, + 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63 +}; + +JpgRet WriteJpgBsBufHelperStream(JpgDecHandle handle, BufInfo *pBufInfo, + PhysicalAddress paBsBufStart, + PhysicalAddress paBsBufEnd, int defaultsize, + int checkeos, int *pstreameos, int endian) +{ + JpgRet ret = JPG_RET_SUCCESS; + int size = 0; + int fillSize = 0; + PhysicalAddress paRdPtr, paWrPtr; + + ret = JPU_DecGetBitstreamBuffer(handle, &paRdPtr, &paWrPtr, &size); + JLOG(INFO, "rdPtr: 0x%lx, wrPtr: 0x%lx, size: %d\n", paRdPtr, paWrPtr, size); + if (ret != JPG_RET_SUCCESS) { + JLOG(ERR, "VPU_DecGetBitstreamBuffer failed Error code is 0x%x\n", ret); + goto FILL_BS_ERROR; + } + + if (size <= 0) + return JPG_RET_SUCCESS; + + if (defaultsize) { + if (size < defaultsize) + fillSize = size; + else + fillSize = defaultsize; + } else { + fillSize = size; + } + + JLOG(INFO, "Before fillSize: %d\n", fillSize); + + fillSize = FillSdramBurst(pBufInfo, paWrPtr, paBsBufStart, paBsBufEnd, + fillSize, checkeos, pstreameos, endian); + + if (fillSize == 0 && pBufInfo->fillendbs != 1) + return ret; + JLOG(INFO, "After fillSize :%d\n", fillSize); + if (*pstreameos == 0) { + ret = JPU_DecUpdateBitstreamBuffer(handle, fillSize); + if (ret != JPG_RET_SUCCESS) { + JLOG(ERR, "VPU_DecUpdateBitstreamBuffer failed Error code is 0x%x\n", ret); + goto FILL_BS_ERROR; + } + + if (pBufInfo->fillendbs == 1) { + ret = JPU_DecUpdateBitstreamBuffer(handle, STREAM_END_SIZE); + if (ret != JPG_RET_SUCCESS) { + JLOG(ERR, "VPU_DecUpdateBitstreamBuffer failed Error code is 0x%x\n", ret); + goto FILL_BS_ERROR; + } + + // pBufInfo->fillendbs = 1; + } + } else { + if (!pBufInfo->fillendbs) { + ret = JPU_DecUpdateBitstreamBuffer(handle, STREAM_END_SIZE); + if (ret != JPG_RET_SUCCESS) { + JLOG(ERR, "VPU_DecUpdateBitstreamBuffer failed Error code is 0x%x\n", ret); + goto FILL_BS_ERROR; + } + pBufInfo->fillendbs = 1; + } + } + +FILL_BS_ERROR: + + return ret; +} + +JpgRet WriteJpgBsBufHelper(JpgDecHandle handle, BufInfo *pBufInfo, + PhysicalAddress paBsBufStart, + PhysicalAddress paBsBufEnd, int defaultsize, + int checkeos, int *pstreameos, int endian) +{ + JpgRet ret = JPG_RET_SUCCESS; + int size = 0; + int fillSize = 0; + PhysicalAddress paRdPtr, paWrPtr; + + ret = JPU_DecGetBitstreamBuffer(handle, &paRdPtr, &paWrPtr, &size); + + JLOG(INFO, "rdPtr: 0x%lx, wrPtr: 0x%lx, size: %d\n", paRdPtr, paWrPtr, size); + + if (ret != JPG_RET_SUCCESS) { + JLOG(ERR, "VPU_DecGetBitstreamBuffer failed Error code is 0x%x\n", ret); + goto FILL_BS_ERROR; + } + + if (size <= 0) + return JPG_RET_SUCCESS; + + if (defaultsize) { + if (size < defaultsize) + fillSize = size; + else + fillSize = defaultsize; + } else { + fillSize = size; + } + + fillSize = FillSdramBurst(pBufInfo, paWrPtr, paBsBufStart, paBsBufEnd, + fillSize, checkeos, pstreameos, endian); + + JLOG(INFO, "fillSize :%d\n", fillSize); + + if (*pstreameos == 0) { + ret = JPU_DecUpdateBitstreamBuffer(handle, fillSize); + if (ret != JPG_RET_SUCCESS) { + JLOG(ERR, "VPU_DecUpdateBitstreamBuffer failed Error code is 0x%x\n", ret); + goto FILL_BS_ERROR; + } + + if ((pBufInfo->size - pBufInfo->point) <= 0) { + ret = JPU_DecUpdateBitstreamBuffer(handle, STREAM_END_SIZE); + if (ret != JPG_RET_SUCCESS) { + JLOG(ERR, "VPU_DecUpdateBitstreamBuffer failed Error code is 0x%x\n", ret); + goto FILL_BS_ERROR; + } + + pBufInfo->fillendbs = 1; + } + } else { + if (!pBufInfo->fillendbs) { + ret = JPU_DecUpdateBitstreamBuffer(handle, STREAM_END_SIZE); + if (ret != JPG_RET_SUCCESS) { + JLOG(ERR, "VPU_DecUpdateBitstreamBuffer failed Error code is 0x%x\n", ret); + goto FILL_BS_ERROR; + } + pBufInfo->fillendbs = 1; + } + } + +FILL_BS_ERROR: + + return ret; +} + +/** + * Bitstream Read for encoders + */ +JpgRet ReadJpgBsBufHelper(JpgEncHandle handle, osal_file_t *bsFp, + PhysicalAddress paBsBufStart, + PhysicalAddress paBsBufEnd, int encHeaderSize, + int endian) +{ + JpgRet ret = JPG_RET_SUCCESS; + int loadSize = 0; + int stuffSize; + PhysicalAddress paRdPtr, paWrPtr; + int size = 0; + + ret = JPU_EncGetBitstreamBuffer(handle, &paRdPtr, &paWrPtr, &size); + if (ret != JPG_RET_SUCCESS) { + JLOG(ERR, "JPU_EncGetBitstreamBuffer failed Error code is 0x%x\n", ret); + goto LOAD_BS_ERROR; + } + + if (size > 0) { + stuffSize = 0; + if (encHeaderSize && (size + encHeaderSize) % 8) { + stuffSize = (size + encHeaderSize) - ((size + encHeaderSize) / 8) * 8; + stuffSize = 8 - stuffSize; + } + + loadSize = size; + + if (loadSize > 0) { + ProcessEncodedBitstreamBurst(bsFp, paRdPtr, paBsBufStart, paBsBufEnd, loadSize, endian); + + ret = JPU_EncUpdateBitstreamBuffer(handle, loadSize); + if (ret != JPG_RET_SUCCESS) { + JLOG(ERR, "VPU_EncUpdateBitstreamBuffer failed Error code is 0x%x\n", ret); + goto LOAD_BS_ERROR; + } + } + } + +LOAD_BS_ERROR: + + return ret; +} + +/****************************************************************************** + * DPB Image Data Control + ******************************************************************************/ +int LoadYuvImageHelperFormat(osal_file_t *yuvFp, Uint8 *pYuv, + PhysicalAddress addrY, PhysicalAddress addrCb, + PhysicalAddress addrCr, int picWidth, + int picHeight, int stride, int interleave, + int format, int endian, int packed) +{ + int frameSize = 0; + + switch (format) { + case FORMAT_420: + frameSize = picWidth * picHeight * 3 / 2; + break; + case FORMAT_224: + frameSize = picWidth * picHeight * 4 / 2; + break; + case FORMAT_422: + frameSize = picWidth * picHeight * 4 / 2; + break; + case FORMAT_444: + frameSize = picWidth * picHeight * 6 / 2; + break; + case FORMAT_400: + frameSize = picWidth * picHeight; + break; + } + + if (packed == PACKED_FORMAT_NONE) { + frameSize = frameSize; + } else if (packed == PACKED_FORMAT_444) { + frameSize = picWidth * 3 * picHeight; + } else { // PACKED_FORMAT_422_XXXX + frameSize = picWidth * 2 * picHeight; + } + + // Load source one picture image to encode to SDRAM frame buffer. + if (!OSAL_FREAD(pYuv, 1, frameSize, yuvFp)) { + if (!OSAL_FEOF(yuvFp)) + JLOG(ERR, "Yuv Data fread failed file handle is 0x%p\n", yuvFp); + return 0; + } + + LoadYuvImageBurstFormat(pYuv, picWidth, picHeight, addrY, addrCb, + addrCr, stride, interleave, format, endian, + packed); + + return 1; +} + +int LoadYuvPartialImageHelperFormat(osal_file_t *yuvFp, Uint8 *pYuv, PhysicalAddress addrY, + PhysicalAddress addrCb, PhysicalAddress addrCr, int picWidth, int picHeight, + int picHeightPartial, int stride, int interleave, int format, int endian, + int partPosIdx, int frameIdx, int packed) +{ + int LumaPicSize; + int ChromaPicSize; + int LumaPartialSize; + int ChromaPartialSize; + int pos; + int divX, divY; + int frameSize = 0; + + divX = format == FORMAT_420 || format == FORMAT_422 ? 2 : 1; + divY = format == FORMAT_420 || format == FORMAT_224 ? 2 : 1; + + LumaPicSize = picWidth * picHeight; + ChromaPicSize = LumaPicSize / divX / divY; + + LumaPartialSize = picWidth * picHeightPartial; + ChromaPartialSize = LumaPartialSize / divX / divY; + + if (format == FORMAT_400) + frameSize = LumaPicSize; + else + frameSize = LumaPicSize + ChromaPicSize * 2; + // Load source one picture image to encode to SDRAM frame buffer. + + if (packed) { + if (packed == PACKED_FORMAT_444) { + LumaPicSize = picWidth * 3 * picHeight; + LumaPartialSize = picWidth * 3 * picHeightPartial; + } else { + LumaPicSize = picWidth * 2 * picHeight; + LumaPartialSize = picWidth * 2 * picHeightPartial; + } + frameSize = LumaPicSize; + ChromaPicSize = 0; + ChromaPartialSize = 0; + } + + // Y + OSAL_FSEEK(yuvFp, (frameIdx * frameSize), SEEK_SET); + pos = LumaPartialSize * partPosIdx; + OSAL_FSEEK(yuvFp, pos, SEEK_CUR); + + if (!OSAL_FREAD(pYuv, 1, LumaPartialSize, yuvFp)) { + if (!OSAL_FEOF(yuvFp)) + JLOG(ERR, "Yuv Data fread failed file handle is 0x%p\n", yuvFp); + return 0; + } + + if (format != FORMAT_400 && packed == 0) { + // Cb + OSAL_FSEEK(yuvFp, (frameIdx * frameSize), SEEK_SET); + pos = LumaPicSize + ChromaPartialSize * partPosIdx; + OSAL_FSEEK(yuvFp, pos, SEEK_CUR); + + if (!OSAL_FREAD(pYuv + LumaPartialSize, 1, ChromaPartialSize, + yuvFp)) { + if (!OSAL_FEOF(yuvFp)) + JLOG(ERR, "Yuv Data fread failed file handle is 0x%p\n", yuvFp); + return 0; + } + + // Cr + OSAL_FSEEK(yuvFp, (frameIdx * frameSize), SEEK_SET); + pos = LumaPicSize + ChromaPicSize + ChromaPartialSize * partPosIdx; + OSAL_FSEEK(yuvFp, pos, SEEK_CUR); + + if (!OSAL_FREAD(pYuv + LumaPartialSize + ChromaPartialSize, 1, ChromaPartialSize, yuvFp)) { + if (!OSAL_FEOF(yuvFp)) + JLOG(ERR, "Yuv Data fread failed file handle is 0x%p\n", yuvFp); + return 0; + } + } + + LoadYuvImageBurstFormat(pYuv, picWidth, picHeightPartial, addrY, addrCb, + addrCr, stride, interleave, format, endian, + packed); + + return 1; +} + +int SaveYuvImageHelperFormat(osal_file_t *yuvFp, Uint8 *pYuv, + PhysicalAddress addrY, PhysicalAddress addrCb, + PhysicalAddress addrCr, int picWidth, + int picHeight, int stride, int interLeave, + int format, int endian, int packed) +{ + int frameSize; + + frameSize = StoreYuvImageBurstFormat(pYuv, picWidth, picHeight, addrY, + addrCb, addrCr, stride, interLeave, + format, endian, packed); + + if (yuvFp) { + if (!OSAL_FWRITE(pYuv, sizeof(Uint8), frameSize, yuvFp)) { + JLOG(ERR, "Frame Data fwrite failed file handle is 0x%p\n", yuvFp); + return 0; + } + OSAL_FFLUSH(yuvFp); + } + return 1; +} + +int SaveYuvPartialImageHelperFormat(osal_file_t *yuvFp, Uint8 *pYuv, PhysicalAddress addrY, + PhysicalAddress addrCb, PhysicalAddress addrCr, int picWidth, int picHeight, + int picHeightPartial, int stride, int interLeave, int format, int endian, + int partPosIdx, int frameIdx, int packed) +{ + int LumaPicSize = 0; + int ChromaPicSize = 0; + int frameSize = 0; + + int LumaPartialSize = 0; + int ChromaPartialSize = 0; + + int pos = 0; + // int divX, divY; + + // divX = format == FORMAT_420 || format == FORMAT_422 ? 2 : 1; + // divY = format == FORMAT_420 || format == FORMAT_224 ? 2 : 1; + + switch (format) { + case FORMAT_420: + LumaPicSize = picWidth * ((picHeight + 1) / 2 * 2); + ChromaPicSize = ((picWidth + 1) / 2) * ((picHeight + 1) / 2); + frameSize = LumaPicSize + ChromaPicSize * 2; + + LumaPartialSize = picWidth * ((picHeightPartial + 1) / 2 * 2); + ChromaPartialSize = ((picWidth + 1) / 2) * ((picHeightPartial + 1) / 2); + if (interLeave) + ChromaPartialSize = (((picWidth + 1) / 2) * 2) * ((picHeightPartial + 1) / 2); + break; + case FORMAT_224: + LumaPicSize = picWidth * ((picHeight + 1) / 2 * 2); + ChromaPicSize = picWidth * ((picHeight + 1) / 2); + frameSize = LumaPicSize + ChromaPicSize * 2; + + LumaPartialSize = picWidth * ((picHeightPartial + 1) / 2 * 2); + ChromaPartialSize = picWidth * ((picHeightPartial + 1) / 2); + if (interLeave) + ChromaPartialSize = picWidth * 2 * ((picHeightPartial + 1) / 2); + break; + case FORMAT_422: + LumaPicSize = picWidth * picHeight; + ChromaPicSize = ((picWidth + 1) / 2) * picHeight; + frameSize = LumaPicSize + ChromaPicSize * 2; + + LumaPartialSize = picWidth * picHeightPartial; + ChromaPartialSize = ((picWidth + 1) / 2) * picHeightPartial; + if (interLeave) + ChromaPartialSize = (((picWidth + 1) / 2) * 2) * picHeightPartial; + break; + case FORMAT_444: + LumaPicSize = picWidth * picHeight; + ChromaPicSize = picWidth * picHeight; + frameSize = LumaPicSize + ChromaPicSize * 2; + + LumaPartialSize = picWidth * picHeightPartial; + ChromaPartialSize = picWidth * picHeightPartial; + if (interLeave) + ChromaPartialSize = picWidth * 2 * picHeightPartial; + break; + case FORMAT_400: + LumaPicSize = picWidth * picHeight; + ChromaPicSize = 0; + frameSize = LumaPicSize + ChromaPicSize * 2; + + LumaPartialSize = picWidth * picHeightPartial; + ChromaPartialSize = 0; + break; + } + + if (packed) { + if (packed == PACKED_FORMAT_444) + picWidth *= 3; + else + picWidth *= 2; + + LumaPicSize = picWidth * picHeight; + ChromaPicSize = 0; + frameSize = LumaPicSize; + LumaPartialSize = picWidth * picHeightPartial; + ChromaPartialSize = 0; + } + + StoreYuvImageBurstFormat(pYuv, picWidth, picHeightPartial, addrY, + addrCb, addrCr, stride, interLeave, format, + endian, packed); + + if (yuvFp) { + // Y + OSAL_FSEEK(yuvFp, (frameIdx * frameSize), SEEK_SET); + pos = LumaPartialSize * partPosIdx; + OSAL_FSEEK(yuvFp, pos, SEEK_CUR); + if (!OSAL_FWRITE(pYuv, sizeof(Uint8), LumaPartialSize, yuvFp)) { + JLOG(ERR, "Frame Data fwrite failed file handle is 0x%p\n", yuvFp); + return 0; + } + + if (packed) { + OSAL_FFLUSH(yuvFp); + return 1; + } + + if (format != FORMAT_400) { + // Cb + OSAL_FSEEK(yuvFp, (frameIdx * frameSize), SEEK_SET); + pos = LumaPicSize + ChromaPartialSize * partPosIdx; + OSAL_FSEEK(yuvFp, pos, SEEK_CUR); + if (!OSAL_FWRITE(pYuv + LumaPartialSize, sizeof(Uint8), ChromaPartialSize, yuvFp)) { + JLOG(ERR, "Frame Data fwrite failed file handle is 0x%p\n", yuvFp); + return 0; + } + + if (interLeave) { + OSAL_FFLUSH(yuvFp); + return 1; + } + + // Cr + OSAL_FSEEK(yuvFp, (frameIdx * frameSize), SEEK_SET); + pos = LumaPicSize + ChromaPicSize + ChromaPartialSize * partPosIdx; + OSAL_FSEEK(yuvFp, pos, SEEK_CUR); + if (!OSAL_FWRITE(pYuv + LumaPartialSize + ChromaPartialSize, sizeof(Uint8), + ChromaPartialSize, yuvFp)) { + JLOG(ERR, "Frame Data fwrite failed file handle is 0x%p\n", yuvFp); + return 0; + } + } + OSAL_FFLUSH(yuvFp); + } + return 1; +} + +/****************************************************************************** + * JPEG specific Helper + ******************************************************************************/ +static int getTblElement(osal_file_t *fp, char *str) +{ + static int LineNum = 1; + + while (1) { + if (!OSAL_FGETS(str, 256, fp)) + return 0; + if ((str[0] != ';') && (str[0] != '/')) + break; + LineNum++; + } + return 1; +} + +static int parseHuffmanTable(osal_file_t *fp, EncMjpgParam *param) +{ + int ret = 0; + char sLine[256] = { + 0, + }; + unsigned int h[8] = { + 0, + }; + BYTE *huffBit; + BYTE *huffVal; + int i, j; + + huffBit = param->huffBits[DC_TABLE_INDEX0]; + huffVal = param->huffVal[DC_TABLE_INDEX0]; + + for (i = 0; i < 2; i++) { // Luma DC BitLength + if (getTblElement(fp, sLine) == 0) + return 0; + + memset(h, 0x00, 8 * sizeof(unsigned int)); + ret = sscanf(sLine, "%x %x %x %x %x %x %x %x", &h[0], &h[1], &h[2], + &h[3], &h[4], &h[5], &h[6], &h[7]); + + for (j = 0; j < 8; j++) + *huffBit++ = (BYTE)h[j]; + } + + for (i = 0; i < (16 / 8); i++) { // Luma DC HuffValue + if (getTblElement(fp, sLine) == 0) + return 0; + + memset(h, 0x00, 8 * sizeof(unsigned int)); + ret = sscanf(sLine, "%x %x %x %x %x %x %x %x", &h[0], &h[1], &h[2], + &h[3], &h[4], &h[5], &h[6], &h[7]); + + for (j = 0; j < 8; j++) + *huffVal++ = (BYTE)h[j]; + } + + huffBit = param->huffBits[AC_TABLE_INDEX0]; + huffVal = param->huffVal[AC_TABLE_INDEX0]; + + for (i = 0; i < (16 / 8); i++) { // Luma AC BitLength + if (getTblElement(fp, sLine) == 0) + return 0; + + memset(h, 0x00, 8 * sizeof(unsigned int)); + ret = sscanf(sLine, "%x %x %x %x %x %x %x %x", &h[0], &h[1], &h[2], + &h[3], &h[4], &h[5], &h[6], &h[7]); + for (j = 0; j < 8; j++) + *huffBit++ = (BYTE)h[j]; + } + + for (i = 0; i < (162 / 8); i++) { // Luma DC HuffValue + if (getTblElement(fp, sLine) == 0) + return 0; + + memset(h, 0x00, 8 * sizeof(unsigned int)); + ret = sscanf(sLine, "%x %x %x %x %x %x %x %x", &h[0], &h[1], &h[2], + &h[3], &h[4], &h[5], &h[6], &h[7]); + for (j = 0; j < 8; j++) + *huffVal++ = (BYTE)h[j]; + } + + if (getTblElement(fp, sLine) == 0) + return 0; + + memset(h, 0x00, 8 * sizeof(unsigned int)); + ret = sscanf(sLine, "%x %x %x %x %x %x %x %x", &h[0], &h[1], &h[2], &h[3], + &h[4], &h[5], &h[6], &h[7]); + for (j = 0; j < 2; j++) + *huffVal++ = (BYTE)h[j]; + + huffBit = param->huffBits[DC_TABLE_INDEX1]; + huffVal = param->huffVal[DC_TABLE_INDEX1]; + + for (i = 0; i < (16 / 8); i++) { // Chroma DC BitLength + if (getTblElement(fp, sLine) == 0) + return 0; + + memset(h, 0x00, 8 * sizeof(unsigned int)); + ret = sscanf(sLine, "%x %x %x %x %x %x %x %x", &h[0], &h[1], &h[2], + &h[3], &h[4], &h[5], &h[6], &h[7]); + for (j = 0; j < 8; j++) + *huffBit++ = (BYTE)h[j]; + } + + for (i = 0; i < (16 / 8); i++) { // Chroma DC HuffValue + if (getTblElement(fp, sLine) == 0) + return 0; + + memset(h, 0x00, 8 * sizeof(unsigned int)); + ret = sscanf(sLine, "%x %x %x %x %x %x %x %x", &h[0], &h[1], &h[2], + &h[3], &h[4], &h[5], &h[6], &h[7]); + for (j = 0; j < 8; j++) + *huffVal++ = (BYTE)h[j]; + } + + huffBit = param->huffBits[AC_TABLE_INDEX1]; + huffVal = param->huffVal[AC_TABLE_INDEX1]; + + for (i = 0; i < (16 / 8); i++) { // Chroma DC BitLength + if (getTblElement(fp, sLine) == 0) + return 0; + + memset(h, 0x00, 8 * sizeof(unsigned int)); + ret = sscanf(sLine, "%x %x %x %x %x %x %x %x", &h[0], &h[1], &h[2], + &h[3], &h[4], &h[5], &h[6], &h[7]); + for (j = 0; j < 8; j++) + *huffBit++ = (BYTE)h[j]; + } + + for (i = 0; i < (162 / 8); i++) {// Luma DC HuffValue + if (getTblElement(fp, sLine) == 0) + return 0; + + memset(h, 0x00, 8 * sizeof(unsigned int)); + ret = sscanf(sLine, "%x %x %x %x %x %x %x %x", &h[0], &h[1], &h[2], + &h[3], &h[4], &h[5], &h[6], &h[7]); + for (j = 0; j < 8; j++) + *huffVal++ = (BYTE)h[j]; + } + + if (getTblElement(fp, sLine) == 0) + return 0; + + memset(h, 0x00, 8 * sizeof(unsigned int)); + ret = sscanf(sLine, "%x %x %x %x %x %x %x %x", &h[0], &h[1], &h[2], &h[3], + &h[4], &h[5], &h[6], &h[7]); + for (j = 0; j < 2; j++) + *huffVal++ = (BYTE)h[j]; + + (void)ret; + return 1; +} + +static int parseQMatrix(osal_file_t *fp, EncMjpgParam *param) +{ + int ret = 0; + char sLine[256] = { + 0, + }; + int i, j; + unsigned int h[8] = { + 0, + }; + BYTE temp_dc[64], temp_ac[64]; + BYTE *qTable_dc, *qTable_ac, *qTable; + + qTable = temp_dc; + for (i = 0; i < (64 / 8); i++) { + if (getTblElement(fp, sLine) == 0) + return 0; + + memset(h, 0x00, 8 * sizeof(unsigned int)); + ret = sscanf(sLine, "%x %x %x %x %x %x %x %x", &h[0], &h[1], &h[2], + &h[3], &h[4], &h[5], &h[6], &h[7]); + + for (j = 0; j < 8; j++) + *qTable++ = (BYTE)h[j]; + } + + qTable = temp_ac; + for (i = 0; i < (64 / 8); i++) { + if (getTblElement(fp, sLine) == 0) + return 0; + + memset(h, 0x00, 8 * sizeof(unsigned int)); + ret = sscanf(sLine, "%x %x %x %x %x %x %x %x", &h[0], &h[1], &h[2], + &h[3], &h[4], &h[5], &h[6], &h[7]); + + for (j = 0; j < 8; j++) + *qTable++ = (BYTE)h[j]; + } + + qTable_dc = param->qMatTab[DC_TABLE_INDEX0]; + qTable_ac = param->qMatTab[AC_TABLE_INDEX0]; + + for (i = 0; i < 64; i++) { + qTable_dc[InvScanTable[i]] = temp_dc[i]; + qTable_ac[InvScanTable[i]] = temp_ac[i]; + } + + memcpy(param->qMatTab[DC_TABLE_INDEX1], param->qMatTab[DC_TABLE_INDEX0], 64); + memcpy(param->qMatTab[AC_TABLE_INDEX1], param->qMatTab[AC_TABLE_INDEX0], 64); + + (void)ret; + return 1; +} + +int jpgGetHuffTable(char *huffFileName, EncMjpgParam *param) +{ + char huffFilePath[256]; + osal_file_t *huffFp = NULL; + + if (huffFileName && huffFileName[0] != 0) { + // strcpy(huffFilePath, huffFileName); + huffFp = OSAL_FOPEN(huffFilePath, "rt"); + if (!huffFp) { + JLOG(ERR, "Can't open Huffman Table file %s\n", huffFilePath); + return 0; + } + parseHuffmanTable(huffFp, param); + OSAL_FCLOSE(huffFp); + } else { + // Rearrange and insert pre-defined Huffman table to deticated + // variable. + memcpy(param->huffBits[DC_TABLE_INDEX0], lumaDcBits, 16); // Luma DC BitLength + memcpy(param->huffVal[DC_TABLE_INDEX0], lumaDcValue, 16); // Luma DC HuffValue + + memcpy(param->huffBits[AC_TABLE_INDEX0], lumaAcBits, 16); // Luma DC BitLength + memcpy(param->huffVal[AC_TABLE_INDEX0], lumaAcValue, 162); // Luma DC HuffValue + + memcpy(param->huffBits[DC_TABLE_INDEX1], chromaDcBits, 16); // Chroma DC BitLength + memcpy(param->huffVal[DC_TABLE_INDEX1], chromaDcValue, 16); // Chroma DC HuffValue + + memcpy(param->huffBits[AC_TABLE_INDEX1], chromaAcBits, 16); // Chroma AC BitLength + memcpy(param->huffVal[AC_TABLE_INDEX1], chromaAcValue, 162); // Chorma AC HuffValue + } + + return 1; +} + +int jpgGetQMatrix(char *qMatFileName, EncMjpgParam *param) +{ + char qMatFilePath[256]; + osal_file_t *qMatFp = NULL; + + if (qMatFileName && qMatFileName[0] != 0) { + // strcpy(qMatFilePath, qMatFileName); + qMatFp = OSAL_FOPEN(qMatFilePath, "rt"); + if (!qMatFp) { + JLOG(ERR, "Can't open Q Matrix file %s\n", qMatFilePath); + return 0; + } + parseQMatrix(qMatFp, param); + OSAL_FCLOSE(qMatFp); + } else { + // Rearrange and insert pre-defined Q-matrix to deticated + // variable. + memcpy(param->qMatTab[DC_TABLE_INDEX0], lumaQ2, 64); + memcpy(param->qMatTab[AC_TABLE_INDEX0], chromaBQ2, 64); + + memcpy(param->qMatTab[DC_TABLE_INDEX1], param->qMatTab[DC_TABLE_INDEX0], 64); + memcpy(param->qMatTab[AC_TABLE_INDEX1], param->qMatTab[AC_TABLE_INDEX0], 64); + } + + return 1; +} + +/****************************************************************************** + * EncOpenParam Initialization + ******************************************************************************/ +int getJpgEncOpenParamDefault(JpgEncOpenParam *pEncOP, + EncConfigParam *pEncConfig) +{ + int ret; + EncMjpgParam mjpgParam; + + memset(&mjpgParam, 0x00, sizeof(EncMjpgParam)); + + pEncOP->picWidth = pEncConfig->picWidth; + pEncOP->picHeight = pEncConfig->picHeight; + pEncOP->sourceFormat = pEncConfig->mjpgChromaFormat; + pEncOP->restartInterval = 0; + pEncOP->chroma_interleave = pEncConfig->chroma_interleave; + pEncOP->packedFormat = pEncConfig->packedFormat; + mjpgParam.sourceFormat = pEncConfig->mjpgChromaFormat; + ret = jpgGetHuffTable(pEncConfig->huffFileName, &mjpgParam); + if (ret == 0) + return ret; + ret = jpgGetQMatrix(pEncConfig->qMatFileName, &mjpgParam); + if (ret == 0) + return ret; + + memcpy(pEncOP->huffVal, mjpgParam.huffVal, 4 * 162); + memcpy(pEncOP->huffBits, mjpgParam.huffBits, 4 * 256); + memcpy(pEncOP->qMatTab, mjpgParam.qMatTab, 4 * 64); + + return 1; +} + +/** + * To init EncOpenParam by CFG file + * IN + * EncConfigParam *pEncConfig + * OUT + * EncOpenParam *pEncOP + * char *srcYuvFileName + */ + +int getJpgEncOpenParam(JpgEncOpenParam *pEncOP, EncConfigParam *pEncConfig, char *srcYuvFileName) +{ + ENC_CFG encCfg; + int ret; + EncMjpgParam mjpgParam; + char cfgFileName[MAX_FILE_PATH]; + + // Source YUV Image File to load + // strcpy(srcYuvFileName, encCfg.SrcFileName); + memset(&encCfg, 0x00, sizeof(ENC_CFG)); + memset(&mjpgParam, 0x00, sizeof(EncMjpgParam)); + + if (strlen(pEncConfig->strCfgDir)) + sprintf(cfgFileName, "%s%s", pEncConfig->strCfgDir, pEncConfig->cfgFileName); + // else + // strcpy(cfgFileName, pEncConfig->cfgFileName); + + parseJpgCfgFile(&encCfg, cfgFileName); + + if (srcYuvFileName) { + if (strlen(pEncConfig->strStmDir)) + sprintf(srcYuvFileName, "%s%s", pEncConfig->strStmDir, encCfg.SrcFileName); + // else + // strcpy(srcYuvFileName, encCfg.SrcFileName); + } + + if (encCfg.FrmFormat == 0) + pEncConfig->chroma_interleave = CBCR_SEPARATED; + else if (encCfg.FrmFormat == 1) + pEncConfig->chroma_interleave = CBCR_INTERLEAVE; + else if (encCfg.FrmFormat == 2) + pEncConfig->chroma_interleave = CRCB_INTERLEAVE; + else + pEncConfig->chroma_interleave = CBCR_SEPARATED; + + pEncConfig->packedFormat = (encCfg.FrmFormat - 2); + if (pEncConfig->packedFormat < 0) + pEncConfig->packedFormat = 0; + + pEncConfig->outNum = encCfg.NumFrame; + + if (pEncOP) { + pEncOP->picWidth = encCfg.PicX; + pEncOP->picHeight = encCfg.PicY; + pEncOP->chroma_interleave = pEncConfig->chroma_interleave; + pEncOP->packedFormat = pEncConfig->packedFormat; + pEncOP->sourceFormat = encCfg.SrcFormat; + pEncOP->restartInterval = encCfg.RstIntval; + + mjpgParam.sourceFormat = encCfg.SrcFormat; + ret = jpgGetHuffTable(encCfg.HuffTabName, &mjpgParam); + if (ret == 0) + return ret; + ret = jpgGetQMatrix(encCfg.QMatTabName, &mjpgParam); + if (ret == 0) + return ret; + + memcpy(pEncOP->huffVal, mjpgParam.huffVal, 4 * 162); + memcpy(pEncOP->huffBits, mjpgParam.huffBits, 4 * 256); + memcpy(pEncOP->qMatTab, mjpgParam.qMatTab, 4 * 64); + } + + return 1; +} + +//------------------------------------------------------------------------------ +// ENCODE PARAMETER PARSE FUNCSIONS +//------------------------------------------------------------------------------ +// Parameter parsing helper +static int GetValue(osal_file_t *fp, char *para, char *value) +{ + static int LineNum = 1; + char lineStr[256]; + char paraStr[256]; + int ret = 0; + + OSAL_FSEEK(fp, 0, SEEK_SET); + + while (1) { + if (!OSAL_FGETS(lineStr, 256, fp)) + return 0; + ret = sscanf(lineStr, "%s %s", paraStr, value); + if (paraStr[0] != ';') { + if (strcmp(para, paraStr) == 0) + return 1; + } + LineNum++; + } + + (void)ret; + return 1; +} + +int parseJpgCfgFile(ENC_CFG *pEncCfg, char *FileName) +{ + osal_file_t *Fp; + int ret = 0; + + char sLine[256] = { + 0, + }; + + Fp = OSAL_FOPEN(FileName, "rt"); + + if (!Fp) { + BM_DBG_ERR(" > ERROR: File not exist <%s>\n", FileName); + return 0; + } + + // source file name + if (GetValue(Fp, "YUV_SRC_IMG", sLine) == 0) + return 0; + ret = sscanf(sLine, "%s", (char *)&pEncCfg->SrcFileName); + + // frame format + // ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr + // alternative) ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed + // (444 only) + if (GetValue(Fp, "FRAME_FORMAT", sLine) == 0) + return 0; + ret = kstrtoint(sLine, 10, &pEncCfg->FrmFormat);//sscanf(sLine, "%d", &pEncCfg->FrmFormat); + + // width + if (GetValue(Fp, "PICTURE_WIDTH", sLine) == 0) + return 0; + ret = kstrtoint(sLine, 10, &pEncCfg->PicX);//sscanf(sLine, "%d", &pEncCfg->PicX); + + // height + if (GetValue(Fp, "PICTURE_HEIGHT", sLine) == 0) + return 0; + ret = kstrtoint(sLine, 10, &pEncCfg->PicY);//sscanf(sLine, "%d", &pEncCfg->PicY); + + // frame_rate + if (GetValue(Fp, "FRAME_RATE", sLine) == 0) + return 0; + { + double frameRate = 0.0; + int timeRes, timeInc; + + // frameRate = (double)(int)atoi(sLine); + + timeInc = 1; + while ((int)frameRate != frameRate) { + timeInc *= 10; + frameRate *= 10; + } + timeRes = (int)frameRate; + // divide 2 or 5 + if (timeInc % 2 == 0 && timeRes % 2 == 0) + timeInc /= 2, timeRes /= 2; + if (timeInc % 5 == 0 && timeRes % 5 == 0) + timeInc /= 5, timeRes /= 5; + + if (timeRes == 2997 && timeInc == 100) + timeRes = 30000, timeInc = 1001; + pEncCfg->FrameRate = (timeInc - 1) << 16; + pEncCfg->FrameRate |= timeRes; + } + + // frame count + if (GetValue(Fp, "FRAME_NUMBER_ENCODED", sLine) == 0) + return 0; + + ret = kstrtoint(sLine, 10, &pEncCfg->NumFrame);//sscanf(sLine, "%d", &pEncCfg->NumFrame); + + if (GetValue(Fp, "VERSION_ID", sLine) == 0) + return 0; + + ret = kstrtoint(sLine, 10, &pEncCfg->VersionID);//sscanf(sLine, "%d", &pEncCfg->VersionID); + + if (GetValue(Fp, "RESTART_INTERVAL", sLine) == 0) + return 0; + + ret = kstrtoint(sLine, 10, &pEncCfg->RstIntval);//sscanf(sLine, "%d", &pEncCfg->RstIntval); + + if (GetValue(Fp, "IMG_FORMAT", sLine) == 0) + return 0; + + ret = kstrtoint(sLine, 10, &pEncCfg->SrcFormat);//sscanf(sLine, "%d", &pEncCfg->SrcFormat); + + if (GetValue(Fp, "QMATRIX_TABLE", sLine) == 0) + return 0; + + ret = sscanf(sLine, "%s", (char *)&pEncCfg->QMatTabName); + + if (GetValue(Fp, "HUFFMAN_TABLE", sLine) == 0) + return 0; + + ret = sscanf(sLine, "%s", (char *)&pEncCfg->HuffTabName); + + (void)ret; + OSAL_FCLOSE(Fp); + return 1; +} + +int FillSdramBurst(BufInfo *pBufInfo, Uint64 targetAddr, + PhysicalAddress bsBufStartAddr, PhysicalAddress bsBufEndAddr, + Uint32 size, int checkeos, int *streameos, int endian) +{ + Uint8 *pBuf; + int room; + + pBufInfo->count = 0; + + if (checkeos == 1 && pBufInfo->point >= pBufInfo->size) { + *streameos = 1; + return 0; + } + + if ((pBufInfo->size - pBufInfo->point) < (int)size) + pBufInfo->count = (pBufInfo->size - pBufInfo->point); + else + pBufInfo->count = size; + + pBuf = pBufInfo->buf + pBufInfo->point; + + if ((targetAddr + pBufInfo->count) > bsBufEndAddr) { + room = bsBufEndAddr - targetAddr; + JpuWriteMem(targetAddr, pBuf, room, endian); + JpuWriteMem(bsBufStartAddr, pBuf + room, (pBufInfo->count - room), endian); + } else { + JpuWriteMem(targetAddr, pBuf, pBufInfo->count, endian); + } + + pBufInfo->point += pBufInfo->count; + return pBufInfo->count; +} + +int StoreYuvImageBurstFormat(Uint8 *dst, int picWidth, int picHeight, + unsigned long addrY, unsigned long addrCb, + unsigned long addrCr, int stride, int interLeave, + int format, int endian, int packed) +{ + int size = 0; + int y = 0, nY = 0, nCb = 0, nCr = 0; + unsigned long addr = 0; + int lumaSize = 0, chromaSize = 0, chromaStride = 0, chromaWidth = 0, chromaHeight = 0; + + Uint8 *puc; + + switch (format) { + case FORMAT_420: + nY = (picHeight + 1) / 2 * 2; + nCb = (picHeight + 1) / 2; + nCr = (picHeight + 1) / 2; + chromaSize = ((picWidth + 1) / 2) * ((picHeight + 1) / 2); + chromaStride = stride / 2; + chromaWidth = (picWidth + 1) / 2; + chromaHeight = nY; + break; + case FORMAT_224: + nY = (picHeight + 1) / 2 * 2; + nCb = (picHeight + 1) / 2; + nCr = (picHeight + 1) / 2; + chromaSize = (picWidth) * ((picHeight + 1) / 2); + chromaStride = stride; + chromaWidth = picWidth; + chromaHeight = nY; + break; + case FORMAT_422: + nY = picHeight; + nCb = picHeight; + nCr = picHeight; + chromaSize = ((picWidth + 1) / 2) * picHeight; + chromaStride = stride / 2; + chromaWidth = (picWidth + 1) / 2; + chromaHeight = nY * 2; + break; + case FORMAT_444: + nY = picHeight; + nCb = picHeight; + nCr = picHeight; + chromaSize = picWidth * picHeight; + chromaStride = stride; + chromaWidth = picWidth; + chromaHeight = nY * 2; + break; + case FORMAT_400: + nY = picHeight; + nCb = 0; + nCr = 0; + chromaSize = 0; + chromaStride = 0; + chromaWidth = 0; + chromaHeight = 0; + break; + } + + puc = dst; + addr = addrY; + + if (packed) { + if (packed == PACKED_FORMAT_444) + picWidth *= 3; + else + picWidth *= 2; + + chromaSize = 0; + } + + lumaSize = picWidth * nY; + + size = lumaSize + chromaSize * 2; + + if (picWidth == stride) { + JpuReadMem(addr, (Uint8 *)(puc), lumaSize, endian); + + if (packed) + return size; + + if (interLeave) { + puc = dst + lumaSize; + addr = addrCb; + JpuReadMem(addr, (Uint8 *)(puc), chromaSize * 2, + endian); + } else { + puc = dst + lumaSize; + addr = addrCb; + JpuReadMem(addr, (Uint8 *)(puc), chromaSize, endian); + + puc = dst + lumaSize + chromaSize; + addr = addrCr; + JpuReadMem(addr, (Uint8 *)(puc), chromaSize, endian); + } + } else { + for (y = 0; y < nY; ++y) { + JpuReadMem(addr + stride * y, (Uint8 *)(puc + y * picWidth), picWidth, endian); + } + + if (packed) + return size; + + if (interLeave) { + puc = dst + lumaSize; + addr = addrCb; + for (y = 0; y < (chromaHeight / 2); ++y) { + JpuReadMem(addr + (chromaStride * 2) * y, + (Uint8 *)(puc + y * (chromaWidth * 2)), + (chromaWidth * 2), endian); + } + } else { + puc = dst + lumaSize; + addr = addrCb; + for (y = 0; y < nCb; ++y) { + JpuReadMem(addr + chromaStride * y, + (Uint8 *)(puc + y * chromaWidth), + chromaWidth, endian); + } + + puc = dst + lumaSize + chromaSize; + addr = addrCr; + for (y = 0; y < nCr; ++y) { + JpuReadMem(addr + chromaStride * y, + (Uint8 *)(puc + y * chromaWidth), + chromaWidth, endian); + } + } + } + + return size; +} + +void ProcessEncodedBitstreamBurst(osal_file_t *fp, unsigned long targetAddr, + PhysicalAddress bsBufStartAddr, + PhysicalAddress bsBufEndAddr, int size, + int endian) +{ + Uint8 *val = 0; + int room = 0; + + BM_DBG_TRACE("target addr :%lx\n", targetAddr); + BM_DBG_TRACE("start :%lx, end:%lx, size:%d\n", bsBufStartAddr, bsBufEndAddr, size); + + val = (Uint8 *)OSAL_MALLOC(size); + if ((targetAddr + size) > (unsigned long)bsBufEndAddr) { + room = bsBufEndAddr - targetAddr; + JpuReadMem(targetAddr, val, room, endian); + JpuReadMem(bsBufStartAddr, val + room, (size - room), endian); + } else { + BM_DBG_TRACE("read target addr :%lx\n", targetAddr); + JpuReadMem(targetAddr, val, size, endian); + } + + if (fp) { + OSAL_FWRITE(val, sizeof(Uint8), size, fp); + OSAL_FFLUSH(fp); + } + + OSAL_FREE(val); +} + +int LoadYuvImageBurstFormat(Uint8 *src, int picWidth, int picHeight, + unsigned long addrY, unsigned long addrCb, + unsigned long addrCr, int stride, int interLeave, + int format, int endian, int packed) +{ + int y = 0, nY = 0, nCb = 0, nCr = 0; + unsigned long addr = 0; + int size = 0; + int lumaSize = 0, chromaSize = 0, chromaStride = 0, chromaWidth = 0; + Uint8 *puc = NULL; + + switch (format) { + case FORMAT_420: + nY = picHeight; + nCb = picHeight / 2; + nCr = picHeight / 2; + chromaSize = picWidth * picHeight / 4; + chromaStride = stride / 2; + chromaWidth = picWidth / 2; + break; + case FORMAT_224: + nY = picHeight; + nCb = picHeight / 2; + nCr = picHeight / 2; + chromaSize = picWidth * picHeight / 2; + chromaStride = stride; + chromaWidth = picWidth; + break; + case FORMAT_422: + nY = picHeight; + nCb = picHeight; + nCr = picHeight; + chromaSize = picWidth * picHeight / 2; + chromaStride = stride / 2; + chromaWidth = picWidth / 2; + break; + case FORMAT_444: + nY = picHeight; + nCb = picHeight; + nCr = picHeight; + chromaSize = picWidth * picHeight; + chromaStride = stride; + chromaWidth = picWidth; + break; + case FORMAT_400: + nY = picHeight; + nCb = 0; + nCr = 0; + chromaSize = picWidth * picHeight / 4; + chromaStride = stride / 2; + chromaWidth = picWidth / 2; + break; + } + + puc = src; + addr = addrY; + + if (packed) { + if (packed == PACKED_FORMAT_444) + picWidth *= 3; + else + picWidth *= 2; + + chromaSize = 0; + } + + lumaSize = picWidth * nY; + + size = lumaSize + chromaSize * 2; + + if (picWidth == stride) { // for fast write + JpuWriteMem(addr, (Uint8 *)(puc), lumaSize, endian); + + if (format == FORMAT_400) + return size; + + if (packed) + return size; + + if (interLeave) { + Uint8 t0, t1, t2, t3, t4, t5, t6, t7; + int i, height, width; + int stride; + Uint8 *pTemp; + Uint8 *dstAddrCb; + Uint8 *dstAddrCr; + + addr = addrCb; + stride = chromaStride * 2; + height = nCb; + width = chromaWidth * 2; + + dstAddrCb = (Uint8 *)(puc + picWidth * nY); + dstAddrCr = (Uint8 *)(dstAddrCb + chromaSize); + + pTemp = OSAL_MALLOC(width); + if (!pTemp) { + return 0; + } + + for (y = 0; y < height; ++y) { + for (i = 0; i < width; i += 8) { + t0 = *dstAddrCb++; + t2 = *dstAddrCb++; + t4 = *dstAddrCb++; + t6 = *dstAddrCb++; + t1 = *dstAddrCr++; + t3 = *dstAddrCr++; + t5 = *dstAddrCr++; + t7 = *dstAddrCr++; + if (interLeave == CBCR_INTERLEAVE) { + pTemp[i] = t0; + pTemp[i + 1] = t1; + pTemp[i + 2] = t2; + pTemp[i + 3] = t3; + pTemp[i + 4] = t4; + pTemp[i + 5] = t5; + pTemp[i + 6] = t6; + pTemp[i + 7] = t7; + } else { // CRCB_INTERLEAVE + pTemp[i] = t1; + pTemp[i + 1] = t0; + pTemp[i + 2] = t3; + pTemp[i + 3] = t2; + pTemp[i + 4] = t5; + pTemp[i + 5] = t4; + pTemp[i + 6] = t7; + pTemp[i + 7] = t6; + } + } + JpuWriteMem(addr + stride * y, (unsigned char *)pTemp, width, endian); + } + + OSAL_FREE(pTemp); + } else { + puc = src + lumaSize; + addr = addrCb; + JpuWriteMem(addr, (Uint8 *)puc, chromaSize, endian); + + puc = src + lumaSize + chromaSize; + addr = addrCr; + JpuWriteMem(addr, (Uint8 *)puc, chromaSize, endian); + } + } else { + for (y = 0; y < nY; ++y) { + JpuWriteMem(addr + stride * y, (Uint8 *)(puc + y * picWidth), picWidth, endian); + } + + if (format == FORMAT_400) + return size; + + if (packed) + return size; + + if (interLeave == 1) { + Uint8 t0, t1, t2, t3, t4, t5, t6, t7; + int i, width, height, stride; + Uint8 *pTemp; + Uint8 *dstAddrCb; + Uint8 *dstAddrCr; + + addr = addrCb; + stride = chromaStride * 2; + height = nCb / 2; + width = chromaWidth * 2; + + dstAddrCb = (Uint8 *)(puc + picWidth * nY); + dstAddrCr = (Uint8 *)(dstAddrCb + chromaSize); + + pTemp = OSAL_MALLOC((width + 7) & ~7); + if (!pTemp) { + return 0; + } + + // it may be not occur that pic_width in not 8byte + // alined. + for (y = 0; y < height; ++y) { + for (i = 0; i < width; i += 8) { + t0 = *dstAddrCb++; + t2 = *dstAddrCb++; + t4 = *dstAddrCb++; + t6 = *dstAddrCb++; + t1 = *dstAddrCr++; + t3 = *dstAddrCr++; + t5 = *dstAddrCr++; + t7 = *dstAddrCr++; + + if (interLeave == CBCR_INTERLEAVE) { + pTemp[i] = t0; + pTemp[i + 1] = t1; + pTemp[i + 2] = t2; + pTemp[i + 3] = t3; + pTemp[i + 4] = t4; + pTemp[i + 5] = t5; + pTemp[i + 6] = t6; + pTemp[i + 7] = t7; + } else { // CRCB_INTERLEAVE + pTemp[i] = t1; + pTemp[i + 1] = t0; + pTemp[i + 2] = t3; + pTemp[i + 3] = t2; + pTemp[i + 4] = t5; + pTemp[i + 5] = t3; + pTemp[i + 6] = t7; + pTemp[i + 7] = t6; + } + + JpuWriteMem(addr + stride * y, (unsigned char *)pTemp, stride, endian); + } + } + + } else { + puc = src + lumaSize; + addr = addrCb; + for (y = 0; y < nCb; ++y) { + JpuWriteMem(addr + chromaStride * y, + (Uint8 *)(puc + y * chromaWidth), + chromaWidth, endian); + } + + puc = src + lumaSize + chromaSize; + addr = addrCr; + for (y = 0; y < nCr; ++y) { + JpuWriteMem(addr + chromaStride * y, + (Uint8 *)(puc + y * chromaWidth), + chromaWidth, endian); + } + } + } + + return size; +} + +void GetMcuUnitSize(int format, int *mcuWidth, int *mcuHeight) +{ + switch (format) { + case FORMAT_420: + *mcuWidth = 16; + *mcuHeight = 16; + break; + case FORMAT_422: + *mcuWidth = 16; + *mcuHeight = 8; + break; + case FORMAT_224: + *mcuWidth = 8; + *mcuHeight = 16; + break; + default: // FORMAT_444,400 + *mcuWidth = 8; + *mcuHeight = 8; + break; + } +} + +unsigned int GetFrameBufSize(int framebufFormat, int picWidth, int picHeight) +{ + unsigned int framebufSize = 0; + unsigned int framebufWidth, framebufHeight; + + if (framebufFormat == FORMAT_420 || framebufFormat == FORMAT_422) + framebufWidth = ((picWidth + 15) / 16) * 16; + else + framebufWidth = ((picWidth + 7) / 8) * 8; + + if (framebufFormat == FORMAT_420 || framebufFormat == FORMAT_224) + framebufHeight = ((picHeight + 15) / 16) * 16; + else + framebufHeight = ((picHeight + 7) / 8) * 8; + + switch (framebufFormat) { + case FORMAT_420: + framebufSize = + framebufWidth * ((framebufHeight + 1) / 2 * 2) + + ((framebufWidth + 1) / 2) * ((framebufHeight + 1) / 2) * 2; + break; + case FORMAT_224: + framebufSize = framebufWidth * ((framebufHeight + 1) / 2 * 2) + + framebufWidth * ((framebufHeight + 1) / 2) * 2; + break; + case FORMAT_422: + framebufSize = framebufWidth * framebufHeight + + ((framebufWidth + 1) / 2) * framebufHeight * 2; + break; + case FORMAT_444: + framebufSize = framebufWidth * framebufHeight * 3; + break; + case FORMAT_400: + framebufSize = framebufWidth * framebufHeight; + break; + } + + framebufSize = ((framebufSize + 7) & ~7); + + return framebufSize; +} + +// inteleave : 0 (chroma separate mode), 1 (cbcr interleave mode), 2 (crcb +// interleave mode) +yuv2rgb_color_format +convert_jpuapi_format_to_yuv2rgb_color_format(int planar_format, + int pack_format, int interleave) +{ + yuv2rgb_color_format format = 0; + + if (!pack_format) { + switch (planar_format) { + case FORMAT_400: + format = YUV400; + break; + case FORMAT_444: + format = YUV444; + break; + case FORMAT_224: + case FORMAT_422: + format = YUV422; + break; + case FORMAT_420: + if (interleave == 0) + format = YUV420; + else if (interleave == 1) + format = NV12; + else + format = NV21; + break; + } + } else { + switch (pack_format) { + case PACKED_FORMAT_422_YUYV: + format = YUYV; + break; + case PACKED_FORMAT_422_UYVY: + format = UYVY; + break; + case PACKED_FORMAT_422_YVYU: + format = YVYU; + break; + case PACKED_FORMAT_422_VYUY: + format = VYUY; + break; + case PACKED_FORMAT_444: + format = YYY; + break; + } + } + + return format; +} + +void jpu_yuv2rgb(int width, int height, yuv2rgb_color_format format, + unsigned char *src, unsigned char *rgba, int cbcr_reverse) +{ +#define jpu_clip(var) (((var) >= 255) ? 255 : ((var) <= 0) ? 0 : (var)) + int j, i; + int c, d, e; + + unsigned char *line = rgba; + unsigned char *cur = NULL; + unsigned char *y = NULL; + unsigned char *u = NULL; + unsigned char *v = NULL; + unsigned char *misc = NULL; + + int frame_size_y; + int frame_size_uv; + int t_width; + + frame_size_y = width * height; + + if (format == YUV444 || format == RGB_PLANAR) + frame_size_uv = width * height; + else if (format == YUV422) + frame_size_uv = (width * height) >> 1; + else if (format == YUV420 || format == NV12 || format == NV21) + frame_size_uv = (width * height) >> 2; + else + frame_size_uv = 0; + + t_width = width; + + if (format == YUYV || format == YVYU || format == UYVY || format == VYUY) { + misc = src; + } else if (format == NV12 || format == NV21) { + y = src; + misc = src + frame_size_y; + } else if (format == RGB32 || format == RGB24 || format == RGB16) { + misc = src; + } else { + y = src; + u = src + frame_size_y; + v = src + frame_size_y + frame_size_uv; + } + + if (format == YUV444) { + for (j = 0; j < height; j++) { + cur = line; + for (i = 0; i < width; i++) { + c = y[j * width + i] - 16; + d = u[j * width + i] - 128; + e = v[j * width + i] - 128; + + if (!cbcr_reverse) { + d = u[j * width + i] - 128; + e = v[j * width + i] - 128; + } else { + e = u[j * width + i] - 128; + e = v[j * width + i] - 128; + } + (*cur) = jpu_clip((298 * c + 409 * e + 128) >> 8); + cur++; + (*cur) = jpu_clip((298 * c - 100 * d - 208 * e + 128) >> 8); + cur++; + (*cur) = jpu_clip((298 * c + 516 * d + 128) >> 8); + cur++; + (*cur) = 0; + cur++; + } + line += t_width << 2; + } + } else if (format == YUV422) { + for (j = 0; j < height; j++) { + cur = line; + for (i = 0; i < width; i++) { + c = y[j * width + i] - 16; + d = u[j * (width >> 1) + (i >> 1)] - 128; + e = v[j * (width >> 1) + (i >> 1)] - 128; + + if (!cbcr_reverse) { + d = u[j * (width >> 1) + (i >> 1)] - 128; + e = v[j * (width >> 1) + (i >> 1)] - 128; + } else { + e = u[j * (width >> 1) + (i >> 1)] - 128; + d = v[j * (width >> 1) + (i >> 1)] - 128; + } + + (*cur) = jpu_clip((298 * c + 409 * e + 128) >> 8); + cur++; + (*cur) = jpu_clip((298 * c - 100 * d - 208 * e + 128) >> 8); + cur++; + (*cur) = jpu_clip((298 * c + 516 * d + 128) >> 8); + cur++; + (*cur) = 0; + cur++; + } + line += t_width << 2; + } + } else if (format == YUYV || format == YVYU || format == UYVY || format == VYUY) { + unsigned char *t = misc; + + for (j = 0; j < height; j++) { + cur = line; + for (i = 0; i < width; i += 2) { + switch (format) { + case YUYV: + c = *(t) - 16; + if (!cbcr_reverse) { + d = *(t + 1) - 128; + e = *(t + 3) - 128; + } else { + e = *(t + 1) - 128; + d = *(t + 3) - 128; + } + break; + case YVYU: + c = *(t) - 16; + if (!cbcr_reverse) { + d = *(t + 3) - 128; + e = *(t + 1) - 128; + } else { + e = *(t + 3) - 128; + d = *(t + 1) - 128; + } + break; + case UYVY: + c = *(t + 1) - 16; + if (!cbcr_reverse) { + d = *(t) - 128; + e = *(t + 2) - 128; + } else { + e = *(t) - 128; + d = *(t + 2) - 128; + } + break; + case VYUY: + c = *(t + 1) - 16; + if (!cbcr_reverse) { + d = *(t + 2) - 128; + e = *(t) - 128; + } else { + e = *(t + 2) - 128; + d = *(t) - 128; + } + break; + default: // like YUYV + c = *(t) - 16; + if (!cbcr_reverse) { + d = *(t + 1) - 128; + e = *(t + 3) - 128; + } else { + e = *(t + 1) - 128; + d = *(t + 3) - 128; + } + break; + } + + (*cur) = jpu_clip((298 * c + 409 * e + 128) >> 8); + cur++; + (*cur) = jpu_clip((298 * c - 100 * d - 208 * e + 128) >> 8); + cur++; + (*cur) = jpu_clip((298 * c + 516 * d + 128) >> 8); + cur++; + (*cur) = 0; + cur++; + + switch (format) { + case YUYV: + case YVYU: + c = *(t + 2) - 16; + break; + + case VYUY: + case UYVY: + c = *(t + 3) - 16; + break; + default: // like YUYV + c = *(t + 2) - 16; + break; + } + + (*cur) = jpu_clip((298 * c + 409 * e + 128) >> 8); + cur++; + (*cur) = jpu_clip((298 * c - 100 * d - 208 * e + 128) >> 8); + cur++; + (*cur) = jpu_clip((298 * c + 516 * d + 128) >> 8); + cur++; + (*cur) = 0; + cur++; + + t += 4; + } + line += t_width << 2; + } + } else if (format == YUV420 || format == NV12 || format == NV21) { + for (j = 0; j < height; j++) { + cur = line; + for (i = 0; i < width; i++) { + c = y[j * width + i] - 16; + if (format == YUV420) { + if (!cbcr_reverse) { + d = u[(j >> 1) * (width >> 1) + (i >> 1)] - 128; + e = v[(j >> 1) * (width >> 1) + (i >> 1)] - 128; + } else { + e = u[(j >> 1) * (width >> 1) + (i >> 1)] - 128; + d = v[(j >> 1) * (width >> 1) + (i >> 1)] - 128; + } + } else if (format == NV12) { + if (!cbcr_reverse) { + d = misc[(j >> 1) * width + (i >> 1 << 1)] - 128; + e = misc[(j >> 1) * width + (i >> 1 << 1) + 1] - 128; + } else { + e = misc[(j >> 1) * width + (i >> 1 << 1)] - 128; + d = misc[(j >> 1) * width + (i >> 1 << 1) + 1] - 128; + } + } else { // if (m_color == NV21) + if (!cbcr_reverse) { + d = misc[(j >> 1) * width + (i >> 1 << 1) + 1] - 128; + e = misc[(j >> 1) * width + (i >> 1 << 1)] - 128; + } else { + e = misc[(j >> 1) * width + (i >> 1 << 1) + 1] - 128; + d = misc[(j >> 1) * width + (i >> 1 << 1)] - 128; + } + } + (*cur) = jpu_clip((298 * c + 409 * e + 128) >> 8); + cur++; + (*cur) = jpu_clip((298 * c - 100 * d - 208 * e + 128) >> 8); + cur++; + (*cur) = jpu_clip((298 * c + 516 * d + 128) >> 8); + cur++; + (*cur) = 0; + cur++; + } + line += t_width << 2; + } + } else if (format == RGB_PLANAR) { + for (j = 0; j < height; j++) { + cur = line; + for (i = 0; i < width; i++) { + (*cur) = y[j * width + i]; + cur++; + (*cur) = u[j * width + i]; + cur++; + (*cur) = v[j * width + i]; + cur++; + (*cur) = 0; + cur++; + } + line += t_width << 2; + } + } else if (format == RGB32) { + for (j = 0; j < height; j++) { + cur = line; + for (i = 0; i < width; i++) { + (*cur) = misc[j * width * 4 + i]; + cur++; // R + (*cur) = misc[j * width * 4 + i + 1]; + cur++; // G + (*cur) = misc[j * width * 4 + i + 2]; + cur++; // B + (*cur) = misc[j * width * 4 + i + 3]; + cur++; // A + } + line += t_width << 2; + } + } else if (format == RGB24) { + for (j = 0; j < height; j++) { + cur = line; + for (i = 0; i < width; i++) { + (*cur) = misc[j * width * 3 + i]; + cur++; // R + (*cur) = misc[j * width * 3 + i + 1]; + cur++; // G + (*cur) = misc[j * width * 3 + i + 2]; + cur++; // B + (*cur) = 0; + cur++; + } + line += t_width << 2; + } + } else if (format == RGB16) { + for (j = 0; j < height; j++) { + cur = line; + for (i = 0; i < width; i++) { + int tmp = misc[j * width * 2 + i] << 8 | misc[j * width * 2 + i + 1]; + (*cur) = ((tmp >> 11) & 0x1F << 3); + cur++; // R(5bit) + (*cur) = ((tmp >> 5) & 0x3F << 2); + cur++; // G(6bit) + (*cur) = ((tmp) & 0x1F << 3); + cur++; // B(5bit) + (*cur) = 0; + cur++; + } + line += t_width << 2; + } + } else { // YYY + for (j = 0; j < height; j++) { + cur = line; + for (i = 0; i < width; i++) { + (*cur) = y[j * width + i]; + cur++; + (*cur) = y[j * width + i]; + cur++; + (*cur) = y[j * width + i]; + cur++; + (*cur) = 0; + cur++; + } + line += t_width << 2; + } + } +} + +int comparateYuv(Uint8 *pYuv, Uint8 *pRefYuv, int picWidth, int picHeight, + int stride, int interleave, int format, int endian, int packed) +{ + int size = 0; + int y = 0, nY = 0, nCb = 0, nCr = 0; + Uint8 *pRef = NULL; + int lumaSize = 0, chromaSize = 0, chromaStride = 0, chromaWidth = 0, chromaHeight = 0; + + Uint8 *pOrg = NULL; + + switch (format) { + case FORMAT_420: + nY = (picHeight + 1) / 2 * 2; + nCb = (picHeight + 1) / 2; + nCr = (picHeight + 1) / 2; + chromaSize = ((picWidth + 1) / 2) * ((picHeight + 1) / 2); + chromaStride = stride / 2; + chromaWidth = (picWidth + 1) / 2; + chromaHeight = nY; + break; + case FORMAT_224: + nY = (picHeight + 1) / 2 * 2; + nCb = (picHeight + 1) / 2; + nCr = (picHeight + 1) / 2; + chromaSize = (picWidth) * ((picHeight + 1) / 2); + chromaStride = stride; + chromaWidth = picWidth; + chromaHeight = nY; + break; + case FORMAT_422: + nY = picHeight; + nCb = picHeight; + nCr = picHeight; + chromaSize = ((picWidth + 1) / 2) * picHeight; + chromaStride = stride / 2; + chromaWidth = (picWidth + 1) / 2; + chromaHeight = nY * 2; + break; + case FORMAT_444: + nY = picHeight; + nCb = picHeight; + nCr = picHeight; + chromaSize = picWidth * picHeight; + chromaStride = stride; + chromaWidth = picWidth; + chromaHeight = nY * 2; + break; + case FORMAT_400: + nY = picHeight; + nCb = 0; + nCr = 0; + chromaSize = 0; + chromaStride = 0; + chromaWidth = 0; + chromaHeight = 0; + break; + } + + pRef = pRefYuv; + pOrg = pYuv; + + if (packed) { + if (packed == PACKED_FORMAT_444) + picWidth *= 3; + else + picWidth *= 2; + + chromaSize = 0; + } + + lumaSize = picWidth * nY; + + size = lumaSize + chromaSize * 2; + + if (picWidth == stride) { + if (OSAL_MEMCMP(pRef, pOrg, size)) { + JLOG(INFO, "pRef = 0x%lx, pOrg = 0x%lx, size:%d\n", + (unsigned long)pRef, (unsigned long)pOrg, size); + return 1; + } else + return 0; + } else { + for (y = 0; y < nY; ++y) { + if (OSAL_MEMCMP(pOrg + stride * y, pRef + y * picWidth, picWidth)) { + JLOG(INFO, "pRef1 = 0x%lx, pOrg1 = 0x%lx\n", + (unsigned long)(pRef + y * picWidth), + (unsigned long)(pOrg + stride * y)); + return 1; + } + } + + if (packed) + return 0; + + pRef = pRef + lumaSize; + pOrg = pOrg + nY * stride; + if (interleave) { + for (y = 0; y < (chromaHeight / 2); ++y) { + if (OSAL_MEMCMP(pOrg + (chromaStride * 2) * y, + pRef + y * (chromaWidth * 2), + (chromaWidth * 2))) { + JLOG(INFO, "pRef1 = 0x%lx\n", (unsigned long)(pOrg + (chromaStride * 2) * y)); + JLOG(INFO, "pOrg2 = 0x%lx\n", (unsigned long)(pRef + y * (chromaWidth * 2))); + return 1; + } + } + } else { + for (y = 0; y < nCb; ++y) { + if (OSAL_MEMCMP(pOrg + chromaStride * y, pRef + y * chromaWidth, chromaWidth)) { + JLOG(INFO, + "pRef3 = 0x%lx, pOrg3 = 0x%lx\n", + (unsigned long)(pOrg + chromaStride * y), + (unsigned long)(pRef + y * chromaWidth)); + return 1; + } + } + + pRef = pRef + chromaSize; + pOrg = pOrg + nCb * chromaStride; + for (y = 0; y < nCr; ++y) { + if (OSAL_MEMCMP(pOrg + chromaStride * y, pRef + y * chromaWidth, chromaWidth)) { + JLOG(INFO, + "pRef4 = 0x%lx, pOrg4 = 0x%lx\n", + (unsigned long)(pOrg + chromaStride * y), + (unsigned long)(pRef + y * chromaWidth)); + return 1; + } + } + } + } + + return 0; +} diff --git a/u-boot-2021.10/drivers/jpeg/jpuhelper.h b/u-boot-2021.10/drivers/jpeg/jpuhelper.h new file mode 100644 index 000000000..f000b5b9d --- /dev/null +++ b/u-boot-2021.10/drivers/jpeg/jpuhelper.h @@ -0,0 +1,165 @@ +#ifndef _JPU_HELPER_H_ +#define _JPU_HELPER_H_ + +#include "jpuapi.h" +#include "jpurun.h" + +typedef struct { + char SrcFileName[256]; + int NumFrame; + int PicX; + int PicY; + int FrameRate; + + // MPEG4 ONLY + int VerId; + int DataPartEn; + int RevVlcEn; + int ShortVideoHeader; + int AnnexI; + int AnnexJ; + int AnnexK; + int AnnexT; + int IntraDcVlcThr; + int VopQuant; + + // H.264 ONLY + int ConstIntraPredFlag; + int DisableDeblk; + int DeblkOffsetA; + int DeblkOffsetB; + int ChromaQpOffset; + int PicQpY; + + // MJPEG ONLY + char HuffTabName[256]; + char QMatTabName[256]; + int VersionID; + int FrmFormat; + int SrcFormat; + int RstIntval; + int ThumbEnable; + int ThumbSizeX; + int ThumbSizeY; + + // COMMON + int GopPicNum; + int SliceMode; + int SliceSizeMode; + int SliceSizeNum; + + int IntraRefreshNum; + + int ConstantIntraQPEnable; + int RCIntraQP; + int MaxQpSetEnable; + int MaxQp; + int GammaSetEnable; + int Gamma; + int HecEnable; + + // RC + int RcEnable; + int RcBitRate; + int RcInitDelay; + int RcBufSize; + + // NEW RC Scheme + int RcIntervalMode; + int RcMBInterval; + int IntraCostWeight; + int SearchRange; + int MeUseZeroPmv; + int MeBlkModeEnable; + +} ENC_CFG; + +typedef struct { + int sourceFormat; + int restartInterval; + BYTE huffVal[4][162]; + BYTE huffBits[4][256]; + BYTE qMatTab[4][64]; +} EncMjpgParam; + +#if defined(__cplusplus) +extern "C" { +#endif + +int jpgGetHuffTable(char *huffFileName, EncMjpgParam *param); +int jpgGetQMatrix(char *qMatFileName, EncMjpgParam *param); + +int getJpgEncOpenParamDefault(JpgEncOpenParam *pEncOP, EncConfigParam *pEncConfig); +int getJpgEncOpenParam(JpgEncOpenParam *pEncOP, EncConfigParam *pEncConfig, char *srcYuvFileName); +int parseJpgCfgFile(ENC_CFG *pEncCfg, char *FileName); + +JpgRet WriteJpgBsBufHelper(JpgDecHandle handle, BufInfo *pBufInfo, + PhysicalAddress paBsBufStart, + PhysicalAddress paBsBufEnd, int defaultsize, + int checkeos, int *pstreameos, int endian); + +int WriteBsBufFromBufHelper(JpgDecHandle handle, jpu_buffer_t *pJbStream, + BYTE *pChunk, int chunkSize, int endian); + +JpgRet ReadJpgBsBufHelper(JpgEncHandle handle, osal_file_t *bsFp, + PhysicalAddress paBsBufStart, + PhysicalAddress paBsBufEnd, int encHeaderSize, + int endian); + +int LoadYuvImageHelperFormat(osal_file_t *yuvFp, Uint8 *pYuv, + PhysicalAddress addrY, PhysicalAddress addrCb, + PhysicalAddress addrCr, int picWidth, + int picHeight, int stride, int interleave, + int format, int endian, int packed); + +int LoadYuvPartialImageHelperFormat(osal_file_t *yuvFp, Uint8 *pYuv, PhysicalAddress addrY, + PhysicalAddress addrCb, PhysicalAddress addrCr, int picWidth, int picHeight, + int picHeightPartial, int stride, int interleave, int format, int endian, + int partPosIdx, int frameIdx, int packed); + +int SaveYuvImageHelperFormat(osal_file_t *yuvFp, Uint8 *pYuv, + PhysicalAddress addrY, PhysicalAddress addrCb, + PhysicalAddress addrCr, int picWidth, + int picHeight, int stride, int interLeave, + int format, int endian, int packed); + +int SaveYuvPartialImageHelperFormat(osal_file_t *yuvFp, Uint8 *pYuv, PhysicalAddress addrY, + PhysicalAddress addrCb, PhysicalAddress addrCr, int picWidth, int picHeight, + int picHeightPartial, int stride, int interLeave, int format, int endian, + int partPosIdx, int frameIdx, int packed); + +unsigned int GetFrameBufSize(int framebufFormat, int picWidth, int picHeight); +void GetMcuUnitSize(int format, int *mcuWidth, int *mcuHeight); + +typedef enum { + YUV444, + YUV422, + YUV420, + NV12, + NV21, + YUV400, + YUYV, + YVYU, + UYVY, + VYUY, + YYY, + RGB_PLANAR, + RGB32, + RGB24, + RGB16 +} yuv2rgb_color_format; + +void jpu_yuv2rgb(int width, int height, yuv2rgb_color_format format, + unsigned char *src, unsigned char *rgba, int chroma_reverse); +yuv2rgb_color_format +convert_jpuapi_format_to_yuv2rgb_color_format(int planar_format, + int pack_format, int interleave); + +int comparateYuv(Uint8 *pYuv, Uint8 *pRefYuv, int picWidth, int picHeight, + int stride, int interleave, int format, int endian, + int packed); +#if defined(__cplusplus) +} +#endif + +#endif //#ifndef _JPU_HELPER_H_ diff --git a/u-boot-2021.10/drivers/jpeg/jpulog.h b/u-boot-2021.10/drivers/jpeg/jpulog.h new file mode 100644 index 000000000..70e7e1973 --- /dev/null +++ b/u-boot-2021.10/drivers/jpeg/jpulog.h @@ -0,0 +1,79 @@ +#ifndef _JPU_LOG_H_ +#define _JPU_LOG_H_ + +#include +#include +#include +#include +#include + +enum { NONE = 0, INFO, WARN, ERR, TRACE, MAX_LOG_LEVEL }; + +enum { + LOG_HAS_DAY_NAME = 1, /**< Include day name [default: no] */ + LOG_HAS_YEAR = 2, /**< Include year digit [no] */ + LOG_HAS_MONTH = 4, /**< Include month [no] */ + LOG_HAS_DAY_OF_MON = 8, /**< Include day of month [no] */ + LOG_HAS_TIME = 16, /**< Include time [yes] */ + LOG_HAS_MICRO_SEC = 32, /**< Include microseconds [yes] ......*/ + LOG_HAS_FILE = 64, /**< Include sender in the log [yes] */ + LOG_HAS_NEWLINE = 128, /**< Terminate each call with newline [yes] .*/ + LOG_HAS_CR = 256, /**< Include carriage return [no] */ + LOG_HAS_SPACE = 512, /**< Include two spaces before log[yes] ..*/ + LOG_HAS_COLOR = 1024, /**< Colorize logs [yes on win32] */ + LOG_HAS_LEVEL_TEXT = 2048 /**< Include level text string [no] */ +}; + +enum { + TERM_COLOR_R = 2, /**< Red */ + TERM_COLOR_G = 4, /**< Green */ + TERM_COLOR_B = 1, /**< Blue. */ + TERM_COLOR_BRIGHT = 8 /**< Bright mask. */ +}; + +#define MAX_PRINT_LENGTH 512 +#ifdef ANDROID +#include +#undef LOG_NDEBUG +#define LOG_NDEBUG 0 +#undef LOG_TAG +#define LOG_TAG "JPUAPI" +#endif + +#define JLOG LogMsg + +#define LOG_ENABLE_FILE SetLogDecor(GetLogDecor() | LOG_HAS_FILE) + +#if defined(__cplusplus) +extern "C" { +#endif + +int InitLog(void); +void DeInitLog(void); + +void SetMaxLogLevel(int level); +int GetMaxLogLevel(void); + +void SetLogColor(int level, int color); +int GetLogColor(int level); + +void SetLogDecor(int decor); +int GetLogDecor(void); + +#define JLOG_LEVEL ERR + +#define LogMsg(level, msg, ...) \ + if (JLOG_LEVEL <= (level)) \ + printf("%s = %d, " msg, __func__, __LINE__, ##__VA_ARGS__) + +void timer_stop(void); +double timer_elapsed_us(void); +double timer_elapsed_ms(void); +int timer_is_valid(void); +double timer_frequency(void); + +#if defined(__cplusplus) +} +#endif + +#endif //#ifndef _JPU_LOG_H_ \ No newline at end of file diff --git a/u-boot-2021.10/drivers/jpeg/jpurun.c b/u-boot-2021.10/drivers/jpeg/jpurun.c new file mode 100644 index 000000000..d7b07c6b2 --- /dev/null +++ b/u-boot-2021.10/drivers/jpeg/jpurun.c @@ -0,0 +1,704 @@ +#include "jpuapi.h" +#include "jpuapifunc.h" +#include "jpuhelper.h" +#include "jpulog.h" +#include "jpurun.h" +#include "mixer.h" +#include "regdefine.h" +#include +#include "asm/cache.h" + +#ifdef JPU_FPGA_PLATFORM +//#define ENC_SOURCE_FRAME_DISPLAY +#endif + +#define NUM_FRAME_BUF MAX_FRAME +#define MAX_ROT_BUF_NUM 1 +#define EXTRA_FRAME_BUFFER_NUM 0 +#define ENC_SRC_BUF_NUM 1 +//#define ROI_RANDOM_TEST +//#define TEST_JPEG_PERFORMANCE + +#ifdef TEST_JPEG_PERFORMANCE +#undef __CONFIG_H__ + +#include "fw_config.h" +#include "system_common.h" +#include "dm/device.h" +#include "timer.h" +#endif + +#define ALIGN_N_BIT(ADDR, BITS) ((((ADDR) + ((1 << (BITS)) - 1)) >> (BITS)) << (BITS)) + +int img_width, img_height; + +int copy_to_dest_addr(Uint8 *pYuv, Uint8 *pRefYuv, + int picWidth, int picHeight, int strideY, int strideC, + int interleave, int format, int endian, int packed) +{ + int size = 0; + int nY = 0; + Uint8 *pRef = NULL; + int lumaSize = 0, chromaSize = 0; + + Uint8 *pOrg = NULL; + + switch (format) { + case FORMAT_420: + nY = (picHeight + 1) / 2 * 2; + chromaSize = ((picWidth + 1) / 2) * ((picHeight + 1) / 2); + break; + case FORMAT_224: + nY = (picHeight + 1) / 2 * 2; + chromaSize = (picWidth) * ((picHeight + 1) / 2); + break; + case FORMAT_422: + nY = picHeight; + chromaSize = ((picWidth + 1) / 2) * picHeight; + break; + case FORMAT_444: + nY = picHeight; + chromaSize = picWidth * picHeight; + break; + case FORMAT_400: + nY = picHeight; + chromaSize = 0; + break; + } + + pRef = pRefYuv; + pOrg = pYuv; + + if (packed) { + if (packed == PACKED_FORMAT_444) + picWidth *= 3; + else + picWidth *= 2; + + lumaSize = picWidth * nY; + chromaSize = 0; + } else { + if (format == FORMAT_420) { + lumaSize = strideY * nY; + chromaSize = strideC * ((picHeight + 1) / 2); + } else { + lumaSize = picWidth * nY; + } + } + + CVI_JPG_DBG("nY = %d, picHeight = %d\n", nY, picHeight); + CVI_JPG_DBG("strideY = %d, lumaSize = 0x%X\n", strideY, lumaSize); + CVI_JPG_DBG("strideC = %d, chromaSize = 0x%X\n", strideC, chromaSize); + + size = lumaSize + chromaSize * 2; + + CVI_JPG_DBG("size = 0x%X, lumaSize = 0x%X, chromaSize = 0x%X\n", size, lumaSize, chromaSize); + + CVI_JPG_DBG("y, pRef = %p, pOrg = %p\n", pRef, pOrg); + OSAL_MEMCPY(pRef, pOrg, lumaSize); + + pOrg += lumaSize; + pRef += lumaSize; + pRef = (Uint8 *)ALIGN_N_BIT((unsigned long long)pRef, 12); + CVI_JPG_DBG("u, pRef = %p, pOrg = %p\n", pRef, pOrg); + OSAL_MEMCPY(pRef, pOrg, chromaSize); + + pOrg += chromaSize; + pRef += chromaSize; + pRef = (Uint8 *)ALIGN_N_BIT((unsigned long long)pRef, 12); + CVI_JPG_DBG("v, pRef = %p, pOrg = %p\n", pRef, pOrg); + OSAL_MEMCPY(pRef, pOrg, chromaSize); + + //flush_dcache_all(); + flush_dcache_range((unsigned long)pRefYuv, (unsigned long)pRefYuv + lumaSize + chromaSize + chromaSize); + + return 0; +} + +int jpeg_decode_helper(DecConfigParam *param) +{ + JpgDecHandle handle = {0}; + JpgDecOpenParam decOP = {0}; + JpgDecInitialInfo initialInfo = {0}; + JpgDecOutputInfo outputInfo = {0}; + JpgDecParam decParam = {0}; + JpgRet ret = JPG_RET_SUCCESS; + FrameBuffer frameBuf[NUM_FRAME_BUF]; + jpu_buffer_t vbStream = {0}; + BufInfo bufInfo = {0}; + FRAME_BUF * pFrame[NUM_FRAME_BUF]; + Uint32 framebufWidth = 0, framebufHeight = 0; + Uint32 framebufStrideY = 0, framebufStrideC = 0; + Uint32 framebufFormat = FORMAT_420; + int dispWidth = 0, dispHeight = 0; + int i = 0, frameIdx = 0, ppIdx = 0, saveIdx = 0, totalNumofErrMbs = 0, streameos = 0, dispImage = 0; + int suc = 1; + Uint8 *pRefYuvBuf = NULL; + int needFrameBufCount = 0, regFrameBufCount = 0; + int rotEnable = 0; + int int_reason = 0; + int instIdx; + int partPosIdx = 0; + int partBufIdx = 0; + int partMaxIdx = 0; + int partialHeight = 0; + int jpeg_done = 0; + + DecConfigParam decConfig; + + memcpy(&decConfig, param, sizeof(DecConfigParam)); + memset(&pFrame, 0x00, sizeof(FRAME_BUF *) * NUM_FRAME_BUF); + memset(&frameBuf, 0x00, sizeof(FrameBuffer) * NUM_FRAME_BUF); + + instIdx = decConfig.instNum; + if (decConfig.usePartialMode && decConfig.roiEnable) { + JLOG(ERR, "Invalid operation mode : partial and ROI mode can not be worked\n"); + goto ERR_DEC_INIT; + } + + if (decConfig.packedFormat && decConfig.roiEnable) { + JLOG(ERR, "Invalid operation mode : packed mode and ROI mode can not be worked\n"); + goto ERR_DEC_INIT; + } + + if ((decConfig.iHorScaleMode || decConfig.iVerScaleMode) && decConfig.roiEnable) { + JLOG(ERR, "Invalid operation mode : Scaler mode and ROI mode can not be worked\n"); + goto ERR_DEC_INIT; + } + + if (decConfig.useRot && decConfig.roiEnable) { + JLOG(ERR, "Invalid operation mode : Rotator mode and ROI mode can not be worked\n"); + goto ERR_DEC_INIT; + } + + if (!decConfig.yuvFileName) + dispImage = 0; + else + dispImage = 1; + + decConfig.comparatorFlag = param->comparatorFlag; + + pRefYuvBuf = (Uint8 *)decConfig.yuv_addr; + bufInfo.buf = (Uint8 *)decConfig.bs_addr; + bufInfo.size = decConfig.size; + bufInfo.point = 0; + + ret = JPU_Init(); + + if (ret != JPG_RET_SUCCESS && ret != JPG_RET_CALLED_BEFORE) { + suc = 0; + JLOG(ERR, "JPU_Init failed Error code is 0x%x\n", ret); + goto ERR_DEC_INIT; + } + + // Open an instance and get initial information for decoding. + + vbStream.size = STREAM_BUF_SIZE; + if (jdi_allocate_dma_memory(&vbStream) < 0) { + JLOG(ERR, "fail to allocate bitstream buffer\n"); + goto ERR_DEC_INIT; + } + + decOP.streamEndian = decConfig.StreamEndian; + decOP.frameEndian = decConfig.FrameEndian; + decOP.chroma_interleave = (CbCrInterLeave)decConfig.chroma_interleave; + decOP.bitstreamBuffer = vbStream.phys_addr; + decOP.bitstreamBufferSize = vbStream.size; + decOP.pBitStream = (BYTE *)vbStream.virt_addr; // set virtual address mapped of physical address + decOP.packedFormat = decConfig.packedFormat; + decOP.roiEnable = decConfig.roiEnable; + decOP.roiOffsetX = decConfig.roiOffsetX; + decOP.roiOffsetY = decConfig.roiOffsetY; + decOP.roiWidth = decConfig.roiWidth; + decOP.roiHeight = decConfig.roiHeight; + + decParam.scaleDownRatioWidth = decConfig.iHorScaleMode; + decParam.scaleDownRatioHeight = decConfig.iVerScaleMode; + + JLOG(INFO, "scale ratio:%d, %d\n", decParam.scaleDownRatioWidth, decParam.scaleDownRatioHeight); + + ret = JPU_DecOpen(&handle, &decOP); + + if (ret != JPG_RET_SUCCESS) { + JLOG(ERR, "JPU_DecOpen failed Error code is 0x%x\n", ret); + goto ERR_DEC_INIT; + } + + // JPU_DecGiveCommand(handle, ENABLE_LOGGING, NULL); + + if (decConfig.useRot) + rotEnable = 1; + else + rotEnable = 0; + + ret = WriteJpgBsBufHelper(handle, &bufInfo, decOP.bitstreamBuffer, + decOP.bitstreamBuffer + decOP.bitstreamBufferSize, + 0, 0, &streameos, decOP.streamEndian); + + //flush_dcache_all(); + flush_dcache_range(decOP.bitstreamBuffer, decOP.bitstreamBuffer + decOP.bitstreamBufferSize); + + if (ret != JPG_RET_SUCCESS) { + suc = 0; + JLOG(ERR, "WriteBsBufHelper failed Error code is 0x%x\n", ret); + goto ERR_DEC_OPEN; + } + + ret = JPU_DecGetInitialInfo(handle, &initialInfo); + + if (ret != JPG_RET_SUCCESS) { + suc = 0; + JLOG(ERR, "JPU_DecGetInitialInfo failed Error code is 0x%x, inst=%d\n", ret, instIdx); + goto ERR_DEC_OPEN; + } + + if (decConfig.usePartialMode) { + // disable Rotator, Scaler + rotEnable = 0; + decConfig.iHorScaleMode = 0; + decConfig.iVerScaleMode = 0; + partialHeight = (initialInfo.sourceFormat == FORMAT_420 || initialInfo.sourceFormat == FORMAT_224) ? + 16 : 8; + + partMaxIdx = ((initialInfo.picHeight + 15) & ~15) / partialHeight; + + if (partMaxIdx < decConfig.partialBufNum) + decConfig.partialBufNum = partMaxIdx; + } + img_width = initialInfo.picWidth; + img_height = initialInfo.picHeight; + + JLOG(INFO, "init info width: %d, height = %d\n", initialInfo.picWidth, initialInfo.picHeight); + + if (initialInfo.sourceFormat == FORMAT_420 || initialInfo.sourceFormat == FORMAT_422) + framebufWidth = ((initialInfo.picWidth + 15) / 16) * 16; + else + framebufWidth = ((initialInfo.picWidth + 7) / 8) * 8; + + if (initialInfo.sourceFormat == FORMAT_420 || initialInfo.sourceFormat == FORMAT_224) + framebufHeight = ((initialInfo.picHeight + 15) / 16) * 16; + else + framebufHeight = ((initialInfo.picHeight + 7) / 8) * 8; + + if (decConfig.roiEnable) { + framebufWidth = initialInfo.roiFrameWidth; + framebufHeight = initialInfo.roiFrameHeight; + } + + // scaler constraint when conformance test is disable + if (framebufWidth < 128 || framebufHeight < 128) { + if (decConfig.iHorScaleMode || decConfig.iVerScaleMode) + JLOG(WARN, + "Invalid operation mode : Not supported resolution with Scaler, width=%d, height=%d\n", + framebufWidth, framebufHeight); + decConfig.iHorScaleMode = 0; + decConfig.iVerScaleMode = 0; + } + + JLOG(INFO, "* Dec InitialInfo =>\n instance #%d,\n minframeBuffercount: %u\n", + instIdx, initialInfo.minFrameBufferCount); + JLOG(INFO, "picWidth: %u\n picHeight: %u\n roiWidth: %u\n rouHeight: %u\n", + initialInfo.picWidth, initialInfo.picHeight, initialInfo.roiFrameWidth, initialInfo.roiFrameHeight); + + if (decConfig.usePartialMode) { + JLOG(INFO, "Partial Mode Enable\n "); + JLOG(INFO, "Num of Buffer for Partial : %d\n ", decConfig.partialBufNum); + JLOG(INFO, "Num of Line for Partial : %d\n ", partialHeight); + } + + framebufFormat = initialInfo.sourceFormat; + framebufWidth >>= decConfig.iHorScaleMode; + framebufHeight >>= decConfig.iVerScaleMode; + + if (decConfig.iHorScaleMode || decConfig.iVerScaleMode) { + framebufHeight = ((framebufHeight + 1) / 2) * 2; + framebufWidth = ((framebufWidth + 1) / 2) * 2; + } + + dispWidth = (decConfig.rot_angle == 90 || decConfig.rot_angle == 270) ? framebufHeight : framebufWidth; + dispHeight = (decConfig.rot_angle == 90 || decConfig.rot_angle == 270) ? framebufWidth : framebufHeight; + + if (decConfig.rot_angle == 90 || decConfig.rot_angle == 270) { + framebufStrideY = framebufHeight; + framebufHeight = framebufWidth; + framebufFormat = (framebufFormat == FORMAT_422) ? FORMAT_224 : + (framebufFormat == FORMAT_224) ? FORMAT_422 : framebufFormat; + } else { + framebufStrideY = framebufWidth; + } + + framebufStrideC = framebufStrideY / 2; + printf("framebufStrideY = %d, framebufStrideC = %d\n", framebufStrideY, framebufStrideC); + + if (decConfig.iHorScaleMode || decConfig.iVerScaleMode) + framebufStrideY = ((framebufStrideY + 15) / 16) * 16; + + if (decOP.packedFormat >= PACKED_FORMAT_422_YUYV && decOP.packedFormat <= PACKED_FORMAT_422_VYUY) { + framebufStrideY = framebufStrideY * 2; + framebufFormat = FORMAT_422; + if (decConfig.rot_angle == 90 || decConfig.rot_angle == 270) + framebufFormat = FORMAT_224; + + } else if (decOP.packedFormat == PACKED_FORMAT_444) { + framebufStrideY = framebufStrideY * 3; + framebufFormat = FORMAT_444; + } else if (decOP.packedFormat == PACKED_FORMAT_NONE) { +#ifdef ALIGN_32 + if (framebufFormat == FORMAT_420) { + framebufStrideY = ALIGN_X(framebufStrideY, 32); + framebufStrideC = ALIGN_X(framebufStrideY / 2, 32); + } +#endif + } + + JLOG(INFO, "framebufStrideY = %d, framebufHeight = %d\n", framebufStrideY, framebufHeight); + JLOG(INFO, "framebufFormat = %d, packedFormat = %d\n", framebufFormat, decOP.packedFormat); + JLOG(INFO, "display width: %d, height = %d\n", dispWidth, dispHeight); + + // Allocate frame buffer + regFrameBufCount = initialInfo.minFrameBufferCount + EXTRA_FRAME_BUFFER_NUM; + + if (decConfig.usePartialMode) { + if (decConfig.partialBufNum > 4) + decConfig.partialBufNum = 4; + + regFrameBufCount *= decConfig.partialBufNum; + } + + needFrameBufCount = regFrameBufCount; + + AllocateFrameBuffer(instIdx, framebufFormat, framebufStrideY, + framebufHeight, needFrameBufCount, 0, framebufStrideC); + + JpgEnterLock(); + + for (i = 0; i < needFrameBufCount; ++i) { + pFrame[i] = GetFrameBuffer(instIdx, i); + frameBuf[i].bufY = pFrame[i]->vb_y.phys_addr; + JLOG(INFO, "frame buffer Y addr: 0x%lx\n", frameBuf[i].bufY); + frameBuf[i].bufCb = pFrame[i]->vb_cb.phys_addr; + JLOG(INFO, "frame buffer Cb addr: 0x%lx\n", frameBuf[i].bufCb); + + if (decOP.chroma_interleave == CBCR_SEPARATED) { + frameBuf[i].bufCr = pFrame[i]->vb_cr.phys_addr; + JLOG(INFO, "frame buffer Cr addr: 0x%lx\n", frameBuf[i].bufCr); + } + + if (dispImage) { + clear_frame_buffer(instIdx, i); + JLOG(INFO, "."); + } + } + + JpgLeaveLock(); + + ret = JPU_DecGiveCommand(handle, SET_JPG_USE_PARTIAL_MODE, &decConfig.usePartialMode); + if (ret != JPG_RET_SUCCESS) { + suc = 0; + JLOG(ERR, "JPU_DecGiveCommand[SET_JPG_USE_PARTIAL_MODE] failed Error code is 0x%x\n", ret); + goto ERR_DEC_OPEN; + } + + ret = JPU_DecGiveCommand(handle, SET_JPG_PARTIAL_FRAME_NUM, &decConfig.partialBufNum); + + if (ret != JPG_RET_SUCCESS) { + suc = 0; + JLOG(ERR, "JPU_DecGiveCommand[SET_JPG_PARTIAL_FRAME_NUM] failed Error code is 0x%x\n", ret); + goto ERR_DEC_OPEN; + } + + ret = JPU_DecGiveCommand(handle, SET_JPG_PARTIAL_LINE_NUM, &partialHeight); + + if (ret != JPG_RET_SUCCESS) { + suc = 0; + JLOG(ERR, "JPU_DecGiveCommand[SET_JPG_PARTIAL_LINE_NUM] failed Error code is 0x%x\n", ret); + goto ERR_DEC_OPEN; + } + + // Register frame buffers requested by the decoder. + ret = JPU_DecRegisterFrameBuffer(handle, frameBuf, regFrameBufCount, framebufStrideY, framebufStrideC); + if (ret != JPG_RET_SUCCESS) { + suc = 0; + JLOG(ERR, "JPU_DecRegisterFrameBuffer failed Error code is 0x%x\n", ret); + goto ERR_DEC_OPEN; + } + + ppIdx = 0; + + while (1) { +#ifdef TEST_JPEG_PERFORMANCE + u64 now = timer_get_tick(); // get_timer(0); + u64 time_consume = 0; +#endif + if (rotEnable) { + JPU_DecGiveCommand(handle, SET_JPG_ROTATION_ANGLE, &decConfig.rot_angle); + JPU_DecGiveCommand(handle, SET_JPG_MIRROR_DIRECTION, &decConfig.mirDir); + JPU_DecGiveCommand(handle, SET_JPG_ROTATOR_OUTPUT, &frameBuf[ppIdx]); + JPU_DecGiveCommand(handle, SET_JPG_ROTATOR_STRIDE, &framebufStrideY); + JPU_DecGiveCommand(handle, ENABLE_JPG_ROTATION, 0); + JPU_DecGiveCommand(handle, ENABLE_JPG_MIRRORING, 0); + } + + JPU_DecGiveCommand(handle, SET_JPG_SCALE_HOR, &decConfig.iHorScaleMode); + JPU_DecGiveCommand(handle, SET_JPG_SCALE_VER, &decConfig.iVerScaleMode); + + if (decConfig.usePartialMode) { + partPosIdx = 0; + partBufIdx = 0; + outputInfo.decodingSuccess = 0; + JPU_SWReset(); + } + + // Start decoding a frame. + ret = JPU_DecStartOneFrame(handle, &decParam); + + if (ret != JPG_RET_SUCCESS && ret != JPG_RET_EOS) { + if (ret == JPG_RET_BIT_EMPTY) { + ret = WriteJpgBsBufHelper(handle, &bufInfo, decOP.bitstreamBuffer, + decOP.bitstreamBuffer + decOP.bitstreamBufferSize, + STREAM_FILL_SIZE, 0, &streameos, decOP.streamEndian); + + if (ret != JPG_RET_SUCCESS) { + suc = 0; + JLOG(ERR, "WriteBsBufHelper failed Error code is 0x%x\n", ret); + goto ERR_DEC_OPEN; + } + continue; + } + + suc = 0; + JLOG(ERR, "JPU_DecStartOneFrame failed Error code is 0x%x\n", ret); + goto ERR_DEC_OPEN; + } + + if (ret == JPG_RET_EOS) + goto JPU_END_OF_STREAM; + + while (1) { + int_reason = JPU_WaitInterrupt(JPU_INTERRUPT_TIMEOUT_MS); + + if (int_reason == -1) { + JLOG(ERR, "Error : timeout happened\n"); + JPU_SWReset(); + break; + } + + if (decConfig.usePartialMode && (int_reason & 0xf0)) { + partBufIdx = ((partPosIdx) % decConfig.partialBufNum); + + if ((1 << partBufIdx) & ((int_reason & 0xf0) >> 4)) { + printf("DECODED : PARTIAL BUFFER IDX %d / POS %d / MAX POS %d / INT_REASON=0x%x\n", + partBufIdx, partPosIdx + 1, partMaxIdx, int_reason); + + if (dispImage) { +// p_disp_frame = FindFrameBuffer(instIdx, +// frameBuf[partBufIdx].bufY); +#ifdef JPU_FPGA_PLATFORM + set_mixer_dec_out_frame(p_disp_frame, framebufStrideY, partialHeight); +#endif + } + + partPosIdx++; + JPU_ClrStatus((1 << (INT_JPU_PARIAL_BUF0_EMPTY + partBufIdx))); + + continue; + } else { + suc = 0; + JLOG(ERR, + "Invalid partial interrupt : expected reason =0x%x, actual reason=0x%x\n", + (1 << partBufIdx), ((int_reason & 0xF0) >> 4)); + goto ERR_DEC_OPEN; + } + } + + if (int_reason & (1 << INT_JPU_DONE)) { + // Must catch PIC_DONE interrupt before catching EMPTY interrupt + // Do no clear INT_JPU_DONE and INT_JPU_ERROR interrupt. + // these will be cleared in JPU_DecGetOutputInfo. + JLOG(INFO, "jpeg done\n"); + jpeg_done = 1; + break; + } + + if (int_reason & (1 << INT_JPU_ERROR)) { + // Must catch PIC_DONE interrupt before catching EMPTY interrupt + // Do no clear INT_JPU_DONE and INT_JPU_ERROR interrupt. + // these will be cleared in JPU_DecGetOutputInfo. + break; + } + + if (int_reason & (1 << INT_JPU_BIT_BUF_EMPTY)) { + ret = WriteJpgBsBufHelper(handle, &bufInfo, decOP.bitstreamBuffer, + decOP.bitstreamBuffer + decOP.bitstreamBufferSize, + STREAM_FILL_SIZE, 0, &streameos, decOP.streamEndian); + printf("write buffer in empty intterupt!\n\n"); + if (ret != JPG_RET_SUCCESS) { + suc = 0; + JLOG(ERR, + "WriteBsBufHelper failed Error code is 0x%x\n", + ret); + goto ERR_DEC_OPEN; + } + JPU_ClrStatus((1 << INT_JPU_BIT_BUF_EMPTY)); + } + + if (int_reason & (1 << INT_JPU_BIT_BUF_STOP)) { + ret = JPU_DecCompleteStop(handle); + if (ret != JPG_RET_SUCCESS) { + suc = 0; + JLOG(ERR, "JPU_DecCompleteStop failed Error code is 0x%x\n", ret); + goto ERR_DEC_OPEN; + } + JPU_ClrStatus((1 << INT_JPU_BIT_BUF_STOP)); + break; + } + + if (int_reason & (1 << INT_JPU_PARIAL_OVERFLOW)) + JPU_ClrStatus((1 << INT_JPU_PARIAL_OVERFLOW)); + } + +JPU_END_OF_STREAM: + ret = JPU_DecGetOutputInfo(handle, &outputInfo); + + if (ret != JPG_RET_SUCCESS) { + suc = 0; + JLOG(ERR, "JPU_DecGetOutputInfo failed Error code is 0x%x\n", ret); + goto ERR_DEC_OPEN; + } + +#ifdef TEST_JPEG_PERFORMANCE + time_consume = timer_get_tick(); + JLOG(INFO, "time_consume: %ld\n", (time_consume - now) / TIMER_CNT_US); +#endif + +#ifdef MJPEG_ERROR_CONCEAL + if (outputInfo.numOfErrMBs) { + int err_rst_idx, errPosX, errPosY; + + err_rst_idx = (outputInfo.numOfErrMBs & 0x0F000000) >> 24; + errPosX = (outputInfo.numOfErrMBs & 0x00FFF000) >> 12; + errPosY = (outputInfo.numOfErrMBs & 0x00000FFF); + JLOG(ERR, + "Error restart Idx : %d, MCU x:%d, y:%d, in Frame : %d\n", + err_rst_idx, errPosX, errPosY, frameIdx); + continue; + } +#endif + + if (outputInfo.decodingSuccess == 0) + JLOG(ERR, "JPU_DecGetOutputInfo decode fail framdIdx %d\n", frameIdx); + + JLOG(INFO, + "#%d:%d, indexFrameDisplay %d || consumedByte %d || ppIdx %d || frameStart=0x%x || ecsStart=0x%x\n", + instIdx, frameIdx, outputInfo.indexFrameDisplay, outputInfo.consumedByte, + ppIdx, outputInfo.bytePosFrameStart, outputInfo.bytePosFrameStart + outputInfo.ecsPtr); + + JLOG(INFO, "rdPtr=0x%x || wrPtr=0x%x || pos=%d\n", + JpuReadReg(MJPEG_BBC_RD_PTR_REG), + JpuReadReg(MJPEG_BBC_WR_PTR_REG), + JpuReadReg(MJPEG_BBC_CUR_POS_REG)); + + if (outputInfo.indexFrameDisplay == -1) + break; + + // YUV Dump Done when partial buffer is all displayed. + int_reason = JPU_GetStatus(); + + if (decConfig.usePartialMode && !(int_reason & 0xF0)) + goto SKIP_BUF_DUMP; + + // indexFrameDisplay points to the frame buffer, among ones + // registered, which holds the output of the decoder. + if (dispImage) { +#ifdef JPU_FPGA_PLATFORM + if (frameIdx) + wait_mixer_int(); +#endif + if (!rotEnable) { +#ifdef JPU_FPGA_PLATFORM + set_mixer_dec_out_frame(p_disp_frame, outputInfo.decPicWidth, outputInfo.decPicHeight); +#endif + } else { +#ifdef JPU_FPGA_PLATFORM + set_mixer_dec_out_frame(p_disp_frame, + (decConfig.rot_angle == 90 || decConfig.rot_angle == 270) + ? outputInfo.decPicHeight : outputInfo.decPicWidth, + (decConfig.rot_angle == 90 || decConfig.rot_angle == 270) + ? outputInfo.decPicWidth : outputInfo.decPicHeight); +#endif + + ppIdx = (ppIdx - regFrameBufCount + 1) % MAX_ROT_BUF_NUM; + } + } else if (decConfig.comparatorFlag != 0) { + JLOG(INFO, "compare yuv, frameBuf[%d].bufY = 0x%lx\n", saveIdx, frameBuf[saveIdx].bufY); + JLOG(INFO, "width:%d, height:%d\n", dispWidth, dispHeight); + + saveIdx = ppIdx; + if (comparateYuv((Uint8 *)frameBuf[saveIdx].bufY, pRefYuvBuf, + dispWidth, dispHeight, framebufStrideY, (int)decOP.chroma_interleave, + framebufFormat, 0, decOP.packedFormat) != 0) { + suc = 0; + } + + JLOG(INFO, "compare result: %d\n", 1 - suc); + + if (suc) + JLOG(ERR, "compare pass\n"); + + ppIdx = (ppIdx - regFrameBufCount + 1) % MAX_ROT_BUF_NUM; + } + + copy_to_dest_addr((Uint8 *)frameBuf[saveIdx].bufY, pRefYuvBuf, + dispWidth, dispHeight, framebufStrideY, framebufStrideC, + (int)decOP.chroma_interleave, framebufFormat, 0, decOP.packedFormat); + +SKIP_BUF_DUMP: + if (outputInfo.numOfErrMBs) { + int err_rst_idx, errPosX, errPosY; + + err_rst_idx = (outputInfo.numOfErrMBs & 0x0F000000) >> 24; + errPosX = (outputInfo.numOfErrMBs & 0x00FFF000) >> 12; + errPosY = (outputInfo.numOfErrMBs & 0x00000FFF); + JLOG(ERR, + "Error restart Idx : %d, MCU x:%d, y:%d, in Frame : %d\n", + err_rst_idx, errPosX, errPosY, frameIdx); + } + frameIdx++; + + if (decConfig.outNum && frameIdx == decConfig.outNum) + break; + } + + if (totalNumofErrMbs) { + suc = 0; + JLOG(ERR, "Total Num of Error MBs : %d\n", totalNumofErrMbs); + } + +ERR_DEC_OPEN: + // Now that we are done with decoding, close the open instance. + ret = JPU_DecClose(handle); + + JLOG(INFO, "Dec End. Tot Frame %d\n", frameIdx); + +ERR_DEC_INIT: + free_frame_buffer(instIdx); + + jdi_free_dma_memory(&vbStream); + + JPU_DeInit(); + + if (jpeg_done == 1) { + JLOG(INFO, "decode test done\n"); + } + + return suc; +} + +int get_jpeg_size(int *width_addr, int *height_addr) +{ + *width_addr = img_width; + *height_addr = img_height; + + return 0; +} + diff --git a/u-boot-2021.10/drivers/jpeg/jpurun.h b/u-boot-2021.10/drivers/jpeg/jpurun.h new file mode 100644 index 000000000..247276a4d --- /dev/null +++ b/u-boot-2021.10/drivers/jpeg/jpurun.h @@ -0,0 +1,114 @@ +#ifndef _JPU_RUN_H_ +#define _JPU_RUN_H_ +#include "jpuconfig.h" + +#define MAX_FILE_PATH 256 + +typedef struct { + unsigned char *buf; + int size; + int point; + int count; + int fillendbs; +} BufInfo; + +typedef struct { + char *yuvFileName; + char *bitstreamFileName; + char *huffFileName; + char *qMatFileName; + char *qpFileName; + char *cfgFileName; + int picWidth; + int picHeight; + int rot_angle; + int mirDir; + int useRot; + int mjpgChromaFormat; + int outNum; + int instNum; + int roiEnable; + + int StreamEndian; + int FrameEndian; + int chroma_interleave; + int bEnStuffByte; + + // altek requirement + int encHeaderMode; + + char *strStmDir; + char *strCfgDir; + int usePartialMode; + int partialBufNum; + int partialHeight; + int packedFormat; + int RandRotMode; + int compareJpg; +} EncConfigParam; + +typedef struct { + char *yuvFileName; + char *bitstreamFileName; + int comparatorFlag; + int rot_angle; + int mirDir; + int useRot; + int outNum; + int checkeos; + int instNum; + int StreamEndian; + int FrameEndian; + int chroma_interleave; + int iHorScaleMode; + int iVerScaleMode; + + // ROI + int roiEnable; + int roiWidth; + int roiHeight; + int roiOffsetX; + int roiOffsetY; + int roiWidthInMcu; + int roiHeightInMcu; + int roiOffsetXInMcu; + int roiOffsetYInMcu; + + // packed + int packedFormat; + + int usePartialMode; + int partialBufNum; + + int partialHeight; + int filePlay; + + int size; + void *bs_addr; + void *yuv_addr; +} DecConfigParam; + +enum { STD_JPG_ENC }; + +typedef struct { + int codecMode; + int numMulti; + int saveYuv; + int multiMode[MAX_NUM_INSTANCE]; + char *multiFileName[MAX_NUM_INSTANCE]; + char *multiYuvFileName[MAX_NUM_INSTANCE]; + EncConfigParam encConfig[MAX_NUM_INSTANCE]; + DecConfigParam decConfig[MAX_NUM_INSTANCE]; +} MultiConfigParam; + +#if defined(__cplusplus) +extern "C" { +#endif +int jpeg_decode_helper(DecConfigParam *param); +int EncodeTest(EncConfigParam *param); +int MultiInstanceTest(MultiConfigParam *param); +int get_jpeg_size(int *width_addr, int *height_addr); +#if defined(__cplusplus) +} +#endif +#endif /* _JPU_RUN_H_ */ diff --git a/u-boot-2021.10/drivers/jpeg/jputable.h b/u-boot-2021.10/drivers/jpeg/jputable.h new file mode 100644 index 000000000..cb174093c --- /dev/null +++ b/u-boot-2021.10/drivers/jpeg/jputable.h @@ -0,0 +1,125 @@ +#ifndef _JPU_TABLE_H_ +#define _JPU_TABLE_H_ + +static unsigned char lumaDcBits[16] = { + 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static unsigned char lumaDcValue[16] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x00, 0x00, 0x00, 0x00, +}; + +static unsigned char lumaAcBits[16] = { + 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, + 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, +}; + +static unsigned char lumaAcValue[168] = { + 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, + 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, + 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24, 0x33, 0x62, 0x72, + 0x82, 0x09, 0x0A, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, + 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, + 0x76, 0x77, 0x78, 0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, + 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, + 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, + 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, + 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, + 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static unsigned char chromaDcBits[16] = { + 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static unsigned char chromaDcValue[16] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x00, 0x00, 0x00, 0x00, +}; + +static unsigned char chromaAcBits[16] = { + 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, + 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, +}; + +static unsigned char chromaAcValue[168] = { + 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, + 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, + 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, + 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, + 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, + 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, + 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, + 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, + 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, + 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, + 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +#ifdef NOT_USED +static unsigned char lumaQ[64] = { + 0x0C, 0x08, 0x08, 0x08, 0x09, 0x08, 0x0C, 0x09, 0x09, 0x0C, 0x11, + 0x0B, 0x0A, 0x0B, 0x11, 0x15, 0x0F, 0x0C, 0x0C, 0x0F, 0x15, 0x18, + 0x13, 0x13, 0x15, 0x13, 0x13, 0x18, 0x11, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x11, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, +}; + +static unsigned char chromaBQ[64] = { + 0x0D, 0x0B, 0x0B, 0x0D, 0x0E, 0x0D, 0x10, 0x0E, 0x0E, 0x10, 0x14, + 0x0E, 0x0E, 0x0E, 0x14, 0x14, 0x0E, 0x0E, 0x0E, 0x0E, 0x14, 0x11, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x11, 0x11, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x11, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, +}; + +static unsigned char chromaRQ[64] = { + 0x0D, 0x0B, 0x0B, 0x0D, 0x0E, 0x0D, 0x10, 0x0E, 0x0E, 0x10, 0x14, + 0x0E, 0x0E, 0x0E, 0x14, 0x14, 0x0E, 0x0E, 0x0E, 0x0E, 0x14, 0x11, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x11, 0x11, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x11, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, +}; +#endif +static unsigned char lumaQ2[64] = { + 0x06, 0x04, 0x04, 0x04, 0x05, 0x04, 0x06, 0x05, 0x05, 0x06, 0x09, + 0x06, 0x05, 0x06, 0x09, 0x0B, 0x08, 0x06, 0x06, 0x08, 0x0B, 0x0C, + 0x0A, 0x0A, 0x0B, 0x0A, 0x0A, 0x0C, 0x10, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x10, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, +}; + +static unsigned char chromaBQ2[64] = { + 0x07, 0x07, 0x07, 0x0D, 0x0C, 0x0D, 0x18, 0x10, 0x10, 0x18, 0x14, + 0x0E, 0x0E, 0x0E, 0x14, 0x14, 0x0E, 0x0E, 0x0E, 0x0E, 0x14, 0x11, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x11, 0x11, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x11, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, +}; + +#ifdef NOT_USED +static unsigned char chromaRQ2[64] = { + 0x07, 0x07, 0x07, 0x0D, 0x0C, 0x0D, 0x18, 0x10, 0x10, 0x18, 0x14, + 0x0E, 0x0E, 0x0E, 0x14, 0x14, 0x0E, 0x0E, 0x0E, 0x0E, 0x14, 0x11, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x11, 0x11, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x11, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, +}; +#endif + +#endif //_JPU_TABLE_H_ \ No newline at end of file diff --git a/u-boot-2021.10/drivers/jpeg/jputypes.h b/u-boot-2021.10/drivers/jpeg/jputypes.h new file mode 100644 index 000000000..bdcf8fb0d --- /dev/null +++ b/u-boot-2021.10/drivers/jpeg/jputypes.h @@ -0,0 +1,62 @@ + +#ifndef _JPU_TYPES_H_ +#define _JPU_TYPES_H_ + +typedef unsigned int UINT; +typedef unsigned char Uint8; +typedef unsigned int Uint32; +typedef unsigned short Uint16; +typedef char Int8; +typedef int Int32; +typedef short Int16; +#if defined(_MSC_VER) +typedef unsigned _int64 Uint64; +typedef _int64 Int64; +#else +typedef unsigned long Uint64; +typedef long Int64; +#endif +typedef Uint64 PhysicalAddress; +typedef unsigned char BYTE; +typedef int BOOL; + +#ifndef HAVE_STDIN_H + +typedef unsigned char uint8_t; +typedef unsigned int uint32_t; +typedef int int32_t; +typedef unsigned short uint16_t; +typedef short int16_t; +#if defined(_MSC_VER) +typedef unsigned _int64 uint64_t; +typedef _int64 int64_t; +#else +#endif + +#ifndef __int8_t_defined +typedef signed char int8_t; +#endif + +typedef int int32_t; +typedef short int16_t; + +#ifndef BYTE +typedef unsigned char BYTE; +#endif + +#ifndef BOOL +typedef int BOOL; +#endif + +#endif + +#ifndef NULL +#define NULL 0 +#endif + +#if defined(linux) || defined(__linux) || defined(ANDROID) +#define TRUE 1 +#define FALSE 0 +#endif + +#endif /* _JPU_TYPES_H_ */ diff --git a/u-boot-2021.10/drivers/jpeg/mixer.c b/u-boot-2021.10/drivers/jpeg/mixer.c new file mode 100644 index 000000000..d1a91ee17 --- /dev/null +++ b/u-boot-2021.10/drivers/jpeg/mixer.c @@ -0,0 +1,373 @@ +//#include +#include "jpuapi.h" +#include "jpuhelper.h" +#include "jpulog.h" +#include "mixer.h" +#include "regdefine.h" +#include +#include + +typedef struct { + FRAME_BUF frameBuf[MAX_FRAME]; + jpu_buffer_t vb_base; + int instIndex; + int last_num; + unsigned long last_addr; +} fb_context; + +static fb_context s_fb[MAX_NUM_INSTANCE]; + +int AllocateFrameBuffer(int instIdx, int format, int strideY, int height, + int frameBufNum, int pack, int strideC) +{ + unsigned int divX, divY; + int i; + unsigned int lum_size, chr_size; + fb_context *fb; + + fb = &s_fb[instIdx]; + + divX = format == FORMAT_420 || format == FORMAT_422 ? 2 : 1; + divY = format == FORMAT_420 || format == FORMAT_224 ? 2 : 1; + + switch (format) { + case FORMAT_420: + height = (height + 1) / 2 * 2; + strideY = (strideY + 1) / 2 * 2; + break; + case FORMAT_224: + height = (height + 1) / 2 * 2; + break; + case FORMAT_422: + strideY = (strideY + 1) / 2 * 2; + break; + case FORMAT_444: + height = (height + 1) / 2 * 2; + strideY = (strideY + 1) / 2 * 2; + break; + case FORMAT_400: + height = (height + 1) / 2 * 2; + strideY = (strideY + 1) / 2 * 2; + break; + } + + lum_size = (unsigned int)strideY * (unsigned int)height; + + if (pack) + chr_size = 0; + else { + if (format == FORMAT_420) + chr_size = strideC * height / divY; + else + chr_size = lum_size / divX / divY; + } + + fb->vb_base.size = lum_size + chr_size * 2; + fb->vb_base.size *= frameBufNum; + + if (jdi_allocate_dma_memory(&fb->vb_base) < 0) { + JLOG(ERR, "Fail to allocate frame buffer size=%d\n", fb->vb_base.size); + return 0; + } + + fb->last_addr = fb->vb_base.phys_addr; + + for (i = fb->last_num; i < fb->last_num + frameBufNum; i++) { + fb->frameBuf[i].Format = format; + fb->frameBuf[i].Index = i; + + fb->frameBuf[i].vb_y.phys_addr = fb->last_addr; + fb->frameBuf[i].vb_y.size = lum_size; + + fb->last_addr += fb->frameBuf[i].vb_y.size; + fb->last_addr = ((fb->last_addr + 7) & ~7); + + if (chr_size) { + fb->frameBuf[i].vb_cb.phys_addr = fb->last_addr; + fb->frameBuf[i].vb_cb.size = chr_size; + + fb->last_addr += fb->frameBuf[i].vb_cb.size; + fb->last_addr = ((fb->last_addr + 7) & ~7); + + fb->frameBuf[i].vb_cr.phys_addr = fb->last_addr; + fb->frameBuf[i].vb_cr.size = chr_size; + + fb->last_addr += fb->frameBuf[i].vb_cr.size; + fb->last_addr = ((fb->last_addr + 7) & ~7); + } + + fb->frameBuf[i].strideY = strideY; + if (format == FORMAT_420) + fb->frameBuf[i].strideC = strideC; + else + fb->frameBuf[i].strideC = strideY / divX; + } + + fb->last_num += frameBufNum; + + return 1; +} + +int GetFrameBufBase(int instIdx) +{ + fb_context *fb; + + fb = &s_fb[instIdx]; + + return fb->vb_base.phys_addr; +} + +int GetFrameBufAllocSize(int instIdx) +{ + fb_context *fb; + + fb = &s_fb[instIdx]; + + return (fb->last_addr - fb->vb_base.phys_addr); +} + +FRAME_BUF *GetFrameBuffer(int instIdx, int index) +{ + fb_context *fb; + + fb = &s_fb[instIdx]; + return &fb->frameBuf[index]; +} + +FRAME_BUF *find_frame_buffer(int instIdx, PhysicalAddress addrY) +{ + int i; + fb_context *fb; + + fb = &s_fb[instIdx]; + + for (i = 0; i < MAX_FRAME; i++) { + if (fb->frameBuf[i].vb_y.phys_addr == addrY) { + return &fb->frameBuf[i]; + } + } + + return NULL; +} + +void clear_frame_buffer(int instIdx, int index) +{ +} + +void free_frame_buffer(int instIdx) +{ + fb_context *fb; + + fb = &s_fb[instIdx]; + + fb->last_num = 0; + fb->last_addr = -1; + + jdi_free_dma_memory(&fb->vb_base); + fb->vb_base.base = 0; + fb->vb_base.size = 0; +} + +#ifdef JPU_FPGA_PLATFORM +//------------------------------------------------------------------------------ +// MIXER REGISTER ADDRESS +//------------------------------------------------------------------------------ +#define MIX_BASE 0x1000000 +#define DISP_MIX 0x2000000 + +#define MIX_INT (MIX_BASE + 0x044) + +#define MIX_STRIDE_Y (MIX_BASE + 0x144) +#define MIX_STRIDE_CB (MIX_BASE + 0x148) +#define MIX_STRIDE_CR (MIX_BASE + 0x14c) + +#define MIX_ADDR_Y (MIX_BASE + 0x138) +#define MIX_ADDR_CB (MIX_BASE + 0x13C) +#define MIX_ADDR_CR (MIX_BASE + 0x140) + +#define MIX_RUN (MIX_BASE + 0x120) + +#define DISP_TOTAL_SAMPLE (DISP_MIX + 0x00C) +#define DISP_ACTIVE_SAMPLE (DISP_MIX + 0x010) +#define DISP_HSYNC_START_END (DISP_MIX + 0x014) +#define DISP_VSYNC_TOP_START (DISP_MIX + 0x018) +#define DISP_VSYNC_TOP_END (DISP_MIX + 0x01C) +#define DISP_VSYNC_BOT_START (DISP_MIX + 0x020) +#define DISP_VSYNC_BOT_END (DISP_MIX + 0x024) +#define DISP_ACTIVE_REGION_TOP (DISP_MIX + 0x02C) +#define DISP_ACTIVE_REGION_BOT (DISP_MIX + 0x030) + +#define MIX_MIX_INTRPT (MIX_BASE + 0x0000) +#define MIX_SYNC_STATE (MIX_BASE + 0x0004) +#define MIX_SYNC_CTRL (MIX_BASE + 0x0008) +#define MIX_TOTAL_SAMPLE (MIX_BASE + 0x000c) +#define MIX_ACTIVE_SAMPLE (MIX_BASE + 0x0010) +#define MIX_HSYNC_START_END (MIX_BASE + 0x0014) +#define MIX_VSYNC_TOP_START (MIX_BASE + 0x0018) +#define MIX_VSYNC_TOP_END (MIX_BASE + 0x001c) +#define MIX_VSYNC_BOT_START (MIX_BASE + 0x0020) +#define MIX_VSYNC_BOT_END (MIX_BASE + 0x0024) +#define MIX_ACT_REGION_SAMPLE (MIX_BASE + 0x0028) +#define MIX_ACT_REGION_TOP (MIX_BASE + 0x002c) +#define MIX_ACT_REGION_BOT (MIX_BASE + 0x0030) +#define MIX_TOP_START (MIX_BASE + 0x0034) +#define MIX_BOT_START (MIX_BASE + 0x0038) +#define MIX_LINE_INC (MIX_BASE + 0x003c) +#define MIX_LATCH_PARAM_CTRL (MIX_BASE + 0x0040) +#define MIX_INTERRUPT (MIX_BASE + 0x0044) + +#define MIX_LAYER_CTRL (MIX_BASE + 0x0100) +#define MIX_LAYER_ORDER (MIX_BASE + 0x0104) +#define MIX_BIG_ENDIAN (MIX_BASE + 0x0108) +#define MIX_L0_BG_COLOR (MIX_BASE + 0x0110) +#define MIX_L1_CTRL (MIX_BASE + 0x0120) +#define MIX_L1_LSIZE (MIX_BASE + 0x0124) +#define MIX_L1_SSIZE (MIX_BASE + 0x0128) +#define MIX_L1_LPOS (MIX_BASE + 0x012c) +#define MIX_L1_SPOS (MIX_BASE + 0x0130) +#define MIX_L1_BG_COLOR (MIX_BASE + 0x0134) +#define MIX_L1_Y_SADDR (MIX_BASE + 0x0138) +#define MIX_L1_CB_SADDR (MIX_BASE + 0x013c) +#define MIX_L1_CR_SADDR (MIX_BASE + 0x0140) +#define MIX_L1_Y_STRIDE (MIX_BASE + 0x0144) +#define MIX_L1_CB_STRIDE (MIX_BASE + 0x0148) +#define MIX_L1_CR_STRIDE (MIX_BASE + 0x014c) + +int SetMixerDecOutFrame(FRAME_BUF *pFrame, int width, int height) +{ + int staX, staY; + int div; + + staX = (MAX_DISPLAY_WIDTH - width) / 2; + if (height > MAX_DISPLAY_HEIGHT) + staY = 0; + else + staY = (MAX_DISPLAY_HEIGHT - height) / 2; + if (staX % 16) + staX = (staX + 15) / 16 * 16; + + JpuWriteReg(MIX_L0_BG_COLOR, (0 << 16) | (0x80 << 8) | 0x80); + + JpuWriteReg(MIX_L1_LSIZE, (height << 12) | width); + JpuWriteReg(MIX_L1_SSIZE, (height << 12) | width); + JpuWriteReg(MIX_L1_LPOS, (staY << 12) | staX); + + div = (pFrame->Format == FORMAT_420 || pFrame->Format == FORMAT_422 || + pFrame->Format == FORMAT_400) + ? 2 + : 1; + + JpuWriteReg(MIX_STRIDE_Y, width); + JpuWriteReg(MIX_STRIDE_CB, width / div); + JpuWriteReg(MIX_STRIDE_CR, width / div); + + JpuWriteReg(MIX_ADDR_Y, pFrame->vb_y.phys_addr); + JpuWriteReg(MIX_ADDR_CB, pFrame->vb_cb.phys_addr); + JpuWriteReg(MIX_ADDR_CR, pFrame->vb_cr.phys_addr); + + JpuWriteReg(DISP_HSYNC_START_END, + ((0x7d7 - 40) << 12) | (0x82f - 40)); // horizontal center + JpuWriteReg(DISP_ACTIVE_REGION_TOP, ((0x014 - 2) << 12) | (0x230 - 2)); + JpuWriteReg(DISP_ACTIVE_REGION_BOT, ((0x247 - 2) << 12) | (0x463 - 2)); + + JpuWriteReg(MIX_LAYER_CTRL, 0x3); // backgroup on + JpuWriteReg(MIX_RUN, 0x92); // on, vdec, from sdram + + return 1; +} + +int SetMixerDecOutLayer(int instIdx, int index, int width, int height) +{ + FRAME_BUF *pFrame; + int staX, staY; + int div; + + pFrame = GetFrameBuffer(instIdx, index); + + staX = (MAX_DISPLAY_WIDTH - width) / 2; + if (height > MAX_DISPLAY_HEIGHT) + staY = 0; + else + staY = (MAX_DISPLAY_HEIGHT - height) / 2; + if (staX % 16) + staX = (staX + 15) / 16 * 16; + + JpuWriteReg(MIX_L0_BG_COLOR, (0 << 16) | (0x80 << 8) | 0x80); + + JpuWriteReg(MIX_L1_LSIZE, (height << 12) | width); + JpuWriteReg(MIX_L1_SSIZE, (height << 12) | width); + JpuWriteReg(MIX_L1_LPOS, (staY << 12) | staX); + + div = (pFrame->Format == FORMAT_420 || pFrame->Format == FORMAT_422 || + pFrame->Format == FORMAT_400) + ? 2 + : 1; + + JpuWriteReg(MIX_STRIDE_Y, width); + JpuWriteReg(MIX_STRIDE_CB, width / div); + JpuWriteReg(MIX_STRIDE_CR, width / div); + + JpuWriteReg(MIX_ADDR_Y, pFrame->vb_y.phys_addr); + JpuWriteReg(MIX_ADDR_CB, pFrame->vb_cb.phys_addr); + JpuWriteReg(MIX_ADDR_CR, pFrame->vb_cr.phys_addr); + + JpuWriteReg(DISP_HSYNC_START_END, ((0x7d7 - 40) << 12) | (0x82f - 40)); // horizontal center + JpuWriteReg(DISP_ACTIVE_REGION_TOP, ((0x014 - 2) << 12) | (0x230 - 2)); + JpuWriteReg(DISP_ACTIVE_REGION_BOT, ((0x247 - 2) << 12) | (0x463 - 2)); + + JpuWriteReg(MIX_LAYER_CTRL, 0x3); // backgroup on + JpuWriteReg(MIX_RUN, 0x92); // on, vdec, from sdram + + return 1; +} + +void wait_mixer_int(void) +{ + int data; + + return; + + if (JpuReadReg(MIX_INT) == 1) + JpuWriteReg(MIX_INT, 0); + + while (1) { + data = JpuReadReg(MIX_INT); + if (data & 1) + break; + } + JpuWriteReg(MIX_INT, 0); +} + +#endif + +#ifdef PLATFORM_LINUX +#include +#define FBDEV_FILENAME "/dev/fb0" + +typedef struct { + int s_fd; + unsigned char *s_scr_ptr; + unsigned char *s_rgb_ptr; + unsigned long s_product; + int s_fb_stride; + int s_fb_height; + int s_fb_width; + int s_fb_bpp; +} sw_mixer_context_t; +#endif // PLATFORM_LINUX + +int sw_mixer_open(int instIdx, int width, int height) +{ + return 0; +} + +int sw_mixer_draw(int instIdx, int x, int y, int width, int height, + int planar_format, int pack_format, int interleave, + unsigned char *pbImage) +{ + return 0; +} + +void sw_mixer_close(int instIdx) +{ +} diff --git a/u-boot-2021.10/drivers/jpeg/mixer.h b/u-boot-2021.10/drivers/jpeg/mixer.h new file mode 100644 index 000000000..96663aacd --- /dev/null +++ b/u-boot-2021.10/drivers/jpeg/mixer.h @@ -0,0 +1,47 @@ + +#ifndef _MIXER_H_ +#define _MIXER_H_ + +#include "jpuconfig.h" + +typedef struct { + int Format; + int Index; + jpu_buffer_t vb_y; + jpu_buffer_t vb_cb; + jpu_buffer_t vb_cr; + int strideY; + int strideC; +} FRAME_BUF; + +#define MAX_DISPLAY_WIDTH 1920 +#define MAX_DISPLAY_HEIGHT 1088 + +#if defined(__cplusplus) +extern "C" { +#endif + +int AllocateFrameBuffer(int instIdx, int format, int strideY, int height, + int frameBufNum, int pack, int strideC); +void free_frame_buffer(int instIdx); +FRAME_BUF *GetFrameBuffer(int instIdx, int index); +int GetFrameBufBase(int instIdx); +int GetFrameBufAllocSize(int instIdx); +void clear_frame_buffer(int instIdx, int index); +FRAME_BUF *find_frame_buffer(int instIdx, PhysicalAddress addrY); +#ifdef JPU_FPGA_PLATFORM +int SetMixerDecOutLayer(int instIdx, int index, int picX, int picY); +int SetMixerDecOutFrame(FRAME_BUF *pFrame, int width, int height); +void wait_mixer_int(void); +#endif +int sw_mixer_open(int instIdx, int width, int height); +int sw_mixer_draw(int instIdx, int x, int y, int width, int height, + int planar_format, int pack_format, int inteleave, + unsigned char *pbImage); +void sw_mixer_close(int instIdx); + +#if defined(__cplusplus) +} +#endif + +#endif //#ifndef _MIXER_H_ diff --git a/u-boot-2021.10/drivers/jpeg/mm.c b/u-boot-2021.10/drivers/jpeg/mm.c new file mode 100644 index 000000000..ed3c34e5f --- /dev/null +++ b/u-boot-2021.10/drivers/jpeg/mm.c @@ -0,0 +1,582 @@ + +#include +#include "mm.h" +#include "jdi_osal.h" +#include +#include "jpulog.h" + +#define P_ALLOC(_x) OSAL_MALLOC(_x) +#define P_FREE(_x) OSAL_FREE(_x) +//#define assert(_exp) // if (!(_exp)) { osal_printf("assert at %s:%d\n", __FILE__, __LINE__); while(1); } +#define HEIGHT(_tree) (!(_tree) ? -1 : _tree->height) + +/* + * doubly linked list + */ +#define MAX(_a, _b) ((_a) >= (_b) ? (_a) : (_b)) + +enum { + LEFT, + RIGHT +} rotation_dir_t; + +struct avl_node_data { + int key; + page_t *page; +} avl_node_data_t; + +static avl_node_t *make_avl_node(vmem_key_t key, page_t *page) +{ + avl_node_t *node = (avl_node_t *) + + josal_malloc(sizeof(avl_node_t)); + + node->key = key; + node->page = page; + node->height = 0; + node->left = NULL; + node->right = NULL; + + return node; +} + +static int get_balance_factor(avl_node_t *tree) +{ + int factor = 0; + + if (tree) { + factor = HEIGHT(tree->right) - HEIGHT(tree->left); + } + + return factor; +} + +/* + * Left Rotation + * + * A B + * \ / \ + * B => A C + * / \ \ + * D C D + * + */ +static avl_node_t *rotation_left(avl_node_t *tree) +{ + avl_node_t *rchild; + avl_node_t *lchild; + + if (!tree) + return NULL; + + rchild = tree->right; + + if (!rchild) { + return tree; + } + + lchild = rchild->left; + rchild->left = tree; + tree->right = lchild; + + tree->height = MAX(HEIGHT(tree->left), HEIGHT(tree->right)) + 1; + rchild->height = MAX(HEIGHT(rchild->left), HEIGHT(rchild->right)) + 1; + + return rchild; +} + +/* + * Reft Rotation + * + * A B + * \ / \ + * B => D A + * / \ / + * D C C + * + */ +static avl_node_t *rotation_right(avl_node_t *tree) +{ + avl_node_t *rchild; + avl_node_t *lchild; + + if (!tree) + return NULL; + + lchild = tree->left; + + if (!lchild) + return NULL; + + rchild = lchild->right; + lchild->right = tree; + tree->left = rchild; + + tree->height = MAX(HEIGHT(tree->left), HEIGHT(tree->right)) + 1; + lchild->height = MAX(HEIGHT(lchild->left), HEIGHT(lchild->right)) + 1; + + return lchild; +} + +static avl_node_t *do_balance(avl_node_t *tree) +{ + int bfactor = 0, child_bfactor; /* balancing factor */ + + bfactor = get_balance_factor(tree); + + if (bfactor >= 2) { + child_bfactor = get_balance_factor(tree->right); + + if (child_bfactor == 1 || child_bfactor == 0) { + tree = rotation_left(tree); + } else if (child_bfactor == -1) { + tree->right = rotation_right(tree->right); + tree = rotation_left(tree); + } else { + //fprintf(stderr, "invalid balancing factor: %d\n", child_bfactor); + assert(0); + return NULL; + } + } else if (bfactor <= -2) { + child_bfactor = get_balance_factor(tree->left); + + if (child_bfactor == -1 || child_bfactor == 0) { + tree = rotation_right(tree); + } else if (child_bfactor == 1) { + tree->left = rotation_left(tree->left); + tree = rotation_right(tree); + } else { + //fprintf(stderr, "invalid balancing factor: %d\n", child_bfactor); + assert(0); + return NULL; + } + } + + return tree; +} + +static avl_node_t *unlink_end_node(avl_node_t *tree, int dir, avl_node_t **found_node) +{ + // avl_node_t* node; + *found_node = NULL; + + if (!tree) + return NULL; + + if (dir == LEFT) { + if (!tree->left) { + *found_node = tree; + return NULL; + } + } else { + if (!tree->right) { + *found_node = tree; + return NULL; + } + } + + if (dir == LEFT) { + // node = tree->left; + tree->left = unlink_end_node(tree->left, LEFT, found_node); + + if (!tree->left) { + tree->left = (*found_node)->right; + (*found_node)->left = NULL; + (*found_node)->right = NULL; + } + } else { + // node = tree->right; + tree->right = unlink_end_node(tree->right, RIGHT, found_node); + + if (!tree->right) { + tree->right = (*found_node)->left; + (*found_node)->left = NULL; + (*found_node)->right = NULL; + } + } + + tree->height = MAX(HEIGHT(tree->left), HEIGHT(tree->right)) + 1; + + return do_balance(tree); +} + +static avl_node_t *avltree_insert(avl_node_t *tree, vmem_key_t key, page_t *page) +{ + if (!tree) { + tree = make_avl_node(key, page); + } else { + if (key >= tree->key) { + tree->right = avltree_insert(tree->right, key, page); + } else { + tree->left = avltree_insert(tree->left, key, page); + } + } + + tree = do_balance(tree); + tree->height = MAX(HEIGHT(tree->left), HEIGHT(tree->right)) + 1; + + return tree; +} + +static avl_node_t *do_unlink(avl_node_t *tree) +{ + avl_node_t *node; + avl_node_t *end_node; + + node = unlink_end_node(tree->right, LEFT, &end_node); + + if (node) { + tree->right = node; + } else { + node = unlink_end_node(tree->left, RIGHT, &end_node); + + if (node) + tree->left = node; + } + + if (!node) { + node = tree->right ? tree->right : tree->left; + end_node = node; + } + + if (end_node) { + end_node->left = (tree->left != end_node) ? tree->left : end_node->left; + end_node->right = (tree->right != end_node) ? tree->right : end_node->right; + end_node->height = MAX(HEIGHT(end_node->left), HEIGHT(end_node->right)) + 1; + } + + tree = end_node; + + return tree; +} + +static avl_node_t *avltree_remove(avl_node_t *tree, avl_node_t **found_node, vmem_key_t key) +{ + *found_node = NULL; + + if (!tree) { + // DPRINT("failed to find key %d\n", key); + return NULL; + } + + if (key == tree->key) { + *found_node = tree; + tree = do_unlink(tree); + } else if (key > tree->key) { + tree->right = avltree_remove(tree->right, found_node, key); + } else { + tree->left = avltree_remove(tree->left, found_node, key); + } + + if (tree) + tree->height = MAX(HEIGHT(tree->left), HEIGHT(tree->right)) + 1; + + tree = do_balance(tree); + + return tree; + +} + +void jpu_avltree_free(avl_node_t *tree) +{ + if (!tree) + return; + + if (!tree->left && !tree->right) { + P_FREE(tree); + return; + } + + jpu_avltree_free(tree->left); + tree->left = NULL; + jpu_avltree_free(tree->right); + tree->right = NULL; +} + +static avl_node_t *remove_approx_value(avl_node_t *tree, avl_node_t **found, vmem_key_t key) +{ + *found = NULL; + + if (!tree) { + return NULL; + } + + if (key == tree->key) { + *found = tree; + tree = do_unlink(tree); + } else if (key > tree->key) { + tree->right = remove_approx_value(tree->right, found, key); + } else { + tree->left = remove_approx_value(tree->left, found, key); + + if (!*found) { + *found = tree; + tree = do_unlink(tree); + } + } + + if (tree) + tree->height = MAX(HEIGHT(tree->left), HEIGHT(tree->right)) + 1; + + tree = do_balance(tree); + + return tree; +} + +static void set_blocks_free(jpeg_mm_t *mm, int pageno, int npages) +{ + int last_pageno = pageno + npages - 1; + int i; + page_t *page; + page_t *last_page; + + assert(npages); + + if (last_pageno >= mm->num_pages) { + // DPRINT("set_blocks_free: invalid last page number: %d\n", last_pageno); + assert(0); + return; + } + + for (i = pageno; i <= last_pageno; i++) { + mm->page_list[i].used = 0; + mm->page_list[i].alloc_pages = 0; + mm->page_list[i].first_pageno = -1; + } + + page = &mm->page_list[pageno]; + page->alloc_pages = npages; + last_page = &mm->page_list[last_pageno]; + last_page->first_pageno = pageno; + + mm->free_tree = avltree_insert(mm->free_tree, MAKE_KEY(npages, pageno), page); +} + +static void set_blocks_alloc(jpeg_mm_t *mm, int pageno, int npages) +{ + int last_pageno = pageno + npages - 1; + int i; + page_t *page; + page_t *last_page; + + if (last_pageno >= mm->num_pages) { + // DPRINT("set_blocks_free: invalid last page number: %d\n", last_pageno); + assert(0); + return; + } + + for (i = pageno; i <= last_pageno; i++) { + mm->page_list[i].used = 1; + mm->page_list[i].alloc_pages = 0; + mm->page_list[i].first_pageno = -1; + } + + page = &mm->page_list[pageno]; + page->alloc_pages = npages; + + last_page = &mm->page_list[last_pageno]; + last_page->first_pageno = pageno; + + mm->alloc_tree = avltree_insert(mm->alloc_tree, MAKE_KEY(page->addr, 0), page); +} + +int jmem_init(jpeg_mm_t *mm, unsigned long addr, unsigned long size) +{ + int i; + + mm->base_addr = (addr + (VMEM_PAGE_SIZE - 1)) & ~(VMEM_PAGE_SIZE - 1); + mm->mem_size = size & ~VMEM_PAGE_SIZE; + mm->num_pages = mm->mem_size / VMEM_PAGE_SIZE; + mm->page_list = (page_t *) + P_ALLOC(mm->num_pages * sizeof(page_t)); + mm->free_tree = NULL; + mm->alloc_tree = NULL; + mm->free_page_count = mm->num_pages; + mm->alloc_page_count = 0; + + // printf("page list addr: 0x%llx\n", mm->page_list); + for (i = 0; i < mm->num_pages; i++) { + mm->page_list[i].pageno = i; + mm->page_list[i].addr = mm->base_addr + i * VMEM_PAGE_SIZE; + mm->page_list[i].alloc_pages = 0; + mm->page_list[i].used = 0; + mm->page_list[i].first_pageno = -1; + } + + set_blocks_free(mm, 0, mm->num_pages); + return 0; +} + +int jmem_exit(jpeg_mm_t *mm) +{ + if (!mm) { + // DPRINT("vmem_exit: invalid handle\n"); + return -1; + } + + if (mm->free_tree) { + jpu_avltree_free(mm->free_tree); + } + + if (mm->alloc_tree) { + jpu_avltree_free(mm->alloc_tree); + } + + P_FREE(mm->page_list); + + return 0; +} + +unsigned long jmem_alloc(jpeg_mm_t *mm, unsigned int size, unsigned long pid) +{ + avl_node_t *node; + page_t *free_page; + int npages, free_size; + int alloc_pageno; + unsigned long ptr; + + if (!mm) { +// DPRINT("vmem_alloc: invalid handle\n"); + return -1; + } + + if (size <= 0) + return -1; + + npages = (size + VMEM_PAGE_SIZE - 1) / VMEM_PAGE_SIZE; + + mm->free_tree = remove_approx_value(mm->free_tree, &node, MAKE_KEY(npages, 0)); + + if (!node) { + return -1; + } + + free_page = node->page; + free_size = KEY_TO_VALUE(node->key); + + alloc_pageno = free_page->pageno; + set_blocks_alloc(mm, alloc_pageno, npages); + + if (npages != free_size) { + int free_pageno = alloc_pageno + npages; + + set_blocks_free(mm, free_pageno, (free_size - npages)); + } + + P_FREE(node); + + ptr = mm->page_list[alloc_pageno].addr; + mm->alloc_page_count += npages; + mm->free_page_count -= npages; + + return ptr; +} + +int jmem_free(jpeg_mm_t *mm, unsigned long ptr, unsigned long pid) +{ + unsigned long addr; + avl_node_t *found; + page_t *page; + int pageno, prev_free_pageno, next_free_pageno; + int prev_size, next_size; + int merge_page_no, merge_page_size, free_page_size; + + if (!mm) { + // DPRINT("vmem_free: invalid handle\n"); + return -1; + } + + addr = ptr; + + mm->alloc_tree = avltree_remove(mm->alloc_tree, &found, MAKE_KEY(addr, 0)); + + if (!found) { + // DPRINT("vmem_free: 0x%08x not found\n", addr); + return -1; + } + + /* find previous free block */ + page = found->page; + pageno = page->pageno; + free_page_size = page->alloc_pages; + prev_free_pageno = pageno - 1; + prev_size = -1; + + if (prev_free_pageno >= 0) { + if (mm->page_list[prev_free_pageno].used == 0) { + prev_free_pageno = mm->page_list[prev_free_pageno].first_pageno; + prev_size = mm->page_list[prev_free_pageno].alloc_pages; + } + } + + /* find next free block */ + next_free_pageno = pageno + page->alloc_pages; + next_free_pageno = (next_free_pageno == mm->num_pages) ? -1 : next_free_pageno; + next_size = -1; + + if (next_free_pageno >= 0) { + if (mm->page_list[next_free_pageno].used == 0) { + next_size = mm->page_list[next_free_pageno].alloc_pages; + } + } + + P_FREE(found); + + /* merge */ + merge_page_no = page->pageno; + merge_page_size = page->alloc_pages; + + if (prev_size >= 0) { + mm->free_tree = avltree_remove(mm->free_tree, &found, MAKE_KEY(prev_size, prev_free_pageno)); + + if (!found) { + assert(0); + return -1; + } + + merge_page_no = found->page->pageno; + merge_page_size += found->page->alloc_pages; + P_FREE(found); + } + + if (next_size >= 0) { + mm->free_tree = avltree_remove(mm->free_tree, &found, MAKE_KEY(next_size, next_free_pageno)); + + if (!found) { + assert(0); + return -1; + } + + merge_page_size += found->page->alloc_pages; + P_FREE(found); + } + + page->alloc_pages = 0; + page->first_pageno = -1; + + set_blocks_free(mm, merge_page_no, merge_page_size); + + mm->alloc_page_count -= free_page_size; + mm->free_page_count += free_page_size; + + return 0; +} + +int jmem_get_info(jpeg_mm_t *mm, jmem_info_t *info) +{ + if (!mm) { + // DPRINT("vmem_get_info: invalid handle\n"); + return -1; + } + + if (!info) { + return -1; + } + + info->total_pages = mm->num_pages; + info->alloc_pages = mm->alloc_page_count; + info->free_pages = mm->free_page_count; + info->page_size = VMEM_PAGE_SIZE; + + return 0; +} diff --git a/u-boot-2021.10/drivers/jpeg/mm.h b/u-boot-2021.10/drivers/jpeg/mm.h new file mode 100644 index 000000000..461b9100f --- /dev/null +++ b/u-boot-2021.10/drivers/jpeg/mm.h @@ -0,0 +1,71 @@ +#ifndef __JPU_VIDEO_MEMORY_MANAGEMENT_H__ +#define __JPU_VIDEO_MEMORY_MANAGEMENT_H__ + +typedef struct _jmem_info_struct { + unsigned long total_pages; + unsigned long alloc_pages; + unsigned long free_pages; + unsigned long page_size; +} jmem_info_t; + +#if defined(WIN32) || defined(WIN64) +#if (_MSC_VER == 1200) +typedef _int64 vmem_key_t; +#else +typedef unsigned long long vmem_key_t; +#endif +#else +typedef unsigned long long vmem_key_t; +#endif + +#define VMEM_PAGE_SIZE (16 * 1024) + +#define MAKE_KEY(_a, _b) (((vmem_key_t)(_a)) << 32 | (_b)) +#define KEY_TO_VALUE(_key) ((_key) >> 32) + +typedef struct page_struct { + int pageno; + unsigned long addr; + int used; + int alloc_pages; + int first_pageno; +} page_t; + +typedef struct avl_node_struct { + vmem_key_t key; + int height; + page_t *page; + struct avl_node_struct *left; + struct avl_node_struct *right; +} avl_node_t; + +typedef struct _jpeg_mm_struct { + avl_node_t *free_tree; + avl_node_t *alloc_tree; + page_t *page_list; + int num_pages; + unsigned long base_addr; + unsigned long mem_size; + void *mutex; + int free_page_count; + int alloc_page_count; +} jpeg_mm_t; + +#if defined(__cplusplus) +extern "C" { +#endif + +extern int jmem_init(jpeg_mm_t *mm, unsigned long addr, unsigned long size); + +extern int jmem_exit(jpeg_mm_t *mm); + +extern unsigned long jmem_alloc(jpeg_mm_t *mm, unsigned int size, unsigned long pid); + +extern int jmem_free(jpeg_mm_t *mm, unsigned long ptr, unsigned long pid); + +extern int jmem_get_info(jpeg_mm_t *mm, jmem_info_t *info); + +#if defined(__cplusplus) +} +#endif +#endif /* __JPU_VIDEO_MEMORY_MANAGEMENT_H__ */ \ No newline at end of file diff --git a/u-boot-2021.10/drivers/jpeg/regdefine.h b/u-boot-2021.10/drivers/jpeg/regdefine.h new file mode 100644 index 000000000..51b877bd9 --- /dev/null +++ b/u-boot-2021.10/drivers/jpeg/regdefine.h @@ -0,0 +1,162 @@ +#include "config.h" + +#ifndef NPT_REGDEFINE_H_INCLUDED +#define NPT_REGDEFINE_H_INCLUDED + +//------------------------------------------------------------------------------ +// REGISTER BASE +//------------------------------------------------------------------------------ +#define TOP_BASE 0x03000000 +#define TOP_USB_PHY_CTRSTS_REG (TOP_BASE + 0x48) +#define UPCR_EXTERNAL_VBUS_VALID_OFFSET 0 + +#define TOP_DDR_ADDR_MODE_REG (TOP_BASE + 0x64) +#define DAMR_REG_USB_REMAP_ADDR_39_32_OFFSET 16 +#define DAMR_REG_USB_REMAP_ADDR_39_32_MSK (0xff) + +#define DAMR_REG_VD_REMAP_ADDR_39_32_OFFSET 24 +#define DAMR_REG_VD_REMAP_ADDR_39_32_MSK (0xff) + +#define JPEG_INTRPT_REQ 75 + +#define NPT_REG_SIZE 0x300 +#define NPT_REG_BASE (0x10000000 + 0x3000) +#define VC_REG_BASE (0x0B000000 + 0x30000) + +#define NPT_BASE 0x00 + +/*-------------------------------------------------------------------- + * NIEUPORT REGISTERS + *------------------------------------------------------------------ + */ +// MAIN CONTROL REGISTER +// [3] - start partial encoding [2] - pic stop en/decoding[1] - pic init +// en/decoding [0] - pic start en/decoding +#define MJPEG_PIC_START_REG (NPT_BASE + 0x000) + +// [8] - stop [7:4] - partial buffer interrupt [3] - overflow, [2] - bbc +// interrupt, [1] - error, [0] - done +#define MJPEG_PIC_STATUS_REG (NPT_BASE + 0x004) + +// [27:24] - error restart idx, [23:12] - error MCU pos X, [11:0] - error MCU +// pos Y +#define MJPEG_PIC_ERRMB_REG (NPT_BASE + 0x008) + +// [27:16] - MCU pos X, [11:0] - MCU pos Y +#define MJPEG_PIC_SETMB_REG (NPT_BASE + 0x00C) + +// [12:7] huffman table index [6] - user huffman en, [4] - TC direction, [3] - +// encoder enable, [1:0] - operation mode +#define MJPEG_PIC_CTRL_REG (NPT_BASE + 0x010) +#define MJPEG_PIC_SIZE_REG (NPT_BASE + 0x014) +#define MJPEG_MCU_INFO_REG (NPT_BASE + 0x018) + +// [4] - rot-mir enable, [3:0] - rot-mir mode +#define MJPEG_ROT_INFO_REG (NPT_BASE + 0x01C) +#define MJPEG_SCL_INFO_REG (NPT_BASE + 0x020) + +// [1] - sensor interface clear, [0] - display interface clear +#define MJPEG_IF_INFO_REG (NPT_BASE + 0x024) +#define MJPEG_CLP_INFO_REG (NPT_BASE + 0x028) + +// [31:16] - # of line in 1 partial buffer, [5:3] - # of partial buffers [2:0] - +// # of request +#define MJPEG_OP_INFO_REG (NPT_BASE + 0x02C) + +#define MJPEG_DPB_CONFIG_REG (NPT_BASE + 0x030) +#define MJPEG_DPB_BASE00_REG (NPT_BASE + 0x034) +#define MJPEG_DPB_BASE01_REG (NPT_BASE + 0x038) +#define MJPEG_DPB_BASE02_REG (NPT_BASE + 0x03C) + +#define MJPEG_DPB_BASE10_REG (NPT_BASE + 0x040) +#define MJPEG_DPB_BASE11_REG (NPT_BASE + 0x044) +#define MJPEG_DPB_BASE12_REG (NPT_BASE + 0x048) +#define MJPEG_DPB_BASE20_REG (NPT_BASE + 0x04C) + +#define MJPEG_DPB_BASE21_REG (NPT_BASE + 0x050) +#define MJPEG_DPB_BASE22_REG (NPT_BASE + 0x054) +#define MJPEG_DPB_BASE30_REG (NPT_BASE + 0x058) +#define MJPEG_DPB_BASE31_REG (NPT_BASE + 0x05C) + +#define MJPEG_DPB_BASE32_REG (NPT_BASE + 0x060) +#define MJPEG_DPB_YSTRIDE_REG (NPT_BASE + 0x064) +#define MJPEG_DPB_CSTRIDE_REG (NPT_BASE + 0x068) +#define MJPEG_WRESP_CHECK_REG (NPT_BASE + 0x06C) + +#define MJPEG_CLP_BASE_REG (NPT_BASE + 0x070) +#define MJPEG_CLP_SIZE_REG (NPT_BASE + 0x074) + +#define MJPEG_HUFF_CTRL_REG (NPT_BASE + 0x080) +#define MJPEG_HUFF_ADDR_REG (NPT_BASE + 0x084) +#define MJPEG_HUFF_DATA_REG (NPT_BASE + 0x088) + +#define MJPEG_QMAT_CTRL_REG (NPT_BASE + 0x090) +#define MJPEG_QMAT_ADDR_REG (NPT_BASE + 0x094) +#define MJPEG_QMAT_DATA_REG (NPT_BASE + 0x098) + +#define MJPEG_COEF_CTRL_REG (NPT_BASE + 0x0A0) +#define MJPEG_COEF_ADDR_REG (NPT_BASE + 0x0A4) +#define MJPEG_COEF_DATA_REG (NPT_BASE + 0x0A8) + +#define MJPEG_RST_INTVAL_REG (NPT_BASE + 0x0B0) +#define MJPEG_RST_INDEX_REG (NPT_BASE + 0x0B4) +#define MJPEG_RST_COUNT_REG (NPT_BASE + 0x0B8) + +#define MJPEG_INTR_MASK_REG (NPT_BASE + 0x0C0) +#define MJPEG_CYCLE_INFO_REG (NPT_BASE + 0x0C8) + +#define MJPEG_DPCM_DIFF_Y_REG (NPT_BASE + 0x0F0) +#define MJPEG_DPCM_DIFF_CB_REG (NPT_BASE + 0x0F4) +#define MJPEG_DPCM_DIFF_CR_REG (NPT_BASE + 0x0F8) + +// GBU CONTROL REGISTER +#define MJPEG_GBU_CTRL_REG \ + (NPT_BASE + \ + 0x100) // [3] - GBU flush for encoding [2] - init GBU for decoding [1] + // - init GBU ff emulation for decoding [0] - reserved +#define MJPEG_GBU_PBIT_BUSY_REG (NPT_BASE + 0x104) + +#define MJPEG_GBU_BT_PTR_REG (NPT_BASE + 0x110) +#define MJPEG_GBU_WD_PTR_REG (NPT_BASE + 0x114) +#define MJPEG_GBU_TT_CNT_REG (NPT_BASE + 0x118) +//#define MJPEG_GBU_TT_CNT_REG+4 (NPT_BASE + 0x11C) + +#define MJPEG_GBU_PBIT_08_REG (NPT_BASE + 0x120) +#define MJPEG_GBU_PBIT_16_REG (NPT_BASE + 0x124) +#define MJPEG_GBU_PBIT_24_REG (NPT_BASE + 0x128) +#define MJPEG_GBU_PBIT_32_REG (NPT_BASE + 0x12C) + +#define MJPEG_GBU_BBSR_REG (NPT_BASE + 0x140) +#define MJPEG_GBU_BBER_REG (NPT_BASE + 0x144) +#define MJPEG_GBU_BBIR_REG (NPT_BASE + 0x148) +#define MJPEG_GBU_BBHR_REG (NPT_BASE + 0x14C) + +#define MJPEG_GBU_BCNT_REG (NPT_BASE + 0x158) + +#define MJPEG_GBU_FF_RPTR_REG (NPT_BASE + 0x160) +#define MJPEG_GBU_FF_WPTR_REG (NPT_BASE + 0x164) + +// BBC CONTROL REGISTER +#define MJPEG_BBC_END_ADDR_REG (NPT_BASE + 0x208) +#define MJPEG_BBC_WR_PTR_REG (NPT_BASE + 0x20C) +#define MJPEG_BBC_RD_PTR_REG (NPT_BASE + 0x210) + +#define MJPEG_BBC_EXT_ADDR_REG (NPT_BASE + 0x214) +#define MJPEG_BBC_INT_ADDR_REG (NPT_BASE + 0x218) +#define MJPEG_BBC_DATA_CNT_REG (NPT_BASE + 0x21C) +#define MJPEG_BBC_COMMAND_REG \ + (NPT_BASE + 0x220) // [2:1] - endianness [0] - load/save +#define MJPEG_BBC_BUSY_REG (NPT_BASE + 0x224) + +#define MJPEG_BBC_CTRL_REG \ + (NPT_BASE + 0x228) // [2:1] - endianness [0] - BBC auto run +#define MJPEG_BBC_CUR_POS_REG (NPT_BASE + 0x22C) + +#define MJPEG_BBC_BAS_ADDR_REG (NPT_BASE + 0x230) +#define MJPEG_BBC_STRM_CTRL_REG \ + (NPT_BASE + \ + 0x234) // [31] - end of bitstream file [23:0] - stream counter + +#define MJPEG_BBC_FLUSH_CMD_REG (NPT_BASE + 0x238) + +#endif diff --git a/u-boot-2021.10/drivers/mtd/spi/spi-nor-core.c b/u-boot-2021.10/drivers/mtd/spi/spi-nor-core.c index 125e43b23..3a169242a 100644 --- a/u-boot-2021.10/drivers/mtd/spi/spi-nor-core.c +++ b/u-boot-2021.10/drivers/mtd/spi/spi-nor-core.c @@ -2759,6 +2759,7 @@ static int spi_nor_init_params(struct spi_nor *nor, case SNOR_MFR_SPANSION: case SNOR_MFR_BOYA: case SNOR_MFR_PY: + case SNOR_MFR_FUDAN: params->quad_enable = quad_enable_SR2_bit1; break; diff --git a/u-boot-2021.10/drivers/mtd/spi/spi-nor-ids.c b/u-boot-2021.10/drivers/mtd/spi/spi-nor-ids.c index 26eca45ce..ee9bf2e02 100644 --- a/u-boot-2021.10/drivers/mtd/spi/spi-nor-ids.c +++ b/u-boot-2021.10/drivers/mtd/spi/spi-nor-ids.c @@ -128,6 +128,10 @@ const struct flash_info spi_nor_ids[] = { SPI_NOR_QUAD_READ | SECT_4K) }, { INFO("FM25Q64", 0xF83217, 0x0, 64 * 1024, 128, SPI_NOR_QUAD_READ | SECT_4K) }, + { INFO("FM25Q128A", 0xA14018, 0x0, 64 * 1024, 256, + SPI_NOR_QUAD_READ | SECT_4K) }, + { INFO("FM25W128", 0xA12818, 0x0, 64 * 1024, 256, + SPI_NOR_QUAD_READ | SECT_4K) }, { INFO("BY25Q128AS", 0x684018, 0x0, 64 * 1024, 256, SPI_NOR_QUAD_READ | SECT_4K) }, { INFO("BY25Q256FS", 0x684919, 0x0, 64 * 1024, 512, diff --git a/u-boot-2021.10/drivers/net/phy/Kconfig b/u-boot-2021.10/drivers/net/phy/Kconfig index 9b069c319..f2e85f0ec 100644 --- a/u-boot-2021.10/drivers/net/phy/Kconfig +++ b/u-boot-2021.10/drivers/net/phy/Kconfig @@ -148,11 +148,11 @@ config PHY_CORTINA_ACCESS help Cortina Access Ethernet PHYs init process -config PHY_CVITEK_CV182XA - bool "CVITEK CV182XA Ethernet PHYs support" +config PHY_CVITEK + bool "CVITEK internal Ethernet PHYs support" help Enable support for RMII PHYs manufactured by CVITEK - Include driver for cv182xa. + Include driver for cvitek. This is an internal ethernet phy. And support 100Mbs full duplex. diff --git a/u-boot-2021.10/drivers/net/phy/Makefile b/u-boot-2021.10/drivers/net/phy/Makefile index 35080e58f..16d36cff6 100644 --- a/u-boot-2021.10/drivers/net/phy/Makefile +++ b/u-boot-2021.10/drivers/net/phy/Makefile @@ -15,7 +15,7 @@ obj-$(CONFIG_PHY_ATHEROS) += atheros.o obj-$(CONFIG_PHY_BROADCOM) += broadcom.o obj-$(CONFIG_PHY_CORTINA) += cortina.o obj-$(CONFIG_PHY_CORTINA_ACCESS) += ca_phy.o -obj-$(CONFIG_PHY_CVITEK_CV182XA) += cv182xa.o +obj-$(CONFIG_PHY_CVITEK) += cvitek.o obj-$(CONFIG_PHY_DAVICOM) += davicom.o obj-$(CONFIG_PHY_ET1011C) += et1011c.o obj-$(CONFIG_PHY_LXT) += lxt.o diff --git a/u-boot-2021.10/drivers/net/phy/cv182xa.c b/u-boot-2021.10/drivers/net/phy/cvitek.c similarity index 92% rename from u-boot-2021.10/drivers/net/phy/cv182xa.c rename to u-boot-2021.10/drivers/net/phy/cvitek.c index da631dc33..c9367960e 100644 --- a/u-boot-2021.10/drivers/net/phy/cv182xa.c +++ b/u-boot-2021.10/drivers/net/phy/cvitek.c @@ -232,12 +232,12 @@ static void cv182xa_ephy_init(void) mmio_write_32(0x03009054, 0x2F62); // LED PAD MUX - mmio_write_32(0x030010e0, 0x05); - mmio_write_32(0x030010e4, 0x05); - //(SD1_CLK selphy) - mmio_write_32(0x050270b0, 0x11111111); - //(SD1_CMD selphy) - mmio_write_32(0x050270b4, 0x11111111); + // mmio_write_32(0x030010e0, 0x05); + // mmio_write_32(0x030010e4, 0x05); + // //(SD1_CLK selphy) + // mmio_write_32(0x050270b0, 0x11111111); + // //(SD1_CMD selphy) + // mmio_write_32(0x050270b4, 0x11111111); // LED // Switch to MII-page1 @@ -262,14 +262,25 @@ static void cv182xa_ephy_init(void) // Switch to MII-page18 mmio_write_32(0x0300907c, 0x1200); - // p18.0x12, lpf +#if IS_ENABLED(CONFIG_TARGET_CVITEK_CV181X) + /* mars LPF(8, 8, 8, 8) HPF(-8, 50(+32), -36, -8) */ + // lpf mmio_write_32(0x03009048, 0x0808); mmio_write_32(0x0300904C, 0x0808); -// hpf -//sean + // hpf mmio_write_32(0x03009050, 0x32f8); mmio_write_32(0x03009054, 0xf8dc); - +#elif IS_ENABLED(CONFIG_TARGET_CVITEK_CV180X) + /* phobos LPF:(1 8 23 23 8 1) HPF:(-4,58,-45,8,-5, 0) from sean PPT */ + // lpf + mmio_write_32(0x03009048, 0x0801); + mmio_write_32(0x0300904C, 0x1717); + mmio_write_32(0x0300905C, 0x0108); + // hpf + mmio_write_32(0x03009050, 0x3afc); + mmio_write_32(0x03009054, 0x08d3); + mmio_write_32(0x03009060, 0x00fb); +#endif // Switch to MII-page0 mmio_write_32(0x0300907c, 0x0000); // EPHY start auto-neg procedure @@ -341,7 +352,7 @@ static struct phy_driver cv182xa_driver = { .shutdown = &genphy_shutdown, }; -int phy_cv182xa_init(void) +int phy_cvitek_init(void) { phy_register(&cv182xa_driver); diff --git a/u-boot-2021.10/drivers/net/phy/phy.c b/u-boot-2021.10/drivers/net/phy/phy.c index 4faef8d59..1e29f140f 100644 --- a/u-boot-2021.10/drivers/net/phy/phy.c +++ b/u-boot-2021.10/drivers/net/phy/phy.c @@ -505,8 +505,8 @@ int phy_init(void) #ifdef CONFIG_PHY_CORTINA_ACCESS phy_cortina_access_init(); #endif -#ifdef CONFIG_PHY_CVITEK_CV182XA - phy_cv182xa_init(); +#ifdef CONFIG_PHY_CVITEK + phy_cvitek_init(); #endif #ifdef CONFIG_PHY_DAVICOM phy_davicom_init(); diff --git a/u-boot-2021.10/drivers/video/Kconfig b/u-boot-2021.10/drivers/video/Kconfig index 8b940d70e..1990d77cb 100644 --- a/u-boot-2021.10/drivers/video/Kconfig +++ b/u-boot-2021.10/drivers/video/Kconfig @@ -430,6 +430,8 @@ config VIDEO_LCD_RAYDIUM_RM68200 Say Y here if you want to enable support for Raydium RM68200 720x1280 DSI video mode panel. +source "drivers/video/cvitek/Kconfig" + config VIDEO_LCD_SSD2828 bool "SSD2828 bridge chip" default n diff --git a/u-boot-2021.10/drivers/video/Makefile b/u-boot-2021.10/drivers/video/Makefile index 7ae0ab2b3..993fcb6f5 100644 --- a/u-boot-2021.10/drivers/video/Makefile +++ b/u-boot-2021.10/drivers/video/Makefile @@ -73,6 +73,6 @@ obj-$(CONFIG_VIDEO_TEGRA20) += tegra.o obj-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o obj-$(CONFIG_VIDEO_VESA) += vesa.o obj-$(CONFIG_VIDEO_SEPS525) += seps525.o - +obj-$(CONFIG_VIDEO_CVITEK) += cvitek/ obj-y += bridge/ obj-y += sunxi/ diff --git a/u-boot-2021.10/drivers/video/cvitek/Kconfig b/u-boot-2021.10/drivers/video/cvitek/Kconfig index 4d55c2678..dd81ad2eb 100644 --- a/u-boot-2021.10/drivers/video/cvitek/Kconfig +++ b/u-boot-2021.10/drivers/video/cvitek/Kconfig @@ -64,6 +64,11 @@ config DISPLAY_CVITEK_MIPI high-speed serial interface between a host processor and a display module. +config MIPI_PANEL_LANE_SWAP + bool "MIPI DSI lane PN swap" + help + This enables Display Serial Interface(DSI) lane PN swap function. + endchoice endif diff --git a/u-boot-2021.10/drivers/video/cvitek/cvi_disp.c b/u-boot-2021.10/drivers/video/cvitek/cvi_disp.c index aa7d9b395..9d7fb95bb 100644 --- a/u-boot-2021.10/drivers/video/cvitek/cvi_disp.c +++ b/u-boot-2021.10/drivers/video/cvitek/cvi_disp.c @@ -9,11 +9,11 @@ #include #include #include -#include +//#include #include #include #include - +//#include #include "vip_common.h" #include "scaler.h" #include "dsi_phy.h" @@ -29,10 +29,9 @@ struct cvi_vo_priv { static int cvi_vo_bind(struct udevice *dev) { - struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); - - plat->size = 4 * (CONFIG_VIDEO_CVITEK_MAX_XRES * - CONFIG_VIDEO_CVITEK_MAX_YRES); + //struct video_uc_plat *plat = dev_get_uclass_plat(dev); + //plat->size = 4 * (CONFIG_VIDEO_CVITEK_MAX_XRES * + //CONFIG_VIDEO_CVITEK_MAX_YRES); return 0; } @@ -43,17 +42,17 @@ static int cvi_vo_ofdata_to_platdata(struct udevice *dev) priv->regs_sc = devfdt_get_addr_name(dev, "sc"); if (priv->regs_sc == FDT_ADDR_T_NONE) { - debug("%s: Get VO sc address failed (ret=%llu)\n", __func__, (u64)priv->regs_sc); + printf("%s: Get VO sc address failed (ret=%llu)\n", __func__, (u64)priv->regs_sc); return -ENXIO; } priv->regs_vip = devfdt_get_addr_name(dev, "vip_sys"); if (priv->regs_vip == FDT_ADDR_T_NONE) { - debug("%s: Get dsi address failed (ret=%llu)\n", __func__, (u64)priv->regs_vip); + printf("%s: Get dsi address failed (ret=%llu)\n", __func__, (u64)priv->regs_vip); return -ENXIO; } priv->regs_dphy = devfdt_get_addr_name(dev, "dphy"); if (priv->regs_dphy == FDT_ADDR_T_NONE) { - debug("%s: Get MIPI dsi address failed (ret=%llu)\n", __func__, (u64)priv->regs_dphy); + printf("%s: Get MIPI dsi address failed (ret=%llu)\n", __func__, (u64)priv->regs_dphy); return -ENXIO; } debug("%s: base(sc)=%#llx base(vip)=%#llx base(dphy)=%#llx\n", __func__ @@ -68,8 +67,6 @@ static int cvi_vo_probe(struct udevice *dev) struct cvi_vo_priv *priv = dev_get_priv(dev); int ret = 0; - debug("%s: start\n", __func__); - /* Before relocation we don't need to do anything */ if (!(gd->flags & GD_FLG_RELOC)) return 0; @@ -81,27 +78,28 @@ static int cvi_vo_probe(struct udevice *dev) #ifdef BOOTLOGO_ISP_RESET vip_isp_clk_reset(); #endif + sclr_ctrl_init(); sclr_ctrl_set_disp_src(false); ret = gpio_request_by_name(dev, "reset-gpio", 0, &priv->ctrl_gpios.disp_reset_gpio, GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); if (ret) { - debug("%s: Warning: cannot get enable GPIO: ret=%d\n", __func__, ret); + printf("%s: Warning: cannot get reset GPIO: ret=%d\n", __func__, ret); if (ret != -ENOENT) return ret; } ret = gpio_request_by_name(dev, "pwm-gpio", 0, &priv->ctrl_gpios.disp_pwm_gpio, GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); if (ret) { - debug("%s: Warning: cannot get enable GPIO: ret=%d\n", __func__, ret); + printf("%s: Warning: cannot get pwm GPIO: ret=%d\n", __func__, ret); if (ret != -ENOENT) return ret; } ret = gpio_request_by_name(dev, "power-ct-gpio", 0, &priv->ctrl_gpios.disp_power_ct_gpio, GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); if (ret) { - debug("%s: Warning: cannot get enable GPIO: ret=%d\n", __func__, ret); + printf("%s: Warning: cannot get power GPIO: ret=%d\n", __func__, ret); if (ret != -ENOENT) return ret; } @@ -121,12 +119,12 @@ static const struct video_ops cvi_vo_ops = { }; U_BOOT_DRIVER(cvi_vo) = { - .name = "cvi_vo", + .name = "vo", .id = UCLASS_VIDEO, .of_match = cvi_vo_ids, .ops = &cvi_vo_ops, .bind = cvi_vo_bind, .probe = cvi_vo_probe, - .ofdata_to_platdata = cvi_vo_ofdata_to_platdata, - .priv_auto_alloc_size = sizeof(struct cvi_vo_priv), + .of_to_plat = cvi_vo_ofdata_to_platdata, + .priv_auto = sizeof(struct cvi_vo_priv), }; diff --git a/u-boot-2021.10/drivers/video/cvitek/cvi_i80.c b/u-boot-2021.10/drivers/video/cvitek/cvi_i80.c index 532d8cb6e..59e483db2 100644 --- a/u-boot-2021.10/drivers/video/cvitek/cvi_i80.c +++ b/u-boot-2021.10/drivers/video/cvitek/cvi_i80.c @@ -6,7 +6,7 @@ #include #include #include -#include +//#include #include #include "reg.h" diff --git a/u-boot-2021.10/drivers/video/cvitek/cvi_lvds.c b/u-boot-2021.10/drivers/video/cvitek/cvi_lvds.c index 4dbf6e3e4..a7f5d54dd 100644 --- a/u-boot-2021.10/drivers/video/cvitek/cvi_lvds.c +++ b/u-boot-2021.10/drivers/video/cvitek/cvi_lvds.c @@ -5,166 +5,95 @@ #include #include -#include -#include -#include -#include -#include -#include #include -#include +//#include #include -#include +//#include #include +#include "reg.h" #include "vip_common.h" #include "scaler.h" #include "dsi_phy.h" +#include -DECLARE_GLOBAL_DATA_PTR; - -#define MHz 1000000 - -/* - * Private information for cvi lvds - * - * @regs: lvds controller address - * @panel: panel assined by device tree - * @ref_clk: reference clock for lvds dsi pll - * @sysclk: config clock for lvds dsi register - * @pix_clk: pixel clock for vop->dsi data transmission - * @phy_clk: lvds dphy output clock - * @txbyte_clk: clock for dsi->dphy high speed data transmission - * @txesc_clk: clock for tx esc mode - */ -struct cvi_lvds_priv { - struct udevice *panel; - u32 ref_clk; - u32 sys_clk; - u32 pix_clk; - u32 phy_clk; - u32 txbyte_clk; - u32 txesc_clk; -}; - -static int cvi_lvds_read_timing(struct udevice *dev, struct display_timing *timing) +static void _fill_disp_timing(struct sclr_disp_timing *timing, struct sync_info_s *sync_info) { - int ret; + timing->vtotal = sync_info->vid_vsa_lines + sync_info->vid_vbp_lines + + sync_info->vid_active_lines + sync_info->vid_vfp_lines - 1; + timing->htotal = sync_info->vid_hsa_pixels + sync_info->vid_hbp_pixels + + sync_info->vid_hline_pixels + sync_info->vid_hfp_pixels - 1; + timing->vsync_start = 1; + timing->vsync_end = timing->vsync_start + sync_info->vid_vsa_lines - 1; + timing->vfde_start = timing->vsync_start + sync_info->vid_vsa_lines + sync_info->vid_vbp_lines; + timing->vfde_end = timing->vfde_start + sync_info->vid_active_lines - 1; + timing->hsync_start = 1; + timing->hsync_end = timing->hsync_start + sync_info->vid_hsa_pixels - 1; + timing->hfde_start = timing->hsync_start + sync_info->vid_hsa_pixels + sync_info->vid_hbp_pixels; + timing->hfde_end = timing->hfde_start + sync_info->vid_hline_pixels - 1; + timing->vsync_pol = sync_info->vid_vsa_pos_polarity; + timing->hsync_pol = sync_info->vid_hsa_pos_polarity; - ret = fdtdec_decode_display_timing(gd->fdt_blob, dev_of_offset(dev), 0, timing); - if (ret) { - debug("%s: Failed to decode display timing (ret=%d)\n", - __func__, ret); - return -EINVAL; - } - - return 0; + timing->vmde_start = timing->vfde_start; + timing->vmde_end = timing->vfde_end; + timing->hmde_start = timing->hfde_start; + timing->hmde_end = timing->hfde_end; } -/* - * This function is called by cvi_display_init() using cvi_lvds_enable() and - * cvi_lvds_phy_enable() to initialize lvds controller and dphy. If success, - * enable backlight. - */ -static int cvi_lvds_enable(struct udevice *dev, int panel_bpp, const struct display_timing *timing) +int lvds_init(struct cvi_lvds_cfg_s *lvds_cfg) { - int ret = 0; - struct cvi_lvds_priv *priv = dev_get_priv(dev); + union sclr_lvdstx lvds_reg; + bool data_en[LANE_MAX_NUM] = {false, false, false, false, false}; + struct sclr_disp_timing timing; + struct disp_ctrl_gpios ctrl_gpios; + int i = 0, ret = 0; - /* Fill the lvds controller parameter */ - priv->ref_clk = 24 * MHz; - priv->sys_clk = priv->ref_clk; - priv->pix_clk = timing->pixelclock.typ; - priv->phy_clk = priv->pix_clk * 6; - priv->txbyte_clk = priv->phy_clk / 8; - priv->txesc_clk = 20 * MHz; - -#if 0 - /* Config and enable lvds dsi according to timing */ - ret = rk_lvds_enable(dev, timing); - if (ret) { - debug("%s: rk_lvds_enable() failed (err=%d)\n", - __func__, ret); - return ret; + for (i = 0; i < LANE_MAX_NUM; i++) { + if (lvds_cfg->lane_id[i] < 0 || lvds_cfg->lane_id[i] >= LANE_MAX_NUM) { + dphy_dsi_set_lane(i, VO_LVDS_LANE_MAX, false, false); + continue; + } + dphy_dsi_set_lane(i, lvds_cfg->lane_id[i], lvds_cfg->lane_pn_swap[i], false); + if (lvds_cfg->lane_id[i] != VO_LVDS_LANE_CLK) { + data_en[lvds_cfg->lane_id[i] - 1] = true; + } } - /* Config and enable lvds phy */ - ret = rk_lvds_phy_enable(dev); - if (ret) { - debug("%s: rk_lvds_phy_enable() failed (err=%d)\n", - __func__, ret); - return ret; - } + dphy_dsi_lane_en(true, data_en, false); + sclr_disp_set_intf(SCLR_VO_INTF_LVDS); - /* Enable backlight */ - ret = panel_enable_backlight(priv->panel); - if (ret) { - debug("%s: panel_enable_backlight() failed (err=%d)\n", - __func__, ret); - return ret; + lvds_reg.b.out_bit = lvds_cfg->out_bits; + lvds_reg.b.vesa_mode = lvds_cfg->mode; + if (lvds_cfg->chn_num == 1) + lvds_reg.b.dual_ch = 0; + else if (lvds_cfg->chn_num == 2) + lvds_reg.b.dual_ch = 1; + else { + lvds_reg.b.dual_ch = 0; + printf("invalid lvds chn_num(%d). Use 1 instead.", lvds_cfg->chn_num); } -#endif + lvds_reg.b.vs_out_en = 1; + lvds_reg.b.hs_out_en = 1; + lvds_reg.b.hs_blk_en = 1; + lvds_reg.b.ml_swap = 1; + lvds_reg.b.ctrl_rev = 0; + lvds_reg.b.oe_swap = 0; + lvds_reg.b.en = 1; + + dphy_lvds_set_pll(lvds_cfg->pixelclock, lvds_cfg->chn_num); + dphy_dsi_analog_setting(true); + sclr_lvdstx_set(lvds_reg); + + _fill_disp_timing(&timing, &lvds_cfg->sync_info); + sclr_disp_set_timing(&timing); + sclr_disp_tgen_enable(true); + + get_disp_ctrl_gpios(&ctrl_gpios); + ret = dm_gpio_set_value(&ctrl_gpios.disp_pwm_gpio, + ctrl_gpios.disp_pwm_gpio.flags & GPIOD_ACTIVE_LOW ? 0 : 1); + if (ret < 0) + printf("dm_gpio_set_value(disp_pwm_gpio, deassert) failed: %d", ret); return ret; } -static int cvi_lvds_ofdata_to_platdata(struct udevice *dev) -{ - struct cvi_lvds_priv *priv = dev_get_priv(dev); - - priv = priv; - -#if 0 - priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); - if (priv->grf <= 0) { - debug("%s: Get syscon grf failed (ret=%llu)\n", - __func__, (u64)priv->grf); - return -ENXIO; - } -#endif - return 0; -} - -/* - * Probe function: check panel existence and readingit's timing. Then config - * lvds dsi controller and enable it according to the timing parameter. - */ -static int cvi_lvds_probe(struct udevice *dev) -{ - int ret = 0; - struct cvi_lvds_priv *priv = dev_get_priv(dev); - - priv = priv; - -#if 0 - ret = uclass_get_device_by_phandle(UCLASS_PANEL, dev, "cvitek,panel", - &priv->panel); - if (ret) { - debug("%s: Can not find panel (err=%d)\n", __func__, ret); - return ret; - } -#endif - - return ret; -} - -static const struct dm_display_ops cvi_lvds_ops = { - .read_timing = cvi_lvds_read_timing, - .enable = cvi_lvds_enable, -}; - -static const struct udevice_id cvi_lvds_ids[] = { - { .compatible = "cvitek,lvds" }, - { } -}; - -U_BOOT_DRIVER(cvi_lvds) = { - .name = "cvi_lvds", - .id = UCLASS_DISPLAY, - .of_match = cvi_lvds_ids, - .ofdata_to_platdata = cvi_lvds_ofdata_to_platdata, - .probe = cvi_lvds_probe, - .ops = &cvi_lvds_ops, - .priv_auto_alloc_size = sizeof(struct cvi_lvds_priv), -}; - diff --git a/u-boot-2021.10/drivers/video/cvitek/cvi_mipi.c b/u-boot-2021.10/drivers/video/cvitek/cvi_mipi.c index f97e3af5e..587f0961f 100644 --- a/u-boot-2021.10/drivers/video/cvitek/cvi_mipi.c +++ b/u-boot-2021.10/drivers/video/cvitek/cvi_mipi.c @@ -6,9 +6,10 @@ #include #include #include -#include +//#include #include #include +#include #include "reg.h" #include "vip_common.h" @@ -20,6 +21,9 @@ * bit[0]: dcs cmd mode. 0(hw)/1(sw) */ static int cmd_mode = 1; +unsigned int pixel_clk; +u8 lane_num; +u8 bits; static void _fill_disp_timing(struct sclr_disp_timing *timing, struct sync_info_s *sync_info) { @@ -84,10 +88,8 @@ int mipi_tx_set_combo_dev_cfg(const struct combo_dev_cfg_s *dev_cfg) { int ret, i; bool data_en[LANE_MAX_NUM] = {false, false, false, false, false}; - u8 lane_num = 0; struct sclr_disp_timing timing; enum sclr_dsi_fmt dsi_fmt; - u8 bits; bool preamble_on = false; struct combo_dev_cfg_s dev_cfg_t = *dev_cfg; struct disp_ctrl_gpios ctrl_gpios; @@ -99,14 +101,14 @@ int mipi_tx_set_combo_dev_cfg(const struct combo_dev_cfg_s *dev_cfg) data_en[i] = false; continue; } - dphy_dsi_set_lane(i, dev_cfg_t.lane_id[i], dev_cfg_t.lane_pn_swap[i]); + dphy_dsi_set_lane(i, dev_cfg_t.lane_id[i], dev_cfg_t.lane_pn_swap[i], true); if (dev_cfg_t.lane_id[i] != MIPI_TX_LANE_CLK) { ++lane_num; data_en[dev_cfg_t.lane_id[i] - 1] = true; } } if (lane_num == 0) { - debug("%s: no active mipi-dsi lane\n", __func__); + printf("%s: no active mipi-dsi lane\n", __func__); return -EINVAL; } @@ -135,6 +137,7 @@ int mipi_tx_set_combo_dev_cfg(const struct combo_dev_cfg_s *dev_cfg) return -EINVAL; } _cal_htt_extra(&dev_cfg_t, lane_num, bits); + pixel_clk = dev_cfg_t.pixel_clk; _fill_disp_timing(&timing, &dev_cfg_t.sync_info); preamble_on = (dev_cfg_t.pixel_clk * bits / lane_num) > 1500000; dphy_dsi_lane_en(true, data_en, preamble_on); @@ -148,33 +151,33 @@ int mipi_tx_set_combo_dev_cfg(const struct combo_dev_cfg_s *dev_cfg) ret = dm_gpio_set_value(&ctrl_gpios.disp_power_ct_gpio, ctrl_gpios.disp_power_ct_gpio.flags & GPIOD_ACTIVE_LOW ? 0 : 1); if (ret < 0) { - error("dm_gpio_set_value(disp_power_ct_gpio, deassert) failed: %d", ret); + printf("dm_gpio_set_value(disp_power_ct_gpio, deassert) failed: %d", ret); return ret; } ret = dm_gpio_set_value(&ctrl_gpios.disp_pwm_gpio, ctrl_gpios.disp_pwm_gpio.flags & GPIOD_ACTIVE_LOW ? 0 : 1); if (ret < 0) { - error("dm_gpio_set_value(disp_pwm_gpio, deassert) failed: %d", ret); + printf("dm_gpio_set_value(disp_pwm_gpio, deassert) failed: %d", ret); return ret; } ret = dm_gpio_set_value(&ctrl_gpios.disp_reset_gpio, ctrl_gpios.disp_reset_gpio.flags & GPIOD_ACTIVE_LOW ? 0 : 1); if (ret < 0) { - error("dm_gpio_set_value(disp_reset_gpio, deassert) failed: %d", ret); + printf("dm_gpio_set_value(disp_reset_gpio, deassert) failed: %d", ret); return ret; } mdelay(10); ret = dm_gpio_set_value(&ctrl_gpios.disp_reset_gpio, ctrl_gpios.disp_reset_gpio.flags & GPIOD_ACTIVE_LOW ? 1 : 0); if (ret < 0) { - error("dm_gpio_set_value(disp_reset_gpio, deassert) failed: %d", ret); + printf("dm_gpio_set_value(disp_reset_gpio, deassert) failed: %d", ret); return ret; } mdelay(10); ret = dm_gpio_set_value(&ctrl_gpios.disp_reset_gpio, ctrl_gpios.disp_reset_gpio.flags & GPIOD_ACTIVE_LOW ? 0 : 1); if (ret < 0) { - error("dm_gpio_set_value(disp_reset_gpio, deassert) failed: %d", ret); + printf("dm_gpio_set_value(disp_reset_gpio, deassert) failed: %d", ret); return ret; } mdelay(100); @@ -185,10 +188,10 @@ int mipi_tx_set_combo_dev_cfg(const struct combo_dev_cfg_s *dev_cfg) int mipi_tx_set_cmd(struct cmd_info_s *cmd_info) { if (cmd_info->cmd_size > CMD_MAX_NUM) { - debug("cmd_size(%d) can't exceed %d!\n", cmd_info->cmd_size, CMD_MAX_NUM); + printf("cmd_size(%d) can't exceed %d!\n", cmd_info->cmd_size, CMD_MAX_NUM); return -EINVAL; } else if ((cmd_info->cmd_size != 0) && !cmd_info->cmd) { - debug("cmd is NULL, but cmd_size(%d) isn't zero!\n", cmd_info->cmd_size); + printf("cmd is NULL, but cmd_size(%d) isn't zero!\n", cmd_info->cmd_size); return -EINVAL; } @@ -205,16 +208,24 @@ int mipi_tx_set_cmd(struct cmd_info_s *cmd_info) int mipi_tx_get_cmd(struct get_cmd_info_s *get_cmd_info) { + int ret = 0; + if (get_cmd_info->get_data_size > RX_MAX_NUM) { - debug("get_data_size(%d) can't exceed %d!\n", get_cmd_info->get_data_size, RX_MAX_NUM); + printf("get_data_size(%d) can't exceed %d!\n", get_cmd_info->get_data_size, RX_MAX_NUM); return -EINVAL; } else if ((get_cmd_info->get_data_size != 0) && (!get_cmd_info->get_data)) { - debug("cmd is NULL, but cmd_size(%d) isn't zero!\n", get_cmd_info->get_data_size); + printf("cmd is NULL, but cmd_size(%d) isn't zero!\n", get_cmd_info->get_data_size); return -EINVAL; } - return sclr_dsi_dcs_read_buffer(get_cmd_info->data_type, get_cmd_info->data_param + if (pixel_clk) + dphy_dsi_set_pll(pixel_clk * 2, lane_num, bits); + ret = sclr_dsi_dcs_read_buffer(get_cmd_info->data_type, get_cmd_info->data_param , get_cmd_info->get_data, get_cmd_info->get_data_size, cmd_mode & 0x01); + if (pixel_clk) + dphy_dsi_set_pll(pixel_clk, lane_num, bits); + + return ret; } void mipi_tx_set_mode(unsigned long mode_flags) diff --git a/u-boot-2021.10/drivers/video/cvitek/dsi_phy.c b/u-boot-2021.10/drivers/video/cvitek/dsi_phy.c index 5b676486d..b034c0241 100644 --- a/u-boot-2021.10/drivers/video/cvitek/dsi_phy.c +++ b/u-boot-2021.10/drivers/video/cvitek/dsi_phy.c @@ -1,7 +1,7 @@ #include #include #include - +#include #include "vip_common.h" #include "scaler_reg.h" #include "reg.h" @@ -49,9 +49,10 @@ void dphy_dsi_lane_en(bool clk_en, bool *data_en, bool preamble_en) * @param lane_num: lane[0-4]. * @param lane: the role of this lane. * @param pn_swap: if this lane positive/negative swap. + * @param clk_phase_shift: if this clk lane phase shift 90 degree. * @return: 0 for success. */ -int dphy_dsi_set_lane(u8 lane_num, enum lane_id lane, bool pn_swap) +int dphy_dsi_set_lane(u8 lane_num, enum lane_id lane, bool pn_swap, bool clk_phase_shift) { if ((lane_num > 4) || (lane > DSI_LANE_MAX)) return -1; @@ -60,7 +61,8 @@ int dphy_dsi_set_lane(u8 lane_num, enum lane_id lane, bool pn_swap) _reg_write_mask(reg_base + REG_DSI_PHY_LANE_PN_SWAP, BIT(lane_num), pn_swap << lane_num); if (lane == DSI_LANE_CLK) - _reg_write_mask(reg_base + REG_DSI_PHY_LANE_SEL, 0x1f << 24, (1 << 24) << lane_num); + _reg_write_mask(reg_base + REG_DSI_PHY_LANE_SEL, 0x1f << 24, + clk_phase_shift ? ((1 << 24) << lane_num) : 0); if (lane == DSI_LANE_0) { data_0_lane = lane_num; data_0_pn_swap = pn_swap; @@ -156,6 +158,15 @@ void dphy_dsi_set_pll(u32 clkkHz, u8 lane, u8 bits) _reg_write_mask(reg_base + REG_DSI_PHY_REG_8C, BIT(0), 1); } +void dphy_dsi_analog_setting(bool is_lvds) +{ + //mercury needs this analog setting while lvds tx mode + if (is_lvds) + _reg_write_mask(reg_base + REG_DSI_PHY_REG_74, 0x3ff, 0x2AA); + else + _reg_write_mask(reg_base + REG_DSI_PHY_REG_74, 0x3ff, 0x0); +} + #define dcs_delay 1 enum LP_DATA { diff --git a/u-boot-2021.10/drivers/video/cvitek/dsi_phy.h b/u-boot-2021.10/drivers/video/cvitek/dsi_phy.h index 81593379f..f2a5483f1 100644 --- a/u-boot-2021.10/drivers/video/cvitek/dsi_phy.h +++ b/u-boot-2021.10/drivers/video/cvitek/dsi_phy.h @@ -19,11 +19,12 @@ enum lane_id { void dphy_set_base_addr(void *base); void dphy_dsi_lane_en(bool clk_en, bool *data_en, bool preamble_en); -int dphy_dsi_set_lane(u8 lane_num, enum lane_id lane, bool pn_swap); +int dphy_dsi_set_lane(u8 lane_num, enum lane_id lane, bool pn_swap, bool clk_phase_shift); void dphy_init(enum sclr_vo_intf intf); void dphy_dsi_set_pll(u32 clkkHz, u8 lane, u8 bits); void dphy_lvds_enable(bool en); void dphy_lvds_set_pll(u32 clkkHz, u8 link); +void dphy_dsi_analog_setting(bool is_lvds); void dpyh_mipi_tx_manual_packet(const u8 *data, u8 count); diff --git a/u-boot-2021.10/drivers/video/cvitek/scaler.c b/u-boot-2021.10/drivers/video/cvitek/scaler.c index a5f344783..72b9ce49f 100644 --- a/u-boot-2021.10/drivers/video/cvitek/scaler.c +++ b/u-boot-2021.10/drivers/video/cvitek/scaler.c @@ -1,5 +1,5 @@ #include - +#include #include "vip_common.h" #include "scaler.h" #include "scaler_reg.h" @@ -754,7 +754,7 @@ void sclr_disp_set_pattern(enum sclr_disp_pat_type type, break; } default: - debug("%s - unacceptiable pattern-type(%d)\n", __func__, type); + printf("%s - unacceptiable pattern-type(%d)\n", __func__, type); break; } } @@ -1074,7 +1074,7 @@ int sclr_dsi_long_packet_raw(const u8 *data, u8 count) u8 i = 0; if ((count > SCL_MAX_DSI_LP) || (count == 0)) { - debug("%s: count(%d) invalid\n", __func__, count); + printf("%s: count(%d) invalid\n", __func__, count); return -1; } @@ -1172,20 +1172,20 @@ int sclr_dsi_short_packet(u8 di, const u8 *data, u8 count, bool sw_mode) int sclr_dsi_dcs_write_buffer(u8 di, const void *data, size_t len, bool sw_mode) { if (len == 0) { - debug("[cvi_mipi_tx] %s: 0 param unacceptable.\n", __func__); + printf("[cvi_mipi_tx] %s: 0 param unacceptable.\n", __func__); return -1; } if ((di == 0x06) || (di == 0x05) || (di == 0x04) || (di == 0x03)) { if (len != 1) { - debug("[cvi_mipi_tx] %s: cmd(0x%02x) should has 1 param.\n", __func__, di); + printf("[cvi_mipi_tx] %s: cmd(0x%02x) should has 1 param.\n", __func__, di); return -1; } return sclr_dsi_short_packet(di, data, len, sw_mode); } if ((di == 0x15) || (di == 0x37) || (di == 0x13) || (di == 0x14)) { if (len != 2) { - debug("[cvi_mipi_tx] %s: cmd(0x%02x) should has 2 param.\n", __func__, di); + printf("[cvi_mipi_tx] %s: cmd(0x%02x) should has 2 param.\n", __func__, di); return -1; } return sclr_dsi_short_packet(di, data, len, sw_mode); @@ -1214,11 +1214,12 @@ int sclr_dsi_dcs_read_buffer(u8 di, const u16 data_param, u8 *data, size_t len, len = 4; if (sclr_dsi_get_mode() == SCLR_DSI_MODE_HS) { - debug("[cvi_mipi_tx] %s: not work in HS.\n", __func__); + printf("[cvi_mipi_tx] %s: not work in HS.\n", __func__); return -1; } - _reg_write(reg_base + REG_SCL_DSI_ESC, 0x04); + // only set necessery bits + _reg_write_mask(reg_base + REG_SCL_DSI_ESC, 0x07, 0x04); // send read cmd sclr_dsi_short_packet(di, (u8 *)&data_param, 2, sw_mode); @@ -1230,7 +1231,7 @@ int sclr_dsi_dcs_read_buffer(u8 di, const u16 data_param, u8 *data, size_t len, if (ret == 0) { sclr_dsi_clr_mode(); } else { - debug("[cvi_mipi_tx] %s: BTA error.\n", __func__); + printf("[cvi_mipi_tx] %s: BTA error.\n", __func__); return ret; } @@ -1253,12 +1254,12 @@ int sclr_dsi_dcs_read_buffer(u8 di, const u16 data_param, u8 *data, size_t len, data[i] = (rx_data >> (i * 8)) & 0xff; break; case ACK_WR: - debug("[cvi_mipi_tx] %s: dcs read, ack with error(%#x %#x).\n" + printf("[cvi_mipi_tx] %s: dcs read, ack with error(%#x %#x).\n" , __func__, (rx_data >> 8) & 0xff, (rx_data >> 16) & 0xff); ret = -1; break; default: - debug("[cvi_mipi_tx] %s: unknown DT, %#x.", __func__, rx_data); + printf("[cvi_mipi_tx] %s: unknown DT, %#x.", __func__, rx_data); ret = -1; break; } @@ -1280,7 +1281,7 @@ int sclr_dsi_config(u8 lane_num, enum sclr_dsi_fmt fmt, u16 width) lane_num >>= 1; val = (fmt << 30) | (lane_num << 24); _reg_write_mask(reg_base + REG_SCL_DSI_HS_0, 0xc3000000, val); - val = (width / 6) << 16 | ((width * bit_depth[fmt] + 7) >> 3); + val = (width / 10) << 16 | ((width * bit_depth[fmt] + 7) >> 3); _reg_write(reg_base + REG_SCL_DSI_HS_1, val); return 0; @@ -1311,7 +1312,7 @@ void sclr_i80_packet(u32 cmd) } while (++cnt < 10); if (cnt == 10) - debug("[cvi_vip] %s: cmd(%#x) not ready.\n", __func__, cmd); + printf("[cvi_vip] %s: cmd(%#x) not ready.\n", __func__, cmd); } void sclr_i80_run(void) @@ -1327,7 +1328,7 @@ void sclr_i80_run(void) } while (++cnt < 10); if (cnt == 10) { - debug("[cvi_vip] %s: not finish. sw clear it.\n", __func__); + printf("[cvi_vip] %s: not finish. sw clear it.\n", __func__); _reg_write_mask(reg_base + REG_SCL_DISP_MCU_IF_CTRL, BIT(10), BIT(10)); } } diff --git a/u-boot-2021.10/drivers/video/cvitek/scaler_reg.h b/u-boot-2021.10/drivers/video/cvitek/scaler_reg.h index e4ca0ae22..4dd18f512 100644 --- a/u-boot-2021.10/drivers/video/cvitek/scaler_reg.h +++ b/u-boot-2021.10/drivers/video/cvitek/scaler_reg.h @@ -136,6 +136,7 @@ #define REG_DSI_PHY_LPRX_OV (REG_DSI_WRAP_BASE + 0x4C) #define REG_DSI_PHY_PD (REG_DSI_WRAP_BASE + 0x64) #define REG_DSI_PHY_TXPLL (REG_DSI_WRAP_BASE + 0x6C) +#define REG_DSI_PHY_REG_74 (REG_DSI_WRAP_BASE + 0x74) #define REG_DSI_PHY_REG_8C (REG_DSI_WRAP_BASE + 0x8C) #define REG_DSI_PHY_REG_SET (REG_DSI_WRAP_BASE + 0x90) #define REG_DSI_PHY_LANE_SEL (REG_DSI_WRAP_BASE + 0x9C) diff --git a/u-boot-2021.10/drivers/video/cvitek/vip_sys.c b/u-boot-2021.10/drivers/video/cvitek/vip_sys.c index b85373b75..3c7220b15 100644 --- a/u-boot-2021.10/drivers/video/cvitek/vip_sys.c +++ b/u-boot-2021.10/drivers/video/cvitek/vip_sys.c @@ -1,5 +1,5 @@ #include - +#include #include "vip_common.h" #include "reg.h" diff --git a/u-boot-2021.10/drivers/watchdog/designware_wdt.c b/u-boot-2021.10/drivers/watchdog/designware_wdt.c index ee84d60aa..a409bd9ad 100644 --- a/u-boot-2021.10/drivers/watchdog/designware_wdt.c +++ b/u-boot-2021.10/drivers/watchdog/designware_wdt.c @@ -14,6 +14,8 @@ #include "../../board/cvitek/cv181x/cv181x_reg.h" #elif IS_ENABLED(CONFIG_TARGET_CVITEK_CV180X) #include "../../board/cvitek/cv180x/cv180x_reg.h" +#elif IS_ENABLED(CONFIG_TARGET_CVITEK_ATHENA2) +#include "../../board/cvitek/athena2/athena2_reg.h" #endif #define DW_WDT_CR 0x00 diff --git a/u-boot-2021.10/include/configs/cv180x-asic.h b/u-boot-2021.10/include/configs/cv180x-asic.h index db3ef7fae..851f8c7b1 100644 --- a/u-boot-2021.10/include/configs/cv180x-asic.h +++ b/u-boot-2021.10/include/configs/cv180x-asic.h @@ -69,7 +69,6 @@ #define SYS_COUNTER_FREQ_IN_SECOND 25000000 /* 16550 Serial Configuration */ -#define CONFIG_CONS_INDEX 1 #define CONFIG_SYS_NS16550_COM1 0x04140000 #define CONFIG_SYS_NS16550_SERIAL #define CONFIG_SYS_NS16550_REG_SIZE (-4) diff --git a/u-boot-2021.10/include/configs/cv180x-fpga.h b/u-boot-2021.10/include/configs/cv180x-fpga.h index 83d4a01d4..ab152f74c 100644 --- a/u-boot-2021.10/include/configs/cv180x-fpga.h +++ b/u-boot-2021.10/include/configs/cv180x-fpga.h @@ -69,7 +69,6 @@ #define SYS_COUNTER_FREQ_IN_SECOND 25000000 /* 16550 Serial Configuration */ -#define CONFIG_CONS_INDEX 1 #define CONFIG_SYS_NS16550_COM1 0x04140000 #define CONFIG_SYS_NS16550_SERIAL #define CONFIG_SYS_NS16550_REG_SIZE (-4) diff --git a/u-boot-2021.10/include/configs/cv181x-asic.h b/u-boot-2021.10/include/configs/cv181x-asic.h index 6f2a43873..cb627682e 100644 --- a/u-boot-2021.10/include/configs/cv181x-asic.h +++ b/u-boot-2021.10/include/configs/cv181x-asic.h @@ -37,6 +37,7 @@ /* Physical Memory Map */ #define CONFIG_SYS_RESVIONSZ CVIMMAP_ION_SIZE +#define CONFIG_SYS_RESVLOGOSZ CVIMMAP_BOOTLOGO_SIZE #define CONFIG_SYS_BOOTMAPSZ CVIMMAP_KERNEL_MEMORY_SIZE #define PHYS_SDRAM_1 CVIMMAP_KERNEL_MEMORY_ADDR @@ -69,7 +70,6 @@ #define SYS_COUNTER_FREQ_IN_SECOND 25000000 /* 16550 Serial Configuration */ -#define CONFIG_CONS_INDEX 1 #define CONFIG_SYS_NS16550_COM1 0x04140000 #define CONFIG_SYS_NS16550_SERIAL #define CONFIG_SYS_NS16550_REG_SIZE (-4) @@ -187,10 +187,10 @@ #define UIMAG_ADDR CVIMMAP_UIMAG_ADDR #ifdef CONFIG_BOOTLOGO - #define LOGO_RESERVED_ADDR "0x81800000" - #define LOGO_READ_ADDR "0x84080000" + #define LOGO_RESERVED_ADDR __stringify(CVIMMAP_BOOTLOGO_ADDR)//yuv load addr + #define LOGO_READ_ADDR "0x84080000" //jpeg load addr #define VO_ALIGNMENT "16" - #define LOGOSIZE "0x80000" + #define LOGOSIZE "0x80000" //jpeg max size #endif /******************************************************************************/ /* define common env */ @@ -270,11 +270,11 @@ #ifdef CONFIG_NAND_SUPPORT #define LOAD_LOGO "nand read " LOGO_READ_ADDR " MISC;" #elif defined(CONFIG_SPI_FLASH) - #define LOAD_LOGO "" + #define LOAD_LOGO "sf probe;sf read " LOGO_READ_ADDR " ${MISC_PART_OFFSET} ${MISC_PART_SIZE};" #else #define LOAD_LOGO "mmc dev 0;mmc read " LOGO_READ_ADDR " ${MISC_PART_OFFSET} ${MISC_PART_SIZE};" #endif - #define SHOWLOGOCOMMAND (LOAD_LOGO CVI_JPEG START_VO START_VL SET_VO_BG) + #define SHOWLOGOCOMMAND LOAD_LOGO CVI_JPEG START_VO START_VL SET_VO_BG #else #define SHOWLOGOCMD #endif diff --git a/u-boot-2021.10/include/configs/cv181x-fpga.h b/u-boot-2021.10/include/configs/cv181x-fpga.h index 5e146d87e..38097259b 100644 --- a/u-boot-2021.10/include/configs/cv181x-fpga.h +++ b/u-boot-2021.10/include/configs/cv181x-fpga.h @@ -31,12 +31,16 @@ #define CONFIG_REMAKE_ELF /* Physical Memory Map */ +#ifndef CONFIG_SYS_BOOTMAPSZ +#define CONFIG_SYS_BOOTMAPSZ 0x10000000 +#endif #define PHYS_SDRAM_1 0x80000000 #define PHYS_SDRAM_1_SIZE CONFIG_SYS_BOOTMAPSZ #define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1 /* Link Definitions */ -#define CONFIG_SYS_TEXT_BASE 0x80200000 +#define CVIMMAP_ION_ADDR 0x83c80000 /* offset 60.5MiB */ +#define CONFIG_SYS_TEXT_BASE 0x88000000 #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0x03f00000) /* default address for bootm command without arguments */ @@ -59,7 +63,6 @@ #endif /* 16550 Serial Configuration */ -#define CONFIG_CONS_INDEX 1 #define CONFIG_SYS_NS16550_COM1 0x04140000 #define CONFIG_SYS_NS16550_SERIAL #define CONFIG_SYS_NS16550_REG_SIZE (-4) @@ -74,6 +77,7 @@ /* Download related definitions */ #define UPGRADE_SRAM_ADDR 0x0e000030 #define UBOOT_PID_SRAM_ADDR 0x0e000030 +#define UPDATE_ADDR 0x83800000 #define IMG_ADDR 0x80090000 #define HEADER_ADDR 0x80080000 #define USB_UPDATE_MAGIC 0x4D474E31 @@ -224,11 +228,19 @@ #define CONSOLEDEV "ttyS0\0" /* config loglevel */ +#ifdef __riscv__ #ifdef RELEASE - #define OTHERBOOTARGS "othbootargs=earlycon=sbi release loglevel=0\0" + #define OTHERBOOTARGS "othbootargs=earlycon=sbi release loglevel=10\0" #else - #define OTHERBOOTARGS "othbootargs=earlycon=sbi loglevel=9\0" + #define OTHERBOOTARGS "othbootargs=earlycon=sbi loglevel=10\0" #endif +#else + #ifdef RELEASE + #define OTHERBOOTARGS "othbootargs=earlycon release loglevel=10\0" + #else + #define OTHERBOOTARGS "othbootargs=earlycon loglevel=10\0" + #endif +#endif /* config mtdids */ #ifdef CONFIG_NAND_SUPPORT diff --git a/u-boot-2021.10/include/cvi_efuse.h b/u-boot-2021.10/include/cvi_efuse.h index b912862bc..453e12f45 100644 --- a/u-boot-2021.10/include/cvi_efuse.h +++ b/u-boot-2021.10/include/cvi_efuse.h @@ -48,7 +48,7 @@ enum CVI_EFUSE_OTHERS_E { CVI_S32 CVI_EFUSE_GetSize(enum CVI_EFUSE_AREA_E area, CVI_U32 *size); CVI_S32 CVI_EFUSE_Read(enum CVI_EFUSE_AREA_E area, CVI_U8 *buf, CVI_U32 buf_size); CVI_S32 CVI_EFUSE_Write(enum CVI_EFUSE_AREA_E area, const CVI_U8 *buf, CVI_U32 buf_size); -CVI_S32 CVI_EFUSE_EnableSecureBoot(void); +CVI_S32 CVI_EFUSE_EnableSecureBoot(uint32_t sel); CVI_S32 CVI_EFUSE_IsSecureBootEnabled(void); CVI_S32 CVI_EFUSE_Lock(enum CVI_EFUSE_LOCK_E lock); CVI_S32 CVI_EFUSE_IsLocked(enum CVI_EFUSE_LOCK_E lock); diff --git a/u-boot-2021.10/include/cvitek/cvi_efuse.h b/u-boot-2021.10/include/cvitek/cvi_efuse.h index b912862bc..453e12f45 100644 --- a/u-boot-2021.10/include/cvitek/cvi_efuse.h +++ b/u-boot-2021.10/include/cvitek/cvi_efuse.h @@ -48,7 +48,7 @@ enum CVI_EFUSE_OTHERS_E { CVI_S32 CVI_EFUSE_GetSize(enum CVI_EFUSE_AREA_E area, CVI_U32 *size); CVI_S32 CVI_EFUSE_Read(enum CVI_EFUSE_AREA_E area, CVI_U8 *buf, CVI_U32 buf_size); CVI_S32 CVI_EFUSE_Write(enum CVI_EFUSE_AREA_E area, const CVI_U8 *buf, CVI_U32 buf_size); -CVI_S32 CVI_EFUSE_EnableSecureBoot(void); +CVI_S32 CVI_EFUSE_EnableSecureBoot(uint32_t sel); CVI_S32 CVI_EFUSE_IsSecureBootEnabled(void); CVI_S32 CVI_EFUSE_Lock(enum CVI_EFUSE_LOCK_E lock); CVI_S32 CVI_EFUSE_IsLocked(enum CVI_EFUSE_LOCK_E lock); diff --git a/u-boot-2021.10/include/cvitek/cvi_lvds.h b/u-boot-2021.10/include/cvitek/cvi_lvds.h new file mode 100644 index 000000000..0155f6f41 --- /dev/null +++ b/u-boot-2021.10/include/cvitek/cvi_lvds.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) Cvitek Co., Ltd. 2019-2021. All rights reserved. + * + */ + +#ifndef _CVI_LVDS_H_ +#define _CVI_LVDS_H_ + +#include "cvi_mipi.h" + +#define LANE_MAX_NUM 5 + +enum lvds_lane_id { + VO_LVDS_LANE_CLK = 0, + VO_LVDS_LANE_0, + VO_LVDS_LANE_1, + VO_LVDS_LANE_2, + VO_LVDS_LANE_3, + VO_LVDS_LANE_MAX, +}; + +enum LVDS_OUT_BIT { + LVDS_OUT_6BIT = 0, + LVDS_OUT_8BIT, + LVDS_OUT_10BIT, + LVDS_OUT_MAX, +}; + +enum LVDS_MODE { + LVDS_MODE_JEIDA = 0, + LVDS_MODE_VESA, + LVDS_MODE_MAX, +}; + +/* + * @pixelclock: pixel clock in kHz + */ +struct cvi_lvds_cfg_s { + enum LVDS_OUT_BIT out_bits; + enum LVDS_MODE mode; + unsigned char chn_num; + bool data_big_endian; + enum lvds_lane_id lane_id[LANE_MAX_NUM]; + bool lane_pn_swap[LANE_MAX_NUM]; + struct sync_info_s sync_info; + unsigned short u16FrameRate; + unsigned int pixelclock; +}; + +int lvds_init(struct cvi_lvds_cfg_s *lvds_cfg); + +#endif // _CVI_LVDS_H_ diff --git a/u-boot-2021.10/include/cvitek/cvi_panels/cvi_panel_diffs.h b/u-boot-2021.10/include/cvitek/cvi_panels/cvi_panel_diffs.h index 2d83cf1be..5b8ded9da 100644 --- a/u-boot-2021.10/include/cvitek/cvi_panels/cvi_panel_diffs.h +++ b/u-boot-2021.10/include/cvitek/cvi_panels/cvi_panel_diffs.h @@ -8,14 +8,15 @@ #ifndef __CVI_PANEL_DIFFS_H__ #define __CVI_PANEL_DIFFS_H__ -#ifdef I80_PANEL_ST7789V +#ifdef CONFIG_DISPLAY_CVITEK_I80 #define CVI_JPEG "" #define START_VO "startvo 0 65536 0;" -#define LOGO_POS_INFO " 736 0 0 240 320;" +#elif defined(CONFIG_DISPLAY_CVITEK_LVDS) +#define CVI_JPEG "cvi_jpeg_dec " LOGO_READ_ADDR " " LOGO_RESERVED_ADDR " " LOGOSIZE ";" +#define START_VO "startvo 0 2048 0;" #else -#define CVI_JPEG "cvi_jpeg " LOGO_READ_ADDR " " LOGO_RESERVED_ADDR " " LOGOSIZE ";" +#define CVI_JPEG "cvi_jpeg_dec " LOGO_READ_ADDR " " LOGO_RESERVED_ADDR " " LOGOSIZE ";" #define START_VO "startvo 0 8192 0;" - #endif #define START_VL "startvl 0 " LOGO_READ_ADDR " " LOGO_RESERVED_ADDR " " LOGOSIZE " " VO_ALIGNMENT ";" diff --git a/u-boot-2021.10/include/cvitek/cvi_panels/cvi_panels.h b/u-boot-2021.10/include/cvitek/cvi_panels/cvi_panels.h index 8670d8c60..ac6ce6db9 100644 --- a/u-boot-2021.10/include/cvitek/cvi_panels/cvi_panels.h +++ b/u-boot-2021.10/include/cvitek/cvi_panels/cvi_panels.h @@ -9,6 +9,7 @@ #define __CVI_PANEL_H__ #include "cvi_i80.h" +#include "cvi_lvds.h" struct panel_desc_s { char *panel_name; @@ -19,6 +20,7 @@ struct panel_desc_s { const struct _VO_I80_CFG_S *i80_cfg; const struct _VO_I80_INSTR_S *i80_init_cmds; int i80_init_cmds_size; + struct cvi_lvds_cfg_s *lvds_cfg; }; #ifdef MIPI_PANEL_HX8394 @@ -118,6 +120,11 @@ static struct panel_desc_s panel_desc = { .i80_init_cmds = i80_st7789v_init_cmds, .i80_init_cmds_size = ARRAY_SIZE(i80_st7789v_init_cmds) }; +#elif defined(LVDS_PANEL_EK79202) +#include "lvds_ek79202.h" +static struct panel_desc_s panel_desc = { + .lvds_cfg = &lvds_ek79202_cfg +}; #else #include "dsi_hx8394_evb.h" static struct panel_desc_s panel_desc = { diff --git a/u-boot-2021.10/include/cvitek/cvi_panels/dsi_hx8394_evb.h b/u-boot-2021.10/include/cvitek/cvi_panels/dsi_hx8394_evb.h index ef20ae5fd..cc6c2e0d1 100644 --- a/u-boot-2021.10/include/cvitek/cvi_panels/dsi_hx8394_evb.h +++ b/u-boot-2021.10/include/cvitek/cvi_panels/dsi_hx8394_evb.h @@ -7,7 +7,6 @@ #define _MIPI_TX_PARAM_HX8394_H_ #include - const struct combo_dev_cfg_s dev_cfg_hx8394_720x1280 = { .devno = 0, #ifdef MIPI_PANEL_2_LANES @@ -15,7 +14,7 @@ const struct combo_dev_cfg_s dev_cfg_hx8394_720x1280 = { #else .lane_id = {MIPI_TX_LANE_0, MIPI_TX_LANE_1, MIPI_TX_LANE_CLK, MIPI_TX_LANE_2, MIPI_TX_LANE_3}, #endif -#ifdef MIPI_PANEL_LANE_SWAP +#ifdef CONFIG_MIPI_PANEL_LANE_SWAP .lane_pn_swap = {true, true, true, true, true}, #else .lane_pn_swap = {false, false, false, false, false}, diff --git a/u-boot-2021.10/include/cvitek/cvi_panels/lvds_ek79202.h b/u-boot-2021.10/include/cvitek/cvi_panels/lvds_ek79202.h new file mode 100644 index 000000000..a0a994b09 --- /dev/null +++ b/u-boot-2021.10/include/cvitek/cvi_panels/lvds_ek79202.h @@ -0,0 +1,30 @@ +#ifndef _LVDS_EK79202_H_ +#define _LVDS_EK79202_H_ + +#include + +struct cvi_lvds_cfg_s lvds_ek79202_cfg = { + .mode = LVDS_MODE_VESA, + .out_bits = LVDS_OUT_8BIT, + .chn_num = 1, + .lane_id = {VO_LVDS_LANE_0, VO_LVDS_LANE_1, VO_LVDS_LANE_2, VO_LVDS_LANE_3, VO_LVDS_LANE_CLK}, + .lane_pn_swap = {false, false, false, false, false}, + .sync_info = { + .vid_hsa_pixels = 10, + .vid_hbp_pixels = 88, + .vid_hfp_pixels = 62, + .vid_hline_pixels = 1280, + .vid_vsa_lines = 4, + .vid_vbp_lines = 23, + .vid_vfp_lines = 11, + .vid_active_lines = 800, + .vid_vsa_pos_polarity = 0, + .vid_hsa_pos_polarity = 0, + }, + .u16FrameRate = 60, + .pixelclock = 72403, +}; + +#else +#error "_LVDS_EK79202_H_ multi-delcaration!!" +#endif // _LVDS_EK79202_H_ diff --git a/u-boot-2021.10/include/env_default.h b/u-boot-2021.10/include/env_default.h index e840425e4..807026bca 100644 --- a/u-boot-2021.10/include/env_default.h +++ b/u-boot-2021.10/include/env_default.h @@ -52,6 +52,9 @@ const uchar default_environment[] = { #ifdef CONFIG_NORBOOTCOMMAND "norboot=" CONFIG_NORBOOTCOMMAND "\0" #endif +#ifdef CONFIG_BOOTLOGO + "showlogo=" SHOWLOGOCOMMAND "\0" +#endif #if defined(CONFIG_BOOTDELAY) "bootdelay=" __stringify(CONFIG_BOOTDELAY) "\0" #endif diff --git a/u-boot-2021.10/include/linux/mtd/spi-nor.h b/u-boot-2021.10/include/linux/mtd/spi-nor.h index 170db5ee5..cfa600575 100644 --- a/u-boot-2021.10/include/linux/mtd/spi-nor.h +++ b/u-boot-2021.10/include/linux/mtd/spi-nor.h @@ -37,6 +37,7 @@ #define SNOR_MFR_JUYANG CFI_MFR_JUYANG #define SNOR_MFR_BOYA CFI_MFR_BOYA #define SNOR_MFR_PY 0x85 +#define SNOR_MFR_FUDAN 0xA1 /* * Note on opcode nomenclature: some opcodes have a format like diff --git a/u-boot-2021.10/include/phy.h b/u-boot-2021.10/include/phy.h index 741136b26..6d6f937fb 100644 --- a/u-boot-2021.10/include/phy.h +++ b/u-boot-2021.10/include/phy.h @@ -519,7 +519,7 @@ int phy_atheros_init(void); int phy_broadcom_init(void); int phy_cortina_init(void); int phy_cortina_access_init(void); -int phy_cv182xa_init(void); +int phy_cvitek_init(void); int phy_davicom_init(void); int phy_et1011c_init(void); int phy_lxt_init(void); diff --git a/u-boot-2021.10/include/sdhci.h b/u-boot-2021.10/include/sdhci.h index 9e4644587..26072d17d 100644 --- a/u-boot-2021.10/include/sdhci.h +++ b/u-boot-2021.10/include/sdhci.h @@ -23,6 +23,8 @@ #include <../../board/cvitek/cv181x/sdhci_reg.h> #elif defined(CONFIG_TARGET_CVITEK_CV180X) #include <../../board/cvitek/cv180x/sdhci_reg.h> +#elif defined(CONFIG_TARGET_CVITEK_ATHENA2) +#include <../../board/cvitek/athena2/sdhci_reg.h> #endif /* * Controller registers diff --git a/u-boot-2021.10/scripts/config_whitelist.txt b/u-boot-2021.10/scripts/config_whitelist.txt index 782b6099d..24b6b2911 100644 --- a/u-boot-2021.10/scripts/config_whitelist.txt +++ b/u-boot-2021.10/scripts/config_whitelist.txt @@ -3037,6 +3037,7 @@ CONFIG_SYS_RESET_ADDR CONFIG_SYS_RESET_ADDRESS CONFIG_SYS_RESET_SCTRL CONFIG_SYS_RESVIONSZ +CONFIG_SYS_RESVLOGOSZ CONFIG_SYS_RFD CONFIG_SYS_RGMII1_PHY_ADDR CONFIG_SYS_RGMII2_PHY_ADDR