From fde374a243d1c34397e39bb12836cac36a528dd1 Mon Sep 17 00:00:00 2001 From: Sandor Yu Date: Mon, 9 Apr 2018 11:29:47 +0800 Subject: [PATCH] MLK-17997: video: imx: hdp: Add HDMI RX firmware loading Add iMX8QM HDMI RX firmware loading. Signed-off-by: Sandor Yu (cherry picked from commit 969d93660e1b34765627ff9f6f8dcab08dcd1250) (cherry picked from commit 43bc31a2700f4078ffc5f55ff3fea0ed554f4506) --- drivers/video/imx/Makefile | 2 +- drivers/video/imx/hdp/API_General.c | 21 ++++++++ drivers/video/imx/hdp/API_General.h | 3 ++ drivers/video/imx/hdp/externs.h | 4 ++ drivers/video/imx/hdp/test_base_sw.c | 51 ++++++++++++++++++++ drivers/video/imx/hdprx_load.c | 72 ++++++++++++++++++++++++++++ include/configs/imx8qm_mek.h | 6 +++ 7 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 drivers/video/imx/hdprx_load.c diff --git a/drivers/video/imx/Makefile b/drivers/video/imx/Makefile index 5c243af8fd..fe72d61164 100644 --- a/drivers/video/imx/Makefile +++ b/drivers/video/imx/Makefile @@ -5,5 +5,5 @@ # UBOOTINCLUDE += -I$(srctree)/drivers/video/imx/hdp -obj-$(CONFIG_VIDEO_IMX_HDP_LOAD) += hdp_load.o hdp/ +obj-$(CONFIG_VIDEO_IMX_HDP_LOAD) += hdp_load.o hdprx_load.o hdp/ obj-$(CONFIG_VIDEO_IMX8_HDMI) += hdp.o imx8_hdmi.o hdp/ diff --git a/drivers/video/imx/hdp/API_General.c b/drivers/video/imx/hdp/API_General.c index fb606558c2..f52e994b24 100644 --- a/drivers/video/imx/hdp/API_General.c +++ b/drivers/video/imx/hdp/API_General.c @@ -65,6 +65,27 @@ void cdn_api_init(void) memset(&state, 0, sizeof(state_struct)); } +CDN_API_STATUS hdp_rx_loadfirmware(unsigned char *imem, int imemsize, + unsigned char *dmem, int dmemsize) +{ + int i; + for (i = 0; i < imemsize; i += 4) + if (hdp_rx_apb_write(ADDR_IMEM + i, + (unsigned int)imem[i] << 0 | + (unsigned int)imem[i + 1] << 8 | + (unsigned int)imem[i + 2] << 16 | + (unsigned int)imem[i + 3] << 24)) + return CDN_ERR; + for (i = 0; i < dmemsize; i += 4) + if (hdp_rx_apb_write(ADDR_DMEM + i, + (unsigned int)dmem[i] << 0 | + (unsigned int)dmem[i + 1] << 8 | + (unsigned int)dmem[i + 2] << 16 | + (unsigned int)dmem[i + 3] << 24)) + return CDN_ERR; + return CDN_OK; +} + CDN_API_STATUS cdn_api_loadfirmware(unsigned char *imem, int imemsize, unsigned char *dmem, int dmemsize) { diff --git a/drivers/video/imx/hdp/API_General.h b/drivers/video/imx/hdp/API_General.h index e631919f57..42e4c5c0a7 100644 --- a/drivers/video/imx/hdp/API_General.h +++ b/drivers/video/imx/hdp/API_General.h @@ -298,5 +298,8 @@ CDN_API_STATUS cdn_api_general_write_field_blocking(unsigned int addr, unsigned int val); CDN_API_STATUS cdn_api_general_phy_test_access(uint8_t *resp); CDN_API_STATUS cdn_api_general_phy_test_access_blocking(uint8_t *resp); +CDN_API_STATUS hdp_rx_loadfirmware(unsigned char *imem, + int imemsize, + unsigned char *dmem, int dmemsize); #endif diff --git a/drivers/video/imx/hdp/externs.h b/drivers/video/imx/hdp/externs.h index 5be1192b5b..31ed64693e 100644 --- a/drivers/video/imx/hdp/externs.h +++ b/drivers/video/imx/hdp/externs.h @@ -77,5 +77,9 @@ uint32_t cdn_apb_read(uint32_t addr, uint32_t *value); uint32_t cdn_sapb_read(uint32_t addr, uint32_t *value); uint32_t cdn_apb_write(uint32_t addr, uint32_t value); uint32_t cdn_sapb_write(uint32_t addr, uint32_t value); +uint32_t hdp_rx_apb_read(uint32_t addr, uint32_t *value); +uint32_t hdp_rx_sapb_read(uint32_t addr, uint32_t *value); +uint32_t hdp_rx_apb_write(uint32_t addr, uint32_t value); +uint32_t hdp_rx_sapb_write(uint32_t addr, uint32_t value); #endif diff --git a/drivers/video/imx/hdp/test_base_sw.c b/drivers/video/imx/hdp/test_base_sw.c index f828c88494..a276c829e8 100644 --- a/drivers/video/imx/hdp/test_base_sw.c +++ b/drivers/video/imx/hdp/test_base_sw.c @@ -64,6 +64,11 @@ #define HDMI_SEC_BASE 0x56269000 #define HDMI_OFFSET_ADDR 0x56261008 #define HDMI_SEC_OFFSET_ADDR 0x5626100c + +#define HDMI_RX_BASE 0x58268000 +#define HDMI_RX_SEC_BASE 0x58269000 +#define HDMI_RX_OFFSET_ADDR 0x58261004 +#define HDMI_RX_SEC_OFFSET_ADDR 0x58261008 #endif #endif @@ -168,6 +173,52 @@ int cdn_sapb_write(unsigned int addr, unsigned int value) return 0; } +int hdp_rx_apb_read(unsigned int addr, unsigned int *value) +{ + unsigned int temp; + uint64_t tmp_addr = (addr & 0xfff) + HDMI_RX_BASE; + + __raw_writel(addr >> 12, HDMI_RX_OFFSET_ADDR); + + temp = __raw_readl(tmp_addr); + + *value = temp; + return 0; +} + +int hdp_rx_apb_write(unsigned int addr, unsigned int value) +{ + uint64_t tmp_addr = (addr & 0xfff) + HDMI_RX_BASE; + + __raw_writel(addr >> 12, HDMI_RX_OFFSET_ADDR); + + __raw_writel(value, tmp_addr); + + return 0; +} + +int hdp_rx_sapb_read(unsigned int addr, unsigned int *value) +{ + unsigned int temp; + uint64_t tmp_addr = (addr & 0xfff) + HDMI_RX_SEC_BASE; + + __raw_writel(addr >> 12, HDMI_RX_SEC_OFFSET_ADDR); + + temp = __raw_readl(tmp_addr); + *value = temp; + return 0; +} + +int hdp_rx_sapb_write(unsigned int addr, unsigned int value) +{ + uint64_t tmp_addr = (addr & 0xfff) + HDMI_RX_SEC_BASE; + + __raw_writel(addr >> 12, HDMI_RX_SEC_OFFSET_ADDR); + __raw_writel(value, tmp_addr); + + return 0; +} + void cdn_sleep(uint32_t ms) { mdelay(ms); diff --git a/drivers/video/imx/hdprx_load.c b/drivers/video/imx/hdprx_load.c new file mode 100644 index 0000000000..80b4c1774d --- /dev/null +++ b/drivers/video/imx/hdprx_load.c @@ -0,0 +1,72 @@ +/* + * Copyright 2018 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include + +#include "API_General.h" +#include "scfw_utils.h" + +DECLARE_GLOBAL_DATA_PTR; + +#define ON 1 +#define OFF 0 + +static void hdmi_rx_set_power(int onoff) +{ + SC_PM_SET_RESOURCE_POWER_MODE(-1, SC_R_ISI_CH0, onoff); + SC_PM_SET_RESOURCE_POWER_MODE(-1, SC_R_HDMI_RX, onoff); + SC_PM_SET_RESOURCE_POWER_MODE(-1, SC_R_HDMI_RX_BYPASS, onoff); +} + +int do_hdprx(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + if (argc < 2) + return 0; + + if (strncmp(argv[1], "tracescfw", 9) == 0) { + g_debug_scfw = 1; + printf("Enabled SCFW API tracing\n"); + } else if (strncmp(argv[1], "load", 4) == 0) { + unsigned long address = 0; + unsigned long offset = 0x2000; + const int iram_size = 0x10000; + const int dram_size = 0x8000; + + if (argc > 2) { + address = simple_strtoul(argv[2], NULL, 0); + if (argc > 3) + offset = simple_strtoul(argv[3], NULL, 0); + } else + printf("Missing address\n"); + + printf("Loading hdp rx firmware from 0x%016lx offset 0x%016lx\n", + address, offset); + hdmi_rx_set_power(SC_PM_PW_MODE_ON); + hdp_rx_loadfirmware((unsigned char *)(address + offset), + iram_size, + (unsigned char *)(address + offset + + iram_size), + dram_size); + printf("Loading hdp rx firmware Complete\n"); + /* do not turn off hdmi power or firmware load will be lost */ + } else { + printf("test error argc %d\n", argc); + } + + return 0; +} +/***************************************************/ + +U_BOOT_CMD( + hdprx, CONFIG_SYS_MAXARGS, 1, do_hdprx, + "load hdmi rx firmware ", + "[] ...\n" + "hdpload [address] []\n" + " address - address where the binary image starts\n" + " - IRAM offset in the binary image (8192 default)\n" + "tracescfw - Trace SCFW API calls for video commands\n" + ); diff --git a/include/configs/imx8qm_mek.h b/include/configs/imx8qm_mek.h index 04176beb67..610f507b1a 100644 --- a/include/configs/imx8qm_mek.h +++ b/include/configs/imx8qm_mek.h @@ -111,6 +111,7 @@ "${get_cmd} ${loadaddr} xen;" \ "${get_cmd} ${fdt_addr} fsl-imx8qm-mek-dom0.dtb;" \ "if ${get_cmd} ${hdp_addr} ${hdp_file}; then; hdp load ${hdp_addr}; fi;" \ + "if ${get_cmd} ${hdprx_addr} ${hdprx_file}; then; hdprx load ${hdprx_addr}; fi;" \ "${get_cmd} ${xenlinux_addr} ${image};" \ "fdt addr ${fdt_addr};" \ "fdt resize 256;" \ @@ -173,10 +174,14 @@ "loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}\0" \ "loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}\0" \ "hdp_addr=0x84000000\0" \ + "hdprx_addr=0x84800000\0" \ "hdp_file=hdmitxfw.bin\0" \ + "hdprx_file=hdmirxfw.bin\0" \ "loadhdp=fatload mmc ${mmcdev}:${mmcpart} ${hdp_addr} ${hdp_file}\0" \ + "loadhdprx=fatload mmc ${mmcdev}:${mmcpart} ${hdprx_addr} ${hdprx_file}\0" \ "mmcboot=echo Booting from mmc ...; " \ "if run loadhdp; then; hdp load ${hdp_addr}; fi;" \ + "if run loadhdprx; then; hdprx load ${hdprx_addr}; fi;" \ "run mmcargs; " \ "if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \ "if run loadfdt; then " \ @@ -198,6 +203,7 @@ "setenv get_cmd tftp; " \ "fi; " \ "if ${get_cmd} ${hdp_addr} ${hdp_file}; then; hdp load ${hdp_addr}; fi;" \ + "if ${get_cmd} ${hdprx_addr} ${hdprx_file}; then; hdprx load ${hdprx_addr}; fi;" \ "${get_cmd} ${loadaddr} ${image}; " \ "if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \ "if ${get_cmd} ${fdt_addr} ${fdt_file}; then " \ -- 2.17.1