diff --git a/arch/arm/cpu/armv8/gxb/firmware/scp_task/hdmi_cec_arc.c b/arch/arm/cpu/armv8/gxb/firmware/scp_task/hdmi_cec_arc.c index 969777f720b..7d397cac8b3 100644 --- a/arch/arm/cpu/armv8/gxb/firmware/scp_task/hdmi_cec_arc.c +++ b/arch/arm/cpu/armv8/gxb/firmware/scp_task/hdmi_cec_arc.c @@ -41,7 +41,7 @@ static void *cec_memcpy(void *memto, const void *memfrom, unsigned int size) } static void waiting_aocec_free(void) { - unsigned int cnt = 0; + unsigned long cnt = 0; while (readl(P_AO_CEC_RW_REG) & (1<<23)) { if (8192 <= cnt++) @@ -146,8 +146,6 @@ void remote_cec_hw_reset(void) static int cec_triggle_tx(unsigned char *msg, unsigned char len) { unsigned int i, cnt = 0; - cec_dbg_print("cec_triggle_tx len:0x", len); - cec_dbg_prints("\n"); cec_dbg_prints(" T:"); for (i = 0; i < len; i++) { @@ -168,6 +166,7 @@ static int cec_triggle_tx(unsigned char *msg, unsigned char len) cec_dbg_prints("\n"); } + _udelay(150); return 0; } @@ -180,7 +179,7 @@ static int cec_triggle_tx(unsigned char *msg, unsigned char len) #define DEVICE_PURE_CEC_SWITCH 6 #define DEVICE_VIDEO_PROCESSOR 7 -static unsigned char log_addr_to_devtype(unsigned int addr) +static unsigned char log_addr_to_devtype(unsigned char addr) { static unsigned char addr_map[] = { DEVICE_TV, @@ -211,7 +210,7 @@ static void cec_report_physical_address(void) msg[0] = ((cec_msg.log_addr & 0xf) << 4) | CEC_BROADCAST_ADDR; msg[1] = CEC_OC_REPORT_PHYSICAL_ADDRESS; msg[2] = (cec_msg.phy_addr >> 8) & 0xff; - msg[3] = cec_msg.phy_addr & 0xff; + msg[3] = (cec_msg.phy_addr >> 0) & 0xff; msg[4] = log_addr_to_devtype(cec_msg.log_addr); cec_triggle_tx(msg, 5); @@ -245,18 +244,44 @@ static void cec_feature_abort(unsigned char reason, unsigned char initiator) cec_triggle_tx(msg, 4); } -static void cec_set_stream_path(void) +static void cec_menu_status(unsigned char menu_status, unsigned char initiator) +{ + unsigned char msg[3]; + cec_dbg_print("cec_menu_status menu_status:0x", menu_status); + cec_dbg_printx(", initiator:0x", initiator, 4); + cec_dbg_prints("\n"); + + msg[0] = ((cec_msg.log_addr & 0xf) << 4) | (initiator & 0xf); + msg[1] = CEC_OC_MENU_STATUS; + msg[2] = menu_status; + + cec_triggle_tx(msg, 3); +} + +static void cec_set_stream_path(unsigned char initiator) { - unsigned char phy_addr_ab = (cec_msg.phy_addr >> 8) & 0xff; - unsigned char phy_addr_cd = cec_msg.phy_addr & 0xff; - cec_dbg_prints("cec_set_stream_path\n"); - - if ((hdmi_cec_func_config >> AUTO_POWER_ON_MASK) & 0x1) { - if ((hdmi_cec_func_config >> STREAMPATH_POWER_ON_MASK) & 0x1) { - if ((phy_addr_ab == cec_msg.msg[2]) && - (phy_addr_cd == cec_msg.msg[3])) { - cec_msg.cec_power = 0x1; - } + unsigned int phy_addr = (cec_msg.msg[2] << 8) | cec_msg.msg[3]; + cec_dbg_printx("cec_set_stream_path initiator:0x", initiator, 4); + cec_dbg_printx(", phy_addr:0x", phy_addr, 16); + cec_dbg_prints("\n"); + + if ((hdmi_cec_func_config >> STREAMPATH_POWER_ON_MASK) & 0x1) { + if (cec_msg.phy_addr == phy_addr && initiator == CEC_TV_ADDR) { + cec_msg.cec_power = 0x1; + } + } +} + +static void cec_routing_change(unsigned char initiator) +{ + unsigned int phy_addr = (cec_msg.msg[4] << 8) | cec_msg.msg[5]; + cec_dbg_printx("cec_routing_change initiator:0x", initiator, 4); + cec_dbg_printx(", phy_addr:0x", phy_addr, 16); + cec_dbg_prints("\n"); + + if ((hdmi_cec_func_config >> STREAMPATH_POWER_ON_MASK) & 0x1) { + if (cec_msg.phy_addr == phy_addr && initiator == CEC_TV_ADDR) { + cec_msg.cec_power = 0x1; } } } @@ -266,10 +291,14 @@ static void cec_user_control_pressed(void) cec_dbg_print("cec_user_control_pressed operation:0x", cec_msg.msg[2]); cec_dbg_prints("\n"); - if ((hdmi_cec_func_config >> AUTO_POWER_ON_MASK) & 0x1) { + if ((hdmi_cec_func_config >> ONE_TOUCH_STANDBY_MASK) & 0x1) { if ((0x40 == cec_msg.msg[2]) || // Power (0x6b == cec_msg.msg[2]) || // Power Toggle Function (0x6d == cec_msg.msg[2]) || // Power On Function + (0x0a == cec_msg.msg[2]) || // Setup Menu + (0x0b == cec_msg.msg[2]) || // Contents Menu + (0x10 == cec_msg.msg[2]) || // Media Top Menu + (0x11 == cec_msg.msg[2]) || // Media Context-sensitive Menu (0x09 == cec_msg.msg[2])) { // Root Menu cec_msg.cec_power = 0x1; } @@ -290,20 +319,6 @@ static void cec_device_vendor_id(void) cec_triggle_tx(msg, 5); } -static void cec_menu_status(unsigned char menu_status, unsigned char initiator) -{ - unsigned char msg[3]; - cec_dbg_print("cec_menu_status menu_status:0x", menu_status); - cec_dbg_printx(", initiator:0x", initiator, 4); - cec_dbg_prints("\n"); - - msg[0] = ((cec_msg.log_addr & 0xf) << 4) | (initiator & 0xf); - msg[1] = CEC_OC_MENU_STATUS; - msg[2] = menu_status; - - cec_triggle_tx(msg, 3); -} - static void cec_deck_status(unsigned char initiator) { unsigned char msg[3]; @@ -349,7 +364,7 @@ static unsigned int cec_handle_message(void) unsigned char initiator = (cec_msg.msg[0] >> 4) & 0xf; unsigned char destination = cec_msg.msg[0] & 0xf; unsigned char opcode = (cec_msg.msg_len > 1) ? cec_msg.msg[1] : CEC_OC_POLLING_MESSAGE; - unsigned char directly_addressed = (destination != 0xf && destination == cec_msg.log_addr); + unsigned char directly_addressed = (destination != CEC_BROADCAST_ADDR && destination == cec_msg.log_addr); cec_dbg_printx("cec_handle_message initiator:0x", initiator, 4); cec_dbg_printx(", destination:0x", destination, 4); @@ -380,7 +395,10 @@ static unsigned int cec_handle_message(void) cec_set_osd_name(initiator); break; case CEC_OC_SET_STREAM_PATH: - cec_set_stream_path(); + cec_set_stream_path(initiator); + break; + case CEC_OC_ROUTING_CHANGE: + cec_routing_change(initiator); break; case CEC_OC_GIVE_DEVICE_POWER_STATUS: if (directly_addressed) @@ -494,16 +512,7 @@ unsigned int cec_handler(void) void cec_node_init(void) { unsigned int phy_addr = readl(P_AO_DEBUG_REG1) & 0xffff; - unsigned int log_addr = readl(P_AO_DEBUG_REG3) & 0xf; - if (!log_addr) - log_addr = 0xf; - - cec_dbg_printx("AO_DEBUG_REG0:0x", readl(P_AO_DEBUG_REG0), 32); - cec_dbg_printx(", AO_DEBUG_REG1:0x", readl(P_AO_DEBUG_REG1), 32); - cec_dbg_prints("\n"); - cec_dbg_printx("AO_DEBUG_REG2:0x", readl(P_AO_DEBUG_REG2), 32); - cec_dbg_printx(", AO_DEBUG_REG3:0x", readl(P_AO_DEBUG_REG3), 32); - cec_dbg_prints("\n"); + unsigned char log_addr = readl(P_AO_DEBUG_REG3) & 0xf; cec_dbg_print("cec_node_init cec_config:0x", hdmi_cec_func_config); cec_dbg_printx(", log_addr:0x", log_addr, 4); @@ -515,6 +524,12 @@ void cec_node_init(void) cec_msg.log_addr = log_addr; cec_msg.phy_addr = phy_addr; + if (!cec_msg.log_addr || !cec_msg.phy_addr) { + cec_dbg_prints("WARNING: log/phy_addr is not set, disabling cec wakeup\n"); + hdmi_cec_func_config = hdmi_cec_func_config & ~(0x1 << CEC_FUNC_MASK); + return; + } + cec_wr_reg(CEC_LOGICAL_ADDR0, 0); cec_hw_buf_clear(); cec_wr_reg(CEC_LOGICAL_ADDR0, log_addr); @@ -523,7 +538,6 @@ void cec_node_init(void) _udelay(100); cec_report_physical_address(); - _udelay(150); cec_device_vendor_id(); cec_set_osd_name(CEC_TV_ADDR); } diff --git a/arch/arm/cpu/armv8/gxb/firmware/scp_task/suspend.c b/arch/arm/cpu/armv8/gxb/firmware/scp_task/suspend.c index 8a414da3664..b16910c4e04 100644 --- a/arch/arm/cpu/armv8/gxb/firmware/scp_task/suspend.c +++ b/arch/arm/cpu/armv8/gxb/firmware/scp_task/suspend.c @@ -73,8 +73,6 @@ void enter_suspend(unsigned int suspend_from) // FIXME : (1) BLUE LED GPIOAO_13 (2) Current issue 12*mA -> 7*mA #ifdef CONFIG_CEC_WAKEUP hdmi_cec_func_config = readl(P_AO_DEBUG_REG0) & 0xff; - if (!hdmi_cec_func_config) - hdmi_cec_func_config = 0x2f; // Force cec config until kernel is "fixed" wait_uart_empty(); uart_puts("CEC cfg:0x"); uart_put_hex(hdmi_cec_func_config, 8);