Created
August 5, 2017 06:23
-
-
Save xerpi/acf095250768b216471b8416e5bdc07c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "hdmi.h" | |
#include "libc.h" | |
#include "utils.h" | |
#include "adv7511.h" | |
#include "i2c.h" | |
#include "gpio.h" | |
#include "pervasive.h" | |
#include "syscon.h" | |
#include "log.h" | |
#define BIT(x) (1 << (x)) | |
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) | |
#define HDMI_I2C_BUS 1 | |
#define HDMI_I2C_ADDR 0x7A | |
/* Configurable addresses */ | |
#define HDMI_I2C_CEC_ADDR 0x7C | |
static void hdmi_i2c_cmd_write(unsigned char addr, unsigned char reg, const unsigned char *data, int size) | |
{ | |
unsigned char buffer[8]; | |
int i = 0; | |
while (size > 7) { | |
buffer[0] = reg + i; | |
memcpy(&buffer[1], &data[i], sizeof(buffer) - 1); | |
i2c_transfer_write(HDMI_I2C_BUS, addr, buffer, sizeof(buffer)); | |
i += 7; | |
size -= 7; | |
} | |
if (size > 0) { | |
buffer[0] = reg + i; | |
memcpy(&buffer[1], &data[i], size); | |
i2c_transfer_write(HDMI_I2C_BUS, addr, buffer, size + 1); | |
} | |
} | |
static void hdmi_i2c_cmd_write_read(unsigned char addr, unsigned char reg, unsigned char *buff, unsigned int size) | |
{ | |
unsigned char buffer; | |
int i = 0; | |
while (size > 8) { | |
buffer = reg + i; | |
i2c_transfer_write_read(HDMI_I2C_BUS, addr, &buffer, sizeof(buffer), addr, &buff[i], size); | |
i += 8; | |
size -= 8; | |
} | |
if (size > 0) { | |
buffer = reg + i; | |
i2c_transfer_write_read(HDMI_I2C_BUS, addr, &buffer, sizeof(buffer), addr, &buff[i], size); | |
} | |
} | |
static inline void hdmi_i2c_cmd_write_1(unsigned char addr, unsigned char reg, unsigned char data) | |
{ | |
unsigned char buff = data; | |
hdmi_i2c_cmd_write(addr, reg, &buff, sizeof(buff)); | |
} | |
static inline void hdmi_i2c_cmd_write_read_1(unsigned char addr, unsigned char reg, unsigned char *data) | |
{ | |
hdmi_i2c_cmd_write_read(addr, reg, data, 1); | |
} | |
struct reg_sequence { | |
unsigned char reg; | |
unsigned char cmd; | |
}; | |
static const struct reg_sequence adv7511_fixed_registers[] = { | |
{ 0x98, 0x03 }, | |
{ 0x9a, 0xe0 }, | |
{ 0x9c, 0x30 }, | |
{ 0x9d, 0x61 }, | |
{ 0xa2, 0xa4 }, | |
{ 0xa3, 0xa4 }, | |
{ 0xe0, 0xd0 }, | |
{ 0xf9, 0x00 }, | |
{ 0x55, 0x02 }, | |
}; | |
static const struct reg_sequence adv7533_fixed_registers[] = { | |
{ 0x16, 0x20 }, | |
{ 0x9a, 0xe0 }, | |
{ 0xba, 0x70 }, | |
{ 0xde, 0x82 }, | |
{ 0xe4, 0x40 }, | |
{ 0xe5, 0x80 }, | |
}; | |
static const struct reg_sequence adv7533_cec_fixed_registers[] = { | |
{ 0x15, 0xd0 }, | |
{ 0x17, 0xd0 }, | |
{ 0x24, 0x20 }, | |
{ 0x57, 0x11 }, | |
{ 0x05, 0xc8 }, | |
}; | |
void hdmi_i2c_update_bits(unsigned char addr, unsigned char reg, | |
unsigned char mask, unsigned char val) | |
{ | |
unsigned char data; | |
hdmi_i2c_cmd_write_read_1(addr, reg, &data); | |
data &= ~mask; | |
data |= val & mask; | |
hdmi_i2c_cmd_write_1(addr, reg, data); | |
} | |
static void hdmi_config_dsi_timing_gen(void) | |
{ | |
unsigned int hsw, hfp, hbp, vsw, vfp, vbp; | |
static const unsigned char clock_div_by_lanes[] = { 6, 4, 3 }; /* 2, 3, 4 lanes */ | |
/* | |
|VIC|Hactive|Vactive|I / P|Htotal|Hblank|Vtotal|Vblank|H Freq|V Freq |Pixel Freq| | |
|2,3| 720 | 480 |Prog | 858 | 138 | 525 | 45 |31.469|59.9403| 27.000 | | |
|flags|pixelclk24|subinfo_24bpp|pixelclk30|subinfo_30bpp|htotal|vtotal|mode|HFP|HSW|HBP|VFP|VSW|VBP| | |
| 1 |0x107AC0 |&stru_BD0E04 | 0x149970 |&stru_BD0AC4 | 858 | 525 | 0 |16 |62 |60 | 9 | 6 |30 | | |
HBP + HFP + HSS = 16 + 62 + 60 = 138 | |
VFP + VBP + VSS = 9 + 6 + 30 = 45 | |
VIC 4: 0x672, 0x2EE, 0, 0x6E, 0x28, 0xDC, 5, 5, 0x14}; | |
*/ | |
static const unsigned char lanes = 3; | |
unsigned int htotal = 1650; | |
unsigned int vtotal = 750; | |
hsw = 0x28; | |
hfp = 0x6E; | |
hbp = 0xDC; | |
vsw = 5; | |
vfp = 5; | |
vbp = 0x14; | |
/* set pixel clock divider mode */ | |
hdmi_i2c_cmd_write_1(HDMI_I2C_CEC_ADDR, 0x16, | |
clock_div_by_lanes[lanes - 2] << 3); | |
/* horizontal porch params */ | |
hdmi_i2c_cmd_write_1(HDMI_I2C_CEC_ADDR, 0x28, htotal >> 4); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_CEC_ADDR, 0x29, (htotal << 4) & 0xff); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_CEC_ADDR, 0x2a, hsw >> 4); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_CEC_ADDR, 0x2b, (hsw << 4) & 0xff); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_CEC_ADDR, 0x2c, hfp >> 4); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_CEC_ADDR, 0x2d, (hfp << 4) & 0xff); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_CEC_ADDR, 0x2e, hbp >> 4); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_CEC_ADDR, 0x2f, (hbp << 4) & 0xff); | |
/* vertical porch params */ | |
hdmi_i2c_cmd_write_1(HDMI_I2C_CEC_ADDR, 0x30, vtotal >> 4); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_CEC_ADDR, 0x31, (vtotal << 4) & 0xff); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_CEC_ADDR, 0x32, vsw >> 4); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_CEC_ADDR, 0x33, (vsw << 4) & 0xff); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_CEC_ADDR, 0x34, vfp >> 4); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_CEC_ADDR, 0x35, (vfp << 4) & 0xff); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_CEC_ADDR, 0x36, vbp >> 4); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_CEC_ADDR, 0x37, (vbp << 4) & 0xff); | |
} | |
static void hdmi_set_link_config(void) | |
{ | |
/* | |
* The input style values documented in the datasheet don't match the | |
* hardware register field values :-( | |
*/ | |
static const unsigned int input_styles[4] = { 0, 2, 1, 3 }; | |
static const unsigned int config_input_colorspace = HDMI_COLORSPACE_RGB; | |
static const unsigned int config_clock_delay = 0; | |
static const unsigned int config_input_style = 0; | |
static const unsigned int config_input_color_depth = 8; | |
static const unsigned int config_embedded_sync = 0; | |
static const unsigned int config_input_clock = ADV7511_INPUT_CLOCK_1X; | |
static const unsigned int config_input_justification = ADV7511_INPUT_JUSTIFICATION_LEFT; | |
static const unsigned int config_input_ddr_alignment = ADV7511_INPUT_DDR_ALIGNMENT_35_18; | |
static const unsigned int config_input_bus_order = ADV7511_INPUT_BUS_ORDER_REVERSE; | |
static const unsigned int config_sync_pulse = ADV7511_INPUT_SYNC_PULSE_DE; | |
unsigned int clock_delay; | |
unsigned int color_depth; | |
unsigned int input_id; | |
clock_delay = (config_clock_delay + 1200) / 400; | |
color_depth = config_input_color_depth == 8 ? 3 | |
: (config_input_color_depth == 10 ? 1 : 2); | |
if (config_input_colorspace != HDMI_COLORSPACE_YUV422) | |
input_id = config_input_clock == ADV7511_INPUT_CLOCK_DDR | |
? 5 : 0; | |
else if (config_input_clock == ADV7511_INPUT_CLOCK_DDR) | |
input_id = config_embedded_sync ? 8 : 7; | |
else if (config_input_clock == ADV7511_INPUT_CLOCK_2X) | |
input_id = config_embedded_sync ? 4 : 3; | |
else | |
input_id = config_embedded_sync ? 2 : 1; | |
hdmi_i2c_update_bits(HDMI_I2C_ADDR, ADV7511_REG_I2C_FREQ_ID_CFG, 0xf, | |
input_id); | |
hdmi_i2c_update_bits(HDMI_I2C_ADDR, ADV7511_REG_VIDEO_INPUT_CFG1, 0x7e, | |
(color_depth << 4) | | |
(input_styles[config_input_style] << 2)); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, ADV7511_REG_VIDEO_INPUT_CFG2, | |
(config_input_justification << 3) | | |
(config_input_ddr_alignment << 5) | | |
(config_input_bus_order << 6)); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, ADV7511_REG_TIMING_GEN_SEQ, | |
config_sync_pulse << 2); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, 0xba, clock_delay << 5); | |
} | |
typedef unsigned char u8; | |
#define hdmi_write(addr,reg, data) \ | |
hdmi_i2c_cmd_write_1(addr, reg, data) | |
static inline u8 hdmi_read(u8 addr, u8 reg) | |
{ | |
unsigned char data; | |
hdmi_i2c_cmd_write_read_1(addr, reg, &data); | |
return data; | |
} | |
void hdmi_set_bit(u8 addr, u8 reg, u8 bit) | |
{ | |
u8 val; | |
val = hdmi_read(addr, reg); | |
val |= bit; | |
hdmi_write(addr, reg, val); | |
} | |
void hdmi_clr_bit(u8 addr, u8 reg, u8 bit) | |
{ | |
u8 val; | |
val = hdmi_read(addr, reg); | |
val &= ~bit; | |
hdmi_write(addr, reg, val); | |
} | |
static int adv7533_set_video(int hdmi_format, int internal_timing) | |
{ | |
//int fmt; | |
int temp_timing; | |
u8 temp_byte; | |
//fmt = hdmi_format - 1; | |
/* Set DSI LP Oscillator and HDMI Enable to Normal Operation (Enabled)*/ | |
hdmi_write(HDMI_I2C_CEC_ADDR, 0x03, 0x89); | |
/* HDMI Startup*/ | |
/* Set Vsync and Hsync Polarity according to hdmi_format*/ | |
if ((hdmi_format == 0) || (hdmi_format == 4) || (hdmi_format == 5) | |
|| (hdmi_format == 16) || (hdmi_format == 19)) { | |
hdmi_clr_bit(HDMI_I2C_ADDR, ADV7533_MAIN_SYNC_REG, | |
(ADV7533_MAIN_SYNC_H|ADV7533_MAIN_SYNC_V)); | |
} else { | |
hdmi_set_bit(HDMI_I2C_ADDR, ADV7533_MAIN_SYNC_REG, | |
(ADV7533_MAIN_SYNC_H | ADV7533_MAIN_SYNC_V)); | |
} | |
/* Input aspect ratio 16:9 */ | |
hdmi_set_bit(HDMI_I2C_ADDR, ADV7533_MAIN_SYNC_REG, 1 << 1); | |
/* Fixed Register Settings per PG*/ | |
hdmi_write(HDMI_I2C_CEC_ADDR, 0x24, 0x20); | |
hdmi_write(HDMI_I2C_CEC_ADDR, 0x26, 0x3C); | |
hdmi_write(HDMI_I2C_ADDR, 0x9A, 0xE0); | |
hdmi_write(HDMI_I2C_ADDR, 0x9B, 0x19); | |
hdmi_write(HDMI_I2C_ADDR, 0xBA, 0x70); | |
hdmi_write(HDMI_I2C_ADDR, 0xDE, 0x82); | |
hdmi_write(HDMI_I2C_ADDR, 0xE4, 0x40); | |
hdmi_write(HDMI_I2C_ADDR, 0xE5, 0x80); | |
/* Ungate Audio and CEC Clocks - clear bit 4 and 5*/ | |
hdmi_clr_bit(HDMI_I2C_CEC_ADDR, 0x05, 0x20); | |
hdmi_clr_bit(HDMI_I2C_CEC_ADDR, 0x05, 0x10); | |
/* Start DSI Programming*/ | |
/* Set Number of DSI Data Lanes to 3*/ | |
hdmi_set_bit(HDMI_I2C_CEC_ADDR, 0x1C, 0x30); | |
/* Set CEC Power Mode = Always Active. Clear bits before*/ | |
hdmi_clr_bit(HDMI_I2C_CEC_ADDR, 0xBE, 0x03); | |
hdmi_set_bit(HDMI_I2C_CEC_ADDR, 0xBE, 0x01); | |
/* Set Timing Generator Settings*/ | |
if (internal_timing) { | |
#if 0 | |
struct lcd_frame_config frame_timings; | |
get_frame_config(&frame_timings, fmt); | |
/*Set Horizontal parameters*/ | |
temp_timing = frame_timings.LCD_Horizontal | |
+ frame_timings.LCD_HSW + frame_timings.LCD_BLW | |
+ frame_timings.LCD_ELW; | |
temp_byte = (u8)((temp_timing & ADV7533_CEC_DSI_TIMING_H_MASK) | |
>> ADV7533_CEC_DSI_TIMING_OFFSET); | |
hdmi_write(HDMI_I2C_CEC_ADDR, | |
ADV7533_CEC_DSI_TOTAL_WIDTH_H_REG, temp_byte); | |
temp_byte = (u8)((temp_timing & ADV7533_CEC_DSI_TIMING_L_MASK) | |
<< ADV7533_CEC_DSI_TIMING_OFFSET); | |
hdmi_write(HDMI_I2C_CEC_ADDR, | |
ADV7533_CEC_DSI_TOTAL_WIDTH_L_REG, temp_byte); | |
temp_timing = frame_timings.LCD_HSW; | |
temp_byte = (u8)((temp_timing & ADV7533_CEC_DSI_TIMING_H_MASK) | |
>> ADV7533_CEC_DSI_TIMING_OFFSET); | |
hdmi_write(HDMI_I2C_CEC_ADDR, | |
ADV7533_CEC_DSI_HSYNC_H_REG, temp_byte); | |
temp_byte = (u8)((temp_timing & ADV7533_CEC_DSI_TIMING_L_MASK) | |
<< ADV7533_CEC_DSI_TIMING_OFFSET); | |
hdmi_write(HDMI_I2C_CEC_ADDR, | |
ADV7533_CEC_DSI_HSYNC_L_REG, temp_byte); | |
temp_timing = frame_timings.LCD_ELW; | |
temp_byte = (u8)((temp_timing & ADV7533_CEC_DSI_TIMING_H_MASK) | |
>> ADV7533_CEC_DSI_TIMING_OFFSET); | |
hdmi_write(HDMI_I2C_CEC_ADDR, | |
ADV7533_CEC_DSI_HFP_H_REG, temp_byte); | |
temp_byte = (u8)((temp_timing & ADV7533_CEC_DSI_TIMING_L_MASK) | |
<< ADV7533_CEC_DSI_TIMING_OFFSET); | |
hdmi_write(HDMI_I2C_CEC_ADDR, | |
ADV7533_CEC_DSI_HFP_L_REG, temp_byte); | |
temp_timing = frame_timings.LCD_BLW; | |
temp_byte = (u8)((temp_timing & ADV7533_CEC_DSI_TIMING_H_MASK) | |
>> ADV7533_CEC_DSI_TIMING_OFFSET); | |
hdmi_write(HDMI_I2C_CEC_ADDR, | |
ADV7533_CEC_DSI_HBP_H_REG, temp_byte); | |
temp_byte = (u8)((temp_timing & ADV7533_CEC_DSI_TIMING_L_MASK) | |
<< ADV7533_CEC_DSI_TIMING_OFFSET); | |
hdmi_write(HDMI_I2C_CEC_ADDR, | |
ADV7533_CEC_DSI_HBP_L_REG, temp_byte); | |
/*Set Vertical parameters*/ | |
temp_timing = frame_timings.LCD_Vertical + frame_timings.LCD_VSW | |
+ frame_timings.LCD_BFW + frame_timings.LCD_EFW; | |
temp_byte = (u8)((temp_timing & ADV7533_CEC_DSI_TIMING_H_MASK) | |
>> ADV7533_CEC_DSI_TIMING_OFFSET); | |
hdmi_write(HDMI_I2C_CEC_ADDR, | |
ADV7533_CEC_DSI_TOTAL_HEIGHT_H_REG, temp_byte); | |
temp_byte = (u8)((temp_timing & ADV7533_CEC_DSI_TIMING_L_MASK) | |
<< ADV7533_CEC_DSI_TIMING_OFFSET); | |
hdmi_write(HDMI_I2C_CEC_ADDR, | |
ADV7533_CEC_DSI_TOTAL_HEIGHT_L_REG, temp_byte); | |
temp_timing = frame_timings.LCD_VSW; | |
temp_byte = (u8)((temp_timing & ADV7533_CEC_DSI_TIMING_H_MASK) | |
>> ADV7533_CEC_DSI_TIMING_OFFSET); | |
hdmi_write(HDMI_I2C_CEC_ADDR, | |
ADV7533_CEC_DSI_VSYNC_H_REG, temp_byte); | |
temp_byte = (u8)((temp_timing & ADV7533_CEC_DSI_TIMING_L_MASK) | |
<< ADV7533_CEC_DSI_TIMING_OFFSET); | |
hdmi_write(HDMI_I2C_CEC_ADDR, | |
ADV7533_CEC_DSI_VSYNC_L_REG, temp_byte); | |
temp_timing = frame_timings.LCD_EFW; | |
temp_byte = (u8)((temp_timing & ADV7533_CEC_DSI_TIMING_H_MASK) | |
>> ADV7533_CEC_DSI_TIMING_OFFSET); | |
hdmi_write(HDMI_I2C_CEC_ADDR, | |
ADV7533_CEC_DSI_VFP_H_REG, temp_byte); | |
temp_byte = (u8)((temp_timing & ADV7533_CEC_DSI_TIMING_L_MASK) | |
<< ADV7533_CEC_DSI_TIMING_OFFSET); | |
hdmi_write(HDMI_I2C_CEC_ADDR, | |
ADV7533_CEC_DSI_VFP_L_REG, temp_byte); | |
temp_timing = frame_timings.LCD_BFW; | |
temp_byte = (u8)((temp_timing & ADV7533_CEC_DSI_TIMING_H_MASK) | |
>> ADV7533_CEC_DSI_TIMING_OFFSET); | |
hdmi_write(HDMI_I2C_CEC_ADDR, | |
ADV7533_CEC_DSI_VBP_H_REG, temp_byte); | |
temp_byte = (u8)((temp_timing & ADV7533_CEC_DSI_TIMING_L_MASK) | |
<< ADV7533_CEC_DSI_TIMING_OFFSET); | |
hdmi_write(HDMI_I2C_CEC_ADDR, | |
ADV7533_CEC_DSI_VBP_L_REG, temp_byte); | |
#endif | |
/*Enable timing generator*/ | |
hdmi_set_bit(HDMI_I2C_CEC_ADDR, ADV7533_CEC_DSI_INTERNAL_TIMING, | |
ADV7533_CEC_DSI_INTERNAL_TIMING_EN); | |
} else { | |
/*Enable timing generator*/ | |
hdmi_clr_bit(HDMI_I2C_CEC_ADDR, ADV7533_CEC_DSI_INTERNAL_TIMING, | |
ADV7533_CEC_DSI_INTERNAL_TIMING_EN); | |
} | |
/* HDMI Output Settings*/ | |
/* Set HDMI/DVI Mode Select = HDMI Mode Enabled - bit 1*/ | |
hdmi_set_bit(HDMI_I2C_ADDR, 0xAF, 0x2); | |
/* Enable GC Packet */ | |
hdmi_set_bit(HDMI_I2C_ADDR, 0x40, 0x80); | |
/* Set Color Depth to 24 Bits/Pixel. Clear field before*/ | |
hdmi_clr_bit(HDMI_I2C_ADDR, 0x4C, 0x0F); | |
hdmi_set_bit(HDMI_I2C_ADDR, 0x4C, 0x04); | |
/* Set Active Format Aspect Ratio = 16:9 (Center) Clear field before*/ | |
hdmi_clr_bit(HDMI_I2C_ADDR, 0x56, 0x0F); | |
hdmi_set_bit(HDMI_I2C_ADDR, 0x56, 0x0A); | |
/* ?? V*/ | |
hdmi_write(HDMI_I2C_ADDR, 0xE4, 0xC0); | |
/* 24 bit RGB 4:4:4 or YCbCr 4:4:4 (separate syncs) */ | |
hdmi_write(HDMI_I2C_ADDR, 0x15, 0x20); | |
return 0; | |
} | |
#if 0 | |
int hdmi_init_old(void) | |
{ | |
int i; | |
pervasive_hdmi_cec_set_enabled(1); | |
syscon_set_hdmi_cdc_hpd(1); | |
gpio_set_port_mode(0, GPIO_PORT_HDMI_BRIDGE, | |
GPIO_PORT_MODE_OUTPUT); | |
gpio_port_clear(0, GPIO_PORT_HDMI_BRIDGE); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, ADV7511_REG_CEC_I2C_ADDR, | |
HDMI_I2C_CEC_ADDR); | |
unsigned char status; | |
do { | |
hdmi_i2c_cmd_write_read_1(HDMI_I2C_ADDR, ADV7511_REG_STATUS, &status); | |
} while (!(status & ADV7511_STATUS_HPD)); | |
hdmi_i2c_update_bits(HDMI_I2C_ADDR, ADV7511_REG_POWER, | |
ADV7511_POWER_POWER_DOWN, 0); | |
hdmi_i2c_update_bits(HDMI_I2C_ADDR, ADV7511_REG_POWER2, | |
ADV7511_REG_POWER2_HPD_SRC_MASK, | |
ADV7511_REG_POWER2_HPD_SRC_HPD); | |
static unsigned char i2c_0x7A[] = { | |
0x14, | |
0x00, | |
0x2D, | |
0x80, | |
0x22, | |
0x25, | |
0x51, | |
0x00, | |
0x00, | |
0x00, | |
0x50, | |
0xCE, | |
0xB8, | |
0x18, | |
0x01, | |
0x13, | |
0x25, | |
0x37, | |
0x00, | |
0x00, | |
0x00, | |
0x20, | |
0x00, | |
0x02, | |
0xA8, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x08, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x08, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0xC0, | |
0x04, | |
0x04, | |
0x10, | |
0x00, | |
0xC0, | |
0x10, | |
0x70, | |
0x7E, | |
0x79, | |
0x70, | |
0x70, | |
0x70, | |
0x70, | |
0xFC, | |
0x80, | |
0x80, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x02, | |
0x0D, | |
0x43, | |
0x00, | |
0x28, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x01, | |
0x0A, | |
0x70, | |
0x01, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0xC6, | |
0xBF, | |
0x31, | |
0x00, | |
0x03, | |
0x02, | |
0xE0, | |
0x18, | |
0x38, | |
0x61, | |
0x12, | |
0x00, | |
0x00, | |
0x00, | |
0xA0, | |
0xA0, | |
0x08, | |
0x04, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x40, | |
0x00, | |
0x00, | |
0x40, | |
0x96, | |
0xA0, | |
0x87, | |
0x7B, | |
0x90, | |
0xF2, | |
0xE3, | |
0x0F, | |
0x39, | |
0x60, | |
0x00, | |
0x70, | |
0x00, | |
0x28, | |
0xCD, | |
0x80, | |
0x94, | |
0xA4, | |
0xDE, | |
0x2D, | |
0x72, | |
0x00, | |
0x70, | |
0x1E, | |
0x00, | |
0x04, | |
0x01, | |
0x00, | |
0x00, | |
0x02, | |
0x00, | |
0x01, | |
0x04, | |
0x30, | |
0xFF, | |
0x80, | |
0x80, | |
0x80, | |
0x00, | |
0x48, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x82, | |
0x01, | |
0x80, | |
0x7C, | |
0x00, | |
0x00, | |
0xC0, | |
0x80, | |
0xFD, | |
0x20, | |
0x00, | |
0x00, | |
0x52, | |
0x46, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x95, | |
0x04, | |
0xFF, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x10, | |
0x7D, | |
0xAA, | |
0x1C, | |
0x00, | |
0xB0, | |
0x00 | |
}; | |
static unsigned char i2c_0x7C[] = { | |
0x75, | |
0x33, | |
0x01, | |
0x89, | |
0x78, | |
0xC8, | |
0x00, | |
0x80, | |
0x80, | |
0x80, | |
0x80, | |
0x80, | |
0x80, | |
0x80, | |
0x80, | |
0x80, | |
0xC0, | |
0x08, | |
0x00, | |
0x00, | |
0x90, | |
0xD0, | |
0x20, | |
0xD0, | |
0x60, | |
0x19, | |
0x04, | |
0x00, | |
0x30, | |
0xA4, | |
0x00, | |
0x30, | |
0x30, | |
0xFF, | |
0xFF, | |
0x80, | |
0x20, | |
0x12, | |
0x3C, | |
0xD0, | |
0x67, | |
0x20, | |
0x02, | |
0x80, | |
0x06, | |
0xE0, | |
0x0D, | |
0xC0, | |
0x2E, | |
0xE0, | |
0x00, | |
0x50, | |
0x00, | |
0x50, | |
0x01, | |
0x40, | |
0x80, | |
0x00, | |
0x7E, | |
0x00, | |
0x21, | |
0x00, | |
0x00, | |
0x12, | |
0x80, | |
0x10, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x73, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x0A, | |
0x00, | |
0xEC, | |
0x11, | |
0xFF, | |
0xFF, | |
0xFF, | |
0xFF, | |
0xFF, | |
0xFF, | |
0xFF, | |
0xFF, | |
0xFF, | |
0xFF, | |
0xFF, | |
0xFF, | |
0xFF, | |
0xFF, | |
0xFF, | |
0xFF, | |
0xFF, | |
0xFF, | |
0xFF, | |
0x00, | |
0x09, | |
0xD8, | |
0xE4, | |
0x00, | |
0x40, | |
0x00, | |
0x89, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x04, | |
0x07, | |
0x13, | |
0x57, | |
0x00, | |
0x04, | |
0x89, | |
0x01, | |
0xE0, | |
0x91, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x03, | |
0x40, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x00, | |
0x08, | |
0x10, | |
0xF4, | |
0x0F, | |
0x21, | |
0x07, | |
0x00, | |
0x0D, | |
0x2F, | |
0x0C, | |
0x4E, | |
0x0E, | |
0x10, | |
0x0A, | |
0xD7, | |
0x09, | |
0xF6, | |
0x0B, | |
0xB8, | |
0x07, | |
0x08, | |
0x05, | |
0xB7, | |
0x08, | |
0x5A, | |
0x01, | |
0xC2, | |
0x04, | |
0x65, | |
0x05, | |
0x46, | |
0x03, | |
0x14, | |
0x0A, | |
0x8C, | |
0x00, | |
0x00, | |
0xBC, | |
0x00, | |
0x00, | |
0xE1, | |
0x02, | |
0xA3, | |
0x03, | |
0x84, | |
0x6D, | |
0x8F, | |
0x82, | |
0x04, | |
0x0D, | |
0x70, | |
0x42, | |
0x41, | |
0x41, | |
0x00, | |
0x0F, | |
0xFF, | |
0x00, | |
0x0F, | |
0xFF, | |
0x00, | |
0x00, | |
0x20, | |
0x00, | |
0x60, | |
0x02, | |
0x00, | |
0x06, | |
0x06, | |
0x06, | |
}; | |
/* HDCP disable */ | |
i2c_0x7A[0xAF] = 0x06; | |
/* Disable SPDIF receiver */ | |
i2c_0x7A[0x0B] = 0x0E; | |
/* Disable I2S */ | |
i2c_0x7A[0x0C] = 0; | |
/* Disable all DSD Channel */ | |
i2c_0x7A[0x46] = 0; | |
/* I2S Sampling Frequency: 0001 = Do not use; 0000 = 24 bit RGB 4:4:4 or YCbCr 4:4:4 (separate syncs) */ | |
i2c_0x7A[0x15] = 0x10; | |
/* Audio Select: N/A */ | |
i2c_0x7A[0x0A] = 0x50; | |
/* */ | |
//i2c_0x7A[0x40] = 0x80; | |
/*for (int i = 0; i < ARRAY_SIZE(i2c_0x7A); i++) { | |
if (i != 0x41) | |
hdmi_i2c_cmd_write_1(0x7A, i, i2c_0x7A[i]); | |
} | |
for (int i = 0; i < ARRAY_SIZE(i2c_0x7C); i++) | |
hdmi_i2c_cmd_write_1(0x7C, i, i2c_0x7C[i]); | |
adv7533_set_video(4, 1);*/ | |
#define ADV7533_MAIN HDMI_I2C_ADDR | |
#define ADV7533_CEC_DSI HDMI_I2C_CEC_ADDR | |
struct adv7533_reg_cfg { | |
u8 addr, reg, val; | |
}; | |
static const struct adv7533_reg_cfg setup_cfg[] = { | |
//{ADV7533_MAIN, 0x41, 0x10}, /* HDMI normal */ | |
//{ADV7533_MAIN, 0xd6, 0x48}, /* HPD overriden */ | |
{ADV7533_CEC_DSI, 0x03, 0x89}, /* HDMI enabled */ | |
{ADV7533_MAIN, 0x16, 0x20}, | |
{ADV7533_MAIN, 0x9A, 0xE0}, | |
{ADV7533_MAIN, 0xBA, 0x70}, | |
{ADV7533_MAIN, 0xDE, 0x82}, | |
{ADV7533_MAIN, 0xE4, 0xC0}, | |
{ADV7533_MAIN, 0xE5, 0x80}, | |
{ADV7533_CEC_DSI, 0x15, 0xD0}, | |
{ADV7533_CEC_DSI, 0x17, 0xD0}, | |
{ADV7533_CEC_DSI, 0x24, 0x20}, | |
{ADV7533_CEC_DSI, 0x57, 0x11}, | |
/* hdmi or dvi mode: hdmi */ | |
{ADV7533_MAIN, 0xAF, 0x06}, | |
{ADV7533_MAIN, 0x40, 0x80}, | |
{ADV7533_MAIN, 0x4C, 0x04}, | |
{ADV7533_MAIN, 0x49, 0x02}, | |
{ADV7533_MAIN, 0x0D, 1 << 6}, | |
}; | |
static const struct adv7533_reg_cfg tg_cfg_1080p[] = { | |
/* 4 lanes */ | |
{ADV7533_CEC_DSI, 0x1C, 0x40}, | |
/* hsync and vsync active low */ | |
{ADV7533_MAIN, 0x17, 0x02}, | |
/* Control for Pixel Clock Divider */ | |
{ADV7533_CEC_DSI, 0x16, 0x00}, | |
/* Timing Generator Enable */ | |
{ADV7533_CEC_DSI, 0x27, 0xCB}, | |
/* h_width 0x898 2200*/ | |
{ADV7533_CEC_DSI, 0x28, 0x89}, | |
{ADV7533_CEC_DSI, 0x29, 0x80}, | |
/* hsync_width 0x2C 44*/ | |
{ADV7533_CEC_DSI, 0x2A, 0x02}, | |
{ADV7533_CEC_DSI, 0x2B, 0xC0}, | |
/* hfp 0x58 88 */ | |
{ADV7533_CEC_DSI, 0x2C, 0x05}, | |
{ADV7533_CEC_DSI, 0x2D, 0x80}, | |
/* hbp 0x94 148 */ | |
{ADV7533_CEC_DSI, 0x2E, 0x09}, | |
{ADV7533_CEC_DSI, 0x2F, 0x40}, | |
/* v_total 0x465 1125 */ | |
{ADV7533_CEC_DSI, 0x30, 0x46}, | |
{ADV7533_CEC_DSI, 0x31, 0x50}, | |
/* vsync_width 0x05 5*/ | |
{ADV7533_CEC_DSI, 0x32, 0x00}, | |
{ADV7533_CEC_DSI, 0x33, 0x50}, | |
/* vfp 0x04 4 */ | |
{ADV7533_CEC_DSI, 0x34, 0x00}, | |
{ADV7533_CEC_DSI, 0x35, 0x40}, | |
/* vbp 0x24 36 */ | |
{ADV7533_CEC_DSI, 0x36, 0x02}, | |
{ADV7533_CEC_DSI, 0x37, 0x40}, | |
/* Timing Generator Enable */ | |
{ADV7533_CEC_DSI, 0x27, 0xCB}, | |
{ADV7533_CEC_DSI, 0x27, 0x8B}, | |
{ADV7533_CEC_DSI, 0x27, 0xCB}, | |
/* Reset Internal Timing Generator */ | |
{ADV7533_MAIN, 0xAF, 0x16}, | |
/* HDMI Mode Select */ | |
{ADV7533_CEC_DSI, 0x78, 0x03}, | |
/* HDMI Output Enable */ | |
{ADV7533_MAIN, 0x40, 0x80}, | |
/* GC Packet Enable */ | |
{ADV7533_MAIN, 0x4C, 0x04}, | |
/* Colour Depth 24-bit per pixel */ | |
{ADV7533_MAIN, 0x49, 0x00}, | |
/* Down Dither Output 8-bit Colour Depth */ | |
{ADV7533_CEC_DSI, 0x05, 0xC8}, | |
/* ADI Required Write */ | |
{ADV7533_CEC_DSI, 0xBE, 0x3D}, | |
/* Test Pattern Disable (0x55[7] = 0) */ | |
{ADV7533_CEC_DSI, 0x55, 0x00}, | |
}; | |
static const struct adv7533_reg_cfg tg_cfg_pattern_1080p[] = { | |
/* 4 lanes */ | |
{ADV7533_CEC_DSI, 0x1C, 0x40}, | |
/* hsync and vsync active low */ | |
{ADV7533_MAIN, 0x17, 0x02}, | |
/* Control for Pixel Clock Divider */ | |
{ADV7533_CEC_DSI, 0x16, 0x00}, | |
/* Timing Generator Enable */ | |
{ADV7533_CEC_DSI, 0x27, 0xCB}, | |
/* h_width 0x898 2200*/ | |
{ADV7533_CEC_DSI, 0x28, 0x89}, | |
{ADV7533_CEC_DSI, 0x29, 0x80}, | |
/* hsync_width 0x2C 44*/ | |
{ADV7533_CEC_DSI, 0x2A, 0x02}, | |
{ADV7533_CEC_DSI, 0x2B, 0xC0}, | |
/* hfp 0x58 88 */ | |
{ADV7533_CEC_DSI, 0x2C, 0x05}, | |
{ADV7533_CEC_DSI, 0x2D, 0x80}, | |
/* hbp 0x94 148 */ | |
{ADV7533_CEC_DSI, 0x2E, 0x09}, | |
{ADV7533_CEC_DSI, 0x2F, 0x40}, | |
/* v_total 0x465 1125 */ | |
{ADV7533_CEC_DSI, 0x30, 0x46}, | |
{ADV7533_CEC_DSI, 0x31, 0x50}, | |
/* vsync_width 0x05 5*/ | |
{ADV7533_CEC_DSI, 0x32, 0x00}, | |
{ADV7533_CEC_DSI, 0x33, 0x50}, | |
/* vfp 0x04 4 */ | |
{ADV7533_CEC_DSI, 0x34, 0x00}, | |
{ADV7533_CEC_DSI, 0x35, 0x40}, | |
/* vbp 0x24 36 */ | |
{ADV7533_CEC_DSI, 0x36, 0x02}, | |
{ADV7533_CEC_DSI, 0x37, 0x40}, | |
/* Timing Generator Enable */ | |
{ADV7533_CEC_DSI, 0x27, 0xCB}, | |
{ADV7533_CEC_DSI, 0x27, 0x8B}, | |
{ADV7533_CEC_DSI, 0x27, 0xCB}, | |
/* Reset Internal Timing Generator */ | |
{ADV7533_MAIN, 0xAF, 0x16}, | |
/* HDMI Mode Select */ | |
{ADV7533_CEC_DSI, 0x78, 0x03}, | |
/* HDMI Output Enable */ | |
{ADV7533_MAIN, 0x40, 0x80}, | |
/* GC Packet Enable */ | |
{ADV7533_MAIN, 0x4C, 0x04}, | |
/* Colour Depth 24-bit per pixel */ | |
{ADV7533_MAIN, 0x49, 0x00}, | |
/* Down Dither Output 8-bit Colour Depth */ | |
{ADV7533_CEC_DSI, 0x05, 0xC8}, | |
/* ADI Required Write */ | |
{ADV7533_CEC_DSI, 0xBE, 0x3D}, | |
/* Test Pattern Enable (0x55[7] = 1) */ | |
{ADV7533_CEC_DSI, 0x55, 0x80}, | |
}; | |
static const struct adv7533_reg_cfg tg_cfg_720p[] = { | |
{ADV7533_CEC_DSI, 0x1C, 0x30}, | |
/* hsync and vsync active low */ | |
{ADV7533_MAIN, 0x17, 0x02}, | |
/* Control for Pixel Clock Divider */ | |
{ADV7533_CEC_DSI, 0x16, 0x24}, | |
/* h_width 0x898 2200*/ | |
{ADV7533_CEC_DSI, 0x28, 0x67}, | |
{ADV7533_CEC_DSI, 0x29, 0x20}, | |
/* hsync_width 0x2C 44*/ | |
{ADV7533_CEC_DSI, 0x2A, 0x02}, | |
{ADV7533_CEC_DSI, 0x2B, 0x80}, | |
/* hfp 0x58 88 */ | |
{ADV7533_CEC_DSI, 0x2C, 0x06}, | |
{ADV7533_CEC_DSI, 0x2D, 0xE0}, | |
/* hbp 0x94 148 */ | |
{ADV7533_CEC_DSI, 0x2E, 0x0D}, | |
{ADV7533_CEC_DSI, 0x2F, 0xC0}, | |
/* v_total 0x465 1125 */ | |
{ADV7533_CEC_DSI, 0x30, 0x2E}, | |
{ADV7533_CEC_DSI, 0x31, 0xE0}, | |
/* vsync_width 0x05 5*/ | |
{ADV7533_CEC_DSI, 0x32, 0x00}, | |
{ADV7533_CEC_DSI, 0x33, 0x50}, | |
/* vfp 0x04 4 */ | |
{ADV7533_CEC_DSI, 0x34, 0x00}, | |
{ADV7533_CEC_DSI, 0x35, 0x50}, | |
/* vbp 0x24 36 */ | |
{ADV7533_CEC_DSI, 0x36, 0x01}, | |
{ADV7533_CEC_DSI, 0x37, 0x40}, | |
/* Test Pattern Disable (0x55[7] = 0) */ | |
{ADV7533_CEC_DSI, 0x55, 0x00}, | |
/* HDMI disabled */ | |
{ADV7533_CEC_DSI, 0x03, 0x09}, | |
/* HDMI enabled */ | |
{ADV7533_CEC_DSI, 0x03, 0x89}, | |
}; | |
static const struct adv7533_reg_cfg tg_cfg_pattern_720p[] = { | |
{ADV7533_CEC_DSI, 0x1C, 0x30}, | |
/* hsync and vsync active low */ | |
{ADV7533_MAIN, 0x17, 0x02}, | |
/* Control for Pixel Clock Divider */ | |
{ADV7533_CEC_DSI, 0x16, 0x24}, | |
/* h_width 0x898 2200*/ | |
{ADV7533_CEC_DSI, 0x28, 0x67}, | |
{ADV7533_CEC_DSI, 0x29, 0x20}, | |
/* hsync_width 0x2C 44*/ | |
{ADV7533_CEC_DSI, 0x2A, 0x02}, | |
{ADV7533_CEC_DSI, 0x2B, 0x80}, | |
/* hfp 0x58 88 */ | |
{ADV7533_CEC_DSI, 0x2C, 0x06}, | |
{ADV7533_CEC_DSI, 0x2D, 0xE0}, | |
/* hbp 0x94 148 */ | |
{ADV7533_CEC_DSI, 0x2E, 0x0D}, | |
{ADV7533_CEC_DSI, 0x2F, 0xC0}, | |
/* v_total 0x465 1125 */ | |
{ADV7533_CEC_DSI, 0x30, 0x2E}, | |
{ADV7533_CEC_DSI, 0x31, 0xE0}, | |
/* vsync_width 0x05 5*/ | |
{ADV7533_CEC_DSI, 0x32, 0x00}, | |
{ADV7533_CEC_DSI, 0x33, 0x50}, | |
/* vfp 0x04 4 */ | |
{ADV7533_CEC_DSI, 0x34, 0x00}, | |
{ADV7533_CEC_DSI, 0x35, 0x50}, | |
/* vbp 0x24 36 */ | |
{ADV7533_CEC_DSI, 0x36, 0x01}, | |
{ADV7533_CEC_DSI, 0x37, 0x40}, | |
/* DSI Internal Timing Generator Enable register bit (0x27[7] = 1) */ | |
{ADV7533_CEC_DSI, 0x27, 0x8B}, | |
/* Test Pattern Enable (0x55[7] = 1) */ | |
{ADV7533_CEC_DSI, 0x55, 0x80}, | |
/* DSI Internal Timing Generator Reset Enable | |
register bit (0x27[6] = 0) */ | |
{ADV7533_CEC_DSI, 0x27, 0x8B}, | |
/* DSI Internal Timing Generator Reset Enable | |
register bit (0x27[6] = 1) */ | |
{ADV7533_CEC_DSI, 0x27, 0xCB}, | |
{ADV7533_CEC_DSI, 0x03, 0x09},/* HDMI disabled */ | |
{ADV7533_CEC_DSI, 0x03, 0x89},/* HDMI enabled */ | |
}; | |
static const struct adv7533_reg_cfg irq_config[] = { | |
{ADV7533_CEC_DSI, 0x38, 0xCE}, | |
{ADV7533_CEC_DSI, 0x38, 0xC0}, | |
}; | |
for (i = 0; i < ARRAY_SIZE(adv7533_fixed_registers); i++) | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, | |
adv7533_fixed_registers[i].reg, | |
adv7533_fixed_registers[i].cmd); | |
for (i = 0; i < ARRAY_SIZE(adv7533_cec_fixed_registers); i++) | |
hdmi_i2c_cmd_write_1(HDMI_I2C_CEC_ADDR, | |
adv7533_cec_fixed_registers[i].reg, | |
adv7533_cec_fixed_registers[i].cmd); | |
static const u8 clock_div_by_lanes[] = { 6, 4, 3 }; /* 2, 3, 4 lanes */ | |
unsigned int hsw, hfp, hbp, vsw, vfp, vbp; | |
static const unsigned char lanes = 3; | |
unsigned int htotal = 1650; | |
unsigned int vtotal = 750; | |
hsw = 0x28; | |
hfp = 0x6E; | |
hbp = 0xDC; | |
vsw = 5; | |
vfp = 5; | |
vbp = 0x14; | |
#define ADV7533_REG_CEC_PIXEL_CLOCK_DIV 0x16 | |
/* set pixel clock auto mode */ | |
hdmi_write(ADV7533_CEC_DSI, ADV7533_REG_CEC_PIXEL_CLOCK_DIV, 0x00); | |
/* horizontal porch params */ | |
hdmi_write(ADV7533_CEC_DSI, 0x28, htotal >> 4); | |
hdmi_write(ADV7533_CEC_DSI, 0x29, | |
(htotal << 4) & 0xff); | |
hdmi_write(ADV7533_CEC_DSI, 0x2a, hsw >> 4); | |
hdmi_write(ADV7533_CEC_DSI, 0x2b, (hsw << 4) & 0xff); | |
hdmi_write(ADV7533_CEC_DSI, 0x2c, hfp >> 4); | |
hdmi_write(ADV7533_CEC_DSI, 0x2d, (hfp << 4) & 0xff); | |
hdmi_write(ADV7533_CEC_DSI, 0x2e, hbp >> 4); | |
hdmi_write(ADV7533_CEC_DSI, 0x2f, (hbp << 4) & 0xff); | |
/* vertical porch params */ | |
hdmi_write(ADV7533_CEC_DSI, 0x30, vtotal >> 4); | |
hdmi_write(ADV7533_CEC_DSI, 0x31, | |
(vtotal << 4) & 0xff); | |
hdmi_write(ADV7533_CEC_DSI, 0x32, vsw >> 4); | |
hdmi_write(ADV7533_CEC_DSI, 0x33, (vsw << 4) & 0xff); | |
hdmi_write(ADV7533_CEC_DSI, 0x34, vfp >> 4); | |
hdmi_write(ADV7533_CEC_DSI, 0x35, (vfp << 4) & 0xff); | |
hdmi_write(ADV7533_CEC_DSI, 0x36, vbp >> 4); | |
hdmi_write(ADV7533_CEC_DSI, 0x37, (vbp << 4) & 0xff); | |
/* 30Hz Low Refresh Rate (VIC Detection) */ | |
/* set number of dsi lanes */ | |
hdmi_write(ADV7533_CEC_DSI, 0x1c, 3 << 4); | |
/* reset internal timing generator */ | |
hdmi_write(ADV7533_CEC_DSI, 0x27, 0xcb); | |
hdmi_write(ADV7533_CEC_DSI, 0x27, 0x8b); | |
hdmi_write(ADV7533_CEC_DSI, 0x27, 0xcb); | |
/* 09-03 AVI Infoframe - RGB - 16-9 Aspect Ratio */ | |
hdmi_write(HDMI_I2C_ADDR, 0x55, 0x10); | |
hdmi_write(HDMI_I2C_ADDR, 0x56, 0x28); | |
/* 04-04 GC Packet Enable */ | |
hdmi_write(HDMI_I2C_ADDR, 0x40, 0x80); | |
/* 04-06 GC Colour Depth - 24 Bit */ | |
hdmi_write(HDMI_I2C_ADDR, 0x4c, 0x04); | |
/* 04-09 Down Dither Output Colour Depth - 8 Bit (default) */ | |
hdmi_write(HDMI_I2C_ADDR, 0x49, 0x00); | |
/* 07-01 CEC Power Mode - Always Active */ | |
hdmi_write(ADV7533_CEC_DSI, 0xbe, 0x3d); | |
/* enable hdmi */ | |
hdmi_write(ADV7533_CEC_DSI, 0x03, 0x89); | |
/*enable test mode */ | |
hdmi_write(ADV7533_CEC_DSI, 0x55, 0x80); | |
/*for (int k = 0; k < 32; k++) { | |
if (k == GPIO_PORT_HDMI_BRIDGE) | |
continue; | |
gpio_set_port_mode(0, k, | |
GPIO_PORT_MODE_OUTPUT); | |
gpio_port_clear(0, k); | |
delay(4000); | |
gpio_port_set(0, k); | |
delay(4000); | |
LOG_HEX(k); | |
}*/ | |
/*for (int i = 0; i < ARRAY_SIZE(setup_cfg); i++) | |
hdmi_write(setup_cfg[i].addr, setup_cfg[i].reg, | |
setup_cfg[i].val); | |
for (int i = 0; i < ARRAY_SIZE(tg_cfg_pattern_720p); i++) | |
hdmi_write(tg_cfg_pattern_720p[i].addr, tg_cfg_pattern_720p[i].reg, | |
tg_cfg_pattern_720p[i].val); | |
for (int i = 0; i < ARRAY_SIZE(irq_config); i++) | |
hdmi_write(irq_config[i].addr, irq_config[i].reg, | |
irq_config[i].val);*/ | |
#if 0 | |
for (i = 0; i < ARRAY_SIZE(adv7533_fixed_registers); i++) | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, | |
adv7533_fixed_registers[i].reg, | |
adv7533_fixed_registers[i].cmd); | |
unsigned char irq; | |
hdmi_i2c_cmd_write_read_1(HDMI_I2C_ADDR, ADV7511_REG_INT(0), &irq); | |
if (irq & ADV7511_INT0_HPD) | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, ADV7511_REG_INT(0), ADV7511_INT0_HPD); | |
/* Unknown */ | |
hdmi_i2c_cmd_write_1(HDMI_I2C_CEC_ADDR, 0x25, 18); | |
/* DSI */ | |
hdmi_set_link_config(); | |
hdmi_config_dsi_timing_gen(); | |
/* set number of dsi lanes */ | |
hdmi_i2c_cmd_write_1(HDMI_I2C_CEC_ADDR, 0x1C, 3 << 4); | |
/* Reset internal timing generator */ | |
hdmi_i2c_cmd_write_1(HDMI_I2C_CEC_ADDR, 0x27, 0x90); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_CEC_ADDR, 0x27, 0xD0); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_CEC_ADDR, 0x26, 0x1C); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_CEC_ADDR, 0x26, 0x3C); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, 0x0A, 0x41); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, 0x15, 0x20); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_CEC_ADDR, 0x07, 0x80); | |
/* enable hdmi */ | |
hdmi_i2c_cmd_write_1(HDMI_I2C_CEC_ADDR, 0x03, 0x89); | |
/* disable test mode */ | |
hdmi_i2c_cmd_write_1(HDMI_I2C_CEC_ADDR, 0x55, 0x00); | |
/* unk */ | |
hdmi_i2c_cmd_write_1(HDMI_I2C_CEC_ADDR, 0x20, 0x30); | |
for (i = 0; i < ARRAY_SIZE(adv7533_cec_fixed_registers); i++) | |
hdmi_i2c_cmd_write_1(HDMI_I2C_CEC_ADDR, | |
adv7533_cec_fixed_registers[i].reg, | |
adv7533_cec_fixed_registers[i].cmd); | |
/* CSC */ | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, 0x18, 0xA8); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, 0x1A, 1 << 5); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, 0x22, 0x08); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, 0x26, 0x0F); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, 0x27, 0xFF); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, 0x2, 0x08); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, 0x1A, 0 << 5); | |
#endif | |
/* CSC */ | |
/*hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, 0x18, 0xA8); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, 0x1A, 1 << 5); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, 0x22, 0x08); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, 0x26, 0x0F); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, 0x27, 0xFF); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, 0x2, 0x08); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, 0x1A, 0 << 5);*/ | |
#if 0 | |
/* Register Settings for DE Generation */ | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, 0x35, 0x40); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, 0x36, 0xD9); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, 0x37, 0x0A); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, 0x38, 0x00); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, 0x39, 0x2D); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, 0x3A, 0x00); | |
/* Register Settings for Sync Adjustment */ | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, 0xD7, 0x1B); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, 0xD8, 0x82); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, 0xD9, 0x80); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, 0xDA, 0x14); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, 0xDB, 0x05); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, 0x17, 0b11); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, 0x41, 0x10 | (1 << 1)); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, 0xD0, 0x30 | (1 << 1)); | |
#endif | |
//while (1) | |
// hdmi_check(); | |
} | |
#endif | |
int hdmi_init(void) | |
{ | |
pervasive_hdmi_cec_set_enabled(1); | |
syscon_set_hdmi_cdc_hpd(1); | |
gpio_set_port_mode(0, GPIO_PORT_HDMI_BRIDGE, | |
GPIO_PORT_MODE_OUTPUT); | |
gpio_port_clear(0, GPIO_PORT_HDMI_BRIDGE); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, ADV7511_REG_CEC_I2C_ADDR, | |
HDMI_I2C_CEC_ADDR); | |
unsigned char status; | |
do { | |
hdmi_i2c_cmd_write_read_1(HDMI_I2C_ADDR, ADV7511_REG_STATUS, &status); | |
} while (!(status & ADV7511_STATUS_HPD)); | |
hdmi_i2c_update_bits(HDMI_I2C_ADDR, ADV7511_REG_POWER, | |
ADV7511_POWER_POWER_DOWN, 0); | |
hdmi_i2c_update_bits(HDMI_I2C_ADDR, ADV7511_REG_POWER2, | |
ADV7511_REG_POWER2_HPD_SRC_MASK, | |
ADV7511_REG_POWER2_HPD_SRC_HPD); | |
for (int i = 0; i < ARRAY_SIZE(adv7533_fixed_registers); i++) | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, | |
adv7533_fixed_registers[i].reg, | |
adv7533_fixed_registers[i].cmd); | |
for (int i = 0; i < ARRAY_SIZE(adv7533_cec_fixed_registers); i++) | |
hdmi_i2c_cmd_write_1(HDMI_I2C_CEC_ADDR, | |
adv7533_cec_fixed_registers[i].reg, | |
adv7533_cec_fixed_registers[i].cmd); | |
static const int test_mode = 0; | |
static const unsigned char lanes = 3; | |
if (test_mode) { | |
/* set pixel clock auto mode */ | |
hdmi_write(HDMI_I2C_CEC_ADDR, 0x16, 0x00); | |
} else { | |
static const u8 clock_div_by_lanes[] = { 6, 4, 3 }; /* 2, 3, 4 lanes */ | |
/* set pixel clock divider mode */ | |
hdmi_write(HDMI_I2C_CEC_ADDR, 0x16, | |
clock_div_by_lanes[lanes - 2] << 3); | |
} | |
if (test_mode) { | |
unsigned int htotal = 1650; | |
unsigned int vtotal = 750; | |
unsigned int hsw = 0x28; | |
unsigned int hfp = 0x6E; | |
unsigned int hbp = 0xDC; | |
unsigned int vsw = 5; | |
unsigned int vfp = 5; | |
unsigned int vbp = 0x14; | |
/* horizontal porch params */ | |
hdmi_write(HDMI_I2C_CEC_ADDR, 0x28, htotal >> 4); | |
hdmi_write(HDMI_I2C_CEC_ADDR, 0x29, | |
(htotal << 4) & 0xff); | |
hdmi_write(HDMI_I2C_CEC_ADDR, 0x2a, hsw >> 4); | |
hdmi_write(HDMI_I2C_CEC_ADDR, 0x2b, (hsw << 4) & 0xff); | |
hdmi_write(HDMI_I2C_CEC_ADDR, 0x2c, hfp >> 4); | |
hdmi_write(HDMI_I2C_CEC_ADDR, 0x2d, (hfp << 4) & 0xff); | |
hdmi_write(HDMI_I2C_CEC_ADDR, 0x2e, hbp >> 4); | |
hdmi_write(HDMI_I2C_CEC_ADDR, 0x2f, (hbp << 4) & 0xff); | |
/* vertical porch params */ | |
hdmi_write(HDMI_I2C_CEC_ADDR, 0x30, vtotal >> 4); | |
hdmi_write(HDMI_I2C_CEC_ADDR, 0x31, | |
(vtotal << 4) & 0xff); | |
hdmi_write(HDMI_I2C_CEC_ADDR, 0x32, vsw >> 4); | |
hdmi_write(HDMI_I2C_CEC_ADDR, 0x33, (vsw << 4) & 0xff); | |
hdmi_write(HDMI_I2C_CEC_ADDR, 0x34, vfp >> 4); | |
hdmi_write(HDMI_I2C_CEC_ADDR, 0x35, (vfp << 4) & 0xff); | |
hdmi_write(HDMI_I2C_CEC_ADDR, 0x36, vbp >> 4); | |
hdmi_write(HDMI_I2C_CEC_ADDR, 0x37, (vbp << 4) & 0xff); | |
/* set number of dsi lanes */ | |
hdmi_write(HDMI_I2C_CEC_ADDR, 0x1C, 3 << 4); | |
hdmi_clr_bit(HDMI_I2C_CEC_ADDR, 0x05, 0x20); | |
hdmi_clr_bit(HDMI_I2C_CEC_ADDR, 0x05, 0x10); | |
/* Set CEC Power Mode = Always Active. Clear bits before*/ | |
hdmi_clr_bit(HDMI_I2C_CEC_ADDR, 0xBE, 0x03); | |
hdmi_set_bit(HDMI_I2C_CEC_ADDR, 0xBE, 0x01); | |
/* Fixed Register Settings per PG*/ | |
hdmi_write(HDMI_I2C_CEC_ADDR, 0x24, 0x20); | |
hdmi_write(HDMI_I2C_CEC_ADDR, 0x26, 0x3C); | |
hdmi_write(HDMI_I2C_ADDR, 0x9A, 0xE0); | |
hdmi_write(HDMI_I2C_ADDR, 0x9B, 0x19); | |
hdmi_write(HDMI_I2C_ADDR, 0xBA, 0x70); | |
hdmi_write(HDMI_I2C_ADDR, 0xDE, 0x82); | |
hdmi_write(HDMI_I2C_ADDR, 0xE4, 0x40); | |
hdmi_write(HDMI_I2C_ADDR, 0xE5, 0x80); | |
/* reset internal timing generator */ | |
hdmi_write(HDMI_I2C_CEC_ADDR, 0x27, 0xcb); | |
hdmi_write(HDMI_I2C_CEC_ADDR, 0x27, 0x8b); | |
hdmi_write(HDMI_I2C_CEC_ADDR, 0x27, 0xcb); | |
} else { | |
/* disable internal timing generator */ | |
hdmi_write(HDMI_I2C_CEC_ADDR, 0x27, 0x0b); | |
} | |
/* 09-03 AVI Infoframe - RGB - 16-9 Aspect Ratio */ | |
hdmi_write(HDMI_I2C_ADDR, 0x55, 0x10); | |
hdmi_write(HDMI_I2C_ADDR, 0x56, 0x28); | |
/* 04-04 GC Packet Enable */ | |
hdmi_write(HDMI_I2C_ADDR, 0x40, 0x80); | |
/* 04-06 GC Colour Depth - 24 Bit */ | |
hdmi_write(HDMI_I2C_ADDR, 0x4c, 0x04); | |
/* 04-09 Down Dither Output Colour Depth - 8 Bit (default) */ | |
hdmi_write(HDMI_I2C_ADDR, 0x49, 0x00); | |
/* 07-01 CEC Power Mode - Always Active */ | |
hdmi_write(HDMI_I2C_CEC_ADDR, 0xbe, 0x3d); | |
/* HDMI Output Settings*/ | |
/* Set HDMI/DVI Mode Select = HDMI Mode Enabled - bit 1*/ | |
hdmi_set_bit(HDMI_I2C_ADDR, 0xAF, 0x2); | |
/* Enable GC Packet */ | |
hdmi_set_bit(HDMI_I2C_ADDR, 0x40, 0x80); | |
/* Set Color Depth to 24 Bits/Pixel. Clear field before*/ | |
hdmi_clr_bit(HDMI_I2C_ADDR, 0x4C, 0x0F); | |
hdmi_set_bit(HDMI_I2C_ADDR, 0x4C, 0x04); | |
/* Set Active Format Aspect Ratio = 4:3 (Center) Clear field before*/ | |
hdmi_clr_bit(HDMI_I2C_ADDR, 0x56, 0x0F); | |
hdmi_set_bit(HDMI_I2C_ADDR, 0x56, 0x09); | |
/* Set V1P2 Enable = +1.2V*/ | |
hdmi_set_bit(HDMI_I2C_ADDR, 0xE4, 0xC0); | |
if (test_mode) | |
/*enable test mode */ | |
hdmi_write(HDMI_I2C_CEC_ADDR, 0x55, 0x80); | |
else | |
/* disable test mode */ | |
hdmi_write(HDMI_I2C_CEC_ADDR, 0x55, 0x00); | |
/* enable hdmi */ | |
hdmi_write(HDMI_I2C_CEC_ADDR, 0x03, 0x89); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, 0xAF, 0b10010110); // 0x96 = 0b10010110 | |
//hdmi_i2c_cmd_write_1(HDMI_I2C_CEC_ADDR, 0x81, 0x07); | |
/* Wait for the BKSV flag */ | |
unsigned char data; | |
do { | |
hdmi_i2c_cmd_write_read_1(HDMI_I2C_ADDR, 0x97, &data); | |
} while (!(data & (1 << 6))); | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, 0x97, (data & ~0xBF) | (1 << 6)); | |
return 0; | |
} | |
void hdmi_check(void) | |
{ | |
unsigned char data; | |
static int i = 0; | |
/*hdmi_i2c_cmd_write_read_1(HDMI_I2C_ADDR, 0x42, &data); | |
LOG_HEX(data);*/ | |
hdmi_i2c_cmd_write_read_1(HDMI_I2C_ADDR, 0x3E, &data); | |
LOG_HEX(data); | |
hdmi_i2c_cmd_write_read_1(HDMI_I2C_ADDR, 0x96, &data); | |
//if (data & (1 << 5)) | |
hdmi_i2c_cmd_write_1(HDMI_I2C_ADDR, 0x96, data); | |
LOG_HEX(data); | |
hdmi_i2c_cmd_write_read_1(HDMI_I2C_CEC_ADDR, 0x83, &data); | |
LOG_HEX(data); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment