#!/bin/sh
#
# Dump all DSS peripheral registers for DSS0 and DSS1 on AM62Px
# Uses rwmem to read 32-bit registers
# Output format: address: value (all hex)
#

OUTFILE="/tmp/dss_reg_dump_$(date +%Y%m%d_%H%M%S).txt"
DONE=0
TOTAL=0

check_dss_probed() {
    base_addr="$1"
    for dev in /sys/bus/platform/devices/${base_addr}.*; do
        if [ -e "$dev/driver" ]; then
            return 0
        fi
    done
    return 1
}

count_words() {
    echo $@ | wc -w
}

progress_bar() {
    pct=$(( DONE * 100 / TOTAL ))
    filled=$(( pct / 2 ))
    empty=$(( 50 - filled ))
    bar=$(printf '%0.s#' $(seq 1 $filled 2>/dev/null))
    gap=$(printf '%0.s-' $(seq 1 $empty 2>/dev/null))
    printf '\r[%-50s] %3d%% (%d/%d)' "${bar}${gap}" "$pct" "$DONE" "$TOTAL" >&2
}

dump_regs() {
    label="$1"
    base="$2"
    shift 2

    echo "# ${label} (base: $(printf '0x%08X' $base))" >> "$OUTFILE"
    for off in $@; do
        addr=$(( base + off ))
        val=$(rwmem $(printf '0x%08X' $addr) 2>/dev/null | awk '{print $NF}')
        printf '%08x: %s\n' "$addr" "$val" >> "$OUTFILE"
        DONE=$(( DONE + 1 ))
        progress_bar
    done
    echo "" >> "$OUTFILE"
}

# --- Probe check ---

DSS0_PROBED=0
DSS1_PROBED=0

if check_dss_probed "30200000"; then
    DSS0_PROBED=1
    echo "DSS0 (0x30200000): probed" >&2
else
    echo "DSS0 (0x30200000): NOT probed, skipping" >&2
fi

if check_dss_probed "30220000"; then
    DSS1_PROBED=1
    echo "DSS1 (0x30220000): probed" >&2
else
    echo "DSS1 (0x30220000): NOT probed, skipping" >&2
fi

echo "" >&2

if [ "$DSS0_PROBED" -eq 0 ] && [ "$DSS1_PROBED" -eq 0 ]; then
    echo "Neither DSS0 nor DSS1 is probed. Nothing to dump." >&2
    exit 0
fi

# --- Register offset definitions ---

DSS_COMMON="0x0004 0x0008 0x0020 0x0024 0x0028 0x002C 0x0030 0x0040 \
0x0044 0x0048 0x0058 0x005C 0x0070 0x0074 0x007C 0x0080 \
0x0090 0x0094 0x0098 0x009C 0x00A0 0x00A4 0x00A8 0x00AC"

DSS_COMMON1="0x0024 0x0028 0x002C 0x0030 0x0040 0x0044 0x0048 0x0054 \
0x0058 0x005C 0x0070 0x0074 0x007C 0x0080"

DSS_VIDL1="0x0020 0x0024 0x0028 0x002C 0x0030 0x0034 0x0038 0x003C \
0x0040 0x0044 0x0048 0x004C 0x0050 0x0054 0x0058 \
0x01FC 0x0208 0x020C 0x0210 0x0218 0x021C \
0x022C 0x0230 0x0234 0x0238 0x023C 0x0248 \
0x0260 0x0264 0x0268 0x026C 0x0270 0x0274 0x0278 0x027C \
0x0280 0x0284 0x0288 0x028C 0x0290 0x0294 0x0298 0x029C \
0x02A0 0x02A4 0x02A8 0x02AC 0x02B0 0x02B4 0x02B8"

DSS_VID="0x0000 0x0004 0x0008 0x000C 0x0010 0x0014 0x0018 0x001C \
0x0020 0x0024 0x0028 0x002C 0x0030 0x0034 0x0038 0x003C \
0x0040 0x0044 0x0048 0x004C 0x0050 0x0054 0x0058 \
0x005C 0x0060 0x0064 0x0068 \
0x006C 0x0070 0x0074 0x0078 0x007C 0x0080 0x0084 0x0088 0x008C \
0x0090 0x0094 0x0098 0x009C 0x00A0 0x00A4 0x00A8 0x00AC 0x00B0 \
0x00B4 0x00B8 0x00BC 0x00C0 0x00C4 0x00C8 0x00CC 0x00D0 0x00D4 \
0x00D8 0x00DC 0x00E0 0x00E4 0x00E8 0x00EC 0x00F0 \
0x00F4 0x00F8 0x00FC 0x0100 0x0104 0x0108 0x010C 0x0110 0x0114 \
0x0118 0x011C 0x0120 0x0124 0x0128 0x012C 0x0130 \
0x0134 0x0138 0x013C 0x0140 0x0144 0x0148 0x014C 0x0150 0x0154 \
0x0158 0x015C 0x0160 0x0164 0x0168 0x016C 0x0170 0x0174 0x0178 \
0x017C 0x0180 0x0184 0x0188 0x018C 0x0190 0x0194 0x0198 0x019C \
0x01A0 0x01A4 0x01A8 0x01AC 0x01B0 0x01B4 0x01B8 \
0x01BC 0x01C0 0x01C4 0x01C8 0x01CC 0x01D0 0x01D4 0x01D8 0x01DC \
0x01E0 0x01E4 0x01E8 0x01EC 0x01F0 0x01F4 0x01F8 \
0x01FC 0x0208 0x020C 0x0210 0x0218 0x021C 0x0220 \
0x022C 0x0230 0x0234 0x0238 0x023C 0x0248 \
0x0260 0x0264 0x0268 0x026C 0x0270 0x0274 0x0278 0x027C \
0x0280 0x0284 0x0288 0x028C 0x0290 0x0294 0x0298 0x029C \
0x02A0 0x02A4 0x02A8 0x02AC 0x02B0 0x02B4 0x02B8"

DSS_OVR1="0x0000 0x0008 0x000C 0x0010 0x0014 0x0018 0x001C \
0x0020 0x0024 0x0028 0x002C"

DSS_OVR2="0x0000 0x0008 0x000C 0x0010 0x0014 0x0018 0x001C \
0x0020 0x0024 0x0028 0x002C"

DSS_VP1="0x0000 0x0004 0x0008 0x000C 0x0010 0x0014 0x0018 0x001C \
0x0044 0x004C 0x0050 0x0054 0x0058 \
0x005C 0x0060 0x0064 0x0068 0x006C \
0x0070 0x0074 0x0078 0x007C \
0x0090 0x0094 0x0098 0x009C \
0x00B0 0x00B4 0x00B8 0x00BC \
0x00D0 0x00D4 0x00D8 0x00DC \
0x00F0 0x00F4 0x00F8 0x00FC \
0x0110 \
0x0120 0x0124 0x0128 0x012C 0x0130 0x0134 0x0138 0x013C \
0x0140 0x0144 0x0148 0x014C 0x0150 0x0154 0x0158 0x015C \
0x0160 0x0164 0x0168"

DSS_VP2="0x0000 0x0004 0x0008 0x000C 0x0010 0x0014 0x0018 0x001C \
0x0044 0x004C 0x0050 0x0054 0x0058 \
0x005C 0x0060 0x0064 0x0068 0x006C \
0x0070 0x0074 0x0078 0x007C \
0x0090 0x0094 0x0098 0x009C \
0x00B0 0x00B4 0x00B8 0x00BC \
0x00D0 0x00D4 0x00D8 0x00DC \
0x00F0 0x00F4 0x00F8 0x00FC \
0x0110 \
0x0120 0x0124 0x0128 0x012C 0x0130 0x0134 0x0138 0x013C \
0x0140 0x0144 0x0148 0x014C 0x0150 0x0154 0x0158 0x015C \
0x0160 0x0164 0x0168"

# --- Count total registers to dump ---

ALL_GROUPS="$DSS_COMMON $DSS_COMMON1 $DSS_VIDL1 $DSS_VID $DSS_OVR1 $DSS_OVR2 $DSS_VP1 $DSS_VP2"
PER_INSTANCE=$(count_words $ALL_GROUPS)

if [ "$DSS0_PROBED" -eq 1 ]; then
    TOTAL=$(( TOTAL + PER_INSTANCE ))
fi
if [ "$DSS1_PROBED" -eq 1 ]; then
    TOTAL=$(( TOTAL + PER_INSTANCE ))
fi

echo "Dumping $TOTAL registers to $OUTFILE ..." >&2
echo "" >&2

# --- Dump ---

> "$OUTFILE"

if [ "$DSS0_PROBED" -eq 1 ]; then
    echo "###############" >> "$OUTFILE"
    echo "# DSS0" >> "$OUTFILE"
    echo "###############" >> "$OUTFILE"
    echo "" >> "$OUTFILE"
    dump_regs "DSS_COMMON (DSS0)"  0x30200000 $DSS_COMMON
    dump_regs "DSS_COMMON1 (DSS0)" 0x30201000 $DSS_COMMON1
    dump_regs "DSS_VIDL1 (DSS0)"   0x30202000 $DSS_VIDL1
    dump_regs "DSS_VID (DSS0)"     0x30206000 $DSS_VID
    dump_regs "DSS_OVR1 (DSS0)"    0x30207000 $DSS_OVR1
    dump_regs "DSS_OVR2 (DSS0)"    0x30208000 $DSS_OVR2
    dump_regs "DSS_VP1 (DSS0)"     0x3020A000 $DSS_VP1
    dump_regs "DSS_VP2 (DSS0)"     0x3020B000 $DSS_VP2
fi

if [ "$DSS1_PROBED" -eq 1 ]; then
    echo "###############" >> "$OUTFILE"
    echo "# DSS1" >> "$OUTFILE"
    echo "###############" >> "$OUTFILE"
    echo "" >> "$OUTFILE"
    dump_regs "DSS_COMMON (DSS1)"  0x30220000 $DSS_COMMON
    dump_regs "DSS_COMMON1 (DSS1)" 0x30221000 $DSS_COMMON1
    dump_regs "DSS_VIDL1 (DSS1)"   0x30222000 $DSS_VIDL1
    dump_regs "DSS_VID (DSS1)"     0x30226000 $DSS_VID
    dump_regs "DSS_OVR1 (DSS1)"    0x30227000 $DSS_OVR1
    dump_regs "DSS_OVR2 (DSS1)"    0x30228000 $DSS_OVR2
    dump_regs "DSS_VP1 (DSS1)"     0x3022A000 $DSS_VP1
    dump_regs "DSS_VP2 (DSS1)"     0x3022B000 $DSS_VP2
fi

echo "" >&2
echo "Done. Dump saved to: $OUTFILE" >&2
