mirror of
https://github.com/orangepi-xunlong/u-boot-orangepi.git
synced 2026-05-17 08:26:11 +03:00
Add sunxi_spl
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -89,5 +89,3 @@ GTAGS
|
||||
*.orig
|
||||
*~
|
||||
\#*#
|
||||
|
||||
sunxi_spl/
|
||||
|
||||
23
sunxi_spl/.gitignore
vendored
Executable file
23
sunxi_spl/.gitignore
vendored
Executable file
@@ -0,0 +1,23 @@
|
||||
#
|
||||
# NOTE! Don't add files that are generated in specific
|
||||
# subdirectories here. Add them in the ".gitignore" file
|
||||
# in that subdirectory instead.
|
||||
#
|
||||
# Normal rules
|
||||
#
|
||||
|
||||
*.rej
|
||||
*.axf
|
||||
*.map
|
||||
*.bin
|
||||
*.lds
|
||||
*.o
|
||||
*.depend
|
||||
*.cur
|
||||
cur.log
|
||||
include/generated/generic-asm-offsets.h
|
||||
#
|
||||
# Generated files
|
||||
#
|
||||
|
||||
|
||||
137
sunxi_spl/boot0/Makefile
Executable file
137
sunxi_spl/boot0/Makefile
Executable file
@@ -0,0 +1,137 @@
|
||||
#
|
||||
# (C) Copyright 2000-2011
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# (C) Copyright 2011
|
||||
# Daniel Schwierzeck, daniel.schwierzeck@googlemail.com.
|
||||
#
|
||||
# (C) Copyright 2011
|
||||
# Texas Instruments Incorporated - http://www.ti.com/
|
||||
# Aneesh V <aneesh@ti.com>
|
||||
#
|
||||
# This file is released under the terms of GPL v2 and any later version.
|
||||
# See the file COPYING in the root directory of the source tree for details.
|
||||
#
|
||||
# Based on top-level Makefile.
|
||||
#
|
||||
|
||||
include $(SPLDIR)/config.mk
|
||||
include $(TOPDIR)/include/autoconf.mk
|
||||
include $(TOPDIR)/include/autoconf.mk.dep
|
||||
|
||||
CONFIG_SPL := y
|
||||
export CONFIG_SPL
|
||||
|
||||
TOOLS_DIR := $(TOPDIR)/tools
|
||||
|
||||
BOOT0_LDSCRIPT := $(SPLBASE)/sunxi_spl/boot0/main/boot0.lds
|
||||
|
||||
# We want the final binaries in this directory
|
||||
obj := $(SPLBASE)/sunxi_spl/boot0/
|
||||
|
||||
BOOT0_HEAD := sunxi_spl/boot0/boot0_head.o
|
||||
START := sunxi_spl/boot0/boot0_entry.o
|
||||
|
||||
LIBS-y += sunxi_spl/boot0/spl/libsource_spl.o
|
||||
LIBS-y += sunxi_spl/boot0/main/libmain.o
|
||||
LIBS-y += sunxi_spl/boot0/libs/libgeneric.o
|
||||
LIBS-y += sunxi_spl/spl/lib/libgeneric.o
|
||||
LIBS-y += sunxi_spl/dram/$(SOC)/dram/libdram.o
|
||||
LIBS-$(CONFIG_SUNXI_HDMI_IN_BOOT0) += sunxi_spl/display/hdmi/libdisplay.o
|
||||
|
||||
LIBS-$(CONFIG_SUNXI_CHIPID) += sunxi_spl/dram/$(SOC)/dram/libchipid.o
|
||||
LIBS := $(addprefix $(SPLBASE)/,$(sort $(LIBS-y)))
|
||||
|
||||
LIBNAND-$(CONFIG_STORAGE_MEDIA_NAND) += $(SPLBASE)/sunxi_spl/boot0/load_nand/libloadnand.o
|
||||
LIBNAND-$(CONFIG_STORAGE_MEDIA_NAND) += $(TOPDIR)/arch/$(ARCH)/cpu/$(CPU)/$(SOC)/nand/libnand.o
|
||||
LIBNAND-$(CONFIG_STORAGE_MEDIA_SPINAND) += $(TOPDIR)/arch/$(ARCH)/cpu/$(CPU)/$(SOC)/spinand/libspinand.o
|
||||
|
||||
LIBNAND := $(LIBNAND-y)
|
||||
|
||||
LIBMMC-$(CONFIG_STORAGE_MEDIA_MMC) += $(SPLBASE)/sunxi_spl/boot0/load_mmc/libloadmmc.o
|
||||
LIBMMC-$(CONFIG_STORAGE_MEDIA_MMC) += $(TOPDIR)/arch/$(ARCH)/cpu/$(CPU)/$(SOC)/mmc/libmmc.o
|
||||
|
||||
LIBMMC := $(LIBMMC-y)
|
||||
|
||||
|
||||
LIBSPINOR-$(CONFIG_STORAGE_MEDIA_SPINOR) += $(SPLBASE)/sunxi_spl/boot0/load_spinor/libloadspinor.o
|
||||
LIBSPINOR-$(CONFIG_STORAGE_MEDIA_SPINOR) += $(TOPDIR)/arch/$(ARCH)/cpu/$(CPU)/$(SOC)/spinor/libspinor.o
|
||||
|
||||
LIBSPINOR := $(LIBSPINOR-y)
|
||||
|
||||
ifndef CONFIG_BOOT0_SIZE_LIMIT
|
||||
BOOT0SIZE = $(CONFIG_SYS_INIT_RAM_SIZE)
|
||||
else
|
||||
BOOT0SIZE = $(CONFIG_BOOT0_SIZE_LIMIT)
|
||||
endif
|
||||
|
||||
__LIBS := $(subst $(obj),,$(LIBS))
|
||||
|
||||
|
||||
|
||||
# Special flags for CPP when processing the linker script.
|
||||
# Pass the version down so we can handle backwards compatibility
|
||||
# on the fly.
|
||||
LDPPFLAGS += \
|
||||
-include $(TOPDIR)/include/u-boot/u-boot.lds.h \
|
||||
-DBOOT0ADDR=$(CONFIG_BOOT0_RUN_ADDR) \
|
||||
-DBOOT0SIZE=$(BOOT0SIZE) \
|
||||
$(shell $(LD) --version | \
|
||||
sed -ne 's/GNU ld version \([0-9][0-9]*\)\.\([0-9][0-9]*\).*/-DLD_MAJOR=\1 -DLD_MINOR=\2/p')
|
||||
|
||||
ALL-$(CONFIG_STORAGE_MEDIA_NAND) += $(obj)boot0_nand.bin
|
||||
ALL-$(CONFIG_STORAGE_MEDIA_MMC) += $(obj)boot0_sdcard.bin
|
||||
ALL-$(CONFIG_STORAGE_MEDIA_SPINOR) += $(obj)boot0_spinor.bin
|
||||
|
||||
|
||||
all: $(ALL-y)
|
||||
|
||||
$(obj)boot0_nand.bin: $(obj)boot0_nand.axf $(obj)cur.log
|
||||
@echo bootaddr is $(CONFIG_BOOT0_RUN_ADDR)
|
||||
$(OBJCOPY) $(OBJCFLAGS) -O binary $< $@
|
||||
@$(SPLDIR)/../../tools/add_hash.sh -f $(SPLDIR)/boot0/boot0_nand.bin -m boot0
|
||||
|
||||
$(obj)boot0_nand.axf: $(LIBS) $(LIBNAND) $(obj)boot0.lds
|
||||
$(LD) $(LIBS) $(LIBNAND) $(PLATFORM_LIBGCC) $(LDFLAGS) $(LDFLAGS_boot0) -T$(obj)boot0.lds -o boot0_nand.axf -Map boot0_nand.map
|
||||
|
||||
$(obj)boot0_sdcard.bin: $(obj)boot0_sdcard.axf $(obj)cur.log
|
||||
$(OBJCOPY) $(OBJCFLAGS) -O binary $< $@
|
||||
@$(SPLDIR)/../../tools/add_hash.sh -f $(SPLDIR)/boot0/boot0_sdcard.bin -m boot0
|
||||
|
||||
$(obj)boot0_sdcard.axf: $(LIBS) $(LIBMMC) $(obj)boot0.lds
|
||||
$(LD) $(LIBS) $(LIBMMC) $(PLATFORM_LIBGCC) $(LDFLAGS) $(LDFLAGS_boot0) -T$(obj)boot0.lds -o boot0_sdcard.axf -Map boot0_sdcard.map
|
||||
|
||||
$(obj)boot0_spinor.bin: $(obj)boot0_spinor.axf $(obj)cur.log
|
||||
$(OBJCOPY) $(OBJCFLAGS) -O binary $< $@
|
||||
@$(SPLDIR)/../../tools/add_hash.sh -f $(SPLDIR)/boot0/boot0_spinor.bin -m boot0
|
||||
|
||||
$(obj)boot0_spinor.axf: $(LIBS) $(LIBSPINOR) $(obj)boot0.lds
|
||||
$(LD) $(LIBS) $(LIBSPINOR) $(PLATFORM_LIBGCC) $(LDFLAGS) $(LDFLAGS_boot0) -T$(obj)boot0.lds -o boot0_spinor.axf -Map boot0_spinor.map
|
||||
|
||||
$(LIBS): depend
|
||||
$(MAKE) -C $(SRCTREE)$(dir $(subst $(OBJTREE),,$@))
|
||||
|
||||
$(LIBNAND): depend
|
||||
$(MAKE) -C $(SRCTREE)$(dir $(subst $(OBJTREE),,$@))
|
||||
|
||||
$(LIBMMC): depend
|
||||
$(MAKE) -C $(SRCTREE)$(dir $(subst $(OBJTREE),,$@))
|
||||
|
||||
$(LIBSPINOR): depend
|
||||
$(MAKE) -C $(SRCTREE)$(dir $(subst $(OBJTREE),,$@))
|
||||
|
||||
$(obj)boot0.lds: $(BOOT0_LDSCRIPT)
|
||||
@$(CPP) $(ALL_CFLAGS) $(LDPPFLAGS) -ansi -D__ASSEMBLY__ -P - <$^ >$@
|
||||
|
||||
$(obj)cur.log:
|
||||
@git show HEAD --pretty=format:"%H" | head -n 1 > cur.log
|
||||
|
||||
depend: .depend
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude .depend
|
||||
|
||||
#########################################################################
|
||||
38
sunxi_spl/boot0/libs/Makefile
Executable file
38
sunxi_spl/boot0/libs/Makefile
Executable file
@@ -0,0 +1,38 @@
|
||||
|
||||
##
|
||||
## Makefile for Sunxi Secure Boot
|
||||
##
|
||||
|
||||
|
||||
|
||||
include $(SPLDIR)/config.mk
|
||||
|
||||
LIB := $(lib)libgeneric.o
|
||||
|
||||
COBJS += check.o
|
||||
COBJS += nand_misc.o
|
||||
COBJS += mmu.o
|
||||
COBJS += eabi_compat.o
|
||||
#COBJS += jmp.o
|
||||
COBJS += common.o
|
||||
|
||||
SOBJS += jmpto64.o memcpy_align16.o
|
||||
|
||||
SOBJS := $(SOBJS)
|
||||
COBJS := $(COBJS)
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
|
||||
|
||||
all: $(obj).depend $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
66
sunxi_spl/boot0/libs/check.c
Executable file
66
sunxi_spl/boot0/libs/check.c
Executable file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* (C) Copyright 2013-2020
|
||||
* Allwinner Technology Co., Ltd. <www.allwinnertech.com>
|
||||
* wangwei <wangflord@allwinnertech.com>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "private_toc.h"
|
||||
#include <private_uboot.h>
|
||||
|
||||
|
||||
int verify_addsum( void *mem_base, __u32 size )
|
||||
{
|
||||
__u32 *buf;
|
||||
__u32 count;
|
||||
__u32 src_sum;
|
||||
__u32 sum;
|
||||
sbrom_toc1_head_info_t *bfh;
|
||||
|
||||
bfh = (sbrom_toc1_head_info_t *)mem_base;
|
||||
/*generate checksum*/
|
||||
src_sum = bfh->add_sum;
|
||||
bfh->add_sum = STAMP_VALUE;
|
||||
count = size >> 2;
|
||||
sum = 0;
|
||||
buf = (__u32 *)mem_base;
|
||||
do
|
||||
{
|
||||
sum += *buf++;
|
||||
sum += *buf++;
|
||||
sum += *buf++;
|
||||
sum += *buf++;
|
||||
}while( ( count -= 4 ) > (4-1) );
|
||||
|
||||
while( count-- > 0 )
|
||||
sum += *buf++;
|
||||
|
||||
bfh->add_sum = src_sum;
|
||||
|
||||
// printf("sum=%x\n", sum);
|
||||
// printf("src_sum=%x\n", src_sum);
|
||||
|
||||
//check: 0-success -1:fail
|
||||
if( sum == src_sum )
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
68
sunxi_spl/boot0/libs/common.c
Executable file
68
sunxi_spl/boot0/libs/common.c
Executable file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* (C) Copyright 2007-2013
|
||||
* Allwinner Technology Co., Ltd. <www.allwinnertech.com>
|
||||
* Young <guoyingyang@allwinnertech.com>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "asm/armv7.h"
|
||||
#include <private_boot0.h>
|
||||
#include <asm/arch/uart.h>
|
||||
#include <boot0_helper.h>
|
||||
|
||||
extern const boot0_file_head_t BT0_head;
|
||||
extern int debug_enable;
|
||||
/*
|
||||
************************************************************************************************************
|
||||
*
|
||||
* function
|
||||
*
|
||||
* name :set_debugmode_flag
|
||||
*
|
||||
* parmeters :void
|
||||
*
|
||||
* return :
|
||||
*
|
||||
* note :if BT0_head.prvt_head.debug_mode_off = 1,do not print any message to uart
|
||||
*
|
||||
*
|
||||
************************************************************************************************************
|
||||
*/
|
||||
|
||||
int set_debugmode_flag(void)
|
||||
{
|
||||
char c = 0;
|
||||
|
||||
c = get_uart_input();
|
||||
if(c == 'd')
|
||||
{
|
||||
debug_enable = LOG_LEVEL_INFO;
|
||||
return c;
|
||||
}
|
||||
|
||||
if(BT0_head.prvt_head.debug_mode)
|
||||
debug_enable = BT0_head.prvt_head.debug_mode;
|
||||
else
|
||||
debug_enable = 0;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
22
sunxi_spl/boot0/libs/eabi_compat.c
Normal file
22
sunxi_spl/boot0/libs/eabi_compat.c
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Utility functions needed for (some) EABI conformant tool chains.
|
||||
*
|
||||
* (C) Copyright 2009 Wolfgang Denk <wd@denx.de>
|
||||
*
|
||||
* This program is Free Software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
int raise (int signum)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Dummy function to avoid linker complaints */
|
||||
void __aeabi_unwind_cpp_pr0(void)
|
||||
{
|
||||
};
|
||||
20
sunxi_spl/boot0/libs/jmpto64.S
Executable file
20
sunxi_spl/boot0/libs/jmpto64.S
Executable file
@@ -0,0 +1,20 @@
|
||||
|
||||
|
||||
|
||||
|
||||
.globl RMR_TO64
|
||||
|
||||
RMR_TO64:
|
||||
MRC p15,0,r1,c12,c0,2
|
||||
ORR r1,r1,#(0x3<<0)
|
||||
DSB
|
||||
MCR p15,0,r1,c12,c0,2
|
||||
ISB
|
||||
|
||||
Loop1:
|
||||
WFI
|
||||
B Loop1
|
||||
BX lr
|
||||
|
||||
|
||||
|
||||
28
sunxi_spl/boot0/libs/memcpy_align16.S
Normal file
28
sunxi_spl/boot0/libs/memcpy_align16.S
Normal file
@@ -0,0 +1,28 @@
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/assembler.h>
|
||||
|
||||
/*
|
||||
* void *memcpy_align_16(void *dest, const void *src, size_t n);
|
||||
*
|
||||
* note: the size must be 16 bytes align.
|
||||
*
|
||||
*/
|
||||
|
||||
ENTRY(memcpy_align16)
|
||||
stmfd sp!, {r4-r10, lr}
|
||||
mov r4,r1 /* r4 is the source address */
|
||||
mov r5,r0 /* r5 is the dest address */
|
||||
|
||||
mov r10,r1
|
||||
add r10,r10,r2 /* r10 is the end address */
|
||||
|
||||
copy_loop:
|
||||
ldmia r4!, {r6-r9} /* copy from source address [r4] */
|
||||
stmia r5!, {r6-r9} /* copy to target address [r5] */
|
||||
cmp r4, r10 /* until source end address [r10] */
|
||||
blo copy_loop
|
||||
|
||||
ldmfd sp!, {r4-r10, pc}
|
||||
ENDPROC(memcpy_align16)
|
||||
|
||||
|
||||
120
sunxi_spl/boot0/libs/mmu.c
Executable file
120
sunxi_spl/boot0/libs/mmu.c
Executable file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* (C) Copyright 2007-2013
|
||||
* Allwinner Technology Co., Ltd. <www.allwinnertech.com>
|
||||
* Jerry Wang <wangflord@allwinnertech.com>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "asm/arch/archdef.h"
|
||||
#include "asm/arch/timer.h"
|
||||
/*
|
||||
************************************************************************************************************
|
||||
*
|
||||
* function
|
||||
*
|
||||
* name :
|
||||
*
|
||||
* parmeters :
|
||||
*
|
||||
* return :
|
||||
*
|
||||
* note :
|
||||
*
|
||||
*
|
||||
************************************************************************************************************
|
||||
*/
|
||||
void mmu_setup(u32 dram_size)
|
||||
{
|
||||
u32 mmu_base;
|
||||
//u32 *page_table = (u32 *)BOOT0_MMU_BASE_ADDRESS;
|
||||
//use dram high 16M
|
||||
u32* mmu_base_addr = (u32 *)(PLAT_SDRAM_BASE +((dram_size-16)<<20));
|
||||
u32* page_table = mmu_base_addr;
|
||||
|
||||
int i;
|
||||
u32 reg;
|
||||
|
||||
page_table[0] = (3 << 10) | (15 << 5) | (1 << 3) | (0 << 2) | 0x2;
|
||||
/* the front 1G of memory(treated as 4G for all) is set up as none cacheable */
|
||||
for (i = 1; i < (PLAT_SDRAM_BASE>>20); i++)
|
||||
page_table[i] = (i << 20) | (3 << 10) | (15 << 5) | (0 << 3) | 0x2;
|
||||
/* Set up as write through and buffered(not write back) for other 3GB, rw for everyone */
|
||||
for (i = (PLAT_SDRAM_BASE>>20); i < 4096; i++)
|
||||
page_table[i] = (i << 20) | (3 << 10) | (15 << 5) | (1 << 3) | (0 << 2) | 0x2;
|
||||
/* flush tlb */
|
||||
asm volatile("mcr p15, 0, %0, c8, c7, 0" : : "r" (0));
|
||||
/* Copy the page table address to cp15 */
|
||||
|
||||
mmu_base = (u32)mmu_base_addr;
|
||||
mmu_base |= (1 << 0) | (1 << 1) | (2 << 3);
|
||||
asm volatile("mcr p15, 0, %0, c2, c0, 0"
|
||||
: : "r" (mmu_base) : "memory");
|
||||
asm volatile("mcr p15, 0, %0, c2, c0, 1"
|
||||
: : "r" (mmu_base) : "memory");
|
||||
/* Set the access control to all-supervisor */
|
||||
asm volatile("mcr p15, 0, %0, c3, c0, 0"
|
||||
: : "r" (0x55555555)); //modified, origin value is (~0)
|
||||
asm volatile("isb");
|
||||
/* and enable the mmu */
|
||||
asm volatile("mrc p15, 0, %0, c1, c0, 0 @ get CR" : "=r" (reg) : : "cc");
|
||||
|
||||
__usdelay(100);
|
||||
reg |= ((5<<0)|(1<<12)); //enable mmu, icache, dcache
|
||||
asm volatile("mcr p15, 0, %0, c1, c0, 0 @ set CR" : : "r" (reg) : "cc");
|
||||
asm volatile("isb");
|
||||
}
|
||||
/*
|
||||
************************************************************************************************************
|
||||
*
|
||||
* function
|
||||
*
|
||||
* name :
|
||||
*
|
||||
* parmeters :
|
||||
*
|
||||
* return :
|
||||
*
|
||||
* note :
|
||||
*
|
||||
*
|
||||
************************************************************************************************************
|
||||
*/
|
||||
void mmu_turn_off( void )
|
||||
{
|
||||
uint reg;
|
||||
/* and disable the mmu */
|
||||
asm volatile("mrc p15, 0, %0, c1, c0, 0 @ get CR" : "=r" (reg) : : "cc");
|
||||
__usdelay(100);
|
||||
reg &= ~((7<<0)|(1<<12)); //disable mmu
|
||||
asm volatile("mcr p15, 0, %0, c1, c0, 0 @ set CR" : : "r" (reg) : "cc");
|
||||
ARCHISB;
|
||||
/*
|
||||
* Invalidate all instruction caches to PoU.
|
||||
* Also flushes branch target cache.
|
||||
*/
|
||||
asm volatile ("mcr p15, 0, %0, c7, c5, 0" : : "r" (0));
|
||||
/* Invalidate entire branch predictor array */
|
||||
asm volatile ("mcr p15, 0, %0, c7, c5, 6" : : "r" (0));
|
||||
/* Full system DSB - make sure that the invalidation is complete */
|
||||
ARCHDSB;
|
||||
/* ISB - make sure the instruction stream sees it */
|
||||
ARCHISB;
|
||||
}
|
||||
202
sunxi_spl/boot0/libs/nand_misc.c
Executable file
202
sunxi_spl/boot0/libs/nand_misc.c
Executable file
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
**********************************************************************************************************************
|
||||
*
|
||||
* the Embedded Secure Bootloader System
|
||||
*
|
||||
*
|
||||
* Copyright(C), 2006-2014, Allwinnertech Co., Ltd.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File :
|
||||
*
|
||||
* By :
|
||||
*
|
||||
* Version : V2.00
|
||||
*
|
||||
* Date :
|
||||
*
|
||||
* Descript:
|
||||
**********************************************************************************************************************
|
||||
*/
|
||||
#include "common.h"
|
||||
#include <private_boot0.h>
|
||||
#include <private_uboot.h>
|
||||
#include <asm/arch/dram.h>
|
||||
#include <asm/arch/uart.h>
|
||||
|
||||
extern const boot0_file_head_t BT0_head;
|
||||
void set_pll( void );
|
||||
|
||||
|
||||
#ifdef FPGA_PLATFORM
|
||||
//---------------------------------------------------------------
|
||||
// 结构体 定义
|
||||
//---------------------------------------------------------------
|
||||
typedef struct
|
||||
{
|
||||
__u32 ChannelCnt;
|
||||
__u32 ChipCnt; //the count of the total nand flash chips are currently connecting on the CE pin
|
||||
__u32 ChipConnectInfo; //chip connect information, bit == 1 means there is a chip connecting on the CE pin
|
||||
__u32 RbCnt;
|
||||
__u32 RbConnectInfo; //the connect information of the all rb chips are connected
|
||||
__u32 RbConnectMode; //the rb connect mode
|
||||
__u32 BankCntPerChip; //the count of the banks in one nand chip, multiple banks can support Inter-Leave
|
||||
__u32 DieCntPerChip; //the count of the dies in one nand chip, block management is based on Die
|
||||
__u32 PlaneCntPerDie; //the count of planes in one die, multiple planes can support multi-plane operation
|
||||
__u32 SectorCntPerPage; //the count of sectors in one single physic page, one sector is 0.5k
|
||||
__u32 PageCntPerPhyBlk; //the count of physic pages in one physic block
|
||||
__u32 BlkCntPerDie; //the count of the physic blocks in one die, include valid block and invalid block
|
||||
__u32 OperationOpt; //the mask of the operation types which current nand flash can support support
|
||||
__u32 FrequencePar; //the parameter of the hardware access clock, based on 'MHz'
|
||||
__u32 EccMode; //the Ecc Mode for the nand flash chip, 0: bch-16, 1:bch-28, 2:bch_32
|
||||
__u8 NandChipId[8]; //the nand chip id of current connecting nand chip
|
||||
__u32 ValidBlkRatio; //the ratio of the valid physical blocks, based on 1024
|
||||
__u32 good_block_ratio; //good block ratio get from hwscan
|
||||
__u32 ReadRetryType; //the read retry type
|
||||
__u32 DDRType;
|
||||
__u32 uboot_start_block;
|
||||
__u32 uboot_next_block;
|
||||
__u32 logic_start_block;
|
||||
__u32 nand_specialinfo_page;
|
||||
__u32 nand_specialinfo_offset;
|
||||
__u32 physic_block_reserved;
|
||||
__u32 random_cmd2_send_flag; //special nand cmd for some nand in batch cmd, only for write
|
||||
__u32 random_addr_num; //random col addr num in batch cmd
|
||||
__u32 nand_real_page_size;
|
||||
__u32 Reserved[13];
|
||||
|
||||
}boot_nand_para_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
************************************************************************************************************
|
||||
*
|
||||
* function
|
||||
*
|
||||
* name :
|
||||
*
|
||||
* parmeters :
|
||||
*
|
||||
* return :
|
||||
*
|
||||
* note :
|
||||
*
|
||||
*
|
||||
************************************************************************************************************
|
||||
*/
|
||||
int BOOT_NandGetPara(void *param, uint size)
|
||||
{
|
||||
#if 0 //FPGA_PLATFORM
|
||||
boot_nand_para_t *nand_para = (boot_nand_para_t *)param;
|
||||
//sand disk flash on fpga
|
||||
nand_para->ChannelCnt=1;
|
||||
nand_para->ChipCnt = 1;
|
||||
nand_para->ChipConnectInfo = 1;
|
||||
nand_para->RbCnt = 1;
|
||||
nand_para->RbConnectInfo = 1;
|
||||
nand_para->RbConnectMode = 1;
|
||||
nand_para->BankCntPerChip = 1;
|
||||
nand_para->DieCntPerChip = 1;
|
||||
nand_para->PlaneCntPerDie = 1;
|
||||
nand_para->SectorCntPerPage = 32;
|
||||
nand_para->PageCntPerPhyBlk = 512;
|
||||
nand_para->BlkCntPerDie = 2048;
|
||||
nand_para->OperationOpt = 0x1f041788;
|
||||
nand_para->FrequencePar = 40;
|
||||
nand_para->EccMode = 4;
|
||||
memset(nand_para->NandChipId, 0xff, 8);
|
||||
nand_para->NandChipId[0] = 0x2c;
|
||||
nand_para->NandChipId[1] = 0x84;
|
||||
nand_para->NandChipId[2] = 0x64;
|
||||
nand_para->NandChipId[3] = 0x3c;
|
||||
nand_para->NandChipId[4] = 0xa5;
|
||||
nand_para->ValidBlkRatio = 900;
|
||||
nand_para->good_block_ratio = 960;
|
||||
nand_para->ReadRetryType = 0x400a01;
|
||||
nand_para->DDRType = 0;
|
||||
|
||||
nand_para->uboot_start_block=4;
|
||||
nand_para->uboot_next_block=12;
|
||||
|
||||
nand_para->logic_start_block=4;
|
||||
nand_para->nand_specialinfo_page=1;
|
||||
nand_para->nand_specialinfo_offset=1;
|
||||
nand_para->physic_block_reserved=0;
|
||||
nand_para->random_cmd2_send_flag=0;
|
||||
nand_para->random_addr_num=0;
|
||||
nand_para->nand_real_page_size=16384+1216;
|
||||
|
||||
#else
|
||||
memcpy( (void *)param, BT0_head.prvt_head.storage_data, size);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
************************************************************************************************************
|
||||
*
|
||||
* function
|
||||
*
|
||||
* name :
|
||||
*
|
||||
* parmeters :
|
||||
*
|
||||
* return :
|
||||
*
|
||||
* note :
|
||||
*
|
||||
*
|
||||
************************************************************************************************************
|
||||
*/
|
||||
__u8 *get_page_buf( void )
|
||||
{
|
||||
|
||||
return (__u8 *)(CONFIG_SYS_SDRAM_BASE + 1024 * 1024);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*函数名称: g_mod
|
||||
*函数原型:uint32 g_mod( __u32 dividend, __u32 divisor, __u32 *quot_p )
|
||||
*函数功能: 从nand flash的某一块中找到一个完好备份将其载入到RAM中。如果成功,返
|
||||
* 回OK;否则,返回ERROR。
|
||||
*入口参数: dividend 输入。被除数
|
||||
* divisor 输入。除数
|
||||
* quot_p 输出。商
|
||||
*返 回 值: 余数
|
||||
*******************************************************************************/
|
||||
__u32 g_mod( __u32 dividend, __u32 divisor, __u32 *quot_p )
|
||||
{
|
||||
if( divisor == 0 )
|
||||
{
|
||||
*quot_p = 0;
|
||||
return 0;
|
||||
}
|
||||
if( divisor == 1 )
|
||||
{
|
||||
*quot_p = dividend;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for( *quot_p = 0; dividend >= divisor; ++(*quot_p) )
|
||||
dividend -= divisor;
|
||||
return dividend;
|
||||
}
|
||||
|
||||
|
||||
void set_dram_para(void *dram_addr , __u32 dram_size, __u32 boot_cpu)
|
||||
{
|
||||
struct spare_boot_head_t *uboot_buf = (struct spare_boot_head_t *)CONFIG_SYS_TEXT_BASE;
|
||||
|
||||
memcpy((void *)uboot_buf->boot_data.dram_para, dram_addr, 32 * sizeof(int));
|
||||
#ifdef CONFIG_BOOT_A15
|
||||
uboot_buf->boot_data.reserved[0] = boot_cpu;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
extern const boot0_file_head_t BT0_head;
|
||||
|
||||
void cpu_init_s(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
35
sunxi_spl/boot0/libs/sbrom_libs.h
Normal file
35
sunxi_spl/boot0/libs/sbrom_libs.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
**********************************************************************************************************************
|
||||
*
|
||||
* the Embedded Secure Bootloader System
|
||||
*
|
||||
*
|
||||
* Copyright(C), 2006-2014, Allwinnertech Co., Ltd.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File :
|
||||
*
|
||||
* By :
|
||||
*
|
||||
* Version : V2.00
|
||||
*
|
||||
* Date :
|
||||
*
|
||||
* Descript:
|
||||
**********************************************************************************************************************
|
||||
*/
|
||||
#ifndef __SBORM_LIBS_H__
|
||||
#define __SBORM_LIBS_H__
|
||||
|
||||
|
||||
extern void mmu_setup(void);
|
||||
extern void mmu_turn_off(void);
|
||||
|
||||
extern int create_heap(unsigned int pHeapHead, unsigned int nHeapSize);
|
||||
|
||||
extern unsigned int go_exec (unsigned int run_addr, unsigned int para_addr, int out_secure);
|
||||
|
||||
void boot0_jump(unsigned int addr);
|
||||
|
||||
#endif
|
||||
|
||||
29
sunxi_spl/boot0/load_mmc/Makefile
Executable file
29
sunxi_spl/boot0/load_mmc/Makefile
Executable file
@@ -0,0 +1,29 @@
|
||||
|
||||
##
|
||||
## Makefile for Sunxi Secure Boot
|
||||
##
|
||||
|
||||
|
||||
|
||||
include $(SPLDIR)/config.mk
|
||||
|
||||
LIB := $(obj)libloadmmc.o
|
||||
|
||||
COBJS-y += load_boot1_from_sdmmc.o
|
||||
|
||||
SRCS := $(COBJS-y:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS-y))
|
||||
|
||||
all: $(obj).depend $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
187
sunxi_spl/boot0/load_mmc/load_boot1_from_sdmmc.c
Executable file
187
sunxi_spl/boot0/load_mmc/load_boot1_from_sdmmc.c
Executable file
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* eGON
|
||||
* the Embedded GO-ON Bootloader System
|
||||
*
|
||||
* Copyright(C), 2006-2009, SoftWinners Microelectronic Co., Ltd.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File Name : load_boot1_from_sdmmc.c
|
||||
*
|
||||
* Author : Gary.Wang
|
||||
*
|
||||
* Version : 1.1.0
|
||||
*
|
||||
* Date : 2009.12.08
|
||||
*
|
||||
* Description :
|
||||
*
|
||||
* Others : None at present.
|
||||
*
|
||||
*
|
||||
* History :
|
||||
*
|
||||
* <Author> <time> <version> <description>
|
||||
*
|
||||
* Gary.Wang 2009.12.08 1.1.0 build the file
|
||||
*
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
#include "common.h"
|
||||
#include "spare_head.h"
|
||||
#include "private_boot0.h"
|
||||
#include "private_uboot.h"
|
||||
#include <private_toc.h>
|
||||
#include <asm/arch/mmc_boot0.h>
|
||||
|
||||
extern __s32 check_magic( __u32 *mem_base, const char *magic );
|
||||
extern int verify_addsum( void *mem_base, __u32 size );
|
||||
|
||||
|
||||
extern const boot0_file_head_t BT0_head;
|
||||
|
||||
enum {
|
||||
E_SDMMC_OK = 0,
|
||||
E_SDMMC_NUM_ERR = 1,
|
||||
E_SDMMC_INIT_ERR = 2,
|
||||
E_SDMMC_READ_ERR = 3,
|
||||
E_SDMMC_FIND_BOOT1_ERR =4,
|
||||
};
|
||||
|
||||
|
||||
typedef struct _boot_sdcard_info_t
|
||||
{
|
||||
__s32 card_ctrl_num; //总共的卡的个数
|
||||
__s32 boot_offset; //指定卡启动之后,逻辑和物理分区的管理
|
||||
__s32 card_no[4]; //当前启动的卡号, 16-31:GPIO编号,0-15:实际卡控制器编号
|
||||
__s32 speed_mode[4]; //卡的速度模式,0:低速,其它:高速
|
||||
__s32 line_sel[4]; //卡的线制,0: 1线,其它,4线
|
||||
__s32 line_count[4]; //卡使用线的个数
|
||||
}
|
||||
boot_sdcard_info_t;
|
||||
|
||||
//card num: 0-sd 1-card3 2-emmc
|
||||
int get_card_num(void)
|
||||
{
|
||||
int card_num = 0;
|
||||
|
||||
card_num = BT0_head.boot_head.platform[0] & 0xf;
|
||||
card_num = (card_num == 1)? 3: card_num;
|
||||
return card_num;
|
||||
}
|
||||
|
||||
void update_flash_para(void)
|
||||
{
|
||||
int card_num;
|
||||
struct spare_boot_head_t *bfh = (struct spare_boot_head_t *) CONFIG_SYS_TEXT_BASE;
|
||||
card_num = get_card_num();
|
||||
if(card_num == 0)
|
||||
{
|
||||
bfh->boot_data.storage_type = STORAGE_SD;
|
||||
}
|
||||
else if(card_num == 2)
|
||||
{
|
||||
bfh->boot_data.storage_type = STORAGE_EMMC;
|
||||
set_mmc_para(2,(void *)&BT0_head.prvt_head.storage_data);
|
||||
}
|
||||
else if(card_num == 3)
|
||||
{
|
||||
bfh->boot_data.storage_type = STORAGE_EMMC3;
|
||||
set_mmc_para(3,(void *)&BT0_head.prvt_head.storage_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int load_toc1_from_sdmmc(char *buf)
|
||||
{
|
||||
u8 *tmp_buff = (u8 *)CONFIG_BOOTPKG_STORE_IN_DRAM_BASE;
|
||||
uint total_size;
|
||||
sbrom_toc1_head_info_t *toc1_head;
|
||||
int card_no;
|
||||
int ret =0;
|
||||
int start_sector,i;
|
||||
int error_num = E_SDMMC_OK;
|
||||
int start_sectors[4] = {UBOOT_START_SECTOR_IN_SDMMC,UBOOT_BACKUP_START_SECTOR_IN_SDMMC,0,0};
|
||||
boot_sdcard_info_t *sdcard_info = (boot_sdcard_info_t *)buf;
|
||||
|
||||
card_no = get_card_num();
|
||||
|
||||
printf("card no is %d\n", card_no);
|
||||
if(card_no < 0)
|
||||
{
|
||||
error_num = E_SDMMC_NUM_ERR;
|
||||
goto __ERROR_EXIT;
|
||||
}
|
||||
|
||||
if(!sdcard_info->line_sel[card_no])
|
||||
{
|
||||
sdcard_info->line_sel[card_no] = 4;
|
||||
}
|
||||
printf("sdcard %d line count %d\n", card_no, sdcard_info->line_sel[card_no] );
|
||||
|
||||
if( sunxi_mmc_init(card_no, sdcard_info->line_sel[card_no], BT0_head.prvt_head.storage_gpio, 16, (void *)(sdcard_info) ) == -1)
|
||||
{
|
||||
error_num = E_SDMMC_INIT_ERR;
|
||||
goto __ERROR_EXIT;;
|
||||
}
|
||||
|
||||
for(i=0; i < 4; i++)
|
||||
{
|
||||
start_sector = start_sectors[i];
|
||||
tmp_buff = (u8 *)CONFIG_BOOTPKG_STORE_IN_DRAM_BASE;
|
||||
if(start_sector == 0)
|
||||
{
|
||||
error_num = E_SDMMC_FIND_BOOT1_ERR;
|
||||
goto __ERROR_EXIT;
|
||||
}
|
||||
ret = mmc_bread(card_no, start_sector, 64, tmp_buff);
|
||||
if(!ret)
|
||||
{
|
||||
error_num = E_SDMMC_READ_ERR;
|
||||
goto __ERROR_EXIT;
|
||||
}
|
||||
toc1_head = (struct sbrom_toc1_head_info *)tmp_buff;
|
||||
if(toc1_head->magic != TOC_MAIN_INFO_MAGIC)
|
||||
{
|
||||
printf("error:bad magic.\n");
|
||||
continue;
|
||||
}
|
||||
total_size = toc1_head->valid_len;
|
||||
if(total_size > 64 * 512)
|
||||
{
|
||||
tmp_buff += 64*512;
|
||||
ret = mmc_bread(card_no, start_sector + 64, (total_size - 64*512 + 511)/512, tmp_buff);
|
||||
if(!ret)
|
||||
{
|
||||
error_num = E_SDMMC_READ_ERR;
|
||||
goto __ERROR_EXIT;
|
||||
}
|
||||
}
|
||||
|
||||
if( verify_addsum( (__u32 *)CONFIG_BOOTPKG_STORE_IN_DRAM_BASE, total_size) != 0 )
|
||||
{
|
||||
printf("error:bad checksum.\n");
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
printf("Loading boot-pkg Succeed(index=%d).\n",
|
||||
(BT0_head.boot_head.platform[0] & 0xf0)>>4);
|
||||
sunxi_mmc_exit( card_no, BT0_head.prvt_head.storage_gpio, 16 );
|
||||
return 0;
|
||||
|
||||
__ERROR_EXIT:
|
||||
printf("Loading boot-pkg fail(error=%d)\n",error_num);
|
||||
sunxi_mmc_exit(card_no, BT0_head.prvt_head.storage_gpio, 16 );
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int load_boot1(void)
|
||||
{
|
||||
memcpy((void *)DRAM_PARA_STORE_ADDR, (void *)BT0_head.prvt_head.dram_para,
|
||||
SUNXI_DRAM_PARA_MAX * 4);
|
||||
|
||||
return load_toc1_from_sdmmc((char *)BT0_head.prvt_head.storage_data);
|
||||
}
|
||||
29
sunxi_spl/boot0/load_nand/Makefile
Executable file
29
sunxi_spl/boot0/load_nand/Makefile
Executable file
@@ -0,0 +1,29 @@
|
||||
|
||||
##
|
||||
## Makefile for Sunxi Secure Boot
|
||||
##
|
||||
|
||||
|
||||
|
||||
include $(SPLDIR)/config.mk
|
||||
|
||||
LIB := $(obj)libloadnand.o
|
||||
|
||||
COBJS-y += load_Boot1_from_nand.o
|
||||
|
||||
SRCS := $(COBJS-y:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS-y))
|
||||
|
||||
all: $(obj).depend $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
234
sunxi_spl/boot0/load_nand/load_Boot1_from_nand.c
Executable file
234
sunxi_spl/boot0/load_nand/load_Boot1_from_nand.c
Executable file
@@ -0,0 +1,234 @@
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* eGON
|
||||
* the Embedded GO-ON Bootloader System
|
||||
*
|
||||
* Copyright(C), 2006-2008, SoftWinners Microelectronic Co., Ltd.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File Name : load_Boot1_from_nand.c
|
||||
*
|
||||
* Author : Gary.Wang
|
||||
*
|
||||
* Version : 1.1.0
|
||||
*
|
||||
* Date : 2007.10.14
|
||||
*
|
||||
* Description : This file provides a function "load_Boot1_from_nand" to load a good copy of Boot1
|
||||
* from outside nand flash chips to SRAM.
|
||||
*
|
||||
* Others : None at present.
|
||||
*
|
||||
*
|
||||
* History :
|
||||
*
|
||||
* <Author> <time> <version> <description>
|
||||
*
|
||||
* Gary.Wang 2007.10.14 1.1.0 build the file
|
||||
*
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
//#include "load_Boot1_from_nand_i.h"
|
||||
#include "common.h"
|
||||
#include "spare_head.h"
|
||||
#include "private_uboot.h"
|
||||
#include "asm/arch/nand_boot0.h"
|
||||
#include <private_toc.h>
|
||||
#include "private_boot0.h"
|
||||
|
||||
extern const boot0_file_head_t BT0_head;
|
||||
|
||||
void update_flash_para(void)
|
||||
{
|
||||
#ifdef CONFIG_STORAGE_MEDIA_SPINAND
|
||||
struct spare_boot_head_t *bfh = (struct spare_boot_head_t *) CONFIG_SYS_TEXT_BASE;
|
||||
|
||||
bfh->boot_data.storage_type = (BT0_head.boot_head.platform[0]&0xf) == 4 ? \
|
||||
STORAGE_SPI_NAND : STORAGE_NAND ;
|
||||
#endif
|
||||
}
|
||||
|
||||
extern int verify_addsum( void *mem_base, __u32 size );
|
||||
/*
|
||||
************************************************************************************************************
|
||||
*
|
||||
* function
|
||||
*
|
||||
* name :load_Boot1_from_nand
|
||||
*
|
||||
* parmeters :void
|
||||
*
|
||||
* return :0--success, -1--fail
|
||||
*
|
||||
* note :
|
||||
*
|
||||
*
|
||||
************************************************************************************************************
|
||||
*/
|
||||
|
||||
int load_toc1_from_nand( void )
|
||||
{
|
||||
__u32 i;
|
||||
__s32 status;
|
||||
__u32 length;
|
||||
__u32 read_blks;
|
||||
sbrom_toc1_head_info_t *toc1_head;
|
||||
char *buffer = (void*)CONFIG_BOOTPKG_STORE_IN_DRAM_BASE;
|
||||
|
||||
if(NF_open( ) == NF_ERROR)
|
||||
{
|
||||
printf("fail in opening nand flash\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("block from %d to %d\n", BOOT1_START_BLK_NUM, BOOT1_LAST_BLK_NUM);
|
||||
for( i = BOOT1_START_BLK_NUM; i <= BOOT1_LAST_BLK_NUM; i++ )
|
||||
{
|
||||
if( NF_read_status( i ) == NF_BAD_BLOCK )
|
||||
{
|
||||
printf("nand block %d is bad\n", i);
|
||||
continue;
|
||||
}
|
||||
/*read head*/
|
||||
if( NF_read( i * ( NF_BLOCK_SIZE >> NF_SCT_SZ_WIDTH ), (void *)buffer, 1 ) == NF_OVERTIME_ERR )
|
||||
{
|
||||
printf("the first data is error\n");
|
||||
continue;
|
||||
}
|
||||
/* check magic */
|
||||
toc1_head = (sbrom_toc1_head_info_t *) buffer;
|
||||
if(toc1_head->magic != TOC_MAIN_INFO_MAGIC)
|
||||
{
|
||||
printf("%s err: the toc1 head magic is invalid\n", __func__);
|
||||
continue;
|
||||
}
|
||||
//check align
|
||||
length = toc1_head->valid_len;
|
||||
if( ( length & ( ALIGN_SIZE - 1 ) ) != 0 )
|
||||
{
|
||||
printf("the boot1 is not aligned by 0x%x\n", ALIGN_SIZE);
|
||||
continue;
|
||||
}
|
||||
if( 1==load_uboot_in_one_block_judge(length) )
|
||||
{
|
||||
/* load toc1 in one blk */
|
||||
status = load_and_check_in_one_blk( i, (void *)buffer, length, NF_BLOCK_SIZE );
|
||||
if( status == ADV_NF_OVERTIME_ERR )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if( status == ADV_NF_OK )
|
||||
{
|
||||
printf("Check is correct.\n");
|
||||
NF_close( );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* load toc in many blks */
|
||||
status = load_in_many_blks( i, BOOT1_LAST_BLK_NUM,
|
||||
(void*)buffer,length,
|
||||
NF_BLOCK_SIZE, &read_blks );
|
||||
if( status == ADV_NF_LACK_BLKS )
|
||||
{
|
||||
printf("ADV_NF_LACK_BLKS\n");
|
||||
NF_close( );
|
||||
return -1;
|
||||
}
|
||||
else if( status == ADV_NF_OVERTIME_ERR )
|
||||
{
|
||||
printf("mult block ADV_NF_OVERTIME_ERR\n");
|
||||
continue;
|
||||
}
|
||||
if( verify_addsum( (__u32 *)buffer, length ) == 0 )
|
||||
{
|
||||
printf("The file stored in start block %u is perfect.\n", i );
|
||||
NF_close( );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("Can't find a good Boot1 copy in nand.\n");
|
||||
NF_close( );
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_STORAGE_MEDIA_SPINAND
|
||||
#include "asm/arch/spinand_boot0.h"
|
||||
__s32 load_toc1_from_spinand( void )
|
||||
{
|
||||
__u32 i;
|
||||
__s32 status;
|
||||
__u32 length;
|
||||
__u32 read_blks;
|
||||
sbrom_toc1_head_info_t *toc1_head;
|
||||
char *buffer = (void*)CONFIG_BOOTPKG_STORE_IN_DRAM_BASE;
|
||||
|
||||
if(SpiNand_PhyInit( ) != 0)
|
||||
{
|
||||
printf("fail in opening nand flash\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("block from %d to %d\n", UBOOT_START_BLK_NUM, UBOOT_LAST_BLK_NUM);
|
||||
for( i = UBOOT_START_BLK_NUM; i <= UBOOT_LAST_BLK_NUM; i++ )
|
||||
{
|
||||
if( SpiNand_Check_BadBlock( i ) == SPINAND_BAD_BLOCK )
|
||||
{
|
||||
printf("spi nand block %d is bad\n", i);
|
||||
continue;
|
||||
}
|
||||
if( SpiNand_Read( i * ( SPN_BLOCK_SIZE >> NF_SCT_SZ_WIDTH ), (void *)buffer, 1 ) == NAND_OP_FALSE )
|
||||
{
|
||||
printf("the first data is error\n");
|
||||
continue;
|
||||
}
|
||||
toc1_head = (sbrom_toc1_head_info_t *) buffer;
|
||||
if(toc1_head->magic != TOC_MAIN_INFO_MAGIC)
|
||||
{
|
||||
printf("%s err: magic is invalid\n", __func__);
|
||||
continue;
|
||||
}
|
||||
|
||||
//check align
|
||||
length = toc1_head->valid_len;
|
||||
if( ( length & ( ALIGN_SIZE - 1 ) ) != 0 )
|
||||
{
|
||||
printf("the boot1 is not aligned by 0x%x\n", ALIGN_SIZE);
|
||||
continue;
|
||||
}
|
||||
|
||||
status = Spinand_Load_Boot1_Copy( i, (void*)buffer, length, SPN_BLOCK_SIZE, &read_blks );
|
||||
if( status == NAND_OP_FALSE )
|
||||
{
|
||||
printf("SPI nand load uboot copy fail\n");
|
||||
continue;
|
||||
}
|
||||
if( verify_addsum( buffer, length ) == 0 )
|
||||
{
|
||||
printf("Check is correct.\n");
|
||||
SpiNand_PhyExit( );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
printf("Can't find a good Boot1 copy in spi nand.\n");
|
||||
SpiNand_PhyExit( );
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
int load_boot1(void)
|
||||
{
|
||||
memcpy((void *)DRAM_PARA_STORE_ADDR, (void *)BT0_head.prvt_head.dram_para,
|
||||
SUNXI_DRAM_PARA_MAX * 4);
|
||||
|
||||
#ifdef CONFIG_STORAGE_MEDIA_SPINAND
|
||||
if((BT0_head.boot_head.platform[0]&0xf) == 4)
|
||||
return load_toc1_from_spinand();
|
||||
else
|
||||
#endif
|
||||
return load_toc1_from_nand();
|
||||
}
|
||||
27
sunxi_spl/boot0/load_spinor/Makefile
Executable file
27
sunxi_spl/boot0/load_spinor/Makefile
Executable file
@@ -0,0 +1,27 @@
|
||||
|
||||
##
|
||||
## Makefile for Sunxi Secure Boot
|
||||
##
|
||||
|
||||
|
||||
|
||||
include $(SPLDIR)/config.mk
|
||||
|
||||
LIB := $(obj)libloadspinor.o
|
||||
|
||||
COBJS-y += load_boot1_from_spinor.o
|
||||
|
||||
SRCS := $(COBJS-y:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS-y))
|
||||
|
||||
all: $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
|
||||
#########################################################################
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
102
sunxi_spl/boot0/load_spinor/load_boot1_from_spinor.c
Executable file
102
sunxi_spl/boot0/load_spinor/load_boot1_from_spinor.c
Executable file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* (C) Copyright 2012
|
||||
* wangflord@allwinnertech.com
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program;
|
||||
*
|
||||
*/
|
||||
#include "common.h"
|
||||
#include "spare_head.h"
|
||||
#include "private_boot0.h"
|
||||
#include "private_uboot.h"
|
||||
#include <private_toc.h>
|
||||
#include <asm/arch/spinor.h>
|
||||
|
||||
|
||||
|
||||
extern const boot0_file_head_t BT0_head;
|
||||
|
||||
void update_flash_para(void)
|
||||
{
|
||||
struct spare_boot_head_t *bfh = (struct spare_boot_head_t *) CONFIG_SYS_TEXT_BASE;
|
||||
bfh->boot_data.storage_type = STORAGE_NOR;
|
||||
}
|
||||
|
||||
/*
|
||||
************************************************************************************************************
|
||||
*
|
||||
* function
|
||||
*
|
||||
* name :
|
||||
*
|
||||
* parmeters :
|
||||
*
|
||||
* return :
|
||||
*
|
||||
* note :
|
||||
*
|
||||
*
|
||||
************************************************************************************************************
|
||||
*/
|
||||
int load_boot1_from_spinor(void)
|
||||
{
|
||||
sbrom_toc1_head_info_t *toc1_head;
|
||||
u8 *tmp_buff = (u8 *)CONFIG_BOOTPKG_STORE_IN_DRAM_BASE;
|
||||
int start_sector = UBOOT_START_SECTOR_IN_SPINOR;
|
||||
uint total_size = 0;
|
||||
|
||||
if(spinor_init(0))
|
||||
{
|
||||
printf("spinor init fail\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(spinor_read(start_sector, 1, (void *)tmp_buff ) )
|
||||
{
|
||||
printf("the first data is error\n");
|
||||
goto __load_boot1_from_spinor_fail;
|
||||
}
|
||||
printf("Succeed in reading toc file head.\n");
|
||||
|
||||
toc1_head = (struct sbrom_toc1_head_info *)tmp_buff;
|
||||
if(toc1_head->magic != TOC_MAIN_INFO_MAGIC)
|
||||
{
|
||||
printf("toc1 magic error\n");
|
||||
goto __load_boot1_from_spinor_fail;
|
||||
}
|
||||
total_size = toc1_head->valid_len;
|
||||
printf("The size of toc is %x.\n", total_size );
|
||||
|
||||
if(spinor_read(start_sector, total_size/512, (void *)tmp_buff ))
|
||||
{
|
||||
printf("spinor read data error\n");
|
||||
goto __load_boot1_from_spinor_fail;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
__load_boot1_from_spinor_fail:
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int load_boot1(void)
|
||||
{
|
||||
memcpy((void *)DRAM_PARA_STORE_ADDR, (void *)BT0_head.prvt_head.dram_para,
|
||||
SUNXI_DRAM_PARA_MAX * 4);
|
||||
return load_boot1_from_spinor();
|
||||
}
|
||||
|
||||
|
||||
37
sunxi_spl/boot0/main/Makefile
Executable file
37
sunxi_spl/boot0/main/Makefile
Executable file
@@ -0,0 +1,37 @@
|
||||
|
||||
##
|
||||
## Makefile for Sunxi Secure Boot
|
||||
##
|
||||
|
||||
|
||||
|
||||
include $(SPLDIR)/config.mk
|
||||
|
||||
LIB := $(obj)libmain.o
|
||||
|
||||
HEAD := boot0_head.o
|
||||
|
||||
DATA := boot0_hash.o
|
||||
START := boot0_entry.o
|
||||
COBJS += boot0_main.o
|
||||
|
||||
SRCS := $(START:.o=.S) $(COBJS:.o=.c) $(HEAD:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS) $(COBJS-y) $(SOBJS))
|
||||
HEAD := $(addprefix $(obj),$(HEAD))
|
||||
START := $(addprefix $(obj),$(START))
|
||||
|
||||
|
||||
all: $(obj).depend $(HEAD) $(START) $(LIB) $(DATA)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
46
sunxi_spl/boot0/main/boot0_entry.S
Executable file
46
sunxi_spl/boot0/main/boot0_entry.S
Executable file
@@ -0,0 +1,46 @@
|
||||
|
||||
|
||||
#include <config.h>
|
||||
#include "asm/mode.h"
|
||||
|
||||
.globl _start
|
||||
_start: b reset
|
||||
|
||||
reset:
|
||||
mrs r0, cpsr
|
||||
bic r0, r0, #ARMV7_MODE_MASK
|
||||
orr r0, r0, #ARMV7_SVC_MODE
|
||||
orr r0, r0, #( ARMV7_IRQ_MASK | ARMV7_FIQ_MASK ) @// After reset, ARM automaticly disables IRQ and FIQ, and runs in SVC mode.
|
||||
bic r0, r0, #(1<<9) @// set little-endian
|
||||
msr cpsr_c, r0
|
||||
|
||||
mrc p15, 0, r0, c1, c0, 0
|
||||
#ifdef CONFIG_ARCH_SUN8IW10P1
|
||||
orr r0, r0, #0x00002000 @ set bits 13 (--V-)
|
||||
#else
|
||||
bic r0, r0, #0x00002000 @ clear bits 13 (--V-)
|
||||
#endif
|
||||
bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM)
|
||||
orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB
|
||||
bic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache
|
||||
mcr p15, 0, r0, c1, c0, 0
|
||||
|
||||
ldr sp, =CONFIG_BOOT0_STACK_BOTTOM
|
||||
bl clear_bss
|
||||
bl cpu_init_s
|
||||
bl main
|
||||
|
||||
clear_bss:
|
||||
ldr r0, =__bss_start
|
||||
ldr r1, =__bss_end
|
||||
|
||||
mov r2, #0 /* clear */
|
||||
|
||||
clbss_1:
|
||||
stmia r0!, {r2}
|
||||
cmp r0, r1
|
||||
blt clbss_1
|
||||
|
||||
mov pc, lr
|
||||
|
||||
|
||||
25
sunxi_spl/boot0/main/boot0_hash.c
Executable file
25
sunxi_spl/boot0/main/boot0_hash.c
Executable file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* (C) Copyright 2007-2013
|
||||
* Allwinner Technology Co., Ltd. <www.allwinnertech.com>
|
||||
* Jerry Wang <wangflord@allwinnertech.com>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
#include <common.h>
|
||||
char boot0_hash_value[64] = {0x38};
|
||||
134
sunxi_spl/boot0/main/boot0_head.c
Executable file
134
sunxi_spl/boot0/main/boot0_head.c
Executable file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* eGON
|
||||
* the Embedded GO-ON Bootloader System
|
||||
*
|
||||
* Copyright(C), 2006-2008, SoftWinners Microelectronic Co., Ltd.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File Name : Boot0_head.c
|
||||
*
|
||||
* Author : Gary.Wang
|
||||
*
|
||||
* Version : 1.1.0
|
||||
*
|
||||
* Date : 2007.11.06
|
||||
*
|
||||
* Description : This file defines the file head part of Boot0, which contains some important
|
||||
* infomations such as magic, platform infomation and so on, and MUST be allocted in the
|
||||
* head of Boot0.
|
||||
*
|
||||
* Others : None at present.
|
||||
*
|
||||
*
|
||||
* History :
|
||||
*
|
||||
* <Author> <time> <version> <description>
|
||||
*
|
||||
* Gary.Wang 2007.11.06 1.1.0 build the file
|
||||
*
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
#include "common.h"
|
||||
#include <private_boot0.h>
|
||||
|
||||
extern char uboot_hash_value[64];
|
||||
|
||||
|
||||
const boot0_file_head_t BT0_head =
|
||||
{
|
||||
{
|
||||
/* jump_instruction */
|
||||
( 0xEA000000 | ( ( ( sizeof( boot0_file_head_t ) + sizeof(uboot_hash_value) + sizeof( int ) - 1 ) / sizeof( int ) - 2 ) & 0x00FFFFFF ) ),
|
||||
BOOT0_MAGIC,
|
||||
STAMP_VALUE,
|
||||
#ifdef ALIGN_SIZE_8K
|
||||
0x2000,
|
||||
#else
|
||||
0x4000,
|
||||
#endif
|
||||
sizeof( boot_file_head_t ),
|
||||
BOOT_PUB_HEAD_VERSION,
|
||||
CONFIG_BOOT0_RET_ADDR,
|
||||
CONFIG_BOOT0_RUN_ADDR,
|
||||
0,
|
||||
{
|
||||
//brom modify: nand-4bytes sdmmc-2bytes
|
||||
0, 0,0,0, '4','.','0',0
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
//__u32 prvt_head_size;
|
||||
0,
|
||||
//char prvt_head_vsn[4];
|
||||
1,
|
||||
0, /* power_mode */
|
||||
{0}, /* reserver[2] */
|
||||
//unsigned int dram_para[32] ;
|
||||
{0},
|
||||
//__s32 uart_port;
|
||||
0,
|
||||
//normal_gpio_cfg uart_ctrl[2];
|
||||
{
|
||||
{ 6, 2, 4, 1, 1, 0, {0}},//PB8: 4--RX
|
||||
{ 6, 4, 4, 1, 1, 0, {0}},//PB9: 4--TX
|
||||
},
|
||||
//__s32 enable_jtag;
|
||||
0,
|
||||
//normal_gpio_cfg jtag_gpio[5];
|
||||
{{0},{0},{0},{0},{0}},
|
||||
//normal_gpio_cfg storage_gpio[32];
|
||||
{
|
||||
{ 0, 0, 2, 1, 2, 0, {0}},//PF0-5: 2--SDC
|
||||
{ 0, 1, 2, 1, 2, 0, {0}},
|
||||
{ 0, 2, 2, 1, 2, 0, {0}},
|
||||
{ 0, 3, 2, 1, 2, 0, {0}},
|
||||
{ 0, 4, 2, 1, 2, 0, {0}},
|
||||
{ 0, 5, 2, 1, 2, 0, {0}},
|
||||
},
|
||||
//char storage_data[512 - sizeof(normal_gpio_cfg) * 32];
|
||||
{0}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* 关于Boot_file_head中的jump_instruction字段
|
||||
*
|
||||
* jump_instruction字段存放的是一条跳转指令:( B BACK_OF_Boot_file_head ),此跳
|
||||
*转指令被执行后,程序将跳转到Boot_file_head后面第一条指令。
|
||||
*
|
||||
* ARM指令中的B指令编码如下:
|
||||
* +--------+---------+------------------------------+
|
||||
* | 31--28 | 27--24 | 23--0 |
|
||||
* +--------+---------+------------------------------+
|
||||
* | cond | 1 0 1 0 | signed_immed_24 |
|
||||
* +--------+---------+------------------------------+
|
||||
* 《ARM Architecture Reference Manual》对于此指令有如下解释:
|
||||
* Syntax :
|
||||
* B{<cond>} <target_address>
|
||||
* <cond> Is the condition under which the instruction is executed. If the
|
||||
* <cond> is ommitted, the AL(always,its code is 0b1110 )is used.
|
||||
* <target_address>
|
||||
* Specified the address to branch to. The branch target address is
|
||||
* calculated by:
|
||||
* 1. Sign-extending the 24-bit signed(wro's complement)immediate
|
||||
* to 32 bits.
|
||||
* 2. Shifting the result left two bits.
|
||||
* 3. Adding to the contents of the PC, which contains the address
|
||||
* of the branch instruction plus 8.
|
||||
*
|
||||
* 由此可知,此指令编码的最高8位为:0b11101010,低24位根据Boot_file_head的大小动
|
||||
*态生成,所以指令的组装过程如下:
|
||||
* ( sizeof( boot_file_head_t ) + sizeof( int ) - 1 ) / sizeof( int )
|
||||
* 求出文件头占用的“字”的个数
|
||||
* - 2 减去PC预取的指令条数
|
||||
* & 0x00FFFFFF 求出signed-immed-24
|
||||
* | 0xEA000000 组装成B指令
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
337
sunxi_spl/boot0/main/boot0_main.c
Executable file
337
sunxi_spl/boot0/main/boot0_main.c
Executable file
@@ -0,0 +1,337 @@
|
||||
/*
|
||||
**********************************************************************************************************************
|
||||
*
|
||||
* the Embedded Secure Bootloader System
|
||||
*
|
||||
*
|
||||
* Copyright(C), 2006-2014, Allwinnertech Co., Ltd.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File :
|
||||
*
|
||||
* By :
|
||||
*
|
||||
* Version : V2.00
|
||||
*
|
||||
* Date :
|
||||
*
|
||||
* Descript:
|
||||
**********************************************************************************************************************
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <private_boot0.h>
|
||||
#include <private_uboot.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/timer.h>
|
||||
#include <asm/arch/uart.h>
|
||||
#include <asm/arch/dram.h>
|
||||
#include <asm/arch/rtc_region.h>
|
||||
#include <private_toc.h>
|
||||
#include <boot0_helper.h>
|
||||
#include <asm/arch/key.h>
|
||||
#include <asm/arch/base_pmu.h>
|
||||
|
||||
#ifdef CONFIG_SUNXI_MULITCORE_BOOT
|
||||
#include <asm/arch/platsmp.h>
|
||||
extern void sunxi_set_cpu1_wfi(void);
|
||||
extern uint sunxi_probe_key_input(void);
|
||||
extern uint sunxi_probe_uart_input(void);
|
||||
#endif
|
||||
|
||||
static int uart_input_value, lradc_input_value;
|
||||
|
||||
extern const boot0_file_head_t BT0_head;
|
||||
static int boot0_clear_env(void);
|
||||
static void update_uboot_info(__u32 dram_size);
|
||||
static int check_update_key(int key_value);
|
||||
|
||||
#ifdef SUNXI_OTA_TEST
|
||||
static void print_ota_test(void);
|
||||
#endif
|
||||
|
||||
extern void disp_init(void);
|
||||
extern char boot0_hash_value[64];
|
||||
extern int debug_enable;
|
||||
|
||||
int mmc_config_addr = (int)(BT0_head.prvt_head.storage_data);
|
||||
|
||||
//phoenixcard will set this bit
|
||||
#define BOOT0_BURN_SECURE_BIT (1<<31)
|
||||
|
||||
/*******************************************************
|
||||
we should implement below interfaces if platform support
|
||||
handler standby flag in boot0
|
||||
*******************************************************/
|
||||
void __attribute__((weak)) handler_super_standby(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void __attribute__((weak)) sid_set_security_mode(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void __attribute__((weak)) reboot(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void __attribute__((weak)) set_gpio_gate(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int __attribute__((weak)) probe_power_key(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
main: body for c runtime
|
||||
*******************************************************************************/
|
||||
void main( void )
|
||||
{
|
||||
__u32 status;
|
||||
__s32 dram_size;
|
||||
__u32 fel_flag;
|
||||
__u32 boot_cpu=0;
|
||||
int use_monitor = 0;
|
||||
__maybe_unused int pmu_type = 0;
|
||||
__maybe_unused int cpu1_power_on = 0;
|
||||
__maybe_unused struct spare_boot_head_t *bfh = NULL;
|
||||
|
||||
timer_init();
|
||||
sunxi_serial_init( BT0_head.prvt_head.uart_port, (void *)BT0_head.prvt_head.uart_ctrl, 6 );
|
||||
pr_force("HELLO! BOOT0 is starting!\n");
|
||||
pr_force("boot0 commit : %s \n",boot0_hash_value);
|
||||
uart_input_value = set_debugmode_flag();
|
||||
sunxi_key_init();
|
||||
#ifdef SUNXI_OTA_TEST
|
||||
print_ota_test();
|
||||
#endif
|
||||
|
||||
if (BT0_head.prvt_head.enable_jtag&BOOT0_BURN_SECURE_BIT)
|
||||
{
|
||||
printf("ready to burn secure bit\n");
|
||||
sid_set_security_mode();
|
||||
reboot();
|
||||
}
|
||||
|
||||
if( BT0_head.prvt_head.enable_jtag )
|
||||
{
|
||||
boot_set_gpio((normal_gpio_cfg *)BT0_head.prvt_head.jtag_gpio, 6, 1);
|
||||
}
|
||||
|
||||
pmu_type = pmu_init(BT0_head.prvt_head.power_mode);
|
||||
#ifdef CONFIG_SUNXI_MULITCORE_BOOT
|
||||
set_pll_voltage(CONFIG_SUNXI_CORE_VOL);
|
||||
#endif
|
||||
set_pll();
|
||||
set_gpio_gate();
|
||||
|
||||
//detect step1: rtc
|
||||
fel_flag = rtc_region_probe_fel_flag();
|
||||
if(fel_flag == SUNXI_RUN_EFEX_FLAG)
|
||||
{
|
||||
rtc_region_clear_fel_flag();
|
||||
printf("eraly jump fel\n");
|
||||
goto __boot0_entry_err1;
|
||||
#if defined(CONFIG_SUNXI_CRASH)
|
||||
} else if (fel_flag == SUNXI_RUN_CRASHDUMP_RESET_FLAG) {
|
||||
//clear fel flag
|
||||
rtc_region_clear_fel_flag();
|
||||
//set fel flag
|
||||
rtc_region_set_fel_flag(SUNXI_RUN_CRASHDUMP_RESET_READY);
|
||||
do {
|
||||
__msdelay(150);
|
||||
fel_flag = rtc_region_probe_fel_flag();
|
||||
}
|
||||
while (fel_flag != SUNXI_RUN_CRASHDUMP_REFRESH_READY);
|
||||
printf("carshdump mode , jump fel\n");
|
||||
goto __boot0_entry_err0;
|
||||
#endif
|
||||
}
|
||||
|
||||
//detect ste2: uart input
|
||||
if (uart_input_value == '2') {
|
||||
printf("detected user input 2\n");
|
||||
goto __boot0_entry_err1;
|
||||
}
|
||||
|
||||
//detect step3: power unit
|
||||
lradc_input_value = sunxi_key_read();
|
||||
if (check_update_key(lradc_input_value) ) {
|
||||
printf("detected power key unit\n");
|
||||
goto __boot0_entry_err0;
|
||||
}
|
||||
|
||||
#ifdef FPGA_PLATFORM
|
||||
dram_size = mctl_init((void *)BT0_head.prvt_head.dram_para);
|
||||
#else
|
||||
dram_size = init_DRAM(0, (void *)BT0_head.prvt_head.dram_para);
|
||||
#endif
|
||||
if(dram_size)
|
||||
{
|
||||
printf("dram size =%d\n", dram_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("initializing SDRAM Fail.\n");
|
||||
goto __boot0_entry_err0;
|
||||
}
|
||||
//on some platform, boot0 should handler standby flag.
|
||||
handler_super_standby();
|
||||
|
||||
mmu_setup(dram_size);
|
||||
|
||||
//load boot1
|
||||
status = load_boot1();
|
||||
if(status == 0 )
|
||||
{
|
||||
use_monitor = 0;
|
||||
status = load_fip(&use_monitor);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SUNXI_HDMI_IN_BOOT0
|
||||
disp_init();
|
||||
#endif
|
||||
|
||||
printf("Ready to disable icache.\n");
|
||||
|
||||
// disable instruction cache
|
||||
mmu_turn_off( );
|
||||
|
||||
if( status == 0 )
|
||||
{
|
||||
//update bootpackage size for uboot
|
||||
update_uboot_info(dram_size);
|
||||
//update flash para
|
||||
update_flash_para();
|
||||
//update dram para before jmp to boot1
|
||||
set_dram_para((void *)&BT0_head.prvt_head.dram_para, dram_size, boot_cpu);
|
||||
|
||||
bfh = (struct spare_boot_head_t *) CONFIG_SYS_TEXT_BASE;
|
||||
bfh->boot_ext[0].data[0] = pmu_type;
|
||||
bfh->boot_ext[0].data[1] = uart_input_value;
|
||||
bfh->boot_ext[0].data[2] = lradc_input_value;
|
||||
bfh->boot_ext[0].data[3] = debug_enable;
|
||||
|
||||
if (uart_input_value == 'k') {
|
||||
printf_all();
|
||||
}
|
||||
|
||||
printf("Jump to secend Boot.\n");
|
||||
if(use_monitor)
|
||||
{
|
||||
boot0_jmp_monitor();
|
||||
}
|
||||
else
|
||||
{
|
||||
boot0_jmp_boot1(CONFIG_SYS_TEXT_BASE);
|
||||
}
|
||||
}
|
||||
|
||||
__boot0_entry_err0:
|
||||
printf_all();
|
||||
__boot0_entry_err1:
|
||||
boot0_clear_env();
|
||||
|
||||
boot0_jmp_other(FEL_BASE);
|
||||
}
|
||||
|
||||
/*
|
||||
************************************************************************************************************
|
||||
*
|
||||
* function
|
||||
*
|
||||
* name :
|
||||
*
|
||||
* parmeters :
|
||||
*
|
||||
* return :
|
||||
*
|
||||
* note :
|
||||
*
|
||||
*
|
||||
************************************************************************************************************
|
||||
*/
|
||||
static int boot0_clear_env(void)
|
||||
{
|
||||
|
||||
reset_pll();
|
||||
mmu_turn_off();
|
||||
|
||||
__msdelay(10);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
static void update_uboot_info(__u32 dram_size)
|
||||
{
|
||||
struct spare_boot_head_t *bfh = (struct spare_boot_head_t *) CONFIG_SYS_TEXT_BASE;
|
||||
struct sbrom_toc1_head_info *toc1_head = (struct sbrom_toc1_head_info *)CONFIG_BOOTPKG_STORE_IN_DRAM_BASE;
|
||||
bfh->boot_data.boot_package_size = toc1_head->valid_len;
|
||||
bfh->boot_data.dram_scan_size = dram_size;
|
||||
//printf("boot package size: 0x%x\n",bfh->boot_data.boot_package_size);
|
||||
}
|
||||
|
||||
#define KEY_DELAY_MAX (8)
|
||||
#define KEY_DELAY_EACH_TIME (40)
|
||||
#define KEY_MAX_COUNT_GO_ON ((KEY_DELAY_MAX * 1000)/(KEY_DELAY_EACH_TIME))
|
||||
|
||||
static int check_update_key(int key_value)
|
||||
{
|
||||
int time_tick = 0;
|
||||
int count = 0;
|
||||
int power_key;
|
||||
|
||||
if(key_value <= 0)
|
||||
return 0;
|
||||
|
||||
probe_power_key(); //clear power key status
|
||||
while(sunxi_key_read() > 0) //press key and not loosen
|
||||
{
|
||||
time_tick++;
|
||||
__msdelay(KEY_DELAY_EACH_TIME);
|
||||
//detect power key status for fel mode
|
||||
power_key = probe_power_key();
|
||||
if (power_key > 0)
|
||||
{
|
||||
count ++;
|
||||
}
|
||||
if(count == 3)
|
||||
{
|
||||
pr_force("you can loosen the key to update now\n");
|
||||
//jump to fel
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(time_tick > KEY_MAX_COUNT_GO_ON)
|
||||
{
|
||||
pr_force("time out\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
pr_force("key not pressed anymore\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef SUNXI_OTA_TEST
|
||||
static void print_ota_test(void)
|
||||
{
|
||||
printf("*********************************************\n");
|
||||
printf("*********************************************\n");
|
||||
printf("*********************************************\n");
|
||||
printf("*********************************************\n");
|
||||
printf("********[OTA TEST]:update boot0 sucess*******\n");
|
||||
printf("*********************************************\n");
|
||||
printf("*********************************************\n");
|
||||
printf("*********************************************\n");
|
||||
printf("*********************************************\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
64
sunxi_spl/boot0/spl/Makefile
Executable file
64
sunxi_spl/boot0/spl/Makefile
Executable file
@@ -0,0 +1,64 @@
|
||||
#
|
||||
# (C) Copyright 2000-2003
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(SPLDIR)/config.mk
|
||||
|
||||
LIB = $(obj)libsource_spl.o
|
||||
|
||||
COBJS-y += $(TOPDIR)/arch/$(ARCH)/cpu/$(CPU)/$(SOC)/spl/rtc_region.o
|
||||
COBJS-y += $(TOPDIR)/arch/$(ARCH)/cpu/$(CPU)/$(SOC)/spl/timer_spl.o
|
||||
COBJS-y += $(TOPDIR)/arch/$(ARCH)/cpu/$(CPU)/$(SOC)/spl/gpio_spl.o
|
||||
COBJS-y += $(TOPDIR)/arch/$(ARCH)/cpu/$(CPU)/$(SOC)/spl/serial_spl.o
|
||||
COBJS-y += $(TOPDIR)/arch/$(ARCH)/cpu/$(CPU)/$(SOC)/spl/clock_spl.o
|
||||
COBJS-$(CONFIG_SUNXI_MODULE_AXP) += $(TOPDIR)/arch/$(ARCH)/cpu/$(CPU)/$(SOC)/spl/pmu_spl.o
|
||||
COBJS-$(CONFIG_AXP_USE_RSB) += $(TOPDIR)/arch/$(ARCH)/cpu/$(CPU)/$(SOC)/spl/rsb_spl.o
|
||||
COBJS-$(CONFIG_AXP_USE_I2C) += $(TOPDIR)/arch/$(ARCH)/cpu/$(CPU)/$(SOC)/spl/sunxi_i2c_spl.o
|
||||
COBJS-$(CONFIG_SUNXI_CHIPID)+= $(TOPDIR)/arch/$(ARCH)/cpu/$(CPU)/$(SOC)/spl/efuse_spl.o
|
||||
COBJS-y += $(TOPDIR)/arch/$(ARCH)/cpu/$(CPU)/$(SOC)/spl/fip_common.o
|
||||
COBJS-y += $(TOPDIR)/arch/$(ARCH)/cpu/$(CPU)/$(SOC)/spl/jmp.o
|
||||
|
||||
ifndef CONFIG_GPADC_KEY
|
||||
COBJS-y += $(TOPDIR)/arch/$(ARCH)/cpu/$(CPU)/sunxi_spl_common/key.o
|
||||
else
|
||||
COBJS-y += $(TOPDIR)/arch/$(ARCH)/cpu/$(CPU)/sunxi_spl_common/gpkey.o
|
||||
endif
|
||||
|
||||
#COBJS-$(CONFIG_XXXX) += xxxx.o
|
||||
COBJS := $(COBJS-y)
|
||||
SRCS := $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS))
|
||||
|
||||
all: $(obj).depend $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
|
||||
83
sunxi_spl/config.mk
Executable file
83
sunxi_spl/config.mk
Executable file
@@ -0,0 +1,83 @@
|
||||
|
||||
|
||||
# Load generated board configuration
|
||||
sinclude $(OBJTREE)/include/autoconf.mk
|
||||
|
||||
#CROSS_COMPILE := $(TOPDIR)/../toolchain/gcc-arm/bin/arm-linux-gnueabihf-
|
||||
CROSS_COMPILE := $(TOPDIR)/../gcc-linaro/bin/arm-linux-gnueabi-
|
||||
|
||||
AS = $(CROSS_COMPILE)as
|
||||
LD = $(CROSS_COMPILE)ld
|
||||
CC = $(CROSS_COMPILE)gcc
|
||||
CPP = $(CC) -E
|
||||
AR = $(CROSS_COMPILE)ar
|
||||
NM = $(CROSS_COMPILE)nm
|
||||
LDR = $(CROSS_COMPILE)ldr
|
||||
STRIP = $(CROSS_COMPILE)strip
|
||||
OBJCOPY = $(CROSS_COMPILE)objcopy
|
||||
OBJDUMP = $(CROSS_COMPILE)objdump
|
||||
|
||||
##########################################################
|
||||
COMPILEINC := -isystem $(shell dirname `$(CC) -print-libgcc-file-name`)/include
|
||||
SPLINCLUDE := \
|
||||
-I$(SRCTREE)/include \
|
||||
-I$(SRCTREE)/arch/arm/include \
|
||||
-I$(SPLDIR)/include \
|
||||
-I$(SRCTREE)/include/openssl
|
||||
|
||||
PLATFORM_RELFLAGS += -march=armv7-a
|
||||
|
||||
COMM_FLAGS := -nostdinc $(COMPILEINC) \
|
||||
-g -Os -fno-common -msoft-float -mfpu=neon \
|
||||
-ffunction-sections \
|
||||
-fno-builtin -ffreestanding \
|
||||
-D__KERNEL__ \
|
||||
-DCONFIG_ARM -D__ARM__ \
|
||||
-D__NEON_SIMD__ \
|
||||
-mabi=aapcs-linux \
|
||||
-mthumb-interwork \
|
||||
-fno-stack-protector \
|
||||
-Wall \
|
||||
-Werror \
|
||||
-Wstrict-prototypes \
|
||||
-Wno-format-security \
|
||||
-Wno-format-nonliteral \
|
||||
-pipe
|
||||
|
||||
|
||||
|
||||
|
||||
C_FLAGS += $(SPLINCLUDE) $(COMM_FLAGS)
|
||||
S_FLAGS += $(SPLINCLUDE) -D__ASSEMBLY__ $(COMM_FLAGS)
|
||||
#LDFLAGS += --gap-fill=0xff
|
||||
LDFLAGS_boot0 = --gc-sections
|
||||
export LDFLAGS_boot0
|
||||
###########################################################
|
||||
|
||||
###########################################################
|
||||
PLATFORM_LIBGCC = -L $(shell dirname `$(CC) $(CFLAGS) -print-libgcc-file-name`) -lgcc
|
||||
export PLATFORM_LIBGCC
|
||||
###########################################################
|
||||
|
||||
# Allow boards to use custom optimize flags on a per dir/file basis
|
||||
ALL_AFLAGS = $(AFLAGS) $(PLATFORM_RELFLAGS) $(S_FLAGS)
|
||||
ALL_CFLAGS = $(CFLAGS) $(PLATFORM_RELFLAGS) $(C_FLAGS)
|
||||
export ALL_CFLAGS ALL_AFLAGS
|
||||
|
||||
|
||||
$(obj)%.o: %.S
|
||||
@$(CC) $(ALL_AFLAGS) -o $@ $< -c
|
||||
@echo " CC "$< ...
|
||||
$(obj)%.o: %.c
|
||||
@$(CC) $(ALL_CFLAGS) -o $@ $< -c
|
||||
@echo " CC "$< ...
|
||||
|
||||
#########################################################################
|
||||
|
||||
# If the list of objects to link is empty, just create an empty built-in.o
|
||||
cmd_link_o_target = $(if $(strip $1),\
|
||||
@$(LD) $(LDFLAGS) -r -o $@ $1,\
|
||||
rm -f $@; $(AR) rcs $@ )
|
||||
|
||||
#########################################################################
|
||||
|
||||
54
sunxi_spl/display/Makefile
Executable file
54
sunxi_spl/display/Makefile
Executable file
@@ -0,0 +1,54 @@
|
||||
#
|
||||
# (C) Copyright 2000-2011
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# (C) Copyright 2011
|
||||
# Daniel Schwierzeck, daniel.schwierzeck@googlemail.com.
|
||||
#
|
||||
# (C) Copyright 2011
|
||||
# Texas Instruments Incorporated - http://www.ti.com/
|
||||
# Aneesh V <aneesh@ti.com>
|
||||
#
|
||||
# This file is released under the terms of GPL v2 and any later version.
|
||||
# See the file COPYING in the root directory of the source tree for details.
|
||||
#
|
||||
# Based on top-level Makefile.
|
||||
#
|
||||
|
||||
include $(SPLDIR)/config.mk
|
||||
|
||||
CONFIG_SPL := y
|
||||
#export CONFIG_SPL
|
||||
|
||||
# We want the final binaries in this directory
|
||||
obj := $(OBJTREE)/sunxi_spl/display/
|
||||
|
||||
|
||||
LIBS-y += arch/$(ARCH)/cpu/$(CPU)/$(SOC)/spl/libsource_spl.o
|
||||
LIBS-$(CONFIG_STORAGE_MEDIA_MMC) += arch/$(ARCH)/cpu/$(CPU)/$(SOC)/mmc/libmmc.o
|
||||
LIBS-$(CONFIG_STORAGE_MEDIA_NAND) += arch/$(ARCH)/cpu/$(CPU)/$(SOC)/nand/libnand.o
|
||||
LIBS-y += arch/$(ARCH)/cpu/$(CPU)/$(SOC)/dram/libdram.o
|
||||
#LIBS-y += lib/libgeneral.o
|
||||
|
||||
LIBS := $(addprefix $(OBJTREE)/,$(sort $(LIBS-y)))
|
||||
|
||||
ALL-y += $(obj)libdisplay.o
|
||||
|
||||
all: $(ALL-y)
|
||||
|
||||
$(obj)libspl.o: depend $(LIBS)
|
||||
|
||||
$(LIBS): depend
|
||||
$(MAKE) -C $(SRCTREE)$(dir $(subst $(OBJTREE),,$@))
|
||||
|
||||
depend: tmpdep
|
||||
|
||||
ALL_LIBS := $(LIBS)
|
||||
ALL_LIBS := $(dir $(sort $(ALL_LIBS)))
|
||||
|
||||
tmpdep:
|
||||
@for dir in $(ALL_LIBS); do\
|
||||
$(MAKE) -C $$dir _depend ; done
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
23
sunxi_spl/display/hdmi/Makefile
Executable file
23
sunxi_spl/display/hdmi/Makefile
Executable file
@@ -0,0 +1,23 @@
|
||||
include $(SPLDIR)/config.mk
|
||||
LIB = $(obj)libdisplay.o
|
||||
|
||||
COBJS += clk.o
|
||||
COBJS += hdmi.o
|
||||
COBJS += tcon.o
|
||||
COBJS += display.o
|
||||
COBJS += video.o fc_video.o phy.o access.o irq.o main_controller.o packets.o scdc.o
|
||||
SRCS := $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS))
|
||||
all: $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
302
sunxi_spl/display/hdmi/access.c
Executable file
302
sunxi_spl/display/hdmi/access.c
Executable file
@@ -0,0 +1,302 @@
|
||||
/*
|
||||
* Allwinner SoCs hdmi2.0 driver.
|
||||
*
|
||||
* Copyright (C) 2016 Allwinner.
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#include "access.h"
|
||||
#include "irq.h"
|
||||
|
||||
#define I2CM_OPERATION_READ 0x01
|
||||
#define I2CM_OPERATION_READ_EXT 0x02
|
||||
#define I2CM_OPERATION_READ_SEQ 0x04
|
||||
#define I2CM_OPERATION_READ_SEQ_EXT 0x08
|
||||
#define I2CM_OPERATION_WRITE 0x10
|
||||
|
||||
#define I2C_DIV_FACTOR 100000
|
||||
|
||||
|
||||
static struct device_access *device_bsp;
|
||||
struct system_functions *snps_functions;
|
||||
|
||||
/*calculate valid bit account*/
|
||||
static u8 lowestBitSet(u8 x)
|
||||
{
|
||||
u8 result = 0;
|
||||
|
||||
/* x=0 is not properly handled by while-loop */
|
||||
if (x == 0)
|
||||
return 0;
|
||||
|
||||
while ((x & 1) == 0) {
|
||||
x >>= 1;
|
||||
result++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void register_bsp_functions(struct device_access *device)
|
||||
{
|
||||
LOG_TRACE();
|
||||
device_bsp = device;
|
||||
}
|
||||
|
||||
void register_system_functions(struct system_functions *functions)
|
||||
{
|
||||
HDMI_INFO_MSG("System functions %s", functions->name);
|
||||
snps_functions = functions;
|
||||
}
|
||||
|
||||
u32 dev_read(hdmi_tx_dev_t *dev, u32 addr)
|
||||
{
|
||||
if (dev && device_bsp)
|
||||
return device_bsp->read((uintptr_t)addr);
|
||||
|
||||
HDMI_INFO_MSG("BSP functions not registered\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dev_write(hdmi_tx_dev_t *dev, u32 addr, u32 data)
|
||||
{
|
||||
if (dev && device_bsp)
|
||||
return device_bsp->write((uintptr_t)addr, data);
|
||||
|
||||
HDMI_INFO_MSG("BSP functions not registered\n");
|
||||
}
|
||||
|
||||
u32 dev_read_mask(hdmi_tx_dev_t *dev, u32 addr, u8 mask)
|
||||
{
|
||||
u8 shift = lowestBitSet(mask);
|
||||
|
||||
return (dev_read(dev, addr) & mask) >> shift;
|
||||
}
|
||||
|
||||
void dev_write_mask(hdmi_tx_dev_t *dev, u32 addr, u8 mask, u8 data)
|
||||
{
|
||||
u8 temp = 0;
|
||||
u8 shift = lowestBitSet(mask);
|
||||
|
||||
temp = dev_read(dev, addr);
|
||||
temp &= ~(mask);
|
||||
temp |= (mask & (data << shift));
|
||||
dev_write(dev, addr, temp);
|
||||
}
|
||||
|
||||
static int dev_standby(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
if (device_bsp)
|
||||
return device_bsp->disable();
|
||||
|
||||
HDMI_INFO_MSG("BSP functions not registered\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int access_Standby(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
return dev_standby(dev);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void snps_sleep(unsigned us)
|
||||
{
|
||||
snps_functions->sleep(us);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int _write(hdmi_tx_dev_t *dev, u8 i2cAddr, u8 addr, u8 data)
|
||||
{
|
||||
int timeout = I2CDDC_TIMEOUT;
|
||||
u32 status = 0;
|
||||
|
||||
LOG_TRACE1(addr);
|
||||
|
||||
dev_write_mask(dev, I2CM_SLAVE, I2CM_SLAVE_SLAVEADDR_MASK, i2cAddr);
|
||||
dev_write(dev, I2CM_ADDRESS, addr);
|
||||
dev_write(dev, I2CM_DATAO, data);
|
||||
dev_write(dev, I2CM_OPERATION, I2CM_OPERATION_WRITE);
|
||||
do {
|
||||
snps_sleep(10);
|
||||
status = dev_read_mask(dev, IH_I2CM_STAT0,
|
||||
IH_I2CM_STAT0_I2CMASTERERROR_MASK
|
||||
| IH_I2CM_STAT0_I2CMASTERDONE_MASK);
|
||||
} while (status == 0 && (timeout--));
|
||||
|
||||
dev_write(dev, IH_I2CM_STAT0, status); /* clear read status */
|
||||
|
||||
if (status & IH_I2CM_STAT0_I2CMASTERERROR_MASK) {
|
||||
HDMI_INFO_MSG("I2C DDC write failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (status & IH_I2CM_STAT0_I2CMASTERDONE_MASK)
|
||||
return 0;
|
||||
|
||||
HDMI_INFO_MSG("ASSERT I2C Write timeout - check system - exiting");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int _read(hdmi_tx_dev_t *dev, u8 i2cAddr, u8 segment,
|
||||
u8 pointer, u8 addr, u8 *value)
|
||||
{
|
||||
int timeout = I2CDDC_TIMEOUT;
|
||||
u32 status = 0;
|
||||
|
||||
LOG_TRACE1(addr);
|
||||
dev_write_mask(dev, I2CM_SLAVE, I2CM_SLAVE_SLAVEADDR_MASK, i2cAddr);
|
||||
dev_write(dev, I2CM_ADDRESS, addr);
|
||||
dev_write(dev, I2CM_SEGADDR, segment);
|
||||
dev_write(dev, I2CM_SEGPTR, pointer);
|
||||
|
||||
if (pointer)
|
||||
dev_write(dev, I2CM_OPERATION, I2CM_OPERATION_READ_EXT);
|
||||
else
|
||||
dev_write(dev, I2CM_OPERATION, I2CM_OPERATION_READ);
|
||||
|
||||
do {
|
||||
snps_sleep(10);
|
||||
status = dev_read_mask(dev, IH_I2CM_STAT0,
|
||||
IH_I2CM_STAT0_I2CMASTERERROR_MASK
|
||||
| IH_I2CM_STAT0_I2CMASTERDONE_MASK);
|
||||
} while (status == 0 && (timeout--));
|
||||
|
||||
dev_write(dev, IH_I2CM_STAT0, status); /* clear read status */
|
||||
|
||||
if (status & IH_I2CM_STAT0_I2CMASTERERROR_MASK) {
|
||||
HDMI_INFO_MSG("I2C DDC Read failed for i2cAddr 0x%x seg 0x%x pointer 0x%x addr 0x%x",
|
||||
i2cAddr, segment, pointer, addr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (status & IH_I2CM_STAT0_I2CMASTERDONE_MASK) {
|
||||
*value = (u8) dev_read(dev, I2CM_DATAI);
|
||||
return 0;
|
||||
}
|
||||
|
||||
HDMI_INFO_MSG("ASSERT I2C DDC Read timeout - check system - exiting");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int _read8(hdmi_tx_dev_t *dev, u8 i2cAddr, u8 segment,
|
||||
u8 pointer, u8 addr, u8 *value)
|
||||
{
|
||||
int timeout = I2CDDC_TIMEOUT;
|
||||
u32 status = 0;
|
||||
|
||||
LOG_TRACE1(addr);
|
||||
dev_write_mask(dev, I2CM_SLAVE, I2CM_SLAVE_SLAVEADDR_MASK, i2cAddr);
|
||||
dev_write(dev, I2CM_SEGADDR, segment);
|
||||
dev_write(dev, I2CM_SEGPTR, pointer);
|
||||
dev_write(dev, I2CM_ADDRESS, addr);
|
||||
|
||||
if (pointer)
|
||||
dev_write(dev, I2CM_OPERATION, I2CM_OPERATION_READ_SEQ_EXT);
|
||||
else
|
||||
dev_write(dev, I2CM_OPERATION, I2CM_OPERATION_READ_SEQ);
|
||||
|
||||
do {
|
||||
snps_sleep(10);
|
||||
status = dev_read_mask(dev, IH_I2CM_STAT0,
|
||||
IH_I2CM_STAT0_I2CMASTERERROR_MASK |
|
||||
IH_I2CM_STAT0_I2CMASTERDONE_MASK);
|
||||
} while (status == 0 && (timeout--));
|
||||
|
||||
HDMI_INFO_MSG("I2C Master state: %d\n", status);
|
||||
dev_write(dev, IH_I2CM_STAT0, status); /* clear read status */
|
||||
|
||||
if (status & IH_I2CM_STAT0_I2CMASTERERROR_MASK) {
|
||||
HDMI_INFO_MSG("I2C DDC Read8 extended failed for i2cAddr 0x%x seg 0x%x pointer 0x%x addr 0x%x\n",
|
||||
i2cAddr, segment, pointer, addr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (status & IH_I2CM_STAT0_I2CMASTERDONE_MASK) {
|
||||
int i = 0;
|
||||
|
||||
while (i < 8) { /* read 8 bytes */
|
||||
value[i] = (u8) dev_read(dev,
|
||||
I2CM_READ_BUFF0 + (4 * i));
|
||||
i += 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
HDMI_INFO_MSG("ASSERT I2C DDC Read extended timeout - check system - exiting\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/********************* PUBLIC FUNCTIONS ***********************/
|
||||
|
||||
|
||||
void i2cddc_fast_mode(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
/* bit 4 selects between high and standard speed operation */
|
||||
dev_write_mask(dev, I2CM_DIV, I2CM_DIV_FAST_STD_MODE_MASK, value);
|
||||
}
|
||||
|
||||
|
||||
void i2cddc_mask_interrupts(hdmi_tx_dev_t *dev, u8 mask)
|
||||
{
|
||||
LOG_TRACE1(mask);
|
||||
|
||||
dev_write_mask(dev, I2CM_INT, I2CM_INT_DONE_MASK, mask ? 1 : 0);
|
||||
dev_write_mask(dev, I2CM_CTLINT,
|
||||
I2CM_CTLINT_ARBITRATION_MASK, mask ? 1 : 0);
|
||||
dev_write_mask(dev, I2CM_CTLINT, I2CM_CTLINT_NACK_MASK, mask ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
int ddc_write(hdmi_tx_dev_t *dev, u8 i2cAddr, u8 addr, u8 len, u8 *data)
|
||||
{
|
||||
int i, status = 0;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
int tries = 3;
|
||||
|
||||
do {
|
||||
status = _write(dev, i2cAddr, addr, data[i]);
|
||||
} while (status && tries--);
|
||||
|
||||
if (status) /* Error after 3 failed writes */
|
||||
return status;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ddc_read(hdmi_tx_dev_t *dev, u8 i2cAddr, u8 segment,
|
||||
u8 pointer, u8 addr, u8 len, u8 *data)
|
||||
{
|
||||
int i, status = 0;
|
||||
|
||||
for (i = 0; i < len;) {
|
||||
int tries = 3;
|
||||
|
||||
if ((len - i) >= 8) {
|
||||
do {
|
||||
status = _read8(dev, i2cAddr, segment,
|
||||
pointer, addr + i, &(data[i]));
|
||||
} while (status && tries--);
|
||||
|
||||
if (status) /* Error after 3 failed writes */
|
||||
return status;
|
||||
i += 8;
|
||||
} else {
|
||||
do {
|
||||
status = _read(dev, i2cAddr, segment,
|
||||
pointer, addr + i, &(data[i]));
|
||||
} while (status && tries--);
|
||||
|
||||
if (status) /* Error after 3 failed writes */
|
||||
return status;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
258
sunxi_spl/display/hdmi/access.h
Executable file
258
sunxi_spl/display/hdmi/access.h
Executable file
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
* Allwinner SoCs hdmi2.0 driver.
|
||||
*
|
||||
* Copyright (C) 2016 Allwinner.
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ACCESS_H_
|
||||
#define ACCESS_H_
|
||||
|
||||
#include "hdmitx_dev.h"
|
||||
|
||||
//#include "log.h"
|
||||
|
||||
#define ADDR_JUMP 4
|
||||
|
||||
#define I2C_SFR_CLK 2400
|
||||
#define I2CDDC_TIMEOUT 100
|
||||
#define I2C_MIN_FS_SCL_HIGH_TIME 600/* 61 //63 //75 */
|
||||
#define I2C_MIN_FS_SCL_LOW_TIME 1300/* 132 //137 //163 */
|
||||
#define I2C_MIN_SS_SCL_HIGH_TIME 5333/*4000*//* 4737 //5625 */
|
||||
#define I2C_MIN_SS_SCL_LOW_TIME 6266 /*4700*//* 5263 //6250 */
|
||||
|
||||
/*****************************************************************************
|
||||
* *
|
||||
* E-DDC Registers *
|
||||
* *
|
||||
*****************************************************************************/
|
||||
|
||||
/* I2C DDC Slave address Configuration Register */
|
||||
#define I2CM_SLAVE 0x0001F800
|
||||
#define I2CM_SLAVE_SLAVEADDR_MASK 0x0000007F /* Slave address to be sent during read and write normal operations */
|
||||
|
||||
/* I2C DDC Address Configuration Register */
|
||||
#define I2CM_ADDRESS 0x0001F804
|
||||
#define I2CM_ADDRESS_ADDRESS_MASK 0x000000FF /* Register address for read and write operations */
|
||||
|
||||
/* I2C DDC Data Write Register */
|
||||
#define I2CM_DATAO 0x0001F808
|
||||
#define I2CM_DATAO_DATAO_MASK 0x000000FF /* Data to be written on register pointed by address[7:0] */
|
||||
|
||||
/* I2C DDC Data read Register */
|
||||
#define I2CM_DATAI 0x0001F80C
|
||||
#define I2CM_DATAI_DATAI_MASK 0x000000FF /* Data read from register pointed by address[7:0] */
|
||||
|
||||
/* I2C DDC RD/RD_EXT/WR Operation Register Read and write operation request */
|
||||
#define I2CM_OPERATION 0x0001F810
|
||||
#define I2CM_OPERATION_RD_MASK 0x00000001 /* Single byte read operation request */
|
||||
#define I2CM_OPERATION_RD_EXT_MASK 0x00000002 /* After writing 1'b1 to rd_ext bit a extended data read operation is started (E-DDC read operation) */
|
||||
#define I2CM_OPERATION_RD8_MASK 0x00000004 /* Sequential read operation request */
|
||||
#define I2CM_OPERATION_RD8_EXT_MASK 0x00000008 /* Extended sequential read operation request */
|
||||
#define I2CM_OPERATION_WR_MASK 0x00000010 /* Single byte write operation request */
|
||||
|
||||
/* I2C DDC Done Interrupt Register This register configures the I2C master interrupts */
|
||||
#define I2CM_INT 0x0001F814
|
||||
#define I2CM_INT_DONE_MASK 0x00000004 /* Done interrupt mask signal */
|
||||
#define I2CM_INT_READ_REQ_MASK 0x00000040 /* Read request interruption mask signal */
|
||||
|
||||
/* I2C DDC error Interrupt Register This register configures the I2C master arbitration lost and not acknowledge error interrupts */
|
||||
#define I2CM_CTLINT 0x0001F818
|
||||
#define I2CM_CTLINT_ARBITRATION_MASK 0x00000004 /* Arbitration error interrupt mask signal */
|
||||
#define I2CM_CTLINT_NACK_MASK 0x00000040 /* Not acknowledge error interrupt mask signal */
|
||||
|
||||
/* I2C DDC Speed Control Register This register configures the division relation between master and scl clock */
|
||||
#define I2CM_DIV 0x0001F81C
|
||||
#define I2CM_DIV_SPARE_MASK 0x00000007 /* This bit is a spare register with no associated functionality */
|
||||
#define I2CM_DIV_FAST_STD_MODE_MASK 0x00000008 /* Sets the I2C Master to work in Fast Mode or Standard Mode: 1: Fast Mode 0: Standard Mode */
|
||||
|
||||
/* I2C DDC Segment Address Configuration Register This register configures the segment address for extended R/W destination and is used for EDID reading operations, particularly for the Extended Data Read Operation for Enhanced DDC */
|
||||
#define I2CM_SEGADDR 0x0001F820
|
||||
#define I2CM_SEGADDR_SEG_ADDR_MASK 0x0000007F /* I2C DDC Segment Address Configuration Register */
|
||||
|
||||
/* I2C DDC Software Reset Control Register This register resets the I2C master */
|
||||
#define I2CM_SOFTRSTZ 0x0001F824
|
||||
#define I2CM_SOFTRSTZ_I2C_SOFTRSTZ_MASK 0x00000001 /* I2C Master Software Reset */
|
||||
|
||||
/* I2C DDC Segment Pointer Register This register configures the segment pointer for extended RD/WR request */
|
||||
#define I2CM_SEGPTR 0x0001F828
|
||||
#define I2CM_SEGPTR_SEGPTR_MASK 0x000000FF /* I2C DDC Segment Pointer Register */
|
||||
|
||||
/* I2C DDC Slow Speed SCL High Level Control Register 1 */
|
||||
#define I2CM_SS_SCL_HCNT_1_ADDR 0x0001F82C
|
||||
#define I2CM_SS_SCL_HCNT_1_ADDR_I2CMP_SS_SCL_HCNT1_MASK 0x000000FF /* I2C DDC Slow Speed SCL High Level Control Register 1 */
|
||||
|
||||
/* I2C DDC Slow Speed SCL High Level Control Register 0 */
|
||||
#define I2CM_SS_SCL_HCNT_0_ADDR 0x0001F830
|
||||
#define I2CM_SS_SCL_HCNT_0_ADDR_I2CMP_SS_SCL_HCNT0_MASK 0x000000FF /* I2C DDC Slow Speed SCL High Level Control Register 0 */
|
||||
|
||||
/* I2C DDC Slow Speed SCL Low Level Control Register 1 */
|
||||
#define I2CM_SS_SCL_LCNT_1_ADDR 0x0001F834
|
||||
#define I2CM_SS_SCL_LCNT_1_ADDR_I2CMP_SS_SCL_LCNT1_MASK 0x000000FF /* I2C DDC Slow Speed SCL Low Level Control Register 1 */
|
||||
|
||||
/* I2C DDC Slow Speed SCL Low Level Control Register 0 */
|
||||
#define I2CM_SS_SCL_LCNT_0_ADDR 0x0001F838
|
||||
#define I2CM_SS_SCL_LCNT_0_ADDR_I2CMP_SS_SCL_LCNT0_MASK 0x000000FF /* I2C DDC Slow Speed SCL Low Level Control Register 0 */
|
||||
|
||||
/* I2C DDC Fast Speed SCL High Level Control Register 1 */
|
||||
#define I2CM_FS_SCL_HCNT_1_ADDR 0x0001F83C
|
||||
#define I2CM_FS_SCL_HCNT_1_ADDR_I2CMP_FS_SCL_HCNT1_MASK 0x000000FF /* I2C DDC Fast Speed SCL High Level Control Register 1 */
|
||||
|
||||
/* I2C DDC Fast Speed SCL High Level Control Register 0 */
|
||||
#define I2CM_FS_SCL_HCNT_0_ADDR 0x0001F840
|
||||
#define I2CM_FS_SCL_HCNT_0_ADDR_I2CMP_FS_SCL_HCNT0_MASK 0x000000FF /* I2C DDC Fast Speed SCL High Level Control Register 0 */
|
||||
|
||||
/* I2C DDC Fast Speed SCL Low Level Control Register 1 */
|
||||
#define I2CM_FS_SCL_LCNT_1_ADDR 0x0001F844
|
||||
#define I2CM_FS_SCL_LCNT_1_ADDR_I2CMP_FS_SCL_LCNT1_MASK 0x000000FF /* I2C DDC Fast Speed SCL Low Level Control Register 1 */
|
||||
|
||||
/* I2C DDC Fast Speed SCL Low Level Control Register 0 */
|
||||
#define I2CM_FS_SCL_LCNT_0_ADDR 0x0001F848
|
||||
#define I2CM_FS_SCL_LCNT_0_ADDR_I2CMP_FS_SCL_LCNT0_MASK 0x000000FF /* I2C DDC Fast Speed SCL Low Level Control Register 0 */
|
||||
|
||||
/* I2C DDC SDA Hold Register */
|
||||
#define I2CM_SDA_HOLD 0x0001F84C
|
||||
#define I2CM_SDA_HOLD_OSDA_HOLD_MASK 0x000000FF /* Defines the number of SFR clock cycles to meet tHD;DAT (300 ns) osda_hold = round_to_high_integer (300 ns / (1 / isfrclk_frequency)) */
|
||||
|
||||
/* SCDC Control Register This register configures the SCDC update status read through the I2C master interface */
|
||||
#define I2CM_SCDC_READ_UPDATE 0x0001F850
|
||||
#define I2CM_SCDC_READ_UPDATE_READ_UPDATE_MASK 0x00000001 /* When set to 1'b1, a SCDC Update Read is performed and the read data loaded into registers i2cm_scdc_update0 and i2cm_scdc_update1 */
|
||||
#define I2CM_SCDC_READ_UPDATE_READ_REQUEST_EN_MASK 0x00000010 /* Read request enabled */
|
||||
#define I2CM_SCDC_READ_UPDATE_UPDTRD_VSYNCPOLL_EN_MASK 0x00000020 /* Update read polling enabled */
|
||||
|
||||
/* I2C Master Sequential Read Buffer Register 0 */
|
||||
#define I2CM_READ_BUFF0 0x0001F880
|
||||
#define I2CM_READ_BUFF0_I2CM_READ_BUFF0_MASK 0x000000FF /* Byte 0 of a I2C read buffer sequential read (from address i2cm_address) */
|
||||
|
||||
/* I2C Master Sequential Read Buffer Register 1 */
|
||||
#define I2CM_READ_BUFF1 0x0001F884
|
||||
#define I2CM_READ_BUFF1_I2CM_READ_BUFF1_MASK 0x000000FF /* Byte 1 of a I2C read buffer sequential read (from address i2cm_address+1) */
|
||||
|
||||
/* I2C Master Sequential Read Buffer Register 2 */
|
||||
#define I2CM_READ_BUFF2 0x0001F888
|
||||
#define I2CM_READ_BUFF2_I2CM_READ_BUFF2_MASK 0x000000FF /* Byte 2 of a I2C read buffer sequential read (from address i2cm_address+2) */
|
||||
|
||||
/* I2C Master Sequential Read Buffer Register 3 */
|
||||
#define I2CM_READ_BUFF3 0x0001F88C
|
||||
#define I2CM_READ_BUFF3_I2CM_READ_BUFF3_MASK 0x000000FF /* Byte 3 of a I2C read buffer sequential read (from address i2cm_address+3) */
|
||||
|
||||
/* I2C Master Sequential Read Buffer Register 4 */
|
||||
#define I2CM_READ_BUFF4 0x0001F890
|
||||
#define I2CM_READ_BUFF4_I2CM_READ_BUFF4_MASK 0x000000FF /* Byte 4 of a I2C read buffer sequential read (from address i2cm_address+4) */
|
||||
|
||||
/* I2C Master Sequential Read Buffer Register 5 */
|
||||
#define I2CM_READ_BUFF5 0x0001F894
|
||||
#define I2CM_READ_BUFF5_I2CM_READ_BUFF5_MASK 0x000000FF /* Byte 5 of a I2C read buffer sequential read (from address i2cm_address+5) */
|
||||
|
||||
/* I2C Master Sequential Read Buffer Register 6 */
|
||||
#define I2CM_READ_BUFF6 0x0001F898
|
||||
#define I2CM_READ_BUFF6_I2CM_READ_BUFF6_MASK 0x000000FF /* Byte 6 of a I2C read buffer sequential read (from address i2cm_address+6) */
|
||||
|
||||
/* I2C Master Sequential Read Buffer Register 7 */
|
||||
#define I2CM_READ_BUFF7 0x0001F89C
|
||||
#define I2CM_READ_BUFF7_I2CM_READ_BUFF7_MASK 0x000000FF /* Byte 7 of a I2C read buffer sequential read (from address i2cm_address+7) */
|
||||
|
||||
/* I2C SCDC Read Update Register 0 */
|
||||
#define I2CM_SCDC_UPDATE0 0x0001F8C0
|
||||
#define I2CM_SCDC_UPDATE0_I2CM_SCDC_UPDATE0_MASK 0x000000FF /* Byte 0 of a SCDC I2C update sequential read */
|
||||
|
||||
/* I2C SCDC Read Update Register 1 */
|
||||
#define I2CM_SCDC_UPDATE1 0x0001F8C4
|
||||
#define I2CM_SCDC_UPDATE1_I2CM_SCDC_UPDATE1_MASK 0x000000FF /* Byte 1 of a SCDC I2C update sequential read */
|
||||
|
||||
struct device_access {
|
||||
char name[30];
|
||||
|
||||
int (*initialize)(void);
|
||||
int (*disable)(void);
|
||||
|
||||
void (*write)(u32 addr, u32 data);
|
||||
u32 (*read)(u32 addr);
|
||||
};
|
||||
|
||||
struct system_functions {
|
||||
char name[30];
|
||||
void (*sleep)(int us);
|
||||
};
|
||||
|
||||
void register_bsp_functions(struct device_access *device);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*Read the contents of a register
|
||||
*@param addr of the register
|
||||
*@return 8bit byte containing the contents
|
||||
*/
|
||||
u32 dev_read(hdmi_tx_dev_t *dev, u32 addr);
|
||||
|
||||
/**
|
||||
*Read several bits from a register
|
||||
*@param addr of the register
|
||||
*@param shift of the bit from the beginning
|
||||
*@param width or number of bits to read
|
||||
*@return the contents of the specified bits
|
||||
*/
|
||||
u32 dev_read_mask(hdmi_tx_dev_t *dev, u32 addr, u8 mask);
|
||||
|
||||
/**
|
||||
*Write a byte to a register
|
||||
*@param data to be written to the register
|
||||
*@param addr of the register
|
||||
*/
|
||||
void dev_write(hdmi_tx_dev_t *dev, u32 addr, u32 data);
|
||||
|
||||
/**
|
||||
*Write to several bits in a register
|
||||
*
|
||||
*@param data to be written to the required part
|
||||
*@param addr of the register
|
||||
*@param shift of the bits from the beginning
|
||||
*@param width or number of bits to written to
|
||||
*/
|
||||
void dev_write_mask(hdmi_tx_dev_t *dev, u32 addr, u8 mask, u8 data);
|
||||
|
||||
/**
|
||||
*Initialize communications with development board
|
||||
*
|
||||
*@param baseAddr pointer to the address of the core on the bus
|
||||
*@return TRUE if successful.
|
||||
*/
|
||||
int access_Initialize(hdmi_tx_dev_t *dev);
|
||||
|
||||
/**
|
||||
*Close communications with development board and free resources
|
||||
*
|
||||
*@return TRUE if successful.
|
||||
*/
|
||||
int access_Standby(hdmi_tx_dev_t *dev);
|
||||
|
||||
|
||||
void register_system_functions(struct system_functions *functions);
|
||||
|
||||
void snps_sleep(unsigned us);
|
||||
|
||||
|
||||
|
||||
int ddc_read(hdmi_tx_dev_t *dev, u8 i2cAddr, u8 segment, u8 pointer,
|
||||
u8 addr, u8 len, u8 *data);
|
||||
|
||||
/** Write from extended addresses, E-DDC.
|
||||
*
|
||||
* @param i2cAddr i2c device address to read data
|
||||
* @param addr base address of the module registers
|
||||
* @param len lenght to write
|
||||
* @param data pointer to data write
|
||||
* @returns 0 if ok and error in other cases
|
||||
*/
|
||||
int ddc_write(hdmi_tx_dev_t *dev, u8 i2cAddr, u8 addr, u8 len, u8 *data);
|
||||
void i2cddc_fast_mode(hdmi_tx_dev_t *dev, u8 value);
|
||||
|
||||
|
||||
#endif /* ACCESS_H_ */
|
||||
721
sunxi_spl/display/hdmi/audio.c
Executable file
721
sunxi_spl/display/hdmi/audio.c
Executable file
@@ -0,0 +1,721 @@
|
||||
/*
|
||||
* Allwinner SoCs hdmi2.0 driver.
|
||||
*
|
||||
* Copyright (C) 2016 Allwinner.
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
#include "audio.h"
|
||||
#include "fc_audio.h"
|
||||
|
||||
|
||||
typedef union iec {
|
||||
u32 frequency;
|
||||
u8 sample_size;
|
||||
} iec_t;
|
||||
|
||||
typedef struct iec_sampling_freq {
|
||||
iec_t iec;
|
||||
u8 value;
|
||||
} iec_params_t;
|
||||
|
||||
typedef struct channel_count {
|
||||
unsigned char channel_allocation;
|
||||
unsigned char channel_count;
|
||||
} channel_count_t;
|
||||
|
||||
typedef struct audio_n_computation {
|
||||
u32 pixel_clock;/*KHZ*/
|
||||
u32 n;
|
||||
} audio_n_computation_t;
|
||||
|
||||
/*sampling frequency: unit:Hz*/
|
||||
static iec_params_t iec_original_sampling_freq_values[] = {
|
||||
{{.frequency = 44100}, 0xF},
|
||||
{{.frequency = 88200}, 0x7},
|
||||
{{.frequency = 22050}, 0xB},
|
||||
{{.frequency = 176400}, 0x3},
|
||||
{{.frequency = 48000}, 0xD},
|
||||
{{.frequency = 96000}, 0x5},
|
||||
{{.frequency = 24000}, 0x9},
|
||||
{{.frequency = 192000}, 0x1},
|
||||
{{.frequency = 8000}, 0x6},
|
||||
{{.frequency = 11025}, 0xA},
|
||||
{{.frequency = 12000}, 0x2},
|
||||
{{.frequency = 32000}, 0xC},
|
||||
{{.frequency = 16000}, 0x8},
|
||||
{{.frequency = 0}, 0x0}
|
||||
};
|
||||
|
||||
static iec_params_t iec_sampling_freq_values[] = {
|
||||
{{.frequency = 22050}, 0x4},
|
||||
{{.frequency = 44100}, 0x0},
|
||||
{{.frequency = 88200}, 0x8},
|
||||
{{.frequency = 176400}, 0xC},
|
||||
{{.frequency = 24000}, 0x6},
|
||||
{{.frequency = 48000}, 0x2},
|
||||
{{.frequency = 96000}, 0xA},
|
||||
{{.frequency = 192000}, 0xE},
|
||||
{{.frequency = 32000}, 0x3},
|
||||
{{.frequency = 768000}, 0x9},
|
||||
{{.frequency = 0}, 0x0}
|
||||
};
|
||||
|
||||
iec_params_t iec_word_length[] = {
|
||||
{{.sample_size = 16}, 0x2},
|
||||
{{.sample_size = 17}, 0xC},
|
||||
{{.sample_size = 18}, 0x4},
|
||||
{{.sample_size = 19}, 0x8},
|
||||
{{.sample_size = 20}, 0x3},
|
||||
{{.sample_size = 21}, 0xD},
|
||||
{{.sample_size = 22}, 0x5},
|
||||
{{.sample_size = 23}, 0x9},
|
||||
{{.sample_size = 24}, 0xB},
|
||||
{{.sample_size = 0}, 0x0}
|
||||
};
|
||||
|
||||
static channel_count_t channel_cnt[] = {
|
||||
{0x00, 1},
|
||||
{0x01, 2},
|
||||
{0x02, 2},
|
||||
{0x04, 2},
|
||||
{0x03, 3},
|
||||
{0x05, 3},
|
||||
{0x06, 3},
|
||||
{0x08, 3},
|
||||
{0x14, 3},
|
||||
{0x07, 4},
|
||||
{0x09, 4},
|
||||
{0x0A, 4},
|
||||
{0x0C, 4},
|
||||
{0x15, 4},
|
||||
{0x16, 4},
|
||||
{0x18, 4},
|
||||
{0x0B, 5},
|
||||
{0x0D, 5},
|
||||
{0x0E, 5},
|
||||
{0x10, 5},
|
||||
{0x17, 5},
|
||||
{0x19, 5},
|
||||
{0x1A, 5},
|
||||
{0x1C, 5},
|
||||
{0x20, 5},
|
||||
{0x22, 5},
|
||||
{0x24, 5},
|
||||
{0x26, 5},
|
||||
{0x0F, 6},
|
||||
{0x11, 6},
|
||||
{0x12, 6},
|
||||
{0x1B, 6},
|
||||
{0x1D, 6},
|
||||
{0x1E, 6},
|
||||
{0x21, 6},
|
||||
{0x23, 6},
|
||||
{0x25, 6},
|
||||
{0x27, 6},
|
||||
{0x28, 6},
|
||||
{0x2A, 6},
|
||||
{0x2C, 6},
|
||||
{0x2E, 6},
|
||||
{0x30, 6},
|
||||
{0x13, 7},
|
||||
{0x1F, 7},
|
||||
{0x29, 7},
|
||||
{0x2B, 7},
|
||||
{0x2D, 7},
|
||||
{0x2F, 7},
|
||||
{0x31, 7},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
|
||||
static audio_n_computation_t n_values_32[] = {
|
||||
{0, 4096},
|
||||
{25175, 4576},
|
||||
{25200, 4096},
|
||||
{27000, 4096},
|
||||
{27027, 4096},
|
||||
{31500, 4096},/*add*/
|
||||
{33750, 4096},/*add*/
|
||||
{54000, 4096},
|
||||
{54054, 4096},
|
||||
{67500, 4096},/*add*/
|
||||
{74176, 11648},
|
||||
{74250, 4096},
|
||||
{928125, 8192},/*add*/
|
||||
{148352, 11648},
|
||||
{148500, 4096},
|
||||
{185625, 4096},/*add*/
|
||||
{296703, 5824},
|
||||
{297000, 3072},
|
||||
{371250, 6144},/*add*/
|
||||
{5940000, 3072},/*add*/
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
static audio_n_computation_t n_values_44p1[] = {
|
||||
{0, 6272},
|
||||
{25175, 7007},
|
||||
{25200, 6272},
|
||||
{27000, 6272},
|
||||
{27027, 6272},
|
||||
{31500, 6272},/*add*/
|
||||
{33750, 6272},/*add*/
|
||||
{54000, 6272},
|
||||
{54054, 6272},
|
||||
{67500, 6272},/*add*/
|
||||
{74176, 17836},
|
||||
{74250, 6272},
|
||||
{92812, 6272},/*add*/
|
||||
{148352, 8918},
|
||||
{148500, 6272},
|
||||
{185625, 6272},/*add*/
|
||||
{296703, 4459},
|
||||
{297000, 4704},
|
||||
{371250, 4704},/*add*/
|
||||
{594000, 9048},/*add*/
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
static audio_n_computation_t n_values_48[] = {
|
||||
{0, 6144},
|
||||
{25175, 6864},
|
||||
{25200, 6144},
|
||||
{27000, 6144},
|
||||
{27027, 6144},
|
||||
{31500, 6144},/*add*/
|
||||
{33750, 6144},/*add*/
|
||||
{54000, 6144},
|
||||
{54054, 6144},
|
||||
{67500, 6144},/*add*/
|
||||
{74176, 11648},
|
||||
{74250, 6144},
|
||||
{928125, 12288},/*add*/
|
||||
{148352, 5824},
|
||||
{148500, 6144},
|
||||
{185625, 6144},/*add*/
|
||||
{296703, 5824},
|
||||
{297000, 5120},
|
||||
{371250, 5120},/*add*/
|
||||
{594000, 6144},/*add*/
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
|
||||
u8 audio_channel_count(hdmi_tx_dev_t *dev, audioParams_t *params)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; channel_cnt[i].channel_count != 0; i++) {
|
||||
if (channel_cnt[i].channel_allocation ==
|
||||
params->mChannelAllocation) {
|
||||
return channel_cnt[i].channel_count;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8 audio_iec_original_sampling_freq(hdmi_tx_dev_t *dev, audioParams_t *params)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; iec_original_sampling_freq_values[i].iec.frequency != 0; i++) {
|
||||
if (params->mSamplingFrequency ==
|
||||
iec_original_sampling_freq_values[i].iec.frequency) {
|
||||
u8 value = iec_original_sampling_freq_values[i].value;
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/* Not indicated */
|
||||
return 0x0;
|
||||
}
|
||||
|
||||
u8 audio_iec_sampling_freq(hdmi_tx_dev_t *dev, audioParams_t *params)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; iec_sampling_freq_values[i].iec.frequency != 0; i++) {
|
||||
if (params->mSamplingFrequency ==
|
||||
iec_sampling_freq_values[i].iec.frequency) {
|
||||
u8 value = iec_sampling_freq_values[i].value;
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/* Not indicated */
|
||||
return 0x1;
|
||||
}
|
||||
|
||||
u8 audio_iec_word_length(hdmi_tx_dev_t *dev, audioParams_t *params)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; iec_word_length[i].iec.sample_size != 0; i++) {
|
||||
if (params->mSampleSize == iec_word_length[i].iec.sample_size)
|
||||
return iec_word_length[i].value;
|
||||
}
|
||||
|
||||
return 0x0;
|
||||
}
|
||||
|
||||
u8 audio_is_channel_en(hdmi_tx_dev_t *dev, audioParams_t *params, u8 channel)
|
||||
{
|
||||
switch (channel) {
|
||||
case 0:
|
||||
case 1:
|
||||
HDMI_INFO_MSG("channal %d is enable\n", channel);
|
||||
return 1;
|
||||
case 2:
|
||||
HDMI_INFO_MSG("channal %d is enable\n", channel);
|
||||
return params->mChannelAllocation & BIT(0);
|
||||
case 3:
|
||||
HDMI_INFO_MSG("channal %d is enable\n", channel);
|
||||
return (params->mChannelAllocation & BIT(1)) >> 1;
|
||||
case 4:
|
||||
if (((params->mChannelAllocation > 0x03) &&
|
||||
(params->mChannelAllocation < 0x14)) ||
|
||||
((params->mChannelAllocation > 0x17) &&
|
||||
(params->mChannelAllocation < 0x20))) {
|
||||
HDMI_INFO_MSG("channal %d is enable\n", channel);
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
case 5:
|
||||
if (((params->mChannelAllocation > 0x07) &&
|
||||
(params->mChannelAllocation < 0x14)) ||
|
||||
((params->mChannelAllocation > 0x1C) &&
|
||||
(params->mChannelAllocation < 0x20))) {
|
||||
HDMI_INFO_MSG("channal %d is enable\n", channel);
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
case 6:
|
||||
if ((params->mChannelAllocation > 0x0B) &&
|
||||
(params->mChannelAllocation < 0x20)) {
|
||||
HDMI_INFO_MSG("channal %d is enable\n", channel);
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
case 7:
|
||||
HDMI_INFO_MSG("channal %d is enable\n", channel);
|
||||
return (params->mChannelAllocation & BIT(4)) >> 4;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**********************************************
|
||||
* Internal functions
|
||||
*/
|
||||
static void _audio_clock_n(hdmi_tx_dev_t *dev, u32 value)
|
||||
{
|
||||
/* LOG_TRACE(); */
|
||||
/* 19-bit width */
|
||||
dev_write(dev, AUD_N1, (u8)(value >> 0));
|
||||
dev_write(dev, AUD_N2, (u8)(value >> 8));
|
||||
dev_write_mask(dev, AUD_N3, AUD_N3_AUDN_MASK, (u8)(value >> 16));
|
||||
/* no shift */
|
||||
dev_write_mask(dev, AUD_CTS3, AUD_CTS3_N_SHIFT_MASK, 0);
|
||||
}
|
||||
|
||||
static void _audio_clock_cts(hdmi_tx_dev_t *dev, u32 value)
|
||||
{
|
||||
/* LOG_TRACE1(value); */
|
||||
if (value > 0) {
|
||||
/* 19-bit width */
|
||||
dev_write(dev, AUD_CTS1, (u8)(value >> 0));
|
||||
dev_write(dev, AUD_CTS2, (u8)(value >> 8));
|
||||
dev_write_mask(dev, AUD_CTS3, AUD_CTS3_AUDCTS_MASK,
|
||||
(u8)(value >> 16));
|
||||
dev_write_mask(dev, AUD_CTS3, AUD_CTS3_CTS_MANUAL_MASK, 1);
|
||||
} else{
|
||||
/* Set to automatic generation of CTS values */
|
||||
dev_write_mask(dev, AUD_CTS3, AUD_CTS3_CTS_MANUAL_MASK, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void _audio_clock_f(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
/* LOG_TRACE(); */
|
||||
dev_write_mask(dev, AUD_INPUTCLKFS, AUD_INPUTCLKFS_IFSFACTOR_MASK,
|
||||
value);
|
||||
}
|
||||
|
||||
static void _audio_i2s_reset_fifo(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
LOG_TRACE();
|
||||
dev_write_mask(dev, AUD_CONF0, AUD_CONF0_SW_AUDIO_FIFO_RST_MASK, 1);
|
||||
}
|
||||
|
||||
static void _audio_i2s_data_enable(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write_mask(dev, AUD_CONF0, AUD_CONF0_I2S_IN_EN_MASK, value);
|
||||
}
|
||||
|
||||
static void _audio_i2s_data_mode(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write_mask(dev, AUD_CONF1, AUD_CONF1_I2S_MODE_MASK, value);
|
||||
}
|
||||
|
||||
static void _audio_i2s_data_width(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write_mask(dev, AUD_CONF1, AUD_CONF1_I2S_WIDTH_MASK, value);
|
||||
}
|
||||
|
||||
static void audio_i2s_select(hdmi_tx_dev_t *dev, u8 bit)
|
||||
{
|
||||
LOG_TRACE1(bit);
|
||||
dev_write_mask(dev, AUD_CONF0, AUD_CONF0_I2S_SELECT_MASK, bit);
|
||||
}
|
||||
|
||||
static void audio_i2s_interrupt_mask(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write_mask(dev, AUD_INT, AUD_INT_FIFO_FULL_MASK_MASK |
|
||||
AUD_INT_FIFO_EMPTY_MASK_MASK, value);
|
||||
}
|
||||
|
||||
static void audio_pcuv_insert_mode(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write_mask(dev, AUD_CONF2, AUD_CONF2_INSERT_PCUV_MASK, value);
|
||||
}
|
||||
|
||||
static void audio_nlpcm_select(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write_mask(dev, AUD_CONF2, AUD_CONF2_NLPCM_MASK, value);
|
||||
}
|
||||
|
||||
static void audio_hbr_select(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write_mask(dev, AUD_CONF2, AUD_CONF2_HBR_MASK, value);
|
||||
}
|
||||
|
||||
static int audio_i2s_configure(hdmi_tx_dev_t *dev, audioParams_t *audio)
|
||||
{
|
||||
/*select i2s interface*/
|
||||
audio_i2s_select(dev, 1);
|
||||
/*i2s data off*/
|
||||
_audio_i2s_data_enable(dev, 0x0);
|
||||
|
||||
/*set audio packet mode*/
|
||||
/*PCM mode, I2S input is RAW data,
|
||||
the IP set the raw data to ICE60958 frame packet*/
|
||||
/*PCM mode, the ACR should be fs */
|
||||
/*if (audio->mPacketType == PACKET_NOT_DEFINED) {
|
||||
return -1;
|
||||
}*/
|
||||
|
||||
/*if(audio->mPacketType == AUDIO_SAMPLE_LPCM) {*/
|
||||
/*if (audio->mCodingType == PCM) {
|
||||
audio_pcuv_insert_mode(dev, 1);
|
||||
audio_nlpcm_select(dev, 0);
|
||||
audio_hbr_select(dev, 0);
|
||||
}*/
|
||||
|
||||
if (audio->mCodingType == PCM) {
|
||||
audio_pcuv_insert_mode(dev, 1);
|
||||
audio_hbr_select(dev, 0);
|
||||
audio_nlpcm_select(dev, 0);
|
||||
} else if ((audio->mCodingType == DTS_HD) ||
|
||||
(audio->mCodingType == MAT)) {
|
||||
/* HBR mode, I2S input is ICE60958 frame,
|
||||
you must trans the ICE61937 frame to 60958 frame
|
||||
before it be sent to i2s */
|
||||
/* HBR mode: the frame rate>192Khz, the ACR should be fs/4 */
|
||||
audio_pcuv_insert_mode(dev, 0);
|
||||
audio_hbr_select(dev, 1);
|
||||
audio_nlpcm_select(dev, 1);
|
||||
} else {
|
||||
/*NO-PCM mode, I2S input is ICE60958 frame, you must trans the
|
||||
ICE61937 frame to 60958 frame before it be sent to i2s*/
|
||||
/*NO-PCM mode: the frame rate<=192Khz, the ACR should be fs*/
|
||||
audio_pcuv_insert_mode(dev, 0);
|
||||
audio_hbr_select(dev, 0);
|
||||
audio_nlpcm_select(dev, 1);
|
||||
|
||||
}
|
||||
|
||||
if (audio->mCodingType != PCM)
|
||||
_audio_i2s_data_width(dev, 24);
|
||||
else
|
||||
_audio_i2s_data_width(dev, audio->mSampleSize);
|
||||
/* ATTENTION: fixed I2S data mode (standard) */
|
||||
_audio_i2s_data_mode(dev, 0x0);
|
||||
audio_i2s_interrupt_mask(dev, 3);
|
||||
_audio_i2s_reset_fifo(dev);
|
||||
mc_audio_i2s_reset(dev, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int configure_i2s(hdmi_tx_dev_t *dev, audioParams_t *audio)
|
||||
{
|
||||
audio_i2s_configure(dev, audio);
|
||||
|
||||
switch (audio->mClockFsFactor) {
|
||||
case 64:
|
||||
_audio_clock_f(dev, 4);
|
||||
break;
|
||||
case 128:
|
||||
_audio_clock_f(dev, 0);
|
||||
break;
|
||||
case 256:
|
||||
_audio_clock_f(dev, 1);
|
||||
break;
|
||||
case 512:
|
||||
_audio_clock_f(dev, 2);
|
||||
break;
|
||||
default:
|
||||
_audio_clock_f(dev, 0);
|
||||
HDMI_INFO_MSG("Fs Factor [%d] not supported\n",
|
||||
audio->mClockFsFactor);
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void audio_spdif_interrupt_mask(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write_mask(dev, AUD_SPDIFINT,
|
||||
AUD_SPDIFINT_SPDIF_FIFO_FULL_MASK_MASK |
|
||||
AUD_SPDIFINT_SPDIF_FIFO_EMPTY_MASK_MASK, value);
|
||||
}
|
||||
#if 0
|
||||
static void halAudioMultistream_MetaDataPacket_Descriptor_X(hdmi_tx_dev_t *dev,
|
||||
u8 descrNr, audioMetaDataDescriptor_t *mAudioMetaDataDescriptor)
|
||||
{
|
||||
u8 pb = 0x00;
|
||||
|
||||
dev_write(dev, FC_AMP_PB,
|
||||
(u8)(mAudioMetaDataDescriptor->mMultiviewRightLeft & 0x03));
|
||||
pb = ((mAudioMetaDataDescriptor->mLC_Valid & 0x01) << 7);
|
||||
pb = pb | ((mAudioMetaDataDescriptor->mSuppl_A_Valid & 0x01) << 4);
|
||||
pb = pb | ((mAudioMetaDataDescriptor->mSuppl_A_Mixed & 0x01) << 3);
|
||||
pb = pb | ((mAudioMetaDataDescriptor->mSuppl_A_Type & 0x03) << 0);
|
||||
HDMI_INFO_MSG("NOTICE: pb = 0x%x\n", pb);
|
||||
dev_write(dev, (FC_AMP_PB + (((0x05 * descrNr) + 0x01)*4)), (u8)(pb));
|
||||
if (mAudioMetaDataDescriptor->mLC_Valid == 1) {
|
||||
dev_write(dev, FC_AMP_PB + (((0x05 * descrNr) + 0x02)*4),
|
||||
((u8)(mAudioMetaDataDescriptor->mLanguage_Code[0])) & 0xff);
|
||||
dev_write(dev, FC_AMP_PB + (((0x05 * descrNr) + 0x03)*4),
|
||||
((u8)(mAudioMetaDataDescriptor->mLanguage_Code[1])) & 0xff);
|
||||
dev_write(dev, FC_AMP_PB + (((0x05 * descrNr) + 0x04)*4),
|
||||
((u8)(mAudioMetaDataDescriptor->mLanguage_Code[2])) & 0xff);
|
||||
}
|
||||
HDMI_INFO_MSG("NOTICE: body AMP descriptor 0 0x%x\n",
|
||||
FC_AMP_PB + (((0x05 * descrNr) + 0x00)*4));
|
||||
HDMI_INFO_MSG("NOTICE: body AMP descriptor 0 0x%x\n",
|
||||
FC_AMP_PB + (((0x05 * descrNr) + 0x01)*4));
|
||||
HDMI_INFO_MSG("NOTICE: body AMP descriptor 0 0x%x\n",
|
||||
FC_AMP_PB + (((0x05 * descrNr) + 0x02)*4));
|
||||
HDMI_INFO_MSG("NOTICE: body AMP descriptor 0 0x%x\n",
|
||||
FC_AMP_PB + (((0x05 * descrNr) + 0x03)*4));
|
||||
HDMI_INFO_MSG("NOTICE: body AMP descriptor 0 0x%x\n",
|
||||
FC_AMP_PB + (((0x05 * descrNr) + 0x04)*4));
|
||||
}
|
||||
|
||||
void halAudioMultistream_MetaDataPacket_Header(hdmi_tx_dev_t *dev,
|
||||
audioMetaDataPacket_t *mAudioMetaDataPckt)
|
||||
{
|
||||
dev_write(dev, FC_AMP_HB1,
|
||||
(u8)(mAudioMetaDataPckt->mAudioMetaDataHeader.m3dAudio));
|
||||
dev_write(dev, FC_AMP_HB2,
|
||||
(u8)(((mAudioMetaDataPckt->mAudioMetaDataHeader.mNumViews) |
|
||||
(mAudioMetaDataPckt->mAudioMetaDataHeader.mNumAudioStreams) << 2)));
|
||||
HDMI_INFO_MSG("NOTICE: AMP HB1 0x%x\n", FC_AMP_HB1);
|
||||
HDMI_INFO_MSG("NOTICE: AMP HB1 data 0x%x\n",
|
||||
(u8)(mAudioMetaDataPckt->mAudioMetaDataHeader.m3dAudio));
|
||||
HDMI_INFO_MSG("NOTICE: AMP HB2 0x%x\n", FC_AMP_HB2);
|
||||
HDMI_INFO_MSG("NOTICE: AMP HB2 data 0x%x\n",
|
||||
(u8)(((mAudioMetaDataPckt->mAudioMetaDataHeader.mNumViews) |
|
||||
(mAudioMetaDataPckt->mAudioMetaDataHeader.mNumAudioStreams) << 2)));
|
||||
}
|
||||
|
||||
void halAudioMultistream_MetaDataPacketBody(hdmi_tx_dev_t *dev,
|
||||
audioMetaDataPacket_t *mAudioMetaDataPacket)
|
||||
{
|
||||
u8 cnt = 0;
|
||||
|
||||
while (cnt <= (mAudioMetaDataPacket->mAudioMetaDataHeader.mNumAudioStreams + 1)) {
|
||||
HDMI_INFO_MSG("NOTICE: (mAudioMetaDataPacket->mAudioMetaDataHeader.mNumAudioStreams + 1) = %d\n", (mAudioMetaDataPacket->mAudioMetaDataHeader.mNumAudioStreams + 1));
|
||||
HDMI_INFO_MSG("NOTICE: audiometadata packet descriptor %d\n", cnt);
|
||||
halAudioMultistream_MetaDataPacket_Descriptor_X(dev, 0,
|
||||
&(mAudioMetaDataPacket->mAudioMetaDataDescriptor[cnt]));
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Mute audio.
|
||||
* Stop sending audio packets
|
||||
* @param baseAddr base Address of controller
|
||||
* @param state: 1 to enable/0 to disable the mute
|
||||
* @return TRUE if successful
|
||||
*/
|
||||
int audio_mute(hdmi_tx_dev_t *dev, u8 state)
|
||||
{
|
||||
/* audio mute priority: AVMUTE, sample flat, validity */
|
||||
/* AVMUTE also mutes video */
|
||||
if (state)
|
||||
fc_audio_mute(dev);
|
||||
else
|
||||
fc_audio_unmute(dev);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initial set up of package and prepare it to be configured.
|
||||
* Set audio mute to on.
|
||||
* @param baseAddr base Address of controller
|
||||
* @return TRUE if successful
|
||||
*/
|
||||
int audio_Initialize(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
LOG_TRACE();
|
||||
|
||||
/* Mask all interrupts */
|
||||
audio_i2s_interrupt_mask(dev, 0x3);
|
||||
audio_spdif_interrupt_mask(dev, 0x3);
|
||||
|
||||
return audio_mute(dev, 1);
|
||||
}
|
||||
|
||||
static u32 audio_ComputeN(hdmi_tx_dev_t *dev, u32 freq, u32 pixelClk)
|
||||
{
|
||||
int i = 0;
|
||||
u32 n = 0;
|
||||
audio_n_computation_t *n_values = NULL;
|
||||
int multiplier_factor = 1;
|
||||
|
||||
if ((freq == 64000) || (freq == 882000) || (freq == 96000))
|
||||
multiplier_factor = 2;
|
||||
else if ((freq == 128000) || (freq == 176400) || (freq == 192000))
|
||||
multiplier_factor = 4;
|
||||
else if ((freq == 256000) || (freq == 3528000) || (freq == 384000))
|
||||
multiplier_factor = 8;
|
||||
|
||||
if (32000 == (freq/multiplier_factor)) {
|
||||
n_values = n_values_32;
|
||||
} else if (44100 == (freq/multiplier_factor)) {
|
||||
n_values = n_values_44p1;
|
||||
} else if (48000 == (freq/multiplier_factor)) {
|
||||
n_values = n_values_48;
|
||||
} else {
|
||||
HDMI_INFO_MSG("Could not compute N values\n");
|
||||
HDMI_INFO_MSG("Audio Frequency %dhz\n", freq/1000);
|
||||
HDMI_INFO_MSG("Pixel Clock %dkhz\n", pixelClk);
|
||||
HDMI_INFO_MSG("Multiplier factor %d\n", multiplier_factor);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (i = 0; n_values[i].n != 0; i++) {
|
||||
if (pixelClk == n_values[i].pixel_clock) {
|
||||
n = n_values[i].n * multiplier_factor;
|
||||
HDMI_INFO_MSG("DEBUG:Audio N value = %d\n", n);
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
n = n_values[0].n * multiplier_factor;
|
||||
|
||||
printf("EEROR:Audio N value default = %d\n", n);
|
||||
|
||||
return n;
|
||||
}
|
||||
int audio_Configure(hdmi_tx_dev_t *dev, audioParams_t *audio)
|
||||
{
|
||||
u32 n = 0;
|
||||
|
||||
|
||||
if ((dev == NULL) || (audio == NULL)) {
|
||||
printf("ERROR:Improper function arguments\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (dev->snps_hdmi_ctrl.audio_on == 0) {
|
||||
printf("WARN:audio is not on\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (dev->snps_hdmi_ctrl.hdmi_on == 0) {
|
||||
printf("WARN:avi mode,audio is not configured\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ((audio->mCodingType == ONE_BIT_AUDIO) || (audio->mCodingType == DST)) {
|
||||
printf("ERROR: hdmi does not support this coding type:%d\n",
|
||||
audio->mCodingType);
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
|
||||
if ((dev->snps_hdmi_ctrl.pixel_clock < 74250) &&
|
||||
((audio->mChannelNum * audio->mSamplingFrequency) > 384000)) {
|
||||
printf("ERROR: hdmi do not support this audio framerate on this video format\n");
|
||||
return FALSE;
|
||||
}
|
||||
/* Set PCUV info from external source */
|
||||
audio->mGpaInsertPucv = 1;
|
||||
audio_mute(dev, 1);
|
||||
|
||||
/* Configure Frame Composer audio parameters */
|
||||
fc_audio_config(dev, audio);
|
||||
|
||||
audio->mClockFsFactor = 64;
|
||||
if (audio->mInterfaceType == I2S) {
|
||||
if (configure_i2s(dev, audio) == FALSE) {
|
||||
printf("ERROR:Configuring I2S audio\n");
|
||||
return FALSE;
|
||||
}
|
||||
} else if (audio->mInterfaceType != I2S) {
|
||||
printf("ERROR:the audio interface is not supported\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
n = audio_ComputeN(dev, audio->mSamplingFrequency,
|
||||
dev->snps_hdmi_ctrl.tmds_clk);
|
||||
|
||||
/* for HBR mode and NO-PCM mode: frame rate >192Khz, the ACR should be fs/4 */
|
||||
/*for cmpressed audio frame, alway 2ch and sampling frequency is frame rate*/
|
||||
/*if ((audio->mCodingType == DTS_HD) || (audio->mCodingType == MAT))
|
||||
n = n * 4 / 4;*/
|
||||
pr_info("===========audio_Configure=============\n");
|
||||
_audio_clock_n(dev, n);
|
||||
_audio_clock_cts(dev, 0);
|
||||
|
||||
/*reset fifo*/
|
||||
/*snps_sleep(10);
|
||||
_audio_i2s_reset_fifo(dev);
|
||||
snps_sleep(10);
|
||||
mc_audio_i2s_reset(dev, 0);
|
||||
snps_sleep(10);
|
||||
|
||||
_audio_i2s_data_enable(dev, 0xff);
|
||||
mc_audio_sampler_clock_enable(dev, 0);*/
|
||||
|
||||
_audio_i2s_data_enable(dev, (1 << (audio->mChannelNum / 2)) - 1);
|
||||
|
||||
audio_mute(dev, 0);
|
||||
/* Configure audio info frame packets */
|
||||
fc_audio_info_config(dev, audio);
|
||||
return TRUE;
|
||||
}
|
||||
314
sunxi_spl/display/hdmi/audio.h
Executable file
314
sunxi_spl/display/hdmi/audio.h
Executable file
@@ -0,0 +1,314 @@
|
||||
/*
|
||||
* Allwinner SoCs hdmi2.0 driver.
|
||||
*
|
||||
* Copyright (C) 2016 Allwinner.
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef AUDIO_H_
|
||||
#define AUDIO_H_
|
||||
|
||||
#include "hdmitx_dev.h"
|
||||
#include "main_controller.h"
|
||||
#include "packets.h"
|
||||
#include "frame_composer_reg.h"
|
||||
#include "access.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* *
|
||||
* Audio Sample SPDIF Registers *
|
||||
* *
|
||||
*****************************************************************************/
|
||||
|
||||
/* Audio SPDIF Software FIFO Reset Control Register 0 This register allows the system processor to reset audio FIFOs upon underflow/overflow error detection */
|
||||
#define AUD_SPDIF0 0x0000CC00
|
||||
#define AUD_SPDIF0_SPARE_MASK 0x0000007F /* This field is a "spare" bit with no associated functionality */
|
||||
#define AUD_SPDIF0_SW_AUDIO_FIFO_RST_MASK 0x00000080 /* Audio FIFOs software reset Writing 0b: no action taken Writing 1b: Resets all audio FIFOs Reading from this register always returns 0b */
|
||||
|
||||
/* Audio SPDIF NLPCM and Width Configuration Register 1 This register configures the SPDIF data width */
|
||||
#define AUD_SPDIF1 0x0000CC04
|
||||
#define AUD_SPDIF1_SPDIF_WIDTH_MASK 0x0000001F /* SPDIF input data width SPDIF_width[4:0] | Action 00000b-01111b | Not used 10000b | 16-bit data samples at input 10001b | 17-bit data samples at input 10010b | 18-bit data samples at input 10011b | 19-bit data samples at input 10100b | 20-bit data samples at input 10101b | 21-bit data samples at input 10110b | 22-bit data samples at input 10111b | 23-bit data samples at input 11000b | 24-bit data samples at input 11001b-11111b | Not Used */
|
||||
#define AUD_SPDIF1_SPARE_MASK 0x00000020 /* This field is a "spare" bit with no associated functionality */
|
||||
#define AUD_SPDIF1_SPDIF_HBR_MODE_MASK 0x00000040 /* When set to 1'b1, this bit field indicates that the input stream has a High Bit Rate (HBR) to be transmitted in HDMI HBR packets */
|
||||
#define AUD_SPDIF1_SETNLPCM_MASK 0x00000080 /* Select Non-Linear (1b) / Linear (0b) PCM mode */
|
||||
|
||||
/* Audio SPDIF FIFO Empty/Full Mask Register */
|
||||
#define AUD_SPDIFINT 0x0000CC08
|
||||
#define AUD_SPDIFINT_SPDIF_FIFO_FULL_MASK_MASK 0x00000004 /* SPDIF FIFO full mask */
|
||||
#define AUD_SPDIFINT_SPDIF_FIFO_EMPTY_MASK_MASK 0x00000008 /* SPDIF FIFO empty mask */
|
||||
|
||||
/* Audio SPDIF Mask Interrupt Register 1 This register masks interrupts present in the SPDIF module */
|
||||
#define AUD_SPDIFINT1 0x0000CC0C
|
||||
#define AUD_SPDIFINT1_FIFO_OVERRUN_MASK_MASK 0x00000010 /* FIFO overrun mask */
|
||||
|
||||
/* Audio SPDIF Enable Configuration Register 2 */
|
||||
#define AUD_SPDIF2 0x0000CC10
|
||||
#define AUD_SPDIF2_IN_EN_MASK 0x0000000F
|
||||
|
||||
/*****************************************************************************
|
||||
* *
|
||||
* Audio Packetizer Registers *
|
||||
* *
|
||||
*****************************************************************************/
|
||||
|
||||
/* Audio Clock Regenerator N Value Register 1 For N expected values, refer to the HDMI 1 */
|
||||
#define AUD_N1 0x0000C800
|
||||
#define AUD_N1_AUDN_MASK 0x000000FF /* HDMI Audio Clock Regenerator N value */
|
||||
|
||||
/* Audio Clock Regenerator N Value Register 2 For N expected values, refer to the HDMI 1 */
|
||||
#define AUD_N2 0x0000C804
|
||||
#define AUD_N2_AUDN_MASK 0x000000FF /* HDMI Audio Clock Regenerator N value */
|
||||
|
||||
/* Audio Clock Regenerator N Value Register 3 For N expected values, refer to the HDMI 1 */
|
||||
#define AUD_N3 0x0000C808
|
||||
#define AUD_N3_AUDN_MASK 0x0000000F /* HDMI Audio Clock Regenerator N value */
|
||||
#define AUD_N3_NCTS_ATOMIC_WRITE_MASK 0x00000080 /* When set, the new N and CTS values are only used when aud_n1 register is written */
|
||||
|
||||
/* Audio Clock Regenerator CTS Value Register 1 For CTS expected values, refer to the HDMI 1 */
|
||||
#define AUD_CTS1 0x0000C80C
|
||||
#define AUD_CTS1_AUDCTS_MASK 0x000000FF /* HDMI Audio Clock Regenerator CTS calculated value */
|
||||
|
||||
/* Audio Clock Regenerator CTS Register 2 For CTS expected values, refer to the HDMI 1 */
|
||||
#define AUD_CTS2 0x0000C810
|
||||
#define AUD_CTS2_AUDCTS_MASK 0x000000FF /* HDMI Audio Clock Regenerator CTS calculated value */
|
||||
|
||||
/* Audio Clock Regenerator CTS value Register 3 */
|
||||
#define AUD_CTS3 0x0000C814
|
||||
#define AUD_CTS3_AUDCTS_MASK 0x0000000F /* HDMI Audio Clock Regenerator CTS calculated value */
|
||||
#define AUD_CTS3_CTS_MANUAL_MASK 0x00000010 /* If the CTS_manual bit equals 0b, this registers contains audCTS[19:0] generated by the Cycle time counter according to the specified timing */
|
||||
#define AUD_CTS3_N_SHIFT_MASK 0x000000E0 /* N_shift factor configuration: N_shift | Shift Factor | Action 0 | 1 | This is the N shift factor used for the case that N' ="audN[19:0]" */
|
||||
|
||||
/* Audio Input Clock FS Factor Register */
|
||||
#define AUD_INPUTCLKFS 0x0000C818
|
||||
#define AUD_INPUTCLKFS_IFSFACTOR_MASK 0x00000007 /* Fs factor configuration: ifsfactor[2:0] | Audio Clock | Action 0 | 128xFs | If you select the Bypass SPDIF DRU unit in coreConsultant, the input audio clock (either I2S or SPDIF according to configuration) is used at the audio packetizer to calculate the CTS value and ACR packet insertion rate */
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* *
|
||||
* Audio Sample Registers *
|
||||
* *
|
||||
*****************************************************************************/
|
||||
|
||||
/* Audio I2S Software FIFO Reset, Select, and Enable Control Register 0 This register configures the I2S input enable that indicates which input I2S channels have valid data */
|
||||
#define AUD_CONF0 0x0000C400
|
||||
#define AUD_CONF0_I2S_IN_EN_MASK 0x0000000F /* Action I2S_in_en[0] - I2Sdata[0] enable I2S_in_en[1] - I2Sdata[1] enable I2S_in_en[2] - I2Sdata[2] enable I2S_in_en[3] - I2Sdata[3] enable */
|
||||
#define AUD_CONF0_SPARE_1_MASK 0x00000010 /* This field is a "spare" bit with no associated functionality */
|
||||
#define AUD_CONF0_I2S_SELECT_MASK 0x00000020 /* 1b: Selects I2S Audio Interface 0b: Selects the second (SPDIF/GPA) interface, in configurations with more that one audio interface (DOUBLE/GDOUBLE) */
|
||||
#define AUD_CONF0_SPARE_2_MASK 0x00000040 /* This field is a "spare" bit with no associated functionality */
|
||||
#define AUD_CONF0_SW_AUDIO_FIFO_RST_MASK 0x00000080 /* Audio FIFOs software reset - Writing 0b: no action taken - Writing 1b: Resets all audio FIFOs Reading from this register always returns 0b */
|
||||
|
||||
/* Audio I2S Width and Mode Configuration Register 1 This register configures the I2S mode and data width of the input data */
|
||||
#define AUD_CONF1 0x0000C404
|
||||
#define AUD_CONF1_I2S_WIDTH_MASK 0x0000001F /* I2S input data width I2S_width[4:0] | Action 00000b-01111b | Not used 10000b | 16 bit data samples at input 10001b | 17 bit data samples at input 10010b | 18 bit data samples at input 10011b | 19 bit data samples at input 10100b | 20 bit data samples at input 10101b | 21 bit data samples at input 10110b | 22 bit data samples at input 10111b | 23 bit data samples at input 11000b | 24 bit data samples at input 11001b-11111b | Not Used */
|
||||
/* I2S input data mode I2S_mode[4:0] | Action */
|
||||
/* 000b | Standard I2S mode */
|
||||
/* 001b | Right-justified I2S mode */
|
||||
/* 010b | Left-justified I2S mode */
|
||||
/* 011b | Burst 1 mode */
|
||||
/* 100b | Burst 2 mode */
|
||||
#define AUD_CONF1_I2S_MODE_MASK 0x000000E0
|
||||
/* I2S FIFO status and interrupts */
|
||||
#define AUD_INT 0x0000C408
|
||||
#define AUD_INT_FIFO_FULL_MASK_MASK 0x00000004 /* FIFO full mask */
|
||||
#define AUD_INT_FIFO_EMPTY_MASK_MASK 0x00000008 /* FIFO empty mask */
|
||||
|
||||
/* Audio I2S NLPCM and HBR configuration Register 2 This register configures the I2S Audio Data mapping */
|
||||
#define AUD_CONF2 0x0000C40C
|
||||
#define AUD_CONF2_HBR_MASK 0x00000001 /* I2S HBR Mode Enable */
|
||||
#define AUD_CONF2_NLPCM_MASK 0x00000002 /* I2S NLPCM Mode Enable */
|
||||
#define AUD_CONF2_INSERT_PCUV_MASK 0x00000004
|
||||
|
||||
/* I2S Mask Interrupt Register This register masks the interrupts present in the I2S module */
|
||||
#define AUD_INT1 0x0000C410
|
||||
#define AUD_INT1_FIFO_OVERRUN_MASK_MASK 0x00000010 /* FIFO overrun mask */
|
||||
|
||||
|
||||
/***********AUDIO************/
|
||||
typedef enum {
|
||||
INTERFACE_NOT_DEFINED = -1, I2S = 0, SPDIF, HBR, GPA, DMA
|
||||
} interfaceType_t;
|
||||
|
||||
typedef enum {
|
||||
PACKET_NOT_DEFINED = -1, AUDIO_SAMPLE = 1, HBR_STREAM
|
||||
} packet_t;
|
||||
|
||||
typedef enum {
|
||||
CODING_NOT_DEFINED = -1,
|
||||
PCM = 1,
|
||||
AC3,
|
||||
MPEG1,
|
||||
MP3,
|
||||
MPEG2,
|
||||
AAC,
|
||||
DTS,
|
||||
ATRAC,
|
||||
ONE_BIT_AUDIO,
|
||||
DOLBY_DIGITAL_PLUS,
|
||||
DTS_HD,
|
||||
MAT,
|
||||
DST,
|
||||
WMAPRO
|
||||
} codingType_t;
|
||||
|
||||
typedef enum {
|
||||
DMA_NOT_DEFINED = -1,
|
||||
DMA_4_BEAT_INCREMENT = 0,
|
||||
DMA_8_BEAT_INCREMENT,
|
||||
DMA_16_BEAT_INCREMENT,
|
||||
DMA_UNUSED_BEAT_INCREMENT,
|
||||
DMA_UNSPECIFIED_INCREMENT
|
||||
} dmaIncrement_t;
|
||||
|
||||
/* Supplementary Audio type, table 8-14 HDMI 2.0 Spec. pg 79 */
|
||||
typedef enum {
|
||||
RESERVED = 0,
|
||||
AUDIO_FOR_VIS_IMP_NARR,
|
||||
AUDIO_FOR_VIS_IMP_SPOKEN,
|
||||
AUDIO_FOR_HEAR_IMPAIRED,
|
||||
ADDITIONAL_AUDIO
|
||||
} suppl_A_Type_t;
|
||||
|
||||
|
||||
|
||||
/***********AUDIO************/
|
||||
/* Audio Metadata Packet Header, table 8-4 HDMI 2.0 Spec. pg 71 */
|
||||
typedef struct {
|
||||
u8 m3dAudio;
|
||||
u8 mNumViews;
|
||||
u8 mNumAudioStreams;
|
||||
} audioMetaDataHeader_t;
|
||||
|
||||
/* Audio Metadata Descriptor, table 8-13 HDMI 2.0 Spec. pg 78 */
|
||||
typedef struct {
|
||||
u8 mMultiviewRightLeft;
|
||||
u8 mLC_Valid;
|
||||
u8 mSuppl_A_Valid;
|
||||
u8 mSuppl_A_Mixed;
|
||||
suppl_A_Type_t mSuppl_A_Type;
|
||||
u8 mLanguage_Code[3];/*ISO 639.2 alpha-3 code, examples: eng,fre,spa,por,jpn,chi */
|
||||
|
||||
} audioMetaDataDescriptor_t;
|
||||
|
||||
typedef struct {
|
||||
audioMetaDataHeader_t mAudioMetaDataHeader;
|
||||
audioMetaDataDescriptor_t mAudioMetaDataDescriptor[4];
|
||||
} audioMetaDataPacket_t;
|
||||
|
||||
/**
|
||||
* For detailed handling of this structure,
|
||||
* refer to documentation of the functions
|
||||
*/
|
||||
typedef struct {
|
||||
interfaceType_t mInterfaceType;
|
||||
|
||||
codingType_t mCodingType; /** (audioParams_t *params, see InfoFrame) */
|
||||
|
||||
u8 mChannelNum;
|
||||
|
||||
u8 mChannelAllocation; /** channel allocation (audioParams_t *params,
|
||||
see InfoFrame) */
|
||||
|
||||
u8 mSampleSize; /** sample size (audioParams_t *params, 16 to 24) */
|
||||
|
||||
u32 mSamplingFrequency; /** sampling frequency (audioParams_t *params, Hz) */
|
||||
|
||||
u8 mLevelShiftValue; /** level shift value (audioParams_t *params,
|
||||
see InfoFrame) */
|
||||
|
||||
u8 mDownMixInhibitFlag; /** down-mix inhibit flag (audioParams_t *params,
|
||||
see InfoFrame) */
|
||||
|
||||
u8 mIecCopyright; /** IEC copyright */
|
||||
|
||||
u8 mIecCgmsA; /** IEC CGMS-A */
|
||||
|
||||
u8 mIecPcmMode; /** IEC PCM mode */
|
||||
|
||||
u8 mIecCategoryCode; /** IEC category code */
|
||||
|
||||
u8 mIecSourceNumber; /** IEC source number */
|
||||
|
||||
u8 mIecClockAccuracy; /** IEC clock accuracy */
|
||||
|
||||
packet_t mPacketType; /** packet type. currently only Audio Sample (AUDS)
|
||||
and High Bit Rate (HBR) are supported */
|
||||
|
||||
u16 mClockFsFactor; /** Input audio clock Fs factor used at the audio
|
||||
packetizer to calculate the CTS value and ACR packet
|
||||
insertion rate */
|
||||
|
||||
dmaIncrement_t mDmaBeatIncrement; /** Incremental burst modes: unspecified
|
||||
lengths (upper limit is 1kB boundary) and
|
||||
INCR4, INCR8, and INCR16 fixed-beat burst */
|
||||
|
||||
u8 mDmaThreshold; /** When the number of samples in the Audio FIFO is lower
|
||||
than the threshold, the DMA engine requests a new burst
|
||||
request to the AHB master interface */
|
||||
|
||||
u8 mDmaHlock; /** Master burst lock mechanism */
|
||||
|
||||
u8 mGpaInsertPucv; /* discard incoming (Parity, Channel status, User bit,
|
||||
Valid and B bit) data and insert data configured in
|
||||
controller instead */
|
||||
audioMetaDataPacket_t mAudioMetaDataPacket; /** Audio Multistream variables, to be written to the Audio Metadata Packet */
|
||||
} audioParams_t;
|
||||
/***********AUDIO************/
|
||||
|
||||
|
||||
/**
|
||||
* @param params pointer to the audio parameters structure
|
||||
* @return number of audio channels transmitted -1
|
||||
*/
|
||||
u8 audio_channel_count(hdmi_tx_dev_t *dev, audioParams_t *params);
|
||||
|
||||
/**
|
||||
* @param params pointer to the audio parameters structure
|
||||
*/
|
||||
u8 audio_iec_original_sampling_freq(hdmi_tx_dev_t *dev, audioParams_t *params);
|
||||
|
||||
/**
|
||||
* @param params pointer to the audio parameters structure
|
||||
*/
|
||||
u8 audio_iec_sampling_freq(hdmi_tx_dev_t *dev, audioParams_t *params);
|
||||
|
||||
/**
|
||||
* @param params pointer to the audio parameters structure
|
||||
*/
|
||||
u8 audio_iec_word_length(hdmi_tx_dev_t *dev, audioParams_t *params);
|
||||
|
||||
/**
|
||||
* return if channel is enabled or not using the user's channel allocation
|
||||
* code
|
||||
* @param params pointer to the audio parameters structure
|
||||
* @param channel in question -1
|
||||
* @return 1 if channel is to be enabled, 0 otherwise
|
||||
*/
|
||||
u8 audio_is_channel_en(hdmi_tx_dev_t *dev, audioParams_t *params, u8 channel);
|
||||
|
||||
void halAudioMultistream_MetaDataPacket_Header(hdmi_tx_dev_t *dev,
|
||||
audioMetaDataPacket_t *mAudioMetaDataPckt);
|
||||
void halAudioMultistream_MetaDataPacketBody(hdmi_tx_dev_t *dev,
|
||||
audioMetaDataPacket_t *mAudioMetaDataPacket);
|
||||
|
||||
int audio_mute(hdmi_tx_dev_t *dev, u8 state);
|
||||
int audio_Initialize(hdmi_tx_dev_t *dev);
|
||||
|
||||
/**
|
||||
* Configure hardware modules corresponding to user requirements to start transmitting audio packets.
|
||||
* @param baseAddr base Address of controller
|
||||
* @param params: audio parameters
|
||||
* @param pixelClk: pixel clock [0.01 MHz]
|
||||
* @param ratioClk: ratio clock (TMDS / Pixel) [0.01]
|
||||
* @return TRUE if successful
|
||||
*/
|
||||
int audio_Configure(hdmi_tx_dev_t *dev, audioParams_t *params);
|
||||
|
||||
extern void fc_audio_info_config(hdmi_tx_dev_t *dev, audioParams_t *audio);
|
||||
|
||||
|
||||
#endif /* AUDIO_H_ */
|
||||
93
sunxi_spl/display/hdmi/clk.c
Executable file
93
sunxi_spl/display/hdmi/clk.c
Executable file
@@ -0,0 +1,93 @@
|
||||
#include "common.h"
|
||||
|
||||
#define PLL_DE_CLK_REG_BASE 0x03001060
|
||||
#define PLL_VIDEO1_CLK_REG_BASE 0x03001048
|
||||
#define DE_CLK_GATE_BUS_REG_BASE 0x0300160c
|
||||
#define DE_CLK_GATE_ENABLE_REG_BASE 0x03001600
|
||||
#define TCON_TV_CLK_REG_BASE 0x03001b80
|
||||
#define TCON_TV_CLK_GATE_BUS_REG_BASE 0x03001b9c
|
||||
#define HDMI_DDC_CLK_REG_BASE 0x03001b04
|
||||
#define HDMI_CLK_GATE_BUS_REG_BASE 0x03001b1c
|
||||
#define HDMI_CLK_GATE_ENABLE_REG_BASE 0x03001b00
|
||||
#define TCON_TOP_CLK_GATE_BUS_REG_BASE 0x03001b5c
|
||||
|
||||
#define GPIO_DDC_GROUP_FUNC_ADDR 0x0300b100
|
||||
#define GPIO_DDC_GROUP_PULL_ADDR 0x0300b118
|
||||
#define GPIO_DDC_GROUP_DLEVEL_ADDR 0x0300b110
|
||||
|
||||
void hdmi_clk_enable (void)
|
||||
{
|
||||
volatile unsigned int *pll_video1_reg = (unsigned int *)PLL_VIDEO1_CLK_REG_BASE;
|
||||
volatile unsigned int *hdmi_clk_gate_bus_reg = (unsigned int *)HDMI_CLK_GATE_BUS_REG_BASE;
|
||||
volatile unsigned int *hdmi_clk_gate_enable_reg = (unsigned int *)HDMI_CLK_GATE_ENABLE_REG_BASE;
|
||||
|
||||
*pll_video1_reg = 0x80006201;
|
||||
*hdmi_clk_gate_bus_reg = 0x00030001;
|
||||
*hdmi_clk_gate_enable_reg = 0x81000000;
|
||||
}
|
||||
|
||||
void de_clk_enable (void)
|
||||
{
|
||||
volatile unsigned int *pll_de_reg = (unsigned int *)PLL_DE_CLK_REG_BASE;
|
||||
volatile unsigned int *de_clk_gate_bus_reg = (unsigned int *)DE_CLK_GATE_BUS_REG_BASE;
|
||||
volatile unsigned int *de_clk_gate_enable_reg = (unsigned int *)DE_CLK_GATE_ENABLE_REG_BASE;
|
||||
|
||||
*pll_de_reg = 0x80001c00;
|
||||
*de_clk_gate_bus_reg = 0x00010001;
|
||||
*de_clk_gate_enable_reg = 0x80000000;
|
||||
}
|
||||
|
||||
void hdmi_ddc_clk_enable (void)
|
||||
{
|
||||
volatile unsigned int *hdmi_ddc_clk_reg = (unsigned int *)HDMI_DDC_CLK_REG_BASE;
|
||||
|
||||
*hdmi_ddc_clk_reg = 0x80000000;
|
||||
}
|
||||
|
||||
void hdmi_ddc_gpio_enable (void)
|
||||
{
|
||||
volatile unsigned int *gpio_ddc_group_func_reg = (unsigned int *)GPIO_DDC_GROUP_FUNC_ADDR;
|
||||
volatile unsigned int *gpio_ddc_group_pull_reg = (unsigned int *)GPIO_DDC_GROUP_PULL_ADDR;
|
||||
volatile unsigned int *gpio_ddc_group_dlevel_reg = (unsigned int *)GPIO_DDC_GROUP_DLEVEL_ADDR;
|
||||
|
||||
*gpio_ddc_group_func_reg = 0x722;
|
||||
*gpio_ddc_group_pull_reg = 0x5;
|
||||
*gpio_ddc_group_dlevel_reg = 0x15555f;
|
||||
|
||||
}
|
||||
|
||||
void tcon_tv_clk_config (u32 rate)
|
||||
{
|
||||
volatile unsigned int *tcon_tv_reg = (unsigned int *)TCON_TV_CLK_REG_BASE;
|
||||
volatile unsigned int *tcon_tv_clk_gate_bus_reg = (unsigned int *)TCON_TV_CLK_GATE_BUS_REG_BASE;
|
||||
|
||||
switch (rate) {
|
||||
case 148500000:
|
||||
*tcon_tv_reg = 0x82000003;
|
||||
break;
|
||||
case 297000000:
|
||||
*tcon_tv_reg = 0x82000001;
|
||||
break;
|
||||
case 74250000:
|
||||
*tcon_tv_reg = 0x82000007;
|
||||
break;
|
||||
case 594000000:
|
||||
*tcon_tv_reg = 0x82000000;
|
||||
break;
|
||||
case 27027000:
|
||||
case 27000000:
|
||||
*tcon_tv_reg = 0x8200010a;
|
||||
break;
|
||||
default:
|
||||
*tcon_tv_reg = 0x82000003;
|
||||
break;
|
||||
}
|
||||
*tcon_tv_clk_gate_bus_reg = 0x00010001;
|
||||
}
|
||||
|
||||
void tcon_top_clk_enable (void)
|
||||
{
|
||||
volatile unsigned int *tcon_top_clk_gate_bus_reg = (unsigned int *)TCON_TOP_CLK_GATE_BUS_REG_BASE;
|
||||
|
||||
*tcon_top_clk_gate_bus_reg = 0x00010001;
|
||||
}
|
||||
11
sunxi_spl/display/hdmi/clk.h
Executable file
11
sunxi_spl/display/hdmi/clk.h
Executable file
@@ -0,0 +1,11 @@
|
||||
#ifndef __CLK_H__
|
||||
#define __CLK_H__
|
||||
|
||||
void hdmi_clk_enable (void);
|
||||
void hdmi_ddc_clk_enable (void);
|
||||
void tcon_tv_clk_config (u32 rate);
|
||||
void de_clk_enable (void);
|
||||
void tcon_top_clk_enable (void);
|
||||
void hdmi_ddc_gpio_enable (void);
|
||||
|
||||
#endif
|
||||
184
sunxi_spl/display/hdmi/display.c
Executable file
184
sunxi_spl/display/hdmi/display.c
Executable file
@@ -0,0 +1,184 @@
|
||||
|
||||
#include <common.h>
|
||||
#include <private_boot0.h>
|
||||
#include <private_uboot.h>
|
||||
|
||||
#include "tcon.h"
|
||||
#include "clk.h"
|
||||
#include "hdmi.h"
|
||||
#include "phy.h"
|
||||
|
||||
#define TCON_TV_REG_BASE 0x06515000
|
||||
#define TCON_TOP_REG_BASE 0x06510000
|
||||
#define SCREEN_ID 1
|
||||
#define DE_NUM 0
|
||||
static enum disp_csc_type sPixelFormat;
|
||||
|
||||
|
||||
int disp_al_hdmi_cfg(u32 screen_id, struct disp_video_timings *video_info)
|
||||
{
|
||||
|
||||
if (sPixelFormat == DISP_CSC_TYPE_YUV420) {
|
||||
video_info->x_res /= 2;
|
||||
video_info->hor_total_time /= 2;
|
||||
video_info->hor_back_porch /= 2;
|
||||
video_info->hor_front_porch /= 2;
|
||||
video_info->hor_sync_time /= 2;
|
||||
}
|
||||
|
||||
|
||||
tcon_init(screen_id);
|
||||
tcon1_set_timming(screen_id, video_info);
|
||||
|
||||
tcon1_src_select(screen_id, LCD_SRC_DE, DE_NUM);
|
||||
tcon1_black_src(screen_id, 1, sPixelFormat);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* hdmi */
|
||||
int disp_al_hdmi_enable(u32 screen_id)
|
||||
{
|
||||
tcon1_hdmi_clk_enable(screen_id, 1);
|
||||
|
||||
tcon1_open(screen_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define TOLOWER(a) ((a<='Z') ? a+('a'-'A') : a )
|
||||
static bool isxdigit(char c)
|
||||
{
|
||||
if ((c>='0' && c<='9') || (c>='A' && c<='F') || (c>='a' && c<='f'))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
static bool isdigit(char c)
|
||||
{
|
||||
if (c>='0' && c<='9')
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static unsigned int simple_guess_base(const char *cp)
|
||||
{
|
||||
if (cp[0] == '0') {
|
||||
if (TOLOWER(cp[1]) == 'x' && isxdigit(cp[2]))
|
||||
return 16;
|
||||
else
|
||||
return 8;
|
||||
} else {
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base)
|
||||
{
|
||||
unsigned long result = 0;
|
||||
|
||||
if (!base)
|
||||
base = simple_guess_base(cp);
|
||||
|
||||
if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')
|
||||
cp += 2;
|
||||
|
||||
while (isxdigit(*cp)) {
|
||||
unsigned int value;
|
||||
|
||||
value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;
|
||||
if (value >= base)
|
||||
break;
|
||||
result = result * base + value;
|
||||
cp++;
|
||||
}
|
||||
|
||||
if (endp)
|
||||
*endp = (char *)cp;
|
||||
return result;
|
||||
}
|
||||
|
||||
static int get_display_resolution(const int type, char *buf, int num)
|
||||
{
|
||||
int format = 0;
|
||||
char *p = buf;
|
||||
|
||||
while (num > 0) {
|
||||
while ((*p != '\n') && (*p != '\0'))
|
||||
p++;
|
||||
*p++ = '\0';
|
||||
format = simple_strtoul(buf, NULL, 16);
|
||||
if (type == ((format >> 8) & 0xFF)) {
|
||||
printf("get format[%x] for type[%d]\n", format, type);
|
||||
return format & 0xff;
|
||||
}
|
||||
num -= (p - buf);
|
||||
buf = p;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void disp_init (void)
|
||||
{
|
||||
char buf[64];
|
||||
u32 rate;
|
||||
u32 len;
|
||||
struct disp_device_config config;
|
||||
struct disp_video_timings video_info;
|
||||
struct spare_parameter_head_t *param_head = NULL;
|
||||
|
||||
hdmi_clk_enable();
|
||||
hdmi_ddc_clk_enable();
|
||||
hdmi_ddc_gpio_enable();
|
||||
de_clk_enable ();
|
||||
tcon_top_clk_enable();
|
||||
tcon_set_reg_base(1, TCON_TV_REG_BASE);
|
||||
tcon_top_set_reg_base(0, TCON_TOP_REG_BASE);
|
||||
|
||||
hdmi_init();
|
||||
|
||||
param_head = (struct spare_parameter_head_t *)CONFIG_SUNXI_PARAMETER_ADDR;
|
||||
|
||||
len = strlen(param_head->para_data.display_param.resolution);
|
||||
strncpy(buf, param_head->para_data.display_param.resolution, 64);
|
||||
config.type = DISP_OUTPUT_TYPE_HDMI;
|
||||
config.mode = get_display_resolution(DISP_OUTPUT_TYPE_HDMI, buf, len);
|
||||
config.format = param_head->para_data.display_param.format;
|
||||
config.bits = param_head->para_data.display_param.depth;
|
||||
config.eotf = param_head->para_data.display_param.eotf;
|
||||
config.cs = param_head->para_data.display_param.color_space;
|
||||
|
||||
if (config.mode == -1)
|
||||
{
|
||||
config.mode = DISP_TV_MOD_1080P_60HZ;
|
||||
config.bits = DISP_DATA_8BITS;
|
||||
config.eotf= DISP_EOTF_UNDEF;
|
||||
config.cs = DISP_BT709;
|
||||
config.format = DISP_CSC_TYPE_YUV444;
|
||||
|
||||
}
|
||||
|
||||
sPixelFormat = config.format;
|
||||
/*
|
||||
printf("*********** parameter data************\n");
|
||||
printf("display resolution : %s\n", param_head->para_data.display_param.resolution);
|
||||
printf("display margin : %s\n", param_head->para_data.display_param.margin);
|
||||
printf("display vendorid : %s\n", param_head->para_data.display_param.vendorid);
|
||||
printf("display mode : %d\n",config.mode);
|
||||
printf("display format : %d\n", param_head->para_data.display_param.format);
|
||||
printf("display depth : %d\n", param_head->para_data.display_param.depth);
|
||||
printf("display eotf : %d\n", param_head->para_data.display_param.eotf);
|
||||
printf("display color_space: %d\n", param_head->para_data.display_param.color_space);
|
||||
*/
|
||||
hdmi_set_static_config(&config);
|
||||
hdmi_get_video_timming_info(&video_info);
|
||||
|
||||
rate = video_info.pixel_clk * (video_info.pixel_repeat + 1);
|
||||
if (sPixelFormat == DISP_CSC_TYPE_YUV420)
|
||||
rate /= 2;
|
||||
tcon_tv_clk_config(rate);
|
||||
|
||||
disp_al_hdmi_cfg(SCREEN_ID, &video_info);
|
||||
disp_al_hdmi_enable(SCREEN_ID);
|
||||
hdmi_configure(PHY_MODEL_301);
|
||||
|
||||
printf("disp_init end\n");
|
||||
}
|
||||
338
sunxi_spl/display/hdmi/fc_audio.c
Executable file
338
sunxi_spl/display/hdmi/fc_audio.c
Executable file
@@ -0,0 +1,338 @@
|
||||
/*
|
||||
* Allwinner SoCs hdmi2.0 driver.
|
||||
*
|
||||
* Copyright (C) 2016 Allwinner.
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#include "fc_audio.h"
|
||||
|
||||
static void fc_packet_layout(hdmi_tx_dev_t *dev, u8 bit);
|
||||
static void fc_validity_right(hdmi_tx_dev_t *dev, u8 bit, unsigned channel);
|
||||
static void fc_validity_left(hdmi_tx_dev_t *dev, u8 bit, unsigned channel);
|
||||
static void fc_user_right(hdmi_tx_dev_t *dev, u8 bit, unsigned channel);
|
||||
static void fc_user_left(hdmi_tx_dev_t *dev, u8 bit, unsigned channel);
|
||||
static void fc_iec_cgmsA(hdmi_tx_dev_t *dev, u8 value);
|
||||
static void fc_iec_copyright(hdmi_tx_dev_t *dev, u8 bit);
|
||||
static void fc_iec_category_code(hdmi_tx_dev_t *dev, u8 value);
|
||||
static void fc_iec_pcm_mode(hdmi_tx_dev_t *dev, u8 value);
|
||||
static void fc_iec_source(hdmi_tx_dev_t *dev, u8 value);
|
||||
static void fc_iec_channel_right(hdmi_tx_dev_t *dev, u8 value,
|
||||
unsigned channel);
|
||||
static void fc_iec_channel_left(hdmi_tx_dev_t *dev, u8 value,
|
||||
unsigned channel);
|
||||
static void fc_iec_clock_accuracy(hdmi_tx_dev_t *dev, u8 value);
|
||||
static void fc_iec_sampling_freq(hdmi_tx_dev_t *dev, u8 value);
|
||||
static void fc_iec_original_sampling_freq(hdmi_tx_dev_t *dev, u8 value);
|
||||
static void fc_iec_word_length(hdmi_tx_dev_t *dev, u8 value);
|
||||
|
||||
|
||||
static void fc_channel_count(hdmi_tx_dev_t *dev, u8 noOfChannels)
|
||||
{
|
||||
LOG_TRACE1(noOfChannels);
|
||||
dev_write_mask(dev, FC_AUDICONF0, FC_AUDICONF0_CC_MASK, noOfChannels);
|
||||
}
|
||||
|
||||
static void fc_sample_freq(hdmi_tx_dev_t *dev, u8 sf)
|
||||
{
|
||||
LOG_TRACE1(sf);
|
||||
dev_write_mask(dev, FC_AUDICONF1, FC_AUDICONF1_SF_MASK, sf);
|
||||
}
|
||||
|
||||
static void fc_allocate_channels(hdmi_tx_dev_t *dev, u8 ca)
|
||||
{
|
||||
LOG_TRACE1(ca);
|
||||
dev_write(dev, FC_AUDICONF2, ca);
|
||||
}
|
||||
|
||||
static void fc_level_shift_value(hdmi_tx_dev_t *dev, u8 lsv)
|
||||
{
|
||||
LOG_TRACE1(lsv);
|
||||
dev_write_mask(dev, FC_AUDICONF3, FC_AUDICONF3_LSV_MASK, lsv);
|
||||
}
|
||||
|
||||
static void fc_down_mix_inhibit(hdmi_tx_dev_t *dev, u8 prohibited)
|
||||
{
|
||||
LOG_TRACE1(prohibited);
|
||||
dev_write_mask(dev, FC_AUDICONF3, FC_AUDICONF3_DM_INH_MASK,
|
||||
(prohibited ? 1 : 0));
|
||||
}
|
||||
|
||||
static void fc_coding_type(hdmi_tx_dev_t *dev, u8 codingType)
|
||||
{
|
||||
LOG_TRACE1(codingType);
|
||||
dev_write_mask(dev, FC_AUDICONF0, FC_AUDICONF0_CT_MASK, codingType);
|
||||
}
|
||||
|
||||
static void fc_sampling_size(hdmi_tx_dev_t *dev, u8 ss)
|
||||
{
|
||||
LOG_TRACE1(ss);
|
||||
dev_write_mask(dev, FC_AUDICONF1, FC_AUDICONF1_SS_MASK, ss);
|
||||
}
|
||||
|
||||
void fc_audio_info_config(hdmi_tx_dev_t *dev, audioParams_t *audio)
|
||||
{
|
||||
u8 channel_count = audio_channel_count(dev, audio);
|
||||
|
||||
LOG_TRACE();
|
||||
|
||||
fc_channel_count(dev, channel_count);
|
||||
fc_allocate_channels(dev, audio->mChannelAllocation);
|
||||
fc_level_shift_value(dev, audio->mLevelShiftValue);
|
||||
fc_down_mix_inhibit(dev, audio->mDownMixInhibitFlag);
|
||||
|
||||
HDMI_INFO_MSG("DEBUG:Audio channel count = %d\n", channel_count);
|
||||
HDMI_INFO_MSG("DEBUG:Audio channel allocation = %d\n",
|
||||
audio->mChannelAllocation);
|
||||
HDMI_INFO_MSG("DEBUG:Audio level shift = %d\n",
|
||||
audio->mLevelShiftValue);
|
||||
|
||||
if ((audio->mCodingType == ONE_BIT_AUDIO) ||
|
||||
(audio->mCodingType == DST)) {
|
||||
u32 sampling_freq = audio->mSamplingFrequency;
|
||||
|
||||
/* Audio InfoFrame sample frequency when OBA or DST */
|
||||
if (sampling_freq == 32000)
|
||||
fc_sample_freq(dev, 1);
|
||||
else if (sampling_freq == 44100)
|
||||
fc_sample_freq(dev, 2);
|
||||
else if (sampling_freq == 48000)
|
||||
fc_sample_freq(dev, 3);
|
||||
else if (sampling_freq == 88200)
|
||||
fc_sample_freq(dev, 4);
|
||||
else if (sampling_freq == 96000)
|
||||
fc_sample_freq(dev, 5);
|
||||
else if (sampling_freq == 176400)
|
||||
fc_sample_freq(dev, 6);
|
||||
else if (sampling_freq == 192000)
|
||||
fc_sample_freq(dev, 7);
|
||||
else
|
||||
fc_sample_freq(dev, 0);
|
||||
|
||||
} else {
|
||||
fc_sample_freq(dev, 0);/*otherwise refer to stream header (0)*/
|
||||
}
|
||||
|
||||
fc_coding_type(dev, 0); /*for HDMI refer to stream header (0)*/
|
||||
fc_sampling_size(dev, 0);/* for HDMI refer to stream header (0) */
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void fc_packet_sample_flat(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write_mask(dev, FC_AUDSCONF, FC_AUDSCONF_AUD_PACKET_SAMPFLT_MASK,
|
||||
value);
|
||||
}
|
||||
|
||||
static void fc_packet_layout(hdmi_tx_dev_t *dev, u8 bit)
|
||||
{
|
||||
LOG_TRACE1(bit);
|
||||
dev_write_mask(dev, FC_AUDSCONF, FC_AUDSCONF_AUD_PACKET_LAYOUT_MASK,
|
||||
bit);
|
||||
}
|
||||
|
||||
static void fc_validity_right(hdmi_tx_dev_t *dev, u8 bit, unsigned channel)
|
||||
{
|
||||
LOG_TRACE2(bit, channel);
|
||||
if (channel < 4)
|
||||
dev_write_mask(dev, FC_AUDSV, (1 << (4 + channel)), bit);
|
||||
else
|
||||
printf("ERROR:invalid channel number\n");
|
||||
}
|
||||
|
||||
static void fc_validity_left(hdmi_tx_dev_t *dev, u8 bit, unsigned channel)
|
||||
{
|
||||
LOG_TRACE2(bit, channel);
|
||||
if (channel < 4)
|
||||
dev_write_mask(dev, FC_AUDSV, (1 << channel), bit);
|
||||
else
|
||||
printf("ERROR:invalid channel number: %d", channel);
|
||||
}
|
||||
|
||||
static void fc_user_right(hdmi_tx_dev_t *dev, u8 bit, unsigned channel)
|
||||
{
|
||||
LOG_TRACE2(bit, channel);
|
||||
if (channel < 4)
|
||||
dev_write_mask(dev, FC_AUDSU, (1 << (4 + channel)), bit);
|
||||
else
|
||||
printf("ERROR:invalid channel number: %d\n", channel);
|
||||
}
|
||||
|
||||
static void fc_user_left(hdmi_tx_dev_t *dev, u8 bit, unsigned channel)
|
||||
{
|
||||
LOG_TRACE2(bit, channel);
|
||||
if (channel < 4)
|
||||
dev_write_mask(dev, FC_AUDSU, (1 << channel), bit);
|
||||
else
|
||||
printf("ERRORinvalid channel number: %d\n", channel);
|
||||
}
|
||||
|
||||
static void fc_iec_cgmsA(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write_mask(dev, FC_AUDSCHNL0, FC_AUDSCHNL0_OIEC_CGMSA_MASK, value);
|
||||
}
|
||||
|
||||
static void fc_iec_copyright(hdmi_tx_dev_t *dev, u8 bit)
|
||||
{
|
||||
LOG_TRACE1(bit);
|
||||
dev_write_mask(dev, FC_AUDSCHNL0,
|
||||
FC_AUDSCHNL0_OIEC_COPYRIGHT_MASK, bit);
|
||||
}
|
||||
|
||||
static void fc_iec_category_code(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write(dev, FC_AUDSCHNL1, value);
|
||||
}
|
||||
|
||||
static void fc_iec_pcm_mode(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write_mask(dev, FC_AUDSCHNL2,
|
||||
FC_AUDSCHNL2_OIEC_PCMAUDIOMODE_MASK, value);
|
||||
}
|
||||
|
||||
static void fc_iec_source(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write_mask(dev, FC_AUDSCHNL2,
|
||||
FC_AUDSCHNL2_OIEC_SOURCENUMBER_MASK, value);
|
||||
}
|
||||
|
||||
static void fc_iec_channel_right(hdmi_tx_dev_t *dev, u8 value, unsigned channel)
|
||||
{
|
||||
LOG_TRACE2(value, channel);
|
||||
if (channel == 0)
|
||||
dev_write_mask(dev, FC_AUDSCHNL3,
|
||||
FC_AUDSCHNL3_OIEC_CHANNELNUMCR0_MASK, value);
|
||||
else if (channel == 1)
|
||||
dev_write_mask(dev, FC_AUDSCHNL3,
|
||||
FC_AUDSCHNL3_OIEC_CHANNELNUMCR1_MASK, value);
|
||||
else if (channel == 2)
|
||||
dev_write_mask(dev, FC_AUDSCHNL4,
|
||||
FC_AUDSCHNL4_OIEC_CHANNELNUMCR2_MASK, value);
|
||||
else if (channel == 3)
|
||||
dev_write_mask(dev, FC_AUDSCHNL4,
|
||||
FC_AUDSCHNL4_OIEC_CHANNELNUMCR3_MASK, value);
|
||||
else
|
||||
HDMI_INFO_MSG("ERROR:invalid channel number: %d\n", channel);
|
||||
}
|
||||
|
||||
static void fc_iec_channel_left(hdmi_tx_dev_t *dev, u8 value, unsigned channel)
|
||||
{
|
||||
LOG_TRACE2(value, channel);
|
||||
if (channel == 0)
|
||||
dev_write_mask(dev, FC_AUDSCHNL5,
|
||||
FC_AUDSCHNL5_OIEC_CHANNELNUMCL0_MASK, value);
|
||||
else if (channel == 1)
|
||||
dev_write_mask(dev, FC_AUDSCHNL5,
|
||||
FC_AUDSCHNL5_OIEC_CHANNELNUMCL1_MASK, value);
|
||||
else if (channel == 2)
|
||||
dev_write_mask(dev, FC_AUDSCHNL6,
|
||||
FC_AUDSCHNL6_OIEC_CHANNELNUMCL2_MASK, value);
|
||||
else if (channel == 3)
|
||||
dev_write_mask(dev, FC_AUDSCHNL6,
|
||||
FC_AUDSCHNL6_OIEC_CHANNELNUMCL3_MASK, value);
|
||||
else
|
||||
HDMI_INFO_MSG("ERROR:invalid channel number: %d", channel);
|
||||
}
|
||||
|
||||
static void fc_iec_clock_accuracy(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write_mask(dev, FC_AUDSCHNL7,
|
||||
FC_AUDSCHNL7_OIEC_CLKACCURACY_MASK, value);
|
||||
}
|
||||
|
||||
static void fc_iec_sampling_freq(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write_mask(dev, FC_AUDSCHNL7,
|
||||
FC_AUDSCHNL7_OIEC_SAMPFREQ_MASK, value);
|
||||
}
|
||||
|
||||
static void fc_iec_original_sampling_freq(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write_mask(dev, FC_AUDSCHNL8,
|
||||
FC_AUDSCHNL8_OIEC_ORIGSAMPFREQ_MASK, value);
|
||||
}
|
||||
|
||||
static void fc_iec_word_length(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write_mask(dev, FC_AUDSCHNL8,
|
||||
FC_AUDSCHNL8_OIEC_WORDLENGTH_MASK, value);
|
||||
}
|
||||
|
||||
void fc_audio_config(hdmi_tx_dev_t *dev, audioParams_t *audio)
|
||||
{
|
||||
int i = 0;
|
||||
u8 channel_count = audio_channel_count(dev, audio);
|
||||
/*u8 channel_count = audio->mChannelNum;*/
|
||||
u8 data = 0;
|
||||
|
||||
/* More than 2 channels => layout 1 else layout 0 */
|
||||
if ((channel_count + 1) > 2)
|
||||
fc_packet_layout(dev, 1);
|
||||
else
|
||||
fc_packet_layout(dev, 0);
|
||||
|
||||
/* iec validity and user bits (IEC 60958-1) */
|
||||
for (i = 0; i < 4; i++) {
|
||||
/* audio_is_channel_en considers left as 1 channel and
|
||||
* right as another (+1), hence the x2 factor in the following */
|
||||
/* validity bit is 0 when reliable, which is !IsChannelEn */
|
||||
u8 channel_enable = audio_is_channel_en(dev, audio, (2 * i));
|
||||
HDMI_INFO_MSG("channel %d right is %d\n", i, channel_enable);
|
||||
fc_validity_right(dev, !channel_enable, i);
|
||||
|
||||
channel_enable = audio_is_channel_en(dev, audio, (2 * i) + 1);
|
||||
HDMI_INFO_MSG("channel %d left is %d\n", i, channel_enable);
|
||||
fc_validity_left(dev, !channel_enable, i);
|
||||
|
||||
fc_user_right(dev, 1, i);
|
||||
fc_user_left(dev, 1, i);
|
||||
}
|
||||
|
||||
if (audio->mCodingType != PCM)
|
||||
return;
|
||||
/* IEC - not needed if non-linear PCM*/
|
||||
fc_iec_cgmsA(dev, audio->mIecCgmsA);
|
||||
fc_iec_copyright(dev, audio->mIecCopyright ? 0 : 1);
|
||||
fc_iec_category_code(dev, audio->mIecCategoryCode);
|
||||
fc_iec_pcm_mode(dev, audio->mIecPcmMode);
|
||||
fc_iec_source(dev, audio->mIecSourceNumber);
|
||||
|
||||
for (i = 0; i < 4; i++) { /* 0, 1, 2, 3 */
|
||||
fc_iec_channel_left(dev, 2 * i + 1, i); /* 1, 3, 5, 7 */
|
||||
fc_iec_channel_right(dev, 2 * (i + 1), i); /* 2, 4, 6, 8 */
|
||||
}
|
||||
|
||||
fc_iec_clock_accuracy(dev, audio->mIecClockAccuracy);
|
||||
|
||||
data = audio_iec_sampling_freq(dev, audio);
|
||||
fc_iec_sampling_freq(dev, data);
|
||||
|
||||
data = audio_iec_original_sampling_freq(dev, audio);
|
||||
fc_iec_original_sampling_freq(dev, data);
|
||||
|
||||
data = audio_iec_word_length(dev, audio);
|
||||
fc_iec_word_length(dev, data);
|
||||
}
|
||||
|
||||
void fc_audio_mute(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
fc_packet_sample_flat(dev, 0xF);
|
||||
}
|
||||
|
||||
void fc_audio_unmute(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
fc_packet_sample_flat(dev, 0);
|
||||
}
|
||||
26
sunxi_spl/display/hdmi/fc_audio.h
Executable file
26
sunxi_spl/display/hdmi/fc_audio.h
Executable file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Allwinner SoCs hdmi2.0 driver.
|
||||
*
|
||||
* Copyright (C) 2016 Allwinner.
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef HALFRAMECOMPOSERAUDIO_H_
|
||||
#define HALFRAMECOMPOSERAUDIO_H_
|
||||
|
||||
#include "frame_composer_reg.h"
|
||||
#include "hdmitx_dev.h"
|
||||
#include "audio.h"
|
||||
#include "access.h"
|
||||
|
||||
void fc_audio_config(hdmi_tx_dev_t *dev, audioParams_t *audio);
|
||||
void fc_audio_mute(hdmi_tx_dev_t *dev);
|
||||
void fc_audio_unmute(hdmi_tx_dev_t *dev);
|
||||
|
||||
|
||||
|
||||
#endif /* HALFRAMECOMPOSERAUDIO_H_ */
|
||||
300
sunxi_spl/display/hdmi/fc_video.c
Executable file
300
sunxi_spl/display/hdmi/fc_video.c
Executable file
@@ -0,0 +1,300 @@
|
||||
/*
|
||||
* Allwinner SoCs hdmi2.0 driver.
|
||||
*
|
||||
* Copyright (C) 2016 Allwinner.
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#include "fc_video.h"
|
||||
|
||||
void fc_video_hdcp_keepout(hdmi_tx_dev_t *dev, u8 bit)
|
||||
{
|
||||
LOG_TRACE1(bit);
|
||||
dev_write_mask(dev, FC_INVIDCONF, FC_INVIDCONF_HDCP_KEEPOUT_MASK, bit);
|
||||
}
|
||||
|
||||
static void fc_video_VSyncPolarity(hdmi_tx_dev_t *dev, u8 bit)
|
||||
{
|
||||
LOG_TRACE1(bit);
|
||||
dev_write_mask(dev, FC_INVIDCONF,
|
||||
FC_INVIDCONF_VSYNC_IN_POLARITY_MASK, bit);
|
||||
}
|
||||
|
||||
static void fc_video_HSyncPolarity(hdmi_tx_dev_t *dev, u8 bit)
|
||||
{
|
||||
LOG_TRACE1(bit);
|
||||
dev_write_mask(dev, FC_INVIDCONF,
|
||||
FC_INVIDCONF_HSYNC_IN_POLARITY_MASK, bit);
|
||||
}
|
||||
|
||||
static void fc_video_DataEnablePolarity(hdmi_tx_dev_t *dev, u8 bit)
|
||||
{
|
||||
LOG_TRACE1(bit);
|
||||
dev_write_mask(dev, FC_INVIDCONF,
|
||||
FC_INVIDCONF_DE_IN_POLARITY_MASK, bit);
|
||||
}
|
||||
|
||||
void fc_video_DviOrHdmi(hdmi_tx_dev_t *dev, u8 bit)
|
||||
{
|
||||
LOG_TRACE1(bit);
|
||||
/* 1: HDMI; 0: DVI */
|
||||
dev_write_mask(dev, FC_INVIDCONF, FC_INVIDCONF_DVI_MODEZ_MASK, bit);
|
||||
}
|
||||
|
||||
static void fc_video_VBlankOsc(hdmi_tx_dev_t *dev, u8 bit)
|
||||
{
|
||||
LOG_TRACE1(bit);
|
||||
dev_write_mask(dev, FC_INVIDCONF,
|
||||
FC_INVIDCONF_R_V_BLANK_IN_OSC_MASK, bit);
|
||||
}
|
||||
|
||||
/*for some video modes that have fractional Vblank*/
|
||||
static void fc_video_Interlaced(hdmi_tx_dev_t *dev, u8 bit)
|
||||
{
|
||||
LOG_TRACE1(bit);
|
||||
dev_write_mask(dev, FC_INVIDCONF, FC_INVIDCONF_IN_I_P_MASK, bit);
|
||||
}
|
||||
|
||||
static void fc_video_HActive(hdmi_tx_dev_t *dev, u16 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
/* 12-bit width */
|
||||
dev_write(dev, (FC_INHACTIV0), (u8) (value));
|
||||
dev_write_mask(dev, FC_INHACTIV1, FC_INHACTIV1_H_IN_ACTIV_MASK |
|
||||
FC_INHACTIV1_H_IN_ACTIV_12_MASK, (u8)(value >> 8));
|
||||
}
|
||||
|
||||
static void fc_video_HBlank(hdmi_tx_dev_t *dev, u16 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
/* 10-bit width */
|
||||
dev_write(dev, (FC_INHBLANK0), (u8) (value));
|
||||
dev_write_mask(dev, FC_INHBLANK1, FC_INHBLANK1_H_IN_BLANK_MASK |
|
||||
FC_INHBLANK1_H_IN_BLANK_12_MASK, (u8)(value >> 8));
|
||||
}
|
||||
|
||||
static void fc_video_VActive(hdmi_tx_dev_t *dev, u16 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
/*Vactive value holds 11-bit width in two register */
|
||||
dev_write(dev, (FC_INVACTIV0), (u8) (value));
|
||||
dev_write_mask(dev, FC_INVACTIV1, FC_INVACTIV1_V_IN_ACTIV_MASK |
|
||||
FC_INVACTIV1_V_IN_ACTIV_12_11_MASK, (u8)(value >> 8));
|
||||
}
|
||||
|
||||
static void fc_video_VBlank(hdmi_tx_dev_t *dev, u16 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
/* 8-bit width */
|
||||
dev_write(dev, (FC_INVBLANK), (u8) (value));
|
||||
}
|
||||
|
||||
/*Setting Frame Composer Input Video HSync Front Porch*/
|
||||
static void fc_video_HSyncEdgeDelay(hdmi_tx_dev_t *dev, u16 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
/* 11-bit width */
|
||||
dev_write(dev, (FC_HSYNCINDELAY0), (u8) (value));
|
||||
dev_write_mask(dev, FC_HSYNCINDELAY1, FC_HSYNCINDELAY1_H_IN_DELAY_MASK |
|
||||
FC_HSYNCINDELAY1_H_IN_DELAY_12_MASK, (u8)(value >> 8));
|
||||
}
|
||||
|
||||
static void fc_video_HSyncPulseWidth(hdmi_tx_dev_t *dev, u16 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
/* 9-bit width */
|
||||
dev_write(dev, (FC_HSYNCINWIDTH0), (u8) (value));
|
||||
dev_write_mask(dev, FC_HSYNCINWIDTH1, FC_HSYNCINWIDTH1_H_IN_WIDTH_MASK,
|
||||
(u8)(value >> 8));
|
||||
}
|
||||
|
||||
static void fc_video_VSyncEdgeDelay(hdmi_tx_dev_t *dev, u16 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
/* 8-bit width */
|
||||
dev_write(dev, (FC_VSYNCINDELAY), (u8) (value));
|
||||
}
|
||||
|
||||
static void fc_video_VSyncPulseWidth(hdmi_tx_dev_t *dev, u16 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write_mask(dev, FC_VSYNCINWIDTH, FC_VSYNCINWIDTH_V_IN_WIDTH_MASK,
|
||||
(u8)(value));
|
||||
}
|
||||
|
||||
/*static void fc_video_RefreshRate(hdmi_tx_dev_t *dev, u32 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
20-bit width
|
||||
dev_write(dev, (FC_INFREQ0), (u8) (value >> 0));
|
||||
dev_write(dev, (FC_INFREQ1), (u8) (value >> 8));
|
||||
dev_write_mask(dev, FC_INFREQ2, FC_INFREQ2_INFREQ_MASK,
|
||||
(u8)(value >> 16));
|
||||
}*/
|
||||
|
||||
static void fc_video_ControlPeriodMinDuration(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write(dev, (FC_CTRLDUR), value);
|
||||
}
|
||||
|
||||
static void fc_video_ExtendedControlPeriodMinDuration(hdmi_tx_dev_t *dev,
|
||||
u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write(dev, (FC_EXCTRLDUR), value);
|
||||
}
|
||||
|
||||
static void fc_video_ExtendedControlPeriodMaxSpacing(hdmi_tx_dev_t *dev,
|
||||
u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write(dev, (FC_EXCTRLSPAC), value);
|
||||
}
|
||||
|
||||
static void fc_video_PreambleFilter(hdmi_tx_dev_t *dev, u8 value,
|
||||
unsigned channel)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
if (channel == 0)
|
||||
dev_write(dev, (FC_CH0PREAM), value);
|
||||
else if (channel == 1)
|
||||
dev_write_mask(dev, FC_CH1PREAM,
|
||||
FC_CH1PREAM_CH1_PREAMBLE_FILTER_MASK, value);
|
||||
else if (channel == 2)
|
||||
dev_write_mask(dev, FC_CH2PREAM,
|
||||
FC_CH2PREAM_CH2_PREAMBLE_FILTER_MASK, value);
|
||||
else
|
||||
HDMI_INFO_MSG("invalid channel number: %d\n", channel);
|
||||
}
|
||||
|
||||
static void fc_video_PixelRepetitionInput(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write_mask(dev, FC_PRCONF,
|
||||
FC_PRCONF_INCOMING_PR_FACTOR_MASK, value);
|
||||
}
|
||||
|
||||
void fc_force_audio(hdmi_tx_dev_t *dev, u8 bit)
|
||||
{
|
||||
LOG_TRACE1(bit);
|
||||
dev_write_mask(dev, FC_DBGFORCE, FC_DBGFORCE_FORCEAUDIO_MASK, bit);
|
||||
}
|
||||
|
||||
void fc_force_video(hdmi_tx_dev_t *dev, u8 bit)
|
||||
{
|
||||
LOG_TRACE1(bit);
|
||||
|
||||
/* avoid glitches */
|
||||
if (bit != 0) {
|
||||
dev_write(dev, FC_DBGTMDS2, bit ? 0x00 : 0x00); /* R */
|
||||
dev_write(dev, FC_DBGTMDS1, bit ? 0x00 : 0x00); /* G */
|
||||
dev_write(dev, FC_DBGTMDS0, bit ? 0xFF : 0x00); /* B */
|
||||
dev_write_mask(dev, FC_DBGFORCE,
|
||||
FC_DBGFORCE_FORCEVIDEO_MASK, 1);
|
||||
} else {
|
||||
dev_write_mask(dev, FC_DBGFORCE,
|
||||
FC_DBGFORCE_FORCEVIDEO_MASK, 0);
|
||||
dev_write(dev, FC_DBGTMDS2, bit ? 0x00 : 0x00); /* R */
|
||||
dev_write(dev, FC_DBGTMDS1, bit ? 0x00 : 0x00); /* G */
|
||||
dev_write(dev, FC_DBGTMDS0, bit ? 0xFF : 0x00); /* B */
|
||||
}
|
||||
}
|
||||
|
||||
void fc_force_output(hdmi_tx_dev_t *dev, int enable)
|
||||
{
|
||||
LOG_TRACE1(enable);
|
||||
fc_force_audio(dev, 0);
|
||||
fc_force_video(dev, (u8)enable);
|
||||
}
|
||||
|
||||
|
||||
int fc_video_config(hdmi_tx_dev_t *dev, videoParams_t *video)
|
||||
{
|
||||
const dtd_t *dtd = &video->mDtd;
|
||||
u16 i = 0;
|
||||
|
||||
LOG_TRACE();
|
||||
|
||||
if ((dev == NULL) || (video == NULL)) {
|
||||
HDMI_ERROR_MSG("Invalid arguments: dev=%lx; video=%lx\n",
|
||||
(uintptr_t)dev, (uintptr_t)video);
|
||||
return false;
|
||||
}
|
||||
|
||||
dtd = &video->mDtd;
|
||||
|
||||
fc_video_VSyncPolarity(dev, dtd->mVSyncPolarity);
|
||||
fc_video_HSyncPolarity(dev, dtd->mHSyncPolarity);
|
||||
fc_video_DataEnablePolarity(dev,
|
||||
dev->snps_hdmi_ctrl.data_enable_polarity);
|
||||
fc_video_DviOrHdmi(dev, video->mHdmi);
|
||||
|
||||
if (video->mHdmiVideoFormat == 2) {
|
||||
if (video->m3dStructure == 0) {
|
||||
/* 3d data frame packing
|
||||
is transmitted as a progressive format */
|
||||
fc_video_VBlankOsc(dev, 0);
|
||||
fc_video_Interlaced(dev, 0);
|
||||
|
||||
if (dtd->mInterlaced) {
|
||||
fc_video_VActive(dev,
|
||||
(dtd->mVActive << 2) + 3 * dtd->mVBlanking + 2);
|
||||
} else {
|
||||
fc_video_VActive(dev,
|
||||
(dtd->mVActive << 1) + dtd->mVBlanking);
|
||||
}
|
||||
} else {
|
||||
fc_video_VBlankOsc(dev, dtd->mInterlaced);
|
||||
fc_video_Interlaced(dev, dtd->mInterlaced);
|
||||
fc_video_VActive(dev, dtd->mVActive);
|
||||
}
|
||||
} else {
|
||||
fc_video_VBlankOsc(dev, dtd->mInterlaced);
|
||||
fc_video_Interlaced(dev, dtd->mInterlaced);
|
||||
fc_video_VActive(dev, dtd->mVActive);
|
||||
}
|
||||
|
||||
if (video->mEncodingOut == YCC420) {
|
||||
HDMI_INFO_MSG("Encoding configured to YCC 420\n");
|
||||
fc_video_HActive(dev, dtd->mHActive/2);
|
||||
fc_video_HBlank(dev, dtd->mHBlanking/2);
|
||||
fc_video_HSyncPulseWidth(dev, dtd->mHSyncPulseWidth/2);
|
||||
fc_video_HSyncEdgeDelay(dev, dtd->mHSyncOffset/2);
|
||||
} else {
|
||||
fc_video_HActive(dev, dtd->mHActive);
|
||||
fc_video_HBlank(dev, dtd->mHBlanking);
|
||||
fc_video_HSyncPulseWidth(dev, dtd->mHSyncPulseWidth);
|
||||
fc_video_HSyncEdgeDelay(dev, dtd->mHSyncOffset);
|
||||
}
|
||||
|
||||
fc_video_VBlank(dev, dtd->mVBlanking);
|
||||
fc_video_VSyncEdgeDelay(dev, dtd->mVSyncOffset);
|
||||
fc_video_VSyncPulseWidth(dev, dtd->mVSyncPulseWidth);
|
||||
fc_video_ControlPeriodMinDuration(dev, 12);
|
||||
fc_video_ExtendedControlPeriodMinDuration(dev, 32);
|
||||
|
||||
/* spacing < 256^2 * config / tmdsClock, spacing <= 50ms
|
||||
* worst case: tmdsClock == 25MHz => config <= 19
|
||||
*/
|
||||
fc_video_ExtendedControlPeriodMaxSpacing(dev, 1);
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
fc_video_PreambleFilter(dev, (i + 1) * 11, i);
|
||||
|
||||
fc_video_PixelRepetitionInput(dev, dtd->mPixelRepetitionInput + 1);
|
||||
|
||||
/* due to HDCP and Scrambler */
|
||||
if (dev->snps_hdmi_ctrl.hdcp_on ||
|
||||
(dev->snps_hdmi_ctrl.tmds_clk > 340000))
|
||||
/*Start koopout window generation*/
|
||||
fc_video_hdcp_keepout(dev, true);
|
||||
else
|
||||
fc_video_hdcp_keepout(dev, false);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
29
sunxi_spl/display/hdmi/fc_video.h
Executable file
29
sunxi_spl/display/hdmi/fc_video.h
Executable file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Allwinner SoCs hdmi2.0 driver.
|
||||
*
|
||||
* Copyright (C) 2016 Allwinner.
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#ifndef HALFRAMECOMPOSERVIDEO_H_
|
||||
#define HALFRAMECOMPOSERVIDEO_H_
|
||||
|
||||
#include "video.h"
|
||||
#include "frame_composer_reg.h"
|
||||
#include "hdmitx_dev.h"
|
||||
|
||||
#include "access.h"
|
||||
|
||||
|
||||
void fc_force_output(hdmi_tx_dev_t *dev, int enable);
|
||||
|
||||
int fc_video_config(hdmi_tx_dev_t *dev, videoParams_t *video);
|
||||
|
||||
void fc_video_hdcp_keepout(hdmi_tx_dev_t *dev, u8 bit);
|
||||
u8 fc_video_tmdsMode_get(hdmi_tx_dev_t *dev);
|
||||
void fc_video_DviOrHdmi(hdmi_tx_dev_t *dev, u8 bit);
|
||||
|
||||
#endif /* HALFRAMECOMPOSERVIDEO_H_ */
|
||||
845
sunxi_spl/display/hdmi/frame_composer_reg.h
Executable file
845
sunxi_spl/display/hdmi/frame_composer_reg.h
Executable file
@@ -0,0 +1,845 @@
|
||||
/*
|
||||
* Allwinner SoCs hdmi2.0 driver.
|
||||
*
|
||||
* Copyright (C) 2016 Allwinner.
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SRC_CORE_FRAME_COMPOSER_FRAME_COMPOSER_REG_H_
|
||||
#define SRC_CORE_FRAME_COMPOSER_FRAME_COMPOSER_REG_H_
|
||||
|
||||
/*****************************************************************************
|
||||
* *
|
||||
* Frame Composer Registers *
|
||||
* *
|
||||
*****************************************************************************/
|
||||
|
||||
/* Frame Composer Input Video Configuration and HDCP Keepout Register */
|
||||
#define FC_INVIDCONF 0x00004000
|
||||
#define FC_INVIDCONF_IN_I_P_MASK 0x00000001 /* Input video mode: 1b: Interlaced 0b: Progressive */
|
||||
#define FC_INVIDCONF_R_V_BLANK_IN_OSC_MASK 0x00000002 /* Used for CEA861-D modes with fractional Vblank (for example, modes 5, 6, 7, 10, 11, 20, 21, and 22) */
|
||||
#define FC_INVIDCONF_DVI_MODEZ_MASK 0x00000008 /* Active low 0b: DVI mode selected 1b: HDMI mode selected */
|
||||
#define FC_INVIDCONF_DE_IN_POLARITY_MASK 0x00000010 /* Data enable input polarity 1b: Active high 0b: Active low */
|
||||
#define FC_INVIDCONF_HSYNC_IN_POLARITY_MASK 0x00000020 /* Hsync input polarity 1b: Active high 0b: Active low */
|
||||
#define FC_INVIDCONF_VSYNC_IN_POLARITY_MASK 0x00000040 /* Vsync input polarity 1b: Active high 0b: Active low */
|
||||
#define FC_INVIDCONF_HDCP_KEEPOUT_MASK 0x00000080 /* Start/stop HDCP keepout window generation 1b: Active */
|
||||
|
||||
/* Frame Composer Input Video HActive Pixels Register 0 */
|
||||
#define FC_INHACTIV0 0x00004004
|
||||
#define FC_INHACTIV0_H_IN_ACTIV_MASK 0x000000FF /* Input video Horizontal active pixel region width */
|
||||
|
||||
/* Frame Composer Input Video HActive Pixels Register 1 */
|
||||
#define FC_INHACTIV1 0x00004008
|
||||
#define FC_INHACTIV1_H_IN_ACTIV_MASK 0x0000000F /* Input video Horizontal active pixel region width */
|
||||
#define FC_INHACTIV1_H_IN_ACTIV_12_MASK 0x00000010 /* Input video Horizontal active pixel region width (0 */
|
||||
#define FC_INHACTIV1_H_IN_ACTIV_13_MASK 0x00000020 /* Input video Horizontal active pixel region width (0 */
|
||||
|
||||
/* Frame Composer Input Video HBlank Pixels Register 0 */
|
||||
#define FC_INHBLANK0 0x0000400C
|
||||
#define FC_INHBLANK0_H_IN_BLANK_MASK 0x000000FF /* Input video Horizontal blanking pixel region width */
|
||||
|
||||
/* Frame Composer Input Video HBlank Pixels Register 1 */
|
||||
#define FC_INHBLANK1 0x00004010
|
||||
#define FC_INHBLANK1_H_IN_BLANK_MASK 0x00000003 /* Input video Horizontal blanking pixel region width this bit field holds bits 9:8 of number of Horizontal blanking pixels */
|
||||
#define FC_INHBLANK1_H_IN_BLANK_12_MASK 0x0000001C /* Input video Horizontal blanking pixel region width If configuration parameter DWC_HDMI_TX_14 = True (1), this bit field holds bit 12:10 of number of horizontal blanking pixels */
|
||||
|
||||
/* Frame Composer Input Video VActive Pixels Register 0 */
|
||||
#define FC_INVACTIV0 0x00004014
|
||||
#define FC_INVACTIV0_V_IN_ACTIV_MASK 0x000000FF /* Input video Vertical active pixel region width */
|
||||
|
||||
/* Frame Composer Input Video VActive Pixels Register 1 */
|
||||
#define FC_INVACTIV1 0x00004018
|
||||
#define FC_INVACTIV1_V_IN_ACTIV_MASK 0x00000007 /* Input video Vertical active pixel region width */
|
||||
#define FC_INVACTIV1_V_IN_ACTIV_12_11_MASK 0x00000018 /* Input video Vertical active pixel region width */
|
||||
|
||||
/* Frame Composer Input Video VBlank Pixels Register */
|
||||
#define FC_INVBLANK 0x0000401C
|
||||
#define FC_INVBLANK_V_IN_BLANK_MASK 0x000000FF /* Input video Vertical blanking pixel region width */
|
||||
|
||||
/* Frame Composer Input Video HSync Front Porch Register 0 */
|
||||
#define FC_HSYNCINDELAY0 0x00004020
|
||||
#define FC_HSYNCINDELAY0_H_IN_DELAY_MASK 0x000000FF /* Input video Hsync active edge delay */
|
||||
|
||||
/* Frame Composer Input Video HSync Front Porch Register 1 */
|
||||
#define FC_HSYNCINDELAY1 0x00004024
|
||||
#define FC_HSYNCINDELAY1_H_IN_DELAY_MASK 0x00000007 /* Input video Horizontal active edge delay */
|
||||
#define FC_HSYNCINDELAY1_H_IN_DELAY_12_MASK 0x00000018 /* Input video Horizontal active edge delay */
|
||||
|
||||
/* Frame Composer Input Video HSync Width Register 0 */
|
||||
#define FC_HSYNCINWIDTH0 0x00004028
|
||||
#define FC_HSYNCINWIDTH0_H_IN_WIDTH_MASK 0x000000FF /* Input video Hsync active pulse width */
|
||||
|
||||
/* Frame Composer Input Video HSync Width Register 1 */
|
||||
#define FC_HSYNCINWIDTH1 0x0000402C
|
||||
#define FC_HSYNCINWIDTH1_H_IN_WIDTH_MASK 0x00000001 /* Input video Hsync active pulse width */
|
||||
#define FC_HSYNCINWIDTH1_H_IN_WIDTH_9_MASK 0x00000002 /* Input video Hsync active pulse width */
|
||||
|
||||
/* Frame Composer Input Video VSync Front Porch Register */
|
||||
#define FC_VSYNCINDELAY 0x00004030
|
||||
#define FC_VSYNCINDELAY_V_IN_DELAY_MASK 0x000000FF /* Input video Vsync active edge delay */
|
||||
|
||||
/* Frame Composer Input Video VSync Width Register */
|
||||
#define FC_VSYNCINWIDTH 0x00004034
|
||||
#define FC_VSYNCINWIDTH_V_IN_WIDTH_MASK 0x0000003F /* Input video Vsync active pulse width */
|
||||
|
||||
/* Frame Composer Input Video Refresh Rate Register 0 */
|
||||
#define FC_INFREQ0 0x00004038
|
||||
#define FC_INFREQ0_INFREQ_MASK 0x000000FF /* Video refresh rate in Hz*1E3 format */
|
||||
|
||||
/* Frame Composer Input Video Refresh Rate Register 1 */
|
||||
#define FC_INFREQ1 0x0000403C
|
||||
#define FC_INFREQ1_INFREQ_MASK 0x000000FF /* Video refresh rate in Hz*1E3 format */
|
||||
|
||||
/* Frame Composer Input Video Refresh Rate Register 2 */
|
||||
#define FC_INFREQ2 0x00004040
|
||||
#define FC_INFREQ2_INFREQ_MASK 0x0000000F /* Video refresh rate in Hz*1E3 format */
|
||||
|
||||
/* Frame Composer Control Period Duration Register */
|
||||
#define FC_CTRLDUR 0x00004044
|
||||
#define FC_CTRLDUR_CTRLPERIODDURATION_MASK 0x000000FF /* Configuration of the control period minimum duration (minimum of 12 pixel clock cycles; refer to HDMI 1 */
|
||||
|
||||
/* Frame Composer Extended Control Period Duration Register */
|
||||
#define FC_EXCTRLDUR 0x00004048
|
||||
#define FC_EXCTRLDUR_EXCTRLPERIODDURATION_MASK 0x000000FF /* Configuration of the extended control period minimum duration (minimum of 32 pixel clock cycles; refer to HDMI 1 */
|
||||
|
||||
/* Frame Composer Extended Control Period Maximum Spacing Register */
|
||||
#define FC_EXCTRLSPAC 0x0000404C
|
||||
#define FC_EXCTRLSPAC_EXCTRLPERIODSPACING_MASK 0x000000FF /* Configuration of the maximum spacing between consecutive extended control periods (maximum of 50ms; refer to the applicable HDMI specification) */
|
||||
|
||||
/* Frame Composer Channel 0 Non-Preamble Data Register */
|
||||
#define FC_CH0PREAM 0x00004050
|
||||
#define FC_CH0PREAM_CH0_PREAMBLE_FILTER_MASK 0x000000FF /* When in control mode, configures 8 bits that fill the channel 0 data lines not used to transmit the preamble (for more clarification, refer to the HDMI 1 */
|
||||
|
||||
/* Frame Composer Channel 1 Non-Preamble Data Register */
|
||||
#define FC_CH1PREAM 0x00004054
|
||||
#define FC_CH1PREAM_CH1_PREAMBLE_FILTER_MASK 0x0000003F /* When in control mode, configures 6 bits that fill the channel 1 data lines not used to transmit the preamble (for more clarification, refer to the HDMI 1 */
|
||||
|
||||
/* Frame Composer Channel 2 Non-Preamble Data Register */
|
||||
#define FC_CH2PREAM 0x00004058
|
||||
#define FC_CH2PREAM_CH2_PREAMBLE_FILTER_MASK 0x0000003F /* When in control mode, configures 6 bits that fill the channel 2 data lines not used to transmit the preamble (for more clarification, refer to the HDMI 1 */
|
||||
|
||||
/* Frame Composer AVI Packet Configuration Register 3 */
|
||||
#define FC_AVICONF3 0x0000405C
|
||||
#define FC_AVICONF3_CN_MASK 0x00000003 /* IT content type according to CEA the specification */
|
||||
#define FC_AVICONF3_YQ_MASK 0x0000000C /* YCC Quantization range according to the CEA specification */
|
||||
|
||||
/* Frame Composer GCP Packet Configuration Register */
|
||||
#define FC_GCP 0x00004060
|
||||
#define FC_GCP_CLEAR_AVMUTE_MASK 0x00000001 /* Value of "clear_avmute" in the GCP packet */
|
||||
#define FC_GCP_SET_AVMUTE_MASK 0x00000002 /* Value of "set_avmute" in the GCP packet Once the AVmute is set, the frame composer schedules the GCP packet with AVmute set in the packet scheduler to be sent once (may only be transmitted between the active edge of VSYNC and 384 pixels following this edge) */
|
||||
#define FC_GCP_DEFAULT_PHASE_MASK 0x00000004 /* Value of "default_phase" in the GCP packet */
|
||||
|
||||
/* Frame Composer AVI Packet Configuration Register 0 */
|
||||
#define FC_AVICONF0 0x00004064
|
||||
#define FC_AVICONF0_RGC_YCC_INDICATION_MASK 0x00000003 /* Y1,Y0 RGB or YCC indicator */
|
||||
#define FC_AVICONF0_BAR_INFORMATION_MASK 0x0000000C /* Bar information data valid */
|
||||
#define FC_AVICONF0_SCAN_INFORMATION_MASK 0x00000030 /* Scan information */
|
||||
#define FC_AVICONF0_ACTIVE_FORMAT_PRESENT_MASK 0x00000040 /* Active format present */
|
||||
#define FC_AVICONF0_RGC_YCC_INDICATION_2_MASK 0x00000080 /* Y2, Bit 2 of rgc_ycc_indication */
|
||||
|
||||
/* Frame Composer AVI Packet Configuration Register 1 */
|
||||
#define FC_AVICONF1 0x00004068
|
||||
#define FC_AVICONF1_ACTIVE_ASPECT_RATIO_MASK 0x0000000F /* Active aspect ratio */
|
||||
#define FC_AVICONF1_PICTURE_ASPECT_RATIO_MASK 0x00000030 /* Picture aspect ratio */
|
||||
#define FC_AVICONF1_COLORIMETRY_MASK 0x000000C0 /* Colorimetry */
|
||||
|
||||
/* Frame Composer AVI Packet Configuration Register 2 */
|
||||
#define FC_AVICONF2 0x0000406C
|
||||
#define FC_AVICONF2_NON_UNIFORM_PICTURE_SCALING_MASK 0x00000003 /* Non-uniform picture scaling */
|
||||
#define FC_AVICONF2_QUANTIZATION_RANGE_MASK 0x0000000C /* Quantization range */
|
||||
#define FC_AVICONF2_EXTENDED_COLORIMETRY_MASK 0x00000070 /* Extended colorimetry */
|
||||
#define FC_AVICONF2_IT_CONTENT_MASK 0x00000080 /* IT content */
|
||||
|
||||
/* Frame Composer AVI Packet VIC Register */
|
||||
#define FC_AVIVID 0x00004070
|
||||
#define FC_AVIVID_FC_AVIVID_MASK 0x0000007F /* Configures the AVI InfoFrame Video Identification code */
|
||||
#define FC_AVIVID_FC_AVIVID_7_MASK 0x00000080 /* Bit 7 of fc_avivid register */
|
||||
|
||||
#define FC_AVIETB0 0x4074
|
||||
#define FC_AVIETB1 0x4078
|
||||
#define FC_AVISBB0 0x407C
|
||||
#define FC_AVISBB1 0x4080
|
||||
#define FC_AVIELB0 0x4084
|
||||
#define FC_AVIELB1 0x4088
|
||||
#define FC_AVISRB0 0x408C
|
||||
#define FC_AVISRB1 0x4090
|
||||
|
||||
/* Frame Composer AUD Packet Configuration Register 0 */
|
||||
#define FC_AUDICONF0 0x00004094
|
||||
#define FC_AUDICONF0_CT_MASK 0x0000000F /* Coding Type */
|
||||
#define FC_AUDICONF0_CC_MASK 0x00000070 /* Channel count */
|
||||
|
||||
/* Frame Composer AUD Packet Configuration Register 1 */
|
||||
#define FC_AUDICONF1 0x00004098
|
||||
#define FC_AUDICONF1_SF_MASK 0x00000007 /* Sampling frequency */
|
||||
#define FC_AUDICONF1_SS_MASK 0x00000030 /* Sampling size */
|
||||
|
||||
/* Frame Composer AUD Packet Configuration Register 2 */
|
||||
#define FC_AUDICONF2 0x0000409C
|
||||
#define FC_AUDICONF2_CA_MASK 0x000000FF /* Channel allocation */
|
||||
|
||||
/* Frame Composer AUD Packet Configuration Register 0 */
|
||||
#define FC_AUDICONF3 0x000040A0
|
||||
#define FC_AUDICONF3_LSV_MASK 0x0000000F /* Level shift value (for down mixing) */
|
||||
#define FC_AUDICONF3_DM_INH_MASK 0x00000010 /* Down mix enable */
|
||||
#define FC_AUDICONF3_LFEPBL_MASK 0x00000060 /* LFE playback information LFEPBL1, LFEPBL0 LFE playback level as compared to the other channels */
|
||||
|
||||
/* Frame Composer VSI Packet Data IEEE Register 0 */
|
||||
#define FC_VSDIEEEID0 0x000040A4
|
||||
#define FC_VSDIEEEID0_IEEE_MASK 0x000000FF /* This register configures the Vendor Specific InfoFrame IEEE registration identifier */
|
||||
|
||||
/* Frame Composer VSI Packet Data Size Register */
|
||||
#define FC_VSDSIZE 0x000040A8
|
||||
#define FC_VSDSIZE_VSDSIZE_MASK 0x0000001F /* Packet size as described in the HDMI Vendor Specific InfoFrame (from the HDMI specification) */
|
||||
|
||||
/* Frame Composer VSI Packet Data IEEE Register 1 */
|
||||
#define FC_VSDIEEEID1 0x000040C0
|
||||
#define FC_VSDIEEEID1_IEEE_MASK 0x000000FF /* This register configures the Vendor Specific InfoFrame IEEE registration identifier */
|
||||
|
||||
/* Frame Composer VSI Packet Data IEEE Register 2 */
|
||||
#define FC_VSDIEEEID2 0x000040C4
|
||||
#define FC_VSDIEEEID2_IEEE_MASK 0x000000FF /* This register configures the Vendor Specific InfoFrame IEEE registration identifier */
|
||||
|
||||
#define FC_VSDPAYLOAD0 0x40C8
|
||||
|
||||
#define FC_SPDVENDORNAME0 0x4128
|
||||
#define FC_SPDPRODUCTNAME0 0x4148
|
||||
|
||||
/* Frame Composer SPD Packet Data Source Product Descriptor Register */
|
||||
#define FC_SPDDEVICEINF 0x00004188
|
||||
#define FC_SPDDEVICEINF_FC_SPDDEVICEINF_MASK 0x000000FF /* Frame Composer SPD Packet Data Source Product Descriptor Register */
|
||||
|
||||
/* Frame Composer Audio Sample Flat and Layout Configuration Register */
|
||||
#define FC_AUDSCONF 0x0000418C
|
||||
#define FC_AUDSCONF_AUD_PACKET_LAYOUT_MASK 0x00000001 /* Set the audio packet layout to be sent in the packet: 1b: layout 1 0b: layout 0 If DWC_HDMI_TX_20 is defined and register field fc_multistream_ctrl */
|
||||
#define FC_AUDSCONF_AUD_PACKET_SAMPFLT_MASK 0x000000F0 /* Set the audio packet sample flat value to be sent on the packet */
|
||||
|
||||
/* Frame Composer Audio Sample Flat and Layout Configuration Register */
|
||||
#define FC_AUDSSTAT 0x00004190
|
||||
#define FC_AUDSSTAT_PACKET_SAMPPRS_MASK 0x0000000F /* Shows the data sample present indication of the last Audio sample packet sent by the HDMI TX Controller */
|
||||
|
||||
/* Frame Composer Audio Sample Validity Flag Register */
|
||||
#define FC_AUDSV 0x00004194
|
||||
#define FC_AUDSV_V0L_MASK 0x00000001 /* Set validity bit "V" for Channel 0, Left */
|
||||
#define FC_AUDSV_V1L_MASK 0x00000002 /* Set validity bit "V" for Channel 1, Left */
|
||||
#define FC_AUDSV_V2L_MASK 0x00000004 /* Set validity bit "V" for Channel 2, Left */
|
||||
#define FC_AUDSV_V3L_MASK 0x00000008 /* Set validity bit "V" for Channel 3, Left */
|
||||
#define FC_AUDSV_V0R_MASK 0x00000010 /* Set validity bit "V" for Channel 0, Right */
|
||||
#define FC_AUDSV_V1R_MASK 0x00000020 /* Set validity bit "V" for Channel 1, Right */
|
||||
#define FC_AUDSV_V2R_MASK 0x00000040 /* Set validity bit "V" for Channel 2, Right */
|
||||
#define FC_AUDSV_V3R_MASK 0x00000080 /* Set validity bit "V" for Channel 3, Right */
|
||||
|
||||
/* Frame Composer Audio Sample User Flag Register */
|
||||
#define FC_AUDSU 0x00004198
|
||||
#define FC_AUDSU_U0L_MASK 0x00000001 /* Set user bit "U" for Channel 0, Left */
|
||||
#define FC_AUDSU_U1L_MASK 0x00000002 /* Set user bit "U" for Channel 1, Left */
|
||||
#define FC_AUDSU_U2L_MASK 0x00000004 /* Set user bit "U" for Channel 2, Left */
|
||||
#define FC_AUDSU_U3L_MASK 0x00000008 /* Set user bit "U" for Channel 3, Left */
|
||||
#define FC_AUDSU_U0R_MASK 0x00000010 /* Set user bit "U" for Channel 0, Right */
|
||||
#define FC_AUDSU_U1R_MASK 0x00000020 /* Set user bit "U" for Channel 1, Right */
|
||||
#define FC_AUDSU_U2R_MASK 0x00000040 /* Set user bit "U" for Channel 2, Right */
|
||||
#define FC_AUDSU_U3R_MASK 0x00000080 /* Set user bit "U" for Channel 3, Right */
|
||||
|
||||
/* Frame Composer Audio Sample Channel Status Configuration Register 0 */
|
||||
#define FC_AUDSCHNL0 0x0000419C
|
||||
#define FC_AUDSCHNL0_OIEC_COPYRIGHT_MASK 0x00000001 /* IEC Copyright indication */
|
||||
#define FC_AUDSCHNL0_OIEC_CGMSA_MASK 0x00000030 /* CGMS-A */
|
||||
|
||||
/* Frame Composer Audio Sample Channel Status Configuration Register 1 */
|
||||
#define FC_AUDSCHNL1 0x000041A0
|
||||
#define FC_AUDSCHNL1_OIEC_CATEGORYCODE_MASK 0x000000FF /* Category code */
|
||||
|
||||
/* Frame Composer Audio Sample Channel Status Configuration Register 2 */
|
||||
#define FC_AUDSCHNL2 0x000041A4
|
||||
#define FC_AUDSCHNL2_OIEC_SOURCENUMBER_MASK 0x0000000F /* Source number */
|
||||
#define FC_AUDSCHNL2_OIEC_PCMAUDIOMODE_MASK 0x00000070 /* PCM audio mode */
|
||||
|
||||
/* Frame Composer Audio Sample Channel Status Configuration Register 3 */
|
||||
#define FC_AUDSCHNL3 0x000041A8
|
||||
#define FC_AUDSCHNL3_OIEC_CHANNELNUMCR0_MASK 0x0000000F /* Channel number for first right sample */
|
||||
#define FC_AUDSCHNL3_OIEC_CHANNELNUMCR1_MASK 0x000000F0 /* Channel number for second right sample */
|
||||
|
||||
/* Frame Composer Audio Sample Channel Status Configuration Register 4 */
|
||||
#define FC_AUDSCHNL4 0x000041AC
|
||||
#define FC_AUDSCHNL4_OIEC_CHANNELNUMCR2_MASK 0x0000000F /* Channel number for third right sample */
|
||||
#define FC_AUDSCHNL4_OIEC_CHANNELNUMCR3_MASK 0x000000F0 /* Channel number for fourth right sample */
|
||||
|
||||
/* Frame Composer Audio Sample Channel Status Configuration Register 5 */
|
||||
#define FC_AUDSCHNL5 0x000041B0
|
||||
#define FC_AUDSCHNL5_OIEC_CHANNELNUMCL0_MASK 0x0000000F /* Channel number for first left sample */
|
||||
#define FC_AUDSCHNL5_OIEC_CHANNELNUMCL1_MASK 0x000000F0 /* Channel number for second left sample */
|
||||
|
||||
/* Frame Composer Audio Sample Channel Status Configuration Register 6 */
|
||||
#define FC_AUDSCHNL6 0x000041B4
|
||||
#define FC_AUDSCHNL6_OIEC_CHANNELNUMCL2_MASK 0x0000000F /* Channel number for third left sample */
|
||||
#define FC_AUDSCHNL6_OIEC_CHANNELNUMCL3_MASK 0x000000F0 /* Channel number for fourth left sample */
|
||||
|
||||
/* Frame Composer Audio Sample Channel Status Configuration Register 7 */
|
||||
#define FC_AUDSCHNL7 0x000041B8
|
||||
#define FC_AUDSCHNL7_OIEC_SAMPFREQ_MASK 0x0000000F /* Sampling frequency */
|
||||
#define FC_AUDSCHNL7_OIEC_CLKACCURACY_MASK 0x00000030 /* Clock accuracy */
|
||||
#define FC_AUDSCHNL7_OIEC_SAMPFREQ_EXT_MASK 0x000000C0 /* Sampling frequency (channel status bits 31 and 30) */
|
||||
|
||||
/* Frame Composer Audio Sample Channel Status Configuration Register 8 */
|
||||
#define FC_AUDSCHNL8 0x000041BC
|
||||
#define FC_AUDSCHNL8_OIEC_WORDLENGTH_MASK 0x0000000F /* Word length configuration */
|
||||
#define FC_AUDSCHNL8_OIEC_ORIGSAMPFREQ_MASK 0x000000F0 /* Original sampling frequency */
|
||||
|
||||
/* Frame Composer Number of High Priority Packets Attended Configuration Register */
|
||||
#define FC_CTRLQHIGH 0x000041CC
|
||||
#define FC_CTRLQHIGH_ONHIGHATTENDED_MASK 0x0000001F /* Configures the number of high priority packets or audio sample packets consecutively attended before checking low priority queue status */
|
||||
|
||||
/* Frame Composer Number of Low Priority Packets Attended Configuration Register */
|
||||
#define FC_CTRLQLOW 0x000041D0
|
||||
#define FC_CTRLQLOW_ONLOWATTENDED_MASK 0x0000001F /* Configures the number of low priority packets or null packets consecutively attended before checking high priority queue status or audio samples availability */
|
||||
|
||||
/*ACP: Audio content protection*/
|
||||
/* Frame Composer ACP Packet Type Configuration Register 0 */
|
||||
#define FC_ACP0 0x000041D4
|
||||
#define FC_ACP0_ACPTYPE_MASK 0x000000FF /* Configures the ACP packet type */
|
||||
|
||||
/* Frame Composer ACP Packet Body Configuration Register 16 */
|
||||
#define FC_ACP16 0x00004208
|
||||
#define FC_ACP16_FC_ACP16_MASK 0x000000FF /* Frame Composer ACP Packet Body Configuration Register 16 */
|
||||
|
||||
/* Frame Composer ACP Packet Body Configuration Register 15 */
|
||||
#define FC_ACP15 0x0000420C
|
||||
#define FC_ACP15_FC_ACP15_MASK 0x000000FF /* Frame Composer ACP Packet Body Configuration Register 15 */
|
||||
|
||||
/* Frame Composer ACP Packet Body Configuration Register 14 */
|
||||
#define FC_ACP14 0x00004210
|
||||
#define FC_ACP14_FC_ACP14_MASK 0x000000FF /* Frame Composer ACP Packet Body Configuration Register 14 */
|
||||
|
||||
/* Frame Composer ACP Packet Body Configuration Register 13 */
|
||||
#define FC_ACP13 0x00004214
|
||||
#define FC_ACP13_FC_ACP13_MASK 0x000000FF /* Frame Composer ACP Packet Body Configuration Register 13 */
|
||||
|
||||
/* Frame Composer ACP Packet Body Configuration Register 12 */
|
||||
#define FC_ACP12 0x00004218
|
||||
#define FC_ACP12_FC_ACP12_MASK 0x000000FF /* Frame Composer ACP Packet Body Configuration Register 12 */
|
||||
|
||||
/* Frame Composer ACP Packet Body Configuration Register 11 */
|
||||
#define FC_ACP11 0x0000421C
|
||||
#define FC_ACP11_FC_ACP11_MASK 0x000000FF /* Frame Composer ACP Packet Body Configuration Register 11 */
|
||||
|
||||
/* Frame Composer ACP Packet Body Configuration Register 10 */
|
||||
#define FC_ACP10 0x00004220
|
||||
#define FC_ACP10_FC_ACP10_MASK 0x000000FF /* Frame Composer ACP Packet Body Configuration Register 10 */
|
||||
|
||||
/* Frame Composer ACP Packet Body Configuration Register 9 */
|
||||
#define FC_ACP9 0x00004224
|
||||
#define FC_ACP9_FC_ACP9_MASK 0x000000FF /* Frame Composer ACP Packet Body Configuration Register 9 */
|
||||
|
||||
/* Frame Composer ACP Packet Body Configuration Register 8 */
|
||||
#define FC_ACP8 0x00004228
|
||||
#define FC_ACP8_FC_ACP8_MASK 0x000000FF /* Frame Composer ACP Packet Body Configuration Register 8 */
|
||||
|
||||
/* Frame Composer ACP Packet Body Configuration Register 7 */
|
||||
#define FC_ACP7 0x0000422C
|
||||
#define FC_ACP7_FC_ACP7_MASK 0x000000FF /* Frame Composer ACP Packet Body Configuration Register 7 */
|
||||
|
||||
/* Frame Composer ACP Packet Body Configuration Register 6 */
|
||||
#define FC_ACP6 0x00004230
|
||||
#define FC_ACP6_FC_ACP6_MASK 0x000000FF /* Frame Composer ACP Packet Body Configuration Register 6 */
|
||||
|
||||
/* Frame Composer ACP Packet Body Configuration Register 5 */
|
||||
#define FC_ACP5 0x00004234
|
||||
#define FC_ACP5_FC_ACP5_MASK 0x000000FF /* Frame Composer ACP Packet Body Configuration Register 5 */
|
||||
|
||||
/* Frame Composer ACP Packet Body Configuration Register 4 */
|
||||
#define FC_ACP4 0x00004238
|
||||
#define FC_ACP4_FC_ACP4_MASK 0x000000FF /* Frame Composer ACP Packet Body Configuration Register 4 */
|
||||
|
||||
/* Frame Composer ACP Packet Body Configuration Register 3 */
|
||||
#define FC_ACP3 0x0000423C
|
||||
#define FC_ACP3_FC_ACP3_MASK 0x000000FF /* Frame Composer ACP Packet Body Configuration Register 3 */
|
||||
|
||||
/* Frame Composer ACP Packet Body Configuration Register 2 */
|
||||
#define FC_ACP2 0x00004240
|
||||
#define FC_ACP2_FC_ACP2_MASK 0x000000FF /* Frame Composer ACP Packet Body Configuration Register 2 */
|
||||
|
||||
/* Frame Composer ACP Packet Body Configuration Register 1 */
|
||||
#define FC_ACP1 0x00004244
|
||||
#define FC_ACP1_FC_ACP1_MASK 0x000000FF /* Frame Composer ACP Packet Body Configuration Register 1 */
|
||||
|
||||
/* Frame Composer ISRC1 Packet Status, Valid, and Continue Configuration Register */
|
||||
#define FC_ISCR1_0 0x00004248
|
||||
#define FC_ISCR1_0_ISRC_CONT_MASK 0x00000001 /* ISRC1 Indication of packet continuation (ISRC2 will be transmitted) */
|
||||
#define FC_ISCR1_0_ISRC_VALID_MASK 0x00000002 /* ISRC1 Valid control signal */
|
||||
#define FC_ISCR1_0_ISRC_STATUS_MASK 0x0000001C /* ISRC1 Status signal */
|
||||
|
||||
/* Frame Composer ISRC1 Packet Body Register 16 */
|
||||
#define FC_ISCR1_16 0x0000424C
|
||||
#define FC_ISCR1_16_FC_ISCR1_16_MASK 0x000000FF /* Frame Composer ISRC1 Packet Body Register 16; configures ISRC1 packet body of the ISRC1 packet */
|
||||
|
||||
/* Frame Composer ISRC1 Packet Body Register 15 */
|
||||
#define FC_ISCR1_15 0x00004250
|
||||
#define FC_ISCR1_15_FC_ISCR1_15_MASK 0x000000FF /* Frame Composer ISRC1 Packet Body Register 15 */
|
||||
|
||||
/* Frame Composer ISRC1 Packet Body Register 14 */
|
||||
#define FC_ISCR1_14 0x00004254
|
||||
#define FC_ISCR1_14_FC_ISCR1_14_MASK 0x000000FF /* Frame Composer ISRC1 Packet Body Register 14 */
|
||||
|
||||
/* Frame Composer ISRC1 Packet Body Register 13 */
|
||||
#define FC_ISCR1_13 0x00004258
|
||||
#define FC_ISCR1_13_FC_ISCR1_13_MASK 0x000000FF /* Frame Composer ISRC1 Packet Body Register 13 */
|
||||
|
||||
/* Frame Composer ISRC1 Packet Body Register 12 */
|
||||
#define FC_ISCR1_12 0x0000425C
|
||||
#define FC_ISCR1_12_FC_ISCR1_12_MASK 0x000000FF /* Frame Composer ISRC1 Packet Body Register 12 */
|
||||
|
||||
/* Frame Composer ISRC1 Packet Body Register 11 */
|
||||
#define FC_ISCR1_11 0x00004260
|
||||
#define FC_ISCR1_11_FC_ISCR1_11_MASK 0x000000FF /* Frame Composer ISRC1 Packet Body Register 11 */
|
||||
|
||||
/* Frame Composer ISRC1 Packet Body Register 10 */
|
||||
#define FC_ISCR1_10 0x00004264
|
||||
#define FC_ISCR1_10_FC_ISCR1_10_MASK 0x000000FF /* Frame Composer ISRC1 Packet Body Register 10 */
|
||||
|
||||
/* Frame Composer ISRC1 Packet Body Register 9 */
|
||||
#define FC_ISCR1_9 0x00004268
|
||||
#define FC_ISCR1_9_FC_ISCR1_9_MASK 0x000000FF /* Frame Composer ISRC1 Packet Body Register 9 */
|
||||
|
||||
/* Frame Composer ISRC1 Packet Body Register 8 */
|
||||
#define FC_ISCR1_8 0x0000426C
|
||||
#define FC_ISCR1_8_FC_ISCR1_8_MASK 0x000000FF /* Frame Composer ISRC1 Packet Body Register 8 */
|
||||
|
||||
/* Frame Composer ISRC1 Packet Body Register 7 */
|
||||
#define FC_ISCR1_7 0x00004270
|
||||
#define FC_ISCR1_7_FC_ISCR1_7_MASK 0x000000FF /* Frame Composer ISRC1 Packet Body Register 7 */
|
||||
|
||||
/* Frame Composer ISRC1 Packet Body Register 6 */
|
||||
#define FC_ISCR1_6 0x00004274
|
||||
#define FC_ISCR1_6_FC_ISCR1_6_MASK 0x000000FF /* Frame Composer ISRC1 Packet Body Register 6 */
|
||||
|
||||
/* Frame Composer ISRC1 Packet Body Register 5 */
|
||||
#define FC_ISCR1_5 0x00004278
|
||||
#define FC_ISCR1_5_FC_ISCR1_5_MASK 0x000000FF /* Frame Composer ISRC1 Packet Body Register 5 */
|
||||
|
||||
/* Frame Composer ISRC1 Packet Body Register 4 */
|
||||
#define FC_ISCR1_4 0x0000427C
|
||||
#define FC_ISCR1_4_FC_ISCR1_4_MASK 0x000000FF /* Frame Composer ISRC1 Packet Body Register 4 */
|
||||
|
||||
/* Frame Composer ISRC1 Packet Body Register 3 */
|
||||
#define FC_ISCR1_3 0x00004280
|
||||
#define FC_ISCR1_3_FC_ISCR1_3_MASK 0x000000FF /* Frame Composer ISRC1 Packet Body Register 3 */
|
||||
|
||||
/* Frame Composer ISRC1 Packet Body Register 2 */
|
||||
#define FC_ISCR1_2 0x00004284
|
||||
#define FC_ISCR1_2_FC_ISCR1_2_MASK 0x000000FF /* Frame Composer ISRC1 Packet Body Register 2 */
|
||||
|
||||
/* Frame Composer ISRC1 Packet Body Register 1 */
|
||||
#define FC_ISCR1_1 0x00004288
|
||||
#define FC_ISCR1_1_FC_ISCR1_1_MASK 0x000000FF /* Frame Composer ISRC1 Packet Body Register 1 */
|
||||
|
||||
/* Frame Composer ISRC2 Packet Body Register 15 */
|
||||
#define FC_ISCR2_15 0x0000428C
|
||||
#define FC_ISCR2_15_FC_ISCR2_15_MASK 0x000000FF /* Frame Composer ISRC2 Packet Body Register 15; configures the ISRC2 packet body of the ISRC2 packet */
|
||||
|
||||
/* Frame Composer ISRC2 Packet Body Register 14 */
|
||||
#define FC_ISCR2_14 0x00004290
|
||||
#define FC_ISCR2_14_FC_ISCR2_14_MASK 0x000000FF /* Frame Composer ISRC2 Packet Body Register 14 */
|
||||
|
||||
/* Frame Composer ISRC2 Packet Body Register 13 */
|
||||
#define FC_ISCR2_13 0x00004294
|
||||
#define FC_ISCR2_13_FC_ISCR2_13_MASK 0x000000FF /* Frame Composer ISRC2 Packet Body Register 13 */
|
||||
|
||||
/* Frame Composer ISRC2 Packet Body Register 12 */
|
||||
#define FC_ISCR2_12 0x00004298
|
||||
#define FC_ISCR2_12_FC_ISCR2_12_MASK 0x000000FF /* Frame Composer ISRC2 Packet Body Register 12 */
|
||||
|
||||
/* Frame Composer ISRC2 Packet Body Register 11 */
|
||||
#define FC_ISCR2_11 0x0000429C
|
||||
#define FC_ISCR2_11_FC_ISCR2_11_MASK 0x000000FF /* Frame Composer ISRC2 Packet Body Register 11 */
|
||||
|
||||
/* Frame Composer ISRC2 Packet Body Register 10 */
|
||||
#define FC_ISCR2_10 0x000042A0
|
||||
#define FC_ISCR2_10_FC_ISCR2_10_MASK 0x000000FF /* Frame Composer ISRC2 Packet Body Register 10 */
|
||||
|
||||
/* Frame Composer ISRC2 Packet Body Register 9 */
|
||||
#define FC_ISCR2_9 0x000042A4
|
||||
#define FC_ISCR2_9_FC_ISCR2_9_MASK 0x000000FF /* Frame Composer ISRC2 Packet Body Register 9 */
|
||||
|
||||
/* Frame Composer ISRC2 Packet Body Register 8 */
|
||||
#define FC_ISCR2_8 0x000042A8
|
||||
#define FC_ISCR2_8_FC_ISCR2_8_MASK 0x000000FF /* Frame Composer ISRC2 Packet Body Register 8 */
|
||||
|
||||
/* Frame Composer ISRC2 Packet Body Register 7 */
|
||||
#define FC_ISCR2_7 0x000042AC
|
||||
#define FC_ISCR2_7_FC_ISCR2_7_MASK 0x000000FF /* Frame Composer ISRC2 Packet Body Register 7 */
|
||||
|
||||
/* Frame Composer ISRC2 Packet Body Register 6 */
|
||||
#define FC_ISCR2_6 0x000042B0
|
||||
#define FC_ISCR2_6_FC_ISCR2_6_MASK 0x000000FF /* Frame Composer ISRC2 Packet Body Register 6 */
|
||||
|
||||
/* Frame Composer ISRC2 Packet Body Register 5 */
|
||||
#define FC_ISCR2_5 0x000042B4
|
||||
#define FC_ISCR2_5_FC_ISCR2_5_MASK 0x000000FF /* Frame Composer ISRC2 Packet Body Register 5 */
|
||||
|
||||
/* Frame Composer ISRC2 Packet Body Register 4 */
|
||||
#define FC_ISCR2_4 0x000042B8
|
||||
#define FC_ISCR2_4_FC_ISCR2_4_MASK 0x000000FF /* Frame Composer ISRC2 Packet Body Register 4 */
|
||||
|
||||
/* Frame Composer ISRC2 Packet Body Register 3 */
|
||||
#define FC_ISCR2_3 0x000042BC
|
||||
#define FC_ISCR2_3_FC_ISCR2_3_MASK 0x000000FF /* Frame Composer ISRC2 Packet Body Register 3 */
|
||||
|
||||
/* Frame Composer ISRC2 Packet Body Register 2 */
|
||||
#define FC_ISCR2_2 0x000042C0
|
||||
#define FC_ISCR2_2_FC_ISCR2_2_MASK 0x000000FF /* Frame Composer ISRC2 Packet Body Register 2 */
|
||||
|
||||
/* Frame Composer ISRC2 Packet Body Register 1 */
|
||||
#define FC_ISCR2_1 0x000042C4
|
||||
#define FC_ISCR2_1_FC_ISCR2_1_MASK 0x000000FF /* Frame Composer ISRC2 Packet Body Register 1 */
|
||||
|
||||
/* Frame Composer ISRC2 Packet Body Register 0 */
|
||||
#define FC_ISCR2_0 0x000042C8
|
||||
#define FC_ISCR2_0_FC_ISCR2_0_MASK 0x000000FF /* Frame Composer ISRC2 Packet Body Register 0 */
|
||||
|
||||
/* Frame Composer Data Island Auto Packet Scheduling Register 0 Configures the Frame Composer RDRB(1)/Manual(0) data island packet insertion for SPD, VSD, ISRC2, ISRC1 and ACP packets */
|
||||
#define FC_DATAUTO0 0x000042CC
|
||||
#define FC_DATAUTO0_ACP_AUTO_MASK 0x00000001 /* Enables ACP automatic packet scheduling */
|
||||
#define FC_DATAUTO0_ISCR1_AUTO_MASK 0x00000002 /* Enables ISRC1 automatic packet scheduling */
|
||||
#define FC_DATAUTO0_ISCR2_AUTO_MASK 0x00000004 /* Enables ISRC2 automatic packet scheduling */
|
||||
#define FC_DATAUTO0_VSD_AUTO_MASK 0x00000008 /* Enables VSD automatic packet scheduling */
|
||||
#define FC_DATAUTO0_SPD_AUTO_MASK 0x00000010 /* Enables SPD automatic packet scheduling */
|
||||
|
||||
/* Frame Composer Data Island Auto Packet Scheduling Register 1 Configures the Frame Composer (FC) RDRB frame interpolation for SPD, VSD, ISRC2, ISRC1 and ACP packet insertion on data island when FC is on RDRB mode for the listed packets */
|
||||
#define FC_DATAUTO1 0x000042D0
|
||||
#define FC_DATAUTO1_AUTO_FRAME_INTERPOLATION_MASK 0x0000000F /* Packet frame interpolation for automatic packet scheduling */
|
||||
|
||||
/* Frame Composer Data Island Auto packet scheduling Register 2 Configures the Frame Composer (FC) RDRB line interpolation and number of packets in frame for SPD, VSD, ISRC2, ISRC1 and ACP packet insertion on data island when FC is on RDRB mode for the listed packets */
|
||||
#define FC_DATAUTO2 0x000042D4
|
||||
#define FC_DATAUTO2_AUTO_LINE_SPACING_MASK 0x0000000F /* Packets line spacing, for automatic packet scheduling */
|
||||
#define FC_DATAUTO2_AUTO_FRAME_PACKETS_MASK 0x000000F0 /* Packets per frame, for automatic packet scheduling */
|
||||
|
||||
/* Frame Composer Data Island Manual Packet Request Register Requests to the Frame Composer the data island packet insertion for NULL, SPD, VSD, ISRC2, ISRC1 and ACP packets when FC_DATAUTO0 bit is in manual mode for the packet requested */
|
||||
#define FC_DATMAN 0x000042D8
|
||||
#define FC_DATMAN_ACP_TX_MASK 0x00000001 /* ACP packet */
|
||||
#define FC_DATMAN_ISCR1_TX_MASK 0x00000002 /* ISRC1 packet */
|
||||
#define FC_DATMAN_ISCR2_TX_MASK 0x00000004 /* ISRC2 packet */
|
||||
#define FC_DATMAN_VSD_TX_MASK 0x00000008 /* VSD packet */
|
||||
#define FC_DATMAN_SPD_TX_MASK 0x00000010 /* SPD packet */
|
||||
#define FC_DATMAN_NULL_TX_MASK 0x00000020 /* Null packet */
|
||||
|
||||
/* Frame Composer Data Island Auto Packet Scheduling Register 3 Configures the Frame Composer Automatic(1)/RDRB(0) data island packet insertion for AVI, GCP, AUDI and ACR packets */
|
||||
#define FC_DATAUTO3 0x000042DC
|
||||
#define FC_DATAUTO3_ACR_AUTO_MASK 0x00000001 /* Enables ACR packet insertion */
|
||||
#define FC_DATAUTO3_AUDI_AUTO_MASK 0x00000002 /* Enables AUDI packet insertion */
|
||||
#define FC_DATAUTO3_GCP_AUTO_MASK 0x00000004 /* Enables GCP packet insertion */
|
||||
#define FC_DATAUTO3_AVI_AUTO_MASK 0x00000008 /* Enables AVI packet insertion */
|
||||
#define FC_DATAUTO3_AMP_AUTO_MASK 0x00000010 /* Enables AMP packet insertion */
|
||||
#define FC_DATAUTO3_NVBI_AUTO_MASK 0x00000020 /* Enables NTSC VBI packet insertion */
|
||||
|
||||
/* Frame Composer Round Robin ACR Packet Insertion Register 0 Configures the Frame Composer (FC) RDRB frame interpolation for ACR packet insertion on data island when FC is on RDRB mode for this packet */
|
||||
#define FC_RDRB0 0x000042E0
|
||||
#define FC_RDRB0_ACRFRAMEINTERPOLATION_MASK 0x0000000F /* ACR Frame interpolation */
|
||||
|
||||
/* Frame Composer Round Robin ACR Packet Insertion Register 1 Configures the Frame Composer (FC) RDRB line interpolation and number of packets in frame for the ACR packet insertion on data island when FC is on RDRB mode this packet */
|
||||
#define FC_RDRB1 0x000042E4
|
||||
#define FC_RDRB1_ACRPACKETLINESPACING_MASK 0x0000000F /* ACR packet line spacing */
|
||||
#define FC_RDRB1_ACRPACKETSINFRAME_MASK 0x000000F0 /* ACR packets in frame */
|
||||
|
||||
/* Frame Composer Round Robin AUDI Packet Insertion Register 2 Configures the Frame Composer (FC) RDRB frame interpolation for AUDI packet insertion on data island when FC is on RDRB mode for this packet */
|
||||
#define FC_RDRB2 0x000042E8
|
||||
#define FC_RDRB2_AUDIFRAMEINTERPOLATION_MASK 0x0000000F /* Audio frame interpolation */
|
||||
|
||||
/* Frame Composer Round Robin AUDI Packet Insertion Register 3 Configures the Frame Composer (FC) RDRB line interpolation and number of packets in frame for the AUDI packet insertion on data island when FC is on RDRB mode this packet */
|
||||
#define FC_RDRB3 0x000042EC
|
||||
#define FC_RDRB3_AUDIPACKETLINESPACING_MASK 0x0000000F /* Audio packets line spacing */
|
||||
#define FC_RDRB3_AUDIPACKETSINFRAME_MASK 0x000000F0 /* Audio packets per frame */
|
||||
|
||||
/* Frame Composer Round Robin GCP Packet Insertion Register 4 Configures the Frame Composer (FC) RDRB frame interpolation for GCP packet insertion on data island when FC is on RDRB mode for this packet */
|
||||
#define FC_RDRB4 0x000042F0
|
||||
#define FC_RDRB4_GCPFRAMEINTERPOLATION_MASK 0x0000000F /* Frames interpolated between GCP packets */
|
||||
|
||||
/* Frame Composer Round Robin GCP Packet Insertion Register 5 Configures the Frame Composer (FC) RDRB line interpolation and number of packets in frame for the GCP packet insertion on data island when FC is on RDRB mode this packet */
|
||||
#define FC_RDRB5 0x000042F4
|
||||
#define FC_RDRB5_GCPPACKETLINESPACING_MASK 0x0000000F /* GCP packets line spacing */
|
||||
#define FC_RDRB5_GCPPACKETSINFRAME_MASK 0x000000F0 /* GCP packets per frame */
|
||||
|
||||
/* Frame Composer Round Robin AVI Packet Insertion Register 6 Configures the Frame Composer (FC) RDRB frame interpolation for AVI packet insertion on data island when FC is on RDRB mode for this packet */
|
||||
#define FC_RDRB6 0x000042F8
|
||||
#define FC_RDRB6_AVIFRAMEINTERPOLATION_MASK 0x0000000F /* Frames interpolated between AVI packets */
|
||||
|
||||
/* Frame Composer Round Robin AVI Packet Insertion Register 7 Configures the Frame Composer (FC) RDRB line interpolation and number of packets in frame for the AVI packet insertion on data island when FC is on RDRB mode this packet */
|
||||
#define FC_RDRB7 0x000042FC
|
||||
#define FC_RDRB7_AVIPACKETLINESPACING_MASK 0x0000000F /* AVI packets line spacing */
|
||||
#define FC_RDRB7_AVIPACKETSINFRAME_MASK 0x000000F0 /* AVI packets per frame */
|
||||
|
||||
/* Frame Composer Round Robin AMP Packet Insertion Register 8 */
|
||||
#define FC_RDRB8 0x00004300
|
||||
#define FC_RDRB8_AMPFRAMEINTERPOLATION_MASK 0x0000000F /* AMP frame interpolation */
|
||||
|
||||
/* Frame Composer Round Robin AMP Packet Insertion Register 9 */
|
||||
#define FC_RDRB9 0x00004304
|
||||
#define FC_RDRB9_AMPPACKETLINESPACING_MASK 0x0000000F /* AMP packets line spacing */
|
||||
#define FC_RDRB9_AMPPACKETSINFRAME_MASK 0x000000F0 /* AMP packets per frame */
|
||||
|
||||
/* Frame Composer Round Robin NTSC VBI Packet Insertion Register 10 */
|
||||
#define FC_RDRB10 0x00004308
|
||||
#define FC_RDRB10_NVBIFRAMEINTERPOLATION_MASK 0x0000000F /* NTSC VBI frame interpolation */
|
||||
|
||||
/* Frame Composer Round Robin NTSC VBI Packet Insertion Register 11 */
|
||||
#define FC_RDRB11 0x0000430C
|
||||
#define FC_RDRB11_NVBIPACKETLINESPACING_MASK 0x0000000F /* NTSC VBI packets line spacing */
|
||||
#define FC_RDRB11_NVBIPACKETSINFRAME_MASK 0x000000F0 /* NTSC VBI packets per frame */
|
||||
|
||||
/* Frame Composer Packet Interrupt Mask Register 0 */
|
||||
#define FC_MASK0 0x00004348
|
||||
#define FC_MASK0_NULL_MASK 0x00000001 /* Mask bit for FC_INT0 */
|
||||
#define FC_MASK0_ACR_MASK 0x00000002 /* Mask bit for FC_INT0 */
|
||||
#define FC_MASK0_AUDS_MASK 0x00000004 /* Mask bit for FC_INT0 */
|
||||
#define FC_MASK0_NVBI_MASK 0x00000008 /* Mask bit for FC_INT0 */
|
||||
#define FC_MASK0_MAS_MASK 0x00000010 /* Mask bit for FC_INT0 */
|
||||
#define FC_MASK0_HBR_MASK 0x00000020 /* Mask bit for FC_INT0 */
|
||||
#define FC_MASK0_ACP_MASK 0x00000040 /* Mask bit for FC_INT0 */
|
||||
#define FC_MASK0_AUDI_MASK 0x00000080 /* Mask bit for FC_INT0 */
|
||||
|
||||
/* Frame Composer Packet Interrupt Mask Register 1 */
|
||||
#define FC_MASK1 0x00004358
|
||||
#define FC_MASK1_GCP_MASK 0x00000001 /* Mask bit for FC_INT1 */
|
||||
#define FC_MASK1_AVI_MASK 0x00000002 /* Mask bit for FC_INT1 */
|
||||
#define FC_MASK1_AMP_MASK 0x00000004 /* Mask bit for FC_INT1 */
|
||||
#define FC_MASK1_SPD_MASK 0x00000008 /* Mask bit for FC_INT1 */
|
||||
#define FC_MASK1_VSD_MASK 0x00000010 /* Mask bit for FC_INT1 */
|
||||
#define FC_MASK1_ISCR2_MASK 0x00000020 /* Mask bit for FC_INT1 */
|
||||
#define FC_MASK1_ISCR1_MASK 0x00000040 /* Mask bit for FC_INT1 */
|
||||
#define FC_MASK1_GMD_MASK 0x00000080 /* Mask bit for FC_INT1 */
|
||||
|
||||
/* Frame Composer High/Low Priority Overflow Interrupt Mask Register 2 */
|
||||
#define FC_MASK2 0x00004368
|
||||
#define FC_MASK2_HIGHPRIORITY_OVERFLOW_MASK 0x00000001 /* Mask bit for FC_INT2 */
|
||||
#define FC_MASK2_LOWPRIORITY_OVERFLOW_MASK 0x00000002 /* Mask bit for FC_INT2 */
|
||||
|
||||
/* Frame Composer Pixel Repetition Configuration Register */
|
||||
#define FC_PRCONF 0x00004380
|
||||
#define FC_PRCONF_OUTPUT_PR_FACTOR_MASK 0x0000000F /* Configures the video pixel repetition ratio to be sent on the AVI InfoFrame */
|
||||
#define FC_PRCONF_INCOMING_PR_FACTOR_MASK 0x000000F0 /* Configures the input video pixel repetition */
|
||||
|
||||
/* Frame Composer Scrambler Control */
|
||||
#define FC_SCRAMBLER_CTRL 0x00004384
|
||||
#define FC_SCRAMBLER_CTRL_SCRAMBLER_ON_MASK 0x00000001 /* When set (1'b1), this field activates the HDMI 2 */
|
||||
#define FC_SCRAMBLER_CTRL_SCRAMBLER_UCP_LINE_MASK 0x00000010 /* Debug register */
|
||||
|
||||
/* Frame Composer Multi-Stream Audio Control */
|
||||
#define FC_MULTISTREAM_CTRL 0x00004388
|
||||
#define FC_MULTISTREAM_CTRL_FC_MAS_PACKET_EN_MASK 0x00000001 /* This field, when set (1'b1), activates the HDMI 2 */
|
||||
|
||||
/* Frame Composer Packet Transmission Control */
|
||||
#define FC_PACKET_TX_EN 0x0000438C
|
||||
#define FC_PACKET_TX_EN_ACR_TX_EN_MASK 0x00000001 /* ACR packet transmission control 1b: Transmission enabled 0b: Transmission disabled */
|
||||
#define FC_PACKET_TX_EN_GCP_TX_EN_MASK 0x00000002 /* GCP transmission control 1b: Transmission enabled 0b: Transmission disabled */
|
||||
#define FC_PACKET_TX_EN_AVI_TX_EN_MASK 0x00000004 /* AVI packet transmission control 1b: Transmission enabled 0b: Transmission disabled */
|
||||
#define FC_PACKET_TX_EN_AUDI_TX_EN_MASK 0x00000008 /* AUDI packet transmission control 1b: Transmission enabled 0b: Transmission disabled */
|
||||
#define FC_PACKET_TX_EN_AUT_TX_EN_MASK 0x00000010 /* ACP, SPD, VSIF, ISRC1, and SRC2 packet transmission control 1b: Transmission enabled 0b: Transmission disabled */
|
||||
#define FC_PACKET_TX_EN_AMP_TX_EN_MASK 0x00000020 /* AMP transmission control 1b: Transmission enabled 0b: Transmission disabled */
|
||||
#define FC_PACKET_TX_EN_NVBI_TX_EN_MASK 0x00000040 /* NTSC VBI transmission control 1b: Transmission enabled 0b: Transmission disabled */
|
||||
#define FC_PACKET_TX_EN_DRM_TX_EN_MASK 0x00000080/*DRM transmission control*/
|
||||
|
||||
/* Frame Composer Active Space Control */
|
||||
#define FC_ACTSPC_HDLR_CFG 0x000043A0
|
||||
#define FC_ACTSPC_HDLR_CFG_ACTSPC_HDLR_EN_MASK 0x00000001 /* Active Space Handler Control 1b: Fixed active space value mode enabled */
|
||||
#define FC_ACTSPC_HDLR_CFG_ACTSPC_HDLR_TGL_MASK 0x00000002 /* Active Space handler control 1b: Active space 1 value is different from Active Space 2 value */
|
||||
|
||||
/* Frame Composer Input Video 2D VActive Pixels Register 0 */
|
||||
#define FC_INVACT_2D_0 0x000043A4
|
||||
#define FC_INVACT_2D_0_FC_INVACT_2D_0_MASK 0x000000FF /* 2D Input video vertical active pixel region width */
|
||||
|
||||
/* Frame Composer Input Video VActive pixels Register 1 */
|
||||
#define FC_INVACT_2D_1 0x000043A8
|
||||
#define FC_INVACT_2D_1_FC_INVACT_2D_1_MASK 0x0000000F /* 2D Input video vertical active pixel region width */
|
||||
|
||||
/* Frame Composer GMD Packet Status Register Gamut metadata packet status bit information for no_current_gmd, next_gmd_field, gmd_packet_sequence and current_gamut_seq_num */
|
||||
#define FC_GMD_STAT 0x00004400
|
||||
#define FC_GMD_STAT_IGMDCURRENT_GAMUT_SEQ_NUM_MASK 0x0000000F /* Gamut scheduling: Current Gamut packet sequence number */
|
||||
#define FC_GMD_STAT_IGMDPACKET_SEQ_MASK 0x00000030 /* Gamut scheduling: Gamut packet sequence */
|
||||
#define FC_GMD_STAT_IGMDDNEXT_FIELD_MASK 0x00000040 /* Gamut scheduling: Gamut Next field */
|
||||
#define FC_GMD_STAT_IGMDNO_CRNT_GBD_MASK 0x00000080 /* Gamut scheduling: No current gamut data */
|
||||
|
||||
/* Frame Composer GMD Packet Enable Register This register enables Gamut metadata (GMD) packet transmission */
|
||||
#define FC_GMD_EN 0x00004404
|
||||
#define FC_GMD_EN_GMDENABLETX_MASK 0x00000001 /* Gamut Metadata packet transmission enable (1b) */
|
||||
|
||||
/* Frame Composer GMD Packet Update Register This register performs an GMD packet content update according to the configured packet body (FC_GMD_PB0 to FC_GMD_PB27) and packet header (FC_GMD_HB) */
|
||||
#define FC_GMD_UP 0x00004408
|
||||
#define FC_GMD_UP_GMDUPDATEPACKET_MASK 0x00000001 /* Gamut Metadata packet update */
|
||||
|
||||
/* Frame Composer GMD Packet Schedule Configuration Register This register configures the number of GMD packets to be inserted per frame (starting always in the line where the active Vsync appears) and the line spacing between the transmitted GMD packets */
|
||||
#define FC_GMD_CONF 0x0000440C
|
||||
#define FC_GMD_CONF_GMDPACKETLINESPACING_MASK 0x0000000F /* Number of line spacing between the transmitted GMD packets */
|
||||
#define FC_GMD_CONF_GMDPACKETSINFRAME_MASK 0x000000F0 /* Number of GMD packets per frame or video field (profile P0) */
|
||||
|
||||
/* Frame Composer GMD Packet Profile and Gamut Sequence Configuration Register This register configures the GMD packet header affected_gamut_seq_num and gmd_profile bits */
|
||||
#define FC_GMD_HB 0x00004410
|
||||
#define FC_GMD_HB_GMDAFFECTED_GAMUT_SEQ_NUM_MASK 0x0000000F /* Affected gamut sequence number */
|
||||
#define FC_GMD_HB_GMDGBD_PROFILE_MASK 0x00000070 /* GMD profile bits */
|
||||
|
||||
#define FC_GMD_PB0 0x4414
|
||||
#define FC_GMD_PB27 0x4480
|
||||
|
||||
/* Frame Composer AMP Packet Header Register 1 */
|
||||
#define FC_AMP_HB1 0x000044A0
|
||||
#define FC_AMP_HB1_FC_AMP_HB0_MASK 0x000000FF /* Frame Composer AMP Packet Header Register 1 */
|
||||
|
||||
/* Frame Composer AMP Packet Header Register 2 */
|
||||
#define FC_AMP_HB2 0x000044A4
|
||||
#define FC_AMP_HB2_FC_AMP_HB1_MASK 0x000000FF /* Frame Composer AMP Packet Header Register 2 */
|
||||
|
||||
#define FC_AMP_PB 0x000044A8
|
||||
|
||||
/* Frame Composer NTSC VBI Packet Header Register 1 */
|
||||
#define FC_NVBI_HB1 0x00004520
|
||||
#define FC_NVBI_HB1_FC_NVBI_HB0_MASK 0x000000FF /* Frame Composer NTSC VBI Packet Header Register 1 */
|
||||
|
||||
/* Frame Composer NTSC VBI Packet Header Register 2 */
|
||||
#define FC_NVBI_HB2 0x00004524
|
||||
#define FC_NVBI_HB2_FC_NVBI_HB1_MASK 0x000000FF /* Frame Composer NTSC VBI Packet Header Register 2 */
|
||||
|
||||
/* Frame Composer video/audio Force Enable Register This register allows to force the controller to output audio and video data the values configured in the FC_DBGAUD and FC_DBGTMDS registers */
|
||||
#define FC_DBGFORCE 0x00004800
|
||||
#define FC_DBGFORCE_FORCEVIDEO_MASK 0x00000001 /* Force fixed video output with FC_DBGTMDSx register contents */
|
||||
#define FC_DBGFORCE_FORCEAUDIO_MASK 0x00000010 /* Force fixed audio output with FC_DBGAUDxCHx register contents */
|
||||
|
||||
/* Frame Composer Audio Data Channel 0 Register 0 Configures the audio fixed data to be used in channel 0 when in fixed audio selection */
|
||||
#define FC_DBGAUD0CH0 0x00004804
|
||||
#define FC_DBGAUD0CH0_FC_DBGAUD0CH0_MASK 0x000000FF /* Frame Composer Audio Data Channel 0 Register 0 */
|
||||
|
||||
/* Frame Composer Audio Data Channel 0 Register 1 Configures the audio fixed data to be used in channel 0 when in fixed audio selection */
|
||||
#define FC_DBGAUD1CH0 0x00004808
|
||||
#define FC_DBGAUD1CH0_FC_DBGAUD1CH0_MASK 0x000000FF /* Frame Composer Audio Data Channel 0 Register 1 */
|
||||
|
||||
/* Frame Composer Audio Data Channel 0 Register 2 Configures the audio fixed data to be used in channel 0 when in fixed audio selection */
|
||||
#define FC_DBGAUD2CH0 0x0000480C
|
||||
#define FC_DBGAUD2CH0_FC_DBGAUD2CH0_MASK 0x000000FF /* Frame Composer Audio Data Channel 0 Register 2 */
|
||||
|
||||
/* Frame Composer Audio Data Channel 1 Register 0 Configures the audio fixed data to be used in channel 1 when in fixed audio selection */
|
||||
#define FC_DBGAUD0CH1 0x00004810
|
||||
#define FC_DBGAUD0CH1_FC_DBGAUD0CH1_MASK 0x000000FF /* Frame Composer Audio Data Channel 1 Register 0 */
|
||||
|
||||
/* Frame Composer Audio Data Channel 1 Register 1 Configures the audio fixed data to be used in channel 1 when in fixed audio selection */
|
||||
#define FC_DBGAUD1CH1 0x00004814
|
||||
#define FC_DBGAUD1CH1_FC_DBGAUD1CH1_MASK 0x000000FF /* Frame Composer Audio Data Channel 1 Register 1 */
|
||||
|
||||
/* Frame Composer Audio Data Channel 1 Register 2 Configures the audio fixed data to be used in channel 1 when in fixed audio selection */
|
||||
#define FC_DBGAUD2CH1 0x00004818
|
||||
#define FC_DBGAUD2CH1_FC_DBGAUD2CH1_MASK 0x000000FF /* Frame Composer Audio Data Channel 1 Register 2 */
|
||||
|
||||
/* Frame Composer Audio Data Channel 2 Register 0 Configures the audio fixed data to be used in channel 2 when in fixed audio selection */
|
||||
#define FC_DBGAUD0CH2 0x0000481C
|
||||
#define FC_DBGAUD0CH2_FC_DBGAUD0CH2_MASK 0x000000FF /* Frame Composer Audio Data Channel 2 Register 0 */
|
||||
|
||||
/* Frame Composer Audio Data Channel 2 Register 1 Configures the audio fixed data to be used in channel 2 when in fixed audio selection */
|
||||
#define FC_DBGAUD1CH2 0x00004820
|
||||
#define FC_DBGAUD1CH2_FC_DBGAUD1CH2_MASK 0x000000FF /* Frame Composer Audio Data Channel 2 Register 1 */
|
||||
|
||||
/* Frame Composer Audio Data Channel 2 Register 2 Configures the audio fixed data to be used in channel 2 when in fixed audio selection */
|
||||
#define FC_DBGAUD2CH2 0x00004824
|
||||
#define FC_DBGAUD2CH2_FC_DBGAUD2CH2_MASK 0x000000FF /* Frame Composer Audio Data Channel 2 Register 2 */
|
||||
|
||||
/* Frame Composer Audio Data Channel 3 Register 0 Configures the audio fixed data to be used in channel 3 when in fixed audio selection */
|
||||
#define FC_DBGAUD0CH3 0x00004828
|
||||
#define FC_DBGAUD0CH3_FC_DBGAUD0CH3_MASK 0x000000FF /* Frame Composer Audio Data Channel 3 Register 0 */
|
||||
|
||||
/* Frame Composer Audio Data Channel 3 Register 1 Configures the audio fixed data to be used in channel 3 when in fixed audio selection */
|
||||
#define FC_DBGAUD1CH3 0x0000482C
|
||||
#define FC_DBGAUD1CH3_FC_DBGAUD1CH3_MASK 0x000000FF /* Frame Composer Audio Data Channel 3 Register 1 */
|
||||
|
||||
/* Frame Composer Audio Data Channel 3 Register 2 Configures the audio fixed data to be used in channel 3 when in fixed audio selection */
|
||||
#define FC_DBGAUD2CH3 0x00004830
|
||||
#define FC_DBGAUD2CH3_FC_DBGAUD2CH3_MASK 0x000000FF /* Frame Composer Audio Data Channel 3 Register 2 */
|
||||
|
||||
/* Frame Composer Audio Data Channel 4 Register 0 Configures the audio fixed data to be used in channel 4 when in fixed audio selection */
|
||||
#define FC_DBGAUD0CH4 0x00004834
|
||||
#define FC_DBGAUD0CH4_FC_DBGAUD0CH4_MASK 0x000000FF /* Frame Composer Audio Data Channel 4 Register 0 */
|
||||
|
||||
/* Frame Composer Audio Data Channel 4 Register 1 Configures the audio fixed data to be used in channel 4 when in fixed audio selection */
|
||||
#define FC_DBGAUD1CH4 0x00004838
|
||||
#define FC_DBGAUD1CH4_FC_DBGAUD1CH4_MASK 0x000000FF /* Frame Composer Audio Data Channel 4 Register 1 */
|
||||
|
||||
/* Frame Composer Audio Data Channel 4 Register 2 Configures the audio fixed data to be used in channel 4 when in fixed audio selection */
|
||||
#define FC_DBGAUD2CH4 0x0000483C
|
||||
#define FC_DBGAUD2CH4_FC_DBGAUD2CH4_MASK 0x000000FF /* Frame Composer Audio Data Channel 4 Register 2 */
|
||||
|
||||
/* Frame Composer Audio Data Channel 5 Register 0 Configures the audio fixed data to be used in channel 5 when in fixed audio selection */
|
||||
#define FC_DBGAUD0CH5 0x00004840
|
||||
#define FC_DBGAUD0CH5_FC_DBGAUD0CH5_MASK 0x000000FF /* Frame Composer Audio Data Channel 5 Register 0 */
|
||||
|
||||
/* Frame Composer Audio Data Channel 5 Register 1 Configures the audio fixed data to be used in channel 5 when in fixed audio selection */
|
||||
#define FC_DBGAUD1CH5 0x00004844
|
||||
#define FC_DBGAUD1CH5_FC_DBGAUD1CH5_MASK 0x000000FF /* Frame Composer Audio Data Channel 5 Register 1 */
|
||||
|
||||
/* Frame Composer Audio Data Channel 5 Register 2 Configures the audio fixed data to be used in channel 5 when in fixed audio selection */
|
||||
#define FC_DBGAUD2CH5 0x00004848
|
||||
#define FC_DBGAUD2CH5_FC_DBGAUD2CH5_MASK 0x000000FF /* Frame Composer Audio Data Channel 5 Register 2 */
|
||||
|
||||
/* Frame Composer Audio Data Channel 6 Register 0 Configures the audio fixed data to be used in channel 6 when in fixed audio selection */
|
||||
#define FC_DBGAUD0CH6 0x0000484C
|
||||
#define FC_DBGAUD0CH6_FC_DBGAUD0CH6_MASK 0x000000FF /* Frame Composer Audio Data Channel 6 Register 0 */
|
||||
|
||||
/* Frame Composer Audio Data Channel 6 Register 1 Configures the audio fixed data to be used in channel 6 when in fixed audio selection */
|
||||
#define FC_DBGAUD1CH6 0x00004850
|
||||
#define FC_DBGAUD1CH6_FC_DBGAUD1CH6_MASK 0x000000FF /* Frame Composer Audio Data Channel 6 Register 1 */
|
||||
|
||||
/* Frame Composer Audio Data Channel 6 Register 2 Configures the audio fixed data to be used in channel 6 when in fixed audio selection */
|
||||
#define FC_DBGAUD2CH6 0x00004854
|
||||
#define FC_DBGAUD2CH6_FC_DBGAUD2CH6_MASK 0x000000FF /* Frame Composer Audio Data Channel 6 Register 2 */
|
||||
|
||||
/* Frame Composer Audio Data Channel 7 Register 0 Configures the audio fixed data to be used in channel 7 when in fixed audio selection */
|
||||
#define FC_DBGAUD0CH7 0x00004858
|
||||
#define FC_DBGAUD0CH7_FC_DBGAUD0CH7_MASK 0x000000FF /* Frame Composer Audio Data Channel 7 Register 0 */
|
||||
|
||||
/* Frame Composer Audio Data Channel 7 Register 1 Configures the audio fixed data to be used in channel 7 when in fixed audio selection */
|
||||
#define FC_DBGAUD1CH7 0x0000485C
|
||||
#define FC_DBGAUD1CH7_FC_DBGAUD1CH7_MASK 0x000000FF /* Frame Composer Audio Data Channel 7 Register 1 */
|
||||
|
||||
/* Frame Composer Audio Data Channel 7 Register 2 Configures the audio fixed data to be used in channel 7 when in fixed audio selection */
|
||||
#define FC_DBGAUD2CH7 0x00004860
|
||||
#define FC_DBGAUD2CH7_FC_DBGAUD2CH7_MASK 0x000000FF /* Frame Composer Audio Data Channel 7 Register 2 */
|
||||
|
||||
#define FC_DBGTMDS0 0x4864
|
||||
#define FC_DBGTMDS1 0x4868
|
||||
#define FC_DBGTMDS2 0x486C
|
||||
|
||||
/*Frame Composer DRM Packet*/
|
||||
#define FC_DRM_UP 0x459C
|
||||
#define FC_DRM_UP_DRMPACKETUPDATE_MASK 0x00000001
|
||||
|
||||
/*Frame Composer DRM Packet Header Rigister Array*/
|
||||
#define FC_DRM_HB0 0x45A0
|
||||
#define FC_DRM_HB1 0x45A4
|
||||
#define FC_DRM_UP_FC_DRM_HB_MASK 0x000000FF
|
||||
|
||||
#define FC_DRM_PB0 0x45A8
|
||||
#define FC_DRM_PB1 0x45AC
|
||||
#define FC_DRM_PB2 0x45B0
|
||||
#define FC_DRM_PB3 0x45B4
|
||||
#define FC_DRM_PB4 0x45B8
|
||||
#define FC_DRM_PB5 0x45BC
|
||||
#define FC_DRM_PB6 0x45C0
|
||||
#define FC_DRM_PB7 0x45C4
|
||||
#define FC_DRM_PB8 0x45C8
|
||||
#define FC_DRM_PB9 0x45CC
|
||||
#define FC_DRM_PB10 0x45D0
|
||||
#define FC_DRM_PB11 0x45D4
|
||||
#define FC_DRM_PB12 0x45D8
|
||||
#define FC_DRM_PB13 0x45DC
|
||||
#define FC_DRM_PB14 0x45E0
|
||||
#define FC_DRM_PB15 0x45E4
|
||||
#define FC_DRM_PB16 0x45E8
|
||||
#define FC_DRM_PB17 0x45EC
|
||||
#define FC_DRM_PB18 0x45F0
|
||||
#define FC_DRM_PB19 0x45F4
|
||||
#define FC_DRM_PB20 0x45F8
|
||||
#define FC_DRM_PB21 0x45FC
|
||||
#define FC_DRM_PB22 0x4600
|
||||
#define FC_DRM_PB23 0x4604
|
||||
#define FC_DRM_PB24 0x4608
|
||||
#define FC_DRM_PB25 0x460C
|
||||
#define FC_DRM_PB26 0x4610
|
||||
|
||||
#endif /* SRC_CORE_FRAME_COMPOSER_FRAME_COMPOSER_REG_H_ */
|
||||
536
sunxi_spl/display/hdmi/hdmi.c
Executable file
536
sunxi_spl/display/hdmi/hdmi.c
Executable file
@@ -0,0 +1,536 @@
|
||||
#include "common.h"
|
||||
|
||||
#include "hdmi.h"
|
||||
#include "phy.h"
|
||||
#include "video.h"
|
||||
#include "access.h"
|
||||
#include "tcon.h"
|
||||
#include "packets.h"
|
||||
#include "irq.h"
|
||||
#include "scdc.h"
|
||||
#include "main_controller.h"
|
||||
#include "fc_video.h"
|
||||
#include "hdmitx_dev.h"
|
||||
#include "audio.h"
|
||||
|
||||
|
||||
#define HDMI_CTRL_REG_BASE 0x06000000
|
||||
|
||||
|
||||
enum HDMI_VIC {
|
||||
HDMI_VIC_640x480P60 = 1,
|
||||
HDMI_VIC_720x480P60_4_3,
|
||||
HDMI_VIC_720x480P60_16_9,
|
||||
HDMI_VIC_1280x720P60,
|
||||
HDMI_VIC_1920x1080I60,
|
||||
HDMI_VIC_720x480I_4_3,
|
||||
HDMI_VIC_720x480I_16_9,
|
||||
HDMI_VIC_720x240P_4_3,
|
||||
HDMI_VIC_720x240P_16_9,
|
||||
HDMI_VIC_1920x1080P60 = 16,
|
||||
HDMI_VIC_720x576P_4_3,
|
||||
HDMI_VIC_720x576P_16_9,
|
||||
HDMI_VIC_1280x720P50,
|
||||
HDMI_VIC_1920x1080I50,
|
||||
HDMI_VIC_720x576I_4_3,
|
||||
HDMI_VIC_720x576I_16_9,
|
||||
HDMI_VIC_1920x1080P50 = 31,
|
||||
HDMI_VIC_1920x1080P24,
|
||||
HDMI_VIC_1920x1080P25,
|
||||
HDMI_VIC_1920x1080P30,
|
||||
HDMI_VIC_1280x720P24 = 60,
|
||||
HDMI_VIC_1280x720P25,
|
||||
HDMI_VIC_1280x720P30,
|
||||
HDMI_VIC_3840x2160P24 = 93,
|
||||
HDMI_VIC_3840x2160P25,
|
||||
HDMI_VIC_3840x2160P30,
|
||||
HDMI_VIC_3840x2160P50,
|
||||
HDMI_VIC_3840x2160P60,
|
||||
HDMI_VIC_4096x2160P24,
|
||||
HDMI_VIC_4096x2160P25,
|
||||
HDMI_VIC_4096x2160P30,
|
||||
HDMI_VIC_4096x2160P50,
|
||||
HDMI_VIC_4096x2160P60,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
SDR_LUMINANCE_RANGE = 0,
|
||||
HDR_LUMINANCE_RANGE,
|
||||
SMPTE_ST_2084,
|
||||
HLG
|
||||
} eotf_t;
|
||||
|
||||
struct disp_hdmi_mode {
|
||||
enum disp_tv_mode mode;
|
||||
int hdmi_mode;/* vic */
|
||||
};
|
||||
|
||||
static struct disp_hdmi_mode hdmi_mode_tbl[] = {
|
||||
{DISP_TV_MOD_480I, HDMI_VIC_720x480I_16_9, },
|
||||
{DISP_TV_MOD_576I, HDMI_VIC_720x576I_16_9, },
|
||||
{DISP_TV_MOD_480P, HDMI_VIC_720x480P60_16_9, },
|
||||
{DISP_TV_MOD_576P, HDMI_VIC_720x576P_16_9, },
|
||||
{DISP_TV_MOD_720P_50HZ, HDMI_VIC_1280x720P50, },
|
||||
{DISP_TV_MOD_720P_60HZ, HDMI_VIC_1280x720P60, },
|
||||
{DISP_TV_MOD_1080I_50HZ, HDMI_VIC_1920x1080I50, },
|
||||
{DISP_TV_MOD_1080I_60HZ, HDMI_VIC_1920x1080I60, },
|
||||
{DISP_TV_MOD_1080P_24HZ, HDMI_VIC_1920x1080P24, },
|
||||
{DISP_TV_MOD_1080P_50HZ, HDMI_VIC_1920x1080P50, },
|
||||
{DISP_TV_MOD_1080P_60HZ, HDMI_VIC_1920x1080P60, },
|
||||
{DISP_TV_MOD_1080P_25HZ, HDMI_VIC_1920x1080P25, },
|
||||
{DISP_TV_MOD_1080P_30HZ, HDMI_VIC_1920x1080P30, },
|
||||
//{DISP_TV_MOD_1080P_24HZ_3D_FP, HDMI1080P_24_3D_FP,},
|
||||
//{DISP_TV_MOD_720P_50HZ_3D_FP, HDMI720P_50_3D_FP, },
|
||||
//{DISP_TV_MOD_720P_60HZ_3D_FP, HDMI720P_60_3D_FP, },
|
||||
{DISP_TV_MOD_3840_2160P_30HZ, HDMI_VIC_3840x2160P30, },
|
||||
{DISP_TV_MOD_3840_2160P_25HZ, HDMI_VIC_3840x2160P25, },
|
||||
{DISP_TV_MOD_3840_2160P_24HZ, HDMI_VIC_3840x2160P24, },
|
||||
{DISP_TV_MOD_4096_2160P_24HZ, HDMI_VIC_4096x2160P24, },
|
||||
{DISP_TV_MOD_4096_2160P_25HZ, HDMI_VIC_4096x2160P25, },
|
||||
{DISP_TV_MOD_4096_2160P_30HZ, HDMI_VIC_4096x2160P30, },
|
||||
|
||||
{DISP_TV_MOD_3840_2160P_50HZ, HDMI_VIC_3840x2160P50,},
|
||||
{DISP_TV_MOD_4096_2160P_50HZ, HDMI_VIC_4096x2160P50,},
|
||||
|
||||
{DISP_TV_MOD_3840_2160P_60HZ, HDMI_VIC_3840x2160P60, },
|
||||
{DISP_TV_MOD_4096_2160P_60HZ, HDMI_VIC_4096x2160P60, },
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct hdmi_ctrl {
|
||||
videoParams_t video_params;
|
||||
audioParams_t audio_params;
|
||||
productParams_t product_params;
|
||||
hdmi_tx_dev_t hdmi_tx_dev;
|
||||
struct device_access dev_access;
|
||||
struct system_functions sys_functions;
|
||||
} hdmi_ctrl_t;
|
||||
|
||||
static hdmi_ctrl_t sHdmiCtr;
|
||||
|
||||
|
||||
/*
|
||||
static int videoParams_GetHdmiVicCode(int cea_code)
|
||||
{
|
||||
switch (cea_code) {
|
||||
case 95:
|
||||
return 1;
|
||||
break;
|
||||
case 94:
|
||||
return 2;
|
||||
break;
|
||||
case 93:
|
||||
return 3;
|
||||
break;
|
||||
case 98:
|
||||
return 4;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
*@code: svd <1-107, 0x80+4, 0x80+19, 0x80+32>
|
||||
*@refresh_rate: [optional] Hz*1000,which is 1000 times than 1 Hz
|
||||
*/
|
||||
static u32 svd_user_config(u32 code, u32 refresh_rate)
|
||||
{
|
||||
dtd_t *p_dtd;
|
||||
//dtd_t dtd;
|
||||
int hdmi_vic = 0;
|
||||
|
||||
/*memset(&core->mode.pVideo, 0, sizeof(videoParams_t));*/
|
||||
|
||||
if (code < 1 || code > 256) {
|
||||
printf("ERROR:VIC Code is out of range\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
p_dtd = get_dtd(code,refresh_rate);
|
||||
if (p_dtd == NULL) {
|
||||
HDMI_INFO_MSG("Can not find detailed timing\n");
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
p_dtd->mLimitedToYcc420 = false;
|
||||
p_dtd->mYcc420 = false;
|
||||
|
||||
memcpy(&sHdmiCtr.video_params.mDtd, p_dtd, sizeof(dtd_t));
|
||||
|
||||
hdmi_vic = videoParams_GetHdmiVicCode(sHdmiCtr.video_params.mDtd.mCode);
|
||||
if (hdmi_vic > 0) {
|
||||
sHdmiCtr.product_params.mOUI = 0x000c03;
|
||||
sHdmiCtr.product_params.mVendorPayload[0] = 0x20;
|
||||
sHdmiCtr.product_params.mVendorPayload[1] = hdmi_vic;
|
||||
sHdmiCtr.product_params.mVendorPayloadLength = 2;
|
||||
|
||||
sHdmiCtr.video_params.mDtd.mCode = 0;
|
||||
sHdmiCtr.video_params.mCea_code = 0;
|
||||
sHdmiCtr.video_params.mHdmi_code = hdmi_vic;
|
||||
} else {
|
||||
sHdmiCtr.product_params.mOUI = 0x000c03;
|
||||
sHdmiCtr.product_params.mVendorPayload[0] = 0x0;
|
||||
sHdmiCtr.product_params.mVendorPayload[1] = 0;
|
||||
sHdmiCtr.product_params.mVendorPayloadLength = 2;
|
||||
|
||||
sHdmiCtr.video_params.mCea_code = sHdmiCtr.video_params.mDtd.mCode;
|
||||
sHdmiCtr.video_params.mHdmi_code = 0;
|
||||
}
|
||||
|
||||
if (sHdmiCtr.video_params.mHdmi_code) {
|
||||
sHdmiCtr.video_params.mHdmiVideoFormat = 0x01;
|
||||
sHdmiCtr.video_params.m3dStructure = 0;
|
||||
} else {
|
||||
sHdmiCtr.video_params.mHdmiVideoFormat = 0x0;
|
||||
sHdmiCtr.video_params.m3dStructure = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static s32 hdmi_set_display_mode(u32 mode)
|
||||
{
|
||||
u32 hdmi_mode;
|
||||
u32 i;
|
||||
bool find = false;
|
||||
|
||||
for (i = 0; i < sizeof(hdmi_mode_tbl)/sizeof(struct disp_hdmi_mode); i++) {
|
||||
if (hdmi_mode_tbl[i].mode == (enum disp_tv_mode)mode) {
|
||||
hdmi_mode = hdmi_mode_tbl[i].hdmi_mode;
|
||||
find = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (find) {
|
||||
/*user configure detailed timing according to vic*/
|
||||
if (svd_user_config(hdmi_mode, 0) != 0) {
|
||||
HDMI_ERROR_MSG("svd user config failed!\n");
|
||||
return -1;
|
||||
} else {
|
||||
HDMI_INFO_MSG("Set hdmi mode: %d\n", hdmi_mode);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
HDMI_ERROR_MSG("unsupported video mode %d when set display mode\n", mode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
s32 hdmi_set_static_config(struct disp_device_config *config)
|
||||
{
|
||||
u32 data_bit = 0;
|
||||
|
||||
videoParams_t *pVideo = &sHdmiCtr.video_params;
|
||||
|
||||
//pVideo->update = hdmi_check_updated(core, config);
|
||||
|
||||
memset(pVideo, 0, sizeof(videoParams_t));
|
||||
/*set vic mode and dtd*/
|
||||
hdmi_set_display_mode(config->mode);
|
||||
|
||||
/*set encoding mode*/
|
||||
pVideo->mEncodingIn = config->format;
|
||||
pVideo->mEncodingOut = config->format;
|
||||
|
||||
/*set data bits*/
|
||||
if ((config->bits >= 0) && (config->bits < 3))
|
||||
data_bit = 8 + 2 * config->bits;
|
||||
if (config->bits == 3)
|
||||
data_bit = 16;
|
||||
pVideo->mColorResolution = (u8)data_bit;
|
||||
|
||||
/*set eotf*/
|
||||
if (config->eotf) {
|
||||
|
||||
//if (pVideo->pb) {
|
||||
pVideo->pb.r_x = 0x33c2;
|
||||
pVideo->pb.r_y = 0x86c4;
|
||||
pVideo->pb.g_x = 0x1d4c;
|
||||
pVideo->pb.g_y = 0x0bb8;
|
||||
pVideo->pb.b_x = 0x84d0;
|
||||
pVideo->pb.b_y = 0x3e80;
|
||||
pVideo->pb.w_x = 0x3d13;
|
||||
pVideo->pb.w_y = 0x4042;
|
||||
pVideo->pb.luma_max = 0x03e8;
|
||||
pVideo->pb.luma_min = 0x1;
|
||||
pVideo->pb.mcll = 0x03e8;
|
||||
pVideo->pb.mfll = 0x0190;
|
||||
//}
|
||||
|
||||
|
||||
switch (config->eotf) {
|
||||
case DISP_EOTF_GAMMA22:
|
||||
pVideo->mHdr = 0;
|
||||
pVideo->pb.eotf = SDR_LUMINANCE_RANGE;
|
||||
break;
|
||||
case DISP_EOTF_SMPTE2084:
|
||||
pVideo->mHdr = 1;
|
||||
pVideo->pb.eotf = SMPTE_ST_2084;
|
||||
break;
|
||||
case DISP_EOTF_ARIB_STD_B67:
|
||||
pVideo->mHdr = 1;
|
||||
pVideo->pb.eotf = HLG;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (config->mode < 4)
|
||||
pVideo->mColorimetry = ITU601;
|
||||
else
|
||||
pVideo->mColorimetry = ITU709;
|
||||
|
||||
}
|
||||
|
||||
/*set color space*/
|
||||
switch (config->cs) {
|
||||
case DISP_UNDEF:
|
||||
pVideo->mColorimetry = 0;
|
||||
break;
|
||||
case DISP_BT601:
|
||||
pVideo->mColorimetry = ITU601;
|
||||
break;
|
||||
case DISP_BT709:
|
||||
pVideo->mColorimetry = ITU709;
|
||||
break;
|
||||
case DISP_BT2020NC:
|
||||
pVideo->mColorimetry = EXTENDED_COLORIMETRY;
|
||||
pVideo->mExtColorimetry = BT2020_Y_CB_CR;
|
||||
break;
|
||||
default:
|
||||
pVideo->mColorimetry = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
pVideo->mHdmi = HDMI;
|
||||
|
||||
//memcpy(&core->config, config, sizeof(struct disp_device_config));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
s32 hdmi_get_video_timming_info(struct disp_video_timings *video_info)
|
||||
{
|
||||
dtd_t *dtd = NULL;
|
||||
|
||||
|
||||
dtd = &sHdmiCtr.video_params.mDtd;
|
||||
video_info->vic = dtd->mCode;
|
||||
video_info->tv_mode = 0;
|
||||
|
||||
video_info->pixel_clk = (dtd->mPixelClock) * 1000 / (dtd->mPixelRepetitionInput+1);
|
||||
if ((video_info->vic == 6) || (video_info->vic == 7) || (video_info->vic == 21) || (video_info->vic == 22))
|
||||
video_info->pixel_clk = (dtd->mPixelClock) * 1000 / (dtd->mPixelRepetitionInput + 1) / (dtd->mInterlaced + 1);
|
||||
video_info->pixel_repeat = dtd->mPixelRepetitionInput;
|
||||
video_info->x_res = (dtd->mHActive) / (dtd->mPixelRepetitionInput+1);
|
||||
if (dtd->mInterlaced == 1)
|
||||
video_info->y_res = (dtd->mVActive) * 2;
|
||||
else if (dtd->mInterlaced == 0)
|
||||
video_info->y_res = dtd->mVActive;
|
||||
|
||||
video_info->hor_total_time = (dtd->mHActive + dtd->mHBlanking) / (dtd->mPixelRepetitionInput+1);
|
||||
video_info->hor_back_porch = (dtd->mHBlanking - dtd->mHSyncOffset - dtd->mHSyncPulseWidth) / (dtd->mPixelRepetitionInput+1);
|
||||
video_info->hor_front_porch = (dtd->mHSyncOffset) / (dtd->mPixelRepetitionInput+1);
|
||||
video_info->hor_sync_time = (dtd->mHSyncPulseWidth) / (dtd->mPixelRepetitionInput+1);
|
||||
|
||||
if (dtd->mInterlaced == 1)
|
||||
video_info->ver_total_time = (dtd->mVActive + dtd->mVBlanking) * 2 + 1;
|
||||
else if (dtd->mInterlaced == 0)
|
||||
video_info->ver_total_time = dtd->mVActive + dtd->mVBlanking;
|
||||
video_info->ver_back_porch = dtd->mVBlanking - dtd->mVSyncOffset - dtd->mVSyncPulseWidth;
|
||||
video_info->ver_front_porch = dtd->mVSyncOffset;
|
||||
video_info->ver_sync_time = dtd->mVSyncPulseWidth;
|
||||
|
||||
video_info->hor_sync_polarity = dtd->mHSyncPolarity;
|
||||
video_info->ver_sync_polarity = dtd->mVSyncPolarity;
|
||||
video_info->b_interlace = dtd->mInterlaced;
|
||||
video_info->vactive_space = 0;
|
||||
video_info->trd_mode = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define A_HDCPCFG0 0x00014000
|
||||
#define A_HDCPCFG0_AVMUTE_MASK 0x00000008 /* This register holds the current AVMUTE state of the DWC_hdmi_tx controller, as expected to be perceived by the connected HDMI/HDCP sink device */
|
||||
|
||||
static void _EnableAvmute(hdmi_tx_dev_t *dev, u8 bit)
|
||||
{
|
||||
//LOG_TRACE1(bit);
|
||||
dev_write_mask(dev, A_HDCPCFG0, A_HDCPCFG0_AVMUTE_MASK, bit);
|
||||
}
|
||||
|
||||
|
||||
static void hdcp_av_mute(hdmi_tx_dev_t *dev, int enable)
|
||||
{
|
||||
//LOG_TRACE1(enable);
|
||||
_EnableAvmute(dev,
|
||||
(enable == true) ? 1 : 0);
|
||||
}
|
||||
|
||||
static void api_avmute(hdmi_tx_dev_t *dev, int enable)
|
||||
{
|
||||
packets_AvMute(dev, enable);
|
||||
hdcp_av_mute(dev, enable);
|
||||
}
|
||||
|
||||
int hdmi_configure(u16 phy_model)
|
||||
{
|
||||
int success = true;
|
||||
unsigned int tmds_clk = 0;
|
||||
videoParams_t *video = &sHdmiCtr.video_params;
|
||||
//audioParams_t *audio = &sHdmiCtr.audio_params;
|
||||
productParams_t *product = &sHdmiCtr.product_params;
|
||||
|
||||
sHdmiCtr.hdmi_tx_dev.snps_hdmi_ctrl.hdmi_on = (video->mHdmi == HDMI) ? 1 : 0;
|
||||
//hdmiTxDev.audio_on = (video->mHdmi == HDMI) ? 1 : 0;
|
||||
sHdmiCtr.hdmi_tx_dev.snps_hdmi_ctrl.pixel_clock = videoParams_GetPixelClock(&sHdmiCtr.hdmi_tx_dev, video);
|
||||
sHdmiCtr.hdmi_tx_dev.snps_hdmi_ctrl.color_resolution = video->mColorResolution;
|
||||
sHdmiCtr.hdmi_tx_dev.snps_hdmi_ctrl.pixel_repetition = video->mDtd.mPixelRepetitionInput;
|
||||
|
||||
/*be used to calculate tmds clk*/
|
||||
HDMI_INFO_MSG("video pixel clock=%d\n", sHdmiCtr.hdmi_tx_dev.snps_hdmi_ctrl.pixel_clock);
|
||||
|
||||
/*for auto scrambling if tmds_clk > 3.4Gbps*/
|
||||
switch (video->mColorResolution) {
|
||||
case COLOR_DEPTH_8:
|
||||
tmds_clk = sHdmiCtr.hdmi_tx_dev.snps_hdmi_ctrl.pixel_clock;
|
||||
break;
|
||||
case COLOR_DEPTH_10:
|
||||
if (video->mEncodingOut != YCC422)
|
||||
tmds_clk = sHdmiCtr.hdmi_tx_dev.snps_hdmi_ctrl.pixel_clock * 125 / 100;
|
||||
else
|
||||
tmds_clk = sHdmiCtr.hdmi_tx_dev.snps_hdmi_ctrl.pixel_clock;
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
sHdmiCtr.hdmi_tx_dev.snps_hdmi_ctrl.tmds_clk = tmds_clk;
|
||||
|
||||
if (video->mEncodingIn == YCC420) {
|
||||
sHdmiCtr.hdmi_tx_dev.snps_hdmi_ctrl.pixel_clock = sHdmiCtr.hdmi_tx_dev.snps_hdmi_ctrl.pixel_clock / 2;
|
||||
sHdmiCtr.hdmi_tx_dev.snps_hdmi_ctrl.tmds_clk /= 2;
|
||||
}
|
||||
if (video->mEncodingIn == YCC422)
|
||||
sHdmiCtr.hdmi_tx_dev.snps_hdmi_ctrl.color_resolution = 8;
|
||||
|
||||
api_avmute(&sHdmiCtr.hdmi_tx_dev, true);
|
||||
|
||||
phy_standby(&sHdmiCtr.hdmi_tx_dev);
|
||||
|
||||
/* Disable interrupts */
|
||||
irq_mute(&sHdmiCtr.hdmi_tx_dev);
|
||||
|
||||
success = video_Configure(&sHdmiCtr.hdmi_tx_dev, video);
|
||||
if (success == false)
|
||||
HDMI_INFO_MSG("Could not configure video\n");
|
||||
|
||||
#if 0
|
||||
/* Audio - Workaround */
|
||||
audio_Initialize(&sHdmiCtr.hdmi_tx_dev);
|
||||
success = audio_Configure(&sHdmiCtr.hdmi_tx_dev, audio);
|
||||
if (success == false)
|
||||
HDMI_INFO_MSG("ERROR:Audio not configured\n");
|
||||
#endif
|
||||
|
||||
/* Packets */
|
||||
success = packets_Configure(&sHdmiCtr.hdmi_tx_dev, video, product);
|
||||
if (success == false)
|
||||
HDMI_INFO_MSG("ERROR:Could not configure packets\n");
|
||||
|
||||
mc_enable_all_clocks(&sHdmiCtr.hdmi_tx_dev);
|
||||
snps_sleep(10000);
|
||||
|
||||
if (sHdmiCtr.hdmi_tx_dev.snps_hdmi_ctrl.tmds_clk > 340000) {
|
||||
scrambling(&sHdmiCtr.hdmi_tx_dev, 1);
|
||||
HDMI_INFO_MSG("enable scrambling\n");
|
||||
}
|
||||
|
||||
|
||||
/*add calibrated resistor configuration for all video resolution*/
|
||||
dev_write(&sHdmiCtr.hdmi_tx_dev, 0x40018, 0xc0);
|
||||
dev_write(&sHdmiCtr.hdmi_tx_dev, 0x4001c, 0x80);
|
||||
|
||||
success = phy_configure(&sHdmiCtr.hdmi_tx_dev, 301);
|
||||
if (success == false)
|
||||
HDMI_INFO_MSG("ERROR:Could not configure PHY\n");
|
||||
|
||||
/* Disable blue screen transmission
|
||||
after turning on all necessary blocks (e.g. HDCP) */
|
||||
fc_force_output(&sHdmiCtr.hdmi_tx_dev, false);
|
||||
|
||||
|
||||
irq_mask_all(&sHdmiCtr.hdmi_tx_dev);
|
||||
/* enable interrupts */
|
||||
irq_unmute(&sHdmiCtr.hdmi_tx_dev);
|
||||
|
||||
snps_sleep(100000);
|
||||
api_avmute(&sHdmiCtr.hdmi_tx_dev, false);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static void hdmitx_write(u32 addr, u32 data)
|
||||
{
|
||||
//asm volatile("dsb st");
|
||||
*((volatile u8 *)(HDMI_CTRL_REG_BASE + (addr >> 2))) = data;
|
||||
}
|
||||
|
||||
static u32 hdmitx_read(u32 addr)
|
||||
{
|
||||
return *((volatile u8 *)(HDMI_CTRL_REG_BASE + (addr >> 2)));
|
||||
}
|
||||
|
||||
static void hdmitx_sleep(int us)
|
||||
{
|
||||
//udelay(us);
|
||||
}
|
||||
|
||||
u8 hdmi_hpd_status_get(void)
|
||||
{
|
||||
return phy_hot_plug_state(&sHdmiCtr.hdmi_tx_dev);
|
||||
|
||||
}
|
||||
|
||||
void hdmi_init (void)
|
||||
{
|
||||
memset(&sHdmiCtr, 0, sizeof(hdmi_ctrl_t));
|
||||
sHdmiCtr.hdmi_tx_dev.snps_hdmi_ctrl.csc_on = 1;
|
||||
sHdmiCtr.hdmi_tx_dev.snps_hdmi_ctrl.audio_on = 1;
|
||||
sHdmiCtr.hdmi_tx_dev.snps_hdmi_ctrl.data_enable_polarity = 1;
|
||||
|
||||
sHdmiCtr.dev_access.read = hdmitx_read;
|
||||
sHdmiCtr.dev_access.write = hdmitx_write;
|
||||
|
||||
sHdmiCtr.sys_functions.sleep = hdmitx_sleep;
|
||||
/*
|
||||
audioParams_t *audio = &sHdmiCtr.audio_params;
|
||||
|
||||
memset(audio, 0, sizeof(audioParams_t));
|
||||
audio->mInterfaceType = I2S;
|
||||
audio->mCodingType = PCM;
|
||||
audio->mSamplingFrequency = 44100;
|
||||
audio->mChannelAllocation = 0;
|
||||
audio->mChannelNum = 2;
|
||||
audio->mSampleSize = 16;
|
||||
audio->mClockFsFactor = 64;
|
||||
audio->mPacketType = PACKET_NOT_DEFINED;
|
||||
audio->mDmaBeatIncrement = DMA_NOT_DEFINED;
|
||||
*/
|
||||
register_system_functions(&sHdmiCtr.sys_functions);
|
||||
register_bsp_functions(&sHdmiCtr.dev_access);
|
||||
irq_hpd_sense_enable(&sHdmiCtr.hdmi_tx_dev, 1);
|
||||
}
|
||||
147
sunxi_spl/display/hdmi/hdmi.h
Executable file
147
sunxi_spl/display/hdmi/hdmi.h
Executable file
@@ -0,0 +1,147 @@
|
||||
#ifndef _HDMI_H_
|
||||
#define _HDMI_H_
|
||||
#include "tcon.h"
|
||||
typedef enum
|
||||
{
|
||||
DISP_OUTPUT_TYPE_NONE = 0,
|
||||
DISP_OUTPUT_TYPE_LCD = 1,
|
||||
DISP_OUTPUT_TYPE_TV = 2,
|
||||
DISP_OUTPUT_TYPE_HDMI = 4,
|
||||
DISP_OUTPUT_TYPE_VGA = 8,
|
||||
}disp_output_type;
|
||||
|
||||
enum disp_csc_type
|
||||
{
|
||||
DISP_CSC_TYPE_RGB = 0,
|
||||
DISP_CSC_TYPE_YUV444 = 1,
|
||||
DISP_CSC_TYPE_YUV422 = 2,
|
||||
DISP_CSC_TYPE_YUV420 = 3,
|
||||
};
|
||||
|
||||
enum disp_data_bits {
|
||||
DISP_DATA_8BITS = 0,
|
||||
DISP_DATA_10BITS = 1,
|
||||
DISP_DATA_12BITS = 2,
|
||||
DISP_DATA_16BITS = 3,
|
||||
};
|
||||
|
||||
enum disp_eotf {
|
||||
DISP_EOTF_RESERVED = 0x000,
|
||||
DISP_EOTF_BT709 = 0x001,
|
||||
DISP_EOTF_UNDEF = 0x002,
|
||||
DISP_EOTF_GAMMA22 = 0x004, /* SDR */
|
||||
DISP_EOTF_GAMMA28 = 0x005,
|
||||
DISP_EOTF_BT601 = 0x006,
|
||||
DISP_EOTF_SMPTE240M = 0x007,
|
||||
DISP_EOTF_LINEAR = 0x008,
|
||||
DISP_EOTF_LOG100 = 0x009,
|
||||
DISP_EOTF_LOG100S10 = 0x00a,
|
||||
DISP_EOTF_IEC61966_2_4 = 0x00b,
|
||||
DISP_EOTF_BT1361 = 0x00c,
|
||||
DISP_EOTF_IEC61966_2_1 = 0X00d,
|
||||
DISP_EOTF_BT2020_0 = 0x00e,
|
||||
DISP_EOTF_BT2020_1 = 0x00f,
|
||||
DISP_EOTF_SMPTE2084 = 0x010, /* HDR10 */
|
||||
DISP_EOTF_SMPTE428_1 = 0x011,
|
||||
DISP_EOTF_ARIB_STD_B67 = 0x012, /* HLG */
|
||||
};
|
||||
|
||||
enum disp_color_space
|
||||
{
|
||||
DISP_UNDEF = 0x00,
|
||||
DISP_UNDEF_F = 0x01,
|
||||
DISP_GBR = 0x100,
|
||||
DISP_BT709 = 0x101,
|
||||
DISP_FCC = 0x102,
|
||||
DISP_BT470BG = 0x103,
|
||||
DISP_BT601 = 0x104,
|
||||
DISP_SMPTE240M = 0x105,
|
||||
DISP_YCGCO = 0x106,
|
||||
DISP_BT2020NC = 0x107,
|
||||
DISP_BT2020C = 0x108,
|
||||
DISP_GBR_F = 0x200,
|
||||
DISP_BT709_F = 0x201,
|
||||
DISP_FCC_F = 0x202,
|
||||
DISP_BT470BG_F = 0x203,
|
||||
DISP_BT601_F = 0x204,
|
||||
DISP_SMPTE240M_F = 0x205,
|
||||
DISP_YCGCO_F = 0x206,
|
||||
DISP_BT2020NC_F = 0x207,
|
||||
DISP_BT2020C_F = 0x208,
|
||||
DISP_RESERVED = 0x300,
|
||||
DISP_RESERVED_F = 0x301,
|
||||
};
|
||||
|
||||
enum disp_tv_mode
|
||||
{
|
||||
DISP_TV_MOD_480I = 0,
|
||||
DISP_TV_MOD_576I = 1,
|
||||
DISP_TV_MOD_480P = 2,
|
||||
DISP_TV_MOD_576P = 3,
|
||||
DISP_TV_MOD_720P_50HZ = 4,
|
||||
DISP_TV_MOD_720P_60HZ = 5,
|
||||
DISP_TV_MOD_1080I_50HZ = 6,
|
||||
DISP_TV_MOD_1080I_60HZ = 7,
|
||||
DISP_TV_MOD_1080P_24HZ = 8,
|
||||
DISP_TV_MOD_1080P_50HZ = 9,
|
||||
DISP_TV_MOD_1080P_60HZ = 0xa,
|
||||
DISP_TV_MOD_1080P_24HZ_3D_FP = 0x17,
|
||||
DISP_TV_MOD_720P_50HZ_3D_FP = 0x18,
|
||||
DISP_TV_MOD_720P_60HZ_3D_FP = 0x19,
|
||||
DISP_TV_MOD_1080P_25HZ = 0x1a,
|
||||
DISP_TV_MOD_1080P_30HZ = 0x1b,
|
||||
DISP_TV_MOD_PAL = 0xb,
|
||||
DISP_TV_MOD_PAL_SVIDEO = 0xc,
|
||||
DISP_TV_MOD_NTSC = 0xe,
|
||||
DISP_TV_MOD_NTSC_SVIDEO = 0xf,
|
||||
DISP_TV_MOD_PAL_M = 0x11,
|
||||
DISP_TV_MOD_PAL_M_SVIDEO = 0x12,
|
||||
DISP_TV_MOD_PAL_NC = 0x14,
|
||||
DISP_TV_MOD_PAL_NC_SVIDEO = 0x15,
|
||||
DISP_TV_MOD_3840_2160P_30HZ = 0x1c,
|
||||
DISP_TV_MOD_3840_2160P_25HZ = 0x1d,
|
||||
DISP_TV_MOD_3840_2160P_24HZ = 0x1e,
|
||||
DISP_TV_MOD_4096_2160P_24HZ = 0x1f,
|
||||
DISP_TV_MOD_4096_2160P_25HZ = 0x20,
|
||||
DISP_TV_MOD_4096_2160P_30HZ = 0x21,
|
||||
DISP_TV_MOD_3840_2160P_60HZ = 0x22,
|
||||
DISP_TV_MOD_4096_2160P_60HZ = 0x23,
|
||||
DISP_TV_MOD_3840_2160P_50HZ = 0x24,
|
||||
DISP_TV_MOD_4096_2160P_50HZ = 0x25,
|
||||
/*
|
||||
* vga
|
||||
* NOTE:macro'value of new solution must between
|
||||
* DISP_VGA_MOD_640_480P_60 and DISP_VGA_MOD_MAX_NUM
|
||||
* or you have to modify is_vag_mode function in drv_tv.h
|
||||
*/
|
||||
DISP_VGA_MOD_640_480P_60 = 0x50,
|
||||
DISP_VGA_MOD_800_600P_60 = 0x51,
|
||||
DISP_VGA_MOD_1024_768P_60 = 0x52,
|
||||
DISP_VGA_MOD_1280_768P_60 = 0x53,
|
||||
DISP_VGA_MOD_1280_800P_60 = 0x54,
|
||||
DISP_VGA_MOD_1366_768P_60 = 0x55,
|
||||
DISP_VGA_MOD_1440_900P_60 = 0x56,
|
||||
DISP_VGA_MOD_1920_1080P_60 = 0x57,
|
||||
DISP_VGA_MOD_1280_720P_60 = 0x58,
|
||||
DISP_VGA_MOD_1920_1200P_60 = 0x5a,
|
||||
DISP_VGA_MOD_MAX_NUM = 0x5b,
|
||||
DISP_TV_MODE_NUM = 0x5c,
|
||||
};
|
||||
|
||||
|
||||
struct disp_device_config {
|
||||
disp_output_type type;
|
||||
enum disp_tv_mode mode;
|
||||
enum disp_csc_type format;
|
||||
enum disp_data_bits bits;
|
||||
enum disp_eotf eotf;
|
||||
enum disp_color_space cs;
|
||||
};
|
||||
|
||||
s32 hdmi_get_video_timming_info(struct disp_video_timings *video_info);
|
||||
s32 hdmi_set_static_config(struct disp_device_config *config);
|
||||
void hdmi_init (void);
|
||||
int hdmi_configure(u16 phy_model);
|
||||
u8 hdmi_hpd_status_get(void);
|
||||
|
||||
#endif
|
||||
76
sunxi_spl/display/hdmi/hdmitx_dev.h
Executable file
76
sunxi_spl/display/hdmi/hdmitx_dev.h
Executable file
@@ -0,0 +1,76 @@
|
||||
|
||||
|
||||
#ifndef _HDMITX_DEV_H_
|
||||
#define _HDMITX_DEV_H_
|
||||
#include <common.h>
|
||||
|
||||
|
||||
#define HDMI_ERROR_MSG printf
|
||||
#define HDMI_INFO_MSG printf
|
||||
#define LOG_TRACE()
|
||||
#define LOG_TRACE1(a)
|
||||
#define LOG_TRACE2(a, b)
|
||||
#define LOG_TRACE3(a, b, c)
|
||||
#define BIT(x) (1 << (x))
|
||||
|
||||
#define FALSE false
|
||||
#define TRUE true
|
||||
typedef enum {
|
||||
PHY_ACCESS_UNDEFINED = 0,
|
||||
PHY_I2C = 1,
|
||||
PHY_JTAG
|
||||
} phy_access_t;
|
||||
|
||||
struct hdmi_tx_ctrl {
|
||||
u8 data_enable_polarity;
|
||||
u32 pixel_clock;
|
||||
u8 pixel_repetition;
|
||||
u32 tmds_clk;
|
||||
u8 color_resolution;
|
||||
u8 csc_on;
|
||||
u8 audio_on;
|
||||
u8 esm_enable;
|
||||
u8 hdmi_on;
|
||||
u8 hdcp_on;
|
||||
u8 cec_on;
|
||||
phy_access_t phy_access;
|
||||
};
|
||||
|
||||
typedef struct hdmi_tx_dev_api {
|
||||
struct hdmi_tx_ctrl snps_hdmi_ctrl;
|
||||
} hdmi_tx_dev_t;
|
||||
|
||||
/* *************************************************************************
|
||||
* Data Manipulation and Access
|
||||
* *************************************************************************/
|
||||
/**
|
||||
* Find first (least significant) bit set
|
||||
* @param[in] data word to search
|
||||
* @return bit position or 32 if none is set
|
||||
*/
|
||||
static inline unsigned first_bit_set(uint32_t data)
|
||||
{
|
||||
unsigned n = 0;
|
||||
|
||||
if (data != 0) {
|
||||
for (n = 0; (data & 1) == 0; n++)
|
||||
data >>= 1;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set bit field
|
||||
* @param[in] data raw data
|
||||
* @param[in] mask bit field mask
|
||||
* @param[in] value new value
|
||||
* @return new raw data
|
||||
*/
|
||||
static inline uint32_t set(uint32_t data, uint32_t mask, uint32_t value)
|
||||
{
|
||||
return ((value << first_bit_set(mask)) & mask) | (data & ~mask);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
240
sunxi_spl/display/hdmi/irq.c
Executable file
240
sunxi_spl/display/hdmi/irq.c
Executable file
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
* Allwinner SoCs hdmi2.0 driver.
|
||||
*
|
||||
* Copyright (C) 2016 Allwinner.
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#include "irq.h"
|
||||
#include "access.h"
|
||||
#include "phy.h"
|
||||
|
||||
typedef struct irq_vector {
|
||||
irq_sources_t source;
|
||||
unsigned int stat_reg;
|
||||
unsigned int mute_reg;
|
||||
} irq_vector_t;
|
||||
|
||||
static irq_vector_t irq_vec[] = {
|
||||
{AUDIO_PACKETS, IH_FC_STAT0, IH_MUTE_FC_STAT0},
|
||||
{OTHER_PACKETS, IH_FC_STAT1, IH_MUTE_FC_STAT1},
|
||||
{PACKETS_OVERFLOW, IH_FC_STAT2, IH_MUTE_FC_STAT2},
|
||||
{AUDIO_SAMPLER, IH_AS_STAT0, IH_MUTE_AS_STAT0},
|
||||
{PHY, IH_PHY_STAT0, IH_MUTE_PHY_STAT0},
|
||||
{I2C_DDC, IH_I2CM_STAT0, IH_MUTE_I2CM_STAT0},
|
||||
{CEC, IH_CEC_STAT0, IH_MUTE_CEC_STAT0},
|
||||
{VIDEO_PACKETIZER, IH_VP_STAT0, IH_MUTE_VP_STAT0},
|
||||
{I2C_PHY, IH_I2CMPHY_STAT0, IH_MUTE_I2CMPHY_STAT0},
|
||||
{AUDIO_DMA, IH_AHBDMAAUD_STAT0, IH_MUTE_AHBDMAAUD_STAT0},
|
||||
{0, 0, 0},
|
||||
};
|
||||
|
||||
int irq_read_stat(hdmi_tx_dev_t *dev, irq_sources_t irq_source, u8 *stat)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; irq_vec[i].source != 0; i++) {
|
||||
if (irq_vec[i].source == irq_source) {
|
||||
*stat = dev_read(dev, irq_vec[i].stat_reg);
|
||||
HDMI_INFO_MSG("IRQ read state: irq[%d] stat[%d]\n",
|
||||
irq_source, *stat);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
HDMI_INFO_MSG("IRQ source [%d] is not supported\n", irq_source);
|
||||
*stat = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* Clear IRQ miscellaneous
|
||||
*/
|
||||
int irq_clear_source(hdmi_tx_dev_t *dev, irq_sources_t irq_source)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; irq_vec[i].source != 0; i++) {
|
||||
if (irq_vec[i].source == irq_source) {
|
||||
HDMI_INFO_MSG("IRQ write clear: irq[%d] mask[%d]\n",
|
||||
irq_source, 0xff);
|
||||
dev_write(dev, irq_vec[i].stat_reg, 0xff);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
HDMI_INFO_MSG("IRQ source [%d] is not supported\n", irq_source);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int irq_clear_bit(hdmi_tx_dev_t *dev, irq_sources_t irq_source, u8 bit_mask)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; irq_vec[i].source != 0; i++) {
|
||||
if (irq_vec[i].source == irq_source) {
|
||||
HDMI_INFO_MSG("IRQ write clear bit: irq[%d] bitmask[%d]\n",
|
||||
irq_source, bit_mask);
|
||||
dev_write_mask(dev, irq_vec[i].stat_reg, bit_mask, 1);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
HDMI_INFO_MSG("IRQ source [%d] is not supported\n", irq_source);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* Mute IRQ miscellaneous
|
||||
*/
|
||||
int irq_mute_source(hdmi_tx_dev_t *dev, irq_sources_t irq_source)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; irq_vec[i].source != 0; i++) {
|
||||
if (irq_vec[i].source == irq_source) {
|
||||
HDMI_INFO_MSG("IRQ write mute: irq[%d] mask[%d]\n",
|
||||
irq_source, 0xff);
|
||||
dev_write(dev, irq_vec[i].mute_reg, 0xff);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
HDMI_INFO_MSG("IRQ source [%d] is not supported\n", irq_source);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* Unmute IRQ miscellaneous
|
||||
*/
|
||||
int irq_unmute_source(hdmi_tx_dev_t *dev, irq_sources_t irq_source)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; irq_vec[i].source != 0; i++) {
|
||||
if (irq_vec[i].source == irq_source) {
|
||||
HDMI_INFO_MSG("IRQ write unmute: irq[%d] mask[%d]\n",
|
||||
irq_source, 0x0);
|
||||
dev_write(dev, irq_vec[i].mute_reg, 0x00);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
HDMI_INFO_MSG("IRQ source [%d] is supported\n", irq_source);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
int irq_mask_bit(hdmi_tx_dev_t *dev, irq_sources_t irq_source, u8 bit_mask)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; irq_vec[i].source != 0; i++) {
|
||||
if (irq_vec[i].source == irq_source) {
|
||||
HDMI_INFO_MSG("IRQ mask bit: irq[%d] bit_mask[%d]\n",
|
||||
irq_source, bit_mask);
|
||||
dev_write_mask(dev, irq_vec[i].mute_reg, bit_mask, 1);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
HDMI_INFO_MSG("IRQ source [%d] is not supported\n", irq_source);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int irq_unmask_bit(hdmi_tx_dev_t *dev, irq_sources_t irq_source, u8 bit_mask)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; irq_vec[i].source != 0; i++) {
|
||||
if (irq_vec[i].source == irq_source) {
|
||||
HDMI_INFO_MSG("IRQ unmask bit: irq[%d] bit_mask[%d]\n",
|
||||
irq_source, bit_mask);
|
||||
dev_write_mask(dev, irq_vec[i].mute_reg, bit_mask, 0);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
HDMI_INFO_MSG("IRQ source [%d] is not supported\n", irq_source);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
void irq_mute(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
LOG_TRACE();
|
||||
dev_write(dev, IH_MUTE, 0x3);
|
||||
}
|
||||
|
||||
void irq_unmute(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
LOG_TRACE();
|
||||
dev_write(dev, IH_MUTE, 0x0);
|
||||
}
|
||||
|
||||
void irq_clear_all(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
LOG_TRACE();
|
||||
irq_clear_source(dev, AUDIO_PACKETS);
|
||||
irq_clear_source(dev, OTHER_PACKETS);
|
||||
irq_clear_source(dev, PACKETS_OVERFLOW);
|
||||
irq_clear_source(dev, AUDIO_SAMPLER);
|
||||
irq_clear_source(dev, PHY);
|
||||
irq_clear_source(dev, I2C_DDC);
|
||||
irq_clear_source(dev, CEC);
|
||||
irq_clear_source(dev, VIDEO_PACKETIZER);
|
||||
irq_clear_source(dev, I2C_PHY);
|
||||
irq_clear_source(dev, AUDIO_DMA);
|
||||
}
|
||||
|
||||
void irq_mask_all(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
LOG_TRACE();
|
||||
irq_mute(dev);
|
||||
irq_mute_source(dev, AUDIO_PACKETS);
|
||||
irq_mute_source(dev, OTHER_PACKETS);
|
||||
irq_mute_source(dev, PACKETS_OVERFLOW);
|
||||
irq_mute_source(dev, AUDIO_SAMPLER);
|
||||
irq_mute_source(dev, PHY);
|
||||
irq_mute_source(dev, I2C_DDC);
|
||||
irq_mute_source(dev, CEC);
|
||||
irq_mute_source(dev, VIDEO_PACKETIZER);
|
||||
irq_mute_source(dev, I2C_PHY);
|
||||
irq_mute_source(dev, AUDIO_DMA);
|
||||
}
|
||||
|
||||
void irq_scdc_read_request(hdmi_tx_dev_t *dev, int enable)
|
||||
{
|
||||
if (enable)
|
||||
irq_unmask_bit(dev, I2C_DDC,
|
||||
IH_MUTE_I2CM_STAT0_SCDC_READREQ_MASK);
|
||||
else
|
||||
irq_mask_bit(dev, I2C_DDC,
|
||||
IH_MUTE_I2CM_STAT0_SCDC_READREQ_MASK);
|
||||
}
|
||||
|
||||
void un_mask_i2c_interrupt(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
irq_clear_source(dev, I2C_DDC);
|
||||
|
||||
/* scdc_readreq */
|
||||
irq_unmask_bit(dev, I2C_DDC, IH_MUTE_I2CM_STAT0_I2CMASTERERROR_MASK);
|
||||
/* I2Cmasterdone */
|
||||
irq_unmask_bit(dev, I2C_DDC, IH_MUTE_I2CM_STAT0_I2CMASTERDONE_MASK);
|
||||
/* I2Cmastererror */
|
||||
irq_unmask_bit(dev, I2C_DDC, IH_MUTE_I2CM_STAT0_SCDC_READREQ_MASK);
|
||||
}
|
||||
|
||||
void irq_hpd_sense_enable(hdmi_tx_dev_t *dev, u8 enable)
|
||||
{
|
||||
LOG_TRACE();
|
||||
|
||||
if (enable) {
|
||||
i2cddc_fast_mode(dev, 0);
|
||||
|
||||
/* Enable HDMI TX PHY HPD Detector */
|
||||
phy_enable_hpd_sense(dev);
|
||||
} else {
|
||||
phy_disable_hpd_sense(dev);
|
||||
}
|
||||
}
|
||||
244
sunxi_spl/display/hdmi/irq.h
Executable file
244
sunxi_spl/display/hdmi/irq.h
Executable file
@@ -0,0 +1,244 @@
|
||||
/*
|
||||
* Allwinner SoCs hdmi2.0 driver.
|
||||
*
|
||||
* Copyright (C) 2016 Allwinner.
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#ifndef HALINTERRUPT_H_
|
||||
#define HALINTERRUPT_H_
|
||||
|
||||
#include "access.h"
|
||||
//#include "../log.h"
|
||||
//#include "phy.h"
|
||||
#include "hdmitx_dev.h"
|
||||
|
||||
#define ALL_IRQ_MASK 0xff
|
||||
|
||||
typedef enum irq_sources {
|
||||
AUDIO_PACKETS = 1,
|
||||
OTHER_PACKETS,
|
||||
PACKETS_OVERFLOW,
|
||||
AUDIO_SAMPLER,
|
||||
PHY,
|
||||
I2C_DDC,
|
||||
CEC,
|
||||
VIDEO_PACKETIZER,
|
||||
I2C_PHY,
|
||||
AUDIO_DMA,
|
||||
} irq_sources_t;
|
||||
|
||||
/*****************************************************************************
|
||||
* *
|
||||
* Interrupt Registers *
|
||||
* *
|
||||
*****************************************************************************/
|
||||
|
||||
/* Frame Composer Interrupt Status Register 0 (Packet Interrupts) */
|
||||
#define IH_FC_STAT0 0x00000400
|
||||
#define IH_FC_STAT0_NULL_MASK 0x00000001 /* Active after successful transmission of an Null packet */
|
||||
#define IH_FC_STAT0_ACR_MASK 0x00000002 /* Active after successful transmission of an Audio Clock Regeneration (N/CTS transmission) packet */
|
||||
#define IH_FC_STAT0_AUDS_MASK 0x00000004 /* Active after successful transmission of an Audio Sample packet */
|
||||
#define IH_FC_STAT0_NVBI_MASK 0x00000008 /* Active after successful transmission of an NTSC VBI packet */
|
||||
#define IH_FC_STAT0_MAS_MASK 0x00000010 /* Active after successful transmission of an MultiStream Audio packet */
|
||||
#define IH_FC_STAT0_HBR_MASK 0x00000020 /* Active after successful transmission of an Audio HBR packet */
|
||||
#define IH_FC_STAT0_ACP_MASK 0x00000040 /* Active after successful transmission of an Audio Content Protection packet */
|
||||
#define IH_FC_STAT0_AUDI_MASK 0x00000080 /* Active after successful transmission of an Audio InfoFrame packet */
|
||||
|
||||
/* Frame Composer Interrupt Status Register 1 (Packet Interrupts) */
|
||||
#define IH_FC_STAT1 0x00000404
|
||||
#define IH_FC_STAT1_GCP_MASK 0x00000001 /* Active after successful transmission of an General Control Packet */
|
||||
#define IH_FC_STAT1_AVI_MASK 0x00000002 /* Active after successful transmission of an AVI InfoFrame packet */
|
||||
#define IH_FC_STAT1_AMP_MASK 0x00000004 /* Active after successful transmission of an Audio Metadata packet */
|
||||
#define IH_FC_STAT1_SPD_MASK 0x00000008 /* Active after successful transmission of an Source Product Descriptor InfoFrame packet */
|
||||
#define IH_FC_STAT1_VSD_MASK 0x00000010 /* Active after successful transmission of an Vendor Specific Data InfoFrame packet */
|
||||
#define IH_FC_STAT1_ISCR2_MASK 0x00000020 /* Active after successful transmission of an International Standard Recording Code 2 packet */
|
||||
#define IH_FC_STAT1_ISCR1_MASK 0x00000040 /* Active after successful transmission of an International Standard Recording Code 1 packet */
|
||||
#define IH_FC_STAT1_GMD_MASK 0x00000080 /* Active after successful transmission of an Gamut metadata packet */
|
||||
|
||||
/* Frame Composer Interrupt Status Register 2 (Packet Queue Overflow Interrupts) */
|
||||
#define IH_FC_STAT2 0x00000408
|
||||
#define IH_FC_STAT2_HIGHPRIORITY_OVERFLOW_MASK 0x00000001 /* Frame Composer high priority packet queue descriptor overflow indication */
|
||||
#define IH_FC_STAT2_LOWPRIORITY_OVERFLOW_MASK 0x00000002 /* Frame Composer low priority packet queue descriptor overflow indication */
|
||||
|
||||
/* Audio Sampler Interrupt Status Register (FIFO Threshold, Underflow and Overflow Interrupts) */
|
||||
#define IH_AS_STAT0 0x0000040C
|
||||
#define IH_AS_STAT0_AUD_FIFO_OVERFLOW_MASK 0x00000001 /* Audio Sampler audio FIFO full indication */
|
||||
#define IH_AS_STAT0_AUD_FIFO_UNDERFLOW_MASK 0x00000002 /* Audio Sampler audio FIFO empty indication */
|
||||
#define IH_AS_STAT0_AUD_FIFO_UNDERFLOW_THR_MASK 0x00000004 /* Audio Sampler audio FIFO empty threshold (four samples) indication for the legacy HBR audio interface */
|
||||
#define IH_AS_STAT0_FIFO_OVERRUN_MASK 0x00000008 /* Indicates an overrun on the audio FIFO */
|
||||
|
||||
/* PHY Interface Interrupt Status Register (RXSENSE, PLL Lock and HPD Interrupts) */
|
||||
#define IH_PHY_STAT0 0x00000410
|
||||
#define IH_PHY_STAT0_HPD_MASK 0x00000001 /* HDMI Hot Plug Detect indication */
|
||||
#define IH_PHY_STAT0_TX_PHY_LOCK_MASK 0x00000002 /* TX PHY PLL lock indication */
|
||||
#define IH_PHY_STAT0_RX_SENSE_0_MASK 0x00000004 /* TX PHY RX_SENSE indication for driver 0 */
|
||||
#define IH_PHY_STAT0_RX_SENSE_1_MASK 0x00000008 /* TX PHY RX_SENSE indication for driver 1 */
|
||||
#define IH_PHY_STAT0_RX_SENSE_2_MASK 0x00000010 /* TX PHY RX_SENSE indication for driver 2 */
|
||||
#define IH_PHY_STAT0_RX_SENSE_3_MASK 0x00000020 /* TX PHY RX_SENSE indication for driver 3 */
|
||||
|
||||
/* E-DDC I2C Master Interrupt Status Register (Done and Error Interrupts) */
|
||||
#define IH_I2CM_STAT0 0x00000414
|
||||
#define IH_I2CM_STAT0_I2CMASTERERROR_MASK 0x00000001 /* I2C Master error indication */
|
||||
#define IH_I2CM_STAT0_I2CMASTERDONE_MASK 0x00000002 /* I2C Master done indication */
|
||||
#define IH_I2CM_STAT0_SCDC_READREQ_MASK 0x00000004 /* I2C Master SCDC read request indication */
|
||||
|
||||
/* CEC Interrupt Status Register (Functional Operation Interrupts) */
|
||||
#define IH_CEC_STAT0 0x00000418
|
||||
#define IH_CEC_STAT0_DONE_MASK 0x00000001 /* CEC Done Indication */
|
||||
#define IH_CEC_STAT0_EOM_MASK 0x00000002 /* CEC End of Message Indication */
|
||||
#define IH_CEC_STAT0_NACK_MASK 0x00000004 /* CEC Not Acknowledge indication */
|
||||
#define IH_CEC_STAT0_ARB_LOST_MASK 0x00000008 /* CEC Arbitration Lost indication */
|
||||
#define IH_CEC_STAT0_ERROR_INITIATOR_MASK 0x00000010 /* CEC Error Initiator indication */
|
||||
#define IH_CEC_STAT0_ERROR_FOLLOW_MASK 0x00000020 /* CEC Error Follow indication */
|
||||
#define IH_CEC_STAT0_WAKEUP_MASK 0x00000040 /* CEC Wake-up indication */
|
||||
|
||||
/* Video Packetizer Interrupt Status Register (FIFO Full and Empty Interrupts) */
|
||||
#define IH_VP_STAT0 0x0000041C
|
||||
#define IH_VP_STAT0_FIFOEMPTYBYP_MASK 0x00000001 /* Video Packetizer 8 bit bypass FIFO empty interrupt */
|
||||
#define IH_VP_STAT0_FIFOFULLBYP_MASK 0x00000002 /* Video Packetizer 8 bit bypass FIFO full interrupt */
|
||||
#define IH_VP_STAT0_FIFOEMPTYREMAP_MASK 0x00000004 /* Video Packetizer pixel YCC 422 re-mapper FIFO empty interrupt */
|
||||
#define IH_VP_STAT0_FIFOFULLREMAP_MASK 0x00000008 /* Video Packetizer pixel YCC 422 re-mapper FIFO full interrupt */
|
||||
#define IH_VP_STAT0_FIFOEMPTYPP_MASK 0x00000010 /* Video Packetizer pixel packing FIFO empty interrupt */
|
||||
#define IH_VP_STAT0_FIFOFULLPP_MASK 0x00000020 /* Video Packetizer pixel packing FIFO full interrupt */
|
||||
#define IH_VP_STAT0_FIFOEMPTYREPET_MASK 0x00000040 /* Video Packetizer pixel repeater FIFO empty interrupt */
|
||||
#define IH_VP_STAT0_FIFOFULLREPET_MASK 0x00000080 /* Video Packetizer pixel repeater FIFO full interrupt */
|
||||
|
||||
/* PHY GEN2 I2C Master Interrupt Status Register (Done and Error Interrupts) */
|
||||
#define IH_I2CMPHY_STAT0 0x00000420
|
||||
#define IH_I2CMPHY_STAT0_I2CMPHYERROR_MASK 0x00000001 /* I2C Master PHY error indication */
|
||||
#define IH_I2CMPHY_STAT0_I2CMPHYDONE_MASK 0x00000002 /* I2C Master PHY done indication */
|
||||
|
||||
/* DMA - not supported in this build */
|
||||
#define IH_AHBDMAAUD_STAT0 0x00000424
|
||||
|
||||
/* Interruption Handler Decode Assist Register */
|
||||
#define IH_DECODE 0x000005C0
|
||||
#define IH_DECODE_IH_AHBDMAAUD_STAT0_MASK 0x00000001 /* Interruption active at the ih_ahbdmaaud_stat0 register */
|
||||
#define IH_DECODE_IH_CEC_STAT0_MASK 0x00000002 /* Interruption active at the ih_cec_stat0 register */
|
||||
#define IH_DECODE_IH_I2CM_STAT0_MASK 0x00000004 /* Interruption active at the ih_i2cm_stat0 register */
|
||||
#define IH_DECODE_IH_PHY_MASK 0x00000008 /* Interruption active at the ih_phy_stat0 or ih_i2cmphy_stat0 register */
|
||||
#define IH_DECODE_IH_AS_STAT0_MASK 0x00000010 /* Interruption active at the ih_as_stat0 register */
|
||||
#define IH_DECODE_IH_FC_STAT2_VP_MASK 0x00000020 /* Interruption active at the ih_fc_stat2 or ih_vp_stat0 register */
|
||||
#define IH_DECODE_IH_FC_STAT1_MASK 0x00000040 /* Interruption active at the ih_fc_stat1 register */
|
||||
#define IH_DECODE_IH_FC_STAT0_MASK 0x00000080 /* Interruption active at the ih_fc_stat0 register */
|
||||
|
||||
/* Frame Composer Interrupt Mute Control Register 0 */
|
||||
#define IH_MUTE_FC_STAT0 0x00000600
|
||||
#define IH_MUTE_FC_STAT0_NULL_MASK 0x00000001 /* When set to 1, mutes ih_fc_stat0[0] */
|
||||
#define IH_MUTE_FC_STAT0_ACR_MASK 0x00000002 /* When set to 1, mutes ih_fc_stat0[1] */
|
||||
#define IH_MUTE_FC_STAT0_AUDS_MASK 0x00000004 /* When set to 1, mutes ih_fc_stat0[2] */
|
||||
#define IH_MUTE_FC_STAT0_NVBI_MASK 0x00000008 /* When set to 1, mutes ih_fc_stat0[3] */
|
||||
#define IH_MUTE_FC_STAT0_MAS_MASK 0x00000010 /* When set to 1, mutes ih_fc_stat0[4] */
|
||||
#define IH_MUTE_FC_STAT0_HBR_MASK 0x00000020 /* When set to 1, mutes ih_fc_stat0[5] */
|
||||
#define IH_MUTE_FC_STAT0_ACP_MASK 0x00000040 /* When set to 1, mutes ih_fc_stat0[6] */
|
||||
#define IH_MUTE_FC_STAT0_AUDI_MASK 0x00000080 /* When set to 1, mutes ih_fc_stat0[7] */
|
||||
|
||||
/* Frame Composer Interrupt Mute Control Register 1 */
|
||||
#define IH_MUTE_FC_STAT1 0x00000604
|
||||
#define IH_MUTE_FC_STAT1_GCP_MASK 0x00000001 /* When set to 1, mutes ih_fc_stat1[0] */
|
||||
#define IH_MUTE_FC_STAT1_AVI_MASK 0x00000002 /* When set to 1, mutes ih_fc_stat1[1] */
|
||||
#define IH_MUTE_FC_STAT1_AMP_MASK 0x00000004 /* When set to 1, mutes ih_fc_stat1[2] */
|
||||
#define IH_MUTE_FC_STAT1_SPD_MASK 0x00000008 /* When set to 1, mutes ih_fc_stat1[3] */
|
||||
#define IH_MUTE_FC_STAT1_VSD_MASK 0x00000010 /* When set to 1, mutes ih_fc_stat1[4] */
|
||||
#define IH_MUTE_FC_STAT1_ISCR2_MASK 0x00000020 /* When set to 1, mutes ih_fc_stat1[5] */
|
||||
#define IH_MUTE_FC_STAT1_ISCR1_MASK 0x00000040 /* When set to 1, mutes ih_fc_stat1[6] */
|
||||
#define IH_MUTE_FC_STAT1_GMD_MASK 0x00000080 /* When set to 1, mutes ih_fc_stat1[7] */
|
||||
|
||||
/* Frame Composer Interrupt Mute Control Register 2 */
|
||||
#define IH_MUTE_FC_STAT2 0x00000608
|
||||
#define IH_MUTE_FC_STAT2_HIGHPRIORITY_OVERFLOW_MASK 0x00000001 /* When set to 1, mutes ih_fc_stat2[0] */
|
||||
#define IH_MUTE_FC_STAT2_LOWPRIORITY_OVERFLOW_MASK 0x00000002 /* When set to 1, mutes ih_fc_stat2[1] */
|
||||
|
||||
/* Audio Sampler Interrupt Mute Control Register */
|
||||
#define IH_MUTE_AS_STAT0 0x0000060C
|
||||
#define IH_MUTE_AS_STAT0_AUD_FIFO_OVERFLOW_MASK 0x00000001 /* When set to 1, mutes ih_as_stat0[0] */
|
||||
#define IH_MUTE_AS_STAT0_AUD_FIFO_UNDERFLOW_MASK 0x00000002 /* When set to 1, mutes ih_as_stat0[1] */
|
||||
#define IH_MUTE_AS_STAT0_AUD_FIFO_UNDERFLOW_THR_MASK 0x00000004 /* When set to 1, mutes ih_as_stat0[2] */
|
||||
#define IH_MUTE_AS_STAT0_FIFO_OVERRUN_MASK 0x00000008 /* When set to 1, mutes ih_as_stat0[3] */
|
||||
|
||||
/* PHY Interface Interrupt Mute Control Register */
|
||||
#define IH_MUTE_PHY_STAT0 0x00000610
|
||||
#define IH_MUTE_PHY_STAT0_HPD_MASK 0x00000001 /* When set to 1, mutes ih_phy_stat0[0] */
|
||||
#define IH_MUTE_PHY_STAT0_TX_PHY_LOCK_MASK 0x00000002 /* When set to 1, mutes ih_phy_stat0[1] */
|
||||
#define IH_MUTE_PHY_STAT0_RX_SENSE_0_MASK 0x00000004 /* When set to 1, mutes ih_phy_stat0[2] */
|
||||
#define IH_MUTE_PHY_STAT0_RX_SENSE_1_MASK 0x00000008 /* When set to 1, mutes ih_phy_stat0[3] */
|
||||
#define IH_MUTE_PHY_STAT0_RX_SENSE_2_MASK 0x00000010 /* When set to 1, mutes ih_phy_stat0[4] */
|
||||
#define IH_MUTE_PHY_STAT0_RX_SENSE_3_MASK 0x00000020 /* When set to 1, mutes ih_phy_stat0[5] */
|
||||
|
||||
/* E-DDC I2C Master Interrupt Mute Control Register */
|
||||
#define IH_MUTE_I2CM_STAT0 0x00000614
|
||||
#define IH_MUTE_I2CM_STAT0_I2CMASTERERROR_MASK 0x00000001 /* When set to 1, mutes ih_i2cm_stat0[0] */
|
||||
#define IH_MUTE_I2CM_STAT0_I2CMASTERDONE_MASK 0x00000002 /* When set to 1, mutes ih_i2cm_stat0[1] */
|
||||
#define IH_MUTE_I2CM_STAT0_SCDC_READREQ_MASK 0x00000004 /* When set to 1, mutes ih_i2cm_stat0[2] */
|
||||
|
||||
/* CEC Interrupt Mute Control Register */
|
||||
#define IH_MUTE_CEC_STAT0 0x00000618
|
||||
#define IH_MUTE_CEC_STAT0_DONE_MASK 0x00000001 /* When set to 1, mutes ih_cec_stat0[0] */
|
||||
#define IH_MUTE_CEC_STAT0_EOM_MASK 0x00000002 /* When set to 1, mutes ih_cec_stat0[1] */
|
||||
#define IH_MUTE_CEC_STAT0_NACK_MASK 0x00000004 /* When set to 1, mutes ih_cec_stat0[2] */
|
||||
#define IH_MUTE_CEC_STAT0_ARB_LOST_MASK 0x00000008 /* When set to 1, mutes ih_cec_stat0[3] */
|
||||
#define IH_MUTE_CEC_STAT0_ERROR_INITIATOR_MASK 0x00000010 /* When set to 1, mutes ih_cec_stat0[4] */
|
||||
#define IH_MUTE_CEC_STAT0_ERROR_FOLLOW_MASK 0x00000020 /* When set to 1, mutes ih_cec_stat0[5] */
|
||||
#define IH_MUTE_CEC_STAT0_WAKEUP_MASK 0x00000040 /* When set to 1, mutes ih_cec_stat0[6] */
|
||||
|
||||
/* Video Packetizer Interrupt Mute Control Register */
|
||||
#define IH_MUTE_VP_STAT0 0x0000061C
|
||||
#define IH_MUTE_VP_STAT0_FIFOEMPTYBYP_MASK 0x00000001 /* When set to 1, mutes ih_vp_stat0[0] */
|
||||
#define IH_MUTE_VP_STAT0_FIFOFULLBYP_MASK 0x00000002 /* When set to 1, mutes ih_vp_stat0[1] */
|
||||
#define IH_MUTE_VP_STAT0_FIFOEMPTYREMAP_MASK 0x00000004 /* When set to 1, mutes ih_vp_stat0[2] */
|
||||
#define IH_MUTE_VP_STAT0_FIFOFULLREMAP_MASK 0x00000008 /* When set to 1, mutes ih_vp_stat0[3] */
|
||||
#define IH_MUTE_VP_STAT0_FIFOEMPTYPP_MASK 0x00000010 /* When set to 1, mutes ih_vp_stat0[4] */
|
||||
#define IH_MUTE_VP_STAT0_FIFOFULLPP_MASK 0x00000020 /* When set to 1, mutes ih_vp_stat0[5] */
|
||||
#define IH_MUTE_VP_STAT0_FIFOEMPTYREPET_MASK 0x00000040 /* When set to 1, mutes ih_vp_stat0[6] */
|
||||
#define IH_MUTE_VP_STAT0_FIFOFULLREPET_MASK 0x00000080 /* When set to 1, mutes ih_vp_stat0[7] */
|
||||
|
||||
/* PHY GEN2 I2C Master Interrupt Mute Control Register */
|
||||
#define IH_MUTE_I2CMPHY_STAT0 0x00000620
|
||||
#define IH_MUTE_I2CMPHY_STAT0_I2CMPHYERROR_MASK 0x00000001 /* When set to 1, mutes ih_i2cmphy_stat0[0] */
|
||||
#define IH_MUTE_I2CMPHY_STAT0_I2CMPHYDONE_MASK 0x00000002 /* When set to 1, mutes ih_i2cmphy_stat0[1] */
|
||||
|
||||
/* AHB Audio DMA Interrupt Mute Control Register */
|
||||
#define IH_MUTE_AHBDMAAUD_STAT0 0x00000624
|
||||
#define IH_MUTE_AHBDMAAUD_STAT0_INTBUFFEMPTY_MASK 0x00000001 /* When set to 1, mutes ih_ahbdmaaud_stat0[0] */
|
||||
#define IH_MUTE_AHBDMAAUD_STAT0_INTBUFFULL_MASK 0x00000002 /* en set to 1, mutes ih_ahbdmaaud_stat0[1] */
|
||||
#define IH_MUTE_AHBDMAAUD_STAT0_INTDONE_MASK 0x00000004 /* When set to 1, mutes ih_ahbdmaaud_stat0[2] */
|
||||
#define IH_MUTE_AHBDMAAUD_STAT0_INTINTERTRYSPLIT_MASK 0x00000008 /* When set to 1, mutes ih_ahbdmaaud_stat0[3] */
|
||||
#define IH_MUTE_AHBDMAAUD_STAT0_INTLOSTOWNERSHIP_MASK 0x00000010 /* When set to 1, mutes ih_ahbdmaaud_stat0[4] */
|
||||
#define IH_MUTE_AHBDMAAUD_STAT0_INTERROR_MASK 0x00000020 /* When set to 1, mutes ih_ahbdmaaud_stat0[5] */
|
||||
#define IH_MUTE_AHBDMAAUD_STAT0_INTBUFFOVERRUN_MASK 0x00000040 /* When set to 1, mutes ih_ahbdmaaud_stat0[6] */
|
||||
|
||||
/* Global Interrupt Mute Control Register */
|
||||
#define IH_MUTE 0x000007FC
|
||||
#define IH_MUTE_MUTE_ALL_INTERRUPT_MASK 0x00000001 /* When set to 1, mutes the main interrupt line (where all interrupts are ORed) */
|
||||
#define IH_MUTE_MUTE_WAKEUP_INTERRUPT_MASK 0x00000002 /* When set to 1, mutes the main interrupt output port */
|
||||
|
||||
int irq_read_stat(hdmi_tx_dev_t *dev, irq_sources_t irq_source, u8 *stat);
|
||||
|
||||
int irq_clear_source(hdmi_tx_dev_t *dev, irq_sources_t irq_source);
|
||||
int irq_clear_bit(hdmi_tx_dev_t *dev, irq_sources_t irq_source, u8 bit_mask);
|
||||
|
||||
int irq_mute_source(hdmi_tx_dev_t *dev, irq_sources_t irq_source);
|
||||
int irq_unmute_source(hdmi_tx_dev_t *dev, irq_sources_t irq_source);
|
||||
|
||||
void irq_mute(hdmi_tx_dev_t *dev);
|
||||
void irq_unmute(hdmi_tx_dev_t *dev);
|
||||
|
||||
void irq_clear_all(hdmi_tx_dev_t *dev);
|
||||
void irq_mask_all(hdmi_tx_dev_t *dev);
|
||||
|
||||
int irq_mask_bit(hdmi_tx_dev_t *dev, irq_sources_t irq_source, u8 bit_mask);
|
||||
int irq_unmask_bit(hdmi_tx_dev_t *dev, irq_sources_t irq_source, u8 bit_mask);
|
||||
|
||||
|
||||
extern void irq_hpd_sense_enable(hdmi_tx_dev_t *dev, u8 enable);
|
||||
|
||||
void irq_scdc_read_request(hdmi_tx_dev_t *dev, int enable);
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* HALINTERRUPT_H_ */
|
||||
98
sunxi_spl/display/hdmi/main_controller.c
Executable file
98
sunxi_spl/display/hdmi/main_controller.c
Executable file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Allwinner SoCs hdmi2.0 driver.
|
||||
*
|
||||
* Copyright (C) 2016 Allwinner.
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#include "main_controller.h"
|
||||
#include "access.h"
|
||||
|
||||
static void mc_hdcp_clock_enable(hdmi_tx_dev_t *dev, u8 bit)
|
||||
{
|
||||
LOG_TRACE1(bit);
|
||||
dev_write_mask(dev, MC_CLKDIS, MC_CLKDIS_HDCPCLK_DISABLE_MASK, bit);
|
||||
}
|
||||
|
||||
void mc_cec_clock_enable(hdmi_tx_dev_t *dev, u8 bit)
|
||||
{
|
||||
LOG_TRACE1(bit);
|
||||
dev_write_mask(dev, MC_CLKDIS, MC_CLKDIS_CECCLK_DISABLE_MASK, bit);
|
||||
}
|
||||
|
||||
static void mc_colorspace_converter_clock_enable(hdmi_tx_dev_t *dev, u8 bit)
|
||||
{
|
||||
LOG_TRACE1(bit);
|
||||
dev_write_mask(dev, MC_CLKDIS, MC_CLKDIS_CSCCLK_DISABLE_MASK, bit);
|
||||
}
|
||||
|
||||
void mc_audio_sampler_clock_enable(hdmi_tx_dev_t *dev, u8 bit)
|
||||
{
|
||||
LOG_TRACE1(bit);
|
||||
dev_write_mask(dev, MC_CLKDIS, MC_CLKDIS_AUDCLK_DISABLE_MASK, bit);
|
||||
}
|
||||
|
||||
static void mc_pixel_repetition_clock_enable(hdmi_tx_dev_t *dev, u8 bit)
|
||||
{
|
||||
LOG_TRACE1(bit);
|
||||
dev_write_mask(dev, MC_CLKDIS, MC_CLKDIS_PREPCLK_DISABLE_MASK, bit);
|
||||
}
|
||||
|
||||
static void mc_tmds_clock_enable(hdmi_tx_dev_t *dev, u8 bit)
|
||||
{
|
||||
LOG_TRACE1(bit);
|
||||
dev_write_mask(dev, MC_CLKDIS, MC_CLKDIS_TMDSCLK_DISABLE_MASK, bit);
|
||||
}
|
||||
|
||||
static void mc_pixel_clock_enable(hdmi_tx_dev_t *dev, u8 bit)
|
||||
{
|
||||
LOG_TRACE1(bit);
|
||||
dev_write_mask(dev, MC_CLKDIS, MC_CLKDIS_PIXELCLK_DISABLE_MASK, bit);
|
||||
}
|
||||
|
||||
void mc_audio_i2s_reset(hdmi_tx_dev_t *dev, u8 bit)
|
||||
{
|
||||
LOG_TRACE1(bit);
|
||||
dev_write_mask(dev, MC_SWRSTZREQ,
|
||||
MC_SWRSTZREQ_II2SSWRST_REQ_MASK, bit);
|
||||
}
|
||||
|
||||
|
||||
static void mc_video_feed_through_off(hdmi_tx_dev_t *dev, u8 bit)
|
||||
{
|
||||
LOG_TRACE1(bit);
|
||||
dev_write_mask(dev, MC_FLOWCTRL,
|
||||
MC_FLOWCTRL_FEED_THROUGH_OFF_MASK, bit);
|
||||
}
|
||||
|
||||
void mc_phy_reset(hdmi_tx_dev_t *dev, u8 bit)
|
||||
{
|
||||
LOG_TRACE1(bit);
|
||||
/* active low */
|
||||
dev_write_mask(dev, MC_PHYRSTZ, MC_PHYRSTZ_PHYRSTZ_MASK, bit);
|
||||
}
|
||||
|
||||
void mc_tmds_clock_reset(hdmi_tx_dev_t *dev, u8 bit)
|
||||
{
|
||||
LOG_TRACE1(bit);
|
||||
dev_write_mask(dev, MC_SWRSTZREQ, MC_SWRSTZREQ_TMDSSWRST_REQ_MASK, bit);
|
||||
}
|
||||
|
||||
|
||||
void mc_enable_all_clocks(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
LOG_TRACE();
|
||||
mc_video_feed_through_off(dev, dev->snps_hdmi_ctrl.csc_on ? 0 : 1);
|
||||
mc_pixel_clock_enable(dev, 0);
|
||||
mc_tmds_clock_enable(dev, 0);
|
||||
mc_pixel_repetition_clock_enable(dev,
|
||||
(dev->snps_hdmi_ctrl.pixel_repetition > 0) ? 0 : 1);
|
||||
mc_colorspace_converter_clock_enable(dev, 0);
|
||||
mc_audio_sampler_clock_enable(dev,
|
||||
dev->snps_hdmi_ctrl.audio_on ? 0 : 1);
|
||||
mc_cec_clock_enable(dev, dev->snps_hdmi_ctrl.cec_on ? 0 : 1);
|
||||
mc_hdcp_clock_enable(dev, dev->snps_hdmi_ctrl.hdcp_on ? 0 : 1);
|
||||
}
|
||||
82
sunxi_spl/display/hdmi/main_controller.h
Executable file
82
sunxi_spl/display/hdmi/main_controller.h
Executable file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Allwinner SoCs hdmi2.0 driver.
|
||||
*
|
||||
* Copyright (C) 2016 Allwinner.
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef HALMAINCONTROLLER_H_
|
||||
#define HALMAINCONTROLLER_H_
|
||||
|
||||
|
||||
#include "hdmitx_dev.h"
|
||||
|
||||
//#include "../log.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* *
|
||||
* Main Controller Registers *
|
||||
* *
|
||||
*****************************************************************************/
|
||||
|
||||
/* Main Controller Synchronous Clock Domain Disable Register */
|
||||
#define MC_CLKDIS 0x00010004
|
||||
#define MC_CLKDIS_PIXELCLK_DISABLE_MASK 0x00000001 /* Pixel clock synchronous disable signal */
|
||||
#define MC_CLKDIS_TMDSCLK_DISABLE_MASK 0x00000002 /* TMDS clock synchronous disable signal */
|
||||
#define MC_CLKDIS_PREPCLK_DISABLE_MASK 0x00000004 /* Pixel Repetition clock synchronous disable signal */
|
||||
#define MC_CLKDIS_AUDCLK_DISABLE_MASK 0x00000008 /* Audio Sampler clock synchronous disable signal */
|
||||
#define MC_CLKDIS_CSCCLK_DISABLE_MASK 0x00000010 /* Color Space Converter clock synchronous disable signal */
|
||||
#define MC_CLKDIS_CECCLK_DISABLE_MASK 0x00000020 /* CEC Engine clock synchronous disable signal */
|
||||
#define MC_CLKDIS_HDCPCLK_DISABLE_MASK 0x00000040 /* HDCP clock synchronous disable signal */
|
||||
|
||||
/* Main Controller Software Reset Register Main controller software reset request per clock domain */
|
||||
#define MC_SWRSTZREQ 0x00010008
|
||||
#define MC_SWRSTZREQ_PIXELSWRST_REQ_MASK 0x00000001 /* Pixel software reset request */
|
||||
#define MC_SWRSTZREQ_TMDSSWRST_REQ_MASK 0x00000002 /* TMDS software reset request */
|
||||
#define MC_SWRSTZREQ_PREPSWRST_REQ_MASK 0x00000004 /* Pixel Repetition software reset request */
|
||||
#define MC_SWRSTZREQ_II2SSWRST_REQ_MASK 0x00000008 /* I2S audio software reset request */
|
||||
#define MC_SWRSTZREQ_ISPDIFSWRST_REQ_MASK 0x00000010 /* SPDIF audio software reset request */
|
||||
#define MC_SWRSTZREQ_CECSWRST_REQ_MASK 0x00000040 /* CEC software reset request */
|
||||
#define MC_SWRSTZREQ_IGPASWRST_REQ_MASK 0x00000080 /* GPAUD interface soft reset request */
|
||||
|
||||
/* Main Controller HDCP Bypass Control Register */
|
||||
#define MC_OPCTRL 0x0001000C
|
||||
#define MC_OPCTRL_HDCP_BLOCK_BYP_MASK 0x00000001 /* Block HDCP bypass mechanism - 1'b0: This is the default value */
|
||||
|
||||
/* Main Controller Feed Through Control Register */
|
||||
#define MC_FLOWCTRL 0x00010010
|
||||
#define MC_FLOWCTRL_FEED_THROUGH_OFF_MASK 0x00000001 /* Video path Feed Through enable bit: - 1b: Color Space Converter is in the video data path */
|
||||
|
||||
/* Main Controller PHY Reset Register */
|
||||
#define MC_PHYRSTZ 0x00010014
|
||||
#define MC_PHYRSTZ_PHYRSTZ_MASK 0x00000001 /* HDMI Source PHY active low reset control for PHY GEN1, active high reset control for PHY GEN2 */
|
||||
|
||||
/* Main Controller Clock Present Register */
|
||||
#define MC_LOCKONCLOCK 0x00010018
|
||||
#define MC_LOCKONCLOCK_CECCLK_MASK 0x00000001 /* CEC clock status */
|
||||
#define MC_LOCKONCLOCK_AUDIOSPDIFCLK_MASK 0x00000004 /* SPDIF clock status */
|
||||
#define MC_LOCKONCLOCK_I2SCLK_MASK 0x00000008 /* I2S clock status */
|
||||
#define MC_LOCKONCLOCK_PREPCLK_MASK 0x00000010 /* Pixel Repetition clock status */
|
||||
#define MC_LOCKONCLOCK_TCLK_MASK 0x00000020 /* TMDS clock status */
|
||||
#define MC_LOCKONCLOCK_PCLK_MASK 0x00000040 /* Pixel clock status */
|
||||
#define MC_LOCKONCLOCK_IGPACLK_MASK 0x00000080 /* GPAUD interface clock status */
|
||||
|
||||
void mc_audio_i2s_reset(hdmi_tx_dev_t *dev, u8 bit);
|
||||
void mc_disable_all_clocks(hdmi_tx_dev_t *dev);
|
||||
|
||||
void mc_enable_all_clocks(hdmi_tx_dev_t *dev);
|
||||
|
||||
void mc_rst_all_clocks(hdmi_tx_dev_t *dev);
|
||||
void mc_audio_sampler_clock_enable(hdmi_tx_dev_t *dev, u8 bit);
|
||||
void mc_audio_i2s_reset(hdmi_tx_dev_t *dev, u8 bit);
|
||||
|
||||
void mc_tmds_clock_reset(hdmi_tx_dev_t *dev, u8 bit);
|
||||
|
||||
void mc_phy_reset(hdmi_tx_dev_t *dev, u8 bit);
|
||||
|
||||
|
||||
#endif /* HALMAINCONTROLLER_H_ */
|
||||
921
sunxi_spl/display/hdmi/packets.c
Executable file
921
sunxi_spl/display/hdmi/packets.c
Executable file
@@ -0,0 +1,921 @@
|
||||
/*
|
||||
* Allwinner SoCs hdmi2.0 driver.
|
||||
*
|
||||
* Copyright (C) 2016 Allwinner.
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#include "packets.h"
|
||||
#include "access.h"
|
||||
|
||||
#define ACP_PACKET_SIZE 16
|
||||
#define ISRC_PACKET_SIZE 16
|
||||
|
||||
#define FC_GMD_PB_SIZE 28
|
||||
|
||||
|
||||
void fc_drm_disable(hdmi_tx_dev_t *dev);
|
||||
|
||||
void fc_acp_type(hdmi_tx_dev_t *dev, u8 type)
|
||||
{
|
||||
LOG_TRACE1(type);
|
||||
dev_write(dev, FC_ACP0, type);
|
||||
}
|
||||
|
||||
void fc_acp_type_dependent_fields(hdmi_tx_dev_t *dev, u8 *fields,
|
||||
u8 fieldsLength)
|
||||
{
|
||||
u8 c = 0;
|
||||
|
||||
LOG_TRACE1(fields[0]);
|
||||
if (fieldsLength > (FC_ACP1 - FC_ACP16 + 1)) {
|
||||
fieldsLength = (FC_ACP1 - FC_ACP16 + 1);
|
||||
HDMI_INFO_MSG("WARN:ACP Fields Truncated\n");
|
||||
}
|
||||
|
||||
for (c = 0; c < fieldsLength; c++)
|
||||
dev_write(dev, FC_ACP1 - c, fields[c]);
|
||||
}
|
||||
|
||||
void fc_RgbYcc(hdmi_tx_dev_t *dev, u8 type)
|
||||
{
|
||||
LOG_TRACE1(type);
|
||||
dev_write_mask(dev, FC_AVICONF0,
|
||||
FC_AVICONF0_RGC_YCC_INDICATION_MASK, type);
|
||||
}
|
||||
|
||||
void fc_ScanInfo(hdmi_tx_dev_t *dev, u8 left)
|
||||
{
|
||||
LOG_TRACE1(left);
|
||||
dev_write_mask(dev, FC_AVICONF0,
|
||||
FC_AVICONF0_SCAN_INFORMATION_MASK, left);
|
||||
}
|
||||
|
||||
void fc_Colorimetry(hdmi_tx_dev_t *dev, unsigned cscITU)
|
||||
{
|
||||
LOG_TRACE1(cscITU);
|
||||
dev_write_mask(dev, FC_AVICONF1, FC_AVICONF1_COLORIMETRY_MASK, cscITU);
|
||||
}
|
||||
|
||||
void fc_PicAspectRatio(hdmi_tx_dev_t *dev, u8 ar)
|
||||
{
|
||||
LOG_TRACE1(ar);
|
||||
dev_write_mask(dev, FC_AVICONF1,
|
||||
FC_AVICONF1_PICTURE_ASPECT_RATIO_MASK, ar);
|
||||
}
|
||||
|
||||
void fc_ActiveAspectRatioValid(hdmi_tx_dev_t *dev, u8 valid)
|
||||
{
|
||||
LOG_TRACE1(valid);
|
||||
dev_write_mask(dev, FC_AVICONF0,
|
||||
FC_AVICONF0_ACTIVE_FORMAT_PRESENT_MASK, valid);
|
||||
}
|
||||
|
||||
void fc_ActiveFormatAspectRatio(hdmi_tx_dev_t *dev, u8 left)
|
||||
{
|
||||
LOG_TRACE1(left);
|
||||
dev_write_mask(dev, FC_AVICONF1,
|
||||
FC_AVICONF1_ACTIVE_ASPECT_RATIO_MASK, left);
|
||||
}
|
||||
|
||||
void fc_IsItContent(hdmi_tx_dev_t *dev, u8 it)
|
||||
{
|
||||
LOG_TRACE1(it);
|
||||
dev_write_mask(dev, FC_AVICONF2,
|
||||
FC_AVICONF2_IT_CONTENT_MASK, (it ? 1 : 0));
|
||||
}
|
||||
|
||||
void fc_ExtendedColorimetry(hdmi_tx_dev_t *dev, u8 extColor)
|
||||
{
|
||||
LOG_TRACE1(extColor);
|
||||
dev_write_mask(dev, FC_AVICONF2,
|
||||
FC_AVICONF2_EXTENDED_COLORIMETRY_MASK, extColor);
|
||||
dev_write_mask(dev, FC_AVICONF1, FC_AVICONF1_COLORIMETRY_MASK, 0x3);
|
||||
}
|
||||
|
||||
void fc_QuantizationRange(hdmi_tx_dev_t *dev, u8 range)
|
||||
{
|
||||
LOG_TRACE1(range);
|
||||
dev_write_mask(dev, FC_AVICONF2,
|
||||
FC_AVICONF2_QUANTIZATION_RANGE_MASK, range);
|
||||
}
|
||||
|
||||
void fc_NonUniformPicScaling(hdmi_tx_dev_t *dev, u8 scale)
|
||||
{
|
||||
LOG_TRACE1(scale);
|
||||
dev_write_mask(dev, FC_AVICONF2,
|
||||
FC_AVICONF2_NON_UNIFORM_PICTURE_SCALING_MASK, scale);
|
||||
}
|
||||
|
||||
void fc_VideoCode(hdmi_tx_dev_t *dev, u8 code)
|
||||
{
|
||||
LOG_TRACE1(code);
|
||||
dev_write(dev, FC_AVIVID, code);
|
||||
}
|
||||
|
||||
void fc_HorizontalBarsValid(hdmi_tx_dev_t *dev, u8 validity)
|
||||
{
|
||||
dev_write_mask(dev, FC_AVICONF0,
|
||||
FC_AVICONF0_BAR_INFORMATION_MASK & 0x8, (validity ? 1 : 0));
|
||||
}
|
||||
|
||||
void fc_HorizontalBars(hdmi_tx_dev_t *dev, u16 endTop, u16 startBottom)
|
||||
{
|
||||
LOG_TRACE2(endTop, startBottom);
|
||||
dev_write(dev, FC_AVIETB0, (u8) (endTop));
|
||||
dev_write(dev, FC_AVIETB1, (u8) (endTop >> 8));
|
||||
dev_write(dev, FC_AVISBB0, (u8) (startBottom));
|
||||
dev_write(dev, FC_AVISBB1, (u8) (startBottom >> 8));
|
||||
}
|
||||
|
||||
void fc_VerticalBarsValid(hdmi_tx_dev_t *dev, u8 validity)
|
||||
{
|
||||
dev_write_mask(dev, FC_AVICONF0,
|
||||
FC_AVICONF0_BAR_INFORMATION_MASK & 0x4, (validity ? 1 : 0));
|
||||
}
|
||||
|
||||
void fc_VerticalBars(hdmi_tx_dev_t *dev, u16 endLeft, u16 startRight)
|
||||
{
|
||||
LOG_TRACE2(endLeft, startRight);
|
||||
dev_write(dev, FC_AVIELB0, (u8) (endLeft));
|
||||
dev_write(dev, FC_AVIELB1, (u8) (endLeft >> 8));
|
||||
dev_write(dev, FC_AVISRB0, (u8) (startRight));
|
||||
dev_write(dev, FC_AVISRB1, (u8) (startRight >> 8));
|
||||
}
|
||||
|
||||
void fc_OutPixelRepetition(hdmi_tx_dev_t *dev, u8 pr)
|
||||
{
|
||||
LOG_TRACE1(pr);
|
||||
dev_write_mask(dev, FC_PRCONF, FC_PRCONF_OUTPUT_PR_FACTOR_MASK, pr);
|
||||
}
|
||||
|
||||
u32 fc_GetInfoFrameSatus(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
return dev_read(dev, FC_AVICONF0);
|
||||
}
|
||||
|
||||
void fc_avi_config(hdmi_tx_dev_t *dev, videoParams_t *videoParams)
|
||||
{
|
||||
u16 endTop = 0;
|
||||
u16 startBottom = 0;
|
||||
u16 endLeft = 0;
|
||||
u16 startRight = 0;
|
||||
dtd_t *dtd = &videoParams->mDtd;
|
||||
|
||||
LOG_TRACE();
|
||||
|
||||
if (videoParams->mEncodingOut == RGB) {
|
||||
HDMI_INFO_MSG("rgb\n");
|
||||
fc_RgbYcc(dev, 0);
|
||||
} else if (videoParams->mEncodingOut == YCC422) {
|
||||
HDMI_INFO_MSG("ycc422\n");
|
||||
fc_RgbYcc(dev, 1);
|
||||
} else if (videoParams->mEncodingOut == YCC444) {
|
||||
HDMI_INFO_MSG("ycc444\n");
|
||||
fc_RgbYcc(dev, 2);
|
||||
} else if (videoParams->mEncodingOut == YCC420) {
|
||||
HDMI_INFO_MSG("ycc420\n");
|
||||
fc_RgbYcc(dev, 3);
|
||||
}
|
||||
|
||||
fc_ActiveFormatAspectRatio(dev, 0x8);
|
||||
|
||||
HDMI_INFO_MSG("infoframe status before %x\n",
|
||||
fc_GetInfoFrameSatus(dev));
|
||||
|
||||
fc_ScanInfo(dev, videoParams->mScanInfo);
|
||||
|
||||
if (dtd->mHImageSize != 0 || dtd->mVImageSize != 0) {
|
||||
u8 pic = (dtd->mHImageSize * 10) % dtd->mVImageSize;
|
||||
/* 16:9 or 4:3 */
|
||||
fc_PicAspectRatio(dev, (pic > 5) ? 2 : 1);
|
||||
} else {
|
||||
/* No Data */
|
||||
fc_PicAspectRatio(dev, 0);
|
||||
}
|
||||
|
||||
fc_IsItContent(dev, videoParams->mItContent);
|
||||
|
||||
fc_QuantizationRange(dev, videoParams->mRgbQuantizationRange);
|
||||
fc_NonUniformPicScaling(dev, videoParams->mNonUniformScaling);
|
||||
|
||||
/*set cea code*/
|
||||
/*if (videoParams->mHdmi20 == 1) {
|
||||
fc_VideoCode(dev, videoParams->mCea_code);
|
||||
} else {
|
||||
if (videoParams->mCea_code < 90)
|
||||
fc_VideoCode(dev, videoParams->mCea_code);
|
||||
else
|
||||
fc_VideoCode(dev, 0);
|
||||
}*/
|
||||
#if defined(__LINUX_PLAT__)
|
||||
fc_VideoCode(dev, videoParams->mCea_code);
|
||||
#else
|
||||
if (dtd->mCode != (u8) (-1)) {
|
||||
fc_VideoCode(dev, dtd->mCode);
|
||||
} else
|
||||
fc_VideoCode(dev, 0);
|
||||
#endif
|
||||
if (videoParams->mColorimetry == EXTENDED_COLORIMETRY) {
|
||||
/* ext colorimetry valid */
|
||||
if (videoParams->mExtColorimetry != (u8) (-1)) {
|
||||
fc_ExtendedColorimetry(dev, videoParams->mExtColorimetry);
|
||||
fc_Colorimetry(dev, videoParams->mColorimetry);/*EXT-3*/
|
||||
} else {
|
||||
fc_Colorimetry(dev, 0); /* No Data */
|
||||
}
|
||||
} else {
|
||||
/* NODATA-0/ 601-1/ 709-2/ EXT-3 */
|
||||
fc_Colorimetry(dev, videoParams->mColorimetry);
|
||||
}
|
||||
if (videoParams->mActiveFormatAspectRatio != 0) {
|
||||
fc_ActiveFormatAspectRatio(dev, videoParams->mActiveFormatAspectRatio);
|
||||
fc_ActiveAspectRatioValid(dev, 1);
|
||||
} else {
|
||||
fc_ActiveFormatAspectRatio(dev, 0);
|
||||
fc_ActiveAspectRatioValid(dev, 0);
|
||||
}
|
||||
if (videoParams->mEndTopBar != (u16) (-1) ||
|
||||
videoParams->mStartBottomBar != (u16) (-1)) {
|
||||
|
||||
if (videoParams->mEndTopBar != (u16) (-1))
|
||||
endTop = videoParams->mEndTopBar;
|
||||
if (videoParams->mStartBottomBar != (u16) (-1))
|
||||
startBottom = videoParams->mStartBottomBar;
|
||||
|
||||
fc_HorizontalBars(dev, endTop, startBottom);
|
||||
fc_HorizontalBarsValid(dev, 1);
|
||||
} else {
|
||||
fc_HorizontalBarsValid(dev, 0);
|
||||
}
|
||||
if (videoParams->mEndLeftBar != (u16) (-1) ||
|
||||
videoParams->mStartRightBar != (u16) (-1)) {
|
||||
if (videoParams->mEndLeftBar != (u16) (-1))
|
||||
endLeft = videoParams->mEndLeftBar;
|
||||
|
||||
if (videoParams->mStartRightBar != (u16) (-1))
|
||||
startRight = videoParams->mStartRightBar;
|
||||
|
||||
fc_VerticalBars(dev, endLeft, startRight);
|
||||
fc_VerticalBarsValid(dev, 1);
|
||||
} else {
|
||||
fc_VerticalBarsValid(dev, 0);
|
||||
}
|
||||
fc_OutPixelRepetition(dev, (dtd->mPixelRepetitionInput + 1) *
|
||||
(videoParams->mPixelRepetitionFactor + 1) - 1);
|
||||
HDMI_INFO_MSG("infoframe status before after:%x\n",
|
||||
fc_GetInfoFrameSatus(dev));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void fc_gamut_Profile(hdmi_tx_dev_t *dev, u8 profile)
|
||||
{
|
||||
LOG_TRACE1(profile);
|
||||
dev_write_mask(dev, FC_GMD_HB, FC_GMD_HB_GMDGBD_PROFILE_MASK, profile);
|
||||
}
|
||||
|
||||
void fc_gamut_AffectedSeqNo(hdmi_tx_dev_t *dev, u8 no)
|
||||
{
|
||||
LOG_TRACE1(no);
|
||||
dev_write_mask(dev, FC_GMD_HB,
|
||||
FC_GMD_HB_GMDAFFECTED_GAMUT_SEQ_NUM_MASK, no);
|
||||
}
|
||||
|
||||
void fc_gamut_PacketsPerFrame(hdmi_tx_dev_t *dev, u8 packets)
|
||||
{
|
||||
LOG_TRACE1(packets);
|
||||
dev_write_mask(dev, FC_GMD_CONF,
|
||||
FC_GMD_CONF_GMDPACKETSINFRAME_MASK, packets);
|
||||
}
|
||||
|
||||
void fc_gamut_PacketLineSpacing(hdmi_tx_dev_t *dev, u8 lineSpacing)
|
||||
{
|
||||
LOG_TRACE1(lineSpacing);
|
||||
dev_write_mask(dev, FC_GMD_CONF,
|
||||
FC_GMD_CONF_GMDPACKETLINESPACING_MASK, lineSpacing);
|
||||
}
|
||||
|
||||
void fc_gamut_Content(hdmi_tx_dev_t *dev, const u8 *content, u8 length)
|
||||
{
|
||||
u8 i = 0;
|
||||
|
||||
LOG_TRACE1(content[0]);
|
||||
if (length > (FC_GMD_PB_SIZE)) {
|
||||
length = (FC_GMD_PB_SIZE);
|
||||
HDMI_INFO_MSG("WARN:Gamut Content Truncated");
|
||||
}
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
dev_write(dev, FC_GMD_PB0 + (i*4), content[i]);
|
||||
}
|
||||
|
||||
void fc_gamut_enable_tx(hdmi_tx_dev_t *dev, u8 enable)
|
||||
{
|
||||
LOG_TRACE1(enable);
|
||||
if (enable)
|
||||
enable = 1; /* ensure value is 1 */
|
||||
dev_write_mask(dev, FC_GMD_EN, FC_GMD_EN_GMDENABLETX_MASK, enable);
|
||||
}
|
||||
|
||||
void fc_gamut_UpdatePacket(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
LOG_TRACE();
|
||||
dev_write_mask(dev, FC_GMD_UP, FC_GMD_UP_GMDUPDATEPACKET_MASK, 1);
|
||||
}
|
||||
|
||||
u8 fc_gamut_CurrentSeqNo(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
LOG_TRACE();
|
||||
return (u8)(dev_read(dev, FC_GMD_STAT) & 0xF);
|
||||
}
|
||||
|
||||
|
||||
void fc_gamut_config(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
/* P0 */
|
||||
fc_gamut_Profile(dev, 0x0);
|
||||
|
||||
/* P0 */
|
||||
fc_gamut_PacketsPerFrame(dev, 0x1);
|
||||
fc_gamut_PacketLineSpacing(dev, 0x1);
|
||||
}
|
||||
|
||||
void fc_gamut_packet_config(hdmi_tx_dev_t *dev, const u8 *gbdContent, u8 length)
|
||||
{
|
||||
fc_gamut_enable_tx(dev, 1);
|
||||
/*sequential*/
|
||||
fc_gamut_AffectedSeqNo(dev, (fc_gamut_CurrentSeqNo(dev) + 1) % 16);
|
||||
fc_gamut_Content(dev, gbdContent, length);
|
||||
fc_gamut_UpdatePacket(dev); /* set next_field to 1 */
|
||||
}
|
||||
|
||||
void fc_isrc_status(hdmi_tx_dev_t *dev, u8 code)
|
||||
{
|
||||
LOG_TRACE1(code);
|
||||
dev_write_mask(dev, FC_ISCR1_0, FC_ISCR1_0_ISRC_STATUS_MASK, code);
|
||||
}
|
||||
|
||||
void fc_isrc_valid(hdmi_tx_dev_t *dev, u8 validity)
|
||||
{
|
||||
LOG_TRACE1(validity);
|
||||
dev_write_mask(dev, FC_ISCR1_0, FC_ISCR1_0_ISRC_VALID_MASK,
|
||||
(validity ? 1 : 0));
|
||||
}
|
||||
|
||||
void fc_isrc_cont(hdmi_tx_dev_t *dev, u8 isContinued)
|
||||
{
|
||||
LOG_TRACE1(isContinued);
|
||||
dev_write_mask(dev, FC_ISCR1_0, FC_ISCR1_0_ISRC_CONT_MASK,
|
||||
(isContinued ? 1 : 0));
|
||||
}
|
||||
|
||||
void fc_isrc_isrc1_codes(hdmi_tx_dev_t *dev, u8 *codes, u8 length)
|
||||
{
|
||||
u8 c = 0;
|
||||
|
||||
LOG_TRACE1(codes[0]);
|
||||
if (length > (FC_ISCR1_1 - FC_ISCR1_16 + 1)) {
|
||||
length = (FC_ISCR1_1 - FC_ISCR1_16 + 1);
|
||||
HDMI_INFO_MSG("WARN:ISCR1 Codes Truncated\n");
|
||||
}
|
||||
|
||||
for (c = 0; c < length; c++)
|
||||
dev_write(dev, FC_ISCR1_1 - c, codes[c]);
|
||||
}
|
||||
|
||||
void fc_isrc_isrc2_codes(hdmi_tx_dev_t *dev, u8 *codes, u8 length)
|
||||
{
|
||||
u8 c = 0;
|
||||
|
||||
LOG_TRACE1(codes[0]);
|
||||
if (length > (FC_ISCR2_0 - FC_ISCR2_15 + 1)) {
|
||||
length = (FC_ISCR2_0 - FC_ISCR2_15 + 1);
|
||||
HDMI_INFO_MSG("WARN:ISCR2 Codes Truncated\n");
|
||||
}
|
||||
|
||||
for (c = 0; c < length; c++)
|
||||
dev_write(dev, FC_ISCR2_0 - c, codes[c]);
|
||||
}
|
||||
|
||||
void fc_packets_QueuePriorityHigh(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write_mask(dev, FC_CTRLQHIGH,
|
||||
FC_CTRLQHIGH_ONHIGHATTENDED_MASK, value);
|
||||
}
|
||||
|
||||
void fc_packets_QueuePriorityLow(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write_mask(dev, FC_CTRLQLOW, FC_CTRLQLOW_ONLOWATTENDED_MASK, value);
|
||||
}
|
||||
|
||||
void fc_packets_MetadataFrameInterpolation(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write_mask(dev, FC_DATAUTO1,
|
||||
FC_DATAUTO1_AUTO_FRAME_INTERPOLATION_MASK, value);
|
||||
}
|
||||
|
||||
void fc_packets_MetadataFramesPerPacket(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write_mask(dev, FC_DATAUTO2,
|
||||
FC_DATAUTO2_AUTO_FRAME_PACKETS_MASK, value);
|
||||
}
|
||||
|
||||
void fc_packets_MetadataLineSpacing(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write_mask(dev, FC_DATAUTO2,
|
||||
FC_DATAUTO2_AUTO_LINE_SPACING_MASK, value);
|
||||
}
|
||||
|
||||
void fc_packets_AutoSend(hdmi_tx_dev_t *dev, u8 enable, u8 mask)
|
||||
{
|
||||
LOG_TRACE2(enable, mask);
|
||||
dev_write_mask(dev, FC_DATAUTO0, (1 << mask), (enable ? 1 : 0));
|
||||
}
|
||||
|
||||
void fc_packets_ManualSend(hdmi_tx_dev_t *dev, u8 mask)
|
||||
{
|
||||
LOG_TRACE1(mask);
|
||||
dev_write_mask(dev, FC_DATMAN, (1 << mask), 1);
|
||||
}
|
||||
|
||||
void fc_packets_disable_all(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
uint32_t value = (uint32_t)(~(BIT(ACP_TX) | BIT(ISRC1_TX) |
|
||||
BIT(ISRC2_TX) | BIT(SPD_TX) | BIT(VSD_TX)));
|
||||
|
||||
LOG_TRACE();
|
||||
dev_write(dev, FC_DATAUTO0, value & dev_read(dev, FC_DATAUTO0));
|
||||
}
|
||||
|
||||
void fc_packets_metadata_config(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
fc_packets_MetadataFrameInterpolation(dev, 1);
|
||||
fc_packets_MetadataFramesPerPacket(dev, 1);
|
||||
fc_packets_MetadataLineSpacing(dev, 1);
|
||||
}
|
||||
|
||||
void fc_spd_VendorName(hdmi_tx_dev_t *dev, const u8 *data,
|
||||
unsigned short length)
|
||||
{
|
||||
unsigned short i = 0;
|
||||
|
||||
LOG_TRACE();
|
||||
for (i = 0; i < length; i++)
|
||||
dev_write(dev, FC_SPDVENDORNAME0 + (i*4), data[i]);
|
||||
}
|
||||
|
||||
void fc_spd_ProductName(hdmi_tx_dev_t *dev, const u8 *data,
|
||||
unsigned short length)
|
||||
{
|
||||
unsigned short i = 0;
|
||||
|
||||
LOG_TRACE();
|
||||
for (i = 0; i < length; i++)
|
||||
dev_write(dev, FC_SPDPRODUCTNAME0 + (i*4), data[i]);
|
||||
}
|
||||
|
||||
void fc_spd_SourceDeviceInfo(hdmi_tx_dev_t *dev, u8 code)
|
||||
{
|
||||
LOG_TRACE1(code);
|
||||
dev_write(dev, FC_SPDDEVICEINF, code);
|
||||
}
|
||||
|
||||
int fc_spd_config(hdmi_tx_dev_t *dev, fc_spd_info_t *spd_data)
|
||||
{
|
||||
const unsigned short pSize = 8;
|
||||
const unsigned short vSize = 16;
|
||||
|
||||
LOG_TRACE();
|
||||
|
||||
if (spd_data == NULL) {
|
||||
HDMI_ERROR_MSG("Improper argument: spd_data\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fc_packets_AutoSend(dev, 0, SPD_TX);/*prevent sending half the info.*/
|
||||
|
||||
if (spd_data->vName == 0) {
|
||||
// error_set(ERR_INVALID_PARAM_VENDOR_NAME);
|
||||
HDMI_ERROR_MSG("invalid parameter\n");
|
||||
return FALSE;
|
||||
}
|
||||
if (spd_data->vLength > vSize) {
|
||||
spd_data->vLength = vSize;
|
||||
HDMI_INFO_MSG("vendor name truncated\n");
|
||||
}
|
||||
if (spd_data->pName == 0) {
|
||||
// error_set(ERR_INVALID_PARAM_PRODUCT_NAME);
|
||||
HDMI_ERROR_MSG("invalid parameter\n");
|
||||
return FALSE;
|
||||
}
|
||||
if (spd_data->pLength > pSize) {
|
||||
spd_data->pLength = pSize;
|
||||
HDMI_INFO_MSG("product name truncated\n");
|
||||
}
|
||||
|
||||
fc_spd_VendorName(dev, spd_data->vName, spd_data->vLength);
|
||||
fc_spd_ProductName(dev, spd_data->pName, spd_data->pLength);
|
||||
|
||||
fc_spd_SourceDeviceInfo(dev, spd_data->code);
|
||||
|
||||
if (spd_data->autoSend)
|
||||
fc_packets_AutoSend(dev, spd_data->autoSend, SPD_TX);
|
||||
else
|
||||
fc_packets_ManualSend(dev, SPD_TX);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void fc_vsd_vendor_OUI(hdmi_tx_dev_t *dev, u32 id)
|
||||
{
|
||||
LOG_TRACE1(id);
|
||||
dev_write(dev, (FC_VSDIEEEID0), id);
|
||||
dev_write(dev, (FC_VSDIEEEID1), id >> 8);
|
||||
dev_write(dev, (FC_VSDIEEEID2), id >> 16);
|
||||
}
|
||||
|
||||
u8 fc_vsd_vendor_payload(hdmi_tx_dev_t *dev, const u8 *data,
|
||||
unsigned short length)
|
||||
{
|
||||
const unsigned short size = 24;
|
||||
unsigned i = 0;
|
||||
|
||||
LOG_TRACE();
|
||||
if (data == 0) {
|
||||
HDMI_INFO_MSG("invalid parameter\n");
|
||||
return -1;
|
||||
}
|
||||
if (length > size) {
|
||||
length = size;
|
||||
HDMI_INFO_MSG("vendor payload truncated\n");
|
||||
}
|
||||
for (i = 0; i < length; i++)
|
||||
dev_write(dev, (FC_VSDPAYLOAD0 + (i*4)), data[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fc_vsif_enable(hdmi_tx_dev_t *dev, u8 enable)
|
||||
{
|
||||
dev_write_mask(dev, FC_PACKET_TX_EN, FC_PACKET_TX_EN_AUT_TX_EN_MASK, enable);
|
||||
}
|
||||
|
||||
int packets_Initialize(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
LOG_TRACE();
|
||||
packets_DisableAllPackets(dev);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*packets configure is the same as infoframe configure*/
|
||||
int packets_Configure(hdmi_tx_dev_t *dev, videoParams_t *video,
|
||||
productParams_t *prod)
|
||||
{
|
||||
u32 oui = 0;
|
||||
u8 struct_3d = 0;
|
||||
u8 data[3];
|
||||
u8 *vendor_payload = prod->mVendorPayload;
|
||||
u8 payload_length = prod->mVendorPayloadLength;
|
||||
|
||||
LOG_TRACE();
|
||||
|
||||
if (dev->snps_hdmi_ctrl.hdmi_on == 0) {
|
||||
printf("DVI mode selected: packets not configured\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (video->mHdmiVideoFormat == 2) {
|
||||
struct_3d = video->m3dStructure;
|
||||
HDMI_INFO_MSG("3D packets configure\n");
|
||||
|
||||
/* frame packing || tab || sbs */
|
||||
if ((struct_3d == 0) || (struct_3d == 6) || (struct_3d == 8)) {
|
||||
data[0] = video->mHdmiVideoFormat << 5; /* PB4 */
|
||||
data[1] = struct_3d << 4; /* PB5 */
|
||||
data[2] = video->m3dExtData << 4;
|
||||
/* HDMI Licensing, LLC */
|
||||
packets_VendorSpecificInfoFrame(dev, 0x000C03, data,
|
||||
sizeof(data), 1);
|
||||
fc_vsif_enable(dev, 1);
|
||||
} else {
|
||||
//error_set(ERR_3D_STRUCT_NOT_SUPPORTED);
|
||||
HDMI_ERROR_MSG("3D structure not supported %d\n",
|
||||
struct_3d);
|
||||
return FALSE;
|
||||
}
|
||||
} else if ((video->mHdmiVideoFormat == 0x1) || (video->mHdmiVideoFormat == 0x0)) {
|
||||
if (prod != 0) {
|
||||
fc_spd_info_t spd_data;
|
||||
|
||||
spd_data.vName = prod->mVendorName;
|
||||
spd_data.vLength = prod->mVendorNameLength;
|
||||
spd_data.pName = prod->mProductName;
|
||||
spd_data.pLength = prod->mProductNameLength;
|
||||
spd_data.code = prod->mSourceType;
|
||||
spd_data.autoSend = 1;
|
||||
|
||||
oui = prod->mOUI;
|
||||
fc_spd_config(dev, &spd_data);
|
||||
packets_VendorSpecificInfoFrame(dev, oui, vendor_payload,
|
||||
payload_length, 1);
|
||||
fc_vsif_enable(dev, 1);
|
||||
} else {
|
||||
HDMI_INFO_MSG("No product info provided: not configured\n");
|
||||
}
|
||||
} else {
|
||||
printf("error: unknow video format\n");
|
||||
fc_vsif_enable(dev, 0);
|
||||
}
|
||||
|
||||
fc_packets_metadata_config(dev);
|
||||
|
||||
/* default phase 1 = true */
|
||||
dev_write_mask(dev, FC_GCP, FC_GCP_DEFAULT_PHASE_MASK,
|
||||
((video->mPixelPackingDefaultPhase == 1) ? 1 : 0));
|
||||
|
||||
fc_gamut_config(dev);
|
||||
|
||||
fc_avi_config(dev, video);
|
||||
|
||||
/** Colorimetry */
|
||||
packets_colorimetry_config(dev, video);
|
||||
|
||||
if (video->mHdr) {
|
||||
HDMI_INFO_MSG("Is HDR video format\n");
|
||||
fc_drm_up(dev, &video->pb);
|
||||
} else {
|
||||
fc_drm_disable(dev);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void packets_AudioContentProtection(hdmi_tx_dev_t *dev, u8 type,
|
||||
const u8 *fields, u8 length, u8 autoSend)
|
||||
{
|
||||
u8 newFields[ACP_PACKET_SIZE];
|
||||
u16 i = 0;
|
||||
/* LOG_TRACE(); */
|
||||
fc_packets_AutoSend(dev, 0, ACP_TX);
|
||||
|
||||
fc_acp_type(dev, type);
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
newFields[i] = fields[i];
|
||||
|
||||
if (length < ACP_PACKET_SIZE) {
|
||||
for (i = length; i < ACP_PACKET_SIZE; i++)
|
||||
newFields[i] = 0; /* Padding */
|
||||
|
||||
length = ACP_PACKET_SIZE;
|
||||
}
|
||||
fc_acp_type_dependent_fields(dev, newFields, length);
|
||||
if (!autoSend)
|
||||
fc_packets_ManualSend(dev, ACP_TX);
|
||||
else
|
||||
fc_packets_AutoSend(dev, autoSend, ACP_TX);
|
||||
|
||||
}
|
||||
|
||||
void packets_IsrcPackets(hdmi_tx_dev_t *dev, u8 initStatus,
|
||||
const u8 *codes, u8 length, u8 autoSend)
|
||||
{
|
||||
u16 i = 0;
|
||||
u8 newCodes[ISRC_PACKET_SIZE * 2];
|
||||
|
||||
LOG_TRACE();
|
||||
|
||||
fc_packets_AutoSend(dev, 0, ISRC1_TX);
|
||||
fc_packets_AutoSend(dev, 0, ISRC2_TX);
|
||||
|
||||
fc_isrc_status(dev, initStatus);
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
newCodes[i] = codes[i];
|
||||
|
||||
if (length > ISRC_PACKET_SIZE) {
|
||||
for (i = length; i < (ISRC_PACKET_SIZE * 2); i++)
|
||||
newCodes[i] = 0; /* Padding */
|
||||
|
||||
length = (ISRC_PACKET_SIZE * 2);
|
||||
|
||||
fc_isrc_isrc2_codes(dev, newCodes +
|
||||
(ISRC_PACKET_SIZE * sizeof(u8)),
|
||||
length - ISRC_PACKET_SIZE);
|
||||
fc_isrc_cont(dev, 1);
|
||||
|
||||
fc_packets_AutoSend(dev, autoSend, ISRC2_TX);
|
||||
|
||||
if (!autoSend)
|
||||
fc_packets_ManualSend(dev, ISRC2_TX);
|
||||
|
||||
}
|
||||
if (length < ISRC_PACKET_SIZE) {
|
||||
for (i = length; i < ISRC_PACKET_SIZE; i++)
|
||||
newCodes[i] = 0; /* Padding */
|
||||
|
||||
|
||||
length = ISRC_PACKET_SIZE;
|
||||
|
||||
fc_isrc_cont(dev, 0);
|
||||
}
|
||||
|
||||
fc_isrc_isrc1_codes(dev, newCodes, length); /* first part only */
|
||||
fc_isrc_valid(dev, 1);
|
||||
|
||||
fc_packets_AutoSend(dev, autoSend, ISRC1_TX);
|
||||
|
||||
if (!autoSend)
|
||||
fc_packets_ManualSend(dev, ISRC1_TX);
|
||||
}
|
||||
|
||||
void packets_AvMute(hdmi_tx_dev_t *dev, u8 enable)
|
||||
{
|
||||
LOG_TRACE1(enable);
|
||||
dev_write_mask(dev, FC_GCP, FC_GCP_SET_AVMUTE_MASK, (enable ? 1 : 0));
|
||||
dev_write_mask(dev, FC_GCP, FC_GCP_CLEAR_AVMUTE_MASK, (enable ? 0 : 1));
|
||||
}
|
||||
|
||||
void packets_IsrcStatus(hdmi_tx_dev_t *dev, u8 status)
|
||||
{
|
||||
LOG_TRACE();
|
||||
fc_isrc_status(dev, status);
|
||||
}
|
||||
|
||||
void packets_StopSendAcp(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
LOG_TRACE();
|
||||
fc_packets_AutoSend(dev, 0, ACP_TX);
|
||||
}
|
||||
|
||||
void packets_StopSendIsrc1(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
LOG_TRACE();
|
||||
fc_packets_AutoSend(dev, 0, ISRC1_TX);
|
||||
fc_packets_AutoSend(dev, 0, ISRC2_TX);
|
||||
}
|
||||
|
||||
void packets_StopSendIsrc2(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
LOG_TRACE();
|
||||
fc_isrc_cont(dev, 0);
|
||||
fc_packets_AutoSend(dev, 0, ISRC2_TX);
|
||||
}
|
||||
|
||||
void packets_StopSendSpd(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
LOG_TRACE();
|
||||
fc_packets_AutoSend(dev, 0, SPD_TX);
|
||||
}
|
||||
|
||||
void packets_StopSendVsd(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
LOG_TRACE();
|
||||
fc_packets_AutoSend(dev, 0, VSD_TX);
|
||||
}
|
||||
|
||||
void packets_DisableAllPackets(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
LOG_TRACE();
|
||||
fc_packets_disable_all(dev);
|
||||
}
|
||||
|
||||
int packets_VendorSpecificInfoFrame(hdmi_tx_dev_t *dev, u32 oui,
|
||||
const u8 *payload, u8 length, u8 autoSend)
|
||||
{
|
||||
LOG_TRACE();
|
||||
fc_packets_AutoSend(dev, 0, VSD_TX);/*prevent sending half the info.*/
|
||||
fc_vsd_vendor_OUI(dev, oui);
|
||||
if (fc_vsd_vendor_payload(dev, payload, length))
|
||||
return FALSE; /* DEFINE ERROR */
|
||||
|
||||
if (autoSend)
|
||||
fc_packets_AutoSend(dev, autoSend, VSD_TX);
|
||||
else
|
||||
fc_packets_ManualSend(dev, VSD_TX);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
/*
|
||||
u8 packets_AudioMetaDataPacket(hdmi_tx_dev_t *dev,
|
||||
audioMetaDataPacket_t *audioMetaDataPckt)
|
||||
{
|
||||
halAudioMultistream_MetaDataPacket_Header(dev, audioMetaDataPckt);
|
||||
halAudioMultistream_MetaDataPacketBody(dev, audioMetaDataPckt);
|
||||
return TRUE;
|
||||
}*/
|
||||
|
||||
void packets_colorimetry_config(hdmi_tx_dev_t *dev, videoParams_t *video)
|
||||
{
|
||||
u8 gamut_metadata[28] = {0};
|
||||
int gdb_color_space = 0;
|
||||
|
||||
fc_gamut_enable_tx(dev, 0);
|
||||
|
||||
if (video->mColorimetry == EXTENDED_COLORIMETRY) {
|
||||
if (video->mExtColorimetry == XV_YCC601) {
|
||||
gdb_color_space = 1;
|
||||
} else if (video->mExtColorimetry == XV_YCC709) {
|
||||
gdb_color_space = 2;
|
||||
HDMI_INFO_MSG("xv ycc709\n");
|
||||
} else if (video->mExtColorimetry == S_YCC601) {
|
||||
gdb_color_space = 3;
|
||||
} else if (video->mExtColorimetry == ADOBE_YCC601) {
|
||||
gdb_color_space = 3;
|
||||
} else if (video->mExtColorimetry == ADOBE_RGB) {
|
||||
gdb_color_space = 3;
|
||||
}
|
||||
|
||||
if (video->mColorimetryDataBlock == TRUE) {
|
||||
gamut_metadata[0] = (1 << 7) | gdb_color_space;
|
||||
fc_gamut_packet_config(dev, gamut_metadata,
|
||||
(sizeof(gamut_metadata) / sizeof(u8)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fc_drm_up(hdmi_tx_dev_t *dev, fc_drm_pb_t *pb)
|
||||
{
|
||||
int timeout = 10;
|
||||
u32 status = 0;
|
||||
|
||||
/*Configure Dynamic Range and Mastering infoFrame*/
|
||||
if (pb != 0) {
|
||||
dev_write(dev, FC_DRM_PB0, pb->eotf & 0x07);
|
||||
dev_write(dev, FC_DRM_PB1, pb->metadata & 0x07);
|
||||
dev_write(dev, FC_DRM_PB2, (pb->r_x >> 0) & 0xff);
|
||||
dev_write(dev, FC_DRM_PB3, (pb->r_x >> 8) & 0xff);
|
||||
dev_write(dev, FC_DRM_PB4, (pb->r_y >> 0) & 0xff);
|
||||
dev_write(dev, FC_DRM_PB5, (pb->r_y >> 8) & 0xff);
|
||||
dev_write(dev, FC_DRM_PB6, (pb->g_x >> 0) & 0xff);
|
||||
dev_write(dev, FC_DRM_PB7, (pb->g_x >> 8) & 0xff);
|
||||
dev_write(dev, FC_DRM_PB8, (pb->g_y >> 0) & 0xff);
|
||||
dev_write(dev, FC_DRM_PB9, (pb->g_y >> 8) & 0xff);
|
||||
dev_write(dev, FC_DRM_PB10, (pb->b_x >> 0) & 0xff);
|
||||
dev_write(dev, FC_DRM_PB11, (pb->b_x >> 8) & 0xff);
|
||||
dev_write(dev, FC_DRM_PB12, (pb->b_y >> 0) & 0xff);
|
||||
dev_write(dev, FC_DRM_PB13, (pb->b_y >> 8) & 0xff);
|
||||
dev_write(dev, FC_DRM_PB14, (pb->w_x >> 0) & 0xff);
|
||||
dev_write(dev, FC_DRM_PB15, (pb->w_x >> 8) & 0xff);
|
||||
dev_write(dev, FC_DRM_PB16, (pb->w_y >> 0) & 0xff);
|
||||
dev_write(dev, FC_DRM_PB17, (pb->w_y >> 8) & 0xff);
|
||||
dev_write(dev, FC_DRM_PB18, (pb->luma_max >> 0) & 0xff);
|
||||
dev_write(dev, FC_DRM_PB19, (pb->luma_max >> 8) & 0xff);
|
||||
dev_write(dev, FC_DRM_PB20, (pb->luma_min >> 0) & 0xff);
|
||||
dev_write(dev, FC_DRM_PB21, (pb->luma_min >> 8) & 0xff);
|
||||
dev_write(dev, FC_DRM_PB22, (pb->mcll >> 0) & 0xff);
|
||||
dev_write(dev, FC_DRM_PB23, (pb->mcll >> 8) & 0xff);
|
||||
dev_write(dev, FC_DRM_PB24, (pb->mfll >> 0) & 0xff);
|
||||
dev_write(dev, FC_DRM_PB25, (pb->mfll >> 8) & 0xff);
|
||||
}
|
||||
dev_write_mask(dev, FC_DRM_HB0, FC_DRM_UP_FC_DRM_HB_MASK, 0x01);
|
||||
dev_write_mask(dev, FC_DRM_HB1, FC_DRM_UP_FC_DRM_HB_MASK, 26);
|
||||
dev_write_mask(dev, FC_PACKET_TX_EN, FC_PACKET_TX_EN_DRM_TX_EN_MASK, 0x1);
|
||||
do {
|
||||
snps_sleep(10);
|
||||
status = dev_read_mask(dev, FC_DRM_UP, FC_DRM_UP_DRMPACKETUPDATE_MASK);
|
||||
} while (status && (timeout--));
|
||||
dev_write_mask(dev, FC_DRM_UP, FC_DRM_UP_DRMPACKETUPDATE_MASK, 0x1);
|
||||
}
|
||||
|
||||
void fc_drm_disable(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
dev_write_mask(dev, FC_PACKET_TX_EN, FC_PACKET_TX_EN_DRM_TX_EN_MASK, 0x0);
|
||||
}
|
||||
|
||||
void fc_VideoCode_set(hdmi_tx_dev_t *dev, u8 data)
|
||||
{
|
||||
LOG_TRACE();
|
||||
return dev_write_mask(dev, FC_AVIVID, FC_AVIVID_FC_AVIVID_MASK, data);
|
||||
}
|
||||
|
||||
/*
|
||||
* get vsif data
|
||||
* data[0]: hdmi_format filed in vsif
|
||||
* data[1]: hdmi_vic or 3d strcture filed in vsif
|
||||
*/
|
||||
void fc_vsif_get(hdmi_tx_dev_t *dev, u8 *data)
|
||||
{
|
||||
data[0] = dev_read(dev, FC_VSDPAYLOAD0);
|
||||
data[1] = dev_read(dev, FC_VSDPAYLOAD0 + 0x4);
|
||||
}
|
||||
|
||||
/*
|
||||
* set vsif data
|
||||
* data[0]: hdmi_format filed in vsif
|
||||
* data[1]: hdmi_vic or 3d strcture filed in vsif
|
||||
*/
|
||||
void fc_vsif_set(hdmi_tx_dev_t *dev, u8 *data)
|
||||
{
|
||||
dev_write(dev, FC_VSDPAYLOAD0, data[0]);
|
||||
dev_write(dev, FC_VSDPAYLOAD0 + 0x4, data[1]);
|
||||
}
|
||||
266
sunxi_spl/display/hdmi/packets.h
Executable file
266
sunxi_spl/display/hdmi/packets.h
Executable file
@@ -0,0 +1,266 @@
|
||||
/*
|
||||
* Allwinner SoCs hdmi2.0 driver.
|
||||
*
|
||||
* Copyright (C) 2016 Allwinner.
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef PACKETS_H_
|
||||
#define PACKETS_H_
|
||||
|
||||
|
||||
#include "video.h"
|
||||
#include "phy.h"
|
||||
#include "frame_composer_reg.h"
|
||||
#include "hdmitx_dev.h"
|
||||
|
||||
|
||||
#define ACP_TX 0
|
||||
#define ISRC1_TX 1
|
||||
#define ISRC2_TX 2
|
||||
#define SPD_TX 4
|
||||
#define VSD_TX 3
|
||||
|
||||
typedef struct {
|
||||
/* Vendor Name of eight 7-bit ASCII characters */
|
||||
u8 mVendorName[8];
|
||||
|
||||
u8 mVendorNameLength;
|
||||
|
||||
/* Product name or description,
|
||||
consists of sixteen 7-bit ASCII characters */
|
||||
u8 mProductName[16];
|
||||
|
||||
u8 mProductNameLength;
|
||||
|
||||
/* Code that classifies the source device (CEA Table 15) */
|
||||
u8 mSourceType;
|
||||
|
||||
/* oui 24 bit IEEE Registration Identifier */
|
||||
u32 mOUI;
|
||||
|
||||
u8 mVendorPayload[24];
|
||||
|
||||
u8 mVendorPayloadLength;
|
||||
|
||||
} productParams_t;
|
||||
|
||||
typedef struct fc_spd_info {
|
||||
const u8 *vName;
|
||||
u8 vLength;
|
||||
const u8 *pName;
|
||||
u8 pLength;
|
||||
u8 code;
|
||||
u8 autoSend;
|
||||
} fc_spd_info_t;
|
||||
|
||||
void fc_drm_up(hdmi_tx_dev_t *dev, fc_drm_pb_t *pb);
|
||||
void fc_acp_type(hdmi_tx_dev_t *dev, u8 type);
|
||||
void fc_acp_type_dependent_fields(hdmi_tx_dev_t *dev,
|
||||
u8 *fields, u8 fieldsLength);
|
||||
|
||||
void fc_avi_config(hdmi_tx_dev_t *dev, videoParams_t *videoParams);
|
||||
|
||||
void fc_gamut_config(hdmi_tx_dev_t *dev);
|
||||
void fc_gamut_packet_config(hdmi_tx_dev_t *dev,
|
||||
const u8 *gbdContent, u8 length);
|
||||
|
||||
/*
|
||||
* Configure the ISRC packet status
|
||||
* @param code
|
||||
* 001 - Starting Position
|
||||
* 010 - Intermediate Position
|
||||
* 100 - Ending Position
|
||||
* @param baseAddr block base address
|
||||
*/
|
||||
void fc_isrc_status(hdmi_tx_dev_t *dev, u8 code);
|
||||
|
||||
/*
|
||||
* Configure the validity bit in the ISRC packets
|
||||
* @param validity: 1 if valid
|
||||
* @param baseAddr block base address
|
||||
*/
|
||||
void fc_isrc_valid(hdmi_tx_dev_t *dev, u8 validity);
|
||||
|
||||
/*
|
||||
* Configure the cont bit in the ISRC1 packets
|
||||
* When a subsequent ISRC2 Packet is transmitted,
|
||||
* the ISRC_Cont field shall be set and shall be clear otherwise.
|
||||
* @param isContinued 1 when set
|
||||
* @param baseAddr block base address
|
||||
*/
|
||||
void fc_isrc_cont(hdmi_tx_dev_t *dev, u8 isContinued);
|
||||
|
||||
/*
|
||||
* Configure the ISRC 1 Codes
|
||||
* @param codes
|
||||
* @param length
|
||||
* @param baseAddr block base address
|
||||
*/
|
||||
void fc_isrc_isrc1_codes(hdmi_tx_dev_t *dev, u8 *codes, u8 length);
|
||||
|
||||
/*
|
||||
* Configure the ISRC 2 Codes
|
||||
* @param codes
|
||||
* @param length
|
||||
* @param baseAddr block base address
|
||||
*/
|
||||
void fc_isrc_isrc2_codes(hdmi_tx_dev_t *dev, u8 *codes, u8 length);
|
||||
|
||||
|
||||
|
||||
void fc_packets_metadata_config(hdmi_tx_dev_t *dev);
|
||||
void fc_packets_AutoSend(hdmi_tx_dev_t *dev, u8 enable, u8 mask);
|
||||
void fc_packets_ManualSend(hdmi_tx_dev_t *dev, u8 mask);
|
||||
void fc_packets_disable_all(hdmi_tx_dev_t *dev);
|
||||
|
||||
|
||||
int fc_spd_config(hdmi_tx_dev_t *dev, fc_spd_info_t *spd_data);
|
||||
|
||||
/*
|
||||
* Configure the 24 bit IEEE Registration Identifier
|
||||
* @param baseAddr Block base address
|
||||
* @param id vendor unique identifier
|
||||
*/
|
||||
void fc_vsd_vendor_OUI(hdmi_tx_dev_t *dev, u32 id);
|
||||
|
||||
/*
|
||||
* Configure the Vendor Payload to be carried by the InfoFrame
|
||||
* @param info array
|
||||
* @param length of the array
|
||||
* @return 0 when successful and 1 on error
|
||||
*/
|
||||
u8 fc_vsd_vendor_payload(hdmi_tx_dev_t *dev,
|
||||
const u8 *data, unsigned short length);
|
||||
void fc_vsif_enable(hdmi_tx_dev_t *dev, u8 enable);
|
||||
/**
|
||||
* Initialize the packets package. Reset local variables.
|
||||
* @param dev Device structure
|
||||
* @return TRUE when successful
|
||||
*/
|
||||
int packets_Initialize(hdmi_tx_dev_t *dev);
|
||||
|
||||
/**
|
||||
* Configure Source Product Description, Vendor Specific and Auxiliary
|
||||
* Video InfoFrames.
|
||||
* @param dev Device structure
|
||||
* @param video Video Parameters to set up AVI InfoFrame (and all
|
||||
* other video parameters)
|
||||
* @param prod Description of Vendor and Product to set up Vendor
|
||||
* Specific InfoFrame and Source Product Description InfoFrame
|
||||
* @return TRUE when successful
|
||||
*/
|
||||
int packets_Configure(hdmi_tx_dev_t *dev, videoParams_t *video,
|
||||
productParams_t *prod);
|
||||
|
||||
/**
|
||||
* Configure Audio Content Protection packets.
|
||||
* @param type Content protection type (see HDMI1.3a Section 9.3)
|
||||
* @param fields ACP Type Dependent Fields
|
||||
* @param length of the ACP fields
|
||||
* @param autoSend Send Packets Automatically
|
||||
*/
|
||||
void packets_AudioContentProtection(hdmi_tx_dev_t *dev, u8 type,
|
||||
const u8 *fields, u8 length, u8 autoSend);
|
||||
|
||||
/**
|
||||
* Configure ISRC 1 & 2 Packets
|
||||
* @param dev Device structure
|
||||
* @param initStatus Initial status
|
||||
* which the packets are sent with (usually starting position)
|
||||
* @param codes ISRC codes array
|
||||
* @param length of the ISRC codes array
|
||||
* @param autoSend Send ISRC Automatically
|
||||
* @note Automatic sending does not change status automatically,
|
||||
* it does the insertion of the packets in the data
|
||||
* islands.
|
||||
*/
|
||||
void packets_IsrcPackets(hdmi_tx_dev_t *dev, u8 initStatus, const u8 *codes,
|
||||
u8 length, u8 autoSend);
|
||||
|
||||
/**
|
||||
* Send/stop sending AV Mute in the General Control Packet
|
||||
* @param dev Device structure
|
||||
* @param enable (TRUE) /disable (FALSE) the AV Mute
|
||||
*/
|
||||
void packets_AvMute(hdmi_tx_dev_t *dev, u8 enable);
|
||||
|
||||
/**
|
||||
* Set ISRC status that is changing during play back
|
||||
* depending on position (see HDMI 1.3a Section 8.8)
|
||||
* @param dev Device structure
|
||||
* @param status the ISRC status code according to position of track
|
||||
*/
|
||||
void packets_IsrcStatus(hdmi_tx_dev_t *dev, u8 status);
|
||||
|
||||
|
||||
/**
|
||||
* Stop sending ACP packets when in auto send mode
|
||||
* @param dev Device structure
|
||||
*/
|
||||
void packets_StopSendAcp(hdmi_tx_dev_t *dev);
|
||||
|
||||
/**
|
||||
* Stop sending ISRC 1 & 2 packets when in auto send mode
|
||||
* (ISRC 2 packets cannot be send without ISRC 1)
|
||||
* @param dev Device structure
|
||||
*/
|
||||
void packets_StopSendIsrc1(hdmi_tx_dev_t *dev);
|
||||
|
||||
/**
|
||||
* Stop sending ISRC 2 packets when in auto send mode
|
||||
* @param dev Device structure
|
||||
*/
|
||||
void packets_StopSendIsrc2(hdmi_tx_dev_t *dev);
|
||||
|
||||
/**
|
||||
* Stop sending Source Product Description InfoFrame packets
|
||||
* when in auto send mode
|
||||
* @param dev Device structure
|
||||
*/
|
||||
void packets_StopSendSpd(hdmi_tx_dev_t *dev);
|
||||
|
||||
/**
|
||||
* Stop sending Vendor Specific InfoFrame packets when in auto send mode
|
||||
* @param dev Device structure
|
||||
*/
|
||||
void packets_StopSendVsd(hdmi_tx_dev_t *dev);
|
||||
|
||||
/**
|
||||
* Disable all metadata packets from being sent automatically.
|
||||
* (ISRC 1& 2, ACP, VSD and SPD)
|
||||
* @param dev Device structure
|
||||
*/
|
||||
void packets_DisableAllPackets(hdmi_tx_dev_t *dev);
|
||||
|
||||
/**
|
||||
* Configure Vendor Specific InfoFrames.
|
||||
* @param dev Device structure
|
||||
* @param oui Vendor Organisational Unique Identifier 24 bit IEEE
|
||||
* Registration Identifier
|
||||
* @param payload Vendor Specific Info Payload
|
||||
* @param length of the payload array
|
||||
* @param autoSend Start send Vendor Specific InfoFrame automatically
|
||||
*/
|
||||
int packets_VendorSpecificInfoFrame(hdmi_tx_dev_t *dev, u32 oui,
|
||||
const u8 *payload, u8 length, u8 autoSend);
|
||||
|
||||
/**
|
||||
* Configure Colorimetry packets
|
||||
* @param dev Device structure
|
||||
* @param video Video information structure
|
||||
*/
|
||||
void packets_colorimetry_config(hdmi_tx_dev_t *dev, videoParams_t *video);
|
||||
|
||||
u8 fc_Colorimetry_get(hdmi_tx_dev_t *dev);
|
||||
u8 fc_RgbYcc_get(hdmi_tx_dev_t *dev);
|
||||
u8 fc_VideoCode_get(hdmi_tx_dev_t *dev);
|
||||
void fc_VideoCode_set(hdmi_tx_dev_t *dev, u8 data);
|
||||
void fc_vsif_get(hdmi_tx_dev_t *dev, u8 *data);
|
||||
void fc_vsif_set(hdmi_tx_dev_t *dev, u8 *data);
|
||||
|
||||
#endif /* PACKETS_H_ */
|
||||
877
sunxi_spl/display/hdmi/phy.c
Executable file
877
sunxi_spl/display/hdmi/phy.c
Executable file
@@ -0,0 +1,877 @@
|
||||
/*
|
||||
* Allwinner SoCs hdmi2.0 driver.
|
||||
*
|
||||
* Copyright (C) 2016 Allwinner.
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#include "phy.h"
|
||||
#include "main_controller.h"
|
||||
#include "irq.h"
|
||||
|
||||
#define I2C_TIMEOUT 100
|
||||
|
||||
static void phy_interrupt_mask(hdmi_tx_dev_t *dev, u8 mask);
|
||||
static int phy_phase_lock_loop_state(hdmi_tx_dev_t *dev);
|
||||
static int phy_slave_address(hdmi_tx_dev_t *dev, u8 value);
|
||||
static int phy_reconfigure_interface(hdmi_tx_dev_t *dev);
|
||||
|
||||
|
||||
static void phy_power_down(hdmi_tx_dev_t *dev, u8 bit)
|
||||
{
|
||||
LOG_TRACE1(bit);
|
||||
dev_write_mask(dev, PHY_CONF0, PHY_CONF0_SPARES_2_MASK, (bit ? 1 : 0));
|
||||
}
|
||||
|
||||
static void phy_enable_tmds(hdmi_tx_dev_t *dev, u8 bit)
|
||||
{
|
||||
LOG_TRACE1(bit);
|
||||
dev_write_mask(dev, PHY_CONF0, PHY_CONF0_SPARES_1_MASK, (bit ? 1 : 0));
|
||||
}
|
||||
|
||||
static void phy_gen2_pddq(hdmi_tx_dev_t *dev, u8 bit)
|
||||
{
|
||||
LOG_TRACE1(bit);
|
||||
dev_write_mask(dev, PHY_CONF0, PHY_CONF0_PDDQ_MASK, (bit ? 1 : 0));
|
||||
}
|
||||
|
||||
static void phy_gen2_tx_power_on(hdmi_tx_dev_t *dev, u8 bit)
|
||||
{
|
||||
LOG_TRACE1(bit);
|
||||
dev_write_mask(dev, PHY_CONF0, PHY_CONF0_TXPWRON_MASK, (bit ? 1 : 0));
|
||||
}
|
||||
|
||||
static void phy_gen2_en_hpd_rx_sense(hdmi_tx_dev_t *dev, u8 bit)
|
||||
{
|
||||
LOG_TRACE1(bit);
|
||||
dev_write_mask(dev, PHY_CONF0, PHY_CONF0_ENHPDRXSENSE_MASK,
|
||||
(bit ? 1 : 0));
|
||||
}
|
||||
|
||||
static void phy_i2c_slave_address(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write_mask(dev, PHY_I2CM_SLAVE,
|
||||
PHY_I2CM_SLAVE_SLAVEADDR_MASK, value);
|
||||
}
|
||||
|
||||
int phy_i2c_write(hdmi_tx_dev_t *dev, u8 addr, u16 data)
|
||||
{
|
||||
int timeout = PHY_TIMEOUT;
|
||||
u32 status = 0;
|
||||
|
||||
LOG_TRACE2(data, addr);
|
||||
|
||||
/* Set address */
|
||||
dev_write(dev, PHY_I2CM_ADDRESS, addr);
|
||||
|
||||
/* Set value */
|
||||
dev_write(dev, PHY_I2CM_DATAO_1, (u8) ((data >> 8) & 0xFF));
|
||||
dev_write(dev, PHY_I2CM_DATAO_0, (u8) (data & 0xFF));
|
||||
|
||||
dev_write(dev, PHY_I2CM_OPERATION, PHY_I2CM_OPERATION_WR_MASK);
|
||||
|
||||
do {
|
||||
snps_sleep(10);
|
||||
status = dev_read_mask(dev, IH_I2CMPHY_STAT0,
|
||||
IH_I2CMPHY_STAT0_I2CMPHYERROR_MASK |
|
||||
IH_I2CMPHY_STAT0_I2CMPHYDONE_MASK);
|
||||
} while (status == 0 && (timeout--));
|
||||
|
||||
dev_write(dev, IH_I2CMPHY_STAT0, status); /* clear read status */
|
||||
|
||||
if (status & IH_I2CMPHY_STAT0_I2CMPHYERROR_MASK) {
|
||||
HDMI_ERROR_MSG(" I2C PHY write failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (status & IH_I2CMPHY_STAT0_I2CMPHYDONE_MASK)
|
||||
return 0;
|
||||
|
||||
HDMI_ERROR_MSG(" ASSERT I2C Write timeout - check PHY - exiting\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int phy_i2c_read(hdmi_tx_dev_t *dev, u8 addr, u16 *value)
|
||||
{
|
||||
int timeout = PHY_TIMEOUT;
|
||||
u32 status = 0;
|
||||
|
||||
/* Set address */
|
||||
dev_write(dev, PHY_I2CM_ADDRESS, addr);
|
||||
|
||||
dev_write(dev, PHY_I2CM_OPERATION, PHY_I2CM_OPERATION_RD_MASK);
|
||||
|
||||
do {
|
||||
snps_sleep(10);
|
||||
status = dev_read_mask(dev, IH_I2CMPHY_STAT0,
|
||||
IH_I2CMPHY_STAT0_I2CMPHYERROR_MASK |
|
||||
IH_I2CMPHY_STAT0_I2CMPHYDONE_MASK);
|
||||
} while (status == 0 && (timeout--));
|
||||
|
||||
dev_write(dev, IH_I2CMPHY_STAT0, status); /* clear read status */
|
||||
|
||||
if (status & IH_I2CMPHY_STAT0_I2CMPHYERROR_MASK) {
|
||||
printf(" I2C Read failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (status & IH_I2CMPHY_STAT0_I2CMPHYDONE_MASK) {
|
||||
|
||||
*value = ((u16) (dev_read(dev, (PHY_I2CM_DATAI_1)) << 8)
|
||||
| dev_read(dev, (PHY_I2CM_DATAI_0)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf(" ASSERT I2C Read timeout - check PHY - exiting\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************************
|
||||
* External functions
|
||||
*************************************************************/
|
||||
|
||||
static int phy_write(hdmi_tx_dev_t *dev, u8 addr, u16 data)
|
||||
{
|
||||
//switch (dev->snps_hdmi_ctrl.phy_access) {
|
||||
//case PHY_JTAG:
|
||||
//return phy_jtag_write(dev, addr, data);
|
||||
//case PHY_I2C:
|
||||
return phy_i2c_write(dev, addr, data);
|
||||
//default:
|
||||
// HDMI_INFO_MSG("PHY interface not defined");
|
||||
//}
|
||||
//return -1;
|
||||
}
|
||||
|
||||
static int phy_read(hdmi_tx_dev_t *dev, u8 addr, u16 *value)
|
||||
{
|
||||
//switch (dev->snps_hdmi_ctrl.phy_access) {
|
||||
//case PHY_JTAG:
|
||||
//return phy_jtag_read(dev, addr, value);
|
||||
// case PHY_I2C:
|
||||
return phy_i2c_read(dev, addr, value);
|
||||
//default:
|
||||
//HDMI_INFO_MSG("PHY interface not defined");
|
||||
// }
|
||||
//return -1;
|
||||
}
|
||||
|
||||
|
||||
/*phy301 clock: unit:kHZ*/
|
||||
static struct phy_config phy301[] = {
|
||||
{13500, PIXEL_REPETITION_1, COLOR_DEPTH_8, HDMI_14, 0x133, 0x0, 0x0, 0x4, 0x232, 0x8009},
|
||||
{13500, PIXEL_REPETITION_1, COLOR_DEPTH_10, HDMI_14, 0x2173, 0x0, 0x0, 0x4, 0x232, 0x8009},
|
||||
{13500, PIXEL_REPETITION_1, COLOR_DEPTH_12, HDMI_14, 0x41B3, 0x0, 0x0, 0x4, 0x232, 0x8009},
|
||||
{13500, PIXEL_REPETITION_1, COLOR_DEPTH_16, HDMI_14, 0x6132, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{13500, PIXEL_REPETITION_3, COLOR_DEPTH_8, HDMI_14, 0x132, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{13500, PIXEL_REPETITION_3, COLOR_DEPTH_10, HDMI_14, 0x2172, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{13500, PIXEL_REPETITION_3, COLOR_DEPTH_12, HDMI_14, 0x41B2, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{13500, PIXEL_REPETITION_3, COLOR_DEPTH_16, HDMI_14, 0x6131, 0x18, 0x2, 0x4, 0x232, 0x8009},
|
||||
{13500, PIXEL_REPETITION_7, COLOR_DEPTH_8, HDMI_14, 0x131, 0x18, 0x2, 0x4, 0x232, 0x8009},
|
||||
{13500, PIXEL_REPETITION_7, COLOR_DEPTH_10, HDMI_14, 0x2171, 0x18, 0x2, 0x4, 0x232, 0x8009},
|
||||
{13500, PIXEL_REPETITION_7, COLOR_DEPTH_12, HDMI_14, 0x41B1, 0x18, 0x2, 0x4, 0x232, 0x8009},
|
||||
{13500, PIXEL_REPETITION_7, COLOR_DEPTH_16, HDMI_14, 0x6130, 0x30, 0x3, 0x4, 0x232, 0x8009},
|
||||
{18000, PIXEL_REPETITION_2, COLOR_DEPTH_8, HDMI_14, 0x00F2, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{18000, PIXEL_REPETITION_2, COLOR_DEPTH_10, HDMI_14, 0x2162, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{18000, PIXEL_REPETITION_2, COLOR_DEPTH_12, HDMI_14, 0x41A2, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{18000, PIXEL_REPETITION_2, COLOR_DEPTH_16, HDMI_14, 0x60F1, 0x18, 0x2, 0x4, 0x232, 0x8009},
|
||||
{18000, PIXEL_REPETITION_5, COLOR_DEPTH_8, HDMI_14, 0x00F1, 0x18, 0x2, 0x4, 0x232, 0x8009},
|
||||
{18000, PIXEL_REPETITION_5, COLOR_DEPTH_10, HDMI_14, 0x2161, 0x18, 0x2, 0x4, 0x232, 0x8009},
|
||||
{18000, PIXEL_REPETITION_5, COLOR_DEPTH_12, HDMI_14, 0x41A1, 0x18, 0x2, 0x4, 0x232, 0x8009},
|
||||
{18000, PIXEL_REPETITION_5, COLOR_DEPTH_16, HDMI_14, 0x60F0, 0x31, 0x3, 0x4, 0x232, 0x8009},
|
||||
{21600, PIXEL_REPETITION_4, COLOR_DEPTH_8, HDMI_14, 0x151, 0x18, 0x2, 0x4, 0x232, 0x8009},
|
||||
{21600, PIXEL_REPETITION_4, COLOR_DEPTH_12, HDMI_14, 0x4161, 0x18, 0x2, 0x4, 0x232, 0x8009},
|
||||
{21600, PIXEL_REPETITION_4, COLOR_DEPTH_16, HDMI_14, 0x6150, 0x31, 0x3, 0x4, 0x232, 0x8009},
|
||||
{21600, PIXEL_REPETITION_9, COLOR_DEPTH_8, HDMI_14, 0x150, 0x31, 0x3, 0x4, 0x232, 0x8009},
|
||||
{21600, PIXEL_REPETITION_9, COLOR_DEPTH_12, HDMI_14, 0x4160, 0x30, 0x3, 0x4, 0x232, 0x8009},
|
||||
{21600, PIXEL_REPETITION_9, COLOR_DEPTH_16, HDMI_20, 0x7B70, 0x001B, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{24000, PIXEL_REPETITION_8, COLOR_DEPTH_8, HDMI_14, 0x00E0, 0x32, 0x3, 0x4, 0x232, 0x8009},
|
||||
{24000, PIXEL_REPETITION_8, COLOR_DEPTH_16, HDMI_20, 0x7BA0, 0x001B, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{25175, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x00B3, 0x0, 0x0, 0x4, 0x232, 0x8009},
|
||||
{25175, PIXEL_REPETITION_OFF, COLOR_DEPTH_10, HDMI_14, 0x2153, 0x0, 0x0, 0x4, 0x232, 0x8009},
|
||||
{25175, PIXEL_REPETITION_OFF, COLOR_DEPTH_12, HDMI_14, 0x40F3, 0x0, 0x0, 0x4, 0x232, 0x8009},
|
||||
{25175, PIXEL_REPETITION_OFF, COLOR_DEPTH_16, HDMI_14, 0x60B2, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{27000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x00B3, 0x12, 0x0, 0x7, 0x2b0, 0x8009},
|
||||
{27000, PIXEL_REPETITION_OFF, COLOR_DEPTH_10, HDMI_14, 0x2153, 0x0, 0x0, 0x4, 0x2b0, 0x8009},
|
||||
{27000, PIXEL_REPETITION_OFF, COLOR_DEPTH_12, HDMI_14, 0x40F3, 0x0, 0x0, 0x4, 0x232, 0x8009},
|
||||
{27000, PIXEL_REPETITION_OFF, COLOR_DEPTH_16, HDMI_14, 0x60B2, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{27000, PIXEL_REPETITION_1, COLOR_DEPTH_8, HDMI_14, 0x00B2, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{27000, PIXEL_REPETITION_1, COLOR_DEPTH_10, HDMI_14, 0x2152, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{27000, PIXEL_REPETITION_1, COLOR_DEPTH_12, HDMI_14, 0x40F2, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{27000, PIXEL_REPETITION_1, COLOR_DEPTH_16, HDMI_14, 0x60B1, 0x19, 0x2, 0x4, 0x232, 0x8009},
|
||||
{27000, PIXEL_REPETITION_3, COLOR_DEPTH_8, HDMI_14, 0x00B1, 0x19, 0x2, 0x4, 0x232, 0x8009},
|
||||
{27000, PIXEL_REPETITION_3, COLOR_DEPTH_10, HDMI_14, 0x2151, 0x18, 0x2, 0x4, 0x232, 0x8009},
|
||||
{27000, PIXEL_REPETITION_3, COLOR_DEPTH_12, HDMI_14, 0x40F1, 0x18, 0x2, 0x4, 0x232, 0x8009},
|
||||
{27000, PIXEL_REPETITION_3, COLOR_DEPTH_16, HDMI_14, 0x60B0, 0x32, 0x3, 0x4, 0x232, 0x8009},
|
||||
{27000, PIXEL_REPETITION_7, COLOR_DEPTH_8, HDMI_14, 0x00B0, 0x32, 0x3, 0x4, 0x232, 0x8009},
|
||||
{27000, PIXEL_REPETITION_7, COLOR_DEPTH_10, HDMI_14, 0x2150, 0x31, 0x3, 0x4, 0x232, 0x8009},
|
||||
{27000, PIXEL_REPETITION_7, COLOR_DEPTH_12, HDMI_14, 0x40F0, 0x31, 0x3, 0x4, 0x232, 0x8009},
|
||||
{27000, PIXEL_REPETITION_7, COLOR_DEPTH_16, HDMI_20, 0x7B30, 0x001B, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{31500, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x00B3, 0x0, 0x0, 0x4, 0x232, 0x8009},
|
||||
{33750, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x00B3, 0x0, 0x0, 0x4, 0x232, 0x8009},
|
||||
{35500, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x00B3, 0x0, 0x0, 0x4, 0x232, 0x8009},
|
||||
{36000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x00B3, 0x0, 0x0, 0x4, 0x232, 0x8009},
|
||||
{36000, PIXEL_REPETITION_2, COLOR_DEPTH_8, HDMI_14, 0x00A1, 0x001A, 0x2, 0x4, 0x232, 0x8009},
|
||||
{36000, PIXEL_REPETITION_2, COLOR_DEPTH_10, HDMI_14, 0x2165, 0x18, 0x2, 0x4, 0x232, 0x8009},
|
||||
{36000, PIXEL_REPETITION_2, COLOR_DEPTH_12, HDMI_14, 0x40E1, 0x19, 0x2, 0x4, 0x232, 0x8009},
|
||||
{36000, PIXEL_REPETITION_2, COLOR_DEPTH_16, HDMI_14, 0x60A0, 0x32, 0x3, 0x4, 0x232, 0x8009},
|
||||
{36000, PIXEL_REPETITION_5, COLOR_DEPTH_8, HDMI_14, 0x00A0, 0x32, 0x3, 0x4, 0x232, 0x8009},
|
||||
{36000, PIXEL_REPETITION_5, COLOR_DEPTH_10, HDMI_14, 0x2164, 0x30, 0x3, 0x4, 0x232, 0x8009},
|
||||
{36000, PIXEL_REPETITION_5, COLOR_DEPTH_12, HDMI_14, 0x40E0, 0x32, 0x3, 0x4, 0x232, 0x8009},
|
||||
{36000, PIXEL_REPETITION_5, COLOR_DEPTH_16, HDMI_20, 0x7AF0, 0x001B, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{40000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x00B3, 0x0, 0x0, 0x4, 0x232, 0x8009},
|
||||
{43200, PIXEL_REPETITION_4, COLOR_DEPTH_8, HDMI_14, 0x140, 0x33, 0x3, 0x4, 0x232, 0x8009},
|
||||
{43200, PIXEL_REPETITION_4, COLOR_DEPTH_12, HDMI_14, 0x4164, 0x30, 0x3, 0x4, 0x232, 0x8009},
|
||||
{43200, PIXEL_REPETITION_4, COLOR_DEPTH_16, HDMI_20, 0x7B50, 0x001B, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{44900, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x00B3, 0x0, 0x0, 0x4, 0x232, 0x8009},
|
||||
{49500, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x72, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{50000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x72, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{50350, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x72, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{50350, PIXEL_REPETITION_OFF, COLOR_DEPTH_10, HDMI_14, 0x2142, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{50350, PIXEL_REPETITION_OFF, COLOR_DEPTH_12, HDMI_14, 0x40A2, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{50350, PIXEL_REPETITION_OFF, COLOR_DEPTH_16, HDMI_14, 0x6071, 0x001A, 0x2, 0x4, 0x232, 0x8009},
|
||||
{54000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x72, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{54000, PIXEL_REPETITION_OFF, COLOR_DEPTH_10, HDMI_14, 0x2142, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{54000, PIXEL_REPETITION_OFF, COLOR_DEPTH_12, HDMI_14, 0x40A2, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{54000, PIXEL_REPETITION_OFF, COLOR_DEPTH_16, HDMI_14, 0x6071, 0x001A, 0x2, 0x4, 0x232, 0x8009},
|
||||
{54000, PIXEL_REPETITION_1, COLOR_DEPTH_8, HDMI_14, 0x71, 0x001A, 0x2, 0x4, 0x232, 0x8009},
|
||||
{54000, PIXEL_REPETITION_1, COLOR_DEPTH_10, HDMI_14, 0x2141, 0x001A, 0x2, 0x4, 0x232, 0x8009},
|
||||
{54000, PIXEL_REPETITION_1, COLOR_DEPTH_12, HDMI_14, 0x40A1, 0x001A, 0x2, 0x4, 0x232, 0x8009},
|
||||
{54000, PIXEL_REPETITION_1, COLOR_DEPTH_16, HDMI_14, 0x6070, 0x33, 0x3, 0x4, 0x232, 0x8009},
|
||||
{54000, PIXEL_REPETITION_3, COLOR_DEPTH_8, HDMI_14, 0x70, 0x33, 0x3, 0x4, 0x232, 0x8009},
|
||||
{54000, PIXEL_REPETITION_3, COLOR_DEPTH_10, HDMI_14, 0x2140, 0x33, 0x3, 0x4, 0x232, 0x8009},
|
||||
{54000, PIXEL_REPETITION_3, COLOR_DEPTH_12, HDMI_14, 0x40A0, 0x32, 0x3, 0x4, 0x232, 0x8009},
|
||||
{54000, PIXEL_REPETITION_3, COLOR_DEPTH_16, HDMI_20, 0x7AB0, 0x001B, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{56250, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x72, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{59400, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x72, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{59400, PIXEL_REPETITION_OFF, COLOR_DEPTH_10, HDMI_14, 0x2142, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{59400, PIXEL_REPETITION_OFF, COLOR_DEPTH_12, HDMI_14, 0x40A2, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{59400, PIXEL_REPETITION_OFF, COLOR_DEPTH_16, HDMI_14, 0x6071, 0x001A, 0x2, 0x4, 0x232, 0x8009},
|
||||
{65000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x72, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{68250, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x72, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{71000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x72, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{72000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x72, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{72000, PIXEL_REPETITION_OFF, COLOR_DEPTH_10, HDMI_14, 0x2142, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{72000, PIXEL_REPETITION_OFF, COLOR_DEPTH_12, HDMI_14, 0x4061, 0x001B, 0x2, 0x4, 0x232, 0x8009},
|
||||
{72000, PIXEL_REPETITION_OFF, COLOR_DEPTH_16, HDMI_14, 0x6071, 0x001A, 0x2, 0x4, 0x232, 0x8009},
|
||||
{72000, PIXEL_REPETITION_2, COLOR_DEPTH_8, HDMI_14, 0x60, 0x34, 0x3, 0x4, 0x232, 0x8009},
|
||||
{72000, PIXEL_REPETITION_2, COLOR_DEPTH_10, HDMI_14, 0x216C, 0x30, 0x3, 0x4, 0x232, 0x8009},
|
||||
{72000, PIXEL_REPETITION_2, COLOR_DEPTH_12, HDMI_14, 0x40E4, 0x32, 0x3, 0x4, 0x232, 0x8009},
|
||||
{72000, PIXEL_REPETITION_2, COLOR_DEPTH_16, HDMI_20, 0x7AA0, 0x001B, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{73250, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x72, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{74250, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x72, 0x13, 0x1, 0x6, 0x22d, 0x8009},
|
||||
{74250, PIXEL_REPETITION_OFF, COLOR_DEPTH_10, HDMI_14, 0x2145, 0x001A, 0x2, 0x4, 0x232, 0x8009},
|
||||
{74250, PIXEL_REPETITION_OFF, COLOR_DEPTH_12, HDMI_14, 0x4061, 0x001B, 0x2, 0x4, 0x232, 0x8009},
|
||||
{74250, PIXEL_REPETITION_OFF, COLOR_DEPTH_16, HDMI_14, 0x6071, 0x001A, 0x2, 0x4, 0x230, 0x8009},
|
||||
{75000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x72, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{78750, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x72, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{79500, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x72, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{82500, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x72, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{82500, PIXEL_REPETITION_OFF, COLOR_DEPTH_10, HDMI_14, 0x2145, 0x001A, 0x2, 0x4, 0x232, 0x8009},
|
||||
{82500, PIXEL_REPETITION_OFF, COLOR_DEPTH_12, HDMI_14, 0x4061, 0x001B, 0x2, 0x4, 0x232, 0x8009},
|
||||
{82500, PIXEL_REPETITION_OFF, COLOR_DEPTH_16, HDMI_14, 0x6071, 0x001A, 0x2, 0x4, 0x230, 0x8009},
|
||||
{83500, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x72, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{85500, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x72, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{88750, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x72, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{90000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x72, 0x8, 0x1, 0x4, 0x232, 0x8009},
|
||||
{90000, PIXEL_REPETITION_OFF, COLOR_DEPTH_10, HDMI_14, 0x2145, 0x001A, 0x2, 0x4, 0x232, 0x8009},
|
||||
{90000, PIXEL_REPETITION_OFF, COLOR_DEPTH_12, HDMI_14, 0x4061, 0x001B, 0x2, 0x4, 0x232, 0x8009},
|
||||
{90000, PIXEL_REPETITION_OFF, COLOR_DEPTH_16, HDMI_14, 0x6071, 0x001A, 0x2, 0x4, 0x230, 0x8009},
|
||||
{94500, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x51, 0x001B, 0x2, 0x4, 0x232, 0x8009},
|
||||
{99000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x51, 0x001B, 0x2, 0x4, 0x232, 0x8009},
|
||||
{99000, PIXEL_REPETITION_OFF, COLOR_DEPTH_10, HDMI_14, 0x2145, 0x001A, 0x2, 0x4, 0x232, 0x8009},
|
||||
{99000, PIXEL_REPETITION_OFF, COLOR_DEPTH_12, HDMI_14, 0x4061, 0x001B, 0x2, 0x4, 0x230, 0x8009},
|
||||
{99000, PIXEL_REPETITION_OFF, COLOR_DEPTH_16, HDMI_14, 0x6050, 0x35, 0x3, 0x4, 0x230, 0x8009},
|
||||
{100700, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x51, 0x001B, 0x2, 0x4, 0x232, 0x8009},
|
||||
{100700, PIXEL_REPETITION_OFF, COLOR_DEPTH_10, HDMI_14, 0x2145, 0x001A, 0x2, 0x4, 0x232, 0x8009},
|
||||
{100700, PIXEL_REPETITION_OFF, COLOR_DEPTH_12, HDMI_14, 0x4061, 0x001B, 0x2, 0x4, 0x230, 0x8009},
|
||||
{100700, PIXEL_REPETITION_OFF, COLOR_DEPTH_16, HDMI_14, 0x6050, 0x35, 0x3, 0x4, 0x230, 0x8009},
|
||||
{101000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x51, 0x001B, 0x2, 0x4, 0x232, 0x8009},
|
||||
{102250, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x51, 0x001B, 0x2, 0x4, 0x232, 0x8009},
|
||||
{106500, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x51, 0x001B, 0x2, 0x4, 0x232, 0x8009},
|
||||
{108000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x51, 0x001B, 0x2, 0x4, 0x232, 0x8009},
|
||||
{108000, PIXEL_REPETITION_OFF, COLOR_DEPTH_10, HDMI_14, 0x2145, 0x001A, 0x2, 0x4, 0x232, 0x8009},
|
||||
{108000, PIXEL_REPETITION_OFF, COLOR_DEPTH_12, HDMI_14, 0x4061, 0x001B, 0x2, 0x4, 0x230, 0x8009},
|
||||
{108000, PIXEL_REPETITION_OFF, COLOR_DEPTH_16, HDMI_14, 0x6050, 0x35, 0x3, 0x4, 0x230, 0x8009},
|
||||
{108000, PIXEL_REPETITION_1, COLOR_DEPTH_8, HDMI_14, 0x50, 0x35, 0x3, 0x4, 0x232, 0x8009},
|
||||
{108000, PIXEL_REPETITION_1, COLOR_DEPTH_10, HDMI_14, 0x2144, 0x33, 0x3, 0x4, 0x232, 0x8009},
|
||||
{108000, PIXEL_REPETITION_1, COLOR_DEPTH_12, HDMI_14, 0x4060, 0x34, 0x3, 0x4, 0x230, 0x8009},
|
||||
{108000, PIXEL_REPETITION_1, COLOR_DEPTH_16, HDMI_20, 0x7A70, 0x33, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{115500, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x51, 0x001B, 0x2, 0x4, 0x232, 0x8009},
|
||||
{117500, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x51, 0x001B, 0x2, 0x4, 0x232, 0x8009},
|
||||
{118800, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x51, 0x001B, 0x2, 0x4, 0x232, 0x8009},
|
||||
{118800, PIXEL_REPETITION_OFF, COLOR_DEPTH_10, HDMI_14, 0x2145, 0x001A, 0x2, 0x4, 0x230, 0x8009},
|
||||
{118800, PIXEL_REPETITION_OFF, COLOR_DEPTH_12, HDMI_14, 0x4061, 0x001B, 0x2, 0x4, 0x230, 0x8009},
|
||||
{118800, PIXEL_REPETITION_OFF, COLOR_DEPTH_16, HDMI_14, 0x6050, 0x35, 0x3, 0x4, 0x273, 0x8009},
|
||||
{119000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x51, 0x001B, 0x2, 0x4, 0x232, 0x8009},
|
||||
{121750, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x51, 0x001B, 0x2, 0x4, 0x232, 0x8009},
|
||||
{122500, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x51, 0x001B, 0x2, 0x4, 0x232, 0x8009},
|
||||
{135000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x51, 0x001B, 0x2, 0x4, 0x232, 0x8009},
|
||||
{136750, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x51, 0x001B, 0x2, 0x4, 0x232, 0x8009},
|
||||
{140250, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x51, 0x001B, 0x2, 0x4, 0x232, 0x8009},
|
||||
{144000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x51, 0x001B, 0x2, 0x4, 0x232, 0x8009},
|
||||
{144000, PIXEL_REPETITION_OFF, COLOR_DEPTH_10, HDMI_14, 0x2145, 0x001A, 0x2, 0x4, 0x230, 0x8009},
|
||||
{144000, PIXEL_REPETITION_OFF, COLOR_DEPTH_12, HDMI_14, 0x4064, 0x34, 0x3, 0x4, 0x230, 0x8009},
|
||||
{144000, PIXEL_REPETITION_OFF, COLOR_DEPTH_16, HDMI_14, 0x6050, 0x35, 0x3, 0x4, 0x273, 0x8009},
|
||||
{146250, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x51, 0x001B, 0x2, 0x4, 0x232, 0x8009},
|
||||
{148250, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x51, 0x001B, 0x2, 0x4, 0x232, 0x8009},
|
||||
{148500, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x51, 0x0019, 0x2, 0x6, 0x270, 0x8029},
|
||||
{148500, PIXEL_REPETITION_OFF, COLOR_DEPTH_10, HDMI_14, 0x214C, 0x33, 0x3, 0x4, 0x20b, 0x8019},
|
||||
{148500, PIXEL_REPETITION_OFF, COLOR_DEPTH_12, HDMI_14, 0x4064, 0x34, 0x3, 0x4, 0x273, 0x8009},
|
||||
{148500, PIXEL_REPETITION_OFF, COLOR_DEPTH_16, HDMI_14, 0x6050, 0x35, 0x3, 0x4, 0x273, 0x8029},
|
||||
{154000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x51, 0x001B, 0x2, 0x4, 0x230, 0x8009},
|
||||
{156000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x51, 0x001B, 0x2, 0x4, 0x230, 0x8009},
|
||||
{157000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x51, 0x001B, 0x2, 0x4, 0x230, 0x8009},
|
||||
{157500, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x51, 0x001B, 0x2, 0x4, 0x230, 0x8009},
|
||||
{162000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x51, 0x001B, 0x2, 0x4, 0x230, 0x8009},
|
||||
{165000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x51, 0x001B, 0x2, 0x4, 0x230, 0x8009},
|
||||
{165000, PIXEL_REPETITION_OFF, COLOR_DEPTH_10, HDMI_14, 0x214C, 0x33, 0x3, 0x4, 0x230, 0x8009},
|
||||
{165000, PIXEL_REPETITION_OFF, COLOR_DEPTH_12, HDMI_14, 0x4064, 0x34, 0x3, 0x4, 0x273, 0x8009},
|
||||
{165000, PIXEL_REPETITION_OFF, COLOR_DEPTH_16, HDMI_14, 0x6050, 0x35, 0x3, 0x4, 0x273, 0x8029},
|
||||
{175500, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x51, 0x001B, 0x2, 0x4, 0x230, 0x8009},
|
||||
{179500, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x51, 0x001B, 0x2, 0x4, 0x230, 0x8009},
|
||||
{180000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x51, 0x001B, 0x2, 0x4, 0x230, 0x8009},
|
||||
{180000, PIXEL_REPETITION_OFF, COLOR_DEPTH_10, HDMI_14, 0x214C, 0x33, 0x3, 0x4, 0x273, 0x8009},
|
||||
{180000, PIXEL_REPETITION_OFF, COLOR_DEPTH_12, HDMI_14, 0x4064, 0x34, 0x3, 0x4, 0x273, 0x8009},
|
||||
{180000, PIXEL_REPETITION_OFF, COLOR_DEPTH_16, HDMI_20, 0x7A50, 0x001B, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{182750, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x51, 0x001B, 0x2, 0x4, 0x230, 0x8009},
|
||||
{185625, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x40, 0x36, 0x3, 0x4, 0x230, 0x8009},
|
||||
{185625, PIXEL_REPETITION_OFF, COLOR_DEPTH_10, HDMI_14, 0x214C, 0x33, 0x3, 0x4, 0x273, 0x8009},
|
||||
{185625, PIXEL_REPETITION_OFF, COLOR_DEPTH_12, HDMI_14, 0x4064, 0x34, 0x3, 0x4, 0x273, 0x8009},
|
||||
{185625, PIXEL_REPETITION_OFF, COLOR_DEPTH_16, HDMI_20, 0x7A50, 0x001B, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{187000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x40, 0x36, 0x3, 0x4, 0x230, 0x8009},
|
||||
{187250, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x40, 0x36, 0x3, 0x4, 0x230, 0x8009},
|
||||
{189000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x40, 0x36, 0x3, 0x4, 0x230, 0x8009},
|
||||
{193250, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x40, 0x36, 0x3, 0x4, 0x230, 0x8009},
|
||||
{198000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x40, 0x36, 0x3, 0x4, 0x230, 0x8009},
|
||||
{198000, PIXEL_REPETITION_OFF, COLOR_DEPTH_10, HDMI_14, 0x214C, 0x33, 0x3, 0x4, 0x273, 0x8009},
|
||||
{198000, PIXEL_REPETITION_OFF, COLOR_DEPTH_12, HDMI_14, 0x4064, 0x34, 0x3, 0x4, 0x273, 0x8029},
|
||||
{198000, PIXEL_REPETITION_OFF, COLOR_DEPTH_16, HDMI_20, 0x7A50, 0x001B, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{202500, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x40, 0x36, 0x3, 0x4, 0x230, 0x8009},
|
||||
{204750, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x40, 0x36, 0x3, 0x4, 0x230, 0x8009},
|
||||
{208000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x40, 0x36, 0x3, 0x4, 0x230, 0x8009},
|
||||
{214750, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x40, 0x36, 0x3, 0x4, 0x230, 0x8009},
|
||||
{216000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x40, 0x36, 0x3, 0x4, 0x230, 0x8009},
|
||||
{216000, PIXEL_REPETITION_OFF, COLOR_DEPTH_10, HDMI_14, 0x214C, 0x33, 0x3, 0x4, 0x273, 0x8009},
|
||||
{216000, PIXEL_REPETITION_OFF, COLOR_DEPTH_12, HDMI_14, 0x4064, 0x34, 0x3, 0x4, 0x273, 0x8029},
|
||||
{216000, PIXEL_REPETITION_OFF, COLOR_DEPTH_16, HDMI_20, 0x7A50, 0x001B, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{218250, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x40, 0x36, 0x3, 0x4, 0x230, 0x8009},
|
||||
{229500, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x40, 0x36, 0x3, 0x4, 0x273, 0x8009},
|
||||
{234000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x40, 0x36, 0x3, 0x4, 0x273, 0x8009},
|
||||
{237600, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x40, 0x36, 0x3, 0x4, 0x273, 0x8009},
|
||||
{237600, PIXEL_REPETITION_OFF, COLOR_DEPTH_10, HDMI_14, 0x214C, 0x33, 0x3, 0x4, 0x273, 0x8029},
|
||||
{237600, PIXEL_REPETITION_OFF, COLOR_DEPTH_12, HDMI_20, 0x5A64, 0x001B, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{237600, PIXEL_REPETITION_OFF, COLOR_DEPTH_16, HDMI_20, 0x7A50, 0x001B, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{245250, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x40, 0x36, 0x3, 0x4, 0x273, 0x8009},
|
||||
{245500, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x40, 0x36, 0x3, 0x4, 0x273, 0x8009},
|
||||
{261000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x40, 0x36, 0x3, 0x4, 0x273, 0x8009},
|
||||
{268250, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x40, 0x36, 0x3, 0x4, 0x273, 0x8009},
|
||||
{268500, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x40, 0x36, 0x3, 0x4, 0x273, 0x8009},
|
||||
{281250, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x40, 0x36, 0x3, 0x4, 0x273, 0x8009},
|
||||
{288000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x40, 0x36, 0x3, 0x4, 0x273, 0x8009},
|
||||
{288000, PIXEL_REPETITION_OFF, COLOR_DEPTH_10, HDMI_20, 0x3B4C, 0x001B, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{288000, PIXEL_REPETITION_OFF, COLOR_DEPTH_12, HDMI_20, 0x5A64, 0x001B, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{288000, PIXEL_REPETITION_OFF, COLOR_DEPTH_16, HDMI_20, 0x7A50, 0x003D, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{297000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x40, 0x19, 0x3, 0x5, 0x1ab, 0x8039},
|
||||
{297000, PIXEL_REPETITION_OFF, COLOR_DEPTH_10, HDMI_20, 0x3B4C, 0x001B, 0x3, 0x0, 0x16A, 0x8019},
|
||||
{297000, PIXEL_REPETITION_OFF, COLOR_DEPTH_12, HDMI_20, 0x5A64, 0x001B, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{297000, PIXEL_REPETITION_OFF, COLOR_DEPTH_16, HDMI_20, 0x7A50, 0x003D, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{317000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x40, 0x36, 0x3, 0x4, 0x273, 0x8029},
|
||||
{330000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x40, 0x36, 0x3, 0x4, 0x273, 0x8029},
|
||||
{330000, PIXEL_REPETITION_OFF, COLOR_DEPTH_10, HDMI_20, 0x3B4C, 0x001B, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{330000, PIXEL_REPETITION_OFF, COLOR_DEPTH_12, HDMI_20, 0x5A64, 0x001B, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{333250, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x40, 0x36, 0x3, 0x4, 0x273, 0x8029},
|
||||
{340000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_14, 0x40, 0x36, 0x3, 0x4, 0x273, 0x8029},
|
||||
{348500, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_20, 0x1A40, 0x003F, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{356500, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_20, 0x1A40, 0x003F, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{360000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_20, 0x1A40, 0x003F, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{360000, PIXEL_REPETITION_OFF, COLOR_DEPTH_10, HDMI_20, 0x3B4C, 0x001B, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{360000, PIXEL_REPETITION_OFF, COLOR_DEPTH_12, HDMI_20, 0x5A64, 0x001B, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{371250, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_20, 0x1A40, 0x003F, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{371250, PIXEL_REPETITION_OFF, COLOR_DEPTH_10, HDMI_20, 0x3B4C, 0x001B, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{371250, PIXEL_REPETITION_OFF, COLOR_DEPTH_12, HDMI_20, 0x5A64, 0x001B, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{396000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_20, 0x1A40, 0x003F, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{396000, PIXEL_REPETITION_OFF, COLOR_DEPTH_10, HDMI_20, 0x3B4C, 0x001B, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{396000, PIXEL_REPETITION_OFF, COLOR_DEPTH_12, HDMI_20, 0x5A64, 0x001B, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{432000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_20, 0x1A40, 0x003F, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{432000, PIXEL_REPETITION_OFF, COLOR_DEPTH_10, HDMI_20, 0x3B4C, 0x001B, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{443250, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_20, 0x1A40, 0x003F, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{475200, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_20, 0x1A40, 0x003F, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{475200, PIXEL_REPETITION_OFF, COLOR_DEPTH_10, HDMI_20, 0x3B4C, 0x001B, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{495000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_20, 0x1A40, 0x003F, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{505250, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_20, 0x1A40, 0x003F, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{552750, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_20, 0x1A40, 0x003F, 0x3, 0x4, 0x14A, 0x8039},
|
||||
{594000, PIXEL_REPETITION_OFF, COLOR_DEPTH_8, HDMI_20, 0x1A7c, 0x0010, 0x3, 0x0, 0x8A, 0x8029},
|
||||
{0, PIXEL_REPETITION_OFF, COLOR_DEPTH_INVALID, HDMI_14, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static u32 phy301_get_freq(u32 pClk)
|
||||
{
|
||||
if (((pClk >= 25175) && (pClk <= 25180)) ||
|
||||
((pClk >= 25195) && (pClk <= 25205)))
|
||||
return 25175;
|
||||
else if (((pClk >= 26995) && (pClk <= 27005)) ||
|
||||
((pClk >= 27022) && (pClk <= 27032)))
|
||||
return 27000;
|
||||
else if (pClk == 31500)
|
||||
return 31500;
|
||||
else if (pClk == 33750)
|
||||
return 33750;
|
||||
else if (pClk == 35500)
|
||||
return 35500;
|
||||
else if (((pClk >= 35995) && (pClk <= 36005)) ||
|
||||
((pClk >= 36031) && (pClk <= 36041)))
|
||||
return 36000;
|
||||
else if (pClk == 40000)
|
||||
return 40000;
|
||||
else if (pClk == 44900)
|
||||
return 44900;
|
||||
else if (pClk == 49500)
|
||||
return 49500;
|
||||
else if (pClk == 50000)
|
||||
return 50000;
|
||||
else if (((pClk >= 50345) && (pClk <= 50355)) ||
|
||||
((pClk >= 50395) && (pClk <= 50405)))
|
||||
return 50350;
|
||||
else if (((pClk >= 53995) && (pClk <= 54005)) ||
|
||||
((pClk >= 50049) && (pClk <= 54059)))
|
||||
return 54000;
|
||||
else if (pClk == 56250)
|
||||
return 56250;
|
||||
else if (((pClk >= 59336) && (pClk <= 59346)) ||
|
||||
((pClk >= 59395) && (pClk <= 59405)))
|
||||
return 59400;
|
||||
else if (pClk == 65000)
|
||||
return 65000;
|
||||
else if (pClk == 68250)
|
||||
return 68250;
|
||||
else if (pClk == 71000)
|
||||
return 71000;
|
||||
else if (pClk == 72000)
|
||||
return 72000;
|
||||
else if (pClk == 73250)
|
||||
return 73250;
|
||||
else if (((pClk >= 74171) && (pClk <= 74181)) ||
|
||||
((pClk >= 74245) && (pClk <= 74255)))
|
||||
return 74250;
|
||||
else if (pClk == 75000)
|
||||
return 75000;
|
||||
else if (pClk == 78750)
|
||||
return 78750;
|
||||
else if (pClk == 79500)
|
||||
return 79500;
|
||||
else if (((pClk >= 82143) && (pClk <= 82153)) ||
|
||||
((pClk >= 82495) && (pClk <= 82505)))
|
||||
return 82500;
|
||||
else if (pClk == 83500)
|
||||
return 83500;
|
||||
else if (pClk == 85500)
|
||||
return 85500;
|
||||
else if (pClk == 88750)
|
||||
return 88750;
|
||||
else if (pClk == 90000)
|
||||
return 90000;
|
||||
else if (pClk == 94500)
|
||||
return 94500;
|
||||
else if (((pClk >= 98896) && (pClk <= 98906)) ||
|
||||
((pClk >= 98995) && (pClk <= 99005)))
|
||||
return 99000;
|
||||
else if (((pClk >= 100695) && (pClk <= 100705)) ||
|
||||
((pClk >= 100795) && (pClk <= 100805)))
|
||||
return 100700;
|
||||
else if (pClk == 101000)
|
||||
return 101000;
|
||||
else if (pClk == 102250)
|
||||
return 102250;
|
||||
else if (pClk == 106500)
|
||||
return 106500;
|
||||
else if (((pClk > 107994) && (pClk < 108006)) ||
|
||||
((pClk > 108102) && (pClk < 108114)))
|
||||
return 108000;
|
||||
else if (pClk == 115500)
|
||||
return 115500;
|
||||
else if (pClk == 117500)
|
||||
return 117500;
|
||||
else if (((pClk >= 118795) && (pClk <= 118805)) ||
|
||||
((pClk >= 118677) && (pClk <= 118687)))
|
||||
return 118800;
|
||||
else if (pClk == 119000)
|
||||
return 119000;
|
||||
else if (pClk == 121750)
|
||||
return 122500;
|
||||
else if (pClk == 122500)
|
||||
return 121750;
|
||||
else if (pClk == 135000)
|
||||
return 135000;
|
||||
else if (pClk == 136750)
|
||||
return 136750;
|
||||
else if (pClk == 140250)
|
||||
return 140250;
|
||||
else if (pClk == 144000)
|
||||
return 144000;
|
||||
else if (pClk == 146250)
|
||||
return 146250;
|
||||
else if (pClk == 148250)
|
||||
return 148250;
|
||||
else if (((pClk >= 148347) && (pClk <= 148357)) ||
|
||||
((pClk >= 148495) && (pClk <= 148505)))
|
||||
return 148500;
|
||||
else if (pClk == 154000)
|
||||
return 154000;
|
||||
else if (pClk == 156000)
|
||||
return 156000;
|
||||
else if (pClk == 157000)
|
||||
return 157000;
|
||||
else if (pClk == 157500)
|
||||
return 157500;
|
||||
else if (pClk == 162000)
|
||||
return 162000;
|
||||
else if (((pClk >= 164830) && (pClk <= 164840)) ||
|
||||
((pClk >= 164995) && (pClk <= 165005)))
|
||||
return 165000;
|
||||
else if (pClk == 175500)
|
||||
return 175500;
|
||||
else if (pClk == 179500)
|
||||
return 179500;
|
||||
else if (pClk == 180000)
|
||||
return 180000;
|
||||
else if (pClk == 182750)
|
||||
return 182750;
|
||||
else if (((pClk >= 185435) && (pClk <= 185445)) ||
|
||||
((pClk >= 185620) && (pClk <= 185630)))
|
||||
return 185625;
|
||||
else if (pClk == 187000)
|
||||
return 187000;
|
||||
else if (pClk == 187250)
|
||||
return 187250;
|
||||
else if (pClk == 189000)
|
||||
return 189000;
|
||||
else if (pClk == 193250)
|
||||
return 193250;
|
||||
else if (((pClk >= 197797) && (pClk <= 197807)) ||
|
||||
((pClk >= 197995) && (pClk <= 198005)))
|
||||
return 198000;
|
||||
else if (pClk == 202500)
|
||||
return 202500;
|
||||
else if (pClk == 204750)
|
||||
return 204750;
|
||||
else if (pClk == 208000)
|
||||
return 208000;
|
||||
else if (pClk == 214750)
|
||||
return 214750;
|
||||
else if (((pClk >= 216211) && (pClk <= 216221)) ||
|
||||
((pClk >= 215995) && (pClk <= 216005)))
|
||||
return 216000;
|
||||
else if (pClk == 218250)
|
||||
return 218250;
|
||||
else if (pClk == 229500)
|
||||
return 229500;
|
||||
else if (pClk == 234000)
|
||||
return 234000;
|
||||
else if (((pClk >= 237359) && (pClk <= 237369)) ||
|
||||
((pClk >= 237595) && (pClk <= 237605)))
|
||||
return 237600;
|
||||
else if (pClk == 245250)
|
||||
return 245250;
|
||||
else if (pClk == 245500)
|
||||
return 245500;
|
||||
else if (pClk == 261000)
|
||||
return 261000;
|
||||
else if (pClk == 268250)
|
||||
return 268250;
|
||||
else if (pClk == 268500)
|
||||
return 268500;
|
||||
else if (pClk == 281250)
|
||||
return 281250;
|
||||
else if (pClk == 288000)
|
||||
return 288000;
|
||||
else if (((pClk >= 296698) && (pClk <= 296708)) ||
|
||||
((pClk >= 296995) && (pClk <= 297005)))
|
||||
return 297000;
|
||||
else if (pClk == 317000)
|
||||
return 317000;
|
||||
else if (pClk == 330000)
|
||||
return 330000;
|
||||
else if (pClk == 333250)
|
||||
return 333250;
|
||||
else if (((pClk >= 339655) && (pClk <= 339665)) ||
|
||||
((pClk >= 339995) && (pClk <= 340005)))
|
||||
return 340000;
|
||||
else if (pClk == 348500)
|
||||
return 348500;
|
||||
else if (pClk == 356500)
|
||||
return 356500;
|
||||
else if (pClk == 360000)
|
||||
return 360000;
|
||||
else if (((pClk >= 370874) && (pClk <= 370884)) ||
|
||||
((pClk >= 371245) && (pClk <= 371255)))
|
||||
return 371250;
|
||||
else if (pClk == 380500)
|
||||
return 380500;
|
||||
else if (((pClk >= 395599) && (pClk <= 395609)) ||
|
||||
((pClk >= 395995) && (pClk <= 396005)))
|
||||
return 396000;
|
||||
else if (((pClk >= 431952) && (pClk <= 431967)) ||
|
||||
((pClk >= 431995) && (pClk <= 432005)) ||
|
||||
((pClk >= 432427) && (pClk <= 432437)))
|
||||
return 432000;
|
||||
else if (pClk == 443250)
|
||||
return 443250;
|
||||
else if (((pClk >= 475148) && (pClk <= 475158)) ||
|
||||
((pClk >= 475195) && (pClk <= 475205)) ||
|
||||
((pClk >= 474723) && (pClk <= 474733)))
|
||||
return 475200;
|
||||
else if (((pClk >= 494500) && (pClk <= 494510)) ||
|
||||
((pClk >= 494995) && (pClk <= 495005)))
|
||||
return 495000;
|
||||
else if (pClk == 505250)
|
||||
return 505250;
|
||||
else if (pClk == 552750)
|
||||
return 552750;
|
||||
else if (((pClk >= 593995) && (pClk <= 594005)) ||
|
||||
((pClk >= 593403) && (pClk <= 593413)))
|
||||
return 594000;
|
||||
else{
|
||||
HDMI_ERROR_MSG("Unable to map input pixel clock frequency %d kHz\n", pClk);
|
||||
}
|
||||
return 1000;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static struct phy_config *phy301_get_configs(u32 pClk, color_depth_t color,
|
||||
pixel_repetition_t pixel)
|
||||
{
|
||||
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; phy301[i].clock != 0; i++) {
|
||||
|
||||
pClk = phy301_get_freq(pClk);
|
||||
|
||||
if ((pClk == phy301[i].clock) &&
|
||||
(color == phy301[i].color) &&
|
||||
(pixel == phy301[i].pixel)) {
|
||||
return &(phy301[i]);
|
||||
}
|
||||
}
|
||||
printf("EEROR: do not get phy_config\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static int phy301_configure(hdmi_tx_dev_t *dev, u32 pClk, color_depth_t color,
|
||||
pixel_repetition_t pixel)
|
||||
{
|
||||
int i = 0;
|
||||
u16 phyRead = 0;
|
||||
u8 lock = 0;
|
||||
struct phy_config *config = NULL;
|
||||
/* value = 0;*/
|
||||
|
||||
LOG_TRACE();
|
||||
/* Color resolution 0 is 8 bit color depth */
|
||||
if (color == 0)
|
||||
color = COLOR_DEPTH_8;
|
||||
|
||||
config = phy301_get_configs(pClk, color, pixel);
|
||||
|
||||
if (config == NULL) {
|
||||
HDMI_ERROR_MSG("Configuration for clk %dkhz color depth %d pixel repetition %d\n",
|
||||
pClk, color, pixel);
|
||||
return -1;
|
||||
}
|
||||
|
||||
mc_phy_reset(dev, 1);
|
||||
|
||||
dev_write_mask(dev, PHY_CONF0, PHY_CONF0_TXPWRON_MASK, 0);
|
||||
dev_write_mask(dev, PHY_CONF0, PHY_CONF0_PDDQ_MASK, 1);
|
||||
dev_write_mask(dev, PHY_CONF0, PHY_CONF0_SVSRET_MASK, 0);
|
||||
|
||||
dev_write_mask(dev, PHY_CONF0, PHY_CONF0_SVSRET_MASK, 1);
|
||||
|
||||
mc_phy_reset(dev, 0);
|
||||
|
||||
/*dev->snps_hdmi_ctrl.phy_access = PHY_I2C;*/
|
||||
phy_reconfigure_interface(dev);
|
||||
|
||||
phy_write(dev, OPMODE_PLLCFG, config->oppllcfg);
|
||||
if (phy_read(dev, OPMODE_PLLCFG, &phyRead) || (phyRead != config->oppllcfg))
|
||||
HDMI_ERROR_MSG("OPMODE_PLLCFG Mismatch Write 0x%04x Read 0x%04x\n",
|
||||
config->oppllcfg, phyRead);
|
||||
|
||||
phy_write(dev, PLLCURRCTRL, config->pllcurrctrl);
|
||||
if (phy_read(dev, PLLCURRCTRL, &phyRead) || (phyRead != config->pllcurrctrl))
|
||||
HDMI_ERROR_MSG("PLLCURRCTRL Mismatch Write 0x%04x Read 0x%04x\n",
|
||||
config->pllcurrctrl, phyRead);
|
||||
|
||||
phy_write(dev, PLLGMPCTRL, config->pllgmpctrl);
|
||||
if (phy_read(dev, PLLGMPCTRL, &phyRead) || (phyRead != config->pllgmpctrl))
|
||||
HDMI_ERROR_MSG("PLLGMPCTRL Mismatch Write 0x%04x Read 0x%04x\n",
|
||||
config->pllgmpctrl, phyRead);
|
||||
|
||||
phy_write(dev, TXTERM, config->txterm);
|
||||
if (phy_read(dev, TXTERM, &phyRead) || (phyRead != config->txterm))
|
||||
HDMI_ERROR_MSG("TXTERM Mismatch Write 0x%04x Read 0x%04x\n",
|
||||
config->txterm, phyRead);
|
||||
|
||||
|
||||
phy_write(dev, CKSYMTXCTRL, config->cksymtxctrl);
|
||||
if (phy_read(dev, CKSYMTXCTRL, &phyRead) || (phyRead != config->cksymtxctrl))
|
||||
HDMI_ERROR_MSG("CKSYMTXCTRL Mismatch Write 0x%04x Read 0x%04x\n",
|
||||
config->cksymtxctrl, phyRead);
|
||||
|
||||
phy_write(dev, VLEVCTRL, config->vlevctrl);
|
||||
if (phy_read(dev, VLEVCTRL, &phyRead) || (phyRead != config->vlevctrl))
|
||||
HDMI_ERROR_MSG("VLEVCTRL Mismatch Write 0x%04x Read 0x%04x\n",
|
||||
config->vlevctrl, phyRead);
|
||||
|
||||
if (dev->snps_hdmi_ctrl.pixel_clock == 594000) {
|
||||
phy_write(dev, 0x17, 0x8006);
|
||||
if (phy_read(dev, 0x17, &phyRead) || (phyRead != 0x8006))
|
||||
HDMI_ERROR_MSG("VLEVCTRL Mismatch Write 0x8006 Read 0x%04x\n",
|
||||
phyRead);
|
||||
}
|
||||
|
||||
dev_write_mask(dev, PHY_CONF0, PHY_CONF0_PDDQ_MASK, 0);
|
||||
dev_write_mask(dev, PHY_CONF0, PHY_CONF0_TXPWRON_MASK, 1);
|
||||
|
||||
/* wait PHY_TIMEOUT no of cycles at most for
|
||||
the PLL lock signal to raise ~around 20us max */
|
||||
for (i = 0; i < PHY_TIMEOUT; i++) {
|
||||
snps_sleep(5);
|
||||
lock = phy_phase_lock_loop_state(dev);
|
||||
if (lock & 0x1) {
|
||||
HDMI_ERROR_MSG("PHY PLL locked\n");
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// error_set(ERR_PHY_NOT_LOCKED);
|
||||
HDMI_ERROR_MSG("PHY PLL not locked\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static int phy_reconfigure_interface(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
//switch (dev->snps_hdmi_ctrl.phy_access) {
|
||||
//case PHY_JTAG:
|
||||
//phy_jtag_init(dev, 0xD4);
|
||||
// break;
|
||||
//case PHY_I2C:
|
||||
dev_write(dev, JTAG_PHY_CONFIG, JTAG_PHY_CONFIG_I2C_JTAGZ_MASK);
|
||||
phy_slave_address(dev, PHY_I2C_SLAVE_ADDR);
|
||||
// break;
|
||||
//default:
|
||||
// HDMI_INFO_MSG("PHY interface not defined");
|
||||
// return -1;
|
||||
// }
|
||||
//HDMI_INFO_MSG("PHY interface reconfiguration, set to %s",
|
||||
//dev->snps_hdmi_ctrl.phy_access == PHY_I2C ? "I2C" : "JTAG");
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int phy_slave_address(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
//switch (dev->snps_hdmi_ctrl.phy_access) {
|
||||
//case PHY_JTAG:
|
||||
//phy_jtag_slave_address(dev, 0xD4);
|
||||
// return 0;
|
||||
//case PHY_I2C:
|
||||
phy_i2c_slave_address(dev, value);
|
||||
return 0;
|
||||
//default:
|
||||
// HDMI_INFO_MSG("PHY interface not defined");
|
||||
//}
|
||||
//return -1;
|
||||
}
|
||||
|
||||
|
||||
int phy_configure(hdmi_tx_dev_t *dev, u16 phy_model)
|
||||
{
|
||||
LOG_TRACE();
|
||||
if (phy_model == PHY_MODEL_301) {
|
||||
return phy301_configure(dev, dev->snps_hdmi_ctrl.pixel_clock,
|
||||
dev->snps_hdmi_ctrl.color_resolution,
|
||||
dev->snps_hdmi_ctrl.pixel_repetition);
|
||||
}
|
||||
|
||||
HDMI_INFO_MSG("****** PHY not supported %d *******\n", phy_model);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int phy_standby(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
#ifndef PHY_THIRD_PARTY
|
||||
phy_interrupt_mask(dev, PHY_MASK0_TX_PHY_LOCK_MASK |
|
||||
PHY_MASK0_RX_SENSE_0_MASK |
|
||||
PHY_MASK0_RX_SENSE_1_MASK |
|
||||
PHY_MASK0_RX_SENSE_2_MASK |
|
||||
PHY_MASK0_RX_SENSE_3_MASK);
|
||||
/* mask phy interrupts - leave HPD */
|
||||
phy_enable_tmds(dev, 0);
|
||||
phy_power_down(dev, 0); /* disable PHY */
|
||||
phy_gen2_tx_power_on(dev, 0);
|
||||
phy_gen2_pddq(dev, 1);
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int phy_enable_hpd_sense(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
#ifndef PHY_THIRD_PARTY
|
||||
phy_gen2_en_hpd_rx_sense(dev, 1);
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int phy_disable_hpd_sense(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
#ifndef PHY_THIRD_PARTY
|
||||
phy_gen2_en_hpd_rx_sense(dev, 0);
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
int phy_interrupt_enable(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write(dev, PHY_MASK0, value);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int phy_phase_lock_loop_state(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
LOG_TRACE();
|
||||
return dev_read_mask(dev, (PHY_STAT0), PHY_STAT0_TX_PHY_LOCK_MASK);
|
||||
}
|
||||
|
||||
static void phy_interrupt_mask(hdmi_tx_dev_t *dev, u8 mask)
|
||||
{
|
||||
LOG_TRACE1(mask);
|
||||
/* Mask will determine which bits will be enabled */
|
||||
dev_write_mask(dev, PHY_MASK0, mask, 0xff);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
u8 phy_hot_plug_state(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
return dev_read_mask(dev, (PHY_STAT0), PHY_STAT0_HPD_MASK);
|
||||
}
|
||||
313
sunxi_spl/display/hdmi/phy.h
Executable file
313
sunxi_spl/display/hdmi/phy.h
Executable file
@@ -0,0 +1,313 @@
|
||||
/*
|
||||
* Allwinner SoCs hdmi2.0 driver.
|
||||
*
|
||||
* Copyright (C) 2016 Allwinner.
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#ifndef PHY_H_
|
||||
#define PHY_H_
|
||||
|
||||
#include "hdmitx_dev.h"
|
||||
|
||||
|
||||
#define PHY_TIMEOUT 100
|
||||
#define PHY_I2C_SLAVE_ADDR 0x69
|
||||
|
||||
#define PHY_MODEL_301 301
|
||||
#define PHY_MODEL_303 303
|
||||
#define PHY_MODEL_108 108
|
||||
|
||||
#define OPMODE_PLLCFG 0x06 /* Mode of Operation and PLL Dividers Control Register */
|
||||
#define CKSYMTXCTRL 0x09 /* Clock Symbol and Transmitter Control Register */
|
||||
#define PLLCURRCTRL 0x10 /* PLL Current Control Register */
|
||||
#define VLEVCTRL 0x0E /* Voltage Level Control Register */
|
||||
#define PLLGMPCTRL 0x15 /* PLL Gmp Control Register */
|
||||
#define TXTERM 0x19 /* Transmission Termination Register */
|
||||
|
||||
#define JTAG_TAP_ADDR_CMD 0
|
||||
#define JTAG_TAP_WRITE_CMD 1
|
||||
#define JTAG_TAP_READ_CMD 3
|
||||
|
||||
typedef enum {
|
||||
HDMI_14 = 1,
|
||||
HDMI_20,
|
||||
MHL_24,
|
||||
MHL_PACKEDPIXEL
|
||||
} operation_mode_t;
|
||||
|
||||
typedef enum {
|
||||
PIXEL_REPETITION_OFF = 0,
|
||||
PIXEL_REPETITION_1 = 1,
|
||||
PIXEL_REPETITION_2 = 2,
|
||||
PIXEL_REPETITION_3 = 3,
|
||||
PIXEL_REPETITION_4 = 4,
|
||||
PIXEL_REPETITION_5 = 5,
|
||||
PIXEL_REPETITION_6 = 6,
|
||||
PIXEL_REPETITION_7 = 7,
|
||||
PIXEL_REPETITION_8 = 8,
|
||||
PIXEL_REPETITION_9 = 9,
|
||||
PIXEL_REPETITION_10 = 10
|
||||
} pixel_repetition_t;
|
||||
|
||||
typedef enum {
|
||||
COLOR_DEPTH_INVALID = 0,
|
||||
COLOR_DEPTH_8 = 8,
|
||||
COLOR_DEPTH_10 = 10,
|
||||
COLOR_DEPTH_12 = 12,
|
||||
COLOR_DEPTH_16 = 16
|
||||
} color_depth_t;
|
||||
|
||||
struct phy_config {
|
||||
u32 clock;/*phy clock: unit:kHZ*/
|
||||
pixel_repetition_t pixel;
|
||||
color_depth_t color;
|
||||
operation_mode_t opmode;
|
||||
u16 oppllcfg;
|
||||
u16 pllcurrctrl;
|
||||
u16 pllgmpctrl;
|
||||
u16 txterm;
|
||||
u16 vlevctrl;
|
||||
u16 cksymtxctrl;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* *
|
||||
* PHY Configuration Registers *
|
||||
* *
|
||||
*****************************************************************************/
|
||||
|
||||
/* PHY Configuration Register This register holds the power down, data enable polarity, and interface control of the HDMI Source PHY control */
|
||||
#define PHY_CONF0 0x0000C000
|
||||
#define PHY_CONF0_SELDIPIF_MASK 0x00000001 /* Select interface control */
|
||||
#define PHY_CONF0_SELDATAENPOL_MASK 0x00000002 /* Select data enable polarity */
|
||||
#define PHY_CONF0_ENHPDRXSENSE_MASK 0x00000004 /* PHY ENHPDRXSENSE signal */
|
||||
#define PHY_CONF0_TXPWRON_MASK 0x00000008 /* PHY TXPWRON signal */
|
||||
#define PHY_CONF0_PDDQ_MASK 0x00000010 /* PHY PDDQ signal */
|
||||
#define PHY_CONF0_SVSRET_MASK 0x00000020 /* Reserved as "spare" register with no associated functionality */
|
||||
#define PHY_CONF0_SPARES_1_MASK 0x00000040 /* Reserved as "spare" register with no associated functionality */
|
||||
#define PHY_CONF0_SPARES_2_MASK 0x00000080 /* Reserved as "spare" register with no associated functionality */
|
||||
|
||||
/* PHY Test Interface Register 0 PHY TX mapped test interface (control) */
|
||||
#define PHY_TST0 0x0000C004
|
||||
#define PHY_TST0_SPARE_0_MASK 0x00000001 /* Reserved as "spare" register with no associated functionality */
|
||||
#define PHY_TST0_SPARE_1_MASK 0x0000000E /* Reserved as "spare" bit with no associated functionality */
|
||||
#define PHY_TST0_SPARE_3_MASK 0x00000010 /* Reserved as "spare" register with no associated functionality */
|
||||
#define PHY_TST0_SPARE_4_MASK 0x00000020 /* Reserved as "spare" register with no associated functionality */
|
||||
#define PHY_TST0_SPARE_2_MASK 0x000000C0 /* Reserved as "spare" bit with no associated functionality */
|
||||
|
||||
/* PHY Test Interface Register 1 PHY TX mapped text interface (data in) */
|
||||
#define PHY_TST1 0x0000C008
|
||||
#define PHY_TST1_SPARE_MASK 0x000000FF /* Reserved as "spare" register with no associated functionality */
|
||||
|
||||
/* PHY Test Interface Register 2 PHY TX mapped text interface (data out) */
|
||||
#define PHY_TST2 0x0000C00C
|
||||
#define PHY_TST2_SPARE_MASK 0x000000FF /* Reserved as "spare" register with no associated functionality */
|
||||
|
||||
/* PHY RXSENSE, PLL Lock, and HPD Status Register This register contains the following active high packet sent status indications */
|
||||
#define PHY_STAT0 0x0000C010
|
||||
#define PHY_STAT0_TX_PHY_LOCK_MASK 0x00000001 /* Status bit */
|
||||
#define PHY_STAT0_HPD_MASK 0x00000002 /* Status bit */
|
||||
#define PHY_STAT0_RX_SENSE_0_MASK 0x00000010 /* Status bit */
|
||||
#define PHY_STAT0_RX_SENSE_1_MASK 0x00000020 /* Status bit */
|
||||
#define PHY_STAT0_RX_SENSE_2_MASK 0x00000040 /* Status bit */
|
||||
#define PHY_STAT0_RX_SENSE_3_MASK 0x00000080 /* Status bit */
|
||||
|
||||
/* PHY RXSENSE, PLL Lock, and HPD Interrupt Register This register contains the interrupt indication of the PHY_STAT0 status interrupts */
|
||||
#define PHY_INT0 0x0000C014
|
||||
#define PHY_INT0_TX_PHY_LOCK_MASK 0x00000001 /* Interrupt indication bit */
|
||||
#define PHY_INT0_HPD_MASK 0x00000002 /* Interrupt indication bit */
|
||||
#define PHY_INT0_RX_SENSE_0_MASK 0x00000010 /* Interrupt indication bit */
|
||||
#define PHY_INT0_RX_SENSE_1_MASK 0x00000020 /* Interrupt indication bit */
|
||||
#define PHY_INT0_RX_SENSE_2_MASK 0x00000040 /* Interrupt indication bit */
|
||||
#define PHY_INT0_RX_SENSE_3_MASK 0x00000080 /* Interrupt indication bit */
|
||||
|
||||
/* PHY RXSENSE, PLL Lock, and HPD Mask Register Mask register for generation of PHY_INT0 interrupts */
|
||||
#define PHY_MASK0 0x0000C018
|
||||
#define PHY_MASK0_TX_PHY_LOCK_MASK 0x00000001 /* Mask bit for PHY_INT0 */
|
||||
#define PHY_MASK0_HPD_MASK 0x00000002 /* Mask bit for PHY_INT0 */
|
||||
#define PHY_MASK0_RX_SENSE_0_MASK 0x00000010 /* Mask bit for PHY_INT0 */
|
||||
#define PHY_MASK0_RX_SENSE_1_MASK 0x00000020 /* Mask bit for PHY_INT0 */
|
||||
#define PHY_MASK0_RX_SENSE_2_MASK 0x00000040 /* Mask bit for PHY_INT0 */
|
||||
#define PHY_MASK0_RX_SENSE_3_MASK 0x00000080 /* Mask bit for PHY_INT0 */
|
||||
|
||||
/* PHY RXSENSE, PLL Lock, and HPD Polarity Register Polarity register for generation of PHY_INT0 interrupts */
|
||||
#define PHY_POL0 0x0000C01C
|
||||
#define PHY_POL0_TX_PHY_LOCK_MASK 0x00000001 /* Polarity bit for PHY_INT0 */
|
||||
#define PHY_POL0_HPD_MASK 0x00000002 /* Polarity bit for PHY_INT0 */
|
||||
#define PHY_POL0_RX_SENSE_0_MASK 0x00000010 /* Polarity bit for PHY_INT0 */
|
||||
#define PHY_POL0_RX_SENSE_1_MASK 0x00000020 /* Polarity bit for PHY_INT0 */
|
||||
#define PHY_POL0_RX_SENSE_2_MASK 0x00000040 /* Polarity bit for PHY_INT0 */
|
||||
#define PHY_POL0_RX_SENSE_3_MASK 0x00000080 /* Polarity bit for PHY_INT0 */
|
||||
|
||||
/* PHY I2C Slave Address Configuration Register */
|
||||
#define PHY_I2CM_SLAVE 0x0000C080
|
||||
#define PHY_I2CM_SLAVE_SLAVEADDR_MASK 0x0000007F /* Slave address to be sent during read and write operations */
|
||||
|
||||
/* PHY I2C Address Configuration Register This register writes the address for read and write operations */
|
||||
#define PHY_I2CM_ADDRESS 0x0000C084
|
||||
#define PHY_I2CM_ADDRESS_ADDRESS_MASK 0x000000FF /* Register address for read and write operations */
|
||||
|
||||
/* PHY I2C Data Write Register 1 */
|
||||
#define PHY_I2CM_DATAO_1 0x0000C088
|
||||
#define PHY_I2CM_DATAO_1_DATAO_MASK 0x000000FF /* Data MSB (datao[15:8]) to be written on register pointed by phy_i2cm_address [7:0] */
|
||||
|
||||
/* PHY I2C Data Write Register 0 */
|
||||
#define PHY_I2CM_DATAO_0 0x0000C08C
|
||||
#define PHY_I2CM_DATAO_0_DATAO_MASK 0x000000FF /* Data LSB (datao[7:0]) to be written on register pointed by phy_i2cm_address [7:0] */
|
||||
|
||||
/* PHY I2C Data Read Register 1 */
|
||||
#define PHY_I2CM_DATAI_1 0x0000C090
|
||||
#define PHY_I2CM_DATAI_1_DATAI_MASK 0x000000FF /* Data MSB (datai[15:8]) read from register pointed by phy_i2cm_address[7:0] */
|
||||
|
||||
/* PHY I2C Data Read Register 0 */
|
||||
#define PHY_I2CM_DATAI_0 0x0000C094
|
||||
#define PHY_I2CM_DATAI_0_DATAI_MASK 0x000000FF /* Data LSB (datai[7:0]) read from register pointed by phy_i2cm_address[7:0] */
|
||||
|
||||
/* PHY I2C RD/RD_EXT/WR Operation Register This register requests read and write operations from the I2C Master PHY */
|
||||
#define PHY_I2CM_OPERATION 0x0000C098
|
||||
#define PHY_I2CM_OPERATION_RD_MASK 0x00000001 /* Read operation request */
|
||||
#define PHY_I2CM_OPERATION_WR_MASK 0x00000010 /* Write operation request */
|
||||
|
||||
/* PHY I2C Done Interrupt Register This register contains and configures I2C master PHY done interrupt */
|
||||
#define PHY_I2CM_INT 0x0000C09C
|
||||
#define PHY_I2CM_INT_DONE_STATUS_MASK 0x00000001 /* Operation done status bit */
|
||||
#define PHY_I2CM_INT_DONE_INTERRUPT_MASK 0x00000002 /* Operation done interrupt bit */
|
||||
#define PHY_I2CM_INT_DONE_MASK_MASK 0x00000004 /* Done interrupt mask signal */
|
||||
#define PHY_I2CM_INT_DONE_POL_MASK 0x00000008 /* Done interrupt polarity configuration */
|
||||
|
||||
/* PHY I2C error Interrupt Register This register contains and configures the I2C master PHY error interrupts */
|
||||
#define PHY_I2CM_CTLINT 0x0000C0A0
|
||||
#define PHY_I2CM_CTLINT_ARBITRATION_STATUS_MASK 0x00000001 /* Arbitration error status bit */
|
||||
#define PHY_I2CM_CTLINT_ARBITRATION_INTERRUPT_MASK 0x00000002 /* Arbitration error interrupt bit {arbitration_interrupt = (arbitration_mask==0b) && (arbitration_status==arbitration_pol)} Note: This bit field is read by the sticky bits present on the ih_i2cmphy_stat0 register */
|
||||
#define PHY_I2CM_CTLINT_ARBITRATION_MASK_MASK 0x00000004 /* Arbitration error interrupt mask signal */
|
||||
#define PHY_I2CM_CTLINT_ARBITRATION_POL_MASK 0x00000008 /* Arbitration error interrupt polarity configuration */
|
||||
#define PHY_I2CM_CTLINT_NACK_STATUS_MASK 0x00000010 /* Not acknowledge error status bit */
|
||||
#define PHY_I2CM_CTLINT_NACK_INTERRUPT_MASK 0x00000020 /* Not acknowledge error interrupt bit */
|
||||
#define PHY_I2CM_CTLINT_NACK_MASK_MASK 0x00000040 /* Not acknowledge error interrupt mask signal */
|
||||
#define PHY_I2CM_CTLINT_NACK_POL_MASK 0x00000080 /* Not acknowledge error interrupt polarity configuration */
|
||||
|
||||
/* PHY I2C Speed control Register This register wets the I2C Master PHY to work in either Fast or Standard mode */
|
||||
#define PHY_I2CM_DIV 0x0000C0A4
|
||||
#define PHY_I2CM_DIV_SPARE_MASK 0x00000007 /* Reserved as "spare" register with no associated functionality */
|
||||
#define PHY_I2CM_DIV_FAST_STD_MODE_MASK 0x00000008 /* Sets the I2C Master to work in Fast Mode or Standard Mode: 1: Fast Mode 0: Standard Mode */
|
||||
|
||||
/* PHY I2C SW reset control register This register sets the I2C Master PHY software reset */
|
||||
#define PHY_I2CM_SOFTRSTZ 0x0000C0A8
|
||||
#define PHY_I2CM_SOFTRSTZ_I2C_SOFTRSTZ_MASK 0x00000001 /* I2C Master Software Reset */
|
||||
|
||||
/* PHY I2C Slow Speed SCL High Level Control Register 1 */
|
||||
#define PHY_I2CM_SS_SCL_HCNT_1_ADDR 0x0000C0AC
|
||||
#define PHY_I2CM_SS_SCL_HCNT_1_ADDR_I2CMP_SS_SCL_HCNT1_MASK 0x000000FF /* PHY I2C Slow Speed SCL High Level Control Register 1 */
|
||||
|
||||
/* PHY I2C Slow Speed SCL High Level Control Register 0 */
|
||||
#define PHY_I2CM_SS_SCL_HCNT_0_ADDR 0x0000C0B0
|
||||
#define PHY_I2CM_SS_SCL_HCNT_0_ADDR_I2CMP_SS_SCL_HCNT0_MASK 0x000000FF /* PHY I2C Slow Speed SCL High Level Control Register 0 */
|
||||
|
||||
/* PHY I2C Slow Speed SCL Low Level Control Register 1 */
|
||||
#define PHY_I2CM_SS_SCL_LCNT_1_ADDR 0x0000C0B4
|
||||
#define PHY_I2CM_SS_SCL_LCNT_1_ADDR_I2CMP_SS_SCL_LCNT1_MASK 0x000000FF /* PHY I2C Slow Speed SCL Low Level Control Register 1 */
|
||||
|
||||
/* PHY I2C Slow Speed SCL Low Level Control Register 0 */
|
||||
#define PHY_I2CM_SS_SCL_LCNT_0_ADDR 0x0000C0B8
|
||||
#define PHY_I2CM_SS_SCL_LCNT_0_ADDR_I2CMP_SS_SCL_LCNT0_MASK 0x000000FF /* PHY I2C Slow Speed SCL Low Level Control Register 0 */
|
||||
|
||||
/* PHY I2C Fast Speed SCL High Level Control Register 1 */
|
||||
#define PHY_I2CM_FS_SCL_HCNT_1_ADDR 0x0000C0BC
|
||||
#define PHY_I2CM_FS_SCL_HCNT_1_ADDR_I2CMP_FS_SCL_HCNT1_MASK 0x000000FF /* PHY I2C Fast Speed SCL High Level Control Register 1 */
|
||||
|
||||
/* PHY I2C Fast Speed SCL High Level Control Register 0 */
|
||||
#define PHY_I2CM_FS_SCL_HCNT_0_ADDR 0x0000C0C0
|
||||
#define PHY_I2CM_FS_SCL_HCNT_0_ADDR_I2CMP_FS_SCL_HCNT0_MASK 0x000000FF /* PHY I2C Fast Speed SCL High Level Control Register 0 */
|
||||
|
||||
/* PHY I2C Fast Speed SCL Low Level Control Register 1 */
|
||||
#define PHY_I2CM_FS_SCL_LCNT_1_ADDR 0x0000C0C4
|
||||
#define PHY_I2CM_FS_SCL_LCNT_1_ADDR_I2CMP_FS_SCL_LCNT1_MASK 0x000000FF /* PHY I2C Fast Speed SCL Low Level Control Register 1 */
|
||||
|
||||
/* PHY I2C Fast Speed SCL Low Level Control Register 0 */
|
||||
#define PHY_I2CM_FS_SCL_LCNT_0_ADDR 0x0000C0C8
|
||||
#define PHY_I2CM_FS_SCL_LCNT_0_ADDR_I2CMP_FS_SCL_LCNT0_MASK 0x000000FF /* PHY I2C Fast Speed SCL Low Level Control Register 0 */
|
||||
|
||||
/* PHY I2C SDA HOLD Control Register */
|
||||
#define PHY_I2CM_SDA_HOLD 0x0000C0CC
|
||||
#define PHY_I2CM_SDA_HOLD_OSDA_HOLD_MASK 0x000000FF /* Defines the number of SFR clock cycles to meet tHD:DAT (300 ns) osda_hold = round_to_high_integer (300 ns / (1/isfrclk_frequency)) */
|
||||
|
||||
/* PHY I2C/JTAG I/O Configuration Control Register */
|
||||
#define JTAG_PHY_CONFIG 0x0000C0D0
|
||||
#define JTAG_PHY_CONFIG_JTAG_TRST_N_MASK 0x00000001 /* Configures the JTAG PHY interface output pin JTAG_TRST_N when in internal control mode (iphy_ext_ctrl=1'b0) or ophyext_jtag_trst_n when PHY_EXTERNAL=1 */
|
||||
#define JTAG_PHY_CONFIG_I2C_JTAGZ_MASK 0x00000010 /* Configures the JTAG PHY interface output pin I2C_JTAGZ to select the PHY configuration interface when in internal control mode (iphy_ext_ctrl=1'b0) or ophyext_jtag_i2c_jtagz when PHY_EXTERNAL=1 */
|
||||
|
||||
/* PHY JTAG Clock Control Register */
|
||||
#define JTAG_PHY_TAP_TCK 0x0000C0D4
|
||||
#define JTAG_PHY_TAP_TCK_JTAG_TCK_MASK 0x00000001 /* Configures the JTAG PHY interface pin JTAG_TCK when in internal control mode (iphy_ext_ctrl=1'b0) or ophyext_jtag_tck when PHY_EXTERNAL=1 */
|
||||
|
||||
/* PHY JTAG TAP In Control Register */
|
||||
#define JTAG_PHY_TAP_IN 0x0000C0D8
|
||||
#define JTAG_PHY_TAP_IN_JTAG_TDI_MASK 0x00000001 /* Configures the JTAG PHY interface pin JTAG_TDI when in internal control mode (iphy_ext_ctrl=1'b0) or ophyext_jtag_tdi when PHY_EXTERNAL=1 */
|
||||
#define JTAG_PHY_TAP_IN_JTAG_TMS_MASK 0x00000010 /* Configures the JTAG PHY interface pin JTAG_TMS when in internal control mode (iphy_ext_ctrl=1'b0) or ophyext_jtag_tms when PHY_EXTERNAL=1 */
|
||||
|
||||
/* PHY JTAG TAP Out Control Register */
|
||||
#define JTAG_PHY_TAP_OUT 0x0000C0DC
|
||||
#define JTAG_PHY_TAP_OUT_JTAG_TDO_MASK 0x00000001 /* Read JTAG PHY interface input pin JTAG_TDO when in internal control mode (iphy_ext_ctrl=1'b0) or iphyext_jtag_tdo when PHY_EXTERNAL=1 */
|
||||
#define JTAG_PHY_TAP_OUT_JTAG_TDO_EN_MASK 0x00000010 /* Read JTAG PHY interface input pin JTAG_TDO_EN when in internal control mode (iphy_ext_ctrl=1'b0) or iphyext_jtag_tdo_en when PHY_EXTERNAL=1 */
|
||||
|
||||
/* PHY JTAG Address Control Register */
|
||||
#define JTAG_PHY_ADDR 0x0000C0E0
|
||||
#define JTAG_PHY_ADDR_JTAG_ADDR_MASK 0x000000FF /* Configures the JTAG PHY interface pin JTAG_ADDR[7:0] when in internal control mode (iphy_ext_ctrl=1'b0) or iphyext_jtag_addr[7:0] when PHY_EXTERNAL=1 */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Bring up PHY and start sending media for a specified pixel clock, pixel
|
||||
* repetition and color resolution (to calculate TMDS) - this fields must
|
||||
* be configured in the dev->snps_hdmi_ctrl variables
|
||||
* @param dev device structure
|
||||
* return TRUE if success, FALSE if not success and -1 if PHY configurations
|
||||
* are not supported.
|
||||
*/
|
||||
int phy_configure(hdmi_tx_dev_t *dev, u16 phy_model);
|
||||
|
||||
/**
|
||||
* Set PHY to standby mode - turn off all interrupts
|
||||
* @param dev device structure
|
||||
*/
|
||||
int phy_standby(hdmi_tx_dev_t *dev);
|
||||
|
||||
/**
|
||||
* Enable HPD sensing circuitry
|
||||
* @param dev device structure
|
||||
*/
|
||||
int phy_enable_hpd_sense(hdmi_tx_dev_t *dev);
|
||||
|
||||
/**
|
||||
* Disable HPD sensing circuitry
|
||||
* @param dev device structure
|
||||
*/
|
||||
int phy_disable_hpd_sense(hdmi_tx_dev_t *dev);
|
||||
|
||||
|
||||
/**
|
||||
* @param dev device structure
|
||||
* @param value of mask of interrupt register
|
||||
*/
|
||||
int phy_interrupt_enable(hdmi_tx_dev_t *dev, u8 value);
|
||||
|
||||
|
||||
int phy_i2c_read(hdmi_tx_dev_t *dev, u8 addr, u16 *value);
|
||||
int phy_i2c_write(hdmi_tx_dev_t *dev, u8 addr, u16 data);
|
||||
|
||||
u8 phy_hot_plug_state(hdmi_tx_dev_t *dev);
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* PHY_H_ */
|
||||
174
sunxi_spl/display/hdmi/scdc.c
Executable file
174
sunxi_spl/display/hdmi/scdc.c
Executable file
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Allwinner SoCs hdmi2.0 driver.
|
||||
*
|
||||
* Copyright (C) 2016 Allwinner.
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#include "scdc.h"
|
||||
#include "main_controller.h"
|
||||
|
||||
/*static void scdc_enable_rr(hdmi_tx_dev_t *dev, u8 enable);*/
|
||||
/*static int scdc_scrambling_status(hdmi_tx_dev_t *dev);*/
|
||||
static int scdc_scrambling_enable_flag(hdmi_tx_dev_t *dev, u8 flag);
|
||||
/*static void scdc_set_rr_flag(hdmi_tx_dev_t *dev, u8 enable);*/
|
||||
/*static int scdc_get_rr_flag(hdmi_tx_dev_t *dev, u8 *flag);*/
|
||||
|
||||
|
||||
int scdc_read(hdmi_tx_dev_t *dev, u8 address, u8 size, u8 *data)
|
||||
{
|
||||
if (ddc_read(dev, SCDC_SLAVE_ADDRESS, 0, 0, address, size, data)) {
|
||||
HDMI_ERROR_MSG("SCDC addr 0x%x read failed\n",
|
||||
address);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int scdc_write(hdmi_tx_dev_t *dev, u8 address, u8 size, u8 *data)
|
||||
{
|
||||
if (ddc_write(dev, SCDC_SLAVE_ADDRESS, address, size, data)) {
|
||||
HDMI_ERROR_MSG("SCDC addr 0x%x write failed\n",
|
||||
address);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void scrambling(hdmi_tx_dev_t *dev, u8 enable)
|
||||
{
|
||||
u8 data = 0;
|
||||
|
||||
LOG_TRACE1(enable);
|
||||
if (enable == 1) {
|
||||
scdc_scrambling_enable_flag(dev, 1);
|
||||
|
||||
/* Start/stop HDCP keep-out window generation not needed because it's always on */
|
||||
/* TMDS software reset request */
|
||||
mc_tmds_clock_reset(dev, TRUE);
|
||||
|
||||
/* Enable/Disable Scrambling */
|
||||
scrambling_Enable(dev, TRUE);
|
||||
|
||||
if (scdc_read(dev, SCDC_TMDS_CONFIG, 1 , &data))
|
||||
HDMI_INFO_MSG("%s: SCDC addr 0x%x read failed ", __func__, SCDC_TMDS_CONFIG);
|
||||
/* Write on RX the bit Scrambling_Enable, register 0x20 */
|
||||
data |= 0x02;
|
||||
scdc_write(dev, SCDC_TMDS_CONFIG, 1, &data);
|
||||
data |= 0x01;
|
||||
scdc_write(dev, SCDC_TMDS_CONFIG, 1, &data);
|
||||
} else {
|
||||
/* Enable/Disable Scrambling */
|
||||
scrambling_Enable(dev, FALSE);
|
||||
scdc_scrambling_enable_flag(dev, 0);
|
||||
|
||||
/* TMDS software reset request */
|
||||
mc_tmds_clock_reset(dev, TRUE);
|
||||
|
||||
/* Write on RX the bit Scrambling_Enable, register 0x20 */
|
||||
data = 0x00;
|
||||
scdc_write(dev, SCDC_TMDS_CONFIG, 1, &data);
|
||||
}
|
||||
}
|
||||
|
||||
void scrambling_Enable(hdmi_tx_dev_t *dev, u8 bit)
|
||||
{
|
||||
dev_write_mask(dev, FC_SCRAMBLER_CTRL,
|
||||
FC_SCRAMBLER_CTRL_SCRAMBLER_ON_MASK, bit);
|
||||
}
|
||||
|
||||
/*static void scdc_enable_rr(hdmi_tx_dev_t *dev, u8 enable)
|
||||
{
|
||||
|
||||
if (enable == 1) {*/
|
||||
/* Enable Readrequest from the Tx controller */
|
||||
/*dev_write_mask(dev, I2CM_SCDC_READ_UPDATE,
|
||||
I2CM_SCDC_READ_UPDATE_READ_REQUEST_EN_MASK, 1);
|
||||
scdc_set_rr_flag(dev, 0x01);
|
||||
irq_scdc_read_request(dev, TRUE);
|
||||
}*/
|
||||
/*if (enable == 0) {*/
|
||||
/* Disable ReadRequest on Tx controller */
|
||||
/*irq_scdc_read_request(dev, FALSE);
|
||||
scdc_set_rr_flag(dev, 0x00);
|
||||
dev_write_mask(dev, I2CM_SCDC_READ_UPDATE,
|
||||
I2CM_SCDC_READ_UPDATE_READ_REQUEST_EN_MASK, 0);
|
||||
}
|
||||
}*/
|
||||
|
||||
/*static int scdc_scrambling_status(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
u8 read_value = 0;
|
||||
|
||||
if (scdc_read(dev, SCDC_SCRAMBLER_STAT, 1, &read_value)) {
|
||||
HDMI_ERROR_MSG("SCDC addr 0x%x read failed\n",
|
||||
SCDC_SINK_VER);
|
||||
return 0;
|
||||
}
|
||||
return read_value & 0x01;
|
||||
}*/
|
||||
|
||||
static int scdc_scrambling_enable_flag(hdmi_tx_dev_t *dev, u8 enable)
|
||||
{
|
||||
u8 read_value = 0;
|
||||
|
||||
if (scdc_read(dev, SCDC_TMDS_CONFIG, 1, &read_value)) {
|
||||
HDMI_ERROR_MSG("SCDC addr 0x%x read failed\n",
|
||||
SCDC_TMDS_CONFIG);
|
||||
return -1;
|
||||
}
|
||||
read_value = set(read_value, 0x1, enable ? 0x1 : 0x0);
|
||||
if (scdc_write(dev, SCDC_TMDS_CONFIG, 1, &read_value)) {
|
||||
HDMI_ERROR_MSG("SCDC addr 0x%x write failed\n",
|
||||
SCDC_TMDS_CONFIG);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*static void scdc_set_rr_flag(hdmi_tx_dev_t *dev, u8 enable)
|
||||
{
|
||||
|
||||
if (ddc_write(dev, SCDC_SLAVE_ADDRESS, SCDC_CONFIG_0, 1, &enable)) {
|
||||
HDMI_ERROR_MSG("SCDC addr 0x%x - 0x%x write failed\n",
|
||||
SCDC_CONFIG_0, enable);
|
||||
}
|
||||
}*/
|
||||
|
||||
/*static int scdc_get_rr_flag(hdmi_tx_dev_t *dev, u8 *flag)
|
||||
{
|
||||
if (ddc_read(dev, SCDC_SLAVE_ADDRESS, 0, 0, SCDC_CONFIG_0, 1, flag)) {
|
||||
HDMI_ERROR_MSG("SCDC addr 0x%x read failed\n",
|
||||
SCDC_CONFIG_0);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}*/
|
||||
|
||||
/*static void scdc_test_rr(hdmi_tx_dev_t *dev, u8 test_rr_delay)
|
||||
{
|
||||
scdc_enable_rr(dev, 0x01);
|
||||
test_rr_delay = set(test_rr_delay, 0x80, 1);
|
||||
scdc_write(dev, SCDC_TEST_CFG_0, 1, &test_rr_delay);
|
||||
}*/
|
||||
|
||||
/*static int scdc_test_rr_update_flag(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
u8 read_value = 0;
|
||||
|
||||
if (scdc_read(dev, SCDC_UPDATE_0, 1, &read_value)) {
|
||||
HDMI_ERROR_MSG("SCDC addr 0x%x read failed\n",
|
||||
SCDC_UPDATE_0);
|
||||
return 0;
|
||||
}
|
||||
return read_value;
|
||||
}*/
|
||||
|
||||
u8 scrambling_state(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
return dev_read_mask(dev, FC_SCRAMBLER_CTRL,
|
||||
FC_SCRAMBLER_CTRL_SCRAMBLER_ON_MASK);
|
||||
}
|
||||
66
sunxi_spl/display/hdmi/scdc.h
Executable file
66
sunxi_spl/display/hdmi/scdc.h
Executable file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Allwinner SoCs hdmi2.0 driver.
|
||||
*
|
||||
* Copyright (C) 2016 Allwinner.
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SCDC_H_
|
||||
#define SCDC_H_
|
||||
|
||||
//#include "util.h"
|
||||
//#include "log.h"
|
||||
|
||||
#include "hdmitx_dev.h"
|
||||
#include "access.h"
|
||||
#include "irq.h"
|
||||
#include "frame_composer_reg.h"
|
||||
|
||||
|
||||
/* SCDC Registers */
|
||||
#define SCDC_SLAVE_ADDRESS 0x54
|
||||
|
||||
#define SCDC_SINK_VER 0x01 /* sink version */
|
||||
#define SCDC_SOURCE_VER 0x02 /* source version */
|
||||
#define SCDC_UPDATE_0 0x10 /* Update_0 */
|
||||
#define SCDC_UPDATE_0_STATUS 0x1 /* Status update flag */
|
||||
#define SCDC_UPDATE_0_CED 0x2 /* Character error update flag */
|
||||
#define SCDC_UPDATE_0_RR_TEST 0x4 /* Read request test */
|
||||
|
||||
#define SCDC_UPDATE_1 0x11 /* Update_1 */
|
||||
#define SCDC_UPDATE_RESERVED 0x12 /* 0x12-0x1f - Reserved for Update Related Uses */
|
||||
#define SCDC_TMDS_CONFIG 0x20 /* TMDS_Config */
|
||||
#define SCDC_SCRAMBLER_STAT 0x21 /* Scrambler_Status */
|
||||
#define SCDC_CONFIG_0 0x30 /* Config_0 */
|
||||
#define SCDC_CONFIG_RESERVED 0x31 /* 0x31-0x3f - Reserved for configuration */
|
||||
#define SCDC_STATUS_FLAG_0 0x40 /* Status_Flag_0 */
|
||||
#define SCDC_STATUS_FLAG_1 0x41 /* Status_Flag_1 */
|
||||
#define SCDC_STATUS_RESERVED 0x42 /* 0x42-0x4f - Reserved for Status Related Uses */
|
||||
#define SCDC_ERR_DET_0_L 0x50 /* Err_Det_0_L */
|
||||
#define SCDC_ERR_DET_0_H 0x51 /* Err_Det_0_H */
|
||||
#define SCDC_ERR_DET_1_L 0x52 /* Err_Det_1_L */
|
||||
#define SCDC_ERR_DET_1_H 0x53 /* Err_Det_1_H */
|
||||
#define SCDC_ERR_DET_2_L 0x54 /* Err_Det_2_L */
|
||||
#define SCDC_ERR_DET_2_H 0x55 /* Err_Det_2_H */
|
||||
#define SCDC_ERR_DET_CHKSUM 0x56 /* Err_Det_Checksum */
|
||||
#define SCDC_TEST_CFG_0 0xc0 /* Test_config_0 */
|
||||
#define SCDC_TEST_RESERVED 0xc1 /* 0xc1-0xcf - Reserved for test features */
|
||||
#define SCDC_MAN_OUI_3RD 0xd0 /* Manufacturer IEEE OUI, Third Octet */
|
||||
#define SCDC_MAN_OUI_2ND 0xd1 /* Manufacturer IEEE OUI, Second Octet */
|
||||
#define SCDC_MAN_OUI_1ST 0xd2 /* Manufacturer IEEE OUI, First Octet */
|
||||
#define SCDC_DEVICE_ID 0xd3 /* 0xd3-0xdd - Device ID */
|
||||
#define SCDC_MAN_SPECIFIC 0xde /* 0xde-0xff - ManufacturerSpecific */
|
||||
|
||||
|
||||
int scdc_read(hdmi_tx_dev_t *dev, u8 address, u8 size, u8 *data);
|
||||
int scdc_write(hdmi_tx_dev_t *dev, u8 address, u8 size, u8 *data);
|
||||
|
||||
void scrambling(hdmi_tx_dev_t *dev, u8 enable);
|
||||
void scrambling_Enable(hdmi_tx_dev_t *dev, u8 bit);
|
||||
u8 scrambling_state(hdmi_tx_dev_t *dev);
|
||||
|
||||
#endif /* SCDC_H_ */
|
||||
1037
sunxi_spl/display/hdmi/tcon.c
Executable file
1037
sunxi_spl/display/hdmi/tcon.c
Executable file
File diff suppressed because it is too large
Load Diff
69
sunxi_spl/display/hdmi/tcon.h
Executable file
69
sunxi_spl/display/hdmi/tcon.h
Executable file
@@ -0,0 +1,69 @@
|
||||
|
||||
|
||||
#ifndef __TCON_H__
|
||||
#define __TCON_H__
|
||||
|
||||
enum __lcd_src_t {
|
||||
LCD_SRC_DE = 0,
|
||||
LCD_SRC_COLOR_BAR = 1,
|
||||
LCD_SRC_GRAYSCALE = 2,
|
||||
LCD_SRC_BLACK_BY_WHITE = 3,
|
||||
LCD_SRC_BLACK = 4,
|
||||
LCD_SRC_WHITE = 5,
|
||||
LCD_SRC_GRID = 7,
|
||||
LCD_SRC_BLUE = 8
|
||||
};
|
||||
|
||||
enum __de_perh_t {
|
||||
LCD0 = 0,
|
||||
LCD1 = 1,
|
||||
TV0 = 2,
|
||||
TV1 = 3
|
||||
};
|
||||
|
||||
enum __lcd_irq_id_t {
|
||||
LCD_IRQ_TCON0_VBLK = 15,
|
||||
LCD_IRQ_TCON1_VBLK = 14,
|
||||
LCD_IRQ_TCON0_LINE = 13,
|
||||
LCD_IRQ_TCON1_LINE = 12,
|
||||
LCD_IRQ_TCON0_TRIF = 11,
|
||||
LCD_IRQ_TCON0_CNTR = 10,
|
||||
};
|
||||
|
||||
struct disp_video_timings
|
||||
{
|
||||
unsigned int vic; //video infomation code
|
||||
unsigned int tv_mode;
|
||||
unsigned int pixel_clk;//khz
|
||||
unsigned int pixel_repeat;//pixel repeat (pixel_repeat+1) times
|
||||
unsigned int x_res;
|
||||
unsigned int y_res;
|
||||
unsigned int hor_total_time;
|
||||
unsigned int hor_back_porch;
|
||||
unsigned int hor_front_porch;
|
||||
unsigned int hor_sync_time;
|
||||
unsigned int ver_total_time;
|
||||
unsigned int ver_back_porch;
|
||||
unsigned int ver_front_porch;
|
||||
unsigned int ver_sync_time;
|
||||
unsigned int hor_sync_polarity;//0: negative, 1: positive
|
||||
unsigned int ver_sync_polarity;//0: negative, 1: positive
|
||||
bool b_interlace;
|
||||
unsigned int vactive_space;
|
||||
unsigned int trd_mode;
|
||||
};
|
||||
|
||||
s32 tcon_init(u32 sel);
|
||||
s32 tcon1_open(u32 sel);
|
||||
s32 tcon1_cfg(u32 sel, struct disp_video_timings *timing);
|
||||
s32 tcon1_set_timming(u32 sel, struct disp_video_timings *timming);
|
||||
s32 tcon1_src_select(u32 sel, enum __lcd_src_t src, enum __de_perh_t de_no);
|
||||
s32 tcon_irq_enable(u32 sel, enum __lcd_irq_id_t id);
|
||||
s32 tcon_top_set_reg_base(u32 sel, u32 base);
|
||||
s32 tcon_set_reg_base(u32 sel, u32 base);
|
||||
s32 tcon_de_attach(u32 tcon_index, u32 de_index);
|
||||
s32 tcon1_hdmi_clk_enable(u32 sel, u32 en);
|
||||
s32 tcon1_black_src(u32 sel, u32 on_off, u32 color);
|
||||
|
||||
|
||||
#endif
|
||||
964
sunxi_spl/display/hdmi/video.c
Executable file
964
sunxi_spl/display/hdmi/video.c
Executable file
@@ -0,0 +1,964 @@
|
||||
/*
|
||||
* Allwinner SoCs hdmi2.0 driver.
|
||||
*
|
||||
* Copyright (C) 2016 Allwinner.
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
|
||||
#include "video.h"
|
||||
#include "fc_video.h"
|
||||
#include "phy.h"
|
||||
|
||||
typedef struct supported_dtd {
|
||||
u32 refresh_rate;/* 1HZ * 1000 */
|
||||
dtd_t dtd;
|
||||
} supported_dtd_t;
|
||||
|
||||
static supported_dtd_t _dtd[] = {
|
||||
/* pclk I/P Ha Hb Va Vb */
|
||||
{60000, { 1, 0, 0, 0, 25200, 0, 640, 160, 0, 4, 16, 96, 0, 480, 45, 0, 3, 10, 2, 0} },
|
||||
{59940, { 1, 0, 0, 0, 25175, 0, 640, 160, 0, 4, 16, 96, 0, 480, 45, 0, 3, 10, 2, 0} },
|
||||
{60000, { 2, 0, 0, 0, 27027, 0, 720, 138, 0, 4, 16, 62, 0, 480, 45, 0, 3, 9, 6, 0} },
|
||||
{59940, { 2, 0, 0, 0, 27000, 0, 720, 138, 0, 4, 16, 62, 0, 480, 45, 0, 3, 9, 6, 0} },
|
||||
{60000, { 3, 0, 0, 0, 27027, 0, 720, 138, 0, 16, 16, 62, 0, 480, 45, 0, 9, 9, 6, 0} },
|
||||
{59940, { 3, 0, 0, 0, 27000, 0, 720, 138, 0, 16, 16, 62, 0, 480, 45, 0, 9, 9, 6, 0} },
|
||||
{60000, { 4, 0, 0, 0, 74250, 0, 1280, 370, 0, 16, 110, 40, 1, 720, 30, 0, 9, 5, 5, 1} },
|
||||
{59940, { 4, 0, 0, 0, 74176, 0, 1280, 370, 0, 16, 110, 40, 1, 720, 30, 0, 9, 5, 5, 1} },
|
||||
{60000, { 5, 0, 0, 0, 74250, 1, 1920, 280, 0, 16, 88, 44, 1, 540, 22, 0, 9, 2, 5, 1} },
|
||||
{59940, { 5, 0, 0, 0, 74176, 1, 1920, 280, 0, 16, 88, 44, 1, 540, 22, 0, 9, 2, 5, 1} },
|
||||
{60000, { 6, 0, 0, 1, 27027, 1, 1440, 276, 0, 4, 38, 124, 0, 240, 22, 0, 3, 4, 3, 0} },
|
||||
{59940, { 6, 0, 0, 1, 27000, 1, 1440, 276, 0, 4, 38, 124, 0, 240, 22, 0, 3, 4, 3, 0} },
|
||||
{60000, { 7, 0, 0, 1, 27027, 1, 1440, 276, 0, 16, 38, 124, 0, 240, 22, 0, 9, 4, 3, 0} },
|
||||
{59940, { 7, 0, 0, 1, 27000, 1, 1440, 276, 0, 16, 38, 124, 0, 240, 22, 0, 9, 4, 3, 0} },
|
||||
{60000, { 8, 0, 0, 1, 27027, 0, 1440, 276, 0, 4, 38, 124, 0, 240, 22, 0, 3, 4, 3, 0} },
|
||||
{60054, { 8, 0, 0, 1, 27000, 0, 1440, 276, 0, 4, 38, 124, 0, 240, 22, 0, 3, 4, 3, 0} },
|
||||
{59826, { 8, 0, 0, 1, 27000, 0, 1440, 276, 0, 4, 38, 124, 0, 240, 23, 0, 3, 5, 3, 0} },
|
||||
{60000, { 9, 0, 0, 1, 27027, 0, 1440, 276, 0, 16, 38, 124, 0, 240, 22, 0, 9, 4, 3, 0} },
|
||||
{60054, { 9, 0, 0, 1, 27000, 0, 1440, 276, 0, 16, 38, 124, 0, 240, 22, 0, 9, 4, 3, 0} },
|
||||
{59826, { 9, 0, 0, 1, 27000, 0, 1440, 276, 0, 16, 38, 124, 0, 240, 23, 0, 9, 5, 3, 0} },
|
||||
{60000, { 10, 0, 0, 0, 54054, 1, 2880, 552, 0, 4, 76, 248, 0, 240, 22, 0, 3, 4, 3, 0} },
|
||||
{59940, { 11, 0, 0, 0, 54000, 1, 2880, 552, 0, 16, 76, 248, 0, 240, 22, 0, 9, 4, 3, 0} },
|
||||
{60000, { 12, 0, 0, 0, 54054, 0, 2880, 552, 0, 4, 76, 248, 0, 240, 22, 0, 3, 4, 3, 0} },
|
||||
{60054, { 12, 0, 0, 0, 54000, 0, 2880, 552, 0, 4, 76, 248, 0, 240, 22, 0, 3, 4, 3, 0} },
|
||||
{59826, { 12, 0, 0, 0, 54000, 0, 2880, 552, 0, 4, 76, 248, 0, 240, 23, 0, 3, 5, 3, 0} },
|
||||
{60000, { 13, 0, 0, 0, 54054, 0, 2880, 552, 0, 16, 76, 248, 0, 240, 22, 0, 9, 4, 3, 0} },
|
||||
{60054, { 13, 0, 0, 0, 54000, 0, 2880, 552, 0, 16, 76, 248, 0, 240, 22, 0, 9, 4, 3, 0} },
|
||||
{59826, { 13, 0, 0, 0, 54000, 0, 2880, 552, 0, 16, 76, 248, 0, 240, 23, 0, 9, 5, 3, 0} },
|
||||
{60000, { 14, 0, 0, 0, 54054, 0, 1440, 276, 0, 4, 32, 124, 0, 480, 45, 0, 3, 9, 6, 0} },
|
||||
{59940, { 14, 0, 0, 0, 54000, 0, 1440, 276, 0, 4, 32, 124, 0, 480, 45, 0, 3, 9, 6, 0} },
|
||||
{60000, { 15, 0, 0, 0, 54054, 0, 1440, 276, 0, 16, 32, 124, 0, 480, 45, 0, 9, 9, 6, 0} },
|
||||
{59940, { 15, 0, 0, 0, 54000, 0, 1440, 276, 0, 16, 32, 124, 0, 480, 45, 0, 9, 9, 6, 0} },
|
||||
{60000, { 16, 0, 0, 0, 148500, 0, 1920, 280, 0, 16, 88, 44, 1, 1080, 45, 0, 9, 4, 5, 1} },
|
||||
{59940, { 16, 0, 0, 0, 148352, 0, 1920, 280, 0, 16, 88, 44, 1, 1080, 45, 0, 9, 4, 5, 1} },
|
||||
{50000, { 17, 0, 0, 0, 27000, 0, 720, 144, 0, 4, 12, 64, 0, 576, 49, 0, 3, 5, 5, 0} },
|
||||
{50000, { 18, 0, 0, 0, 27000, 0, 720, 144, 0, 16, 12, 64, 0, 576, 49, 0, 9, 5, 5, 0} },
|
||||
{50000, { 19, 0, 0, 0, 74250, 0, 1280, 700, 0, 16, 440, 40, 1, 720, 30, 0, 9, 5, 5, 1} },
|
||||
{50000, { 20, 0, 0, 0, 74250, 1, 1920, 720, 0, 16, 528, 44, 1, 540, 22, 0, 9, 2, 5, 1} },
|
||||
{50000, { 21, 0, 0, 1, 27000, 1, 1440, 288, 0, 4, 24, 126, 0, 288, 24, 0, 3, 2, 3, 0} },
|
||||
{50000, { 22, 0, 0, 1, 27000, 1, 1440, 288, 0, 16, 24, 126, 0, 288, 24, 0, 9, 2, 3, 0} },
|
||||
{50000, { 23, 0, 0, 1, 27000, 0, 1440, 288, 0, 4, 24, 126, 0, 288, 24, 0, 3, 2, 3, 0} },
|
||||
{50000, { 23, 0, 0, 1, 27000, 0, 1440, 288, 0, 4, 24, 126, 0, 288, 24, 0, 3, 2, 3, 0} },
|
||||
{49920, { 23, 0, 0, 1, 27000, 0, 1440, 288, 0, 4, 24, 126, 0, 288, 25, 0, 3, 3, 3, 0} },
|
||||
{50000, { 24, 0, 0, 1, 27000, 0, 1440, 288, 0, 16, 24, 126, 0, 288, 24, 0, 9, 2, 3, 0} },
|
||||
{50000, { 24, 0, 0, 1, 27000, 0, 1440, 288, 0, 16, 24, 126, 0, 288, 24, 0, 9, 2, 3, 0} },
|
||||
{49920, { 24, 0, 0, 1, 27000, 0, 1440, 288, 0, 16, 24, 126, 0, 288, 25, 0, 9, 3, 3, 0} },
|
||||
{50000, { 25, 0, 0, 0, 54000, 1, 2880, 576, 0, 4, 48, 252, 0, 288, 24, 0, 3, 2, 3, 0} },
|
||||
{50000, { 26, 0, 0, 0, 54000, 1, 2880, 576, 0, 16, 48, 252, 0, 288, 24, 0, 9, 2, 3, 0} },
|
||||
{50000, { 27, 0, 0, 0, 54000, 0, 2880, 576, 0, 4, 48, 252, 0, 288, 24, 0, 3, 2, 3, 0} },
|
||||
{49920, { 27, 0, 0, 0, 54000, 0, 2880, 576, 0, 4, 48, 252, 0, 288, 25, 0, 3, 3, 3, 0} },
|
||||
{50000, { 27, 0, 0, 0, 54000, 0, 2880, 576, 0, 4, 48, 252, 0, 288, 24, 0, 3, 2, 3, 0} },
|
||||
{50000, { 28, 0, 0, 0, 54000, 0, 2880, 576, 0, 16, 48, 252, 0, 288, 24, 0, 9, 2, 3, 0} },
|
||||
{49920, { 28, 0, 0, 0, 54000, 0, 2880, 576, 0, 16, 48, 252, 0, 288, 25, 0, 9, 3, 3, 0} },
|
||||
{50000, { 28, 0, 0, 0, 54000, 0, 2880, 576, 0, 16, 48, 252, 0, 288, 24, 0, 9, 2, 3, 0} },
|
||||
{50000, { 29, 0, 0, 0, 54000, 0, 1440, 288, 0, 4, 24, 128, 0, 576, 49, 0, 3, 5, 5, 0} },
|
||||
{50000, { 30, 0, 0, 0, 54000, 0, 1440, 288, 0, 16, 24, 128, 0, 576, 49, 0, 9, 5, 5, 0} },
|
||||
{50000, { 31, 0, 0, 0, 148500, 0, 1920, 720, 0, 16, 528, 44, 1, 1080, 45, 0, 9, 4, 5, 1} },
|
||||
{24000, { 32, 0, 0, 0, 74250, 0, 1920, 830, 0, 16, 638, 44, 1, 1080, 45, 0, 9, 4, 5, 1} },
|
||||
{23976, { 32, 0, 0, 0, 74176, 0, 1920, 830, 0, 16, 638, 44, 1, 1080, 45, 0, 9, 4, 5, 1} },
|
||||
{25000, { 33, 0, 0, 0, 74250, 0, 1920, 720, 0, 16, 528, 44, 1, 1080, 45, 0, 9, 4, 5, 1} },
|
||||
{30000, { 34, 0, 0, 0, 74250, 0, 1920, 280, 0, 16, 88, 44, 1, 1080, 45, 0, 9, 4, 5, 1} },
|
||||
{29970, { 34, 0, 0, 0, 74176, 0, 1920, 280, 0, 16, 88, 44, 1, 1080, 45, 0, 9, 4, 5, 1} },
|
||||
{60000, { 35, 0, 0, 0, 108108, 0, 2880, 552, 0, 4, 64, 248, 0, 480, 45, 0, 3, 9, 6, 0} },
|
||||
{59940, { 35, 0, 0, 0, 108000, 0, 2880, 552, 0, 4, 64, 248, 0, 480, 45, 0, 3, 9, 6, 0} },
|
||||
{60000, { 36, 0, 0, 0, 108108, 0, 2880, 552, 0, 16, 64, 248, 0, 480, 45, 0, 9, 9, 6, 0} },
|
||||
{59940, { 36, 0, 0, 0, 108100, 0, 2880, 552, 0, 16, 64, 248, 0, 480, 45, 0, 9, 9, 6, 0} },
|
||||
{50000, { 37, 0, 0, 0, 108000, 0, 2880, 576, 0, 4, 48, 256, 0, 576, 49, 0, 3, 5, 5, 0} },
|
||||
{50000, { 38, 0, 0, 0, 108000, 0, 2880, 576, 0, 16, 48, 256, 0, 576, 49, 0, 9, 5, 5, 0} },
|
||||
{50000, { 39, 0, 0, 0, 72000, 1, 1920, 384, 0, 16, 32, 168, 1, 540, 85, 0, 9, 23, 5, 0} },
|
||||
{100000, { 40, 0, 0, 0, 148500, 1, 1920, 720, 0, 16, 528, 44, 1, 540, 22, 0, 9, 2, 5, 1} },
|
||||
{100000, { 41, 0, 0, 0, 148500, 0, 1280, 700, 0, 16, 440, 40, 1, 720, 30, 0, 9, 5, 5, 1} },
|
||||
{100000, { 42, 0, 0, 0, 54000, 0, 720, 144, 0, 4, 12, 64, 0, 576, 49, 0, 3, 5, 5, 0} },
|
||||
{100000, { 43, 0, 0, 0, 54000, 0, 720, 144, 0, 16, 12, 64, 0, 576, 49, 0, 9, 5, 5, 0} },
|
||||
{100000, { 44, 0, 0, 1, 54000, 1, 1440, 288, 0, 4, 24, 126, 0, 288, 24, 0, 3, 2, 3, 0} },
|
||||
{100000, { 45, 0, 0, 1, 54000, 1, 1440, 288, 0, 16, 24, 126, 0, 288, 24, 0, 9, 2, 3, 0} },
|
||||
{120000, { 46, 0, 0, 0, 148500, 1, 1920, 280, 0, 16, 88, 44, 1, 540, 22, 0, 9, 2, 5, 1} },
|
||||
{119880, { 46, 0, 0, 0, 148352, 1, 1920, 280, 0, 16, 88, 44, 1, 540, 22, 0, 9, 2, 5, 1} },
|
||||
{120000, { 47, 0, 0, 0, 148500, 0, 1280, 370, 0, 16, 110, 40, 1, 720, 30, 0, 9, 5, 5, 1} },
|
||||
{120000, { 48, 0, 0, 0, 54054, 0, 720, 138, 0, 4, 16, 62, 0, 480, 45, 0, 3, 9, 6, 0} },
|
||||
{120000, { 49, 0, 0, 0, 54054, 0, 720, 138, 0, 16, 16, 62, 0, 480, 45, 0, 9, 9, 6, 0} },
|
||||
{119880, { 49, 0, 0, 0, 54000, 0, 720, 138, 0, 16, 16, 62, 0, 480, 45, 0, 9, 9, 6, 0} },
|
||||
{120000, { 50, 0, 0, 1, 54054, 1, 1440, 276, 0, 4, 38, 124, 0, 240, 22, 0, 3, 4, 3, 0} },
|
||||
{119880, { 50, 0, 0, 1, 54000, 1, 1440, 276, 0, 4, 38, 124, 0, 240, 22, 0, 3, 4, 3, 0} },
|
||||
{120000, { 51, 0, 0, 1, 54054, 1, 1440, 276, 0, 16, 38, 124, 0, 240, 22, 0, 9, 4, 3, 0} },
|
||||
{119880, { 51, 0, 0, 1, 54000, 1, 1440, 276, 0, 16, 38, 124, 0, 240, 22, 0, 9, 4, 3, 0} },
|
||||
{200000, { 52, 0, 0, 0, 108000, 0, 720, 144, 0, 4, 12, 64, 0, 576, 49, 0, 3, 5, 5, 0} },
|
||||
{200000, { 53, 0, 0, 0, 108000, 0, 720, 144, 0, 16, 12, 64, 0, 576, 49, 0, 9, 5, 5, 0} },
|
||||
{200000, { 54, 0, 0, 1, 108000, 1, 1440, 288, 0, 4, 24, 126, 0, 288, 24, 0, 3, 2, 3, 0} },
|
||||
{200000, { 55, 0, 0, 1, 108000, 1, 1440, 288, 0, 16, 24, 126, 0, 288, 24, 0, 9, 2, 3, 0} },
|
||||
{240000, { 56, 0, 0, 0, 108100, 0, 720, 138, 0, 4, 16, 62, 0, 480, 45, 0, 3, 9, 6, 0} },
|
||||
{240000, { 57, 0, 0, 0, 108100, 0, 720, 138, 0, 16, 16, 62, 0, 480, 45, 0, 9, 9, 6, 0} },
|
||||
{239760, { 57, 0, 0, 0, 108000, 0, 720, 138, 0, 16, 16, 62, 0, 480, 45, 0, 9, 9, 6, 0} },
|
||||
{240000, { 58, 0, 0, 1, 108100, 1, 1440, 276, 0, 4, 38, 124, 0, 240, 22, 0, 3, 4, 3, 0} },
|
||||
{239760, { 58, 0, 0, 1, 108000, 1, 1440, 276, 0, 4, 38, 124, 0, 240, 22, 0, 3, 4, 3, 0} },
|
||||
{240000, { 59, 0, 0, 1, 108100, 1, 1440, 276, 0, 16, 38, 124, 0, 240, 22, 0, 9, 4, 3, 0} },
|
||||
{239760, { 59, 0, 0, 1, 108000, 1, 1440, 276, 0, 16, 38, 124, 0, 240, 22, 0, 9, 4, 3, 0} },
|
||||
{24000, { 60, 0, 0, 0, 59400, 0, 1280, 2020, 0, 16, 1760, 40, 1, 720, 30, 0, 9, 5, 5, 1} },
|
||||
{23970, { 60, 0, 0, 0, 59341, 0, 1280, 2020, 0, 16, 1760, 40, 1, 720, 30, 0, 9, 5, 5, 1} },
|
||||
{25000, { 61, 0, 0, 0, 74250, 0, 1280, 2680, 0, 16, 2420, 40, 1, 720, 30, 0, 9, 5, 5, 1} },
|
||||
{30000, { 62, 0, 0, 0, 74250, 0, 1280, 2020, 0, 16, 1760, 40, 1, 720, 30, 0, 9, 5, 5, 1} },
|
||||
{29970, { 62, 0, 0, 0, 74176, 0, 1280, 2020, 0, 16, 1760, 40, 1, 720, 30, 0, 9, 5, 5, 1} },
|
||||
{120000, { 63, 0, 0, 0, 297000, 0, 1920, 280, 0, 16, 88, 44, 1, 1080, 45, 0, 9, 4, 5, 1} },
|
||||
{119880, { 63, 0, 0, 0, 296703, 0, 1920, 280, 0, 16, 88, 44, 1, 1080, 45, 0, 9, 4, 5, 1} },
|
||||
{100000, { 64, 0, 0, 0, 297000, 0, 1920, 720, 0, 16, 528, 44, 1, 1080, 45, 0, 9, 4, 5, 1} },
|
||||
{50000, { 68, 0, 0, 0, 74250, 0, 1280, 700, 0, 16, 440, 40, 1, 720, 30, 0, 9, 5, 5, 1} },
|
||||
{60000, { 69, 0, 0, 0, 74250, 0, 1280, 370, 0, 16, 110, 40, 1, 720, 30, 0, 9, 5, 5, 1} },
|
||||
{50000, { 75, 0, 0, 0, 148500, 0, 1920, 720, 0, 16, 528, 44, 1, 1080, 45, 0, 9, 4, 5, 1} },
|
||||
{60000, { 76, 0, 0, 0, 148500, 0, 1920, 280, 0, 16, 88, 44, 1, 1080, 45, 0, 9, 4, 5, 1} },
|
||||
{24000, { 93, 0, 0, 0, 297000, 0, 3840, 1660, 0, 16, 1276, 88, 1, 2160, 90, 0, 9, 8, 10, 1} },
|
||||
{25000, { 94, 0, 0, 0, 297000, 0, 3840, 1440, 0, 16, 1056, 88, 1, 2160, 90, 0, 9, 8, 10, 1} },
|
||||
{30000, { 95, 0, 0, 0, 297000, 0, 3840, 560, 0, 16, 176, 88, 1, 2160, 90, 0, 9, 8, 10, 1} },
|
||||
{50000, { 96, 0, 0, 0, 594000, 0, 3840, 1440, 0, 16, 1056, 88, 1, 2160, 90, 0, 9, 8, 10, 1} },
|
||||
{60000, { 97, 0, 0, 0, 594000, 0, 3840, 560, 0, 16, 176, 88, 1, 2160, 90, 0, 9, 8, 10, 1} },
|
||||
{24000, { 98, 0, 0, 0, 297000, 0, 4096, 1404, 0, 16, 1020, 88, 1, 2160, 90, 0, 9, 8, 10, 1} },
|
||||
{25000, { 99, 0, 0, 0, 297000, 0, 4096, 1184, 0, 16, 968, 88, 1, 2160, 90, 0, 9, 8, 10, 1} },
|
||||
{30000, { 100, 0, 0, 0, 297000, 0, 4096, 304, 0, 16, 88, 88, 1, 2160, 90, 0, 9, 8, 10, 1} },
|
||||
{50000, { 101, 0, 0, 0, 594000, 0, 4096, 1184, 0, 16, 968, 88, 1, 2160, 90, 0, 9, 8, 10, 1} },
|
||||
{60000, { 102, 0, 0, 0, 594000, 0, 4096, 304, 0, 16, 88, 88, 1, 2160, 90, 0, 9, 8, 10, 1} },
|
||||
{30000, { 103, 0, 0, 0, 297000, 0, 3840, 1660, 0, 16, 1276, 88, 1, 2160, 90, 0, 9, 8, 10, 1} },
|
||||
{30000, { 104, 0, 0, 0, 297000, 0, 3840, 1440, 0, 16, 1056, 88, 1, 2160, 90, 0, 9, 8, 10, 1} },
|
||||
{30000, { 105, 0, 0, 0, 297000, 0, 3840, 560, 0, 16, 176, 88, 1, 2160, 90, 0, 9, 8, 10, 1} },
|
||||
{50000, { 106, 0, 0, 0, 594000, 0, 3840, 1440, 0, 16, 1056, 88, 1, 2160, 90, 0, 9, 8, 10, 1} },
|
||||
{60000, { 107, 0, 0, 0, 594000, 0, 3840, 560, 0, 16, 176, 88, 1, 2160, 90, 0, 9, 8, 10, 1} },
|
||||
{0.0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
|
||||
};
|
||||
|
||||
int videoParams_GetCeaVicCode(int hdmi_vic_code)
|
||||
{
|
||||
switch (hdmi_vic_code) {
|
||||
case 1:
|
||||
return 95;
|
||||
break;
|
||||
case 2:
|
||||
return 94;
|
||||
break;
|
||||
case 3:
|
||||
return 93;
|
||||
break;
|
||||
case 4:
|
||||
return 98;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int videoParams_GetHdmiVicCode(int cea_code)
|
||||
{
|
||||
switch (cea_code) {
|
||||
case 95:
|
||||
return 1;
|
||||
break;
|
||||
case 94:
|
||||
return 2;
|
||||
break;
|
||||
case 93:
|
||||
return 3;
|
||||
break;
|
||||
case 98:
|
||||
return 4;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
dtd_t *get_dtd(u8 code, u32 refreshRate)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; _dtd[i].dtd.mCode != 0; i++) {
|
||||
if (_dtd[i].dtd.mCode == code) {
|
||||
if (refreshRate == 0)
|
||||
return &_dtd[i].dtd;
|
||||
|
||||
if (refreshRate == _dtd[i].refresh_rate)
|
||||
return &_dtd[i].dtd;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int dtd_fill(hdmi_tx_dev_t *dev, dtd_t *dtd, u8 code, u32 refreshRate)
|
||||
{
|
||||
dtd_t *p_dtd = NULL;
|
||||
|
||||
HDMI_INFO_MSG("vic mode=%d\n", code);
|
||||
p_dtd = get_dtd(code, refreshRate);
|
||||
if (p_dtd == NULL) {
|
||||
HDMI_INFO_MSG("VIC code [%d] with refresh rate [%dHz] is not supported\n", code, refreshRate);
|
||||
return false;
|
||||
}
|
||||
p_dtd->mLimitedToYcc420 = false;
|
||||
p_dtd->mYcc420 = false;
|
||||
|
||||
memcpy(dtd, p_dtd, sizeof(dtd_t));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void video_params_reset(hdmi_tx_dev_t *dev, videoParams_t *params)
|
||||
{
|
||||
dtd_t dtd;
|
||||
|
||||
LOG_TRACE();
|
||||
dtd_fill(dev, &dtd, 1, 60000);
|
||||
|
||||
params->mHdmi = DVI;
|
||||
params->mEncodingOut = RGB;
|
||||
params->mEncodingIn = RGB;
|
||||
params->mColorResolution = COLOR_DEPTH_8;
|
||||
params->mPixelRepetitionFactor = 0;
|
||||
params->mRgbQuantizationRange = 0;
|
||||
params->mPixelPackingDefaultPhase = 0;
|
||||
params->mColorimetry = 0;
|
||||
params->mScanInfo = 0;
|
||||
params->mActiveFormatAspectRatio = 8;
|
||||
params->mNonUniformScaling = 0;
|
||||
params->mExtColorimetry = ~0;
|
||||
params->mItContent = 0;
|
||||
params->mEndTopBar = ~0;
|
||||
params->mStartBottomBar = ~0;
|
||||
params->mEndLeftBar = ~0;
|
||||
params->mStartRightBar = ~0;
|
||||
params->mCscFilter = 0;
|
||||
params->mHdmiVideoFormat = 0;
|
||||
params->m3dStructure = 0;
|
||||
params->m3dExtData = 0;
|
||||
params->mHdmiVic = 0;
|
||||
params->mHdmi20 = 0;
|
||||
|
||||
memcpy(¶ms->mDtd, &dtd, sizeof(dtd_t));
|
||||
|
||||
/* params->mDtd.mCode = 0; */
|
||||
/* params->mDtd.mLimitedToYcc420 = 0xFF; */
|
||||
/* params->mDtd.mYcc420 = 0xFF; */
|
||||
/* params->mDtd.mPixelRepetitionInput = 0xFF; */
|
||||
/* params->mDtd.mPixelClock = 0; */
|
||||
/* params->mDtd.mInterlaced = 0xFF; */
|
||||
/* params->mDtd.mHActive = 0; */
|
||||
/* params->mDtd.mHBlanking = 0; */
|
||||
/* params->mDtd.mHBorder = 0xFFFF; */
|
||||
/* params->mDtd.mHImageSize = 0; */
|
||||
/* params->mDtd.mHSyncOffset = 0; */
|
||||
/* params->mDtd.mHSyncPulseWidth = 0; */
|
||||
/* params->mDtd.mHSyncPolarity = 0xFF; */
|
||||
/* params->mDtd.mVActive = 0; */
|
||||
/* params->mDtd.mVBlanking = 0; */
|
||||
/* params->mDtd.mVBorder = 0xFFFF; */
|
||||
/* params->mDtd.mVImageSize = 0; */
|
||||
/* params->mDtd.mVSyncOffset = 0; */
|
||||
/* params->mDtd.mVSyncPulseWidth = 0; */
|
||||
/* params->mDtd.mVSyncPolarity = 0xFF; */
|
||||
}
|
||||
|
||||
u16 *videoParams_GetCscA(hdmi_tx_dev_t *dev, videoParams_t *params)
|
||||
{
|
||||
videoParams_UpdateCscCoefficients(dev, params);
|
||||
return params->mCscA;
|
||||
}
|
||||
|
||||
void videoParams_SetCscA(hdmi_tx_dev_t *dev,
|
||||
videoParams_t *params, u16 value[4])
|
||||
{
|
||||
u16 i = 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(params->mCscA); i++)
|
||||
params->mCscA[i] = value[i];
|
||||
|
||||
}
|
||||
|
||||
u16 *videoParams_GetCscB(hdmi_tx_dev_t *dev, videoParams_t *params)
|
||||
{
|
||||
videoParams_UpdateCscCoefficients(dev, params);
|
||||
return params->mCscB;
|
||||
}
|
||||
|
||||
void videoParams_SetCscB(hdmi_tx_dev_t *dev,
|
||||
videoParams_t *params, u16 value[4])
|
||||
{
|
||||
u16 i = 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(params->mCscB); i++)
|
||||
params->mCscB[i] = value[i];
|
||||
|
||||
}
|
||||
|
||||
u16 *videoParams_GetCscC(hdmi_tx_dev_t *dev, videoParams_t *params)
|
||||
{
|
||||
videoParams_UpdateCscCoefficients(dev, params);
|
||||
return params->mCscC;
|
||||
}
|
||||
|
||||
void videoParams_SetCscC(hdmi_tx_dev_t *dev,
|
||||
videoParams_t *params, u16 value[4])
|
||||
{
|
||||
u16 i = 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(params->mCscC); i++)
|
||||
params->mCscC[i] = value[i];
|
||||
|
||||
}
|
||||
|
||||
void videoParams_SetCscScale(hdmi_tx_dev_t *dev,
|
||||
videoParams_t *params, u16 value)
|
||||
{
|
||||
params->mCscScale = value;
|
||||
}
|
||||
|
||||
/* [KHz] */
|
||||
u32 videoParams_GetPixelClock(hdmi_tx_dev_t *dev, videoParams_t *params)
|
||||
{
|
||||
if (params->mHdmiVideoFormat == 2) {
|
||||
if (params->m3dStructure == 0)
|
||||
return 2 * params->mDtd.mPixelClock;
|
||||
}
|
||||
return params->mDtd.mPixelClock;
|
||||
}
|
||||
|
||||
/* 0.01 */
|
||||
unsigned videoParams_GetRatioClock(hdmi_tx_dev_t *dev, videoParams_t *params)
|
||||
{
|
||||
unsigned ratio = 100;
|
||||
|
||||
if (params->mEncodingOut != YCC422) {
|
||||
if (params->mColorResolution == 8)
|
||||
ratio = 100;
|
||||
else if (params->mColorResolution == 10)
|
||||
ratio = 125;
|
||||
else if (params->mColorResolution == 12)
|
||||
ratio = 150;
|
||||
else if (params->mColorResolution == 16)
|
||||
ratio = 200;
|
||||
}
|
||||
return ratio * (params->mPixelRepetitionFactor + 1);
|
||||
}
|
||||
|
||||
int videoParams_IsColorSpaceConversion(hdmi_tx_dev_t *dev,
|
||||
videoParams_t *params)
|
||||
{
|
||||
return params->mEncodingIn != params->mEncodingOut;
|
||||
}
|
||||
|
||||
int videoParams_IsColorSpaceDecimation(hdmi_tx_dev_t *dev,
|
||||
videoParams_t *params)
|
||||
{
|
||||
return params->mEncodingOut == YCC422 && (params->mEncodingIn == RGB
|
||||
|| params->mEncodingIn ==
|
||||
YCC444);
|
||||
}
|
||||
|
||||
int videoParams_IsColorSpaceInterpolation(hdmi_tx_dev_t *dev,
|
||||
videoParams_t *params)
|
||||
{
|
||||
return params->mEncodingIn == YCC422 && (params->mEncodingOut == RGB
|
||||
|| params->mEncodingOut ==
|
||||
YCC444);
|
||||
}
|
||||
|
||||
int videoParams_IsPixelRepetition(hdmi_tx_dev_t *dev, videoParams_t *params)
|
||||
{
|
||||
return (params->mPixelRepetitionFactor > 0) ||
|
||||
(params->mDtd.mPixelRepetitionInput > 0);
|
||||
}
|
||||
|
||||
void videoParams_UpdateCscCoefficients(hdmi_tx_dev_t *dev,
|
||||
videoParams_t *params)
|
||||
{
|
||||
u16 i = 0;
|
||||
|
||||
if (!videoParams_IsColorSpaceConversion(dev, params)) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
params->mCscA[i] = 0;
|
||||
params->mCscB[i] = 0;
|
||||
params->mCscC[i] = 0;
|
||||
}
|
||||
params->mCscA[0] = 0x2000;
|
||||
params->mCscB[1] = 0x2000;
|
||||
params->mCscC[2] = 0x2000;
|
||||
params->mCscScale = 1;
|
||||
} else if (videoParams_IsColorSpaceConversion(dev, params) &&
|
||||
params->mEncodingOut == RGB) {
|
||||
if (params->mColorimetry == ITU601) {
|
||||
params->mCscA[0] = 0x2000;
|
||||
params->mCscA[1] = 0x6926;
|
||||
params->mCscA[2] = 0x74fd;
|
||||
params->mCscA[3] = 0x010e;
|
||||
|
||||
params->mCscB[0] = 0x2000;
|
||||
params->mCscB[1] = 0x2cdd;
|
||||
params->mCscB[2] = 0x0000;
|
||||
params->mCscB[3] = 0x7e9a;
|
||||
|
||||
params->mCscC[0] = 0x2000;
|
||||
params->mCscC[1] = 0x0000;
|
||||
params->mCscC[2] = 0x38b4;
|
||||
params->mCscC[3] = 0x7e3b;
|
||||
|
||||
params->mCscScale = 1;
|
||||
} else if (params->mColorimetry == ITU709) {
|
||||
params->mCscA[0] = 0x2000;
|
||||
params->mCscA[1] = 0x7106;
|
||||
params->mCscA[2] = 0x7a02;
|
||||
params->mCscA[3] = 0x00a7;
|
||||
|
||||
params->mCscB[0] = 0x2000;
|
||||
params->mCscB[1] = 0x3264;
|
||||
params->mCscB[2] = 0x0000;
|
||||
params->mCscB[3] = 0x7e6d;
|
||||
|
||||
params->mCscC[0] = 0x2000;
|
||||
params->mCscC[1] = 0x0000;
|
||||
params->mCscC[2] = 0x3b61;
|
||||
params->mCscC[3] = 0x7e25;
|
||||
|
||||
params->mCscScale = 1;
|
||||
}
|
||||
} else if (videoParams_IsColorSpaceConversion(dev, params) &&
|
||||
params->mEncodingIn == RGB) {
|
||||
if (params->mColorimetry == ITU601) {
|
||||
params->mCscA[0] = 0x2591;
|
||||
params->mCscA[1] = 0x1322;
|
||||
params->mCscA[2] = 0x074b;
|
||||
params->mCscA[3] = 0x0000;
|
||||
|
||||
params->mCscB[0] = 0x6535;
|
||||
params->mCscB[1] = 0x2000;
|
||||
params->mCscB[2] = 0x7acc;
|
||||
params->mCscB[3] = 0x0200;
|
||||
|
||||
params->mCscC[0] = 0x6acd;
|
||||
params->mCscC[1] = 0x7534;
|
||||
params->mCscC[2] = 0x2000;
|
||||
params->mCscC[3] = 0x0200;
|
||||
|
||||
params->mCscScale = 0;
|
||||
} else if (params->mColorimetry == ITU709) {
|
||||
params->mCscA[0] = 0x2dc5;
|
||||
params->mCscA[1] = 0x0d9b;
|
||||
params->mCscA[2] = 0x049e;
|
||||
params->mCscA[3] = 0x0000;
|
||||
|
||||
params->mCscB[0] = 0x62f0;
|
||||
params->mCscB[1] = 0x2000;
|
||||
params->mCscB[2] = 0x7d11;
|
||||
params->mCscB[3] = 0x0200;
|
||||
|
||||
params->mCscC[0] = 0x6756;
|
||||
params->mCscC[1] = 0x78ab;
|
||||
params->mCscC[2] = 0x2000;
|
||||
params->mCscC[3] = 0x0200;
|
||||
|
||||
params->mCscScale = 0;
|
||||
}
|
||||
}
|
||||
/* else use user coefficients */
|
||||
}
|
||||
|
||||
char *getEncodingString(encoding_t encoding)
|
||||
{
|
||||
switch (encoding) {
|
||||
case RGB:
|
||||
return "RGB";
|
||||
case YCC444:
|
||||
return "YCbCr-444";
|
||||
case YCC422:
|
||||
return "YCbCr-422";
|
||||
case YCC420:
|
||||
return "YCbCr-420";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "Undefined";
|
||||
}
|
||||
|
||||
void halVideoSampler_InternalDataEnableGenerator(hdmi_tx_dev_t *dev, u8 bit)
|
||||
{
|
||||
LOG_TRACE1(bit);
|
||||
dev_write_mask(dev, TX_INVID0,
|
||||
TX_INVID0_INTERNAL_DE_GENERATOR_MASK, (bit ? 1 : 0));
|
||||
}
|
||||
|
||||
void halVideoSampler_VideoMapping(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write_mask(dev, TX_INVID0, TX_INVID0_VIDEO_MAPPING_MASK, value);
|
||||
}
|
||||
|
||||
void halVideoSampler_StuffingGy(hdmi_tx_dev_t *dev, u16 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write(dev, (TX_GYDATA0), (u8) (value >> 0));
|
||||
dev_write(dev, (TX_GYDATA1), (u8) (value >> 8));
|
||||
dev_write_mask(dev, TX_INSTUFFING,
|
||||
TX_INSTUFFING_GYDATA_STUFFING_MASK, 1);
|
||||
}
|
||||
|
||||
void halVideoSampler_StuffingRcr(hdmi_tx_dev_t *dev, u16 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write(dev, (TX_RCRDATA0), (u8) (value >> 0));
|
||||
dev_write(dev, (TX_RCRDATA1), (u8) (value >> 8));
|
||||
dev_write_mask(dev, TX_INSTUFFING,
|
||||
TX_INSTUFFING_RCRDATA_STUFFING_MASK, 1);
|
||||
}
|
||||
|
||||
void halVideoSampler_StuffingBcb(hdmi_tx_dev_t *dev, u16 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write(dev, (TX_BCBDATA0), (u8) (value >> 0));
|
||||
dev_write(dev, (TX_BCBDATA1), (u8) (value >> 8));
|
||||
dev_write_mask(dev, TX_INSTUFFING,
|
||||
TX_INSTUFFING_BCBDATA_STUFFING_MASK, 1);
|
||||
}
|
||||
|
||||
void video_sampler_config(hdmi_tx_dev_t *dev, u8 map_code)
|
||||
{
|
||||
halVideoSampler_InternalDataEnableGenerator(dev, 0);
|
||||
halVideoSampler_VideoMapping(dev, map_code);
|
||||
halVideoSampler_StuffingGy(dev, 0);
|
||||
halVideoSampler_StuffingRcr(dev, 0);
|
||||
halVideoSampler_StuffingBcb(dev, 0);
|
||||
}
|
||||
|
||||
u8 vp_PixelPackingPhase(hdmi_tx_dev_t *dev)
|
||||
{
|
||||
LOG_TRACE();
|
||||
return (u8)(dev_read(dev, VP_STATUS) & 0xF);
|
||||
}
|
||||
|
||||
void vp_ColorDepth(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
/* color depth */
|
||||
dev_write_mask(dev, VP_PR_CD, VP_PR_CD_COLOR_DEPTH_MASK, value);
|
||||
}
|
||||
|
||||
void vp_PixelPackingDefaultPhase(hdmi_tx_dev_t *dev, u8 bit)
|
||||
{
|
||||
LOG_TRACE1(bit);
|
||||
dev_write_mask(dev, VP_STUFF, VP_STUFF_IDEFAULT_PHASE_MASK, bit);
|
||||
}
|
||||
|
||||
/*be used if the user wants to do pixel repetition using H13TCTRL controller*/
|
||||
void vp_PixelRepetitionFactor(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
/* desired factor */
|
||||
dev_write_mask(dev, VP_PR_CD, VP_PR_CD_DESIRED_PR_FACTOR_MASK, value);
|
||||
/* enable stuffing */
|
||||
dev_write_mask(dev, VP_STUFF, VP_STUFF_PR_STUFFING_MASK, 1);
|
||||
/* enable block */
|
||||
dev_write_mask(dev, VP_CONF, VP_CONF_PR_EN_MASK, (value > 1) ? 1 : 0);
|
||||
/* bypass block */
|
||||
dev_write_mask(dev, VP_CONF, VP_CONF_BYPASS_SELECT_MASK,
|
||||
(value > 1) ? 0 : 1);
|
||||
}
|
||||
|
||||
void vp_Ycc422RemapSize(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write_mask(dev, VP_REMAP, VP_REMAP_YCC422_SIZE_MASK, value);
|
||||
}
|
||||
|
||||
void vp_OutputSelector(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
if (value == 0) { /* pixel packing */
|
||||
dev_write_mask(dev, VP_CONF, VP_CONF_BYPASS_EN_MASK, 0);
|
||||
/* enable pixel packing */
|
||||
dev_write_mask(dev, VP_CONF, VP_CONF_PP_EN_MASK, 1);
|
||||
dev_write_mask(dev, VP_CONF, VP_CONF_YCC422_EN_MASK, 0);
|
||||
} else if (value == 1) { /* YCC422 */
|
||||
dev_write_mask(dev, VP_CONF, VP_CONF_BYPASS_EN_MASK, 0);
|
||||
dev_write_mask(dev, VP_CONF, VP_CONF_PP_EN_MASK, 0);
|
||||
/* enable YCC422 */
|
||||
dev_write_mask(dev, VP_CONF, VP_CONF_YCC422_EN_MASK, 1);
|
||||
} else if (value == 2 || value == 3) { /* bypass */
|
||||
/* enable bypass */
|
||||
dev_write_mask(dev, VP_CONF, VP_CONF_BYPASS_EN_MASK, 1);
|
||||
dev_write_mask(dev, VP_CONF, VP_CONF_PP_EN_MASK, 0);
|
||||
dev_write_mask(dev, VP_CONF, VP_CONF_YCC422_EN_MASK, 0);
|
||||
} else {
|
||||
HDMI_ERROR_MSG("wrong output option: %d\n", value);
|
||||
return;
|
||||
}
|
||||
|
||||
/* YCC422 stuffing */
|
||||
dev_write_mask(dev, VP_STUFF, VP_STUFF_YCC422_STUFFING_MASK, 1);
|
||||
/* pixel packing stuffing */
|
||||
dev_write_mask(dev, VP_STUFF, VP_STUFF_PP_STUFFING_MASK, 1);
|
||||
|
||||
/* output selector */
|
||||
dev_write_mask(dev, VP_CONF, VP_CONF_OUTPUT_SELECTOR_MASK, value);
|
||||
}
|
||||
|
||||
|
||||
void csc_Interpolation(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
/* 2-bit width */
|
||||
dev_write_mask(dev, CSC_CFG, CSC_CFG_INTMODE_MASK, value);
|
||||
}
|
||||
|
||||
void csc_Decimation(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
/* 2-bit width */
|
||||
dev_write_mask(dev, CSC_CFG, CSC_CFG_DECMODE_MASK, value);
|
||||
}
|
||||
|
||||
void csc_ColorDepth(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
/* 4-bit width */
|
||||
dev_write_mask(dev, CSC_SCALE, CSC_SCALE_CSC_COLOR_DEPTH_MASK, value);
|
||||
}
|
||||
|
||||
void csc_ScaleFactor(hdmi_tx_dev_t *dev, u8 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
/* 2-bit width */
|
||||
dev_write_mask(dev, CSC_SCALE, CSC_SCALE_CSCSCALE_MASK, value);
|
||||
}
|
||||
|
||||
void csc_CoefficientA1(hdmi_tx_dev_t *dev, u16 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
/* 15-bit width */
|
||||
dev_write(dev, CSC_COEF_A1_LSB, (u8)(value));
|
||||
dev_write_mask(dev, CSC_COEF_A1_MSB,
|
||||
CSC_COEF_A1_MSB_CSC_COEF_A1_MSB_MASK, (u8)(value >> 8));
|
||||
}
|
||||
|
||||
void csc_CoefficientA2(hdmi_tx_dev_t *dev, u16 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
/* 15-bit width */
|
||||
dev_write(dev, CSC_COEF_A2_LSB, (u8)(value));
|
||||
dev_write_mask(dev, CSC_COEF_A2_MSB,
|
||||
CSC_COEF_A2_MSB_CSC_COEF_A2_MSB_MASK, (u8)(value >> 8));
|
||||
}
|
||||
|
||||
void csc_CoefficientA3(hdmi_tx_dev_t *dev, u16 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
/* 15-bit width */
|
||||
dev_write(dev, CSC_COEF_A3_LSB, (u8)(value));
|
||||
dev_write_mask(dev, CSC_COEF_A3_MSB,
|
||||
CSC_COEF_A3_MSB_CSC_COEF_A3_MSB_MASK, (u8)(value >> 8));
|
||||
}
|
||||
|
||||
void csc_CoefficientA4(hdmi_tx_dev_t *dev, u16 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
/* 15-bit width */
|
||||
dev_write(dev, CSC_COEF_A4_LSB, (u8)(value));
|
||||
dev_write_mask(dev, CSC_COEF_A4_MSB,
|
||||
CSC_COEF_A4_MSB_CSC_COEF_A4_MSB_MASK, (u8)(value >> 8));
|
||||
}
|
||||
|
||||
void csc_CoefficientB1(hdmi_tx_dev_t *dev, u16 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
/* 15-bit width */
|
||||
dev_write(dev, CSC_COEF_B1_LSB, (u8)(value));
|
||||
dev_write_mask(dev, CSC_COEF_B1_MSB,
|
||||
CSC_COEF_B1_MSB_CSC_COEF_B1_MSB_MASK, (u8)(value >> 8));
|
||||
}
|
||||
|
||||
void csc_CoefficientB2(hdmi_tx_dev_t *dev, u16 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
/* 15-bit width */
|
||||
dev_write(dev, CSC_COEF_B2_LSB, (u8)(value));
|
||||
dev_write_mask(dev, CSC_COEF_B2_MSB,
|
||||
CSC_COEF_B2_MSB_CSC_COEF_B2_MSB_MASK, (u8)(value >> 8));
|
||||
}
|
||||
|
||||
void csc_CoefficientB3(hdmi_tx_dev_t *dev, u16 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
/* 15-bit width */
|
||||
dev_write(dev, CSC_COEF_B3_LSB, (u8)(value));
|
||||
dev_write_mask(dev, CSC_COEF_B3_MSB,
|
||||
CSC_COEF_B3_MSB_CSC_COEF_B3_MSB_MASK, (u8)(value >> 8));
|
||||
}
|
||||
|
||||
void csc_CoefficientB4(hdmi_tx_dev_t *dev, u16 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
/* 15-bit width */
|
||||
dev_write(dev, CSC_COEF_B4_LSB, (u8)(value));
|
||||
dev_write_mask(dev, CSC_COEF_B4_MSB,
|
||||
CSC_COEF_B4_MSB_CSC_COEF_B4_MSB_MASK, (u8)(value >> 8));
|
||||
}
|
||||
|
||||
void csc_CoefficientC1(hdmi_tx_dev_t *dev, u16 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
/* 15-bit width */
|
||||
dev_write(dev, CSC_COEF_C1_LSB, (u8) (value));
|
||||
dev_write_mask(dev, CSC_COEF_C1_MSB,
|
||||
CSC_COEF_C1_MSB_CSC_COEF_C1_MSB_MASK, (u8)(value >> 8));
|
||||
}
|
||||
|
||||
void csc_CoefficientC2(hdmi_tx_dev_t *dev, u16 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
/* 15-bit width */
|
||||
dev_write(dev, CSC_COEF_C2_LSB, (u8) (value));
|
||||
dev_write_mask(dev, CSC_COEF_C2_MSB,
|
||||
CSC_COEF_C2_MSB_CSC_COEF_C2_MSB_MASK, (u8)(value >> 8));
|
||||
}
|
||||
|
||||
void csc_CoefficientC3(hdmi_tx_dev_t *dev, u16 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
/* 15-bit width */
|
||||
dev_write(dev, CSC_COEF_C3_LSB, (u8) (value));
|
||||
dev_write_mask(dev, CSC_COEF_C3_MSB,
|
||||
CSC_COEF_C3_MSB_CSC_COEF_C3_MSB_MASK, (u8)(value >> 8));
|
||||
}
|
||||
|
||||
void csc_CoefficientC4(hdmi_tx_dev_t *dev, u16 value)
|
||||
{
|
||||
LOG_TRACE1(value);
|
||||
dev_write(dev, CSC_COEF_C4_LSB, (u8) (value));
|
||||
dev_write_mask(dev, CSC_COEF_C4_MSB,
|
||||
CSC_COEF_C4_MSB_CSC_COEF_C4_MSB_MASK, (u8)(value >> 8));
|
||||
}
|
||||
|
||||
void csc_config(hdmi_tx_dev_t *dev, videoParams_t *video,
|
||||
unsigned interpolation, unsigned decimation, unsigned color_depth)
|
||||
{
|
||||
csc_Interpolation(dev, interpolation);
|
||||
csc_Decimation(dev, decimation);
|
||||
csc_CoefficientA1(dev, video->mCscA[0]);
|
||||
csc_CoefficientA2(dev, video->mCscA[1]);
|
||||
csc_CoefficientA3(dev, video->mCscA[2]);
|
||||
csc_CoefficientA4(dev, video->mCscA[3]);
|
||||
csc_CoefficientB1(dev, video->mCscB[0]);
|
||||
csc_CoefficientB2(dev, video->mCscB[1]);
|
||||
csc_CoefficientB3(dev, video->mCscB[2]);
|
||||
csc_CoefficientB4(dev, video->mCscB[3]);
|
||||
csc_CoefficientC1(dev, video->mCscC[0]);
|
||||
csc_CoefficientC2(dev, video->mCscC[1]);
|
||||
csc_CoefficientC3(dev, video->mCscC[2]);
|
||||
csc_CoefficientC4(dev, video->mCscC[3]);
|
||||
csc_ScaleFactor(dev, video->mCscScale);
|
||||
csc_ColorDepth(dev, color_depth);
|
||||
}
|
||||
|
||||
int video_Initialize(hdmi_tx_dev_t *dev, videoParams_t *video,
|
||||
u8 dataEnablePolarity)
|
||||
{
|
||||
LOG_TRACE1(dataEnablePolarity);
|
||||
return true;
|
||||
}
|
||||
|
||||
int video_Configure(hdmi_tx_dev_t *dev, videoParams_t *video)
|
||||
{
|
||||
LOG_TRACE();
|
||||
|
||||
/* DVI mode does not support pixel repetition */
|
||||
if ((video->mHdmi == DVI) &&
|
||||
videoParams_IsPixelRepetition(dev, video)) {
|
||||
//error_set(ERR_DVI_MODE_WITH_PIXEL_REPETITION);
|
||||
HDMI_ERROR_MSG("DVI mode with pixel repetition:video not transmitted\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
fc_force_output(dev, 1);
|
||||
|
||||
if (fc_video_config(dev, video) == false)
|
||||
return false;
|
||||
if (video_VideoPacketizer(dev, video) == false)
|
||||
return false;
|
||||
if (video_ColorSpaceConverter(dev, video) == false)
|
||||
return false;
|
||||
if (video_VideoSampler(dev, video) == false)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int video_ColorSpaceConverter(hdmi_tx_dev_t *dev, videoParams_t *video)
|
||||
{
|
||||
unsigned interpolation = 0;
|
||||
unsigned decimation = 0;
|
||||
unsigned color_depth = 0;
|
||||
|
||||
LOG_TRACE();
|
||||
|
||||
if (videoParams_IsColorSpaceInterpolation(dev, video)) {
|
||||
if (video->mCscFilter > 1) {
|
||||
//error_set(ERR_CHROMA_INTERPOLATION_FILTER_INVALID);
|
||||
HDMI_ERROR_MSG("invalid chroma interpolation filter:%d\n", video->mCscFilter);
|
||||
return false;
|
||||
}
|
||||
interpolation = 1 + video->mCscFilter;
|
||||
} else if (videoParams_IsColorSpaceDecimation(dev, video)) {
|
||||
if (video->mCscFilter > 2) {
|
||||
//error_set(ERR_CHROMA_DECIMATION_FILTER_INVALID);
|
||||
HDMI_ERROR_MSG("invalid chroma decimation filter:%d\n", video->mCscFilter);
|
||||
return false;
|
||||
}
|
||||
decimation = 1 + video->mCscFilter;
|
||||
}
|
||||
|
||||
if ((video->mColorResolution == COLOR_DEPTH_8) ||
|
||||
(video->mColorResolution == 0))
|
||||
color_depth = 4;
|
||||
else if (video->mColorResolution == COLOR_DEPTH_10)
|
||||
color_depth = 5;
|
||||
else if (video->mColorResolution == COLOR_DEPTH_12)
|
||||
color_depth = 6;
|
||||
else if (video->mColorResolution == COLOR_DEPTH_16)
|
||||
color_depth = 7;
|
||||
else {
|
||||
//error_set(ERR_COLOR_DEPTH_NOT_SUPPORTED);
|
||||
HDMI_ERROR_MSG("invalid color depth: %d\n",
|
||||
video->mColorResolution);
|
||||
return false;
|
||||
}
|
||||
|
||||
csc_config(dev, video, interpolation, decimation, color_depth);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int video_VideoPacketizer(hdmi_tx_dev_t *dev, videoParams_t *video)
|
||||
{
|
||||
unsigned color_depth = 0;
|
||||
unsigned remap_size = 0;
|
||||
unsigned output_select = 0;
|
||||
|
||||
LOG_TRACE();
|
||||
if ((video->mEncodingOut == RGB) || (video->mEncodingOut == YCC444) ||
|
||||
(video->mEncodingOut == YCC420)) {
|
||||
if (video->mColorResolution == 0)
|
||||
output_select = 3;
|
||||
else if (video->mColorResolution == COLOR_DEPTH_8) {
|
||||
color_depth = 0;
|
||||
output_select = 3;
|
||||
} else if (video->mColorResolution == COLOR_DEPTH_10)
|
||||
color_depth = 5;
|
||||
else if (video->mColorResolution == COLOR_DEPTH_12)
|
||||
color_depth = 6;
|
||||
else if (video->mColorResolution == COLOR_DEPTH_16)
|
||||
color_depth = 7;
|
||||
else {
|
||||
//error_set(ERR_COLOR_DEPTH_NOT_SUPPORTED);
|
||||
HDMI_ERROR_MSG("invalid color depth: %d\n",
|
||||
video->mColorResolution);
|
||||
return false;
|
||||
}
|
||||
} else if (video->mEncodingOut == YCC422) {
|
||||
if ((video->mColorResolution == COLOR_DEPTH_8) ||
|
||||
(video->mColorResolution == 0))
|
||||
remap_size = 0;
|
||||
else if (video->mColorResolution == COLOR_DEPTH_10)
|
||||
remap_size = 1;
|
||||
else if (video->mColorResolution == COLOR_DEPTH_12)
|
||||
remap_size = 2;
|
||||
else {
|
||||
//error_set(ERR_COLOR_REMAP_SIZE_INVALID);
|
||||
HDMI_ERROR_MSG("invalid color remap size: %d\n",
|
||||
video->mColorResolution);
|
||||
return false;
|
||||
}
|
||||
output_select = 1;
|
||||
} else {
|
||||
//error_set(ERR_OUTPUT_ENCODING_TYPE_INVALID);
|
||||
HDMI_ERROR_MSG("invalid output encoding type: %d\n",
|
||||
video->mEncodingOut);
|
||||
return false;
|
||||
}
|
||||
|
||||
vp_PixelRepetitionFactor(dev, video->mPixelRepetitionFactor);
|
||||
vp_ColorDepth(dev, color_depth);
|
||||
vp_PixelPackingDefaultPhase(dev, video->mPixelPackingDefaultPhase);
|
||||
vp_Ycc422RemapSize(dev, remap_size);
|
||||
vp_OutputSelector(dev, output_select);
|
||||
return true;
|
||||
}
|
||||
|
||||
int video_VideoSampler(hdmi_tx_dev_t *dev, videoParams_t *video)
|
||||
{
|
||||
unsigned map_code = 0;
|
||||
|
||||
LOG_TRACE();
|
||||
|
||||
if (video->mEncodingIn == RGB || video->mEncodingIn == YCC444
|
||||
|| video->mEncodingIn == YCC420) {
|
||||
if ((video->mColorResolution == COLOR_DEPTH_8) ||
|
||||
(video->mColorResolution == 0))
|
||||
map_code = 1;
|
||||
else if (video->mColorResolution == COLOR_DEPTH_10)
|
||||
map_code = 3;
|
||||
else if (video->mColorResolution == COLOR_DEPTH_12)
|
||||
map_code = 5;
|
||||
else if (video->mColorResolution == COLOR_DEPTH_16)
|
||||
map_code = 7;
|
||||
else {
|
||||
//error_set(ERR_COLOR_DEPTH_NOT_SUPPORTED);
|
||||
HDMI_ERROR_MSG("invalid color depth: %d\n",
|
||||
video->mColorResolution);
|
||||
return false;
|
||||
}
|
||||
map_code += (video->mEncodingIn == YCC444) ? 22 : 0;
|
||||
map_code += (video->mEncodingIn == YCC420) ? 8 : 0;
|
||||
} else if (video->mEncodingIn == YCC422) {
|
||||
/* YCC422 mapping is discontinued - only map 1 is supported */
|
||||
if (video->mColorResolution == COLOR_DEPTH_12)
|
||||
map_code = 18;
|
||||
else if (video->mColorResolution == COLOR_DEPTH_10)
|
||||
map_code = 20;
|
||||
else if ((video->mColorResolution == COLOR_DEPTH_8) ||
|
||||
(video->mColorResolution == 0))
|
||||
map_code = 22;
|
||||
else {
|
||||
//error_set(ERR_COLOR_REMAP_SIZE_INVALID);
|
||||
HDMI_ERROR_MSG("invalid color remap size: %d\n",
|
||||
video->mColorResolution);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
//error_set(ERR_INPUT_ENCODING_TYPE_INVALID);
|
||||
HDMI_ERROR_MSG("invalid input encoding type: %d\n",
|
||||
video->mEncodingIn);
|
||||
return false;
|
||||
}
|
||||
|
||||
video_sampler_config(dev, map_code);
|
||||
|
||||
return true;
|
||||
}
|
||||
549
sunxi_spl/display/hdmi/video.h
Executable file
549
sunxi_spl/display/hdmi/video.h
Executable file
@@ -0,0 +1,549 @@
|
||||
/*
|
||||
* Allwinner SoCs hdmi2.0 driver.
|
||||
*
|
||||
* Copyright (C) 2016 Allwinner.
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef VIDEO_H_
|
||||
#define VIDEO_H_
|
||||
/**
|
||||
* @file
|
||||
* Video controller layer.
|
||||
* Configure and set up the video transmitted to sink.
|
||||
* This includes colour-space conversion as well as pixel packetising.
|
||||
*/
|
||||
|
||||
#include "hdmitx_dev.h"
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* *
|
||||
* Video Sampler Registers *
|
||||
* *
|
||||
*****************************************************************************/
|
||||
|
||||
/* Video Input Mapping and Internal Data Enable Configuration Register */
|
||||
#define TX_INVID0 0x00000800
|
||||
#define TX_INVID0_VIDEO_MAPPING_MASK 0x0000001F /* Video Input mapping (color space/color depth): 0x01: RGB 4:4:4/8 bits 0x03: RGB 4:4:4/10 bits 0x05: RGB 4:4:4/12 bits 0x07: RGB 4:4:4/16 bits 0x09: YCbCr 4:4:4 or 4:2:0/8 bits 0x0B: YCbCr 4:4:4 or 4:2:0/10 bits 0x0D: YCbCr 4:4:4 or 4:2:0/12 bits 0x0F: YCbCr 4:4:4 or 4:2:0/16 bits 0x16: YCbCr 4:2:2/8 bits 0x14: YCbCr 4:2:2/10 bits 0x12: YCbCr 4:2:2/12 bits 0x17: YCbCr 4:4:4 (IPI)/8 bits 0x18: YCbCr 4:4:4 (IPI)/10 bits 0x19: YCbCr 4:4:4 (IPI)/12 bits 0x1A: YCbCr 4:4:4 (IPI)/16 bits 0x1B: YCbCr 4:2:2 (IPI)/12 bits 0x1C: YCbCr 4:2:0 (IPI)/8 bits 0x1D: YCbCr 4:2:0 (IPI)/10 bits 0x1E: YCbCr 4:2:0 (IPI)/12 bits 0x1F: YCbCr 4:2:0 (IPI)/16 bits */
|
||||
#define TX_INVID0_INTERNAL_DE_GENERATOR_MASK 0x00000080 /* Internal data enable (DE) generator enable */
|
||||
|
||||
/* Video Input Stuffing Enable Register */
|
||||
#define TX_INSTUFFING 0x00000804
|
||||
#define TX_INSTUFFING_GYDATA_STUFFING_MASK 0x00000001 /* - 0b: When the dataen signal is low, the value in the gydata[15:0] output is the one sampled from the corresponding input data */
|
||||
#define TX_INSTUFFING_RCRDATA_STUFFING_MASK 0x00000002 /* - 0b: When the dataen signal is low, the value in the rcrdata[15:0] output is the one sampled from the corresponding input data */
|
||||
#define TX_INSTUFFING_BCBDATA_STUFFING_MASK 0x00000004 /* - 0b: When the dataen signal is low, the value in the bcbdata[15:0] output is the one sampled from the corresponding input data */
|
||||
|
||||
/* Video Input gy Data Channel Stuffing Register 0 */
|
||||
#define TX_GYDATA0 0x00000808
|
||||
#define TX_GYDATA0_GYDATA_MASK 0x000000FF /* This register defines the value of gydata[7:0] when TX_INSTUFFING[0] (gydata_stuffing) is set to 1b */
|
||||
|
||||
/* Video Input gy Data Channel Stuffing Register 1 */
|
||||
#define TX_GYDATA1 0x0000080C
|
||||
#define TX_GYDATA1_GYDATA_MASK 0x000000FF /* This register defines the value of gydata[15:8] when TX_INSTUFFING[0] (gydata_stuffing) is set to 1b */
|
||||
|
||||
/* Video Input rcr Data Channel Stuffing Register 0 */
|
||||
#define TX_RCRDATA0 0x00000810
|
||||
#define TX_RCRDATA0_RCRDATA_MASK 0x000000FF /* This register defines the value of rcrydata[7:0] when TX_INSTUFFING[1] (rcrdata_stuffing) is set to 1b */
|
||||
|
||||
/* Video Input rcr Data Channel Stuffing Register 1 */
|
||||
#define TX_RCRDATA1 0x00000814
|
||||
#define TX_RCRDATA1_RCRDATA_MASK 0x000000FF /* This register defines the value of rcrydata[15:8] when TX_INSTUFFING[1] (rcrdata_stuffing) is set to 1b */
|
||||
|
||||
/* Video Input bcb Data Channel Stuffing Register 0 */
|
||||
#define TX_BCBDATA0 0x00000818
|
||||
#define TX_BCBDATA0_BCBDATA_MASK 0x000000FF /* This register defines the value of bcbdata[7:0] when TX_INSTUFFING[2] (bcbdata_stuffing) is set to 1b */
|
||||
|
||||
/* Video Input bcb Data Channel Stuffing Register 1 */
|
||||
#define TX_BCBDATA1 0x0000081C
|
||||
#define TX_BCBDATA1_BCBDATA_MASK 0x000000FF /* This register defines the value of bcbdata[15:8] when TX_INSTUFFING[2] (bcbdata_stuffing) is set to 1b */
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* *
|
||||
* Video Packetizer Registers *
|
||||
* *
|
||||
*****************************************************************************/
|
||||
|
||||
/* Video Packetizer Packing Phase Status Register */
|
||||
#define VP_STATUS 0x00002000
|
||||
#define VP_STATUS_PACKING_PHASE_MASK 0x0000000F /* Read only register that holds the "packing phase" output of the Video Packetizer block */
|
||||
|
||||
/* Video Packetizer Pixel Repetition and Color Depth Register */
|
||||
#define VP_PR_CD 0x00002004
|
||||
#define VP_PR_CD_DESIRED_PR_FACTOR_MASK 0x0000000F /* Desired pixel repetition factor configuration */
|
||||
#define VP_PR_CD_COLOR_DEPTH_MASK 0x000000F0 /* The Color depth configuration is described as the following, with the action stated corresponding to color_depth[3:0]: - 0000b: 24 bits per pixel video (8 bits per component) */
|
||||
|
||||
/* Video Packetizer Stuffing and Default Packing Phase Register */
|
||||
#define VP_STUFF 0x00002008
|
||||
#define VP_STUFF_PR_STUFFING_MASK 0x00000001 /* Pixel repeater stuffing control */
|
||||
#define VP_STUFF_PP_STUFFING_MASK 0x00000002 /* Pixel packing stuffing control */
|
||||
#define VP_STUFF_YCC422_STUFFING_MASK 0x00000004 /* YCC 422 remap stuffing control */
|
||||
#define VP_STUFF_ICX_GOTO_P0_ST_MASK 0x00000008 /* Reserved */
|
||||
#define VP_STUFF_IFIX_PP_TO_LAST_MASK 0x00000010 /* Reserved */
|
||||
#define VP_STUFF_IDEFAULT_PHASE_MASK 0x00000020 /* Controls the default phase packing machine used according to HDMI 1 */
|
||||
|
||||
/* Video Packetizer YCC422 Remapping Register */
|
||||
#define VP_REMAP 0x0000200C
|
||||
#define VP_REMAP_YCC422_SIZE_MASK 0x00000003 /* YCC 422 remap input video size ycc422_size[1:0] 00b: YCC 422 16-bit input video (8 bits per component) 01b: YCC 422 20-bit input video (10 bits per component) 10b: YCC 422 24-bit input video (12 bits per component) 11b: Reserved */
|
||||
|
||||
/* Video Packetizer Output, Bypass and Enable Configuration Register */
|
||||
#define VP_CONF 0x00002010
|
||||
#define VP_CONF_OUTPUT_SELECTOR_MASK 0x00000003 /* Video Packetizer output selection output_selector[1:0] 00b: Data from pixel packing block 01b: Data from YCC 422 remap block 10b: Data from 8-bit bypass block 11b: Data from 8-bit bypass block */
|
||||
#define VP_CONF_BYPASS_SELECT_MASK 0x00000004 /* bypass_select 0b: Data from pixel repeater block 1b: Data from input of Video Packetizer block */
|
||||
#define VP_CONF_YCC422_EN_MASK 0x00000008 /* YCC 422 select enable */
|
||||
#define VP_CONF_PR_EN_MASK 0x00000010 /* Pixel repeater enable */
|
||||
#define VP_CONF_PP_EN_MASK 0x00000020 /* Pixel packing enable */
|
||||
#define VP_CONF_BYPASS_EN_MASK 0x00000040 /* Bypass enable */
|
||||
|
||||
/* Video Packetizer Interrupt Mask Register */
|
||||
#define VP_MASK 0x0000201C
|
||||
#define VP_MASK_OINTEMPTYBYP_MASK 0x00000001 /* Mask bit for Video Packetizer 8-bit bypass FIFO empty */
|
||||
#define VP_MASK_OINTFULLBYP_MASK 0x00000002 /* Mask bit for Video Packetizer 8-bit bypass FIFO full */
|
||||
#define VP_MASK_OINTEMPTYREMAP_MASK 0x00000004 /* Mask bit for Video Packetizer pixel YCC 422 re-mapper FIFO empty */
|
||||
#define VP_MASK_OINTFULLREMAP_MASK 0x00000008 /* Mask bit for Video Packetizer pixel YCC 422 re-mapper FIFO full */
|
||||
#define VP_MASK_OINTEMPTYPP_MASK 0x00000010 /* Mask bit for Video Packetizer pixel packing FIFO empty */
|
||||
#define VP_MASK_OINTFULLPP_MASK 0x00000020 /* Mask bit for Video Packetizer pixel packing FIFO full */
|
||||
#define VP_MASK_OINTEMPTYREPET_MASK 0x00000040 /* Mask bit for Video Packetizer pixel repeater FIFO empty */
|
||||
#define VP_MASK_OINTFULLREPET_MASK 0x00000080 /* Mask bit for Video Packetizer pixel repeater FIFO full */
|
||||
|
||||
/*****************************************************************************
|
||||
* *
|
||||
* Color Space Converter Registers *
|
||||
* *
|
||||
*****************************************************************************/
|
||||
|
||||
/* Color Space Converter Interpolation and Decimation Configuration Register */
|
||||
#define CSC_CFG 0x00010400
|
||||
#define CSC_CFG_DECMODE_MASK 0x00000003 /* Chroma decimation configuration: decmode[1:0] | Chroma Decimation 00 | decimation disabled 01 | Hd (z) =1 10 | Hd(z)=1/ 4 + 1/2z^(-1 )+1/4 z^(-2) 11 | Hd(z)x2^(11)= -5+12z^(-2) - 22z^(-4)+39z^(-8) +109z^(-10) -204z^(-12)+648z^(-14) + 1024z^(-15) +648z^(-16) -204z^(-18) +109z^(-20)- 65z^(-22) +39z^(-24) -22z^(-26) +12z^(-28)-5z^(-30) */
|
||||
#define CSC_CFG_SPARE_1_MASK 0x0000000C /* This is a spare register with no associated functionality */
|
||||
#define CSC_CFG_INTMODE_MASK 0x00000030 /* Chroma interpolation configuration: intmode[1:0] | Chroma Interpolation 00 | interpolation disabled 01 | Hu (z) =1 + z^(-1) 10 | Hu(z)=1/ 2 + z^(-11)+1/2 z^(-2) 11 | interpolation disabled */
|
||||
#define CSC_CFG_SPARE_2_MASK 0x00000040 /* This is a spare register with no associated functionality */
|
||||
#define CSC_CFG_CSC_LIMIT_MASK 0x00000080 /* When set (1'b1), the range limitation values defined in registers csc_mat_uplim and csc_mat_dnlim are applied to the output of the Color Space Conversion matrix */
|
||||
|
||||
/* Color Space Converter Scale and Deep Color Configuration Register */
|
||||
#define CSC_SCALE 0x00010404
|
||||
#define CSC_SCALE_CSCSCALE_MASK 0x00000003 /* Defines the cscscale[1:0] scale factor to apply to all coefficients in Color Space Conversion */
|
||||
#define CSC_SCALE_SPARE_MASK 0x0000000C /* The is a spare register with no associated functionality */
|
||||
#define CSC_SCALE_CSC_COLOR_DEPTH_MASK 0x000000F0 /* Color space converter color depth configuration: csc_colordepth[3:0] | Action 0000 | 24 bit per pixel video (8 bit per component) */
|
||||
|
||||
/* Color Space Converter Matrix A1 Coefficient Register MSB Notes: - The coefficients used in the CSC matrix use only 15 bits for the internal computations */
|
||||
#define CSC_COEF_A1_MSB 0x00010408
|
||||
#define CSC_COEF_A1_MSB_CSC_COEF_A1_MSB_MASK 0x000000FF /* Color Space Converter Matrix A1 Coefficient Register MSB */
|
||||
|
||||
/* Color Space Converter Matrix A1 Coefficient Register LSB Notes: - The coefficients used in the CSC matrix use only 15 bits for the internal computations */
|
||||
#define CSC_COEF_A1_LSB 0x0001040C
|
||||
#define CSC_COEF_A1_LSB_CSC_COEF_A1_LSB_MASK 0x000000FF /* Color Space Converter Matrix A1 Coefficient Register LSB */
|
||||
|
||||
/* Color Space Converter Matrix A2 Coefficient Register MSB Color Space Conversion A2 coefficient */
|
||||
#define CSC_COEF_A2_MSB 0x00010410
|
||||
#define CSC_COEF_A2_MSB_CSC_COEF_A2_MSB_MASK 0x000000FF /* Color Space Converter Matrix A2 Coefficient Register MSB */
|
||||
|
||||
/* Color Space Converter Matrix A2 Coefficient Register LSB Color Space Conversion A2 coefficient */
|
||||
#define CSC_COEF_A2_LSB 0x00010414
|
||||
#define CSC_COEF_A2_LSB_CSC_COEF_A2_LSB_MASK 0x000000FF /* Color Space Converter Matrix A2 Coefficient Register LSB */
|
||||
|
||||
/* Color Space Converter Matrix A3 Coefficient Register MSB Color Space Conversion A3 coefficient */
|
||||
#define CSC_COEF_A3_MSB 0x00010418
|
||||
#define CSC_COEF_A3_MSB_CSC_COEF_A3_MSB_MASK 0x000000FF /* Color Space Converter Matrix A3 Coefficient Register MSB */
|
||||
|
||||
/* Color Space Converter Matrix A3 Coefficient Register LSB Color Space Conversion A3 coefficient */
|
||||
#define CSC_COEF_A3_LSB 0x0001041C
|
||||
#define CSC_COEF_A3_LSB_CSC_COEF_A3_LSB_MASK 0x000000FF /* Color Space Converter Matrix A3 Coefficient Register LSB */
|
||||
|
||||
/* Color Space Converter Matrix A4 Coefficient Register MSB Color Space Conversion A4 coefficient */
|
||||
#define CSC_COEF_A4_MSB 0x00010420
|
||||
#define CSC_COEF_A4_MSB_CSC_COEF_A4_MSB_MASK 0x000000FF /* Color Space Converter Matrix A4 Coefficient Register MSB */
|
||||
|
||||
/* Color Space Converter Matrix A4 Coefficient Register LSB Color Space Conversion A4 coefficient */
|
||||
#define CSC_COEF_A4_LSB 0x00010424
|
||||
#define CSC_COEF_A4_LSB_CSC_COEF_A4_LSB_MASK 0x000000FF /* Color Space Converter Matrix A4 Coefficient Register LSB */
|
||||
|
||||
/* Color Space Converter Matrix B1 Coefficient Register MSB Color Space Conversion B1 coefficient */
|
||||
#define CSC_COEF_B1_MSB 0x00010428
|
||||
#define CSC_COEF_B1_MSB_CSC_COEF_B1_MSB_MASK 0x000000FF /* Color Space Converter Matrix B1 Coefficient Register MSB */
|
||||
|
||||
/* Color Space Converter Matrix B1 Coefficient Register LSB Color Space Conversion B1 coefficient */
|
||||
#define CSC_COEF_B1_LSB 0x0001042C
|
||||
#define CSC_COEF_B1_LSB_CSC_COEF_B1_LSB_MASK 0x000000FF /* Color Space Converter Matrix B1 Coefficient Register LSB */
|
||||
|
||||
/* Color Space Converter Matrix B2 Coefficient Register MSB Color Space Conversion B2 coefficient */
|
||||
#define CSC_COEF_B2_MSB 0x00010430
|
||||
#define CSC_COEF_B2_MSB_CSC_COEF_B2_MSB_MASK 0x000000FF /* Color Space Converter Matrix B2 Coefficient Register MSB */
|
||||
|
||||
/* Color Space Converter Matrix B2 Coefficient Register LSB Color Space Conversion B2 coefficient */
|
||||
#define CSC_COEF_B2_LSB 0x00010434
|
||||
#define CSC_COEF_B2_LSB_CSC_COEF_B2_LSB_MASK 0x000000FF /* Color Space Converter Matrix B2 Coefficient Register LSB */
|
||||
|
||||
/* Color Space Converter Matrix B3 Coefficient Register MSB Color Space Conversion B3 coefficient */
|
||||
#define CSC_COEF_B3_MSB 0x00010438
|
||||
#define CSC_COEF_B3_MSB_CSC_COEF_B3_MSB_MASK 0x000000FF /* Color Space Converter Matrix B3 Coefficient Register MSB */
|
||||
|
||||
/* Color Space Converter Matrix B3 Coefficient Register LSB Color Space Conversion B3 coefficient */
|
||||
#define CSC_COEF_B3_LSB 0x0001043C
|
||||
#define CSC_COEF_B3_LSB_CSC_COEF_B3_LSB_MASK 0x000000FF /* Color Space Converter Matrix B3 Coefficient Register LSB */
|
||||
|
||||
/* Color Space Converter Matrix B4 Coefficient Register MSB Color Space Conversion B4 coefficient */
|
||||
#define CSC_COEF_B4_MSB 0x00010440
|
||||
#define CSC_COEF_B4_MSB_CSC_COEF_B4_MSB_MASK 0x000000FF /* Color Space Converter Matrix B4 Coefficient Register MSB */
|
||||
|
||||
/* Color Space Converter Matrix B4 Coefficient Register LSB Color Space Conversion B4 coefficient */
|
||||
#define CSC_COEF_B4_LSB 0x00010444
|
||||
#define CSC_COEF_B4_LSB_CSC_COEF_B4_LSB_MASK 0x000000FF /* Color Space Converter Matrix B4 Coefficient Register LSB */
|
||||
|
||||
/* Color Space Converter Matrix C1 Coefficient Register MSB Color Space Conversion C1 coefficient */
|
||||
#define CSC_COEF_C1_MSB 0x00010448
|
||||
#define CSC_COEF_C1_MSB_CSC_COEF_C1_MSB_MASK 0x000000FF /* Color Space Converter Matrix C1 Coefficient Register MSB */
|
||||
|
||||
/* Color Space Converter Matrix C1 Coefficient Register LSB Color Space Conversion C1 coefficient */
|
||||
#define CSC_COEF_C1_LSB 0x0001044C
|
||||
#define CSC_COEF_C1_LSB_CSC_COEF_C1_LSB_MASK 0x000000FF /* Color Space Converter Matrix C1 Coefficient Register LSB */
|
||||
|
||||
/* Color Space Converter Matrix C2 Coefficient Register MSB Color Space Conversion C2 coefficient */
|
||||
#define CSC_COEF_C2_MSB 0x00010450
|
||||
#define CSC_COEF_C2_MSB_CSC_COEF_C2_MSB_MASK 0x000000FF /* Color Space Converter Matrix C2 Coefficient Register MSB */
|
||||
|
||||
/* Color Space Converter Matrix C2 Coefficient Register LSB Color Space Conversion C2 coefficient */
|
||||
#define CSC_COEF_C2_LSB 0x00010454
|
||||
#define CSC_COEF_C2_LSB_CSC_COEF_C2_LSB_MASK 0x000000FF /* Color Space Converter Matrix C2 Coefficient Register LSB */
|
||||
|
||||
/* Color Space Converter Matrix C3 Coefficient Register MSB Color Space Conversion C3 coefficient */
|
||||
#define CSC_COEF_C3_MSB 0x00010458
|
||||
#define CSC_COEF_C3_MSB_CSC_COEF_C3_MSB_MASK 0x000000FF /* Color Space Converter Matrix C3 Coefficient Register MSB */
|
||||
|
||||
/* Color Space Converter Matrix C3 Coefficient Register LSB Color Space Conversion C3 coefficient */
|
||||
#define CSC_COEF_C3_LSB 0x0001045C
|
||||
#define CSC_COEF_C3_LSB_CSC_COEF_C3_LSB_MASK 0x000000FF /* Color Space Converter Matrix C3 Coefficient Register LSB */
|
||||
|
||||
/* Color Space Converter Matrix C4 Coefficient Register MSB Color Space Conversion C4 coefficient */
|
||||
#define CSC_COEF_C4_MSB 0x00010460
|
||||
#define CSC_COEF_C4_MSB_CSC_COEF_C4_MSB_MASK 0x000000FF /* Color Space Converter Matrix C4 Coefficient Register MSB */
|
||||
|
||||
/* Color Space Converter Matrix C4 Coefficient Register LSB Color Space Conversion C4 coefficient */
|
||||
#define CSC_COEF_C4_LSB 0x00010464
|
||||
#define CSC_COEF_C4_LSB_CSC_COEF_C4_LSB_MASK 0x000000FF /* Color Space Converter Matrix C4 Coefficient Register LSB */
|
||||
|
||||
/* Color Space Converter Matrix Output Up Limit Register MSB For more details, refer to the HDMI 1 */
|
||||
#define CSC_LIMIT_UP_MSB 0x00010468
|
||||
#define CSC_LIMIT_UP_MSB_CSC_LIMIT_UP_MSB_MASK 0x000000FF /* Color Space Converter Matrix Output Upper Limit Register MSB */
|
||||
|
||||
/* Color Space Converter Matrix output Up Limit Register LSB For more details, refer to the HDMI 1 */
|
||||
#define CSC_LIMIT_UP_LSB 0x0001046C
|
||||
#define CSC_LIMIT_UP_LSB_CSC_LIMIT_UP_LSB_MASK 0x000000FF /* Color Space Converter Matrix Output Upper Limit Register LSB */
|
||||
|
||||
/* Color Space Converter Matrix output Down Limit Register MSB For more details, refer to the HDMI 1 */
|
||||
#define CSC_LIMIT_DN_MSB 0x00010470
|
||||
#define CSC_LIMIT_DN_MSB_CSC_LIMIT_DN_MSB_MASK 0x000000FF /* Color Space Converter Matrix output Down Limit Register MSB */
|
||||
|
||||
/* Color Space Converter Matrix output Down Limit Register LSB For more details, refer to the HDMI 1 */
|
||||
#define CSC_LIMIT_DN_LSB 0x00010474
|
||||
#define CSC_LIMIT_DN_LSB_CSC_LIMIT_DN_LSB_MASK 0x000000FF /* Color Space Converter Matrix Output Down Limit Register LSB */
|
||||
|
||||
typedef enum {
|
||||
ENC_UNDEFINED = -1,
|
||||
RGB = 0,
|
||||
YCC444,
|
||||
YCC422,
|
||||
YCC420
|
||||
} encoding_t;
|
||||
|
||||
typedef struct {
|
||||
/** VIC code */
|
||||
u32 mCode;
|
||||
|
||||
/** Identifies modes that ONLY can be displayed in YCC 4:2:0 */
|
||||
u8 mLimitedToYcc420;
|
||||
|
||||
/** Identifies modes that can also be displayed in YCC 4:2:0 */
|
||||
u8 mYcc420;
|
||||
|
||||
u16 mPixelRepetitionInput;
|
||||
|
||||
/** In units of 1KHz */
|
||||
u32 mPixelClock;
|
||||
|
||||
/** 1 for interlaced, 0 progressive */
|
||||
u8 mInterlaced;
|
||||
|
||||
u16 mHActive;
|
||||
|
||||
u16 mHBlanking;
|
||||
|
||||
u16 mHBorder;
|
||||
|
||||
u16 mHImageSize; /*For picture aspect ratio*/
|
||||
|
||||
u16 mHSyncOffset;
|
||||
|
||||
u16 mHSyncPulseWidth;
|
||||
|
||||
/** 0 for Active low, 1 active high */
|
||||
u8 mHSyncPolarity;
|
||||
|
||||
u16 mVActive;
|
||||
|
||||
u16 mVBlanking;
|
||||
|
||||
u16 mVBorder;
|
||||
|
||||
u16 mVImageSize; /*For picture aspect ratio*/
|
||||
|
||||
u16 mVSyncOffset;
|
||||
|
||||
u16 mVSyncPulseWidth;
|
||||
|
||||
/** 0 for Active low, 1 active high */
|
||||
u8 mVSyncPolarity;
|
||||
|
||||
} dtd_t;
|
||||
|
||||
typedef enum {
|
||||
MODE_UNDEFINED = -1,
|
||||
DVI = 0,
|
||||
HDMI
|
||||
} video_mode_t;
|
||||
|
||||
|
||||
typedef enum {
|
||||
ITU601 = 1,
|
||||
ITU709,
|
||||
EXTENDED_COLORIMETRY
|
||||
} colorimetry_t;
|
||||
|
||||
typedef enum {
|
||||
XV_YCC601 = 0,
|
||||
XV_YCC709,
|
||||
S_YCC601,
|
||||
ADOBE_YCC601,
|
||||
ADOBE_RGB,
|
||||
BT2020_Yc_Cbc_Crc,
|
||||
BT2020_Y_CB_CR
|
||||
} ext_colorimetry_t;
|
||||
|
||||
typedef struct fc_drm_pb {
|
||||
u8 eotf;
|
||||
u8 metadata;
|
||||
u16 r_x;
|
||||
u16 r_y;
|
||||
u16 g_x;
|
||||
u16 g_y;
|
||||
u16 b_x;
|
||||
u16 b_y;
|
||||
u16 w_x;
|
||||
u16 w_y;
|
||||
u16 luma_max;
|
||||
u16 luma_min;
|
||||
u16 mcll;
|
||||
u16 mfll;
|
||||
} fc_drm_pb_t;
|
||||
|
||||
typedef struct {
|
||||
video_mode_t mHdmi;
|
||||
u8 mCea_code;
|
||||
u8 mHdmi_code;
|
||||
u8 mHdr;
|
||||
fc_drm_pb_t pb;
|
||||
fc_drm_pb_t dynamic_pb;
|
||||
encoding_t mEncodingOut;
|
||||
encoding_t mEncodingIn;
|
||||
u8 mColorResolution; /*color depth*/
|
||||
u8 mPixelRepetitionFactor; /*For packetizer pixel repeater*/
|
||||
dtd_t mDtd;
|
||||
u8 mRgbQuantizationRange;
|
||||
u8 mPixelPackingDefaultPhase;
|
||||
u8 mColorimetry;
|
||||
u8 mScanInfo;
|
||||
u8 mActiveFormatAspectRatio;
|
||||
u8 mNonUniformScaling;
|
||||
ext_colorimetry_t mExtColorimetry;
|
||||
u8 mColorimetryDataBlock;
|
||||
u8 mItContent;
|
||||
u16 mEndTopBar;
|
||||
u16 mStartBottomBar;
|
||||
u16 mEndLeftBar;
|
||||
u16 mStartRightBar;
|
||||
u16 mCscFilter;
|
||||
u16 mCscA[4];
|
||||
u16 mCscC[4];
|
||||
u16 mCscB[4];
|
||||
u16 mCscScale;
|
||||
u8 mHdmiVideoFormat;/*0:There's not 4k*2k or not 3D 1:4k*2k 2:3D */
|
||||
u8 m3dStructure; /*packing frame and so on*/
|
||||
u8 m3dExtData;/*3d extra structure, if 3d_structure=0x1000,there must be a 3d extra structure*/
|
||||
u8 mHdmiVic;
|
||||
u8 mHdmi20;/*decided by sink*/
|
||||
u8 scdc_ability;
|
||||
} videoParams_t;
|
||||
|
||||
int videoParams_GetCeaVicCode(int hdmi_vic_code);
|
||||
|
||||
int videoParams_GetHdmiVicCode(int cea_code);
|
||||
|
||||
/**
|
||||
* This methotaEnablePolarity
|
||||
* to put the state of the strucutre to default
|
||||
* @param params pointer to the video parameters structure
|
||||
*/
|
||||
void video_params_reset(hdmi_tx_dev_t *dev, videoParams_t *params);
|
||||
|
||||
/**
|
||||
* @param params pointer to the video parameters structure
|
||||
* @return the custom csc coefficients A
|
||||
*/
|
||||
u16 *videoParams_GetCscA(hdmi_tx_dev_t *dev, videoParams_t *params);
|
||||
|
||||
void videoParams_SetCscA(hdmi_tx_dev_t *dev,
|
||||
videoParams_t *params, u16 value[4]);
|
||||
|
||||
/**
|
||||
* @param params pointer to the video parameters structure
|
||||
* @return the custom csc coefficients B
|
||||
*/
|
||||
u16 *videoParams_GetCscB(hdmi_tx_dev_t *dev, videoParams_t *params);
|
||||
|
||||
void videoParams_SetCscB(hdmi_tx_dev_t *dev,
|
||||
videoParams_t *params, u16 value[4]);
|
||||
|
||||
/**
|
||||
* @param params pointer to the video parameters structure
|
||||
* @return the custom csc coefficients C
|
||||
*/
|
||||
u16 *videoParams_GetCscC(hdmi_tx_dev_t *dev, videoParams_t *params);
|
||||
|
||||
void videoParams_SetCscC(hdmi_tx_dev_t *dev, videoParams_t *params,
|
||||
u16 value[4]);
|
||||
|
||||
void videoParams_SetCscScale(hdmi_tx_dev_t *dev, videoParams_t *params,
|
||||
u16 value);
|
||||
|
||||
/**
|
||||
* @param params pointer to the video parameters structure
|
||||
* @return Video PixelClock in [0.01 MHz]
|
||||
*/
|
||||
u32 videoParams_GetPixelClock(hdmi_tx_dev_t *dev, videoParams_t *params);
|
||||
|
||||
/**
|
||||
* @param params pointer to the video parameters structure
|
||||
* @return TMDS Clock in [0.01 MHz]
|
||||
*/
|
||||
u16 videoParams_GetTmdsClock(hdmi_tx_dev_t *dev, videoParams_t *params);
|
||||
|
||||
/**
|
||||
* @param params pointer to the video parameters structure
|
||||
* @return Ration clock x 100 (hdmi_tx_dev_t *dev,
|
||||
* should be multiplied by x 0.01 afterwards)
|
||||
*/
|
||||
unsigned videoParams_GetRatioClock(hdmi_tx_dev_t *dev, videoParams_t *params);
|
||||
|
||||
/**
|
||||
* @param params pointer to the video parameters structure
|
||||
* @return TRUE if csc is needed
|
||||
*/
|
||||
int videoParams_IsColorSpaceConversion(hdmi_tx_dev_t *dev,
|
||||
videoParams_t *params);
|
||||
|
||||
/**
|
||||
* @param params pointer to the video parameters structure
|
||||
* @return TRUE if color space decimation is needed
|
||||
*/
|
||||
int videoParams_IsColorSpaceDecimation(hdmi_tx_dev_t *dev, videoParams_t *params);
|
||||
|
||||
/**
|
||||
* @param params pointer to the video parameters structure
|
||||
* @return TRUE if if video is interpolated
|
||||
*/
|
||||
int videoParams_IsColorSpaceInterpolation(hdmi_tx_dev_t *dev, videoParams_t *params);
|
||||
|
||||
/**
|
||||
* @param params pointer to the video parameters structure
|
||||
* @return TRUE if if video has pixel repetition
|
||||
*/
|
||||
int videoParams_IsPixelRepetition(hdmi_tx_dev_t *dev, videoParams_t *params);
|
||||
|
||||
void videoParams_UpdateCscCoefficients(hdmi_tx_dev_t *dev, videoParams_t *params);
|
||||
|
||||
u8 videoParams_IsLimitedToYcc420(hdmi_tx_dev_t *dev, videoParams_t *params);
|
||||
|
||||
char *getEncodingString(encoding_t encoding);
|
||||
|
||||
|
||||
void video_sampler_config(hdmi_tx_dev_t *dev, u8 map_code);
|
||||
|
||||
u8 vp_PixelPackingPhase(hdmi_tx_dev_t *dev);
|
||||
void vp_ColorDepth(hdmi_tx_dev_t *dev, u8 value);
|
||||
void vp_PixelPackingDefaultPhase(hdmi_tx_dev_t *dev, u8 bit);
|
||||
void vp_PixelRepetitionFactor(hdmi_tx_dev_t *dev, u8 value);
|
||||
void vp_Ycc422RemapSize(hdmi_tx_dev_t *dev, u8 value);
|
||||
void vp_OutputSelector(hdmi_tx_dev_t *dev, u8 value);
|
||||
|
||||
|
||||
/**
|
||||
* Initializes and configures the video blocks to transmit a blue screen
|
||||
* @param baseAddr Base Address of module
|
||||
* @param params VideoParams
|
||||
* @param dataEnablePolarity data enable polarity (1 = enable, 0 not)
|
||||
* @return TRUE if successful
|
||||
*/
|
||||
int video_Initialize(hdmi_tx_dev_t *dev, videoParams_t *params,
|
||||
u8 dataEnablePolarity);
|
||||
|
||||
/**
|
||||
* Configures the video blocks to do any video processing and to
|
||||
* transmit the video set up required by the user, allowing to
|
||||
* force video pixels (from the DEBUG pixels) to be transmitted
|
||||
* rather than the video stream being received.
|
||||
* @param baseAddr Base Address of module
|
||||
* @param params VideoParams
|
||||
* @return TRUE if successful
|
||||
*/
|
||||
int video_Configure(hdmi_tx_dev_t *dev, videoParams_t *params);
|
||||
|
||||
/**
|
||||
* Set up color space converter to video requirements
|
||||
* (if there is any encoding type conversion or csc coefficients)
|
||||
* @param baseAddr Base Address of module
|
||||
* @param params VideoParams
|
||||
* @return TRUE if successful
|
||||
*/
|
||||
int video_ColorSpaceConverter(hdmi_tx_dev_t *dev, videoParams_t *params);
|
||||
|
||||
/**
|
||||
* Set up video packetizer which "packetizes" pixel transmission
|
||||
* (in deep colour mode, YCC422 mapping and pixel repetition)
|
||||
* @param baseAddr Base Address of module
|
||||
* @param params VideoParams
|
||||
* @return TRUE if successful
|
||||
*/
|
||||
int video_VideoPacketizer(hdmi_tx_dev_t *dev, videoParams_t *params);
|
||||
|
||||
/**
|
||||
* Set up video mapping and stuffing
|
||||
* @param baseAddr Base Address of module
|
||||
* @param params VideoParams
|
||||
* @return TRUE if successful
|
||||
*/
|
||||
int video_VideoSampler(hdmi_tx_dev_t *dev, videoParams_t *params);
|
||||
|
||||
/**
|
||||
* A test only method that is used for a test module
|
||||
* @param baseAddr Base Address of module
|
||||
* @param params VideoParams
|
||||
* @param dataEnablePolarity
|
||||
* @return TRUE if successful
|
||||
*/
|
||||
int video_VideoGenerator(hdmi_tx_dev_t *dev, videoParams_t *params,
|
||||
u8 dataEnablePolarity);
|
||||
|
||||
extern void csc_config(hdmi_tx_dev_t *dev, videoParams_t *params,
|
||||
unsigned interpolation, unsigned decimation, unsigned color_depth);
|
||||
|
||||
|
||||
dtd_t *get_dtd(u8 code, u32 refreshRate);
|
||||
|
||||
#endif /* VIDEO_H_ */
|
||||
50
sunxi_spl/dram/sun50iw1p1/dram/Makefile
Executable file
50
sunxi_spl/dram/sun50iw1p1/dram/Makefile
Executable file
@@ -0,0 +1,50 @@
|
||||
|
||||
#
|
||||
# (C) Copyright 2000, 2001, 2002
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
all:
|
||||
ifeq ($(notdir $(shell find ./ -name lib-dram)), lib-dram)
|
||||
make -C lib-dram
|
||||
else
|
||||
@echo "libdram exist"
|
||||
endif
|
||||
|
||||
ifeq ($(notdir $(shell find ./ -name lib-chipid)), lib-chipid)
|
||||
make -C lib-chipid
|
||||
else
|
||||
@echo "lib-chipid exist"
|
||||
endif
|
||||
|
||||
cp ./libdram ./libdram.o
|
||||
cp ./libchipid ./libchipid.o
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
BIN
sunxi_spl/dram/sun50iw1p1/dram/libchipid
Executable file
BIN
sunxi_spl/dram/sun50iw1p1/dram/libchipid
Executable file
Binary file not shown.
BIN
sunxi_spl/dram/sun50iw1p1/dram/libdram
Executable file
BIN
sunxi_spl/dram/sun50iw1p1/dram/libdram
Executable file
Binary file not shown.
50
sunxi_spl/dram/sun50iw2p1/dram/Makefile
Executable file
50
sunxi_spl/dram/sun50iw2p1/dram/Makefile
Executable file
@@ -0,0 +1,50 @@
|
||||
|
||||
#
|
||||
# (C) Copyright 2000, 2001, 2002
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
all:
|
||||
ifeq ($(notdir $(shell find ./ -name lib-dram)), lib-dram)
|
||||
make -C lib-dram
|
||||
else
|
||||
@echo "libdram exist"
|
||||
endif
|
||||
|
||||
ifeq ($(notdir $(shell find ./ -name lib-chipid)), lib-chipid)
|
||||
make -C lib-chipid
|
||||
else
|
||||
@echo "lib-chipid exist"
|
||||
endif
|
||||
|
||||
cp ./libdram ./libdram.o
|
||||
cp ./libchipid ./libchipid.o
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
BIN
sunxi_spl/dram/sun50iw2p1/dram/libchipid
Executable file
BIN
sunxi_spl/dram/sun50iw2p1/dram/libchipid
Executable file
Binary file not shown.
BIN
sunxi_spl/dram/sun50iw2p1/dram/libdram
Executable file
BIN
sunxi_spl/dram/sun50iw2p1/dram/libdram
Executable file
Binary file not shown.
50
sunxi_spl/dram/sun50iw3p1/dram/Makefile
Executable file
50
sunxi_spl/dram/sun50iw3p1/dram/Makefile
Executable file
@@ -0,0 +1,50 @@
|
||||
|
||||
#
|
||||
# (C) Copyright 2000, 2001, 2002
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
all:
|
||||
ifeq ($(notdir $(shell find ./ -name lib-dram)), lib-dram)
|
||||
make -C lib-dram
|
||||
else
|
||||
@echo "libdram exist"
|
||||
endif
|
||||
|
||||
ifeq ($(notdir $(shell find ./ -name lib-chipid)), lib-chipid)
|
||||
make -C lib-chipid
|
||||
else
|
||||
@echo "lib-chipid exist"
|
||||
endif
|
||||
|
||||
cp ./libdram ./libdram.o
|
||||
cp ./libchipid ./libchipid.o
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
27
sunxi_spl/dram/sun50iw3p1/dram/lib-dram/Makefile
Executable file
27
sunxi_spl/dram/sun50iw3p1/dram/lib-dram/Makefile
Executable file
@@ -0,0 +1,27 @@
|
||||
##
|
||||
## Makefile for Sunxi Boot
|
||||
##
|
||||
|
||||
include $(SPLDIR)/config.mk
|
||||
LIB := $(obj)libdram
|
||||
|
||||
COBJS-y += mctl_hal.o
|
||||
|
||||
COBJS := $(COBJS-y)
|
||||
SRCS := $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS))
|
||||
|
||||
all: $(LIB)
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
cp $(LIB) ../
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
1541
sunxi_spl/dram/sun50iw3p1/dram/lib-dram/mctl_hal.c
Executable file
1541
sunxi_spl/dram/sun50iw3p1/dram/lib-dram/mctl_hal.c
Executable file
File diff suppressed because it is too large
Load Diff
92
sunxi_spl/dram/sun50iw3p1/dram/lib-dram/mctl_hal.h
Executable file
92
sunxi_spl/dram/sun50iw3p1/dram/lib-dram/mctl_hal.h
Executable file
@@ -0,0 +1,92 @@
|
||||
#ifndef _MCTL_HAL_H
|
||||
#define _MCTL_HAL_H
|
||||
/*****************************************
|
||||
Verify Platform
|
||||
1.FPGA_VERIFY --- FPGA Verify
|
||||
2.SIM_VERIFY --- Simulation
|
||||
*****************************************/
|
||||
#define FPGA_VERIFY
|
||||
//#define SIM_VERIFY
|
||||
|
||||
#ifdef SIM_VERIFY
|
||||
/*****************************************
|
||||
Function: DRAM Type Choose
|
||||
*****************************************/
|
||||
#define DRAM_TYPE_DDR3
|
||||
//#define DRAM_TYPE_LPDDR2
|
||||
//#define DRAM_TYPE_LPDDR3
|
||||
//#define DRAM_TYPE_DDR2
|
||||
/*****************************************
|
||||
Function: CLK Source Choose
|
||||
*****************************************/
|
||||
#define SOURCE_CLK_USE_DDR_PLL1
|
||||
//#define SOURCE_CLK_USE_DDR_PLL0
|
||||
//#define OPEN_ANOTHER_SOURCE
|
||||
/*****************************************
|
||||
Function: DQS Mode Choose
|
||||
*****************************************/
|
||||
//#define DRAMC_USE_AUTO_DQS_GATE_PD_MODE
|
||||
//#define DRAMC_USE_DQS_GATING_MODE
|
||||
#define DRAMC_USE_AUTO_DQS_GATE_PU_MODE
|
||||
|
||||
/*****************************************
|
||||
Function: No Care
|
||||
*****************************************/
|
||||
#if defined DRAM_TYPE_LPDDR2 || defined DRAM_TYPE_LPDDR3
|
||||
#define DRAMC_USE_1T_MODE
|
||||
#else
|
||||
#define DRAMC_USE_2T_MODE
|
||||
#endif
|
||||
/*****************************************
|
||||
Function: Close Print
|
||||
*****************************************/
|
||||
#define dram_dbg(fmt,args...)
|
||||
#else
|
||||
/*****************************************
|
||||
Function: Open Print
|
||||
*****************************************/
|
||||
#define dram_dbg(fmt,args...) printk(fmt ,##args)
|
||||
#endif
|
||||
|
||||
typedef struct __DRAM_PARA
|
||||
{
|
||||
unsigned int dram_clk;
|
||||
unsigned int dram_type;
|
||||
unsigned int dram_zq;
|
||||
unsigned int dram_odt_en;
|
||||
unsigned int dram_para1;
|
||||
unsigned int dram_para2;
|
||||
unsigned int dram_mr0;
|
||||
unsigned int dram_mr1;
|
||||
unsigned int dram_mr2;
|
||||
unsigned int dram_mr3;
|
||||
unsigned int dram_tpr0;
|
||||
unsigned int dram_tpr1;
|
||||
unsigned int dram_tpr2;
|
||||
unsigned int dram_tpr3;
|
||||
unsigned int dram_tpr4;
|
||||
unsigned int dram_tpr5;
|
||||
unsigned int dram_tpr6;
|
||||
unsigned int dram_tpr7;
|
||||
unsigned int dram_tpr8;
|
||||
unsigned int dram_tpr9;
|
||||
unsigned int dram_tpr10;
|
||||
unsigned int dram_tpr11;
|
||||
unsigned int dram_tpr12;
|
||||
unsigned int dram_tpr13;
|
||||
unsigned int dram_tpr14;
|
||||
unsigned int dram_tpr15;
|
||||
unsigned int dram_tpr16;
|
||||
unsigned int dram_tpr17;
|
||||
unsigned int dram_tpr18;
|
||||
unsigned int dram_tpr19;
|
||||
unsigned int dram_tpr20;
|
||||
unsigned int dram_tpr21;
|
||||
}__dram_para_t;
|
||||
|
||||
|
||||
extern unsigned int mctl_init(void *para);
|
||||
extern signed int init_DRAM(int type, __dram_para_t *para);
|
||||
extern void dram_udelay(unsigned int n);
|
||||
#endif //_MCTL_HAL_H
|
||||
|
||||
218
sunxi_spl/dram/sun50iw3p1/dram/lib-dram/mctl_reg.h
Executable file
218
sunxi_spl/dram/sun50iw3p1/dram/lib-dram/mctl_reg.h
Executable file
@@ -0,0 +1,218 @@
|
||||
#ifndef _MCTL_REG_H
|
||||
#define _MCTL_REG_H
|
||||
|
||||
/*=====================================
|
||||
*DRAM驱动专用读写函数
|
||||
* ====================================
|
||||
*/
|
||||
#define mctl_write_w(v, addr) (*((volatile unsigned long *)(addr)) = (unsigned long)(v))
|
||||
#define mctl_read_w(addr) (*((volatile unsigned long *)(addr)))
|
||||
#define __REG(x) (*(volatile unsigned int *)(x))
|
||||
|
||||
#define DRAM_RET_OK 0
|
||||
#define DRAM_RET_FAIL 1
|
||||
|
||||
#define DRAM_BASE_ADDR 0x40000000
|
||||
#define DRAM_TYPE_ADDR MCTL_COM_BASE + 0x80c //0x01c6280c
|
||||
/*该地址用于time out功能验证,bit17 disable high rank,bit16 disable high DQ*/
|
||||
#define DRAM_SDL_ADDR MCTL_COM_BASE + 0x820 //0x01c62820
|
||||
/*该地址用于SDL功能验证
|
||||
0x820[0] 写1触发
|
||||
0x820[15:8] 编号:
|
||||
0x00-0x1F :DQ0 -DQ31 wsdl
|
||||
0x20-0x3F :DQ0 -DQ31 rsdl
|
||||
|
||||
0x40-0x43 :DQS0-DQS3 wsdl
|
||||
0x44-0x47 :DQS0-DQS3 rsdl
|
||||
0x48-0x4b :DQS0#-DQS3# rsdl
|
||||
0x4c-0x4f :DM0-DM3 wsdl
|
||||
*/
|
||||
|
||||
#define MCTL_COM_BASE 0x04002000
|
||||
#define MCTL_CTL_BASE 0x04003000
|
||||
|
||||
/*=====================================
|
||||
*MSI域寄存器
|
||||
*0x04002000
|
||||
* ====================================
|
||||
*/
|
||||
#define MC_WORK_MODE (MCTL_COM_BASE + 0x00)
|
||||
#define MC_R1_WORK_MODE (MCTL_COM_BASE + 0x04)
|
||||
#define MC_DBGCR (MCTL_COM_BASE + 0x08)
|
||||
#define MC_TMR (MCTL_COM_BASE + 0x0c)
|
||||
#define MC_CCCR (MCTL_COM_BASE + 0x14)
|
||||
|
||||
#define MC_MAER0 (MCTL_COM_BASE + 0x20)
|
||||
#define MC_MAER1 (MCTL_COM_BASE + 0x24)
|
||||
#define MC_MAER2 (MCTL_COM_BASE + 0x28)
|
||||
#define MC_SWONR0 (MCTL_COM_BASE + 0x30)
|
||||
#define MC_SWONR1 (MCTL_COM_BASE + 0x34)
|
||||
#define MC_SWONR2 (MCTL_COM_BASE + 0x38)
|
||||
|
||||
#define MC_SWOFFR0 (MCTL_COM_BASE + 0x40)
|
||||
#define MC_SWOFFR1 (MCTL_COM_BASE + 0x44)
|
||||
#define MC_SWOFFR2 (MCTL_COM_BASE + 0x48)
|
||||
|
||||
#define MC_MCGCR (MCTL_COM_BASE + 0x9c)
|
||||
#define MC_CPU_BWCR (MCTL_COM_BASE + 0xa0)
|
||||
#define MC_GPU_BWCR (MCTL_COM_BASE + 0xa4)
|
||||
#define MC_VE_BWCR (MCTL_COM_BASE + 0xa8)
|
||||
#define MC_DISP_BWCR (MCTL_COM_BASE + 0xac)
|
||||
#define MC_OTHER_BWCR (MCTL_COM_BASE + 0xb0)
|
||||
#define MC_TOTAL_BWCR (MCTL_COM_BASE + 0xb4)
|
||||
#define MC_CSI_BWCR (MCTL_COM_BASE + 0xb8)
|
||||
|
||||
#define MC_MDFSCR (MCTL_COM_BASE + 0x100)
|
||||
|
||||
#define MC_MDFSMRMR (MCTL_COM_BASE + 0x108)
|
||||
#define MC_MDFSTR (MCTL_COM_BASE + 0x10c)
|
||||
#define MC_MDFSCNTR (MCTL_COM_BASE + 0x110)
|
||||
#define MC_MDFS_BWC_PRD (MCTL_COM_BASE + 0x114)
|
||||
#define MC_MDFSMER0 (MCTL_COM_BASE + 0x118)
|
||||
#define MC_MDFSMER1 (MCTL_COM_BASE + 0x11c)
|
||||
|
||||
#define MC_MDFS_MER0 (MCTL_COM_BASE + 0x130)
|
||||
#define MC_MDFS_MER1 (MCTL_COM_BASE + 0x134)
|
||||
#define MC_MDFS_MSR0 (MCTL_COM_BASE + 0x138)
|
||||
#define MC_MDFS_MSR1 (MCTL_COM_BASE + 0x13c)
|
||||
|
||||
|
||||
#define MC_MDFS_ACC_IRQ_STA0 (MCTL_COM_BASE + 0x140)
|
||||
#define MC_MDFS_ACC_IRQ_STA1 (MCTL_COM_BASE + 0x144)
|
||||
#define MC_MDFS_IDL_IRQ_STA0 (MCTL_COM_BASE + 0x148)
|
||||
#define MC_MDFS_IDL_IRQ_STA1 (MCTL_COM_BASE + 0x14c)
|
||||
#define MC_MDFS_ACC_IRQ_MASK0 (MCTL_COM_BASE + 0x150)
|
||||
#define MC_MDFS_ACC_IRQ_MASK1 (MCTL_COM_BASE + 0x154)
|
||||
#define MC_MDFS_IDL_IRQ_MASK0 (MCTL_COM_BASE + 0x158)
|
||||
#define MC_MDFS_IDL_IRQ_MASK1 (MCTL_COM_BASE + 0x15c)
|
||||
|
||||
#define MC_BWCR (MCTL_COM_BASE + 0x200)
|
||||
|
||||
#define MC_MnCR0(x) (MCTL_COM_BASE + 0x210 + 0x10 * x)
|
||||
#define MC_MnCR1(x) (MCTL_COM_BASE + 0x214 + 0x10 * x)
|
||||
#define MC_Mn_BWLR (MCTL_COM_BASE + 0x218 + 0x10 * x)
|
||||
|
||||
|
||||
/*protect register*/
|
||||
#define MC_MPRAR (MCTL_COM_BASE + 0x800)
|
||||
|
||||
/*=====================================
|
||||
*PHY域寄存器
|
||||
*0x01c63000
|
||||
* ====================================
|
||||
*/
|
||||
#define PIR (MCTL_CTL_BASE + 0x00000000)
|
||||
#define PWRCTL (MCTL_CTL_BASE + 0x00000004)
|
||||
#define MRCTRL0 (MCTL_CTL_BASE + 0x00000008)
|
||||
#define CLKEN (MCTL_CTL_BASE + 0x0000000c)
|
||||
#define PGSR0 (MCTL_CTL_BASE + 0x00000010)
|
||||
#define PGSR1 (MCTL_CTL_BASE + 0x00000014)
|
||||
#define STATR (MCTL_CTL_BASE + 0x00000018)
|
||||
#define LP3MR11 (MCTL_CTL_BASE + 0x0000002c)
|
||||
#define DRAM_MR0 (MCTL_CTL_BASE + 0x00000030)
|
||||
#define DRAM_MR1 (MCTL_CTL_BASE + 0x00000034)
|
||||
#define DRAM_MR2 (MCTL_CTL_BASE + 0x00000038)
|
||||
#define DRAM_MR3 (MCTL_CTL_BASE + 0x0000003c)
|
||||
#define PTR0 (MCTL_CTL_BASE + 0x00000044)
|
||||
#define PTR2 (MCTL_CTL_BASE + 0x0000004c)
|
||||
#define PTR3 (MCTL_CTL_BASE + 0x00000050)
|
||||
#define PTR4 (MCTL_CTL_BASE + 0x00000054)
|
||||
#define DRAMTMG0 (MCTL_CTL_BASE + 0x00000058)
|
||||
#define DRAMTMG1 (MCTL_CTL_BASE + 0x0000005c)
|
||||
#define DRAMTMG2 (MCTL_CTL_BASE + 0x00000060)
|
||||
#define DRAMTMG3 (MCTL_CTL_BASE + 0x00000064)
|
||||
#define DRAMTMG4 (MCTL_CTL_BASE + 0x00000068)
|
||||
#define DRAMTMG5 (MCTL_CTL_BASE + 0x0000006c)
|
||||
#define DRAMTMG6 (MCTL_CTL_BASE + 0x00000070)
|
||||
#define DRAMTMG7 (MCTL_CTL_BASE + 0x00000074)
|
||||
#define DRAMTMG8 (MCTL_CTL_BASE + 0x00000078)
|
||||
#define ODTCFG (MCTL_CTL_BASE + 0x0000007c)
|
||||
#define PITMG0 (MCTL_CTL_BASE + 0x00000080)
|
||||
#define PITMG1 (MCTL_CTL_BASE + 0x00000084)
|
||||
#define LPTPR (MCTL_CTL_BASE + 0x00000088)
|
||||
#define RFSHCTL0 (MCTL_CTL_BASE + 0x0000008c)
|
||||
#define RFSHTMG (MCTL_CTL_BASE + 0x00000090)
|
||||
#define RFSHCTL1 (MCTL_CTL_BASE + 0x00000094)
|
||||
#define PWRTMG (MCTL_CTL_BASE + 0x00000098)
|
||||
#define VTFCR (MCTL_CTL_BASE + 0x000000b8)
|
||||
#define DQSGMR (MCTL_CTL_BASE + 0x000000bc)
|
||||
#define DTCR (MCTL_CTL_BASE + 0x000000c0)
|
||||
#define DTAR0 (MCTL_CTL_BASE + 0x000000c4)
|
||||
#define PGCR0 (MCTL_CTL_BASE + 0x00000100)
|
||||
#define PGCR1 (MCTL_CTL_BASE + 0x00000104)
|
||||
#define PGCR2 (MCTL_CTL_BASE + 0x00000108)
|
||||
#define PGCR3 (MCTL_CTL_BASE + 0x0000010c)
|
||||
#define DXCCR (MCTL_CTL_BASE + 0x0000011c)
|
||||
#define ODTMAP (MCTL_CTL_BASE + 0x00000120)
|
||||
#define ZQCTL0 (MCTL_CTL_BASE + 0x00000124)
|
||||
#define ZQCTL1 (MCTL_CTL_BASE + 0x00000128)
|
||||
#define ZQCR (MCTL_CTL_BASE + 0x00000140)
|
||||
#define ZQSR (MCTL_CTL_BASE + 0x00000144 )
|
||||
#define ZQDR0 (MCTL_CTL_BASE + 0x00000148 )
|
||||
#define ZQDR1 (MCTL_CTL_BASE + 0x0000014c )
|
||||
#define ZQDR2 (MCTL_CTL_BASE + 0x00000150 )
|
||||
#define SCHED (MCTL_CTL_BASE + 0x000001c0)
|
||||
#define PERFHPR0 (MCTL_CTL_BASE + 0x000001c4)
|
||||
#define PERFHPR1 (MCTL_CTL_BASE + 0x000001c8)
|
||||
#define PERFLPR0 (MCTL_CTL_BASE + 0x000001cc)
|
||||
#define PERFLPR1 (MCTL_CTL_BASE + 0x000001d0)
|
||||
#define PERFWR0 (MCTL_CTL_BASE + 0x000001d4)
|
||||
#define PERFWR1 (MCTL_CTL_BASE + 0x000001d8)
|
||||
#define ACMDLR (MCTL_CTL_BASE + 0x00000200)
|
||||
#define ACLDLR (MCTL_CTL_BASE + 0x00000204)
|
||||
#define ACIOCR0 (MCTL_CTL_BASE + 0x00000208)
|
||||
#define ACIOCR1(x) (MCTL_CTL_BASE + 0x00000210 + 0x4 * (x))
|
||||
#define DXnMDLR(x) (MCTL_CTL_BASE + 0x00000300 + 0x80 * x)
|
||||
#define DXnLDLR0(x) (MCTL_CTL_BASE + 0x00000304 + 0x80 * x)
|
||||
#define DXnLDLR1(x) (MCTL_CTL_BASE + 0x00000308 + 0x80 * x)
|
||||
#define DXnLDLR2(x) (MCTL_CTL_BASE + 0x0000030c + 0x80 * x)
|
||||
#define DXIOCR (MCTL_CTL_BASE + 0x00000310)
|
||||
#define DATX0IOCR(x) (MCTL_CTL_BASE + 0x00000310 + 0x4 * (x))
|
||||
#define DATX1IOCR(x) (MCTL_CTL_BASE + 0x00000390 + 0x4 * (x))
|
||||
#define DATX2IOCR(x) (MCTL_CTL_BASE + 0x00000410 + 0x4 * (x))
|
||||
#define DATX3IOCR(x) (MCTL_CTL_BASE + 0x00000490 + 0x4 * (x))
|
||||
#define DXnSDLR6(x) (MCTL_CTL_BASE + 0x0000033c + 0x80 * x)
|
||||
#define DXnGTR(x) (MCTL_CTL_BASE + 0x00000340 + 0x80 * x)
|
||||
#define DXnGCR0(x) (MCTL_CTL_BASE + 0x00000344 + 0x80 * x)
|
||||
#define DXnGSR0(x) (MCTL_CTL_BASE + 0x00000348 + 0x80 * x)
|
||||
|
||||
/*=====================================
|
||||
*PROTECT域寄存器
|
||||
*0x01c63800
|
||||
* ====================================
|
||||
*/
|
||||
#define UPD0 (MCTL_CTL_BASE + 0x00000880)
|
||||
#define UPD1 (MCTL_CTL_BASE + 0x00000884)
|
||||
#define UPD2 (MCTL_CTL_BASE + 0x00000888)
|
||||
#define UPD3 (MCTL_CTL_BASE + 0x0000088c)
|
||||
#define PLPCFG0 (MCTL_CTL_BASE + 0x00000890)
|
||||
/*=====================================
|
||||
*MMCU域寄存器--系统资源
|
||||
*0x01c20000
|
||||
* ====================================
|
||||
*/
|
||||
#define _CCM_BASE 0x03001000
|
||||
|
||||
#define _PLL_DDR0_CTRL_REG (_CCM_BASE+0x10)
|
||||
#define _PLL_DDR1_CTRL_REG (_CCM_BASE+0x18)
|
||||
#define _MBUS_CFG_REG (_CCM_BASE+0x540)
|
||||
#define _DRAM_CLK_REG (_CCM_BASE+0x800)
|
||||
#define _DRAM_BGR_REG (_CCM_BASE+0x80C)
|
||||
#define _PLL_DDR0_SSC_LIN_CTRL_REG (_CCM_BASE+0x214)
|
||||
#define _PLL_DDR1_SSC_LIN_CTRL_REG (_CCM_BASE+0x218)
|
||||
|
||||
/*
|
||||
#define _CCM_PLL_DDR0_REG (_CCM_BASE+0x20)
|
||||
#define _CCM_PLL_DDR1_REG (_CCM_BASE+0x4c)
|
||||
#define _CCM_PLL_DDR_AUX_REG (_CCM_BASE+0xf0)
|
||||
#define _CCM_DRAMCLK_CFG_REG (_CCM_BASE+0xf4)
|
||||
#define _CCM_PLL_DDR1_CFG_REG (_CCM_BASE+0xf8)
|
||||
#define MBUS_RESET_REG (_CCM_BASE+0xfc)
|
||||
#define MBUS_CLK_CTL_REG (_CCM_BASE+0x15c)
|
||||
#define BUS_CLK_GATE_REG0 (_CCM_BASE+0x060)
|
||||
#define PLL_DDR0_PAT_CTL_REG (_CCM_BASE+0x2ac)
|
||||
#define BUS_RST_REG0 (_CCM_BASE+0x2c0)
|
||||
#define CCU_PLL_LOCK_CTRL_REG (_CCM_BASE+0x320)
|
||||
*/
|
||||
|
||||
#endif
|
||||
BIN
sunxi_spl/dram/sun50iw3p1/dram/libchipid
Executable file
BIN
sunxi_spl/dram/sun50iw3p1/dram/libchipid
Executable file
Binary file not shown.
50
sunxi_spl/dram/sun50iw6p1/dram/Makefile
Executable file
50
sunxi_spl/dram/sun50iw6p1/dram/Makefile
Executable file
@@ -0,0 +1,50 @@
|
||||
|
||||
#
|
||||
# (C) Copyright 2000, 2001, 2002
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
all:
|
||||
ifeq ($(notdir $(shell find ./ -name lib-dram)), lib-dram)
|
||||
make -C lib-dram
|
||||
else
|
||||
@echo "libdram exist"
|
||||
endif
|
||||
|
||||
ifeq ($(notdir $(shell find ./ -name lib-chipid)), lib-chipid)
|
||||
make -C lib-chipid
|
||||
else
|
||||
@echo "lib-chipid exist"
|
||||
endif
|
||||
|
||||
cp ./libdram ./libdram.o
|
||||
cp ./libchipid ./libchipid.o
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
BIN
sunxi_spl/dram/sun50iw6p1/dram/libchipid
Executable file
BIN
sunxi_spl/dram/sun50iw6p1/dram/libchipid
Executable file
Binary file not shown.
BIN
sunxi_spl/dram/sun50iw6p1/dram/libdram
Executable file
BIN
sunxi_spl/dram/sun50iw6p1/dram/libdram
Executable file
Binary file not shown.
44
sunxi_spl/dram/sun8iw10p1/dram/Makefile
Executable file
44
sunxi_spl/dram/sun8iw10p1/dram/Makefile
Executable file
@@ -0,0 +1,44 @@
|
||||
|
||||
#
|
||||
# (C) Copyright 2000, 2001, 2002
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
all:
|
||||
ifeq ($(notdir $(shell find ./ -name lib-dram)), lib-dram)
|
||||
make -C lib-dram
|
||||
else
|
||||
@echo "libdram exist"
|
||||
endif
|
||||
|
||||
|
||||
cp ./libdram ./libdram.o
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
BIN
sunxi_spl/dram/sun8iw10p1/dram/libdram
Executable file
BIN
sunxi_spl/dram/sun8iw10p1/dram/libdram
Executable file
Binary file not shown.
50
sunxi_spl/dram/sun8iw11p1/dram/Makefile
Executable file
50
sunxi_spl/dram/sun8iw11p1/dram/Makefile
Executable file
@@ -0,0 +1,50 @@
|
||||
|
||||
#
|
||||
# (C) Copyright 2000, 2001, 2002
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
all:
|
||||
ifeq ($(notdir $(shell find ./ -name lib-dram)), lib-dram)
|
||||
make -C lib-dram
|
||||
else
|
||||
@echo "libdram exist"
|
||||
endif
|
||||
|
||||
ifeq ($(notdir $(shell find ./ -name lib-chipid)), lib-chipid)
|
||||
make -C lib-chipid
|
||||
else
|
||||
@echo "lib-chipid exist"
|
||||
endif
|
||||
|
||||
cp ./libdram ./libdram.o
|
||||
cp ./libchipid ./libchipid.o
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
BIN
sunxi_spl/dram/sun8iw11p1/dram/libchipid
Executable file
BIN
sunxi_spl/dram/sun8iw11p1/dram/libchipid
Executable file
Binary file not shown.
BIN
sunxi_spl/dram/sun8iw11p1/dram/libdram
Executable file
BIN
sunxi_spl/dram/sun8iw11p1/dram/libdram
Executable file
Binary file not shown.
50
sunxi_spl/dram/sun8iw12p1/dram/Makefile
Executable file
50
sunxi_spl/dram/sun8iw12p1/dram/Makefile
Executable file
@@ -0,0 +1,50 @@
|
||||
|
||||
#
|
||||
# (C) Copyright 2000, 2001, 2002
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
all:
|
||||
ifeq ($(notdir $(shell find ./ -name lib-dram)), lib-dram)
|
||||
make -C lib-dram
|
||||
else
|
||||
@echo "libdram exist"
|
||||
endif
|
||||
|
||||
ifeq ($(notdir $(shell find ./ -name lib-chipid)), lib-chipid)
|
||||
make -C lib-chipid
|
||||
else
|
||||
@echo "lib-chipid exist"
|
||||
endif
|
||||
|
||||
cp ./libdram ./libdram.o
|
||||
cp ./libchipid ./libchipid.o
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
BIN
sunxi_spl/dram/sun8iw12p1/dram/libchipid
Executable file
BIN
sunxi_spl/dram/sun8iw12p1/dram/libchipid
Executable file
Binary file not shown.
BIN
sunxi_spl/dram/sun8iw12p1/dram/libdram
Executable file
BIN
sunxi_spl/dram/sun8iw12p1/dram/libdram
Executable file
Binary file not shown.
75
sunxi_spl/fes_init/Makefile
Executable file
75
sunxi_spl/fes_init/Makefile
Executable file
@@ -0,0 +1,75 @@
|
||||
#
|
||||
# (C) Copyright 2000-2011
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# (C) Copyright 2011
|
||||
# Daniel Schwierzeck, daniel.schwierzeck@googlemail.com.
|
||||
#
|
||||
# (C) Copyright 2011
|
||||
# Texas Instruments Incorporated - http://www.ti.com/
|
||||
# Aneesh V <aneesh@ti.com>
|
||||
#
|
||||
# This file is released under the terms of GPL v2 and any later version.
|
||||
# See the file COPYING in the root directory of the source tree for details.
|
||||
#
|
||||
# Based on top-level Makefile.
|
||||
#
|
||||
|
||||
include $(SPLDIR)/config.mk
|
||||
include $(TOPDIR)/include/autoconf.mk
|
||||
include $(TOPDIR)/include/autoconf.mk.dep
|
||||
|
||||
CONFIG_SPL := y
|
||||
export CONFIG_SPL
|
||||
|
||||
FES_LDSCRIPT := $(SPLDIR)/fes_init/main/fes_init.lds
|
||||
|
||||
|
||||
# We want the final binaries in this directory
|
||||
obj := $(SPLBASE)/sunxi_spl/fes_init/
|
||||
|
||||
|
||||
LIBS-y += sunxi_spl/fes_init/spl/libsource_spl.o
|
||||
LIBS-y += sunxi_spl/fes_init/main/libmain.o
|
||||
LIBS-y += sunxi_spl/spl/lib/libgeneric.o
|
||||
LIBS-y += sunxi_spl/dram/$(SOC)/dram/libdram.o
|
||||
LIBS-$(CONFIG_SUNXI_CHIPID) += sunxi_spl/dram/$(SOC)/dram/libchipid.o
|
||||
|
||||
LIBS := $(addprefix $(SPLBASE)/,$(sort $(LIBS-y)))
|
||||
|
||||
|
||||
# Special flags for CPP when processing the linker script.
|
||||
# Pass the version down so we can handle backwards compatibility
|
||||
# on the fly.
|
||||
LDPPFLAGS += \
|
||||
-include $(TOPDIR)/include/u-boot/u-boot.lds.h \
|
||||
-DFES1ADDR=$(CONFIG_FES1_RUN_ADDR) \
|
||||
$(shell $(LD) --version | \
|
||||
sed -ne 's/GNU ld version \([0-9][0-9]*\)\.\([0-9][0-9]*\).*/-DLD_MAJOR=\1 -DLD_MINOR=\2/p')
|
||||
|
||||
ALL-y += $(obj)fes1.bin
|
||||
|
||||
all: $(ALL-y)
|
||||
|
||||
$(obj)fes1.bin: $(obj)fes1.axf
|
||||
$(OBJCOPY) $(OBJCFLAGS) -O binary $< $@
|
||||
|
||||
$(obj)fes1.axf: $(LIBS) $(obj)fes_init.lds
|
||||
$(LD) $(LIBS) $(PLATFORM_LIBGCC) $(LDFLAGS) -T$(obj)fes_init.lds -o fes1.axf -Map fes1.map
|
||||
|
||||
$(LIBS): depend
|
||||
$(MAKE) -C $(SRCTREE)$(dir $(subst $(OBJTREE),,$@))
|
||||
|
||||
$(obj)fes_init.lds: $(FES_LDSCRIPT)
|
||||
@$(CPP) $(ALL_CFLAGS) $(LDPPFLAGS) -ansi -D__ASSEMBLY__ -P - <$^ >$@
|
||||
|
||||
depend:.depend
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude .depend
|
||||
|
||||
#########################################################################
|
||||
35
sunxi_spl/fes_init/main/Makefile
Executable file
35
sunxi_spl/fes_init/main/Makefile
Executable file
@@ -0,0 +1,35 @@
|
||||
|
||||
##
|
||||
## Makefile for Sunxi Secure Boot
|
||||
##
|
||||
|
||||
|
||||
|
||||
include $(SPLDIR)/config.mk
|
||||
|
||||
LIB := $(obj)libmain.o
|
||||
|
||||
HEAD := fes_head.o
|
||||
|
||||
START := fes1_entry.o
|
||||
|
||||
COBJS += fes1_main.o
|
||||
|
||||
SRCS := $(START:.o=.S) $(COBJS:.o=.c) $(HEAD:.o=.c)
|
||||
|
||||
OBJS = $(COBJS)
|
||||
|
||||
all: .depend $(HEAD) $(START) $(LIB)
|
||||
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
45
sunxi_spl/fes_init/main/fes1_entry.S
Executable file
45
sunxi_spl/fes_init/main/fes1_entry.S
Executable file
@@ -0,0 +1,45 @@
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
.globl _start
|
||||
_start: b reset
|
||||
|
||||
reset:
|
||||
stmfd sp!, {lr}
|
||||
bl clear_bss
|
||||
bl main
|
||||
ldmfd sp!, {lr}
|
||||
#ifndef CONFIG_ARCH_SUN8IW10P1
|
||||
mov pc, lr
|
||||
#else
|
||||
ldr r0, =0x40200000
|
||||
mov r1, sp
|
||||
mov r2, #0x2000
|
||||
|
||||
memcpy_loop:
|
||||
ldmia r1!, {r7-r10}
|
||||
stmia r0!, {r7-r10}
|
||||
sub r2, r2, #16
|
||||
cmp r2, #0
|
||||
bne memcpy_loop
|
||||
|
||||
ldr r0, =0x40200000
|
||||
mov sp, r0
|
||||
mov pc, lr
|
||||
#endif
|
||||
|
||||
|
||||
clear_bss:
|
||||
ldr r0, =__bss_start
|
||||
ldr r1, =__bss_end
|
||||
|
||||
mov r2, #0x00000000 /* clear */
|
||||
|
||||
clbss_l:
|
||||
str r2, [r0] /* clear loop... */
|
||||
add r0, r0, #4
|
||||
cmp r0, r1
|
||||
bne clbss_l
|
||||
|
||||
mov pc, lr
|
||||
154
sunxi_spl/fes_init/main/fes1_main.c
Executable file
154
sunxi_spl/fes_init/main/fes1_main.c
Executable file
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
**********************************************************************************************************************
|
||||
*
|
||||
* the Embedded Secure Bootloader System
|
||||
*
|
||||
*
|
||||
* Copyright(C), 2006-2014, Allwinnertech Co., Ltd.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File :
|
||||
*
|
||||
* By :
|
||||
*
|
||||
* Version : V2.00
|
||||
*
|
||||
* Date :
|
||||
*
|
||||
* Descript:
|
||||
**********************************************************************************************************************
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <private_boot0.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/timer.h>
|
||||
#include <asm/arch/uart.h>
|
||||
#include <asm/arch/dram.h>
|
||||
#include <asm/arch/ccmu.h>
|
||||
#include <asm/arch/base_pmu.h>
|
||||
|
||||
extern void set_pll( void );
|
||||
extern void set_gpio_gate( void );
|
||||
|
||||
extern const boot0_file_head_t fes1_head;
|
||||
|
||||
typedef struct __fes_aide_info{
|
||||
__u32 dram_init_flag; /* Dram初始化完成标志 */
|
||||
__u32 dram_update_flag; /* Dram 参数是否被修改标志 */
|
||||
__u32 dram_paras[SUNXI_DRAM_PARA_MAX];
|
||||
}fes_aide_info_t;
|
||||
|
||||
|
||||
//note: this function for linker error
|
||||
int raise (int signum)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Dummy function to avoid linker complaints */
|
||||
void __aeabi_unwind_cpp_pr0(void)
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************
|
||||
* note_dram_log
|
||||
*
|
||||
* Description:
|
||||
* ???????
|
||||
* Parameters:
|
||||
* void
|
||||
* Return value:
|
||||
* 0: success
|
||||
* !0: fail
|
||||
* History:
|
||||
* void
|
||||
************************************************************************************
|
||||
*/
|
||||
static void note_dram_log(int dram_init_flag)
|
||||
{
|
||||
fes_aide_info_t *fes_aide = (fes_aide_info_t *)CONFIG_FES1_RET_ADDR;
|
||||
|
||||
memset(fes_aide, 0, sizeof(fes_aide_info_t));
|
||||
fes_aide->dram_init_flag = SYS_PARA_LOG;
|
||||
fes_aide->dram_update_flag = dram_init_flag;
|
||||
|
||||
memcpy(fes_aide->dram_paras, fes1_head.prvt_head.dram_para, SUNXI_DRAM_PARA_MAX * 4);
|
||||
memcpy((void *)DRAM_PARA_STORE_ADDR, fes1_head.prvt_head.dram_para, SUNXI_DRAM_PARA_MAX * 4);
|
||||
}
|
||||
/*
|
||||
************************************************************************************************************
|
||||
*
|
||||
* function
|
||||
*
|
||||
* name :
|
||||
*
|
||||
* parmeters :
|
||||
*
|
||||
* return :
|
||||
*
|
||||
* note :
|
||||
*
|
||||
*
|
||||
************************************************************************************************************
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
__s32 dram_size=0;
|
||||
|
||||
timer_init();
|
||||
//serial init
|
||||
sunxi_serial_init(fes1_head.prvt_head.uart_port, (void *)fes1_head.prvt_head.uart_ctrl, 2);
|
||||
|
||||
pmu_init(fes1_head.prvt_head.power_mode);
|
||||
#ifdef CONFIG_SUNXI_MULITCORE_BOOT
|
||||
set_pll_voltage(CONFIG_SUNXI_CORE_VOL);
|
||||
#endif
|
||||
set_pll();
|
||||
|
||||
//enable gpio gate
|
||||
set_gpio_gate();
|
||||
//dram init
|
||||
printf("beign to init dram\n");
|
||||
#ifdef FPGA_PLATFORM
|
||||
dram_size = mctl_init((void *)fes1_head.prvt_head.dram_para);
|
||||
#else
|
||||
#if defined(CONFIG_SUNXI_CRASH)
|
||||
dram_size = DRAMC_get_dram_size();
|
||||
printf("dram size=%dM\n", dram_size);
|
||||
if (dram_size)
|
||||
{
|
||||
__dram_para_t *dram_para = (__dram_para_t *)fes1_head.prvt_head.dram_para;
|
||||
|
||||
dram_para->dram_para2 &= 0xffff;
|
||||
dram_para->dram_para2 |= (dram_size << 16);
|
||||
|
||||
note_dram_log(1);
|
||||
printf("init dram ok\n");
|
||||
} else {
|
||||
dram_size = init_DRAM(0, (void *)fes1_head.prvt_head.dram_para);
|
||||
}
|
||||
#else
|
||||
dram_size = init_DRAM(0, (void *)fes1_head.prvt_head.dram_para);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (dram_size)
|
||||
{
|
||||
note_dram_log(1);
|
||||
printf("init dram ok\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
note_dram_log(0);
|
||||
printf("init dram fail\n");
|
||||
}
|
||||
|
||||
__msdelay(10);
|
||||
|
||||
return dram_size;
|
||||
}
|
||||
|
||||
124
sunxi_spl/fes_init/main/fes_head.c
Executable file
124
sunxi_spl/fes_init/main/fes_head.c
Executable file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* eGON
|
||||
* the Embedded GO-ON Bootloader System
|
||||
*
|
||||
* Copyright(C), 2006-2008, SoftWinners Microelectronic Co., Ltd.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File Name : Boot0_head.c
|
||||
*
|
||||
* Author : Gary.Wang
|
||||
*
|
||||
* Version : 1.1.0
|
||||
*
|
||||
* Date : 2007.11.06
|
||||
*
|
||||
* Description : This file defines the file head part of Boot0, which contains some important
|
||||
* infomations such as magic, platform infomation and so on, and MUST be allocted in the
|
||||
* head of Boot0.
|
||||
*
|
||||
* Others : None at present.
|
||||
*
|
||||
*
|
||||
* History :
|
||||
*
|
||||
* <Author> <time> <version> <description>
|
||||
*
|
||||
* Gary.Wang 2007.11.06 1.1.0 build the file
|
||||
*
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
#include "common.h"
|
||||
#include <private_boot0.h>
|
||||
|
||||
const boot0_file_head_t fes1_head =
|
||||
{
|
||||
{
|
||||
/* jump_instruction */
|
||||
( 0xEA000000 | ( ( ( sizeof( boot0_file_head_t ) + sizeof( int ) - 1 ) / sizeof( int ) - 2 ) & 0x00FFFFFF ) ),
|
||||
BOOT0_MAGIC,
|
||||
STAMP_VALUE,
|
||||
32,
|
||||
sizeof( boot_file_head_t ),
|
||||
BOOT_PUB_HEAD_VERSION,
|
||||
CONFIG_FES1_RET_ADDR,
|
||||
CONFIG_FES1_RUN_ADDR,
|
||||
0,
|
||||
{
|
||||
0, 0, '3','.','0','.','0',0
|
||||
},
|
||||
},
|
||||
{
|
||||
//__u32 prvt_head_size;
|
||||
0,
|
||||
//char prvt_head_vsn[4];
|
||||
0,
|
||||
0, /*power_mode*/
|
||||
{0},/* reserver[2] */
|
||||
//unsigned int dram_para[32] ;
|
||||
{0},
|
||||
//__s32 uart_port;
|
||||
0,
|
||||
//normal_gpio_cfg uart_ctrl[2];
|
||||
{
|
||||
{ 2, 8, 4, 1, 1, 0, {0}},//PB8: 4--RX
|
||||
{ 2, 9, 4, 1, 1, 0, {0}},//PB9: 4--TX
|
||||
},
|
||||
//__s32 enable_jtag;
|
||||
0,
|
||||
//normal_gpio_cfg jtag_gpio[5];
|
||||
{{0},{0},{0},{0},{0}},
|
||||
//normal_gpio_cfg storage_gpio[32];
|
||||
{
|
||||
{ 6, 0, 2, 1, 2, 0, {0}},//PF0-5: 2--SDC
|
||||
{ 6, 1, 2, 1, 2, 0, {0}},
|
||||
{ 6, 2, 2, 1, 2, 0, {0}},
|
||||
{ 6, 3, 2, 1, 2, 0, {0}},
|
||||
{ 6, 4, 2, 1, 2, 0, {0}},
|
||||
{ 6, 5, 2, 1, 2, 0, {0}},
|
||||
},
|
||||
//char storage_data[512 - sizeof(normal_gpio_cfg) * 32];
|
||||
{0}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* 关于Boot_file_head中的jump_instruction字段
|
||||
*
|
||||
* jump_instruction字段存放的是一条跳转指令:( B BACK_OF_Boot_file_head ),此跳
|
||||
*转指令被执行后,程序将跳转到Boot_file_head后面第一条指令。
|
||||
*
|
||||
* ARM指令中的B指令编码如下:
|
||||
* +--------+---------+------------------------------+
|
||||
* | 31--28 | 27--24 | 23--0 |
|
||||
* +--------+---------+------------------------------+
|
||||
* | cond | 1 0 1 0 | signed_immed_24 |
|
||||
* +--------+---------+------------------------------+
|
||||
* 《ARM Architecture Reference Manual》对于此指令有如下解释:
|
||||
* Syntax :
|
||||
* B{<cond>} <target_address>
|
||||
* <cond> Is the condition under which the instruction is executed. If the
|
||||
* <cond> is ommitted, the AL(always,its code is 0b1110 )is used.
|
||||
* <target_address>
|
||||
* Specified the address to branch to. The branch target address is
|
||||
* calculated by:
|
||||
* 1. Sign-extending the 24-bit signed(wro's complement)immediate
|
||||
* to 32 bits.
|
||||
* 2. Shifting the result left two bits.
|
||||
* 3. Adding to the contents of the PC, which contains the address
|
||||
* of the branch instruction plus 8.
|
||||
*
|
||||
* 由此可知,此指令编码的最高8位为:0b11101010,低24位根据Boot_file_head的大小动
|
||||
*态生成,所以指令的组装过程如下:
|
||||
* ( sizeof( boot_file_head_t ) + sizeof( int ) - 1 ) / sizeof( int )
|
||||
* 求出文件头占用的“字”的个数
|
||||
* - 2 减去PC预取的指令条数
|
||||
* & 0x00FFFFFF 求出signed-immed-24
|
||||
* | 0xEA000000 组装成B指令
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
55
sunxi_spl/fes_init/spl/Makefile
Executable file
55
sunxi_spl/fes_init/spl/Makefile
Executable file
@@ -0,0 +1,55 @@
|
||||
#
|
||||
# (C) Copyright 2000-2003
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(SPLDIR)/config.mk
|
||||
|
||||
LIB = $(obj)libsource_spl.o
|
||||
|
||||
COBJS-y += $(TOPDIR)/arch/$(ARCH)/cpu/$(CPU)/$(SOC)/spl/timer_spl.o
|
||||
COBJS-y += $(TOPDIR)/arch/$(ARCH)/cpu/$(CPU)/$(SOC)/spl/gpio_spl.o
|
||||
COBJS-y += $(TOPDIR)/arch/$(ARCH)/cpu/$(CPU)/$(SOC)/spl/serial_spl.o
|
||||
COBJS-y += $(TOPDIR)/arch/$(ARCH)/cpu/$(CPU)/$(SOC)/spl/clock_spl.o
|
||||
COBJS-$(CONFIG_SUNXI_MODULE_AXP) += $(TOPDIR)/arch/$(ARCH)/cpu/$(CPU)/$(SOC)/spl/pmu_spl.o
|
||||
COBJS-$(CONFIG_AXP_USE_RSB) += $(TOPDIR)/arch/$(ARCH)/cpu/$(CPU)/$(SOC)/spl/rsb_spl.o
|
||||
COBJS-$(CONFIG_AXP_USE_I2C) += $(TOPDIR)/arch/$(ARCH)/cpu/$(CPU)/$(SOC)/spl/sunxi_i2c_spl.o
|
||||
COBJS-$(CONFIG_SUNXI_CHIPID)+= $(TOPDIR)/arch/$(ARCH)/cpu/$(CPU)/$(SOC)/spl/efuse_spl.o
|
||||
|
||||
#COBJS-$(CONFIG_XXXX) += xxxx.o
|
||||
COBJS := $(COBJS-y)
|
||||
|
||||
SRCS := $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS))
|
||||
|
||||
all: $(obj).depend $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
33
sunxi_spl/include/boot0_helper.h
Executable file
33
sunxi_spl/include/boot0_helper.h
Executable file
@@ -0,0 +1,33 @@
|
||||
|
||||
#ifndef _BOOT0_HELPER_H_
|
||||
#define _BOOT0_HELPER_H_
|
||||
|
||||
extern __s32 boot_set_gpio(void *user_gpio_list, __u32 group_count_max, __s32 set_gpio);
|
||||
extern void mmu_setup(u32 dram_size);
|
||||
extern void mmu_turn_off( void );
|
||||
extern int load_boot1(void);
|
||||
extern void set_dram_para(void *dram_addr , __u32 dram_size, __u32 boot_cpu);
|
||||
extern void boot0_jump(unsigned int addr);
|
||||
extern void boot0_jmp_boot1(unsigned int addr);
|
||||
extern void boot0_jmp_other(unsigned int addr);
|
||||
extern void boot0_jmp_monitor(void);
|
||||
extern void reset_pll( void );
|
||||
extern int load_fip(int *use_monitor);
|
||||
extern int set_debugmode_flag(void);
|
||||
extern void set_pll( void );
|
||||
extern void update_flash_para(void);
|
||||
|
||||
|
||||
extern int printf(const char *fmt, ...);
|
||||
extern void * memcpy(void * dest,const void *src,size_t count);
|
||||
extern void * memset(void * s, int c, size_t count);
|
||||
extern void * memcpy_align16(void * dest,const void *src,size_t count);
|
||||
extern int strncmp(const char * cs,const char * ct,size_t count);
|
||||
|
||||
u32 get_sys_ticks(void);
|
||||
void __usdelay(unsigned long us);
|
||||
void __msdelay(unsigned long ms);
|
||||
char get_uart_input(void);
|
||||
|
||||
|
||||
#endif
|
||||
43
sunxi_spl/sbrom/.gitignore
vendored
Executable file
43
sunxi_spl/sbrom/.gitignore
vendored
Executable file
@@ -0,0 +1,43 @@
|
||||
#
|
||||
# NOTE! Don't add files that are generated in specific
|
||||
# subdirectories here. Add them in the ".gitignore" file
|
||||
# in that subdirectory instead.
|
||||
#
|
||||
# Normal rules
|
||||
#
|
||||
|
||||
*.rej
|
||||
*.orig
|
||||
*.a
|
||||
*.o
|
||||
*~
|
||||
*.swp
|
||||
*.patch
|
||||
*.bin
|
||||
*.axf
|
||||
|
||||
#
|
||||
# Top-level generic files
|
||||
#
|
||||
|
||||
/sboot
|
||||
/sboot.hex
|
||||
/sboot.imx
|
||||
/sboot.map
|
||||
/sboot.srec
|
||||
/sboot.ldr
|
||||
/sboot.ldr.hex
|
||||
/sboot.ldr.srec
|
||||
/sboot.img
|
||||
/sboot.kwb
|
||||
/sboot.sha1
|
||||
/sboot.dis
|
||||
/sboot.lds
|
||||
/sboot.ubl
|
||||
|
||||
#
|
||||
# Generated files
|
||||
#
|
||||
|
||||
*.depend
|
||||
|
||||
96
sunxi_spl/sbrom/Makefile
Executable file
96
sunxi_spl/sbrom/Makefile
Executable file
@@ -0,0 +1,96 @@
|
||||
#
|
||||
# (C) Copyright 2000-2011
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# (C) Copyright 2011
|
||||
# Daniel Schwierzeck, daniel.schwierzeck@googlemail.com.
|
||||
#
|
||||
# (C) Copyright 2011
|
||||
# Texas Instruments Incorporated - http://www.ti.com/
|
||||
# Aneesh V <aneesh@ti.com>
|
||||
#
|
||||
# This file is released under the terms of GPL v2 and any later version.
|
||||
# See the file COPYING in the root directory of the source tree for details.
|
||||
#
|
||||
# Based on top-level Makefile.
|
||||
#
|
||||
|
||||
include $(SPLDIR)/config.mk
|
||||
include $(TOPDIR)/include/autoconf.mk
|
||||
include $(TOPDIR)/include/autoconf.mk.dep
|
||||
|
||||
CONFIG_SPL := y
|
||||
export CONFIG_SPL
|
||||
|
||||
TOOLS_DIR := $(TOPDIR)/tools
|
||||
|
||||
SBROM_LDSCRIPT := $(SPLBASE)/sunxi_spl/sbrom/main/sboot.lds
|
||||
|
||||
# We want the final binaries in this directory
|
||||
obj := $(SPLBASE)/sunxi_spl/sbrom/
|
||||
|
||||
HEAD := main/sbromsw_head.o
|
||||
START := main/brom.o
|
||||
|
||||
LIBS-y += sunxi_spl/sbrom/spl/libsource_spl.o
|
||||
LIBS-y += sunxi_spl/sbrom/main/libmain.o
|
||||
LIBS-y += sunxi_spl/sbrom/libs/libgeneric.o
|
||||
LIBS-y += sunxi_spl/sbrom/flash/libflash.o
|
||||
LIBS-y += sunxi_spl/sbrom/load/libload.o
|
||||
LIBS-y += sunxi_spl/spl/lib/libgeneric.o
|
||||
LIBS-y += sunxi_spl/sbrom/openssl/libopenssl.o
|
||||
LIBS-y += sunxi_spl/dram/$(SOC)/dram/libdram.o
|
||||
LIBS-$(CONFIG_SUNXI_HDMI_IN_BOOT0) += sunxi_spl/display/hdmi/libdisplay.o
|
||||
LIBS-$(CONFIG_SUNXI_CHIPID) += sunxi_spl/dram/$(SOC)/dram/libchipid.o
|
||||
LIBS-$(CONFIG_SUNXI_KEY_LADDER) += sunxi_spl/sbrom/keyladder/libkeyladder.o
|
||||
|
||||
LIBS := $(addprefix $(SPLBASE)/,$(sort $(LIBS-y)))
|
||||
__LIBS := $(subst $(obj),,$(LIBS))
|
||||
|
||||
FLASH-y += $(TOPDIR)/arch/$(ARCH)/cpu/$(CPU)/$(SOC)/nand/libnand.o
|
||||
FLASH-y += $(TOPDIR)/arch/$(ARCH)/cpu/$(CPU)/$(SOC)/mmc/libmmc.o
|
||||
|
||||
LIBS += $(FLASH-y)
|
||||
|
||||
# Special flags for CPP when processing the linker script.
|
||||
# Pass the version down so we can handle backwards compatibility
|
||||
# on the fly.
|
||||
LDPPFLAGS += \
|
||||
-include $(TOPDIR)/include/u-boot/u-boot.lds.h \
|
||||
-DSBROMSWADDR=$(CONFIG_TOC0_RUN_ADDR) \
|
||||
$(shell $(LD) --version | \
|
||||
sed -ne 's/GNU ld version \([0-9][0-9]*\)\.\([0-9][0-9]*\).*/-DLD_MAJOR=\1 -DLD_MINOR=\2/p')
|
||||
|
||||
ALL-y += $(obj)sboot.bin
|
||||
|
||||
all: $(ALL-y)
|
||||
|
||||
|
||||
$(obj)sboot.bin: $(obj)sboot.axf $(obj)cur.log
|
||||
$(OBJCOPY) $(OBJCFLAGS) -O binary $< $@
|
||||
$(SPLDIR)/../../tools/add_hash.sh -f $(SPLDIR)/sbrom/sboot.bin -m sboot
|
||||
|
||||
$(obj)sboot.axf: $(LIBS) $(obj)sboot.lds
|
||||
$(LD) $(LIBS) $(PLATFORM_LIBGCC) $(LDFLAGS) -T$(obj)sboot.lds -o sboot.axf -Map sboot.map
|
||||
|
||||
$(LIBS): depend
|
||||
$(MAKE) -C $(SRCTREE)$(dir $(subst $(OBJTREE),,$@))
|
||||
|
||||
$(obj)sboot.lds: $(SBROM_LDSCRIPT)
|
||||
$(CPP) $(CPPFLAGS) $(LDPPFLAGS) -ansi -D__ASSEMBLY__ -P - <$^ >$@
|
||||
|
||||
$(obj)cur.log:
|
||||
@git show HEAD --pretty=format:"%H" | head -n 1 > cur.log
|
||||
|
||||
depend:.depend
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude .depend
|
||||
|
||||
#########################################################################
|
||||
|
||||
|
||||
31
sunxi_spl/sbrom/flash/Makefile
Executable file
31
sunxi_spl/sbrom/flash/Makefile
Executable file
@@ -0,0 +1,31 @@
|
||||
|
||||
##
|
||||
## Makefile for Sunxi Secure Boot
|
||||
##
|
||||
|
||||
|
||||
|
||||
include $(SPLDIR)/config.mk
|
||||
|
||||
LIB := $(obj)libflash.o
|
||||
|
||||
COBJS += flash.o
|
||||
|
||||
|
||||
COBJS := $(COBJS)
|
||||
SRCS := $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS))
|
||||
|
||||
all: $(LIB)
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
158
sunxi_spl/sbrom/flash/flash.c
Executable file
158
sunxi_spl/sbrom/flash/flash.c
Executable file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
**********************************************************************************************************************
|
||||
*
|
||||
* the Embedded Secure Bootloader System
|
||||
*
|
||||
*
|
||||
* Copyright(C), 2006-2014, Allwinnertech Co., Ltd.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File :
|
||||
*
|
||||
* By :
|
||||
*
|
||||
* Version : V2.00
|
||||
*
|
||||
* Date :
|
||||
*
|
||||
* Descript:
|
||||
**********************************************************************************************************************
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "mmc.h"
|
||||
#include "spare_head.h"
|
||||
#include "private_toc.h"
|
||||
|
||||
|
||||
extern int sunxi_mmc_init(int sdc_no, unsigned bus_width, normal_gpio_cfg *gpio_info, int offset);
|
||||
extern int load_toc1_from_nand( void );
|
||||
extern int verify_addsum( void *mem_base, __u32 size );
|
||||
|
||||
|
||||
extern sbrom_toc0_config_t *toc0_config;
|
||||
/*
|
||||
************************************************************************************************************
|
||||
*
|
||||
* function
|
||||
*
|
||||
* name :
|
||||
*
|
||||
* parmeters :
|
||||
*
|
||||
* return :
|
||||
*
|
||||
* note :
|
||||
*
|
||||
*
|
||||
************************************************************************************************************
|
||||
*/
|
||||
int sunxi_flash_init(int boot_type)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if((boot_type == BOOT_FROM_SD0) || (boot_type == BOOT_FROM_SD2))
|
||||
{
|
||||
u8 *tmp_buff = (u8 *)CONFIG_TOC1_STORE_IN_DRAM_BASE;
|
||||
uint head_size;
|
||||
sbrom_toc1_head_info_t *toc1_head;
|
||||
int sunxi_flash_mmc_card_no;
|
||||
int start_sector,i;
|
||||
int start_sectors[4] = {UBOOT_START_SECTOR_IN_SDMMC,UBOOT_BACKUP_START_SECTOR_IN_SDMMC,0,0};
|
||||
|
||||
if(boot_type == BOOT_FROM_SD0)
|
||||
{
|
||||
sunxi_flash_mmc_card_no = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
sunxi_flash_mmc_card_no = 2;
|
||||
}
|
||||
ret = sunxi_mmc_init(sunxi_flash_mmc_card_no, 4, toc0_config->storage_gpio + 24, 8);
|
||||
if(ret <= 0)
|
||||
{
|
||||
printf("mmc: init failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(i = 0; i<4; i++)
|
||||
{
|
||||
start_sector = start_sectors[i];
|
||||
tmp_buff = (u8 *)CONFIG_TOC1_STORE_IN_DRAM_BASE;
|
||||
if(start_sector == 0)
|
||||
{
|
||||
printf("mmc: read all toc1 failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = mmc_bread(sunxi_flash_mmc_card_no, start_sector, 64, tmp_buff);
|
||||
if(!ret)
|
||||
{
|
||||
printf("mmc: read error,start=%d\n",start_sector);
|
||||
continue;
|
||||
}
|
||||
toc1_head = (struct sbrom_toc1_head_info *)tmp_buff;
|
||||
if(toc1_head->magic != TOC_MAIN_INFO_MAGIC)
|
||||
{
|
||||
printf("mmc: toc1 magic error\n");
|
||||
continue;
|
||||
}
|
||||
head_size = toc1_head->valid_len;
|
||||
if(head_size > 64 * 512)
|
||||
{
|
||||
tmp_buff += 64*512;
|
||||
ret = mmc_bread(sunxi_flash_mmc_card_no, start_sector + 64, (head_size - 64*512 + 511)/512, tmp_buff);
|
||||
if(!ret)
|
||||
{
|
||||
printf("mmc:read error\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if( verify_addsum( (__u32 *)CONFIG_TOC1_STORE_IN_DRAM_BASE, head_size) != 0 )
|
||||
{
|
||||
printf("mmc: toc1 checksun error.\n");
|
||||
continue;
|
||||
}
|
||||
printf("read toc1 from emmc %d sector\n",start_sector);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else if(boot_type == BOOT_FROM_NFC)
|
||||
{
|
||||
if(load_toc1_from_nand())
|
||||
{
|
||||
printf("nand: init failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("PANIC: boot_type(%d) not support now\n",boot_type);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/*
|
||||
************************************************************************************************************
|
||||
*
|
||||
* function
|
||||
*
|
||||
* name :
|
||||
*
|
||||
* parmeters :
|
||||
*
|
||||
* return :
|
||||
*
|
||||
* note :
|
||||
*
|
||||
*
|
||||
************************************************************************************************************
|
||||
*/
|
||||
int sunxi_flash_read(u32 start_sector, u32 blkcnt, void *buff)
|
||||
{
|
||||
memcpy(buff, (void *)(CONFIG_TOC1_STORE_IN_DRAM_BASE + 512 * start_sector), 512 * blkcnt);
|
||||
|
||||
return blkcnt;
|
||||
}
|
||||
29
sunxi_spl/sbrom/keyladder/Makefile
Executable file
29
sunxi_spl/sbrom/keyladder/Makefile
Executable file
@@ -0,0 +1,29 @@
|
||||
|
||||
##
|
||||
## Makefile for Sunxi Secure Boot
|
||||
##
|
||||
|
||||
|
||||
|
||||
include $(SPLDIR)/config.mk
|
||||
|
||||
LIB := $(obj)libkeyladder.o
|
||||
|
||||
COBJS += keyladder.o
|
||||
|
||||
COBJS := $(COBJS)
|
||||
OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
|
||||
|
||||
all: $(LIB)
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
171
sunxi_spl/sbrom/keyladder/keyladder.c
Executable file
171
sunxi_spl/sbrom/keyladder/keyladder.c
Executable file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
**********************************************************************************************************************
|
||||
*
|
||||
* the Embedded Secure Bootloader System
|
||||
*
|
||||
*
|
||||
* Copyright(C), 2006-2014, Allwinnertech Co., Ltd.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File :
|
||||
*
|
||||
* By :
|
||||
*
|
||||
* Version : V2.00
|
||||
*
|
||||
* Date :
|
||||
*
|
||||
* Descript:
|
||||
**********************************************************************************************************************
|
||||
*/
|
||||
#include "common.h"
|
||||
#include <private_toc.h>
|
||||
#include <private_uboot.h>
|
||||
#include "asm/arch/platform.h"
|
||||
#include "openssl_ext.h"
|
||||
#include "asm/arch/ss.h"
|
||||
#include "asm/arch/uart.h"
|
||||
|
||||
extern int sid_prode_key_ladder(void);
|
||||
extern void ndump(u8 *buf, int count);
|
||||
|
||||
extern sbrom_toc0_config_t *toc0_config;
|
||||
extern int mmc_config_addr;
|
||||
SBROM_TOC0_KEY_ITEM_info_t *key_item = NULL;
|
||||
int key_ladder_flag;
|
||||
|
||||
static void toc0_config_init(void)
|
||||
{
|
||||
toc0_config = (sbrom_toc0_config_t *) (CONFIG_SBROMSW_BASE + 0xA0);
|
||||
mmc_config_addr = (int)(toc0_config->storage_data + 160);
|
||||
}
|
||||
|
||||
/*
|
||||
* get_key1_pk
|
||||
*
|
||||
* fuction: get key1 from toc0 head
|
||||
*
|
||||
* return:
|
||||
*
|
||||
*/
|
||||
|
||||
static void get_key1_pk(toc0_private_head_t *toc0)
|
||||
{
|
||||
SBROM_TOC0_ITEM_info_t *toc0_item = NULL;
|
||||
int i=0;
|
||||
|
||||
toc0_item = (SBROM_TOC0_ITEM_info_t *) (CONFIG_SBROMSW_BASE + sizeof(toc0_private_head_t));
|
||||
for ( i = 0; i < toc0->items_nr;i++) {
|
||||
if (toc0_item->name == ITEM_NAME_SBROMSW_KEY) {
|
||||
key_item = (SBROM_TOC0_KEY_ITEM_info_t *) (CONFIG_SBROMSW_BASE + toc0_item->data_offset);
|
||||
return ;
|
||||
}
|
||||
toc0_item++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* key_ladder_init
|
||||
*
|
||||
* fuction: It will prode the key ladder is valid,it will set toc0_config offset
|
||||
* and get key1 from toc0 head.
|
||||
* return:
|
||||
*
|
||||
*/
|
||||
|
||||
void key_ladder_init(toc0_private_head_t *toc0)
|
||||
{
|
||||
key_ladder_flag = sid_prode_key_ladder();
|
||||
if (key_ladder_flag == 2) {
|
||||
toc0_config_init();
|
||||
get_key1_pk(toc0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#define RSA_BIT_WITDH 2048
|
||||
int sunxi_key_ladder_pk_check(sunxi_key_t *pubkey)
|
||||
{
|
||||
char key_item_hash[256], rotpk_hash[256];
|
||||
char pk[RSA_BIT_WITDH/8 * 2 + 256];
|
||||
|
||||
if(key_item == NULL) {
|
||||
pr_error("key_item is NULL!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(key_item_hash, 0, 32);
|
||||
memset(pk, 0x91, sizeof(pk));
|
||||
char *align = (char *)(((u32)pk+31)&(~31));
|
||||
if ( *(key_item->KEY1_PK) ) {
|
||||
memcpy(align, key_item->KEY1_PK, (key_item->KEY1_PK_mod_len + key_item->KEY1_PK_e_len));
|
||||
} else {
|
||||
memcpy(align, key_item->KEY1_PK+1, (key_item->KEY1_PK_mod_len-1 + key_item->KEY1_PK_e_len));
|
||||
}
|
||||
if (sunxi_sha_calc( (u8 *)key_item_hash, 32, (u8 *)align, RSA_BIT_WITDH/8*2 )) {
|
||||
printf("sunxi_sha_calc: calc key item key1 pk sha256 with hardware err\n");
|
||||
return -1;
|
||||
}
|
||||
/*ndump((u8 *)align , RSA_BIT_WITDH/8*2 );*/
|
||||
|
||||
memset(rotpk_hash, 0, 32);
|
||||
memset(pk, 0x91, sizeof(pk));
|
||||
if ( *(pubkey->n) ) {
|
||||
memcpy(align, pubkey->n, pubkey->n_len);
|
||||
memcpy(align+pubkey->n_len, pubkey->e, pubkey->e_len);
|
||||
} else {
|
||||
memcpy(align, pubkey->n+1, pubkey->n_len-1);
|
||||
memcpy(align+pubkey->n_len-1, pubkey->e, pubkey->e_len);
|
||||
}
|
||||
|
||||
if (sunxi_sha_calc( (u8 *)rotpk_hash, 32, (u8 *)align, RSA_BIT_WITDH/8*2 )) {
|
||||
printf("sunxi_sha_calc: calc pubkey sha256 with hardware err\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (memcmp(rotpk_hash, key_item_hash, 32)) {
|
||||
pr_error("certif pk dump\n");
|
||||
ndump((u8 *)align , RSA_BIT_WITDH/8*2 );
|
||||
|
||||
pr_error("calc certif pk hash dump\n");
|
||||
ndump((u8 *)rotpk_hash,32);
|
||||
|
||||
pr_error("key_item_hash pk1 hash dump\n");
|
||||
ndump((u8 *)key_item_hash,32);
|
||||
|
||||
pr_error("sunxi_key_ladder_pk_check: pubkey hash check err\n");
|
||||
return -1;
|
||||
}
|
||||
return 0 ;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* sunxi_key_ladder_verify
|
||||
*
|
||||
* fuction:if the key ladder is valid,it will check the pk
|
||||
* of key item
|
||||
* return: 0-- check pk right
|
||||
* 1-- check pk failure
|
||||
* 2-- no key ladder check
|
||||
*/
|
||||
|
||||
int sunxi_key_ladder_verify(sunxi_key_t *pubkey)
|
||||
{
|
||||
int ret = 0;
|
||||
if (key_ladder_flag == 2 ) {
|
||||
pr_force("enter the two key ladder pk check!\n");
|
||||
ret = sunxi_key_ladder_pk_check(pubkey);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
pr_force("enter the one key ladder pk check!\n");
|
||||
}
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
29
sunxi_spl/sbrom/keyladder/keyladder.h
Executable file
29
sunxi_spl/sbrom/keyladder/keyladder.h
Executable file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
**********************************************************************************************************************
|
||||
*
|
||||
* the Embedded Secure Bootloader System
|
||||
*
|
||||
*
|
||||
* Copyright(C), 2006-2014, Allwinnertech Co., Ltd.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File :
|
||||
*
|
||||
* By :
|
||||
*
|
||||
* Version : V2.00
|
||||
*
|
||||
* Date :
|
||||
*
|
||||
* Descript:
|
||||
**********************************************************************************************************************
|
||||
*/
|
||||
#ifndef __KEYLADDER_H__
|
||||
#define __KEYLADDER_H__
|
||||
|
||||
extern void key_ladder_init(toc0_private_head_t *toc0);
|
||||
extern int sunxi_key_ladder_verify(sunxi_key_t *pubkey);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
38
sunxi_spl/sbrom/libs/Makefile
Executable file
38
sunxi_spl/sbrom/libs/Makefile
Executable file
@@ -0,0 +1,38 @@
|
||||
|
||||
##
|
||||
## Makefile for Sunxi Secure Boot
|
||||
##
|
||||
|
||||
|
||||
|
||||
include $(SPLDIR)/config.mk
|
||||
|
||||
LIB := $(obj)libgeneric.o
|
||||
|
||||
SOBJS += switch2ns.o
|
||||
|
||||
COBJS += exec.o
|
||||
COBJS += malloc.o
|
||||
COBJS += check.o
|
||||
COBJS += nand_misc.o
|
||||
COBJS += mmu.o
|
||||
COBJS += common.o
|
||||
|
||||
SOBJS := $(SOBJS)
|
||||
COBJS := $(COBJS)
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
|
||||
|
||||
all: $(LIB)
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
71
sunxi_spl/sbrom/libs/check.c
Normal file
71
sunxi_spl/sbrom/libs/check.c
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* Boot rom
|
||||
* Seucre Boot
|
||||
*
|
||||
* Copyright(C), 2006-2013, AllWinners Microelectronic Co., Ltd.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File Name : Base.h
|
||||
*
|
||||
* Author : glhuang
|
||||
*
|
||||
* Version : 0.0.1
|
||||
*
|
||||
* Date : 2013.09.05
|
||||
*
|
||||
* Description :
|
||||
*
|
||||
* Others : None at present.
|
||||
*
|
||||
*
|
||||
* History :
|
||||
*
|
||||
* <Author> <time> <version> <description>
|
||||
*
|
||||
* glhuang 2013.09.05 0.0.1 build the file
|
||||
*
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
#include "common.h"
|
||||
#include "private_toc.h"
|
||||
|
||||
extern sbrom_toc0_config_t *toc0_config;
|
||||
|
||||
int verify_addsum( void *mem_base, __u32 size )
|
||||
{
|
||||
__u32 *buf;
|
||||
__u32 count;
|
||||
__u32 src_sum;
|
||||
__u32 sum;
|
||||
sbrom_toc1_head_info_t *bfh;
|
||||
|
||||
bfh = (sbrom_toc1_head_info_t *)mem_base;
|
||||
|
||||
/* 生成校验和 */
|
||||
src_sum = bfh->add_sum; // 从Boot_file_head中的“check_sum”字段取出校验和
|
||||
bfh->add_sum = STAMP_VALUE; // 将STAMP_VALUE写入Boot_file_head中的“check_sum”字段
|
||||
|
||||
count = size >> 2; // 以 字(4bytes)为单位计数
|
||||
sum = 0;
|
||||
buf = (__u32 *)mem_base;
|
||||
do
|
||||
{
|
||||
sum += *buf++; // 依次累加,求得校验和
|
||||
sum += *buf++; // 依次累加,求得校验和
|
||||
sum += *buf++; // 依次累加,求得校验和
|
||||
sum += *buf++; // 依次累加,求得校验和
|
||||
}while( ( count -= 4 ) > (4-1) );
|
||||
|
||||
while( count-- > 0 )
|
||||
sum += *buf++;
|
||||
|
||||
bfh->add_sum = src_sum; // 恢复Boot_file_head中的“check_sum”字段的值
|
||||
|
||||
if( sum == src_sum )
|
||||
return 0; // 校验成功
|
||||
else
|
||||
return -1; // 校验失败
|
||||
}
|
||||
|
||||
|
||||
66
sunxi_spl/sbrom/libs/common.c
Executable file
66
sunxi_spl/sbrom/libs/common.c
Executable file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* (C) Copyright 2007-2013
|
||||
* Allwinner Technology Co., Ltd. <www.allwinnertech.com>
|
||||
* Young <guoyingyang@allwinnertech.com>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "asm/armv7.h"
|
||||
#include <private_toc.h>
|
||||
#include <asm/arch/uart.h>
|
||||
#include <boot0_helper.h>
|
||||
|
||||
extern sbrom_toc0_config_t *toc0_config ;
|
||||
extern int debug_enable;
|
||||
/*
|
||||
************************************************************************************************************
|
||||
*
|
||||
* function
|
||||
*
|
||||
* name :set_debugmode_flag
|
||||
*
|
||||
* parmeters :void
|
||||
*
|
||||
* return :
|
||||
*
|
||||
* note :if BT0_head.prvt_head.debug_mode_off = 1,do not print any message to uart ;
|
||||
* if you press 'd' button,turn on printf
|
||||
*
|
||||
************************************************************************************************************
|
||||
*/
|
||||
|
||||
int set_debugmode_flag(void)
|
||||
{
|
||||
char c = get_uart_input();
|
||||
if(c == 'd')
|
||||
{
|
||||
debug_enable = LOG_LEVEL_INFO;
|
||||
return c;
|
||||
}
|
||||
|
||||
if(toc0_config->debug_mode)
|
||||
debug_enable = toc0_config->debug_mode;
|
||||
else
|
||||
debug_enable = 0;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
174
sunxi_spl/sbrom/libs/exec.c
Executable file
174
sunxi_spl/sbrom/libs/exec.c
Executable file
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
**********************************************************************************************************************
|
||||
*
|
||||
* the Embedded Secure Bootloader System
|
||||
*
|
||||
*
|
||||
* Copyright(C), 2006-2014, Allwinnertech Co., Ltd.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File :
|
||||
*
|
||||
* By :
|
||||
*
|
||||
* Version : V2.00
|
||||
*
|
||||
* Date :
|
||||
*
|
||||
* Descript:
|
||||
**********************************************************************************************************************
|
||||
*/
|
||||
#include "common.h"
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/spc.h>
|
||||
#include <asm/arch/smc.h>
|
||||
#include <asm/arch/mmc_boot0.h>
|
||||
#include <private_toc.h>
|
||||
#include <private_uboot.h>
|
||||
#include "asm/arch/platform.h"
|
||||
|
||||
struct spare_optee_head {
|
||||
unsigned int jump_instruction;
|
||||
unsigned char magic[8];
|
||||
unsigned int dram_size;
|
||||
unsigned int drm_size;
|
||||
unsigned int length;
|
||||
unsigned int optee_length;
|
||||
unsigned char version[8];
|
||||
unsigned char platform[8];
|
||||
int reserved[1];
|
||||
};
|
||||
|
||||
|
||||
extern sbrom_toc0_config_t *toc0_config;
|
||||
|
||||
void secure_switch_unsecure(u32 run_addr, u32 para_addr);
|
||||
void secure_switch_other(u32 run_addr, u32 para_addr);
|
||||
static void boot0_jmp_monitor(unsigned int addr);
|
||||
void boot0_jmp_boot1(unsigned int addr);
|
||||
|
||||
unsigned int go_exec (u32 monitor_entry, u32 uboot_entry, int optee_entry, unsigned int dram_size)
|
||||
{
|
||||
struct spare_boot_head_t *bfh = (struct spare_boot_head_t *)uboot_entry;
|
||||
toc0_private_head_t *toc0 = (toc0_private_head_t *)CONFIG_SBROMSW_BASE;
|
||||
int boot_type = toc0->platform[0]&0xf;
|
||||
int card_work_mode = toc0_config->card_work_mode;
|
||||
|
||||
if(!boot_type)
|
||||
{
|
||||
boot_type = 1;
|
||||
}
|
||||
else if(boot_type == 1)
|
||||
{
|
||||
boot_type = 0;
|
||||
}else if(boot_type == 2){
|
||||
//char storage_data[384]; // 0-159,存储nand信息;160-255,存放卡信息^M
|
||||
set_mmc_para(2,(void *)(toc0_config->storage_data+160));
|
||||
}
|
||||
|
||||
if(card_work_mode)
|
||||
{
|
||||
bfh->boot_data.work_mode = card_work_mode;
|
||||
pr_msg("card_work_mode=%d\n", card_work_mode);
|
||||
}
|
||||
|
||||
sunxi_smc_config(dram_size, toc0_config->secure_dram_mbytes);
|
||||
sunxi_drm_config(PLAT_SDRAM_BASE + (dram_size<<20), toc0_config->secure_dram_mbytes<<20);
|
||||
|
||||
pr_msg("storage_type=%d\n", boot_type);
|
||||
bfh->boot_data.storage_type = boot_type;
|
||||
|
||||
#if defined(CONFIG_ARCH_SUN8IW6P1)
|
||||
bfh->boot_data.dram_scan_size = dram_size - toc0_config->secure_dram_mbytes - 16 - 4;
|
||||
//16: standby for the size of secure os, which is placed in dts
|
||||
//4: the share memory size, which is placed the top dram before drm memory
|
||||
#elif defined(CONFIG_ARCH_SUN50IW6P1) || defined(CONFIG_ARCH_SUN50IW3P1)
|
||||
bfh->boot_data.dram_scan_size = dram_size;
|
||||
#else
|
||||
bfh->boot_data.dram_scan_size = dram_size - toc0_config->secure_dram_mbytes;
|
||||
#endif
|
||||
pr_notice("dram = %d M \n", bfh->boot_data.dram_scan_size);
|
||||
|
||||
bfh->boot_data.secureos_exist = optee_entry ? 1:0;
|
||||
bfh->boot_data.monitor_exist = \
|
||||
monitor_entry ? SUNXI_SECURE_MODE_USE_SEC_MONITOR:0;
|
||||
|
||||
memcpy(bfh->boot_data.dram_para, toc0_config->dram_para, 32 * 4);
|
||||
|
||||
pr_force("run out of boot0\n");
|
||||
if (monitor_entry) {
|
||||
struct spare_optee_head *head = (struct spare_optee_head *)optee_entry;
|
||||
head->dram_size= dram_size;
|
||||
head->drm_size= toc0_config->secure_dram_mbytes;
|
||||
boot0_jmp_monitor(monitor_entry);
|
||||
}
|
||||
else if (optee_entry) {
|
||||
struct spare_optee_head *head = (struct spare_optee_head *)optee_entry;
|
||||
|
||||
head->dram_size= dram_size;
|
||||
head->drm_size= toc0_config->secure_dram_mbytes;
|
||||
|
||||
asm volatile ("mov lr, %0" :: "r" (uboot_entry) : "memory");
|
||||
asm volatile ("bx %0" :: "r" (optee_entry) : "memory");
|
||||
} else {
|
||||
boot0_jmp_boot1(uboot_entry);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void boot0_jmp_monitor(unsigned int addr)
|
||||
{
|
||||
// jmp to AA64
|
||||
//set the cpu boot entry addr:
|
||||
writel(addr,RVBARADDR0_L);
|
||||
writel(0,RVBARADDR0_H);
|
||||
|
||||
//*(volatile unsigned int*)0x40080000 =0x14000000; //
|
||||
//note: warm reset to 0x40080000 when run on fpga,
|
||||
//*(volatile unsigned int*)0x40080000 =0xd61f0060; //hard code: br x3
|
||||
//asm volatile("ldr r3, =(0x7e000000)"); //set r3
|
||||
|
||||
//asm volatile("ldr r0, =(0x7f000200)");
|
||||
//asm volatile("ldr r1, =(0x12345678)");
|
||||
|
||||
//set cpu to AA64 execution state when the cpu boots into after a warm reset
|
||||
asm volatile("MRC p15,0,r2,c12,c0,2");
|
||||
asm volatile("ORR r2,r2,#(0x3<<0)");
|
||||
asm volatile("DSB");
|
||||
asm volatile("MCR p15,0,r2,c12,c0,2");
|
||||
asm volatile("ISB");
|
||||
__LOOP:
|
||||
asm volatile("WFI");
|
||||
goto __LOOP;
|
||||
|
||||
}
|
||||
|
||||
void boot0_jmp_other(unsigned int addr)
|
||||
{
|
||||
asm volatile("mov r2, #0");
|
||||
asm volatile("mcr p15, 0, r2, c7, c5, 6");
|
||||
asm volatile("bx r0");
|
||||
}
|
||||
|
||||
void boot0_jmp_boot1(unsigned int addr)
|
||||
{
|
||||
boot0_jmp_other(addr);
|
||||
}
|
||||
|
||||
int sunxi_deassert_arisc(void)
|
||||
{
|
||||
pr_msg("set arisc reset to de-assert state\n");
|
||||
{
|
||||
volatile unsigned long value;
|
||||
value = readl(SUNXI_RCPUCFG_BASE + 0x0);
|
||||
value &= ~1;
|
||||
writel(value, SUNXI_RCPUCFG_BASE + 0x0);
|
||||
value = readl(SUNXI_RCPUCFG_BASE + 0x0);
|
||||
value |= 1;
|
||||
writel(value, SUNXI_RCPUCFG_BASE + 0x0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
222
sunxi_spl/sbrom/libs/malloc.c
Normal file
222
sunxi_spl/sbrom/libs/malloc.c
Normal file
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
**********************************************************************************************************************
|
||||
* eGon
|
||||
* the Embedded GO-ON Bootloader System
|
||||
* eGON memory sub-system
|
||||
*
|
||||
* Copyright(C), 2006-2010, SoftWinners Microelectronic Co., Ltd.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File : mem_alloc
|
||||
*
|
||||
* By : Jerry
|
||||
*
|
||||
* Version : V2.00
|
||||
*
|
||||
* Date :
|
||||
*
|
||||
* Descript:
|
||||
**********************************************************************************************************************
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
struct alloc_struct_t
|
||||
{
|
||||
__u32 address; //申请内存的地址
|
||||
__u32 size; //分配的内存大小,用户实际得到的内存大小
|
||||
__u32 o_size; //用户申请的内存大小
|
||||
struct alloc_struct_t *next;
|
||||
};
|
||||
|
||||
#define MY_BYTE_ALIGN(x) ( ( (x + 15)/16) * 16) /* alloc based on 1k byte */
|
||||
|
||||
static struct alloc_struct_t boot_heap_head, boot_heap_tail;
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CREATE HEAP
|
||||
*
|
||||
* Description: create heap.
|
||||
*
|
||||
* Aguments : pHeapHead heap start address.
|
||||
* nHeapSize heap size.
|
||||
*
|
||||
* Returns : EPDK_OK/EPDK_FAIL.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
__s32 create_heap(__u32 pHeapHead, __u32 nHeapSize)
|
||||
{
|
||||
boot_heap_head.size = boot_heap_tail.size = 0;
|
||||
boot_heap_head.address = pHeapHead;
|
||||
boot_heap_tail.address = pHeapHead + nHeapSize;
|
||||
boot_heap_head.next = &boot_heap_tail;
|
||||
boot_heap_tail.next = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* MALLOC BUFFER FROM HEAP
|
||||
*
|
||||
* Description: malloc a buffer from heap.
|
||||
*
|
||||
* Aguments : num_bytes the size of the buffer need malloc;
|
||||
*
|
||||
* Returns : the po__s32er to buffer has malloc.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
void *malloc(__u32 num_bytes)
|
||||
{
|
||||
struct alloc_struct_t *ptr, *newptr;
|
||||
__u32 actual_bytes;
|
||||
|
||||
if (!num_bytes) return 0;
|
||||
|
||||
actual_bytes = MY_BYTE_ALIGN(num_bytes); /* translate the byte count to size of long type */
|
||||
|
||||
ptr = &boot_heap_head; /* scan from the boot_heap_head of the heap */
|
||||
|
||||
while (ptr && ptr->next) /* look for enough memory for alloc */
|
||||
{
|
||||
if (ptr->next->address >= (ptr->address + ptr->size + \
|
||||
2 * sizeof(struct alloc_struct_t) + actual_bytes))
|
||||
{
|
||||
break;
|
||||
}
|
||||
/* find enough memory to alloc */
|
||||
ptr = ptr->next;
|
||||
}
|
||||
|
||||
if (!ptr->next)
|
||||
{
|
||||
return 0; /* it has reached the boot_heap_tail of the heap now */
|
||||
}
|
||||
|
||||
newptr = (struct alloc_struct_t *)(ptr->address + ptr->size);
|
||||
/* create a new node for the memory block */
|
||||
if (!newptr)
|
||||
{
|
||||
return 0; /* create the node failed, can't manage the block */
|
||||
}
|
||||
|
||||
/* set the memory block chain, insert the node to the chain */
|
||||
newptr->address = ptr->address + ptr->size + sizeof(struct alloc_struct_t);
|
||||
newptr->size = actual_bytes;
|
||||
newptr->o_size = num_bytes;
|
||||
newptr->next = ptr->next;
|
||||
ptr->next = newptr;
|
||||
|
||||
return (void *)newptr->address;
|
||||
}
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* MALLOC BUFFER FROM HEAP
|
||||
*
|
||||
* Description: malloc a buffer from heap.
|
||||
*
|
||||
* Aguments : num_bytes the size of the buffer need malloc;
|
||||
*
|
||||
* Returns : the po__s32er to buffer has malloc.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
void *realloc(void *p, __u32 num_bytes)
|
||||
{
|
||||
struct alloc_struct_t *ptr, *prev;
|
||||
void *tmp;
|
||||
__u32 actual_bytes;
|
||||
|
||||
if(!p)
|
||||
{
|
||||
return malloc(num_bytes); /* 如果传进的指针是空,则按照传进的字节数申请内存 */
|
||||
}
|
||||
if (!num_bytes)
|
||||
{
|
||||
return p; /* 如果申请追加的内存字节数是0,则直接返回当前的指针 */
|
||||
}
|
||||
|
||||
ptr = &boot_heap_head; /* look for the node which po__s32 this memory block */
|
||||
while (ptr && ptr->next)
|
||||
{
|
||||
if (ptr->next->address == (__u32)p)
|
||||
break; /* find the node which need to be release */
|
||||
ptr = ptr->next;
|
||||
}
|
||||
|
||||
//此时,ptr指向的是用户指针的前一个节点
|
||||
prev = ptr;
|
||||
ptr = ptr->next;
|
||||
|
||||
if(!ptr)
|
||||
{
|
||||
return 0; /* 如果没有找到用户传进的地址 */
|
||||
}
|
||||
//用ptr指向用户节点
|
||||
actual_bytes = MY_BYTE_ALIGN(ptr->o_size + num_bytes);
|
||||
if(actual_bytes == ptr->size)
|
||||
{
|
||||
return p;
|
||||
}
|
||||
|
||||
if (ptr->next->address >= (ptr->address + actual_bytes + \
|
||||
2 * sizeof(struct alloc_struct_t)))
|
||||
{
|
||||
ptr->size = actual_bytes;
|
||||
ptr->o_size += num_bytes;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
tmp = malloc(actual_bytes);
|
||||
if(!tmp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
memcpy(tmp, (void *)ptr->address, ptr->size);
|
||||
prev->next = ptr->next; /* delete the node which need be released from the memory block chain */
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* FREE BUFFER TO HEAP
|
||||
*
|
||||
* Description: free buffer to heap
|
||||
*
|
||||
* Aguments : p the po__s32er to the buffer which need be free.
|
||||
*
|
||||
* Returns : none
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
void free(void *p)
|
||||
{
|
||||
struct alloc_struct_t *ptr, *prev;
|
||||
|
||||
if( p == NULL )
|
||||
return;
|
||||
|
||||
ptr = &boot_heap_head; /* look for the node which po__s32 this memory block */
|
||||
while (ptr && ptr->next)
|
||||
{
|
||||
if (ptr->next->address == (__u32)p)
|
||||
break; /* find the node which need to be release */
|
||||
ptr = ptr->next;
|
||||
}
|
||||
|
||||
prev = ptr;
|
||||
ptr = ptr->next;
|
||||
|
||||
if (!ptr) return; /* the node is heap boot_heap_tail */
|
||||
|
||||
prev->next = ptr->next; /* delete the node which need be released from the memory block chain */
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
118
sunxi_spl/sbrom/libs/mmu.c
Executable file
118
sunxi_spl/sbrom/libs/mmu.c
Executable file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* (C) Copyright 2007-2013
|
||||
* Allwinner Technology Co., Ltd. <www.allwinnertech.com>
|
||||
* Jerry Wang <wangflord@allwinnertech.com>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "asm/armv7.h"
|
||||
#include "asm/arch/archdef.h"
|
||||
#include "asm/arch/timer.h"
|
||||
/*
|
||||
************************************************************************************************************
|
||||
*
|
||||
* function
|
||||
*
|
||||
* name :
|
||||
*
|
||||
* parmeters :
|
||||
*
|
||||
* return :
|
||||
*
|
||||
* note :
|
||||
*
|
||||
*
|
||||
************************************************************************************************************
|
||||
*/
|
||||
void mmu_setup(void)
|
||||
{
|
||||
u32 mmu_base;
|
||||
u32 *page_table = (u32 *)TOC0_MMU_BASE_ADDRESS;
|
||||
int i;
|
||||
u32 reg;
|
||||
|
||||
page_table[0] = (3 << 10) | (15 << 5) | (1 << 3) | (0 << 2) | 0x2;
|
||||
/* the front 1G of memory(treated as 4G for all) is set up as none cacheable */
|
||||
for (i = 1; i < (CONFIG_SYS_SDRAM_BASE>>20); i++)
|
||||
page_table[i] = (i << 20) | (3 << 10) | (15 << 5) | (0 << 3) | 0x2;
|
||||
/* Set up as write through and buffered(not write back) for other 3GB, rw for everyone */
|
||||
for (i = (CONFIG_SYS_SDRAM_BASE>>20); i < 4096; i++)
|
||||
page_table[i] = (i << 20) | (3 << 10) | (15 << 5) | (1 << 3) | (0 << 2) | 0x2;
|
||||
/* flush tlb */
|
||||
asm volatile("mcr p15, 0, %0, c8, c7, 0" : : "r" (0));
|
||||
/* Copy the page table address to cp15 */
|
||||
mmu_base = TOC0_MMU_BASE_ADDRESS;
|
||||
mmu_base |= (1 << 0) | (1 << 1) | (2 << 3);
|
||||
asm volatile("mcr p15, 0, %0, c2, c0, 0"
|
||||
: : "r" (mmu_base) : "memory");
|
||||
asm volatile("mcr p15, 0, %0, c2, c0, 1"
|
||||
: : "r" (mmu_base) : "memory");
|
||||
/* Set the access control to all-supervisor */
|
||||
asm volatile("mcr p15, 0, %0, c3, c0, 0"
|
||||
: : "r" (0x55555555)); //modified, origin value is (~0)
|
||||
asm volatile("isb");
|
||||
/* and enable the mmu */
|
||||
asm volatile("mrc p15, 0, %0, c1, c0, 0 @ get CR" : "=r" (reg) : : "cc");
|
||||
|
||||
__usdelay(100);
|
||||
reg |= (1 | (1<<12)); //enable mmu & icache
|
||||
asm volatile("mcr p15, 0, %0, c1, c0, 0 @ set CR" : : "r" (reg) : "cc");
|
||||
asm volatile("isb");
|
||||
|
||||
|
||||
}
|
||||
/*
|
||||
************************************************************************************************************
|
||||
*
|
||||
* function
|
||||
*
|
||||
* name :
|
||||
*
|
||||
* parmeters :
|
||||
*
|
||||
* return :
|
||||
*
|
||||
* note :
|
||||
*
|
||||
*
|
||||
************************************************************************************************************
|
||||
*/
|
||||
void mmu_turn_off( void )
|
||||
{
|
||||
uint reg;
|
||||
/* and disable the mmu */
|
||||
asm volatile("mrc p15, 0, %0, c1, c0, 0 @ get CR" : "=r" (reg) : : "cc");
|
||||
__usdelay(100);
|
||||
reg &= ~((7<<0)|(1<<12)); //disable mmu & icache
|
||||
asm volatile("mcr p15, 0, %0, c1, c0, 0 @ set CR" : : "r" (reg) : "cc");
|
||||
asm volatile("isb");
|
||||
/*
|
||||
* Invalidate all instruction caches to PoU.
|
||||
* Also flushes branch target cache.
|
||||
*/
|
||||
asm volatile ("mcr p15, 0, %0, c7, c5, 0" : : "r" (0));
|
||||
/* Invalidate entire branch predictor array */
|
||||
asm volatile ("mcr p15, 0, %0, c7, c5, 6" : : "r" (0));
|
||||
/* Full system DSB - make sure that the invalidation is complete */
|
||||
CP15DSB;
|
||||
/* ISB - make sure the instruction stream sees it */
|
||||
CP15ISB;
|
||||
}
|
||||
97
sunxi_spl/sbrom/libs/nand_misc.c
Normal file
97
sunxi_spl/sbrom/libs/nand_misc.c
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
**********************************************************************************************************************
|
||||
*
|
||||
* the Embedded Secure Bootloader System
|
||||
*
|
||||
*
|
||||
* Copyright(C), 2006-2014, Allwinnertech Co., Ltd.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File :
|
||||
*
|
||||
* By :
|
||||
*
|
||||
* Version : V2.00
|
||||
*
|
||||
* Date :
|
||||
*
|
||||
* Descript:
|
||||
**********************************************************************************************************************
|
||||
*/
|
||||
#include "common.h"
|
||||
#include "malloc.h"
|
||||
#include <private_toc.h>
|
||||
|
||||
extern sbrom_toc0_config_t *toc0_config;
|
||||
/*
|
||||
************************************************************************************************************
|
||||
*
|
||||
* function
|
||||
*
|
||||
* name :
|
||||
*
|
||||
* parmeters :
|
||||
*
|
||||
* return :
|
||||
*
|
||||
* note :
|
||||
*
|
||||
*
|
||||
************************************************************************************************************
|
||||
*/
|
||||
int BOOT_NandGetPara(void *param, uint size)
|
||||
{
|
||||
memcpy( (void *)param, toc0_config->storage_data, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
************************************************************************************************************
|
||||
*
|
||||
* function
|
||||
*
|
||||
* name :
|
||||
*
|
||||
* parmeters :
|
||||
*
|
||||
* return :
|
||||
*
|
||||
* note :
|
||||
*
|
||||
*
|
||||
************************************************************************************************************
|
||||
*/
|
||||
__u8 *get_page_buf( void )
|
||||
{
|
||||
|
||||
return (__u8 *)malloc(16 * 1024);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*函数名称: g_mod
|
||||
*函数原型:uint32 g_mod( __u32 dividend, __u32 divisor, __u32 *quot_p )
|
||||
*函数功能: 从nand flash的某一块中找到一个完好备份将其载入到RAM中。如果成功,返
|
||||
* 回OK;否则,返回ERROR。
|
||||
*入口参数: dividend 输入。被除数
|
||||
* divisor 输入。除数
|
||||
* quot_p 输出。商
|
||||
*返 回 值: 余数
|
||||
*******************************************************************************/
|
||||
__u32 g_mod( __u32 dividend, __u32 divisor, __u32 *quot_p )
|
||||
{
|
||||
if( divisor == 0 )
|
||||
{
|
||||
*quot_p = 0;
|
||||
return 0;
|
||||
}
|
||||
if( divisor == 1 )
|
||||
{
|
||||
*quot_p = dividend;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for( *quot_p = 0; dividend >= divisor; ++(*quot_p) )
|
||||
dividend -= divisor;
|
||||
return dividend;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user