return BP_RESULT_NORECORD;
}
+static enum bp_result bios_parser_get_connector_aux_info(struct dc_bios *dcb,
+ struct graphics_object_id id,
+ struct graphics_object_i2c_info *info)
+{
+ uint32_t offset;
+ struct atom_display_object_path_v2 *object;
+ struct atom_display_object_path_v3 *object_path_v3;
+ struct atom_common_record_header *header;
+ struct atom_i2c_record *record;
+ struct bios_parser *bp = BP_FROM_DCB(dcb);
+
+ if (!info)
+ return BP_RESULT_BADINPUT;
+
+ switch (bp->object_info_tbl.revision.minor) {
+ case 4:
+ default:
+ object = get_bios_object(bp, id);
+
+ if (!object)
+ return BP_RESULT_BADINPUT;
+
+ offset = object->disp_recordoffset + bp->object_info_tbl_offset;
+ break;
+ case 5:
+ object_path_v3 = get_bios_object_from_path_v3(bp, id);
+
+ if (!object_path_v3)
+ return BP_RESULT_BADINPUT;
+
+ offset = object_path_v3->disp_recordoffset + bp->object_info_tbl_offset;
+ break;
+ }
+
+ for (;;) {
+ header = GET_IMAGE(struct atom_common_record_header, offset);
+
+ if (!header)
+ return BP_RESULT_BADBIOSTABLE;
+
+ if (header->record_type == LAST_RECORD_TYPE ||
+ !header->record_size)
+ break;
+
+ if (header->record_type == ATOM_I2C_RECORD_TYPE
+ && sizeof(struct atom_i2c_record) <=
+ header->record_size) {
+ /* get_connector_aux_info - which aux instance is used it is based
+ * on record->i2c_id field only, does not need GPIO DDC
+ */
+ record = (struct atom_i2c_record *)header;
+
+ info->i2c_line = record->i2c_id & I2C_HW_LANE_MUX;
+
+ return BP_RESULT_OK;
+ }
+
+ offset += header->record_size;
+ }
+
+ return BP_RESULT_NORECORD;
+}
+
static struct device_id device_type_from_device_id(uint16_t device_id)
{
? 1 : 0;
info->INTERNAL_DISPLAY_BL = (record_path_v3->connector_caps & ATOM_CONNECTOR_CAP_INTERNAL_DISPLAY_BL)
? 1 : 0;
+ // All aux transactions for this connector should rely only on aux instance, not on ddc instance
+ info->NO_DDC_PIN = (record_path_v3->connector_caps & ATOM_CONNECTOR_CAP_DP_PLUS_PLUS_TYPE2_ONLY) ? 1 : 0;
+
break;
}
.get_lttpr_interop = bios_parser_get_lttpr_interop,
.get_connector_speed_cap_info = bios_parser_get_connector_speed_cap_info,
+ .get_connector_aux_info = bios_parser_get_connector_aux_info,
};
static bool bios_parser2_construct(
bool enable_dpia_pre_training;
bool unify_link_enc_assignment;
bool enable_cursor_offload;
+ bool dp_connector_no_native_i2c;
bool frame_update_cmd_version2;
struct spl_sharpness_range dcn_sharpness_range;
struct spl_sharpness_range dcn_override_sharpness_range;
struct dc_link_training_overrides preferred_training_settings;
struct dp_audio_test_data audio_test_data;
+ /* On ASICs with dp_connector_no_native_i2c cap set and no_ddc_pin cap
+ * set by IFWI, link aux_hw_inst is used in aux layer functions instead
+ * of ddc_pin to know which aux instance is associated with link.
+ */
+ bool no_ddc_pin;
+ enum gpio_ddc_line aux_hw_inst;
+
enum gpio_ddc_line ddc_hw_inst;
uint8_t hpd_src;
struct dc_bios *bios,
struct graphics_object_id object_id,
struct bp_connector_speed_cap_info *info);
+ enum bp_result(*get_connector_aux_info)(
+ struct dc_bios *dcb,
+ struct graphics_object_id id,
+ struct graphics_object_i2c_info *info);
};
struct bios_registers {
if (!link)
return false;
- const bool over_aux = false;
- const uint32_t ddc_line = link->ddc->ddc_pin->pin_data->en;
+ const bool over_aux = link->no_ddc_pin;
+ const uint32_t ddc_line = over_aux ? link->aux_hw_inst : link->ddc->ddc_pin->pin_data->en;
union dmub_rb_cmd commands[3] = { 0 };
const bool converted = op_i2c_convert(&commands[0], write, FUSED_REQUEST_WRITE, ddc_line, over_aux)
}
REG_UPDATE(AUX_SW_CONTROL, AUX_SW_GO, 1);
- EVENT_LOG_AUX_REQ(engine->ddc->pin_data->en, EVENT_LOG_AUX_ORIGIN_NATIVE,
- request->action, request->address, request->length, request->data);
+
+ if (engine->ddc) {
+ EVENT_LOG_AUX_REQ(engine->ddc->pin_data->en, EVENT_LOG_AUX_ORIGIN_NATIVE,
+ request->action, request->address, request->length, request->data);
+ } else {
+ EVENT_LOG_AUX_REQ(engine->inst, EVENT_LOG_AUX_ORIGIN_NATIVE,
+ request->action, request->address, request->length, request->data);
+ }
}
static int read_channel_reply(struct dce_aux *engine, uint32_t size,
return true;
}
+static bool acquire_aux_engine_without_ddc_pin(
+ struct dce_aux *engine,
+ struct ddc *ddc)
+{
+ (void)ddc;
+ if ((engine == NULL) || !is_engine_available(engine))
+ return false;
+
+ if (!acquire_engine(engine)) {
+ release_engine(engine);
+ return false;
+ }
+ return true;
+}
+
void dce110_engine_destroy(struct dce_aux **engine)
{
}
+static uint32_t dce_aux_configure_timeout_without_ddc_pin(struct ddc_service *ddc,
+ uint32_t timeout_in_us)
+{
+ uint32_t multiplier = 0;
+ uint32_t length = 0;
+ uint32_t prev_length = 0;
+ uint32_t prev_mult = 0;
+ uint32_t prev_timeout_val = 0;
+ struct dce_aux *aux_engine = ddc->ctx->dc->res_pool->engines[ddc->link->aux_hw_inst];
+ struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(aux_engine);
+
+ /* 1-Update polling timeout period */
+ aux110->polling_timeout_period = timeout_in_us * SW_AUX_TIMEOUT_PERIOD_MULTIPLIER;
+
+ /* 2-Update aux timeout period length and multiplier */
+ if (timeout_in_us == 0) {
+ multiplier = DEFAULT_AUX_ENGINE_MULT;
+ length = DEFAULT_AUX_ENGINE_LENGTH;
+ } else if (timeout_in_us <= TIME_OUT_INCREMENT) {
+ multiplier = 0;
+ length = timeout_in_us / TIME_OUT_MULTIPLIER_8;
+ if (timeout_in_us % TIME_OUT_MULTIPLIER_8 != 0)
+ length++;
+ } else if (timeout_in_us <= 2 * TIME_OUT_INCREMENT) {
+ multiplier = 1;
+ length = timeout_in_us / TIME_OUT_MULTIPLIER_16;
+ if (timeout_in_us % TIME_OUT_MULTIPLIER_16 != 0)
+ length++;
+ } else if (timeout_in_us <= 4 * TIME_OUT_INCREMENT) {
+ multiplier = 2;
+ length = timeout_in_us / TIME_OUT_MULTIPLIER_32;
+ if (timeout_in_us % TIME_OUT_MULTIPLIER_32 != 0)
+ length++;
+ } else if (timeout_in_us > 4 * TIME_OUT_INCREMENT) {
+ multiplier = 3;
+ length = timeout_in_us / TIME_OUT_MULTIPLIER_64;
+ if (timeout_in_us % TIME_OUT_MULTIPLIER_64 != 0)
+ length++;
+ }
+
+ length = (length < MAX_TIMEOUT_LENGTH) ? length : MAX_TIMEOUT_LENGTH;
+
+ REG_GET_2(AUX_DPHY_RX_CONTROL1, AUX_RX_TIMEOUT_LEN, &prev_length, AUX_RX_TIMEOUT_LEN_MUL, &prev_mult);
+
+ switch (prev_mult) {
+ case 0:
+ prev_timeout_val = prev_length * TIME_OUT_MULTIPLIER_8;
+ break;
+ case 1:
+ prev_timeout_val = prev_length * TIME_OUT_MULTIPLIER_16;
+ break;
+ case 2:
+ prev_timeout_val = prev_length * TIME_OUT_MULTIPLIER_32;
+ break;
+ case 3:
+ prev_timeout_val = prev_length * TIME_OUT_MULTIPLIER_64;
+ break;
+ default:
+ prev_timeout_val = DEFAULT_AUX_ENGINE_LENGTH * TIME_OUT_MULTIPLIER_8;
+ break;
+ }
+
+ REG_UPDATE_SEQ_2(AUX_DPHY_RX_CONTROL1, AUX_RX_TIMEOUT_LEN, length, AUX_RX_TIMEOUT_LEN_MUL, multiplier);
+
+ return prev_timeout_val;
+}
+
static uint32_t dce_aux_configure_timeout(struct ddc_service *ddc,
uint32_t timeout_in_us)
{
uint32_t prev_mult = 0;
uint32_t prev_timeout_val = 0;
struct ddc *ddc_pin = ddc->ddc_pin;
+
+ if (ddc->ctx->dc->config.dp_connector_no_native_i2c && ddc->link->no_ddc_pin)
+ return dce_aux_configure_timeout_without_ddc_pin(ddc, timeout_in_us);
+
struct dce_aux *aux_engine = ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en];
struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(aux_engine);
struct aux_payload *payload,
enum aux_return_code_type *operation_result)
{
- if (ddc->ctx->dc->debug.enable_dmub_aux_for_legacy_ddc ||
- !ddc->ddc_pin) {
- return dce_aux_transfer_dmub_raw(ddc, payload, operation_result);
+ if (ddc->ctx->dc->config.dp_connector_no_native_i2c && ddc->link->no_ddc_pin) {
+ /* Check whether aux to be processed via dmub or dcn directly */
+ if (ddc->ctx->dc->debug.enable_dmub_aux_for_legacy_ddc) {
+ return dce_aux_transfer_dmub_raw(ddc, payload, operation_result);
+ } else {
+ return dce_aux_transfer_raw_without_ddc_pin(ddc, payload, operation_result);
+ }
} else {
- return dce_aux_transfer_raw_with_ddc_pin(ddc, payload, operation_result);
+ if (ddc->ctx->dc->debug.enable_dmub_aux_for_legacy_ddc ||
+ !ddc->ddc_pin) {
+ return dce_aux_transfer_dmub_raw(ddc, payload, operation_result);
+ } else {
+ return dce_aux_transfer_raw_with_ddc_pin(ddc, payload, operation_result);
+ }
}
}
return res;
}
+int dce_aux_transfer_raw_without_ddc_pin(struct ddc_service *ddc,
+ struct aux_payload *payload,
+ enum aux_return_code_type *operation_result)
+{
+ struct ddc *ddc_pin = ddc->ddc_pin;
+ struct dce_aux *aux_engine;
+ struct aux_request_transaction_data aux_req;
+ uint8_t returned_bytes = 0;
+ int res = -1;
+ uint32_t status;
+
+ memset(&aux_req, 0, sizeof(aux_req));
+
+ aux_engine = ddc->ctx->dc->res_pool->engines[ddc->link->aux_hw_inst];
+
+ if (!acquire_aux_engine_without_ddc_pin(aux_engine, ddc_pin)) {
+ *operation_result = AUX_RET_ERROR_ENGINE_ACQUIRE;
+ return -1;
+ }
+
+ if (payload->i2c_over_aux)
+ aux_req.type = AUX_TRANSACTION_TYPE_I2C;
+ else
+ aux_req.type = AUX_TRANSACTION_TYPE_DP;
+
+ aux_req.action = i2caux_action_from_payload(payload);
+
+ aux_req.address = payload->address;
+ aux_req.delay = 0;
+ aux_req.length = payload->length;
+ aux_req.data = payload->data;
+
+ submit_channel_request(aux_engine, &aux_req);
+ *operation_result = get_channel_status(aux_engine, &returned_bytes);
+
+ if (*operation_result == AUX_RET_SUCCESS) {
+ int __maybe_unused bytes_replied = 0;
+
+ bytes_replied = read_channel_reply(aux_engine, payload->length,
+ payload->data, payload->reply,
+ &status);
+ EVENT_LOG_AUX_REP(aux_engine->inst,
+ EVENT_LOG_AUX_ORIGIN_NATIVE, *payload->reply,
+ bytes_replied, payload->data);
+ res = returned_bytes;
+ } else {
+ res = -1;
+ }
+
+ release_engine(aux_engine);
+ return res;
+}
+
int dce_aux_transfer_dmub_raw(struct ddc_service *ddc,
struct aux_payload *payload,
enum aux_return_code_type *operation_result)
release_engine(aux_engine);
}
+ if (ddc->ctx->dc->config.dp_connector_no_native_i2c && ddc->link->no_ddc_pin) {
+ struct dce_aux *aux_engine = ddc->ctx->dc->res_pool->engines[ddc->link->aux_hw_inst];
+
+ if (!acquire_aux_engine_without_ddc_pin(aux_engine, ddc_pin)) {
+ *operation_result = AUX_RET_ERROR_ENGINE_ACQUIRE;
+ return -1;
+ }
+ release_engine(aux_engine);
+ }
+
return dm_helper_dmub_aux_transfer_sync(ddc->ctx, ddc->link, payload, operation_result);
}
aux110 = FROM_AUX_ENGINE(aux_engine);
}
+ if (ddc->ctx->dc->config.dp_connector_no_native_i2c && ddc->link->no_ddc_pin) {
+ aux_engine = ddc->ctx->dc->res_pool->engines[ddc->link->aux_hw_inst];
+ aux110 = FROM_AUX_ENGINE(aux_engine);
+ }
+
if (!payload->reply) {
payload_reply = false;
payload->reply = &reply;
struct aux_payload *cmd,
enum aux_return_code_type *operation_result);
+int dce_aux_transfer_raw_without_ddc_pin(struct ddc_service *ddc,
+ struct aux_payload *cmd,
+ enum aux_return_code_type *operation_result);
+
int dce_aux_transfer_dmub_raw(struct ddc_service *ddc,
struct aux_payload *payload,
enum aux_return_code_type *operation_result);
#include "link_enc_cfg.h"
#include "../hw_sequencer.h"
#include "dio/dcn10/dcn10_dio.h"
+#include "gpio_service_interface.h"
#define DC_LOGGER_INIT(logger)
backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl);
user_level = link->panel_cntl->stored_backlight_registers.USER_LEVEL;
}
+
+ if (link->ctx->dc->config.dp_connector_no_native_i2c && link->no_ddc_pin) {
+ struct graphics_object_i2c_info i2c_info;
+ struct ddc *ddc_pin;
+ struct gpio_ddc_hw_info hw_info;
+
+ if (link->ctx->dc_bios->funcs->get_i2c_info(dcb, link->link_id, &i2c_info) == BP_RESULT_OK) {
+ hw_info.ddc_channel = i2c_info.i2c_line;
+ hw_info.hw_supported = i2c_info.i2c_hw_assist;
+
+ ddc_pin = dal_gpio_create_ddc(
+ link->ctx->gpio_service,
+ i2c_info.gpio_info.clk_a_register_index,
+ 1 << i2c_info.gpio_info.clk_a_shift,
+ &hw_info);
+
+ if (ddc_pin) {
+ // need to switch pad to aux mode, one time only
+ // TODO: Handle result
+ dal_ddc_open(ddc_pin, GPIO_MODE_HARDWARE,
+ GPIO_DDC_CONFIG_TYPE_MODE_AUX);
+
+ dal_gpio_destroy_ddc(&ddc_pin);
+ }
+ }
+ }
}
for (i = 0; i < dc->res_pool->pipe_count; i++) {
channel = CHANNEL_ID_UNKNOWN;
- ddc = get_ddc_pin(link->ddc);
+ if (link->ctx->dc->config.dp_connector_no_native_i2c && link->no_ddc_pin) {
+ channel = link->aux_hw_inst + 1;
+ } else {
+ ddc = get_ddc_pin(link->ddc);
- if (ddc) {
- switch (dal_ddc_get_line(ddc)) {
- case GPIO_DDC_LINE_DDC1:
- channel = CHANNEL_ID_DDC1;
- break;
- case GPIO_DDC_LINE_DDC2:
- channel = CHANNEL_ID_DDC2;
- break;
- case GPIO_DDC_LINE_DDC3:
- channel = CHANNEL_ID_DDC3;
- break;
- case GPIO_DDC_LINE_DDC4:
- channel = CHANNEL_ID_DDC4;
- break;
- case GPIO_DDC_LINE_DDC5:
- channel = CHANNEL_ID_DDC5;
- break;
- case GPIO_DDC_LINE_DDC6:
- channel = CHANNEL_ID_DDC6;
- break;
- case GPIO_DDC_LINE_DDC_VGA:
- channel = CHANNEL_ID_DDC_VGA;
- break;
- case GPIO_DDC_LINE_I2C_PAD:
- channel = CHANNEL_ID_I2C_PAD;
- break;
- default:
- BREAK_TO_DEBUGGER();
- break;
+ if (ddc) {
+ switch (dal_ddc_get_line(ddc)) {
+ case GPIO_DDC_LINE_DDC1:
+ channel = CHANNEL_ID_DDC1;
+ break;
+ case GPIO_DDC_LINE_DDC2:
+ channel = CHANNEL_ID_DDC2;
+ break;
+ case GPIO_DDC_LINE_DDC3:
+ channel = CHANNEL_ID_DDC3;
+ break;
+ case GPIO_DDC_LINE_DDC4:
+ channel = CHANNEL_ID_DDC4;
+ break;
+ case GPIO_DDC_LINE_DDC5:
+ channel = CHANNEL_ID_DDC5;
+ break;
+ case GPIO_DDC_LINE_DDC6:
+ channel = CHANNEL_ID_DDC6;
+ break;
+ case GPIO_DDC_LINE_DDC_VGA:
+ channel = CHANNEL_ID_DDC_VGA;
+ break;
+ case GPIO_DDC_LINE_I2C_PAD:
+ channel = CHANNEL_ID_I2C_PAD;
+ break;
+ default:
+ BREAK_TO_DEBUGGER();
+ break;
+ }
}
}
-
return channel;
}
bios->funcs->get_disp_connector_caps_info(bios, link->link_id, &disp_connect_caps_info);
link->is_internal_display = (disp_connect_caps_info.INTERNAL_DISPLAY != 0);
DC_LOG_DC("BIOS object table - is_internal_display: %d", link->is_internal_display);
+ link->no_ddc_pin = disp_connect_caps_info.NO_DDC_PIN != 0;
}
if (link->link_id.type != OBJECT_TYPE_CONNECTOR) {
goto ddc_create_fail;
}
- /* Embedded display connectors such as LVDS may not have DDC. */
- if (!link->ddc->ddc_pin &&
- !dc_is_embedded_signal(link->connector_signal)) {
- DC_ERROR("Failed to get I2C info for connector!\n");
- goto ddc_create_fail;
- }
+ if (link->ctx->dc->config.dp_connector_no_native_i2c && link->no_ddc_pin) {
+ link->ddc_hw_inst = link->aux_hw_inst;
+ } else {
+ /* Embedded display connectors such as LVDS may not have DDC. */
+ if (!link->ddc->ddc_pin &&
+ !dc_is_embedded_signal(link->connector_signal)) {
+ DC_ERROR("Failed to get I2C info for connector!\n");
+ goto ddc_create_fail;
+ }
- link->ddc_hw_inst =
- dal_ddc_get_line(get_ddc_pin(link->ddc));
+ link->ddc_hw_inst =
+ dal_ddc_get_line(get_ddc_pin(link->ddc));
+ }
enc_init_data.ctx = dc_ctx;
enc_init_data.connector = link->link_id;
ddc_service->link = init_data->link;
ddc_service->ctx = init_data->ctx;
- if (init_data->is_dpia_link ||
- dcb->funcs->get_i2c_info(dcb, init_data->id, &i2c_info) != BP_RESULT_OK) {
- ddc_service->ddc_pin = NULL;
- } else {
- DC_LOGGER_INIT(ddc_service->ctx->logger);
- DC_LOG_DC("BIOS object table - i2c_line: %d", i2c_info.i2c_line);
- DC_LOG_DC("BIOS object table - i2c_engine_id: %d", i2c_info.i2c_engine_id);
-
- hw_info.ddc_channel = i2c_info.i2c_line;
- if (ddc_service->link != NULL)
- hw_info.hw_supported = i2c_info.i2c_hw_assist;
- else
- hw_info.hw_supported = false;
-
- ddc_service->ddc_pin = dal_gpio_create_ddc(
- gpio_service,
- i2c_info.gpio_info.clk_a_register_index,
- 1 << i2c_info.gpio_info.clk_a_shift,
- &hw_info);
+ if (ddc_service->link && ddc_service->ctx->dc->config.dp_connector_no_native_i2c &&
+ ddc_service->link->no_ddc_pin) {
+ // Obtain aux instance info from i2c_info without GPIO DDC pin info
+ if (dcb->funcs->get_connector_aux_info(dcb, init_data->id, &i2c_info) == BP_RESULT_OK)
+ ddc_service->link->aux_hw_inst = (uint8_t)i2c_info.i2c_line;
+ } else {
+ if (init_data->is_dpia_link ||
+ dcb->funcs->get_i2c_info(dcb, init_data->id, &i2c_info) != BP_RESULT_OK) {
+ ddc_service->ddc_pin = NULL;
+ } else {
+ DC_LOGGER_INIT(ddc_service->ctx->logger);
+ DC_LOG_DC("BIOS object table - i2c_line: %d", i2c_info.i2c_line);
+ DC_LOG_DC("BIOS object table - i2c_engine_id: %d", i2c_info.i2c_engine_id);
+
+ hw_info.ddc_channel = i2c_info.i2c_line;
+ if (ddc_service->link != NULL)
+ hw_info.hw_supported = i2c_info.i2c_hw_assist;
+ else
+ hw_info.hw_supported = false;
+
+ ddc_service->ddc_pin = dal_gpio_create_ddc(
+ gpio_service,
+ i2c_info.gpio_info.clk_a_register_index,
+ 1 << i2c_info.gpio_info.clk_a_shift,
+ &hw_info);
+ }
}
ddc_service->flags.EDID_QUERY_DONE_ONCE = false;
if (ddc->link->ep_type != DISPLAY_ENDPOINT_PHY)
return true;
- if (ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en]->funcs->configure_timeout) {
- ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en]->funcs->configure_timeout(ddc, timeout);
- result = true;
- }
+ if (ddc->ctx->dc->config.dp_connector_no_native_i2c && ddc->link->no_ddc_pin) {
+ if (ddc->ctx->dc->res_pool->engines[ddc->link->aux_hw_inst]->funcs->configure_timeout) {
+ ddc->ctx->dc->res_pool->engines[ddc->link->aux_hw_inst]->funcs->configure_timeout(ddc, timeout);
+ result = true;
+ }
+ } else {
+ if (ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en]->funcs->configure_timeout) {
+ ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en]->funcs->configure_timeout(ddc, timeout);
+ result = true;
+ }
+ }
return result;
}
(connector_id == CONNECTOR_ID_EDP) ||
(connector_id == CONNECTOR_ID_USBC));
+ /* We can't perform the step below for ASICs with no Native
+ * I2C signaling support on DP connectors, so skip it.
+ */
+ if (link->ctx->dc->config.dp_connector_no_native_i2c && link->no_ddc_pin)
+ return present;
+
ddc = get_ddc_pin(link->ddc);
if (!ddc) {
}
}
- psr_context->channel = link->ddc->ddc_pin->hw_info.ddc_channel;
+ if (dc->config.dp_connector_no_native_i2c && link->no_ddc_pin)
+ psr_context->channel = (enum channel_id)link->aux_hw_inst;
+ else
+ psr_context->channel = link->ddc->ddc_pin->hw_info.ddc_channel;
psr_context->transmitterId = link->link_enc->transmitter;
psr_context->engineId = link->link_enc->preferred_engine;
struct bp_disp_connector_caps_info {
uint32_t INTERNAL_DISPLAY : 1;
uint32_t INTERNAL_DISPLAY_BL : 1;
+ uint32_t NO_DDC_PIN : 1;
};
struct bp_encoder_cap_info {