#
# SPDX-License-Identifier: GPL-2.0
#
# Copyright (c) 2013-2023 Igor Pecovnik, igor@armbian.com
#
# This file is a part of the Armbian Build Framework
# https://github.com/armbian/build/
#
enable_extension "rkbin-tools"

# BOOT_SOC has to be set in the board configuration file; if not set
# we resort to rk3288
BOOT_SOC=${BOOT_SOC:="rk3288"}

ARCH=armhf
BOOTDELAY=1
SERIALCON=ttyS2

if [[ "$BOOT_SOC" == "rk3288" ]]; then

	BOOTSCRIPT="boot-rockchip.cmd:boot.cmd"
	BOOTENV_FILE='rockchip.txt'
	OVERLAY_PREFIX='rockchip'
	UBOOT_TARGET_MAP=";;$SRC/packages/blobs/rockchip/rk3288_boot.bin u-boot-rockchip-with-spl.bin"

	BOOTBRANCH='tag:v2022.04'
	BOOTPATCHDIR='v2022.04'

	if [[ $BOARD == miqi ]]; then
		BOOTBRANCH='tag:v2017.11'
		BOOTPATCHDIR='legacy'
	fi

elif [[ "$BOOT_SOC" == "rk322x" ]]; then

	# enable extension to fix autodetection for Lima driver and x.org
	# on non-legacy kernels
	enable_extension xorg-lima-serverflags

	BOOTSCRIPT="boot-rk322x.cmd:boot.cmd"
	BOOTENV_FILE='rk322x.txt'
	OVERLAY_PREFIX='rk322x'
	UBOOT_TARGET_MAP="all u-boot.itb;;u-boot-rk322x-with-spl.bin"

	BOOTBRANCH='tag:v2022.04'
	BOOTPATCHDIR='v2022.04'

fi

case $BRANCH in

	current)

		declare -g KERNEL_MAJOR_MINOR="6.6" # Major and minor versions of this kernel.
		;;

	edge)

		declare -g KERNEL_MAJOR_MINOR="6.8" # Major and minor versions of this kernel.
		;;

esac

CPUMIN="600000"
CPUMAX="1900000"
GOVERNOR="ondemand"

# write_uboot_platform() and uboot_custom_postprocess() functions are dependent upon SOC,
# so we declare them differently for each supported SOC. Also note that write_uboot_platform()
# is used to install the bootloader in the proper place during live systems upgrade.
if [[ "$BOOT_SOC" == "rk3288" ]]; then

	write_uboot_platform() {

		UBOOT_SRC="u-boot-rockchip-with-spl.bin"

		dd if=/dev/zero of=$2 bs=32k count=63 seek=1 status=noxfer > /dev/null 2>&1
		dd if=$1/$UBOOT_SRC of=$2 bs=32k seek=1 conv=notrunc

	}

	uboot_custom_postprocess() {

		# xt-q8l-v10 requires the original DDR init blob because u-boot does not support LPDDR2 initialization
		# for rk3288 SoC (binary is in sources/rkbin-tools/rk32 path). U-boot is configured to produce a TPL
		# which is thrown away. SPL does some more initial configurations, expecially pinmux for power hold,
		# so reset works more reliably. U-boot image is set to be at sector 0x200 on the eMMC/SD,
		# so we burn it 0x200-0x40 because of the rockchip 0x40 sectors offset.
		if [[ "$BOARD" == "xt-q8l-v10" ]]; then
			run_host_command_logged tools/mkimage -n rk3288 -T rksd -d $SRC/cache/sources/rkbin-tools/rk32/rk3288_ddr_400MHz_v1.08.bin u-boot-rockchip-with-spl.bin
		else
			run_host_command_logged tools/mkimage -n rk3288 -T rksd -d tpl/u-boot-tpl.bin u-boot-rockchip-with-spl.bin
		fi

		run_host_command_logged cat spl/u-boot-spl-dtb.bin >> u-boot-rockchip-with-spl.bin
		run_host_command_logged dd if=u-boot-dtb.img of=u-boot-rockchip-with-spl.bin seek=$((0x200 - 0x40)) conv=notrunc

	}

elif [[ "$BOOT_SOC" == "rk322x" ]]; then

	write_uboot_platform() {

		# Extract the Command Rate bit from existing loader.
		# Some DDR memories have issues with different Command Rate, so we
		# restore the same value after installing the new loader.
		# Note: this has to be done only on live installations (DIR variable
		# is present only during boot loader upgrade on running system)
		# while loop is only for convenient break syntax
		while [[ -n $DIR ]]; do

			# Only applicable to rk322x
			[[ "$BOOT_SOC" != "rk322x" ]] && break

			# Find the signature "a7866565" in the first 128k of the stored running image
			SIGNATURE_OFFSET=$(dd if=$2 bs=128k count=1 2> /dev/null | od -A o -w4 -tx4 | grep 'a7866565' | cut -d " " -f 1)

			# Some command failed, skip the rest
			[[ $? -ne 0 ]] && break

			# No signature found, skip the rest
			[[ -z $SIGNATURE_OFFSET ]] && break

			# Command rate bit is 16 bytes before signature
			CMD_RATE_OFFSET=$(($SIGNATURE_OFFSET - 16))
			CR_BYTE=$(od -A n -t dI -j $CMD_RATE_OFFSET -N 1 $2)

			# No command rate byte for some reason, skip the rest
			[[ -z $CR_BYTE ]] && break

			# Invalid command rate byte (should be 0 or 1), skip the rest
			[[ "$CR_BYTE" -ne 0 && "$CR_BYTE" -ne 1 ]] && break

			# Proceed patching u-boot-rk322x-with-spl.bin, do find the
			# cr bit there too to verify that the position of the CR bit is right
			SIGNATURE_OFFSET=$(dd if=$1/u-boot-rk322x-with-spl.bin bs=128k count=1 2> /dev/null | od -A o -w4 -tx4 | grep 'a7866565' | cut -d " " -f 1)

			# Some command failed, skip the rest
			[[ $? -ne 0 ]] && break

			# No signature found, skip the rest
			[[ -z $SIGNATURE_OFFSET ]] && break

			# Command rate bit is 16 bytes before signature
			CMD_RATE_OFFSET=$(($SIGNATURE_OFFSET - 16))
			DST_BYTE=$(od -A n -t dI -j $CMD_RATE_OFFSET -N 1 $1/u-boot-rk322x-with-spl.bin)

			# Verify command rate byte is 0 or 1
			[[ "$DST_BYTE" -ne 0 && "$DST_BYTE" -ne 1 ]] && break

			# Patch the file
			[[ "$CR_BYTE" -eq 0 ]] && HEX_CR="\x00"
			[[ "$CR_BYTE" -eq 1 ]] && HEX_CR="\x01"

			echo -e $HEX_CR | dd of=$1/u-boot-rk322x-with-spl.bin bs=1 seek=$CMD_RATE_OFFSET count=1 conv=notrunc > /dev/null 2>&1

			# always break the while loop
			break

		done

		UBOOT_SRC="u-boot-rk322x-with-spl.bin"

		dd if=/dev/zero of=$2 bs=32k count=63 seek=1 status=noxfer > /dev/null 2>&1
		dd if=$1/$UBOOT_SRC of=$2 bs=32k seek=1 conv=notrunc

	}

	uboot_custom_postprocess() {

		# We use the rockchip proprietary blob to initialize memory chips
		# instead of letting u-boot doing the job. Such devices, like xt-mx4vr-v01, have DDR2
		# or LPDDR2 memories and the blob is better suited for the job.
		# Also it may come handy when there are different memory flavours among boards, with
		# different timings, specs and frequencies.
		# The rockchip proprietary blob is a drop-in substitute for the u-boot tpl.
		# In case you want to use the u-boot TPL remember to set the proper timing
		# registers in device tree and this command line instead of the other one:
		#
		# 	tools/mkimage -n rk322x -T rksd -d tpl/u-boot-tpl.bin u-boot-rk322x-with-spl.bin
		#

		run_host_command_logged tools/mkimage -n rk322x -T rksd -d $SRC/packages/blobs/rockchip/rk322x_ddr_333MHz_v1.11_2t.bin u-boot-rk322x-with-spl.bin
		run_host_command_logged cat spl/u-boot-spl.bin ">>" u-boot-rk322x-with-spl.bin
		run_host_command_logged dd if=u-boot.itb of=u-boot-rk322x-with-spl.bin seek=$((0x200 - 0x40)) conv=notrunc

	}

fi

family_tweaks() {

	if [[ $BOARD == tinkerboard ]]; then
		chroot_sdcard_apt_get_install rfkill bluetooth bluez bluez-tools
		if [[ -f "$SDCARD/etc/pulse/default.pa" ]]; then
			sed -i -e "/#load-module module-alsa-sink/r $SRC/packages/bsp/rockchip/pulseaudio.txt" "$SDCARD/etc/pulse/default.pa" 2>&1
		else
			display_alert "Can't find pulseaudio config" "${BOARD} - family_tweaks" "warn"
		fi
	fi

	# Create gpio and i2c groups on the build rootfs; they are matched against
	# udev rules to allow non-root user access to these resources
	chroot_sdcard addgroup --system --quiet --gid 900 gpio
	chroot_sdcard addgroup --system --quiet --gid 901 i2c

	return 0

}

family_tweaks_bsp() {
	#Graphics and media
	mkdir -p $destination/etc/udev/rules.d
	mkdir -p $destination/usr/local/bin
	cp $SRC/packages/bsp/rockchip/hdmi.rules $destination/etc/udev/rules.d
	cp $SRC/packages/bsp/rockchip/50-hevc.rules $destination/etc/udev/rules.d
	cp $SRC/packages/bsp/rockchip/50-mali.rules $destination/etc/udev/rules.d
	cp $SRC/packages/bsp/rockchip/50-vpu.rules $destination/etc/udev/rules.d
	cp $SRC/packages/bsp/rockchip/60-media.rules $destination/etc/udev/rules.d
	install -m 755 $SRC/packages/bsp/rockchip/hdmi-hotplug $destination/usr/local/bin

	# Peripheral access for specific groups
	cp $SRC/packages/bsp/rockchip/70-gpio.rules $destination/etc/udev/rules.d
	cp $SRC/packages/bsp/rockchip/71-i2c.rules $destination/etc/udev/rules.d

	# Bluetooth
	install -m 755 $SRC/packages/bsp/rk322x/rtk_hciattach $destination/usr/bin
	cp $SRC/packages/bsp/rk322x/rtk-bluetooth.service $destination/lib/systemd/system/

	# Sound
	cp $SRC/packages/bsp/rockchip/asound.conf $destination/etc/
	cp $SRC/packages/bsp/rockchip/89-pulseaudio-usb.rules $destination/etc/udev/rules.d

	# AP6330 (BCM4330) firmware initramfs hook for in-kernel btbcm driver
	mkdir -p $destination/etc/initramfs-tools/hooks
	install -m 550 $SRC/packages/bsp/rockchip/ap6330-initramfs-firmware $destination/etc/initramfs-tools/hooks

	# esp8089 wifi driver modprobe default configuration options, only for legacy kernel
	mkdir -p $destination/etc/modprobe.d
	if [[ "$BOOT_SOC" == "rk322x" && "$BRANCH" == "legacy" ]]; then
		cp $SRC/packages/bsp/rk322x/esp8089.conf $destination/etc/modprobe.d/esp8089.conf
	fi

	# Board selection script, only for rk322x-box
	if [[ "$BOARD" == "rk322x-box" ]]; then
		install -m 755 $SRC/packages/bsp/rk322x/rk322x-config $destination/usr/sbin
	fi

	return 0 # exit with success

}
