# HG changeset patch # User Paul Boddie # Date 1591393528 -7200 # Node ID 3d98739acdc622db92212e03815441912d67eb17 # Parent bea5a6794d720f3df6138ea68b353b3818afd54b Employ a software reset when enabling overflow interrupts, apparently necessary. Introduced more specific enum types, adjusted register and value names. diff -r bea5a6794d72 -r 3d98739acdc6 pkg/devices/lib/hdmi/src/jz4780.cc --- a/pkg/devices/lib/hdmi/src/jz4780.cc Fri Jun 05 23:42:35 2020 +0200 +++ b/pkg/devices/lib/hdmi/src/jz4780.cc Fri Jun 05 23:45:28 2020 +0200 @@ -207,7 +207,7 @@ // Video packetizer registers. Packet_status = 0x0800, // VP_STATUS - Packet_pixel_repeater = 0x0801, // VP_PR_CD + Packet_pr_cd = 0x0801, // VP_PR_CD Packet_stuffing = 0x0802, // VP_STUFF Packet_remap = 0x0803, // VP_REMAP Packet_config = 0x0804, // VP_CONF @@ -215,7 +215,7 @@ // Identification values. -enum Product_id_values : unsigned +enum Product_id_values : uint8_t { Product_id0_transmitter = 0xa0, // PRODUCT_ID0_HDMI_TX @@ -226,7 +226,7 @@ // Configuration values. -enum Config_id_values : unsigned +enum Config_id_values : uint8_t { Config_id0_i2s = 0x10, // CONFIG0_I2S Config_id0_cec = 0x02, // CONFIG0_CEC @@ -247,7 +247,7 @@ // Status and mask bits. -enum Int_mask_bits : unsigned +enum Int_mask_bits : uint8_t { Int_mask_wakeup = 0x02, Int_mask_all = 0x01, @@ -255,7 +255,7 @@ // I2C status and mask bits, also for PHY I2C. -enum I2c_int_status_bits : unsigned +enum I2c_int_status_bits : uint8_t { I2c_int_status_done = 0x02, I2c_int_status_error = 0x01, @@ -263,7 +263,7 @@ // I2C operation bits. -enum I2c_operation_bits : unsigned +enum I2c_operation_bits : uint8_t { I2c_operation_write = 0x10, I2c_operation_segment_read = 0x02, // not PHY I2C @@ -272,7 +272,7 @@ // Device addresses. -enum I2c_phy_device_addresses : unsigned +enum I2c_phy_device_addresses : uint8_t { I2c_phy_device_phy_gen2 = 0x69, // PHY_I2CM_SLAVE_ADDR_PHY_GEN2 I2c_phy_device_phy_heac = 0x49, // PHY_I2CM_SLAVE_ADDR_HEAC_PHY @@ -280,7 +280,7 @@ // Device registers. -enum I2c_phy_device_registers : unsigned +enum I2c_phy_device_registers : uint8_t { I2c_phy_3d_tx_clock_cal_ctrl = 0x05, // 3D_TX_PHY_CKCALCTRL I2c_phy_3d_tx_cpce_ctrl = 0x06, // 3D_TX_PHY_CPCE_CTRL @@ -295,25 +295,25 @@ // PHY I2C register values. -enum Msm_ctrl_bits : unsigned +enum Msm_ctrl_bits : uint16_t { Msm_ctrl_clock_output_select_fb = 1 << 3, // 3D_TX_PHY_MSM_CTRL_CKO_SEL_FB_CLK }; -enum Clock_cal_ctrl_bits : unsigned +enum Clock_cal_ctrl_bits : uint16_t { Clock_cal_ctrl_override = 1 << 15, // 3D_TX_PHY_CKCALCTRL_OVERRIDE }; // Interrupt configuration bits, also for PHY I2C. -enum I2c_int_config0_bits : unsigned +enum I2c_int_config0_bits : uint8_t { I2c_int_config0_done_polarity = 0x08, I2c_int_config0_done_mask = 0x04, }; -enum I2c_int_config1_bits : unsigned +enum I2c_int_config1_bits : uint8_t { I2c_int_config1_nack_polarity = 0x80, I2c_int_config1_nack_mask = 0x40, @@ -323,7 +323,7 @@ // PHY configuration values. -enum Phy_config_bits : unsigned +enum Phy_config_bits : uint8_t { Phy_config_powerdown_disable = 0x80, // PHY_CONF0_PDZ_MASK Phy_config_tmds = 0x40, // PHY_CONF0_ENTMDS_MASK @@ -335,7 +335,7 @@ Phy_config_select_interface_control = 0x01, // PHY_CONF0_SELDIPIF_MASK }; -enum Phy_test_bits : unsigned +enum Phy_test_bits : uint8_t { Phy_test0_clear_mask = 0x20, // PHY_TST0_TSTCLR_MASK Phy_test0_enable_mask = 0x10, // PHY_TST0_TSTEN_MASK @@ -344,7 +344,7 @@ // PHY status and mask values. -enum Phy_status_bits : unsigned +enum Phy_status_bits : uint8_t { Phy_status_all = 0xf3, Phy_status_rx_sense_all = 0xf0, @@ -359,7 +359,7 @@ // PHY interrupt status and mask values. -enum Phy_int_status_bits : unsigned +enum Phy_int_status_bits : uint8_t { Phy_int_status_all = 0x3f, Phy_int_status_rx_sense_all = 0x3c, @@ -374,18 +374,18 @@ // PHY main register values. -enum Main_heac_phy_reset_bits : unsigned +enum Main_heac_phy_reset_bits : uint8_t { Main_heac_phy_reset_assert = 0x01, // MC_HEACPHY_RST_ASSERT }; -enum Main_flow_control_bits : unsigned +enum Main_flow_control_bits : uint8_t { Main_flow_control_csc_active = 0x01, // MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH Main_flow_control_csc_inactive = 0x00, // MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS }; -enum Main_clock_disable_bits : unsigned +enum Main_clock_disable_bits : uint8_t { Main_clock_disable_hdcp = 0x40, // MC_CLKDIS_HDCPCLK_DISABLE Main_clock_disable_cec = 0x20, // MC_CLKDIS_CECCLK_DISABLE @@ -396,9 +396,14 @@ Main_clock_disable_pixel = 0x01, // MC_CLKDIS_PIXELCLK_DISABLE }; +enum Main_software_reset_bits : uint8_t +{ + Main_software_reset_tmds = 0x02, // MC_SWRSTZ_TMDSSWRST_REQ +}; + // Frame composer values. -enum Fc_video_config_bits : unsigned +enum Fc_video_config_bits : uint8_t { Fc_video_config_hdcp_keepout_active = 0x80, // FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE Fc_video_config_hdcp_keepout_inactive = 0x00, // FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE @@ -416,7 +421,7 @@ Fc_video_config_progressive = 0x00, // FC_INVIDCONF_IN_I_P_PROGRESSIVE }; -enum Fc_int_status2_bits : unsigned +enum Fc_int_status2_bits : uint8_t { Fc_int_status2_overflow = 0x03, // FC_STAT2_OVERFLOW_MASK Fc_int_status2_overflow_low = 0x02, // FC_STAT2_LOW_PRIORITY_OVERFLOW @@ -425,7 +430,7 @@ // Colour space conversion values. -enum Csc_config_bits : unsigned +enum Csc_config_bits : uint8_t { Csc_config_interpolation_mask = 0x30, // CSC_CFG_INTMODE_MASK Csc_config_interpolation_disable = 0x00, // CSC_CFG_INTMODE_DISABLE @@ -438,7 +443,7 @@ Csc_config_decimation_form3 = 0x3, // CSC_CFG_DECMODE_CHROMA_INT_FORMULA3 }; -enum Csc_scale_bits : unsigned +enum Csc_scale_bits : uint8_t { Csc_scale_colour_depth_mask = 0xf0, // CSC_SCALE_CSC_COLORDE_PTH_MASK Csc_scale_colour_depth_24bpp = 0x00, // CSC_SCALE_CSC_COLORDE_PTH_24BPP @@ -450,30 +455,30 @@ // HDCP register values. -enum Hdcp_config0_bits : unsigned +enum Hdcp_config0_bits : uint8_t { Hdcp_config0_rxdetect_enable = 0x4, // A_HDCPCFG0_RXDETECT_ENABLE }; -enum Hdcp_config1_bits : unsigned +enum Hdcp_config1_bits : uint8_t { Hdcp_config1_encryption_disable = 0x2, // A_HDCPCFG1_ENCRYPTIONDISABLE_DISABLE }; -enum Hdcp_video_polarity_bits : unsigned +enum Hdcp_video_polarity_bits : uint8_t { Hdcp_video_polarity_data_enable_active_high = 0x10, // A_VIDPOLCFG_DATAENPOL_ACTIVE_HIGH }; // Video sample register values. -enum Sample_video_config_bits : unsigned +enum Sample_video_config_bits : uint8_t { Sample_video_config_data_enable_active = 0x80, // TX_INVID0_INTERNAL_DE_GENERATOR_ENABLE Sample_video_config_mapping_mask = 0x1f, // TX_INVID0_VIDEO_MAPPING_MASK }; -enum Sample_video_stuffing_bits : unsigned +enum Sample_video_stuffing_bits : uint8_t { Sample_video_stuffing_bdb_data = 0x04, // TX_INSTUFFING_BDBDATA_STUFFING_ENABLE Sample_video_stuffing_rcr_data = 0x02, // TX_INSTUFFING_RCRDATA_STUFFING_ENABLE @@ -482,7 +487,7 @@ // Video packetizer register values. -enum Packet_stuffing_bits : unsigned +enum Packet_stuffing_bits : uint8_t { Packet_stuffing_default_phase = 0x20, // VP_STUFF_IDEFAULT_PHASE_MASK Packet_stuffing_ifix_pp_to_last = 0x10, // VP_STUFF_IFIX_PP_TO_LAST_MASK @@ -492,7 +497,7 @@ Packet_stuffing_pr = 0x01, // VP_STUFF_PR_STUFFING_STUFFING_MODE }; -enum Packet_config_bits : unsigned +enum Packet_config_bits : uint8_t { Packet_config_bypass_enable = 0x40, // VP_CONF_BYPASS_EN_ENABLE Packet_config_pp_enable = 0x20, // VP_CONF_PP_EN_ENABLE @@ -505,7 +510,7 @@ Packet_config_output_selector_pp = 0x0, // VP_CONF_OUTPUT_SELECTOR_PP }; -enum Packet_remap_bits : unsigned +enum Packet_remap_bits : uint8_t { Packet_remap_mask = 0x3, // VP_REMAP_MASK Packet_remap_ycc422_24bit = 0x2, // VP_REMAP_YCC422_24bit @@ -513,12 +518,12 @@ Packet_remap_ycc422_16bit = 0x0, // VP_REMAP_YCC422_16bit }; -enum Packet_pixel_repeater_bits : unsigned +enum Packet_pr_cd_bits : uint8_t { - Packet_pixel_repeater_depth_mask = 0xf0, // VP_PR_CD_COLOR_DEPTH_MASK - Packet_pixel_repeater_depth_offset = 4, // VP_PR_CD_COLOR_DEPTH_OFFSET - Packet_pixel_repeater_factor_mask = 0x0f, // VP_PR_CD_DESIRED_PR_FACTOR_MASK - Packet_pixel_repeater_factor_offset = 0, // VP_PR_CD_DESIRED_PR_FACTOR_OFFSET + Packet_pr_cd_depth_mask = 0xf0, // VP_PR_CD_COLOR_DEPTH_MASK + Packet_pr_cd_depth_offset = 4, // VP_PR_CD_COLOR_DEPTH_OFFSET + Packet_pr_cd_factor_mask = 0x0f, // VP_PR_CD_DESIRED_PR_FACTOR_MASK + Packet_pr_cd_factor_offset = 0, // VP_PR_CD_DESIRED_PR_FACTOR_OFFSET }; @@ -1192,7 +1197,20 @@ void Hdmi_jz4780_chip::enable_overflow_irq(bool enable) { - reg_update(Fc_int_mask2, Fc_int_status2_overflow, !enable); + if (!enable) + reg_update(Fc_int_mask2, Fc_int_status2_overflow, !enable); + + // Apparent workaround required. + + else + { + uint8_t config = _regs[Fc_video_config]; + + _regs[Main_software_reset] = ~(Main_software_reset_tmds); + + for (int i = 0; i < 4; i++) + _regs[Fc_video_config] = config; + } } void Hdmi_jz4780_chip::frame_init() @@ -1321,9 +1339,9 @@ int colour_depth = 4; - _regs[Packet_pixel_repeater] = - ((colour_depth << Packet_pixel_repeater_depth_offset) & - Packet_pixel_repeater_depth_mask); + _regs[Packet_pr_cd] = + ((colour_depth << Packet_pr_cd_depth_offset) & + Packet_pr_cd_depth_mask); _regs[Packet_remap] = Packet_remap_ycc422_16bit; @@ -1334,14 +1352,14 @@ // Disable pixel repeater. - reg_update_field(Packet_config, Packet_config_pr_enable | - Packet_config_bypass_select_packetizer | - Packet_config_bypass_enable | + reg_update_field(Packet_config, Packet_config_bypass_enable | + Packet_config_pr_enable | Packet_config_pp_enable | Packet_config_ycc422_enable | - Packet_config_output_selector_mask, Packet_config_bypass_select_packetizer | + Packet_config_output_selector_mask, Packet_config_bypass_enable | + Packet_config_bypass_select_packetizer | Packet_config_output_selector_bypass); }